Fri, 10 Oct 2008 11:16:23 -0700  Google Inc. <opensource@google.com>

  * Issue #15: open-vcdiff fails to compile on Fedora 9
    * Add header <string.h> to source files that use memcmp, memset, memcpy,
      and/or strlen.
    * Change C++-style includes like <cstdlib> to C-style includes like
      <stdlib.h> so that function names are guaranteed to be defined
      in the global namespace.
  * Issue #8: Decoder should not crash if it runs out of memory
    * Add a new interface that places a limit on the maximum bytes allowed in
      a single target window or a target file.
  * Issue #13: Add unit test for vcdiff command-line executable
    * Unit test vcdiff_test.sh added for Linux and Mac builds.
    * Still need to add a Windows version of this test.
diff --git a/ChangeLog b/ChangeLog
index 395532e..126ab30 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,18 @@
+Fri, 10 Oct 2008 11:16:23 -0700  Google Inc. <opensource@google.com>
+
+  * Issue #15: open-vcdiff fails to compile on Fedora 9
+    * Add header <string.h> to source files that use memcmp, memset, memcpy,
+      and/or strlen.
+    * Change C++-style includes like <cstdlib> to C-style includes like
+      <stdlib.h> so that function names are guaranteed to be defined
+      in the global namespace.
+  * Issue #8: Decoder should not crash if it runs out of memory
+    * Add a new interface that places a limit on the maximum bytes allowed in
+      a single target window or a target file.
+  * Issue #13: Add unit test for vcdiff command-line executable
+    * Unit test vcdiff_test.sh added for Linux and Mac builds.
+    * Still need to add a Windows version of this test.
+
 Tue, 02 Sep 2008 09:27:54 -0700  Google Inc. <opensource@google.com>
 
   * Fix problems found on OpenBSD platform.
diff --git a/Makefile.am b/Makefile.am
index 9a7d98e..dfa4d55 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -25,33 +25,28 @@
 			src/google/output_string.h
 
 docdir = $(prefix)/share/doc/$(PACKAGE)-$(VERSION)
-## This is for HTML and other documentation you want to install.
-## Add your documentation files (in doc/) in addition to these
-## top-level boilerplate files.  Also add a TODO file if you have one.
-dist_doc_DATA = AUTHORS COPYING ChangeLog INSTALL NEWS README THANKS
+dist_doc_DATA = AUTHORS COPYING ChangeLog INSTALL NEWS README THANKS \
+		src/gtest/README
 
 # The manual pages that should be installed
 dist_man1_MANS = man/vcdiff.1
 
-## The libraries (.so's) you want to install
+## The libraries (.so's) you want to build and install
 lib_LTLIBRARIES =
 
-## Internal libraries that will not be installed
-noinst_LTLIBRARIES =
-
-## Binaries to be built; these are added in the RULES section
+## Binaries to be built and installed; these are added in the RULES section
 bin_PROGRAMS =
 
-## unittests you want to run when people type 'make check'.
-## Individual tests are added to TESTS in the RULES section.
-## TESTS is for binary unittests, check_SCRIPTS for script-based unittests.
-## TESTS_ENVIRONMENT sets environment variables for when you run unittest,
-## but it only seems to take effect for *binary* unittests (argh!)
-TESTS =
-TESTS_ENVIRONMENT = SRCDIR="$(top_srcdir)"
+## Binary and script unit tests you want to run when people type 'make check'.
+## Tests are added one by one to these lists in the RULES sections.
+check_PROGRAMS =
 check_SCRIPTS =
-# Every time you add a unittest to check_SCRIPTS, add it here too
+
+## Other binaries, scripts, and libraries that are built but not automatically
+## installed.
+noinst_PROGRAMS =
 noinst_SCRIPTS =
+noinst_LTLIBRARIES =
 
 ## vvvv RULES TO MAKE THE LIBRARIES, BINARIES, AND UNITTESTS
 
@@ -134,65 +129,72 @@
 vcdiff_SOURCES = src/vcdiff_main.cc
 vcdiff_LDADD = libvcddec.la libvcdenc.la libgflags.la
 
-TESTS += addrcache_test
+check_PROGRAMS += addrcache_test
 addrcache_test_SOURCES = src/addrcache_test.cc
 addrcache_test_LDADD = libvcdcom.la libgtest_main.la
 
-TESTS += blockhash_test
+check_PROGRAMS += blockhash_test
 blockhash_test_SOURCES = src/blockhash_test.cc
 blockhash_test_LDADD = libvcdenc.la libgtest_main.la
 
-TESTS += codetable_test
+check_PROGRAMS += codetable_test
 codetable_test_SOURCES = src/codetable_test.cc
 codetable_test_LDADD = libvcdcom.la libgtest_main.la
 
-TESTS += decodetable_test
+check_PROGRAMS += decodetable_test
 decodetable_test_SOURCES = src/decodetable_test.cc
 decodetable_test_LDADD = libvcddec.la libgtest_main.la
 
-TESTS += encodetable_test
+check_PROGRAMS += encodetable_test
 encodetable_test_SOURCES = src/encodetable_test.cc
 encodetable_test_LDADD = libvcdenc.la libgtest_main.la
 
-TESTS += headerparser_test
+check_PROGRAMS += headerparser_test
 headerparser_test_SOURCES = src/headerparser_test.cc
 headerparser_test_LDADD = libvcddec.la libgtest_main.la
 
-TESTS += instruction_map_test
+check_PROGRAMS += instruction_map_test
 instruction_map_test_SOURCES = src/instruction_map_test.cc
 instruction_map_test_LDADD = libvcdenc.la libgtest_main.la
 
-TESTS += output_string_test
-output_string_test_SOURCES = src/output_string_test.cc
+check_PROGRAMS += output_string_test
+output_string_test_SOURCES = src/output_string_crope.h \
+			     src/output_string_test.cc
 output_string_test_LDADD = libgtest_main.la
 
-TESTS += rolling_hash_test
+check_PROGRAMS += rolling_hash_test
 rolling_hash_test_SOURCES = src/rolling_hash_test.cc
 rolling_hash_test_LDADD = libvcdcom.la libgtest_main.la
 
-TESTS += varint_bigendian_test
+check_PROGRAMS += varint_bigendian_test
 varint_bigendian_test_SOURCES = src/varint_bigendian_test.cc
 varint_bigendian_test_LDADD = libvcdcom.la libgtest_main.la
 
-TESTS += vcdecoder_test
+check_PROGRAMS += vcdecoder_test
 vcdecoder_test_SOURCES = src/vcdecoder_test.h src/vcdecoder_test.cc \
-			 src/vcdecoder_test1.cc src/vcdecoder_test2.cc \
-			 src/vcdecoder_test3.cc src/vcdecoder_test4.cc
+			 src/vcdecoder1_test.cc src/vcdecoder2_test.cc \
+			 src/vcdecoder3_test.cc src/vcdecoder4_test.cc
 vcdecoder_test_LDADD = libvcddec.la libgtest_main.la
 
-TESTS += vcdiffengine_test
+check_PROGRAMS += vcdiffengine_test
 vcdiffengine_test_SOURCES = src/vcdiffengine_test.cc
 vcdiffengine_test_LDADD = libvcdenc.la libgtest_main.la
 
-TESTS += vcencoder_test
+check_PROGRAMS += vcencoder_test
 vcencoder_test_SOURCES = src/vcencoder_test.cc
 vcencoder_test_LDADD = libvcddec.la libvcdenc.la libgtest_main.la
 
+check_SCRIPTS += src/vcdiff_test.sh
+dist_noinst_DATA = testdata/configure.ac.v0.1 \
+                   testdata/configure.ac.v0.2 \
+                   testdata/allocates_4gb.vcdiff
+
 ## ^^^^ END OF RULES TO MAKE THE LIBRARIES, BINARIES, AND UNITTESTS
 
-## This should always include $(TESTS), but may also include other
-## binaries that you compile but don't want automatically installed.
-noinst_PROGRAMS = $(TESTS)
+TESTS = $(check_PROGRAMS) $(check_SCRIPTS)
+## TESTS_ENVIRONMENT sets environment variables for when you run unit tests,
+## but it only seems to take effect for *binary* unit tests (argh!)
+TESTS_ENVIRONMENT = SRCDIR="$(top_srcdir)"
 
 rpm: dist-gzip packages/rpm.sh packages/rpm/rpm.spec
 	@cd packages && ./rpm.sh ${PACKAGE} ${VERSION}
@@ -203,5 +205,30 @@
 libtool: $(LIBTOOL_DEPS)
 	$(SHELL) ./config.status --recheck
 
-EXTRA_DIST = packages/rpm.sh packages/rpm/rpm.spec packages/deb.sh \
-  packages/deb autogen.sh $(SCRIPTS) libtool
+EXTRA_DIST = $(check_SCRIPTS) \
+	     autogen.sh \
+	     packages/rpm.sh \
+	     packages/rpm/rpm.spec \
+	     packages/deb.sh \
+	     packages/deb \
+	     vsprojects/config.h \
+	     vsprojects/stdint.h \
+	     vsprojects/open-vcdiff.sln \
+	     vsprojects/addrcache_test/addrcache_test.vcproj \
+	     vsprojects/blockhash_test/blockhash_test.vcproj \
+	     vsprojects/codetable_test/codetable_test.vcproj \
+	     vsprojects/decodetable_test/decodetable_test.vcproj \
+	     vsprojects/encodetable_test/encodetable_test.vcproj \
+	     vsprojects/gtest/gtest.vcproj \
+	     vsprojects/headerparser_test/headerparser_test.vcproj \
+	     vsprojects/instruction_map_test/instruction_map_test.vcproj \
+	     vsprojects/output_string_test/output_string_test.vcproj \
+	     vsprojects/rolling_hash_test/rolling_hash_test.vcproj \
+	     vsprojects/varint_bigendian_test/varint_bigendian_test.vcproj \
+	     vsprojects/vcdcom/vcdcom.vcproj \
+	     vsprojects/vcddec/vcddec.vcproj \
+	     vsprojects/vcdecoder_test/vcdecoder_test.vcproj \
+	     vsprojects/vcdenc/vcdenc.vcproj \
+	     vsprojects/vcdiff/vcdiff.vcproj \
+	     vsprojects/vcdiffengine_test/vcdiffengine_test.vcproj \
+	     vsprojects/vcencoder_test/vcencoder_test.vcproj
diff --git a/Makefile.in b/Makefile.in
index e50ce58..f3c1219 100644
--- a/Makefile.in
+++ b/Makefile.in
@@ -49,9 +49,16 @@
 # "-Wextra" when we can be sure that early gcc versions will not be used.
 @GCC_TRUE@am__append_1 = -Wall -Wwrite-strings -Woverloaded-virtual -W
 bin_PROGRAMS = vcdiff$(EXEEXT)
-noinst_PROGRAMS = $(am__EXEEXT_1)
+check_PROGRAMS = addrcache_test$(EXEEXT) blockhash_test$(EXEEXT) \
+	codetable_test$(EXEEXT) decodetable_test$(EXEEXT) \
+	encodetable_test$(EXEEXT) headerparser_test$(EXEEXT) \
+	instruction_map_test$(EXEEXT) output_string_test$(EXEEXT) \
+	rolling_hash_test$(EXEEXT) varint_bigendian_test$(EXEEXT) \
+	vcdecoder_test$(EXEEXT) vcdiffengine_test$(EXEEXT) \
+	vcencoder_test$(EXEEXT)
+noinst_PROGRAMS =
 DIST_COMMON = README $(am__configure_deps) $(dist_doc_DATA) \
-	$(dist_man1_MANS) $(googleinclude_HEADERS) \
+	$(dist_man1_MANS) $(dist_noinst_DATA) $(googleinclude_HEADERS) \
 	$(srcdir)/Makefile.am $(srcdir)/Makefile.in \
 	$(top_srcdir)/configure $(top_srcdir)/src/config.h.in AUTHORS \
 	COPYING ChangeLog INSTALL NEWS THANKS compile config.guess \
@@ -100,13 +107,6 @@
 	instruction_map.lo vcdiffengine.lo vcencoder.lo
 libvcdenc_la_OBJECTS = $(am_libvcdenc_la_OBJECTS)
 binPROGRAMS_INSTALL = $(INSTALL_PROGRAM)
-am__EXEEXT_1 = addrcache_test$(EXEEXT) blockhash_test$(EXEEXT) \
-	codetable_test$(EXEEXT) decodetable_test$(EXEEXT) \
-	encodetable_test$(EXEEXT) headerparser_test$(EXEEXT) \
-	instruction_map_test$(EXEEXT) output_string_test$(EXEEXT) \
-	rolling_hash_test$(EXEEXT) varint_bigendian_test$(EXEEXT) \
-	vcdecoder_test$(EXEEXT) vcdiffengine_test$(EXEEXT) \
-	vcencoder_test$(EXEEXT)
 PROGRAMS = $(bin_PROGRAMS) $(noinst_PROGRAMS)
 am_addrcache_test_OBJECTS = addrcache_test.$(OBJEXT)
 addrcache_test_OBJECTS = $(am_addrcache_test_OBJECTS)
@@ -139,8 +139,8 @@
 varint_bigendian_test_OBJECTS = $(am_varint_bigendian_test_OBJECTS)
 varint_bigendian_test_DEPENDENCIES = libvcdcom.la libgtest_main.la
 am_vcdecoder_test_OBJECTS = vcdecoder_test.$(OBJEXT) \
-	vcdecoder_test1.$(OBJEXT) vcdecoder_test2.$(OBJEXT) \
-	vcdecoder_test3.$(OBJEXT) vcdecoder_test4.$(OBJEXT)
+	vcdecoder1_test.$(OBJEXT) vcdecoder2_test.$(OBJEXT) \
+	vcdecoder3_test.$(OBJEXT) vcdecoder4_test.$(OBJEXT)
 vcdecoder_test_OBJECTS = $(am_vcdecoder_test_OBJECTS)
 vcdecoder_test_DEPENDENCIES = libvcddec.la libgtest_main.la
 am_vcdiff_OBJECTS = vcdiff_main.$(OBJEXT)
@@ -197,7 +197,7 @@
 NROFF = nroff
 MANS = $(dist_man1_MANS)
 dist_docDATA_INSTALL = $(INSTALL_DATA)
-DATA = $(dist_doc_DATA)
+DATA = $(dist_doc_DATA) $(dist_noinst_DATA)
 googleincludeHEADERS_INSTALL = $(INSTALL_HEADER)
 HEADERS = $(googleinclude_HEADERS)
 ETAGS = etags
@@ -324,7 +324,9 @@
 			src/google/output_string.h
 
 docdir = $(prefix)/share/doc/$(PACKAGE)-$(VERSION)
-dist_doc_DATA = AUTHORS COPYING ChangeLog INSTALL NEWS README THANKS
+dist_doc_DATA = AUTHORS COPYING ChangeLog INSTALL NEWS README THANKS \
+		src/gtest/README
+
 
 # The manual pages that should be installed
 dist_man1_MANS = man/vcdiff.1
@@ -335,6 +337,8 @@
 
 # libvcdenc: The open-vcdiff *encoder* library
 lib_LTLIBRARIES = libvcdcom.la libvcddec.la libvcdenc.la
+check_SCRIPTS = src/vcdiff_test.sh
+noinst_SCRIPTS = 
 
 # google-gflags: Used for command-line client
 #     Please refer to http://code.google.com/p/google-gflags/ for details
@@ -342,14 +346,6 @@
 # gtest (Google Test): Used for unit tests only
 #     Please refer to http://code.google.com/p/googletest/ for details
 noinst_LTLIBRARIES = libgflags.la libgtest.la libgtest_main.la
-TESTS = addrcache_test blockhash_test codetable_test decodetable_test \
-	encodetable_test headerparser_test instruction_map_test \
-	output_string_test rolling_hash_test varint_bigendian_test \
-	vcdecoder_test vcdiffengine_test vcencoder_test
-TESTS_ENVIRONMENT = SRCDIR="$(top_srcdir)"
-check_SCRIPTS = 
-# Every time you add a unittest to check_SCRIPTS, add it here too
-noinst_SCRIPTS = 
 libgflags_la_SOURCES = src/gflags/gflags.h \
 		       src/gflags.cc \
 		       src/gflags_reporting.cc
@@ -427,23 +423,56 @@
 headerparser_test_LDADD = libvcddec.la libgtest_main.la
 instruction_map_test_SOURCES = src/instruction_map_test.cc
 instruction_map_test_LDADD = libvcdenc.la libgtest_main.la
-output_string_test_SOURCES = src/output_string_test.cc
+output_string_test_SOURCES = src/output_string_crope.h \
+			     src/output_string_test.cc
+
 output_string_test_LDADD = libgtest_main.la
 rolling_hash_test_SOURCES = src/rolling_hash_test.cc
 rolling_hash_test_LDADD = libvcdcom.la libgtest_main.la
 varint_bigendian_test_SOURCES = src/varint_bigendian_test.cc
 varint_bigendian_test_LDADD = libvcdcom.la libgtest_main.la
 vcdecoder_test_SOURCES = src/vcdecoder_test.h src/vcdecoder_test.cc \
-			 src/vcdecoder_test1.cc src/vcdecoder_test2.cc \
-			 src/vcdecoder_test3.cc src/vcdecoder_test4.cc
+			 src/vcdecoder1_test.cc src/vcdecoder2_test.cc \
+			 src/vcdecoder3_test.cc src/vcdecoder4_test.cc
 
 vcdecoder_test_LDADD = libvcddec.la libgtest_main.la
 vcdiffengine_test_SOURCES = src/vcdiffengine_test.cc
 vcdiffengine_test_LDADD = libvcdenc.la libgtest_main.la
 vcencoder_test_SOURCES = src/vcencoder_test.cc
 vcencoder_test_LDADD = libvcddec.la libvcdenc.la libgtest_main.la
