diff --git a/Makefile.am b/Makefile.am
index 9565c15d13784ba9c78bf9c69ee07888e6545907_TWFrZWZpbGUuYW0=..d1697a8148c434a25b06a700d919c41e2e622bbe_TWFrZWZpbGUuYW0= 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -47,6 +47,7 @@
 endif
 
 EXTRA_DIST = \
+	po4a \
 	extra \
 	dos \
 	windows \
@@ -99,5 +100,7 @@
 	fi
 
 # This works with GNU tar and gives cleaner package than normal 'make dist'.
+# This also ensures that the man page translations are up to date (dist-hook
+# would be too late for that).
 mydist:
 	sh "$(srcdir)/src/liblzma/validate_map.sh"
@@ -102,5 +105,6 @@
 mydist:
 	sh "$(srcdir)/src/liblzma/validate_map.sh"
+	cd "$(srcdir)/po4a" && sh update-po
 	VERSION=$(VERSION); \
 	if test -d "$(srcdir)/.git" && type git > /dev/null 2>&1; then \
 		SNAPSHOT=`cd "$(srcdir)" && git describe --abbrev=4 | cut -b2-`; \
diff --git a/autogen.sh b/autogen.sh
index 9565c15d13784ba9c78bf9c69ee07888e6545907_YXV0b2dlbi5zaA==..d1697a8148c434a25b06a700d919c41e2e622bbe_YXV0b2dlbi5zaA== 100755
--- a/autogen.sh
+++ b/autogen.sh
@@ -9,8 +9,5 @@
 #
 ###############################################################################
 
-# The result of using "autoreconf -fi" should be identical to using this
-# script. I'm leaving this script here just in case someone finds it useful.
-
 set -e -x
 
@@ -15,8 +12,9 @@
 set -e -x
 
+# The following six lines are almost identical to "autoreconf -fi" but faster.
 ${AUTOPOINT:-autopoint} -f
 ${LIBTOOLIZE:-libtoolize} -c -f || glibtoolize -c -f
 ${ACLOCAL:-aclocal} -I m4
 ${AUTOCONF:-autoconf}
 ${AUTOHEADER:-autoheader}
 ${AUTOMAKE:-automake} -acf --foreign
@@ -17,6 +15,10 @@
 ${AUTOPOINT:-autopoint} -f
 ${LIBTOOLIZE:-libtoolize} -c -f || glibtoolize -c -f
 ${ACLOCAL:-aclocal} -I m4
 ${AUTOCONF:-autoconf}
 ${AUTOHEADER:-autoheader}
 ${AUTOMAKE:-automake} -acf --foreign
+
+# Generate the translated man pages if the "po4a" tool is available.
+# This is *NOT* done by "autoreconf -fi" or when "make" is run.
+cd po4a && sh update-po
diff --git a/po4a/.gitignore b/po4a/.gitignore
new file mode 100644
index 0000000000000000000000000000000000000000..d1697a8148c434a25b06a700d919c41e2e622bbe_cG80YS8uZ2l0aWdub3Jl
--- /dev/null
+++ b/po4a/.gitignore
@@ -0,0 +1,2 @@
+/man
+/xz-man.pot
diff --git a/po4a/po4a.conf b/po4a/po4a.conf
new file mode 100644
index 0000000000000000000000000000000000000000..d1697a8148c434a25b06a700d919c41e2e622bbe_cG80YS9wbzRhLmNvbmY=
--- /dev/null
+++ b/po4a/po4a.conf
@@ -0,0 +1,14 @@
+# To add a new language, add it to po4a_langs and run "update-po"
+# to get a new .po file. After translating the .po file, run
+# "update-po" again to generate the translated man pages.
+
+[po4a_langs]
+[po4a_paths] xz-man.pot $lang:$lang.po
+
+[type: man] ../src/xz/xz.1              $lang:man/$lang/xz.1
+[type: man] ../src/xzdec/xzdec.1        $lang:man/$lang/xzdec.1
+[type: man] ../src/lzmainfo/lzmainfo.1  $lang:man/$lang/lzmainfo.1
+[type: man] ../src/scripts/xzdiff.1     $lang:man/$lang/xzdiff.1
+[type: man] ../src/scripts/xzgrep.1     $lang:man/$lang/xzgrep.1
+[type: man] ../src/scripts/xzless.1     $lang:man/$lang/xzless.1
+[type: man] ../src/scripts/xzmore.1     $lang:man/$lang/xzmore.1
diff --git a/po4a/update-po b/po4a/update-po
new file mode 100755
index 0000000000000000000000000000000000000000..d1697a8148c434a25b06a700d919c41e2e622bbe_cG80YS91cGRhdGUtcG8=
--- /dev/null
+++ b/po4a/update-po
@@ -0,0 +1,45 @@
+#!/bin/sh
+#
+#############################################################################
+#
+# Updates xz-man.pot and the *.po files, and generates translated man pages.
+# These are done using the program po4a. If po4a is missing, it is still
+# possible to build the package without translated man pages.
+#
+#############################################################################
+#
+# Author: Lasse Collin
+#
+# This file has been put into the public domain.
+# You can do whatever you want with this file.
+#
+#############################################################################
+
+if type po4a > /dev/null 2>&1; then
+	:
+else
+	echo "po4a/update-po: The program 'po4a' was not found." >&2
+	echo "po4a/update-po: Translated man pages were not generated." >&2
+	exit 1
+fi
+
+if test ! -f po4a.conf; then
+	cd `dirname "$0"` || exit 1
+	if test ! -f po4a.conf; then
+		echo "update-po: Error: Cannot find po4a.conf." >&2
+		exit 1
+	fi
+fi
+
+PACKAGE_VERSION=`cd .. && sh build-aux/version.sh` || exit 1
+
+# Using --force to get up-to-date version numbers in the output files
+# when nothing else has changed. This makes it slower but it's fine
+# as long as this isn't run every time when "make" is run at the
+# top level directory. (po4a isn't super-fast even without --force).
+set -x
+po4a --force --verbose \
+	--package-name="XZ Utils" \
+	--package-version="$PACKAGE_VERSION" \
+	--copyright-holder="This file is put in the public domain." \
+	po4a.conf
diff --git a/src/scripts/Makefile.am b/src/scripts/Makefile.am
index 9565c15d13784ba9c78bf9c69ee07888e6545907_c3JjL3NjcmlwdHMvTWFrZWZpbGUuYW0=..d1697a8148c434a25b06a700d919c41e2e622bbe_c3JjL3NjcmlwdHMvTWFrZWZpbGUuYW0= 100644
--- a/src/scripts/Makefile.am
+++ b/src/scripts/Makefile.am
@@ -25,16 +25,7 @@
 endif
 
 install-exec-hook:
