diff -u -r -N squid-3.2.0.12/ChangeLog squid-3.2.0.13/ChangeLog
--- squid-3.2.0.12/ChangeLog	2011-09-16 23:37:30.000000000 +1200
+++ squid-3.2.0.13/ChangeLog	2011-10-14 14:42:56.000000000 +1300
@@ -1,3 +1,25 @@
+Changes to squid-3.2.0.13 (14 Oct 2011):
+
+	- Regression Bug 3363: never_direct always 'unable to forward this request at this time'
+	- Regression Bug 3351: FTP timeout causing "store_status == STORE_PENDING" assertion
+	- Regression Bug 3336: reconfigure assertion 'hlp->childs.n_running > 0'
+	- Regression fix: always_direct/never_direct failures
+	- Regression fix: stop an SSL header file being included after --disable-ssl
+	- Regression fix: parse HTTP list headers with embedded 8-bit characters
+	- Bug 3355: configure setting --with-swapdir ignored
+	- Bug 3325: option to selectively enable strict host verify checks
+	- Bug 3337: HTTP status 200 is not accepted for deny_info
+	- Bug 3077: '\' in url query strings cause Digest authentication to fail
+	- Support SMP worker shared memory cache
+	- Support SMP worker shared disk cache (rock)
+	- ext_session_acl: version 1.1
+	- Fix Host verify: do not pinn destination IP if URL re-write has been done
+	- Fix IPF interception
+	- Fix ssl_crtd "Cannot add certificate to db" when updating expired cert
+	- Fix ssl_crtd CertificateDB locking scheme
+	- ... and all changes from 3.1.16
+	- ... and many compile and polishing fixes
+
 Changes to squid-3.2.0.12 (17 Sep 2011):
 
 	- Regression Bug 3335: ICAP service is down
@@ -264,6 +286,19 @@
 	- ... and a great many testing improvements
 	- ... and many documentation updates
 
+Changes to squid-3.1.16 (14 Oct 2011):
+
+	- Bug 3373: invalid URL in ERR_CACHE_ACCESS_DENIED
+	- Bug 3368: Unhandled exceptions are not logged (workaround)
+	- Bug 3326: miss_access incorrect default
+	- Bug 3320: miss_access description confusing
+	- Bug 3241: squid_kerb_auth cross compilation fix
+	- Bug 3237: seq fault in free() from rfc1035RRDestroy
+	- Bug 3190: Large HTTP POST stuck after early ICAP 400 error response 
+	- db_auth: display available DSN drivers on connect error
+	- Updated OpenSSL 1.0.0 version checks
+	- ... and several documentation fixes
+
 Changes to squid-3.1.15 (28 Aug 2011):
 
 	- Regression fix: vhost and defaultsite causing vport to be ignored
diff -u -r -N squid-3.2.0.12/compat/Makefile.am squid-3.2.0.13/compat/Makefile.am
--- squid-3.2.0.12/compat/Makefile.am	2011-09-16 23:37:30.000000000 +1200
+++ squid-3.2.0.13/compat/Makefile.am	2011-10-14 14:42:56.000000000 +1300
@@ -31,6 +31,7 @@
 	initgroups.h \
 	osdetect.h \
 	psignal.h \
+	shm.h \
 	stdio.h \
 	stdvarargs.h \
 	strnstr.cc \
diff -u -r -N squid-3.2.0.12/compat/Makefile.in squid-3.2.0.13/compat/Makefile.in
--- squid-3.2.0.12/compat/Makefile.in	2011-09-16 23:38:07.000000000 +1200
+++ squid-3.2.0.13/compat/Makefile.in	2011-10-14 14:46:37.000000000 +1300
@@ -353,6 +353,7 @@
 	initgroups.h \
 	osdetect.h \
 	psignal.h \
+	shm.h \
 	stdio.h \
 	stdvarargs.h \
 	strnstr.cc \
diff -u -r -N squid-3.2.0.12/compat/shm.h squid-3.2.0.13/compat/shm.h
--- squid-3.2.0.12/compat/shm.h	1970-01-01 12:00:00.000000000 +1200
+++ squid-3.2.0.13/compat/shm.h	2011-10-14 14:42:56.000000000 +1300
@@ -0,0 +1,45 @@
+/*
+ * $Id$
+ */
+#ifndef SQUID_COMPAT_SHM_H
+#define SQUID_COMPAT_SHM_H
+
+#if HAVE_SHM
+
+#if HAVE_SYS_STAT_H
+#include <sys/stat.h> /* for mode constants */
+#endif
+
+#if HAVE_FCNTL_H
+#include <fcntl.h> /* for O_* constants */
+#endif
+
+#if HAVE_SYS_MMAN_H
+#include <sys/mman.h>
+#endif
+
+#else /* HAVE_SHM */
+
+#if HAVE_ERRNO_H
+#include <errno.h>
+#endif
+
+extern "C" {
+
+    inline int
+    shm_open(const char *, int, mode_t) {
+        errno = ENOTSUP;
+        return -1;
+    }
+
+    inline int
+    shm_unlink(const char *) {
+        errno = ENOTSUP;
+        return -1;
+    }
+
+} /* extern "C" */
+
+#endif /* HAVE_SHM */
+
+#endif /* SQUID_COMPAT_CPU_H */
diff -u -r -N squid-3.2.0.12/configure squid-3.2.0.13/configure
--- squid-3.2.0.12/configure	2011-09-16 23:38:35.000000000 +1200
+++ squid-3.2.0.13/configure	2011-10-14 14:49:52.000000000 +1300
@@ -1,7 +1,7 @@
 #! /bin/sh
 # From configure.ac Revision.
 # Guess values for system-dependent variables and create Makefiles.
-# Generated by GNU Autoconf 2.68 for Squid Web Proxy 3.2.0.12.
+# Generated by GNU Autoconf 2.68 for Squid Web Proxy 3.2.0.13.
 #
 # Report bugs to <http://www.squid-cache.org/bugs/>.
 #
@@ -575,8 +575,8 @@
 # Identity of this package.
 PACKAGE_NAME='Squid Web Proxy'
 PACKAGE_TARNAME='squid'
-PACKAGE_VERSION='3.2.0.12'
-PACKAGE_STRING='Squid Web Proxy 3.2.0.12'
+PACKAGE_VERSION='3.2.0.13'
+PACKAGE_STRING='Squid Web Proxy 3.2.0.13'
 PACKAGE_BUGREPORT='http://www.squid-cache.org/bugs/'
 PACKAGE_URL=''
 
@@ -1570,7 +1570,7 @@
   # Omit some internal or obsolete options to make the list less imposing.
   # This message is too long to be a string in the A/UX 3.1 sh.
   cat <<_ACEOF
-\`configure' configures Squid Web Proxy 3.2.0.12 to adapt to many kinds of systems.
+\`configure' configures Squid Web Proxy 3.2.0.13 to adapt to many kinds of systems.
 
 Usage: $0 [OPTION]... [VAR=VALUE]...
 
@@ -1640,7 +1640,7 @@
 
 if test -n "$ac_init_help"; then
   case $ac_init_help in
-     short | recursive ) echo "Configuration of Squid Web Proxy 3.2.0.12:";;
+     short | recursive ) echo "Configuration of Squid Web Proxy 3.2.0.13:";;
    esac
   cat <<\_ACEOF
 
@@ -2018,7 +2018,7 @@
 test -n "$ac_init_help" && exit $ac_status
 if $ac_init_version; then
   cat <<\_ACEOF
-Squid Web Proxy configure 3.2.0.12
+Squid Web Proxy configure 3.2.0.13
 generated by GNU Autoconf 2.68
 
 Copyright (C) 2010 Free Software Foundation, Inc.
@@ -3114,7 +3114,7 @@
 This file contains any messages produced by compilers while
 running configure, to aid debugging if configure makes a mistake.
 
-It was created by Squid Web Proxy $as_me 3.2.0.12, which was
+It was created by Squid Web Proxy $as_me 3.2.0.13, which was
 generated by GNU Autoconf 2.68.  Invocation command line was
 
   $ $0 $@
@@ -3933,7 +3933,7 @@
 
 # Define the identity of the package.
  PACKAGE='squid'
- VERSION='3.2.0.12'
+ VERSION='3.2.0.13'
 
 
 cat >>confdefs.h <<_ACEOF
@@ -18667,6 +18667,45 @@
 # to be used by sub-commands
 export enable_inline
 
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for atomic operations support" >&5
+$as_echo_n "checking for atomic operations support... " >&6; }
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+    int n = 0;
+
+int
+main ()
+{
+
+    __sync_add_and_fetch(&n, 10); // n becomes 10
+    __sync_fetch_and_add(&n, 20); // n becomes 30
+    __sync_sub_and_fetch(&n, 15); // n becomes 15
+    __sync_bool_compare_and_swap(&n, 15, 201); // n becomes 201
+    __sync_fetch_and_and(&n, 200); // n becomes 200
+    return (n == 200) ? 0 : -1;
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_cxx_try_compile "$LINENO"; then :
+
+
+$as_echo "#define HAVE_ATOMIC_OPS 1" >>confdefs.h
+
+    { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+
+else
+
+    { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+
+
 # Check whether --enable-debug-cbdata was given.
 if test "${enable_debug_cbdata+set}" = set; then :
   enableval=$enable_debug_cbdata;
@@ -18779,6 +18818,68 @@
 $as_echo "$as_me: With dl" >&6;}
 fi
 
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for library containing shm_open" >&5
+$as_echo_n "checking for library containing shm_open... " >&6; }
+if ${ac_cv_search_shm_open+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  ac_func_search_save_LIBS=$LIBS
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+/* Override any GCC internal prototype to avoid an error.
+   Use char because int might match the return type of a GCC
+   builtin and then its argument prototype would still apply.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+char shm_open ();
+int
+main ()
+{
+return shm_open ();
+  ;
+  return 0;
+}
+_ACEOF
+for ac_lib in '' rt; do
+  if test -z "$ac_lib"; then
+    ac_res="none required"
+  else
+    ac_res=-l$ac_lib
+    LIBS="-l$ac_lib  $ac_func_search_save_LIBS"
+  fi
+  if ac_fn_cxx_try_link "$LINENO"; then :
+  ac_cv_search_shm_open=$ac_res
+fi
+rm -f core conftest.err conftest.$ac_objext \
+    conftest$ac_exeext
+  if ${ac_cv_search_shm_open+:} false; then :
+  break
+fi
+done
+if ${ac_cv_search_shm_open+:} false; then :
+
+else
+  ac_cv_search_shm_open=no
+fi
+rm conftest.$ac_ext
+LIBS=$ac_func_search_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_search_shm_open" >&5
+$as_echo "$ac_cv_search_shm_open" >&6; }
+ac_res=$ac_cv_search_shm_open
+if test "$ac_res" != no; then :
+  test "$ac_res" = "none required" || LIBS="$ac_res $LIBS"
+
+fi
+
+if test "x$ac_cv_search_shm_open" != "xno" ; then
+
+$as_echo "#define HAVE_SHM 1" >>confdefs.h
+
+fi
+
 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for DiskIO modules to be enabled" >&5
 $as_echo_n "checking for DiskIO modules to be enabled... " >&6; }
 squid_disk_module_candidates=""
@@ -18837,6 +18938,10 @@
   fi
 done
 
+    if test "x$ac_cv_search_shm_open" = "xno" ; then
+        # disable IpcIo
+        squid_disk_module_candidates=`echo $squid_disk_module_candidates|sed 's/IpcIo//'`
+    fi
 fi
 
 { $as_echo "$as_me:${as_lineno-$LINENO}: result: ${squid_disk_module_candidates:-none}" >&5
@@ -19318,6 +19423,28 @@
       fi
       ;;
 
+    Mmapped)
+      { $as_echo "$as_me:${as_lineno-$LINENO}: Enabling Mmapped DiskIO module" >&5
+$as_echo "$as_me: Enabling Mmapped DiskIO module" >&6;}
+      DISK_LIBS="$DISK_LIBS libMmapped.a"
+      DISK_MODULES="$DISK_MODULES Mmapped"
+      DISK_LINKOBJS="$DISK_LINKOBJS DiskIO/Mmapped/MmappedDiskIOModule.o"
+      ;;
+
+    IpcIo)
+      { $as_echo "$as_me:${as_lineno-$LINENO}: Enabling IpcIo DiskIO module" >&5
+$as_echo "$as_me: Enabling IpcIo DiskIO module" >&6;}
+      if test "x$ac_cv_search_shm_open" = "xno" ; then
+        as_fn_error $? "DiskIO IpcIo module requires shared memory support" "$LINENO" 5
+      fi
+      DISK_LIBS="$DISK_LIBS libIpcIo.a"
+      DISK_MODULES="$DISK_MODULES IpcIo"
+      DISK_LINKOBJS="$DISK_LINKOBJS DiskIO/IpcIo/IpcIoDiskIOModule.o"
+
+$as_echo "#define USE_DISKIO_IPCIO 1" >>confdefs.h
+
+      ;;
+
     Blocking)
       { $as_echo "$as_me:${as_lineno-$LINENO}: Enabling Blocking DiskIO module" >&5
 $as_echo "$as_me: Enabling Blocking DiskIO module" >&6;}
@@ -19462,6 +19589,12 @@
       # for STORE_TESTS substition
       STORE_TESTS="$STORE_TESTS tests/testCoss$EXEEXT"
       ;;
+    rock)
+	if test "x$squid_disk_module_candidates_IpcIo" != "xyes" -a \
+	  "x$squid_disk_module_candidates_Blocking" != "xyes"; then
+	  as_fn_error $? "Storage module Rock requires IpcIo or Blocking DiskIO module" "$LINENO" 5
+	fi
+	;;
     ufs)
       STORE_TESTS="$STORE_TESTS tests/testUfs$EXEEXT"
     esac
@@ -19473,6 +19606,7 @@
 
 
 
+
 STORE_LIBS_TO_BUILD=
 STORE_LIBS_TO_ADD=
 for fs in $squid_storeio_module_candidates; do
@@ -23993,6 +24127,7 @@
   sys/param.h \
   sys/prctl.h \
   sys/md5.h \
+  sys/mman.h \
   sys/msg.h \
   sys/resource.h \
   sys/select.h \
@@ -30543,7 +30678,7 @@
 # report actual input values of CONFIG_FILES etc. instead of their
 # values after options handling.
 ac_log="
-This file was extended by Squid Web Proxy $as_me 3.2.0.12, which was
+This file was extended by Squid Web Proxy $as_me 3.2.0.13, which was
 generated by GNU Autoconf 2.68.  Invocation command line was
 
   CONFIG_FILES    = $CONFIG_FILES
@@ -30609,7 +30744,7 @@
 cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
 ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`"
 ac_cs_version="\\
-Squid Web Proxy config.status 3.2.0.12
+Squid Web Proxy config.status 3.2.0.13
 configured by $0, generated by GNU Autoconf 2.68,
   with options \\"\$ac_cs_config\\"
 
diff -u -r -N squid-3.2.0.12/configure.ac squid-3.2.0.13/configure.ac
--- squid-3.2.0.12/configure.ac	2011-09-16 23:38:35.000000000 +1200
+++ squid-3.2.0.13/configure.ac	2011-10-14 14:49:52.000000000 +1300
@@ -3,7 +3,7 @@
 dnl
 dnl
 dnl
-AC_INIT([Squid Web Proxy],[3.2.0.12],[http://www.squid-cache.org/bugs/],[squid])
+AC_INIT([Squid Web Proxy],[3.2.0.13],[http://www.squid-cache.org/bugs/],[squid])
 AC_PREREQ(2.61)
 AC_CONFIG_HEADERS([include/autoconf.h])
 AC_CONFIG_AUX_DIR(cfgaux)
@@ -367,6 +367,29 @@
 # to be used by sub-commands
 export enable_inline
 
+dnl
+dnl Check for atomic operations support in the compiler
+dnl
+AC_MSG_CHECKING([for atomic operations support])
+AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[
+    int n = 0;
+]],[[
+    __sync_add_and_fetch(&n, 10); // n becomes 10
+    __sync_fetch_and_add(&n, 20); // n becomes 30
+    __sync_sub_and_fetch(&n, 15); // n becomes 15
+    __sync_bool_compare_and_swap(&n, 15, 201); // n becomes 201
+    __sync_fetch_and_and(&n, 200); // n becomes 200
+    return (n == 200) ? 0 : -1;
+]])],
+[
+    AC_DEFINE(HAVE_ATOMIC_OPS,1,
+        [Define to 1 if you have __sync_add_and_fetch() and such])
+    AC_MSG_RESULT(yes)
+],[
+    AC_MSG_RESULT(no)
+])
+
+
 AC_ARG_ENABLE(debug-cbdata,
   AS_HELP_STRING([--enable-debug-cbdata],
       [Provide some debug information in cbdata]), [ 
@@ -439,6 +462,11 @@
   AC_MSG_NOTICE([With dl])
 fi
 
+AC_SEARCH_LIBS([shm_open], [rt])
+if test "x$ac_cv_search_shm_open" != "xno" ; then
+  AC_DEFINE(HAVE_SHM,1,[Support shared memory features])
+fi
+
 AC_MSG_CHECKING([for DiskIO modules to be enabled])
 squid_disk_module_candidates=""
 squid_opt_enable_diskio="auto"  #values: no, yes, "auto"(=yes+detect modules)
@@ -469,6 +497,10 @@
 if test "x$squid_opt_enable_diskio" = "xauto"; then
     squid_opt_enable_diskio="yes"
     SQUID_LOOK_FOR_MODULES([$srcdir/src/DiskIO],[squid_disk_module_candidates])
+    if test "x$ac_cv_search_shm_open" = "xno" ; then
+        # disable IpcIo
+        squid_disk_module_candidates=`echo $squid_disk_module_candidates|sed 's/IpcIo//'`
+    fi
 fi
 
 AC_MSG_RESULT([${squid_disk_module_candidates:-none}])
@@ -635,6 +667,24 @@
       fi
       ;;
 
+    Mmapped)
+      AC_MSG_NOTICE([Enabling Mmapped DiskIO module])
+      DISK_LIBS="$DISK_LIBS libMmapped.a"
+      DISK_MODULES="$DISK_MODULES Mmapped"
+      DISK_LINKOBJS="$DISK_LINKOBJS DiskIO/Mmapped/MmappedDiskIOModule.o"
+      ;;
+
+    IpcIo)
+      AC_MSG_NOTICE([Enabling IpcIo DiskIO module])
+      if test "x$ac_cv_search_shm_open" = "xno" ; then
+        AC_MSG_ERROR([DiskIO IpcIo module requires shared memory support])
+      fi
+      DISK_LIBS="$DISK_LIBS libIpcIo.a"
+      DISK_MODULES="$DISK_MODULES IpcIo"
+      DISK_LINKOBJS="$DISK_LINKOBJS DiskIO/IpcIo/IpcIoDiskIOModule.o"
+      AC_DEFINE(USE_DISKIO_IPCIO, 1, [Enable DiskIO IpcIo module.])
+      ;;
+
     Blocking)
       AC_MSG_NOTICE([Enabling Blocking DiskIO module])
       DISK_LIBS="$DISK_LIBS libBlocking.a"
@@ -722,6 +772,12 @@
       # for STORE_TESTS substition
       STORE_TESTS="$STORE_TESTS tests/testCoss$EXEEXT"
       ;;
+    rock)
+	if test "x$squid_disk_module_candidates_IpcIo" != "xyes" -a \
+	  "x$squid_disk_module_candidates_Blocking" != "xyes"; then
+	  AC_MSG_ERROR([Storage module Rock requires IpcIo or Blocking DiskIO module])
+	fi
+	;;
     ufs)
       STORE_TESTS="$STORE_TESTS tests/testUfs$EXEEXT"
     esac
@@ -733,6 +789,7 @@
 AH_TEMPLATE(HAVE_FS_AUFS, "Define to 1 if aufs filesystem module is build")
 AH_TEMPLATE(HAVE_FS_DISKD, "Define to 1 if diskd filesystem module is build")
 AH_TEMPLATE(HAVE_FS_COSS, "Define to 1 if coss filesystem module is build")
+AH_TEMPLATE(HAVE_FS_ROCK, "Define to 1 if rock filesystem module is build")
 
 
 dnl got final squid_storeio_module_candidates, build library lists
@@ -2297,6 +2354,7 @@
   sys/param.h \
   sys/prctl.h \
   sys/md5.h \
+  sys/mman.h \
   sys/msg.h \
   sys/resource.h \
   sys/select.h \
diff -u -r -N squid-3.2.0.12/doc/debug-sections.txt squid-3.2.0.13/doc/debug-sections.txt
--- squid-3.2.0.12/doc/debug-sections.txt	2011-09-16 23:37:30.000000000 +1200
+++ squid-3.2.0.13/doc/debug-sections.txt	2011-10-14 14:42:56.000000000 +1300
@@ -36,6 +36,7 @@
 section 17    Request Forwarding
 section 18    Cache Manager Statistics
 section 19    Store Memory Primitives
+section 20    Memory Cache
 section 20    Storage Manager
 section 20    Storage Manager Heap-based replacement
 section 20    Storage Manager Logging Functions
diff -u -r -N squid-3.2.0.12/errors/af/ERR_CACHE_ACCESS_DENIED squid-3.2.0.13/errors/af/ERR_CACHE_ACCESS_DENIED
--- squid-3.2.0.12/errors/af/ERR_CACHE_ACCESS_DENIED	2011-09-16 23:39:41.000000000 +1200
+++ squid-3.2.0.13/errors/af/ERR_CACHE_ACCESS_DENIED	2011-10-14 14:59:30.000000000 +1300
@@ -1 +1 @@
-<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd"> <html><head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8"> <title>FOUT: Cache Access Denied</title> <style type="text/css"><!--   %l  body :lang(fa) { direction: rtl; font-size: 100%; font-family: Tahoma, Roya, sans-serif; float: right; } :lang(he) { direction: rtl; }  --></style> </head><body id=%c> <div id="titles"> <h1>ERROR</h1> <h2>Cache Toegang geweier.</h2> </div> <hr>  <div id="content"> <p>Die volgende fout is teëgekom tydens verkryging van die URL: <a href="%U">%U</a></p>  <blockquote id="error"> <p><b>Toegang tot kasgeheue geweier.</b></p> </blockquote>  <p>Sorry, you are not currently allowed to request %U from this cache until you have authenticated yourself.</p>  <p>Please contact the <a href="mailto:%w%W">cache administrator</a> if you have difficulties authenticating yourself or <a href="http://%h/cgi-bin/chpasswd.cgi">change</a> your default password.</p>  <br> </div>  <hr>  <div id="footer"> <p>Gegenereer op %T deur %h (%s)</p> <!-- %c --> </div> </body></html> 
\ No newline at end of file
+<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd"> <html><head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8"> <title>FOUT: Cache Access Denied</title> <style type="text/css"><!--   %l  body :lang(fa) { direction: rtl; font-size: 100%; font-family: Tahoma, Roya, sans-serif; float: right; } :lang(he) { direction: rtl; }  --></style> </head><body id=%c> <div id="titles"> <h1>ERROR</h1> <h2>Cache Toegang geweier.</h2> </div> <hr>  <div id="content"> <p>Die volgende fout is teëgekom tydens verkryging van die URL: <a href="%U">%U</a></p>  <blockquote id="error"> <p><b>Toegang tot kasgeheue geweier.</b></p> </blockquote>  <p>Sorry, you are not currently allowed to request %U from this cache until you have authenticated yourself.</p>  <p>Please contact the <a href="mailto:%w%W">cache administrator</a> if you have difficulties authenticating yourself.</p>  <br> </div>  <hr>  <div id="footer"> <p>Gegenereer op %T deur %h (%s)</p> <!-- %c --> </div> </body></html> 
\ No newline at end of file
diff -u -r -N squid-3.2.0.12/errors/af/error-details.txt squid-3.2.0.13/errors/af/error-details.txt
--- squid-3.2.0.12/errors/af/error-details.txt	2011-09-16 23:39:59.000000000 +1200
+++ squid-3.2.0.13/errors/af/error-details.txt	2011-10-14 15:01:29.000000000 +1300
@@ -46,19 +46,19 @@
 detail: "%ssl_error_descr: %ssl_subject"
 descr: "CRL has expired"
 
-name: X509_V_ERR_FOUT_IN_CERT_NOT_BEFORE_FIELD
+name: X509_V_ERR_ERROR_IN_CERT_NOT_BEFORE_FIELD
 detail: "SSL Certificate has invalid start date (the 'not before' field): %ssl_subject"
 descr: "Format error in certificate's notBefore field"
 
-name: X509_V_ERR_FOUT_IN_CERT_NOT_AFTER_FIELD
+name: X509_V_ERR_ERROR_IN_CERT_NOT_AFTER_FIELD
 detail: "SSL Certificate has invalid expiration date (the 'not after' field): %ssl_subject"
 descr: "Format error in certificate's notAfter field"
 
-name: X509_V_ERR_FOUT_IN_CRL_LAST_UPDATE_FIELD
+name: X509_V_ERR_ERROR_IN_CRL_LAST_UPDATE_FIELD
 detail: "%ssl_error_descr: %ssl_subject"
 descr: "Format error in CRL's lastUpdate field"
 
-name: X509_V_ERR_FOUT_IN_CRL_NEXT_UPDATE_FIELD
+name: X509_V_ERR_ERROR_IN_CRL_NEXT_UPDATE_FIELD
 detail: "%ssl_error_descr: %ssl_subject"
 descr: "Format error in CRL's nextUpdate field"
 
diff -u -r -N squid-3.2.0.12/errors/ar/ERR_CACHE_ACCESS_DENIED squid-3.2.0.13/errors/ar/ERR_CACHE_ACCESS_DENIED
--- squid-3.2.0.12/errors/ar/ERR_CACHE_ACCESS_DENIED	2011-09-16 23:40:01.000000000 +1200
+++ squid-3.2.0.13/errors/ar/ERR_CACHE_ACCESS_DENIED	2011-10-14 15:01:46.000000000 +1300
@@ -1 +1 @@
-<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd"> <html><head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8"> <title>خطأ: Cache Access Denied</title> <style type="text/css"><!--   %l  body :lang(fa) { direction: rtl; font-size: 100%; font-family: Tahoma, Roya, sans-serif; float: right; } :lang(he) { direction: rtl; }  --></style> </head><body id=%c> <div id="titles"> <h1>ERROR</h1> <h2>Cache Access Denied.</h2> </div> <hr>  <div id="content"> <p>The following error was encountered while trying to retrieve the URL: <a href="%U">%U</a></p>  <blockquote id="error"> <p><b>Cache Access Denied.</b></p> </blockquote>  <p>Sorry, you are not currently allowed to request %U from this cache until you have authenticated yourself.</p>  <p>Please contact the <a href="mailto:%w%W">cache administrator</a> if you have difficulties authenticating yourself or <a href="http://%h/cgi-bin/chpasswd.cgi">change</a> your default password.</p>  <br> </div>  <hr>  <div id="footer"> <p>Generated %T by %h (%s)</p> <!-- %c --> </div> </body></html> 
\ No newline at end of file
+<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd"> <html><head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8"> <title>خطأ: Cache Access Denied</title> <style type="text/css"><!--   %l  body :lang(fa) { direction: rtl; font-size: 100%; font-family: Tahoma, Roya, sans-serif; float: right; } :lang(he) { direction: rtl; }  --></style> </head><body id=%c> <div id="titles"> <h1>ERROR</h1> <h2>Cache Access Denied.</h2> </div> <hr>  <div id="content"> <p>The following error was encountered while trying to retrieve the URL: <a href="%U">%U</a></p>  <blockquote id="error"> <p><b>Cache Access Denied.</b></p> </blockquote>  <p>Sorry, you are not currently allowed to request %U from this cache until you have authenticated yourself.</p>  <p>Please contact the <a href="mailto:%w%W">cache administrator</a> if you have difficulties authenticating yourself.</p>  <br> </div>  <hr>  <div id="footer"> <p>Generated %T by %h (%s)</p> <!-- %c --> </div> </body></html> 
\ No newline at end of file
diff -u -r -N squid-3.2.0.12/errors/ar/error-details.txt squid-3.2.0.13/errors/ar/error-details.txt
--- squid-3.2.0.12/errors/ar/error-details.txt	2011-09-16 23:40:18.000000000 +1200
+++ squid-3.2.0.13/errors/ar/error-details.txt	2011-10-14 15:04:09.000000000 +1300
@@ -46,19 +46,19 @@
 detail: "%ssl_error_descr: %ssl_subject"
 descr: "CRL has expired"
 
-name: X509_V_ERR_خطأ_IN_CERT_NOT_BEFORE_FIELD
+name: X509_V_ERR_ERROR_IN_CERT_NOT_BEFORE_FIELD
 detail: "SSL Certificate has invalid start date (the 'not before' field): %ssl_subject"
 descr: "Format error in certificate's notBefore field"
 
-name: X509_V_ERR_خطأ_IN_CERT_NOT_AFTER_FIELD
+name: X509_V_ERR_ERROR_IN_CERT_NOT_AFTER_FIELD
 detail: "SSL Certificate has invalid expiration date (the 'not after' field): %ssl_subject"
 descr: "Format error in certificate's notAfter field"
 
-name: X509_V_ERR_خطأ_IN_CRL_LAST_UPDATE_FIELD
+name: X509_V_ERR_ERROR_IN_CRL_LAST_UPDATE_FIELD
 detail: "%ssl_error_descr: %ssl_subject"
 descr: "Format error in CRL's lastUpdate field"
 
-name: X509_V_ERR_خطأ_IN_CRL_NEXT_UPDATE_FIELD
+name: X509_V_ERR_ERROR_IN_CRL_NEXT_UPDATE_FIELD
 detail: "%ssl_error_descr: %ssl_subject"
 descr: "Format error in CRL's nextUpdate field"
 
diff -u -r -N squid-3.2.0.12/errors/az/ERR_CACHE_ACCESS_DENIED squid-3.2.0.13/errors/az/ERR_CACHE_ACCESS_DENIED
--- squid-3.2.0.12/errors/az/ERR_CACHE_ACCESS_DENIED	2011-09-16 23:40:20.000000000 +1200
+++ squid-3.2.0.13/errors/az/ERR_CACHE_ACCESS_DENIED	2011-10-14 15:04:25.000000000 +1300
@@ -1 +1 @@
-<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd"> <html><head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8"> <title>SƏHV: Cache Access Denied</title> <style type="text/css"><!--   %l  body :lang(fa) { direction: rtl; font-size: 100%; font-family: Tahoma, Roya, sans-serif; float: right; } :lang(he) { direction: rtl; }  --></style> </head><body id=%c> <div id="titles"> <h1>ERROR</h1> <h2>Cache Giriş qadağandır.</h2> </div> <hr>  <div id="content"> <p>The following error was encountered while trying to retrieve the URL: <a href="%U">%U</a></p>  <blockquote id="error"> <p><b>Keşdən istifadə qadağandır</b></p> </blockquote>  <p>Sorry, you are not currently allowed to request %U from this cache until you have authenticated yourself.</p>  <p>İdentifikasiya ilə çətinlik olduğu halda, xahiş edirik, <a href="mailto:%w%W">KEŞİN sistem administratoru </a> ilə əlaqə saxlayın və ya <a href="http://%h/cgi-bin/chpasswd.cgi">şifrənizi</a> dəyişdirin.</p>  <br> </div>  <hr>  <div id="footer"> <p>Generated %T by %h (%s)</p> <!-- %c --> </div> </body></html> 
\ No newline at end of file
+<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd"> <html><head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8"> <title>SƏHV: Cache Access Denied</title> <style type="text/css"><!--   %l  body :lang(fa) { direction: rtl; font-size: 100%; font-family: Tahoma, Roya, sans-serif; float: right; } :lang(he) { direction: rtl; }  --></style> </head><body id=%c> <div id="titles"> <h1>ERROR</h1> <h2>Cache Giriş qadağandır.</h2> </div> <hr>  <div id="content"> <p>The following error was encountered while trying to retrieve the URL: <a href="%U">%U</a></p>  <blockquote id="error"> <p><b>Keşdən istifadə qadağandır</b></p> </blockquote>  <p>Sorry, you are not currently allowed to request %U from this cache until you have authenticated yourself.</p>  <p>Please contact the <a href="mailto:%w%W">cache administrator</a> if you have difficulties authenticating yourself.</p>  <br> </div>  <hr>  <div id="footer"> <p>Generated %T by %h (%s)</p> <!-- %c --> </div> </body></html> 
\ No newline at end of file
diff -u -r -N squid-3.2.0.12/errors/az/error-details.txt squid-3.2.0.13/errors/az/error-details.txt
--- squid-3.2.0.12/errors/az/error-details.txt	2011-09-16 23:40:38.000000000 +1200
+++ squid-3.2.0.13/errors/az/error-details.txt	2011-10-14 15:06:24.000000000 +1300
@@ -46,19 +46,19 @@
 detail: "%ssl_error_descr: %ssl_subject"
 descr: "CRL has expired"
 
-name: X509_V_ERR_SƏHV_IN_CERT_NOT_BEFORE_FIELD
+name: X509_V_ERR_ERROR_IN_CERT_NOT_BEFORE_FIELD
 detail: "SSL Certificate has invalid start date (the 'not before' field): %ssl_subject"
 descr: "Format error in certificate's notBefore field"
 
-name: X509_V_ERR_SƏHV_IN_CERT_NOT_AFTER_FIELD
+name: X509_V_ERR_ERROR_IN_CERT_NOT_AFTER_FIELD
 detail: "SSL Certificate has invalid expiration date (the 'not after' field): %ssl_subject"
 descr: "Format error in certificate's notAfter field"
 
-name: X509_V_ERR_SƏHV_IN_CRL_LAST_UPDATE_FIELD
+name: X509_V_ERR_ERROR_IN_CRL_LAST_UPDATE_FIELD
 detail: "%ssl_error_descr: %ssl_subject"
 descr: "Format error in CRL's lastUpdate field"
 
-name: X509_V_ERR_SƏHV_IN_CRL_NEXT_UPDATE_FIELD
+name: X509_V_ERR_ERROR_IN_CRL_NEXT_UPDATE_FIELD
 detail: "%ssl_error_descr: %ssl_subject"
 descr: "Format error in CRL's nextUpdate field"
 
diff -u -r -N squid-3.2.0.12/errors/bg/ERR_CACHE_ACCESS_DENIED squid-3.2.0.13/errors/bg/ERR_CACHE_ACCESS_DENIED
--- squid-3.2.0.12/errors/bg/ERR_CACHE_ACCESS_DENIED	2011-09-16 23:40:39.000000000 +1200
+++ squid-3.2.0.13/errors/bg/ERR_CACHE_ACCESS_DENIED	2011-10-14 15:06:35.000000000 +1300
@@ -1 +1 @@
-<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd"> <html><head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8"> <title>ГРЕШКА: Cache Access Denied</title> <style type="text/css"><!--   %l  body :lang(fa) { direction: rtl; font-size: 100%; font-family: Tahoma, Roya, sans-serif; float: right; } :lang(he) { direction: rtl; }  --></style> </head><body id=%c> <div id="titles"> <h1>ERROR</h1> <h2>Cache Отказан достъп</h2> </div> <hr>  <div id="content"> <p>Възникна следната грешка при опит за достъп до: <a href="%U">%U</a></p>  <blockquote id="error"> <p><b>Отказан достъп до кешираните данни.</b></p> </blockquote>  <p>Съжалявам, не Ви е позволен достъп до %U от този кеш докато не представите своето име и парола за достъп.</p>  <p>Моля обърнете се към <a href="mailto:%w%W">администратора</a> ако имате проблем с достъпа или <a href="http://%h/cgi-bin/chpasswd.cgi">сменете</a> паролата си.</p>  <br> </div>  <hr>  <div id="footer"> <p>Генерирано на %T от %h (%s)</p> <!-- %c --> </div> </body></html> 
\ No newline at end of file
+<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd"> <html><head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8"> <title>ГРЕШКА: Cache Access Denied</title> <style type="text/css"><!--   %l  body :lang(fa) { direction: rtl; font-size: 100%; font-family: Tahoma, Roya, sans-serif; float: right; } :lang(he) { direction: rtl; }  --></style> </head><body id=%c> <div id="titles"> <h1>ERROR</h1> <h2>Cache Отказан достъп</h2> </div> <hr>  <div id="content"> <p>Възникна следната грешка при опит за достъп до: <a href="%U">%U</a></p>  <blockquote id="error"> <p><b>Отказан достъп до кешираните данни.</b></p> </blockquote>  <p>Съжалявам, не Ви е позволен достъп до %U от този кеш докато не представите своето име и парола за достъп.</p>  <p>Please contact the <a href="mailto:%w%W">cache administrator</a> if you have difficulties authenticating yourself.</p>  <br> </div>  <hr>  <div id="footer"> <p>Генерирано на %T от %h (%s)</p> <!-- %c --> </div> </body></html> 
\ No newline at end of file
diff -u -r -N squid-3.2.0.12/errors/bg/error-details.txt squid-3.2.0.13/errors/bg/error-details.txt
--- squid-3.2.0.12/errors/bg/error-details.txt	2011-09-16 23:40:57.000000000 +1200
+++ squid-3.2.0.13/errors/bg/error-details.txt	2011-10-14 15:08:37.000000000 +1300
@@ -46,19 +46,19 @@
 detail: "%ssl_error_descr: %ssl_subject"
 descr: "CRL has expired"
 
-name: X509_V_ERR_ГРЕШКА_IN_CERT_NOT_BEFORE_FIELD
+name: X509_V_ERR_ERROR_IN_CERT_NOT_BEFORE_FIELD
 detail: "SSL Certificate has invalid start date (the 'not before' field): %ssl_subject"
 descr: "Format error in certificate's notBefore field"
 
-name: X509_V_ERR_ГРЕШКА_IN_CERT_NOT_AFTER_FIELD
+name: X509_V_ERR_ERROR_IN_CERT_NOT_AFTER_FIELD
 detail: "SSL Certificate has invalid expiration date (the 'not after' field): %ssl_subject"
 descr: "Format error in certificate's notAfter field"
 
-name: X509_V_ERR_ГРЕШКА_IN_CRL_LAST_UPDATE_FIELD
+name: X509_V_ERR_ERROR_IN_CRL_LAST_UPDATE_FIELD
 detail: "%ssl_error_descr: %ssl_subject"
 descr: "Format error in CRL's lastUpdate field"
 
-name: X509_V_ERR_ГРЕШКА_IN_CRL_NEXT_UPDATE_FIELD
+name: X509_V_ERR_ERROR_IN_CRL_NEXT_UPDATE_FIELD
 detail: "%ssl_error_descr: %ssl_subject"
 descr: "Format error in CRL's nextUpdate field"
 
diff -u -r -N squid-3.2.0.12/errors/ca/ERR_CACHE_ACCESS_DENIED squid-3.2.0.13/errors/ca/ERR_CACHE_ACCESS_DENIED
--- squid-3.2.0.12/errors/ca/ERR_CACHE_ACCESS_DENIED	2011-09-16 23:40:59.000000000 +1200
+++ squid-3.2.0.13/errors/ca/ERR_CACHE_ACCESS_DENIED	2011-10-14 15:08:48.000000000 +1300
@@ -1 +1 @@
-<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd"> <html><head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8"> <title>ERROR: Acc&eacute;s denegat a la cache</title> <style type="text/css"><!--   %l  body :lang(fa) { direction: rtl; font-size: 100%; font-family: Tahoma, Roya, sans-serif; float: right; } :lang(he) { direction: rtl; }  --></style> </head><body id=%c> <div id="titles"> <h1>ERROR</h1> <h2>Cache Acc&eacute;s no autoritzat.</h2> </div> <hr>  <div id="content"> <p>The following error was encountered while trying to retrieve the URL: <a href="%U">%U</a></p>  <blockquote id="error"> <p><b>Acc&eacute;s denegat a la cache</b></p> </blockquote>  <p>L'acc&eacute;s a l'objecte %U no est&agrave; perm&egrave;s sense autentificaci&oacute; pr&egrave;via.</p>  <p>Contacteu ambel vostre <a href="mailto:%w%W">administrador de <i>cache</i></a> si teniudificultats per a autentificar-vos o <a href="http://%h/cgi-bin/chpasswd.cgi">canvieu</a> la vostra contrasenya.</p>  <br> </div>  <hr>  <div id="footer"> <p>Generated %T by %h (%s)</p> <!-- %c --> </div> </body></html> 
\ No newline at end of file
+<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd"> <html><head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8"> <title>ERROR: Acc&eacute;s denegat a la cache</title> <style type="text/css"><!--   %l  body :lang(fa) { direction: rtl; font-size: 100%; font-family: Tahoma, Roya, sans-serif; float: right; } :lang(he) { direction: rtl; }  --></style> </head><body id=%c> <div id="titles"> <h1>ERROR</h1> <h2>Cache Acc&eacute;s no autoritzat.</h2> </div> <hr>  <div id="content"> <p>The following error was encountered while trying to retrieve the URL: <a href="%U">%U</a></p>  <blockquote id="error"> <p><b>Acc&eacute;s denegat a la cache</b></p> </blockquote>  <p>L'acc&eacute;s a l'objecte %U no est&agrave; perm&egrave;s sense autentificaci&oacute; pr&egrave;via.</p>  <p>Please contact the <a href="mailto:%w%W">cache administrator</a> if you have difficulties authenticating yourself.</p>  <br> </div>  <hr>  <div id="footer"> <p>Generated %T by %h (%s)</p> <!-- %c --> </div> </body></html> 
\ No newline at end of file
diff -u -r -N squid-3.2.0.12/errors/cs/ERR_CACHE_ACCESS_DENIED squid-3.2.0.13/errors/cs/ERR_CACHE_ACCESS_DENIED
--- squid-3.2.0.12/errors/cs/ERR_CACHE_ACCESS_DENIED	2011-09-16 23:41:18.000000000 +1200
+++ squid-3.2.0.13/errors/cs/ERR_CACHE_ACCESS_DENIED	2011-10-14 15:10:35.000000000 +1300
@@ -1 +1 @@
-<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd"> <html><head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8"> <title>CHYBA: Cache Access Denied</title> <style type="text/css"><!--   %l  body :lang(fa) { direction: rtl; font-size: 100%; font-family: Tahoma, Roya, sans-serif; float: right; } :lang(he) { direction: rtl; }  --></style> </head><body id=%c> <div id="titles"> <h1>ERROR</h1> <h2>Cache Přístup odepřen.</h2> </div> <hr>  <div id="content"> <p>The following error was encountered while trying to retrieve the URL: <a href="%U">%U</a></p>  <blockquote id="error"> <p><b>Přístup k cache odepřen.</b></p> </blockquote>  <p>Sorry, you are not currently allowed to request %U from this cache until you have authenticated yourself.</p>  <p>V případě problému se prosím obraťte na <a href="mailto:%w%W">cache administratora</a> nebo si změňte <a href="http://%h/cgi-bin/chpasswd.cgi">heslo</a>.</p>  <br> </div>  <hr>  <div id="footer"> <p>Generated %T by %h (%s)</p> <!-- %c --> </div> </body></html> 
\ No newline at end of file
+<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd"> <html><head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8"> <title>CHYBA: Cache Access Denied</title> <style type="text/css"><!--   %l  body :lang(fa) { direction: rtl; font-size: 100%; font-family: Tahoma, Roya, sans-serif; float: right; } :lang(he) { direction: rtl; }  --></style> </head><body id=%c> <div id="titles"> <h1>ERROR</h1> <h2>Cache Přístup odepřen.</h2> </div> <hr>  <div id="content"> <p>The following error was encountered while trying to retrieve the URL: <a href="%U">%U</a></p>  <blockquote id="error"> <p><b>Přístup k cache odepřen.</b></p> </blockquote>  <p>Sorry, you are not currently allowed to request %U from this cache until you have authenticated yourself.</p>  <p>Please contact the <a href="mailto:%w%W">cache administrator</a> if you have difficulties authenticating yourself.</p>  <br> </div>  <hr>  <div id="footer"> <p>Generated %T by %h (%s)</p> <!-- %c --> </div> </body></html> 
\ No newline at end of file
diff -u -r -N squid-3.2.0.12/errors/cs/error-details.txt squid-3.2.0.13/errors/cs/error-details.txt
--- squid-3.2.0.12/errors/cs/error-details.txt	2011-09-16 23:41:36.000000000 +1200
+++ squid-3.2.0.13/errors/cs/error-details.txt	2011-10-14 15:12:14.000000000 +1300
@@ -46,19 +46,19 @@
 detail: "%ssl_error_descr: %ssl_subject"
 descr: "CRL has expired"
 
-name: X509_V_ERR_CHYBA_IN_CERT_NOT_BEFORE_FIELD
+name: X509_V_ERR_ERROR_IN_CERT_NOT_BEFORE_FIELD
 detail: "SSL Certificate has invalid start date (the 'not before' field): %ssl_subject"
 descr: "Format error in certificate's notBefore field"
 
-name: X509_V_ERR_CHYBA_IN_CERT_NOT_AFTER_FIELD
+name: X509_V_ERR_ERROR_IN_CERT_NOT_AFTER_FIELD
 detail: "SSL Certificate has invalid expiration date (the 'not after' field): %ssl_subject"
 descr: "Format error in certificate's notAfter field"
 
-name: X509_V_ERR_CHYBA_IN_CRL_LAST_UPDATE_FIELD
+name: X509_V_ERR_ERROR_IN_CRL_LAST_UPDATE_FIELD
 detail: "%ssl_error_descr: %ssl_subject"
 descr: "Format error in CRL's lastUpdate field"
 
-name: X509_V_ERR_CHYBA_IN_CRL_NEXT_UPDATE_FIELD
+name: X509_V_ERR_ERROR_IN_CRL_NEXT_UPDATE_FIELD
 detail: "%ssl_error_descr: %ssl_subject"
 descr: "Format error in CRL's nextUpdate field"
 
diff -u -r -N squid-3.2.0.12/errors/da/ERR_CACHE_ACCESS_DENIED squid-3.2.0.13/errors/da/ERR_CACHE_ACCESS_DENIED
--- squid-3.2.0.12/errors/da/ERR_CACHE_ACCESS_DENIED	2011-09-16 23:41:38.000000000 +1200
+++ squid-3.2.0.13/errors/da/ERR_CACHE_ACCESS_DENIED	2011-10-14 15:12:24.000000000 +1300
@@ -1 +1 @@
-<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd"> <html><head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8"> <title>FEJL: Cache Access Denied</title> <style type="text/css"><!--   %l  body :lang(fa) { direction: rtl; font-size: 100%; font-family: Tahoma, Roya, sans-serif; float: right; } :lang(he) { direction: rtl; }  --></style> </head><body id=%c> <div id="titles"> <h1>ERROR</h1> <h2>Cache Adgang N&aelig;gtet.</h2> </div> <hr>  <div id="content"> <p>The following error was encountered while trying to retrieve the URL: <a href="%U">%U</a></p>  <blockquote id="error"> <p><b>Cache Adgang N&aelig;gtet.</b></p> </blockquote>  <p>Du har desv&aelig;rre ikke lov til at hente %U fra denne cache f&oslash;rend du har autenticieret dig selv.</p>  <p>Kontakt <a href="mailto:%w%W">cache administratoren</a> hvis du har problemer med at autenticiere dig eller <a href="http://%h/cgi-bin/chpasswd.cgi">skift</a> dit password.</p>  <br> </div>  <hr>  <div id="footer"> <p>Generated %T by %h (%s)</p> <!-- %c --> </div> </body></html> 
\ No newline at end of file
+<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd"> <html><head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8"> <title>FEJL: Cache Access Denied</title> <style type="text/css"><!--   %l  body :lang(fa) { direction: rtl; font-size: 100%; font-family: Tahoma, Roya, sans-serif; float: right; } :lang(he) { direction: rtl; }  --></style> </head><body id=%c> <div id="titles"> <h1>ERROR</h1> <h2>Cache Adgang N&aelig;gtet.</h2> </div> <hr>  <div id="content"> <p>The following error was encountered while trying to retrieve the URL: <a href="%U">%U</a></p>  <blockquote id="error"> <p><b>Cache Adgang N&aelig;gtet.</b></p> </blockquote>  <p>Du har desv&aelig;rre ikke lov til at hente %U fra denne cache f&oslash;rend du har autenticieret dig selv.</p>  <p>Please contact the <a href="mailto:%w%W">cache administrator</a> if you have difficulties authenticating yourself.</p>  <br> </div>  <hr>  <div id="footer"> <p>Generated %T by %h (%s)</p> <!-- %c --> </div> </body></html> 
\ No newline at end of file
diff -u -r -N squid-3.2.0.12/errors/da/error-details.txt squid-3.2.0.13/errors/da/error-details.txt
--- squid-3.2.0.12/errors/da/error-details.txt	2011-09-16 23:41:55.000000000 +1200
+++ squid-3.2.0.13/errors/da/error-details.txt	2011-10-14 15:13:41.000000000 +1300
@@ -46,19 +46,19 @@
 detail: "%ssl_error_descr: %ssl_subject"
 descr: "CRL has expired"
 
-name: X509_V_ERR_FEJL_IN_CERT_NOT_BEFORE_FIELD
+name: X509_V_ERR_ERROR_IN_CERT_NOT_BEFORE_FIELD
 detail: "SSL Certificate has invalid start date (the 'not before' field): %ssl_subject"
 descr: "Format error in certificate's notBefore field"
 
-name: X509_V_ERR_FEJL_IN_CERT_NOT_AFTER_FIELD
+name: X509_V_ERR_ERROR_IN_CERT_NOT_AFTER_FIELD
 detail: "SSL Certificate has invalid expiration date (the 'not after' field): %ssl_subject"
 descr: "Format error in certificate's notAfter field"
 
-name: X509_V_ERR_FEJL_IN_CRL_LAST_UPDATE_FIELD
+name: X509_V_ERR_ERROR_IN_CRL_LAST_UPDATE_FIELD
 detail: "%ssl_error_descr: %ssl_subject"
 descr: "Format error in CRL's lastUpdate field"
 
-name: X509_V_ERR_FEJL_IN_CRL_NEXT_UPDATE_FIELD
+name: X509_V_ERR_ERROR_IN_CRL_NEXT_UPDATE_FIELD
 detail: "%ssl_error_descr: %ssl_subject"
 descr: "Format error in CRL's nextUpdate field"
 
diff -u -r -N squid-3.2.0.12/errors/de/ERR_CACHE_ACCESS_DENIED squid-3.2.0.13/errors/de/ERR_CACHE_ACCESS_DENIED
--- squid-3.2.0.12/errors/de/ERR_CACHE_ACCESS_DENIED	2011-09-16 23:41:57.000000000 +1200
+++ squid-3.2.0.13/errors/de/ERR_CACHE_ACCESS_DENIED	2011-10-14 15:13:49.000000000 +1300
@@ -1 +1 @@
-<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd"> <html><head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8"> <title>FEHLER: Cache Access Denied</title> <style type="text/css"><!--   %l  body :lang(fa) { direction: rtl; font-size: 100%; font-family: Tahoma, Roya, sans-serif; float: right; } :lang(he) { direction: rtl; }  --></style> </head><body id=%c> <div id="titles"> <h1>ERROR</h1> <h2>Cache Zugriff verweigert.</h2> </div> <hr>  <div id="content"> <p>Der folgende Fehler wurde beim Versuch die URL <a href="%U">%U</a> zu holen festgestellt:</p>  <blockquote id="error"> <p><b>Cache Zugriff verweigert.</b></p> </blockquote>  <p>Sie sind momentan nicht berechtigt %U von diesem Cache abzurufen, bis sie sich authentifiziert haben.</p>  <p>Bitte kontaktieren sie den <a href="mailto:%w%W">Cache Administrator</a> Falls sie Schwierigkeiten haben sich zu authentifizieren oder <a href="http://%h/cgi-bin/chpasswd.cgi">ändern</a> sie ihr Standardpasswort.</p>  <br> </div>  <hr>  <div id="footer"> <p>Erzeugt am %T von %h (%s)</p> <!-- %c --> </div> </body></html> 
\ No newline at end of file
+<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd"> <html><head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8"> <title>FEHLER: Cache Access Denied</title> <style type="text/css"><!--   %l  body :lang(fa) { direction: rtl; font-size: 100%; font-family: Tahoma, Roya, sans-serif; float: right; } :lang(he) { direction: rtl; }  --></style> </head><body id=%c> <div id="titles"> <h1>ERROR</h1> <h2>Cache Zugriff verweigert.</h2> </div> <hr>  <div id="content"> <p>Der folgende Fehler wurde beim Versuch die URL <a href="%U">%U</a> zu holen festgestellt:</p>  <blockquote id="error"> <p><b>Cache Zugriff verweigert.</b></p> </blockquote>  <p>Sie sind momentan nicht berechtigt %U von diesem Cache abzurufen, bis sie sich authentifiziert haben.</p>  <p>Please contact the <a href="mailto:%w%W">cache administrator</a> if you have difficulties authenticating yourself.</p>  <br> </div>  <hr>  <div id="footer"> <p>Erzeugt am %T von %h (%s)</p> <!-- %c --> </div> </body></html> 
\ No newline at end of file
diff -u -r -N squid-3.2.0.12/errors/de/error-details.txt squid-3.2.0.13/errors/de/error-details.txt
--- squid-3.2.0.12/errors/de/error-details.txt	2011-09-16 23:42:14.000000000 +1200
+++ squid-3.2.0.13/errors/de/error-details.txt	2011-10-14 15:15:15.000000000 +1300
@@ -46,19 +46,19 @@
 detail: "%ssl_error_descr: %ssl_subject"
 descr: "CRL has expired"
 
-name: X509_V_ERR_FEHLER_IN_CERT_NOT_BEFORE_FIELD
+name: X509_V_ERR_ERROR_IN_CERT_NOT_BEFORE_FIELD
 detail: "SSL Certificate has invalid start date (the 'not before' field): %ssl_subject"
 descr: "Format error in certificate's notBefore field"
 
-name: X509_V_ERR_FEHLER_IN_CERT_NOT_AFTER_FIELD
+name: X509_V_ERR_ERROR_IN_CERT_NOT_AFTER_FIELD
 detail: "SSL Certificate has invalid expiration date (the 'not after' field): %ssl_subject"
 descr: "Format error in certificate's notAfter field"
 
-name: X509_V_ERR_FEHLER_IN_CRL_LAST_UPDATE_FIELD
+name: X509_V_ERR_ERROR_IN_CRL_LAST_UPDATE_FIELD
 detail: "%ssl_error_descr: %ssl_subject"
 descr: "Format error in CRL's lastUpdate field"
 
-name: X509_V_ERR_FEHLER_IN_CRL_NEXT_UPDATE_FIELD
+name: X509_V_ERR_ERROR_IN_CRL_NEXT_UPDATE_FIELD
 detail: "%ssl_error_descr: %ssl_subject"
 descr: "Format error in CRL's nextUpdate field"
 
diff -u -r -N squid-3.2.0.12/errors/el/ERR_CACHE_ACCESS_DENIED squid-3.2.0.13/errors/el/ERR_CACHE_ACCESS_DENIED
--- squid-3.2.0.12/errors/el/ERR_CACHE_ACCESS_DENIED	2011-09-16 23:42:16.000000000 +1200
+++ squid-3.2.0.13/errors/el/ERR_CACHE_ACCESS_DENIED	2011-10-14 15:15:27.000000000 +1300
@@ -1 +1 @@
-<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd"> <html><head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8"> <title>ΣΦΑΛΜΑ: Cache Access Denied</title> <style type="text/css"><!--   %l  body :lang(fa) { direction: rtl; font-size: 100%; font-family: Tahoma, Roya, sans-serif; float: right; } :lang(he) { direction: rtl; }  --></style> </head><body id=%c> <div id="titles"> <h1>ERROR</h1> <h2>Cache Απαγορεύεται η Πρόσβαση.</h2> </div> <hr>  <div id="content"> <p>The following error was encountered while trying to retrieve the URL: <a href="%U">%U</a></p>  <blockquote id="error"> <p><b>Απαγορεύεται η Πρόσβαση στο Μεσολαβητή.</b></p> </blockquote>  <p>Sorry, you are not currently allowed to request %U from this cache until you have authenticated yourself.</p>  <p>Επικοινωνήστε με τον <a href="mailto:%w%W">διαχειριστή του μεσολαβητή σας</a> αν αντιμετωπίζετε δυσκολία να πιστοποιήσετε τον λογαριασμό σας ή να <a href="http://%h/cgi-bin/chpasswd.cgi">αλλάξτε</a> τον κωδικό σας.</p>  <br> </div>  <hr>  <div id="footer"> <p>Generated %T by %h (%s)</p> <!-- %c --> </div> </body></html> 
\ No newline at end of file
+<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd"> <html><head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8"> <title>ΣΦΑΛΜΑ: Cache Access Denied</title> <style type="text/css"><!--   %l  body :lang(fa) { direction: rtl; font-size: 100%; font-family: Tahoma, Roya, sans-serif; float: right; } :lang(he) { direction: rtl; }  --></style> </head><body id=%c> <div id="titles"> <h1>ERROR</h1> <h2>Cache Απαγορεύεται η Πρόσβαση.</h2> </div> <hr>  <div id="content"> <p>The following error was encountered while trying to retrieve the URL: <a href="%U">%U</a></p>  <blockquote id="error"> <p><b>Απαγορεύεται η Πρόσβαση στο Μεσολαβητή.</b></p> </blockquote>  <p>Sorry, you are not currently allowed to request %U from this cache until you have authenticated yourself.</p>  <p>Please contact the <a href="mailto:%w%W">cache administrator</a> if you have difficulties authenticating yourself.</p>  <br> </div>  <hr>  <div id="footer"> <p>Generated %T by %h (%s)</p> <!-- %c --> </div> </body></html> 
\ No newline at end of file
diff -u -r -N squid-3.2.0.12/errors/el/error-details.txt squid-3.2.0.13/errors/el/error-details.txt
--- squid-3.2.0.12/errors/el/error-details.txt	2011-09-16 23:42:34.000000000 +1200
+++ squid-3.2.0.13/errors/el/error-details.txt	2011-10-14 15:17:23.000000000 +1300
@@ -46,19 +46,19 @@
 detail: "%ssl_error_descr: %ssl_subject"
 descr: "CRL has expired"
 
-name: X509_V_ERR_ΣΦΑΛΜΑ_IN_CERT_NOT_BEFORE_FIELD
+name: X509_V_ERR_ERROR_IN_CERT_NOT_BEFORE_FIELD
 detail: "SSL Certificate has invalid start date (the 'not before' field): %ssl_subject"
 descr: "Format error in certificate's notBefore field"
 
-name: X509_V_ERR_ΣΦΑΛΜΑ_IN_CERT_NOT_AFTER_FIELD
+name: X509_V_ERR_ERROR_IN_CERT_NOT_AFTER_FIELD
 detail: "SSL Certificate has invalid expiration date (the 'not after' field): %ssl_subject"
 descr: "Format error in certificate's notAfter field"
 
-name: X509_V_ERR_ΣΦΑΛΜΑ_IN_CRL_LAST_UPDATE_FIELD
+name: X509_V_ERR_ERROR_IN_CRL_LAST_UPDATE_FIELD
 detail: "%ssl_error_descr: %ssl_subject"
 descr: "Format error in CRL's lastUpdate field"
 
-name: X509_V_ERR_ΣΦΑΛΜΑ_IN_CRL_NEXT_UPDATE_FIELD
+name: X509_V_ERR_ERROR_IN_CRL_NEXT_UPDATE_FIELD
 detail: "%ssl_error_descr: %ssl_subject"
 descr: "Format error in CRL's nextUpdate field"
 
diff -u -r -N squid-3.2.0.12/errors/en/ERR_CACHE_ACCESS_DENIED squid-3.2.0.13/errors/en/ERR_CACHE_ACCESS_DENIED
--- squid-3.2.0.12/errors/en/ERR_CACHE_ACCESS_DENIED	2011-09-16 23:42:36.000000000 +1200
+++ squid-3.2.0.13/errors/en/ERR_CACHE_ACCESS_DENIED	2011-10-14 15:17:33.000000000 +1300
@@ -1 +1 @@
-<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd"> <html><head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8"> <title>ERROR: Cache Access Denied</title> <style type="text/css"><!--   %l  body :lang(fa) { direction: rtl; font-size: 100%; font-family: Tahoma, Roya, sans-serif; float: right; } :lang(he) { direction: rtl; }  --></style> </head><body id=%c> <div id="titles"> <h1>ERROR</h1> <h2>Cache Access Denied.</h2> </div> <hr>  <div id="content"> <p>The following error was encountered while trying to retrieve the URL: <a href="%U">%U</a></p>  <blockquote id="error"> <p><b>Cache Access Denied.</b></p> </blockquote>  <p>Sorry, you are not currently allowed to request %U from this cache until you have authenticated yourself.</p>  <p>Please contact the <a href="mailto:%w%W">cache administrator</a> if you have difficulties authenticating yourself or <a href="http://%h/cgi-bin/chpasswd.cgi">change</a> your default password.</p>  <br> </div>  <hr>  <div id="footer"> <p>Generated %T by %h (%s)</p> <!-- %c --> </div> </body></html> 
\ No newline at end of file
+<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd"> <html><head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8"> <title>ERROR: Cache Access Denied</title> <style type="text/css"><!--   %l  body :lang(fa) { direction: rtl; font-size: 100%; font-family: Tahoma, Roya, sans-serif; float: right; } :lang(he) { direction: rtl; }  --></style> </head><body id=%c> <div id="titles"> <h1>ERROR</h1> <h2>Cache Access Denied.</h2> </div> <hr>  <div id="content"> <p>The following error was encountered while trying to retrieve the URL: <a href="%U">%U</a></p>  <blockquote id="error"> <p><b>Cache Access Denied.</b></p> </blockquote>  <p>Sorry, you are not currently allowed to request %U from this cache until you have authenticated yourself.</p>  <p>Please contact the <a href="mailto:%w%W">cache administrator</a> if you have difficulties authenticating yourself.</p>  <br> </div>  <hr>  <div id="footer"> <p>Generated %T by %h (%s)</p> <!-- %c --> </div> </body></html> 
\ No newline at end of file
diff -u -r -N squid-3.2.0.12/errors/es/ERR_CACHE_ACCESS_DENIED squid-3.2.0.13/errors/es/ERR_CACHE_ACCESS_DENIED
--- squid-3.2.0.12/errors/es/ERR_CACHE_ACCESS_DENIED	2011-09-16 23:42:55.000000000 +1200
+++ squid-3.2.0.13/errors/es/ERR_CACHE_ACCESS_DENIED	2011-10-14 15:18:53.000000000 +1300
@@ -1 +1 @@
-<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd"> <html><head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8"> <title>ERROR: Acceso Denegado a la Caché</title> <style type="text/css"><!--   %l  body :lang(fa) { direction: rtl; font-size: 100%; font-family: Tahoma, Roya, sans-serif; float: right; } :lang(he) { direction: rtl; }  --></style> </head><body id=%c> <div id="titles"> <h1>ERROR</h1> <h2>Cache Acceso Denegado</h2> </div> <hr>  <div id="content"> <p>Se encontró el siguiente error al intentar recuperar la dirección URL: <a href="%U">%U</a></p>  <blockquote id="error"> <p><b>Acceso Denegado a la Caché</b></p> </blockquote>  <p>Lo lamento, tu no estás autorizado a solicitar %U de este caché hasta que te hayas autenticado.</p>  <p>Por favor contacte al <a href="mailto:%w%W">administrador del cach&eacute;</a> si tiene dificultad para autenticarse o <a href="http://%h/cgi-bin/chpasswd.cgi">cambie</a> su password.</p>  <br> </div>  <hr>  <div id="footer"> <p>Generado %T por %h (%s)</p> <!-- %c --> </div> </body></html> 
\ No newline at end of file
+<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd"> <html><head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8"> <title>ERROR: Acceso Denegado a la Caché</title> <style type="text/css"><!--   %l  body :lang(fa) { direction: rtl; font-size: 100%; font-family: Tahoma, Roya, sans-serif; float: right; } :lang(he) { direction: rtl; }  --></style> </head><body id=%c> <div id="titles"> <h1>ERROR</h1> <h2>Cache Acceso Denegado</h2> </div> <hr>  <div id="content"> <p>Se encontró el siguiente error al intentar recuperar la dirección URL: <a href="%U">%U</a></p>  <blockquote id="error"> <p><b>Acceso Denegado a la Caché</b></p> </blockquote>  <p>Lo lamento, tu no estás autorizado a solicitar %U de este caché hasta que te hayas autenticado.</p>  <p>Please contact the <a href="mailto:%w%W">cache administrator</a> if you have difficulties authenticating yourself.</p>  <br> </div>  <hr>  <div id="footer"> <p>Generado %T por %h (%s)</p> <!-- %c --> </div> </body></html> 
\ No newline at end of file
diff -u -r -N squid-3.2.0.12/errors/et/ERR_CACHE_ACCESS_DENIED squid-3.2.0.13/errors/et/ERR_CACHE_ACCESS_DENIED
--- squid-3.2.0.12/errors/et/ERR_CACHE_ACCESS_DENIED	2011-09-16 23:43:14.000000000 +1200
+++ squid-3.2.0.13/errors/et/ERR_CACHE_ACCESS_DENIED	2011-10-14 15:20:55.000000000 +1300
@@ -1 +1 @@
-<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd"> <html><head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8"> <title>VIGA: Cache Access Denied</title> <style type="text/css"><!--   %l  body :lang(fa) { direction: rtl; font-size: 100%; font-family: Tahoma, Roya, sans-serif; float: right; } :lang(he) { direction: rtl; }  --></style> </head><body id=%c> <div id="titles"> <h1>ERROR</h1> <h2>Cache Juurdep&auml;&auml;s keelatud.</h2> </div> <hr>  <div id="content"> <p>The following error was encountered while trying to retrieve the URL: <a href="%U">%U</a></p>  <blockquote id="error"> <p><b>Vahemälu serveri kasutamine keelatud.</b></p> </blockquote>  <p>abandust, teil pole &otilde;igust p&auml;ringule %U kuni te pole l&auml;binud autoriseerimist.</p>  <p>Palun kontakteeruge <a href="mailto:%w%W">vahemälu serveri administraatoriga</a>, kui teil on probleeme autoriseerimisega v&otilde;i<a href="http://%h/cgi-bin/chpasswd.cgi">vahetage</a> oma parool.</p>  <br> </div>  <hr>  <div id="footer"> <p>Generated %T by %h (%s)</p> <!-- %c --> </div> </body></html> 
\ No newline at end of file
+<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd"> <html><head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8"> <title>VIGA: Cache Access Denied</title> <style type="text/css"><!--   %l  body :lang(fa) { direction: rtl; font-size: 100%; font-family: Tahoma, Roya, sans-serif; float: right; } :lang(he) { direction: rtl; }  --></style> </head><body id=%c> <div id="titles"> <h1>ERROR</h1> <h2>Cache Juurdep&auml;&auml;s keelatud.</h2> </div> <hr>  <div id="content"> <p>The following error was encountered while trying to retrieve the URL: <a href="%U">%U</a></p>  <blockquote id="error"> <p><b>Vahemälu serveri kasutamine keelatud.</b></p> </blockquote>  <p>abandust, teil pole &otilde;igust p&auml;ringule %U kuni te pole l&auml;binud autoriseerimist.</p>  <p>Please contact the <a href="mailto:%w%W">cache administrator</a> if you have difficulties authenticating yourself.</p>  <br> </div>  <hr>  <div id="footer"> <p>Generated %T by %h (%s)</p> <!-- %c --> </div> </body></html> 
\ No newline at end of file
diff -u -r -N squid-3.2.0.12/errors/et/error-details.txt squid-3.2.0.13/errors/et/error-details.txt
--- squid-3.2.0.12/errors/et/error-details.txt	2011-09-16 23:43:32.000000000 +1200
+++ squid-3.2.0.13/errors/et/error-details.txt	2011-10-14 15:22:55.000000000 +1300
@@ -46,19 +46,19 @@
 detail: "%ssl_error_descr: %ssl_subject"
 descr: "CRL has expired"
 
-name: X509_V_ERR_VIGA_IN_CERT_NOT_BEFORE_FIELD
+name: X509_V_ERR_ERROR_IN_CERT_NOT_BEFORE_FIELD
 detail: "SSL Certificate has invalid start date (the 'not before' field): %ssl_subject"
 descr: "Format error in certificate's notBefore field"
 
-name: X509_V_ERR_VIGA_IN_CERT_NOT_AFTER_FIELD
+name: X509_V_ERR_ERROR_IN_CERT_NOT_AFTER_FIELD
 detail: "SSL Certificate has invalid expiration date (the 'not after' field): %ssl_subject"
 descr: "Format error in certificate's notAfter field"
 
-name: X509_V_ERR_VIGA_IN_CRL_LAST_UPDATE_FIELD
+name: X509_V_ERR_ERROR_IN_CRL_LAST_UPDATE_FIELD
 detail: "%ssl_error_descr: %ssl_subject"
 descr: "Format error in CRL's lastUpdate field"
 
-name: X509_V_ERR_VIGA_IN_CRL_NEXT_UPDATE_FIELD
+name: X509_V_ERR_ERROR_IN_CRL_NEXT_UPDATE_FIELD
 detail: "%ssl_error_descr: %ssl_subject"
 descr: "Format error in CRL's nextUpdate field"
 
diff -u -r -N squid-3.2.0.12/errors/fa/ERR_CACHE_ACCESS_DENIED squid-3.2.0.13/errors/fa/ERR_CACHE_ACCESS_DENIED
--- squid-3.2.0.12/errors/fa/ERR_CACHE_ACCESS_DENIED	2011-09-16 23:43:34.000000000 +1200
+++ squid-3.2.0.13/errors/fa/ERR_CACHE_ACCESS_DENIED	2011-10-14 15:23:06.000000000 +1300
@@ -1 +1 @@
-<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd"> <html><head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8"> <title>خطا: Cache Access Denied</title> <style type="text/css"><!--   %l  body :lang(fa) { direction: rtl; font-size: 100%; font-family: Tahoma, Roya, sans-serif; float: right; } :lang(he) { direction: rtl; }  --></style> </head><body id=%c> <div id="titles"> <h1>ERROR</h1> <h2>Cache دسترسی رد شد.</h2> </div> <hr>  <div id="content"> <p>The following error was encountered while trying to retrieve the URL: <a href="%U">%U</a></p>  <blockquote id="error"> <p><b>دسترسی به نهانگاه رد شد.</b></p> </blockquote>  <p>Sorry, you are not currently allowed to request %U from this cache until you have authenticated yourself.</p>  <p>لطفا در صورت داشتن مشکلاتی در زمینه شناسایی خودتان با <a href="mailto:%w%W">cache administrator</a> تماس حاصل فرمایید یا از طریق <a href="http://%h/cgi-bin/chpasswd.cgi">تغییر</a> رمز خود مشکل را حل نمایید.</p>  <br> </div>  <hr>  <div id="footer"> <p>%T توسط %h(%s) تولید شد.</p> <!-- %c --> </div> </body></html> 
\ No newline at end of file
+<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd"> <html><head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8"> <title>خطا: Cache Access Denied</title> <style type="text/css"><!--   %l  body :lang(fa) { direction: rtl; font-size: 100%; font-family: Tahoma, Roya, sans-serif; float: right; } :lang(he) { direction: rtl; }  --></style> </head><body id=%c> <div id="titles"> <h1>ERROR</h1> <h2>Cache دسترسی رد شد.</h2> </div> <hr>  <div id="content"> <p>The following error was encountered while trying to retrieve the URL: <a href="%U">%U</a></p>  <blockquote id="error"> <p><b>دسترسی به نهانگاه رد شد.</b></p> </blockquote>  <p>Sorry, you are not currently allowed to request %U from this cache until you have authenticated yourself.</p>  <p>Please contact the <a href="mailto:%w%W">cache administrator</a> if you have difficulties authenticating yourself.</p>  <br> </div>  <hr>  <div id="footer"> <p>%T توسط %h(%s) تولید شد.</p> <!-- %c --> </div> </body></html> 
\ No newline at end of file
diff -u -r -N squid-3.2.0.12/errors/fa/error-details.txt squid-3.2.0.13/errors/fa/error-details.txt
--- squid-3.2.0.12/errors/fa/error-details.txt	2011-09-16 23:43:52.000000000 +1200
+++ squid-3.2.0.13/errors/fa/error-details.txt	2011-10-14 15:24:44.000000000 +1300
@@ -46,19 +46,19 @@
 detail: "%ssl_error_descr: %ssl_subject"
 descr: "CRL has expired"
 
-name: X509_V_ERR_خطا_IN_CERT_NOT_BEFORE_FIELD
+name: X509_V_ERR_ERROR_IN_CERT_NOT_BEFORE_FIELD
 detail: "SSL Certificate has invalid start date (the 'not before' field): %ssl_subject"
 descr: "Format error in certificate's notBefore field"
 
-name: X509_V_ERR_خطا_IN_CERT_NOT_AFTER_FIELD
+name: X509_V_ERR_ERROR_IN_CERT_NOT_AFTER_FIELD
 detail: "SSL Certificate has invalid expiration date (the 'not after' field): %ssl_subject"
 descr: "Format error in certificate's notAfter field"
 
-name: X509_V_ERR_خطا_IN_CRL_LAST_UPDATE_FIELD
+name: X509_V_ERR_ERROR_IN_CRL_LAST_UPDATE_FIELD
 detail: "%ssl_error_descr: %ssl_subject"
 descr: "Format error in CRL's lastUpdate field"
 
-name: X509_V_ERR_خطا_IN_CRL_NEXT_UPDATE_FIELD
+name: X509_V_ERR_ERROR_IN_CRL_NEXT_UPDATE_FIELD
 detail: "%ssl_error_descr: %ssl_subject"
 descr: "Format error in CRL's nextUpdate field"
 
diff -u -r -N squid-3.2.0.12/errors/fi/ERR_CACHE_ACCESS_DENIED squid-3.2.0.13/errors/fi/ERR_CACHE_ACCESS_DENIED
--- squid-3.2.0.12/errors/fi/ERR_CACHE_ACCESS_DENIED	2011-09-16 23:43:53.000000000 +1200
+++ squid-3.2.0.13/errors/fi/ERR_CACHE_ACCESS_DENIED	2011-10-14 15:24:55.000000000 +1300
@@ -1 +1 @@
-<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd"> <html><head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8"> <title>VIRHE: Cache Access Denied</title> <style type="text/css"><!--   %l  body :lang(fa) { direction: rtl; font-size: 100%; font-family: Tahoma, Roya, sans-serif; float: right; } :lang(he) { direction: rtl; }  --></style> </head><body id=%c> <div id="titles"> <h1>ERROR</h1> <h2>Cache Pääsy evätty.</h2> </div> <hr>  <div id="content"> <p>The following error was encountered while trying to retrieve the URL: <a href="%U">%U</a></p>  <blockquote id="error"> <p><b>Pääsy välityspalvelimeen evätty.</b></p> </blockquote>  <p>Sinulla ei tällä hetkellä ole oikeutta pyytää osoitetta %U tästä välityspalvelimesta ennen kuin olet todentanut henkilöllisyytesi.</p>  <p>Jos sinulla on hankaluuksia hekilöllisyytesi todentamisessa, ota yhteyttä <a href="mailto:%w%W">välityspalvelimen ylläpitoon</a> tai <a href="http://%h/cgi-bin/chpasswd.cgi">vaihda</a> oletussalasanasi.</p>  <br> </div>  <hr>  <div id="footer"> <p>Generated %T by %h (%s)</p> <!-- %c --> </div> </body></html> 
\ No newline at end of file
+<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd"> <html><head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8"> <title>VIRHE: Cache Access Denied</title> <style type="text/css"><!--   %l  body :lang(fa) { direction: rtl; font-size: 100%; font-family: Tahoma, Roya, sans-serif; float: right; } :lang(he) { direction: rtl; }  --></style> </head><body id=%c> <div id="titles"> <h1>ERROR</h1> <h2>Cache Pääsy evätty.</h2> </div> <hr>  <div id="content"> <p>The following error was encountered while trying to retrieve the URL: <a href="%U">%U</a></p>  <blockquote id="error"> <p><b>Pääsy välityspalvelimeen evätty.</b></p> </blockquote>  <p>Sinulla ei tällä hetkellä ole oikeutta pyytää osoitetta %U tästä välityspalvelimesta ennen kuin olet todentanut henkilöllisyytesi.</p>  <p>Please contact the <a href="mailto:%w%W">cache administrator</a> if you have difficulties authenticating yourself.</p>  <br> </div>  <hr>  <div id="footer"> <p>Generated %T by %h (%s)</p> <!-- %c --> </div> </body></html> 
\ No newline at end of file
diff -u -r -N squid-3.2.0.12/errors/fi/error-details.txt squid-3.2.0.13/errors/fi/error-details.txt
--- squid-3.2.0.12/errors/fi/error-details.txt	2011-09-16 23:44:11.000000000 +1200
+++ squid-3.2.0.13/errors/fi/error-details.txt	2011-10-14 15:26:48.000000000 +1300
@@ -46,19 +46,19 @@
 detail: "%ssl_error_descr: %ssl_subject"
 descr: "CRL has expired"
 
-name: X509_V_ERR_VIRHE_IN_CERT_NOT_BEFORE_FIELD
+name: X509_V_ERR_ERROR_IN_CERT_NOT_BEFORE_FIELD
 detail: "SSL Certificate has invalid start date (the 'not before' field): %ssl_subject"
 descr: "Format error in certificate's notBefore field"
 
-name: X509_V_ERR_VIRHE_IN_CERT_NOT_AFTER_FIELD
+name: X509_V_ERR_ERROR_IN_CERT_NOT_AFTER_FIELD
 detail: "SSL Certificate has invalid expiration date (the 'not after' field): %ssl_subject"
 descr: "Format error in certificate's notAfter field"
 
-name: X509_V_ERR_VIRHE_IN_CRL_LAST_UPDATE_FIELD
+name: X509_V_ERR_ERROR_IN_CRL_LAST_UPDATE_FIELD
 detail: "%ssl_error_descr: %ssl_subject"
 descr: "Format error in CRL's lastUpdate field"
 
-name: X509_V_ERR_VIRHE_IN_CRL_NEXT_UPDATE_FIELD
+name: X509_V_ERR_ERROR_IN_CRL_NEXT_UPDATE_FIELD
 detail: "%ssl_error_descr: %ssl_subject"
 descr: "Format error in CRL's nextUpdate field"
 
diff -u -r -N squid-3.2.0.12/errors/fr/ERR_CACHE_ACCESS_DENIED squid-3.2.0.13/errors/fr/ERR_CACHE_ACCESS_DENIED
--- squid-3.2.0.12/errors/fr/ERR_CACHE_ACCESS_DENIED	2011-09-16 23:44:13.000000000 +1200
+++ squid-3.2.0.13/errors/fr/ERR_CACHE_ACCESS_DENIED	2011-10-14 15:27:04.000000000 +1300
@@ -1 +1 @@
-<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd"> <html><head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8"> <title>ERREUR: Cache Access Denied</title> <style type="text/css"><!--   %l  body :lang(fa) { direction: rtl; font-size: 100%; font-family: Tahoma, Roya, sans-serif; float: right; } :lang(he) { direction: rtl; }  --></style> </head><body id=%c> <div id="titles"> <h1>ERROR</h1> <h2>Cache Accès interdit.</h2> </div> <hr>  <div id="content"> <p>L'erreur suivante s'est produite en essayant d'accéder à l'URL : <a href="%U">%U</a></p>  <blockquote id="error"> <p><b>Accès au cache interdit.</b></p> </blockquote>  <p>Désolé, vous n'êtes pas autorisé à demander la requête %U de ce cache tant que vous ne vous serez pas identifié.</p>  <p>S'il vous plait, contacter <a href="mailto:%w%W">l'administrateur du proxy</a> si vous avez des difficultés pour vous authentifier ou pour <a href="http://%h/cgi-bin/chpasswd.cgi">changez</a> votre mot de passe par défaut.</p>  <br> </div>  <hr>  <div id="footer"> <p>Générer le %T en %h (%s)</p> <!-- %c --> </div> </body></html> 
\ No newline at end of file
+<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd"> <html><head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8"> <title>ERREUR: Cache Access Denied</title> <style type="text/css"><!--   %l  body :lang(fa) { direction: rtl; font-size: 100%; font-family: Tahoma, Roya, sans-serif; float: right; } :lang(he) { direction: rtl; }  --></style> </head><body id=%c> <div id="titles"> <h1>ERROR</h1> <h2>Cache Accès interdit.</h2> </div> <hr>  <div id="content"> <p>L'erreur suivante s'est produite en essayant d'accéder à l'URL : <a href="%U">%U</a></p>  <blockquote id="error"> <p><b>Accès au cache interdit.</b></p> </blockquote>  <p>Désolé, vous n'êtes pas autorisé à demander la requête %U de ce cache tant que vous ne vous serez pas identifié.</p>  <p>Please contact the <a href="mailto:%w%W">cache administrator</a> if you have difficulties authenticating yourself.</p>  <br> </div>  <hr>  <div id="footer"> <p>Générer le %T en %h (%s)</p> <!-- %c --> </div> </body></html> 
\ No newline at end of file
diff -u -r -N squid-3.2.0.12/errors/fr/error-details.txt squid-3.2.0.13/errors/fr/error-details.txt
--- squid-3.2.0.12/errors/fr/error-details.txt	2011-09-16 23:44:30.000000000 +1200
+++ squid-3.2.0.13/errors/fr/error-details.txt	2011-10-14 15:28:55.000000000 +1300
@@ -46,19 +46,19 @@
 detail: "%ssl_error_descr: %ssl_subject"
 descr: "CRL has expired"
 
-name: X509_V_ERR_ERREUR_IN_CERT_NOT_BEFORE_FIELD
+name: X509_V_ERR_ERROR_IN_CERT_NOT_BEFORE_FIELD
 detail: "SSL Certificate has invalid start date (the 'not before' field): %ssl_subject"
 descr: "Format error in certificate's notBefore field"
 
-name: X509_V_ERR_ERREUR_IN_CERT_NOT_AFTER_FIELD
+name: X509_V_ERR_ERROR_IN_CERT_NOT_AFTER_FIELD
 detail: "SSL Certificate has invalid expiration date (the 'not after' field): %ssl_subject"
 descr: "Format error in certificate's notAfter field"
 
-name: X509_V_ERR_ERREUR_IN_CRL_LAST_UPDATE_FIELD
+name: X509_V_ERR_ERROR_IN_CRL_LAST_UPDATE_FIELD
 detail: "%ssl_error_descr: %ssl_subject"
 descr: "Format error in CRL's lastUpdate field"
 
-name: X509_V_ERR_ERREUR_IN_CRL_NEXT_UPDATE_FIELD
+name: X509_V_ERR_ERROR_IN_CRL_NEXT_UPDATE_FIELD
 detail: "%ssl_error_descr: %ssl_subject"
 descr: "Format error in CRL's nextUpdate field"
 
diff -u -r -N squid-3.2.0.12/errors/he/ERR_CACHE_ACCESS_DENIED squid-3.2.0.13/errors/he/ERR_CACHE_ACCESS_DENIED
--- squid-3.2.0.12/errors/he/ERR_CACHE_ACCESS_DENIED	2011-09-16 23:44:32.000000000 +1200
+++ squid-3.2.0.13/errors/he/ERR_CACHE_ACCESS_DENIED	2011-10-14 15:29:07.000000000 +1300
@@ -1 +1 @@
-<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd"> <html><head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8"> <title>שגיאה: Cache Access Denied</title> <style type="text/css"><!--   %l  body :lang(fa) { direction: rtl; font-size: 100%; font-family: Tahoma, Roya, sans-serif; float: right; } :lang(he) { direction: rtl; }  --></style> </head><body id=%c> <div id="titles"> <h1>ERROR</h1> <h2>Cache הגישה נדחית</h2> </div> <hr>  <div id="content"> <p>The following error was encountered while trying to retrieve the URL: <a href="%U">%U</a></p>  <blockquote id="error"> <p><b>גישה ל-Cache נדחית</b></p> </blockquote>  <p>Sorry, you are not currently allowed to request %U from this cache until you have authenticated yourself.</p>  <p>Please contact the <a href="mailto:%w%W">cache administrator</a> if you have difficulties authenticating yourself or <a href="http://%h/cgi-bin/chpasswd.cgi">change</a> your default password.</p>  <br> </div>  <hr>  <div id="footer"> <p>Generated %T by %h (%s)</p> <!-- %c --> </div> </body></html> 
\ No newline at end of file
+<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd"> <html><head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8"> <title>שגיאה: Cache Access Denied</title> <style type="text/css"><!--   %l  body :lang(fa) { direction: rtl; font-size: 100%; font-family: Tahoma, Roya, sans-serif; float: right; } :lang(he) { direction: rtl; }  --></style> </head><body id=%c> <div id="titles"> <h1>ERROR</h1> <h2>Cache הגישה נדחית</h2> </div> <hr>  <div id="content"> <p>The following error was encountered while trying to retrieve the URL: <a href="%U">%U</a></p>  <blockquote id="error"> <p><b>גישה ל-Cache נדחית</b></p> </blockquote>  <p>Sorry, you are not currently allowed to request %U from this cache until you have authenticated yourself.</p>  <p>Please contact the <a href="mailto:%w%W">cache administrator</a> if you have difficulties authenticating yourself.</p>  <br> </div>  <hr>  <div id="footer"> <p>Generated %T by %h (%s)</p> <!-- %c --> </div> </body></html> 
\ No newline at end of file
diff -u -r -N squid-3.2.0.12/errors/he/error-details.txt squid-3.2.0.13/errors/he/error-details.txt
--- squid-3.2.0.12/errors/he/error-details.txt	2011-09-16 23:44:49.000000000 +1200
+++ squid-3.2.0.13/errors/he/error-details.txt	2011-10-14 15:30:40.000000000 +1300
@@ -46,19 +46,19 @@
 detail: "%ssl_error_descr: %ssl_subject"
 descr: "CRL has expired"
 
-name: X509_V_ERR_שגיאה_IN_CERT_NOT_BEFORE_FIELD
+name: X509_V_ERR_ERROR_IN_CERT_NOT_BEFORE_FIELD
 detail: "SSL Certificate has invalid start date (the 'not before' field): %ssl_subject"
 descr: "Format error in certificate's notBefore field"
 
-name: X509_V_ERR_שגיאה_IN_CERT_NOT_AFTER_FIELD
+name: X509_V_ERR_ERROR_IN_CERT_NOT_AFTER_FIELD
 detail: "SSL Certificate has invalid expiration date (the 'not after' field): %ssl_subject"
 descr: "Format error in certificate's notAfter field"
 
-name: X509_V_ERR_שגיאה_IN_CRL_LAST_UPDATE_FIELD
+name: X509_V_ERR_ERROR_IN_CRL_LAST_UPDATE_FIELD
 detail: "%ssl_error_descr: %ssl_subject"
 descr: "Format error in CRL's lastUpdate field"
 
-name: X509_V_ERR_שגיאה_IN_CRL_NEXT_UPDATE_FIELD
+name: X509_V_ERR_ERROR_IN_CRL_NEXT_UPDATE_FIELD
 detail: "%ssl_error_descr: %ssl_subject"
 descr: "Format error in CRL's nextUpdate field"
 
diff -u -r -N squid-3.2.0.12/errors/hu/ERR_CACHE_ACCESS_DENIED squid-3.2.0.13/errors/hu/ERR_CACHE_ACCESS_DENIED
--- squid-3.2.0.12/errors/hu/ERR_CACHE_ACCESS_DENIED	2011-09-16 23:44:51.000000000 +1200
+++ squid-3.2.0.13/errors/hu/ERR_CACHE_ACCESS_DENIED	2011-10-14 15:30:50.000000000 +1300
@@ -1 +1 @@
-<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd"> <html><head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8"> <title>HIBA: Cache Access Denied</title> <style type="text/css"><!--   %l  body :lang(fa) { direction: rtl; font-size: 100%; font-family: Tahoma, Roya, sans-serif; float: right; } :lang(he) { direction: rtl; }  --></style> </head><body id=%c> <div id="titles"> <h1>ERROR</h1> <h2>Cache Hozzáférés megtagadva.</h2> </div> <hr>  <div id="content"> <p>The following error was encountered while trying to retrieve the URL: <a href="%U">%U</a></p>  <blockquote id="error"> <p><b>Cache hozzáférés megtagadva.</b></p> </blockquote>  <p>Sajnos az alábbi URL-t nem töltheti le cache szerverünktől %U amíg nem jelentkezik be rendszerünkbe.</p>  <p>Kérjük, forduljon a <a href="mailto:%w%W">cache adminisztrátorhoz</a> amennyiben nem sikerül bejelentkeznie vagy <a ref="http://%h/cgi-bin/chpasswd.cgi">megváltoztatnia</a>eredetileg beállított jelszavát.</p>  <br> </div>  <hr>  <div id="footer"> <p>Generated %T by %h (%s)</p> <!-- %c --> </div> </body></html> 
\ No newline at end of file
+<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd"> <html><head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8"> <title>HIBA: Cache Access Denied</title> <style type="text/css"><!--   %l  body :lang(fa) { direction: rtl; font-size: 100%; font-family: Tahoma, Roya, sans-serif; float: right; } :lang(he) { direction: rtl; }  --></style> </head><body id=%c> <div id="titles"> <h1>ERROR</h1> <h2>Cache Hozzáférés megtagadva.</h2> </div> <hr>  <div id="content"> <p>The following error was encountered while trying to retrieve the URL: <a href="%U">%U</a></p>  <blockquote id="error"> <p><b>Cache hozzáférés megtagadva.</b></p> </blockquote>  <p>Sajnos az alábbi URL-t nem töltheti le cache szerverünktől %U amíg nem jelentkezik be rendszerünkbe.</p>  <p>Please contact the <a href="mailto:%w%W">cache administrator</a> if you have difficulties authenticating yourself.</p>  <br> </div>  <hr>  <div id="footer"> <p>Generated %T by %h (%s)</p> <!-- %c --> </div> </body></html> 
\ No newline at end of file
diff -u -r -N squid-3.2.0.12/errors/hu/error-details.txt squid-3.2.0.13/errors/hu/error-details.txt
--- squid-3.2.0.12/errors/hu/error-details.txt	2011-09-16 23:45:09.000000000 +1200
+++ squid-3.2.0.13/errors/hu/error-details.txt	2011-10-14 15:32:50.000000000 +1300
@@ -46,19 +46,19 @@
 detail: "%ssl_error_descr: %ssl_subject"
 descr: "CRL has expired"
 
-name: X509_V_ERR_HIBA_IN_CERT_NOT_BEFORE_FIELD
+name: X509_V_ERR_ERROR_IN_CERT_NOT_BEFORE_FIELD
 detail: "SSL Certificate has invalid start date (the 'not before' field): %ssl_subject"
 descr: "Format error in certificate's notBefore field"
 
-name: X509_V_ERR_HIBA_IN_CERT_NOT_AFTER_FIELD
+name: X509_V_ERR_ERROR_IN_CERT_NOT_AFTER_FIELD
 detail: "SSL Certificate has invalid expiration date (the 'not after' field): %ssl_subject"
 descr: "Format error in certificate's notAfter field"
 
-name: X509_V_ERR_HIBA_IN_CRL_LAST_UPDATE_FIELD
+name: X509_V_ERR_ERROR_IN_CRL_LAST_UPDATE_FIELD
 detail: "%ssl_error_descr: %ssl_subject"
 descr: "Format error in CRL's lastUpdate field"
 
-name: X509_V_ERR_HIBA_IN_CRL_NEXT_UPDATE_FIELD
+name: X509_V_ERR_ERROR_IN_CRL_NEXT_UPDATE_FIELD
 detail: "%ssl_error_descr: %ssl_subject"
 descr: "Format error in CRL's nextUpdate field"
 
diff -u -r -N squid-3.2.0.12/errors/hy/ERR_CACHE_ACCESS_DENIED squid-3.2.0.13/errors/hy/ERR_CACHE_ACCESS_DENIED
--- squid-3.2.0.12/errors/hy/ERR_CACHE_ACCESS_DENIED	2011-09-16 23:45:11.000000000 +1200
+++ squid-3.2.0.13/errors/hy/ERR_CACHE_ACCESS_DENIED	2011-10-14 15:33:01.000000000 +1300
@@ -1 +1 @@
-<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd"> <html><head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8"> <title>ՍԽԱԼ: Cache Access Denied</title> <style type="text/css"><!--   %l  body :lang(fa) { direction: rtl; font-size: 100%; font-family: Tahoma, Roya, sans-serif; float: right; } :lang(he) { direction: rtl; }  --></style> </head><body id=%c> <div id="titles"> <h1>ERROR</h1> <h2>Cache Մուտքն արգելված է.</h2> </div> <hr>  <div id="content"> <p>URL-ի ստացման ընթացքում առաջացավ հետևյալ սխալը: <a href="%U">%U</a></p>  <blockquote id="error"> <p><b>Մուտքը քեշին արգելված է.</b></p> </blockquote>  <p>Ներողություն,Դուք չեք կարող իրականացնել հետևյալ հարցումը %U մինչև աութենտիֆիկացիան չանցնեք.</p>  <p>Խնդիրներ առաջանալու դեպքում խնդրվում է դիմել<a href="mailto:%w%W">քեշի կառավարիչին</a> կամ <a href="http://%h/cgi-bin/chpasswd.cgi">փոխել</a> Ձեր ընթացիկ գաղտնաբառը.</p>  <br> </div>  <hr>  <div id="footer"> <p>Ստեղծված է %T by %h (%s)</p> <!-- %c --> </div> </body></html> 
\ No newline at end of file
+<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd"> <html><head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8"> <title>ՍԽԱԼ: Cache Access Denied</title> <style type="text/css"><!--   %l  body :lang(fa) { direction: rtl; font-size: 100%; font-family: Tahoma, Roya, sans-serif; float: right; } :lang(he) { direction: rtl; }  --></style> </head><body id=%c> <div id="titles"> <h1>ERROR</h1> <h2>Cache Մուտքն արգելված է.</h2> </div> <hr>  <div id="content"> <p>URL-ի ստացման ընթացքում առաջացավ հետևյալ սխալը: <a href="%U">%U</a></p>  <blockquote id="error"> <p><b>Մուտքը քեշին արգելված է.</b></p> </blockquote>  <p>Ներողություն,Դուք չեք կարող իրականացնել հետևյալ հարցումը %U մինչև աութենտիֆիկացիան չանցնեք.</p>  <p>Please contact the <a href="mailto:%w%W">cache administrator</a> if you have difficulties authenticating yourself.</p>  <br> </div>  <hr>  <div id="footer"> <p>Ստեղծված է %T by %h (%s)</p> <!-- %c --> </div> </body></html> 
\ No newline at end of file
diff -u -r -N squid-3.2.0.12/errors/hy/error-details.txt squid-3.2.0.13/errors/hy/error-details.txt
--- squid-3.2.0.12/errors/hy/error-details.txt	2011-09-16 23:45:28.000000000 +1200
+++ squid-3.2.0.13/errors/hy/error-details.txt	2011-10-14 15:34:50.000000000 +1300
@@ -46,19 +46,19 @@
 detail: "%ssl_error_descr: %ssl_subject"
 descr: "CRL has expired"
 
-name: X509_V_ERR_ՍԽԱԼ_IN_CERT_NOT_BEFORE_FIELD
+name: X509_V_ERR_ERROR_IN_CERT_NOT_BEFORE_FIELD
 detail: "SSL Certificate has invalid start date (the 'not before' field): %ssl_subject"
 descr: "Format error in certificate's notBefore field"
 
-name: X509_V_ERR_ՍԽԱԼ_IN_CERT_NOT_AFTER_FIELD
+name: X509_V_ERR_ERROR_IN_CERT_NOT_AFTER_FIELD
 detail: "SSL Certificate has invalid expiration date (the 'not after' field): %ssl_subject"
 descr: "Format error in certificate's notAfter field"
 
-name: X509_V_ERR_ՍԽԱԼ_IN_CRL_LAST_UPDATE_FIELD
+name: X509_V_ERR_ERROR_IN_CRL_LAST_UPDATE_FIELD
 detail: "%ssl_error_descr: %ssl_subject"
 descr: "Format error in CRL's lastUpdate field"
 
-name: X509_V_ERR_ՍԽԱԼ_IN_CRL_NEXT_UPDATE_FIELD
+name: X509_V_ERR_ERROR_IN_CRL_NEXT_UPDATE_FIELD
 detail: "%ssl_error_descr: %ssl_subject"
 descr: "Format error in CRL's nextUpdate field"
 
diff -u -r -N squid-3.2.0.12/errors/id/ERR_CACHE_ACCESS_DENIED squid-3.2.0.13/errors/id/ERR_CACHE_ACCESS_DENIED
--- squid-3.2.0.12/errors/id/ERR_CACHE_ACCESS_DENIED	2011-09-16 23:45:30.000000000 +1200
+++ squid-3.2.0.13/errors/id/ERR_CACHE_ACCESS_DENIED	2011-10-14 15:35:05.000000000 +1300
@@ -1 +1 @@
-<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd"> <html><head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8"> <title>ERROR: Cache Access Denied</title> <style type="text/css"><!--   %l  body :lang(fa) { direction: rtl; font-size: 100%; font-family: Tahoma, Roya, sans-serif; float: right; } :lang(he) { direction: rtl; }  --></style> </head><body id=%c> <div id="titles"> <h1>ERROR</h1> <h2>Cache Akses Ditolak</h2> </div> <hr>  <div id="content"> <p>The following error was encountered while trying to retrieve the URL: <a href="%U">%U</a></p>  <blockquote id="error"> <p><b>Akses Cache Ditolak</b></p> </blockquote>  <p>Sorry, you are not currently allowed to request %U from this cache until you have authenticated yourself.</p>  <p>Please contact the <a href="mailto:%w%W">cache administrator</a> if you have difficulties authenticating yourself or <a href="http://%h/cgi-bin/chpasswd.cgi">change</a> your default password.</p>  <br> </div>  <hr>  <div id="footer"> <p>Generated %T by %h (%s)</p> <!-- %c --> </div> </body></html> 
\ No newline at end of file
+<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd"> <html><head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8"> <title>ERROR: Cache Access Denied</title> <style type="text/css"><!--   %l  body :lang(fa) { direction: rtl; font-size: 100%; font-family: Tahoma, Roya, sans-serif; float: right; } :lang(he) { direction: rtl; }  --></style> </head><body id=%c> <div id="titles"> <h1>ERROR</h1> <h2>Cache Akses Ditolak</h2> </div> <hr>  <div id="content"> <p>The following error was encountered while trying to retrieve the URL: <a href="%U">%U</a></p>  <blockquote id="error"> <p><b>Akses Cache Ditolak</b></p> </blockquote>  <p>Sorry, you are not currently allowed to request %U from this cache until you have authenticated yourself.</p>  <p>Please contact the <a href="mailto:%w%W">cache administrator</a> if you have difficulties authenticating yourself.</p>  <br> </div>  <hr>  <div id="footer"> <p>Generated %T by %h (%s)</p> <!-- %c --> </div> </body></html> 
\ No newline at end of file
diff -u -r -N squid-3.2.0.12/errors/it/ERR_CACHE_ACCESS_DENIED squid-3.2.0.13/errors/it/ERR_CACHE_ACCESS_DENIED
--- squid-3.2.0.12/errors/it/ERR_CACHE_ACCESS_DENIED	2011-09-16 23:45:49.000000000 +1200
+++ squid-3.2.0.13/errors/it/ERR_CACHE_ACCESS_DENIED	2011-10-14 15:37:18.000000000 +1300
@@ -1 +1 @@
-<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd"> <html><head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8"> <title>ERRORE: Cache Access Denied</title> <style type="text/css"><!--   %l  body :lang(fa) { direction: rtl; font-size: 100%; font-family: Tahoma, Roya, sans-serif; float: right; } :lang(he) { direction: rtl; }  --></style> </head><body id=%c> <div id="titles"> <h1>ERROR</h1> <h2>Cache Accesso negato.</h2> </div> <hr>  <div id="content"> <p>Mentre si cercava di accedere alla URL <a href="%U">%U</a> si è presentato il seguente errore:</p>  <blockquote id="error"> <p><b>Accesso alla cache negato.</b></p> </blockquote>  <p>Per richiedere %U da questa cache è necessario prima identificarsi.</p>  <p>Si prega di contattare il <a href="mailto:%w%W">gestore del vostro proxy</a> se avete diffcoltà nell'identificarvi per l'accesso al servizio, o di <a href="http://%h/cgi-bin/chpasswd.cgi">cambiare</a> la vostra password iniziale.</p>  <br> </div>  <hr>  <div id="footer"> <p>Generato da %h (%s) il %T.</p> <!-- %c --> </div> </body></html> 
\ No newline at end of file
+<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd"> <html><head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8"> <title>ERRORE: Cache Access Denied</title> <style type="text/css"><!--   %l  body :lang(fa) { direction: rtl; font-size: 100%; font-family: Tahoma, Roya, sans-serif; float: right; } :lang(he) { direction: rtl; }  --></style> </head><body id=%c> <div id="titles"> <h1>ERROR</h1> <h2>Cache Accesso negato.</h2> </div> <hr>  <div id="content"> <p>Mentre si cercava di accedere alla URL <a href="%U">%U</a> si è presentato il seguente errore:</p>  <blockquote id="error"> <p><b>Accesso alla cache negato.</b></p> </blockquote>  <p>Per richiedere %U da questa cache è necessario prima identificarsi.</p>  <p>Please contact the <a href="mailto:%w%W">cache administrator</a> if you have difficulties authenticating yourself.</p>  <br> </div>  <hr>  <div id="footer"> <p>Generato da %h (%s) il %T.</p> <!-- %c --> </div> </body></html> 
\ No newline at end of file
diff -u -r -N squid-3.2.0.12/errors/it/error-details.txt squid-3.2.0.13/errors/it/error-details.txt
--- squid-3.2.0.12/errors/it/error-details.txt	2011-09-16 23:46:07.000000000 +1200
+++ squid-3.2.0.13/errors/it/error-details.txt	2011-10-14 15:39:07.000000000 +1300
@@ -46,19 +46,19 @@
 detail: "%ssl_error_descr: %ssl_subject"
 descr: "CRL has expired"
 
-name: X509_V_ERR_ERRORE_IN_CERT_NOT_BEFORE_FIELD
+name: X509_V_ERR_ERROR_IN_CERT_NOT_BEFORE_FIELD
 detail: "SSL Certificate has invalid start date (the 'not before' field): %ssl_subject"
 descr: "Format error in certificate's notBefore field"
 
-name: X509_V_ERR_ERRORE_IN_CERT_NOT_AFTER_FIELD
+name: X509_V_ERR_ERROR_IN_CERT_NOT_AFTER_FIELD
 detail: "SSL Certificate has invalid expiration date (the 'not after' field): %ssl_subject"
 descr: "Format error in certificate's notAfter field"
 
-name: X509_V_ERR_ERRORE_IN_CRL_LAST_UPDATE_FIELD
+name: X509_V_ERR_ERROR_IN_CRL_LAST_UPDATE_FIELD
 detail: "%ssl_error_descr: %ssl_subject"
 descr: "Format error in CRL's lastUpdate field"
 
-name: X509_V_ERR_ERRORE_IN_CRL_NEXT_UPDATE_FIELD
+name: X509_V_ERR_ERROR_IN_CRL_NEXT_UPDATE_FIELD
 detail: "%ssl_error_descr: %ssl_subject"
 descr: "Format error in CRL's nextUpdate field"
 
diff -u -r -N squid-3.2.0.12/errors/ja/ERR_CACHE_ACCESS_DENIED squid-3.2.0.13/errors/ja/ERR_CACHE_ACCESS_DENIED
--- squid-3.2.0.12/errors/ja/ERR_CACHE_ACCESS_DENIED	2011-09-16 23:46:09.000000000 +1200
+++ squid-3.2.0.13/errors/ja/ERR_CACHE_ACCESS_DENIED	2011-10-14 15:39:18.000000000 +1300
@@ -1 +1 @@
-<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd"> <html><head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8"> <title>エラー: Cache Access Denied</title> <style type="text/css"><!--   %l  body :lang(fa) { direction: rtl; font-size: 100%; font-family: Tahoma, Roya, sans-serif; float: right; } :lang(he) { direction: rtl; }  --></style> </head><body id=%c> <div id="titles"> <h1>ERROR</h1> <h2>Cache アクセスを拒否されました。</h2> </div> <hr>  <div id="content"> <p>The following error was encountered while trying to retrieve the URL: <a href="%U">%U</a></p>  <blockquote id="error"> <p><b>キャッシュへのアクセスを拒否されました．</b></p> </blockquote>  <p>申し訳ありませんが、あなた自身の認証を済ませるまで、このキャッシュに %U をリクエストすることは現在許可されていません。</p>  <p>あなた自身の認証やデフォルトのパスワードの<a href="http://%h/cgi-bin/chpasswd.cgi">変更</a>困難な場合は、<a href="mailto:%w%W">キャッシュの管理者</a>に連絡してください。</p>  <br> </div>  <hr>  <div id="footer"> <p>%Tに%h (%s)が生成しました。</p> <!-- %c --> </div> </body></html> 
\ No newline at end of file
+<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd"> <html><head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8"> <title>エラー: Cache Access Denied</title> <style type="text/css"><!--   %l  body :lang(fa) { direction: rtl; font-size: 100%; font-family: Tahoma, Roya, sans-serif; float: right; } :lang(he) { direction: rtl; }  --></style> </head><body id=%c> <div id="titles"> <h1>ERROR</h1> <h2>Cache アクセスを拒否されました。</h2> </div> <hr>  <div id="content"> <p>The following error was encountered while trying to retrieve the URL: <a href="%U">%U</a></p>  <blockquote id="error"> <p><b>キャッシュへのアクセスを拒否されました．</b></p> </blockquote>  <p>申し訳ありませんが、あなた自身の認証を済ませるまで、このキャッシュに %U をリクエストすることは現在許可されていません。</p>  <p>Please contact the <a href="mailto:%w%W">cache administrator</a> if you have difficulties authenticating yourself.</p>  <br> </div>  <hr>  <div id="footer"> <p>%Tに%h (%s)が生成しました。</p> <!-- %c --> </div> </body></html> 
\ No newline at end of file
diff -u -r -N squid-3.2.0.12/errors/ja/error-details.txt squid-3.2.0.13/errors/ja/error-details.txt
--- squid-3.2.0.12/errors/ja/error-details.txt	2011-09-16 23:46:26.000000000 +1200
+++ squid-3.2.0.13/errors/ja/error-details.txt	2011-10-14 15:41:12.000000000 +1300
@@ -46,19 +46,19 @@
 detail: "%ssl_error_descr: %ssl_subject"
 descr: "CRL has expired"
 
-name: X509_V_ERR_エラー_IN_CERT_NOT_BEFORE_FIELD
+name: X509_V_ERR_ERROR_IN_CERT_NOT_BEFORE_FIELD
 detail: "SSL Certificate has invalid start date (the 'not before' field): %ssl_subject"
 descr: "Format error in certificate's notBefore field"
 
-name: X509_V_ERR_エラー_IN_CERT_NOT_AFTER_FIELD
+name: X509_V_ERR_ERROR_IN_CERT_NOT_AFTER_FIELD
 detail: "SSL Certificate has invalid expiration date (the 'not after' field): %ssl_subject"
 descr: "Format error in certificate's notAfter field"
 
-name: X509_V_ERR_エラー_IN_CRL_LAST_UPDATE_FIELD
+name: X509_V_ERR_ERROR_IN_CRL_LAST_UPDATE_FIELD
 detail: "%ssl_error_descr: %ssl_subject"
 descr: "Format error in CRL's lastUpdate field"
 
-name: X509_V_ERR_エラー_IN_CRL_NEXT_UPDATE_FIELD
+name: X509_V_ERR_ERROR_IN_CRL_NEXT_UPDATE_FIELD
 detail: "%ssl_error_descr: %ssl_subject"
 descr: "Format error in CRL's nextUpdate field"
 
diff -u -r -N squid-3.2.0.12/errors/ko/ERR_CACHE_ACCESS_DENIED squid-3.2.0.13/errors/ko/ERR_CACHE_ACCESS_DENIED
--- squid-3.2.0.12/errors/ko/ERR_CACHE_ACCESS_DENIED	2011-09-16 23:46:28.000000000 +1200
+++ squid-3.2.0.13/errors/ko/ERR_CACHE_ACCESS_DENIED	2011-10-14 15:41:27.000000000 +1300
@@ -1 +1 @@
-<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd"> <html><head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8"> <title>에러: Cache Access Denied</title> <style type="text/css"><!--   %l  body :lang(fa) { direction: rtl; font-size: 100%; font-family: Tahoma, Roya, sans-serif; float: right; } :lang(he) { direction: rtl; }  --></style> </head><body id=%c> <div id="titles"> <h1>ERROR</h1> <h2>Cache 서버 이용 요구가 거절되었습니다.</h2> </div> <hr>  <div id="content"> <p>The following error was encountered while trying to retrieve the URL: <a href="%U">%U</a></p>  <blockquote id="error"> <p><b>캐쉬 이용 요청이 거절되었습니다.</b></p> </blockquote>  <p>죄송합니다. 이 캐쉬를 통해 다음 서비스를 받기 위해서는 %U 인증절차를 거쳐야 합니다.</p>  <p>Please contact the <a href="mailto:%w%W">cache administrator</a> if you have difficulties authenticating yourself or <a href="http://%h/cgi-bin/chpasswd.cgi">change</a> your default password.</p>  <br> </div>  <hr>  <div id="footer"> <p>Generated %T by %h (%s)</p> <!-- %c --> </div> </body></html> 
\ No newline at end of file
+<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd"> <html><head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8"> <title>에러: Cache Access Denied</title> <style type="text/css"><!--   %l  body :lang(fa) { direction: rtl; font-size: 100%; font-family: Tahoma, Roya, sans-serif; float: right; } :lang(he) { direction: rtl; }  --></style> </head><body id=%c> <div id="titles"> <h1>ERROR</h1> <h2>Cache 서버 이용 요구가 거절되었습니다.</h2> </div> <hr>  <div id="content"> <p>The following error was encountered while trying to retrieve the URL: <a href="%U">%U</a></p>  <blockquote id="error"> <p><b>캐쉬 이용 요청이 거절되었습니다.</b></p> </blockquote>  <p>죄송합니다. 이 캐쉬를 통해 다음 서비스를 받기 위해서는 %U 인증절차를 거쳐야 합니다.</p>  <p>Please contact the <a href="mailto:%w%W">cache administrator</a> if you have difficulties authenticating yourself.</p>  <br> </div>  <hr>  <div id="footer"> <p>Generated %T by %h (%s)</p> <!-- %c --> </div> </body></html> 
\ No newline at end of file
diff -u -r -N squid-3.2.0.12/errors/ko/error-details.txt squid-3.2.0.13/errors/ko/error-details.txt
--- squid-3.2.0.12/errors/ko/error-details.txt	2011-09-16 23:46:45.000000000 +1200
+++ squid-3.2.0.13/errors/ko/error-details.txt	2011-10-14 15:44:17.000000000 +1300
@@ -46,19 +46,19 @@
 detail: "%ssl_error_descr: %ssl_subject"
 descr: "CRL has expired"
 
-name: X509_V_ERR_에러_IN_CERT_NOT_BEFORE_FIELD
+name: X509_V_ERR_ERROR_IN_CERT_NOT_BEFORE_FIELD
 detail: "SSL Certificate has invalid start date (the 'not before' field): %ssl_subject"
 descr: "Format error in certificate's notBefore field"
 
-name: X509_V_ERR_에러_IN_CERT_NOT_AFTER_FIELD
+name: X509_V_ERR_ERROR_IN_CERT_NOT_AFTER_FIELD
 detail: "SSL Certificate has invalid expiration date (the 'not after' field): %ssl_subject"
 descr: "Format error in certificate's notAfter field"
 
-name: X509_V_ERR_에러_IN_CRL_LAST_UPDATE_FIELD
+name: X509_V_ERR_ERROR_IN_CRL_LAST_UPDATE_FIELD
 detail: "%ssl_error_descr: %ssl_subject"
 descr: "Format error in CRL's lastUpdate field"
 
-name: X509_V_ERR_에러_IN_CRL_NEXT_UPDATE_FIELD
+name: X509_V_ERR_ERROR_IN_CRL_NEXT_UPDATE_FIELD
 detail: "%ssl_error_descr: %ssl_subject"
 descr: "Format error in CRL's nextUpdate field"
 
diff -u -r -N squid-3.2.0.12/errors/lt/ERR_CACHE_ACCESS_DENIED squid-3.2.0.13/errors/lt/ERR_CACHE_ACCESS_DENIED
--- squid-3.2.0.12/errors/lt/ERR_CACHE_ACCESS_DENIED	2011-09-16 23:46:47.000000000 +1200
+++ squid-3.2.0.13/errors/lt/ERR_CACHE_ACCESS_DENIED	2011-10-14 15:44:37.000000000 +1300
@@ -1 +1 @@
-<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd"> <html><head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8"> <title>KLAIDA: Cache Access Denied</title> <style type="text/css"><!--   %l  body :lang(fa) { direction: rtl; font-size: 100%; font-family: Tahoma, Roya, sans-serif; float: right; } :lang(he) { direction: rtl; }  --></style> </head><body id=%c> <div id="titles"> <h1>ERROR</h1> <h2>Cache Priėjimas draudžiamas.</h2> </div> <hr>  <div id="content"> <p>The following error was encountered while trying to retrieve the URL: <a href="%U">%U</a></p>  <blockquote id="error"> <p><b>Priėjimas prie kešo uždraustas.</b></p> </blockquote>  <p>Sorry, you are not currently allowed to request %U from this cache until you have authenticated yourself.</p>  <p>Prašome susisiekti su <a href="mailto:%w%W">proxy administratoriumi</a>, jei jums kils sunkumai prisistatant arba <a href="http://%h/cgi-bin/chpasswd.cgi">pakeisti</a> savo slaptažodį.</p>  <br> </div>  <hr>  <div id="footer"> <p>Generated %T by %h (%s)</p> <!-- %c --> </div> </body></html> 
\ No newline at end of file
+<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd"> <html><head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8"> <title>KLAIDA: Cache Access Denied</title> <style type="text/css"><!--   %l  body :lang(fa) { direction: rtl; font-size: 100%; font-family: Tahoma, Roya, sans-serif; float: right; } :lang(he) { direction: rtl; }  --></style> </head><body id=%c> <div id="titles"> <h1>ERROR</h1> <h2>Cache Priėjimas draudžiamas.</h2> </div> <hr>  <div id="content"> <p>The following error was encountered while trying to retrieve the URL: <a href="%U">%U</a></p>  <blockquote id="error"> <p><b>Priėjimas prie kešo uždraustas.</b></p> </blockquote>  <p>Sorry, you are not currently allowed to request %U from this cache until you have authenticated yourself.</p>  <p>Please contact the <a href="mailto:%w%W">cache administrator</a> if you have difficulties authenticating yourself.</p>  <br> </div>  <hr>  <div id="footer"> <p>Generated %T by %h (%s)</p> <!-- %c --> </div> </body></html> 
\ No newline at end of file
diff -u -r -N squid-3.2.0.12/errors/lt/error-details.txt squid-3.2.0.13/errors/lt/error-details.txt
--- squid-3.2.0.12/errors/lt/error-details.txt	2011-09-16 23:47:05.000000000 +1200
+++ squid-3.2.0.13/errors/lt/error-details.txt	2011-10-14 15:47:50.000000000 +1300
@@ -46,19 +46,19 @@
 detail: "%ssl_error_descr: %ssl_subject"
 descr: "CRL has expired"
 
-name: X509_V_ERR_KLAIDA_IN_CERT_NOT_BEFORE_FIELD
+name: X509_V_ERR_ERROR_IN_CERT_NOT_BEFORE_FIELD
 detail: "SSL Certificate has invalid start date (the 'not before' field): %ssl_subject"
 descr: "Format error in certificate's notBefore field"
 
-name: X509_V_ERR_KLAIDA_IN_CERT_NOT_AFTER_FIELD
+name: X509_V_ERR_ERROR_IN_CERT_NOT_AFTER_FIELD
 detail: "SSL Certificate has invalid expiration date (the 'not after' field): %ssl_subject"
 descr: "Format error in certificate's notAfter field"
 
-name: X509_V_ERR_KLAIDA_IN_CRL_LAST_UPDATE_FIELD
+name: X509_V_ERR_ERROR_IN_CRL_LAST_UPDATE_FIELD
 detail: "%ssl_error_descr: %ssl_subject"
 descr: "Format error in CRL's lastUpdate field"
 
-name: X509_V_ERR_KLAIDA_IN_CRL_NEXT_UPDATE_FIELD
+name: X509_V_ERR_ERROR_IN_CRL_NEXT_UPDATE_FIELD
 detail: "%ssl_error_descr: %ssl_subject"
 descr: "Format error in CRL's nextUpdate field"
 
diff -u -r -N squid-3.2.0.12/errors/lv/ERR_CACHE_ACCESS_DENIED squid-3.2.0.13/errors/lv/ERR_CACHE_ACCESS_DENIED
--- squid-3.2.0.12/errors/lv/ERR_CACHE_ACCESS_DENIED	2011-09-16 23:47:07.000000000 +1200
+++ squid-3.2.0.13/errors/lv/ERR_CACHE_ACCESS_DENIED	2011-10-14 15:48:12.000000000 +1300
@@ -1 +1 @@
-<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd"> <html><head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8"> <title>Kļūda: Cache Access Denied</title> <style type="text/css"><!--   %l  body :lang(fa) { direction: rtl; font-size: 100%; font-family: Tahoma, Roya, sans-serif; float: right; } :lang(he) { direction: rtl; }  --></style> </head><body id=%c> <div id="titles"> <h1>ERROR</h1> <h2>Cache Pieeja liegta</h2> </div> <hr>  <div id="content"> <p>Iestājusies sekojoša kļūda mēģinot atvērt adresi: <a href="%U">%U</a></p>  <blockquote id="error"> <p><b>Kešatmiņas pieeja liegta</b></p> </blockquote>  <p>Atvainojiet, Jums nav atļauts pieprasīt %U no kešatmiņas pirms neesat autentificējies.</p>  <p>Lūdzu sazinieties <a href="mailto:%w%W">kešatmiņas administratoru</a>, ja Jums ir problēmas ar autentifikāciju vai <a href="http://%h/cgi-bin/chpasswd.cgi">nomainiet</a> Jūsu paroli.</p>  <br> </div>  <hr>  <div id="footer"> <p>Ģenerēts %T by %h (%s)</p> <!-- %c --> </div> </body></html> 
\ No newline at end of file
+<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd"> <html><head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8"> <title>Kļūda: Cache Access Denied</title> <style type="text/css"><!--   %l  body :lang(fa) { direction: rtl; font-size: 100%; font-family: Tahoma, Roya, sans-serif; float: right; } :lang(he) { direction: rtl; }  --></style> </head><body id=%c> <div id="titles"> <h1>ERROR</h1> <h2>Cache Pieeja liegta</h2> </div> <hr>  <div id="content"> <p>Iestājusies sekojoša kļūda mēģinot atvērt adresi: <a href="%U">%U</a></p>  <blockquote id="error"> <p><b>Kešatmiņas pieeja liegta</b></p> </blockquote>  <p>Atvainojiet, Jums nav atļauts pieprasīt %U no kešatmiņas pirms neesat autentificējies.</p>  <p>Please contact the <a href="mailto:%w%W">cache administrator</a> if you have difficulties authenticating yourself.</p>  <br> </div>  <hr>  <div id="footer"> <p>Ģenerēts %T by %h (%s)</p> <!-- %c --> </div> </body></html> 
\ No newline at end of file
diff -u -r -N squid-3.2.0.12/errors/lv/error-details.txt squid-3.2.0.13/errors/lv/error-details.txt
--- squid-3.2.0.12/errors/lv/error-details.txt	2011-09-16 23:47:24.000000000 +1200
+++ squid-3.2.0.13/errors/lv/error-details.txt	2011-10-14 15:50:53.000000000 +1300
@@ -46,19 +46,19 @@
 detail: "%ssl_error_descr: %ssl_subject"
 descr: "CRL has expired"
 
-name: X509_V_ERR_Kļūda_IN_CERT_NOT_BEFORE_FIELD
+name: X509_V_ERR_ERROR_IN_CERT_NOT_BEFORE_FIELD
 detail: "SSL Certificate has invalid start date (the 'not before' field): %ssl_subject"
 descr: "Format error in certificate's notBefore field"
 
-name: X509_V_ERR_Kļūda_IN_CERT_NOT_AFTER_FIELD
+name: X509_V_ERR_ERROR_IN_CERT_NOT_AFTER_FIELD
 detail: "SSL Certificate has invalid expiration date (the 'not after' field): %ssl_subject"
 descr: "Format error in certificate's notAfter field"
 
-name: X509_V_ERR_Kļūda_IN_CRL_LAST_UPDATE_FIELD
+name: X509_V_ERR_ERROR_IN_CRL_LAST_UPDATE_FIELD
 detail: "%ssl_error_descr: %ssl_subject"
 descr: "Format error in CRL's lastUpdate field"
 
-name: X509_V_ERR_Kļūda_IN_CRL_NEXT_UPDATE_FIELD
+name: X509_V_ERR_ERROR_IN_CRL_NEXT_UPDATE_FIELD
 detail: "%ssl_error_descr: %ssl_subject"
 descr: "Format error in CRL's nextUpdate field"
 
diff -u -r -N squid-3.2.0.12/errors/Makefile.am squid-3.2.0.13/errors/Makefile.am
--- squid-3.2.0.12/errors/Makefile.am	2011-09-16 23:37:30.000000000 +1200
+++ squid-3.2.0.13/errors/Makefile.am	2011-10-14 14:42:56.000000000 +1300
@@ -50,7 +50,7 @@
 		page=`basename $$f`; \
 		$(PO2HTML) $(NOTIDY) --progress=none -i $(top_srcdir)/errors/$$lang.po -t $(top_srcdir)/errors/$$f >$(top_builddir)/errors/$$lang/$$page || exit 1; \
 	    done; \
-	    $(PO2TEXT) -t $(top_srcdir)/errors/templates/error-details.txt -i $(top_srcdir)/errors/$$lang.po > $(top_builddir)/errors/$$lang/error-details.txt || exit 1; \
+	    cp $(top_srcdir)/errors/templates/error-details.txt $(top_builddir)/errors/$$lang/error-details.txt || exit 1; \
 	    echo "done."; \
 	fi; \
 	touch $@
diff -u -r -N squid-3.2.0.12/errors/Makefile.in squid-3.2.0.13/errors/Makefile.in
--- squid-3.2.0.12/errors/Makefile.in	2011-09-16 23:38:07.000000000 +1200
+++ squid-3.2.0.13/errors/Makefile.in	2011-10-14 14:46:41.000000000 +1300
@@ -582,7 +582,7 @@
 		page=`basename $$f`; \
 		$(PO2HTML) $(NOTIDY) --progress=none -i $(top_srcdir)/errors/$$lang.po -t $(top_srcdir)/errors/$$f >$(top_builddir)/errors/$$lang/$$page || exit 1; \
 	    done; \
-	    $(PO2TEXT) -t $(top_srcdir)/errors/templates/error-details.txt -i $(top_srcdir)/errors/$$lang.po > $(top_builddir)/errors/$$lang/error-details.txt || exit 1; \
+	    cp $(top_srcdir)/errors/templates/error-details.txt $(top_builddir)/errors/$$lang/error-details.txt || exit 1; \
 	    echo "done."; \
 	fi; \
 	touch $@
diff -u -r -N squid-3.2.0.12/errors/ms/ERR_CACHE_ACCESS_DENIED squid-3.2.0.13/errors/ms/ERR_CACHE_ACCESS_DENIED
--- squid-3.2.0.12/errors/ms/ERR_CACHE_ACCESS_DENIED	2011-09-16 23:47:26.000000000 +1200
+++ squid-3.2.0.13/errors/ms/ERR_CACHE_ACCESS_DENIED	2011-10-14 15:51:16.000000000 +1300
@@ -1 +1 @@
-<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd"> <html><head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8"> <title>RALAT: Cache Access Denied</title> <style type="text/css"><!--   %l  body :lang(fa) { direction: rtl; font-size: 100%; font-family: Tahoma, Roya, sans-serif; float: right; } :lang(he) { direction: rtl; }  --></style> </head><body id=%c> <div id="titles"> <h1>ERROR</h1> <h2>Cache Akses Disekat</h2> </div> <hr>  <div id="content"> <p>The following error was encountered while trying to retrieve the URL: <a href="%U">%U</a></p>  <blockquote id="error"> <p><b>Akses ke Cache disekat</b></p> </blockquote>  <p>Sorry, you are not currently allowed to request %U from this cache until you have authenticated yourself.</p>  <p>Please contact the <a href="mailto:%w%W">cache administrator</a> if you have difficulties authenticating yourself or <a href="http://%h/cgi-bin/chpasswd.cgi">change</a> your default password.</p>  <br> </div>  <hr>  <div id="footer"> <p>Dibuat pada %T by %h (%s)</p> <!-- %c --> </div> </body></html> 
\ No newline at end of file
+<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd"> <html><head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8"> <title>RALAT: Cache Access Denied</title> <style type="text/css"><!--   %l  body :lang(fa) { direction: rtl; font-size: 100%; font-family: Tahoma, Roya, sans-serif; float: right; } :lang(he) { direction: rtl; }  --></style> </head><body id=%c> <div id="titles"> <h1>ERROR</h1> <h2>Cache Akses Disekat</h2> </div> <hr>  <div id="content"> <p>The following error was encountered while trying to retrieve the URL: <a href="%U">%U</a></p>  <blockquote id="error"> <p><b>Akses ke Cache disekat</b></p> </blockquote>  <p>Sorry, you are not currently allowed to request %U from this cache until you have authenticated yourself.</p>  <p>Please contact the <a href="mailto:%w%W">cache administrator</a> if you have difficulties authenticating yourself.</p>  <br> </div>  <hr>  <div id="footer"> <p>Dibuat pada %T by %h (%s)</p> <!-- %c --> </div> </body></html> 
\ No newline at end of file
diff -u -r -N squid-3.2.0.12/errors/ms/error-details.txt squid-3.2.0.13/errors/ms/error-details.txt
--- squid-3.2.0.12/errors/ms/error-details.txt	2011-09-16 23:47:43.000000000 +1200
+++ squid-3.2.0.13/errors/ms/error-details.txt	2011-10-14 15:53:51.000000000 +1300
@@ -46,19 +46,19 @@
 detail: "%ssl_error_descr: %ssl_subject"
 descr: "CRL has expired"
 
-name: X509_V_ERR_RALAT_IN_CERT_NOT_BEFORE_FIELD
+name: X509_V_ERR_ERROR_IN_CERT_NOT_BEFORE_FIELD
 detail: "SSL Certificate has invalid start date (the 'not before' field): %ssl_subject"
 descr: "Format error in certificate's notBefore field"
 
-name: X509_V_ERR_RALAT_IN_CERT_NOT_AFTER_FIELD
+name: X509_V_ERR_ERROR_IN_CERT_NOT_AFTER_FIELD
 detail: "SSL Certificate has invalid expiration date (the 'not after' field): %ssl_subject"
 descr: "Format error in certificate's notAfter field"
 
-name: X509_V_ERR_RALAT_IN_CRL_LAST_UPDATE_FIELD
+name: X509_V_ERR_ERROR_IN_CRL_LAST_UPDATE_FIELD
 detail: "%ssl_error_descr: %ssl_subject"
 descr: "Format error in CRL's lastUpdate field"
 
-name: X509_V_ERR_RALAT_IN_CRL_NEXT_UPDATE_FIELD
+name: X509_V_ERR_ERROR_IN_CRL_NEXT_UPDATE_FIELD
 detail: "%ssl_error_descr: %ssl_subject"
 descr: "Format error in CRL's nextUpdate field"
 
diff -u -r -N squid-3.2.0.12/errors/nl/ERR_CACHE_ACCESS_DENIED squid-3.2.0.13/errors/nl/ERR_CACHE_ACCESS_DENIED
--- squid-3.2.0.12/errors/nl/ERR_CACHE_ACCESS_DENIED	2011-09-16 23:47:45.000000000 +1200
+++ squid-3.2.0.13/errors/nl/ERR_CACHE_ACCESS_DENIED	2011-10-14 15:54:09.000000000 +1300
@@ -1 +1 @@
-<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd"> <html><head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8"> <title>FOUT: Cache Access Denied</title> <style type="text/css"><!--   %l  body :lang(fa) { direction: rtl; font-size: 100%; font-family: Tahoma, Roya, sans-serif; float: right; } :lang(he) { direction: rtl; }  --></style> </head><body id=%c> <div id="titles"> <h1>ERROR</h1> <h2>Cache Toegang niet toegestaan.</h2> </div> <hr>  <div id="content"> <p>De volgende fout is opgetreden tijdens het ophalen van URL: <a href="%U">%U</a></p>  <blockquote id="error"> <p><b>Cache toegang niet toegestaan.</b></p> </blockquote>  <p>Sorry, het is u niet toegestaan om %U van deze cache op te vragen totdat u zich geidentificeerd hebt.</p>  <p>Neem contact op met de <a href="mailto:%w%W">cache beheerder</a> als u problemen heeft met authenticatie of <a href="http://%h/cgi-bin/chpasswd.cgi">verander</a> hier uw standaard wachtwoord.</p>  <br> </div>  <hr>  <div id="footer"> <p>Gegenereerd %T door %h (%s)</p> <!-- %c --> </div> </body></html> 
\ No newline at end of file
+<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd"> <html><head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8"> <title>FOUT: Cache Access Denied</title> <style type="text/css"><!--   %l  body :lang(fa) { direction: rtl; font-size: 100%; font-family: Tahoma, Roya, sans-serif; float: right; } :lang(he) { direction: rtl; }  --></style> </head><body id=%c> <div id="titles"> <h1>ERROR</h1> <h2>Cache Toegang niet toegestaan.</h2> </div> <hr>  <div id="content"> <p>De volgende fout is opgetreden tijdens het ophalen van URL: <a href="%U">%U</a></p>  <blockquote id="error"> <p><b>Cache toegang niet toegestaan.</b></p> </blockquote>  <p>Sorry, het is u niet toegestaan om %U van deze cache op te vragen totdat u zich geidentificeerd hebt.</p>  <p>Please contact the <a href="mailto:%w%W">cache administrator</a> if you have difficulties authenticating yourself.</p>  <br> </div>  <hr>  <div id="footer"> <p>Gegenereerd %T door %h (%s)</p> <!-- %c --> </div> </body></html> 
\ No newline at end of file
diff -u -r -N squid-3.2.0.12/errors/nl/error-details.txt squid-3.2.0.13/errors/nl/error-details.txt
--- squid-3.2.0.12/errors/nl/error-details.txt	2011-09-16 23:48:03.000000000 +1200
+++ squid-3.2.0.13/errors/nl/error-details.txt	2011-10-14 15:56:40.000000000 +1300
@@ -46,19 +46,19 @@
 detail: "%ssl_error_descr: %ssl_subject"
 descr: "CRL has expired"
 
-name: X509_V_ERR_FOUT_IN_CERT_NOT_BEFORE_FIELD
+name: X509_V_ERR_ERROR_IN_CERT_NOT_BEFORE_FIELD
 detail: "SSL Certificate has invalid start date (the 'not before' field): %ssl_subject"
 descr: "Format error in certificate's notBefore field"
 
-name: X509_V_ERR_FOUT_IN_CERT_NOT_AFTER_FIELD
+name: X509_V_ERR_ERROR_IN_CERT_NOT_AFTER_FIELD
 detail: "SSL Certificate has invalid expiration date (the 'not after' field): %ssl_subject"
 descr: "Format error in certificate's notAfter field"
 
-name: X509_V_ERR_FOUT_IN_CRL_LAST_UPDATE_FIELD
+name: X509_V_ERR_ERROR_IN_CRL_LAST_UPDATE_FIELD
 detail: "%ssl_error_descr: %ssl_subject"
 descr: "Format error in CRL's lastUpdate field"
 
-name: X509_V_ERR_FOUT_IN_CRL_NEXT_UPDATE_FIELD
+name: X509_V_ERR_ERROR_IN_CRL_NEXT_UPDATE_FIELD
 detail: "%ssl_error_descr: %ssl_subject"
 descr: "Format error in CRL's nextUpdate field"
 
diff -u -r -N squid-3.2.0.12/errors/oc/ERR_CACHE_ACCESS_DENIED squid-3.2.0.13/errors/oc/ERR_CACHE_ACCESS_DENIED
--- squid-3.2.0.12/errors/oc/ERR_CACHE_ACCESS_DENIED	2011-09-16 23:48:05.000000000 +1200
+++ squid-3.2.0.13/errors/oc/ERR_CACHE_ACCESS_DENIED	2011-10-14 15:57:04.000000000 +1300
@@ -1 +1 @@
-<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd"> <html><head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8"> <title>ERROR: Cache Access Denied</title> <style type="text/css"><!--   %l  body :lang(fa) { direction: rtl; font-size: 100%; font-family: Tahoma, Roya, sans-serif; float: right; } :lang(he) { direction: rtl; }  --></style> </head><body id=%c> <div id="titles"> <h1>ERROR</h1> <h2>Cache Accès interdich.</h2> </div> <hr>  <div id="content"> <p>L'error seguenta s'es producha en ensajant d'accedir a l'URL : <a href="%U">%U</a></p>  <blockquote id="error"> <p><b>Accès a l'amagatal interdich.</b></p> </blockquote>  <p>Sorry, you are not currently allowed to request %U from this cache until you have authenticated yourself.</p>  <p>Please contact the <a href="mailto:%w%W">cache administrator</a> if you have difficulties authenticating yourself or <a href="http://%h/cgi-bin/chpasswd.cgi">change</a> your default password.</p>  <br> </div>  <hr>  <div id="footer"> <p>Generada lo %T per %h (%s)</p> <!-- %c --> </div> </body></html> 
\ No newline at end of file
+<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd"> <html><head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8"> <title>ERROR: Cache Access Denied</title> <style type="text/css"><!--   %l  body :lang(fa) { direction: rtl; font-size: 100%; font-family: Tahoma, Roya, sans-serif; float: right; } :lang(he) { direction: rtl; }  --></style> </head><body id=%c> <div id="titles"> <h1>ERROR</h1> <h2>Cache Accès interdich.</h2> </div> <hr>  <div id="content"> <p>L'error seguenta s'es producha en ensajant d'accedir a l'URL : <a href="%U">%U</a></p>  <blockquote id="error"> <p><b>Accès a l'amagatal interdich.</b></p> </blockquote>  <p>Sorry, you are not currently allowed to request %U from this cache until you have authenticated yourself.</p>  <p>Please contact the <a href="mailto:%w%W">cache administrator</a> if you have difficulties authenticating yourself.</p>  <br> </div>  <hr>  <div id="footer"> <p>Generada lo %T per %h (%s)</p> <!-- %c --> </div> </body></html> 
\ No newline at end of file
diff -u -r -N squid-3.2.0.12/errors/pl/ERR_CACHE_ACCESS_DENIED squid-3.2.0.13/errors/pl/ERR_CACHE_ACCESS_DENIED
--- squid-3.2.0.12/errors/pl/ERR_CACHE_ACCESS_DENIED	2011-09-16 23:48:25.000000000 +1200
+++ squid-3.2.0.13/errors/pl/ERR_CACHE_ACCESS_DENIED	2011-10-14 15:59:50.000000000 +1300
@@ -1 +1 @@
-<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd"> <html><head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8"> <title>BŁĄD: Cache Access Denied</title> <style type="text/css"><!--   %l  body :lang(fa) { direction: rtl; font-size: 100%; font-family: Tahoma, Roya, sans-serif; float: right; } :lang(he) { direction: rtl; }  --></style> </head><body id=%c> <div id="titles"> <h1>ERROR</h1> <h2>Cache Dostęp zabroniony.</h2> </div> <hr>  <div id="content"> <p>The following error was encountered while trying to retrieve the URL: <a href="%U">%U</a></p>  <blockquote id="error"> <p><b>Dostęp do serwera cache zabroniony.</b></p> </blockquote>  <p>Sorry, you are not currently allowed to request %U from this cache until you have authenticated yourself.</p>  <p>Skontaktuj się z <a href="mailto:%w%W">administratorem serwera cache</a> jeśli masz trudności z autoryzacją lub <a href="http://%h/cgi-bin/chpasswd.cgi">zmień</a> haslo.</p>  <br> </div>  <hr>  <div id="footer"> <p>Utworzono %T przez %h (%s)</p> <!-- %c --> </div> </body></html> 
\ No newline at end of file
+<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd"> <html><head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8"> <title>BŁĄD: Cache Access Denied</title> <style type="text/css"><!--   %l  body :lang(fa) { direction: rtl; font-size: 100%; font-family: Tahoma, Roya, sans-serif; float: right; } :lang(he) { direction: rtl; }  --></style> </head><body id=%c> <div id="titles"> <h1>ERROR</h1> <h2>Cache Dostęp zabroniony.</h2> </div> <hr>  <div id="content"> <p>The following error was encountered while trying to retrieve the URL: <a href="%U">%U</a></p>  <blockquote id="error"> <p><b>Dostęp do serwera cache zabroniony.</b></p> </blockquote>  <p>Sorry, you are not currently allowed to request %U from this cache until you have authenticated yourself.</p>  <p>Please contact the <a href="mailto:%w%W">cache administrator</a> if you have difficulties authenticating yourself.</p>  <br> </div>  <hr>  <div id="footer"> <p>Utworzono %T przez %h (%s)</p> <!-- %c --> </div> </body></html> 
\ No newline at end of file
diff -u -r -N squid-3.2.0.12/errors/pl/error-details.txt squid-3.2.0.13/errors/pl/error-details.txt
--- squid-3.2.0.12/errors/pl/error-details.txt	2011-09-16 23:48:42.000000000 +1200
+++ squid-3.2.0.13/errors/pl/error-details.txt	2011-10-14 16:02:31.000000000 +1300
@@ -46,19 +46,19 @@
 detail: "%ssl_error_descr: %ssl_subject"
 descr: "CRL has expired"
 
-name: X509_V_ERR_BŁĄD_IN_CERT_NOT_BEFORE_FIELD
+name: X509_V_ERR_ERROR_IN_CERT_NOT_BEFORE_FIELD
 detail: "SSL Certificate has invalid start date (the 'not before' field): %ssl_subject"
 descr: "Format error in certificate's notBefore field"
 
-name: X509_V_ERR_BŁĄD_IN_CERT_NOT_AFTER_FIELD
+name: X509_V_ERR_ERROR_IN_CERT_NOT_AFTER_FIELD
 detail: "SSL Certificate has invalid expiration date (the 'not after' field): %ssl_subject"
 descr: "Format error in certificate's notAfter field"
 
-name: X509_V_ERR_BŁĄD_IN_CRL_LAST_UPDATE_FIELD
+name: X509_V_ERR_ERROR_IN_CRL_LAST_UPDATE_FIELD
 detail: "%ssl_error_descr: %ssl_subject"
 descr: "Format error in CRL's lastUpdate field"
 
-name: X509_V_ERR_BŁĄD_IN_CRL_NEXT_UPDATE_FIELD
+name: X509_V_ERR_ERROR_IN_CRL_NEXT_UPDATE_FIELD
 detail: "%ssl_error_descr: %ssl_subject"
 descr: "Format error in CRL's nextUpdate field"
 
diff -u -r -N squid-3.2.0.12/errors/pt/ERR_CACHE_ACCESS_DENIED squid-3.2.0.13/errors/pt/ERR_CACHE_ACCESS_DENIED
--- squid-3.2.0.12/errors/pt/ERR_CACHE_ACCESS_DENIED	2011-09-16 23:49:03.000000000 +1200
+++ squid-3.2.0.13/errors/pt/ERR_CACHE_ACCESS_DENIED	2011-10-14 16:05:23.000000000 +1300
@@ -1 +1 @@
-<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd"> <html><head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8"> <title>ERRO: Cache Access Denied</title> <style type="text/css"><!--   %l  body :lang(fa) { direction: rtl; font-size: 100%; font-family: Tahoma, Roya, sans-serif; float: right; } :lang(he) { direction: rtl; }  --></style> </head><body id=%c> <div id="titles"> <h1>ERROR</h1> <h2>Cache Proibido o Acesso.</h2> </div> <hr>  <div id="content"> <p>The following error was encountered while trying to retrieve the URL: <a href="%U">%U</a></p>  <blockquote id="error"> <p><b>Proibido o acesso ao Cache.</b></p> </blockquote>  <p>Sorry, you are not currently allowed to request %U from this cache until you have authenticated yourself.</p>  <p>Por favor, contate o <a href="mailto:%w%W">administrador do cache</a> se você tiver dificuldades para se autenticar ou, <a href="http://%h/cgi-bin/chpasswd.cgi">altere</a> sua senha.</p>  <br> </div>  <hr>  <div id="footer"> <p>Generated %T by %h (%s)</p> <!-- %c --> </div> </body></html> 
\ No newline at end of file
+<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd"> <html><head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8"> <title>ERRO: Cache Access Denied</title> <style type="text/css"><!--   %l  body :lang(fa) { direction: rtl; font-size: 100%; font-family: Tahoma, Roya, sans-serif; float: right; } :lang(he) { direction: rtl; }  --></style> </head><body id=%c> <div id="titles"> <h1>ERROR</h1> <h2>Cache Proibido o Acesso.</h2> </div> <hr>  <div id="content"> <p>The following error was encountered while trying to retrieve the URL: <a href="%U">%U</a></p>  <blockquote id="error"> <p><b>Proibido o acesso ao Cache.</b></p> </blockquote>  <p>Sorry, you are not currently allowed to request %U from this cache until you have authenticated yourself.</p>  <p>Please contact the <a href="mailto:%w%W">cache administrator</a> if you have difficulties authenticating yourself.</p>  <br> </div>  <hr>  <div id="footer"> <p>Generated %T by %h (%s)</p> <!-- %c --> </div> </body></html> 
\ No newline at end of file
diff -u -r -N squid-3.2.0.12/errors/pt/error-details.txt squid-3.2.0.13/errors/pt/error-details.txt
--- squid-3.2.0.12/errors/pt/error-details.txt	2011-09-16 23:49:21.000000000 +1200
+++ squid-3.2.0.13/errors/pt/error-details.txt	2011-10-14 16:08:12.000000000 +1300
@@ -46,19 +46,19 @@
 detail: "%ssl_error_descr: %ssl_subject"
 descr: "CRL has expired"
 
-name: X509_V_ERR_ERRO_IN_CERT_NOT_BEFORE_FIELD
+name: X509_V_ERR_ERROR_IN_CERT_NOT_BEFORE_FIELD
 detail: "SSL Certificate has invalid start date (the 'not before' field): %ssl_subject"
 descr: "Format error in certificate's notBefore field"
 
-name: X509_V_ERR_ERRO_IN_CERT_NOT_AFTER_FIELD
+name: X509_V_ERR_ERROR_IN_CERT_NOT_AFTER_FIELD
 detail: "SSL Certificate has invalid expiration date (the 'not after' field): %ssl_subject"
 descr: "Format error in certificate's notAfter field"
 
-name: X509_V_ERR_ERRO_IN_CRL_LAST_UPDATE_FIELD
+name: X509_V_ERR_ERROR_IN_CRL_LAST_UPDATE_FIELD
 detail: "%ssl_error_descr: %ssl_subject"
 descr: "Format error in CRL's lastUpdate field"
 
-name: X509_V_ERR_ERRO_IN_CRL_NEXT_UPDATE_FIELD
+name: X509_V_ERR_ERROR_IN_CRL_NEXT_UPDATE_FIELD
 detail: "%ssl_error_descr: %ssl_subject"
 descr: "Format error in CRL's nextUpdate field"
 
diff -u -r -N squid-3.2.0.12/errors/pt-br/ERR_CACHE_ACCESS_DENIED squid-3.2.0.13/errors/pt-br/ERR_CACHE_ACCESS_DENIED
--- squid-3.2.0.12/errors/pt-br/ERR_CACHE_ACCESS_DENIED	2011-09-16 23:48:44.000000000 +1200
+++ squid-3.2.0.13/errors/pt-br/ERR_CACHE_ACCESS_DENIED	2011-10-14 16:02:49.000000000 +1300
@@ -1 +1 @@
-<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd"> <html><head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8"> <title>ERRO: Cache Access Denied</title> <style type="text/css"><!--   %l  body :lang(fa) { direction: rtl; font-size: 100%; font-family: Tahoma, Roya, sans-serif; float: right; } :lang(he) { direction: rtl; }  --></style> </head><body id=%c> <div id="titles"> <h1>ERROR</h1> <h2>Cache Acesso Negado.</h2> </div> <hr>  <div id="content"> <p>O seguinte erro foi encontrado ao tentar recuperar a URL: <a href="%U">%U</a></p>  <blockquote id="error"> <p><b>Acesso negado ao cache.</b></p> </blockquote>  <p>Desculpe. Atualmente, você não está permitido a requisitar %U desse cache até que você tenha se autenticado.</p>  <p>Por favor, contate o <a href="mailto:%w%W">administrador do cache</a> se você está tendo dificuldades em se autenticar ou <a href="http://%h/cgi-bin/chpasswd.cgi">mude</a> sua senha.</p>  <br> </div>  <hr>  <div id="footer"> <p>Gerado %T por %h (%s)</p> <!-- %c --> </div> </body></html> 
\ No newline at end of file
+<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd"> <html><head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8"> <title>ERRO: Cache Access Denied</title> <style type="text/css"><!--   %l  body :lang(fa) { direction: rtl; font-size: 100%; font-family: Tahoma, Roya, sans-serif; float: right; } :lang(he) { direction: rtl; }  --></style> </head><body id=%c> <div id="titles"> <h1>ERROR</h1> <h2>Cache Acesso Negado.</h2> </div> <hr>  <div id="content"> <p>O seguinte erro foi encontrado ao tentar recuperar a URL: <a href="%U">%U</a></p>  <blockquote id="error"> <p><b>Acesso negado ao cache.</b></p> </blockquote>  <p>Desculpe. Atualmente, você não está permitido a requisitar %U desse cache até que você tenha se autenticado.</p>  <p>Please contact the <a href="mailto:%w%W">cache administrator</a> if you have difficulties authenticating yourself.</p>  <br> </div>  <hr>  <div id="footer"> <p>Gerado %T por %h (%s)</p> <!-- %c --> </div> </body></html> 
\ No newline at end of file
diff -u -r -N squid-3.2.0.12/errors/pt-br/error-details.txt squid-3.2.0.13/errors/pt-br/error-details.txt
--- squid-3.2.0.12/errors/pt-br/error-details.txt	2011-09-16 23:49:01.000000000 +1200
+++ squid-3.2.0.13/errors/pt-br/error-details.txt	2011-10-14 16:05:12.000000000 +1300
@@ -46,19 +46,19 @@
 detail: "%ssl_error_descr: %ssl_subject"
 descr: "CRL has expired"
 
-name: X509_V_ERR_ERRO_IN_CERT_NOT_BEFORE_FIELD
+name: X509_V_ERR_ERROR_IN_CERT_NOT_BEFORE_FIELD
 detail: "SSL Certificate has invalid start date (the 'not before' field): %ssl_subject"
 descr: "Format error in certificate's notBefore field"
 
-name: X509_V_ERR_ERRO_IN_CERT_NOT_AFTER_FIELD
+name: X509_V_ERR_ERROR_IN_CERT_NOT_AFTER_FIELD
 detail: "SSL Certificate has invalid expiration date (the 'not after' field): %ssl_subject"
 descr: "Format error in certificate's notAfter field"
 
-name: X509_V_ERR_ERRO_IN_CRL_LAST_UPDATE_FIELD
+name: X509_V_ERR_ERROR_IN_CRL_LAST_UPDATE_FIELD
 detail: "%ssl_error_descr: %ssl_subject"
 descr: "Format error in CRL's lastUpdate field"
 
-name: X509_V_ERR_ERRO_IN_CRL_NEXT_UPDATE_FIELD
+name: X509_V_ERR_ERROR_IN_CRL_NEXT_UPDATE_FIELD
 detail: "%ssl_error_descr: %ssl_subject"
 descr: "Format error in CRL's nextUpdate field"
 
diff -u -r -N squid-3.2.0.12/errors/ro/ERR_CACHE_ACCESS_DENIED squid-3.2.0.13/errors/ro/ERR_CACHE_ACCESS_DENIED
--- squid-3.2.0.12/errors/ro/ERR_CACHE_ACCESS_DENIED	2011-09-16 23:49:23.000000000 +1200
+++ squid-3.2.0.13/errors/ro/ERR_CACHE_ACCESS_DENIED	2011-10-14 16:08:29.000000000 +1300
@@ -1 +1 @@
-<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd"> <html><head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8"> <title>EROARE: Cache Access Denied</title> <style type="text/css"><!--   %l  body :lang(fa) { direction: rtl; font-size: 100%; font-family: Tahoma, Roya, sans-serif; float: right; } :lang(he) { direction: rtl; }  --></style> </head><body id=%c> <div id="titles"> <h1>ERROR</h1> <h2>Cache Acces interzis.</h2> </div> <hr>  <div id="content"> <p>S-a recepţionat următoarea eroare când se încerca accesarea URL-ului: <a href="%U">%U</a></p>  <blockquote id="error"> <p><b>Interzis accesul la cache.</b></p> </blockquote>  <p>Ne pare rău, nu aveţi momentan permisiunea să accesaţi %U din acest cache până când nu vă autentificaţi.</p>  <p>Vă rugăm contactaţi <a href="mailto:%w%W">administratorul cache-ului</a> dacă aveţi dificultăţi în a vă autentifica sau <a href="http://%h/cgi-bin/chpasswd.cgi">schimbaţi-vă</a> parola implicită.</p>  <br> </div>  <hr>  <div id="footer"> <p>Generat %T de către %h (%s)</p> <!-- %c --> </div> </body></html> 
\ No newline at end of file
+<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd"> <html><head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8"> <title>EROARE: Cache Access Denied</title> <style type="text/css"><!--   %l  body :lang(fa) { direction: rtl; font-size: 100%; font-family: Tahoma, Roya, sans-serif; float: right; } :lang(he) { direction: rtl; }  --></style> </head><body id=%c> <div id="titles"> <h1>ERROR</h1> <h2>Cache Acces interzis.</h2> </div> <hr>  <div id="content"> <p>S-a recepţionat următoarea eroare când se încerca accesarea URL-ului: <a href="%U">%U</a></p>  <blockquote id="error"> <p><b>Interzis accesul la cache.</b></p> </blockquote>  <p>Ne pare rău, nu aveţi momentan permisiunea să accesaţi %U din acest cache până când nu vă autentificaţi.</p>  <p>Please contact the <a href="mailto:%w%W">cache administrator</a> if you have difficulties authenticating yourself.</p>  <br> </div>  <hr>  <div id="footer"> <p>Generat %T de către %h (%s)</p> <!-- %c --> </div> </body></html> 
\ No newline at end of file
diff -u -r -N squid-3.2.0.12/errors/ro/error-details.txt squid-3.2.0.13/errors/ro/error-details.txt
--- squid-3.2.0.12/errors/ro/error-details.txt	2011-09-16 23:49:40.000000000 +1200
+++ squid-3.2.0.13/errors/ro/error-details.txt	2011-10-14 16:11:21.000000000 +1300
@@ -46,19 +46,19 @@
 detail: "%ssl_error_descr: %ssl_subject"
 descr: "CRL has expired"
 
-name: X509_V_ERR_EROARE_IN_CERT_NOT_BEFORE_FIELD
+name: X509_V_ERR_ERROR_IN_CERT_NOT_BEFORE_FIELD
 detail: "SSL Certificate has invalid start date (the 'not before' field): %ssl_subject"
 descr: "Format error in certificate's notBefore field"
 
-name: X509_V_ERR_EROARE_IN_CERT_NOT_AFTER_FIELD
+name: X509_V_ERR_ERROR_IN_CERT_NOT_AFTER_FIELD
 detail: "SSL Certificate has invalid expiration date (the 'not after' field): %ssl_subject"
 descr: "Format error in certificate's notAfter field"
 
-name: X509_V_ERR_EROARE_IN_CRL_LAST_UPDATE_FIELD
+name: X509_V_ERR_ERROR_IN_CRL_LAST_UPDATE_FIELD
 detail: "%ssl_error_descr: %ssl_subject"
 descr: "Format error in CRL's lastUpdate field"
 
-name: X509_V_ERR_EROARE_IN_CRL_NEXT_UPDATE_FIELD
+name: X509_V_ERR_ERROR_IN_CRL_NEXT_UPDATE_FIELD
 detail: "%ssl_error_descr: %ssl_subject"
 descr: "Format error in CRL's nextUpdate field"
 
diff -u -r -N squid-3.2.0.12/errors/ru/ERR_CACHE_ACCESS_DENIED squid-3.2.0.13/errors/ru/ERR_CACHE_ACCESS_DENIED
--- squid-3.2.0.12/errors/ru/ERR_CACHE_ACCESS_DENIED	2011-09-16 23:49:42.000000000 +1200
+++ squid-3.2.0.13/errors/ru/ERR_CACHE_ACCESS_DENIED	2011-10-14 16:11:44.000000000 +1300
@@ -1 +1 @@
-<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd"> <html><head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8"> <title>ОШИБКА: Cache Access Denied</title> <style type="text/css"><!--   %l  body :lang(fa) { direction: rtl; font-size: 100%; font-family: Tahoma, Roya, sans-serif; float: right; } :lang(he) { direction: rtl; }  --></style> </head><body id=%c> <div id="titles"> <h1>ERROR</h1> <h2>Cache Доступ запрещён.</h2> </div> <hr>  <div id="content"> <p>При получении URL <a href="%U">%U</a> произошла следующая ошибка</p>  <blockquote id="error"> <p><b>Доступ к кэшу запрещён.</b></p> </blockquote>  <p>Извините, Вы не можете запросить %U из этого кэша до тех пор, пока не пройдёте аутентификацию.</p>  <p>Если у Вас возникли проблемы с аутентификацией, пожалуйста, свяжитесь с <a href="mailto:%w%W">администратором кэша</a> или <a href="http://%h/cgi-bin/chpasswd.cgi">смените</a> Ваш пароль по умолчанию.</p>  <br> </div>  <hr>  <div id="footer"> <p>Создано %T на %h (%s)</p> <!-- %c --> </div> </body></html> 
\ No newline at end of file
+<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd"> <html><head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8"> <title>ОШИБКА: Cache Access Denied</title> <style type="text/css"><!--   %l  body :lang(fa) { direction: rtl; font-size: 100%; font-family: Tahoma, Roya, sans-serif; float: right; } :lang(he) { direction: rtl; }  --></style> </head><body id=%c> <div id="titles"> <h1>ERROR</h1> <h2>Cache Доступ запрещён.</h2> </div> <hr>  <div id="content"> <p>При получении URL <a href="%U">%U</a> произошла следующая ошибка</p>  <blockquote id="error"> <p><b>Доступ к кэшу запрещён.</b></p> </blockquote>  <p>Извините, Вы не можете запросить %U из этого кэша до тех пор, пока не пройдёте аутентификацию.</p>  <p>Please contact the <a href="mailto:%w%W">cache administrator</a> if you have difficulties authenticating yourself.</p>  <br> </div>  <hr>  <div id="footer"> <p>Создано %T на %h (%s)</p> <!-- %c --> </div> </body></html> 
\ No newline at end of file
diff -u -r -N squid-3.2.0.12/errors/ru/error-details.txt squid-3.2.0.13/errors/ru/error-details.txt
--- squid-3.2.0.12/errors/ru/error-details.txt	2011-09-16 23:49:59.000000000 +1200
+++ squid-3.2.0.13/errors/ru/error-details.txt	2011-10-14 16:13:50.000000000 +1300
@@ -46,19 +46,19 @@
 detail: "%ssl_error_descr: %ssl_subject"
 descr: "CRL has expired"
 
-name: X509_V_ERR_ОШИБКА_IN_CERT_NOT_BEFORE_FIELD
+name: X509_V_ERR_ERROR_IN_CERT_NOT_BEFORE_FIELD
 detail: "SSL Certificate has invalid start date (the 'not before' field): %ssl_subject"
 descr: "Format error in certificate's notBefore field"
 
-name: X509_V_ERR_ОШИБКА_IN_CERT_NOT_AFTER_FIELD
+name: X509_V_ERR_ERROR_IN_CERT_NOT_AFTER_FIELD
 detail: "SSL Certificate has invalid expiration date (the 'not after' field): %ssl_subject"
 descr: "Format error in certificate's notAfter field"
 
-name: X509_V_ERR_ОШИБКА_IN_CRL_LAST_UPDATE_FIELD
+name: X509_V_ERR_ERROR_IN_CRL_LAST_UPDATE_FIELD
 detail: "%ssl_error_descr: %ssl_subject"
 descr: "Format error in CRL's lastUpdate field"
 
-name: X509_V_ERR_ОШИБКА_IN_CRL_NEXT_UPDATE_FIELD
+name: X509_V_ERR_ERROR_IN_CRL_NEXT_UPDATE_FIELD
 detail: "%ssl_error_descr: %ssl_subject"
 descr: "Format error in CRL's nextUpdate field"
 
diff -u -r -N squid-3.2.0.12/errors/sk/ERR_CACHE_ACCESS_DENIED squid-3.2.0.13/errors/sk/ERR_CACHE_ACCESS_DENIED
--- squid-3.2.0.12/errors/sk/ERR_CACHE_ACCESS_DENIED	2011-09-16 23:50:02.000000000 +1200
+++ squid-3.2.0.13/errors/sk/ERR_CACHE_ACCESS_DENIED	2011-10-14 16:14:00.000000000 +1300
@@ -1 +1 @@
-<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd"> <html><head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8"> <title>CHYBA: Cache Access Denied</title> <style type="text/css"><!--   %l  body :lang(fa) { direction: rtl; font-size: 100%; font-family: Tahoma, Roya, sans-serif; float: right; } :lang(he) { direction: rtl; }  --></style> </head><body id=%c> <div id="titles"> <h1>ERROR</h1> <h2>Cache Prístup zamietnutý.</h2> </div> <hr>  <div id="content"> <p>Pri pokuse o získanie URL sa vyskytla nasledovná chyba: <a href="%U">%U</a></p>  <blockquote id="error"> <p><b>Prístup ku cache zamietnutý.</b></p> </blockquote>  <p>Ľutujeme, prístup k dokumentu %U z cache vám bude povolený až po tom ako sa autentifikujete.</p>  <p>Ak máte problém pri autentifikácii, kontaktujte prosím <a href="mailto:%w%W">správcu cache</a> alebo si <a href="http://%h/cgi-bin/chpasswd.cgi">zmeňte</a> svoje predvolené heslo.</p>  <br> </div>  <hr>  <div id="footer"> <p>Vytvoril %T, %h (%s)</p> <!-- %c --> </div> </body></html> 
\ No newline at end of file
+<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd"> <html><head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8"> <title>CHYBA: Cache Access Denied</title> <style type="text/css"><!--   %l  body :lang(fa) { direction: rtl; font-size: 100%; font-family: Tahoma, Roya, sans-serif; float: right; } :lang(he) { direction: rtl; }  --></style> </head><body id=%c> <div id="titles"> <h1>ERROR</h1> <h2>Cache Prístup zamietnutý.</h2> </div> <hr>  <div id="content"> <p>Pri pokuse o získanie URL sa vyskytla nasledovná chyba: <a href="%U">%U</a></p>  <blockquote id="error"> <p><b>Prístup ku cache zamietnutý.</b></p> </blockquote>  <p>Ľutujeme, prístup k dokumentu %U z cache vám bude povolený až po tom ako sa autentifikujete.</p>  <p>Please contact the <a href="mailto:%w%W">cache administrator</a> if you have difficulties authenticating yourself.</p>  <br> </div>  <hr>  <div id="footer"> <p>Vytvoril %T, %h (%s)</p> <!-- %c --> </div> </body></html> 
\ No newline at end of file
diff -u -r -N squid-3.2.0.12/errors/sk/error-details.txt squid-3.2.0.13/errors/sk/error-details.txt
--- squid-3.2.0.12/errors/sk/error-details.txt	2011-09-16 23:50:21.000000000 +1200
+++ squid-3.2.0.13/errors/sk/error-details.txt	2011-10-14 16:15:39.000000000 +1300
@@ -46,19 +46,19 @@
 detail: "%ssl_error_descr: %ssl_subject"
 descr: "CRL has expired"
 
-name: X509_V_ERR_CHYBA_IN_CERT_NOT_BEFORE_FIELD
+name: X509_V_ERR_ERROR_IN_CERT_NOT_BEFORE_FIELD
 detail: "SSL Certificate has invalid start date (the 'not before' field): %ssl_subject"
 descr: "Format error in certificate's notBefore field"
 
-name: X509_V_ERR_CHYBA_IN_CERT_NOT_AFTER_FIELD
+name: X509_V_ERR_ERROR_IN_CERT_NOT_AFTER_FIELD
 detail: "SSL Certificate has invalid expiration date (the 'not after' field): %ssl_subject"
 descr: "Format error in certificate's notAfter field"
 
-name: X509_V_ERR_CHYBA_IN_CRL_LAST_UPDATE_FIELD
+name: X509_V_ERR_ERROR_IN_CRL_LAST_UPDATE_FIELD
 detail: "%ssl_error_descr: %ssl_subject"
 descr: "Format error in CRL's lastUpdate field"
 
-name: X509_V_ERR_CHYBA_IN_CRL_NEXT_UPDATE_FIELD
+name: X509_V_ERR_ERROR_IN_CRL_NEXT_UPDATE_FIELD
 detail: "%ssl_error_descr: %ssl_subject"
 descr: "Format error in CRL's nextUpdate field"
 
diff -u -r -N squid-3.2.0.12/errors/sl/ERR_CACHE_ACCESS_DENIED squid-3.2.0.13/errors/sl/ERR_CACHE_ACCESS_DENIED
--- squid-3.2.0.12/errors/sl/ERR_CACHE_ACCESS_DENIED	2011-09-16 23:50:23.000000000 +1200
+++ squid-3.2.0.13/errors/sl/ERR_CACHE_ACCESS_DENIED	2011-10-14 16:15:54.000000000 +1300
@@ -1 +1 @@
-<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd"> <html><head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8"> <title>NAPAKA: Cache Access Denied</title> <style type="text/css"><!--   %l  body :lang(fa) { direction: rtl; font-size: 100%; font-family: Tahoma, Roya, sans-serif; float: right; } :lang(he) { direction: rtl; }  --></style> </head><body id=%c> <div id="titles"> <h1>ERROR</h1> <h2>Cache Dostop zavrnjen.</h2> </div> <hr>  <div id="content"> <p>Prišlo je do napake med poskusom nalaganja naslova URL: <a href="%U">%U</a></p>  <blockquote id="error"> <p><b>Dostop do predpomnilnika zavrnjen.</b></p> </blockquote>  <p>Žal trenutno ne morete zahtevati %U od tega predpomnilnika, dokler ne potrdite svoje istovetnosti.</p>  <p>Obrnite se na <a href="mailto:%w%W">skrbnika predpomnilnika</a>, če imate težave pri avtentikaciji, ali pa <a href="http://%h/cgi-bin/chpasswd.cgi">spremenite</a> svoje privzeto geslo.</p>  <br> </div>  <hr>  <div id="footer"> <p>Ustvaril %h (%s) dne %T</p> <!-- %c --> </div> </body></html> 
\ No newline at end of file
+<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd"> <html><head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8"> <title>NAPAKA: Cache Access Denied</title> <style type="text/css"><!--   %l  body :lang(fa) { direction: rtl; font-size: 100%; font-family: Tahoma, Roya, sans-serif; float: right; } :lang(he) { direction: rtl; }  --></style> </head><body id=%c> <div id="titles"> <h1>ERROR</h1> <h2>Cache Dostop zavrnjen.</h2> </div> <hr>  <div id="content"> <p>Prišlo je do napake med poskusom nalaganja naslova URL: <a href="%U">%U</a></p>  <blockquote id="error"> <p><b>Dostop do predpomnilnika zavrnjen.</b></p> </blockquote>  <p>Žal trenutno ne morete zahtevati %U od tega predpomnilnika, dokler ne potrdite svoje istovetnosti.</p>  <p>Please contact the <a href="mailto:%w%W">cache administrator</a> if you have difficulties authenticating yourself.</p>  <br> </div>  <hr>  <div id="footer"> <p>Ustvaril %h (%s) dne %T</p> <!-- %c --> </div> </body></html> 
\ No newline at end of file
diff -u -r -N squid-3.2.0.12/errors/sl/error-details.txt squid-3.2.0.13/errors/sl/error-details.txt
--- squid-3.2.0.12/errors/sl/error-details.txt	2011-09-16 23:50:41.000000000 +1200
+++ squid-3.2.0.13/errors/sl/error-details.txt	2011-10-14 16:17:39.000000000 +1300
@@ -46,19 +46,19 @@
 detail: "%ssl_error_descr: %ssl_subject"
 descr: "CRL has expired"
 
-name: X509_V_ERR_NAPAKA_IN_CERT_NOT_BEFORE_FIELD
+name: X509_V_ERR_ERROR_IN_CERT_NOT_BEFORE_FIELD
 detail: "SSL Certificate has invalid start date (the 'not before' field): %ssl_subject"
 descr: "Format error in certificate's notBefore field"
 
-name: X509_V_ERR_NAPAKA_IN_CERT_NOT_AFTER_FIELD
+name: X509_V_ERR_ERROR_IN_CERT_NOT_AFTER_FIELD
 detail: "SSL Certificate has invalid expiration date (the 'not after' field): %ssl_subject"
 descr: "Format error in certificate's notAfter field"
 
-name: X509_V_ERR_NAPAKA_IN_CRL_LAST_UPDATE_FIELD
+name: X509_V_ERR_ERROR_IN_CRL_LAST_UPDATE_FIELD
 detail: "%ssl_error_descr: %ssl_subject"
 descr: "Format error in CRL's lastUpdate field"
 
-name: X509_V_ERR_NAPAKA_IN_CRL_NEXT_UPDATE_FIELD
+name: X509_V_ERR_ERROR_IN_CRL_NEXT_UPDATE_FIELD
 detail: "%ssl_error_descr: %ssl_subject"
 descr: "Format error in CRL's nextUpdate field"
 
diff -u -r -N squid-3.2.0.12/errors/sr-cyrl/ERR_CACHE_ACCESS_DENIED squid-3.2.0.13/errors/sr-cyrl/ERR_CACHE_ACCESS_DENIED
--- squid-3.2.0.12/errors/sr-cyrl/ERR_CACHE_ACCESS_DENIED	2011-09-16 23:50:43.000000000 +1200
+++ squid-3.2.0.13/errors/sr-cyrl/ERR_CACHE_ACCESS_DENIED	2011-10-14 16:17:50.000000000 +1300
@@ -1 +1 @@
-<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd"> <html><head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8"> <title>ERROR: Cache Access Denied</title> <style type="text/css"><!--   %l  body :lang(fa) { direction: rtl; font-size: 100%; font-family: Tahoma, Roya, sans-serif; float: right; } :lang(he) { direction: rtl; }  --></style> </head><body id=%c> <div id="titles"> <h1>ERROR</h1> <h2>Cache Access Denied.</h2> </div> <hr>  <div id="content"> <p>The following error was encountered while trying to retrieve the URL: <a href="%U">%U</a></p>  <blockquote id="error"> <p><b>Cache Access Denied.</b></p> </blockquote>  <p>Sorry, you are not currently allowed to request %U from this cache until you have authenticated yourself.</p>  <p>Please contact the <a href="mailto:%w%W">cache administrator</a> if you have difficulties authenticating yourself or <a href="http://%h/cgi-bin/chpasswd.cgi">change</a> your default password.</p>  <br> </div>  <hr>  <div id="footer"> <p>Generated %T by %h (%s)</p> <!-- %c --> </div> </body></html> 
\ No newline at end of file
+<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd"> <html><head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8"> <title>ERROR: Cache Access Denied</title> <style type="text/css"><!--   %l  body :lang(fa) { direction: rtl; font-size: 100%; font-family: Tahoma, Roya, sans-serif; float: right; } :lang(he) { direction: rtl; }  --></style> </head><body id=%c> <div id="titles"> <h1>ERROR</h1> <h2>Cache Access Denied.</h2> </div> <hr>  <div id="content"> <p>The following error was encountered while trying to retrieve the URL: <a href="%U">%U</a></p>  <blockquote id="error"> <p><b>Cache Access Denied.</b></p> </blockquote>  <p>Sorry, you are not currently allowed to request %U from this cache until you have authenticated yourself.</p>  <p>Please contact the <a href="mailto:%w%W">cache administrator</a> if you have difficulties authenticating yourself.</p>  <br> </div>  <hr>  <div id="footer"> <p>Generated %T by %h (%s)</p> <!-- %c --> </div> </body></html> 
\ No newline at end of file
diff -u -r -N squid-3.2.0.12/errors/sr-latn/ERR_CACHE_ACCESS_DENIED squid-3.2.0.13/errors/sr-latn/ERR_CACHE_ACCESS_DENIED
--- squid-3.2.0.12/errors/sr-latn/ERR_CACHE_ACCESS_DENIED	2011-09-16 23:51:06.000000000 +1200
+++ squid-3.2.0.13/errors/sr-latn/ERR_CACHE_ACCESS_DENIED	2011-10-14 16:19:16.000000000 +1300
@@ -1 +1 @@
-<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd"> <html><head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8"> <title>GREŠKA: Cache Access Denied</title> <style type="text/css"><!--   %l  body :lang(fa) { direction: rtl; font-size: 100%; font-family: Tahoma, Roya, sans-serif; float: right; } :lang(he) { direction: rtl; }  --></style> </head><body id=%c> <div id="titles"> <h1>ERROR</h1> <h2>Cache Pristup nije dozvoljen.</h2> </div> <hr>  <div id="content"> <p>Greška učitavanja podataka sa adrese (URL): <a href="%U">%U</a></p>  <blockquote id="error"> <p><b>Pristup proksi/keš serveru nije dozvoljen.</b></p> </blockquote>  <p>Na žalost nije vam dozvoljen da zahtev %U od ovog proksi servera ukoliko se ne autentifikujete.</p>  <p>Molimo kontaktirajte <a href="mailto:%w%W">keš administratora</a> ako imate problema sa autentifikacijom ili <a href="http://%h/cgi-bin/chpasswd.cgi">promenite</a> vašu šifru.</p>  <br> </div>  <hr>  <div id="footer"> <p>Generisano %T sa %h (%s)</p> <!-- %c --> </div> </body></html> 
\ No newline at end of file
+<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd"> <html><head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8"> <title>GREŠKA: Cache Access Denied</title> <style type="text/css"><!--   %l  body :lang(fa) { direction: rtl; font-size: 100%; font-family: Tahoma, Roya, sans-serif; float: right; } :lang(he) { direction: rtl; }  --></style> </head><body id=%c> <div id="titles"> <h1>ERROR</h1> <h2>Cache Pristup nije dozvoljen.</h2> </div> <hr>  <div id="content"> <p>Greška učitavanja podataka sa adrese (URL): <a href="%U">%U</a></p>  <blockquote id="error"> <p><b>Pristup proksi/keš serveru nije dozvoljen.</b></p> </blockquote>  <p>Na žalost nije vam dozvoljen da zahtev %U od ovog proksi servera ukoliko se ne autentifikujete.</p>  <p>Please contact the <a href="mailto:%w%W">cache administrator</a> if you have difficulties authenticating yourself.</p>  <br> </div>  <hr>  <div id="footer"> <p>Generisano %T sa %h (%s)</p> <!-- %c --> </div> </body></html> 
\ No newline at end of file
diff -u -r -N squid-3.2.0.12/errors/sr-latn/error-details.txt squid-3.2.0.13/errors/sr-latn/error-details.txt
--- squid-3.2.0.12/errors/sr-latn/error-details.txt	2011-09-16 23:51:25.000000000 +1200
+++ squid-3.2.0.13/errors/sr-latn/error-details.txt	2011-10-14 16:20:57.000000000 +1300
@@ -46,19 +46,19 @@
 detail: "%ssl_error_descr: %ssl_subject"
 descr: "CRL has expired"
 
-name: X509_V_ERR_GREŠKA_IN_CERT_NOT_BEFORE_FIELD
+name: X509_V_ERR_ERROR_IN_CERT_NOT_BEFORE_FIELD
 detail: "SSL Certificate has invalid start date (the 'not before' field): %ssl_subject"
 descr: "Format error in certificate's notBefore field"
 
-name: X509_V_ERR_GREŠKA_IN_CERT_NOT_AFTER_FIELD
+name: X509_V_ERR_ERROR_IN_CERT_NOT_AFTER_FIELD
 detail: "SSL Certificate has invalid expiration date (the 'not after' field): %ssl_subject"
 descr: "Format error in certificate's notAfter field"
 
-name: X509_V_ERR_GREŠKA_IN_CRL_LAST_UPDATE_FIELD
+name: X509_V_ERR_ERROR_IN_CRL_LAST_UPDATE_FIELD
 detail: "%ssl_error_descr: %ssl_subject"
 descr: "Format error in CRL's lastUpdate field"
 
-name: X509_V_ERR_GREŠKA_IN_CRL_NEXT_UPDATE_FIELD
+name: X509_V_ERR_ERROR_IN_CRL_NEXT_UPDATE_FIELD
 detail: "%ssl_error_descr: %ssl_subject"
 descr: "Format error in CRL's nextUpdate field"
 
diff -u -r -N squid-3.2.0.12/errors/sv/ERR_CACHE_ACCESS_DENIED squid-3.2.0.13/errors/sv/ERR_CACHE_ACCESS_DENIED
--- squid-3.2.0.12/errors/sv/ERR_CACHE_ACCESS_DENIED	2011-09-16 23:51:27.000000000 +1200
+++ squid-3.2.0.13/errors/sv/ERR_CACHE_ACCESS_DENIED	2011-10-14 16:21:22.000000000 +1300
@@ -1 +1 @@
-<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd"> <html><head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8"> <title>FEL: Cache Access Denied</title> <style type="text/css"><!--   %l  body :lang(fa) { direction: rtl; font-size: 100%; font-family: Tahoma, Roya, sans-serif; float: right; } :lang(he) { direction: rtl; }  --></style> </head><body id=%c> <div id="titles"> <h1>ERROR</h1> <h2>Cache Tilltr&auml;de Nekas.</h2> </div> <hr>  <div id="content"> <p>F&ouml;ljande fel p&aring;tr&auml;ffades vid h&auml;mtning av URL: <a href="%U">%U</a></p>  <blockquote id="error"> <p><b>Tilltr&auml;de till Cache Nekas.</b></p> </blockquote>  <p>Ledsen, Ni &auml;r f&ouml;rn&auml;rvarande ej ber&auml;ttigad att beg&auml;ra %U fr&aring;n denna cache tills det att Ni har autentifierat Er.</p>  <p>V&auml;nligen kontakta <a href="mailto:%w%W">cacheadministratorn</a> om Ni har sv&aring;righ eter med att autentifiera Er sj&auml;lv, eller <a href="http://%h/cgi-bin/chpasswd.cgi">byt</a> Ert l&ouml;senord.</p>  <br> </div>  <hr>  <div id="footer"> <p>Skapad %T av %h (%s)</p> <!-- %c --> </div> </body></html> 
\ No newline at end of file
+<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd"> <html><head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8"> <title>FEL: Cache Access Denied</title> <style type="text/css"><!--   %l  body :lang(fa) { direction: rtl; font-size: 100%; font-family: Tahoma, Roya, sans-serif; float: right; } :lang(he) { direction: rtl; }  --></style> </head><body id=%c> <div id="titles"> <h1>ERROR</h1> <h2>Cache Tilltr&auml;de Nekas.</h2> </div> <hr>  <div id="content"> <p>F&ouml;ljande fel p&aring;tr&auml;ffades vid h&auml;mtning av URL: <a href="%U">%U</a></p>  <blockquote id="error"> <p><b>Tilltr&auml;de till Cache Nekas.</b></p> </blockquote>  <p>Ledsen, Ni &auml;r f&ouml;rn&auml;rvarande ej ber&auml;ttigad att beg&auml;ra %U fr&aring;n denna cache tills det att Ni har autentifierat Er.</p>  <p>Please contact the <a href="mailto:%w%W">cache administrator</a> if you have difficulties authenticating yourself.</p>  <br> </div>  <hr>  <div id="footer"> <p>Skapad %T av %h (%s)</p> <!-- %c --> </div> </body></html> 
\ No newline at end of file
diff -u -r -N squid-3.2.0.12/errors/sv/error-details.txt squid-3.2.0.13/errors/sv/error-details.txt
--- squid-3.2.0.12/errors/sv/error-details.txt	2011-09-16 23:51:45.000000000 +1200
+++ squid-3.2.0.13/errors/sv/error-details.txt	2011-10-14 16:23:51.000000000 +1300
@@ -46,19 +46,19 @@
 detail: "%ssl_error_descr: %ssl_subject"
 descr: "CRL has expired"
 
-name: X509_V_ERR_FEL_IN_CERT_NOT_BEFORE_FIELD
+name: X509_V_ERR_ERROR_IN_CERT_NOT_BEFORE_FIELD
 detail: "SSL Certificate has invalid start date (the 'not before' field): %ssl_subject"
 descr: "Format error in certificate's notBefore field"
 
-name: X509_V_ERR_FEL_IN_CERT_NOT_AFTER_FIELD
+name: X509_V_ERR_ERROR_IN_CERT_NOT_AFTER_FIELD
 detail: "SSL Certificate has invalid expiration date (the 'not after' field): %ssl_subject"
 descr: "Format error in certificate's notAfter field"
 
-name: X509_V_ERR_FEL_IN_CRL_LAST_UPDATE_FIELD
+name: X509_V_ERR_ERROR_IN_CRL_LAST_UPDATE_FIELD
 detail: "%ssl_error_descr: %ssl_subject"
 descr: "Format error in CRL's lastUpdate field"
 
-name: X509_V_ERR_FEL_IN_CRL_NEXT_UPDATE_FIELD
+name: X509_V_ERR_ERROR_IN_CRL_NEXT_UPDATE_FIELD
 detail: "%ssl_error_descr: %ssl_subject"
 descr: "Format error in CRL's nextUpdate field"
 
diff -u -r -N squid-3.2.0.12/errors/templates/ERR_CACHE_ACCESS_DENIED squid-3.2.0.13/errors/templates/ERR_CACHE_ACCESS_DENIED
--- squid-3.2.0.12/errors/templates/ERR_CACHE_ACCESS_DENIED	2011-09-16 23:37:30.000000000 +1200
+++ squid-3.2.0.13/errors/templates/ERR_CACHE_ACCESS_DENIED	2011-10-14 14:42:56.000000000 +1300
@@ -25,7 +25,7 @@
 
 <p>Sorry, you are not currently allowed to request %U from this cache until you have authenticated yourself.</p>
 
-<p>Please contact the <a href="mailto:%w%W">cache administrator</a> if you have difficulties authenticating yourself or <a href="http://%h/cgi-bin/chpasswd.cgi">change</a> your default password.</p>
+<p>Please contact the <a href="mailto:%w%W">cache administrator</a> if you have difficulties authenticating yourself.</p>
 
 <br>
 </div>
diff -u -r -N squid-3.2.0.12/errors/th/ERR_CACHE_ACCESS_DENIED squid-3.2.0.13/errors/th/ERR_CACHE_ACCESS_DENIED
--- squid-3.2.0.12/errors/th/ERR_CACHE_ACCESS_DENIED	2011-09-16 23:51:48.000000000 +1200
+++ squid-3.2.0.13/errors/th/ERR_CACHE_ACCESS_DENIED	2011-10-14 16:24:08.000000000 +1300
@@ -1 +1 @@
-<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd"> <html><head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8"> <title>ERROR: การเรียกใช้ระบบแคชไม่ได้รับอนุญาต</title> <style type="text/css"><!--   %l  body :lang(fa) { direction: rtl; font-size: 100%; font-family: Tahoma, Roya, sans-serif; float: right; } :lang(he) { direction: rtl; }  --></style> </head><body id=%c> <div id="titles"> <h1>ERROR</h1> <h2>การเรียกใช้ระบบแคชไม่ได้รับอนุญาต</h2> </div> <hr>  <div id="content"> <p>พบความผิดพลาดดังต่อไปนี้ระหว่างที่พยายามเรียกดู URL: <a href="%U">%U</a></p>  <blockquote id="error"> <p><b>Cache Access Denied.</b></p> </blockquote>  <p>Sorry, you are not currently allowed to request %U from this cache until you have authenticated yourself.</p>  <p>Please contact the <a href="mailto:%w%W">cache administrator</a> if you have difficulties authenticating yourself or <a href="http://%h/cgi-bin/chpasswd.cgi">change</a> your default password.</p>  <br> </div>  <hr>  <div id="footer"> <p>Generated %T by %h (%s)</p> <!-- %c --> </div> </body></html> 
\ No newline at end of file
+<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd"> <html><head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8"> <title>ERROR: การเรียกใช้ระบบแคชไม่ได้รับอนุญาต</title> <style type="text/css"><!--   %l  body :lang(fa) { direction: rtl; font-size: 100%; font-family: Tahoma, Roya, sans-serif; float: right; } :lang(he) { direction: rtl; }  --></style> </head><body id=%c> <div id="titles"> <h1>ERROR</h1> <h2>การเรียกใช้ระบบแคชไม่ได้รับอนุญาต</h2> </div> <hr>  <div id="content"> <p>พบความผิดพลาดดังต่อไปนี้ระหว่างที่พยายามเรียกดู URL: <a href="%U">%U</a></p>  <blockquote id="error"> <p><b>Cache Access Denied.</b></p> </blockquote>  <p>Sorry, you are not currently allowed to request %U from this cache until you have authenticated yourself.</p>  <p>Please contact the <a href="mailto:%w%W">cache administrator</a> if you have difficulties authenticating yourself.</p>  <br> </div>  <hr>  <div id="footer"> <p>Generated %T by %h (%s)</p> <!-- %c --> </div> </body></html> 
\ No newline at end of file
diff -u -r -N squid-3.2.0.12/errors/tr/ERR_CACHE_ACCESS_DENIED squid-3.2.0.13/errors/tr/ERR_CACHE_ACCESS_DENIED
--- squid-3.2.0.12/errors/tr/ERR_CACHE_ACCESS_DENIED	2011-09-16 23:52:07.000000000 +1200
+++ squid-3.2.0.13/errors/tr/ERR_CACHE_ACCESS_DENIED	2011-10-14 16:27:20.000000000 +1300
@@ -1 +1 @@
-<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd"> <html><head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8"> <title>HATA: Cache Access Denied</title> <style type="text/css"><!--   %l  body :lang(fa) { direction: rtl; font-size: 100%; font-family: Tahoma, Roya, sans-serif; float: right; } :lang(he) { direction: rtl; }  --></style> </head><body id=%c> <div id="titles"> <h1>ERROR</h1> <h2>Cache Erişim Yasak.</h2> </div> <hr>  <div id="content"> <p>URL adresine erişilmeye çalışıyorken hata meydana geldi: <a href="%U">%U</a></p>  <blockquote id="error"> <p><b>Cache Sunucusunu Kullanamazsınız.</b></p> </blockquote>  <p>Özür dilerim, istediğiniz %U adresine bu Cache Sunucusunu kullanarak ulaşamazsınız.</p>  <p>Lütfen <a href="mailto:%w%W">Cache Yöneticisi</a> ile bağlantıya geçin, veya şifrenizi değiştirmek için <a href="http://%h/cgi-bin/chpasswd.cgi">buraya</a> tıklayın.</p>  <br> </div>  <hr>  <div id="footer"> <p>%h (%s) tarafından %T oluşturuldu</p> <!-- %c --> </div> </body></html> 
\ No newline at end of file
+<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd"> <html><head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8"> <title>HATA: Cache Access Denied</title> <style type="text/css"><!--   %l  body :lang(fa) { direction: rtl; font-size: 100%; font-family: Tahoma, Roya, sans-serif; float: right; } :lang(he) { direction: rtl; }  --></style> </head><body id=%c> <div id="titles"> <h1>ERROR</h1> <h2>Cache Erişim Yasak.</h2> </div> <hr>  <div id="content"> <p>URL adresine erişilmeye çalışıyorken hata meydana geldi: <a href="%U">%U</a></p>  <blockquote id="error"> <p><b>Cache Sunucusunu Kullanamazsınız.</b></p> </blockquote>  <p>Özür dilerim, istediğiniz %U adresine bu Cache Sunucusunu kullanarak ulaşamazsınız.</p>  <p>Please contact the <a href="mailto:%w%W">cache administrator</a> if you have difficulties authenticating yourself.</p>  <br> </div>  <hr>  <div id="footer"> <p>%h (%s) tarafından %T oluşturuldu</p> <!-- %c --> </div> </body></html> 
\ No newline at end of file
diff -u -r -N squid-3.2.0.12/errors/tr/error-details.txt squid-3.2.0.13/errors/tr/error-details.txt
--- squid-3.2.0.12/errors/tr/error-details.txt	2011-09-16 23:52:25.000000000 +1200
+++ squid-3.2.0.13/errors/tr/error-details.txt	2011-10-14 16:30:11.000000000 +1300
@@ -46,19 +46,19 @@
 detail: "%ssl_error_descr: %ssl_subject"
 descr: "CRL has expired"
 
-name: X509_V_ERR_HATA_IN_CERT_NOT_BEFORE_FIELD
+name: X509_V_ERR_ERROR_IN_CERT_NOT_BEFORE_FIELD
 detail: "SSL Certificate has invalid start date (the 'not before' field): %ssl_subject"
 descr: "Format error in certificate's notBefore field"
 
-name: X509_V_ERR_HATA_IN_CERT_NOT_AFTER_FIELD
+name: X509_V_ERR_ERROR_IN_CERT_NOT_AFTER_FIELD
 detail: "SSL Certificate has invalid expiration date (the 'not after' field): %ssl_subject"
 descr: "Format error in certificate's notAfter field"
 
-name: X509_V_ERR_HATA_IN_CRL_LAST_UPDATE_FIELD
+name: X509_V_ERR_ERROR_IN_CRL_LAST_UPDATE_FIELD
 detail: "%ssl_error_descr: %ssl_subject"
 descr: "Format error in CRL's lastUpdate field"
 
-name: X509_V_ERR_HATA_IN_CRL_NEXT_UPDATE_FIELD
+name: X509_V_ERR_ERROR_IN_CRL_NEXT_UPDATE_FIELD
 detail: "%ssl_error_descr: %ssl_subject"
 descr: "Format error in CRL's nextUpdate field"
 
diff -u -r -N squid-3.2.0.12/errors/uk/ERR_CACHE_ACCESS_DENIED squid-3.2.0.13/errors/uk/ERR_CACHE_ACCESS_DENIED
--- squid-3.2.0.12/errors/uk/ERR_CACHE_ACCESS_DENIED	2011-09-16 23:52:27.000000000 +1200
+++ squid-3.2.0.13/errors/uk/ERR_CACHE_ACCESS_DENIED	2011-10-14 16:30:30.000000000 +1300
@@ -1 +1 @@
-<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd"> <html><head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8"> <title>ПОМИЛКА: Cache Access Denied</title> <style type="text/css"><!--   %l  body :lang(fa) { direction: rtl; font-size: 100%; font-family: Tahoma, Roya, sans-serif; float: right; } :lang(he) { direction: rtl; }  --></style> </head><body id=%c> <div id="titles"> <h1>ERROR</h1> <h2>Cache Доступ заборонено</h2> </div> <hr>  <div id="content"> <p>При отриманні URL: <a href="%U">%U</a> виникла помилка.</p>  <blockquote id="error"> <p><b>Доступ до кешу заборонено</b></p> </blockquote>  <p>Вибачте, Вам зараз не дозволено запитувати %U з цього кешу. Спочатку авторизуйтеся.</p>  <p>Будь-ласка, зв'яжіться з <a href="mailto:%w%W">Адміністратором кешу</a>, якщо у Вас виникли труднощі з авторизацією, або <a href="http://%h/cgi-bin/chpasswd.cgi">змініть</a> Ваш пароль.</p>  <br> </div>  <hr>  <div id="footer"> <p>Згенеровано %T на %h (%s)</p> <!-- %c --> </div> </body></html> 
\ No newline at end of file
+<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd"> <html><head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8"> <title>ПОМИЛКА: Cache Access Denied</title> <style type="text/css"><!--   %l  body :lang(fa) { direction: rtl; font-size: 100%; font-family: Tahoma, Roya, sans-serif; float: right; } :lang(he) { direction: rtl; }  --></style> </head><body id=%c> <div id="titles"> <h1>ERROR</h1> <h2>Cache Доступ заборонено</h2> </div> <hr>  <div id="content"> <p>При отриманні URL: <a href="%U">%U</a> виникла помилка.</p>  <blockquote id="error"> <p><b>Доступ до кешу заборонено</b></p> </blockquote>  <p>Вибачте, Вам зараз не дозволено запитувати %U з цього кешу. Спочатку авторизуйтеся.</p>  <p>Please contact the <a href="mailto:%w%W">cache administrator</a> if you have difficulties authenticating yourself.</p>  <br> </div>  <hr>  <div id="footer"> <p>Згенеровано %T на %h (%s)</p> <!-- %c --> </div> </body></html> 
\ No newline at end of file
diff -u -r -N squid-3.2.0.12/errors/uk/error-details.txt squid-3.2.0.13/errors/uk/error-details.txt
--- squid-3.2.0.12/errors/uk/error-details.txt	2011-09-16 23:52:44.000000000 +1200
+++ squid-3.2.0.13/errors/uk/error-details.txt	2011-10-14 16:33:33.000000000 +1300
@@ -46,19 +46,19 @@
 detail: "%ssl_error_descr: %ssl_subject"
 descr: "CRL has expired"
 
-name: X509_V_ERR_ПОМИЛКА_IN_CERT_NOT_BEFORE_FIELD
+name: X509_V_ERR_ERROR_IN_CERT_NOT_BEFORE_FIELD
 detail: "SSL Certificate has invalid start date (the 'not before' field): %ssl_subject"
 descr: "Format error in certificate's notBefore field"
 
-name: X509_V_ERR_ПОМИЛКА_IN_CERT_NOT_AFTER_FIELD
+name: X509_V_ERR_ERROR_IN_CERT_NOT_AFTER_FIELD
 detail: "SSL Certificate has invalid expiration date (the 'not after' field): %ssl_subject"
 descr: "Format error in certificate's notAfter field"
 
-name: X509_V_ERR_ПОМИЛКА_IN_CRL_LAST_UPDATE_FIELD
+name: X509_V_ERR_ERROR_IN_CRL_LAST_UPDATE_FIELD
 detail: "%ssl_error_descr: %ssl_subject"
 descr: "Format error in CRL's lastUpdate field"
 
-name: X509_V_ERR_ПОМИЛКА_IN_CRL_NEXT_UPDATE_FIELD
+name: X509_V_ERR_ERROR_IN_CRL_NEXT_UPDATE_FIELD
 detail: "%ssl_error_descr: %ssl_subject"
 descr: "Format error in CRL's nextUpdate field"
 
diff -u -r -N squid-3.2.0.12/errors/uz/ERR_CACHE_ACCESS_DENIED squid-3.2.0.13/errors/uz/ERR_CACHE_ACCESS_DENIED
--- squid-3.2.0.12/errors/uz/ERR_CACHE_ACCESS_DENIED	2011-09-16 23:52:46.000000000 +1200
+++ squid-3.2.0.13/errors/uz/ERR_CACHE_ACCESS_DENIED	2011-10-14 16:33:49.000000000 +1300
@@ -1 +1 @@
-<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd"> <html><head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8"> <title>ХАТО: Cache Access Denied</title> <style type="text/css"><!--   %l  body :lang(fa) { direction: rtl; font-size: 100%; font-family: Tahoma, Roya, sans-serif; float: right; } :lang(he) { direction: rtl; }  --></style> </head><body id=%c> <div id="titles"> <h1>ERROR</h1> <h2>Cache Рухсат берилмаган.</h2> </div> <hr>  <div id="content"> <p>The following error was encountered while trying to retrieve the URL: <a href="%U">%U</a></p>  <blockquote id="error"> <p><b>Cache Access Denied.</b></p> </blockquote>  <p>Кечирасиз, сизнинг %U сўровингизга ушбу кеш томонидан тасдиқдан ўтмагунингизча рухсат берилмайди.</p>  <p></a> Агар сиз тасдиқдан ўтишда ёки андоза махфий сўзингизни <a href="http://%h/cgi-bin/chpasswd.cgi">ўзгартиришда</a>қийналаётган бўлсангиз,  марҳамат, <a href="mailto:%w%W">кеш адмнистратори билан боғланинг.</p>  <br> </div>  <hr>  <div id="footer"> <p>%h (%s) томонидан  %T яратилган</p> <!-- %c --> </div> </body></html> 
\ No newline at end of file
+<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd"> <html><head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8"> <title>ХАТО: Cache Access Denied</title> <style type="text/css"><!--   %l  body :lang(fa) { direction: rtl; font-size: 100%; font-family: Tahoma, Roya, sans-serif; float: right; } :lang(he) { direction: rtl; }  --></style> </head><body id=%c> <div id="titles"> <h1>ERROR</h1> <h2>Cache Рухсат берилмаган.</h2> </div> <hr>  <div id="content"> <p>The following error was encountered while trying to retrieve the URL: <a href="%U">%U</a></p>  <blockquote id="error"> <p><b>Cache Access Denied.</b></p> </blockquote>  <p>Кечирасиз, сизнинг %U сўровингизга ушбу кеш томонидан тасдиқдан ўтмагунингизча рухсат берилмайди.</p>  <p>Please contact the <a href="mailto:%w%W">cache administrator</a> if you have difficulties authenticating yourself.</p>  <br> </div>  <hr>  <div id="footer"> <p>%h (%s) томонидан  %T яратилган</p> <!-- %c --> </div> </body></html> 
\ No newline at end of file
diff -u -r -N squid-3.2.0.12/errors/uz/error-details.txt squid-3.2.0.13/errors/uz/error-details.txt
--- squid-3.2.0.12/errors/uz/error-details.txt	2011-09-16 23:53:03.000000000 +1200
+++ squid-3.2.0.13/errors/uz/error-details.txt	2011-10-14 16:36:42.000000000 +1300
@@ -46,19 +46,19 @@
 detail: "%ssl_error_descr: %ssl_subject"
 descr: "CRL has expired"
 
-name: X509_V_ERR_ХАТО_IN_CERT_NOT_BEFORE_FIELD
+name: X509_V_ERR_ERROR_IN_CERT_NOT_BEFORE_FIELD
 detail: "SSL Certificate has invalid start date (the 'not before' field): %ssl_subject"
 descr: "Format error in certificate's notBefore field"
 
-name: X509_V_ERR_ХАТО_IN_CERT_NOT_AFTER_FIELD
+name: X509_V_ERR_ERROR_IN_CERT_NOT_AFTER_FIELD
 detail: "SSL Certificate has invalid expiration date (the 'not after' field): %ssl_subject"
 descr: "Format error in certificate's notAfter field"
 
-name: X509_V_ERR_ХАТО_IN_CRL_LAST_UPDATE_FIELD
+name: X509_V_ERR_ERROR_IN_CRL_LAST_UPDATE_FIELD
 detail: "%ssl_error_descr: %ssl_subject"
 descr: "Format error in CRL's lastUpdate field"
 
-name: X509_V_ERR_ХАТО_IN_CRL_NEXT_UPDATE_FIELD
+name: X509_V_ERR_ERROR_IN_CRL_NEXT_UPDATE_FIELD
 detail: "%ssl_error_descr: %ssl_subject"
 descr: "Format error in CRL's nextUpdate field"
 
diff -u -r -N squid-3.2.0.12/errors/vi/ERR_CACHE_ACCESS_DENIED squid-3.2.0.13/errors/vi/ERR_CACHE_ACCESS_DENIED
--- squid-3.2.0.12/errors/vi/ERR_CACHE_ACCESS_DENIED	2011-09-16 23:53:05.000000000 +1200
+++ squid-3.2.0.13/errors/vi/ERR_CACHE_ACCESS_DENIED	2011-10-14 16:37:02.000000000 +1300
@@ -1 +1 @@
-<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd"> <html><head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8"> <title>LỖI: Cache Access Denied</title> <style type="text/css"><!--   %l  body :lang(fa) { direction: rtl; font-size: 100%; font-family: Tahoma, Roya, sans-serif; float: right; } :lang(he) { direction: rtl; }  --></style> </head><body id=%c> <div id="titles"> <h1>ERROR</h1> <h2>Cache Truy cập bị từ chối.</h2> </div> <hr>  <div id="content"> <p>The following error was encountered while trying to retrieve the URL: <a href="%U">%U</a></p>  <blockquote id="error"> <p><b>Truy cập đến vùng nhớ tạm bị từ chối.</b></p> </blockquote>  <p>Để yêu cầu %U từ vùng nhớ tạm này thì trước tiên bạn cần phải tự xác thực.</p>  <p>Hãy liên lạc với <a href="mailto:%w%W">quản trị vùng nhớ tạm</a> nếu bạn gặp khó khăn trong việc tự xác thực, hoặc bạn <a href="http://%h/cgi-bin/chpasswd.cgi">thay đổi</a> mật khẩu mặc định của mình.</p>  <br> </div>  <hr>  <div id="footer"> <p>Tạo %T bởi %h (%s)</p> <!-- %c --> </div> </body></html> 
\ No newline at end of file
+<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd"> <html><head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8"> <title>LỖI: Cache Access Denied</title> <style type="text/css"><!--   %l  body :lang(fa) { direction: rtl; font-size: 100%; font-family: Tahoma, Roya, sans-serif; float: right; } :lang(he) { direction: rtl; }  --></style> </head><body id=%c> <div id="titles"> <h1>ERROR</h1> <h2>Cache Truy cập bị từ chối.</h2> </div> <hr>  <div id="content"> <p>The following error was encountered while trying to retrieve the URL: <a href="%U">%U</a></p>  <blockquote id="error"> <p><b>Truy cập đến vùng nhớ tạm bị từ chối.</b></p> </blockquote>  <p>Để yêu cầu %U từ vùng nhớ tạm này thì trước tiên bạn cần phải tự xác thực.</p>  <p>Please contact the <a href="mailto:%w%W">cache administrator</a> if you have difficulties authenticating yourself.</p>  <br> </div>  <hr>  <div id="footer"> <p>Tạo %T bởi %h (%s)</p> <!-- %c --> </div> </body></html> 
\ No newline at end of file
diff -u -r -N squid-3.2.0.12/errors/vi/error-details.txt squid-3.2.0.13/errors/vi/error-details.txt
--- squid-3.2.0.12/errors/vi/error-details.txt	2011-09-16 23:53:23.000000000 +1200
+++ squid-3.2.0.13/errors/vi/error-details.txt	2011-10-14 16:40:18.000000000 +1300
@@ -46,19 +46,19 @@
 detail: "%ssl_error_descr: %ssl_subject"
 descr: "CRL has expired"
 
-name: X509_V_ERR_LỖI_IN_CERT_NOT_BEFORE_FIELD
+name: X509_V_ERR_ERROR_IN_CERT_NOT_BEFORE_FIELD
 detail: "SSL Certificate has invalid start date (the 'not before' field): %ssl_subject"
 descr: "Format error in certificate's notBefore field"
 
-name: X509_V_ERR_LỖI_IN_CERT_NOT_AFTER_FIELD
+name: X509_V_ERR_ERROR_IN_CERT_NOT_AFTER_FIELD
 detail: "SSL Certificate has invalid expiration date (the 'not after' field): %ssl_subject"
 descr: "Format error in certificate's notAfter field"
 
-name: X509_V_ERR_LỖI_IN_CRL_LAST_UPDATE_FIELD
+name: X509_V_ERR_ERROR_IN_CRL_LAST_UPDATE_FIELD
 detail: "%ssl_error_descr: %ssl_subject"
 descr: "Format error in CRL's lastUpdate field"
 
-name: X509_V_ERR_LỖI_IN_CRL_NEXT_UPDATE_FIELD
+name: X509_V_ERR_ERROR_IN_CRL_NEXT_UPDATE_FIELD
 detail: "%ssl_error_descr: %ssl_subject"
 descr: "Format error in CRL's nextUpdate field"
 
diff -u -r -N squid-3.2.0.12/errors/zh-cn/ERR_CACHE_ACCESS_DENIED squid-3.2.0.13/errors/zh-cn/ERR_CACHE_ACCESS_DENIED
--- squid-3.2.0.12/errors/zh-cn/ERR_CACHE_ACCESS_DENIED	2011-09-16 23:53:25.000000000 +1200
+++ squid-3.2.0.13/errors/zh-cn/ERR_CACHE_ACCESS_DENIED	2011-10-14 16:40:37.000000000 +1300
@@ -1 +1 @@
-<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd"> <html><head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8"> <title>错误: Cache Access Denied</title> <style type="text/css"><!--   %l  body :lang(fa) { direction: rtl; font-size: 100%; font-family: Tahoma, Roya, sans-serif; float: right; } :lang(he) { direction: rtl; }  --></style> </head><body id=%c> <div id="titles"> <h1>ERROR</h1> <h2>Cache 访问被拒绝。</h2> </div> <hr>  <div id="content"> <p>当尝试取回该 URL 时遇到下面的错误：<a href="%U">%U</a></p>  <blockquote id="error"> <p><b>缓存访问被拒绝。</b></p> </blockquote>  <p>抱歉，您不被允许通过本网络缓存服务器访问下列位置 %U 除非您通过了我们的身份验证。</p>  <p>如果您在身份验证上 发生困难，请与 <a href="mailto:%w%W">管理者</a> 联系。 或是<a href="http://%h/cgi-bin/chpasswd.cgi">更改</a>您的密码。</p>  <br> </div>  <hr>  <div id="footer"> <p>已由 %h (%s) 生成 %T</p> <!-- %c --> </div> </body></html> 
\ No newline at end of file
+<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd"> <html><head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8"> <title>错误: Cache Access Denied</title> <style type="text/css"><!--   %l  body :lang(fa) { direction: rtl; font-size: 100%; font-family: Tahoma, Roya, sans-serif; float: right; } :lang(he) { direction: rtl; }  --></style> </head><body id=%c> <div id="titles"> <h1>ERROR</h1> <h2>Cache 访问被拒绝。</h2> </div> <hr>  <div id="content"> <p>当尝试取回该 URL 时遇到下面的错误：<a href="%U">%U</a></p>  <blockquote id="error"> <p><b>缓存访问被拒绝。</b></p> </blockquote>  <p>抱歉，您不被允许通过本网络缓存服务器访问下列位置 %U 除非您通过了我们的身份验证。</p>  <p>Please contact the <a href="mailto:%w%W">cache administrator</a> if you have difficulties authenticating yourself.</p>  <br> </div>  <hr>  <div id="footer"> <p>已由 %h (%s) 生成 %T</p> <!-- %c --> </div> </body></html> 
\ No newline at end of file
diff -u -r -N squid-3.2.0.12/errors/zh-cn/error-details.txt squid-3.2.0.13/errors/zh-cn/error-details.txt
--- squid-3.2.0.12/errors/zh-cn/error-details.txt	2011-09-16 23:53:42.000000000 +1200
+++ squid-3.2.0.13/errors/zh-cn/error-details.txt	2011-10-14 16:43:58.000000000 +1300
@@ -46,19 +46,19 @@
 detail: "%ssl_error_descr: %ssl_subject"
 descr: "CRL has expired"
 
-name: X509_V_ERR_错误_IN_CERT_NOT_BEFORE_FIELD
+name: X509_V_ERR_ERROR_IN_CERT_NOT_BEFORE_FIELD
 detail: "SSL Certificate has invalid start date (the 'not before' field): %ssl_subject"
 descr: "Format error in certificate's notBefore field"
 
-name: X509_V_ERR_错误_IN_CERT_NOT_AFTER_FIELD
+name: X509_V_ERR_ERROR_IN_CERT_NOT_AFTER_FIELD
 detail: "SSL Certificate has invalid expiration date (the 'not after' field): %ssl_subject"
 descr: "Format error in certificate's notAfter field"
 
-name: X509_V_ERR_错误_IN_CRL_LAST_UPDATE_FIELD
+name: X509_V_ERR_ERROR_IN_CRL_LAST_UPDATE_FIELD
 detail: "%ssl_error_descr: %ssl_subject"
 descr: "Format error in CRL's lastUpdate field"
 
-name: X509_V_ERR_错误_IN_CRL_NEXT_UPDATE_FIELD
+name: X509_V_ERR_ERROR_IN_CRL_NEXT_UPDATE_FIELD
 detail: "%ssl_error_descr: %ssl_subject"
 descr: "Format error in CRL's nextUpdate field"
 
diff -u -r -N squid-3.2.0.12/errors/zh-tw/ERR_CACHE_ACCESS_DENIED squid-3.2.0.13/errors/zh-tw/ERR_CACHE_ACCESS_DENIED
--- squid-3.2.0.12/errors/zh-tw/ERR_CACHE_ACCESS_DENIED	2011-09-16 23:53:44.000000000 +1200
+++ squid-3.2.0.13/errors/zh-tw/ERR_CACHE_ACCESS_DENIED	2011-10-14 16:44:22.000000000 +1300
@@ -1 +1 @@
-<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd"> <html><head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8"> <title>錯誤: Cache Access Denied</title> <style type="text/css"><!--   %l  body :lang(fa) { direction: rtl; font-size: 100%; font-family: Tahoma, Roya, sans-serif; float: right; } :lang(he) { direction: rtl; }  --></style> </head><body id=%c> <div id="titles"> <h1>ERROR</h1> <h2>Cache 存取被拒絕</h2> </div> <hr>  <div id="content"> <p>The following error was encountered while trying to retrieve the URL: <a href="%U">%U</a></p>  <blockquote id="error"> <p><b>快取伺服器存取被拒絕</b></p> </blockquote>  <p>抱歉，您不被允許透過我們這個網路快取伺服器傳回下列位置 %U 除非您通過了我們的身份驗證。</p>  <p>如果您在身份驗證上發生困難，請與 <a href="mailto:%w%W">管理者</a> 聯繫。或是<a href="http://%h/cgi-bin/chpasswd.cgi">更改</a>您的密碼。</p>  <br> </div>  <hr>  <div id="footer"> <p>Generated %T by %h (%s)</p> <!-- %c --> </div> </body></html> 
\ No newline at end of file
+<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd"> <html><head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8"> <title>錯誤: Cache Access Denied</title> <style type="text/css"><!--   %l  body :lang(fa) { direction: rtl; font-size: 100%; font-family: Tahoma, Roya, sans-serif; float: right; } :lang(he) { direction: rtl; }  --></style> </head><body id=%c> <div id="titles"> <h1>ERROR</h1> <h2>Cache 存取被拒絕</h2> </div> <hr>  <div id="content"> <p>The following error was encountered while trying to retrieve the URL: <a href="%U">%U</a></p>  <blockquote id="error"> <p><b>快取伺服器存取被拒絕</b></p> </blockquote>  <p>抱歉，您不被允許透過我們這個網路快取伺服器傳回下列位置 %U 除非您通過了我們的身份驗證。</p>  <p>Please contact the <a href="mailto:%w%W">cache administrator</a> if you have difficulties authenticating yourself.</p>  <br> </div>  <hr>  <div id="footer"> <p>Generated %T by %h (%s)</p> <!-- %c --> </div> </body></html> 
\ No newline at end of file
diff -u -r -N squid-3.2.0.12/errors/zh-tw/error-details.txt squid-3.2.0.13/errors/zh-tw/error-details.txt
--- squid-3.2.0.12/errors/zh-tw/error-details.txt	2011-09-16 23:54:01.000000000 +1200
+++ squid-3.2.0.13/errors/zh-tw/error-details.txt	2011-10-14 16:47:36.000000000 +1300
@@ -46,19 +46,19 @@
 detail: "%ssl_error_descr: %ssl_subject"
 descr: "CRL has expired"
 
-name: X509_V_ERR_錯誤_IN_CERT_NOT_BEFORE_FIELD
+name: X509_V_ERR_ERROR_IN_CERT_NOT_BEFORE_FIELD
 detail: "SSL Certificate has invalid start date (the 'not before' field): %ssl_subject"
 descr: "Format error in certificate's notBefore field"
 
-name: X509_V_ERR_錯誤_IN_CERT_NOT_AFTER_FIELD
+name: X509_V_ERR_ERROR_IN_CERT_NOT_AFTER_FIELD
 detail: "SSL Certificate has invalid expiration date (the 'not after' field): %ssl_subject"
 descr: "Format error in certificate's notAfter field"
 
-name: X509_V_ERR_錯誤_IN_CRL_LAST_UPDATE_FIELD
+name: X509_V_ERR_ERROR_IN_CRL_LAST_UPDATE_FIELD
 detail: "%ssl_error_descr: %ssl_subject"
 descr: "Format error in CRL's lastUpdate field"
 
-name: X509_V_ERR_錯誤_IN_CRL_NEXT_UPDATE_FIELD
+name: X509_V_ERR_ERROR_IN_CRL_NEXT_UPDATE_FIELD
 detail: "%ssl_error_descr: %ssl_subject"
 descr: "Format error in CRL's nextUpdate field"
 
diff -u -r -N squid-3.2.0.12/helpers/basic_auth/DB/basic_db_auth.8 squid-3.2.0.13/helpers/basic_auth/DB/basic_db_auth.8
--- squid-3.2.0.12/helpers/basic_auth/DB/basic_db_auth.8	2011-09-16 23:54:03.000000000 +1200
+++ squid-3.2.0.13/helpers/basic_auth/DB/basic_db_auth.8	2011-10-14 16:47:52.000000000 +1300
@@ -124,7 +124,7 @@
 .\" ========================================================================
 .\"
 .IX Title "BASIC_DB_AUTH 1"
-.TH BASIC_DB_AUTH 1 "2011-09-16" "perl v5.10.1" "User Contributed Perl Documentation"
+.TH BASIC_DB_AUTH 1 "2011-10-13" "perl v5.10.1" "User Contributed Perl Documentation"
 .\" For nroff, turn off justification.  Always turn off hyphenation; it makes
 .\" way too many mistakes in technical documents.
 .if n .ad l
diff -u -r -N squid-3.2.0.12/helpers/external_acl/session/ext_session_acl.8 squid-3.2.0.13/helpers/external_acl/session/ext_session_acl.8
--- squid-3.2.0.12/helpers/external_acl/session/ext_session_acl.8	2011-09-16 23:37:30.000000000 +1200
+++ squid-3.2.0.13/helpers/external_acl/session/ext_session_acl.8	2011-10-14 14:42:56.000000000 +1300
@@ -1,11 +1,11 @@
-.if !'po4a'hide' .TH ext_session_acl 8 "19 March 2006"
+.if !'po4a'hide' .TH ext_session_acl 8 "19 September 2011"
 .
 .SH NAME
 .if !'po4a'hide' .B ext_session_acl
 .if !'po4a'hide' \-
 Squid session tracking external acl helper.
 .PP
-Version 1.0
+Version 1.1
 .
 .SH SYNOPSIS
 .if !'po4a'hide' .B ext_session_acl
@@ -18,23 +18,43 @@
 .SH DESCRIPTION
 .B ext_session_acl
 maintains a concept of sessions by monitoring requests
-and timing out sessions if no requests have been seen for the idle timeout
-timer.
-.PP
-Intended use is for displaying "terms of use" pages, ad popups etc.
+and timing out sessions. The timeout is based either on idle use (
+.B \-t
+) or a fixed period of time (
+.B \-T
+). The former is suitable for displaying terms and conditions to a user; the
+latter is suitable for the display of advertisments or other notices (both as a
+splash page \- see config examples in the wiki online). The session helper can also be used
+to force users to re\-authenticate if the 
+.B %LOGIN 
+and 
+.B \-a
+are both used.
 .
 .SH OPTIONS
 .if !'po4a'hide' .TP 12
 .if !'po4a'hide' .B "\-t timeout"
-.B Timeout
-for any session. If not specified the default is 3600 seconds.
+Idle timeout for any session. The default if not specified (set to 3600 seconds).
+.
+.if !'po4a'hide' .TP
+.if !'po4a'hide' .B "\-T timeout"
+Fixed timeout for any session. This will end the session after the timeout regardless
+of a user's activity. If used with
+.B active
+mode, this will terminate the user's session after
+.B timeout
+, after which another
+.B LOGIN
+will be required.
+.B LOGOUT
+will reset the session and timeout.
 .
 .if !'po4a'hide' .TP
 .if !'po4a'hide' .B "\-b path"
 .B Path
 to persistent database. If not specified the session details
 will be kept in memory only and all sessions will reset each time
-Squid restarts it's helpers (Squid restart or rotation of logs).
+Squid restarts its helpers (Squid restart or rotation of logs).
 .
 .if !'po4a'hide' .TP
 .if !'po4a'hide' .B \-a
@@ -42,13 +62,17 @@
 acl with the argument
 .B LOGIN
 , or terminated by the argument
-.B LOGOUT
-.PP
+.B LOGOUT .
 Without this flag the helper automatically starts the session after
 the first request.
-.
 .SH CONFIGURATION
 .PP
+The
+.B ext_session_acl
+helper is a concurrent helper; therefore, the concurrency= option
+.B must
+be specified in the configuration.
+.PP
 Configuration example using the default automatic mode
 .if !'po4a'hide' .RS
 .if !'po4a'hide' .B external_acl_type session ttl=300 negative_ttl=0 children=1 concurrency=200 %LOGIN /usr/local/squid/libexec/ext_session_acl
diff -u -r -N squid-3.2.0.12/helpers/external_acl/session/ext_session_acl.cc squid-3.2.0.13/helpers/external_acl/session/ext_session_acl.cc
--- squid-3.2.0.12/helpers/external_acl/session/ext_session_acl.cc	2011-09-16 23:37:30.000000000 +1200
+++ squid-3.2.0.13/helpers/external_acl/session/ext_session_acl.cc	2011-10-14 14:42:56.000000000 +1300
@@ -52,6 +52,7 @@
 #endif
 
 static int session_ttl = 3600;
+static int fixed_timeout = 0;
 char *db_path = NULL;
 const char *program_name;
 
@@ -101,6 +102,7 @@
     data.data = &now;
     data.size = sizeof(now);
     db->put(db, &key, &data, 0);
+    db->sync(db, 0);
 }
 
 static void session_logout(const char *details, size_t len)
@@ -113,8 +115,9 @@
 
 static void usage(void)
 {
-    fprintf(stderr, "Usage: %s [-t session_timeout] [-b dbpath] [-a]\n", program_name);
-    fprintf(stderr, "	-t sessiontimeout	Idle timeout after which sessions will be forgotten\n");
+    fprintf(stderr, "Usage: %s [-t|-T session_timeout] [-b dbpath] [-a]\n", program_name);
+    fprintf(stderr, "	-t sessiontimeout	Idle timeout after which sessions will be forgotten (user activity will reset)\n");
+    fprintf(stderr, "	-T sessiontimeout	Fixed timeout after which sessions will be forgotten (regardless of user activity)\n");
     fprintf(stderr, "	-b dbpath		Path where persistent session database will be kept\n");
     fprintf(stderr, "	-a			Active mode requiring LOGIN argument to start a session\n");
 }
@@ -126,8 +129,10 @@
 
     program_name = argv[0];
 
-    while ((opt = getopt(argc, argv, "t:b:a?")) != -1) {
+    while ((opt = getopt(argc, argv, "t:T:b:a?")) != -1) {
         switch (opt) {
+        case 'T':
+            fixed_timeout = 1;
         case 't':
             session_ttl = strtol(optarg, NULL, 0);
             break;
@@ -150,8 +155,13 @@
 
     while (fgets(request, HELPER_INPUT_BUFFER, stdin)) {
         int action = 0;
-        const char *user_key = strtok(request, " \n");
+        const char *channel_id = strtok(request, " ");
         const char *detail = strtok(NULL, "\n");
+        if (detail == NULL) {
+            // Only 1 paramater supplied. We are expecting at least 2 (including the channel ID)
+            fprintf(stderr, "FATAL: %s is concurrent and requires the concurrency option to be specified.\n", program_name);
+            exit(1);
+        }
         const char *lastdetail = strrchr(detail, ' ');
         size_t detail_len = strlen(detail);
         if (lastdetail) {
@@ -165,18 +175,20 @@
         }
         if (action == -1) {
             session_logout(detail, detail_len);
-            printf("%s OK message=\"Bye\"\n", user_key);
+            printf("%s OK message=\"Bye\"\n", channel_id);
         } else if (action == 1) {
             session_login(detail, detail_len);
-            printf("%s OK message=\"Welcome\"\n", user_key);
+            printf("%s OK message=\"Welcome\"\n", channel_id);
         } else if (session_active(detail, detail_len)) {
-            session_login(detail, detail_len);
-            printf("%s OK\n", user_key);
+            if (fixed_timeout == 0) {
+                session_login(detail, detail_len);
+            }
+            printf("%s OK\n", channel_id);
         } else if (default_action == 1) {
             session_login(detail, detail_len);
-            printf("%s ERR message=\"Welcome\"\n", user_key);
+            printf("%s ERR message=\"Welcome\"\n", channel_id);
         } else {
-            printf("%s ERR message=\"No session available\"\n", user_key);
+            printf("%s ERR message=\"No session available\"\n", channel_id);
         }
     }
     shutdown_db();
diff -u -r -N squid-3.2.0.12/helpers/external_acl/wbinfo_group/ext_wbinfo_group_acl.8 squid-3.2.0.13/helpers/external_acl/wbinfo_group/ext_wbinfo_group_acl.8
--- squid-3.2.0.12/helpers/external_acl/wbinfo_group/ext_wbinfo_group_acl.8	2011-09-16 23:54:05.000000000 +1200
+++ squid-3.2.0.13/helpers/external_acl/wbinfo_group/ext_wbinfo_group_acl.8	2011-10-14 16:48:15.000000000 +1300
@@ -124,7 +124,7 @@
 .\" ========================================================================
 .\"
 .IX Title "EXT_WBINFO_GROUP_ACL.PL.IN 1"
-.TH EXT_WBINFO_GROUP_ACL.PL.IN 1 "2011-09-16" "perl v5.10.1" "User Contributed Perl Documentation"
+.TH EXT_WBINFO_GROUP_ACL.PL.IN 1 "2011-10-13" "perl v5.10.1" "User Contributed Perl Documentation"
 .\" For nroff, turn off justification.  Always turn off hyphenation; it makes
 .\" way too many mistakes in technical documents.
 .if n .ad l
diff -u -r -N squid-3.2.0.12/include/autoconf.h.in squid-3.2.0.13/include/autoconf.h.in
--- squid-3.2.0.12/include/autoconf.h.in	2011-09-16 23:38:04.000000000 +1200
+++ squid-3.2.0.13/include/autoconf.h.in	2011-10-14 14:46:18.000000000 +1300
@@ -79,6 +79,9 @@
 /* Define to 1 if you have the <assert.h> header file. */
 #undef HAVE_ASSERT_H
 
+/* Define to 1 if you have __sync_add_and_fetch() and such */
+#undef HAVE_ATOMIC_OPS
+
 /* Basic auth module is built */
 #undef HAVE_AUTH_MODULE_BASIC
 
@@ -235,6 +238,9 @@
 /* "Define to 1 if diskd filesystem module is build" */
 #undef HAVE_FS_DISKD
 
+/* "Define to 1 if rock filesystem module is build" */
+#undef HAVE_FS_ROCK
+
 /* "Define to 1 if ufs filesystem module is build" */
 #undef HAVE_FS_UFS
 
@@ -773,6 +779,9 @@
 /* Define if you have the shl_load function. */
 #undef HAVE_SHL_LOAD
 
+/* Support shared memory features */
+#undef HAVE_SHM
+
 /* Define to 1 if you have the `sigaction' function. */
 #undef HAVE_SIGACTION
 
@@ -933,6 +942,9 @@
 /* Define to 1 if you have the <sys/md5.h> header file. */
 #undef HAVE_SYS_MD5_H
 
+/* Define to 1 if you have the <sys/mman.h> header file. */
+#undef HAVE_SYS_MMAN_H
+
 /* Define to 1 if you have the <sys/mount.h> header file. */
 #undef HAVE_SYS_MOUNT_H
 
@@ -1221,6 +1233,9 @@
 /* Whether pthreads support is needed. Automatic */
 #undef USE_DISKIO_DISKTHREADS
 
+/* Enable DiskIO IpcIo module. */
+#undef USE_DISKIO_IPCIO
+
 /* Use dnsserver processes instead of the internal DNS protocol support */
 #undef USE_DNSSERVERS
 
diff -u -r -N squid-3.2.0.12/include/version.h squid-3.2.0.13/include/version.h
--- squid-3.2.0.12/include/version.h	2011-09-16 23:38:35.000000000 +1200
+++ squid-3.2.0.13/include/version.h	2011-10-14 14:49:52.000000000 +1300
@@ -9,7 +9,7 @@
  */
 
 #ifndef SQUID_RELEASE_TIME
-#define SQUID_RELEASE_TIME 1316173049
+#define SQUID_RELEASE_TIME 1318556567
 #endif
 
 #ifndef APP_SHORTNAME
diff -u -r -N squid-3.2.0.12/lib/rfc1035.c squid-3.2.0.13/lib/rfc1035.c
--- squid-3.2.0.12/lib/rfc1035.c	2011-09-16 23:37:30.000000000 +1200
+++ squid-3.2.0.13/lib/rfc1035.c	2011-10-14 14:42:56.000000000 +1300
@@ -519,11 +519,11 @@
 void
 rfc1035RRDestroy(rfc1035_rr ** rr, int n)
 {
-    if (*rr == NULL || n < 1) {
+    if (*rr == NULL) {
         return;
     }
 
-    while (n--) {
+    while (n-- > 0) {
         if ((*rr)[n].rdata)
             xfree((*rr)[n].rdata);
     }
diff -u -r -N squid-3.2.0.12/RELEASENOTES.html squid-3.2.0.13/RELEASENOTES.html
--- squid-3.2.0.12/RELEASENOTES.html	2011-09-16 23:54:10.000000000 +1200
+++ squid-3.2.0.13/RELEASENOTES.html	2011-10-14 16:49:16.000000000 +1300
@@ -2,10 +2,10 @@
 <HTML>
 <HEAD>
  <META NAME="GENERATOR" CONTENT="LinuxDoc-Tools 0.9.66">
- <TITLE>Squid 3.2.0.12 release notes</TITLE>
+ <TITLE>Squid 3.2.0.13 release notes</TITLE>
 </HEAD>
 <BODY>
-<H1>Squid 3.2.0.12 release notes</H1>
+<H1>Squid 3.2.0.13 release notes</H1>
 
 <H2>Squid Developers</H2>
 <HR>
@@ -73,7 +73,7 @@
 <HR>
 <H2><A NAME="s1">1.</A> <A HREF="#toc1">Notice</A></H2>
 
-<P>The Squid Team are pleased to announce the release of Squid-3.2.0.12 for testing.</P>
+<P>The Squid Team are pleased to announce the release of Squid-3.2.0.13 for testing.</P>
 <P>This new release is available for download from 
 <A HREF="http://www.squid-cache.org/Versions/v3/3.2/">http://www.squid-cache.org/Versions/v3/3.2/</A> or the 
 <A HREF="http://www.squid-cache.org/Mirrors/http-mirrors.html">mirrors</A>.</P>
@@ -176,13 +176,11 @@
 
 <P>Workers can share logs.</P>
 
-<P>Workers cannot share caches, for now. Cache_dir options must be adjusted to
-point each disk-caching worker to its own disk area. ICP and HTCP responses
-are based on the responding worker cache state. Overall, SMP Squid behaves
-as a Squid farm behind a load-balancer with no cache affinity awareness.
-This is perfect for non-caching Squids but inappropriate for Squids that
-must coordinate caching activities (in-between environments are in a gray
-area requiring case-by-case analysis).</P>
+<P>Workers can share caches. Memory cache is automatically shared when multiple
+workers are used. Cache_dir are shared when configured with the <EM>rock</EM>
+storage type. Cache_dir of other types must be adjusted to point each
+disk-caching worker to its own disk area. ICP and HTCP responses are based
+on the responding worker cache state.</P>
 
 <P>Cache manager statistics are reported from a worker point of view, for now.
 Though some reports are combined. SNMP statistics are combined across all
diff -u -r -N squid-3.2.0.12/src/adaptation/ecap/XactionRep.cc squid-3.2.0.13/src/adaptation/ecap/XactionRep.cc
--- squid-3.2.0.12/src/adaptation/ecap/XactionRep.cc	2011-09-16 23:37:30.000000000 +1200
+++ squid-3.2.0.13/src/adaptation/ecap/XactionRep.cc	2011-10-14 14:42:56.000000000 +1300
@@ -133,6 +133,7 @@
 const libecap::Area
 Adaptation::Ecap::XactionRep::usernameValue() const
 {
+#if USE_AUTH
     const HttpRequest *request = dynamic_cast<const HttpRequest*>(theCauseRep ?
                                  theCauseRep->raw().header : theVirginRep.raw().header);
     Must(request);
@@ -140,6 +141,7 @@
         if (char const *name = request->auth_user_request->username())
             return libecap::Area::FromTempBuffer(name, strlen(name));
     }
+#endif
     return libecap::Area();
 }
 
diff -u -r -N squid-3.2.0.12/src/adaptation/ServiceConfig.cc squid-3.2.0.13/src/adaptation/ServiceConfig.cc
--- squid-3.2.0.12/src/adaptation/ServiceConfig.cc	2011-09-16 23:37:30.000000000 +1200
+++ squid-3.2.0.13/src/adaptation/ServiceConfig.cc	2011-10-14 14:42:56.000000000 +1300
@@ -6,6 +6,7 @@
 #include "ConfigParser.h"
 #include "adaptation/ServiceConfig.h"
 #include "ip/tools.h"
+#include <set>
 
 Adaptation::ServiceConfig::ServiceConfig():
         port(-1), method(methodNone), point(pointNone),
@@ -69,29 +70,41 @@
     bypass = routing = false;
 
     // handle optional service name=value parameters
-    const char *lastOption = NULL;
     bool grokkedUri = false;
     bool onOverloadSet = false;
+    std::set<std::string> options;
+
     while (char *option = strtok(NULL, w_space)) {
+        const char *name = option;
+        const char *value = "";
         if (strcmp(option, "0") == 0) { // backward compatibility
-            bypass = false;
-            continue;
-        }
-        if (strcmp(option, "1") == 0) { // backward compatibility
-            bypass = true;
-            continue;
+            name = "bypass";
+            value = "off";
+            debugs(3, opt_parse_cfg_only?0:1, "UPGRADE: Please use 'bypass=off' option to disable service bypass");
+        }  else if (strcmp(option, "1") == 0) { // backward compatibility
+            name = "bypass";
+            value = "on";
+            debugs(3, opt_parse_cfg_only?0:1, "UPGRADE: Please use 'bypass=on' option to enable service bypass");
+        } else {
+            char *eq = strstr(option, "=");
+            const char *sffx = strstr(option, "://");
+            if (!eq || (sffx && sffx < eq)) { //no "=" or has the form "icap://host?arg=val"
+                name = "uri";
+                value = option;
+            }  else { // a normal name=value option
+                *eq = '\0'; // terminate option name
+                value = eq + 1; // skip '='
+            }
         }
 
-        const char *name = option;
-        char *value = strstr(option, "=");
-        if (!value) {
-            lastOption = option;
-            break;
+        // Check if option is set twice
+        if (options.find(name) != options.end()) {
+            debugs(3, DBG_CRITICAL, cfg_filename << ':' << config_lineno << ": " <<
+                   "Duplicate option \"" << name << "\" in adaptation service definition");
+            return false;
         }
-        *value = '\0'; // terminate option name
-        ++value; // skip '='
+        options.insert(name);
 
-        // TODO: warn if option is set twice?
         bool grokked = false;
         if (strcmp(name, "bypass") == 0) {
             grokked = grokBool(bypass, name, value);
@@ -119,14 +132,10 @@
     if (!onOverloadSet)
         onOverload = bypass ? srvBypass : srvWait;
 
-    // what is left must be the service URI
-    if (!grokkedUri && !grokUri(lastOption))
-        return false;
-
-    // there should be nothing else left
-    if (const char *tail = strtok(NULL, w_space)) {
-        debugs(3, 0, cfg_filename << ':' << config_lineno << ": " <<
-               "garbage after adaptation service URI: " << tail);
+    // is the service URI set?
+    if (!grokkedUri) {
+        debugs(3, DBG_CRITICAL, cfg_filename << ':' << config_lineno << ": " <<
+               "No \"uri\" option in adaptation service definition");
         return false;
     }
 
diff -u -r -N squid-3.2.0.12/src/auth/basic/auth_basic.cc squid-3.2.0.13/src/auth/basic/auth_basic.cc
--- squid-3.2.0.12/src/auth/basic/auth_basic.cc	2011-09-16 23:37:30.000000000 +1200
+++ squid-3.2.0.13/src/auth/basic/auth_basic.cc	2011-10-14 14:42:56.000000000 +1300
@@ -354,7 +354,7 @@
 
         basicauthenticators->cmdline = authenticateProgram;
 
-        basicauthenticators->childs = authenticateChildren;
+        basicauthenticators->childs.updateLimits(authenticateChildren);
 
         basicauthenticators->ipc_type = IPC_STREAM;
 
diff -u -r -N squid-3.2.0.12/src/auth/digest/auth_digest.cc squid-3.2.0.13/src/auth/digest/auth_digest.cc
--- squid-3.2.0.12/src/auth/digest/auth_digest.cc	2011-09-16 23:37:30.000000000 +1200
+++ squid-3.2.0.13/src/auth/digest/auth_digest.cc	2011-10-14 14:42:56.000000000 +1300
@@ -46,6 +46,7 @@
 #include "auth/Gadgets.h"
 #include "auth/State.h"
 #include "base64.h"
+#include "base/StringArea.h"
 #include "event.h"
 #include "mgr/Registration.h"
 #include "Store.h"
@@ -583,7 +584,7 @@
 
         digestauthenticators->cmdline = authenticateProgram;
 
-        digestauthenticators->childs = authenticateChildren;
+        digestauthenticators->childs.updateLimits(authenticateChildren);
 
         digestauthenticators->ipc_type = IPC_STREAM;
 
@@ -814,10 +815,28 @@
             vlen = 0;
         }
 
-        /* parse value. auth-param     = token "=" ( token | quoted-string ) */
+        StringArea keyName(item, nlen-1);
         String value;
+
         if (vlen > 0) {
-            if (*p == '"') {
+            // see RFC 2617 section 3.2.1 and 3.2.2 for details on the BNF
+
+            if (keyName == StringArea("domain",6) || keyName == StringArea("uri",3)) {
+                // domain is Special. Not a quoted-string, must not be de-quoted. But is wrapped in '"'
+                // BUG 3077: uri= can also be sent to us in a mangled (invalid!) form like domain
+                if (*p == '"' && *(p + vlen -1) == '"') {
+                    value.limitInit(p+1, vlen-2);
+                }
+            } else if (keyName == StringArea("qop",3)) {
+                // qop is more special.
+                // On request this must not be quoted-string de-quoted. But is several values wrapped in '"'
+                // On response this is a single un-quoted token.
+                if (*p == '"' && *(p + vlen -1) == '"') {
+                    value.limitInit(p+1, vlen-2);
+                } else {
+                    value.limitInit(p, vlen);
+                }
+            } else if (*p == '"') {
                 if (!httpHeaderParseQuotedString(p, vlen, &value)) {
                     debugs(29, 9, "authDigestDecodeAuth: Failed to parse attribute '" << item << "' in '" << temp << "'");
                     continue;
diff -u -r -N squid-3.2.0.12/src/auth/negotiate/auth_negotiate.cc squid-3.2.0.13/src/auth/negotiate/auth_negotiate.cc
--- squid-3.2.0.12/src/auth/negotiate/auth_negotiate.cc	2011-09-16 23:37:30.000000000 +1200
+++ squid-3.2.0.13/src/auth/negotiate/auth_negotiate.cc	2011-10-14 14:42:56.000000000 +1300
@@ -176,7 +176,7 @@
 
         negotiateauthenticators->cmdline = authenticateProgram;
 
-        negotiateauthenticators->childs = authenticateChildren;
+        negotiateauthenticators->childs.updateLimits(authenticateChildren);
 
         negotiateauthenticators->ipc_type = IPC_STREAM;
 
diff -u -r -N squid-3.2.0.12/src/auth/ntlm/auth_ntlm.cc squid-3.2.0.13/src/auth/ntlm/auth_ntlm.cc
--- squid-3.2.0.12/src/auth/ntlm/auth_ntlm.cc	2011-09-16 23:37:30.000000000 +1200
+++ squid-3.2.0.13/src/auth/ntlm/auth_ntlm.cc	2011-10-14 14:42:56.000000000 +1300
@@ -163,7 +163,7 @@
 
         ntlmauthenticators->cmdline = authenticateProgram;
 
-        ntlmauthenticators->childs = authenticateChildren;
+        ntlmauthenticators->childs.updateLimits(authenticateChildren);
 
         ntlmauthenticators->ipc_type = IPC_STREAM;
 
diff -u -r -N squid-3.2.0.12/src/base/Makefile.am squid-3.2.0.13/src/base/Makefile.am
--- squid-3.2.0.12/src/base/Makefile.am	2011-09-16 23:37:30.000000000 +1200
+++ squid-3.2.0.13/src/base/Makefile.am	2011-10-14 14:42:56.000000000 +1300
@@ -19,4 +19,5 @@
 	RunnersRegistry.h \
 	Subscription.h \
 	TextException.cc \
-	TextException.h
+	TextException.h \
+	StringArea.h
diff -u -r -N squid-3.2.0.12/src/base/Makefile.in squid-3.2.0.13/src/base/Makefile.in
--- squid-3.2.0.12/src/base/Makefile.in	2011-09-16 23:38:18.000000000 +1200
+++ squid-3.2.0.13/src/base/Makefile.in	2011-10-14 14:48:00.000000000 +1300
@@ -324,7 +324,8 @@
 	RunnersRegistry.h \
 	Subscription.h \
 	TextException.cc \
-	TextException.h
+	TextException.h \
+	StringArea.h
 
 all: all-am
 
diff -u -r -N squid-3.2.0.12/src/base/RunnersRegistry.cc squid-3.2.0.13/src/base/RunnersRegistry.cc
--- squid-3.2.0.12/src/base/RunnersRegistry.cc	2011-09-16 23:37:30.000000000 +1200
+++ squid-3.2.0.13/src/base/RunnersRegistry.cc	2011-10-14 14:42:56.000000000 +1300
@@ -44,7 +44,6 @@
 DeactivateRegistered(const RunnerRegistry &registryId)
 {
     Runners &runners = GetRunners(registryId);
-    typedef Runners::iterator RRI;
     while (!runners.empty()) {
         delete runners.back();
         runners.pop_back();
diff -u -r -N squid-3.2.0.12/src/base/StringArea.h squid-3.2.0.13/src/base/StringArea.h
--- squid-3.2.0.12/src/base/StringArea.h	1970-01-01 12:00:00.000000000 +1200
+++ squid-3.2.0.13/src/base/StringArea.h	2011-10-14 14:42:56.000000000 +1300
@@ -0,0 +1,66 @@
+/*
+ * StringArea.h
+ *
+ *
+ * SQUID Web Proxy Cache          http://www.squid-cache.org/
+ * ----------------------------------------------------------
+ *
+ *  Squid is the result of efforts by numerous individuals from
+ *  the Internet community; see the CONTRIBUTORS file for full
+ *  details.   Many organizations have provided support for Squid's
+ *  development; see the SPONSORS file for full details.  Squid is
+ *  Copyrighted (C) 2001 by the Regents of the University of
+ *  California; see the COPYRIGHT file for full details.  Squid
+ *  incorporates software developed and/or copyrighted by other
+ *  sources; see the CREDITS file for full details.
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111, USA.
+ */
+
+#ifndef SQUID_STRINGAREA_H
+#define SQUID_STRINGAREA_H
+
+#if HAVE_CSTRING
+#include <cstring>
+#endif
+
+/** A char* plus length combination. Useful for temporary storing
+ * and quickly looking up strings.
+ *
+ * The pointed-to string may not be null-terminated.
+ * The pointed-to string is not copied.
+ *
+ * Not meant for stand-alone storage. Validity of the
+ * pointed-to string is responsibility of the caller.
+ */
+class StringArea
+{
+public:
+    /// build a StringArea by explicitly assigning pointed-to area and and length
+    StringArea(const char * ptr, size_t len): theStart(ptr), theLen(len) {}
+    bool operator==(const StringArea &s) const { return theLen==s.theLen && memcmp(theStart,s.theStart,theLen)==0; }
+    bool operator!=(const StringArea &s) const { return !operator==(s); }
+    bool operator< ( const StringArea &s) const {
+        return (theLen < s.theLen || (theLen == s.theLen && memcmp(theStart,s.theStart,theLen) < 0)) ;
+    }
+
+private:
+    /// pointed to the externally-managed memory area
+    const char *theStart;
+    /// length of the string
+    size_t theLen;
+};
+
+#endif /* SQUID_STRINGAREA_H */
diff -u -r -N squid-3.2.0.12/src/cache_cf.cc squid-3.2.0.13/src/cache_cf.cc
--- squid-3.2.0.12/src/cache_cf.cc	2011-09-16 23:37:30.000000000 +1200
+++ squid-3.2.0.13/src/cache_cf.cc	2011-10-14 14:42:56.000000000 +1300
@@ -56,6 +56,7 @@
 #endif
 #include "ConfigParser.h"
 #include "CpuAffinityMap.h"
+#include "DiskIO/DiskIOModule.h"
 #include "eui/Config.h"
 #if USE_SQUID_ESI
 #include "esi/Parser.h"
@@ -599,6 +600,12 @@
         /* Memory-only cache probably in effect. */
         /* turn off the cache rebuild delays... */
         StoreController::store_dirs_rebuilding = 0;
+    } else if (InDaemonMode()) { // no diskers in non-daemon mode
+        for (int i = 0; i < Config.cacheSwap.n_configured; ++i) {
+            const RefCount<SwapDir> sd = Config.cacheSwap.swapDirs[i];
+            if (sd->needsDiskStrand())
+                sd->disker = Config.workers + (++Config.cacheSwap.n_strands);
+        }
     }
 
     if (Debug::rotateNumber < 0) {
@@ -614,7 +621,7 @@
     if (0 == Store::Root().maxSize())
         /* people might want a zero-sized cache on purpose */
         (void) 0;
-    else if (Store::Root().maxSize() < (Config.memMaxSize >> 10))
+    else if (Store::Root().maxSize() < Config.memMaxSize)
         /* This is bogus. folk with NULL caches will want this */
         debugs(3, 0, "WARNING cache_mem is larger than total disk cache space!");
 
@@ -1921,18 +1928,6 @@
 static void
 parse_cachedir(SquidConfig::_cacheSwap * swap)
 {
-    // The workers option must preceed cache_dir for the IamWorkerProcess check
-    // below to work. TODO: Redo IamWorkerProcess to work w/o Config and remove
-    if (KidIdentifier > 1 && Config.workers == 1) {
-        debugs(3, DBG_CRITICAL,
-               "FATAL: cache_dir found before the workers option. Reorder.");
-        self_destruct();
-    }
-
-    // Among all processes, only workers may need and can handle cache_dir.
-    if (!IamWorkerProcess())
-        return;
-
     char *type_str;
     char *path_str;
     RefCount<SwapDir> sd;
@@ -1965,13 +1960,13 @@
 
             sd = dynamic_cast<SwapDir *>(swap->swapDirs[i].getRaw());
 
-            if (sd->type() != StoreFileSystem::FileSystems().items[fs]->type()) {
+            if (strcmp(sd->type(), StoreFileSystem::FileSystems().items[fs]->type()) != 0) {
                 debugs(3, 0, "ERROR: Can't change type of existing cache_dir " <<
                        sd->type() << " " << sd->path << " to " << type_str << ". Restart required");
                 return;
             }
 
-            sd->reconfigure (i, path_str);
+            sd->reconfigure();
 
             update_maxobjsize();
 
@@ -3358,6 +3353,40 @@
     storeAppendPrintf(entry, "\n");
 }
 
+void
+YesNoNone::configure(bool beSet)
+{
+    option = beSet ? +1 : -1;
+}
+
+YesNoNone::operator void*() const
+{
+    assert(option != 0); // must call configure() first
+    return option > 0 ? (void*)this : NULL;
+}
+
+
+inline void
+free_YesNoNone(YesNoNone *)
+{
+    // do nothing: no explicit cleanup is required
+}
+
+static void
+parse_YesNoNone(YesNoNone *option)
+{
+    int value = 0;
+    parse_onoff(&value);
+    option->configure(value > 0);
+}
+
+static void
+dump_YesNoNone(StoreEntry * entry, const char *name, YesNoNone &option)
+{
+    if (option.configured())
+        dump_onoff(entry, name, option ? 1 : 0);
+}
+
 static void
 free_memcachemode(SquidConfig * config)
 {
diff -u -r -N squid-3.2.0.12/src/cf.data.depend squid-3.2.0.13/src/cf.data.depend
--- squid-3.2.0.12/src/cf.data.depend	2011-09-16 23:37:30.000000000 +1200
+++ squid-3.2.0.13/src/cf.data.depend	2011-10-14 14:42:56.000000000 +1300
@@ -45,6 +45,7 @@
 kb_int64_t
 kb_size_t
 logformat
+YesNoNone
 memcachemode
 obsolete
 onoff
diff -u -r -N squid-3.2.0.12/src/cf.data.pre squid-3.2.0.13/src/cf.data.pre
--- squid-3.2.0.12/src/cf.data.pre	2011-09-16 23:37:30.000000000 +1200
+++ squid-3.2.0.13/src/cf.data.pre	2011-10-14 14:42:56.000000000 +1300
@@ -1775,6 +1775,34 @@
 
 DOC_END
 
+NAME: host_verify_strict
+TYPE: onoff
+DEFAULT: off
+LOC: Config.onoff.hostStrictVerify
+DOC_START
+	Regardless of this option setting, when dealing with intercepted
+	traffic, Squid always verifies that the destination IP address matches
+	the Host header domain or IP (called 'authority form URL'). Squid
+	responds with an HTTP 409 (Conflict) error page and logs a security
+	warning if there is no match.
+	
+	When set to ON, Squid verifies that the destination IP address matches
+	the Host header for forward-proxy and reverse-proxy traffic as well. For
+	those traffic types, Squid also enables the following checks, comparing
+	the corresponding Host header and Request-URI components:
+	
+	 * The host names (domain or IP) must be identical,
+	   but valueless or missing Host header disables all checks.
+	   For the two host names to match, both must be either IP or FQDN.
+	
+	 * Port numbers must be identical,
+	   but if a port is missing, the scheme-default port is assumed.
+	
+	This enforcement is performed to satisfy a MUST-level requirement in
+	RFC 2616 section 14.23: "The Host field value MUST represent the naming
+	authority of the origin server or gateway given by the original URL".
+DOC_END
+
 NAME: client_dst_passthru
 TYPE: onoff
 DEFAULT: on
@@ -2558,6 +2586,11 @@
 	decreases, blocks will be freed until the high-water mark is
 	reached.  Thereafter, blocks will be used to store hot
 	objects.
+
+	If shared memory caching is enabled, Squid does not use the shared
+	cache space for in-transit objects, but they still consume as much
+	local memory as they need. For more details about the shared memory
+	cache, see memory_cache_shared.
 DOC_END
 
 NAME: maximum_object_size_in_memory
@@ -2572,6 +2605,34 @@
 	enough to keep larger objects from hoarding cache_mem.
 DOC_END
 
+NAME: memory_cache_shared
+COMMENT: on|off
+TYPE: YesNoNone
+LOC: Config.memShared
+DEFAULT: none
+DEFAULT_DOC: "on" where supported if doing memory caching with multiple SMP workers.
+DOC_START
+	Controls whether the memory cache is shared among SMP workers.
+
+	The shared memory cache is meant to occupy cache_mem bytes and replace
+	the non-shared memory cache, although some entities may still be
+	cached locally by workers for now (e.g., internal and in-transit
+	objects may be served from a local memory cache even if shared memory
+	caching is enabled).
+
+	By default, the memory cache is shared if and only if all of the
+	following conditions are satisfied: Squid runs in SMP mode with
+	multiple workers, cache_mem is positive, and Squid environment
+	supports required IPC primitives (e.g., POSIX shared memory segments
+	and GCC-style atomic operations).
+
+	To avoid blocking locks, shared memory uses opportunistic algorithms
+	that do not guarantee that every cachable entity that could have been
+	shared among SMP workers will actually be shared.
+
+	Currently, entities exceeding 32KB in size cannot be shared.
+DOC_END
+
 NAME: memory_cache_mode
 TYPE: memcachemode
 LOC: Config
@@ -2724,6 +2785,36 @@
 	higher hit ratio at the expense of an increase in response
 	time.
 
+	The rock store type:
+
+	    cache_dir rock Directory-Name Mbytes <max-size=bytes> [options]
+
+	The Rock Store type is a database-style storage. All cached
+	entries are stored in a "database" file, using fixed-size slots,
+	one entry per slot. The database size is specified in MB. The
+	slot size is specified in bytes using the max-size option. See
+	below for more info on the max-size option.
+
+	swap-timeout=msec: Squid will not start writing a miss to or
+	reading a hit from disk if it estimates that the swap operation
+	will take more than the specified number of milliseconds. By
+	default and when set to zero, disables the disk I/O time limit
+	enforcement. Ignored when using blocking I/O module because
+	blocking synchronous I/O does not allow Squid to estimate the
+	expected swap wait time.
+
+	max-swap-rate=swaps/sec: Artificially limits disk access using
+	the specified I/O rate limit. Swap in and swap out requests that
+	would cause the average I/O rate to exceed the limit are
+	delayed. This is necessary on file systems that buffer "too
+	many" writes and then start blocking Squid and other processes
+	while committing those writes to disk.  Usually used together
+	with swap-timeout to avoid excessive delays and queue overflows
+	when disk demand exceeds available disk "bandwidth". By default
+	and when set to zero, disables the disk I/O rate limit
+	enforcement. Currently supported by IpcIo module only.
+
+
 	The coss store type:
 
 	NP: COSS filesystem in Squid-3 has been deemed too unstable for
@@ -3393,7 +3484,7 @@
 
 NAME: netdb_filename
 TYPE: string
-DEFAULT: @DEFAULT_NETDB_FILE@
+DEFAULT: stdio:@DEFAULT_NETDB_FILE@
 LOC: Config.netdbFilename
 IFDEF: USE_ICMP
 DOC_START
@@ -4069,8 +4160,8 @@
 DOC_END
 
 NAME: store_avg_object_size
-COMMENT: (kbytes)
-TYPE: kb_int64_t
+COMMENT: (bytes)
+TYPE: b_int64_t
 DEFAULT: 13 KB
 LOC: Config.Store.avgObjectSize
 DOC_START
@@ -6543,17 +6634,19 @@
 DOC_START
 	Defines a single ICAP service using the following format:
 
-	icap_service service_name vectoring_point [options] service_url
+	icap_service id vectoring_point uri [option ...]
 
-	service_name: ID
-		an opaque identifier which must be unique in squid.conf
+	id: ID
+		an opaque identifier or name which is used to direct traffic to
+		this specific service. Must be unique among all adaptation
+		services in squid.conf.
 
 	vectoring_point: reqmod_precache|reqmod_postcache|respmod_precache|respmod_postcache
 		This specifies at which point of transaction processing the
 		ICAP service should be activated. *_postcache vectoring points
 		are not yet supported.
 
-	service_url: icap://servername:port/servicepath
+	uri: icap://servername:port/servicepath
 		ICAP server and service location.
 
 	ICAP does not allow a single service to handle both REQMOD and RESPMOD
@@ -6622,8 +6715,8 @@
 	deprecated but supported for backward compatibility.
 
 Example:
-icap_service svcBlocker reqmod_precache bypass=0 icap://icap1.mydomain.net:1344/reqmod
-icap_service svcLogger reqmod_precache routing=on icap://icap2.mydomain.net:1344/respmod
+icap_service svcBlocker reqmod_precache icap://icap1.mydomain.net:1344/reqmod bypass=0
+icap_service svcLogger reqmod_precache icap://icap2.mydomain.net:1344/respmod routing=on
 DOC_END
 
 NAME: icap_class
@@ -6675,25 +6768,56 @@
 DOC_START
 	Defines a single eCAP service
 
-	ecap_service servicename vectoring_point bypass service_url
+	ecap_service id vectoring_point uri [option ...]
+
+        id: ID
+		an opaque identifier or name which is used to direct traffic to
+		this specific service. Must be unique among all adaptation
+		services in squid.conf.
 
-	vectoring_point = reqmod_precache|reqmod_postcache|respmod_precache|respmod_postcache
+	vectoring_point: reqmod_precache|reqmod_postcache|respmod_precache|respmod_postcache
 		This specifies at which point of transaction processing the
 		eCAP service should be activated. *_postcache vectoring points
 		are not yet supported.
-	bypass = 1|0
-		If set to 1, the eCAP service is treated as optional. If the
-		service cannot be reached or malfunctions, Squid will try to
-		ignore any errors and process the message as if the service
+
+	uri: ecap://vendor/service_name?custom&cgi=style&parameters=optional
+		Squid uses the eCAP service URI to match this configuration
+		line with one of the dynamically loaded services. Each loaded
+		eCAP service must have a unique URI. Obtain the right URI from
+		the service provider.
+
+
+	Service options are separated by white space. eCAP services support
+	the following name=value options:
+
+	bypass=on|off|1|0
+		If set to 'on' or '1', the eCAP service is treated as optional.
+		If the service cannot be reached or malfunctions, Squid will try
+		to ignore any errors and process the message as if the service
 		was not enabled. No all eCAP errors can be bypassed.
-		If set to 0, the eCAP service is treated as essential and all
-		eCAP errors will result in an error page returned to the
+		If set to 'off' or '0', the eCAP service is treated as essential
+		and all eCAP errors will result in an error page returned to the
 		HTTP client.
-	service_url = ecap://vendor/service_name?custom&cgi=style&parameters=optional
+
+                Bypass is off by default: services are treated as essential.
+
+	routing=on|off|1|0
+		If set to 'on' or '1', the eCAP service is allowed to
+		dynamically change the current message adaptation plan by
+		returning a chain of services to be used next.
+
+		Dynamic adaptation plan may cross or cover multiple supported
+		vectoring points in their natural processing order.
+
+		Routing is not allowed by default.
+
+	Older ecap_service format without optional named parameters is
+	deprecated but supported for backward compatibility.
+
 
 Example:
-ecap_service service_1 reqmod_precache 0 ecap://filters-R-us/leakDetector?on_error=block
-ecap_service service_2 respmod_precache 1 icap://filters-R-us/virusFilter?config=/etc/vf.cfg
+ecap_service s1 reqmod_precache ecap://filters.R.us/leakDetector?on_error=block bypass=off
+ecap_service s2 respmod_precache ecap://filters.R.us/virusFilter config=/etc/vf.cfg bypass=on
 DOC_END
 
 NAME: loadable_modules
@@ -7145,6 +7269,25 @@
 		*) May negatively impact connection delay times.
 DOC_END
 
+NAME: dns_v4_first
+TYPE: onoff
+DEFAULT: off
+LOC: Config.dns.v4_first
+IFDEF: !USE_DNSSERVERS
+DOC_START
+	With the IPv6 Internet being as fast or faster than IPv4 Internet
+	for most networks Squid prefers to contact websites over IPv6.
+
+	This option reverses the order of preference to make Squid contact
+	dual-stack websites over IPv4 first. Squid will still perform both
+	IPv6 and IPv4 DNS lookups before connecting.
+
+	WARNING:
+	  This option will restrict the situations under which IPv6
+	  connectivity is used (and tested). Hiding network problems
+	  which would otherwise be detected and warned about.
+DOC_END
+
 NAME: ipcache_size
 COMMENT: (number of entries)
 TYPE: int
diff -u -r -N squid-3.2.0.12/src/client_side.cc squid-3.2.0.13/src/client_side.cc
--- squid-3.2.0.12/src/client_side.cc	2011-09-16 23:37:30.000000000 +1200
+++ squid-3.2.0.13/src/client_side.cc	2011-10-14 14:42:56.000000000 +1300
@@ -1821,11 +1821,11 @@
 void
 ClientSocketContext::writeComplete(const Comm::ConnectionPointer &conn, char *bufnotused, size_t size, comm_err_t errflag)
 {
-    StoreEntry *entry = http->storeEntry();
+    const StoreEntry *entry = http->storeEntry();
     http->out.size += size;
     debugs(33, 5, HERE << conn << ", sz " << size <<
            ", err " << errflag << ", off " << http->out.size << ", len " <<
-           entry ? entry->objectLen() : 0);
+           (entry ? entry->objectLen() : 0));
     clientUpdateSocketStats(http->logType, size);
 
     /* Bail out quickly on COMM_ERR_CLOSING - close handlers will tidy up */
@@ -2301,8 +2301,10 @@
 int
 ConnStateData::getAvailableBufferLength() const
 {
-    int result = in.allocatedSize - in.notYetUsed - 1;
-    assert (result >= 0);
+    assert (in.allocatedSize > in.notYetUsed); // allocated more than used
+    const size_t result = in.allocatedSize - in.notYetUsed - 1;
+    // huge request_header_max_size may lead to more than INT_MAX unused space
+    assert (static_cast<ssize_t>(result) <= INT_MAX);
     return result;
 }
 
@@ -3936,6 +3938,15 @@
     bodyPipe->enableAutoConsumption();
 }
 
+void
+ConnStateData::expectNoForwarding()
+{
+    if (bodyPipe != NULL) {
+        debugs(33, 4, HERE << "no consumer for virgin body " << bodyPipe->status());
+        bodyPipe->expectNoConsumption();
+    }
+}
+
 /// initialize dechunking state
 void
 ConnStateData::startDechunkingRequest()
diff -u -r -N squid-3.2.0.12/src/client_side.h squid-3.2.0.13/src/client_side.h
--- squid-3.2.0.12/src/client_side.h	2011-09-16 23:37:30.000000000 +1200
+++ squid-3.2.0.13/src/client_side.h	2011-10-14 14:42:56.000000000 +1300
@@ -262,6 +262,7 @@
 
     bool closing() const;
     void startClosing(const char *reason);
+    void expectNoForwarding(); ///< cleans up virgin request [body] forwarding state
 
     BodyPipe::Pointer expectRequestBody(int64_t size);
     virtual void noteMoreBodySpaceAvailable(BodyPipe::Pointer);
diff -u -r -N squid-3.2.0.12/src/client_side_reply.cc squid-3.2.0.13/src/client_side_reply.cc
--- squid-3.2.0.12/src/client_side_reply.cc	2011-09-16 23:37:30.000000000 +1200
+++ squid-3.2.0.13/src/client_side_reply.cc	2011-10-14 14:42:56.000000000 +1300
@@ -1044,6 +1044,8 @@
 int
 clientReplyContext::storeOKTransferDone() const
 {
+    assert(http->storeEntry()->objectLen() >= 0);
+    assert(http->storeEntry()->objectLen() >= headers_sz);
     if (http->out.offset >= http->storeEntry()->objectLen() - headers_sz) {
         debugs(88,3,HERE << "storeOKTransferDone " <<
                " out.offset=" << http->out.offset <<
diff -u -r -N squid-3.2.0.12/src/client_side_request.cc squid-3.2.0.13/src/client_side_request.cc
--- squid-3.2.0.12/src/client_side_request.cc	2011-09-16 23:37:30.000000000 +1200
+++ squid-3.2.0.13/src/client_side_request.cc	2011-10-14 14:42:56.000000000 +1300
@@ -67,6 +67,7 @@
 #include "compat/inet_pton.h"
 #include "fde.h"
 #include "format/Tokens.h"
+#include "HttpHdrCc.h"
 #include "HttpReply.h"
 #include "HttpRequest.h"
 #include "ip/QosConfig.h"
@@ -194,7 +195,7 @@
 {
     assert(request);
     return request->cache_control &&
-           EBIT_TEST(request->cache_control->mask, CC_ONLY_IF_CACHED);
+           request->cache_control->onlyIfCached();
 }
 
 /*
@@ -633,6 +634,9 @@
             // verify the destination DNS is one of the Host: headers IPs
             ipcache_nbgethostbyname(host, hostHeaderIpVerifyWrapper, this);
         }
+    } else if (Config.onoff.hostStrictVerify) {
+        debugs(85, 3, HERE << "validate skipped.");
+        http->doCallouts();
     } else if (strlen(host) != strlen(http->request->GetHost())) {
         // Verify forward-proxy requested URL domain matches the Host: header
         debugs(85, 3, HERE << "FAIL on validate URL domain length " << http->request->GetHost() << " matches Host: " << host);
@@ -1016,7 +1020,7 @@
         }
 
         if (request->cache_control)
-            if (EBIT_TEST(request->cache_control->mask, CC_NO_CACHE))
+            if (request->cache_control->noCache())
                 no_cache++;
 
         /*
@@ -1787,6 +1791,7 @@
 
     request->detailError(ERR_ICAP_FAILURE, errDetail);
     c->flags.readMore = true;
+    c->expectNoForwarding();
     node = (clientStreamNode *)client_stream.tail->data;
     clientStreamRead(node, this, node->readBuffer);
 }
diff -u -r -N squid-3.2.0.12/src/comm/Makefile.am squid-3.2.0.13/src/comm/Makefile.am
--- squid-3.2.0.12/src/comm/Makefile.am	2011-09-16 23:37:30.000000000 +1200
+++ squid-3.2.0.13/src/comm/Makefile.am	2011-10-14 14:42:56.000000000 +1300
@@ -27,5 +27,3 @@
 	Write.h \
 	\
 	comm_internal.h
-
-EXTRA_DIST= stub_libcomm.cc
diff -u -r -N squid-3.2.0.12/src/comm/Makefile.in squid-3.2.0.13/src/comm/Makefile.in
--- squid-3.2.0.12/src/comm/Makefile.in	2011-09-16 23:38:19.000000000 +1200
+++ squid-3.2.0.13/src/comm/Makefile.in	2011-10-14 14:48:02.000000000 +1300
@@ -335,7 +335,6 @@
 	\
 	comm_internal.h
 
-EXTRA_DIST = stub_libcomm.cc
 all: all-am
 
 .SUFFIXES:
diff -u -r -N squid-3.2.0.12/src/comm/stub_libcomm.cc squid-3.2.0.13/src/comm/stub_libcomm.cc
--- squid-3.2.0.12/src/comm/stub_libcomm.cc	2011-09-16 23:37:30.000000000 +1200
+++ squid-3.2.0.13/src/comm/stub_libcomm.cc	1970-01-01 12:00:00.000000000 +1200
@@ -1,60 +0,0 @@
-#include "config.h"
-#include "base/AsyncJob.h"
-#include "structs.h"
-
-#define STUB_API "comm/libcomm.la"
-#include "tests/STUB.h"
-
-#include "AcceptLimiter.h"
-Comm::AcceptLimiter dummy;
-Comm::AcceptLimiter & Comm::AcceptLimiter::Instance() STUB_RETVAL(dummy)
-void Comm::AcceptLimiter::defer(Comm::TcpAcceptor *afd) STUB
-void Comm::AcceptLimiter::removeDead(const Comm::TcpAcceptor *afd) STUB
-void Comm::AcceptLimiter::kick() STUB
-
-#include "comm/Connection.h"
-Comm::Connection::Connection() STUB
-Comm::Connection::~Connection() STUB
-Comm::ConnectionPointer Comm::Connection::copyDetails() const STUB_RETVAL(NULL)
-void Comm::Connection::close() STUB
-peer * Comm::Connection::getPeer() const STUB_RETVAL(NULL)
-void Comm::Connection::setPeer(peer * p) STUB
-
-#include "comm/ConnOpener.h"
-bool Comm::ConnOpener::doneAll() const STUB_RETVAL(false)
-//Comm::ConnOpener::ConnOpener(Comm::ConnectionPointer &, AsyncCall::Pointer &, time_t) STUB
-//Comm::ConnOpener::~ConnOpener() STUB
-void Comm::ConnOpener::setHost(const char *) STUB
-const char * Comm::ConnOpener::getHost() const STUB_RETVAL(NULL)
-
-#include "comm/forward.h"
-bool Comm::IsConnOpen(const Comm::ConnectionPointer &) STUB_RETVAL(false)
-
-#include "comm/IoCallback.h"
-void Comm::IoCallback::setCallback(iocb_type type, AsyncCall::Pointer &cb, char *buf, FREE *func, int sz) STUB
-void Comm::IoCallback::selectOrQueueWrite() STUB
-void Comm::IoCallback::cancel(const char *reason) STUB
-void Comm::IoCallback::finish(comm_err_t code, int xerrn) STUB
-Comm::CbEntry *Comm::iocb_table = NULL;
-void Comm::CallbackTableInit() STUB
-void Comm::CallbackTableDestruct() STUB
-
-#include "comm/Loops.h"
-void Comm::SelectLoopInit(void) STUB
-void Comm::SetSelect(int, unsigned int, PF *, void *, time_t) STUB
-void Comm::ResetSelect(int) STUB
-comm_err_t Comm::DoSelect(int) STUB_RETVAL(COMM_ERROR)
-void Comm::QuickPollRequired(void) STUB
-
-#include "comm/TcpAcceptor.h"
-//Comm::TcpAcceptor(const Comm::ConnectionPointer &conn, const char *note, const Subscription::Pointer &aSub) STUB
-void Comm::TcpAcceptor::subscribe(const Subscription::Pointer &aSub) STUB
-void Comm::TcpAcceptor::unsubscribe(const char *) STUB
-void Comm::TcpAcceptor::acceptNext() STUB
-void Comm::TcpAcceptor::notify(const comm_err_t flag, const Comm::ConnectionPointer &) const STUB
-
-#include "comm/Write.h"
-void Comm::Write(const Comm::ConnectionPointer &, const char *, int, AsyncCall::Pointer &, FREE *) STUB
-void Comm::Write(const Comm::ConnectionPointer &conn, MemBuf *mb, AsyncCall::Pointer &callback) STUB
-void Comm::WriteCancel(const Comm::ConnectionPointer &conn, const char *reason) STUB
-//PF Comm::HandleWrite STUB
diff -u -r -N squid-3.2.0.12/src/disk.cc squid-3.2.0.13/src/disk.cc
--- squid-3.2.0.12/src/disk.cc	2011-09-16 23:37:30.000000000 +1200
+++ squid-3.2.0.13/src/disk.cc	2011-10-14 14:42:56.000000000 +1300
@@ -231,12 +231,14 @@
 
     assert(fdd->write_q->len > fdd->write_q->buf_offset);
 
-    debugs(6, 3, "diskHandleWrite: FD " << fd << " writing " << (fdd->write_q->len - fdd->write_q->buf_offset) << " bytes");
+    debugs(6, 3, "diskHandleWrite: FD " << fd << " writing " <<
+           (fdd->write_q->len - fdd->write_q->buf_offset) << " bytes at " <<
+           fdd->write_q->file_offset);
 
     errno = 0;
 
     if (fdd->write_q->file_offset != -1)
-        lseek(fd, fdd->write_q->file_offset, SEEK_SET);
+        lseek(fd, fdd->write_q->file_offset, SEEK_SET); /* XXX ignore return? */
 
     len = FD_WRITE_METHOD(fd,
                           fdd->write_q->buf + fdd->write_q->buf_offset,
@@ -433,7 +435,11 @@
 
     PROF_start(diskHandleRead);
 
+#if WRITES_MAINTAIN_DISK_OFFSET
     if (F->disk.offset != ctrl_dat->offset) {
+#else
+    {
+#endif
         debugs(6, 3, "diskHandleRead: FD " << fd << " seeking to offset " << ctrl_dat->offset);
         lseek(fd, ctrl_dat->offset, SEEK_SET);	/* XXX ignore return? */
         statCounter.syscalls.disk.seeks++;
diff -u -r -N squid-3.2.0.12/src/DiskIO/Blocking/BlockingFile.cc squid-3.2.0.13/src/DiskIO/Blocking/BlockingFile.cc
--- squid-3.2.0.12/src/DiskIO/Blocking/BlockingFile.cc	2011-09-16 23:37:30.000000000 +1200
+++ squid-3.2.0.13/src/DiskIO/Blocking/BlockingFile.cc	2011-10-14 14:42:56.000000000 +1300
@@ -146,6 +146,7 @@
     assert (fd > -1);
     assert (ioRequestor.getRaw());
     readRequest = aRequest;
+    debugs(79, 3, HERE << aRequest->len << " for FD " << fd << " at " << aRequest->offset);
     file_read(fd, aRequest->buf, aRequest->len, aRequest->offset, ReadDone, this);
 }
 
@@ -160,7 +161,7 @@
 void
 BlockingFile::write(WriteRequest *aRequest)
 {
-    debugs(79, 3, "storeUfsWrite: FD " << fd);
+    debugs(79, 3, HERE << aRequest->len << " for FD " << fd << " at " << aRequest->offset);
     writeRequest = aRequest;
     file_write(fd,
                aRequest->offset,
@@ -216,7 +217,7 @@
 BlockingFile::writeDone(int rvfd, int errflag, size_t len)
 {
     assert (rvfd == fd);
-    debugs(79, 3, "storeUfsWriteDone: FD " << fd << ", len " << len);
+    debugs(79, 3, HERE << "FD " << fd << ", len " << len);
 
     WriteRequest::Pointer result = writeRequest;
     writeRequest = NULL;
diff -u -r -N squid-3.2.0.12/src/DiskIO/DiskFile.h squid-3.2.0.13/src/DiskIO/DiskFile.h
--- squid-3.2.0.12/src/DiskIO/DiskFile.h	2011-09-16 23:37:30.000000000 +1200
+++ squid-3.2.0.13/src/DiskIO/DiskFile.h	2011-10-14 14:42:56.000000000 +1300
@@ -47,8 +47,25 @@
 {
 
 public:
+
+    /// generally useful configuration options supported by some children
+    class Config
+    {
+    public:
+        Config(): ioTimeout(0), ioRate(-1) {}
+
+        /// canRead/Write should return false if expected I/O delay exceeds it
+        time_msec_t ioTimeout; // not enforced if zero, which is the default
+
+        /// shape I/O request stream to approach that many per second
+        int ioRate; // not enforced if negative, which is the default
+    };
+
     typedef RefCount<DiskFile> Pointer;
 
+    /// notes supported configuration options; kids must call this first
+    virtual void configure(const Config &cfg) {}
+
     virtual void open(int flags, mode_t mode, RefCount<IORequestor> callback) = 0;
     virtual void create(int flags, mode_t mode, RefCount<IORequestor> callback) = 0;
     virtual void read(ReadRequest *) = 0;
diff -u -r -N squid-3.2.0.12/src/DiskIO/IpcIo/IpcIoDiskIOModule.cc squid-3.2.0.13/src/DiskIO/IpcIo/IpcIoDiskIOModule.cc
--- squid-3.2.0.12/src/DiskIO/IpcIo/IpcIoDiskIOModule.cc	1970-01-01 12:00:00.000000000 +1200
+++ squid-3.2.0.13/src/DiskIO/IpcIo/IpcIoDiskIOModule.cc	2011-10-14 14:42:56.000000000 +1300
@@ -0,0 +1,37 @@
+#include "squid.h"
+#include "IpcIoDiskIOModule.h"
+#include "IpcIoIOStrategy.h"
+
+IpcIoDiskIOModule::IpcIoDiskIOModule()
+{
+    ModuleAdd(*this);
+}
+
+IpcIoDiskIOModule &
+IpcIoDiskIOModule::GetInstance()
+{
+    return Instance;
+}
+
+void
+IpcIoDiskIOModule::init()
+{}
+
+void
+IpcIoDiskIOModule::shutdown()
+{}
+
+
+DiskIOStrategy*
+IpcIoDiskIOModule::createStrategy()
+{
+    return new IpcIoIOStrategy();
+}
+
+IpcIoDiskIOModule IpcIoDiskIOModule::Instance;
+
+char const *
+IpcIoDiskIOModule::type () const
+{
+    return "IpcIo";
+}
diff -u -r -N squid-3.2.0.12/src/DiskIO/IpcIo/IpcIoDiskIOModule.h squid-3.2.0.13/src/DiskIO/IpcIo/IpcIoDiskIOModule.h
--- squid-3.2.0.12/src/DiskIO/IpcIo/IpcIoDiskIOModule.h	1970-01-01 12:00:00.000000000 +1200
+++ squid-3.2.0.13/src/DiskIO/IpcIo/IpcIoDiskIOModule.h	2011-10-14 14:42:56.000000000 +1300
@@ -0,0 +1,21 @@
+#ifndef SQUID_IPC_IODISKIOMODULE_H
+#define SQUID_IPC_IODISKIOMODULE_H
+
+#include "DiskIO/DiskIOModule.h"
+
+class IpcIoDiskIOModule : public DiskIOModule
+{
+
+public:
+    static IpcIoDiskIOModule &GetInstance();
+    IpcIoDiskIOModule();
+    virtual void init();
+    virtual void shutdown();
+    virtual char const *type () const;
+    virtual DiskIOStrategy* createStrategy();
+
+private:
+    static IpcIoDiskIOModule Instance;
+};
+
+#endif /* SQUID_IPC_IODISKIOMODULE_H */
diff -u -r -N squid-3.2.0.12/src/DiskIO/IpcIo/IpcIoFile.cc squid-3.2.0.13/src/DiskIO/IpcIo/IpcIoFile.cc
--- squid-3.2.0.12/src/DiskIO/IpcIo/IpcIoFile.cc	1970-01-01 12:00:00.000000000 +1200
+++ squid-3.2.0.13/src/DiskIO/IpcIo/IpcIoFile.cc	2011-10-14 14:42:56.000000000 +1300
@@ -0,0 +1,866 @@
+/*
+ * $Id$
+ *
+ * DEBUG: section 47    Store Directory Routines
+ */
+
+#include "config.h"
+#include "base/RunnersRegistry.h"
+#include "base/TextException.h"
+#include "DiskIO/IORequestor.h"
+#include "DiskIO/IpcIo/IpcIoFile.h"
+#include "DiskIO/ReadRequest.h"
+#include "DiskIO/WriteRequest.h"
+#include "ipc/Messages.h"
+#include "ipc/Port.h"
+#include "ipc/Queue.h"
+#include "ipc/StrandSearch.h"
+#include "ipc/UdsOp.h"
+#include "ipc/mem/Pages.h"
+#include "SquidTime.h"
+
+CBDATA_CLASS_INIT(IpcIoFile);
+
+/// shared memory segment path to use for IpcIoFile maps
+static const char *const ShmLabel = "io_file";
+
+const double IpcIoFile::Timeout = 7; // seconds;  XXX: ALL,9 may require more
+IpcIoFile::IpcIoFileList IpcIoFile::WaitingForOpen;
+IpcIoFile::IpcIoFilesMap IpcIoFile::IpcIoFiles;
+std::auto_ptr<IpcIoFile::Queue> IpcIoFile::queue;
+
+bool IpcIoFile::DiskerHandleMoreRequestsScheduled = false;
+
+static bool DiskerOpen(const String &path, int flags, mode_t mode);
+static void DiskerClose(const String &path);
+
+/// IpcIo wrapper for debugs() streams; XXX: find a better class name
+struct SipcIo {
+    SipcIo(int aWorker, const IpcIoMsg &aMsg, int aDisker):
+            worker(aWorker), msg(aMsg), disker(aDisker) {}
+
+    int worker;
+    const IpcIoMsg &msg;
+    int disker;
+};
+
+std::ostream &
+operator <<(std::ostream &os, const SipcIo &sio)
+{
+    return os << "ipcIo" << sio.worker << '.' << sio.msg.requestId <<
+           (sio.msg.command == IpcIo::cmdRead ? 'r' : 'w') << sio.disker;
+}
+
+
+IpcIoFile::IpcIoFile(char const *aDb):
+        dbName(aDb), diskId(-1), error_(false), lastRequestId(0),
+        olderRequests(&requestMap1), newerRequests(&requestMap2),
+        timeoutCheckScheduled(false)
+{
+}
+
+IpcIoFile::~IpcIoFile()
+{
+    if (diskId >= 0) {
+        const IpcIoFilesMap::iterator i = IpcIoFiles.find(diskId);
+        // XXX: warn and continue?
+        Must(i != IpcIoFiles.end());
+        Must(i->second == this);
+        IpcIoFiles.erase(i);
+    }
+}
+
+void
+IpcIoFile::configure(const Config &cfg)
+{
+    DiskFile::configure(cfg);
+    config = cfg;
+}
+
+void
+IpcIoFile::open(int flags, mode_t mode, RefCount<IORequestor> callback)
+{
+    ioRequestor = callback;
+    Must(diskId < 0); // we do not know our disker yet
+
+    if (!queue.get())
+        queue.reset(new Queue(ShmLabel, IamWorkerProcess() ? Queue::groupA : Queue::groupB, KidIdentifier));
+
+    if (IamDiskProcess()) {
+        error_ = !DiskerOpen(dbName, flags, mode);
+        if (error_)
+            return;
+
+        diskId = KidIdentifier;
+        const bool inserted =
+            IpcIoFiles.insert(std::make_pair(diskId, this)).second;
+        Must(inserted);
+
+        queue->localRateLimit() =
+            static_cast<Ipc::QueueReader::Rate::Value>(config.ioRate);
+
+        Ipc::HereIamMessage ann(Ipc::StrandCoord(KidIdentifier, getpid()));
+        ann.strand.tag = dbName;
+        Ipc::TypedMsgHdr message;
+        ann.pack(message);
+        SendMessage(Ipc::coordinatorAddr, message);
+
+        ioRequestor->ioCompletedNotification();
+        return;
+    }
+
+    Ipc::StrandSearchRequest request;
+    request.requestorId = KidIdentifier;
+    request.tag = dbName;
+
+    Ipc::TypedMsgHdr msg;
+    request.pack(msg);
+    Ipc::SendMessage(Ipc::coordinatorAddr, msg);
+
+    WaitingForOpen.push_back(this);
+
+    eventAdd("IpcIoFile::OpenTimeout", &IpcIoFile::OpenTimeout,
+             this, Timeout, 0, false); // "this" pointer is used as id
+}
+
+void
+IpcIoFile::openCompleted(const Ipc::StrandSearchResponse *const response)
+{
+    Must(diskId < 0); // we do not know our disker yet
+
+    if (!response) {
+        debugs(79,1, HERE << "error: timeout");
+        error_ = true;
+    } else {
+        diskId = response->strand.kidId;
+        if (diskId >= 0) {
+            const bool inserted =
+                IpcIoFiles.insert(std::make_pair(diskId, this)).second;
+            Must(inserted);
+        } else {
+            error_ = true;
+            debugs(79,1, HERE << "error: no disker claimed " << dbName);
+        }
+    }
+
+    ioRequestor->ioCompletedNotification();
+}
+
+/**
+ * Alias for IpcIoFile::open(...)
+ \copydoc IpcIoFile::open(int flags, mode_t mode, RefCount<IORequestor> callback)
+ */
+void
+IpcIoFile::create(int flags, mode_t mode, RefCount<IORequestor> callback)
+{
+    assert(false); // check
+    /* We use the same logic path for open */
+    open(flags, mode, callback);
+}
+
+void
+IpcIoFile::close()
+{
+    assert(ioRequestor != NULL);
+
+    if (IamDiskProcess())
+        DiskerClose(dbName);
+    // XXX: else nothing to do?
+
+    ioRequestor->closeCompleted();
+}
+
+bool
+IpcIoFile::canRead() const
+{
+    return diskId >= 0 && canWait();
+}
+
+bool
+IpcIoFile::canWrite() const
+{
+    return diskId >= 0 && canWait();
+}
+
+bool
+IpcIoFile::error() const
+{
+    return error_;
+}
+
+void
+IpcIoFile::read(ReadRequest *readRequest)
+{
+    debugs(79,3, HERE << "(disker" << diskId << ", " << readRequest->len << ", " <<
+           readRequest->offset << ")");
+
+    assert(ioRequestor != NULL);
+    assert(readRequest->offset >= 0);
+    Must(!error_);
+
+    //assert(minOffset < 0 || minOffset <= readRequest->offset);
+    //assert(maxOffset < 0 || readRequest->offset + readRequest->len <= (uint64_t)maxOffset);
+
+    IpcIoPendingRequest *const pending = new IpcIoPendingRequest(this);
+    pending->readRequest = readRequest;
+    push(pending);
+}
+
+void
+IpcIoFile::readCompleted(ReadRequest *readRequest,
+                         IpcIoMsg *const response)
+{
+    bool ioError = false;
+    if (!response) {
+        debugs(79, 3, HERE << "error: timeout");
+        ioError = true; // I/O timeout does not warrant setting error_?
+    } else {
+        if (response->xerrno) {
+            debugs(79,1, HERE << "error: " << xstrerr(response->xerrno));
+            ioError = error_ = true;
+        } else if (!response->page) {
+            debugs(79,1, HERE << "error: run out of shared memory pages");
+            ioError = true;
+        } else {
+            const char *const buf = Ipc::Mem::PagePointer(response->page);
+            memcpy(readRequest->buf, buf, response->len);
+        }
+
+        Ipc::Mem::PutPage(response->page);
+    }
+
+    const ssize_t rlen = ioError ? -1 : (ssize_t)readRequest->len;
+    const int errflag = ioError ? DISK_ERROR :DISK_OK;
+    ioRequestor->readCompleted(readRequest->buf, rlen, errflag, readRequest);
+}
+
+void
+IpcIoFile::write(WriteRequest *writeRequest)
+{
+    debugs(79,3, HERE << "(disker" << diskId << ", " << writeRequest->len << ", " <<
+           writeRequest->offset << ")");
+
+    assert(ioRequestor != NULL);
+    assert(writeRequest->len > 0); // TODO: work around mmap failures on zero-len?
+    assert(writeRequest->offset >= 0);
+    Must(!error_);
+
+    //assert(minOffset < 0 || minOffset <= writeRequest->offset);
+    //assert(maxOffset < 0 || writeRequest->offset + writeRequest->len <= (uint64_t)maxOffset);
+
+    IpcIoPendingRequest *const pending = new IpcIoPendingRequest(this);
+    pending->writeRequest = writeRequest;
+    push(pending);
+}
+
+void
+IpcIoFile::writeCompleted(WriteRequest *writeRequest,
+                          const IpcIoMsg *const response)
+{
+    bool ioError = false;
+    if (!response) {
+        debugs(79, 3, HERE << "error: timeout");
+        ioError = true; // I/O timeout does not warrant setting error_?
+    } else if (response->xerrno) {
+        debugs(79,1, HERE << "error: " << xstrerr(response->xerrno));
+        ioError = error_ = true;
+    } else if (response->len != writeRequest->len) {
+        debugs(79,1, HERE << "problem: " << response->len << " < " << writeRequest->len);
+        error_ = true;
+    }
+
+    if (writeRequest->free_func)
+        (writeRequest->free_func)(const_cast<char*>(writeRequest->buf)); // broken API?
+
+    if (!ioError) {
+        debugs(79,5, HERE << "wrote " << writeRequest->len << " to disker" <<
+               diskId << " at " << writeRequest->offset);
+    }
+
+    const ssize_t rlen = ioError ? 0 : (ssize_t)writeRequest->len;
+    const int errflag = ioError ? DISK_ERROR :DISK_OK;
+    ioRequestor->writeCompleted(errflag, rlen, writeRequest);
+}
+
+bool
+IpcIoFile::ioInProgress() const
+{
+    return !olderRequests->empty() || !newerRequests->empty();
+}
+
+/// track a new pending request
+void
+IpcIoFile::trackPendingRequest(IpcIoPendingRequest *const pending)
+{
+    newerRequests->insert(std::make_pair(lastRequestId, pending));
+    if (!timeoutCheckScheduled)
+        scheduleTimeoutCheck();
+}
+
+/// push an I/O request to disker
+void
+IpcIoFile::push(IpcIoPendingRequest *const pending)
+{
+    // prevent queue overflows: check for responses to earlier requests
+    HandleResponses("before push");
+
+    debugs(47, 7, HERE);
+    Must(diskId >= 0);
+    Must(pending);
+    Must(pending->readRequest || pending->writeRequest);
+
+    IpcIoMsg ipcIo;
+    try {
+        ipcIo.requestId = lastRequestId;
+        ipcIo.start = current_time;
+        if (pending->readRequest) {
+            ipcIo.command = IpcIo::cmdRead;
+            ipcIo.offset = pending->readRequest->offset;
+            ipcIo.len = pending->readRequest->len;
+        } else { // pending->writeRequest
+            Must(pending->writeRequest->len <= Ipc::Mem::PageSize());
+            if (!Ipc::Mem::GetPage(Ipc::Mem::PageId::ioPage, ipcIo.page)) {
+                ipcIo.len = 0;
+                throw TexcHere("run out of shared memory pages for IPC I/O");
+            }
+            ipcIo.command = IpcIo::cmdWrite;
+            ipcIo.offset = pending->writeRequest->offset;
+            ipcIo.len = pending->writeRequest->len;
+            char *const buf = Ipc::Mem::PagePointer(ipcIo.page);
+            memcpy(buf, pending->writeRequest->buf, ipcIo.len); // optimize away
+        }
+
+        debugs(47, 7, HERE << "pushing " << SipcIo(KidIdentifier, ipcIo, diskId));
+
+        if (queue->push(diskId, ipcIo))
+            Notify(diskId); // must notify disker
+        trackPendingRequest(pending);
+    } catch (const Queue::Full &) {
+        debugs(47, DBG_IMPORTANT, "Worker I/O push queue overflow: " <<
+               SipcIo(KidIdentifier, ipcIo, diskId)); // TODO: report queue len
+        // TODO: grow queue size
+
+        pending->completeIo(NULL);
+        delete pending;
+    } catch (const TextException &e) {
+        debugs(47, DBG_IMPORTANT, HERE << e.what());
+        pending->completeIo(NULL);
+        delete pending;
+    }
+}
+
+/// whether we think there is enough time to complete the I/O
+bool
+IpcIoFile::canWait() const
+{
+    if (!config.ioTimeout)
+        return true; // no timeout specified
+
+    IpcIoMsg oldestIo;
+    if (!queue->peek(diskId, oldestIo) || oldestIo.start.tv_sec <= 0)
+        return true; // we cannot estimate expected wait time; assume it is OK
+
+    const int expectedWait = tvSubMsec(oldestIo.start, current_time);
+    if (expectedWait < 0 ||
+            static_cast<time_msec_t>(expectedWait) < config.ioTimeout)
+        return true; // expected wait time is acceptible
+
+    debugs(47,2, HERE << "cannot wait: " << expectedWait <<
+           " oldest: " << SipcIo(KidIdentifier, oldestIo, diskId));
+    return false; // do not want to wait that long
+}
+
+/// called when coordinator responds to worker open request
+void
+IpcIoFile::HandleOpenResponse(const Ipc::StrandSearchResponse &response)
+{
+    debugs(47, 7, HERE << "coordinator response to open request");
+    for (IpcIoFileList::iterator i = WaitingForOpen.begin();
+            i != WaitingForOpen.end(); ++i) {
+        if (response.strand.tag == (*i)->dbName) {
+            (*i)->openCompleted(&response);
+            WaitingForOpen.erase(i);
+            return;
+        }
+    }
+
+    debugs(47, 4, HERE << "LATE disker response to open for " <<
+           response.strand.tag);
+    // nothing we can do about it; completeIo() has been called already
+}
+
+void
+IpcIoFile::HandleResponses(const char *const when)
+{
+    debugs(47, 4, HERE << "popping all " << when);
+    IpcIoMsg ipcIo;
+    // get all responses we can: since we are not pushing, this will stop
+    int diskId;
+    while (queue->pop(diskId, ipcIo)) {
+        const IpcIoFilesMap::const_iterator i = IpcIoFiles.find(diskId);
+        Must(i != IpcIoFiles.end()); // TODO: warn but continue
+        i->second->handleResponse(ipcIo);
+    }
+}
+
+void
+IpcIoFile::handleResponse(IpcIoMsg &ipcIo)
+{
+    const int requestId = ipcIo.requestId;
+    debugs(47, 7, HERE << "popped disker response: " <<
+           SipcIo(KidIdentifier, ipcIo, diskId));
+
+    Must(requestId);
+    if (IpcIoPendingRequest *const pending = dequeueRequest(requestId)) {
+        pending->completeIo(&ipcIo);
+        delete pending; // XXX: leaking if throwing
+    } else {
+        debugs(47, 4, HERE << "LATE disker response to " << ipcIo.command <<
+               "; ipcIo" << KidIdentifier << '.' << requestId);
+        // nothing we can do about it; completeIo() has been called already
+    }
+}
+
+void
+IpcIoFile::Notify(const int peerId)
+{
+    // TODO: Count and report the total number of notifications, pops, pushes.
+    debugs(47, 7, HERE << "kid" << peerId);
+    Ipc::TypedMsgHdr msg;
+    msg.setType(Ipc::mtIpcIoNotification); // TODO: add proper message type?
+    msg.putInt(KidIdentifier);
+    const String addr = Ipc::Port::MakeAddr(Ipc::strandAddrPfx, peerId);
+    Ipc::SendMessage(addr, msg);
+}
+
+void
+IpcIoFile::HandleNotification(const Ipc::TypedMsgHdr &msg)
+{
+    const int from = msg.getInt();
+    debugs(47, 7, HERE << "from " << from);
+    queue->clearReaderSignal(from);
+    if (IamDiskProcess())
+        DiskerHandleRequests();
+    else
+        HandleResponses("after notification");
+}
+
+/// handles open request timeout
+void
+IpcIoFile::OpenTimeout(void *const param)
+{
+    Must(param);
+    // the pointer is used for comparison only and not dereferenced
+    const IpcIoFile *const ipcIoFile =
+        reinterpret_cast<const IpcIoFile *>(param);
+    for (IpcIoFileList::iterator i = WaitingForOpen.begin();
+            i != WaitingForOpen.end(); ++i) {
+        if (*i == ipcIoFile) {
+            (*i)->openCompleted(NULL);
+            WaitingForOpen.erase(i);
+            break;
+        }
+    }
+}
+
+/// IpcIoFile::checkTimeouts wrapper
+void
+IpcIoFile::CheckTimeouts(void *const param)
+{
+    Must(param);
+    const int diskId = reinterpret_cast<uintptr_t>(param);
+    debugs(47, 7, HERE << "diskId=" << diskId);
+    const IpcIoFilesMap::const_iterator i = IpcIoFiles.find(diskId);
+    if (i != IpcIoFiles.end())
+        i->second->checkTimeouts();
+}
+
+void
+IpcIoFile::checkTimeouts()
+{
+    timeoutCheckScheduled = false;
+
+    // last chance to recover in case a notification message was lost, etc.
+    const RequestMap::size_type timeoutsBefore = olderRequests->size();
+    HandleResponses("before timeout");
+    const RequestMap::size_type timeoutsNow = olderRequests->size();
+
+    if (timeoutsBefore > timeoutsNow) { // some requests were rescued
+        // notification message lost or significantly delayed?
+        debugs(47, DBG_IMPORTANT, "WARNING: communication with disker " <<
+               "may be too slow or disrupted for about " <<
+               Timeout << "s; rescued " << (timeoutsBefore - timeoutsNow) <<
+               " out of " << timeoutsBefore << " I/Os");
+    }
+
+    if (timeoutsNow) {
+        debugs(47, DBG_IMPORTANT, "WARNING: abandoning " <<
+               timeoutsNow << " I/Os after at least " <<
+               Timeout << "s timeout");
+    }
+
+    // any old request would have timed out by now
+    typedef RequestMap::const_iterator RMCI;
+    for (RMCI i = olderRequests->begin(); i != olderRequests->end(); ++i) {
+        IpcIoPendingRequest *const pending = i->second;
+
+        const unsigned int requestId = i->first;
+        debugs(47, 7, HERE << "disker timeout; ipcIo" <<
+               KidIdentifier << '.' << requestId);
+
+        pending->completeIo(NULL); // no response
+        delete pending; // XXX: leaking if throwing
+    }
+    olderRequests->clear();
+
+    swap(olderRequests, newerRequests); // switches pointers around
+    if (!olderRequests->empty() && !timeoutCheckScheduled)
+        scheduleTimeoutCheck();
+}
+
+/// prepare to check for timeouts in a little while
+void
+IpcIoFile::scheduleTimeoutCheck()
+{
+    // we check all older requests at once so some may be wait for 2*Timeout
+    eventAdd("IpcIoFile::CheckTimeouts", &IpcIoFile::CheckTimeouts,
+             reinterpret_cast<void *>(diskId), Timeout, 0, false);
+    timeoutCheckScheduled = true;
+}
+
+/// returns and forgets the right IpcIoFile pending request
+IpcIoPendingRequest *
+IpcIoFile::dequeueRequest(const unsigned int requestId)
+{
+    Must(requestId != 0);
+
+    RequestMap *map = NULL;
+    RequestMap::iterator i = requestMap1.find(requestId);
+
+    if (i != requestMap1.end())
+        map = &requestMap1;
+    else {
+        i = requestMap2.find(requestId);
+        if (i != requestMap2.end())
+            map = &requestMap2;
+    }
+
+    if (!map) // not found in both maps
+        return NULL;
+
+    IpcIoPendingRequest *pending = i->second;
+    map->erase(i);
+    return pending;
+}
+
+int
+IpcIoFile::getFD() const
+{
+    assert(false); // not supported; TODO: remove this method from API
+    return -1;
+}
+
+
+/* IpcIoMsg */
+
+IpcIoMsg::IpcIoMsg():
+        requestId(0), offset(0), len(0), command(IpcIo::cmdNone), xerrno(0)
+{
+    start.tv_sec = 0;
+}
+
+/* IpcIoPendingRequest */
+
+IpcIoPendingRequest::IpcIoPendingRequest(const IpcIoFile::Pointer &aFile):
+        file(aFile), readRequest(NULL), writeRequest(NULL)
+{
+    Must(file != NULL);
+    if (++file->lastRequestId == 0) // don't use zero value as requestId
+        ++file->lastRequestId;
+}
+
+void
+IpcIoPendingRequest::completeIo(IpcIoMsg *const response)
+{
+    if (readRequest)
+        file->readCompleted(readRequest, response);
+    else if (writeRequest)
+        file->writeCompleted(writeRequest, response);
+    else {
+        Must(!response); // only timeouts are handled here
+        file->openCompleted(NULL);
+    }
+}
+
+
+
+/* XXX: disker code that should probably be moved elsewhere */
+
+static int TheFile = -1; ///< db file descriptor
+
+static void
+diskerRead(IpcIoMsg &ipcIo)
+{
+    if (!Ipc::Mem::GetPage(Ipc::Mem::PageId::ioPage, ipcIo.page)) {
+        ipcIo.len = 0;
+        debugs(47,2, HERE << "run out of shared memory pages for IPC I/O");
+        return;
+    }
+
+    char *const buf = Ipc::Mem::PagePointer(ipcIo.page);
+    const ssize_t read = pread(TheFile, buf, min(ipcIo.len, Ipc::Mem::PageSize()), ipcIo.offset);
+    statCounter.syscalls.disk.reads++;
+    fd_bytes(TheFile, read, FD_READ);
+
+    if (read >= 0) {
+        ipcIo.xerrno = 0;
+        const size_t len = static_cast<size_t>(read); // safe because read > 0
+        debugs(47,8, HERE << "disker" << KidIdentifier << " read " <<
+               (len == ipcIo.len ? "all " : "just ") << read);
+        ipcIo.len = len;
+    } else {
+        ipcIo.xerrno = errno;
+        ipcIo.len = 0;
+        debugs(47,5, HERE << "disker" << KidIdentifier << " read error: " <<
+               ipcIo.xerrno);
+    }
+}
+
+static void
+diskerWrite(IpcIoMsg &ipcIo)
+{
+    const char *const buf = Ipc::Mem::PagePointer(ipcIo.page);
+    const ssize_t wrote = pwrite(TheFile, buf, min(ipcIo.len, Ipc::Mem::PageSize()), ipcIo.offset);
+    statCounter.syscalls.disk.writes++;
+    fd_bytes(TheFile, wrote, FD_WRITE);
+
+    if (wrote >= 0) {
+        ipcIo.xerrno = 0;
+        const size_t len = static_cast<size_t>(wrote); // safe because wrote > 0
+        debugs(47,8, HERE << "disker" << KidIdentifier << " wrote " <<
+               (len == ipcIo.len ? "all " : "just ") << wrote);
+        ipcIo.len = len;
+    } else {
+        ipcIo.xerrno = errno;
+        ipcIo.len = 0;
+        debugs(47,5, HERE << "disker" << KidIdentifier << " write error: " <<
+               ipcIo.xerrno);
+    }
+
+    Ipc::Mem::PutPage(ipcIo.page);
+}
+
+
+void
+IpcIoFile::DiskerHandleMoreRequests(void *source)
+{
+    debugs(47, 7, HERE << "resuming handling requests after " <<
+           static_cast<const char *>(source));
+    DiskerHandleMoreRequestsScheduled = false;
+    IpcIoFile::DiskerHandleRequests();
+}
+
+bool
+IpcIoFile::WaitBeforePop()
+{
+    const Ipc::QueueReader::Rate::Value ioRate = queue->localRateLimit();
+    const double maxRate = ioRate/1e3; // req/ms
+
+    // do we need to enforce configured I/O rate?
+    if (maxRate <= 0)
+        return false;
+
+    // is there an I/O request we could potentially delay?
+    if (!queue->popReady()) {
+        // unlike pop(), popReady() is not reliable and does not block reader
+        // so we must proceed with pop() even if it is likely to fail
+        return false;
+    }
+
+    static timeval LastIo = current_time;
+
+    const double ioDuration = 1.0 / maxRate; // ideal distance between two I/Os
+    // do not accumulate more than 100ms or 100 I/Os, whichever is smaller
+    const int64_t maxImbalance = min(static_cast<int64_t>(100), static_cast<int64_t>(100 * ioDuration));
+
+    const double credit = ioDuration; // what the last I/O should have cost us
+    const double debit = tvSubMsec(LastIo, current_time); // actual distance from the last I/O
+    LastIo = current_time;
+
+    Ipc::QueueReader::Balance &balance = queue->localBalance();
+    balance += static_cast<int64_t>(credit - debit);
+
+    debugs(47, 7, HERE << "rate limiting balance: " << balance << " after +" << credit << " -" << debit);
+
+    if (balance > maxImbalance) {
+        // if we accumulated too much time for future slow I/Os,
+        // then shed accumulated time to keep just half of the excess
+        const int64_t toSpend = balance - maxImbalance/2;
+
+        if (toSpend/1e3 > Timeout)
+            debugs(47, DBG_IMPORTANT, "WARNING: Rock disker delays I/O " <<
+                   "requests for " << (toSpend/1e3) << " seconds to obey " <<
+                   ioRate << "/sec rate limit");
+
+        debugs(47, 3, HERE << "rate limiting by " << toSpend << " ms to get" <<
+               (1e3*maxRate) << "/sec rate");
+        eventAdd("IpcIoFile::DiskerHandleMoreRequests",
+                 &IpcIoFile::DiskerHandleMoreRequests,
+                 const_cast<char*>("rate limiting"),
+                 toSpend/1e3, 0, false);
+        DiskerHandleMoreRequestsScheduled = true;
+        return true;
+    } else if (balance < -maxImbalance) {
+        // do not owe "too much" to avoid "too large" bursts of I/O
+        balance = -maxImbalance;
+    }
+
+    return false;
+}
+
+void
+IpcIoFile::DiskerHandleRequests()
+{
+    // Balance our desire to maximize the number of concurrent I/O requests
+    // (reordred by OS to minimize seek time) with a requirement to
+    // send 1st-I/O notification messages, process Coordinator events, etc.
+    const int maxSpentMsec = 10; // keep small: most RAM I/Os are under 1ms
+    const timeval loopStart = current_time;
+
+    int popped = 0;
+    int workerId = 0;
+    IpcIoMsg ipcIo;
+    while (!WaitBeforePop() && queue->pop(workerId, ipcIo)) {
+        ++popped;
+
+        // at least one I/O per call is guaranteed if the queue is not empty
+        DiskerHandleRequest(workerId, ipcIo);
+
+        getCurrentTime();
+        const double elapsedMsec = tvSubMsec(loopStart, current_time);
+        if (elapsedMsec > maxSpentMsec || elapsedMsec < 0) {
+            if (!DiskerHandleMoreRequestsScheduled) {
+                // the gap must be positive for select(2) to be given a chance
+                const double minBreakSecs = 0.001;
+                eventAdd("IpcIoFile::DiskerHandleMoreRequests",
+                         &IpcIoFile::DiskerHandleMoreRequests,
+                         const_cast<char*>("long I/O loop"),
+                         minBreakSecs, 0, false);
+                DiskerHandleMoreRequestsScheduled = true;
+            }
+            debugs(47, 3, HERE << "pausing after " << popped << " I/Os in " <<
+                   elapsedMsec << "ms; " << (elapsedMsec/popped) << "ms per I/O");
+            break;
+        }
+    }
+
+    // TODO: consider using O_DIRECT with "elevator" optimization where we pop
+    // requests first, then reorder the popped requests to optimize seek time,
+    // then do I/O, then take a break, and come back for the next set of I/O
+    // requests.
+}
+
+/// called when disker receives an I/O request
+void
+IpcIoFile::DiskerHandleRequest(const int workerId, IpcIoMsg &ipcIo)
+{
+    if (ipcIo.command != IpcIo::cmdRead && ipcIo.command != IpcIo::cmdWrite) {
+        debugs(0,0, HERE << "disker" << KidIdentifier <<
+               " should not receive " << ipcIo.command <<
+               " ipcIo" << workerId << '.' << ipcIo.requestId);
+        return;
+    }
+
+    debugs(47,5, HERE << "disker" << KidIdentifier <<
+           (ipcIo.command == IpcIo::cmdRead ? " reads " : " writes ") <<
+           ipcIo.len << " at " << ipcIo.offset <<
+           " ipcIo" << workerId << '.' << ipcIo.requestId);
+
+    if (ipcIo.command == IpcIo::cmdRead)
+        diskerRead(ipcIo);
+    else // ipcIo.command == IpcIo::cmdWrite
+        diskerWrite(ipcIo);
+
+    debugs(47, 7, HERE << "pushing " << SipcIo(workerId, ipcIo, KidIdentifier));
+
+    try {
+        if (queue->push(workerId, ipcIo))
+            Notify(workerId); // must notify worker
+    } catch (const Queue::Full &) {
+        // The worker queue should not overflow because the worker should pop()
+        // before push()ing and because if disker pops N requests at a time,
+        // we should make sure the worker pop() queue length is the worker
+        // push queue length plus N+1. XXX: implement the N+1 difference.
+        debugs(47, DBG_IMPORTANT, "BUG: Worker I/O pop queue overflow: " <<
+               SipcIo(workerId, ipcIo, KidIdentifier)); // TODO: report queue len
+
+        // the I/O request we could not push will timeout
+    }
+}
+
+static bool
+DiskerOpen(const String &path, int flags, mode_t mode)
+{
+    assert(TheFile < 0);
+
+    TheFile = file_open(path.termedBuf(), flags);
+
+    if (TheFile < 0) {
+        const int xerrno = errno;
+        debugs(47,0, HERE << "rock db error opening " << path << ": " <<
+               xstrerr(xerrno));
+        return false;
+    }
+
+    store_open_disk_fd++;
+    debugs(79,3, HERE << "rock db opened " << path << ": FD " << TheFile);
+    return true;
+}
+
+static void
+DiskerClose(const String &path)
+{
+    if (TheFile >= 0) {
+        file_close(TheFile);
+        debugs(79,3, HERE << "rock db closed " << path << ": FD " << TheFile);
+        TheFile = -1;
+        store_open_disk_fd--;
+    }
+}
+
+
+/// initializes shared memory segments used by IpcIoFile
+class IpcIoRr: public Ipc::Mem::RegisteredRunner
+{
+public:
+    /* RegisteredRunner API */
+    IpcIoRr(): owner(NULL) {}
+    virtual ~IpcIoRr();
+
+protected:
+    virtual void create(const RunnerRegistry &);
+
+private:
+    Ipc::FewToFewBiQueue::Owner *owner;
+};
+
+RunnerRegistrationEntry(rrAfterConfig, IpcIoRr);
+
+
+void IpcIoRr::create(const RunnerRegistry &)
+{
+    if (!UsingSmp())
+        return;
+
+    Must(!owner);
+    // XXX: make capacity configurable
+    owner = Ipc::FewToFewBiQueue::Init(ShmLabel, Config.workers, 1,
+                                       Config.cacheSwap.n_strands,
+                                       1 + Config.workers, sizeof(IpcIoMsg),
+                                       1024);
+}
+
+IpcIoRr::~IpcIoRr()
+{
+    delete owner;
+}
diff -u -r -N squid-3.2.0.12/src/DiskIO/IpcIo/IpcIoFile.h squid-3.2.0.13/src/DiskIO/IpcIo/IpcIoFile.h
--- squid-3.2.0.12/src/DiskIO/IpcIo/IpcIoFile.h	1970-01-01 12:00:00.000000000 +1200
+++ squid-3.2.0.13/src/DiskIO/IpcIo/IpcIoFile.h	2011-10-14 14:42:56.000000000 +1300
@@ -0,0 +1,163 @@
+#ifndef SQUID_IPC_IOFILE_H
+#define SQUID_IPC_IOFILE_H
+
+#include "base/AsyncCall.h"
+#include "cbdata.h"
+#include "DiskIO/DiskFile.h"
+#include "DiskIO/IORequestor.h"
+#include "ipc/forward.h"
+#include "ipc/mem/Page.h"
+#include <list>
+#include <map>
+#include <memory>
+
+namespace Ipc
+{
+class FewToFewBiQueue;
+} // Ipc
+
+// TODO: expand to all classes
+namespace IpcIo
+{
+
+/// what kind of I/O the disker needs to do or have done
+typedef enum { cmdNone, cmdOpen, cmdRead, cmdWrite } Command;
+
+} // namespace IpcIo
+
+
+/// converts DiskIO requests to IPC queue messages
+class IpcIoMsg
+{
+public:
+    IpcIoMsg();
+
+public:
+    unsigned int requestId; ///< unique for requestor; matches request w/ response
+
+    off_t offset;
+    size_t len;
+    Ipc::Mem::PageId page;
+
+    IpcIo::Command command; ///< what disker is supposed to do or did
+    struct timeval start; ///< when the I/O request was converted to IpcIoMsg
+
+    int xerrno; ///< I/O error code or zero
+};
+
+class IpcIoPendingRequest;
+
+class IpcIoFile: public DiskFile
+{
+
+public:
+    typedef RefCount<IpcIoFile> Pointer;
+
+    IpcIoFile(char const *aDb);
+    virtual ~IpcIoFile();
+
+    /* DiskFile API */
+    virtual void configure(const Config &cfg);
+    virtual void open(int flags, mode_t mode, RefCount<IORequestor> callback);
+    virtual void create(int flags, mode_t mode, RefCount<IORequestor> callback);
+    virtual void read(ReadRequest *);
+    virtual void write(WriteRequest *);
+    virtual void close();
+    virtual bool error() const;
+    virtual int getFD() const;
+    virtual bool canRead() const;
+    virtual bool canWrite() const;
+    virtual bool ioInProgress() const;
+
+    /// handle open response from coordinator
+    static void HandleOpenResponse(const Ipc::StrandSearchResponse &response);
+
+    /// handle queue push notifications from worker or disker
+    static void HandleNotification(const Ipc::TypedMsgHdr &msg);
+
+    DiskFile::Config config; ///< supported configuration options
+
+protected:
+    friend class IpcIoPendingRequest;
+    void openCompleted(const Ipc::StrandSearchResponse *const response);
+    void readCompleted(ReadRequest *readRequest, IpcIoMsg *const response);
+    void writeCompleted(WriteRequest *writeRequest, const IpcIoMsg *const response);
+    bool canWait() const;
+
+private:
+    void trackPendingRequest(IpcIoPendingRequest *const pending);
+    void push(IpcIoPendingRequest *const pending);
+    IpcIoPendingRequest *dequeueRequest(const unsigned int requestId);
+
+    static void Notify(const int peerId);
+
+    static void OpenTimeout(void *const param);
+    static void CheckTimeouts(void *const param);
+    void checkTimeouts();
+    void scheduleTimeoutCheck();
+
+    static void HandleResponses(const char *const when);
+    void handleResponse(IpcIoMsg &ipcIo);
+
+    static void DiskerHandleMoreRequests(void*);
+    static void DiskerHandleRequests();
+    static void DiskerHandleRequest(const int workerId, IpcIoMsg &ipcIo);
+    static bool WaitBeforePop();
+
+private:
+    const String dbName; ///< the name of the file we are managing
+    int diskId; ///< the process ID of the disker we talk to
+    RefCount<IORequestor> ioRequestor;
+
+    bool error_; ///< whether we have seen at least one I/O error (XXX)
+
+    unsigned int lastRequestId; ///< last requestId used
+
+    /// maps requestId to the handleResponse callback
+    typedef std::map<unsigned int, IpcIoPendingRequest*> RequestMap;
+    RequestMap requestMap1; ///< older (or newer) pending requests
+    RequestMap requestMap2; ///< newer (or older) pending requests
+    RequestMap *olderRequests; ///< older requests (map1 or map2)
+    RequestMap *newerRequests; ///< newer requests (map2 or map1)
+    bool timeoutCheckScheduled; ///< we expect a CheckTimeouts() call
+
+    static const double Timeout; ///< timeout value in seconds
+
+    typedef std::list<Pointer> IpcIoFileList;
+    static IpcIoFileList WaitingForOpen; ///< pending open requests
+
+    ///< maps diskerId to IpcIoFile, cleared in destructor
+    typedef std::map<int, IpcIoFile*> IpcIoFilesMap;
+    static IpcIoFilesMap IpcIoFiles;
+
+    typedef Ipc::FewToFewBiQueue Queue;
+    static std::auto_ptr<Queue> queue; ///< IPC queue
+
+    /// whether we are waiting for an event to handle still queued I/O requests
+    static bool DiskerHandleMoreRequestsScheduled;
+
+    CBDATA_CLASS2(IpcIoFile);
+};
+
+
+/// keeps original I/O request parameters while disker is handling the request
+class IpcIoPendingRequest
+{
+public:
+    IpcIoPendingRequest(const IpcIoFile::Pointer &aFile);
+
+    /// called when response is received and, with a nil response, on timeouts
+    void completeIo(IpcIoMsg *const response);
+
+public:
+    const IpcIoFile::Pointer file; ///< the file object waiting for the response
+    ReadRequest *readRequest; ///< set if this is a read requests
+    WriteRequest *writeRequest; ///< set if this is a write request
+
+private:
+    IpcIoPendingRequest(const IpcIoPendingRequest &d); // not implemented
+    IpcIoPendingRequest &operator =(const IpcIoPendingRequest &d); // ditto
+};
+
+
+#endif /* SQUID_IPC_IOFILE_H */
diff -u -r -N squid-3.2.0.12/src/DiskIO/IpcIo/IpcIoIOStrategy.cc squid-3.2.0.13/src/DiskIO/IpcIo/IpcIoIOStrategy.cc
--- squid-3.2.0.12/src/DiskIO/IpcIo/IpcIoIOStrategy.cc	1970-01-01 12:00:00.000000000 +1200
+++ squid-3.2.0.13/src/DiskIO/IpcIo/IpcIoIOStrategy.cc	2011-10-14 14:42:56.000000000 +1300
@@ -0,0 +1,39 @@
+
+/*
+ * $Id$
+ *
+ * DEBUG: section 47    Store Directory Routines
+ */
+
+#include "config.h"
+#include "IpcIoFile.h"
+#include "IpcIoIOStrategy.h"
+
+bool
+IpcIoIOStrategy::shedLoad()
+{
+    return false;
+}
+
+int
+IpcIoIOStrategy::load()
+{
+    /* Return 999 (99.9%) constant load */
+    return 999;
+}
+
+DiskFile::Pointer
+IpcIoIOStrategy::newFile (char const *path)
+{
+    return new IpcIoFile (path);
+}
+
+void
+IpcIoIOStrategy::unlinkFile(char const *path)
+{
+#if USE_UNLINKD
+    unlinkdUnlink(path);
+#else
+    ::unlink(path);
+#endif
+}
diff -u -r -N squid-3.2.0.12/src/DiskIO/IpcIo/IpcIoIOStrategy.h squid-3.2.0.13/src/DiskIO/IpcIo/IpcIoIOStrategy.h
--- squid-3.2.0.12/src/DiskIO/IpcIo/IpcIoIOStrategy.h	1970-01-01 12:00:00.000000000 +1200
+++ squid-3.2.0.13/src/DiskIO/IpcIo/IpcIoIOStrategy.h	2011-10-14 14:42:56.000000000 +1300
@@ -0,0 +1,15 @@
+#ifndef SQUID_IPC_IOIOSTRATEGY_H
+#define SQUID_IPC_IOIOSTRATEGY_H
+#include "DiskIO/DiskIOStrategy.h"
+
+class IpcIoIOStrategy : public DiskIOStrategy
+{
+
+public:
+    virtual bool shedLoad();
+    virtual int load();
+    virtual RefCount<DiskFile> newFile(char const *path);
+    virtual void unlinkFile (char const *);
+};
+
+#endif /* SQUID_IPC_IOIOSTRATEGY_H */
diff -u -r -N squid-3.2.0.12/src/DiskIO/Mmapped/MmappedDiskIOModule.cc squid-3.2.0.13/src/DiskIO/Mmapped/MmappedDiskIOModule.cc
--- squid-3.2.0.12/src/DiskIO/Mmapped/MmappedDiskIOModule.cc	1970-01-01 12:00:00.000000000 +1200
+++ squid-3.2.0.13/src/DiskIO/Mmapped/MmappedDiskIOModule.cc	2011-10-14 14:42:56.000000000 +1300
@@ -0,0 +1,37 @@
+#include "squid.h"
+#include "MmappedDiskIOModule.h"
+#include "MmappedIOStrategy.h"
+
+MmappedDiskIOModule::MmappedDiskIOModule()
+{
+    ModuleAdd(*this);
+}
+
+MmappedDiskIOModule &
+MmappedDiskIOModule::GetInstance()
+{
+    return Instance;
+}
+
+void
+MmappedDiskIOModule::init()
+{}
+
+void
+MmappedDiskIOModule::shutdown()
+{}
+
+
+DiskIOStrategy*
+MmappedDiskIOModule::createStrategy()
+{
+    return new MmappedIOStrategy();
+}
+
+MmappedDiskIOModule MmappedDiskIOModule::Instance;
+
+char const *
+MmappedDiskIOModule::type () const
+{
+    return "Mmapped";
+}
diff -u -r -N squid-3.2.0.12/src/DiskIO/Mmapped/MmappedDiskIOModule.h squid-3.2.0.13/src/DiskIO/Mmapped/MmappedDiskIOModule.h
--- squid-3.2.0.12/src/DiskIO/Mmapped/MmappedDiskIOModule.h	1970-01-01 12:00:00.000000000 +1200
+++ squid-3.2.0.13/src/DiskIO/Mmapped/MmappedDiskIOModule.h	2011-10-14 14:42:56.000000000 +1300
@@ -0,0 +1,21 @@
+#ifndef SQUID_MMAPPEDDISKIOMODULE_H
+#define SQUID_MMAPPEDDISKIOMODULE_H
+
+#include "DiskIO/DiskIOModule.h"
+
+class MmappedDiskIOModule : public DiskIOModule
+{
+
+public:
+    static MmappedDiskIOModule &GetInstance();
+    MmappedDiskIOModule();
+    virtual void init();
+    virtual void shutdown();
+    virtual char const *type () const;
+    virtual DiskIOStrategy* createStrategy();
+
+private:
+    static MmappedDiskIOModule Instance;
+};
+
+#endif /* SQUID_MMAPPEDDISKIOMODULE_H */
diff -u -r -N squid-3.2.0.12/src/DiskIO/Mmapped/MmappedFile.cc squid-3.2.0.13/src/DiskIO/Mmapped/MmappedFile.cc
--- squid-3.2.0.12/src/DiskIO/Mmapped/MmappedFile.cc	1970-01-01 12:00:00.000000000 +1200
+++ squid-3.2.0.13/src/DiskIO/Mmapped/MmappedFile.cc	2011-10-14 14:42:56.000000000 +1300
@@ -0,0 +1,270 @@
+/*
+ * $Id$
+ *
+ * DEBUG: section 47    Store Directory Routines
+ */
+
+#include "config.h"
+#include "DiskIO/IORequestor.h"
+#include "DiskIO/Mmapped/MmappedFile.h"
+#include "DiskIO/ReadRequest.h"
+#include "DiskIO/WriteRequest.h"
+#include <sys/mman.h>
+
+CBDATA_CLASS_INIT(MmappedFile);
+
+// helper class to deal with mmap(2) offset alignment and other low-level specs
+class Mmapping
+{
+public:
+    Mmapping(int fd, size_t length, int prot, int flags, off_t offset);
+    ~Mmapping();
+
+    void *map(); ///< calls mmap(2); returns usable buffer or nil on failure
+    bool unmap(); ///< unmaps previously mapped buffer, if any
+
+private:
+    const int fd; ///< descriptor of the mmapped file
+    const size_t length; ///< user-requested data length, needed for munmap
+    const int prot; ///< mmap(2) "protection" flags
+    const int flags; ///< other mmap(2) flags
+    const off_t offset; ///< user-requested data offset
+
+    off_t delta; ///< mapped buffer increment to hit user offset
+    void *buf; ///< buffer returned by mmap, needed for munmap
+};
+
+
+void *
+MmappedFile::operator new(size_t sz)
+{
+    CBDATA_INIT_TYPE(MmappedFile);
+    MmappedFile *result = cbdataAlloc(MmappedFile);
+    /* Mark result as being owned - we want the refcounter to do the delete
+     * call */
+    return result;
+}
+
+void
+MmappedFile::operator delete(void *address)
+{
+    MmappedFile *t = static_cast<MmappedFile *>(address);
+    cbdataFree(t);
+}
+
+MmappedFile::MmappedFile(char const *aPath): fd(-1),
+        minOffset(0), maxOffset(-1), error_(false)
+{
+    assert(aPath);
+    path_ = xstrdup(aPath);
+    debugs(79,5, HERE << this << ' ' << path_);
+}
+
+MmappedFile::~MmappedFile()
+{
+    safe_free(path_);
+    doClose();
+}
+
+// XXX: almost a copy of BlockingFile::open
+void
+MmappedFile::open(int flags, mode_t mode, RefCount<IORequestor> callback)
+{
+    assert(fd < 0);
+
+    /* Simulate async calls */
+    fd = file_open(path_ , flags);
+    ioRequestor = callback;
+
+    if (fd < 0) {
+        debugs(79,3, HERE << "open error: " << xstrerror());
+        error_ = true;
+    } else {
+        store_open_disk_fd++;
+        debugs(79,3, HERE << "FD " << fd);
+
+        // setup mapping boundaries
+        struct stat sb;
+        if (fstat(fd, &sb) == 0)
+            maxOffset = sb.st_size; // we do not expect it to change
+    }
+
+    callback->ioCompletedNotification();
+}
+
+/**
+ * Alias for MmappedFile::open(...)
+ \copydoc MmappedFile::open(int flags, mode_t mode, RefCount<IORequestor> callback)
+ */
+void
+MmappedFile::create(int flags, mode_t mode, RefCount<IORequestor> callback)
+{
+    /* We use the same logic path for open */
+    open(flags, mode, callback);
+}
+
+void MmappedFile::doClose()
+{
+    if (fd >= 0) {
+        file_close(fd);
+        fd = -1;
+        store_open_disk_fd--;
+    }
+}
+
+void
+MmappedFile::close()
+{
+    debugs(79, 3, HERE << this << " closing for " << ioRequestor);
+    doClose();
+    assert(ioRequestor != NULL);
+    ioRequestor->closeCompleted();
+}
+
+bool
+MmappedFile::canRead() const
+{
+    return fd >= 0;
+}
+
+bool
+MmappedFile::canWrite() const
+{
+    return fd >= 0;
+}
+
+bool
+MmappedFile::error() const
+{
+    return error_;
+}
+
+void
+MmappedFile::read(ReadRequest *aRequest)
+{
+    debugs(79,3, HERE << "(FD " << fd << ", " << aRequest->len << ", " <<
+           aRequest->offset << ")");
+
+    assert(fd >= 0);
+    assert(ioRequestor != NULL);
+    assert(aRequest->len > 0); // TODO: work around mmap failures on zero-len?
+    assert(aRequest->offset >= 0);
+    assert(!error_); // TODO: propagate instead?
+
+    assert(minOffset < 0 || minOffset <= aRequest->offset);
+    assert(maxOffset < 0 || static_cast<uint64_t>(aRequest->offset + aRequest->len) <= static_cast<uint64_t>(maxOffset));
+
+    Mmapping mapping(fd, aRequest->len, PROT_READ, MAP_PRIVATE | MAP_NORESERVE,
+                     aRequest->offset);
+
+    bool done = false;
+    if (void *buf = mapping.map()) {
+        memcpy(aRequest->buf, buf, aRequest->len);
+        done = mapping.unmap();
+    }
+    error_ = !done;
+
+    const ssize_t rlen = error_ ? -1 : (ssize_t)aRequest->len;
+    const int errflag = error_ ? DISK_ERROR :DISK_OK;
+    ioRequestor->readCompleted(aRequest->buf, rlen, errflag, aRequest);
+}
+
+void
+MmappedFile::write(WriteRequest *aRequest)
+{
+    debugs(79,3, HERE << "(FD " << fd << ", " << aRequest->len << ", " <<
+           aRequest->offset << ")");
+
+    assert(fd >= 0);
+    assert(ioRequestor != NULL);
+    assert(aRequest->len > 0); // TODO: work around mmap failures on zero-len?
+    assert(aRequest->offset >= 0);
+    assert(!error_); // TODO: propagate instead?
+
+    assert(minOffset < 0 || minOffset <= aRequest->offset);
+    assert(maxOffset < 0 || static_cast<uint64_t>(aRequest->offset + aRequest->len) <= static_cast<uint64_t>(maxOffset));
+
+    const ssize_t written =
+        pwrite(fd, aRequest->buf, aRequest->len, aRequest->offset);
+    if (written < 0) {
+        debugs(79,1, HERE << "error: " << xstrerr(errno));
+        error_ = true;
+    } else if (static_cast<size_t>(written) != aRequest->len) {
+        debugs(79,1, HERE << "problem: " << written << " < " << aRequest->len);
+        error_ = true;
+    }
+
+    if (aRequest->free_func)
+        (aRequest->free_func)(const_cast<char*>(aRequest->buf)); // broken API?
+
+    if (!error_) {
+        debugs(79,5, HERE << "wrote " << aRequest->len << " to FD " << fd << " at " << aRequest->offset);
+    } else {
+        doClose();
+    }
+
+    const ssize_t rlen = error_ ? 0 : (ssize_t)aRequest->len;
+    const int errflag = error_ ? DISK_ERROR :DISK_OK;
+    ioRequestor->writeCompleted(errflag, rlen, aRequest);
+}
+
+/// we only support blocking I/O
+bool
+MmappedFile::ioInProgress() const
+{
+    return false;
+}
+
+Mmapping::Mmapping(int aFd, size_t aLength, int aProt, int aFlags, off_t anOffset):
+        fd(aFd), length(aLength), prot(aProt), flags(aFlags), offset(anOffset),
+        delta(-1), buf(NULL)
+{
+}
+
+Mmapping::~Mmapping()
+{
+    if (buf)
+        unmap();
+}
+
+void *
+Mmapping::map()
+{
+    // mmap(2) requires that offset is a multiple of the page size
+    static const int pageSize = getpagesize();
+    delta = offset % pageSize;
+
+    buf = mmap(NULL, length + delta, prot, flags, fd, offset - delta);
+
+    if (buf == MAP_FAILED) {
+        const int errNo = errno;
+        debugs(79,3, HERE << "error FD " << fd << "mmap(" << length << '+' <<
+               delta << ", " << offset << '-' << delta << "): " << xstrerr(errNo));
+        buf = NULL;
+        return NULL;
+    }
+
+    return static_cast<char*>(buf) + delta;
+}
+
+bool
+Mmapping::unmap()
+{
+    debugs(79,9, HERE << "FD " << fd <<
+           " munmap(" << buf << ", " << length << '+' << delta << ')');
+
+    if (!buf) // forgot or failed to map
+        return false;
+
+    const bool error = munmap(buf, length + delta) != 0;
+    if (error) {
+        const int errNo = errno;
+        debugs(79,3, HERE << "error FD " << fd <<
+               " munmap(" << buf << ", " << length << '+' << delta << "): " <<
+               "): " << xstrerr(errNo));
+    }
+    buf = NULL;
+    return !error;
+}
+
+// TODO: check MAP_NORESERVE, consider MAP_POPULATE and MAP_FIXED
diff -u -r -N squid-3.2.0.12/src/DiskIO/Mmapped/MmappedFile.h squid-3.2.0.13/src/DiskIO/Mmapped/MmappedFile.h
--- squid-3.2.0.12/src/DiskIO/Mmapped/MmappedFile.h	1970-01-01 12:00:00.000000000 +1200
+++ squid-3.2.0.13/src/DiskIO/Mmapped/MmappedFile.h	2011-10-14 14:42:56.000000000 +1300
@@ -0,0 +1,46 @@
+#ifndef SQUID_MMAPPEDFILE_H
+#define SQUID_MMAPPEDFILE_H
+
+#include "cbdata.h"
+#include "DiskIO/DiskFile.h"
+#include "DiskIO/IORequestor.h"
+
+class MmappedFile : public DiskFile
+{
+
+public:
+    void *operator new(size_t);
+    void operator delete(void *);
+    MmappedFile(char const *path);
+    ~MmappedFile();
+    virtual void open(int flags, mode_t mode, RefCount<IORequestor> callback);
+    virtual void create(int flags, mode_t mode, RefCount<IORequestor> callback);
+    virtual void read(ReadRequest *);
+    virtual void write(WriteRequest *);
+    virtual void close();
+    virtual bool error() const;
+    virtual int getFD() const { return fd;}
+
+    virtual bool canRead() const;
+    virtual bool canWrite() const;
+    virtual bool ioInProgress() const;
+
+private:
+    CBDATA_CLASS(MmappedFile);
+
+    char const *path_;
+    RefCount<IORequestor> ioRequestor;
+    //RefCount<ReadRequest> readRequest;
+    //RefCount<WriteRequest> writeRequest;
+    int fd;
+
+    // mmapped memory leads to SEGV and bus errors if it maps beyond file
+    int64_t minOffset; ///< enforced if not negative (to preserve file headers)
+    int64_t maxOffset; ///< enforced if not negative (to avoid crashes)
+
+    bool error_;
+
+    void doClose();
+};
+
+#endif /* SQUID_MMAPPEDFILE_H */
diff -u -r -N squid-3.2.0.12/src/DiskIO/Mmapped/MmappedIOStrategy.cc squid-3.2.0.13/src/DiskIO/Mmapped/MmappedIOStrategy.cc
--- squid-3.2.0.12/src/DiskIO/Mmapped/MmappedIOStrategy.cc	1970-01-01 12:00:00.000000000 +1200
+++ squid-3.2.0.13/src/DiskIO/Mmapped/MmappedIOStrategy.cc	2011-10-14 14:42:56.000000000 +1300
@@ -0,0 +1,39 @@
+
+/*
+ * $Id$
+ *
+ * DEBUG: section 47    Store Directory Routines
+ */
+
+#include "config.h"
+#include "MmappedFile.h"
+#include "MmappedIOStrategy.h"
+
+bool
+MmappedIOStrategy::shedLoad()
+{
+    return false;
+}
+
+int
+MmappedIOStrategy::load()
+{
+    /* Return 999 (99.9%) constant load */
+    return 999;
+}
+
+DiskFile::Pointer
+MmappedIOStrategy::newFile (char const *path)
+{
+    return new MmappedFile (path);
+}
+
+void
+MmappedIOStrategy::unlinkFile(char const *path)
+{
+#if USE_UNLINKD
+    unlinkdUnlink(path);
+#else
+    ::unlink(path);
+#endif
+}
diff -u -r -N squid-3.2.0.12/src/DiskIO/Mmapped/MmappedIOStrategy.h squid-3.2.0.13/src/DiskIO/Mmapped/MmappedIOStrategy.h
--- squid-3.2.0.12/src/DiskIO/Mmapped/MmappedIOStrategy.h	1970-01-01 12:00:00.000000000 +1200
+++ squid-3.2.0.13/src/DiskIO/Mmapped/MmappedIOStrategy.h	2011-10-14 14:42:56.000000000 +1300
@@ -0,0 +1,15 @@
+#ifndef SQUID_MMAPPEDIOSTRATEGY_H
+#define SQUID_MMAPPEDIOSTRATEGY_H
+#include "DiskIO/DiskIOStrategy.h"
+
+class MmappedIOStrategy : public DiskIOStrategy
+{
+
+public:
+    virtual bool shedLoad();
+    virtual int load();
+    virtual RefCount<DiskFile> newFile(char const *path);
+    virtual void unlinkFile (char const *);
+};
+
+#endif /* SQUID_MMAPPEDIOSTRATEGY_H */
diff -u -r -N squid-3.2.0.12/src/dns.cc squid-3.2.0.13/src/dns.cc
--- squid-3.2.0.12/src/dns.cc	2011-09-16 23:37:30.000000000 +1200
+++ squid-3.2.0.13/src/dns.cc	2011-10-14 14:42:56.000000000 +1300
@@ -74,7 +74,7 @@
     if (dnsservers == NULL)
         dnsservers = new helper("dnsserver");
 
-    dnsservers->childs = Config.dnsChildren;
+    dnsservers->childs.updateLimits(Config.dnsChildren);
 
     dnsservers->ipc_type = IPC_STREAM;
 
diff -u -r -N squid-3.2.0.12/src/dns_internal.cc squid-3.2.0.13/src/dns_internal.cc
--- squid-3.2.0.12/src/dns_internal.cc	2011-09-16 23:37:30.000000000 +1200
+++ squid-3.2.0.13/src/dns_internal.cc	2011-10-14 14:42:56.000000000 +1300
@@ -1217,25 +1217,35 @@
 
         debugs(78, 6, HERE << "Merging DNS results " << q->name << " AAAA has " << q->initial_AAAA.count << " RR, A has " << n << " RR");
 
+        if (Config.dns.v4_first) {
+            memcpy( tmp, message->answer, (sizeof(rfc1035_rr)*n) );
+            tmp += n;
+            /* free the RR object without freeing its child strings (they are now taken by the copy above) */
+            safe_free(message->answer);
+        }
+
         memcpy(tmp, q->initial_AAAA.answers, (sizeof(rfc1035_rr)*(q->initial_AAAA.count)) );
         tmp += q->initial_AAAA.count;
         /* free the RR object without freeing its child strings (they are now taken by the copy above) */
         safe_free(q->initial_AAAA.answers);
 
-        memcpy( tmp, message->answer, (sizeof(rfc1035_rr)*n) );
-        /* free the RR object without freeing its child strings (they are now taken by the copy above) */
-        safe_free(message->answer);
+        if (!Config.dns.v4_first) {
+            memcpy( tmp, message->answer, (sizeof(rfc1035_rr)*n) );
+            /* free the RR object without freeing its child strings (they are now taken by the copy above) */
+            safe_free(message->answer);
+        }
 
-        message->answer = result;
-        message->ancount += q->initial_AAAA.count;
         n += q->initial_AAAA.count;
-        q->initial_AAAA.count=0;
+        q->initial_AAAA.count = 0;
+        message->answer = result;
+        message->ancount = n;
     } else if (q->initial_AAAA.count > 0 && n <= 0) {
         /* initial of dual queries was the only result set. */
         debugs(78, 6, HERE << "Merging DNS results " << q->name << " AAAA has " << q->initial_AAAA.count << " RR, A has " << n << " RR");
         rfc1035RRDestroy(&(message->answer), n);
         message->answer = q->initial_AAAA.answers;
         n = q->initial_AAAA.count;
+        message->ancount = n;
     }
     /* else initial results were empty. just use the final set as authoritative */
 
diff -u -r -N squid-3.2.0.12/src/enums.h squid-3.2.0.13/src/enums.h
--- squid-3.2.0.12/src/enums.h	2011-09-16 23:37:30.000000000 +1200
+++ squid-3.2.0.13/src/enums.h	2011-10-14 14:42:56.000000000 +1300
@@ -218,7 +218,6 @@
     MEM_DLINK_NODE,
     MEM_DREAD_CTRL,
     MEM_DWRITE_Q,
-    MEM_HTTP_HDR_CC,
     MEM_HTTP_HDR_CONTENT_RANGE,
     MEM_MD5_DIGEST,
     MEM_NETDBENTRY,
diff -u -r -N squid-3.2.0.12/src/errorpage.cc squid-3.2.0.13/src/errorpage.cc
--- squid-3.2.0.12/src/errorpage.cc	2011-09-16 23:37:30.000000000 +1200
+++ squid-3.2.0.13/src/errorpage.cc	2011-10-14 14:42:56.000000000 +1300
@@ -39,7 +39,9 @@
 #include "auth/UserRequest.h"
 #endif
 #include "SquidTime.h"
+#if USE_SSL
 #include "ssl/ErrorDetailManager.h"
+#endif
 #include "Store.h"
 #include "html_quote.h"
 #include "HttpReply.h"
@@ -1136,7 +1138,7 @@
     const char *name = errorPageName(page_id);
     /* no LMT for error pages; error pages expire immediately */
 
-    if (name[0] == '3' || (name[0] != '4' && name[0] != '5' && strchr(name, ':'))) {
+    if (name[0] == '3' || (name[0] != '2' && name[0] != '4' && name[0] != '5' && strchr(name, ':'))) {
         /* Redirection */
         http_status status = HTTP_MOVED_TEMPORARILY;
         // Use configured 3xx reply status if set.
diff -u -r -N squid-3.2.0.12/src/external_acl.cc squid-3.2.0.13/src/external_acl.cc
--- squid-3.2.0.12/src/external_acl.cc	2011-09-16 23:37:30.000000000 +1200
+++ squid-3.2.0.13/src/external_acl.cc	2011-10-14 14:42:56.000000000 +1300
@@ -1508,7 +1508,7 @@
 
         p->theHelper->cmdline = p->cmdline;
 
-        p->theHelper->childs = p->children;
+        p->theHelper->childs.updateLimits(p->children);
 
         p->theHelper->ipc_type = IPC_TCP_SOCKET;
 
diff -u -r -N squid-3.2.0.12/src/forward.cc squid-3.2.0.13/src/forward.cc
--- squid-3.2.0.12/src/forward.cc	2011-09-16 23:37:30.000000000 +1200
+++ squid-3.2.0.13/src/forward.cc	2011-10-14 14:42:56.000000000 +1300
@@ -120,7 +120,7 @@
     // Bug 3243: CVE 2009-0801
     // Bypass of browser same-origin access control in intercepted communication
     // To resolve this we must force DIRECT and only to the original client destination.
-    if (Config.onoff.client_dst_passthru && request &&
+    if (Config.onoff.client_dst_passthru && request && !request->flags.redirected &&
             (request->flags.intercepted || request->flags.spoof_client_ip)) {
         Comm::ConnectionPointer p = new Comm::Connection();
         p->remote = clientConn->local;
@@ -146,6 +146,11 @@
 
     flags.forward_completed = 1;
 
+    if (EBIT_TEST(entry->flags, ENTRY_ABORTED)) {
+        debugs(17, 3, HERE << "entry aborted");
+        return ;
+    }
+
 #if URL_CHECKSUM_DEBUG
 
     entry->mem_obj->checkUrlChecksum();
@@ -361,7 +366,6 @@
 void
 FwdState::complete()
 {
-    assert(entry->store_status == STORE_PENDING);
     debugs(17, 3, HERE << entry->url() << "\n\tstatus " << entry->getReply()->sline.status  );
 #if URL_CHECKSUM_DEBUG
 
@@ -1017,6 +1021,12 @@
 {
     StoreEntry *e = entry;
     http_status s;
+
+    if (EBIT_TEST(e->flags, ENTRY_ABORTED)) {
+        debugs(17, 3, HERE << "entry aborted");
+        return 0;
+    }
+
     assert(e->store_status == STORE_PENDING);
     assert(e->mem_obj);
 #if URL_CHECKSUM_DEBUG
diff -u -r -N squid-3.2.0.12/src/fs/coss/CossSwapDir.h squid-3.2.0.13/src/fs/coss/CossSwapDir.h
--- squid-3.2.0.12/src/fs/coss/CossSwapDir.h	2011-09-16 23:37:30.000000000 +1200
+++ squid-3.2.0.13/src/fs/coss/CossSwapDir.h	2011-10-14 14:42:56.000000000 +1300
@@ -37,7 +37,7 @@
     virtual StoreSearch *search(String const url, HttpRequest *);
     virtual void unlink (StoreEntry &);
     virtual void statfs (StoreEntry &)const;
-    virtual int canStore(StoreEntry const &)const;
+    virtual bool canStore(const StoreEntry &e, int64_t diskSpaceNeeded, int &load) const;
     virtual int callback();
     virtual void sync();
     virtual StoreIOState::Pointer createStoreIO(StoreEntry &, StoreIOState::STFNCB *, StoreIOState::STIOCB *, void *);
@@ -48,7 +48,10 @@
     virtual void writeCleanDone();
     virtual void logEntry(const StoreEntry & e, int op) const;
     virtual void parse (int index, char *path);
-    virtual void reconfigure (int, char *);
+    virtual void reconfigure();
+    virtual void swappedOut(const StoreEntry &e);
+    virtual uint64_t currentSize() const { return cur_size; }
+    virtual uint64_t currentCount() const { return n_disk_objects; }
     /* internals */
     virtual off_t storeCossFilenoToDiskOffset(sfileno);
     virtual sfileno storeCossDiskOffsetToFileno(off_t);
@@ -76,6 +79,16 @@
     CossMemBuf *createMemBuf(off_t start, sfileno curfn, int *collision);
     sfileno allocate(const StoreEntry * e, int which);
     void startMembuf();
+    StoreEntry *addDiskRestore(const cache_key *const key,
+                               int file_number,
+                               uint64_t swap_file_sz,
+                               time_t expires,
+                               time_t timestamp,
+                               time_t lastref,
+                               time_t lastmod,
+                               uint32_t refcount,
+                               uint16_t flags,
+                               int clean);
 
 private:
     void changeIO(DiskIOModule *module);
@@ -88,6 +101,8 @@
     const char *ioModule;
     mutable ConfigOptionVector *currentIOOptions;
     const char *stripe_path;
+    uint64_t cur_size; ///< currently used space in the storage area
+    uint64_t n_disk_objects; ///< total number of objects stored
 };
 
 /// \ingroup COSS
diff -u -r -N squid-3.2.0.12/src/fs/coss/store_coss.h squid-3.2.0.13/src/fs/coss/store_coss.h
--- squid-3.2.0.12/src/fs/coss/store_coss.h	2011-09-16 23:37:30.000000000 +1200
+++ squid-3.2.0.13/src/fs/coss/store_coss.h	2011-10-14 14:42:56.000000000 +1300
@@ -79,7 +79,7 @@
     off_t st_size;
     void read_(char *buf, size_t size, off_t offset, STRCB * callback, void *callback_data);
     void write(char const *buf, size_t size, off_t offset, FREE * free_func);
-    void close();
+    virtual void close(int);
     void doCallback(int errflag);
     void lockMemBuf();
 
diff -u -r -N squid-3.2.0.12/src/fs/coss/store_dir_coss.cc squid-3.2.0.13/src/fs/coss/store_dir_coss.cc
--- squid-3.2.0.12/src/fs/coss/store_dir_coss.cc	2011-09-16 23:37:30.000000000 +1200
+++ squid-3.2.0.13/src/fs/coss/store_dir_coss.cc	2011-10-14 14:42:56.000000000 +1300
@@ -49,7 +49,7 @@
 #include "StoreFScoss.h"
 #include "Parsing.h"
 #include "swap_log_op.h"
-//#include "SquidMath.h"
+#include "SquidMath.h"
 
 #define STORE_META_BUFSZ 4096
 
@@ -74,16 +74,6 @@
 
 static char *storeCossDirSwapLogFile(SwapDir *, const char *);
 static EVH storeCossRebuildFromSwapLog;
-static StoreEntry *storeCossAddDiskRestore(CossSwapDir * SD, const cache_key * key,
-        int file_number,
-        uint64_t swap_file_sz,
-        time_t expires,
-        time_t timestamp,
-        time_t lastref,
-        time_t lastmod,
-        uint32_t refcount,
-        uint16_t flags,
-        int clean);
 static void storeCossDirRebuild(CossSwapDir * sd);
 static void storeCossDirCloseTmpSwapLog(CossSwapDir * sd);
 static FILE *storeCossDirOpenTmpSwapLog(CossSwapDir *, int *, int *);
@@ -358,7 +348,7 @@
     CossIndexNode *coss_node = (CossIndexNode *)e->repl.data;
     e->repl.data = NULL;
     dlinkDelete(&coss_node->node, &sd->cossindex);
-    coss_index_pool->free(coss_node);
+    coss_index_pool->freeOne(coss_node);
     sd->count -= 1;
 }
 
@@ -427,9 +417,8 @@
                 /*
                  * Make sure we don't unlink the file, it might be
                  * in use by a subsequent entry.  Also note that
-                 * we don't have to subtract from store_swap_size
-                 * because adding to store_swap_size happens in
-                 * the cleanup procedure.
+                 * we don't have to subtract from cur_size because
+                 * adding to cur_size happens in the cleanup procedure.
                  */
                 e->expireNow();
                 e->releaseRequest();
@@ -481,19 +470,18 @@
             continue;
         }
 
-        /* update store_swap_size */
         rb->counts.objcount++;
 
-        e = storeCossAddDiskRestore(rb->sd, s.key,
-                                    s.swap_filen,
-                                    s.swap_file_sz,
-                                    s.expires,
-                                    s.timestamp,
-                                    s.lastref,
-                                    s.lastmod,
-                                    s.refcount,
-                                    s.flags,
-                                    (int) rb->flags.clean);
+        e = rb->sd->addDiskRestore(s.key,
+                                   s.swap_filen,
+                                   s.swap_file_sz,
+                                   s.expires,
+                                   s.timestamp,
+                                   s.lastref,
+                                   s.lastmod,
+                                   s.refcount,
+                                   s.flags,
+                                   (int) rb->flags.clean);
 
         storeDirSwapLog(e, SWAP_LOG_ADD);
     }
@@ -503,17 +491,17 @@
 
 /* Add a new object to the cache with empty memory copy and pointer to disk
  * use to rebuild store from disk. */
-static StoreEntry *
-storeCossAddDiskRestore(CossSwapDir * SD, const cache_key * key,
-                        int file_number,
-                        uint64_t swap_file_sz,
-                        time_t expires,
-                        time_t timestamp,
-                        time_t lastref,
-                        time_t lastmod,
-                        uint32_t refcount,
-                        uint16_t flags,
-                        int clean)
+StoreEntry *
+CossSwapDir::addDiskRestore(const cache_key *const key,
+                            int file_number,
+                            uint64_t swap_file_sz,
+                            time_t expires,
+                            time_t timestamp,
+                            time_t lastref,
+                            time_t lastmod,
+                            uint32_t refcount,
+                            uint16_t flags,
+                            int clean)
 {
     StoreEntry *e = NULL;
     debugs(47, 5, "storeCossAddDiskRestore: " << storeKeyText(key)  <<
@@ -524,7 +512,7 @@
      * already in use! */
     e = new StoreEntry();
     e->store_status = STORE_OK;
-    e->swap_dirn = SD->index;
+    e->swap_dirn = index;
     e->setMemStatus(NOT_IN_MEMORY);
     e->swap_status = SWAPOUT_DONE;
     e->swap_filen = file_number;
@@ -541,8 +529,10 @@
     EBIT_CLR(e->flags, KEY_PRIVATE);
     e->ping_status = PING_NONE;
     EBIT_CLR(e->flags, ENTRY_VALIDATED);
+    cur_size += fs.blksize * sizeInBlocks(e->swap_file_sz);
+    ++n_disk_objects;
     e->hashInsert(key);	/* do it after we clear KEY_PRIVATE */
-    storeCossAdd(SD, e);
+    storeCossAdd(this, e);
     assert(e->swap_filen >= 0);
     return e;
 }
@@ -925,13 +915,12 @@
     swap = open(stripePath(), O_WRONLY | O_CREAT | O_TRUNC | O_BINARY, 0600);
 
     /* TODO just set the file size */
-    /* swap size is in K */
-    char *block[1024];
+    char block[1024];
+    Must(maxSize() % sizeof(block) == 0);
+    memset(block, '\0', sizeof(block));
 
-    memset(&block, '\0', 1024);
-
-    for (off_t offset = 0; offset < max_size; ++offset) {
-        if (write (swap, block, 1024) < 1024) {
+    for (uint64_t offset = 0; offset < maxSize(); offset += sizeof(block)) {
+        if (write (swap, block, sizeof(block)) != sizeof(block)) {
             debugs (47, 0, "Failed to create COSS swap space in " << path);
         }
     }
@@ -959,26 +948,14 @@
     safe_free(stripe_path);
 }
 
-/*
- * storeCossDirCheckObj
- *
- * This routine is called by storeDirSelectSwapDir to see if the given
- * object is able to be stored on this filesystem. COSS filesystems will
- * not store everything. We don't check for maxobjsize here since its
- * done by the upper layers.
- */
-int
-CossSwapDir::canStore(StoreEntry const &e)const
+bool
+CossSwapDir::canStore(const StoreEntry &e, int64_t diskSpaceNeeded, int &load) const
 {
+    if (!SwapDir::canStore(e, diskSpaceNeeded, load))
+        return false;
 
-    /* Check if the object is a special object, we can't cache these */
-
-    if (EBIT_TEST(e.flags, ENTRY_SPECIAL))
-        return -1;
-
-    /* Otherwise, we're ok */
-    /* Return load, cs->aq.aq_numpending out of MAX_ASYNCOP */
-    return io->load();
+    load = io->load();
+    return true;
 }
 
 /*
@@ -996,10 +973,10 @@
 CossSwapDir::statfs(StoreEntry & sentry) const
 {
     storeAppendPrintf(&sentry, "\n");
-    storeAppendPrintf(&sentry, "Maximum Size: %lu KB\n", max_size);
-    storeAppendPrintf(&sentry, "Current Size: %lu KB\n", cur_size);
+    storeAppendPrintf(&sentry, "Maximum Size: %"PRIu64" KB\n", maxSize() >> 10);
+    storeAppendPrintf(&sentry, "Current Size: %.2f KB\n", currentSize() / 1024.0);
     storeAppendPrintf(&sentry, "Percent Used: %0.2f%%\n",
-                      (100.0 * (double)cur_size / (double)max_size) );
+                      Math::doublePercent(currentSize(), maxSize()) );
     storeAppendPrintf(&sentry, "Number of object collisions: %d\n", (int) numcollisions);
 #if 0
     /* is this applicable? I Hope not .. */
@@ -1023,21 +1000,15 @@
 void
 CossSwapDir::parse(int anIndex, char *aPath)
 {
-    unsigned int i;
-    unsigned int size;
-    off_t max_offset;
-
-    i = GetInteger();
-    size = i << 10;		/* Mbytes to Kbytes */
-
-    if (size <= 0)
+    const int i = GetInteger();
+    if (i <= 0)
         fatal("storeCossDirParse: invalid size value");
 
     index = anIndex;
 
     path = xstrdup(aPath);
 
-    max_size = size;
+    max_size = static_cast<uint64_t>(i) << 20; // MBytes to Bytes
 
     parseOptions(0);
 
@@ -1052,38 +1023,31 @@
         fatalf("COSS max-size option must be less than COSS_MEMBUF_SZ (%d)\n",
                COSS_MEMBUF_SZ);
 
-    /*
-     * check that we won't overflow sfileno later.  0xFFFFFF is the
-     * largest possible sfileno, assuming sfileno is a 25-bit
-     * signed integer, as defined in structs.h.
-     */
-    max_offset = (off_t) 0xFFFFFF << blksz_bits;
+    // check that we won't overflow sfileno later.
+    const uint64_t max_offset = (uint64_t)SwapFilenMax << blksz_bits;
 
-    if ((off_t)max_size > (max_offset>>10)) {
+    if (maxSize() > max_offset) {
         debugs(47, 0, "COSS block-size = " << (1<<blksz_bits) << " bytes");
         debugs(47,0, "COSS largest file offset = " << (max_offset >> 10) << " KB");
-        debugs(47, 0, "COSS cache_dir size = " << max_size << " KB");
+        debugs(47, 0, "COSS cache_dir size = " << (maxSize() >> 10) << " KB");
         fatal("COSS cache_dir size exceeds largest offset\n");
     }
 }
 
 
 void
-CossSwapDir::reconfigure(int index, char *path)
+CossSwapDir::reconfigure()
 {
-    unsigned int i;
-    unsigned int size;
-
-    i = GetInteger();
-    size = i << 10;		/* Mbytes to Kbytes */
-
-    if (size <= 0)
+    const int i = GetInteger();
+    if (i <= 0)
         fatal("storeCossDirParse: invalid size value");
 
-    if (size == (size_t)max_size)
-        debugs(3, 1, "Cache COSS dir '" << path << "' size remains unchanged at " << size << " KB");
+    const uint64_t size = static_cast<uint64_t>(i) << 20; // MBytes to Bytes
+
+    if (size == maxSize())
+        debugs(3, 1, "Cache COSS dir '" << path << "' size remains unchanged at " << i << " MB");
     else {
-        debugs(3, 1, "Cache COSS dir '" << path << "' size changed to " << size << " KB");
+        debugs(3, 1, "Cache COSS dir '" << path << "' size changed to " << i << " MB");
         max_size = size;
     }
 
@@ -1093,13 +1057,20 @@
 }
 
 void
+CossSwapDir::swappedOut(const StoreEntry &e)
+{
+    cur_size += fs.blksize * sizeInBlocks(e.swap_file_sz);
+    ++n_disk_objects;
+}
+
+void
 CossSwapDir::dump(StoreEntry &entry)const
 {
-    storeAppendPrintf(&entry, " %lu", (max_size >> 10));
+    storeAppendPrintf(&entry, " %"PRIu64, maxSize() >> 20);
     dumpOptions(&entry);
 }
 
-CossSwapDir::CossSwapDir() : SwapDir ("coss"), swaplog_fd(-1), count(0), current_membuf (NULL), current_offset(0), numcollisions(0),  blksz_bits(0), io (NULL), ioModule(NULL), currentIOOptions(new ConfigOptionVector()), stripe_path(NULL)
+CossSwapDir::CossSwapDir() : SwapDir ("coss"), swaplog_fd(-1), count(0), current_membuf (NULL), current_offset(0), numcollisions(0),  blksz_bits(0), io (NULL), ioModule(NULL), currentIOOptions(new ConfigOptionVector()), stripe_path(NULL), cur_size(0), n_disk_objects(0)
 {
     membufs.head = NULL;
     membufs.tail = NULL;
diff -u -r -N squid-3.2.0.12/src/fs/coss/store_io_coss.cc squid-3.2.0.13/src/fs/coss/store_io_coss.cc
--- squid-3.2.0.12/src/fs/coss/store_io_coss.cc	2011-09-16 23:37:30.000000000 +1200
+++ squid-3.2.0.13/src/fs/coss/store_io_coss.cc	2011-10-14 14:42:56.000000000 +1300
@@ -83,8 +83,7 @@
         allocsize = e->objectLen() + e->mem_obj->swap_hdr_sz;
 
     /* Check if we have overflowed the disk .. */
-    /* max_size is int, so cast to (off_t) *before* bit-shifting */
-    if ((current_offset + allocsize) > ((off_t)max_size << 10)) {
+    if (current_offset + allocsize > static_cast<int64_t>(maxSize())) {
         /*
          * tried to allocate past the end of the disk, so wrap
          * back to the beginning
@@ -134,6 +133,10 @@
 CossSwapDir::unlink(StoreEntry & e)
 {
     debugs(79, 3, "storeCossUnlink: offset " << e.swap_filen);
+    if (e.swap_status == SWAPOUT_DONE && EBIT_TEST(e.flags, ENTRY_VALIDATED)) {
+        cur_size -= fs.blksize * sizeInBlocks(e.swap_file_sz);
+        --n_disk_objects;
+    }
     StoreFScoss::GetInstance().stats.unlink.ops++;
     StoreFScoss::GetInstance().stats.unlink.success++;
     storeCossRemove(this, &e);
@@ -275,8 +278,9 @@
     return sio;
 }
 
+/// COSS does not distinguish different closure types
 void
-CossState::close()
+CossState::close(int)
 {
     debugs(79, 3, "storeCossClose: offset " << swap_filen);
 
diff -u -r -N squid-3.2.0.12/src/fs/Makefile.am squid-3.2.0.13/src/fs/Makefile.am
--- squid-3.2.0.12/src/fs/Makefile.am	2011-09-16 23:37:30.000000000 +1200
+++ squid-3.2.0.13/src/fs/Makefile.am	2011-10-14 14:42:56.000000000 +1300
@@ -1,6 +1,6 @@
 include $(top_srcdir)/src/Common.am
 
-EXTRA_LTLIBRARIES = libaufs.la libdiskd.la libcoss.la libufs.la
+EXTRA_LTLIBRARIES = libaufs.la libdiskd.la libcoss.la libufs.la librock.la
 noinst_LTLIBRARIES =  $(STORE_LIBS_TO_BUILD) libfs.la
 
 # aufs is a "fake" legacy store
@@ -28,6 +28,19 @@
 	ufs/ufscommon.cc \
 	ufs/ufscommon.h 
 
+librock_la_SOURCES = \
+	rock/RockDbCell.h \
+	rock/RockIoState.cc \
+	rock/RockIoState.h \
+	rock/RockIoRequests.cc \
+	rock/RockIoRequests.h \
+	rock/RockRebuild.cc \
+	rock/RockRebuild.h \
+	rock/RockStoreFileSystem.cc \
+	rock/RockStoreFileSystem.h \
+	rock/RockSwapDir.cc \
+	rock/RockSwapDir.h
+
 libfs_la_SOURCES = Module.cc Module.h
 libfs_la_LIBADD =  $(STORE_LIBS_TO_BUILD)
 libfs_la_DEPENDENCIES = $(STORE_LIBS_TO_BUILD)
@@ -44,13 +57,15 @@
 coss/clean: clean
 ufs/all: libufs.la
 ufs/clean: clean
+rock/all: librock.la
+rock/clean: clean
 
 
 TESTS += testHeaders
 
 ## Special Universal .h dependency test script
 ## aborts if error encountered
-testHeaders: $(srcdir)/ufs/*.h $(srcdir)/coss/*.h
+testHeaders: $(srcdir)/ufs/*.h $(srcdir)/coss/*.h $(srcdir)/rock/*.h
 	$(SHELL) $(top_srcdir)/test-suite/testheaders.sh "$(CXXCOMPILE)" $^ || exit 1
 ## diskd/ has no .h files
 ## aufs/ has no .h files
diff -u -r -N squid-3.2.0.12/src/fs/Makefile.in squid-3.2.0.13/src/fs/Makefile.in
--- squid-3.2.0.12/src/fs/Makefile.in	2011-09-16 23:38:19.000000000 +1200
+++ squid-3.2.0.13/src/fs/Makefile.in	2011-10-14 14:48:07.000000000 +1300
@@ -68,6 +68,10 @@
 am__DEPENDENCIES_1 =
 am_libfs_la_OBJECTS = Module.lo
 libfs_la_OBJECTS = $(am_libfs_la_OBJECTS)
+librock_la_LIBADD =
+am_librock_la_OBJECTS = RockIoState.lo RockIoRequests.lo \
+	RockRebuild.lo RockStoreFileSystem.lo RockSwapDir.lo
+librock_la_OBJECTS = $(am_librock_la_OBJECTS)
 libufs_la_LIBADD =
 am_libufs_la_OBJECTS = StoreFSufs.lo store_dir_ufs.lo store_io_ufs.lo \
 	ufscommon.lo
@@ -96,10 +100,10 @@
 	$(LDFLAGS) -o $@
 SOURCES = $(libaufs_la_SOURCES) $(libcoss_la_SOURCES) \
 	$(libdiskd_la_SOURCES) $(libfs_la_SOURCES) \
-	$(libufs_la_SOURCES)
+	$(librock_la_SOURCES) $(libufs_la_SOURCES)
 DIST_SOURCES = $(libaufs_la_SOURCES) $(libcoss_la_SOURCES) \
 	$(libdiskd_la_SOURCES) $(libfs_la_SOURCES) \
-	$(libufs_la_SOURCES)
+	$(librock_la_SOURCES) $(libufs_la_SOURCES)
 ETAGS = etags
 CTAGS = ctags
 am__tty_colors = \
@@ -325,7 +329,7 @@
 @ENABLE_XPROF_STATS_TRUE@LIBPROFILER = $(top_builddir)/lib/profiler/libprofiler.la
 COMPAT_LIB = -L$(top_builddir)/compat -lcompat-squid $(LIBPROFILER)
 subst_perlshell = sed -e 's,[@]PERL[@],$(PERL),g' <$(srcdir)/$@.pl.in >$@ || ($(RM) -f $@ ; exit 1)
-EXTRA_LTLIBRARIES = libaufs.la libdiskd.la libcoss.la libufs.la
+EXTRA_LTLIBRARIES = libaufs.la libdiskd.la libcoss.la libufs.la librock.la
 noinst_LTLIBRARIES = $(STORE_LIBS_TO_BUILD) libfs.la
 
 # aufs is a "fake" legacy store
@@ -354,6 +358,19 @@
 	ufs/ufscommon.cc \
 	ufs/ufscommon.h 
 
+librock_la_SOURCES = \
+	rock/RockDbCell.h \
+	rock/RockIoState.cc \
+	rock/RockIoState.h \
+	rock/RockIoRequests.cc \
+	rock/RockIoRequests.h \
+	rock/RockRebuild.cc \
+	rock/RockRebuild.h \
+	rock/RockStoreFileSystem.cc \
+	rock/RockStoreFileSystem.h \
+	rock/RockSwapDir.cc \
+	rock/RockSwapDir.h
+
 libfs_la_SOURCES = Module.cc Module.h
 libfs_la_LIBADD = $(STORE_LIBS_TO_BUILD)
 libfs_la_DEPENDENCIES = $(STORE_LIBS_TO_BUILD)
@@ -411,6 +428,8 @@
 	$(CXXLINK)  $(libdiskd_la_OBJECTS) $(libdiskd_la_LIBADD) $(LIBS)
 libfs.la: $(libfs_la_OBJECTS) $(libfs_la_DEPENDENCIES) 
 	$(CXXLINK)  $(libfs_la_OBJECTS) $(libfs_la_LIBADD) $(LIBS)
+librock.la: $(librock_la_OBJECTS) $(librock_la_DEPENDENCIES) 
+	$(CXXLINK)  $(librock_la_OBJECTS) $(librock_la_LIBADD) $(LIBS)
 libufs.la: $(libufs_la_OBJECTS) $(libufs_la_DEPENDENCIES) 
 	$(CXXLINK)  $(libufs_la_OBJECTS) $(libufs_la_LIBADD) $(LIBS)
 
@@ -430,6 +449,11 @@
 	-rm -f *.tab.c
 
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/Module.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/RockIoRequests.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/RockIoState.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/RockRebuild.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/RockStoreFileSystem.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/RockSwapDir.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/StoreFSaufs.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/StoreFScoss.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/StoreFSdiskd.Plo@am__quote@
@@ -496,6 +520,41 @@
 @AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
 @am__fastdepCXX_FALSE@	$(LIBTOOL)  --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o StoreFSdiskd.lo `test -f 'diskd/StoreFSdiskd.cc' || echo '$(srcdir)/'`diskd/StoreFSdiskd.cc
 
+RockIoState.lo: rock/RockIoState.cc
+@am__fastdepCXX_TRUE@	$(LIBTOOL)  --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT RockIoState.lo -MD -MP -MF $(DEPDIR)/RockIoState.Tpo -c -o RockIoState.lo `test -f 'rock/RockIoState.cc' || echo '$(srcdir)/'`rock/RockIoState.cc
+@am__fastdepCXX_TRUE@	$(am__mv) $(DEPDIR)/RockIoState.Tpo $(DEPDIR)/RockIoState.Plo
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@	source='rock/RockIoState.cc' object='RockIoState.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCXX_FALSE@	$(LIBTOOL)  --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o RockIoState.lo `test -f 'rock/RockIoState.cc' || echo '$(srcdir)/'`rock/RockIoState.cc
+
+RockIoRequests.lo: rock/RockIoRequests.cc
+@am__fastdepCXX_TRUE@	$(LIBTOOL)  --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT RockIoRequests.lo -MD -MP -MF $(DEPDIR)/RockIoRequests.Tpo -c -o RockIoRequests.lo `test -f 'rock/RockIoRequests.cc' || echo '$(srcdir)/'`rock/RockIoRequests.cc
+@am__fastdepCXX_TRUE@	$(am__mv) $(DEPDIR)/RockIoRequests.Tpo $(DEPDIR)/RockIoRequests.Plo
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@	source='rock/RockIoRequests.cc' object='RockIoRequests.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCXX_FALSE@	$(LIBTOOL)  --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o RockIoRequests.lo `test -f 'rock/RockIoRequests.cc' || echo '$(srcdir)/'`rock/RockIoRequests.cc
+
+RockRebuild.lo: rock/RockRebuild.cc
+@am__fastdepCXX_TRUE@	$(LIBTOOL)  --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT RockRebuild.lo -MD -MP -MF $(DEPDIR)/RockRebuild.Tpo -c -o RockRebuild.lo `test -f 'rock/RockRebuild.cc' || echo '$(srcdir)/'`rock/RockRebuild.cc
+@am__fastdepCXX_TRUE@	$(am__mv) $(DEPDIR)/RockRebuild.Tpo $(DEPDIR)/RockRebuild.Plo
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@	source='rock/RockRebuild.cc' object='RockRebuild.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCXX_FALSE@	$(LIBTOOL)  --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o RockRebuild.lo `test -f 'rock/RockRebuild.cc' || echo '$(srcdir)/'`rock/RockRebuild.cc
+
+RockStoreFileSystem.lo: rock/RockStoreFileSystem.cc
+@am__fastdepCXX_TRUE@	$(LIBTOOL)  --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT RockStoreFileSystem.lo -MD -MP -MF $(DEPDIR)/RockStoreFileSystem.Tpo -c -o RockStoreFileSystem.lo `test -f 'rock/RockStoreFileSystem.cc' || echo '$(srcdir)/'`rock/RockStoreFileSystem.cc
+@am__fastdepCXX_TRUE@	$(am__mv) $(DEPDIR)/RockStoreFileSystem.Tpo $(DEPDIR)/RockStoreFileSystem.Plo
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@	source='rock/RockStoreFileSystem.cc' object='RockStoreFileSystem.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCXX_FALSE@	$(LIBTOOL)  --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o RockStoreFileSystem.lo `test -f 'rock/RockStoreFileSystem.cc' || echo '$(srcdir)/'`rock/RockStoreFileSystem.cc
+
+RockSwapDir.lo: rock/RockSwapDir.cc
+@am__fastdepCXX_TRUE@	$(LIBTOOL)  --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT RockSwapDir.lo -MD -MP -MF $(DEPDIR)/RockSwapDir.Tpo -c -o RockSwapDir.lo `test -f 'rock/RockSwapDir.cc' || echo '$(srcdir)/'`rock/RockSwapDir.cc
+@am__fastdepCXX_TRUE@	$(am__mv) $(DEPDIR)/RockSwapDir.Tpo $(DEPDIR)/RockSwapDir.Plo
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@	source='rock/RockSwapDir.cc' object='RockSwapDir.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCXX_FALSE@	$(LIBTOOL)  --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o RockSwapDir.lo `test -f 'rock/RockSwapDir.cc' || echo '$(srcdir)/'`rock/RockSwapDir.cc
+
 StoreFSufs.lo: ufs/StoreFSufs.cc
 @am__fastdepCXX_TRUE@	$(LIBTOOL)  --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT StoreFSufs.lo -MD -MP -MF $(DEPDIR)/StoreFSufs.Tpo -c -o StoreFSufs.lo `test -f 'ufs/StoreFSufs.cc' || echo '$(srcdir)/'`ufs/StoreFSufs.cc
 @am__fastdepCXX_TRUE@	$(am__mv) $(DEPDIR)/StoreFSufs.Tpo $(DEPDIR)/StoreFSufs.Plo
@@ -830,8 +889,10 @@
 coss/clean: clean
 ufs/all: libufs.la
 ufs/clean: clean
+rock/all: librock.la
+rock/clean: clean
 
-testHeaders: $(srcdir)/ufs/*.h $(srcdir)/coss/*.h
+testHeaders: $(srcdir)/ufs/*.h $(srcdir)/coss/*.h $(srcdir)/rock/*.h
 	$(SHELL) $(top_srcdir)/test-suite/testheaders.sh "$(CXXCOMPILE)" $^ || exit 1
 
 .PHONY: testHeaders
diff -u -r -N squid-3.2.0.12/src/fs/Module.cc squid-3.2.0.13/src/fs/Module.cc
--- squid-3.2.0.12/src/fs/Module.cc	2011-09-16 23:37:30.000000000 +1200
+++ squid-3.2.0.13/src/fs/Module.cc	2011-10-14 14:42:56.000000000 +1300
@@ -22,6 +22,12 @@
 static StoreFSufs<UFSSwapDir> *DiskdInstance;
 #endif
 
+#if HAVE_FS_ROCK
+#include "fs/rock/RockStoreFileSystem.h"
+static Rock::StoreFileSystem *RockInstance = NULL;
+#endif
+
+
 /* TODO: Modify coss code to:
  * (a) remove the StoreFScoss::GetInstance method,
  * (b) declare the StoreFScoss::stats  as static and
@@ -48,6 +54,10 @@
     DiskdInstance = new StoreFSufs<UFSSwapDir>("DiskDaemon", "diskd");;
 #endif
 
+#if HAVE_FS_ROCK
+    RockInstance = new Rock::StoreFileSystem();
+#endif
+
 }
 
 
@@ -66,4 +76,8 @@
     delete DiskdInstance;
 #endif
 
+#if HAVE_FS_ROCK
+    delete RockInstance;
+#endif
+
 }
diff -u -r -N squid-3.2.0.12/src/fs/rock/RockDbCell.h squid-3.2.0.13/src/fs/rock/RockDbCell.h
--- squid-3.2.0.12/src/fs/rock/RockDbCell.h	1970-01-01 12:00:00.000000000 +1200
+++ squid-3.2.0.13/src/fs/rock/RockDbCell.h	2011-10-14 14:42:56.000000000 +1300
@@ -0,0 +1,25 @@
+#ifndef SQUID_FS_ROCK_DB_CELL_H
+#define SQUID_FS_ROCK_DB_CELL_H
+
+namespace Rock
+{
+
+/** \ingroup Rock
+ * Meta-information at the beginning of every db cell.
+ * Stored on disk and used as sizeof() argument so it must remain POD.
+ */
+class DbCellHeader
+{
+public:
+    DbCellHeader(): payloadSize(0), reserved(0) {}
+
+    /// whether the freshly loaded header fields make sense
+    bool sane() const { return payloadSize >= 0 && reserved == 0; }
+
+    int64_t payloadSize; ///< cell contents size excluding this header
+    int64_t reserved; ///< reserved for future use (next cell pointer?)
+};
+
+} // namespace Rock
+
+#endif /* SQUID_FS_ROCK_DB_CELL_H */
diff -u -r -N squid-3.2.0.12/src/fs/rock/RockIoRequests.cc squid-3.2.0.13/src/fs/rock/RockIoRequests.cc
--- squid-3.2.0.12/src/fs/rock/RockIoRequests.cc	1970-01-01 12:00:00.000000000 +1200
+++ squid-3.2.0.13/src/fs/rock/RockIoRequests.cc	2011-10-14 14:42:56.000000000 +1300
@@ -0,0 +1,25 @@
+/*
+ * $Id$
+ *
+ * DEBUG: section 79    Disk IO Routines
+ */
+
+#include "config.h"
+#include "fs/rock/RockIoRequests.h"
+
+CBDATA_NAMESPACED_CLASS_INIT(Rock, ReadRequest);
+CBDATA_NAMESPACED_CLASS_INIT(Rock, WriteRequest);
+
+Rock::ReadRequest::ReadRequest(const ::ReadRequest &base,
+                               const IoState::Pointer &anSio):
+        ::ReadRequest(base),
+        sio(anSio)
+{
+}
+
+Rock::WriteRequest::WriteRequest(const ::WriteRequest &base,
+                                 const IoState::Pointer &anSio):
+        ::WriteRequest(base),
+        sio(anSio)
+{
+}
diff -u -r -N squid-3.2.0.12/src/fs/rock/RockIoRequests.h squid-3.2.0.13/src/fs/rock/RockIoRequests.h
--- squid-3.2.0.12/src/fs/rock/RockIoRequests.h	1970-01-01 12:00:00.000000000 +1200
+++ squid-3.2.0.13/src/fs/rock/RockIoRequests.h	2011-10-14 14:42:56.000000000 +1300
@@ -0,0 +1,39 @@
+#ifndef SQUID_FS_ROCK_IO_REQUESTS_H
+#define SQUID_FS_ROCK_IO_REQUESTS_H
+
+#include "DiskIO/ReadRequest.h"
+#include "DiskIO/WriteRequest.h"
+#include "fs/rock/RockIoState.h"
+
+class DiskFile;
+
+namespace Rock
+{
+
+/// \ingroup Rock
+class ReadRequest: public ::ReadRequest
+{
+public:
+    ReadRequest(const ::ReadRequest &base, const IoState::Pointer &anSio);
+    IoState::Pointer sio;
+
+private:
+    CBDATA_CLASS2(ReadRequest);
+};
+
+
+/// \ingroup Rock
+class WriteRequest: public ::WriteRequest
+{
+public:
+    WriteRequest(const ::WriteRequest &base, const IoState::Pointer &anSio);
+    IoState::Pointer sio;
+
+private:
+    CBDATA_CLASS2(WriteRequest);
+};
+
+
+} // namespace Rock
+
+#endif /* SQUID_FS_ROCK_IO_REQUESTS_H */
diff -u -r -N squid-3.2.0.12/src/fs/rock/RockIoState.cc squid-3.2.0.13/src/fs/rock/RockIoState.cc
--- squid-3.2.0.12/src/fs/rock/RockIoState.cc	1970-01-01 12:00:00.000000000 +1200
+++ squid-3.2.0.13/src/fs/rock/RockIoState.cc	2011-10-14 14:42:56.000000000 +1300
@@ -0,0 +1,210 @@
+/*
+ * $Id$
+ *
+ * DEBUG: section 79    Disk IO Routines
+ */
+
+#include "config.h"
+#include "MemObject.h"
+#include "Parsing.h"
+#include "DiskIO/DiskIOModule.h"
+#include "DiskIO/DiskIOStrategy.h"
+#include "DiskIO/WriteRequest.h"
+#include "fs/rock/RockIoState.h"
+#include "fs/rock/RockIoRequests.h"
+#include "fs/rock/RockSwapDir.h"
+
+Rock::IoState::IoState(SwapDir *dir,
+                       StoreEntry *anEntry,
+                       StoreIOState::STFNCB *cbFile,
+                       StoreIOState::STIOCB *cbIo,
+                       void *data):
+        slotSize(0),
+        diskOffset(-1),
+        payloadEnd(-1)
+{
+    e = anEntry;
+    // swap_filen, swap_dirn, diskOffset, and payloadEnd are set by the caller
+    slotSize = dir->max_objsize;
+    file_callback = cbFile;
+    callback = cbIo;
+    callback_data = cbdataReference(data);
+    ++store_open_disk_fd; // TODO: use a dedicated counter?
+    //theFile is set by SwapDir because it depends on DiskIOStrategy
+}
+
+Rock::IoState::~IoState()
+{
+    --store_open_disk_fd;
+    if (callback_data)
+        cbdataReferenceDone(callback_data);
+    theFile = NULL;
+}
+
+void
+Rock::IoState::file(const RefCount<DiskFile> &aFile)
+{
+    assert(!theFile);
+    assert(aFile != NULL);
+    theFile = aFile;
+}
+
+void
+Rock::IoState::read_(char *buf, size_t len, off_t coreOff, STRCB *cb, void *data)
+{
+    assert(theFile != NULL);
+    assert(coreOff >= 0);
+    offset_ = coreOff;
+
+    // we skip our cell header; it is only read when building the map
+    const int64_t cellOffset = sizeof(DbCellHeader) +
+                               static_cast<int64_t>(coreOff);
+    assert(cellOffset <= payloadEnd);
+
+    // Core specifies buffer length, but we must not exceed stored entry size
+    if (cellOffset + (int64_t)len > payloadEnd)
+        len = payloadEnd - cellOffset;
+
+    assert(read.callback == NULL);
+    assert(read.callback_data == NULL);
+    read.callback = cb;
+    read.callback_data = cbdataReference(data);
+
+    theFile->read(new ReadRequest(
+                      ::ReadRequest(buf, diskOffset + cellOffset, len), this));
+}
+
+// We only buffer data here; we actually write when close() is called.
+// We buffer, in part, to avoid forcing OS to _read_ old unwritten portions
+// of the slot when the write does not end at the page or sector boundary.
+void
+Rock::IoState::write(char const *buf, size_t size, off_t coreOff, FREE *dtor)
+{
+    // TODO: move to create?
+    if (!coreOff) {
+        assert(theBuf.isNull());
+        assert(payloadEnd <= slotSize);
+        theBuf.init(min(payloadEnd, slotSize), slotSize);
+        // start with our header; TODO: consider making it a trailer
+        DbCellHeader header;
+        assert(static_cast<int64_t>(sizeof(header)) <= payloadEnd);
+        header.payloadSize = payloadEnd - sizeof(header);
+        theBuf.append(reinterpret_cast<const char*>(&header), sizeof(header));
+    } else {
+        // Core uses -1 offset as "append". Sigh.
+        assert(coreOff == -1);
+        assert(!theBuf.isNull());
+    }
+
+    theBuf.append(buf, size);
+    offset_ += size; // so that Core thinks we wrote it
+
+    if (dtor)
+        (dtor)(const_cast<char*>(buf)); // cast due to a broken API?
+}
+
+// write what was buffered during write() calls
+void
+Rock::IoState::startWriting()
+{
+    assert(theFile != NULL);
+    assert(!theBuf.isNull());
+
+    // TODO: if DiskIO module is mmap-based, we should be writing whole pages
+    // to avoid triggering read-page;new_head+old_tail;write-page overheads
+
+    debugs(79, 5, HERE << swap_filen << " at " << diskOffset << '+' <<
+           theBuf.contentSize());
+
+    assert(theBuf.contentSize() <= slotSize);
+    // theFile->write may call writeCompleted immediatelly
+    theFile->write(new WriteRequest(::WriteRequest(theBuf.content(),
+                                    diskOffset, theBuf.contentSize(), theBuf.freeFunc()), this));
+}
+
+//
+void
+Rock::IoState::finishedWriting(const int errFlag)
+{
+    // we incremented offset_ while accumulating data in write()
+    callBack(errFlag);
+}
+
+void
+Rock::IoState::close(int how)
+{
+    debugs(79, 3, HERE << swap_filen << " accumulated: " << offset_ <<
+           " how=" << how);
+    if (how == wroteAll && !theBuf.isNull())
+        startWriting();
+    else
+        callBack(how == writerGone ? DISK_ERROR : 0); // TODO: add DISK_CALLER_GONE
+}
+
+/// close callback (STIOCB) dialer: breaks dependencies and
+/// counts IOState concurrency level
+class StoreIOStateCb: public CallDialer
+{
+public:
+    StoreIOStateCb(StoreIOState::STIOCB *cb, void *data, int err, const Rock::IoState::Pointer &anSio):
+            callback(NULL),
+            callback_data(NULL),
+            errflag(err),
+            sio(anSio) {
+
+        callback = cb;
+        callback_data = cbdataReference(data);
+    }
+
+    StoreIOStateCb(const StoreIOStateCb &cb):
+            callback(NULL),
+            callback_data(NULL),
+            errflag(cb.errflag),
+            sio(cb.sio) {
+
+        callback = cb.callback;
+        callback_data = cbdataReference(cb.callback_data);
+    }
+
+    virtual ~StoreIOStateCb() {
+        cbdataReferenceDone(callback_data); // may be nil already
+    }
+
+    void dial(AsyncCall &call) {
+        void *cbd;
+        if (cbdataReferenceValidDone(callback_data, &cbd) && callback)
+            callback(cbd, errflag, sio.getRaw());
+    }
+
+    bool canDial(AsyncCall &call) const {
+        return cbdataReferenceValid(callback_data) && callback;
+    }
+
+    virtual void print(std::ostream &os) const {
+        os << '(' << callback_data << ", err=" << errflag << ')';
+    }
+
+private:
+    StoreIOStateCb &operator =(const StoreIOStateCb &cb); // not defined
+
+    StoreIOState::STIOCB *callback;
+    void *callback_data;
+    int errflag;
+    Rock::IoState::Pointer sio;
+};
+
+
+void
+Rock::IoState::callBack(int errflag)
+{
+    debugs(79,3, HERE << "errflag=" << errflag);
+    theFile = NULL;
+
+    AsyncCall::Pointer call = asyncCall(79,3, "SomeIoStateCloseCb",
+                                        StoreIOStateCb(callback, callback_data, errflag, this));
+    ScheduleCallHere(call);
+
+    callback = NULL;
+    cbdataReferenceDone(callback_data);
+}
+
diff -u -r -N squid-3.2.0.12/src/fs/rock/RockIoState.h squid-3.2.0.13/src/fs/rock/RockIoState.h
--- squid-3.2.0.12/src/fs/rock/RockIoState.h	1970-01-01 12:00:00.000000000 +1200
+++ squid-3.2.0.13/src/fs/rock/RockIoState.h	2011-10-14 14:42:56.000000000 +1300
@@ -0,0 +1,54 @@
+#ifndef SQUID_FS_ROCK_IO_STATE_H
+#define SQUID_FS_ROCK_IO_STATE_H
+
+#include "MemBuf.h"
+#include "SwapDir.h"
+
+class DiskFile;
+
+namespace Rock
+{
+
+class SwapDir;
+
+/// \ingroup Rock
+class IoState: public ::StoreIOState
+{
+public:
+    typedef RefCount<IoState> Pointer;
+
+    IoState(SwapDir *dir, StoreEntry *e, StoreIOState::STFNCB *cbFile, StoreIOState::STIOCB *cbIo, void *data);
+    virtual ~IoState();
+
+    void file(const RefCount<DiskFile> &aFile);
+
+    // ::StoreIOState API
+    virtual void read_(char *buf, size_t size, off_t offset, STRCB * callback, void *callback_data);
+    virtual void write(char const *buf, size_t size, off_t offset, FREE * free_func);
+    virtual void close(int how);
+
+    /// called by SwapDir when writing is done
+    void finishedWriting(int errFlag);
+
+    int64_t slotSize; ///< db cell size
+    int64_t diskOffset; ///< the start of this cell inside the db file
+
+    /// when reading: number of bytes previously written to the db cell;
+    /// when writing: maximum payload offset in a db cell
+    int64_t payloadEnd;
+
+    MEMPROXY_CLASS(IoState);
+
+private:
+    void startWriting();
+    void callBack(int errflag);
+
+    RefCount<DiskFile> theFile; // "file" responsible for this I/O
+    MemBuf theBuf; // use for write content accumulation only
+};
+
+MEMPROXY_CLASS_INLINE(IoState);
+
+} // namespace Rock
+
+#endif /* SQUID_FS_ROCK_IO_STATE_H */
diff -u -r -N squid-3.2.0.12/src/fs/rock/RockRebuild.cc squid-3.2.0.13/src/fs/rock/RockRebuild.cc
--- squid-3.2.0.12/src/fs/rock/RockRebuild.cc	1970-01-01 12:00:00.000000000 +1200
+++ squid-3.2.0.13/src/fs/rock/RockRebuild.cc	2011-10-14 14:42:56.000000000 +1300
@@ -0,0 +1,202 @@
+/*
+ * $Id$
+ *
+ * DEBUG: section 79    Disk IO Routines
+ */
+
+#include "config.h"
+#include "fs/rock/RockRebuild.h"
+#include "fs/rock/RockSwapDir.h"
+#include "fs/rock/RockDbCell.h"
+#include "SquidTime.h"
+
+CBDATA_NAMESPACED_CLASS_INIT(Rock, Rebuild);
+
+Rock::Rebuild::Rebuild(SwapDir *dir): AsyncJob("Rock::Rebuild"),
+        sd(dir),
+        dbSize(0),
+        dbEntrySize(0),
+        dbEntryLimit(0),
+        fd(-1),
+        dbOffset(0),
+        filen(0)
+{
+    assert(sd);
+    memset(&counts, 0, sizeof(counts));
+    dbSize = sd->diskOffsetLimit(); // we do not care about the trailer waste
+    dbEntrySize = sd->max_objsize;
+    dbEntryLimit = sd->entryLimit();
+}
+
+Rock::Rebuild::~Rebuild()
+{
+    if (fd >= 0)
+        file_close(fd);
+}
+
+/// prepares and initiates entry loading sequence
+void
+Rock::Rebuild::start()
+{
+    // in SMP mode, only the disker is responsible for populating the map
+    if (UsingSmp() && !IamDiskProcess()) {
+        debugs(47, 2, "Non-disker skips rebuilding of cache_dir #" <<
+               sd->index << " from " << sd->filePath);
+        mustStop("non-disker");
+        return;
+    }
+
+    debugs(47, DBG_IMPORTANT, "Loading cache_dir #" << sd->index <<
+           " from " << sd->filePath);
+
+    fd = file_open(sd->filePath, O_RDONLY | O_BINARY);
+    if (fd < 0)
+        failure("cannot open db", errno);
+
+    char buf[SwapDir::HeaderSize];
+    if (read(fd, buf, sizeof(buf)) != SwapDir::HeaderSize)
+        failure("cannot read db header", errno);
+
+    dbOffset = SwapDir::HeaderSize;
+    filen = 0;
+
+    checkpoint();
+}
+
+/// continues after a pause if not done
+void
+Rock::Rebuild::checkpoint()
+{
+    if (!done())
+        eventAdd("Rock::Rebuild", Rock::Rebuild::Steps, this, 0.01, 1, true);
+}
+
+bool
+Rock::Rebuild::doneAll() const
+{
+    return dbOffset >= dbSize && AsyncJob::doneAll();
+}
+
+void
+Rock::Rebuild::Steps(void *data)
+{
+    // use async call to enable job call protection that time events lack
+    CallJobHere(47, 5, static_cast<Rebuild*>(data), Rock::Rebuild, steps);
+}
+
+void
+Rock::Rebuild::steps()
+{
+    debugs(47,5, HERE << sd->index << " filen " << filen << " at " <<
+           dbOffset << " <= " << dbSize);
+
+    // Balance our desire to maximize the number of entries processed at once
+    // (and, hence, minimize overheads and total rebuild time) with a
+    // requirement to also process Coordinator events, disk I/Os, etc.
+    const int maxSpentMsec = 50; // keep small: most RAM I/Os are under 1ms
+    const timeval loopStart = current_time;
+
+    int loaded = 0;
+    while (loaded < dbEntryLimit && dbOffset < dbSize) {
+        doOneEntry();
+        dbOffset += dbEntrySize;
+        ++filen;
+        ++loaded;
+
+        if (counts.scancount % 1000 == 0)
+            storeRebuildProgress(sd->index, dbEntryLimit, counts.scancount);
+
+        if (opt_foreground_rebuild)
+            continue; // skip "few entries at a time" check below
+
+        getCurrentTime();
+        const double elapsedMsec = tvSubMsec(loopStart, current_time);
+        if (elapsedMsec > maxSpentMsec || elapsedMsec < 0) {
+            debugs(47, 5, HERE << "pausing after " << loaded << " entries in " <<
+                   elapsedMsec << "ms; " << (elapsedMsec/loaded) << "ms per entry");
+            break;
+        }
+    }
+
+    checkpoint();
+}
+
+void
+Rock::Rebuild::doOneEntry()
+{
+    debugs(47,5, HERE << sd->index << " filen " << filen << " at " <<
+           dbOffset << " <= " << dbSize);
+
+    ++counts.scancount;
+
+    if (lseek(fd, dbOffset, SEEK_SET) < 0)
+        failure("cannot seek to db entry", errno);
+
+    MemBuf buf;
+    buf.init(SM_PAGE_SIZE, SM_PAGE_SIZE);
+
+    if (!storeRebuildLoadEntry(fd, sd->index, buf, counts))
+        return;
+
+    // get our header
+    DbCellHeader header;
+    if (buf.contentSize() < static_cast<mb_size_t>(sizeof(header))) {
+        debugs(47, DBG_IMPORTANT, "WARNING: cache_dir[" << sd->index << "]: " <<
+               "Ignoring truncated cache entry meta data at " << dbOffset);
+        counts.invalid++;
+        return;
+    }
+    memcpy(&header, buf.content(), sizeof(header));
+
+    if (!header.sane()) {
+        debugs(47, DBG_IMPORTANT, "WARNING: cache_dir[" << sd->index << "]: " <<
+               "Ignoring malformed cache entry meta data at " << dbOffset);
+        counts.invalid++;
+        return;
+    }
+    buf.consume(sizeof(header)); // optimize to avoid memmove()
+
+    cache_key key[SQUID_MD5_DIGEST_LENGTH];
+    StoreEntry loadedE;
+    if (!storeRebuildParseEntry(buf, loadedE, key, counts, header.payloadSize)) {
+        // skip empty slots
+        if (loadedE.swap_filen > 0 || loadedE.swap_file_sz > 0) {
+            counts.invalid++;
+            //sd->unlink(filen); leave garbage on disk, it should not hurt
+        }
+        return;
+    }
+
+    assert(loadedE.swap_filen < dbEntryLimit);
+    if (!storeRebuildKeepEntry(loadedE, key, counts))
+        return;
+
+    counts.objcount++;
+    // loadedE->dump(5);
+
+    sd->addEntry(filen, header, loadedE);
+}
+
+void
+Rock::Rebuild::swanSong()
+{
+    debugs(47,3, HERE << "cache_dir #" << sd->index << " rebuild level: " <<
+           StoreController::store_dirs_rebuilding);
+    --StoreController::store_dirs_rebuilding;
+    storeRebuildComplete(&counts);
+}
+
+void
+Rock::Rebuild::failure(const char *msg, int errNo)
+{
+    debugs(47,5, HERE << sd->index << " filen " << filen << " at " <<
+           dbOffset << " <= " << dbSize);
+
+    if (errNo)
+        debugs(47, DBG_CRITICAL, "ERROR: Rock cache_dir rebuild failure: " << xstrerr(errNo));
+    debugs(47, DBG_CRITICAL, "Do you need to run 'squid -z' to initialize storage?");
+
+    assert(sd);
+    fatalf("Rock cache_dir[%d] rebuild of %s failed: %s.",
+           sd->index, sd->filePath, msg);
+}
diff -u -r -N squid-3.2.0.12/src/fs/rock/RockRebuild.h squid-3.2.0.13/src/fs/rock/RockRebuild.h
--- squid-3.2.0.12/src/fs/rock/RockRebuild.h	1970-01-01 12:00:00.000000000 +1200
+++ squid-3.2.0.13/src/fs/rock/RockRebuild.h	2011-10-14 14:42:56.000000000 +1300
@@ -0,0 +1,51 @@
+#ifndef SQUID_FS_ROCK_REBUILD_H
+#define SQUID_FS_ROCK_REBUILD_H
+
+#include "base/AsyncJob.h"
+#include "structs.h"
+
+namespace Rock
+{
+
+class SwapDir;
+
+/// \ingroup Rock
+/// manages store rebuild process: loading meta information from db on disk
+class Rebuild: public AsyncJob
+{
+public:
+    Rebuild(SwapDir *dir);
+    ~Rebuild();
+
+protected:
+    /* AsyncJob API */
+    virtual void start();
+    virtual bool doneAll() const;
+    virtual void swanSong();
+
+private:
+    void checkpoint();
+    void steps();
+    void doOneEntry();
+    void failure(const char *msg, int errNo = 0);
+
+    SwapDir *sd;
+
+    int64_t dbSize;
+    int dbEntrySize;
+    int dbEntryLimit;
+
+    int fd; // store db file descriptor
+    int64_t dbOffset;
+    int filen;
+
+    struct _store_rebuild_data counts;
+
+    static void Steps(void *data);
+
+    CBDATA_CLASS2(Rebuild);
+};
+
+} // namespace Rock
+
+#endif /* SQUID_FS_ROCK_REBUILD_H */
diff -u -r -N squid-3.2.0.12/src/fs/rock/RockStoreFileSystem.cc squid-3.2.0.13/src/fs/rock/RockStoreFileSystem.cc
--- squid-3.2.0.12/src/fs/rock/RockStoreFileSystem.cc	1970-01-01 12:00:00.000000000 +1200
+++ squid-3.2.0.13/src/fs/rock/RockStoreFileSystem.cc	2011-10-14 14:42:56.000000000 +1300
@@ -0,0 +1,54 @@
+/*
+ * $Id$
+ *
+ * DEBUG: section 92    Storage File System
+ */
+
+#include "config.h"
+#include "fs/rock/RockStoreFileSystem.h"
+#include "fs/rock/RockSwapDir.h"
+
+
+Rock::StoreFileSystem::StoreFileSystem()
+{
+    FsAdd(*this);
+}
+
+Rock::StoreFileSystem::~StoreFileSystem()
+{
+}
+
+char const *
+Rock::StoreFileSystem::type() const
+{
+    return "rock";
+}
+
+SwapDir *
+Rock::StoreFileSystem::createSwapDir()
+{
+    return new SwapDir();
+}
+
+void
+Rock::StoreFileSystem::done()
+{
+}
+
+void
+Rock::StoreFileSystem::registerWithCacheManager()
+{
+    assert(false); // XXX: implement
+}
+
+void
+Rock::StoreFileSystem::setup()
+{
+    debugs(92,2, HERE << "Will use Rock FS");
+}
+
+void
+Rock::StoreFileSystem::Stats(StoreEntry *sentry)
+{
+    assert(false); // XXX: implement
+}
diff -u -r -N squid-3.2.0.12/src/fs/rock/RockStoreFileSystem.h squid-3.2.0.13/src/fs/rock/RockStoreFileSystem.h
--- squid-3.2.0.12/src/fs/rock/RockStoreFileSystem.h	1970-01-01 12:00:00.000000000 +1200
+++ squid-3.2.0.13/src/fs/rock/RockStoreFileSystem.h	2011-10-14 14:42:56.000000000 +1300
@@ -0,0 +1,34 @@
+#ifndef SQUID_FS_ROCK_FS_H
+#define SQUID_FS_ROCK_FS_H
+
+#include "StoreFileSystem.h"
+
+namespace Rock
+{
+
+/// \ingroup Rock, FileSystems
+class StoreFileSystem: public ::StoreFileSystem
+{
+
+public:
+    static void Stats(StoreEntry * sentry);
+
+    StoreFileSystem();
+    virtual ~StoreFileSystem();
+
+    virtual char const *type() const;
+    virtual SwapDir *createSwapDir();
+    virtual void done();
+    virtual void registerWithCacheManager();
+    virtual void setup();
+
+private:
+    //static Stats Stats_;
+
+    StoreFileSystem(const StoreFileSystem &); // not implemented
+    StoreFileSystem &operator=(const StoreFileSystem &); // not implemented
+};
+
+} // namespace Rock
+
+#endif /* SQUID_FS_ROCK_FS_H */
diff -u -r -N squid-3.2.0.12/src/fs/rock/RockSwapDir.cc squid-3.2.0.13/src/fs/rock/RockSwapDir.cc
--- squid-3.2.0.12/src/fs/rock/RockSwapDir.cc	1970-01-01 12:00:00.000000000 +1200
+++ squid-3.2.0.13/src/fs/rock/RockSwapDir.cc	2011-10-14 14:42:56.000000000 +1300
@@ -0,0 +1,847 @@
+/*
+ * $Id$
+ *
+ * DEBUG: section 47    Store Directory Routines
+ */
+
+#include "config.h"
+#include "base/RunnersRegistry.h"
+#include "ConfigOption.h"
+#include "DiskIO/DiskIOModule.h"
+#include "DiskIO/DiskIOStrategy.h"
+#include "DiskIO/ReadRequest.h"
+#include "DiskIO/WriteRequest.h"
+#include "fs/rock/RockSwapDir.h"
+#include "fs/rock/RockIoState.h"
+#include "fs/rock/RockIoRequests.h"
+#include "fs/rock/RockRebuild.h"
+#include "ipc/mem/Pages.h"
+#include "MemObject.h"
+#include "Parsing.h"
+#include "SquidMath.h"
+#include <iomanip>
+
+const int64_t Rock::SwapDir::HeaderSize = 16*1024;
+
+Rock::SwapDir::SwapDir(): ::SwapDir("rock"), filePath(NULL), io(NULL), map(NULL)
+{
+}
+
+Rock::SwapDir::~SwapDir()
+{
+    delete io;
+    delete map;
+    safe_free(filePath);
+}
+
+StoreSearch *
+Rock::SwapDir::search(String const url, HttpRequest *)
+{
+    assert(false);
+    return NULL; // XXX: implement
+}
+
+void
+Rock::SwapDir::get(String const key, STOREGETCLIENT cb, void *data)
+{
+    ::SwapDir::get(key, cb, data);
+}
+
+// called when Squid core needs a StoreEntry with a given key
+StoreEntry *
+Rock::SwapDir::get(const cache_key *key)
+{
+    if (!map || !theFile || !theFile->canRead())
+        return NULL;
+
+    sfileno filen;
+    const Ipc::StoreMapSlot *const slot = map->openForReading(key, filen);
+    if (!slot)
+        return NULL;
+
+    const Ipc::StoreMapSlot::Basics &basics = slot->basics;
+
+    // create a brand new store entry and initialize it with stored basics
+    StoreEntry *e = new StoreEntry();
+    e->lock_count = 0;
+    e->swap_dirn = index;
+    e->swap_filen = filen;
+    e->swap_file_sz = basics.swap_file_sz;
+    e->lastref = basics.lastref;
+    e->timestamp = basics.timestamp;
+    e->expires = basics.expires;
+    e->lastmod = basics.lastmod;
+    e->refcount = basics.refcount;
+    e->flags = basics.flags;
+    e->store_status = STORE_OK;
+    e->setMemStatus(NOT_IN_MEMORY);
+    e->swap_status = SWAPOUT_DONE;
+    e->ping_status = PING_NONE;
+    EBIT_SET(e->flags, ENTRY_CACHABLE);
+    EBIT_CLR(e->flags, RELEASE_REQUEST);
+    EBIT_CLR(e->flags, KEY_PRIVATE);
+    EBIT_SET(e->flags, ENTRY_VALIDATED);
+    e->hashInsert(key);
+    trackReferences(*e);
+
+    return e;
+    // the disk entry remains open for reading, protected from modifications
+}
+
+void Rock::SwapDir::disconnect(StoreEntry &e)
+{
+    assert(e.swap_dirn == index);
+    assert(e.swap_filen >= 0);
+    // cannot have SWAPOUT_NONE entry with swap_filen >= 0
+    assert(e.swap_status != SWAPOUT_NONE);
+
+    // do not rely on e.swap_status here because there is an async delay
+    // before it switches from SWAPOUT_WRITING to SWAPOUT_DONE.
+
+    // since e has swap_filen, its slot is locked for either reading or writing
+    map->abortIo(e.swap_filen);
+    e.swap_dirn = -1;
+    e.swap_filen = -1;
+    e.swap_status = SWAPOUT_NONE;
+}
+
+uint64_t
+Rock::SwapDir::currentSize() const
+{
+    return HeaderSize + max_objsize * currentCount();
+}
+
+uint64_t
+Rock::SwapDir::currentCount() const
+{
+    return map ? map->entryCount() : 0;
+}
+
+/// In SMP mode only the disker process reports stats to avoid
+/// counting the same stats by multiple processes.
+bool
+Rock::SwapDir::doReportStat() const
+{
+    return ::SwapDir::doReportStat() && (!UsingSmp() || IamDiskProcess());
+}
+
+void
+Rock::SwapDir::swappedOut(const StoreEntry &)
+{
+    // stats are not stored but computed when needed
+}
+
+int64_t
+Rock::SwapDir::entryLimitAllowed() const
+{
+    const int64_t eLimitLo = map ? map->entryLimit() : 0; // dynamic shrinking unsupported
+    const int64_t eWanted = (maxSize() - HeaderSize)/maxObjectSize();
+    return min(max(eLimitLo, eWanted), entryLimitHigh());
+}
+
+// TODO: encapsulate as a tool; identical to CossSwapDir::create()
+void
+Rock::SwapDir::create()
+{
+    assert(path);
+    assert(filePath);
+
+    if (UsingSmp() && !IamDiskProcess()) {
+        debugs (47,3, HERE << "disker will create in " << path);
+        return;
+    }
+
+    debugs (47,3, HERE << "creating in " << path);
+
+    struct stat swap_sb;
+    if (::stat(path, &swap_sb) < 0) {
+        debugs (47, DBG_IMPORTANT, "Creating Rock db directory: " << path);
+        const int res = mkdir(path, 0700);
+        if (res != 0) {
+            debugs(47, DBG_CRITICAL, "Failed to create Rock db dir " << path <<
+                   ": " << xstrerror());
+            fatal("Rock Store db creation error");
+        }
+    }
+
+#if SLOWLY_FILL_WITH_ZEROS
+    char block[1024];
+    Must(maxSize() % sizeof(block) == 0);
+    memset(block, '\0', sizeof(block));
+
+    const int swap = open(filePath, O_WRONLY|O_CREAT|O_TRUNC|O_BINARY, 0600);
+    for (off_t offset = 0; offset < maxSize(); offset += sizeof(block)) {
+        if (write(swap, block, sizeof(block)) != sizeof(block)) {
+            debugs(47, DBG_CRITICAL, "ERROR: Failed to create Rock Store db in " << filePath <<
+                   ": " << xstrerror());
+            fatal("Rock Store db creation error");
+        }
+    }
+    close(swap);
+#else
+    const int swap = open(filePath, O_WRONLY|O_CREAT|O_TRUNC|O_BINARY, 0600);
+    if (swap < 0) {
+        debugs(47, DBG_CRITICAL, "ERROR: Failed to initialize Rock Store db in " << filePath <<
+               "; create error: " << xstrerror());
+        fatal("Rock Store db creation error");
+    }
+
+    if (ftruncate(swap, maxSize()) != 0) {
+        debugs(47, DBG_CRITICAL, "ERROR: Failed to initialize Rock Store db in " << filePath <<
+               "; truncate error: " << xstrerror());
+        fatal("Rock Store db creation error");
+    }
+
+    char header[HeaderSize];
+    memset(header, '\0', sizeof(header));
+    if (write(swap, header, sizeof(header)) != sizeof(header)) {
+        debugs(47, DBG_CRITICAL, "ERROR: Failed to initialize Rock Store db in " << filePath <<
+               "; write error: " << xstrerror());
+        fatal("Rock Store db initialization error");
+    }
+    close(swap);
+#endif
+}
+
+void
+Rock::SwapDir::init()
+{
+    debugs(47,2, HERE);
+
+    // XXX: SwapDirs aren't refcounted. We make IORequestor calls, which
+    // are refcounted. We up our count once to avoid implicit delete's.
+    RefCountReference();
+
+    Must(!map);
+    map = new DirMap(path);
+
+    const char *ioModule = needsDiskStrand() ? "IpcIo" : "Blocking";
+    if (DiskIOModule *m = DiskIOModule::Find(ioModule)) {
+        debugs(47,2, HERE << "Using DiskIO module: " << ioModule);
+        io = m->createStrategy();
+        io->init();
+    } else {
+        debugs(47, DBG_CRITICAL, "FATAL: Rock store is missing DiskIO module: " <<
+               ioModule);
+        fatal("Rock Store missing a required DiskIO module");
+    }
+
+    theFile = io->newFile(filePath);
+    theFile->configure(fileConfig);
+    theFile->open(O_RDWR, 0644, this);
+
+    // Increment early. Otherwise, if one SwapDir finishes rebuild before
+    // others start, storeRebuildComplete() will think the rebuild is over!
+    // TODO: move store_dirs_rebuilding hack to store modules that need it.
+    ++StoreController::store_dirs_rebuilding;
+}
+
+bool
+Rock::SwapDir::needsDiskStrand() const
+{
+    const bool wontEvenWorkWithoutDisker = Config.workers > 1;
+    const bool wouldWorkBetterWithDisker = DiskIOModule::Find("IpcIo");
+    return InDaemonMode() && (wontEvenWorkWithoutDisker ||
+                              wouldWorkBetterWithDisker);
+}
+
+void
+Rock::SwapDir::parse(int anIndex, char *aPath)
+{
+    index = anIndex;
+
+    path = xstrdup(aPath);
+
+    // cache store is located at path/db
+    String fname(path);
+    fname.append("/rock");
+    filePath = xstrdup(fname.termedBuf());
+
+    parseSize(false);
+    parseOptions(0);
+
+    // Current openForWriting() code overwrites the old slot if needed
+    // and possible, so proactively removing old slots is probably useless.
+    assert(!repl); // repl = createRemovalPolicy(Config.replPolicy);
+
+    validateOptions();
+}
+
+void
+Rock::SwapDir::reconfigure()
+{
+    parseSize(true);
+    parseOptions(1);
+    // TODO: can we reconfigure the replacement policy (repl)?
+    validateOptions();
+}
+
+/// parse maximum db disk size
+void
+Rock::SwapDir::parseSize(const bool reconfiguring)
+{
+    const int i = GetInteger();
+    if (i < 0)
+        fatal("negative Rock cache_dir size value");
+    const uint64_t new_max_size =
+        static_cast<uint64_t>(i) << 20; // MBytes to Bytes
+    if (!reconfiguring)
+        max_size = new_max_size;
+    else if (new_max_size != max_size) {
+        debugs(3, DBG_IMPORTANT, "WARNING: cache_dir '" << path << "' size "
+               "cannot be changed dynamically, value left unchanged (" <<
+               (max_size >> 20) << " MB)");
+    }
+}
+
+ConfigOption *
+Rock::SwapDir::getOptionTree() const
+{
+    ConfigOptionVector *vector = dynamic_cast<ConfigOptionVector*>(::SwapDir::getOptionTree());
+    assert(vector);
+    vector->options.push_back(new ConfigOptionAdapter<SwapDir>(*const_cast<SwapDir *>(this), &SwapDir::parseTimeOption, &SwapDir::dumpTimeOption));
+    vector->options.push_back(new ConfigOptionAdapter<SwapDir>(*const_cast<SwapDir *>(this), &SwapDir::parseRateOption, &SwapDir::dumpRateOption));
+    return vector;
+}
+
+bool
+Rock::SwapDir::allowOptionReconfigure(const char *const option) const
+{
+    return strcmp(option, "max-size") != 0 &&
+           ::SwapDir::allowOptionReconfigure(option);
+}
+
+/// parses time-specific options; mimics ::SwapDir::optionObjectSizeParse()
+bool
+Rock::SwapDir::parseTimeOption(char const *option, const char *value, int reconfiguring)
+{
+    // TODO: ::SwapDir or, better, Config should provide time-parsing routines,
+    // including time unit handling. Same for size.
+
+    time_msec_t *storedTime;
+    if (strcmp(option, "swap-timeout") == 0)
+        storedTime = &fileConfig.ioTimeout;
+    else
+        return false;
+
+    if (!value)
+        self_destruct();
+
+    // TODO: handle time units and detect parsing errors better
+    const int64_t parsedValue = strtoll(value, NULL, 10);
+    if (parsedValue < 0) {
+        debugs(3, DBG_CRITICAL, "FATAL: cache_dir " << path << ' ' << option << " must not be negative but is: " << parsedValue);
+        self_destruct();
+    }
+
+    const time_msec_t newTime = static_cast<time_msec_t>(parsedValue);
+
+    if (reconfiguring && *storedTime != newTime)
+        debugs(3, DBG_IMPORTANT, "cache_dir " << path << ' ' << option << " is now " << newTime);
+
+    *storedTime = newTime;
+
+    return true;
+}
+
+/// reports time-specific options; mimics ::SwapDir::optionObjectSizeDump()
+void
+Rock::SwapDir::dumpTimeOption(StoreEntry * e) const
+{
+    if (fileConfig.ioTimeout)
+        storeAppendPrintf(e, " swap-timeout=%"PRId64,
+                          static_cast<int64_t>(fileConfig.ioTimeout));
+}
+
+/// parses rate-specific options; mimics ::SwapDir::optionObjectSizeParse()
+bool
+Rock::SwapDir::parseRateOption(char const *option, const char *value, int isaReconfig)
+{
+    int *storedRate;
+    if (strcmp(option, "max-swap-rate") == 0)
+        storedRate = &fileConfig.ioRate;
+    else
+        return false;
+
+    if (!value)
+        self_destruct();
+
+    // TODO: handle time units and detect parsing errors better
+    const int64_t parsedValue = strtoll(value, NULL, 10);
+    if (parsedValue < 0) {
+        debugs(3, DBG_CRITICAL, "FATAL: cache_dir " << path << ' ' << option << " must not be negative but is: " << parsedValue);
+        self_destruct();
+    }
+
+    const int newRate = static_cast<int>(parsedValue);
+
+    if (newRate < 0) {
+        debugs(3, DBG_CRITICAL, "FATAL: cache_dir " << path << ' ' << option << " must not be negative but is: " << newRate);
+        self_destruct();
+    }
+
+    if (isaReconfig && *storedRate != newRate)
+        debugs(3, DBG_IMPORTANT, "cache_dir " << path << ' ' << option << " is now " << newRate);
+
+    *storedRate = newRate;
+
+    return true;
+}
+
+/// reports rate-specific options; mimics ::SwapDir::optionObjectSizeDump()
+void
+Rock::SwapDir::dumpRateOption(StoreEntry * e) const
+{
+    if (fileConfig.ioRate >= 0)
+        storeAppendPrintf(e, " max-swap-rate=%d", fileConfig.ioRate);
+}
+
+/// check the results of the configuration; only level-0 debugging works here
+void
+Rock::SwapDir::validateOptions()
+{
+    if (max_objsize <= 0)
+        fatal("Rock store requires a positive max-size");
+
+    const int64_t maxSizeRoundingWaste = 1024 * 1024; // size is configured in MB
+    const int64_t maxObjectSizeRoundingWaste = maxObjectSize();
+    const int64_t maxRoundingWaste =
+        max(maxSizeRoundingWaste, maxObjectSizeRoundingWaste);
+    const int64_t usableDiskSize = diskOffset(entryLimitAllowed());
+    const int64_t diskWasteSize = maxSize() - usableDiskSize;
+    Must(diskWasteSize >= 0);
+
+    // warn if maximum db size is not reachable due to sfileno limit
+    if (entryLimitAllowed() == entryLimitHigh() &&
+            diskWasteSize >= maxRoundingWaste) {
+        debugs(47, DBG_CRITICAL, "Rock store cache_dir[" << index << "] '" << path << "':");
+        debugs(47, DBG_CRITICAL, "\tmaximum number of entries: " << entryLimitAllowed());
+        debugs(47, DBG_CRITICAL, "\tmaximum object size: " << maxObjectSize() << " Bytes");
+        debugs(47, DBG_CRITICAL, "\tmaximum db size: " << maxSize() << " Bytes");
+        debugs(47, DBG_CRITICAL, "\tusable db size:  " << usableDiskSize << " Bytes");
+        debugs(47, DBG_CRITICAL, "\tdisk space waste: " << diskWasteSize << " Bytes");
+        debugs(47, DBG_CRITICAL, "WARNING: Rock store config wastes space.");
+    }
+}
+
+void
+Rock::SwapDir::rebuild()
+{
+    //++StoreController::store_dirs_rebuilding; // see Rock::SwapDir::init()
+    AsyncJob::Start(new Rebuild(this));
+}
+
+/* Add a new object to the cache with empty memory copy and pointer to disk
+ * use to rebuild store from disk. Based on UFSSwapDir::addDiskRestore */
+bool
+Rock::SwapDir::addEntry(const int filen, const DbCellHeader &header, const StoreEntry &from)
+{
+    debugs(47, 8, HERE << &from << ' ' << from.getMD5Text() <<
+           ", filen="<< std::setfill('0') << std::hex << std::uppercase <<
+           std::setw(8) << filen);
+
+    sfileno newLocation = 0;
+    if (Ipc::StoreMapSlot *slot = map->openForWriting(reinterpret_cast<const cache_key *>(from.key), newLocation)) {
+        if (filen == newLocation) {
+            slot->set(from);
+            map->extras(filen) = header;
+        } // else some other, newer entry got into our cell
+        map->closeForWriting(newLocation, false);
+        return filen == newLocation;
+    }
+
+    return false;
+}
+
+
+bool
+Rock::SwapDir::canStore(const StoreEntry &e, int64_t diskSpaceNeeded, int &load) const
+{
+    if (!::SwapDir::canStore(e, sizeof(DbCellHeader)+diskSpaceNeeded, load))
+        return false;
+
+    if (!theFile || !theFile->canWrite())
+        return false;
+
+    if (!map)
+        return false;
+
+    // Do not start I/O transaction if there are less than 10% free pages left.
+    // TODO: reserve page instead
+    if (needsDiskStrand() &&
+            Ipc::Mem::PageLevel(Ipc::Mem::PageId::ioPage) >= 0.9 * Ipc::Mem::PageLimit(Ipc::Mem::PageId::ioPage)) {
+        debugs(47, 5, HERE << "too few shared pages for IPC I/O left");
+        return false;
+    }
+
+    if (io->shedLoad())
+        return false;
+
+    load = io->load();
+    return true;
+}
+
+StoreIOState::Pointer
+Rock::SwapDir::createStoreIO(StoreEntry &e, StoreIOState::STFNCB *cbFile, StoreIOState::STIOCB *cbIo, void *data)
+{
+    if (!theFile || theFile->error()) {
+        debugs(47,4, HERE << theFile);
+        return NULL;
+    }
+
+    // compute payload size for our cell header, using StoreEntry info
+    // careful: e.objectLen() may still be negative here
+    const int64_t expectedReplySize = e.mem_obj->expectedReplySize();
+    assert(expectedReplySize >= 0); // must know to prevent cell overflows
+    assert(e.mem_obj->swap_hdr_sz > 0);
+    DbCellHeader header;
+    header.payloadSize = e.mem_obj->swap_hdr_sz + expectedReplySize;
+    const int64_t payloadEnd = sizeof(DbCellHeader) + header.payloadSize;
+    assert(payloadEnd <= max_objsize);
+
+    sfileno filen;
+    Ipc::StoreMapSlot *const slot =
+        map->openForWriting(reinterpret_cast<const cache_key *>(e.key), filen);
+    if (!slot) {
+        debugs(47, 5, HERE << "map->add failed");
+        return NULL;
+    }
+    e.swap_file_sz = header.payloadSize; // and will be copied to the map
+    slot->set(e);
+    map->extras(filen) = header;
+
+    // XXX: We rely on our caller, storeSwapOutStart(), to set e.fileno.
+    // If that does not happen, the entry will not decrement the read level!
+
+    IoState *sio = new IoState(this, &e, cbFile, cbIo, data);
+
+    sio->swap_dirn = index;
+    sio->swap_filen = filen;
+    sio->payloadEnd = payloadEnd;
+    sio->diskOffset = diskOffset(sio->swap_filen);
+
+    debugs(47,5, HERE << "dir " << index << " created new filen " <<
+           std::setfill('0') << std::hex << std::uppercase << std::setw(8) <<
+           sio->swap_filen << std::dec << " at " << sio->diskOffset);
+
+    assert(sio->diskOffset + payloadEnd <= diskOffsetLimit());
+
+    sio->file(theFile);
+
+    trackReferences(e);
+    return sio;
+}
+
+int64_t
+Rock::SwapDir::diskOffset(int filen) const
+{
+    assert(filen >= 0);
+    return HeaderSize + max_objsize*filen;
+}
+
+int64_t
+Rock::SwapDir::diskOffsetLimit() const
+{
+    assert(map);
+    return diskOffset(map->entryLimit());
+}
+
+// tries to open an old or being-written-to entry with swap_filen for reading
+StoreIOState::Pointer
+Rock::SwapDir::openStoreIO(StoreEntry &e, StoreIOState::STFNCB *cbFile, StoreIOState::STIOCB *cbIo, void *data)
+{
+    if (!theFile || theFile->error()) {
+        debugs(47,4, HERE << theFile);
+        return NULL;
+    }
+
+    if (e.swap_filen < 0) {
+        debugs(47,4, HERE << e);
+        return NULL;
+    }
+
+    // Do not start I/O transaction if there are less than 10% free pages left.
+    // TODO: reserve page instead
+    if (needsDiskStrand() &&
+            Ipc::Mem::PageLevel(Ipc::Mem::PageId::ioPage) >= 0.9 * Ipc::Mem::PageLimit(Ipc::Mem::PageId::ioPage)) {
+        debugs(47, 5, HERE << "too few shared pages for IPC I/O left");
+        return NULL;
+    }
+
+    // The are two ways an entry can get swap_filen: our get() locked it for
+    // reading or our storeSwapOutStart() locked it for writing. Peeking at our
+    // locked entry is safe, but no support for reading a filling entry.
+    const Ipc::StoreMapSlot *slot = map->peekAtReader(e.swap_filen);
+    if (!slot)
+        return NULL; // we were writing afterall
+
+    IoState *sio = new IoState(this, &e, cbFile, cbIo, data);
+
+    sio->swap_dirn = index;
+    sio->swap_filen = e.swap_filen;
+    sio->payloadEnd = sizeof(DbCellHeader) + map->extras(e.swap_filen).payloadSize;
+    assert(sio->payloadEnd <= max_objsize); // the payload fits the slot
+
+    debugs(47,5, HERE << "dir " << index << " has old filen: " <<
+           std::setfill('0') << std::hex << std::uppercase << std::setw(8) <<
+           sio->swap_filen);
+
+    assert(slot->basics.swap_file_sz > 0);
+    assert(slot->basics.swap_file_sz == e.swap_file_sz);
+
+    sio->diskOffset = diskOffset(sio->swap_filen);
+    assert(sio->diskOffset + sio->payloadEnd <= diskOffsetLimit());
+
+    sio->file(theFile);
+    return sio;
+}
+
+void
+Rock::SwapDir::ioCompletedNotification()
+{
+    if (!theFile)
+        fatalf("Rock cache_dir failed to initialize db file: %s", filePath);
+
+    if (theFile->error())
+        fatalf("Rock cache_dir at %s failed to open db file: %s", filePath,
+               xstrerror());
+
+    debugs(47, 2, "Rock cache_dir[" << index << "] limits: " <<
+           std::setw(12) << maxSize() << " disk bytes and " <<
+           std::setw(7) << map->entryLimit() << " entries");
+
+    rebuild();
+}
+
+void
+Rock::SwapDir::closeCompleted()
+{
+    theFile = NULL;
+}
+
+void
+Rock::SwapDir::readCompleted(const char *buf, int rlen, int errflag, RefCount< ::ReadRequest> r)
+{
+    ReadRequest *request = dynamic_cast<Rock::ReadRequest*>(r.getRaw());
+    assert(request);
+    IoState::Pointer sio = request->sio;
+
+    if (errflag == DISK_OK && rlen > 0)
+        sio->offset_ += rlen;
+    assert(sio->diskOffset + sio->offset_ <= diskOffsetLimit()); // post-factum
+
+    StoreIOState::STRCB *callback = sio->read.callback;
+    assert(callback);
+    sio->read.callback = NULL;
+    void *cbdata;
+    if (cbdataReferenceValidDone(sio->read.callback_data, &cbdata))
+        callback(cbdata, r->buf, rlen, sio.getRaw());
+}
+
+void
+Rock::SwapDir::writeCompleted(int errflag, size_t rlen, RefCount< ::WriteRequest> r)
+{
+    Rock::WriteRequest *request = dynamic_cast<Rock::WriteRequest*>(r.getRaw());
+    assert(request);
+    assert(request->sio !=  NULL);
+    IoState &sio = *request->sio;
+
+    if (errflag == DISK_OK) {
+        // close, assuming we only write once; the entry gets the read lock
+        map->closeForWriting(sio.swap_filen, true);
+        // do not increment sio.offset_ because we do it in sio->write()
+    } else {
+        // Do not abortWriting here. The entry should keep the write lock
+        // instead of losing association with the store and confusing core.
+        map->free(sio.swap_filen); // will mark as unusable, just in case
+    }
+
+    assert(sio.diskOffset + sio.offset_ <= diskOffsetLimit()); // post-factum
+
+    sio.finishedWriting(errflag);
+}
+
+bool
+Rock::SwapDir::full() const
+{
+    return map && map->full();
+}
+
+// storeSwapOutFileClosed calls this nethod on DISK_NO_SPACE_LEFT,
+// but it should not happen for us
+void
+Rock::SwapDir::diskFull()
+{
+    debugs(20, DBG_IMPORTANT, "BUG: No space left with rock cache_dir: " <<
+           filePath);
+}
+
+/// purge while full(); it should be sufficient to purge just one
+void
+Rock::SwapDir::maintain()
+{
+    debugs(47,3, HERE << "cache_dir[" << index << "] guards: " <<
+           !repl << !map << !full() << StoreController::store_dirs_rebuilding);
+
+    if (!repl)
+        return; // no means (cannot find a victim)
+
+    if (!map)
+        return; // no victims (yet)
+
+    if (!full())
+        return; // no need (to find a victim)
+
+    // XXX: UFSSwapDir::maintain says we must quit during rebuild
+    if (StoreController::store_dirs_rebuilding)
+        return;
+
+    debugs(47,3, HERE << "cache_dir[" << index << "] state: " << map->full() <<
+           ' ' << currentSize() << " < " << diskOffsetLimit());
+
+    // Hopefully, we find a removable entry much sooner (TODO: use time?)
+    const int maxProbed = 10000;
+    RemovalPurgeWalker *walker = repl->PurgeInit(repl, maxProbed);
+
+    // It really should not take that long, but this will stop "infinite" loops
+    const int maxFreed = 1000;
+    int freed = 0;
+    // TODO: should we purge more than needed to minimize overheads?
+    for (; freed < maxFreed && full(); ++freed) {
+        if (StoreEntry *e = walker->Next(walker))
+            e->release(); // will call our unlink() method
+        else
+            break; // no more objects
+    }
+
+    debugs(47,2, HERE << "Rock cache_dir[" << index << "] freed " << freed <<
+           " scanned " << walker->scanned << '/' << walker->locked);
+
+    walker->Done(walker);
+
+    if (full()) {
+        debugs(47, DBG_CRITICAL, "ERROR: Rock cache_dir[" << index << "] " <<
+               "is still full after freeing " << freed << " entries. A bug?");
+    }
+}
+
+void
+Rock::SwapDir::reference(StoreEntry &e)
+{
+    debugs(47, 5, HERE << &e << ' ' << e.swap_dirn << ' ' << e.swap_filen);
+    if (repl && repl->Referenced)
+        repl->Referenced(repl, &e, &e.repl);
+}
+
+bool
+Rock::SwapDir::dereference(StoreEntry &e)
+{
+    debugs(47, 5, HERE << &e << ' ' << e.swap_dirn << ' ' << e.swap_filen);
+    if (repl && repl->Dereferenced)
+        repl->Dereferenced(repl, &e, &e.repl);
+
+    // no need to keep e in the global store_table for us; we have our own map
+    return false;
+}
+
+void
+Rock::SwapDir::unlink(StoreEntry &e)
+{
+    debugs(47, 5, HERE << e);
+    ignoreReferences(e);
+    map->free(e.swap_filen);
+    disconnect(e);
+}
+
+void
+Rock::SwapDir::trackReferences(StoreEntry &e)
+{
+    debugs(47, 5, HERE << e);
+    if (repl)
+        repl->Add(repl, &e, &e.repl);
+}
+
+
+void
+Rock::SwapDir::ignoreReferences(StoreEntry &e)
+{
+    debugs(47, 5, HERE << e);
+    if (repl)
+        repl->Remove(repl, &e, &e.repl);
+}
+
+void
+Rock::SwapDir::statfs(StoreEntry &e) const
+{
+    storeAppendPrintf(&e, "\n");
+    storeAppendPrintf(&e, "Maximum Size: %"PRIu64" KB\n", maxSize() >> 10);
+    storeAppendPrintf(&e, "Current Size: %.2f KB %.2f%%\n",
+                      currentSize() / 1024.0,
+                      Math::doublePercent(currentSize(), maxSize()));
+
+    if (map) {
+        const int limit = map->entryLimit();
+        storeAppendPrintf(&e, "Maximum entries: %9d\n", limit);
+        if (limit > 0) {
+            const int entryCount = map->entryCount();
+            storeAppendPrintf(&e, "Current entries: %9d %.2f%%\n",
+                              entryCount, (100.0 * entryCount / limit));
+
+            if (limit < 100) { // XXX: otherwise too expensive to count
+                Ipc::ReadWriteLockStats stats;
+                map->updateStats(stats);
+                stats.dump(e);
+            }
+        }
+    }
+
+    storeAppendPrintf(&e, "Pending operations: %d out of %d\n",
+                      store_open_disk_fd, Config.max_open_disk_fds);
+
+    storeAppendPrintf(&e, "Flags:");
+
+    if (flags.selected)
+        storeAppendPrintf(&e, " SELECTED");
+
+    if (flags.read_only)
+        storeAppendPrintf(&e, " READ-ONLY");
+
+    storeAppendPrintf(&e, "\n");
+
+}
+
+
+/// initializes shared memory segments used by Rock::SwapDir
+class RockSwapDirRr: public Ipc::Mem::RegisteredRunner
+{
+public:
+    /* RegisteredRunner API */
+    virtual ~RockSwapDirRr();
+
+protected:
+    virtual void create(const RunnerRegistry &);
+
+private:
+    Vector<Rock::SwapDir::DirMap::Owner *> owners;
+};
+
+RunnerRegistrationEntry(rrAfterConfig, RockSwapDirRr);
+
+
+void RockSwapDirRr::create(const RunnerRegistry &)
+{
+    Must(owners.empty());
+    for (int i = 0; i < Config.cacheSwap.n_configured; ++i) {
+        if (const Rock::SwapDir *const sd = dynamic_cast<Rock::SwapDir *>(INDEXSD(i))) {
+            Rock::SwapDir::DirMap::Owner *const owner =
+                Rock::SwapDir::DirMap::Init(sd->path, sd->entryLimitAllowed());
+            owners.push_back(owner);
+        }
+    }
+}
+
+RockSwapDirRr::~RockSwapDirRr()
+{
+    for (size_t i = 0; i < owners.size(); ++i)
+        delete owners[i];
+}
diff -u -r -N squid-3.2.0.12/src/fs/rock/RockSwapDir.h squid-3.2.0.13/src/fs/rock/RockSwapDir.h
--- squid-3.2.0.12/src/fs/rock/RockSwapDir.h	1970-01-01 12:00:00.000000000 +1200
+++ squid-3.2.0.13/src/fs/rock/RockSwapDir.h	2011-10-14 14:42:56.000000000 +1300
@@ -0,0 +1,101 @@
+#ifndef SQUID_FS_ROCK_SWAP_DIR_H
+#define SQUID_FS_ROCK_SWAP_DIR_H
+
+#include "SwapDir.h"
+#include "DiskIO/DiskFile.h"
+#include "DiskIO/IORequestor.h"
+#include "fs/rock/RockDbCell.h"
+#include "ipc/StoreMap.h"
+
+class DiskIOStrategy;
+class ReadRequest;
+class WriteRequest;
+
+namespace Rock
+{
+
+class Rebuild;
+
+/// \ingroup Rock
+class SwapDir: public ::SwapDir, public IORequestor
+{
+public:
+    SwapDir();
+    virtual ~SwapDir();
+
+    /* public ::SwapDir API */
+    virtual void reconfigure();
+    virtual StoreSearch *search(String const url, HttpRequest *);
+    virtual StoreEntry *get(const cache_key *key);
+    virtual void get(String const, STOREGETCLIENT, void * cbdata);
+    virtual void disconnect(StoreEntry &e);
+    virtual uint64_t currentSize() const;
+    virtual uint64_t currentCount() const;
+    virtual bool doReportStat() const;
+    virtual void swappedOut(const StoreEntry &e);
+
+    int64_t entryLimitHigh() const { return SwapFilenMax; } ///< Core limit
+    int64_t entryLimitAllowed() const;
+
+    typedef Ipc::StoreMapWithExtras<DbCellHeader> DirMap;
+
+protected:
+    /* protected ::SwapDir API */
+    virtual bool needsDiskStrand() const;
+    virtual void create();
+    virtual void init();
+    virtual ConfigOption *getOptionTree() const;
+    virtual bool allowOptionReconfigure(const char *const option) const;
+    virtual bool canStore(const StoreEntry &e, int64_t diskSpaceNeeded, int &load) const;
+    virtual StoreIOState::Pointer createStoreIO(StoreEntry &, StoreIOState::STFNCB *, StoreIOState::STIOCB *, void *);
+    virtual StoreIOState::Pointer openStoreIO(StoreEntry &, StoreIOState::STFNCB *, StoreIOState::STIOCB *, void *);
+    virtual void maintain();
+    virtual void diskFull();
+    virtual void reference(StoreEntry &e);
+    virtual bool dereference(StoreEntry &e);
+    virtual void unlink(StoreEntry &e);
+    virtual void statfs(StoreEntry &e) const;
+
+    /* IORequestor API */
+    virtual void ioCompletedNotification();
+    virtual void closeCompleted();
+    virtual void readCompleted(const char *buf, int len, int errflag, RefCount< ::ReadRequest>);
+    virtual void writeCompleted(int errflag, size_t len, RefCount< ::WriteRequest>);
+
+    virtual void parse(int index, char *path);
+    void parseSize(const bool reconfiguring); ///< parses anonymous cache_dir size option
+    void validateOptions(); ///< warns of configuration problems; may quit
+    bool parseTimeOption(char const *option, const char *value, int reconfiguring);
+    void dumpTimeOption(StoreEntry * e) const;
+    bool parseRateOption(char const *option, const char *value, int reconfiguring);
+    void dumpRateOption(StoreEntry * e) const;
+
+    void rebuild(); ///< starts loading and validating stored entry metadata
+    ///< used to add entries successfully loaded during rebuild
+    bool addEntry(const int fileno, const DbCellHeader &header, const StoreEntry &from);
+
+    bool full() const; ///< no more entries can be stored without purging
+    void trackReferences(StoreEntry &e); ///< add to replacement policy scope
+    void ignoreReferences(StoreEntry &e); ///< delete from repl policy scope
+
+    int64_t diskOffset(int filen) const;
+    int64_t diskOffsetLimit() const;
+    int entryLimit() const { return map->entryLimit(); }
+
+    friend class Rebuild;
+    const char *filePath; ///< location of cache storage file inside path/
+
+private:
+    DiskIOStrategy *io;
+    RefCount<DiskFile> theFile; ///< cache storage for this cache_dir
+    DirMap *map;
+
+    /* configurable options */
+    DiskFile::Config fileConfig; ///< file-level configuration options
+
+    static const int64_t HeaderSize; ///< on-disk db header size
+};
+
+} // namespace Rock
+
+#endif /* SQUID_FS_ROCK_SWAP_DIR_H */
diff -u -r -N squid-3.2.0.12/src/fs/ufs/store_dir_ufs.cc squid-3.2.0.13/src/fs/ufs/store_dir_ufs.cc
--- squid-3.2.0.12/src/fs/ufs/store_dir_ufs.cc	2011-09-16 23:37:30.000000000 +1200
+++ squid-3.2.0.13/src/fs/ufs/store_dir_ufs.cc	2011-10-14 14:42:56.000000000 +1300
@@ -57,13 +57,17 @@
  * object is able to be stored on this filesystem. UFS filesystems will
  * happily store anything as long as the LRU time isn't too small.
  */
-int
-UFSSwapDir::canStore(StoreEntry const &e)const
+bool
+UFSSwapDir::canStore(const StoreEntry &e, int64_t diskSpaceNeeded, int &load) const
 {
+    if (!SwapDir::canStore(e, diskSpaceNeeded, load))
+        return false;
+
     if (IO->shedLoad())
-        return -1;
+        return false;
 
-    return IO->load();
+    load = IO->load();
+    return true;
 }
 
 
@@ -76,14 +80,14 @@
     if (i <= 0)
         fatal("UFSSwapDir::parseSizeL1L2: invalid size value");
 
-    size_t size = i << 10;		/* Mbytes to kbytes */
+    const uint64_t size = static_cast<uint64_t>(i) << 20; // MBytes to Bytes
 
     /* just reconfigure it */
     if (reconfiguring) {
-        if (size == max_size)
-            debugs(3, 2, "Cache dir '" << path << "' size remains unchanged at " << size << " KB");
+        if (size == maxSize())
+            debugs(3, 2, "Cache dir '" << path << "' size remains unchanged at " << i << " MB");
         else
-            debugs(3, 1, "Cache dir '" << path << "' size changed to " << size << " KB");
+            debugs(3, 1, "Cache dir '" << path << "' size changed to " << i << " MB");
     }
 
     max_size = size;
@@ -106,7 +110,7 @@
  */
 
 void
-UFSSwapDir::reconfigure(int aIndex, char *aPath)
+UFSSwapDir::reconfigure()
 {
     parseSizeL1L2();
     parseOptions(1);
@@ -242,7 +246,7 @@
     createSwapSubDirs();
 }
 
-UFSSwapDir::UFSSwapDir(char const *aType, const char *anIOType) : SwapDir(aType), IO(NULL), map(file_map_create()), suggest(0), swaplog_fd (-1), currentIOOptions(new ConfigOptionVector()), ioType(xstrdup(anIOType))
+UFSSwapDir::UFSSwapDir(char const *aType, const char *anIOType) : SwapDir(aType), IO(NULL), map(file_map_create()), suggest(0), swaplog_fd (-1), currentIOOptions(new ConfigOptionVector()), ioType(xstrdup(anIOType)), cur_size(0), n_disk_objects(0)
 {
     /* modulename is only set to disk modules that are built, by configure,
      * so the Find call should never return NULL here.
@@ -312,10 +316,10 @@
     int x;
     storeAppendPrintf(&sentry, "First level subdirectories: %d\n", l1);
     storeAppendPrintf(&sentry, "Second level subdirectories: %d\n", l2);
-    storeAppendPrintf(&sentry, "Maximum Size: %"PRIu64" KB\n", max_size);
-    storeAppendPrintf(&sentry, "Current Size: %"PRIu64" KB\n", cur_size);
+    storeAppendPrintf(&sentry, "Maximum Size: %"PRIu64" KB\n", maxSize() >> 10);
+    storeAppendPrintf(&sentry, "Current Size: %.2f KB\n", currentSize() / 1024.0);
     storeAppendPrintf(&sentry, "Percent Used: %0.2f%%\n",
-                      (double)(100.0 * cur_size) / (double)max_size);
+                      Math::doublePercent(currentSize(), maxSize()));
     storeAppendPrintf(&sentry, "Filemap bits in use: %d of %d (%d%%)\n",
                       map->n_files_in_map, map->max_n_files,
                       Math::intPercent(map->n_files_in_map, map->max_n_files));
@@ -361,7 +365,7 @@
 
     RemovalPurgeWalker *walker;
 
-    double f = (double) (cur_size - minSize()) / (max_size - minSize());
+    double f = (double) (currentSize() - minSize()) / (maxSize() - minSize());
 
     f = f < 0.0 ? 0.0 : f > 1.0 ? 1.0 : f;
 
@@ -378,7 +382,7 @@
     walker = repl->PurgeInit(repl, max_scan);
 
     while (1) {
-        if (cur_size < minSize())
+        if (currentSize() < minSize())
             break;
 
         if (removed >= max_remove)
@@ -420,13 +424,15 @@
  * This routine is called whenever the last reference to an object is
  * removed, to maintain replacement information within the storage fs.
  */
-void
+bool
 UFSSwapDir::dereference(StoreEntry & e)
 {
     debugs(47, 3, "UFSSwapDir::dereference: referencing " << &e << " " << e.swap_dirn << "/" << e.swap_filen);
 
     if (repl->Dereferenced)
         repl->Dereferenced(repl, &e, &e.repl);
+
+    return true; // keep e in the global store_table
 }
 
 StoreIOState::Pointer
@@ -713,6 +719,8 @@
     e->ping_status = PING_NONE;
     EBIT_CLR(e->flags, ENTRY_VALIDATED);
     mapBitSet(e->swap_filen);
+    cur_size += fs.blksize * sizeInBlocks(e->swap_file_sz);
+    ++n_disk_objects;
     e->hashInsert(key);	/* do it after we clear KEY_PRIVATE */
     replacementAdd (e);
     return e;
@@ -1284,6 +1292,10 @@
 {
     debugs(79, 3, "storeUfsUnlink: dirno " << index  << ", fileno "<<
            std::setfill('0') << std::hex << std::uppercase << std::setw(8) << e.swap_filen);
+    if (e.swap_status == SWAPOUT_DONE && EBIT_TEST(e.flags, ENTRY_VALIDATED)) {
+        cur_size -= fs.blksize * sizeInBlocks(e.swap_file_sz);
+        --n_disk_objects;
+    }
     replacementRemove(&e);
     mapBitReset(e.swap_filen);
     UFSSwapDir::unlinkFile(e.swap_filen);
@@ -1322,7 +1334,7 @@
 void
 UFSSwapDir::dump(StoreEntry & entry) const
 {
-    storeAppendPrintf(&entry, " %"PRIu64" %d %d", (max_size >> 10), l1, l2);
+    storeAppendPrintf(&entry, " %"PRIu64" %d %d", maxSize() >> 20, l1, l2);
     dumpOptions(&entry);
 }
 
@@ -1359,6 +1371,13 @@
     IO->sync();
 }
 
+void
+UFSSwapDir::swappedOut(const StoreEntry &e)
+{
+    cur_size += fs.blksize * sizeInBlocks(e.swap_file_sz);
+    ++n_disk_objects;
+}
+
 StoreSearch *
 UFSSwapDir::search(String const url, HttpRequest *request)
 {
diff -u -r -N squid-3.2.0.12/src/fs/ufs/store_io_ufs.cc squid-3.2.0.13/src/fs/ufs/store_io_ufs.cc
--- squid-3.2.0.12/src/fs/ufs/store_io_ufs.cc	2011-09-16 23:37:30.000000000 +1200
+++ squid-3.2.0.13/src/fs/ufs/store_io_ufs.cc	2011-10-14 14:42:56.000000000 +1300
@@ -190,11 +190,11 @@
  * when it is safe to actually signal the lower layer for closing.
  */
 void
-UFSStoreState::close()
+UFSStoreState::close(int)
 {
     debugs(79, 3, "UFSStoreState::close: dirno " << swap_dirn  << ", fileno "<<
            std::setfill('0') << std::hex << std::uppercase << std::setw(8) << swap_filen);
-    tryClosing();
+    tryClosing(); // UFS does not distinguish different closure types
 }
 
 void
diff -u -r -N squid-3.2.0.12/src/fs/ufs/ufscommon.cc squid-3.2.0.13/src/fs/ufs/ufscommon.cc
--- squid-3.2.0.12/src/fs/ufs/ufscommon.cc	2011-09-16 23:37:30.000000000 +1200
+++ squid-3.2.0.13/src/fs/ufs/ufscommon.cc	2011-10-14 14:42:56.000000000 +1300
@@ -362,63 +362,14 @@
         rebuildFromDirectory();
 }
 
-struct InitStoreEntry : public unary_function<StoreMeta, void> {
-    InitStoreEntry(StoreEntry *anEntry, cache_key *aKey):what(anEntry),index(aKey) {}
-
-    void operator()(StoreMeta const &x) {
-        switch (x.getType()) {
-
-        case STORE_META_KEY:
-            assert(x.length == SQUID_MD5_DIGEST_LENGTH);
-            memcpy(index, x.value, SQUID_MD5_DIGEST_LENGTH);
-            break;
-
-        case STORE_META_STD:
-            struct old_metahdr {
-                time_t timestamp;
-                time_t lastref;
-                time_t expires;
-                time_t lastmod;
-                size_t swap_file_sz;
-                uint16_t refcount;
-                uint16_t flags;
-            } *tmp;
-            tmp = (struct old_metahdr *)x.value;
-            assert(x.length == STORE_HDR_METASIZE_OLD);
-            what->timestamp = tmp->timestamp;
-            what->lastref = tmp->lastref;
-            what->expires = tmp->expires;
-            what->lastmod = tmp->lastmod;
-            what->swap_file_sz = tmp->swap_file_sz;
-            what->refcount = tmp->refcount;
-            what->flags = tmp->flags;
-            break;
-
-        case STORE_META_STD_LFS:
-            assert(x.length == STORE_HDR_METASIZE);
-            memcpy(&what->timestamp, x.value, STORE_HDR_METASIZE);
-            break;
-
-        default:
-            break;
-        }
-    }
-
-    StoreEntry *what;
-    cache_key *index;
-};
-
 void
 RebuildState::rebuildFromDirectory()
 {
-    LOCAL_ARRAY(char, hdr_buf, SM_PAGE_SIZE);
     currentEntry(NULL);
     cache_key key[SQUID_MD5_DIGEST_LENGTH];
 
     struct stat sb;
-    int swap_hdr_len;
     int fd = -1;
-    StoreMeta *tlv_list;
     assert(this != NULL);
     debugs(47, 3, "commonUfsDirRebuildFromDirectory: DIR #" << sd->index);
 
@@ -447,114 +398,27 @@
             continue;
         }
 
-        if ((++counts.scancount & 0xFFFF) == 0)
-            debugs(47, 3, "  " << sd->path  << " " << std::setw(7) << counts.scancount  << " files opened so far.");
-        debugs(47, 9, "file_in: fd=" << fd  << " "<< std::setfill('0') << std::hex << std::uppercase << std::setw(8) << filn);
-
-
-        statCounter.syscalls.disk.reads++;
-
-        int len;
+        MemBuf buf;
+        buf.init(SM_PAGE_SIZE, SM_PAGE_SIZE);
+        if (!storeRebuildLoadEntry(fd, sd->index, buf, counts))
+            return;
 
-        if ((len = FD_READ_METHOD(fd, hdr_buf, SM_PAGE_SIZE)) < 0) {
-            debugs(47, 1, "commonUfsDirRebuildFromDirectory: read(FD " << fd << "): " << xstrerror());
-            file_close(fd);
-            store_open_disk_fd--;
-            fd = -1;
-            continue;
-        }
+        StoreEntry tmpe;
+        const bool loaded = storeRebuildParseEntry(buf, tmpe, key, counts,
+                            (int64_t)sb.st_size);
 
         file_close(fd);
         store_open_disk_fd--;
         fd = -1;
-        swap_hdr_len = 0;
-
-        StoreMetaUnpacker aBuilder(hdr_buf, len, &swap_hdr_len);
-
-        if (!aBuilder.isBufferSane()) {
-            debugs(47, 1, "commonUfsDirRebuildFromDirectory: Swap data buffer length is not sane.");
-            /* XXX shouldn't this be a call to commonUfsUnlink ? */
-            sd->unlinkFile ( filn);
-            continue;
-        }
-
-        tlv_list = aBuilder.createStoreMeta ();
 
-        if (tlv_list == NULL) {
-            debugs(47, 1, "commonUfsDirRebuildFromDirectory: failed to get meta data");
-            /* XXX shouldn't this be a call to commonUfsUnlink ? */
-            sd->unlinkFile (filn);
+        if (!loaded) {
+            // XXX: shouldn't this be a call to commonUfsUnlink?
+            sd->unlinkFile(filn); // should we unlink in all failure cases?
             continue;
         }
 
-        debugs(47, 3, "commonUfsDirRebuildFromDirectory: successful swap meta unpacking");
-        memset(key, '\0', SQUID_MD5_DIGEST_LENGTH);
-
-        StoreEntry tmpe;
-        InitStoreEntry visitor(&tmpe, key);
-        for_each(*tlv_list, visitor);
-        storeSwapTLVFree(tlv_list);
-        tlv_list = NULL;
-
-        if (storeKeyNull(key)) {
-            debugs(47, 1, "commonUfsDirRebuildFromDirectory: NULL key");
-            sd->unlinkFile(filn);
+        if (!storeRebuildKeepEntry(tmpe, key, counts))
             continue;
-        }
-
-        tmpe.key = key;
-        /* check sizes */
-
-        if (tmpe.swap_file_sz == 0) {
-            tmpe.swap_file_sz = (uint64_t) sb.st_size;
-        } else if (tmpe.swap_file_sz == (uint64_t)(sb.st_size - swap_hdr_len)) {
-            tmpe.swap_file_sz = (uint64_t) sb.st_size;
-        } else if (tmpe.swap_file_sz != (uint64_t)sb.st_size) {
-            debugs(47, 1, "commonUfsDirRebuildFromDirectory: SIZE MISMATCH " <<
-                   tmpe.swap_file_sz << "!=" <<
-                   sb.st_size);
-
-            sd->unlinkFile(filn);
-            continue;
-        }
-
-        if (EBIT_TEST(tmpe.flags, KEY_PRIVATE)) {
-            sd->unlinkFile(filn);
-            counts.badflags++;
-            continue;
-        }
-
-        /* this needs to become
-         * 1) unpack url
-         * 2) make synthetic request with headers ?? or otherwise search
-         * for a matching object in the store
-         * TODO FIXME change to new async api
-         * TODO FIXME I think there is a race condition here with the
-         * async api :
-         * store A reads in object foo, searchs for it, and finds nothing.
-         * store B reads in object foo, searchs for it, finds nothing.
-         * store A gets called back with nothing, so registers the object
-         * store B gets called back with nothing, so registers the object,
-         * which will conflict when the in core index gets around to scanning
-         * store B.
-         *
-         * this suggests that rather than searching for duplicates, the
-         * index rebuild should just assume its the most recent accurate
-         * store entry and whoever indexes the stores handles duplicates.
-         */
-        e = Store::Root().get(key);
-
-        if (e && e->lastref >= tmpe.lastref) {
-            /* key already exists, current entry is newer */
-            /* keep old, ignore new */
-            counts.dupcount++;
-            continue;
-        } else if (NULL != e) {
-            /* URL already exists, this swapfile not being used */
-            /* junk old, load new */
-            e->release();	/* release old entry */
-            counts.dupcount++;
-        }
 
         counts.objcount++;
         // tmpe.dump(5);
@@ -644,9 +508,8 @@
                 /*
                  * Make sure we don't unlink the file, it might be
                  * in use by a subsequent entry.  Also note that
-                 * we don't have to subtract from store_swap_size
-                 * because adding to store_swap_size happens in
-                 * the cleanup procedure.
+                 * we don't have to subtract from cur_size because
+                 * adding to cur_size happens in the cleanup procedure.
                  */
                 currentEntry()->expireNow();
                 currentEntry()->releaseRequest();
@@ -783,7 +646,6 @@
             (void) 0;
         }
 
-        /* update store_swap_size */
         counts.objcount++;
 
         currentEntry(sd->addDiskRestore(swapData.key,
diff -u -r -N squid-3.2.0.12/src/fs/ufs/ufscommon.h squid-3.2.0.13/src/fs/ufs/ufscommon.h
--- squid-3.2.0.12/src/fs/ufs/ufscommon.h	2011-09-16 23:37:30.000000000 +1200
+++ squid-3.2.0.13/src/fs/ufs/ufscommon.h	2011-10-14 14:42:56.000000000 +1300
@@ -62,9 +62,9 @@
     virtual void unlink(StoreEntry &);
     virtual void statfs(StoreEntry &)const;
     virtual void maintain();
-    virtual int canStore(StoreEntry const &)const;
+    virtual bool canStore(const StoreEntry &e, int64_t diskSpaceNeeded, int &load) const;
     virtual void reference(StoreEntry &);
-    virtual void dereference(StoreEntry &);
+    virtual bool dereference(StoreEntry &);
     virtual StoreIOState::Pointer createStoreIO(StoreEntry &, StoreIOState::STFNCB *, StoreIOState::STIOCB *, void *);
     virtual StoreIOState::Pointer openStoreIO(StoreEntry &, StoreIOState::STFNCB *, StoreIOState::STIOCB *, void *);
     virtual void openLog();
@@ -73,9 +73,12 @@
     virtual void writeCleanDone();
     virtual void logEntry(const StoreEntry & e, int op) const;
     virtual void parse(int index, char *path);
-    virtual void reconfigure(int, char *);
+    virtual void reconfigure();
     virtual int callback();
     virtual void sync();
+    virtual void swappedOut(const StoreEntry &e);
+    virtual uint64_t currentSize() const { return cur_size; }
+    virtual uint64_t currentCount() const { return n_disk_objects; }
 
     void unlinkFile(sfileno f);
     // move down when unlink is a virtual method
@@ -135,7 +138,8 @@
     void optionIODump(StoreEntry * e) const;
     mutable ConfigOptionVector *currentIOOptions;
     char const *ioType;
-
+    uint64_t cur_size; ///< currently used space in the storage area
+    uint64_t n_disk_objects; ///< total number of objects stored
 };
 
 #include "RefCount.h"
@@ -206,7 +210,7 @@
     void operator delete (void *);
     UFSStoreState(SwapDir * SD, StoreEntry * anEntry, STIOCB * callback_, void *callback_data_);
     ~UFSStoreState();
-    virtual void close();
+    virtual void close(int how);
     virtual void closeCompleted();
     // protected:
     virtual void ioCompletedNotification();
diff -u -r -N squid-3.2.0.12/src/ftp.cc squid-3.2.0.13/src/ftp.cc
--- squid-3.2.0.12/src/ftp.cc	2011-09-16 23:37:30.000000000 +1200
+++ squid-3.2.0.13/src/ftp.cc	2011-10-14 14:42:56.000000000 +1300
@@ -669,6 +669,9 @@
 {
     debugs(9, 4, HERE << io.conn << ": '" << entry->url() << "'" );
 
+    if (abortOnBadEntry("entry went bad while waiting for a timeout"))
+        return;
+
     if (SENT_PASV == state && io.conn->fd == data.conn->fd) {
         /* stupid ftp.netscape.com */
         flags.pasv_supported = false;
diff -u -r -N squid-3.2.0.12/src/globals.h squid-3.2.0.13/src/globals.h
--- squid-3.2.0.12/src/globals.h	2011-09-16 23:37:30.000000000 +1200
+++ squid-3.2.0.13/src/globals.h	2011-10-14 14:42:56.000000000 +1300
@@ -108,7 +108,6 @@
     extern int starting_up;	/* 1 */
     extern int shutting_down;	/* 0 */
     extern int reconfiguring;	/* 0 */
-    extern unsigned long store_swap_size;	/* 0 */
     extern time_t hit_only_mode_until;	/* 0 */
     extern StatCounters statCounter;
     extern double request_failure_ratio;	/* 0.0 */
diff -u -r -N squid-3.2.0.12/src/HelperChildConfig.cc squid-3.2.0.13/src/HelperChildConfig.cc
--- squid-3.2.0.12/src/HelperChildConfig.cc	2011-09-16 23:37:30.000000000 +1200
+++ squid-3.2.0.13/src/HelperChildConfig.cc	2011-10-14 14:42:56.000000000 +1300
@@ -4,22 +4,24 @@
 
 #include <string.h>
 
-HelperChildConfig::HelperChildConfig(const unsigned int m, const unsigned int s, const unsigned int i, const unsigned int cc) :
+HelperChildConfig::HelperChildConfig(const unsigned int m):
         n_max(m),
-        n_startup(s),
-        n_idle(i),
-        concurrency(cc),
+        n_startup(0),
+        n_idle(1),
+        concurrency(0),
         n_running(0),
         n_active(0)
 {}
 
-HelperChildConfig::~HelperChildConfig()
-{}
-
 HelperChildConfig &
-HelperChildConfig::operator =(const HelperChildConfig &rhs)
+HelperChildConfig::updateLimits(const HelperChildConfig &rhs)
 {
-    memcpy(this, &rhs, sizeof(HelperChildConfig));
+    // Copy the limits only.
+    // Preserve the local state values (n_running and n_active)
+    n_max = rhs.n_max;
+    n_startup = rhs.n_startup;
+    n_idle = rhs.n_idle;
+    concurrency = rhs.concurrency;
     return *this;
 }
 
diff -u -r -N squid-3.2.0.12/src/HelperChildConfig.h squid-3.2.0.13/src/HelperChildConfig.h
--- squid-3.2.0.12/src/HelperChildConfig.h	2011-09-16 23:37:30.000000000 +1200
+++ squid-3.2.0.13/src/HelperChildConfig.h	2011-10-14 14:42:56.000000000 +1300
@@ -10,11 +10,9 @@
 class HelperChildConfig
 {
 public:
-    HelperChildConfig(const unsigned int m=0, const unsigned int s=0, const unsigned int i=1, const unsigned int cc=0);
-    ~HelperChildConfig();
-    HelperChildConfig &operator =(const HelperChildConfig &rhs);
+    explicit HelperChildConfig(const unsigned int m = 0);
 
-    /*
+    /**
      * When new helpers are needed call this to find out how many more
      * we are allowed to start.
      * \retval 0       No more helpers may be started right now.
@@ -24,6 +22,13 @@
     int needNew() const;
     void parseConfig();
 
+    /**
+     * Update an existing set of details with new start/max/idle/concurrent limits.
+     * This is for parsing new child settings into an object incrementally then updating
+     * the running set without loosing any of the active state or causing races.
+     */
+    HelperChildConfig &updateLimits(const HelperChildConfig &rhs);
+
     /* values from squid.conf */
 public:
 
@@ -55,7 +60,6 @@
     unsigned int concurrency;
 
     /* derived from active operations */
-public:
 
     /**
      * Total helper children objects currently existing.
diff -u -r -N squid-3.2.0.12/src/http.cc squid-3.2.0.13/src/http.cc
--- squid-3.2.0.12/src/http.cc	2011-09-16 23:37:30.000000000 +1200
+++ squid-3.2.0.13/src/http.cc	2011-10-14 14:42:56.000000000 +1300
@@ -58,6 +58,7 @@
 #include "http.h"
 #include "HttpControlMsg.h"
 #include "HttpHdrContRange.h"
+#include "HttpHdrCc.h"
 #include "HttpHdrSc.h"
 #include "HttpHdrScTarget.h"
 #include "HttpReply.h"
@@ -330,7 +331,6 @@
 {
     HttpReply const *rep = finalReply();
     HttpHeader const *hdr = &rep->header;
-    const int cc_mask = (rep->cache_control) ? rep->cache_control->mask : 0;
     const char *v;
 #if USE_HTTP_VIOLATIONS
 
@@ -353,22 +353,23 @@
 
     // RFC 2616: do not cache replies to responses with no-store CC directive
     if (request && request->cache_control &&
-            EBIT_TEST(request->cache_control->mask, CC_NO_STORE) &&
+            request->cache_control->noStore() &&
             !REFRESH_OVERRIDE(ignore_no_store))
         return 0;
 
-    if (!ignoreCacheControl) {
-        if (EBIT_TEST(cc_mask, CC_PRIVATE)) {
+    if (!ignoreCacheControl && request->cache_control != NULL) {
+        const HttpHdrCc* cc=request->cache_control;
+        if (cc->Private()) {
             if (!REFRESH_OVERRIDE(ignore_private))
                 return 0;
         }
 
-        if (EBIT_TEST(cc_mask, CC_NO_CACHE)) {
+        if (cc->noCache()) {
             if (!REFRESH_OVERRIDE(ignore_no_cache))
                 return 0;
         }
 
-        if (EBIT_TEST(cc_mask, CC_NO_STORE)) {
+        if (cc->noStore()) {
             if (!REFRESH_OVERRIDE(ignore_no_store))
                 return 0;
         }
@@ -381,7 +382,7 @@
          * RFC 2068, sec 14.9.4
          */
 
-        if (!EBIT_TEST(cc_mask, CC_PUBLIC)) {
+        if (!request->cache_control->Public()) {
             if (!REFRESH_OVERRIDE(ignore_auth))
                 return 0;
         }
@@ -925,9 +926,10 @@
 no_cache:
 
     if (!ignoreCacheControl && rep->cache_control) {
-        if (EBIT_TEST(rep->cache_control->mask, CC_PROXY_REVALIDATE) ||
-                EBIT_TEST(rep->cache_control->mask, CC_MUST_REVALIDATE) ||
-                EBIT_TEST(rep->cache_control->mask, CC_S_MAXAGE))
+        if (rep->cache_control->proxyRevalidate() ||
+                rep->cache_control->mustRevalidate() ||
+                rep->cache_control->hasSMaxAge()
+           )
             EBIT_SET(entry->flags, ENTRY_REVALIDATE);
     }
 
@@ -1185,7 +1187,7 @@
         if (!continueAfterParsingHeader()) // parsing error or need more data
             return; // TODO: send errors to ICAP
 
-        adaptOrFinalizeReply();
+        adaptOrFinalizeReply(); // may write to, abort, or "close" the entry
     }
 
     // kick more reads if needed and/or process the response body, if any
@@ -1354,14 +1356,16 @@
      * That means header content has been removed from readBuf and
      * it contains only body data.
      */
-    if (flags.chunked) {
-        if (!decodeAndWriteReplyBody()) {
-            flags.do_next_read = 0;
-            serverComplete();
-            return;
-        }
-    } else
-        writeReplyBody();
+    if (entry->isAccepting()) {
+        if (flags.chunked) {
+            if (!decodeAndWriteReplyBody()) {
+                flags.do_next_read = 0;
+                serverComplete();
+                return;
+            }
+        } else
+            writeReplyBody();
+    }
 
     if (EBIT_TEST(entry->flags, ENTRY_ABORTED)) {
         /*
@@ -1758,7 +1762,7 @@
         HttpHdrCc *cc = hdr_in->getCc();
 
         if (!cc)
-            cc = httpHdrCcCreate();
+            cc = new HttpHdrCc();
 
 #if 0 /* see bug 2330 */
         /* Set no-cache if determined needed but not found */
@@ -1767,20 +1771,20 @@
 #endif
 
         /* Add max-age only without no-cache */
-        if (!EBIT_TEST(cc->mask, CC_MAX_AGE) && !EBIT_TEST(cc->mask, CC_NO_CACHE)) {
+        if (!cc->hasMaxAge() && !cc->noCache()) {
             const char *url =
                 entry ? entry->url() : urlCanonical(request);
-            httpHdrCcSetMaxAge(cc, getMaxAge(url));
+            cc->maxAge(getMaxAge(url));
 
         }
 
         /* Enforce sibling relations */
         if (flags.only_if_cached)
-            EBIT_SET(cc->mask, CC_ONLY_IF_CACHED);
+            cc->onlyIfCached(true);
 
         hdr_out->putCc(cc);
 
-        httpHdrCcDestroy(cc);
+        delete cc;
     }
 
     /* maybe append Connection: keep-alive */
diff -u -r -N squid-3.2.0.12/src/HttpHdrCc.cc squid-3.2.0.13/src/HttpHdrCc.cc
--- squid-3.2.0.12/src/HttpHdrCc.cc	2011-09-16 23:37:30.000000000 +1200
+++ squid-3.2.0.13/src/HttpHdrCc.cc	2011-10-14 14:42:56.000000000 +1300
@@ -1,9 +1,6 @@
-
 /*
- * $Id$
  *
  * DEBUG: section 65    HTTP Cache Control Header
- * AUTHOR: Alex Rousskov
  *
  * SQUID Web Proxy Cache          http://www.squid-cache.org/
  * ----------------------------------------------------------
@@ -34,30 +31,45 @@
  */
 
 #include "squid.h"
+#include "base/StringArea.h"
 #include "Store.h"
 #include "HttpHeader.h"
+#include "HttpHdrCc.h"
 
-/* this table is used for parsing cache control header */
-static const HttpHeaderFieldAttrs CcAttrs[CC_ENUM_END] = {
-    {"public", (http_hdr_type)CC_PUBLIC},
-
-    {"private", (http_hdr_type)CC_PRIVATE},
-    {"no-cache", (http_hdr_type)CC_NO_CACHE},
-    {"no-store", (http_hdr_type)CC_NO_STORE},
-    {"no-transform", (http_hdr_type)CC_NO_TRANSFORM},
-    {"must-revalidate", (http_hdr_type)CC_MUST_REVALIDATE},
-    {"proxy-revalidate", (http_hdr_type)CC_PROXY_REVALIDATE},
-    {"only-if-cached", (http_hdr_type)CC_ONLY_IF_CACHED},
-    {"max-age", (http_hdr_type)CC_MAX_AGE},
-    {"s-maxage", (http_hdr_type)CC_S_MAXAGE},
-    {"max-stale", (http_hdr_type)CC_MAX_STALE},
-    {"stale-if-error", (http_hdr_type)CC_STALE_IF_ERROR},
-    {"min-fresh", (http_hdr_type)CC_MIN_FRESH},
-    {"Other,", (http_hdr_type)CC_OTHER}	/* ',' will protect from matches */
+#if HAVE_MAP
+#include <map>
+#endif
+
+/* a row in the table used for parsing cache control header and statistics */
+typedef struct {
+    const char *name;
+    http_hdr_cc_type id;
+    HttpHeaderFieldStat stat;
+} HttpHeaderCcFields;
+
+/* order must match that of enum http_hdr_cc_type. The constraint is verified at initialization time */
+static HttpHeaderCcFields CcAttrs[CC_ENUM_END] = {
+    {"public", CC_PUBLIC},
+    {"private", CC_PRIVATE},
+    {"no-cache", CC_NO_CACHE},
+    {"no-store", CC_NO_STORE},
+    {"no-transform", CC_NO_TRANSFORM},
+    {"must-revalidate", CC_MUST_REVALIDATE},
+    {"proxy-revalidate", CC_PROXY_REVALIDATE},
+    {"max-age", CC_MAX_AGE},
+    {"s-maxage", CC_S_MAXAGE},
+    {"max-stale", CC_MAX_STALE},
+    {"min-fresh", CC_MIN_FRESH},
+    {"only-if-cached", CC_ONLY_IF_CACHED},
+    {"stale-if-error", CC_STALE_IF_ERROR},
+    {"Other,", CC_OTHER} /* ',' will protect from matches */
 };
 
-HttpHeaderFieldInfo *CcFieldsInfo = NULL;
+/// Map an header name to its type, to expedite parsing
+typedef std::map<const StringArea,http_hdr_cc_type> CcNameToIdMap_t;
+static CcNameToIdMap_t CcNameToIdMap;
 
+/// used to walk a table of http_header_cc_type structs
 http_hdr_cc_type &operator++ (http_hdr_cc_type &aHeader)
 {
     int tmp = (int)aHeader;
@@ -66,52 +78,34 @@
 }
 
 
-/* local prototypes */
-static int httpHdrCcParseInit(HttpHdrCc * cc, const String * str);
-
-
-/* module initialization */
-
+/// Module initialization hook
 void
 httpHdrCcInitModule(void)
 {
-    CcFieldsInfo = httpHeaderBuildFieldsInfo(CcAttrs, CC_ENUM_END);
+    /* build lookup and accounting structures */
+    for (int32_t i = 0; i < CC_ENUM_END; ++i) {
+        const HttpHeaderCcFields &f=CcAttrs[i];
+        assert(i == f.id); /* verify assumption: the id is the key into the array */
+        const StringArea k(f.name,strlen(f.name));
+        CcNameToIdMap[k]=f.id;
+    }
 }
 
+/// Module cleanup hook.
 void
 httpHdrCcCleanModule(void)
 {
-    httpHeaderDestroyFieldsInfo(CcFieldsInfo, CC_ENUM_END);
-    CcFieldsInfo = NULL;
-}
-
-/* implementation */
-
-HttpHdrCc *
-httpHdrCcCreate(void)
-{
-    HttpHdrCc *cc = (HttpHdrCc *)memAllocate(MEM_HTTP_HDR_CC);
-    cc->max_age = cc->s_maxage = cc->max_stale = cc->min_fresh = -1;
-    return cc;
+    // HdrCcNameToIdMap is self-cleaning
 }
 
-/* creates an cc object from a 0-terminating string */
-HttpHdrCc *
-httpHdrCcParseCreate(const String * str)
+void
+HttpHdrCc::clear()
 {
-    HttpHdrCc *cc = httpHdrCcCreate();
-
-    if (!httpHdrCcParseInit(cc, str)) {
-        httpHdrCcDestroy(cc);
-        cc = NULL;
-    }
-
-    return cc;
+    *this=HttpHdrCc();
 }
 
-/* parses a 0-terminating string and inits cc */
-static int
-httpHdrCcParseInit(HttpHdrCc * cc, const String * str)
+bool
+HttpHdrCc::parse(const String & str)
 {
     const char *item;
     const char *p;		/* '=' parameter */
@@ -119,11 +113,10 @@
     http_hdr_cc_type type;
     int ilen;
     int nlen;
-    assert(cc && str);
 
     /* iterate through comma separated list */
 
-    while (strListGetItem(str, ',', &item, &ilen, &pos)) {
+    while (strListGetItem(&str, ',', &item, &ilen, &pos)) {
         /* isolate directive name */
 
         if ((p = (const char *)memchr(item, '=', ilen)) && (p - item < ilen))
@@ -132,82 +125,99 @@
             nlen = ilen;
 
         /* find type */
-        type = (http_hdr_cc_type ) httpHeaderIdByName(item, nlen,
-                CcFieldsInfo, CC_ENUM_END);
-
-        if (type < 0) {
-            debugs(65, 2, "hdr cc: unknown cache-directive: near '" << item << "' in '" << str << "'");
-            type = CC_OTHER;
-        }
+        const CcNameToIdMap_t::const_iterator i=CcNameToIdMap.find(StringArea(item,nlen));
+        if (i==CcNameToIdMap.end())
+            type=CC_OTHER;
+        else
+            type=i->second;
 
         // ignore known duplicate directives
-        if (EBIT_TEST(cc->mask, type)) {
+        if (isSet(type)) {
             if (type != CC_OTHER) {
                 debugs(65, 2, "hdr cc: ignoring duplicate cache-directive: near '" << item << "' in '" << str << "'");
-                CcFieldsInfo[type].stat.repCount++;
+                ++CcAttrs[type].stat.repCount;
                 continue;
             }
-        } else {
-            EBIT_SET(cc->mask, type);
         }
 
-        /* post-processing special cases */
+        /* special-case-parsing and attribute-setting */
         switch (type) {
 
         case CC_MAX_AGE:
-
-            if (!p || !httpHeaderParseInt(p, &cc->max_age)) {
+            if (!p || !httpHeaderParseInt(p, &max_age) || max_age < 0) {
                 debugs(65, 2, "cc: invalid max-age specs near '" << item << "'");
-                cc->max_age = -1;
-                EBIT_CLR(cc->mask, type);
+                clearMaxAge();
+            } else {
+                setMask(type,true);
             }
-
             break;
 
         case CC_S_MAXAGE:
-
-            if (!p || !httpHeaderParseInt(p, &cc->s_maxage)) {
+            if (!p || !httpHeaderParseInt(p, &s_maxage) || s_maxage < 0) {
                 debugs(65, 2, "cc: invalid s-maxage specs near '" << item << "'");
-                cc->s_maxage = -1;
-                EBIT_CLR(cc->mask, type);
+                clearSMaxAge();
+            } else {
+                setMask(type,true);
             }
-
             break;
 
         case CC_MAX_STALE:
-
-            if (!p || !httpHeaderParseInt(p, &cc->max_stale)) {
+            if (!p || !httpHeaderParseInt(p, &max_stale) || max_stale < 0) {
                 debugs(65, 2, "cc: max-stale directive is valid without value");
-                cc->max_stale = -1;
+                maxStale(MAX_STALE_ANY);
+            } else {
+                setMask(type,true);
             }
-
             break;
 
         case CC_MIN_FRESH:
-
-            if (!p || !httpHeaderParseInt(p, &cc->min_fresh)) {
+            if (!p || !httpHeaderParseInt(p, &min_fresh) || min_fresh < 0) {
                 debugs(65, 2, "cc: invalid min-fresh specs near '" << item << "'");
-                cc->min_fresh = -1;
-                EBIT_CLR(cc->mask, type);
+                clearMinFresh();
+            } else {
+                setMask(type,true);
             }
-
             break;
 
         case CC_STALE_IF_ERROR:
-            if (!p || !httpHeaderParseInt(p, &cc->stale_if_error)) {
+            if (!p || !httpHeaderParseInt(p, &stale_if_error) || stale_if_error < 0) {
                 debugs(65, 2, "cc: invalid stale-if-error specs near '" << item << "'");
-                cc->stale_if_error = -1;
-                EBIT_CLR(cc->mask, type);
+                clearStaleIfError();
+            } else {
+                setMask(type,true);
             }
             break;
 
-        case CC_OTHER:
-
-            if (cc->other.size())
-                cc->other.append(", ");
+        case CC_PUBLIC:
+            Public(true);
+            break;
+        case CC_PRIVATE:
+            Private(true);
+            break;
+        case CC_NO_CACHE:
+            noCache(true);
+            break;
+        case CC_NO_STORE:
+            noStore(true);
+            break;
+        case CC_NO_TRANSFORM:
+            noTransform(true);
+            break;
+        case CC_MUST_REVALIDATE:
+            mustRevalidate(true);
+            break;
+        case CC_PROXY_REVALIDATE:
+            proxyRevalidate(true);
+            break;
+        case CC_ONLY_IF_CACHED:
+            onlyIfCached(true);
+            break;
 
-            cc->other.append(item, ilen);
+        case CC_OTHER:
+            if (other.size())
+                other.append(", ");
 
+            other.append(item, ilen);
             break;
 
         default:
@@ -216,95 +226,55 @@
         }
     }
 
-    return cc->mask != 0;
+    return (mask != 0);
 }
 
 void
-httpHdrCcDestroy(HttpHdrCc * cc)
-{
-    assert(cc);
-
-    if (cc->other.defined())
-        cc->other.clean();
-
-    memFree(cc, MEM_HTTP_HDR_CC);
-}
-
-HttpHdrCc *
-httpHdrCcDup(const HttpHdrCc * cc)
+HttpHdrCc::packInto(Packer * p) const
 {
-    HttpHdrCc *dup;
-    assert(cc);
-    dup = httpHdrCcCreate();
-    dup->mask = cc->mask;
-    dup->max_age = cc->max_age;
-    dup->s_maxage = cc->s_maxage;
-    dup->max_stale = cc->max_stale;
-    dup->min_fresh = cc->min_fresh;
-    return dup;
-}
+    // optimization: if the mask is empty do nothing
+    if (mask==0)
+        return;
 
-void
-httpHdrCcPackInto(const HttpHdrCc * cc, Packer * p)
-{
     http_hdr_cc_type flag;
     int pcount = 0;
-    assert(cc && p);
+    assert(p);
 
     for (flag = CC_PUBLIC; flag < CC_ENUM_END; ++flag) {
-        if (EBIT_TEST(cc->mask, flag) && flag != CC_OTHER) {
-
-            /* print option name */
-            packerPrintf(p, (pcount ? ", " SQUIDSTRINGPH : SQUIDSTRINGPH),
-                         SQUIDSTRINGPRINT(CcFieldsInfo[flag].name));
-
-            /* handle options with values */
-
-            if (flag == CC_MAX_AGE)
-                packerPrintf(p, "=%d", (int) cc->max_age);
+        if (isSet(flag) && flag != CC_OTHER) {
 
-            if (flag == CC_S_MAXAGE)
-                packerPrintf(p, "=%d", (int) cc->s_maxage);
+            /* print option name for all options */
+            packerPrintf(p, (pcount ? ", %s": "%s") , CcAttrs[flag].name);
 
-            if (flag == CC_MAX_STALE && cc->max_stale >= 0)
-                packerPrintf(p, "=%d", (int) cc->max_stale);
-
-            if (flag == CC_MIN_FRESH)
-                packerPrintf(p, "=%d", (int) cc->min_fresh);
+            /* for all options having values, "=value" after the name */
+            switch (flag) {
+            case CC_MAX_AGE:
+                packerPrintf(p, "=%d", (int) maxAge());
+                break;
+            case CC_S_MAXAGE:
+                packerPrintf(p, "=%d", (int) sMaxAge());
+                break;
+            case CC_MAX_STALE:
+                /* max-stale's value is optional.
+                  If we didn't receive it, don't send it */
+                if (maxStale()!=MAX_STALE_ANY)
+                    packerPrintf(p, "=%d", (int) maxStale());
+                break;
+            case CC_MIN_FRESH:
+                packerPrintf(p, "=%d", (int) minFresh());
+                break;
+            default:
+                /* do nothing, directive was already printed */
+                break;
+            }
 
-            pcount++;
+            ++pcount;
         }
     }
 
-    if (cc->other.size() != 0)
+    if (other.size() != 0)
         packerPrintf(p, (pcount ? ", " SQUIDSTRINGPH : SQUIDSTRINGPH),
-                     SQUIDSTRINGPRINT(cc->other));
-}
-
-/* negative max_age will clean old max_Age setting */
-void
-httpHdrCcSetMaxAge(HttpHdrCc * cc, int max_age)
-{
-    assert(cc);
-    cc->max_age = max_age;
-
-    if (max_age >= 0)
-        EBIT_SET(cc->mask, CC_MAX_AGE);
-    else
-        EBIT_CLR(cc->mask, CC_MAX_AGE);
-}
-
-/* negative s_maxage will clean old s-maxage setting */
-void
-httpHdrCcSetSMaxAge(HttpHdrCc * cc, int s_maxage)
-{
-    assert(cc);
-    cc->s_maxage = s_maxage;
-
-    if (s_maxage >= 0)
-        EBIT_SET(cc->mask, CC_S_MAXAGE);
-    else
-        EBIT_CLR(cc->mask, CC_S_MAXAGE);
+                     SQUIDSTRINGPRINT(other));
 }
 
 void
@@ -314,7 +284,7 @@
     assert(cc);
 
     for (c = CC_PUBLIC; c < CC_ENUM_END; ++c)
-        if (EBIT_TEST(cc->mask, c))
+        if (cc->isSet(c))
             statHistCount(hist, c);
 }
 
@@ -324,9 +294,13 @@
     extern const HttpHeaderStat *dump_stat;	/* argh! */
     const int id = (int) val;
     const int valid_id = id >= 0 && id < CC_ENUM_END;
-    const char *name = valid_id ? CcFieldsInfo[id].name.termedBuf() : "INVALID";
+    const char *name = valid_id ? CcAttrs[id].name : "INVALID";
 
     if (count || valid_id)
         storeAppendPrintf(sentry, "%2d\t %-20s\t %5d\t %6.2f\n",
                           id, name, count, xdiv(count, dump_stat->ccParsedCount));
 }
+
+#if !_USE_INLINE_
+#include "HttpHdrCc.cci"
+#endif
diff -u -r -N squid-3.2.0.12/src/HttpHdrCc.cci squid-3.2.0.13/src/HttpHdrCc.cci
--- squid-3.2.0.12/src/HttpHdrCc.cci	1970-01-01 12:00:00.000000000 +1200
+++ squid-3.2.0.13/src/HttpHdrCc.cci	2011-10-14 14:42:56.000000000 +1300
@@ -0,0 +1,65 @@
+/*
+ *
+ * DEBUG: section 65    HTTP Cache Control Header
+ *
+ * SQUID Web Proxy Cache          http://www.squid-cache.org/
+ * ----------------------------------------------------------
+ *
+ *  Squid is the result of efforts by numerous individuals from
+ *  the Internet community; see the CONTRIBUTORS file for full
+ *  details.   Many organizations have provided support for Squid's
+ *  development; see the SPONSORS file for full details.  Squid is
+ *  Copyrighted (C) 2001 by the Regents of the University of
+ *  California; see the COPYRIGHT file for full details.  Squid
+ *  incorporates software developed and/or copyrighted by other
+ *  sources; see the CREDITS file for full details.
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111, USA.
+ *
+ */
+bool
+HttpHdrCc::isSet(http_hdr_cc_type id) const
+{
+    assert(id>=CC_PUBLIC && id < CC_ENUM_END);
+    return EBIT_TEST(mask,id);
+}
+
+void
+HttpHdrCc::setMask(http_hdr_cc_type id, bool newval)
+{
+    if (newval)
+        EBIT_SET(mask,id);
+    else
+        EBIT_CLR(mask,id);
+}
+
+/// set a data member to a new value, and set the corresponding mask-bit.
+/// if setting is false, then the mask-bit is cleared.
+void
+HttpHdrCc::setValue(int32_t &value, int32_t new_value, http_hdr_cc_type hdr, bool setting)
+{
+    if (setting) {
+        if (new_value < 0) {
+            debugs(65,3,HERE << "rejecting negative-value Cache-Control directive " << hdr
+                   << " value " << new_value );
+            return;
+        }
+    } else {
+        new_value=-1; //rely on the convention that "unknown" is -1
+    }
+
+    value=new_value;
+    setMask(hdr,setting);
+}
diff -u -r -N squid-3.2.0.12/src/HttpHdrCc.h squid-3.2.0.13/src/HttpHdrCc.h
--- squid-3.2.0.12/src/HttpHdrCc.h	1970-01-01 12:00:00.000000000 +1200
+++ squid-3.2.0.13/src/HttpHdrCc.h	2011-10-14 14:42:56.000000000 +1300
@@ -0,0 +1,184 @@
+/*
+ * HttpHdrCc.h
+ *
+ *
+ * SQUID Web Proxy Cache          http://www.squid-cache.org/
+ * ----------------------------------------------------------
+ *
+ *  Squid is the result of efforts by numerous individuals from
+ *  the Internet community; see the CONTRIBUTORS file for full
+ *  details.   Many organizations have provided support for Squid's
+ *  development; see the SPONSORS file for full details.  Squid is
+ *  Copyrighted (C) 2001 by the Regents of the University of
+ *  California; see the COPYRIGHT file for full details.  Squid
+ *  incorporates software developed and/or copyrighted by other
+ *  sources; see the CREDITS file for full details.
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111, USA.
+ */
+
+#ifndef SQUID_HTTPHDRCC_H
+#define SQUID_HTTPHDRCC_H
+
+#include "config.h"
+#include "MemPool.h"
+#include "SquidString.h"
+
+/** Http Cache-Control header representation
+ *
+ * Store and parse the Cache-Control HTTP header.
+ */
+class HttpHdrCc
+{
+
+public:
+    static const int32_t MAX_AGE_UNKNOWN=-1; //max-age is unset
+    static const int32_t S_MAXAGE_UNKNOWN=-1; //s-maxage is unset
+    static const int32_t MAX_STALE_UNKNOWN=-1; //max-stale is unset
+    ///used to mark a valueless Cache-Control: max-stale directive, which instructs
+    /// us to treat responses of any age as fresh
+    static const int32_t MAX_STALE_ANY=0x7fffffff;
+    static const int32_t STALE_IF_ERROR_UNKNOWN=-1; //stale_if_error is unset
+    static const int32_t MIN_FRESH_UNKNOWN=-1; //min_fresh is unset
+
+    HttpHdrCc() :
+            mask(0), max_age(MAX_AGE_UNKNOWN), s_maxage(S_MAXAGE_UNKNOWN),
+            max_stale(MAX_STALE_UNKNOWN), stale_if_error(STALE_IF_ERROR_UNKNOWN),
+            min_fresh(MIN_FRESH_UNKNOWN) {}
+
+    /// reset data-members to default state
+    void clear();
+
+    /// parse a header-string and fill in appropriate values.
+    bool parse(const String & s);
+
+    //manipulation for Cache-Control: public header
+    bool hasPublic() const {return isSet(CC_PUBLIC);}
+    bool Public() const {return isSet(CC_PUBLIC);}
+    void Public(bool v) {setMask(CC_PUBLIC,v);}
+    void clearPublic() {setMask(CC_PUBLIC,false);}
+
+    //manipulation for Cache-Control: private header
+    bool hasPrivate() const {return isSet(CC_PRIVATE);}
+    bool Private() const {return isSet(CC_PRIVATE);}
+    void Private(bool v) {setMask(CC_PRIVATE,v);}
+    void clearPrivate() {setMask(CC_PRIVATE,false);}
+
+    //manipulation for Cache-Control: no-cache header
+    bool hasNoCache() const {return isSet(CC_NO_CACHE);}
+    bool noCache() const {return isSet(CC_NO_CACHE);}
+    void noCache(bool v) {setMask(CC_NO_CACHE,v);}
+    void clearNoCache() {setMask(CC_NO_CACHE,false);}
+
+    //manipulation for Cache-Control: no-store header
+    bool hasNoStore() const {return isSet(CC_NO_STORE);}
+    bool noStore() const {return isSet(CC_NO_STORE);}
+    void noStore(bool v) {setMask(CC_NO_STORE,v);}
+    void clearNoStore() {setMask(CC_NO_STORE,false);}
+
+    //manipulation for Cache-Control: no-transform header
+    bool hasNoTransform() const {return isSet(CC_NO_TRANSFORM);}
+    bool noTransform() const {return isSet(CC_NO_TRANSFORM);}
+    void noTransform(bool v) {setMask(CC_NO_TRANSFORM,v);}
+    void clearNoTransform() {setMask(CC_NO_TRANSFORM,false);}
+
+    //manipulation for Cache-Control: must-revalidate header
+    bool hasMustRevalidate() const {return isSet(CC_MUST_REVALIDATE);}
+    bool mustRevalidate() const {return isSet(CC_MUST_REVALIDATE);}
+    void mustRevalidate(bool v) {setMask(CC_MUST_REVALIDATE,v);}
+    void clearMustRevalidate() {setMask(CC_MUST_REVALIDATE,false);}
+
+    //manipulation for Cache-Control: proxy-revalidate header
+    bool hasProxyRevalidate() const {return isSet(CC_PROXY_REVALIDATE);}
+    bool proxyRevalidate() const {return isSet(CC_PROXY_REVALIDATE);}
+    void proxyRevalidate(bool v) {setMask(CC_PROXY_REVALIDATE,v);}
+    void clearProxyRevalidate() {setMask(CC_PROXY_REVALIDATE,false);}
+
+    //manipulation for Cache-Control: max-age header
+    bool hasMaxAge() const {return isSet(CC_MAX_AGE);}
+    int32_t maxAge() const { return max_age;}
+    void maxAge(int32_t v) {setValue(max_age,v,CC_MAX_AGE); }
+    void clearMaxAge() {setValue(max_age,MAX_AGE_UNKNOWN,CC_MAX_AGE,false);}
+
+    //manipulation for Cache-Control: s-maxage header
+    bool hasSMaxAge() const {return isSet(CC_S_MAXAGE);}
+    int32_t sMaxAge() const { return s_maxage;}
+    void sMaxAge(int32_t v) {setValue(s_maxage,v,CC_S_MAXAGE); }
+    void clearSMaxAge() {setValue(s_maxage,MAX_AGE_UNKNOWN,CC_S_MAXAGE,false);}
+
+    //manipulation for Cache-Control: max-stale header
+    bool hasMaxStale() const {return isSet(CC_MAX_STALE);}
+    int32_t maxStale() const { return max_stale;}
+    // max-stale has a special value (MAX_STALE_ANY) which correspond to having
+    // the directive without a numeric specification, and directs to consider the object
+    // as always-expired.
+    void maxStale(int32_t v) {setValue(max_stale,v,CC_MAX_STALE);}
+    void clearMaxStale() {setValue(max_stale,MAX_STALE_UNKNOWN,CC_MAX_STALE,false);}
+
+    //manipulation for Cache-Control:min-fresh header
+    bool hasMinFresh() const {return isSet(CC_MIN_FRESH);}
+    int32_t minFresh() const { return min_fresh;}
+    void minFresh(int32_t v) {if (v < 0) return; setValue(min_fresh,v,CC_MIN_FRESH); }
+    void clearMinFresh() {setValue(min_fresh,MIN_FRESH_UNKNOWN,CC_MIN_FRESH,false);}
+
+    //manipulation for Cache-Control: only-if-cached header
+    bool hasOnlyIfCached() const {return isSet(CC_ONLY_IF_CACHED);}
+    bool onlyIfCached() const {return isSet(CC_ONLY_IF_CACHED);}
+    void onlyIfCached(bool v) {setMask(CC_ONLY_IF_CACHED,v);}
+    void clearOnlyIfCached() {setMask(CC_ONLY_IF_CACHED,false);}
+
+    //manipulation for Cache-Control: stale-if-error header
+    bool hasStaleIfError() const {return isSet(CC_STALE_IF_ERROR);}
+    int32_t staleIfError() const { return stale_if_error;}
+    void staleIfError(int32_t v) {setValue(stale_if_error,v,CC_STALE_IF_ERROR); }
+    void clearStaleIfError() {setValue(stale_if_error,STALE_IF_ERROR_UNKNOWN,CC_STALE_IF_ERROR,false);}
+
+    /// check whether the attribute value supplied by id is set
+    _SQUID_INLINE_ bool isSet(http_hdr_cc_type id) const;
+
+    void packInto(Packer * p) const;
+
+    MEMPROXY_CLASS(HttpHdrCc);
+
+    /** bit-mask representing what header values are set among those
+     * recognized by squid.
+     *
+     * managed via EBIT_SET/TEST/CLR
+     */
+private:
+    int32_t mask;
+    int32_t max_age;
+    int32_t s_maxage;
+    int32_t max_stale;
+    int32_t stale_if_error;
+    int32_t min_fresh;
+    /// low-level part of the public set method, performs no checks
+    _SQUID_INLINE_ void setMask(http_hdr_cc_type id, bool newval=true);
+    _SQUID_INLINE_ void setValue(int32_t &value, int32_t new_value, http_hdr_cc_type hdr, bool setting=true);
+
+public:
+    /**comma-separated representation of the header values which were
+     * received but are not recognized.
+     */
+    String other;
+};
+
+MEMPROXY_CLASS_INLINE(HttpHdrCc);
+
+#if _USE_INLINE_
+#include "HttpHdrCc.cci"
+#endif
+
+#endif /* SQUID_HTTPHDRCC_H */
diff -u -r -N squid-3.2.0.12/src/HttpHeader.cc squid-3.2.0.13/src/HttpHeader.cc
--- squid-3.2.0.12/src/HttpHeader.cc	2011-09-16 23:37:30.000000000 +1200
+++ squid-3.2.0.13/src/HttpHeader.cc	2011-10-14 14:42:56.000000000 +1300
@@ -36,6 +36,7 @@
 #include "squid.h"
 #include "base64.h"
 #include "HttpHdrContRange.h"
+#include "HttpHdrCc.h"
 #include "HttpHdrSc.h"
 #include "HttpHeader.h"
 #include "MemBuf.h"
@@ -1151,7 +1152,7 @@
     /* pack into mb */
     mb.init();
     packerToMemInit(&p, &mb);
-    httpHdrCcPackInto(cc, &p);
+    cc->packInto(&p);
     /* put */
     addEntry(new HttpHeaderEntry(HDR_CACHE_CONTROL, NULL, mb.buf));
     /* cleanup */
@@ -1310,16 +1311,19 @@
 HttpHdrCc *
 HttpHeader::getCc() const
 {
-    HttpHdrCc *cc;
-    String s;
-
     if (!CBIT_TEST(mask, HDR_CACHE_CONTROL))
         return NULL;
     PROF_start(HttpHeader_getCc);
 
+    String s;
     getList(HDR_CACHE_CONTROL, &s);
 
-    cc = httpHdrCcParseCreate(&s);
+    HttpHdrCc *cc=new HttpHdrCc();
+
+    if (!cc->parse(s)) {
+        delete cc;
+        cc = NULL;
+    }
 
     HttpHeaderStats[owner].ccParsedCount++;
 
diff -u -r -N squid-3.2.0.12/src/HttpHeaderTools.cc squid-3.2.0.13/src/HttpHeaderTools.cc
--- squid-3.2.0.12/src/HttpHeaderTools.cc	2011-09-16 23:37:30.000000000 +1200
+++ squid-3.2.0.13/src/HttpHeaderTools.cc	2011-10-14 14:42:56.000000000 +1300
@@ -377,9 +377,9 @@
             }
         }
         end = pos;
-        while (end < (start+len) && *end != '\\' && *end != '\"' && *end > 0x1F && *end != 0x7F)
+        while (end < (start+len) && *end != '\\' && *end != '\"' && (unsigned char)*end > 0x1F && *end != 0x7F)
             end++;
-        if ((*end <= 0x1F && *end != '\r' && *end != '\n') || *end == 0x7F) {
+        if (((unsigned char)*end <= 0x1F && *end != '\r' && *end != '\n') || *end == 0x7F) {
             debugs(66, 2, HERE << "failed to parse a quoted-string header field with CTL octet " << (start-pos)
                    << " bytes into '" << start << "'");
             val->clean();
diff -u -r -N squid-3.2.0.12/src/HttpReply.cc squid-3.2.0.13/src/HttpReply.cc
--- squid-3.2.0.12/src/HttpReply.cc	2011-09-16 23:37:30.000000000 +1200
+++ squid-3.2.0.13/src/HttpReply.cc	2011-10-14 14:42:56.000000000 +1300
@@ -38,6 +38,7 @@
 #include "Store.h"
 #include "HttpReply.h"
 #include "HttpHdrContRange.h"
+#include "HttpHdrCc.h"
 #include "HttpHdrSc.h"
 #include "acl/FilledChecklist.h"
 #include "HttpRequest.h"
@@ -330,21 +331,21 @@
 
     if (cache_control) {
         if (date >= 0) {
-            if (cache_control->s_maxage >= 0)
-                return date + cache_control->s_maxage;
+            if (cache_control->hasSMaxAge())
+                return date + cache_control->sMaxAge();
 
-            if (cache_control->max_age >= 0)
-                return date + cache_control->max_age;
+            if (cache_control->hasMaxAge())
+                return date + cache_control->maxAge();
         } else {
             /*
              * Conservatively handle the case when we have a max-age
              * header, but no Date for reference?
              */
 
-            if (cache_control->s_maxage >= 0)
+            if (cache_control->hasSMaxAge())
                 return squid_curtime;
 
-            if (cache_control->max_age >= 0)
+            if (cache_control->hasMaxAge())
                 return squid_curtime;
         }
     }
@@ -402,7 +403,7 @@
     content_type.clean();
 
     if (cache_control) {
-        httpHdrCcDestroy(cache_control);
+        delete cache_control;
         cache_control = NULL;
     }
 
diff -u -r -N squid-3.2.0.12/src/HttpRequest.cc squid-3.2.0.13/src/HttpRequest.cc
--- squid-3.2.0.12/src/HttpRequest.cc	2011-09-16 23:37:30.000000000 +1200
+++ squid-3.2.0.13/src/HttpRequest.cc	2011-10-14 14:42:56.000000000 +1300
@@ -37,6 +37,7 @@
 #include "squid.h"
 #include "DnsLookupDetails.h"
 #include "HttpRequest.h"
+#include "HttpHdrCc.h"
 #if USE_AUTH
 #include "auth/UserRequest.h"
 #endif
@@ -145,7 +146,7 @@
     header.clean();
 
     if (cache_control) {
-        httpHdrCcDestroy(cache_control);
+        delete cache_control;
         cache_control = NULL;
     }
 
diff -u -r -N squid-3.2.0.12/src/ip/Address.cc squid-3.2.0.13/src/ip/Address.cc
--- squid-3.2.0.12/src/ip/Address.cc	2011-09-16 23:37:30.000000000 +1200
+++ squid-3.2.0.13/src/ip/Address.cc	2011-10-14 14:42:56.000000000 +1300
@@ -185,7 +185,7 @@
 bool
 Ip::Address::IsAnyAddr() const
 {
-    return IN6_IS_ADDR_UNSPECIFIED( &m_SocketAddr.sin6_addr ) || IN6_ARE_ADDR_EQUAL( &m_SocketAddr.sin6_addr, &v4_anyaddr); ;
+    return IN6_IS_ADDR_UNSPECIFIED(&m_SocketAddr.sin6_addr) || IN6_ARE_ADDR_EQUAL(&m_SocketAddr.sin6_addr, &v4_anyaddr);
 }
 
 /// NOTE: Does NOT clear the Port stored. Ony the Address and Type.
diff -u -r -N squid-3.2.0.12/src/ip/Intercept.cc squid-3.2.0.13/src/ip/Intercept.cc
--- squid-3.2.0.12/src/ip/Intercept.cc	2011-09-16 23:37:30.000000000 +1200
+++ squid-3.2.0.13/src/ip/Intercept.cc	2011-10-14 14:42:56.000000000 +1300
@@ -204,7 +204,7 @@
 
     natLookup.nl_inport = htons(newConn->local.GetPort());
     newConn->local.GetInAddr(natLookup.nl_inip);
-    natLookup.nl_outport = htons(neConn->remote.GetPort());
+    natLookup.nl_outport = htons(newConn->remote.GetPort());
     newConn->remote.GetInAddr(natLookup.nl_outip);
     natLookup.nl_flags = IPN_TCP;
 
diff -u -r -N squid-3.2.0.12/src/ipc/AtomicWord.h squid-3.2.0.13/src/ipc/AtomicWord.h
--- squid-3.2.0.12/src/ipc/AtomicWord.h	1970-01-01 12:00:00.000000000 +1200
+++ squid-3.2.0.13/src/ipc/AtomicWord.h	2011-10-14 14:42:56.000000000 +1300
@@ -0,0 +1,88 @@
+/*
+ * $Id$
+ *
+ */
+
+#ifndef SQUID_IPC_ATOMIC_WORD_H
+#define SQUID_IPC_ATOMIC_WORD_H
+
+#if HAVE_ATOMIC_OPS
+/// Supplies atomic operations for an integral Value in memory shared by kids.
+/// Used to implement non-blocking shared locks, queues, tables, and pools.
+template <class ValueType>
+class AtomicWordT
+{
+public:
+    typedef ValueType Value;
+
+    AtomicWordT() {} // leave value unchanged
+    AtomicWordT(Value aValue): value(aValue) {} // XXX: unsafe
+
+    Value operator +=(int delta) { return __sync_add_and_fetch(&value, delta); }
+    Value operator -=(int delta) { return __sync_sub_and_fetch(&value, delta); }
+    Value operator ++() { return *this += 1; }
+    Value operator --() { return *this -= 1; }
+    Value operator ++(int) { return __sync_fetch_and_add(&value, 1); }
+    Value operator --(int) { return __sync_fetch_and_sub(&value, 1); }
+
+    bool swap_if(const int comparand, const int replacement) { return __sync_bool_compare_and_swap(&value, comparand, replacement); }
+
+    /// v1 = value; value &= v2; return v1;
+    Value fetchAndAnd(const Value v2) { return __sync_fetch_and_and(&value, v2); }
+
+    // TODO: no need for __sync_bool_compare_and_swap here?
+    bool operator ==(int v2) { return __sync_bool_compare_and_swap(&value, v2, value); }
+
+    // TODO: no need for __sync_fetch_and_add here?
+    Value get() const { return __sync_fetch_and_add(const_cast<Value*>(&value), 0); }
+    operator Value () const { return get(); }
+
+private:
+    Value value;
+};
+
+enum { AtomicOperationsSupported = 1 };
+
+#else
+/// A wrapper to provide AtomicWordT API (and asserting implementation)
+/// where we do not support atomic operations. This avoids ifdefs in core code.
+template <class ValueType>
+class AtomicWordT
+{
+public:
+    typedef ValueType Value;
+
+    AtomicWordT() {} // leave value unchanged
+    AtomicWordT(Value aValue): value(aValue) {} // XXX: unsafe
+
+    Value operator +=(int) { assert(false); return *this; }
+    Value operator ++() { return *this += 1; }
+    Value operator --() { return *this += -1; }
+    Value operator ++(int) { assert(false); return *this; }
+    Value operator --(int) { assert(false); return *this; }
+
+    bool swap_if(const int comparand, const int replacement)
+    { assert(false); return false; }
+
+    /// v1 = value; value &= v2; return v1;
+    Value fetchAndAnd(const Value v2)
+    { assert(false); return value; }
+
+    // TODO: no need for __sync_bool_compare_and_swap here?
+    bool operator ==(int v2) { assert(false); return false; }
+
+    // TODO: no need for __sync_fetch_and_add here?
+    Value get() const { assert(false); return value; }
+    operator Value () const { return get(); }
+
+private:
+    Value value;
+};
+
+enum { AtomicOperationsSupported = 0 };
+
+#endif /* HAVE_ATOMIC_OPS */
+
+typedef AtomicWordT<int> AtomicWord;
+
+#endif // SQUID_IPC_ATOMIC_WORD_H
diff -u -r -N squid-3.2.0.12/src/ipc/Coordinator.cc squid-3.2.0.13/src/ipc/Coordinator.cc
--- squid-3.2.0.12/src/ipc/Coordinator.cc	2011-09-16 23:37:30.000000000 +1200
+++ squid-3.2.0.13/src/ipc/Coordinator.cc	2011-10-14 14:42:56.000000000 +1300
@@ -49,10 +49,27 @@
 
 void Ipc::Coordinator::registerStrand(const StrandCoord& strand)
 {
-    if (StrandCoord* found = findStrand(strand.kidId))
+    debugs(54, 3, HERE << "registering kid" << strand.kidId <<
+           ' ' << strand.tag);
+    if (StrandCoord* found = findStrand(strand.kidId)) {
+        const String oldTag = found->tag;
         *found = strand;
-    else
+        if (oldTag.size() && !strand.tag.size())
+            found->tag = oldTag; // keep more detailed info (XXX?)
+    } else {
         strands_.push_back(strand);
+    }
+
+    // notify searchers waiting for this new strand, if any
+    typedef Searchers::iterator SRI;
+    for (SRI i = searchers.begin(); i != searchers.end();) {
+        if (i->tag == strand.tag) {
+            notifySearcher(*i, strand);
+            i = searchers.erase(i);
+        } else {
+            ++i;
+        }
+    }
 }
 
 void Ipc::Coordinator::receive(const TypedMsgHdr& message)
@@ -60,9 +77,17 @@
     switch (message.type()) {
     case mtRegistration:
         debugs(54, 6, HERE << "Registration request");
-        handleRegistrationRequest(StrandCoord(message));
+        handleRegistrationRequest(HereIamMessage(message));
         break;
 
+    case mtStrandSearchRequest: {
+        const StrandSearchRequest sr(message);
+        debugs(54, 6, HERE << "Strand search request: " << sr.requestorId <<
+               " tag: " << sr.tag);
+        handleSearchRequest(sr);
+        break;
+    }
+
     case mtSharedListenRequest:
         debugs(54, 6, HERE << "Shared listen request");
         handleSharedListenRequest(SharedListenRequest(message));
@@ -104,14 +129,14 @@
     }
 }
 
-void Ipc::Coordinator::handleRegistrationRequest(const StrandCoord& strand)
+void Ipc::Coordinator::handleRegistrationRequest(const HereIamMessage& msg)
 {
-    registerStrand(strand);
+    registerStrand(msg.strand);
 
     // send back an acknowledgement; TODO: remove as not needed?
     TypedMsgHdr message;
-    strand.pack(message);
-    SendMessage(MakeAddr(strandAddrPfx, strand.kidId), message);
+    msg.pack(message);
+    SendMessage(MakeAddr(strandAddrPfx, msg.strand.kidId), message);
 }
 
 void
@@ -139,15 +164,25 @@
 {
     debugs(54, 4, HERE);
 
+    try {
+        Mgr::Action::Pointer action =
+            CacheManager::GetInstance()->createRequestedAction(request.params);
+        AsyncJob::Start(new Mgr::Inquirer(action, request, strands_));
+    } catch (const std::exception &ex) {
+        debugs(54, DBG_IMPORTANT, "BUG: cannot aggregate mgr:" <<
+               request.params.actionName << ": " << ex.what());
+        // TODO: Avoid half-baked Connections or teach them how to close.
+        ::close(request.conn->fd);
+        request.conn->fd = -1;
+        return; // the worker will timeout and close
+    }
+
     // Let the strand know that we are now responsible for handling the request
     Mgr::Response response(request.requestId);
     TypedMsgHdr message;
     response.pack(message);
     SendMessage(MakeAddr(strandAddrPfx, request.requestorId), message);
 
-    Mgr::Action::Pointer action =
-        CacheManager::GetInstance()->createRequestedAction(request.params);
-    AsyncJob::Start(new Mgr::Inquirer(action, request, strands_));
 }
 
 void
@@ -156,6 +191,39 @@
     Mgr::Inquirer::HandleRemoteAck(response);
 }
 
+void
+Ipc::Coordinator::handleSearchRequest(const Ipc::StrandSearchRequest &request)
+{
+    // do we know of a strand with the given search tag?
+    const StrandCoord *strand = NULL;
+    typedef StrandCoords::const_iterator SCCI;
+    for (SCCI i = strands_.begin(); !strand && i != strands_.end(); ++i) {
+        if (i->tag == request.tag)
+            strand = &(*i);
+    }
+
+    if (strand) {
+        notifySearcher(request, *strand);
+        return;
+    }
+
+    searchers.push_back(request);
+    debugs(54, 3, HERE << "cannot yet tell kid" << request.requestorId <<
+           " who " << request.tag << " is");
+}
+
+void
+Ipc::Coordinator::notifySearcher(const Ipc::StrandSearchRequest &request,
+                                 const StrandCoord& strand)
+{
+    debugs(54, 3, HERE << "tell kid" << request.requestorId << " that " <<
+           request.tag << " is kid" << strand.kidId);
+    const StrandSearchResponse response(strand);
+    TypedMsgHdr message;
+    response.pack(message);
+    SendMessage(MakeAddr(strandAddrPfx, request.requestorId), message);
+}
+
 #if SQUID_SNMP
 void
 Ipc::Coordinator::handleSnmpRequest(const Snmp::Request& request)
diff -u -r -N squid-3.2.0.12/src/ipc/Coordinator.h squid-3.2.0.13/src/ipc/Coordinator.h
--- squid-3.2.0.12/src/ipc/Coordinator.h	2011-09-16 23:37:30.000000000 +1200
+++ squid-3.2.0.13/src/ipc/Coordinator.h	2011-10-14 14:42:56.000000000 +1300
@@ -14,10 +14,12 @@
 #include "ipc/Port.h"
 #include "ipc/SharedListen.h"
 #include "ipc/StrandCoords.h"
+#include "ipc/StrandSearch.h"
 #include "mgr/forward.h"
 #if SQUID_SNMP
 #include "snmp/forward.h"
 #endif
+#include <list>
 #include <map>
 
 namespace Ipc
@@ -42,7 +44,12 @@
 
     StrandCoord* findStrand(int kidId); ///< registered strand or NULL
     void registerStrand(const StrandCoord &); ///< adds or updates existing
-    void handleRegistrationRequest(const StrandCoord &); ///< register,ACK
+    void handleRegistrationRequest(const HereIamMessage &); ///< register,ACK
+
+    /// answer the waiting search request
+    void notifySearcher(const StrandSearchRequest &request, const StrandCoord&);
+    /// answers or queues the request if the answer is not yet known
+    void handleSearchRequest(const StrandSearchRequest &request);
 
     /// returns cached socket or calls openListenSocket()
     void handleSharedListenRequest(const SharedListenRequest& request);
@@ -58,7 +65,10 @@
 private:
     StrandCoords strands_; ///< registered processes and threads
 
-    typedef std::map<OpenListenerParams, Comm::ConnectionPointer> Listeners; ///< params:fd map
+    typedef std::list<StrandSearchRequest> Searchers; ///< search requests
+    Searchers searchers; ///< yet unanswered search requests in arrival order
+
+    typedef std::map<OpenListenerParams, Comm::ConnectionPointer> Listeners; ///< params:connection map
     Listeners listeners; ///< cached comm_open_listener() results
 
     static Coordinator* TheInstance; ///< the only class instance in existence
diff -u -r -N squid-3.2.0.12/src/ipc/Forwarder.cc squid-3.2.0.13/src/ipc/Forwarder.cc
--- squid-3.2.0.12/src/ipc/Forwarder.cc	2011-09-16 23:37:30.000000000 +1200
+++ squid-3.2.0.13/src/ipc/Forwarder.cc	2011-10-14 14:42:56.000000000 +1300
@@ -92,6 +92,8 @@
 {
     debugs(54, 3, HERE);
     request->requestId = 0;
+    // Do not clear ENTRY_FWD_HDR_WAIT or do entry->complete() because
+    // it will trigger our client side processing. Let job cleanup close.
 }
 
 /// Ipc::Forwarder::requestTimedOut wrapper
diff -u -r -N squid-3.2.0.12/src/ipc/forward.h squid-3.2.0.13/src/ipc/forward.h
--- squid-3.2.0.12/src/ipc/forward.h	2011-09-16 23:37:30.000000000 +1200
+++ squid-3.2.0.13/src/ipc/forward.h	2011-10-14 14:42:56.000000000 +1300
@@ -13,6 +13,8 @@
 
 class TypedMsgHdr;
 class StrandCoord;
+class HereIamMessage;
+class StrandSearchResponse;
 class Forwarder;
 class Inquirer;
 class Request;
diff -u -r -N squid-3.2.0.12/src/ipc/Kid.cc squid-3.2.0.13/src/ipc/Kid.cc
--- squid-3.2.0.12/src/ipc/Kid.cc	2011-09-16 23:37:30.000000000 +1200
+++ squid-3.2.0.13/src/ipc/Kid.cc	2011-10-14 14:42:56.000000000 +1300
@@ -13,6 +13,8 @@
 #include <sys/wait.h>
 #endif
 
+int TheProcessKind = pkOther;
+
 Kid::Kid():
         badFailures(0),
         pid(-1),
diff -u -r -N squid-3.2.0.12/src/ipc/Kid.h squid-3.2.0.13/src/ipc/Kid.h
--- squid-3.2.0.12/src/ipc/Kid.h	2011-09-16 23:37:30.000000000 +1200
+++ squid-3.2.0.13/src/ipc/Kid.h	2011-10-14 14:42:56.000000000 +1300
@@ -85,4 +85,19 @@
     status_type status; ///< exit status of a stopped kid
 };
 
+
+// TODO: processes may not be kids; is there a better place to put this?
+
+/// process kinds
+typedef enum {
+    pkOther  = 0, ///< we do not know or do not care
+    pkCoordinator = 1, ///< manages all other kids
+    pkWorker = 2, ///< general-purpose worker bee
+    pkDisker = 4, ///< cache_dir manager
+} ProcessKind;
+
+/// ProcessKind for the current process
+extern int TheProcessKind;
+
+
 #endif /* SQUID_IPC_KID_H */
diff -u -r -N squid-3.2.0.12/src/ipc/Kids.cc squid-3.2.0.13/src/ipc/Kids.cc
--- squid-3.2.0.12/src/ipc/Kids.cc	2011-09-16 23:37:30.000000000 +1200
+++ squid-3.2.0.13/src/ipc/Kids.cc	2011-10-14 14:42:56.000000000 +1300
@@ -6,7 +6,9 @@
  */
 
 #include "config.h"
+#include "base/TextException.h"
 #include "ipc/Kids.h"
+#include "protos.h"
 
 Kids TheKids;
 KidName TheKidName;
@@ -16,28 +18,34 @@
 }
 
 /// maintain n kids
-void Kids::init(size_t n)
+void Kids::init()
 {
-    assert(n > 0);
-
     if (storage.size() > 0)
         storage.clean();
 
-    storage.reserve(n);
+    storage.reserve(NumberOfKids());
 
     char kid_name[32];
 
-    // add Kid records for all n main strands
-    for (size_t i = 1; i <= n; ++i) {
-        snprintf(kid_name, sizeof(kid_name), "(squid-%d)", (int)i);
+    // add Kid records for all workers
+    for (int i = 0; i < Config.workers; ++i) {
+        snprintf(kid_name, sizeof(kid_name), "(squid-%d)", (int)(storage.size()+1));
+        storage.push_back(Kid(kid_name));
+    }
+
+    // add Kid records for all disk processes
+    for (int i = 0; i < Config.cacheSwap.n_strands; ++i) {
+        snprintf(kid_name, sizeof(kid_name), "(squid-disk-%d)", (int)(storage.size()+1));
         storage.push_back(Kid(kid_name));
     }
 
     // if coordination is needed, add a Kid record for Coordinator
-    if (n > 1) {
-        snprintf(kid_name, sizeof(kid_name), "(squid-coord-%d)", (int)(n + 1));
+    if (storage.size() > 1) {
+        snprintf(kid_name, sizeof(kid_name), "(squid-coord-%d)", (int)(storage.size()+1));
         storage.push_back(Kid(kid_name));
     }
+
+    Must(storage.size() == static_cast<size_t>(NumberOfKids()));
 }
 
 /// returns kid by pid
diff -u -r -N squid-3.2.0.12/src/ipc/Kids.h squid-3.2.0.13/src/ipc/Kids.h
--- squid-3.2.0.12/src/ipc/Kids.h	2011-09-16 23:37:30.000000000 +1200
+++ squid-3.2.0.13/src/ipc/Kids.h	2011-10-14 14:42:56.000000000 +1300
@@ -21,8 +21,8 @@
     Kids& operator= (const Kids&); ///< not implemented
 
 public:
-    /// maintain n kids
-    void init(size_t n);
+    /// initialize all kid records based on Config
+    void init();
 
     /// returns kid by pid
     Kid* find(pid_t pid);
diff -u -r -N squid-3.2.0.12/src/ipc/Makefile.am squid-3.2.0.13/src/ipc/Makefile.am
--- squid-3.2.0.12/src/ipc/Makefile.am	2011-09-16 23:37:30.000000000 +1200
+++ squid-3.2.0.13/src/ipc/Makefile.am	2011-10-14 14:42:56.000000000 +1300
@@ -4,6 +4,7 @@
 noinst_LTLIBRARIES = libipc.la
 
 libipc_la_SOURCES = \
+	AtomicWord.h \
 	FdNotes.cc \
 	FdNotes.h \
 	Kid.cc \
@@ -11,11 +12,19 @@
 	Kids.cc \
 	Kids.h \
 	Messages.h \
+	Queue.cc \
+	Queue.h \
+	ReadWriteLock.cc \
+	ReadWriteLock.h \
 	StartListening.cc \
 	StartListening.h \
+	StoreMap.cc \
+	StoreMap.h \
 	StrandCoord.cc \
 	StrandCoord.h \
 	StrandCoords.h \
+	StrandSearch.cc \
+	StrandSearch.h \
 	SharedListen.cc \
 	SharedListen.h \
 	TypedMsgHdr.cc \
@@ -34,7 +43,19 @@
 	Inquirer.cc \
 	Inquirer.h \
 	Request.h \
-	Response.h
+	Response.h \
+	\
+	mem/Page.cc \
+	mem/Page.h \
+	mem/PagePool.cc \
+	mem/PagePool.h \
+	mem/Pages.cc \
+	mem/Pages.h \
+	mem/PageStack.cc \
+	mem/PageStack.h \
+	mem/Pointer.h \
+	mem/Segment.cc \
+	mem/Segment.h
 
 DEFS += -DDEFAULT_STATEDIR=\"$(localstatedir)/run/squid\"
 
diff -u -r -N squid-3.2.0.12/src/ipc/Makefile.in squid-3.2.0.13/src/ipc/Makefile.in
--- squid-3.2.0.12/src/ipc/Makefile.in	2011-09-16 23:38:20.000000000 +1200
+++ squid-3.2.0.13/src/ipc/Makefile.in	2011-10-14 14:48:14.000000000 +1300
@@ -56,9 +56,11 @@
 CONFIG_CLEAN_VPATH_FILES =
 LTLIBRARIES = $(noinst_LTLIBRARIES)
 libipc_la_LIBADD =
-am_libipc_la_OBJECTS = FdNotes.lo Kid.lo Kids.lo StartListening.lo \
-	StrandCoord.lo SharedListen.lo TypedMsgHdr.lo Coordinator.lo \
-	UdsOp.lo Port.lo Strand.lo Forwarder.lo Inquirer.lo
+am_libipc_la_OBJECTS = FdNotes.lo Kid.lo Kids.lo Queue.lo \
+	ReadWriteLock.lo StartListening.lo StoreMap.lo StrandCoord.lo \
+	StrandSearch.lo SharedListen.lo TypedMsgHdr.lo Coordinator.lo \
+	UdsOp.lo Port.lo Strand.lo Forwarder.lo Inquirer.lo Page.lo \
+	PagePool.lo Pages.lo PageStack.lo Segment.lo
 libipc_la_OBJECTS = $(am_libipc_la_OBJECTS)
 DEFAULT_INCLUDES = 
 depcomp = $(SHELL) $(top_srcdir)/cfgaux/depcomp
@@ -311,6 +313,7 @@
 subst_perlshell = sed -e 's,[@]PERL[@],$(PERL),g' <$(srcdir)/$@.pl.in >$@ || ($(RM) -f $@ ; exit 1)
 noinst_LTLIBRARIES = libipc.la
 libipc_la_SOURCES = \
+	AtomicWord.h \
 	FdNotes.cc \
 	FdNotes.h \
 	Kid.cc \
@@ -318,11 +321,19 @@
 	Kids.cc \
 	Kids.h \
 	Messages.h \
+	Queue.cc \
+	Queue.h \
+	ReadWriteLock.cc \
+	ReadWriteLock.h \
 	StartListening.cc \
 	StartListening.h \
+	StoreMap.cc \
+	StoreMap.h \
 	StrandCoord.cc \
 	StrandCoord.h \
 	StrandCoords.h \
+	StrandSearch.cc \
+	StrandSearch.h \
 	SharedListen.cc \
 	SharedListen.h \
 	TypedMsgHdr.cc \
@@ -341,7 +352,19 @@
 	Inquirer.cc \
 	Inquirer.h \
 	Request.h \
-	Response.h
+	Response.h \
+	\
+	mem/Page.cc \
+	mem/Page.h \
+	mem/PagePool.cc \
+	mem/PagePool.h \
+	mem/Pages.cc \
+	mem/Pages.h \
+	mem/PageStack.cc \
+	mem/PageStack.h \
+	mem/Pointer.h \
+	mem/Segment.cc \
+	mem/Segment.h
 
 all: all-am
 
@@ -410,11 +433,20 @@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/Inquirer.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/Kid.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/Kids.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/Page.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/PagePool.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/PageStack.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/Pages.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/Port.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/Queue.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ReadWriteLock.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/Segment.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/SharedListen.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/StartListening.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/StoreMap.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/Strand.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/StrandCoord.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/StrandSearch.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/TypedMsgHdr.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/UdsOp.Plo@am__quote@
 
@@ -439,6 +471,41 @@
 @AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
 @am__fastdepCXX_FALSE@	$(LTCXXCOMPILE) -c -o $@ $<
 
+Page.lo: mem/Page.cc
+@am__fastdepCXX_TRUE@	$(LIBTOOL)  --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT Page.lo -MD -MP -MF $(DEPDIR)/Page.Tpo -c -o Page.lo `test -f 'mem/Page.cc' || echo '$(srcdir)/'`mem/Page.cc
+@am__fastdepCXX_TRUE@	$(am__mv) $(DEPDIR)/Page.Tpo $(DEPDIR)/Page.Plo
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@	source='mem/Page.cc' object='Page.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCXX_FALSE@	$(LIBTOOL)  --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o Page.lo `test -f 'mem/Page.cc' || echo '$(srcdir)/'`mem/Page.cc
+
+PagePool.lo: mem/PagePool.cc
+@am__fastdepCXX_TRUE@	$(LIBTOOL)  --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT PagePool.lo -MD -MP -MF $(DEPDIR)/PagePool.Tpo -c -o PagePool.lo `test -f 'mem/PagePool.cc' || echo '$(srcdir)/'`mem/PagePool.cc
+@am__fastdepCXX_TRUE@	$(am__mv) $(DEPDIR)/PagePool.Tpo $(DEPDIR)/PagePool.Plo
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@	source='mem/PagePool.cc' object='PagePool.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCXX_FALSE@	$(LIBTOOL)  --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o PagePool.lo `test -f 'mem/PagePool.cc' || echo '$(srcdir)/'`mem/PagePool.cc
+
+Pages.lo: mem/Pages.cc
+@am__fastdepCXX_TRUE@	$(LIBTOOL)  --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT Pages.lo -MD -MP -MF $(DEPDIR)/Pages.Tpo -c -o Pages.lo `test -f 'mem/Pages.cc' || echo '$(srcdir)/'`mem/Pages.cc
+@am__fastdepCXX_TRUE@	$(am__mv) $(DEPDIR)/Pages.Tpo $(DEPDIR)/Pages.Plo
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@	source='mem/Pages.cc' object='Pages.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCXX_FALSE@	$(LIBTOOL)  --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o Pages.lo `test -f 'mem/Pages.cc' || echo '$(srcdir)/'`mem/Pages.cc
+
+PageStack.lo: mem/PageStack.cc
+@am__fastdepCXX_TRUE@	$(LIBTOOL)  --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT PageStack.lo -MD -MP -MF $(DEPDIR)/PageStack.Tpo -c -o PageStack.lo `test -f 'mem/PageStack.cc' || echo '$(srcdir)/'`mem/PageStack.cc
+@am__fastdepCXX_TRUE@	$(am__mv) $(DEPDIR)/PageStack.Tpo $(DEPDIR)/PageStack.Plo
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@	source='mem/PageStack.cc' object='PageStack.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCXX_FALSE@	$(LIBTOOL)  --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o PageStack.lo `test -f 'mem/PageStack.cc' || echo '$(srcdir)/'`mem/PageStack.cc
+
+Segment.lo: mem/Segment.cc
+@am__fastdepCXX_TRUE@	$(LIBTOOL)  --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT Segment.lo -MD -MP -MF $(DEPDIR)/Segment.Tpo -c -o Segment.lo `test -f 'mem/Segment.cc' || echo '$(srcdir)/'`mem/Segment.cc
+@am__fastdepCXX_TRUE@	$(am__mv) $(DEPDIR)/Segment.Tpo $(DEPDIR)/Segment.Plo
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@	source='mem/Segment.cc' object='Segment.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCXX_FALSE@	$(LIBTOOL)  --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o Segment.lo `test -f 'mem/Segment.cc' || echo '$(srcdir)/'`mem/Segment.cc
+
 mostlyclean-libtool:
 	-rm -f *.lo
 
diff -u -r -N squid-3.2.0.12/src/ipc/mem/Page.cc squid-3.2.0.13/src/ipc/mem/Page.cc
--- squid-3.2.0.12/src/ipc/mem/Page.cc	1970-01-01 12:00:00.000000000 +1200
+++ squid-3.2.0.13/src/ipc/mem/Page.cc	2011-10-14 14:42:56.000000000 +1300
@@ -0,0 +1,19 @@
+/*
+ * $Id$
+ *
+ * DEBUG: section 54    Interprocess Communication
+ *
+ */
+
+#include "config.h"
+#include "ipc/mem/Page.h"
+
+#if HAVE_IOSTREAM
+#include <iostream>
+#endif
+
+
+std::ostream &Ipc::Mem::operator <<(std::ostream &os, const PageId &page)
+{
+    return os << "sh_page" << page.pool << '.' << page.number;
+}
diff -u -r -N squid-3.2.0.12/src/ipc/mem/Page.h squid-3.2.0.13/src/ipc/mem/Page.h
--- squid-3.2.0.12/src/ipc/mem/Page.h	1970-01-01 12:00:00.000000000 +1200
+++ squid-3.2.0.13/src/ipc/mem/Page.h	2011-10-14 14:42:56.000000000 +1300
@@ -0,0 +1,42 @@
+/*
+ * $Id$
+ *
+ */
+
+#ifndef SQUID_IPC_MEM_PAGE_H
+#define SQUID_IPC_MEM_PAGE_H
+
+#if HAVE_IOSFWD
+#include <iosfwd>
+#endif
+
+namespace Ipc
+{
+
+namespace Mem
+{
+
+/// Shared memory page identifier, address, or handler
+class PageId
+{
+public:
+    PageId(): pool(0), number(0), purpose(maxPurpose) {}
+
+    operator bool() const { return pool && number; }
+
+    uint32_t pool; ///< page pool ID within Squid
+    // uint32_t segment; ///< memory segment ID within the pool; unused for now
+    uint32_t number; ///< page number within the segment
+
+    enum Purpose { cachePage, ioPage, maxPurpose };
+    Purpose purpose; ///< page purpose
+};
+
+/// writes page address (e.g., "sh_page5.3"), for debugging
+std::ostream &operator <<(std::ostream &os, const PageId &page);
+
+} // namespace Mem
+
+} // namespace Ipc
+
+#endif // SQUID_IPC_MEM_PAGE_H
diff -u -r -N squid-3.2.0.12/src/ipc/mem/PagePool.cc squid-3.2.0.13/src/ipc/mem/PagePool.cc
--- squid-3.2.0.12/src/ipc/mem/PagePool.cc	1970-01-01 12:00:00.000000000 +1200
+++ squid-3.2.0.13/src/ipc/mem/PagePool.cc	2011-10-14 14:42:56.000000000 +1300
@@ -0,0 +1,70 @@
+/*
+ * $Id$
+ *
+ * DEBUG: section 54    Interprocess Communication
+ *
+ */
+
+#include "config.h"
+#include "base/TextException.h"
+#include "ipc/mem/Page.h"
+#include "ipc/mem/PagePool.h"
+
+
+// Ipc::Mem::PagePool
+
+Ipc::Mem::PagePool::Owner *
+Ipc::Mem::PagePool::Init(const char *const id, const unsigned int capacity, const size_t pageSize)
+{
+    static uint32_t LastPagePoolId = 0;
+    if (++LastPagePoolId == 0)
+        ++LastPagePoolId; // skip zero pool id
+    return shm_new(PageStack)(id, LastPagePoolId, capacity, pageSize);
+}
+
+Ipc::Mem::PagePool::PagePool(const char *const id):
+        pageIndex(shm_old(PageStack)(id)),
+        theLevels(reinterpret_cast<AtomicWord *>(
+                      reinterpret_cast<char *>(pageIndex.getRaw()) +
+                      pageIndex->stackSize())),
+        theBuf(reinterpret_cast<char *>(theLevels + PageId::maxPurpose))
+{
+}
+
+size_t
+Ipc::Mem::PagePool::level(const int purpose) const
+{
+    Must(0 <= purpose && purpose < PageId::maxPurpose);
+    return theLevels[purpose];
+}
+
+bool
+Ipc::Mem::PagePool::get(const PageId::Purpose purpose, PageId &page)
+{
+    Must(0 <= purpose && purpose < PageId::maxPurpose);
+    if (pageIndex->pop(page)) {
+        page.purpose = purpose;
+        ++theLevels[purpose];
+        return true;
+    }
+    return false;
+}
+
+void
+Ipc::Mem::PagePool::put(PageId &page)
+{
+    if (!page)
+        return;
+
+    Must(0 <= page.purpose && page.purpose < PageId::maxPurpose);
+    --theLevels[page.purpose];
+    page.purpose = PageId::maxPurpose;
+    return pageIndex->push(page);
+}
+
+char *
+Ipc::Mem::PagePool::pagePointer(const PageId &page)
+{
+    Must(pageIndex->pageIdIsValid(page));
+    return theBuf + pageSize() * (page.number - 1);
+}
diff -u -r -N squid-3.2.0.12/src/ipc/mem/PagePool.h squid-3.2.0.13/src/ipc/mem/PagePool.h
--- squid-3.2.0.12/src/ipc/mem/PagePool.h	1970-01-01 12:00:00.000000000 +1200
+++ squid-3.2.0.13/src/ipc/mem/PagePool.h	2011-10-14 14:42:56.000000000 +1300
@@ -0,0 +1,58 @@
+/*
+ * $Id$
+ *
+ */
+
+#ifndef SQUID_IPC_MEM_PAGE_POOL_H
+#define SQUID_IPC_MEM_PAGE_POOL_H
+
+#include "ipc/mem/Page.h"
+#include "ipc/mem/PageStack.h"
+#include "ipc/mem/Pointer.h"
+
+namespace Ipc
+{
+
+namespace Mem
+{
+
+/// Atomic container of shared memory pages. Implemented using a collection of
+/// Segments, each with a PageStack index of free pages. All pools must be
+/// created by a single process.
+class PagePool
+{
+public:
+    typedef Ipc::Mem::Owner<PageStack> Owner;
+
+    static Owner *Init(const char *const id, const unsigned int capacity, const size_t pageSize);
+
+    PagePool(const char *const id);
+
+    unsigned int capacity() const { return pageIndex->capacity(); }
+    size_t pageSize() const { return pageIndex->pageSize(); }
+    /// lower bound for the number of free pages
+    unsigned int size() const { return pageIndex->size(); }
+    /// approximate number of shared memory pages used now
+    size_t level() const { return capacity() - size(); }
+    /// approximate number of shared memory pages used now for given purpose
+    size_t level(const int purpose) const;
+
+    /// sets page ID and returns true unless no free pages are found
+    bool get(const PageId::Purpose purpose, PageId &page);
+    /// makes identified page available as a free page to future get() callers
+    void put(PageId &page);
+    /// converts page handler into a temporary writeable shared memory pointer
+    char *pagePointer(const PageId &page);
+
+private:
+    Ipc::Mem::Pointer<PageStack> pageIndex; ///< free pages index
+    /// number of shared memory pages used now for each purpose
+    AtomicWord *const theLevels;
+    char *const theBuf; ///< pages storage
+};
+
+} // namespace Mem
+
+} // namespace Ipc
+
+#endif // SQUID_IPC_MEM_PAGE_POOL_H
diff -u -r -N squid-3.2.0.12/src/ipc/mem/Pages.cc squid-3.2.0.13/src/ipc/mem/Pages.cc
--- squid-3.2.0.12/src/ipc/mem/Pages.cc	1970-01-01 12:00:00.000000000 +1200
+++ squid-3.2.0.13/src/ipc/mem/Pages.cc	2011-10-14 14:42:56.000000000 +1300
@@ -0,0 +1,151 @@
+/*
+ * $Id$
+ *
+ * DEBUG: section 54    Interprocess Communication
+ *
+ */
+
+#include "config.h"
+#include "base/TextException.h"
+#include "base/RunnersRegistry.h"
+#include "ipc/mem/PagePool.h"
+#include "ipc/mem/Pages.h"
+#include "structs.h"
+#include "SwapDir.h"
+
+// Uses a single PagePool instance, for now.
+// Eventually, we may have pools dedicated to memory caching, disk I/O, etc.
+
+// TODO: make pool id more unique so it does not conflict with other Squids?
+static const char *PagePoolId = "squid-page-pool";
+static Ipc::Mem::PagePool *ThePagePool = 0;
+
+// TODO: make configurable to avoid waste when mem-cached objects are small/big
+size_t
+Ipc::Mem::PageSize()
+{
+    return 32*1024;
+}
+
+bool
+Ipc::Mem::GetPage(const PageId::Purpose purpose, PageId &page)
+{
+    return ThePagePool && PagesAvailable(purpose) > 0 ?
+           ThePagePool->get(purpose, page) : false;
+}
+
+void
+Ipc::Mem::PutPage(PageId &page)
+{
+    Must(ThePagePool);
+    ThePagePool->put(page);
+}
+
+char *
+Ipc::Mem::PagePointer(const PageId &page)
+{
+    Must(ThePagePool);
+    return ThePagePool->pagePointer(page);
+}
+
+size_t
+Ipc::Mem::PageLimit()
+{
+    size_t limit = 0;
+    for (int i = 0; i < PageId::maxPurpose; ++i)
+        limit += PageLimit(i);
+    return limit;
+}
+
+size_t
+Ipc::Mem::PageLimit(const int purpose)
+{
+    switch (purpose) {
+    case PageId::cachePage:
+        return Config.memMaxSize > 0 ? Config.memMaxSize / PageSize() : 0;
+    case PageId::ioPage:
+        // XXX: this should be independent from memory cache pages
+        return PageLimit(PageId::cachePage)/2;
+    default:
+        Must(false);
+    }
+    return 0;
+}
+
+size_t
+Ipc::Mem::PageLevel()
+{
+    return ThePagePool ? ThePagePool->level() : 0;
+}
+
+size_t
+Ipc::Mem::PageLevel(const int purpose)
+{
+    return ThePagePool ? ThePagePool->level(purpose) : 0;
+}
+
+/// initializes shared memory pages
+class SharedMemPagesRr: public Ipc::Mem::RegisteredRunner
+{
+public:
+    /* RegisteredRunner API */
+    SharedMemPagesRr(): owner(NULL) {}
+    virtual void run(const RunnerRegistry &);
+    virtual void create(const RunnerRegistry &);
+    virtual void open(const RunnerRegistry &);
+    virtual ~SharedMemPagesRr();
+
+private:
+    Ipc::Mem::PagePool::Owner *owner;
+};
+
+RunnerRegistrationEntry(rrAfterConfig, SharedMemPagesRr);
+
+
+void
+SharedMemPagesRr::run(const RunnerRegistry &r)
+{
+    if (!UsingSmp())
+        return;
+
+    // When cache_dirs start using shared memory pages, they would
+    // need to communicate their needs to us somehow.
+    if (Config.memMaxSize <= 0)
+        return;
+
+    if (Ipc::Mem::PageLimit() <= 0) {
+        if (IamMasterProcess()) {
+            debugs(54, DBG_IMPORTANT, "WARNING: mem-cache size is too small ("
+                   << (Config.memMaxSize / 1024.0) << " KB), should be >= " <<
+                   (Ipc::Mem::PageSize() / 1024.0) << " KB");
+        }
+        return;
+    }
+
+    Ipc::Mem::RegisteredRunner::run(r);
+}
+
+void
+SharedMemPagesRr::create(const RunnerRegistry &)
+{
+    Must(!owner);
+    owner = Ipc::Mem::PagePool::Init(PagePoolId, Ipc::Mem::PageLimit(),
+                                     Ipc::Mem::PageSize());
+}
+
+void
+SharedMemPagesRr::open(const RunnerRegistry &)
+{
+    Must(!ThePagePool);
+    ThePagePool = new Ipc::Mem::PagePool(PagePoolId);
+}
+
+SharedMemPagesRr::~SharedMemPagesRr()
+{
+    if (!UsingSmp())
+        return;
+
+    delete ThePagePool;
+    ThePagePool = NULL;
+    delete owner;
+}
diff -u -r -N squid-3.2.0.12/src/ipc/mem/Pages.h squid-3.2.0.13/src/ipc/mem/Pages.h
--- squid-3.2.0.12/src/ipc/mem/Pages.h	1970-01-01 12:00:00.000000000 +1200
+++ squid-3.2.0.13/src/ipc/mem/Pages.h	2011-10-14 14:42:56.000000000 +1300
@@ -0,0 +1,58 @@
+/*
+ * $Id$
+ *
+ */
+
+#ifndef SQUID_IPC_MEM_PAGES_H
+#define SQUID_IPC_MEM_PAGES_H
+
+#include "ipc/mem/Page.h"
+
+namespace Ipc
+{
+
+namespace Mem
+{
+
+/* Single page manipulation */
+
+/// sets page ID and returns true unless no free pages are found
+bool GetPage(const PageId::Purpose purpose, PageId &page);
+
+/// makes identified page available as a free page to future GetPage() callers
+void PutPage(PageId &page);
+
+/// converts page handler into a temporary writeable shared memory pointer
+char *PagePointer(const PageId &page);
+
+
+/* Limits and statistics */
+
+/// the total number of shared memory pages that can be in use at any time
+size_t PageLimit();
+
+/// the total number of shared memory pages that can be in use at any
+/// time for given purpose
+size_t PageLimit(const int purpose);
+
+/// approximate total number of shared memory pages used now
+size_t PageLevel();
+
+/// approximate total number of shared memory pages used now for given purpose
+size_t PageLevel(const int purpose);
+
+/// approximate total number of shared memory pages we can allocate now
+inline size_t PagesAvailable() { return PageLimit() - PageLevel(); }
+
+/// approximate total number of shared memory pages we can allocate
+/// now for given purpose
+inline size_t PagesAvailable(const int purpose) { return PageLimit(purpose) - PageLevel(purpose); }
+
+/// returns page size in bytes; all pages are assumed to be the same size
+size_t PageSize();
+
+} // namespace Mem
+
+} // namespace Ipc
+
+#endif // SQUID_IPC_MEM_PAGES_H
diff -u -r -N squid-3.2.0.12/src/ipc/mem/PageStack.cc squid-3.2.0.13/src/ipc/mem/PageStack.cc
--- squid-3.2.0.12/src/ipc/mem/PageStack.cc	1970-01-01 12:00:00.000000000 +1200
+++ squid-3.2.0.13/src/ipc/mem/PageStack.cc	2011-10-14 14:42:56.000000000 +1300
@@ -0,0 +1,131 @@
+/*
+ * $Id$
+ *
+ * DEBUG: section 54    Interprocess Communication
+ *
+ */
+
+#include "config.h"
+
+#include "base/TextException.h"
+#include "ipc/mem/Page.h"
+#include "ipc/mem/PageStack.h"
+
+/// used to mark a stack slot available for storing free page offsets
+const Ipc::Mem::PageStack::Value Writable = 0;
+
+
+Ipc::Mem::PageStack::PageStack(const uint32_t aPoolId, const unsigned int aCapacity, const size_t aPageSize):
+        thePoolId(aPoolId), theCapacity(aCapacity), thePageSize(aPageSize),
+        theSize(theCapacity),
+        theLastReadable(prev(theSize)), theFirstWritable(next(theLastReadable))
+{
+    // initially, all pages are free
+    for (Offset i = 0; i < theSize; ++i)
+        theItems[i] = i + 1; // skip page number zero to keep numbers positive
+}
+
+/*
+ * TODO: We currently rely on the theLastReadable hint during each
+ * loop iteration. We could also use hint just for the start position:
+ * (const Offset start = theLastReadable) and then scan the stack
+ * sequentially regardless of theLastReadable changes by others. Which
+ * approach is better? Same for push().
+ */
+bool
+Ipc::Mem::PageStack::pop(PageId &page)
+{
+    Must(!page);
+
+    // we may fail to dequeue, but be conservative to prevent long searches
+    --theSize;
+
+    // find a Readable slot, starting with theLastReadable and going left
+    while (theSize >= 0) {
+        const Offset idx = theLastReadable;
+        // mark the slot at ids Writable while extracting its current value
+        const Value value = theItems[idx].fetchAndAnd(0); // works if Writable is 0
+        const bool popped = value != Writable;
+        // theItems[idx] is probably not Readable [any more]
+
+        // Whether we popped a Readable value or not, we should try going left
+        // to maintain the index (and make progress).
+        // We may fail if others already updated the index, but that is OK.
+        theLastReadable.swap_if(idx, prev(idx)); // may fail or lie
+
+        if (popped) {
+            // the slot we emptied may already be filled, but that is OK
+            theFirstWritable = idx; // may lie
+            page.pool = thePoolId;
+            page.number = value;
+            return true;
+        }
+        // TODO: report suspiciously long loops
+    }
+
+    ++theSize;
+    return false;
+}
+
+void
+Ipc::Mem::PageStack::push(PageId &page)
+{
+    if (!page)
+        return;
+
+    Must(pageIdIsValid(page));
+    // find a Writable slot, starting with theFirstWritable and going right
+    while (theSize < theCapacity) {
+        const Offset idx = theFirstWritable;
+        const bool pushed = theItems[idx].swap_if(Writable, page.number);
+        // theItems[idx] is probably not Writable [any more];
+
+        // Whether we pushed the page number or not, we should try going right
+        // to maintain the index (and make progress).
+        // We may fail if others already updated the index, but that is OK.
+        theFirstWritable.swap_if(idx, next(idx)); // may fail or lie
+
+        if (pushed) {
+            // the enqueued value may already by gone, but that is OK
+            theLastReadable = idx; // may lie
+            ++theSize;
+            page = PageId();
+            return;
+        }
+        // TODO: report suspiciously long loops
+    }
+    Must(false); // the number of pages cannot exceed theCapacity
+}
+
+bool
+Ipc::Mem::PageStack::pageIdIsValid(const PageId &page) const
+{
+    return page.pool == thePoolId && page.number != Writable &&
+           page.number <= capacity();
+}
+
+size_t
+Ipc::Mem::PageStack::sharedMemorySize() const
+{
+    return SharedMemorySize(thePoolId, theCapacity, thePageSize);
+}
+
+size_t
+Ipc::Mem::PageStack::SharedMemorySize(const uint32_t, const unsigned int capacity, const size_t pageSize)
+{
+    const size_t levelsSize = PageId::maxPurpose * sizeof(AtomicWord);
+    const size_t pagesDataSize = capacity * pageSize;
+    return StackSize(capacity) + pagesDataSize + levelsSize;
+}
+
+size_t
+Ipc::Mem::PageStack::StackSize(const unsigned int capacity)
+{
+    return sizeof(PageStack) + capacity * sizeof(Item);
+}
+
+size_t
+Ipc::Mem::PageStack::stackSize() const
+{
+    return StackSize(theCapacity);
+}
diff -u -r -N squid-3.2.0.12/src/ipc/mem/PageStack.h squid-3.2.0.13/src/ipc/mem/PageStack.h
--- squid-3.2.0.12/src/ipc/mem/PageStack.h	1970-01-01 12:00:00.000000000 +1200
+++ squid-3.2.0.13/src/ipc/mem/PageStack.h	2011-10-14 14:42:56.000000000 +1300
@@ -0,0 +1,77 @@
+/*
+ * $Id$
+ *
+ */
+
+#ifndef SQUID_IPC_MEM_PAGE_STACK_H
+#define SQUID_IPC_MEM_PAGE_STACK_H
+
+#include "ipc/AtomicWord.h"
+
+namespace Ipc
+{
+
+namespace Mem
+{
+
+class PageId;
+
+/// Atomic container of "free" page numbers inside a single SharedMemory space.
+/// Assumptions: all page numbers are unique, positive, have an known maximum,
+/// and can be temporary unavailable as long as they are never trully lost.
+class PageStack
+{
+public:
+    typedef uint32_t Value; ///< stack item type (a free page number)
+
+    PageStack(const uint32_t aPoolId, const unsigned int aCapacity, const size_t aPageSize);
+
+    unsigned int capacity() const { return theCapacity; }
+    size_t pageSize() const { return thePageSize; }
+    /// lower bound for the number of free pages
+    unsigned int size() const { return max(0, theSize.get()); }
+
+    /// sets value and returns true unless no free page numbers are found
+    bool pop(PageId &page);
+    /// makes value available as a free page number to future pop() callers
+    void push(PageId &page);
+
+    bool pageIdIsValid(const PageId &page) const;
+
+    /// total shared memory size required to share
+    static size_t SharedMemorySize(const uint32_t aPoolId, const unsigned int capacity, const size_t pageSize);
+    size_t sharedMemorySize() const;
+
+    /// shared memory size required only by PageStack, excluding
+    /// shared counters and page data
+    static size_t StackSize(const unsigned int capacity);
+    size_t stackSize() const;
+
+private:
+    /// stack index and size type (may temporary go negative)
+    typedef int Offset;
+
+    // these help iterate the stack in search of a free spot or a page
+    Offset next(const Offset idx) const { return (idx + 1) % theCapacity; }
+    Offset prev(const Offset idx) const { return (theCapacity + idx - 1) % theCapacity; }
+
+    const uint32_t thePoolId; ///< pool ID
+    const Offset theCapacity; ///< stack capacity, i.e. theItems size
+    const size_t thePageSize; ///< page size, used to calculate shared memory size
+    /// lower bound for the number of free pages (may get negative!)
+    AtomicWordT<Offset> theSize;
+
+    /// last readable item index; just a hint, not a guarantee
+    AtomicWordT<Offset> theLastReadable;
+    /// first writable item index; just a hint, not a guarantee
+    AtomicWordT<Offset> theFirstWritable;
+
+    typedef AtomicWordT<Value> Item;
+    Item theItems[]; ///< page number storage
+};
+
+} // namespace Mem
+
+} // namespace Ipc
+
+#endif // SQUID_IPC_MEM_PAGE_STACK_H
diff -u -r -N squid-3.2.0.12/src/ipc/mem/Pointer.h squid-3.2.0.13/src/ipc/mem/Pointer.h
--- squid-3.2.0.12/src/ipc/mem/Pointer.h	1970-01-01 12:00:00.000000000 +1200
+++ squid-3.2.0.13/src/ipc/mem/Pointer.h	2011-10-14 14:42:56.000000000 +1300
@@ -0,0 +1,180 @@
+/*
+ * $Id$
+ *
+ */
+
+#ifndef SQUID_IPC_MEM_POINTER_H
+#define SQUID_IPC_MEM_POINTER_H
+
+#include "base/TextException.h"
+#include "ipc/mem/Segment.h"
+#include "RefCount.h"
+
+namespace Ipc
+{
+
+namespace Mem
+{
+
+/// allocates/deallocates shared memory; creates and later destroys a
+/// Class object using that memory
+template <class Class>
+class Owner
+{
+public:
+    static Owner *New(const char *const id);
+    template <class P1>
+    static Owner *New(const char *const id, const P1 &p1);
+    template <class P1, class P2>
+    static Owner *New(const char *const id, const P1 &p1, const P2 &p2);
+    template <class P1, class P2, class P3>
+    static Owner *New(const char *const id, const P1 &p1, const P2 &p2, const P3 &p3);
+    template <class P1, class P2, class P3, class P4>
+    static Owner *New(const char *const id, const P1 &p1, const P2 &p2, const P3 &p3, const P4 &p4);
+
+    ~Owner();
+
+private:
+    Owner(const char *const id, const off_t sharedSize);
+
+    // not implemented
+    Owner(const Owner &);
+    Owner &operator =(const Owner &);
+
+    Segment theSegment; ///< shared memory segment that holds the object
+    Class *theObject; ///< shared object
+};
+
+template <class Class> class Pointer;
+
+/// attaches to a shared memory segment with Class object owned by Owner
+template <class Class>
+class Object: public RefCountable
+{
+public:
+    static Pointer<Class> Old(const char *const id);
+
+private:
+    explicit Object(const char *const id);
+
+    // not implemented
+    Object(const Object &);
+    Object &operator =(const Object &);
+
+    Segment theSegment; ///< shared memory segment that holds the object
+    Class *theObject; ///< shared object
+
+    friend class Pointer<Class>;
+};
+
+/// uses a refcounted pointer to Object<Class> as a parent, but
+/// translates its API to return raw Class pointers
+template <class Class>
+class Pointer: public RefCount< Object<Class> >
+{
+private:
+    typedef RefCount< Object<Class> > Base;
+
+public:
+    explicit Pointer(Object<Class> *const anObject = NULL): Base(anObject) {}
+
+    Class *operator ->() const { return Base::operator ->()->theObject; }
+    Class &operator *() const { return *Base::operator *().theObject; }
+    const Class *getRaw() const { return Base::getRaw()->theObject; }
+    Class *getRaw() { return Base::getRaw()->theObject; }
+};
+
+// Owner implementation
+
+template <class Class>
+Owner<Class>::Owner(const char *const id, const off_t sharedSize):
+        theSegment(id), theObject(NULL)
+{
+    theSegment.create(sharedSize);
+    Must(theSegment.mem());
+}
+
+template <class Class>
+Owner<Class>::~Owner()
+{
+    if (theObject)
+        theObject->~Class();
+}
+
+template <class Class>
+Owner<Class> *
+Owner<Class>::New(const char *const id)
+{
+    const off_t sharedSize = Class::SharedMemorySize();
+    Owner *const owner = new Owner(id, sharedSize);
+    owner->theObject = new (owner->theSegment.reserve(sharedSize)) Class;
+    return owner;
+}
+
+template <class Class> template <class P1>
+Owner<Class> *
+Owner<Class>::New(const char *const id, const P1 &p1)
+{
+    const off_t sharedSize = Class::SharedMemorySize(p1);
+    Owner *const owner = new Owner(id, sharedSize);
+    owner->theObject = new (owner->theSegment.reserve(sharedSize)) Class(p1);
+    return owner;
+}
+
+template <class Class> template <class P1, class P2>
+Owner<Class> *
+Owner<Class>::New(const char *const id, const P1 &p1, const P2 &p2)
+{
+    const off_t sharedSize = Class::SharedMemorySize(p1, p2);
+    Owner *const owner = new Owner(id, sharedSize);
+    owner->theObject = new (owner->theSegment.reserve(sharedSize)) Class(p1, p2);
+    return owner;
+}
+
+template <class Class> template <class P1, class P2, class P3>
+Owner<Class> *
+Owner<Class>::New(const char *const id, const P1 &p1, const P2 &p2, const P3 &p3)
+{
+    const off_t sharedSize = Class::SharedMemorySize(p1, p2, p3);
+    Owner *const owner = new Owner(id, sharedSize);
+    owner->theObject = new (owner->theSegment.reserve(sharedSize)) Class(p1, p2, p3);
+    return owner;
+}
+
+template <class Class> template <class P1, class P2, class P3, class P4>
+Owner<Class> *
+Owner<Class>::New(const char *const id, const P1 &p1, const P2 &p2, const P3 &p3, const P4 &p4)
+{
+    const off_t sharedSize = Class::SharedMemorySize(p1, p2, p3, p4);
+    Owner *const owner = new Owner(id, sharedSize);
+    owner->theObject = new (owner->theSegment.reserve(sharedSize)) Class(p1, p2, p3, p4);
+    return owner;
+}
+
+// Object implementation
+
+template <class Class>
+Object<Class>::Object(const char *const id): theSegment(id)
+{
+    theSegment.open();
+    Must(theSegment.mem());
+    theObject = reinterpret_cast<Class*>(theSegment.mem());
+    Must(static_cast<off_t>(theObject->sharedMemorySize()) == theSegment.size());
+}
+
+template <class Class>
+Pointer<Class>
+Object<Class>::Old(const char *const id)
+{
+    return Pointer<Class>(new Object(id));
+}
+
+// convenience macros for creating shared objects
+#define shm_new(Class) Ipc::Mem::Owner<Class>::New
+#define shm_old(Class) Ipc::Mem::Object<Class>::Old
+
+} // namespace Mem
+
+} // namespace Ipc
+
+#endif /* SQUID_IPC_MEM_POINTER_H */
diff -u -r -N squid-3.2.0.12/src/ipc/mem/Segment.cc squid-3.2.0.13/src/ipc/mem/Segment.cc
--- squid-3.2.0.12/src/ipc/mem/Segment.cc	1970-01-01 12:00:00.000000000 +1200
+++ squid-3.2.0.13/src/ipc/mem/Segment.cc	2011-10-14 14:42:56.000000000 +1300
@@ -0,0 +1,278 @@
+/*
+ * $Id$
+ *
+ * DEBUG: section 54    Interprocess Communication
+ *
+ */
+
+#include "config.h"
+#include "base/TextException.h"
+#include "compat/shm.h"
+#include "ipc/mem/Segment.h"
+#include "protos.h"
+
+#include <fcntl.h>
+#include <sys/mman.h>
+#include <sys/stat.h>
+#include <unistd.h>
+
+void *
+Ipc::Mem::Segment::reserve(size_t chunkSize)
+{
+    Must(theMem);
+    // check for overflows
+    // chunkSize >= 0 may result in warnings on systems where off_t is unsigned
+    assert(!chunkSize || static_cast<off_t>(chunkSize) > 0);
+    assert(static_cast<off_t>(chunkSize) <= theSize);
+    assert(theReserved <= theSize - static_cast<off_t>(chunkSize));
+    void *result = reinterpret_cast<char*>(theMem) + theReserved;
+    theReserved += chunkSize;
+    return result;
+}
+
+#if HAVE_SHM
+
+Ipc::Mem::Segment::Segment(const char *const id):
+        theFD(-1), theName(GenerateName(id)), theMem(NULL),
+        theSize(0), theReserved(0), doUnlink(false)
+{
+}
+
+Ipc::Mem::Segment::~Segment()
+{
+    if (theFD >= 0) {
+        detach();
+        if (close(theFD) != 0)
+            debugs(54, 5, HERE << "close " << theName << ": " << xstrerror());
+    }
+    if (doUnlink)
+        unlink();
+}
+
+// fake Ipc::Mem::Segment::Enabled (!HAVE_SHM) is more selective
+bool
+Ipc::Mem::Segment::Enabled()
+{
+    return true;
+}
+
+void
+Ipc::Mem::Segment::create(const off_t aSize)
+{
+    assert(aSize > 0);
+    assert(theFD < 0);
+
+    theFD = shm_open(theName.termedBuf(), O_CREAT | O_RDWR | O_TRUNC,
+                     S_IRUSR | S_IWUSR);
+    if (theFD < 0) {
+        debugs(54, 5, HERE << "shm_open " << theName << ": " << xstrerror());
+        fatal("Ipc::Mem::Segment::create failed to shm_open");
+    }
+
+    if (ftruncate(theFD, aSize)) {
+        debugs(54, 5, HERE << "ftruncate " << theName << ": " << xstrerror());
+        fatal("Ipc::Mem::Segment::create failed to ftruncate");
+    }
+
+    assert(statSize("Ipc::Mem::Segment::create") == aSize); // paranoid
+
+    theSize = aSize;
+    theReserved = 0;
+    doUnlink = true;
+
+    debugs(54, 3, HERE << "created " << theName << " segment: " << theSize);
+
+    attach();
+}
+
+void
+Ipc::Mem::Segment::open()
+{
+    assert(theFD < 0);
+
+    theFD = shm_open(theName.termedBuf(), O_RDWR, 0);
+    if (theFD < 0) {
+        debugs(54, 5, HERE << "shm_open " << theName << ": " << xstrerror());
+        String s = "Ipc::Mem::Segment::open failed to shm_open ";
+        s.append(theName);
+        fatal(s.termedBuf());
+    }
+
+    theSize = statSize("Ipc::Mem::Segment::open");
+
+    debugs(54, 3, HERE << "opened " << theName << " segment: " << theSize);
+
+    attach();
+}
+
+/// Map the shared memory segment to the process memory space.
+void
+Ipc::Mem::Segment::attach()
+{
+    assert(theFD >= 0);
+    assert(!theMem);
+
+    // mmap() accepts size_t for the size; we give it off_t which might
+    // be bigger; assert overflows until we support multiple mmap()s?
+    assert(theSize == static_cast<off_t>(static_cast<size_t>(theSize)));
+
+    void *const p =
+        mmap(NULL, theSize, PROT_READ | PROT_WRITE, MAP_SHARED, theFD, 0);
+    if (p == MAP_FAILED) {
+        debugs(54, 5, HERE << "mmap " << theName << ": " << xstrerror());
+        fatal("Ipc::Mem::Segment::attach failed to mmap");
+    }
+    theMem = p;
+}
+
+/// Unmap the shared memory segment from the process memory space.
+void
+Ipc::Mem::Segment::detach()
+{
+    if (!theMem)
+        return;
+
+    if (munmap(theMem, theSize)) {
+        debugs(54, 5, HERE << "munmap " << theName << ": " << xstrerror());
+        fatal("Ipc::Mem::Segment::detach failed to munmap");
+    }
+    theMem = 0;
+}
+
+void
+Ipc::Mem::Segment::unlink()
+{
+    if (shm_unlink(theName.termedBuf()) != 0)
+        debugs(54, 5, HERE << "shm_unlink(" << theName << "): " << xstrerror());
+    else
+        debugs(54, 3, HERE << "unlinked " << theName << " segment");
+}
+
+/// determines the size of the underlying "file"
+off_t
+Ipc::Mem::Segment::statSize(const char *context) const
+{
+    Must(theFD >= 0);
+
+    struct stat s;
+    memset(&s, 0, sizeof(s));
+
+    if (fstat(theFD, &s) != 0) {
+        debugs(54, 5, HERE << "fstat " << theName << ": " << xstrerror());
+        String s = context;
+        s.append("failed to fstat(2) ");
+        s.append(theName);
+        fatal(s.termedBuf());
+    }
+
+    return s.st_size;
+}
+
+/// Generate name for shared memory segment. Replaces all slashes with dots.
+String
+Ipc::Mem::Segment::GenerateName(const char *id)
+{
+    String name("/squid-");
+    for (const char *slash = strchr(id, '/'); slash; slash = strchr(id, '/')) {
+        if (id != slash) {
+            name.append(id, slash - id);
+            name.append('.');
+        }
+        id = slash + 1;
+    }
+    name.append(id);
+    return name;
+}
+
+#else // HAVE_SHM
+
+#include <map>
+
+typedef std::map<String, Ipc::Mem::Segment *> SegmentMap;
+static SegmentMap Segments;
+
+Ipc::Mem::Segment::Segment(const char *const id):
+        theName(id), theMem(NULL), theSize(0), theReserved(0), doUnlink(false)
+{
+}
+
+Ipc::Mem::Segment::~Segment()
+{
+    if (doUnlink) {
+        delete [] static_cast<char *>(theMem);
+        debugs(54, 3, HERE << "deleted " << theName << " segment");
+    }
+}
+
+bool
+Ipc::Mem::Segment::Enabled()
+{
+    return !InDaemonMode() || (!UsingSmp() && IamWorkerProcess());
+}
+
+void
+Ipc::Mem::Segment::create(const off_t aSize)
+{
+    assert(aSize > 0);
+    assert(!theMem);
+    checkSupport("Fake segment creation");
+
+    const bool inserted = Segments.insert(std::make_pair(theName, this)).second;
+    if (!inserted)
+        fatalf("Duplicate fake segment creation: %s", theName.termedBuf());
+
+    theMem = new char[aSize];
+    theSize = aSize;
+    doUnlink = true;
+
+    debugs(54, 3, HERE << "created " << theName << " fake segment: " << theSize);
+}
+
+void
+Ipc::Mem::Segment::open()
+{
+    assert(!theMem);
+    checkSupport("Fake segment open");
+
+    const SegmentMap::const_iterator i = Segments.find(theName);
+    if (i == Segments.end())
+        fatalf("Fake segment not found: %s", theName.termedBuf());
+
+    const Segment &segment = *i->second;
+    theMem = segment.theMem;
+    theSize = segment.theSize;
+
+    debugs(54, 3, HERE << "opened " << theName << " fake segment: " << theSize);
+}
+
+void
+Ipc::Mem::Segment::checkSupport(const char *const context)
+{
+    if (!Enabled()) {
+        debugs(54, 5, HERE << "True shared memory segments are not supported. "
+               "Cannot fake shared segments in SMP config.");
+        fatalf("%s failed", context);
+    }
+}
+
+#endif // HAVE_SHM
+
+void
+Ipc::Mem::RegisteredRunner::run(const RunnerRegistry &r)
+{
+    // If Squid is built with real segments, we create() real segments
+    // in the master process only.  Otherwise, we create() fake
+    // segments in each worker process.  We assume that only workers
+    // need and can work with fake segments.
+#if HAVE_SHM
+    if (IamMasterProcess())
+#else
+    if (IamWorkerProcess())
+#endif
+        create(r);
+
+    // we assume that master process does not need shared segments
+    // unless it is also a worker
+    if (!InDaemonMode() || !IamMasterProcess())
+        open(r);
+}
diff -u -r -N squid-3.2.0.12/src/ipc/mem/Segment.h squid-3.2.0.13/src/ipc/mem/Segment.h
--- squid-3.2.0.12/src/ipc/mem/Segment.h	1970-01-01 12:00:00.000000000 +1200
+++ squid-3.2.0.13/src/ipc/mem/Segment.h	2011-10-14 14:42:56.000000000 +1300
@@ -0,0 +1,89 @@
+/*
+ * $Id$
+ *
+ */
+
+#ifndef SQUID_IPC_MEM_SEGMENT_H
+#define SQUID_IPC_MEM_SEGMENT_H
+
+#include "base/RunnersRegistry.h"
+#include "SquidString.h"
+
+namespace Ipc
+{
+
+namespace Mem
+{
+
+/// POSIX shared memory segment
+class Segment
+{
+public:
+    /// Create a shared memory segment.
+    Segment(const char *const id);
+    ~Segment();
+
+    /// Whether shared memory support is available
+    static bool Enabled();
+
+    /// Create a new shared memory segment. Unlinks the segment on destruction.
+    void create(const off_t aSize);
+    void open(); ///< Open an existing shared memory segment.
+
+    const String &name() { return theName; } ///< shared memory segment name
+    off_t size() { return theSize; } ///< shared memory segment size
+    void *mem() { return reserve(0); } ///< pointer to the next chunk
+    void *reserve(size_t chunkSize); ///< reserve and return the next chunk
+
+
+private:
+
+    // not implemented
+    Segment(const Segment &);
+    Segment &operator =(const Segment &);
+
+#if HAVE_SHM
+
+    void attach();
+    void detach();
+    void unlink(); ///< unlink the segment
+    off_t statSize(const char *context) const;
+
+    static String GenerateName(const char *id);
+
+    int theFD; ///< shared memory segment file descriptor
+
+#else // HAVE_SHM
+
+    void checkSupport(const char *const context);
+
+#endif // HAVE_SHM
+
+    const String theName; ///< shared memory segment file name
+    void *theMem; ///< pointer to mmapped shared memory segment
+    off_t theSize; ///< shared memory segment size
+    off_t theReserved; ///< the total number of reserve()d bytes
+    bool doUnlink; ///< whether the segment should be unlinked on destruction
+};
+
+/// Base class for runners that create and open shared memory segments.
+/// First may run create() method and then open().
+class RegisteredRunner: public ::RegisteredRunner
+{
+public:
+    /* RegisteredRunner API */
+    virtual void run(const RunnerRegistry &r);
+
+protected:
+    /// called when the runner should create a new memory segment
+    virtual void create(const RunnerRegistry &) = 0;
+    /// called when the runner should open a previously created segment,
+    /// not needed if segments are opened in constructor or init methods
+    virtual void open(const RunnerRegistry &) {}
+};
+
+} // namespace Mem
+
+} // namespace Ipc
+
+#endif /* SQUID_IPC_MEM_SEGMENT_H */
diff -u -r -N squid-3.2.0.12/src/ipc/Messages.h squid-3.2.0.13/src/ipc/Messages.h
--- squid-3.2.0.12/src/ipc/Messages.h	2011-09-16 23:37:30.000000000 +1200
+++ squid-3.2.0.13/src/ipc/Messages.h	2011-10-14 14:42:56.000000000 +1300
@@ -15,7 +15,9 @@
 
 /// message class identifier
 typedef enum { mtNone = 0, mtRegistration,
+               mtStrandSearchRequest, mtStrandSearchResponse,
                mtSharedListenRequest, mtSharedListenResponse,
+               mtIpcIoNotification,
                mtCacheMgrRequest, mtCacheMgrResponse
 #if SQUID_SNMP
                ,
diff -u -r -N squid-3.2.0.12/src/ipc/Queue.cc squid-3.2.0.13/src/ipc/Queue.cc
--- squid-3.2.0.12/src/ipc/Queue.cc	1970-01-01 12:00:00.000000000 +1200
+++ squid-3.2.0.13/src/ipc/Queue.cc	2011-10-14 14:42:56.000000000 +1300
@@ -0,0 +1,285 @@
+/*
+ * $Id$
+ *
+ * DEBUG: section 54    Interprocess Communication
+ *
+ */
+
+#include "config.h"
+#include "base/TextException.h"
+#include "Debug.h"
+#include "globals.h"
+#include "ipc/Queue.h"
+
+/// constructs Metadata ID from parent queue ID
+static String
+MetadataId(String id)
+{
+    id.append("__metadata");
+    return id;
+}
+
+/// constructs one-to-one queues ID from parent queue ID
+static String
+QueuesId(String id)
+{
+    id.append("__queues");
+    return id;
+}
+
+/// constructs QueueReaders ID from parent queue ID
+static String
+ReadersId(String id)
+{
+    id.append("__readers");
+    return id;
+}
+
+
+/* QueueReader */
+
+InstanceIdDefinitions(Ipc::QueueReader, "ipcQR");
+
+Ipc::QueueReader::QueueReader(): popBlocked(1), popSignal(0),
+        rateLimit(0), balance(0)
+{
+    debugs(54, 7, HERE << "constructed " << id);
+}
+
+/* QueueReaders */
+
+Ipc::QueueReaders::QueueReaders(const int aCapacity): theCapacity(aCapacity)
+{
+    Must(theCapacity > 0);
+    new (theReaders) QueueReader[theCapacity];
+}
+
+size_t
+Ipc::QueueReaders::sharedMemorySize() const
+{
+    return SharedMemorySize(theCapacity);
+}
+
+size_t
+Ipc::QueueReaders::SharedMemorySize(const int capacity)
+{
+    return sizeof(QueueReaders) + sizeof(QueueReader) * capacity;
+}
+
+
+// OneToOneUniQueue
+
+Ipc::OneToOneUniQueue::OneToOneUniQueue(const unsigned int aMaxItemSize, const int aCapacity):
+        theIn(0), theOut(0), theSize(0), theMaxItemSize(aMaxItemSize),
+        theCapacity(aCapacity)
+{
+    Must(theMaxItemSize > 0);
+    Must(theCapacity > 0);
+}
+
+int
+Ipc::OneToOneUniQueue::Bytes2Items(const unsigned int maxItemSize, int size)
+{
+    assert(maxItemSize > 0);
+    size -= sizeof(OneToOneUniQueue);
+    return size >= 0 ? size / maxItemSize : 0;
+}
+
+int
+Ipc::OneToOneUniQueue::Items2Bytes(const unsigned int maxItemSize, const int size)
+{
+    assert(size >= 0);
+    return sizeof(OneToOneUniQueue) + maxItemSize * size;
+}
+
+
+/* OneToOneUniQueues */
+
+Ipc::OneToOneUniQueues::OneToOneUniQueues(const int aCapacity, const unsigned int maxItemSize, const int queueCapacity): theCapacity(aCapacity)
+{
+    Must(theCapacity > 0);
+    for (int i = 0; i < theCapacity; ++i)
+        new (&(*this)[i]) OneToOneUniQueue(maxItemSize, queueCapacity);
+}
+
+size_t
+Ipc::OneToOneUniQueues::sharedMemorySize() const
+{
+    return sizeof(*this) + theCapacity * front().sharedMemorySize();
+}
+
+size_t
+Ipc::OneToOneUniQueues::SharedMemorySize(const int capacity, const unsigned int maxItemSize, const int queueCapacity)
+{
+    const int queueSize =
+        OneToOneUniQueue::Items2Bytes(maxItemSize, queueCapacity);
+    return sizeof(OneToOneUniQueues) + queueSize * capacity;
+}
+
+const Ipc::OneToOneUniQueue &
+Ipc::OneToOneUniQueues::operator [](const int index) const
+{
+    Must(0 <= index && index < theCapacity);
+    const size_t queueSize = index ? front().sharedMemorySize() : 0;
+    const char *const queue =
+        reinterpret_cast<const char *>(this) + sizeof(*this) + index * queueSize;
+    return *reinterpret_cast<const OneToOneUniQueue *>(queue);
+}
+
+
+// FewToFewBiQueue
+
+Ipc::FewToFewBiQueue::Owner *
+Ipc::FewToFewBiQueue::Init(const String &id, const int groupASize, const int groupAIdOffset, const int groupBSize, const int groupBIdOffset, const unsigned int maxItemSize, const int capacity)
+{
+    return new Owner(id, groupASize, groupAIdOffset, groupBSize, groupBIdOffset, maxItemSize, capacity);
+}
+
+Ipc::FewToFewBiQueue::FewToFewBiQueue(const String &id, const Group aLocalGroup, const int aLocalProcessId):
+        metadata(shm_old(Metadata)(MetadataId(id).termedBuf())),
+        queues(shm_old(OneToOneUniQueues)(QueuesId(id).termedBuf())),
+        readers(shm_old(QueueReaders)(ReadersId(id).termedBuf())),
+        theLocalGroup(aLocalGroup), theLocalProcessId(aLocalProcessId),
+        theLastPopProcessId(readers->theCapacity)
+{
+    Must(queues->theCapacity == metadata->theGroupASize * metadata->theGroupBSize * 2);
+    Must(readers->theCapacity == metadata->theGroupASize + metadata->theGroupBSize);
+
+    const QueueReader &localReader = reader(theLocalGroup, theLocalProcessId);
+    debugs(54, 7, HERE << "queue " << id << " reader: " << localReader.id);
+}
+
+bool
+Ipc::FewToFewBiQueue::validProcessId(const Group group, const int processId) const
+{
+    switch (group) {
+    case groupA:
+        return metadata->theGroupAIdOffset <= processId &&
+               processId < metadata->theGroupAIdOffset + metadata->theGroupASize;
+    case groupB:
+        return metadata->theGroupBIdOffset <= processId &&
+               processId < metadata->theGroupBIdOffset + metadata->theGroupBSize;
+    }
+    return false;
+}
+
+int
+Ipc::FewToFewBiQueue::oneToOneQueueIndex(const Group fromGroup, const int fromProcessId, const Group toGroup, const int toProcessId) const
+{
+    Must(fromGroup != toGroup);
+    assert(validProcessId(fromGroup, fromProcessId));
+    assert(validProcessId(toGroup, toProcessId));
+    int index1;
+    int index2;
+    int offset;
+    if (fromGroup == groupA) {
+        index1 = fromProcessId - metadata->theGroupAIdOffset;
+        index2 = toProcessId - metadata->theGroupBIdOffset;
+        offset = 0;
+    } else {
+        index1 = toProcessId - metadata->theGroupAIdOffset;
+        index2 = fromProcessId - metadata->theGroupBIdOffset;
+        offset = metadata->theGroupASize * metadata->theGroupBSize;
+    }
+    const int index = offset + index1 * metadata->theGroupBSize + index2;
+    return index;
+}
+
+Ipc::OneToOneUniQueue &
+Ipc::FewToFewBiQueue::oneToOneQueue(const Group fromGroup, const int fromProcessId, const Group toGroup, const int toProcessId)
+{
+    return (*queues)[oneToOneQueueIndex(fromGroup, fromProcessId, toGroup, toProcessId)];
+}
+
+const Ipc::OneToOneUniQueue &
+Ipc::FewToFewBiQueue::oneToOneQueue(const Group fromGroup, const int fromProcessId, const Group toGroup, const int toProcessId) const
+{
+    return (*queues)[oneToOneQueueIndex(fromGroup, fromProcessId, toGroup, toProcessId)];
+}
+
+int
+Ipc::FewToFewBiQueue::readerIndex(const Group group, const int processId) const
+{
+    Must(validProcessId(group, processId));
+    return group == groupA ?
+           processId - metadata->theGroupAIdOffset :
+           metadata->theGroupASize + processId - metadata->theGroupBIdOffset;
+}
+
+Ipc::QueueReader &
+Ipc::FewToFewBiQueue::reader(const Group group, const int processId)
+{
+    return readers->theReaders[readerIndex(group, processId)];
+}
+
+const Ipc::QueueReader &
+Ipc::FewToFewBiQueue::reader(const Group group, const int processId) const
+{
+    return readers->theReaders[readerIndex(group, processId)];
+}
+
+void
+Ipc::FewToFewBiQueue::clearReaderSignal(const int remoteProcessId)
+{
+    QueueReader &localReader = reader(theLocalGroup, theLocalProcessId);
+    debugs(54, 7, HERE << "reader: " << localReader.id);
+
+    Must(validProcessId(remoteGroup(), remoteProcessId));
+    localReader.clearSignal();
+
+    // we got a hint; we could reposition iteration to try popping from the
+    // remoteProcessId queue first; but it does not seem to help much and might
+    // introduce some bias so we do not do that for now:
+    // theLastPopProcessId = remoteProcessId;
+}
+
+bool
+Ipc::FewToFewBiQueue::popReady() const
+{
+    // mimic FewToFewBiQueue::pop() but quit just before popping
+    int popProcessId = theLastPopProcessId; // preserve for future pop()
+    for (int i = 0; i < remoteGroupSize(); ++i) {
+        if (++popProcessId >= remoteGroupIdOffset() + remoteGroupSize())
+            popProcessId = remoteGroupIdOffset();
+        const OneToOneUniQueue &queue = oneToOneQueue(remoteGroup(), popProcessId, theLocalGroup, theLocalProcessId);
+        if (!queue.empty())
+            return true;
+    }
+    return false; // most likely, no process had anything to pop
+}
+
+Ipc::QueueReader::Balance &
+Ipc::FewToFewBiQueue::localBalance()
+{
+    QueueReader &r = reader(theLocalGroup, theLocalProcessId);
+    return r.balance;
+}
+
+Ipc::QueueReader::Rate &
+Ipc::FewToFewBiQueue::localRateLimit()
+{
+    QueueReader &r = reader(theLocalGroup, theLocalProcessId);
+    return r.rateLimit;
+}
+
+Ipc::FewToFewBiQueue::Metadata::Metadata(const int aGroupASize, const int aGroupAIdOffset, const int aGroupBSize, const int aGroupBIdOffset):
+        theGroupASize(aGroupASize), theGroupAIdOffset(aGroupAIdOffset),
+        theGroupBSize(aGroupBSize), theGroupBIdOffset(aGroupBIdOffset)
+{
+    Must(theGroupASize > 0);
+    Must(theGroupBSize > 0);
+}
+
+Ipc::FewToFewBiQueue::Owner::Owner(const String &id, const int groupASize, const int groupAIdOffset, const int groupBSize, const int groupBIdOffset, const unsigned int maxItemSize, const int capacity):
+        metadataOwner(shm_new(Metadata)(MetadataId(id).termedBuf(), groupASize, groupAIdOffset, groupBSize, groupBIdOffset)),
+        queuesOwner(shm_new(OneToOneUniQueues)(QueuesId(id).termedBuf(), groupASize*groupBSize*2, maxItemSize, capacity)),
+        readersOwner(shm_new(QueueReaders)(ReadersId(id).termedBuf(), groupASize+groupBSize))
+{
+}
+
+Ipc::FewToFewBiQueue::Owner::~Owner()
+{
+    delete metadataOwner;
+    delete queuesOwner;
+    delete readersOwner;
+}
diff -u -r -N squid-3.2.0.12/src/ipc/Queue.h squid-3.2.0.13/src/ipc/Queue.h
--- squid-3.2.0.12/src/ipc/Queue.h	1970-01-01 12:00:00.000000000 +1200
+++ squid-3.2.0.13/src/ipc/Queue.h	2011-10-14 14:42:56.000000000 +1300
@@ -0,0 +1,373 @@
+/*
+ * $Id$
+ *
+ */
+
+#ifndef SQUID_IPC_QUEUE_H
+#define SQUID_IPC_QUEUE_H
+
+#include "Array.h"
+#include "Debug.h"
+#include "base/InstanceId.h"
+#include "ipc/AtomicWord.h"
+#include "ipc/mem/Pointer.h"
+#include "util.h"
+
+class String;
+
+namespace Ipc
+{
+
+/// State of the reading end of a queue (i.e., of the code calling pop()).
+/// Multiple queues attached to one reader share this state.
+class QueueReader
+{
+public:
+    QueueReader(); // the initial state is "blocked without a signal"
+
+    /// whether the reader is waiting for a notification signal
+    bool blocked() const { return popBlocked == 1; }
+
+    /// marks the reader as blocked, waiting for a notification signal
+    void block() { popBlocked.swap_if(0, 1); }
+
+    /// removes the block() effects
+    void unblock() { popBlocked.swap_if(1, 0); }
+
+    /// if reader is blocked and not notified, marks the notification signal
+    /// as sent and not received, returning true; otherwise, returns false
+    bool raiseSignal() { return blocked() && popSignal.swap_if(0,1); }
+
+    /// marks sent reader notification as received (also removes pop blocking)
+    void clearSignal() { unblock(); popSignal.swap_if(1,0); }
+
+private:
+    AtomicWord popBlocked; ///< whether the reader is blocked on pop()
+    AtomicWord popSignal; ///< whether writer has sent and reader has not received notification
+
+public:
+    typedef AtomicWord Rate; ///< pop()s per second
+    Rate rateLimit; ///< pop()s per second limit if positive
+
+    // we need a signed atomic type because balance may get negative
+    typedef AtomicWordT<int> AtomicSignedMsec;
+    typedef AtomicSignedMsec Balance;
+    /// how far ahead the reader is compared to a perfect read/sec event rate
+    Balance balance;
+
+    /// unique ID for debugging which reader is used (works across processes)
+    const InstanceId<QueueReader> id;
+};
+
+/// shared array of QueueReaders
+class QueueReaders
+{
+public:
+    QueueReaders(const int aCapacity);
+    size_t sharedMemorySize() const;
+    static size_t SharedMemorySize(const int capacity);
+
+    const int theCapacity; /// number of readers
+    QueueReader theReaders[]; /// readers
+};
+
+/**
+ * Lockless fixed-capacity queue for a single writer and a single reader.
+ *
+ * If the queue is empty, the reader is considered "blocked" and needs
+ * an out-of-band notification message to notice the next pushed item.
+ *
+ * Current implementation assumes that the writer cannot get blocked: if the
+ * queue is full, the writer will just not push and come back later (with a
+ * different value). We can add support for blocked writers if needed.
+ */
+class OneToOneUniQueue
+{
+public:
+    // pop() and push() exceptions; TODO: use TextException instead
+    class Full {};
+    class ItemTooLarge {};
+
+    OneToOneUniQueue(const unsigned int aMaxItemSize, const int aCapacity);
+
+    unsigned int maxItemSize() const { return theMaxItemSize; }
+    int size() const { return theSize; }
+    int capacity() const { return theCapacity; }
+    int sharedMemorySize() const { return Items2Bytes(theMaxItemSize, theCapacity); }
+
+    bool empty() const { return !theSize; }
+    bool full() const { return theSize == theCapacity; }
+
+    static int Bytes2Items(const unsigned int maxItemSize, int size);
+    static int Items2Bytes(const unsigned int maxItemSize, const int size);
+
+    /// returns true iff the value was set; [un]blocks the reader as needed
+    template<class Value> bool pop(Value &value, QueueReader *const reader = NULL);
+
+    /// returns true iff the caller must notify the reader of the pushed item
+    template<class Value> bool push(const Value &value, QueueReader *const reader = NULL);
+
+    /// returns true iff the value was set; the value may be stale!
+    template<class Value> bool peek(Value &value) const;
+
+private:
+
+    unsigned int theIn; ///< input index, used only in push()
+    unsigned int theOut; ///< output index, used only in pop()
+
+    AtomicWord theSize; ///< number of items in the queue
+    const unsigned int theMaxItemSize; ///< maximum item size
+    const int theCapacity; ///< maximum number of items, i.e. theBuffer size
+
+    char theBuffer[];
+};
+
+/// shared array of OneToOneUniQueues
+class OneToOneUniQueues
+{
+public:
+    OneToOneUniQueues(const int aCapacity, const unsigned int maxItemSize, const int queueCapacity);
+
+    size_t sharedMemorySize() const;
+    static size_t SharedMemorySize(const int capacity, const unsigned int maxItemSize, const int queueCapacity);
+
+    const OneToOneUniQueue &operator [](const int index) const;
+    inline OneToOneUniQueue &operator [](const int index);
+
+private:
+    inline const OneToOneUniQueue &front() const;
+
+public:
+    const int theCapacity; /// number of OneToOneUniQueues
+};
+
+/**
+ * Lockless fixed-capacity bidirectional queue for a limited number
+ * processes. Allows communication between two groups of processes:
+ * any process in one group may send data to and receive from any
+ * process in another group, but processes in the same group can not
+ * communicate. Process in each group has a unique integer ID in
+ * [groupIdOffset, groupIdOffset + groupSize) range.
+ */
+class FewToFewBiQueue
+{
+public:
+    typedef OneToOneUniQueue::Full Full;
+    typedef OneToOneUniQueue::ItemTooLarge ItemTooLarge;
+
+private:
+    /// Shared metadata for FewToFewBiQueue
+    struct Metadata {
+        Metadata(const int aGroupASize, const int aGroupAIdOffset, const int aGroupBSize, const int aGroupBIdOffset);
+        size_t sharedMemorySize() const { return sizeof(*this); }
+        static size_t SharedMemorySize(const int, const int, const int, const int) { return sizeof(Metadata); }
+
+        const int theGroupASize;
+        const int theGroupAIdOffset;
+        const int theGroupBSize;
+        const int theGroupBIdOffset;
+    };
+
+public:
+    class Owner
+    {
+    public:
+        Owner(const String &id, const int groupASize, const int groupAIdOffset, const int groupBSize, const int groupBIdOffset, const unsigned int maxItemSize, const int capacity);
+        ~Owner();
+
+    private:
+        Mem::Owner<Metadata> *const metadataOwner;
+        Mem::Owner<OneToOneUniQueues> *const queuesOwner;
+        Mem::Owner<QueueReaders> *const readersOwner;
+    };
+
+    static Owner *Init(const String &id, const int groupASize, const int groupAIdOffset, const int groupBSize, const int groupBIdOffset, const unsigned int maxItemSize, const int capacity);
+
+    enum Group { groupA = 0, groupB = 1 };
+    FewToFewBiQueue(const String &id, const Group aLocalGroup, const int aLocalProcessId);
+
+    Group localGroup() const { return theLocalGroup; }
+    Group remoteGroup() const { return theLocalGroup == groupA ? groupB : groupA; }
+
+    /// clears the reader notification received by the local process from the remote process
+    void clearReaderSignal(const int remoteProcessId);
+
+    /// picks a process and calls OneToOneUniQueue::pop() using its queue
+    template <class Value> bool pop(int &remoteProcessId, Value &value);
+
+    /// calls OneToOneUniQueue::push() using the given process queue
+    template <class Value> bool push(const int remoteProcessId, const Value &value);
+
+    // TODO: rename to findOldest() or some such
+    /// calls OneToOneUniQueue::peek() using the given process queue
+    template<class Value> bool peek(const int remoteProcessId, Value &value) const;
+
+    /// returns true if pop() would have probably succeeded but does not pop()
+    bool popReady() const;
+
+    /// returns local reader's balance
+    QueueReader::Balance &localBalance();
+
+    /// returns local reader's rate limit
+    QueueReader::Rate &localRateLimit();
+
+private:
+    bool validProcessId(const Group group, const int processId) const;
+    int oneToOneQueueIndex(const Group fromGroup, const int fromProcessId, const Group toGroup, const int toProcessId) const;
+    const OneToOneUniQueue &oneToOneQueue(const Group fromGroup, const int fromProcessId, const Group toGroup, const int toProcessId) const;
+    OneToOneUniQueue &oneToOneQueue(const Group fromGroup, const int fromProcessId, const Group toGroup, const int toProcessId);
+    QueueReader &reader(const Group group, const int processId);
+    const QueueReader &reader(const Group group, const int processId) const;
+    int readerIndex(const Group group, const int processId) const;
+    int remoteGroupSize() const { return theLocalGroup == groupA ? metadata->theGroupBSize : metadata->theGroupASize; }
+    int remoteGroupIdOffset() const { return theLocalGroup == groupA ? metadata->theGroupBIdOffset : metadata->theGroupAIdOffset; }
+
+private:
+    const Mem::Pointer<Metadata> metadata; ///< shared metadata
+    const Mem::Pointer<OneToOneUniQueues> queues; ///< unidirection one-to-one queues
+    const Mem::Pointer<QueueReaders> readers; ///< readers array
+
+    const Group theLocalGroup; ///< group of this queue
+    const int theLocalProcessId; ///< process ID of this queue
+    int theLastPopProcessId; ///< the ID of the last process we tried to pop() from
+};
+
+
+// OneToOneUniQueue
+
+template <class Value>
+bool
+OneToOneUniQueue::pop(Value &value, QueueReader *const reader)
+{
+    if (sizeof(value) > theMaxItemSize)
+        throw ItemTooLarge();
+
+    // A writer might push between the empty test and block() below, so we do
+    // not return false right after calling block(), but test again.
+    if (empty()) {
+        if (!reader)
+            return false;
+
+        reader->block();
+        // A writer might push between the empty test and block() below,
+        // so we must test again as such a writer will not signal us.
+        if (empty())
+            return false;
+    }
+
+    if (reader)
+        reader->unblock();
+
+    const unsigned int pos = (theOut++ % theCapacity) * theMaxItemSize;
+    memcpy(&value, theBuffer + pos, sizeof(value));
+    --theSize;
+
+    return true;
+}
+
+template <class Value>
+bool
+OneToOneUniQueue::peek(Value &value) const
+{
+    if (sizeof(value) > theMaxItemSize)
+        throw ItemTooLarge();
+
+    if (empty())
+        return false;
+
+    // the reader may pop() before we copy; making this method imprecise
+    const unsigned int pos = (theOut % theCapacity) * theMaxItemSize;
+    memcpy(&value, theBuffer + pos, sizeof(value));
+    return true;
+}
+
+template <class Value>
+bool
+OneToOneUniQueue::push(const Value &value, QueueReader *const reader)
+{
+    if (sizeof(value) > theMaxItemSize)
+        throw ItemTooLarge();
+
+    if (full())
+        throw Full();
+
+    const bool wasEmpty = empty();
+    const unsigned int pos = theIn++ % theCapacity * theMaxItemSize;
+    memcpy(theBuffer + pos, &value, sizeof(value));
+    ++theSize;
+
+    return wasEmpty && (!reader || reader->raiseSignal());
+}
+
+
+// OneToOneUniQueues
+
+inline OneToOneUniQueue &
+OneToOneUniQueues::operator [](const int index)
+{
+    return const_cast<OneToOneUniQueue &>((*const_cast<const OneToOneUniQueues *>(this))[index]);
+}
+
+inline const OneToOneUniQueue &
+OneToOneUniQueues::front() const
+{
+    const char *const queue =
+        reinterpret_cast<const char *>(this) + sizeof(*this);
+    return *reinterpret_cast<const OneToOneUniQueue *>(queue);
+}
+
+
+// FewToFewBiQueue
+
+template <class Value>
+bool
+FewToFewBiQueue::pop(int &remoteProcessId, Value &value)
+{
+    // iterate all remote group processes, starting after the one we visited last
+    QueueReader &localReader = reader(theLocalGroup, theLocalProcessId);
+    for (int i = 0; i < remoteGroupSize(); ++i) {
+        if (++theLastPopProcessId >= remoteGroupIdOffset() + remoteGroupSize())
+            theLastPopProcessId = remoteGroupIdOffset();
+        OneToOneUniQueue &queue = oneToOneQueue(remoteGroup(), theLastPopProcessId, theLocalGroup, theLocalProcessId);
+        if (queue.pop(value, &localReader)) {
+            remoteProcessId = theLastPopProcessId;
+            debugs(54, 7, HERE << "popped from " << remoteProcessId << " to " << theLocalProcessId << " at " << queue.size());
+            return true;
+        }
+    }
+    return false; // no process had anything to pop
+}
+
+template <class Value>
+bool
+FewToFewBiQueue::push(const int remoteProcessId, const Value &value)
+{
+    OneToOneUniQueue &remoteQueue = oneToOneQueue(theLocalGroup, theLocalProcessId, remoteGroup(), remoteProcessId);
+    QueueReader &remoteReader = reader(remoteGroup(), remoteProcessId);
+    debugs(54, 7, HERE << "pushing from " << theLocalProcessId << " to " << remoteProcessId << " at " << remoteQueue.size());
+    return remoteQueue.push(value, &remoteReader);
+}
+
+template <class Value>
+bool
+FewToFewBiQueue::peek(const int remoteProcessId, Value &value) const
+{
+    // we may be called before remote process configured its queue end
+    if (!validProcessId(remoteGroup(), remoteProcessId))
+        return false;
+
+    // we need the oldest value, so start with the incoming, them-to-us queue:
+    const OneToOneUniQueue &inQueue = oneToOneQueue(remoteGroup(), remoteProcessId, theLocalGroup, theLocalProcessId);
+    debugs(54, 2, HERE << "peeking from " << remoteProcessId << " to " << theLocalProcessId << " at " << inQueue.size());
+    if (inQueue.peek(value))
+        return true;
+
+    // if the incoming queue is empty, check the outgoing, us-to-them queue:
+    const OneToOneUniQueue &outQueue = oneToOneQueue(theLocalGroup, theLocalProcessId, remoteGroup(), remoteProcessId);
+    debugs(54, 2, HERE << "peeking from " << theLocalProcessId << " to " << remoteProcessId << " at " << outQueue.size());
+    return outQueue.peek(value);
+}
+
+} // namespace Ipc
+
+#endif // SQUID_IPC_QUEUE_H
diff -u -r -N squid-3.2.0.12/src/ipc/ReadWriteLock.cc squid-3.2.0.13/src/ipc/ReadWriteLock.cc
--- squid-3.2.0.12/src/ipc/ReadWriteLock.cc	1970-01-01 12:00:00.000000000 +1200
+++ squid-3.2.0.13/src/ipc/ReadWriteLock.cc	2011-10-14 14:42:56.000000000 +1300
@@ -0,0 +1,97 @@
+/*
+ * $Id$
+ *
+ * DEBUG: section 54    Interprocess Communication
+ */
+
+#include "squid.h"
+
+#include "Store.h"
+#include "ipc/ReadWriteLock.h"
+
+bool
+Ipc::ReadWriteLock::lockShared()
+{
+    ++readers; // this locks "new" writers out
+    if (!writers) // there are no old writers
+        return true;
+    --readers;
+    return false;
+}
+
+bool
+Ipc::ReadWriteLock::lockExclusive()
+{
+    if (!writers++) { // we are the first writer + this locks "new" readers out
+        if (!readers) // there are no old readers
+            return true;
+    }
+    --writers;
+    return false;
+}
+
+void
+Ipc::ReadWriteLock::unlockShared()
+{
+    assert(readers-- > 0);
+}
+
+void
+Ipc::ReadWriteLock::unlockExclusive()
+{
+    assert(writers-- > 0);
+}
+
+void
+Ipc::ReadWriteLock::switchExclusiveToShared()
+{
+    ++readers; // must be done before we release exclusive control
+    unlockExclusive();
+}
+
+void
+Ipc::ReadWriteLock::updateStats(ReadWriteLockStats &stats) const
+{
+    if (readers) {
+        ++stats.readable;
+        stats.readers += readers;
+    } else if (writers) {
+        ++stats.writeable;
+        stats.writers += writers;
+    } else {
+        ++stats.idle;
+    }
+    ++stats.count;
+}
+
+
+/* Ipc::ReadWriteLockStats */
+
+Ipc::ReadWriteLockStats::ReadWriteLockStats()
+{
+    memset(this, 0, sizeof(*this));
+}
+
+void
+Ipc::ReadWriteLockStats::dump(StoreEntry &e) const
+{
+    storeAppendPrintf(&e, "Available locks: %9d\n", count);
+
+    if (!count)
+        return;
+
+    storeAppendPrintf(&e, "Reading: %9d %6.2f%%\n",
+                      readable, (100.0 * readable / count));
+    storeAppendPrintf(&e, "Writing: %9d %6.2f%%\n",
+                      writeable, (100.0 * writeable / count));
+    storeAppendPrintf(&e, "Idle:    %9d %6.2f%%\n",
+                      idle, (100.0 * idle / count));
+
+    if (readers || writers) {
+        const int locked = readers + writers;
+        storeAppendPrintf(&e, "Readers:         %9d %6.2f%%\n",
+                          readers, (100.0 * readers / locked));
+        storeAppendPrintf(&e, "Writers:         %9d %6.2f%%\n",
+                          writers, (100.0 * writers / locked));
+    }
+}
diff -u -r -N squid-3.2.0.12/src/ipc/ReadWriteLock.h squid-3.2.0.13/src/ipc/ReadWriteLock.h
--- squid-3.2.0.12/src/ipc/ReadWriteLock.h	1970-01-01 12:00:00.000000000 +1200
+++ squid-3.2.0.13/src/ipc/ReadWriteLock.h	2011-10-14 14:42:56.000000000 +1300
@@ -0,0 +1,52 @@
+#ifndef SQUID_IPC_READ_WRITE_LOCK_H
+#define SQUID_IPC_READ_WRITE_LOCK_H
+
+#include "ipc/AtomicWord.h"
+
+class StoreEntry;
+
+namespace Ipc
+{
+
+class ReadWriteLockStats;
+
+/// an atomic readers-writer or shared-exclusive lock suitable for maps/tables
+class ReadWriteLock
+{
+public:
+    // default constructor is OK because of shared memory zero-initialization
+
+    bool lockShared(); ///< lock for reading or return false
+    bool lockExclusive(); ///< lock for modification or return false
+    void unlockShared(); ///< undo successful sharedLock()
+    void unlockExclusive(); ///< undo successful exclusiveLock()
+    void switchExclusiveToShared(); ///< stop writing, start reading
+
+    /// adds approximate current stats to the supplied ones
+    void updateStats(ReadWriteLockStats &stats) const;
+
+public:
+    mutable AtomicWord readers; ///< number of users trying to read
+    AtomicWord writers; ///< number of writers trying to modify protected data
+};
+
+
+/// approximate stats of a set of ReadWriteLocks
+class ReadWriteLockStats
+{
+public:
+    ReadWriteLockStats();
+
+    void dump(StoreEntry &e) const;
+
+    int count; ///< the total number of locks
+    int readable; ///< number of locks locked for reading
+    int writeable; ///< number of locks locked for writing
+    int idle; ///< number of unlocked locks
+    int readers; ///< sum of lock.readers
+    int writers; ///< sum of lock.writers
+};
+
+} // namespace Ipc
+
+#endif /* SQUID_IPC_READ_WRITE_LOCK_H */
diff -u -r -N squid-3.2.0.12/src/ipc/StoreMap.cc squid-3.2.0.13/src/ipc/StoreMap.cc
--- squid-3.2.0.12/src/ipc/StoreMap.cc	1970-01-01 12:00:00.000000000 +1200
+++ squid-3.2.0.13/src/ipc/StoreMap.cc	2011-10-14 14:42:56.000000000 +1300
@@ -0,0 +1,324 @@
+/*
+ * $Id$
+ *
+ * DEBUG: section 54    Interprocess Communication
+ */
+
+#include "squid.h"
+
+#include "Store.h"
+#include "ipc/StoreMap.h"
+
+Ipc::StoreMap::Owner *
+Ipc::StoreMap::Init(const char *const path, const int limit, const size_t extrasSize)
+{
+    assert(limit > 0); // we should not be created otherwise
+    Owner *const owner = shm_new(Shared)(path, limit, extrasSize);
+    debugs(54, 5, HERE << "new map [" << path << "] created: " << limit);
+    return owner;
+}
+
+Ipc::StoreMap::Owner *
+Ipc::StoreMap::Init(const char *const path, const int limit)
+{
+    return Init(path, limit, 0);
+}
+
+Ipc::StoreMap::StoreMap(const char *const aPath): cleaner(NULL), path(aPath),
+        shared(shm_old(Shared)(aPath))
+{
+    assert(shared->limit > 0); // we should not be created otherwise
+    debugs(54, 5, HERE << "attached map [" << path << "] created: " <<
+           shared->limit);
+}
+
+Ipc::StoreMap::Slot *
+Ipc::StoreMap::openForWriting(const cache_key *const key, sfileno &fileno)
+{
+    debugs(54, 5, HERE << " trying to open slot for key " << storeKeyText(key)
+           << " for writing in map [" << path << ']');
+    const int idx = slotIndexByKey(key);
+
+    Slot &s = shared->slots[idx];
+    ReadWriteLock &lock = s.lock;
+
+    if (lock.lockExclusive()) {
+        assert(s.state != Slot::Writeable); // until we start breaking locks
+
+        // free if the entry was used, keeping the entry locked
+        if (s.waitingToBeFreed == true || s.state == Slot::Readable)
+            freeLocked(s, true);
+
+        assert(s.state == Slot::Empty);
+        ++shared->count;
+        s.state = Slot::Writeable;
+        fileno = idx;
+        //s.setKey(key); // XXX: the caller should do that
+        debugs(54, 5, HERE << " opened slot at " << idx <<
+               " for writing in map [" << path << ']');
+        return &s; // and keep the entry locked
+    }
+
+    debugs(54, 5, HERE << " failed to open slot at " << idx <<
+           " for writing in map [" << path << ']');
+    return NULL;
+}
+
+void
+Ipc::StoreMap::closeForWriting(const sfileno fileno, bool lockForReading)
+{
+    debugs(54, 5, HERE << " closing slot at " << fileno << " for writing and "
+           "openning for reading in map [" << path << ']');
+    assert(valid(fileno));
+    Slot &s = shared->slots[fileno];
+    assert(s.state == Slot::Writeable);
+    s.state = Slot::Readable;
+    if (lockForReading)
+        s.lock.switchExclusiveToShared();
+    else
+        s.lock.unlockExclusive();
+}
+
+/// terminate writing the entry, freeing its slot for others to use
+void
+Ipc::StoreMap::abortWriting(const sfileno fileno)
+{
+    debugs(54, 5, HERE << " abort writing slot at " << fileno <<
+           " in map [" << path << ']');
+    assert(valid(fileno));
+    Slot &s = shared->slots[fileno];
+    assert(s.state == Slot::Writeable);
+    freeLocked(s, false);
+}
+
+void
+Ipc::StoreMap::abortIo(const sfileno fileno)
+{
+    debugs(54, 5, HERE << " abort I/O for slot at " << fileno <<
+           " in map [" << path << ']');
+    assert(valid(fileno));
+    Slot &s = shared->slots[fileno];
+
+    // The caller is a lock holder. Thus, if we are Writeable, then the
+    // caller must be the writer; otherwise the caller must be the reader.
+    if (s.state == Slot::Writeable)
+        abortWriting(fileno);
+    else
+        closeForReading(fileno);
+}
+
+const Ipc::StoreMap::Slot *
+Ipc::StoreMap::peekAtReader(const sfileno fileno) const
+{
+    assert(valid(fileno));
+    const Slot &s = shared->slots[fileno];
+    switch (s.state) {
+    case Slot::Readable:
+        return &s; // immediate access by lock holder so no locking
+    case Slot::Writeable:
+        return NULL; // cannot read the slot when it is being written
+    case Slot::Empty:
+        assert(false); // must be locked for reading or writing
+    }
+    assert(false); // not reachable
+    return NULL;
+}
+
+void
+Ipc::StoreMap::free(const sfileno fileno)
+{
+    debugs(54, 5, HERE << " marking slot at " << fileno << " to be freed in"
+           " map [" << path << ']');
+
+    assert(valid(fileno));
+    Slot &s = shared->slots[fileno];
+
+    if (s.lock.lockExclusive())
+        freeLocked(s, false);
+    else
+        s.waitingToBeFreed = true; // mark to free it later
+}
+
+const Ipc::StoreMap::Slot *
+Ipc::StoreMap::openForReading(const cache_key *const key, sfileno &fileno)
+{
+    debugs(54, 5, HERE << " trying to open slot for key " << storeKeyText(key)
+           << " for reading in map [" << path << ']');
+    const int idx = slotIndexByKey(key);
+    if (const Slot *slot = openForReadingAt(idx)) {
+        if (slot->sameKey(key)) {
+            fileno = idx;
+            debugs(54, 5, HERE << " opened slot at " << fileno << " for key "
+                   << storeKeyText(key) << " for reading in map [" << path <<
+                   ']');
+            return slot; // locked for reading
+        }
+        slot->lock.unlockShared();
+    }
+    debugs(54, 5, HERE << " failed to open slot for key " << storeKeyText(key)
+           << " for reading in map [" << path << ']');
+    return NULL;
+}
+
+const Ipc::StoreMap::Slot *
+Ipc::StoreMap::openForReadingAt(const sfileno fileno)
+{
+    debugs(54, 5, HERE << " trying to open slot at " << fileno << " for "
+           "reading in map [" << path << ']');
+    assert(valid(fileno));
+    Slot &s = shared->slots[fileno];
+
+    if (!s.lock.lockShared()) {
+        debugs(54, 5, HERE << " failed to lock slot at " << fileno << " for "
+               "reading in map [" << path << ']');
+        return NULL;
+    }
+
+    if (s.state == Slot::Empty) {
+        s.lock.unlockShared();
+        debugs(54, 7, HERE << " empty slot at " << fileno << " for "
+               "reading in map [" << path << ']');
+        return NULL;
+    }
+
+    if (s.waitingToBeFreed) {
+        s.lock.unlockShared();
+        debugs(54, 7, HERE << " dirty slot at " << fileno << " for "
+               "reading in map [" << path << ']');
+        return NULL;
+    }
+
+    // cannot be Writing here if we got shared lock and checked Empty above
+    assert(s.state == Slot::Readable);
+    debugs(54, 5, HERE << " opened slot at " << fileno << " for reading in"
+           " map [" << path << ']');
+    return &s;
+}
+
+void
+Ipc::StoreMap::closeForReading(const sfileno fileno)
+{
+    debugs(54, 5, HERE << " closing slot at " << fileno << " for reading in "
+           "map [" << path << ']');
+    assert(valid(fileno));
+    Slot &s = shared->slots[fileno];
+    assert(s.state == Slot::Readable);
+    s.lock.unlockShared();
+}
+
+int
+Ipc::StoreMap::entryLimit() const
+{
+    return shared->limit;
+}
+
+int
+Ipc::StoreMap::entryCount() const
+{
+    return shared->count;
+}
+
+bool
+Ipc::StoreMap::full() const
+{
+    return entryCount() >= entryLimit();
+}
+
+void
+Ipc::StoreMap::updateStats(ReadWriteLockStats &stats) const
+{
+    for (int i = 0; i < shared->limit; ++i)
+        shared->slots[i].lock.updateStats(stats);
+}
+
+bool
+Ipc::StoreMap::valid(const int pos) const
+{
+    return 0 <= pos && pos < entryLimit();
+}
+
+int
+Ipc::StoreMap::slotIndexByKey(const cache_key *const key) const
+{
+    const uint64_t *const k = reinterpret_cast<const uint64_t *>(key);
+    // TODO: use a better hash function
+    return (k[0] + k[1]) % shared->limit;
+}
+
+Ipc::StoreMap::Slot &
+Ipc::StoreMap::slotByKey(const cache_key *const key)
+{
+    return shared->slots[slotIndexByKey(key)];
+}
+
+/// unconditionally frees the already exclusively locked slot and releases lock
+void
+Ipc::StoreMap::freeLocked(Slot &s, bool keepLocked)
+{
+    if (s.state == Slot::Readable && cleaner)
+        cleaner->cleanReadable(&s - shared->slots);
+
+    s.waitingToBeFreed = false;
+    s.state = Slot::Empty;
+    if (!keepLocked)
+        s.lock.unlockExclusive();
+    --shared->count;
+    debugs(54, 5, HERE << " freed slot at " << (&s - shared->slots) <<
+           " in map [" << path << ']');
+}
+
+
+/* Ipc::StoreMapSlot */
+
+Ipc::StoreMapSlot::StoreMapSlot(): state(Empty)
+{
+    xmemset(&key, 0, sizeof(key));
+    xmemset(&basics, 0, sizeof(basics));
+}
+
+void
+Ipc::StoreMapSlot::setKey(const cache_key *const aKey)
+{
+    memcpy(key, aKey, sizeof(key));
+}
+
+bool
+Ipc::StoreMapSlot::sameKey(const cache_key *const aKey) const
+{
+    const uint64_t *const k = reinterpret_cast<const uint64_t *>(aKey);
+    return k[0] == key[0] && k[1] == key[1];
+}
+
+void
+Ipc::StoreMapSlot::set(const StoreEntry &from)
+{
+    memcpy(key, from.key, sizeof(key));
+    // XXX: header = aHeader;
+    basics.timestamp = from.timestamp;
+    basics.lastref = from.lastref;
+    basics.expires = from.expires;
+    basics.lastmod = from.lastmod;
+    basics.swap_file_sz = from.swap_file_sz;
+    basics.refcount = from.refcount;
+    basics.flags = from.flags;
+}
+
+/* Ipc::StoreMap::Shared */
+
+Ipc::StoreMap::Shared::Shared(const int aLimit, const size_t anExtrasSize):
+        limit(aLimit), extrasSize(anExtrasSize), count(0)
+{
+}
+
+size_t
+Ipc::StoreMap::Shared::sharedMemorySize() const
+{
+    return SharedMemorySize(limit, extrasSize);
+}
+
+size_t
+Ipc::StoreMap::Shared::SharedMemorySize(const int limit, const size_t extrasSize)
+{
+    return sizeof(Shared) + limit * (sizeof(Slot) + extrasSize);
+}
+
diff -u -r -N squid-3.2.0.12/src/ipc/StoreMap.h squid-3.2.0.13/src/ipc/StoreMap.h
--- squid-3.2.0.12/src/ipc/StoreMap.h	1970-01-01 12:00:00.000000000 +1200
+++ squid-3.2.0.13/src/ipc/StoreMap.h	2011-10-14 14:42:56.000000000 +1300
@@ -0,0 +1,201 @@
+#ifndef SQUID_IPC_STORE_MAP_H
+#define SQUID_IPC_STORE_MAP_H
+
+#include "ipc/ReadWriteLock.h"
+#include "ipc/mem/Pointer.h"
+#include "typedefs.h"
+
+namespace Ipc
+{
+
+/// a StoreMap element, holding basic shareable StoreEntry info
+class StoreMapSlot
+{
+public:
+    StoreMapSlot();
+
+    /// store StoreEntry key and basics
+    void set(const StoreEntry &anEntry);
+
+    void setKey(const cache_key *const aKey);
+    bool sameKey(const cache_key *const aKey) const;
+
+public:
+    mutable ReadWriteLock lock; ///< protects slot data below
+    AtomicWordT<uint8_t> waitingToBeFreed; ///< may be accessed w/o a lock
+
+    uint64_t key[2]; ///< StoreEntry key
+
+    // STORE_META_STD TLV field from StoreEntry
+    struct Basics {
+        time_t timestamp;
+        time_t lastref;
+        time_t expires;
+        time_t lastmod;
+        uint64_t swap_file_sz;
+        uint16_t refcount;
+        uint16_t flags;
+    } basics;
+
+    /// possible persistent states
+    typedef enum {
+        Empty, ///< ready for writing, with nothing of value
+        Writeable, ///< transitions from Empty to Readable
+        Readable, ///< ready for reading
+    } State;
+    State state; ///< current state
+};
+
+class StoreMapCleaner;
+
+/// map of StoreMapSlots indexed by their keys, with read/write slot locking
+/// kids extend to store custom data
+class StoreMap
+{
+public:
+    typedef StoreMapSlot Slot;
+
+    /// data shared across maps in different processes
+    class Shared
+    {
+    public:
+        Shared(const int aLimit, const size_t anExtrasSize);
+        size_t sharedMemorySize() const;
+        static size_t SharedMemorySize(const int limit, const size_t anExtrasSize);
+
+        const int limit; ///< maximum number of map slots
+        const size_t extrasSize; ///< size of slot extra data
+        AtomicWord count; ///< current number of map slots
+        Slot slots[]; ///< slots storage
+    };
+
+public:
+    typedef Mem::Owner<Shared> Owner;
+
+    /// initialize shared memory
+    static Owner *Init(const char *const path, const int limit);
+
+    StoreMap(const char *const aPath);
+
+    /// finds, reservers space for writing a new entry or returns nil
+    Slot *openForWriting(const cache_key *const key, sfileno &fileno);
+    /// successfully finish writing the entry
+    void closeForWriting(const sfileno fileno, bool lockForReading = false);
+
+    /// only works on locked entries; returns nil unless the slot is readable
+    const Slot *peekAtReader(const sfileno fileno) const;
+
+    /// mark the slot as waiting to be freed and, if possible, free it
+    void free(const sfileno fileno);
+
+    /// open slot for reading, increments read level
+    const Slot *openForReading(const cache_key *const key, sfileno &fileno);
+    /// open slot for reading, increments read level
+    const Slot *openForReadingAt(const sfileno fileno);
+    /// close slot after reading, decrements read level
+    void closeForReading(const sfileno fileno);
+
+    /// called by lock holder to terminate either slot writing or reading
+    void abortIo(const sfileno fileno);
+
+    bool full() const; ///< there are no empty slots left
+    bool valid(const int n) const; ///< whether n is a valid slot coordinate
+    int entryCount() const; ///< number of used slots
+    int entryLimit() const; ///< maximum number of slots that can be used
+
+    /// adds approximate current stats to the supplied ones
+    void updateStats(ReadWriteLockStats &stats) const;
+
+    StoreMapCleaner *cleaner; ///< notified before a readable entry is freed
+
+protected:
+    static Owner *Init(const char *const path, const int limit, const size_t extrasSize);
+
+    const String path; ///< cache_dir path, used for logging
+    Mem::Pointer<Shared> shared;
+
+private:
+    int slotIndexByKey(const cache_key *const key) const;
+    Slot &slotByKey(const cache_key *const key);
+
+    Slot *openForReading(Slot &s);
+    void abortWriting(const sfileno fileno);
+    void freeIfNeeded(Slot &s);
+    void freeLocked(Slot &s, bool keepLocked);
+};
+
+/// StoreMap with extra slot data
+/// Note: ExtrasT must be POD, it is initialized with zeroes, no
+/// constructors or destructors are called
+template <class ExtrasT>
+class StoreMapWithExtras: public StoreMap
+{
+public:
+    typedef ExtrasT Extras;
+
+    /// initialize shared memory
+    static Owner *Init(const char *const path, const int limit);
+
+    StoreMapWithExtras(const char *const path);
+
+    /// write access to the extras; call openForWriting() first!
+    ExtrasT &extras(const sfileno fileno);
+    /// read-only access to the extras; call openForReading() first!
+    const ExtrasT &extras(const sfileno fileno) const;
+
+protected:
+
+    ExtrasT *sharedExtras; ///< pointer to extras in shared memory
+};
+
+/// API for adjusting external state when dirty map slot is being freed
+class StoreMapCleaner
+{
+public:
+    virtual ~StoreMapCleaner() {}
+
+    /// adjust slot-linked state before a locked Readable slot is erased
+    virtual void cleanReadable(const sfileno fileno) = 0;
+};
+
+// StoreMapWithExtras implementation
+
+template <class ExtrasT>
+StoreMap::Owner *
+StoreMapWithExtras<ExtrasT>::Init(const char *const path, const int limit)
+{
+    return StoreMap::Init(path, limit, sizeof(Extras));
+}
+
+template <class ExtrasT>
+StoreMapWithExtras<ExtrasT>::StoreMapWithExtras(const char *const path):
+        StoreMap(path)
+{
+    const size_t sharedSizeWithoutExtras =
+        Shared::SharedMemorySize(entryLimit(), 0);
+    sharedExtras = reinterpret_cast<Extras *>(reinterpret_cast<char *>(shared.getRaw()) + sharedSizeWithoutExtras);
+}
+
+template <class ExtrasT>
+ExtrasT &
+StoreMapWithExtras<ExtrasT>::extras(const sfileno fileno)
+{
+    return const_cast<ExtrasT &>(const_cast<const StoreMapWithExtras *>(this)->extras(fileno));
+}
+
+template <class ExtrasT>
+const ExtrasT &
+StoreMapWithExtras<ExtrasT>::extras(const sfileno fileno) const
+{
+    assert(sharedExtras);
+    assert(valid(fileno));
+    return sharedExtras[fileno];
+}
+
+
+} // namespace Ipc
+
+// We do not reuse struct _fileMap because we cannot control its size,
+// resulting in sfilenos that are pointing beyond the database.
+
+#endif /* SQUID_IPC_STORE_MAP_H */
diff -u -r -N squid-3.2.0.12/src/ipc/Strand.cc squid-3.2.0.13/src/ipc/Strand.cc
--- squid-3.2.0.12/src/ipc/Strand.cc	2011-09-16 23:37:30.000000000 +1200
+++ squid-3.2.0.13/src/ipc/Strand.cc	2011-10-14 14:42:56.000000000 +1300
@@ -13,11 +13,16 @@
 #include "ipc/StrandCoord.h"
 #include "ipc/Messages.h"
 #include "ipc/SharedListen.h"
+#include "ipc/StrandSearch.h"
 #include "ipc/Kids.h"
 #include "mgr/Request.h"
 #include "mgr/Response.h"
 #include "mgr/Forwarder.h"
+#include "SwapDir.h" /* XXX: scope boundary violation */
 #include "CacheManager.h"
+#if USE_DISKIO_IPCIO
+#include "DiskIO/IpcIo/IpcIoFile.h" /* XXX: scope boundary violation */
+#endif
 #if SQUID_SNMP
 #include "snmp/Forwarder.h"
 #include "snmp/Request.h"
@@ -43,8 +48,10 @@
 {
     debugs(54, 6, HERE);
     Must(!isRegistered);
+
+    HereIamMessage ann(StrandCoord(KidIdentifier, getpid()));
     TypedMsgHdr message;
-    StrandCoord(KidIdentifier, getpid()).pack(message);
+    ann.pack(message);
     SendMessage(coordinatorAddr, message);
     setTimeout(6, "Ipc::Strand::timeoutHandler"); // TODO: make 6 configurable?
 }
@@ -55,13 +62,23 @@
     switch (message.type()) {
 
     case mtRegistration:
-        handleRegistrationResponse(StrandCoord(message));
+        handleRegistrationResponse(HereIamMessage(message));
         break;
 
     case mtSharedListenResponse:
         SharedListenJoined(SharedListenResponse(message));
         break;
 
+#if USE_DISKIO_IPCIO
+    case mtStrandSearchResponse:
+        IpcIoFile::HandleOpenResponse(StrandSearchResponse(message));
+        break;
+
+    case mtIpcIoNotification:
+        IpcIoFile::HandleNotification(message);
+        break;
+#endif /* USE_DISKIO_IPCIO */
+
     case mtCacheMgrRequest: {
         const Mgr::Request req(message);
         handleCacheMgrRequest(req);
@@ -94,10 +111,10 @@
     }
 }
 
-void Ipc::Strand::handleRegistrationResponse(const StrandCoord &strand)
+void Ipc::Strand::handleRegistrationResponse(const HereIamMessage &msg)
 {
     // handle registration response from the coordinator; it could be stale
-    if (strand.kidId == KidIdentifier && strand.pid == getpid()) {
+    if (msg.strand.kidId == KidIdentifier && msg.strand.pid == getpid()) {
         debugs(54, 6, "kid" << KidIdentifier << " registered");
         clearTimeout(); // we are done
     } else {
diff -u -r -N squid-3.2.0.12/src/ipc/StrandCoord.cc squid-3.2.0.13/src/ipc/StrandCoord.cc
--- squid-3.2.0.12/src/ipc/StrandCoord.cc	2011-09-16 23:37:30.000000000 +1200
+++ squid-3.2.0.13/src/ipc/StrandCoord.cc	2011-10-14 14:42:56.000000000 +1300
@@ -7,6 +7,7 @@
 
 
 #include "config.h"
+#include "Debug.h"
 #include "ipc/Messages.h"
 #include "ipc/StrandCoord.h"
 #include "ipc/TypedMsgHdr.h"
@@ -20,14 +21,35 @@
 {
 }
 
-Ipc::StrandCoord::StrandCoord(const TypedMsgHdr &hdrMsg): kidId(-1), pid(0)
+void
+Ipc::StrandCoord::unpack(const TypedMsgHdr &hdrMsg)
 {
-    hdrMsg.checkType(mtRegistration);
-    hdrMsg.getPod(*this);
+    hdrMsg.getPod(kidId);
+    hdrMsg.getPod(pid);
+    hdrMsg.getString(tag);
 }
 
 void Ipc::StrandCoord::pack(TypedMsgHdr &hdrMsg) const
 {
+    hdrMsg.putPod(kidId);
+    hdrMsg.putPod(pid);
+    hdrMsg.putString(tag);
+}
+
+
+Ipc::HereIamMessage::HereIamMessage(const StrandCoord &aStrand):
+        strand(aStrand)
+{
+}
+
+Ipc::HereIamMessage::HereIamMessage(const TypedMsgHdr &hdrMsg)
+{
+    hdrMsg.checkType(mtRegistration);
+    strand.unpack(hdrMsg);
+}
+
+void Ipc::HereIamMessage::pack(TypedMsgHdr &hdrMsg) const
+{
     hdrMsg.setType(mtRegistration);
-    hdrMsg.putPod(*this);
+    strand.pack(hdrMsg);
 }
diff -u -r -N squid-3.2.0.12/src/ipc/StrandCoord.h squid-3.2.0.13/src/ipc/StrandCoord.h
--- squid-3.2.0.12/src/ipc/StrandCoord.h	2011-09-16 23:37:30.000000000 +1200
+++ squid-3.2.0.13/src/ipc/StrandCoord.h	2011-10-14 14:42:56.000000000 +1300
@@ -7,7 +7,7 @@
 #define SQUID_IPC_STRAND_COORD_H
 
 #include "ipc/forward.h"
-#include <sys/types.h>
+#include "SquidString.h"
 
 namespace Ipc
 {
@@ -17,15 +17,32 @@
 {
 public:
     StrandCoord(); ///< unknown location
-    StrandCoord(int akidId, pid_t aPid); ///< from registrant
-    explicit StrandCoord(const TypedMsgHdr &hdrMsg); ///< from recvmsg()
+    StrandCoord(int akidId, pid_t aPid);
+
     void pack(TypedMsgHdr &hdrMsg) const; ///< prepare for sendmsg()
+    void unpack(const TypedMsgHdr &hdrMsg); ///< from recvmsg()
 
 public:
     int kidId; ///< internal Squid process number
     pid_t pid; ///< OS process or thread identifier
+
+    String tag; ///< optional unique well-known key (e.g., cache_dir path)
 };
 
+/// strand registration with Coordinator (also used as an ACK)
+class HereIamMessage
+{
+public:
+    explicit HereIamMessage(const StrandCoord &strand); ///< from registrant
+    explicit HereIamMessage(const TypedMsgHdr &hdrMsg); ///< from recvmsg()
+    void pack(TypedMsgHdr &hdrMsg) const; ///< prepare for sendmsg()
+
+public:
+    StrandCoord strand; ///< registrant coordinates and related details
+};
+
+
+
 } // namespace Ipc;
 
 #endif /* SQUID_IPC_STRAND_COORD_H */
diff -u -r -N squid-3.2.0.12/src/ipc/Strand.h squid-3.2.0.13/src/ipc/Strand.h
--- squid-3.2.0.12/src/ipc/Strand.h	2011-09-16 23:37:30.000000000 +1200
+++ squid-3.2.0.13/src/ipc/Strand.h	2011-10-14 14:42:56.000000000 +1300
@@ -8,6 +8,7 @@
 #ifndef SQUID_IPC_STRAND_H
 #define SQUID_IPC_STRAND_H
 
+#include "ipc/forward.h"
 #include "ipc/Port.h"
 #include "mgr/forward.h"
 #if SQUID_SNMP
@@ -33,7 +34,7 @@
 
 private:
     void registerSelf(); /// let Coordinator know this strand exists
-    void handleRegistrationResponse(const StrandCoord &strand);
+    void handleRegistrationResponse(const HereIamMessage &msg);
     void handleCacheMgrRequest(const Mgr::Request& request);
     void handleCacheMgrResponse(const Mgr::Response& response);
 #if SQUID_SNMP
diff -u -r -N squid-3.2.0.12/src/ipc/StrandSearch.cc squid-3.2.0.13/src/ipc/StrandSearch.cc
--- squid-3.2.0.12/src/ipc/StrandSearch.cc	1970-01-01 12:00:00.000000000 +1200
+++ squid-3.2.0.13/src/ipc/StrandSearch.cc	2011-10-14 14:42:56.000000000 +1300
@@ -0,0 +1,52 @@
+/*
+ * $Id$
+ *
+ * DEBUG: section 54    Interprocess Communication
+ *
+ */
+
+
+#include "config.h"
+#include "ipc/Messages.h"
+#include "ipc/StrandSearch.h"
+#include "ipc/TypedMsgHdr.h"
+
+
+Ipc::StrandSearchRequest::StrandSearchRequest(): requestorId(-1)
+{
+}
+
+Ipc::StrandSearchRequest::StrandSearchRequest(const TypedMsgHdr &hdrMsg):
+        requestorId(-1)
+{
+    hdrMsg.checkType(mtStrandSearchRequest);
+    hdrMsg.getPod(requestorId);
+    hdrMsg.getString(tag);
+}
+
+void Ipc::StrandSearchRequest::pack(TypedMsgHdr &hdrMsg) const
+{
+    hdrMsg.setType(mtStrandSearchRequest);
+    hdrMsg.putPod(requestorId);
+    hdrMsg.putString(tag);
+}
+
+
+/* StrandSearchResponse */
+
+Ipc::StrandSearchResponse::StrandSearchResponse(const Ipc::StrandCoord &aStrand):
+        strand(aStrand)
+{
+}
+
+Ipc::StrandSearchResponse::StrandSearchResponse(const TypedMsgHdr &hdrMsg)
+{
+    hdrMsg.checkType(mtStrandSearchResponse);
+    strand.unpack(hdrMsg);
+}
+
+void Ipc::StrandSearchResponse::pack(TypedMsgHdr &hdrMsg) const
+{
+    hdrMsg.setType(mtStrandSearchResponse);
+    strand.pack(hdrMsg);
+}
diff -u -r -N squid-3.2.0.12/src/ipc/StrandSearch.h squid-3.2.0.13/src/ipc/StrandSearch.h
--- squid-3.2.0.12/src/ipc/StrandSearch.h	1970-01-01 12:00:00.000000000 +1200
+++ squid-3.2.0.13/src/ipc/StrandSearch.h	2011-10-14 14:42:56.000000000 +1300
@@ -0,0 +1,43 @@
+/*
+ * $Id$
+ *
+ */
+
+#ifndef SQUID_IPC_STRAND_SEARCH_H
+#define SQUID_IPC_STRAND_SEARCH_H
+
+#include "ipc/forward.h"
+#include "ipc/StrandCoord.h"
+#include "SquidString.h"
+
+namespace Ipc
+{
+
+/// asynchronous strand search request
+class StrandSearchRequest
+{
+public:
+    StrandSearchRequest();
+    explicit StrandSearchRequest(const TypedMsgHdr &hdrMsg); ///< from recvmsg()
+    void pack(TypedMsgHdr &hdrMsg) const; ///< prepare for sendmsg()
+
+public:
+    int requestorId; ///< sender-provided return address
+    String tag; ///< set when looking for a matching StrandCoord::tag
+};
+
+/// asynchronous strand search response
+class StrandSearchResponse
+{
+public:
+    StrandSearchResponse(const StrandCoord &strand);
+    explicit StrandSearchResponse(const TypedMsgHdr &hdrMsg); ///< from recvmsg()
+    void pack(TypedMsgHdr &hdrMsg) const; ///< prepare for sendmsg()
+
+public:
+    StrandCoord strand; ///< answer matching StrandSearchRequest criteria
+};
+
+} // namespace Ipc;
+
+#endif /* SQUID_IPC_STRAND_SEARCH_H */
diff -u -r -N squid-3.2.0.12/src/log/FormatSquidIcap.cc squid-3.2.0.13/src/log/FormatSquidIcap.cc
--- squid-3.2.0.12/src/log/FormatSquidIcap.cc	2011-09-16 23:37:30.000000000 +1200
+++ squid-3.2.0.13/src/log/FormatSquidIcap.cc	2011-10-14 14:42:56.000000000 +1300
@@ -75,11 +75,12 @@
     if (user && !*user)
         safe_free(user);
 
-    logfilePrintf(logfile, "%9ld.%03d %6d %s -/%03d %"PRId64" %s %s %s -/%s -\n",
+    logfilePrintf(logfile, "%9ld.%03d %6d %s %s/%03d %"PRId64" %s %s %s -/%s -\n",
                   (long int) current_time.tv_sec,
                   (int) current_time.tv_usec / 1000,
                   al->icap.trTime,
                   client,
+                  al->icap.outcome,
                   al->icap.resStatus,
                   al->icap.bytesRead,
                   Adaptation::Icap::ICAP::methodStr(al->icap.reqMethod),
diff -u -r -N squid-3.2.0.12/src/main.cc squid-3.2.0.13/src/main.cc
--- squid-3.2.0.12/src/main.cc	2011-09-16 23:37:30.000000000 +1200
+++ squid-3.2.0.13/src/main.cc	2011-10-14 14:42:56.000000000 +1300
@@ -669,8 +669,8 @@
         wccp2ConnectionOpen();
 #endif
     }
-    // Coordinator does not start proxying services
-    if (!IamCoordinatorProcess()) {
+    // start various proxying services if we are responsible for them
+    if (IamWorkerProcess()) {
         clientOpenListenSockets();
         icpConnectionsOpen();
 #if USE_HTCP
@@ -712,7 +712,7 @@
         wccp2ConnectionClose();
 #endif
     }
-    if (!IamCoordinatorProcess()) {
+    if (IamWorkerProcess()) {
         clientHttpConnectionsClose();
         icpConnectionShutdown();
 #if USE_HTCP
@@ -1008,6 +1008,9 @@
 #endif
 
     debugs(1, 1, "Process ID " << getpid());
+
+    debugs(1, 1, "Process Roles:" << ProcessRoles());
+
     setSystemLimits();
     debugs(1, 1, "With " << Squid_MaxFD << " file descriptors available");
 
@@ -1243,10 +1246,11 @@
     try {
         return SquidMain(argc, argv);
     } catch (const std::exception &e) {
-        std::cerr << "dying from an unhandled exception: " << e.what() << std::endl;
+        debugs(1, DBG_CRITICAL, "FATAL: dying from an unhandled exception: " <<
+               e.what());
         throw;
     } catch (...) {
-        std::cerr << "dying from an unhandled exception." << std::endl;
+        debugs(1, DBG_CRITICAL, "FATAL: dying from an unhandled exception.");
         throw;
     }
     return -1; // not reached
@@ -1263,6 +1267,14 @@
             const size_t nameLen = idStart - (processName + 1);
             assert(nameLen < sizeof(TheKidName));
             xstrncpy(TheKidName, processName + 1, nameLen + 1);
+            if (!strcmp(TheKidName, "squid-coord"))
+                TheProcessKind = pkCoordinator;
+            else if (!strcmp(TheKidName, "squid"))
+                TheProcessKind = pkWorker;
+            else if (!strcmp(TheKidName, "squid-disk"))
+                TheProcessKind = pkDisker;
+            else
+                TheProcessKind = pkOther; // including coordinator
         }
     } else {
         xstrncpy(TheKidName, APP_SHORTNAME, sizeof(TheKidName));
@@ -1507,7 +1519,7 @@
 
     if (IamCoordinatorProcess())
         AsyncJob::Start(Ipc::Coordinator::Instance());
-    else if (UsingSmp() && IamWorkerProcess())
+    else if (UsingSmp() && (IamWorkerProcess() || IamDiskProcess()))
         AsyncJob::Start(new Ipc::Strand);
 
     /* at this point we are finished the synchronous startup. */
@@ -1720,7 +1732,9 @@
                Config.workers);
         // but we keep going in hope that user knows best
     }
-    TheKids.init(Config.workers);
+    TheKids.init();
+
+    syslog(LOG_NOTICE, "Squid Parent: will start %d kids", (int)TheKids.count());
 
     // keep [re]starting kids until it is time to quit
     for (;;) {
@@ -1742,7 +1756,8 @@
             }
 
             kid.start(pid);
-            syslog(LOG_NOTICE, "Squid Parent: child process %d started", pid);
+            syslog(LOG_NOTICE, "Squid Parent: %s process %d started",
+                   kid.name().termedBuf(), pid);
         }
 
         /* parent */
@@ -1766,19 +1781,22 @@
                 kid->stop(status);
                 if (kid->calledExit()) {
                     syslog(LOG_NOTICE,
-                           "Squid Parent: child process %d exited with status %d",
+                           "Squid Parent: %s process %d exited with status %d",
+                           kid->name().termedBuf(),
                            kid->getPid(), kid->exitStatus());
                 } else if (kid->signaled()) {
                     syslog(LOG_NOTICE,
-                           "Squid Parent: child process %d exited due to signal %d with status %d",
+                           "Squid Parent: %s process %d exited due to signal %d with status %d",
+                           kid->name().termedBuf(),
                            kid->getPid(), kid->termSignal(), kid->exitStatus());
                 } else {
-                    syslog(LOG_NOTICE, "Squid Parent: child process %d exited", kid->getPid());
+                    syslog(LOG_NOTICE, "Squid Parent: %s process %d exited",
+                           kid->name().termedBuf(), kid->getPid());
                 }
                 if (kid->hopeless()) {
-                    syslog(LOG_NOTICE, "Squid Parent: child process %d will not"
+                    syslog(LOG_NOTICE, "Squid Parent: %s process %d will not"
                            " be restarted due to repeated, frequent failures",
-                           kid->getPid());
+                           kid->name().termedBuf(), kid->getPid());
                 }
             } else {
                 syslog(LOG_NOTICE, "Squid Parent: unknown child process %d exited", pid);
diff -u -r -N squid-3.2.0.12/src/Makefile.am squid-3.2.0.13/src/Makefile.am
--- squid-3.2.0.12/src/Makefile.am	2011-09-16 23:37:30.000000000 +1200
+++ squid-3.2.0.13/src/Makefile.am	2011-10-14 14:42:56.000000000 +1300
@@ -174,7 +174,8 @@
 AIOPS_SOURCE = DiskIO/DiskThreads/aiops.cc
 endif
 
-EXTRA_LIBRARIES = libAIO.a libBlocking.a libDiskDaemon.a libDiskThreads.a
+EXTRA_LIBRARIES = libAIO.a libBlocking.a libDiskDaemon.a libDiskThreads.a \
+	libMmapped.a libIpcIo.a
 noinst_LIBRARIES = $(DISK_LIBS)
 noinst_LTLIBRARIES = libsquid.la
 
@@ -341,7 +342,9 @@
 	HttpStatusCode.h \
 	HttpStatusLine.cc \
 	HttpStatusLine.h \
+	HttpHdrCc.h \
 	HttpHdrCc.cc \
+	HttpHdrCc.cci \
 	HttpHdrRange.cc \
 	HttpHdrSc.cc \
 	HttpHdrSc.h \
@@ -466,6 +469,8 @@
 	swap_log_op.h \
 	SwapDir.cc \
 	SwapDir.h \
+	MemStore.cc \
+	MemStore.h \
 	time.cc \
 	TimeOrTag.h \
 	tools.cc \
@@ -544,6 +549,7 @@
 	eui/libeui.la \
 	acl/libstate.la \
 	$(AUTH_LIBS) \
+	$(DISK_LIBS) \
 	acl/libapi.la \
 	base/libbase.la \
 	libsquid.la \
@@ -560,7 +566,6 @@
 	$(XTRA_OBJS) \
 	$(DISK_LINKOBJS) \
 	$(REPL_OBJS) \
-	$(DISK_LIBS) \
 	$(DISK_OS_LIBS) \
 	$(CRYPTLIB) \
 	$(REGEXLIB) \
@@ -779,6 +784,22 @@
 		DiskIO/Blocking/BlockingDiskIOModule.cc \
 		DiskIO/Blocking/BlockingDiskIOModule.h 
 
+libMmapped_a_SOURCES = \
+		DiskIO/Mmapped/MmappedFile.cc \
+		DiskIO/Mmapped/MmappedFile.h \
+		DiskIO/Mmapped/MmappedIOStrategy.cc \
+		DiskIO/Mmapped/MmappedIOStrategy.h \
+		DiskIO/Mmapped/MmappedDiskIOModule.cc \
+		DiskIO/Mmapped/MmappedDiskIOModule.h 
+
+libIpcIo_a_SOURCES = \
+		DiskIO/IpcIo/IpcIoFile.cc \
+		DiskIO/IpcIo/IpcIoFile.h \
+		DiskIO/IpcIo/IpcIoIOStrategy.cc \
+		DiskIO/IpcIo/IpcIoIOStrategy.h \
+		DiskIO/IpcIo/IpcIoDiskIOModule.cc \
+		DiskIO/IpcIo/IpcIoDiskIOModule.h 
+
 libDiskDaemon_a_SOURCES = \
 		DiskIO/DiskDaemon/DiskdFile.cc \
 		DiskIO/DiskDaemon/DiskdFile.h \
@@ -824,7 +845,6 @@
 DEFAULT_ACCESS_LOG	= $(DEFAULT_LOG_PREFIX)/access.log
 DEFAULT_STORE_LOG	= $(DEFAULT_LOG_PREFIX)/store.log
 DEFAULT_NETDB_FILE	= $(DEFAULT_LOG_PREFIX)/netdb.state
-DEFAULT_SWAP_DIR	= $(localstatedir)/cache
 DEFAULT_SSL_DB_DIR	= $(localstatedir)/lib/ssl_db
 DEFAULT_PINGER		= $(libexecdir)/`echo pinger | sed '$(transform);s/$$/$(EXEEXT)/'`
 DEFAULT_UNLINKD		= $(libexecdir)/`echo unlinkd | sed '$(transform);s/$$/$(EXEEXT)/'`
@@ -1015,7 +1035,9 @@
 	cbdata.h \
 	ETag.cc \
 	HttpBody.cc \
+	HttpHdrCc.h \
 	HttpHdrCc.cc \
+	HttpHdrCc.cci \
 	HttpHdrContRange.cc \
 	HttpHdrContRange.h \
 	HttpHdrRange.cc \
@@ -1044,6 +1066,7 @@
 	SquidString.h \
 	SquidTime.h \
 	String.cc \
+	tests/stub_cache_cf.cc \
 	tests/stub_cache_manager.cc \
 	tests/stub_debug.cc \
 	tests/stub_HelperChildConfig.cc \
@@ -1052,7 +1075,8 @@
 	tests/testHttpReply.cc \
 	tests/testHttpReply.h \
 	tests/testMain.cc \
-	time.cc
+	time.cc \
+	wordlist.cc
 nodist_tests_testHttpReply_SOURCES=\
 	$(TESTSOURCES)
 tests_testHttpReply_LDFLAGS = $(LIBADD_DL)
@@ -1108,7 +1132,9 @@
 	HttpHeaderTools.cc \
 	HttpHdrContRange.cc \
 	HttpHdrRange.cc \
+	HttpHdrCc.h \
 	HttpHdrCc.cc \
+	HttpHdrCc.cci \
 	HttpHdrSc.cc \
 	HttpHdrScTarget.cc \
 	HttpMsg.cc \
@@ -1146,10 +1172,12 @@
 	tests/stub_fd.cc \
 	tests/stub_HttpRequest.cc \
 	tests/stub_MemObject.cc \
+	tests/stub_MemStore.cc \
 	tests/stub_mime.cc \
 	tests/stub_store.cc \
 	tests/stub_store_rebuild.cc \
 	tests/stub_store_swapout.cc \
+	tests/stub_tools.cc \
 	tests/stub_cache_manager.cc \
 	tests/testACLMaxUserIP.cc \
 	tests/testACLMaxUserIP.h \
@@ -1179,6 +1207,7 @@
 	$(top_builddir)/lib/libmisccontainers.la \
 	$(top_builddir)/lib/libmiscencoding.la \
 	$(top_builddir)/lib/libmiscutil.la \
+	$(DISK_OS_LIBS) \
 	$(REGEXLIB) \
 	$(SQUID_CPPUNIT_LIBS) \
 	$(SSLLIB) \
@@ -1244,6 +1273,7 @@
 	CpuAffinitySet.cc \
 	CpuAffinitySet.h \
 	$(DELAY_POOL_SOURCE) \
+	$(DISKIO_SOURCE) \
 	disk.cc \
 	dlink.h \
 	dlink.cc \
@@ -1255,6 +1285,7 @@
 	ExternalACLEntry.cc \
 	fd.cc \
 	fde.cc \
+	filemap.cc \
 	forward.cc \
 	fqdncache.cc \
 	ftp.cc \
@@ -1268,7 +1299,9 @@
 	HttpBody.cc \
 	HttpHeader.cc \
 	HttpHeaderTools.cc \
+	HttpHdrCc.h \
 	HttpHdrCc.cc \
+	HttpHdrCc.cci \
 	HttpHdrContRange.cc \
 	HttpHdrRange.cc \
 	HttpHdrSc.cc \
@@ -1332,6 +1365,8 @@
 	tools.cc \
 	tunnel.cc \
 	SwapDir.cc \
+	MemStore.cc \
+	$(UNLINKDSOURCE) \
 	url.cc \
 	URLScheme.cc \
 	urn.cc \
@@ -1341,7 +1376,8 @@
 	$(WIN32_SOURCE) \
 	wordlist.cc
 nodist_tests_testCacheManager_SOURCES = \
-	$(BUILT_SOURCES)
+	$(BUILT_SOURCES) \
+	$(DISKIO_GEN_SOURCE)
 # comm.cc only requires comm/libcomm.la until fdc_table is dead.
 tests_testCacheManager_LDADD = \
 	$(AUTH_ACL_LIBS) \
@@ -1355,18 +1391,20 @@
 	libsquid.la \
 	ip/libip.la \
 	fs/libfs.la \
-	ipc/libipc.la \
-	mgr/libmgr.la \
-	$(SNMP_LIBS) \
 	comm/libcomm.la \
 	icmp/libicmp.la icmp/libicmp-core.la \
 	log/liblog.la \
 	format/libformat.la \
 	$(REPL_OBJS) \
+	$(DISK_LIBS) \
+	$(DISK_OS_LIBS) \
 	$(ADAPTATION_LIBS) \
 	$(ESI_LIBS) \
 	$(SSL_LIBS) \
 	anyp/libanyp.la \
+	ipc/libipc.la \
+	mgr/libmgr.la \
+	$(SNMP_LIBS) \
 	$(top_builddir)/lib/libmisccontainers.la \
 	$(top_builddir)/lib/libmiscencoding.la \
 	$(top_builddir)/lib/libmiscutil.la \
@@ -1399,7 +1437,9 @@
 	fd.cc \
 	filemap.cc \
 	HttpBody.cc \
+	HttpHdrCc.h \
 	HttpHdrCc.cc \
+	HttpHdrCc.cci \
 	HttpHdrContRange.cc \
 	HttpHdrSc.cc \
 	HttpHdrScTarget.cc \
@@ -1457,13 +1497,13 @@
 	tests/stub_ipc.cc \
 	tests/stub_ipcache.cc \
 	tests/stub_libicmp.cc \
+	tests/stub_MemStore.cc \
 	tests/stub_mime.cc \
 	tests/stub_pconn.cc \
 	tests/stub_Port.cc \
 	tests/stub_store_client.cc \
 	tests/stub_store_rebuild.cc \
 	tests/stub_tools.cc \
-	tests/stub_TypedMsgHdr.cc \
 	tests/stub_UdsOp.cc \
 	tests/testDiskIO.cc \
 	tests/testDiskIO.h \
@@ -1495,7 +1535,6 @@
 	$(AUTH_LIBS) \
 	libsquid.la \
 	comm/libcomm.la \
-	base/libbase.la \
 	ip/libip.la \
 	fs/libfs.la \
 	ipc/libipc.la \
@@ -1504,6 +1543,8 @@
 	$(DISK_OS_LIBS) \
 	acl/libapi.la \
 	mgr/libmgr.la \
+	ipc/libipc.la \
+	base/libbase.la \
 	$(SSL_LIBS) \
 	$(top_builddir)/lib/libmisccontainers.la \
 	$(top_builddir)/lib/libmiscencoding.la \
@@ -1544,6 +1585,7 @@
 	CpuAffinitySet.h \
 	debug.cc \
 	$(DELAY_POOL_SOURCE) \
+	$(DISKIO_SOURCE) \
 	disk.cc \
 	dlink.h \
 	dlink.cc \
@@ -1558,6 +1600,7 @@
 	FadingCounter.cc \
 	fd.cc \
 	fde.cc \
+	filemap.cc \
 	forward.cc \
 	fqdncache.cc \
 	ftp.cc \
@@ -1571,7 +1614,9 @@
 	HttpBody.cc \
 	HttpHeader.cc \
 	HttpHeaderTools.cc \
+	HttpHdrCc.h \
 	HttpHdrCc.cc \
+	HttpHdrCc.cci \
 	HttpHdrContRange.cc \
 	HttpHdrRange.cc \
 	HttpHdrSc.cc \
@@ -1650,6 +1695,8 @@
 	time.cc \
 	tools.cc \
 	tunnel.cc \
+	MemStore.cc \
+	$(UNLINKDSOURCE) \
 	url.cc \
 	URLScheme.cc \
 	urn.cc \
@@ -1658,7 +1705,8 @@
 	$(WIN32_SOURCE) \
 	wordlist.cc
 nodist_tests_testEvent_SOURCES = \
-	$(BUILT_SOURCES)
+	$(BUILT_SOURCES) \
+	$(DISKIO_GEN_SOURCE)
 tests_testEvent_LDADD = \
 	$(AUTH_ACL_LIBS) \
 	ident/libident.la \
@@ -1671,10 +1719,7 @@
 	libsquid.la \
 	ip/libip.la \
 	fs/libfs.la \
-	ipc/libipc.la \
-	mgr/libmgr.la \
 	anyp/libanyp.la \
-	$(SNMP_LIBS) \
 	icmp/libicmp.la icmp/libicmp-core.la \
 	comm/libcomm.la \
 	log/liblog.la \
@@ -1686,6 +1731,11 @@
 	$(top_builddir)/lib/libmisccontainers.la \
 	$(top_builddir)/lib/libmiscencoding.la \
 	$(top_builddir)/lib/libmiscutil.la \
+	$(DISK_LIBS) \
+	$(DISK_OS_LIBS) \
+	ipc/libipc.la \
+	mgr/libmgr.la \
+	$(SNMP_LIBS) \
 	$(REGEXLIB) \
 	$(SQUID_CPPUNIT_LIBS) \
 	$(SQUID_CPPUNIT_LA) \
@@ -1722,6 +1772,7 @@
 	CpuAffinitySet.h \
 	debug.cc \
 	$(DELAY_POOL_SOURCE) \
+	$(DISKIO_SOURCE) \
 	disk.cc \
 	dlink.h \
 	dlink.cc \
@@ -1736,6 +1787,7 @@
 	FadingCounter.cc \
 	fd.cc \
 	fde.cc \
+	filemap.cc \
 	forward.cc \
 	fqdncache.cc \
 	ftp.cc \
@@ -1749,7 +1801,9 @@
 	HttpBody.cc \
 	HttpHeader.cc \
 	HttpHeaderTools.cc \
+	HttpHdrCc.h \
 	HttpHdrCc.cc \
+	HttpHdrCc.cci \
 	HttpHdrContRange.cc \
 	HttpHdrRange.cc \
 	HttpHdrSc.cc \
@@ -1827,6 +1881,8 @@
 	time.cc \
 	tools.cc \
 	tunnel.cc \
+	MemStore.cc \
+	$(UNLINKDSOURCE) \
 	url.cc \
 	URLScheme.cc \
 	urn.cc \
@@ -1835,7 +1891,8 @@
 	$(WIN32_SOURCE) \
 	wordlist.cc
 nodist_tests_testEventLoop_SOURCES = \
-	$(BUILT_SOURCES)
+	$(BUILT_SOURCES) \
+	$(DISKIO_GEN_SOURCE)
 tests_testEventLoop_LDADD = \
 	$(AUTH_ACL_LIBS) \
 	ident/libident.la \
@@ -1848,10 +1905,7 @@
 	libsquid.la \
 	ip/libip.la \
 	fs/libfs.la \
-	ipc/libipc.la \
-	mgr/libmgr.la \
 	anyp/libanyp.la \
-	$(SNMP_LIBS) \
 	icmp/libicmp.la icmp/libicmp-core.la \
 	comm/libcomm.la \
 	log/liblog.la \
@@ -1863,6 +1917,11 @@
 	$(top_builddir)/lib/libmisccontainers.la \
 	$(top_builddir)/lib/libmiscencoding.la \
 	$(top_builddir)/lib/libmiscutil.la \
+	$(DISK_LIBS) \
+	$(DISK_OS_LIBS) \
+	ipc/libipc.la \
+	mgr/libmgr.la \
+	$(SNMP_LIBS) \
 	$(REGEXLIB) \
 	$(SQUID_CPPUNIT_LIBS) \
 	$(SQUID_CPPUNIT_LA) \
@@ -1900,6 +1959,7 @@
 	CpuAffinitySet.h \
 	debug.cc \
 	$(DELAY_POOL_SOURCE) \
+	$(DISKIO_SOURCE) \
 	disk.cc \
 	dlink.h \
 	dlink.cc \
@@ -1912,6 +1972,7 @@
 	FadingCounter.cc \
 	fd.cc \
 	fde.cc \
+	filemap.cc \
 	forward.cc \
 	fqdncache.cc \
 	ftp.cc \
@@ -1923,7 +1984,9 @@
 	$(HTCPSOURCE) \
 	http.cc \
 	HttpBody.cc \
+	HttpHdrCc.h \
 	HttpHdrCc.cc \
+	HttpHdrCc.cci \
 	HttpHdrContRange.cc \
 	HttpHdrRange.cc \
 	HttpHdrSc.cc \
@@ -1996,9 +2059,11 @@
 	tests/test_http_range.cc \
 	tests/stub_ipc_Forwarder.cc \
 	tests/stub_main_cc.cc \
+	tests/stub_MemStore.cc \
 	time.cc \
 	tools.cc \
 	tunnel.cc \
+	$(UNLINKDSOURCE) \
 	url.cc \
 	URLScheme.cc \
 	urn.cc \
@@ -2007,7 +2072,8 @@
 	$(WIN32_SOURCE) \
 	wordlist.cc
 nodist_tests_test_http_range_SOURCES = \
-	$(BUILT_SOURCES)
+	$(BUILT_SOURCES) \
+	$(DISKIO_GEN_SOURCE)
 tests_test_http_range_LDADD = \
 	$(AUTH_ACL_LIBS) \
 	ident/libident.la \
@@ -2016,22 +2082,24 @@
 	acl/libstate.la \
 	$(AUTH_LIBS) \
 	acl/libapi.la \
-	base/libbase.la \
 	libsquid.la \
 	ip/libip.la \
 	fs/libfs.la \
-	ipc/libipc.la \
-	mgr/libmgr.la \
 	anyp/libanyp.la \
-	$(SNMP_LIBS) \
 	icmp/libicmp.la icmp/libicmp-core.la \
 	comm/libcomm.la \
 	log/liblog.la \
 	format/libformat.la \
 	$(REPL_OBJS) \
+	$(DISK_LIBS) \
+	$(DISK_OS_LIBS) \
 	$(ADAPTATION_LIBS) \
 	$(ESI_LIBS) \
 	$(SSL_LIBS) \
+	ipc/libipc.la \
+	base/libbase.la \
+	mgr/libmgr.la \
+	$(SNMP_LIBS) \
 	$(top_builddir)/lib/libmisccontainers.la \
 	$(top_builddir)/lib/libmiscencoding.la \
 	$(top_builddir)/lib/libmiscutil.la \
@@ -2054,7 +2122,9 @@
 	MemBuf.cc \
 	MemBuf.h \
 	mem.cc \
+	String.cc \
 	structs.h \
+	tests/stub_cache_cf.cc \
 	tests/stub_cache_manager.cc \
 	tests/stub_debug.cc \
 	tests/stub_event.cc \
@@ -2062,7 +2132,8 @@
 	tests/testHttpParser.cc \
 	tests/testHttpParser.h \
 	tests/testMain.cc \
-	time.cc
+	time.cc \
+	wordlist.cc
 nodist_tests_testHttpParser_SOURCES = \
 	$(TESTSOURCES)
 tests_testHttpParser_LDADD= \
@@ -2091,6 +2162,7 @@
 	tests/testHttpRequestMethod.h \
 	tests/testHttpRequestMethod.cc \
 	tests/testMain.cc \
+	tests/stub_DiskIOModule.cc \
 	tests/stub_main_cc.cc \
 	tests/stub_ipc_Forwarder.cc \
 	time.cc \
@@ -2140,7 +2212,9 @@
 	HttpBody.cc \
 	HttpHeader.cc \
 	HttpHeaderTools.cc \
+	HttpHdrCc.h \
 	HttpHdrCc.cc \
+	HttpHdrCc.cci \
 	HttpHdrContRange.cc \
 	HttpHdrRange.cc \
 	HttpHdrSc.cc \
@@ -2205,6 +2279,7 @@
 	tools.cc \
 	tunnel.cc \
 	SwapDir.cc \
+	MemStore.cc \
 	url.cc \
 	URLScheme.cc \
 	urn.cc \
@@ -2223,11 +2298,11 @@
 	acl/libstate.la \
 	$(AUTH_LIBS) \
 	acl/libapi.la \
-	base/libbase.la \
 	libsquid.la \
 	ip/libip.la \
 	fs/libfs.la \
 	ipc/libipc.la \
+	base/libbase.la \
 	mgr/libmgr.la \
 	anyp/libanyp.la \
 	$(SNMP_LIBS) \
@@ -2242,6 +2317,7 @@
 	$(top_builddir)/lib/libmisccontainers.la \
 	$(top_builddir)/lib/libmiscencoding.la \
 	$(top_builddir)/lib/libmiscutil.la \
+	$(DISK_OS_LIBS) \
 	$(REGEXLIB) \
 	$(SQUID_CPPUNIT_LIBS) \
 	$(SQUID_CPPUNIT_LA) \
@@ -2270,7 +2346,9 @@
 	event.cc \
 	EventLoop.cc \
 	filemap.cc \
+	HttpHdrCc.h \
 	HttpHdrCc.cc \
+	HttpHdrCc.cci \
 	HttpHdrContRange.cc \
 	HttpHdrRange.cc \
 	HttpHdrSc.cc \
@@ -2322,14 +2400,15 @@
 	tests/stub_http.cc \
 	tests/stub_HttpReply.cc \
 	tests/stub_HttpRequest.cc \
+	tests/stub_libcomm.cc \
 	tests/stub_MemObject.cc \
+	tests/stub_MemStore.cc \
 	tests/stub_mime.cc \
 	tests/stub_Port.cc \
 	tests/stub_store_client.cc \
 	tests/stub_store_rebuild.cc \
 	tests/stub_store_swapout.cc \
 	tests/stub_tools.cc \
-	tests/stub_TypedMsgHdr.cc \
 	tests/stub_UdsOp.cc \
 	tests/testMain.cc \
 	tests/testStore.cc \
@@ -2367,8 +2446,8 @@
 	libsquid.la \
 	ip/libip.la \
 	fs/libfs.la \
-	ipc/libipc.la \
 	mgr/libmgr.la \
+	ipc/libipc.la \
 	anyp/libanyp.la \
 	$(top_builddir)/lib/libmisccontainers.la \
 	$(top_builddir)/lib/libmiscencoding.la \
@@ -2390,14 +2469,17 @@
 tests_testString_SOURCES = \
 	ClientInfo.h \
 	mem.cc \
+	MemBuf.cc \
 	String.cc \
 	tests/testMain.cc \
 	tests/testString.cc \
 	tests/testString.h \
+	tests/stub_cache_cf.cc \
 	tests/stub_cache_manager.cc \
 	tests/stub_debug.cc \
 	tests/stub_HelperChildConfig.cc \
-	time.cc
+	time.cc \
+	wordlist.cc
 nodist_tests_testString_SOURCES = \
 	$(TESTSOURCES)
 tests_testString_LDADD = \
@@ -2442,9 +2524,9 @@
 	tests/stub_HelperChildConfig.cc \
 	tests/stub_icp.cc \
 	tests/stub_ipc.cc \
+	tests/stub_MemStore.cc \
 	tests/stub_pconn.cc \
 	tests/stub_Port.cc \
-	tests/stub_TypedMsgHdr.cc \
 	tests/stub_UdsOp.cc \
 	tests/stub_internal.cc \
 	tests/stub_store_rebuild.cc \
@@ -2504,7 +2586,9 @@
 	MemBuf.cc \
 	HttpHdrContRange.cc \
 	Packer.cc \
+	HttpHdrCc.h \
 	HttpHdrCc.cc \
+	HttpHdrCc.cci \
 	HttpHdrSc.cc \
 	HttpHdrScTarget.cc \
 	url.cc \
@@ -2540,17 +2624,17 @@
 	acl/libstate.la \
 	$(AUTH_LIBS) \
 	acl/libapi.la \
-	base/libbase.la \
 	libsquid.la \
 	ip/libip.la \
 	fs/libfs.la \
-	ipc/libipc.la \
 	mgr/libmgr.la \
 	$(REPL_OBJS) \
 	acl/libacls.la \
 	anyp/libanyp.la \
 	$(DISK_LIBS) \
 	$(DISK_OS_LIBS) \
+	acl/libapi.la \
+	ipc/libipc.la \
 	$(SSL_LIBS) \
 	comm/libcomm.la \
 	base/libbase.la \
@@ -2572,10 +2656,12 @@
 	tests/testMain.cc \
 	tests/testCoss.h \
 	tests/stub_cache_manager.cc \
+	tests/stub_client_db.cc \
 	tests/stub_debug.cc \
 	tests/stub_HelperChildConfig.cc \
 	tests/stub_internal.cc \
-	tests/stub_CommIO.cc \
+	tests/stub_ipc.cc \
+	tests/stub_pconn.cc \
 	tests/stub_store_rebuild.cc \
 	fd.cc \
 	disk.cc \
@@ -2620,8 +2706,6 @@
 	tests/stub_helper.cc \
 	cbdata.cc \
 	String.cc \
-	tests/stub_comm.cc \
-	tests/stub_debug.cc \
 	tests/stub_client_side_request.cc \
 	tests/stub_http.cc \
 	mem_node.cc \
@@ -2634,7 +2718,9 @@
 	MemBuf.cc \
 	HttpHdrContRange.cc \
 	Packer.cc \
+	HttpHdrCc.h \
 	HttpHdrCc.cc \
+	HttpHdrCc.cci \
 	HttpHdrSc.cc \
 	HttpHdrScTarget.cc \
 	url.cc \
@@ -2645,8 +2731,11 @@
 	tests/stub_HttpRequest.cc \
 	tests/stub_access_log.cc \
 	refresh.cc \
+	tests/stub_MemStore.cc \
+	tests/stub_Port.cc \
 	tests/stub_store_client.cc \
 	tests/stub_tools.cc \
+	tests/stub_UdsOp.cc \
 	tests/testStoreSupport.cc \
 	tests/testStoreSupport.h \
 	time.cc \
@@ -2661,6 +2750,7 @@
 	$(TESTSOURCES) \
 	$(DISKIO_GEN_SOURCE)
 tests_testCoss_LDADD = \
+	anyp/libanyp.la \
 	libsquid.la \
 	$(REGEXLIB) \
 	$(AUTH_ACL_LIBS) \
@@ -2670,18 +2760,19 @@
 	acl/libstate.la \
 	$(AUTH_LIBS) \
 	acl/libapi.la \
-	base/libbase.la \
 	libsquid.la \
+	comm/libcomm.la \
 	ip/libip.la \
 	fs/libfs.la \
-	ipc/libipc.la \
 	mgr/libmgr.la \
 	$(REPL_OBJS) \
 	$(DISK_LIBS) \
 	$(DISK_OS_LIBS) \
 	$(COMMON_LIBS) \
-	libsquid.la \
+	$(SSL_LIBS) \
 	acl/libapi.la \
+	ipc/libipc.la \
+	base/libbase.la \
 	$(top_builddir)/lib/libmisccontainers.la \
 	$(top_builddir)/lib/libmiscencoding.la \
 	$(top_builddir)/lib/libmiscutil.la \
@@ -2758,7 +2849,9 @@
 	MemBuf.cc \
 	HttpHdrContRange.cc \
 	Packer.cc \
+	HttpHdrCc.h \
 	HttpHdrCc.cc \
+	HttpHdrCc.cci \
 	HttpHdrSc.cc \
 	HttpHdrScTarget.cc \
 	url.cc \
@@ -2860,7 +2953,9 @@
 	$(HTCPSOURCE) \
 	http.cc \
 	HttpBody.cc \
+	HttpHdrCc.h \
 	HttpHdrCc.cc \
+	HttpHdrCc.cci \
 	HttpHdrContRange.cc \
 	HttpHdrRange.cc \
 	HttpHdrSc.cc \
@@ -2932,6 +3027,7 @@
 	StoreSwapLogData.cc \
 	String.cc \
 	SwapDir.cc \
+	MemStore.cc \
 	tests/stub_debug.cc \
 	tests/stub_DiskIOModule.cc \
 	tests/stub_main_cc.cc \
@@ -2973,6 +3069,7 @@
 	icmp/libicmp.la icmp/libicmp-core.la \
 	comm/libcomm.la \
 	log/liblog.la \
+	$(DISK_OS_LIBS) \
 	format/libformat.la \
 	$(REGEXLIB) \
 	$(REPL_OBJS) \
diff -u -r -N squid-3.2.0.12/src/Makefile.in squid-3.2.0.13/src/Makefile.in
--- squid-3.2.0.12/src/Makefile.in	2011-09-16 23:38:16.000000000 +1200
+++ squid-3.2.0.13/src/Makefile.in	2011-10-14 14:47:47.000000000 +1300
@@ -139,6 +139,18 @@
 	DiskIO/DiskThreads/DiskThreadsDiskIOModule.$(OBJEXT) \
 	DiskIO/DiskThreads/DiskThreadsIOStrategy.$(OBJEXT)
 libDiskThreads_a_OBJECTS = $(am_libDiskThreads_a_OBJECTS)
+libIpcIo_a_AR = $(AR) $(ARFLAGS)
+libIpcIo_a_LIBADD =
+am_libIpcIo_a_OBJECTS = DiskIO/IpcIo/IpcIoFile.$(OBJEXT) \
+	DiskIO/IpcIo/IpcIoIOStrategy.$(OBJEXT) \
+	DiskIO/IpcIo/IpcIoDiskIOModule.$(OBJEXT)
+libIpcIo_a_OBJECTS = $(am_libIpcIo_a_OBJECTS)
+libMmapped_a_AR = $(AR) $(ARFLAGS)
+libMmapped_a_LIBADD =
+am_libMmapped_a_OBJECTS = DiskIO/Mmapped/MmappedFile.$(OBJEXT) \
+	DiskIO/Mmapped/MmappedIOStrategy.$(OBJEXT) \
+	DiskIO/Mmapped/MmappedDiskIOModule.$(OBJEXT)
+libMmapped_a_OBJECTS = $(am_libMmapped_a_OBJECTS)
 LTLIBRARIES = $(noinst_LTLIBRARIES)
 libsquid_la_LIBADD =
 am_libsquid_la_OBJECTS = comm.lo CommCalls.lo DescriptorSet.lo \
@@ -222,42 +234,42 @@
 	HelperChildConfig.h HelperChildConfig.cc hier_code.h \
 	HierarchyLogEntry.h htcp.cc htcp.h http.cc http.h \
 	HttpStatusCode.h HttpStatusLine.cc HttpStatusLine.h \
-	HttpHdrCc.cc HttpHdrRange.cc HttpHdrSc.cc HttpHdrSc.h \
-	HttpHdrScTarget.cc HttpHdrScTarget.h HttpHdrContRange.cc \
-	HttpHdrContRange.h HttpHeader.cc HttpHeader.h HttpHeaderMask.h \
-	HttpHeaderRange.h HttpHeaderTools.cc HttpBody.cc \
-	HttpControlMsg.h HttpMsg.cc HttpMsg.h HttpParser.cc \
-	HttpParser.h HttpReply.cc HttpReply.h HttpRequest.cc \
-	HttpRequest.h HttpRequestMethod.cc HttpRequestMethod.h \
-	HttpVersion.h ICP.h icp_opcode.h icp_v2.cc icp_v3.cc int.cc \
-	internal.cc ipc.cc ipc_win32.cc ipcache.cc ipcache.h \
-	LeakFinder.cc list.cc lookup_t.h main.cc mem.cc mem_node.cc \
-	mem_node.h Mem.h MemBuf.cc MemObject.cc MemObject.h mime.cc \
-	mime_header.cc multicast.cc neighbors.cc Packer.cc Packer.h \
-	Parsing.cc Parsing.h ProfStats.cc pconn.cc pconn.h \
-	PeerDigest.h peer_digest.cc peer_proxy_negotiate_auth.cc \
-	peer_select.cc peer_sourcehash.cc peer_userhash.cc \
-	PeerSelectState.h PingData.h protos.h redirect.cc refresh.cc \
-	RemovalPolicy.cc RemovalPolicy.h send-announce.cc \
-	base/InstanceId.h MemBlob.h MemBlob.cc snmp_core.h \
-	snmp_core.cc snmp_agent.cc squid.h SquidMath.h SquidMath.cc \
-	SquidNew.cc stat.cc StatHist.cc String.cc stmem.cc stmem.h \
-	store.cc Store.h StoreFileSystem.cc StoreFileSystem.h \
-	StoreHashIndex.h store_io.cc StoreIOBuffer.h StoreIOState.cc \
-	StoreIOState.h store_client.cc StoreClient.h store_digest.cc \
-	store_dir.cc store_key_md5.cc store_log.cc store_rebuild.cc \
-	store_swapin.cc store_swapmeta.cc store_swapout.cc \
-	StoreMeta.cc StoreMeta.h StoreMetaMD5.cc StoreMetaMD5.h \
-	StoreMetaSTD.cc StoreMetaSTD.h StoreMetaSTDLFS.cc \
-	StoreMetaSTDLFS.h StoreMetaObjSize.h StoreMetaUnpacker.cc \
-	StoreMetaUnpacker.h StoreMetaURL.cc StoreMetaURL.h \
-	StoreMetaVary.cc StoreMetaVary.h StoreSearch.h \
+	HttpHdrCc.h HttpHdrCc.cc HttpHdrCc.cci HttpHdrRange.cc \
+	HttpHdrSc.cc HttpHdrSc.h HttpHdrScTarget.cc HttpHdrScTarget.h \
+	HttpHdrContRange.cc HttpHdrContRange.h HttpHeader.cc \
+	HttpHeader.h HttpHeaderMask.h HttpHeaderRange.h \
+	HttpHeaderTools.cc HttpBody.cc HttpControlMsg.h HttpMsg.cc \
+	HttpMsg.h HttpParser.cc HttpParser.h HttpReply.cc HttpReply.h \
+	HttpRequest.cc HttpRequest.h HttpRequestMethod.cc \
+	HttpRequestMethod.h HttpVersion.h ICP.h icp_opcode.h icp_v2.cc \
+	icp_v3.cc int.cc internal.cc ipc.cc ipc_win32.cc ipcache.cc \
+	ipcache.h LeakFinder.cc list.cc lookup_t.h main.cc mem.cc \
+	mem_node.cc mem_node.h Mem.h MemBuf.cc MemObject.cc \
+	MemObject.h mime.cc mime_header.cc multicast.cc neighbors.cc \
+	Packer.cc Packer.h Parsing.cc Parsing.h ProfStats.cc pconn.cc \
+	pconn.h PeerDigest.h peer_digest.cc \
+	peer_proxy_negotiate_auth.cc peer_select.cc peer_sourcehash.cc \
+	peer_userhash.cc PeerSelectState.h PingData.h protos.h \
+	redirect.cc refresh.cc RemovalPolicy.cc RemovalPolicy.h \
+	send-announce.cc base/InstanceId.h MemBlob.h MemBlob.cc \
+	snmp_core.h snmp_core.cc snmp_agent.cc squid.h SquidMath.h \
+	SquidMath.cc SquidNew.cc stat.cc StatHist.cc String.cc \
+	stmem.cc stmem.h store.cc Store.h StoreFileSystem.cc \
+	StoreFileSystem.h StoreHashIndex.h store_io.cc StoreIOBuffer.h \
+	StoreIOState.cc StoreIOState.h store_client.cc StoreClient.h \
+	store_digest.cc store_dir.cc store_key_md5.cc store_log.cc \
+	store_rebuild.cc store_swapin.cc store_swapmeta.cc \
+	store_swapout.cc StoreMeta.cc StoreMeta.h StoreMetaMD5.cc \
+	StoreMetaMD5.h StoreMetaSTD.cc StoreMetaSTD.h \
+	StoreMetaSTDLFS.cc StoreMetaSTDLFS.h StoreMetaObjSize.h \
+	StoreMetaUnpacker.cc StoreMetaUnpacker.h StoreMetaURL.cc \
+	StoreMetaURL.h StoreMetaVary.cc StoreMetaVary.h StoreSearch.h \
 	StoreSwapLogData.cc StoreSwapLogData.h Server.cc Server.h \
-	structs.h swap_log_op.h SwapDir.cc SwapDir.h time.cc \
-	TimeOrTag.h tools.cc tunnel.cc typedefs.h unlinkd.cc url.cc \
-	URL.h URLScheme.cc URLScheme.h urn.cc wccp.cc wccp2.cc \
-	whois.cc wordlist.cc wordlist.h win32.cc WinSvc.cc \
-	LoadableModule.h LoadableModule.cc LoadableModules.h \
+	structs.h swap_log_op.h SwapDir.cc SwapDir.h MemStore.cc \
+	MemStore.h time.cc TimeOrTag.h tools.cc tunnel.cc typedefs.h \
+	unlinkd.cc url.cc URL.h URLScheme.cc URLScheme.h urn.cc \
+	wccp.cc wccp2.cc whois.cc wordlist.cc wordlist.h win32.cc \
+	WinSvc.cc LoadableModule.h LoadableModule.cc LoadableModules.h \
 	LoadableModules.cc
 am__objects_4 = AclRegs.$(OBJEXT) AuthReg.$(OBJEXT)
 am__objects_5 = delay_pools.$(OBJEXT) DelayId.$(OBJEXT) \
@@ -332,11 +344,12 @@
 	StoreMetaSTD.$(OBJEXT) StoreMetaSTDLFS.$(OBJEXT) \
 	StoreMetaUnpacker.$(OBJEXT) StoreMetaURL.$(OBJEXT) \
 	StoreMetaVary.$(OBJEXT) StoreSwapLogData.$(OBJEXT) \
-	Server.$(OBJEXT) SwapDir.$(OBJEXT) time.$(OBJEXT) \
-	tools.$(OBJEXT) tunnel.$(OBJEXT) $(am__objects_16) \
-	url.$(OBJEXT) URLScheme.$(OBJEXT) urn.$(OBJEXT) wccp.$(OBJEXT) \
-	wccp2.$(OBJEXT) whois.$(OBJEXT) wordlist.$(OBJEXT) \
-	$(am__objects_17) $(am__objects_18) $(am__objects_20)
+	Server.$(OBJEXT) SwapDir.$(OBJEXT) MemStore.$(OBJEXT) \
+	time.$(OBJEXT) tools.$(OBJEXT) tunnel.$(OBJEXT) \
+	$(am__objects_16) url.$(OBJEXT) URLScheme.$(OBJEXT) \
+	urn.$(OBJEXT) wccp.$(OBJEXT) wccp2.$(OBJEXT) whois.$(OBJEXT) \
+	wordlist.$(OBJEXT) $(am__objects_17) $(am__objects_18) \
+	$(am__objects_20)
 am__EXTRA_squid_SOURCES_DIST = DiskIO/AIO/aio_win32.cc \
 	DiskIO/AIO/aio_win32.h ConfigOption.h CommonPool.h \
 	CompositePoolNode.h delay_pools.cc DelayId.cc DelayId.h \
@@ -389,9 +402,10 @@
 	tests/stub_debug.$(OBJEXT) tests/stub_DelayId.$(OBJEXT) \
 	tests/stub_DiskIOModule.$(OBJEXT) tests/stub_fd.$(OBJEXT) \
 	tests/stub_HttpRequest.$(OBJEXT) \
-	tests/stub_MemObject.$(OBJEXT) tests/stub_mime.$(OBJEXT) \
-	tests/stub_store.$(OBJEXT) tests/stub_store_rebuild.$(OBJEXT) \
-	tests/stub_store_swapout.$(OBJEXT) \
+	tests/stub_MemObject.$(OBJEXT) tests/stub_MemStore.$(OBJEXT) \
+	tests/stub_mime.$(OBJEXT) tests/stub_store.$(OBJEXT) \
+	tests/stub_store_rebuild.$(OBJEXT) \
+	tests/stub_store_swapout.$(OBJEXT) tests/stub_tools.$(OBJEXT) \
 	tests/stub_cache_manager.$(OBJEXT) \
 	tests/testACLMaxUserIP.$(OBJEXT) tests/testMain.$(OBJEXT) \
 	time.$(OBJEXT) url.$(OBJEXT) URLScheme.$(OBJEXT) mem.$(OBJEXT) \
@@ -429,14 +443,19 @@
 	DelayPools.h DelaySpec.cc DelaySpec.h DelayTagged.cc \
 	DelayTagged.h DelayUser.cc DelayUser.h DelayVector.cc \
 	DelayVector.h NullDelayId.cc NullDelayId.h \
-	ClientDelayConfig.cc ClientDelayConfig.h disk.cc dlink.h \
-	dlink.cc dns_internal.cc DnsLookupDetails.h \
-	DnsLookupDetails.cc dns.cc errorpage.cc ETag.cc event.cc \
-	external_acl.cc ExternalACLEntry.cc fd.cc fde.cc forward.cc \
-	fqdncache.cc ftp.cc gopher.cc hier_code.h helper.cc \
-	HelperChildConfig.h HelperChildConfig.cc htcp.cc htcp.h \
-	http.cc HttpBody.cc HttpHeader.cc HttpHeaderTools.cc \
-	HttpHdrCc.cc HttpHdrContRange.cc HttpHdrRange.cc HttpHdrSc.cc \
+	ClientDelayConfig.cc ClientDelayConfig.h \
+	DiskIO/DiskIOModule.cc DiskIO/ReadRequest.cc \
+	DiskIO/ReadRequest.h DiskIO/WriteRequest.cc \
+	DiskIO/WriteRequest.h DiskIO/DiskFile.h \
+	DiskIO/DiskIOStrategy.h DiskIO/IORequestor.h \
+	DiskIO/DiskIOModule.h disk.cc dlink.h dlink.cc dns_internal.cc \
+	DnsLookupDetails.h DnsLookupDetails.cc dns.cc errorpage.cc \
+	ETag.cc event.cc external_acl.cc ExternalACLEntry.cc fd.cc \
+	fde.cc filemap.cc forward.cc fqdncache.cc ftp.cc gopher.cc \
+	hier_code.h helper.cc HelperChildConfig.h HelperChildConfig.cc \
+	htcp.cc htcp.h http.cc HttpBody.cc HttpHeader.cc \
+	HttpHeaderTools.cc HttpHdrCc.h HttpHdrCc.cc HttpHdrCc.cci \
+	HttpHdrContRange.cc HttpHdrRange.cc HttpHdrSc.cc \
 	HttpHdrScTarget.cc HttpMsg.cc HttpReply.cc HttpStatusLine.cc \
 	icp_v2.cc icp_v3.cc ipc.cc ipc_win32.cc ipcache.cc int.cc \
 	internal.cc list.cc multicast.cc mem_node.cc MemBuf.cc \
@@ -452,8 +471,8 @@
 	StoreIOState.cc StoreMeta.cc StoreMetaMD5.cc StoreMetaSTD.cc \
 	StoreMetaSTDLFS.cc StoreMetaUnpacker.cc StoreMetaURL.cc \
 	StoreMetaVary.cc StoreSwapLogData.cc tools.cc tunnel.cc \
-	SwapDir.cc url.cc URLScheme.cc urn.cc wccp2.cc whois.cc \
-	FadingCounter.cc win32.cc wordlist.cc
+	SwapDir.cc MemStore.cc unlinkd.cc url.cc URLScheme.cc urn.cc \
+	wccp2.cc whois.cc FadingCounter.cc win32.cc wordlist.cc
 am_tests_testCacheManager_OBJECTS = $(am__objects_4) debug.$(OBJEXT) \
 	HttpParser.$(OBJEXT) HttpRequest.$(OBJEXT) \
 	HttpRequestMethod.$(OBJEXT) mem.$(OBJEXT) String.$(OBJEXT) \
@@ -467,24 +486,24 @@
 	client_side_reply.$(OBJEXT) client_side_request.$(OBJEXT) \
 	clientStream.$(OBJEXT) ConfigOption.$(OBJEXT) \
 	ConfigParser.$(OBJEXT) CpuAffinityMap.$(OBJEXT) \
-	CpuAffinitySet.$(OBJEXT) $(am__objects_6) disk.$(OBJEXT) \
-	dlink.$(OBJEXT) $(am__objects_8) errorpage.$(OBJEXT) \
-	ETag.$(OBJEXT) event.$(OBJEXT) external_acl.$(OBJEXT) \
-	ExternalACLEntry.$(OBJEXT) fd.$(OBJEXT) fde.$(OBJEXT) \
-	forward.$(OBJEXT) fqdncache.$(OBJEXT) ftp.$(OBJEXT) \
-	gopher.$(OBJEXT) helper.$(OBJEXT) HelperChildConfig.$(OBJEXT) \
-	$(am__objects_9) http.$(OBJEXT) HttpBody.$(OBJEXT) \
-	HttpHeader.$(OBJEXT) HttpHeaderTools.$(OBJEXT) \
-	HttpHdrCc.$(OBJEXT) HttpHdrContRange.$(OBJEXT) \
-	HttpHdrRange.$(OBJEXT) HttpHdrSc.$(OBJEXT) \
-	HttpHdrScTarget.$(OBJEXT) HttpMsg.$(OBJEXT) \
-	HttpReply.$(OBJEXT) HttpStatusLine.$(OBJEXT) icp_v2.$(OBJEXT) \
-	icp_v3.$(OBJEXT) $(am__objects_10) ipcache.$(OBJEXT) \
-	int.$(OBJEXT) internal.$(OBJEXT) list.$(OBJEXT) \
-	multicast.$(OBJEXT) mem_node.$(OBJEXT) MemBuf.$(OBJEXT) \
-	MemObject.$(OBJEXT) mime.$(OBJEXT) mime_header.$(OBJEXT) \
-	neighbors.$(OBJEXT) Packer.$(OBJEXT) Parsing.$(OBJEXT) \
-	pconn.$(OBJEXT) peer_digest.$(OBJEXT) \
+	CpuAffinitySet.$(OBJEXT) $(am__objects_6) $(am__objects_7) \
+	disk.$(OBJEXT) dlink.$(OBJEXT) $(am__objects_8) \
+	errorpage.$(OBJEXT) ETag.$(OBJEXT) event.$(OBJEXT) \
+	external_acl.$(OBJEXT) ExternalACLEntry.$(OBJEXT) fd.$(OBJEXT) \
+	fde.$(OBJEXT) filemap.$(OBJEXT) forward.$(OBJEXT) \
+	fqdncache.$(OBJEXT) ftp.$(OBJEXT) gopher.$(OBJEXT) \
+	helper.$(OBJEXT) HelperChildConfig.$(OBJEXT) $(am__objects_9) \
+	http.$(OBJEXT) HttpBody.$(OBJEXT) HttpHeader.$(OBJEXT) \
+	HttpHeaderTools.$(OBJEXT) HttpHdrCc.$(OBJEXT) \
+	HttpHdrContRange.$(OBJEXT) HttpHdrRange.$(OBJEXT) \
+	HttpHdrSc.$(OBJEXT) HttpHdrScTarget.$(OBJEXT) \
+	HttpMsg.$(OBJEXT) HttpReply.$(OBJEXT) HttpStatusLine.$(OBJEXT) \
+	icp_v2.$(OBJEXT) icp_v3.$(OBJEXT) $(am__objects_10) \
+	ipcache.$(OBJEXT) int.$(OBJEXT) internal.$(OBJEXT) \
+	list.$(OBJEXT) multicast.$(OBJEXT) mem_node.$(OBJEXT) \
+	MemBuf.$(OBJEXT) MemObject.$(OBJEXT) mime.$(OBJEXT) \
+	mime_header.$(OBJEXT) neighbors.$(OBJEXT) Packer.$(OBJEXT) \
+	Parsing.$(OBJEXT) pconn.$(OBJEXT) peer_digest.$(OBJEXT) \
 	peer_proxy_negotiate_auth.$(OBJEXT) peer_select.$(OBJEXT) \
 	peer_sourcehash.$(OBJEXT) peer_userhash.$(OBJEXT) \
 	redirect.$(OBJEXT) refresh.$(OBJEXT) RemovalPolicy.$(OBJEXT) \
@@ -500,10 +519,12 @@
 	StoreMetaSTDLFS.$(OBJEXT) StoreMetaUnpacker.$(OBJEXT) \
 	StoreMetaURL.$(OBJEXT) StoreMetaVary.$(OBJEXT) \
 	StoreSwapLogData.$(OBJEXT) tools.$(OBJEXT) tunnel.$(OBJEXT) \
-	SwapDir.$(OBJEXT) url.$(OBJEXT) URLScheme.$(OBJEXT) \
-	urn.$(OBJEXT) wccp2.$(OBJEXT) whois.$(OBJEXT) \
-	FadingCounter.$(OBJEXT) $(am__objects_17) wordlist.$(OBJEXT)
-nodist_tests_testCacheManager_OBJECTS = $(am__objects_22)
+	SwapDir.$(OBJEXT) MemStore.$(OBJEXT) $(am__objects_16) \
+	url.$(OBJEXT) URLScheme.$(OBJEXT) urn.$(OBJEXT) \
+	wccp2.$(OBJEXT) whois.$(OBJEXT) FadingCounter.$(OBJEXT) \
+	$(am__objects_17) wordlist.$(OBJEXT)
+nodist_tests_testCacheManager_OBJECTS = $(am__objects_22) \
+	$(am__objects_21)
 tests_testCacheManager_OBJECTS = $(am_tests_testCacheManager_OBJECTS) \
 	$(nodist_tests_testCacheManager_OBJECTS)
 tests_testCacheManager_LINK = $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) \
@@ -511,8 +532,9 @@
 	$(CXXFLAGS) $(tests_testCacheManager_LDFLAGS) $(LDFLAGS) -o $@
 am__tests_testCoss_SOURCES_DIST = tests/testCoss.cc tests/testMain.cc \
 	tests/testCoss.h tests/stub_cache_manager.cc \
-	tests/stub_debug.cc tests/stub_HelperChildConfig.cc \
-	tests/stub_internal.cc tests/stub_CommIO.cc \
+	tests/stub_client_db.cc tests/stub_debug.cc \
+	tests/stub_HelperChildConfig.cc tests/stub_internal.cc \
+	tests/stub_ipc.cc tests/stub_pconn.cc \
 	tests/stub_store_rebuild.cc fd.cc disk.cc filemap.cc \
 	HttpBody.cc HttpReply.cc HttpStatusLine.cc int.cc list.cc \
 	MemObject.cc StoreSwapLogData.cc StoreIOState.cc StoreMeta.cc \
@@ -531,14 +553,16 @@
 	HttpRequestMethod.cc store_key_md5.cc Parsing.cc \
 	ConfigOption.cc SwapDir.cc tests/stub_acl.cc \
 	tests/stub_cache_cf.cc tests/stub_helper.cc cbdata.cc \
-	String.cc tests/stub_comm.cc tests/stub_client_side_request.cc \
-	tests/stub_http.cc mem_node.cc stmem.cc tests/stub_mime.cc \
-	HttpHeaderTools.cc HttpHeader.cc mem.cc ClientInfo.h MemBuf.cc \
-	HttpHdrContRange.cc Packer.cc HttpHdrCc.cc HttpHdrSc.cc \
-	HttpHdrScTarget.cc url.cc StatHist.cc HttpHdrRange.cc ETag.cc \
-	tests/stub_errorpage.cc tests/stub_HttpRequest.cc \
-	tests/stub_access_log.cc refresh.cc tests/stub_store_client.cc \
-	tests/stub_tools.cc tests/testStoreSupport.cc \
+	String.cc tests/stub_client_side_request.cc tests/stub_http.cc \
+	mem_node.cc stmem.cc tests/stub_mime.cc HttpHeaderTools.cc \
+	HttpHeader.cc mem.cc ClientInfo.h MemBuf.cc \
+	HttpHdrContRange.cc Packer.cc HttpHdrCc.h HttpHdrCc.cc \
+	HttpHdrCc.cci HttpHdrSc.cc HttpHdrScTarget.cc url.cc \
+	StatHist.cc HttpHdrRange.cc ETag.cc tests/stub_errorpage.cc \
+	tests/stub_HttpRequest.cc tests/stub_access_log.cc refresh.cc \
+	tests/stub_MemStore.cc tests/stub_Port.cc \
+	tests/stub_store_client.cc tests/stub_tools.cc \
+	tests/stub_UdsOp.cc tests/testStoreSupport.cc \
 	tests/testStoreSupport.h time.cc URLScheme.cc wordlist.cc \
 	DiskIO/DiskIOModule.cc DiskIO/ReadRequest.cc \
 	DiskIO/ReadRequest.h DiskIO/WriteRequest.cc \
@@ -547,11 +571,12 @@
 	DiskIO/DiskIOModule.h
 am_tests_testCoss_OBJECTS = tests/testCoss.$(OBJEXT) \
 	tests/testMain.$(OBJEXT) tests/stub_cache_manager.$(OBJEXT) \
-	tests/stub_debug.$(OBJEXT) \
+	tests/stub_client_db.$(OBJEXT) tests/stub_debug.$(OBJEXT) \
 	tests/stub_HelperChildConfig.$(OBJEXT) \
-	tests/stub_internal.$(OBJEXT) tests/stub_CommIO.$(OBJEXT) \
-	tests/stub_store_rebuild.$(OBJEXT) fd.$(OBJEXT) disk.$(OBJEXT) \
-	filemap.$(OBJEXT) HttpBody.$(OBJEXT) HttpReply.$(OBJEXT) \
+	tests/stub_internal.$(OBJEXT) tests/stub_ipc.$(OBJEXT) \
+	tests/stub_pconn.$(OBJEXT) tests/stub_store_rebuild.$(OBJEXT) \
+	fd.$(OBJEXT) disk.$(OBJEXT) filemap.$(OBJEXT) \
+	HttpBody.$(OBJEXT) HttpReply.$(OBJEXT) \
 	HttpStatusLine.$(OBJEXT) int.$(OBJEXT) list.$(OBJEXT) \
 	MemObject.$(OBJEXT) StoreSwapLogData.$(OBJEXT) \
 	StoreIOState.$(OBJEXT) StoreMeta.$(OBJEXT) \
@@ -568,7 +593,6 @@
 	Parsing.$(OBJEXT) ConfigOption.$(OBJEXT) SwapDir.$(OBJEXT) \
 	tests/stub_acl.$(OBJEXT) tests/stub_cache_cf.$(OBJEXT) \
 	tests/stub_helper.$(OBJEXT) cbdata.$(OBJEXT) String.$(OBJEXT) \
-	tests/stub_comm.$(OBJEXT) tests/stub_debug.$(OBJEXT) \
 	tests/stub_client_side_request.$(OBJEXT) \
 	tests/stub_http.$(OBJEXT) mem_node.$(OBJEXT) stmem.$(OBJEXT) \
 	tests/stub_mime.$(OBJEXT) HttpHeaderTools.$(OBJEXT) \
@@ -580,9 +604,11 @@
 	tests/stub_errorpage.$(OBJEXT) \
 	tests/stub_HttpRequest.$(OBJEXT) \
 	tests/stub_access_log.$(OBJEXT) refresh.$(OBJEXT) \
+	tests/stub_MemStore.$(OBJEXT) tests/stub_Port.$(OBJEXT) \
 	tests/stub_store_client.$(OBJEXT) tests/stub_tools.$(OBJEXT) \
-	tests/testStoreSupport.$(OBJEXT) time.$(OBJEXT) \
-	URLScheme.$(OBJEXT) wordlist.$(OBJEXT) $(am__objects_7)
+	tests/stub_UdsOp.$(OBJEXT) tests/testStoreSupport.$(OBJEXT) \
+	time.$(OBJEXT) URLScheme.$(OBJEXT) wordlist.$(OBJEXT) \
+	$(am__objects_7)
 nodist_tests_testCoss_OBJECTS = swap_log_op.$(OBJEXT) \
 	SquidMath.$(OBJEXT) $(am__objects_23) $(am__objects_21)
 tests_testCoss_OBJECTS = $(am_tests_testCoss_OBJECTS) \
@@ -603,31 +629,32 @@
 	DiskIO/WriteRequest.cc DiskIO/WriteRequest.h DiskIO/DiskFile.h \
 	DiskIO/DiskIOStrategy.h DiskIO/IORequestor.h \
 	DiskIO/DiskIOModule.h disk.cc ETag.cc EventLoop.cc event.cc \
-	fd.cc filemap.cc HttpBody.cc HttpHdrCc.cc HttpHdrContRange.cc \
-	HttpHdrSc.cc HttpHdrScTarget.cc HttpHdrRange.cc \
-	HttpHeaderTools.cc HttpHeader.cc HttpMsg.cc HttpReply.cc \
-	HttpRequestMethod.cc HttpStatusLine.cc int.cc list.cc \
-	MemBuf.cc MemObject.cc mem_node.cc mem.cc Packer.cc Parsing.cc \
-	refresh.cc RemovalPolicy.cc StatHist.cc stmem.cc \
-	StoreFileSystem.cc StoreIOState.cc StoreMeta.cc \
-	StoreMetaMD5.cc StoreMetaSTD.cc StoreMetaSTDLFS.cc \
-	StoreMetaUnpacker.cc StoreMetaURL.cc StoreMetaVary.cc \
-	StoreSwapLogData.cc store_dir.cc store_io.cc store_key_md5.cc \
-	store_swapout.cc store_swapmeta.cc store.cc String.cc \
-	SwapDir.cc tests/stub_access_log.cc tests/stub_acl.cc \
-	tests/stub_cache_cf.cc tests/stub_cache_manager.cc \
-	tests/stub_client_db.cc tests/stub_client_side_request.cc \
-	tests/stub_debug.cc tests/stub_errorpage.cc \
-	tests/stub_helper.cc tests/stub_HelperChildConfig.cc \
-	tests/stub_HttpRequest.cc tests/stub_http.cc tests/stub_icp.cc \
-	tests/stub_internal.cc tests/stub_ipc.cc tests/stub_ipcache.cc \
-	tests/stub_libicmp.cc tests/stub_mime.cc tests/stub_pconn.cc \
+	fd.cc filemap.cc HttpBody.cc HttpHdrCc.h HttpHdrCc.cc \
+	HttpHdrCc.cci HttpHdrContRange.cc HttpHdrSc.cc \
+	HttpHdrScTarget.cc HttpHdrRange.cc HttpHeaderTools.cc \
+	HttpHeader.cc HttpMsg.cc HttpReply.cc HttpRequestMethod.cc \
+	HttpStatusLine.cc int.cc list.cc MemBuf.cc MemObject.cc \
+	mem_node.cc mem.cc Packer.cc Parsing.cc refresh.cc \
+	RemovalPolicy.cc StatHist.cc stmem.cc StoreFileSystem.cc \
+	StoreIOState.cc StoreMeta.cc StoreMetaMD5.cc StoreMetaSTD.cc \
+	StoreMetaSTDLFS.cc StoreMetaUnpacker.cc StoreMetaURL.cc \
+	StoreMetaVary.cc StoreSwapLogData.cc store_dir.cc store_io.cc \
+	store_key_md5.cc store_swapout.cc store_swapmeta.cc store.cc \
+	String.cc SwapDir.cc tests/stub_access_log.cc \
+	tests/stub_acl.cc tests/stub_cache_cf.cc \
+	tests/stub_cache_manager.cc tests/stub_client_db.cc \
+	tests/stub_client_side_request.cc tests/stub_debug.cc \
+	tests/stub_errorpage.cc tests/stub_helper.cc \
+	tests/stub_HelperChildConfig.cc tests/stub_HttpRequest.cc \
+	tests/stub_http.cc tests/stub_icp.cc tests/stub_internal.cc \
+	tests/stub_ipc.cc tests/stub_ipcache.cc tests/stub_libicmp.cc \
+	tests/stub_MemStore.cc tests/stub_mime.cc tests/stub_pconn.cc \
 	tests/stub_Port.cc tests/stub_store_client.cc \
 	tests/stub_store_rebuild.cc tests/stub_tools.cc \
-	tests/stub_TypedMsgHdr.cc tests/stub_UdsOp.cc \
-	tests/testDiskIO.cc tests/testDiskIO.h tests/testMain.cc \
-	tests/testStoreSupport.cc tests/testStoreSupport.h time.cc \
-	unlinkd.cc url.cc URLScheme.cc win32.cc wordlist.cc
+	tests/stub_UdsOp.cc tests/testDiskIO.cc tests/testDiskIO.h \
+	tests/testMain.cc tests/testStoreSupport.cc \
+	tests/testStoreSupport.h time.cc unlinkd.cc url.cc \
+	URLScheme.cc win32.cc wordlist.cc
 am_tests_testDiskIO_OBJECTS = CacheDigest.$(OBJEXT) cbdata.$(OBJEXT) \
 	ConfigOption.$(OBJEXT) ConfigParser.$(OBJEXT) $(am__objects_6) \
 	$(am__objects_7) disk.$(OBJEXT) ETag.$(OBJEXT) \
@@ -661,15 +688,14 @@
 	tests/stub_HttpRequest.$(OBJEXT) tests/stub_http.$(OBJEXT) \
 	tests/stub_icp.$(OBJEXT) tests/stub_internal.$(OBJEXT) \
 	tests/stub_ipc.$(OBJEXT) tests/stub_ipcache.$(OBJEXT) \
-	tests/stub_libicmp.$(OBJEXT) tests/stub_mime.$(OBJEXT) \
-	tests/stub_pconn.$(OBJEXT) tests/stub_Port.$(OBJEXT) \
-	tests/stub_store_client.$(OBJEXT) \
+	tests/stub_libicmp.$(OBJEXT) tests/stub_MemStore.$(OBJEXT) \
+	tests/stub_mime.$(OBJEXT) tests/stub_pconn.$(OBJEXT) \
+	tests/stub_Port.$(OBJEXT) tests/stub_store_client.$(OBJEXT) \
 	tests/stub_store_rebuild.$(OBJEXT) tests/stub_tools.$(OBJEXT) \
-	tests/stub_TypedMsgHdr.$(OBJEXT) tests/stub_UdsOp.$(OBJEXT) \
-	tests/testDiskIO.$(OBJEXT) tests/testMain.$(OBJEXT) \
-	tests/testStoreSupport.$(OBJEXT) time.$(OBJEXT) \
-	$(am__objects_16) url.$(OBJEXT) URLScheme.$(OBJEXT) \
-	$(am__objects_17) wordlist.$(OBJEXT)
+	tests/stub_UdsOp.$(OBJEXT) tests/testDiskIO.$(OBJEXT) \
+	tests/testMain.$(OBJEXT) tests/testStoreSupport.$(OBJEXT) \
+	time.$(OBJEXT) $(am__objects_16) url.$(OBJEXT) \
+	URLScheme.$(OBJEXT) $(am__objects_17) wordlist.$(OBJEXT)
 nodist_tests_testDiskIO_OBJECTS = $(am__objects_23) $(am__objects_21) \
 	SquidMath.$(OBJEXT) swap_log_op.$(OBJEXT)
 tests_testDiskIO_OBJECTS = $(am_tests_testDiskIO_OBJECTS) \
@@ -689,14 +715,19 @@
 	DelayPool.cc DelayPool.h DelayPools.h DelaySpec.cc DelaySpec.h \
 	DelayTagged.cc DelayTagged.h DelayUser.cc DelayUser.h \
 	DelayVector.cc DelayVector.h NullDelayId.cc NullDelayId.h \
-	ClientDelayConfig.cc ClientDelayConfig.h disk.cc dlink.h \
-	dlink.cc dns_internal.cc DnsLookupDetails.h \
-	DnsLookupDetails.cc dns.cc errorpage.cc ETag.cc event.cc \
-	EventLoop.h EventLoop.cc external_acl.cc ExternalACLEntry.cc \
-	FadingCounter.cc fd.cc fde.cc forward.cc fqdncache.cc ftp.cc \
-	gopher.cc helper.cc HelperChildConfig.h HelperChildConfig.cc \
-	hier_code.h htcp.cc htcp.h http.cc HttpBody.cc HttpHeader.cc \
-	HttpHeaderTools.cc HttpHdrCc.cc HttpHdrContRange.cc \
+	ClientDelayConfig.cc ClientDelayConfig.h \
+	DiskIO/DiskIOModule.cc DiskIO/ReadRequest.cc \
+	DiskIO/ReadRequest.h DiskIO/WriteRequest.cc \
+	DiskIO/WriteRequest.h DiskIO/DiskFile.h \
+	DiskIO/DiskIOStrategy.h DiskIO/IORequestor.h \
+	DiskIO/DiskIOModule.h disk.cc dlink.h dlink.cc dns_internal.cc \
+	DnsLookupDetails.h DnsLookupDetails.cc dns.cc errorpage.cc \
+	ETag.cc event.cc EventLoop.h EventLoop.cc external_acl.cc \
+	ExternalACLEntry.cc FadingCounter.cc fd.cc fde.cc filemap.cc \
+	forward.cc fqdncache.cc ftp.cc gopher.cc helper.cc \
+	HelperChildConfig.h HelperChildConfig.cc hier_code.h htcp.cc \
+	htcp.h http.cc HttpBody.cc HttpHeader.cc HttpHeaderTools.cc \
+	HttpHdrCc.h HttpHdrCc.cc HttpHdrCc.cci HttpHdrContRange.cc \
 	HttpHdrRange.cc HttpHdrSc.cc HttpHdrScTarget.cc HttpMsg.cc \
 	HttpParser.cc HttpParser.h HttpReply.cc HttpRequest.cc \
 	HttpRequestMethod.cc HttpStatusLine.cc icp_v2.cc icp_v3.cc \
@@ -717,8 +748,9 @@
 	StoreSwapLogData.cc String.cc SwapDir.cc \
 	tests/CapturingStoreEntry.h tests/testEvent.cc \
 	tests/testEvent.h tests/testMain.cc tests/stub_main_cc.cc \
-	tests/stub_ipc_Forwarder.cc time.cc tools.cc tunnel.cc url.cc \
-	URLScheme.cc urn.cc wccp2.cc whois.cc win32.cc wordlist.cc
+	tests/stub_ipc_Forwarder.cc time.cc tools.cc tunnel.cc \
+	MemStore.cc unlinkd.cc url.cc URLScheme.cc urn.cc wccp2.cc \
+	whois.cc win32.cc wordlist.cc
 am_tests_testEvent_OBJECTS = $(am__objects_4) BodyPipe.$(OBJEXT) \
 	CacheDigest.$(OBJEXT) cache_cf.$(OBJEXT) \
 	cache_manager.$(OBJEXT) carp.$(OBJEXT) cbdata.$(OBJEXT) \
@@ -727,49 +759,50 @@
 	client_side_request.$(OBJEXT) clientStream.$(OBJEXT) \
 	ConfigOption.$(OBJEXT) ConfigParser.$(OBJEXT) \
 	CpuAffinityMap.$(OBJEXT) CpuAffinitySet.$(OBJEXT) \
-	debug.$(OBJEXT) $(am__objects_6) disk.$(OBJEXT) \
-	dlink.$(OBJEXT) $(am__objects_8) errorpage.$(OBJEXT) \
-	ETag.$(OBJEXT) event.$(OBJEXT) EventLoop.$(OBJEXT) \
-	external_acl.$(OBJEXT) ExternalACLEntry.$(OBJEXT) \
-	FadingCounter.$(OBJEXT) fd.$(OBJEXT) fde.$(OBJEXT) \
-	forward.$(OBJEXT) fqdncache.$(OBJEXT) ftp.$(OBJEXT) \
-	gopher.$(OBJEXT) helper.$(OBJEXT) HelperChildConfig.$(OBJEXT) \
-	$(am__objects_9) http.$(OBJEXT) HttpBody.$(OBJEXT) \
-	HttpHeader.$(OBJEXT) HttpHeaderTools.$(OBJEXT) \
-	HttpHdrCc.$(OBJEXT) HttpHdrContRange.$(OBJEXT) \
-	HttpHdrRange.$(OBJEXT) HttpHdrSc.$(OBJEXT) \
-	HttpHdrScTarget.$(OBJEXT) HttpMsg.$(OBJEXT) \
-	HttpParser.$(OBJEXT) HttpReply.$(OBJEXT) HttpRequest.$(OBJEXT) \
-	HttpRequestMethod.$(OBJEXT) HttpStatusLine.$(OBJEXT) \
-	icp_v2.$(OBJEXT) icp_v3.$(OBJEXT) $(am__objects_10) \
-	ipcache.$(OBJEXT) int.$(OBJEXT) internal.$(OBJEXT) \
-	list.$(OBJEXT) mem.$(OBJEXT) mem_node.$(OBJEXT) \
-	MemBuf.$(OBJEXT) MemObject.$(OBJEXT) mime.$(OBJEXT) \
-	mime_header.$(OBJEXT) multicast.$(OBJEXT) neighbors.$(OBJEXT) \
-	Packer.$(OBJEXT) Parsing.$(OBJEXT) pconn.$(OBJEXT) \
-	peer_digest.$(OBJEXT) peer_proxy_negotiate_auth.$(OBJEXT) \
-	peer_select.$(OBJEXT) peer_sourcehash.$(OBJEXT) \
-	peer_userhash.$(OBJEXT) ProtoPort.$(OBJEXT) redirect.$(OBJEXT) \
-	refresh.$(OBJEXT) RemovalPolicy.$(OBJEXT) Server.$(OBJEXT) \
-	$(am__objects_15) SquidMath.$(OBJEXT) stat.$(OBJEXT) \
-	StatHist.$(OBJEXT) stmem.$(OBJEXT) store.$(OBJEXT) \
-	store_client.$(OBJEXT) store_digest.$(OBJEXT) \
-	store_dir.$(OBJEXT) store_io.$(OBJEXT) store_key_md5.$(OBJEXT) \
-	store_log.$(OBJEXT) store_rebuild.$(OBJEXT) \
-	store_swapin.$(OBJEXT) store_swapmeta.$(OBJEXT) \
-	store_swapout.$(OBJEXT) StoreFileSystem.$(OBJEXT) \
-	StoreIOState.$(OBJEXT) StoreMeta.$(OBJEXT) \
-	StoreMetaMD5.$(OBJEXT) StoreMetaSTD.$(OBJEXT) \
-	StoreMetaSTDLFS.$(OBJEXT) StoreMetaUnpacker.$(OBJEXT) \
-	StoreMetaURL.$(OBJEXT) StoreMetaVary.$(OBJEXT) \
-	StoreSwapLogData.$(OBJEXT) String.$(OBJEXT) SwapDir.$(OBJEXT) \
-	tests/testEvent.$(OBJEXT) tests/testMain.$(OBJEXT) \
-	tests/stub_main_cc.$(OBJEXT) \
+	debug.$(OBJEXT) $(am__objects_6) $(am__objects_7) \
+	disk.$(OBJEXT) dlink.$(OBJEXT) $(am__objects_8) \
+	errorpage.$(OBJEXT) ETag.$(OBJEXT) event.$(OBJEXT) \
+	EventLoop.$(OBJEXT) external_acl.$(OBJEXT) \
+	ExternalACLEntry.$(OBJEXT) FadingCounter.$(OBJEXT) \
+	fd.$(OBJEXT) fde.$(OBJEXT) filemap.$(OBJEXT) forward.$(OBJEXT) \
+	fqdncache.$(OBJEXT) ftp.$(OBJEXT) gopher.$(OBJEXT) \
+	helper.$(OBJEXT) HelperChildConfig.$(OBJEXT) $(am__objects_9) \
+	http.$(OBJEXT) HttpBody.$(OBJEXT) HttpHeader.$(OBJEXT) \
+	HttpHeaderTools.$(OBJEXT) HttpHdrCc.$(OBJEXT) \
+	HttpHdrContRange.$(OBJEXT) HttpHdrRange.$(OBJEXT) \
+	HttpHdrSc.$(OBJEXT) HttpHdrScTarget.$(OBJEXT) \
+	HttpMsg.$(OBJEXT) HttpParser.$(OBJEXT) HttpReply.$(OBJEXT) \
+	HttpRequest.$(OBJEXT) HttpRequestMethod.$(OBJEXT) \
+	HttpStatusLine.$(OBJEXT) icp_v2.$(OBJEXT) icp_v3.$(OBJEXT) \
+	$(am__objects_10) ipcache.$(OBJEXT) int.$(OBJEXT) \
+	internal.$(OBJEXT) list.$(OBJEXT) mem.$(OBJEXT) \
+	mem_node.$(OBJEXT) MemBuf.$(OBJEXT) MemObject.$(OBJEXT) \
+	mime.$(OBJEXT) mime_header.$(OBJEXT) multicast.$(OBJEXT) \
+	neighbors.$(OBJEXT) Packer.$(OBJEXT) Parsing.$(OBJEXT) \
+	pconn.$(OBJEXT) peer_digest.$(OBJEXT) \
+	peer_proxy_negotiate_auth.$(OBJEXT) peer_select.$(OBJEXT) \
+	peer_sourcehash.$(OBJEXT) peer_userhash.$(OBJEXT) \
+	ProtoPort.$(OBJEXT) redirect.$(OBJEXT) refresh.$(OBJEXT) \
+	RemovalPolicy.$(OBJEXT) Server.$(OBJEXT) $(am__objects_15) \
+	SquidMath.$(OBJEXT) stat.$(OBJEXT) StatHist.$(OBJEXT) \
+	stmem.$(OBJEXT) store.$(OBJEXT) store_client.$(OBJEXT) \
+	store_digest.$(OBJEXT) store_dir.$(OBJEXT) store_io.$(OBJEXT) \
+	store_key_md5.$(OBJEXT) store_log.$(OBJEXT) \
+	store_rebuild.$(OBJEXT) store_swapin.$(OBJEXT) \
+	store_swapmeta.$(OBJEXT) store_swapout.$(OBJEXT) \
+	StoreFileSystem.$(OBJEXT) StoreIOState.$(OBJEXT) \
+	StoreMeta.$(OBJEXT) StoreMetaMD5.$(OBJEXT) \
+	StoreMetaSTD.$(OBJEXT) StoreMetaSTDLFS.$(OBJEXT) \
+	StoreMetaUnpacker.$(OBJEXT) StoreMetaURL.$(OBJEXT) \
+	StoreMetaVary.$(OBJEXT) StoreSwapLogData.$(OBJEXT) \
+	String.$(OBJEXT) SwapDir.$(OBJEXT) tests/testEvent.$(OBJEXT) \
+	tests/testMain.$(OBJEXT) tests/stub_main_cc.$(OBJEXT) \
 	tests/stub_ipc_Forwarder.$(OBJEXT) time.$(OBJEXT) \
-	tools.$(OBJEXT) tunnel.$(OBJEXT) url.$(OBJEXT) \
-	URLScheme.$(OBJEXT) urn.$(OBJEXT) wccp2.$(OBJEXT) \
-	whois.$(OBJEXT) $(am__objects_17) wordlist.$(OBJEXT)
-nodist_tests_testEvent_OBJECTS = $(am__objects_22)
+	tools.$(OBJEXT) tunnel.$(OBJEXT) MemStore.$(OBJEXT) \
+	$(am__objects_16) url.$(OBJEXT) URLScheme.$(OBJEXT) \
+	urn.$(OBJEXT) wccp2.$(OBJEXT) whois.$(OBJEXT) \
+	$(am__objects_17) wordlist.$(OBJEXT)
+nodist_tests_testEvent_OBJECTS = $(am__objects_22) $(am__objects_21)
 tests_testEvent_OBJECTS = $(am_tests_testEvent_OBJECTS) \
 	$(nodist_tests_testEvent_OBJECTS)
 tests_testEvent_LINK = $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) \
@@ -787,14 +820,19 @@
 	DelayPool.cc DelayPool.h DelayPools.h DelaySpec.cc DelaySpec.h \
 	DelayTagged.cc DelayTagged.h DelayUser.cc DelayUser.h \
 	DelayVector.cc DelayVector.h NullDelayId.cc NullDelayId.h \
-	ClientDelayConfig.cc ClientDelayConfig.h disk.cc dlink.h \
-	dlink.cc dns_internal.cc DnsLookupDetails.h \
-	DnsLookupDetails.cc dns.cc errorpage.cc ETag.cc EventLoop.h \
-	EventLoop.cc event.cc external_acl.cc ExternalACLEntry.cc \
-	FadingCounter.cc fd.cc fde.cc forward.cc fqdncache.cc ftp.cc \
-	gopher.cc helper.cc HelperChildConfig.h HelperChildConfig.cc \
-	hier_code.h htcp.cc htcp.h http.cc HttpBody.cc HttpHeader.cc \
-	HttpHeaderTools.cc HttpHdrCc.cc HttpHdrContRange.cc \
+	ClientDelayConfig.cc ClientDelayConfig.h \
+	DiskIO/DiskIOModule.cc DiskIO/ReadRequest.cc \
+	DiskIO/ReadRequest.h DiskIO/WriteRequest.cc \
+	DiskIO/WriteRequest.h DiskIO/DiskFile.h \
+	DiskIO/DiskIOStrategy.h DiskIO/IORequestor.h \
+	DiskIO/DiskIOModule.h disk.cc dlink.h dlink.cc dns_internal.cc \
+	DnsLookupDetails.h DnsLookupDetails.cc dns.cc errorpage.cc \
+	ETag.cc EventLoop.h EventLoop.cc event.cc external_acl.cc \
+	ExternalACLEntry.cc FadingCounter.cc fd.cc fde.cc filemap.cc \
+	forward.cc fqdncache.cc ftp.cc gopher.cc helper.cc \
+	HelperChildConfig.h HelperChildConfig.cc hier_code.h htcp.cc \
+	htcp.h http.cc HttpBody.cc HttpHeader.cc HttpHeaderTools.cc \
+	HttpHdrCc.h HttpHdrCc.cc HttpHdrCc.cci HttpHdrContRange.cc \
 	HttpHdrRange.cc HttpHdrSc.cc HttpHdrScTarget.cc HttpMsg.cc \
 	HttpParser.cc HttpParser.h HttpReply.cc HttpRequest.cc \
 	HttpRequestMethod.cc HttpStatusLine.cc icp_v2.cc icp_v3.cc \
@@ -814,8 +852,8 @@
 	StoreMetaVary.cc StoreSwapLogData.cc String.cc SwapDir.cc \
 	tests/testEventLoop.cc tests/testEventLoop.h tests/testMain.cc \
 	tests/stub_main_cc.cc tests/stub_ipc_Forwarder.cc time.cc \
-	tools.cc tunnel.cc url.cc URLScheme.cc urn.cc wccp2.cc \
-	whois.cc win32.cc wordlist.cc
+	tools.cc tunnel.cc MemStore.cc unlinkd.cc url.cc URLScheme.cc \
+	urn.cc wccp2.cc whois.cc win32.cc wordlist.cc
 am_tests_testEventLoop_OBJECTS = $(am__objects_4) BodyPipe.$(OBJEXT) \
 	CacheDigest.$(OBJEXT) cache_manager.$(OBJEXT) \
 	cache_cf.$(OBJEXT) carp.$(OBJEXT) cbdata.$(OBJEXT) \
@@ -824,61 +862,65 @@
 	client_side_request.$(OBJEXT) clientStream.$(OBJEXT) \
 	ConfigOption.$(OBJEXT) ConfigParser.$(OBJEXT) \
 	CpuAffinityMap.$(OBJEXT) CpuAffinitySet.$(OBJEXT) \
-	debug.$(OBJEXT) $(am__objects_6) disk.$(OBJEXT) \
-	dlink.$(OBJEXT) $(am__objects_8) errorpage.$(OBJEXT) \
-	ETag.$(OBJEXT) EventLoop.$(OBJEXT) event.$(OBJEXT) \
-	external_acl.$(OBJEXT) ExternalACLEntry.$(OBJEXT) \
-	FadingCounter.$(OBJEXT) fd.$(OBJEXT) fde.$(OBJEXT) \
-	forward.$(OBJEXT) fqdncache.$(OBJEXT) ftp.$(OBJEXT) \
-	gopher.$(OBJEXT) helper.$(OBJEXT) HelperChildConfig.$(OBJEXT) \
-	$(am__objects_9) http.$(OBJEXT) HttpBody.$(OBJEXT) \
-	HttpHeader.$(OBJEXT) HttpHeaderTools.$(OBJEXT) \
-	HttpHdrCc.$(OBJEXT) HttpHdrContRange.$(OBJEXT) \
-	HttpHdrRange.$(OBJEXT) HttpHdrSc.$(OBJEXT) \
-	HttpHdrScTarget.$(OBJEXT) HttpMsg.$(OBJEXT) \
-	HttpParser.$(OBJEXT) HttpReply.$(OBJEXT) HttpRequest.$(OBJEXT) \
-	HttpRequestMethod.$(OBJEXT) HttpStatusLine.$(OBJEXT) \
-	icp_v2.$(OBJEXT) icp_v3.$(OBJEXT) $(am__objects_10) \
-	ipcache.$(OBJEXT) int.$(OBJEXT) internal.$(OBJEXT) \
-	list.$(OBJEXT) MemBuf.$(OBJEXT) MemObject.$(OBJEXT) \
-	mem.$(OBJEXT) mem_node.$(OBJEXT) mime.$(OBJEXT) \
-	mime_header.$(OBJEXT) multicast.$(OBJEXT) neighbors.$(OBJEXT) \
-	Packer.$(OBJEXT) Parsing.$(OBJEXT) pconn.$(OBJEXT) \
-	peer_digest.$(OBJEXT) peer_proxy_negotiate_auth.$(OBJEXT) \
-	peer_select.$(OBJEXT) peer_sourcehash.$(OBJEXT) \
-	peer_userhash.$(OBJEXT) ProtoPort.$(OBJEXT) \
-	RemovalPolicy.$(OBJEXT) redirect.$(OBJEXT) refresh.$(OBJEXT) \
-	Server.$(OBJEXT) $(am__objects_15) SquidMath.$(OBJEXT) \
-	stat.$(OBJEXT) StatHist.$(OBJEXT) stmem.$(OBJEXT) \
-	store.$(OBJEXT) store_client.$(OBJEXT) store_digest.$(OBJEXT) \
-	store_dir.$(OBJEXT) store_io.$(OBJEXT) store_key_md5.$(OBJEXT) \
-	store_log.$(OBJEXT) store_rebuild.$(OBJEXT) \
-	store_swapin.$(OBJEXT) store_swapmeta.$(OBJEXT) \
-	store_swapout.$(OBJEXT) StoreFileSystem.$(OBJEXT) \
-	StoreIOState.$(OBJEXT) StoreMeta.$(OBJEXT) \
-	StoreMetaMD5.$(OBJEXT) StoreMetaSTD.$(OBJEXT) \
-	StoreMetaSTDLFS.$(OBJEXT) StoreMetaUnpacker.$(OBJEXT) \
-	StoreMetaURL.$(OBJEXT) StoreMetaVary.$(OBJEXT) \
-	StoreSwapLogData.$(OBJEXT) String.$(OBJEXT) SwapDir.$(OBJEXT) \
+	debug.$(OBJEXT) $(am__objects_6) $(am__objects_7) \
+	disk.$(OBJEXT) dlink.$(OBJEXT) $(am__objects_8) \
+	errorpage.$(OBJEXT) ETag.$(OBJEXT) EventLoop.$(OBJEXT) \
+	event.$(OBJEXT) external_acl.$(OBJEXT) \
+	ExternalACLEntry.$(OBJEXT) FadingCounter.$(OBJEXT) \
+	fd.$(OBJEXT) fde.$(OBJEXT) filemap.$(OBJEXT) forward.$(OBJEXT) \
+	fqdncache.$(OBJEXT) ftp.$(OBJEXT) gopher.$(OBJEXT) \
+	helper.$(OBJEXT) HelperChildConfig.$(OBJEXT) $(am__objects_9) \
+	http.$(OBJEXT) HttpBody.$(OBJEXT) HttpHeader.$(OBJEXT) \
+	HttpHeaderTools.$(OBJEXT) HttpHdrCc.$(OBJEXT) \
+	HttpHdrContRange.$(OBJEXT) HttpHdrRange.$(OBJEXT) \
+	HttpHdrSc.$(OBJEXT) HttpHdrScTarget.$(OBJEXT) \
+	HttpMsg.$(OBJEXT) HttpParser.$(OBJEXT) HttpReply.$(OBJEXT) \
+	HttpRequest.$(OBJEXT) HttpRequestMethod.$(OBJEXT) \
+	HttpStatusLine.$(OBJEXT) icp_v2.$(OBJEXT) icp_v3.$(OBJEXT) \
+	$(am__objects_10) ipcache.$(OBJEXT) int.$(OBJEXT) \
+	internal.$(OBJEXT) list.$(OBJEXT) MemBuf.$(OBJEXT) \
+	MemObject.$(OBJEXT) mem.$(OBJEXT) mem_node.$(OBJEXT) \
+	mime.$(OBJEXT) mime_header.$(OBJEXT) multicast.$(OBJEXT) \
+	neighbors.$(OBJEXT) Packer.$(OBJEXT) Parsing.$(OBJEXT) \
+	pconn.$(OBJEXT) peer_digest.$(OBJEXT) \
+	peer_proxy_negotiate_auth.$(OBJEXT) peer_select.$(OBJEXT) \
+	peer_sourcehash.$(OBJEXT) peer_userhash.$(OBJEXT) \
+	ProtoPort.$(OBJEXT) RemovalPolicy.$(OBJEXT) redirect.$(OBJEXT) \
+	refresh.$(OBJEXT) Server.$(OBJEXT) $(am__objects_15) \
+	SquidMath.$(OBJEXT) stat.$(OBJEXT) StatHist.$(OBJEXT) \
+	stmem.$(OBJEXT) store.$(OBJEXT) store_client.$(OBJEXT) \
+	store_digest.$(OBJEXT) store_dir.$(OBJEXT) store_io.$(OBJEXT) \
+	store_key_md5.$(OBJEXT) store_log.$(OBJEXT) \
+	store_rebuild.$(OBJEXT) store_swapin.$(OBJEXT) \
+	store_swapmeta.$(OBJEXT) store_swapout.$(OBJEXT) \
+	StoreFileSystem.$(OBJEXT) StoreIOState.$(OBJEXT) \
+	StoreMeta.$(OBJEXT) StoreMetaMD5.$(OBJEXT) \
+	StoreMetaSTD.$(OBJEXT) StoreMetaSTDLFS.$(OBJEXT) \
+	StoreMetaUnpacker.$(OBJEXT) StoreMetaURL.$(OBJEXT) \
+	StoreMetaVary.$(OBJEXT) StoreSwapLogData.$(OBJEXT) \
+	String.$(OBJEXT) SwapDir.$(OBJEXT) \
 	tests/testEventLoop.$(OBJEXT) tests/testMain.$(OBJEXT) \
 	tests/stub_main_cc.$(OBJEXT) \
 	tests/stub_ipc_Forwarder.$(OBJEXT) time.$(OBJEXT) \
-	tools.$(OBJEXT) tunnel.$(OBJEXT) url.$(OBJEXT) \
-	URLScheme.$(OBJEXT) urn.$(OBJEXT) wccp2.$(OBJEXT) \
-	whois.$(OBJEXT) $(am__objects_17) wordlist.$(OBJEXT)
-nodist_tests_testEventLoop_OBJECTS = $(am__objects_22)
+	tools.$(OBJEXT) tunnel.$(OBJEXT) MemStore.$(OBJEXT) \
+	$(am__objects_16) url.$(OBJEXT) URLScheme.$(OBJEXT) \
+	urn.$(OBJEXT) wccp2.$(OBJEXT) whois.$(OBJEXT) \
+	$(am__objects_17) wordlist.$(OBJEXT)
+nodist_tests_testEventLoop_OBJECTS = $(am__objects_22) \
+	$(am__objects_21)
 tests_testEventLoop_OBJECTS = $(am_tests_testEventLoop_OBJECTS) \
 	$(nodist_tests_testEventLoop_OBJECTS)
 tests_testEventLoop_LINK = $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) \
 	$(LIBTOOLFLAGS) --mode=link $(CXXLD) $(AM_CXXFLAGS) \
 	$(CXXFLAGS) $(tests_testEventLoop_LDFLAGS) $(LDFLAGS) -o $@
 am_tests_testHttpParser_OBJECTS = HttpParser.$(OBJEXT) \
-	MemBuf.$(OBJEXT) mem.$(OBJEXT) \
+	MemBuf.$(OBJEXT) mem.$(OBJEXT) String.$(OBJEXT) \
+	tests/stub_cache_cf.$(OBJEXT) \
 	tests/stub_cache_manager.$(OBJEXT) tests/stub_debug.$(OBJEXT) \
 	tests/stub_event.$(OBJEXT) \
 	tests/stub_HelperChildConfig.$(OBJEXT) \
 	tests/testHttpParser.$(OBJEXT) tests/testMain.$(OBJEXT) \
-	time.$(OBJEXT)
+	time.$(OBJEXT) wordlist.$(OBJEXT)
 nodist_tests_testHttpParser_OBJECTS = $(am__objects_23)
 tests_testHttpParser_OBJECTS = $(am_tests_testHttpParser_OBJECTS) \
 	$(nodist_tests_testHttpParser_OBJECTS)
@@ -893,11 +935,12 @@
 	HttpMsg.$(OBJEXT) HttpReply.$(OBJEXT) HttpStatusLine.$(OBJEXT) \
 	mem.$(OBJEXT) MemBuf.$(OBJEXT) mime_header.$(OBJEXT) \
 	Packer.$(OBJEXT) String.$(OBJEXT) \
+	tests/stub_cache_cf.$(OBJEXT) \
 	tests/stub_cache_manager.$(OBJEXT) tests/stub_debug.$(OBJEXT) \
 	tests/stub_HelperChildConfig.$(OBJEXT) \
 	tests/stub_StatHist.$(OBJEXT) tests/stub_store.$(OBJEXT) \
 	tests/testHttpReply.$(OBJEXT) tests/testMain.$(OBJEXT) \
-	time.$(OBJEXT)
+	time.$(OBJEXT) wordlist.$(OBJEXT)
 nodist_tests_testHttpReply_OBJECTS = $(am__objects_23)
 tests_testHttpReply_OBJECTS = $(am_tests_testHttpReply_OBJECTS) \
 	$(nodist_tests_testHttpReply_OBJECTS)
@@ -909,32 +952,33 @@
 	mem.cc String.cc tests/testHttpRequest.h \
 	tests/testHttpRequest.cc tests/testHttpRequestMethod.h \
 	tests/testHttpRequestMethod.cc tests/testMain.cc \
-	tests/stub_main_cc.cc tests/stub_ipc_Forwarder.cc time.cc \
-	BodyPipe.cc cache_manager.cc cache_cf.cc debug.cc ProtoPort.cc \
-	ProtoPort.h CacheDigest.cc carp.cc cbdata.cc \
-	ChunkedCodingParser.cc client_db.cc client_side.cc \
-	client_side_reply.cc client_side_request.cc ClientInfo.h \
-	clientStream.cc ConfigOption.cc ConfigParser.cc \
-	CpuAffinityMap.cc CpuAffinityMap.h CpuAffinitySet.cc \
-	CpuAffinitySet.h CommonPool.h CompositePoolNode.h \
-	delay_pools.cc DelayId.cc DelayId.h DelayIdComposite.h \
-	DelayBucket.cc DelayBucket.h DelayConfig.cc DelayConfig.h \
-	DelayPool.cc DelayPool.h DelayPools.h DelaySpec.cc DelaySpec.h \
-	DelayTagged.cc DelayTagged.h DelayUser.cc DelayUser.h \
-	DelayVector.cc DelayVector.h NullDelayId.cc NullDelayId.h \
+	tests/stub_DiskIOModule.cc tests/stub_main_cc.cc \
+	tests/stub_ipc_Forwarder.cc time.cc BodyPipe.cc \
+	cache_manager.cc cache_cf.cc debug.cc ProtoPort.cc ProtoPort.h \
+	CacheDigest.cc carp.cc cbdata.cc ChunkedCodingParser.cc \
+	client_db.cc client_side.cc client_side_reply.cc \
+	client_side_request.cc ClientInfo.h clientStream.cc \
+	ConfigOption.cc ConfigParser.cc CpuAffinityMap.cc \
+	CpuAffinityMap.h CpuAffinitySet.cc CpuAffinitySet.h \
+	CommonPool.h CompositePoolNode.h delay_pools.cc DelayId.cc \
+	DelayId.h DelayIdComposite.h DelayBucket.cc DelayBucket.h \
+	DelayConfig.cc DelayConfig.h DelayPool.cc DelayPool.h \
+	DelayPools.h DelaySpec.cc DelaySpec.h DelayTagged.cc \
+	DelayTagged.h DelayUser.cc DelayUser.h DelayVector.cc \
+	DelayVector.h NullDelayId.cc NullDelayId.h \
 	ClientDelayConfig.cc ClientDelayConfig.h disk.cc dlink.h \
 	dlink.cc dns_internal.cc DnsLookupDetails.h \
 	DnsLookupDetails.cc dns.cc errorpage.cc ETag.cc \
 	external_acl.cc ExternalACLEntry.cc fd.cc fde.cc forward.cc \
 	fqdncache.cc ftp.cc gopher.cc helper.cc HelperChildConfig.h \
 	HelperChildConfig.cc hier_code.h htcp.cc htcp.h http.cc \
-	HttpBody.cc HttpHeader.cc HttpHeaderTools.cc HttpHdrCc.cc \
-	HttpHdrContRange.cc HttpHdrRange.cc HttpHdrSc.cc \
-	HttpHdrScTarget.cc HttpMsg.cc HttpReply.cc HttpStatusLine.cc \
-	icp_v2.cc icp_v3.cc ipc.cc ipc_win32.cc ipcache.cc int.cc \
-	internal.cc list.cc multicast.cc mem_node.cc MemBuf.cc \
-	MemObject.cc mime.cc mime_header.cc neighbors.cc Packer.cc \
-	Parsing.cc pconn.cc peer_digest.cc \
+	HttpBody.cc HttpHeader.cc HttpHeaderTools.cc HttpHdrCc.h \
+	HttpHdrCc.cc HttpHdrCc.cci HttpHdrContRange.cc HttpHdrRange.cc \
+	HttpHdrSc.cc HttpHdrScTarget.cc HttpMsg.cc HttpReply.cc \
+	HttpStatusLine.cc icp_v2.cc icp_v3.cc ipc.cc ipc_win32.cc \
+	ipcache.cc int.cc internal.cc list.cc multicast.cc mem_node.cc \
+	MemBuf.cc MemObject.cc mime.cc mime_header.cc neighbors.cc \
+	Packer.cc Parsing.cc pconn.cc peer_digest.cc \
 	peer_proxy_negotiate_auth.cc peer_select.cc peer_sourcehash.cc \
 	peer_userhash.cc redirect.cc refresh.cc RemovalPolicy.cc \
 	Server.cc snmp_core.h snmp_core.cc snmp_agent.cc SquidMath.h \
@@ -945,14 +989,14 @@
 	StoreIOState.cc StoreMeta.cc StoreMetaMD5.cc StoreMetaSTD.cc \
 	StoreMetaSTDLFS.cc StoreMetaUnpacker.cc StoreMetaURL.cc \
 	StoreMetaVary.cc StoreSwapLogData.cc event.cc tools.cc \
-	tunnel.cc SwapDir.cc url.cc URLScheme.cc urn.cc wccp2.cc \
-	whois.cc FadingCounter.cc win32.cc wordlist.cc
+	tunnel.cc SwapDir.cc MemStore.cc url.cc URLScheme.cc urn.cc \
+	wccp2.cc whois.cc FadingCounter.cc win32.cc wordlist.cc
 am_tests_testHttpRequest_OBJECTS = $(am__objects_4) \
 	HttpParser.$(OBJEXT) HttpRequest.$(OBJEXT) \
 	HttpRequestMethod.$(OBJEXT) mem.$(OBJEXT) String.$(OBJEXT) \
 	tests/testHttpRequest.$(OBJEXT) \
 	tests/testHttpRequestMethod.$(OBJEXT) tests/testMain.$(OBJEXT) \
-	tests/stub_main_cc.$(OBJEXT) \
+	tests/stub_DiskIOModule.$(OBJEXT) tests/stub_main_cc.$(OBJEXT) \
 	tests/stub_ipc_Forwarder.$(OBJEXT) time.$(OBJEXT) \
 	BodyPipe.$(OBJEXT) cache_manager.$(OBJEXT) cache_cf.$(OBJEXT) \
 	debug.$(OBJEXT) ProtoPort.$(OBJEXT) CacheDigest.$(OBJEXT) \
@@ -994,10 +1038,10 @@
 	StoreMetaSTDLFS.$(OBJEXT) StoreMetaUnpacker.$(OBJEXT) \
 	StoreMetaURL.$(OBJEXT) StoreMetaVary.$(OBJEXT) \
 	StoreSwapLogData.$(OBJEXT) event.$(OBJEXT) tools.$(OBJEXT) \
-	tunnel.$(OBJEXT) SwapDir.$(OBJEXT) url.$(OBJEXT) \
-	URLScheme.$(OBJEXT) urn.$(OBJEXT) wccp2.$(OBJEXT) \
-	whois.$(OBJEXT) FadingCounter.$(OBJEXT) $(am__objects_17) \
-	wordlist.$(OBJEXT)
+	tunnel.$(OBJEXT) SwapDir.$(OBJEXT) MemStore.$(OBJEXT) \
+	url.$(OBJEXT) URLScheme.$(OBJEXT) urn.$(OBJEXT) \
+	wccp2.$(OBJEXT) whois.$(OBJEXT) FadingCounter.$(OBJEXT) \
+	$(am__objects_17) wordlist.$(OBJEXT)
 nodist_tests_testHttpRequest_OBJECTS = $(am__objects_22)
 tests_testHttpRequest_OBJECTS = $(am_tests_testHttpRequest_OBJECTS) \
 	$(nodist_tests_testHttpRequest_OBJECTS)
@@ -1028,15 +1072,15 @@
 	tests/stub_client_side_request.cc tests/stub_http.cc \
 	mem_node.cc stmem.cc tests/stub_mime.cc HttpHeaderTools.cc \
 	HttpHeader.cc mem.cc ClientInfo.h MemBuf.cc \
-	HttpHdrContRange.cc Packer.cc HttpHdrCc.cc HttpHdrSc.cc \
-	HttpHdrScTarget.cc url.cc StatHist.cc HttpHdrRange.cc ETag.cc \
-	tests/stub_errorpage.cc tests/stub_HttpRequest.cc \
-	tests/stub_access_log.cc refresh.cc tests/stub_store_client.cc \
-	tests/stub_tools.cc tests/testStoreSupport.cc \
-	tests/testStoreSupport.h time.cc URLScheme.cc wordlist.cc \
-	DiskIO/DiskIOModule.cc DiskIO/ReadRequest.cc \
-	DiskIO/ReadRequest.h DiskIO/WriteRequest.cc \
-	DiskIO/WriteRequest.h DiskIO/DiskFile.h \
+	HttpHdrContRange.cc Packer.cc HttpHdrCc.h HttpHdrCc.cc \
+	HttpHdrCc.cci HttpHdrSc.cc HttpHdrScTarget.cc url.cc \
+	StatHist.cc HttpHdrRange.cc ETag.cc tests/stub_errorpage.cc \
+	tests/stub_HttpRequest.cc tests/stub_access_log.cc refresh.cc \
+	tests/stub_store_client.cc tests/stub_tools.cc \
+	tests/testStoreSupport.cc tests/testStoreSupport.h time.cc \
+	URLScheme.cc wordlist.cc DiskIO/DiskIOModule.cc \
+	DiskIO/ReadRequest.cc DiskIO/ReadRequest.h \
+	DiskIO/WriteRequest.cc DiskIO/WriteRequest.h DiskIO/DiskFile.h \
 	DiskIO/DiskIOStrategy.h DiskIO/IORequestor.h \
 	DiskIO/DiskIOModule.h
 am_tests_testNull_OBJECTS = tests/testNull.$(OBJEXT) \
@@ -1091,34 +1135,35 @@
 	NullDelayId.cc NullDelayId.h ClientDelayConfig.cc \
 	ClientDelayConfig.h disk.cc DiskIO/ReadRequest.cc \
 	DiskIO/WriteRequest.cc ETag.cc event.cc EventLoop.cc \
-	filemap.cc HttpHdrCc.cc HttpHdrContRange.cc HttpHdrRange.cc \
-	HttpHdrSc.cc HttpHdrScTarget.cc HttpHeaderTools.cc \
-	HttpHeader.cc HttpMsg.cc HttpRequestMethod.cc int.cc list.cc \
-	mem.cc mem_node.cc MemBuf.cc Packer.cc Parsing.cc \
-	RemovalPolicy.cc refresh.cc StatHist.cc stmem.cc store.cc \
-	store_dir.cc store_io.cc store_swapout.cc StoreIOState.cc \
-	StoreMeta.cc StoreMetaMD5.cc StoreMetaSTD.cc \
-	StoreMetaSTDLFS.cc StoreMetaUnpacker.cc StoreMetaURL.cc \
-	StoreMetaVary.cc StoreSwapLogData.cc store_key_md5.cc \
-	String.cc SwapDir.cc tests/CapturingStoreEntry.h \
-	tests/stub_access_log.cc tests/stub_acl.cc \
-	tests/stub_cache_cf.cc tests/stub_cache_manager.cc \
-	tests/stub_client_side_request.cc tests/stub_comm.cc \
-	tests/stub_debug.cc tests/stub_DiskIOModule.cc \
-	tests/stub_errorpage.cc tests/stub_fd.cc tests/stub_helper.cc \
+	filemap.cc HttpHdrCc.h HttpHdrCc.cc HttpHdrCc.cci \
+	HttpHdrContRange.cc HttpHdrRange.cc HttpHdrSc.cc \
+	HttpHdrScTarget.cc HttpHeaderTools.cc HttpHeader.cc HttpMsg.cc \
+	HttpRequestMethod.cc int.cc list.cc mem.cc mem_node.cc \
+	MemBuf.cc Packer.cc Parsing.cc RemovalPolicy.cc refresh.cc \
+	StatHist.cc stmem.cc store.cc store_dir.cc store_io.cc \
+	store_swapout.cc StoreIOState.cc StoreMeta.cc StoreMetaMD5.cc \
+	StoreMetaSTD.cc StoreMetaSTDLFS.cc StoreMetaUnpacker.cc \
+	StoreMetaURL.cc StoreMetaVary.cc StoreSwapLogData.cc \
+	store_key_md5.cc String.cc SwapDir.cc \
+	tests/CapturingStoreEntry.h tests/stub_access_log.cc \
+	tests/stub_acl.cc tests/stub_cache_cf.cc \
+	tests/stub_cache_manager.cc tests/stub_client_side_request.cc \
+	tests/stub_comm.cc tests/stub_debug.cc \
+	tests/stub_DiskIOModule.cc tests/stub_errorpage.cc \
+	tests/stub_fd.cc tests/stub_helper.cc \
 	tests/stub_HelperChildConfig.cc tests/stub_http.cc \
 	tests/stub_HttpReply.cc tests/stub_HttpRequest.cc \
-	tests/stub_MemObject.cc tests/stub_mime.cc tests/stub_Port.cc \
+	tests/stub_libcomm.cc tests/stub_MemObject.cc \
+	tests/stub_MemStore.cc tests/stub_mime.cc tests/stub_Port.cc \
 	tests/stub_store_client.cc tests/stub_store_rebuild.cc \
 	tests/stub_store_swapout.cc tests/stub_tools.cc \
-	tests/stub_TypedMsgHdr.cc tests/stub_UdsOp.cc \
-	tests/testMain.cc tests/testStore.cc tests/testStore.h \
-	tests/testStoreEntryStream.cc tests/testStoreEntryStream.h \
-	tests/testStoreController.cc tests/testStoreController.h \
-	tests/testStoreHashIndex.cc tests/testStoreHashIndex.h \
-	tests/testStoreSupport.cc tests/testStoreSupport.h \
-	tests/TestSwapDir.cc tests/TestSwapDir.h time.cc url.cc \
-	URLScheme.cc wordlist.cc
+	tests/stub_UdsOp.cc tests/testMain.cc tests/testStore.cc \
+	tests/testStore.h tests/testStoreEntryStream.cc \
+	tests/testStoreEntryStream.h tests/testStoreController.cc \
+	tests/testStoreController.h tests/testStoreHashIndex.cc \
+	tests/testStoreHashIndex.h tests/testStoreSupport.cc \
+	tests/testStoreSupport.h tests/TestSwapDir.cc \
+	tests/TestSwapDir.h time.cc url.cc URLScheme.cc wordlist.cc
 am_tests_testStore_OBJECTS = CacheDigest.$(OBJEXT) cbdata.$(OBJEXT) \
 	ConfigOption.$(OBJEXT) ConfigParser.$(OBJEXT) $(am__objects_6) \
 	disk.$(OBJEXT) DiskIO/ReadRequest.$(OBJEXT) \
@@ -1149,14 +1194,14 @@
 	tests/stub_helper.$(OBJEXT) \
 	tests/stub_HelperChildConfig.$(OBJEXT) \
 	tests/stub_http.$(OBJEXT) tests/stub_HttpReply.$(OBJEXT) \
-	tests/stub_HttpRequest.$(OBJEXT) \
-	tests/stub_MemObject.$(OBJEXT) tests/stub_mime.$(OBJEXT) \
-	tests/stub_Port.$(OBJEXT) tests/stub_store_client.$(OBJEXT) \
+	tests/stub_HttpRequest.$(OBJEXT) tests/stub_libcomm.$(OBJEXT) \
+	tests/stub_MemObject.$(OBJEXT) tests/stub_MemStore.$(OBJEXT) \
+	tests/stub_mime.$(OBJEXT) tests/stub_Port.$(OBJEXT) \
+	tests/stub_store_client.$(OBJEXT) \
 	tests/stub_store_rebuild.$(OBJEXT) \
 	tests/stub_store_swapout.$(OBJEXT) tests/stub_tools.$(OBJEXT) \
-	tests/stub_TypedMsgHdr.$(OBJEXT) tests/stub_UdsOp.$(OBJEXT) \
-	tests/testMain.$(OBJEXT) tests/testStore.$(OBJEXT) \
-	tests/testStoreEntryStream.$(OBJEXT) \
+	tests/stub_UdsOp.$(OBJEXT) tests/testMain.$(OBJEXT) \
+	tests/testStore.$(OBJEXT) tests/testStoreEntryStream.$(OBJEXT) \
 	tests/testStoreController.$(OBJEXT) \
 	tests/testStoreHashIndex.$(OBJEXT) \
 	tests/testStoreSupport.$(OBJEXT) tests/TestSwapDir.$(OBJEXT) \
@@ -1169,10 +1214,12 @@
 tests_testStore_LINK = $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) \
 	$(LIBTOOLFLAGS) --mode=link $(CXXLD) $(AM_CXXFLAGS) \
 	$(CXXFLAGS) $(tests_testStore_LDFLAGS) $(LDFLAGS) -o $@
-am_tests_testString_OBJECTS = mem.$(OBJEXT) String.$(OBJEXT) \
-	tests/testMain.$(OBJEXT) tests/testString.$(OBJEXT) \
+am_tests_testString_OBJECTS = mem.$(OBJEXT) MemBuf.$(OBJEXT) \
+	String.$(OBJEXT) tests/testMain.$(OBJEXT) \
+	tests/testString.$(OBJEXT) tests/stub_cache_cf.$(OBJEXT) \
 	tests/stub_cache_manager.$(OBJEXT) tests/stub_debug.$(OBJEXT) \
-	tests/stub_HelperChildConfig.$(OBJEXT) time.$(OBJEXT)
+	tests/stub_HelperChildConfig.$(OBJEXT) time.$(OBJEXT) \
+	wordlist.$(OBJEXT)
 nodist_tests_testString_OBJECTS = $(am__objects_23)
 tests_testString_OBJECTS = $(am_tests_testString_OBJECTS) \
 	$(nodist_tests_testString_OBJECTS)
@@ -1198,30 +1245,31 @@
 	ExternalACLEntry.cc fd.cc fde.cc filemap.cc forward.cc \
 	fqdncache.cc ftp.cc gopher.cc helper.cc HelperChildConfig.h \
 	HelperChildConfig.cc hier_code.h htcp.cc htcp.h http.cc \
-	HttpBody.cc HttpHdrCc.cc HttpHdrContRange.cc HttpHdrRange.cc \
-	HttpHdrSc.cc HttpHdrScTarget.cc HttpHeader.cc \
-	HttpHeaderTools.cc HttpMsg.cc HttpParser.cc HttpParser.h \
-	HttpReply.cc HttpRequest.cc HttpRequestMethod.cc \
-	HttpStatusLine.cc icp_v2.cc icp_v3.cc ipc.cc ipc_win32.cc \
-	ipcache.cc int.cc internal.cc list.cc multicast.cc mem.cc \
-	mem_node.cc MemBuf.cc MemObject.cc mime.cc mime_header.cc \
-	neighbors.cc Packer.cc Parsing.cc pconn.cc peer_digest.cc \
-	peer_proxy_negotiate_auth.cc peer_select.cc peer_sourcehash.cc \
-	peer_userhash.cc ProtoPort.cc ProtoPort.h redirect.cc \
-	refresh.cc RemovalPolicy.cc Server.cc snmp_core.h snmp_core.cc \
-	snmp_agent.cc SquidMath.h SquidMath.cc stat.cc StatHist.cc \
-	stmem.cc store.cc store_client.cc store_digest.cc store_dir.cc \
-	store_io.cc store_key_md5.cc store_log.cc store_rebuild.cc \
-	store_swapin.cc store_swapmeta.cc store_swapout.cc \
-	StoreFileSystem.cc StoreIOState.cc StoreMeta.cc \
-	StoreMetaMD5.cc StoreMetaSTD.cc StoreMetaSTDLFS.cc \
-	StoreMetaUnpacker.cc StoreMetaURL.cc StoreMetaVary.cc \
-	StoreSwapLogData.cc String.cc SwapDir.cc tests/stub_debug.cc \
-	tests/stub_DiskIOModule.cc tests/stub_main_cc.cc \
-	tests/stub_ipc_Forwarder.cc tests/testURL.cc tests/testURL.h \
-	tests/testURLScheme.cc tests/testURLScheme.h tests/testMain.cc \
-	time.cc tools.cc tunnel.cc url.cc URLScheme.cc urn.cc wccp2.cc \
-	whois.cc FadingCounter.cc win32.cc wordlist.cc
+	HttpBody.cc HttpHdrCc.h HttpHdrCc.cc HttpHdrCc.cci \
+	HttpHdrContRange.cc HttpHdrRange.cc HttpHdrSc.cc \
+	HttpHdrScTarget.cc HttpHeader.cc HttpHeaderTools.cc HttpMsg.cc \
+	HttpParser.cc HttpParser.h HttpReply.cc HttpRequest.cc \
+	HttpRequestMethod.cc HttpStatusLine.cc icp_v2.cc icp_v3.cc \
+	ipc.cc ipc_win32.cc ipcache.cc int.cc internal.cc list.cc \
+	multicast.cc mem.cc mem_node.cc MemBuf.cc MemObject.cc mime.cc \
+	mime_header.cc neighbors.cc Packer.cc Parsing.cc pconn.cc \
+	peer_digest.cc peer_proxy_negotiate_auth.cc peer_select.cc \
+	peer_sourcehash.cc peer_userhash.cc ProtoPort.cc ProtoPort.h \
+	redirect.cc refresh.cc RemovalPolicy.cc Server.cc snmp_core.h \
+	snmp_core.cc snmp_agent.cc SquidMath.h SquidMath.cc stat.cc \
+	StatHist.cc stmem.cc store.cc store_client.cc store_digest.cc \
+	store_dir.cc store_io.cc store_key_md5.cc store_log.cc \
+	store_rebuild.cc store_swapin.cc store_swapmeta.cc \
+	store_swapout.cc StoreFileSystem.cc StoreIOState.cc \
+	StoreMeta.cc StoreMetaMD5.cc StoreMetaSTD.cc \
+	StoreMetaSTDLFS.cc StoreMetaUnpacker.cc StoreMetaURL.cc \
+	StoreMetaVary.cc StoreSwapLogData.cc String.cc SwapDir.cc \
+	MemStore.cc tests/stub_debug.cc tests/stub_DiskIOModule.cc \
+	tests/stub_main_cc.cc tests/stub_ipc_Forwarder.cc \
+	tests/testURL.cc tests/testURL.h tests/testURLScheme.cc \
+	tests/testURLScheme.h tests/testMain.cc time.cc tools.cc \
+	tunnel.cc url.cc URLScheme.cc urn.cc wccp2.cc whois.cc \
+	FadingCounter.cc win32.cc wordlist.cc
 am_tests_testURL_OBJECTS = $(am__objects_4) BodyPipe.$(OBJEXT) \
 	cache_cf.$(OBJEXT) cache_manager.$(OBJEXT) \
 	CacheDigest.$(OBJEXT) carp.$(OBJEXT) cbdata.$(OBJEXT) \
@@ -1265,8 +1313,9 @@
 	StoreMetaSTD.$(OBJEXT) StoreMetaSTDLFS.$(OBJEXT) \
 	StoreMetaUnpacker.$(OBJEXT) StoreMetaURL.$(OBJEXT) \
 	StoreMetaVary.$(OBJEXT) StoreSwapLogData.$(OBJEXT) \
-	String.$(OBJEXT) SwapDir.$(OBJEXT) tests/stub_debug.$(OBJEXT) \
-	tests/stub_DiskIOModule.$(OBJEXT) tests/stub_main_cc.$(OBJEXT) \
+	String.$(OBJEXT) SwapDir.$(OBJEXT) MemStore.$(OBJEXT) \
+	tests/stub_debug.$(OBJEXT) tests/stub_DiskIOModule.$(OBJEXT) \
+	tests/stub_main_cc.$(OBJEXT) \
 	tests/stub_ipc_Forwarder.$(OBJEXT) tests/testURL.$(OBJEXT) \
 	tests/testURLScheme.$(OBJEXT) tests/testMain.$(OBJEXT) \
 	time.$(OBJEXT) tools.$(OBJEXT) tunnel.$(OBJEXT) url.$(OBJEXT) \
@@ -1282,40 +1331,39 @@
 am__tests_testUfs_SOURCES_DIST = tests/testUfs.cc tests/testMain.cc \
 	tests/testUfs.h tests/stub_cache_manager.cc \
 	tests/stub_client_db.cc tests/stub_HelperChildConfig.cc \
-	tests/stub_icp.cc tests/stub_ipc.cc tests/stub_pconn.cc \
-	tests/stub_Port.cc tests/stub_TypedMsgHdr.cc \
-	tests/stub_UdsOp.cc tests/stub_internal.cc \
-	tests/stub_store_rebuild.cc fd.cc disk.cc filemap.cc \
-	HttpBody.cc HttpReply.cc HttpStatusLine.cc int.cc list.cc \
-	MemObject.cc StoreSwapLogData.cc StoreIOState.cc StoreMeta.cc \
-	StoreMetaMD5.cc StoreMetaSTD.cc StoreMetaSTDLFS.cc \
-	StoreMetaUnpacker.cc StoreMetaURL.cc StoreMetaVary.cc \
-	StoreFileSystem.cc store_io.cc store_swapout.cc \
-	store_swapmeta.cc unlinkd.cc win32.cc event.cc CommonPool.h \
-	CompositePoolNode.h delay_pools.cc DelayId.cc DelayId.h \
-	DelayIdComposite.h DelayBucket.cc DelayBucket.h DelayConfig.cc \
-	DelayConfig.h DelayPool.cc DelayPool.h DelayPools.h \
-	DelaySpec.cc DelaySpec.h DelayTagged.cc DelayTagged.h \
-	DelayUser.cc DelayUser.h DelayVector.cc DelayVector.h \
-	NullDelayId.cc NullDelayId.h ClientDelayConfig.cc \
-	ClientDelayConfig.h CacheDigest.cc ConfigParser.cc \
-	EventLoop.cc HttpMsg.cc RemovalPolicy.cc store_dir.cc store.cc \
-	HttpRequestMethod.cc store_key_md5.cc Parsing.cc \
-	ConfigOption.cc SwapDir.cc tests/stub_acl.cc \
+	tests/stub_icp.cc tests/stub_ipc.cc tests/stub_MemStore.cc \
+	tests/stub_pconn.cc tests/stub_Port.cc tests/stub_UdsOp.cc \
+	tests/stub_internal.cc tests/stub_store_rebuild.cc fd.cc \
+	disk.cc filemap.cc HttpBody.cc HttpReply.cc HttpStatusLine.cc \
+	int.cc list.cc MemObject.cc StoreSwapLogData.cc \
+	StoreIOState.cc StoreMeta.cc StoreMetaMD5.cc StoreMetaSTD.cc \
+	StoreMetaSTDLFS.cc StoreMetaUnpacker.cc StoreMetaURL.cc \
+	StoreMetaVary.cc StoreFileSystem.cc store_io.cc \
+	store_swapout.cc store_swapmeta.cc unlinkd.cc win32.cc \
+	event.cc CommonPool.h CompositePoolNode.h delay_pools.cc \
+	DelayId.cc DelayId.h DelayIdComposite.h DelayBucket.cc \
+	DelayBucket.h DelayConfig.cc DelayConfig.h DelayPool.cc \
+	DelayPool.h DelayPools.h DelaySpec.cc DelaySpec.h \
+	DelayTagged.cc DelayTagged.h DelayUser.cc DelayUser.h \
+	DelayVector.cc DelayVector.h NullDelayId.cc NullDelayId.h \
+	ClientDelayConfig.cc ClientDelayConfig.h CacheDigest.cc \
+	ConfigParser.cc EventLoop.cc HttpMsg.cc RemovalPolicy.cc \
+	store_dir.cc store.cc HttpRequestMethod.cc store_key_md5.cc \
+	Parsing.cc ConfigOption.cc SwapDir.cc tests/stub_acl.cc \
 	tests/stub_cache_cf.cc tests/stub_helper.cc cbdata.cc \
 	String.cc tests/stub_debug.cc \
 	tests/stub_client_side_request.cc tests/stub_http.cc \
 	mem_node.cc stmem.cc tests/stub_mime.cc HttpHeaderTools.cc \
 	HttpHeader.cc mem.cc ClientInfo.h MemBuf.cc \
-	HttpHdrContRange.cc Packer.cc HttpHdrCc.cc HttpHdrSc.cc \
-	HttpHdrScTarget.cc url.cc StatHist.cc HttpHdrRange.cc ETag.cc \
-	tests/stub_errorpage.cc tests/stub_HttpRequest.cc \
-	tests/stub_access_log.cc refresh.cc tests/stub_store_client.cc \
-	tests/stub_tools.cc tests/testStoreSupport.cc \
-	tests/testStoreSupport.h time.cc URLScheme.cc wordlist.cc \
-	DiskIO/DiskIOModule.cc DiskIO/ReadRequest.cc \
-	DiskIO/ReadRequest.h DiskIO/WriteRequest.cc \
-	DiskIO/WriteRequest.h DiskIO/DiskFile.h \
+	HttpHdrContRange.cc Packer.cc HttpHdrCc.h HttpHdrCc.cc \
+	HttpHdrCc.cci HttpHdrSc.cc HttpHdrScTarget.cc url.cc \
+	StatHist.cc HttpHdrRange.cc ETag.cc tests/stub_errorpage.cc \
+	tests/stub_HttpRequest.cc tests/stub_access_log.cc refresh.cc \
+	tests/stub_store_client.cc tests/stub_tools.cc \
+	tests/testStoreSupport.cc tests/testStoreSupport.h time.cc \
+	URLScheme.cc wordlist.cc DiskIO/DiskIOModule.cc \
+	DiskIO/ReadRequest.cc DiskIO/ReadRequest.h \
+	DiskIO/WriteRequest.cc DiskIO/WriteRequest.h DiskIO/DiskFile.h \
 	DiskIO/DiskIOStrategy.h DiskIO/IORequestor.h \
 	DiskIO/DiskIOModule.h
 am_tests_testUfs_OBJECTS = tests/testUfs.$(OBJEXT) \
@@ -1323,8 +1371,8 @@
 	tests/stub_client_db.$(OBJEXT) \
 	tests/stub_HelperChildConfig.$(OBJEXT) \
 	tests/stub_icp.$(OBJEXT) tests/stub_ipc.$(OBJEXT) \
-	tests/stub_pconn.$(OBJEXT) tests/stub_Port.$(OBJEXT) \
-	tests/stub_TypedMsgHdr.$(OBJEXT) tests/stub_UdsOp.$(OBJEXT) \
+	tests/stub_MemStore.$(OBJEXT) tests/stub_pconn.$(OBJEXT) \
+	tests/stub_Port.$(OBJEXT) tests/stub_UdsOp.$(OBJEXT) \
 	tests/stub_internal.$(OBJEXT) \
 	tests/stub_store_rebuild.$(OBJEXT) fd.$(OBJEXT) disk.$(OBJEXT) \
 	filemap.$(OBJEXT) HttpBody.$(OBJEXT) HttpReply.$(OBJEXT) \
@@ -1379,23 +1427,28 @@
 	DelayPool.cc DelayPool.h DelayPools.h DelaySpec.cc DelaySpec.h \
 	DelayTagged.cc DelayTagged.h DelayUser.cc DelayUser.h \
 	DelayVector.cc DelayVector.h NullDelayId.cc NullDelayId.h \
-	ClientDelayConfig.cc ClientDelayConfig.h disk.cc dlink.h \
-	dlink.cc dns_internal.cc DnsLookupDetails.h \
-	DnsLookupDetails.cc dns.cc errorpage.cc ETag.cc event.cc \
-	external_acl.cc ExternalACLEntry.cc FadingCounter.cc fd.cc \
-	fde.cc forward.cc fqdncache.cc ftp.cc gopher.cc helper.cc \
-	HelperChildConfig.h HelperChildConfig.cc hier_code.h htcp.cc \
-	htcp.h http.cc HttpBody.cc HttpHdrCc.cc HttpHdrContRange.cc \
-	HttpHdrRange.cc HttpHdrSc.cc HttpHdrScTarget.cc HttpHeader.cc \
-	HttpHeaderTools.cc HttpMsg.cc HttpParser.cc HttpParser.h \
-	HttpReply.cc HttpRequest.cc HttpRequestMethod.cc \
-	HttpStatusLine.cc icp_v2.cc icp_v3.cc int.cc internal.cc \
-	ipc.cc ipc_win32.cc ipcache.cc list.cc MemBuf.cc MemObject.cc \
-	mem.cc mem_node.cc mime.cc mime_header.cc multicast.cc \
-	neighbors.cc Packer.cc Parsing.cc peer_digest.cc \
-	peer_proxy_negotiate_auth.cc peer_select.cc peer_sourcehash.cc \
-	peer_userhash.cc pconn.cc redirect.cc refresh.cc \
-	RemovalPolicy.cc Server.cc snmp_core.h snmp_core.cc \
+	ClientDelayConfig.cc ClientDelayConfig.h \
+	DiskIO/DiskIOModule.cc DiskIO/ReadRequest.cc \
+	DiskIO/ReadRequest.h DiskIO/WriteRequest.cc \
+	DiskIO/WriteRequest.h DiskIO/DiskFile.h \
+	DiskIO/DiskIOStrategy.h DiskIO/IORequestor.h \
+	DiskIO/DiskIOModule.h disk.cc dlink.h dlink.cc dns_internal.cc \
+	DnsLookupDetails.h DnsLookupDetails.cc dns.cc errorpage.cc \
+	ETag.cc event.cc external_acl.cc ExternalACLEntry.cc \
+	FadingCounter.cc fd.cc fde.cc filemap.cc forward.cc \
+	fqdncache.cc ftp.cc gopher.cc helper.cc HelperChildConfig.h \
+	HelperChildConfig.cc hier_code.h htcp.cc htcp.h http.cc \
+	HttpBody.cc HttpHdrCc.h HttpHdrCc.cc HttpHdrCc.cci \
+	HttpHdrContRange.cc HttpHdrRange.cc HttpHdrSc.cc \
+	HttpHdrScTarget.cc HttpHeader.cc HttpHeaderTools.cc HttpMsg.cc \
+	HttpParser.cc HttpParser.h HttpReply.cc HttpRequest.cc \
+	HttpRequestMethod.cc HttpStatusLine.cc icp_v2.cc icp_v3.cc \
+	int.cc internal.cc ipc.cc ipc_win32.cc ipcache.cc list.cc \
+	MemBuf.cc MemObject.cc mem.cc mem_node.cc mime.cc \
+	mime_header.cc multicast.cc neighbors.cc Packer.cc Parsing.cc \
+	peer_digest.cc peer_proxy_negotiate_auth.cc peer_select.cc \
+	peer_sourcehash.cc peer_userhash.cc pconn.cc redirect.cc \
+	refresh.cc RemovalPolicy.cc Server.cc snmp_core.h snmp_core.cc \
 	snmp_agent.cc SquidMath.h SquidMath.cc stat.cc StatHist.cc \
 	stmem.cc store.cc store_client.cc store_digest.cc store_dir.cc \
 	store_key_md5.cc store_io.cc store_log.cc store_rebuild.cc \
@@ -1405,8 +1458,9 @@
 	StoreMetaUnpacker.cc StoreMetaURL.cc StoreMetaVary.cc \
 	StoreSwapLogData.cc String.cc SwapDir.cc \
 	tests/test_http_range.cc tests/stub_ipc_Forwarder.cc \
-	tests/stub_main_cc.cc time.cc tools.cc tunnel.cc url.cc \
-	URLScheme.cc urn.cc wccp2.cc whois.cc win32.cc wordlist.cc
+	tests/stub_main_cc.cc tests/stub_MemStore.cc time.cc tools.cc \
+	tunnel.cc unlinkd.cc url.cc URLScheme.cc urn.cc wccp2.cc \
+	whois.cc win32.cc wordlist.cc
 am_tests_test_http_range_OBJECTS = $(am__objects_4) BodyPipe.$(OBJEXT) \
 	cache_cf.$(OBJEXT) ProtoPort.$(OBJEXT) cache_manager.$(OBJEXT) \
 	CacheDigest.$(OBJEXT) carp.$(OBJEXT) cbdata.$(OBJEXT) \
@@ -1415,14 +1469,15 @@
 	client_side_request.$(OBJEXT) clientStream.$(OBJEXT) \
 	ConfigOption.$(OBJEXT) ConfigParser.$(OBJEXT) \
 	CpuAffinityMap.$(OBJEXT) CpuAffinitySet.$(OBJEXT) \
-	debug.$(OBJEXT) $(am__objects_6) disk.$(OBJEXT) \
-	dlink.$(OBJEXT) $(am__objects_8) errorpage.$(OBJEXT) \
-	ETag.$(OBJEXT) event.$(OBJEXT) external_acl.$(OBJEXT) \
-	ExternalACLEntry.$(OBJEXT) FadingCounter.$(OBJEXT) \
-	fd.$(OBJEXT) fde.$(OBJEXT) forward.$(OBJEXT) \
-	fqdncache.$(OBJEXT) ftp.$(OBJEXT) gopher.$(OBJEXT) \
-	helper.$(OBJEXT) HelperChildConfig.$(OBJEXT) $(am__objects_9) \
-	http.$(OBJEXT) HttpBody.$(OBJEXT) HttpHdrCc.$(OBJEXT) \
+	debug.$(OBJEXT) $(am__objects_6) $(am__objects_7) \
+	disk.$(OBJEXT) dlink.$(OBJEXT) $(am__objects_8) \
+	errorpage.$(OBJEXT) ETag.$(OBJEXT) event.$(OBJEXT) \
+	external_acl.$(OBJEXT) ExternalACLEntry.$(OBJEXT) \
+	FadingCounter.$(OBJEXT) fd.$(OBJEXT) fde.$(OBJEXT) \
+	filemap.$(OBJEXT) forward.$(OBJEXT) fqdncache.$(OBJEXT) \
+	ftp.$(OBJEXT) gopher.$(OBJEXT) helper.$(OBJEXT) \
+	HelperChildConfig.$(OBJEXT) $(am__objects_9) http.$(OBJEXT) \
+	HttpBody.$(OBJEXT) HttpHdrCc.$(OBJEXT) \
 	HttpHdrContRange.$(OBJEXT) HttpHdrRange.$(OBJEXT) \
 	HttpHdrSc.$(OBJEXT) HttpHdrScTarget.$(OBJEXT) \
 	HttpHeader.$(OBJEXT) HttpHeaderTools.$(OBJEXT) \
@@ -1452,11 +1507,13 @@
 	StoreSwapLogData.$(OBJEXT) String.$(OBJEXT) SwapDir.$(OBJEXT) \
 	tests/test_http_range.$(OBJEXT) \
 	tests/stub_ipc_Forwarder.$(OBJEXT) \
-	tests/stub_main_cc.$(OBJEXT) time.$(OBJEXT) tools.$(OBJEXT) \
-	tunnel.$(OBJEXT) url.$(OBJEXT) URLScheme.$(OBJEXT) \
+	tests/stub_main_cc.$(OBJEXT) tests/stub_MemStore.$(OBJEXT) \
+	time.$(OBJEXT) tools.$(OBJEXT) tunnel.$(OBJEXT) \
+	$(am__objects_16) url.$(OBJEXT) URLScheme.$(OBJEXT) \
 	urn.$(OBJEXT) wccp2.$(OBJEXT) whois.$(OBJEXT) \
 	$(am__objects_17) wordlist.$(OBJEXT)
-nodist_tests_test_http_range_OBJECTS = $(am__objects_22)
+nodist_tests_test_http_range_OBJECTS = $(am__objects_22) \
+	$(am__objects_21)
 tests_test_http_range_OBJECTS = $(am_tests_test_http_range_OBJECTS) \
 	$(nodist_tests_test_http_range_OBJECTS)
 tests_test_http_range_LINK = $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) \
@@ -1510,6 +1567,7 @@
 	$(LDFLAGS) -o $@
 SOURCES = $(libAIO_a_SOURCES) $(libBlocking_a_SOURCES) \
 	$(libDiskDaemon_a_SOURCES) $(libDiskThreads_a_SOURCES) \
+	$(libIpcIo_a_SOURCES) $(libMmapped_a_SOURCES) \
 	$(libsquid_la_SOURCES) $(DiskIO_DiskDaemon_diskd_SOURCES) \
 	$(nodist_DiskIO_DiskDaemon_diskd_SOURCES) $(cf_gen_SOURCES) \
 	$(dnsserver_SOURCES) $(recv_announce_SOURCES) $(squid_SOURCES) \
@@ -1541,7 +1599,8 @@
 	$(nodist_ufsdump_SOURCES) $(unlinkd_SOURCES)
 DIST_SOURCES = $(am__libAIO_a_SOURCES_DIST) $(libBlocking_a_SOURCES) \
 	$(libDiskDaemon_a_SOURCES) \
-	$(am__libDiskThreads_a_SOURCES_DIST) $(libsquid_la_SOURCES) \
+	$(am__libDiskThreads_a_SOURCES_DIST) $(libIpcIo_a_SOURCES) \
+	$(libMmapped_a_SOURCES) $(libsquid_la_SOURCES) \
 	$(DiskIO_DiskDaemon_diskd_SOURCES) $(cf_gen_SOURCES) \
 	$(dnsserver_SOURCES) $(recv_announce_SOURCES) \
 	$(am__squid_SOURCES_DIST) $(am__EXTRA_squid_SOURCES_DIST) \
@@ -1661,7 +1720,7 @@
 DEFAULT_HOSTS = @DEFAULT_HOSTS@
 DEFAULT_LOG_DIR = @DEFAULT_LOG_DIR@
 DEFAULT_PID_FILE = @DEFAULT_PID_FILE@
-DEFAULT_SWAP_DIR = $(localstatedir)/cache
+DEFAULT_SWAP_DIR = @DEFAULT_SWAP_DIR@
 
 # Make location configure settings available to the code
 DEFS = @DEFS@ -DDEFAULT_CONFIG_FILE=\"$(DEFAULT_CONFIG_FILE)\" \
@@ -1958,7 +2017,9 @@
 @USE_AIO_WIN32_TRUE@AIO_WIN32_SOURCES = $(AIO_WIN32_ALL_SOURCES)
 @USE_AIOPS_WIN32_FALSE@AIOPS_SOURCE = DiskIO/DiskThreads/aiops.cc
 @USE_AIOPS_WIN32_TRUE@AIOPS_SOURCE = DiskIO/DiskThreads/aiops_win32.cc
-EXTRA_LIBRARIES = libAIO.a libBlocking.a libDiskDaemon.a libDiskThreads.a
+EXTRA_LIBRARIES = libAIO.a libBlocking.a libDiskDaemon.a libDiskThreads.a \
+	libMmapped.a libIpcIo.a
+
 noinst_LIBRARIES = $(DISK_LIBS)
 noinst_LTLIBRARIES = libsquid.la
 cf_gen_SOURCES = cf_gen.cc
@@ -2017,17 +2078,17 @@
 	HelperChildConfig.h HelperChildConfig.cc hier_code.h \
 	HierarchyLogEntry.h $(HTCPSOURCE) http.cc http.h \
 	HttpStatusCode.h HttpStatusLine.cc HttpStatusLine.h \
-	HttpHdrCc.cc HttpHdrRange.cc HttpHdrSc.cc HttpHdrSc.h \
-	HttpHdrScTarget.cc HttpHdrScTarget.h HttpHdrContRange.cc \
-	HttpHdrContRange.h HttpHeader.cc HttpHeader.h HttpHeaderMask.h \
-	HttpHeaderRange.h HttpHeaderTools.cc HttpBody.cc \
-	HttpControlMsg.h HttpMsg.cc HttpMsg.h HttpParser.cc \
-	HttpParser.h HttpReply.cc HttpReply.h HttpRequest.cc \
-	HttpRequest.h HttpRequestMethod.cc HttpRequestMethod.h \
-	HttpVersion.h ICP.h icp_opcode.h icp_v2.cc icp_v3.cc int.cc \
-	internal.cc $(IPC_SOURCE) ipcache.cc ipcache.h \
-	$(LEAKFINDERSOURCE) list.cc lookup_t.h main.cc mem.cc \
-	mem_node.cc mem_node.h Mem.h MemBuf.cc MemObject.cc \
+	HttpHdrCc.h HttpHdrCc.cc HttpHdrCc.cci HttpHdrRange.cc \
+	HttpHdrSc.cc HttpHdrSc.h HttpHdrScTarget.cc HttpHdrScTarget.h \
+	HttpHdrContRange.cc HttpHdrContRange.h HttpHeader.cc \
+	HttpHeader.h HttpHeaderMask.h HttpHeaderRange.h \
+	HttpHeaderTools.cc HttpBody.cc HttpControlMsg.h HttpMsg.cc \
+	HttpMsg.h HttpParser.cc HttpParser.h HttpReply.cc HttpReply.h \
+	HttpRequest.cc HttpRequest.h HttpRequestMethod.cc \
+	HttpRequestMethod.h HttpVersion.h ICP.h icp_opcode.h icp_v2.cc \
+	icp_v3.cc int.cc internal.cc $(IPC_SOURCE) ipcache.cc \
+	ipcache.h $(LEAKFINDERSOURCE) list.cc lookup_t.h main.cc \
+	mem.cc mem_node.cc mem_node.h Mem.h MemBuf.cc MemObject.cc \
 	MemObject.h mime.cc mime_header.cc multicast.cc neighbors.cc \
 	Packer.cc Packer.h Parsing.cc Parsing.h $(XPROF_STATS_SOURCE) \
 	pconn.cc pconn.h PeerDigest.h peer_digest.cc \
@@ -2047,11 +2108,11 @@
 	StoreMetaUnpacker.cc StoreMetaUnpacker.h StoreMetaURL.cc \
 	StoreMetaURL.h StoreMetaVary.cc StoreMetaVary.h StoreSearch.h \
 	StoreSwapLogData.cc StoreSwapLogData.h Server.cc Server.h \
-	structs.h swap_log_op.h SwapDir.cc SwapDir.h time.cc \
-	TimeOrTag.h tools.cc tunnel.cc typedefs.h $(UNLINKDSOURCE) \
-	url.cc URL.h URLScheme.cc URLScheme.h urn.cc wccp.cc wccp2.cc \
-	whois.cc wordlist.cc wordlist.h $(WIN32_SOURCE) \
-	$(WINSVC_SOURCE) $(am__append_8)
+	structs.h swap_log_op.h SwapDir.cc SwapDir.h MemStore.cc \
+	MemStore.h time.cc TimeOrTag.h tools.cc tunnel.cc typedefs.h \
+	$(UNLINKDSOURCE) url.cc URL.h URLScheme.cc URLScheme.h urn.cc \
+	wccp.cc wccp2.cc whois.cc wordlist.cc wordlist.h \
+	$(WIN32_SOURCE) $(WINSVC_SOURCE) $(am__append_8)
 EXTRA_squid_SOURCES = \
 	$(AIO_WIN32_ALL_SOURCES) \
 	$(all_AUTHMODULES) \
@@ -2103,12 +2164,12 @@
 	$(BUILT_SOURCES)
 
 squid_LDADD = $(AUTH_ACL_LIBS) ident/libident.la acl/libacls.la \
-	eui/libeui.la acl/libstate.la $(AUTH_LIBS) acl/libapi.la \
-	base/libbase.la libsquid.la ip/libip.la fs/libfs.la \
-	ipc/libipc.la mgr/libmgr.la anyp/libanyp.la comm/libcomm.la \
-	eui/libeui.la icmp/libicmp.la icmp/libicmp-core.la \
-	log/liblog.la format/libformat.la $(XTRA_OBJS) \
-	$(DISK_LINKOBJS) $(REPL_OBJS) $(DISK_LIBS) $(DISK_OS_LIBS) \
+	eui/libeui.la acl/libstate.la $(AUTH_LIBS) $(DISK_LIBS) \
+	acl/libapi.la base/libbase.la libsquid.la ip/libip.la \
+	fs/libfs.la ipc/libipc.la mgr/libmgr.la anyp/libanyp.la \
+	comm/libcomm.la eui/libeui.la icmp/libicmp.la \
+	icmp/libicmp-core.la log/liblog.la format/libformat.la \
+	$(XTRA_OBJS) $(DISK_LINKOBJS) $(REPL_OBJS) $(DISK_OS_LIBS) \
 	$(CRYPTLIB) $(REGEXLIB) $(ADAPTATION_LIBS) $(ESI_LIBS) \
 	$(SSL_LIBS) $(SNMP_LIBS) \
 	$(top_builddir)/lib/libmisccontainers.la \
@@ -2275,6 +2336,22 @@
 		DiskIO/Blocking/BlockingDiskIOModule.cc \
 		DiskIO/Blocking/BlockingDiskIOModule.h 
 
+libMmapped_a_SOURCES = \
+		DiskIO/Mmapped/MmappedFile.cc \
+		DiskIO/Mmapped/MmappedFile.h \
+		DiskIO/Mmapped/MmappedIOStrategy.cc \
+		DiskIO/Mmapped/MmappedIOStrategy.h \
+		DiskIO/Mmapped/MmappedDiskIOModule.cc \
+		DiskIO/Mmapped/MmappedDiskIOModule.h 
+
+libIpcIo_a_SOURCES = \
+		DiskIO/IpcIo/IpcIoFile.cc \
+		DiskIO/IpcIo/IpcIoFile.h \
+		DiskIO/IpcIo/IpcIoIOStrategy.cc \
+		DiskIO/IpcIo/IpcIoIOStrategy.h \
+		DiskIO/IpcIo/IpcIoDiskIOModule.cc \
+		DiskIO/IpcIo/IpcIoDiskIOModule.h 
+
 libDiskDaemon_a_SOURCES = \
 		DiskIO/DiskDaemon/DiskdFile.cc \
 		DiskIO/DiskDaemon/DiskdFile.h \
@@ -2367,7 +2444,9 @@
 	cbdata.h \
 	ETag.cc \
 	HttpBody.cc \
+	HttpHdrCc.h \
 	HttpHdrCc.cc \
+	HttpHdrCc.cci \
 	HttpHdrContRange.cc \
 	HttpHdrContRange.h \
 	HttpHdrRange.cc \
@@ -2396,6 +2475,7 @@
 	SquidString.h \
 	SquidTime.h \
 	String.cc \
+	tests/stub_cache_cf.cc \
 	tests/stub_cache_manager.cc \
 	tests/stub_debug.cc \
 	tests/stub_HelperChildConfig.cc \
@@ -2404,7 +2484,8 @@
 	tests/testHttpReply.cc \
 	tests/testHttpReply.h \
 	tests/testMain.cc \
-	time.cc
+	time.cc \
+	wordlist.cc
 
 nodist_tests_testHttpReply_SOURCES = \
 	$(TESTSOURCES)
@@ -2441,7 +2522,9 @@
 	HttpHeaderTools.cc \
 	HttpHdrContRange.cc \
 	HttpHdrRange.cc \
+	HttpHdrCc.h \
 	HttpHdrCc.cc \
+	HttpHdrCc.cci \
 	HttpHdrSc.cc \
 	HttpHdrScTarget.cc \
 	HttpMsg.cc \
@@ -2479,10 +2562,12 @@
 	tests/stub_fd.cc \
 	tests/stub_HttpRequest.cc \
 	tests/stub_MemObject.cc \
+	tests/stub_MemStore.cc \
 	tests/stub_mime.cc \
 	tests/stub_store.cc \
 	tests/stub_store_rebuild.cc \
 	tests/stub_store_swapout.cc \
+	tests/stub_tools.cc \
 	tests/stub_cache_manager.cc \
 	tests/testACLMaxUserIP.cc \
 	tests/testACLMaxUserIP.h \
@@ -2514,6 +2599,7 @@
 	$(top_builddir)/lib/libmisccontainers.la \
 	$(top_builddir)/lib/libmiscencoding.la \
 	$(top_builddir)/lib/libmiscutil.la \
+	$(DISK_OS_LIBS) \
 	$(REGEXLIB) \
 	$(SQUID_CPPUNIT_LIBS) \
 	$(SSLLIB) \
@@ -2580,6 +2666,7 @@
 	CpuAffinitySet.cc \
 	CpuAffinitySet.h \
 	$(DELAY_POOL_SOURCE) \
+	$(DISKIO_SOURCE) \
 	disk.cc \
 	dlink.h \
 	dlink.cc \
@@ -2591,6 +2678,7 @@
 	ExternalACLEntry.cc \
 	fd.cc \
 	fde.cc \
+	filemap.cc \
 	forward.cc \
 	fqdncache.cc \
 	ftp.cc \
@@ -2604,7 +2692,9 @@
 	HttpBody.cc \
 	HttpHeader.cc \
 	HttpHeaderTools.cc \
+	HttpHdrCc.h \
 	HttpHdrCc.cc \
+	HttpHdrCc.cci \
 	HttpHdrContRange.cc \
 	HttpHdrRange.cc \
 	HttpHdrSc.cc \
@@ -2668,6 +2758,8 @@
 	tools.cc \
 	tunnel.cc \
 	SwapDir.cc \
+	MemStore.cc \
+	$(UNLINKDSOURCE) \
 	url.cc \
 	URLScheme.cc \
 	urn.cc \
@@ -2678,7 +2770,8 @@
 	wordlist.cc
 
 nodist_tests_testCacheManager_SOURCES = \
-	$(BUILT_SOURCES)
+	$(BUILT_SOURCES) \
+	$(DISKIO_GEN_SOURCE)
 
 # comm.cc only requires comm/libcomm.la until fdc_table is dead.
 tests_testCacheManager_LDADD = \
@@ -2693,18 +2786,20 @@
 	libsquid.la \
 	ip/libip.la \
 	fs/libfs.la \
-	ipc/libipc.la \
-	mgr/libmgr.la \
-	$(SNMP_LIBS) \
 	comm/libcomm.la \
 	icmp/libicmp.la icmp/libicmp-core.la \
 	log/liblog.la \
 	format/libformat.la \
 	$(REPL_OBJS) \
+	$(DISK_LIBS) \
+	$(DISK_OS_LIBS) \
 	$(ADAPTATION_LIBS) \
 	$(ESI_LIBS) \
 	$(SSL_LIBS) \
 	anyp/libanyp.la \
+	ipc/libipc.la \
+	mgr/libmgr.la \
+	$(SNMP_LIBS) \
 	$(top_builddir)/lib/libmisccontainers.la \
 	$(top_builddir)/lib/libmiscencoding.la \
 	$(top_builddir)/lib/libmiscutil.la \
@@ -2739,7 +2834,9 @@
 	fd.cc \
 	filemap.cc \
 	HttpBody.cc \
+	HttpHdrCc.h \
 	HttpHdrCc.cc \
+	HttpHdrCc.cci \
 	HttpHdrContRange.cc \
 	HttpHdrSc.cc \
 	HttpHdrScTarget.cc \
@@ -2797,13 +2894,13 @@
 	tests/stub_ipc.cc \
 	tests/stub_ipcache.cc \
 	tests/stub_libicmp.cc \
+	tests/stub_MemStore.cc \
 	tests/stub_mime.cc \
 	tests/stub_pconn.cc \
 	tests/stub_Port.cc \
 	tests/stub_store_client.cc \
 	tests/stub_store_rebuild.cc \
 	tests/stub_tools.cc \
-	tests/stub_TypedMsgHdr.cc \
 	tests/stub_UdsOp.cc \
 	tests/testDiskIO.cc \
 	tests/testDiskIO.h \
@@ -2837,7 +2934,6 @@
 	$(AUTH_LIBS) \
 	libsquid.la \
 	comm/libcomm.la \
-	base/libbase.la \
 	ip/libip.la \
 	fs/libfs.la \
 	ipc/libipc.la \
@@ -2846,6 +2942,8 @@
 	$(DISK_OS_LIBS) \
 	acl/libapi.la \
 	mgr/libmgr.la \
+	ipc/libipc.la \
+	base/libbase.la \
 	$(SSL_LIBS) \
 	$(top_builddir)/lib/libmisccontainers.la \
 	$(top_builddir)/lib/libmiscencoding.la \
@@ -2885,6 +2983,7 @@
 	CpuAffinitySet.h \
 	debug.cc \
 	$(DELAY_POOL_SOURCE) \
+	$(DISKIO_SOURCE) \
 	disk.cc \
 	dlink.h \
 	dlink.cc \
@@ -2899,6 +2998,7 @@
 	FadingCounter.cc \
 	fd.cc \
 	fde.cc \
+	filemap.cc \
 	forward.cc \
 	fqdncache.cc \
 	ftp.cc \
@@ -2912,7 +3012,9 @@
 	HttpBody.cc \
 	HttpHeader.cc \
 	HttpHeaderTools.cc \
+	HttpHdrCc.h \
 	HttpHdrCc.cc \
+	HttpHdrCc.cci \
 	HttpHdrContRange.cc \
 	HttpHdrRange.cc \
 	HttpHdrSc.cc \
@@ -2991,6 +3093,8 @@
 	time.cc \
 	tools.cc \
 	tunnel.cc \
+	MemStore.cc \
+	$(UNLINKDSOURCE) \
 	url.cc \
 	URLScheme.cc \
 	urn.cc \
@@ -3000,7 +3104,8 @@
 	wordlist.cc
 
 nodist_tests_testEvent_SOURCES = \
-	$(BUILT_SOURCES)
+	$(BUILT_SOURCES) \
+	$(DISKIO_GEN_SOURCE)
 
 tests_testEvent_LDADD = \
 	$(AUTH_ACL_LIBS) \
@@ -3014,10 +3119,7 @@
 	libsquid.la \
 	ip/libip.la \
 	fs/libfs.la \
-	ipc/libipc.la \
-	mgr/libmgr.la \
 	anyp/libanyp.la \
-	$(SNMP_LIBS) \
 	icmp/libicmp.la icmp/libicmp-core.la \
 	comm/libcomm.la \
 	log/liblog.la \
@@ -3029,6 +3131,11 @@
 	$(top_builddir)/lib/libmisccontainers.la \
 	$(top_builddir)/lib/libmiscencoding.la \
 	$(top_builddir)/lib/libmiscutil.la \
+	$(DISK_LIBS) \
+	$(DISK_OS_LIBS) \
+	ipc/libipc.la \
+	mgr/libmgr.la \
+	$(SNMP_LIBS) \
 	$(REGEXLIB) \
 	$(SQUID_CPPUNIT_LIBS) \
 	$(SQUID_CPPUNIT_LA) \
@@ -3065,6 +3172,7 @@
 	CpuAffinitySet.h \
 	debug.cc \
 	$(DELAY_POOL_SOURCE) \
+	$(DISKIO_SOURCE) \
 	disk.cc \
 	dlink.h \
 	dlink.cc \
@@ -3079,6 +3187,7 @@
 	FadingCounter.cc \
 	fd.cc \
 	fde.cc \
+	filemap.cc \
 	forward.cc \
 	fqdncache.cc \
 	ftp.cc \
@@ -3092,7 +3201,9 @@
 	HttpBody.cc \
 	HttpHeader.cc \
 	HttpHeaderTools.cc \
+	HttpHdrCc.h \
 	HttpHdrCc.cc \
+	HttpHdrCc.cci \
 	HttpHdrContRange.cc \
 	HttpHdrRange.cc \
 	HttpHdrSc.cc \
@@ -3170,6 +3281,8 @@
 	time.cc \
 	tools.cc \
 	tunnel.cc \
+	MemStore.cc \
+	$(UNLINKDSOURCE) \
 	url.cc \
 	URLScheme.cc \
 	urn.cc \
@@ -3179,7 +3292,8 @@
 	wordlist.cc
 
 nodist_tests_testEventLoop_SOURCES = \
-	$(BUILT_SOURCES)
+	$(BUILT_SOURCES) \
+	$(DISKIO_GEN_SOURCE)
 
 tests_testEventLoop_LDADD = \
 	$(AUTH_ACL_LIBS) \
@@ -3193,10 +3307,7 @@
 	libsquid.la \
 	ip/libip.la \
 	fs/libfs.la \
-	ipc/libipc.la \
-	mgr/libmgr.la \
 	anyp/libanyp.la \
-	$(SNMP_LIBS) \
 	icmp/libicmp.la icmp/libicmp-core.la \
 	comm/libcomm.la \
 	log/liblog.la \
@@ -3208,6 +3319,11 @@
 	$(top_builddir)/lib/libmisccontainers.la \
 	$(top_builddir)/lib/libmiscencoding.la \
 	$(top_builddir)/lib/libmiscutil.la \
+	$(DISK_LIBS) \
+	$(DISK_OS_LIBS) \
+	ipc/libipc.la \
+	mgr/libmgr.la \
+	$(SNMP_LIBS) \
 	$(REGEXLIB) \
 	$(SQUID_CPPUNIT_LIBS) \
 	$(SQUID_CPPUNIT_LA) \
@@ -3246,6 +3362,7 @@
 	CpuAffinitySet.h \
 	debug.cc \
 	$(DELAY_POOL_SOURCE) \
+	$(DISKIO_SOURCE) \
 	disk.cc \
 	dlink.h \
 	dlink.cc \
@@ -3258,6 +3375,7 @@
 	FadingCounter.cc \
 	fd.cc \
 	fde.cc \
+	filemap.cc \
 	forward.cc \
 	fqdncache.cc \
 	ftp.cc \
@@ -3269,7 +3387,9 @@
 	$(HTCPSOURCE) \
 	http.cc \
 	HttpBody.cc \
+	HttpHdrCc.h \
 	HttpHdrCc.cc \
+	HttpHdrCc.cci \
 	HttpHdrContRange.cc \
 	HttpHdrRange.cc \
 	HttpHdrSc.cc \
@@ -3342,9 +3462,11 @@
 	tests/test_http_range.cc \
 	tests/stub_ipc_Forwarder.cc \
 	tests/stub_main_cc.cc \
+	tests/stub_MemStore.cc \
 	time.cc \
 	tools.cc \
 	tunnel.cc \
+	$(UNLINKDSOURCE) \
 	url.cc \
 	URLScheme.cc \
 	urn.cc \
@@ -3354,7 +3476,8 @@
 	wordlist.cc
 
 nodist_tests_test_http_range_SOURCES = \
-	$(BUILT_SOURCES)
+	$(BUILT_SOURCES) \
+	$(DISKIO_GEN_SOURCE)
 
 tests_test_http_range_LDADD = \
 	$(AUTH_ACL_LIBS) \
@@ -3364,22 +3487,24 @@
 	acl/libstate.la \
 	$(AUTH_LIBS) \
 	acl/libapi.la \
-	base/libbase.la \
 	libsquid.la \
 	ip/libip.la \
 	fs/libfs.la \
-	ipc/libipc.la \
-	mgr/libmgr.la \
 	anyp/libanyp.la \
-	$(SNMP_LIBS) \
 	icmp/libicmp.la icmp/libicmp-core.la \
 	comm/libcomm.la \
 	log/liblog.la \
 	format/libformat.la \
 	$(REPL_OBJS) \
+	$(DISK_LIBS) \
+	$(DISK_OS_LIBS) \
 	$(ADAPTATION_LIBS) \
 	$(ESI_LIBS) \
 	$(SSL_LIBS) \
+	ipc/libipc.la \
+	base/libbase.la \
+	mgr/libmgr.la \
+	$(SNMP_LIBS) \
 	$(top_builddir)/lib/libmisccontainers.la \
 	$(top_builddir)/lib/libmiscencoding.la \
 	$(top_builddir)/lib/libmiscutil.la \
@@ -3402,7 +3527,9 @@
 	MemBuf.cc \
 	MemBuf.h \
 	mem.cc \
+	String.cc \
 	structs.h \
+	tests/stub_cache_cf.cc \
 	tests/stub_cache_manager.cc \
 	tests/stub_debug.cc \
 	tests/stub_event.cc \
@@ -3410,7 +3537,8 @@
 	tests/testHttpParser.cc \
 	tests/testHttpParser.h \
 	tests/testMain.cc \
-	time.cc
+	time.cc \
+	wordlist.cc
 
 nodist_tests_testHttpParser_SOURCES = \
 	$(TESTSOURCES)
@@ -3441,6 +3569,7 @@
 	tests/testHttpRequestMethod.h \
 	tests/testHttpRequestMethod.cc \
 	tests/testMain.cc \
+	tests/stub_DiskIOModule.cc \
 	tests/stub_main_cc.cc \
 	tests/stub_ipc_Forwarder.cc \
 	time.cc \
@@ -3490,7 +3619,9 @@
 	HttpBody.cc \
 	HttpHeader.cc \
 	HttpHeaderTools.cc \
+	HttpHdrCc.h \
 	HttpHdrCc.cc \
+	HttpHdrCc.cci \
 	HttpHdrContRange.cc \
 	HttpHdrRange.cc \
 	HttpHdrSc.cc \
@@ -3555,6 +3686,7 @@
 	tools.cc \
 	tunnel.cc \
 	SwapDir.cc \
+	MemStore.cc \
 	url.cc \
 	URLScheme.cc \
 	urn.cc \
@@ -3575,11 +3707,11 @@
 	acl/libstate.la \
 	$(AUTH_LIBS) \
 	acl/libapi.la \
-	base/libbase.la \
 	libsquid.la \
 	ip/libip.la \
 	fs/libfs.la \
 	ipc/libipc.la \
+	base/libbase.la \
 	mgr/libmgr.la \
 	anyp/libanyp.la \
 	$(SNMP_LIBS) \
@@ -3594,6 +3726,7 @@
 	$(top_builddir)/lib/libmisccontainers.la \
 	$(top_builddir)/lib/libmiscencoding.la \
 	$(top_builddir)/lib/libmiscutil.la \
+	$(DISK_OS_LIBS) \
 	$(REGEXLIB) \
 	$(SQUID_CPPUNIT_LIBS) \
 	$(SQUID_CPPUNIT_LA) \
@@ -3621,7 +3754,9 @@
 	event.cc \
 	EventLoop.cc \
 	filemap.cc \
+	HttpHdrCc.h \
 	HttpHdrCc.cc \
+	HttpHdrCc.cci \
 	HttpHdrContRange.cc \
 	HttpHdrRange.cc \
 	HttpHdrSc.cc \
@@ -3673,14 +3808,15 @@
 	tests/stub_http.cc \
 	tests/stub_HttpReply.cc \
 	tests/stub_HttpRequest.cc \
+	tests/stub_libcomm.cc \
 	tests/stub_MemObject.cc \
+	tests/stub_MemStore.cc \
 	tests/stub_mime.cc \
 	tests/stub_Port.cc \
 	tests/stub_store_client.cc \
 	tests/stub_store_rebuild.cc \
 	tests/stub_store_swapout.cc \
 	tests/stub_tools.cc \
-	tests/stub_TypedMsgHdr.cc \
 	tests/stub_UdsOp.cc \
 	tests/testMain.cc \
 	tests/testStore.cc \
@@ -3718,8 +3854,8 @@
 	libsquid.la \
 	ip/libip.la \
 	fs/libfs.la \
-	ipc/libipc.la \
 	mgr/libmgr.la \
+	ipc/libipc.la \
 	anyp/libanyp.la \
 	$(top_builddir)/lib/libmisccontainers.la \
 	$(top_builddir)/lib/libmiscencoding.la \
@@ -3739,14 +3875,17 @@
 tests_testString_SOURCES = \
 	ClientInfo.h \
 	mem.cc \
+	MemBuf.cc \
 	String.cc \
 	tests/testMain.cc \
 	tests/testString.cc \
 	tests/testString.h \
+	tests/stub_cache_cf.cc \
 	tests/stub_cache_manager.cc \
 	tests/stub_debug.cc \
 	tests/stub_HelperChildConfig.cc \
-	time.cc
+	time.cc \
+	wordlist.cc
 
 nodist_tests_testString_SOURCES = \
 	$(TESTSOURCES)
@@ -3794,9 +3933,9 @@
 	tests/stub_HelperChildConfig.cc \
 	tests/stub_icp.cc \
 	tests/stub_ipc.cc \
+	tests/stub_MemStore.cc \
 	tests/stub_pconn.cc \
 	tests/stub_Port.cc \
-	tests/stub_TypedMsgHdr.cc \
 	tests/stub_UdsOp.cc \
 	tests/stub_internal.cc \
 	tests/stub_store_rebuild.cc \
@@ -3856,7 +3995,9 @@
 	MemBuf.cc \
 	HttpHdrContRange.cc \
 	Packer.cc \
+	HttpHdrCc.h \
 	HttpHdrCc.cc \
+	HttpHdrCc.cci \
 	HttpHdrSc.cc \
 	HttpHdrScTarget.cc \
 	url.cc \
@@ -3893,17 +4034,17 @@
 	acl/libstate.la \
 	$(AUTH_LIBS) \
 	acl/libapi.la \
-	base/libbase.la \
 	libsquid.la \
 	ip/libip.la \
 	fs/libfs.la \
-	ipc/libipc.la \
 	mgr/libmgr.la \
 	$(REPL_OBJS) \
 	acl/libacls.la \
 	anyp/libanyp.la \
 	$(DISK_LIBS) \
 	$(DISK_OS_LIBS) \
+	acl/libapi.la \
+	ipc/libipc.la \
 	$(SSL_LIBS) \
 	comm/libcomm.la \
 	base/libbase.la \
@@ -3926,10 +4067,12 @@
 	tests/testMain.cc \
 	tests/testCoss.h \
 	tests/stub_cache_manager.cc \
+	tests/stub_client_db.cc \
 	tests/stub_debug.cc \
 	tests/stub_HelperChildConfig.cc \
 	tests/stub_internal.cc \
-	tests/stub_CommIO.cc \
+	tests/stub_ipc.cc \
+	tests/stub_pconn.cc \
 	tests/stub_store_rebuild.cc \
 	fd.cc \
 	disk.cc \
@@ -3974,8 +4117,6 @@
 	tests/stub_helper.cc \
 	cbdata.cc \
 	String.cc \
-	tests/stub_comm.cc \
-	tests/stub_debug.cc \
 	tests/stub_client_side_request.cc \
 	tests/stub_http.cc \
 	mem_node.cc \
@@ -3988,7 +4129,9 @@
 	MemBuf.cc \
 	HttpHdrContRange.cc \
 	Packer.cc \
+	HttpHdrCc.h \
 	HttpHdrCc.cc \
+	HttpHdrCc.cci \
 	HttpHdrSc.cc \
 	HttpHdrScTarget.cc \
 	url.cc \
@@ -3999,8 +4142,11 @@
 	tests/stub_HttpRequest.cc \
 	tests/stub_access_log.cc \
 	refresh.cc \
+	tests/stub_MemStore.cc \
+	tests/stub_Port.cc \
 	tests/stub_store_client.cc \
 	tests/stub_tools.cc \
+	tests/stub_UdsOp.cc \
 	tests/testStoreSupport.cc \
 	tests/testStoreSupport.h \
 	time.cc \
@@ -4016,6 +4162,7 @@
 	$(DISKIO_GEN_SOURCE)
 
 tests_testCoss_LDADD = \
+	anyp/libanyp.la \
 	libsquid.la \
 	$(REGEXLIB) \
 	$(AUTH_ACL_LIBS) \
@@ -4025,18 +4172,19 @@
 	acl/libstate.la \
 	$(AUTH_LIBS) \
 	acl/libapi.la \
-	base/libbase.la \
 	libsquid.la \
+	comm/libcomm.la \
 	ip/libip.la \
 	fs/libfs.la \
-	ipc/libipc.la \
 	mgr/libmgr.la \
 	$(REPL_OBJS) \
 	$(DISK_LIBS) \
 	$(DISK_OS_LIBS) \
 	$(COMMON_LIBS) \
-	libsquid.la \
+	$(SSL_LIBS) \
 	acl/libapi.la \
+	ipc/libipc.la \
+	base/libbase.la \
 	$(top_builddir)/lib/libmisccontainers.la \
 	$(top_builddir)/lib/libmiscencoding.la \
 	$(top_builddir)/lib/libmiscutil.la \
@@ -4114,7 +4262,9 @@
 	MemBuf.cc \
 	HttpHdrContRange.cc \
 	Packer.cc \
+	HttpHdrCc.h \
 	HttpHdrCc.cc \
+	HttpHdrCc.cci \
 	HttpHdrSc.cc \
 	HttpHdrScTarget.cc \
 	url.cc \
@@ -4216,7 +4366,9 @@
 	$(HTCPSOURCE) \
 	http.cc \
 	HttpBody.cc \
+	HttpHdrCc.h \
 	HttpHdrCc.cc \
+	HttpHdrCc.cci \
 	HttpHdrContRange.cc \
 	HttpHdrRange.cc \
 	HttpHdrSc.cc \
@@ -4288,6 +4440,7 @@
 	StoreSwapLogData.cc \
 	String.cc \
 	SwapDir.cc \
+	MemStore.cc \
 	tests/stub_debug.cc \
 	tests/stub_DiskIOModule.cc \
 	tests/stub_main_cc.cc \
@@ -4331,6 +4484,7 @@
 	icmp/libicmp.la icmp/libicmp-core.la \
 	comm/libcomm.la \
 	log/liblog.la \
+	$(DISK_OS_LIBS) \
 	format/libformat.la \
 	$(REGEXLIB) \
 	$(REPL_OBJS) \
@@ -4478,6 +4632,41 @@
 	-rm -f libDiskThreads.a
 	$(libDiskThreads_a_AR) libDiskThreads.a $(libDiskThreads_a_OBJECTS) $(libDiskThreads_a_LIBADD)
 	$(RANLIB) libDiskThreads.a
+DiskIO/IpcIo/$(am__dirstamp):
+	@$(MKDIR_P) DiskIO/IpcIo
+	@: > DiskIO/IpcIo/$(am__dirstamp)
+DiskIO/IpcIo/$(DEPDIR)/$(am__dirstamp):
+	@$(MKDIR_P) DiskIO/IpcIo/$(DEPDIR)
+	@: > DiskIO/IpcIo/$(DEPDIR)/$(am__dirstamp)
+DiskIO/IpcIo/IpcIoFile.$(OBJEXT): DiskIO/IpcIo/$(am__dirstamp) \
+	DiskIO/IpcIo/$(DEPDIR)/$(am__dirstamp)
+DiskIO/IpcIo/IpcIoIOStrategy.$(OBJEXT): DiskIO/IpcIo/$(am__dirstamp) \
+	DiskIO/IpcIo/$(DEPDIR)/$(am__dirstamp)
+DiskIO/IpcIo/IpcIoDiskIOModule.$(OBJEXT):  \
+	DiskIO/IpcIo/$(am__dirstamp) \
+	DiskIO/IpcIo/$(DEPDIR)/$(am__dirstamp)
+libIpcIo.a: $(libIpcIo_a_OBJECTS) $(libIpcIo_a_DEPENDENCIES) 
+	-rm -f libIpcIo.a
+	$(libIpcIo_a_AR) libIpcIo.a $(libIpcIo_a_OBJECTS) $(libIpcIo_a_LIBADD)
+	$(RANLIB) libIpcIo.a
+DiskIO/Mmapped/$(am__dirstamp):
+	@$(MKDIR_P) DiskIO/Mmapped
+	@: > DiskIO/Mmapped/$(am__dirstamp)
+DiskIO/Mmapped/$(DEPDIR)/$(am__dirstamp):
+	@$(MKDIR_P) DiskIO/Mmapped/$(DEPDIR)
+	@: > DiskIO/Mmapped/$(DEPDIR)/$(am__dirstamp)
+DiskIO/Mmapped/MmappedFile.$(OBJEXT): DiskIO/Mmapped/$(am__dirstamp) \
+	DiskIO/Mmapped/$(DEPDIR)/$(am__dirstamp)
+DiskIO/Mmapped/MmappedIOStrategy.$(OBJEXT):  \
+	DiskIO/Mmapped/$(am__dirstamp) \
+	DiskIO/Mmapped/$(DEPDIR)/$(am__dirstamp)
+DiskIO/Mmapped/MmappedDiskIOModule.$(OBJEXT):  \
+	DiskIO/Mmapped/$(am__dirstamp) \
+	DiskIO/Mmapped/$(DEPDIR)/$(am__dirstamp)
+libMmapped.a: $(libMmapped_a_OBJECTS) $(libMmapped_a_DEPENDENCIES) 
+	-rm -f libMmapped.a
+	$(libMmapped_a_AR) libMmapped.a $(libMmapped_a_OBJECTS) $(libMmapped_a_LIBADD)
+	$(RANLIB) libMmapped.a
 
 clean-noinstLTLIBRARIES:
 	-test -z "$(noinst_LTLIBRARIES)" || rm -f $(noinst_LTLIBRARIES)
@@ -4688,6 +4877,8 @@
 	tests/$(DEPDIR)/$(am__dirstamp)
 tests/stub_MemObject.$(OBJEXT): tests/$(am__dirstamp) \
 	tests/$(DEPDIR)/$(am__dirstamp)
+tests/stub_MemStore.$(OBJEXT): tests/$(am__dirstamp) \
+	tests/$(DEPDIR)/$(am__dirstamp)
 tests/stub_mime.$(OBJEXT): tests/$(am__dirstamp) \
 	tests/$(DEPDIR)/$(am__dirstamp)
 tests/stub_store.$(OBJEXT): tests/$(am__dirstamp) \
@@ -4696,6 +4887,8 @@
 	tests/$(DEPDIR)/$(am__dirstamp)
 tests/stub_store_swapout.$(OBJEXT): tests/$(am__dirstamp) \
 	tests/$(DEPDIR)/$(am__dirstamp)
+tests/stub_tools.$(OBJEXT): tests/$(am__dirstamp) \
+	tests/$(DEPDIR)/$(am__dirstamp)
 tests/stub_cache_manager.$(OBJEXT): tests/$(am__dirstamp) \
 	tests/$(DEPDIR)/$(am__dirstamp)
 tests/testACLMaxUserIP.$(OBJEXT): tests/$(am__dirstamp) \
@@ -4721,11 +4914,15 @@
 	$(tests_testCacheManager_LINK) $(tests_testCacheManager_OBJECTS) $(tests_testCacheManager_LDADD) $(LIBS)
 tests/testCoss.$(OBJEXT): tests/$(am__dirstamp) \
 	tests/$(DEPDIR)/$(am__dirstamp)
+tests/stub_client_db.$(OBJEXT): tests/$(am__dirstamp) \
+	tests/$(DEPDIR)/$(am__dirstamp)
 tests/stub_HelperChildConfig.$(OBJEXT): tests/$(am__dirstamp) \
 	tests/$(DEPDIR)/$(am__dirstamp)
 tests/stub_internal.$(OBJEXT): tests/$(am__dirstamp) \
 	tests/$(DEPDIR)/$(am__dirstamp)
-tests/stub_CommIO.$(OBJEXT): tests/$(am__dirstamp) \
+tests/stub_ipc.$(OBJEXT): tests/$(am__dirstamp) \
+	tests/$(DEPDIR)/$(am__dirstamp)
+tests/stub_pconn.$(OBJEXT): tests/$(am__dirstamp) \
 	tests/$(DEPDIR)/$(am__dirstamp)
 tests/stub_acl.$(OBJEXT): tests/$(am__dirstamp) \
 	tests/$(DEPDIR)/$(am__dirstamp)
@@ -4737,33 +4934,23 @@
 	tests/$(DEPDIR)/$(am__dirstamp)
 tests/stub_errorpage.$(OBJEXT): tests/$(am__dirstamp) \
 	tests/$(DEPDIR)/$(am__dirstamp)
+tests/stub_Port.$(OBJEXT): tests/$(am__dirstamp) \
+	tests/$(DEPDIR)/$(am__dirstamp)
 tests/stub_store_client.$(OBJEXT): tests/$(am__dirstamp) \
 	tests/$(DEPDIR)/$(am__dirstamp)
-tests/stub_tools.$(OBJEXT): tests/$(am__dirstamp) \
+tests/stub_UdsOp.$(OBJEXT): tests/$(am__dirstamp) \
 	tests/$(DEPDIR)/$(am__dirstamp)
 tests/testStoreSupport.$(OBJEXT): tests/$(am__dirstamp) \
 	tests/$(DEPDIR)/$(am__dirstamp)
 tests/testCoss$(EXEEXT): $(tests_testCoss_OBJECTS) $(tests_testCoss_DEPENDENCIES) tests/$(am__dirstamp)
 	@rm -f tests/testCoss$(EXEEXT)
 	$(tests_testCoss_LINK) $(tests_testCoss_OBJECTS) $(tests_testCoss_LDADD) $(LIBS)
-tests/stub_client_db.$(OBJEXT): tests/$(am__dirstamp) \
-	tests/$(DEPDIR)/$(am__dirstamp)
 tests/stub_icp.$(OBJEXT): tests/$(am__dirstamp) \
 	tests/$(DEPDIR)/$(am__dirstamp)
-tests/stub_ipc.$(OBJEXT): tests/$(am__dirstamp) \
-	tests/$(DEPDIR)/$(am__dirstamp)
 tests/stub_ipcache.$(OBJEXT): tests/$(am__dirstamp) \
 	tests/$(DEPDIR)/$(am__dirstamp)
 tests/stub_libicmp.$(OBJEXT): tests/$(am__dirstamp) \
 	tests/$(DEPDIR)/$(am__dirstamp)
-tests/stub_pconn.$(OBJEXT): tests/$(am__dirstamp) \
-	tests/$(DEPDIR)/$(am__dirstamp)
-tests/stub_Port.$(OBJEXT): tests/$(am__dirstamp) \
-	tests/$(DEPDIR)/$(am__dirstamp)
-tests/stub_TypedMsgHdr.$(OBJEXT): tests/$(am__dirstamp) \
-	tests/$(DEPDIR)/$(am__dirstamp)
-tests/stub_UdsOp.$(OBJEXT): tests/$(am__dirstamp) \
-	tests/$(DEPDIR)/$(am__dirstamp)
 tests/testDiskIO.$(OBJEXT): tests/$(am__dirstamp) \
 	tests/$(DEPDIR)/$(am__dirstamp)
 tests/testDiskIO$(EXEEXT): $(tests_testDiskIO_OBJECTS) $(tests_testDiskIO_DEPENDENCIES) tests/$(am__dirstamp)
@@ -4802,11 +4989,15 @@
 	$(tests_testHttpRequest_LINK) $(tests_testHttpRequest_OBJECTS) $(tests_testHttpRequest_LDADD) $(LIBS)
 tests/testNull.$(OBJEXT): tests/$(am__dirstamp) \
 	tests/$(DEPDIR)/$(am__dirstamp)
+tests/stub_CommIO.$(OBJEXT): tests/$(am__dirstamp) \
+	tests/$(DEPDIR)/$(am__dirstamp)
 tests/testNull$(EXEEXT): $(tests_testNull_OBJECTS) $(tests_testNull_DEPENDENCIES) tests/$(am__dirstamp)
 	@rm -f tests/testNull$(EXEEXT)
 	$(tests_testNull_LINK) $(tests_testNull_OBJECTS) $(tests_testNull_LDADD) $(LIBS)
 tests/stub_HttpReply.$(OBJEXT): tests/$(am__dirstamp) \
 	tests/$(DEPDIR)/$(am__dirstamp)
+tests/stub_libcomm.$(OBJEXT): tests/$(am__dirstamp) \
+	tests/$(DEPDIR)/$(am__dirstamp)
 tests/testStore.$(OBJEXT): tests/$(am__dirstamp) \
 	tests/$(DEPDIR)/$(am__dirstamp)
 tests/testStoreEntryStream.$(OBJEXT): tests/$(am__dirstamp) \
@@ -4871,6 +5062,12 @@
 	-rm -f DiskIO/DiskThreads/aiops.$(OBJEXT)
 	-rm -f DiskIO/DiskThreads/aiops_win32.$(OBJEXT)
 	-rm -f DiskIO/DiskThreads/async_io.$(OBJEXT)
+	-rm -f DiskIO/IpcIo/IpcIoDiskIOModule.$(OBJEXT)
+	-rm -f DiskIO/IpcIo/IpcIoFile.$(OBJEXT)
+	-rm -f DiskIO/IpcIo/IpcIoIOStrategy.$(OBJEXT)
+	-rm -f DiskIO/Mmapped/MmappedDiskIOModule.$(OBJEXT)
+	-rm -f DiskIO/Mmapped/MmappedFile.$(OBJEXT)
+	-rm -f DiskIO/Mmapped/MmappedIOStrategy.$(OBJEXT)
 	-rm -f DiskIO/ReadRequest.$(OBJEXT)
 	-rm -f DiskIO/WriteRequest.$(OBJEXT)
 	-rm -f tests/TestSwapDir.$(OBJEXT)
@@ -4881,9 +5078,9 @@
 	-rm -f tests/stub_HttpReply.$(OBJEXT)
 	-rm -f tests/stub_HttpRequest.$(OBJEXT)
 	-rm -f tests/stub_MemObject.$(OBJEXT)
+	-rm -f tests/stub_MemStore.$(OBJEXT)
 	-rm -f tests/stub_Port.$(OBJEXT)
 	-rm -f tests/stub_StatHist.$(OBJEXT)
-	-rm -f tests/stub_TypedMsgHdr.$(OBJEXT)
 	-rm -f tests/stub_UdsOp.$(OBJEXT)
 	-rm -f tests/stub_access_log.$(OBJEXT)
 	-rm -f tests/stub_acl.$(OBJEXT)
@@ -4903,6 +5100,7 @@
 	-rm -f tests/stub_ipc.$(OBJEXT)
 	-rm -f tests/stub_ipc_Forwarder.$(OBJEXT)
 	-rm -f tests/stub_ipcache.$(OBJEXT)
+	-rm -f tests/stub_libcomm.$(OBJEXT)
 	-rm -f tests/stub_libicmp.$(OBJEXT)
 	-rm -f tests/stub_main_cc.$(OBJEXT)
 	-rm -f tests/stub_mime.$(OBJEXT)
@@ -4988,6 +5186,7 @@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/MemBlob.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/MemBuf.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/MemObject.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/MemStore.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/NullDelayId.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/Packer.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/Parsing.Po@am__quote@
@@ -5128,6 +5327,12 @@
 @AMDEP_TRUE@@am__include@ @am__quote@DiskIO/DiskThreads/$(DEPDIR)/aiops.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@DiskIO/DiskThreads/$(DEPDIR)/aiops_win32.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@DiskIO/DiskThreads/$(DEPDIR)/async_io.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@DiskIO/IpcIo/$(DEPDIR)/IpcIoDiskIOModule.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@DiskIO/IpcIo/$(DEPDIR)/IpcIoFile.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@DiskIO/IpcIo/$(DEPDIR)/IpcIoIOStrategy.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@DiskIO/Mmapped/$(DEPDIR)/MmappedDiskIOModule.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@DiskIO/Mmapped/$(DEPDIR)/MmappedFile.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@DiskIO/Mmapped/$(DEPDIR)/MmappedIOStrategy.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@tests/$(DEPDIR)/TestSwapDir.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@tests/$(DEPDIR)/stub_CommIO.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@tests/$(DEPDIR)/stub_DelayId.Po@am__quote@
@@ -5136,9 +5341,9 @@
 @AMDEP_TRUE@@am__include@ @am__quote@tests/$(DEPDIR)/stub_HttpReply.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@tests/$(DEPDIR)/stub_HttpRequest.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@tests/$(DEPDIR)/stub_MemObject.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@tests/$(DEPDIR)/stub_MemStore.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@tests/$(DEPDIR)/stub_Port.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@tests/$(DEPDIR)/stub_StatHist.Po@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@tests/$(DEPDIR)/stub_TypedMsgHdr.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@tests/$(DEPDIR)/stub_UdsOp.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@tests/$(DEPDIR)/stub_access_log.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@tests/$(DEPDIR)/stub_acl.Po@am__quote@
@@ -5158,6 +5363,7 @@
 @AMDEP_TRUE@@am__include@ @am__quote@tests/$(DEPDIR)/stub_ipc.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@tests/$(DEPDIR)/stub_ipc_Forwarder.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@tests/$(DEPDIR)/stub_ipcache.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@tests/$(DEPDIR)/stub_libcomm.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@tests/$(DEPDIR)/stub_libicmp.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@tests/$(DEPDIR)/stub_main_cc.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@tests/$(DEPDIR)/stub_mime.Po@am__quote@
@@ -5644,6 +5850,10 @@
 	-rm -f DiskIO/DiskDaemon/$(am__dirstamp)
 	-rm -f DiskIO/DiskThreads/$(DEPDIR)/$(am__dirstamp)
 	-rm -f DiskIO/DiskThreads/$(am__dirstamp)
+	-rm -f DiskIO/IpcIo/$(DEPDIR)/$(am__dirstamp)
+	-rm -f DiskIO/IpcIo/$(am__dirstamp)
+	-rm -f DiskIO/Mmapped/$(DEPDIR)/$(am__dirstamp)
+	-rm -f DiskIO/Mmapped/$(am__dirstamp)
 	-rm -f tests/$(DEPDIR)/$(am__dirstamp)
 	-rm -f tests/$(am__dirstamp)
 
@@ -5659,7 +5869,7 @@
 	clean-sbinPROGRAMS mostlyclean-am
 
 distclean: distclean-recursive
-	-rm -rf ./$(DEPDIR) DiskIO/$(DEPDIR) DiskIO/AIO/$(DEPDIR) DiskIO/Blocking/$(DEPDIR) DiskIO/DiskDaemon/$(DEPDIR) DiskIO/DiskThreads/$(DEPDIR) tests/$(DEPDIR)
+	-rm -rf ./$(DEPDIR) DiskIO/$(DEPDIR) DiskIO/AIO/$(DEPDIR) DiskIO/Blocking/$(DEPDIR) DiskIO/DiskDaemon/$(DEPDIR) DiskIO/DiskThreads/$(DEPDIR) DiskIO/IpcIo/$(DEPDIR) DiskIO/Mmapped/$(DEPDIR) tests/$(DEPDIR)
 	-rm -f Makefile
 distclean-am: clean-am distclean-compile distclean-generic \
 	distclean-tags
@@ -5706,7 +5916,7 @@
 installcheck-am:
 
 maintainer-clean: maintainer-clean-recursive
-	-rm -rf ./$(DEPDIR) DiskIO/$(DEPDIR) DiskIO/AIO/$(DEPDIR) DiskIO/Blocking/$(DEPDIR) DiskIO/DiskDaemon/$(DEPDIR) DiskIO/DiskThreads/$(DEPDIR) tests/$(DEPDIR)
+	-rm -rf ./$(DEPDIR) DiskIO/$(DEPDIR) DiskIO/AIO/$(DEPDIR) DiskIO/Blocking/$(DEPDIR) DiskIO/DiskDaemon/$(DEPDIR) DiskIO/DiskThreads/$(DEPDIR) DiskIO/IpcIo/$(DEPDIR) DiskIO/Mmapped/$(DEPDIR) tests/$(DEPDIR)
 	-rm -f Makefile
 maintainer-clean-am: distclean-am maintainer-clean-generic
 
diff -u -r -N squid-3.2.0.12/src/mem.cc squid-3.2.0.13/src/mem.cc
--- squid-3.2.0.12/src/mem.cc	2011-09-16 23:37:30.000000000 +1200
+++ squid-3.2.0.13/src/mem.cc	2011-10-14 14:42:56.000000000 +1300
@@ -453,7 +453,6 @@
     memDataInit(MEM_DLINK_NODE, "dlink_node", sizeof(dlink_node), 10);
     memDataInit(MEM_DREAD_CTRL, "dread_ctrl", sizeof(dread_ctrl), 0);
     memDataInit(MEM_DWRITE_Q, "dwrite_q", sizeof(dwrite_q), 0);
-    memDataInit(MEM_HTTP_HDR_CC, "HttpHdrCc", sizeof(HttpHdrCc), 0);
     memDataInit(MEM_HTTP_HDR_CONTENT_RANGE, "HttpHdrContRange", sizeof(HttpHdrContRange), 0);
     memDataInit(MEM_NETDBENTRY, "netdbEntry", sizeof(netdbEntry), 0);
     memDataInit(MEM_NET_DB_NAME, "net_db_name", sizeof(net_db_name), 0);
@@ -521,7 +520,8 @@
 memClean(void)
 {
     MemPoolGlobalStats stats;
-    MemPools::GetInstance().setIdleLimit(0);
+    if (Config.MemPools.limit > 0) // do not reset if disabled or same
+        MemPools::GetInstance().setIdleLimit(0);
     MemPools::GetInstance().clean(0);
     memPoolGetGlobalStats(&stats);
 
diff -u -r -N squid-3.2.0.12/src/MemObject.cc squid-3.2.0.13/src/MemObject.cc
--- squid-3.2.0.12/src/MemObject.cc	2011-09-16 23:37:30.000000000 +1200
+++ squid-3.2.0.13/src/MemObject.cc	2011-10-14 14:42:56.000000000 +1300
@@ -72,6 +72,15 @@
     return Pool().inUseCount();
 }
 
+void
+MemObject::resetUrls(char const *aUrl, char const *aLog_url)
+{
+    safe_free(url);
+    safe_free(log_url);    /* XXX account log_url */
+    log_url = xstrdup(aLog_url);
+    url = xstrdup(aUrl);
+}
+
 MemObject::MemObject(char const *aUrl, char const *aLog_url)
 {
     debugs(20, 3, HERE << "new MemObject " << this);
@@ -91,6 +100,8 @@
     object_sz = -1;
 
     /* XXX account log_url */
+
+    swapout.decision = SwapOut::swNeedsCheck;
 }
 
 MemObject::~MemObject()
@@ -234,6 +245,15 @@
     return data_hdr.endOffset();
 }
 
+void
+MemObject::markEndOfReplyHeaders()
+{
+    const int hdr_sz = endOffset();
+    assert(hdr_sz >= 0);
+    assert(_reply);
+    _reply->hdr_sz = hdr_sz;
+}
+
 int64_t
 MemObject::size() const
 {
@@ -243,6 +263,23 @@
     return object_sz;
 }
 
+int64_t
+MemObject::expectedReplySize() const
+{
+    debugs(20, 7, HERE << "object_sz: " << object_sz);
+    if (object_sz >= 0) // complete() has been called; we know the exact answer
+        return object_sz;
+
+    if (_reply) {
+        const int64_t clen = _reply->bodySize(method);
+        debugs(20, 7, HERE << "clen: " << clen);
+        if (clen >= 0 && _reply->hdr_sz > 0) // yuck: HttpMsg sets hdr_sz to 0
+            return clen + _reply->hdr_sz;
+    }
+
+    return -1; // not enough information to predict
+}
+
 void
 MemObject::reset()
 {
@@ -342,7 +379,7 @@
      * there will be a chunk of the data which is not in memory
      * and is not yet on disk.
      * The -1 makes sure the page isn't freed until storeSwapOut has
-     * walked to the next page. (mem->swapout.memnode)
+     * walked to the next page.
      */
     int64_t on_disk;
 
diff -u -r -N squid-3.2.0.12/src/MemObject.h squid-3.2.0.13/src/MemObject.h
--- squid-3.2.0.12/src/MemObject.h	2011-09-16 23:37:30.000000000 +1200
+++ squid-3.2.0.13/src/MemObject.h	2011-10-14 14:42:56.000000000 +1300
@@ -58,12 +58,19 @@
     MemObject(char const *, char const *);
     ~MemObject();
 
+    /// replaces construction-time URLs with correct ones; see hidden_mem_obj
+    void resetUrls(char const *aUrl, char const *aLog_url);
+
     void write(StoreIOBuffer, STMCB *, void *);
     void unlinkRequest();
     HttpReply const *getReply() const;
     void replaceHttpReply(HttpReply *newrep);
     void stat (MemBuf * mb) const;
     int64_t endOffset () const;
+    void markEndOfReplyHeaders(); ///< sets _reply->hdr_sz to endOffset()
+    /// negative if unknown; otherwise, expected object_sz, expected endOffset
+    /// maximum, and stored reply headers+body size (all three are the same)
+    int64_t expectedReplySize() const;
     int64_t size() const;
     void reset();
     int64_t lowestMemReaderOffset() const;
@@ -106,9 +113,12 @@
     {
 
     public:
-        int64_t queue_offset;     /* relative to in-mem data */
-        mem_node *memnode;      /* which node we're currently paging out */
+        int64_t queue_offset; ///< number of bytes sent to SwapDir for writing
         StoreIOState::Pointer sio;
+
+        /// Decision states for StoreEntry::swapoutPossible() and related code.
+        typedef enum { swNeedsCheck = 0, swImpossible = -1, swPossible = +1 } Decision;
+        Decision decision; ///< current decision state
     };
 
     SwapOut swapout;
diff -u -r -N squid-3.2.0.12/src/MemStore.cc squid-3.2.0.13/src/MemStore.cc
--- squid-3.2.0.12/src/MemStore.cc	1970-01-01 12:00:00.000000000 +1200
+++ squid-3.2.0.13/src/MemStore.cc	2011-10-14 14:42:56.000000000 +1300
@@ -0,0 +1,399 @@
+/*
+ * $Id$
+ *
+ * DEBUG: section 20    Memory Cache
+ *
+ */
+
+#include "config.h"
+#include "base/RunnersRegistry.h"
+#include "ipc/mem/Page.h"
+#include "ipc/mem/Pages.h"
+#include "MemObject.h"
+#include "MemStore.h"
+#include "HttpReply.h"
+
+/// shared memory segment path to use for MemStore maps
+static const char *ShmLabel = "cache_mem";
+
+// XXX: support storage using more than one page per entry
+
+MemStore::MemStore(): map(NULL), theCurrentSize(0)
+{
+}
+
+MemStore::~MemStore()
+{
+    delete map;
+}
+
+void
+MemStore::init()
+{
+    const int64_t entryLimit = EntryLimit();
+    if (entryLimit <= 0)
+        return; // no memory cache configured or a misconfiguration
+
+    const int64_t diskMaxSize = Store::Root().maxObjectSize();
+    const int64_t memMaxSize = maxObjectSize();
+    if (diskMaxSize == -1) {
+        debugs(20, DBG_IMPORTANT, "WARNING: disk-cache maximum object size "
+               "is unlimited but mem-cache maximum object size is " <<
+               memMaxSize / 1024.0 << " KB");
+    } else if (diskMaxSize > memMaxSize) {
+        debugs(20, DBG_IMPORTANT, "WARNING: disk-cache maximum object size "
+               "is too large for mem-cache: " <<
+               diskMaxSize / 1024.0 << " KB > " <<
+               memMaxSize / 1024.0 << " KB");
+    }
+
+    map = new MemStoreMap(ShmLabel);
+    map->cleaner = this;
+}
+
+void
+MemStore::stat(StoreEntry &e) const
+{
+    storeAppendPrintf(&e, "\n\nShared Memory Cache\n");
+
+    storeAppendPrintf(&e, "Maximum Size: %.0f KB\n", Config.memMaxSize/1024.0);
+
+    if (map) {
+        const int limit = map->entryLimit();
+        storeAppendPrintf(&e, "Maximum entries: %9d\n", limit);
+        if (limit > 0) {
+            storeAppendPrintf(&e, "Current entries: %"PRId64" %.2f%%\n",
+                              currentCount(), (100.0 * currentCount() / limit));
+
+            if (limit < 100) { // XXX: otherwise too expensive to count
+                Ipc::ReadWriteLockStats stats;
+                map->updateStats(stats);
+                stats.dump(e);
+            }
+        }
+    }
+}
+
+void
+MemStore::maintain()
+{
+}
+
+uint64_t
+MemStore::minSize() const
+{
+    return 0; // XXX: irrelevant, but Store parent forces us to implement this
+}
+
+uint64_t
+MemStore::maxSize() const
+{
+    return 0; // XXX: make configurable
+}
+
+uint64_t
+MemStore::currentSize() const
+{
+    return theCurrentSize;
+}
+
+uint64_t
+MemStore::currentCount() const
+{
+    return map ? map->entryCount() : 0;
+}
+
+int64_t
+MemStore::maxObjectSize() const
+{
+    return Ipc::Mem::PageSize();
+}
+
+void
+MemStore::reference(StoreEntry &)
+{
+}
+
+bool
+MemStore::dereference(StoreEntry &)
+{
+    // no need to keep e in the global store_table for us; we have our own map
+    return false;
+}
+
+int
+MemStore::callback()
+{
+    return 0;
+}
+
+StoreSearch *
+MemStore::search(String const, HttpRequest *)
+{
+    fatal("not implemented");
+    return NULL;
+}
+
+StoreEntry *
+MemStore::get(const cache_key *key)
+{
+    if (!map)
+        return NULL;
+
+    // XXX: replace sfileno with a bigger word (sfileno is only for cache_dirs)
+    sfileno index;
+    const Ipc::StoreMapSlot *const slot = map->openForReading(key, index);
+    if (!slot)
+        return NULL;
+
+    const Ipc::StoreMapSlot::Basics &basics = slot->basics;
+    const MemStoreMap::Extras &extras = map->extras(index);
+
+    // create a brand new store entry and initialize it with stored info
+    StoreEntry *e = new StoreEntry();
+    e->lock_count = 0;
+
+    e->swap_file_sz = basics.swap_file_sz;
+    e->lastref = basics.lastref;
+    e->timestamp = basics.timestamp;
+    e->expires = basics.expires;
+    e->lastmod = basics.lastmod;
+    e->refcount = basics.refcount;
+    e->flags = basics.flags;
+
+    e->store_status = STORE_OK;
+    e->mem_status = IN_MEMORY; // setMemStatus(IN_MEMORY) requires mem_obj
+    //e->swap_status = set in StoreEntry constructor to SWAPOUT_NONE;
+    e->ping_status = PING_NONE;
+
+    EBIT_SET(e->flags, ENTRY_CACHABLE);
+    EBIT_CLR(e->flags, RELEASE_REQUEST);
+    EBIT_CLR(e->flags, KEY_PRIVATE);
+    EBIT_SET(e->flags, ENTRY_VALIDATED);
+
+    const bool copied = copyFromShm(*e, extras);
+
+    // we copied everything we could to local memory; no more need to lock
+    map->closeForReading(index);
+
+    if (copied) {
+        e->hashInsert(key);
+        return e;
+    }
+
+    debugs(20, 3, HERE << "mem-loading failed; freeing " << index);
+    map->free(index); // do not let others into the same trap
+    return NULL;
+}
+
+void
+MemStore::get(String const key, STOREGETCLIENT aCallback, void *aCallbackData)
+{
+    // XXX: not needed but Store parent forces us to implement this
+    fatal("MemStore::get(key,callback,data) should not be called");
+}
+
+bool
+MemStore::copyFromShm(StoreEntry &e, const MemStoreMap::Extras &extras)
+{
+    const Ipc::Mem::PageId &page = extras.page;
+
+    StoreIOBuffer sourceBuf(extras.storedSize, 0,
+                            static_cast<char*>(PagePointer(page)));
+
+    // XXX: We do not know the URLs yet, only the key, but we need to parse and
+    // store the response for the Root().get() callers to be happy because they
+    // expect IN_MEMORY entries to already have the response headers and body.
+    // At least one caller calls createMemObject() if there is not one, so
+    // we hide the true object until that happens (to avoid leaking TBD URLs).
+    e.createMemObject("TBD", "TBD");
+
+    // emulate the usual Store code but w/o inapplicable checks and callbacks:
+
+    // from store_client::readBody():
+    HttpReply *rep = (HttpReply *)e.getReply();
+    const ssize_t end = headersEnd(sourceBuf.data, sourceBuf.length);
+    if (!rep->parseCharBuf(sourceBuf.data, end)) {
+        debugs(20, DBG_IMPORTANT, "Could not parse mem-cached headers: " << e);
+        return false;
+    }
+    // local memory stores both headers and body
+    e.mem_obj->object_sz = sourceBuf.length; // from StoreEntry::complete()
+
+    storeGetMemSpace(sourceBuf.length); // from StoreEntry::write()
+
+    assert(e.mem_obj->data_hdr.write(sourceBuf)); // from MemObject::write()
+    const int64_t written = e.mem_obj->endOffset();
+    // we should write all because StoreEntry::write() never fails
+    assert(written >= 0 &&
+           static_cast<size_t>(written) == sourceBuf.length);
+    // would be nice to call validLength() here, but it needs e.key
+
+    debugs(20, 7, HERE << "mem-loaded all " << written << " bytes of " << e <<
+           " from " << page);
+
+    e.hideMemObject();
+
+    return true;
+}
+
+void
+MemStore::considerKeeping(StoreEntry &e)
+{
+    if (!e.memoryCachable()) {
+        debugs(20, 7, HERE << "Not memory cachable: " << e);
+        return; // cannot keep due to entry state or properties
+    }
+
+    assert(e.mem_obj);
+    if (!willFit(e.mem_obj->endOffset())) {
+        debugs(20, 5, HERE << "No mem-cache space for " << e);
+        return; // failed to free enough space
+    }
+
+    keep(e); // may still fail
+}
+
+bool
+MemStore::willFit(int64_t need)
+{
+    // TODO: obey configured maximum entry size (with page-based rounding)
+    return need <= static_cast<int64_t>(Ipc::Mem::PageSize());
+}
+
+/// allocates map slot and calls copyToShm to store the entry in shared memory
+void
+MemStore::keep(StoreEntry &e)
+{
+    if (!map) {
+        debugs(20, 5, HERE << "No map to mem-cache " << e);
+        return;
+    }
+
+    sfileno index = 0;
+    Ipc::StoreMapSlot *slot = map->openForWriting(reinterpret_cast<const cache_key *>(e.key), index);
+    if (!slot) {
+        debugs(20, 5, HERE << "No room in mem-cache map to index " << e);
+        return;
+    }
+
+    MemStoreMap::Extras &extras = map->extras(index);
+    if (copyToShm(e, extras)) {
+        slot->set(e);
+        map->closeForWriting(index, false);
+    } else {
+        map->abortIo(index);
+    }
+}
+
+/// uses mem_hdr::copy() to copy local data to shared memory
+bool
+MemStore::copyToShm(StoreEntry &e, MemStoreMap::Extras &extras)
+{
+    Ipc::Mem::PageId page;
+    if (!Ipc::Mem::GetPage(Ipc::Mem::PageId::cachePage, page)) {
+        debugs(20, 5, HERE << "No mem-cache page for " << e);
+        return false; // GetPage is responsible for any cleanup on failures
+    }
+
+    const int64_t bufSize = Ipc::Mem::PageSize();
+    const int64_t eSize = e.mem_obj->endOffset();
+
+    StoreIOBuffer sharedSpace(bufSize, 0,
+                              static_cast<char*>(PagePointer(page)));
+
+    // check that we kept everything or purge incomplete/sparse cached entry
+    const ssize_t copied = e.mem_obj->data_hdr.copy(sharedSpace);
+    if (eSize != copied) {
+        debugs(20, 2, HERE << "Failed to mem-cache " << e << ": " <<
+               eSize << "!=" << copied);
+        // cleanup
+        PutPage(page);
+        return false;
+    }
+
+    debugs(20, 7, HERE << "mem-cached all " << eSize << " bytes of " << e <<
+           " in " << page);
+
+    theCurrentSize += Ipc::Mem::PageSize();
+    // remember storage location and size
+    extras.page = page;
+    extras.storedSize = copied;
+    return true;
+}
+
+void
+MemStore::cleanReadable(const sfileno fileno)
+{
+    Ipc::Mem::PutPage(map->extras(fileno).page);
+    theCurrentSize -= Ipc::Mem::PageSize();
+}
+
+/// calculates maximum number of entries we need to store and map
+int64_t
+MemStore::EntryLimit()
+{
+    if (!Config.memMaxSize)
+        return 0; // no memory cache configured
+
+    const int64_t entrySize = Ipc::Mem::PageSize(); // for now
+    const int64_t entryLimit = Config.memMaxSize / entrySize;
+    return entryLimit;
+}
+
+
+/// initializes shared memory segments used by MemStore
+class MemStoreRr: public Ipc::Mem::RegisteredRunner
+{
+public:
+    /* RegisteredRunner API */
+    MemStoreRr(): owner(NULL) {}
+    virtual void run(const RunnerRegistry &);
+    virtual ~MemStoreRr();
+
+protected:
+    virtual void create(const RunnerRegistry &);
+
+private:
+    MemStoreMap::Owner *owner;
+};
+
+RunnerRegistrationEntry(rrAfterConfig, MemStoreRr);
+
+
+void MemStoreRr::run(const RunnerRegistry &r)
+{
+    // decide whether to use a shared memory cache if the user did not specify
+    if (!Config.memShared.configured()) {
+        Config.memShared.configure(AtomicOperationsSupported &&
+                                   Ipc::Mem::Segment::Enabled() && UsingSmp() &&
+                                   Config.memMaxSize > 0);
+    } else if (Config.memShared && !AtomicOperationsSupported) {
+        // bail if the user wants shared memory cache but we cannot support it
+        fatal("memory_cache_shared is on, but no support for atomic operations detected");
+    } else if (Config.memShared && !Ipc::Mem::Segment::Enabled()) {
+        fatal("memory_cache_shared is on, but no support for shared memory detected");
+    } else if (Config.memShared && !UsingSmp()) {
+        debugs(20, DBG_IMPORTANT, "WARNING: memory_cache_shared is on, but only"
+               " a single worker is running");
+    }
+
+    Ipc::Mem::RegisteredRunner::run(r);
+}
+
+void MemStoreRr::create(const RunnerRegistry &)
+{
+    if (!Config.memShared)
+        return;
+
+    Must(!owner);
+    const int64_t entryLimit = MemStore::EntryLimit();
+    if (entryLimit <= 0)
+        return; // no memory cache configured or a misconfiguration
+    owner = MemStoreMap::Init(ShmLabel, entryLimit);
+}
+
+MemStoreRr::~MemStoreRr()
+{
+    delete owner;
+}
diff -u -r -N squid-3.2.0.12/src/MemStore.h squid-3.2.0.13/src/MemStore.h
--- squid-3.2.0.12/src/MemStore.h	1970-01-01 12:00:00.000000000 +1200
+++ squid-3.2.0.13/src/MemStore.h	2011-10-14 14:42:56.000000000 +1300
@@ -0,0 +1,69 @@
+/*
+ * $Id$
+ */
+
+#ifndef SQUID_MEMSTORE_H
+#define SQUID_MEMSTORE_H
+
+#include "ipc/mem/Page.h"
+#include "ipc/StoreMap.h"
+#include "Store.h"
+
+// StoreEntry restoration info not already stored by Ipc::StoreMap
+struct MemStoreMapExtras {
+    Ipc::Mem::PageId page; ///< shared memory page with the entry content
+    int64_t storedSize; ///< total size of the stored entry content
+};
+typedef Ipc::StoreMapWithExtras<MemStoreMapExtras> MemStoreMap;
+
+/// Stores HTTP entities in RAM. Current implementation uses shared memory.
+/// Unlike a disk store (SwapDir), operations are synchronous (and fast).
+class MemStore: public Store, public Ipc::StoreMapCleaner
+{
+public:
+    MemStore();
+    virtual ~MemStore();
+
+    /// cache the entry or forget about it until the next considerKeeping call
+    void considerKeeping(StoreEntry &e);
+
+    /* Store API */
+    virtual int callback();
+    virtual StoreEntry * get(const cache_key *);
+    virtual void get(String const key , STOREGETCLIENT callback, void *cbdata);
+    virtual void init();
+    virtual uint64_t maxSize() const;
+    virtual uint64_t minSize() const;
+    virtual uint64_t currentSize() const;
+    virtual uint64_t currentCount() const;
+    virtual int64_t maxObjectSize() const;
+    virtual void stat(StoreEntry &) const;
+    virtual StoreSearch *search(String const url, HttpRequest *);
+    virtual void reference(StoreEntry &);
+    virtual bool dereference(StoreEntry &);
+    virtual void maintain();
+
+    static int64_t EntryLimit();
+
+protected:
+    bool willFit(int64_t needed);
+    void keep(StoreEntry &e);
+
+    bool copyToShm(StoreEntry &e, MemStoreMap::Extras &extras);
+    bool copyFromShm(StoreEntry &e, const MemStoreMap::Extras &extras);
+
+    // Ipc::StoreMapCleaner API
+    virtual void cleanReadable(const sfileno fileno);
+
+private:
+    MemStoreMap *map; ///< index of mem-cached entries
+    uint64_t theCurrentSize; ///< currently used space in the storage area
+};
+
+// Why use Store as a base? MemStore and SwapDir are both "caches".
+
+// Why not just use a SwapDir API? That would not help much because Store has
+// to check/update memory cache separately from the disk cache. And same API
+// would hurt because we can support synchronous get/put, unlike the disks.
+
+#endif /* SQUID_MEMSTORE_H */
diff -u -r -N squid-3.2.0.12/src/mgr/FunAction.cc squid-3.2.0.13/src/mgr/FunAction.cc
--- squid-3.2.0.12/src/mgr/FunAction.cc	2011-09-16 23:37:30.000000000 +1200
+++ squid-3.2.0.13/src/mgr/FunAction.cc	2011-10-14 14:42:56.000000000 +1300
@@ -44,9 +44,9 @@
 {
     debugs(16, 5, HERE);
     Must(entry != NULL);
-    if (UsingSmp() && IamWorkerProcess())
+    if (UsingSmp())
         storeAppendPrintf(entry, "by kid%d {\n", KidIdentifier);
     handler(entry);
-    if (atomic() && UsingSmp() && IamWorkerProcess())
+    if (atomic() && UsingSmp())
         storeAppendPrintf(entry, "} by kid%d\n\n", KidIdentifier);
 }
diff -u -r -N squid-3.2.0.12/src/mgr/InfoAction.cc squid-3.2.0.13/src/mgr/InfoAction.cc
--- squid-3.2.0.12/src/mgr/InfoAction.cc	2011-09-16 23:37:30.000000000 +1200
+++ squid-3.2.0.13/src/mgr/InfoAction.cc	2011-10-14 14:42:56.000000000 +1300
@@ -176,10 +176,10 @@
     Must(entry != NULL);
 
 #if XMALLOC_STATISTICS
-    if (UsingSmp() && IamWorkerProcess())
+    if (UsingSmp())
         storeAppendPrintf(entry, "by kid%d {\n", KidIdentifier);
     DumpMallocStatistics(entry);
-    if (UsingSmp() && IamWorkerProcess())
+    if (UsingSmp())
         storeAppendPrintf(entry, "} by kid%d\n\n", KidIdentifier);
 #endif
     if (IamPrimaryProcess())
diff -u -r -N squid-3.2.0.12/src/mime.cc squid-3.2.0.13/src/mime.cc
--- squid-3.2.0.12/src/mime.cc	2011-09-16 23:37:30.000000000 +1200
+++ squid-3.2.0.13/src/mime.cc	2011-10-14 14:42:56.000000000 +1300
@@ -34,6 +34,7 @@
  */
 
 #include "squid.h"
+#include "HttpHdrCc.h"
 #include "Store.h"
 #include "StoreClient.h"
 #include "HttpReply.h"
@@ -462,9 +463,9 @@
 
     reply->setHeaders(HTTP_OK, NULL, mimeGetContentType(icon), sb.st_size, sb.st_mtime, -1);
 
-    reply->cache_control = httpHdrCcCreate();
+    reply->cache_control = new HttpHdrCc();
 
-    httpHdrCcSetMaxAge(reply->cache_control, 86400);
+    reply->cache_control->maxAge(86400);
 
     reply->header.putCc(reply->cache_control);
 
diff -u -r -N squid-3.2.0.12/src/neighbors.cc squid-3.2.0.13/src/neighbors.cc
--- squid-3.2.0.12/src/neighbors.cc	2011-09-16 23:37:30.000000000 +1200
+++ squid-3.2.0.13/src/neighbors.cc	2011-10-14 14:42:56.000000000 +1300
@@ -1025,6 +1025,7 @@
     }
 
     if (entry->lock_count == 0) {
+        // TODO: many entries are unlocked; why is this reported at level 1?
         debugs(12, 1, "neighborsUdpAck: '" << storeKeyText(key) << "' has no locks");
         neighborCountIgnored(p);
         return;
@@ -1419,9 +1420,8 @@
 
     cbdataReferenceDone(psstate->callback_data);
 
-    EBIT_SET(fake->flags, ENTRY_ABORTED);
+    fake->abort(); // sets ENTRY_ABORTED and initiates releated cleanup
     HTTPMSGUNLOCK(fake->mem_obj->request);
-    fake->releaseRequest();
     fake->unlock();
     HTTPMSGUNLOCK(psstate->request);
     cbdataFree(psstate);
@@ -1729,6 +1729,7 @@
     }
 
     if (e->lock_count == 0) {
+        // TODO: many entries are unlocked; why is this reported at level 1?
         debugs(12, 1, "neighborsUdpAck: '" << storeKeyText(key) << "' has no locks");
         neighborCountIgnored(p);
         return;
diff -u -r -N squid-3.2.0.12/src/peer_select.cc squid-3.2.0.13/src/peer_select.cc
--- squid-3.2.0.12/src/peer_select.cc	2011-09-16 23:37:30.000000000 +1200
+++ squid-3.2.0.13/src/peer_select.cc	2011-10-14 14:42:56.000000000 +1300
@@ -177,15 +177,21 @@
     psstate->never_direct = answer;
     switch (answer) {
     case ACCESS_ALLOWED:
-        /** if always_direct says YES, do that. */
-        psstate->direct = DIRECT_YES;
+        /** if never_direct says YES, do that. */
+        psstate->direct = DIRECT_NO;
         debugs(44, 3, HERE << "direct = " << DirectStr[psstate->direct] << " (never_direct allow)");
         break;
     case ACCESS_DENIED: // not relevant.
+    case ACCESS_DUNNO:  // not relevant.
         break;
-    default: // Oops. Failed to get a result.
+    case ACCESS_REQ_PROXY_AUTH:
+#if WHEN_AUTH_CASES_PORT
+    case ACCESS_AUTH_REQUIRED:
+    case ACCESS_AUTH_EXPIRED_OK:
+    case ACCESS_AUTH_EXPIRED_BAD:
+#endif
         debugs(44, DBG_IMPORTANT, "WARNING: never_direct resulted in " << answer << ". Username ACLs are not reliable here.");
-        assert(answer != ACCESS_DUNNO);
+        break;
     }
     peerSelectFoo(psstate);
 }
@@ -204,10 +210,16 @@
         debugs(44, 3, HERE << "direct = " << DirectStr[psstate->direct] << " (always_direct allow)");
         break;
     case ACCESS_DENIED: // not relevant.
+    case ACCESS_DUNNO:  // not relevant.
         break;
-    default: // Oops. Failed to get a result.
+    case ACCESS_REQ_PROXY_AUTH:
+#if WHEN_AUTH_CASES_PORT
+    case ACCESS_AUTH_REQUIRED:
+    case ACCESS_AUTH_EXPIRED_OK:
+    case ACCESS_AUTH_EXPIRED_BAD:
+#endif
         debugs(44, DBG_IMPORTANT, "WARNING: always_direct resulted in " << answer << ". Username ACLs are not reliable here.");
-        assert(answer != ACCESS_DUNNO);
+        break;
     }
     peerSelectFoo(psstate);
 }
diff -u -r -N squid-3.2.0.12/src/protos.h squid-3.2.0.13/src/protos.h
--- squid-3.2.0.12/src/protos.h	2011-09-16 23:37:30.000000000 +1200
+++ squid-3.2.0.13/src/protos.h	2011-10-14 14:42:56.000000000 +1300
@@ -237,13 +237,6 @@
 /* Http Cache Control Header Field */
 SQUIDCEXTERN void httpHdrCcInitModule(void);
 SQUIDCEXTERN void httpHdrCcCleanModule(void);
-SQUIDCEXTERN HttpHdrCc *httpHdrCcCreate(void);
-SQUIDCEXTERN HttpHdrCc *httpHdrCcParseCreate(const String * str);
-SQUIDCEXTERN void httpHdrCcDestroy(HttpHdrCc * cc);
-SQUIDCEXTERN HttpHdrCc *httpHdrCcDup(const HttpHdrCc * cc);
-SQUIDCEXTERN void httpHdrCcPackInto(const HttpHdrCc * cc, Packer * p);
-SQUIDCEXTERN void httpHdrCcSetMaxAge(HttpHdrCc * cc, int max_age);
-SQUIDCEXTERN void httpHdrCcSetSMaxAge(HttpHdrCc * cc, int s_maxage);
 SQUIDCEXTERN void httpHdrCcUpdateStats(const HttpHdrCc * cc, StatHist * hist);
 void httpHdrCcStatDumper(StoreEntry * sentry, int idx, double val, double size, int count);
 
@@ -511,6 +504,14 @@
 SQUIDCEXTERN void storeRebuildComplete(struct _store_rebuild_data *);
 SQUIDCEXTERN void storeRebuildProgress(int sd_index, int total, int sofar);
 
+/// loads entry from disk; fills supplied memory buffer on success
+bool storeRebuildLoadEntry(int fd, int diskIndex, MemBuf &buf, struct _store_rebuild_data &counts);
+/// parses entry buffer and validates entry metadata; fills e on success
+bool storeRebuildParseEntry(MemBuf &buf, StoreEntry &e, cache_key *key, struct _store_rebuild_data &counts, uint64_t expectedSize);
+/// checks whether the loaded entry should be kept; updates counters
+bool storeRebuildKeepEntry(const StoreEntry &e, const cache_key *key, struct _store_rebuild_data &counts);
+
+
 /*
  * store_swapin.c
  */
@@ -559,12 +560,16 @@
 SQUIDCEXTERN bool IamCoordinatorProcess();
 /// whether the current process handles HTTP transactions and such
 SQUIDCEXTERN bool IamWorkerProcess();
+/// whether the current process is dedicated to managing a cache_dir
+bool IamDiskProcess();
 /// Whether we are running in daemon mode
 SQUIDCEXTERN bool InDaemonMode(); // try using specific Iam*() checks above first
 /// Whether there should be more than one worker process running
 SQUIDCEXTERN bool UsingSmp(); // try using specific Iam*() checks above first
 /// number of Kid processes as defined in src/ipc/Kid.h
 SQUIDCEXTERN int NumberOfKids();
+/// a string describing this process roles such as worker or coordinator
+String ProcessRoles();
 SQUIDCEXTERN int DebugSignal;
 
 /* AYJ debugs function to show locations being reset with memset() */
diff -u -r -N squid-3.2.0.12/src/redirect.cc squid-3.2.0.13/src/redirect.cc
--- squid-3.2.0.12/src/redirect.cc	2011-09-16 23:37:30.000000000 +1200
+++ squid-3.2.0.13/src/redirect.cc	2011-10-14 14:42:56.000000000 +1300
@@ -251,7 +251,7 @@
 
     redirectors->cmdline = Config.Program.redirect;
 
-    redirectors->childs = Config.redirectChildren;
+    redirectors->childs.updateLimits(Config.redirectChildren);
 
     redirectors->ipc_type = IPC_STREAM;
 
diff -u -r -N squid-3.2.0.12/src/refresh.cc squid-3.2.0.13/src/refresh.cc
--- squid-3.2.0.12/src/refresh.cc	2011-09-16 23:37:30.000000000 +1200
+++ squid-3.2.0.13/src/refresh.cc	2011-10-14 14:42:56.000000000 +1300
@@ -38,6 +38,7 @@
 #endif
 
 #include "squid.h"
+#include "HttpHdrCc.h"
 #include "mgr/Registration.h"
 #include "Store.h"
 #include "MemObject.h"
@@ -267,14 +268,15 @@
 
     if (request && !request->flags.ignore_cc) {
         const HttpHdrCc *const cc = request->cache_control;
-        if (cc && cc->min_fresh > 0) {
+        if (cc && cc->hasMinFresh()) {
+            const int32_t minFresh=cc->minFresh();
             debugs(22, 3, "\tage + min-fresh:\t" << age << " + " <<
-                   cc->min_fresh << " = " << age + cc->min_fresh);
+                   minFresh << " = " << age + minFresh);
             debugs(22, 3, "\tcheck_time + min-fresh:\t" << check_time << " + "
-                   << cc->min_fresh << " = " <<
-                   mkrfc1123(check_time + cc->min_fresh));
-            age += cc->min_fresh;
-            check_time += cc->min_fresh;
+                   << minFresh << " = " <<
+                   mkrfc1123(check_time + minFresh));
+            age += minFresh;
+            check_time += minFresh;
         }
     }
 
@@ -286,8 +288,8 @@
 
     // stale-if-error requires any failure be passed thru when its period is over.
     if (request && entry->mem_obj && entry->mem_obj->getReply() && entry->mem_obj->getReply()->cache_control &&
-            EBIT_TEST(entry->mem_obj->getReply()->cache_control->mask, CC_STALE_IF_ERROR) &&
-            entry->mem_obj->getReply()->cache_control->stale_if_error < staleness) {
+            entry->mem_obj->getReply()->cache_control->hasStaleIfError() &&
+            entry->mem_obj->getReply()->cache_control->staleIfError() < staleness) {
 
         debugs(22, 3, "refreshCheck: stale-if-error period expired.");
         request->flags.fail_on_validation_err = 1;
@@ -334,31 +336,31 @@
 
 #endif
         if (NULL != cc) {
-            if (cc->max_age > -1) {
+            if (cc->hasMaxAge()) {
 #if USE_HTTP_VIOLATIONS
-                if (R->flags.ignore_reload && cc->max_age == 0) {
+                if (R->flags.ignore_reload && cc->maxAge() == 0) {
                     debugs(22, 3, "refreshCheck: MAYBE: client-max-age = 0 and ignore-reload");
                 } else
 #endif
                 {
-                    if (cc->max_age == 0) {
+                    if (cc->maxAge() == 0) {
                         debugs(22, 3, "refreshCheck: YES: client-max-age = 0");
                         return STALE_EXCEEDS_REQUEST_MAX_AGE_VALUE;
                     }
 
-                    if (age > cc->max_age) {
+                    if (age > cc->maxAge()) {
                         debugs(22, 3, "refreshCheck: YES: age > client-max-age");
                         return STALE_EXCEEDS_REQUEST_MAX_AGE_VALUE;
                     }
                 }
             }
 
-            if (EBIT_TEST(cc->mask, CC_MAX_STALE) && staleness > -1) {
-                if (cc->max_stale < 0) {
+            if (cc->hasMaxStale() && staleness > -1) {
+                if (cc->maxStale()==HttpHdrCc::MAX_STALE_ANY) {
                     /* max-stale directive without a value */
                     debugs(22, 3, "refreshCheck: NO: max-stale wildcard");
                     return FRESH_REQUEST_MAX_STALE_ALL;
-                } else if (staleness < cc->max_stale) {
+                } else if (staleness < cc->maxStale()) {
                     debugs(22, 3, "refreshCheck: NO: staleness < max-stale");
                     return FRESH_REQUEST_MAX_STALE_VALUE;
                 }
diff -u -r -N squid-3.2.0.12/src/Server.cc squid-3.2.0.13/src/Server.cc
--- squid-3.2.0.12/src/Server.cc	2011-09-16 23:37:30.000000000 +1200
+++ squid-3.2.0.13/src/Server.cc	2011-10-14 14:42:56.000000000 +1300
@@ -163,8 +163,10 @@
     assert(rep);
     theFinalReply = HTTPMSGLOCK(rep);
 
-    entry->replaceHttpReply(theFinalReply);
-    haveParsedReplyHeaders();
+    // give entry the reply because haveParsedReplyHeaders() expects it there
+    entry->replaceHttpReply(theFinalReply, false); // but do not write yet
+    haveParsedReplyHeaders(); // update the entry/reply (e.g., set timestamps)
+    entry->startWriting(); // write the updated entry to store
 
     return theFinalReply;
 }
@@ -382,10 +384,10 @@
     }
 
     if (io.flag) {
-        debugs(11, 1, "sentRequestBody error: FD " << io.fd << ": " << xstrerr(errno));
+        debugs(11, 1, "sentRequestBody error: FD " << io.fd << ": " << xstrerr(io.xerrno));
         ErrorState *err;
         err = errorCon(ERR_WRITE_ERROR, HTTP_BAD_GATEWAY, fwd->request);
-        err->xerrno = errno;
+        err->xerrno = io.xerrno;
         fwd->fail(err);
         abortTransaction("I/O error while sending request body");
         return;
@@ -520,7 +522,7 @@
     purgeEntriesByHeader(request, reqUrl, theFinalReply, HDR_CONTENT_LOCATION);
 }
 
-// called (usually by kids) when we have final (possibly adapted) reply headers
+/// called when we have final (possibly adapted) reply headers; kids extend
 void
 ServerStateData::haveParsedReplyHeaders()
 {
diff -u -r -N squid-3.2.0.12/src/snmp_agent.cc squid-3.2.0.13/src/snmp_agent.cc
--- squid-3.2.0.12/src/snmp_agent.cc	2011-09-16 23:37:30.000000000 +1200
+++ squid-3.2.0.13/src/snmp_agent.cc	2011-10-14 14:42:56.000000000 +1300
@@ -67,7 +67,7 @@
 
     case SYSSTOR:
         Answer = snmp_var_new_integer(Var->name, Var->name_length,
-                                      store_swap_size,
+                                      Store::Root().currentSize() >> 10,
                                       ASN_INTEGER);
         break;
 
@@ -131,7 +131,7 @@
 
         case CONF_ST_SWMAXSZ:
             Answer = snmp_var_new_integer(Var->name, Var->name_length,
-                                          (snint) (Store::Root().maxSize() >> 10),
+                                          (snint) (Store::Root().maxSize() >> 20),
                                           ASN_INTEGER);
             break;
 
@@ -531,7 +531,7 @@
 
         case PERF_PROTOSTAT_AGGR_CURSWAP:
             Answer = snmp_var_new_integer(Var->name, Var->name_length,
-                                          (snint) store_swap_size,
+                                          (snint) Store::Root().currentSize() >> 10,
                                           SMI_GAUGE32);
             break;
 
diff -u -r -N squid-3.2.0.12/src/ssl/certificate_db.cc squid-3.2.0.13/src/ssl/certificate_db.cc
--- squid-3.2.0.12/src/ssl/certificate_db.cc	2011-09-16 23:37:30.000000000 +1200
+++ squid-3.2.0.13/src/ssl/certificate_db.cc	2011-10-14 14:42:56.000000000 +1300
@@ -4,6 +4,9 @@
 
 #include "config.h"
 #include "ssl/certificate_db.h"
+#if HAVE_ERRNO_H
+#include <errno.h>
+#endif
 #if HAVE_FSTREAM
 #include <fstream>
 #endif
@@ -20,33 +23,86 @@
 #include <fcntl.h>
 #endif
 
-Ssl::FileLocker::FileLocker(std::string const & filename)
-        :    fd(-1)
+#define HERE "(ssl_crtd) " << __FILE__ << ':' << __LINE__ << ": "
+
+Ssl::Lock::Lock(std::string const &aFilename) :
+        filename(aFilename),
+#if _SQUID_MSWIN_
+        hFile(INVALID_HANDLE_VALUE)
+#else
+        fd(-1)
+#endif
+{
+}
+
+bool Ssl::Lock::locked() const
+{
+#if _SQUID_MSWIN_
+    return hFile != INVALID_HANDLE_VALUE;
+#else
+    return fd != -1;
+#endif
+}
+
+void Ssl::Lock::lock()
 {
+
 #if _SQUID_MSWIN_
     hFile = CreateFile(TEXT(filename.c_str()), GENERIC_READ, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
-    if (hFile != INVALID_HANDLE_VALUE)
-        LockFile(hFile, 0, 0, 1, 0);
+    if (hFile == INVALID_HANDLE_VALUE)
 #else
     fd = open(filename.c_str(), 0);
-    if (fd != -1)
-        flock(fd, LOCK_EX);
+    if (fd == -1)
 #endif
+        throw std::runtime_error("Failed to open file " + filename);
+
+
+#if _SQUID_MSWIN_
+    if (!LockFile(hFile, 0, 0, 1, 0))
+#else
+    if (flock(fd, LOCK_EX) != 0)
+#endif
+        throw std::runtime_error("Failed to get a lock of " + filename);
 }
 
-Ssl::FileLocker::~FileLocker()
+void Ssl::Lock::unlock()
 {
 #if _SQUID_MSWIN_
     if (hFile != INVALID_HANDLE_VALUE) {
         UnlockFile(hFile, 0, 0, 1, 0);
         CloseHandle(hFile);
+        hFile = INVALID_HANDLE_VALUE;
     }
 #else
     if (fd != -1) {
         flock(fd, LOCK_UN);
         close(fd);
+        fd = -1;
     }
 #endif
+    else
+        throw std::runtime_error("Lock is already unlocked for " + filename);
+}
+
+Ssl::Lock::~Lock()
+{
+    if (locked())
+        unlock();
+}
+
+Ssl::Locker::Locker(Lock &aLock, const char *aFileName, int aLineNo):
+        weLocked(false), lock(aLock), fileName(aFileName), lineNo(aLineNo)
+{
+    if (!lock.locked()) {
+        lock.lock();
+        weLocked = true;
+    }
+}
+
+Ssl::Locker::~Locker()
+{
+    if (weLocked)
+        lock.unlock();
 }
 
 Ssl::CertificateDb::Row::Row()
@@ -130,26 +186,26 @@
         db(NULL),
         max_db_size(aMax_db_size),
         fs_block_size(aFs_block_size),
+        dbLock(db_full),
+        dbSerialLock(serial_full),
         enabled_disk_store(true)
 {
     if (db_path.empty() && !max_db_size)
         enabled_disk_store = false;
     else if ((db_path.empty() && max_db_size) || (!db_path.empty() && !max_db_size))
         throw std::runtime_error("ssl_crtd is missing the required parameter. There should be -s and -M parameters together.");
-    else
-        load();
 }
 
 bool Ssl::CertificateDb::find(std::string const & host_name, Ssl::X509_Pointer & cert, Ssl::EVP_PKEY_Pointer & pkey)
 {
-    FileLocker db_locker(db_full);
+    const Locker locker(dbLock, Here);
     load();
     return pure_find(host_name, cert, pkey);
 }
 
 bool Ssl::CertificateDb::addCertAndPrivateKey(Ssl::X509_Pointer & cert, Ssl::EVP_PKEY_Pointer & pkey)
 {
-    FileLocker db_locker(db_full);
+    const Locker locker(dbLock, Here);
     load();
     if (!db || !cert || !pkey || min_db_size > max_db_size)
         return false;
@@ -195,7 +251,6 @@
 
     row.reset();
     std::string filename(cert_full + "/" + serial_string + ".pem");
-    FileLocker cert_locker(filename);
     if (!writeCertAndPrivateKeyToFile(cert, pkey, filename.c_str()))
         return false;
     addSize(filename);
@@ -206,7 +261,7 @@
 
 BIGNUM * Ssl::CertificateDb::getCurrentSerialNumber()
 {
-    FileLocker serial_locker(serial_full);
+    const Locker locker(dbSerialLock, Here);
     // load serial number from file.
     Ssl::BIO_Pointer file(BIO_new(BIO_s_file()));
     if (!file)
@@ -297,11 +352,12 @@
 void Ssl::CertificateDb::check(std::string const & db_path, size_t max_db_size)
 {
     CertificateDb db(db_path, max_db_size, 0);
+    db.load();
 }
 
 std::string Ssl::CertificateDb::getSNString() const
 {
-    FileLocker serial_locker(serial_full);
+    const Locker locker(dbSerialLock, Here);
     std::ifstream file(serial_full.c_str());
     if (!file)
         return "";
@@ -329,7 +385,6 @@
 
     // read cert and pkey from file.
     std::string filename(cert_full + "/" + rrow[cnlSerial] + ".pem");
-    FileLocker cert_locker(filename);
     readCertAndPrivateKeyFromFiles(cert, pkey, filename.c_str(), NULL);
     if (!cert || !pkey)
         return false;
@@ -338,19 +393,16 @@
 
 size_t Ssl::CertificateDb::size() const
 {
-    FileLocker size_locker(size_full);
     return readSize();
 }
 
 void Ssl::CertificateDb::addSize(std::string const & filename)
 {
-    FileLocker size_locker(size_full);
     writeSize(readSize() + getFileSize(filename));
 }
 
 void Ssl::CertificateDb::subSize(std::string const & filename)
 {
-    FileLocker size_locker(size_full);
     writeSize(readSize() - getFileSize(filename));
 }
 
@@ -427,6 +479,34 @@
         throw std::runtime_error("Failed to write " + db_full + " file");
 }
 
+// Normally defined in defines.h file
+#define countof(arr) (sizeof(arr)/sizeof(*arr))
+void Ssl::CertificateDb::deleteRow(const char **row, int rowIndex)
+{
+    const std::string filename(cert_full + "/" + row[cnlSerial] + ".pem");
+#if OPENSSL_VERSION_NUMBER >= 0x1000004fL
+    sk_OPENSSL_PSTRING_delete(db.get()->data, rowIndex);
+#else
+    sk_delete(db.get()->data, rowIndex);
+#endif
+
+    const Columns db_indexes[]={cnlSerial, cnlName};
+    for (unsigned int i = 0; i < countof(db_indexes); i++) {
+#if OPENSSL_VERSION_NUMBER >= 0x1000004fL
+        if (LHASH_OF(OPENSSL_STRING) *fieldIndex =  db.get()->index[db_indexes[i]])
+            lh_OPENSSL_STRING_delete(fieldIndex, (char **)row);
+#else
+        if (LHASH *fieldIndex = db.get()->index[db_indexes[i]])
+            lh_delete(fieldIndex, row);
+#endif
+    }
+
+    subSize(filename);
+    int ret = remove(filename.c_str());
+    if (ret < 0)
+        throw std::runtime_error("Failed to remove certficate file " + filename + " from db");
+}
+
 bool Ssl::CertificateDb::deleteInvalidCertificate()
 {
     if (!db)
@@ -442,15 +522,7 @@
 #endif
 
         if (!sslDateIsInTheFuture(current_row[cnlExp_date])) {
-            std::string filename(cert_full + "/" + current_row[cnlSerial] + ".pem");
-            FileLocker cert_locker(filename);
-#if OPENSSL_VERSION_NUMBER >= 0x1000004fL
-            sk_OPENSSL_PSTRING_delete(db.get()->data, i);
-#else
-            sk_delete(db.get()->data, i);
-#endif
-            subSize(filename);
-            remove(filename.c_str());
+            deleteRow(current_row, i);
             removed_one = true;
             break;
         }
@@ -478,17 +550,8 @@
 #else
     const char **row = (const char **)sk_value(db.get()->data, 0);
 #endif
-    std::string filename(cert_full + "/" + row[cnlSerial] + ".pem");
-    FileLocker cert_locker(filename);
-
-#if OPENSSL_VERSION_NUMBER >= 0x1000004fL
-    sk_OPENSSL_PSTRING_delete(db.get()->data, 0);
-#else
-    sk_delete(db.get()->data, 0);
-#endif
 
-    subSize(filename);
-    remove(filename.c_str());
+    deleteRow(row, 0);
 
     return true;
 }
@@ -506,15 +569,7 @@
         const char ** current_row = ((const char **)sk_value(db.get()->data, i));
 #endif
         if (host == current_row[cnlName]) {
-            std::string filename(cert_full + "/" + current_row[cnlSerial] + ".pem");
-            FileLocker cert_locker(filename);
-#if OPENSSL_VERSION_NUMBER >= 0x1000004fL
-            sk_OPENSSL_PSTRING_delete(db.get()->data, i);
-#else
-            sk_delete(db.get()->data, i);
-#endif
-            subSize(filename);
-            remove(filename.c_str());
+            deleteRow(current_row, i);
             return true;
         }
     }
diff -u -r -N squid-3.2.0.12/src/ssl/certificate_db.h squid-3.2.0.13/src/ssl/certificate_db.h
--- squid-3.2.0.12/src/ssl/certificate_db.h	2011-09-16 23:37:30.000000000 +1200
+++ squid-3.2.0.13/src/ssl/certificate_db.h	2011-10-14 14:42:56.000000000 +1300
@@ -16,15 +16,18 @@
 
 namespace Ssl
 {
-/// Cross platform file locker.
-class FileLocker
+/// maintains an exclusive blocking file-based lock
+class Lock
 {
 public:
-    /// Lock file
-    FileLocker(std::string const & aFilename);
-    /// Unlock file
-    ~FileLocker();
+    explicit Lock(std::string const &filename); ///<  creates an unlocked lock
+    ~Lock(); ///<  releases the lock if it is locked
+    void lock(); ///<  locks the lock, may block
+    void unlock(); ///<  unlocks locked lock or throws
+    bool locked() const; ///<  whether our lock is locked
+    const char *name() const { return filename.c_str(); }
 private:
+    std::string filename;
 #if _SQUID_MSWIN_
     HANDLE hFile; ///< Windows file handle.
 #else
@@ -32,6 +35,24 @@
 #endif
 };
 
+/// an exception-safe way to obtain and release a lock
+class Locker
+{
+public:
+    /// locks the lock if the lock was unlocked
+    Locker(Lock &lock, const char  *aFileName, int lineNo);
+    /// unlocks the lock if it was locked by us
+    ~Locker();
+private:
+    bool weLocked; ///<  whether we locked the lock
+    Lock &lock; ///<  the lock we are operating on
+    const std::string fileName; ///<  where the lock was needed
+    const int lineNo; ///<  where the lock was needed
+};
+
+/// convenience macro to pass source code location to Locker and others
+#define Here __FILE__, __LINE__
+
 /**
  * Database class for storing SSL certificates and their private keys.
  * A database consist by:
@@ -98,6 +119,7 @@
     /// Only find certificate in current db and return it.
     bool pure_find(std::string const & host_name, Ssl::X509_Pointer & cert, Ssl::EVP_PKEY_Pointer & pkey);
 
+    void deleteRow(const char **row, int rowIndex); ///< Delete a row from TXT_DB
     bool deleteInvalidCertificate(); ///< Delete invalid certificate.
     bool deleteOldestCertificate(); ///< Delete oldest certificate.
     bool deleteByHostname(std::string const & host); ///< Delete using host name.
@@ -149,6 +171,8 @@
     TXT_DB_Pointer db; ///< Database with certificates info.
     const size_t max_db_size; ///< Max size of db.
     const size_t fs_block_size; ///< File system block size.
+    mutable Lock dbLock;  ///< protects the database file
+    mutable Lock dbSerialLock; ///< protects the serial number file
 
     bool enabled_disk_store; ///< The storage on the disk is enabled.
 };
diff -u -r -N squid-3.2.0.12/src/ssl/helper.cc squid-3.2.0.13/src/ssl/helper.cc
--- squid-3.2.0.12/src/ssl/helper.cc	2011-09-16 23:37:30.000000000 +1200
+++ squid-3.2.0.13/src/ssl/helper.cc	2011-10-14 14:42:56.000000000 +1300
@@ -40,7 +40,7 @@
         return;
 
     ssl_crtd = new helper("ssl_crtd");
-    ssl_crtd->childs = Ssl::TheConfig.ssl_crtdChildren;
+    ssl_crtd->childs.updateLimits(Ssl::TheConfig.ssl_crtdChildren);
     ssl_crtd->ipc_type = IPC_STREAM;
     // The crtd messages may contain the eol ('\n') character. We are
     // going to use the '\1' char as the end-of-message mark.
diff -u -r -N squid-3.2.0.12/src/stat.cc squid-3.2.0.13/src/stat.cc
--- squid-3.2.0.12/src/stat.cc	2011-09-16 23:37:30.000000000 +1200
+++ squid-3.2.0.13/src/stat.cc	2011-10-14 14:42:56.000000000 +1300
@@ -548,14 +548,16 @@
     stats.request_hit_disk_ratio5 = statRequestHitDiskRatio(5);
     stats.request_hit_disk_ratio60 = statRequestHitDiskRatio(60);
 
-    stats.store_swap_size = store_swap_size;
+    stats.store_swap_size = Store::Root().currentSize() / 1024.0;
     stats.store_swap_max_size = Store::Root().maxSize();
 
     stats.store_mem_size = mem_node::StoreMemSize();
     stats.store_pages_max = store_pages_max;
     stats.store_mem_used = mem_node::InUseCount();
 
-    stats.objects_size = n_disk_objects ? (double) store_swap_size / n_disk_objects : 0.0;
+    stats.n_disk_objects = Store::Root().currentCount();
+    stats.objects_size = stats.n_disk_objects > 0 ?
+                         stats.store_swap_size / stats.n_disk_objects : 0.0;
 
     stats.unlink_requests = statCounter.unlink.requests;
 
@@ -668,7 +670,6 @@
     stats.store_entries = StoreEntry::inUseCount();
     stats.store_mem_entries = MemObject::inUseCount();
     stats.hot_obj_count = hot_obj_count;
-    stats.n_disk_objects = n_disk_objects;
 }
 
 void
diff -u -r -N squid-3.2.0.12/src/stmem.cc squid-3.2.0.13/src/stmem.cc
--- squid-3.2.0.12/src/stmem.cc	2011-09-16 23:37:30.000000000 +1200
+++ squid-3.2.0.13/src/stmem.cc	2011-10-14 14:42:56.000000000 +1300
@@ -85,6 +85,7 @@
 {
     nodes.destroy(SplayNode<mem_node *>::DefaultFree);
     inmem_hi = 0;
+    debugs(19, 9, HERE << this << " hi: " << inmem_hi);
 }
 
 bool
@@ -144,12 +145,15 @@
 
     memcpy(aNode->nodeBuffer.data + aNode->nodeBuffer.length, source, copyLen);
 
+    debugs(19, 9, HERE << this << " hi: " << inmem_hi);
     if (inmem_hi <= location)
         inmem_hi = location + copyLen;
 
     /* Adjust the ptr and len according to what was deposited in the page */
     aNode->nodeBuffer.length += copyLen;
 
+    debugs(19, 9, HERE << this << " hi: " << inmem_hi);
+    debugs(19, 9, HERE << this << " hi: " << endOffset());
     return copyLen;
 }
 
@@ -176,7 +180,7 @@
 void
 mem_hdr::internalAppend(const char *data, int len)
 {
-    debugs(19, 6, "memInternalAppend: len " << len);
+    debugs(19, 6, "memInternalAppend: " << this << " len " << len);
 
     while (len > 0) {
         makeAppendSpace();
@@ -194,6 +198,7 @@
 mem_node *
 mem_hdr::getBlockContainingLocation (int64_t location) const
 {
+    // Optimize: do not create a whole mem_node just to store location
     mem_node target (location);
     target.nodeBuffer.length = 1;
     mem_node *const *result = nodes.find (&target, NodeCompare);
@@ -245,7 +250,7 @@
 {
 
     assert(target.range().end > target.range().start);
-    debugs(19, 6, "memCopy: " << target.range());
+    debugs(19, 6, "memCopy: " << this << " " << target.range());
 
     /* we shouldn't ever ask for absent offsets */
 
@@ -361,7 +366,7 @@
 mem_hdr::write (StoreIOBuffer const &writeBuffer)
 {
     PROF_start(mem_hdr_write);
-    debugs(19, 6, "mem_hdr::write: " << writeBuffer.range() << " object end " << endOffset());
+    debugs(19, 6, "mem_hdr::write: " << this << " " << writeBuffer.range() << " object end " << endOffset());
 
     if (unionNotEmpty(writeBuffer)) {
         debugs(19,0,"mem_hdr::write: writeBuffer: " << writeBuffer.range());
@@ -391,7 +396,9 @@
 }
 
 mem_hdr::mem_hdr() : inmem_hi(0)
-{}
+{
+    debugs(19, 9, HERE << this << " hi: " << inmem_hi);
+}
 
 mem_hdr::~mem_hdr()
 {
diff -u -r -N squid-3.2.0.12/src/store.cc squid-3.2.0.13/src/store.cc
--- squid-3.2.0.12/src/store.cc	2011-09-16 23:37:30.000000000 +1200
+++ squid-3.2.0.13/src/store.cc	2011-10-14 14:42:56.000000000 +1300
@@ -49,6 +49,7 @@
 #include "mem_node.h"
 #include "StoreMeta.h"
 #include "SwapDir.h"
+#include "StoreIOState.h"
 #if USE_DELAY_POOLS
 #include "DelayPools.h"
 #endif
@@ -256,6 +257,16 @@
 
     }
 
+    if (fd_table[conn->fd].closing()) {
+        // Readers must have closing callbacks if they want to be notified. No
+        // readers appeared to care around 2009/12/14 as they skipped reading
+        // for other reasons. Closing may already be true at the delyaAwareRead
+        // call time or may happen while we wait after delayRead() above.
+        debugs(20, 3, HERE << "wont read from closing " << conn << " for " <<
+               callback);
+        return; // the read callback will never be called
+    }
+
     comm_read(conn, buf, amountToRead, callback);
 }
 
@@ -305,6 +316,13 @@
      * offset 0 in the memory object is the HTTP headers.
      */
 
+    if (mem_status == IN_MEMORY && UsingSmp()) {
+        // clients of an object cached in shared memory are memory clients
+        return STORE_MEM_CLIENT;
+    }
+
+    assert(mem_obj);
+
     if (mem_obj->inmem_lo)
         return STORE_DISK_CLIENT;
 
@@ -319,6 +337,7 @@
 
         if (mem_obj->inmem_lo == 0 && !isEmpty()) {
             if (swap_status == SWAPOUT_DONE) {
+                debugs(20,7, HERE << mem_obj << " lo: " << mem_obj->inmem_lo << " hi: " << mem_obj->endOffset() << " size: " << mem_obj->object_sz);
                 if (mem_obj->endOffset() == mem_obj->object_sz) {
                     /* hot object fully swapped in */
                     return STORE_MEM_CLIENT;
@@ -354,28 +373,43 @@
     return STORE_DISK_CLIENT;
 }
 
-StoreEntry::StoreEntry()
+StoreEntry::StoreEntry():
+        hidden_mem_obj(NULL),
+        swap_file_sz(0)
 {
     debugs(20, 3, HERE << "new StoreEntry " << this);
     mem_obj = NULL;
 
     expires = lastmod = lastref = timestamp = -1;
 
+    swap_status = SWAPOUT_NONE;
     swap_filen = -1;
     swap_dirn = -1;
 }
 
-StoreEntry::StoreEntry(const char *aUrl, const char *aLogUrl)
+StoreEntry::StoreEntry(const char *aUrl, const char *aLogUrl):
+        hidden_mem_obj(NULL),
+        swap_file_sz(0)
 {
     debugs(20, 3, HERE << "new StoreEntry " << this);
     mem_obj = new MemObject(aUrl, aLogUrl);
 
     expires = lastmod = lastref = timestamp = -1;
 
+    swap_status = SWAPOUT_NONE;
     swap_filen = -1;
     swap_dirn = -1;
 }
 
+StoreEntry::~StoreEntry()
+{
+    if (swap_filen >= 0) {
+        SwapDir &sd = dynamic_cast<SwapDir&>(*store());
+        sd.disconnect(*this);
+    }
+    delete hidden_mem_obj;
+}
+
 void
 StoreEntry::destroyMemObject()
 {
@@ -384,6 +418,18 @@
     MemObject *mem = mem_obj;
     mem_obj = NULL;
     delete mem;
+    delete hidden_mem_obj;
+    hidden_mem_obj = NULL;
+}
+
+void
+StoreEntry::hideMemObject()
+{
+    debugs(20, 3, HERE << "hiding " << mem_obj);
+    assert(mem_obj);
+    assert(!hidden_mem_obj);
+    hidden_mem_obj = mem_obj;
+    mem_obj = NULL;
 }
 
 void
@@ -504,22 +550,15 @@
 
     assert(storePendingNClients(this) == 0);
 
-    if (EBIT_TEST(flags, RELEASE_REQUEST))
+    if (EBIT_TEST(flags, RELEASE_REQUEST)) {
         this->release();
-    else if (keepInMemory()) {
-        Store::Root().dereference(*this);
-        setMemStatus(IN_MEMORY);
-        mem_obj->unlinkRequest();
-    } else {
-        Store::Root().dereference(*this);
-
-        if (EBIT_TEST(flags, KEY_PRIVATE))
-            debugs(20, 1, "WARNING: " << __FILE__ << ":" << __LINE__ << ": found KEY_PRIVATE");
-
-        /* StoreEntry::purgeMem may free e */
-        purgeMem();
+        return 0;
     }
 
+    if (EBIT_TEST(flags, KEY_PRIVATE))
+        debugs(20, 1, "WARNING: " << __FILE__ << ":" << __LINE__ << ": found KEY_PRIVATE");
+
+    Store::Root().handleIdleEntry(*this); // may delete us
     return 0;
 }
 
@@ -687,6 +726,8 @@
             }
         }
 
+        // TODO: storeGetPublic() calls below may create unlocked entries.
+        // We should add/use storeHas() API or lock/unlock those entries.
         if (mem_obj->vary_headers && !storeGetPublic(mem_obj->url, mem_obj->method)) {
             /* Create "vary" base object */
             String vary;
@@ -776,9 +817,6 @@
 
     e->store_status = STORE_PENDING;
     e->setMemStatus(NOT_IN_MEMORY);
-    e->swap_status = SWAPOUT_NONE;
-    e->swap_filen = -1;
-    e->swap_dirn = -1;
     e->refcount = 0;
     e->lastref = squid_curtime;
     e->timestamp = -1;          /* set in StoreEntry::timestampsSet() */
@@ -925,6 +963,8 @@
     return 0;
 }
 
+// TODO: remove checks already performed by swapoutPossible()
+// TODO: move "too many open..." checks outside -- we are called too early/late
 int
 StoreEntry::checkCachable()
 {
@@ -1081,16 +1121,6 @@
 
     store_status = STORE_OK;
 
-    /*
-     * We assign an object length here.  The only other place we assign
-     * the object length is in storeComplete()
-     */
-    /* RBC: What do we need an object length for? we've just aborted the
-     * request, the request is private and negatively cached. Surely
-     * the object length is inappropriate to set.
-     */
-    mem_obj->object_sz = mem_obj->endOffset();
-
     /* Notify the server side */
 
     /*
@@ -1114,8 +1144,8 @@
     /* Notify the client side */
     invokeHandlers();
 
-    /* Close any swapout file */
-    swapOutFileClose();
+    // abort swap out, invalidating what was created so far (release follows)
+    swapOutFileClose(StoreIOState::writerGone);
 
     unlock();       /* unlock */
 }
@@ -1204,10 +1234,11 @@
 
     /* this should be emitted by the oversize dir, not globally */
 
-    if (store_swap_size > Store::Root().maxSize()) {
+    if (Store::Root().currentSize() > Store::Root().maxSize()) {
         if (squid_curtime - last_warn_time > 10) {
-            debugs(20, 0, "WARNING: Disk space over limit: " << store_swap_size << " KB > "
-                   << Store::Root().maxSize() << " KB");
+            debugs(20, DBG_CRITICAL, "WARNING: Disk space over limit: "
+                   << Store::Root().currentSize() / 1024.0 << " KB > "
+                   << (Store::Root().maxSize() >> 10) << " KB");
             last_warn_time = squid_curtime;
         }
     }
@@ -1246,31 +1277,23 @@
             lock_count++;
             setReleaseFlag();
             LateReleaseStack.push_back(this);
-            PROF_stop(storeRelease);
-            return;
         } else {
             destroyStoreEntry(static_cast<hash_link *>(this));
+            // "this" is no longer valid
         }
+
+        PROF_stop(storeRelease);
+        return;
     }
 
     storeLog(STORE_LOG_RELEASE, this);
 
     if (swap_filen > -1) {
-        unlink();
-
-        if (swap_status == SWAPOUT_DONE)
-            if (EBIT_TEST(flags, ENTRY_VALIDATED))
-                store()->updateSize(swap_file_sz, -1);
-
+        // log before unlink() below clears swap_filen
         if (!EBIT_TEST(flags, KEY_PRIVATE))
             storeDirSwapLog(this, SWAP_LOG_DEL);
 
-#if 0
-        /* From 2.4. I think we do this in storeUnlink? */
-        storeSwapFileNumberSet(this, -1);
-
-#endif
-
+        unlink();
     }
 
     setMemStatus(NOT_IN_MEMORY);
@@ -1291,7 +1314,7 @@
     }
 
     for (i = 0; i < 10; i++) {
-        e = LateReleaseStack.pop();
+        e = LateReleaseStack.count ? LateReleaseStack.pop() : NULL;
 
         if (e == NULL) {
             /* done! */
@@ -1406,8 +1429,8 @@
     store_pages_max = Config.memMaxSize / sizeof(mem_node);
 }
 
-int
-StoreEntry::keepInMemory() const
+bool
+StoreEntry::memoryCachable() const
 {
     if (mem_obj == NULL)
         return 0;
@@ -1421,6 +1444,14 @@
     if (!Config.onoff.memory_cache_first && swap_status == SWAPOUT_DONE && refcount == 1)
         return 0;
 
+    if (UsingSmp()) {
+        const int64_t expectedSize = mem_obj->expectedReplySize();
+        // objects of unknown size are not allowed into memory cache, for now
+        if (expectedSize < 0 ||
+                expectedSize > static_cast<int64_t>(Config.Store.maxInMemObjSize))
+            return 0;
+    }
+
     return 1;
 }
 
@@ -1596,6 +1627,15 @@
     if (new_status == mem_status)
         return;
 
+    if (UsingSmp()) {
+        assert(new_status != IN_MEMORY); // we do not call this otherwise
+        // This method was designed to update replacement policy, not to
+        // actually purge something from the memory cache (TODO: rename?).
+        // Shared memory cache does not have a policy that needs updates.
+        mem_status = new_status;
+        return;
+    }
+
     assert(mem_obj != NULL);
 
     if (new_status == IN_MEMORY) {
@@ -1605,10 +1645,10 @@
             debugs(20, 4, "StoreEntry::setMemStatus: not inserting special " << mem_obj->url << " into policy");
         } else {
             mem_policy->Add(mem_policy, this, &mem_obj->repl);
-            debugs(20, 4, "StoreEntry::setMemStatus: inserted mem node " << mem_obj->url);
+            debugs(20, 4, "StoreEntry::setMemStatus: inserted mem node " << mem_obj->url << " key: " << getMD5Text());
         }
 
-        hot_obj_count++;
+        hot_obj_count++; // TODO: maintain for the shared hot cache as well
     } else {
         if (EBIT_TEST(flags, ENTRY_SPECIAL)) {
             debugs(20, 4, "StoreEntry::setMemStatus: special entry " << mem_obj->url);
@@ -1640,6 +1680,14 @@
     if (mem_obj)
         return;
 
+    if (hidden_mem_obj) {
+        debugs(20, 3, HERE << "restoring " << hidden_mem_obj);
+        mem_obj = hidden_mem_obj;
+        hidden_mem_obj = NULL;
+        mem_obj->resetUrls(aUrl, aLogUrl);
+        return;
+    }
+
     mem_obj = new MemObject(aUrl, aLogUrl);
 }
 
@@ -1781,10 +1829,9 @@
  * a new reply. This eats the reply.
  */
 void
-StoreEntry::replaceHttpReply(HttpReply *rep)
+StoreEntry::replaceHttpReply(HttpReply *rep, bool andStartWriting)
 {
     debugs(20, 3, "StoreEntry::replaceHttpReply: " << url());
-    Packer p;
 
     if (!mem_obj) {
         debugs(20, 0, "Attempt to replace object with no in-memory representation");
@@ -1793,18 +1840,31 @@
 
     mem_obj->replaceHttpReply(rep);
 
+    if (andStartWriting)
+        startWriting();
+}
+
+
+void
+StoreEntry::startWriting()
+{
+    Packer p;
+
     /* TODO: when we store headers serparately remove the header portion */
     /* TODO: mark the length of the headers ? */
     /* We ONLY want the headers */
     packerToStoreInit(&p, this);
 
     assert (isEmpty());
+    assert(mem_obj);
 
-    getReply()->packHeadersInto(&p);
+    const HttpReply *rep = getReply();
+    assert(rep);
 
-    rep->hdr_sz = mem_obj->endOffset();
+    rep->packHeadersInto(&p);
+    mem_obj->markEndOfReplyHeaders();
 
-    httpBodyPackInto(&getReply()->body, &p);
+    httpBodyPackInto(&rep->body, &p);
 
     packerClean(&p);
 }
@@ -1825,21 +1885,87 @@
 bool
 StoreEntry::swapoutPossible()
 {
+    if (!Config.cacheSwap.n_configured)
+        return false;
+
     /* should we swap something out to disk? */
     debugs(20, 7, "storeSwapOut: " << url());
     debugs(20, 7, "storeSwapOut: store_status = " << storeStatusStr[store_status]);
 
+    assert(mem_obj);
+    MemObject::SwapOut::Decision &decision = mem_obj->swapout.decision;
+
+    // if we decided that swapout is not possible, do not repeat same checks
+    if (decision == MemObject::SwapOut::swImpossible) {
+        debugs(20, 3, "storeSwapOut: already rejected");
+        return false;
+    }
+
+    // this flag may change so we must check it even if we already said "yes"
     if (EBIT_TEST(flags, ENTRY_ABORTED)) {
         assert(EBIT_TEST(flags, RELEASE_REQUEST));
-        swapOutFileClose();
+        // StoreEntry::abort() already closed the swap out file, if any
+        decision = MemObject::SwapOut::swImpossible;
+        return false;
+    }
+
+    // if we decided that swapout is possible, do not repeat same checks
+    if (decision == MemObject::SwapOut::swPossible) {
+        debugs(20, 3, "storeSwapOut: already allowed");
+        return true;
+    }
+
+    // if we are swapping out already, do not repeat same checks
+    if (swap_status != SWAPOUT_NONE) {
+        debugs(20, 3, "storeSwapOut: already started");
+        decision = MemObject::SwapOut::swPossible;
+        return true;
+    }
+
+    if (!checkCachable()) {
+        debugs(20, 3, "storeSwapOut: not cachable");
+        decision = MemObject::SwapOut::swImpossible;
         return false;
     }
 
     if (EBIT_TEST(flags, ENTRY_SPECIAL)) {
         debugs(20, 3, "storeSwapOut: " << url() << " SPECIAL");
+        decision = MemObject::SwapOut::swImpossible;
         return false;
     }
 
+    // check cache_dir max-size limit if all cache_dirs have it
+    if (store_maxobjsize >= 0) {
+        // TODO: add estimated store metadata size to be conservative
+
+        // use guaranteed maximum if it is known
+        const int64_t expectedEnd = mem_obj->expectedReplySize();
+        debugs(20, 7, "storeSwapOut: expectedEnd = " << expectedEnd);
+        if (expectedEnd > store_maxobjsize) {
+            debugs(20, 3, "storeSwapOut: will not fit: " << expectedEnd <<
+                   " > " << store_maxobjsize);
+            decision = MemObject::SwapOut::swImpossible;
+            return false; // known to outgrow the limit eventually
+        }
+
+        // use current minimum (always known)
+        const int64_t currentEnd = mem_obj->endOffset();
+        if (currentEnd > store_maxobjsize) {
+            debugs(20, 3, "storeSwapOut: does not fit: " << currentEnd <<
+                   " > " << store_maxobjsize);
+            decision = MemObject::SwapOut::swImpossible;
+            return false; // already does not fit and may only get bigger
+        }
+
+        // prevent default swPossible answer for yet unknown length
+        if (expectedEnd < 0) {
+            debugs(20, 3, "storeSwapOut: wait for more info: " <<
+                   store_maxobjsize);
+            return false; // may fit later, but will be rejected now
+        }
+    }
+
+    decision = MemObject::SwapOut::swPossible;
     return true;
 }
 
@@ -1956,7 +2082,7 @@
     return matched;
 }
 
-StorePointer
+SwapDir::Pointer
 StoreEntry::store() const
 {
     assert(0 <= swap_dirn && swap_dirn < Config.cacheSwap.n_configured);
@@ -1966,7 +2092,10 @@
 void
 StoreEntry::unlink()
 {
-    store()->unlink(*this);
+    store()->unlink(*this); // implies disconnect()
+    swap_filen = -1;
+    swap_dirn = -1;
+    swap_status = SWAPOUT_NONE;
 }
 
 /*
@@ -1985,6 +2114,13 @@
     return true;
 }
 
+std::ostream &operator <<(std::ostream &os, const StoreEntry &e)
+{
+    return os << e.swap_filen << '@' << e.swap_dirn << '=' <<
+           e.mem_status << '/' << e.ping_status << '/' << e.store_status << '/' <<
+           e.swap_status;
+}
+
 /* NullStoreEntry */
 
 NullStoreEntry NullStoreEntry::_instance;
diff -u -r -N squid-3.2.0.12/src/store_client.cc squid-3.2.0.13/src/store_client.cc
--- squid-3.2.0.12/src/store_client.cc	2011-09-16 23:37:30.000000000 +1200
+++ squid-3.2.0.13/src/store_client.cc	2011-10-14 14:42:56.000000000 +1300
@@ -591,9 +591,14 @@
 
     storeSwapTLVFree(tlv_list);
 
+    assert(swap_hdr_sz >= 0);
+    assert(entry->swap_file_sz > 0);
+    assert(entry->swap_file_sz >= static_cast<uint64_t>(swap_hdr_sz));
     entry->mem_obj->swap_hdr_sz = swap_hdr_sz;
     entry->mem_obj->object_sz = entry->swap_file_sz - swap_hdr_sz;
-
+    debugs(90, 5, "store_client::unpackHeader: swap_file_sz=" <<
+           entry->swap_file_sz << "( " << swap_hdr_sz << " + " <<
+           entry->mem_obj->object_sz << ")");
 }
 
 void
@@ -696,7 +701,7 @@
         e->swapOut();
 
     if (sc->swapin_sio != NULL) {
-        storeClose(sc->swapin_sio);
+        storeClose(sc->swapin_sio, StoreIOState::readerDone);
         sc->swapin_sio = NULL;
         statCounter.swap.ins++;
     }
diff -u -r -N squid-3.2.0.12/src/store_digest.cc squid-3.2.0.13/src/store_digest.cc
--- squid-3.2.0.12/src/store_digest.cc	2011-09-16 23:37:30.000000000 +1200
+++ squid-3.2.0.13/src/store_digest.cc	2011-10-14 14:42:56.000000000 +1300
@@ -507,7 +507,7 @@
      * number of _entries_ we want to pre-allocate for.
      */
     const int hi_cap = Store::Root().maxSize() / Config.Store.avgObjectSize;
-    const int lo_cap = 1 + store_swap_size / Config.Store.avgObjectSize;
+    const int lo_cap = 1 + Store::Root().currentSize() / Config.Store.avgObjectSize;
     const int e_count = StoreEntry::inUseCount();
     int cap = e_count ? e_count :hi_cap;
     debugs(71, 2, "storeDigestCalcCap: have: " << e_count << ", want " << cap <<
diff -u -r -N squid-3.2.0.12/src/store_dir.cc squid-3.2.0.13/src/store_dir.cc
--- squid-3.2.0.12/src/store_dir.cc	2011-09-16 23:37:30.000000000 +1200
+++ squid-3.2.0.13/src/store_dir.cc	2011-10-14 14:42:56.000000000 +1300
@@ -36,6 +36,8 @@
 #include "squid.h"
 #include "Store.h"
 #include "MemObject.h"
+#include "MemStore.h"
+#include "mem_node.h"
 #include "SquidMath.h"
 #include "SquidTime.h"
 #include "SwapDir.h"
@@ -73,10 +75,13 @@
 int StoreController::store_dirs_rebuilding = 1;
 
 StoreController::StoreController() : swapDir (new StoreHashIndex())
+        , memStore(NULL)
 {}
 
 StoreController::~StoreController()
-{}
+{
+    delete memStore;
+}
 
 /*
  * This function pointer is set according to 'store_dir_select_algorithm'
@@ -87,6 +92,11 @@
 void
 StoreController::init()
 {
+    if (Config.memShared && IamWorkerProcess()) {
+        memStore = new MemStore;
+        memStore->init();
+    }
+
     swapDir->init();
 
     if (0 == strcasecmp(Config.store_dir_select_algorithm, "round-robin")) {
@@ -189,28 +199,20 @@
     int load;
     RefCount<SwapDir> sd;
 
-    ssize_t objsize = e->objectLen();
+    // e->objectLen() is negative at this point when we are still STORE_PENDING
+    ssize_t objsize = e->mem_obj->expectedReplySize();
     if (objsize != -1)
         objsize += e->mem_obj->swap_hdr_sz;
 
-    for (i = 0; i <= Config.cacheSwap.n_configured; i++) {
+    for (i = 0; i < Config.cacheSwap.n_configured; i++) {
         if (++dirn >= Config.cacheSwap.n_configured)
             dirn = 0;
 
         sd = dynamic_cast<SwapDir *>(INDEXSD(dirn));
 
-        if (sd->flags.read_only)
-            continue;
-
-        if (sd->cur_size > sd->max_size)
+        if (!sd->canStore(*e, objsize, load))
             continue;
 
-        if (!sd->objectSizeIsAcceptable(objsize))
-            continue;
-
-        /* check for error or overload condition */
-        load = sd->canStore(*e);
-
         if (load < 0 || load > 1000) {
             continue;
         }
@@ -237,8 +239,7 @@
 static int
 storeDirSelectSwapDirLeastLoad(const StoreEntry * e)
 {
-    ssize_t objsize;
-    ssize_t most_free = 0, cur_free;
+    int64_t most_free = 0;
     ssize_t least_objsize = -1;
     int least_load = INT_MAX;
     int load;
@@ -246,8 +247,8 @@
     int i;
     RefCount<SwapDir> SD;
 
-    /* Calculate the object size */
-    objsize = e->objectLen();
+    // e->objectLen() is negative at this point when we are still STORE_PENDING
+    ssize_t objsize = e->mem_obj->expectedReplySize();
 
     if (objsize != -1)
         objsize += e->mem_obj->swap_hdr_sz;
@@ -255,25 +256,17 @@
     for (i = 0; i < Config.cacheSwap.n_configured; i++) {
         SD = dynamic_cast<SwapDir *>(INDEXSD(i));
         SD->flags.selected = 0;
-        load = SD->canStore(*e);
-
-        if (load < 0 || load > 1000) {
-            continue;
-        }
 
-        if (!SD->objectSizeIsAcceptable(objsize))
+        if (!SD->canStore(*e, objsize, load))
             continue;
 
-        if (SD->flags.read_only)
-            continue;
-
-        if (SD->cur_size > SD->max_size)
+        if (load < 0 || load > 1000)
             continue;
 
         if (load > least_load)
             continue;
 
-        cur_free = SD->max_size - SD->cur_size;
+        const int64_t cur_free = SD->maxSize() - SD->currentSize();
 
         /* If the load is equal, then look in more details */
         if (load == least_load) {
@@ -334,39 +327,21 @@
 }
 
 void
-StoreController::updateSize(int64_t size, int sign)
-{
-    fatal("StoreController has no independent size\n");
-}
-
-void
-SwapDir::updateSize(int64_t size, int sign)
-{
-    int64_t blks = (size + fs.blksize - 1) / fs.blksize;
-    int64_t k = ((blks * fs.blksize) >> 10) * sign;
-    cur_size += k;
-    store_swap_size += k;
-
-    if (sign > 0)
-        n_disk_objects++;
-    else if (sign < 0)
-        n_disk_objects--;
-}
-
-void
 StoreController::stat(StoreEntry &output) const
 {
     storeAppendPrintf(&output, "Store Directory Statistics:\n");
     storeAppendPrintf(&output, "Store Entries          : %lu\n",
                       (unsigned long int)StoreEntry::inUseCount());
     storeAppendPrintf(&output, "Maximum Swap Size      : %"PRIu64" KB\n",
-                      maxSize());
-    storeAppendPrintf(&output, "Current Store Swap Size: %8lu KB\n",
-                      store_swap_size);
-    storeAppendPrintf(&output, "Current Capacity       : %"PRId64"%% used, %"PRId64"%% free\n",
-                      Math::int64Percent(store_swap_size, maxSize()),
-                      Math::int64Percent((maxSize() - store_swap_size), maxSize()));
-    /* FIXME Here we should output memory statistics */
+                      maxSize() >> 10);
+    storeAppendPrintf(&output, "Current Store Swap Size: %.2f KB\n",
+                      currentSize() / 1024.0);
+    storeAppendPrintf(&output, "Current Capacity       : %.2f%% used, %.2f%% free\n",
+                      Math::doublePercent(currentSize(), maxSize()),
+                      Math::doublePercent((maxSize() - currentSize()), maxSize()));
+
+    if (memStore)
+        memStore->stat(output);
 
     /* now the swapDir */
     swapDir->stat(output);
@@ -387,15 +362,33 @@
     return swapDir->minSize();
 }
 
+uint64_t
+StoreController::currentSize() const
+{
+    return swapDir->currentSize();
+}
+
+uint64_t
+StoreController::currentCount() const
+{
+    return swapDir->currentCount();
+}
+
+int64_t
+StoreController::maxObjectSize() const
+{
+    return swapDir->maxObjectSize();
+}
+
 void
 SwapDir::diskFull()
 {
-    if (cur_size >= max_size)
+    if (currentSize() >= maxSize())
         return;
 
-    max_size = cur_size;
+    max_size = currentSize();
 
-    debugs(20, 1, "WARNING: Shrinking cache_dir #" << index << " to " << cur_size << " KB");
+    debugs(20, 1, "WARNING: Shrinking cache_dir #" << index << " to " << currentSize() / 1024.0 << " KB");
 }
 
 void
@@ -518,10 +511,19 @@
     return INDEXSD(x);
 }
 
+SwapDir &
+StoreHashIndex::dir(const int i) const
+{
+    SwapDir *sd = dynamic_cast<SwapDir*>(INDEXSD(i));
+    assert(sd);
+    return *sd;
+}
+
 void
 StoreController::sync(void)
 {
-    /* sync mem cache? */
+    if (memStore)
+        memStore->sync();
     swapDir->sync();
 }
 
@@ -620,13 +622,12 @@
 {
     if (swap->swapDirs == NULL) {
         swap->n_allocated = 4;
-        swap->swapDirs = static_cast<StorePointer *>(xcalloc(swap->n_allocated, sizeof(StorePointer)));
+        swap->swapDirs = static_cast<SwapDir::Pointer *>(xcalloc(swap->n_allocated, sizeof(SwapDir::Pointer)));
     }
 
     if (swap->n_allocated == swap->n_configured) {
-        StorePointer *tmp;
         swap->n_allocated <<= 1;
-        tmp = static_cast<StorePointer *>(xcalloc(swap->n_allocated, sizeof(StorePointer)));
+        SwapDir::Pointer *const tmp = static_cast<SwapDir::Pointer *>(xcalloc(swap->n_allocated, sizeof(SwapDir::Pointer)));
         memcpy(tmp, swap->swapDirs, swap->n_configured * sizeof(SwapDir *));
         xfree(swap->swapDirs);
         swap->swapDirs = tmp;
@@ -667,35 +668,83 @@
     /* Notify the fs that we're referencing this object again */
 
     if (e.swap_dirn > -1)
-        e.store()->reference(e);
+        swapDir->reference(e);
+
+    // Notify the memory cache that we're referencing this object again
+    if (memStore && e.mem_status == IN_MEMORY)
+        memStore->reference(e);
 
-    /* Notify the memory cache that we're referencing this object again */
+    // TODO: move this code to a non-shared memory cache class when we have it
     if (e.mem_obj) {
         if (mem_policy->Referenced)
             mem_policy->Referenced(mem_policy, &e, &e.mem_obj->repl);
     }
 }
 
-void
+bool
 StoreController::dereference(StoreEntry & e)
 {
+    bool keepInStoreTable = true; // keep if there are no objections
+
     /* Notify the fs that we're not referencing this object any more */
 
     if (e.swap_filen > -1)
-        e.store()->dereference(e);
+        keepInStoreTable = swapDir->dereference(e) && keepInStoreTable;
 
-    /* Notify the memory cache that we're not referencing this object any more */
+    // Notify the memory cache that we're not referencing this object any more
+    if (memStore && e.mem_status == IN_MEMORY)
+        keepInStoreTable = memStore->dereference(e) && keepInStoreTable;
+
+    // TODO: move this code to a non-shared memory cache class when we have it
     if (e.mem_obj) {
         if (mem_policy->Dereferenced)
             mem_policy->Dereferenced(mem_policy, &e, &e.mem_obj->repl);
     }
+
+    return keepInStoreTable;
 }
 
 StoreEntry *
 StoreController::get(const cache_key *key)
 {
+    if (StoreEntry *e = swapDir->get(key)) {
+        // TODO: ignore and maybe handleIdleEntry() unlocked intransit entries
+        // because their backing store slot may be gone already.
+        debugs(20, 3, HERE << "got in-transit entry: " << *e);
+        return e;
+    }
+
+    if (memStore) {
+        if (StoreEntry *e = memStore->get(key)) {
+            debugs(20, 3, HERE << "got mem-cached entry: " << *e);
+            return e;
+        }
+    }
+
+    // TODO: this disk iteration is misplaced; move to StoreHashIndex when
+    // the global store_table is no longer used for in-transit objects.
+    if (const int cacheDirs = Config.cacheSwap.n_configured) {
+        // ask each cache_dir until the entry is found; use static starting
+        // point to avoid asking the same subset of disks more often
+        // TODO: coordinate with put() to be able to guess the right disk often
+        static int idx = 0;
+        for (int n = 0; n < cacheDirs; ++n) {
+            idx = (idx + 1) % cacheDirs;
+            SwapDir *sd = dynamic_cast<SwapDir*>(INDEXSD(idx));
+            if (!sd->active())
+                continue;
+
+            if (StoreEntry *e = sd->get(key)) {
+                debugs(20, 3, HERE << "cache_dir " << idx <<
+                       " got cached entry: " << *e);
+                return e;
+            }
+        }
+    }
 
-    return swapDir->get(key);
+    debugs(20, 4, HERE << "none of " << Config.cacheSwap.n_configured <<
+           " cache_dirs have " << storeKeyText(key));
+    return NULL;
 }
 
 void
@@ -704,6 +753,36 @@
     fatal("not implemented");
 }
 
+void
+StoreController::handleIdleEntry(StoreEntry &e)
+{
+    bool keepInLocalMemory = false;
+    if (memStore) {
+        memStore->considerKeeping(e);
+        // leave keepInLocalMemory false; memStore maintains its own cache
+    } else {
+        keepInLocalMemory = e.memoryCachable() && // entry is in good shape and
+                            // the local memory cache is not overflowing
+                            (mem_node::InUseCount() <= store_pages_max);
+    }
+
+    // An idle, unlocked entry that belongs to a SwapDir which controls
+    // its own index, should not stay in the global store_table.
+    if (!dereference(e)) {
+        debugs(20, 5, HERE << "destroying unlocked entry: " << &e << ' ' << e);
+        destroyStoreEntry(static_cast<hash_link*>(&e));
+        return;
+    }
+
+    // TODO: move this into [non-shared] memory cache class when we have one
+    if (keepInLocalMemory) {
+        e.setMemStatus(IN_MEMORY);
+        e.mem_obj->unlinkRequest();
+    } else {
+        e.purgeMem(); // may free e
+    }
+}
+
 StoreHashIndex::StoreHashIndex()
 {
     if (store_table)
@@ -755,8 +834,10 @@
 void
 StoreHashIndex::create()
 {
-    for (int i = 0; i < Config.cacheSwap.n_configured; i++)
-        store(i)->create();
+    for (int i = 0; i < Config.cacheSwap.n_configured; i++) {
+        if (dir(i).active())
+            store(i)->create();
+    }
 }
 
 /* Lookup an object in the cache.
@@ -783,8 +864,8 @@
     /* Calculate size of hash table (maximum currently 64k buckets).  */
     /* this is very bogus, its specific to the any Store maintaining an
      * in-core index, not global */
-    size_t buckets = (Store::Root().maxSize() + ( Config.memMaxSize >> 10)) / Config.Store.avgObjectSize;
-    debugs(20, 1, "Swap maxSize " << Store::Root().maxSize() <<
+    size_t buckets = (Store::Root().maxSize() + Config.memMaxSize) / Config.Store.avgObjectSize;
+    debugs(20, 1, "Swap maxSize " << (Store::Root().maxSize() >> 10) <<
            " + " << ( Config.memMaxSize >> 10) << " KB, estimated " << buckets << " objects");
     buckets /= Config.Store.objectsPerBucket;
     debugs(20, 1, "Target number of buckets: " << buckets);
@@ -792,8 +873,9 @@
      * moment it remains at approximately 24 hours.  */
     store_hash_buckets = storeKeyHashBuckets(buckets);
     debugs(20, 1, "Using " << store_hash_buckets << " Store buckets");
-    debugs(20, 1, "Max Mem  size: " << ( Config.memMaxSize >> 10) << " KB");
-    debugs(20, 1, "Max Swap size: " << Store::Root().maxSize() << " KB");
+    debugs(20, 1, "Max Mem  size: " << ( Config.memMaxSize >> 10) << " KB" <<
+           (Config.memShared ? " [shared]" : ""));
+    debugs(20, 1, "Max Swap size: " << (Store::Root().maxSize() >> 10) << " KB");
 
     store_table = hash_create(storeKeyHashCmp,
                               store_hash_buckets, storeKeyHashHash);
@@ -813,7 +895,8 @@
         *         above
         * Step 3: have the hash index walk the searches itself.
          */
-        store(i)->init();
+        if (dir(i).active())
+            store(i)->init();
     }
 }
 
@@ -822,8 +905,10 @@
 {
     uint64_t result = 0;
 
-    for (int i = 0; i < Config.cacheSwap.n_configured; i++)
-        result += store(i)->maxSize();
+    for (int i = 0; i < Config.cacheSwap.n_configured; i++) {
+        if (dir(i).doReportStat())
+            result += store(i)->maxSize();
+    }
 
     return result;
 }
@@ -833,8 +918,49 @@
 {
     uint64_t result = 0;
 
-    for (int i = 0; i < Config.cacheSwap.n_configured; i++)
-        result += store(i)->minSize();
+    for (int i = 0; i < Config.cacheSwap.n_configured; i++) {
+        if (dir(i).doReportStat())
+            result += store(i)->minSize();
+    }
+
+    return result;
+}
+
+uint64_t
+StoreHashIndex::currentSize() const
+{
+    uint64_t result = 0;
+
+    for (int i = 0; i < Config.cacheSwap.n_configured; i++) {
+        if (dir(i).doReportStat())
+            result += store(i)->currentSize();
+    }
+
+    return result;
+}
+
+uint64_t
+StoreHashIndex::currentCount() const
+{
+    uint64_t result = 0;
+
+    for (int i = 0; i < Config.cacheSwap.n_configured; i++) {
+        if (dir(i).doReportStat())
+            result += store(i)->currentCount();
+    }
+
+    return result;
+}
+
+int64_t
+StoreHashIndex::maxObjectSize() const
+{
+    int64_t result = -1;
+
+    for (int i = 0; i < Config.cacheSwap.n_configured; i++) {
+        if (dir(i).active() && store(i)->maxObjectSize() > result)
+            result = store(i)->maxObjectSize();
+    }
 
     return result;
 }
@@ -853,12 +979,16 @@
 }
 
 void
-StoreHashIndex::reference(StoreEntry&)
-{}
+StoreHashIndex::reference(StoreEntry &e)
+{
+    e.store()->reference(e);
+}
 
-void
-StoreHashIndex::dereference(StoreEntry&)
-{}
+bool
+StoreHashIndex::dereference(StoreEntry &e)
+{
+    return e.store()->dereference(e);
+}
 
 void
 StoreHashIndex::maintain()
@@ -876,10 +1006,6 @@
 }
 
 void
-StoreHashIndex::updateSize(int64_t, int)
-{}
-
-void
 StoreHashIndex::sync()
 {
     for (int i = 0; i < Config.cacheSwap.n_configured; ++i)
diff -u -r -N squid-3.2.0.12/src/Store.h squid-3.2.0.13/src/Store.h
--- squid-3.2.0.12/src/Store.h	2011-09-16 23:37:30.000000000 +1200
+++ squid-3.2.0.13/src/Store.h	2011-10-14 14:42:56.000000000 +1300
@@ -58,8 +58,8 @@
 class AsyncCall;
 class StoreClient;
 class MemObject;
-class Store;
 class StoreSearch;
+class SwapDir;
 
 typedef struct {
 
@@ -73,6 +73,9 @@
 
 extern StoreIoStats store_io_stats;
 
+/// maximum number of entries per cache_dir
+enum { SwapFilenMax = 0xFFFFFF }; // keep in sync with StoreEntry::swap_filen
+
 /**
  \ingroup StoreAPI
  */
@@ -86,7 +89,7 @@
     virtual const char *getMD5Text() const;
     StoreEntry();
     StoreEntry(const char *url, const char *log_url);
-    virtual ~StoreEntry() {}
+    virtual ~StoreEntry();
 
     virtual HttpReply const *getReply() const;
     virtual void write (StoreIOBuffer);
@@ -96,7 +99,8 @@
     virtual void complete();
     virtual store_client_t storeClientType() const;
     virtual char const *getSerialisedMetaData();
-    virtual void replaceHttpReply(HttpReply *);
+    void replaceHttpReply(HttpReply *, bool andStartWriting = true);
+    void startWriting(); ///< pack and write reply headers and, maybe, body
     virtual bool swapoutPossible();
     virtual void trimMemory();
     void abort();
@@ -111,16 +115,18 @@
     void cacheNegatively();		/** \todo argh, why both? */
     void invokeHandlers();
     void purgeMem();
+    void cacheInMemory(); ///< start or continue storing in memory cache
     void swapOut();
     bool swapOutAble() const;
-    void swapOutFileClose();
+    void swapOutFileClose(int how);
     const char *url() const;
     int checkCachable();
     int checkNegativeHit() const;
     int locked() const;
     int validToSend() const;
-    int keepInMemory() const;
+    bool memoryCachable() const; ///< may be cached in memory
     void createMemObject(const char *, const char *);
+    void hideMemObject(); ///< no mem_obj for callers until createMemObject
     void dump(int debug_lvl) const;
     void hashDelete();
     void hashInsert(const cache_key *);
@@ -142,9 +148,10 @@
     bool hasIfNoneMatchEtag(const HttpRequest &request) const;
 
     /** What store does this entry belong too ? */
-    virtual RefCount<Store> store() const;
+    virtual RefCount<SwapDir> store() const;
 
     MemObject *mem_obj;
+    MemObject *hidden_mem_obj; ///< mem_obj created before URLs were known
     RemovalPolicyNode repl;
     /* START OF ON-DISK STORE_META_STD TLV field */
     time_t timestamp;
@@ -156,7 +163,8 @@
     uint16_t flags;
     /* END OF ON-DISK STORE_META_STD */
 
-    sfileno swap_filen:25;
+    /// unique ID inside a cache_dir for swapped out entries; -1 for others
+    sfileno swap_filen:25; // keep in sync with SwapFilenMax
 
     sdirno swap_dirn:7;
 
@@ -209,6 +217,8 @@
     bool hasOneOfEtags(const String &reqETags, const bool allowWeakMatch) const;
 };
 
+std::ostream &operator <<(std::ostream &os, const StoreEntry &e);
+
 /// \ingroup StoreAPI
 class NullStoreEntry:public StoreEntry
 {
@@ -296,6 +306,15 @@
     /** The minimum size the store will shrink to via normal housekeeping */
     virtual uint64_t minSize() const = 0;
 
+    /** current store size */
+    virtual uint64_t currentSize() const = 0;
+
+    /** the total number of objects stored */
+    virtual uint64_t currentCount() const = 0;
+
+    /** the maximum object size that can be stored, -1 if unlimited */
+    virtual int64_t maxObjectSize() const = 0;
+
     /**
      * Output stats to the provided store entry.
      \todo make these calls asynchronous
@@ -314,12 +333,15 @@
     /* pulled up from SwapDir for migration.... probably do not belong here */
     virtual void reference(StoreEntry &) = 0;	/* Reference this object */
 
-    virtual void dereference(StoreEntry &) = 0;	/* Unreference this object */
+    /// Undo reference(), returning false iff idle e should be destroyed
+    virtual bool dereference(StoreEntry &e) = 0;
 
     virtual void maintain() = 0; /* perform regular maintenance should be private and self registered ... */
 
-    /* These should really be private */
-    virtual void updateSize(int64_t size, int sign) = 0;
+    // XXX: This method belongs to Store::Root/StoreController, but it is here
+    // because test cases use non-StoreController derivatives as Root
+    /// called when the entry is no longer needed by any transaction
+    virtual void handleIdleEntry(StoreEntry &e) {}
 
 private:
     static RefCount<Store> CurrentRoot;
diff -u -r -N squid-3.2.0.12/src/StoreHashIndex.h squid-3.2.0.13/src/StoreHashIndex.h
--- squid-3.2.0.12/src/StoreHashIndex.h	2011-09-16 23:37:30.000000000 +1200
+++ squid-3.2.0.13/src/StoreHashIndex.h	2011-10-14 14:42:56.000000000 +1300
@@ -67,21 +67,26 @@
 
     virtual uint64_t minSize() const;
 
+    virtual uint64_t currentSize() const;
+
+    virtual uint64_t currentCount() const;
+
+    virtual int64_t maxObjectSize() const;
+
     virtual void stat(StoreEntry&) const;
 
     virtual void reference(StoreEntry&);
 
-    virtual void dereference(StoreEntry&);
+    virtual bool dereference(StoreEntry&);
 
     virtual void maintain();
 
-    virtual void updateSize(int64_t, int);
-
     virtual StoreSearch *search(String const url, HttpRequest *);
 
 private:
     /* migration logic */
     StorePointer store(int const x) const;
+    SwapDir &dir(int const idx) const;
 };
 
 class StoreHashIndexEntry : public StoreEntry
diff -u -r -N squid-3.2.0.12/src/store_io.cc squid-3.2.0.13/src/store_io.cc
--- squid-3.2.0.12/src/store_io.cc	2011-09-16 23:37:30.000000000 +1200
+++ squid-3.2.0.13/src/store_io.cc	2011-10-14 14:42:56.000000000 +1300
@@ -15,31 +15,23 @@
 storeCreate(StoreEntry * e, StoreIOState::STFNCB * file_callback, StoreIOState::STIOCB * close_callback, void *callback_data)
 {
     assert (e);
-    ssize_t objsize;
-    sdirno dirn;
-    RefCount<SwapDir> SD;
 
     store_io_stats.create.calls++;
-    /* This is just done for logging purposes */
-    objsize = e->objectLen();
-
-    if (objsize != -1)
-        objsize += e->mem_obj->swap_hdr_sz;
 
     /*
      * Pick the swapdir
      * We assume that the header has been packed by now ..
      */
-    dirn = storeDirSelectSwapDir(e);
+    const sdirno dirn = storeDirSelectSwapDir(e);
 
     if (dirn == -1) {
-        debugs(20, 2, "storeCreate: no valid swapdirs for this object");
+        debugs(20, 2, "storeCreate: no swapdirs for " << *e);
         store_io_stats.create.select_fail++;
         return NULL;
     }
 
-    debugs(20, 2, "storeCreate: Selected dir '" << dirn << "' for obj size '" << objsize << "'");
-    SD = dynamic_cast<SwapDir *>(INDEXSD(dirn));
+    debugs(20, 2, "storeCreate: Selected dir " << dirn << " for " << *e);
+    SwapDir *SD = dynamic_cast<SwapDir *>(INDEXSD(dirn));
 
     /* Now that we have a fs to use, call its storeCreate function */
     StoreIOState::Pointer sio = SD->createStoreIO(*e, file_callback, close_callback, callback_data);
@@ -63,7 +55,7 @@
 }
 
 void
-storeClose(StoreIOState::Pointer sio)
+storeClose(StoreIOState::Pointer sio, int how)
 {
     if (sio->flags.closing) {
         debugs(20,3,HERE << "storeClose: flags.closing already set, bailing");
@@ -72,8 +64,8 @@
 
     sio->flags.closing = 1;
 
-    debugs(20,3,HERE << "storeClose: calling sio->close()");
-    sio->close();
+    debugs(20,3,HERE << "storeClose: calling sio->close(" << how << ")");
+    sio->close(how);
 }
 
 void
diff -u -r -N squid-3.2.0.12/src/StoreIOState.h squid-3.2.0.13/src/StoreIOState.h
--- squid-3.2.0.12/src/StoreIOState.h	2011-09-16 23:37:30.000000000 +1200
+++ squid-3.2.0.13/src/StoreIOState.h	2011-10-14 14:42:56.000000000 +1300
@@ -84,13 +84,19 @@
 
     virtual void read_(char *buf, size_t size, off_t offset, STRCB * callback, void *callback_data) = 0;
     virtual void write(char const *buf, size_t size, off_t offset, FREE * free_func) = 0;
-    virtual void close() = 0;
+
+    typedef enum {
+        wroteAll, ///< success: caller supplied all data it wanted to swap out
+        writerGone, ///< failure: caller left before swapping out everything
+        readerDone ///< success or failure: either way, stop swapping in
+    } CloseHow;
+    virtual void close(int how) = 0; ///< finish or abort swapping per CloseHow
 
     sdirno swap_dirn;
     sfileno swap_filen;
     StoreEntry *e;		/* Need this so the FS layers can play god */
     mode_t mode;
-    off_t offset_;		/* current on-disk offset pointer */
+    off_t offset_; ///< number of bytes written or read for this entry so far
     STFNCB *file_callback;	/* called on delayed sfileno assignments */
     STIOCB *callback;
     void *callback_data;
@@ -107,7 +113,7 @@
 
 StoreIOState::Pointer storeCreate(StoreEntry *, StoreIOState::STFNCB *, StoreIOState::STIOCB *, void *);
 StoreIOState::Pointer storeOpen(StoreEntry *, StoreIOState::STFNCB *, StoreIOState::STIOCB *, void *);
-SQUIDCEXTERN void storeClose(StoreIOState::Pointer);
+SQUIDCEXTERN void storeClose(StoreIOState::Pointer, int how);
 SQUIDCEXTERN void storeRead(StoreIOState::Pointer, char *, size_t, off_t, StoreIOState::STRCB *, void *);
 SQUIDCEXTERN void storeIOWrite(StoreIOState::Pointer, char const *, size_t, off_t, FREE *);
 
diff -u -r -N squid-3.2.0.12/src/StoreMetaUnpacker.cc squid-3.2.0.13/src/StoreMetaUnpacker.cc
--- squid-3.2.0.12/src/StoreMetaUnpacker.cc	2011-09-16 23:37:30.000000000 +1200
+++ squid-3.2.0.13/src/StoreMetaUnpacker.cc	2011-10-14 14:42:56.000000000 +1300
@@ -39,6 +39,24 @@
 
 int const StoreMetaUnpacker::MinimumBufferLength = sizeof(char) + sizeof(int);
 
+/// useful for meta stored in pre-initialized (with zeros) db files
+bool
+StoreMetaUnpacker::isBufferZero()
+{
+    // We could memcmp the entire buffer, but it is probably safe enough
+    // to test a few bytes because if we do not detect a corrupted entry
+    // it is not a big deal. Empty entries are not isBufferSane anyway.
+    const int depth = 10;
+    if (buflen < depth)
+        return false; // cannot be sure enough
+
+    for (int i = 0; i < depth; ++i) {
+        if (buf[i])
+            return false;
+    }
+    return true;
+}
+
 bool
 StoreMetaUnpacker::isBufferSane()
 {
diff -u -r -N squid-3.2.0.12/src/StoreMetaUnpacker.h squid-3.2.0.13/src/StoreMetaUnpacker.h
--- squid-3.2.0.12/src/StoreMetaUnpacker.h	2011-09-16 23:37:30.000000000 +1200
+++ squid-3.2.0.13/src/StoreMetaUnpacker.h	2011-10-14 14:42:56.000000000 +1300
@@ -41,6 +41,7 @@
 public:
     StoreMetaUnpacker (const char *buf, ssize_t bufferLength, int *hdrlen);
     StoreMeta *createStoreMeta();
+    bool isBufferZero(); ///< all-zeros buffer, implies !isBufferSane
     bool isBufferSane();
 
 private:
diff -u -r -N squid-3.2.0.12/src/store_rebuild.cc squid-3.2.0.13/src/store_rebuild.cc
--- squid-3.2.0.12/src/store_rebuild.cc	2011-09-16 23:37:30.000000000 +1200
+++ squid-3.2.0.13/src/store_rebuild.cc	2011-10-14 14:42:56.000000000 +1300
@@ -74,7 +74,6 @@
     size_t statCount = 500;
 
     while (statCount-- && !currentSearch->isDone() && currentSearch->next()) {
-        ++validated;
         StoreEntry *e;
 
         e = currentSearch->currentItem();
@@ -99,7 +98,6 @@
          * Only set the file bit if we know its a valid entry
          * otherwise, set it in the validation procedure
          */
-        e->store()->updateSize(e->swap_file_sz, 1);
 
         if ((++validated & 0x3FFFF) == 0)
             /* TODO format the int with with a stream operator */
@@ -109,7 +107,7 @@
     if (currentSearch->isDone()) {
         debugs(20, 1, "  Completed Validation Procedure");
         debugs(20, 1, "  Validated " << validated << " Entries");
-        debugs(20, 1, "  store_swap_size = " << store_swap_size);
+        debugs(20, 1, "  store_swap_size = " << Store::Root().currentSize() / 1024.0 << " KB");
         StoreController::store_dirs_rebuilding--;
         assert(0 == StoreController::store_dirs_rebuilding);
 
@@ -231,3 +229,188 @@
     debugs(20, 1, "Store rebuilding is "<< std::setw(4)<< std::setprecision(2) << 100.0 * n / d << "% complete");
     last_report = squid_curtime;
 }
+
+#include "fde.h"
+#include "StoreMetaUnpacker.h"
+#include "StoreMeta.h"
+#include "Generic.h"
+
+struct InitStoreEntry : public unary_function<StoreMeta, void> {
+    InitStoreEntry(StoreEntry *anEntry, cache_key *aKey):what(anEntry),index(aKey) {}
+
+    void operator()(StoreMeta const &x) {
+        switch (x.getType()) {
+
+        case STORE_META_KEY:
+            assert(x.length == SQUID_MD5_DIGEST_LENGTH);
+            memcpy(index, x.value, SQUID_MD5_DIGEST_LENGTH);
+            break;
+
+        case STORE_META_STD:
+            struct old_metahdr {
+                time_t timestamp;
+                time_t lastref;
+                time_t expires;
+                time_t lastmod;
+                size_t swap_file_sz;
+                uint16_t refcount;
+                uint16_t flags;
+            } *tmp;
+            tmp = (struct old_metahdr *)x.value;
+            assert(x.length == STORE_HDR_METASIZE_OLD);
+            what->timestamp = tmp->timestamp;
+            what->lastref = tmp->lastref;
+            what->expires = tmp->expires;
+            what->lastmod = tmp->lastmod;
+            what->swap_file_sz = tmp->swap_file_sz;
+            what->refcount = tmp->refcount;
+            what->flags = tmp->flags;
+            break;
+
+        case STORE_META_STD_LFS:
+            assert(x.length == STORE_HDR_METASIZE);
+            memcpy(&what->timestamp, x.value, STORE_HDR_METASIZE);
+            break;
+
+        default:
+            break;
+        }
+    }
+
+    StoreEntry *what;
+    cache_key *index;
+};
+
+bool
+storeRebuildLoadEntry(int fd, int diskIndex, MemBuf &buf,
+                      struct _store_rebuild_data &counts)
+{
+    if (fd < 0)
+        return false;
+
+    assert(buf.hasSpace()); // caller must allocate
+
+    const int len = FD_READ_METHOD(fd, buf.space(), buf.spaceSize());
+    statCounter.syscalls.disk.reads++;
+    if (len < 0) {
+        const int xerrno = errno;
+        debugs(47, DBG_IMPORTANT, "WARNING: cache_dir[" << diskIndex << "]: " <<
+               "Ignoring cached entry after meta data read failure: " << xstrerr(xerrno));
+        return false;
+    }
+
+    buf.appended(len);
+    return true;
+}
+
+bool
+storeRebuildParseEntry(MemBuf &buf, StoreEntry &tmpe, cache_key *key,
+                       struct _store_rebuild_data &counts,
+                       uint64_t expectedSize)
+{
+    int swap_hdr_len = 0;
+    StoreMetaUnpacker aBuilder(buf.content(), buf.contentSize(), &swap_hdr_len);
+    if (aBuilder.isBufferZero()) {
+        debugs(47,5, HERE << "skipping empty record.");
+        return false;
+    }
+
+    if (!aBuilder.isBufferSane()) {
+        debugs(47, DBG_IMPORTANT, "WARNING: Ignoring malformed cache entry.");
+        return false;
+    }
+
+    StoreMeta *tlv_list = aBuilder.createStoreMeta();
+    if (!tlv_list) {
+        debugs(47, DBG_IMPORTANT, "WARNING: Ignoring cache entry with invalid " <<
+               "meta data");
+        return false;
+    }
+
+    // TODO: consume parsed metadata?
+
+    debugs(47,7, HERE << "successful swap meta unpacking");
+    memset(key, '\0', SQUID_MD5_DIGEST_LENGTH);
+
+    InitStoreEntry visitor(&tmpe, key);
+    for_each(*tlv_list, visitor);
+    storeSwapTLVFree(tlv_list);
+    tlv_list = NULL;
+
+    if (storeKeyNull(key)) {
+        debugs(47, DBG_IMPORTANT, "WARNING: Ignoring keyless cache entry");
+        return false;
+    }
+
+    tmpe.key = key;
+    /* check sizes */
+
+    if (expectedSize > 0) {
+        if (tmpe.swap_file_sz == 0) {
+            tmpe.swap_file_sz = expectedSize;
+        } else if (tmpe.swap_file_sz == (uint64_t)(expectedSize - swap_hdr_len)) {
+            tmpe.swap_file_sz = expectedSize;
+        } else if (tmpe.swap_file_sz != expectedSize) {
+            debugs(47, DBG_IMPORTANT, "WARNING: Ignoring cache entry due to a " <<
+                   "SIZE MISMATCH " << tmpe.swap_file_sz << "!=" << expectedSize);
+            return false;
+        }
+    } else if (tmpe.swap_file_sz <= 0) {
+        debugs(47, DBG_IMPORTANT, "WARNING: Ignoring cache entry with " <<
+               "unknown size: " << tmpe);
+        return false;
+    }
+
+    if (EBIT_TEST(tmpe.flags, KEY_PRIVATE)) {
+        counts.badflags++;
+        return false;
+    }
+
+    return true;
+}
+
+bool
+storeRebuildKeepEntry(const StoreEntry &tmpe, const cache_key *key,
+                      struct _store_rebuild_data &counts)
+{
+    /* this needs to become
+     * 1) unpack url
+     * 2) make synthetic request with headers ?? or otherwise search
+     * for a matching object in the store
+     * TODO FIXME change to new async api
+     * TODO FIXME I think there is a race condition here with the
+     * async api :
+     * store A reads in object foo, searchs for it, and finds nothing.
+     * store B reads in object foo, searchs for it, finds nothing.
+     * store A gets called back with nothing, so registers the object
+     * store B gets called back with nothing, so registers the object,
+     * which will conflict when the in core index gets around to scanning
+     * store B.
+     *
+     * this suggests that rather than searching for duplicates, the
+     * index rebuild should just assume its the most recent accurate
+     * store entry and whoever indexes the stores handles duplicates.
+     */
+    if (StoreEntry *e = Store::Root().get(key)) {
+
+        if (e->lastref >= tmpe.lastref) {
+            /* key already exists, old entry is newer */
+            /* keep old, ignore new */
+            counts.dupcount++;
+
+            // For some stores, get() creates/unpacks a store entry. Signal
+            // such stores that we will no longer use the get() result:
+            e->lock();
+            e->unlock();
+
+            return false;
+        } else {
+            /* URL already exists, this swapfile not being used */
+            /* junk old, load new */
+            e->release();	/* release old entry */
+            counts.dupcount++;
+        }
+    }
+
+    return true;
+}
diff -u -r -N squid-3.2.0.12/src/store_swapin.cc squid-3.2.0.13/src/store_swapin.cc
--- squid-3.2.0.12/src/store_swapin.cc	2011-09-16 23:37:30.000000000 +1200
+++ squid-3.2.0.13/src/store_swapin.cc	2011-10-14 14:42:56.000000000 +1300
@@ -50,6 +50,9 @@
         return;
     }
 
+    if (e->mem_status != NOT_IN_MEMORY)
+        debugs(20, 3, HERE << "already IN_MEMORY");
+
     debugs(20, 3, "storeSwapInStart: called for : " << e->swap_dirn << " " <<
            std::hex << std::setw(8) << std::setfill('0') << std::uppercase <<
            e->swap_filen << " " <<  e->getMD5Text());
@@ -94,6 +97,7 @@
            e->swap_dirn << " to " << sc->swapin_sio->swap_filen << "/" <<
            sc->swapin_sio->swap_dirn);
 
+    assert(e->swap_filen < 0); // if this fails, call SwapDir::disconnect(e)
     e->swap_filen = sc->swapin_sio->swap_filen;
     e->swap_dirn = sc->swapin_sio->swap_dirn;
 }
diff -u -r -N squid-3.2.0.12/src/store_swapmeta.cc squid-3.2.0.13/src/store_swapmeta.cc
--- squid-3.2.0.12/src/store_swapmeta.cc	2011-09-16 23:37:30.000000000 +1200
+++ squid-3.2.0.13/src/store_swapmeta.cc	2011-10-14 14:42:56.000000000 +1300
@@ -61,8 +61,8 @@
     tlv **T = &TLV;
     const char *url;
     const char *vary;
-    const int64_t objsize = e->objectLen();
     assert(e->mem_obj != NULL);
+    const int64_t objsize = e->mem_obj->expectedReplySize();
     assert(e->swap_status == SWAPOUT_WRITING);
     url = e->url();
     debugs(20, 3, "storeSwapMetaBuild: " << url  );
diff -u -r -N squid-3.2.0.12/src/store_swapout.cc squid-3.2.0.13/src/store_swapout.cc
--- squid-3.2.0.12/src/store_swapout.cc	2011-09-16 23:37:30.000000000 +1200
+++ squid-3.2.0.13/src/store_swapout.cc	2011-10-14 14:42:56.000000000 +1300
@@ -85,6 +85,7 @@
 
     if (sio == NULL) {
         e->swap_status = SWAPOUT_NONE;
+        mem->swapout.decision = MemObject::SwapOut::swImpossible;
         delete c;
         xfree((char*)buf);
         storeLog(STORE_LOG_SWAPOUTFAIL, e);
@@ -115,6 +116,7 @@
     assert(mem);
     assert(mem->swapout.sio == self);
     assert(errflag == 0);
+    assert(e->swap_filen < 0); // if this fails, call SwapDir::disconnect(e)
     e->swap_filen = mem->swapout.sio->swap_filen;
     e->swap_dirn = mem->swapout.sio->swap_dirn;
 }
@@ -125,22 +127,16 @@
     MemObject *mem = anEntry->mem_obj;
 
     do {
-        /*
-         * Evil hack time.
-         * We are paging out to disk in page size chunks. however, later on when
-         * we update the queue position, we might not have a page (I *think*),
-         * so we do the actual page update here.
-         */
-
-        if (mem->swapout.memnode == NULL) {
-            /* We need to swap out the first page */
-            mem->swapout.memnode = const_cast<mem_node *>(mem->data_hdr.start());
-        } else {
-            /* We need to swap out the next page */
-            /* 20030636 RBC - we don't have ->next anymore.
-             * But we do have the next location */
-            mem->swapout.memnode = mem->data_hdr.getBlockContainingLocation (mem->swapout.memnode->end());
-        }
+        // find the page containing the first byte we have not swapped out yet
+        mem_node *page =
+            mem->data_hdr.getBlockContainingLocation(mem->swapout.queue_offset);
+
+        if (!page)
+            return; // wait for more data to become available
+
+        // memNodeWriteComplete() and absence of buffer offset math below
+        // imply that we always write from the very beginning of the page
+        assert(page->start() == mem->swapout.queue_offset);
 
         /*
          * Get the length of this buffer. We are assuming(!) that the buffer
@@ -150,7 +146,7 @@
          * but we can look at this at a later date or whenever the code results
          * in bad swapouts, whichever happens first. :-)
          */
-        ssize_t swap_buf_len = mem->swapout.memnode->nodeBuffer.length;
+        ssize_t swap_buf_len = page->nodeBuffer.length;
 
         debugs(20, 3, "storeSwapOut: swap_buf_len = " << swap_buf_len);
 
@@ -161,7 +157,7 @@
         mem->swapout.queue_offset += swap_buf_len;
 
         storeIOWrite(mem->swapout.sio,
-                     mem->data_hdr.NodeGet(mem->swapout.memnode),
+                     mem->data_hdr.NodeGet(page),
                      swap_buf_len,
                      -1,
                      memNodeWriteComplete);
@@ -194,6 +190,9 @@
     if (!swapoutPossible())
         return;
 
+    // Aborted entries have STORE_OK, but swapoutPossible rejects them. Thus,
+    // store_status == STORE_OK below means we got everything we wanted.
+
     debugs(20, 7, HERE << "storeSwapOut: mem->inmem_lo = " << mem_obj->inmem_lo);
     debugs(20, 7, HERE << "storeSwapOut: mem->endOffset() = " << mem_obj->endOffset());
     debugs(20, 7, HERE << "storeSwapOut: swapout.queue_offset = " << mem_obj->swapout.queue_offset);
@@ -201,6 +200,7 @@
     if (mem_obj->swapout.sio != NULL)
         debugs(20, 7, "storeSwapOut: storeOffset() = " << mem_obj->swapout.sio->offset()  );
 
+    // buffered bytes we have not swapped out yet
     int64_t swapout_maxsize = mem_obj->endOffset() - mem_obj->swapout.queue_offset;
 
     assert(swapout_maxsize >= 0);
@@ -209,25 +209,29 @@
 
     debugs(20, 7, HERE << "storeSwapOut: lowest_offset = " << lowest_offset);
 
-    /*
-     * Grab the swapout_size and check to see whether we're going to defer
-     * the swapout based upon size
-     */
-    if ((store_status != STORE_OK) && (swapout_maxsize < store_maxobjsize)) {
-        /*
-         * NOTE: the store_maxobjsize here is the max of optional
-         * max-size values from 'cache_dir' lines.  It is not the
-         * same as 'maximum_object_size'.  By default, store_maxobjsize
-         * will be set to -1.  However, I am worried that this
-         * deferance may consume a lot of memory in some cases.
-         * It would be good to make this decision based on reply
-         * content-length, rather than wait to accumulate huge
-         * amounts of object data in memory.
-         */
-        debugs(20, 5, "storeSwapOut: Deferring starting swapping out");
-        return;
+    // Check to see whether we're going to defer the swapout based upon size
+    if (store_status != STORE_OK) {
+        const int64_t expectedSize = mem_obj->expectedReplySize();
+        const int64_t maxKnownSize = expectedSize < 0 ?
+                                     swapout_maxsize : expectedSize;
+        debugs(20, 7, HERE << "storeSwapOut: maxKnownSize= " << maxKnownSize);
+
+        if (maxKnownSize < store_maxobjsize) {
+            /*
+             * NOTE: the store_maxobjsize here is the max of optional
+             * max-size values from 'cache_dir' lines.  It is not the
+             * same as 'maximum_object_size'.  By default, store_maxobjsize
+             * will be set to -1.  However, I am worried that this
+             * deferance may consume a lot of memory in some cases.
+             * Should we add an option to limit this memory consumption?
+             */
+            debugs(20, 5, "storeSwapOut: Deferring swapout start for " <<
+                   (store_maxobjsize - maxKnownSize) << " bytes");
+            return;
+        }
     }
 
+// TODO: it is better to trim as soon as we swap something out, not before
     trimMemory();
 #if SIZEOF_OFF_T <= 4
 
@@ -246,11 +250,13 @@
 
     debugs(20, 7, "storeSwapOut: swapout_size = " << swapout_maxsize);
 
-    if (swapout_maxsize == 0) {
-        if (store_status == STORE_OK)
-            swapOutFileClose();
-
-        return;			/* Nevermore! */
+    if (swapout_maxsize == 0) { // swapped everything we got
+        if (store_status == STORE_OK) { // got everything we wanted
+            assert(mem_obj->object_sz >= 0);
+            swapOutFileClose(StoreIOState::wroteAll);
+        }
+        // else need more data to swap out
+        return;
     }
 
     if (store_status == STORE_PENDING) {
@@ -271,13 +277,7 @@
     if (swap_status == SWAPOUT_NONE) {
         assert(mem_obj->swapout.sio == NULL);
         assert(mem_obj->inmem_lo == 0);
-
-        if (checkCachable())
-            storeSwapOutStart(this);
-        else
-            return;
-
-        /* ENTRY_CACHABLE will be cleared and we'll never get here again */
+        storeSwapOutStart(this); // sets SwapOut::swImpossible on failures
     }
 
     if (mem_obj->swapout.sio == NULL)
@@ -295,22 +295,23 @@
          * to the filesystem at this point because storeSwapOut() is
          * not going to be called again for this entry.
          */
+        assert(mem_obj->object_sz >= 0);
         assert(mem_obj->endOffset() == mem_obj->swapout.queue_offset);
-        swapOutFileClose();
+        swapOutFileClose(StoreIOState::wroteAll);
     }
 }
 
 void
-StoreEntry::swapOutFileClose()
+StoreEntry::swapOutFileClose(int how)
 {
     assert(mem_obj != NULL);
-    debugs(20, 3, "storeSwapOutFileClose: " << getMD5Text());
+    debugs(20, 3, "storeSwapOutFileClose: " << getMD5Text() << " how=" << how);
     debugs(20, 3, "storeSwapOutFileClose: sio = " << mem_obj->swapout.sio.getRaw());
 
     if (mem_obj->swapout.sio == NULL)
         return;
 
-    storeClose(mem_obj->swapout.sio);
+    storeClose(mem_obj->swapout.sio, how);
 }
 
 static void
@@ -323,11 +324,11 @@
     assert(e->swap_status == SWAPOUT_WRITING);
     cbdataFree(c);
 
-    if (errflag) {
-        debugs(20, 1, "storeSwapOutFileClosed: dirno " << e->swap_dirn << ", swapfile " <<
+    // if object_size is still unknown, the entry was probably aborted
+    if (errflag || e->objectLen() < 0) {
+        debugs(20, 2, "storeSwapOutFileClosed: dirno " << e->swap_dirn << ", swapfile " <<
                std::hex << std::setw(8) << std::setfill('0') << std::uppercase <<
                e->swap_filen << ", errflag=" << errflag);
-        debugs(20, 1, "\t" << xstrerror());
 
         if (errflag == DISK_NO_SPACE_LEFT) {
             /* FIXME: this should be handle by the link from store IO to
@@ -337,14 +338,10 @@
             storeConfigure();
         }
 
-        if (e->swap_filen > 0)
+        if (e->swap_filen >= 0)
             e->unlink();
 
-        e->swap_filen = -1;
-
-        e->swap_dirn = -1;
-
-        e->swap_status = SWAPOUT_NONE;
+        assert(e->swap_status == SWAPOUT_NONE);
 
         e->releaseRequest();
     } else {
@@ -352,10 +349,17 @@
         debugs(20, 3, "storeSwapOutFileClosed: SwapOut complete: '" << e->url() << "' to " <<
                e->swap_dirn  << ", " << std::hex << std::setw(8) << std::setfill('0') <<
                std::uppercase << e->swap_filen);
+        debugs(20, 5, HERE << "swap_file_sz = " <<
+               e->objectLen() << " + " << mem->swap_hdr_sz);
+
         e->swap_file_sz = e->objectLen() + mem->swap_hdr_sz;
         e->swap_status = SWAPOUT_DONE;
-        e->store()->updateSize(e->swap_file_sz, 1);
+        e->store()->swappedOut(*e);
 
+        // XXX: For some Stores, it is pointless to re-check cachability here
+        // and it leads to double counts in store_check_cachable_hist. We need
+        // another way to signal a completed but failed swapout. Or, better,
+        // each Store should handle its own logging and LOG state setting.
         if (e->checkCachable()) {
             storeLog(STORE_LOG_SWAPOUT, e);
             storeDirSwapLog(e, SWAP_LOG_ADD);
diff -u -r -N squid-3.2.0.12/src/structs.h squid-3.2.0.13/src/structs.h
--- squid-3.2.0.12/src/structs.h	2011-09-16 23:37:30.000000000 +1200
+++ squid-3.2.0.13/src/structs.h	2011-10-14 14:42:56.000000000 +1300
@@ -144,7 +144,30 @@
 class CpuAffinityMap;
 class RemovalPolicySettings;
 class external_acl;
-class Store;
+class SwapDir;
+
+/// Used for boolean enabled/disabled options with complex default logic.
+/// Allows Squid to compute the right default after configuration.
+/// Checks that not-yet-defined option values are not used.
+class YesNoNone
+{
+// TODO: generalize to non-boolean option types
+public:
+    YesNoNone(): option(0) {}
+
+    /// returns true iff enabled; asserts if the option has not been configured
+    operator void *() const; // TODO: use a fancy/safer version of the operator
+
+    /// enables or disables the option;
+    void configure(bool beSet);
+
+    /// whether the option was enabled or disabled, by user or Squid
+    bool configured() const { return option != 0; }
+
+private:
+    enum { optUnspecified = -1, optDisabled = 0, optEnabled = 1 };
+    int option; ///< configured value or zero
+};
 
 struct SquidConfig {
 
@@ -155,6 +178,8 @@
         int highWaterMark;
         int lowWaterMark;
     } Swap;
+
+    YesNoNone memShared; ///< whether the memory cache is shared among workers
     size_t memMaxSize;
 
     struct {
@@ -435,6 +460,7 @@
         int WIN32_IpAddrChangeMonitor;
         int memory_cache_first;
         int memory_cache_disk;
+        int hostStrictVerify;
         int client_dst_passthru;
     } onoff;
 
@@ -496,9 +522,11 @@
     refresh_t *Refresh;
 
     struct _cacheSwap {
-        RefCount<class Store> *swapDirs;
+        RefCount<SwapDir> *swapDirs;
         int n_allocated;
         int n_configured;
+        /// number of disk processes required to support all cache_dirs
+        int n_strands;
     } cacheSwap;
     /*
      * I'm sick of having to keep doing this ..
@@ -617,6 +645,7 @@
     int client_ip_max_connections;
 
     struct {
+        int v4_first;       ///< Place IPv4 first in the order of DNS results.
         ssize_t packet_max; ///< maximum size EDNS advertised for DNS replies.
     } dns;
 };
@@ -696,21 +725,6 @@
     String value;		/* field-value from HTTP/1.1 */
 };
 
-/* http cache control header field */
-
-class HttpHdrCc
-{
-
-public:
-    int mask;
-    int max_age;
-    int s_maxage;
-    int max_stale;
-    int stale_if_error;
-    int min_fresh;
-    String other;
-};
-
 /* per field statistics */
 
 class HttpHeaderFieldStat
diff -u -r -N squid-3.2.0.12/src/SwapDir.cc squid-3.2.0.13/src/SwapDir.cc
--- squid-3.2.0.12/src/SwapDir.cc	2011-09-16 23:37:30.000000000 +1200
+++ squid-3.2.0.13/src/SwapDir.cc	2011-10-14 14:42:56.000000000 +1300
@@ -38,8 +38,18 @@
 #include "StoreFileSystem.h"
 #include "ConfigOption.h"
 
+SwapDir::SwapDir(char const *aType): theType(aType),
+        max_size(0),
+        path(NULL), index(-1), disker(-1), min_objsize(0), max_objsize (-1),
+        repl(NULL), removals(0), scanned(0),
+        cleanLog(NULL)
+{
+    fs.blksize = 1024;
+}
+
 SwapDir::~SwapDir()
 {
+    // TODO: should we delete repl?
     xfree(path);
 }
 
@@ -61,6 +71,9 @@
 void
 SwapDir::stat(StoreEntry &output) const
 {
+    if (!doReportStat())
+        return;
+
     storeAppendPrintf(&output, "Store Directory #%d (%s): %s\n", index, type(),
                       path);
     storeAppendPrintf(&output, "FS Block Size %d Bytes\n",
@@ -90,8 +103,11 @@
 void
 SwapDir::reference(StoreEntry &) {}
 
-void
-SwapDir::dereference(StoreEntry &) {}
+bool
+SwapDir::dereference(StoreEntry &)
+{
+    return true; // keep in global store_table
+}
 
 int
 SwapDir::callback()
@@ -99,6 +115,30 @@
     return 0;
 }
 
+bool
+SwapDir::canStore(const StoreEntry &e, int64_t diskSpaceNeeded, int &load) const
+{
+    debugs(47,8, HERE << "cache_dir[" << index << "]: needs " <<
+           diskSpaceNeeded << " <? " << max_objsize);
+
+    if (EBIT_TEST(e.flags, ENTRY_SPECIAL))
+        return false; // we do not store Squid-generated entries
+
+    if (!objectSizeIsAcceptable(diskSpaceNeeded))
+        return false; // does not satisfy size limits
+
+    if (flags.read_only)
+        return false; // cannot write at all
+
+    if (currentSize() > maxSize())
+        return false; // already overflowing
+
+    /* Return 999 (99.9%) constant load; TODO: add a named constant for this */
+    load = 999;
+    return true; // kids may provide more tests and should report true load
+}
+
+
 void
 SwapDir::sync() {}
 
@@ -151,6 +191,25 @@
     return theType;
 }
 
+bool
+SwapDir::active() const
+{
+    if (IamWorkerProcess())
+        return true;
+
+    // we are inside a disker dedicated to this disk
+    if (KidIdentifier == disker)
+        return true;
+
+    return false; // Coordinator, wrong disker, etc.
+}
+
+bool
+SwapDir::needsDiskStrand() const
+{
+    return false;
+}
+
 /* NOT performance critical. Really. Don't bother optimising for speed
  * - RBC 20030718
  */
@@ -251,8 +310,17 @@
 
     int64_t size = strtoll(value, NULL, 10);
 
-    if (isaReconfig && *val != size)
-        debugs(3, 1, "Cache dir '" << path << "' object " << option << " now " << size);
+    if (isaReconfig && *val != size) {
+        if (allowOptionReconfigure(option)) {
+            debugs(3, DBG_IMPORTANT, "cache_dir '" << path << "' object " <<
+                   option << " now " << size << " Bytes");
+        } else {
+            debugs(3, DBG_IMPORTANT, "WARNING: cache_dir '" << path << "' "
+                   "object " << option << " cannot be changed dynamically, " <<
+                   "value left unchanged (" << *val << " Bytes)");
+            return true;
+        }
+    }
 
     *val = size;
 
@@ -269,13 +337,11 @@
         storeAppendPrintf(e, " max-size=%"PRId64, max_objsize);
 }
 
-/* Swapdirs do not have an index of their own - thus they ask their parent..
- * but the parent child relationship isn't implemented yet
- */
+// some SwapDirs may maintain their indexes and be able to lookup an entry key
 StoreEntry *
 SwapDir::get(const cache_key *key)
 {
-    return Store::Root().get(key);
+    return NULL;
 }
 
 void
diff -u -r -N squid-3.2.0.12/src/SwapDir.h squid-3.2.0.13/src/SwapDir.h
--- squid-3.2.0.12/src/SwapDir.h	2011-09-16 23:37:30.000000000 +1200
+++ squid-3.2.0.13/src/SwapDir.h	2011-10-14 14:42:56.000000000 +1300
@@ -37,14 +37,14 @@
 
 /* forward decls */
 class RemovalPolicy;
+class MemStore;
 
 /* Store dir configuration routines */
 /* SwapDir *sd, char *path ( + char *opt later when the strtok mess is gone) */
 
 class ConfigOption;
 
-/* New class that replaces the static SwapDir methods as part of the Store overhaul */
-
+/// hides memory/disk cache distinction from callers
 class StoreController : public Store
 {
 
@@ -58,6 +58,9 @@
 
     virtual void get(String const, STOREGETCLIENT, void * cbdata);
 
+    /* Store parent API */
+    virtual void handleIdleEntry(StoreEntry &e);
+
     virtual void init();
 
     virtual void maintain(); /* perform regular maintenance should be private and self registered ... */
@@ -66,6 +69,12 @@
 
     virtual uint64_t minSize() const;
 
+    virtual uint64_t currentSize() const;
+
+    virtual uint64_t currentCount() const;
+
+    virtual int64_t maxObjectSize() const;
+
     virtual void stat(StoreEntry &) const;
 
     virtual void sync();	/* Sync the store prior to shutdown */
@@ -74,9 +83,7 @@
 
     virtual void reference(StoreEntry &);	/* Reference this object */
 
-    virtual void dereference(StoreEntry &);	/* Unreference this object */
-
-    virtual void updateSize(int64_t size, int sign);
+    virtual bool dereference(StoreEntry &);	/* Unreference this object */
 
     /* the number of store dirs being rebuilt. */
     static int store_dirs_rebuilding;
@@ -84,7 +91,8 @@
 private:
     void createOneStore(Store &aStore);
 
-    StorePointer swapDir;
+    StorePointer swapDir; ///< summary view of all disk caches
+    MemStore *memStore; ///< memory cache
 };
 
 /* migrating from the Config based list of swapdirs */
@@ -108,20 +116,23 @@
 SQUIDCEXTERN int storeDirGetBlkSize(const char *path, int *blksize);
 SQUIDCEXTERN int storeDirGetUFSStats(const char *, int *, int *, int *, int *);
 
-
+/// manages a single cache_dir
 class SwapDir : public Store
 {
 
 public:
-    SwapDir(char const *aType) : theType (aType), cur_size(0), max_size(0), min_objsize(0), max_objsize(-1), cleanLog(NULL) {
-        fs.blksize = 1024;
-        path = NULL;
-    }
+    typedef RefCount<SwapDir> Pointer;
 
+    SwapDir(char const *aType);
     virtual ~SwapDir();
-    virtual void reconfigure(int, char *) = 0;
+    virtual void reconfigure() = 0;
     char const *type() const;
 
+    virtual bool needsDiskStrand() const; ///< needs a dedicated kid process
+    virtual bool active() const; ///< may be used in this strand
+    /// whether stat should be reported by this SwapDir
+    virtual bool doReportStat() const { return active(); }
+
     /* official Store interface functions */
     virtual void diskFull();
 
@@ -132,18 +143,28 @@
     virtual uint64_t maxSize() const { return max_size;}
 
     virtual uint64_t minSize() const;
+
+    virtual int64_t maxObjectSize() const { return max_objsize; }
+
     virtual void stat (StoreEntry &anEntry) const;
     virtual StoreSearch *search(String const url, HttpRequest *) = 0;
 
-    virtual void updateSize(int64_t size, int sign);
-
     /* migrated from store_dir.cc */
     bool objectSizeIsAcceptable(int64_t objsize) const;
 
+    /// called when the entry is about to forget its association with cache_dir
+    virtual void disconnect(StoreEntry &) {}
+
+    /// called when entry swap out is complete
+    virtual void swappedOut(const StoreEntry &e) = 0;
+
 protected:
     void parseOptions(int reconfiguring);
     void dumpOptions(StoreEntry * e) const;
     virtual ConfigOption *getOptionTree() const;
+    virtual bool allowOptionReconfigure(const char *const) const { return true; }
+
+    int64_t sizeInBlocks(const int64_t size) const { return (size + fs.blksize - 1) / fs.blksize; }
 
 private:
     bool optionReadOnlyParse(char const *option, const char *value, int reconfiguring);
@@ -152,11 +173,13 @@
     void optionObjectSizeDump(StoreEntry * e) const;
     char const *theType;
 
-public:
-    uint64_t cur_size;        ///< currently used space in the storage area
+protected:
     uint64_t max_size;        ///< maximum allocatable size of the storage area
+
+public:
     char *path;
     int index;			/* This entry's index into the swapDirs array */
+    int disker; ///< disker kid id dedicated to this SwapDir or -1
     int64_t min_objsize;
     int64_t max_objsize;
     RemovalPolicy *repl;
@@ -174,11 +197,11 @@
     virtual bool doubleCheck(StoreEntry &);	/* Double check the obj integrity */
     virtual void statfs(StoreEntry &) const;	/* Dump fs statistics */
     virtual void maintain();	/* Replacement maintainence */
-    /* <0 == error. > 1000 == error */
-    virtual int canStore(StoreEntry const &)const = 0; /* Check if the fs will store an object */
+    /// check whether we can store the entry; if we can, report current load
+    virtual bool canStore(const StoreEntry &e, int64_t diskSpaceNeeded, int &load) const = 0;
     /* These two are notifications */
     virtual void reference(StoreEntry &);	/* Reference this object */
-    virtual void dereference(StoreEntry &);	/* Unreference this object */
+    virtual bool dereference(StoreEntry &);	/* Unreference this object */
     virtual int callback();	/* Handle pending callbacks */
     virtual void sync();	/* Sync the store prior to shutdown */
     virtual StoreIOState::Pointer createStoreIO(StoreEntry &, StoreIOState::STFNCB *, StoreIOState::STIOCB *, void *) = 0;
diff -u -r -N squid-3.2.0.12/src/tests/stub_cache_cf.cc squid-3.2.0.13/src/tests/stub_cache_cf.cc
--- squid-3.2.0.12/src/tests/stub_cache_cf.cc	2011-09-16 23:37:30.000000000 +1200
+++ squid-3.2.0.13/src/tests/stub_cache_cf.cc	2011-10-14 14:42:56.000000000 +1300
@@ -115,6 +115,12 @@
     fatal("not implemented 11");
 }
 
+YesNoNone::operator void*() const
+{
+    /* ignore this for testing  */
+    return NULL;
+}
+
 /*
  * DO NOT MODIFY:
  * arch-tag: 9bbc3b5f-8d7b-4fdc-af59-0b524a785307
diff -u -r -N squid-3.2.0.12/src/tests/stub_HelperChildConfig.cc squid-3.2.0.13/src/tests/stub_HelperChildConfig.cc
--- squid-3.2.0.12/src/tests/stub_HelperChildConfig.cc	2011-09-16 23:37:30.000000000 +1200
+++ squid-3.2.0.13/src/tests/stub_HelperChildConfig.cc	2011-10-14 14:42:56.000000000 +1300
@@ -4,25 +4,15 @@
 
 #include <string.h>
 
-HelperChildConfig::HelperChildConfig(const unsigned int m, const unsigned int s, const unsigned int i, const unsigned int cc) :
+HelperChildConfig::HelperChildConfig(const unsigned int m):
         n_max(m),
-        n_startup(s),
-        n_idle(i),
-        concurrency(cc),
+        n_startup(0),
+        n_idle(1),
+        concurrency(0),
         n_running(0),
         n_active(0)
 {}
 
-HelperChildConfig::~HelperChildConfig()
-{}
-
-HelperChildConfig &
-HelperChildConfig::operator =(const HelperChildConfig &rhs)
-{
-    memcpy(this, &rhs, sizeof(HelperChildConfig));
-    return *this;
-}
-
 int
 HelperChildConfig::needNew() const
 {
diff -u -r -N squid-3.2.0.12/src/tests/stub_HttpReply.cc squid-3.2.0.13/src/tests/stub_HttpReply.cc
--- squid-3.2.0.12/src/tests/stub_HttpReply.cc	2011-09-16 23:37:30.000000000 +1200
+++ squid-3.2.0.13/src/tests/stub_HttpReply.cc	2011-10-14 14:42:56.000000000 +1300
@@ -122,3 +122,10 @@
     fatal("Not implemented");
     return false;
 }
+
+int64_t
+HttpReply::bodySize(const HttpRequestMethod&) const
+{
+    fatal("Not implemented");
+    return 0;
+}
diff -u -r -N squid-3.2.0.12/src/tests/stub_HttpRequest.cc squid-3.2.0.13/src/tests/stub_HttpRequest.cc
--- squid-3.2.0.12/src/tests/stub_HttpRequest.cc	2011-09-16 23:37:30.000000000 +1200
+++ squid-3.2.0.13/src/tests/stub_HttpRequest.cc	2011-10-14 14:42:56.000000000 +1300
@@ -108,6 +108,13 @@
     return false;
 }
 
+int64_t
+HttpRequest::getRangeOffsetLimit()
+{
+    fatal("Not implemented");
+    return 0;
+}
+
 /*
  * DO NOT MODIFY:
  * arch-tag: dd894aa8-63cc-4543-92d9-1079a18bee11
diff -u -r -N squid-3.2.0.12/src/tests/stub_libcomm.cc squid-3.2.0.13/src/tests/stub_libcomm.cc
--- squid-3.2.0.12/src/tests/stub_libcomm.cc	1970-01-01 12:00:00.000000000 +1200
+++ squid-3.2.0.13/src/tests/stub_libcomm.cc	2011-10-14 14:42:56.000000000 +1300
@@ -0,0 +1,60 @@
+#include "config.h"
+#include "base/AsyncJob.h"
+#include "structs.h"
+
+#define STUB_API "comm/libcomm.la"
+#include "tests/STUB.h"
+
+#include "comm/AcceptLimiter.h"
+Comm::AcceptLimiter dummy;
+Comm::AcceptLimiter & Comm::AcceptLimiter::Instance() STUB_RETVAL(dummy)
+void Comm::AcceptLimiter::defer(Comm::TcpAcceptor *afd) STUB
+void Comm::AcceptLimiter::removeDead(const Comm::TcpAcceptor *afd) STUB
+void Comm::AcceptLimiter::kick() STUB
+
+#include "comm/Connection.h"
+Comm::Connection::Connection() STUB
+Comm::Connection::~Connection() STUB
+Comm::ConnectionPointer Comm::Connection::copyDetails() const STUB_RETVAL(NULL)
+void Comm::Connection::close() STUB
+peer * Comm::Connection::getPeer() const STUB_RETVAL(NULL)
+void Comm::Connection::setPeer(peer * p) STUB
+
+#include "comm/ConnOpener.h"
+bool Comm::ConnOpener::doneAll() const STUB_RETVAL(false)
+//Comm::ConnOpener::ConnOpener(Comm::ConnectionPointer &, AsyncCall::Pointer &, time_t) STUB
+//Comm::ConnOpener::~ConnOpener() STUB
+void Comm::ConnOpener::setHost(const char *) STUB
+const char * Comm::ConnOpener::getHost() const STUB_RETVAL(NULL)
+
+#include "comm/forward.h"
+bool Comm::IsConnOpen(const Comm::ConnectionPointer &) STUB_RETVAL(false)
+
+#include "comm/IoCallback.h"
+void Comm::IoCallback::setCallback(iocb_type type, AsyncCall::Pointer &cb, char *buf, FREE *func, int sz) STUB
+void Comm::IoCallback::selectOrQueueWrite() STUB
+void Comm::IoCallback::cancel(const char *reason) STUB
+void Comm::IoCallback::finish(comm_err_t code, int xerrn) STUB
+Comm::CbEntry *Comm::iocb_table = NULL;
+void Comm::CallbackTableInit() STUB
+void Comm::CallbackTableDestruct() STUB
+
+#include "comm/Loops.h"
+void Comm::SelectLoopInit(void) STUB
+void Comm::SetSelect(int, unsigned int, PF *, void *, time_t) STUB
+void Comm::ResetSelect(int) STUB
+comm_err_t Comm::DoSelect(int) STUB_RETVAL(COMM_ERROR)
+void Comm::QuickPollRequired(void) STUB
+
+#include "comm/TcpAcceptor.h"
+//Comm::TcpAcceptor(const Comm::ConnectionPointer &conn, const char *note, const Subscription::Pointer &aSub) STUB
+void Comm::TcpAcceptor::subscribe(const Subscription::Pointer &aSub) STUB
+void Comm::TcpAcceptor::unsubscribe(const char *) STUB
+void Comm::TcpAcceptor::acceptNext() STUB
+void Comm::TcpAcceptor::notify(const comm_err_t flag, const Comm::ConnectionPointer &) const STUB
+
+#include "comm/Write.h"
+void Comm::Write(const Comm::ConnectionPointer &, const char *, int, AsyncCall::Pointer &, FREE *) STUB
+void Comm::Write(const Comm::ConnectionPointer &conn, MemBuf *mb, AsyncCall::Pointer &callback) STUB
+void Comm::WriteCancel(const Comm::ConnectionPointer &conn, const char *reason) STUB
+//PF Comm::HandleWrite STUB
diff -u -r -N squid-3.2.0.12/src/tests/stub_MemObject.cc squid-3.2.0.13/src/tests/stub_MemObject.cc
--- squid-3.2.0.12/src/tests/stub_MemObject.cc	2011-09-16 23:37:30.000000000 +1200
+++ squid-3.2.0.13/src/tests/stub_MemObject.cc	2011-10-14 14:42:56.000000000 +1300
@@ -180,3 +180,22 @@
     fatal ("MemObject.cc required.");
     return false;
 }
+
+int64_t
+MemObject::expectedReplySize() const
+{
+    fatal ("MemObject.cc required.");
+    return 0;
+}
+
+void
+MemObject::resetUrls(char const*, char const*)
+{
+    fatal ("MemObject.cc required.");
+}
+
+void
+MemObject::markEndOfReplyHeaders()
+{
+    fatal ("MemObject.cc required.");
+}
diff -u -r -N squid-3.2.0.12/src/tests/stub_MemStore.cc squid-3.2.0.13/src/tests/stub_MemStore.cc
--- squid-3.2.0.12/src/tests/stub_MemStore.cc	1970-01-01 12:00:00.000000000 +1200
+++ squid-3.2.0.13/src/tests/stub_MemStore.cc	2011-10-14 14:42:56.000000000 +1300
@@ -0,0 +1,31 @@
+/*
+ * $Id$
+ *
+ * DEBUG: section 84    Helper process maintenance
+ *
+ */
+
+#include "config.h"
+#include "MemStore.h"
+
+#define STUB_API "MemStore.cc"
+#include "tests/STUB.h"
+
+MemStore::MemStore() STUB
+MemStore::~MemStore() STUB
+void MemStore::considerKeeping(StoreEntry &) STUB
+void MemStore::reference(StoreEntry &) STUB
+void MemStore::maintain() STUB
+void MemStore::cleanReadable(const sfileno) STUB
+void MemStore::get(String const, STOREGETCLIENT, void *) STUB
+void MemStore::init() STUB
+void MemStore::stat(StoreEntry &) const STUB
+int MemStore::callback() STUB_RETVAL(0)
+StoreEntry *MemStore::get(const cache_key *) STUB_RETVAL(NULL)
+uint64_t MemStore::maxSize() const STUB_RETVAL(0)
+uint64_t MemStore::minSize() const STUB_RETVAL(0)
+uint64_t MemStore::currentSize() const STUB_RETVAL(0)
+uint64_t MemStore::currentCount() const STUB_RETVAL(0)
+int64_t MemStore::maxObjectSize() const STUB_RETVAL(0)
+StoreSearch *MemStore::search(String const, HttpRequest *) STUB_RETVAL(NULL)
+bool MemStore::dereference(StoreEntry &) STUB_RETVAL(false)
diff -u -r -N squid-3.2.0.12/src/tests/stub_Port.cc squid-3.2.0.13/src/tests/stub_Port.cc
--- squid-3.2.0.12/src/tests/stub_Port.cc	2011-09-16 23:37:30.000000000 +1200
+++ squid-3.2.0.13/src/tests/stub_Port.cc	2011-10-14 14:42:56.000000000 +1300
@@ -1,4 +1,10 @@
 #include "config.h"
 #include "ipc/Port.h"
 
+#define STUB_API "ipc/Port.cc"
+#include "tests/STUB.h"
+
 const char Ipc::coordinatorAddr[] = "";
+const char Ipc::strandAddrPfx[] = "";
+
+String Ipc::Port::MakeAddr(char const*, int) STUB_RETVAL("")
diff -u -r -N squid-3.2.0.12/src/tests/stub_store.cc squid-3.2.0.13/src/tests/stub_store.cc
--- squid-3.2.0.12/src/tests/stub_store.cc	2011-09-16 23:37:30.000000000 +1200
+++ squid-3.2.0.13/src/tests/stub_store.cc	2011-10-14 14:42:56.000000000 +1300
@@ -17,6 +17,7 @@
 const char *StoreEntry::getMD5Text() const STUB_RETVAL(NULL)
 StoreEntry::StoreEntry() STUB
 StoreEntry::StoreEntry(const char *url, const char *log_url) STUB
+StoreEntry::~StoreEntry() STUB
 HttpReply const *StoreEntry::getReply() const STUB_RETVAL(NULL)
 void StoreEntry::write(StoreIOBuffer) STUB
 bool StoreEntry::isAccepting() const STUB_RETVAL(false)
@@ -24,7 +25,7 @@
 void StoreEntry::complete() STUB
 store_client_t StoreEntry::storeClientType() const STUB_RETVAL(STORE_NON_CLIENT)
 char const *StoreEntry::getSerialisedMetaData() STUB_RETVAL(NULL)
-void StoreEntry::replaceHttpReply(HttpReply *) STUB
+void StoreEntry::replaceHttpReply(HttpReply *, bool andStartWriting) STUB
 bool StoreEntry::swapoutPossible() STUB_RETVAL(false)
 void StoreEntry::trimMemory() STUB
 void StoreEntry::abort() STUB
@@ -41,14 +42,15 @@
 void StoreEntry::purgeMem() STUB
 void StoreEntry::swapOut() STUB
 bool StoreEntry::swapOutAble() const STUB_RETVAL(false)
-void StoreEntry::swapOutFileClose() STUB
+void StoreEntry::swapOutFileClose(int how) STUB
 const char *StoreEntry::url() const STUB_RETVAL(NULL)
 int StoreEntry::checkCachable() STUB_RETVAL(0)
 int StoreEntry::checkNegativeHit() const STUB_RETVAL(0)
 int StoreEntry::locked() const STUB_RETVAL(0)
 int StoreEntry::validToSend() const STUB_RETVAL(0)
-int StoreEntry::keepInMemory() const STUB_RETVAL(0)
+bool StoreEntry::memoryCachable() const STUB_RETVAL(false)
 void StoreEntry::createMemObject(const char *, const char *) STUB
+void StoreEntry::hideMemObject() STUB
 void StoreEntry::dump(int debug_lvl) const STUB
 void StoreEntry::hashDelete() STUB
 void StoreEntry::hashInsert(const cache_key *) STUB
@@ -64,7 +66,7 @@
 bool StoreEntry::modifiedSince(HttpRequest * request) const STUB_RETVAL(false)
 bool StoreEntry::hasIfMatchEtag(const HttpRequest &request) const STUB_RETVAL(false)
 bool StoreEntry::hasIfNoneMatchEtag(const HttpRequest &request) const STUB_RETVAL(false)
-RefCount<Store> StoreEntry::store() const STUB_RETVAL(StorePointer())
+RefCount<SwapDir> StoreEntry::store() const STUB_RETVAL(NULL)
 size_t StoreEntry::inUseCount() STUB_RETVAL(0)
 void StoreEntry::getPublicByRequestMethod(StoreClient * aClient, HttpRequest * request, const HttpRequestMethod& method) STUB
 void StoreEntry::getPublicByRequest(StoreClient * aClient, HttpRequest * request) STUB
@@ -103,6 +105,12 @@
 void Store::sync() STUB
 void Store::unlink(StoreEntry &) STUB
 
+std::ostream &operator <<(std::ostream &os, const StoreEntry &)
+{
+    STUB
+    return os;
+}
+
 SQUIDCEXTERN size_t storeEntryInUse() STUB_RETVAL(0)
 SQUIDCEXTERN const char *storeEntryFlags(const StoreEntry *) STUB_RETVAL(NULL)
 void storeEntryReplaceObject(StoreEntry *, HttpReply *) STUB
diff -u -r -N squid-3.2.0.12/src/tests/stub_store_rebuild.cc squid-3.2.0.13/src/tests/stub_store_rebuild.cc
--- squid-3.2.0.12/src/tests/stub_store_rebuild.cc	2011-09-16 23:37:30.000000000 +1200
+++ squid-3.2.0.13/src/tests/stub_store_rebuild.cc	2011-10-14 14:42:56.000000000 +1300
@@ -45,3 +45,21 @@
 storeRebuildComplete(struct _store_rebuild_data *dc)
 {}
 
+bool
+storeRebuildLoadEntry(int, int, MemBuf&, _store_rebuild_data&)
+{
+    return false;
+}
+
+bool
+storeRebuildKeepEntry(const StoreEntry &tmpe, const cache_key *key,
+                      struct _store_rebuild_data &counts)
+{
+    return false;
+}
+
+bool
+storeRebuildParseEntry(MemBuf &, StoreEntry &, cache_key *, struct _store_rebuild_data &, uint64_t)
+{
+    return false;
+}
diff -u -r -N squid-3.2.0.12/src/tests/stub_tools.cc squid-3.2.0.13/src/tests/stub_tools.cc
--- squid-3.2.0.12/src/tests/stub_tools.cc	2011-09-16 23:37:30.000000000 +1200
+++ squid-3.2.0.13/src/tests/stub_tools.cc	2011-10-14 14:42:56.000000000 +1300
@@ -54,6 +54,41 @@
     return memset(dst, val, sz);
 }
 
+bool
+IamWorkerProcess()
+{
+    fprintf(stderr, "Not implemented");
+    return true;
+}
+
+bool
+IamDiskProcess()
+{
+    fprintf(stderr, "Not implemented");
+    return false;
+}
+
+bool
+IamMasterProcess()
+{
+    fprintf(stderr, "Not implemented");
+    return false;
+}
+
+bool
+InDaemonMode()
+{
+    fprintf(stderr, "Not implemented");
+    return false;
+}
+
+bool
+UsingSmp()
+{
+    fprintf(stderr, "Not implemented");
+    return false;
+}
+
 void
 logsFlush(void)
 {
diff -u -r -N squid-3.2.0.12/src/tests/stub_TypedMsgHdr.cc squid-3.2.0.13/src/tests/stub_TypedMsgHdr.cc
--- squid-3.2.0.12/src/tests/stub_TypedMsgHdr.cc	2011-09-16 23:37:30.000000000 +1200
+++ squid-3.2.0.13/src/tests/stub_TypedMsgHdr.cc	1970-01-01 12:00:00.000000000 +1200
@@ -1,44 +0,0 @@
-#include "config.h"
-#include "fatal.h"
-#include "ipc/TypedMsgHdr.h"
-
-Ipc::TypedMsgHdr::TypedMsgHdr()
-{
-    fatal("Not implemented");
-}
-
-void
-Ipc::TypedMsgHdr::getFixed(void *raw, size_t size) const
-{
-    fatal("Not implemented");
-}
-
-void
-Ipc::TypedMsgHdr::putFixed(const void *raw, size_t size)
-{
-    fatal("Not implemented");
-}
-
-void
-Ipc::TypedMsgHdr::getString(String &size) const
-{
-    fatal("Not implemented");
-}
-
-void
-Ipc::TypedMsgHdr::putString(const String & size)
-{
-    fatal("Not implemented");
-}
-
-void
-Ipc::TypedMsgHdr::checkType(int destType) const
-{
-    fatal("Not implemented");
-}
-
-void
-Ipc::TypedMsgHdr::setType(int aType)
-{
-    fatal("Not implemented");
-}
diff -u -r -N squid-3.2.0.12/src/tests/testCoss.cc squid-3.2.0.13/src/tests/testCoss.cc
--- squid-3.2.0.12/src/tests/testCoss.cc	2011-09-16 23:37:30.000000000 +1200
+++ squid-3.2.0.13/src/tests/testCoss.cc	2011-10-14 14:42:56.000000000 +1300
@@ -80,9 +80,7 @@
     if (0 > system ("rm -rf " TESTDIR))
         throw std::runtime_error("Failed to clean test work directory");
 
-    StorePointer aRoot (new StoreController);
-
-    Store::Root(aRoot);
+    Store::Root(new StoreController);
 
     SwapDirPointer aStore (new CossSwapDir());
 
@@ -111,10 +109,10 @@
 
     /* TODO: check the size */
 
-    free_cachedir(&Config.cacheSwap);
-
     Store::Root(NULL);
 
+    free_cachedir(&Config.cacheSwap);
+
     /* todo: here we should test a dirty rebuild */
 
     //    safe_free(Config.replPolicy->type);
@@ -146,9 +144,7 @@
     if (0 > system ("rm -rf " TESTDIR))
         throw std::runtime_error("Failed to clean test work directory");
 
-    StorePointer aRoot (new StoreController);
-
-    Store::Root(aRoot);
+    Store::Root(new StoreController);
 
     SwapDirPointer aStore (new CossSwapDir());
 
@@ -257,10 +253,10 @@
     CPPUNIT_ASSERT(search->isDone() == true);
     CPPUNIT_ASSERT(search->currentItem() == NULL);
 
-    free_cachedir(&Config.cacheSwap);
-
     Store::Root(NULL);
 
+    free_cachedir(&Config.cacheSwap);
+
     /* todo: here we should test a dirty rebuild */
 
     //TODO: do this once, or each time.    safe_free(Config.replPolicy->type);
@@ -280,8 +276,7 @@
     if (0 > system ("rm -rf " TESTDIR))
         throw std::runtime_error("Failed to clean test work directory");
 
-    StorePointer aRoot (new StoreController);
-    Store::Root(aRoot);
+    Store::Root(new StoreController);
     SwapDirPointer aStore (new CossSwapDir());
     addSwapDir(aStore);
     commonInit();
@@ -294,8 +289,8 @@
     safe_free(config_line);
     CPPUNIT_ASSERT(aStore->io != NULL);
 
-    free_cachedir(&Config.cacheSwap);
     Store::Root(NULL);
+    free_cachedir(&Config.cacheSwap);
     if (0 > system ("rm -rf " TESTDIR))
         throw std::runtime_error("Failed to clean test work directory");
 }
diff -u -r -N squid-3.2.0.12/src/tests/testStore.cc squid-3.2.0.13/src/tests/testStore.cc
--- squid-3.2.0.12/src/tests/testStore.cc	2011-09-16 23:37:30.000000000 +1200
+++ squid-3.2.0.13/src/tests/testStore.cc	2011-10-14 14:42:56.000000000 +1300
@@ -6,9 +6,6 @@
 
 CPPUNIT_TEST_SUITE_REGISTRATION( testStore );
 
-// Stubs so this test will link cleanly
-#include "comm/stub_libcomm.cc"
-
 int
 TestStore::callback()
 {
@@ -41,6 +38,24 @@
 {
     return 1;
 }
+
+uint64_t
+TestStore::currentSize() const
+{
+    return 2;
+}
+
+uint64_t
+TestStore::currentCount() const
+{
+    return 2;
+}
+
+int64_t
+TestStore::maxObjectSize() const
+{
+    return 1;
+}
 
 void
 TestStore::stat(StoreEntry &) const
diff -u -r -N squid-3.2.0.12/src/tests/testStore.h squid-3.2.0.13/src/tests/testStore.h
--- squid-3.2.0.12/src/tests/testStore.h	2011-09-16 23:37:30.000000000 +1200
+++ squid-3.2.0.13/src/tests/testStore.h	2011-10-14 14:42:56.000000000 +1300
@@ -59,13 +59,17 @@
 
     virtual uint64_t minSize() const;
 
+    virtual uint64_t currentSize() const;
+
+    virtual uint64_t currentCount() const;
+
+    virtual int64_t maxObjectSize() const;
+
     virtual void stat(StoreEntry &) const; /* output stats to the provided store entry */
 
     virtual void reference(StoreEntry &) {}	/* Reference this object */
 
-    virtual void dereference(StoreEntry &) {}	/* Unreference this object */
-
-    virtual void updateSize(int64_t size, int sign) {}
+    virtual bool dereference(StoreEntry &) { return true; }
 
     virtual StoreSearch *search(String const url, HttpRequest *);
 };
diff -u -r -N squid-3.2.0.12/src/tests/TestSwapDir.cc squid-3.2.0.13/src/tests/TestSwapDir.cc
--- squid-3.2.0.12/src/tests/TestSwapDir.cc	2011-09-16 23:37:30.000000000 +1200
+++ squid-3.2.0.13/src/tests/TestSwapDir.cc	2011-10-14 14:42:56.000000000 +1300
@@ -9,6 +9,18 @@
     return 3;
 }
 
+uint64_t
+TestSwapDir::currentSize() const
+{
+    return 2;
+}
+
+uint64_t
+TestSwapDir::currentCount() const
+{
+    return 2;
+}
+
 void
 TestSwapDir::stat(StoreEntry &) const
 {
@@ -16,16 +28,17 @@
 }
 
 void
-TestSwapDir::reconfigure(int, char*)
+TestSwapDir::reconfigure()
 {}
 
 void
 TestSwapDir::init()
 {}
 
-int
-TestSwapDir::canStore(const StoreEntry&) const
+bool
+TestSwapDir::canStore(const StoreEntry &, int64_t, int &load) const
 {
+    load = 0;
     return true;
 }
 
diff -u -r -N squid-3.2.0.12/src/tests/TestSwapDir.h squid-3.2.0.13/src/tests/TestSwapDir.h
--- squid-3.2.0.12/src/tests/TestSwapDir.h	2011-09-16 23:37:30.000000000 +1200
+++ squid-3.2.0.13/src/tests/TestSwapDir.h	2011-10-14 14:42:56.000000000 +1300
@@ -13,11 +13,14 @@
     bool statsCalled;
 
     virtual uint64_t maxSize() const;
+    virtual uint64_t currentSize() const;
+    virtual uint64_t currentCount() const;
     virtual void stat(StoreEntry &) const; /* output stats to the provided store entry */
+    virtual void swappedOut(const StoreEntry &e) {}
 
-    virtual void reconfigure(int, char*);
+    virtual void reconfigure();
     virtual void init();
-    virtual int canStore(const StoreEntry&) const;
+    virtual bool canStore(const StoreEntry &e, int64_t diskSpaceNeeded, int &load) const;
     virtual StoreIOState::Pointer createStoreIO(StoreEntry &, StoreIOState::STFNCB *, StoreIOState::STIOCB *, void *);
     virtual StoreIOState::Pointer openStoreIO(StoreEntry &, StoreIOState::STFNCB *, StoreIOState::STIOCB *, void *);
     virtual void parse(int, char*);
diff -u -r -N squid-3.2.0.12/src/tests/testUfs.cc squid-3.2.0.13/src/tests/testUfs.cc
--- squid-3.2.0.12/src/tests/testUfs.cc	2011-09-16 23:37:30.000000000 +1200
+++ squid-3.2.0.13/src/tests/testUfs.cc	2011-10-14 14:42:56.000000000 +1300
@@ -87,9 +87,7 @@
     if (0 > system ("rm -rf " TESTDIR))
         throw std::runtime_error("Failed to clean test work directory");
 
-    StorePointer aRoot (new StoreController);
-
-    Store::Root(aRoot);
+    Store::Root(new StoreController);
 
     SwapDirPointer aStore (new UFSSwapDir("ufs", "Blocking"));
 
@@ -205,11 +203,12 @@
     CPPUNIT_ASSERT(search->isDone() == true);
     CPPUNIT_ASSERT(search->currentItem() == NULL);
 
+    Store::Root(NULL);
+
     free_cachedir(&Config.cacheSwap);
 
     /* todo: here we should test a dirty rebuild */
 
-    Store::Root(NULL);
     safe_free(Config.replPolicy->type);
     delete Config.replPolicy;
 
@@ -232,8 +231,7 @@
     // objects such as "StorePointer aRoot" from being called.
     CPPUNIT_ASSERT(!store_table); // or StoreHashIndex ctor will abort below
 
-    StorePointer aRoot (new StoreController);
-    Store::Root(aRoot);
+    Store::Root(new StoreController);
     SwapDirPointer aStore (new UFSSwapDir("ufs", "Blocking"));
     addSwapDir(aStore);
     commonInit();
@@ -249,8 +247,8 @@
     safe_free(config_line);
     CPPUNIT_ASSERT(aStore->IO->io != NULL);
 
-    free_cachedir(&Config.cacheSwap);
     Store::Root(NULL);
+    free_cachedir(&Config.cacheSwap);
     safe_free(Config.replPolicy->type);
     delete Config.replPolicy;
 
diff -u -r -N squid-3.2.0.12/src/tools.cc squid-3.2.0.13/src/tools.cc
--- squid-3.2.0.12/src/tools.cc	2011-09-16 23:37:30.000000000 +1200
+++ squid-3.2.0.13/src/tools.cc	2011-10-14 14:42:56.000000000 +1300
@@ -821,7 +821,13 @@
     if (opt_no_daemon || Config.workers == 0)
         return true;
 
-    return 0 < KidIdentifier && KidIdentifier <= Config.workers;
+    return TheProcessKind == pkWorker;
+}
+
+bool
+IamDiskProcess()
+{
+    return TheProcessKind == pkDisker;
 }
 
 bool
@@ -833,13 +839,13 @@
 bool
 UsingSmp()
 {
-    return !opt_no_daemon && Config.workers > 1;
+    return InDaemonMode() && NumberOfKids() > 1;
 }
 
 bool
 IamCoordinatorProcess()
 {
-    return UsingSmp() && KidIdentifier == Config.workers + 1;
+    return TheProcessKind == pkCoordinator;
 }
 
 bool
@@ -851,7 +857,7 @@
 
     // when there is a master and worker process, the master delegates
     // primary functions to its only kid
-    if (Config.workers == 1)
+    if (NumberOfKids() == 1)
         return IamWorkerProcess();
 
     // in SMP mode, multiple kids delegate primary functions to the coordinator
@@ -865,11 +871,27 @@
     if (!InDaemonMode())
         return 0;
 
-    // workers + the coordinator process
-    if (UsingSmp())
-        return Config.workers + 1;
+    // XXX: detect and abort when called before workers/cache_dirs are parsed
 
-    return Config.workers;
+    const int rockDirs = Config.cacheSwap.n_strands;
+
+    const bool needCoord = Config.workers > 1 || rockDirs > 0;
+    return (needCoord ? 1 : 0) + Config.workers + rockDirs;
+}
+
+String
+ProcessRoles()
+{
+    String roles = "";
+    if (IamMasterProcess())
+        roles.append(" master");
+    if (IamCoordinatorProcess())
+        roles.append(" coordinator");
+    if (IamWorkerProcess())
+        roles.append(" worker");
+    if (IamDiskProcess())
+        roles.append(" disker");
+    return roles;
 }
 
 void
diff -u -r -N squid-3.2.0.12/src/urn.cc squid-3.2.0.13/src/urn.cc
--- squid-3.2.0.12/src/urn.cc	2011-09-16 23:37:30.000000000 +1200
+++ squid-3.2.0.13/src/urn.cc	2011-10-14 14:42:56.000000000 +1300
@@ -505,6 +505,8 @@
 
         list[i].url = url;
         list[i].host = xstrdup(host);
+        // TODO: Use storeHas() or lock/unlock entry to avoid creating unlocked
+        // ones.
         list[i].flags.cached = storeGetPublic(url, m) ? 1 : 0;
         i++;
     }
diff -u -r -N squid-3.2.0.12/tools/squidclient.cc squid-3.2.0.13/tools/squidclient.cc
--- squid-3.2.0.12/tools/squidclient.cc	2011-09-16 23:37:30.000000000 +1200
+++ squid-3.2.0.13/tools/squidclient.cc	2011-10-14 14:42:56.000000000 +1300
@@ -211,7 +211,9 @@
     int keep_alive = 0;
     int opt_noaccept = 0;
     int opt_verbose = 0;
-    int www_neg, proxy_neg;
+#if HAVE_GSSAPI
+    int www_neg = 0, proxy_neg = 0;
+#endif
     const char *hostname, *localhost;
     Ip::Address iaddr;
     char url[BUFSIZ], msg[MESSAGELEN], buf[BUFSIZ];
@@ -243,8 +245,6 @@
     ping = 0;
     pcount = 0;
     ping_int = 1 * 1000;
-    www_neg = 0;
-    proxy_neg = 0;
 
     if (argc < 2) {
         usage(argv[0]);		/* need URL */