-EXTRA_DIST = packages/rpm.sh packages/rpm/rpm.spec packages/deb.sh \
-  packages/deb autogen.sh $(SCRIPTS) libtool
+dist_noinst_DATA = testdata/configure.ac.v0.1 \
+                   testdata/configure.ac.v0.2 \
+                   testdata/allocates_4gb.vcdiff
+
+TESTS = $(check_PROGRAMS) $(check_SCRIPTS)
+TESTS_ENVIRONMENT = SRCDIR="$(top_srcdir)"
+EXTRA_DIST = $(check_SCRIPTS) \
+	     autogen.sh \
+	     packages/rpm.sh \
+	     packages/rpm/rpm.spec \
+	     packages/deb.sh \
+	     packages/deb \
+	     vsprojects/config.h \
+	     vsprojects/stdint.h \
+	     vsprojects/open-vcdiff.sln \
+	     vsprojects/addrcache_test/addrcache_test.vcproj \
+	     vsprojects/blockhash_test/blockhash_test.vcproj \
+	     vsprojects/codetable_test/codetable_test.vcproj \
+	     vsprojects/decodetable_test/decodetable_test.vcproj \
+	     vsprojects/encodetable_test/encodetable_test.vcproj \
+	     vsprojects/gtest/gtest.vcproj \
+	     vsprojects/headerparser_test/headerparser_test.vcproj \
+	     vsprojects/instruction_map_test/instruction_map_test.vcproj \
+	     vsprojects/output_string_test/output_string_test.vcproj \
+	     vsprojects/rolling_hash_test/rolling_hash_test.vcproj \
+	     vsprojects/varint_bigendian_test/varint_bigendian_test.vcproj \
+	     vsprojects/vcdcom/vcdcom.vcproj \
+	     vsprojects/vcddec/vcddec.vcproj \
+	     vsprojects/vcdecoder_test/vcdecoder_test.vcproj \
+	     vsprojects/vcdenc/vcdenc.vcproj \
+	     vsprojects/vcdiff/vcdiff.vcproj \
+	     vsprojects/vcdiffengine_test/vcdiffengine_test.vcproj \
+	     vsprojects/vcencoder_test/vcencoder_test.vcproj
 
 all: all-am
 
@@ -576,6 +605,13 @@
 	  rm -f $$p $$f ; \
 	done
 
+clean-checkPROGRAMS:
+	@list='$(check_PROGRAMS)'; for p in $$list; do \
+	  f=`echo $$p|sed 's/$(EXEEXT)$$//'`; \
+	  echo " rm -f $$p $$f"; \
+	  rm -f $$p $$f ; \
+	done
+
 clean-noinstPROGRAMS:
 	@list='$(noinst_PROGRAMS)'; for p in $$list; do \
 	  f=`echo $$p|sed 's/$(EXEEXT)$$//'`; \
@@ -659,11 +695,11 @@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/varint_bigendian.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/varint_bigendian_test.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/vcdecoder.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/vcdecoder1_test.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/vcdecoder2_test.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/vcdecoder3_test.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/vcdecoder4_test.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/vcdecoder_test.Po@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/vcdecoder_test1.Po@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/vcdecoder_test2.Po@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/vcdecoder_test3.Po@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/vcdecoder_test4.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/vcdiff_main.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/vcdiffengine.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/vcdiffengine_test.Po@am__quote@
@@ -1006,61 +1042,61 @@
 @AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
 @am__fastdepCXX_FALSE@	$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o vcdecoder_test.obj `if test -f 'src/vcdecoder_test.cc'; then $(CYGPATH_W) 'src/vcdecoder_test.cc'; else $(CYGPATH_W) '$(srcdir)/src/vcdecoder_test.cc'; fi`
 
-vcdecoder_test1.o: src/vcdecoder_test1.cc
-@am__fastdepCXX_TRUE@	if $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT vcdecoder_test1.o -MD -MP -MF "$(DEPDIR)/vcdecoder_test1.Tpo" -c -o vcdecoder_test1.o `test -f 'src/vcdecoder_test1.cc' || echo '$(srcdir)/'`src/vcdecoder_test1.cc; \
-@am__fastdepCXX_TRUE@	then mv -f "$(DEPDIR)/vcdecoder_test1.Tpo" "$(DEPDIR)/vcdecoder_test1.Po"; else rm -f "$(DEPDIR)/vcdecoder_test1.Tpo"; exit 1; fi
-@AMDEP_TRUE@@am__fastdepCXX_FALSE@	source='src/vcdecoder_test1.cc' object='vcdecoder_test1.o' libtool=no @AMDEPBACKSLASH@
+vcdecoder1_test.o: src/vcdecoder1_test.cc
+@am__fastdepCXX_TRUE@	if $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT vcdecoder1_test.o -MD -MP -MF "$(DEPDIR)/vcdecoder1_test.Tpo" -c -o vcdecoder1_test.o `test -f 'src/vcdecoder1_test.cc' || echo '$(srcdir)/'`src/vcdecoder1_test.cc; \
+@am__fastdepCXX_TRUE@	then mv -f "$(DEPDIR)/vcdecoder1_test.Tpo" "$(DEPDIR)/vcdecoder1_test.Po"; else rm -f "$(DEPDIR)/vcdecoder1_test.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@	source='src/vcdecoder1_test.cc' object='vcdecoder1_test.o' libtool=no @AMDEPBACKSLASH@
 @AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCXX_FALSE@	$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o vcdecoder_test1.o `test -f 'src/vcdecoder_test1.cc' || echo '$(srcdir)/'`src/vcdecoder_test1.cc
+@am__fastdepCXX_FALSE@	$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o vcdecoder1_test.o `test -f 'src/vcdecoder1_test.cc' || echo '$(srcdir)/'`src/vcdecoder1_test.cc
 
-vcdecoder_test1.obj: src/vcdecoder_test1.cc
-@am__fastdepCXX_TRUE@	if $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT vcdecoder_test1.obj -MD -MP -MF "$(DEPDIR)/vcdecoder_test1.Tpo" -c -o vcdecoder_test1.obj `if test -f 'src/vcdecoder_test1.cc'; then $(CYGPATH_W) 'src/vcdecoder_test1.cc'; else $(CYGPATH_W) '$(srcdir)/src/vcdecoder_test1.cc'; fi`; \
-@am__fastdepCXX_TRUE@	then mv -f "$(DEPDIR)/vcdecoder_test1.Tpo" "$(DEPDIR)/vcdecoder_test1.Po"; else rm -f "$(DEPDIR)/vcdecoder_test1.Tpo"; exit 1; fi
-@AMDEP_TRUE@@am__fastdepCXX_FALSE@	source='src/vcdecoder_test1.cc' object='vcdecoder_test1.obj' libtool=no @AMDEPBACKSLASH@
+vcdecoder1_test.obj: src/vcdecoder1_test.cc
+@am__fastdepCXX_TRUE@	if $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT vcdecoder1_test.obj -MD -MP -MF "$(DEPDIR)/vcdecoder1_test.Tpo" -c -o vcdecoder1_test.obj `if test -f 'src/vcdecoder1_test.cc'; then $(CYGPATH_W) 'src/vcdecoder1_test.cc'; else $(CYGPATH_W) '$(srcdir)/src/vcdecoder1_test.cc'; fi`; \
+@am__fastdepCXX_TRUE@	then mv -f "$(DEPDIR)/vcdecoder1_test.Tpo" "$(DEPDIR)/vcdecoder1_test.Po"; else rm -f "$(DEPDIR)/vcdecoder1_test.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@	source='src/vcdecoder1_test.cc' object='vcdecoder1_test.obj' libtool=no @AMDEPBACKSLASH@
 @AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCXX_FALSE@	$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o vcdecoder_test1.obj `if test -f 'src/vcdecoder_test1.cc'; then $(CYGPATH_W) 'src/vcdecoder_test1.cc'; else $(CYGPATH_W) '$(srcdir)/src/vcdecoder_test1.cc'; fi`
+@am__fastdepCXX_FALSE@	$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o vcdecoder1_test.obj `if test -f 'src/vcdecoder1_test.cc'; then $(CYGPATH_W) 'src/vcdecoder1_test.cc'; else $(CYGPATH_W) '$(srcdir)/src/vcdecoder1_test.cc'; fi`
 
-vcdecoder_test2.o: src/vcdecoder_test2.cc
-@am__fastdepCXX_TRUE@	if $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT vcdecoder_test2.o -MD -MP -MF "$(DEPDIR)/vcdecoder_test2.Tpo" -c -o vcdecoder_test2.o `test -f 'src/vcdecoder_test2.cc' || echo '$(srcdir)/'`src/vcdecoder_test2.cc; \
-@am__fastdepCXX_TRUE@	then mv -f "$(DEPDIR)/vcdecoder_test2.Tpo" "$(DEPDIR)/vcdecoder_test2.Po"; else rm -f "$(DEPDIR)/vcdecoder_test2.Tpo"; exit 1; fi
-@AMDEP_TRUE@@am__fastdepCXX_FALSE@	source='src/vcdecoder_test2.cc' object='vcdecoder_test2.o' libtool=no @AMDEPBACKSLASH@
+vcdecoder2_test.o: src/vcdecoder2_test.cc
+@am__fastdepCXX_TRUE@	if $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT vcdecoder2_test.o -MD -MP -MF "$(DEPDIR)/vcdecoder2_test.Tpo" -c -o vcdecoder2_test.o `test -f 'src/vcdecoder2_test.cc' || echo '$(srcdir)/'`src/vcdecoder2_test.cc; \
+@am__fastdepCXX_TRUE@	then mv -f "$(DEPDIR)/vcdecoder2_test.Tpo" "$(DEPDIR)/vcdecoder2_test.Po"; else rm -f "$(DEPDIR)/vcdecoder2_test.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@	source='src/vcdecoder2_test.cc' object='vcdecoder2_test.o' libtool=no @AMDEPBACKSLASH@
 @AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCXX_FALSE@	$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o vcdecoder_test2.o `test -f 'src/vcdecoder_test2.cc' || echo '$(srcdir)/'`src/vcdecoder_test2.cc
+@am__fastdepCXX_FALSE@	$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o vcdecoder2_test.o `test -f 'src/vcdecoder2_test.cc' || echo '$(srcdir)/'`src/vcdecoder2_test.cc
 
-vcdecoder_test2.obj: src/vcdecoder_test2.cc
-@am__fastdepCXX_TRUE@	if $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT vcdecoder_test2.obj -MD -MP -MF "$(DEPDIR)/vcdecoder_test2.Tpo" -c -o vcdecoder_test2.obj `if test -f 'src/vcdecoder_test2.cc'; then $(CYGPATH_W) 'src/vcdecoder_test2.cc'; else $(CYGPATH_W) '$(srcdir)/src/vcdecoder_test2.cc'; fi`; \
-@am__fastdepCXX_TRUE@	then mv -f "$(DEPDIR)/vcdecoder_test2.Tpo" "$(DEPDIR)/vcdecoder_test2.Po"; else rm -f "$(DEPDIR)/vcdecoder_test2.Tpo"; exit 1; fi
-@AMDEP_TRUE@@am__fastdepCXX_FALSE@	source='src/vcdecoder_test2.cc' object='vcdecoder_test2.obj' libtool=no @AMDEPBACKSLASH@
+vcdecoder2_test.obj: src/vcdecoder2_test.cc
+@am__fastdepCXX_TRUE@	if $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT vcdecoder2_test.obj -MD -MP -MF "$(DEPDIR)/vcdecoder2_test.Tpo" -c -o vcdecoder2_test.obj `if test -f 'src/vcdecoder2_test.cc'; then $(CYGPATH_W) 'src/vcdecoder2_test.cc'; else $(CYGPATH_W) '$(srcdir)/src/vcdecoder2_test.cc'; fi`; \
+@am__fastdepCXX_TRUE@	then mv -f "$(DEPDIR)/vcdecoder2_test.Tpo" "$(DEPDIR)/vcdecoder2_test.Po"; else rm -f "$(DEPDIR)/vcdecoder2_test.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@	source='src/vcdecoder2_test.cc' object='vcdecoder2_test.obj' libtool=no @AMDEPBACKSLASH@
 @AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCXX_FALSE@	$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o vcdecoder_test2.obj `if test -f 'src/vcdecoder_test2.cc'; then $(CYGPATH_W) 'src/vcdecoder_test2.cc'; else $(CYGPATH_W) '$(srcdir)/src/vcdecoder_test2.cc'; fi`
+@am__fastdepCXX_FALSE@	$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o vcdecoder2_test.obj `if test -f 'src/vcdecoder2_test.cc'; then $(CYGPATH_W) 'src/vcdecoder2_test.cc'; else $(CYGPATH_W) '$(srcdir)/src/vcdecoder2_test.cc'; fi`
 
-vcdecoder_test3.o: src/vcdecoder_test3.cc
-@am__fastdepCXX_TRUE@	if $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT vcdecoder_test3.o -MD -MP -MF "$(DEPDIR)/vcdecoder_test3.Tpo" -c -o vcdecoder_test3.o `test -f 'src/vcdecoder_test3.cc' || echo '$(srcdir)/'`src/vcdecoder_test3.cc; \
-@am__fastdepCXX_TRUE@	then mv -f "$(DEPDIR)/vcdecoder_test3.Tpo" "$(DEPDIR)/vcdecoder_test3.Po"; else rm -f "$(DEPDIR)/vcdecoder_test3.Tpo"; exit 1; fi
-@AMDEP_TRUE@@am__fastdepCXX_FALSE@	source='src/vcdecoder_test3.cc' object='vcdecoder_test3.o' libtool=no @AMDEPBACKSLASH@
+vcdecoder3_test.o: src/vcdecoder3_test.cc
+@am__fastdepCXX_TRUE@	if $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT vcdecoder3_test.o -MD -MP -MF "$(DEPDIR)/vcdecoder3_test.Tpo" -c -o vcdecoder3_test.o `test -f 'src/vcdecoder3_test.cc' || echo '$(srcdir)/'`src/vcdecoder3_test.cc; \
+@am__fastdepCXX_TRUE@	then mv -f "$(DEPDIR)/vcdecoder3_test.Tpo" "$(DEPDIR)/vcdecoder3_test.Po"; else rm -f "$(DEPDIR)/vcdecoder3_test.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@	source='src/vcdecoder3_test.cc' object='vcdecoder3_test.o' libtool=no @AMDEPBACKSLASH@
 @AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCXX_FALSE@	$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o vcdecoder_test3.o `test -f 'src/vcdecoder_test3.cc' || echo '$(srcdir)/'`src/vcdecoder_test3.cc
+@am__fastdepCXX_FALSE@	$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o vcdecoder3_test.o `test -f 'src/vcdecoder3_test.cc' || echo '$(srcdir)/'`src/vcdecoder3_test.cc
 
-vcdecoder_test3.obj: src/vcdecoder_test3.cc
-@am__fastdepCXX_TRUE@	if $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT vcdecoder_test3.obj -MD -MP -MF "$(DEPDIR)/vcdecoder_test3.Tpo" -c -o vcdecoder_test3.obj `if test -f 'src/vcdecoder_test3.cc'; then $(CYGPATH_W) 'src/vcdecoder_test3.cc'; else $(CYGPATH_W) '$(srcdir)/src/vcdecoder_test3.cc'; fi`; \
-@am__fastdepCXX_TRUE@	then mv -f "$(DEPDIR)/vcdecoder_test3.Tpo" "$(DEPDIR)/vcdecoder_test3.Po"; else rm -f "$(DEPDIR)/vcdecoder_test3.Tpo"; exit 1; fi
-@AMDEP_TRUE@@am__fastdepCXX_FALSE@	source='src/vcdecoder_test3.cc' object='vcdecoder_test3.obj' libtool=no @AMDEPBACKSLASH@
+vcdecoder3_test.obj: src/vcdecoder3_test.cc
+@am__fastdepCXX_TRUE@	if $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT vcdecoder3_test.obj -MD -MP -MF "$(DEPDIR)/vcdecoder3_test.Tpo" -c -o vcdecoder3_test.obj `if test -f 'src/vcdecoder3_test.cc'; then $(CYGPATH_W) 'src/vcdecoder3_test.cc'; else $(CYGPATH_W) '$(srcdir)/src/vcdecoder3_test.cc'; fi`; \
+@am__fastdepCXX_TRUE@	then mv -f "$(DEPDIR)/vcdecoder3_test.Tpo" "$(DEPDIR)/vcdecoder3_test.Po"; else rm -f "$(DEPDIR)/vcdecoder3_test.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@	source='src/vcdecoder3_test.cc' object='vcdecoder3_test.obj' libtool=no @AMDEPBACKSLASH@
 @AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCXX_FALSE@	$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o vcdecoder_test3.obj `if test -f 'src/vcdecoder_test3.cc'; then $(CYGPATH_W) 'src/vcdecoder_test3.cc'; else $(CYGPATH_W) '$(srcdir)/src/vcdecoder_test3.cc'; fi`
+@am__fastdepCXX_FALSE@	$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o vcdecoder3_test.obj `if test -f 'src/vcdecoder3_test.cc'; then $(CYGPATH_W) 'src/vcdecoder3_test.cc'; else $(CYGPATH_W) '$(srcdir)/src/vcdecoder3_test.cc'; fi`
 
-vcdecoder_test4.o: src/vcdecoder_test4.cc
-@am__fastdepCXX_TRUE@	if $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT vcdecoder_test4.o -MD -MP -MF "$(DEPDIR)/vcdecoder_test4.Tpo" -c -o vcdecoder_test4.o `test -f 'src/vcdecoder_test4.cc' || echo '$(srcdir)/'`src/vcdecoder_test4.cc; \
-@am__fastdepCXX_TRUE@	then mv -f "$(DEPDIR)/vcdecoder_test4.Tpo" "$(DEPDIR)/vcdecoder_test4.Po"; else rm -f "$(DEPDIR)/vcdecoder_test4.Tpo"; exit 1; fi
-@AMDEP_TRUE@@am__fastdepCXX_FALSE@	source='src/vcdecoder_test4.cc' object='vcdecoder_test4.o' libtool=no @AMDEPBACKSLASH@
+vcdecoder4_test.o: src/vcdecoder4_test.cc
+@am__fastdepCXX_TRUE@	if $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT vcdecoder4_test.o -MD -MP -MF "$(DEPDIR)/vcdecoder4_test.Tpo" -c -o vcdecoder4_test.o `test -f 'src/vcdecoder4_test.cc' || echo '$(srcdir)/'`src/vcdecoder4_test.cc; \
+@am__fastdepCXX_TRUE@	then mv -f "$(DEPDIR)/vcdecoder4_test.Tpo" "$(DEPDIR)/vcdecoder4_test.Po"; else rm -f "$(DEPDIR)/vcdecoder4_test.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@	source='src/vcdecoder4_test.cc' object='vcdecoder4_test.o' libtool=no @AMDEPBACKSLASH@
 @AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCXX_FALSE@	$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o vcdecoder_test4.o `test -f 'src/vcdecoder_test4.cc' || echo '$(srcdir)/'`src/vcdecoder_test4.cc