-	cd $(DESTDIR)$(bindir) && \
-	for pair in $(links); do \
-		target=`echo $$pair | sed 's/-.*$$//' | sed '$(transform)'` && \
-		link=`echo $$pair | sed 's/^.*-//' | sed '$(transform)'` && \
-		rm -f $$link && \
-		$(LN_S) $$target $$link; \
-	done
-
-install-data-hook:
-	cd $(DESTDIR)$(mandir)/man1 && \
+	cd "$(DESTDIR)$(bindir)" && \
 	for pair in $(links); do \
 		target=`echo $$pair | sed 's/-.*$$//' | sed '$(transform)'` && \
 		link=`echo $$pair | sed 's/^.*-//' | sed '$(transform)'` && \
@@ -38,8 +29,42 @@
 	for pair in $(links); do \
 		target=`echo $$pair | sed 's/-.*$$//' | sed '$(transform)'` && \
 		link=`echo $$pair | sed 's/^.*-//' | sed '$(transform)'` && \
-		rm -f $$link.1 && \
-		$(LN_S) $$target.1 $$link.1; \
+		rm -f "$$link" && \
+		$(LN_S) "$$target" "$$link"; \
+	done
+
+# The installation of translated man pages abuses Automake internals
+# by calling "install-man" with redefined dist_man_MANS and man_MANS.
+# If this breaks some day, don't blame Automake developers.
+install-data-hook:
+	languages= ; \
+	if test "$(USE_NLS)" = yes && test -d "$(top_srcdir)/po4a/man"; then \
+		languages=`ls "$(top_srcdir)/po4a/man"`; \
+	fi; \
+	for lang in $$languages; do \
+		mans= ; \
+		for man in $(dist_man_MANS); do \
+			man="$(top_srcdir)/po4a/man/$$lang/$$man" ; \
+			if test -f "$$man"; then \
+				mans="$$mans $$man"; \
+			fi; \
+		done; \
+		$(MAKE) dist_man_MANS="$$mans" man_MANS= \
+				mandir="$(mandir)/$$lang" install-man; \
+	done; \
+	for lang in . $$languages; do \
+		for pair in $(links); do \
+			target=`echo $$pair | sed 's/-.*$$//' \
+					| sed '$(transform)'` && \
+			link=`echo $$pair | sed 's/^.*-//' \
+					| sed '$(transform)'` && \
+			man1dir="$(DESTDIR)$(mandir)/$$lang/man1" && \
+			if test -f "$$man1dir/$$target.1"; then ( \
+				cd "$$man1dir" && \
+				rm -f "$$link.1" && \
+				$(LN_S) "$$target.1" "$$link.1" \
+			); fi; \
+		done; \
 	done
 
 uninstall-hook:
