debian: New upstream release

I tried to package this in your source repo but didn't figure out how to
handle the clashes (i.e. how to drop patches except to revert the
initial commit). So the repo above is git-dpm for now.

I kept
	liblzma-make-dlopen-based-liblzma2-compatibility-opt.patch
	liblzma-skip-ABI-incompatible-check-when-liblzma.so.patch
but I think that we shouldn't worry about liblzma2 since it is long
gone. Anyway, it is there. The current changelog:

| * switch to git-dpm for packaging (closes: #540405)
| * New Upstream (closes: #731634)
|  - no more "xzless error in line 49" (closes: #693537)
|  - xzgrep -h works (closes: #780268)
| * update symbol file

I built pixz against it and the internal testsuite passed. I checked out
all pristine-tar files from clamav (in the xz format) and the checkout
worked.

[jrnieder@gmail.com: imported from uploaded NMU]
diff --git a/.gitignore b/.gitignore
index 1217ea8..3220269 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,6 +1,7 @@
 *~
 *.bak
 *.bak[0-9]
+.gdb_history
 
 .deps
 .libs
@@ -29,6 +30,7 @@
 build-aux/install-sh
 build-aux/ltmain.sh
 build-aux/missing
+build-aux/test-driver
 
 /src/liblzma/liblzma.pc
 /src/lzmainfo/lzmainfo
diff --git a/INSTALL b/INSTALL
index 8b39319..22ef077 100644
--- a/INSTALL
+++ b/INSTALL
@@ -26,6 +26,8 @@
        4.2. "No POSIX conforming shell (sh) was found."
        4.3. configure works but build fails at crc32_x86.S
        4.4. Lots of warnings about symbol visibility
+       4.5. "make check" fails
+       4.6. liblzma.so (or similar) not found when running xz
 
 
 0. Preface
@@ -120,6 +122,10 @@
     This can be worked around by passing gl_cv_cc_visibility=no
     as an argument to the configure script.
 
+    test_scripts.sh in "make check" may fail if good enough tools are
+    missing from PATH (/usr/xpg4/bin or /usr/xpg6/bin). See sections
+    4.5 and 3.2 for more information.
+
 
 1.2.6. Tru64
 
@@ -130,21 +136,33 @@
 
 1.2.7. Windows
 
-    Building XZ Utils on Windows is supported under MinGW + MSYS,
-    MinGW-w64 + MSYS, and Cygwin. There is windows/build.bash to
-    ease packaging XZ Utils with MinGW(-w64) + MSYS into a
-    redistributable .zip or .7z file. See windows/INSTALL-Windows.txt
-    for more information.
+    Building XZ Utils on Windows is supported under the following
+    environments:
 
-    It might be possible to build liblzma with a non-GNU toolchain too,
-    but that will probably require writing a separate makefile. Building
+      - MinGW-w64 + MSYS (32-bit and 64-bit x86): This is used
+        for building the official binary packages for Windows.
+        There is windows/build.bash to ease packaging XZ Utils with
+        MinGW(-w64) + MSYS into a redistributable .zip or .7z file.
+        See windows/INSTALL-MinGW.txt for more information.
+
+      - MinGW + MSYS (32-bit x86): I haven't recently tested this.
+
+      - Cygwin 1.7.35 and later: NOTE that using XZ Utils >= 5.2.0
+        under Cygwin older than 1.7.35 can lead to DATA LOSS! If
+        you must use an old Cygwin version, stick to XZ Utils 5.0.x
+        which is safe under older Cygwin versions. You can check
+        the Cygwin version with the command "cygcheck -V".
+
+      - Microsoft Visual Studio 2013 update 2 or later (MSVC for short):
+        See windows/INSTALL-MSVC.txt for more information.
+
+    It may be possible to build liblzma with other toolchains too, but
+    that will probably require writing a separate makefile. Building
     the command line tools with non-GNU toolchains will be harder than
     building only liblzma.
 
-    Even if liblzma is built with MinGW, the resulting DLL or static
-    library can be used by other compilers and linkers, including MSVC.
-    Thus, it shouldn't be a problem to use MinGW to build liblzma even
-    if you cannot use MinGW to build the rest of your project. See
+    Even if liblzma is built with MinGW(-w64), the resulting DLL can
+    be used by other compilers and linkers, including MSVC. See
     windows/README-Windows.txt for details.
 
 
@@ -251,6 +269,12 @@
                 Don't install the scripts xzdiff, xzgrep, xzmore, xzless,
                 and their symlinks.
 
+    --disable-doc
+                Don't install the documentation files to $docdir
+                (often /usr/doc/xz or /usr/local/doc/xz). Man pages
+                will still be installed. The $docdir can be changed
+                with --docdir=DIR.
+
     --disable-assembler
                 liblzma includes some assembler optimizations. Currently
                 there is only assembler code for CRC32 and CRC64 for
@@ -307,16 +331,42 @@
                 the amount of RAM on the operating system you use. See
                 src/common/tuklib_physmem.c for details.
 
-    --disable-threads
-                Disable threading support. This makes some things
-                thread-unsafe, meaning that if multithreaded application
-                calls liblzma functions from more than one thread,
-                something bad may happen.
+    --enable-threads=METHOD
+                Threading support is enabled by default so normally there
+                is no need to specify this option.
 
-                Use this option if threading support causes you trouble,
-                or if you know that you will use liblzma only from
-                single-threaded applications and want to avoid dependency
-                on libpthread.
+                Supported values for METHOD:
+
+                        yes     Autodetect the threading method. If none
+                                is found, configure will give an error.
+
+                        posix   Use POSIX pthreads. This is the default
+                                except on Windows outside Cygwin.
+
+                        win95   Use Windows 95 compatible threads. This
+                                is compatible with Windows XP and later
+                                too. This is the default for 32-bit x86
+                                Windows builds. The `win95' threading is
+                                incompatible with --enable-small.
+
+                        vista   Use Windows Vista compatible threads. The
+                                resulting binaries won't run on Windows XP
+                                or older. This is the default for Windows
+                                excluding 32-bit x86 builds (that is, on
+                                x86-64 the default is `vista').
+
+                        no      Disable threading support. This is the
+                                same as using --disable-threads.
+                                NOTE: If combined with --enable-small, the
+                                resulting liblzma won't be thread safe,
+                                that is, if a multi-threaded application
+                                calls any liblzma functions from more than
+                                one thread, something bad may happen.
+
+    --enable-symbol-versions
+                Use symbol versioning for liblzma. This is enabled by
+                default on GNU/Linux, other GNU-based systems, and
+                FreeBSD.
 
     --enable-debug
                 This enables the assert() macro and possibly some other
@@ -387,11 +437,16 @@
     gl_cv_posix_shell=/path/to/posix-sh as an argument to the configure
     script.
 
-    Some of the scripts require also mktemp. The original mktemp can be
-    found from <http://www.mktemp.org/>. On GNU, most will use the mktemp
-    program from GNU coreutils instead of the original implementation.
-    Both mktemp versions are fine for XZ Utils (and practically for
-    everything else too).
+    xzdiff (xzcmp/lzdiff/lzcmp) may use mktemp if it is available. As
+    a fallback xzdiff will use mkdir to securely create a temporary
+    directory. Having mktemp available is still recommended since the
+    mkdir fallback method isn't as robust as mktemp is. The original
+    mktemp can be found from <http://www.mktemp.org/>. On GNU, most will
+    use the mktemp program from GNU coreutils instead of the original
+    implementation. Both mktemp versions are fine.
+
+    In addition to using xz to decompress .xz files, xzgrep and xzdiff
+    use gzip, bzip2, and lzop to support .gz, bz2, and .lzo files.
 
 
 3.2. PATH
@@ -432,7 +487,8 @@
     to POSIX. The configure script tries to find such a shell. If
     it fails, you can force the shell to be used by passing
     gl_cv_posix_shell=/path/to/posix-sh as an argument to the configure
-    script.
+    script. Alternatively you can omit the installation of scripts and
+    this error by passing --disable-scripts to configure.
 
 
 4.3. configure works but build fails at crc32_x86.S
@@ -463,3 +519,36 @@
     resulting binaries, but fewer warnings looks nicer and may allow
     using --enable-werror.
 
+
+4.5. "make check" fails
+
+    If the other tests pass but test_scripts.sh fails, then the problem
+    is in the scripts in src/scripts. Comparing the contents of
+    tests/xzgrep_test_output to tests/xzgrep_expected_output might
+    give a good idea about problems in xzgrep. One possibility is that
+    some tools are missing from the current PATH or the tools lack
+    support for some POSIX features. This can happen at least on
+    Solaris where the tools in /bin may be ancient but good enough
+    tools are available in /usr/xpg4/bin or /usr/xpg6/bin. One fix
+    for this problem is described in section 3.2 of this file.
+
+    If tests other than test_scripts.sh fail, a likely reason is that
+    libtool links the test programs against an installed version of
+    liblzma instead of the version that was just built. This is
+    obviously a bug which seems to happen on some platforms.
+    A workaround is to uninstall the old liblzma versions first.
+
+    If the problem isn't any of those described above, then it's likely
+    a bug in XZ Utils or in the compiler. See the platform-specific
+    notes in this file for possible known problems. Please report
+    a bug if you cannot solve the problem. See README for contact
+    information.
+
+
+4.6. liblzma.so (or similar) not found when running xz
+
+    If you installed the package with "make install" and get an error
+    about liblzma.so (or a similarly named file) being missing, try
+    running "ldconfig" to update the run-time linker cache (if your
+    operating system has such a command).
+
diff --git a/Makefile.am b/Makefile.am
index 8963586..1053697 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -17,6 +17,7 @@
 
 SUBDIRS += src po tests
 
+if COND_DOC
 dist_doc_DATA = \
 	AUTHORS \
 	COPYING \
@@ -36,17 +37,20 @@
 	doc/examples/01_compress_easy.c \
 	doc/examples/02_decompress.c \
 	doc/examples/03_compress_custom.c \
+	doc/examples/04_compress_easy_mt.c \
 	doc/examples/Makefile
 
 examplesolddir = $(docdir)/examples_old
 dist_examplesold_DATA = \
 	doc/examples_old/xz_pipe_comp.c \
 	doc/examples_old/xz_pipe_decomp.c
+endif
 
 EXTRA_DIST = \
 	extra \
 	dos \
 	windows \
+	macosx \
 	autogen.sh \
 	Doxyfile.in \
 	COPYING.GPLv2 \
diff --git a/NEWS b/NEWS
index 2986b51..24166e4 100644
--- a/NEWS
+++ b/NEWS
@@ -2,6 +2,223 @@
 XZ Utils Release Notes
 ======================
 
+5.2.2 (2015-09-29)
+
+    * Fixed bugs in QNX-specific code.
+
+    * Omitted the use of pipe2() even if it is available to avoid
+      portability issues with some old Linux and glibc combinations.
+
+    * Updated German translation.
+
+    * Added project files to build static and shared liblzma (not the
+      whole XZ Utils) with Visual Studio 2013 update 2 or later.
+
+    * Documented that threaded decompression hasn't been implemented
+      yet. A 5.2.0 NEWS entry describing multi-threading support had
+      incorrectly said "decompression" when it should have said
+      "compression".
+
+
+5.2.1 (2015-02-26)
+
+    * Fixed a compression-ratio regression in fast mode of LZMA1 and
+      LZMA2. The bug is present in 5.1.4beta and 5.2.0 releases.
+
+    * Fixed a portability problem in xz that affected at least OpenBSD.
+
+    * Fixed xzdiff to be compatible with FreeBSD's mktemp which differs
+      from most other mktemp implementations.
+
+    * Changed CPU core count detection to use cpuset_getaffinity() on
+      FreeBSD.
+
+
+5.2.0 (2014-12-21)
+
+    Since 5.1.4beta:
+
+    * All fixes from 5.0.8
+
+    * liblzma: Fixed lzma_stream_encoder_mt_memusage() when a preset
+      was used.
+
+    * xzdiff: If mktemp isn't installed, mkdir will be used as
+      a fallback to create a temporary directory. Installing mktemp
+      is still recommended.
+
+    * Updated French, German, Italian, Polish, and Vietnamese
+      translations.
+
+    Summary of fixes and new features added in the 5.1.x development
+    releases:
+
+    * liblzma:
+
+        - Added support for multi-threaded compression. See the
+          lzma_mt structure, lzma_stream_encoder_mt(), and
+          lzma_stream_encoder_mt_memusage() in <lzma/container.h>,
+          lzma_get_progress() in <lzma/base.h>, and lzma_cputhreads()
+          in <lzma/hardware.h> for details.
+
+        - Made the uses of lzma_allocator const correct.
+
+        - Added lzma_block_uncomp_encode() to create uncompressed
+          .xz Blocks using LZMA2 uncompressed chunks.
+
+        - Added support for LZMA_IGNORE_CHECK.
+
+        - A few speed optimizations were made.
+
+        - Added support for symbol versioning. It is enabled by default
+          on GNU/Linux, other GNU-based systems, and FreeBSD.
+
+        - liblzma (not the whole XZ Utils) should now be buildable
+          with MSVC 2013 update 2 or later using windows/config.h.
+
+    * xz:
+
+        - Fixed a race condition in the signal handling. It was
+          possible that e.g. the first SIGINT didn't make xz exit
+          if reading or writing blocked and one had bad luck. The fix
+          is non-trivial, so as of writing it is unknown if it will be
+          backported to the v5.0 branch.
+
+        - Multi-threaded compression can be enabled with the
+          --threads (-T) option.
+          [Fixed: This originally said "decompression".]
+
+        - New command line options in xz: --single-stream,
+          --block-size=SIZE, --block-list=SIZES,
+          --flush-timeout=TIMEOUT, and --ignore-check.
+
+        - xz -lvv now shows the minimum xz version that is required to
+          decompress the file. Currently it is 5.0.0 for all supported
+          .xz files except files with empty LZMA2 streams require 5.0.2.
+
+    * xzdiff and xzgrep now support .lzo files if lzop is installed.
+      The .tzo suffix is also recognized as a shorthand for .tar.lzo.
+
+
+5.1.4beta (2014-09-14)
+
+    * All fixes from 5.0.6
+
+    * liblzma: Fixed the use of presets in threaded encoder
+      initialization.
+
+    * xz --block-list and --block-size can now be used together
+      in single-threaded mode. Previously the combination only
+      worked in multi-threaded mode.
+
+    * Added support for LZMA_IGNORE_CHECK to liblzma and made it
+      available in xz as --ignore-check.
+
+    * liblzma speed optimizations:
+
+        - Initialization of a new LZMA1 or LZMA2 encoder has been
+          optimized. (The speed of reinitializing an already-allocated
+          encoder isn't affected.) This helps when compressing many
+          small buffers with lzma_stream_buffer_encode() and other
+          similar situations where an already-allocated encoder state
+          isn't reused. This speed-up is visible in xz too if one
+          compresses many small files one at a time instead running xz
+          once and giving all files as command-line arguments.
+
+        - Buffer comparisons are now much faster when unaligned access
+          is allowed (configured with --enable-unaligned-access). This
+          speeds up encoding significantly. There is arch-specific code
+          for 32-bit and 64-bit x86 (32-bit needs SSE2 for the best
+          results and there's no run-time CPU detection for now).
+          For other archs there is only generic code which probably
+          isn't as optimal as arch-specific solutions could be.
+
+        - A few speed optimizations were made to the SHA-256 code.
+          (Note that the builtin SHA-256 code isn't used on all
+          operating systems.)
+
+    * liblzma can now be built with MSVC 2013 update 2 or later
+      using windows/config.h.
+
+    * Vietnamese translation was added.
+
+
+5.1.3alpha (2013-10-26)
+
+    * All fixes from 5.0.5
+
+    * liblzma:
+
+        - Fixed a deadlock in the threaded encoder.
+
+        - Made the uses of lzma_allocator const correct.
+
+        - Added lzma_block_uncomp_encode() to create uncompressed
+          .xz Blocks using LZMA2 uncompressed chunks.
+
+        - Added support for native threads on Windows and the ability
+          to detect the number of CPU cores.
+
+    * xz:
+
+        - Fixed a race condition in the signal handling. It was
+          possible that e.g. the first SIGINT didn't make xz exit
+          if reading or writing blocked and one had bad luck. The fix
+          is non-trivial, so as of writing it is unknown if it will be
+          backported to the v5.0 branch.
+
+        - Made the progress indicator work correctly in threaded mode.
+
+        - Threaded encoder now works together with --block-list=SIZES.
+
+        - Added preliminary support for --flush-timeout=TIMEOUT.
+          It can be useful for (somewhat) real-time streaming. For
+          now the decompression side has to be done with something
+          else than the xz tool due to how xz does buffering, but this
+          should be fixed.
+
+
+5.1.2alpha (2012-07-04)
+
+    * All fixes from 5.0.3 and 5.0.4
+
+    * liblzma:
+
+        - Fixed a deadlock and an invalid free() in the threaded encoder.
+
+        - Added support for symbol versioning. It is enabled by default
+          on GNU/Linux, other GNU-based systems, and FreeBSD.
+
+        - Use SHA-256 implementation from the operating system if one is
+          available in libc, libmd, or libutil. liblzma won't use e.g.
+          OpenSSL or libgcrypt to avoid introducing new dependencies.
+
+        - Fixed liblzma.pc for static linking.
+
+        - Fixed a few portability bugs.
+
+    * xz --decompress --single-stream now fixes the input position after
+      successful decompression. Now the following works:
+
+          echo foo | xz > foo.xz
+          echo bar | xz >> foo.xz
+          ( xz -dc --single-stream ; xz -dc --single-stream ) < foo.xz
+
+      Note that it doesn't work if the input is not seekable
+      or if there is Stream Padding between the concatenated
+      .xz Streams.
+
+    * xz -lvv now shows the minimum xz version that is required to
+      decompress the file. Currently it is 5.0.0 for all supported .xz
+      files except files with empty LZMA2 streams require 5.0.2.
+
+    * Added an *incomplete* implementation of --block-list=SIZES to xz.
+      It only works correctly in single-threaded mode and when
+      --block-size isn't used at the same time. --block-list allows
+      specifying the sizes of Blocks which can be useful e.g. when
+      creating files for random-access reading.
+
+
 5.1.1alpha (2011-04-12)
 
     * All fixes from 5.0.2
@@ -45,6 +262,125 @@
       experimental and may change before it gets into a stable release.
 
 
+5.0.8 (2014-12-21)
+
+    * Fixed an old bug in xzgrep that affected OpenBSD and probably
+      a few other operating systems too.
+
+    * Updated French and German translations.
+
+    * Added support for detecting the amount of RAM on AmigaOS/AROS.
+
+    * Minor build system updates.
+
+
+5.0.7 (2014-09-20)
+
+    * Fix regressions introduced in 5.0.6:
+
+        - Fix building with non-GNU make.
+
+        - Fix invalid Libs.private value in liblzma.pc which broke
+          static linking against liblzma if the linker flags were
+          taken from pkg-config.
+
+
+5.0.6 (2014-09-14)
+
+    * xzgrep now exits with status 0 if at least one file matched.
+
+    * A few minor portability and build system fixes
+
+
+5.0.5 (2013-06-30)
+
+    * lzmadec and liblzma's lzma_alone_decoder(): Support decompressing
+      .lzma files that have less common settings in the headers
+      (dictionary size other than 2^n or 2^n + 2^(n-1), or uncompressed
+      size greater than 256 GiB). The limitations existed to avoid false
+      positives when detecting .lzma files. The lc + lp <= 4 limitation
+      still remains since liblzma's LZMA decoder has that limitation.
+
+      NOTE: xz's .lzma support or liblzma's lzma_auto_decoder() are NOT
+      affected by this change. They still consider uncommon .lzma headers
+      as not being in the .lzma format. Changing this would give way too
+      many false positives.
+
+    * xz:
+
+        - Interaction of preset and custom filter chain options was
+          made less illogical. This affects only certain less typical
+          uses cases so few people are expected to notice this change.
+
+          Now when a custom filter chain option (e.g. --lzma2) is
+          specified, all preset options (-0 ... -9, -e) earlier are on
+          the command line are completely forgotten. Similarly, when
+          a preset option is specified, all custom filter chain options
+          earlier on the command line are completely forgotten.
+
+          Example 1: "xz -9 --lzma2=preset=5 -e" is equivalent to "xz -e"
+          which is equivalent to "xz -6e". Earlier -e didn't put xz back
+          into preset mode and thus the example command was equivalent
+          to "xz --lzma2=preset=5".
+
+          Example 2: "xz -9e --lzma2=preset=5 -7" is equivalent to
+          "xz -7". Earlier a custom filter chain option didn't make
+          xz forget the -e option so the example was equivalent to
+          "xz -7e".
+
+        - Fixes and improvements to error handling.
+
+        - Various fixes to the man page.
+
+    * xzless: Fixed to work with "less" versions 448 and later.
+
+    * xzgrep: Made -h an alias for --no-filename.
+
+    * Include the previously missing debug/translation.bash which can
+      be useful for translators.
+
+    * Include a build script for Mac OS X. This has been in the Git
+      repository since 2010 but due to a mistake in Makefile.am the
+      script hasn't been included in a release tarball before.
+
+
+5.0.4 (2012-06-22)
+
+    * liblzma:
+
+        - Fix lzma_index_init(). It could crash if memory allocation
+          failed.
+
+        - Fix the possibility of an incorrect LZMA_BUF_ERROR when a BCJ
+          filter is used and the application only provides exactly as
+          much output space as is the uncompressed size of the file.
+
+        - Fix a bug in doc/examples_old/xz_pipe_decompress.c. It didn't
+          check if the last call to lzma_code() really returned
+          LZMA_STREAM_END, which made the program think that truncated
+          files are valid.
+
+        - New example programs in doc/examples (old programs are now in
+          doc/examples_old). These have more comments and more detailed
+          error handling.
+
+    * Fix "xz -lvv foo.xz". It could crash on some corrupted files.
+
+    * Fix output of "xz --robot -lv" and "xz --robot -lvv" which
+      incorrectly printed the filename also in the "foo (x/x)" format.
+
+    * Fix exit status of "xzdiff foo.xz bar.xz".
+
+    * Fix exit status of "xzgrep foo binary_file".
+
+    * Fix portability to EBCDIC systems.
+
+    * Fix a configure issue on AIX with the XL C compiler. See INSTALL
+      for details.
+
+    * Update French, German, Italian, and Polish translations.
+
+
 5.0.3 (2011-05-21)
 
     * liblzma fixes:
diff --git a/README b/README
index 1b02f05..ab8aadf 100644
--- a/README
+++ b/README
@@ -210,8 +210,8 @@
         # <Edit the .po file in the po directory.>
         make -C po update-po
         make install
-        bash debug/translations.bash | less
-        bash debug/translations.bash | less -S  # For --list outputs
+        bash debug/translation.bash | less
+        bash debug/translation.bash | less -S  # For --list outputs
 
     Repeat the above as needed (no need to re-run configure though).
 
diff --git a/THANKS b/THANKS
index 7b36e72..d9c62d4 100644
--- a/THANKS
+++ b/THANKS
@@ -6,6 +6,7 @@
 has been important. :-) In alphabetical order:
   - Mark Adler
   - H. Peter Anvin
+  - Jeff Bastian
   - Nelson H. F. Beebe
   - Karl Berry
   - Anders F. Björklund
@@ -19,6 +20,8 @@
   - Daniel Mealha Cabrita
   - Milo Casagrande
   - Marek Černocký
+  - Tomer Chachamu
+  - Gabi Davar
   - Chris Donawa
   - Andrew Dudman
   - Markus Duft
@@ -27,19 +30,28 @@
   - Gilles Espinasse
   - Denis Excoffier
   - Michael Felt
+  - Michael Fox
   - Mike Frysinger
+  - Daniel Richard G.
   - Bill Glessner
   - Jason Gorski
   - Juan Manuel Guerrero
+  - Diederik de Haas
   - Joachim Henke
+  - Christian Hesse
+  - Vincenzo Innocente
   - Peter Ivanov
   - Jouk Jansen
+  - Jun I Jin
   - Per Øyvind Karlsen
   - Thomas Klausner
   - Richard Koch
   - Ville Koskinen
+  - Jan Kratochvil
+  - Christian Kujau
   - Stephan Kulow
   - Peter Lawler
+  - James M Leddy
   - Hin-Tak Leung
   - Andraž 'ruskie' Levstik
   - Cary Lewis
@@ -49,6 +61,7 @@
   - Gregory Margo
   - Jim Meyering
   - Arkadiusz Miskiewicz
+  - Conley Moorhous
   - Rafał Mużyło
   - Adrien Nader
   - Hongbo Ni
@@ -56,29 +69,39 @@
   - Andre Noll
   - Peter O'Gorman
   - Peter Pallinger
+  - Rui Paulo
   - Igor Pavlov
   - Diego Elio Pettenò
   - Elbert Pol
   - Mikko Pouru
+  - Trần Ngọc Quân
+  - Pavel Raiskup
+  - Ole André Vadla Ravnås
   - Robert Readman
   - Bernhard Reutner-Fischer
+  - Eric S. Raymond
   - Cristian Rodríguez
   - Christian von Roques
+  - Torsten Rupp
   - Jukka Salmi
   - Alexandre Sauvé
   - Benno Schulenberg
   - Andreas Schwab
   - Dan Shechter
   - Stuart Shelton
+  - Brad Smith
   - Jonathan Stott
   - Dan Stromberg
+  - Vincent Torri
   - Paul Townsend
   - Mohammed Adnène Trojette
   - Alexey Tourbin
   - Patrick J. Volkerding
   - Martin Väth
+  - Adam Walling
   - Christian Weisgerber
   - Bert Wesarg
+  - Fredrik Wikstrom
   - Ralf Wildenhues
   - Charles Wilson
   - Lars Wirzenius
diff --git a/TODO b/TODO
index 9448660..45ba433 100644
--- a/TODO
+++ b/TODO
@@ -12,10 +12,6 @@
     it would be  possible by switching from BT2/BT3/BT4 match finder to
     HC3/HC4.
 
-    The code to detect number of CPU cores doesn't count hyperthreading
-    as multiple cores. In context of xz, it probably should.
-    Hyperthreading is good at least with p7zip.
-
     XZ Utils compress some files significantly worse than LZMA Utils.
     This is due to faster compression presets used by XZ Utils, and
     can often be worked around by using "xz --extreme". With some files
@@ -32,10 +28,29 @@
     time and calculated (de)compression speed won't make sense in the
     progress indicator (xz --verbose).
 
+    If liblzma has created threads and fork() gets called, liblzma
+    code will break in the child process unless it calls exec() and
+    doesn't touch liblzma.
+
 
 Missing features
 ----------------
 
+    Add support for storing metadata in .xz files. A preliminary
+    idea is to create a new Stream type for metadata. When both
+    metadata and data are wanted in the same .xz file, two or more
+    Streams would be concatenated.
+
+    The state stored in lzma_stream should be cloneable, which would
+    be mostly useful when using a preset dictionary in LZMA2, but
+    it may have other uses too. Compare to deflateCopy() in zlib.
+
+    Support LZMA_FINISH in raw decoder to indicate end of LZMA1 and
+    other streams that don't have an end of payload marker.
+
+    Adjust dictionary size when the input file size is known.
+    Maybe do this only if an option is given.
+
     xz doesn't support copying extended attributes, access control
     lists etc. from source to target file.
 
@@ -53,8 +68,6 @@
     It will be a separate library that supports uncompressed, .gz,
     .bz2, .lzma, and .xz files.
 
-    Check the first 0x00 byte of LZMA data.
-
     Support changing lzma_options_lzma.mode with lzma_filters_update().
 
     Support LZMA_FULL_FLUSH for lzma_stream_decoder() to stop at
@@ -64,14 +77,35 @@
     This is tricky, because the same error codes are used with
     slightly different meanings, and this cannot be fixed anymore.
 
+    Make it possible to adjust LZMA2 options in the middle of a Block
+    so that the encoding speed vs. compression ratio can be optimized
+    when the compressed data is streamed over network.
+
+    Improved BCJ filters. The current filters are small but they aren't
+    so great when compressing binary packages that contain various file
+    types. Specifically, they make things worse if there are static
+    libraries or Linux kernel modules. The filtering could also be
+    more effective (without getting overly complex), for example,
+    streamable variant BCJ2 from 7-Zip could be implemented.
+
+    Filter that autodetects specific data types in the input stream
+    and applies appropriate filters for the corrects parts of the input.
+    Perhaps combine this with the BCJ filter improvement point above.
+
+    Long-range LZ77 method as a separate filter or as a new LZMA2
+    match finder.
+
 
 Documentation
 -------------
 
-    Some tutorial is needed for liblzma. I have planned to write some
-    extremely well commented example programs, which would work as
-    a tutorial. I suppose the Doxygen tags are quite OK as a quick
-    reference once one is familiar with the liblzma API.
+    More tutorial programs are needed for liblzma.
 
     Document the LZMA1 and LZMA2 algorithms.
 
+
+Miscellaneous
+------------
+
+    Try to get the media type for .xz registered at IANA.
+
diff --git a/build-aux/version.sh b/build-aux/version.sh
index 40d0493..f9fcda7 100644
--- a/build-aux/version.sh
+++ b/build-aux/version.sh
@@ -21,4 +21,4 @@
 	src/liblzma/api/lzma/version.h \
 	| tr '\n' '|' \
 	| sed 's/|/./; s/|/./; s/|//g' \
-	| tr -d '\n'
+	| tr -d '\r\n'
diff --git a/configure.ac b/configure.ac
index 0c2f2fc..d17629e 100644
--- a/configure.ac
+++ b/configure.ac
@@ -34,8 +34,8 @@
 
 # We do some special things on Windows (32-bit or 64-bit) builds.
 case $host_os in
-	mingw* | cygwin*) is_w32=yes ;;
-	*)                is_w32=no ;;
+	mingw* | cygwin | msys) is_w32=yes ;;
+	*)                      is_w32=no ;;
 esac
 AM_CONDITIONAL([COND_W32], [test "$is_w32" = yes])
 
@@ -43,9 +43,15 @@
 # executables. Cygwin is an exception to this, since it is recommended
 # that symlinks don't have the .exe suffix. To make this work, we
 # define LN_EXEEXT.
+#
+# MSYS2 is treated the same way as Cygwin. It uses plain "msys" like
+# the original MSYS when building MSYS/MSYS2-binaries. Hopefully this
+# doesn't break things for the original MSYS developers. Note that this
+# doesn't affect normal MSYS/MSYS2 users building non-MSYS/MSYS2 binaries
+# since in that case the $host_os is usually mingw32.
 case $host_os in
-	cygwin)  LN_EXEEXT= ;;
-	*)       LN_EXEEXT='$(EXEEXT)' ;;
+	cygwin | msys)  LN_EXEEXT= ;;
+	*)              LN_EXEEXT='$(EXEEXT)' ;;
 esac
 AC_SUBST([LN_EXEEXT])
 
@@ -59,7 +65,7 @@
 #############
 
 AC_MSG_CHECKING([if debugging code should be compiled])
-AC_ARG_ENABLE([debug], AC_HELP_STRING([--enable-debug], [Enable debugging code.]),
+AC_ARG_ENABLE([debug], AS_HELP_STRING([--enable-debug], [Enable debugging code.]),
 	[], enable_debug=no)
 if test "x$enable_debug" = xyes; then
 	AC_MSG_RESULT([yes])
@@ -84,7 +90,7 @@
 ])dnl
 
 AC_MSG_CHECKING([which encoders to build])
-AC_ARG_ENABLE([encoders], AC_HELP_STRING([--enable-encoders=LIST],
+AC_ARG_ENABLE([encoders], AS_HELP_STRING([--enable-encoders=LIST],
 		[Comma-separated list of encoders to build. Default=all.
 		Available encoders:]
 			m4_translit(m4_defn([SUPPORTED_FILTERS]), [,], [ ])),
@@ -112,7 +118,7 @@
 fi
 
 AC_MSG_CHECKING([which decoders to build])
-AC_ARG_ENABLE([decoders], AC_HELP_STRING([--enable-decoders=LIST],
+AC_ARG_ENABLE([decoders], AS_HELP_STRING([--enable-decoders=LIST],
 		[Comma-separated list of decoders to build. Default=all.
 		Available decoders are the same as available encoders.]),
 	[], [enable_decoders=SUPPORTED_FILTERS])
@@ -195,7 +201,7 @@
 ])
 
 AC_MSG_CHECKING([which match finders to build])
-AC_ARG_ENABLE([match-finders], AC_HELP_STRING([--enable-match-finders=LIST],
+AC_ARG_ENABLE([match-finders], AS_HELP_STRING([--enable-match-finders=LIST],
 		[Comma-separated list of match finders to build. Default=all.
 		At least one match finder is required for encoding with
 		the LZMA1 and LZMA2 filters. Available match finders:]
@@ -234,7 +240,7 @@
 ])dnl
 
 AC_MSG_CHECKING([which integrity checks to build])
-AC_ARG_ENABLE([checks], AC_HELP_STRING([--enable-checks=LIST],
+AC_ARG_ENABLE([checks], AS_HELP_STRING([--enable-checks=LIST],
 		[Comma-separated list of integrity checks to build.
 		Default=all. Available integrity checks:]
 		m4_translit(m4_defn([SUPPORTED_CHECKS]), [,], [ ])),
@@ -260,7 +266,7 @@
 	done
 	AC_MSG_RESULT([$enable_checks])
 fi
-if test "x$enable_checks_crc32" = xno ; then
+if test "x$enable_check_crc32" = xno ; then
 	AC_MSG_ERROR([For now, the CRC32 check must always be enabled.])
 fi
 
@@ -274,7 +280,7 @@
 ###########################
 
 AC_MSG_CHECKING([if assembler optimizations should be used])
-AC_ARG_ENABLE([assembler], AC_HELP_STRING([--disable-assembler],
+AC_ARG_ENABLE([assembler], AS_HELP_STRING([--disable-assembler],
 		[Do not use assembler optimizations even if such exist
 		for the architecture.]),
 	[], [enable_assembler=yes])
@@ -283,7 +289,7 @@
 	case $host_os in
 		# Darwin should work too but only if not creating universal
 		# binaries. Solaris x86 could work too but I cannot test.
-		linux* | *bsd* | mingw* | cygwin* | *djgpp*)
+		linux* | *bsd* | mingw* | cygwin | msys | *djgpp*)
 			case $host_cpu in
 				i?86)   enable_assembler=x86 ;;
 				x86_64) enable_assembler=x86_64 ;;
@@ -297,7 +303,7 @@
 		;;
 	*)
 		AC_MSG_RESULT([])
-		AC_MSG_ERROR([--enable-assembler accepts only \`yes', \`no', \`x86', or \`x86_64'.])
+		AC_MSG_ERROR([--enable-assembler accepts only `yes', `no', `x86', or `x86_64'.])
 		;;
 esac
 AM_CONDITIONAL(COND_ASM_X86, test "x$enable_assembler" = xx86)
@@ -309,7 +315,7 @@
 #####################
 
 AC_MSG_CHECKING([if small size is preferred over speed])
-AC_ARG_ENABLE([small], AC_HELP_STRING([--enable-small],
+AC_ARG_ENABLE([small], AS_HELP_STRING([--enable-small],
 		[Make liblzma smaller and a little slower.
 		This is disabled by default to optimize for speed.]),
 	[], [enable_small=no])
@@ -317,7 +323,7 @@
 	AC_DEFINE([HAVE_SMALL], [1], [Define to 1 if optimizing for size.])
 elif test "x$enable_small" != xno; then
 	AC_MSG_RESULT([])
-	AC_MSG_ERROR([--enable-small accepts only \`yes' or \`no'])
+	AC_MSG_ERROR([--enable-small accepts only `yes' or `no'])
 fi
 AC_MSG_RESULT([$enable_small])
 AM_CONDITIONAL(COND_SMALL, test "x$enable_small" = xyes)
@@ -328,15 +334,47 @@
 #############
 
 AC_MSG_CHECKING([if threading support is wanted])
-AC_ARG_ENABLE([threads], AC_HELP_STRING([--disable-threads],
-		[Disable threading support.
-		This makes some things thread-unsafe.]),
+AC_ARG_ENABLE([threads], AS_HELP_STRING([--enable-threads=METHOD],
+		[Supported METHODS are `yes', `no', `posix', `win95', and
+		`vista'. The default is `yes'. Using `no' together with
+		--enable-small makes liblzma thread unsafe.]),
 	[], [enable_threads=yes])
-if test "x$enable_threads" != xyes && test "x$enable_threads" != xno; then
-	AC_MSG_RESULT([])
-	AC_MSG_ERROR([--enable-threads accepts only \`yes' or \`no'])
+
+if test "x$enable_threads" = xyes; then
+	case $host_os in
+		mingw*)
+			case $host_cpu in
+				i?86)   enable_threads=win95 ;;
+				*)      enable_threads=vista ;;
+			esac
+			;;
+		*)
+			enable_threads=posix
+			;;
+	esac
 fi
-AC_MSG_RESULT([$enable_threads])
+
+case $enable_threads in
+	posix | win95 | vista)
+		AC_MSG_RESULT([yes, $enable_threads])
+		;;
+	no)
+		AC_MSG_RESULT([no])
+		;;
+	*)
+		AC_MSG_RESULT([])
+		AC_MSG_ERROR([--enable-threads only accepts `yes', `no', `posix', `win95', or `vista'])
+		;;
+esac
+
+# The Win95 threading lacks thread-safe one-time initialization function.
+# It's better to disallow it instead of allowing threaded but thread-unsafe
+# build.
+if test "x$enable_small$enable_threads" = xyeswin95; then
+	AC_MSG_ERROR([--enable-threads=win95 and --enable-small cannot be
+		used at the same time])
+fi
+
 # We use the actual result a little later.
 
 
@@ -349,7 +387,7 @@
 # but most systems, on which we don't have any way to determine the amount
 # of RAM, will probably have at least 128 MiB of RAM.
 AC_MSG_CHECKING([how much RAM to assume if the real amount is unknown])
-AC_ARG_ENABLE([assume-ram], AC_HELP_STRING([--enable-assume-ram=SIZE],
+AC_ARG_ENABLE([assume-ram], AS_HELP_STRING([--enable-assume-ram=SIZE],
 		[If and only if the real amount of RAM cannot be determined,
 		assume SIZE MiB. The default is 128 MiB. This affects the
 		default memory usage limit.]),
@@ -369,51 +407,61 @@
 # Components to install #
 #########################
 
-AC_ARG_ENABLE([xz], [AC_HELP_STRING([--disable-xz],
+AC_ARG_ENABLE([xz], [AS_HELP_STRING([--disable-xz],
 		[do not build the xz tool])],
 	[], [enable_xz=yes])
 AM_CONDITIONAL([COND_XZ], [test x$enable_xz != xno])
 
-AC_ARG_ENABLE([xzdec], [AC_HELP_STRING([--disable-xzdec],
+AC_ARG_ENABLE([xzdec], [AS_HELP_STRING([--disable-xzdec],
 		[do not build xzdec])],
 	[], [enable_xzdec=yes])
 AM_CONDITIONAL([COND_XZDEC], [test x$enable_xzdec != xno])
 
-AC_ARG_ENABLE([lzmadec], [AC_HELP_STRING([--disable-lzmadec],
+AC_ARG_ENABLE([lzmadec], [AS_HELP_STRING([--disable-lzmadec],
 		[do not build lzmadec
 		(it exists primarily for LZMA Utils compatibility)])],
 	[], [enable_lzmadec=yes])
 AM_CONDITIONAL([COND_LZMADEC], [test x$enable_lzmadec != xno])
 
-AC_ARG_ENABLE([lzmainfo], [AC_HELP_STRING([--disable-lzmainfo],
+AC_ARG_ENABLE([lzmainfo], [AS_HELP_STRING([--disable-lzmainfo],
 		[do not build lzmainfo
 		(it exists primarily for LZMA Utils compatibility)])],
 	[], [enable_lzmainfo=yes])
 AM_CONDITIONAL([COND_LZMAINFO], [test x$enable_lzmainfo != xno])
 
-AC_ARG_ENABLE([lzma-links], [AC_HELP_STRING([--disable-lzma-links],
+AC_ARG_ENABLE([lzma-links], [AS_HELP_STRING([--disable-lzma-links],
 		[do not create symlinks for LZMA Utils compatibility])],
 	[], [enable_lzma_links=yes])
 AM_CONDITIONAL([COND_LZMALINKS], [test x$enable_lzma_links != xno])
 
-AC_ARG_ENABLE([scripts], [AC_HELP_STRING([--disable-scripts],
+AC_ARG_ENABLE([scripts], [AS_HELP_STRING([--disable-scripts],
 		[do not install the scripts xzdiff, xzgrep, xzless, xzmore,
 		and their symlinks])],
 	[], [enable_scripts=yes])
 AM_CONDITIONAL([COND_SCRIPTS], [test x$enable_scripts != xno])
 
+AC_ARG_ENABLE([doc], [AS_HELP_STRING([--disable-doc],
+		[do not install documentation files to docdir
+		(man pages will still be installed)])],
+	[], [enable_doc=yes])
+AM_CONDITIONAL([COND_DOC], [test x$enable_doc != xno])
+
 
 #####################
 # Symbol versioning #
 #####################
 
 AC_MSG_CHECKING([if library symbol versioning should be used])
-AC_ARG_ENABLE([symbol-versions], [AC_HELP_STRING([--enable-symbol-versions],
+AC_ARG_ENABLE([symbol-versions], [AS_HELP_STRING([--enable-symbol-versions],
 		[Use symbol versioning for liblzma. Enabled by default on
 		GNU/Linux, other GNU-based systems, and FreeBSD.])],
 	[], [enable_symbol_versions=auto])
 if test "x$enable_symbol_versions" = xauto; then
 	case $host_os in
+		# NOTE: Even if one omits -gnu on GNU/Linux (e.g.
+		# i486-slackware-linux), configure will (via config.sub)
+		# append -gnu (e.g. i486-slackware-linux-gnu), and this
+		# test will work correctly.
 		gnu* | *-gnu* | freebsd*)
 			enable_symbol_versions=yes
 			;;
@@ -432,14 +480,19 @@
 
 echo
 gl_POSIX_SHELL
-if test -z "$POSIX_SHELL" ; then
+if test -z "$POSIX_SHELL" && test "x$enable_scripts" = xyes ; then
 	AC_MSG_ERROR([No POSIX conforming shell (sh) was found.])
 fi
 
 echo
 echo "Initializing Automake:"
 
-AM_INIT_AUTOMAKE([1.10 foreign tar-v7 filename-length-max=99])
+# We don't use "subdir-objects" yet because it breaks "make distclean" when
+# dependencies are enabled (as of Automake 1.14.1) due to this bug:
+# http://debbugs.gnu.org/cgi/bugreport.cgi?bug=17354
+# The -Wno-unsupported is used to silence warnings about missing
+# "subdir-objects".
+AM_INIT_AUTOMAKE([1.12 foreign tar-v7 filename-length-max=99 serial-tests -Wno-unsupported])
 AC_PROG_LN_S
 
 AC_PROG_CC_C99
@@ -451,26 +504,49 @@
 AM_PROG_AS
 AC_USE_SYSTEM_EXTENSIONS
 
-if test "x$enable_threads" = xyes; then
-	echo
-	echo "Threading support:"
-	AX_PTHREAD
-	LIBS="$LIBS $PTHREAD_LIBS"
-	AM_CFLAGS="$AM_CFLAGS $PTHREAD_CFLAGS"
+case $enable_threads in
+	posix)
+		echo
+		echo "POSIX threading support:"
+		AX_PTHREAD([:]) dnl We don't need the HAVE_PTHREAD macro.
+		LIBS="$LIBS $PTHREAD_LIBS"
+		AM_CFLAGS="$AM_CFLAGS $PTHREAD_CFLAGS"
 
-	dnl NOTE: PTHREAD_CC is ignored. It would be useful on AIX, but
-	dnl it's tricky to get it right together with AC_PROG_CC_C99.
-	dnl Thus, this is handled by telling the user in INSTALL to set
-	dnl the correct CC manually.
+		dnl NOTE: PTHREAD_CC is ignored. It would be useful on AIX,
+		dnl but it's tricky to get it right together with
+		dnl AC_PROG_CC_C99. Thus, this is handled by telling the
+		dnl user in INSTALL to set the correct CC manually.
 
-	# These are nice to have but not mandatory.
-	OLD_CFLAGS=$CFLAGS
-	CFLAGS="$CFLAGS $PTHREAD_CFLAGS"
-	AC_SEARCH_LIBS([clock_gettime], [rt])
-	AC_CHECK_FUNCS([clock_gettime pthread_condattr_setclock])
-	AC_CHECK_DECLS([CLOCK_MONOTONIC], [], [], [[#include <time.h>]])
-	CFLAGS=$OLD_CFLAGS
-fi
+		AC_DEFINE([MYTHREAD_POSIX], [1],
+			[Define to 1 when using POSIX threads (pthreads).])
+
+		# These are nice to have but not mandatory.
+		#
+		# FIXME: xz uses clock_gettime if it is available and can do
+		# it even when threading is disabled. Moving this outside
+		# of pthread detection may be undesirable because then
+		# liblzma may get linked against librt even when librt isn't
+		# needed by liblzma.
+		OLD_CFLAGS=$CFLAGS
+		CFLAGS="$CFLAGS $PTHREAD_CFLAGS"
+		AC_SEARCH_LIBS([clock_gettime], [rt])
+		AC_CHECK_FUNCS([clock_gettime pthread_condattr_setclock])
+		AC_CHECK_DECLS([CLOCK_MONOTONIC], [], [], [[#include <time.h>]])
+		CFLAGS=$OLD_CFLAGS
+		;;
+	win95)
+		AC_DEFINE([MYTHREAD_WIN95], [1], [Define to 1 when using
+			Windows 95 (and thus XP) compatible threads.
+			This avoids use of features that were added in
+			Windows Vista.])
+		;;
+	vista)
+		AC_DEFINE([MYTHREAD_VISTA], [1], [Define to 1 when using
+			Windows Vista compatible threads. This uses
+			features that are not available on Windows XP.])
+		;;
+esac
+AM_CONDITIONAL([COND_THREADS], [test "x$enable_threads" != xno])
 
 # As a Debian-specific hack, liblzma can use dlopen() to check if extra
 # paranoia is needed because unversioned symbols from liblzma.so.2 are
@@ -525,9 +601,10 @@
 
 echo
 echo "Initializing gettext:"
-AM_GNU_GETTEXT_VERSION([0.16.1])
+AM_GNU_GETTEXT_VERSION([0.18])
 AM_GNU_GETTEXT([external])
 
+
 ###############################################################################
 # Checks for header files.
 ###############################################################################
@@ -541,6 +618,9 @@
 	[],
 	[AC_MSG_ERROR([Required header file(s) are missing.])])
 
+# This allows the use of the intrinsic functions if they are available.
+AC_CHECK_HEADERS([immintrin.h])
+
 
 ###############################################################################
 # Checks for typedefs, structures, and compiler characteristics.
@@ -563,7 +643,7 @@
 AC_CHECK_SIZEOF([size_t])
 
 # The command line tool can copy high resolution timestamps if such
-# information is availabe in struct stat. Otherwise one second accuracy
+# information is available in struct stat. Otherwise one second accuracy
 # is used.
 AC_CHECK_MEMBERS([
 	struct stat.st_atim.tv_nsec,
@@ -649,6 +729,15 @@
 		&& test "x$ac_cv_func_SHA256Init" != xyes \
 		&& test "x$ac_cv_func_CC_SHA256_Init" != xyes])
 
+# Check for SSE2 intrinsics.
+AC_CHECK_DECL([_mm_movemask_epi8],
+	[AC_DEFINE([HAVE__MM_MOVEMASK_EPI8], [1],
+		[Define to 1 if _mm_movemask_epi8 is available.])],
+	[],
+[#ifdef HAVE_IMMINTRIN_H
+#include <immintrin.h>
+#endif])
+
 
 ###############################################################################
 # If using GCC, set some additional AM_CFLAGS:
@@ -682,6 +771,7 @@
 	for NEW_FLAG in \
 			-Wall \
 			-Wextra \
+			-Wvla \
 			-Wformat=2 \
 			-Winit-self \
 			-Wmissing-include-dirs \
@@ -703,8 +793,9 @@
 	do
 		AC_MSG_CHECKING([if $CC accepts $NEW_FLAG])
 		OLD_CFLAGS="$CFLAGS"
-		CFLAGS="$CFLAGS $NEW_FLAG"
-		AC_COMPILE_IFELSE([AC_LANG_SOURCE([void foo(void) { }])], [
+		CFLAGS="$CFLAGS $NEW_FLAG -Werror"
+		AC_COMPILE_IFELSE([AC_LANG_SOURCE(
+				[void foo(void); void foo(void) { }])], [
 			AM_CFLAGS="$AM_CFLAGS $NEW_FLAG"
 			AC_MSG_RESULT([yes])
 		], [
@@ -714,7 +805,7 @@
 	done
 
 	AC_ARG_ENABLE([werror],
-		AC_HELP_STRING([--enable-werror], [Enable -Werror to abort
+		AS_HELP_STRING([--enable-werror], [Enable -Werror to abort
 			compilation on all compiler warnings.]),
 		[], [enable_werror=no])
 	if test "x$enable_werror" = "xyes"; then
@@ -746,7 +837,6 @@
 	po/Makefile.in
 	lib/Makefile
 	src/Makefile
-	src/liblzma/liblzma.pc
 	src/liblzma/Makefile
 	src/liblzma/api/Makefile
 	src/xz/Makefile
@@ -777,3 +867,10 @@
 	echo "WARNING:"
 	echo "No supported method to detect the number of CPU cores."
 fi
+
+if test "x$enable_threads$enable_small" = xnoyes; then
+	echo
+	echo "NOTE:"
+	echo "liblzma will be thread unsafe due the combination"
+	echo "of --disable-threads --enable-small."
+fi
diff --git a/debian/.git-dpm b/debian/.git-dpm
new file mode 100644
index 0000000..6dcce22
--- /dev/null
+++ b/debian/.git-dpm
@@ -0,0 +1,8 @@
+# see git-dpm(1) from git-dpm package
+e284cfe27457239e932038fb90084c91f4229c36
+e284cfe27457239e932038fb90084c91f4229c36
+141d36d7861b6e8522c213194d5fba1e47af63e9
+141d36d7861b6e8522c213194d5fba1e47af63e9
+xz-utils_5.2.2.orig.tar.xz
+72c567d3263345844191a7e618779b179d1f49e0
+1016404
diff --git a/debian/changelog b/debian/changelog
index 5347a1c..15e6f53 100644
--- a/debian/changelog
+++ b/debian/changelog
@@ -1,3 +1,15 @@
+xz-utils (5.2.2-1.1) unstable; urgency=medium
+
+  * Non-maintainer upload.
+  * switch to git-dpm for packaging (closes: #540405)
+  * New Upstream (closes: #731634)
+   - no more "xzless error in line 49" (closes: #693537)
+   - xzgrep -h works (closes: #780268)
+  * update symbol file
+  * enable threads for the "normal build"
+
+ -- Sebastian Andrzej Siewior <sebastian@breakpoint.cc>  Mon, 26 Sep 2016 20:45:45 +0200
+
 xz-utils (5.1.1alpha+20120614-2.1) unstable; urgency=medium
 
   [ Helmut Grohne ]
diff --git a/debian/clean.sh b/debian/clean.sh
index 1a2f8b3..59248e4 100644
--- a/debian/clean.sh
+++ b/debian/clean.sh
@@ -38,7 +38,7 @@
 '
 
 dh_testdir
-rm -f debug/translation.bash tests/test_block.c ChangeLog
+rm -f debug/translation.bash tests/test_block.c
 rm -f ABOUT-NLS aclocal.m4 config.h.in configure
 (cd po && perl -e "$remove_files") < debian/generated-po.list
 (cd m4 && perl -e "$remove_files") < debian/generated-m4.list
diff --git a/debian/patches/abi-threaded-encoder b/debian/patches/abi-threaded-encoder
deleted file mode 100644
index 04babbf..0000000
--- a/debian/patches/abi-threaded-encoder
+++ /dev/null
@@ -1,2163 +0,0 @@
-From: Jonathan Nieder <jrnieder@gmail.com>
-Date: Sat, 11 Jun 2011 21:41:15 -0500
-Subject: Remove threading functionality for now
-
-This reverts the following commits:
-
- - 6ef4eabc0 (Bump the version number to 5.1.1alpha and liblzma soname
-   to 5.0.99)
- - 70e750f59 (xz: Update the man page about threading)
- - c29e6630c (xz: Print the maximum number of worker threads in xz -vv)
- - 335fe260a (xz: Minor internal changes to handling of --threads)
- - 24e0406c0 (xz: Add support for threaded compression)
- - 9a4377be0 (Put the unstable APIs behind #ifdef LZMA_UNSTABLE)
- - de678e0c9 (liblmza: Add lzma_stream_encoder_mt() for threaded
-   compression)
-
-The multithreaded compression functions, while useful, are not set in
-stone as part of the stable ABI.  Changes will be easier to weather
-until the functions stabilize if they are left out from the
-non-experimental development branch of Debian for now.
-
-Signed-off-by: Jonathan Nieder <jrnieder@gmail.com>
----
- configure.ac                           |    1 -
- src/liblzma/Makefile.am                |    2 +-
- src/liblzma/api/lzma/container.h       |  167 ------
- src/liblzma/api/lzma/version.h         |    2 +-
- src/liblzma/common/Makefile.inc        |    7 -
- src/liblzma/common/common.c            |    9 +-
- src/liblzma/common/common.h            |   16 -
- src/liblzma/common/outqueue.c          |  184 ------
- src/liblzma/common/outqueue.h          |  155 -----
- src/liblzma/common/stream_encoder_mt.c | 1013 --------------------------------
- src/xz/args.c                          |    5 +-
- src/xz/coder.c                         |  210 +++----
- src/xz/hardware.c                      |   24 +-
- src/xz/hardware.h                      |    9 +-
- src/xz/private.h                       |    2 -
- src/xz/xz.1                            |   34 +-
- 16 files changed, 117 insertions(+), 1723 deletions(-)
- delete mode 100644 src/liblzma/common/outqueue.c
- delete mode 100644 src/liblzma/common/outqueue.h
- delete mode 100644 src/liblzma/common/stream_encoder_mt.c
-
-diff --git a/configure.ac b/configure.ac
-index 25eb838..c9585e5 100644
---- a/configure.ac
-+++ b/configure.ac
-@@ -471,7 +471,6 @@ if test "x$enable_threads" = xyes; then
- 	AC_CHECK_DECLS([CLOCK_MONOTONIC], [], [], [[#include <time.h>]])
- 	CFLAGS=$OLD_CFLAGS
- fi
--AM_CONDITIONAL([COND_THREADS], [test "x$ax_pthread_ok" = xyes])
- 
- echo
- echo "Initializing Libtool:"
-diff --git a/src/liblzma/Makefile.am b/src/liblzma/Makefile.am
-index 5bd205d..ac2d1ed 100644
---- a/src/liblzma/Makefile.am
-+++ b/src/liblzma/Makefile.am
-@@ -24,7 +24,7 @@ liblzma_la_CPPFLAGS = \
- 	-I$(top_srcdir)/src/liblzma/simple \
- 	-I$(top_srcdir)/src/common \
- 	-DTUKLIB_SYMBOL_PREFIX=lzma_
--liblzma_la_LDFLAGS = -no-undefined -version-info 5:99:0
-+liblzma_la_LDFLAGS = -no-undefined -version-info 5:0:0
- 
- if COND_SYMVERS
- EXTRA_DIST += liblzma.map
-diff --git a/src/liblzma/api/lzma/container.h b/src/liblzma/api/lzma/container.h
-index 499d8b9..7a9ffc6 100644
---- a/src/liblzma/api/lzma/container.h
-+++ b/src/liblzma/api/lzma/container.h
-@@ -60,129 +60,6 @@
- #define LZMA_PRESET_EXTREME       (UINT32_C(1) << 31)
- 
- 
--#ifdef LZMA_UNSTABLE /* Unstable API that may change. Use only for testing. */
--/**
-- * \brief       Multithreading options
-- */
--typedef struct {
--	/**
--	 * \brief       Flags
--	 *
--	 * Set this to zero if no flags are wanted.
--	 *
--	 * No flags are currently supported.
--	 */
--	uint32_t flags;
--
--	/**
--	 * \brief       Number of worker threads to use
--	 */
--	uint32_t threads;
--
--	/**
--	 * \brief       Maximum uncompressed size of a Block
--	 *
--	 * The encoder will start a new .xz Block every block_size bytes.
--	 * Using LZMA_FULL_FLUSH or LZMA_FULL_BARRIER with lzma_code()
--	 * the caller may tell liblzma to start a new Block earlier.
--	 *
--	 * With LZMA2, a recommended block size is 2-4 times the LZMA2
--	 * dictionary size. With very small dictionaries, it is recommended
--	 * to use at least 1 MiB block size for good compression ratio, even
--	 * if this is more than four times the dictionary size. Note that
--	 * these are only recommendations for typical use cases; feel free
--	 * to use other values. Just keep in mind that using a block size
--	 * less than the LZMA2 dictionary size is waste of RAM.
--	 *
--	 * Set this to 0 to let liblzma choose the block size depending
--	 * on the compression options. For LZMA2 it will be 3*dict_size
--	 * or 1 MiB, whichever is more.
--	 */
--	uint64_t block_size;
--
--	/**
--	 * \brief       Timeout to allow lzma_code() to return early
--	 *
--	 * Multithreading can make liblzma to consume input and produce
--	 * output in a very bursty way: it may first read a lot of input
--	 * to fill internal buffers, then no input or output occurs for
--	 * a while.
--	 *
--	 * In single-threaded mode, lzma_code() won't return until it has
--	 * either consumed all the input or filled the output buffer. If
--	 * this is done in multithreaded mode, it may cause a call
--	 * lzma_code() to take even tens of seconds, which isn't acceptable
--	 * in all applications.
--	 *
--	 * To avoid very long blocking times in lzma_code(), a timeout
--	 * (in milliseconds) may be set here. If lzma_code() would block
--	 * longer than this number of milliseconds, it will return with
--	 * LZMA_OK. Reasonable values are 100 ms or more. The xz command
--	 * line tool uses 300 ms.
--	 *
--	 * If long blocking times are fine for you, set timeout to a special
--	 * value of 0, which will disable the timeout mechanism and will make
--	 * lzma_code() block until all the input is consumed or the output
--	 * buffer has been filled.
--	 *
--	 * \note        Even with a timeout, lzma_code() might sometimes take
--	 *              somewhat long time to return. No timing guarantees
--	 *              are made.
--	 */
--	uint32_t timeout;
--
--	/**
--	 * \brief       Compression preset (level and possible flags)
--	 *
--	 * The preset is set just like with lzma_easy_encoder().
--	 * The preset is ignored if filters below is non-NULL.
--	 */
--	uint32_t preset;
--
--	/**
--	 * \brief       Filter chain (alternative to a preset)
--	 *
--	 * If this is NULL, the preset above is used. Otherwise the preset
--	 * is ignored and the filter chain specified here is used.
--	 */
--	const lzma_filter *filters;
--
--	/**
--	 * \brief       Integrity check type
--	 *
--	 * See check.h for available checks. The xz command line tool
--	 * defaults to LZMA_CHECK_CRC64, which is a good choice if you
--	 * are unsure.
--	 */
--	lzma_check check;
--
--	/*
--	 * Reserved space to allow possible future extensions without
--	 * breaking the ABI. You should not touch these, because the names
--	 * of these variables may change. These are and will never be used
--	 * with the currently supported options, so it is safe to leave these
--	 * uninitialized.
--	 */
--	lzma_reserved_enum reserved_enum1;
--	lzma_reserved_enum reserved_enum2;
--	lzma_reserved_enum reserved_enum3;
--	uint32_t reserved_int1;
--	uint32_t reserved_int2;
--	uint32_t reserved_int3;
--	uint32_t reserved_int4;
--	uint64_t reserved_int5;
--	uint64_t reserved_int6;
--	uint64_t reserved_int7;
--	uint64_t reserved_int8;
--	void *reserved_ptr1;
--	void *reserved_ptr2;
--	void *reserved_ptr3;
--	void *reserved_ptr4;
--
--} lzma_mt;
--#endif
--
--
- /**
-  * \brief       Calculate approximate memory usage of easy encoder
-  *
-@@ -313,50 +190,6 @@ extern LZMA_API(lzma_ret) lzma_stream_encoder(lzma_stream *strm,
- 		lzma_nothrow lzma_attr_warn_unused_result;
- 
- 
--#ifdef LZMA_UNSTABLE /* Unstable API that may change. Use only for testing. */
--/**
-- * \brief       Calculate approximate memory usage of multithreaded .xz encoder
-- *
-- * Since doing the encoding in threaded mode doesn't affect the memory
-- * requirements of single-threaded decompressor, you can use
-- * lzma_easy_decoder_memusage(options->preset) or
-- * lzma_raw_decoder_memusage(options->filters) to calculate
-- * the decompressor memory requirements.
-- *
-- * \param       options Compression options
-- *
-- * \return      Number of bytes of memory required for encoding with the
-- *              given options. If an error occurs, for example due to
-- *              unsupported preset or filter chain, UINT64_MAX is returned.
-- */
--extern LZMA_API(uint64_t) lzma_stream_encoder_mt_memusage(
--		const lzma_mt *options) lzma_nothrow lzma_attr_pure;
--
--
--/**
-- * \brief       Initialize multithreaded .xz Stream encoder
-- *
-- * This provides the functionality of lzma_easy_encoder() and
-- * lzma_stream_encoder() as a single function for multithreaded use.
-- *
-- * TODO: For lzma_code(), only LZMA_RUN and LZMA_FINISH are currently
-- * supported. Support for other actions has been planned.
-- *
-- * \param       strm    Pointer to properly prepared lzma_stream
-- * \param       options Pointer to multithreaded compression options
-- *
-- * \return      - LZMA_OK
-- *              - LZMA_MEM_ERROR
-- *              - LZMA_UNSUPPORTED_CHECK
-- *              - LZMA_OPTIONS_ERROR
-- *              - LZMA_PROG_ERROR
-- */
--extern LZMA_API(lzma_ret) lzma_stream_encoder_mt(
--		lzma_stream *strm, const lzma_mt *options)
--		lzma_nothrow lzma_attr_warn_unused_result;
--#endif
--
--
- /**
-  * \brief       Initialize .lzma encoder (legacy file format)
-  *
-diff --git a/src/liblzma/api/lzma/version.h b/src/liblzma/api/lzma/version.h
-index 4bf7e40..a908ea2 100644
---- a/src/liblzma/api/lzma/version.h
-+++ b/src/liblzma/api/lzma/version.h
-@@ -22,7 +22,7 @@
-  */
- #define LZMA_VERSION_MAJOR 5
- #define LZMA_VERSION_MINOR 1
--#define LZMA_VERSION_PATCH 1
-+#define LZMA_VERSION_PATCH 0
- #define LZMA_VERSION_STABILITY LZMA_VERSION_STABILITY_ALPHA
- 
- #ifndef LZMA_VERSION_COMMIT
-diff --git a/src/liblzma/common/Makefile.inc b/src/liblzma/common/Makefile.inc
-index dd5a8c8..81d751e 100644
---- a/src/liblzma/common/Makefile.inc
-+++ b/src/liblzma/common/Makefile.inc
-@@ -40,13 +40,6 @@ liblzma_la_SOURCES += \
- 	common/stream_encoder.c \
- 	common/stream_flags_encoder.c \
- 	common/vli_encoder.c
--
--if COND_THREADS
--liblzma_la_SOURCES += \
--	common/outqueue.c \
--	common/outqueue.h \
--	common/stream_encoder_mt.c
--endif
- endif
- 
- if COND_MAIN_DECODER
-diff --git a/src/liblzma/common/common.c b/src/liblzma/common/common.c
-index 85ae96a..50c984c 100644
---- a/src/liblzma/common/common.c
-+++ b/src/liblzma/common/common.c
-@@ -263,9 +263,7 @@ lzma_code(lzma_stream *strm, lzma_action action)
- 
- 	strm->internal->avail_in = strm->avail_in;
- 
--	// Cast is needed to silence a warning about LZMA_TIMED_OUT, which
--	// isn't part of lzma_ret enumeration.
--	switch ((unsigned int)(ret)) {
-+	switch (ret) {
- 	case LZMA_OK:
- 		// Don't return LZMA_BUF_ERROR when it happens the first time.
- 		// This is to avoid returning LZMA_BUF_ERROR when avail_out
-@@ -281,11 +279,6 @@ lzma_code(lzma_stream *strm, lzma_action action)
- 		}
- 		break;
- 
--	case LZMA_TIMED_OUT:
--		strm->internal->allow_buf_error = false;
--		ret = LZMA_OK;
--		break;
--
- 	case LZMA_STREAM_END:
- 		if (strm->internal->sequence == ISEQ_SYNC_FLUSH
- 				|| strm->internal->sequence == ISEQ_FULL_FLUSH)
-diff --git a/src/liblzma/common/common.h b/src/liblzma/common/common.h
-index 5c92af2..45aba4f 100644
---- a/src/liblzma/common/common.h
-+++ b/src/liblzma/common/common.h
-@@ -32,8 +32,6 @@
- 
- #define LZMA_API(type) LZMA_API_EXPORT type LZMA_API_CALL
- 
--#define LZMA_UNSTABLE
--
- #include "lzma.h"
- 
- // These allow helping the compiler in some often-executed branches, whose
-@@ -51,13 +49,6 @@
- #define LZMA_BUFFER_SIZE 4096
- 
- 
--/// Maximum number of worker threads within one multithreaded component.
--/// The limit exists solely to make it simpler to prevent integer overflows
--/// when allocating structures etc. This should be big enough for now...
--/// the code won't scale anywhere close to this number anyway.
--#define LZMA_THREADS_MAX 16384
--
--
- /// Starting value for memory usage estimates. Instead of calculating size
- /// of _every_ structure and taking into account malloc() overhead etc., we
- /// add a base size to all memory usage estimates. It's not very accurate
-@@ -78,13 +69,6 @@
- 	| LZMA_CONCATENATED )
- 
- 
--/// Special return value (lzma_ret) to indicate that a timeout was reached
--/// and lzma_code() must not return LZMA_BUF_ERROR. This is converted to
--/// LZMA_OK in lzma_code(). This is not in the lzma_ret enumeration because
--/// there's no need to have it in the public API.
--#define LZMA_TIMED_OUT 32
--
--
- /// Type of encoder/decoder specific data; the actual structure is defined
- /// differently in different coders.
- typedef struct lzma_coder_s lzma_coder;
-diff --git a/src/liblzma/common/outqueue.c b/src/liblzma/common/outqueue.c
-deleted file mode 100644
-index d7a87d9..0000000
---- a/src/liblzma/common/outqueue.c
-+++ /dev/null
-@@ -1,184 +0,0 @@
--///////////////////////////////////////////////////////////////////////////////
--//
--/// \file       outqueue.c
--/// \brief      Output queue handling in multithreaded coding
--//
--//  Author:     Lasse Collin
--//
--//  This file has been put into the public domain.
--//  You can do whatever you want with this file.
--//
--///////////////////////////////////////////////////////////////////////////////
--
--#include "outqueue.h"
--
--
--/// This is to ease integer overflow checking: We may allocate up to
--/// 2 * LZMA_THREADS_MAX buffers and we need some extra memory for other
--/// data structures (that's the second /2).
--#define BUF_SIZE_MAX (UINT64_MAX / LZMA_THREADS_MAX / 2 / 2)
--
--
--static lzma_ret
--get_options(uint64_t *bufs_alloc_size, uint32_t *bufs_count,
--		uint64_t buf_size_max, uint32_t threads)
--{
--	if (threads > LZMA_THREADS_MAX || buf_size_max > BUF_SIZE_MAX)
--		return LZMA_OPTIONS_ERROR;
--
--	// The number of buffers is twice the number of threads.
--	// This wastes RAM but keeps the threads busy when buffers
--	// finish out of order.
--	//
--	// NOTE: If this is changed, update BUF_SIZE_MAX too.
--	*bufs_count = threads * 2;
--	*bufs_alloc_size = *bufs_count * buf_size_max;
--
--	return LZMA_OK;
--}
--
--
--extern uint64_t
--lzma_outq_memusage(uint64_t buf_size_max, uint32_t threads)
--{
--	uint64_t bufs_alloc_size;
--	uint32_t bufs_count;
--
--	if (get_options(&bufs_alloc_size, &bufs_count, buf_size_max, threads)
--			!= LZMA_OK)
--		return UINT64_MAX;
--
--	return sizeof(lzma_outq) + bufs_count * sizeof(lzma_outbuf)
--			+ bufs_alloc_size;
--}
--
--
--extern lzma_ret
--lzma_outq_init(lzma_outq *outq, lzma_allocator *allocator,
--		uint64_t buf_size_max, uint32_t threads)
--{
--	uint64_t bufs_alloc_size;
--	uint32_t bufs_count;
--
--	// Set bufs_count and bufs_alloc_size.
--	return_if_error(get_options(&bufs_alloc_size, &bufs_count,
--			buf_size_max, threads));
--
--	// Allocate memory if needed.
--	if (outq->buf_size_max != buf_size_max
--			|| outq->bufs_allocated != bufs_count) {
--		lzma_outq_end(outq, allocator);
--
--#if SIZE_MAX < UINT64_MAX
--		if (bufs_alloc_size > SIZE_MAX)
--			return LZMA_MEM_ERROR;
--#endif
--
--		outq->bufs = lzma_alloc(bufs_count * sizeof(lzma_outbuf),
--				allocator);
--		outq->bufs_mem = lzma_alloc((size_t)(bufs_alloc_size),
--				allocator);
--
--		if (outq->bufs == NULL || outq->bufs_mem == NULL) {
--			lzma_outq_end(outq, allocator);
--			return LZMA_MEM_ERROR;
--		}
--	}
--
--	// Initialize the rest of the main structure. Initialization of
--	// outq->bufs[] is done when they are actually needed.
--	outq->buf_size_max = (size_t)(buf_size_max);
--	outq->bufs_allocated = bufs_count;
--	outq->bufs_pos = 0;
--	outq->bufs_used = 0;
--	outq->read_pos = 0;
--
--	return LZMA_OK;
--}
--
--
--extern void
--lzma_outq_end(lzma_outq *outq, lzma_allocator *allocator)
--{
--	lzma_free(outq->bufs, allocator);
--	outq->bufs = NULL;
--
--	lzma_free(outq->bufs_mem, allocator);
--	outq->bufs_mem = NULL;
--
--	return;
--}
--
--
--extern lzma_outbuf *
--lzma_outq_get_buf(lzma_outq *outq)
--{
--	// Caller must have checked it with lzma_outq_has_buf().
--	assert(outq->bufs_used < outq->bufs_allocated);
--
--	// Initialize the new buffer.
--	lzma_outbuf *buf = &outq->bufs[outq->bufs_pos];
--	buf->buf = outq->bufs_mem + outq->bufs_pos * outq->buf_size_max;
--	buf->size = 0;
--	buf->finished = false;
--
--	// Update the queue state.
--	if (++outq->bufs_pos == outq->bufs_allocated)
--		outq->bufs_pos = 0;
--
--	++outq->bufs_used;
--
--	return buf;
--}
--
--
--extern bool
--lzma_outq_is_readable(const lzma_outq *outq)
--{
--	uint32_t i = outq->bufs_pos - outq->bufs_used;
--	if (outq->bufs_pos < outq->bufs_used)
--		i += outq->bufs_allocated;
--
--	return outq->bufs[i].finished;
--}
--
--
--extern lzma_ret
--lzma_outq_read(lzma_outq *restrict outq, uint8_t *restrict out,
--		size_t *restrict out_pos, size_t out_size,
--		lzma_vli *restrict unpadded_size,
--		lzma_vli *restrict uncompressed_size)
--{
--	// There must be at least one buffer from which to read.
--	if (outq->bufs_used == 0)
--		return LZMA_OK;
--
--	// Get the buffer.
--	uint32_t i = outq->bufs_pos - outq->bufs_used;
--	if (outq->bufs_pos < outq->bufs_used)
--		i += outq->bufs_allocated;
--
--	lzma_outbuf *buf = &outq->bufs[i];
--
--	// If it isn't finished yet, we cannot read from it.
--	if (!buf->finished)
--		return LZMA_OK;
--
--	// Copy from the buffer to output.
--	lzma_bufcpy(buf->buf, &outq->read_pos, buf->size,
--			out, out_pos, out_size);
--
--	// Return if we didn't get all the data from the buffer.
--	if (outq->read_pos < buf->size)
--		return LZMA_OK;
--
--	// The buffer was finished. Tell the caller its size information.
--	*unpadded_size = buf->unpadded_size;
--	*uncompressed_size = buf->uncompressed_size;
--
--	// Free this buffer for further use.
--	--outq->bufs_used;
--	outq->read_pos = 0;
--
--	return LZMA_STREAM_END;
--}
-diff --git a/src/liblzma/common/outqueue.h b/src/liblzma/common/outqueue.h
-deleted file mode 100644
-index 154f91b..0000000
---- a/src/liblzma/common/outqueue.h
-+++ /dev/null
-@@ -1,155 +0,0 @@
--///////////////////////////////////////////////////////////////////////////////
--//
--/// \file       outqueue.h
--/// \brief      Output queue handling in multithreaded coding
--//
--//  Author:     Lasse Collin
--//
--//  This file has been put into the public domain.
--//  You can do whatever you want with this file.
--//
--///////////////////////////////////////////////////////////////////////////////
--
--#include "common.h"
--
--
--/// Output buffer for a single thread
--typedef struct {
--	/// Pointer to the output buffer of lzma_outq.buf_size_max bytes
--	uint8_t *buf;
--
--	/// Amount of data written to buf
--	size_t size;
--
--	/// Additional size information
--	lzma_vli unpadded_size;
--	lzma_vli uncompressed_size;
--
--	/// True when no more data will be written into this buffer.
--	///
--	/// \note       This is read by another thread and thus access
--	///             to this variable needs a mutex.
--	bool finished;
--
--} lzma_outbuf;
--
--
--typedef struct {
--	/// Array of buffers that are used cyclically.
--	lzma_outbuf *bufs;
--
--	/// Memory allocated for all the buffers
--	uint8_t *bufs_mem;
--
--	/// Amount of buffer space available in each buffer
--	size_t buf_size_max;
--
--	/// Number of buffers allocated
--	uint32_t bufs_allocated;
--
--	/// Position in the bufs array. The next buffer to be taken
--	/// into use is bufs[bufs_pos].
--	uint32_t bufs_pos;
--
--	/// Number of buffers in use
--	uint32_t bufs_used;
--
--	/// Position in the buffer in lzma_outq_read()
--	size_t read_pos;
--
--} lzma_outq;
--
--
--/**
-- * \brief       Calculate the memory usage of an output queue
-- *
-- * \return      Approximate memory usage in bytes or UINT64_MAX on error.
-- */
--extern uint64_t lzma_outq_memusage(uint64_t buf_size_max, uint32_t threads);
--
--
--/// \brief      Initialize an output queue
--///
--/// \param      outq            Pointer to an output queue. Before calling
--///                             this function the first time, *outq should
--///                             have been zeroed with memzero() so that this
--///                             function knows that there are no previous
--///                             allocations to free.
--/// \param      allocator       Pointer to allocator or NULL
--/// \param      buf_size_max    Maximum amount of data that a single buffer
--///                             in the queue may need to store.
--/// \param      threads         Number of buffers that may be in use
--///                             concurrently. Note that more than this number
--///                             of buffers will actually get allocated to
--///                             improve performance when buffers finish
--///                             out of order.
--///
--/// \return     - LZMA_OK
--///             - LZMA_MEM_ERROR
--///
--extern lzma_ret lzma_outq_init(lzma_outq *outq, lzma_allocator *allocator,
--		uint64_t buf_size_max, uint32_t threads);
--
--
--/// \brief      Free the memory associated with the output queue
--extern void lzma_outq_end(lzma_outq *outq, lzma_allocator *allocator);
--
--
--/// \brief      Get a new buffer
--///
--/// lzma_outq_has_buf() must be used to check that there is a buffer
--/// available before calling lzma_outq_get_buf().
--///
--extern lzma_outbuf *lzma_outq_get_buf(lzma_outq *outq);
--
--
--/// \brief      Test if there is data ready to be read
--///
--/// Call to this function must be protected with the same mutex that
--/// is used to protect lzma_outbuf.finished.
--///
--extern bool lzma_outq_is_readable(const lzma_outq *outq);
--
--
--/// \brief      Read finished data
--///
--/// \param      outq            Pointer to an output queue
--/// \param      out             Beginning of the output buffer
--/// \param      out_pos         The next byte will be written to
--///                             out[*out_pos].
--/// \param      out_size        Size of the out buffer; the first byte into
--///                             which no data is written to is out[out_size].
--/// \param      unpadded_size   Unpadded Size from the Block encoder
--/// \param      uncompressed_size Uncompressed Size from the Block encoder
--///
--/// \return     - LZMA: All OK. Either no data was available or the buffer
--///               being read didn't become empty yet.
--///             - LZMA_STREAM_END: The buffer being read was finished.
--///               *unpadded_size and *uncompressed_size were set.
--///
--/// \note       This reads lzma_outbuf.finished variables and thus call
--///             to this function needs to be protected with a mutex.
--///
--extern lzma_ret lzma_outq_read(lzma_outq *restrict outq,
--		uint8_t *restrict out, size_t *restrict out_pos,
--		size_t out_size, lzma_vli *restrict unpadded_size,
--		lzma_vli *restrict uncompressed_size);
--
--
--/// \brief      Test if there is at least one buffer free
--///
--/// This must be used before getting a new buffer with lzma_outq_get_buf().
--///
--static inline bool
--lzma_outq_has_buf(const lzma_outq *outq)
--{
--	return outq->bufs_used < outq->bufs_allocated;
--}
--
--
--/// \brief      Test if the queue is completely empty
--static inline bool
--lzma_outq_is_empty(const lzma_outq *outq)
--{
--	return outq->bufs_used == 0;
--}
-diff --git a/src/liblzma/common/stream_encoder_mt.c b/src/liblzma/common/stream_encoder_mt.c
-deleted file mode 100644
-index a4b2800..0000000
---- a/src/liblzma/common/stream_encoder_mt.c
-+++ /dev/null
-@@ -1,1013 +0,0 @@
--///////////////////////////////////////////////////////////////////////////////
--//
--/// \file       stream_encoder_mt.c
--/// \brief      Multithreaded .xz Stream encoder
--//
--//  Author:     Lasse Collin
--//
--//  This file has been put into the public domain.
--//  You can do whatever you want with this file.
--//
--///////////////////////////////////////////////////////////////////////////////
--
--#include "filter_encoder.h"
--#include "easy_preset.h"
--#include "block_encoder.h"
--#include "index_encoder.h"
--#include "outqueue.h"
--
--
--/// Maximum supported block size. This makes it simpler to prevent integer
--/// overflows if we are given unusually large block size.
--#define BLOCK_SIZE_MAX (UINT64_MAX / LZMA_THREADS_MAX)
--
--
--typedef enum {
--	/// Waiting for work.
--	THR_IDLE,
--
--	/// Encoding is in progress.
--	THR_RUN,
--
--	/// Encoding is in progress but no more input data will
--	/// be read.
--	THR_FINISH,
--
--	/// The main thread wants the thread to stop whatever it was doing
--	/// but not exit.
--	THR_STOP,
--
--	/// The main thread wants the thread to exit. We could use
--	/// cancellation but since there's stopped anyway, this is lazier.
--	THR_EXIT,
--
--} worker_state;
--
--
--typedef struct worker_thread_s worker_thread;
--struct worker_thread_s {
--	worker_state state;
--
--	/// Input buffer of coder->block_size bytes. The main thread will
--	/// put new input into this and update in_size accordingly. Once
--	/// no more input is coming, state will be set to THR_FINISH.
--	uint8_t *in;
--
--	/// Amount of data available in the input buffer. This is modified
--	/// only by the main thread.
--	size_t in_size;
--
--	/// Output buffer for this thread. This is set by the main
--	/// thread every time a new Block is started with this thread
--	/// structure.
--	lzma_outbuf *outbuf;
--
--	/// Pointer to the main structure is needed when putting this
--	/// thread back to the stack of free threads.
--	lzma_coder *coder;
--
--	/// The allocator is set by the main thread. Since a copy of the
--	/// pointer is kept here, the application must not change the
--	/// allocator before calling lzma_end().
--	lzma_allocator *allocator;
--
--	/// Block encoder
--	lzma_next_coder block_encoder;
--
--	/// Compression options for this Block
--	lzma_block block_options;
--
--	/// Next structure in the stack of free worker threads.
--	worker_thread *next;
--
--	pthread_mutex_t mutex;
--	pthread_cond_t cond;
--
--	/// The ID of this thread is used to join the thread
--	/// when it's not needed anymore.
--	pthread_t thread_id;
--};
--
--
--struct lzma_coder_s {
--	enum {
--		SEQ_STREAM_HEADER,
--		SEQ_BLOCK,
--		SEQ_INDEX,
--		SEQ_STREAM_FOOTER,
--	} sequence;
--
--	/// Start a new Block every block_size bytes of input unless
--	/// LZMA_FULL_FLUSH or LZMA_FULL_BARRIER is used earlier.
--	size_t block_size;
--
--	/// The filter chain currently in use
--	lzma_filter filters[LZMA_FILTERS_MAX + 1];
--
--
--	/// Index to hold sizes of the Blocks
--	lzma_index *index;
--
--	/// Index encoder
--	lzma_next_coder index_encoder;
--
--
--	/// Stream Flags for encoding the Stream Header and Stream Footer.
--	lzma_stream_flags stream_flags;
--
--	/// Buffer to hold Stream Header and Stream Footer.
--	uint8_t header[LZMA_STREAM_HEADER_SIZE];
--
--	/// Read position in header[]
--	size_t header_pos;
--
--
--	/// Output buffer queue for compressed data
--	lzma_outq outq;
--
--
--	/// True if wait_max is used.
--	bool has_timeout;
--
--	/// Maximum wait time if cannot use all the input and cannot
--	/// fill the output buffer.
--	struct timespec wait_max;
--
--
--	/// Error code from a worker thread
--	lzma_ret thread_error;
--
--	/// Array of allocated thread-specific structures
--	worker_thread *threads;
--
--	/// Number of structures in "threads" above. This is also the
--	/// number of threads that will be created at maximum.
--	uint32_t threads_max;
--
--	/// Number of thread structures that have been initialized, and
--	/// thus the number of worker threads actually created so far.
--	uint32_t threads_initialized;
--
--	/// Stack of free threads. When a thread finishes, it puts itself
--	/// back into this stack. This starts as empty because threads
--	/// are created only when actually needed.
--	worker_thread *threads_free;
--
--	/// The most recent worker thread to which the main thread writes
--	/// the new input from the application.
--	worker_thread *thr;
--
--	pthread_mutex_t mutex;
--	mythread_cond cond;
--};
--
--
--/// Tell the main thread that something has gone wrong.
--static void
--worker_error(worker_thread *thr, lzma_ret ret)
--{
--	assert(ret != LZMA_OK);
--	assert(ret != LZMA_STREAM_END);
--
--	mythread_sync(thr->coder->mutex) {
--		if (thr->coder->thread_error == LZMA_OK)
--			thr->coder->thread_error = ret;
--
--		mythread_cond_signal(&thr->coder->cond);
--	}
--
--	return;
--}
--
--
--static worker_state
--worker_encode(worker_thread *thr, worker_state state)
--{
--	// Set the Block options.
--	thr->block_options = (lzma_block){
--		.version = 0,
--		.check = thr->coder->stream_flags.check,
--		.compressed_size = thr->coder->outq.buf_size_max,
--		.uncompressed_size = thr->coder->block_size,
--
--		// TODO: To allow changing the filter chain, the filters
--		// array must be copied to each worker_thread.
--		.filters = thr->coder->filters,
--	};
--
--	// Calculate maximum size of the Block Header. This amount is
--	// reserved in the beginning of the buffer so that Block Header
--	// along with Compressed Size and Uncompressed Size can be
--	// written there.
--	lzma_ret ret = lzma_block_header_size(&thr->block_options);
--	if (ret != LZMA_OK) {
--		worker_error(thr, ret);
--		return THR_STOP;
--	}
--
--	// Initialize the Block encoder.
--	ret = lzma_block_encoder_init(&thr->block_encoder,
--			thr->allocator, &thr->block_options);
--	if (ret != LZMA_OK) {
--		worker_error(thr, ret);
--		return THR_STOP;
--	}
--
--	size_t in_pos = 0;
--	size_t in_size = 0;
--
--	thr->outbuf->size = thr->block_options.header_size;
--	const size_t out_size = thr->coder->outq.buf_size_max;
--
--	do {
--		mythread_sync(thr->mutex) {
--			while (in_size == thr->in_size
--					&& thr->state == THR_RUN)
--				pthread_cond_wait(&thr->cond, &thr->mutex);
--
--			state = thr->state;
--			in_size = thr->in_size;
--
--			// TODO? Store in_pos and out_pos into *thr here
--			// so that the application may read them via
--			// some currently non-existing function to get
--			// progress information.
--		}
--
--		// Return if we were asked to stop or exit.
--		if (state >= THR_STOP)
--			return state;
--
--		lzma_action action = state == THR_FINISH
--				? LZMA_FINISH : LZMA_RUN;
--
--		// Limit the amount of input given to the Block encoder
--		// at once. This way this thread can react fairly quickly
--		// if the main thread wants us to stop or exit.
--		static const size_t in_chunk_max = 16384;
--		size_t in_limit = in_size;
--		if (in_size - in_pos > in_chunk_max) {
--			in_limit = in_pos + in_chunk_max;
--			action = LZMA_RUN;
--		}
--
--		ret = thr->block_encoder.code(
--				thr->block_encoder.coder, thr->allocator,
--				thr->in, &in_pos, in_limit, thr->outbuf->buf,
--				&thr->outbuf->size, out_size, action);
--	} while (ret == LZMA_OK);
--
--	if (ret != LZMA_STREAM_END) {
--		worker_error(thr, ret);
--		return THR_STOP;
--	}
--
--	assert(state == THR_FINISH);
--
--	// Encode the Block Header. By doing it after the compression,
--	// we can store the Compressed Size and Uncompressed Size fields.
--	ret = lzma_block_header_encode(&thr->block_options, thr->outbuf->buf);
--	if (ret != LZMA_OK) {
--		worker_error(thr, ret);
--		return THR_STOP;
--	}
--
--	// Set the size information that will be read by the main thread
--	// to write the Index field.
--	thr->outbuf->unpadded_size
--			= lzma_block_unpadded_size(&thr->block_options);
--	assert(thr->outbuf->unpadded_size != 0);
--	thr->outbuf->uncompressed_size = thr->block_options.uncompressed_size;
--
--	return THR_FINISH;
--}
--
--
--static void *
--worker_start(void *thr_ptr)
--{
--	worker_thread *thr = thr_ptr;
--	worker_state state = THR_IDLE; // Init to silence a warning
--
--	while (true) {
--		// Wait for work.
--		mythread_sync(thr->mutex) {
--			while (true) {
--				// The thread is already idle so if we are
--				// requested to stop, just set the state.
--				if (thr->state == THR_STOP) {
--					thr->state = THR_IDLE;
--					pthread_cond_signal(&thr->cond);
--				}
--
--				state = thr->state;
--				if (state != THR_IDLE)
--					break;
--
--				pthread_cond_wait(&thr->cond, &thr->mutex);
--			}
--		}
--
--		assert(state != THR_IDLE);
--		assert(state != THR_STOP);
--
--		if (state <= THR_FINISH)
--			state = worker_encode(thr, state);
--
--		if (state == THR_EXIT)
--			break;
--
--		// Mark the thread as idle. Signal is needed for the case
--		// where the main thread is waiting for the threads to stop.
--		mythread_sync(thr->mutex) {
--			thr->state = THR_IDLE;
--			pthread_cond_signal(&thr->cond);
--		}
--
--		mythread_sync(thr->coder->mutex) {
--			// Mark the output buffer as finished if
--			// no errors occurred.
--			thr->outbuf->finished = state == THR_FINISH;
--
--			// Return this thread to the stack of free threads.
--			thr->next = thr->coder->threads_free;
--			thr->coder->threads_free = thr;
--
--			mythread_cond_signal(&thr->coder->cond);
--		}
--	}
--
--	// Exiting, free the resources.
--	pthread_mutex_destroy(&thr->mutex);
--	pthread_cond_destroy(&thr->cond);
--
--	lzma_next_end(&thr->block_encoder, thr->allocator);
--	lzma_free(thr->in, thr->allocator);
--	return NULL;
--}
--
--
--/// Make the threads stop but not exit. Optionally wait for them to stop.
--static void
--threads_stop(lzma_coder *coder, bool wait)
--{
--	// Tell the threads to stop.
--	for (uint32_t i = 0; i < coder->threads_initialized; ++i) {
--		mythread_sync(coder->threads[i].mutex) {
--			coder->threads[i].state = THR_STOP;
--			pthread_cond_signal(&coder->threads[i].cond);
--		}
--	}
--
--	if (!wait)
--		return;
--
--	// Wait for the threads to settle in the idle state.
--	for (uint32_t i = 0; i < coder->threads_initialized; ++i) {
--		mythread_sync(coder->threads[i].mutex) {
--			while (coder->threads[i].state != THR_IDLE)
--				pthread_cond_wait(&coder->threads[i].cond,
--						&coder->threads[i].mutex);
--		}
--	}
--
--	return;
--}
--
--
--/// Stop the threads and free the resources associated with them.
--/// Wait until the threads have exited.
--static void
--threads_end(lzma_coder *coder, lzma_allocator *allocator)
--{
--	for (uint32_t i = 0; i < coder->threads_initialized; ++i) {
--		mythread_sync(coder->threads[i].mutex) {
--			coder->threads[i].state = THR_EXIT;
--			pthread_cond_signal(&coder->threads[i].cond);
--		}
--	}
--
--	for (uint32_t i = 0; i < coder->threads_initialized; ++i) {
--		int ret = pthread_join(coder->threads[i].thread_id, NULL);
--		assert(ret == 0);
--		(void)ret;
--	}
--
--	lzma_free(coder->threads, allocator);
--	return;
--}
--
--
--/// Initialize a new worker_thread structure and create a new thread.
--static lzma_ret
--initialize_new_thread(lzma_coder *coder, lzma_allocator *allocator)
--{
--	worker_thread *thr = &coder->threads[coder->threads_initialized];
--
--	thr->in = lzma_alloc(coder->block_size, allocator);
--	if (thr->in == NULL)
--		return LZMA_MEM_ERROR;
--
--	if (pthread_mutex_init(&thr->mutex, NULL))
--		goto error_mutex;
--
--	if (pthread_cond_init(&thr->cond, NULL))
--		goto error_cond;
--
--	thr->state = THR_IDLE;
--	thr->allocator = allocator;
--	thr->coder = coder;
--	thr->block_encoder = LZMA_NEXT_CODER_INIT;
--
--	if (mythread_create(&thr->thread_id, &worker_start, thr))
--		goto error_thread;
--
--	++coder->threads_initialized;
--	coder->thr = thr;
--
--	return LZMA_OK;
--
--error_thread:
--	pthread_cond_destroy(&thr->cond);
--
--error_cond:
--	pthread_mutex_destroy(&thr->mutex);
--
--error_mutex:
--	lzma_free(thr->in, allocator);
--	return LZMA_MEM_ERROR;
--}
--
--
--static lzma_ret
--get_thread(lzma_coder *coder, lzma_allocator *allocator)
--{
--	// If there are no free output subqueues, there is no
--	// point to try getting a thread.
--	if (!lzma_outq_has_buf(&coder->outq))
--		return LZMA_OK;
--
--	// If there is a free structure on the stack, use it.
--	mythread_sync(coder->mutex) {
--		if (coder->threads_free != NULL) {
--			coder->thr = coder->threads_free;
--			coder->threads_free = coder->threads_free->next;
--		}
--	}
--
--	if (coder->thr == NULL) {
--		// If there are no uninitialized structures left, return.
--		if (coder->threads_initialized == coder->threads_max)
--			return LZMA_OK;
--
--		// Initialize a new thread.
--		return_if_error(initialize_new_thread(coder, allocator));
--	}
--
--	// Reset the parts of the thread state that have to be done
--	// in the main thread.
--	mythread_sync(coder->thr->mutex) {
--		coder->thr->state = THR_RUN;
--		coder->thr->in_size = 0;
--		coder->thr->outbuf = lzma_outq_get_buf(&coder->outq);
--		pthread_cond_signal(&coder->thr->cond);
--	}
--
--	return LZMA_OK;
--}
--
--
--static lzma_ret
--stream_encode_in(lzma_coder *coder, lzma_allocator *allocator,
--		const uint8_t *restrict in, size_t *restrict in_pos,
--		size_t in_size, lzma_action action)
--{
--	while (*in_pos < in_size
--			|| (coder->thr != NULL && action != LZMA_RUN)) {
--		if (coder->thr == NULL) {
--			// Get a new thread.
--			const lzma_ret ret = get_thread(coder, allocator);
--			if (coder->thr == NULL)
--				return ret;
--		}
--
--		// Copy the input data to thread's buffer.
--		size_t thr_in_size = coder->thr->in_size;
--		lzma_bufcpy(in, in_pos, in_size, coder->thr->in,
--				&thr_in_size, coder->block_size);
--
--		// Tell the Block encoder to finish if
--		//  - it has got block_size bytes of input; or
--		//  - all input was used and LZMA_FINISH, LZMA_FULL_FLUSH,
--		//    or LZMA_FULL_BARRIER was used.
--		//
--		// TODO: LZMA_SYNC_FLUSH and LZMA_SYNC_BARRIER.
--		const bool finish = thr_in_size == coder->block_size
--				|| (*in_pos == in_size && action != LZMA_RUN);
--
--		bool block_error = false;
--
--		mythread_sync(coder->thr->mutex) {
--			if (coder->thr->state == THR_IDLE) {
--				// Something has gone wrong with the Block
--				// encoder. It has set coder->thread_error
--				// which we will read a few lines later.
--				block_error = true;
--			} else {
--				// Tell the Block encoder its new amount
--				// of input and update the state if needed.
--				coder->thr->in_size = thr_in_size;
--
--				if (finish)
--					coder->thr->state = THR_FINISH;
--
--				pthread_cond_signal(&coder->thr->cond);
--			}
--		}
--
--		if (block_error) {
--			lzma_ret ret;
--
--			mythread_sync(coder->mutex) {
--				ret = coder->thread_error;
--			}
--
--			return ret;
--		}
--
--		if (finish)
--			coder->thr = NULL;
--	}
--
--	return LZMA_OK;
--}
--
--
--/// Wait until more input can be consumed, more output can be read, or
--/// an optional timeout is reached.
--static bool
--wait_for_work(lzma_coder *coder, struct timespec *wait_abs,
--		bool *has_blocked, bool has_input)
--{
--	if (coder->has_timeout && !*has_blocked) {
--		// Every time when stream_encode_mt() is called via
--		// lzma_code(), *has_block starts as false. We set it
--		// to true here and calculate the absolute time when
--		// we must return if there's nothing to do.
--		//
--		// The idea of *has_blocked is to avoid unneeded calls
--		// to mythread_cond_abstime(), which may do a syscall
--		// depending on the operating system.
--		*has_blocked = true;
--		*wait_abs = coder->wait_max;
--		mythread_cond_abstime(&coder->cond, wait_abs);
--	}
--
--	bool timed_out = false;
--
--	mythread_sync(coder->mutex) {
--		// There are four things that we wait. If one of them
--		// becomes possible, we return.
--		//  - If there is input left, we need to get a free
--		//    worker thread and an output buffer for it.
--		//  - Data ready to be read from the output queue.
--		//  - A worker thread indicates an error.
--		//  - Time out occurs.
--		while ((!has_input || coder->threads_free == NULL
--					|| !lzma_outq_has_buf(&coder->outq))
--				&& !lzma_outq_is_readable(&coder->outq)
--				&& coder->thread_error == LZMA_OK
--				&& !timed_out) {
--			if (coder->has_timeout)
--				timed_out = mythread_cond_timedwait(
--						&coder->cond, &coder->mutex,
--						wait_abs) != 0;
--			else
--				mythread_cond_wait(&coder->cond,
--						&coder->mutex);
--		}
--	}
--
--	return timed_out;
--}
--
--
--static lzma_ret
--stream_encode_mt(lzma_coder *coder, lzma_allocator *allocator,
--		const uint8_t *restrict in, size_t *restrict in_pos,
--		size_t in_size, uint8_t *restrict out,
--		size_t *restrict out_pos, size_t out_size, lzma_action action)
--{
--	switch (coder->sequence) {
--	case SEQ_STREAM_HEADER:
--		lzma_bufcpy(coder->header, &coder->header_pos,
--				sizeof(coder->header),
--				out, out_pos, out_size);
--		if (coder->header_pos < sizeof(coder->header))
--			return LZMA_OK;
--
--		coder->header_pos = 0;
--		coder->sequence = SEQ_BLOCK;
--
--	// Fall through
--
--	case SEQ_BLOCK: {
--		// Initialized to silence warnings.
--		lzma_vli unpadded_size = 0;
--		lzma_vli uncompressed_size = 0;
--		lzma_ret ret = LZMA_OK;
--
--		// These are for wait_for_work().
--		bool has_blocked = false;
--		struct timespec wait_abs;
--
--		while (true) {
--			mythread_sync(coder->mutex) {
--				// Check for Block encoder errors.
--				ret = coder->thread_error;
--				if (ret != LZMA_OK) {
--					assert(ret != LZMA_STREAM_END);
--					break;
--				}
--
--				// Try to read compressed data to out[].
--				ret = lzma_outq_read(&coder->outq,
--						out, out_pos, out_size,
--						&unpadded_size,
--						&uncompressed_size);
--			}
--
--			if (ret == LZMA_STREAM_END) {
--				// End of Block. Add it to the Index.
--				ret = lzma_index_append(coder->index,
--						allocator, unpadded_size,
--						uncompressed_size);
--
--				// If we didn't fill the output buffer yet,
--				// try to read more data. Maybe the next
--				// outbuf has been finished already too.
--				if (*out_pos < out_size)
--					continue;
--			}
--
--			if (ret != LZMA_OK) {
--				// coder->thread_error was set or
--				// lzma_index_append() failed.
--				threads_stop(coder, false);
--				return ret;
--			}
--
--			// Check if the last Block was finished.
--			if (action == LZMA_FINISH
--					&& *in_pos == in_size
--					&& lzma_outq_is_empty(
--						&coder->outq))
--				break;
--
--			// Try to give uncompressed data to a worker thread.
--			ret = stream_encode_in(coder, allocator,
--					in, in_pos, in_size, action);
--			if (ret != LZMA_OK) {
--				threads_stop(coder, false);
--				return ret;
--			}
--
--			// Return if
--			//  - we have used all the input and expect to
--			//    get more input; or
--			//  - the output buffer has been filled.
--			//
--			// TODO: Support flushing.
--			if ((*in_pos == in_size && action != LZMA_FINISH)
--					|| *out_pos == out_size)
--				return LZMA_OK;
--
--			// Neither in nor out has been used completely.
--			// Wait until there's something we can do.
--			if (wait_for_work(coder, &wait_abs, &has_blocked,
--					*in_pos < in_size))
--				return LZMA_TIMED_OUT;
--		}
--
--		// All Blocks have been encoded and the threads have stopped.
--		// Prepare to encode the Index field.
--		return_if_error(lzma_index_encoder_init(
--				&coder->index_encoder, allocator,
--				coder->index));
--		coder->sequence = SEQ_INDEX;
--	}
--
--	// Fall through
--
--	case SEQ_INDEX: {
--		// Call the Index encoder. It doesn't take any input, so
--		// those pointers can be NULL.
--		const lzma_ret ret = coder->index_encoder.code(
--				coder->index_encoder.coder, allocator,
--				NULL, NULL, 0,
--				out, out_pos, out_size, LZMA_RUN);
--		if (ret != LZMA_STREAM_END)
--			return ret;
--
--		// Encode the Stream Footer into coder->buffer.
--		coder->stream_flags.backward_size
--				= lzma_index_size(coder->index);
--		if (lzma_stream_footer_encode(&coder->stream_flags,
--				coder->header) != LZMA_OK)
--			return LZMA_PROG_ERROR;
--
--		coder->sequence = SEQ_STREAM_FOOTER;
--	}
--
--	// Fall through
--
--	case SEQ_STREAM_FOOTER:
--		lzma_bufcpy(coder->header, &coder->header_pos,
--				sizeof(coder->header),
--				out, out_pos, out_size);
--		return coder->header_pos < sizeof(coder->header)
--				? LZMA_OK : LZMA_STREAM_END;
--	}
--
--	assert(0);
--	return LZMA_PROG_ERROR;
--}
--
--
--static void
--stream_encoder_mt_end(lzma_coder *coder, lzma_allocator *allocator)
--{
--	// Threads must be killed before the output queue can be freed.
--	threads_end(coder, allocator);
--	lzma_outq_end(&coder->outq, allocator);
--
--	for (size_t i = 0; coder->filters[i].id != LZMA_VLI_UNKNOWN; ++i)
--		lzma_free(coder->filters[i].options, allocator);
--
--	lzma_next_end(&coder->index_encoder, allocator);
--	lzma_index_end(coder->index, allocator);
--
--	mythread_cond_destroy(&coder->cond);
--	pthread_mutex_destroy(&coder->mutex);
--
--	lzma_free(coder, allocator);
--	return;
--}
--
--
--/// Options handling for lzma_stream_encoder_mt_init() and
--/// lzma_stream_encoder_mt_memusage()
--static lzma_ret
--get_options(const lzma_mt *options, lzma_options_easy *opt_easy,
--		const lzma_filter **filters, uint64_t *block_size,
--		uint64_t *outbuf_size_max)
--{
--	// Validate some of the options.
--	if (options == NULL)
--		return LZMA_PROG_ERROR;
--
--	if (options->flags != 0 || options->threads == 0
--			|| options->threads > LZMA_THREADS_MAX)
--		return LZMA_OPTIONS_ERROR;
--
--	if (options->filters != NULL) {
--		// Filter chain was given, use it as is.
--		*filters = options->filters;
--	} else {
--		// Use a preset.
--		if (lzma_easy_preset(opt_easy, options->preset))
--			return LZMA_OPTIONS_ERROR;
--
--		*filters = opt_easy->filters;
--	}
--
--	// Block size
--	if (options->block_size > 0) {
--		if (options->block_size > BLOCK_SIZE_MAX)
--			return LZMA_OPTIONS_ERROR;
--
--		*block_size = options->block_size;
--	} else {
--		// Determine the Block size from the filter chain.
--		*block_size = lzma_mt_block_size(*filters);
--		if (*block_size == 0)
--			return LZMA_OPTIONS_ERROR;
--
--		assert(*block_size <= BLOCK_SIZE_MAX);
--	}
--
--	// Calculate the maximum amount output that a single output buffer
--	// may need to hold. This is the same as the maximum total size of
--	// a Block.
--	//
--	// FIXME: As long as the encoder keeps the whole input buffer
--	// available and doesn't start writing output before finishing
--	// the Block, it could use lzma_stream_buffer_bound() and use
--	// uncompressed LZMA2 chunks if the data doesn't compress.
--	*outbuf_size_max = *block_size + *block_size / 16 + 16384;
--
--	return LZMA_OK;
--}
--
--
--static lzma_ret
--stream_encoder_mt_init(lzma_next_coder *next, lzma_allocator *allocator,
--		const lzma_mt *options)
--{
--	lzma_next_coder_init(&stream_encoder_mt_init, next, allocator);
--
--	// Get the filter chain.
--	lzma_options_easy easy;
--	const lzma_filter *filters;
--	uint64_t block_size;
--	uint64_t outbuf_size_max;
--	return_if_error(get_options(options, &easy, &filters,
--			&block_size, &outbuf_size_max));
--
--#if SIZE_MAX < UINT64_MAX
--	if (block_size > SIZE_MAX)
--		return LZMA_MEM_ERROR;
--#endif
--
--	// FIXME TODO: Validate the filter chain so that we can give
--	// an error in this function instead of delaying it to the first
--	// call to lzma_code().
--
--	// Validate the Check ID.
--	if ((unsigned int)(options->check) > LZMA_CHECK_ID_MAX)
--		return LZMA_PROG_ERROR;
--
--	if (!lzma_check_is_supported(options->check))
--		return LZMA_UNSUPPORTED_CHECK;
--
--	// Allocate and initialize the base structure if needed.
--	if (next->coder == NULL) {
--		next->coder = lzma_alloc(sizeof(lzma_coder), allocator);
--		if (next->coder == NULL)
--			return LZMA_MEM_ERROR;
--
--		// For the mutex and condition variable initializations
--		// the error handling has to be done here because
--		// stream_encoder_mt_end() doesn't know if they have
--		// already been initialized or not.
--		if (pthread_mutex_init(&next->coder->mutex, NULL)) {
--			lzma_free(next->coder, allocator);
--			next->coder = NULL;
--			return LZMA_MEM_ERROR;
--		}
--
--		if (mythread_cond_init(&next->coder->cond)) {
--			pthread_mutex_destroy(&next->coder->mutex);
--			lzma_free(next->coder, allocator);
--			next->coder = NULL;
--			return LZMA_MEM_ERROR;
--		}
--
--		next->code = &stream_encode_mt;
--		next->end = &stream_encoder_mt_end;
--// 		next->update = &stream_encoder_mt_update;
--
--		next->coder->filters[0].id = LZMA_VLI_UNKNOWN;
--		next->coder->index_encoder = LZMA_NEXT_CODER_INIT;
--		next->coder->index = NULL;
--		memzero(&next->coder->outq, sizeof(next->coder->outq));
--		next->coder->threads = NULL;
--		next->coder->threads_max = 0;
--		next->coder->threads_initialized = 0;
--	}
--
--	// Basic initializations
--	next->coder->sequence = SEQ_STREAM_HEADER;
--	next->coder->block_size = (size_t)(block_size);
--	next->coder->thread_error = LZMA_OK;
--	next->coder->thr = NULL;
--
--	// Allocate the thread-specific base structures.
--	assert(options->threads > 0);
--	if (next->coder->threads_max != options->threads) {
--		threads_end(next->coder, allocator);
--
--		next->coder->threads = NULL;
--		next->coder->threads_max = 0;
--
--		next->coder->threads_initialized = 0;
--		next->coder->threads_free = NULL;
--
--		next->coder->threads = lzma_alloc(
--				options->threads * sizeof(worker_thread),
--				allocator);
--		if (next->coder->threads == NULL)
--			return LZMA_MEM_ERROR;
--
--		next->coder->threads_max = options->threads;
--	} else {
--		// Reuse the old structures and threads. Tell the running
--		// threads to stop and wait until they have stopped.
--		threads_stop(next->coder, true);
--	}
--
--	// Output queue
--	return_if_error(lzma_outq_init(&next->coder->outq, allocator,
--			outbuf_size_max, options->threads));
--
--	// Timeout
--	if (options->timeout > 0) {
--		next->coder->wait_max.tv_sec = options->timeout / 1000;
--		next->coder->wait_max.tv_nsec
--				= (options->timeout % 1000) * 1000000L;
--		next->coder->has_timeout = true;
--	} else {
--		next->coder->has_timeout = false;
--	}
--
--	// Free the old filter chain and copy the new one.
--	for (size_t i = 0; next->coder->filters[i].id != LZMA_VLI_UNKNOWN; ++i)
--		lzma_free(next->coder->filters[i].options, allocator);
--
--	return_if_error(lzma_filters_copy(options->filters,
--			next->coder->filters, allocator));
--
--	// Index
--	lzma_index_end(next->coder->index, allocator);
--	next->coder->index = lzma_index_init(allocator);
--	if (next->coder->index == NULL)
--		return LZMA_MEM_ERROR;
--
--	// Stream Header
--	next->coder->stream_flags.version = 0;
--	next->coder->stream_flags.check = options->check;
--	return_if_error(lzma_stream_header_encode(
--			&next->coder->stream_flags, next->coder->header));
--
--	next->coder->header_pos = 0;
--
--	return LZMA_OK;
--}
--
--
--extern LZMA_API(lzma_ret)
--lzma_stream_encoder_mt(lzma_stream *strm, const lzma_mt *options)
--{
--	lzma_next_strm_init(stream_encoder_mt_init, strm, options);
--
--	strm->internal->supported_actions[LZMA_RUN] = true;
--// 	strm->internal->supported_actions[LZMA_SYNC_FLUSH] = true;
--// 	strm->internal->supported_actions[LZMA_FULL_FLUSH] = true;
--// 	strm->internal->supported_actions[LZMA_FULL_BARRIER] = true;
--	strm->internal->supported_actions[LZMA_FINISH] = true;
--
--	return LZMA_OK;
--}
--
--
--// This function name is a monster but it's consistent with the older
--// monster names. :-( 31 chars is the max that C99 requires so in that
--// sense it's not too long. ;-)
--extern LZMA_API(uint64_t)
--lzma_stream_encoder_mt_memusage(const lzma_mt *options)
--{
--	lzma_options_easy easy;
--	const lzma_filter *filters;
--	uint64_t block_size;
--	uint64_t outbuf_size_max;
--
--	if (get_options(options, &easy, &filters, &block_size,
--			&outbuf_size_max) != LZMA_OK)
--		return UINT64_MAX;
--
--	// Memory usage of the input buffers
--	const uint64_t inbuf_memusage = options->threads * block_size;
--
--	// Memory usage of the filter encoders
--	uint64_t filters_memusage
--			= lzma_raw_encoder_memusage(options->filters);
--	if (filters_memusage == UINT64_MAX)
--		return UINT64_MAX;
--
--	filters_memusage *= options->threads;
--
--	// Memory usage of the output queue
--	const uint64_t outq_memusage = lzma_outq_memusage(
--			outbuf_size_max, options->threads);
--	if (outq_memusage == UINT64_MAX)
--		return UINT64_MAX;
--
--	// Sum them with overflow checking.
--	uint64_t total_memusage = LZMA_MEMUSAGE_BASE + sizeof(lzma_coder)
--			+ options->threads * sizeof(worker_thread);
--
--	if (UINT64_MAX - total_memusage < inbuf_memusage)
--		return UINT64_MAX;
--
--	total_memusage += inbuf_memusage;
--
--	if (UINT64_MAX - total_memusage < filters_memusage)
--		return UINT64_MAX;
--
--	total_memusage += filters_memusage;
--
--	if (UINT64_MAX - total_memusage < outq_memusage)
--		return UINT64_MAX;
--
--	return total_memusage + outq_memusage;
--}
-diff --git a/src/xz/args.c b/src/xz/args.c
-index dea93c5..f207e7f 100644
---- a/src/xz/args.c
-+++ b/src/xz/args.c
-@@ -179,9 +179,8 @@ parse_real(args_info *args, int argc, char **argv)
- 			break;
- 
- 		case 'T':
--			// The max is from src/liblzma/common/common.h.
--			hardware_threads_set(str_to_uint64("threads",
--					optarg, 0, 16384));
-+			hardware_threadlimit_set(str_to_uint64(
-+					"threads", optarg, 0, UINT32_MAX));
- 			break;
- 
- 		// --version
-diff --git a/src/xz/coder.c b/src/xz/coder.c
-index 41193a7..4139da4 100644
---- a/src/xz/coder.c
-+++ b/src/xz/coder.c
-@@ -55,14 +55,6 @@ static lzma_check check;
- /// This becomes false if the --check=CHECK option is used.
- static bool check_default = true;
- 
--#ifdef HAVE_PTHREAD
--static lzma_mt mt_options = {
--	.flags = 0,
--	.timeout = 300,
--	.filters = filters,
--};
--#endif
--
- 
- extern void
- coder_set_check(lzma_check new_check)
-@@ -125,15 +117,6 @@ memlimit_too_small(uint64_t memory_usage)
- extern void
- coder_set_compression_settings(void)
- {
--	// The default check type is CRC64, but fallback to CRC32
--	// if CRC64 isn't supported by the copy of liblzma we are
--	// using. CRC32 is always supported.
--	if (check_default) {
--		check = LZMA_CHECK_CRC64;
--		if (!lzma_check_is_supported(check))
--			check = LZMA_CHECK_CRC32;
--	}
--
- 	// Options for LZMA1 or LZMA2 in case we are using a preset.
- 	static lzma_options_lzma opt_lzma;
- 
-@@ -187,30 +170,15 @@ coder_set_compression_settings(void)
- 	// Print the selected filter chain.
- 	message_filters_show(V_DEBUG, filters);
- 
--	// Get the memory usage. Note that if --format=raw was used,
--	// we can be decompressing.
-+	// If using --format=raw, we can be decoding. The memusage function
-+	// also validates the filter chain and the options used for the
-+	// filters.
- 	const uint64_t memory_limit = hardware_memlimit_get(opt_mode);
- 	uint64_t memory_usage;
--	if (opt_mode == MODE_COMPRESS) {
--#ifdef HAVE_PTHREAD
--		if (opt_format == FORMAT_XZ && hardware_threads_get() > 1) {
--			mt_options.threads = hardware_threads_get();
--			mt_options.block_size = opt_block_size;
--			mt_options.check = check;
--			memory_usage = lzma_stream_encoder_mt_memusage(
--					&mt_options);
--			if (memory_usage != UINT64_MAX)
--				message(V_DEBUG, _("Using up to %" PRIu32
--						" threads."),
--						mt_options.threads);
--		} else
--#endif
--		{
--			memory_usage = lzma_raw_encoder_memusage(filters);
--		}
--	} else {
-+	if (opt_mode == MODE_COMPRESS)
-+		memory_usage = lzma_raw_encoder_memusage(filters);
-+	else
- 		memory_usage = lzma_raw_decoder_memusage(filters);
--	}
- 
- 	if (memory_usage == UINT64_MAX)
- 		message_fatal(_("Unsupported filter chain or filter options"));
-@@ -226,99 +194,90 @@ coder_set_compression_settings(void)
- 						round_up_to_mib(decmem), 0));
- 	}
- 
--	if (memory_usage <= memory_limit)
--		return;
-+	if (memory_usage > memory_limit) {
-+		// If --no-auto-adjust was used or we didn't find LZMA1 or
-+		// LZMA2 as the last filter, give an error immediately.
-+		// --format=raw implies --no-auto-adjust.
-+		if (!opt_auto_adjust || opt_format == FORMAT_RAW)
-+			memlimit_too_small(memory_usage);
- 
--	// If --no-auto-adjust was used or we didn't find LZMA1 or
--	// LZMA2 as the last filter, give an error immediately.
--	// --format=raw implies --no-auto-adjust.
--	if (!opt_auto_adjust || opt_format == FORMAT_RAW)
--		memlimit_too_small(memory_usage);
-+		assert(opt_mode == MODE_COMPRESS);
- 
--	assert(opt_mode == MODE_COMPRESS);
-+		// Look for the last filter if it is LZMA2 or LZMA1, so
-+		// we can make it use less RAM. With other filters we don't
-+		// know what to do.
-+		size_t i = 0;
-+		while (filters[i].id != LZMA_FILTER_LZMA2
-+				&& filters[i].id != LZMA_FILTER_LZMA1) {
-+			if (filters[i].id == LZMA_VLI_UNKNOWN)
-+				memlimit_too_small(memory_usage);
-+
-+			++i;
-+		}
- 
--#ifdef HAVE_PTHREAD
--	if (opt_format == FORMAT_XZ && mt_options.threads > 1) {
--		// Try to reduce the number of threads before
--		// adjusting the compression settings down.
--		do {
--			// FIXME? The real single-threaded mode has
--			// lower memory usage, but it's not comparable
--			// because it doesn't write the size info
--			// into Block Headers.
--			if (--mt_options.threads == 0)
-+		// Decrease the dictionary size until we meet the memory
-+		// usage limit. First round down to full mebibytes.
-+		lzma_options_lzma *opt = filters[i].options;
-+		const uint32_t orig_dict_size = opt->dict_size;
-+		opt->dict_size &= ~((UINT32_C(1) << 20) - 1);
-+		while (true) {
-+			// If it is below 1 MiB, auto-adjusting failed. We
-+			// could be more sophisticated and scale it down even
-+			// more, but let's see if many complain about this
-+			// version.
-+			//
-+			// FIXME: Displays the scaled memory usage instead
-+			// of the original.
-+			if (opt->dict_size < (UINT32_C(1) << 20))
- 				memlimit_too_small(memory_usage);
- 
--			memory_usage = lzma_stream_encoder_mt_memusage(
--					&mt_options);
-+			memory_usage = lzma_raw_encoder_memusage(filters);
- 			if (memory_usage == UINT64_MAX)
- 				message_bug();
- 
--		} while (memory_usage > memory_limit);
--
--		message(V_WARNING, _("Adjusted the number of threads "
--			"from %s to %s to not exceed "
--			"the memory usage limit of %s MiB"),
--			uint64_to_str(hardware_threads_get(), 0),
--			uint64_to_str(mt_options.threads, 1),
--			uint64_to_str(round_up_to_mib(
--				memory_limit), 2));
-+			// Accept it if it is low enough.
-+			if (memory_usage <= memory_limit)
-+				break;
-+
-+			// Otherwise 1 MiB down and try again. I hope this
-+			// isn't too slow method for cases where the original
-+			// dict_size is very big.
-+			opt->dict_size -= UINT32_C(1) << 20;
-+		}
-+
-+		// Tell the user that we decreased the dictionary size.
-+		message(V_WARNING, _("Adjusted LZMA%c dictionary size "
-+				"from %s MiB to %s MiB to not exceed "
-+				"the memory usage limit of %s MiB"),
-+				filters[i].id == LZMA_FILTER_LZMA2
-+					? '2' : '1',
-+				uint64_to_str(orig_dict_size >> 20, 0),
-+				uint64_to_str(opt->dict_size >> 20, 1),
-+				uint64_to_str(round_up_to_mib(
-+					memory_limit), 2));
- 	}
--#endif
--
--	if (memory_usage <= memory_limit)
--		return;
--
--	// Look for the last filter if it is LZMA2 or LZMA1, so we can make
--	// it use less RAM. With other filters we don't know what to do.
--	size_t i = 0;
--	while (filters[i].id != LZMA_FILTER_LZMA2
--			&& filters[i].id != LZMA_FILTER_LZMA1) {
--		if (filters[i].id == LZMA_VLI_UNKNOWN)
--			memlimit_too_small(memory_usage);
- 
--		++i;
-+/*
-+	// Limit the number of worker threads so that memory usage
-+	// limit isn't exceeded.
-+	assert(memory_usage > 0);
-+	size_t thread_limit = memory_limit / memory_usage;
-+	if (thread_limit == 0)
-+		thread_limit = 1;
-+
-+	if (opt_threads > thread_limit)
-+		opt_threads = thread_limit;
-+*/
-+
-+	if (check_default) {
-+		// The default check type is CRC64, but fallback to CRC32
-+		// if CRC64 isn't supported by the copy of liblzma we are
-+		// using. CRC32 is always supported.
-+		check = LZMA_CHECK_CRC64;
-+		if (!lzma_check_is_supported(check))
-+			check = LZMA_CHECK_CRC32;
- 	}
- 
--	// Decrease the dictionary size until we meet the memory
--	// usage limit. First round down to full mebibytes.
--	lzma_options_lzma *opt = filters[i].options;
--	const uint32_t orig_dict_size = opt->dict_size;
--	opt->dict_size &= ~((UINT32_C(1) << 20) - 1);
--	while (true) {
--		// If it is below 1 MiB, auto-adjusting failed. We could be
--		// more sophisticated and scale it down even more, but let's
--		// see if many complain about this version.
--		//
--		// FIXME: Displays the scaled memory usage instead
--		// of the original.
--		if (opt->dict_size < (UINT32_C(1) << 20))
--			memlimit_too_small(memory_usage);
--
--		memory_usage = lzma_raw_encoder_memusage(filters);
--		if (memory_usage == UINT64_MAX)
--			message_bug();
--
--		// Accept it if it is low enough.
--		if (memory_usage <= memory_limit)
--			break;
--
--		// Otherwise 1 MiB down and try again. I hope this
--		// isn't too slow method for cases where the original
--		// dict_size is very big.
--		opt->dict_size -= UINT32_C(1) << 20;
--	}
--
--	// Tell the user that we decreased the dictionary size.
--	message(V_WARNING, _("Adjusted LZMA%c dictionary size "
--			"from %s MiB to %s MiB to not exceed "
--			"the memory usage limit of %s MiB"),
--			filters[i].id == LZMA_FILTER_LZMA2
--				? '2' : '1',
--			uint64_to_str(orig_dict_size >> 20, 0),
--			uint64_to_str(opt->dict_size >> 20, 1),
--			uint64_to_str(round_up_to_mib(memory_limit), 2));
--
- 	return;
- }
- 
-@@ -400,14 +359,7 @@ coder_init(file_pair *pair)
- 			break;
- 
- 		case FORMAT_XZ:
--#ifdef HAVE_PTHREAD
--			if (hardware_threads_get() > 1)
--				ret = lzma_stream_encoder_mt(
--						&strm, &mt_options);
--			else
--#endif
--				ret = lzma_stream_encoder(
--						&strm, filters, check);
-+			ret = lzma_stream_encoder(&strm, filters, check);
- 			break;
- 
- 		case FORMAT_LZMA:
-@@ -528,8 +480,8 @@ coder_normal(file_pair *pair)
- 	// to the .xz format. If block_remaining == UINT64_MAX, only
- 	// a single block is created.
- 	uint64_t block_remaining = UINT64_MAX;
--	if (hardware_threads_get() == 1 && opt_mode == MODE_COMPRESS
--			&& opt_format == FORMAT_XZ && opt_block_size > 0)
-+	if (opt_mode == MODE_COMPRESS && opt_format == FORMAT_XZ
-+			&& opt_block_size > 0)
- 		block_remaining = opt_block_size;
- 
- 	strm.next_out = out_buf.u8;
-diff --git a/src/xz/hardware.c b/src/xz/hardware.c
-index 925926c..a4733c2 100644
---- a/src/xz/hardware.c
-+++ b/src/xz/hardware.c
-@@ -14,9 +14,9 @@
- #include "tuklib_cpucores.h"
- 
- 
--/// Maximum number of worker threads. This can be set with
-+/// Maximum number of free *coder* threads. This can be set with
- /// the --threads=NUM command line option.
--static uint32_t threads_max = 1;
-+static uint32_t threadlimit;
- 
- /// Memory usage limit for compression
- static uint64_t memlimit_compress;
-@@ -29,16 +29,15 @@ static uint64_t total_ram;
- 
- 
- extern void
--hardware_threads_set(uint32_t n)
-+hardware_threadlimit_set(uint32_t new_threadlimit)
- {
--	if (n == 0) {
--		// Automatic number of threads was requested.
--		// Use the number of available CPU cores.
--		threads_max = tuklib_cpucores();
--		if (threads_max == 0)
--			threads_max = 1;
-+	if (new_threadlimit == 0) {
-+		// The default is the number of available CPU cores.
-+		threadlimit = tuklib_cpucores();
-+		if (threadlimit == 0)
-+			threadlimit = 1;
- 	} else {
--		threads_max = n;
-+		threadlimit = new_threadlimit;
- 	}
- 
- 	return;
-@@ -46,9 +45,9 @@ hardware_threads_set(uint32_t n)
- 
- 
- extern uint32_t
--hardware_threads_get(void)
-+hardware_threadlimit_get(void)
- {
--	return threads_max;
-+	return threadlimit;
- }
- 
- 
-@@ -140,5 +139,6 @@ hardware_init(void)
- 
- 	// Set the defaults.
- 	hardware_memlimit_set(0, true, true, false);
-+	hardware_threadlimit_set(0);
- 	return;
- }
-diff --git a/src/xz/hardware.h b/src/xz/hardware.h
-index 4fae618..ad526f2 100644
---- a/src/xz/hardware.h
-+++ b/src/xz/hardware.h
-@@ -15,11 +15,12 @@
- extern void hardware_init(void);
- 
- 
--/// Set the maximum number of worker threads.
--extern void hardware_threads_set(uint32_t threadlimit);
-+/// Set custom value for maximum number of coder threads.
-+extern void hardware_threadlimit_set(uint32_t threadlimit);
- 
--/// Get the maximum number of worker threads.
--extern uint32_t hardware_threads_get(void);
-+/// Get the maximum number of coder threads. Some additional helper threads
-+/// are allowed on top of this).
-+extern uint32_t hardware_threadlimit_get(void);
- 
- 
- /// Set the memory usage limit. There are separate limits for compression
-diff --git a/src/xz/private.h b/src/xz/private.h
-index 978f81a..6b01e51 100644
---- a/src/xz/private.h
-+++ b/src/xz/private.h
-@@ -12,8 +12,6 @@
- 
- #include "sysdefs.h"
- #include "mythread.h"
--
--#define LZMA_UNSTABLE
- #include "lzma.h"
- 
- #include <sys/types.h>
-diff --git a/src/xz/xz.1 b/src/xz/xz.1
-index f4680f4..0329128 100644
---- a/src/xz/xz.1
-+++ b/src/xz/xz.1
-@@ -5,7 +5,7 @@
- .\" This file has been put into the public domain.
- .\" You can do whatever you want with this file.
- .\"
--.TH XZ 1 "2011-04-12" "Tukaani" "XZ Utils"
-+.TH XZ 1 "2011-04-11" "Tukaani" "XZ Utils"
- .
- .SH NAME
- xz, unxz, xzcat, lzma, unlzma, lzcat \- Compress or decompress .xz and .lzma files
-@@ -907,30 +907,24 @@ Automatic adjusting is always disabled when creating raw streams
- .TP
- \fB\-T\fR \fIthreads\fR, \fB\-\-threads=\fIthreads
- Specify the number of worker threads to use.
--Setting
--.I threads
--to a special value
--.B 0
--makes
--.B xz
--use as many threads as there are CPU cores on the system.
- The actual number of threads can be less than
- .I threads
--if the input file is not big enough
--for threading with the given settings or
- if using more threads would exceed the memory usage limit.
- .IP ""
--Currently the only threading method is to split the input into
--blocks and compress them independently from each other.
--The default block size depends on the compression level and
--can be overriden with the
--.BI \-\-block\-size= size
--option.
-+.B "Multithreaded compression and decompression are not"
-+.B "implemented yet, so this option has no effect for now."
- .IP ""
--.B "It is possible that the details of this option change before"
--.B "the next stable XZ Utils release."
--.B "This may include the meaning of the special value 0."
--.\" FIXME
-+.B "As of writing (2010-09-27), it hasn't been decided"
-+.B "if threads will be used by default on multicore systems"
-+.B "once support for threading has been implemented."
-+.B "Comments are welcome."
-+The complicating factor is that using many threads
-+will increase the memory usage dramatically.
-+Note that if multithreading will be the default,
-+it will probably be done so that single-threaded and
-+multithreaded modes produce the same output,
-+so compression ratio won't be significantly affected
-+if threading will be enabled by default.
- .
- .SS "Custom compressor filter chains"
- A custom filter chain allows specifying
--- 
-1.7.6
-
diff --git a/debian/patches/abi-version-script b/debian/patches/abi-version-script
deleted file mode 100644
index 2c5a2c4..0000000
--- a/debian/patches/abi-version-script
+++ /dev/null
@@ -1,44 +0,0 @@
-From: Jonathan Nieder <jrnieder@gmail.com>
-Date: Sat, 11 Jun 2011 23:33:43 -0500
-Subject: liblzma: Remove XZ_5.1.1alpha version symbol
-
-Now that the lzma_stream_encoder_mt{,_memusage} symbols are gone on
-this branch, liblzma should stop pretending to satisfy dependencies on
-XZ_5.1.1alpha.
-
-After this change, programs relying on those symbols will error out
-immediately at startup like they are supposed to:
-
-	app: liblzma.so.5: version `XZ_5.1.1alpha' not found (required by app)
-
-And your scripts that look for version definition entries with
-readelf -s (like RPM’s find-provides) can tell that this copy of
-liblzma lacks support for multithreaded encoding.
-
-Signed-off-by: Jonathan Nieder <jrnieder@gmail.com>
----
- src/liblzma/liblzma.map |    8 +-------
- 1 files changed, 1 insertions(+), 7 deletions(-)
-
-diff --git a/src/liblzma/liblzma.map b/src/liblzma/liblzma.map
-index 835eb26..47a7c22 100644
---- a/src/liblzma/liblzma.map
-+++ b/src/liblzma/liblzma.map
-@@ -93,13 +93,7 @@ global:
- 	lzma_vli_decode;
- 	lzma_vli_encode;
- 	lzma_vli_size;
--};
--
--XZ_5.1.1alpha {
--global:
--	lzma_stream_encoder_mt;
--	lzma_stream_encoder_mt_memusage;
- 
- local:
- 	*;
--} XZ_5.0;
-+};
--- 
-1.7.7
-
diff --git a/debian/patches/decoder-check-first-0x00 b/debian/patches/decoder-check-first-0x00
deleted file mode 100644
index 442e318..0000000
--- a/debian/patches/decoder-check-first-0x00
+++ /dev/null
@@ -1,69 +0,0 @@
-From: Lasse Collin <lasse.collin@tukaani.org>
-Date: Thu, 28 Jun 2012 10:47:49 +0300
-Subject: liblzma: Check that the first byte of range encoded data is 0x00.
-
-It is just to be more pedantic and thus perhaps catch broken
-files slightly earlier.
-
-Signed-off-by: Jonathan Nieder <jrnieder@gmail.com>
----
- src/liblzma/lzma/lzma_decoder.c        |    8 ++++++--
- src/liblzma/rangecoder/range_decoder.h |   12 +++++++++---
- 2 files changed, 15 insertions(+), 5 deletions(-)
-
-diff --git a/src/liblzma/lzma/lzma_decoder.c b/src/liblzma/lzma/lzma_decoder.c
-index 5abbc0d..b8f9317 100644
---- a/src/liblzma/lzma/lzma_decoder.c
-+++ b/src/liblzma/lzma/lzma_decoder.c
-@@ -289,8 +289,12 @@ lzma_decode(lzma_coder *restrict coder, lzma_dict *restrict dictptr,
- 	// Initialization //
- 	////////////////////
- 
--	if (!rc_read_init(&coder->rc, in, in_pos, in_size))
--		return LZMA_OK;
-+	{
-+		const lzma_ret ret = rc_read_init(
-+				&coder->rc, in, in_pos, in_size);
-+		if (ret != LZMA_STREAM_END)
-+			return ret;
-+	}
- 
- 	///////////////
- 	// Variables //
-diff --git a/src/liblzma/rangecoder/range_decoder.h b/src/liblzma/rangecoder/range_decoder.h
-index fb96180..e0b051f 100644
---- a/src/liblzma/rangecoder/range_decoder.h
-+++ b/src/liblzma/rangecoder/range_decoder.h
-@@ -25,20 +25,26 @@ typedef struct {
- 
- 
- /// Reads the first five bytes to initialize the range decoder.
--static inline bool
-+static inline lzma_ret
- rc_read_init(lzma_range_decoder *rc, const uint8_t *restrict in,
- 		size_t *restrict in_pos, size_t in_size)
- {
- 	while (rc->init_bytes_left > 0) {
- 		if (*in_pos == in_size)
--			return false;
-+			return LZMA_OK;
-+
-+		// The first byte is always 0x00. It could have been omitted
-+		// in LZMA2 but it wasn't, so one byte is wasted in every
-+		// LZMA2 chunk.
-+		if (rc->init_bytes_left == 5 && in[*in_pos] != 0x00)
-+			return LZMA_DATA_ERROR;
- 
- 		rc->code = (rc->code << 8) | in[*in_pos];
- 		++*in_pos;
- 		--rc->init_bytes_left;
- 	}
- 
--	return true;
-+	return LZMA_STREAM_END;
- }
- 
- 
--- 
-1.7.9.6 (Apple Git-31.1)
-
diff --git a/debian/patches/configure-liblzma2-compat b/debian/patches/liblzma-make-dlopen-based-liblzma2-compatibility-opt.patch
similarity index 86%
rename from debian/patches/configure-liblzma2-compat
rename to debian/patches/liblzma-make-dlopen-based-liblzma2-compatibility-opt.patch
index 46a9233..54617d9 100644
--- a/debian/patches/configure-liblzma2-compat
+++ b/debian/patches/liblzma-make-dlopen-based-liblzma2-compatibility-opt.patch
@@ -1,6 +1,10 @@
+From e284cfe27457239e932038fb90084c91f4229c36 Mon Sep 17 00:00:00 2001
 From: Jonathan Nieder <jrnieder@gmail.com>
 Date: Sat, 16 Jun 2012 05:57:42 -0500
 Subject: liblzma: make dlopen()-based liblzma2 compatibility optional
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
 
 Suppose I want to build a statically linked program:
 
@@ -49,20 +53,21 @@
    want your copy of liblzma to be usable by static libraries that
    were built against the old library.
 
+Patch-Name: liblzma-make-dlopen-based-liblzma2-compatibility-opt.patch
 Signed-off-by: Jonathan Nieder <jrnieder@gmail.com>
 ---
- configure.ac                |   33 +++++++++++++++++++++++++++++++--
- src/liblzma/common/common.c |   40 +++++++++++++++++++++++++++++++++++-----
- src/liblzma/common/common.h |    2 ++
+ configure.ac                | 33 +++++++++++++++++++++++++++++++--
+ src/liblzma/common/common.c | 40 +++++++++++++++++++++++++++++++++++-----
+ src/liblzma/common/common.h |  2 ++
  3 files changed, 68 insertions(+), 7 deletions(-)
 
 diff --git a/configure.ac b/configure.ac
-index cbf92659..eb510fd9 100644
+index 6dae0b9756d6..d17629e0e7f6 100644
 --- a/configure.ac
 +++ b/configure.ac
-@@ -468,10 +468,39 @@ if test "x$enable_threads" = xyes; then
- 	CFLAGS=$OLD_CFLAGS
- fi
+@@ -548,10 +548,39 @@ case $enable_threads in
+ esac
+ AM_CONDITIONAL([COND_THREADS], [test "x$enable_threads" != xno])
  
 -# As a Debian-specific hack, liblzma uses dlopen() to check if extra
 +# As a Debian-specific hack, liblzma can use dlopen() to check if extra
@@ -103,10 +108,10 @@
  echo
  echo "Initializing Libtool:"
 diff --git a/src/liblzma/common/common.c b/src/liblzma/common/common.c
-index e61d940d..3bfdb755 100644
+index 5474211cf0ca..79427b005b4b 100644
 --- a/src/liblzma/common/common.c
 +++ b/src/liblzma/common/common.c
-@@ -143,16 +143,46 @@ lzma_next_end(lzma_next_coder *next, lzma_allocator *allocator)
+@@ -164,16 +164,46 @@ lzma_next_end(lzma_next_coder *next, const lzma_allocator *allocator)
  // External to internal API wrapper //
  //////////////////////////////////////
  
@@ -156,7 +161,7 @@
  
  extern lzma_ret
  lzma_strm_init(lzma_stream *strm)
-@@ -167,7 +197,7 @@ lzma_strm_init(lzma_stream *strm)
+@@ -188,7 +218,7 @@ lzma_strm_init(lzma_stream *strm)
  			return LZMA_MEM_ERROR;
  
  		strm->internal->next = LZMA_NEXT_CODER_INIT;
@@ -165,7 +170,7 @@
  	}
  
  	memzero(strm->internal->supported_actions,
-@@ -220,7 +250,7 @@ lzma_code(lzma_stream *strm, lzma_action action)
+@@ -241,7 +271,7 @@ lzma_code(lzma_stream *strm, lzma_action action)
  			|| strm->reserved_ptr4 != NULL)
  		return LZMA_OPTIONS_ERROR;
  
@@ -175,10 +180,10 @@
  	else if (strm->reserved_int1 != 0
  			|| strm->reserved_int2 != 0
 diff --git a/src/liblzma/common/common.h b/src/liblzma/common/common.h
-index 475661d8..4081c2d3 100644
+index b056e417a29e..eb1d0525c07d 100644
 --- a/src/liblzma/common/common.h
 +++ b/src/liblzma/common/common.h
-@@ -201,9 +201,11 @@ struct lzma_internal_s {
+@@ -227,9 +227,11 @@ struct lzma_internal_s {
  	/// made (no input consumed and no output produced by next.code).
  	bool allow_buf_error;
  
@@ -190,6 +195,3 @@
  };
  
  
--- 
-1.7.10.4
-
diff --git a/debian/patches/abi-liblzma2-compat b/debian/patches/liblzma-skip-ABI-incompatible-check-when-liblzma.so.patch
similarity index 87%
rename from debian/patches/abi-liblzma2-compat
rename to debian/patches/liblzma-skip-ABI-incompatible-check-when-liblzma.so.patch
index 051ab5c..066d260 100644
--- a/debian/patches/abi-liblzma2-compat
+++ b/debian/patches/liblzma-skip-ABI-incompatible-check-when-liblzma.so.patch
@@ -1,6 +1,10 @@
+From 7e228a81c1aa330de9289f579f768c7c9a686db2 Mon Sep 17 00:00:00 2001
 From: Jonathan Nieder <jrnieder@gmail.com>
 Date: Thu, 17 May 2012 18:49:00 -0500
 Subject: liblzma: skip ABI-incompatible check when liblzma.so.2 is loaded
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
 
 When liblzma started using ELF symbol versioning at the same time
 as a soname bump (2 → 5) and a small increase in the reserved space at
@@ -87,31 +91,32 @@
 Thanks to Eduard Bloch for noticing PR13521 and to Ian Lance Taylor
 for PR12977.
 
+Patch-Name: liblzma-skip-ABI-incompatible-check-when-liblzma.so.patch
 Signed-off-by: Jonathan Nieder <jrnieder@gmail.com>
 ---
- configure.ac                |    5 +++++
- src/liblzma/common/common.c |   40 ++++++++++++++++++++++++++++++++++++++--
- src/liblzma/common/common.h |    4 ++++
+ configure.ac                |  5 +++++
+ src/liblzma/common/common.c | 40 ++++++++++++++++++++++++++++++++++++++--
+ src/liblzma/common/common.h |  4 ++++
  3 files changed, 47 insertions(+), 2 deletions(-)
 
 diff --git a/configure.ac b/configure.ac
-index 25eb838f..88b81ba1 100644
+index 53ae7bef7472..6dae0b9756d6 100644
 --- a/configure.ac
 +++ b/configure.ac
-@@ -471,6 +471,11 @@ if test "x$enable_threads" = xyes; then
- 	AC_CHECK_DECLS([CLOCK_MONOTONIC], [], [], [[#include <time.h>]])
- 	CFLAGS=$OLD_CFLAGS
- fi
-+
+@@ -548,6 +548,11 @@ case $enable_threads in
+ esac
+ AM_CONDITIONAL([COND_THREADS], [test "x$enable_threads" != xno])
+ 
 +# As a Debian-specific hack, liblzma uses dlopen() to check if extra
 +# paranoia is needed because unversioned symbols from liblzma.so.2 are
 +# present in the same process.  See src/liblzma/common/common.c.
 +AC_SEARCH_LIBS([dlopen], [dl])
- 
++
  echo
  echo "Initializing Libtool:"
+ LT_PREREQ([2.2])
 diff --git a/src/liblzma/common/common.c b/src/liblzma/common/common.c
-index 50c984c7..e61d940d 100644
+index 28aa2b7142f4..5474211cf0ca 100644
 --- a/src/liblzma/common/common.c
 +++ b/src/liblzma/common/common.c
 @@ -12,6 +12,8 @@
@@ -123,7 +128,7 @@
  
  /////////////
  // Version //
-@@ -141,6 +143,17 @@ lzma_next_end(lzma_next_coder *next, lzma_allocator *allocator)
+@@ -162,6 +164,17 @@ lzma_next_end(lzma_next_coder *next, const lzma_allocator *allocator)
  // External to internal API wrapper //
  //////////////////////////////////////
  
@@ -141,7 +146,7 @@
  extern lzma_ret
  lzma_strm_init(lzma_stream *strm)
  {
-@@ -154,6 +167,7 @@ lzma_strm_init(lzma_stream *strm)
+@@ -175,6 +188,7 @@ lzma_strm_init(lzma_stream *strm)
  			return LZMA_MEM_ERROR;
  
  		strm->internal->next = LZMA_NEXT_CODER_INIT;
@@ -149,7 +154,7 @@
  	}
  
  	memzero(strm->internal->supported_actions,
-@@ -168,6 +182,24 @@ lzma_strm_init(lzma_stream *strm)
+@@ -189,6 +203,24 @@ lzma_strm_init(lzma_stream *strm)
  }
  
  
@@ -174,7 +179,7 @@
  extern LZMA_API(lzma_ret)
  lzma_code(lzma_stream *strm, lzma_action action)
  {
-@@ -185,8 +217,12 @@ lzma_code(lzma_stream *strm, lzma_action action)
+@@ -206,8 +238,12 @@ lzma_code(lzma_stream *strm, lzma_action action)
  	if (strm->reserved_ptr1 != NULL
  			|| strm->reserved_ptr2 != NULL
  			|| strm->reserved_ptr3 != NULL
@@ -190,10 +195,10 @@
  			|| strm->reserved_int3 != 0
  			|| strm->reserved_int4 != 0
 diff --git a/src/liblzma/common/common.h b/src/liblzma/common/common.h
-index 45aba4f0..475661d8 100644
+index 955d784a5b6a..b056e417a29e 100644
 --- a/src/liblzma/common/common.h
 +++ b/src/liblzma/common/common.h
-@@ -200,6 +200,10 @@ struct lzma_internal_s {
+@@ -226,6 +226,10 @@ struct lzma_internal_s {
  	/// If true, lzma_code will return LZMA_BUF_ERROR if no progress was
  	/// made (no input consumed and no output produced by next.code).
  	bool allow_buf_error;
@@ -204,5 +209,3 @@
  };
  
  
--- 
-1.7.10.2
diff --git a/debian/patches/man-date b/debian/patches/man-date
deleted file mode 100644
index f43d3b7..0000000
--- a/debian/patches/man-date
+++ /dev/null
@@ -1,25 +0,0 @@
-From: Lasse Collin <lasse.collin@tukaani.org>
-Date: Fri, 22 Jun 2012 14:34:03 +0300
-Subject: xz: Update man page date to match the latest update.
-
-Signed-off-by: Jonathan Nieder <jrnieder@gmail.com>
----
- src/xz/xz.1 |    2 +-
- 1 file changed, 1 insertion(+), 1 deletion(-)
-
-diff --git a/src/xz/xz.1 b/src/xz/xz.1
-index 3ff89f0..cb8cd1e 100644
---- a/src/xz/xz.1
-+++ b/src/xz/xz.1
-@@ -5,7 +5,7 @@
- .\" This file has been put into the public domain.
- .\" You can do whatever you want with this file.
- .\"
--.TH XZ 1 "2011-04-11" "Tukaani" "XZ Utils"
-+.TH XZ 1 "2012-05-27" "Tukaani" "XZ Utils"
- .
- .SH NAME
- xz, unxz, xzcat, lzma, unlzma, lzcat \- Compress or decompress .xz and .lzma files
--- 
-1.7.9.6 (Apple Git-31.1)
-
diff --git a/debian/patches/man-xz-lvv-minver b/debian/patches/man-xz-lvv-minver
deleted file mode 100644
index 8b2f44d..0000000
--- a/debian/patches/man-xz-lvv-minver
+++ /dev/null
@@ -1,55 +0,0 @@
-From: Lasse Collin <lasse.collin@tukaani.org>
-Date: Sun, 1 Jul 2012 18:44:33 +0300
-Subject: xz: Update the man page about the new field in --robot -lvv.
-
-Signed-off-by: Jonathan Nieder <jrnieder@gmail.com>
----
- src/xz/xz.1 |   18 +++++++++++++++++-
- 1 file changed, 17 insertions(+), 1 deletion(-)
-
-diff --git a/src/xz/xz.1 b/src/xz/xz.1
-index cb8cd1e..4da09ba 100644
---- a/src/xz/xz.1
-+++ b/src/xz/xz.1
-@@ -5,7 +5,7 @@
- .\" This file has been put into the public domain.
- .\" You can do whatever you want with this file.
- .\"
--.TH XZ 1 "2012-05-27" "Tukaani" "XZ Utils"
-+.TH XZ 1 "2012-07-01" "Tukaani" "XZ Utils"
- .
- .SH NAME
- xz, unxz, xzcat, lzma, unlzma, lzcat \- Compress or decompress .xz and .lzma files
-@@ -1889,6 +1889,14 @@ or
- .B no
- indicating if all block headers have both compressed size and
- uncompressed size stored in them
-+.PP
-+.I Since
-+.B xz
-+.I 5.1.2alpha:
-+.IP 4. 4
-+Minimum
-+.B xz
-+version required to decompress the file
- .RE
- .PD
- .PP
-@@ -1939,6 +1947,14 @@ or
- .B no
- indicating if all block headers have both compressed size and
- uncompressed size stored in them
-+.PP
-+.I Since
-+.B xz
-+.I 5.1.2alpha:
-+.IP 12. 4
-+Minimum
-+.B xz
-+version required to decompress the file
- .RE
- .PD
- .PP
--- 
-1.7.9.6 (Apple Git-31.1)
-
diff --git a/debian/patches/series b/debian/patches/series
index 8020937..b37018b 100644
--- a/debian/patches/series
+++ b/debian/patches/series
@@ -1,8 +1,2 @@
-abi-threaded-encoder
-abi-version-script
-abi-liblzma2-compat
-configure-liblzma2-compat
-man-date
-man-xz-lvv-minver
-xz-lvv-empty-block-minver
-decoder-check-first-0x00
+liblzma-skip-ABI-incompatible-check-when-liblzma.so.patch
+liblzma-make-dlopen-based-liblzma2-compatibility-opt.patch
diff --git a/debian/patches/xz-lvv-empty-block-minver b/debian/patches/xz-lvv-empty-block-minver
deleted file mode 100644
index 2c658d9..0000000
--- a/debian/patches/xz-lvv-empty-block-minver
+++ /dev/null
@@ -1,38 +0,0 @@
-From: Lasse Collin <lasse.collin@tukaani.org>
-Date: Wed, 4 Jul 2012 19:58:23 +0300
-Subject: xz: Fix the version number printed by xz -lvv.
-
-The decoder bug was fixed in 5.0.2 instead of 5.0.3.
-
-Signed-off-by: Jonathan Nieder <jrnieder@gmail.com>
----
- src/xz/list.c |    6 +++---
- 1 file changed, 3 insertions(+), 3 deletions(-)
-
-diff --git a/src/xz/list.c b/src/xz/list.c
-index e71fbe2..a9e0adb 100644
---- a/src/xz/list.c
-+++ b/src/xz/list.c
-@@ -482,7 +482,7 @@ parse_block_header(file_pair *pair, const lzma_index_iter *iter,
- 	// Determine the minimum XZ Utils version that supports this Block.
- 	//
- 	// Currently the only thing that 5.0.0 doesn't support is empty
--	// LZMA2 Block. This bug was fixed in 5.0.3.
-+	// LZMA2 Block. This decoder bug was fixed in 5.0.2.
- 	{
- 		size_t i = 0;
- 		while (filters[i + 1].id != LZMA_VLI_UNKNOWN)
-@@ -490,8 +490,8 @@ parse_block_header(file_pair *pair, const lzma_index_iter *iter,
- 
- 		if (filters[i].id == LZMA_FILTER_LZMA2
- 				&& iter->block.uncompressed_size == 0
--				&& xfi->min_version < 50000032U)
--			xfi->min_version = 50000032U;
-+				&& xfi->min_version < 50000022U)
-+			xfi->min_version = 50000022U;
- 	}
- 
- 	// Convert the filter chain to human readable form.
--- 
-1.7.9.6 (Apple Git-31.1)
-
diff --git a/debian/rules b/debian/rules
index fcbf5c2..63bc7c7 100755
--- a/debian/rules
+++ b/debian/rules
@@ -38,7 +38,7 @@
 	ln -s -f /lib/$$arch/$$dso debian/tmp/usr/lib/$$arch/liblzma.so
 
 override_dh_installchangelogs:
-	dh_installchangelogs debian/changelog.upstream
+	dh_installchangelogs ChangeLog
 
 build-plain: debian/normal-build/Makefile
 	dh_auto_build --builddirectory debian/normal-build
@@ -66,7 +66,7 @@
 
 debian/normal-build/Makefile debian/normal-build/Doxyfile: $(configure_input)
 	dh_auto_configure --builddirectory debian/normal-build -- \
-		--disable-threads --disable-static \
+		--enable-threads --disable-static \
 		$(opt_optimize) $(opt_quiet) \
 		--disable-xzdec --disable-lzmadec
 
diff --git a/debian/symbols b/debian/symbols
index ae398c9..4a95cf5 100644
--- a/debian/symbols
+++ b/debian/symbols
@@ -4,3 +4,4 @@
  lzma_code@XZ_5.0 5.1.1alpha+20120614
  lzma_raw_buffer_decode@XZ_5.0 5.1.1alpha+20120614
  lzma_raw_buffer_encode@XZ_5.0 5.1.1alpha+20120614
+ (symver)XZ_5.2 5.2.2
diff --git a/debug/Makefile.am b/debug/Makefile.am
index 45b4b7f..9026fd9 100644
--- a/debug/Makefile.am
+++ b/debug/Makefile.am
@@ -5,6 +5,9 @@
 ## You can do whatever you want with this file.
 ##
 
+EXTRA_DIST = \
+	translation.bash
+
 noinst_PROGRAMS = \
 	repeat \
 	sync_flush \
diff --git a/debug/README b/debug/README
index 749610d..d42b272 100644
--- a/debug/README
+++ b/debug/README
@@ -3,7 +3,7 @@
 -----------
 
     This directory contains a few tiny programs that may be helpful when
-    debugging LZMA Utils.
+    debugging XZ Utils.
 
     These tools are not meant to be installed. Often one needs to edit
     the source code a little to make the programs do the wanted things.
diff --git a/debug/full_flush.c b/debug/full_flush.c
index 67442b1..227f737 100644
--- a/debug/full_flush.c
+++ b/debug/full_flush.c
@@ -14,6 +14,8 @@
 #include "lzma.h"
 #include <stdio.h>
 
+#define CHUNK 64
+
 
 static lzma_stream strm = LZMA_STREAM_INIT;
 static FILE *file_in;
@@ -22,7 +24,6 @@
 static void
 encode(size_t size, lzma_action action)
 {
-	static const size_t CHUNK = 64;
 	uint8_t in[CHUNK];
 	uint8_t out[CHUNK];
 	lzma_ret ret;
diff --git a/debug/sync_flush.c b/debug/sync_flush.c
index fc2ebcb..2292333 100644
--- a/debug/sync_flush.c
+++ b/debug/sync_flush.c
@@ -14,6 +14,8 @@
 #include "lzma.h"
 #include <stdio.h>
 
+#define CHUNK 64
+
 
 static lzma_stream strm = LZMA_STREAM_INIT;
 static FILE *file_in;
@@ -22,7 +24,6 @@
 static void
 encode(size_t size, lzma_action action)
 {
-	static const size_t CHUNK = 64;
 	uint8_t in[CHUNK];
 	uint8_t out[CHUNK];
 	lzma_ret ret;
diff --git a/doc/examples/00_README.txt b/doc/examples/00_README.txt
index a3b9eaa..120e1eb 100644
--- a/doc/examples/00_README.txt
+++ b/doc/examples/00_README.txt
@@ -25,3 +25,7 @@
                                         a custom filter chain
                                         (x86 BCJ + LZMA2)
 
+    04_compress_easy_mt.c               Multi-threaded multi-call
+                                        compression using a compression
+                                        preset
+
diff --git a/doc/examples/01_compress_easy.c b/doc/examples/01_compress_easy.c
index f79cade..e6dd2b0 100644
--- a/doc/examples/01_compress_easy.c
+++ b/doc/examples/01_compress_easy.c
@@ -27,7 +27,7 @@
 {
 	fprintf(stderr, "Usage: %s PRESET < INFILE > OUTFILE\n"
 			"PRESET is a number 0-9 and can optionally be "
-			"by `e' to indicate extreme preset\n",
+			"followed by `e' to indicate extreme preset\n",
 			argv0);
 	exit(EXIT_FAILURE);
 }
diff --git a/doc/examples/03_compress_custom.c b/doc/examples/03_compress_custom.c
index 51abbb1..40c85e3 100644
--- a/doc/examples/03_compress_custom.c
+++ b/doc/examples/03_compress_custom.c
@@ -28,8 +28,8 @@
 	// Use the default preset (6) for LZMA2.
 	//
 	// The lzma_options_lzma structure and the lzma_lzma_preset() function
-	// are declared in lzma/lzma.h (src/liblzma/api/lzma/lzma.h in the
-	// source package or e.g. /usr/include/lzma/lzma.h depending on
+	// are declared in lzma/lzma12.h (src/liblzma/api/lzma/lzma12.h in the
+	// source package or e.g. /usr/include/lzma/lzma12.h depending on
 	// the install prefix).
 	lzma_options_lzma opt_lzma2;
 	if (lzma_lzma_preset(&opt_lzma2, LZMA_PRESET_DEFAULT)) {
@@ -48,7 +48,7 @@
 	// Now we could customize the LZMA2 options if we wanted. For example,
 	// we could set the the dictionary size (opt_lzma2.dict_size) to
 	// something else than the default (8 MiB) of the default preset.
-	// See lzma/lzma.h for details of all LZMA2 options.
+	// See lzma/lzma12.h for details of all LZMA2 options.
 	//
 	// The x86 BCJ filter will try to modify the x86 instruction stream so
 	// that LZMA2 can compress it better. The x86 BCJ filter doesn't need
diff --git a/doc/examples/04_compress_easy_mt.c b/doc/examples/04_compress_easy_mt.c
new file mode 100644
index 0000000..efe5697
--- /dev/null
+++ b/doc/examples/04_compress_easy_mt.c
@@ -0,0 +1,206 @@
+///////////////////////////////////////////////////////////////////////////////
+//
+/// \file       04_compress_easy_mt.c
+/// \brief      Compress in multi-call mode using LZMA2 in multi-threaded mode
+///
+/// Usage:      ./04_compress_easy_mt < INFILE > OUTFILE
+///
+/// Example:    ./04_compress_easy_mt < foo > foo.xz
+//
+//  Author:     Lasse Collin
+//
+//  This file has been put into the public domain.
+//  You can do whatever you want with this file.
+//
+///////////////////////////////////////////////////////////////////////////////
+
+#include <stdbool.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <errno.h>
+#include <lzma.h>
+
+
+static bool
+init_encoder(lzma_stream *strm)
+{
+	// The threaded encoder takes the options as pointer to
+	// a lzma_mt structure.
+	lzma_mt mt = {
+		// No flags are needed.
+		.flags = 0,
+
+		// Let liblzma determine a sane block size.
+		.block_size = 0,
+
+		// Use no timeout for lzma_code() calls by setting timeout
+		// to zero. That is, sometimes lzma_code() might block for
+		// a long time (from several seconds to even minutes).
+		// If this is not OK, for example due to progress indicator
+		// needing updates, specify a timeout in milliseconds here.
+		// See the documentation of lzma_mt in lzma/container.h for
+		// information how to choose a reasonable timeout.
+		.timeout = 0,
+
+		// Use the default preset (6) for LZMA2.
+		// To use a preset, filters must be set to NULL.
+		.preset = LZMA_PRESET_DEFAULT,
+		.filters = NULL,
+
+		// Use CRC64 for integrity checking. See also
+		// 01_compress_easy.c about choosing the integrity check.
+		.check = LZMA_CHECK_CRC64,
+	};
+
+	// Detect how many threads the CPU supports.
+	mt.threads = lzma_cputhreads();
+
+	// If the number of CPU cores/threads cannot be detected,
+	// use one thread. Note that this isn't the same as the normal
+	// single-threaded mode as this will still split the data into
+	// blocks and use more RAM than the normal single-threaded mode.
+	// You may want to consider using lzma_easy_encoder() or
+	// lzma_stream_encoder() instead of lzma_stream_encoder_mt() if
+	// lzma_cputhreads() returns 0 or 1.
+	if (mt.threads == 0)
+		mt.threads = 1;
+
+	// If the number of CPU cores/threads exceeds threads_max,
+	// limit the number of threads to keep memory usage lower.
+	// The number 8 is arbitrarily chosen and may be too low or
+	// high depending on the compression preset and the computer
+	// being used.
+	//
+	// FIXME: A better way could be to check the amount of RAM
+	// (or available RAM) and use lzma_stream_encoder_mt_memusage()
+	// to determine if the number of threads should be reduced.
+	const uint32_t threads_max = 8;
+	if (mt.threads > threads_max)
+		mt.threads = threads_max;
+
+	// Initialize the threaded encoder.
+	lzma_ret ret = lzma_stream_encoder_mt(strm, &mt);
+
+	if (ret == LZMA_OK)
+		return true;
+
+	const char *msg;
+	switch (ret) {
+	case LZMA_MEM_ERROR:
+		msg = "Memory allocation failed";
+		break;
+
+	case LZMA_OPTIONS_ERROR:
+		// We are no longer using a plain preset so this error
+		// message has been edited accordingly compared to
+		// 01_compress_easy.c.
+		msg = "Specified filter chain is not supported";
+		break;
+
+	case LZMA_UNSUPPORTED_CHECK:
+		msg = "Specified integrity check is not supported";
+		break;
+
+	default:
+		msg = "Unknown error, possibly a bug";
+		break;
+	}
+
+	fprintf(stderr, "Error initializing the encoder: %s (error code %u)\n",
+			msg, ret);
+	return false;
+}
+
+
+// This function is identical to the one in 01_compress_easy.c.
+static bool
+compress(lzma_stream *strm, FILE *infile, FILE *outfile)
+{
+	lzma_action action = LZMA_RUN;
+
+	uint8_t inbuf[BUFSIZ];
+	uint8_t outbuf[BUFSIZ];
+
+	strm->next_in = NULL;
+	strm->avail_in = 0;
+	strm->next_out = outbuf;
+	strm->avail_out = sizeof(outbuf);
+
+	while (true) {
+		if (strm->avail_in == 0 && !feof(infile)) {
+			strm->next_in = inbuf;
+			strm->avail_in = fread(inbuf, 1, sizeof(inbuf),
+					infile);
+
+			if (ferror(infile)) {
+				fprintf(stderr, "Read error: %s\n",
+						strerror(errno));
+				return false;
+			}
+
+			if (feof(infile))
+				action = LZMA_FINISH;
+		}
+
+		lzma_ret ret = lzma_code(strm, action);
+
+		if (strm->avail_out == 0 || ret == LZMA_STREAM_END) {
+			size_t write_size = sizeof(outbuf) - strm->avail_out;
+
+			if (fwrite(outbuf, 1, write_size, outfile)
+					!= write_size) {
+				fprintf(stderr, "Write error: %s\n",
+						strerror(errno));
+				return false;
+			}
+
+			strm->next_out = outbuf;
+			strm->avail_out = sizeof(outbuf);
+		}
+
+		if (ret != LZMA_OK) {
+			if (ret == LZMA_STREAM_END)
+				return true;
+
+			const char *msg;
+			switch (ret) {
+			case LZMA_MEM_ERROR:
+				msg = "Memory allocation failed";
+				break;
+
+			case LZMA_DATA_ERROR:
+				msg = "File size limits exceeded";
+				break;
+
+			default:
+				msg = "Unknown error, possibly a bug";
+				break;
+			}
+
+			fprintf(stderr, "Encoder error: %s (error code %u)\n",
+					msg, ret);
+			return false;
+		}
+	}
+}
+
+
+extern int
+main(void)
+{
+	lzma_stream strm = LZMA_STREAM_INIT;
+
+	bool success = init_encoder(&strm);
+	if (success)
+		success = compress(&strm, stdin, stdout);
+
+	lzma_end(&strm);
+
+	if (fclose(stdout)) {
+		fprintf(stderr, "Write error: %s\n", strerror(errno));
+		success = false;
+	}
+
+	return success ? EXIT_SUCCESS : EXIT_FAILURE;
+}
diff --git a/doc/examples/Makefile b/doc/examples/Makefile
index 644dc32..0f3d185 100644
--- a/doc/examples/Makefile
+++ b/doc/examples/Makefile
@@ -12,7 +12,8 @@
 PROGS = \
 	01_compress_easy \
 	02_decompress \
-	03_compress_custom
+	03_compress_custom \
+	04_compress_easy_mt
 
 all: $(PROGS)
 
diff --git a/dos/Makefile b/dos/Makefile
index 3a02899..0ddb43c 100644
--- a/dos/Makefile
+++ b/dos/Makefile
@@ -113,6 +113,7 @@
 	../src/xz/list.c \
 	../src/xz/main.c \
 	../src/xz/message.c \
+	../src/xz/mytime.c \
 	../src/xz/options.c \
 	../src/xz/signals.c \
 	../src/xz/suffix.c \
diff --git a/m4/.gitignore b/m4/.gitignore
index 6e6c301..20f2603 100644
--- a/m4/.gitignore
+++ b/m4/.gitignore
@@ -1,4 +1,5 @@
 codeset.m4
+fcntl-o.m4
 gettext.m4
 glibc2.m4
 glibc21.m4
@@ -6,6 +7,7 @@
 intdiv0.m4
 intl.m4
 intldir.m4
+intlmacosx.m4
 intmax.m4
 inttypes-pri.m4
 inttypes_h.m4
@@ -27,6 +29,7 @@
 progtest.m4
 size_max.m4
 stdint_h.m4
+threadlib.m4
 uintmax_t.m4
 ulonglong.m4
 visibility.m4
diff --git a/m4/ax_pthread.m4 b/m4/ax_pthread.m4
index d90de34..d383ad5 100644
--- a/m4/ax_pthread.m4
+++ b/m4/ax_pthread.m4
@@ -82,7 +82,7 @@
 #   modified version of the Autoconf Macro, you may extend this special
 #   exception to the GPL to apply to your modified version as well.
 
-#serial 18
+#serial 21
 
 AU_ALIAS([ACX_PTHREAD], [AX_PTHREAD])
 AC_DEFUN([AX_PTHREAD], [
@@ -103,8 +103,8 @@
         save_LIBS="$LIBS"
         LIBS="$PTHREAD_LIBS $LIBS"
         AC_MSG_CHECKING([for pthread_join in LIBS=$PTHREAD_LIBS with CFLAGS=$PTHREAD_CFLAGS])
-        AC_TRY_LINK_FUNC(pthread_join, ax_pthread_ok=yes)
-        AC_MSG_RESULT($ax_pthread_ok)
+        AC_TRY_LINK_FUNC([pthread_join], [ax_pthread_ok=yes])
+        AC_MSG_RESULT([$ax_pthread_ok])
         if test x"$ax_pthread_ok" = xno; then
                 PTHREAD_LIBS=""
                 PTHREAD_CFLAGS=""
@@ -164,6 +164,20 @@
         ;;
 esac
 
+# Clang doesn't consider unrecognized options an error unless we specify
+# -Werror. We throw in some extra Clang-specific options to ensure that
+# this doesn't happen for GCC, which also accepts -Werror.
+
+AC_MSG_CHECKING([if compiler needs -Werror to reject unknown flags])
+save_CFLAGS="$CFLAGS"
+ax_pthread_extra_flags="-Werror"
+CFLAGS="$CFLAGS $ax_pthread_extra_flags -Wunknown-warning-option -Wsizeof-array-argument"
+AC_COMPILE_IFELSE([AC_LANG_PROGRAM([int foo(void);],[foo()])],
+                  [AC_MSG_RESULT([yes])],
+                  [ax_pthread_extra_flags=
+                   AC_MSG_RESULT([no])])
+CFLAGS="$save_CFLAGS"
+
 if test x"$ax_pthread_ok" = xno; then
 for flag in $ax_pthread_flags; do
 
@@ -178,7 +192,7 @@
                 ;;
 
                 pthread-config)
-                AC_CHECK_PROG(ax_pthread_config, pthread-config, yes, no)
+                AC_CHECK_PROG([ax_pthread_config], [pthread-config], [yes], [no])
                 if test x"$ax_pthread_config" = xno; then continue; fi
                 PTHREAD_CFLAGS="`pthread-config --cflags`"
                 PTHREAD_LIBS="`pthread-config --ldflags` `pthread-config --libs`"
@@ -193,7 +207,7 @@
         save_LIBS="$LIBS"
         save_CFLAGS="$CFLAGS"
         LIBS="$PTHREAD_LIBS $LIBS"
-        CFLAGS="$CFLAGS $PTHREAD_CFLAGS"
+        CFLAGS="$CFLAGS $PTHREAD_CFLAGS $ax_pthread_extra_flags"
 
         # Check for various functions.  We must include pthread.h,
         # since some functions may be macros.  (On the Sequent, we
@@ -219,7 +233,7 @@
         LIBS="$save_LIBS"
         CFLAGS="$save_CFLAGS"
 
-        AC_MSG_RESULT($ax_pthread_ok)
+        AC_MSG_RESULT([$ax_pthread_ok])
         if test "x$ax_pthread_ok" = xyes; then
                 break;
         fi
@@ -245,9 +259,9 @@
                 [attr_name=$attr; break],
                 [])
         done
-        AC_MSG_RESULT($attr_name)
+        AC_MSG_RESULT([$attr_name])
         if test "$attr_name" != PTHREAD_CREATE_JOINABLE; then
-            AC_DEFINE_UNQUOTED(PTHREAD_CREATE_JOINABLE, $attr_name,
+            AC_DEFINE_UNQUOTED([PTHREAD_CREATE_JOINABLE], [$attr_name],
                                [Define to necessary symbol if this constant
                                 uses a non-standard name on your system.])
         fi
@@ -261,45 +275,54 @@
             if test "$GCC" = "yes"; then
                 flag="-D_REENTRANT"
             else
+                # TODO: What about Clang on Solaris?
                 flag="-mt -D_REENTRANT"
             fi
             ;;
         esac
-        AC_MSG_RESULT(${flag})
+        AC_MSG_RESULT([$flag])
         if test "x$flag" != xno; then
             PTHREAD_CFLAGS="$flag $PTHREAD_CFLAGS"
         fi
 
         AC_CACHE_CHECK([for PTHREAD_PRIO_INHERIT],
-            ax_cv_PTHREAD_PRIO_INHERIT, [
-                AC_LINK_IFELSE([
-                    AC_LANG_PROGRAM([[#include <pthread.h>]], [[int i = PTHREAD_PRIO_INHERIT;]])],
+            [ax_cv_PTHREAD_PRIO_INHERIT], [
+                AC_LINK_IFELSE([AC_LANG_PROGRAM([[#include <pthread.h>]],
+                                                [[int i = PTHREAD_PRIO_INHERIT;]])],
                     [ax_cv_PTHREAD_PRIO_INHERIT=yes],
                     [ax_cv_PTHREAD_PRIO_INHERIT=no])
             ])
         AS_IF([test "x$ax_cv_PTHREAD_PRIO_INHERIT" = "xyes"],
-            AC_DEFINE([HAVE_PTHREAD_PRIO_INHERIT], 1, [Have PTHREAD_PRIO_INHERIT.]))
+            [AC_DEFINE([HAVE_PTHREAD_PRIO_INHERIT], [1], [Have PTHREAD_PRIO_INHERIT.])])
 
         LIBS="$save_LIBS"
         CFLAGS="$save_CFLAGS"
 
-        # More AIX lossage: must compile with xlc_r or cc_r
-        if test x"$GCC" != xyes; then
-          AC_CHECK_PROGS(PTHREAD_CC, xlc_r cc_r, ${CC})
-        else
-          PTHREAD_CC=$CC
+        # More AIX lossage: compile with *_r variant
+        if test "x$GCC" != xyes; then
+            case $host_os in
+                aix*)
+                AS_CASE(["x/$CC"],
+                  [x*/c89|x*/c89_128|x*/c99|x*/c99_128|x*/cc|x*/cc128|x*/xlc|x*/xlc_v6|x*/xlc128|x*/xlc128_v6],
+                  [#handle absolute path differently from PATH based program lookup
+                   AS_CASE(["x$CC"],
+                     [x/*],
+                     [AS_IF([AS_EXECUTABLE_P([${CC}_r])],[PTHREAD_CC="${CC}_r"])],
+                     [AC_CHECK_PROGS([PTHREAD_CC],[${CC}_r],[$CC])])])
+                ;;
+            esac
         fi
-else
-        PTHREAD_CC="$CC"
 fi
 
-AC_SUBST(PTHREAD_LIBS)
-AC_SUBST(PTHREAD_CFLAGS)
-AC_SUBST(PTHREAD_CC)
+test -n "$PTHREAD_CC" || PTHREAD_CC="$CC"
+
+AC_SUBST([PTHREAD_LIBS])
+AC_SUBST([PTHREAD_CFLAGS])
+AC_SUBST([PTHREAD_CC])
 
 # Finally, execute ACTION-IF-FOUND/ACTION-IF-NOT-FOUND:
 if test x"$ax_pthread_ok" = xyes; then
-        ifelse([$1],,AC_DEFINE(HAVE_PTHREAD,1,[Define if you have POSIX threads libraries and header files.]),[$1])
+        ifelse([$1],,[AC_DEFINE([HAVE_PTHREAD],[1],[Define if you have POSIX threads libraries and header files.])],[$1])
         :
 else
         ax_pthread_ok=no
diff --git a/m4/tuklib_cpucores.m4 b/m4/tuklib_cpucores.m4
index 9e295c8..468c2db 100644
--- a/m4/tuklib_cpucores.m4
+++ b/m4/tuklib_cpucores.m4
@@ -9,8 +9,10 @@
 #   This information is used by tuklib_cpucores.c.
 #
 #   Supported methods:
+#     - GetSystemInfo(): Windows (including Cygwin)
 #     - sysctl(): BSDs, OS/2
-#     - sysconf(): GNU/Linux, Solaris, Tru64, IRIX, AIX, Cygwin
+#     - sysconf(): GNU/Linux, Solaris, Tru64, IRIX, AIX, QNX, Cygwin (but
+#       GetSystemInfo() is used on Cygwin)
 #     - pstat_getdynamic(): HP-UX
 #
 # COPYING
@@ -30,10 +32,46 @@
 AC_CACHE_CHECK([how to detect the number of available CPU cores],
 	[tuklib_cv_cpucores_method], [
 
-# Look for sysctl() solution first, because on OS/2, both sysconf()
-# and sysctl() pass the tests in this file, but only sysctl()
-# actually works.
+# Maybe checking $host_os would be enough but this matches what
+# tuklib_cpucores.c does.
+#
+# NOTE: IRIX has a compiler that doesn't error out with #error, so use
+# a non-compilable text instead of #error to generate an error.
 AC_COMPILE_IFELSE([AC_LANG_SOURCE([[
+#if defined(_WIN32) || defined(__CYGWIN__)
+int main(void) { return 0; }
+#else
+compile error
+#endif
+]])], [tuklib_cv_cpucores_method=special], [
+
+# FreeBSD has both cpuset and sysctl. Look for cpuset first because
+# it's a better approach.
+AC_COMPILE_IFELSE([AC_LANG_SOURCE([[
+#include <sys/param.h>
+#include <sys/cpuset.h>
+
+int
+main(void)
+{
+	cpuset_t set;
+	cpuset_getaffinity(CPU_LEVEL_WHICH, CPU_WHICH_PID, -1,
+			sizeof(set), &set);
+	return 0;
+}
+]])], [tuklib_cv_cpucores_method=cpuset], [
+
+# On OS/2, both sysconf() and sysctl() pass the tests in this file,
+# but only sysctl() works. On QNX it's the opposite: only sysconf() works
+# (although it assumes that _POSIX_SOURCE, _XOPEN_SOURCE, and _POSIX_C_SOURCE
+# are undefined or alternatively _QNX_SOURCE is defined).
+#
+# We test sysctl() first and intentionally break the sysctl() test on QNX
+# so that sysctl() is never used on QNX.
+AC_COMPILE_IFELSE([AC_LANG_SOURCE([[
+#ifdef __QNX__
+compile error
+#endif
 #include <sys/types.h>
 #ifdef HAVE_SYS_PARAM_H
 #	include <sys/param.h>
@@ -82,9 +120,14 @@
 ]])], [tuklib_cv_cpucores_method=pstat_getdynamic], [
 
 	tuklib_cv_cpucores_method=unknown
-])])])])
+])])])])])])
 
 case $tuklib_cv_cpucores_method in
+	cpuset)
+		AC_DEFINE([TUKLIB_CPUCORES_CPUSET], [1],
+			[Define to 1 if the number of available CPU cores
+			can be detected with cpuset(2).])
+		;;
 	sysctl)
 		AC_DEFINE([TUKLIB_CPUCORES_SYSCTL], [1],
 			[Define to 1 if the number of available CPU cores
diff --git a/m4/tuklib_integer.m4 b/m4/tuklib_integer.m4
index 5fe66ee..2ab72a2 100644
--- a/m4/tuklib_integer.m4
+++ b/m4/tuklib_integer.m4
@@ -46,7 +46,7 @@
 fi
 
 AC_MSG_CHECKING([if unaligned memory access should be used])
-AC_ARG_ENABLE([unaligned-access], AC_HELP_STRING([--enable-unaligned-access],
+AC_ARG_ENABLE([unaligned-access], AS_HELP_STRING([--enable-unaligned-access],
 		[Enable if the system supports *fast* unaligned memory access
 		with 16-bit and 32-bit integers. By default, this is enabled
 		only on x86, x86_64, and big endian PowerPC.]),
diff --git a/m4/tuklib_physmem.m4 b/m4/tuklib_physmem.m4
index 1249925..8a57ca2 100644
--- a/m4/tuklib_physmem.m4
+++ b/m4/tuklib_physmem.m4
@@ -10,8 +10,8 @@
 #
 #   Supported methods:
 #
-#     - Windows (including Cygwin), OS/2, DJGPP (DOS), and OpenVMS have
-#       operating-system specific functions.
+#     - Windows (including Cygwin), OS/2, DJGPP (DOS), OpenVMS, AROS,
+#       and QNX have operating-system specific functions.
 #
 #     - AIX has _system_configuration.physmem.
 #
@@ -53,7 +53,8 @@
 # a non-compilable text instead of #error to generate an error.
 AC_COMPILE_IFELSE([AC_LANG_SOURCE([[
 #if defined(_WIN32) || defined(__CYGWIN__) || defined(__OS2__) \
-		|| defined(__DJGPP__) || defined(__VMS)
+		|| defined(__DJGPP__) || defined(__VMS) \
+		|| defined(AMIGA) || defined(__AROS__) || defined(__QNX__)
 int main(void) { return 0; }
 #else
 compile error
diff --git a/macosx/build.sh b/macosx/build.sh
index d48ee61..fd089f3 100755
--- a/macosx/build.sh
+++ b/macosx/build.sh
@@ -13,14 +13,26 @@
 # Abort immediately if something goes wrong.
 set -e
 
+GCC="gcc-4.2"
+SDK="/Developer/SDKs/MacOSX10.5.sdk"
+MDT="10.5"
+GTT=i686-apple-darwin9
+
+ARCHES1="-arch ppc -arch ppc64 -arch i386 -arch x86_64"
+ARCHES2="-arch ppc -arch i386"
+PKGFORMAT="10.5" # xar
+
+# avoid "unknown required load command: 0x80000022" from linking on Snow Leopard
+uname -r | grep ^1 >/dev/null && LDFLAGS="$LDFLAGS -Wl,-no_compact_linkedit"
+
 # Clean up if it was already configured.
 [ -f Makefile ] && make distclean
 
 # Build the regular fat program
 
-CC="gcc-4.0" \
-CFLAGS="-O2 -g -arch ppc -arch ppc64 -arch i386 -arch x86_64 -isysroot /Developer/SDKs/MacOSX10.4u.sdk -mmacosx-version-min=10.4" \
-../configure --disable-dependency-tracking --disable-xzdec --disable-lzmadec i686-apple-darwin8
+CC="$GCC" \
+CFLAGS="-O2 -g $ARCHES1 -isysroot $SDK -mmacosx-version-min=$MDT" \
+../configure --disable-dependency-tracking --disable-xzdec --disable-lzmadec $GTT
 
 make
 
@@ -32,9 +44,9 @@
 
 # Build the size-optimized program
 
-CC="gcc-4.0" \
-CFLAGS="-Os -g -arch ppc -arch i386 -isysroot /Developer/SDKs/MacOSX10.4u.sdk -mmacosx-version-min=10.4" \
-../configure --disable-dependency-tracking --disable-shared --disable-nls --disable-encoders --enable-small --disable-threads i686-apple-darwin8
+CC="$GCC" \
+CFLAGS="-Os -g $ARCHES2 -isysroot $SDK -mmacosx-version-min=$MDT" \
+../configure --disable-dependency-tracking --disable-shared --disable-nls --disable-encoders --enable-small --disable-threads $GTT
 
 make -C src/liblzma
 make -C src/xzdec
@@ -44,6 +56,19 @@
 
 make distclean
 
+# Move development files to different package
+
+test -d liblzma && rm -r liblzma
+mkdir -p liblzma/usr/local
+
+mv Root/usr/local/include liblzma/usr/local
+mv Root/usr/local/lib liblzma/usr/local
+
+mkdir -p Root/usr/local/lib
+cp -p liblzma/usr/local/lib/liblzma.5.dylib Root/usr/local/lib
+mkdir -p liblzma/usr/local/share/doc/xz
+mv Root/usr/local/share/doc/xz/examples* liblzma/usr/local/share/doc/xz
+
 # Strip debugging symbols and make relocatable
 
 for bin in xz lzmainfo xzdec lzmadec; do
@@ -56,19 +81,12 @@
     install_name_tool -id @executable_path/../lib/liblzma.5.dylib Root/usr/local/lib/$lib
 done
 
-strip -S  Root/usr/local/lib/liblzma.a
-rm -f Root/usr/local/lib/liblzma.la
-
-# Include pkg-config while making relocatable
-
-sed -e 's|prefix=/usr/local|prefix=${pcfiledir}/../..|' < Root/usr/local/lib/pkgconfig/liblzma.pc > Root/liblzma.pc
-mv Root/liblzma.pc Root/usr/local/lib/pkgconfig/liblzma.pc
-
 # Create tarball, but without the HFS+ attrib
 
 rmdir debug lib po src/liblzma/api src/liblzma src/lzmainfo src/scripts src/xz src/xzdec src tests
 
 ( cd Root/usr/local; COPY_EXTENDED_ATTRIBUTES_DISABLE=true COPYFILE_DISABLE=true tar cvjf ../../../XZ.tbz * )
+( cd liblzma; COPY_EXTENDED_ATTRIBUTES_DISABLE=true COPYFILE_DISABLE=true tar cvjf ../liblzma.tbz ./usr/local )
 
 # Include documentation files for package
 
@@ -80,12 +98,15 @@
 ID="org.tukaani.xz"
 VERSION=`cd ..; sh build-aux/version.sh`
 PACKAGEMAKER=/Developer/Applications/Utilities/PackageMaker.app/Contents/MacOS/PackageMaker
-$PACKAGEMAKER -r Root/usr/local -l /usr/local -e Resources -i $ID -n $VERSION -t XZ -o XZ.pkg -g 10.4 --verbose
+$PACKAGEMAKER -r Root/usr/local -l /usr/local -e Resources -i $ID -n $VERSION -t XZ -o XZ.pkg -g $PKGFORMAT --verbose
+$PACKAGEMAKER -r liblzma -w -k -i $ID.liblzma -n $VERSION -o liblzma.pkg -g $PKGFORMAT --verbose
 
 # Put the package in a disk image
 
+if [ "$PKGFORMAT" != "10.5" ]; then
 hdiutil create -fs HFS+ -format UDZO -quiet -srcfolder XZ.pkg -ov XZ.dmg
 hdiutil internet-enable -yes -quiet XZ.dmg
+fi
 
 echo
 echo "Build completed successfully."
diff --git a/po/LINGUAS b/po/LINGUAS
index 6babcab..e095f6c 100644
--- a/po/LINGUAS
+++ b/po/LINGUAS
@@ -3,3 +3,4 @@
 fr
 it
 pl
+vi
diff --git a/po/de.po b/po/de.po
index 4cf5297..bbf3351 100644
--- a/po/de.po
+++ b/po/de.po
@@ -1,96 +1,131 @@
 # XZ Utils German translation
 # This file is put in the public domain.
-# Andre Noll <maan@systemlinux.org>, 2010.
+# Andre Noll <maan@tuebingen.mpg.de>, 2010.
 #
 msgid ""
 msgstr ""
 "Project-Id-Version: XZ Utils 4.999.9beta\n"
 "Report-Msgid-Bugs-To: lasse.collin@tukaani.org\n"
-"POT-Creation-Date: 2012-05-29 21:55+0200\n"
-"PO-Revision-Date: 2010-09-07 20:27+0200\n"
-"Last-Translator:  <maan@systemlinux.org>\n"
+"POT-Creation-Date: 2015-08-07 05:10+0200\n"
+"PO-Revision-Date: 2015-08-07 14:00+0200\n"
+"Last-Translator:  <sqrt@entless.org>\n"
 "Language-Team: German\n"
+"Language: de\n"
 "MIME-Version: 1.0\n"
 "Content-Type: text/plain; charset=UTF-8\n"
 "Content-Transfer-Encoding: 8bit\n"
 "Plural-Forms: nplurals=2; plural=(n != 1);\n"
 
-#: src/xz/args.c:338
+#: src/xz/args.c:63
+#, c-format
+msgid "%s: Invalid argument to --block-list"
+msgstr "%s: Ungültiges Argument für --block-list"
+
+#: src/xz/args.c:73
+#, c-format
+msgid "%s: Too many arguments to --block-list"
+msgstr "%s: Zu viele Argumente für --block-list"
+
+#: src/xz/args.c:102
+msgid "0 can only be used as the last element in --block-list"
+msgstr "0 kann nur das letzte Element in --block-list sein"
+
+#: src/xz/args.c:406
 #, c-format
 msgid "%s: Unknown file format type"
-msgstr "%s: Unbekanntes file format"
+msgstr "%s: Unbekanntes Dateiformat"
 
-#: src/xz/args.c:361 src/xz/args.c:369
+#: src/xz/args.c:429 src/xz/args.c:437
 #, c-format
 msgid "%s: Unsupported integrity check type"
-msgstr "%s: Integritäts-Check Typ nicht unterstützt"
+msgstr "%s: Integritäts-Check-Typ nicht unterstützt"
 
-#: src/xz/args.c:396
+#: src/xz/args.c:473
 msgid "Only one file can be specified with `--files' or `--files0'."
-msgstr ""
-"Nur ein file kann als Argument für --files oder --files0 angegeben werden."
+msgstr "Nur eine Datei kann als Argument für --files oder --files0 angegeben werden."
 
-#: src/xz/args.c:459
+#: src/xz/args.c:541
 #, c-format
 msgid "The environment variable %s contains too many arguments"
 msgstr "Die Umgebungsvariable %s enthält zu viele Argumente"
 
-#: src/xz/coder.c:105
+#: src/xz/coder.c:110
 msgid "Maximum number of filters is four"
 msgstr "Maximal vier Filter möglich"
 
-#: src/xz/coder.c:118
+#: src/xz/coder.c:129
 msgid "Memory usage limit is too low for the given filter setup."
-msgstr ""
-"Das Speicher Limit ist zu niedrig für die gegebene Filter Konfiguration."
+msgstr "Das Speicher-Limit ist zu niedrig für die gegebene Filter-Konfiguration."
 
-#: src/xz/coder.c:148
+#: src/xz/coder.c:159
 msgid "Using a preset in raw mode is discouraged."
-msgstr "Verwendung der Voreinstellung im raw Modus wird nicht empfohlen."
+msgstr "Verwendung einer Voreinstellung im Raw-Modus wird nicht empfohlen."
 
-#: src/xz/coder.c:150
+#: src/xz/coder.c:161
 msgid "The exact options of the presets may vary between software versions."
-msgstr ""
-"Die genauen Optionen der Voreinstellung können zwischen Software Versionen "
-"variieren."
-
-#: src/xz/coder.c:176
-msgid "The .lzma format supports only the LZMA1 filter"
-msgstr "Das .lzma Format unterstützt nur den LZMA1 Filter"
+msgstr "Die genauen Optionen der Voreinstellung können zwischen Softwareversionen variieren."
 
 #: src/xz/coder.c:184
-msgid "LZMA1 cannot be used with the .xz format"
-msgstr "LZMA1 kann nicht mit dem .xz Format verwendet werden"
+msgid "The .lzma format supports only the LZMA1 filter"
+msgstr "Das .lzma-Format unterstützt nur den LZMA1-Filter"
 
-#: src/xz/coder.c:203
+#: src/xz/coder.c:192
+msgid "LZMA1 cannot be used with the .xz format"
+msgstr "LZMA1 kann nicht mit dem .xz-Format verwendet werden"
+
+#: src/xz/coder.c:209
+msgid "The filter chain is incompatible with --flush-timeout"
+msgstr "Diese Filterkette ist inkompatibel zu --flush-timeout"
+
+#: src/xz/coder.c:215
+msgid "Switching to single-threaded mode due to --flush-timeout"
+msgstr "Schalte um auf Single-Thread-Modus wegen --flush-timeout"
+
+#: src/xz/coder.c:234
+#, c-format
 msgid "Using up to %<PRIu32> threads."
 msgstr "Benutze bis zu %<PRIu32> Threads."
 
-#: src/xz/coder.c:216
+#: src/xz/coder.c:247
 msgid "Unsupported filter chain or filter options"
 msgstr "Optionen nicht unterstützt"
 
-#: src/xz/coder.c:224
+#: src/xz/coder.c:255
 #, c-format
 msgid "Decompression will need %s MiB of memory."
-msgstr "Dekompression wird %s MiB Speicher brauchen."
+msgstr "Dekomprimierung wird %s MiB Speicher brauchen."
 
-#: src/xz/coder.c:259
-msgid ""
-"Adjusted the number of threads from %s to %s to not exceed the memory usage "
-"limit of %s MiB"
-msgstr ""
-"Passte die Anzahl Threads von %s auf %s an um nicht das Speicher "
-"Nutzungslimit von %s MiB zu übersteigen"
-
-#: src/xz/coder.c:313
+#: src/xz/coder.c:290
 #, c-format
-msgid ""
-"Adjusted LZMA%c dictionary size from %s MiB to %s MiB to not exceed the "
-"memory usage limit of %s MiB"
-msgstr ""
-"Passte LZMA%c Wörterbuch Größe von %s MiB to %s MiB an, um nicht das "
-"Speicher Nutzungslimit von %s MiB zu übersteigen"
+msgid "Adjusted the number of threads from %s to %s to not exceed the memory usage limit of %s MiB"
+msgstr "Passte die Anzahl Threads von %s auf %s an um nicht das Speichernutzungslimit von %s MiB zu übersteigen"
+
+#: src/xz/coder.c:344
+#, c-format
+msgid "Adjusted LZMA%c dictionary size from %s MiB to %s MiB to not exceed the memory usage limit of %s MiB"
+msgstr "Passte LZMA%c-Wörterbuchgröße von %s MiB to %s MiB an, um nicht das Speichernutzungslimit von %s MiB zu übersteigen"
+
+#: src/xz/file_io.c:100 src/xz/file_io.c:108
+#, c-format
+msgid "Error creating a pipe: %s"
+msgstr "Fehler beim Erzeugen der Pipeline: %s"
+
+#: src/xz/file_io.c:163
+msgid "Sandbox is disabled due to incompatible command line arguments"
+msgstr "Sandbox ist wegen inkompatibler Kommandozeilenargumente deaktiviert"
+
+#: src/xz/file_io.c:206
+msgid "Sandbox was successfully enabled"
+msgstr "Sandbox wurde erfolgreich aktiviert"
+
+#: src/xz/file_io.c:210
+msgid "Failed to enable the sandbox"
+msgstr "Konnte Sandbox nicht aktivieren"
+
+#: src/xz/file_io.c:252
+#, c-format
+msgid "%s: poll() failed: %s"
+msgstr "%s: poll() Fehler: %s"
 
 #. TRANSLATORS: When compression or decompression finishes,
 #. and xz is going to remove the source file, xz first checks
@@ -102,116 +137,128 @@
 #. it is possible that the user has put a new file in place
 #. of the original file, and in that case it obviously
 #. shouldn't be removed.
-#: src/xz/file_io.c:136
+#: src/xz/file_io.c:322
 #, c-format
 msgid "%s: File seems to have been moved, not removing"
-msgstr ""
-"%s: Datei scheint umbenannt worden zu sein, daher wird sie nicht gelöscht"
+msgstr "%s: Datei scheint umbenannt worden zu sein, daher wird sie nicht gelöscht"
 
-#: src/xz/file_io.c:143 src/xz/file_io.c:635
+#: src/xz/file_io.c:329 src/xz/file_io.c:847
 #, c-format
 msgid "%s: Cannot remove: %s"
 msgstr "%s: Kann nicht löschen: %s"
 
-#: src/xz/file_io.c:168
+#: src/xz/file_io.c:354
 #, c-format
 msgid "%s: Cannot set the file owner: %s"
-msgstr "%s: Kann Datei Eigentümer nicht setzen: %s"
+msgstr "%s: Kann Dateieigentümer nicht setzen: %s"
 
-#: src/xz/file_io.c:174
+#: src/xz/file_io.c:360
 #, c-format
 msgid "%s: Cannot set the file group: %s"
-msgstr "%s: Kann Datei Gruppe nicht setzen: %s"
+msgstr "%s: Kann Dateigruppe nicht setzen: %s"
 
-#: src/xz/file_io.c:193
+#: src/xz/file_io.c:379
 #, c-format
 msgid "%s: Cannot set the file permissions: %s"
 msgstr "%s: Kann Zugriffsrechte nicht setzen: %s"
 
-#: src/xz/file_io.c:340 src/xz/file_io.c:423
+#: src/xz/file_io.c:489
+#, c-format
+msgid "Error getting the file status flags from standard input: %s"
+msgstr "Kann Status-Flags der Standardeingabe nicht ermitteln: %s"
+
+#: src/xz/file_io.c:543 src/xz/file_io.c:605
 #, c-format
 msgid "%s: Is a symbolic link, skipping"
-msgstr "%s: Überspringe symbolischen Verweis"
+msgstr "%s: Überspringe symbolischen Link"
 
-#: src/xz/file_io.c:468
+#: src/xz/file_io.c:634
 #, c-format
 msgid "%s: Is a directory, skipping"
 msgstr "%s: Überspringe Verzeichnis"
 
-#: src/xz/file_io.c:474
+#: src/xz/file_io.c:640
 #, c-format
 msgid "%s: Not a regular file, skipping"
 msgstr "%s: Keine reguläre Datei, überspringe"
 
-#: src/xz/file_io.c:491
+#: src/xz/file_io.c:657
 #, c-format
 msgid "%s: File has setuid or setgid bit set, skipping"
-msgstr "%s: Datei hat das setuid oder setgid Bit gesetzt, überspringe"
+msgstr "%s: Datei hat das setuid- oder setgid-Bit gesetzt, überspringe"
 
-#: src/xz/file_io.c:498
+#: src/xz/file_io.c:664
 #, c-format
 msgid "%s: File has sticky bit set, skipping"
-msgstr "%s: Datei hat sticky Bit gesetzt, überspringe"
+msgstr "%s: Datei hat sticky-Bit gesetzt, überspringe"
 
-#: src/xz/file_io.c:505
+#: src/xz/file_io.c:671
 #, c-format
 msgid "%s: Input file has more than one hard link, skipping"
-msgstr "%s: Eingabedatei hat mehr als einen hard link, überspringe"
+msgstr "%s: Eingabedatei hat mehr als einen Hard Link, überspringe"
 
-#: src/xz/file_io.c:761
+#: src/xz/file_io.c:756
+#, c-format
+msgid "Error restoring the status flags to standard input: %s"
+msgstr "Fehler beim Wiederherstellen der Status-Flags für die Standardausgabe: %s"
+
+#: src/xz/file_io.c:805
+#, c-format
+msgid "Error getting the file status flags from standard output: %s"
+msgstr "Kann Status-Flags der Standardausgabe nicht ermitteln: %s"
+
+#: src/xz/file_io.c:983
 #, c-format
 msgid "Error restoring the O_APPEND flag to standard output: %s"
-msgstr ""
-"Fehler beim Wiederherstellen des O_APPEND flags bei Standard Output: %s"
+msgstr "Fehler beim Wiederherstellen des O_APPEND-Flags bei Standardausgabe: %s"
 
-#: src/xz/file_io.c:773
+#: src/xz/file_io.c:995
 #, c-format
 msgid "%s: Closing the file failed: %s"
-msgstr "%s: Fehler beim Schießen der Datei: %s"
+msgstr "%s: Fehler beim Schließen der Datei: %s"
 
-#: src/xz/file_io.c:809 src/xz/file_io.c:1008
+#: src/xz/file_io.c:1031 src/xz/file_io.c:1257
 #, c-format
 msgid "%s: Seeking failed when trying to create a sparse file: %s"
-msgstr ""
-"%s: Positionierungsfehler beim Versuch eine sparse Datei zu erzeugen: %s"
+msgstr "%s: Positionierungsfehler beim Versuch eine sparse (dünnbesetzte) Datei zu erzeugen: %s"
 
-#: src/xz/file_io.c:883
+#: src/xz/file_io.c:1126
 #, c-format
 msgid "%s: Read error: %s"
 msgstr "%s: Lesefehler: %s"
 
-#: src/xz/file_io.c:906
+#: src/xz/file_io.c:1146
 #, c-format
 msgid "%s: Error seeking the file: %s"
 msgstr "%s: Fehler beim Lesen der Dateinamen: %s"
 
-#: src/xz/file_io.c:916
+#: src/xz/file_io.c:1156
 #, c-format
 msgid "%s: Unexpected end of file"
 msgstr "%s: Unerwartetes Ende der Datei"
 
-#: src/xz/file_io.c:966
+#: src/xz/file_io.c:1215
 #, c-format
 msgid "%s: Write error: %s"
 msgstr "%s: Schreibfehler: %s"
 
-#: src/xz/hardware.c:101
+#: src/xz/hardware.c:107
 msgid "Disabled"
 msgstr "Deaktiviert"
 
 #. TRANSLATORS: Test with "xz --info-memory" to see if
 #. the alignment looks nice.
-#: src/xz/hardware.c:120
+#: src/xz/hardware.c:126
 msgid "Total amount of physical memory (RAM): "
-msgstr "Gesamtmenge physikalischer Speicher (RAM): "
+msgstr "Gesamtmenge physikalischer Speicher (RAM):  "
 
-#: src/xz/hardware.c:122
+#: src/xz/hardware.c:128
 msgid "Memory usage limit for compression:    "
-msgstr "Speicher Nutzungslimit für Kompression:    "
+msgstr "Speichernutzungslimit für Komprimierung:    "
 
-#: src/xz/hardware.c:124
+#: src/xz/hardware.c:130
 msgid "Memory usage limit for decompression:  "
-msgstr "Speicher Nutzungslimit für Dekompression:  "
+msgstr "Speichernutzungslimit für Dekomprimierung:  "
 
 #. TRANSLATORS: Indicates that there is no integrity check.
 #. This string is used in tables, so the width must not
@@ -281,76 +328,72 @@
 #: src/xz/list.c:158
 #, c-format
 msgid "%s: Too small to be a valid .xz file"
-msgstr "%s: Zu klein um ein gültiges .xz file zu sein"
+msgstr "%s: Zu klein um eine gültige .xz-Datei zu sein"
 
 #. TRANSLATORS: These are column headings. From Strms (Streams)
 #. to Ratio, the columns are right aligned. Check and Filename
 #. are left aligned. If you need longer words, it's OK to
 #. use two lines here. Test with "xz -l foo.xz".
-#: src/xz/list.c:645
+#: src/xz/list.c:671
 msgid "Strms  Blocks   Compressed Uncompressed  Ratio  Check   Filename"
 msgstr " Str.  Blöcke       Kompr.     Unkompr.  Verh.  Check   Dateiname"
 
-#: src/xz/list.c:685
+#: src/xz/list.c:711
 #, c-format
 msgid "  Streams:            %s\n"
 msgstr "  Ströme:              %s\n"
 
-#: src/xz/list.c:687
+#: src/xz/list.c:713
 #, c-format
 msgid "  Blocks:             %s\n"
 msgstr "  Blöcke:              %s\n"
 
-#: src/xz/list.c:689
+#: src/xz/list.c:715
 #, c-format
 msgid "  Compressed size:    %s\n"
 msgstr "  Größe komprimiert:   %s\n"
 
-#: src/xz/list.c:692
+#: src/xz/list.c:718
 #, c-format
 msgid "  Uncompressed size:  %s\n"
 msgstr "  Größe unkomprimiert: %s\n"
 
-#: src/xz/list.c:695
+#: src/xz/list.c:721
 #, c-format
 msgid "  Ratio:              %s\n"
 msgstr "  Verhältnis:          %s\n"
 
-#: src/xz/list.c:697
+#: src/xz/list.c:723
 #, c-format
 msgid "  Check:              %s\n"
 msgstr "  Check:               %s\n"
 
-#: src/xz/list.c:698
+#: src/xz/list.c:724
 #, c-format
 msgid "  Stream padding:     %s\n"
-msgstr "  Strom Auffüllung:    %s\n"
+msgstr "  Strom-Auffüllung:    %s\n"
 
 #. TRANSLATORS: The second line is column headings. All except
 #. Check are right aligned; Check is left aligned. Test with
 #. "xz -lv foo.xz".
-#: src/xz/list.c:726
+#: src/xz/list.c:752
 msgid ""
 "  Streams:\n"
-"    Stream    Blocks      CompOffset    UncompOffset        CompSize      "
-"UncompSize  Ratio  Check      Padding"
+"    Stream    Blocks      CompOffset    UncompOffset        CompSize      UncompSize  Ratio  Check      Padding"
 msgstr ""
 "  Ströme:\n"
-"     Strom    Blöcke      KompOffset    UnkompOffset       KompGröße     "
-"UnkompGröße  Verh.  Check   Auffüllung"
+"     Strom    Blöcke      KompOffset    UnkompOffset       KompGröße     UnkompGröße  Verh.  Check   Auffüllung"
 
 #. TRANSLATORS: The second line is column headings. All
 #. except Check are right aligned; Check is left aligned.
-#: src/xz/list.c:781
+#: src/xz/list.c:807
 #, c-format
 msgid ""
 "  Blocks:\n"
-"    Stream     Block      CompOffset    UncompOffset       TotalSize      "
-"UncompSize  Ratio  Check"
+"    Stream     Block      CompOffset    UncompOffset       TotalSize      UncompSize  Ratio  Check"
 msgstr ""
 "  Blöcke:\n"
-"     Strom     Block      KompOffset    UnkompOffset      TotalGröße     "
-"UnkompGröße  Verh.  Check"
+"     Strom     Block      KompOffset    UnkompOffset      TotalGröße     UnkompGröße  Verh.  Check"
 
 #. TRANSLATORS: These are additional column headings
 #. for the most verbose listing mode. CheckVal
@@ -359,58 +402,57 @@
 #. are right aligned. %*s is replaced with 0-120
 #. spaces to make the CheckVal column wide enough.
 #. Test with "xz -lvv foo.xz".
-#: src/xz/list.c:793
+#: src/xz/list.c:819
 #, c-format
 msgid "      CheckVal %*s Header  Flags        CompSize    MemUsage  Filters"
 msgstr "      CheckWert %*s  Kopf  Schalter    KompGröße    Speicher  Filter"
 
-#: src/xz/list.c:871 src/xz/list.c:1046
+#: src/xz/list.c:897 src/xz/list.c:1072
 #, c-format
 msgid "  Memory needed:      %s MiB\n"
 msgstr "  Benötigter Speicher: %s MiB\n"
 
-#: src/xz/list.c:873 src/xz/list.c:1048
+#: src/xz/list.c:899 src/xz/list.c:1074
 #, c-format
 msgid "  Sizes in headers:   %s\n"
 msgstr "  Größe in Köpfen:     %s\n"
 
-#: src/xz/list.c:874 src/xz/list.c:1049
+#: src/xz/list.c:900 src/xz/list.c:1075
 msgid "Yes"
 msgstr "Ja"
 
-#: src/xz/list.c:874 src/xz/list.c:1049
+#: src/xz/list.c:900 src/xz/list.c:1075
 msgid "No"
 msgstr "Nein"
 
-#: src/xz/list.c:875 src/xz/list.c:1050
+#: src/xz/list.c:901 src/xz/list.c:1076
 #, c-format
 msgid "  Minimum XZ Utils version: %s\n"
-msgstr "  Kleinste XZ Utils version: %s\n"
+msgstr "  Kleinste XZ Utils-Version: %s\n"
 
 #. TRANSLATORS: %s is an integer. Only the plural form of this
 #. message is used (e.g. "2 files"). Test with "xz -l foo.xz bar.xz".
-#: src/xz/list.c:1025
+#: src/xz/list.c:1051
 #, c-format
 msgid "%s file\n"
 msgid_plural "%s files\n"
 msgstr[0] "%s Datei\n"
 msgstr[1] "%s Dateien\n"
 
-#: src/xz/list.c:1038
+#: src/xz/list.c:1064
 msgid "Totals:"
 msgstr "Gesamt:"
 
-#: src/xz/list.c:1039
+#: src/xz/list.c:1065
 #, c-format
 msgid "  Number of files:    %s\n"
 msgstr "   Anzahl Dateien:     %s\n"
 
-#: src/xz/list.c:1114
+#: src/xz/list.c:1140
 msgid "--list works only on .xz files (--format=xz or --format=auto)"
-msgstr ""
-"--list funktioniert nur mit .xz Dateien (--format=xz oder --format=auto)"
+msgstr "--list funktioniert nur mit .xz-Dateien (--format=xz oder --format=auto)"
 
-#: src/xz/list.c:1120
+#: src/xz/list.c:1146
 msgid "--list does not support reading from standard input"
 msgstr "--list unterstützt kein Lesen der Standardeingabe"
 
@@ -426,93 +468,83 @@
 
 #: src/xz/main.c:120
 #, c-format
-msgid ""
-"%s: Null character found when reading filenames; maybe you meant to use `--"
-"files0' instead of `--files'?"
-msgstr ""
-"%s: Null Charakter gefunden beim Lesen der Dateinamen; Meinten Sie `--"
-"files0' statt `--files'?"
+msgid "%s: Null character found when reading filenames; maybe you meant to use `--files0' instead of `--files'?"
+msgstr "%s: Null-Zeichen gefunden beim Lesen der Dateinamen; Meinten Sie `--files0' statt `--files'?"
 
 #: src/xz/main.c:174
 msgid "Compression and decompression with --robot are not supported yet."
-msgstr "Kompression und Dekompression mit --robot ist noch nicht unterstützt."
+msgstr "Komprimierung und Dekomprimierung mit --robot ist noch nicht unterstützt."
 
-#: src/xz/main.c:231
-msgid ""
-"Cannot read data from standard input when reading filenames from standard "
-"input"
-msgstr ""
-"Lesen der Standardeingabe ist nicht möglich, wenn die Dateinamen auch von "
-"der Standardeingabe gelesen werden"
+#: src/xz/main.c:249
+msgid "Cannot read data from standard input when reading filenames from standard input"
+msgstr "Lesen der Standardeingabe ist nicht möglich, wenn die Dateinamen auch von der Standardeingabe gelesen werden"
 
 #. TRANSLATORS: This is the program name in the beginning
 #. of the line in messages. Usually it becomes "xz: ".
 #. This is a translatable string because French needs
 #. a space before a colon.
-#: src/xz/message.c:733
+#: src/xz/message.c:714
 #, c-format
 msgid "%s: "
-msgstr ""
+msgstr "%s: "
 
-#: src/xz/message.c:796 src/xz/message.c:846
+#: src/xz/message.c:777 src/xz/message.c:827
 msgid "Internal error (bug)"
 msgstr "Interner Fehler (Bug)"
 
-#: src/xz/message.c:803
+#: src/xz/message.c:784
 msgid "Cannot establish signal handlers"
-msgstr "Kann Signal Routine nicht setzen"
+msgstr "Kann Signalroutine nicht setzen"
 
-#: src/xz/message.c:812
+#: src/xz/message.c:793
 msgid "No integrity check; not verifying file integrity"
 msgstr "Kein Integritäts-Check; werde Datei-Integrität nicht überprüfen"
 
-#: src/xz/message.c:815
+#: src/xz/message.c:796
 msgid "Unsupported type of integrity check; not verifying file integrity"
-msgstr ""
-"Typ des Integritäts-Checks nicht unterstützt; werde Datei-Integrität nicht "
-"überprüfen"
+msgstr "Typ des Integritäts-Checks nicht unterstützt; werde Datei-Integrität nicht überprüfen"
 
-#: src/xz/message.c:822
+#: src/xz/message.c:803
 msgid "Memory usage limit reached"
-msgstr "Speicher-Limit erreicht"
+msgstr "Speichernutzungslimit erreicht"
 
-#: src/xz/message.c:825
+#: src/xz/message.c:806
 msgid "File format not recognized"
-msgstr "Datei Format nicht erkannt"
+msgstr "Dateiformat nicht erkannt"
 
-#: src/xz/message.c:828
+#: src/xz/message.c:809
 msgid "Unsupported options"
 msgstr "Optionen nicht unterstützt"
 
-#: src/xz/message.c:831
+#: src/xz/message.c:812
 msgid "Compressed data is corrupt"
 msgstr "Komprimierte Daten sind korrupt"
 
-#: src/xz/message.c:834
+#: src/xz/message.c:815
 msgid "Unexpected end of input"
-msgstr "Unerwartetes Eingabe Ende"
+msgstr "Unerwartetes Ende der Eingabe"
 
-#: src/xz/message.c:867
+#: src/xz/message.c:848
 #, c-format
 msgid "%s MiB of memory is required. The limiter is disabled."
 msgstr "%s MiB Speicher wird benötigt. Der Begrenzer ist deaktiviert."
 
-#: src/xz/message.c:895
+#: src/xz/message.c:876
 #, c-format
 msgid "%s MiB of memory is required. The limit is %s."
 msgstr "%s MiB Speicher wird benötigt. Limit ist %s."
 
-#: src/xz/message.c:1062
+#: src/xz/message.c:1043
 #, c-format
 msgid "%s: Filter chain: %s\n"
-msgstr "%s: Filter Kette: %s\n"
+msgstr "%s: Filterkette: %s\n"
 
-#: src/xz/message.c:1072
+#: src/xz/message.c:1053
 #, c-format
 msgid "Try `%s --help' for more information."
 msgstr "Versuchen Sie `%s --help' für mehr Informationen."
 
-#: src/xz/message.c:1098
+#: src/xz/message.c:1079
 #, c-format
 msgid ""
 "Usage: %s [OPTION]... [FILE]...\n"
@@ -520,33 +552,32 @@
 "\n"
 msgstr ""
 "Benutzung: %s [OPTION]... [DATEI]...\n"
-"Komprimiert oder dekomprimiert .xz DATEI(EN).\n"
+"Komprimiert oder dekomprimiert .xz-DATEI(EN).\n"
 "\n"
 
-#: src/xz/message.c:1105
-msgid ""
-"Mandatory arguments to long options are mandatory for short options too.\n"
+#: src/xz/message.c:1086
+msgid "Mandatory arguments to long options are mandatory for short options too.\n"
 msgstr ""
 "Obligatorische Argumente für lange Optionen sind auch für kurze Optionen\n"
 "zwingend.\n"
 
-#: src/xz/message.c:1109
+#: src/xz/message.c:1090
 msgid " Operation mode:\n"
 msgstr " Operationsmodus:\n"
 
-#: src/xz/message.c:1112
+#: src/xz/message.c:1093
 msgid ""
 "  -z, --compress      force compression\n"
 "  -d, --decompress    force decompression\n"
 "  -t, --test          test compressed file integrity\n"
 "  -l, --list          list information about .xz files"
 msgstr ""
-"  -z, --compress        erzwinge Komprimierung\n"
-"  -d, --decompress      erzwinge Dekomprimierung\n"
-"  -t, --test            überprüfe Datei Integrität\n"
-"  -l, --list            liste Datei Informationen"
+"  -z, --compress        Erzwinge Komprimierung\n"
+"  -d, --decompress      Erzwinge Dekomprimierung\n"
+"  -t, --test            Überprüfe Dateiintegrität\n"
+"  -l, --list            Führe Dateiinformationen auf"
 
-#: src/xz/message.c:1118
+#: src/xz/message.c:1099
 msgid ""
 "\n"
 " Operation modifiers:\n"
@@ -554,148 +585,170 @@
 "\n"
 " Operationsmodifikatoren:\n"
 
-#: src/xz/message.c:1121
+#: src/xz/message.c:1102
 msgid ""
 "  -k, --keep          keep (don't delete) input files\n"
 "  -f, --force         force overwrite of output file and (de)compress links\n"
 "  -c, --stdout        write to standard output and don't delete input files"
 msgstr ""
 "  -k, --keep            Eingabedateien beibehalten (nicht löschen)\n"
-"  -f, --force           erzwinge Überschreiben der Ausgabedatei und\n"
+"  -f, --force           Erzwinge Überschreiben der Ausgabedatei und\n"
 "                        (de)komprimiere Verweise (Links)\n"
-"  -c, --stdout          schreibe nach Standard Output und lösche nicht die\n"
+"  -c, --stdout          Schreibe nach Standardausgabe und lösche nicht die\n"
 "                        Eingabedateien"
 
-#: src/xz/message.c:1127
+#: src/xz/message.c:1108
 msgid ""
 "      --single-stream decompress only the first stream, and silently\n"
 "                      ignore possible remaining input data"
 msgstr ""
-"      --single-stream dekomprimiere nur den ersten Datenstrom und ignoriere\n"
-"                      stillschweigend mögliche weitere Eingabedaten"
+"      --single-stream   Dekomprimiere nur den ersten Datenstrom und ignoriere\n"
+"                        stillschweigend mögliche weitere Eingabedaten"
 
-#: src/xz/message.c:1130
+#: src/xz/message.c:1111
 msgid ""
 "      --no-sparse     do not create sparse files when decompressing\n"
 "  -S, --suffix=.SUF   use the suffix `.SUF' on compressed files\n"
 "      --files[=FILE]  read filenames to process from FILE; if FILE is\n"
 "                      omitted, filenames are read from the standard input;\n"
-"                      filenames must be terminated with the newline "
-"character\n"
+"                      filenames must be terminated with the newline character\n"
 "      --files0[=FILE] like --files but use the null character as terminator"
 msgstr ""
-"      --no-sparse       erzeuge keine sparse Datei beim Dekomprimieren\n"
-"  -S, --suffix=.SUF     benutze `.SUF' Endung für komprimierte Dateien\n"
-"      --files=[DATEI]   lese zu verarbeitende Dateinamen von DATEI; falls\n"
+"      --no-sparse       Erzeuge beim Dekomprimieren keine dünnbesetzten\n"
+"                        (sparse) Dateien\n"
+"  -S, --suffix=.SUF     Benutze `.SUF' als Endung für komprimierte Dateien\n"
+"      --files=[DATEI]   Lese zu verarbeitende Dateinamen von DATEI; falls\n"
 "                        DATEI nicht angegeben wurde, werden Dateinamen\n"
-"                        von Standard Input gelesen. Dateinamen müssen mit\n"
+"                        von der Standardeingabe gelesen. Dateinamen müssen mit\n"
 "                        einem Zeilenumbruch voneinander getrennt werden\n"
-"      --files0=[DATEI]  wie --files, aber benutze den Null Charakter als "
-"Trenner"
+"      --files0=[DATEI]  Wie --files, aber benutze das Null-Zeichen als Trenner"
 
-#: src/xz/message.c:1139
+#: src/xz/message.c:1120
 msgid ""
 "\n"
 " Basic file format and compression options:\n"
 msgstr ""
 "\n"
-" Grundlegende Optionen für Dateiformat und Kompression:\n"
+" Grundlegende Optionen für Dateiformat und Komprimierung:\n"
 
-#: src/xz/message.c:1141
+#: src/xz/message.c:1122
 msgid ""
 "  -F, --format=FMT    file format to encode or decode; possible values are\n"
 "                      `auto' (default), `xz', `lzma', and `raw'\n"
 "  -C, --check=CHECK   integrity check type: `none' (use with caution),\n"
 "                      `crc32', `crc64' (default), or `sha256'"
 msgstr ""
-"  -F, --format=FMT      Dateiformat zur Kodierung oder Dekodierung; "
-"mögliche\n"
-"                        Werte sind `auto' (Voreinstellung), `xz', `lzma' "
-"und\n"
+"  -F, --format=FMT      Dateiformat zur Kodierung oder Dekodierung; mögliche\n"
+"                        Werte sind `auto' (Voreinstellung), `xz', `lzma' und\n"
 "                        `raw'\n"
-"  -C, --check=CHECK     Typ des Integritätschecks: `none' (Vorsicht), "
-"`crc32',\n"
+"  -C, --check=CHECK     Typ des Integritätschecks: `none' (Vorsicht), `crc32',\n"
 "                        `crc64' (Voreinstellung), oder `sha256'"
 
+#: src/xz/message.c:1127
+msgid "      --ignore-check  don't verify the integrity check when decompressing"
+msgstr "     --ignore-check     überprüfe nicht den Integritätscheck beim Dekomprimieren"
+
+#: src/xz/message.c:1131
+msgid ""
+"  -0 ... -9           compression preset; default is 6; take compressor *and*\n"
+"                      decompressor memory usage into account before using 7-9!"
+msgstr ""
+"  -0 .. -9              Kompressionseinstellung; Voreinstellung is 6. Beachten\n"
+"                        Sie den Speicherverbrauch des Komprimierers *und* des\n"
+"                        Dekomprimierers, wenn Sie 7-9 benutzen!"
+
+#: src/xz/message.c:1135
+msgid ""
+"  -e, --extreme       try to improve compression ratio by using more CPU time;\n"
+"                      does not affect decompressor memory requirements"
+msgstr ""
+"  -e, --extreme         Versuche durch stärkere CPU-Nutzung das Kompressions-\n"
+"                        verhältnis zu verbessern. Dies beeinflusst nicht den\n"
+"                        Speicherbedarf des Dekomprimierers."
+
+#: src/xz/message.c:1139
+msgid ""
+"  -T, --threads=NUM   use at most NUM threads; the default is 1; set to 0\n"
+"                      to use as many threads as there are processor cores"
+msgstr ""
+"  -T, --threads=ZAHL    Erzeuge höchstens ZAHL viele Threads; die Grund-\n"
+"                        einstellung ist 1. Wenn der Wert 0 angegeben wird, dann\n"
+"                        werden so viele Threads erzeugt, wie es Prozessorkerne\n"
+"                        gibt"
+
+#: src/xz/message.c:1144
+msgid ""
+"      --block-size=SIZE\n"
+"                      start a new .xz block after every SIZE bytes of input;\n"
+"                      use this to set the block size for threaded compression"
+msgstr ""
+"      --block-size=GRÖẞE\n"
+"                        Beginne einen neuen .xz-Block nach GRÖẞE Bytes Eingabe;\n"
+"                        Benutzen Sie diese Option um die Block Größe für\n"
+"                        Komprimierung mit mehreren Threads zu setzen"
+
 #: src/xz/message.c:1148
 msgid ""
-"  -0 ... -9           compression preset; default is 6; take compressor "
-"*and*\n"
-"                      decompressor memory usage into account before using 7-"
-"9!"
+"      --block-list=SIZES\n"
+"                      start a new .xz block after the given comma-separated\n"
+"                      intervals of uncompressed data"
 msgstr ""
-"  -0 .. -9              Kompressionseinstellung; Voreinstellung is 6. "
-"Beachten\n"
-"                        Sie den Speicherverbrauch des Komprimieres *und* "
-"des\n"
-"                        Dekomprimierers, wenn Sie 7-9 benutzen!"
+"      --block-list=GRÖẞEN\n"
+"                        Beginne einen neuen .xz-Block gemäß der angegebenen,\n"
+"                        durch Kommata getrennten Intervalle an unkomprimierten\n"
+"                        Daten"
 
 #: src/xz/message.c:1152
 msgid ""
-"  -e, --extreme       try to improve compression ratio by using more CPU "
-"time;\n"
-"                      does not affect decompressor memory requirements"
+"      --flush-timeout=TIMEOUT\n"
+"                      when compressing, if more than TIMEOUT milliseconds has\n"
+"                      passed since the previous flush and reading more input\n"
+"                      would block, all pending data is flushed out"
 msgstr ""
-"  -e, --extreme         Versuche durch stärkere CPU Nutzung das "
-"Kompressions-\n"
-"                        verhältnis zu verbessern. Das beeinflusst nicht den\n"
-"                        Speicherbedarf des Dekomprimierers."
+"      --flush-timeout=ZEITÜBERSCHREITUNG\n"
+"                        Wenn beim Komprimieren mehr als ZEITÜBERSCHREITUNG\n"
+"                        Millisekunden seit der letzten Flush-Operation ver-\n"
+"                        gangen sind und das Lesen von zusätzlichen Eingabe-\n"
+"                        daten den Prozess blockieren würde, dann werden alle\n"
+"                        noch ausstehenden Daten geschrieben"
 
-#: src/xz/message.c:1157
-msgid ""
-"      --block-size=SIZE\n"
-"                      when compressing to the .xz format, start a new block\n"
-"                      after every SIZE Eingabe Bytes; 0=disabled (default)"
-msgstr ""
-"      --block-size=SIZE\n"
-"                      beim Komprimieren ins .xz Format, starte einen neuen\n"
-"                      Block nach jeweils SIZE Eingabe Bytes; 0=deaktiviert\n"
-"                      (Grundeinstellung)"
-
-#: src/xz/message.c:1161
+#: src/xz/message.c:1158
 #, no-c-format
 msgid ""
 "      --memlimit-compress=LIMIT\n"
 "      --memlimit-decompress=LIMIT\n"
 "  -M, --memlimit=LIMIT\n"
-"                      set memory usage limit for compression, "
-"decompression,\n"
+"                      set memory usage limit for compression, decompression,\n"
 "                      or both; LIMIT is in bytes, % of RAM, or 0 for defaults"
 msgstr ""
 "      --memlimit-compress=LIMIT\n"
 "      --memlimit-decompress=LIMIT\n"
-"  -M, --memlimit=LIMIT  Setze Speicher Nutzungslimit für Kompression,\n"
-"                        Dekompression, oder beides; LIMIT ist in bytes, % "
-"RAM,\n"
-"                        oder 0 für Grundeinstellungen."
+"  -M, --memlimit=LIMIT  Setze Speichernutzungslimit für Komprimierung,\n"
+"                        Dekomprimierung, oder beides; LIMIT ist in Bytes, % RAM,\n"
+"                        oder 0 für Verwenden der Grundeinstellungen."
 
-#: src/xz/message.c:1168
+#: src/xz/message.c:1165
 msgid ""
-"      --no-adjust     if compression settings exceed the memory usage "
-"limit,\n"
-"                      give an error instead of adjusting the settings "
-"downwards"
+"      --no-adjust     if compression settings exceed the memory usage limit,\n"
+"                      give an error instead of adjusting the settings downwards"
 msgstr ""
-"      --no-adjust       Wenn die Kompressionseinstellungen das Speicher\n"
-"                        Nutzungslimit übersteigen, erzeuge einen Fehler "
-"statt\n"
+"      --no-adjust       Wenn die Kompressionseinstellungen das Speicher-\n"
+"                        nutzungslimit übersteigen, erzeuge einen Fehler statt\n"
 "                        die Einstellungen nach unten anzupassen."
 
-#: src/xz/message.c:1174
+#: src/xz/message.c:1171
 msgid ""
 "\n"
 " Custom filter chain for compression (alternative for using presets):"
 msgstr ""
 "\n"
-" User-definierte Filter Kette für Kompression (alternativ zu Voreinstellung):"
+" Benutzerdef. Filterkette für Komprimierung (alternativ zu Voreinstellung):"
 
-#: src/xz/message.c:1183
+#: src/xz/message.c:1180
 msgid ""
 "\n"
-"  --lzma1[=OPTS]      LZMA1 or LZMA2; OPTS is a comma-separated list of zero "
-"or\n"
-"  --lzma2[=OPTS]      more of the following options (valid values; "
-"default):\n"
+"  --lzma1[=OPTS]      LZMA1 or LZMA2; OPTS is a comma-separated list of zero or\n"
+"  --lzma2[=OPTS]      more of the following options (valid values; default):\n"
 "                        preset=PRE reset options to a preset (0-9[e])\n"
 "                        dict=NUM   dictionary size (4KiB - 1536MiB; 8MiB)\n"
 "                        lc=NUM     number of literal context bits (0-4; 3)\n"
@@ -703,37 +756,28 @@
 "                        pb=NUM     number of position bits (0-4; 2)\n"
 "                        mode=MODE  compression mode (fast, normal; normal)\n"
 "                        nice=NUM   nice length of a match (2-273; 64)\n"
-"                        mf=NAME    match finder (hc3, hc4, bt2, bt3, bt4; "
-"bt4)\n"
-"                        depth=NUM  maximum search depth; 0=automatic "
-"(default)"
+"                        mf=NAME    match finder (hc3, hc4, bt2, bt3, bt4; bt4)\n"
+"                        depth=NUM  maximum search depth; 0=automatic (default)"
 msgstr ""
 "\n"
 "  --lzma1[=OPTIONEN]    LZMA1 oder LZMA2; OPTIONEN ist eine durch Kommata\n"
-"  --lzma2[=OPTIONEN]    getrennte Liste bestehend aus den folgenden "
-"Optionen\n"
+"  --lzma2[=OPTIONEN]    Getrennte Liste bestehend aus den folgenden Optionen\n"
 "                        (zulässige Werte; Voreinstellung):\n"
-"                          preset=NUM Setze Optionen zurück zu "
-"Voreinstellung\n"
+"                          preset=NUM Setze Optionen zurück zu Voreinstellung\n"
 "                                     (0-9[e])\n"
-"                          dict=NUM   Wörterbuch Größe (4 KiB - 1536 MiB; 8 "
-"MiB)\n"
-"                          lc=NUM     Anzahl der Literal Kontext Bits (0-4; "
-"3)\n"
-"                          lp=NUM     Anzahl der Literal Positionsbits (0-4; "
-"0)\n"
-"                          pb=NUM     Anzahl der Positionsbits (0-4; 2)\n"
-"                          mode=MODUS Kompressionsmodus (fast, normal; "
-"normal)\n"
+"                          dict=NUM   Wörterbuchgröße (4 KiB - 1536 MiB; 8 MiB)\n"
+"                          lc=NUM     Anzahl der Literal-Kontext-Bits (0-4; 3)\n"
+"                          lp=NUM     Anzahl der Literal-Positions-Bits (0-4; 0)\n"
+"                          pb=NUM     Anzahl der Positions-Bits (0-4; 2)\n"
+"                          mode=MODUS Kompressionsmodus (fast, normal; normal)\n"
 "                          nice=NUM   Nice-Länge eines Treffers (2-273; 64)\n"
 "                          mf=NAME    Algorithmus zum Auffinden von\n"
-"                                     Übereinstimmungen (hc3, hc4, bt2, bt3, "
-"bt4;\n"
+"                                     Übereinstimmungen (hc3, hc4, bt2, bt3, bt4;\n"
 "                                     bt4)\n"
 "                          depth=NUM  Maximale Suchtiefe; 0=automatisch\n"
 "                                     (Voreinstellung)"
 
-#: src/xz/message.c:1198
+#: src/xz/message.c:1195
 msgid ""
 "\n"
 "  --x86[=OPTS]        x86 BCJ filter (32-bit and 64-bit)\n"
@@ -746,17 +790,17 @@
 "                        start=NUM  start offset for conversions (default=0)"
 msgstr ""
 "\n"
-"  --x86[=OPTIONEN]      x86 BCJ Filter (32-bit und 64-bit)\n"
-"  --powerpc[=OPTIONEN]  PowerPC BCJ Filter (nur big endian)\n"
-"  --ia64[=OPTIONEN]     IA64 (Itanium) BCJ Filter\n"
-"  --arm[=OPTIONEN]      ARM BCJ Filter (nur little endian)\n"
-"  --armthumb[=OPTIONEN] ARM-Thumb BCJ Filter (nur little endian)\n"
-"  --sparc[=OPTIONEN]    SPARC BCJ Filter\n"
-"                        Zulässige Optionen für alle BCJ Filter:\n"
+"  --x86[=OPTIONEN]      x86 BCJ-Filter (32-bit und 64-bit)\n"
+"  --powerpc[=OPTIONEN]  PowerPC-BCJ-Filter (nur Big Endian)\n"
+"  --ia64[=OPTIONEN]     IA64-(Itanium-)BCJ-Filter\n"
+"  --arm[=OPTIONEN]      ARM-BCJ-Filter (nur Little Endian)\n"
+"  --armthumb[=OPTIONEN] ARM-Thumb-BCJ-Filter (nur Little Endian)\n"
+"  --sparc[=OPTIONEN]    SPARC-BCJ-Filter\n"
+"                        Zulässige Optionen für alle BCJ-Filter:\n"
 "                          start=NUM  Start-Offset für Konversion\n"
 "                          (Voreinstellung=0)"
 
-#: src/xz/message.c:1210
+#: src/xz/message.c:1207
 msgid ""
 "\n"
 "  --delta[=OPTS]      Delta filter; valid OPTS (valid values; default):\n"
@@ -764,13 +808,12 @@
 "                                   from each other (1-256; 1)"
 msgstr ""
 "\n"
-"  --delta[=OPTIONEN]    Delta Filter; zulässige Optionen (gültige Werte;\n"
+"  --delta[=OPTIONEN]    Delta-Filter; zulässige Optionen (gültige Werte;\n"
 "                        Voreinstellung):\n"
-"                          dist=NUM  Abstand zwischen den Bytes, die "
-"voneinander\n"
+"                          dist=NUM  Abstand zwischen den Bytes, die voneinander\n"
 "                                    subtrahiert werden (1-256; 1)"
 
-#: src/xz/message.c:1218
+#: src/xz/message.c:1215
 msgid ""
 "\n"
 " Other options:\n"
@@ -778,60 +821,55 @@
 "\n"
 " Andere Optionen:\n"
 
-#: src/xz/message.c:1221
+#: src/xz/message.c:1218
 msgid ""
-"  -q, --quiet         suppress warnings; specify twice to suppress errors "
-"too\n"
+"  -q, --quiet         suppress warnings; specify twice to suppress errors too\n"
 "  -v, --verbose       be verbose; specify twice for even more verbose"
 msgstr ""
-"  -q, --quiet           unterdrücke Warnungen; benutze diese Option zweimal\n"
+"  -q, --quiet           Unterdrücke Warnungen; benutze diese Option zweimal\n"
 "                        um auch Fehlermeldungen zu unterdrücken\n"
-"  -v, --verbose         sei gesprächig; benutze diese Option zweimal um "
-"noch\n"
+"  -v, --verbose         Sei gesprächig; benutze diese Option zweimal um noch\n"
 "                        gesprächiger zu sein"
 
-#: src/xz/message.c:1226
+#: src/xz/message.c:1223
 msgid "  -Q, --no-warn       make warnings not affect the exit status"
-msgstr "  -Q, --no-warn         Warnungen verändern nicht den exit status"
+msgstr "  -Q, --no-warn         Warnungen verändern nicht den Exit Status"
+
+#: src/xz/message.c:1225
+msgid "      --robot         use machine-parsable messages (useful for scripts)"
+msgstr ""
+"      --robot           Benutze maschinen-lesbare Meldungen (nützlich für\n"
+"                        Skripte)"
 
 #: src/xz/message.c:1228
 msgid ""
-"      --robot         use machine-parsable messages (useful for scripts)"
-msgstr ""
-"      --robot           benutze Maschinen-lesbare Meldungen (nützlich für\n"
-"                        Skripte)"
+"      --info-memory   display the total amount of RAM and the currently active\n"
+"                      memory usage limits, and exit"
+msgstr "      --info-memory     Zeige Speicherlimit an und terminiere"
 
 #: src/xz/message.c:1231
 msgid ""
-"      --info-memory   display the total amount of RAM and the currently "
-"active\n"
-"                      memory usage limits, and exit"
-msgstr "      --info-memory     zeige Speicherlimit an und terminiere"
-
-#: src/xz/message.c:1234
-msgid ""
 "  -h, --help          display the short help (lists only the basic options)\n"
 "  -H, --long-help     display this long help and exit"
 msgstr ""
-"  -h, --help            zeige kurze Hilfe and (zeigt nur die grundlegenden\n"
+"  -h, --help            Zeige kurze Hilfe an (zeigt nur die grundlegenden\n"
 "                        Optionen)\n"
-"  -H, --long-help       zeige diese lange Hilfe an und terminiere"
+"  -H, --long-help       Zeige diese lange Hilfe an und terminiere"
 
-#: src/xz/message.c:1238
+#: src/xz/message.c:1235
 msgid ""
 "  -h, --help          display this short help and exit\n"
 "  -H, --long-help     display the long help (lists also the advanced options)"
 msgstr ""
-"  -h, --help            zeige diese kurze Hilfe an und terminiere\n"
-"  -H, --long-help       zeige die lange Hilfe an (zeigt auch "
-"fortgeschrittene\n"
+"  -h, --help            Zeige diese kurze Hilfe an und terminiere\n"
+"  -H, --long-help       Zeige die lange Hilfe an (zeigt auch fortgeschrittene\n"
 "                        Optionen an)"
 
-#: src/xz/message.c:1243
+#: src/xz/message.c:1240
 msgid "  -V, --version       display the version number and exit"
-msgstr "  -V, --version         zeige Versionsnummer an und terminiere"
+msgstr "  -V, --version         Zeige Versionsnummer an und terminiere"
 
-#: src/xz/message.c:1245
+#: src/xz/message.c:1242
 msgid ""
 "\n"
 "With no FILE, or when FILE is -, read standard input.\n"
@@ -844,25 +882,26 @@
 #. for this package. Please add _another line_ saying
 #. "Report translation bugs to <...>\n" with the email or WWW
 #. address for translation bugs. Thanks.
-#: src/xz/message.c:1251
+#: src/xz/message.c:1248
 #, c-format
 msgid "Report bugs to <%s> (in English or Finnish).\n"
 msgstr ""
-"Melde Bugs an <%s> (in englisch oder finnisch).\n"
-"Melde Übersetzungsfehler an <maan@systemlinux.org> (in englisch oder "
-"deutsch).\n"
+"Melde Bugs an <%s> (auf Englisch oder Finnisch).\n"
+"Melde Übersetzungsfehler an <maan@tuebingen.mpg.de> (auf Engl. oder Deutsch).\n"
 
-#: src/xz/message.c:1253
+#: src/xz/message.c:1250
 #, c-format
 msgid "%s home page: <%s>\n"
 msgstr "%s Homepage: <%s>\n"
 
+#: src/xz/message.c:1254
+msgid "THIS IS A DEVELOPMENT VERSION NOT INTENDED FOR PRODUCTION USE."
+msgstr "DIES IST EINE NICHT FÜR DEN PRODUKTIVBETRIEB GEEIGNETE ENTWICKLERVERSION."
+
 #: src/xz/options.c:86
 #, c-format
 msgid "%s: Options must be `name=value' pairs separated with commas"
-msgstr ""
-"%s: Optionen müssen in der Form `Name=Wert` gegeben werden, getrennt durch "
-"Kommata"
+msgstr "%s: Optionen müssen in der Form `Name=Wert` gegeben werden, getrennt durch Kommata"
 
 #: src/xz/options.c:93
 #, c-format
@@ -886,17 +925,12 @@
 #: src/xz/options.c:359
 #, c-format
 msgid "The selected match finder requires at least nice=%<PRIu32>"
-msgstr ""
-"Der ausgewählte Algorithmus zum Auffinden von Übereinstimmungen braucht "
-"mindestens nice=%<PRIu32>"
+msgstr "Der ausgewählte Algorithmus zum Auffinden von Übereinstimmungen braucht mindestens nice=%<PRIu32>"
 
 #: src/xz/suffix.c:133 src/xz/suffix.c:258
 #, c-format
-msgid ""
-"%s: With --format=raw, --suffix=.SUF is required unless writing to stdout"
-msgstr ""
-"%s: Mit --format=raw ist --sufix=.SUF notwendig, falls nicht nach stdout "
-"geschrieben wird"
+msgid "%s: With --format=raw, --suffix=.SUF is required unless writing to stdout"
+msgstr "%s: Mit --format=raw ist --suffix=.SUF notwendig, falls nicht auf die Standardausgabe geschrieben wird"
 
 #: src/xz/suffix.c:164
 #, c-format
@@ -906,41 +940,41 @@
 #: src/xz/suffix.c:185
 #, c-format
 msgid "%s: File already has `%s' suffix, skipping"
-msgstr "%s: Datei hat bereits `%s' Endung, überspringe"
+msgstr "%s: Datei hat bereits `%s'-Endung, überspringe"
 
 #: src/xz/suffix.c:393
 #, c-format
 msgid "%s: Invalid filename suffix"
-msgstr "%s: Ungültige Datei Endung"
+msgstr "%s: Ungültige Dateiendung"
 
-#: src/xz/util.c:61
+#: src/xz/util.c:71
 #, c-format
 msgid "%s: Value is not a non-negative decimal integer"
 msgstr "%s: Wert ist keine nicht-negative ganze Zahl"
 
-#: src/xz/util.c:103
+#: src/xz/util.c:113
 #, c-format
 msgid "%s: Invalid multiplier suffix"
 msgstr "%s: Ungültige Einheit"
 
-#: src/xz/util.c:105
+#: src/xz/util.c:115
 msgid "Valid suffixes are `KiB' (2^10), `MiB' (2^20), and `GiB' (2^30)."
 msgstr "Gültige Einheiten sind `KiB' (2^10), `MiB' (2^20), und `GiB' (2^30)."
 
-#: src/xz/util.c:122
+#: src/xz/util.c:132
 #, c-format
 msgid "Value of the option `%s' must be in the range [%<PRIu64>, %<PRIu64>]"
 msgstr "Wert der Option `%s' muss im Bereich [%<PRIu64>, %<PRIu64>] sein"
 
-#: src/xz/util.c:247
+#: src/xz/util.c:257
 msgid "Empty filename, skipping"
-msgstr "Leere Dateiname, überspringe"
+msgstr "Leerer Dateiname, überspringe"
 
-#: src/xz/util.c:261
+#: src/xz/util.c:271
 msgid "Compressed data cannot be read from a terminal"
 msgstr "Komprimierte Daten können nicht vom Terminal gelesen werden"
 
-#: src/xz/util.c:274
+#: src/xz/util.c:284
 msgid "Compressed data cannot be written to a terminal"
 msgstr "Komprimierte Daten können nicht auf das Terminal geschrieben werden"
 
@@ -951,3 +985,9 @@
 #: src/common/tuklib_exit.c:42
 msgid "Unknown error"
 msgstr "Unbekannter Fehler"
+
+#~ msgid "Error setting O_NONBLOCK on standard input: %s"
+#~ msgstr "Fehler beim Setzen des O_NONBLOCK-Flags für Standardausgabe: %s"
+
+#~ msgid "Error setting O_NONBLOCK on standard output: %s"
+#~ msgstr "Fehler beim Setzen von O_NONBLOCK für die Standardausgabe: %s"
diff --git a/po/fr.po b/po/fr.po
index a21aa85..b85f46b 100644
--- a/po/fr.po
+++ b/po/fr.po
@@ -1,14 +1,14 @@
 # XZ Utils French Translation
 # This file is put in the public domain.
-# Adrien Nader <camaradetux@gmail.com>, 2011.
+# Adrien Nader <adrien@notk.org>, 2011-2014.
 #
 msgid ""
 msgstr ""
 "Project-Id-Version: xz-utils\n"
 "Report-Msgid-Bugs-To: lasse.collin@tukaani.org\n"
-"POT-Creation-Date: 2012-05-30 20:40+0200\n"
+"POT-Creation-Date: 2014-11-25 20:23+0100\n"
 "PO-Revision-Date: 2010-09-24 21;12+0200\n"
-"Last-Translator: Adrien Nader <camaradetux@gmail.com>\n"
+"Last-Translator: Adrien Nader <adrien@notk.org>\n"
 "Language-Team: None\n"
 "Language: fr\n"
 "MIME-Version: 1.0\n"
@@ -16,73 +16,105 @@
 "Content-Transfer-Encoding: 8bit\n"
 "Plural-Forms: nplurals=2; plural=(n==1) ? 0 : 1;\n"
 
-#: src/xz/args.c:338
+#: src/xz/args.c:63
+#, c-format
+msgid "%s: Invalid argument to --block-list"
+msgstr ""
+
+#: src/xz/args.c:73
+#, c-format
+msgid "%s: Too many arguments to --block-list"
+msgstr ""
+
+#: src/xz/args.c:102
+msgid "0 can only be used as the last element in --block-list"
+msgstr ""
+
+#: src/xz/args.c:406
 #, c-format
 msgid "%s: Unknown file format type"
 msgstr "%s : Format de fichier inconnu"
 
-#: src/xz/args.c:361 src/xz/args.c:369
+#: src/xz/args.c:429 src/xz/args.c:437
 #, c-format
 msgid "%s: Unsupported integrity check type"
 msgstr "%s : Type de vérification d'intégrité inconnu"
 
-#: src/xz/args.c:396
+#: src/xz/args.c:473
 msgid "Only one file can be specified with `--files' or `--files0'."
 msgstr "Un seul fichier peut être spécifié avec `--files' ou `--files0'."
 
-#: src/xz/args.c:459
+#: src/xz/args.c:541
 #, c-format
 msgid "The environment variable %s contains too many arguments"
 msgstr "La variable d'environnement %s contient trop d'arguments"
 
-#: src/xz/coder.c:105
+#: src/xz/coder.c:110
 msgid "Maximum number of filters is four"
 msgstr "Le nombre maximal de filtres est quatre"
 
-#: src/xz/coder.c:118
+#: src/xz/coder.c:129
 msgid "Memory usage limit is too low for the given filter setup."
 msgstr "La limite d'utilisation mémoire est trop basse pour la configuration de filtres donnée."
 
-#: src/xz/coder.c:148
+#: src/xz/coder.c:159
 msgid "Using a preset in raw mode is discouraged."
 msgstr "Utiliser un préréglage en mode `raw' est déconseillé."
 
-#: src/xz/coder.c:150
+#: src/xz/coder.c:161
 msgid "The exact options of the presets may vary between software versions."
 msgstr "Le détail des préréglages peut varier entre différentes versions du logiciel."
 
-#: src/xz/coder.c:176
+#: src/xz/coder.c:184
 msgid "The .lzma format supports only the LZMA1 filter"
 msgstr "Le format .lzma ne prend en charge que le filtre LZMA1"
 
-#: src/xz/coder.c:184
+#: src/xz/coder.c:192
 msgid "LZMA1 cannot be used with the .xz format"
 msgstr "Le filtre LZMA1 ne peut être utilisé avec le format .xz"
 
-#: src/xz/coder.c:203
+#: src/xz/coder.c:209
+msgid "The filter chain is incompatible with --flush-timeout"
+msgstr ""
+
+#: src/xz/coder.c:215
+msgid "Switching to single-threaded mode due to --flush-timeout"
+msgstr ""
+
+#: src/xz/coder.c:234
 #, c-format
 msgid "Using up to %<PRIu32> threads."
 msgstr "Jusqu'à %<PRIu32> threads seront utilisés."
 
-#: src/xz/coder.c:216
+#: src/xz/coder.c:247
 msgid "Unsupported filter chain or filter options"
 msgstr "Enchaînement ou options de filtres non pris en charge"
 
-#: src/xz/coder.c:224
+#: src/xz/coder.c:255
 #, c-format
 msgid "Decompression will need %s MiB of memory."
 msgstr "La décompression nécessitera %s MiB de mémoire."
 
-#: src/xz/coder.c:259
+#: src/xz/coder.c:290
 #, c-format
 msgid "Adjusted the number of threads from %s to %s to not exceed the memory usage limit of %s MiB"
 msgstr "Nombre de threads réduit de %s à %s pour ne pas dépasser la limite d'utilisation mémoire de %s MiB"
 
-#: src/xz/coder.c:313
+#: src/xz/coder.c:344
 #, c-format
 msgid "Adjusted LZMA%c dictionary size from %s MiB to %s MiB to not exceed the memory usage limit of %s MiB"
 msgstr "Taille du dictionnaire LZMA%c réduite de %s MiB à %s MiB pour ne pas dépasser la limite d'utilisation mémoire de %s MiB"
 
+#: src/xz/file_io.c:90
+#, c-format
+msgid "Error creating a pipe: %s"
+msgstr "Impossible de créer un tube anonyme (pipe) : %s"
+
+#: src/xz/file_io.c:166
+#, c-format
+msgid "%s: poll() failed: %s"
+msgstr "%s : L'appel à la fonction poll() a échoué : %s"
+
 #. TRANSLATORS: When compression or decompression finishes,
 #. and xz is going to remove the source file, xz first checks
 #. if the source file still exists, and if it does, does its
@@ -93,111 +125,146 @@
 #. it is possible that the user has put a new file in place
 #. of the original file, and in that case it obviously
 #. shouldn't be removed.
-#: src/xz/file_io.c:136
+#: src/xz/file_io.c:236
 #, c-format
 msgid "%s: File seems to have been moved, not removing"
 msgstr "%s : Le fichier a apparemment été déplacé, suppression annulée"
 
-#: src/xz/file_io.c:143 src/xz/file_io.c:635
+#: src/xz/file_io.c:243 src/xz/file_io.c:761
 #, c-format
 msgid "%s: Cannot remove: %s"
 msgstr "%s : Impossible de supprimer : %s"
 
-#: src/xz/file_io.c:168
+#: src/xz/file_io.c:268
 #, c-format
 msgid "%s: Cannot set the file owner: %s"
 msgstr "%s : Impossible de modifier le propriétaire du fichier : %s"
 
-#: src/xz/file_io.c:174
+#: src/xz/file_io.c:274
 #, c-format
 msgid "%s: Cannot set the file group: %s"
 msgstr "%s : Impossible de modifier le groupe propriétaire du fichier : %s"
 
-#: src/xz/file_io.c:193
+#: src/xz/file_io.c:293
 #, c-format
 msgid "%s: Cannot set the file permissions: %s"
 msgstr "%s : Impossible de modifier les permissions du fichier : %s"
 
-#: src/xz/file_io.c:340 src/xz/file_io.c:423
+# Note from translator on "file status flags".
+# The following entry is kept un-translated on purpose. It is difficult to
+# translate and should only happen in exceptional circumstances which means
+# that translating would:
+# - lose some of the meaning
+# - make it more difficult to look up in search engines; it might happen one in
+# a million times, if we dilute the error message in 20 languages, it will be
+# almost impossible to find an explanation and support for the error.
+#: src/xz/file_io.c:399
+#, c-format
+msgid "Error getting the file status flags from standard input: %s"
+msgstr ""
+
+#: src/xz/file_io.c:408
+#, c-format
+msgid "Error setting O_NONBLOCK on standard input: %s"
+msgstr "Impossible d'établir le drapeau O_NONBLOCK sur la sortie standard : %s"
+
+#: src/xz/file_io.c:460 src/xz/file_io.c:522
 #, c-format
 msgid "%s: Is a symbolic link, skipping"
 msgstr "%s est un lien symbolique : ignoré"
 
-#: src/xz/file_io.c:468
+#: src/xz/file_io.c:551
 #, c-format
 msgid "%s: Is a directory, skipping"
 msgstr "%s est un répertoire : ignoré"
 
-#: src/xz/file_io.c:474
+#: src/xz/file_io.c:557
 #, c-format
 msgid "%s: Not a regular file, skipping"
 msgstr "%s n'est pas un fichier régulier : ignoré"
 
-#: src/xz/file_io.c:491
+#: src/xz/file_io.c:574
 #, c-format
 msgid "%s: File has setuid or setgid bit set, skipping"
 msgstr "%s : Le fichier possède les bits `setuid' ou `setgid' : ignoré"
 
-#: src/xz/file_io.c:498
+#: src/xz/file_io.c:581
 #, c-format
 msgid "%s: File has sticky bit set, skipping"
 msgstr "%s : Le fichier possède le bit `sticky' : ignoré"
 
-#: src/xz/file_io.c:505
+#: src/xz/file_io.c:588
 #, c-format
 msgid "%s: Input file has more than one hard link, skipping"
 msgstr "%s : Le fichier d'entrée a plus d'un lien matériel : ignoré"
 
-#: src/xz/file_io.c:761
+# See note from translator above titled "file status flags".
+#: src/xz/file_io.c:668
+#, c-format
+msgid "Error restoring the status flags to standard input: %s"
+msgstr ""
+
+# See note from translator above titled "file status flags".
+#: src/xz/file_io.c:714
+#, c-format
+msgid "Error getting the file status flags from standard output: %s"
+msgstr ""
+
+#: src/xz/file_io.c:723
+#, c-format
+msgid "Error setting O_NONBLOCK on standard output: %s"
+msgstr "Impossible d'activer le drapeau O_NONBLOCK sur la sortie standard : %s"
+
+#: src/xz/file_io.c:896
 #, c-format
 msgid "Error restoring the O_APPEND flag to standard output: %s"
 msgstr "Impossible de rétablir le drapeau O_APPEND sur la sortie standard : %s"
 
-#: src/xz/file_io.c:773
+#: src/xz/file_io.c:908
 #, c-format
 msgid "%s: Closing the file failed: %s"
 msgstr "%s : Impossible de fermer le fichier : %s"
 
-#: src/xz/file_io.c:809 src/xz/file_io.c:1008
+#: src/xz/file_io.c:944 src/xz/file_io.c:1170
 #, c-format
 msgid "%s: Seeking failed when trying to create a sparse file: %s"
 msgstr "%s : Impossible de se déplacer dans le fichier pour créer un 'sparse file' : %s"
 
-#: src/xz/file_io.c:883
+#: src/xz/file_io.c:1039
 #, c-format
 msgid "%s: Read error: %s"
 msgstr "%s : Erreur d'écriture : %s"
 
-#: src/xz/file_io.c:906
+#: src/xz/file_io.c:1059
 #, c-format
 msgid "%s: Error seeking the file: %s"
 msgstr "%s : Impossible de se déplacer dans le fichier : %s"
 
-#: src/xz/file_io.c:916
+#: src/xz/file_io.c:1069
 #, c-format
 msgid "%s: Unexpected end of file"
 msgstr "%s : Fin de fichier inattendue"
 
-#: src/xz/file_io.c:966
+#: src/xz/file_io.c:1128
 #, c-format
 msgid "%s: Write error: %s"
 msgstr "%s : Erreur d'écriture : %s"
 
-#: src/xz/hardware.c:101
+#: src/xz/hardware.c:107
 msgid "Disabled"
 msgstr "Désactivé"
 
 #. TRANSLATORS: Test with "xz --info-memory" to see if
 #. the alignment looks nice.
-#: src/xz/hardware.c:120
+#: src/xz/hardware.c:126
 msgid "Total amount of physical memory (RAM): "
 msgstr "Quantité totale de mémoire physique (RAM) :  "
 
-#: src/xz/hardware.c:122
+#: src/xz/hardware.c:128
 msgid "Memory usage limit for compression:    "
 msgstr "Limite d'utilisation pour la compression :   "
 
-#: src/xz/hardware.c:124
+#: src/xz/hardware.c:130
 msgid "Memory usage limit for decompression:  "
 msgstr "Limite d'utilisation pour la décompression : "
 
@@ -275,41 +342,41 @@
 #. to Ratio, the columns are right aligned. Check and Filename
 #. are left aligned. If you need longer words, it's OK to
 #. use two lines here. Test with "xz -l foo.xz".
-#: src/xz/list.c:645
+#: src/xz/list.c:671
 msgid "Strms  Blocks   Compressed Uncompressed  Ratio  Check   Filename"
-msgstr "Flux    Blocs    Compressé  Décompressé  Ratio  Vérif   Nom de fichier"
+msgstr "Flux    Blocs    Compressé  Décompressé  Ratio  Vérif.  Nom de fichier"
 
-#: src/xz/list.c:685
+#: src/xz/list.c:711
 #, c-format
 msgid "  Streams:            %s\n"
 msgstr "  Flux :                            %s\n"
 
-#: src/xz/list.c:687
+#: src/xz/list.c:713
 #, c-format
 msgid "  Blocks:             %s\n"
 msgstr "  Blocs :                           %s\n"
 
-#: src/xz/list.c:689
+#: src/xz/list.c:715
 #, c-format
 msgid "  Compressed size:    %s\n"
-msgstr "  Taille compressé :                %s\n"
+msgstr "  Taille données avec compression : %s\n"
 
-#: src/xz/list.c:692
+#: src/xz/list.c:718
 #, c-format
 msgid "  Uncompressed size:  %s\n"
-msgstr "  Taille décompressé :              %s\n"
+msgstr "  Taille données sans compression : %s\n"
 
-#: src/xz/list.c:695
+#: src/xz/list.c:721
 #, c-format
 msgid "  Ratio:              %s\n"
 msgstr "  Ratio :                           %s\n"
 
-#: src/xz/list.c:697
+#: src/xz/list.c:723
 #, c-format
 msgid "  Check:              %s\n"
 msgstr "  Vérification :                    %s\n"
 
-#: src/xz/list.c:698
+#: src/xz/list.c:724
 #, c-format
 msgid "  Stream padding:     %s\n"
 msgstr "  Octets de rembourrage du flux :   %s\n"
@@ -317,7 +384,7 @@
 #. TRANSLATORS: The second line is column headings. All except
 #. Check are right aligned; Check is left aligned. Test with
 #. "xz -lv foo.xz".
-#: src/xz/list.c:726
+#: src/xz/list.c:752
 msgid ""
 "  Streams:\n"
 "    Stream    Blocks      CompOffset    UncompOffset        CompSize      UncompSize  Ratio  Check      Padding"
@@ -327,7 +394,7 @@
 
 #. TRANSLATORS: The second line is column headings. All
 #. except Check are right aligned; Check is left aligned.
-#: src/xz/list.c:781
+#: src/xz/list.c:807
 #, c-format
 msgid ""
 "  Blocks:\n"
@@ -343,57 +410,57 @@
 #. are right aligned. %*s is replaced with 0-120
 #. spaces to make the CheckVal column wide enough.
 #. Test with "xz -lvv foo.xz".
-#: src/xz/list.c:793
+#: src/xz/list.c:819
 #, c-format
 msgid "      CheckVal %*s Header  Flags        CompSize    MemUsage  Filters"
 msgstr "     ValVérif %*sEn-tête  Drapeaux   TailleComp     UtilMém  Filtres"
 
-#: src/xz/list.c:871 src/xz/list.c:1046
+#: src/xz/list.c:897 src/xz/list.c:1072
 #, c-format
 msgid "  Memory needed:      %s MiB\n"
 msgstr "  Mémoire nécessaire :              %s MiB\n"
 
-#: src/xz/list.c:873 src/xz/list.c:1048
+#: src/xz/list.c:899 src/xz/list.c:1074
 #, c-format
 msgid "  Sizes in headers:   %s\n"
 msgstr "  Tailles stockées dans l'en-tête : %s\n"
 
-#: src/xz/list.c:874 src/xz/list.c:1049
+#: src/xz/list.c:900 src/xz/list.c:1075
 msgid "Yes"
 msgstr "Oui"
 
-#: src/xz/list.c:874 src/xz/list.c:1049
+#: src/xz/list.c:900 src/xz/list.c:1075
 msgid "No"
 msgstr "Non"
 
-#: src/xz/list.c:875 src/xz/list.c:1050
+#: src/xz/list.c:901 src/xz/list.c:1076
 #, c-format
 msgid "  Minimum XZ Utils version: %s\n"
 msgstr "  Version minimale de XZ Utils : %s\n"
 
 #. TRANSLATORS: %s is an integer. Only the plural form of this
 #. message is used (e.g. "2 files"). Test with "xz -l foo.xz bar.xz".
-#: src/xz/list.c:1025
+#: src/xz/list.c:1051
 #, c-format
 msgid "%s file\n"
 msgid_plural "%s files\n"
 msgstr[0] "%s fichier\n"
 msgstr[1] "%s fichiers\n"
 
-#: src/xz/list.c:1038
+#: src/xz/list.c:1064
 msgid "Totals:"
 msgstr "Totaux :"
 
-#: src/xz/list.c:1039
+#: src/xz/list.c:1065
 #, c-format
 msgid "  Number of files:    %s\n"
 msgstr "  Nombre de fichiers : %s\n"
 
-#: src/xz/list.c:1114
+#: src/xz/list.c:1140
 msgid "--list works only on .xz files (--format=xz or --format=auto)"
 msgstr "--list ne marche que sur les fichiers .xz (--format=xz ou --format=auto)"
 
-#: src/xz/list.c:1120
+#: src/xz/list.c:1146
 msgid "--list does not support reading from standard input"
 msgstr "--list est incompatible avec la lecture sur l'entrée standard"
 
@@ -424,68 +491,68 @@
 #. of the line in messages. Usually it becomes "xz: ".
 #. This is a translatable string because French needs
 #. a space before a colon.
-#: src/xz/message.c:733
+#: src/xz/message.c:713
 #, c-format
 msgid "%s: "
 msgstr "%s : "
 
-#: src/xz/message.c:796 src/xz/message.c:846
+#: src/xz/message.c:776 src/xz/message.c:826
 msgid "Internal error (bug)"
 msgstr "Erreur interne (bug)"
 
-#: src/xz/message.c:803
+#: src/xz/message.c:783
 msgid "Cannot establish signal handlers"
 msgstr "Impossible d'installer le gestionnaire de signaux"
 
-#: src/xz/message.c:812
+#: src/xz/message.c:792
 msgid "No integrity check; not verifying file integrity"
 msgstr "Pas de données de vérification d'intégrité ; vérification non effectuée"
 
-#: src/xz/message.c:815
+#: src/xz/message.c:795
 msgid "Unsupported type of integrity check; not verifying file integrity"
 msgstr "Méthode de vérification d'intégrité non prise en charge ; vérification non effectuée"
 
-#: src/xz/message.c:822
+#: src/xz/message.c:802
 msgid "Memory usage limit reached"
 msgstr "Limite d'utilisation mémoire atteinte"
 
-#: src/xz/message.c:825
+#: src/xz/message.c:805
 msgid "File format not recognized"
 msgstr "Format de fichier inconnu"
 
-#: src/xz/message.c:828
+#: src/xz/message.c:808
 msgid "Unsupported options"
 msgstr "Options non prises en charge"
 
-#: src/xz/message.c:831
+#: src/xz/message.c:811
 msgid "Compressed data is corrupt"
 msgstr "Les données compressées sont corrompues"
 
-#: src/xz/message.c:834
+#: src/xz/message.c:814
 msgid "Unexpected end of input"
 msgstr "Fin des données inattendue "
 
-#: src/xz/message.c:867
+#: src/xz/message.c:847
 #, c-format
 msgid "%s MiB of memory is required. The limiter is disabled."
 msgstr "%s MiB de mémoire sont nécessaires. La limite est désactivée."
 
-#: src/xz/message.c:895
+#: src/xz/message.c:875
 #, c-format
 msgid "%s MiB of memory is required. The limit is %s."
 msgstr "%s MiB de mémoire sont nécessaires, la limite étant %s."
 
-#: src/xz/message.c:1062
+#: src/xz/message.c:1042
 #, c-format
 msgid "%s: Filter chain: %s\n"
 msgstr "%s : Enchaînement de filtres : %s\n"
 
-#: src/xz/message.c:1072
+#: src/xz/message.c:1052
 #, c-format
 msgid "Try `%s --help' for more information."
-msgstr "Utilisez `%s --help' pour plus d'informations."
+msgstr "Éxécutez `%s --help' pour obtenir davantage d'informations."
 
-#: src/xz/message.c:1098
+#: src/xz/message.c:1078
 #, c-format
 msgid ""
 "Usage: %s [OPTION]... [FILE]...\n"
@@ -496,57 +563,57 @@
 "Compresse ou decompresse FICHIER(s) au format .xz.\n"
 "\n"
 
-#: src/xz/message.c:1105
+#: src/xz/message.c:1085
 msgid "Mandatory arguments to long options are mandatory for short options too.\n"
 msgstr ""
 "Les arguments obligatoires pour les options longues le sont aussi pour les\n"
 "options courtes.\n"
 
-#: src/xz/message.c:1109
+#: src/xz/message.c:1089
 msgid " Operation mode:\n"
 msgstr " Mode d'opération :\n"
 
-#: src/xz/message.c:1112
+#: src/xz/message.c:1092
 msgid ""
 "  -z, --compress      force compression\n"
 "  -d, --decompress    force decompression\n"
 "  -t, --test          test compressed file integrity\n"
 "  -l, --list          list information about .xz files"
 msgstr ""
-"  -z, --compress      forcer la compression\n"
-"  -d, --decompress    forcer la décompression\n"
+"  -z, --compress      forcer le mode compression\n"
+"  -d, --decompress    forcer le mode décompression\n"
 "  -t, --test          tester l'intégrité du fichier compressé\n"
-"  -l, --list          lister les informations à propos des fichiers .xz"
+"  -l, --list          lister les informations sur les fichiers .xz"
 
-#: src/xz/message.c:1118
+#: src/xz/message.c:1098
 msgid ""
 "\n"
 " Operation modifiers:\n"
 msgstr ""
 "\n"
-" Modifictauers :\n"
+" Modificateurs :\n"
 
-#: src/xz/message.c:1121
+#: src/xz/message.c:1101
 msgid ""
 "  -k, --keep          keep (don't delete) input files\n"
 "  -f, --force         force overwrite of output file and (de)compress links\n"
 "  -c, --stdout        write to standard output and don't delete input files"
 msgstr ""
-"  -k, --keep          ne pas supprimer les fichiers d'entrée (\"keep\")\n"
-"  -f, --force         forcer l'écrasement du fichier de sortie et\n"
-"                      (dé)compresser les liens\n"
+"  -k, --keep          ne pas supprimer les fichiers d'entrée\n"
+"  -f, --force         forcer l'écrasement éventuel du fichier de sortie et\n"
+"                      (dé)compresser les liens symboliques\n"
 "  -c, --stdout        écrire sur la sortie standard et ne pas supprimer les\n"
 "                      fichiers d'entrée"
 
-#: src/xz/message.c:1127
+#: src/xz/message.c:1107
 msgid ""
 "      --single-stream decompress only the first stream, and silently\n"
 "                      ignore possible remaining input data"
 msgstr ""
 "      --single-stream décompresser uniquement le premier flux et ignorer\n"
-"                      silenciseusement les données éventuellement restantes"
+"                      silencieusement les données éventuellement restantes"
 
-#: src/xz/message.c:1130
+#: src/xz/message.c:1110
 msgid ""
 "      --no-sparse     do not create sparse files when decompressing\n"
 "  -S, --suffix=.SUF   use the suffix `.SUF' on compressed files\n"
@@ -559,10 +626,10 @@
 "  -S, --suffix=.SUF   utiliser le suffixe `.SUF' pour les fichiers compressés\n"
 "      --files[=FILE]  lire les fichiers sur lesquels opérer depuis FILE ; si\n"
 "                      FILE est omis, ceux-ci sont lus depuis l'entrée standard\n"
-"                      et doivent être suivis d'un caractère de retour à la ligne\n"
+"                      et doivent être suivis d'un caractère retour à la ligne\n"
 "      --files0[=FILE] comme --files mais avec un caractère null comme séparateur"
 
-#: src/xz/message.c:1139
+#: src/xz/message.c:1119
 msgid ""
 "\n"
 " Basic file format and compression options:\n"
@@ -570,47 +637,80 @@
 "\n"
 " Options basiques de format de fichier et de compression :\n"
 
-#: src/xz/message.c:1141
+#: src/xz/message.c:1121
 msgid ""
 "  -F, --format=FMT    file format to encode or decode; possible values are\n"
 "                      `auto' (default), `xz', `lzma', and `raw'\n"
 "  -C, --check=CHECK   integrity check type: `none' (use with caution),\n"
 "                      `crc32', `crc64' (default), or `sha256'"
 msgstr ""
-"  -F, --format=FMT    format de fichier à encoder ou décoder ; les possibilités\n"
-"                      sont : `auto' (par défaut), `xz', `lzma' et `raw'\n"
+"  -F, --format=FMT    format du fichier à encoder ou décoder ; sont acceptés :\n"
+"                      `auto' (par défaut), `xz', `lzma' et `raw'\n"
 "  -C, --check=CHECK   type de vérification d'intégrité : `none' (à utiliser avec\n"
 "                      précaution), `crc32', `crc64' (par défaut) ou `sha256'"
 
-#: src/xz/message.c:1148
+#: src/xz/message.c:1126
+msgid "      --ignore-check  don't verify the integrity check when decompressing"
+msgstr ""
+"      --ignore-check  ne pas vérifier l'intégrité des données lors de\n"
+"                      la décompression"
+
+#: src/xz/message.c:1130
 msgid ""
 "  -0 ... -9           compression preset; default is 6; take compressor *and*\n"
 "                      decompressor memory usage into account before using 7-9!"
 msgstr ""
-"  -0 ... -9           préréglage de compression ; 6 par défaut ; pensez à\n"
+"  -0 ... -9           préréglage de compression : 6 par défaut ; pensez à\n"
 "                      l'utilisation mémoire du compresseur *et* du décompresseur\n"
 "                      avant d'utiliser 7, 8 ou 9 !"
 
-#: src/xz/message.c:1152
+#: src/xz/message.c:1134
 msgid ""
 "  -e, --extreme       try to improve compression ratio by using more CPU time;\n"
 "                      does not affect decompressor memory requirements"
 msgstr ""
 "  -e, --extreme       essayer d'améliorer la compression en utilisant davantage\n"
-"                      de temps processeur sans affecter les besoins mémoire du\n"
-"                      décompresseur"
+"                      de temps processeur ;\n"
+"                      n'affecte pas les besoins mémoire du décompresseur"
 
-#: src/xz/message.c:1157
+#: src/xz/message.c:1138
+msgid ""
+"  -T, --threads=NUM   use at most NUM threads; the default is 1; set to 0\n"
+"                      to use as many threads as there are processor cores"
+msgstr ""
+"  -T, --threads=NB    créer au plus NB fils de compression (1 par défault) ; la\n"
+"                      valeur 0 est spéciale et équivaut au nombre de processeurs\n"
+"                      de la machine"
+
+#: src/xz/message.c:1143
 msgid ""
 "      --block-size=SIZE\n"
-"                      when compressing to the .xz format, start a new block\n"
-"                      after every SIZE bytes of input; 0=disabled (default)"
+"                      start a new .xz block after every SIZE bytes of input;\n"
+"                      use this to set the block size for threaded compression"
 msgstr ""
-"      --block-size=SIZE\n"
-"                      pour une compression au format .xz, entamer un nouveau\n"
-"                      bloc après SIZE octets d'entrée ; 0=désactivé (par défaut)"
+"      --block-size=TAILLE\n"
+"                      débuter un bloc XZ après chaque TAILLE octets de données\n"
+"                      d'entrée ; ce réglage sert pour la compression paralléle"
 
-#: src/xz/message.c:1161
+#: src/xz/message.c:1147
+msgid ""
+"      --block-list=SIZES\n"
+"                      start a new .xz block after the given comma-separated\n"
+"                      intervals of uncompressed data"
+msgstr ""
+"      --block-list=TAILLES\n"
+"                      débuter des blocs XZ après les TAILLES octets de données\n"
+"                      spécifiées avec des virgules pour séparateur"
+
+#: src/xz/message.c:1151
+msgid ""
+"      --flush-timeout=TIMEOUT\n"
+"                      when compressing, if more than TIMEOUT milliseconds has\n"
+"                      passed since the previous flush and reading more input\n"
+"                      would block, all pending data is flushed out"
+msgstr ""
+
+#: src/xz/message.c:1157
 #, no-c-format
 msgid ""
 "      --memlimit-compress=LIMIT\n"
@@ -623,10 +723,10 @@
 "      --memlimit-decompress=LIMIT\n"
 "  -M, --memlimit=LIMIT\n"
 "                      règle la limite d'utilisation mémoire pour la compression,\n"
-"                      décompression ou les deux ; LIMIT est en octets, % de\n"
-"                      RAM, ou 0 pour les valeurs par défaut"
+"                      décompression ou les deux ; LIMIT est en octets,\n"
+"                      pourcentage de RAM, ou 0 pour la valeur par défaut"
 
-#: src/xz/message.c:1168
+#: src/xz/message.c:1164
 msgid ""
 "      --no-adjust     if compression settings exceed the memory usage limit,\n"
 "                      give an error instead of adjusting the settings downwards"
@@ -635,15 +735,15 @@
 "                      d'utilisation mémoire, renvoyer une erreur plutôt que de\n"
 "                      diminuer les réglages"
 
-#: src/xz/message.c:1174
+#: src/xz/message.c:1170
 msgid ""
 "\n"
 " Custom filter chain for compression (alternative for using presets):"
 msgstr ""
 "\n"
-" Enchaînement de filtres de compression personnalisé (au lieu des préréglages) :"
+" Chaîne de filtres de compression personnalisée (en lieu des préréglages) :"
 
-#: src/xz/message.c:1183
+#: src/xz/message.c:1179
 msgid ""
 "\n"
 "  --lzma1[=OPTS]      LZMA1 or LZMA2; OPTS is a comma-separated list of zero or\n"
@@ -659,8 +759,8 @@
 "                        depth=NUM  maximum search depth; 0=automatic (default)"
 msgstr ""
 "\n"
-"  --lzma1[=OPTS]      LZMA1 ou LZMA2 ; OPTS est une liste de zéro ou plusieurs\n"
-"  --lzma2[=OPTS]      options parmi les suivantes (vals. valides ; par défaut) :\n"
+"  --lzma1[=OPTS]      LZMA1/2 ; OPTS est une liste d'options parmi les suivantes\n"
+"  --lzma2[=OPTS]      (entre parenthèses : valeurs valides et par défaut) :\n"
 "                        preset=PRE remettre les options à un préréglage (0-9[e])\n"
 "                        dict=NUM   taille dictionnaire (4KiB - 1536MiB ; 8MiB)\n"
 "                        lc=NUM     nombre de 'literal context bits' (0-4 ; 3)\n"
@@ -672,7 +772,7 @@
 "                        depth=NUM  profondeur de recherche maximale ;\n"
 "                                      0=automatique (par défaut)"
 
-#: src/xz/message.c:1198
+#: src/xz/message.c:1194
 msgid ""
 "\n"
 "  --x86[=OPTS]        x86 BCJ filter (32-bit and 64-bit)\n"
@@ -692,9 +792,9 @@
 "  --armthumb[=OPTS]   filtre BCJ ARM-Thumb ('little endian' uniquement)\n"
 "  --sparc[=OPTS]      filtre BCJ SPARC\n"
 "                      OPTS valides pour tous les filtres BCJ :\n"
-"                        start=NUM  start offset for conversions (default=0)"
+"                        start=NUM  position de début de la conversion (défaut=0)"
 
-#: src/xz/message.c:1210
+#: src/xz/message.c:1206
 msgid ""
 "\n"
 "  --delta[=OPTS]      Delta filter; valid OPTS (valid values; default):\n"
@@ -703,10 +803,10 @@
 msgstr ""
 "\n"
 "  --delta[=OPTS]      Filtre delta ; OPTS valides (vals. valides ; par défaut) :\n"
-"                        dist=NUM   distance entre les octets soustraits\n"
-"                                   les uns aux autres (1-256 ; 1)"
+"                        dist=NUM   distance entre les octets soustraits les\n"
+"                                   uns aux autres (1-256 ; 1)"
 
-#: src/xz/message.c:1218
+#: src/xz/message.c:1214
 msgid ""
 "\n"
 " Other options:\n"
@@ -714,54 +814,54 @@
 "\n"
 " Autres options :\n"
 
-#: src/xz/message.c:1221
+#: src/xz/message.c:1217
 msgid ""
 "  -q, --quiet         suppress warnings; specify twice to suppress errors too\n"
 "  -v, --verbose       be verbose; specify twice for even more verbose"
 msgstr ""
-"  -q, --quiet         supprimer les avertissemnts ; spécifier deux fois pour\n"
-"                      aussi supprimer les erreur\n"
+"  -q, --quiet         masquer les avertissements ; spécifier deux fois pour\n"
+"                      aussi masquer les erreurs\n"
 "  -v, --verbose       être bavard ; spécifier deux fois pour l'être davantage"
 
-#: src/xz/message.c:1226
+#: src/xz/message.c:1222
 msgid "  -Q, --no-warn       make warnings not affect the exit status"
 msgstr "  -Q, --no-warn       les avertissements ne modifient pas le code de sortie"
 
-#: src/xz/message.c:1228
+#: src/xz/message.c:1224
 msgid "      --robot         use machine-parsable messages (useful for scripts)"
 msgstr ""
 "      --robot         utiliser des messages lisibles par un programme\n"
 "                      (utile pour les scripts)"
 
-#: src/xz/message.c:1231
+#: src/xz/message.c:1227
 msgid ""
 "      --info-memory   display the total amount of RAM and the currently active\n"
 "                      memory usage limits, and exit"
 msgstr ""
-"      --info-memory   affiche la quantité totale de RAM et la limite actuelle\n"
-"                      en mémoire puis quitte"
+"      --info-memory   afficher la quantité totale de RAM ainsi que la limite\n"
+"                      actuelle d'utilisation mémoire puis quitter"
 
-#: src/xz/message.c:1234
+#: src/xz/message.c:1230
 msgid ""
 "  -h, --help          display the short help (lists only the basic options)\n"
 "  -H, --long-help     display this long help and exit"
 msgstr ""
-"  -h, --help          affiche l'aide courte (ne liste que les options de base)\n"
-"  -H, --long-help     affiche l'aide longue (ceci) puis quitte"
+"  -h, --help          afficher l'aide courte (ne liste que les options de base)\n"
+"  -H, --long-help     afficher l'aide longue (ceci) puis quitter"
 
-#: src/xz/message.c:1238
+#: src/xz/message.c:1234
 msgid ""
 "  -h, --help          display this short help and exit\n"
 "  -H, --long-help     display the long help (lists also the advanced options)"
 msgstr ""
-"  -h, --help          affiche l'aide courte (ceci) puis quitte\n"
-"  -H, --long-help     affiche l'aide longue (liste aussi les options avancées)"
+"  -h, --help          afficher l'aide courte (ceci) puis quitter\n"
+"  -H, --long-help     afficher l'aide longue (liste aussi les options avancées)"
 
-#: src/xz/message.c:1243
+#: src/xz/message.c:1239
 msgid "  -V, --version       display the version number and exit"
-msgstr "  -V, --version       affiche le numéro de version puis quitte"
+msgstr "  -V, --version       afficher le numéro de version puis quitter"
 
-#: src/xz/message.c:1245
+#: src/xz/message.c:1241
 msgid ""
 "\n"
 "With no FILE, or when FILE is -, read standard input.\n"
@@ -773,17 +873,21 @@
 #. for this package. Please add _another line_ saying
 #. "Report translation bugs to <...>\n" with the email or WWW
 #. address for translation bugs. Thanks.
-#: src/xz/message.c:1251
+#: src/xz/message.c:1247
 #, c-format
 msgid "Report bugs to <%s> (in English or Finnish).\n"
 msgstr ""
 "Signaler les bogues à <%s> (en anglais ou en finlandais).\n"
-"Signaler les bogues de traduction à <camaradetux@gmail.com>.\n"
+"Signaler les bogues de traduction à <adrien@notk.org>.\n"
 
-#: src/xz/message.c:1253
+#: src/xz/message.c:1249
 #, c-format
 msgid "%s home page: <%s>\n"
-msgstr "%s page du projet : <%s>\n"
+msgstr "Page du projet %s : <%s>\n"
+
+#: src/xz/message.c:1253
+msgid "THIS IS A DEVELOPMENT VERSION NOT INTENDED FOR PRODUCTION USE."
+msgstr ""
 
 #: src/xz/options.c:86
 #, c-format
@@ -803,7 +907,7 @@
 #: src/xz/options.c:247
 #, c-format
 msgid "Unsupported LZMA1/LZMA2 preset: %s"
-msgstr "Préréglage LZMA1/LZMA2 non pris en charge : %s"
+msgstr "Préréglage LZMA1/LZMA2 non reconnu : %s"
 
 #: src/xz/options.c:355
 msgid "The sum of lc and lp must not exceed 4"
@@ -834,34 +938,34 @@
 msgid "%s: Invalid filename suffix"
 msgstr "%s: Suffixe de nom de fichier invalide"
 
-#: src/xz/util.c:61
+#: src/xz/util.c:71
 #, c-format
 msgid "%s: Value is not a non-negative decimal integer"
 msgstr "%s : La valeur n'est pas un entier décimal non négatif"
 
-#: src/xz/util.c:103
+#: src/xz/util.c:113
 #, c-format
 msgid "%s: Invalid multiplier suffix"
 msgstr "%s : Suffixe multiplicateur invalide"
 
-#: src/xz/util.c:105
+#: src/xz/util.c:115
 msgid "Valid suffixes are `KiB' (2^10), `MiB' (2^20), and `GiB' (2^30)."
 msgstr "Les suffixes valides sont 'KiB' (2^10), 'MiB' (2^20) et 'GiB' (2^30)."
 
-#: src/xz/util.c:122
+#: src/xz/util.c:132
 #, c-format
 msgid "Value of the option `%s' must be in the range [%<PRIu64>, %<PRIu64>]"
 msgstr "La valeur de l'option '%s' doit être inclue entre %<PRIu64> et %<PRIu64>"
 
-#: src/xz/util.c:247
+#: src/xz/util.c:257
 msgid "Empty filename, skipping"
 msgstr "Nom de fichier vide, ignoré"
 
-#: src/xz/util.c:261
+#: src/xz/util.c:271
 msgid "Compressed data cannot be read from a terminal"
 msgstr "Les données compressées ne peuvent pas être lues depuis un terminal"
 
-#: src/xz/util.c:274
+#: src/xz/util.c:284
 msgid "Compressed data cannot be written to a terminal"
 msgstr "Les données compressées ne peuvent pas être écrites dans un terminal"
 
diff --git a/po/it.po b/po/it.po
index b9986f3..dc1cfbf 100644
--- a/po/it.po
+++ b/po/it.po
@@ -2,87 +2,107 @@
 # This file is in the public domain
 # Gruppo traduzione italiano di Ubuntu-it <gruppo-traduzione@ubuntu-it.org>, 2009, 2010
 # Lorenzo De Liso <blackz@ubuntu.com>, 2010.
-# Milo Casagrande <milo@ubuntu.com>, 2009, 2010, 2011.
+# Milo Casagrande <milo@ubuntu.com>, 2009, 2010, 2011, 2014.
 #
 msgid ""
 msgstr ""
 "Project-Id-Version: xz-utils\n"
-"Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2011-05-27 11:59+0200\n"
-"PO-Revision-Date: 2011-05-27 11:59+0200\n"
-"Last-Translator: Milo Casagrande <milo@ubuntu.com>\n"
+"Report-Msgid-Bugs-To: lasse.collin@tukaani.org\n"
+"POT-Creation-Date: 2014-09-14 21:56+0300\n"
+"PO-Revision-Date: 2014-10-20 13:16+0100\n"
+"Last-Translator: Milo Casagrande <milo@milo.name>\n"
 "Language-Team: Italian <tp@lists.linux.it>\n"
 "Language: it\n"
 "MIME-Version: 1.0\n"
 "Content-Type: text/plain; charset=UTF-8\n"
 "Content-Transfer-Encoding: 8bit\n"
 "X-Launchpad-Export-Date: 2010-08-16 19:16+0000\n"
-"X-Generator: Launchpad (build Unknown)\n"
-"Plural-Forms: nplurals=2; plural=(n != 1)\n"
+"X-Generator: Poedit 1.6.10\n"
+"Plural-Forms: nplurals=2; plural=(n != 1);\n"
 
-#: ../src/xz/args.c:338
+#: src/xz/args.c:63
+#, c-format
+msgid "%s: Invalid argument to --block-list"
+msgstr "%s: argomento non valido per --block-list"
+
+#: src/xz/args.c:73
+#, c-format
+msgid "%s: Too many arguments to --block-list"
+msgstr "%s: troppi argomenti per --block-list"
+
+#: src/xz/args.c:102
+msgid "0 can only be used as the last element in --block-list"
+msgstr "0 può essere usato solo come ultimo elemento in --block-list"
+
+#: src/xz/args.c:406
 #, c-format
 msgid "%s: Unknown file format type"
 msgstr "%s: tipo di formato del file sconosciuto"
 
-#: ../src/xz/args.c:361 ../src/xz/args.c:369
+#: src/xz/args.c:429 src/xz/args.c:437
 #, c-format
 msgid "%s: Unsupported integrity check type"
 msgstr "%s: tipo di controllo integrità non supportato"
 
-#: ../src/xz/args.c:396
+#: src/xz/args.c:473
 msgid "Only one file can be specified with `--files' or `--files0'."
 msgstr "Solo un file può essere specificato con \"--files\" o \"--files0\"."
 
-#: ../src/xz/args.c:459
+#: src/xz/args.c:541
 #, c-format
 msgid "The environment variable %s contains too many arguments"
 msgstr "La variabile d'ambiente %s contiene troppi argomenti"
 
-#: ../src/xz/coder.c:105
+#: src/xz/coder.c:110
 msgid "Maximum number of filters is four"
 msgstr "Il numero massimo di filtri è quattro"
 
-#: ../src/xz/coder.c:118
+#: src/xz/coder.c:129
 msgid "Memory usage limit is too low for the given filter setup."
 msgstr ""
 "Il limite dell'uso della memoria è troppo basso per l'impostazione del "
 "filtro dato."
 
-#. The message is shown only if warnings are allowed
-#. but the exit status isn't changed.
-#: ../src/xz/coder.c:148
+#: src/xz/coder.c:159
 msgid "Using a preset in raw mode is discouraged."
 msgstr "Non è consigliato usare un preset nella modalità raw."
 
-#: ../src/xz/coder.c:150
+#: src/xz/coder.c:161
 msgid "The exact options of the presets may vary between software versions."
 msgstr ""
 "Le opzioni esatte per i preset possono variare tra le versioni del software."
 
-#: ../src/xz/coder.c:176
+#: src/xz/coder.c:184
 msgid "The .lzma format supports only the LZMA1 filter"
 msgstr "Il formato .lzma supporta solo il filtro LZMA1"
 
-#: ../src/xz/coder.c:184
+#: src/xz/coder.c:192
 msgid "LZMA1 cannot be used with the .xz format"
 msgstr "LZMA1 non può essere usato con il formato .xz"
 
-#: ../src/xz/coder.c:203
+#: src/xz/coder.c:209
+msgid "The filter chain is incompatible with --flush-timeout"
+msgstr "La catena di filtri non è compatibile con --flush-timeout"
+
+#: src/xz/coder.c:215
+msgid "Switching to single-threaded mode due to --flush-timeout"
+msgstr "Passaggio a modalità singolo thread poiché viene usato --flush-timeout"
+
+#: src/xz/coder.c:234
 #, c-format
 msgid "Using up to %<PRIu32> threads."
 msgstr "Vengono usati circa %<PRIu32> thread."
 
-#: ../src/xz/coder.c:216
+#: src/xz/coder.c:247
 msgid "Unsupported filter chain or filter options"
 msgstr "Catena di filtri od opzioni del filtro non supportata"
 
-#: ../src/xz/coder.c:224
+#: src/xz/coder.c:255
 #, c-format
 msgid "Decompression will need %s MiB of memory."
 msgstr "L'estrazione necessita di %s MiB di memoria."
 
-#: ../src/xz/coder.c:259
+#: src/xz/coder.c:290
 #, c-format
 msgid ""
 "Adjusted the number of threads from %s to %s to not exceed the memory usage "
@@ -91,8 +111,7 @@
 "Regolato il numero di thread da %s a %s per non eccedere il limite di "
 "utilizzo della memoria di %s MiB"
 
-#. Tell the user that we decreased the dictionary size.
-#: ../src/xz/coder.c:313
+#: src/xz/coder.c:344
 #, c-format
 msgid ""
 "Adjusted LZMA%c dictionary size from %s MiB to %s MiB to not exceed the "
@@ -101,6 +120,16 @@
 "Regolata la dimensione del dizionario LZMA%c da %s MiB a %s MiB per non "
 "superare il limite dell'uso della memoria di %s MiB"
 
+#: src/xz/file_io.c:90
+#, c-format
+msgid "Error creating a pipe: %s"
+msgstr "Errore nel creare una pipe: %s"
+
+#: src/xz/file_io.c:166
+#, c-format
+msgid "%s: poll() failed: %s"
+msgstr "%s: poll() non riuscita: %s"
+
 #. TRANSLATORS: When compression or decompression finishes,
 #. and xz is going to remove the source file, xz first checks
 #. if the source file still exists, and if it does, does its
@@ -111,128 +140,146 @@
 #. it is possible that the user has put a new file in place
 #. of the original file, and in that case it obviously
 #. shouldn't be removed.
-#: ../src/xz/file_io.c:136
+#: src/xz/file_io.c:236
 #, c-format
 msgid "%s: File seems to have been moved, not removing"
 msgstr "%s: sembra che il file sia stato spostato, non viene rimosso"
 
-#: ../src/xz/file_io.c:143 ../src/xz/file_io.c:635
+#: src/xz/file_io.c:243 src/xz/file_io.c:761
 #, c-format
 msgid "%s: Cannot remove: %s"
 msgstr "%s: impossibile rimuovere: %s"
 
-#: ../src/xz/file_io.c:168
+#: src/xz/file_io.c:268
 #, c-format
 msgid "%s: Cannot set the file owner: %s"
 msgstr "%s: impossibile impostare il proprietario del file: %s"
 
-#: ../src/xz/file_io.c:174
+#: src/xz/file_io.c:274
 #, c-format
 msgid "%s: Cannot set the file group: %s"
 msgstr "%s: impossibile impostare il gruppo del file: %s"
 
-#: ../src/xz/file_io.c:193
+#: src/xz/file_io.c:293
 #, c-format
 msgid "%s: Cannot set the file permissions: %s"
 msgstr "%s: impossibile impostare i permessi del file: %s"
 
-#: ../src/xz/file_io.c:340 ../src/xz/file_io.c:423
+#: src/xz/file_io.c:399
+#, c-format
+msgid "Error getting the file status flags from standard input: %s"
+msgstr ""
+"Errore nel recuperare le flag di stato del file dallo standard input: %s"
+
+#: src/xz/file_io.c:408
+#, c-format
+msgid "Error setting O_NONBLOCK on standard input: %s"
+msgstr "Errore nell'impostare O_NONBLOCK sullo standard input: %s"
+
+#: src/xz/file_io.c:460 src/xz/file_io.c:522
 #, c-format
 msgid "%s: Is a symbolic link, skipping"
 msgstr "%s: è un collegamento simbolico, viene saltato"
 
-#: ../src/xz/file_io.c:468
+#: src/xz/file_io.c:551
 #, c-format
 msgid "%s: Is a directory, skipping"
 msgstr "%s: è una directory, viene saltata"
 
-#: ../src/xz/file_io.c:474
+#: src/xz/file_io.c:557
 #, c-format
 msgid "%s: Not a regular file, skipping"
 msgstr "%s: non è un file regolare, viene saltato"
 
-#. gzip rejects setuid and setgid files even
-#. when --force was used. bzip2 doesn't check
-#. for them, but calls fchown() after fchmod(),
-#. and many systems automatically drop setuid
-#. and setgid bits there.
-#.
-#. We accept setuid and setgid files if
-#. --force was used. We drop these bits
-#. explicitly in io_copy_attr().
-#: ../src/xz/file_io.c:491
+#: src/xz/file_io.c:574
 #, c-format
 msgid "%s: File has setuid or setgid bit set, skipping"
 msgstr "%s: il file ha il bit setuid o setgid impostato, viene saltato"
 
-#: ../src/xz/file_io.c:498
+#: src/xz/file_io.c:581
 #, c-format
 msgid "%s: File has sticky bit set, skipping"
 msgstr "%s: il file ha lo sticky bit impostato, viene saltato"
 
-#: ../src/xz/file_io.c:505
+#: src/xz/file_io.c:588
 #, c-format
 msgid "%s: Input file has more than one hard link, skipping"
 msgstr "%s: il file di input ha più di un collegamento fisico, viene saltato"
 
-#: ../src/xz/file_io.c:761
+#: src/xz/file_io.c:668
+#, c-format
+msgid "Error restoring the status flags to standard input: %s"
+msgstr "Errore nel ripristinare le flag di stato sullo standard input: %s"
+
+#: src/xz/file_io.c:714
+#, c-format
+msgid "Error getting the file status flags from standard output: %s"
+msgstr ""
+"Errore nel recuperare le flag di stato del file dallo standard output: %s"
+
+#: src/xz/file_io.c:723
+#, c-format
+msgid "Error setting O_NONBLOCK on standard output: %s"
+msgstr "Errore nell'impostare O_NONBLOCK sullo standard output: %s"
+
+#: src/xz/file_io.c:896
 #, c-format
 msgid "Error restoring the O_APPEND flag to standard output: %s"
 msgstr "Errore nel ripristinare la flag O_APPEND sullo standard output: %s"
 
-#: ../src/xz/file_io.c:773
+#: src/xz/file_io.c:908
 #, c-format
 msgid "%s: Closing the file failed: %s"
 msgstr "%s: chiusura del file non riuscita: %s"
 
-#: ../src/xz/file_io.c:809 ../src/xz/file_io.c:1008
+#: src/xz/file_io.c:944 src/xz/file_io.c:1170
 #, c-format
 msgid "%s: Seeking failed when trying to create a sparse file: %s"
 msgstr ""
 "%s: posizionamento non riuscito nel tentativo di creare un file sparso: %s"
 
-#: ../src/xz/file_io.c:883
+#: src/xz/file_io.c:1039
 #, c-format
 msgid "%s: Read error: %s"
 msgstr "%s: errore di lettura: %s"
 
-#: ../src/xz/file_io.c:906
+#: src/xz/file_io.c:1059
 #, c-format
 msgid "%s: Error seeking the file: %s"
 msgstr "%s: errore nel cercare il file: %s"
 
-#: ../src/xz/file_io.c:916
+#: src/xz/file_io.c:1069
 #, c-format
 msgid "%s: Unexpected end of file"
 msgstr "%s: fine del file inaspettata"
 
-#: ../src/xz/file_io.c:966
+#: src/xz/file_io.c:1128
 #, c-format
 msgid "%s: Write error: %s"
 msgstr "%s: errore di scrittura: %s"
 
-#: ../src/xz/hardware.c:101
+#: src/xz/hardware.c:107
 msgid "Disabled"
 msgstr "Disabilitato"
 
 #. TRANSLATORS: Test with "xz --info-memory" to see if
 #. the alignment looks nice.
-#: ../src/xz/hardware.c:120
+#: src/xz/hardware.c:126
 msgid "Total amount of physical memory (RAM): "
 msgstr "Quantità totale di memoria fisica (RAM):     "
 
-#: ../src/xz/hardware.c:122
+#: src/xz/hardware.c:128
 msgid "Memory usage limit for compression:    "
 msgstr "Limite utilizzo memoria per la compressione: "
 
-#: ../src/xz/hardware.c:124
+#: src/xz/hardware.c:130
 msgid "Memory usage limit for decompression:  "
 msgstr "Limite utilizzo memoria per l'estrazione:    "
 
 #. TRANSLATORS: Indicates that there is no integrity check.
 #. This string is used in tables, so the width must not
 #. exceed ten columns with a fixed-width font.
-#: ../src/xz/list.c:62
+#: src/xz/list.c:65
 msgid "None"
 msgstr "Nessuno"
 
@@ -241,60 +288,60 @@
 #. strings are used in tables, so the width must not exceed ten
 #. columns with a fixed-width font. It's OK to omit the dash if
 #. you need space for one extra letter, but don't use spaces.
-#: ../src/xz/list.c:69
+#: src/xz/list.c:72
 msgid "Unknown-2"
 msgstr "Sconosc2"
 
-#: ../src/xz/list.c:70
+#: src/xz/list.c:73
 msgid "Unknown-3"
 msgstr "Sconosc3"
 
-#: ../src/xz/list.c:72
+#: src/xz/list.c:75
 msgid "Unknown-5"
 msgstr "Sconosc5"
 
-#: ../src/xz/list.c:73
+#: src/xz/list.c:76
 msgid "Unknown-6"
 msgstr "Sconosc6"
 
-#: ../src/xz/list.c:74
+#: src/xz/list.c:77
 msgid "Unknown-7"
 msgstr "Sconosc7"
 
-#: ../src/xz/list.c:75
+#: src/xz/list.c:78
 msgid "Unknown-8"
 msgstr "Sconosc8"
 
-#: ../src/xz/list.c:76
+#: src/xz/list.c:79
 msgid "Unknown-9"
 msgstr "Sconosc9"
 
-#: ../src/xz/list.c:78
+#: src/xz/list.c:81
 msgid "Unknown-11"
 msgstr "Sconosc11"
 
-#: ../src/xz/list.c:79
+#: src/xz/list.c:82
 msgid "Unknown-12"
 msgstr "Sconosc12"
 
-#: ../src/xz/list.c:80
+#: src/xz/list.c:83
 msgid "Unknown-13"
 msgstr "Sconosc13"
 
-#: ../src/xz/list.c:81
+#: src/xz/list.c:84
 msgid "Unknown-14"
 msgstr "Sconosc14"
 
-#: ../src/xz/list.c:82
+#: src/xz/list.c:85
 msgid "Unknown-15"
 msgstr "Sconosc15"
 
-#: ../src/xz/list.c:126
+#: src/xz/list.c:153
 #, c-format
 msgid "%s: File is empty"
 msgstr "%s: il file è vuoto"
 
-#: ../src/xz/list.c:131
+#: src/xz/list.c:158
 #, c-format
 msgid "%s: Too small to be a valid .xz file"
 msgstr "%s: troppo piccolo per essere un file .xz valido"
@@ -303,51 +350,49 @@
 #. to Ratio, the columns are right aligned. Check and Filename
 #. are left aligned. If you need longer words, it's OK to
 #. use two lines here. Test with "xz -l foo.xz".
-#: ../src/xz/list.c:612
+#: src/xz/list.c:671
 msgid "Strms  Blocks   Compressed Uncompressed  Ratio  Check   Filename"
 msgstr " Strm  Blocc.    Compresso     Estratto  Rapp.  Contr   Nome file"
 
-#: ../src/xz/list.c:652
+#: src/xz/list.c:711
 #, c-format
 msgid "  Streams:            %s\n"
 msgstr "  Stream:               %s\n"
 
-#: ../src/xz/list.c:654
+#: src/xz/list.c:713
 #, c-format
 msgid "  Blocks:             %s\n"
 msgstr "  Blocchi:              %s\n"
 
-#: ../src/xz/list.c:656
+#: src/xz/list.c:715
 #, c-format
 msgid "  Compressed size:    %s\n"
 msgstr "  Dim. compresso:       %s\n"
 
-#: ../src/xz/list.c:659
+#: src/xz/list.c:718
 #, c-format
 msgid "  Uncompressed size:  %s\n"
 msgstr "  Dim. estratto:        %s\n"
 
-#: ../src/xz/list.c:662
+#: src/xz/list.c:721
 #, c-format
 msgid "  Ratio:              %s\n"
 msgstr "  Rapporto:             %s\n"
 
-#: ../src/xz/list.c:664
+#: src/xz/list.c:723
 #, c-format
 msgid "  Check:              %s\n"
 msgstr "  Controllo:            %s\n"
 
-#: ../src/xz/list.c:665
+#: src/xz/list.c:724
 #, c-format
 msgid "  Stream padding:     %s\n"
 msgstr "  Padding dello stream: %s\n"
 
-#. Print information about the Streams.
-#.
 #. TRANSLATORS: The second line is column headings. All except
 #. Check are right aligned; Check is left aligned. Test with
 #. "xz -lv foo.xz".
-#: ../src/xz/list.c:693
+#: src/xz/list.c:752
 msgid ""
 "  Streams:\n"
 "    Stream    Blocks      CompOffset    UncompOffset        CompSize      "
@@ -359,7 +404,7 @@
 
 #. TRANSLATORS: The second line is column headings. All
 #. except Check are right aligned; Check is left aligned.
-#: ../src/xz/list.c:748
+#: src/xz/list.c:807
 #, c-format
 msgid ""
 "  Blocks:\n"
@@ -377,74 +422,71 @@
 #. are right aligned. %*s is replaced with 0-120
 #. spaces to make the CheckVal column wide enough.
 #. Test with "xz -lvv foo.xz".
-#: ../src/xz/list.c:760
+#: src/xz/list.c:819
 #, c-format
 msgid "      CheckVal %*s Header  Flags        CompSize    MemUsage  Filters"
 msgstr "      Val.cont %*s Header  Flag       Dim.compr.    Uso mem.  Filtri"
 
-#: ../src/xz/list.c:838 ../src/xz/list.c:1007
+#: src/xz/list.c:897 src/xz/list.c:1072
 #, c-format
 msgid "  Memory needed:      %s MiB\n"
 msgstr "  Memoria necessaria:   %s MiB\n"
 
-#: ../src/xz/list.c:840 ../src/xz/list.c:1009
+#: src/xz/list.c:899 src/xz/list.c:1074
 #, c-format
 msgid "  Sizes in headers:   %s\n"
 msgstr "  Dim. negli header:    %s\n"
 
-#: ../src/xz/list.c:841 ../src/xz/list.c:1010
+#: src/xz/list.c:900 src/xz/list.c:1075
 msgid "Yes"
 msgstr "Sì"
 
-#: ../src/xz/list.c:841 ../src/xz/list.c:1010
+#: src/xz/list.c:900 src/xz/list.c:1075
 msgid "No"
 msgstr "No"
 
-#. Since we print totals only when there are at least two files,
-#. the English message will always use "%s files". But some other
-#. languages need different forms for different plurals so we
-#. have to translate this with ngettext().
-#.
+#: src/xz/list.c:901 src/xz/list.c:1076
+#, c-format
+msgid "  Minimum XZ Utils version: %s\n"
+msgstr "  Versione \"XZ Utils\" minima: %s\n"
+
 #. TRANSLATORS: %s is an integer. Only the plural form of this
 #. message is used (e.g. "2 files"). Test with "xz -l foo.xz bar.xz".
-#: ../src/xz/list.c:986
+#: src/xz/list.c:1051
 #, c-format
 msgid "%s file\n"
 msgid_plural "%s files\n"
 msgstr[0] "%s file\n"
 msgstr[1] "%s file\n"
 
-#: ../src/xz/list.c:999
+#: src/xz/list.c:1064
 msgid "Totals:"
 msgstr "Totali:"
 
-#: ../src/xz/list.c:1000
+#: src/xz/list.c:1065
 #, c-format
 msgid "  Number of files:    %s\n"
 msgstr "  Numero di file:       %s\n"
 
-#: ../src/xz/list.c:1072
+#: src/xz/list.c:1140
 msgid "--list works only on .xz files (--format=xz or --format=auto)"
 msgstr "--list funziona solamente con file .xz (--format=xz o --format=auto)"
 
-#: ../src/xz/list.c:1078
+#: src/xz/list.c:1146
 msgid "--list does not support reading from standard input"
 msgstr "--list non è in grado di leggere dallo standard input"
 
-#: ../src/xz/main.c:89
+#: src/xz/main.c:89
 #, c-format
 msgid "%s: Error reading filenames: %s"
 msgstr "%s: errore nel leggere i nomi dei file: %s"
 
-#: ../src/xz/main.c:96
+#: src/xz/main.c:96
 #, c-format
 msgid "%s: Unexpected end of input when reading filenames"
 msgstr "%s: fine dell'input durante la lettura dei nomi dei file non attesa"
 
-#. A null character was found when using --files,
-#. which expects plain text input separated with
-#. newlines.
-#: ../src/xz/main.c:120
+#: src/xz/main.c:120
 #, c-format
 msgid ""
 "%s: Null character found when reading filenames; maybe you meant to use `--"
@@ -453,11 +495,11 @@
 "%s: nessun carattere trovato durante la lettura dei nomi dei file; forse si "
 "intendeva usare \"--files0\" invece di \"--files\"?"
 
-#: ../src/xz/main.c:174
+#: src/xz/main.c:174
 msgid "Compression and decompression with --robot are not supported yet."
 msgstr "La compressione e l'estrazione con --robot non sono ancora supportate."
 
-#: ../src/xz/main.c:231
+#: src/xz/main.c:231
 msgid ""
 "Cannot read data from standard input when reading filenames from standard "
 "input"
@@ -469,68 +511,71 @@
 #. of the line in messages. Usually it becomes "xz: ".
 #. This is a translatable string because French needs
 #. a space before a colon.
-#: ../src/xz/message.c:733
+#: src/xz/message.c:713
 #, c-format
 msgid "%s: "
 msgstr "%s: "
 
-#: ../src/xz/message.c:796 ../src/xz/message.c:846
+#: src/xz/message.c:776 src/xz/message.c:826
 msgid "Internal error (bug)"
 msgstr "Errore interno (bug)"
 
-#: ../src/xz/message.c:803
+#: src/xz/message.c:783
 msgid "Cannot establish signal handlers"
 msgstr "Impossibile stabilire i gestori dei segnali"
 
-#: ../src/xz/message.c:812
+#: src/xz/message.c:792
 msgid "No integrity check; not verifying file integrity"
 msgstr ""
 "Nessun controllo d'integrità; l'integrità del file non viene verificata"
 
-#: ../src/xz/message.c:815
+#: src/xz/message.c:795
 msgid "Unsupported type of integrity check; not verifying file integrity"
 msgstr ""
 "Tipo di controllo di integrità non supportato; l'integrità del file non "
 "viene verificata"
 
-#: ../src/xz/message.c:822
+#: src/xz/message.c:802
 msgid "Memory usage limit reached"
 msgstr "Limite di utilizzo della memoria raggiunto"
 
-#: ../src/xz/message.c:825
+#: src/xz/message.c:805
 msgid "File format not recognized"
 msgstr "Formato di file non riconosciuto"
 
-#: ../src/xz/message.c:828
+#: src/xz/message.c:808
 msgid "Unsupported options"
 msgstr "Opzioni non supportate"
 
-#: ../src/xz/message.c:831
+#: src/xz/message.c:811
 msgid "Compressed data is corrupt"
 msgstr "I dati compressi sono danneggiati"
 
-#: ../src/xz/message.c:834
+#: src/xz/message.c:814
 msgid "Unexpected end of input"
 msgstr "Fine dell'input non attesa"
 
-#: ../src/xz/message.c:885
+#: src/xz/message.c:847
+#, c-format
+msgid "%s MiB of memory is required. The limiter is disabled."
+msgstr "%s MiB di memoria sono richiesti. Il limite è disabilitato."
+
+#: src/xz/message.c:875
 #, c-format
 msgid "%s MiB of memory is required. The limit is %s."
 msgstr "%s MiB di memoria sono richiesti. Il limite è %s."
 
-#: ../src/xz/message.c:1052
+#: src/xz/message.c:1042
 #, c-format
 msgid "%s: Filter chain: %s\n"
 msgstr "%s: catena di filtri: %s\n"
 
-#. Print this with V_WARNING instead of V_ERROR to prevent it from
-#. showing up when --quiet has been specified.
-#: ../src/xz/message.c:1062
+#: src/xz/message.c:1052
 #, c-format
 msgid "Try `%s --help' for more information."
 msgstr "Provare \"%s --help\" per maggiori informazioni."
 
-#: ../src/xz/message.c:1088
+#: src/xz/message.c:1078
 #, c-format
 msgid ""
 "Usage: %s [OPTION]... [FILE]...\n"
@@ -541,18 +586,18 @@
 "Comprime o estrae i FILE nel formato .xz.\n"
 "\n"
 
-#: ../src/xz/message.c:1095
+#: src/xz/message.c:1085
 msgid ""
 "Mandatory arguments to long options are mandatory for short options too.\n"
 msgstr ""
 "Gli argomenti obbligatori per le opzioni lunghe lo sono anche per quelle "
 "brevi.\n"
 
-#: ../src/xz/message.c:1099
+#: src/xz/message.c:1089
 msgid " Operation mode:\n"
 msgstr " Modalità di operazione:\n"
 
-#: ../src/xz/message.c:1102
+#: src/xz/message.c:1092
 msgid ""
 "  -z, --compress      force compression\n"
 "  -d, --decompress    force decompression\n"
@@ -564,7 +609,7 @@
 "  -t, --test          Verifica l'integrità dei file compressi\n"
 "  -l, --list          Elenca informazioni sui file .xz"
 
-#: ../src/xz/message.c:1108
+#: src/xz/message.c:1098
 msgid ""
 "\n"
 " Operation modifiers:\n"
@@ -572,7 +617,7 @@
 "\n"
 " Modificatori di operazioni:\n"
 
-#: ../src/xz/message.c:1111
+#: src/xz/message.c:1101
 msgid ""
 "  -k, --keep          keep (don't delete) input files\n"
 "  -f, --force         force overwrite of output file and (de)compress links\n"
@@ -585,7 +630,7 @@
 "  -c, --stdout        Scrive sullo standard output e non elimina i file di "
 "input"
 
-#: ../src/xz/message.c:1117
+#: src/xz/message.c:1107
 msgid ""
 "      --single-stream decompress only the first stream, and silently\n"
 "                      ignore possible remaining input data"
@@ -593,7 +638,7 @@
 "      --single-stream Decomprime solamente il primo stream e ignora\n"
 "                      silenziosamente i restanti dati di input"
 
-#: ../src/xz/message.c:1120
+#: src/xz/message.c:1110
 msgid ""
 "      --no-sparse     do not create sparse files when decompressing\n"
 "  -S, --suffix=.SUF   use the suffix `.SUF' on compressed files\n"
@@ -613,7 +658,7 @@
 "                      di newline\n"
 "      --files0=[FILE] Come --files ma usa il carattere null come terminatore"
 
-#: ../src/xz/message.c:1129
+#: src/xz/message.c:1119
 msgid ""
 "\n"
 " Basic file format and compression options:\n"
@@ -621,7 +666,7 @@
 "\n"
 " Formato file di base e opzioni di compressione:\n"
 
-#: ../src/xz/message.c:1131
+#: src/xz/message.c:1121
 msgid ""
 "  -F, --format=FMT    file format to encode or decode; possible values are\n"
 "                      `auto' (default), `xz', `lzma', and `raw'\n"
@@ -636,7 +681,13 @@
 "attenzione),\n"
 "                      \"crc32\", \"crc64\" (predefinito) o \"sha256\""
 
-#: ../src/xz/message.c:1138
+#: src/xz/message.c:1126
+msgid ""
+"      --ignore-check  don't verify the integrity check when decompressing"
+msgstr ""
+"      --ignore-check  Non verifica il codice di integrità quando decomprime"
+
+#: src/xz/message.c:1130
 msgid ""
 "  -0 ... -9           compression preset; default is 6; take compressor "
 "*and*\n"
@@ -649,7 +700,7 @@
 "prima\n"
 "                      di usare 7-9"
 
-#: ../src/xz/message.c:1142
+#: src/xz/message.c:1134
 msgid ""
 "  -e, --extreme       try to improve compression ratio by using more CPU "
 "time;\n"
@@ -660,17 +711,59 @@
 "di\n"
 "                      memoria in fase di estrazione"
 
-#: ../src/xz/message.c:1147
+#: src/xz/message.c:1138
+msgid ""
+"  -T, --threads=NUM   use at most NUM threads; the default is 1; set to 0\n"
+"                      to use as many threads as there are processor cores"
+msgstr ""
+"  -T, --threads=NUM   Usa al massimo NUM thread: il valore predefinito è 1,\n"
+"                      impostare a 0 per usare tanti thread quanti core la "
+"CPU\n"
+"                      ha a disposizione"
+
+#: src/xz/message.c:1143
 msgid ""
 "      --block-size=SIZE\n"
-"                      when compressing to the .xz format, start a new block\n"
-"                      after every SIZE bytes of input; 0=disabled (default)"
+"                      start a new .xz block after every SIZE bytes of "
+"input;\n"
+"                      use this to set the block size for threaded compression"
 msgstr ""
-"      --block-size=DIM \n"
-"                      Comprimendo nel formato .zx, comincia un nuovo blocco\n"
-"                      dopo DIM byte di input; 0=disabilitato (predefinito)"
+"      --block-size=DIM\n"
+"                      Avvia un nuovo blocco .xz dopo ogni DIM byte di "
+"input:\n"
+"                      usare per impostare la dimensione del blocco durante "
+"la\n"
+"                      compressione con thread"
 
-#: ../src/xz/message.c:1151
+#: src/xz/message.c:1147
+msgid ""
+"      --block-list=SIZES\n"
+"                      start a new .xz block after the given comma-separated\n"
+"                      intervals of uncompressed data"
+msgstr ""
+"      --block-list=DIM\n"
+"                      Avvia un nuovo blocco .xz dopo gli intervalli, "
+"sperati\n"
+"                      da virgole, di dati non compressi"
+
+#: src/xz/message.c:1151
+msgid ""
+"      --flush-timeout=TIMEOUT\n"
+"                      when compressing, if more than TIMEOUT milliseconds "
+"has\n"
+"                      passed since the previous flush and reading more "
+"input\n"
+"                      would block, all pending data is flushed out"
+msgstr ""
+"      --flush-timeout=TIMEOUT\n"
+"                      Durante la compressione, se sono passati più di "
+"TIMEOUT\n"
+"                      millisecondi dal flush precedente e la lettura di\n"
+"                      ulteriore input risulterebbe bloccata, viene eseguito "
+"il\n"
+"                      flush di tutti i dati pendenti"
+
+#: src/xz/message.c:1157
 #, no-c-format
 msgid ""
 "      --memlimit-compress=LIMIT\n"
@@ -688,7 +781,7 @@
 "byte,\n"
 "                      % della memoria RAM oppure 0 per il valore predefinito"
 
-#: ../src/xz/message.c:1158
+#: src/xz/message.c:1164
 msgid ""
 "      --no-adjust     if compression settings exceed the memory usage "
 "limit,\n"
@@ -700,7 +793,7 @@
 "                      utilizzo della memoria, lancia un errore invece di\n"
 "                      utilizzare valori più piccoli"
 
-#: ../src/xz/message.c:1164
+#: src/xz/message.c:1170
 msgid ""
 "\n"
 " Custom filter chain for compression (alternative for using presets):"
@@ -709,7 +802,7 @@
 " Catena di filtri personalizzati per la compressione (alternative per\n"
 " l'utilizzo di preset):"
 
-#: ../src/xz/message.c:1173
+#: src/xz/message.c:1179
 msgid ""
 "\n"
 "  --lzma1[=OPTS]      LZMA1 or LZMA2; OPTS is a comma-separated list of zero "
@@ -733,8 +826,8 @@
 "zero\n"
 "  --lzma2[=OPZ]      o più delle seguenti opzioni (valori validi; "
 "predefinito):\n"
-"                        preset=NUM Reimposta le opzioni al preset NUM (0-9"
-"[e])\n"
+"                        preset=NUM Reimposta le opzioni al preset NUM "
+"(0-9[e])\n"
 "                        dict=NUM   Dimensione del dizionario\n"
 "                                   (4KiB - 1536MiB; 8MiB)\n"
 "                        lc=NUM     Numero di bit letterali di contesto (0-4; "
@@ -752,7 +845,7 @@
 "0=automatica\n"
 "                                   (predefinito)"
 
-#: ../src/xz/message.c:1188
+#: src/xz/message.c:1194
 msgid ""
 "\n"
 "  --x86[=OPTS]        x86 BCJ filter (32-bit and 64-bit)\n"
@@ -775,7 +868,7 @@
 "                      start=NUM Offset iniziale per le conversioni\n"
 "                                (predefinito=0)"
 
-#: ../src/xz/message.c:1200
+#: src/xz/message.c:1206
 msgid ""
 "\n"
 "  --delta[=OPTS]      Delta filter; valid OPTS (valid values; default):\n"
@@ -787,7 +880,7 @@
 "                      dist=NUM   Distanza tra byte sottratti\n"
 "                                 gli uni dagli altri (1-256; 1)"
 
-#: ../src/xz/message.c:1208
+#: src/xz/message.c:1214
 msgid ""
 "\n"
 " Other options:\n"
@@ -795,7 +888,7 @@
 "\n"
 " Altre opzioni:\n"
 
-#: ../src/xz/message.c:1211
+#: src/xz/message.c:1217
 msgid ""
 "  -q, --quiet         suppress warnings; specify twice to suppress errors "
 "too\n"
@@ -808,16 +901,16 @@
 "ancora\n"
 "                      più prolisso"
 
-#: ../src/xz/message.c:1216
+#: src/xz/message.c:1222
 msgid "  -Q, --no-warn       make warnings not affect the exit status"
 msgstr "  -Q, --no-warn       Gli avvisi non influenzano lo stato d'uscita"
 
-#: ../src/xz/message.c:1218
+#: src/xz/message.c:1224
 msgid ""
 "      --robot         use machine-parsable messages (useful for scripts)"
 msgstr "      --robot         Usa messaggi analizzabili (utile per gli script)"
 
-#: ../src/xz/message.c:1221
+#: src/xz/message.c:1227
 msgid ""
 "      --info-memory   display the total amount of RAM and the currently "
 "active\n"
@@ -827,7 +920,7 @@
 "attuale\n"
 "                      attivo di utilizzo della memore ed esce"
 
-#: ../src/xz/message.c:1224
+#: src/xz/message.c:1230
 msgid ""
 "  -h, --help          display the short help (lists only the basic options)\n"
 "  -H, --long-help     display this long help and exit"
@@ -835,7 +928,7 @@
 "  -h, --help          Stampa l'aiuto breve (elenca solo le opzioni di base)\n"
 "  -H, --long-help     Stampa questo lungo aiuto ed esce"
 
-#: ../src/xz/message.c:1228
+#: src/xz/message.c:1234
 msgid ""
 "  -h, --help          display this short help and exit\n"
 "  -H, --long-help     display the long help (lists also the advanced options)"
@@ -843,11 +936,11 @@
 "  -h, --help          Stampa questo breve aiuto ed esce\n"
 "  -H, --long-help     Stampa l'aiuto lungo (elenca anche le opzioni avanzate)"
 
-#: ../src/xz/message.c:1233
+#: src/xz/message.c:1239
 msgid "  -V, --version       display the version number and exit"
 msgstr "  -V, --version       Stampa il numero della versione ed esce"
 
-#: ../src/xz/message.c:1235
+#: src/xz/message.c:1241
 msgid ""
 "\n"
 "With no FILE, or when FILE is -, read standard input.\n"
@@ -859,51 +952,56 @@
 #. for this package. Please add _another line_ saying
 #. "Report translation bugs to <...>\n" with the email or WWW
 #. address for translation bugs. Thanks.
-#: ../src/xz/message.c:1241
+#: src/xz/message.c:1247
 #, c-format
 msgid "Report bugs to <%s> (in English or Finnish).\n"
 msgstr ""
 "Segnalare i bug a <%s> (in inglese o finlandese).\n"
 "Segnalare i bug di traduzione a <tp@lists.linux.it>.\n"
 
-#: ../src/xz/message.c:1243
+#: src/xz/message.c:1249
 #, c-format
 msgid "%s home page: <%s>\n"
 msgstr "Sito web di %s: <%s>\n"
 
-#: ../src/xz/options.c:86
+#: src/xz/message.c:1253
+msgid "THIS IS A DEVELOPMENT VERSION NOT INTENDED FOR PRODUCTION USE."
+msgstr ""
+"Questa è una versione di sviluppo non adatta per utilizzi in produzione."
+
+#: src/xz/options.c:86
 #, c-format
 msgid "%s: Options must be `name=value' pairs separated with commas"
 msgstr ""
 "%s: le opzioni devono essere coppie \"nome=valore\" separate da virgole"
 
-#: ../src/xz/options.c:93
+#: src/xz/options.c:93
 #, c-format
 msgid "%s: Invalid option name"
 msgstr "%s: nome opzione non valido"
 
-#: ../src/xz/options.c:113
+#: src/xz/options.c:113
 #, c-format
 msgid "%s: Invalid option value"
 msgstr "%s: valore dell'opzione non valido"
 
-#: ../src/xz/options.c:247
+#: src/xz/options.c:247
 #, c-format
 msgid "Unsupported LZMA1/LZMA2 preset: %s"
 msgstr "Preset LZMA/LZMA2 non supportato: %s"
 
-#: ../src/xz/options.c:355
+#: src/xz/options.c:355
 msgid "The sum of lc and lp must not exceed 4"
 msgstr "La somma di lc e lp non deve superare 4"
 
-#: ../src/xz/options.c:359
+#: src/xz/options.c:359
 #, c-format
 msgid "The selected match finder requires at least nice=%<PRIu32>"
 msgstr ""
 "Lo strumento per cercare corrispondenze selezionato richiede almeno nice="
 "%<PRIu32>"
 
-#: ../src/xz/suffix.c:133 ../src/xz/suffix.c:258
+#: src/xz/suffix.c:133 src/xz/suffix.c:258
 #, c-format
 msgid ""
 "%s: With --format=raw, --suffix=.SUF is required unless writing to stdout"
@@ -911,59 +1009,59 @@
 "%s: con --format=raw, --suffix=.SUF è richiesto a meno che non si scriva "
 "sullo stdout"
 
-#: ../src/xz/suffix.c:164
+#: src/xz/suffix.c:164
 #, c-format
 msgid "%s: Filename has an unknown suffix, skipping"
 msgstr "%s: il nome del file ha un suffisso sconosciuto, viene saltato"
 
-#: ../src/xz/suffix.c:185
+#: src/xz/suffix.c:185
 #, c-format
 msgid "%s: File already has `%s' suffix, skipping"
 msgstr "%s: il file ha già il suffisso \"%s\", viene saltato"
 
-#: ../src/xz/suffix.c:393
+#: src/xz/suffix.c:393
 #, c-format
 msgid "%s: Invalid filename suffix"
 msgstr "%s: suffisso del nome del file non valido"
 
-#: ../src/xz/util.c:61
+#: src/xz/util.c:71
 #, c-format
 msgid "%s: Value is not a non-negative decimal integer"
 msgstr "%s: il valore non è un numero intero decimale non-negativo"
 
-#: ../src/xz/util.c:103
+#: src/xz/util.c:113
 #, c-format
 msgid "%s: Invalid multiplier suffix"
 msgstr "%s: suffisso del moltiplicatore non valido"
 
-#: ../src/xz/util.c:105
+#: src/xz/util.c:115
 msgid "Valid suffixes are `KiB' (2^10), `MiB' (2^20), and `GiB' (2^30)."
 msgstr ""
 "I suffissi validi sono \"KiB\" (2^10), \"MiB\" (2^20), e \"GiB\" (2^30)."
 
-#: ../src/xz/util.c:122
+#: src/xz/util.c:132
 #, c-format
 msgid "Value of the option `%s' must be in the range [%<PRIu64>, %<PRIu64>]"
 msgstr ""
 "Il valore dell'opzione \"%s\" deve essere nell'intervallo [%<PRIu64>, "
 "%<PRIu64>]"
 
-#: ../src/xz/util.c:247
+#: src/xz/util.c:257
 msgid "Empty filename, skipping"
 msgstr "Nome file vuoto, viene saltato"
 
-#: ../src/xz/util.c:261
+#: src/xz/util.c:271
 msgid "Compressed data cannot be read from a terminal"
 msgstr "I dati compressi non possono essere letti da un terminale"
 
-#: ../src/xz/util.c:274
+#: src/xz/util.c:284
 msgid "Compressed data cannot be written to a terminal"
 msgstr "I dati compressi non possono essere scritti ad un terminale"
 
-#: ../src/common/tuklib_exit.c:39
+#: src/common/tuklib_exit.c:39
 msgid "Writing to standard output failed"
 msgstr "Scrittura sullo standard ouput non riuscita"
 
-#: ../src/common/tuklib_exit.c:42
+#: src/common/tuklib_exit.c:42
 msgid "Unknown error"
 msgstr "Errore sconosciuto"
diff --git a/po/pl.po b/po/pl.po
index 55deda1..3dd222e 100644
--- a/po/pl.po
+++ b/po/pl.po
@@ -1,13 +1,13 @@
 # Polish translation for xz.
 # This file is in the public domain.
-# Jakub Bogusz <qboosh@pld-linux.org>, 2011-2012.
+# Jakub Bogusz <qboosh@pld-linux.org>, 2011-2014.
 #
 msgid ""
 msgstr ""
-"Project-Id-Version: xz 5.1.1\n"
+"Project-Id-Version: xz 5.1.4\n"
 "Report-Msgid-Bugs-To: lasse.collin@tukaani.org\n"
-"POT-Creation-Date: 2012-05-29 13:59+0300\n"
-"PO-Revision-Date: 2012-05-29 18:15+0200\n"
+"POT-Creation-Date: 2014-09-14 21:56+0300\n"
+"PO-Revision-Date: 2014-10-15 20:53+0200\n"
 "Last-Translator: Jakub Bogusz <qboosh@pld-linux.org>\n"
 "Language-Team: Polish <translation-team-pl@lists.sourceforge.net>\n"
 "Language: pl\n"
@@ -16,73 +16,105 @@
 "Content-Transfer-Encoding: 8bit\n"
 "Plural-Forms: nplurals=3; plural=n==1 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2;\n"
 
-#: src/xz/args.c:338
+#: src/xz/args.c:63
+#, c-format
+msgid "%s: Invalid argument to --block-list"
+msgstr "%s: Błędny argument dla --block-list"
+
+#: src/xz/args.c:73
+#, c-format
+msgid "%s: Too many arguments to --block-list"
+msgstr "%s: Zbyt dużo argumentów dla --block-list"
+
+#: src/xz/args.c:102
+msgid "0 can only be used as the last element in --block-list"
+msgstr "0 w --block-list może być użyte wyłącznie jako ostatni element"
+
+#: src/xz/args.c:406
 #, c-format
 msgid "%s: Unknown file format type"
 msgstr "%s: Nieznany typ formatu pliku"
 
-#: src/xz/args.c:361 src/xz/args.c:369
+#: src/xz/args.c:429 src/xz/args.c:437
 #, c-format
 msgid "%s: Unsupported integrity check type"
 msgstr "%s: Nieobsługiwany typ kontroli spójności"
 
-#: src/xz/args.c:396
+#: src/xz/args.c:473
 msgid "Only one file can be specified with `--files' or `--files0'."
 msgstr "Wraz z opcją `--files' lub `--files0' można podać tylko jeden plik."
 
-#: src/xz/args.c:459
+#: src/xz/args.c:541
 #, c-format
 msgid "The environment variable %s contains too many arguments"
 msgstr "Zmienna środowiskowa %s zawiera zbyt dużo argumentów"
 
-#: src/xz/coder.c:105
+#: src/xz/coder.c:110
 msgid "Maximum number of filters is four"
 msgstr "Maksymalna liczba filtrów to cztery"
 
-#: src/xz/coder.c:118
+#: src/xz/coder.c:129
 msgid "Memory usage limit is too low for the given filter setup."
 msgstr "Limit użycia pamięci jest zbyt mały dla podanej konfiguracji filtra."
 
-#: src/xz/coder.c:148
+#: src/xz/coder.c:159
 msgid "Using a preset in raw mode is discouraged."
 msgstr "Użycie ustawień predefiniowanych w trybie surowym jest odradzane."
 
-#: src/xz/coder.c:150
+#: src/xz/coder.c:161
 msgid "The exact options of the presets may vary between software versions."
 msgstr "Dokładne opcje ustawień predefiniowanych mogą różnić się między wersjami oprogramowania."
 
-#: src/xz/coder.c:176
+#: src/xz/coder.c:184
 msgid "The .lzma format supports only the LZMA1 filter"
 msgstr "Format .lzma obsługuje tylko filtr LZMA1"
 
-#: src/xz/coder.c:184
+#: src/xz/coder.c:192
 msgid "LZMA1 cannot be used with the .xz format"
 msgstr "LZMA1 nie może być używany z formatem .xz"
 
-#: src/xz/coder.c:203
+#: src/xz/coder.c:209
+msgid "The filter chain is incompatible with --flush-timeout"
+msgstr "Łańcuch filtrów jest niezgodny z --flush-timeout"
+
+#: src/xz/coder.c:215
+msgid "Switching to single-threaded mode due to --flush-timeout"
+msgstr "Przełączanie w tryb jednowątkowy z powodu --flush-timeout"
+
+#: src/xz/coder.c:234
 #, c-format
 msgid "Using up to %<PRIu32> threads."
 msgstr "Maksymalna liczba używanych wątków: %<PRIu32>."
 
-#: src/xz/coder.c:216
+#: src/xz/coder.c:247
 msgid "Unsupported filter chain or filter options"
 msgstr "Nieobsługiwany łańcuch filtrów lub opcje filtra"
 
-#: src/xz/coder.c:224
+#: src/xz/coder.c:255
 #, c-format
 msgid "Decompression will need %s MiB of memory."
 msgstr "Dekompresja będzie wymagała %s MiB pamięci."
 
-#: src/xz/coder.c:259
+#: src/xz/coder.c:290
 #, c-format
 msgid "Adjusted the number of threads from %s to %s to not exceed the memory usage limit of %s MiB"
 msgstr "Skorygowano liczbę wątków z %s do %s, aby nie przekroczyć limitu użycia pamięci %s MiB"
 
-#: src/xz/coder.c:313
+#: src/xz/coder.c:344
 #, c-format
 msgid "Adjusted LZMA%c dictionary size from %s MiB to %s MiB to not exceed the memory usage limit of %s MiB"
 msgstr "Skorygowano rozmiar słownika LZMA%c z %s MiB do %s MiB aby nie przekroczyć limitu użycia pamięci %s MiB"
 
+#: src/xz/file_io.c:90
+#, c-format
+msgid "Error creating a pipe: %s"
+msgstr "Błąd tworzenia potoku: %s"
+
+#: src/xz/file_io.c:166
+#, c-format
+msgid "%s: poll() failed: %s"
+msgstr "%s: poll() nie powiodło się: %s"
+
 #. TRANSLATORS: When compression or decompression finishes,
 #. and xz is going to remove the source file, xz first checks
 #. if the source file still exists, and if it does, does its
@@ -93,111 +125,136 @@
 #. it is possible that the user has put a new file in place
 #. of the original file, and in that case it obviously
 #. shouldn't be removed.
-#: src/xz/file_io.c:136
+#: src/xz/file_io.c:236
 #, c-format
 msgid "%s: File seems to have been moved, not removing"
 msgstr "%s: Plik wygląda na przeniesiony, nie zostanie usunięty"
 
-#: src/xz/file_io.c:143 src/xz/file_io.c:635
+#: src/xz/file_io.c:243 src/xz/file_io.c:761
 #, c-format
 msgid "%s: Cannot remove: %s"
 msgstr "%s: Nie można usunąć: %s"
 
-#: src/xz/file_io.c:168
+#: src/xz/file_io.c:268
 #, c-format
 msgid "%s: Cannot set the file owner: %s"
 msgstr "%s: Nie można ustawić właściciela pliku: %s"
 
-#: src/xz/file_io.c:174
+#: src/xz/file_io.c:274
 #, c-format
 msgid "%s: Cannot set the file group: %s"
 msgstr "%s: Nie można ustawić grupy pliku: %s"
 
-#: src/xz/file_io.c:193
+#: src/xz/file_io.c:293
 #, c-format
 msgid "%s: Cannot set the file permissions: %s"
 msgstr "%s: Nie można ustawić uprawnień pliku: %s"
 
-#: src/xz/file_io.c:340 src/xz/file_io.c:423
+#: src/xz/file_io.c:399
+#, c-format
+msgid "Error getting the file status flags from standard input: %s"
+msgstr "Błąd podczas pobierania flag stanu pliku ze standardowego wejścia: %s"
+
+#: src/xz/file_io.c:408
+#, c-format
+msgid "Error setting O_NONBLOCK on standard input: %s"
+msgstr "Błąd podczas ustawiania O_NONBLOCK dla standardowego wejścia: %s"
+
+#: src/xz/file_io.c:460 src/xz/file_io.c:522
 #, c-format
 msgid "%s: Is a symbolic link, skipping"
 msgstr "%s: Jest dowiązaniem symbolicznym, pominięto"
 
-#: src/xz/file_io.c:468
+#: src/xz/file_io.c:551
 #, c-format
 msgid "%s: Is a directory, skipping"
 msgstr "%s: Jest katalogiem, pominięto"
 
-#: src/xz/file_io.c:474
+#: src/xz/file_io.c:557
 #, c-format
 msgid "%s: Not a regular file, skipping"
 msgstr "%s: Nie jest zwykłym plikiem, pominięto"
 
-#: src/xz/file_io.c:491
+#: src/xz/file_io.c:574
 #, c-format
 msgid "%s: File has setuid or setgid bit set, skipping"
 msgstr "%s: Plik ma ustawiony bit setuid lub setgid, pominięto"
 
-#: src/xz/file_io.c:498
+#: src/xz/file_io.c:581
 #, c-format
 msgid "%s: File has sticky bit set, skipping"
 msgstr "%s: Plik ma ustawiony bit sticky, pominięto"
 
-#: src/xz/file_io.c:505
+#: src/xz/file_io.c:588
 #, c-format
 msgid "%s: Input file has more than one hard link, skipping"
 msgstr "%s: Plik wejściowy ma więcej niż jedno dowiązanie zwykłe, pominięto"
 
-#: src/xz/file_io.c:761
+#: src/xz/file_io.c:668
+#, c-format
+msgid "Error restoring the status flags to standard input: %s"
+msgstr "Błąd podczas odtwarzania flag stanu dla standardowego wejścia: %s"
+
+#: src/xz/file_io.c:714
+#, c-format
+msgid "Error getting the file status flags from standard output: %s"
+msgstr "Błąd podczas pobierania flag stanu pliku ze standardowego wyjścia: %s"
+
+#: src/xz/file_io.c:723
+#, c-format
+msgid "Error setting O_NONBLOCK on standard output: %s"
+msgstr "Błąd podczas ustawiania O_NONBLOCK dla standardowego wyjścia: %s"
+
+#: src/xz/file_io.c:896
 #, c-format
 msgid "Error restoring the O_APPEND flag to standard output: %s"
 msgstr "Błąd podczas odtwarzania flagi O_APPEND dla standardowego wyjścia: %s"
 
-#: src/xz/file_io.c:773
+#: src/xz/file_io.c:908
 #, c-format
 msgid "%s: Closing the file failed: %s"
 msgstr "%s: Zamknięcie pliku nie powiodło się: %s"
 
-#: src/xz/file_io.c:809 src/xz/file_io.c:1008
+#: src/xz/file_io.c:944 src/xz/file_io.c:1170
 #, c-format
 msgid "%s: Seeking failed when trying to create a sparse file: %s"
 msgstr "%s: Zmiana pozycji nie powiodła się podczas próby utworzenia pliku rzadkiego: %s"
 
-#: src/xz/file_io.c:883
+#: src/xz/file_io.c:1039
 #, c-format
 msgid "%s: Read error: %s"
 msgstr "%s: Błąd odczytu: %s"
 
-#: src/xz/file_io.c:906
+#: src/xz/file_io.c:1059
 #, c-format
 msgid "%s: Error seeking the file: %s"
 msgstr "%s: Błąd podczas zmiany pozycji w pliku: %s"
 
-#: src/xz/file_io.c:916
+#: src/xz/file_io.c:1069
 #, c-format
 msgid "%s: Unexpected end of file"
 msgstr "%s: Nieoczekiwany koniec pliku"
 
-#: src/xz/file_io.c:966
+#: src/xz/file_io.c:1128
 #, c-format
 msgid "%s: Write error: %s"
 msgstr "%s: Błąd zapisu: %s"
 
-#: src/xz/hardware.c:101
+#: src/xz/hardware.c:107
 msgid "Disabled"
 msgstr "Wyłączony"
 
 #. TRANSLATORS: Test with "xz --info-memory" to see if
 #. the alignment looks nice.
-#: src/xz/hardware.c:120
+#: src/xz/hardware.c:126
 msgid "Total amount of physical memory (RAM): "
 msgstr "Całkowita ilość pamięci fizycznej (RAM): "
 
-#: src/xz/hardware.c:122
+#: src/xz/hardware.c:128
 msgid "Memory usage limit for compression:    "
 msgstr "Limit użycia pamięci dla kompresji:      "
 
-#: src/xz/hardware.c:124
+#: src/xz/hardware.c:130
 msgid "Memory usage limit for decompression:  "
 msgstr "Limit użycia pamięci dla dekompresji:    "
 
@@ -275,41 +332,41 @@
 #. to Ratio, the columns are right aligned. Check and Filename
 #. are left aligned. If you need longer words, it's OK to
 #. use two lines here. Test with "xz -l foo.xz".
-#: src/xz/list.c:645
+#: src/xz/list.c:671
 msgid "Strms  Blocks   Compressed Uncompressed  Ratio  Check   Filename"
 msgstr "Strum.  Bloki    Spakowany  Rozpakowany  Wsp.  Kontrola Nazwa pliku"
 
-#: src/xz/list.c:685
+#: src/xz/list.c:711
 #, c-format
 msgid "  Streams:            %s\n"
 msgstr "  Strumienie:            %s\n"
 
-#: src/xz/list.c:687
+#: src/xz/list.c:713
 #, c-format
 msgid "  Blocks:             %s\n"
 msgstr "  Bloki:                 %s\n"
 
-#: src/xz/list.c:689
+#: src/xz/list.c:715
 #, c-format
 msgid "  Compressed size:    %s\n"
 msgstr "  Rozmiar spakowany:     %s\n"
 
-#: src/xz/list.c:692
+#: src/xz/list.c:718
 #, c-format
 msgid "  Uncompressed size:  %s\n"
 msgstr "  Rozmiar rozpakowany:   %s\n"
 
-#: src/xz/list.c:695
+#: src/xz/list.c:721
 #, c-format
 msgid "  Ratio:              %s\n"
 msgstr "  Współczynnik:          %s\n"
 
-#: src/xz/list.c:697
+#: src/xz/list.c:723
 #, c-format
 msgid "  Check:              %s\n"
 msgstr "  Kontrola spójności:    %s\n"
 
-#: src/xz/list.c:698
+#: src/xz/list.c:724
 #, c-format
 msgid "  Stream padding:     %s\n"
 msgstr "  Wyrównanie strumienia: %s\n"
@@ -317,7 +374,7 @@
 #. TRANSLATORS: The second line is column headings. All except
 #. Check are right aligned; Check is left aligned. Test with
 #. "xz -lv foo.xz".
-#: src/xz/list.c:726
+#: src/xz/list.c:752
 msgid ""
 "  Streams:\n"
 "    Stream    Blocks      CompOffset    UncompOffset        CompSize      UncompSize  Ratio  Check      Padding"
@@ -327,7 +384,7 @@
 
 #. TRANSLATORS: The second line is column headings. All
 #. except Check are right aligned; Check is left aligned.
-#: src/xz/list.c:781
+#: src/xz/list.c:807
 #, c-format
 msgid ""
 "  Blocks:\n"
@@ -343,37 +400,37 @@
 #. are right aligned. %*s is replaced with 0-120
 #. spaces to make the CheckVal column wide enough.
 #. Test with "xz -lvv foo.xz".
-#: src/xz/list.c:793
+#: src/xz/list.c:819
 #, c-format
 msgid "      CheckVal %*s Header  Flags        CompSize    MemUsage  Filters"
 msgstr "   S.kontr. %*sNagłówek Flagi     Rozm. spak.  Uż.pamięci  Filtry"
 
-#: src/xz/list.c:871 src/xz/list.c:1046
+#: src/xz/list.c:897 src/xz/list.c:1072
 #, c-format
 msgid "  Memory needed:      %s MiB\n"
 msgstr "  Wymagana pamięć:       %s MiB\n"
 
-#: src/xz/list.c:873 src/xz/list.c:1048
+#: src/xz/list.c:899 src/xz/list.c:1074
 #, c-format
 msgid "  Sizes in headers:   %s\n"
 msgstr "  Rozmiar w nagłówkach:  %s\n"
 
-#: src/xz/list.c:874 src/xz/list.c:1049
+#: src/xz/list.c:900 src/xz/list.c:1075
 msgid "Yes"
 msgstr "Tak"
 
-#: src/xz/list.c:874 src/xz/list.c:1049
+#: src/xz/list.c:900 src/xz/list.c:1075
 msgid "No"
 msgstr "Nie"
 
-#: src/xz/list.c:875 src/xz/list.c:1050
+#: src/xz/list.c:901 src/xz/list.c:1076
 #, c-format
 msgid "  Minimum XZ Utils version: %s\n"
 msgstr "  Minimalna wersja XZ Utils: %s\n"
 
 #. TRANSLATORS: %s is an integer. Only the plural form of this
 #. message is used (e.g. "2 files"). Test with "xz -l foo.xz bar.xz".
-#: src/xz/list.c:1025
+#: src/xz/list.c:1051
 #, c-format
 msgid "%s file\n"
 msgid_plural "%s files\n"
@@ -381,20 +438,20 @@
 msgstr[1] "%s pliki\n"
 msgstr[2] "%s plików\n"
 
-#: src/xz/list.c:1038
+#: src/xz/list.c:1064
 msgid "Totals:"
 msgstr "Sumarycznie:"
 
-#: src/xz/list.c:1039
+#: src/xz/list.c:1065
 #, c-format
 msgid "  Number of files:    %s\n"
 msgstr "  Liczba plików:         %s\n"
 
-#: src/xz/list.c:1114
+#: src/xz/list.c:1140
 msgid "--list works only on .xz files (--format=xz or --format=auto)"
 msgstr "--list działa tylko z plikami .xz (--format=xz lub --format=auto)"
 
-#: src/xz/list.c:1120
+#: src/xz/list.c:1146
 msgid "--list does not support reading from standard input"
 msgstr "--list nie obsługuje odczytu ze standardowego wejścia"
 
@@ -425,68 +482,68 @@
 #. of the line in messages. Usually it becomes "xz: ".
 #. This is a translatable string because French needs
 #. a space before a colon.
-#: src/xz/message.c:733
+#: src/xz/message.c:713
 #, c-format
 msgid "%s: "
 msgstr "%s: "
 
-#: src/xz/message.c:796 src/xz/message.c:846
+#: src/xz/message.c:776 src/xz/message.c:826
 msgid "Internal error (bug)"
 msgstr "Błąd wewnętrzny"
 
-#: src/xz/message.c:803
+#: src/xz/message.c:783
 msgid "Cannot establish signal handlers"
 msgstr "Nie można ustawić obsługi sygnałów"
 
-#: src/xz/message.c:812
+#: src/xz/message.c:792
 msgid "No integrity check; not verifying file integrity"
 msgstr "Brak kontroli spójności; poprawność plików nie będzie weryfikowana"
 
-#: src/xz/message.c:815
+#: src/xz/message.c:795
 msgid "Unsupported type of integrity check; not verifying file integrity"
 msgstr "Nieobsługiwany typ kontroli spójności; poprawność plików nie będzie weryfikowana"
 
-#: src/xz/message.c:822
+#: src/xz/message.c:802
 msgid "Memory usage limit reached"
 msgstr "Osiągnięto limit użycia pamięci"
 
-#: src/xz/message.c:825
+#: src/xz/message.c:805
 msgid "File format not recognized"
 msgstr "Nie rozpoznany format pliku"
 
-#: src/xz/message.c:828
+#: src/xz/message.c:808
 msgid "Unsupported options"
 msgstr "Nieobsługiwane opcje"
 
-#: src/xz/message.c:831
+#: src/xz/message.c:811
 msgid "Compressed data is corrupt"
 msgstr "Dane skompresowane są uszkodzone"
 
-#: src/xz/message.c:834
+#: src/xz/message.c:814
 msgid "Unexpected end of input"
 msgstr "Nieoczekiwany koniec wejścia"
 
-#: src/xz/message.c:867
+#: src/xz/message.c:847
 #, c-format
 msgid "%s MiB of memory is required. The limiter is disabled."
 msgstr "Wymagane jest %s MiB pamięci. Limit jest wyłączony."
 
-#: src/xz/message.c:895
+#: src/xz/message.c:875
 #, c-format
 msgid "%s MiB of memory is required. The limit is %s."
 msgstr "Wymagane jest %s MiB pamięci. Limit to %s."
 
-#: src/xz/message.c:1062
+#: src/xz/message.c:1042
 #, c-format
 msgid "%s: Filter chain: %s\n"
 msgstr "%s: Łańcuch filtrów: %s\n"
 
-#: src/xz/message.c:1072
+#: src/xz/message.c:1052
 #, c-format
 msgid "Try `%s --help' for more information."
 msgstr "Polecenie `%s --help' pokaże więcej informacji."
 
-#: src/xz/message.c:1098
+#: src/xz/message.c:1078
 #, c-format
 msgid ""
 "Usage: %s [OPTION]... [FILE]...\n"
@@ -497,17 +554,17 @@
 "Kompresja lub dekompresja PLIKÓW w formacie .xz.\n"
 "\n"
 
-#: src/xz/message.c:1105
+#: src/xz/message.c:1085
 msgid "Mandatory arguments to long options are mandatory for short options too.\n"
 msgstr ""
 "Argumenty obowiązkowe dla opcji długich są obowiązkowe również dla opcji\n"
 "krótkich.\n"
 
-#: src/xz/message.c:1109
+#: src/xz/message.c:1089
 msgid " Operation mode:\n"
 msgstr " Tryb pracy:\n"
 
-#: src/xz/message.c:1112
+#: src/xz/message.c:1092
 msgid ""
 "  -z, --compress      force compression\n"
 "  -d, --decompress    force decompression\n"
@@ -519,7 +576,7 @@
 "  -t, --test          sprawdzenie spójności plików skompresowanych\n"
 "  -l, --list          wypisanie informacji o plikach .xz"
 
-#: src/xz/message.c:1118
+#: src/xz/message.c:1098
 msgid ""
 "\n"
 " Operation modifiers:\n"
@@ -527,7 +584,7 @@
 "\n"
 " Modyfikatory operacji:\n"
 
-#: src/xz/message.c:1121
+#: src/xz/message.c:1101
 msgid ""
 "  -k, --keep          keep (don't delete) input files\n"
 "  -f, --force         force overwrite of output file and (de)compress links\n"
@@ -537,7 +594,7 @@
 "  -f, --force         nadpisywanie plików wyjściowych i (de)kompresja dowiązań\n"
 "  -c, --stdout        zapis na standardowe wyjście, nieusuwanie plików wej."
 
-#: src/xz/message.c:1127
+#: src/xz/message.c:1107
 msgid ""
 "      --single-stream decompress only the first stream, and silently\n"
 "                      ignore possible remaining input data"
@@ -545,7 +602,7 @@
 "      --single-stream dekompresja tylko pierwszego strumienia, ciche\n"
 "                      zignorowanie pozostałych danych wejściowych"
 
-#: src/xz/message.c:1130
+#: src/xz/message.c:1110
 msgid ""
 "      --no-sparse     do not create sparse files when decompressing\n"
 "  -S, --suffix=.SUF   use the suffix `.SUF' on compressed files\n"
@@ -561,7 +618,7 @@
 "                      wejścia; muszą być zakończone znakiem nowej linii\n"
 "      --files0[=PLIK] podobnie do --files, ale znakiem kończącym musi być NUL"
 
-#: src/xz/message.c:1139
+#: src/xz/message.c:1119
 msgid ""
 "\n"
 " Basic file format and compression options:\n"
@@ -569,7 +626,7 @@
 "\n"
 " Podstawowe opcje formatu pliku i kompresji:\n"
 
-#: src/xz/message.c:1141
+#: src/xz/message.c:1121
 msgid ""
 "  -F, --format=FMT    file format to encode or decode; possible values are\n"
 "                      `auto' (default), `xz', `lzma', and `raw'\n"
@@ -581,7 +638,11 @@
 "  -C, --check=TEST    typ kontroli spójności: `none' (ostrożnie!),\n"
 "                      `crc32', `crc64' (domyślny) lub `sha256'"
 
-#: src/xz/message.c:1148
+#: src/xz/message.c:1126
+msgid "      --ignore-check  don't verify the integrity check when decompressing"
+msgstr "      --ignore-check  bez kontroli sprawdzania integralności przy dekompresji"
+
+#: src/xz/message.c:1130
 msgid ""
 "  -0 ... -9           compression preset; default is 6; take compressor *and*\n"
 "                      decompressor memory usage into account before using 7-9!"
@@ -590,7 +651,7 @@
 "                      użyciem wartości 7-9 należy wziąć pod uwagę wykorzystanie\n"
 "                      pamięci przy kompresji *oraz* dekompresji!"
 
-#: src/xz/message.c:1152
+#: src/xz/message.c:1134
 msgid ""
 "  -e, --extreme       try to improve compression ratio by using more CPU time;\n"
 "                      does not affect decompressor memory requirements"
@@ -599,17 +660,48 @@
 "                      ilości czasu procesora; nie wpływa na wymagania\n"
 "                      pamięciowe dekompresora"
 
-#: src/xz/message.c:1157
+#: src/xz/message.c:1138
+msgid ""
+"  -T, --threads=NUM   use at most NUM threads; the default is 1; set to 0\n"
+"                      to use as many threads as there are processor cores"
+msgstr ""
+"  -T, --threads=ILE   użycie maksymalnie ILU wątków; domyślnie 1; 0 oznacza\n"
+"                      tyle, ile jest rdzeni procesorów"
+
+#: src/xz/message.c:1143
 msgid ""
 "      --block-size=SIZE\n"
-"                      when compressing to the .xz format, start a new block\n"
-"                      after every SIZE bytes of input; 0=disabled (default)"
+"                      start a new .xz block after every SIZE bytes of input;\n"
+"                      use this to set the block size for threaded compression"
 msgstr ""
-"      --block-size=LICZBA\n"
-"                      przy kompresji do formatu .xz: rozpoczynanie nowego bloku\n"
-"                      po każdej LICZBIE bajtów wejścia; 0=wyłączone (domyślne)"
+"      --block-size=ROZMIAR\n"
+"                      rozpoczęcie nowego bloku .xz co ROZMIAR bajtów wejścia;\n"
+"                      opcja służy do ustawienia rozmiaru bloku dla kompresji\n"
+"                      wielowątkowej"
 
-#: src/xz/message.c:1161
+#: src/xz/message.c:1147
+msgid ""
+"      --block-list=SIZES\n"
+"                      start a new .xz block after the given comma-separated\n"
+"                      intervals of uncompressed data"
+msgstr ""
+"      --block-list=ROZMIARY\n"
+"                      rozpoczęcie nowego bloku .xz po rozdzielonych przecinkiem\n"
+"                      przedziałach danych nieskompresowanych"
+
+#: src/xz/message.c:1151
+msgid ""
+"      --flush-timeout=TIMEOUT\n"
+"                      when compressing, if more than TIMEOUT milliseconds has\n"
+"                      passed since the previous flush and reading more input\n"
+"                      would block, all pending data is flushed out"
+msgstr ""
+"      --flush-timeout=CZAS\n"
+"                      przy kompresji, jeśli minęło więcej niż CZAS milisekund\n"
+"                      ostatniegu zapisu bloku, a odczyt kolejnych danych byłby\n"
+"                      blokujący, wszystkie gotowe dane są zapisywane"
+
+#: src/xz/message.c:1157
 #, no-c-format
 msgid ""
 "      --memlimit-compress=LIMIT\n"
@@ -625,7 +717,7 @@
 "                      dekompresji lub obu; LIMIT jest w bajtach, % RAM lub 0\n"
 "                      dla limitów domyślnych"
 
-#: src/xz/message.c:1168
+#: src/xz/message.c:1164
 msgid ""
 "      --no-adjust     if compression settings exceed the memory usage limit,\n"
 "                      give an error instead of adjusting the settings downwards"
@@ -634,7 +726,7 @@
 "                      pamięci, zostanie zgłoszony błąd zamiast zmniejszania\n"
 "                      ustawień"
 
-#: src/xz/message.c:1174
+#: src/xz/message.c:1170
 msgid ""
 "\n"
 " Custom filter chain for compression (alternative for using presets):"
@@ -642,7 +734,7 @@
 "\n"
 " Łańcuch własnych filtrów do kompresji (alternatywa do używania -0 .. -9):"
 
-#: src/xz/message.c:1183
+#: src/xz/message.c:1179
 msgid ""
 "\n"
 "  --lzma1[=OPTS]      LZMA1 or LZMA2; OPTS is a comma-separated list of zero or\n"
@@ -671,7 +763,7 @@
 "                        mf=NAZWA   dopasowywacz (hc3, hc4, bt2, bt3, bt4; bt4)\n"
 "                        depth=ILE  maks. głębokość szukania; 0=auto (domyślne)"
 
-#: src/xz/message.c:1198
+#: src/xz/message.c:1194
 msgid ""
 "\n"
 "  --x86[=OPTS]        x86 BCJ filter (32-bit and 64-bit)\n"
@@ -693,7 +785,7 @@
 "                      Poprawne OPCJE dla wszystkich filtrów BCJ:\n"
 "                        start=ILE  offset początku konwersji (domyślnie=0)"
 
-#: src/xz/message.c:1210
+#: src/xz/message.c:1206
 msgid ""
 "\n"
 "  --delta[=OPTS]      Delta filter; valid OPTS (valid values; default):\n"
@@ -705,7 +797,7 @@
 "                        dist=ILE   odległość między bajtami odejmowanymi od\n"
 "                                   siebie (1-256; 1)"
 
-#: src/xz/message.c:1218
+#: src/xz/message.c:1214
 msgid ""
 "\n"
 " Other options:\n"
@@ -713,7 +805,7 @@
 "\n"
 " Inne opcje:\n"
 
-#: src/xz/message.c:1221
+#: src/xz/message.c:1217
 msgid ""
 "  -q, --quiet         suppress warnings; specify twice to suppress errors too\n"
 "  -v, --verbose       be verbose; specify twice for even more verbose"
@@ -721,15 +813,15 @@
 "  -q, --quiet         pominięcie ostrzeżeń; dwukrotne podanie pomija też błędy\n"
 "  -v, --verbose       więcej informacji; dwukrotne podanie to jeszcze więcej"
 
-#: src/xz/message.c:1226
+#: src/xz/message.c:1222
 msgid "  -Q, --no-warn       make warnings not affect the exit status"
 msgstr "  -Q, --no-warn       ostrzeżenia nie mają wpływu na status zakończenia"
 
-#: src/xz/message.c:1228
+#: src/xz/message.c:1224
 msgid "      --robot         use machine-parsable messages (useful for scripts)"
 msgstr "      --robot         komunikaty w formacie dla maszyny (do skryptów)"
 
-#: src/xz/message.c:1231
+#: src/xz/message.c:1227
 msgid ""
 "      --info-memory   display the total amount of RAM and the currently active\n"
 "                      memory usage limits, and exit"
@@ -737,7 +829,7 @@
 "      --info-memory   wyświetlenie całkowitej ilości pamięci RAM oraz aktualnie\n"
 "                      aktywnych limitów pamięci i zakończenie pracy"
 
-#: src/xz/message.c:1234
+#: src/xz/message.c:1230
 msgid ""
 "  -h, --help          display the short help (lists only the basic options)\n"
 "  -H, --long-help     display this long help and exit"
@@ -745,7 +837,7 @@
 "  -h, --help          wyświetlenie krótkiego opisu (tylko podstawowe opcje)\n"
 "  -H, --long-help     wyświetlenie tego długiego opisu i zakończenie"
 
-#: src/xz/message.c:1238
+#: src/xz/message.c:1234
 msgid ""
 "  -h, --help          display this short help and exit\n"
 "  -H, --long-help     display the long help (lists also the advanced options)"
@@ -753,11 +845,11 @@
 "  -h, --help          wyświetlenie tego krótkiego opisu i zakończenie\n"
 "  -H, --long-help     wyświetlenie długiego opisu (także opcje zaawansowane)"
 
-#: src/xz/message.c:1243
+#: src/xz/message.c:1239
 msgid "  -V, --version       display the version number and exit"
 msgstr "  -V, --version       wyświetlenie informacji o wersji i zakończenie"
 
-#: src/xz/message.c:1245
+#: src/xz/message.c:1241
 msgid ""
 "\n"
 "With no FILE, or when FILE is -, read standard input.\n"
@@ -769,7 +861,7 @@
 #. for this package. Please add _another line_ saying
 #. "Report translation bugs to <...>\n" with the email or WWW
 #. address for translation bugs. Thanks.
-#: src/xz/message.c:1251
+#: src/xz/message.c:1247
 #, c-format
 msgid "Report bugs to <%s> (in English or Finnish).\n"
 msgstr ""
@@ -778,11 +870,15 @@
 "Błędy w tłumaczeniu prosimy zgłaszać na adres\n"
 "<translation-team-pl@lists.sourceforge.net>.\n"
 
-#: src/xz/message.c:1253
+#: src/xz/message.c:1249
 #, c-format
 msgid "%s home page: <%s>\n"
 msgstr "Strona domowa %s: <%s>\n"
 
+#: src/xz/message.c:1253
+msgid "THIS IS A DEVELOPMENT VERSION NOT INTENDED FOR PRODUCTION USE."
+msgstr "TA WERSJA JEST ROZWOJOWA, NIE PRZEZNACZONA DO UŻYTKU PRODUKCYJNEGO."
+
 #: src/xz/options.c:86
 #, c-format
 msgid "%s: Options must be `name=value' pairs separated with commas"
@@ -832,34 +928,34 @@
 msgid "%s: Invalid filename suffix"
 msgstr "%s: Błędne rozszerzenie nazwy pliku"
 
-#: src/xz/util.c:61
+#: src/xz/util.c:71
 #, c-format
 msgid "%s: Value is not a non-negative decimal integer"
 msgstr "%s: Wartość nie jest nieujemną liczbą całkowitą"
 
-#: src/xz/util.c:103
+#: src/xz/util.c:113
 #, c-format
 msgid "%s: Invalid multiplier suffix"
 msgstr "%s: Błędny przyrostek mnożnika"
 
-#: src/xz/util.c:105
+#: src/xz/util.c:115
 msgid "Valid suffixes are `KiB' (2^10), `MiB' (2^20), and `GiB' (2^30)."
 msgstr "Poprawne przyrostki to `KiB' (2^10), `MiB' (2^20) i `GiB' (2^30)."
 
-#: src/xz/util.c:122
+#: src/xz/util.c:132
 #, c-format
 msgid "Value of the option `%s' must be in the range [%<PRIu64>, %<PRIu64>]"
 msgstr "Wartość opcji `%s' musi być w przedziale [%<PRIu64>, %<PRIu64>]"
 
-#: src/xz/util.c:247
+#: src/xz/util.c:257
 msgid "Empty filename, skipping"
 msgstr "Pusta nazwa pliku, pominięto"
 
-#: src/xz/util.c:261
+#: src/xz/util.c:271
 msgid "Compressed data cannot be read from a terminal"
 msgstr "Dane skompresowane nie mogą być czytane z terminala"
 
-#: src/xz/util.c:274
+#: src/xz/util.c:284
 msgid "Compressed data cannot be written to a terminal"
 msgstr "Dane skompresowane nie mogą być zapisywane na terminal"
 
diff --git a/po/vi.po b/po/vi.po
new file mode 100644
index 0000000..a5e7382
--- /dev/null
+++ b/po/vi.po
@@ -0,0 +1,1039 @@
+# Vietnamese translations for xz package
+# Bản dịch tiếng Việt cho gói xz.
+# This file is put in the public domain.
+# Trần Ngọc Quân <vnwildman@gmail.com>, 2014.
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: xz 5.1.4beta\n"
+"Report-Msgid-Bugs-To: lasse.collin@tukaani.org\n"
+"POT-Creation-Date: 2014-09-25 08:57+0700\n"
+"PO-Revision-Date: 2014-09-25 09:06+0700\n"
+"Last-Translator: Trần Ngọc Quân <vnwildman@gmail.com>\n"
+"Language-Team: Vietnamese <translation-team-vi@lists.sourceforge.net>\n"
+"Language: vi\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"Plural-Forms: nplurals=1; plural=0;\n"
+"X-Poedit-Basepath: ../\n"
+
+#: src/xz/args.c:63
+#, c-format
+msgid "%s: Invalid argument to --block-list"
+msgstr "%s: Đối số cho --block-list không hợp lệ"
+
+#: src/xz/args.c:73
+#, c-format
+msgid "%s: Too many arguments to --block-list"
+msgstr "%s: Quá nhiều đối số cho --block-list"
+
+#: src/xz/args.c:102
+msgid "0 can only be used as the last element in --block-list"
+msgstr "0 chỉ có thể dùng như là phần tử cuối trong --block-list"
+
+#: src/xz/args.c:406
+#, c-format
+msgid "%s: Unknown file format type"
+msgstr "%s: Không hiểu kiểu định dạng tập tin"
+
+#: src/xz/args.c:429 src/xz/args.c:437
+#, c-format
+msgid "%s: Unsupported integrity check type"
+msgstr "%s: Không hỗ trợ kiểu kiểm tra toàn vẹn"
+
+#: src/xz/args.c:473
+msgid "Only one file can be specified with `--files' or `--files0'."
+msgstr "Chỉ được đưa ra một tập tin cho “--files” hay “--files0”."
+
+#: src/xz/args.c:541
+#, c-format
+msgid "The environment variable %s contains too many arguments"
+msgstr "Biến môi trường %s chứa quá nhiều đối số"
+
+#: src/xz/coder.c:110
+msgid "Maximum number of filters is four"
+msgstr "Số lượng bộ lọc tối đa là bốn"
+
+#: src/xz/coder.c:129
+msgid "Memory usage limit is too low for the given filter setup."
+msgstr "Mức giới hạn dùng bộ nhớ là quá thấp cho việc cài đặt bộ lọc đã cho."
+
+#: src/xz/coder.c:159
+msgid "Using a preset in raw mode is discouraged."
+msgstr "Dùng hiện tại trong chế độ thô là ngớ ngẩn."
+
+#: src/xz/coder.c:161
+msgid "The exact options of the presets may vary between software versions."
+msgstr ""
+"Các tùy chọn trích xuất của chỉnh trước có thể biến đổi phụ thuộc vào phiên "
+"bản."
+
+#: src/xz/coder.c:184
+msgid "The .lzma format supports only the LZMA1 filter"
+msgstr "Định dạng .lzma chỉ hỗ trợ bộ lọc LZMA1"
+
+#: src/xz/coder.c:192
+msgid "LZMA1 cannot be used with the .xz format"
+msgstr "LZMA1 không thể được dùng với định dạng .xz"
+
+#: src/xz/coder.c:209
+msgid "The filter chain is incompatible with --flush-timeout"
+msgstr "Móc xích lọc là không tương thích với --flush-timeout"
+
+#: src/xz/coder.c:215
+msgid "Switching to single-threaded mode due to --flush-timeout"
+msgstr "Chuyển sang chế độ đơn tuyến trình bởi vì --flush-timeout"
+
+#: src/xz/coder.c:234
+#, c-format
+msgid "Using up to %<PRIu32> threads."
+msgstr "Dùng đến %<PRIu32> tuyến trình."
+
+#: src/xz/coder.c:247
+msgid "Unsupported filter chain or filter options"
+msgstr "Không hỗ trợ lọc móc xích hay tùy chọn lọc"
+
+#: src/xz/coder.c:255
+#, c-format
+msgid "Decompression will need %s MiB of memory."
+msgstr "Giải nén sẽ cần %s MiB bộ nhớ."
+
+#: src/xz/coder.c:290
+#, c-format
+msgid ""
+"Adjusted the number of threads from %s to %s to not exceed the memory usage "
+"limit of %s MiB"
+msgstr ""
+"Chỉnh số lượng tuyến trình từ %s thành %s để không vượt quá giới hạn tiêu "
+"dùng bộ nhớ là %s MiB"
+
+#: src/xz/coder.c:344
+#, c-format
+msgid ""
+"Adjusted LZMA%c dictionary size from %s MiB to %s MiB to not exceed the "
+"memory usage limit of %s MiB"
+msgstr ""
+"Chỉnh cỡ từ điển LZMA%c từ %s MiB thành %s MiB để không vượt quá giới hạn "
+"tiêu dùng bộ nhớ là %s MiB"
+
+#: src/xz/file_io.c:90
+#, c-format
+msgid "Error creating a pipe: %s"
+msgstr "Gặp lỗi khi tạo một ống dẫn: %s"
+
+#: src/xz/file_io.c:166
+#, c-format
+msgid "%s: poll() failed: %s"
+msgstr "%s: hàm poll() bị lỗi: %s"
+
+#. TRANSLATORS: When compression or decompression finishes,
+#. and xz is going to remove the source file, xz first checks
+#. if the source file still exists, and if it does, does its
+#. device and inode numbers match what xz saw when it opened
+#. the source file. If these checks fail, this message is
+#. shown, %s being the filename, and the file is not deleted.
+#. The check for device and inode numbers is there, because
+#. it is possible that the user has put a new file in place
+#. of the original file, and in that case it obviously
+#. shouldn't be removed.
+#: src/xz/file_io.c:236
+#, c-format
+msgid "%s: File seems to have been moved, not removing"
+msgstr "%s: Tập tin có lẽ đã bị di chuyển, không phải gỡ bỏ"
+
+#: src/xz/file_io.c:243 src/xz/file_io.c:761
+#, c-format
+msgid "%s: Cannot remove: %s"
+msgstr "%s: Không thể gỡ bỏ: %s"
+
+#: src/xz/file_io.c:268
+#, c-format
+msgid "%s: Cannot set the file owner: %s"
+msgstr "%s: Không thể đặt chủ sở hữu tập tin: %s"
+
+#: src/xz/file_io.c:274
+#, c-format
+msgid "%s: Cannot set the file group: %s"
+msgstr "%s: Không thể đặt nhóm tập tin: %s"
+
+#: src/xz/file_io.c:293
+#, c-format
+msgid "%s: Cannot set the file permissions: %s"
+msgstr "%s: Không thể đặt chế độ đọc ghi cho tập tin: %s"
+
+#: src/xz/file_io.c:399
+#, c-format
+msgid "Error getting the file status flags from standard input: %s"
+msgstr "Gặp lỗi khi lấy các cờ trạng thái tập tin từ đầu vào tiêu chuẩn: %s"
+
+#: src/xz/file_io.c:408
+#, c-format
+msgid "Error setting O_NONBLOCK on standard input: %s"
+msgstr "Lỗi cài đặt O_NONBLOCK trên đầu vào tiêu chuẩn: %s"
+
+#: src/xz/file_io.c:460 src/xz/file_io.c:522
+#, c-format
+msgid "%s: Is a symbolic link, skipping"
+msgstr "%s: Là một liên kết mềm nên bỏ qua"
+
+#: src/xz/file_io.c:551
+#, c-format
+msgid "%s: Is a directory, skipping"
+msgstr "%s: Không phải là một thư mục nên bỏ qua"
+
+#: src/xz/file_io.c:557
+#, c-format
+msgid "%s: Not a regular file, skipping"
+msgstr "%s: Không phải là tập tin thường nên bỏ qua"
+
+#: src/xz/file_io.c:574
+#, c-format
+msgid "%s: File has setuid or setgid bit set, skipping"
+msgstr "%s: Tập tin có đặt bít setuid hoặc setgid nên bỏ qua"
+
+#: src/xz/file_io.c:581
+#, c-format
+msgid "%s: File has sticky bit set, skipping"
+msgstr "%s: Tập tin có bít sticky nên bỏ qua"
+
+#: src/xz/file_io.c:588
+#, c-format
+msgid "%s: Input file has more than one hard link, skipping"
+msgstr "%s: Tập tin đầu vào có nhiều hơn một liên kết cứng nên bỏ qua"
+
+#: src/xz/file_io.c:668
+#, c-format
+msgid "Error restoring the status flags to standard input: %s"
+msgstr "Gặp lỗi khi phục hồi các cờ trạng thái tới đầu vào tiêu chuẩn: %s"
+
+#: src/xz/file_io.c:714
+#, c-format
+msgid "Error getting the file status flags from standard output: %s"
+msgstr "Gặp lỗi khi lấy các cờ trạng thái tập tin từ đầu vào tiêu chuẩn: %s"
+
+#: src/xz/file_io.c:723
+#, c-format
+msgid "Error setting O_NONBLOCK on standard output: %s"
+msgstr "Lỗi cài đặt O_NONBLOCK trên đầu ra tiêu chuẩn: %s"
+
+#: src/xz/file_io.c:896
+#, c-format
+msgid "Error restoring the O_APPEND flag to standard output: %s"
+msgstr "Gặp lỗi khi phục hồi cờ O_APPEND trên đầu ra tiêu chuẩn: %s"
+
+#: src/xz/file_io.c:908
+#, c-format
+msgid "%s: Closing the file failed: %s"
+msgstr "%s: Gặp lỗi khi đóng tập tin: %s"
+
+#: src/xz/file_io.c:944 src/xz/file_io.c:1170
+#, c-format
+msgid "%s: Seeking failed when trying to create a sparse file: %s"
+msgstr ""
+"%s: Gặp lỗi khi di chuyển vị trí đọc khi cố tạo một tập tin rải rác: %s"
+
+#: src/xz/file_io.c:1039
+#, c-format
+msgid "%s: Read error: %s"
+msgstr "%s: Lỗi đọc: %s"
+
+#: src/xz/file_io.c:1059
+#, c-format
+msgid "%s: Error seeking the file: %s"
+msgstr "%s: Gặp lỗi khi di chuyển vị trí đọc tập tin: %s"
+
+#: src/xz/file_io.c:1069
+#, c-format
+msgid "%s: Unexpected end of file"
+msgstr "%s: Kết thúc tập tin bất ngờ"
+
+#: src/xz/file_io.c:1128
+#, c-format
+msgid "%s: Write error: %s"
+msgstr "%s: Lỗi ghi: %s"
+
+#: src/xz/hardware.c:107
+msgid "Disabled"
+msgstr "Bị tắt"
+
+#. TRANSLATORS: Test with "xz --info-memory" to see if
+#. the alignment looks nice.
+#: src/xz/hardware.c:126
+msgid "Total amount of physical memory (RAM): "
+msgstr "Tổng dung lượng bộ nhớ vật lý (RAM):  "
+
+#: src/xz/hardware.c:128
+msgid "Memory usage limit for compression:    "
+msgstr "Mức giới hạn dùng bộ nhớ cho nén:     "
+
+#: src/xz/hardware.c:130
+msgid "Memory usage limit for decompression:  "
+msgstr "Mức giới hạn dùng bộ nhớ cho giải nén:"
+
+#. TRANSLATORS: Indicates that there is no integrity check.
+#. This string is used in tables, so the width must not
+#. exceed ten columns with a fixed-width font.
+#: src/xz/list.c:65
+msgid "None"
+msgstr "Không"
+
+#. TRANSLATORS: Indicates that integrity check name is not known,
+#. but the Check ID is known (here 2). This and other "Unknown-N"
+#. strings are used in tables, so the width must not exceed ten
+#. columns with a fixed-width font. It's OK to omit the dash if
+#. you need space for one extra letter, but don't use spaces.
+#: src/xz/list.c:72
+msgid "Unknown-2"
+msgstr "Chưa_biết2"
+
+#: src/xz/list.c:73
+msgid "Unknown-3"
+msgstr "Chưa_biết3"
+
+#: src/xz/list.c:75
+msgid "Unknown-5"
+msgstr "Chưa_biết5"
+
+#: src/xz/list.c:76
+msgid "Unknown-6"
+msgstr "Chưa_biết6"
+
+#: src/xz/list.c:77
+msgid "Unknown-7"
+msgstr "Chưa_biết7"
+
+#: src/xz/list.c:78
+msgid "Unknown-8"
+msgstr "Chưa_biết8"
+
+#: src/xz/list.c:79
+msgid "Unknown-9"
+msgstr "Chưa_biết9"
+
+#: src/xz/list.c:81
+msgid "Unknown-11"
+msgstr "ChưaBiết11"
+
+#: src/xz/list.c:82
+msgid "Unknown-12"
+msgstr "ChưaBiết12"
+
+#: src/xz/list.c:83
+msgid "Unknown-13"
+msgstr "ChưaBiết13"
+
+#: src/xz/list.c:84
+msgid "Unknown-14"
+msgstr "ChưaBiết14"
+
+#: src/xz/list.c:85
+msgid "Unknown-15"
+msgstr "ChưaBiết15"
+
+#: src/xz/list.c:153
+#, c-format
+msgid "%s: File is empty"
+msgstr "%s: Tập tin trống rỗng"
+
+#: src/xz/list.c:158
+#, c-format
+msgid "%s: Too small to be a valid .xz file"
+msgstr "%s: Là quá nhỏ đối với tập tin .xz hợp lệ"
+
+#. TRANSLATORS: These are column headings. From Strms (Streams)
+#. to Ratio, the columns are right aligned. Check and Filename
+#. are left aligned. If you need longer words, it's OK to
+#. use two lines here. Test with "xz -l foo.xz".
+#: src/xz/list.c:671
+msgid "Strms  Blocks   Compressed Uncompressed  Ratio  Check   Filename"
+msgstr "Luồng    Khối          Nén     Giải nén  Tỷ lệ  Ktra    Tập tin"
+
+#: src/xz/list.c:711
+#, c-format
+msgid "  Streams:            %s\n"
+msgstr "  Luồng dữ liệu:      %s\n"
+
+#: src/xz/list.c:713
+#, c-format
+msgid "  Blocks:             %s\n"
+msgstr "  Khối:               %s\n"
+
+#: src/xz/list.c:715
+#, c-format
+msgid "  Compressed size:    %s\n"
+msgstr "  Cỡ khi bị nén:      %s\n"
+
+#: src/xz/list.c:718
+#, c-format
+msgid "  Uncompressed size:  %s\n"
+msgstr "  Cỡ sau giải nén:    %s\n"
+
+#: src/xz/list.c:721
+#, c-format
+msgid "  Ratio:              %s\n"
+msgstr "  Tỷ lệ nén:          %s\n"
+
+#: src/xz/list.c:723
+#, c-format
+msgid "  Check:              %s\n"
+msgstr "  Kiểm tra:           %s\n"
+
+#: src/xz/list.c:724
+#, c-format
+msgid "  Stream padding:     %s\n"
+msgstr "  Đệm luồng dữ liệu:  %s\n"
+
+#. TRANSLATORS: The second line is column headings. All except
+#. Check are right aligned; Check is left aligned. Test with
+#. "xz -lv foo.xz".
+#: src/xz/list.c:752
+msgid ""
+"  Streams:\n"
+"    Stream    Blocks      CompOffset    UncompOffset        CompSize      "
+"UncompSize  Ratio  Check      Padding"
+msgstr ""
+"  Luồng dữ liệu:\n"
+"     Luồng      Khối           BùNén       BùGiảiNén           CỡNén       "
+"CỡGiảiNén   TỷLệ  Ktra           Đệm"
+
+#. TRANSLATORS: The second line is column headings. All
+#. except Check are right aligned; Check is left aligned.
+#: src/xz/list.c:807
+#, c-format
+msgid ""
+"  Blocks:\n"
+"    Stream     Block      CompOffset    UncompOffset       TotalSize      "
+"UncompSize  Ratio  Check"
+msgstr ""
+"  Khối:\n"
+"     Luồng      Khối           BùNén       BùGiảiNén          CỡTổng       "
+"CỡGiảiNén   TỷLệ  Ktra"
+
+#. TRANSLATORS: These are additional column headings
+#. for the most verbose listing mode. CheckVal
+#. (Check value), Flags, and Filters are left aligned.
+#. Header (Block Header Size), CompSize, and MemUsage
+#. are right aligned. %*s is replaced with 0-120
+#. spaces to make the CheckVal column wide enough.
+#. Test with "xz -lvv foo.xz".
+#: src/xz/list.c:819
+#, c-format
+msgid "      CheckVal %*s Header  Flags        CompSize    MemUsage  Filters"
+msgstr "       GTrịKiểm %*s    Đầu  Cờ              CỡNén     DùngRAM  BộLọc"
+
+#: src/xz/list.c:897 src/xz/list.c:1072
+#, c-format
+msgid "  Memory needed:      %s MiB\n"
+msgstr "  Bộ nhớ cần:         %s MiB\n"
+
+#: src/xz/list.c:899 src/xz/list.c:1074
+#, c-format
+msgid "  Sizes in headers:   %s\n"
+msgstr "  Kích cỡ phần đầu:   %s\n"
+
+#: src/xz/list.c:900 src/xz/list.c:1075
+msgid "Yes"
+msgstr "Có"
+
+#: src/xz/list.c:900 src/xz/list.c:1075
+msgid "No"
+msgstr "Không"
+
+#: src/xz/list.c:901 src/xz/list.c:1076
+#, c-format
+msgid "  Minimum XZ Utils version: %s\n"
+msgstr "  Phiên bản “XZ Utils” tối thiểu: %s\n"
+
+#. TRANSLATORS: %s is an integer. Only the plural form of this
+#. message is used (e.g. "2 files"). Test with "xz -l foo.xz bar.xz".
+#: src/xz/list.c:1051
+#, c-format
+msgid "%s file\n"
+msgid_plural "%s files\n"
+msgstr[0] "%s tập tin\n"
+
+#: src/xz/list.c:1064
+msgid "Totals:"
+msgstr "Tổng cộng:"
+
+#: src/xz/list.c:1065
+#, c-format
+msgid "  Number of files:    %s\n"
+msgstr "  Số tập tin:         %s\n"
+
+#: src/xz/list.c:1140
+msgid "--list works only on .xz files (--format=xz or --format=auto)"
+msgstr ""
+"--list chỉ hoạt động trên các tập tin .xz (--format=xz hay --format=auto)"
+
+#: src/xz/list.c:1146
+msgid "--list does not support reading from standard input"
+msgstr "--list không hỗ trợ đọc từ đầu vào tiêu chuẩn"
+
+#: src/xz/main.c:89
+#, c-format
+msgid "%s: Error reading filenames: %s"
+msgstr "%s: Gặp lỗi khi đọc tên tập tin: %s"
+
+#: src/xz/main.c:96
+#, c-format
+msgid "%s: Unexpected end of input when reading filenames"
+msgstr "%s: Gặp kết thúc đầu vào bất ngờ khi đọc các tên tập tin"
+
+#: src/xz/main.c:120
+#, c-format
+msgid ""
+"%s: Null character found when reading filenames; maybe you meant to use `--"
+"files0' instead of `--files'?"
+msgstr ""
+"%s: Gặp ký hiệu Null khi đọc tên tập tin; có lẽ ý bạn muốn là dùng “--"
+"files0” chứ không phải “--files'?"
+
+#: src/xz/main.c:174
+msgid "Compression and decompression with --robot are not supported yet."
+msgstr "Nén và giải nén với --robot vẫn chưa được hỗ trợ."
+
+#: src/xz/main.c:231
+msgid ""
+"Cannot read data from standard input when reading filenames from standard "
+"input"
+msgstr ""
+"Không thể đọc dữ liệu từ đầu vào tiêu chuẩn khi đọc tập tin từ đầu vào tiêu "
+"chuẩn"
+
+#. TRANSLATORS: This is the program name in the beginning
+#. of the line in messages. Usually it becomes "xz: ".
+#. This is a translatable string because French needs
+#. a space before a colon.
+#: src/xz/message.c:713
+#, c-format
+msgid "%s: "
+msgstr "%s: "
+
+#: src/xz/message.c:776 src/xz/message.c:826
+msgid "Internal error (bug)"
+msgstr "Lỗi nội bộ (lỗi)"
+
+#: src/xz/message.c:783
+msgid "Cannot establish signal handlers"
+msgstr "Không thể thiết lập bộ xử lý tín hiệu"
+
+#: src/xz/message.c:792
+msgid "No integrity check; not verifying file integrity"
+msgstr ""
+"Không có kiểm tra toàn vẹn nên không thể thẩm tra tính toàn vẹn của tập tin"
+
+#: src/xz/message.c:795
+msgid "Unsupported type of integrity check; not verifying file integrity"
+msgstr ""
+"Kiểu kiểm tra toàn vẹn chưa được hỗ trợ; nên không thể thẩm tra tính toàn "
+"vẹn của tập tin"
+
+#: src/xz/message.c:802
+msgid "Memory usage limit reached"
+msgstr "Đã chạm mốc giới hạn sử dụng bộ nhớ"
+
+#: src/xz/message.c:805
+msgid "File format not recognized"
+msgstr "Không nhận ra định dạng tập tin"
+
+#: src/xz/message.c:808
+msgid "Unsupported options"
+msgstr "Tùy chọn không được hỗ trợ"
+
+#: src/xz/message.c:811
+msgid "Compressed data is corrupt"
+msgstr "Dữ liệu đã nén bị hỏng"
+
+#: src/xz/message.c:814
+msgid "Unexpected end of input"
+msgstr "Gặp kết thúc đầu vào bất ngờ"
+
+#: src/xz/message.c:847
+#, c-format
+msgid "%s MiB of memory is required. The limiter is disabled."
+msgstr "Yêu cầu cần có %s MiB bộ nhớ. Nhưng giới hạn bị tắt."
+
+#: src/xz/message.c:875
+#, c-format
+msgid "%s MiB of memory is required. The limit is %s."
+msgstr "Yêu cầu cần có %s MiB bộ nhớ. Nhưng giới hạn là %s."
+
+#: src/xz/message.c:1042
+#, c-format
+msgid "%s: Filter chain: %s\n"
+msgstr "%s: Móc xích lọc: %s\n"
+
+#: src/xz/message.c:1052
+#, c-format
+msgid "Try `%s --help' for more information."
+msgstr "Hãy chạy lệnh “%s --help” để xem thông tin thêm."
+
+#: src/xz/message.c:1078
+#, c-format
+msgid ""
+"Usage: %s [OPTION]... [FILE]...\n"
+"Compress or decompress FILEs in the .xz format.\n"
+"\n"
+msgstr ""
+"Cách dùng: %s [TÙY CHỌN]... [TẬP TIN]...\n"
+"Nén hoặc giải nén các TẬP TIN có định dạng .xz.\n"
+"\n"
+
+#: src/xz/message.c:1085
+msgid ""
+"Mandatory arguments to long options are mandatory for short options too.\n"
+msgstr ""
+"Các tùy chọn dài bắt buộc phải có đối số thì với tùy chọn ngắn cũng vậy.\n"
+
+#: src/xz/message.c:1089
+msgid " Operation mode:\n"
+msgstr " Chế độ thao tác:\n"
+
+#: src/xz/message.c:1092
+msgid ""
+"  -z, --compress      force compression\n"
+"  -d, --decompress    force decompression\n"
+"  -t, --test          test compressed file integrity\n"
+"  -l, --list          list information about .xz files"
+msgstr ""
+"  -z, --compress      ép buộc nén\n"
+"  -d, --decompress    ép buộc giải nén\n"
+"  -t, --test          kiểm tra tính toàn vẹn của tập tin nén\n"
+"  -l, --list          liệt kê các thông tin về tập tin .xz"
+
+#: src/xz/message.c:1098
+msgid ""
+"\n"
+" Operation modifiers:\n"
+msgstr ""
+"\n"
+" Bộ chỉnh sửa thao tác:\n"
+
+#: src/xz/message.c:1101
+msgid ""
+"  -k, --keep          keep (don't delete) input files\n"
+"  -f, --force         force overwrite of output file and (de)compress links\n"
+"  -c, --stdout        write to standard output and don't delete input files"
+msgstr ""
+"  -k, --keep          giữ lại (đừng xóa) tập tin đầu vào\n"
+"  -f, --force         buộc ghi đè tập tin đầu ra và (giải) nén các liên kết\n"
+"  -c, --stdout        ghi ra đầu ra tiêu chuẩn và không xóa tập tin đầu vào"
+
+#: src/xz/message.c:1107
+msgid ""
+"      --single-stream decompress only the first stream, and silently\n"
+"                      ignore possible remaining input data"
+msgstr ""
+"      --single-stream chỉ giải nén luồng dữ liệu đầu, và bỏ qua\n"
+"                      dữ liệu đầu vào còn lại có thể"
+
+#: src/xz/message.c:1110
+msgid ""
+"      --no-sparse     do not create sparse files when decompressing\n"
+"  -S, --suffix=.SUF   use the suffix `.SUF' on compressed files\n"
+"      --files[=FILE]  read filenames to process from FILE; if FILE is\n"
+"                      omitted, filenames are read from the standard input;\n"
+"                      filenames must be terminated with the newline "
+"character\n"
+"      --files0[=FILE] like --files but use the null character as terminator"
+msgstr ""
+"      --no-sparse     đừng tạo các tập tin rải rác khi giải nén\n"
+"  -S, --suffix=.ĐUÔI  dùng hậu tố “.ĐUÔI” trên các tập tin nén\n"
+"      --files[=TẬP-TIN]  đọc các tập tin cần xử lý từ TẬP-TIN; nếu không có\n"
+"                      TẬP-TIN thì tên tập tin sẽ được đọc vào từ đầu vào "
+"tiêu\n"
+"                      chuẩn; chúng phải được kết thúc bằng ký tự dòng mới\n"
+"      --files0[=TẬP-TIN] giống --files nhưng ký tự kết thúc là null"
+
+#: src/xz/message.c:1119
+msgid ""
+"\n"
+" Basic file format and compression options:\n"
+msgstr ""
+"\n"
+" Các tùy chọn về định dạng và nén cơ bản:\n"
+
+#: src/xz/message.c:1121
+msgid ""
+"  -F, --format=FMT    file format to encode or decode; possible values are\n"
+"                      `auto' (default), `xz', `lzma', and `raw'\n"
+"  -C, --check=CHECK   integrity check type: `none' (use with caution),\n"
+"                      `crc32', `crc64' (default), or `sha256'"
+msgstr ""
+"  -F, --format=ĐDạng  định dạng tập tin cần mã hóa hoặc giải mã; giá trị có "
+"thể\n"
+"                      là “auto” (mặc định), “xz”, “lzma”, và “raw”\n"
+"  -C, --check=KIỂM    kiểu kiểm tra toàn vẹn: “none” (thận trọng khi dùng),\n"
+"                      “crc32”, “crc64” (mặc định), hay “sha256”"
+
+#: src/xz/message.c:1126
+msgid ""
+"      --ignore-check  don't verify the integrity check when decompressing"
+msgstr "      --ignore-check  không thẩm tra tính toàn vẹn khi giải nén"
+
+#: src/xz/message.c:1130
+msgid ""
+"  -0 ... -9           compression preset; default is 6; take compressor "
+"*and*\n"
+"                      decompressor memory usage into account before using "
+"7-9!"
+msgstr ""
+"  -0 ... -9           đặt mức nén; mặc định là 6; tiêu dùng nhiều bộ nhớ khi "
+"nén\n"
+"                      và giải nén, nên tính toán trước khi dùng 7-9!"
+
+#: src/xz/message.c:1134
+msgid ""
+"  -e, --extreme       try to improve compression ratio by using more CPU "
+"time;\n"
+"                      does not affect decompressor memory requirements"
+msgstr ""
+"  -e, --extreme       cố gắng nâng cao mức nén bằng cách dùng nhiều CPU "
+"hơn;\n"
+"                      nhưng không yêu cần nhiều bộ nhớ khi giải nén"
+
+#: src/xz/message.c:1138
+msgid ""
+"  -T, --threads=NUM   use at most NUM threads; the default is 1; set to 0\n"
+"                      to use as many threads as there are processor cores"
+msgstr ""
+"  -T, --threads=SỐ    dùng tối đa là SỐ tuyến trình; mặc định là 1; đặt\n"
+"                      thành 0 để dùng số lượng bằng số lõi vi xử lý"
+
+#: src/xz/message.c:1143
+msgid ""
+"      --block-size=SIZE\n"
+"                      start a new .xz block after every SIZE bytes of "
+"input;\n"
+"                      use this to set the block size for threaded compression"
+msgstr ""
+"      --block-size=CỠ\n"
+"                      bắt đầu một khối .xz mới sau mỗi CỠ byte của đầu vào;\n"
+"                      dùng tùy chọn này để đặt cỡ khối cho nén tuyến trình"
+
+#: src/xz/message.c:1147
+msgid ""
+"      --block-list=SIZES\n"
+"                      start a new .xz block after the given comma-separated\n"
+"                      intervals of uncompressed data"
+msgstr ""
+"      --block-list=CỠ\n"
+"                      bắt đầu một khối .xz mới sau một danh sách ngăn\n"
+"                      cách bằng dấu phẩy nhịp dữ của dữ liệu chưa nén"
+
+#: src/xz/message.c:1151
+msgid ""
+"      --flush-timeout=TIMEOUT\n"
+"                      when compressing, if more than TIMEOUT milliseconds "
+"has\n"
+"                      passed since the previous flush and reading more "
+"input\n"
+"                      would block, all pending data is flushed out"
+msgstr ""
+"      --flush-timeout=THỜI_GIAN_CHỜ\n"
+"                      khi đang nén, nếu đã trải qua hơn THỜI_GIAN_CHỜ milli-"
+"giây\n"
+"                      kể từ lần đẩy dữ liệu lên đĩa trước đó và đang đọc "
+"thêm\n"
+"                      khối nữa, mọi dữ liệu đang chờ sẽ được ghi lên đĩa"
+
+#: src/xz/message.c:1157
+#, no-c-format
+msgid ""
+"      --memlimit-compress=LIMIT\n"
+"      --memlimit-decompress=LIMIT\n"
+"  -M, --memlimit=LIMIT\n"
+"                      set memory usage limit for compression, "
+"decompression,\n"
+"                      or both; LIMIT is in bytes, % of RAM, or 0 for defaults"
+msgstr ""
+"      --memlimit-compress=GIỚI_HẠN\n"
+"      --memlimit-decompress=GIỚI_HẠN\n"
+"  -M, --memlimit=GIỚI_HẠN\n"
+"                      đặt mức giới hạn dùng bộ nhớ cho việc nén, giải nén,\n"
+"                      hoặc cả hai; GIỚI_HẠN có đơn vị là byte, % của RAM,\n"
+"                      hay 0 cho mặc định"
+
+#: src/xz/message.c:1164
+msgid ""
+"      --no-adjust     if compression settings exceed the memory usage "
+"limit,\n"
+"                      give an error instead of adjusting the settings "
+"downwards"
+msgstr ""
+"      --no-adjust     nếu các cài đặt nén vượt quá giới hạn dùng bộ nhớ,\n"
+"                      đưa ra một lỗi thay vì sửa đổi các cài đặt xuống"
+
+#: src/xz/message.c:1170
+msgid ""
+"\n"
+" Custom filter chain for compression (alternative for using presets):"
+msgstr ""
+"\n"
+" Móc xích lọc tùy chỉnh cho nén (thay cho việc dùng chỉnh trước):"
+
+#: src/xz/message.c:1179
+msgid ""
+"\n"
+"  --lzma1[=OPTS]      LZMA1 or LZMA2; OPTS is a comma-separated list of zero "
+"or\n"
+"  --lzma2[=OPTS]      more of the following options (valid values; "
+"default):\n"
+"                        preset=PRE reset options to a preset (0-9[e])\n"
+"                        dict=NUM   dictionary size (4KiB - 1536MiB; 8MiB)\n"
+"                        lc=NUM     number of literal context bits (0-4; 3)\n"
+"                        lp=NUM     number of literal position bits (0-4; 0)\n"
+"                        pb=NUM     number of position bits (0-4; 2)\n"
+"                        mode=MODE  compression mode (fast, normal; normal)\n"
+"                        nice=NUM   nice length of a match (2-273; 64)\n"
+"                        mf=NAME    match finder (hc3, hc4, bt2, bt3, bt4; "
+"bt4)\n"
+"                        depth=NUM  maximum search depth; 0=automatic "
+"(default)"
+msgstr ""
+"\n"
+"  --lzma1[=CTC]       LZMA1 hay LZMA2; CÁC-TÙY-CHỌN là danh sách của không "
+"hoặc\n"
+"  --lzma2[=CTC]       hơn các tùy chọn sau đây (giá trị hợp lệ; mặc định):\n"
+"                        preset=PRE các tùy chọn tối ưu nén (0-9[e])\n"
+"                        dict=SỐ    cỡ từ điển (4KiB - 1536MiB; 8MiB)\n"
+"                        lc=SỐ      số bít ngữ cảnh văn bản (0-4; 3)\n"
+"                        lp=SỐ      số bít vị trí văn bản (0-4; 0)\n"
+"                        pb=SỐ      số bít vị trí (0-4; 2)\n"
+"                        mode=CHẾ_ĐỘ  chế độ nén (fast, normal; normal)\n"
+"                        nice=SỐ    chiều dài “tốt” của khớp (2-273; 64)\n"
+"                        mf=TÊN     bộ tìm khớp (hc3, hc4, bt2, bt3, bt4; "
+"bt4)\n"
+"                        depth=SỐ   mức sâu tìm kiếm tối đa; 0=tự động (mặc "
+"định)"
+
+#: src/xz/message.c:1194
+msgid ""
+"\n"
+"  --x86[=OPTS]        x86 BCJ filter (32-bit and 64-bit)\n"
+"  --powerpc[=OPTS]    PowerPC BCJ filter (big endian only)\n"
+"  --ia64[=OPTS]       IA-64 (Itanium) BCJ filter\n"
+"  --arm[=OPTS]        ARM BCJ filter (little endian only)\n"
+"  --armthumb[=OPTS]   ARM-Thumb BCJ filter (little endian only)\n"
+"  --sparc[=OPTS]      SPARC BCJ filter\n"
+"                      Valid OPTS for all BCJ filters:\n"
+"                        start=NUM  start offset for conversions (default=0)"
+msgstr ""
+"\n"
+"  --x86[=OPTS]        bộ lọc x86 BCJ (32-bit và 64-bit)\n"
+"  --powerpc[=OPTS]    bộ lọc PowerPC BCJ (chỉ big endian)\n"
+"  --ia64[=OPTS]       IA-64 (Itanium) BCJ\n"
+"  --arm[=OPTS]        bộ lọc ARM BCJ (chỉ little endian)\n"
+"  --armthumb[=OPTS]   bộ lọc ARM-Thumb BCJ (chỉ little endian)\n"
+"  --sparc[=OPTS]      bộ lọc SPARC BCJ\n"
+"                      các tùy chọn hợp lệ cho mọi bộ lọc BCJ:\n"
+"                        start=SỐ khoảng bù khởi đầu cho chuyển đổi (mặc "
+"định=0)"
+
+#: src/xz/message.c:1206
+msgid ""
+"\n"
+"  --delta[=OPTS]      Delta filter; valid OPTS (valid values; default):\n"
+"                        dist=NUM   distance between bytes being subtracted\n"
+"                                   from each other (1-256; 1)"
+msgstr ""
+"\n"
+"  --delta[=OPTS]      bộ lọc Delta;\n"
+"                      CÁC-TÙY-CHỌN hợp lệ (giá trị hợp lệ; mặc định):\n"
+"                        dist=SỐ    khoảng cách giữa các byte được trừ từ\n"
+"                                   những cái khác (1-256; 1)"
+
+#: src/xz/message.c:1214
+msgid ""
+"\n"
+" Other options:\n"
+msgstr ""
+"\n"
+" Tùy chọn khác:\n"
+
+#: src/xz/message.c:1217
+msgid ""
+"  -q, --quiet         suppress warnings; specify twice to suppress errors "
+"too\n"
+"  -v, --verbose       be verbose; specify twice for even more verbose"
+msgstr ""
+"  -q, --quiet         không xuất các cảnh báo;\n"
+"                      chỉ định hai lần nến bạn muốn chặn cả báo lỗi\n"
+"  -v, --verbose       thông báo chi tiết; dùng hai lần nếu muốn chi tiết hơn"
+
+#: src/xz/message.c:1222
+msgid "  -Q, --no-warn       make warnings not affect the exit status"
+msgstr ""
+"  -Q, --no-warn       làm cho các cảnh báo không ảnh hưởng đến trạng thái "
+"thoát"
+
+#: src/xz/message.c:1224
+msgid ""
+"      --robot         use machine-parsable messages (useful for scripts)"
+msgstr ""
+"      --robot         dùng các thông điệp máy có thể phân tích\n"
+"                      (hữu dụng với scripts)"
+
+#: src/xz/message.c:1227
+msgid ""
+"      --info-memory   display the total amount of RAM and the currently "
+"active\n"
+"                      memory usage limits, and exit"
+msgstr ""
+"      --info-memory   hiển thị tổng lượng RAM và mức giới hạn tiêu dùng\n"
+"                      bộ nhớ hiện tại, rồi thoát"
+
+#: src/xz/message.c:1230
+msgid ""
+"  -h, --help          display the short help (lists only the basic options)\n"
+"  -H, --long-help     display this long help and exit"
+msgstr ""
+"  -h, --help          hiển thị trợ giúp dạng ngắn gọn\n"
+"                      (chỉ liệt kê các tùy chọn cơ bản)\n"
+"  -H, --long-help     hiển thị trợ giúp đầy đủ rồi thoát"
+
+#: src/xz/message.c:1234
+msgid ""
+"  -h, --help          display this short help and exit\n"
+"  -H, --long-help     display the long help (lists also the advanced options)"
+msgstr ""
+"  -h, --help          hiển thị trợ giúp dạng ngắn gọn rồi thoát\n"
+"  -H, --long-help     hiển thị trợ giúp đầy đủ\n"
+"                      (liệt kê cả những tùy chọn cấp cao)"
+
+#: src/xz/message.c:1239
+msgid "  -V, --version       display the version number and exit"
+msgstr "  -V, --version       hiển thị số phiên bản và thoát"
+
+#: src/xz/message.c:1241
+msgid ""
+"\n"
+"With no FILE, or when FILE is -, read standard input.\n"
+msgstr ""
+"\n"
+"Không có TẬP_TIN, hoặc TẬP_TIN là “-”, thì đọc đầu vào tiêu chuẩn.\n"
+
+#. TRANSLATORS: This message indicates the bug reporting address
+#. for this package. Please add _another line_ saying
+#. "Report translation bugs to <...>\n" with the email or WWW
+#. address for translation bugs. Thanks.
+#: src/xz/message.c:1247
+#, c-format
+msgid "Report bugs to <%s> (in English or Finnish).\n"
+msgstr ""
+"Hãy báo cáo lỗi cho <%s> (bằng tiếng Anh hoặc Phần Lan).\n"
+"Thông báo lỗi dịch cho: <http://translationproject.org/team/vi.html>.\n"
+
+#: src/xz/message.c:1249
+#, c-format
+msgid "%s home page: <%s>\n"
+msgstr "Trang chủ %s: <%s>.\n"
+
+#: src/xz/message.c:1253
+msgid "THIS IS A DEVELOPMENT VERSION NOT INTENDED FOR PRODUCTION USE."
+msgstr "ĐÂY LÀ PHIÊN BẢN PHÁT TRIỂN VÀ NÓ KHÔNG PHÙ HỢP VỚI MỤC ĐÍCH SẢN XUẤT."
+
+#: src/xz/options.c:86
+#, c-format
+msgid "%s: Options must be `name=value' pairs separated with commas"
+msgstr ""
+"%s: Các tùy chọn phải là các cặp “name=value” ngăn cách nhau bằng dấu phẩy"
+
+#: src/xz/options.c:93
+#, c-format
+msgid "%s: Invalid option name"
+msgstr "%s: Tên tùy chọn không hợp lệ"
+
+#: src/xz/options.c:113
+#, c-format
+msgid "%s: Invalid option value"
+msgstr "%s: Giá trị của tùy chọn không hợp lệ"
+
+#: src/xz/options.c:247
+#, c-format
+msgid "Unsupported LZMA1/LZMA2 preset: %s"
+msgstr "Hiện nay chưa hỗ trợ LZMA1/LZMA2: %s"
+
+#: src/xz/options.c:355
+msgid "The sum of lc and lp must not exceed 4"
+msgstr "Tổng số lượng lc và lp không được vượt quá 4"
+
+#: src/xz/options.c:359
+#, c-format
+msgid "The selected match finder requires at least nice=%<PRIu32>"
+msgstr "Bộ tìm khớp đã chọn yêu cầu mức “tốt” ít nhất là nice=%<PRIu32>"
+
+#: src/xz/suffix.c:133 src/xz/suffix.c:258
+#, c-format
+msgid ""
+"%s: With --format=raw, --suffix=.SUF is required unless writing to stdout"
+msgstr ""
+"%s: Nếu --format=raw, --suffix=.SUF sẽ được yêu cầu trừ trường hợp ghi ra "
+"đầu ra tiêu chuẩn"
+
+#: src/xz/suffix.c:164
+#, c-format
+msgid "%s: Filename has an unknown suffix, skipping"
+msgstr "%s: Tên tập tin có phần hậu tố chưa biết nên bỏ qua"
+
+#: src/xz/suffix.c:185
+#, c-format
+msgid "%s: File already has `%s' suffix, skipping"
+msgstr "%s: Tập tin đã sẵn có hậu tố “%s” nên bỏ qua"
+
+#: src/xz/suffix.c:393
+#, c-format
+msgid "%s: Invalid filename suffix"
+msgstr "%s: Hậu tố tên tập tin không hợp lệ"
+
+#: src/xz/util.c:71
+#, c-format
+msgid "%s: Value is not a non-negative decimal integer"
+msgstr "%s: Giá trị không phải là số thập phân nguyên không âm"
+
+#: src/xz/util.c:113
+#, c-format
+msgid "%s: Invalid multiplier suffix"
+msgstr "%s: Hậu tố nhân tố không hợp lệ"
+
+#: src/xz/util.c:115
+msgid "Valid suffixes are `KiB' (2^10), `MiB' (2^20), and `GiB' (2^30)."
+msgstr "Các hậu tố hợp lệ là “KiB” (2^10), “MiB” (2^20), và “GiB” (2^30)."
+
+#: src/xz/util.c:132
+#, c-format
+msgid "Value of the option `%s' must be in the range [%<PRIu64>, %<PRIu64>]"
+msgstr "Giá trị cuả tùy chọn “%s” phải nằm trong vùng [%<PRIu64>, %<PRIu64>]"
+
+#: src/xz/util.c:257
+msgid "Empty filename, skipping"
+msgstr "Tên tập tin trống rỗng nên bỏ qua"
+
+#: src/xz/util.c:271
+msgid "Compressed data cannot be read from a terminal"
+msgstr "Dữ liệu đã nén không thể đọc từ thiết bị cuối"
+
+#: src/xz/util.c:284
+msgid "Compressed data cannot be written to a terminal"
+msgstr "Dữ liệu đã nén không thể ghi ra thiết bị cuối"
+
+#: src/common/tuklib_exit.c:39
+msgid "Writing to standard output failed"
+msgstr "Gặp lỗi khi ghi dữ liệu vào đầu ra tiêu chuẩn"
+
+#: src/common/tuklib_exit.c:42
+msgid "Unknown error"
+msgstr "Lỗi chưa biết"
+
+#~ msgid ""
+#~ "      --block-size=SIZE\n"
+#~ "                      when compressing to the .xz format, start a new "
+#~ "block\n"
+#~ "                      after every SIZE bytes of input; 0=disabled "
+#~ "(default)"
+#~ msgstr ""
+#~ "      --block-size=CỠ\n"
+#~ "                      khi nén thành định dạng .xz, bắt đầu khối mới\n"
+#~ "                      sau mỗi SỐ byte đầu vào; 0=tắt (mặc định)"
diff --git a/src/Makefile.am b/src/Makefile.am
index 9fb4caa..d199e85 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -19,4 +19,24 @@
 SUBDIRS += scripts
 endif
 
-EXTRA_DIST = common
+EXTRA_DIST = \
+	common/common_w32res.rc \
+	common/mythread.h \
+	common/sysdefs.h \
+	common/tuklib_common.h \
+	common/tuklib_config.h \
+	common/tuklib_cpucores.c \
+	common/tuklib_cpucores.h \
+	common/tuklib_exit.c \
+	common/tuklib_exit.h \
+	common/tuklib_gettext.h \
+	common/tuklib_integer.h \
+	common/tuklib_mbstr_fw.c \
+	common/tuklib_mbstr.h \
+	common/tuklib_mbstr_width.c \
+	common/tuklib_open_stdxxx.c \
+	common/tuklib_open_stdxxx.h \
+	common/tuklib_physmem.c \
+	common/tuklib_physmem.h \
+	common/tuklib_progname.c \
+	common/tuklib_progname.h
diff --git a/src/common/mythread.h b/src/common/mythread.h
index c538dea..be22654 100644
--- a/src/common/mythread.h
+++ b/src/common/mythread.h
@@ -15,8 +15,86 @@
 
 #include "sysdefs.h"
 
+// If any type of threading is enabled, #define MYTHREAD_ENABLED.
+#if defined(MYTHREAD_POSIX) || defined(MYTHREAD_WIN95) \
+		|| defined(MYTHREAD_VISTA)
+#	define MYTHREAD_ENABLED 1
+#endif
 
-#ifdef HAVE_PTHREAD
+
+#ifdef MYTHREAD_ENABLED
+
+////////////////////////////////////////
+// Shared between all threading types //
+////////////////////////////////////////
+
+// Locks a mutex for a duration of a block.
+//
+// Perform mythread_mutex_lock(&mutex) in the beginning of a block
+// and mythread_mutex_unlock(&mutex) at the end of the block. "break"
+// may be used to unlock the mutex and jump out of the block.
+// mythread_sync blocks may be nested.
+//
+// Example:
+//
+//     mythread_sync(mutex) {
+//         foo();
+//         if (some_error)
+//             break; // Skips bar()
+//         bar();
+//     }
+//
+// At least GCC optimizes the loops completely away so it doesn't slow
+// things down at all compared to plain mythread_mutex_lock(&mutex)
+// and mythread_mutex_unlock(&mutex) calls.
+//
+#define mythread_sync(mutex) mythread_sync_helper1(mutex, __LINE__)
+#define mythread_sync_helper1(mutex, line) mythread_sync_helper2(mutex, line)
+#define mythread_sync_helper2(mutex, line) \
+	for (unsigned int mythread_i_ ## line = 0; \
+			mythread_i_ ## line \
+				? (mythread_mutex_unlock(&(mutex)), 0) \
+				: (mythread_mutex_lock(&(mutex)), 1); \
+			mythread_i_ ## line = 1) \
+		for (unsigned int mythread_j_ ## line = 0; \
+				!mythread_j_ ## line; \
+				mythread_j_ ## line = 1)
+#endif
+
+
+#if !defined(MYTHREAD_ENABLED)
+
+//////////////////
+// No threading //
+//////////////////
+
+// Calls the given function once. This isn't thread safe.
+#define mythread_once(func) \
+do { \
+	static bool once_ = false; \
+	if (!once_) { \
+		func(); \
+		once_ = true; \
+	} \
+} while (0)
+
+
+#if !(defined(_WIN32) && !defined(__CYGWIN__))
+// Use sigprocmask() to set the signal mask in single-threaded programs.
+#include <signal.h>
+
+static inline void
+mythread_sigmask(int how, const sigset_t *restrict set,
+		sigset_t *restrict oset)
+{
+	int ret = sigprocmask(how, set, oset);
+	assert(ret == 0);
+	(void)ret;
+}
+#endif
+
+
+#elif defined(MYTHREAD_POSIX)
 
 ////////////////////
 // Using pthreads //
@@ -26,82 +104,117 @@
 #include <pthread.h>
 #include <signal.h>
 #include <time.h>
+#include <errno.h>
 
+#define MYTHREAD_RET_TYPE void *
+#define MYTHREAD_RET_VALUE NULL
 
-#ifdef __VMS
-// Do nothing on OpenVMS. It doesn't have pthread_sigmask().
-#define mythread_sigmask(how, set, oset) do { } while (0)
-#else
-/// \brief      Set the process signal mask
-///
-/// If threads are disabled, sigprocmask() is used instead
-/// of pthread_sigmask().
-#define mythread_sigmask(how, set, oset) \
-	pthread_sigmask(how, set, oset)
-#endif
-
-/// \brief      Call the given function once
-///
-/// If threads are disabled, a thread-unsafe version is used.
-#define mythread_once(func) \
-do { \
-	static pthread_once_t once_ = PTHREAD_ONCE_INIT; \
-	pthread_once(&once_, &func); \
-} while (0)
-
-
-/// \brief      Lock a mutex for a duration of a block
-///
-/// Perform pthread_mutex_lock(&mutex) in the beginning of a block
-/// and pthread_mutex_unlock(&mutex) at the end of the block. "break"
-/// may be used to unlock the mutex and jump out of the block.
-/// mythread_sync blocks may be nested.
-///
-/// Example:
-///
-///     mythread_sync(mutex) {
-///         foo();
-///         if (some_error)
-///             break; // Skips bar()
-///         bar();
-///     }
-///
-/// At least GCC optimizes the loops completely away so it doesn't slow
-/// things down at all compared to plain pthread_mutex_lock(&mutex)
-/// and pthread_mutex_unlock(&mutex) calls.
-///
-#define mythread_sync(mutex) mythread_sync_helper(mutex, __LINE__)
-#define mythread_sync_helper(mutex, line) \
-	for (unsigned int mythread_i_ ## line = 0; \
-			mythread_i_ ## line \
-				? (pthread_mutex_unlock(&(mutex)), 0) \
-				: (pthread_mutex_lock(&(mutex)), 1); \
-			mythread_i_ ## line = 1) \
-		for (unsigned int mythread_j_ ## line = 0; \
-				!mythread_j_ ## line; \
-				mythread_j_ ## line = 1)
-
+typedef pthread_t mythread;
+typedef pthread_mutex_t mythread_mutex;
 
 typedef struct {
-	/// Condition variable
 	pthread_cond_t cond;
-
 #ifdef HAVE_CLOCK_GETTIME
-	/// Clock ID (CLOCK_REALTIME or CLOCK_MONOTONIC) associated with
-	/// the condition variable
+	// Clock ID (CLOCK_REALTIME or CLOCK_MONOTONIC) associated with
+	// the condition variable.
 	clockid_t clk_id;
 #endif
-
 } mythread_cond;
 
+typedef struct timespec mythread_condtime;
 
-/// \brief      Initialize a condition variable to use CLOCK_MONOTONIC
-///
-/// Using CLOCK_MONOTONIC instead of the default CLOCK_REALTIME makes the
-/// timeout in pthread_cond_timedwait() work correctly also if system time
-/// is suddenly changed. Unfortunately CLOCK_MONOTONIC isn't available
-/// everywhere while the default CLOCK_REALTIME is, so the default is
-/// used if CLOCK_MONOTONIC isn't available.
+
+// Calls the given function once in a thread-safe way.
+#define mythread_once(func) \
+	do { \
+		static pthread_once_t once_ = PTHREAD_ONCE_INIT; \
+		pthread_once(&once_, &func); \
+	} while (0)
+
+
+// Use pthread_sigmask() to set the signal mask in multi-threaded programs.
+// Do nothing on OpenVMS since it lacks pthread_sigmask().
+static inline void
+mythread_sigmask(int how, const sigset_t *restrict set,
+		sigset_t *restrict oset)
+{
+#ifdef __VMS
+	(void)how;
+	(void)set;
+	(void)oset;
+#else
+	int ret = pthread_sigmask(how, set, oset);
+	assert(ret == 0);
+	(void)ret;
+#endif
+}
+
+
+// Creates a new thread with all signals blocked. Returns zero on success
+// and non-zero on error.
+static inline int
+mythread_create(mythread *thread, void *(*func)(void *arg), void *arg)
+{
+	sigset_t old;
+	sigset_t all;
+	sigfillset(&all);
+
+	mythread_sigmask(SIG_SETMASK, &all, &old);
+	const int ret = pthread_create(thread, NULL, func, arg);
+	mythread_sigmask(SIG_SETMASK, &old, NULL);
+
+	return ret;
+}
+
+// Joins a thread. Returns zero on success and non-zero on error.
+static inline int
+mythread_join(mythread thread)
+{
+	return pthread_join(thread, NULL);
+}
+
+
+// Initiatlizes a mutex. Returns zero on success and non-zero on error.
+static inline int
+mythread_mutex_init(mythread_mutex *mutex)
+{
+	return pthread_mutex_init(mutex, NULL);
+}
+
+static inline void
+mythread_mutex_destroy(mythread_mutex *mutex)
+{
+	int ret = pthread_mutex_destroy(mutex);
+	assert(ret == 0);
+	(void)ret;
+}
+
+static inline void
+mythread_mutex_lock(mythread_mutex *mutex)
+{
+	int ret = pthread_mutex_lock(mutex);
+	assert(ret == 0);
+	(void)ret;
+}
+
+static inline void
+mythread_mutex_unlock(mythread_mutex *mutex)
+{
+	int ret = pthread_mutex_unlock(mutex);
+	assert(ret == 0);
+	(void)ret;
+}
+
+
+// Initializes a condition variable.
+//
+// Using CLOCK_MONOTONIC instead of the default CLOCK_REALTIME makes the
+// timeout in pthread_cond_timedwait() work correctly also if system time
+// is suddenly changed. Unfortunately CLOCK_MONOTONIC isn't available
+// everywhere while the default CLOCK_REALTIME is, so the default is
+// used if CLOCK_MONOTONIC isn't available.
+//
+// If clock_gettime() isn't available at all, gettimeofday() will be used.
 static inline int
 mythread_cond_init(mythread_cond *mycond)
 {
@@ -130,6 +243,8 @@
 	}
 
 	// If anything above fails, fall back to the default CLOCK_REALTIME.
+	// POSIX requires that all implementations of clock_gettime() must
+	// support at least CLOCK_REALTIME.
 #	endif
 
 	mycond->clk_id = CLOCK_REALTIME;
@@ -138,89 +253,268 @@
 	return pthread_cond_init(&mycond->cond, NULL);
 }
 
-
-/// \brief      Convert relative time to absolute time for use with timed wait
-///
-/// The current time of the clock associated with the condition variable
-/// is added to the relative time in *ts.
 static inline void
-mythread_cond_abstime(const mythread_cond *mycond, struct timespec *ts)
+mythread_cond_destroy(mythread_cond *cond)
 {
+	int ret = pthread_cond_destroy(&cond->cond);
+	assert(ret == 0);
+	(void)ret;
+}
+
+static inline void
+mythread_cond_signal(mythread_cond *cond)
+{
+	int ret = pthread_cond_signal(&cond->cond);
+	assert(ret == 0);
+	(void)ret;
+}
+
+static inline void
+mythread_cond_wait(mythread_cond *cond, mythread_mutex *mutex)
+{
+	int ret = pthread_cond_wait(&cond->cond, mutex);
+	assert(ret == 0);
+	(void)ret;
+}
+
+// Waits on a condition or until a timeout expires. If the timeout expires,
+// non-zero is returned, otherwise zero is returned.
+static inline int
+mythread_cond_timedwait(mythread_cond *cond, mythread_mutex *mutex,
+		const mythread_condtime *condtime)
+{
+	int ret = pthread_cond_timedwait(&cond->cond, mutex, condtime);
+	assert(ret == 0 || ret == ETIMEDOUT);
+	return ret;
+}
+
+// Sets condtime to the absolute time that is timeout_ms milliseconds
+// in the future. The type of the clock to use is taken from cond.
+static inline void
+mythread_condtime_set(mythread_condtime *condtime, const mythread_cond *cond,
+		uint32_t timeout_ms)
+{
+	condtime->tv_sec = timeout_ms / 1000;
+	condtime->tv_nsec = (timeout_ms % 1000) * 1000000;
+
 #ifdef HAVE_CLOCK_GETTIME
 	struct timespec now;
-	clock_gettime(mycond->clk_id, &now);
+	int ret = clock_gettime(cond->clk_id, &now);
+	assert(ret == 0);
+	(void)ret;
 
-	ts->tv_sec += now.tv_sec;
-	ts->tv_nsec += now.tv_nsec;
+	condtime->tv_sec += now.tv_sec;
+	condtime->tv_nsec += now.tv_nsec;
 #else
-	(void)mycond;
+	(void)cond;
 
 	struct timeval now;
 	gettimeofday(&now, NULL);
 
-	ts->tv_sec += now.tv_sec;
-	ts->tv_nsec += now.tv_usec * 1000L;
+	condtime->tv_sec += now.tv_sec;
+	condtime->tv_nsec += now.tv_usec * 1000L;
 #endif
 
 	// tv_nsec must stay in the range [0, 999_999_999].
-	if (ts->tv_nsec >= 1000000000L) {
-		ts->tv_nsec -= 1000000000L;
-		++ts->tv_sec;
+	if (condtime->tv_nsec >= 1000000000L) {
+		condtime->tv_nsec -= 1000000000L;
+		++condtime->tv_sec;
 	}
-
-	return;
 }
 
 
-#define mythread_cond_wait(mycondptr, mutexptr) \
-	pthread_cond_wait(&(mycondptr)->cond, mutexptr)
+#elif defined(MYTHREAD_WIN95) || defined(MYTHREAD_VISTA)
 
-#define mythread_cond_timedwait(mycondptr, mutexptr, abstimeptr) \
-	pthread_cond_timedwait(&(mycondptr)->cond, mutexptr, abstimeptr)
+/////////////////////
+// Windows threads //
+/////////////////////
 
-#define mythread_cond_signal(mycondptr) \
-	pthread_cond_signal(&(mycondptr)->cond)
+#define WIN32_LEAN_AND_MEAN
+#ifdef MYTHREAD_VISTA
+#	undef _WIN32_WINNT
+#	define _WIN32_WINNT 0x0600
+#endif
+#include <windows.h>
+#include <process.h>
 
-#define mythread_cond_broadcast(mycondptr) \
-	pthread_cond_broadcast(&(mycondptr)->cond)
+#define MYTHREAD_RET_TYPE unsigned int __stdcall
+#define MYTHREAD_RET_VALUE 0
 
-#define mythread_cond_destroy(mycondptr) \
-	pthread_cond_destroy(&(mycondptr)->cond)
+typedef HANDLE mythread;
+typedef CRITICAL_SECTION mythread_mutex;
+
+#ifdef MYTHREAD_WIN95
+typedef HANDLE mythread_cond;
+#else
+typedef CONDITION_VARIABLE mythread_cond;
+#endif
+
+typedef struct {
+	// Tick count (milliseconds) in the beginning of the timeout.
+	// NOTE: This is 32 bits so it wraps around after 49.7 days.
+	// Multi-day timeouts may not work as expected.
+	DWORD start;
+
+	// Length of the timeout in milliseconds. The timeout expires
+	// when the current tick count minus "start" is equal or greater
+	// than "timeout".
+	DWORD timeout;
+} mythread_condtime;
 
 
-/// \brief      Create a thread with all signals blocked
+// mythread_once() is only available with Vista threads.
+#ifdef MYTHREAD_VISTA
+#define mythread_once(func) \
+	do { \
+		static INIT_ONCE once_ = INIT_ONCE_STATIC_INIT; \
+		BOOL pending_; \
+		if (!InitOnceBeginInitialize(&once_, 0, &pending_, NULL)) \
+			abort(); \
+		if (pending_) \
+			func(); \
+		if (!InitOnceComplete(&once, 0, NULL)) \
+			abort(); \
+	} while (0)
+#endif
+
+
+// mythread_sigmask() isn't available on Windows. Even a dummy version would
+// make no sense because the other POSIX signal functions are missing anyway.
+
+
 static inline int
-mythread_create(pthread_t *thread, void *(*func)(void *arg), void *arg)
+mythread_create(mythread *thread,
+		unsigned int (__stdcall *func)(void *arg), void *arg)
 {
-	sigset_t old;
-	sigset_t all;
-	sigfillset(&all);
+	uintptr_t ret = _beginthreadex(NULL, 0, func, arg, 0, NULL);
+	if (ret == 0)
+		return -1;
 
-	pthread_sigmask(SIG_SETMASK, &all, &old);
-	const int ret = pthread_create(thread, NULL, func, arg);
-	pthread_sigmask(SIG_SETMASK, &old, NULL);
+	*thread = (HANDLE)ret;
+	return 0;
+}
+
+static inline int
+mythread_join(mythread thread)
+{
+	int ret = 0;
+
+	if (WaitForSingleObject(thread, INFINITE) != WAIT_OBJECT_0)
+		ret = -1;
+
+	if (!CloseHandle(thread))
+		ret = -1;
 
 	return ret;
 }
 
+
+static inline int
+mythread_mutex_init(mythread_mutex *mutex)
+{
+	InitializeCriticalSection(mutex);
+	return 0;
+}
+
+static inline void
+mythread_mutex_destroy(mythread_mutex *mutex)
+{
+	DeleteCriticalSection(mutex);
+}
+
+static inline void
+mythread_mutex_lock(mythread_mutex *mutex)
+{
+	EnterCriticalSection(mutex);
+}
+
+static inline void
+mythread_mutex_unlock(mythread_mutex *mutex)
+{
+	LeaveCriticalSection(mutex);
+}
+
+
+static inline int
+mythread_cond_init(mythread_cond *cond)
+{
+#ifdef MYTHREAD_WIN95
+	*cond = CreateEvent(NULL, FALSE, FALSE, NULL);
+	return *cond == NULL ? -1 : 0;
 #else
+	InitializeConditionVariable(cond);
+	return 0;
+#endif
+}
 
-//////////////////
-// No threading //
-//////////////////
+static inline void
+mythread_cond_destroy(mythread_cond *cond)
+{
+#ifdef MYTHREAD_WIN95
+	CloseHandle(*cond);
+#else
+	(void)cond;
+#endif
+}
 
-#define mythread_sigmask(how, set, oset) \
-	sigprocmask(how, set, oset)
+static inline void
+mythread_cond_signal(mythread_cond *cond)
+{
+#ifdef MYTHREAD_WIN95
+	SetEvent(*cond);
+#else
+	WakeConditionVariable(cond);
+#endif
+}
 
+static inline void
+mythread_cond_wait(mythread_cond *cond, mythread_mutex *mutex)
+{
+#ifdef MYTHREAD_WIN95
+	LeaveCriticalSection(mutex);
+	WaitForSingleObject(*cond, INFINITE);
+	EnterCriticalSection(mutex);
+#else
+	BOOL ret = SleepConditionVariableCS(cond, mutex, INFINITE);
+	assert(ret);
+	(void)ret;
+#endif
+}
 
-#define mythread_once(func) \
-do { \
-	static bool once_ = false; \
-	if (!once_) { \
-		func(); \
-		once_ = true; \
-	} \
-} while (0)
+static inline int
+mythread_cond_timedwait(mythread_cond *cond, mythread_mutex *mutex,
+		const mythread_condtime *condtime)
+{
+#ifdef MYTHREAD_WIN95
+	LeaveCriticalSection(mutex);
+#endif
+
+	DWORD elapsed = GetTickCount() - condtime->start;
+	DWORD timeout = elapsed >= condtime->timeout
+			? 0 : condtime->timeout - elapsed;
+
+#ifdef MYTHREAD_WIN95
+	DWORD ret = WaitForSingleObject(*cond, timeout);
+	assert(ret == WAIT_OBJECT_0 || ret == WAIT_TIMEOUT);
+
+	EnterCriticalSection(mutex);
+
+	return ret == WAIT_TIMEOUT;
+#else
+	BOOL ret = SleepConditionVariableCS(cond, mutex, timeout);
+	assert(ret || GetLastError() == ERROR_TIMEOUT);
+	return !ret;
+#endif
+}
+
+static inline void
+mythread_condtime_set(mythread_condtime *condtime, const mythread_cond *cond,
+		uint32_t timeout)
+{
+	(void)cond;
+	condtime->start = GetTickCount();
+	condtime->timeout = timeout;
+}
 
 #endif
 
diff --git a/src/common/sysdefs.h b/src/common/sysdefs.h
index 5ea6bda..e056ca4 100644
--- a/src/common/sysdefs.h
+++ b/src/common/sysdefs.h
@@ -165,6 +165,16 @@
 #	include <memory.h>
 #endif
 
+// As of MSVC 2013, inline and restrict are supported with
+// non-standard keywords.
+#if defined(_WIN32) && defined(_MSC_VER)
+#	ifndef inline
+#		define inline __inline
+#	endif
+#	ifndef restrict
+#		define restrict __restrict
+#	endif
+#endif
 
 ////////////
 // Macros //
diff --git a/src/common/tuklib_cpucores.c b/src/common/tuklib_cpucores.c
index 1da13df..e235fd1 100644
--- a/src/common/tuklib_cpucores.c
+++ b/src/common/tuklib_cpucores.c
@@ -12,7 +12,18 @@
 
 #include "tuklib_cpucores.h"
 
-#if defined(TUKLIB_CPUCORES_SYSCTL)
+#if defined(_WIN32) || defined(__CYGWIN__)
+#	ifndef _WIN32_WINNT
+#		define _WIN32_WINNT 0x0500
+#	endif
+#	include <windows.h>
+
+// FreeBSD
+#elif defined(TUKLIB_CPUCORES_CPUSET)
+#	include <sys/param.h>
+#	include <sys/cpuset.h>
+
+#elif defined(TUKLIB_CPUCORES_SYSCTL)
 #	ifdef HAVE_SYS_PARAM_H
 #		include <sys/param.h>
 #	endif
@@ -33,7 +44,25 @@
 {
 	uint32_t ret = 0;
 
-#if defined(TUKLIB_CPUCORES_SYSCTL)
+#if defined(_WIN32) || defined(__CYGWIN__)
+	SYSTEM_INFO sysinfo;
+	GetSystemInfo(&sysinfo);
+	ret = sysinfo.dwNumberOfProcessors;
+
+#elif defined(TUKLIB_CPUCORES_CPUSET)
+	cpuset_t set;
+	if (cpuset_getaffinity(CPU_LEVEL_WHICH, CPU_WHICH_PID, -1,
+			sizeof(set), &set) == 0) {
+#	ifdef CPU_COUNT
+		ret = CPU_COUNT(&set);
+#	else
+		for (unsigned i = 0; i < CPU_SETSIZE; ++i)
+			if (CPU_ISSET(i, &set))
+				++ret;
+#	endif
+	}
+
+#elif defined(TUKLIB_CPUCORES_SYSCTL)
 	int name[2] = { CTL_HW, HW_NCPU };
 	int cpus;
 	size_t cpus_size = sizeof(cpus);
diff --git a/src/common/tuklib_integer.h b/src/common/tuklib_integer.h
index e6daa77..a7fda67 100644
--- a/src/common/tuklib_integer.h
+++ b/src/common/tuklib_integer.h
@@ -321,8 +321,8 @@
 static inline void
 unaligned_write16be(uint8_t *buf, uint16_t num)
 {
-	buf[0] = num >> 8;
-	buf[1] = num;
+	buf[0] = (uint8_t)(num >> 8);
+	buf[1] = (uint8_t)num;
 	return;
 }
 
@@ -330,8 +330,8 @@
 static inline void
 unaligned_write16le(uint8_t *buf, uint16_t num)
 {
-	buf[0] = num;
-	buf[1] = num >> 8;
+	buf[0] = (uint8_t)num;
+	buf[1] = (uint8_t)(num >> 8);
 	return;
 }
 
@@ -339,10 +339,10 @@
 static inline void
 unaligned_write32be(uint8_t *buf, uint32_t num)
 {
-	buf[0] = num >> 24;
-	buf[1] = num >> 16;
-	buf[2] = num >> 8;
-	buf[3] = num;
+	buf[0] = (uint8_t)(num >> 24);
+	buf[1] = (uint8_t)(num >> 16);
+	buf[2] = (uint8_t)(num >> 8);
+	buf[3] = (uint8_t)num;
 	return;
 }
 
@@ -350,10 +350,10 @@
 static inline void
 unaligned_write32le(uint8_t *buf, uint32_t num)
 {
-	buf[0] = num;
-	buf[1] = num >> 8;
-	buf[2] = num >> 16;
-	buf[3] = num >> 24;
+	buf[0] = (uint8_t)num;
+	buf[1] = (uint8_t)(num >> 8);
+	buf[2] = (uint8_t)(num >> 16);
+	buf[3] = (uint8_t)(num >> 24);
 	return;
 }
 
diff --git a/src/common/tuklib_physmem.c b/src/common/tuklib_physmem.c
index 623b6e7..cd2437d 100644
--- a/src/common/tuklib_physmem.c
+++ b/src/common/tuklib_physmem.c
@@ -33,7 +33,14 @@
 #	include <syidef.h>
 #	include <ssdef.h>
 
-// AIX
+#elif defined(AMIGA) || defined(__AROS__)
+#	define __USE_INLINE__
+#	include <proto/exec.h>
+
+#elif defined(__QNX__)
+#	include <sys/syspage.h>
+#	include <string.h>
+
 #elif defined(TUKLIB_PHYSMEM_AIX)
 #	include <sys/systemcfg.h>
 
@@ -119,6 +126,18 @@
 	if (LIB$GETSYI(&val, &vms_mem, 0, 0, 0, 0) == SS$_NORMAL)
 		ret = (uint64_t)vms_mem * 8192;
 
+#elif defined(AMIGA) || defined(__AROS__)
+	ret = AvailMem(MEMF_TOTAL);
+
+#elif defined(__QNX__)
+	const struct asinfo_entry *entries = SYSPAGE_ENTRY(asinfo);
+	size_t count = SYSPAGE_ENTRY_SIZE(asinfo) / sizeof(struct asinfo_entry);
+	const char *strings = SYSPAGE_ENTRY(strings)->data;
+
+	for (size_t i = 0; i < count; ++i)
+		if (strcmp(strings + entries[i].name, "ram") == 0)
+			ret += entries[i].end - entries[i].start + 1;
+
 #elif defined(TUKLIB_PHYSMEM_AIX)
 	ret = _system_configuration.physmem;
 
diff --git a/src/liblzma/Makefile.am b/src/liblzma/Makefile.am
index ac2d1ed..24d9c26 100644
--- a/src/liblzma/Makefile.am
+++ b/src/liblzma/Makefile.am
@@ -12,7 +12,7 @@
 doc_DATA =
 
 lib_LTLIBRARIES = liblzma.la
-liblzma_la_SOURCES = $(top_srcdir)/src/common/tuklib_physmem.c
+liblzma_la_SOURCES =
 liblzma_la_CPPFLAGS = \
 	-I$(top_srcdir)/src/liblzma/api \
 	-I$(top_srcdir)/src/liblzma/common \
@@ -24,14 +24,20 @@
 	-I$(top_srcdir)/src/liblzma/simple \
 	-I$(top_srcdir)/src/common \
 	-DTUKLIB_SYMBOL_PREFIX=lzma_
-liblzma_la_LDFLAGS = -no-undefined -version-info 5:0:0
+liblzma_la_LDFLAGS = -no-undefined -version-info 7:2:2
 
+EXTRA_DIST += liblzma.map validate_map.sh
 if COND_SYMVERS
-EXTRA_DIST += liblzma.map
 liblzma_la_LDFLAGS += \
 	-Wl,--version-script=$(top_srcdir)/src/liblzma/liblzma.map
 endif
 
+liblzma_la_SOURCES += ../common/tuklib_physmem.c
+
+if COND_THREADS
+liblzma_la_SOURCES += ../common/tuklib_cpucores.c
+endif
+
 include $(srcdir)/common/Makefile.inc
 include $(srcdir)/check/Makefile.inc
 
@@ -94,3 +100,23 @@
 pkgconfigdir = $(libdir)/pkgconfig
 pkgconfig_DATA = liblzma.pc
 EXTRA_DIST += liblzma.pc.in
+
+pc_verbose = $(pc_verbose_@AM_V@)
+pc_verbose_ = $(pc_verbose_@AM_DEFAULT_V@)
+pc_verbose_0 = @echo "  PC      " $@;
+
+liblzma.pc: $(srcdir)/liblzma.pc.in
+	$(AM_V_at)rm -f $@
+	$(pc_verbose)sed \
+		-e 's,@prefix[@],$(prefix),g' \
+		-e 's,@exec_prefix[@],$(exec_prefix),g' \
+		-e 's,@libdir[@],$(libdir),g' \
+		-e 's,@includedir[@],$(includedir),g' \
+		-e 's,@PACKAGE_URL[@],$(PACKAGE_URL),g' \
+		-e 's,@PACKAGE_VERSION[@],$(PACKAGE_VERSION),g' \
+		-e 's,@PTHREAD_CFLAGS[@],$(PTHREAD_CFLAGS),g' \
+		-e 's,@LIBS[@],$(LIBS),g' \
+		< $(srcdir)/liblzma.pc.in > $@ || { rm -f $@; exit 1; }
+
+clean-local:
+	rm -f liblzma.pc
diff --git a/src/liblzma/api/Makefile.am b/src/liblzma/api/Makefile.am
index e016de5..db24600 100644
--- a/src/liblzma/api/Makefile.am
+++ b/src/liblzma/api/Makefile.am
@@ -17,7 +17,7 @@
 	lzma/hardware.h \
 	lzma/index.h \
 	lzma/index_hash.h \
-	lzma/lzma.h \
+	lzma/lzma12.h \
 	lzma/stream_flags.h \
 	lzma/version.h \
 	lzma/vli.h
diff --git a/src/liblzma/api/lzma.h b/src/liblzma/api/lzma.h
index fb874c3..ce675a7 100644
--- a/src/liblzma/api/lzma.h
+++ b/src/liblzma/api/lzma.h
@@ -82,12 +82,20 @@
 #	if !defined(UINT32_C) || !defined(UINT64_C) \
 			|| !defined(UINT32_MAX) || !defined(UINT64_MAX)
 		/*
-		 * MSVC has no C99 support, and thus it cannot be used to
-		 * compile liblzma. The liblzma API has to still be usable
-		 * from MSVC, so we need to define the required standard
-		 * integer types here.
+		 * MSVC versions older than 2013 have no C99 support, and
+		 * thus they cannot be used to compile liblzma. Using an
+		 * existing liblzma.dll with old MSVC can work though(*),
+		 * but we need to define the required standard integer
+		 * types here in a MSVC-specific way.
+		 *
+		 * (*) If you do this, the existing liblzma.dll probably uses
+		 *     a different runtime library than your MSVC-built
+		 *     application. Mixing runtimes is generally bad, but
+		 *     in this case it should work as long as you avoid
+		 *     the few rarely-needed liblzma functions that allocate
+		 *     memory and expect the caller to free it using free().
 		 */
-#		if defined(_WIN32) && defined(_MSC_VER)
+#		if defined(_WIN32) && defined(_MSC_VER) && _MSC_VER < 1800
 			typedef unsigned __int8 uint8_t;
 			typedef unsigned __int32 uint32_t;
 			typedef unsigned __int64 uint64_t;
@@ -286,7 +294,7 @@
 #include "lzma/filter.h"
 #include "lzma/bcj.h"
 #include "lzma/delta.h"
-#include "lzma/lzma.h"
+#include "lzma/lzma12.h"
 
 /* Container formats */
 #include "lzma/container.h"
diff --git a/src/liblzma/api/lzma/base.h b/src/liblzma/api/lzma/base.h
index 0bad7bc..7a31a42 100644
--- a/src/liblzma/api/lzma/base.h
+++ b/src/liblzma/api/lzma/base.h
@@ -240,12 +240,12 @@
 /**
  * \brief       The `action' argument for lzma_code()
  *
- * After the first use of LZMA_SYNC_FLUSH, LZMA_FULL_FLUSH, or LZMA_FINISH,
- * the same `action' must is used until lzma_code() returns LZMA_STREAM_END.
- * Also, the amount of input (that is, strm->avail_in) must not be modified
- * by the application until lzma_code() returns LZMA_STREAM_END. Changing the
- * `action' or modifying the amount of input will make lzma_code() return
- * LZMA_PROG_ERROR.
+ * After the first use of LZMA_SYNC_FLUSH, LZMA_FULL_FLUSH, LZMA_FULL_BARRIER,
+ * or LZMA_FINISH, the same `action' must is used until lzma_code() returns
+ * LZMA_STREAM_END. Also, the amount of input (that is, strm->avail_in) must
+ * not be modified by the application until lzma_code() returns
+ * LZMA_STREAM_END. Changing the `action' or modifying the amount of input
+ * will make lzma_code() return LZMA_PROG_ERROR.
  */
 typedef enum {
 	LZMA_RUN = 0,
@@ -293,7 +293,7 @@
 		 *
 		 * All the input data going to the current Block must have
 		 * been given to the encoder (the last bytes can still be
-		 * pending in* next_in). Call lzma_code() with LZMA_FULL_FLUSH
+		 * pending in *next_in). Call lzma_code() with LZMA_FULL_FLUSH
 		 * until it returns LZMA_STREAM_END. Then continue normally
 		 * with LZMA_RUN or finish the Stream with LZMA_FINISH.
 		 *
@@ -302,6 +302,29 @@
 		 * no unfinished Block, no empty Block is created.
 		 */
 
+	LZMA_FULL_BARRIER = 4,
+		/**<
+		 * \brief       Finish encoding of the current Block
+		 *
+		 * This is like LZMA_FULL_FLUSH except that this doesn't
+		 * necessarily wait until all the input has been made
+		 * available via the output buffer. That is, lzma_code()
+		 * might return LZMA_STREAM_END as soon as all the input
+		 * has been consumed (avail_in == 0).
+		 *
+		 * LZMA_FULL_BARRIER is useful with a threaded encoder if
+		 * one wants to split the .xz Stream into Blocks at specific
+		 * offsets but doesn't care if the output isn't flushed
+		 * immediately. Using LZMA_FULL_BARRIER allows keeping
+		 * the threads busy while LZMA_FULL_FLUSH would make
+		 * lzma_code() wait until all the threads have finished
+		 * until more data could be passed to the encoder.
+		 *
+		 * With a lzma_stream initialized with the single-threaded
+		 * lzma_stream_encoder() or lzma_easy_encoder(),
+		 * LZMA_FULL_BARRIER is an alias for LZMA_FULL_FLUSH.
+		 */
+
 	LZMA_FINISH = 3
 		/**<
 		 * \brief       Finish the coding operation
@@ -456,7 +479,8 @@
  *
  * Application may modify the values of total_in and total_out as it wants.
  * They are updated by liblzma to match the amount of data read and
- * written, but aren't used for anything else.
+ * written but aren't used for anything else except as a possible return
+ * values from lzma_get_progress().
  */
 typedef struct {
 	const uint8_t *next_in; /**< Pointer to the next input byte. */
@@ -472,8 +496,10 @@
 	 *
 	 * In most cases this is NULL which makes liblzma use
 	 * the standard malloc() and free().
+	 *
+	 * \note        In 5.0.x this is not a const pointer.
 	 */
-	lzma_allocator *allocator;
+	const lzma_allocator *allocator;
 
 	/** Internal state is not visible to applications. */
 	lzma_internal *internal;
@@ -555,6 +581,25 @@
 
 
 /**
+ * \brief       Get progress information
+ *
+ * In single-threaded mode, applications can get progress information from
+ * strm->total_in and strm->total_out. In multi-threaded mode this is less
+ * useful because a significant amount of both input and output data gets
+ * buffered internally by liblzma. This makes total_in and total_out give
+ * misleading information and also makes the progress indicator updates
+ * non-smooth.
+ *
+ * This function gives realistic progress information also in multi-threaded
+ * mode by taking into account the progress made by each thread. In
+ * single-threaded mode *progress_in and *progress_out are set to
+ * strm->total_in and strm->total_out, respectively.
+ */
+extern LZMA_API(void) lzma_get_progress(lzma_stream *strm,
+		uint64_t *progress_in, uint64_t *progress_out) lzma_nothrow;
+
+
+/**
  * \brief       Get the memory usage of decoder filter chain
  *
  * This function is currently supported only when *strm has been initialized
diff --git a/src/liblzma/api/lzma/block.h b/src/liblzma/api/lzma/block.h
index 8a4bf23..7bdcfd7 100644
--- a/src/liblzma/api/lzma/block.h
+++ b/src/liblzma/api/lzma/block.h
@@ -31,11 +31,16 @@
 	/**
 	 * \brief       Block format version
 	 *
-	 * To prevent API and ABI breakages if new features are needed in
-	 * the Block field, a version number is used to indicate which
-	 * fields in this structure are in use. For now, version must always
-	 * be zero. With non-zero version, most Block related functions will
-	 * return LZMA_OPTIONS_ERROR.
+	 * To prevent API and ABI breakages when new features are needed,
+	 * a version number is used to indicate which fields in this
+	 * structure are in use:
+	 *   - liblzma >= 5.0.0: version = 0 is supported.
+	 *   - liblzma >= 5.1.4beta: Support for version = 1 was added,
+	 *     which adds the ignore_check field.
+	 *
+	 * If version is greater than one, most Block related functions
+	 * will return LZMA_OPTIONS_ERROR (lzma_block_header_decode() works
+	 * with any version value).
 	 *
 	 * Read by:
 	 *  - All functions that take pointer to lzma_block as argument,
@@ -233,7 +238,28 @@
 	lzma_reserved_enum reserved_enum2;
 	lzma_reserved_enum reserved_enum3;
 	lzma_reserved_enum reserved_enum4;
-	lzma_bool reserved_bool1;
+
+	/**
+	 * \brief       A flag to Block decoder to not verify the Check field
+	 *
+	 * This field is supported by liblzma >= 5.1.4beta if .version >= 1.
+	 *
+	 * If this is set to true, the integrity check won't be calculated
+	 * and verified. Unless you know what you are doing, you should
+	 * leave this to false. (A reason to set this to true is when the
+	 * file integrity is verified externally anyway and you want to
+	 * speed up the decompression, which matters mostly when using
+	 * SHA-256 as the integrity check.)
+	 *
+	 * If .version >= 1, read by:
+	 *   - lzma_block_decoder()
+	 *   - lzma_block_buffer_decode()
+	 *
+	 * Written by (.version is ignored):
+	 *   - lzma_block_header_decode() always sets this to false
+	 */
+	lzma_bool ignore_check;
+
 	lzma_bool reserved_bool2;
 	lzma_bool reserved_bool3;
 	lzma_bool reserved_bool4;
@@ -310,14 +336,21 @@
 /**
  * \brief       Decode Block Header
  *
- * block->version should be set to the highest value supported by the
- * application; currently the only possible version is zero. This function
- * will set version to the lowest value that still supports all the features
- * required by the Block Header.
+ * block->version should (usually) be set to the highest value supported
+ * by the application. If the application sets block->version to a value
+ * higher than supported by the current liblzma version, this function will
+ * downgrade block->version to the highest value supported by it. Thus one
+ * should check the value of block->version after calling this function if
+ * block->version was set to a non-zero value and the application doesn't
+ * otherwise know that the liblzma version being used is new enough to
+ * support the specified block->version.
  *
  * The size of the Block Header must have already been decoded with
  * lzma_block_header_size_decode() macro and stored to block->header_size.
  *
+ * The integrity check type from Stream Header must have been stored
+ * to block->check.
+ *
  * block->filters must have been allocated, but they don't need to be
  * initialized (possible existing filter options are not freed).
  *
@@ -341,7 +374,7 @@
  *                block->header_size is invalid or block->filters is NULL.
  */
 extern LZMA_API(lzma_ret) lzma_block_header_decode(lzma_block *block,
-		lzma_allocator *allocator, const uint8_t *in)
+		const lzma_allocator *allocator, const uint8_t *in)
 		lzma_nothrow lzma_attr_warn_unused_result;
 
 
@@ -490,7 +523,25 @@
  *              - LZMA_PROG_ERROR
  */
 extern LZMA_API(lzma_ret) lzma_block_buffer_encode(
-		lzma_block *block, lzma_allocator *allocator,
+		lzma_block *block, const lzma_allocator *allocator,
+		const uint8_t *in, size_t in_size,
+		uint8_t *out, size_t *out_pos, size_t out_size)
+		lzma_nothrow lzma_attr_warn_unused_result;
+
+
+/**
+ * \brief       Single-call uncompressed .xz Block encoder
+ *
+ * This is like lzma_block_buffer_encode() except this doesn't try to
+ * compress the data and instead encodes the data using LZMA2 uncompressed
+ * chunks. The required output buffer size can be determined with
+ * lzma_block_buffer_bound().
+ *
+ * Since the data won't be compressed, this function ignores block->filters.
+ * This function doesn't take lzma_allocator because this function doesn't
+ * allocate any memory from the heap.
+ */
+extern LZMA_API(lzma_ret) lzma_block_uncomp_encode(lzma_block *block,
 		const uint8_t *in, size_t in_size,
 		uint8_t *out, size_t *out_pos, size_t out_size)
 		lzma_nothrow lzma_attr_warn_unused_result;
@@ -524,7 +575,7 @@
  *              - LZMA_PROG_ERROR
  */
 extern LZMA_API(lzma_ret) lzma_block_buffer_decode(
-		lzma_block *block, lzma_allocator *allocator,
+		lzma_block *block, const lzma_allocator *allocator,
 		const uint8_t *in, size_t *in_pos, size_t in_size,
 		uint8_t *out, size_t *out_pos, size_t out_size)
 		lzma_nothrow;
diff --git a/src/liblzma/api/lzma/container.h b/src/liblzma/api/lzma/container.h
index 7a9ffc6..86991ad 100644
--- a/src/liblzma/api/lzma/container.h
+++ b/src/liblzma/api/lzma/container.h
@@ -61,6 +61,131 @@
 
 
 /**
+ * \brief       Multithreading options
+ */
+typedef struct {
+	/**
+	 * \brief       Flags
+	 *
+	 * Set this to zero if no flags are wanted.
+	 *
+	 * No flags are currently supported.
+	 */
+	uint32_t flags;
+
+	/**
+	 * \brief       Number of worker threads to use
+	 */
+	uint32_t threads;
+
+	/**
+	 * \brief       Maximum uncompressed size of a Block
+	 *
+	 * The encoder will start a new .xz Block every block_size bytes.
+	 * Using LZMA_FULL_FLUSH or LZMA_FULL_BARRIER with lzma_code()
+	 * the caller may tell liblzma to start a new Block earlier.
+	 *
+	 * With LZMA2, a recommended block size is 2-4 times the LZMA2
+	 * dictionary size. With very small dictionaries, it is recommended
+	 * to use at least 1 MiB block size for good compression ratio, even
+	 * if this is more than four times the dictionary size. Note that
+	 * these are only recommendations for typical use cases; feel free
+	 * to use other values. Just keep in mind that using a block size
+	 * less than the LZMA2 dictionary size is waste of RAM.
+	 *
+	 * Set this to 0 to let liblzma choose the block size depending
+	 * on the compression options. For LZMA2 it will be 3*dict_size
+	 * or 1 MiB, whichever is more.
+	 *
+	 * For each thread, about 3 * block_size bytes of memory will be
+	 * allocated. This may change in later liblzma versions. If so,
+	 * the memory usage will probably be reduced, not increased.
+	 */
+	uint64_t block_size;
+
+	/**
+	 * \brief       Timeout to allow lzma_code() to return early
+	 *
+	 * Multithreading can make liblzma to consume input and produce
+	 * output in a very bursty way: it may first read a lot of input
+	 * to fill internal buffers, then no input or output occurs for
+	 * a while.
+	 *
+	 * In single-threaded mode, lzma_code() won't return until it has
+	 * either consumed all the input or filled the output buffer. If
+	 * this is done in multithreaded mode, it may cause a call
+	 * lzma_code() to take even tens of seconds, which isn't acceptable
+	 * in all applications.
+	 *
+	 * To avoid very long blocking times in lzma_code(), a timeout
+	 * (in milliseconds) may be set here. If lzma_code() would block
+	 * longer than this number of milliseconds, it will return with
+	 * LZMA_OK. Reasonable values are 100 ms or more. The xz command
+	 * line tool uses 300 ms.
+	 *
+	 * If long blocking times are fine for you, set timeout to a special
+	 * value of 0, which will disable the timeout mechanism and will make
+	 * lzma_code() block until all the input is consumed or the output
+	 * buffer has been filled.
+	 *
+	 * \note        Even with a timeout, lzma_code() might sometimes take
+	 *              somewhat long time to return. No timing guarantees
+	 *              are made.
+	 */
+	uint32_t timeout;
+
+	/**
+	 * \brief       Compression preset (level and possible flags)
+	 *
+	 * The preset is set just like with lzma_easy_encoder().
+	 * The preset is ignored if filters below is non-NULL.
+	 */
+	uint32_t preset;
+
+	/**
+	 * \brief       Filter chain (alternative to a preset)
+	 *
+	 * If this is NULL, the preset above is used. Otherwise the preset
+	 * is ignored and the filter chain specified here is used.
+	 */
+	const lzma_filter *filters;
+
+	/**
+	 * \brief       Integrity check type
+	 *
+	 * See check.h for available checks. The xz command line tool
+	 * defaults to LZMA_CHECK_CRC64, which is a good choice if you
+	 * are unsure.
+	 */
+	lzma_check check;
+
+	/*
+	 * Reserved space to allow possible future extensions without
+	 * breaking the ABI. You should not touch these, because the names
+	 * of these variables may change. These are and will never be used
+	 * with the currently supported options, so it is safe to leave these
+	 * uninitialized.
+	 */
+	lzma_reserved_enum reserved_enum1;
+	lzma_reserved_enum reserved_enum2;
+	lzma_reserved_enum reserved_enum3;
+	uint32_t reserved_int1;
+	uint32_t reserved_int2;
+	uint32_t reserved_int3;
+	uint32_t reserved_int4;
+	uint64_t reserved_int5;
+	uint64_t reserved_int6;
+	uint64_t reserved_int7;
+	uint64_t reserved_int8;
+	void *reserved_ptr1;
+	void *reserved_ptr2;
+	void *reserved_ptr3;
+	void *reserved_ptr4;
+
+} lzma_mt;
+
+
+/**
  * \brief       Calculate approximate memory usage of easy encoder
  *
  * This function is a wrapper for lzma_raw_encoder_memusage().
@@ -165,7 +290,8 @@
  */
 extern LZMA_API(lzma_ret) lzma_easy_buffer_encode(
 		uint32_t preset, lzma_check check,
-		lzma_allocator *allocator, const uint8_t *in, size_t in_size,
+		const lzma_allocator *allocator,
+		const uint8_t *in, size_t in_size,
 		uint8_t *out, size_t *out_pos, size_t out_size) lzma_nothrow;
 
 
@@ -191,6 +317,49 @@
 
 
 /**
+ * \brief       Calculate approximate memory usage of multithreaded .xz encoder
+ *
+ * Since doing the encoding in threaded mode doesn't affect the memory
+ * requirements of single-threaded decompressor, you can use
+ * lzma_easy_decoder_memusage(options->preset) or
+ * lzma_raw_decoder_memusage(options->filters) to calculate
+ * the decompressor memory requirements.
+ *
+ * \param       options Compression options
+ *
+ * \return      Number of bytes of memory required for encoding with the
+ *              given options. If an error occurs, for example due to
+ *              unsupported preset or filter chain, UINT64_MAX is returned.
+ */
+extern LZMA_API(uint64_t) lzma_stream_encoder_mt_memusage(
+		const lzma_mt *options) lzma_nothrow lzma_attr_pure;
+
+
+/**
+ * \brief       Initialize multithreaded .xz Stream encoder
+ *
+ * This provides the functionality of lzma_easy_encoder() and
+ * lzma_stream_encoder() as a single function for multithreaded use.
+ *
+ * The supported actions for lzma_code() are LZMA_RUN, LZMA_FULL_FLUSH,
+ * LZMA_FULL_BARRIER, and LZMA_FINISH. Support for LZMA_SYNC_FLUSH might be
+ * added in the future.
+ *
+ * \param       strm    Pointer to properly prepared lzma_stream
+ * \param       options Pointer to multithreaded compression options
+ *
+ * \return      - LZMA_OK
+ *              - LZMA_MEM_ERROR
+ *              - LZMA_UNSUPPORTED_CHECK
+ *              - LZMA_OPTIONS_ERROR
+ *              - LZMA_PROG_ERROR
+ */
+extern LZMA_API(lzma_ret) lzma_stream_encoder_mt(
+		lzma_stream *strm, const lzma_mt *options)
+		lzma_nothrow lzma_attr_warn_unused_result;
+
+
+/**
  * \brief       Initialize .lzma encoder (legacy file format)
  *
  * The .lzma format is sometimes called the LZMA_Alone format, which is the
@@ -269,7 +438,8 @@
  */
 extern LZMA_API(lzma_ret) lzma_stream_buffer_encode(
 		lzma_filter *filters, lzma_check check,
-		lzma_allocator *allocator, const uint8_t *in, size_t in_size,
+		const lzma_allocator *allocator,
+		const uint8_t *in, size_t in_size,
 		uint8_t *out, size_t *out_pos, size_t out_size)
 		lzma_nothrow lzma_attr_warn_unused_result;
 
@@ -305,6 +475,30 @@
 
 
 /**
+ * This flag makes lzma_code() not calculate and verify the integrity check
+ * of the compressed data in .xz files. This means that invalid integrity
+ * check values won't be detected and LZMA_DATA_ERROR won't be returned in
+ * such cases.
+ *
+ * This flag only affects the checks of the compressed data itself; the CRC32
+ * values in the .xz headers will still be verified normally.
+ *
+ * Don't use this flag unless you know what you are doing. Possible reasons
+ * to use this flag:
+ *
+ *   - Trying to recover data from a corrupt .xz file.
+ *
+ *   - Speeding up decompression, which matters mostly with SHA-256
+ *     or with files that have compressed extremely well. It's recommended
+ *     to not use this flag for this purpose unless the file integrity is
+ *     verified externally in some other way.
+ *
+ * Support for this flag was added in liblzma 5.1.4beta.
+ */
+#define LZMA_IGNORE_CHECK               UINT32_C(0x10)
+
+
+/**
  * This flag enables decoding of concatenated files with file formats that
  * allow concatenating compressed files as is. From the formats currently
  * supported by liblzma, only the .xz format allows concatenated files.
@@ -418,7 +612,8 @@
  *              - LZMA_PROG_ERROR
  */
 extern LZMA_API(lzma_ret) lzma_stream_buffer_decode(
-		uint64_t *memlimit, uint32_t flags, lzma_allocator *allocator,
+		uint64_t *memlimit, uint32_t flags,
+		const lzma_allocator *allocator,
 		const uint8_t *in, size_t *in_pos, size_t in_size,
 		uint8_t *out, size_t *out_pos, size_t out_size)
 		lzma_nothrow lzma_attr_warn_unused_result;
diff --git a/src/liblzma/api/lzma/filter.h b/src/liblzma/api/lzma/filter.h
index e0bc163..4e78752 100644
--- a/src/liblzma/api/lzma/filter.h
+++ b/src/liblzma/api/lzma/filter.h
@@ -116,8 +116,9 @@
  *                is not NULL.
  *              - LZMA_PROG_ERROR: src or dest is NULL.
  */
-extern LZMA_API(lzma_ret) lzma_filters_copy(const lzma_filter *src,
-		lzma_filter *dest, lzma_allocator *allocator) lzma_nothrow;
+extern LZMA_API(lzma_ret) lzma_filters_copy(
+		const lzma_filter *src, lzma_filter *dest,
+		const lzma_allocator *allocator) lzma_nothrow;
 
 
 /**
@@ -256,7 +257,7 @@
  *              won't necessarily meet that bound.)
  */
 extern LZMA_API(lzma_ret) lzma_raw_buffer_encode(
-		const lzma_filter *filters, lzma_allocator *allocator,
+		const lzma_filter *filters, const lzma_allocator *allocator,
 		const uint8_t *in, size_t in_size, uint8_t *out,
 		size_t *out_pos, size_t out_size) lzma_nothrow;
 
@@ -280,7 +281,7 @@
  *                          which no data is written to is out[out_size].
  */
 extern LZMA_API(lzma_ret) lzma_raw_buffer_decode(
-		const lzma_filter *filters, lzma_allocator *allocator,
+		const lzma_filter *filters, const lzma_allocator *allocator,
 		const uint8_t *in, size_t *in_pos, size_t in_size,
 		uint8_t *out, size_t *out_pos, size_t out_size) lzma_nothrow;
 
@@ -356,7 +357,7 @@
  *              - LZMA_MEM_ERROR
  */
 extern LZMA_API(lzma_ret) lzma_properties_decode(
-		lzma_filter *filter, lzma_allocator *allocator,
+		lzma_filter *filter, const lzma_allocator *allocator,
 		const uint8_t *props, size_t props_size) lzma_nothrow;
 
 
@@ -419,6 +420,6 @@
  *              - LZMA_PROG_ERROR
  */
 extern LZMA_API(lzma_ret) lzma_filter_flags_decode(
-		lzma_filter *filter, lzma_allocator *allocator,
+		lzma_filter *filter, const lzma_allocator *allocator,
 		const uint8_t *in, size_t *in_pos, size_t in_size)
 		lzma_nothrow lzma_attr_warn_unused_result;
diff --git a/src/liblzma/api/lzma/hardware.h b/src/liblzma/api/lzma/hardware.h
index e7dd03c..5321d9a 100644
--- a/src/liblzma/api/lzma/hardware.h
+++ b/src/liblzma/api/lzma/hardware.h
@@ -48,3 +48,17 @@
  *              of RAM on the specific operating system.
  */
 extern LZMA_API(uint64_t) lzma_physmem(void) lzma_nothrow;
+
+
+/**
+ * \brief       Get the number of processor cores or threads
+ *
+ * This function may be useful when determining how many threads to use.
+ * If the hardware supports more than one thread per CPU core, the number
+ * of hardware threads is returned if that information is available.
+ *
+ * \brief       On success, the number of available CPU threads or cores is
+ *              returned. If this information isn't available or an error
+ *              occurs, zero is returned.
+ */
+extern LZMA_API(uint32_t) lzma_cputhreads(void) lzma_nothrow;
diff --git a/src/liblzma/api/lzma/index.h b/src/liblzma/api/lzma/index.h
index 16bacc2..dda60ec 100644
--- a/src/liblzma/api/lzma/index.h
+++ b/src/liblzma/api/lzma/index.h
@@ -303,7 +303,7 @@
  * \return      On success, a pointer to an empty initialized lzma_index is
  *              returned. If allocation fails, NULL is returned.
  */
-extern LZMA_API(lzma_index *) lzma_index_init(lzma_allocator *allocator)
+extern LZMA_API(lzma_index *) lzma_index_init(const lzma_allocator *allocator)
 		lzma_nothrow;
 
 
@@ -312,8 +312,8 @@
  *
  * If i is NULL, this does nothing.
  */
-extern LZMA_API(void) lzma_index_end(lzma_index *i, lzma_allocator *allocator)
-		lzma_nothrow;
+extern LZMA_API(void) lzma_index_end(
+		lzma_index *i, const lzma_allocator *allocator) lzma_nothrow;
 
 
 /**
@@ -341,7 +341,7 @@
  *              - LZMA_PROG_ERROR
  */
 extern LZMA_API(lzma_ret) lzma_index_append(
-		lzma_index *i, lzma_allocator *allocator,
+		lzma_index *i, const lzma_allocator *allocator,
 		lzma_vli unpadded_size, lzma_vli uncompressed_size)
 		lzma_nothrow lzma_attr_warn_unused_result;
 
@@ -564,8 +564,8 @@
  *              - LZMA_MEM_ERROR
  *              - LZMA_PROG_ERROR
  */
-extern LZMA_API(lzma_ret) lzma_index_cat(
-		lzma_index *dest, lzma_index *src, lzma_allocator *allocator)
+extern LZMA_API(lzma_ret) lzma_index_cat(lzma_index *dest, lzma_index *src,
+		const lzma_allocator *allocator)
 		lzma_nothrow lzma_attr_warn_unused_result;
 
 
@@ -575,7 +575,7 @@
  * \return      A copy of the lzma_index, or NULL if memory allocation failed.
  */
 extern LZMA_API(lzma_index *) lzma_index_dup(
-		const lzma_index *i, lzma_allocator *allocator)
+		const lzma_index *i, const lzma_allocator *allocator)
 		lzma_nothrow lzma_attr_warn_unused_result;
 
 
@@ -677,6 +677,6 @@
  *              - LZMA_PROG_ERROR
  */
 extern LZMA_API(lzma_ret) lzma_index_buffer_decode(lzma_index **i,
-		uint64_t *memlimit, lzma_allocator *allocator,
+		uint64_t *memlimit, const lzma_allocator *allocator,
 		const uint8_t *in, size_t *in_pos, size_t in_size)
 		lzma_nothrow;
diff --git a/src/liblzma/api/lzma/index_hash.h b/src/liblzma/api/lzma/index_hash.h
index fa2e048..9287f1d 100644
--- a/src/liblzma/api/lzma/index_hash.h
+++ b/src/liblzma/api/lzma/index_hash.h
@@ -37,7 +37,7 @@
  * pointer than the index_hash that was given as an argument.
  */
 extern LZMA_API(lzma_index_hash *) lzma_index_hash_init(
-		lzma_index_hash *index_hash, lzma_allocator *allocator)
+		lzma_index_hash *index_hash, const lzma_allocator *allocator)
 		lzma_nothrow lzma_attr_warn_unused_result;
 
 
@@ -45,7 +45,7 @@
  * \brief       Deallocate lzma_index_hash structure
  */
 extern LZMA_API(void) lzma_index_hash_end(
-		lzma_index_hash *index_hash, lzma_allocator *allocator)
+		lzma_index_hash *index_hash, const lzma_allocator *allocator)
 		lzma_nothrow;
 
 
diff --git a/src/liblzma/api/lzma/lzma.h b/src/liblzma/api/lzma/lzma12.h
similarity index 99%
rename from src/liblzma/api/lzma/lzma.h
rename to src/liblzma/api/lzma/lzma12.h
index 3f8e095..4e32fa3 100644
--- a/src/liblzma/api/lzma/lzma.h
+++ b/src/liblzma/api/lzma/lzma12.h
@@ -1,5 +1,5 @@
 /**
- * \file        lzma/lzma.h
+ * \file        lzma/lzma12.h
  * \brief       LZMA1 and LZMA2 filters
  */
 
diff --git a/src/liblzma/api/lzma/version.h b/src/liblzma/api/lzma/version.h
index a908ea2..8bdc7f0 100644
--- a/src/liblzma/api/lzma/version.h
+++ b/src/liblzma/api/lzma/version.h
@@ -21,9 +21,9 @@
  * Version number split into components
  */
 #define LZMA_VERSION_MAJOR 5
-#define LZMA_VERSION_MINOR 1
-#define LZMA_VERSION_PATCH 0
-#define LZMA_VERSION_STABILITY LZMA_VERSION_STABILITY_ALPHA
+#define LZMA_VERSION_MINOR 2
+#define LZMA_VERSION_PATCH 2
+#define LZMA_VERSION_STABILITY LZMA_VERSION_STABILITY_STABLE
 
 #ifndef LZMA_VERSION_COMMIT
 #	define LZMA_VERSION_COMMIT ""
diff --git a/src/liblzma/check/crc32_fast.c b/src/liblzma/check/crc32_fast.c
index 94da855..3de0263 100644
--- a/src/liblzma/check/crc32_fast.c
+++ b/src/liblzma/check/crc32_fast.c
@@ -20,7 +20,7 @@
 #include "crc_macros.h"
 
 
-// If you make any changes, do some bench marking! Seemingly unrelated
+// If you make any changes, do some benchmarking! Seemingly unrelated
 // changes can very easily ruin the performance (and very probably is
 // very compiler dependent).
 extern LZMA_API(uint32_t)
diff --git a/src/liblzma/check/sha256.c b/src/liblzma/check/sha256.c
index 074cd74..5eede5c 100644
--- a/src/liblzma/check/sha256.c
+++ b/src/liblzma/check/sha256.c
@@ -6,7 +6,6 @@
 /// \todo       Crypto++ has x86 ASM optimizations. They use SSE so if they
 ///             are imported to liblzma, SSE instructions need to be used
 ///             conditionally to keep the code working on older boxes.
-///             We could also support using some external libary for SHA-256.
 //
 //  This code is based on the code found from 7-Zip, which has a modified
 //  version of the SHA-256 found from Crypto++ <http://www.cryptopp.com/>.
@@ -24,20 +23,20 @@
 
 #include "check.h"
 
-// Avoid bogus warnings in transform().
-#if TUKLIB_GNUC_REQ(4, 2)
-#	pragma GCC diagnostic ignored "-Wuninitialized"
-#endif
+// Rotate a uint32_t. GCC can optimize this to a rotate instruction
+// at least on x86.
+static inline uint32_t
+rotr_32(uint32_t num, unsigned amount)
+{
+        return (num >> amount) | (num << (32 - amount));
+}
 
-// At least on x86, GCC is able to optimize this to a rotate instruction.
-#define rotr_32(num, amount) ((num) >> (amount) | (num) << (32 - (amount)))
-
-#define blk0(i) (W[i] = data[i])
+#define blk0(i) (W[i] = conv32be(data[i]))
 #define blk2(i) (W[i & 15] += s1(W[(i - 2) & 15]) + W[(i - 7) & 15] \
 		+ s0(W[(i - 15) & 15]))
 
 #define Ch(x, y, z) (z ^ (x & (y ^ z)))
-#define Maj(x, y, z) ((x & y) | (z & (x | y)))
+#define Maj(x, y, z) ((x & (y ^ z)) + (y & z))
 
 #define a(i) T[(0 - i) & 7]
 #define b(i) T[(1 - i) & 7]
@@ -48,16 +47,17 @@
 #define g(i) T[(6 - i) & 7]
 #define h(i) T[(7 - i) & 7]
 
-#define R(i) \
-	h(i) += S1(e(i)) + Ch(e(i), f(i), g(i)) + SHA256_K[i + j] \
-		+ (j ? blk2(i) : blk0(i)); \
+#define R(i, j, blk) \
+	h(i) += S1(e(i)) + Ch(e(i), f(i), g(i)) + SHA256_K[i + j] + blk; \
 	d(i) += h(i); \
 	h(i) += S0(a(i)) + Maj(a(i), b(i), c(i))
+#define R0(i) R(i, 0, blk0(i))
+#define R2(i) R(i, j, blk2(i))
 
-#define S0(x) (rotr_32(x, 2) ^ rotr_32(x, 13) ^ rotr_32(x, 22))
-#define S1(x) (rotr_32(x, 6) ^ rotr_32(x, 11) ^ rotr_32(x, 25))
-#define s0(x) (rotr_32(x, 7) ^ rotr_32(x, 18) ^ (x >> 3))
-#define s1(x) (rotr_32(x, 17) ^ rotr_32(x, 19) ^ (x >> 10))
+#define S0(x) rotr_32(x ^ rotr_32(x ^ rotr_32(x, 9), 11), 2)
+#define S1(x) rotr_32(x ^ rotr_32(x ^ rotr_32(x, 14), 5), 6)
+#define s0(x) (rotr_32(x ^ rotr_32(x, 11), 7) ^ (x >> 3))
+#define s1(x) (rotr_32(x ^ rotr_32(x, 2), 17) ^ (x >> 10))
 
 
 static const uint32_t SHA256_K[64] = {
@@ -81,7 +81,7 @@
 
 
 static void
-transform(uint32_t state[static 8], const uint32_t data[static 16])
+transform(uint32_t state[8], const uint32_t data[16])
 {
 	uint32_t W[16];
 	uint32_t T[8];
@@ -89,12 +89,18 @@
 	// Copy state[] to working vars.
 	memcpy(T, state, sizeof(T));
 
-	// 64 operations, partially loop unrolled
-	for (unsigned int j = 0; j < 64; j += 16) {
-		R( 0); R( 1); R( 2); R( 3);
-		R( 4); R( 5); R( 6); R( 7);
-		R( 8); R( 9); R(10); R(11);
-		R(12); R(13); R(14); R(15);
+	// The first 16 operations unrolled
+	R0( 0); R0( 1); R0( 2); R0( 3);
+	R0( 4); R0( 5); R0( 6); R0( 7);
+	R0( 8); R0( 9); R0(10); R0(11);
+	R0(12); R0(13); R0(14); R0(15);
+
+	// The remaining 48 operations partially unrolled
+	for (unsigned int j = 16; j < 64; j += 16) {
+		R2( 0); R2( 1); R2( 2); R2( 3);
+		R2( 4); R2( 5); R2( 6); R2( 7);
+		R2( 8); R2( 9); R2(10); R2(11);
+		R2(12); R2(13); R2(14); R2(15);
 	}
 
 	// Add the working vars back into state[].
@@ -112,18 +118,7 @@
 static void
 process(lzma_check_state *check)
 {
-#ifdef WORDS_BIGENDIAN
 	transform(check->state.sha256.state, check->buffer.u32);
-
-#else
-	uint32_t data[16];
-
-	for (size_t i = 0; i < 16; ++i)
-		data[i] = bswap32(check->buffer.u32[i]);
-
-	transform(check->state.sha256.state, data);
-#endif
-
 	return;
 }
 
diff --git a/src/liblzma/common/Makefile.inc b/src/liblzma/common/Makefile.inc
index 81d751e..38a6341 100644
--- a/src/liblzma/common/Makefile.inc
+++ b/src/liblzma/common/Makefile.inc
@@ -8,6 +8,7 @@
 liblzma_la_SOURCES += \
 	common/common.c \
 	common/common.h \
+	common/memcmplen.h \
 	common/block_util.c \
 	common/easy_preset.c \
 	common/easy_preset.h \
@@ -24,6 +25,7 @@
 liblzma_la_SOURCES += \
 	common/alone_encoder.c \
 	common/block_buffer_encoder.c \
+	common/block_buffer_encoder.h \
 	common/block_encoder.c \
 	common/block_encoder.h \
 	common/block_header_encoder.c \
@@ -40,6 +42,14 @@
 	common/stream_encoder.c \
 	common/stream_flags_encoder.c \
 	common/vli_encoder.c
+
+if COND_THREADS
+liblzma_la_SOURCES += \
+	common/hardware_cputhreads.c \
+	common/outqueue.c \
+	common/outqueue.h \
+	common/stream_encoder_mt.c
+endif
 endif
 
 if COND_MAIN_DECODER
diff --git a/src/liblzma/common/alone_decoder.c b/src/liblzma/common/alone_decoder.c
index 678c79e..c1360ca 100644
--- a/src/liblzma/common/alone_decoder.c
+++ b/src/liblzma/common/alone_decoder.c
@@ -26,6 +26,11 @@
 		SEQ_CODE,
 	} sequence;
 
+	/// If true, reject files that are unlikely to be .lzma files.
+	/// If false, more non-.lzma files get accepted and will give
+	/// LZMA_DATA_ERROR either immediately or after a few output bytes.
+	bool picky;
+
 	/// Position in the header fields
 	size_t pos;
 
@@ -46,7 +51,7 @@
 
 static lzma_ret
 alone_decode(lzma_coder *coder,
-		lzma_allocator *allocator lzma_attribute((__unused__)),
+		const lzma_allocator *allocator lzma_attribute((__unused__)),
 		const uint8_t *restrict in, size_t *restrict in_pos,
 		size_t in_size, uint8_t *restrict out,
 		size_t *restrict out_pos, size_t out_size,
@@ -68,13 +73,13 @@
 				|= (size_t)(in[*in_pos]) << (coder->pos * 8);
 
 		if (++coder->pos == 4) {
-			if (coder->options.dict_size != UINT32_MAX) {
+			if (coder->picky && coder->options.dict_size
+					!= UINT32_MAX) {
 				// A hack to ditch tons of false positives:
 				// We allow only dictionary sizes that are
 				// 2^n or 2^n + 2^(n-1). LZMA_Alone created
 				// only files with 2^n, but accepts any
-				// dictionary size. If someone complains, this
-				// will be reconsidered.
+				// dictionary size.
 				uint32_t d = coder->options.dict_size - 1;
 				d |= d >> 2;
 				d |= d >> 3;
@@ -103,9 +108,9 @@
 
 		// Another hack to ditch false positives: Assume that
 		// if the uncompressed size is known, it must be less
-		// than 256 GiB. Again, if someone complains, this
-		// will be reconsidered.
-		if (coder->uncompressed_size != LZMA_VLI_UNKNOWN
+		// than 256 GiB.
+		if (coder->picky
+				&& coder->uncompressed_size != LZMA_VLI_UNKNOWN
 				&& coder->uncompressed_size
 					>= (LZMA_VLI_C(1) << 38))
 			return LZMA_FORMAT_ERROR;
@@ -161,7 +166,7 @@
 
 
 static void
-alone_decoder_end(lzma_coder *coder, lzma_allocator *allocator)
+alone_decoder_end(lzma_coder *coder, const lzma_allocator *allocator)
 {
 	lzma_next_end(&coder->next, allocator);
 	lzma_free(coder, allocator);
@@ -188,8 +193,8 @@
 
 
 extern lzma_ret
-lzma_alone_decoder_init(lzma_next_coder *next, lzma_allocator *allocator,
-		uint64_t memlimit)
+lzma_alone_decoder_init(lzma_next_coder *next, const lzma_allocator *allocator,
+		uint64_t memlimit, bool picky)
 {
 	lzma_next_coder_init(&lzma_alone_decoder_init, next, allocator);
 
@@ -208,6 +213,7 @@
 	}
 
 	next->coder->sequence = SEQ_PROPERTIES;
+	next->coder->picky = picky;
 	next->coder->pos = 0;
 	next->coder->options.dict_size = 0;
 	next->coder->options.preset_dict = NULL;
@@ -223,7 +229,7 @@
 extern LZMA_API(lzma_ret)
 lzma_alone_decoder(lzma_stream *strm, uint64_t memlimit)
 {
-	lzma_next_strm_init(lzma_alone_decoder_init, strm, memlimit);
+	lzma_next_strm_init(lzma_alone_decoder_init, strm, memlimit, false);
 
 	strm->internal->supported_actions[LZMA_RUN] = true;
 	strm->internal->supported_actions[LZMA_FINISH] = true;
diff --git a/src/liblzma/common/alone_decoder.h b/src/liblzma/common/alone_decoder.h
index 70d0d2a..dfa031a 100644
--- a/src/liblzma/common/alone_decoder.h
+++ b/src/liblzma/common/alone_decoder.h
@@ -16,7 +16,8 @@
 #include "common.h"
 
 
-extern lzma_ret lzma_alone_decoder_init(lzma_next_coder *next,
-		lzma_allocator *allocator, uint64_t memlimit);
+extern lzma_ret lzma_alone_decoder_init(
+		lzma_next_coder *next, const lzma_allocator *allocator,
+		uint64_t memlimit, bool picky);
 
 #endif
diff --git a/src/liblzma/common/alone_encoder.c b/src/liblzma/common/alone_encoder.c
index eb1697e..a2bc9ee 100644
--- a/src/liblzma/common/alone_encoder.c
+++ b/src/liblzma/common/alone_encoder.c
@@ -32,7 +32,7 @@
 
 static lzma_ret
 alone_encode(lzma_coder *coder,
-		lzma_allocator *allocator lzma_attribute((__unused__)),
+		const lzma_allocator *allocator lzma_attribute((__unused__)),
 		const uint8_t *restrict in, size_t *restrict in_pos,
 		size_t in_size, uint8_t *restrict out,
 		size_t *restrict out_pos, size_t out_size,
@@ -65,7 +65,7 @@
 
 
 static void
-alone_encoder_end(lzma_coder *coder, lzma_allocator *allocator)
+alone_encoder_end(lzma_coder *coder, const lzma_allocator *allocator)
 {
 	lzma_next_end(&coder->next, allocator);
 	lzma_free(coder, allocator);
@@ -75,7 +75,7 @@
 
 // At least for now, this is not used by any internal function.
 static lzma_ret
-alone_encoder_init(lzma_next_coder *next, lzma_allocator *allocator,
+alone_encoder_init(lzma_next_coder *next, const lzma_allocator *allocator,
 		const lzma_options_lzma *options)
 {
 	lzma_next_coder_init(&alone_encoder_init, next, allocator);
@@ -137,7 +137,7 @@
 
 /*
 extern lzma_ret
-lzma_alone_encoder_init(lzma_next_coder *next, lzma_allocator *allocator,
+lzma_alone_encoder_init(lzma_next_coder *next, const lzma_allocator *allocator,
 		const lzma_options_alone *options)
 {
 	lzma_next_coder_init(&alone_encoder_init, next, allocator, options);
diff --git a/src/liblzma/common/auto_decoder.c b/src/liblzma/common/auto_decoder.c
index ae6c3e7..bf35507 100644
--- a/src/liblzma/common/auto_decoder.c
+++ b/src/liblzma/common/auto_decoder.c
@@ -30,7 +30,7 @@
 
 
 static lzma_ret
-auto_decode(lzma_coder *coder, lzma_allocator *allocator,
+auto_decode(lzma_coder *coder, const lzma_allocator *allocator,
 		const uint8_t *restrict in, size_t *restrict in_pos,
 		size_t in_size, uint8_t *restrict out,
 		size_t *restrict out_pos, size_t out_size, lzma_action action)
@@ -54,7 +54,7 @@
 					coder->memlimit, coder->flags));
 		} else {
 			return_if_error(lzma_alone_decoder_init(&coder->next,
-					allocator, coder->memlimit));
+					allocator, coder->memlimit, true));
 
 			// If the application wants to know about missing
 			// integrity check or about the check in general, we
@@ -100,7 +100,7 @@
 
 
 static void
-auto_decoder_end(lzma_coder *coder, lzma_allocator *allocator)
+auto_decoder_end(lzma_coder *coder, const lzma_allocator *allocator)
 {
 	lzma_next_end(&coder->next, allocator);
 	lzma_free(coder, allocator);
@@ -143,7 +143,7 @@
 
 
 static lzma_ret
-auto_decoder_init(lzma_next_coder *next, lzma_allocator *allocator,
+auto_decoder_init(lzma_next_coder *next, const lzma_allocator *allocator,
 		uint64_t memlimit, uint32_t flags)
 {
 	lzma_next_coder_init(&auto_decoder_init, next, allocator);
diff --git a/src/liblzma/common/block_buffer_decoder.c b/src/liblzma/common/block_buffer_decoder.c
index ff27a11..b0ded90 100644
--- a/src/liblzma/common/block_buffer_decoder.c
+++ b/src/liblzma/common/block_buffer_decoder.c
@@ -14,7 +14,7 @@
 
 
 extern LZMA_API(lzma_ret)
-lzma_block_buffer_decode(lzma_block *block, lzma_allocator *allocator,
+lzma_block_buffer_decode(lzma_block *block, const lzma_allocator *allocator,
 		const uint8_t *in, size_t *in_pos, size_t in_size,
 		uint8_t *out, size_t *out_pos, size_t out_size)
 {
diff --git a/src/liblzma/common/block_buffer_encoder.c b/src/liblzma/common/block_buffer_encoder.c
index 519c6a6..39e263a 100644
--- a/src/liblzma/common/block_buffer_encoder.c
+++ b/src/liblzma/common/block_buffer_encoder.c
@@ -10,6 +10,7 @@
 //
 ///////////////////////////////////////////////////////////////////////////////
 
+#include "block_buffer_encoder.h"
 #include "block_encoder.h"
 #include "filter_encoder.h"
 #include "lzma2_encoder.h"
@@ -28,8 +29,8 @@
 		+ LZMA_CHECK_SIZE_MAX + 3) & ~3)
 
 
-static lzma_vli
-lzma2_bound(lzma_vli uncompressed_size)
+static uint64_t
+lzma2_bound(uint64_t uncompressed_size)
 {
 	// Prevent integer overflow in overhead calculation.
 	if (uncompressed_size > COMPRESSED_SIZE_MAX)
@@ -39,7 +40,7 @@
 	// uncompressed_size up to the next multiple of LZMA2_CHUNK_MAX,
 	// multiply by the size of per-chunk header, and add one byte for
 	// the end marker.
-	const lzma_vli overhead = ((uncompressed_size + LZMA2_CHUNK_MAX - 1)
+	const uint64_t overhead = ((uncompressed_size + LZMA2_CHUNK_MAX - 1)
 				/ LZMA2_CHUNK_MAX)
 			* LZMA2_HEADER_UNCOMPRESSED + 1;
 
@@ -51,30 +52,36 @@
 }
 
 
-extern LZMA_API(size_t)
-lzma_block_buffer_bound(size_t uncompressed_size)
+extern uint64_t
+lzma_block_buffer_bound64(uint64_t uncompressed_size)
 {
-	// For now, if the data doesn't compress, we always use uncompressed
-	// chunks of LZMA2. In future we may use Subblock filter too, but
-	// but for simplicity we probably will still use the same bound
-	// calculation even though Subblock filter would have slightly less
-	// overhead.
-	lzma_vli lzma2_size = lzma2_bound(uncompressed_size);
+	// If the data doesn't compress, we always use uncompressed
+	// LZMA2 chunks.
+	uint64_t lzma2_size = lzma2_bound(uncompressed_size);
 	if (lzma2_size == 0)
 		return 0;
 
 	// Take Block Padding into account.
-	lzma2_size = (lzma2_size + 3) & ~LZMA_VLI_C(3);
+	lzma2_size = (lzma2_size + 3) & ~UINT64_C(3);
 
-#if SIZE_MAX < LZMA_VLI_MAX
-	// Catch the possible integer overflow on 32-bit systems. There's no
-	// overflow on 64-bit systems, because lzma2_bound() already takes
+	// No risk of integer overflow because lzma2_bound() already takes
 	// into account the size of the headers in the Block.
-	if (SIZE_MAX - HEADERS_BOUND < lzma2_size)
+	return HEADERS_BOUND + lzma2_size;
+}
+
+
+extern LZMA_API(size_t)
+lzma_block_buffer_bound(size_t uncompressed_size)
+{
+	uint64_t ret = lzma_block_buffer_bound64(uncompressed_size);
+
+#if SIZE_MAX < UINT64_MAX
+	// Catch the possible integer overflow on 32-bit systems.
+	if (ret > SIZE_MAX)
 		return 0;
 #endif
 
-	return HEADERS_BOUND + lzma2_size;
+	return ret;
 }
 
 
@@ -82,9 +89,6 @@
 block_encode_uncompressed(lzma_block *block, const uint8_t *in, size_t in_size,
 		uint8_t *out, size_t *out_pos, size_t out_size)
 {
-	// TODO: Figure out if the last filter is LZMA2 or Subblock and use
-	// that filter to encode the uncompressed chunks.
-
 	// Use LZMA2 uncompressed chunks. We wouldn't need a dictionary at
 	// all, but LZMA2 always requires a dictionary, so use the minimum
 	// value to minimize memory usage of the decoder.
@@ -160,16 +164,11 @@
 
 
 static lzma_ret
-block_encode_normal(lzma_block *block, lzma_allocator *allocator,
+block_encode_normal(lzma_block *block, const lzma_allocator *allocator,
 		const uint8_t *in, size_t in_size,
 		uint8_t *out, size_t *out_pos, size_t out_size)
 {
 	// Find out the size of the Block Header.
-	block->compressed_size = lzma2_bound(in_size);
-	if (block->compressed_size == 0)
-		return LZMA_DATA_ERROR;
-
-	block->uncompressed_size = in_size;
 	return_if_error(lzma_block_header_size(block));
 
 	// Reserve space for the Block Header and skip it for now.
@@ -221,10 +220,11 @@
 }
 
 
-extern LZMA_API(lzma_ret)
-lzma_block_buffer_encode(lzma_block *block, lzma_allocator *allocator,
+static lzma_ret
+block_buffer_encode(lzma_block *block, const lzma_allocator *allocator,
 		const uint8_t *in, size_t in_size,
-		uint8_t *out, size_t *out_pos, size_t out_size)
+		uint8_t *out, size_t *out_pos, size_t out_size,
+		bool try_to_compress)
 {
 	// Validate the arguments.
 	if (block == NULL || (in == NULL && in_size != 0) || out == NULL
@@ -233,11 +233,11 @@
 
 	// The contents of the structure may depend on the version so
 	// check the version before validating the contents of *block.
-	if (block->version != 0)
+	if (block->version > 1)
 		return LZMA_OPTIONS_ERROR;
 
 	if ((unsigned int)(block->check) > LZMA_CHECK_ID_MAX
-			|| block->filters == NULL)
+			|| (try_to_compress && block->filters == NULL))
 		return LZMA_PROG_ERROR;
 
 	if (!lzma_check_is_supported(block->check))
@@ -258,9 +258,19 @@
 
 	out_size -= check_size;
 
+	// Initialize block->uncompressed_size and calculate the worst-case
+	// value for block->compressed_size.
+	block->uncompressed_size = in_size;
+	block->compressed_size = lzma2_bound(in_size);
+	if (block->compressed_size == 0)
+		return LZMA_DATA_ERROR;
+
 	// Do the actual compression.
-	const lzma_ret ret = block_encode_normal(block, allocator,
-			in, in_size, out, out_pos, out_size);
+	lzma_ret ret = LZMA_BUF_ERROR;
+	if (try_to_compress)
+		ret = block_encode_normal(block, allocator,
+				in, in_size, out, out_pos, out_size);
+
 	if (ret != LZMA_OK) {
 		// If the error was something else than output buffer
 		// becoming full, return the error now.
@@ -303,3 +313,25 @@
 
 	return LZMA_OK;
 }
+
+
+extern LZMA_API(lzma_ret)
+lzma_block_buffer_encode(lzma_block *block, const lzma_allocator *allocator,
+		const uint8_t *in, size_t in_size,
+		uint8_t *out, size_t *out_pos, size_t out_size)
+{
+	return block_buffer_encode(block, allocator,
+			in, in_size, out, out_pos, out_size, true);
+}
+
+
+extern LZMA_API(lzma_ret)
+lzma_block_uncomp_encode(lzma_block *block,
+		const uint8_t *in, size_t in_size,
+		uint8_t *out, size_t *out_pos, size_t out_size)
+{
+	// It won't allocate any memory from heap so no need
+	// for lzma_allocator.
+	return block_buffer_encode(block, NULL,
+			in, in_size, out, out_pos, out_size, false);
+}
diff --git a/src/liblzma/common/block_buffer_encoder.h b/src/liblzma/common/block_buffer_encoder.h
new file mode 100644
index 0000000..653207f
--- /dev/null
+++ b/src/liblzma/common/block_buffer_encoder.h
@@ -0,0 +1,24 @@
+///////////////////////////////////////////////////////////////////////////////
+//
+/// \file       block_buffer_encoder.h
+/// \brief      Single-call .xz Block encoder
+//
+//  Author:     Lasse Collin
+//
+//  This file has been put into the public domain.
+//  You can do whatever you want with this file.
+//
+///////////////////////////////////////////////////////////////////////////////
+
+#ifndef LZMA_BLOCK_BUFFER_ENCODER_H
+#define LZMA_BLOCK_BUFFER_ENCODER_H
+
+#include "common.h"
+
+
+/// uint64_t version of lzma_block_buffer_bound(). It is used by
+/// stream_encoder_mt.c. Probably the original lzma_block_buffer_bound()
+/// should have been 64-bit, but fixing it would break the ABI.
+extern uint64_t lzma_block_buffer_bound64(uint64_t uncompressed_size);
+
+#endif
diff --git a/src/liblzma/common/block_decoder.c b/src/liblzma/common/block_decoder.c
index a3ce6f4..685c3b0 100644
--- a/src/liblzma/common/block_decoder.c
+++ b/src/liblzma/common/block_decoder.c
@@ -45,6 +45,9 @@
 
 	/// Check of the uncompressed data
 	lzma_check_state check;
+
+	/// True if the integrity check won't be calculated and verified.
+	bool ignore_check;
 };
 
 
@@ -71,7 +74,7 @@
 
 
 static lzma_ret
-block_decode(lzma_coder *coder, lzma_allocator *allocator,
+block_decode(lzma_coder *coder, const lzma_allocator *allocator,
 		const uint8_t *restrict in, size_t *restrict in_pos,
 		size_t in_size, uint8_t *restrict out,
 		size_t *restrict out_pos, size_t out_size, lzma_action action)
@@ -97,8 +100,9 @@
 					coder->block->uncompressed_size))
 			return LZMA_DATA_ERROR;
 
-		lzma_check_update(&coder->check, coder->block->check,
-				out + out_start, out_used);
+		if (!coder->ignore_check)
+			lzma_check_update(&coder->check, coder->block->check,
+					out + out_start, out_used);
 
 		if (ret != LZMA_STREAM_END)
 			return ret;
@@ -140,7 +144,9 @@
 		if (coder->block->check == LZMA_CHECK_NONE)
 			return LZMA_STREAM_END;
 
-		lzma_check_finish(&coder->check, coder->block->check);
+		if (!coder->ignore_check)
+			lzma_check_finish(&coder->check, coder->block->check);
+
 		coder->sequence = SEQ_CHECK;
 
 	// Fall through
@@ -155,7 +161,8 @@
 		// Validate the Check only if we support it.
 		// coder->check.buffer may be uninitialized
 		// when the Check ID is not supported.
-		if (lzma_check_is_supported(coder->block->check)
+		if (!coder->ignore_check
+				&& lzma_check_is_supported(coder->block->check)
 				&& memcmp(coder->block->raw_check,
 					coder->check.buffer.u8,
 					check_size) != 0)
@@ -170,7 +177,7 @@
 
 
 static void
-block_decoder_end(lzma_coder *coder, lzma_allocator *allocator)
+block_decoder_end(lzma_coder *coder, const lzma_allocator *allocator)
 {
 	lzma_next_end(&coder->next, allocator);
 	lzma_free(coder, allocator);
@@ -179,7 +186,7 @@
 
 
 extern lzma_ret
-lzma_block_decoder_init(lzma_next_coder *next, lzma_allocator *allocator,
+lzma_block_decoder_init(lzma_next_coder *next, const lzma_allocator *allocator,
 		lzma_block *block)
 {
 	lzma_next_coder_init(&lzma_block_decoder_init, next, allocator);
@@ -224,6 +231,9 @@
 	next->coder->check_pos = 0;
 	lzma_check_init(&next->coder->check, block->check);
 
+	next->coder->ignore_check = block->version >= 1
+			? block->ignore_check : false;
+
 	// Initialize the filter chain.
 	return lzma_raw_decoder_init(&next->coder->next, allocator,
 			block->filters);
diff --git a/src/liblzma/common/block_decoder.h b/src/liblzma/common/block_decoder.h
index 7da9df6..718c5ce 100644
--- a/src/liblzma/common/block_decoder.h
+++ b/src/liblzma/common/block_decoder.h
@@ -17,6 +17,6 @@
 
 
 extern lzma_ret lzma_block_decoder_init(lzma_next_coder *next,
-		lzma_allocator *allocator, lzma_block *block);
+		const lzma_allocator *allocator, lzma_block *block);
 
 #endif
diff --git a/src/liblzma/common/block_encoder.c b/src/liblzma/common/block_encoder.c
index 1eeb502..def5864 100644
--- a/src/liblzma/common/block_encoder.c
+++ b/src/liblzma/common/block_encoder.c
@@ -45,7 +45,7 @@
 
 
 static lzma_ret
-block_encode(lzma_coder *coder, lzma_allocator *allocator,
+block_encode(lzma_coder *coder, const lzma_allocator *allocator,
 		const uint8_t *restrict in, size_t *restrict in_pos,
 		size_t in_size, uint8_t *restrict out,
 		size_t *restrict out_pos, size_t out_size, lzma_action action)
@@ -134,7 +134,7 @@
 
 
 static void
-block_encoder_end(lzma_coder *coder, lzma_allocator *allocator)
+block_encoder_end(lzma_coder *coder, const lzma_allocator *allocator)
 {
 	lzma_next_end(&coder->next, allocator);
 	lzma_free(coder, allocator);
@@ -143,7 +143,7 @@
 
 
 static lzma_ret
-block_encoder_update(lzma_coder *coder, lzma_allocator *allocator,
+block_encoder_update(lzma_coder *coder, const lzma_allocator *allocator,
 		const lzma_filter *filters lzma_attribute((__unused__)),
 		const lzma_filter *reversed_filters)
 {
@@ -156,7 +156,7 @@
 
 
 extern lzma_ret
-lzma_block_encoder_init(lzma_next_coder *next, lzma_allocator *allocator,
+lzma_block_encoder_init(lzma_next_coder *next, const lzma_allocator *allocator,
 		lzma_block *block)
 {
 	lzma_next_coder_init(&lzma_block_encoder_init, next, allocator);
@@ -166,7 +166,7 @@
 
 	// The contents of the structure may depend on the version so
 	// check the version first.
-	if (block->version != 0)
+	if (block->version > 1)
 		return LZMA_OPTIONS_ERROR;
 
 	// If the Check ID is not supported, we cannot calculate the check and
diff --git a/src/liblzma/common/block_encoder.h b/src/liblzma/common/block_encoder.h
index b9eff0b..bd97c18 100644
--- a/src/liblzma/common/block_encoder.h
+++ b/src/liblzma/common/block_encoder.h
@@ -42,6 +42,6 @@
 
 
 extern lzma_ret lzma_block_encoder_init(lzma_next_coder *next,
-		lzma_allocator *allocator, lzma_block *block);
+		const lzma_allocator *allocator, lzma_block *block);
 
 #endif
diff --git a/src/liblzma/common/block_header_decoder.c b/src/liblzma/common/block_header_decoder.c
index 2c9573e..1dd982f 100644
--- a/src/liblzma/common/block_header_decoder.c
+++ b/src/liblzma/common/block_header_decoder.c
@@ -15,7 +15,7 @@
 
 
 static void
-free_properties(lzma_block *block, lzma_allocator *allocator)
+free_properties(lzma_block *block, const lzma_allocator *allocator)
 {
 	// Free allocated filter options. The last array member is not
 	// touched after the initialization in the beginning of
@@ -32,7 +32,7 @@
 
 extern LZMA_API(lzma_ret)
 lzma_block_header_decode(lzma_block *block,
-		lzma_allocator *allocator, const uint8_t *in)
+		const lzma_allocator *allocator, const uint8_t *in)
 {
 	// NOTE: We consider the header to be corrupt not only when the
 	// CRC32 doesn't match, but also when variable-length integers
@@ -46,8 +46,16 @@
 		block->filters[i].options = NULL;
 	}
 
-	// Always zero for now.
-	block->version = 0;
+	// Versions 0 and 1 are supported. If a newer version was specified,
+	// we need to downgrade it.
+	if (block->version > 1)
+		block->version = 1;
+
+	// This isn't a Block Header option, but since the decompressor will
+	// read it if version >= 1, it's better to initialize it here than
+	// to expect the caller to do it since in almost all cases this
+	// should be false.
+	block->ignore_check = false;
 
 	// Validate Block Header Size and Check type. The caller must have
 	// already set these, so it is a programming error if this test fails.
diff --git a/src/liblzma/common/block_header_encoder.c b/src/liblzma/common/block_header_encoder.c
index 707dd0c..5c5f542 100644
--- a/src/liblzma/common/block_header_encoder.c
+++ b/src/liblzma/common/block_header_encoder.c
@@ -17,7 +17,7 @@
 extern LZMA_API(lzma_ret)
 lzma_block_header_size(lzma_block *block)
 {
-	if (block->version != 0)
+	if (block->version > 1)
 		return LZMA_OPTIONS_ERROR;
 
 	// Block Header Size + Block Flags + CRC32.
diff --git a/src/liblzma/common/block_util.c b/src/liblzma/common/block_util.c
index 62c9345..00c7fe8 100644
--- a/src/liblzma/common/block_util.c
+++ b/src/liblzma/common/block_util.c
@@ -51,7 +51,7 @@
 	// NOTE: This function is used for validation too, so it is
 	// essential that these checks are always done even if
 	// Compressed Size is unknown.
-	if (block == NULL || block->version != 0
+	if (block == NULL || block->version > 1
 			|| block->header_size < LZMA_BLOCK_HEADER_SIZE_MIN
 			|| block->header_size > LZMA_BLOCK_HEADER_SIZE_MAX
 			|| (block->header_size & 3)
diff --git a/src/liblzma/common/common.c b/src/liblzma/common/common.c
index 3bfdb75..79427b0 100644
--- a/src/liblzma/common/common.c
+++ b/src/liblzma/common/common.c
@@ -38,7 +38,7 @@
 ///////////////////////
 
 extern void * lzma_attribute((__malloc__)) lzma_attr_alloc_size(1)
-lzma_alloc(size_t size, lzma_allocator *allocator)
+lzma_alloc(size_t size, const lzma_allocator *allocator)
 {
 	// Some malloc() variants return NULL if called with size == 0.
 	if (size == 0)
@@ -55,8 +55,29 @@
 }
 
 
+extern void * lzma_attribute((__malloc__)) lzma_attr_alloc_size(1)
+lzma_alloc_zero(size_t size, const lzma_allocator *allocator)
+{
+	// Some calloc() variants return NULL if called with size == 0.
+	if (size == 0)
+		size = 1;
+
+	void *ptr;
+
+	if (allocator != NULL && allocator->alloc != NULL) {
+		ptr = allocator->alloc(allocator->opaque, 1, size);
+		if (ptr != NULL)
+			memzero(ptr, size);
+	} else {
+		ptr = calloc(1, size);
+	}
+
+	return ptr;
+}
+
+
 extern void
-lzma_free(void *ptr, lzma_allocator *allocator)
+lzma_free(void *ptr, const lzma_allocator *allocator)
 {
 	if (allocator != NULL && allocator->free != NULL)
 		allocator->free(allocator->opaque, ptr);
@@ -90,7 +111,7 @@
 
 
 extern lzma_ret
-lzma_next_filter_init(lzma_next_coder *next, lzma_allocator *allocator,
+lzma_next_filter_init(lzma_next_coder *next, const lzma_allocator *allocator,
 		const lzma_filter_info *filters)
 {
 	lzma_next_coder_init(filters[0].init, next, allocator);
@@ -101,7 +122,7 @@
 
 
 extern lzma_ret
-lzma_next_filter_update(lzma_next_coder *next, lzma_allocator *allocator,
+lzma_next_filter_update(lzma_next_coder *next, const lzma_allocator *allocator,
 		const lzma_filter *reversed_filters)
 {
 	// Check that the application isn't trying to change the Filter ID.
@@ -119,7 +140,7 @@
 
 
 extern void
-lzma_next_end(lzma_next_coder *next, lzma_allocator *allocator)
+lzma_next_end(lzma_next_coder *next, const lzma_allocator *allocator)
 {
 	if (next->init != (uintptr_t)(NULL)) {
 		// To avoid tiny end functions that simply call
@@ -238,7 +259,7 @@
 			|| (strm->next_out == NULL && strm->avail_out != 0)
 			|| strm->internal == NULL
 			|| strm->internal->next.code == NULL
-			|| (unsigned int)(action) > LZMA_FINISH
+			|| (unsigned int)(action) > LZMA_ACTION_MAX
 			|| !strm->internal->supported_actions[action])
 		return LZMA_PROG_ERROR;
 
@@ -277,6 +298,10 @@
 		case LZMA_FINISH:
 			strm->internal->sequence = ISEQ_FINISH;
 			break;
+
+		case LZMA_FULL_BARRIER:
+			strm->internal->sequence = ISEQ_FULL_BARRIER;
+			break;
 		}
 
 		break;
@@ -304,6 +329,13 @@
 
 		break;
 
+	case ISEQ_FULL_BARRIER:
+		if (action != LZMA_FULL_BARRIER
+				|| strm->internal->avail_in != strm->avail_in)
+			return LZMA_PROG_ERROR;
+
+		break;
+
 	case ISEQ_END:
 		return LZMA_STREAM_END;
 
@@ -329,7 +361,9 @@
 
 	strm->internal->avail_in = strm->avail_in;
 
-	switch (ret) {
+	// Cast is needed to silence a warning about LZMA_TIMED_OUT, which
+	// isn't part of lzma_ret enumeration.
+	switch ((unsigned int)(ret)) {
 	case LZMA_OK:
 		// Don't return LZMA_BUF_ERROR when it happens the first time.
 		// This is to avoid returning LZMA_BUF_ERROR when avail_out
@@ -345,9 +379,16 @@
 		}
 		break;
 
+	case LZMA_TIMED_OUT:
+		strm->internal->allow_buf_error = false;
+		ret = LZMA_OK;
+		break;
+
 	case LZMA_STREAM_END:
 		if (strm->internal->sequence == ISEQ_SYNC_FLUSH
-				|| strm->internal->sequence == ISEQ_FULL_FLUSH)
+				|| strm->internal->sequence == ISEQ_FULL_FLUSH
+				|| strm->internal->sequence
+					== ISEQ_FULL_BARRIER)
 			strm->internal->sequence = ISEQ_RUN;
 		else
 			strm->internal->sequence = ISEQ_END;
@@ -387,6 +428,22 @@
 }
 
 
+extern LZMA_API(void)
+lzma_get_progress(lzma_stream *strm,
+		uint64_t *progress_in, uint64_t *progress_out)
+{
+	if (strm->internal->next.get_progress != NULL) {
+		strm->internal->next.get_progress(strm->internal->next.coder,
+				progress_in, progress_out);
+	} else {
+		*progress_in = strm->total_in;
+		*progress_out = strm->total_out;
+	}
+
+	return;
+}
+
+
 extern LZMA_API(lzma_check)
 lzma_get_check(const lzma_stream *strm)
 {
diff --git a/src/liblzma/common/common.h b/src/liblzma/common/common.h
index 4081c2d..eb1d052 100644
--- a/src/liblzma/common/common.h
+++ b/src/liblzma/common/common.h
@@ -49,6 +49,13 @@
 #define LZMA_BUFFER_SIZE 4096
 
 
+/// Maximum number of worker threads within one multithreaded component.
+/// The limit exists solely to make it simpler to prevent integer overflows
+/// when allocating structures etc. This should be big enough for now...
+/// the code won't scale anywhere close to this number anyway.
+#define LZMA_THREADS_MAX 16384
+
+
 /// Starting value for memory usage estimates. Instead of calculating size
 /// of _every_ structure and taking into account malloc() overhead etc., we
 /// add a base size to all memory usage estimates. It's not very accurate
@@ -66,9 +73,21 @@
 	( LZMA_TELL_NO_CHECK \
 	| LZMA_TELL_UNSUPPORTED_CHECK \
 	| LZMA_TELL_ANY_CHECK \
+	| LZMA_IGNORE_CHECK \
 	| LZMA_CONCATENATED )
 
 
+/// Largest valid lzma_action value as unsigned integer.
+#define LZMA_ACTION_MAX ((unsigned int)(LZMA_FULL_BARRIER))
+
+
+/// Special return value (lzma_ret) to indicate that a timeout was reached
+/// and lzma_code() must not return LZMA_BUF_ERROR. This is converted to
+/// LZMA_OK in lzma_code(). This is not in the lzma_ret enumeration because
+/// there's no need to have it in the public API.
+#define LZMA_TIMED_OUT 32
+
+
 /// Type of encoder/decoder specific data; the actual structure is defined
 /// differently in different coders.
 typedef struct lzma_coder_s lzma_coder;
@@ -80,7 +99,7 @@
 
 /// Type of a function used to initialize a filter encoder or decoder
 typedef lzma_ret (*lzma_init_function)(
-		lzma_next_coder *next, lzma_allocator *allocator,
+		lzma_next_coder *next, const lzma_allocator *allocator,
 		const lzma_filter_info *filters);
 
 /// Type of a function to do some kind of coding work (filters, Stream,
@@ -88,7 +107,7 @@
 /// input and output buffers, but for simplicity they still use this same
 /// function prototype.
 typedef lzma_ret (*lzma_code_function)(
-		lzma_coder *coder, lzma_allocator *allocator,
+		lzma_coder *coder, const lzma_allocator *allocator,
 		const uint8_t *restrict in, size_t *restrict in_pos,
 		size_t in_size, uint8_t *restrict out,
 		size_t *restrict out_pos, size_t out_size,
@@ -96,7 +115,7 @@
 
 /// Type of a function to free the memory allocated for the coder
 typedef void (*lzma_end_function)(
-		lzma_coder *coder, lzma_allocator *allocator);
+		lzma_coder *coder, const lzma_allocator *allocator);
 
 
 /// Raw coder validates and converts an array of lzma_filter structures to
@@ -139,6 +158,11 @@
 	/// lzma_next_coder.coder.
 	lzma_end_function end;
 
+	/// Pointer to a function to get progress information. If this is NULL,
+	/// lzma_stream.total_in and .total_out are used instead.
+	void (*get_progress)(lzma_coder *coder,
+			uint64_t *progress_in, uint64_t *progress_out);
+
 	/// Pointer to function to return the type of the integrity check.
 	/// Most coders won't support this.
 	lzma_check (*get_check)(const lzma_coder *coder);
@@ -150,7 +174,7 @@
 
 	/// Update the filter-specific options or the whole filter chain
 	/// in the encoder.
-	lzma_ret (*update)(lzma_coder *coder, lzma_allocator *allocator,
+	lzma_ret (*update)(lzma_coder *coder, const lzma_allocator *allocator,
 			const lzma_filter *filters,
 			const lzma_filter *reversed_filters);
 };
@@ -164,6 +188,7 @@
 		.id = LZMA_VLI_UNKNOWN, \
 		.code = NULL, \
 		.end = NULL, \
+		.get_progress = NULL, \
 		.get_check = NULL, \
 		.memconfig = NULL, \
 		.update = NULL, \
@@ -185,6 +210,7 @@
 		ISEQ_SYNC_FLUSH,
 		ISEQ_FULL_FLUSH,
 		ISEQ_FINISH,
+		ISEQ_FULL_BARRIER,
 		ISEQ_END,
 		ISEQ_ERROR,
 	} sequence;
@@ -195,7 +221,7 @@
 	size_t avail_in;
 
 	/// Indicates which lzma_action values are allowed by next.code.
-	bool supported_actions[4];
+	bool supported_actions[LZMA_ACTION_MAX + 1];
 
 	/// If true, lzma_code will return LZMA_BUF_ERROR if no progress was
 	/// made (no input consumed and no output produced by next.code).
@@ -210,11 +236,17 @@
 
 
 /// Allocates memory
-extern void *lzma_alloc(size_t size, lzma_allocator *allocator)
+extern void *lzma_alloc(size_t size, const lzma_allocator *allocator)
 		lzma_attribute((__malloc__)) lzma_attr_alloc_size(1);
 
+/// Allocates memory and zeroes it (like calloc()). This can be faster
+/// than lzma_alloc() + memzero() while being backward compatible with
+/// custom allocators.
+extern void * lzma_attribute((__malloc__)) lzma_attr_alloc_size(1)
+		lzma_alloc_zero(size_t size, const lzma_allocator *allocator);
+
 /// Frees memory
-extern void lzma_free(void *ptr, lzma_allocator *allocator);
+extern void lzma_free(void *ptr, const lzma_allocator *allocator);
 
 
 /// Allocates strm->internal if it is NULL, and initializes *strm and
@@ -226,17 +258,19 @@
 /// than the filter being initialized now. This way the actual filter
 /// initialization functions don't need to use lzma_next_coder_init macro.
 extern lzma_ret lzma_next_filter_init(lzma_next_coder *next,
-		lzma_allocator *allocator, const lzma_filter_info *filters);
+		const lzma_allocator *allocator,
+		const lzma_filter_info *filters);
 
 /// Update the next filter in the chain, if any. This checks that
 /// the application is not trying to change the Filter IDs.
 extern lzma_ret lzma_next_filter_update(
-		lzma_next_coder *next, lzma_allocator *allocator,
+		lzma_next_coder *next, const lzma_allocator *allocator,
 		const lzma_filter *reversed_filters);
 
 /// Frees the memory allocated for next->coder either using next->end or,
 /// if next->end is NULL, using lzma_free.
-extern void lzma_next_end(lzma_next_coder *next, lzma_allocator *allocator);
+extern void lzma_next_end(lzma_next_coder *next,
+		const lzma_allocator *allocator);
 
 
 /// Copy as much data as possible from in[] to out[] and update *in_pos
diff --git a/src/liblzma/common/easy_buffer_encoder.c b/src/liblzma/common/easy_buffer_encoder.c
index c4be34c..48eb56f 100644
--- a/src/liblzma/common/easy_buffer_encoder.c
+++ b/src/liblzma/common/easy_buffer_encoder.c
@@ -15,8 +15,8 @@
 
 extern LZMA_API(lzma_ret)
 lzma_easy_buffer_encode(uint32_t preset, lzma_check check,
-		lzma_allocator *allocator, const uint8_t *in, size_t in_size,
-		uint8_t *out, size_t *out_pos, size_t out_size)
+		const lzma_allocator *allocator, const uint8_t *in,
+		size_t in_size, uint8_t *out, size_t *out_pos, size_t out_size)
 {
 	lzma_options_easy opt_easy;
 	if (lzma_easy_preset(&opt_easy, preset))
diff --git a/src/liblzma/common/filter_buffer_decoder.c b/src/liblzma/common/filter_buffer_decoder.c
index 2d35ef8..6620986 100644
--- a/src/liblzma/common/filter_buffer_decoder.c
+++ b/src/liblzma/common/filter_buffer_decoder.c
@@ -14,7 +14,8 @@
 
 
 extern LZMA_API(lzma_ret)
-lzma_raw_buffer_decode(const lzma_filter *filters, lzma_allocator *allocator,
+lzma_raw_buffer_decode(
+		const lzma_filter *filters, const lzma_allocator *allocator,
 		const uint8_t *in, size_t *in_pos, size_t in_size,
 		uint8_t *out, size_t *out_pos, size_t out_size)
 {
diff --git a/src/liblzma/common/filter_buffer_encoder.c b/src/liblzma/common/filter_buffer_encoder.c
index 646e1b3..dda18e3 100644
--- a/src/liblzma/common/filter_buffer_encoder.c
+++ b/src/liblzma/common/filter_buffer_encoder.c
@@ -14,9 +14,10 @@
 
 
 extern LZMA_API(lzma_ret)
-lzma_raw_buffer_encode(const lzma_filter *filters, lzma_allocator *allocator,
-		const uint8_t *in, size_t in_size, uint8_t *out,
-		size_t *out_pos, size_t out_size)
+lzma_raw_buffer_encode(
+		const lzma_filter *filters, const lzma_allocator *allocator,
+		const uint8_t *in, size_t in_size,
+		uint8_t *out, size_t *out_pos, size_t out_size)
 {
 	// Validate what isn't validated later in filter_common.c.
 	if ((in == NULL && in_size != 0) || out == NULL
diff --git a/src/liblzma/common/filter_common.c b/src/liblzma/common/filter_common.c
index 7c95b05..9ad5d5d 100644
--- a/src/liblzma/common/filter_common.c
+++ b/src/liblzma/common/filter_common.c
@@ -123,7 +123,7 @@
 
 extern LZMA_API(lzma_ret)
 lzma_filters_copy(const lzma_filter *src, lzma_filter *dest,
-		lzma_allocator *allocator)
+		const lzma_allocator *allocator)
 {
 	if (src == NULL || dest == NULL)
 		return LZMA_PROG_ERROR;
@@ -239,7 +239,7 @@
 
 
 extern lzma_ret
-lzma_raw_coder_init(lzma_next_coder *next, lzma_allocator *allocator,
+lzma_raw_coder_init(lzma_next_coder *next, const lzma_allocator *allocator,
 		const lzma_filter *options,
 		lzma_filter_find coder_find, bool is_encoder)
 {
diff --git a/src/liblzma/common/filter_common.h b/src/liblzma/common/filter_common.h
index cd61fc0..42a26a2 100644
--- a/src/liblzma/common/filter_common.h
+++ b/src/liblzma/common/filter_common.h
@@ -36,7 +36,7 @@
 
 
 extern lzma_ret lzma_raw_coder_init(
-		lzma_next_coder *next, lzma_allocator *allocator,
+		lzma_next_coder *next, const lzma_allocator *allocator,
 		const lzma_filter *filters,
 		lzma_filter_find coder_find, bool is_encoder);
 
diff --git a/src/liblzma/common/filter_decoder.c b/src/liblzma/common/filter_decoder.c
index 1ebbe2a..c75b0a8 100644
--- a/src/liblzma/common/filter_decoder.c
+++ b/src/liblzma/common/filter_decoder.c
@@ -35,7 +35,8 @@
 	/// \return     - LZMA_OK: Properties decoded successfully.
 	///             - LZMA_OPTIONS_ERROR: Unsupported properties
 	///             - LZMA_MEM_ERROR: Memory allocation failed.
-	lzma_ret (*props_decode)(void **options, lzma_allocator *allocator,
+	lzma_ret (*props_decode)(
+			void **options, const lzma_allocator *allocator,
 			const uint8_t *props, size_t props_size);
 
 } lzma_filter_decoder;
@@ -136,7 +137,7 @@
 
 
 extern lzma_ret
-lzma_raw_decoder_init(lzma_next_coder *next, lzma_allocator *allocator,
+lzma_raw_decoder_init(lzma_next_coder *next, const lzma_allocator *allocator,
 		const lzma_filter *options)
 {
 	return lzma_raw_coder_init(next, allocator,
@@ -165,7 +166,7 @@
 
 
 extern LZMA_API(lzma_ret)
-lzma_properties_decode(lzma_filter *filter, lzma_allocator *allocator,
+lzma_properties_decode(lzma_filter *filter, const lzma_allocator *allocator,
 		const uint8_t *props, size_t props_size)
 {
 	// Make it always NULL so that the caller can always safely free() it.
diff --git a/src/liblzma/common/filter_decoder.h b/src/liblzma/common/filter_decoder.h
index d5c68bd..a2e255f 100644
--- a/src/liblzma/common/filter_decoder.h
+++ b/src/liblzma/common/filter_decoder.h
@@ -17,7 +17,7 @@
 
 
 extern lzma_ret lzma_raw_decoder_init(
-		lzma_next_coder *next, lzma_allocator *allocator,
+		lzma_next_coder *next, const lzma_allocator *allocator,
 		const lzma_filter *options);
 
 #endif
diff --git a/src/liblzma/common/filter_encoder.c b/src/liblzma/common/filter_encoder.c
index 4ba652b..c5d8f39 100644
--- a/src/liblzma/common/filter_encoder.c
+++ b/src/liblzma/common/filter_encoder.c
@@ -196,7 +196,7 @@
 
 
 extern lzma_ret
-lzma_raw_encoder_init(lzma_next_coder *next, lzma_allocator *allocator,
+lzma_raw_encoder_init(lzma_next_coder *next, const lzma_allocator *allocator,
 		const lzma_filter *options)
 {
 	return lzma_raw_coder_init(next, allocator,
diff --git a/src/liblzma/common/filter_encoder.h b/src/liblzma/common/filter_encoder.h
index 82fb0d9..f1d5683 100644
--- a/src/liblzma/common/filter_encoder.h
+++ b/src/liblzma/common/filter_encoder.h
@@ -21,7 +21,7 @@
 
 
 extern lzma_ret lzma_raw_encoder_init(
-		lzma_next_coder *next, lzma_allocator *allocator,
+		lzma_next_coder *next, const lzma_allocator *allocator,
 		const lzma_filter *filters);
 
 #endif
diff --git a/src/liblzma/common/filter_flags_decoder.c b/src/liblzma/common/filter_flags_decoder.c
index caae10c..ddfb085 100644
--- a/src/liblzma/common/filter_flags_decoder.c
+++ b/src/liblzma/common/filter_flags_decoder.c
@@ -15,7 +15,7 @@
 
 extern LZMA_API(lzma_ret)
 lzma_filter_flags_decode(
-		lzma_filter *filter, lzma_allocator *allocator,
+		lzma_filter *filter, const lzma_allocator *allocator,
 		const uint8_t *in, size_t *in_pos, size_t in_size)
 {
 	// Set the pointer to NULL so the caller can always safely free it.
diff --git a/src/liblzma/common/hardware_cputhreads.c b/src/liblzma/common/hardware_cputhreads.c
new file mode 100644
index 0000000..f468366
--- /dev/null
+++ b/src/liblzma/common/hardware_cputhreads.c
@@ -0,0 +1,22 @@
+///////////////////////////////////////////////////////////////////////////////
+//
+/// \file       hardware_cputhreads.c
+/// \brief      Get the number of CPU threads or cores
+//
+//  Author:     Lasse Collin
+//
+//  This file has been put into the public domain.
+//  You can do whatever you want with this file.
+//
+///////////////////////////////////////////////////////////////////////////////
+
+#include "common.h"
+
+#include "tuklib_cpucores.h"
+
+
+extern LZMA_API(uint32_t)
+lzma_cputhreads(void)
+{
+	return tuklib_cpucores();
+}
diff --git a/src/liblzma/common/index.c b/src/liblzma/common/index.c
index 9af4bc1..e897646 100644
--- a/src/liblzma/common/index.c
+++ b/src/liblzma/common/index.c
@@ -191,8 +191,8 @@
 
 /// Helper for index_tree_end()
 static void
-index_tree_node_end(index_tree_node *node, lzma_allocator *allocator,
-		void (*free_func)(void *node, lzma_allocator *allocator))
+index_tree_node_end(index_tree_node *node, const lzma_allocator *allocator,
+		void (*free_func)(void *node, const lzma_allocator *allocator))
 {
 	// The tree won't ever be very huge, so recursion should be fine.
 	// 20 levels in the tree is likely quite a lot already in practice.
@@ -215,8 +215,8 @@
 /// to free the Record groups from each index_stream before freeing
 /// the index_stream itself.
 static void
-index_tree_end(index_tree *tree, lzma_allocator *allocator,
-		void (*free_func)(void *node, lzma_allocator *allocator))
+index_tree_end(index_tree *tree, const lzma_allocator *allocator,
+		void (*free_func)(void *node, const lzma_allocator *allocator))
 {
 	if (tree->root != NULL)
 		index_tree_node_end(tree->root, allocator, free_func);
@@ -339,8 +339,8 @@
 /// Allocate and initialize a new Stream using the given base offsets.
 static index_stream *
 index_stream_init(lzma_vli compressed_base, lzma_vli uncompressed_base,
-		lzma_vli stream_number, lzma_vli block_number_base,
-		lzma_allocator *allocator)
+		uint32_t stream_number, lzma_vli block_number_base,
+		const lzma_allocator *allocator)
 {
 	index_stream *s = lzma_alloc(sizeof(index_stream), allocator);
 	if (s == NULL)
@@ -368,7 +368,7 @@
 
 /// Free the memory allocated for a Stream and its Record groups.
 static void
-index_stream_end(void *node, lzma_allocator *allocator)
+index_stream_end(void *node, const lzma_allocator *allocator)
 {
 	index_stream *s = node;
 	index_tree_end(&s->groups, allocator, NULL);
@@ -377,7 +377,7 @@
 
 
 static lzma_index *
-index_init_plain(lzma_allocator *allocator)
+index_init_plain(const lzma_allocator *allocator)
 {
 	lzma_index *i = lzma_alloc(sizeof(lzma_index), allocator);
 	if (i != NULL) {
@@ -395,7 +395,7 @@
 
 
 extern LZMA_API(lzma_index *)
-lzma_index_init(lzma_allocator *allocator)
+lzma_index_init(const lzma_allocator *allocator)
 {
 	lzma_index *i = index_init_plain(allocator);
 	if (i == NULL)
@@ -414,7 +414,7 @@
 
 
 extern LZMA_API(void)
-lzma_index_end(lzma_index *i, lzma_allocator *allocator)
+lzma_index_end(lzma_index *i, const lzma_allocator *allocator)
 {
 	// NOTE: If you modify this function, check also the bottom
 	// of lzma_index_cat().
@@ -637,7 +637,7 @@
 
 
 extern LZMA_API(lzma_ret)
-lzma_index_append(lzma_index *i, lzma_allocator *allocator,
+lzma_index_append(lzma_index *i, const lzma_allocator *allocator,
 		lzma_vli unpadded_size, lzma_vli uncompressed_size)
 {
 	// Validate.
@@ -765,7 +765,7 @@
 
 extern LZMA_API(lzma_ret)
 lzma_index_cat(lzma_index *restrict dest, lzma_index *restrict src,
-		lzma_allocator *allocator)
+		const lzma_allocator *allocator)
 {
 	const lzma_vli dest_file_size = lzma_index_file_size(dest);
 
@@ -859,7 +859,7 @@
 
 /// Duplicate an index_stream.
 static index_stream *
-index_dup_stream(const index_stream *src, lzma_allocator *allocator)
+index_dup_stream(const index_stream *src, const lzma_allocator *allocator)
 {
 	// Catch a somewhat theoretical integer overflow.
 	if (src->record_count > PREALLOC_MAX)
@@ -919,7 +919,7 @@
 
 
 extern LZMA_API(lzma_index *)
-lzma_index_dup(const lzma_index *src, lzma_allocator *allocator)
+lzma_index_dup(const lzma_index *src, const lzma_allocator *allocator)
 {
 	// Allocate the base structure (no initial Stream).
 	lzma_index *dest = index_init_plain(allocator);
@@ -1008,6 +1008,8 @@
 		iter->internal[ITER_GROUP].p = NULL;
 	}
 
+	// NOTE: lzma_index_iter.stream.number is lzma_vli but we use uint32_t
+	// internally.
 	iter->stream.number = stream->number;
 	iter->stream.block_count = stream->record_count;
 	iter->stream.compressed_offset = stream->node.compressed_base;
diff --git a/src/liblzma/common/index_decoder.c b/src/liblzma/common/index_decoder.c
index 83c8a3a..795d183 100644
--- a/src/liblzma/common/index_decoder.c
+++ b/src/liblzma/common/index_decoder.c
@@ -54,7 +54,7 @@
 
 
 static lzma_ret
-index_decode(lzma_coder *coder, lzma_allocator *allocator,
+index_decode(lzma_coder *coder, const lzma_allocator *allocator,
 		const uint8_t *restrict in, size_t *restrict in_pos,
 		size_t in_size,
 		uint8_t *restrict out lzma_attribute((__unused__)),
@@ -207,7 +207,7 @@
 
 
 static void
-index_decoder_end(lzma_coder *coder, lzma_allocator *allocator)
+index_decoder_end(lzma_coder *coder, const lzma_allocator *allocator)
 {
 	lzma_index_end(coder->index, allocator);
 	lzma_free(coder, allocator);
@@ -234,7 +234,7 @@
 
 
 static lzma_ret
-index_decoder_reset(lzma_coder *coder, lzma_allocator *allocator,
+index_decoder_reset(lzma_coder *coder, const lzma_allocator *allocator,
 		lzma_index **i, uint64_t memlimit)
 {
 	// Remember the pointer given by the application. We will set it
@@ -261,7 +261,7 @@
 
 
 static lzma_ret
-index_decoder_init(lzma_next_coder *next, lzma_allocator *allocator,
+index_decoder_init(lzma_next_coder *next, const lzma_allocator *allocator,
 		lzma_index **i, uint64_t memlimit)
 {
 	lzma_next_coder_init(&index_decoder_init, next, allocator);
@@ -299,8 +299,8 @@
 
 
 extern LZMA_API(lzma_ret)
-lzma_index_buffer_decode(
-		lzma_index **i, uint64_t *memlimit, lzma_allocator *allocator,
+lzma_index_buffer_decode(lzma_index **i, uint64_t *memlimit,
+		const lzma_allocator *allocator,
 		const uint8_t *in, size_t *in_pos, size_t in_size)
 {
 	// Sanity checks
diff --git a/src/liblzma/common/index_encoder.c b/src/liblzma/common/index_encoder.c
index 45919f0..d25ac7d 100644
--- a/src/liblzma/common/index_encoder.c
+++ b/src/liblzma/common/index_encoder.c
@@ -42,7 +42,7 @@
 
 static lzma_ret
 index_encode(lzma_coder *coder,
-		lzma_allocator *allocator lzma_attribute((__unused__)),
+		const lzma_allocator *allocator lzma_attribute((__unused__)),
 		const uint8_t *restrict in lzma_attribute((__unused__)),
 		size_t *restrict in_pos lzma_attribute((__unused__)),
 		size_t in_size lzma_attribute((__unused__)),
@@ -159,7 +159,7 @@
 
 
 static void
-index_encoder_end(lzma_coder *coder, lzma_allocator *allocator)
+index_encoder_end(lzma_coder *coder, const lzma_allocator *allocator)
 {
 	lzma_free(coder, allocator);
 	return;
@@ -181,7 +181,7 @@
 
 
 extern lzma_ret
-lzma_index_encoder_init(lzma_next_coder *next, lzma_allocator *allocator,
+lzma_index_encoder_init(lzma_next_coder *next, const lzma_allocator *allocator,
 		const lzma_index *i)
 {
 	lzma_next_coder_init(&lzma_index_encoder_init, next, allocator);
diff --git a/src/liblzma/common/index_encoder.h b/src/liblzma/common/index_encoder.h
index a13c94d..4d55cd1 100644
--- a/src/liblzma/common/index_encoder.h
+++ b/src/liblzma/common/index_encoder.h
@@ -17,7 +17,7 @@
 
 
 extern lzma_ret lzma_index_encoder_init(lzma_next_coder *next,
-		lzma_allocator *allocator, const lzma_index *i);
+		const lzma_allocator *allocator, const lzma_index *i);
 
 
 #endif
diff --git a/src/liblzma/common/index_hash.c b/src/liblzma/common/index_hash.c
index e3e9386..d7a0344 100644
--- a/src/liblzma/common/index_hash.c
+++ b/src/liblzma/common/index_hash.c
@@ -70,7 +70,8 @@
 
 
 extern LZMA_API(lzma_index_hash *)
-lzma_index_hash_init(lzma_index_hash *index_hash, lzma_allocator *allocator)
+lzma_index_hash_init(lzma_index_hash *index_hash,
+		const lzma_allocator *allocator)
 {
 	if (index_hash == NULL) {
 		index_hash = lzma_alloc(sizeof(lzma_index_hash), allocator);
@@ -101,7 +102,8 @@
 
 
 extern LZMA_API(void)
-lzma_index_hash_end(lzma_index_hash *index_hash, lzma_allocator *allocator)
+lzma_index_hash_end(lzma_index_hash *index_hash,
+		const lzma_allocator *allocator)
 {
 	lzma_free(index_hash, allocator);
 	return;
diff --git a/src/liblzma/common/memcmplen.h b/src/liblzma/common/memcmplen.h
new file mode 100644
index 0000000..c1efc9e
--- /dev/null
+++ b/src/liblzma/common/memcmplen.h
@@ -0,0 +1,175 @@
+///////////////////////////////////////////////////////////////////////////////
+//
+/// \file       memcmplen.h
+/// \brief      Optimized comparison of two buffers
+//
+//  Author:     Lasse Collin
+//
+//  This file has been put into the public domain.
+//  You can do whatever you want with this file.
+//
+///////////////////////////////////////////////////////////////////////////////
+
+#ifndef LZMA_MEMCMPLEN_H
+#define LZMA_MEMCMPLEN_H
+
+#include "common.h"
+
+#ifdef HAVE_IMMINTRIN_H
+#	include <immintrin.h>
+#endif
+
+
+/// Find out how many equal bytes the two buffers have.
+///
+/// \param      buf1    First buffer
+/// \param      buf2    Second buffer
+/// \param      len     How many bytes have already been compared and will
+///                     be assumed to match
+/// \param      limit   How many bytes to compare at most, including the
+///                     already-compared bytes. This must be significantly
+///                     smaller than UINT32_MAX to avoid integer overflows.
+///                     Up to LZMA_MEMCMPLEN_EXTRA bytes may be read past
+///                     the specified limit from both buf1 and buf2.
+///
+/// \return     Number of equal bytes in the buffers is returned.
+///             This is always at least len and at most limit.
+///
+/// \note       LZMA_MEMCMPLEN_EXTRA defines how many extra bytes may be read.
+///             It's rounded up to 2^n. This extra amount needs to be
+///             allocated in the buffers being used. It needs to be
+///             initialized too to keep Valgrind quiet.
+static inline uint32_t lzma_attribute((__always_inline__))
+lzma_memcmplen(const uint8_t *buf1, const uint8_t *buf2,
+		uint32_t len, uint32_t limit)
+{
+	assert(len <= limit);
+	assert(limit <= UINT32_MAX / 2);
+
+#if defined(TUKLIB_FAST_UNALIGNED_ACCESS) \
+		&& ((TUKLIB_GNUC_REQ(3, 4) && defined(__x86_64__)) \
+			|| (defined(__INTEL_COMPILER) && defined(__x86_64__)) \
+			|| (defined(__INTEL_COMPILER) && defined(_M_X64)) \
+			|| (defined(_MSC_VER) && defined(_M_X64)))
+	// NOTE: This will use 64-bit unaligned access which
+	// TUKLIB_FAST_UNALIGNED_ACCESS wasn't meant to permit, but
+	// it's convenient here at least as long as it's x86-64 only.
+	//
+	// I keep this x86-64 only for now since that's where I know this
+	// to be a good method. This may be fine on other 64-bit CPUs too.
+	// On big endian one should use xor instead of subtraction and switch
+	// to __builtin_clzll().
+#define LZMA_MEMCMPLEN_EXTRA 8
+	while (len < limit) {
+		const uint64_t x = *(const uint64_t *)(buf1 + len)
+				- *(const uint64_t *)(buf2 + len);
+		if (x != 0) {
+#	if defined(_M_X64) // MSVC or Intel C compiler on Windows
+			unsigned long tmp;
+			_BitScanForward64(&tmp, x);
+			len += (uint32_t)tmp >> 3;
+#	else // GCC, clang, or Intel C compiler
+			len += (uint32_t)__builtin_ctzll(x) >> 3;
+#	endif
+			return my_min(len, limit);
+		}
+
+		len += 8;
+	}
+
+	return limit;
+
+#elif defined(TUKLIB_FAST_UNALIGNED_ACCESS) \
+		&& defined(HAVE__MM_MOVEMASK_EPI8) \
+		&& ((defined(__GNUC__) && defined(__SSE2_MATH__)) \
+			|| (defined(__INTEL_COMPILER) && defined(__SSE2__)) \
+			|| (defined(_MSC_VER) && defined(_M_IX86_FP) \
+				&& _M_IX86_FP >= 2))
+	// NOTE: Like above, this will use 128-bit unaligned access which
+	// TUKLIB_FAST_UNALIGNED_ACCESS wasn't meant to permit.
+	//
+	// SSE2 version for 32-bit and 64-bit x86. On x86-64 the above
+	// version is sometimes significantly faster and sometimes
+	// slightly slower than this SSE2 version, so this SSE2
+	// version isn't used on x86-64.
+#	define LZMA_MEMCMPLEN_EXTRA 16
+	while (len < limit) {
+		const uint32_t x = 0xFFFF ^ _mm_movemask_epi8(_mm_cmpeq_epi8(
+			_mm_loadu_si128((const __m128i *)(buf1 + len)),
+			_mm_loadu_si128((const __m128i *)(buf2 + len))));
+
+		if (x != 0) {
+#	if defined(__INTEL_COMPILER)
+			len += _bit_scan_forward(x);
+#	elif defined(_MSC_VER)
+			unsigned long tmp;
+			_BitScanForward(&tmp, x);
+			len += tmp;
+#	else
+			len += __builtin_ctz(x);
+#	endif
+			return my_min(len, limit);
+		}
+
+		len += 16;
+	}
+
+	return limit;
+
+#elif defined(TUKLIB_FAST_UNALIGNED_ACCESS) && !defined(WORDS_BIGENDIAN)
+	// Generic 32-bit little endian method
+#	define LZMA_MEMCMPLEN_EXTRA 4
+	while (len < limit) {
+		uint32_t x = *(const uint32_t *)(buf1 + len)
+				- *(const uint32_t *)(buf2 + len);
+		if (x != 0) {
+			if ((x & 0xFFFF) == 0) {
+				len += 2;
+				x >>= 16;
+			}
+
+			if ((x & 0xFF) == 0)
+				++len;
+
+			return my_min(len, limit);
+		}
+
+		len += 4;
+	}
+
+	return limit;
+
+#elif defined(TUKLIB_FAST_UNALIGNED_ACCESS) && defined(WORDS_BIGENDIAN)
+	// Generic 32-bit big endian method
+#	define LZMA_MEMCMPLEN_EXTRA 4
+	while (len < limit) {
+		uint32_t x = *(const uint32_t *)(buf1 + len)
+				^ *(const uint32_t *)(buf2 + len);
+		if (x != 0) {
+			if ((x & 0xFFFF0000) == 0) {
+				len += 2;
+				x <<= 16;
+			}
+
+			if ((x & 0xFF000000) == 0)
+				++len;
+
+			return my_min(len, limit);
+		}
+
+		len += 4;
+	}
+
+	return limit;
+
+#else
+	// Simple portable version that doesn't use unaligned access.
+#	define LZMA_MEMCMPLEN_EXTRA 0
+	while (len < limit && buf1[len] == buf2[len])
+		++len;
+
+	return len;
+#endif
+}
+
+#endif
diff --git a/src/liblzma/common/outqueue.c b/src/liblzma/common/outqueue.c
new file mode 100644
index 0000000..2dc8a38
--- /dev/null
+++ b/src/liblzma/common/outqueue.c
@@ -0,0 +1,184 @@
+///////////////////////////////////////////////////////////////////////////////
+//
+/// \file       outqueue.c
+/// \brief      Output queue handling in multithreaded coding
+//
+//  Author:     Lasse Collin
+//
+//  This file has been put into the public domain.
+//  You can do whatever you want with this file.
+//
+///////////////////////////////////////////////////////////////////////////////
+
+#include "outqueue.h"
+
+
+/// This is to ease integer overflow checking: We may allocate up to
+/// 2 * LZMA_THREADS_MAX buffers and we need some extra memory for other
+/// data structures (that's the second /2).
+#define BUF_SIZE_MAX (UINT64_MAX / LZMA_THREADS_MAX / 2 / 2)
+
+
+static lzma_ret
+get_options(uint64_t *bufs_alloc_size, uint32_t *bufs_count,
+		uint64_t buf_size_max, uint32_t threads)
+{
+	if (threads > LZMA_THREADS_MAX || buf_size_max > BUF_SIZE_MAX)
+		return LZMA_OPTIONS_ERROR;
+
+	// The number of buffers is twice the number of threads.
+	// This wastes RAM but keeps the threads busy when buffers
+	// finish out of order.
+	//
+	// NOTE: If this is changed, update BUF_SIZE_MAX too.
+	*bufs_count = threads * 2;
+	*bufs_alloc_size = *bufs_count * buf_size_max;
+
+	return LZMA_OK;
+}
+
+
+extern uint64_t
+lzma_outq_memusage(uint64_t buf_size_max, uint32_t threads)
+{
+	uint64_t bufs_alloc_size;
+	uint32_t bufs_count;
+
+	if (get_options(&bufs_alloc_size, &bufs_count, buf_size_max, threads)
+			!= LZMA_OK)
+		return UINT64_MAX;
+
+	return sizeof(lzma_outq) + bufs_count * sizeof(lzma_outbuf)
+			+ bufs_alloc_size;
+}
+
+
+extern lzma_ret
+lzma_outq_init(lzma_outq *outq, const lzma_allocator *allocator,
+		uint64_t buf_size_max, uint32_t threads)
+{
+	uint64_t bufs_alloc_size;
+	uint32_t bufs_count;
+
+	// Set bufs_count and bufs_alloc_size.
+	return_if_error(get_options(&bufs_alloc_size, &bufs_count,
+			buf_size_max, threads));
+
+	// Allocate memory if needed.
+	if (outq->buf_size_max != buf_size_max
+			|| outq->bufs_allocated != bufs_count) {
+		lzma_outq_end(outq, allocator);
+
+#if SIZE_MAX < UINT64_MAX
+		if (bufs_alloc_size > SIZE_MAX)
+			return LZMA_MEM_ERROR;
+#endif
+
+		outq->bufs = lzma_alloc(bufs_count * sizeof(lzma_outbuf),
+				allocator);
+		outq->bufs_mem = lzma_alloc((size_t)(bufs_alloc_size),
+				allocator);
+
+		if (outq->bufs == NULL || outq->bufs_mem == NULL) {
+			lzma_outq_end(outq, allocator);
+			return LZMA_MEM_ERROR;
+		}
+	}
+
+	// Initialize the rest of the main structure. Initialization of
+	// outq->bufs[] is done when they are actually needed.
+	outq->buf_size_max = (size_t)(buf_size_max);
+	outq->bufs_allocated = bufs_count;
+	outq->bufs_pos = 0;
+	outq->bufs_used = 0;
+	outq->read_pos = 0;
+
+	return LZMA_OK;
+}
+
+
+extern void
+lzma_outq_end(lzma_outq *outq, const lzma_allocator *allocator)
+{
+	lzma_free(outq->bufs, allocator);
+	outq->bufs = NULL;
+
+	lzma_free(outq->bufs_mem, allocator);
+	outq->bufs_mem = NULL;
+
+	return;
+}
+
+
+extern lzma_outbuf *
+lzma_outq_get_buf(lzma_outq *outq)
+{
+	// Caller must have checked it with lzma_outq_has_buf().
+	assert(outq->bufs_used < outq->bufs_allocated);
+
+	// Initialize the new buffer.
+	lzma_outbuf *buf = &outq->bufs[outq->bufs_pos];
+	buf->buf = outq->bufs_mem + outq->bufs_pos * outq->buf_size_max;
+	buf->size = 0;
+	buf->finished = false;
+
+	// Update the queue state.
+	if (++outq->bufs_pos == outq->bufs_allocated)
+		outq->bufs_pos = 0;
+
+	++outq->bufs_used;
+
+	return buf;
+}
+
+
+extern bool
+lzma_outq_is_readable(const lzma_outq *outq)
+{
+	uint32_t i = outq->bufs_pos - outq->bufs_used;
+	if (outq->bufs_pos < outq->bufs_used)
+		i += outq->bufs_allocated;
+
+	return outq->bufs[i].finished;
+}
+
+
+extern lzma_ret
+lzma_outq_read(lzma_outq *restrict outq, uint8_t *restrict out,
+		size_t *restrict out_pos, size_t out_size,
+		lzma_vli *restrict unpadded_size,
+		lzma_vli *restrict uncompressed_size)
+{
+	// There must be at least one buffer from which to read.
+	if (outq->bufs_used == 0)
+		return LZMA_OK;
+
+	// Get the buffer.
+	uint32_t i = outq->bufs_pos - outq->bufs_used;
+	if (outq->bufs_pos < outq->bufs_used)
+		i += outq->bufs_allocated;
+
+	lzma_outbuf *buf = &outq->bufs[i];
+
+	// If it isn't finished yet, we cannot read from it.
+	if (!buf->finished)
+		return LZMA_OK;
+
+	// Copy from the buffer to output.
+	lzma_bufcpy(buf->buf, &outq->read_pos, buf->size,
+			out, out_pos, out_size);
+
+	// Return if we didn't get all the data from the buffer.
+	if (outq->read_pos < buf->size)
+		return LZMA_OK;
+
+	// The buffer was finished. Tell the caller its size information.
+	*unpadded_size = buf->unpadded_size;
+	*uncompressed_size = buf->uncompressed_size;
+
+	// Free this buffer for further use.
+	--outq->bufs_used;
+	outq->read_pos = 0;
+
+	return LZMA_STREAM_END;
+}
diff --git a/src/liblzma/common/outqueue.h b/src/liblzma/common/outqueue.h
new file mode 100644
index 0000000..079634d
--- /dev/null
+++ b/src/liblzma/common/outqueue.h
@@ -0,0 +1,156 @@
+///////////////////////////////////////////////////////////////////////////////
+//
+/// \file       outqueue.h
+/// \brief      Output queue handling in multithreaded coding
+//
+//  Author:     Lasse Collin
+//
+//  This file has been put into the public domain.
+//  You can do whatever you want with this file.
+//
+///////////////////////////////////////////////////////////////////////////////
+
+#include "common.h"
+
+
+/// Output buffer for a single thread
+typedef struct {
+	/// Pointer to the output buffer of lzma_outq.buf_size_max bytes
+	uint8_t *buf;
+
+	/// Amount of data written to buf
+	size_t size;
+
+	/// Additional size information
+	lzma_vli unpadded_size;
+	lzma_vli uncompressed_size;
+
+	/// True when no more data will be written into this buffer.
+	///
+	/// \note       This is read by another thread and thus access
+	///             to this variable needs a mutex.
+	bool finished;
+
+} lzma_outbuf;
+
+
+typedef struct {
+	/// Array of buffers that are used cyclically.
+	lzma_outbuf *bufs;
+
+	/// Memory allocated for all the buffers
+	uint8_t *bufs_mem;
+
+	/// Amount of buffer space available in each buffer
+	size_t buf_size_max;
+
+	/// Number of buffers allocated
+	uint32_t bufs_allocated;
+
+	/// Position in the bufs array. The next buffer to be taken
+	/// into use is bufs[bufs_pos].
+	uint32_t bufs_pos;
+
+	/// Number of buffers in use
+	uint32_t bufs_used;
+
+	/// Position in the buffer in lzma_outq_read()
+	size_t read_pos;
+
+} lzma_outq;
+
+
+/**
+ * \brief       Calculate the memory usage of an output queue
+ *
+ * \return      Approximate memory usage in bytes or UINT64_MAX on error.
+ */
+extern uint64_t lzma_outq_memusage(uint64_t buf_size_max, uint32_t threads);
+
+
+/// \brief      Initialize an output queue
+///
+/// \param      outq            Pointer to an output queue. Before calling
+///                             this function the first time, *outq should
+///                             have been zeroed with memzero() so that this
+///                             function knows that there are no previous
+///                             allocations to free.
+/// \param      allocator       Pointer to allocator or NULL
+/// \param      buf_size_max    Maximum amount of data that a single buffer
+///                             in the queue may need to store.
+/// \param      threads         Number of buffers that may be in use
+///                             concurrently. Note that more than this number
+///                             of buffers will actually get allocated to
+///                             improve performance when buffers finish
+///                             out of order.
+///
+/// \return     - LZMA_OK
+///             - LZMA_MEM_ERROR
+///
+extern lzma_ret lzma_outq_init(
+		lzma_outq *outq, const lzma_allocator *allocator,
+		uint64_t buf_size_max, uint32_t threads);
+
+
+/// \brief      Free the memory associated with the output queue
+extern void lzma_outq_end(lzma_outq *outq, const lzma_allocator *allocator);
+
+
+/// \brief      Get a new buffer
+///
+/// lzma_outq_has_buf() must be used to check that there is a buffer
+/// available before calling lzma_outq_get_buf().
+///
+extern lzma_outbuf *lzma_outq_get_buf(lzma_outq *outq);
+
+
+/// \brief      Test if there is data ready to be read
+///
+/// Call to this function must be protected with the same mutex that
+/// is used to protect lzma_outbuf.finished.
+///
+extern bool lzma_outq_is_readable(const lzma_outq *outq);
+
+
+/// \brief      Read finished data
+///
+/// \param      outq            Pointer to an output queue
+/// \param      out             Beginning of the output buffer
+/// \param      out_pos         The next byte will be written to
+///                             out[*out_pos].
+/// \param      out_size        Size of the out buffer; the first byte into
+///                             which no data is written to is out[out_size].
+/// \param      unpadded_size   Unpadded Size from the Block encoder
+/// \param      uncompressed_size Uncompressed Size from the Block encoder
+///
+/// \return     - LZMA: All OK. Either no data was available or the buffer
+///               being read didn't become empty yet.
+///             - LZMA_STREAM_END: The buffer being read was finished.
+///               *unpadded_size and *uncompressed_size were set.
+///
+/// \note       This reads lzma_outbuf.finished variables and thus call
+///             to this function needs to be protected with a mutex.
+///
+extern lzma_ret lzma_outq_read(lzma_outq *restrict outq,
+		uint8_t *restrict out, size_t *restrict out_pos,
+		size_t out_size, lzma_vli *restrict unpadded_size,
+		lzma_vli *restrict uncompressed_size);
+
+
+/// \brief      Test if there is at least one buffer free
+///
+/// This must be used before getting a new buffer with lzma_outq_get_buf().
+///
+static inline bool
+lzma_outq_has_buf(const lzma_outq *outq)
+{
+	return outq->bufs_used < outq->bufs_allocated;
+}
+
+
+/// \brief      Test if the queue is completely empty
+static inline bool
+lzma_outq_is_empty(const lzma_outq *outq)
+{
+	return outq->bufs_used == 0;
+}
diff --git a/src/liblzma/common/stream_buffer_decoder.c b/src/liblzma/common/stream_buffer_decoder.c
index ae75315..b9745b5 100644
--- a/src/liblzma/common/stream_buffer_decoder.c
+++ b/src/liblzma/common/stream_buffer_decoder.c
@@ -15,7 +15,7 @@
 
 extern LZMA_API(lzma_ret)
 lzma_stream_buffer_decode(uint64_t *memlimit, uint32_t flags,
-		lzma_allocator *allocator,
+		const lzma_allocator *allocator,
 		const uint8_t *in, size_t *in_pos, size_t in_size,
 		uint8_t *out, size_t *out_pos, size_t out_size)
 {
diff --git a/src/liblzma/common/stream_buffer_encoder.c b/src/liblzma/common/stream_buffer_encoder.c
index 2450ee2..af49554 100644
--- a/src/liblzma/common/stream_buffer_encoder.c
+++ b/src/liblzma/common/stream_buffer_encoder.c
@@ -42,7 +42,8 @@
 
 extern LZMA_API(lzma_ret)
 lzma_stream_buffer_encode(lzma_filter *filters, lzma_check check,
-		lzma_allocator *allocator, const uint8_t *in, size_t in_size,
+		const lzma_allocator *allocator,
+		const uint8_t *in, size_t in_size,
 		uint8_t *out, size_t *out_pos_ptr, size_t out_size)
 {
 	// Sanity checks
diff --git a/src/liblzma/common/stream_decoder.c b/src/liblzma/common/stream_decoder.c
index 37ea71e..3ab938c 100644
--- a/src/liblzma/common/stream_decoder.c
+++ b/src/liblzma/common/stream_decoder.c
@@ -57,6 +57,10 @@
 	/// If true, LZMA_GET_CHECK is returned after decoding Stream Header.
 	bool tell_any_check;
 
+	/// If true, we will tell the Block decoder to skip calculating
+	/// and verifying the integrity check.
+	bool ignore_check;
+
 	/// If true, we will decode concatenated Streams that possibly have
 	/// Stream Padding between or after them. LZMA_STREAM_END is returned
 	/// once the application isn't giving us any new input, and we aren't
@@ -80,7 +84,7 @@
 
 
 static lzma_ret
-stream_decoder_reset(lzma_coder *coder, lzma_allocator *allocator)
+stream_decoder_reset(lzma_coder *coder, const lzma_allocator *allocator)
 {
 	// Initialize the Index hash used to verify the Index.
 	coder->index_hash = lzma_index_hash_init(coder->index_hash, allocator);
@@ -96,7 +100,7 @@
 
 
 static lzma_ret
-stream_decode(lzma_coder *coder, lzma_allocator *allocator,
+stream_decode(lzma_coder *coder, const lzma_allocator *allocator,
 		const uint8_t *restrict in, size_t *restrict in_pos,
 		size_t in_size, uint8_t *restrict out,
 		size_t *restrict out_pos, size_t out_size, lzma_action action)
@@ -182,8 +186,8 @@
 
 		coder->pos = 0;
 
-		// Version 0 is currently the only possible version.
-		coder->block_options.version = 0;
+		// Version 1 is needed to support the .ignore_check option.
+		coder->block_options.version = 1;
 
 		// Set up a buffer to hold the filter chain. Block Header
 		// decoder will initialize all members of this array so
@@ -195,6 +199,11 @@
 		return_if_error(lzma_block_header_decode(&coder->block_options,
 				allocator, coder->buffer));
 
+		// If LZMA_IGNORE_CHECK was used, this flag needs to be set.
+		// It has to be set after lzma_block_header_decode() because
+		// it always resets this to false.
+		coder->block_options.ignore_check = coder->ignore_check;
+
 		// Check the memory usage limit.
 		const uint64_t memusage = lzma_raw_decoder_memusage(filters);
 		lzma_ret ret;
@@ -366,7 +375,7 @@
 
 
 static void
-stream_decoder_end(lzma_coder *coder, lzma_allocator *allocator)
+stream_decoder_end(lzma_coder *coder, const lzma_allocator *allocator)
 {
 	lzma_next_end(&coder->block_decoder, allocator);
 	lzma_index_hash_end(coder->index_hash, allocator);
@@ -401,7 +410,8 @@
 
 
 extern lzma_ret
-lzma_stream_decoder_init(lzma_next_coder *next, lzma_allocator *allocator,
+lzma_stream_decoder_init(
+		lzma_next_coder *next, const lzma_allocator *allocator,
 		uint64_t memlimit, uint32_t flags)
 {
 	lzma_next_coder_init(&lzma_stream_decoder_init, next, allocator);
@@ -432,6 +442,7 @@
 	next->coder->tell_unsupported_check
 			= (flags & LZMA_TELL_UNSUPPORTED_CHECK) != 0;
 	next->coder->tell_any_check = (flags & LZMA_TELL_ANY_CHECK) != 0;
+	next->coder->ignore_check = (flags & LZMA_IGNORE_CHECK) != 0;
 	next->coder->concatenated = (flags & LZMA_CONCATENATED) != 0;
 	next->coder->first_stream = true;
 
diff --git a/src/liblzma/common/stream_decoder.h b/src/liblzma/common/stream_decoder.h
index e54ac28..c13c6ba 100644
--- a/src/liblzma/common/stream_decoder.h
+++ b/src/liblzma/common/stream_decoder.h
@@ -15,7 +15,8 @@
 
 #include "common.h"
 
-extern lzma_ret lzma_stream_decoder_init(lzma_next_coder *next,
-		lzma_allocator *allocator, uint64_t memlimit, uint32_t flags);
+extern lzma_ret lzma_stream_decoder_init(
+		lzma_next_coder *next, const lzma_allocator *allocator,
+		uint64_t memlimit, uint32_t flags);
 
 #endif
diff --git a/src/liblzma/common/stream_encoder.c b/src/liblzma/common/stream_encoder.c
index 2a97548..a7663bc 100644
--- a/src/liblzma/common/stream_encoder.c
+++ b/src/liblzma/common/stream_encoder.c
@@ -59,7 +59,7 @@
 
 
 static lzma_ret
-block_encoder_init(lzma_coder *coder, lzma_allocator *allocator)
+block_encoder_init(lzma_coder *coder, const lzma_allocator *allocator)
 {
 	// Prepare the Block options. Even though Block encoder doesn't need
 	// compressed_size, uncompressed_size, and header_size to be
@@ -78,7 +78,7 @@
 
 
 static lzma_ret
-stream_encode(lzma_coder *coder, lzma_allocator *allocator,
+stream_encode(lzma_coder *coder, const lzma_allocator *allocator,
 		const uint8_t *restrict in, size_t *restrict in_pos,
 		size_t in_size, uint8_t *restrict out,
 		size_t *restrict out_pos, size_t out_size, lzma_action action)
@@ -146,11 +146,12 @@
 	}
 
 	case SEQ_BLOCK_ENCODE: {
-		static const lzma_action convert[4] = {
+		static const lzma_action convert[LZMA_ACTION_MAX + 1] = {
 			LZMA_RUN,
 			LZMA_SYNC_FLUSH,
 			LZMA_FINISH,
 			LZMA_FINISH,
+			LZMA_FINISH,
 		};
 
 		const lzma_ret ret = coder->block_encoder.code(
@@ -208,7 +209,7 @@
 
 
 static void
-stream_encoder_end(lzma_coder *coder, lzma_allocator *allocator)
+stream_encoder_end(lzma_coder *coder, const lzma_allocator *allocator)
 {
 	lzma_next_end(&coder->block_encoder, allocator);
 	lzma_next_end(&coder->index_encoder, allocator);
@@ -223,7 +224,7 @@
 
 
 static lzma_ret
-stream_encoder_update(lzma_coder *coder, lzma_allocator *allocator,
+stream_encoder_update(lzma_coder *coder, const lzma_allocator *allocator,
 		const lzma_filter *filters,
 		const lzma_filter *reversed_filters)
 {
@@ -262,7 +263,7 @@
 
 
 static lzma_ret
-stream_encoder_init(lzma_next_coder *next, lzma_allocator *allocator,
+stream_encoder_init(lzma_next_coder *next, const lzma_allocator *allocator,
 		const lzma_filter *filters, lzma_check check)
 {
 	lzma_next_coder_init(&stream_encoder_init, next, allocator);
@@ -324,6 +325,7 @@
 	strm->internal->supported_actions[LZMA_RUN] = true;
 	strm->internal->supported_actions[LZMA_SYNC_FLUSH] = true;
 	strm->internal->supported_actions[LZMA_FULL_FLUSH] = true;
+	strm->internal->supported_actions[LZMA_FULL_BARRIER] = true;
 	strm->internal->supported_actions[LZMA_FINISH] = true;
 
 	return LZMA_OK;
diff --git a/src/liblzma/common/stream_encoder_mt.c b/src/liblzma/common/stream_encoder_mt.c
new file mode 100644
index 0000000..9780ed0
--- /dev/null
+++ b/src/liblzma/common/stream_encoder_mt.c
@@ -0,0 +1,1131 @@
+///////////////////////////////////////////////////////////////////////////////
+//
+/// \file       stream_encoder_mt.c
+/// \brief      Multithreaded .xz Stream encoder
+//
+//  Author:     Lasse Collin
+//
+//  This file has been put into the public domain.
+//  You can do whatever you want with this file.
+//
+///////////////////////////////////////////////////////////////////////////////
+
+#include "filter_encoder.h"
+#include "easy_preset.h"
+#include "block_encoder.h"
+#include "block_buffer_encoder.h"
+#include "index_encoder.h"
+#include "outqueue.h"
+
+
+/// Maximum supported block size. This makes it simpler to prevent integer
+/// overflows if we are given unusually large block size.
+#define BLOCK_SIZE_MAX (UINT64_MAX / LZMA_THREADS_MAX)
+
+
+typedef enum {
+	/// Waiting for work.
+	THR_IDLE,
+
+	/// Encoding is in progress.
+	THR_RUN,
+
+	/// Encoding is in progress but no more input data will
+	/// be read.
+	THR_FINISH,
+
+	/// The main thread wants the thread to stop whatever it was doing
+	/// but not exit.
+	THR_STOP,
+
+	/// The main thread wants the thread to exit. We could use
+	/// cancellation but since there's stopped anyway, this is lazier.
+	THR_EXIT,
+
+} worker_state;
+
+
+typedef struct worker_thread_s worker_thread;
+struct worker_thread_s {
+	worker_state state;
+
+	/// Input buffer of coder->block_size bytes. The main thread will
+	/// put new input into this and update in_size accordingly. Once
+	/// no more input is coming, state will be set to THR_FINISH.
+	uint8_t *in;
+
+	/// Amount of data available in the input buffer. This is modified
+	/// only by the main thread.
+	size_t in_size;
+
+	/// Output buffer for this thread. This is set by the main
+	/// thread every time a new Block is started with this thread
+	/// structure.
+	lzma_outbuf *outbuf;
+
+	/// Pointer to the main structure is needed when putting this
+	/// thread back to the stack of free threads.
+	lzma_coder *coder;
+
+	/// The allocator is set by the main thread. Since a copy of the
+	/// pointer is kept here, the application must not change the
+	/// allocator before calling lzma_end().
+	const lzma_allocator *allocator;
+
+	/// Amount of uncompressed data that has already been compressed.
+	uint64_t progress_in;
+
+	/// Amount of compressed data that is ready.
+	uint64_t progress_out;
+
+	/// Block encoder
+	lzma_next_coder block_encoder;
+
+	/// Compression options for this Block
+	lzma_block block_options;
+
+	/// Next structure in the stack of free worker threads.
+	worker_thread *next;
+
+	mythread_mutex mutex;
+	mythread_cond cond;
+
+	/// The ID of this thread is used to join the thread
+	/// when it's not needed anymore.
+	mythread thread_id;
+};
+
+
+struct lzma_coder_s {
+	enum {
+		SEQ_STREAM_HEADER,
+		SEQ_BLOCK,
+		SEQ_INDEX,
+		SEQ_STREAM_FOOTER,
+	} sequence;
+
+	/// Start a new Block every block_size bytes of input unless
+	/// LZMA_FULL_FLUSH or LZMA_FULL_BARRIER is used earlier.
+	size_t block_size;
+
+	/// The filter chain currently in use
+	lzma_filter filters[LZMA_FILTERS_MAX + 1];
+
+
+	/// Index to hold sizes of the Blocks
+	lzma_index *index;
+
+	/// Index encoder
+	lzma_next_coder index_encoder;
+
+
+	/// Stream Flags for encoding the Stream Header and Stream Footer.
+	lzma_stream_flags stream_flags;
+
+	/// Buffer to hold Stream Header and Stream Footer.
+	uint8_t header[LZMA_STREAM_HEADER_SIZE];
+
+	/// Read position in header[]
+	size_t header_pos;
+
+
+	/// Output buffer queue for compressed data
+	lzma_outq outq;
+
+
+	/// Maximum wait time if cannot use all the input and cannot
+	/// fill the output buffer. This is in milliseconds.
+	uint32_t timeout;
+
+
+	/// Error code from a worker thread
+	lzma_ret thread_error;
+
+	/// Array of allocated thread-specific structures
+	worker_thread *threads;
+
+	/// Number of structures in "threads" above. This is also the
+	/// number of threads that will be created at maximum.
+	uint32_t threads_max;
+
+	/// Number of thread structures that have been initialized, and
+	/// thus the number of worker threads actually created so far.
+	uint32_t threads_initialized;
+
+	/// Stack of free threads. When a thread finishes, it puts itself
+	/// back into this stack. This starts as empty because threads
+	/// are created only when actually needed.
+	worker_thread *threads_free;
+
+	/// The most recent worker thread to which the main thread writes
+	/// the new input from the application.
+	worker_thread *thr;
+
+
+	/// Amount of uncompressed data in Blocks that have already
+	/// been finished.
+	uint64_t progress_in;
+
+	/// Amount of compressed data in Stream Header + Blocks that
+	/// have already been finished.
+	uint64_t progress_out;
+
+
+	mythread_mutex mutex;
+	mythread_cond cond;
+};
+
+
+/// Tell the main thread that something has gone wrong.
+static void
+worker_error(worker_thread *thr, lzma_ret ret)
+{
+	assert(ret != LZMA_OK);
+	assert(ret != LZMA_STREAM_END);
+
+	mythread_sync(thr->coder->mutex) {
+		if (thr->coder->thread_error == LZMA_OK)
+			thr->coder->thread_error = ret;
+
+		mythread_cond_signal(&thr->coder->cond);
+	}
+
+	return;
+}
+
+
+static worker_state
+worker_encode(worker_thread *thr, worker_state state)
+{
+	assert(thr->progress_in == 0);
+	assert(thr->progress_out == 0);
+
+	// Set the Block options.
+	thr->block_options = (lzma_block){
+		.version = 0,
+		.check = thr->coder->stream_flags.check,
+		.compressed_size = thr->coder->outq.buf_size_max,
+		.uncompressed_size = thr->coder->block_size,
+
+		// TODO: To allow changing the filter chain, the filters
+		// array must be copied to each worker_thread.
+		.filters = thr->coder->filters,
+	};
+
+	// Calculate maximum size of the Block Header. This amount is
+	// reserved in the beginning of the buffer so that Block Header
+	// along with Compressed Size and Uncompressed Size can be
+	// written there.
+	lzma_ret ret = lzma_block_header_size(&thr->block_options);
+	if (ret != LZMA_OK) {
+		worker_error(thr, ret);
+		return THR_STOP;
+	}
+
+	// Initialize the Block encoder.
+	ret = lzma_block_encoder_init(&thr->block_encoder,
+			thr->allocator, &thr->block_options);
+	if (ret != LZMA_OK) {
+		worker_error(thr, ret);
+		return THR_STOP;
+	}
+
+	size_t in_pos = 0;
+	size_t in_size = 0;
+
+	thr->outbuf->size = thr->block_options.header_size;
+	const size_t out_size = thr->coder->outq.buf_size_max;
+
+	do {
+		mythread_sync(thr->mutex) {
+			// Store in_pos and out_pos into *thr so that
+			// an application may read them via
+			// lzma_get_progress() to get progress information.
+			//
+			// NOTE: These aren't updated when the encoding
+			// finishes. Instead, the final values are taken
+			// later from thr->outbuf.
+			thr->progress_in = in_pos;
+			thr->progress_out = thr->outbuf->size;
+
+			while (in_size == thr->in_size
+					&& thr->state == THR_RUN)
+				mythread_cond_wait(&thr->cond, &thr->mutex);
+
+			state = thr->state;
+			in_size = thr->in_size;
+		}
+
+		// Return if we were asked to stop or exit.
+		if (state >= THR_STOP)
+			return state;
+
+		lzma_action action = state == THR_FINISH
+				? LZMA_FINISH : LZMA_RUN;
+
+		// Limit the amount of input given to the Block encoder
+		// at once. This way this thread can react fairly quickly
+		// if the main thread wants us to stop or exit.
+		static const size_t in_chunk_max = 16384;
+		size_t in_limit = in_size;
+		if (in_size - in_pos > in_chunk_max) {
+			in_limit = in_pos + in_chunk_max;
+			action = LZMA_RUN;
+		}
+
+		ret = thr->block_encoder.code(
+				thr->block_encoder.coder, thr->allocator,
+				thr->in, &in_pos, in_limit, thr->outbuf->buf,
+				&thr->outbuf->size, out_size, action);
+	} while (ret == LZMA_OK && thr->outbuf->size < out_size);
+
+	switch (ret) {
+	case LZMA_STREAM_END:
+		assert(state == THR_FINISH);
+
+		// Encode the Block Header. By doing it after
+		// the compression, we can store the Compressed Size
+		// and Uncompressed Size fields.
+		ret = lzma_block_header_encode(&thr->block_options,
+				thr->outbuf->buf);
+		if (ret != LZMA_OK) {
+			worker_error(thr, ret);
+			return THR_STOP;
+		}
+
+		break;
+
+	case LZMA_OK:
+		// The data was incompressible. Encode it using uncompressed
+		// LZMA2 chunks.
+		//
+		// First wait that we have gotten all the input.
+		mythread_sync(thr->mutex) {
+			while (thr->state == THR_RUN)
+				mythread_cond_wait(&thr->cond, &thr->mutex);
+
+			state = thr->state;
+			in_size = thr->in_size;
+		}
+
+		if (state >= THR_STOP)
+			return state;
+
+		// Do the encoding. This takes care of the Block Header too.
+		thr->outbuf->size = 0;
+		ret = lzma_block_uncomp_encode(&thr->block_options,
+				thr->in, in_size, thr->outbuf->buf,
+				&thr->outbuf->size, out_size);
+
+		// It shouldn't fail.
+		if (ret != LZMA_OK) {
+			worker_error(thr, LZMA_PROG_ERROR);
+			return THR_STOP;
+		}
+
+		break;
+
+	default:
+		worker_error(thr, ret);
+		return THR_STOP;
+	}
+
+	// Set the size information that will be read by the main thread
+	// to write the Index field.
+	thr->outbuf->unpadded_size
+			= lzma_block_unpadded_size(&thr->block_options);
+	assert(thr->outbuf->unpadded_size != 0);
+	thr->outbuf->uncompressed_size = thr->block_options.uncompressed_size;
+
+	return THR_FINISH;
+}
+
+
+static MYTHREAD_RET_TYPE
+worker_start(void *thr_ptr)
+{
+	worker_thread *thr = thr_ptr;
+	worker_state state = THR_IDLE; // Init to silence a warning
+
+	while (true) {
+		// Wait for work.
+		mythread_sync(thr->mutex) {
+			while (true) {
+				// The thread is already idle so if we are
+				// requested to stop, just set the state.
+				if (thr->state == THR_STOP) {
+					thr->state = THR_IDLE;
+					mythread_cond_signal(&thr->cond);
+				}
+
+				state = thr->state;
+				if (state != THR_IDLE)
+					break;
+
+				mythread_cond_wait(&thr->cond, &thr->mutex);
+			}
+		}
+
+		assert(state != THR_IDLE);
+		assert(state != THR_STOP);
+
+		if (state <= THR_FINISH)
+			state = worker_encode(thr, state);
+
+		if (state == THR_EXIT)
+			break;
+
+		// Mark the thread as idle unless the main thread has
+		// told us to exit. Signal is needed for the case
+		// where the main thread is waiting for the threads to stop.
+		mythread_sync(thr->mutex) {
+			if (thr->state != THR_EXIT) {
+				thr->state = THR_IDLE;
+				mythread_cond_signal(&thr->cond);
+			}
+		}
+
+		mythread_sync(thr->coder->mutex) {
+			// Mark the output buffer as finished if
+			// no errors occurred.
+			thr->outbuf->finished = state == THR_FINISH;
+
+			// Update the main progress info.
+			thr->coder->progress_in
+					+= thr->outbuf->uncompressed_size;
+			thr->coder->progress_out += thr->outbuf->size;
+			thr->progress_in = 0;
+			thr->progress_out = 0;
+
+			// Return this thread to the stack of free threads.
+			thr->next = thr->coder->threads_free;
+			thr->coder->threads_free = thr;
+
+			mythread_cond_signal(&thr->coder->cond);
+		}
+	}
+
+	// Exiting, free the resources.
+	mythread_mutex_destroy(&thr->mutex);
+	mythread_cond_destroy(&thr->cond);
+
+	lzma_next_end(&thr->block_encoder, thr->allocator);
+	lzma_free(thr->in, thr->allocator);
+	return MYTHREAD_RET_VALUE;
+}
+
+
+/// Make the threads stop but not exit. Optionally wait for them to stop.
+static void
+threads_stop(lzma_coder *coder, bool wait_for_threads)
+{
+	// Tell the threads to stop.
+	for (uint32_t i = 0; i < coder->threads_initialized; ++i) {
+		mythread_sync(coder->threads[i].mutex) {
+			coder->threads[i].state = THR_STOP;
+			mythread_cond_signal(&coder->threads[i].cond);
+		}
+	}
+
+	if (!wait_for_threads)
+		return;
+
+	// Wait for the threads to settle in the idle state.
+	for (uint32_t i = 0; i < coder->threads_initialized; ++i) {
+		mythread_sync(coder->threads[i].mutex) {
+			while (coder->threads[i].state != THR_IDLE)
+				mythread_cond_wait(&coder->threads[i].cond,
+						&coder->threads[i].mutex);
+		}
+	}
+
+	return;
+}
+
+
+/// Stop the threads and free the resources associated with them.
+/// Wait until the threads have exited.
+static void
+threads_end(lzma_coder *coder, const lzma_allocator *allocator)
+{
+	for (uint32_t i = 0; i < coder->threads_initialized; ++i) {
+		mythread_sync(coder->threads[i].mutex) {
+			coder->threads[i].state = THR_EXIT;
+			mythread_cond_signal(&coder->threads[i].cond);
+		}
+	}
+
+	for (uint32_t i = 0; i < coder->threads_initialized; ++i) {
+		int ret = mythread_join(coder->threads[i].thread_id);
+		assert(ret == 0);
+		(void)ret;
+	}
+
+	lzma_free(coder->threads, allocator);
+	return;
+}
+
+
+/// Initialize a new worker_thread structure and create a new thread.
+static lzma_ret
+initialize_new_thread(lzma_coder *coder, const lzma_allocator *allocator)
+{
+	worker_thread *thr = &coder->threads[coder->threads_initialized];
+
+	thr->in = lzma_alloc(coder->block_size, allocator);
+	if (thr->in == NULL)
+		return LZMA_MEM_ERROR;
+
+	if (mythread_mutex_init(&thr->mutex))
+		goto error_mutex;
+
+	if (mythread_cond_init(&thr->cond))
+		goto error_cond;
+
+	thr->state = THR_IDLE;
+	thr->allocator = allocator;
+	thr->coder = coder;
+	thr->progress_in = 0;
+	thr->progress_out = 0;
+	thr->block_encoder = LZMA_NEXT_CODER_INIT;
+
+	if (mythread_create(&thr->thread_id, &worker_start, thr))
+		goto error_thread;
+
+	++coder->threads_initialized;
+	coder->thr = thr;
+
+	return LZMA_OK;
+
+error_thread:
+	mythread_cond_destroy(&thr->cond);
+
+error_cond:
+	mythread_mutex_destroy(&thr->mutex);
+
+error_mutex:
+	lzma_free(thr->in, allocator);
+	return LZMA_MEM_ERROR;
+}
+
+
+static lzma_ret
+get_thread(lzma_coder *coder, const lzma_allocator *allocator)
+{
+	// If there are no free output subqueues, there is no
+	// point to try getting a thread.
+	if (!lzma_outq_has_buf(&coder->outq))
+		return LZMA_OK;
+
+	// If there is a free structure on the stack, use it.
+	mythread_sync(coder->mutex) {
+		if (coder->threads_free != NULL) {
+			coder->thr = coder->threads_free;
+			coder->threads_free = coder->threads_free->next;
+		}
+	}
+
+	if (coder->thr == NULL) {
+		// If there are no uninitialized structures left, return.
+		if (coder->threads_initialized == coder->threads_max)
+			return LZMA_OK;
+
+		// Initialize a new thread.
+		return_if_error(initialize_new_thread(coder, allocator));
+	}
+
+	// Reset the parts of the thread state that have to be done
+	// in the main thread.
+	mythread_sync(coder->thr->mutex) {
+		coder->thr->state = THR_RUN;
+		coder->thr->in_size = 0;
+		coder->thr->outbuf = lzma_outq_get_buf(&coder->outq);
+		mythread_cond_signal(&coder->thr->cond);
+	}
+
+	return LZMA_OK;
+}
+
+
+static lzma_ret
+stream_encode_in(lzma_coder *coder, const lzma_allocator *allocator,
+		const uint8_t *restrict in, size_t *restrict in_pos,
+		size_t in_size, lzma_action action)
+{
+	while (*in_pos < in_size
+			|| (coder->thr != NULL && action != LZMA_RUN)) {
+		if (coder->thr == NULL) {
+			// Get a new thread.
+			const lzma_ret ret = get_thread(coder, allocator);
+			if (coder->thr == NULL)
+				return ret;
+		}
+
+		// Copy the input data to thread's buffer.
+		size_t thr_in_size = coder->thr->in_size;
+		lzma_bufcpy(in, in_pos, in_size, coder->thr->in,
+				&thr_in_size, coder->block_size);
+
+		// Tell the Block encoder to finish if
+		//  - it has got block_size bytes of input; or
+		//  - all input was used and LZMA_FINISH, LZMA_FULL_FLUSH,
+		//    or LZMA_FULL_BARRIER was used.
+		//
+		// TODO: LZMA_SYNC_FLUSH and LZMA_SYNC_BARRIER.
+		const bool finish = thr_in_size == coder->block_size
+				|| (*in_pos == in_size && action != LZMA_RUN);
+
+		bool block_error = false;
+
+		mythread_sync(coder->thr->mutex) {
+			if (coder->thr->state == THR_IDLE) {
+				// Something has gone wrong with the Block
+				// encoder. It has set coder->thread_error
+				// which we will read a few lines later.
+				block_error = true;
+			} else {
+				// Tell the Block encoder its new amount
+				// of input and update the state if needed.
+				coder->thr->in_size = thr_in_size;
+
+				if (finish)
+					coder->thr->state = THR_FINISH;
+
+				mythread_cond_signal(&coder->thr->cond);
+			}
+		}
+
+		if (block_error) {
+			lzma_ret ret;
+
+			mythread_sync(coder->mutex) {
+				ret = coder->thread_error;
+			}
+
+			return ret;
+		}
+
+		if (finish)
+			coder->thr = NULL;
+	}
+
+	return LZMA_OK;
+}
+
+
+/// Wait until more input can be consumed, more output can be read, or
+/// an optional timeout is reached.
+static bool
+wait_for_work(lzma_coder *coder, mythread_condtime *wait_abs,
+		bool *has_blocked, bool has_input)
+{
+	if (coder->timeout != 0 && !*has_blocked) {
+		// Every time when stream_encode_mt() is called via
+		// lzma_code(), *has_blocked starts as false. We set it
+		// to true here and calculate the absolute time when
+		// we must return if there's nothing to do.
+		//
+		// The idea of *has_blocked is to avoid unneeded calls
+		// to mythread_condtime_set(), which may do a syscall
+		// depending on the operating system.
+		*has_blocked = true;
+		mythread_condtime_set(wait_abs, &coder->cond, coder->timeout);
+	}
+
+	bool timed_out = false;
+
+	mythread_sync(coder->mutex) {
+		// There are four things that we wait. If one of them
+		// becomes possible, we return.
+		//  - If there is input left, we need to get a free
+		//    worker thread and an output buffer for it.
+		//  - Data ready to be read from the output queue.
+		//  - A worker thread indicates an error.
+		//  - Time out occurs.
+		while ((!has_input || coder->threads_free == NULL
+					|| !lzma_outq_has_buf(&coder->outq))
+				&& !lzma_outq_is_readable(&coder->outq)
+				&& coder->thread_error == LZMA_OK
+				&& !timed_out) {
+			if (coder->timeout != 0)
+				timed_out = mythread_cond_timedwait(
+						&coder->cond, &coder->mutex,
+						wait_abs) != 0;
+			else
+				mythread_cond_wait(&coder->cond,
+						&coder->mutex);
+		}
+	}
+
+	return timed_out;
+}
+
+
+static lzma_ret
+stream_encode_mt(lzma_coder *coder, const lzma_allocator *allocator,
+		const uint8_t *restrict in, size_t *restrict in_pos,
+		size_t in_size, uint8_t *restrict out,
+		size_t *restrict out_pos, size_t out_size, lzma_action action)
+{
+	switch (coder->sequence) {
+	case SEQ_STREAM_HEADER:
+		lzma_bufcpy(coder->header, &coder->header_pos,
+				sizeof(coder->header),
+				out, out_pos, out_size);
+		if (coder->header_pos < sizeof(coder->header))
+			return LZMA_OK;
+
+		coder->header_pos = 0;
+		coder->sequence = SEQ_BLOCK;
+
+	// Fall through
+
+	case SEQ_BLOCK: {
+		// Initialized to silence warnings.
+		lzma_vli unpadded_size = 0;
+		lzma_vli uncompressed_size = 0;
+		lzma_ret ret = LZMA_OK;
+
+		// These are for wait_for_work().
+		bool has_blocked = false;
+		mythread_condtime wait_abs;
+
+		while (true) {
+			mythread_sync(coder->mutex) {
+				// Check for Block encoder errors.
+				ret = coder->thread_error;
+				if (ret != LZMA_OK) {
+					assert(ret != LZMA_STREAM_END);
+					break;
+				}
+
+				// Try to read compressed data to out[].
+				ret = lzma_outq_read(&coder->outq,
+						out, out_pos, out_size,
+						&unpadded_size,
+						&uncompressed_size);
+			}
+
+			if (ret == LZMA_STREAM_END) {
+				// End of Block. Add it to the Index.
+				ret = lzma_index_append(coder->index,
+						allocator, unpadded_size,
+						uncompressed_size);
+
+				// If we didn't fill the output buffer yet,
+				// try to read more data. Maybe the next
+				// outbuf has been finished already too.
+				if (*out_pos < out_size)
+					continue;
+			}
+
+			if (ret != LZMA_OK) {
+				// coder->thread_error was set or
+				// lzma_index_append() failed.
+				threads_stop(coder, false);
+				return ret;
+			}
+
+			// Try to give uncompressed data to a worker thread.
+			ret = stream_encode_in(coder, allocator,
+					in, in_pos, in_size, action);
+			if (ret != LZMA_OK) {
+				threads_stop(coder, false);
+				return ret;
+			}
+
+			// See if we should wait or return.
+			//
+			// TODO: LZMA_SYNC_FLUSH and LZMA_SYNC_BARRIER.
+			if (*in_pos == in_size) {
+				// LZMA_RUN: More data is probably coming
+				// so return to let the caller fill the
+				// input buffer.
+				if (action == LZMA_RUN)
+					return LZMA_OK;
+
+				// LZMA_FULL_BARRIER: The same as with
+				// LZMA_RUN but tell the caller that the
+				// barrier was completed.
+				if (action == LZMA_FULL_BARRIER)
+					return LZMA_STREAM_END;
+
+				// Finishing or flushing isn't completed until
+				// all input data has been encoded and copied
+				// to the output buffer.
+				if (lzma_outq_is_empty(&coder->outq)) {
+					// LZMA_FINISH: Continue to encode
+					// the Index field.
+					if (action == LZMA_FINISH)
+						break;
+
+					// LZMA_FULL_FLUSH: Return to tell
+					// the caller that flushing was
+					// completed.
+					if (action == LZMA_FULL_FLUSH)
+						return LZMA_STREAM_END;
+				}
+			}
+
+			// Return if there is no output space left.
+			// This check must be done after testing the input
+			// buffer, because we might want to use a different
+			// return code.
+			if (*out_pos == out_size)
+				return LZMA_OK;
+
+			// Neither in nor out has been used completely.
+			// Wait until there's something we can do.
+			if (wait_for_work(coder, &wait_abs, &has_blocked,
+					*in_pos < in_size))
+				return LZMA_TIMED_OUT;
+		}
+
+		// All Blocks have been encoded and the threads have stopped.
+		// Prepare to encode the Index field.
+		return_if_error(lzma_index_encoder_init(
+				&coder->index_encoder, allocator,
+				coder->index));
+		coder->sequence = SEQ_INDEX;
+
+		// Update the progress info to take the Index and
+		// Stream Footer into account. Those are very fast to encode
+		// so in terms of progress information they can be thought
+		// to be ready to be copied out.
+		coder->progress_out += lzma_index_size(coder->index)
+				+ LZMA_STREAM_HEADER_SIZE;
+	}
+
+	// Fall through
+
+	case SEQ_INDEX: {
+		// Call the Index encoder. It doesn't take any input, so
+		// those pointers can be NULL.
+		const lzma_ret ret = coder->index_encoder.code(
+				coder->index_encoder.coder, allocator,
+				NULL, NULL, 0,
+				out, out_pos, out_size, LZMA_RUN);
+		if (ret != LZMA_STREAM_END)
+			return ret;
+
+		// Encode the Stream Footer into coder->buffer.
+		coder->stream_flags.backward_size
+				= lzma_index_size(coder->index);
+		if (lzma_stream_footer_encode(&coder->stream_flags,
+				coder->header) != LZMA_OK)
+			return LZMA_PROG_ERROR;
+
+		coder->sequence = SEQ_STREAM_FOOTER;
+	}
+
+	// Fall through
+
+	case SEQ_STREAM_FOOTER:
+		lzma_bufcpy(coder->header, &coder->header_pos,
+				sizeof(coder->header),
+				out, out_pos, out_size);
+		return coder->header_pos < sizeof(coder->header)
+				? LZMA_OK : LZMA_STREAM_END;
+	}
+
+	assert(0);
+	return LZMA_PROG_ERROR;
+}
+
+
+static void
+stream_encoder_mt_end(lzma_coder *coder, const lzma_allocator *allocator)
+{
+	// Threads must be killed before the output queue can be freed.
+	threads_end(coder, allocator);
+	lzma_outq_end(&coder->outq, allocator);
+
+	for (size_t i = 0; coder->filters[i].id != LZMA_VLI_UNKNOWN; ++i)
+		lzma_free(coder->filters[i].options, allocator);
+
+	lzma_next_end(&coder->index_encoder, allocator);
+	lzma_index_end(coder->index, allocator);
+
+	mythread_cond_destroy(&coder->cond);
+	mythread_mutex_destroy(&coder->mutex);
+
+	lzma_free(coder, allocator);
+	return;
+}
+
+
+/// Options handling for lzma_stream_encoder_mt_init() and
+/// lzma_stream_encoder_mt_memusage()
+static lzma_ret
+get_options(const lzma_mt *options, lzma_options_easy *opt_easy,
+		const lzma_filter **filters, uint64_t *block_size,
+		uint64_t *outbuf_size_max)
+{
+	// Validate some of the options.
+	if (options == NULL)
+		return LZMA_PROG_ERROR;
+
+	if (options->flags != 0 || options->threads == 0
+			|| options->threads > LZMA_THREADS_MAX)
+		return LZMA_OPTIONS_ERROR;
+
+	if (options->filters != NULL) {
+		// Filter chain was given, use it as is.
+		*filters = options->filters;
+	} else {
+		// Use a preset.
+		if (lzma_easy_preset(opt_easy, options->preset))
+			return LZMA_OPTIONS_ERROR;
+
+		*filters = opt_easy->filters;
+	}
+
+	// Block size
+	if (options->block_size > 0) {
+		if (options->block_size > BLOCK_SIZE_MAX)
+			return LZMA_OPTIONS_ERROR;
+
+		*block_size = options->block_size;
+	} else {
+		// Determine the Block size from the filter chain.
+		*block_size = lzma_mt_block_size(*filters);
+		if (*block_size == 0)
+			return LZMA_OPTIONS_ERROR;
+
+		assert(*block_size <= BLOCK_SIZE_MAX);
+	}
+
+	// Calculate the maximum amount output that a single output buffer
+	// may need to hold. This is the same as the maximum total size of
+	// a Block.
+	*outbuf_size_max = lzma_block_buffer_bound64(*block_size);
+	if (*outbuf_size_max == 0)
+		return LZMA_MEM_ERROR;
+
+	return LZMA_OK;
+}
+
+
+static void
+get_progress(lzma_coder *coder, uint64_t *progress_in, uint64_t *progress_out)
+{
+	// Lock coder->mutex to prevent finishing threads from moving their
+	// progress info from the worker_thread structure to lzma_coder.
+	mythread_sync(coder->mutex) {
+		*progress_in = coder->progress_in;
+		*progress_out = coder->progress_out;
+
+		for (size_t i = 0; i < coder->threads_initialized; ++i) {
+			mythread_sync(coder->threads[i].mutex) {
+				*progress_in += coder->threads[i].progress_in;
+				*progress_out += coder->threads[i]
+						.progress_out;
+			}
+		}
+	}
+
+	return;
+}
+
+
+static lzma_ret
+stream_encoder_mt_init(lzma_next_coder *next, const lzma_allocator *allocator,
+		const lzma_mt *options)
+{
+	lzma_next_coder_init(&stream_encoder_mt_init, next, allocator);
+
+	// Get the filter chain.
+	lzma_options_easy easy;
+	const lzma_filter *filters;
+	uint64_t block_size;
+	uint64_t outbuf_size_max;
+	return_if_error(get_options(options, &easy, &filters,
+			&block_size, &outbuf_size_max));
+
+#if SIZE_MAX < UINT64_MAX
+	if (block_size > SIZE_MAX)
+		return LZMA_MEM_ERROR;
+#endif
+
+	// Validate the filter chain so that we can give an error in this
+	// function instead of delaying it to the first call to lzma_code().
+	// The memory usage calculation verifies the filter chain as
+	// a side effect so we take advatange of that.
+	if (lzma_raw_encoder_memusage(filters) == UINT64_MAX)
+		return LZMA_OPTIONS_ERROR;
+
+	// Validate the Check ID.
+	if ((unsigned int)(options->check) > LZMA_CHECK_ID_MAX)
+		return LZMA_PROG_ERROR;
+
+	if (!lzma_check_is_supported(options->check))
+		return LZMA_UNSUPPORTED_CHECK;
+
+	// Allocate and initialize the base structure if needed.
+	if (next->coder == NULL) {
+		next->coder = lzma_alloc(sizeof(lzma_coder), allocator);
+		if (next->coder == NULL)
+			return LZMA_MEM_ERROR;
+
+		// For the mutex and condition variable initializations
+		// the error handling has to be done here because
+		// stream_encoder_mt_end() doesn't know if they have
+		// already been initialized or not.
+		if (mythread_mutex_init(&next->coder->mutex)) {
+			lzma_free(next->coder, allocator);
+			next->coder = NULL;
+			return LZMA_MEM_ERROR;
+		}
+
+		if (mythread_cond_init(&next->coder->cond)) {
+			mythread_mutex_destroy(&next->coder->mutex);
+			lzma_free(next->coder, allocator);
+			next->coder = NULL;
+			return LZMA_MEM_ERROR;
+		}
+
+		next->code = &stream_encode_mt;
+		next->end = &stream_encoder_mt_end;
+		next->get_progress = &get_progress;
+// 		next->update = &stream_encoder_mt_update;
+
+		next->coder->filters[0].id = LZMA_VLI_UNKNOWN;
+		next->coder->index_encoder = LZMA_NEXT_CODER_INIT;
+		next->coder->index = NULL;
+		memzero(&next->coder->outq, sizeof(next->coder->outq));
+		next->coder->threads = NULL;
+		next->coder->threads_max = 0;
+		next->coder->threads_initialized = 0;
+	}
+
+	// Basic initializations
+	next->coder->sequence = SEQ_STREAM_HEADER;
+	next->coder->block_size = (size_t)(block_size);
+	next->coder->thread_error = LZMA_OK;
+	next->coder->thr = NULL;
+
+	// Allocate the thread-specific base structures.
+	assert(options->threads > 0);
+	if (next->coder->threads_max != options->threads) {
+		threads_end(next->coder, allocator);
+
+		next->coder->threads = NULL;
+		next->coder->threads_max = 0;
+
+		next->coder->threads_initialized = 0;
+		next->coder->threads_free = NULL;
+
+		next->coder->threads = lzma_alloc(
+				options->threads * sizeof(worker_thread),
+				allocator);
+		if (next->coder->threads == NULL)
+			return LZMA_MEM_ERROR;
+
+		next->coder->threads_max = options->threads;
+	} else {
+		// Reuse the old structures and threads. Tell the running
+		// threads to stop and wait until they have stopped.
+		threads_stop(next->coder, true);
+	}
+
+	// Output queue
+	return_if_error(lzma_outq_init(&next->coder->outq, allocator,
+			outbuf_size_max, options->threads));
+
+	// Timeout
+	next->coder->timeout = options->timeout;
+
+	// Free the old filter chain and copy the new one.
+	for (size_t i = 0; next->coder->filters[i].id != LZMA_VLI_UNKNOWN; ++i)
+		lzma_free(next->coder->filters[i].options, allocator);
+
+	return_if_error(lzma_filters_copy(
+			filters, next->coder->filters, allocator));
+
+	// Index
+	lzma_index_end(next->coder->index, allocator);
+	next->coder->index = lzma_index_init(allocator);
+	if (next->coder->index == NULL)
+		return LZMA_MEM_ERROR;
+
+	// Stream Header
+	next->coder->stream_flags.version = 0;
+	next->coder->stream_flags.check = options->check;
+	return_if_error(lzma_stream_header_encode(
+			&next->coder->stream_flags, next->coder->header));
+
+	next->coder->header_pos = 0;
+
+	// Progress info
+	next->coder->progress_in = 0;
+	next->coder->progress_out = LZMA_STREAM_HEADER_SIZE;
+
+	return LZMA_OK;
+}
+
+
+extern LZMA_API(lzma_ret)
+lzma_stream_encoder_mt(lzma_stream *strm, const lzma_mt *options)
+{
+	lzma_next_strm_init(stream_encoder_mt_init, strm, options);
+
+	strm->internal->supported_actions[LZMA_RUN] = true;
+// 	strm->internal->supported_actions[LZMA_SYNC_FLUSH] = true;
+	strm->internal->supported_actions[LZMA_FULL_FLUSH] = true;
+	strm->internal->supported_actions[LZMA_FULL_BARRIER] = true;
+	strm->internal->supported_actions[LZMA_FINISH] = true;
+
+	return LZMA_OK;
+}
+
+
+// This function name is a monster but it's consistent with the older
+// monster names. :-( 31 chars is the max that C99 requires so in that
+// sense it's not too long. ;-)
+extern LZMA_API(uint64_t)
+lzma_stream_encoder_mt_memusage(const lzma_mt *options)
+{
+	lzma_options_easy easy;
+	const lzma_filter *filters;
+	uint64_t block_size;
+	uint64_t outbuf_size_max;
+
+	if (get_options(options, &easy, &filters, &block_size,
+			&outbuf_size_max) != LZMA_OK)
+		return UINT64_MAX;
+
+	// Memory usage of the input buffers
+	const uint64_t inbuf_memusage = options->threads * block_size;
+
+	// Memory usage of the filter encoders
+	uint64_t filters_memusage = lzma_raw_encoder_memusage(filters);
+	if (filters_memusage == UINT64_MAX)
+		return UINT64_MAX;
+
+	filters_memusage *= options->threads;
+
+	// Memory usage of the output queue
+	const uint64_t outq_memusage = lzma_outq_memusage(
+			outbuf_size_max, options->threads);
+	if (outq_memusage == UINT64_MAX)
+		return UINT64_MAX;
+
+	// Sum them with overflow checking.
+	uint64_t total_memusage = LZMA_MEMUSAGE_BASE + sizeof(lzma_coder)
+			+ options->threads * sizeof(worker_thread);
+
+	if (UINT64_MAX - total_memusage < inbuf_memusage)
+		return UINT64_MAX;
+
+	total_memusage += inbuf_memusage;
+
+	if (UINT64_MAX - total_memusage < filters_memusage)
+		return UINT64_MAX;
+
+	total_memusage += filters_memusage;
+
+	if (UINT64_MAX - total_memusage < outq_memusage)
+		return UINT64_MAX;
+
+	return total_memusage + outq_memusage;
+}
diff --git a/src/liblzma/delta/delta_common.c b/src/liblzma/delta/delta_common.c
index 930ad21..13dd468 100644
--- a/src/liblzma/delta/delta_common.c
+++ b/src/liblzma/delta/delta_common.c
@@ -15,7 +15,7 @@
 
 
 static void
-delta_coder_end(lzma_coder *coder, lzma_allocator *allocator)
+delta_coder_end(lzma_coder *coder, const lzma_allocator *allocator)
 {
 	lzma_next_end(&coder->next, allocator);
 	lzma_free(coder, allocator);
@@ -24,7 +24,7 @@
 
 
 extern lzma_ret
-lzma_delta_coder_init(lzma_next_coder *next, lzma_allocator *allocator,
+lzma_delta_coder_init(lzma_next_coder *next, const lzma_allocator *allocator,
 		const lzma_filter_info *filters)
 {
 	// Allocate memory for the decoder if needed.
diff --git a/src/liblzma/delta/delta_decoder.c b/src/liblzma/delta/delta_decoder.c
index 2cf60d5..726d023 100644
--- a/src/liblzma/delta/delta_decoder.c
+++ b/src/liblzma/delta/delta_decoder.c
@@ -27,7 +27,7 @@
 
 
 static lzma_ret
-delta_decode(lzma_coder *coder, lzma_allocator *allocator,
+delta_decode(lzma_coder *coder, const lzma_allocator *allocator,
 		const uint8_t *restrict in, size_t *restrict in_pos,
 		size_t in_size, uint8_t *restrict out,
 		size_t *restrict out_pos, size_t out_size, lzma_action action)
@@ -47,7 +47,7 @@
 
 
 extern lzma_ret
-lzma_delta_decoder_init(lzma_next_coder *next, lzma_allocator *allocator,
+lzma_delta_decoder_init(lzma_next_coder *next, const lzma_allocator *allocator,
 		const lzma_filter_info *filters)
 {
 	next->code = &delta_decode;
@@ -56,7 +56,7 @@
 
 
 extern lzma_ret
-lzma_delta_props_decode(void **options, lzma_allocator *allocator,
+lzma_delta_props_decode(void **options, const lzma_allocator *allocator,
 		const uint8_t *props, size_t props_size)
 {
 	if (props_size != 1)
diff --git a/src/liblzma/delta/delta_decoder.h b/src/liblzma/delta/delta_decoder.h
index ae89acc..ad89cc6 100644
--- a/src/liblzma/delta/delta_decoder.h
+++ b/src/liblzma/delta/delta_decoder.h
@@ -16,10 +16,11 @@
 #include "delta_common.h"
 
 extern lzma_ret lzma_delta_decoder_init(lzma_next_coder *next,
-		lzma_allocator *allocator, const lzma_filter_info *filters);
+		const lzma_allocator *allocator,
+		const lzma_filter_info *filters);
 
 extern lzma_ret lzma_delta_props_decode(
-		void **options, lzma_allocator *allocator,
+		void **options, const lzma_allocator *allocator,
 		const uint8_t *props, size_t props_size);
 
 #endif
diff --git a/src/liblzma/delta/delta_encoder.c b/src/liblzma/delta/delta_encoder.c
index 15c7951..5a84263 100644
--- a/src/liblzma/delta/delta_encoder.c
+++ b/src/liblzma/delta/delta_encoder.c
@@ -49,7 +49,7 @@
 
 
 static lzma_ret
-delta_encode(lzma_coder *coder, lzma_allocator *allocator,
+delta_encode(lzma_coder *coder, const lzma_allocator *allocator,
 		const uint8_t *restrict in, size_t *restrict in_pos,
 		size_t in_size, uint8_t *restrict out,
 		size_t *restrict out_pos, size_t out_size, lzma_action action)
@@ -84,7 +84,7 @@
 
 
 static lzma_ret
-delta_encoder_update(lzma_coder *coder, lzma_allocator *allocator,
+delta_encoder_update(lzma_coder *coder, const lzma_allocator *allocator,
 		const lzma_filter *filters_null lzma_attribute((__unused__)),
 		const lzma_filter *reversed_filters)
 {
@@ -97,7 +97,7 @@
 
 
 extern lzma_ret
-lzma_delta_encoder_init(lzma_next_coder *next, lzma_allocator *allocator,
+lzma_delta_encoder_init(lzma_next_coder *next, const lzma_allocator *allocator,
 		const lzma_filter_info *filters)
 {
 	next->code = &delta_encode;
diff --git a/src/liblzma/delta/delta_encoder.h b/src/liblzma/delta/delta_encoder.h
index a447862..4ab9847 100644
--- a/src/liblzma/delta/delta_encoder.h
+++ b/src/liblzma/delta/delta_encoder.h
@@ -16,7 +16,8 @@
 #include "delta_common.h"
 
 extern lzma_ret lzma_delta_encoder_init(lzma_next_coder *next,
-		lzma_allocator *allocator, const lzma_filter_info *filters);
+		const lzma_allocator *allocator,
+		const lzma_filter_info *filters);
 
 extern lzma_ret lzma_delta_props_encode(const void *options, uint8_t *out);
 
diff --git a/src/liblzma/delta/delta_private.h b/src/liblzma/delta/delta_private.h
index 62b7fed..46ce0c6 100644
--- a/src/liblzma/delta/delta_private.h
+++ b/src/liblzma/delta/delta_private.h
@@ -31,7 +31,7 @@
 
 
 extern lzma_ret lzma_delta_coder_init(
-		lzma_next_coder *next, lzma_allocator *allocator,
+		lzma_next_coder *next, const lzma_allocator *allocator,
 		const lzma_filter_info *filters);
 
 #endif
diff --git a/src/liblzma/liblzma.map b/src/liblzma/liblzma.map
index 47a7c22..f53a4ea 100644
--- a/src/liblzma/liblzma.map
+++ b/src/liblzma/liblzma.map
@@ -93,7 +93,16 @@
 	lzma_vli_decode;
 	lzma_vli_encode;
 	lzma_vli_size;
+};
+
+XZ_5.2 {
+global:
+	lzma_block_uncomp_encode;
+	lzma_cputhreads;
+	lzma_get_progress;
+	lzma_stream_encoder_mt;
+	lzma_stream_encoder_mt_memusage;
 
 local:
 	*;
-};
+} XZ_5.0;
diff --git a/src/liblzma/lz/lz_decoder.c b/src/liblzma/lz/lz_decoder.c
index d74085c..2328a8e 100644
--- a/src/liblzma/lz/lz_decoder.c
+++ b/src/liblzma/lz/lz_decoder.c
@@ -126,7 +126,7 @@
 
 static lzma_ret
 lz_decode(lzma_coder *coder,
-		lzma_allocator *allocator lzma_attribute((__unused__)),
+		const lzma_allocator *allocator lzma_attribute((__unused__)),
 		const uint8_t *restrict in, size_t *restrict in_pos,
 		size_t in_size, uint8_t *restrict out,
 		size_t *restrict out_pos, size_t out_size,
@@ -184,7 +184,7 @@
 
 
 static void
-lz_decoder_end(lzma_coder *coder, lzma_allocator *allocator)
+lz_decoder_end(lzma_coder *coder, const lzma_allocator *allocator)
 {
 	lzma_next_end(&coder->next, allocator);
 	lzma_free(coder->dict.buf, allocator);
@@ -200,10 +200,10 @@
 
 
 extern lzma_ret
-lzma_lz_decoder_init(lzma_next_coder *next, lzma_allocator *allocator,
+lzma_lz_decoder_init(lzma_next_coder *next, const lzma_allocator *allocator,
 		const lzma_filter_info *filters,
 		lzma_ret (*lz_init)(lzma_lz_decoder *lz,
-			lzma_allocator *allocator, const void *options,
+			const lzma_allocator *allocator, const void *options,
 			lzma_lz_options *lz_options))
 {
 	// Allocate the base structure if it isn't already allocated.
diff --git a/src/liblzma/lz/lz_decoder.h b/src/liblzma/lz/lz_decoder.h
index 7266e80..277900a 100644
--- a/src/liblzma/lz/lz_decoder.h
+++ b/src/liblzma/lz/lz_decoder.h
@@ -67,7 +67,7 @@
 			lzma_vli uncompressed_size);
 
 	/// Free allocated resources
-	void (*end)(lzma_coder *coder, lzma_allocator *allocator);
+	void (*end)(lzma_coder *coder, const lzma_allocator *allocator);
 
 } lzma_lz_decoder;
 
@@ -83,9 +83,10 @@
 
 
 extern lzma_ret lzma_lz_decoder_init(lzma_next_coder *next,
-		lzma_allocator *allocator, const lzma_filter_info *filters,
+		const lzma_allocator *allocator,
+		const lzma_filter_info *filters,
 		lzma_ret (*lz_init)(lzma_lz_decoder *lz,
-			lzma_allocator *allocator, const void *options,
+			const lzma_allocator *allocator, const void *options,
 			lzma_lz_options *lz_options));
 
 extern uint64_t lzma_lz_decoder_memusage(size_t dictionary_size);
diff --git a/src/liblzma/lz/lz_encoder.c b/src/liblzma/lz/lz_encoder.c
index e240696..48bc487 100644
--- a/src/liblzma/lz/lz_encoder.c
+++ b/src/liblzma/lz/lz_encoder.c
@@ -20,6 +20,8 @@
 #	include "lz_encoder_hash_table.h"
 #endif
 
+#include "memcmplen.h"
+
 
 struct lzma_coder_s {
 	/// LZ-based encoder e.g. LZMA
@@ -76,8 +78,9 @@
 /// This function must not be called once it has returned LZMA_STREAM_END.
 ///
 static lzma_ret
-fill_window(lzma_coder *coder, lzma_allocator *allocator, const uint8_t *in,
-		size_t *in_pos, size_t in_size, lzma_action action)
+fill_window(lzma_coder *coder, const lzma_allocator *allocator,
+		const uint8_t *in, size_t *in_pos, size_t in_size,
+		lzma_action action)
 {
 	assert(coder->mf.read_pos <= coder->mf.write_pos);
 
@@ -107,6 +110,12 @@
 
 	coder->mf.write_pos = write_pos;
 
+	// Silence Valgrind. lzma_memcmplen() can read extra bytes
+	// and Valgrind will give warnings if those bytes are uninitialized
+	// because Valgrind cannot see that the values of the uninitialized
+	// bytes are eventually ignored.
+	memzero(coder->mf.buffer + write_pos, LZMA_MEMCMPLEN_EXTRA);
+
 	// If end of stream has been reached or flushing completed, we allow
 	// the encoder to process all the input (that is, read_pos is allowed
 	// to reach write_pos). Otherwise we keep keep_size_after bytes
@@ -130,7 +139,7 @@
 			&& coder->mf.read_pos < coder->mf.read_limit) {
 		// Match finder may update coder->pending and expects it to
 		// start from zero, so use a temporary variable.
-		const size_t pending = coder->mf.pending;
+		const uint32_t pending = coder->mf.pending;
 		coder->mf.pending = 0;
 
 		// Rewind read_pos so that the match finder can hash
@@ -148,7 +157,7 @@
 
 
 static lzma_ret
-lz_encode(lzma_coder *coder, lzma_allocator *allocator,
+lz_encode(lzma_coder *coder, const lzma_allocator *allocator,
 		const uint8_t *restrict in, size_t *restrict in_pos,
 		size_t in_size,
 		uint8_t *restrict out, size_t *restrict out_pos,
@@ -179,7 +188,7 @@
 
 
 static bool
-lz_encoder_prepare(lzma_mf *mf, lzma_allocator *allocator,
+lz_encoder_prepare(lzma_mf *mf, const lzma_allocator *allocator,
 		const lzma_lz_options *lz_options)
 {
 	// For now, the dictionary size is limited to 1.5 GiB. This may grow
@@ -325,25 +334,22 @@
 		hs += HASH_4_SIZE;
 */
 
-	// If the above code calculating hs is modified, make sure that
-	// this assertion stays valid (UINT32_MAX / 5 is not strictly the
-	// exact limit). If it doesn't, you need to calculate that
-	// hash_size_sum + sons_count cannot overflow.
-	assert(hs < UINT32_MAX / 5);
-
-	const uint32_t old_count = mf->hash_size_sum + mf->sons_count;
-	mf->hash_size_sum = hs;
+	const uint32_t old_hash_count = mf->hash_count;
+	const uint32_t old_sons_count = mf->sons_count;
+	mf->hash_count = hs;
 	mf->sons_count = mf->cyclic_size;
 	if (is_bt)
 		mf->sons_count *= 2;
 
-	const uint32_t new_count = mf->hash_size_sum + mf->sons_count;
-
 	// Deallocate the old hash array if it exists and has different size
 	// than what is needed now.
-	if (old_count != new_count) {
+	if (old_hash_count != mf->hash_count
+			|| old_sons_count != mf->sons_count) {
 		lzma_free(mf->hash, allocator);
 		mf->hash = NULL;
+
+		lzma_free(mf->son, allocator);
+		mf->son = NULL;
 	}
 
 	// Maximum number of match finder cycles
@@ -360,14 +366,23 @@
 
 
 static bool
-lz_encoder_init(lzma_mf *mf, lzma_allocator *allocator,
+lz_encoder_init(lzma_mf *mf, const lzma_allocator *allocator,
 		const lzma_lz_options *lz_options)
 {
 	// Allocate the history buffer.
 	if (mf->buffer == NULL) {
-		mf->buffer = lzma_alloc(mf->size, allocator);
+		// lzma_memcmplen() is used for the dictionary buffer
+		// so we need to allocate a few extra bytes to prevent
+		// it from reading past the end of the buffer.
+		mf->buffer = lzma_alloc(mf->size + LZMA_MEMCMPLEN_EXTRA,
+				allocator);
 		if (mf->buffer == NULL)
 			return true;
+
+		// Keep Valgrind happy with lzma_memcmplen() and initialize
+		// the extra bytes whose value may get read but which will
+		// effectively get ignored.
+		memzero(mf->buffer + mf->size, LZMA_MEMCMPLEN_EXTRA);
 	}
 
 	// Use cyclic_size as initial mf->offset. This allows
@@ -381,44 +396,49 @@
 	mf->write_pos = 0;
 	mf->pending = 0;
 
-	// Allocate match finder's hash array.
-	const size_t alloc_count = mf->hash_size_sum + mf->sons_count;
-
 #if UINT32_MAX >= SIZE_MAX / 4
 	// Check for integer overflow. (Huge dictionaries are not
 	// possible on 32-bit CPU.)
-	if (alloc_count > SIZE_MAX / sizeof(uint32_t))
+	if (mf->hash_count > SIZE_MAX / sizeof(uint32_t)
+			|| mf->sons_count > SIZE_MAX / sizeof(uint32_t))
 		return true;
 #endif
 
+	// Allocate and initialize the hash table. Since EMPTY_HASH_VALUE
+	// is zero, we can use lzma_alloc_zero() or memzero() for mf->hash.
+	//
+	// We don't need to initialize mf->son, but not doing that may
+	// make Valgrind complain in normalization (see normalize() in
+	// lz_encoder_mf.c). Skipping the initialization is *very* good
+	// when big dictionary is used but only small amount of data gets
+	// actually compressed: most of the mf->son won't get actually
+	// allocated by the kernel, so we avoid wasting RAM and improve
+	// initialization speed a lot.
 	if (mf->hash == NULL) {
-		mf->hash = lzma_alloc(alloc_count * sizeof(uint32_t),
+		mf->hash = lzma_alloc_zero(mf->hash_count * sizeof(uint32_t),
 				allocator);
-		if (mf->hash == NULL)
+		mf->son = lzma_alloc(mf->sons_count * sizeof(uint32_t),
+				allocator);
+
+		if (mf->hash == NULL || mf->son == NULL) {
+			lzma_free(mf->hash, allocator);
+			mf->hash = NULL;
+
+			lzma_free(mf->son, allocator);
+			mf->son = NULL;
+
 			return true;
+		}
+	} else {
+/*
+		for (uint32_t i = 0; i < mf->hash_count; ++i)
+			mf->hash[i] = EMPTY_HASH_VALUE;
+*/
+		memzero(mf->hash, mf->hash_count * sizeof(uint32_t));
 	}
 
-	mf->son = mf->hash + mf->hash_size_sum;
 	mf->cyclic_pos = 0;
 
-	// Initialize the hash table. Since EMPTY_HASH_VALUE is zero, we
-	// can use memset().
-/*
-	for (uint32_t i = 0; i < hash_size_sum; ++i)
-		mf->hash[i] = EMPTY_HASH_VALUE;
-*/
-	memzero(mf->hash, (size_t)(mf->hash_size_sum) * sizeof(uint32_t));
-
-	// We don't need to initialize mf->son, but not doing that will
-	// make Valgrind complain in normalization (see normalize() in
-	// lz_encoder_mf.c).
-	//
-	// Skipping this initialization is *very* good when big dictionary is
-	// used but only small amount of data gets actually compressed: most
-	// of the mf->hash won't get actually allocated by the kernel, so
-	// we avoid wasting RAM and improve initialization speed a lot.
-	//memzero(mf->son, (size_t)(mf->sons_count) * sizeof(uint32_t));
-
 	// Handle preset dictionary.
 	if (lz_options->preset_dict != NULL
 			&& lz_options->preset_dict_size > 0) {
@@ -445,7 +465,8 @@
 	lzma_mf mf = {
 		.buffer = NULL,
 		.hash = NULL,
-		.hash_size_sum = 0,
+		.son = NULL,
+		.hash_count = 0,
 		.sons_count = 0,
 	};
 
@@ -454,17 +475,17 @@
 		return UINT64_MAX;
 
 	// Calculate the memory usage.
-	return (uint64_t)(mf.hash_size_sum + mf.sons_count)
-				* sizeof(uint32_t)
-			+ (uint64_t)(mf.size) + sizeof(lzma_coder);
+	return ((uint64_t)(mf.hash_count) + mf.sons_count) * sizeof(uint32_t)
+			+ mf.size + sizeof(lzma_coder);
 }
 
 
 static void
-lz_encoder_end(lzma_coder *coder, lzma_allocator *allocator)
+lz_encoder_end(lzma_coder *coder, const lzma_allocator *allocator)
 {
 	lzma_next_end(&coder->next, allocator);
 
+	lzma_free(coder->mf.son, allocator);
 	lzma_free(coder->mf.hash, allocator);
 	lzma_free(coder->mf.buffer, allocator);
 
@@ -479,7 +500,7 @@
 
 
 static lzma_ret
-lz_encoder_update(lzma_coder *coder, lzma_allocator *allocator,
+lz_encoder_update(lzma_coder *coder, const lzma_allocator *allocator,
 		const lzma_filter *filters_null lzma_attribute((__unused__)),
 		const lzma_filter *reversed_filters)
 {
@@ -495,10 +516,10 @@
 
 
 extern lzma_ret
-lzma_lz_encoder_init(lzma_next_coder *next, lzma_allocator *allocator,
+lzma_lz_encoder_init(lzma_next_coder *next, const lzma_allocator *allocator,
 		const lzma_filter_info *filters,
 		lzma_ret (*lz_init)(lzma_lz_encoder *lz,
-			lzma_allocator *allocator, const void *options,
+			const lzma_allocator *allocator, const void *options,
 			lzma_lz_options *lz_options))
 {
 #ifdef HAVE_SMALL
@@ -522,7 +543,8 @@
 
 		next->coder->mf.buffer = NULL;
 		next->coder->mf.hash = NULL;
-		next->coder->mf.hash_size_sum = 0;
+		next->coder->mf.son = NULL;
+		next->coder->mf.hash_count = 0;
 		next->coder->mf.sons_count = 0;
 
 		next->coder->next = LZMA_NEXT_CODER_INIT;
diff --git a/src/liblzma/lz/lz_encoder.h b/src/liblzma/lz/lz_encoder.h
index 741c453..dad9c6b 100644
--- a/src/liblzma/lz/lz_encoder.h
+++ b/src/liblzma/lz/lz_encoder.h
@@ -119,7 +119,7 @@
 	lzma_action action;
 
 	/// Number of elements in hash[]
-	uint32_t hash_size_sum;
+	uint32_t hash_count;
 
 	/// Number of elements in son[]
 	uint32_t sons_count;
@@ -199,7 +199,7 @@
 			size_t *restrict out_pos, size_t out_size);
 
 	/// Free allocated resources
-	void (*end)(lzma_coder *coder, lzma_allocator *allocator);
+	void (*end)(lzma_coder *coder, const lzma_allocator *allocator);
 
 	/// Update the options in the middle of the encoding.
 	lzma_ret (*options_update)(lzma_coder *coder,
@@ -296,10 +296,10 @@
 
 
 extern lzma_ret lzma_lz_encoder_init(
-		lzma_next_coder *next, lzma_allocator *allocator,
+		lzma_next_coder *next, const lzma_allocator *allocator,
 		const lzma_filter_info *filters,
 		lzma_ret (*lz_init)(lzma_lz_encoder *lz,
-			lzma_allocator *allocator, const void *options,
+			const lzma_allocator *allocator, const void *options,
 			lzma_lz_options *lz_options));
 
 
diff --git a/src/liblzma/lz/lz_encoder_mf.c b/src/liblzma/lz/lz_encoder_mf.c
index f82a1c1..7852077 100644
--- a/src/liblzma/lz/lz_encoder_mf.c
+++ b/src/liblzma/lz/lz_encoder_mf.c
@@ -13,6 +13,7 @@
 
 #include "lz_encoder.h"
 #include "lz_encoder_hash.h"
+#include "memcmplen.h"
 
 
 /// \brief      Find matches starting from the current byte
@@ -65,9 +66,7 @@
 			// here because the match distances are zero based.
 			const uint8_t *p2 = p1 - matches[count - 1].dist - 1;
 
-			while (len_best < limit
-					&& p1[len_best] == p2[len_best])
-				++len_best;
+			len_best = lzma_memcmplen(p1, p2, len_best, limit);
 		}
 	}
 
@@ -116,24 +115,27 @@
 			= (MUST_NORMALIZE_POS - mf->cyclic_size);
 				// & (~(UINT32_C(1) << 10) - 1);
 
-	const uint32_t count = mf->hash_size_sum + mf->sons_count;
-	uint32_t *hash = mf->hash;
-
-	for (uint32_t i = 0; i < count; ++i) {
+	for (uint32_t i = 0; i < mf->hash_count; ++i) {
 		// If the distance is greater than the dictionary size,
 		// we can simply mark the hash element as empty.
-		//
-		// NOTE: Only the first mf->hash_size_sum elements are
-		// initialized for sure. There may be uninitialized elements
-		// in mf->son. Since we go through both mf->hash and
-		// mf->son here in normalization, Valgrind may complain
-		// that the "if" below depends on uninitialized value. In
-		// this case it is safe to ignore the warning. See also the
-		// comments in lz_encoder_init() in lz_encoder.c.
-		if (hash[i] <= subvalue)
-			hash[i] = EMPTY_HASH_VALUE;
+		if (mf->hash[i] <= subvalue)
+			mf->hash[i] = EMPTY_HASH_VALUE;
 		else
-			hash[i] -= subvalue;
+			mf->hash[i] -= subvalue;
+	}
+
+	for (uint32_t i = 0; i < mf->sons_count; ++i) {
+		// Do the same for mf->son.
+		//
+		// NOTE: There may be uninitialized elements in mf->son.
+		// Valgrind may complain that the "if" below depends on
+		// an uninitialized value. In this case it is safe to ignore
+		// the warning. See also the comments in lz_encoder_init()
+		// in lz_encoder.c.
+		if (mf->son[i] <= subvalue)
+			mf->son[i] = EMPTY_HASH_VALUE;
+		else
+			mf->son[i] -= subvalue;
 	}
 
 	// Update offset to match the new locations.
@@ -269,10 +271,7 @@
 				+ (delta > cyclic_pos ? cyclic_size : 0)];
 
 		if (pb[len_best] == cur[len_best] && pb[0] == cur[0]) {
-			uint32_t len = 0;
-			while (++len != len_limit)
-				if (pb[len] != cur[len])
-					break;
+			uint32_t len = lzma_memcmplen(pb, cur, 1, len_limit);
 
 			if (len_best < len) {
 				len_best = len;
@@ -318,9 +317,8 @@
 	uint32_t len_best = 2;
 
 	if (delta2 < mf->cyclic_size && *(cur - delta2) == *cur) {
-		for ( ; len_best != len_limit; ++len_best)
-			if (*(cur + len_best - delta2) != cur[len_best])
-				break;
+		len_best = lzma_memcmplen(cur - delta2, cur,
+				len_best, len_limit);
 
 		matches[0].len = len_best;
 		matches[0].dist = delta2 - 1;
@@ -397,9 +395,8 @@
 	}
 
 	if (matches_count != 0) {
-		for ( ; len_best != len_limit; ++len_best)
-			if (*(cur + len_best - delta2) != cur[len_best])
-				break;
+		len_best = lzma_memcmplen(cur - delta2, cur,
+				len_best, len_limit);
 
 		matches[matches_count - 1].len = len_best;
 
@@ -484,9 +481,7 @@
 		uint32_t len = my_min(len0, len1);
 
 		if (pb[len] == cur[len]) {
-			while (++len != len_limit)
-				if (pb[len] != cur[len])
-					break;
+			len = lzma_memcmplen(pb, cur, len + 1, len_limit);
 
 			if (len_best < len) {
 				len_best = len;
@@ -549,9 +544,7 @@
 		uint32_t len = my_min(len0, len1);
 
 		if (pb[len] == cur[len]) {
-			while (++len != len_limit)
-				if (pb[len] != cur[len])
-					break;
+			len = lzma_memcmplen(pb, cur, len + 1, len_limit);
 
 			if (len == len_limit) {
 				*ptr1 = pair[0];
@@ -639,9 +632,8 @@
 	uint32_t len_best = 2;
 
 	if (delta2 < mf->cyclic_size && *(cur - delta2) == *cur) {
-		for ( ; len_best != len_limit; ++len_best)
-			if (*(cur + len_best - delta2) != cur[len_best])
-				break;
+		len_best = lzma_memcmplen(
+				cur, cur - delta2, len_best, len_limit);
 
 		matches[0].len = len_best;
 		matches[0].dist = delta2 - 1;
@@ -712,9 +704,8 @@
 	}
 
 	if (matches_count != 0) {
-		for ( ; len_best != len_limit; ++len_best)
-			if (*(cur + len_best - delta2) != cur[len_best])
-				break;
+		len_best = lzma_memcmplen(
+				cur, cur - delta2, len_best, len_limit);
 
 		matches[matches_count - 1].len = len_best;
 
diff --git a/src/liblzma/lzma/lzma2_decoder.c b/src/liblzma/lzma/lzma2_decoder.c
index 3e42575..84982d2 100644
--- a/src/liblzma/lzma/lzma2_decoder.c
+++ b/src/liblzma/lzma/lzma2_decoder.c
@@ -209,7 +209,7 @@
 
 
 static void
-lzma2_decoder_end(lzma_coder *coder, lzma_allocator *allocator)
+lzma2_decoder_end(lzma_coder *coder, const lzma_allocator *allocator)
 {
 	assert(coder->lzma.end == NULL);
 	lzma_free(coder->lzma.coder, allocator);
@@ -221,7 +221,7 @@
 
 
 static lzma_ret
-lzma2_decoder_init(lzma_lz_decoder *lz, lzma_allocator *allocator,
+lzma2_decoder_init(lzma_lz_decoder *lz, const lzma_allocator *allocator,
 		const void *opt, lzma_lz_options *lz_options)
 {
 	if (lz->coder == NULL) {
@@ -248,7 +248,7 @@
 
 
 extern lzma_ret
-lzma_lzma2_decoder_init(lzma_next_coder *next, lzma_allocator *allocator,
+lzma_lzma2_decoder_init(lzma_next_coder *next, const lzma_allocator *allocator,
 		const lzma_filter_info *filters)
 {
 	// LZMA2 can only be the last filter in the chain. This is enforced
@@ -269,7 +269,7 @@
 
 
 extern lzma_ret
-lzma_lzma2_props_decode(void **options, lzma_allocator *allocator,
+lzma_lzma2_props_decode(void **options, const lzma_allocator *allocator,
 		const uint8_t *props, size_t props_size)
 {
 	if (props_size != 1)
diff --git a/src/liblzma/lzma/lzma2_decoder.h b/src/liblzma/lzma/lzma2_decoder.h
index fac4ac4..ef2dcbf 100644
--- a/src/liblzma/lzma/lzma2_decoder.h
+++ b/src/liblzma/lzma/lzma2_decoder.h
@@ -17,12 +17,13 @@
 #include "common.h"
 
 extern lzma_ret lzma_lzma2_decoder_init(lzma_next_coder *next,
-		lzma_allocator *allocator, const lzma_filter_info *filters);
+		const lzma_allocator *allocator,
+		const lzma_filter_info *filters);
 
 extern uint64_t lzma_lzma2_decoder_memusage(const void *options);
 
 extern lzma_ret lzma_lzma2_props_decode(
-		void **options, lzma_allocator *allocator,
+		void **options, const lzma_allocator *allocator,
 		const uint8_t *props, size_t props_size);
 
 #endif
diff --git a/src/liblzma/lzma/lzma2_encoder.c b/src/liblzma/lzma/lzma2_encoder.c
index 7f6bc63..b6756bf 100644
--- a/src/liblzma/lzma/lzma2_encoder.c
+++ b/src/liblzma/lzma/lzma2_encoder.c
@@ -262,7 +262,7 @@
 
 
 static void
-lzma2_encoder_end(lzma_coder *coder, lzma_allocator *allocator)
+lzma2_encoder_end(lzma_coder *coder, const lzma_allocator *allocator)
 {
 	lzma_free(coder->lzma, allocator);
 	lzma_free(coder, allocator);
@@ -304,7 +304,7 @@
 
 
 static lzma_ret
-lzma2_encoder_init(lzma_lz_encoder *lz, lzma_allocator *allocator,
+lzma2_encoder_init(lzma_lz_encoder *lz, const lzma_allocator *allocator,
 		const void *options, lzma_lz_options *lz_options)
 {
 	if (options == NULL)
@@ -349,7 +349,7 @@
 
 
 extern lzma_ret
-lzma_lzma2_encoder_init(lzma_next_coder *next, lzma_allocator *allocator,
+lzma_lzma2_encoder_init(lzma_next_coder *next, const lzma_allocator *allocator,
 		const lzma_filter_info *filters)
 {
 	return lzma_lz_encoder_init(
diff --git a/src/liblzma/lzma/lzma2_encoder.h b/src/liblzma/lzma/lzma2_encoder.h
index 1288136..515f183 100644
--- a/src/liblzma/lzma/lzma2_encoder.h
+++ b/src/liblzma/lzma/lzma2_encoder.h
@@ -31,7 +31,7 @@
 
 
 extern lzma_ret lzma_lzma2_encoder_init(
-		lzma_next_coder *next, lzma_allocator *allocator,
+		lzma_next_coder *next, const lzma_allocator *allocator,
 		const lzma_filter_info *filters);
 
 extern uint64_t lzma_lzma2_encoder_memusage(const void *options);
diff --git a/src/liblzma/lzma/lzma_decoder.c b/src/liblzma/lzma/lzma_decoder.c
index b6f1b6a..b8f9317 100644
--- a/src/liblzma/lzma/lzma_decoder.c
+++ b/src/liblzma/lzma/lzma_decoder.c
@@ -937,7 +937,7 @@
 
 
 extern lzma_ret
-lzma_lzma_decoder_create(lzma_lz_decoder *lz, lzma_allocator *allocator,
+lzma_lzma_decoder_create(lzma_lz_decoder *lz, const lzma_allocator *allocator,
 		const void *opt, lzma_lz_options *lz_options)
 {
 	if (lz->coder == NULL) {
@@ -965,7 +965,7 @@
 /// initialization (lzma_lzma_decoder_init() passes function pointer to
 /// the LZ initialization).
 static lzma_ret
-lzma_decoder_init(lzma_lz_decoder *lz, lzma_allocator *allocator,
+lzma_decoder_init(lzma_lz_decoder *lz, const lzma_allocator *allocator,
 		const void *options, lzma_lz_options *lz_options)
 {
 	if (!is_lclppb_valid(options))
@@ -982,7 +982,7 @@
 
 
 extern lzma_ret
-lzma_lzma_decoder_init(lzma_next_coder *next, lzma_allocator *allocator,
+lzma_lzma_decoder_init(lzma_next_coder *next, const lzma_allocator *allocator,
 		const lzma_filter_info *filters)
 {
 	// LZMA can only be the last filter in the chain. This is enforced
@@ -1029,7 +1029,7 @@
 
 
 extern lzma_ret
-lzma_lzma_props_decode(void **options, lzma_allocator *allocator,
+lzma_lzma_props_decode(void **options, const lzma_allocator *allocator,
 		const uint8_t *props, size_t props_size)
 {
 	if (props_size != 5)
diff --git a/src/liblzma/lzma/lzma_decoder.h b/src/liblzma/lzma/lzma_decoder.h
index a463a76..fa8ecb2 100644
--- a/src/liblzma/lzma/lzma_decoder.h
+++ b/src/liblzma/lzma/lzma_decoder.h
@@ -19,12 +19,13 @@
 
 /// Allocates and initializes LZMA decoder
 extern lzma_ret lzma_lzma_decoder_init(lzma_next_coder *next,
-		lzma_allocator *allocator, const lzma_filter_info *filters);
+		const lzma_allocator *allocator,
+		const lzma_filter_info *filters);
 
 extern uint64_t lzma_lzma_decoder_memusage(const void *options);
 
 extern lzma_ret lzma_lzma_props_decode(
-		void **options, lzma_allocator *allocator,
+		void **options, const lzma_allocator *allocator,
 		const uint8_t *props, size_t props_size);
 
 
@@ -40,7 +41,7 @@
 /// Allocate and setup function pointers only. This is used by LZMA1 and
 /// LZMA2 decoders.
 extern lzma_ret lzma_lzma_decoder_create(
-		lzma_lz_decoder *lz, lzma_allocator *allocator,
+		lzma_lz_decoder *lz, const lzma_allocator *allocator,
 		const void *opt, lzma_lz_options *lz_options);
 
 /// Gets memory usage without validating lc/lp/pb. This is used by LZMA2
diff --git a/src/liblzma/lzma/lzma_encoder.c b/src/liblzma/lzma/lzma_encoder.c
index 0f91653..4c5f99c 100644
--- a/src/liblzma/lzma/lzma_encoder.c
+++ b/src/liblzma/lzma/lzma_encoder.c
@@ -464,7 +464,7 @@
 	bittree_reset(lencoder->high, LEN_HIGH_BITS);
 
 	if (!fast_mode)
-		for (size_t pos_state = 0; pos_state < num_pos_states;
+		for (uint32_t pos_state = 0; pos_state < num_pos_states;
 				++pos_state)
 			length_update_prices(lencoder, pos_state);
 
@@ -545,7 +545,8 @@
 
 
 extern lzma_ret
-lzma_lzma_encoder_create(lzma_coder **coder_ptr, lzma_allocator *allocator,
+lzma_lzma_encoder_create(lzma_coder **coder_ptr,
+		const lzma_allocator *allocator,
 		const lzma_options_lzma *options, lzma_lz_options *lz_options)
 {
 	// Allocate lzma_coder if it wasn't already allocated.
@@ -604,7 +605,7 @@
 
 
 static lzma_ret
-lzma_encoder_init(lzma_lz_encoder *lz, lzma_allocator *allocator,
+lzma_encoder_init(lzma_lz_encoder *lz, const lzma_allocator *allocator,
 		const void *options, lzma_lz_options *lz_options)
 {
 	lz->code = &lzma_encode;
@@ -614,7 +615,7 @@
 
 
 extern lzma_ret
-lzma_lzma_encoder_init(lzma_next_coder *next, lzma_allocator *allocator,
+lzma_lzma_encoder_init(lzma_next_coder *next, const lzma_allocator *allocator,
 		const lzma_filter_info *filters)
 {
 	return lzma_lz_encoder_init(
diff --git a/src/liblzma/lzma/lzma_encoder.h b/src/liblzma/lzma/lzma_encoder.h
index 835e1f5..cc9cc2f 100644
--- a/src/liblzma/lzma/lzma_encoder.h
+++ b/src/liblzma/lzma/lzma_encoder.h
@@ -18,7 +18,8 @@
 
 
 extern lzma_ret lzma_lzma_encoder_init(lzma_next_coder *next,
-		lzma_allocator *allocator, const lzma_filter_info *filters);
+		const lzma_allocator *allocator,
+		const lzma_filter_info *filters);
 
 
 extern uint64_t lzma_lzma_encoder_memusage(const void *options);
@@ -35,7 +36,7 @@
 
 /// Initializes raw LZMA encoder; this is used by LZMA2.
 extern lzma_ret lzma_lzma_encoder_create(
-		lzma_coder **coder_ptr, lzma_allocator *allocator,
+		lzma_coder **coder_ptr, const lzma_allocator *allocator,
 		const lzma_options_lzma *options, lzma_lz_options *lz_options);
 
 
diff --git a/src/liblzma/lzma/lzma_encoder_optimum_fast.c b/src/liblzma/lzma/lzma_encoder_optimum_fast.c
index 92bbdf7..9b30347 100644
--- a/src/liblzma/lzma/lzma_encoder_optimum_fast.c
+++ b/src/liblzma/lzma/lzma_encoder_optimum_fast.c
@@ -10,6 +10,7 @@
 ///////////////////////////////////////////////////////////////////////////////
 
 #include "lzma_encoder_private.h"
+#include "memcmplen.h"
 
 
 #define change_pair(small_dist, big_dist) \
@@ -57,9 +58,8 @@
 
 		// The first two bytes matched.
 		// Calculate the length of the match.
-		uint32_t len;
-		for (len = 2; len < buf_avail
-				&& buf[len] == buf_back[len]; ++len) ;
+		const uint32_t len = lzma_memcmplen(
+				buf, buf_back, 2, buf_avail);
 
 		// If we have found a repeated match that is at least
 		// nice_len long, return it immediately.
@@ -152,19 +152,10 @@
 	// the old buf pointer instead of recalculating it with mf_ptr().
 	++buf;
 
-	const uint32_t limit = len_main - 1;
+	const uint32_t limit = my_max(2, len_main - 1);
 
 	for (uint32_t i = 0; i < REPS; ++i) {
-		const uint8_t *const buf_back = buf - coder->reps[i] - 1;
-
-		if (not_equal_16(buf, buf_back))
-			continue;
-
-		uint32_t len;
-		for (len = 2; len < limit
-				&& buf[len] == buf_back[len]; ++len) ;
-
-		if (len >= limit) {
+		if (memcmp(buf, buf - coder->reps[i] - 1, limit) == 0) {
 			*back_res = UINT32_MAX;
 			*len_res = 1;
 			return;
diff --git a/src/liblzma/lzma/lzma_encoder_optimum_normal.c b/src/liblzma/lzma/lzma_encoder_optimum_normal.c
index 0dd5f73..a360579 100644
--- a/src/liblzma/lzma/lzma_encoder_optimum_normal.c
+++ b/src/liblzma/lzma/lzma_encoder_optimum_normal.c
@@ -11,6 +11,7 @@
 
 #include "lzma_encoder_private.h"
 #include "fastpos.h"
+#include "memcmplen.h"
 
 
 ////////////
@@ -305,13 +306,9 @@
 			continue;
 		}
 
-		uint32_t len_test;
-		for (len_test = 2; len_test < buf_avail
-				&& buf[len_test] == buf_back[len_test];
-				++len_test) ;
+		rep_lens[i] = lzma_memcmplen(buf, buf_back, 2, buf_avail);
 
-		rep_lens[i] = len_test;
-		if (len_test > rep_lens[rep_max_index])
+		if (rep_lens[i] > rep_lens[rep_max_index])
 			rep_max_index = i;
 	}
 
@@ -568,11 +565,7 @@
 		const uint8_t *const buf_back = buf - reps[0] - 1;
 		const uint32_t limit = my_min(buf_avail_full, nice_len + 1);
 
-		uint32_t len_test = 1;
-		while (len_test < limit && buf[len_test] == buf_back[len_test])
-			++len_test;
-
-		--len_test;
+		const uint32_t len_test = lzma_memcmplen(buf, buf_back, 1, limit) - 1;
 
 		if (len_test >= 2) {
 			lzma_lzma_state state_2 = state;
@@ -612,10 +605,7 @@
 		if (not_equal_16(buf, buf_back))
 			continue;
 
-		uint32_t len_test;
-		for (len_test = 2; len_test < buf_avail
-				&& buf[len_test] == buf_back[len_test];
-				++len_test) ;
+		uint32_t len_test = lzma_memcmplen(buf, buf_back, 2, buf_avail);
 
 		while (len_end < cur + len_test)
 			coder->opts[++len_end].price = RC_INFINITY_PRICE;
diff --git a/src/liblzma/lzma/lzma_encoder_presets.c b/src/liblzma/lzma/lzma_encoder_presets.c
index 21e427a..8484b77 100644
--- a/src/liblzma/lzma/lzma_encoder_presets.c
+++ b/src/liblzma/lzma/lzma_encoder_presets.c
@@ -30,14 +30,16 @@
 	options->lp = LZMA_LP_DEFAULT;
 	options->pb = LZMA_PB_DEFAULT;
 
-	options->dict_size = UINT32_C(1) << (uint8_t []){
-			18, 20, 21, 22, 22, 23, 23, 24, 25, 26 }[level];
+	static const uint8_t dict_pow2[]
+			= { 18, 20, 21, 22, 22, 23, 23, 24, 25, 26 };
+	options->dict_size = UINT32_C(1) << dict_pow2[level];
 
 	if (level <= 3) {
 		options->mode = LZMA_MODE_FAST;
 		options->mf = level == 0 ? LZMA_MF_HC3 : LZMA_MF_HC4;
 		options->nice_len = level <= 1 ? 128 : 273;
-		options->depth = (uint8_t []){ 4, 8, 24, 48 }[level];
+		static const uint8_t depths[] = { 4, 8, 24, 48 };
+		options->depth = depths[level];
 	} else {
 		options->mode = LZMA_MODE_NORMAL;
 		options->mf = LZMA_MF_BT4;
diff --git a/src/liblzma/simple/arm.c b/src/liblzma/simple/arm.c
index a84702a..258d870 100644
--- a/src/liblzma/simple/arm.c
+++ b/src/liblzma/simple/arm.c
@@ -45,7 +45,7 @@
 
 
 static lzma_ret
-arm_coder_init(lzma_next_coder *next, lzma_allocator *allocator,
+arm_coder_init(lzma_next_coder *next, const lzma_allocator *allocator,
 		const lzma_filter_info *filters, bool is_encoder)
 {
 	return lzma_simple_coder_init(next, allocator, filters,
@@ -54,7 +54,8 @@
 
 
 extern lzma_ret
-lzma_simple_arm_encoder_init(lzma_next_coder *next, lzma_allocator *allocator,
+lzma_simple_arm_encoder_init(lzma_next_coder *next,
+		const lzma_allocator *allocator,
 		const lzma_filter_info *filters)
 {
 	return arm_coder_init(next, allocator, filters, true);
@@ -62,7 +63,8 @@
 
 
 extern lzma_ret
-lzma_simple_arm_decoder_init(lzma_next_coder *next, lzma_allocator *allocator,
+lzma_simple_arm_decoder_init(lzma_next_coder *next,
+		const lzma_allocator *allocator,
 		const lzma_filter_info *filters)
 {
 	return arm_coder_init(next, allocator, filters, false);
diff --git a/src/liblzma/simple/armthumb.c b/src/liblzma/simple/armthumb.c
index 4b49175..06c21e4 100644
--- a/src/liblzma/simple/armthumb.c
+++ b/src/liblzma/simple/armthumb.c
@@ -50,7 +50,7 @@
 
 
 static lzma_ret
-armthumb_coder_init(lzma_next_coder *next, lzma_allocator *allocator,
+armthumb_coder_init(lzma_next_coder *next, const lzma_allocator *allocator,
 		const lzma_filter_info *filters, bool is_encoder)
 {
 	return lzma_simple_coder_init(next, allocator, filters,
@@ -60,7 +60,8 @@
 
 extern lzma_ret
 lzma_simple_armthumb_encoder_init(lzma_next_coder *next,
-		lzma_allocator *allocator, const lzma_filter_info *filters)
+		const lzma_allocator *allocator,
+		const lzma_filter_info *filters)
 {
 	return armthumb_coder_init(next, allocator, filters, true);
 }
@@ -68,7 +69,8 @@
 
 extern lzma_ret
 lzma_simple_armthumb_decoder_init(lzma_next_coder *next,
-		lzma_allocator *allocator, const lzma_filter_info *filters)
+		const lzma_allocator *allocator,
+		const lzma_filter_info *filters)
 {
 	return armthumb_coder_init(next, allocator, filters, false);
 }
diff --git a/src/liblzma/simple/ia64.c b/src/liblzma/simple/ia64.c
index ce3692b..ba7249c 100644
--- a/src/liblzma/simple/ia64.c
+++ b/src/liblzma/simple/ia64.c
@@ -86,7 +86,7 @@
 
 
 static lzma_ret
-ia64_coder_init(lzma_next_coder *next, lzma_allocator *allocator,
+ia64_coder_init(lzma_next_coder *next, const lzma_allocator *allocator,
 		const lzma_filter_info *filters, bool is_encoder)
 {
 	return lzma_simple_coder_init(next, allocator, filters,
@@ -96,7 +96,8 @@
 
 extern lzma_ret
 lzma_simple_ia64_encoder_init(lzma_next_coder *next,
-		lzma_allocator *allocator, const lzma_filter_info *filters)
+		const lzma_allocator *allocator,
+		const lzma_filter_info *filters)
 {
 	return ia64_coder_init(next, allocator, filters, true);
 }
@@ -104,7 +105,8 @@
 
 extern lzma_ret
 lzma_simple_ia64_decoder_init(lzma_next_coder *next,
-		lzma_allocator *allocator, const lzma_filter_info *filters)
+		const lzma_allocator *allocator,
+		const lzma_filter_info *filters)
 {
 	return ia64_coder_init(next, allocator, filters, false);
 }
diff --git a/src/liblzma/simple/powerpc.c b/src/liblzma/simple/powerpc.c
index 6f83511..4689919 100644
--- a/src/liblzma/simple/powerpc.c
+++ b/src/liblzma/simple/powerpc.c
@@ -49,7 +49,7 @@
 
 
 static lzma_ret
-powerpc_coder_init(lzma_next_coder *next, lzma_allocator *allocator,
+powerpc_coder_init(lzma_next_coder *next, const lzma_allocator *allocator,
 		const lzma_filter_info *filters, bool is_encoder)
 {
 	return lzma_simple_coder_init(next, allocator, filters,
@@ -59,7 +59,8 @@
 
 extern lzma_ret
 lzma_simple_powerpc_encoder_init(lzma_next_coder *next,
-		lzma_allocator *allocator, const lzma_filter_info *filters)
+		const lzma_allocator *allocator,
+		const lzma_filter_info *filters)
 {
 	return powerpc_coder_init(next, allocator, filters, true);
 }
@@ -67,7 +68,8 @@
 
 extern lzma_ret
 lzma_simple_powerpc_decoder_init(lzma_next_coder *next,
-		lzma_allocator *allocator, const lzma_filter_info *filters)
+		const lzma_allocator *allocator,
+		const lzma_filter_info *filters)
 {
 	return powerpc_coder_init(next, allocator, filters, false);
 }
diff --git a/src/liblzma/simple/simple_coder.c b/src/liblzma/simple/simple_coder.c
index a02b039..dba5417 100644
--- a/src/liblzma/simple/simple_coder.c
+++ b/src/liblzma/simple/simple_coder.c
@@ -18,7 +18,7 @@
 
 /// Copied or encodes/decodes more data to out[].
 static lzma_ret
-copy_or_code(lzma_coder *coder, lzma_allocator *allocator,
+copy_or_code(lzma_coder *coder, const lzma_allocator *allocator,
 		const uint8_t *restrict in, size_t *restrict in_pos,
 		size_t in_size, uint8_t *restrict out,
 		size_t *restrict out_pos, size_t out_size, lzma_action action)
@@ -66,7 +66,7 @@
 
 
 static lzma_ret
-simple_code(lzma_coder *coder, lzma_allocator *allocator,
+simple_code(lzma_coder *coder, const lzma_allocator *allocator,
 		const uint8_t *restrict in, size_t *restrict in_pos,
 		size_t in_size, uint8_t *restrict out,
 		size_t *restrict out_pos, size_t out_size, lzma_action action)
@@ -198,7 +198,7 @@
 
 
 static void
-simple_coder_end(lzma_coder *coder, lzma_allocator *allocator)
+simple_coder_end(lzma_coder *coder, const lzma_allocator *allocator)
 {
 	lzma_next_end(&coder->next, allocator);
 	lzma_free(coder->simple, allocator);
@@ -208,7 +208,7 @@
 
 
 static lzma_ret
-simple_coder_update(lzma_coder *coder, lzma_allocator *allocator,
+simple_coder_update(lzma_coder *coder, const lzma_allocator *allocator,
 		const lzma_filter *filters_null lzma_attribute((__unused__)),
 		const lzma_filter *reversed_filters)
 {
@@ -219,7 +219,7 @@
 
 
 extern lzma_ret
-lzma_simple_coder_init(lzma_next_coder *next, lzma_allocator *allocator,
+lzma_simple_coder_init(lzma_next_coder *next, const lzma_allocator *allocator,
 		const lzma_filter_info *filters,
 		size_t (*filter)(lzma_simple *simple, uint32_t now_pos,
 			bool is_encoder, uint8_t *buffer, size_t size),
diff --git a/src/liblzma/simple/simple_coder.h b/src/liblzma/simple/simple_coder.h
index 0952fad..19c2ee0 100644
--- a/src/liblzma/simple/simple_coder.h
+++ b/src/liblzma/simple/simple_coder.h
@@ -17,44 +17,56 @@
 
 
 extern lzma_ret lzma_simple_x86_encoder_init(lzma_next_coder *next,
-		lzma_allocator *allocator, const lzma_filter_info *filters);
+		const lzma_allocator *allocator,
+		const lzma_filter_info *filters);
 
 extern lzma_ret lzma_simple_x86_decoder_init(lzma_next_coder *next,
-		lzma_allocator *allocator, const lzma_filter_info *filters);
+		const lzma_allocator *allocator,
+		const lzma_filter_info *filters);
 
 
 extern lzma_ret lzma_simple_powerpc_encoder_init(lzma_next_coder *next,
-		lzma_allocator *allocator, const lzma_filter_info *filters);
+		const lzma_allocator *allocator,
+		const lzma_filter_info *filters);
 
 extern lzma_ret lzma_simple_powerpc_decoder_init(lzma_next_coder *next,
-		lzma_allocator *allocator, const lzma_filter_info *filters);
+		const lzma_allocator *allocator,
+		const lzma_filter_info *filters);
 
 
 extern lzma_ret lzma_simple_ia64_encoder_init(lzma_next_coder *next,
-		lzma_allocator *allocator, const lzma_filter_info *filters);
+		const lzma_allocator *allocator,
+		const lzma_filter_info *filters);
 
 extern lzma_ret lzma_simple_ia64_decoder_init(lzma_next_coder *next,
-		lzma_allocator *allocator, const lzma_filter_info *filters);
+		const lzma_allocator *allocator,
+		const lzma_filter_info *filters);
 
 
 extern lzma_ret lzma_simple_arm_encoder_init(lzma_next_coder *next,
-		lzma_allocator *allocator, const lzma_filter_info *filters);
+		const lzma_allocator *allocator,
+		const lzma_filter_info *filters);
 
 extern lzma_ret lzma_simple_arm_decoder_init(lzma_next_coder *next,
-		lzma_allocator *allocator, const lzma_filter_info *filters);
+		const lzma_allocator *allocator,
+		const lzma_filter_info *filters);
 
 
 extern lzma_ret lzma_simple_armthumb_encoder_init(lzma_next_coder *next,
-		lzma_allocator *allocator, const lzma_filter_info *filters);
+		const lzma_allocator *allocator,
+		const lzma_filter_info *filters);
 
 extern lzma_ret lzma_simple_armthumb_decoder_init(lzma_next_coder *next,
-		lzma_allocator *allocator, const lzma_filter_info *filters);
+		const lzma_allocator *allocator,
+		const lzma_filter_info *filters);
 
 
 extern lzma_ret lzma_simple_sparc_encoder_init(lzma_next_coder *next,
-		lzma_allocator *allocator, const lzma_filter_info *filters);
+		const lzma_allocator *allocator,
+		const lzma_filter_info *filters);
 
 extern lzma_ret lzma_simple_sparc_decoder_init(lzma_next_coder *next,
-		lzma_allocator *allocator, const lzma_filter_info *filters);
+		const lzma_allocator *allocator,
+		const lzma_filter_info *filters);
 
 #endif
diff --git a/src/liblzma/simple/simple_decoder.c b/src/liblzma/simple/simple_decoder.c
index 0beccd3..1d864f2 100644
--- a/src/liblzma/simple/simple_decoder.c
+++ b/src/liblzma/simple/simple_decoder.c
@@ -14,7 +14,7 @@
 
 
 extern lzma_ret
-lzma_simple_props_decode(void **options, lzma_allocator *allocator,
+lzma_simple_props_decode(void **options, const lzma_allocator *allocator,
 		const uint8_t *props, size_t props_size)
 {
 	if (props_size == 0)
diff --git a/src/liblzma/simple/simple_decoder.h b/src/liblzma/simple/simple_decoder.h
index b8bf590..bed8d37 100644
--- a/src/liblzma/simple/simple_decoder.h
+++ b/src/liblzma/simple/simple_decoder.h
@@ -16,7 +16,7 @@
 #include "simple_coder.h"
 
 extern lzma_ret lzma_simple_props_decode(
-		void **options, lzma_allocator *allocator,
+		void **options, const lzma_allocator *allocator,
 		const uint8_t *props, size_t props_size);
 
 #endif
diff --git a/src/liblzma/simple/simple_private.h b/src/liblzma/simple/simple_private.h
index fcf9f7c..bb20cb4 100644
--- a/src/liblzma/simple/simple_private.h
+++ b/src/liblzma/simple/simple_private.h
@@ -66,7 +66,8 @@
 
 
 extern lzma_ret lzma_simple_coder_init(lzma_next_coder *next,
-		lzma_allocator *allocator, const lzma_filter_info *filters,
+		const lzma_allocator *allocator,
+		const lzma_filter_info *filters,
 		size_t (*filter)(lzma_simple *simple, uint32_t now_pos,
 			bool is_encoder, uint8_t *buffer, size_t size),
 		size_t simple_size, size_t unfiltered_max,
diff --git a/src/liblzma/simple/sparc.c b/src/liblzma/simple/sparc.c
index 8270d6a..53ee49d 100644
--- a/src/liblzma/simple/sparc.c
+++ b/src/liblzma/simple/sparc.c
@@ -57,7 +57,7 @@
 
 
 static lzma_ret
-sparc_coder_init(lzma_next_coder *next, lzma_allocator *allocator,
+sparc_coder_init(lzma_next_coder *next, const lzma_allocator *allocator,
 		const lzma_filter_info *filters, bool is_encoder)
 {
 	return lzma_simple_coder_init(next, allocator, filters,
@@ -67,7 +67,8 @@
 
 extern lzma_ret
 lzma_simple_sparc_encoder_init(lzma_next_coder *next,
-		lzma_allocator *allocator, const lzma_filter_info *filters)
+		const lzma_allocator *allocator,
+		const lzma_filter_info *filters)
 {
 	return sparc_coder_init(next, allocator, filters, true);
 }
@@ -75,7 +76,8 @@
 
 extern lzma_ret
 lzma_simple_sparc_decoder_init(lzma_next_coder *next,
-		lzma_allocator *allocator, const lzma_filter_info *filters)
+		const lzma_allocator *allocator,
+		const lzma_filter_info *filters)
 {
 	return sparc_coder_init(next, allocator, filters, false);
 }
diff --git a/src/liblzma/simple/x86.c b/src/liblzma/simple/x86.c
index 5d1509b..3b2b4f8 100644
--- a/src/liblzma/simple/x86.c
+++ b/src/liblzma/simple/x86.c
@@ -123,7 +123,7 @@
 
 
 static lzma_ret
-x86_coder_init(lzma_next_coder *next, lzma_allocator *allocator,
+x86_coder_init(lzma_next_coder *next, const lzma_allocator *allocator,
 		const lzma_filter_info *filters, bool is_encoder)
 {
 	const lzma_ret ret = lzma_simple_coder_init(next, allocator, filters,
@@ -139,7 +139,8 @@
 
 
 extern lzma_ret
-lzma_simple_x86_encoder_init(lzma_next_coder *next, lzma_allocator *allocator,
+lzma_simple_x86_encoder_init(lzma_next_coder *next,
+		const lzma_allocator *allocator,
 		const lzma_filter_info *filters)
 {
 	return x86_coder_init(next, allocator, filters, true);
@@ -147,7 +148,8 @@
 
 
 extern lzma_ret
-lzma_simple_x86_decoder_init(lzma_next_coder *next, lzma_allocator *allocator,
+lzma_simple_x86_decoder_init(lzma_next_coder *next,
+		const lzma_allocator *allocator,
 		const lzma_filter_info *filters)
 {
 	return x86_coder_init(next, allocator, filters, false);
diff --git a/src/lzmainfo/Makefile.am b/src/lzmainfo/Makefile.am
index b90b3b3..ff7172b 100644
--- a/src/lzmainfo/Makefile.am
+++ b/src/lzmainfo/Makefile.am
@@ -9,8 +9,8 @@
 
 lzmainfo_SOURCES = \
 	lzmainfo.c \
-	$(top_srcdir)/src/common/tuklib_progname.c \
-	$(top_srcdir)/src/common/tuklib_exit.c
+	../common/tuklib_progname.c \
+	../common/tuklib_exit.c
 
 if COND_W32
 lzmainfo_SOURCES += lzmainfo_w32res.rc
diff --git a/src/lzmainfo/lzmainfo.1 b/src/lzmainfo/lzmainfo.1
index f2b93b4..ce38eee 100644
--- a/src/lzmainfo/lzmainfo.1
+++ b/src/lzmainfo/lzmainfo.1
@@ -4,14 +4,14 @@
 .\" This file has been put into the public domain.
 .\" You can do whatever you want with this file.
 .\"
-.TH LZMAINFO 1 "2010-09-27" "Tukaani" "XZ Utils"
+.TH LZMAINFO 1 "2013-06-30" "Tukaani" "XZ Utils"
 .SH NAME
 lzmainfo \- show information stored in the .lzma file header
 .SH SYNOPSIS
 .B lzmainfo
 .RB [ \-\-help ]
 .RB [ \-\-version ]
-.RI [ file ]...
+.RI [ file... ]
 .SH DESCRIPTION
 .B lzmainfo
 shows information stored in the
diff --git a/src/scripts/xzdiff.in b/src/scripts/xzdiff.in
index e6e3842..6aa6b98 100644
--- a/src/scripts/xzdiff.in
+++ b/src/scripts/xzdiff.in
@@ -136,18 +136,38 @@
             F=`expr "/$2" : '.*/\(.*\)[-.][ablmotxz2]*$'` || F=$prog
             tmp=
             trap '
-              test -n "$tmp" && rm -f "$tmp"
+              test -n "$tmp" && rm -rf "$tmp"
               (exit 2); exit 2
             ' HUP INT PIPE TERM 0
-            tmp=`mktemp -t -- "$F.XXXXXX"` || exit 2
-            $xz2 -cdfq -- "$2" > "$tmp" || exit 2
+            if type mktemp >/dev/null 2>&1; then
+              # Note that FreeBSD's mktemp isn't fully compatible with
+              # the implementations from mktemp.org and GNU coreutils.
+              # It is important that the -t argument is the last argument
+              # and that no "--" is used between -t and the template argument.
+              # This way this command works on all implementations.
+              tmp=`mktemp -d -t "$prog.XXXXXXXXXX"` || exit 2
+            else
+              # Fallback code if mktemp is missing. This isn't as
+              # robust as using mktemp since this doesn't try with
+              # different file names in case of a file name conflict.
+              #
+              # There's no need to save the original umask since
+              # we don't create any non-temp files. Note that using
+              # mkdir -m 0077 isn't secure since some mkdir implementations
+              # create the dir with the default umask and chmod the
+              # the dir afterwards.
+              umask 0077
+              mkdir -- "${TMPDIR-/tmp}/$prog.$$" || exit 2
+              tmp="${TMPDIR-/tmp}/$prog.$$"
+            fi
+            $xz2 -cdfq -- "$2" > "$tmp/$F" || exit 2
             xz_status=$(
               exec 4>&1
               ($xz1 -cdfq -- "$1" 4>&-; echo $? >&4) 3>&- |
-                eval "$cmp" - '"$tmp"' >&3
+                eval "$cmp" - '"$tmp/$F"' >&3
             )
             cmp_status=$?
-            rm -f "$tmp" || xz_status=$?
+            rm -rf "$tmp" || xz_status=$?
             trap - HUP INT PIPE TERM 0
             (exit $cmp_status)
           fi;;
diff --git a/src/scripts/xzgrep.in b/src/scripts/xzgrep.in
index d8e9bb5..a1fd19c 100644
--- a/src/scripts/xzgrep.in
+++ b/src/scripts/xzgrep.in
@@ -106,10 +106,12 @@
     with_filename=1
     continue;;
   (-l | --files-with-*)
-    files_with_matches=1;;
+    files_with_matches=1
+    continue;;
   (-L | --files-witho*)
-    files_without_matches=1;;
-  (--no-f*)
+    files_without_matches=1
+    continue;;
+  (-h | --no-f*)
     no_filename=1;;
   (-V | --v | --ve | --ver | --vers | --versi | --versio | --version)
     echo "$version" || exit 2
@@ -147,7 +149,9 @@
 fi
 
 exec 3>&1
-res=0
+
+# res=1 means that no file matched yet
+res=1
 
 for i; do
   case $i in
@@ -195,8 +199,17 @@
     fi >&3 5>&-
   )
   r=$?
+
+  # fail occured previously, nothing worse can happen
+  test $res -gt 1 && continue
+
   test "$xz_status" -eq 0 || test "$xz_status" -eq 2 \
       || test "$(kill -l "$xz_status" 2> /dev/null)" = "PIPE" || r=2
-  test $res -lt $r && res=$r
+
+  # still no match
+  test $r -eq 1 && continue
+
+  # 0 == match, >=2 == fail
+  res=$r
 done
 exit $res
diff --git a/src/scripts/xzless.in b/src/scripts/xzless.in
index a3da697..288dd87 100644
--- a/src/scripts/xzless.in
+++ b/src/scripts/xzless.in
@@ -46,7 +46,7 @@
 	LESSMETACHARS="$space$tab$nl'"';*?"()<>[|&^`#\$%=~'
 fi
 
-if test "$(less -V | { read ver && echo ${ver#less }; })" -ge 429; then
+if test "$(less -V | { read less ver re && echo ${ver}; })" -ge 429; then
 	# less 429 or later: LESSOPEN pipe will be used on
 	# standard input if $LESSOPEN begins with |-.
 	LESSOPEN="|-$xz -cdfq -- %s"
diff --git a/src/scripts/xzmore.1 b/src/scripts/xzmore.1
index 30dad68..9613974 100644
--- a/src/scripts/xzmore.1
+++ b/src/scripts/xzmore.1
@@ -4,15 +4,15 @@
 .\"
 .\" License: GNU GPLv2+
 .\"
-.TH XZMORE 1 "2010-09-27" "Tukaani" "XZ Utils"
+.TH XZMORE 1 "2013-06-30" "Tukaani" "XZ Utils"
 .SH NAME
 xzmore, lzmore \- view xz or lzma compressed (text) files
 .SH SYNOPSIS
 .B xzmore
-.RI [ "filename ..." ]
+.RI [ file... ]
 .br
 .B lzmore
-.RI [ "filename ..." ]
+.RI [ file... ]
 .SH DESCRIPTION
 .B  xzmore
 is a filter which allows examination of
diff --git a/src/xz/Makefile.am b/src/xz/Makefile.am
index 10ceee7..1f4a279 100644
--- a/src/xz/Makefile.am
+++ b/src/xz/Makefile.am
@@ -22,6 +22,8 @@
 	main.h \
 	message.c \
 	message.h \
+	mytime.c \
+	mytime.h \
 	options.c \
 	options.h \
 	private.h \
@@ -31,12 +33,11 @@
 	suffix.h \
 	util.c \
 	util.h \
-	$(top_srcdir)/src/common/tuklib_open_stdxxx.c \
-	$(top_srcdir)/src/common/tuklib_progname.c \
-	$(top_srcdir)/src/common/tuklib_exit.c \
-	$(top_srcdir)/src/common/tuklib_cpucores.c \
-	$(top_srcdir)/src/common/tuklib_mbstr_width.c \
-	$(top_srcdir)/src/common/tuklib_mbstr_fw.c
+	../common/tuklib_open_stdxxx.c \
+	../common/tuklib_progname.c \
+	../common/tuklib_exit.c \
+	../common/tuklib_mbstr_width.c \
+	../common/tuklib_mbstr_fw.c
 
 if COND_W32
 xz_SOURCES += xz_w32res.rc
diff --git a/src/xz/args.c b/src/xz/args.c
index 1b88c1e..041c800 100644
--- a/src/xz/args.c
+++ b/src/xz/args.c
@@ -22,6 +22,7 @@
 bool opt_force = false;
 bool opt_keep_original = false;
 bool opt_robot = false;
+bool opt_ignore_check = false;
 
 // We don't modify or free() this, but we need to assign it in some
 // non-const pointers.
@@ -55,6 +56,67 @@
 
 
 static void
+parse_block_list(char *str)
+{
+	// It must be non-empty and not begin with a comma.
+	if (str[0] == '\0' || str[0] == ',')
+		message_fatal(_("%s: Invalid argument to --block-list"), str);
+
+	// Count the number of comma-separated strings.
+	size_t count = 1;
+	for (size_t i = 0; str[i] != '\0'; ++i)
+		if (str[i] == ',')
+			++count;
+
+	// Prevent an unlikely integer overflow.
+	if (count > SIZE_MAX / sizeof(uint64_t) - 1)
+		message_fatal(_("%s: Too many arguments to --block-list"),
+				str);
+
+	// Allocate memory to hold all the sizes specified.
+	// If --block-list was specified already, its value is forgotten.
+	free(opt_block_list);
+	opt_block_list = xmalloc((count + 1) * sizeof(uint64_t));
+
+	for (size_t i = 0; i < count; ++i) {
+		// Locate the next comma and replace it with \0.
+		char *p = strchr(str, ',');
+		if (p != NULL)
+			*p = '\0';
+
+		if (str[0] == '\0') {
+			// There is no string, that is, a comma follows
+			// another comma. Use the previous value.
+			//
+			// NOTE: We checked earler that the first char
+			// of the whole list cannot be a comma.
+			assert(i > 0);
+			opt_block_list[i] = opt_block_list[i - 1];
+		} else {
+			opt_block_list[i] = str_to_uint64("block-list", str,
+					0, UINT64_MAX);
+
+			// Zero indicates no more new Blocks.
+			if (opt_block_list[i] == 0) {
+				if (i + 1 != count)
+					message_fatal(_("0 can only be used "
+							"as the last element "
+							"in --block-list"));
+
+				opt_block_list[i] = UINT64_MAX;
+			}
+		}
+
+		str = p + 1;
+	}
+
+	// Terminate the array.
+	opt_block_list[count] = 0;
+	return;
+}
+
+
+static void
 parse_real(args_info *args, int argc, char **argv)
 {
 	enum {
@@ -73,11 +135,14 @@
 		OPT_FILES,
 		OPT_FILES0,
 		OPT_BLOCK_SIZE,
+		OPT_BLOCK_LIST,
 		OPT_MEM_COMPRESS,
 		OPT_MEM_DECOMPRESS,
 		OPT_NO_ADJUST,
 		OPT_INFO_MEMORY,
 		OPT_ROBOT,
+		OPT_FLUSH_TIMEOUT,
+		OPT_IGNORE_CHECK,
 	};
 
 	static const char short_opts[]
@@ -106,13 +171,16 @@
 		// Basic compression settings
 		{ "format",       required_argument, NULL,  'F' },
 		{ "check",        required_argument, NULL,  'C' },
+		{ "ignore-check", no_argument,       NULL,  OPT_IGNORE_CHECK },
 		{ "block-size",   required_argument, NULL,  OPT_BLOCK_SIZE },
+		{ "block-list",  required_argument, NULL,  OPT_BLOCK_LIST },
 		{ "memlimit-compress",   required_argument, NULL, OPT_MEM_COMPRESS },
 		{ "memlimit-decompress", required_argument, NULL, OPT_MEM_DECOMPRESS },
 		{ "memlimit",     required_argument, NULL,  'M' },
 		{ "memory",       required_argument, NULL,  'M' }, // Old alias
 		{ "no-adjust",    no_argument,       NULL,  OPT_NO_ADJUST },
 		{ "threads",      required_argument, NULL,  'T' },
+		{ "flush-timeout", required_argument, NULL, OPT_FLUSH_TIMEOUT },
 
 		{ "extreme",      no_argument,       NULL,  'e' },
 		{ "fast",         no_argument,       NULL,  '0' },
@@ -179,8 +247,9 @@
 			break;
 
 		case 'T':
-			hardware_threadlimit_set(str_to_uint64(
-					"threads", optarg, 0, UINT32_MAX));
+			// The max is from src/liblzma/common/common.h.
+			hardware_threads_set(str_to_uint64("threads",
+					optarg, 0, 16384));
 			break;
 
 		// --version
@@ -372,11 +441,20 @@
 			break;
 		}
 
+		case OPT_IGNORE_CHECK:
+			opt_ignore_check = true;
+			break;
+
 		case OPT_BLOCK_SIZE:
 			opt_block_size = str_to_uint64("block-size", optarg,
 					0, LZMA_VLI_MAX);
 			break;
 
+		case OPT_BLOCK_LIST: {
+			parse_block_list(optarg);
+			break;
+		}
+
 		case OPT_SINGLE_STREAM:
 			opt_single_stream = true;
 			break;
@@ -414,6 +492,11 @@
 			opt_auto_adjust = false;
 			break;
 
+		case OPT_FLUSH_TIMEOUT:
+			opt_flush_timeout = str_to_uint64("flush-timeout",
+					optarg, 0, UINT64_MAX);
+			break;
+
 		default:
 			message_try_help();
 			tuklib_exit(E_ERROR, E_ERROR, false);
@@ -589,3 +672,13 @@
 
 	return;
 }
+
+
+#ifndef NDEBUG
+extern void
+args_free(void)
+{
+	free(opt_block_list);
+	return;
+}
+#endif
diff --git a/src/xz/args.h b/src/xz/args.h
index b23f4ef..46a8e8e 100644
--- a/src/xz/args.h
+++ b/src/xz/args.h
@@ -15,7 +15,7 @@
 	char **arg_names;
 
 	/// Number of filenames from command line
-	size_t arg_count;
+	unsigned int arg_count;
 
 	/// Name of the file from which to read filenames. This is NULL
 	/// if --files or --files0 was not used.
@@ -36,7 +36,9 @@
 extern bool opt_keep_original;
 // extern bool opt_recursive;
 extern bool opt_robot;
+extern bool opt_ignore_check;
 
 extern const char stdin_filename[];
 
 extern void args_parse(args_info *args, int argc, char **argv);
+extern void args_free(void);
diff --git a/src/xz/coder.c b/src/xz/coder.c
index a3366d0..a94bdb8 100644
--- a/src/xz/coder.c
+++ b/src/xz/coder.c
@@ -26,6 +26,7 @@
 bool opt_auto_adjust = true;
 bool opt_single_stream = false;
 uint64_t opt_block_size = 0;
+uint64_t *opt_block_list = NULL;
 
 
 /// Stream used to communicate with liblzma
@@ -42,12 +43,7 @@
 static uint32_t filters_count = 0;
 
 /// Number of the preset (0-9)
-static uint32_t preset_number = 6;
-
-/// If a preset is used (no custom filter chain) and preset_extreme is true,
-/// a significantly slower compression is used to achieve slightly better
-/// compression ratio.
-static bool preset_extreme = false;
+static uint32_t preset_number = LZMA_PRESET_DEFAULT;
 
 /// Integrity check type
 static lzma_check check;
@@ -55,6 +51,14 @@
 /// This becomes false if the --check=CHECK option is used.
 static bool check_default = true;
 
+#ifdef MYTHREAD_ENABLED
+static lzma_mt mt_options = {
+	.flags = 0,
+	.timeout = 300,
+	.filters = filters,
+};
+#endif
+
 
 extern void
 coder_set_check(lzma_check new_check)
@@ -65,11 +69,9 @@
 }
 
 
-extern void
-coder_set_preset(uint32_t new_preset)
+static void
+forget_filter_chain(void)
 {
-	preset_number = new_preset;
-
 	// Setting a preset makes us forget a possibly defined custom
 	// filter chain.
 	while (filters_count > 0) {
@@ -83,9 +85,20 @@
 
 
 extern void
+coder_set_preset(uint32_t new_preset)
+{
+	preset_number &= ~LZMA_PRESET_LEVEL_MASK;
+	preset_number |= new_preset;
+	forget_filter_chain();
+	return;
+}
+
+
+extern void
 coder_set_extreme(void)
 {
-	preset_extreme = true;
+	preset_number |= LZMA_PRESET_EXTREME;
+	forget_filter_chain();
 	return;
 }
 
@@ -100,6 +113,12 @@
 	filters[filters_count].options = options;
 	++filters_count;
 
+	// Setting a custom filter chain makes us forget the preset options.
+	// This makes a difference if one specifies e.g. "xz -9 --lzma2 -e"
+	// where the custom filter chain resets the preset level back to
+	// the default 6, making the example equivalent to "xz -6e".
+	preset_number = LZMA_PRESET_DEFAULT;
+
 	return;
 }
 
@@ -117,6 +136,15 @@
 extern void
 coder_set_compression_settings(void)
 {
+	// The default check type is CRC64, but fallback to CRC32
+	// if CRC64 isn't supported by the copy of liblzma we are
+	// using. CRC32 is always supported.
+	if (check_default) {
+		check = LZMA_CHECK_CRC64;
+		if (!lzma_check_is_supported(check))
+			check = LZMA_CHECK_CRC32;
+	}
+
 	// Options for LZMA1 or LZMA2 in case we are using a preset.
 	static lzma_options_lzma opt_lzma;
 
@@ -136,9 +164,6 @@
 		}
 
 		// Get the preset for LZMA1 or LZMA2.
-		if (preset_extreme)
-			preset_number |= LZMA_PRESET_EXTREME;
-
 		if (lzma_lzma_preset(&opt_lzma, preset_number))
 			message_bug();
 
@@ -170,15 +195,53 @@
 	// Print the selected filter chain.
 	message_filters_show(V_DEBUG, filters);
 
-	// If using --format=raw, we can be decoding. The memusage function
-	// also validates the filter chain and the options used for the
-	// filters.
+	// The --flush-timeout option requires LZMA_SYNC_FLUSH support
+	// from the filter chain. Currently threaded encoder doesn't support
+	// LZMA_SYNC_FLUSH so single-threaded mode must be used.
+	if (opt_mode == MODE_COMPRESS && opt_flush_timeout != 0) {
+		for (size_t i = 0; i < filters_count; ++i) {
+			switch (filters[i].id) {
+			case LZMA_FILTER_LZMA2:
+			case LZMA_FILTER_DELTA:
+				break;
+
+			default:
+				message_fatal(_("The filter chain is "
+					"incompatible with --flush-timeout"));
+			}
+		}
+
+		if (hardware_threads_get() > 1) {
+			message(V_WARNING, _("Switching to single-threaded "
+					"mode due to --flush-timeout"));
+			hardware_threads_set(1);
+		}
+	}
+
+	// Get the memory usage. Note that if --format=raw was used,
+	// we can be decompressing.
 	const uint64_t memory_limit = hardware_memlimit_get(opt_mode);
 	uint64_t memory_usage;
-	if (opt_mode == MODE_COMPRESS)
-		memory_usage = lzma_raw_encoder_memusage(filters);
-	else
+	if (opt_mode == MODE_COMPRESS) {
+#ifdef MYTHREAD_ENABLED
+		if (opt_format == FORMAT_XZ && hardware_threads_get() > 1) {
+			mt_options.threads = hardware_threads_get();
+			mt_options.block_size = opt_block_size;
+			mt_options.check = check;
+			memory_usage = lzma_stream_encoder_mt_memusage(
+					&mt_options);
+			if (memory_usage != UINT64_MAX)
+				message(V_DEBUG, _("Using up to %" PRIu32
+						" threads."),
+						mt_options.threads);
+		} else
+#endif
+		{
+			memory_usage = lzma_raw_encoder_memusage(filters);
+		}
+	} else {
 		memory_usage = lzma_raw_decoder_memusage(filters);
+	}
 
 	if (memory_usage == UINT64_MAX)
 		message_fatal(_("Unsupported filter chain or filter options"));
@@ -194,90 +257,99 @@
 						round_up_to_mib(decmem), 0));
 	}
 
-	if (memory_usage > memory_limit) {
-		// If --no-auto-adjust was used or we didn't find LZMA1 or
-		// LZMA2 as the last filter, give an error immediately.
-		// --format=raw implies --no-auto-adjust.
-		if (!opt_auto_adjust || opt_format == FORMAT_RAW)
-			memlimit_too_small(memory_usage);
+	if (memory_usage <= memory_limit)
+		return;
 
-		assert(opt_mode == MODE_COMPRESS);
+	// If --no-adjust was used or we didn't find LZMA1 or
+	// LZMA2 as the last filter, give an error immediately.
+	// --format=raw implies --no-adjust.
+	if (!opt_auto_adjust || opt_format == FORMAT_RAW)
+		memlimit_too_small(memory_usage);
 
-		// Look for the last filter if it is LZMA2 or LZMA1, so
-		// we can make it use less RAM. With other filters we don't
-		// know what to do.
-		size_t i = 0;
-		while (filters[i].id != LZMA_FILTER_LZMA2
-				&& filters[i].id != LZMA_FILTER_LZMA1) {
-			if (filters[i].id == LZMA_VLI_UNKNOWN)
+	assert(opt_mode == MODE_COMPRESS);
+
+#ifdef MYTHREAD_ENABLED
+	if (opt_format == FORMAT_XZ && mt_options.threads > 1) {
+		// Try to reduce the number of threads before
+		// adjusting the compression settings down.
+		do {
+			// FIXME? The real single-threaded mode has
+			// lower memory usage, but it's not comparable
+			// because it doesn't write the size info
+			// into Block Headers.
+			if (--mt_options.threads == 0)
 				memlimit_too_small(memory_usage);
 
-			++i;
-		}
-
-		// Decrease the dictionary size until we meet the memory
-		// usage limit. First round down to full mebibytes.
-		lzma_options_lzma *opt = filters[i].options;
-		const uint32_t orig_dict_size = opt->dict_size;
-		opt->dict_size &= ~((UINT32_C(1) << 20) - 1);
-		while (true) {
-			// If it is below 1 MiB, auto-adjusting failed. We
-			// could be more sophisticated and scale it down even
-			// more, but let's see if many complain about this
-			// version.
-			//
-			// FIXME: Displays the scaled memory usage instead
-			// of the original.
-			if (opt->dict_size < (UINT32_C(1) << 20))
-				memlimit_too_small(memory_usage);
-
-			memory_usage = lzma_raw_encoder_memusage(filters);
+			memory_usage = lzma_stream_encoder_mt_memusage(
+					&mt_options);
 			if (memory_usage == UINT64_MAX)
 				message_bug();
 
-			// Accept it if it is low enough.
-			if (memory_usage <= memory_limit)
-				break;
+		} while (memory_usage > memory_limit);
 
-			// Otherwise 1 MiB down and try again. I hope this
-			// isn't too slow method for cases where the original
-			// dict_size is very big.
-			opt->dict_size -= UINT32_C(1) << 20;
-		}
+		message(V_WARNING, _("Adjusted the number of threads "
+			"from %s to %s to not exceed "
+			"the memory usage limit of %s MiB"),
+			uint64_to_str(hardware_threads_get(), 0),
+			uint64_to_str(mt_options.threads, 1),
+			uint64_to_str(round_up_to_mib(
+				memory_limit), 2));
+	}
+#endif
 
-		// Tell the user that we decreased the dictionary size.
-		message(V_WARNING, _("Adjusted LZMA%c dictionary size "
-				"from %s MiB to %s MiB to not exceed "
-				"the memory usage limit of %s MiB"),
-				filters[i].id == LZMA_FILTER_LZMA2
-					? '2' : '1',
-				uint64_to_str(orig_dict_size >> 20, 0),
-				uint64_to_str(opt->dict_size >> 20, 1),
-				uint64_to_str(round_up_to_mib(
-					memory_limit), 2));
+	if (memory_usage <= memory_limit)
+		return;
+
+	// Look for the last filter if it is LZMA2 or LZMA1, so we can make
+	// it use less RAM. With other filters we don't know what to do.
+	size_t i = 0;
+	while (filters[i].id != LZMA_FILTER_LZMA2
+			&& filters[i].id != LZMA_FILTER_LZMA1) {
+		if (filters[i].id == LZMA_VLI_UNKNOWN)
+			memlimit_too_small(memory_usage);
+
+		++i;
 	}
 
-/*
-	// Limit the number of worker threads so that memory usage
-	// limit isn't exceeded.
-	assert(memory_usage > 0);
-	size_t thread_limit = memory_limit / memory_usage;
-	if (thread_limit == 0)
-		thread_limit = 1;
+	// Decrease the dictionary size until we meet the memory
+	// usage limit. First round down to full mebibytes.
+	lzma_options_lzma *opt = filters[i].options;
+	const uint32_t orig_dict_size = opt->dict_size;
+	opt->dict_size &= ~((UINT32_C(1) << 20) - 1);
+	while (true) {
+		// If it is below 1 MiB, auto-adjusting failed. We could be
+		// more sophisticated and scale it down even more, but let's
+		// see if many complain about this version.
+		//
+		// FIXME: Displays the scaled memory usage instead
+		// of the original.
+		if (opt->dict_size < (UINT32_C(1) << 20))
+			memlimit_too_small(memory_usage);
 
-	if (opt_threads > thread_limit)
-		opt_threads = thread_limit;
-*/
+		memory_usage = lzma_raw_encoder_memusage(filters);
+		if (memory_usage == UINT64_MAX)
+			message_bug();
 
-	if (check_default) {
-		// The default check type is CRC64, but fallback to CRC32
-		// if CRC64 isn't supported by the copy of liblzma we are
-		// using. CRC32 is always supported.
-		check = LZMA_CHECK_CRC64;
-		if (!lzma_check_is_supported(check))
-			check = LZMA_CHECK_CRC32;
+		// Accept it if it is low enough.
+		if (memory_usage <= memory_limit)
+			break;
+
+		// Otherwise 1 MiB down and try again. I hope this
+		// isn't too slow method for cases where the original
+		// dict_size is very big.
+		opt->dict_size -= UINT32_C(1) << 20;
 	}
 
+	// Tell the user that we decreased the dictionary size.
+	message(V_WARNING, _("Adjusted LZMA%c dictionary size "
+			"from %s MiB to %s MiB to not exceed "
+			"the memory usage limit of %s MiB"),
+			filters[i].id == LZMA_FILTER_LZMA2
+				? '2' : '1',
+			uint64_to_str(orig_dict_size >> 20, 0),
+			uint64_to_str(opt->dict_size >> 20, 1),
+			uint64_to_str(round_up_to_mib(memory_limit), 2));
+
 	return;
 }
 
@@ -359,7 +431,14 @@
 			break;
 
 		case FORMAT_XZ:
-			ret = lzma_stream_encoder(&strm, filters, check);
+#ifdef MYTHREAD_ENABLED
+			if (hardware_threads_get() > 1)
+				ret = lzma_stream_encoder_mt(
+						&strm, &mt_options);
+			else
+#endif
+				ret = lzma_stream_encoder(
+						&strm, filters, check);
 			break;
 
 		case FORMAT_LZMA:
@@ -371,7 +450,15 @@
 			break;
 		}
 	} else {
-		uint32_t flags = LZMA_TELL_UNSUPPORTED_CHECK;
+		uint32_t flags = 0;
+
+		// It seems silly to warn about unsupported check if the
+		// check won't be verified anyway due to --ignore-check.
+		if (opt_ignore_check)
+			flags |= LZMA_IGNORE_CHECK;
+		else
+			flags |= LZMA_TELL_UNSUPPORTED_CHECK;
+
 		if (!opt_single_stream)
 			flags |= LZMA_CONCATENATED;
 
@@ -458,6 +545,56 @@
 }
 
 
+/// Resolve conflicts between opt_block_size and opt_block_list in single
+/// threaded mode. We want to default to opt_block_list, except when it is
+/// larger than opt_block_size. If this is the case for the current Block
+/// at *list_pos, then we break into smaller Blocks. Otherwise advance
+/// to the next Block in opt_block_list, and break apart if needed.
+static void
+split_block(uint64_t *block_remaining,
+	    uint64_t *next_block_remaining,
+	    size_t *list_pos)
+{
+	if (*next_block_remaining > 0) {
+		// The Block at *list_pos has previously been split up.
+		assert(hardware_threads_get() == 1);
+		assert(opt_block_size > 0);
+		assert(opt_block_list != NULL);
+
+		if (*next_block_remaining > opt_block_size) {
+			// We have to split the current Block at *list_pos
+			// into another opt_block_size length Block.
+			*block_remaining = opt_block_size;
+		} else {
+			// This is the last remaining split Block for the
+			// Block at *list_pos.
+			*block_remaining = *next_block_remaining;
+		}
+
+		*next_block_remaining -= *block_remaining;
+
+	} else {
+		// The Block at *list_pos has been finished. Go to the next
+		// entry in the list. If the end of the list has been reached,
+		// reuse the size of the last Block.
+		if (opt_block_list[*list_pos + 1] != 0)
+			++*list_pos;
+
+		*block_remaining = opt_block_list[*list_pos];
+
+		// If in single-threaded mode, split up the Block if needed.
+		// This is not needed in multi-threaded mode because liblzma
+		// will do this due to how threaded encoding works.
+		if (hardware_threads_get() == 1 && opt_block_size > 0
+				&& *block_remaining > opt_block_size) {
+			*next_block_remaining
+					= *block_remaining - opt_block_size;
+			*block_remaining = opt_block_size;
+		}
+	}
+}
+
+
 /// Compress or decompress using liblzma.
 static bool
 coder_normal(file_pair *pair)
@@ -474,23 +611,56 @@
 	// Assume that something goes wrong.
 	bool success = false;
 
-	// block_remaining indicates how many input bytes to encode until
+	// block_remaining indicates how many input bytes to encode before
 	// finishing the current .xz Block. The Block size is set with
-	// --block-size=SIZE. It has an effect only when compressing
-	// to the .xz format. If block_remaining == UINT64_MAX, only
-	// a single block is created.
+	// --block-size=SIZE and --block-list. They have an effect only when
+	// compressing to the .xz format. If block_remaining == UINT64_MAX,
+	// only a single block is created.
 	uint64_t block_remaining = UINT64_MAX;
-	if (opt_mode == MODE_COMPRESS && opt_format == FORMAT_XZ
-			&& opt_block_size > 0)
-		block_remaining = opt_block_size;
+
+	// next_block_remining for when we are in single-threaded mode and
+	// the Block in --block-list is larger than the --block-size=SIZE.
+	uint64_t next_block_remaining = 0;
+
+	// Position in opt_block_list. Unused if --block-list wasn't used.
+	size_t list_pos = 0;
+
+	// Handle --block-size for single-threaded mode and the first step
+	// of --block-list.
+	if (opt_mode == MODE_COMPRESS && opt_format == FORMAT_XZ) {
+		// --block-size doesn't do anything here in threaded mode,
+		// because the threaded encoder will take care of splitting
+		// to fixed-sized Blocks.
+		if (hardware_threads_get() == 1 && opt_block_size > 0)
+			block_remaining = opt_block_size;
+
+		// If --block-list was used, start with the first size.
+		//
+		// For threaded case, --block-size specifies how big Blocks
+		// the encoder needs to be prepared to create at maximum
+		// and --block-list will simultaneously cause new Blocks
+		// to be started at specified intervals. To keep things
+		// logical, the same is done in single-threaded mode. The
+		// output is still not identical because in single-threaded
+		// mode the size info isn't written into Block Headers.
+		if (opt_block_list != NULL) {
+			if (block_remaining < opt_block_list[list_pos]) {
+				assert(hardware_threads_get() == 1);
+				next_block_remaining = opt_block_list[list_pos]
+						- block_remaining;
+			} else {
+				block_remaining = opt_block_list[list_pos];
+			}
+		}
+	}
 
 	strm.next_out = out_buf.u8;
 	strm.avail_out = IO_BUFFER_SIZE;
 
 	while (!user_abort) {
-		// Fill the input buffer if it is empty and we haven't reached
-		// end of file yet.
-		if (strm.avail_in == 0 && !pair->src_eof) {
+		// Fill the input buffer if it is empty and we aren't
+		// flushing or finishing.
+		if (strm.avail_in == 0 && action == LZMA_RUN) {
 			strm.next_in = in_buf.u8;
 			strm.avail_in = io_read(pair, &in_buf,
 					my_min(block_remaining,
@@ -507,8 +677,11 @@
 				// opt_block_size bytes of input.
 				block_remaining -= strm.avail_in;
 				if (block_remaining == 0)
-					action = LZMA_FULL_FLUSH;
+					action = LZMA_FULL_BARRIER;
 			}
+
+			if (action == LZMA_RUN && flush_needed)
+				action = LZMA_SYNC_FLUSH;
 		}
 
 		// Let liblzma do the actual work.
@@ -524,10 +697,37 @@
 			strm.avail_out = IO_BUFFER_SIZE;
 		}
 
-		if (ret == LZMA_STREAM_END && action == LZMA_FULL_FLUSH) {
-			// Start a new Block.
+		if (ret == LZMA_STREAM_END && (action == LZMA_SYNC_FLUSH
+				|| action == LZMA_FULL_BARRIER)) {
+			if (action == LZMA_SYNC_FLUSH) {
+				// Flushing completed. Write the pending data
+				// out immediatelly so that the reading side
+				// can decompress everything compressed so far.
+				if (io_write(pair, &out_buf, IO_BUFFER_SIZE
+						- strm.avail_out))
+					break;
+
+				strm.next_out = out_buf.u8;
+				strm.avail_out = IO_BUFFER_SIZE;
+
+				// Set the time of the most recent flushing.
+				mytime_set_flush_time();
+			} else {
+				// Start a new Block after LZMA_FULL_BARRIER.
+				if (opt_block_list == NULL) {
+					assert(hardware_threads_get() == 1);
+					assert(opt_block_size > 0);
+					block_remaining = opt_block_size;
+				} else {
+					split_block(&block_remaining,
+							&next_block_remaining,
+							&list_pos);
+				}
+			}
+
+			// Start a new Block after LZMA_FULL_FLUSH or continue
+			// the same block after LZMA_SYNC_FLUSH.
 			action = LZMA_RUN;
-			block_remaining = opt_block_size;
 
 		} else if (ret != LZMA_OK) {
 			// Determine if the return value indicates that we
@@ -679,6 +879,11 @@
 			// Don't open the destination file when --test
 			// is used.
 			if (opt_mode == MODE_TEST || !io_open_dest(pair)) {
+				// Remember the current time. It is needed
+				// for progress indicator and for timed
+				// flushing.
+				mytime_set_start_time();
+
 				// Initialize the progress indicator.
 				const uint64_t in_size
 						= pair->src_st.st_size <= 0
diff --git a/src/xz/coder.h b/src/xz/coder.h
index 578d2d7..583da8f 100644
--- a/src/xz/coder.h
+++ b/src/xz/coder.h
@@ -48,6 +48,10 @@
 /// of input. This has an effect only when compressing to the .xz format.
 extern uint64_t opt_block_size;
 
+/// This is non-NULL if --block-list was used. This contains the Block sizes
+/// as an array that is terminated with 0.
+extern uint64_t *opt_block_list;
+
 /// Set the integrity check type used when compressing
 extern void coder_set_check(lzma_check check);
 
diff --git a/src/xz/file_io.c b/src/xz/file_io.c
index f9807a6..9bd515d 100644
--- a/src/xz/file_io.c
+++ b/src/xz/file_io.c
@@ -17,6 +17,7 @@
 #ifdef TUKLIB_DOSLIKE
 #	include <io.h>
 #else
+#	include <poll.h>
 static bool warn_fchown;
 #endif
 
@@ -37,13 +38,30 @@
 #endif
 
 
+typedef enum {
+	IO_WAIT_MORE,    // Reading or writing is possible.
+	IO_WAIT_ERROR,   // Error or user_abort
+	IO_WAIT_TIMEOUT, // poll() timed out
+} io_wait_ret;
+
+
 /// If true, try to create sparse files when decompressing.
 static bool try_sparse = true;
 
 #ifndef TUKLIB_DOSLIKE
-/// File status flags of standard output. This is used by io_open_dest()
-/// and io_close_dest().
-static int stdout_flags = 0;
+/// File status flags of standard input. This is used by io_open_src()
+/// and io_close_src().
+static int stdin_flags;
+static bool restore_stdin_flags = false;
+
+/// Original file status flags of standard output. This is used by
+/// io_open_dest() and io_close_dest() to save and restore the flags.
+static int stdout_flags;
+static bool restore_stdout_flags = false;
+
+/// Self-pipe used together with the user_abort variable to avoid
+/// race conditions with signal handling.
+static int user_abort_pipe[2];
 #endif
 
 
@@ -63,6 +81,20 @@
 	// If fchown() fails setting the owner, we warn about it only if
 	// we are root.
 	warn_fchown = geteuid() == 0;
+
+	// Create a pipe for the self-pipe trick.
+	if (pipe(user_abort_pipe))
+		message_fatal(_("Error creating a pipe: %s"),
+				strerror(errno));
+
+	// Make both ends of the pipe non-blocking.
+	for (unsigned i = 0; i < 2; ++i) {
+		int flags = fcntl(user_abort_pipe[i], F_GETFL);
+		if (flags == -1 || fcntl(user_abort_pipe[i], F_SETFL,
+				flags | O_NONBLOCK) == -1)
+			message_fatal(_("Error creating a pipe: %s"),
+					strerror(errno));
+	}
 #endif
 
 #ifdef __DJGPP__
@@ -75,6 +107,23 @@
 }
 
 
+#ifndef TUKLIB_DOSLIKE
+extern void
+io_write_to_user_abort_pipe(void)
+{
+	// If the write() fails, it's probably due to the pipe being full.
+	// Failing in that case is fine. If the reason is something else,
+	// there's not much we can do since this is called in a signal
+	// handler. So ignore the errors and try to avoid warnings with
+	// GCC and glibc when _FORTIFY_SOURCE=2 is used.
+	uint8_t b = '\0';
+	const int ret = write(user_abort_pipe[1], &b, 1);
+	(void)ret;
+	return;
+}
+#endif
+
+
 extern void
 io_no_sparse(void)
 {
@@ -83,6 +132,63 @@
 }
 
 
+#ifndef TUKLIB_DOSLIKE
+/// \brief      Waits for input or output to become available or for a signal
+///
+/// This uses the self-pipe trick to avoid a race condition that can occur
+/// if a signal is caught after user_abort has been checked but before e.g.
+/// read() has been called. In that situation read() could block unless
+/// non-blocking I/O is used. With non-blocking I/O something like select()
+/// or poll() is needed to avoid a busy-wait loop, and the same race condition
+/// pops up again. There are pselect() (POSIX-1.2001) and ppoll() (not in
+/// POSIX) but neither is portable enough in 2013. The self-pipe trick is
+/// old and very portable.
+static io_wait_ret
+io_wait(file_pair *pair, int timeout, bool is_reading)
+{
+	struct pollfd pfd[2];
+
+	if (is_reading) {
+		pfd[0].fd = pair->src_fd;
+		pfd[0].events = POLLIN;
+	} else {
+		pfd[0].fd = pair->dest_fd;
+		pfd[0].events = POLLOUT;
+	}
+
+	pfd[1].fd = user_abort_pipe[0];
+	pfd[1].events = POLLIN;
+
+	while (true) {
+		const int ret = poll(pfd, 2, timeout);
+
+		if (user_abort)
+			return IO_WAIT_ERROR;
+
+		if (ret == -1) {
+			if (errno == EINTR || errno == EAGAIN)
+				continue;
+
+			message_error(_("%s: poll() failed: %s"),
+					is_reading ? pair->src_name
+						: pair->dest_name,
+					strerror(errno));
+			return IO_WAIT_ERROR;
+		}
+
+		if (ret == 0) {
+			assert(opt_flush_timeout != 0);
+			flush_needed = true;
+			return IO_WAIT_TIMEOUT;
+		}
+
+		if (pfd[0].revents != 0)
+			return IO_WAIT_MORE;
+	}
+}
+#endif
+
+
 /// \brief      Unlink a file
 ///
 /// This tries to verify that the file being unlinked really is the file that
@@ -292,6 +398,24 @@
 		pair->src_fd = STDIN_FILENO;
 #ifdef TUKLIB_DOSLIKE
 		setmode(STDIN_FILENO, O_BINARY);
+#else
+		// Try to set stdin to non-blocking mode. It won't work
+		// e.g. on OpenBSD if stdout is e.g. /dev/null. In such
+		// case we proceed as if stdin were non-blocking anyway
+		// (in case of /dev/null it will be in practice). The
+		// same applies to stdout in io_open_dest_real().
+		stdin_flags = fcntl(STDIN_FILENO, F_GETFL);
+		if (stdin_flags == -1) {
+			message_error(_("Error getting the file status flags "
+					"from standard input: %s"),
+					strerror(errno));
+			return true;
+		}
+
+		if ((stdin_flags & O_NONBLOCK) == 0
+				&& fcntl(STDIN_FILENO, F_SETFL,
+					stdin_flags | O_NONBLOCK) != -1)
+			restore_stdin_flags = true;
 #endif
 #ifdef HAVE_POSIX_FADVISE
 		// It will fail if stdin is a pipe and that's fine.
@@ -313,13 +437,12 @@
 	int flags = O_RDONLY | O_BINARY | O_NOCTTY;
 
 #ifndef TUKLIB_DOSLIKE
-	// If we accept only regular files, we need to be careful to avoid
-	// problems with special files like devices and FIFOs. O_NONBLOCK
-	// prevents blocking when opening such files. When we want to accept
-	// special files, we must not use O_NONBLOCK, or otherwise we won't
-	// block waiting e.g. FIFOs to become readable.
-	if (reg_files_only)
-		flags |= O_NONBLOCK;
+	// Use non-blocking I/O:
+	//   - It prevents blocking when opening FIFOs and some other
+	//     special files, which is good if we want to accept only
+	//     regular files.
+	//   - It can help avoiding some race conditions with signal handling.
+	flags |= O_NONBLOCK;
 #endif
 
 #if defined(O_NOFOLLOW)
@@ -347,30 +470,13 @@
 	(void)follow_symlinks;
 #endif
 
-	// Try to open the file. If we are accepting non-regular files,
-	// unblock the caught signals so that open() can be interrupted
-	// if it blocks e.g. due to a FIFO file.
-	if (!reg_files_only)
-		signals_unblock();
-
-	// Maybe this wouldn't need a loop, since all the signal handlers for
-	// which we don't use SA_RESTART set user_abort to true. But it
-	// doesn't hurt to have it just in case.
-	do {
-		pair->src_fd = open(pair->src_name, flags);
-	} while (pair->src_fd == -1 && errno == EINTR && !user_abort);
-
-	if (!reg_files_only)
-		signals_block();
+	// Try to open the file. Signals have been blocked so EINTR shouldn't
+	// be possible.
+	pair->src_fd = open(pair->src_name, flags);
 
 	if (pair->src_fd == -1) {
-		// If we were interrupted, don't display any error message.
-		if (errno == EINTR) {
-			// All the signals that don't have SA_RESTART
-			// set user_abort.
-			assert(user_abort);
-			return true;
-		}
+		// Signals (that have a signal handler) have been blocked.
+		assert(errno != EINTR);
 
 #ifdef O_NOFOLLOW
 		// Give an understandable error message if the reason
@@ -400,10 +506,6 @@
 			was_symlink = true;
 
 #	elif defined(__NetBSD__)
-		// As of 2010-09-05, NetBSD doesn't document what errno is
-		// used with O_NOFOLLOW. It is EFTYPE though, and I
-		// understood that is very unlikely to change even though
-		// it is undocumented.
 		if (errno == EFTYPE)
 			was_symlink = true;
 
@@ -433,22 +535,6 @@
 		return true;
 	}
 
-#ifndef TUKLIB_DOSLIKE
-	// Drop O_NONBLOCK, which is used only when we are accepting only
-	// regular files. After the open() call, we want things to block
-	// instead of giving EAGAIN.
-	if (reg_files_only) {
-		flags = fcntl(pair->src_fd, F_GETFL);
-		if (flags == -1)
-			goto error_msg;
-
-		flags &= ~O_NONBLOCK;
-
-		if (fcntl(pair->src_fd, F_SETFL, flags))
-			goto error_msg;
-	}
-#endif
-
 	// Stat the source file. We need the result also when we copy
 	// the permissions, and when unlinking.
 	//
@@ -508,17 +594,23 @@
 			goto error;
 		}
 	}
+
+	// If it is something else than a regular file, wait until
+	// there is input available. This way reading from FIFOs
+	// will work when open() is used with O_NONBLOCK.
+	if (!S_ISREG(pair->src_st.st_mode)) {
+		signals_unblock();
+		const io_wait_ret ret = io_wait(pair, -1, true);
+		signals_block();
+
+		if (ret != IO_WAIT_MORE)
+			goto error;
+	}
 #endif
 
 #ifdef HAVE_POSIX_FADVISE
-	const int fadvise_ret = posix_fadvise(
-			pair->src_fd, 0, 0, POSIX_FADV_SEQUENTIAL);
-
-	// It shouldn't fail, but if it does anyway, it doesn't matter.
-	// Check it with an assertion so that if something gets messed
-	// up in the future, it will get caught when debugging is enabled.
-	assert(fadvise_ret == 0);
-	(void)fadvise_ret;
+	// It will fail with some special files like FIFOs but that is fine.
+	(void)posix_fadvise(pair->src_fd, 0, 0, POSIX_FADV_SEQUENTIAL);
 #endif
 
 	return false;
@@ -569,6 +661,19 @@
 static void
 io_close_src(file_pair *pair, bool success)
 {
+#ifndef TUKLIB_DOSLIKE
+	if (restore_stdin_flags) {
+		assert(pair->src_fd == STDIN_FILENO);
+
+		restore_stdin_flags = false;
+
+		if (fcntl(STDIN_FILENO, F_SETFL, stdin_flags) == -1)
+			message_error(_("Error restoring the status flags "
+					"to standard input: %s"),
+					strerror(errno));
+	}
+#endif
+
 	if (pair->src_fd != STDIN_FILENO && pair->src_fd != -1) {
 #ifdef TUKLIB_DOSLIKE
 		(void)close(pair->src_fd);
@@ -602,6 +707,26 @@
 		pair->dest_fd = STDOUT_FILENO;
 #ifdef TUKLIB_DOSLIKE
 		setmode(STDOUT_FILENO, O_BINARY);
+#else
+		// Try to set O_NONBLOCK if it isn't already set.
+		// If it fails, we assume that stdout is non-blocking
+		// in practice. See the comments in io_open_src_real()
+		// for similar situation with stdin.
+		//
+		// NOTE: O_APPEND may be unset later in this function
+		// and it relies on stdout_flags being set here.
+		stdout_flags = fcntl(STDOUT_FILENO, F_GETFL);
+		if (stdout_flags == -1) {
+			message_error(_("Error getting the file status flags "
+					"from standard output: %s"),
+					strerror(errno));
+			return true;
+		}
+
+		if ((stdout_flags & O_NONBLOCK) == 0
+				&& fcntl(STDOUT_FILENO, F_SETFL,
+					stdout_flags | O_NONBLOCK) != -1)
+				restore_stdout_flags = true;
 #endif
 	} else {
 		pair->dest_name = suffix_get_dest_name(pair->src_name);
@@ -616,6 +741,7 @@
 				message_error("%s: Refusing to write to "
 						"a DOS special file",
 						pair->dest_name);
+				free(pair->dest_name);
 				return true;
 			}
 
@@ -625,6 +751,7 @@
 				message_error("%s: Output file is the same "
 						"as the input file",
 						pair->dest_name);
+				free(pair->dest_name);
 				return true;
 			}
 		}
@@ -639,8 +766,11 @@
 		}
 
 		// Open the file.
-		const int flags = O_WRONLY | O_BINARY | O_NOCTTY
+		int flags = O_WRONLY | O_BINARY | O_NOCTTY
 				| O_CREAT | O_EXCL;
+#ifndef TUKLIB_DOSLIKE
+		flags |= O_NONBLOCK;
+#endif
 		const mode_t mode = S_IRUSR | S_IWUSR;
 		pair->dest_fd = open(pair->dest_name, flags, mode);
 
@@ -682,11 +812,7 @@
 			if (!S_ISREG(pair->dest_st.st_mode))
 				return false;
 
-			const int flags = fcntl(STDOUT_FILENO, F_GETFL);
-			if (flags == -1)
-				return false;
-
-			if (flags & O_APPEND) {
+			if (stdout_flags & O_APPEND) {
 				// Creating a sparse file is not possible
 				// when O_APPEND is active (it's used by
 				// shell's >> redirection). As I understand
@@ -704,13 +830,25 @@
 				if (lseek(STDOUT_FILENO, 0, SEEK_END) == -1)
 					return false;
 
-				if (fcntl(STDOUT_FILENO, F_SETFL,
-						stdout_flags & ~O_APPEND))
+				// Construct the new file status flags.
+				// If O_NONBLOCK was set earlier in this
+				// function, it must be kept here too.
+				int flags = stdout_flags & ~O_APPEND;
+				if (restore_stdout_flags)
+					flags |= O_NONBLOCK;
+
+				// If this fcntl() fails, we continue but won't
+				// try to create sparse output. The original
+				// flags will still be restored if needed (to
+				// unset O_NONBLOCK) when the file is finished.
+				if (fcntl(STDOUT_FILENO, F_SETFL, flags) == -1)
 					return false;
 
-				// Remember the flags so that io_close_dest()
-				// can restore them.
-				stdout_flags = flags;
+				// Disabling O_APPEND succeeded. Mark
+				// that the flags should be restored
+				// in io_close_dest(). (This may have already
+				// been set when enabling O_NONBLOCK.)
+				restore_stdout_flags = true;
 
 			} else if (lseek(STDOUT_FILENO, 0, SEEK_CUR)
 					!= pair->dest_st.st_size) {
@@ -751,13 +889,12 @@
 {
 #ifndef TUKLIB_DOSLIKE
 	// If io_open_dest() has disabled O_APPEND, restore it here.
-	if (stdout_flags != 0) {
+	if (restore_stdout_flags) {
 		assert(pair->dest_fd == STDOUT_FILENO);
 
-		const int fail = fcntl(STDOUT_FILENO, F_SETFL, stdout_flags);
-		stdout_flags = 0;
+		restore_stdout_flags = false;
 
-		if (fail) {
+		if (fcntl(STDOUT_FILENO, F_SETFL, stdout_flags) == -1) {
 			message_error(_("Error restoring the O_APPEND flag "
 					"to standard output: %s"),
 					strerror(errno));
@@ -880,12 +1017,30 @@
 				continue;
 			}
 
+#ifndef TUKLIB_DOSLIKE
+			if (errno == EAGAIN || errno == EWOULDBLOCK) {
+				const io_wait_ret ret = io_wait(pair,
+						mytime_get_flush_timeout(),
+						true);
+				switch (ret) {
+				case IO_WAIT_MORE:
+					continue;
+
+				case IO_WAIT_ERROR:
+					return SIZE_MAX;
+
+				case IO_WAIT_TIMEOUT:
+					return size - left;
+
+				default:
+					message_bug();
+				}
+			}
+#endif
+
 			message_error(_("%s: Read error: %s"),
 					pair->src_name, strerror(errno));
 
-			// FIXME Is this needed?
-			pair->src_eof = true;
-
 			return SIZE_MAX;
 		}
 
@@ -945,11 +1100,20 @@
 		if (amount == -1) {
 			if (errno == EINTR) {
 				if (user_abort)
-					return -1;
+					return true;
 
 				continue;
 			}
 
+#ifndef TUKLIB_DOSLIKE
+			if (errno == EAGAIN || errno == EWOULDBLOCK) {
+				if (io_wait(pair, -1, false) == IO_WAIT_MORE)
+					continue;
+
+				return true;
+			}
+#endif
+
 			// Handle broken pipe specially. gzip and bzip2
 			// don't print anything on SIGPIPE. In addition,
 			// gzip --quiet uses exit status 2 (warning) on
diff --git a/src/xz/file_io.h b/src/xz/file_io.h
index ef63932..2de3379 100644
--- a/src/xz/file_io.h
+++ b/src/xz/file_io.h
@@ -68,6 +68,14 @@
 extern void io_init(void);
 
 
+#ifndef TUKLIB_DOSLIKE
+/// \brief      Write a byte to user_abort_pipe[1]
+///
+/// This is called from a signal handler.
+extern void io_write_to_user_abort_pipe(void);
+#endif
+
+
 /// \brief      Disable creation of sparse files when decompressing
 extern void io_no_sparse(void);
 
diff --git a/src/xz/hardware.c b/src/xz/hardware.c
index a4733c2..ff32f6d 100644
--- a/src/xz/hardware.c
+++ b/src/xz/hardware.c
@@ -11,12 +11,11 @@
 ///////////////////////////////////////////////////////////////////////////////
 
 #include "private.h"
-#include "tuklib_cpucores.h"
 
 
-/// Maximum number of free *coder* threads. This can be set with
+/// Maximum number of worker threads. This can be set with
 /// the --threads=NUM command line option.
-static uint32_t threadlimit;
+static uint32_t threads_max = 1;
 
 /// Memory usage limit for compression
 static uint64_t memlimit_compress;
@@ -29,15 +28,23 @@
 
 
 extern void
-hardware_threadlimit_set(uint32_t new_threadlimit)
+hardware_threads_set(uint32_t n)
 {
-	if (new_threadlimit == 0) {
-		// The default is the number of available CPU cores.
-		threadlimit = tuklib_cpucores();
-		if (threadlimit == 0)
-			threadlimit = 1;
+	if (n == 0) {
+		// Automatic number of threads was requested.
+		// If threading support was enabled at build time,
+		// use the number of available CPU cores. Otherwise
+		// use one thread since disabling threading support
+		// omits lzma_cputhreads() from liblzma.
+#ifdef MYTHREAD_ENABLED
+		threads_max = lzma_cputhreads();
+		if (threads_max == 0)
+			threads_max = 1;
+#else
+		threads_max = 1;
+#endif
 	} else {
-		threadlimit = new_threadlimit;
+		threads_max = n;
 	}
 
 	return;
@@ -45,9 +52,9 @@
 
 
 extern uint32_t
-hardware_threadlimit_get(void)
+hardware_threads_get(void)
 {
-	return threadlimit;
+	return threads_max;
 }
 
 
@@ -139,6 +146,5 @@
 
 	// Set the defaults.
 	hardware_memlimit_set(0, true, true, false);
-	hardware_threadlimit_set(0);
 	return;
 }
diff --git a/src/xz/hardware.h b/src/xz/hardware.h
index ad526f2..4fae618 100644
--- a/src/xz/hardware.h
+++ b/src/xz/hardware.h
@@ -15,12 +15,11 @@
 extern void hardware_init(void);
 
 
-/// Set custom value for maximum number of coder threads.
-extern void hardware_threadlimit_set(uint32_t threadlimit);
+/// Set the maximum number of worker threads.
+extern void hardware_threads_set(uint32_t threadlimit);
 
-/// Get the maximum number of coder threads. Some additional helper threads
-/// are allowed on top of this).
-extern uint32_t hardware_threadlimit_get(void);
+/// Get the maximum number of worker threads.
+extern uint32_t hardware_threads_get(void);
 
 
 /// Set the memory usage limit. There are separate limits for compression
diff --git a/src/xz/list.c b/src/xz/list.c
index a9e0adb..449c2bc 100644
--- a/src/xz/list.c
+++ b/src/xz/list.c
@@ -230,6 +230,20 @@
 			goto error;
 		}
 
+		// Check that the Stream Footer doesn't specify something
+		// that we don't support. This can only happen if the xz
+		// version is older than liblzma and liblzma supports
+		// something new.
+		//
+		// It is enough to check Stream Footer. Stream Header must
+		// match when it is compared against Stream Footer with
+		// lzma_stream_flags_compare().
+		if (footer_flags.version != 0) {
+			message_error("%s: %s", pair->src_name,
+					message_strm(LZMA_OPTIONS_ERROR));
+			goto error;
+		}
+
 		// Check that the size of the Index field looks sane.
 		lzma_vli index_size = footer_flags.backward_size;
 		if ((lzma_vli)(pos) < index_size + LZMA_STREAM_HEADER_SIZE) {
@@ -456,7 +470,19 @@
 	switch (lzma_block_compressed_size(&block,
 			iter->block.unpadded_size)) {
 	case LZMA_OK:
-		break;
+		// Validate also block.uncompressed_size if it is present.
+		// If it isn't present, there's no need to set it since
+		// we aren't going to actually decompress the Block; if
+		// we were decompressing, then we should set it so that
+		// the Block decoder could validate the Uncompressed Size
+		// that was stored in the Index.
+		if (block.uncompressed_size == LZMA_VLI_UNKNOWN
+				|| block.uncompressed_size
+					== iter->block.uncompressed_size)
+			break;
+
+		// If the above fails, the file is corrupt so
+		// LZMA_DATA_ERROR is a good error code.
 
 	case LZMA_DATA_ERROR:
 		// Free the memory allocated by lzma_block_header_decode().
diff --git a/src/xz/main.c b/src/xz/main.c
index 4e5b49e..5608229 100644
--- a/src/xz/main.c
+++ b/src/xz/main.c
@@ -212,7 +212,7 @@
 
 	// Process the files given on the command line. Note that if no names
 	// were given, args_parse() gave us a fake "-" filename.
-	for (size_t i = 0; i < args.arg_count && !user_abort; ++i) {
+	for (unsigned i = 0; i < args.arg_count && !user_abort; ++i) {
 		if (strcmp("-", args.arg_names[i]) == 0) {
 			// Processing from stdin to stdout. Check that we
 			// aren't writing compressed data to a terminal or
@@ -277,6 +277,7 @@
 
 #ifndef NDEBUG
 	coder_free();
+	args_free();
 #endif
 
 	// If we have got a signal, raise it to kill the program instead
diff --git a/src/xz/message.c b/src/xz/message.c
index 2b6ac5f..f88c123 100644
--- a/src/xz/message.c
+++ b/src/xz/message.c
@@ -12,10 +12,6 @@
 
 #include "private.h"
 
-#ifdef HAVE_SYS_TIME_H
-#	include <sys/time.h>
-#endif
-
 #include <stdarg.h>
 
 
@@ -64,9 +60,6 @@
 /// and estimate remaining time.
 static uint64_t expected_in_size;
 
-/// Time when we started processing the file
-static uint64_t start_time;
-
 
 // Use alarm() and SIGALRM when they are supported. This has two minor
 // advantages over the alternative of polling gettimeofday():
@@ -112,16 +105,6 @@
 #endif
 
 
-/// Get the current time as microseconds since epoch
-static uint64_t
-my_time(void)
-{
-	struct timeval tv;
-	gettimeofday(&tv, NULL);
-	return (uint64_t)(tv.tv_sec) * UINT64_C(1000000) + tv.tv_usec;
-}
-
-
 extern void
 message_init(void)
 {
@@ -264,11 +247,10 @@
 	// It is needed to find out the position in the stream.
 	progress_strm = strm;
 
-	// Store the processing start time of the file and its expected size.
-	// If we aren't printing any statistics, then these are unused. But
-	// since it is possible that the user sends us a signal to show
-	// statistics, we need to have these available anyway.
-	start_time = my_time();
+	// Store the expected size of the file. If we aren't printing any
+	// statistics, then is will be unused. But since it is possible
+	// that the user sends us a signal to show statistics, we need
+	// to have it available anyway.
 	expected_in_size = in_size;
 
 	// Indicate that progress info may need to be printed before
@@ -290,7 +272,7 @@
 		alarm(1);
 #else
 		progress_needs_updating = true;
-		progress_next_update = 1000000;
+		progress_next_update = 1000;
 #endif
 	}
 
@@ -364,7 +346,7 @@
 {
 	// Don't print the speed immediately, since the early values look
 	// somewhat random.
-	if (elapsed < 3000000)
+	if (elapsed < 3000)
 		return "";
 
 	static const char unit[][8] = {
@@ -377,7 +359,7 @@
 
 	// Calculate the speed as KiB/s.
 	double speed = (double)(uncompressed_pos)
-			/ ((double)(elapsed) * (1024.0 / 1e6));
+			/ ((double)(elapsed) * (1024.0 / 1000.0));
 
 	// Adjust the unit of the speed if needed.
 	while (speed > 999.0) {
@@ -399,15 +381,16 @@
 }
 
 
-/// Make a string indicating elapsed or remaining time. The format is either
+/// Make a string indicating elapsed time. The format is either
 /// M:SS or H:MM:SS depending on if the time is an hour or more.
 static const char *
-progress_time(uint64_t useconds)
+progress_time(uint64_t mseconds)
 {
 	// 9999 hours = 416 days
 	static char buf[sizeof("9999:59:59")];
 
-	uint32_t seconds = useconds / 1000000;
+	// 32-bit variable is enough for elapsed time (136 years).
+	uint32_t seconds = (uint32_t)(mseconds / 1000);
 
 	// Don't show anything if the time is zero or ridiculously big.
 	if (seconds == 0 || seconds > ((9999 * 60) + 59) * 60 + 59)
@@ -445,14 +428,14 @@
 	//  - Only a few seconds has passed since we started (de)compressing,
 	//    so estimate would be too inaccurate.
 	if (expected_in_size == 0 || in_pos > expected_in_size
-			|| in_pos < (UINT64_C(1) << 19) || elapsed < 8000000)
+			|| in_pos < (UINT64_C(1) << 19) || elapsed < 8000)
 		return "";
 
 	// Calculate the estimate. Don't give an estimate of zero seconds,
 	// since it is possible that all the input has been already passed
 	// to the library, but there is still quite a bit of output pending.
 	uint32_t remaining = (double)(expected_in_size - in_pos)
-			* ((double)(elapsed) / 1e6) / (double)(in_pos);
+			* ((double)(elapsed) / 1000.0) / (double)(in_pos);
 	if (remaining < 1)
 		remaining = 1;
 
@@ -518,28 +501,26 @@
 }
 
 
-/// Calculate the elapsed time as microseconds.
-static uint64_t
-progress_elapsed(void)
-{
-	return my_time() - start_time;
-}
-
-
-/// Get information about position in the stream. This is currently simple,
-/// but it will become more complicated once we have multithreading support.
+/// Get how much uncompressed and compressed data has been processed.
 static void
 progress_pos(uint64_t *in_pos,
 		uint64_t *compressed_pos, uint64_t *uncompressed_pos)
 {
-	*in_pos = progress_strm->total_in;
+	uint64_t out_pos;
+	lzma_get_progress(progress_strm, in_pos, &out_pos);
+
+	// It cannot have processed more input than it has been given.
+	assert(*in_pos <= progress_strm->total_in);
+
+	// It cannot have produced more output than it claims to have ready.
+	assert(out_pos >= progress_strm->total_out);
 
 	if (opt_mode == MODE_COMPRESS) {
-		*compressed_pos = progress_strm->total_out;
-		*uncompressed_pos = progress_strm->total_in;
+		*compressed_pos = out_pos;
+		*uncompressed_pos = *in_pos;
 	} else {
-		*compressed_pos = progress_strm->total_in;
-		*uncompressed_pos = progress_strm->total_out;
+		*compressed_pos = *in_pos;
+		*uncompressed_pos = out_pos;
 	}
 
 	return;
@@ -553,13 +534,13 @@
 		return;
 
 	// Calculate how long we have been processing this file.
-	const uint64_t elapsed = progress_elapsed();
+	const uint64_t elapsed = mytime_get_elapsed();
 
 #ifndef SIGALRM
 	if (progress_next_update > elapsed)
 		return;
 
-	progress_next_update = elapsed + 1000000;
+	progress_next_update = elapsed + 1000;
 #endif
 
 	// Get our current position in the stream.
@@ -652,7 +633,7 @@
 
 	progress_active = false;
 
-	const uint64_t elapsed = progress_elapsed();
+	const uint64_t elapsed = mytime_get_elapsed();
 
 	signals_block();
 
@@ -1142,6 +1123,8 @@
 "                      `auto' (default), `xz', `lzma', and `raw'\n"
 "  -C, --check=CHECK   integrity check type: `none' (use with caution),\n"
 "                      `crc32', `crc64' (default), or `sha256'"));
+		puts(_(
+"      --ignore-check  don't verify the integrity check when decompressing"));
 	}
 
 	puts(_(
@@ -1152,11 +1135,25 @@
 "  -e, --extreme       try to improve compression ratio by using more CPU time;\n"
 "                      does not affect decompressor memory requirements"));
 
+	puts(_(
+"  -T, --threads=NUM   use at most NUM threads; the default is 1; set to 0\n"
+"                      to use as many threads as there are processor cores"));
+
 	if (long_help) {
 		puts(_(
 "      --block-size=SIZE\n"
-"                      when compressing to the .xz format, start a new block\n"
-"                      after every SIZE bytes of input; 0=disabled (default)"));
+"                      start a new .xz block after every SIZE bytes of input;\n"
+"                      use this to set the block size for threaded compression"));
+		puts(_(
+"      --block-list=SIZES\n"
+"                      start a new .xz block after the given comma-separated\n"
+"                      intervals of uncompressed data"));
+		puts(_(
+"      --flush-timeout=TIMEOUT\n"
+"                      when compressing, if more than TIMEOUT milliseconds has\n"
+"                      passed since the previous flush and reading more input\n"
+"                      would block, all pending data is flushed out"
+		));
 		puts(_( // xgettext:no-c-format
 "      --memlimit-compress=LIMIT\n"
 "      --memlimit-decompress=LIMIT\n"
@@ -1252,5 +1249,10 @@
 			PACKAGE_BUGREPORT);
 	printf(_("%s home page: <%s>\n"), PACKAGE_NAME, PACKAGE_URL);
 
+#if LZMA_VERSION_STABILITY != LZMA_VERSION_STABILITY_STABLE
+	puts(_(
+"THIS IS A DEVELOPMENT VERSION NOT INTENDED FOR PRODUCTION USE."));
+#endif
+
 	tuklib_exit(E_SUCCESS, E_ERROR, verbosity != V_SILENT);
 }
diff --git a/src/xz/mytime.c b/src/xz/mytime.c
new file mode 100644
index 0000000..4be184f
--- /dev/null
+++ b/src/xz/mytime.c
@@ -0,0 +1,89 @@
+///////////////////////////////////////////////////////////////////////////////
+//
+/// \file       mytime.c
+/// \brief      Time handling functions
+//
+//  Author:     Lasse Collin
+//
+//  This file has been put into the public domain.
+//  You can do whatever you want with this file.
+//
+///////////////////////////////////////////////////////////////////////////////
+
+#include "private.h"
+
+#if !(defined(HAVE_CLOCK_GETTIME) && HAVE_DECL_CLOCK_MONOTONIC)
+#	include <sys/time.h>
+#endif
+
+uint64_t opt_flush_timeout = 0;
+bool flush_needed;
+
+static uint64_t start_time;
+static uint64_t next_flush;
+
+
+/// \brief      Get the current time as milliseconds
+///
+/// It's relative to some point but not necessarily to the UNIX Epoch.
+static uint64_t
+mytime_now(void)
+{
+	// NOTE: HAVE_DECL_CLOCK_MONOTONIC is always defined to 0 or 1.
+#if defined(HAVE_CLOCK_GETTIME) && HAVE_DECL_CLOCK_MONOTONIC
+	// If CLOCK_MONOTONIC was available at compile time but for some
+	// reason isn't at runtime, fallback to CLOCK_REALTIME which
+	// according to POSIX is mandatory for all implementations.
+	static clockid_t clk_id = CLOCK_MONOTONIC;
+	struct timespec tv;
+	while (clock_gettime(clk_id, &tv))
+		clk_id = CLOCK_REALTIME;
+
+	return (uint64_t)(tv.tv_sec) * UINT64_C(1000) + tv.tv_nsec / 1000000;
+#else
+	struct timeval tv;
+	gettimeofday(&tv, NULL);
+	return (uint64_t)(tv.tv_sec) * UINT64_C(1000) + tv.tv_usec / 1000;
+#endif
+}
+
+
+extern void
+mytime_set_start_time(void)
+{
+	start_time = mytime_now();
+	next_flush = start_time + opt_flush_timeout;
+	flush_needed = false;
+	return;
+}
+
+
+extern uint64_t
+mytime_get_elapsed(void)
+{
+	return mytime_now() - start_time;
+}
+
+
+extern void
+mytime_set_flush_time(void)
+{
+	next_flush = mytime_now() + opt_flush_timeout;
+	flush_needed = false;
+	return;
+}
+
+
+extern int
+mytime_get_flush_timeout(void)
+{
+	if (opt_flush_timeout == 0 || opt_mode != MODE_COMPRESS)
+		return -1;
+
+	const uint64_t now = mytime_now();
+	if (now >= next_flush)
+		return 0;
+
+	const uint64_t remaining = next_flush - now;
+	return remaining > INT_MAX ? INT_MAX : (int)remaining;
+}
diff --git a/src/xz/mytime.h b/src/xz/mytime.h
new file mode 100644
index 0000000..ea291ee
--- /dev/null
+++ b/src/xz/mytime.h
@@ -0,0 +1,47 @@
+///////////////////////////////////////////////////////////////////////////////
+//
+/// \file       mytime.h
+/// \brief      Time handling functions
+//
+//  Author:     Lasse Collin
+//
+//  This file has been put into the public domain.
+//  You can do whatever you want with this file.
+//
+///////////////////////////////////////////////////////////////////////////////
+
+
+/// \brief      Number of milliseconds to between LZMA_SYNC_FLUSHes
+///
+/// If 0, timed flushing is disabled. Otherwise if no more input is available
+/// and not at the end of the file and at least opt_flush_timeout milliseconds
+/// has elapsed since the start of compression or the previous flushing
+/// (LZMA_SYNC_FLUSH or LZMA_FULL_FLUSH), set LZMA_SYNC_FLUSH to flush
+/// the pending data.
+extern uint64_t opt_flush_timeout;
+
+
+/// \brief      True when flushing is needed due to expired timeout
+extern bool flush_needed;
+
+
+/// \brief      Store the time when (de)compression was started
+///
+/// The start time is also stored as the time of the first flush.
+extern void mytime_set_start_time(void);
+
+
+/// \brief      Get the number of milliseconds since the operation started
+extern uint64_t mytime_get_elapsed(void);
+
+
+/// \brief      Store the time of when compressor was flushed
+extern void mytime_set_flush_time(void);
+
+
+/// \brief      Get the number of milliseconds until the next flush
+///
+/// This returns -1 if no timed flushing is used.
+///
+/// The return value is inteded for use with poll().
+extern int mytime_get_flush_timeout(void);
diff --git a/src/xz/options.c b/src/xz/options.c
index f21a0ba..de05364 100644
--- a/src/xz/options.c
+++ b/src/xz/options.c
@@ -31,8 +31,8 @@
 } option_map;
 
 
-/// Parses option=value pairs that are separated with colons, semicolons,
-/// or commas: opt=val:opt=val;opt=val,opt=val
+/// Parses option=value pairs that are separated with commas:
+/// opt=val,opt=val,opt=val
 ///
 /// Each option is a string, that is converted to an integer using the
 /// index where the option string is in the array.
@@ -59,7 +59,7 @@
 static void
 parse_options(const char *str, const option_map *opts,
 		void (*set)(void *filter_options,
-			uint32_t key, uint64_t value, const char *valuestr),
+			unsigned key, uint64_t value, const char *valuestr),
 		void *filter_options)
 {
 	if (str == NULL || str[0] == '\0')
@@ -87,7 +87,7 @@
 					"pairs separated with commas"), str);
 
 		// Look for the option name from the option map.
-		size_t i = 0;
+		unsigned i = 0;
 		while (true) {
 			if (opts[i].name == NULL)
 				message_fatal(_("%s: Invalid option name"),
@@ -103,7 +103,7 @@
 		if (opts[i].map != NULL) {
 			// value is a string which we should map
 			// to an integer.
-			size_t j;
+			unsigned j;
 			for (j = 0; opts[i].map[j].name != NULL; ++j) {
 				if (strcmp(opts[i].map[j].name, value) == 0)
 					break;
@@ -149,7 +149,7 @@
 
 
 static void
-set_delta(void *options, uint32_t key, uint64_t value,
+set_delta(void *options, unsigned key, uint64_t value,
 		const char *valuestr lzma_attribute((__unused__)))
 {
 	lzma_options_delta *opt = options;
@@ -193,7 +193,7 @@
 
 
 static void
-set_bcj(void *options, uint32_t key, uint64_t value,
+set_bcj(void *options, unsigned key, uint64_t value,
 		const char *valuestr lzma_attribute((__unused__)))
 {
 	lzma_options_bcj *opt = options;
@@ -249,7 +249,7 @@
 
 
 static void
-set_lzma(void *options, uint32_t key, uint64_t value, const char *valuestr)
+set_lzma(void *options, unsigned key, uint64_t value, const char *valuestr)
 {
 	lzma_options_lzma *opt = options;
 
diff --git a/src/xz/private.h b/src/xz/private.h
index 6b01e51..4acfa8d 100644
--- a/src/xz/private.h
+++ b/src/xz/private.h
@@ -12,6 +12,7 @@
 
 #include "sysdefs.h"
 #include "mythread.h"
+
 #include "lzma.h"
 
 #include <sys/types.h>
@@ -45,6 +46,7 @@
 #endif
 
 #include "main.h"
+#include "mytime.h"
 #include "coder.h"
 #include "message.h"
 #include "args.h"
diff --git a/src/xz/signals.c b/src/xz/signals.c
index de21364..5387c42 100644
--- a/src/xz/signals.c
+++ b/src/xz/signals.c
@@ -41,6 +41,11 @@
 {
 	exit_signal = sig;
 	user_abort = true;
+
+#ifndef TUKLIB_DOSLIKE
+	io_write_to_user_abort_pipe();
+#endif
+
 	return;
 }
 
@@ -77,17 +82,19 @@
 		sigaddset(&hooked_signals, message_progress_sigs[i]);
 #endif
 
-	struct sigaction sa;
+	// Using "my_sa" because "sa" may conflict with a sockaddr variable
+	// from system headers on Solaris.
+	struct sigaction my_sa;
 
 	// All the signals that we handle we also blocked while the signal
 	// handler runs.
-	sa.sa_mask = hooked_signals;
+	my_sa.sa_mask = hooked_signals;
 
 	// Don't set SA_RESTART, because we want EINTR so that we can check
 	// for user_abort and cleanup before exiting. We block the signals
 	// for which we have established a handler when we don't want EINTR.
-	sa.sa_flags = 0;
-	sa.sa_handler = &signal_handler;
+	my_sa.sa_flags = 0;
+	my_sa.sa_handler = &signal_handler;
 
 	for (size_t i = 0; i < ARRAY_SIZE(sigs); ++i) {
 		// If the parent process has left some signals ignored,
@@ -98,7 +105,7 @@
 			continue;
 
 		// Establish the signal handler.
-		if (sigaction(sigs[i], &sa, NULL))
+		if (sigaction(sigs[i], &my_sa, NULL))
 			message_signal_handler();
 	}
 
diff --git a/src/xz/suffix.c b/src/xz/suffix.c
index e515626..9d4fcd1 100644
--- a/src/xz/suffix.c
+++ b/src/xz/suffix.c
@@ -390,7 +390,7 @@
 	// Empty suffix and suffixes having a directory separator are
 	// rejected. Such suffixes would break things later.
 	if (suffix[0] == '\0' || has_dir_sep(suffix))
-		message_fatal(_("%s: Invalid filename suffix"), optarg);
+		message_fatal(_("%s: Invalid filename suffix"), suffix);
 
 	// Replace the old custom_suffix (if any) with the new suffix.
 	free(custom_suffix);
diff --git a/src/xz/util.c b/src/xz/util.c
index 987b443..35850f4 100644
--- a/src/xz/util.c
+++ b/src/xz/util.c
@@ -26,9 +26,19 @@
 {
 	assert(size > 0);
 
+	// Save ptr so that we can free it if realloc fails.
+	// The point is that message_fatal ends up calling stdio functions
+	// which in some libc implementations might allocate memory from
+	// the heap. Freeing ptr improves the chances that there's free
+	// memory for stdio functions if they need it.
+	void *p = ptr;
 	ptr = realloc(ptr, size);
-	if (ptr == NULL)
-		message_fatal("%s", strerror(errno));
+
+	if (ptr == NULL) {
+		const int saved_errno = errno;
+		free(p);
+		message_fatal("%s", strerror(saved_errno));
+	}
 
 	return ptr;
 }
diff --git a/src/xz/xz.1 b/src/xz/xz.1
index 0952f2d..bc5514d 100644
--- a/src/xz/xz.1
+++ b/src/xz/xz.1
@@ -5,16 +5,17 @@
 .\" This file has been put into the public domain.
 .\" You can do whatever you want with this file.
 .\"
-.TH XZ 1 "2012-07-01" "Tukaani" "XZ Utils"
+.TH XZ 1 "2015-05-11" "Tukaani" "XZ Utils"
 .
 .SH NAME
 xz, unxz, xzcat, lzma, unlzma, lzcat \- Compress or decompress .xz and .lzma files
 .
 .SH SYNOPSIS
 .B xz
-.RI [ option ]...
-.RI [ file ]...
-.PP
+.RI [ option... ]
+.RI [ file... ]
+.
+.SH COMMAND ALIASES
 .B unxz
 is equivalent to
 .BR "xz \-\-decompress" .
@@ -608,6 +609,25 @@
 headers is always verified with CRC32.
 It is not possible to change or disable it.
 .TP
+.B \-\-ignore\-check
+Don't verify the integrity check of the compressed data when decompressing.
+The CRC32 values in the
+.B .xz
+headers will still be verified normally.
+.IP ""
+.B "Do not use this option unless you know what you are doing."
+Possible reasons to use this option:
+.RS
+.IP \(bu 3
+Trying to recover data from a corrupt .xz file.
+.IP \(bu 3
+Speeding up decompression.
+This matters mostly with SHA-256 or
+with files that have compressed extremely well.
+It's recommended to not use this option for this purpose
+unless the file integrity is verified externally in some other way.
+.RE
+.TP
 .BR \-0 " ... " \-9
 Select a compression preset level.
 The default is
@@ -731,7 +751,7 @@
 DecMem contains the decompressor memory requirements.
 That is, the compression settings determine
 the memory requirements of the decompressor.
-The exact decompressor memory usage is slighly more than
+The exact decompressor memory usage is slightly more than
 the LZMA2 dictionary size, but the values in the table
 have been rounded up to the next full MiB.
 .RE
@@ -806,8 +826,117 @@
 format, split the input data into blocks of
 .I size
 bytes.
-The blocks are compressed independently from each other.
-.\" FIXME: Explain how to his can be used for random access and threading.
+The blocks are compressed independently from each other,
+which helps with multi-threading and
+makes limited random-access decompression possible.
+This option is typically used to override the default
+block size in multi-threaded mode,
+but this option can be used in single-threaded mode too.
+.IP ""
+In multi-threaded mode about three times
+.I size
+bytes will be allocated in each thread for buffering input and output.
+The default
+.I size
+is three times the LZMA2 dictionary size or 1 MiB,
+whichever is more.
+Typically a good value is 2\-4 times
+the size of the LZMA2 dictionary or at least 1 MiB.
+Using
+.I size
+less than the LZMA2 dictionary size is waste of RAM
+because then the LZMA2 dictionary buffer will never get fully used.
+The sizes of the blocks are stored in the block headers,
+which a future version of
+.B xz
+will use for multi-threaded decompression.
+.IP ""
+In single-threaded mode no block splitting is done by default.
+Setting this option doesn't affect memory usage.
+No size information is stored in block headers,
+thus files created in single-threaded mode
+won't be identical to files created in multi-threaded mode.
+The lack of size information also means that a future version of
+.B xz
+won't be able decompress the files in multi-threaded mode.
+.TP
+.BI \-\-block\-list= sizes
+When compressing to the
+.B .xz
+format, start a new block after
+the given intervals of uncompressed data.
+.IP ""
+The uncompressed
+.I sizes
+of the blocks are specified as a comma-separated list.
+Omitting a size (two or more consecutive commas) is a shorthand
+to use the size of the previous block.
+.IP ""
+If the input file is bigger than the sum of
+.IR sizes ,
+the last value in
+.I sizes
+is repeated until the end of the file.
+A special value of
+.B 0
+may be used as the last value to indicate that
+the rest of the file should be encoded as a single block.
+.IP ""
+If one specifies
+.I sizes
+that exceed the encoder's block size
+(either the default value in threaded mode or
+the value specified with \fB\-\-block\-size=\fIsize\fR),
+the encoder will create additional blocks while
+keeping the boundaries specified in
+.IR sizes .
+For example, if one specifies
+.B \-\-block\-size=10MiB
+.B \-\-block\-list=5MiB,10MiB,8MiB,12MiB,24MiB
+and the input file is 80 MiB,
+one will get 11 blocks:
+5, 10, 8, 10, 2, 10, 10, 4, 10, 10, and 1 MiB.
+.IP ""
+In multi-threaded mode the sizes of the blocks
+are stored in the block headers.
+This isn't done in single-threaded mode,
+so the encoded output won't be
+identical to that of the multi-threaded mode.
+.TP
+.BI \-\-flush\-timeout= timeout
+When compressing, if more than
+.I timeout
+milliseconds (a positive integer) has passed since the previous flush and
+reading more input would block,
+all the pending input data is flushed from the encoder and
+made available in the output stream.
+This can be useful if
+.B xz
+is used to compress data that is streamed over a network.
+Small
+.I timeout
+values make the data available at the receiving end
+with a small delay, but large
+.I timeout
+values give better compression ratio.
+.IP ""
+This feature is disabled by default.
+If this option is specified more than once, the last one takes effect.
+The special
+.I timeout
+value of
+.B 0
+can be used to explicitly disable this feature.
+.IP ""
+This feature is not available on non-POSIX systems.
+.IP ""
+.\" FIXME
+.B "This feature is still experimental."
+Currently
+.B xz
+is unsuitable for decompressing the stream in real time due to how
+.B xz
+does buffering.
 .TP
 .BI \-\-memlimit\-compress= limit
 Set a memory usage limit for compression.
@@ -907,33 +1036,45 @@
 .TP
 \fB\-T\fR \fIthreads\fR, \fB\-\-threads=\fIthreads
 Specify the number of worker threads to use.
+Setting
+.I threads
+to a special value
+.B 0
+makes
+.B xz
+use as many threads as there are CPU cores on the system.
 The actual number of threads can be less than
 .I threads
+if the input file is not big enough
+for threading with the given settings or
 if using more threads would exceed the memory usage limit.
 .IP ""
-.B "Multithreaded compression and decompression are not"
-.B "implemented yet, so this option has no effect for now."
+Currently the only threading method is to split the input into
+blocks and compress them independently from each other.
+The default block size depends on the compression level and
+can be overriden with the
+.BI \-\-block\-size= size
+option.
 .IP ""
-.B "As of writing (2010-09-27), it hasn't been decided"
-.B "if threads will be used by default on multicore systems"
-.B "once support for threading has been implemented."
-.B "Comments are welcome."
-The complicating factor is that using many threads
-will increase the memory usage dramatically.
-Note that if multithreading will be the default,
-it will probably be done so that single-threaded and
-multithreaded modes produce the same output,
-so compression ratio won't be significantly affected
-if threading will be enabled by default.
+Threaded decompression hasn't been implemented yet.
+It will only work on files that contain multiple blocks
+with size information in block headers.
+All files compressed in multi-threaded mode meet this condition,
+but files compressed in single-threaded mode don't even if
+.BI \-\-block\-size= size
+is used.
 .
 .SS "Custom compressor filter chains"
 A custom filter chain allows specifying
 the compression settings in detail instead of relying on
-the settings associated to the preset levels.
+the settings associated to the presets.
 When a custom filter chain is specified,
-the compression preset level options
-(\fB\-0\fR ... \fB\-9\fR and \fB\-\-extreme\fR) are
-silently ignored.
+preset options (\fB\-0\fR ... \fB\-9\fR and \fB\-\-extreme\fR)
+earlier on the command line are forgotten.
+If a preset option is specified
+after one or more custom filter chain options,
+the new preset takes effect and
+the custom filter chain options specified earlier are forgotten.
 .PP
 A filter chain is comparable to piping on the command line.
 When compressing, the uncompressed input goes to the first filter,
@@ -966,6 +1107,15 @@
 are ignored.
 Every option has a default value, so you need to
 specify only those you want to change.
+.PP
+To see the whole filter chain and
+.IR options ,
+use
+.B "xz \-vv"
+(that is, use
+.B \-\-verbose
+twice).
+This works also for viewing the filter chain options used by presets.
 .TP
 \fB\-\-lzma1\fR[\fB=\fIoptions\fR]
 .PD 0
@@ -1008,13 +1158,12 @@
 .BR e ,
 which matches
 .BR \-\-extreme .
-The default
-.I preset
-is
-.BR 6 ,
-from which the default values for the rest of the LZMA1 or LZMA2
+If no
+.B preset
+is specified, the default values of LZMA1 or LZMA2
 .I options
-are taken.
+are taken from the preset
+.BR 6 .
 .TP
 .BI dict= size
 Dictionary (history buffer)
@@ -1610,7 +1759,7 @@
 .BR \-\-info\-memory ,
 and
 .BR \-\-list .
-It will be supported for normal compression and
+It will be supported for compression and
 decompression in the future.
 .
 .SS Version
@@ -2229,14 +2378,15 @@
 builds of the same XZ Utils version,
 if different build options are used.
 .PP
-The above means that implementing
+The above means that once
 .B \-\-rsyncable
-to create rsyncable
-.B .xz
-files is not going to happen without
-freezing a part of the encoder
-implementation, which can then be used with
-.BR \-\-rsyncable .
+has been implemented,
+the resulting files won't necessarily be rsyncable
+unless both old and new files have been compressed
+with the same xz version.
+This problem can be fixed if a part of the encoder
+implementation is frozen to keep rsyncable output
+stable across xz versions.
 .
 .SS "Embedded .xz decompressors"
 Embedded
diff --git a/src/xzdec/Makefile.am b/src/xzdec/Makefile.am
index 2348e4e..5ff8e37 100644
--- a/src/xzdec/Makefile.am
+++ b/src/xzdec/Makefile.am
@@ -14,8 +14,8 @@
 
 xzdec_SOURCES = \
 	xzdec.c \
-	$(top_srcdir)/src/common/tuklib_progname.c \
-	$(top_srcdir)/src/common/tuklib_exit.c
+	../common/tuklib_progname.c \
+	../common/tuklib_exit.c
 
 if COND_W32
 xzdec_SOURCES += xzdec_w32res.rc
@@ -37,8 +37,8 @@
 
 lzmadec_SOURCES = \
 	xzdec.c \
-	$(top_srcdir)/src/common/tuklib_progname.c \
-	$(top_srcdir)/src/common/tuklib_exit.c
+	../common/tuklib_progname.c \
+	../common/tuklib_exit.c
 
 if COND_W32
 lzmadec_SOURCES += lzmadec_w32res.rc
@@ -59,7 +59,14 @@
 if COND_LZMADEC
 bin_PROGRAMS += lzmadec
 
-# FIXME: If xzdec is disabled, this will create a dangling symlink.
+# Create the symlink lzmadec.1->xzdec.1 only if xzdec.1 was installed.
+# This is better than creating a dangling symlink, especially
+# because creating the link may fail due to the directory being missing.
+#
+# FIXME: The correct solution would be to install xzdec.1 as lzmadec.1
+# but I don't know what is the sane way to do it and since this is a bit
+# unusual situation anyway, it's not that important.
+if COND_XZDEC
 install-data-hook:
 	cd $(DESTDIR)$(mandir)/man1 && \
 	target=`echo xzdec | sed '$(transform)'` && \
@@ -72,3 +79,4 @@
 	link=`echo lzmadec | sed '$(transform)'` && \
 	rm -f $$link.1
 endif
+endif
diff --git a/src/xzdec/xzdec.1 b/src/xzdec/xzdec.1
index 7cc9be5..1e5ced9 100644
--- a/src/xzdec/xzdec.1
+++ b/src/xzdec/xzdec.1
@@ -4,17 +4,17 @@
 .\" This file has been put into the public domain.
 .\" You can do whatever you want with this file.
 .\"
-.TH XZDEC 1 "2010-09-27" "Tukaani" "XZ Utils"
+.TH XZDEC 1 "2013-06-30" "Tukaani" "XZ Utils"
 .SH NAME
 xzdec, lzmadec \- Small .xz and .lzma decompressors
 .SH SYNOPSIS
 .B xzdec
-.RI [ option ]...
-.RI [ file ]...
+.RI [ option... ]
+.RI [ file... ]
 .br
 .B lzmadec
-.RI [ option ]...
-.RI [ file ]...
+.RI [ option... ]
+.RI [ file... ]
 .SH DESCRIPTION
 .B xzdec
 is a liblzma-based decompression-only tool for
diff --git a/src/xzdec/xzdec.c b/src/xzdec/xzdec.c
index b7830db..5cb7530 100644
--- a/src/xzdec/xzdec.c
+++ b/src/xzdec/xzdec.c
@@ -62,13 +62,13 @@
 {
 	printf(
 "Usage: %s [OPTION]... [FILE]...\n"
-"Uncompress files in the ." TOOL_FORMAT " format to the standard output.\n"
+"Decompress files in the ." TOOL_FORMAT " format to standard output.\n"
 "\n"
-"  -c, --stdout       (ignored)\n"
-"  -d, --decompress   (ignored)\n"
-"  -k, --keep         (ignored)\n"
+"  -d, --decompress   (ignored, only decompression is supported)\n"
+"  -k, --keep         (ignored, files are never deleted)\n"
+"  -c, --stdout       (ignored, output is always written to standard output)\n"
 "  -q, --quiet        specify *twice* to suppress errors\n"
-"  -Q, --no-warn      (ignored)\n"
+"  -Q, --no-warn      (ignored, the exit status 2 is never used)\n"
 "  -h, --help         display this help and exit\n"
 "  -V, --version      display the version number and exit\n"
 "\n"
diff --git a/tests/Makefile.am b/tests/Makefile.am
index c4e17ed..86084e1 100644
--- a/tests/Makefile.am
+++ b/tests/Makefile.am
@@ -13,7 +13,8 @@
 	test_scripts.sh \
 	bcj_test.c \
 	compress_prepared_bcj_sparc \
-	compress_prepared_bcj_x86
+	compress_prepared_bcj_x86 \
+	xzgrep_expected_output
 
 AM_CPPFLAGS = \
 	-I$(top_srcdir)/src/common \
@@ -52,4 +53,5 @@
 endif
 
 clean-local:
-	-rm -f compress_generated_*
+	-rm -f compress_generated_* \
+		xzgrep_test_output xzgrep_test_1.xz xzgrep_test_2.xz
diff --git a/tests/test_bcj_exact_size.c b/tests/test_bcj_exact_size.c
index cbd9340..4a11a9c 100644
--- a/tests/test_bcj_exact_size.c
+++ b/tests/test_bcj_exact_size.c
@@ -65,6 +65,7 @@
 		if (ret == LZMA_STREAM_END) {
 			expect(strm.total_in == compressed_size);
 			expect(strm.total_out == sizeof(in));
+			lzma_end(&strm);
 			return;
 		}
 
diff --git a/tests/test_block.c b/tests/test_block.c
deleted file mode 100644
index 0352dce..0000000
--- a/tests/test_block.c
+++ /dev/null
@@ -1,52 +0,0 @@
-///////////////////////////////////////////////////////////////////////////////
-//
-/// \file       test_block.c
-/// \brief      Tests Block coders
-//
-//  Author:     Lasse Collin
-//
-//  This file has been put into the public domain.
-//  You can do whatever you want with this file.
-//
-///////////////////////////////////////////////////////////////////////////////
-
-#include "tests.h"
-
-
-static uint8_t text[] = "Hello world!";
-static uint8_t buffer[4096];
-static lzma_options_block block_options;
-static lzma_stream strm = LZMA_STREAM_INIT;
-
-
-static void
-test1(void)
-{
-
-}
-
-
-int
-main()
-{
-	lzma_init();
-
-	block_options = (lzma_options_block){
-		.check_type = LZMA_CHECK_NONE,
-		.has_eopm = true,
-		.has_uncompressed_size_in_footer = false,
-		.has_backward_size = false,
-		.handle_padding = false,
-		.total_size = LZMA_VLI_UNKNOWN,
-		.compressed_size = LZMA_VLI_UNKNOWN,
-		.uncompressed_size = LZMA_VLI_UNKNOWN,
-		.header_size = 5,
-	};
-	block_options.filters[0].id = LZMA_VLI_UNKNOWN;
-	block_options.filters[0].options = NULL;
-
-
-	lzma_end(&strm);
-
-	return 0;
-}
diff --git a/tests/test_files.sh b/tests/test_files.sh
index 2fa8382..0f8a64d 100755
--- a/tests/test_files.sh
+++ b/tests/test_files.sh
@@ -21,7 +21,7 @@
 
 for I in "$srcdir"/files/good-*.xz
 do
-	if test -z "$XZ" || "$XZ" -dc "$I" > /dev/null 2>&1; then
+	if test -z "$XZ" || "$XZ" -dc "$I" > /dev/null; then
 		:
 	else
 		echo "Good file failed: $I"
@@ -29,7 +29,7 @@
 		exit 1
 	fi
 
-	if test -z "$XZDEC" || "$XZDEC" "$I" > /dev/null 2>&1; then
+	if test -z "$XZDEC" || "$XZDEC" "$I" > /dev/null; then
 		:
 	else
 		echo "Good file failed: $I"
diff --git a/tests/test_scripts.sh b/tests/test_scripts.sh
index 293929e..48a9308 100755
--- a/tests/test_scripts.sh
+++ b/tests/test_scripts.sh
@@ -12,16 +12,18 @@
 # If scripts weren't built, this test is skipped.
 XZ=../src/xz/xz
 XZDIFF=../src/scripts/xzdiff
-test -x "$XZ" || XZ=
-test -x "$XZDIFF" || XZDIFF=
-if test -z "$XZ" || test -z "$XZDIFF"; then
+XZGREP=../src/scripts/xzgrep
+
+for i in XZ XZDIFF XZGREP; do
+	eval test -x "\$$i" && continue
 	(exit 77)
 	exit 77
-fi
+done
 
 PATH=`pwd`/../src/xz:$PATH
 export PATH
 
+test -z "$srcdir" && srcdir=.
 preimage=$srcdir/files/good-1-check-crc32.xz
 samepostimage=$srcdir/files/good-1-check-crc64.xz
 otherpostimage=$srcdir/files/good-1-lzma2-1.xz
@@ -50,5 +52,25 @@
 	exit 1
 fi
 
+# The exit status must be 0 when a match was found at least from one file,
+# and 1 when no match was found in any file.
+cp "$srcdir/files/good-1-lzma2-1.xz" xzgrep_test_1.xz
+cp "$srcdir/files/good-2-lzma2.xz" xzgrep_test_2.xz
+for pattern in el Hello NOMATCH; do
+	for opts in "" "-l" "-h" "-H"; do
+		echo "=> xzgrep $opts $pattern <="
+		"$XZGREP" $opts $pattern xzgrep_test_1.xz xzgrep_test_2.xz
+		echo retval $?
+	done
+done > xzgrep_test_output 2>&1
+
+if cmp -s "$srcdir/xzgrep_expected_output" xzgrep_test_output ; then
+	:
+else
+	echo "unexpected output from xzgrep"
+	(exit 1)
+	exit 1
+fi
+
 (exit 0)
 exit 0
diff --git a/tests/xzgrep_expected_output b/tests/xzgrep_expected_output
new file mode 100644
index 0000000..e531d93
--- /dev/null
+++ b/tests/xzgrep_expected_output
@@ -0,0 +1,39 @@
+=> xzgrep  el <=
+xzgrep_test_1.xz:elit, sed do eiusmod tempor incididunt ut 
+xzgrep_test_1.xz:in voluptate velit esse cillum dolore eu 
+xzgrep_test_2.xz:Hello
+retval 0
+=> xzgrep -l el <=
+xzgrep_test_1.xz
+xzgrep_test_2.xz
+retval 0
+=> xzgrep -h el <=
+elit, sed do eiusmod tempor incididunt ut 
+in voluptate velit esse cillum dolore eu 
+Hello
+retval 0
+=> xzgrep -H el <=
+xzgrep_test_1.xz:elit, sed do eiusmod tempor incididunt ut 
+xzgrep_test_1.xz:in voluptate velit esse cillum dolore eu 
+xzgrep_test_2.xz:Hello
+retval 0
+=> xzgrep  Hello <=
+xzgrep_test_2.xz:Hello
+retval 0
+=> xzgrep -l Hello <=
+xzgrep_test_2.xz
+retval 0
+=> xzgrep -h Hello <=
+Hello
+retval 0
+=> xzgrep -H Hello <=
+xzgrep_test_2.xz:Hello
+retval 0
+=> xzgrep  NOMATCH <=
+retval 1
+=> xzgrep -l NOMATCH <=
+retval 1
+=> xzgrep -h NOMATCH <=
+retval 1
+=> xzgrep -H NOMATCH <=
+retval 1
diff --git a/windows/INSTALL-MSVC.txt b/windows/INSTALL-MSVC.txt
new file mode 100644
index 0000000..7dd3168
--- /dev/null
+++ b/windows/INSTALL-MSVC.txt
@@ -0,0 +1,47 @@
+
+Building XZ Utils with Microsoft Visual Studio
+==============================================
+
+Introduction
+------------
+
+    MSVC 2013 update 2 and later have enough C99 support to build
+    liblzma from XZ Utils 5.2.0 and later without modifications.
+    Older MSVC versions would require a large number of changes to
+    the XZ Utils code and thus the old MSVC versions aren't supported.
+
+    As of 2015-06-19, some work has been done to get xz.exe and other
+    command line tools built with MSVC, but it's not complete enough
+    to be included in XZ Utils.
+
+
+Building
+--------
+
+    The following files in this directory are for MSVC:
+
+        config.h              liblzma configuration #defines for MSVC.
+        liblzma.vcxproj       This builds static liblzma.
+        liblzma_dll.vcxproj   This builds liblzma.dll.
+        xz_win.sln            Solution using the above project files.
+
+    The projects have x86 and x86-64 platform configurations, as well
+    as a Debug, Release, and ReleaseMT configuration -- MT is the
+    compiler switch to link to the CRT statically, so it will not
+    have any other DLL dependencies.
+
+    Currently no test programs are built or run under MSVC.
+
+    MSVC gives a bunch of compiler warnings. Some warnings are specific
+    to 32-bit or 64-bit build and some appear for both builds. These
+    are known and shouldn't be a problem. Some of them will probably
+    be fixed in the future.
+
+
+Notes
+-----
+
+    liblzma API headers declare the functions with __declspec(dllimport)
+    by default. To avoid this when using static liblzma from your code,
+    #define LZMA_API_STATIC before #including <lzma.h>.
+
diff --git a/windows/INSTALL-Windows.txt b/windows/INSTALL-MinGW.txt
similarity index 72%
rename from windows/INSTALL-Windows.txt
rename to windows/INSTALL-MinGW.txt
index bb4a4d6..9092171 100644
--- a/windows/INSTALL-Windows.txt
+++ b/windows/INSTALL-MinGW.txt
@@ -6,7 +6,7 @@
 ------------
 
     This document explains shortly where to get and how to install the
-    build tool that are needed to build XZ Utils on Windows. The final
+    build tools that are needed to build XZ Utils on Windows. The final
     binary package will be standalone in sense that it will depend only
     on DLLs that are included in all Windows installations.
 
@@ -25,16 +25,16 @@
     Some of the following is needed:
       - MSYS is always needed to use the GNU Autotools based build system.
       - MinGW builds 32-bit x86 binaries.
-      - MingW-w32 builds 32-bit x86 executables too.
+      - 32-bit MinGW-w64 (I call it MingW-w32 here) builds 32-bit x86
+        executables too.
       - MinGW-w64 builds 64-bit x86-64 binaries.
 
     So you need to pick between MinGW and MinGW-w32 when building
     32-bit version. You don't need both.
 
     You might find 7-Zip <http://7-zip.org/> handy when extracting
-    some files (especially the .tar.lzma files). The ready-made
-    build script will also use 7-Zip to create the distributable
-    .zip and .7z files.
+    some files. The ready-made build script build.bash will also use
+    7-Zip to create the distributable .zip and .7z files.
 
     I used the following directory structure but you can use whatever
     you want. Just note that I will use these in my examples. Each of
@@ -50,14 +50,13 @@
 
     You can download MSYS from MinGW's Sourceforge page:
 
-        http://sourceforge.net/projects/mingw/files/
+        http://sourceforge.net/projects/mingw/files/MSYS/Base/msys-core/
 
-    It's under "MSYS Base System". I recommend using MSYS 1.0.11
-    (MSYS-1.0.11.exe or msysCORE-1.0.11-bin.tar.gz) because that
-    package includes all the required tools. At least some of the
-    later versions include only a subset and thus you would need to
-    download the rest separately. The old version will work fine for
-    building XZ Utils.
+    I recommend using MSYS 1.0.11 (MSYS-1.0.11.exe or
+    msysCORE-1.0.11-bin.tar.gz) because that package includes all the
+    required tools. At least some of the later versions include only
+    a subset and thus you would need to download the rest separately.
+    The old version will work fine for building XZ Utils.
 
     You can use either the .exe or .tar.gz package. I prefer .tar.gz,
     because it can be extracted into any directory and later removed
@@ -66,6 +65,8 @@
 
 Installing MinGW
 
+    NOTE: This section may be outdated. I haven't tried MinGW recently.
+
     You can download the required packages from MinGW's Sourceforge page:
 
         http://sourceforge.net/projects/mingw/files/
@@ -88,21 +89,18 @@
 
 Installing MinGW-w32 or MinGW-w64
 
-    You can find the latest MinGW-w32 and MinGW-w64 builds here:
+    I used the packages from Mingw-builds project. With that it is
+    enough to pick one .7z file for 32-bit and another for 64-bit
+    toolchain. For XZ Utils 5.2.0 I used the packages from these
+    directories:
 
-        http://sourceforge.net/projects/mingw-w64/files/
+        http://sourceforge.net/projects/mingw-w64/files/Toolchains%20targetting%20Win32/Personal%20Builds/mingw-builds/4.9.2/threads-win32/sjlj/
 
-    Locate the appropriate files:
+        http://sourceforge.net/projects/mingw-w64/files/Toolchains%20targetting%20Win64/Personal%20Builds/mingw-builds/4.9.2/threads-win32/sjlj/
 
-        Toolchains targeting Win32 -> mingw-w32-*-mingw*.zip
-        Toolchains targeting Win64 -> mingw-w64-*-mingw*.zip
-
-    I don't know what is the most recommended one. I used sezero's
-    versions from "Personal Builds", since they seemed to have
-    a stable GCC (judging from the GCC version number only).
-
-    If you will install both MinGW-w32 and MinGW-w64, remember to
-    extract them into different directories.
+    If you install both MinGW-w32 and MinGW-w64, remember to extract
+    them into different directories. build.bash looks at
+    C:\devel\tools\mingw-w32 and C:\devel\tools\mingw-w64 by default.
 
 
 Building XZ Utils
diff --git a/windows/README-Windows.txt b/windows/README-Windows.txt
index 72c5a98..f9a0024 100644
--- a/windows/README-Windows.txt
+++ b/windows/README-Windows.txt
@@ -21,15 +21,19 @@
 ----------------
 
     All executables and libraries in this package require msvcrt.dll.
-    It's included in all recent Windows versions. On Windows 95 it
-    might be missing, but once you get it somewhere, XZ Utils should
-    run even on Windows 95.
+    It's included in all recent Windows versions. (On Windows 95 it
+    might be missing, but once you get it somewhere, the i686 binaries
+    should run even on Windows 95 if the processor is new enough.)
 
-    There are two different versions of the executable and library files.
-    There is one directory for each type of binaries:
+    There is a SSE2 optimization in the compression code but this
+    version of XZ Utils doesn't include run-time processor detection.
+    This is why there is a separate i686-SSE2 version.
 
-        bin_i486        32-bit x86 (i486 and up), Windows 95 and later
-        bin_x86-64      64-bit x86-64, Windows XP and later
+    There is one directory for each type of executable and library files:
+
+        bin_i686        32-bit x86 (i686 and newer), Windows 95 and later
+        bin_i686-sse2   32-bit x86 (i686 with SSE2), Windows 98 and later
+        bin_x86-64      64-bit x86-64, Windows Vista and later
 
     Each of the above directories have the following files:
 
@@ -90,15 +94,13 @@
 
         lib /def:liblzma.def /out:liblzma.lib /machine:x64
 
-    Linking against static liblzma might work too, but usually you
-    should use liblzma.dll if possible. (Or, if having a decompressor
-    is enough, consider using XZ Embedded or LZMA SDK which can be
-    compiled with MSVC.)
+    If you need to link statically against liblzma, you should build
+    liblzma with MSVC 2013 update 2 or later. Alternatively, if having
+    a decompressor is enough, consider using XZ Embedded or LZMA SDK.
 
-    To try linking against static liblzma, rename liblzma.a to e.g.
-    liblzma_static.lib and tell MSVC to link against it. You also need
-    to tell lzma.h to not use __declspec(dllimport) by defining the
-    macro LZMA_API_STATIC. You can do it either in the C/C++ code
+    When you plan to link against static liblzma, you need to tell
+    lzma.h to not use __declspec(dllimport) by defining the macro
+    LZMA_API_STATIC. You can do it either in the C/C++ code
 
         #define LZMA_API_STATIC
         #include <lzma.h>
diff --git a/windows/build.bash b/windows/build.bash
index c5cf2b3..4a6a284 100644
--- a/windows/build.bash
+++ b/windows/build.bash
@@ -69,13 +69,14 @@
 	# Clean up if it was already configured.
 	[ -f Makefile ] && make distclean
 
-	# Build the size-optimized binaries. Note that I don't want to
-	# provide size-optimized liblzma (shared nor static), because
-	# that isn't thread-safe now, and depending on bunch of things,
-	# maybe it will never be on Windows (pthreads-win32 helps but
-	# static liblzma might bit a bit tricky with it).
+	# Build the size-optimized binaries. Providing size-optimized liblzma
+	# could be considered but I don't know if it should only use -Os or
+	# should it also use --enable-small and if it should support
+	# threading. So I don't include a size-optimized liblzma for now.
 	./configure \
 		--prefix= \
+		--enable-silent-rules \
+		--disable-dependency-tracking \
 		--disable-nls \
 		--disable-scripts \
 		--disable-threads \
@@ -90,16 +91,14 @@
 
 	make distclean
 
-	# Build the normal speed-optimized binaries. Note that while
-	# --disable-threads has been documented to make some things
-	# thread-unsafe, it's not actually true with this combination
-	# of configure flags in XZ Utils 5.0.x. Things can (and probably
-	# will) change after 5.0.x, and this script will be updated too.
+	# Build the normal speed-optimized binaries. The type of threading
+	# (win95 vs. vista) will be autodetect from the target architecture.
 	./configure \
 		--prefix= \
+		--enable-silent-rules \
+		--disable-dependency-tracking \
 		--disable-nls \
 		--disable-scripts \
-		--disable-threads \
 		--build="$BUILD" \
 		CFLAGS="$CFLAGS -O2"
 	make -C src/liblzma
@@ -131,18 +130,19 @@
 	done
 }
 
-# FIXME: Make sure that we don't get i686 or i586 code from the runtime.
-# Actually i586 would be fine, but i686 probably not if the idea is to
-# support even Win95.
-#
-# FIXME: Using i486 in the configure triplet may be wrong.
 if [ -d "$MINGW_W32_DIR" ]; then
 	# 32-bit x86, Win95 or later, using MinGW-w32
 	PATH=$MINGW_W32_DIR/bin:$MINGW_W32_DIR/i686-w64-mingw32/bin:$PATH \
 			buildit \
-			pkg/bin_i486 \
-			i486-w64-mingw32 \
-			'-march=i486 -mtune=generic'
+			pkg/bin_i686 \
+			i686-w64-mingw32 \
+			'-march=i686 -mtune=generic'
+	# 32-bit x86 with SSE2, Win98 or later, using MinGW-w32
+	PATH=$MINGW_W32_DIR/bin:$MINGW_W32_DIR/i686-w64-mingw32/bin:$PATH \
+			buildit \
+			pkg/bin_i686-sse2 \
+			i686-w64-mingw32 \
+			'-march=i686 -msse2 -mfpmath=sse -mtune=generic'
 elif [ -d "$MINGW_DIR" ]; then
 	# 32-bit x86, Win95 or later, using MinGW
 	PATH=$MINGW_DIR/bin:$PATH \
@@ -153,7 +153,7 @@
 fi
 
 if [ -d "$MINGW_W64_DIR" ]; then
-	# 64-bit x86, WinXP or later, using MinGW-w64
+	# x86-64, Windows Vista or later, using MinGW-w64
 	PATH=$MINGW_W64_DIR/bin:$MINGW_W64_DIR/x86_64-w64-mingw32/bin:$PATH \
 			buildit \
 			pkg/bin_x86-64 \
diff --git a/windows/config.h b/windows/config.h
new file mode 100644
index 0000000..9b1b375
--- /dev/null
+++ b/windows/config.h
@@ -0,0 +1,142 @@
+/* config.h for compiling liblzma (*not* the whole XZ Utils) with MSVC 2013 */
+
+/* Prefix for symbols exported by tuklib_*.c files */
+#define TUKLIB_SYMBOL_PREFIX lzma_
+
+/* How many MiB of RAM to assume if the real amount cannot be determined. */
+#define ASSUME_RAM 128
+
+/* Define to 1 if crc32 integrity check is enabled. */
+#define HAVE_CHECK_CRC32 1
+
+/* Define to 1 if crc64 integrity check is enabled. */
+#define HAVE_CHECK_CRC64 1
+
+/* Define to 1 if sha256 integrity check is enabled. */
+#define HAVE_CHECK_SHA256 1
+
+/* Define to 1 if arm decoder is enabled. */
+#define HAVE_DECODER_ARM 1
+
+/* Define to 1 if armthumb decoder is enabled. */
+#define HAVE_DECODER_ARMTHUMB 1
+
+/* Define to 1 if delta decoder is enabled. */
+#define HAVE_DECODER_DELTA 1
+
+/* Define to 1 if ia64 decoder is enabled. */
+#define HAVE_DECODER_IA64 1
+
+/* Define to 1 if lzma1 decoder is enabled. */
+#define HAVE_DECODER_LZMA1 1
+
+/* Define to 1 if lzma2 decoder is enabled. */
+#define HAVE_DECODER_LZMA2 1
+
+/* Define to 1 if powerpc decoder is enabled. */
+#define HAVE_DECODER_POWERPC 1
+
+/* Define to 1 if sparc decoder is enabled. */
+#define HAVE_DECODER_SPARC 1
+
+/* Define to 1 if x86 decoder is enabled. */
+#define HAVE_DECODER_X86 1
+
+/* Define to 1 if arm encoder is enabled. */
+#define HAVE_ENCODER_ARM 1
+
+/* Define to 1 if armthumb encoder is enabled. */
+#define HAVE_ENCODER_ARMTHUMB 1
+
+/* Define to 1 if delta encoder is enabled. */
+#define HAVE_ENCODER_DELTA 1
+
+/* Define to 1 if ia64 encoder is enabled. */
+#define HAVE_ENCODER_IA64 1
+
+/* Define to 1 if lzma1 encoder is enabled. */
+#define HAVE_ENCODER_LZMA1 1
+
+/* Define to 1 if lzma2 encoder is enabled. */
+#define HAVE_ENCODER_LZMA2 1
+
+/* Define to 1 if powerpc encoder is enabled. */
+#define HAVE_ENCODER_POWERPC 1
+
+/* Define to 1 if sparc encoder is enabled. */
+#define HAVE_ENCODER_SPARC 1
+
+/* Define to 1 if x86 encoder is enabled. */
+#define HAVE_ENCODER_X86 1
+
+/* Define to 1 if you have the <inttypes.h> header file. */
+#define HAVE_INTTYPES_H 1
+
+/* Define to 1 if you have the <limits.h> header file. */
+#define HAVE_LIMITS_H 1
+
+/* Define to 1 to enable bt2 match finder. */
+#define HAVE_MF_BT2 1
+
+/* Define to 1 to enable bt3 match finder. */
+#define HAVE_MF_BT3 1
+
+/* Define to 1 to enable bt4 match finder. */
+#define HAVE_MF_BT4 1
+
+/* Define to 1 to enable hc3 match finder. */
+#define HAVE_MF_HC3 1
+
+/* Define to 1 to enable hc4 match finder. */
+#define HAVE_MF_HC4 1
+
+/* Define to 1 if stdbool.h conforms to C99. */
+#define HAVE_STDBOOL_H 1
+
+/* Define to 1 if you have the <stdint.h> header file. */
+#define HAVE_STDINT_H 1
+
+/* Define to 1 if you have the <stdlib.h> header file. */
+#define HAVE_STDLIB_H 1
+
+/* Define to 1 if you have the <string.h> header file. */
+#define HAVE_STRING_H 1
+
+/* Define to 1 or 0, depending whether the compiler supports simple visibility
+   declarations. */
+#define HAVE_VISIBILITY 0
+
+/* Define to 1 if the system has the type `_Bool'. */
+#define HAVE__BOOL 1
+
+#ifdef _M_IX86
+/* Define to 1 when using Windows 95 (and thus XP) compatible threads. This
+   avoids use of features that were added in Windows Vista.
+   This is used for 32-bit x86 builds for compatibility reasons since it
+   makes no measurable difference in performance compared to Vista threads. */
+#define MYTHREAD_WIN95 1
+#else
+/* Define to 1 when using Windows Vista compatible threads. This uses features
+   that are not available on Windows XP. */
+#define MYTHREAD_VISTA 1
+#endif
+
+/* Define to 1 to disable debugging code. */
+#define NDEBUG 1
+
+/* Define to the full name of this package. */
+#define PACKAGE_NAME "XZ Utils"
+
+/* Define to the home page for this package. */
+#define PACKAGE_URL "http://tukaani.org/xz/"
+
+/* The size of `size_t', as computed by sizeof. */
+#ifdef _WIN64
+#define SIZEOF_SIZE_T 8
+#else
+#define SIZEOF_SIZE_T 4
+#endif
+
+/* Define to 1 if the system supports fast unaligned access to 16-bit and
+   32-bit integers. */
+#define TUKLIB_FAST_UNALIGNED_ACCESS 1
diff --git a/windows/liblzma.vcxproj b/windows/liblzma.vcxproj
new file mode 100644
index 0000000..2feafef
--- /dev/null
+++ b/windows/liblzma.vcxproj
@@ -0,0 +1,354 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project DefaultTargets="Build" ToolsVersion="12.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+  <ItemGroup Label="ProjectConfigurations">
+    <ProjectConfiguration Include="Debug|Win32">
+      <Configuration>Debug</Configuration>
+      <Platform>Win32</Platform>
+    </ProjectConfiguration>
+    <ProjectConfiguration Include="Debug|x64">
+      <Configuration>Debug</Configuration>
+      <Platform>x64</Platform>
+    </ProjectConfiguration>
+    <ProjectConfiguration Include="ReleaseMT|Win32">
+      <Configuration>ReleaseMT</Configuration>
+      <Platform>Win32</Platform>
+    </ProjectConfiguration>
+    <ProjectConfiguration Include="ReleaseMT|x64">
+      <Configuration>ReleaseMT</Configuration>
+      <Platform>x64</Platform>
+    </ProjectConfiguration>
+    <ProjectConfiguration Include="Release|Win32">
+      <Configuration>Release</Configuration>
+      <Platform>Win32</Platform>
+    </ProjectConfiguration>
+    <ProjectConfiguration Include="Release|x64">
+      <Configuration>Release</Configuration>
+      <Platform>x64</Platform>
+    </ProjectConfiguration>
+  </ItemGroup>
+  <PropertyGroup Label="Globals">
+    <ProjectGuid>{12728250-16EC-4DC6-94D7-E21DD88947F8}</ProjectGuid>
+    <Keyword>Win32Proj</Keyword>
+  </PropertyGroup>
+  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
+    <ConfigurationType>StaticLibrary</ConfigurationType>
+    <UseDebugLibraries>true</UseDebugLibraries>
+    <PlatformToolset>v120</PlatformToolset>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
+    <ConfigurationType>StaticLibrary</ConfigurationType>
+    <UseDebugLibraries>true</UseDebugLibraries>
+    <PlatformToolset>v120</PlatformToolset>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
+    <ConfigurationType>StaticLibrary</ConfigurationType>
+    <UseDebugLibraries>false</UseDebugLibraries>
+    <PlatformToolset>v120</PlatformToolset>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
+    <ConfigurationType>StaticLibrary</ConfigurationType>
+    <UseDebugLibraries>false</UseDebugLibraries>
+    <PlatformToolset>v120</PlatformToolset>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseMT|Win32'" Label="Configuration">
+    <ConfigurationType>StaticLibrary</ConfigurationType>
+    <UseDebugLibraries>false</UseDebugLibraries>
+    <PlatformToolset>v120</PlatformToolset>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseMT|x64'" Label="Configuration">
+    <ConfigurationType>StaticLibrary</ConfigurationType>
+    <UseDebugLibraries>false</UseDebugLibraries>
+    <PlatformToolset>v120</PlatformToolset>
+  </PropertyGroup>
+  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
+  <ImportGroup Label="ExtensionSettings">
+  </ImportGroup>
+  <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+  </ImportGroup>
+  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="PropertySheets">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+  </ImportGroup>
+  <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+  </ImportGroup>
+  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="PropertySheets">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+  </ImportGroup>
+  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseMT|Win32'" Label="PropertySheets">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+  </ImportGroup>
+  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseMT|x64'" Label="PropertySheets">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+  </ImportGroup>
+  <PropertyGroup Label="UserMacros" />
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+    <LinkIncremental>true</LinkIncremental>
+    <OutDir>$(SolutionDir)$(Configuration)\$(Platform)\$(ProjectName)\</OutDir>
+    <IntDir>$(Configuration)\$(Platform)\$(ProjectName)\</IntDir>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
+    <LinkIncremental>true</LinkIncremental>
+    <OutDir>$(SolutionDir)$(Configuration)\$(Platform)\$(ProjectName)\</OutDir>
+    <IntDir>$(Configuration)\$(Platform)\$(ProjectName)\</IntDir>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+    <LinkIncremental>true</LinkIncremental>
+    <OutDir>$(SolutionDir)$(Configuration)\$(Platform)\$(ProjectName)\</OutDir>
+    <IntDir>$(Configuration)\$(Platform)\$(ProjectName)\</IntDir>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
+    <LinkIncremental>true</LinkIncremental>
+    <OutDir>$(SolutionDir)$(Configuration)\$(Platform)\$(ProjectName)\</OutDir>
+    <IntDir>$(Configuration)\$(Platform)\$(ProjectName)\</IntDir>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseMT|Win32'">
+    <LinkIncremental>true</LinkIncremental>
+    <OutDir>$(SolutionDir)$(Configuration)\$(Platform)\$(ProjectName)\</OutDir>
+    <IntDir>$(Configuration)\$(Platform)\$(ProjectName)\</IntDir>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseMT|x64'">
+    <LinkIncremental>true</LinkIncremental>
+    <OutDir>$(SolutionDir)$(Configuration)\$(Platform)\$(ProjectName)\</OutDir>
+    <IntDir>$(Configuration)\$(Platform)\$(ProjectName)\</IntDir>
+  </PropertyGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+    <ClCompile>
+      <PreprocessorDefinitions>WIN32;HAVE_CONFIG_H;_DEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
+      <WarningLevel>Level3</WarningLevel>
+      <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
+      <Optimization>Disabled</Optimization>
+      <AdditionalIncludeDirectories>./;../src/liblzma/common;../src/common;../src/liblzma/api;../src/liblzma/check;../src/liblzma/delta;../src/liblzma/lz;../src/liblzma/lzma;../src/liblzma/rangecoder;../src/liblzma/simple</AdditionalIncludeDirectories>
+    </ClCompile>
+    <Link>
+      <TargetMachine>MachineX86</TargetMachine>
+      <GenerateDebugInformation>true</GenerateDebugInformation>
+      <SubSystem>Windows</SubSystem>
+    </Link>
+  </ItemDefinitionGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
+    <ClCompile>
+      <PreprocessorDefinitions>WIN32;HAVE_CONFIG_H;_DEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
+      <WarningLevel>Level3</WarningLevel>
+      <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
+      <Optimization>Disabled</Optimization>
+      <AdditionalIncludeDirectories>./;../src/liblzma/common;../src/common;../src/liblzma/api;../src/liblzma/check;../src/liblzma/delta;../src/liblzma/lz;../src/liblzma/lzma;../src/liblzma/rangecoder;../src/liblzma/simple</AdditionalIncludeDirectories>
+    </ClCompile>
+    <Link>
+      <GenerateDebugInformation>true</GenerateDebugInformation>
+      <SubSystem>Windows</SubSystem>
+    </Link>
+  </ItemDefinitionGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+    <ClCompile>
+      <PreprocessorDefinitions>WIN32;HAVE_CONFIG_H;NDEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
+      <WarningLevel>Level3</WarningLevel>
+      <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
+      <AdditionalIncludeDirectories>./;../src/liblzma/common;../src/common;../src/liblzma/api;../src/liblzma/check;../src/liblzma/delta;../src/liblzma/lz;../src/liblzma/lzma;../src/liblzma/rangecoder;../src/liblzma/simple</AdditionalIncludeDirectories>
+    </ClCompile>
+    <Link>
+      <TargetMachine>MachineX86</TargetMachine>
+      <GenerateDebugInformation>true</GenerateDebugInformation>
+      <SubSystem>Windows</SubSystem>
+      <EnableCOMDATFolding>true</EnableCOMDATFolding>
+      <OptimizeReferences>true</OptimizeReferences>
+    </Link>
+  </ItemDefinitionGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
+    <ClCompile>
+      <PreprocessorDefinitions>WIN32;HAVE_CONFIG_H;NDEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
+      <WarningLevel>Level3</WarningLevel>
+      <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
+      <AdditionalIncludeDirectories>./;../src/liblzma/common;../src/common;../src/liblzma/api;../src/liblzma/check;../src/liblzma/delta;../src/liblzma/lz;../src/liblzma/lzma;../src/liblzma/rangecoder;../src/liblzma/simple</AdditionalIncludeDirectories>
+    </ClCompile>
+    <Link>
+      <GenerateDebugInformation>true</GenerateDebugInformation>
+      <SubSystem>Windows</SubSystem>
+      <EnableCOMDATFolding>true</EnableCOMDATFolding>
+      <OptimizeReferences>true</OptimizeReferences>
+    </Link>
+  </ItemDefinitionGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseMT|Win32'">
+    <ClCompile>
+      <PreprocessorDefinitions>WIN32;HAVE_CONFIG_H;NDEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <RuntimeLibrary>MultiThreaded</RuntimeLibrary>
+      <WarningLevel>Level3</WarningLevel>
+      <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
+      <AdditionalIncludeDirectories>./;../src/liblzma/common;../src/common;../src/liblzma/api;../src/liblzma/check;../src/liblzma/delta;../src/liblzma/lz;../src/liblzma/lzma;../src/liblzma/rangecoder;../src/liblzma/simple</AdditionalIncludeDirectories>
+    </ClCompile>
+    <Link>
+      <TargetMachine>MachineX86</TargetMachine>
+      <GenerateDebugInformation>true</GenerateDebugInformation>
+      <SubSystem>Windows</SubSystem>
+      <EnableCOMDATFolding>true</EnableCOMDATFolding>
+      <OptimizeReferences>true</OptimizeReferences>
+    </Link>
+  </ItemDefinitionGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseMT|x64'">
+    <ClCompile>
+      <PreprocessorDefinitions>WIN32;HAVE_CONFIG_H;NDEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <RuntimeLibrary>MultiThreaded</RuntimeLibrary>
+      <WarningLevel>Level3</WarningLevel>
+      <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
+      <AdditionalIncludeDirectories>./;../src/liblzma/common;../src/common;../src/liblzma/api;../src/liblzma/check;../src/liblzma/delta;../src/liblzma/lz;../src/liblzma/lzma;../src/liblzma/rangecoder;../src/liblzma/simple</AdditionalIncludeDirectories>
+    </ClCompile>
+    <Link>
+      <GenerateDebugInformation>true</GenerateDebugInformation>
+      <SubSystem>Windows</SubSystem>
+      <EnableCOMDATFolding>true</EnableCOMDATFolding>
+      <OptimizeReferences>true</OptimizeReferences>
+    </Link>
+  </ItemDefinitionGroup>
+  <ItemGroup>
+    <ClCompile Include="..\src\common\tuklib_cpucores.c" />
+    <ClCompile Include="..\src\common\tuklib_physmem.c" />
+    <ClCompile Include="..\src\liblzma\check\check.c" />
+    <ClCompile Include="..\src\liblzma\check\crc32_fast.c" />
+    <ClCompile Include="..\src\liblzma\check\crc32_table.c" />
+    <ClCompile Include="..\src\liblzma\check\crc64_fast.c" />
+    <ClCompile Include="..\src\liblzma\check\crc64_table.c" />
+    <ClCompile Include="..\src\liblzma\check\sha256.c" />
+    <ClCompile Include="..\src\liblzma\common\alone_decoder.c" />
+    <ClCompile Include="..\src\liblzma\common\alone_encoder.c" />
+    <ClCompile Include="..\src\liblzma\common\auto_decoder.c" />
+    <ClCompile Include="..\src\liblzma\common\block_buffer_decoder.c" />
+    <ClCompile Include="..\src\liblzma\common\block_buffer_encoder.c" />
+    <ClCompile Include="..\src\liblzma\common\block_decoder.c" />
+    <ClCompile Include="..\src\liblzma\common\block_encoder.c" />
+    <ClCompile Include="..\src\liblzma\common\block_header_decoder.c" />
+    <ClCompile Include="..\src\liblzma\common\block_header_encoder.c" />
+    <ClCompile Include="..\src\liblzma\common\block_util.c" />
+    <ClCompile Include="..\src\liblzma\common\common.c" />
+    <ClCompile Include="..\src\liblzma\common\easy_buffer_encoder.c" />
+    <ClCompile Include="..\src\liblzma\common\easy_decoder_memusage.c" />
+    <ClCompile Include="..\src\liblzma\common\easy_encoder.c" />
+    <ClCompile Include="..\src\liblzma\common\easy_encoder_memusage.c" />
+    <ClCompile Include="..\src\liblzma\common\easy_preset.c" />
+    <ClCompile Include="..\src\liblzma\common\filter_buffer_decoder.c" />
+    <ClCompile Include="..\src\liblzma\common\filter_buffer_encoder.c" />
+    <ClCompile Include="..\src\liblzma\common\filter_common.c" />
+    <ClCompile Include="..\src\liblzma\common\filter_decoder.c" />
+    <ClCompile Include="..\src\liblzma\common\filter_encoder.c" />
+    <ClCompile Include="..\src\liblzma\common\filter_flags_decoder.c" />
+    <ClCompile Include="..\src\liblzma\common\filter_flags_encoder.c" />
+    <ClCompile Include="..\src\liblzma\common\hardware_cputhreads.c" />
+    <ClCompile Include="..\src\liblzma\common\hardware_physmem.c" />
+    <ClCompile Include="..\src\liblzma\common\index.c" />
+    <ClCompile Include="..\src\liblzma\common\index_decoder.c" />
+    <ClCompile Include="..\src\liblzma\common\index_encoder.c" />
+    <ClCompile Include="..\src\liblzma\common\index_hash.c" />
+    <ClCompile Include="..\src\liblzma\common\outqueue.c" />
+    <ClCompile Include="..\src\liblzma\common\stream_buffer_decoder.c" />
+    <ClCompile Include="..\src\liblzma\common\stream_buffer_encoder.c" />
+    <ClCompile Include="..\src\liblzma\common\stream_decoder.c" />
+    <ClCompile Include="..\src\liblzma\common\stream_encoder.c" />
+    <ClCompile Include="..\src\liblzma\common\stream_encoder_mt.c" />
+    <ClCompile Include="..\src\liblzma\common\stream_flags_common.c" />
+    <ClCompile Include="..\src\liblzma\common\stream_flags_decoder.c" />
+    <ClCompile Include="..\src\liblzma\common\stream_flags_encoder.c" />
+    <ClCompile Include="..\src\liblzma\common\vli_decoder.c" />
+    <ClCompile Include="..\src\liblzma\common\vli_encoder.c" />
+    <ClCompile Include="..\src\liblzma\common\vli_size.c" />
+    <ClCompile Include="..\src\liblzma\delta\delta_common.c" />
+    <ClCompile Include="..\src\liblzma\delta\delta_decoder.c" />
+    <ClCompile Include="..\src\liblzma\delta\delta_encoder.c" />
+    <ClCompile Include="..\src\liblzma\lzma\fastpos_table.c" />
+    <ClCompile Include="..\src\liblzma\lzma\lzma2_decoder.c" />
+    <ClCompile Include="..\src\liblzma\lzma\lzma2_encoder.c" />
+    <ClCompile Include="..\src\liblzma\lzma\lzma_decoder.c" />
+    <ClCompile Include="..\src\liblzma\lzma\lzma_encoder.c" />
+    <ClCompile Include="..\src\liblzma\lzma\lzma_encoder_optimum_fast.c" />
+    <ClCompile Include="..\src\liblzma\lzma\lzma_encoder_optimum_normal.c" />
+    <ClCompile Include="..\src\liblzma\lzma\lzma_encoder_presets.c" />
+    <ClCompile Include="..\src\liblzma\lz\lz_decoder.c" />
+    <ClCompile Include="..\src\liblzma\lz\lz_encoder.c" />
+    <ClCompile Include="..\src\liblzma\lz\lz_encoder_mf.c" />
+    <ClCompile Include="..\src\liblzma\rangecoder\price_table.c" />
+    <ClCompile Include="..\src\liblzma\simple\arm.c" />
+    <ClCompile Include="..\src\liblzma\simple\armthumb.c" />
+    <ClCompile Include="..\src\liblzma\simple\ia64.c" />
+    <ClCompile Include="..\src\liblzma\simple\powerpc.c" />
+    <ClCompile Include="..\src\liblzma\simple\simple_coder.c" />
+    <ClCompile Include="..\src\liblzma\simple\simple_decoder.c" />
+    <ClCompile Include="..\src\liblzma\simple\simple_encoder.c" />
+    <ClCompile Include="..\src\liblzma\simple\sparc.c" />
+    <ClCompile Include="..\src\liblzma\simple\x86.c" />
+  </ItemGroup>
+  <ItemGroup>
+    <ClInclude Include="..\src\common\mythread.h" />
+    <ClInclude Include="..\src\common\sysdefs.h" />
+    <ClInclude Include="..\src\common\tuklib_common.h" />
+    <ClInclude Include="..\src\common\tuklib_config.h" />
+    <ClInclude Include="..\src\common\tuklib_cpucores.h" />
+    <ClInclude Include="..\src\common\tuklib_integer.h" />
+    <ClInclude Include="..\src\common\tuklib_physmem.h" />
+    <ClInclude Include="..\src\liblzma\api\lzma.h" />
+    <ClInclude Include="..\src\liblzma\api\lzma\base.h" />
+    <ClInclude Include="..\src\liblzma\api\lzma\bcj.h" />
+    <ClInclude Include="..\src\liblzma\api\lzma\block.h" />
+    <ClInclude Include="..\src\liblzma\api\lzma\check.h" />
+    <ClInclude Include="..\src\liblzma\api\lzma\container.h" />
+    <ClInclude Include="..\src\liblzma\api\lzma\delta.h" />
+    <ClInclude Include="..\src\liblzma\api\lzma\filter.h" />
+    <ClInclude Include="..\src\liblzma\api\lzma\hardware.h" />
+    <ClInclude Include="..\src\liblzma\api\lzma\index.h" />
+    <ClInclude Include="..\src\liblzma\api\lzma\index_hash.h" />
+    <ClInclude Include="..\src\liblzma\api\lzma\lzma12.h" />
+    <ClInclude Include="..\src\liblzma\api\lzma\stream_flags.h" />
+    <ClInclude Include="..\src\liblzma\api\lzma\version.h" />
+    <ClInclude Include="..\src\liblzma\api\lzma\vli.h" />
+    <ClInclude Include="..\src\liblzma\check\check.h" />
+    <ClInclude Include="..\src\liblzma\check\crc32_table_be.h" />
+    <ClInclude Include="..\src\liblzma\check\crc32_table_le.h" />
+    <ClInclude Include="..\src\liblzma\check\crc64_table_be.h" />
+    <ClInclude Include="..\src\liblzma\check\crc64_table_le.h" />
+    <ClInclude Include="..\src\liblzma\check\crc_macros.h" />
+    <ClInclude Include="..\src\liblzma\common\alone_decoder.h" />
+    <ClInclude Include="..\src\liblzma\common\block_buffer_encoder.h" />
+    <ClInclude Include="..\src\liblzma\common\block_decoder.h" />
+    <ClInclude Include="..\src\liblzma\common\block_encoder.h" />
+    <ClInclude Include="..\src\liblzma\common\common.h" />
+    <ClInclude Include="..\src\liblzma\common\easy_preset.h" />
+    <ClInclude Include="..\src\liblzma\common\filter_common.h" />
+    <ClInclude Include="..\src\liblzma\common\filter_decoder.h" />
+    <ClInclude Include="..\src\liblzma\common\filter_encoder.h" />
+    <ClInclude Include="..\src\liblzma\common\index.h" />
+    <ClInclude Include="..\src\liblzma\common\index_encoder.h" />
+    <ClInclude Include="..\src\liblzma\common\memcmplen.h" />
+    <ClInclude Include="..\src\liblzma\common\outqueue.h" />
+    <ClInclude Include="..\src\liblzma\common\stream_decoder.h" />
+    <ClInclude Include="..\src\liblzma\common\stream_flags_common.h" />
+    <ClInclude Include="..\src\liblzma\delta\delta_common.h" />
+    <ClInclude Include="..\src\liblzma\delta\delta_decoder.h" />
+    <ClInclude Include="..\src\liblzma\delta\delta_encoder.h" />
+    <ClInclude Include="..\src\liblzma\delta\delta_private.h" />
+    <ClInclude Include="..\src\liblzma\lzma\fastpos.h" />
+    <ClInclude Include="..\src\liblzma\lzma\lzma2_decoder.h" />
+    <ClInclude Include="..\src\liblzma\lzma\lzma2_encoder.h" />
+    <ClInclude Include="..\src\liblzma\lzma\lzma_common.h" />
+    <ClInclude Include="..\src\liblzma\lzma\lzma_decoder.h" />
+    <ClInclude Include="..\src\liblzma\lzma\lzma_encoder.h" />
+    <ClInclude Include="..\src\liblzma\lzma\lzma_encoder_private.h" />
+    <ClInclude Include="..\src\liblzma\lz\lz_decoder.h" />
+    <ClInclude Include="..\src\liblzma\lz\lz_encoder.h" />
+    <ClInclude Include="..\src\liblzma\lz\lz_encoder_hash.h" />
+    <ClInclude Include="..\src\liblzma\lz\lz_encoder_hash_table.h" />
+    <ClInclude Include="..\src\liblzma\rangecoder\price.h" />
+    <ClInclude Include="..\src\liblzma\rangecoder\range_common.h" />
+    <ClInclude Include="..\src\liblzma\rangecoder\range_decoder.h" />
+    <ClInclude Include="..\src\liblzma\rangecoder\range_encoder.h" />
+    <ClInclude Include="..\src\liblzma\simple\simple_coder.h" />
+    <ClInclude Include="..\src\liblzma\simple\simple_decoder.h" />
+    <ClInclude Include="..\src\liblzma\simple\simple_encoder.h" />
+    <ClInclude Include="..\src\liblzma\simple\simple_private.h" />
+    <ClInclude Include="config.h" />
+  </ItemGroup>
+  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
+  <ImportGroup Label="ExtensionTargets">
+  </ImportGroup>
+</Project>
\ No newline at end of file
diff --git a/windows/liblzma_dll.vcxproj b/windows/liblzma_dll.vcxproj
new file mode 100644
index 0000000..d09f5e4
--- /dev/null
+++ b/windows/liblzma_dll.vcxproj
@@ -0,0 +1,383 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project DefaultTargets="Build" ToolsVersion="12.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+  <ItemGroup Label="ProjectConfigurations">
+    <ProjectConfiguration Include="Debug|Win32">
+      <Configuration>Debug</Configuration>
+      <Platform>Win32</Platform>
+    </ProjectConfiguration>
+    <ProjectConfiguration Include="Debug|x64">
+      <Configuration>Debug</Configuration>
+      <Platform>x64</Platform>
+    </ProjectConfiguration>
+    <ProjectConfiguration Include="ReleaseMT|Win32">
+      <Configuration>ReleaseMT</Configuration>
+      <Platform>Win32</Platform>
+    </ProjectConfiguration>
+    <ProjectConfiguration Include="ReleaseMT|x64">
+      <Configuration>ReleaseMT</Configuration>
+      <Platform>x64</Platform>
+    </ProjectConfiguration>
+    <ProjectConfiguration Include="Release|Win32">
+      <Configuration>Release</Configuration>
+      <Platform>Win32</Platform>
+    </ProjectConfiguration>
+    <ProjectConfiguration Include="Release|x64">
+      <Configuration>Release</Configuration>
+      <Platform>x64</Platform>
+    </ProjectConfiguration>
+  </ItemGroup>
+  <PropertyGroup Label="Globals">
+    <ProjectGuid>{E0F247DB-EF12-4755-8DF9-F74BCD1348F7}</ProjectGuid>
+    <Keyword>Win32Proj</Keyword>
+  </PropertyGroup>
+  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
+    <ConfigurationType>DynamicLibrary</ConfigurationType>
+    <UseDebugLibraries>true</UseDebugLibraries>
+    <PlatformToolset>v120</PlatformToolset>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
+    <ConfigurationType>DynamicLibrary</ConfigurationType>
+    <UseDebugLibraries>true</UseDebugLibraries>
+    <PlatformToolset>v120</PlatformToolset>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
+    <ConfigurationType>DynamicLibrary</ConfigurationType>
+    <UseDebugLibraries>false</UseDebugLibraries>
+    <PlatformToolset>v120</PlatformToolset>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
+    <ConfigurationType>DynamicLibrary</ConfigurationType>
+    <UseDebugLibraries>false</UseDebugLibraries>
+    <PlatformToolset>v120</PlatformToolset>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseMT|Win32'" Label="Configuration">
+    <ConfigurationType>DynamicLibrary</ConfigurationType>
+    <UseDebugLibraries>false</UseDebugLibraries>
+    <PlatformToolset>v120</PlatformToolset>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseMT|x64'" Label="Configuration">
+    <ConfigurationType>DynamicLibrary</ConfigurationType>
+    <UseDebugLibraries>false</UseDebugLibraries>
+    <PlatformToolset>v120</PlatformToolset>
+  </PropertyGroup>
+  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
+  <ImportGroup Label="ExtensionSettings">
+  </ImportGroup>
+  <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+  </ImportGroup>
+  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="PropertySheets">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+  </ImportGroup>
+  <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+  </ImportGroup>
+  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="PropertySheets">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+  </ImportGroup>
+  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseMT|Win32'" Label="PropertySheets">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+  </ImportGroup>
+  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseMT|x64'" Label="PropertySheets">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+  </ImportGroup>
+  <PropertyGroup Label="UserMacros" />
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+    <LinkIncremental>true</LinkIncremental>
+    <OutDir>$(SolutionDir)$(Configuration)\$(Platform)\$(ProjectName)\</OutDir>
+    <IntDir>$(Configuration)\$(Platform)\$(ProjectName)\</IntDir>
+    <TargetName>liblzma</TargetName>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
+    <LinkIncremental>true</LinkIncremental>
+    <OutDir>$(SolutionDir)$(Configuration)\$(Platform)\$(ProjectName)\</OutDir>
+    <IntDir>$(Configuration)\$(Platform)\$(ProjectName)\</IntDir>
+    <TargetName>liblzma</TargetName>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+    <LinkIncremental>
+    </LinkIncremental>
+    <OutDir>$(SolutionDir)$(Configuration)\$(Platform)\$(ProjectName)\</OutDir>
+    <IntDir>$(Configuration)\$(Platform)\$(ProjectName)\</IntDir>
+    <TargetName>liblzma</TargetName>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
+    <LinkIncremental />
+    <OutDir>$(SolutionDir)$(Configuration)\$(Platform)\$(ProjectName)\</OutDir>
+    <IntDir>$(Configuration)\$(Platform)\$(ProjectName)\</IntDir>
+    <TargetName>liblzma</TargetName>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseMT|Win32'">
+    <LinkIncremental>
+    </LinkIncremental>
+    <OutDir>$(SolutionDir)$(Configuration)\$(Platform)\$(ProjectName)\</OutDir>
+    <IntDir>$(Configuration)\$(Platform)\$(ProjectName)\</IntDir>
+    <TargetName>liblzma</TargetName>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseMT|x64'">
+    <LinkIncremental />
+    <OutDir>$(SolutionDir)$(Configuration)\$(Platform)\$(ProjectName)\</OutDir>
+    <IntDir>$(Configuration)\$(Platform)\$(ProjectName)\</IntDir>
+    <TargetName>liblzma</TargetName>
+  </PropertyGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+    <ClCompile>
+      <PreprocessorDefinitions>WIN32;HAVE_CONFIG_H;DLL_EXPORT;_DEBUG;_WINDOWS;_USRDLL;LIBLZMADLL_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
+      <WarningLevel>Level3</WarningLevel>
+      <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
+      <Optimization>Disabled</Optimization>
+      <AdditionalIncludeDirectories>./;../src/liblzma/common;../src/common;../src/liblzma/api;../src/liblzma/check;../src/liblzma/delta;../src/liblzma/lz;../src/liblzma/lzma;../src/liblzma/rangecoder;../src/liblzma/simple</AdditionalIncludeDirectories>
+    </ClCompile>
+    <Link>
+      <TargetMachine>MachineX86</TargetMachine>
+      <GenerateDebugInformation>true</GenerateDebugInformation>
+      <SubSystem>Windows</SubSystem>
+    </Link>
+    <ResourceCompile>
+      <AdditionalIncludeDirectories>./;../src/liblzma/common;../src/common;../src/liblzma/api;</AdditionalIncludeDirectories>
+    </ResourceCompile>
+  </ItemDefinitionGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
+    <ClCompile>
+      <PreprocessorDefinitions>WIN32;HAVE_CONFIG_H;DLL_EXPORT;_DEBUG;_WINDOWS;_USRDLL;LIBLZMADLL_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
+      <WarningLevel>Level3</WarningLevel>
+      <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
+      <Optimization>Disabled</Optimization>
+      <AdditionalIncludeDirectories>./;../src/liblzma/common;../src/common;../src/liblzma/api;../src/liblzma/check;../src/liblzma/delta;../src/liblzma/lz;../src/liblzma/lzma;../src/liblzma/rangecoder;../src/liblzma/simple</AdditionalIncludeDirectories>
+    </ClCompile>
+    <Link>
+      <GenerateDebugInformation>true</GenerateDebugInformation>
+      <SubSystem>Windows</SubSystem>
+    </Link>
+    <ResourceCompile>
+      <AdditionalIncludeDirectories>./;../src/liblzma/common;../src/common;../src/liblzma/api;</AdditionalIncludeDirectories>
+    </ResourceCompile>
+  </ItemDefinitionGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+    <ClCompile>
+      <PreprocessorDefinitions>WIN32;HAVE_CONFIG_H;DLL_EXPORT;NDEBUG;_WINDOWS;_USRDLL;LIBLZMADLL_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
+      <WarningLevel>Level3</WarningLevel>
+      <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
+      <AdditionalIncludeDirectories>./;../src/liblzma/common;../src/common;../src/liblzma/api;../src/liblzma/check;../src/liblzma/delta;../src/liblzma/lz;../src/liblzma/lzma;../src/liblzma/rangecoder;../src/liblzma/simple</AdditionalIncludeDirectories>
+    </ClCompile>
+    <Link>
+      <TargetMachine>MachineX86</TargetMachine>
+      <GenerateDebugInformation>true</GenerateDebugInformation>
+      <SubSystem>Windows</SubSystem>
+      <EnableCOMDATFolding>true</EnableCOMDATFolding>
+      <OptimizeReferences>true</OptimizeReferences>
+    </Link>
+    <ResourceCompile>
+      <AdditionalIncludeDirectories>./;../src/liblzma/common;../src/common;../src/liblzma/api;</AdditionalIncludeDirectories>
+    </ResourceCompile>
+  </ItemDefinitionGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
+    <ClCompile>
+      <PreprocessorDefinitions>WIN32;HAVE_CONFIG_H;DLL_EXPORT;NDEBUG;_WINDOWS;_USRDLL;LIBLZMADLL_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
+      <WarningLevel>Level3</WarningLevel>
+      <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
+      <AdditionalIncludeDirectories>./;../src/liblzma/common;../src/common;../src/liblzma/api;../src/liblzma/check;../src/liblzma/delta;../src/liblzma/lz;../src/liblzma/lzma;../src/liblzma/rangecoder;../src/liblzma/simple</AdditionalIncludeDirectories>
+    </ClCompile>
+    <Link>
+      <GenerateDebugInformation>true</GenerateDebugInformation>
+      <SubSystem>Windows</SubSystem>
+      <EnableCOMDATFolding>true</EnableCOMDATFolding>
+      <OptimizeReferences>true</OptimizeReferences>
+    </Link>
+    <ResourceCompile>
+      <AdditionalIncludeDirectories>./;../src/liblzma/common;../src/common;../src/liblzma/api;</AdditionalIncludeDirectories>
+    </ResourceCompile>
+  </ItemDefinitionGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseMT|Win32'">
+    <ClCompile>
+      <PreprocessorDefinitions>WIN32;HAVE_CONFIG_H;DLL_EXPORT;NDEBUG;_WINDOWS;_USRDLL;LIBLZMADLL_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <RuntimeLibrary>MultiThreaded</RuntimeLibrary>
+      <WarningLevel>Level3</WarningLevel>
+      <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
+      <AdditionalIncludeDirectories>./;../src/liblzma/common;../src/common;../src/liblzma/api;../src/liblzma/check;../src/liblzma/delta;../src/liblzma/lz;../src/liblzma/lzma;../src/liblzma/rangecoder;../src/liblzma/simple</AdditionalIncludeDirectories>
+    </ClCompile>
+    <Link>
+      <TargetMachine>MachineX86</TargetMachine>
+      <GenerateDebugInformation>true</GenerateDebugInformation>
+      <SubSystem>Windows</SubSystem>
+      <EnableCOMDATFolding>true</EnableCOMDATFolding>
+      <OptimizeReferences>true</OptimizeReferences>
+    </Link>
+    <ResourceCompile>
+      <AdditionalIncludeDirectories>./;../src/liblzma/common;../src/common;../src/liblzma/api;</AdditionalIncludeDirectories>
+    </ResourceCompile>
+  </ItemDefinitionGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseMT|x64'">
+    <ClCompile>
+      <PreprocessorDefinitions>WIN32;HAVE_CONFIG_H;DLL_EXPORT;NDEBUG;_WINDOWS;_USRDLL;LIBLZMADLL_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <RuntimeLibrary>MultiThreaded</RuntimeLibrary>
+      <WarningLevel>Level3</WarningLevel>
+      <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
+      <AdditionalIncludeDirectories>./;../src/liblzma/common;../src/common;../src/liblzma/api;../src/liblzma/check;../src/liblzma/delta;../src/liblzma/lz;../src/liblzma/lzma;../src/liblzma/rangecoder;../src/liblzma/simple</AdditionalIncludeDirectories>
+    </ClCompile>
+    <Link>
+      <GenerateDebugInformation>true</GenerateDebugInformation>
+      <SubSystem>Windows</SubSystem>
+      <EnableCOMDATFolding>true</EnableCOMDATFolding>
+      <OptimizeReferences>true</OptimizeReferences>
+    </Link>
+    <ResourceCompile>
+      <AdditionalIncludeDirectories>./;../src/liblzma/common;../src/common;../src/liblzma/api;</AdditionalIncludeDirectories>
+    </ResourceCompile>
+  </ItemDefinitionGroup>
+  <ItemGroup>
+    <ClCompile Include="..\src\common\tuklib_cpucores.c" />
+    <ClCompile Include="..\src\common\tuklib_physmem.c" />
+    <ClCompile Include="..\src\liblzma\check\check.c" />
+    <ClCompile Include="..\src\liblzma\check\crc32_fast.c" />
+    <ClCompile Include="..\src\liblzma\check\crc32_table.c" />
+    <ClCompile Include="..\src\liblzma\check\crc64_fast.c" />
+    <ClCompile Include="..\src\liblzma\check\crc64_table.c" />
+    <ClCompile Include="..\src\liblzma\check\sha256.c" />
+    <ClCompile Include="..\src\liblzma\common\alone_decoder.c" />
+    <ClCompile Include="..\src\liblzma\common\alone_encoder.c" />
+    <ClCompile Include="..\src\liblzma\common\auto_decoder.c" />
+    <ClCompile Include="..\src\liblzma\common\block_buffer_decoder.c" />
+    <ClCompile Include="..\src\liblzma\common\block_buffer_encoder.c" />
+    <ClCompile Include="..\src\liblzma\common\block_decoder.c" />
+    <ClCompile Include="..\src\liblzma\common\block_encoder.c" />
+    <ClCompile Include="..\src\liblzma\common\block_header_decoder.c" />
+    <ClCompile Include="..\src\liblzma\common\block_header_encoder.c" />
+    <ClCompile Include="..\src\liblzma\common\block_util.c" />
+    <ClCompile Include="..\src\liblzma\common\common.c" />
+    <ClCompile Include="..\src\liblzma\common\easy_buffer_encoder.c" />
+    <ClCompile Include="..\src\liblzma\common\easy_decoder_memusage.c" />
+    <ClCompile Include="..\src\liblzma\common\easy_encoder.c" />
+    <ClCompile Include="..\src\liblzma\common\easy_encoder_memusage.c" />
+    <ClCompile Include="..\src\liblzma\common\easy_preset.c" />
+    <ClCompile Include="..\src\liblzma\common\filter_buffer_decoder.c" />
+    <ClCompile Include="..\src\liblzma\common\filter_buffer_encoder.c" />
+    <ClCompile Include="..\src\liblzma\common\filter_common.c" />
+    <ClCompile Include="..\src\liblzma\common\filter_decoder.c" />
+    <ClCompile Include="..\src\liblzma\common\filter_encoder.c" />
+    <ClCompile Include="..\src\liblzma\common\filter_flags_decoder.c" />
+    <ClCompile Include="..\src\liblzma\common\filter_flags_encoder.c" />
+    <ClCompile Include="..\src\liblzma\common\hardware_cputhreads.c" />
+    <ClCompile Include="..\src\liblzma\common\hardware_physmem.c" />
+    <ClCompile Include="..\src\liblzma\common\index.c" />
+    <ClCompile Include="..\src\liblzma\common\index_decoder.c" />
+    <ClCompile Include="..\src\liblzma\common\index_encoder.c" />
+    <ClCompile Include="..\src\liblzma\common\index_hash.c" />
+    <ClCompile Include="..\src\liblzma\common\outqueue.c" />
+    <ClCompile Include="..\src\liblzma\common\stream_buffer_decoder.c" />
+    <ClCompile Include="..\src\liblzma\common\stream_buffer_encoder.c" />
+    <ClCompile Include="..\src\liblzma\common\stream_decoder.c" />
+    <ClCompile Include="..\src\liblzma\common\stream_encoder.c" />
+    <ClCompile Include="..\src\liblzma\common\stream_encoder_mt.c" />
+    <ClCompile Include="..\src\liblzma\common\stream_flags_common.c" />
+    <ClCompile Include="..\src\liblzma\common\stream_flags_decoder.c" />
+    <ClCompile Include="..\src\liblzma\common\stream_flags_encoder.c" />
+    <ClCompile Include="..\src\liblzma\common\vli_decoder.c" />
+    <ClCompile Include="..\src\liblzma\common\vli_encoder.c" />
+    <ClCompile Include="..\src\liblzma\common\vli_size.c" />
+    <ClCompile Include="..\src\liblzma\delta\delta_common.c" />
+    <ClCompile Include="..\src\liblzma\delta\delta_decoder.c" />
+    <ClCompile Include="..\src\liblzma\delta\delta_encoder.c" />
+    <ClCompile Include="..\src\liblzma\lzma\fastpos_table.c" />
+    <ClCompile Include="..\src\liblzma\lzma\lzma2_decoder.c" />
+    <ClCompile Include="..\src\liblzma\lzma\lzma2_encoder.c" />
+    <ClCompile Include="..\src\liblzma\lzma\lzma_decoder.c" />
+    <ClCompile Include="..\src\liblzma\lzma\lzma_encoder.c" />
+    <ClCompile Include="..\src\liblzma\lzma\lzma_encoder_optimum_fast.c" />
+    <ClCompile Include="..\src\liblzma\lzma\lzma_encoder_optimum_normal.c" />
+    <ClCompile Include="..\src\liblzma\lzma\lzma_encoder_presets.c" />
+    <ClCompile Include="..\src\liblzma\lz\lz_decoder.c" />
+    <ClCompile Include="..\src\liblzma\lz\lz_encoder.c" />
+    <ClCompile Include="..\src\liblzma\lz\lz_encoder_mf.c" />
+    <ClCompile Include="..\src\liblzma\rangecoder\price_table.c" />
+    <ClCompile Include="..\src\liblzma\simple\arm.c" />
+    <ClCompile Include="..\src\liblzma\simple\armthumb.c" />
+    <ClCompile Include="..\src\liblzma\simple\ia64.c" />
+    <ClCompile Include="..\src\liblzma\simple\powerpc.c" />
+    <ClCompile Include="..\src\liblzma\simple\simple_coder.c" />
+    <ClCompile Include="..\src\liblzma\simple\simple_decoder.c" />
+    <ClCompile Include="..\src\liblzma\simple\simple_encoder.c" />
+    <ClCompile Include="..\src\liblzma\simple\sparc.c" />
+    <ClCompile Include="..\src\liblzma\simple\x86.c" />
+  </ItemGroup>
+  <ItemGroup>
+    <ClInclude Include="..\src\common\mythread.h" />
+    <ClInclude Include="..\src\common\sysdefs.h" />
+    <ClInclude Include="..\src\common\tuklib_common.h" />
+    <ClInclude Include="..\src\common\tuklib_config.h" />
+    <ClInclude Include="..\src\common\tuklib_cpucores.h" />
+    <ClInclude Include="..\src\common\tuklib_integer.h" />
+    <ClInclude Include="..\src\common\tuklib_physmem.h" />
+    <ClInclude Include="..\src\liblzma\api\lzma.h" />
+    <ClInclude Include="..\src\liblzma\api\lzma\base.h" />
+    <ClInclude Include="..\src\liblzma\api\lzma\bcj.h" />
+    <ClInclude Include="..\src\liblzma\api\lzma\block.h" />
+    <ClInclude Include="..\src\liblzma\api\lzma\check.h" />
+    <ClInclude Include="..\src\liblzma\api\lzma\container.h" />
+    <ClInclude Include="..\src\liblzma\api\lzma\delta.h" />
+    <ClInclude Include="..\src\liblzma\api\lzma\filter.h" />
+    <ClInclude Include="..\src\liblzma\api\lzma\hardware.h" />
+    <ClInclude Include="..\src\liblzma\api\lzma\index.h" />
+    <ClInclude Include="..\src\liblzma\api\lzma\index_hash.h" />
+    <ClInclude Include="..\src\liblzma\api\lzma\lzma12.h" />
+    <ClInclude Include="..\src\liblzma\api\lzma\stream_flags.h" />
+    <ClInclude Include="..\src\liblzma\api\lzma\version.h" />
+    <ClInclude Include="..\src\liblzma\api\lzma\vli.h" />
+    <ClInclude Include="..\src\liblzma\check\check.h" />
+    <ClInclude Include="..\src\liblzma\check\crc32_table_be.h" />
+    <ClInclude Include="..\src\liblzma\check\crc32_table_le.h" />
+    <ClInclude Include="..\src\liblzma\check\crc64_table_be.h" />
+    <ClInclude Include="..\src\liblzma\check\crc64_table_le.h" />
+    <ClInclude Include="..\src\liblzma\check\crc_macros.h" />
+    <ClInclude Include="..\src\liblzma\common\alone_decoder.h" />
+    <ClInclude Include="..\src\liblzma\common\block_buffer_encoder.h" />
+    <ClInclude Include="..\src\liblzma\common\block_decoder.h" />
+    <ClInclude Include="..\src\liblzma\common\block_encoder.h" />
+    <ClInclude Include="..\src\liblzma\common\common.h" />
+    <ClInclude Include="..\src\liblzma\common\easy_preset.h" />
+    <ClInclude Include="..\src\liblzma\common\filter_common.h" />
+    <ClInclude Include="..\src\liblzma\common\filter_decoder.h" />
+    <ClInclude Include="..\src\liblzma\common\filter_encoder.h" />
+    <ClInclude Include="..\src\liblzma\common\index.h" />
+    <ClInclude Include="..\src\liblzma\common\index_encoder.h" />
+    <ClInclude Include="..\src\liblzma\common\memcmplen.h" />
+    <ClInclude Include="..\src\liblzma\common\outqueue.h" />
+    <ClInclude Include="..\src\liblzma\common\stream_decoder.h" />
+    <ClInclude Include="..\src\liblzma\common\stream_flags_common.h" />
+    <ClInclude Include="..\src\liblzma\delta\delta_common.h" />
+    <ClInclude Include="..\src\liblzma\delta\delta_decoder.h" />
+    <ClInclude Include="..\src\liblzma\delta\delta_encoder.h" />
+    <ClInclude Include="..\src\liblzma\delta\delta_private.h" />
+    <ClInclude Include="..\src\liblzma\lzma\fastpos.h" />
+    <ClInclude Include="..\src\liblzma\lzma\lzma2_decoder.h" />
+    <ClInclude Include="..\src\liblzma\lzma\lzma2_encoder.h" />
+    <ClInclude Include="..\src\liblzma\lzma\lzma_common.h" />
+    <ClInclude Include="..\src\liblzma\lzma\lzma_decoder.h" />
+    <ClInclude Include="..\src\liblzma\lzma\lzma_encoder.h" />
+    <ClInclude Include="..\src\liblzma\lzma\lzma_encoder_private.h" />
+    <ClInclude Include="..\src\liblzma\lz\lz_decoder.h" />
+    <ClInclude Include="..\src\liblzma\lz\lz_encoder.h" />
+    <ClInclude Include="..\src\liblzma\lz\lz_encoder_hash.h" />
+    <ClInclude Include="..\src\liblzma\lz\lz_encoder_hash_table.h" />
+    <ClInclude Include="..\src\liblzma\rangecoder\price.h" />
+    <ClInclude Include="..\src\liblzma\rangecoder\range_common.h" />
+    <ClInclude Include="..\src\liblzma\rangecoder\range_decoder.h" />
+    <ClInclude Include="..\src\liblzma\rangecoder\range_encoder.h" />
+    <ClInclude Include="..\src\liblzma\simple\simple_coder.h" />
+    <ClInclude Include="..\src\liblzma\simple\simple_decoder.h" />
+    <ClInclude Include="..\src\liblzma\simple\simple_encoder.h" />
+    <ClInclude Include="..\src\liblzma\simple\simple_private.h" />
+    <ClInclude Include="config.h" />
+  </ItemGroup>
+  <ItemGroup>
+    <ResourceCompile Include="..\src\liblzma\liblzma_w32res.rc" />
+  </ItemGroup>
+  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
+  <ImportGroup Label="ExtensionTargets">
+  </ImportGroup>
+</Project>
\ No newline at end of file
diff --git a/windows/xz_win.sln b/windows/xz_win.sln
new file mode 100644
index 0000000..3d25291
--- /dev/null
+++ b/windows/xz_win.sln
@@ -0,0 +1,48 @@
+
+Microsoft Visual Studio Solution File, Format Version 12.00
+# Visual Studio 2013
+VisualStudioVersion = 12.0.31101.0
+MinimumVisualStudioVersion = 10.0.40219.1
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "liblzma", "liblzma.vcxproj", "{12728250-16EC-4DC6-94D7-E21DD88947F8}"
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "liblzma_dll", "liblzma_dll.vcxproj", "{E0F247DB-EF12-4755-8DF9-F74BCD1348F7}"
+EndProject
+Global
+	GlobalSection(SolutionConfigurationPlatforms) = preSolution
+		Debug|Win32 = Debug|Win32
+		Debug|x64 = Debug|x64
+		Release|Win32 = Release|Win32
+		Release|x64 = Release|x64
+		ReleaseMT|Win32 = ReleaseMT|Win32
+		ReleaseMT|x64 = ReleaseMT|x64
+	EndGlobalSection
+	GlobalSection(ProjectConfigurationPlatforms) = postSolution
+		{12728250-16EC-4DC6-94D7-E21DD88947F8}.Debug|Win32.ActiveCfg = Debug|Win32
+		{12728250-16EC-4DC6-94D7-E21DD88947F8}.Debug|Win32.Build.0 = Debug|Win32
+		{12728250-16EC-4DC6-94D7-E21DD88947F8}.Debug|x64.ActiveCfg = Debug|x64
+		{12728250-16EC-4DC6-94D7-E21DD88947F8}.Debug|x64.Build.0 = Debug|x64
+		{12728250-16EC-4DC6-94D7-E21DD88947F8}.Release|Win32.ActiveCfg = Release|Win32
+		{12728250-16EC-4DC6-94D7-E21DD88947F8}.Release|Win32.Build.0 = Release|Win32
+		{12728250-16EC-4DC6-94D7-E21DD88947F8}.Release|x64.ActiveCfg = Release|x64
+		{12728250-16EC-4DC6-94D7-E21DD88947F8}.Release|x64.Build.0 = Release|x64
+		{12728250-16EC-4DC6-94D7-E21DD88947F8}.ReleaseMT|Win32.ActiveCfg = ReleaseMT|Win32
+		{12728250-16EC-4DC6-94D7-E21DD88947F8}.ReleaseMT|Win32.Build.0 = ReleaseMT|Win32
+		{12728250-16EC-4DC6-94D7-E21DD88947F8}.ReleaseMT|x64.ActiveCfg = ReleaseMT|x64
+		{12728250-16EC-4DC6-94D7-E21DD88947F8}.ReleaseMT|x64.Build.0 = ReleaseMT|x64
+		{E0F247DB-EF12-4755-8DF9-F74BCD1348F7}.Debug|Win32.ActiveCfg = Debug|Win32
+		{E0F247DB-EF12-4755-8DF9-F74BCD1348F7}.Debug|Win32.Build.0 = Debug|Win32
+		{E0F247DB-EF12-4755-8DF9-F74BCD1348F7}.Debug|x64.ActiveCfg = Debug|x64
+		{E0F247DB-EF12-4755-8DF9-F74BCD1348F7}.Debug|x64.Build.0 = Debug|x64
+		{E0F247DB-EF12-4755-8DF9-F74BCD1348F7}.Release|Win32.ActiveCfg = Release|Win32
+		{E0F247DB-EF12-4755-8DF9-F74BCD1348F7}.Release|Win32.Build.0 = Release|Win32
+		{E0F247DB-EF12-4755-8DF9-F74BCD1348F7}.Release|x64.ActiveCfg = Release|x64
+		{E0F247DB-EF12-4755-8DF9-F74BCD1348F7}.Release|x64.Build.0 = Release|x64
+		{E0F247DB-EF12-4755-8DF9-F74BCD1348F7}.ReleaseMT|Win32.ActiveCfg = ReleaseMT|Win32
+		{E0F247DB-EF12-4755-8DF9-F74BCD1348F7}.ReleaseMT|Win32.Build.0 = ReleaseMT|Win32
+		{E0F247DB-EF12-4755-8DF9-F74BCD1348F7}.ReleaseMT|x64.ActiveCfg = ReleaseMT|x64
+		{E0F247DB-EF12-4755-8DF9-F74BCD1348F7}.ReleaseMT|x64.Build.0 = ReleaseMT|x64
+	EndGlobalSection
+	GlobalSection(SolutionProperties) = preSolution
+		HideSolutionNode = FALSE
+	EndGlobalSection
+EndGlobal