+@am__fastdepCXX_FALSE@	$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o vcdecoder4_test.o `test -f 'src/vcdecoder4_test.cc' || echo '$(srcdir)/'`src/vcdecoder4_test.cc
 
-vcdecoder_test4.obj: src/vcdecoder_test4.cc
-@am__fastdepCXX_TRUE@	if $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT vcdecoder_test4.obj -MD -MP -MF "$(DEPDIR)/vcdecoder_test4.Tpo" -c -o vcdecoder_test4.obj `if test -f 'src/vcdecoder_test4.cc'; then $(CYGPATH_W) 'src/vcdecoder_test4.cc'; else $(CYGPATH_W) '$(srcdir)/src/vcdecoder_test4.cc'; fi`; \
-@am__fastdepCXX_TRUE@	then mv -f "$(DEPDIR)/vcdecoder_test4.Tpo" "$(DEPDIR)/vcdecoder_test4.Po"; else rm -f "$(DEPDIR)/vcdecoder_test4.Tpo"; exit 1; fi
-@AMDEP_TRUE@@am__fastdepCXX_FALSE@	source='src/vcdecoder_test4.cc' object='vcdecoder_test4.obj' libtool=no @AMDEPBACKSLASH@
+vcdecoder4_test.obj: src/vcdecoder4_test.cc
+@am__fastdepCXX_TRUE@	if $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT vcdecoder4_test.obj -MD -MP -MF "$(DEPDIR)/vcdecoder4_test.Tpo" -c -o vcdecoder4_test.obj `if test -f 'src/vcdecoder4_test.cc'; then $(CYGPATH_W) 'src/vcdecoder4_test.cc'; else $(CYGPATH_W) '$(srcdir)/src/vcdecoder4_test.cc'; fi`; \
+@am__fastdepCXX_TRUE@	then mv -f "$(DEPDIR)/vcdecoder4_test.Tpo" "$(DEPDIR)/vcdecoder4_test.Po"; else rm -f "$(DEPDIR)/vcdecoder4_test.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@	source='src/vcdecoder4_test.cc' object='vcdecoder4_test.obj' libtool=no @AMDEPBACKSLASH@
 @AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCXX_FALSE@	$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o vcdecoder_test4.obj `if test -f 'src/vcdecoder_test4.cc'; then $(CYGPATH_W) 'src/vcdecoder_test4.cc'; else $(CYGPATH_W) '$(srcdir)/src/vcdecoder_test4.cc'; fi`
+@am__fastdepCXX_FALSE@	$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o vcdecoder4_test.obj `if test -f 'src/vcdecoder4_test.cc'; then $(CYGPATH_W) 'src/vcdecoder4_test.cc'; else $(CYGPATH_W) '$(srcdir)/src/vcdecoder4_test.cc'; fi`
 
 vcdiff_main.o: src/vcdiff_main.cc
 @am__fastdepCXX_TRUE@	if $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT vcdiff_main.o -MD -MP -MF "$(DEPDIR)/vcdiff_main.Tpo" -c -o vcdiff_main.o `test -f 'src/vcdiff_main.cc' || echo '$(srcdir)/'`src/vcdiff_main.cc; \
@@ -1317,7 +1353,7 @@
 distdir: $(DISTFILES)
 	$(am__remove_distdir)
 	mkdir $(distdir)
-	$(mkdir_p) $(distdir)/m4 $(distdir)/man $(distdir)/packages $(distdir)/packages/rpm $(distdir)/src $(distdir)/src/google
+	$(mkdir_p) $(distdir)/m4 $(distdir)/man $(distdir)/packages $(distdir)/packages/rpm $(distdir)/src $(distdir)/src/google $(distdir)/src/gtest $(distdir)/testdata $(distdir)/vsprojects $(distdir)/vsprojects/addrcache_test $(distdir)/vsprojects/blockhash_test $(distdir)/vsprojects/codetable_test $(distdir)/vsprojects/decodetable_test $(distdir)/vsprojects/encodetable_test $(distdir)/vsprojects/gtest $(distdir)/vsprojects/headerparser_test $(distdir)/vsprojects/instruction_map_test $(distdir)/vsprojects/output_string_test $(distdir)/vsprojects/rolling_hash_test $(distdir)/vsprojects/varint_bigendian_test $(distdir)/vsprojects/vcdcom $(distdir)/vsprojects/vcddec $(distdir)/vsprojects/vcdecoder_test $(distdir)/vsprojects/vcdenc $(distdir)/vsprojects/vcdiff $(distdir)/vsprojects/vcdiffengine_test $(distdir)/vsprojects/vcencoder_test
 	@srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; \
 	topsrcdirstrip=`echo "$(top_srcdir)" | sed 's|.|.|g'`; \
 	list='$(DISTFILES)'; for file in $$list; do \
@@ -1442,7 +1478,7 @@
 	       $(distcleancheck_listfiles) ; \
 	       exit 1; } >&2
 check-am: all-am
-	$(MAKE) $(AM_MAKEFLAGS) $(check_SCRIPTS)
+	$(MAKE) $(AM_MAKEFLAGS) $(check_PROGRAMS) $(check_SCRIPTS)
 	$(MAKE) $(AM_MAKEFLAGS) check-TESTS
 check: check-am
 all-am: Makefile $(LTLIBRARIES) $(PROGRAMS) $(SCRIPTS) $(MANS) $(DATA) \
@@ -1479,9 +1515,9 @@
 	@echo "it deletes files that may require special tools to rebuild."
 clean: clean-am
 
-clean-am: clean-binPROGRAMS clean-generic clean-libLTLIBRARIES \
-	clean-libtool clean-noinstLTLIBRARIES clean-noinstPROGRAMS \
-	mostlyclean-am
+clean-am: clean-binPROGRAMS clean-checkPROGRAMS clean-generic \
+	clean-libLTLIBRARIES clean-libtool clean-noinstLTLIBRARIES \
+	clean-noinstPROGRAMS mostlyclean-am
 
 distclean: distclean-am
 	-rm -f $(am__CONFIG_DISTCLEAN_FILES)
@@ -1538,24 +1574,24 @@
 uninstall-man: uninstall-man1
 
 .PHONY: CTAGS GTAGS all all-am am--refresh check check-TESTS check-am \
-	clean clean-binPROGRAMS clean-generic clean-libLTLIBRARIES \
-	clean-libtool clean-noinstLTLIBRARIES clean-noinstPROGRAMS \
-	ctags dist dist-all dist-bzip2 dist-gzip dist-shar dist-tarZ \
-	dist-zip distcheck distclean distclean-compile \
-	distclean-generic distclean-hdr distclean-libtool \
-	distclean-tags distcleancheck distdir distuninstallcheck dvi \
-	dvi-am html html-am info info-am install install-am \
-	install-binPROGRAMS install-data install-data-am \
-	install-dist_docDATA install-exec install-exec-am \
-	install-googleincludeHEADERS install-info install-info-am \
-	install-libLTLIBRARIES install-man install-man1 install-strip \
-	installcheck installcheck-am installdirs maintainer-clean \
-	maintainer-clean-generic mostlyclean mostlyclean-compile \
-	mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \
-	tags uninstall uninstall-am uninstall-binPROGRAMS \
-	uninstall-dist_docDATA uninstall-googleincludeHEADERS \
-	uninstall-info-am uninstall-libLTLIBRARIES uninstall-man \
-	uninstall-man1
+	clean clean-binPROGRAMS clean-checkPROGRAMS clean-generic \
+	clean-libLTLIBRARIES clean-libtool clean-noinstLTLIBRARIES \
+	clean-noinstPROGRAMS ctags dist dist-all dist-bzip2 dist-gzip \
+	dist-shar dist-tarZ dist-zip distcheck distclean \
+	distclean-compile distclean-generic distclean-hdr \
+	distclean-libtool distclean-tags distcleancheck distdir \
+	distuninstallcheck dvi dvi-am html html-am info info-am \
+	install install-am install-binPROGRAMS install-data \
+	install-data-am install-dist_docDATA install-exec \
+	install-exec-am install-googleincludeHEADERS install-info \
+	install-info-am install-libLTLIBRARIES install-man \
+	install-man1 install-strip installcheck installcheck-am \
+	installdirs maintainer-clean maintainer-clean-generic \
+	mostlyclean mostlyclean-compile mostlyclean-generic \
+	mostlyclean-libtool pdf pdf-am ps ps-am tags uninstall \
+	uninstall-am uninstall-binPROGRAMS uninstall-dist_docDATA \
+	uninstall-googleincludeHEADERS uninstall-info-am \
+	uninstall-libLTLIBRARIES uninstall-man uninstall-man1
 
 
 rpm: dist-gzip packages/rpm.sh packages/rpm/rpm.spec
diff --git a/configure b/configure
index 01797f8..f817e0c 100755
--- a/configure
+++ b/configure
@@ -1,6 +1,6 @@
 #! /bin/sh
 # Guess values for system-dependent variables and create Makefiles.
-# Generated by GNU Autoconf 2.59 for open-vcdiff 0.2.
+# Generated by GNU Autoconf 2.59 for open-vcdiff 0.3.
 #
 # Report bugs to <opensource@google.com>.
 #
@@ -423,8 +423,8 @@
 # Identity of this package.
 PACKAGE_NAME='open-vcdiff'
 PACKAGE_TARNAME='open-vcdiff'
-PACKAGE_VERSION='0.2'
-PACKAGE_STRING='open-vcdiff 0.2'
+PACKAGE_VERSION='0.3'
+PACKAGE_STRING='open-vcdiff 0.3'
 PACKAGE_BUGREPORT='opensource@google.com'
 
 ac_unique_file="README"