@@ -43,6 +68,6 @@
 	done
 
 uninstall-hook:
-	cd $(DESTDIR)$(bindir) && \
+	cd "$(DESTDIR)$(bindir)" && \
 	for pair in $(links); do \
 		link=`echo $$pair | sed 's/^.*-//' | sed '$(transform)'` && \
@@ -47,4 +72,4 @@
 	for pair in $(links); do \
 		link=`echo $$pair | sed 's/^.*-//' | sed '$(transform)'` && \
-		rm -f $$link; \
+		rm -f "$$link"; \
 	done
@@ -50,6 +75,15 @@
 	done
-	cd $(DESTDIR)$(mandir)/man1 && \
-	for pair in $(links); do \
-		link=`echo $$pair | sed 's/^.*-//' | sed '$(transform)'` && \
-		rm -f $$link.1; \
+	languages= ; \
+	if test "$(USE_NLS)" = yes && test -d "$(top_srcdir)/po4a/man"; then \
+		languages=`ls "$(top_srcdir)/po4a/man"`; \
+	fi; \
+	for lang in . $$languages; do \
+		for pair in $(links); do \
+			target=`echo $$pair | sed 's/-.*$$//' \
+					| sed '$(transform)'` && \
+			link=`echo $$pair | sed 's/^.*-//' \
+					| sed '$(transform)'` && \
+			rm -f "$(DESTDIR)$(mandir)/$$lang/man1/$$target.1" \
+				"$(DESTDIR)$(mandir)/$$lang/man1/$$link.1"; \
+		done; \
 	done
diff --git a/src/xz/Makefile.am b/src/xz/Makefile.am
index 9565c15d13784ba9c78bf9c69ee07888e6545907_c3JjL3h6L01ha2VmaWxlLmFt..d1697a8148c434a25b06a700d919c41e2e622bbe_c3JjL3h6L01ha2VmaWxlLmFt 100644
--- a/src/xz/Makefile.am
+++ b/src/xz/Makefile.am
@@ -81,7 +81,7 @@
 endif
 
 install-exec-hook:
-	cd $(DESTDIR)$(bindir) && \
+	cd "$(DESTDIR)$(bindir)" && \
 	target=`echo xz | sed '$(transform)'`$(EXEEXT) && \
 	for name in $(xzlinks); do \
 		link=`echo $$name | sed '$(transform)'`$(LN_EXEEXT) && \
@@ -85,7 +85,7 @@
 	target=`echo xz | sed '$(transform)'`$(EXEEXT) && \
 	for name in $(xzlinks); do \
 		link=`echo $$name | sed '$(transform)'`$(LN_EXEEXT) && \
-		rm -f $$link && \
-		$(LN_S) $$target $$link; \
+		rm -f "$$link" && \
+		$(LN_S) "$$target" "$$link"; \
 	done
 
@@ -90,3 +90,6 @@
 	done
 
+# The installation of translated man pages abuses Automake internals
+# by calling "install-man" with redefined dist_man_MANS and man_MANS.
+# If this breaks some day, don't blame Automake developers.
 install-data-hook:
@@ -92,3 +95,6 @@
 install-data-hook:
-	cd $(DESTDIR)$(mandir)/man1 && \
+	languages= ; \
+	if test "$(USE_NLS)" = yes && test -d "$(top_srcdir)/po4a/man"; then \
+		languages=`ls "$(top_srcdir)/po4a/man"`; \
+	fi; \
 	target=`echo xz | sed '$(transform)'` && \
@@ -94,8 +100,19 @@
 	target=`echo xz | sed '$(transform)'` && \
-	for name in $(xzlinks); do \
-		link=`echo $$name | sed '$(transform)'` && \
-		rm -f $$link.1 && \
-		$(LN_S) $$target.1 $$link.1; \
+	for lang in . $$languages; do \
+		man="$(top_srcdir)/po4a/man/$$lang/xz.1" ; \
+		if test -f "$$man"; then \
+			$(MAKE) dist_man_MANS="$$man" man_MANS= \
+				mandir="$(mandir)/$$lang" install-man; \
+		fi; \
+		man1dir="$(DESTDIR)$(mandir)/$$lang/man1" && \
+		if test -f "$$man1dir/$$target.1"; then ( \
+			cd "$$man1dir" && \
+			for name in $(xzlinks); do \
+				link=`echo $$name | sed '$(transform)'` && \
+				rm -f "$$link.1" && \
+				$(LN_S) "$$target.1" "$$link.1"; \
+			done \
+		); fi; \
 	done
 
 uninstall-hook:
@@ -99,6 +116,6 @@
 	done
 
 uninstall-hook:
-	cd $(DESTDIR)$(bindir) && \
+	cd "$(DESTDIR)$(bindir)" && \
 	for name in $(xzlinks); do \
 		link=`echo $$name | sed '$(transform)'`$(LN_EXEEXT) && \