@@ -954,7 +954,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 open-vcdiff 0.2 to adapt to many kinds of systems.
+\`configure' configures open-vcdiff 0.3 to adapt to many kinds of systems.
 
 Usage: $0 [OPTION]... [VAR=VALUE]...
 
@@ -1020,7 +1020,7 @@
 
 if test -n "$ac_init_help"; then
   case $ac_init_help in
-     short | recursive ) echo "Configuration of open-vcdiff 0.2:";;
+     short | recursive ) echo "Configuration of open-vcdiff 0.3:";;
    esac
   cat <<\_ACEOF
 
@@ -1159,7 +1159,7 @@
 test -n "$ac_init_help" && exit 0
 if $ac_init_version; then
   cat <<\_ACEOF
-open-vcdiff configure 0.2
+open-vcdiff configure 0.3
 generated by GNU Autoconf 2.59
 
 Copyright (C) 2003 Free Software Foundation, Inc.
@@ -1173,7 +1173,7 @@
 This file contains any messages produced by compilers while
 running configure, to aid debugging if configure makes a mistake.
 
-It was created by open-vcdiff $as_me 0.2, which was
+It was created by open-vcdiff $as_me 0.3, which was
 generated by GNU Autoconf 2.59.  Invocation command line was
 
   $ $0 $@
@@ -1817,7 +1817,7 @@
 
 # Define the identity of the package.
  PACKAGE='open-vcdiff'
- VERSION='0.2'
+ VERSION='0.3'
 
 
 cat >>confdefs.h <<_ACEOF
@@ -18747,13 +18747,17 @@
 fi
 
 
-case $host in
-  *86*-*-*bsd* | *86*-*-gnu*)
+# Built-in memcmp can be inefficient when gcc compiles for x86 processors.
+# In those cases, use an alternative function instead of memcmp.
+case $host_cpu in
+  *86*)
+    if test "$GCC" = "yes"; then
 
 cat >>confdefs.h <<\_ACEOF
 #define VCDIFF_USE_BLOCK_COMPARE_WORDS 1
 _ACEOF
 
+    fi
     ;;
 esac
 
@@ -21162,7 +21166,7 @@
 } >&5
 cat >&5 <<_CSEOF
 
-This file was extended by open-vcdiff $as_me 0.2, which was
+This file was extended by open-vcdiff $as_me 0.3, which was
 generated by GNU Autoconf 2.59.  Invocation command line was
 
   CONFIG_FILES    = $CONFIG_FILES
@@ -21225,7 +21229,7 @@
 
 cat >>$CONFIG_STATUS <<_ACEOF
 ac_cs_version="\\
-open-vcdiff config.status 0.2
+open-vcdiff config.status 0.3
 configured by $0, generated by GNU Autoconf 2.59,
   with options \\"`echo "$ac_configure_args" | sed 's/[\\""\`\$]/\\\\&/g'`\\"
 
diff --git a/configure.ac b/configure.ac
index 8872538..e1d9234 100644
--- a/configure.ac
+++ b/configure.ac
@@ -4,7 +4,7 @@
 # make sure we're interpreted by some minimal autoconf
 AC_PREREQ(2.57)
 
-AC_INIT(open-vcdiff, 0.2, opensource@google.com)
+AC_INIT(open-vcdiff, 0.3, opensource@google.com)
 AC_CONFIG_SRCDIR(README)
 AM_INIT_AUTOMAKE
 AM_CONFIG_HEADER(src/config.h)
@@ -22,10 +22,14 @@
 # Check whether some low-level functions/files are available
 AC_HEADER_STDC
 
-case $host in
-  *86*-*-*bsd* | *86*-*-gnu*)
-    AC_DEFINE(VCDIFF_USE_BLOCK_COMPARE_WORDS, 1,
-              Use custom compare function instead of memcmp)
+# Built-in memcmp can be inefficient when gcc compiles for x86 processors.
+# In those cases, use an alternative function instead of memcmp.
+case $host_cpu in
+  *86*)
+    if test "$GCC" = "yes"; then
+      AC_DEFINE(VCDIFF_USE_BLOCK_COMPARE_WORDS, 1,
+                Use custom compare function instead of memcmp)
+    fi
     ;;
 esac
 
diff --git a/packages/deb/changelog b/packages/deb/changelog
index 733358c..6cfb830 100644
--- a/packages/deb/changelog
+++ b/packages/deb/changelog
@@ -1,3 +1,20 @@
+open-vcdiff (0.3-1) unstable; urgency=low
+
+  * Issue #15: open-vcdiff fails to compile on Fedora 9
+    * Add header <string.h> to source files that use memcmp, memset, memcpy,
+      and/or strlen.
+    * Change C++-style includes like <cstdlib> to C-style includes like
+      <stdlib.h> so that function names are guaranteed to be defined in the
+      global namespace.
+  * Issue #8: Decoder should not crash if it runs out of memory
+    * Add a new interface that places a limit on the maximum bytes allowed in
+      a single target window or a target file.
+  * Issue #13: Add unit test for vcdiff command-line executable
+    * Unit test vcdiff_test.sh added for Linux and Mac builds.
+    * Still need to add a Windows version of this test.
+
+ -- Google Inc. <opensource@google.com>  Fri, 10 Oct 2008 11:16:23 -0700
+
 open-vcdiff (0.2-1) unstable; urgency=low
 
   * Fix problems found on OpenBSD platform.
diff --git a/src/addrcache.h b/src/addrcache.h
index f2862e8..2974809 100644
--- a/src/addrcache.h
+++ b/src/addrcache.h
@@ -22,7 +22,6 @@
 #define OPEN_VCDIFF_ADDRCACHE_H_
 
 #include <config.h>
-#include <cstring>             // memset
 #include <vector>
 #include "vcdiff_defs.h"  // VCDAddress
 
diff --git a/src/addrcache_test.cc b/src/addrcache_test.cc
index 2e7632d..e313d3e 100644
--- a/src/addrcache_test.cc
+++ b/src/addrcache_test.cc
@@ -15,9 +15,9 @@
 
 #include <config.h>
 #include "addrcache.h"
+#include <limits.h>  // INT_MAX, INT_MIN
 #include <stdint.h>  // uint32_t
-#include <climits>  // INT_MAX, INT_MIN
-#include <cstdlib>  // rand, srand
+#include <stdlib.h>  // rand, srand
 #include <string>
 #include <vector>
 #include "logging.h"
@@ -26,9 +26,6 @@
 #include "vcdiff_defs.h"  // RESULT_ERROR
 
 namespace open_vcdiff {
-
-using std::string;
-
 namespace {
 
 // Provides an address_stream_ buffer and functions to manually encode
@@ -37,6 +34,10 @@
 //
 class VCDiffAddressCacheTest : public testing::Test {
  public:
+#ifndef VCDIFF_HAS_GLOBAL_STRING
+  typedef std::string string;
+#endif  // !VCDIFF_HAS_GLOBAL_STRING
+
   VCDiffAddressCacheTest() : decode_position_(NULL),
                              decode_position_end_(NULL),
                              verify_encode_position_(NULL),
diff --git a/src/blockhash.cc b/src/blockhash.cc
index 7dbec8d..d568d52 100644
--- a/src/blockhash.cc
+++ b/src/blockhash.cc
@@ -17,6 +17,7 @@
 #include "blockhash.h"
 #include "compile_assert.h"
 #include <stdint.h>  // uint32_t
+#include <string.h>  // memcpy, memcmp
 #include "logging.h"
 #include "rolling_hash.h"
 
diff --git a/src/blockhash.h b/src/blockhash.h
index 6b3b02e..8b7f948 100644
--- a/src/blockhash.h
+++ b/src/blockhash.h
@@ -21,8 +21,8 @@
 #define OPEN_VCDIFF_BLOCKHASH_H_
 
 #include <config.h>
+#include <stddef.h>  // size_t
 #include <stdint.h>  // uint32_t
-#include <cstddef>  // size_t
 #include <vector>
 
 namespace open_vcdiff {
diff --git a/src/blockhash_test.cc b/src/blockhash_test.cc
index a0ddecb..bc3d975 100644
--- a/src/blockhash_test.cc
+++ b/src/blockhash_test.cc
@@ -15,7 +15,8 @@
 
 #include <config.h>
 #include "blockhash.h"
-#include <climits>  // INT_MIN
+#include <limits.h>  // INT_MIN
+#include <string.h>  // memcpy, memcmp, strlen
 #include <memory>  // auto_ptr
 #include "encodetable.h"
 #include "logging.h"
@@ -379,12 +380,12 @@
                 << " FASTER than BlockCompareWords" << LOG_ENDL;
     }
   }
-#ifdef NDEBUG
+#if defined(NDEBUG) && !defined(VCDIFF_USE_BLOCK_COMPARE_WORDS)
   // Only check timings for optimized build.  There's plenty of margin: this
   // check will fail only if BlockContentsMatch is at least twice as slow as
   // BlockCompareWords.
   EXPECT_GT(time_for_block_compare_words * 2.0, time_for_block_contents_match);
-#endif  // NDEBUG
+#endif  // NDEBUG && !VCDIFF_USE_BLOCK_COMPARE_WORDS
 }
 
 // The two strings passed to BlockHash::MatchingBytesToLeft do have matching
diff --git a/src/decodetable.h b/src/decodetable.h
index 3ba997a..9d9c8a6 100644
--- a/src/decodetable.h
+++ b/src/decodetable.h
@@ -17,8 +17,8 @@
 #define OPEN_VCDIFF_DECODETABLE_H_
 
 #include <config.h>
+#include <stddef.h>     // NULL
 #include <stdint.h>     // int32_t
-#include <cstddef>      // NULL
 #include <memory>       // auto_ptr
 #include "codetable.h"  // VCDiffInstructi...
 #include "logging.h"
diff --git a/src/encodetable.h b/src/encodetable.h
index b14c795..2bb0c72 100644
--- a/src/encodetable.h
+++ b/src/encodetable.h
@@ -17,8 +17,8 @@
 #define OPEN_VCDIFF_ENCODETABLE_H_
 
 #include <config.h>
-#include <stdint.h>             // int32_t
-#include <cstddef>              // size_t
+#include <stddef.h>  // size_t
+#include <stdint.h>  // int32_t
 #include <string>
 #include <vector>
 #include "addrcache.h"
@@ -27,8 +27,6 @@
 
 namespace open_vcdiff {
 
-using std::string;
-
 class OutputStringInterface;
 class VCDiffInstructionMap;
 
@@ -115,6 +113,10 @@
   const std::vector<int>& match_counts() const { return match_counts_; }
 
  private:
+#ifndef VCDIFF_HAS_GLOBAL_STRING
+  typedef std::string string;
+#endif  // !VCDIFF_HAS_GLOBAL_STRING
+
   // This is an estimate of the longest match size the encoder expects to find.
   // It is used to determine the initial size of the vector match_counts_.
   // If it is too large, then some space will be wasted on vector elements
diff --git a/src/encodetable_test.cc b/src/encodetable_test.cc
index 50a74ca..e8e7dd7 100644
--- a/src/encodetable_test.cc
+++ b/src/encodetable_test.cc
@@ -17,8 +17,8 @@
 
 #include <config.h>
 #include "encodetable.h"
+#include <string.h>  // strlen
 #include <algorithm>
-#include <cstring>  // strlen
 #include <string>
 #include <vector>
 #include "addrcache.h"  // VCDiffAddressCache::kDefaultNearCacheSize
@@ -31,12 +31,11 @@
 namespace open_vcdiff {
 namespace {
 
-using std::string;
-
 class CodeTableWriterTest : public testing::Test {
  protected:
-  // Remove all of the functions below that are not useful for this
-  // test fixture.
+#ifndef VCDIFF_HAS_GLOBAL_STRING
+  typedef std::string string;
+#endif  // !VCDIFF_HAS_GLOBAL_STRING
 
   CodeTableWriterTest()
       : standard_writer(false),
diff --git a/src/google/output_string.h b/src/google/output_string.h
index 8554e5e..e3f5c2e 100644
--- a/src/google/output_string.h
+++ b/src/google/output_string.h
@@ -16,7 +16,7 @@
 #ifndef OPEN_VCDIFF_OUTPUT_STRING_H_
 #define OPEN_VCDIFF_OUTPUT_STRING_H_
 
-#include <cstddef>  // size_t
+#include <stddef.h>  // size_t
 
 namespace open_vcdiff {
 
diff --git a/src/google/vcdecoder.h b/src/google/vcdecoder.h
index d5aa741..72c2ed7 100644
--- a/src/google/vcdecoder.h
+++ b/src/google/vcdecoder.h
@@ -16,14 +16,12 @@
 #ifndef OPEN_VCDIFF_VCDECODER_H_
 #define OPEN_VCDIFF_VCDECODER_H_
 
-#include <cstddef>  // size_t
+#include <stddef.h>  // size_t
 #include <string>
 #include "google/output_string.h"
 
 namespace open_vcdiff {
 
-using std::string;
-
 class VCDiffStreamingDecoderImpl;
 
 // A streaming decoder class.  Takes a dictionary (source) file and a delta
@@ -96,6 +94,32 @@
   //
   bool FinishDecoding();
 
+  // *** Adjustable parameters ***
+
+  // Specifies the maximum allowable target file size.  If the decoder
+  // encounters a delta file that would cause it to create a target file larger
+  // than this limit, it will log an error and stop decoding.  If the decoder is
+  // applied to delta files whose sizes vary greatly and whose contents can be
+  // trusted, then a value larger than the the default value (64 MB) can be
+  // specified to allow for maximum flexibility.  On the other hand, if the
+  // input data is known never to exceed a particular size, and/or the input
+  // data may be maliciously constructed, a lower value can be supplied in order
+  // to guard against running out of memory or swapping to disk while decoding
+  // an extremely large target file.  The argument must be between 0 and
+  // INT32_MAX (2G); if it is within these bounds, the function will set the
+  // limit and return true.  Otherwise, the function will return false and will
+  // not change the limit.  Setting the limit to 0 will cause all decode
+  // operations of non-empty target files to fail.
+  bool SetMaximumTargetFileSize(size_t new_maximum_target_file_size);
+
+  // Specifies the maximum allowable target *window* size.  (A target file is
+  // composed of zero or more target windows.)  If the decoder encounters a
+  // delta window that would cause it to create a target window larger
+  // than this limit, it will log an error and stop decoding.
+  bool SetMaximumTargetWindowSize(size_t new_maximum_target_window_size);
+
+  // *** Diagnostic interfaces ***
+
   // The decoder can create a version of the output target string with XML tags
   // added to indicate where each section of the decoded text came from.  This
   // can assist in debugging the decoder and/or determining the effectiveness of
@@ -147,6 +171,10 @@
 //
 class VCDiffDecoder {
  public:
+#ifndef VCDIFF_HAS_GLOBAL_STRING
+  typedef std::string string;
+#endif  // !VCDIFF_HAS_GLOBAL_STRING
+
   VCDiffDecoder() { }
   ~VCDiffDecoder() { }
 
diff --git a/src/google/vcencoder.h b/src/google/vcencoder.h
index 6faff76..8dc2212 100644
--- a/src/google/vcencoder.h
+++ b/src/google/vcencoder.h
@@ -16,7 +16,7 @@
 #ifndef OPEN_VCDIFF_VCENCODER_H_
 #define OPEN_VCDIFF_VCENCODER_H_
 
-#include <cstddef>  // size_t
+#include <stddef.h>  // size_t
 #include <vector>
 #include "google/output_string.h"
 
diff --git a/src/headerparser.cc b/src/headerparser.cc
index f9b14db..ead4f44 100644
--- a/src/headerparser.cc
+++ b/src/headerparser.cc
@@ -250,13 +250,6 @@
   if (!ParseSize("size of the target window", target_window_length)) {
     return false;
   }
-  if (*target_window_length > kMaxTargetWindowSize) {
-    LOG(ERROR) << "Length of target window (" << (*target_window_length)
-               << ") exceeds limit of " << kMaxTargetWindowSize << " bytes"
-               << LOG_ENDL;
-    return_code_ = RESULT_ERROR;
-    return false;
-  }
   return true;
 }
 
diff --git a/src/headerparser.h b/src/headerparser.h
index 6271f0a..c74fa25 100644
--- a/src/headerparser.h
+++ b/src/headerparser.h
@@ -17,8 +17,8 @@
 #define OPEN_VCDIFF_HEADERPARSER_H_
 
 #include <config.h>
+#include <stddef.h>  // NULL
 #include <stdint.h>  // int32_t, uint32_t
-#include <cstddef>  // NULL
 #include "checksum.h"  // VCDChecksum
 #include "vcdiff_defs.h"  // VCDiffResult
 
@@ -191,14 +191,6 @@
 // or delta window header.
 class VCDiffHeaderParser {
  public:
-  // The maximum allowable size of a target window.  This restricts the amount
-  // of memory that can be allocated by the decoder.  A maliciously formulated
-  // delta file can create a target window of any arbitrary size, so the
-  // decoder needs to be sure that it can allocate this much memory using
-  // std::string::reserve().
-  //
-  static const size_t kMaxTargetWindowSize = 1 << 26;  // 64 MB
-
   // header_start should be the start of the header to be parsed;
   // data_end is the position just after the last byte of available data
   // (which may extend far past the end of the header.)
diff --git a/src/headerparser_test.cc b/src/headerparser_test.cc
index 30a7519..3a7cfa4 100644
--- a/src/headerparser_test.cc
+++ b/src/headerparser_test.cc
@@ -15,7 +15,7 @@
 
 #include <config.h>
 #include "headerparser.h"
-#include <cstdlib>  // rand, srand
+#include <stdlib.h>  // rand, srand
 #include <string>
 #include <vector>
 #include "testing.h"
@@ -24,11 +24,14 @@
 namespace open_vcdiff {
 namespace {  // anonymous
 
-using std::string;
 using std::vector;
 
 class VCDiffHeaderParserTest : public testing::Test {
  protected:
+#ifndef VCDIFF_HAS_GLOBAL_STRING
+  typedef std::string string;
+#endif  // !VCDIFF_HAS_GLOBAL_STRING
+
   static const int kTestSize = 1024;
 
   VCDiffHeaderParserTest() : parser(NULL) { }
diff --git a/src/instruction_map.cc b/src/instruction_map.cc
index 9d5fd5f..12cb811 100644
--- a/src/instruction_map.cc
+++ b/src/instruction_map.cc
@@ -15,6 +15,7 @@
 
 #include <config.h>
 #include "instruction_map.h"
+#include <string.h>  // memset
 #include "addrcache.h"
 #include "vcdiff_defs.h"
 
diff --git a/src/instruction_map_test.cc b/src/instruction_map_test.cc
index c505e49..1070db8 100644
--- a/src/instruction_map_test.cc
+++ b/src/instruction_map_test.cc
@@ -26,7 +26,8 @@
 
 class InstructionMapTest : public testing::Test {
  protected:
-  virtual ~InstructionMapTest() { }
+  static void SetUpTestCase();
+  static void TearDownTestCase();
 
   static void AddExerciseOpcode(unsigned char inst1,
                                 unsigned char mode1,
@@ -34,82 +35,12 @@
                                 unsigned char inst2,
                                 unsigned char mode2,
                                 unsigned char size2,
-                                int opcode) {
-    g_exercise_code_table_->inst1[opcode] = inst1;
-    g_exercise_code_table_->mode1[opcode] = mode1;
-    g_exercise_code_table_->size1[opcode] = (inst1 == VCD_NOOP) ? 0 : size1;
-    g_exercise_code_table_->inst2[opcode] = inst2;
-    g_exercise_code_table_->mode2[opcode] = mode2;
-    g_exercise_code_table_->size2[opcode] = (inst2 == VCD_NOOP) ? 0 : size2;
-  }
-
-  static void SetUpTestCase() {
-    g_exercise_code_table_ = new VCDiffCodeTableData;
-    int opcode = 0;
-    for (unsigned char inst_mode1 = 0;
-         inst_mode1 <= VCD_LAST_INSTRUCTION_TYPE + kLastExerciseMode;
-         ++inst_mode1) {
-      unsigned char inst1 = inst_mode1;
-      unsigned char mode1 = 0;
-      if (inst_mode1 > VCD_COPY) {
-        inst1 = VCD_COPY;
-        mode1 = inst_mode1 - VCD_COPY;
-      }
-      for (unsigned char inst_mode2 = 0;
-           inst_mode2 <= VCD_LAST_INSTRUCTION_TYPE + kLastExerciseMode;
-           ++inst_mode2) {
-        unsigned char inst2 = inst_mode2;
-        unsigned char mode2 = 0;
-        if (inst_mode2 > VCD_COPY) {
-          inst2 = VCD_COPY;
-          mode2 = inst_mode2 - VCD_COPY;
-        }
-        AddExerciseOpcode(inst1, mode1, 0, inst2, mode2, 0, opcode++);
-        AddExerciseOpcode(inst1, mode1, 0, inst2, mode2, 255, opcode++);
-        AddExerciseOpcode(inst1, mode1, 255, inst2, mode2, 0, opcode++);
-        AddExerciseOpcode(inst1, mode1, 255, inst2, mode2, 255, opcode++);
-      }
-    }
-    // This is a CHECK rather than an EXPECT because it validates only
-    // the logic of the test, not of the code being tested.
-    CHECK_EQ(VCDiffCodeTableData::kCodeTableSize, opcode);
-
-    EXPECT_TRUE(VCDiffCodeTableData::kDefaultCodeTableData.Validate());
-    EXPECT_TRUE(g_exercise_code_table_->Validate(kLastExerciseMode));
-    default_map = VCDiffInstructionMap::GetDefaultInstructionMap();
-    exercise_map = new VCDiffInstructionMap(*g_exercise_code_table_,
-                                            kLastExerciseMode);
-  }
-
-  static void TearDownTestCase() {
-    delete exercise_map;
-    delete g_exercise_code_table_;
-  }
+                                int opcode);
 
   void VerifyExerciseFirstInstruction(unsigned char expected_opcode,
                                       unsigned char inst,
                                       unsigned char size,
-                                      unsigned char mode) {
-    int found_opcode = exercise_map->LookupFirstOpcode(inst, size, mode);
-    if (g_exercise_code_table_->inst1[found_opcode] == VCD_NOOP) {
-      // The opcode is backwards: (VCD_NOOP, [instruction])
-      EXPECT_GE(expected_opcode, found_opcode);
-      EXPECT_EQ(inst, g_exercise_code_table_->inst2[found_opcode]);
-      EXPECT_EQ(size, g_exercise_code_table_->size2[found_opcode]);
-      EXPECT_EQ(mode, g_exercise_code_table_->mode2[found_opcode]);
-      EXPECT_EQ(VCD_NOOP, g_exercise_code_table_->inst1[found_opcode]);
-      EXPECT_EQ(0, g_exercise_code_table_->size1[found_opcode]);
-      EXPECT_EQ(0, g_exercise_code_table_->mode1[found_opcode]);
-    } else {
-      EXPECT_EQ(expected_opcode, found_opcode);
-      EXPECT_EQ(inst, g_exercise_code_table_->inst1[found_opcode]);
-      EXPECT_EQ(size, g_exercise_code_table_->size1[found_opcode]);
-      EXPECT_EQ(mode, g_exercise_code_table_->mode1[found_opcode]);
-      EXPECT_EQ(VCD_NOOP, g_exercise_code_table_->inst2[found_opcode]);
-      EXPECT_EQ(0, g_exercise_code_table_->size2[found_opcode]);
-      EXPECT_EQ(0, g_exercise_code_table_->mode2[found_opcode]);
-    }
-  }
+                                      unsigned char mode);
 
   void VerifyExerciseSecondInstruction(unsigned char expected_opcode,
                                        unsigned char inst1,
@@ -117,15 +48,7 @@
                                        unsigned char mode1,
                                        unsigned char inst2,
                                        unsigned char size2,
-                                       unsigned char mode2) {
-    int first_opcode = exercise_map->LookupFirstOpcode(inst1, size1, mode1);
-    EXPECT_NE(kNoOpcode, first_opcode);
-    EXPECT_EQ(expected_opcode,
-              exercise_map->LookupSecondOpcode(first_opcode,
-                                               inst2,
-                                               size2,
-                                               mode2));
-  }
+                                       unsigned char mode2);
 
   // This value is designed so that the total number of inst values and modes
   // will equal 8 (VCD_NOOP, VCD_ADD, VCD_RUN, VCD_COPY modes 0 - 4).
@@ -154,6 +77,107 @@
 const VCDiffInstructionMap* InstructionMapTest::default_map = NULL;
 const VCDiffInstructionMap* InstructionMapTest::exercise_map = NULL;
 
+void InstructionMapTest::SetUpTestCase() {
+  g_exercise_code_table_ = new VCDiffCodeTableData;
+  int opcode = 0;
+  for (unsigned char inst_mode1 = 0;
+       inst_mode1 <= VCD_LAST_INSTRUCTION_TYPE + kLastExerciseMode;
+       ++inst_mode1) {
+    unsigned char inst1 = inst_mode1;
+    unsigned char mode1 = 0;
+    if (inst_mode1 > VCD_COPY) {
+      inst1 = VCD_COPY;
+      mode1 = inst_mode1 - VCD_COPY;
+    }
+    for (unsigned char inst_mode2 = 0;
+         inst_mode2 <= VCD_LAST_INSTRUCTION_TYPE + kLastExerciseMode;
+         ++inst_mode2) {
+      unsigned char inst2 = inst_mode2;
+      unsigned char mode2 = 0;
+      if (inst_mode2 > VCD_COPY) {
+        inst2 = VCD_COPY;
+        mode2 = inst_mode2 - VCD_COPY;
+      }
+      AddExerciseOpcode(inst1, mode1, 0, inst2, mode2, 0, opcode++);
+      AddExerciseOpcode(inst1, mode1, 0, inst2, mode2, 255, opcode++);
+      AddExerciseOpcode(inst1, mode1, 255, inst2, mode2, 0, opcode++);
+      AddExerciseOpcode(inst1, mode1, 255, inst2, mode2, 255, opcode++);
+    }
+  }
+  // This is a CHECK rather than an EXPECT because it validates only
+  // the logic of the test, not of the code being tested.
+  CHECK_EQ(VCDiffCodeTableData::kCodeTableSize, opcode);
+
+  EXPECT_TRUE(VCDiffCodeTableData::kDefaultCodeTableData.Validate());
+  EXPECT_TRUE(g_exercise_code_table_->Validate(kLastExerciseMode));
+  default_map = VCDiffInstructionMap::GetDefaultInstructionMap();
+  exercise_map = new VCDiffInstructionMap(*g_exercise_code_table_,
+                                          kLastExerciseMode);
+}
+
+void InstructionMapTest::TearDownTestCase() {
+  delete exercise_map;
+  delete g_exercise_code_table_;
+}
+
+void InstructionMapTest::AddExerciseOpcode(unsigned char inst1,
+                                           unsigned char mode1,
+                                           unsigned char size1,
+                                           unsigned char inst2,
+                                           unsigned char mode2,
+                                           unsigned char size2,
+                                           int opcode) {
+  g_exercise_code_table_->inst1[opcode] = inst1;
+  g_exercise_code_table_->mode1[opcode] = mode1;
+  g_exercise_code_table_->size1[opcode] = (inst1 == VCD_NOOP) ? 0 : size1;
+  g_exercise_code_table_->inst2[opcode] = inst2;
+  g_exercise_code_table_->mode2[opcode] = mode2;
+  g_exercise_code_table_->size2[opcode] = (inst2 == VCD_NOOP) ? 0 : size2;
+}
+
+void InstructionMapTest::VerifyExerciseFirstInstruction(
+    unsigned char expected_opcode,
+    unsigned char inst,
+    unsigned char size,
+    unsigned char mode) {
+  int found_opcode = exercise_map->LookupFirstOpcode(inst, size, mode);
+  if (g_exercise_code_table_->inst1[found_opcode] == VCD_NOOP) {
+    // The opcode is backwards: (VCD_NOOP, [instruction])
+    EXPECT_GE(expected_opcode, found_opcode);
+    EXPECT_EQ(inst, g_exercise_code_table_->inst2[found_opcode]);
+    EXPECT_EQ(size, g_exercise_code_table_->size2[found_opcode]);
+    EXPECT_EQ(mode, g_exercise_code_table_->mode2[found_opcode]);
+    EXPECT_EQ(VCD_NOOP, g_exercise_code_table_->inst1[found_opcode]);
+    EXPECT_EQ(0, g_exercise_code_table_->size1[found_opcode]);
+    EXPECT_EQ(0, g_exercise_code_table_->mode1[found_opcode]);
+  } else {
+    EXPECT_EQ(expected_opcode, found_opcode);
+    EXPECT_EQ(inst, g_exercise_code_table_->inst1[found_opcode]);
+    EXPECT_EQ(size, g_exercise_code_table_->size1[found_opcode]);
+    EXPECT_EQ(mode, g_exercise_code_table_->mode1[found_opcode]);
+    EXPECT_EQ(VCD_NOOP, g_exercise_code_table_->inst2[found_opcode]);
+    EXPECT_EQ(0, g_exercise_code_table_->size2[found_opcode]);
+    EXPECT_EQ(0, g_exercise_code_table_->mode2[found_opcode]);
+  }
+}
+
+void InstructionMapTest::VerifyExerciseSecondInstruction(
+    unsigned char expected_opcode,
+    unsigned char inst1,
+    unsigned char size1,
+    unsigned char mode1,
+    unsigned char inst2,
+    unsigned char size2,
+    unsigned char mode2) {
+  int first_opcode = exercise_map->LookupFirstOpcode(inst1, size1, mode1);
+  EXPECT_NE(kNoOpcode, first_opcode);
+  EXPECT_EQ(expected_opcode,
+            exercise_map->LookupSecondOpcode(first_opcode,
+                                             inst2,
+                                             size2,
+                                             mode2));
+}
+
 TEST_F(InstructionMapTest, DefaultMapLookupFirstNoop) {
   EXPECT_EQ(kNoOpcode, default_map->LookupFirstOpcode(VCD_NOOP, 0, 0));
   EXPECT_EQ(kNoOpcode, default_map->LookupFirstOpcode(VCD_NOOP, 0, 255));
diff --git a/src/logging.cc b/src/logging.cc
index cdcc42b..e472a48 100644
--- a/src/logging.cc
+++ b/src/logging.cc
@@ -14,6 +14,7 @@
 // limitations under the License.
 
 #include <config.h>
+#include <stdlib.h>  // exit
 #include "logging.h"
 
 namespace open_vcdiff {
diff --git a/src/output_string_test.cc b/src/output_string_test.cc
index 86df075..2b655e9 100644
--- a/src/output_string_test.cc
+++ b/src/output_string_test.cc
@@ -24,16 +24,14 @@
 #endif  // HAVE_EXT_ROPE
 
 namespace open_vcdiff {
-
 namespace {
 
-using std::string;
-#ifdef HAVE_EXT_ROPE
-using __gnu_cxx::crope;
-#endif  // HAVE_EXT_ROPE
-
 class OutputStringTest : public testing::Test {
  public:
+#ifndef VCDIFF_HAS_GLOBAL_STRING
+  typedef std::string string;
+#endif  // !VCDIFF_HAS_GLOBAL_STRING
+
   OutputStringTest() : string_("ab"), output_string_(&string_) { }
 
   virtual ~OutputStringTest() { }
@@ -77,6 +75,8 @@
 #ifdef HAVE_EXT_ROPE
 class OutputCRopeTest : public testing::Test {
  public:
+  typedef __gnu_cxx::crope crope;
+
   OutputCRopeTest() : crope_("ab"), output_crope_(&crope_) { }
 
   virtual ~OutputCRopeTest() { }
diff --git a/src/rolling_hash_test.cc b/src/rolling_hash_test.cc
index 1a7da9a..438aec9 100644
--- a/src/rolling_hash_test.cc
+++ b/src/rolling_hash_test.cc
@@ -16,7 +16,7 @@
 #include <config.h>
 #include "rolling_hash.h"
 #include <stdint.h>  // uint32_t
-#include <cstdlib>  // rand, srand
+#include <stdlib.h>  // rand, srand
 #include <vector>
 #include "testing.h"
 
diff --git a/src/testing.h b/src/testing.h
index 205871b..3227fd8 100644
--- a/src/testing.h
+++ b/src/testing.h
@@ -17,10 +17,10 @@
 #define OPEN_VCDIFF_TESTING_H_
 
 #include <config.h>
-#include <stdint.h>  // int64_t, uint64_t
+#include <assert.h>
+#include <stdint.h>  // int64_t
+#include <stdlib.h>  // rand
 #include <time.h>  // gettimeofday
-#include <cassert>
-#include <cstdlib>  // rand
 #include "gtest/gtest.h"
 
 #ifdef HAVE_SYS_TIME_H
diff --git a/src/varint_bigendian.cc b/src/varint_bigendian.cc
index 4dbf7bb..5098ed2 100644
--- a/src/varint_bigendian.cc
+++ b/src/varint_bigendian.cc
@@ -16,14 +16,13 @@
 #include <config.h>
 #include "varint_bigendian.h"
 #include <stdint.h>  // int32_t, int64_t
+#include <string.h>  // memcpy
 #include <string>
 #include "logging.h"
 #include "google/output_string.h"
 
 namespace open_vcdiff {
 
-using std::string;
-
 template<> const int32_t VarintBE<int32_t>::kMaxVal = 0x7FFFFFFF;
 template<> const int64_t VarintBE<int64_t>::kMaxVal = 0x7FFFFFFFFFFFFFFFULL;
 
diff --git a/src/varint_bigendian.h b/src/varint_bigendian.h
index 34e5035..d5b63d5 100644
--- a/src/varint_bigendian.h
+++ b/src/varint_bigendian.h
@@ -42,8 +42,6 @@
 
 namespace open_vcdiff {
 
-using std::string;
-
 class OutputStringInterface;
 
 // This helper class is needed in order to ensure that
@@ -76,6 +74,10 @@
 template <typename SignedIntegerType>
 class VarintBE {  // BE stands for Big-Endian
  public:
+#ifndef VCDIFF_HAS_GLOBAL_STRING
+  typedef std::string string;
+#endif  // !VCDIFF_HAS_GLOBAL_STRING
+
   // The maximum positive value represented by a SignedIntegerType.
   static const SignedIntegerType kMaxVal;
 
diff --git a/src/varint_bigendian_test.cc b/src/varint_bigendian_test.cc
index 83e180e..6eb8ff0 100644
--- a/src/varint_bigendian_test.cc
+++ b/src/varint_bigendian_test.cc
@@ -15,7 +15,8 @@
 
 #include <config.h>
 #include "varint_bigendian.h"
-#include <cstdlib>  // rand, srand
+#include <stdlib.h>  // rand, srand
+#include <string.h>  // strlen
 #include <string>
 #include <vector>
 #include "logging.h"
@@ -24,10 +25,12 @@
 namespace open_vcdiff {
 namespace {
 
-using std::string;
-
 class VarintBETestCommon : public testing::Test {
  protected:
+#ifndef VCDIFF_HAS_GLOBAL_STRING
+  typedef std::string string;
+#endif  // !VCDIFF_HAS_GLOBAL_STRING
+
   VarintBETestCommon()
       : varint_buf_(VarintBE<int64_t>::kMaxBytes),
         verify_encoded_byte_index_(0),
diff --git a/src/vcdecoder.cc b/src/vcdecoder.cc
index b5ce997..02afa87 100644
--- a/src/vcdecoder.cc
+++ b/src/vcdecoder.cc
@@ -29,8 +29,9 @@
 
 #include <config.h>
 #include "google/vcdecoder.h"
+#include <stddef.h>  // size_t, ptrdiff_t
 #include <stdint.h>  // int32_t
-#include <cstddef>  // size_t, ptrdiff_t
+#include <string.h>  // memcpy, memset
 #include <memory>  // auto_ptr
 #include <string>
 #include "addrcache.h"
@@ -47,8 +48,6 @@
 
 namespace {
 
-using std::string;
-
 enum VCDiffAnnotationType {
   VCD_ANNOTATION_LITERAL,
   VCD_ANNOTATION_DMATCH,
@@ -112,6 +111,10 @@
 //
 class VCDiffDeltaFileWindow {
  public:
+#ifndef VCDIFF_HAS_GLOBAL_STRING
+  typedef std::string string;
+#endif  // !VCDIFF_HAS_GLOBAL_STRING
+
   VCDiffDeltaFileWindow();
   ~VCDiffDeltaFileWindow();
 
@@ -139,7 +142,7 @@
   // is undefined; otherwise, parseable_chunk->Advance() is called to point to
   // the input data position just after the data that has been decoded.
   //
-  // If expected_target_bytes is not set to kUnlimitedBytes, then the decoder
+  // If planned_target_file_size is not set to kUnlimitedBytes, then the decoder
   // expects *exactly* this number of target bytes to be decoded from one or
   // more delta file windows.  If this number is met exactly after finishing a
   // delta window, this function will return RESULT_SUCCESS without processing
@@ -343,9 +346,34 @@
   void operator=(const VCDiffDeltaFileWindow&);
 };
 
+// *** Inline methods for VCDiffDeltaFileWindow
+
+inline VCDiffDeltaFileWindow::VCDiffDeltaFileWindow() : parent_(NULL) {
+  Reset();
+}
+
+inline VCDiffDeltaFileWindow::~VCDiffDeltaFileWindow() { }
+
+inline void VCDiffDeltaFileWindow::Init(VCDiffStreamingDecoderImpl* parent) {
+  parent_ = parent;
+}
+
 class VCDiffStreamingDecoderImpl {
  public:
-  // A constant that is the default value for expected_target_bytes_,
+#ifndef VCDIFF_HAS_GLOBAL_STRING
+  typedef std::string string;
+#endif  // !VCDIFF_HAS_GLOBAL_STRING
+
+  // The default maximum target file size (and target window size) if
+  // SetMaximumTargetFileSize() is not called.
+  static const size_t kDefaultMaximumTargetFileSize = 67108864U;  // 64 MB
+
+  // The largest value that can be passed to SetMaximumTargetFileSize() or
+  // SetMaximumTargetWindowSize().  Using a larger value will result in an
+  // error.
+  static const size_t kTargetSizeLimit = 2147483647U;  // INT32_MAX
+
+  // A constant that is the default value for planned_target_file_size_,
   // indicating that the decoder does not have an expected length
   // for the target data.
   static const size_t kUnlimitedBytes = static_cast<size_t>(-3);
@@ -390,66 +418,67 @@
   //
   bool AllowChecksum() const { return vcdiff_version_code_ == 'S'; }
 
-  // See description of expected_target_bytes_, below.
-  bool HasTargetByteLimit() const {
-    return expected_target_bytes_ != kUnlimitedBytes;
-  }
-
-  void SetTargetByteLimit(size_t expected_target_bytes) {
-    expected_target_bytes_ = expected_target_bytes;
-  }
-
-  // Checks to see whether the decoded target data has reached the expected
-  // size.
-  bool MetTargetByteLimit() const {
-    if (!HasTargetByteLimit()) {
+  bool SetMaximumTargetFileSize(size_t new_maximum_target_file_size) {
+    if (new_maximum_target_file_size > kTargetSizeLimit) {
+      LOG(ERROR) << "Specified maximum target file size "
+                 << new_maximum_target_file_size << " exceeds limit of "
+                 << kTargetSizeLimit << " bytes" << LOG_ENDL;
       return false;
     }
-    // The target byte limit should not have been exceeded, because each target
-    // window size is checked against that limit in ReadHeader(), and
+    maximum_target_file_size_ = new_maximum_target_file_size;
+    return true;
+  }
+
+  bool SetMaximumTargetWindowSize(size_t new_maximum_target_window_size) {
+    if (new_maximum_target_window_size > kTargetSizeLimit) {
+      LOG(ERROR) << "Specified maximum target window size "
+                 << new_maximum_target_window_size << " exceeds limit of "
+                 << kTargetSizeLimit << " bytes" << LOG_ENDL;
+      return false;
+    }
+    maximum_target_window_size_ = new_maximum_target_window_size;
+    return true;
+  }
+
+  // See description of planned_target_file_size_, below.
+  bool HasPlannedTargetFileSize() const {
+    return planned_target_file_size_ != kUnlimitedBytes;
+  }
+
+  void SetPlannedTargetFileSize(size_t planned_target_file_size) {
+    planned_target_file_size_ = planned_target_file_size;
+  }
+
+  // Checks to see whether the decoded target data has reached its planned size.
+  bool ReachedPlannedTargetFileSize() const {
+    if (!HasPlannedTargetFileSize()) {
+      return false;
+    }
+    // The planned target file size should not have been exceeded.
+    // TargetWindowWouldExceedSizeLimits() ensures that the advertised size of
+    // each target window would not make the target file exceed that limit, and
     // DecodeBody() will return RESULT_ERROR if the actual decoded output ever
     // exceeds the advertised target window size.
-    if (decoded_target_.size() > expected_target_bytes_) {
+    if (decoded_target_.size() > planned_target_file_size_) {
       LOG(DFATAL) << "Internal error: Decoded data size "
                   << decoded_target_.size()
-                  << " exceeds target byte limit "
-                  << expected_target_bytes_ << LOG_ENDL;
+                  << " exceeds planned target file size "
+                  << planned_target_file_size_ << LOG_ENDL;
       return true;
     }
-    return decoded_target_.size() == expected_target_bytes_;
+    return decoded_target_.size() == planned_target_file_size_;
   }
 
   // Checks to see whether adding a new target window of the specified size
-  // would exceed the expected target size.  If so, logs an error and returns
-  // true; otherwise, returns false.
-  bool TargetWindowWouldExceedTargetByteLimit(size_t window_size) const {
-    if (!HasTargetByteLimit()) {
-      return false;
-    }
-    // The logical expression to check would be:
-    //
-    //   decoded_target_.size() + target_bytes_to_add > expected_target_bytes_
-    //
-    // but the addition might cause an integer overflow if target_bytes_to_add
-    // is very large.  So it is better to check target_bytes_to_add against
-    // the remaining expected target bytes.
-    size_t remaining_expected_target_bytes =
-        expected_target_bytes_ - decoded_target_.size();
-    if (window_size > remaining_expected_target_bytes) {
-      LOG(ERROR) << "Length of target window (" << window_size
-                 << " bytes) plus previous windows (" << decoded_target_.size()
-                 << " bytes) would exceed expected size of "
-                 << expected_target_bytes_ << " bytes" << LOG_ENDL;
-      return true;
-    } else {
-      return false;
-    }
-  }
+  // would exceed the planned target file size, the maximum target file size,
+  // or the maximum target window size.  If so, logs an error and returns true;
+  // otherwise, returns false.
+  bool TargetWindowWouldExceedSizeLimits(size_t window_size) const;
 
   // Returns the amount of input data passed to the last DecodeChunk()
   // that was not consumed by the decoder.  This is essential if
-  // SetExpectedTargetBytes() is being used, in order to preserve
-  // the input data stream beyond the expected encoding.
+  // SetPlannedTargetFileSize() is being used, in order to preserve the
+  // remaining input data stream once the planned target file has been decoded.
   size_t GetUnconsumedDataSize() const {
     return unparsed_bytes_.size();
   }
@@ -471,8 +500,8 @@
       // The decoder is in the middle of parsing an interleaved format delta
       // window.
       return false;
-    } else if (MetTargetByteLimit()) {
-      // The decoder found exactly the expected number of bytes.  In this case
+    } else if (ReachedPlannedTargetFileSize()) {
+      // The decoder found exactly the planned number of bytes.  In this case
       // it is OK for unparsed_bytes_ to be non-empty; it contains the leftover
       // data after the end of the delta file.
       return true;
@@ -599,7 +628,11 @@
   // stop processing the embedded data once the entire code table has
   // been decoded, and treat the rest of the available data as part
   // of the enclosing delta file.
-  size_t expected_target_bytes_;
+  size_t planned_target_file_size_;
+
+  size_t maximum_target_file_size_;
+
+  size_t maximum_target_window_size_;
 
   // This string will always be empty until EnableAnnotatedOutput() is called,
   // at which point it will start to accumulate annotated delta windows each
@@ -620,7 +653,12 @@
 
 // *** Methods for VCDiffStreamingDecoderImpl
 
-VCDiffStreamingDecoderImpl::VCDiffStreamingDecoderImpl() {
+const size_t VCDiffStreamingDecoderImpl::kDefaultMaximumTargetFileSize;
+const size_t VCDiffStreamingDecoderImpl::kUnlimitedBytes;
+
+VCDiffStreamingDecoderImpl::VCDiffStreamingDecoderImpl()
+    : maximum_target_file_size_(kDefaultMaximumTargetFileSize),
+      maximum_target_window_size_(kDefaultMaximumTargetFileSize) {
   delta_window_.Init(this);
   Reset();
 }
@@ -633,7 +671,7 @@
   dictionary_ptr_ = NULL;
   dictionary_size_ = 0;
   vcdiff_version_code_ = '\0';
-  expected_target_bytes_ = kUnlimitedBytes;
+  planned_target_file_size_ = kUnlimitedBytes;
   addr_cache_.reset();
   custom_code_table_.reset();
   custom_code_table_decoder_.reset();
@@ -779,7 +817,8 @@
       reinterpret_cast<const char*>(
           &VCDiffCodeTableData::kDefaultCodeTableData),
       sizeof(VCDiffCodeTableData::kDefaultCodeTableData));
-  custom_code_table_decoder_->SetTargetByteLimit(sizeof(*custom_code_table_));
+  custom_code_table_decoder_->SetPlannedTargetFileSize(
+      sizeof(*custom_code_table_));
   return static_cast<int>(header_parser.ParsedSize());
 }
 
@@ -808,10 +847,10 @@
     return RESULT_ERROR;
   }
   if (custom_code_table_string_.length() != sizeof(*custom_code_table_)) {
-    LOG(DFATAL) << "Decoded custom code table size "
+    LOG(DFATAL) << "Decoded custom code table size ("
                 << custom_code_table_string_.length()
-                << " does not match expected size "
-                << sizeof(*custom_code_table_) << LOG_ENDL;
+                << ") does not match size of a code table ("
+                << sizeof(*custom_code_table_) << ")" << LOG_ENDL;
     return RESULT_ERROR;
   }
   memcpy(custom_code_table_.get(),
@@ -829,6 +868,10 @@
 
 class TrackNewOutputText {
  public:
+#ifndef VCDIFF_HAS_GLOBAL_STRING
+  typedef std::string string;
+#endif  // !VCDIFF_HAS_GLOBAL_STRING
+
   explicit TrackNewOutputText(const string& decoded_target)
       : decoded_target_(decoded_target),
       initial_decoded_target_size_(decoded_target.size()) { }
@@ -912,18 +955,46 @@
   return success;
 }
 
+bool VCDiffStreamingDecoderImpl::TargetWindowWouldExceedSizeLimits(
+    size_t window_size) const {
+  if (window_size > maximum_target_window_size_) {
+    LOG(ERROR) << "Length of target window (" << window_size
+               << ") exceeds limit of " << maximum_target_window_size_
+               << " bytes" << LOG_ENDL;
+    return true;
+  }
+  if (HasPlannedTargetFileSize()) {
+    // The logical expression to check would be:
+    //
+    //   decoded_target_.size() + window_size > planned_target_file_size_
+    //
+    // but the addition might cause an integer overflow if target_bytes_to_add
+    // is very large.  So it is better to check target_bytes_to_add against
+    // the remaining planned target bytes.
+    size_t remaining_planned_target_file_size =
+        planned_target_file_size_ - decoded_target_.size();
+    if (window_size > remaining_planned_target_file_size) {
+      LOG(ERROR) << "Length of target window (" << window_size
+                 << " bytes) plus previous windows (" << decoded_target_.size()
+                 << " bytes) would exceed planned size of "
+                 << planned_target_file_size_ << " bytes" << LOG_ENDL;
+      return true;
+    }
+  }
+  size_t remaining_maximum_target_bytes =
+      maximum_target_file_size_ - decoded_target_.size();
+  if (window_size > remaining_maximum_target_bytes) {
+    LOG(ERROR) << "Length of target window (" << window_size
+               << " bytes) plus previous windows (" << decoded_target_.size()
+               << " bytes) would exceed maximum target file size of "
+               << maximum_target_file_size_ << " bytes" << LOG_ENDL;
+    return true;
+  }
+  return false;
+}
+
 // *** Methods for VCDiffDeltaFileWindow
 
-inline VCDiffDeltaFileWindow::VCDiffDeltaFileWindow() : parent_(NULL) {
-  Reset();
-}
-
-inline VCDiffDeltaFileWindow::~VCDiffDeltaFileWindow() { }
-
-inline void VCDiffDeltaFileWindow::Init(VCDiffStreamingDecoderImpl* parent) {
-  parent_ = parent;
-}
-
 void VCDiffDeltaFileWindow::Reset() {
   found_header_ = false;
 
@@ -1031,8 +1102,8 @@
   if (!header_parser.ParseWindowLengths(&target_window_length_)) {
     return header_parser.GetResult();
   }
-  if (parent_->TargetWindowWouldExceedTargetByteLimit(target_window_length_)) {
-    // An error has been logged by TargetWindowWouldExceedTargetByteLimit().
+  if (parent_->TargetWindowWouldExceedSizeLimits(target_window_length_)) {
+    // An error has been logged by TargetWindowWouldExceedSizeLimits().
     return RESULT_ERROR;
   }
   header_parser.ParseDeltaIndicator();
@@ -1341,8 +1412,8 @@
     AppendAnnotatedOutput(parent_->annotated_output());
     // Get ready to read a new delta window
     Reset();
-    if (parent_->MetTargetByteLimit()) {
-      // Found exactly the length expected.  Stop decoding.
+    if (parent_->ReachedPlannedTargetFileSize()) {
+      // Found exactly the length we expected.  Stop decoding.
       return RESULT_SUCCESS;
     }
   }
@@ -1371,6 +1442,16 @@
   return impl_->FinishDecoding();
 }
 
+bool VCDiffStreamingDecoder::SetMaximumTargetFileSize(
+    size_t new_maximum_target_file_size) {
+  return impl_->SetMaximumTargetFileSize(new_maximum_target_file_size);
+}
+
+bool VCDiffStreamingDecoder::SetMaximumTargetWindowSize(
+    size_t new_maximum_target_window_size) {
+  return impl_->SetMaximumTargetWindowSize(new_maximum_target_window_size);
+}
+
 void VCDiffStreamingDecoder::EnableAnnotatedOutput() {
   impl_->EnableAnnotatedOutput();
 }
diff --git a/src/vcdecoder_test1.cc b/src/vcdecoder1_test.cc
similarity index 94%
rename from src/vcdecoder_test1.cc
rename to src/vcdecoder1_test.cc
index f0dae41..7c825d7 100644
--- a/src/vcdecoder_test1.cc
+++ b/src/vcdecoder1_test.cc
@@ -22,8 +22,6 @@
 
 namespace open_vcdiff {
 
-using std::string;
-
 TEST_F(VCDiffStandardDecoderTest, DecodeHeaderOnly) {
   decoder_.StartDecoding(dictionary_.data(), dictionary_.size());
   EXPECT_TRUE(decoder_.DecodeChunk(delta_file_header_.data(),
@@ -78,6 +76,44 @@
   EXPECT_EQ("", output_);
 }
 
+TEST_F(VCDiffStandardDecoderTest, TargetMatchesWindowSizeLimit) {
+  decoder_.SetMaximumTargetWindowSize(expected_target_.size());
+  decoder_.StartDecoding(dictionary_.data(), dictionary_.size());
+  EXPECT_TRUE(decoder_.DecodeChunk(delta_file_.data(),
+                                   delta_file_.size(),
+                                   &output_));
+  EXPECT_TRUE(decoder_.FinishDecoding());
+  EXPECT_EQ(expected_target_, output_);
+}
+
+TEST_F(VCDiffStandardDecoderTest, TargetMatchesFileSizeLimit) {
+  decoder_.SetMaximumTargetFileSize(expected_target_.size());
+  decoder_.StartDecoding(dictionary_.data(), dictionary_.size());
+  EXPECT_TRUE(decoder_.DecodeChunk(delta_file_.data(),
+                                   delta_file_.size(),
+                                   &output_));
+  EXPECT_TRUE(decoder_.FinishDecoding());
+  EXPECT_EQ(expected_target_, output_);
+}
+
+TEST_F(VCDiffStandardDecoderTest, TargetExceedsWindowSizeLimit) {
+  decoder_.SetMaximumTargetWindowSize(expected_target_.size() - 1);
+  decoder_.StartDecoding(dictionary_.data(), dictionary_.size());
+  EXPECT_FALSE(decoder_.DecodeChunk(delta_file_.data(),
+                                    delta_file_.size(),
+                                    &output_));
+  EXPECT_EQ("", output_);
+}
+
+TEST_F(VCDiffStandardDecoderTest, TargetExceedsFileSizeLimit) {
+  decoder_.SetMaximumTargetFileSize(expected_target_.size() - 1);
+  decoder_.StartDecoding(dictionary_.data(), dictionary_.size());
+  EXPECT_FALSE(decoder_.DecodeChunk(delta_file_.data(),
+                                    delta_file_.size(),
+                                    &output_));
+  EXPECT_EQ("", output_);
+}
+
 // Fuzz bits to make sure decoder does not violently crash.
 // This test has no expected behavior except that no crashes should occur.
 // In some cases, changing bits will still decode to the correct target;
diff --git a/src/vcdecoder_test2.cc b/src/vcdecoder2_test.cc
similarity index 95%
rename from src/vcdecoder_test2.cc
rename to src/vcdecoder2_test.cc
index a051b12..7f24a78 100644
--- a/src/vcdecoder_test2.cc
+++ b/src/vcdecoder2_test.cc
@@ -15,15 +15,12 @@
 
 #include <config.h>
 #include "google/vcdecoder.h"
-#include <string>
 #include "testing.h"
 #include "vcdecoder_test.h"
 #include "vcdiff_defs.h"  // VCD_SOURCE
 
 namespace open_vcdiff {
 
-using std::string;
-
 // These are the same tests as for VCDiffStandardDecoderTest, with the added
 // complication that instead of calling DecodeChunk() once with the entire data
 // set, DecodeChunk() is called once for each byte of input.  This is intended
@@ -95,6 +92,54 @@
   EXPECT_GE(expected_target_.size(), output_.size());
 }
 
+TEST_F(VCDiffStandardDecoderTestByteByByte, TargetMatchesWindowSizeLimit) {
+  decoder_.SetMaximumTargetWindowSize(expected_target_.size());
+  decoder_.StartDecoding(dictionary_.data(), dictionary_.size());
+  for (size_t i = 0; i < delta_file_.size(); ++i) {
+    EXPECT_TRUE(decoder_.DecodeChunk(&delta_file_[i], 1, &output_));
+  }
+  EXPECT_TRUE(decoder_.FinishDecoding());
+  EXPECT_EQ(expected_target_, output_);
+}
+
+TEST_F(VCDiffStandardDecoderTestByteByByte, TargetMatchesFileSizeLimit) {
+  decoder_.SetMaximumTargetFileSize(expected_target_.size());
+  decoder_.StartDecoding(dictionary_.data(), dictionary_.size());
+  for (size_t i = 0; i < delta_file_.size(); ++i) {
+    EXPECT_TRUE(decoder_.DecodeChunk(&delta_file_[i], 1, &output_));
+  }
+  EXPECT_TRUE(decoder_.FinishDecoding());
+  EXPECT_EQ(expected_target_, output_);
+}
+
+TEST_F(VCDiffStandardDecoderTestByteByByte, TargetExceedsWindowSizeLimit) {
+  decoder_.SetMaximumTargetWindowSize(expected_target_.size() - 1);
+  decoder_.StartDecoding(dictionary_.data(), dictionary_.size());
+  bool failed = false;
+  for (size_t i = 0; i < delta_file_.size(); ++i) {
+    if (!decoder_.DecodeChunk(&delta_file_[i], 1, &output_)) {
+      failed = true;
+      break;
+    }
+  }
+  EXPECT_TRUE(failed);
+  EXPECT_EQ("", output_);
+}
+
+TEST_F(VCDiffStandardDecoderTestByteByByte, TargetExceedsFileSizeLimit) {
+  decoder_.SetMaximumTargetFileSize(expected_target_.size() - 1);
+  decoder_.StartDecoding(dictionary_.data(), dictionary_.size());
+  bool failed = false;
+  for (size_t i = 0; i < delta_file_.size(); ++i) {
+    if (!decoder_.DecodeChunk(&delta_file_[i], 1, &output_)) {
+      failed = true;
+      break;
+    }
+  }
+  EXPECT_TRUE(failed);
+  EXPECT_EQ("", output_);
+}
+
 // Fuzz bits to make sure decoder does not violently crash.
 // This test has no expected behavior except that no crashes should occur.
 // In some cases, changing bits will still decode to the correct target;
diff --git a/src/vcdecoder_test3.cc b/src/vcdecoder3_test.cc
similarity index 92%
rename from src/vcdecoder_test3.cc
rename to src/vcdecoder3_test.cc
index c470d0d..3a0673c 100644
--- a/src/vcdecoder_test3.cc
+++ b/src/vcdecoder3_test.cc
@@ -15,8 +15,8 @@
 
 #include <config.h>
 #include "google/vcdecoder.h"
-#include <cstdlib>  // free, posix_memalign
-#include <cstring>  // memcpy
+#include <stdlib.h>  // free, posix_memalign
+#include <string.h>  // memcpy
 #include <string>
 #include "testing.h"
 #include "varint_bigendian.h"
@@ -38,8 +38,6 @@
 
 namespace open_vcdiff {
 
-using std::string;
-
 // Test headers, valid and invalid.
 
 TEST_F(VCDiffInterleavedDecoderTest, DecodeHeaderOnly) {
@@ -159,6 +157,44 @@
   EXPECT_GE(expected_target_.size(), output_.size());
 }
 
+TEST_F(VCDiffInterleavedDecoderTest, TargetMatchesWindowSizeLimit) {
+  decoder_.SetMaximumTargetWindowSize(expected_target_.size());
+  decoder_.StartDecoding(dictionary_.data(), dictionary_.size());
+  EXPECT_TRUE(decoder_.DecodeChunk(delta_file_.data(),
+                                   delta_file_.size(),
+                                   &output_));
+  EXPECT_TRUE(decoder_.FinishDecoding());
+  EXPECT_EQ(expected_target_, output_);
+}
+
+TEST_F(VCDiffInterleavedDecoderTest, TargetMatchesFileSizeLimit) {
+  decoder_.SetMaximumTargetFileSize(expected_target_.size());
+  decoder_.StartDecoding(dictionary_.data(), dictionary_.size());
+  EXPECT_TRUE(decoder_.DecodeChunk(delta_file_.data(),
+                                   delta_file_.size(),
+                                   &output_));
+  EXPECT_TRUE(decoder_.FinishDecoding());
+  EXPECT_EQ(expected_target_, output_);
+}
+
+TEST_F(VCDiffInterleavedDecoderTest, TargetExceedsWindowSizeLimit) {
+  decoder_.SetMaximumTargetWindowSize(expected_target_.size() - 1);
+  decoder_.StartDecoding(dictionary_.data(), dictionary_.size());
+  EXPECT_FALSE(decoder_.DecodeChunk(delta_file_.data(),
+                                    delta_file_.size(),
+                                    &output_));
+  EXPECT_EQ("", output_);
+}
+
+TEST_F(VCDiffInterleavedDecoderTest, TargetExceedsFileSizeLimit) {
+  decoder_.SetMaximumTargetFileSize(expected_target_.size() - 1);
+  decoder_.StartDecoding(dictionary_.data(), dictionary_.size());
+  EXPECT_FALSE(decoder_.DecodeChunk(delta_file_.data(),
+                                    delta_file_.size(),
+                                    &output_));
+  EXPECT_EQ("", output_);
+}
+
 // Fuzz bits to make sure decoder does not violently crash.
 // This test has no expected behavior except that no crashes should occur.
 // In some cases, changing bits will still decode to the correct target;
@@ -659,6 +695,54 @@
   EXPECT_GE(expected_target_.size(), output_.size());
 }
 
+TEST_F(VCDiffInterleavedDecoderTestByteByByte, TargetMatchesWindowSizeLimit) {
+  decoder_.SetMaximumTargetWindowSize(expected_target_.size());
+  decoder_.StartDecoding(dictionary_.data(), dictionary_.size());
+  for (size_t i = 0; i < delta_file_.size(); ++i) {
+    EXPECT_TRUE(decoder_.DecodeChunk(&delta_file_[i], 1, &output_));
+  }
+  EXPECT_TRUE(decoder_.FinishDecoding());
+  EXPECT_EQ(expected_target_, output_);
+}
+
+TEST_F(VCDiffInterleavedDecoderTestByteByByte, TargetMatchesFileSizeLimit) {
+  decoder_.SetMaximumTargetFileSize(expected_target_.size());
+  decoder_.StartDecoding(dictionary_.data(), dictionary_.size());
+  for (size_t i = 0; i < delta_file_.size(); ++i) {
+    EXPECT_TRUE(decoder_.DecodeChunk(&delta_file_[i], 1, &output_));
+  }
+  EXPECT_TRUE(decoder_.FinishDecoding());
+  EXPECT_EQ(expected_target_, output_);
+}
+
+TEST_F(VCDiffInterleavedDecoderTestByteByByte, TargetExceedsWindowSizeLimit) {
+  decoder_.SetMaximumTargetWindowSize(expected_target_.size() - 1);
+  decoder_.StartDecoding(dictionary_.data(), dictionary_.size());
+  bool failed = false;
+  for (size_t i = 0; i < delta_file_.size(); ++i) {
+    if (!decoder_.DecodeChunk(&delta_file_[i], 1, &output_)) {
+      failed = true;
+      break;
+    }
+  }
+  EXPECT_TRUE(failed);
+  EXPECT_EQ("", output_);
+}
+
+TEST_F(VCDiffInterleavedDecoderTestByteByByte, TargetExceedsFileSizeLimit) {
+  decoder_.SetMaximumTargetFileSize(expected_target_.size() - 1);
+  decoder_.StartDecoding(dictionary_.data(), dictionary_.size());
+  bool failed = false;
+  for (size_t i = 0; i < delta_file_.size(); ++i) {
+    if (!decoder_.DecodeChunk(&delta_file_[i], 1, &output_)) {
+      failed = true;
+      break;
+    }
+  }
+  EXPECT_TRUE(failed);
+  EXPECT_EQ("", output_);
+}
+
 // Fuzz bits to make sure decoder does not violently crash.
 // This test has no expected behavior except that no crashes should occur.
 // In some cases, changing bits will still decode to the correct target;
diff --git a/src/vcdecoder_test4.cc b/src/vcdecoder4_test.cc
similarity index 94%
rename from src/vcdecoder_test4.cc
rename to src/vcdecoder4_test.cc
index adb99e8..a77aa46 100644
--- a/src/vcdecoder_test4.cc
+++ b/src/vcdecoder4_test.cc
@@ -24,8 +24,6 @@
 namespace open_vcdiff {
 namespace {
 
-using std::string;
-
 // Use the interleaved file header with the standard encoding.  Should work.
 class VCDiffDecoderInterleavedAllowedButNotUsed
     : public VCDiffStandardDecoderTest {
@@ -117,6 +115,8 @@
 // Each delta instruction appears in its own window.
 class VCDiffStandardWindowDecoderTest : public VCDiffDecoderTest {
  protected:
+  static const size_t kWindow2Size = 61;
+
   VCDiffStandardWindowDecoderTest();
   virtual ~VCDiffStandardWindowDecoderTest() {}
 
@@ -125,6 +125,8 @@
   static const char kWindowBody[];
 };
 
+const size_t VCDiffStandardWindowDecoderTest::kWindow2Size;
+
 const char VCDiffStandardWindowDecoderTest::kWindowBody[] = {
 // Window 1:
     VCD_SOURCE,  // Win_Indicator: take source from dictionary
@@ -146,7 +148,7 @@
 // Window 2:
     0x00,  // Win_Indicator: No source segment (ADD only)
     0x44,  // Length of the delta encoding
-    0x3D,  // Size of the target window (61)
+    static_cast<char>(kWindow2Size),  // Size of the target window (61)
     0x00,  // Delta_indicator (no compression)
     0x3D,  // length of data for ADDs and RUNs
     0x02,  // length of instructions section
@@ -337,6 +339,47 @@
   }
 }
 
+// For the window test, the maximum target window size is much smaller than the
+// target file size.  (The largest window is Window 2, with 61 target bytes.)
+// Use the minimum values possible.
+TEST_F(VCDiffStandardWindowDecoderTest, TargetMatchesWindowSizeLimit) {
+  decoder_.SetMaximumTargetWindowSize(kWindow2Size);
+  decoder_.StartDecoding(dictionary_.data(), dictionary_.size());
+  EXPECT_TRUE(decoder_.DecodeChunk(delta_file_.data(),
+                                   delta_file_.size(),
+                                   &output_));
+  EXPECT_TRUE(decoder_.FinishDecoding());
+  EXPECT_EQ(expected_target_, output_);
+}
+
+TEST_F(VCDiffStandardWindowDecoderTest, TargetMatchesFileSizeLimit) {
+  decoder_.SetMaximumTargetFileSize(expected_target_.size());
+  decoder_.StartDecoding(dictionary_.data(), dictionary_.size());
+  EXPECT_TRUE(decoder_.DecodeChunk(delta_file_.data(),
+                                   delta_file_.size(),
+                                   &output_));
+  EXPECT_TRUE(decoder_.FinishDecoding());
+  EXPECT_EQ(expected_target_, output_);
+}
+
+TEST_F(VCDiffStandardWindowDecoderTest, TargetExceedsWindowSizeLimit) {
+  decoder_.SetMaximumTargetWindowSize(kWindow2Size - 1);
+  decoder_.StartDecoding(dictionary_.data(), dictionary_.size());
+  EXPECT_FALSE(decoder_.DecodeChunk(delta_file_.data(),
+                                    delta_file_.size(),
+                                    &output_));
+  EXPECT_EQ("", output_);
+}
+
+TEST_F(VCDiffStandardWindowDecoderTest, TargetExceedsFileSizeLimit) {
+  decoder_.SetMaximumTargetFileSize(expected_target_.size() - 1);
+  decoder_.StartDecoding(dictionary_.data(), dictionary_.size());
+  EXPECT_FALSE(decoder_.DecodeChunk(delta_file_.data(),
+                                    delta_file_.size(),
+                                    &output_));
+  EXPECT_EQ("", output_);
+}
+
 typedef VCDiffStandardWindowDecoderTest
     VCDiffStandardWindowDecoderTestByteByByte;
 TEST_F(VCDiffStandardWindowDecoderTestByteByByte, Decode) {
diff --git a/src/vcdecoder_test.cc b/src/vcdecoder_test.cc
index 10ae599..0faa248 100644
--- a/src/vcdecoder_test.cc
+++ b/src/vcdecoder_test.cc
@@ -15,7 +15,7 @@
 
 #include <config.h>
 #include "vcdecoder_test.h"
-#include <string>
+#include <string.h>  // strlen
 #include "checksum.h"
 #include "codetable.h"
 #include "testing.h"
@@ -24,8 +24,6 @@
 
 namespace open_vcdiff {
 
-using std::string;
-
 const char VCDiffDecoderTest::kStandardFileHeader[] = {
     0xD6,  // 'V' | 0x80
     0xC3,  // 'C' | 0x80
diff --git a/src/vcdecoder_test.h b/src/vcdecoder_test.h
index f3c5195..3748c0d 100644
--- a/src/vcdecoder_test.h
+++ b/src/vcdecoder_test.h
@@ -29,6 +29,10 @@
 // overwritten by each specific decoder test as needed.
 class VCDiffDecoderTest : public testing::Test {
  protected:
+#ifndef VCDIFF_HAS_GLOBAL_STRING
+  typedef std::string string;
+#endif  // !VCDIFF_HAS_GLOBAL_STRING
+
   static const char kDictionary[];
   static const char kExpectedTarget[];
   static const char kExpectedAnnotatedTarget[];
diff --git a/src/vcdiff_defs.h b/src/vcdiff_defs.h
index ed35f1f..b59af53 100644
--- a/src/vcdiff_defs.h
+++ b/src/vcdiff_defs.h
@@ -22,8 +22,8 @@
 #define OPEN_VCDIFF_VCDIFF_DEFS_H_
 
 #include <config.h>
+#include <limits.h>             // UCHAR_MAX
 #include <stdint.h>             // int32_t
-#include <climits>              // UCHAR_MAX
 
 namespace open_vcdiff {
 
diff --git a/src/vcdiff_main.cc b/src/vcdiff_main.cc
index 714e6f8..e8388a4 100644
--- a/src/vcdiff_main.cc
+++ b/src/vcdiff_main.cc
@@ -16,10 +16,10 @@
 // A command-line interface to the open-vcdiff library.
 
 #include <config.h>
-#include <cassert>
-#include <cerrno>
-#include <cstdio>
-#include <cstring>  // strerror
+#include <assert.h>
+#include <errno.h>
+#include <stdio.h>
+#include <string.h>  // strerror
 #include <memory>
 #include <string>
 #include <vector>
@@ -28,7 +28,9 @@
 #include "google/vcdecoder.h"
 #include "google/vcencoder.h"
 
+#ifndef VCDIFF_HAS_GLOBAL_STRING
 using std::string;
+#endif  // !VCDIFF_HAS_GLOBAL_STRING
 using google::GetCommandLineFlagInfoOrDie;
 using google::ShowUsageWithFlagsRestrict;
 
@@ -55,6 +57,10 @@
 DEFINE_bool(stats, false, "Report compression percentage");
 DEFINE_bool(target_matches, false, "Find duplicate strings in target data"
                                    " as well as dictionary data");
+DEFINE_uint64(max_target_file_size, kMaxBufferSize,
+              "Maximum target file size allowed by decoder");
+DEFINE_uint64(max_target_window_size, kMaxBufferSize,
+              "Maximum target window size allowed by decoder");
 
 static const char* const kUsageString =
     " {encode | delta | decode | patch }[ <options> ]\n"
@@ -426,6 +432,8 @@
   }
 
   open_vcdiff::VCDiffStreamingDecoder decoder;
+  decoder.SetMaximumTargetFileSize(FLAGS_max_target_file_size);
+  decoder.SetMaximumTargetWindowSize(FLAGS_max_target_window_size);
   string output;
   size_t input_size = 0;
   size_t output_size = 0;
@@ -479,6 +487,8 @@
   }
 
   open_vcdiff::VCDiffStreamingDecoder decoder;
+  decoder.SetMaximumTargetFileSize(FLAGS_max_target_file_size);
+  decoder.SetMaximumTargetWindowSize(FLAGS_max_target_window_size);
   string output;
   size_t input_size = 0;
   size_t output_size = 0;
diff --git a/src/vcdiff_test.sh b/src/vcdiff_test.sh
new file mode 100755
index 0000000..19cd93d
--- /dev/null
+++ b/src/vcdiff_test.sh
@@ -0,0 +1,476 @@
+#!/bin/bash
+#
+# Copyright 2008 Google Inc.
+# Author: Lincoln Smith
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http:#www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+# The caller should set the environment variable $srcdir to the root directory
+# of the open-vcdiff package.  ($srcdir is automatically provided by Automake
+# when this script is run by "make check".)
+
+# Find input files
+VCDIFF=./vcdiff
+# These options are only needed for the encoder;
+# the decoder will recognize the interleaved and checksum formats
+# without needing to specify any options.
+VCD_OPTIONS="-interleaved -checksum"
+DICTIONARY_FILE=$srcdir/testdata/configure.ac.v0.1
+TARGET_FILE=$srcdir/testdata/configure.ac.v0.2
+TEST_TMPDIR=${TMPDIR-/tmp}
+DELTA_FILE=$TEST_TMPDIR/configure.ac.vcdiff
+OUTPUT_TARGET_FILE=$TEST_TMPDIR/configure.ac.output
+MALICIOUS_ENCODING=$srcdir/testdata/allocates_4gb.vcdiff
+
+# vcdiff with no arguments shows usage information & error result
+$VCDIFF \
+&& { echo "vcdiff with no arguments should fail, but succeeded"; \
+     exit 1; }
+echo "Test 1 ok";
+
+# vcdiff with three arguments but without "encode" or "decode"
+# shows usage information & error result
+$VCDIFF $VCD_OPTIONS \
+        -dictionary $DICTIONARY_FILE -target $TARGET_FILE -delta $DELTA_FILE \
+&& { echo "vcdiff without operation argument should fail, but succeeded"; \
+     exit 1; }
+echo "Test 2 ok";
+
+# vcdiff with all three arguments.  Verify that output file matches target file
+$VCDIFF $VCD_OPTIONS \
+        encode -dictionary $DICTIONARY_FILE \
+               -target $TARGET_FILE \
+               -delta $DELTA_FILE \
+|| { echo "Encode with three arguments failed"; \
+     exit 1; }
+$VCDIFF decode -dictionary $DICTIONARY_FILE \
+               -delta $DELTA_FILE \
+               -target $OUTPUT_TARGET_FILE \
+|| { echo "Decode with three arguments failed"; \
+     exit 1; }
+cmp $TARGET_FILE $OUTPUT_TARGET_FILE \
+|| { echo "Decoded target does not match original"; \
+     exit 1; }
+echo "Test 3 ok";
+
+rm $DELTA_FILE
+rm $OUTPUT_TARGET_FILE
+
+# vcdiff using stdin/stdout.  Verify that output file matches target file
+{ $VCDIFF $VCD_OPTIONS \
+          encode -dictionary $DICTIONARY_FILE \
+                 < $TARGET_FILE \
+                 > $DELTA_FILE; } \
+|| { echo "Encode using stdin/stdout failed"; \
+     exit 1; }
+{ $VCDIFF decode -dictionary $DICTIONARY_FILE \
+                 < $DELTA_FILE \
+                 > $OUTPUT_TARGET_FILE; } \
+|| { echo "Decode using stdin/stdout failed"; \
+     exit 1; }
+cmp $TARGET_FILE $OUTPUT_TARGET_FILE \
+|| { echo "Decoded target does not match original"; \
+     exit 1; }
+echo "Test 4 ok";
+
+rm $DELTA_FILE
+rm $OUTPUT_TARGET_FILE
+
+# vcdiff with mixed stdin/stdout.
+{ $VCDIFF $VCD_OPTIONS \
+          encode -dictionary $DICTIONARY_FILE \
+                 -target $TARGET_FILE \
+                 > $DELTA_FILE; } \
+|| { echo "Encode with mixed arguments failed"; \
+     exit 1; }
+{ $VCDIFF decode -dictionary $DICTIONARY_FILE \
+                 -delta $DELTA_FILE \
+                 > $OUTPUT_TARGET_FILE; } \
+|| { echo "Decode with mixed arguments failed"; \
+     exit 1; }
+cmp $TARGET_FILE $OUTPUT_TARGET_FILE \
+|| { echo "Decoded target does not match original"; \
+     exit 1; }
+echo "Test 5 ok";
+
+rm $DELTA_FILE
+rm $OUTPUT_TARGET_FILE
+
+{ $VCDIFF $VCD_OPTIONS \
+          encode -dictionary $DICTIONARY_FILE \
+                 < $TARGET_FILE \
+                 -delta $DELTA_FILE; } \
+|| { echo "Encode with mixed arguments failed"; \
+     exit 1; }
+{ $VCDIFF decode -dictionary $DICTIONARY_FILE \
+                 < $DELTA_FILE \
+                 -target $OUTPUT_TARGET_FILE; } \
+|| { echo "Decode with mixed arguments failed"; \
+     exit 1; }
+cmp $TARGET_FILE $OUTPUT_TARGET_FILE \
+|| { echo "Decoded target does not match original"; \
+     exit 1; }
+echo "Test 6 ok";
+
+rm $OUTPUT_TARGET_FILE
+# Don't remove $DELTA_FILE; use it for the next test
+
+# If using the wrong dictionary, and dictionary is smaller than the original
+# dictionary, vcdiff will spot the mistake and return an error.  (It can't
+# detect the case where the wrong dictionary is larger than the right one.)
+$VCDIFF decode -dictionary $TARGET_FILE \
+               -delta $DELTA_FILE \
+               -target $OUTPUT_TARGET_FILE \
+&& { echo "Decode using larger dictionary should fail, but succeeded"; \
+     exit 1; }
+echo "Test 7 ok";
+
+rm $DELTA_FILE
+rm $OUTPUT_TARGET_FILE
+
+# "vcdiff test" with all three arguments.
+$VCDIFF $VCD_OPTIONS \
+        test -dictionary $DICTIONARY_FILE \
+             -target $TARGET_FILE \
+             -delta $DELTA_FILE \
+|| { echo "vcdiff test with three arguments failed"; \
+     exit 1; }
+echo "Test 8 ok";
+
+rm $DELTA_FILE
+
+# Dictionary file not found.
+$VCDIFF $VCD_OPTIONS \
+        encode -dictionary $TEST_TMPDIR/nonexistent_file \
+               -target $TARGET_FILE \
+               -delta $DELTA_FILE \
+&& { echo "vcdiff with missing dictionary file should fail, but succeeded"; \
+     exit 1; }
+echo "Test 9 ok";
+
+# Target file not found.
+$VCDIFF $VCD_OPTIONS \
+        encode -dictionary $DICTIONARY_FILE \
+               -target $TEST_TMPDIR/nonexistent_file \
+               -delta $DELTA_FILE \
+&& { echo "vcdiff with missing target file should fail, but succeeded"; \
+     exit 1; }
+echo "Test 10 ok";
+
+# Delta file not found.
+$VCDIFF decode -dictionary $DICTIONARY_FILE \
+               -delta $TEST_TMPDIR/nonexistent_file \
+               -target $OUTPUT_TARGET_FILE \
+&& { echo "vcdiff with missing delta file should fail, but succeeded"; \
+     exit 1; }
+echo "Test 11 ok";
+
+# Try traversing an infinite loop of symbolic links.
+ln -s $TEST_TMPDIR/infinite_loop1 $TEST_TMPDIR/infinite_loop2
+ln -s $TEST_TMPDIR/infinite_loop2 $TEST_TMPDIR/infinite_loop1
+$VCDIFF $VCD_OPTIONS \
+        encode -dictionary $TEST_TMPDIR/infinite_loop1 \
+               -target $TEST_TMPDIR/infinite_loop2 \
+               -delta $DELTA_FILE \
+&& { echo "vcdiff with symbolic link loop should fail, but succeeded"; \
+     exit 1; }
+echo "Test 12 ok";
+
+rm $TEST_TMPDIR/infinite_loop1 $TEST_TMPDIR/infinite_loop2
+
+# Test using -stats flag
+$VCDIFF $VCD_OPTIONS \
+        encode -dictionary $DICTIONARY_FILE \
+               -target $TARGET_FILE \
+               -delta $DELTA_FILE \
+               -stats \
+|| { echo "Encode with -stats failed"; \
+     exit 1; }
+$VCDIFF -stats \
+        decode -dictionary $DICTIONARY_FILE \
+               -delta $DELTA_FILE \
+               -target $OUTPUT_TARGET_FILE \
+|| { echo "Decode with -stats failed"; \
+     exit 1; }
+cmp $TARGET_FILE $OUTPUT_TARGET_FILE \
+|| { echo "Decoded target does not match original"; \
+     exit 1; }
+echo "Test 13 ok";
+
+rm $DELTA_FILE
+rm $OUTPUT_TARGET_FILE
+
+# Using /dev/null as dictionary should work, but (because dictionary is empty)
+# it will not produce a small delta file.
+$VCDIFF $VCD_OPTIONS \
+        test -dictionary /dev/null \
+             -target $TARGET_FILE \
+             -delta $DELTA_FILE \
+             -stats \
+|| { echo "vcdiff test with /dev/null as dictionary failed"; \
+     exit 1; }
+echo "Test 14 ok";
+
+rm $DELTA_FILE
+
+# Using /dev/kmem as dictionary or target should produce an error
+# (permission denied, or too large, or special file type)
+$VCDIFF $VCD_OPTIONS \
+        encode -dictionary /dev/kmem \
+               -target $TARGET_FILE \
+               -delta $DELTA_FILE \
+&& { echo "vcdiff with /dev/kmem as dictionary should fail, but succeeded"; \
+     exit 1; }
+echo "Test 15 ok";
+
+$VCDIFF $VCD_OPTIONS \
+        encode -dictionary $DICTIONARY_FILE \
+               -target /dev/kmem \
+               -delta $DELTA_FILE \
+&& { echo "vcdiff with /dev/kmem as target should fail, but succeeded"; \
+     exit 1; }
+echo "Test 16 ok";
+
+# Decode using something that isn't a delta file
+$VCDIFF decode -dictionary $DICTIONARY_FILE \
+               -delta /etc/fstab \
+               -target $OUTPUT_TARGET_FILE \
+&& { echo "vcdiff with invalid delta file should fail, but succeeded"; \
+     exit 1; }
+echo "Test 17 ok";
+
+$VCDIFF $VCD_OPTIONS \
+        encode -target $TARGET_FILE \
+               -delta $DELTA_FILE \
+               -dictionary \
+&& { echo "-dictionary option with no file name should fail, but succeeded"; \
+     exit 1; }
+echo "Test 18 ok";
+
+$VCDIFF $VCD_OPTIONS \
+        encode -dictionary $DICTIONARY_FILE \
+               -delta $DELTA_FILE \
+               -target \
+&& { echo "-target option with no file name should fail, but succeeded"; \
+     exit 1; }
+echo "Test 19 ok";
+
+$VCDIFF $VCD_OPTIONS \
+        encode -dictionary $DICTIONARY_FILE \
+               -target $TARGET_FILE \
+               -delta \
+&& { echo "-delta option with no file name should fail, but succeeded"; \
+     exit 1; }
+echo "Test 20 ok";
+
+$VCDIFF $VCD_OPTIONS \
+        encode -dictionary $DICTIONARY_FILE \
+               -target $TARGET_FILE \
+               -delta $DELTA_FILE \
+               -buffersize \
+&& { echo "-buffersize option with no argument should fail, but succeeded"; \
+     exit 1; }
+echo "Test 21 ok";
+
+# Using -buffersize=1 should still work.
+$VCDIFF $VCD_OPTIONS \
+        test -dictionary $DICTIONARY_FILE \
+             -target $TARGET_FILE \
+             -delta $DELTA_FILE \
+             -buffersize 1 \
+             -stats \
+|| { echo "vcdiff test with -buffersize=1 failed"; \
+     exit 1; }
+echo "Test 22 ok";
+
+rm $DELTA_FILE
+
+# Using -buffersize=1 with stdin/stdout means that vcdiff
+# will create a separate target window for each byte read.
+{ $VCDIFF encode -dictionary $DICTIONARY_FILE \
+                 -buffersize 1 \
+                 -stats \
+                 < $TARGET_FILE \
+                 > $DELTA_FILE; } \
+|| { echo "Encode using stdin/stdout with -buffersize=1 failed"; \
+     exit 1; }
+{ $VCDIFF decode -dictionary $DICTIONARY_FILE \
+                 -buffersize 1 \
+                 -stats \
+                 < $DELTA_FILE \
+                 > $OUTPUT_TARGET_FILE; } \
+|| { echo "Decode using stdin/stdout with -buffersize=1 failed"; \
+     exit 1; }
+cmp $TARGET_FILE $OUTPUT_TARGET_FILE \
+|| { echo "Decoded target does not match original with -buffersize=1"; \
+     exit 1; }
+echo "Test 23 ok";
+
+rm $DELTA_FILE
+rm $OUTPUT_TARGET_FILE
+
+# Using -buffersize=0 should fail.
+$VCDIFF $VCD_OPTIONS \
+        test -dictionary $DICTIONARY_FILE \
+             -target $TARGET_FILE \
+             -delta $DELTA_FILE \
+             -buffersize 0 \
+&& { echo "vcdiff test with -buffersize=0 should fail, but succeeded"; \
+     exit 1; }
+echo "Test 24 ok";
+
+rm $DELTA_FILE
+
+# Using -buffersize=128M (larger than default maximum) should still work.
+$VCDIFF $VCD_OPTIONS \
+        test -dictionary $DICTIONARY_FILE \
+             -target $TARGET_FILE \
+             -delta $DELTA_FILE \
+             -buffersize 134217728 \
+             -stats \
+|| { echo "vcdiff test with -buffersize=128M failed"; \
+     exit 1; }
+echo "Test 25 ok";
+
+rm $DELTA_FILE
+
+$VCDIFF $VCD_OPTIONS \
+        test -dictionary $DICTIONARY_FILE \
+             -target $TARGET_FILE \
+             -delta $DELTA_FILE \
+             -froobish \
+&& { echo "vdiff test with unrecognized option should fail, but succeeded"; \
+     exit 1; }
+echo "Test 26 ok";
+
+$VCDIFF $VCD_OPTIONS \
+        encode -target $TARGET_FILE \
+               -delta $DELTA_FILE \
+&& { echo "encode with no dictionary option should fail, but succeeded"; \
+     exit 1; }
+echo "Test 27 ok";
+
+$VCDIFF decode -target $TARGET_FILE \
+               -delta $DELTA_FILE \
+&& { echo "decode with no dictionary option should fail, but succeeded"; \
+     exit 1; }
+echo "Test 28 ok";
+
+# Remove -interleaved and -checksum options
+{ $VCDIFF encode -dictionary $DICTIONARY_FILE \
+                 < $TARGET_FILE \
+                 > $DELTA_FILE; } \
+|| { echo "Encode without -interleaved and -checksum options failed"; \
+     exit 1; }
+{ $VCDIFF decode -dictionary $DICTIONARY_FILE \
+                 < $DELTA_FILE \
+                 > $OUTPUT_TARGET_FILE; } \
+|| { echo "Decode non-interleaved output failed"; \
+     exit 1; }
+cmp $TARGET_FILE $OUTPUT_TARGET_FILE \
+|| { echo "Decoded target does not match original with -interleaved"; \
+     exit 1; }
+echo "Test 29 ok";
+
+# -target_matches option
+{ $VCDIFF encode -dictionary $DICTIONARY_FILE \
+                 -target_matches \
+                 -stats \
+                 < $TARGET_FILE \
+                 > $DELTA_FILE; } \
+|| { echo "Encode with -target_matches option failed"; \
+     exit 1; }
+# The decode operation ignores the -target_matches option.
+{ $VCDIFF decode -dictionary $DICTIONARY_FILE \
+                 < $DELTA_FILE \
+                 > $OUTPUT_TARGET_FILE; } \
+|| { echo "Decode output failed with -target_matches"; \
+     exit 1; }
+cmp $TARGET_FILE $OUTPUT_TARGET_FILE \
+|| { echo "Decoded target does not match original with -target_matches"; \
+     exit 1; }
+echo "Test 30 ok";
+
+rm $DELTA_FILE
+rm $OUTPUT_TARGET_FILE
+
+$VCDIFF $VCD_OPTIONS \
+        dencode -dictionary $DICTIONARY_FILE \
+                -target $TARGET_FILE \
+                -delta $DELTA_FILE \
+&& { echo "vdiff with unrecognized action should fail, but succeeded"; \
+     exit 1; }
+echo "Test 31 ok";
+
+$VCDIFF $VCD_OPTIONS \
+        test -dictionary $DICTIONARY_FILE \
+             -target $TARGET_FILE \
+&& { echo "vdiff test without delta option should fail, but succeeded"; \
+     exit 1; }
+echo "Test 32 ok";
+
+$VCDIFF $VCD_OPTIONS \
+        test -dictionary $DICTIONARY_FILE \
+             -delta $DELTA_FILE \
+&& { echo "vdiff test without target option should fail, but succeeded"; \
+     exit 1; }
+echo "Test 33 ok";
+
+# open-vcdiff bug 8 (http://code.google.com/p/open-vcdiff/issues/detail?id=8)
+# A malicious encoding that tries to produce a 4GB target file made up of 64
+# windows, each window having a size of 64MB.
+# Start by limiting memory usage to 96MB per process, so the test doesn't take
+# forever to run out of memory.
+ulimit -d 98304
+ulimit -m 98304
+$VCDIFF $VCD_OPTIONS \
+    decode -dictionary $DICTIONARY_FILE \
+           -delta $MALICIOUS_ENCODING \
+           -target /dev/null \
+           -max_target_file_size=65536 \
+&& { echo "Decoding malicious file should fail, but succeeded"; \
+     exit 1; }
+echo "Test 34 ok";
+
+$VCDIFF $VCD_OPTIONS \
+    decode -dictionary $DICTIONARY_FILE \
+           -delta $MALICIOUS_ENCODING \
+           -target /dev/null \
+           -max_target_window_size=65536 \
+&& { echo "Decoding malicious file should fail, but succeeded"; \
+     exit 1; }
+echo "Test 35 ok";
+
+# Decoding a small target with the -max_target_file_size option should succeed.
+$VCDIFF $VCD_OPTIONS \
+        test -dictionary $DICTIONARY_FILE \
+             -target $TARGET_FILE \
+             -delta $DELTA_FILE \
+             -max_target_file_size=65536 \
+|| { echo "vcdiff test with -max_target_file_size failed"; \
+     exit 1; }
+echo "Test 36 ok";
+
+# Decoding a small target with -max_target_window_size option should succeed.
+$VCDIFF $VCD_OPTIONS \
+        test -dictionary $DICTIONARY_FILE \
+             -target $TARGET_FILE \
+             -delta $DELTA_FILE \
+             -max_target_window_size=65536 \
+|| { echo "vcdiff test with -max_target_window_size failed"; \
+     exit 1; }
+echo "Test 37 ok";
+
+rm $DELTA_FILE
+
+echo "PASS"
diff --git a/src/vcdiffengine.h b/src/vcdiffengine.h
index 96ca334..0038e35 100644
--- a/src/vcdiffengine.h
+++ b/src/vcdiffengine.h
@@ -17,8 +17,8 @@
 #define OPEN_VCDIFF_VCDIFFENGINE_H_
 
 #include <config.h>
+#include <stddef.h>  // size_t
 #include <stdint.h>  // uint32_t
-#include <cstddef>  // size_t
 
 namespace open_vcdiff {
 
diff --git a/src/vcdiffengine_test.cc b/src/vcdiffengine_test.cc
index a115adc..cef43bf 100644
--- a/src/vcdiffengine_test.cc
+++ b/src/vcdiffengine_test.cc
@@ -15,6 +15,7 @@
 
 #include <config.h>
 #include "vcdiffengine.h"
+#include <string.h>  // memset, strlen
 #include <algorithm>
 #include <string>
 #include <vector>
@@ -31,10 +32,12 @@
 
 namespace {
 
-using std::string;
-
 class VCDiffEngineTestBase : public testing::Test {
  protected:
+#ifndef VCDIFF_HAS_GLOBAL_STRING
+  typedef std::string string;
+#endif  // !VCDIFF_HAS_GLOBAL_STRING
+
   // Some common definitions and helper functions used in the various tests
   // for VCDiffEngine.
   static const int kBlockSize = BlockHash::kBlockSize;
diff --git a/src/vcencoder_test.cc b/src/vcencoder_test.cc
index 500e799..782cb13 100644
--- a/src/vcencoder_test.cc
+++ b/src/vcencoder_test.cc
@@ -15,9 +15,9 @@
 
 #include <config.h>
 #include "google/vcencoder.h"
+#include <stdlib.h>  // free, posix_memalign
+#include <string.h>  // memcpy
 #include <algorithm>
-#include <cstdlib>  // free, posix_memalign
-#include <cstring>  // memcpy
 #include <string>
 #include <vector>
 #include "blockhash.h"
@@ -51,8 +51,6 @@
 namespace open_vcdiff {
 namespace {
 
-using std::string;
-
 static const size_t kFileHeaderSize = sizeof(DeltaFileHeader);
 
 // This is to check the maximum possible encoding size
@@ -68,6 +66,10 @@
 
 class VerifyEncodedBytesTest : public testing::Test {
  public:
+#ifndef VCDIFF_HAS_GLOBAL_STRING
+  typedef std::string string;
+#endif  // !VCDIFF_HAS_GLOBAL_STRING
+
   VerifyEncodedBytesTest() : delta_index_(0) { }
   virtual ~VerifyEncodedBytesTest() { }
 
diff --git a/testdata/allocates_4gb.vcdiff b/testdata/allocates_4gb.vcdiff
new file mode 100644
index 0000000..48414b9
--- /dev/null
+++ b/testdata/allocates_4gb.vcdiff
Binary files differ
diff --git a/testdata/configure.ac.v0.1 b/testdata/configure.ac.v0.1
new file mode 100644
index 0000000..43f5291
--- /dev/null
+++ b/testdata/configure.ac.v0.1
@@ -0,0 +1,57 @@
+## Process this file with autoconf to produce configure.
+## In general, the safest way to proceed is to run ./autogen.sh
+
+# make sure we're interpreted by some minimal autoconf
+AC_PREREQ(2.57)
+
+AC_INIT(open-vcdiff, 0.1, opensource@google.com)
+AC_CONFIG_SRCDIR(README)
+AM_INIT_AUTOMAKE
+AM_CONFIG_HEADER(src/config.h)
+
+# Checks for programs.
+AC_PROG_CC
+AC_PROG_CPP
+AC_PROG_CXX
+AM_CONDITIONAL(GCC, test "$GCC" = yes)   # let the Makefile know if we're gcc
+AC_CANONICAL_HOST
+
+AC_PROG_LIBTOOL
+AC_SUBST(LIBTOOL_DEPS)
+
+# Check whether some low-level functions/files are available
+AC_HEADER_STDC
+
+case $host in
+  *86*-*-gnu*) AC_DEFINE(VCDIFF_USE_BLOCK_COMPARE_WORDS, 1,
+			 Use custom compare function instead of memcmp)
+esac
+
+AC_CHECK_HEADERS([ext/rope])
+AC_CHECK_HEADERS([getopt.h])
+AC_CHECK_HEADERS([malloc.h])
+AC_CHECK_HEADERS([sys/mman.h])
+AC_CHECK_HEADERS([sys/time.h])
+AC_CHECK_HEADERS([unistd.h])
+AC_CHECK_HEADERS([windows.h])
+AC_CHECK_FUNCS([gettimeofday QueryPerformanceCounter])
+AC_CHECK_FUNCS([memalign posix_memalign])
+AC_CHECK_FUNCS([mprotect])
+
+# Start of definitions needed by gflags package
+
+AC_CHECK_HEADERS([stdint.h sys/types.h inttypes.h])
+AC_CHECK_HEADERS([fnmatch.h])
+AC_CHECK_FUNCS([InitializeCriticalSection])
+AC_CHECK_FUNCS([InterlockedCompareExchange])
+AC_CHECK_FUNCS([strtoll strtoq])
+AC_CHECK_TYPES([uint16_t, u_int16_t, __int16])
+
+AX_C___ATTRIBUTE__
+
+ACX_PTHREAD
+
+# End of definitions needed by gflags package
+
+AC_CONFIG_FILES([Makefile])
+AC_OUTPUT
diff --git a/testdata/configure.ac.v0.2 b/testdata/configure.ac.v0.2
new file mode 100644
index 0000000..8872538
--- /dev/null
+++ b/testdata/configure.ac.v0.2
@@ -0,0 +1,55 @@
+## Process this file with autoconf to produce configure.
+## In general, the safest way to proceed is to run ./autogen.sh
+
+# make sure we're interpreted by some minimal autoconf
+AC_PREREQ(2.57)
+
+AC_INIT(open-vcdiff, 0.2, opensource@google.com)
+AC_CONFIG_SRCDIR(README)
+AM_INIT_AUTOMAKE
+AM_CONFIG_HEADER(src/config.h)
+
+# Checks for programs.
+AC_PROG_CC
+AC_PROG_CPP
+AC_PROG_CXX
+AM_CONDITIONAL(GCC, test "$GCC" = yes)   # let the Makefile know if we're gcc
+AC_CANONICAL_HOST
+
+AC_PROG_LIBTOOL
+AC_SUBST(LIBTOOL_DEPS)
+
+# Check whether some low-level functions/files are available
+AC_HEADER_STDC
+
+case $host in
+  *86*-*-*bsd* | *86*-*-gnu*)
+    AC_DEFINE(VCDIFF_USE_BLOCK_COMPARE_WORDS, 1,
+              Use custom compare function instead of memcmp)
+    ;;
+esac
+
+AC_CHECK_HEADERS([ext/rope])
+AC_CHECK_HEADERS([getopt.h])
+AC_CHECK_HEADERS([malloc.h])
+AC_CHECK_HEADERS([sys/mman.h])
+AC_CHECK_HEADERS([sys/time.h])
+AC_CHECK_HEADERS([unistd.h])
+AC_CHECK_HEADERS([windows.h])
+AC_CHECK_FUNCS([gettimeofday QueryPerformanceCounter])
+AC_CHECK_FUNCS([memalign posix_memalign])
+AC_CHECK_FUNCS([mprotect])
+
+# Start of definitions needed by gflags package
+
+AC_CHECK_HEADERS([stdint.h sys/types.h inttypes.h])
+AC_CHECK_HEADERS([fnmatch.h])
+AC_CHECK_FUNCS([strtoll strtoq])
+AC_CHECK_TYPES([uint16_t, u_int16_t, __int16])
+
+AX_C___ATTRIBUTE__
+
+# End of definitions needed by gflags package
+
+AC_CONFIG_FILES([Makefile])
+AC_OUTPUT
diff --git a/vsprojects/config.h b/vsprojects/config.h
index 4062437..dbdb139 100644
--- a/vsprojects/config.h
+++ b/vsprojects/config.h
@@ -45,19 +45,19 @@
 #define PACKAGE_NAME "open-vcdiff"
 
 /* Define to the full name and version of this package. */
-#define PACKAGE_STRING "open-vcdiff 0.2"
+#define PACKAGE_STRING "open-vcdiff 0.3"
 
 /* Define to the one symbol short name of this package. */
 #define PACKAGE_TARNAME "open-vcdiff"
 
 /* Define to the version of this package. */
-#define PACKAGE_VERSION "0.2"
+#define PACKAGE_VERSION "0.3"
 
 /* Define to 1 if you have the ANSI C header files. */
 #define STDC_HEADERS 1
 
 /* Version number of package */
-#define VERSION "0.2"
+#define VERSION "0.3"
 
 // These functions have different names, but the same behavior,
 // for Visual Studio.
diff --git a/vsprojects/vcdecoder_test/vcdecoder_test.vcproj b/vsprojects/vcdecoder_test/vcdecoder_test.vcproj
index 1e32fe6..5f496b4 100644
--- a/vsprojects/vcdecoder_test/vcdecoder_test.vcproj
+++ b/vsprojects/vcdecoder_test/vcdecoder_test.vcproj
@@ -191,19 +191,19 @@
 				>
 			</File>
 			<File
-				RelativePath="..\..\src\vcdecoder_test1.cc"
+				RelativePath="..\..\src\vcdecoder1_test.cc"
 				>
 			</File>
 			<File
-				RelativePath="..\..\src\vcdecoder_test2.cc"
+				RelativePath="..\..\src\vcdecoder2_test.cc"
 				>
 			</File>
 			<File
-				RelativePath="..\..\src\vcdecoder_test3.cc"
+				RelativePath="..\..\src\vcdecoder3_test.cc"
 				>
 			</File>
 			<File
-				RelativePath="..\..\src\vcdecoder_test4.cc"
+				RelativePath="..\..\src\vcdecoder4_test.cc"
 				>
 			</File>
 		</Filter>