@@ -103,4 +120,4 @@
 	for name in $(xzlinks); do \
 		link=`echo $$name | sed '$(transform)'`$(LN_EXEEXT) && \
-		rm -f $$link; \
+		rm -f "$$link"; \
 	done
@@ -106,6 +123,11 @@
 	done
-	cd $(DESTDIR)$(mandir)/man1 && \
-	for name in $(xzlinks); do \
-		link=`echo $$name | sed '$(transform)'` && \
-		rm -f $$link.1; \
+	languages= ; \
+	if test "$(USE_NLS)" = yes && test -d "$(top_srcdir)/po4a/man"; then \
+		languages=`ls "$(top_srcdir)/po4a/man"`; \
+	fi; \
+	for lang in . $$languages; do \
+		for name in xz $(xzlinks); do \
+			name=`echo $$name | sed '$(transform)'` && \
+			rm -f "$(DESTDIR)$(mandir)/$$lang/man1/$$name.1"; \
+		done; \
 	done
diff --git a/src/xzdec/Makefile.am b/src/xzdec/Makefile.am
index 9565c15d13784ba9c78bf9c69ee07888e6545907_c3JjL3h6ZGVjL01ha2VmaWxlLmFt..d1697a8148c434a25b06a700d919c41e2e622bbe_c3JjL3h6ZGVjL01ha2VmaWxlLmFt 100644
--- a/src/xzdec/Makefile.am
+++ b/src/xzdec/Makefile.am
@@ -50,6 +50,7 @@
 
 
 bin_PROGRAMS =
+lzmadecmanlink =
 
 if COND_XZDEC
 bin_PROGRAMS += xzdec
@@ -60,10 +61,8 @@
 bin_PROGRAMS += lzmadec
 
 # 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.
+# This is better than creating a dangling symlink. The correct solution
+# would be to install xzdec.1 as lzmadec.1 but this code is already too
+# complicated so I won't do it. Installing only lzmadec is a bit unusual
+# situation anyway so it's not that important.
 if COND_XZDEC
@@ -69,2 +68,10 @@
 if COND_XZDEC
+lzmadecmanlink += lzmadec
+endif
+endif
+
+if COND_XZDEC
+# The installation of translated man pages abuses Automake internals
+# by calling "install-man" with redefined dist_man_MANS and man_MANS.
+# If this breaks some day, don't blame Automake developers.
 install-data-hook:
@@ -70,4 +77,7 @@
 install-data-hook:
-	cd $(DESTDIR)$(mandir)/man1 && \
+	languages= ; \
+	if test "$(USE_NLS)" = yes && test -d "$(top_srcdir)/po4a/man"; then \
+		languages=`ls "$(top_srcdir)/po4a/man"`; \
+	fi; \
 	target=`echo xzdec | sed '$(transform)'` && \
 	link=`echo lzmadec | sed '$(transform)'` && \
@@ -72,6 +82,19 @@
 	target=`echo xzdec | sed '$(transform)'` && \
 	link=`echo lzmadec | sed '$(transform)'` && \
-	rm -f $$link.1 && \
-	$(LN_S) $$target.1 $$link.1
+	for lang in . $$languages; do \
+		man="$(top_srcdir)/po4a/man/$$lang/xzdec.1" ; \
+		if test -f "$$man"; then \
+			$(MAKE) dist_man_MANS="$$man" man_MANS= \
+				mandir="$(mandir)/$$lang" install-man; \
+		fi; \
+		man1dir="$(DESTDIR)$(mandir)/$$lang/man1" && \
+		if test -f "$$man1dir/$$target.1"; then \
+			if test -n "$(lzmadecmanlink)"; then ( \
+				cd "$$man1dir" && \
+				rm -f "$$link.1" && \
+				$(LN_S) "$$target.1" "$$link.1" \
+			); fi; \
+		fi; \
+	done
 
 uninstall-hook:
@@ -76,6 +99,13 @@
 
 uninstall-hook:
-	cd $(DESTDIR)$(mandir)/man1 && \
-	link=`echo lzmadec | sed '$(transform)'` && \
-	rm -f $$link.1
+	languages= ; \
+	if test "$(USE_NLS)" = yes && test -d "$(top_srcdir)/po4a/man"; then \
+		languages=`ls "$(top_srcdir)/po4a/man"`; \
+	fi; \
+	for lang in . $$languages; do \
+		for name in xzdec $(lzmadecmanlink); do \
+			name=`echo $$name | sed '$(transform)'` && \
+			rm -f "$(DESTDIR)$(mandir)/$$lang/man1/$$name.1"; \
+		done; \
+	done
 endif
@@ -81,2 +111,1 @@
 endif
-endif