Bug 502933: importing the 7-zip library, r=bsmedberg
authorAlex Pahotkin <alexp@mozilla.com>
Fri, 13 Nov 2009 15:03:30 -0800
changeset 34847 0b3c29bf0fb89bec1c86f5ed97ec238a5327f9fd
parent 34846 57e57190f52087de4f45cca1784d137b8a5e9f17
child 34848 ed50524641ba29d16c6507424cd2b24e72d709dd
push id10300
push userbcrowder@mozilla.com
push dateFri, 13 Nov 2009 23:12:23 +0000
treeherdermozilla-central@0b3c29bf0fb8 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersbsmedberg
bugs502933
milestone1.9.3a1pre
Bug 502933: importing the 7-zip library, r=bsmedberg
modules/lib7z/7zLib.cpp
modules/lib7z/7zLib.h
modules/lib7z/7zobjs.mk
modules/lib7z/LZMASDK/7zC.txt
modules/lib7z/LZMASDK/7zFormat.txt
modules/lib7z/LZMASDK/Asm/x64/7zCrcT8U.asm
modules/lib7z/LZMASDK/Asm/x86/7zCrcT8U.asm
modules/lib7z/LZMASDK/C/7z.h
modules/lib7z/LZMASDK/C/7zBuf.c
modules/lib7z/LZMASDK/C/7zBuf.h
modules/lib7z/LZMASDK/C/7zBuf2.c
modules/lib7z/LZMASDK/C/7zCrc.c
modules/lib7z/LZMASDK/C/7zCrc.h
modules/lib7z/LZMASDK/C/7zCrcT8.c
modules/lib7z/LZMASDK/C/7zDec.c
modules/lib7z/LZMASDK/C/7zFile.c
modules/lib7z/LZMASDK/C/7zFile.h
modules/lib7z/LZMASDK/C/7zIn.c
modules/lib7z/LZMASDK/C/7zStream.c
modules/lib7z/LZMASDK/C/7zVersion.h
modules/lib7z/LZMASDK/C/Alloc.c
modules/lib7z/LZMASDK/C/Alloc.h
modules/lib7z/LZMASDK/C/Bcj2.c
modules/lib7z/LZMASDK/C/Bcj2.h
modules/lib7z/LZMASDK/C/Bra.c
modules/lib7z/LZMASDK/C/Bra.h
modules/lib7z/LZMASDK/C/Bra86.c
modules/lib7z/LZMASDK/C/BraIA64.c
modules/lib7z/LZMASDK/C/CpuArch.h
modules/lib7z/LZMASDK/C/Delta.c
modules/lib7z/LZMASDK/C/Delta.h
modules/lib7z/LZMASDK/C/LzFind.c
modules/lib7z/LZMASDK/C/LzFind.h
modules/lib7z/LZMASDK/C/LzFindMt.c
modules/lib7z/LZMASDK/C/LzFindMt.h
modules/lib7z/LZMASDK/C/LzHash.h
modules/lib7z/LZMASDK/C/Lzma2Dec.c
modules/lib7z/LZMASDK/C/Lzma2Dec.h
modules/lib7z/LZMASDK/C/Lzma2Enc.c
modules/lib7z/LZMASDK/C/Lzma2Enc.h
modules/lib7z/LZMASDK/C/Lzma86.h
modules/lib7z/LZMASDK/C/Lzma86Dec.c
modules/lib7z/LZMASDK/C/Lzma86Enc.c
modules/lib7z/LZMASDK/C/LzmaDec.c
modules/lib7z/LZMASDK/C/LzmaDec.h
modules/lib7z/LZMASDK/C/LzmaEnc.c
modules/lib7z/LZMASDK/C/LzmaEnc.h
modules/lib7z/LZMASDK/C/LzmaLib.c
modules/lib7z/LZMASDK/C/LzmaLib.h
modules/lib7z/LZMASDK/C/MtCoder.c
modules/lib7z/LZMASDK/C/MtCoder.h
modules/lib7z/LZMASDK/C/RotateDefs.h
modules/lib7z/LZMASDK/C/Sha256.c
modules/lib7z/LZMASDK/C/Sha256.h
modules/lib7z/LZMASDK/C/Threads.c
modules/lib7z/LZMASDK/C/Threads.h
modules/lib7z/LZMASDK/C/Types.h
modules/lib7z/LZMASDK/C/Util/7z/7z.dsp
modules/lib7z/LZMASDK/C/Util/7z/7z.dsw
modules/lib7z/LZMASDK/C/Util/7z/7zAlloc.c
modules/lib7z/LZMASDK/C/Util/7z/7zAlloc.h
modules/lib7z/LZMASDK/C/Util/7z/7zMain.c
modules/lib7z/LZMASDK/C/Util/7z/makefile
modules/lib7z/LZMASDK/C/Util/7z/makefile.gcc
modules/lib7z/LZMASDK/C/Util/Lzma/LzmaUtil.c
modules/lib7z/LZMASDK/C/Util/Lzma/LzmaUtil.dsp
modules/lib7z/LZMASDK/C/Util/Lzma/LzmaUtil.dsw
modules/lib7z/LZMASDK/C/Util/Lzma/makefile
modules/lib7z/LZMASDK/C/Util/Lzma/makefile.gcc
modules/lib7z/LZMASDK/C/Util/LzmaLib/LzmaLib.def
modules/lib7z/LZMASDK/C/Util/LzmaLib/LzmaLib.dsp
modules/lib7z/LZMASDK/C/Util/LzmaLib/LzmaLib.dsw
modules/lib7z/LZMASDK/C/Util/LzmaLib/LzmaLibExports.c
modules/lib7z/LZMASDK/C/Util/LzmaLib/makefile
modules/lib7z/LZMASDK/C/Util/LzmaLib/resource.rc
modules/lib7z/LZMASDK/C/Xz.c
modules/lib7z/LZMASDK/C/Xz.h
modules/lib7z/LZMASDK/C/XzCrc64.c
modules/lib7z/LZMASDK/C/XzCrc64.h
modules/lib7z/LZMASDK/C/XzDec.c
modules/lib7z/LZMASDK/C/XzEnc.c
modules/lib7z/LZMASDK/C/XzEnc.h
modules/lib7z/LZMASDK/C/XzIn.c
modules/lib7z/LZMASDK/CPP/7zip/Archive/7z/7zCompressionMode.cpp
modules/lib7z/LZMASDK/CPP/7zip/Archive/7z/7zCompressionMode.h
modules/lib7z/LZMASDK/CPP/7zip/Archive/7z/7zDecode.cpp
modules/lib7z/LZMASDK/CPP/7zip/Archive/7z/7zDecode.h
modules/lib7z/LZMASDK/CPP/7zip/Archive/7z/7zEncode.cpp
modules/lib7z/LZMASDK/CPP/7zip/Archive/7z/7zEncode.h
modules/lib7z/LZMASDK/CPP/7zip/Archive/7z/7zExtract.cpp
modules/lib7z/LZMASDK/CPP/7zip/Archive/7z/7zFolderInStream.cpp
modules/lib7z/LZMASDK/CPP/7zip/Archive/7z/7zFolderInStream.h
modules/lib7z/LZMASDK/CPP/7zip/Archive/7z/7zFolderOutStream.cpp
modules/lib7z/LZMASDK/CPP/7zip/Archive/7z/7zFolderOutStream.h
modules/lib7z/LZMASDK/CPP/7zip/Archive/7z/7zHandler.cpp
modules/lib7z/LZMASDK/CPP/7zip/Archive/7z/7zHandler.h
modules/lib7z/LZMASDK/CPP/7zip/Archive/7z/7zHandlerOut.cpp
modules/lib7z/LZMASDK/CPP/7zip/Archive/7z/7zHeader.cpp
modules/lib7z/LZMASDK/CPP/7zip/Archive/7z/7zHeader.h
modules/lib7z/LZMASDK/CPP/7zip/Archive/7z/7zIn.cpp
modules/lib7z/LZMASDK/CPP/7zip/Archive/7z/7zIn.h
modules/lib7z/LZMASDK/CPP/7zip/Archive/7z/7zItem.h
modules/lib7z/LZMASDK/CPP/7zip/Archive/7z/7zOut.cpp
modules/lib7z/LZMASDK/CPP/7zip/Archive/7z/7zOut.h
modules/lib7z/LZMASDK/CPP/7zip/Archive/7z/7zProperties.cpp
modules/lib7z/LZMASDK/CPP/7zip/Archive/7z/7zProperties.h
modules/lib7z/LZMASDK/CPP/7zip/Archive/7z/7zRegister.cpp
modules/lib7z/LZMASDK/CPP/7zip/Archive/7z/7zSpecStream.cpp
modules/lib7z/LZMASDK/CPP/7zip/Archive/7z/7zSpecStream.h
modules/lib7z/LZMASDK/CPP/7zip/Archive/7z/7zUpdate.cpp
modules/lib7z/LZMASDK/CPP/7zip/Archive/7z/7zUpdate.h
modules/lib7z/LZMASDK/CPP/7zip/Archive/7z/StdAfx.cpp
modules/lib7z/LZMASDK/CPP/7zip/Archive/7z/StdAfx.h
modules/lib7z/LZMASDK/CPP/7zip/Archive/Archive.def
modules/lib7z/LZMASDK/CPP/7zip/Archive/Archive2.def
modules/lib7z/LZMASDK/CPP/7zip/Archive/ArchiveExports.cpp
modules/lib7z/LZMASDK/CPP/7zip/Archive/Common/CoderMixer2.cpp
modules/lib7z/LZMASDK/CPP/7zip/Archive/Common/CoderMixer2.h
modules/lib7z/LZMASDK/CPP/7zip/Archive/Common/CoderMixer2MT.cpp
modules/lib7z/LZMASDK/CPP/7zip/Archive/Common/CoderMixer2MT.h
modules/lib7z/LZMASDK/CPP/7zip/Archive/Common/CrossThreadProgress.cpp
modules/lib7z/LZMASDK/CPP/7zip/Archive/Common/CrossThreadProgress.h
modules/lib7z/LZMASDK/CPP/7zip/Archive/Common/DummyOutStream.cpp
modules/lib7z/LZMASDK/CPP/7zip/Archive/Common/DummyOutStream.h
modules/lib7z/LZMASDK/CPP/7zip/Archive/Common/HandlerOut.cpp
modules/lib7z/LZMASDK/CPP/7zip/Archive/Common/HandlerOut.h
modules/lib7z/LZMASDK/CPP/7zip/Archive/Common/InStreamWithCRC.cpp
modules/lib7z/LZMASDK/CPP/7zip/Archive/Common/InStreamWithCRC.h
modules/lib7z/LZMASDK/CPP/7zip/Archive/Common/ItemNameUtils.cpp
modules/lib7z/LZMASDK/CPP/7zip/Archive/Common/ItemNameUtils.h
modules/lib7z/LZMASDK/CPP/7zip/Archive/Common/MultiStream.cpp
modules/lib7z/LZMASDK/CPP/7zip/Archive/Common/MultiStream.h
modules/lib7z/LZMASDK/CPP/7zip/Archive/Common/OutStreamWithCRC.cpp
modules/lib7z/LZMASDK/CPP/7zip/Archive/Common/OutStreamWithCRC.h
modules/lib7z/LZMASDK/CPP/7zip/Archive/Common/ParseProperties.cpp
modules/lib7z/LZMASDK/CPP/7zip/Archive/Common/ParseProperties.h
modules/lib7z/LZMASDK/CPP/7zip/Archive/Common/StdAfx.h
modules/lib7z/LZMASDK/CPP/7zip/Archive/DllExports2.cpp
modules/lib7z/LZMASDK/CPP/7zip/Archive/IArchive.h
modules/lib7z/LZMASDK/CPP/7zip/Archive/Icons/7z.ico
modules/lib7z/LZMASDK/CPP/7zip/Archive/LzmaHandler.cpp
modules/lib7z/LZMASDK/CPP/7zip/Archive/SplitHandler.cpp
modules/lib7z/LZMASDK/CPP/7zip/Archive/StdAfx.h
modules/lib7z/LZMASDK/CPP/7zip/Archive/XzHandler.cpp
modules/lib7z/LZMASDK/CPP/7zip/Bundles/Alone7z/Alone.dsp
modules/lib7z/LZMASDK/CPP/7zip/Bundles/Alone7z/Alone.dsw
modules/lib7z/LZMASDK/CPP/7zip/Bundles/Alone7z/StdAfx.cpp
modules/lib7z/LZMASDK/CPP/7zip/Bundles/Alone7z/StdAfx.h
modules/lib7z/LZMASDK/CPP/7zip/Bundles/Alone7z/makefile
modules/lib7z/LZMASDK/CPP/7zip/Bundles/Alone7z/resource.rc
modules/lib7z/LZMASDK/CPP/7zip/Bundles/Format7zExtractR/StdAfx.cpp
modules/lib7z/LZMASDK/CPP/7zip/Bundles/Format7zExtractR/StdAfx.h
modules/lib7z/LZMASDK/CPP/7zip/Bundles/Format7zExtractR/makefile
modules/lib7z/LZMASDK/CPP/7zip/Bundles/Format7zExtractR/resource.rc
modules/lib7z/LZMASDK/CPP/7zip/Bundles/Format7zR/StdAfx.cpp
modules/lib7z/LZMASDK/CPP/7zip/Bundles/Format7zR/StdAfx.h
modules/lib7z/LZMASDK/CPP/7zip/Bundles/Format7zR/makefile
modules/lib7z/LZMASDK/CPP/7zip/Bundles/Format7zR/resource.rc
modules/lib7z/LZMASDK/CPP/7zip/Common/CWrappers.cpp
modules/lib7z/LZMASDK/CPP/7zip/Common/CWrappers.h
modules/lib7z/LZMASDK/CPP/7zip/Common/CreateCoder.cpp
modules/lib7z/LZMASDK/CPP/7zip/Common/CreateCoder.h
modules/lib7z/LZMASDK/CPP/7zip/Common/FilePathAutoRename.cpp
modules/lib7z/LZMASDK/CPP/7zip/Common/FilePathAutoRename.h
modules/lib7z/LZMASDK/CPP/7zip/Common/FileStreams.cpp
modules/lib7z/LZMASDK/CPP/7zip/Common/FileStreams.h
modules/lib7z/LZMASDK/CPP/7zip/Common/FilterCoder.cpp
modules/lib7z/LZMASDK/CPP/7zip/Common/FilterCoder.h
modules/lib7z/LZMASDK/CPP/7zip/Common/InBuffer.cpp
modules/lib7z/LZMASDK/CPP/7zip/Common/InBuffer.h
modules/lib7z/LZMASDK/CPP/7zip/Common/InOutTempBuffer.cpp
modules/lib7z/LZMASDK/CPP/7zip/Common/InOutTempBuffer.h
modules/lib7z/LZMASDK/CPP/7zip/Common/LimitedStreams.cpp
modules/lib7z/LZMASDK/CPP/7zip/Common/LimitedStreams.h
modules/lib7z/LZMASDK/CPP/7zip/Common/LockedStream.cpp
modules/lib7z/LZMASDK/CPP/7zip/Common/LockedStream.h
modules/lib7z/LZMASDK/CPP/7zip/Common/MethodId.cpp
modules/lib7z/LZMASDK/CPP/7zip/Common/MethodId.h
modules/lib7z/LZMASDK/CPP/7zip/Common/MethodProps.cpp
modules/lib7z/LZMASDK/CPP/7zip/Common/MethodProps.h
modules/lib7z/LZMASDK/CPP/7zip/Common/OffsetStream.cpp
modules/lib7z/LZMASDK/CPP/7zip/Common/OffsetStream.h
modules/lib7z/LZMASDK/CPP/7zip/Common/OutBuffer.cpp
modules/lib7z/LZMASDK/CPP/7zip/Common/OutBuffer.h
modules/lib7z/LZMASDK/CPP/7zip/Common/ProgressUtils.cpp
modules/lib7z/LZMASDK/CPP/7zip/Common/ProgressUtils.h
modules/lib7z/LZMASDK/CPP/7zip/Common/RegisterArc.h
modules/lib7z/LZMASDK/CPP/7zip/Common/RegisterCodec.h
modules/lib7z/LZMASDK/CPP/7zip/Common/StdAfx.h
modules/lib7z/LZMASDK/CPP/7zip/Common/StreamBinder.cpp
modules/lib7z/LZMASDK/CPP/7zip/Common/StreamBinder.h
modules/lib7z/LZMASDK/CPP/7zip/Common/StreamObjects.cpp
modules/lib7z/LZMASDK/CPP/7zip/Common/StreamObjects.h
modules/lib7z/LZMASDK/CPP/7zip/Common/StreamUtils.cpp
modules/lib7z/LZMASDK/CPP/7zip/Common/StreamUtils.h
modules/lib7z/LZMASDK/CPP/7zip/Common/VirtThread.cpp
modules/lib7z/LZMASDK/CPP/7zip/Common/VirtThread.h
modules/lib7z/LZMASDK/CPP/7zip/Compress/Bcj2Coder.cpp
modules/lib7z/LZMASDK/CPP/7zip/Compress/Bcj2Coder.h
modules/lib7z/LZMASDK/CPP/7zip/Compress/Bcj2Register.cpp
modules/lib7z/LZMASDK/CPP/7zip/Compress/BcjCoder.cpp
modules/lib7z/LZMASDK/CPP/7zip/Compress/BcjCoder.h
modules/lib7z/LZMASDK/CPP/7zip/Compress/BcjRegister.cpp
modules/lib7z/LZMASDK/CPP/7zip/Compress/BranchCoder.cpp
modules/lib7z/LZMASDK/CPP/7zip/Compress/BranchCoder.h
modules/lib7z/LZMASDK/CPP/7zip/Compress/BranchMisc.cpp
modules/lib7z/LZMASDK/CPP/7zip/Compress/BranchMisc.h
modules/lib7z/LZMASDK/CPP/7zip/Compress/BranchRegister.cpp
modules/lib7z/LZMASDK/CPP/7zip/Compress/ByteSwap.cpp
modules/lib7z/LZMASDK/CPP/7zip/Compress/CodecExports.cpp
modules/lib7z/LZMASDK/CPP/7zip/Compress/CopyCoder.cpp
modules/lib7z/LZMASDK/CPP/7zip/Compress/CopyCoder.h
modules/lib7z/LZMASDK/CPP/7zip/Compress/CopyRegister.cpp
modules/lib7z/LZMASDK/CPP/7zip/Compress/DeltaFilter.cpp
modules/lib7z/LZMASDK/CPP/7zip/Compress/LZMA_Alone/AloneLZMA.dsp
modules/lib7z/LZMASDK/CPP/7zip/Compress/LZMA_Alone/AloneLZMA.dsw
modules/lib7z/LZMASDK/CPP/7zip/Compress/LZMA_Alone/LzmaAlone.cpp
modules/lib7z/LZMASDK/CPP/7zip/Compress/LZMA_Alone/LzmaBench.cpp
modules/lib7z/LZMASDK/CPP/7zip/Compress/LZMA_Alone/LzmaBench.h
modules/lib7z/LZMASDK/CPP/7zip/Compress/LZMA_Alone/LzmaBenchCon.cpp
modules/lib7z/LZMASDK/CPP/7zip/Compress/LZMA_Alone/LzmaBenchCon.h
modules/lib7z/LZMASDK/CPP/7zip/Compress/LZMA_Alone/StdAfx.cpp
modules/lib7z/LZMASDK/CPP/7zip/Compress/LZMA_Alone/StdAfx.h
modules/lib7z/LZMASDK/CPP/7zip/Compress/LZMA_Alone/makefile
modules/lib7z/LZMASDK/CPP/7zip/Compress/LZMA_Alone/makefile.gcc
modules/lib7z/LZMASDK/CPP/7zip/Compress/Lzma2Decoder.cpp
modules/lib7z/LZMASDK/CPP/7zip/Compress/Lzma2Decoder.h
modules/lib7z/LZMASDK/CPP/7zip/Compress/Lzma2Encoder.cpp
modules/lib7z/LZMASDK/CPP/7zip/Compress/Lzma2Encoder.h
modules/lib7z/LZMASDK/CPP/7zip/Compress/Lzma2Register.cpp
modules/lib7z/LZMASDK/CPP/7zip/Compress/LzmaDecoder.cpp
modules/lib7z/LZMASDK/CPP/7zip/Compress/LzmaDecoder.h
modules/lib7z/LZMASDK/CPP/7zip/Compress/LzmaEncoder.cpp
modules/lib7z/LZMASDK/CPP/7zip/Compress/LzmaEncoder.h
modules/lib7z/LZMASDK/CPP/7zip/Compress/LzmaRegister.cpp
modules/lib7z/LZMASDK/CPP/7zip/Compress/RangeCoder.h
modules/lib7z/LZMASDK/CPP/7zip/Compress/RangeCoderBit.h
modules/lib7z/LZMASDK/CPP/7zip/Compress/StdAfx.h
modules/lib7z/LZMASDK/CPP/7zip/Crc.mak
modules/lib7z/LZMASDK/CPP/7zip/Crc2.mak
modules/lib7z/LZMASDK/CPP/7zip/Guid.txt
modules/lib7z/LZMASDK/CPP/7zip/ICoder.h
modules/lib7z/LZMASDK/CPP/7zip/IDecl.h
modules/lib7z/LZMASDK/CPP/7zip/IPassword.h
modules/lib7z/LZMASDK/CPP/7zip/IProgress.h
modules/lib7z/LZMASDK/CPP/7zip/IStream.h
modules/lib7z/LZMASDK/CPP/7zip/MyVersion.h
modules/lib7z/LZMASDK/CPP/7zip/MyVersionInfo.rc
modules/lib7z/LZMASDK/CPP/7zip/PropID.h
modules/lib7z/LZMASDK/CPP/7zip/SubBuild.mak
modules/lib7z/LZMASDK/CPP/7zip/UI/Client7z/Client7z.cpp
modules/lib7z/LZMASDK/CPP/7zip/UI/Client7z/Client7z.dsp
modules/lib7z/LZMASDK/CPP/7zip/UI/Client7z/Client7z.dsw
modules/lib7z/LZMASDK/CPP/7zip/UI/Client7z/StdAfx.cpp
modules/lib7z/LZMASDK/CPP/7zip/UI/Client7z/StdAfx.h
modules/lib7z/LZMASDK/CPP/7zip/UI/Client7z/makefile
modules/lib7z/LZMASDK/CPP/7zip/UI/Common/ArchiveCommandLine.cpp
modules/lib7z/LZMASDK/CPP/7zip/UI/Common/ArchiveCommandLine.h
modules/lib7z/LZMASDK/CPP/7zip/UI/Common/ArchiveExtractCallback.cpp
modules/lib7z/LZMASDK/CPP/7zip/UI/Common/ArchiveExtractCallback.h
modules/lib7z/LZMASDK/CPP/7zip/UI/Common/ArchiveName.cpp
modules/lib7z/LZMASDK/CPP/7zip/UI/Common/ArchiveName.h
modules/lib7z/LZMASDK/CPP/7zip/UI/Common/ArchiveOpenCallback.cpp
modules/lib7z/LZMASDK/CPP/7zip/UI/Common/ArchiveOpenCallback.h
modules/lib7z/LZMASDK/CPP/7zip/UI/Common/DefaultName.cpp
modules/lib7z/LZMASDK/CPP/7zip/UI/Common/DefaultName.h
modules/lib7z/LZMASDK/CPP/7zip/UI/Common/DirItem.h
modules/lib7z/LZMASDK/CPP/7zip/UI/Common/EnumDirItems.cpp
modules/lib7z/LZMASDK/CPP/7zip/UI/Common/EnumDirItems.h
modules/lib7z/LZMASDK/CPP/7zip/UI/Common/ExitCode.h
modules/lib7z/LZMASDK/CPP/7zip/UI/Common/Extract.cpp
modules/lib7z/LZMASDK/CPP/7zip/UI/Common/Extract.h
modules/lib7z/LZMASDK/CPP/7zip/UI/Common/ExtractMode.h
modules/lib7z/LZMASDK/CPP/7zip/UI/Common/ExtractingFilePath.cpp
modules/lib7z/LZMASDK/CPP/7zip/UI/Common/ExtractingFilePath.h
modules/lib7z/LZMASDK/CPP/7zip/UI/Common/IFileExtractCallback.h
modules/lib7z/LZMASDK/CPP/7zip/UI/Common/LoadCodecs.cpp
modules/lib7z/LZMASDK/CPP/7zip/UI/Common/LoadCodecs.h
modules/lib7z/LZMASDK/CPP/7zip/UI/Common/OpenArchive.cpp
modules/lib7z/LZMASDK/CPP/7zip/UI/Common/OpenArchive.h
modules/lib7z/LZMASDK/CPP/7zip/UI/Common/PropIDUtils.cpp
modules/lib7z/LZMASDK/CPP/7zip/UI/Common/PropIDUtils.h
modules/lib7z/LZMASDK/CPP/7zip/UI/Common/Property.h
modules/lib7z/LZMASDK/CPP/7zip/UI/Common/SetProperties.cpp
modules/lib7z/LZMASDK/CPP/7zip/UI/Common/SetProperties.h
modules/lib7z/LZMASDK/CPP/7zip/UI/Common/SortUtils.cpp
modules/lib7z/LZMASDK/CPP/7zip/UI/Common/SortUtils.h
modules/lib7z/LZMASDK/CPP/7zip/UI/Common/StdAfx.h
modules/lib7z/LZMASDK/CPP/7zip/UI/Common/TempFiles.cpp
modules/lib7z/LZMASDK/CPP/7zip/UI/Common/TempFiles.h
modules/lib7z/LZMASDK/CPP/7zip/UI/Common/Update.cpp
modules/lib7z/LZMASDK/CPP/7zip/UI/Common/Update.h
modules/lib7z/LZMASDK/CPP/7zip/UI/Common/UpdateAction.cpp
modules/lib7z/LZMASDK/CPP/7zip/UI/Common/UpdateAction.h
modules/lib7z/LZMASDK/CPP/7zip/UI/Common/UpdateCallback.cpp
modules/lib7z/LZMASDK/CPP/7zip/UI/Common/UpdateCallback.h
modules/lib7z/LZMASDK/CPP/7zip/UI/Common/UpdatePair.cpp
modules/lib7z/LZMASDK/CPP/7zip/UI/Common/UpdatePair.h
modules/lib7z/LZMASDK/CPP/7zip/UI/Common/UpdateProduce.cpp
modules/lib7z/LZMASDK/CPP/7zip/UI/Common/UpdateProduce.h
modules/lib7z/LZMASDK/CPP/7zip/UI/Common/WorkDir.cpp
modules/lib7z/LZMASDK/CPP/7zip/UI/Common/WorkDir.h
modules/lib7z/LZMASDK/CPP/7zip/UI/Common/ZipRegistry.h
modules/lib7z/LZMASDK/CPP/7zip/UI/Console/ConsoleClose.cpp
modules/lib7z/LZMASDK/CPP/7zip/UI/Console/ConsoleClose.h
modules/lib7z/LZMASDK/CPP/7zip/UI/Console/ExtractCallbackConsole.cpp
modules/lib7z/LZMASDK/CPP/7zip/UI/Console/ExtractCallbackConsole.h
modules/lib7z/LZMASDK/CPP/7zip/UI/Console/List.cpp
modules/lib7z/LZMASDK/CPP/7zip/UI/Console/List.h
modules/lib7z/LZMASDK/CPP/7zip/UI/Console/Main.cpp
modules/lib7z/LZMASDK/CPP/7zip/UI/Console/MainAr.cpp
modules/lib7z/LZMASDK/CPP/7zip/UI/Console/OpenCallbackConsole.cpp
modules/lib7z/LZMASDK/CPP/7zip/UI/Console/OpenCallbackConsole.h
modules/lib7z/LZMASDK/CPP/7zip/UI/Console/PercentPrinter.cpp
modules/lib7z/LZMASDK/CPP/7zip/UI/Console/PercentPrinter.h
modules/lib7z/LZMASDK/CPP/7zip/UI/Console/StdAfx.cpp
modules/lib7z/LZMASDK/CPP/7zip/UI/Console/StdAfx.h
modules/lib7z/LZMASDK/CPP/7zip/UI/Console/UpdateCallbackConsole.cpp
modules/lib7z/LZMASDK/CPP/7zip/UI/Console/UpdateCallbackConsole.h
modules/lib7z/LZMASDK/CPP/7zip/UI/Console/UserInputUtils.cpp
modules/lib7z/LZMASDK/CPP/7zip/UI/Console/UserInputUtils.h
modules/lib7z/LZMASDK/CPP/7zip/UI/Console/makefile
modules/lib7z/LZMASDK/CPP/7zip/UI/Console/resource.rc
modules/lib7z/LZMASDK/CPP/Build.mak
modules/lib7z/LZMASDK/CPP/Common/AutoPtr.h
modules/lib7z/LZMASDK/CPP/Common/Buffer.h
modules/lib7z/LZMASDK/CPP/Common/CRC.cpp
modules/lib7z/LZMASDK/CPP/Common/C_FileIO.cpp
modules/lib7z/LZMASDK/CPP/Common/C_FileIO.h
modules/lib7z/LZMASDK/CPP/Common/ComTry.h
modules/lib7z/LZMASDK/CPP/Common/CommandLineParser.cpp
modules/lib7z/LZMASDK/CPP/Common/CommandLineParser.h
modules/lib7z/LZMASDK/CPP/Common/Defs.h
modules/lib7z/LZMASDK/CPP/Common/DynamicBuffer.h
modules/lib7z/LZMASDK/CPP/Common/IntToString.cpp
modules/lib7z/LZMASDK/CPP/Common/IntToString.h
modules/lib7z/LZMASDK/CPP/Common/ListFileUtils.cpp
modules/lib7z/LZMASDK/CPP/Common/ListFileUtils.h
modules/lib7z/LZMASDK/CPP/Common/MyCom.h
modules/lib7z/LZMASDK/CPP/Common/MyException.h
modules/lib7z/LZMASDK/CPP/Common/MyGuidDef.h
modules/lib7z/LZMASDK/CPP/Common/MyInitGuid.h
modules/lib7z/LZMASDK/CPP/Common/MyString.cpp
modules/lib7z/LZMASDK/CPP/Common/MyString.h
modules/lib7z/LZMASDK/CPP/Common/MyUnknown.h
modules/lib7z/LZMASDK/CPP/Common/MyVector.cpp
modules/lib7z/LZMASDK/CPP/Common/MyVector.h
modules/lib7z/LZMASDK/CPP/Common/MyWindows.h
modules/lib7z/LZMASDK/CPP/Common/NewHandler.cpp
modules/lib7z/LZMASDK/CPP/Common/NewHandler.h
modules/lib7z/LZMASDK/CPP/Common/StdAfx.h
modules/lib7z/LZMASDK/CPP/Common/StdInStream.cpp
modules/lib7z/LZMASDK/CPP/Common/StdInStream.h
modules/lib7z/LZMASDK/CPP/Common/StdOutStream.cpp
modules/lib7z/LZMASDK/CPP/Common/StdOutStream.h
modules/lib7z/LZMASDK/CPP/Common/StringConvert.cpp
modules/lib7z/LZMASDK/CPP/Common/StringConvert.h
modules/lib7z/LZMASDK/CPP/Common/StringToInt.cpp
modules/lib7z/LZMASDK/CPP/Common/StringToInt.h
modules/lib7z/LZMASDK/CPP/Common/Types.h
modules/lib7z/LZMASDK/CPP/Common/UTFConvert.cpp
modules/lib7z/LZMASDK/CPP/Common/UTFConvert.h
modules/lib7z/LZMASDK/CPP/Common/Wildcard.cpp
modules/lib7z/LZMASDK/CPP/Common/Wildcard.h
modules/lib7z/LZMASDK/CPP/Windows/DLL.cpp
modules/lib7z/LZMASDK/CPP/Windows/DLL.h
modules/lib7z/LZMASDK/CPP/Windows/Defs.h
modules/lib7z/LZMASDK/CPP/Windows/Error.cpp
modules/lib7z/LZMASDK/CPP/Windows/Error.h
modules/lib7z/LZMASDK/CPP/Windows/FileDir.cpp
modules/lib7z/LZMASDK/CPP/Windows/FileDir.h
modules/lib7z/LZMASDK/CPP/Windows/FileFind.cpp
modules/lib7z/LZMASDK/CPP/Windows/FileFind.h
modules/lib7z/LZMASDK/CPP/Windows/FileIO.cpp
modules/lib7z/LZMASDK/CPP/Windows/FileIO.h
modules/lib7z/LZMASDK/CPP/Windows/FileMapping.cpp
modules/lib7z/LZMASDK/CPP/Windows/FileMapping.h
modules/lib7z/LZMASDK/CPP/Windows/FileName.cpp
modules/lib7z/LZMASDK/CPP/Windows/FileName.h
modules/lib7z/LZMASDK/CPP/Windows/Handle.h
modules/lib7z/LZMASDK/CPP/Windows/MemoryLock.cpp
modules/lib7z/LZMASDK/CPP/Windows/MemoryLock.h
modules/lib7z/LZMASDK/CPP/Windows/NtCheck.h
modules/lib7z/LZMASDK/CPP/Windows/PropVariant.cpp
modules/lib7z/LZMASDK/CPP/Windows/PropVariant.h
modules/lib7z/LZMASDK/CPP/Windows/PropVariantConversions.cpp
modules/lib7z/LZMASDK/CPP/Windows/PropVariantConversions.h
modules/lib7z/LZMASDK/CPP/Windows/Registry.cpp
modules/lib7z/LZMASDK/CPP/Windows/Registry.h
modules/lib7z/LZMASDK/CPP/Windows/StdAfx.h
modules/lib7z/LZMASDK/CPP/Windows/Synchronization.cpp
modules/lib7z/LZMASDK/CPP/Windows/Synchronization.h
modules/lib7z/LZMASDK/CPP/Windows/System.cpp
modules/lib7z/LZMASDK/CPP/Windows/System.h
modules/lib7z/LZMASDK/CPP/Windows/Thread.h
modules/lib7z/LZMASDK/CPP/Windows/Time.cpp
modules/lib7z/LZMASDK/CPP/Windows/Time.h
modules/lib7z/LZMASDK/CS/7zip/Common/CRC.cs
modules/lib7z/LZMASDK/CS/7zip/Common/CommandLineParser.cs
modules/lib7z/LZMASDK/CS/7zip/Common/InBuffer.cs
modules/lib7z/LZMASDK/CS/7zip/Common/OutBuffer.cs
modules/lib7z/LZMASDK/CS/7zip/Compress/LZ/IMatchFinder.cs
modules/lib7z/LZMASDK/CS/7zip/Compress/LZ/LzBinTree.cs
modules/lib7z/LZMASDK/CS/7zip/Compress/LZ/LzInWindow.cs
modules/lib7z/LZMASDK/CS/7zip/Compress/LZ/LzOutWindow.cs
modules/lib7z/LZMASDK/CS/7zip/Compress/LZMA/LzmaBase.cs
modules/lib7z/LZMASDK/CS/7zip/Compress/LZMA/LzmaDecoder.cs
modules/lib7z/LZMASDK/CS/7zip/Compress/LZMA/LzmaEncoder.cs
modules/lib7z/LZMASDK/CS/7zip/Compress/LzmaAlone/LzmaAlone.cs
modules/lib7z/LZMASDK/CS/7zip/Compress/LzmaAlone/LzmaAlone.csproj
modules/lib7z/LZMASDK/CS/7zip/Compress/LzmaAlone/LzmaAlone.sln
modules/lib7z/LZMASDK/CS/7zip/Compress/LzmaAlone/LzmaBench.cs
modules/lib7z/LZMASDK/CS/7zip/Compress/LzmaAlone/Properties/AssemblyInfo.cs
modules/lib7z/LZMASDK/CS/7zip/Compress/LzmaAlone/Properties/Resources.cs
modules/lib7z/LZMASDK/CS/7zip/Compress/LzmaAlone/Properties/Settings.cs
modules/lib7z/LZMASDK/CS/7zip/Compress/RangeCoder/RangeCoder.cs
modules/lib7z/LZMASDK/CS/7zip/Compress/RangeCoder/RangeCoderBit.cs
modules/lib7z/LZMASDK/CS/7zip/Compress/RangeCoder/RangeCoderBitTree.cs
modules/lib7z/LZMASDK/CS/7zip/ICoder.cs
modules/lib7z/LZMASDK/Java/SevenZip/CRC.java
modules/lib7z/LZMASDK/Java/SevenZip/Compression/LZ/BinTree.java
modules/lib7z/LZMASDK/Java/SevenZip/Compression/LZ/InWindow.java
modules/lib7z/LZMASDK/Java/SevenZip/Compression/LZ/OutWindow.java
modules/lib7z/LZMASDK/Java/SevenZip/Compression/LZMA/Base.java
modules/lib7z/LZMASDK/Java/SevenZip/Compression/LZMA/Decoder.java
modules/lib7z/LZMASDK/Java/SevenZip/Compression/LZMA/Encoder.java
modules/lib7z/LZMASDK/Java/SevenZip/Compression/RangeCoder/BitTreeDecoder.java
modules/lib7z/LZMASDK/Java/SevenZip/Compression/RangeCoder/BitTreeEncoder.java
modules/lib7z/LZMASDK/Java/SevenZip/Compression/RangeCoder/Decoder.java
modules/lib7z/LZMASDK/Java/SevenZip/Compression/RangeCoder/Encoder.java
modules/lib7z/LZMASDK/Java/SevenZip/ICodeProgress.java
modules/lib7z/LZMASDK/Java/SevenZip/LzmaAlone.java
modules/lib7z/LZMASDK/Java/SevenZip/LzmaBench.java
modules/lib7z/LZMASDK/Methods.txt
modules/lib7z/LZMASDK/README.mozilla
modules/lib7z/LZMASDK/history.txt
modules/lib7z/LZMASDK/lzma.txt
modules/lib7z/Makefile.in
toolkit/toolkit-makefiles.sh
toolkit/toolkit-tiers.mk
new file mode 100644
--- /dev/null
+++ b/modules/lib7z/7zLib.cpp
@@ -0,0 +1,702 @@
+/* -*- Mode: C++; c-basic-offset: 2; tab-width: 8; indent-tabs-mode: nil; -*- */
+/*****************************************************************************
+ *
+ * This 7z Library is based the 7z Client and 7z Standalone Extracting Plugin
+ * code from the LZMA SDK.
+ * It is in the public domain (see http://www.7-zip.org/sdk.html).
+ *
+ * Any copyright in these files held by contributors to the Mozilla Project is
+ * also dedicated to the Public Domain.
+ * http://creativecommons.org/licenses/publicdomain/
+ *
+ * Contributor(s):
+ *   Alex Pakhotin <alexp@mozilla.com>
+ *
+ *****************************************************************************/
+
+#include "Common/MyWindows.h"
+#include "Common/NewHandler.h"
+
+#include "Common/IntToString.h"
+#include "Common/MyInitGuid.h"
+#include "Common/StringConvert.h"
+
+#include "Windows/DLL.h"
+#include "Windows/FileDir.h"
+#include "Windows/FileFind.h"
+#include "Windows/FileName.h"
+#include "Windows/NtCheck.h"
+#include "Windows/PropVariant.h"
+#include "Windows/PropVariantConversions.h"
+
+#include "7zip/Common/FileStreams.h"
+
+#include "7zip/ICoder.h"
+#include "7zip/Archive/IArchive.h"
+
+#include "7zip/IPassword.h"
+#include "7zip/MyVersion.h"
+
+// Used for global structures initialization
+#include "../C/7zCrc.h"
+#include "7zip/Common/RegisterArc.h"
+#include "7zip/Common/RegisterCodec.h"
+#include "7zip/Archive/7z/7zHandler.h"
+#include "7zip/Compress/Bcj2Coder.h"
+#include "7zip/Compress/BcjCoder.h"
+#include "7zip/Compress/CopyCoder.h"
+#include "7zip/Compress/Lzma2Decoder.h"
+#include "7zip/Compress/LzmaDecoder.h"
+
+#include "7zLib.h"
+
+using namespace NWindows;
+
+STDAPI CreateArchiver(const GUID *classID, const GUID *iid, void **outObject);
+
+DEFINE_GUID(CLSID_CArchiveHandler,
+  0x23170F69, 0x40C1, 0x278A, 0x10, 0x00, 0x00, 0x01, 0x10, 0x00, 0x00, 0x00);
+
+DEFINE_GUID(CLSID_CFormat7z,
+  0x23170F69, 0x40C1, 0x278A, 0x10, 0x00, 0x00, 0x01, 0x10, 0x07, 0x00, 0x00);
+
+// Global static structures copied here from *Register.cpp files
+// Static global variable defined in a module didn't work when used in a library
+
+// 7z
+static IInArchive *CreateArc() { return new NArchive::N7z::CHandler; }
+static CArcInfo g_ArcInfo =
+{ L"7z", L"7z", 0, 7, {'7', 'z', 0xBC, 0xAF, 0x27, 0x1C}, 6, false, CreateArc, NULL };
+
+// BCJ2
+static void *CreateCodecBCJ2() { return (void *)(ICompressCoder2 *)(new NCompress::NBcj2::CDecoder()); }
+
+static CCodecInfo g_CodecInfoBCJ2 =
+{ CreateCodecBCJ2, NULL, 0x0303011B, L"BCJ2", 4, false };
+
+// BCJ
+static void *CreateCodecBCJ() { return (void *)(ICompressFilter *)(new CBCJ_x86_Decoder()); }
+
+static CCodecInfo g_CodecInfoBCJ =
+{ CreateCodecBCJ, NULL, 0x03030103, L"BCJ", 1, true };
+
+// Copy
+static void *CreateCodecCopy() { return (void *)(ICompressCoder *)(new NCompress::CCopyCoder); }
+
+static CCodecInfo g_CodecInfoCopy =
+{ CreateCodecCopy, CreateCodecCopy, 0x00, L"Copy", 1, false };
+
+// LZMA2
+static void *CreateCodecLZMA2() { return (void *)(ICompressCoder *)(new NCompress::NLzma2::CDecoder); }
+
+static CCodecInfo g_CodecInfoLZMA2 =
+{ CreateCodecLZMA2, NULL, 0x21, L"LZMA2", 1, false };
+
+// LZMA
+static void *CreateCodecLZMA() { return (void *)(ICompressCoder *)(new NCompress::NLzma::CDecoder); }
+
+static CCodecInfo g_CodecInfoLZMA =
+{ CreateCodecLZMA, NULL, 0x030101, L"LZMA", 1, false };
+
+// Initialize all global structures
+static void Initialize7z()
+{
+  static bool bInitialized = false;
+
+  if (bInitialized)
+    return;
+
+  CrcGenerateTable();
+
+  RegisterArc(&g_ArcInfo);
+
+  RegisterCodec(&g_CodecInfoBCJ2);
+  RegisterCodec(&g_CodecInfoBCJ);
+  RegisterCodec(&g_CodecInfoCopy);
+  RegisterCodec(&g_CodecInfoLZMA2);
+  RegisterCodec(&g_CodecInfoLZMA);
+
+  bInitialized = true;
+}
+
+#ifdef _CONSOLE
+#include "stdio.h"
+
+void PrintString(const UString &s)
+{
+  printf("%s", (LPCSTR)GetOemString(s));
+}
+
+void PrintString(const AString &s)
+{
+  printf("%s", (LPCSTR)s);
+}
+
+void PrintNewLine()
+{
+  PrintString("\n");
+}
+
+void PrintStringLn(const AString &s)
+{
+  PrintString(s);
+  PrintNewLine();
+}
+
+void PrintError(const AString &s)
+{
+  PrintNewLine();
+  PrintString(s);
+  PrintNewLine();
+}
+#else
+
+#define PrintString(s)
+#define PrintString(s)
+#define PrintNewLine()
+#define PrintStringLn(s)
+
+static UString g_sError;
+
+void PrintError(const AString &s)
+{
+  g_sError += GetUnicodeString(s) + L"\n";
+}
+
+const wchar_t* GetExtractorError()
+{
+  return (const wchar_t*)g_sError;
+}
+
+#endif
+
+static HRESULT IsArchiveItemProp(IInArchive *archive, UInt32 index, PROPID propID, bool &result)
+{
+  NCOM::CPropVariant prop;
+  RINOK(archive->GetProperty(index, propID, &prop));
+  if (prop.vt == VT_BOOL)
+    result = VARIANT_BOOLToBool(prop.boolVal);
+  else if (prop.vt == VT_EMPTY)
+    result = false;
+  else
+    return E_FAIL;
+  return S_OK;
+}
+
+static HRESULT IsArchiveItemFolder(IInArchive *archive, UInt32 index, bool &result)
+{
+  return IsArchiveItemProp(archive, index, kpidIsDir, result);
+}
+
+
+static const wchar_t *kEmptyFileAlias = L"[Content]";
+
+
+//////////////////////////////////////////////////////////////
+// Archive Open callback class
+
+class CArchiveOpenCallback:
+  public IArchiveOpenCallback,
+  public ICryptoGetTextPassword,
+  public CMyUnknownImp
+{
+public:
+  MY_UNKNOWN_IMP1(ICryptoGetTextPassword)
+
+  STDMETHOD(SetTotal)(const UInt64 *files, const UInt64 *bytes);
+  STDMETHOD(SetCompleted)(const UInt64 *files, const UInt64 *bytes);
+
+  STDMETHOD(CryptoGetTextPassword)(BSTR *password);
+
+  bool PasswordIsDefined;
+  UString Password;
+
+  CArchiveOpenCallback() : PasswordIsDefined(false) {}
+};
+
+STDMETHODIMP CArchiveOpenCallback::SetTotal(const UInt64 * /* files */, const UInt64 * /* bytes */)
+{
+  return S_OK;
+}
+
+STDMETHODIMP CArchiveOpenCallback::SetCompleted(const UInt64 * /* files */, const UInt64 * /* bytes */)
+{
+  return S_OK;
+}
+  
+STDMETHODIMP CArchiveOpenCallback::CryptoGetTextPassword(BSTR *password)
+{
+  if (!PasswordIsDefined)
+  {
+    // You can ask real password here from user
+    // Password = GetPassword(OutStream);
+    // PasswordIsDefined = true;
+    PrintError("Password is not defined");
+    return E_ABORT;
+  }
+  return StringToBstr(Password, password);
+}
+
+
+//////////////////////////////////////////////////////////////
+// Archive Extracting callback class
+
+static const wchar_t *kCantDeleteOutputFile = L"ERROR: Can not delete output file ";
+
+static const char *kTestingString    =  "Testing     ";
+static const char *kExtractingString =  "Extracting  ";
+static const char *kSkippingString   =  "Skipping    ";
+
+static const char *kUnsupportedMethod = "Unsupported Method";
+static const char *kCRCFailed = "CRC Failed";
+static const char *kDataError = "Data Error";
+static const char *kUnknownError = "Unknown Error";
+
+class CArchiveExtractCallback:
+  public IArchiveExtractCallback,
+  public ICryptoGetTextPassword,
+  public CMyUnknownImp
+{
+public:
+  MY_UNKNOWN_IMP1(ICryptoGetTextPassword)
+
+  // IProgress
+  STDMETHOD(SetTotal)(UInt64 size);
+  STDMETHOD(SetCompleted)(const UInt64 *completeValue);
+
+  // IArchiveExtractCallback
+  STDMETHOD(GetStream)(UInt32 index, ISequentialOutStream **outStream, Int32 askExtractMode);
+  STDMETHOD(PrepareOperation)(Int32 askExtractMode);
+  STDMETHOD(SetOperationResult)(Int32 resultEOperationResult);
+
+  // ICryptoGetTextPassword
+  STDMETHOD(CryptoGetTextPassword)(BSTR *aPassword);
+
+private:
+  CMyComPtr<IInArchive> _archiveHandler;
+  UString _directoryPath;  // Output directory
+  UString _filePath;       // name inside archive
+  UString _diskFilePath;   // full path to file on disk
+  bool _extractMode;
+  struct CProcessedFileInfo
+  {
+    FILETIME MTime;
+    UInt32 Attrib;
+    bool isDir;
+    bool AttribDefined;
+    bool MTimeDefined;
+  } _processedFileInfo;
+
+  COutFileStream *_outFileStreamSpec;
+  CMyComPtr<ISequentialOutStream> _outFileStream;
+
+  SzExtractProgressCallback *_progressCallback;
+  UInt32 _numItemsTotal;
+  UInt32 _numItemsExtracted;
+
+public:
+  void Init(IInArchive *archiveHandler, const UString &directoryPath, SzExtractProgressCallback *progressCallback);
+
+  UInt64 NumErrors;
+  bool PasswordIsDefined;
+  UString Password;
+
+  CArchiveExtractCallback() : PasswordIsDefined(false) {}
+};
+
+void CArchiveExtractCallback::Init(IInArchive *archiveHandler, const UString &directoryPath, SzExtractProgressCallback *progressCallback)
+{
+  NumErrors = 0;
+  _archiveHandler = archiveHandler;
+  _directoryPath = directoryPath;
+  NFile::NName::NormalizeDirPathPrefix(_directoryPath);
+  _progressCallback = progressCallback;
+  _numItemsTotal = 0;
+  _numItemsExtracted = 0;
+  archiveHandler->GetNumberOfItems(&_numItemsTotal);
+}
+
+// SetTotal and SetCompleted callback methods show progress
+// based on the input buffer, which does not really correspond
+// to the actual extraction progress.
+// Current implementation uses number of files as the progress indicator,
+// which gives better result with an archive containing a lot of files.
+STDMETHODIMP CArchiveExtractCallback::SetTotal(UInt64 /* size */)
+{
+/*
+  char s[30];
+  ConvertUInt64ToString(size, s);
+  PrintString(AString("\n--- Total: "));
+  PrintStringLn(s);
+*/
+  return S_OK;
+}
+
+STDMETHODIMP CArchiveExtractCallback::SetCompleted(const UInt64 * /* completeValue */)
+{
+/*
+  char s[30];
+  ConvertUInt64ToString(*completeValue, s);
+  PrintString(AString("\n--- Completed: "));
+  PrintStringLn(s);
+*/
+  return S_OK;
+}
+
+STDMETHODIMP CArchiveExtractCallback::GetStream(UInt32 index,
+    ISequentialOutStream **outStream, Int32 askExtractMode)
+{
+  *outStream = 0;
+  _outFileStream.Release();
+
+  {
+    // Get Name
+    NCOM::CPropVariant prop;
+    RINOK(_archiveHandler->GetProperty(index, kpidPath, &prop));
+    
+    UString fullPath;
+    if (prop.vt == VT_EMPTY)
+      fullPath = kEmptyFileAlias;
+    else
+    {
+      if (prop.vt != VT_BSTR)
+        return E_FAIL;
+      fullPath = prop.bstrVal;
+    }
+    _filePath = fullPath;
+  }
+
+  if (askExtractMode != NArchive::NExtract::NAskMode::kExtract)
+    return S_OK;
+
+  {
+    // Get Attrib
+    NCOM::CPropVariant prop;
+    RINOK(_archiveHandler->GetProperty(index, kpidAttrib, &prop));
+    if (prop.vt == VT_EMPTY)
+    {
+      _processedFileInfo.Attrib = 0;
+      _processedFileInfo.AttribDefined = false;
+    }
+    else
+    {
+      if (prop.vt != VT_UI4)
+        return E_FAIL;
+      _processedFileInfo.Attrib = prop.ulVal;
+      _processedFileInfo.AttribDefined = true;
+    }
+  }
+
+  RINOK(IsArchiveItemFolder(_archiveHandler, index, _processedFileInfo.isDir));
+
+  {
+    // Get Modified Time
+    NCOM::CPropVariant prop;
+    RINOK(_archiveHandler->GetProperty(index, kpidMTime, &prop));
+    _processedFileInfo.MTimeDefined = false;
+    switch(prop.vt)
+    {
+      case VT_EMPTY:
+        // _processedFileInfo.MTime = _utcMTimeDefault;
+        break;
+      case VT_FILETIME:
+        _processedFileInfo.MTime = prop.filetime;
+        _processedFileInfo.MTimeDefined = true;
+        break;
+      default:
+        return E_FAIL;
+    }
+
+  }
+  /*
+  {
+    // Get Size
+    NCOM::CPropVariant prop;
+    RINOK(_archiveHandler->GetProperty(index, kpidSize, &prop));
+    bool newFileSizeDefined = (prop.vt != VT_EMPTY);
+    UInt64 newFileSize;
+    if (newFileSizeDefined)
+      newFileSize = ConvertPropVariantToUInt64(prop);
+  }
+  */
+  
+  {
+    // Create folders for file
+    int slashPos = _filePath.ReverseFind(WCHAR_PATH_SEPARATOR);
+    if (slashPos >= 0)
+      NFile::NDirectory::CreateComplexDirectory(_directoryPath + _filePath.Left(slashPos));
+  }
+
+  UString fullProcessedPath = _directoryPath + _filePath;
+  _diskFilePath = fullProcessedPath;
+
+  if (_processedFileInfo.isDir)
+  {
+    NFile::NDirectory::CreateComplexDirectory(fullProcessedPath);
+  }
+  else
+  {
+    NFile::NFind::CFileInfoW fi;
+    if (fi.Find(fullProcessedPath))
+    {
+      if (!NFile::NDirectory::DeleteFileAlways(fullProcessedPath))
+      {
+        PrintString(UString(kCantDeleteOutputFile) + fullProcessedPath);
+        return E_ABORT;
+      }
+    }
+    
+    _outFileStreamSpec = new COutFileStream;
+    CMyComPtr<ISequentialOutStream> outStreamLoc(_outFileStreamSpec);
+    if (!_outFileStreamSpec->Open(fullProcessedPath, CREATE_ALWAYS))
+    {
+      PrintString((UString)L"can not open output file " + fullProcessedPath);
+      return E_ABORT;
+    }
+    _outFileStream = outStreamLoc;
+    *outStream = outStreamLoc.Detach();
+  }
+  return S_OK;
+}
+
+STDMETHODIMP CArchiveExtractCallback::PrepareOperation(Int32 askExtractMode)
+{
+  _extractMode = false;
+  switch (askExtractMode)
+  {
+    case NArchive::NExtract::NAskMode::kExtract:  _extractMode = true; break;
+  };
+  switch (askExtractMode)
+  {
+    case NArchive::NExtract::NAskMode::kExtract:  PrintString(kExtractingString); break;
+    case NArchive::NExtract::NAskMode::kTest:  PrintString(kTestingString); break;
+    case NArchive::NExtract::NAskMode::kSkip:  PrintString(kSkippingString); break;
+  };
+  PrintString(_filePath);
+  _numItemsExtracted++;
+  if (_progressCallback)
+  {
+    _progressCallback(_numItemsExtracted * 100 / _numItemsTotal);
+  }
+  return S_OK;
+}
+
+STDMETHODIMP CArchiveExtractCallback::SetOperationResult(Int32 operationResult)
+{
+  switch(operationResult)
+  {
+    case NArchive::NExtract::NOperationResult::kOK:
+      break;
+    default:
+    {
+      NumErrors++;
+      PrintString("     ");
+      switch(operationResult)
+      {
+        case NArchive::NExtract::NOperationResult::kUnSupportedMethod:
+          PrintString(kUnsupportedMethod);
+          break;
+        case NArchive::NExtract::NOperationResult::kCRCError:
+          PrintString(kCRCFailed);
+          break;
+        case NArchive::NExtract::NOperationResult::kDataError:
+          PrintString(kDataError);
+          break;
+        default:
+          PrintString(kUnknownError);
+      }
+    }
+  }
+
+  if (_outFileStream != NULL)
+  {
+    if (_processedFileInfo.MTimeDefined)
+      _outFileStreamSpec->SetMTime(&_processedFileInfo.MTime);
+    RINOK(_outFileStreamSpec->Close());
+  }
+  _outFileStream.Release();
+  if (_extractMode && _processedFileInfo.AttribDefined)
+    NFile::NDirectory::MySetFileAttributes(_diskFilePath, _processedFileInfo.Attrib);
+  PrintNewLine();
+  return S_OK;
+}
+
+
+STDMETHODIMP CArchiveExtractCallback::CryptoGetTextPassword(BSTR *password)
+{
+  if (!PasswordIsDefined)
+  {
+    // You can ask real password here from user
+    // Password = GetPassword(OutStream);
+    // PasswordIsDefined = true;
+    PrintError("Password is not defined");
+    return E_ABORT;
+  }
+  return StringToBstr(Password, password);
+}
+
+static WRes MyCreateDir(const WCHAR *name)
+{
+  return CreateDirectoryW(name, NULL) ? 0 : GetLastError();
+}
+
+static WRes CreateOutputDir(const WCHAR *outputDir)
+{
+  WRes res = SZ_OK;
+  WCHAR name[MAX_PATH];
+  size_t j;
+  if (outputDir == NULL || outputDir[0] == 0)
+    return SZ_ERROR_PARAM;
+  wcsncpy(name, outputDir, MAX_PATH-1);
+  name[MAX_PATH-1] = 0;
+
+  for (j = 1; name[j] != 0 && res == 0; j++)
+  {
+    if (name[j] == CHAR_PATH_SEPARATOR)
+    {
+      name[j] = 0;
+      res = MyCreateDir(name);
+      name[j] = CHAR_PATH_SEPARATOR;
+    }
+  }
+  if (res == 0 && name[wcslen(name) - 1] != CHAR_PATH_SEPARATOR)
+  {
+    res = MyCreateDir(name);
+  }
+  return res;
+}
+
+//////////////////////////////////////////////////////////////////////////
+// Main extract functions
+
+/**
+ * Extract 7z-archive
+ *
+ * @param archiveFileName  Name of the archive
+ * @param fileToExtract    Name of the file to extract (if NULL - extract all files)
+ * @param outputDir        Output directory for extracted files
+ * @param progressCallback Function to be called on each file - can show the progress
+ */
+int SzExtract(const WCHAR *archiveName,
+              const WCHAR *fileToExtract, const WCHAR *outputDir,
+              SzExtractProgressCallback *progressCallback)
+{
+  return SzExtractSfx(archiveName, 0, fileToExtract, outputDir, progressCallback);
+}
+
+/**
+ * Extract 7z-SFX-archive
+ *
+ * @param archiveFileName  Name of the archive
+ * @param sfxStubSize      Size of the stub at the beginning of the file before the actual archive data (could be 0)
+ * @param fileToExtract    Name of the file to extract (if NULL - extract all files)
+ * @param outputDir        Output directory for extracted files
+ * @param progressCallback Function to be called on each file to show the progress
+ */
+int SzExtractSfx(const WCHAR *archiveName, DWORD sfxStubSize,
+              const WCHAR *fileToExtract, const WCHAR *outputDir,
+              SzExtractProgressCallback *progressCallback)
+{
+  Initialize7z();
+
+  CreateOutputDir(outputDir);
+
+#ifdef _DEBUG_OUTPUT
+  PrintString("Loading archive ");
+  PrintString(archiveName);
+  PrintNewLine();
+#endif
+
+  // Extracting
+  {
+    CMyComPtr<IInArchive> archive;
+    if (CreateArchiver(&CLSID_CFormat7z, &IID_IInArchive, (void **)&archive) != S_OK)
+    {
+      PrintError("Can not get class object");
+      return SZ_ERROR_FAIL;
+    }
+
+#ifdef _DEBUG_OUTPUT
+    PrintStringLn("Created archiver");
+#endif
+    
+    CInFileStream *fileSpec = new CInFileStream;
+    CMyComPtr<IInStream> file = fileSpec;
+    
+    if (!fileSpec->Open(archiveName))
+    {
+      PrintError("Can not open archive file");
+      return SZ_ERROR_NO_ARCHIVE;
+    }
+    if (sfxStubSize > 0)
+      file->Seek(sfxStubSize, STREAM_SEEK_SET, NULL);
+
+#ifdef _DEBUG_OUTPUT
+    PrintStringLn("Opened file");
+#endif
+
+    {
+      CArchiveOpenCallback *openCallbackSpec = new CArchiveOpenCallback;
+      CMyComPtr<IArchiveOpenCallback> openCallback(openCallbackSpec);
+      openCallbackSpec->PasswordIsDefined = false;
+      // openCallbackSpec->PasswordIsDefined = true;
+      // openCallbackSpec->Password = L"1";
+      
+      if (archive->Open(file, 0, openCallback) != S_OK)
+      {
+        PrintError("Can not open archive");
+        return SZ_ERROR_NO_ARCHIVE;
+      }
+    }
+    
+#ifdef _DEBUG_OUTPUT
+    PrintStringLn("Extracting...");
+#endif
+
+    CArchiveExtractCallback *extractCallbackSpec = new CArchiveExtractCallback;
+    CMyComPtr<IArchiveExtractCallback> extractCallback(extractCallbackSpec);
+    extractCallbackSpec->Init(archive, outputDir, progressCallback);
+    extractCallbackSpec->PasswordIsDefined = false;
+    // extractCallbackSpec->PasswordIsDefined = true;
+    // extractCallbackSpec->Password = L"1";
+
+    HRESULT result = S_OK;
+    UInt32 numItems = 0;
+    archive->GetNumberOfItems(&numItems);
+    if (numItems == 0)
+    {
+	    PrintError("No files found in the archive");
+	    return SZ_ERROR_DATA;
+    }
+    if (fileToExtract)
+    {
+      // Extract one file
+      for (UInt32 i = 0; i < numItems; i++)
+      {
+        // Get name of file
+        NWindows::NCOM::CPropVariant prop;
+        archive->GetProperty(i, kpidPath, &prop);
+        UString s = ConvertPropVariantToString(prop);
+        if (wcscmp(fileToExtract, s) == 0)
+        {
+          PrintString(s);
+          PrintString("\n");
+          // Extract the current file
+          result = archive->Extract(&i, 1, false, extractCallback);
+          break;
+        }
+      }
+    }
+    else
+    {
+      // Extract all
+      result = archive->Extract(NULL, (UInt32)(Int32)(-1), false, extractCallback);
+    }
+    if (result != S_OK)
+    {
+	    PrintError("Extract Error");
+	    return SZ_ERROR_DATA;
+    }
+  }
+  return SZ_OK;
+}
new file mode 100644
--- /dev/null
+++ b/modules/lib7z/7zLib.h
@@ -0,0 +1,41 @@
+/* -*- Mode: C++; c-basic-offset: 2; tab-width: 8; indent-tabs-mode: nil; -*- */
+/*****************************************************************************
+ *
+ * This 7z Library is based the 7z Client and 7z Standalone Extracting Plugin
+ * code from the LZMA SDK.
+ * It is in the public domain (see http://www.7-zip.org/sdk.html).
+ *
+ * Any copyright in these files held by contributors to the Mozilla Project is
+ * also dedicated to the Public Domain.
+ * http://creativecommons.org/licenses/publicdomain/
+ *
+ * Contributor(s):
+ *   Alex Pakhotin <alexp@mozilla.com>
+ *
+ *****************************************************************************/
+
+#ifndef __7ZLIB_H
+#define __7ZLIB_H
+
+#define SZ_OK 0
+#define SZ_ERROR_DATA 1
+#define SZ_ERROR_PARAM 5
+#define SZ_ERROR_FAIL 11
+#define SZ_ERROR_NO_ARCHIVE 17
+
+const WCHAR* GetExtractorError();
+
+typedef void SzExtractProgressCallback(int nPercentComplete);
+
+/**
+ * Extract 7z-archive
+ */
+int SzExtract(const WCHAR *archiveName,
+              const WCHAR *fileToExtract, const WCHAR *outputDir,
+              SzExtractProgressCallback *progressCallback);
+
+int SzExtractSfx(const WCHAR *archiveName, DWORD sfxStubSize,
+              const WCHAR *fileToExtract, const WCHAR *outputDir,
+              SzExtractProgressCallback *progressCallback);
+
+#endif // __7ZLIB_H
new file mode 100644
--- /dev/null
+++ b/modules/lib7z/7zobjs.mk
@@ -0,0 +1,72 @@
+# This makefile contains a list of 7-zip files required for extraction only
+
+7ZIPCPPSRCS = \
+	7zDecode.cpp \
+	7zExtract.cpp \
+	7zFolderOutStream.cpp \
+	7zHandler.cpp \
+	7zHeader.cpp \
+	7zIn.cpp \
+	ArchiveExports.cpp \
+	CoderMixer2.cpp \
+	CoderMixer2MT.cpp \
+	CrossThreadProgress.cpp \
+	ItemNameUtils.cpp \
+	OutStreamWithCRC.cpp \
+	CreateCoder.cpp \
+	FilePathAutoRename.cpp \
+	FileStreams.cpp \
+	FilterCoder.cpp \
+	InBuffer.cpp \
+	LimitedStreams.cpp \
+	LockedStream.cpp \
+	OutBuffer.cpp \
+	ProgressUtils.cpp \
+	StreamBinder.cpp \
+	StreamObjects.cpp \
+	StreamUtils.cpp \
+	VirtThread.cpp \
+	Bcj2Coder.cpp \
+	BcjCoder.cpp \
+	BranchCoder.cpp \
+	CopyCoder.cpp \
+	Lzma2Decoder.cpp \
+	LzmaDecoder.cpp \
+	DefaultName.cpp \
+	ExtractingFilePath.cpp \
+	IntToString.cpp \
+	MyString.cpp \
+	MyVector.cpp \
+	NewHandler.cpp \
+	StringConvert.cpp \
+	Wildcard.cpp \
+	DLL.cpp \
+	Error.cpp \
+	FileDir.cpp \
+	FileFind.cpp \
+	FileIO.cpp \
+	FileName.cpp \
+	PropVariant.cpp \
+	PropVariantConversions.cpp \
+	Synchronization.cpp \
+	$(NULL)
+
+7ZIPCSRCS = \
+	7zCrc.c \
+	Alloc.c \
+	Bra86.c \
+	Lzma2Dec.c \
+	LzmaDec.c \
+	Sha256.c \
+	Threads.c \
+	$(NULL)
+
+vpath %.cpp $(7ZIPSRCDIR)/CPP/7zip/Archive
+vpath %.cpp $(7ZIPSRCDIR)/CPP/7zip/Archive/7z
+vpath %.cpp $(7ZIPSRCDIR)/CPP/7zip/Archive/Common
+vpath %.cpp $(7ZIPSRCDIR)/CPP/7zip/Common
+vpath %.cpp $(7ZIPSRCDIR)/CPP/7zip/Compress
+vpath %.cpp $(7ZIPSRCDIR)/CPP/7zip/UI/Common
+vpath %.cpp $(7ZIPSRCDIR)/CPP/Common
+vpath %.cpp $(7ZIPSRCDIR)/CPP/Windows
+vpath %.c $(7ZIPSRCDIR)/C
new file mode 100644
--- /dev/null
+++ b/modules/lib7z/LZMASDK/7zC.txt
@@ -0,0 +1,194 @@
+7z ANSI-C Decoder 4.62
+----------------------
+
+7z ANSI-C provides 7z/LZMA decoding.
+7z ANSI-C version is simplified version ported from C++ code.
+
+LZMA is default and general compression method of 7z format
+in 7-Zip compression program (www.7-zip.org). LZMA provides high 
+compression ratio and very fast decompression.
+
+
+LICENSE
+-------
+
+7z ANSI-C Decoder is part of the LZMA SDK.
+LZMA SDK is written and placed in the public domain by Igor Pavlov.
+
+Files
+---------------------
+
+7zDecode.*   - Low level 7z decoding
+7zExtract.*  - High level 7z decoding
+7zHeader.*   - .7z format constants
+7zIn.*       - .7z archive opening
+7zItem.*     - .7z structures
+7zMain.c     - Test application
+
+
+How To Use
+----------
+
+You must download 7-Zip program from www.7-zip.org.
+
+You can create .7z archive with 7z.exe or 7za.exe:
+
+  7za.exe a archive.7z *.htm -r -mx -m0fb=255
+
+If you have big number of files in archive, and you need fast extracting, 
+you can use partly-solid archives:
+  
+  7za.exe a archive.7z *.htm -ms=512K -r -mx -m0fb=255 -m0d=512K
+
+In that example 7-Zip will use 512KB solid blocks. So it needs to decompress only 
+512KB for extracting one file from such archive.
+
+
+Limitations of current version of 7z ANSI-C Decoder
+---------------------------------------------------
+
+ - It reads only "FileName", "Size", "LastWriteTime" and "CRC" information for each file in archive.
+ - It supports only LZMA and Copy (no compression) methods with BCJ or BCJ2 filters.
+ - It converts original UTF-16 Unicode file names to UTF-8 Unicode file names.
+ 
+These limitations will be fixed in future versions.
+
+
+Using 7z ANSI-C Decoder Test application:
+-----------------------------------------
+
+Usage: 7zDec <command> <archive_name>
+
+<Command>:
+  e: Extract files from archive
+  l: List contents of archive
+  t: Test integrity of archive
+
+Example: 
+
+  7zDec l archive.7z
+
+lists contents of archive.7z
+
+  7zDec e archive.7z
+
+extracts files from archive.7z to current folder.
+
+
+How to use .7z Decoder
+----------------------
+
+Memory allocation
+~~~~~~~~~~~~~~~~~
+
+7z Decoder uses two memory pools:
+1) Temporary pool
+2) Main pool
+Such scheme can allow you to avoid fragmentation of allocated blocks.
+
+
+Steps for using 7z decoder
+--------------------------
+
+Use code at 7zMain.c as example.
+
+1) Declare variables:
+  inStream                 /* implements ILookInStream interface */
+  CSzArEx db;              /* 7z archive database structure */
+  ISzAlloc allocImp;       /* memory functions for main pool */
+  ISzAlloc allocTempImp;   /* memory functions for temporary pool */
+
+2) call CrcGenerateTable(); function to initialize CRC structures.
+
+3) call SzArEx_Init(&db); function to initialize db structures.
+
+4) call SzArEx_Open(&db, inStream, &allocMain, &allocTemp) to open archive
+
+This function opens archive "inStream" and reads headers to "db".
+All items in "db" will be allocated with "allocMain" functions.
+SzArEx_Open function allocates and frees temporary structures by "allocTemp" functions.
+
+5) List items or Extract items
+
+  Listing code:
+  ~~~~~~~~~~~~~
+    {
+      UInt32 i;
+      for (i = 0; i < db.db.NumFiles; i++)
+      {
+        CFileItem *f = db.db.Files + i;
+        printf("%10d  %s\n", (int)f->Size, f->Name);
+      }
+    }
+
+  Extracting code:
+  ~~~~~~~~~~~~~~~~
+
+  SZ_RESULT SzAr_Extract(
+    CArchiveDatabaseEx *db,
+    ILookInStream *inStream, 
+    UInt32 fileIndex,         /* index of file */
+    UInt32 *blockIndex,       /* index of solid block */
+    Byte **outBuffer,         /* pointer to pointer to output buffer (allocated with allocMain) */
+    size_t *outBufferSize,    /* buffer size for output buffer */
+    size_t *offset,           /* offset of stream for required file in *outBuffer */
+    size_t *outSizeProcessed, /* size of file in *outBuffer */
+    ISzAlloc *allocMain,
+    ISzAlloc *allocTemp);
+
+  If you need to decompress more than one file, you can send these values from previous call:
+    blockIndex, 
+    outBuffer, 
+    outBufferSize,
+  You can consider "outBuffer" as cache of solid block. If your archive is solid, 
+  it will increase decompression speed.
+
+  After decompressing you must free "outBuffer":
+  allocImp.Free(outBuffer);
+
+6) call SzArEx_Free(&db, allocImp.Free) to free allocated items in "db".
+
+
+
+
+Memory requirements for .7z decoding 
+------------------------------------
+
+Memory usage for Archive opening:
+  - Temporary pool:
+     - Memory for uncompressed .7z headers
+     - some other temporary blocks
+  - Main pool:
+     - Memory for database: 
+       Estimated size of one file structures in solid archive:
+         - Size (4 or 8 Bytes)
+         - CRC32 (4 bytes)
+         - LastWriteTime (8 bytes)
+         - Some file information (4 bytes)
+         - File Name (variable length) + pointer + allocation structures
+
+Memory usage for archive Decompressing:
+  - Temporary pool:
+     - Memory for LZMA decompressing structures
+  - Main pool:
+     - Memory for decompressed solid block
+     - Memory for temprorary buffers, if BCJ2 fileter is used. Usually these 
+       temprorary buffers can be about 15% of solid block size. 
+  
+
+7z Decoder doesn't allocate memory for compressed blocks. 
+Instead of this, you must allocate buffer with desired 
+size before calling 7z Decoder. Use 7zMain.c as example.
+
+
+Defines
+-------
+
+_SZ_ALLOC_DEBUG   - define it if you want to debug alloc/free operations to stderr.
+
+
+---
+
+http://www.7-zip.org
+http://www.7-zip.org/sdk.html
+http://www.7-zip.org/support.html
new file mode 100644
--- /dev/null
+++ b/modules/lib7z/LZMASDK/7zFormat.txt
@@ -0,0 +1,471 @@
+7z Format description (2.30 Beta 25)
+-----------------------------------
+
+This file contains description of 7z archive format. 
+7z archive can contain files compressed with any method.
+See "Methods.txt" for description for defined compressing methods.
+
+
+Format structure Overview
+-------------------------
+
+Some fields can be optional.
+
+Archive structure
+~~~~~~~~~~~~~~~~~  
+SignatureHeader
+[PackedStreams]
+[PackedStreamsForHeaders]
+[
+  Header 
+  or 
+  {
+    Packed Header
+    HeaderInfo
+  }
+]
+
+
+
+Header structure
+~~~~~~~~~~~~~~~~  
+{
+  ArchiveProperties
+  AdditionalStreams
+  {
+    PackInfo
+    {
+      PackPos
+      NumPackStreams
+      Sizes[NumPackStreams]
+      CRCs[NumPackStreams]
+    }
+    CodersInfo
+    {
+      NumFolders
+      Folders[NumFolders]
+      {
+        NumCoders
+        CodersInfo[NumCoders]
+        {
+          ID
+          NumInStreams;
+          NumOutStreams;
+          PropertiesSize
+          Properties[PropertiesSize]
+        }
+        NumBindPairs
+        BindPairsInfo[NumBindPairs]
+        {
+          InIndex;
+          OutIndex;
+        }
+        PackedIndices
+      }
+      UnPackSize[Folders][Folders.NumOutstreams]
+      CRCs[NumFolders]
+    }
+    SubStreamsInfo
+    {
+      NumUnPackStreamsInFolders[NumFolders];
+      UnPackSizes[]
+      CRCs[]
+    }
+  }
+  MainStreamsInfo
+  {
+    (Same as in AdditionalStreams)
+  }
+  FilesInfo
+  {
+    NumFiles
+    Properties[]
+    {
+      ID
+      Size
+      Data
+    }
+  }
+}
+
+HeaderInfo structure
+~~~~~~~~~~~~~~~~~~~~
+{
+  (Same as in AdditionalStreams)
+}
+
+
+
+Notes about Notation and encoding
+---------------------------------
+
+7z uses little endian encoding.
+
+7z archive format has optional headers that are marked as
+[]
+Header
+[]
+
+REAL_UINT64 means real UINT64.
+
+UINT64 means real UINT64 encoded with the following scheme:
+
+  Size of encoding sequence depends from first byte:
+  First_Byte  Extra_Bytes        Value
+  (binary)   
+  0xxxxxxx               : ( xxxxxxx           )
+  10xxxxxx    BYTE y[1]  : (  xxxxxx << (8 * 1)) + y
+  110xxxxx    BYTE y[2]  : (   xxxxx << (8 * 2)) + y
+  ...
+  1111110x    BYTE y[6]  : (       x << (8 * 6)) + y
+  11111110    BYTE y[7]  :                         y
+  11111111    BYTE y[8]  :                         y
+
+
+
+Property IDs
+------------
+
+0x00 = kEnd,
+
+0x01 = kHeader,
+
+0x02 = kArchiveProperties,
+    
+0x03 = kAdditionalStreamsInfo,
+0x04 = kMainStreamsInfo,
+0x05 = kFilesInfo,
+    
+0x06 = kPackInfo,
+0x07 = kUnPackInfo,
+0x08 = kSubStreamsInfo,
+
+0x09 = kSize,
+0x0A = kCRC,
+
+0x0B = kFolder,
+
+0x0C = kCodersUnPackSize,
+0x0D = kNumUnPackStream,
+
+0x0E = kEmptyStream,
+0x0F = kEmptyFile,
+0x10 = kAnti,
+
+0x11 = kName,
+0x12 = kCreationTime,
+0x13 = kLastAccessTime,
+0x14 = kLastWriteTime,
+0x15 = kWinAttributes,
+0x16 = kComment,
+
+0x17 = kEncodedHeader,
+
+
+7z format headers
+-----------------
+
+SignatureHeader
+~~~~~~~~~~~~~~~
+  BYTE kSignature[6] = {'7', 'z', 0xBC, 0xAF, 0x27, 0x1C};
+
+  ArchiveVersion
+  {
+    BYTE Major;   // now = 0
+    BYTE Minor;   // now = 2
+  };
+
+  UINT32 StartHeaderCRC;
+
+  StartHeader
+  {
+    REAL_UINT64 NextHeaderOffset
+    REAL_UINT64 NextHeaderSize
+    UINT32 NextHeaderCRC
+  }
+
+
+...........................
+
+
+ArchiveProperties
+~~~~~~~~~~~~~~~~~
+BYTE NID::kArchiveProperties (0x02)
+for (;;)
+{
+  BYTE PropertyType;
+  if (aType == 0)
+    break;
+  UINT64 PropertySize;
+  BYTE PropertyData[PropertySize];
+}
+
+
+Digests (NumStreams)
+~~~~~~~~~~~~~~~~~~~~~
+  BYTE AllAreDefined
+  if (AllAreDefined == 0)
+  {
+    for(NumStreams)
+      BIT Defined
+  }
+  UINT32 CRCs[NumDefined]
+
+
+PackInfo
+~~~~~~~~~~~~
+  BYTE NID::kPackInfo  (0x06)
+  UINT64 PackPos
+  UINT64 NumPackStreams
+
+  []
+  BYTE NID::kSize    (0x09)
+  UINT64 PackSizes[NumPackStreams]
+  []
+
+  []
+  BYTE NID::kCRC      (0x0A)
+  PackStreamDigests[NumPackStreams]
+  []
+
+  BYTE NID::kEnd
+
+
+Folder
+~~~~~~
+  UINT64 NumCoders;
+  for (NumCoders)
+  {
+    BYTE 
+    {
+      0:3 DecompressionMethod.IDSize
+      4:
+        0 - IsSimple
+        1 - Is not simple
+      5:
+        0 - No Attributes
+        1 - There Are Attributes
+      7:
+        0 - Last Method in Alternative_Method_List
+        1 - There are more alternative methods
+    } 
+    BYTE DecompressionMethod.ID[DecompressionMethod.IDSize]
+    if (!IsSimple)
+    {
+      UINT64 NumInStreams;
+      UINT64 NumOutStreams;
+    }
+    if (DecompressionMethod[0] != 0)
+    {
+      UINT64 PropertiesSize
+      BYTE Properties[PropertiesSize]
+    }
+  }
+    
+  NumBindPairs = NumOutStreamsTotal - 1;
+
+  for (NumBindPairs)
+  {
+    UINT64 InIndex;
+    UINT64 OutIndex;
+  }
+
+  NumPackedStreams = NumInStreamsTotal - NumBindPairs;
+  if (NumPackedStreams > 1)
+    for(NumPackedStreams)
+    {
+      UINT64 Index;
+    };
+
+
+
+
+Coders Info
+~~~~~~~~~~~
+
+  BYTE NID::kUnPackInfo  (0x07)
+
+
+  BYTE NID::kFolder  (0x0B)
+  UINT64 NumFolders
+  BYTE External
+  switch(External)
+  {
+    case 0:
+      Folders[NumFolders]
+    case 1:
+      UINT64 DataStreamIndex
+  }
+
+
+  BYTE ID::kCodersUnPackSize  (0x0C)
+  for(Folders)
+    for(Folder.NumOutStreams)
+     UINT64 UnPackSize;
+
+
+  []
+  BYTE NID::kCRC   (0x0A)
+  UnPackDigests[NumFolders]
+  []
+
+  
+
+  BYTE NID::kEnd
+
+
+
+SubStreams Info
+~~~~~~~~~~~~~~
+  BYTE NID::kSubStreamsInfo; (0x08)
+
+  []
+  BYTE NID::kNumUnPackStream; (0x0D)
+  UINT64 NumUnPackStreamsInFolders[NumFolders];
+  []
+
+
+  []
+  BYTE NID::kSize  (0x09)
+  UINT64 UnPackSizes[]
+  []
+
+
+  []
+  BYTE NID::kCRC  (0x0A)
+  Digests[Number of streams with unknown CRC]
+  []
+
+  
+  BYTE NID::kEnd
+
+
+Streams Info
+~~~~~~~~~~~~
+
+  []
+  PackInfo
+  []
+
+
+  []
+  CodersInfo
+  []
+
+
+  []
+  SubStreamsInfo
+  []
+
+  BYTE NID::kEnd
+
+
+FilesInfo
+~~~~~~~~~
+  BYTE NID::kFilesInfo;  (0x05)
+  UINT64 NumFiles
+
+  for (;;)
+  {
+    BYTE PropertyType;
+    if (aType == 0)
+      break;
+
+    UINT64 Size;
+
+    switch(PropertyType)
+    {
+      kEmptyStream:   (0x0E)
+        for(NumFiles)
+          BIT IsEmptyStream
+
+      kEmptyFile:     (0x0F)
+        for(EmptyStreams)
+          BIT IsEmptyFile
+
+      kAnti:          (0x10)
+        for(EmptyStreams)
+          BIT IsAntiFile
+      
+      case kCreationTime:   (0x12)
+      case kLastAccessTime: (0x13)
+      case kLastWriteTime:  (0x14)
+        BYTE AllAreDefined
+        if (AllAreDefined == 0)
+        {
+          for(NumFiles)
+            BIT TimeDefined
+        }
+        BYTE External;
+        if(External != 0)
+          UINT64 DataIndex
+        []
+        for(Definded Items)
+          UINT32 Time
+        []
+      
+      kNames:     (0x11)
+        BYTE External;
+        if(External != 0)
+          UINT64 DataIndex
+        []
+        for(Files)
+        {
+          wchar_t Names[NameSize];
+          wchar_t 0;
+        }
+        []
+
+      kAttributes:  (0x15)
+        BYTE AllAreDefined
+        if (AllAreDefined == 0)
+        {
+          for(NumFiles)
+            BIT AttributesAreDefined
+        }
+        BYTE External;
+        if(External != 0)
+          UINT64 DataIndex
+        []
+        for(Definded Attributes)
+          UINT32 Attributes
+        []
+    }
+  }
+
+
+Header
+~~~~~~
+  BYTE NID::kHeader (0x01)
+
+  []
+  ArchiveProperties
+  []
+
+  []
+  BYTE NID::kAdditionalStreamsInfo; (0x03)
+  StreamsInfo
+  []
+
+  []
+  BYTE NID::kMainStreamsInfo;    (0x04)
+  StreamsInfo
+  []
+
+  []
+  FilesInfo
+  []
+
+  BYTE NID::kEnd
+
+
+HeaderInfo
+~~~~~~~~~~
+  []
+  BYTE NID::kEncodedHeader; (0x17)
+  StreamsInfo for Encoded Header
+  []
+
+
+---
+End of document
new file mode 100644
--- /dev/null
+++ b/modules/lib7z/LZMASDK/Asm/x64/7zCrcT8U.asm
@@ -0,0 +1,101 @@
+.code
+
+
+
+
+CRC1b macro
+    movzx EDX, BYTE PTR [RSI]
+    inc RSI
+    movzx EBX, AL
+    xor EDX, EBX
+    shr EAX, 8
+    xor EAX, [RDI + RDX * 4]
+    dec R8
+endm
+
+
+
+
+align 16
+CrcUpdateT8 PROC
+
+    push RBX
+    push RSI
+    push RDI
+    push RBP
+
+    mov EAX, ECX
+    mov RSI, RDX
+    mov RDI, R9
+
+
+    test R8, R8
+    jz sl_end
+  sl:
+    test RSI, 7
+    jz sl_end
+    CRC1b
+    jnz sl
+  sl_end:
+
+    cmp R8, 16
+    jb crc_end
+    mov R9, R8
+    and R8, 7
+    add R8, 8
+    sub R9, R8
+            
+    add R9, RSI
+    xor EAX, [RSI]
+    mov EBX, [RSI + 4]
+    movzx ECX, BL
+    align 16
+  main_loop:
+    mov EDX, [RDI + RCX*4 + 0C00h]
+    movzx EBP, BH
+    xor EDX, [RDI + RBP*4 + 0800h]
+    shr EBX, 16
+    movzx ECX, BL
+    xor EDX, [RSI + 8]
+    xor EDX, [RDI + RCX*4 + 0400h]
+    movzx ECX, AL
+    movzx EBP, BH
+    xor EDX, [RDI + RBP*4 + 0000h]
+
+    mov EBX, [RSI + 12]
+
+    xor EDX, [RDI + RCX*4 + 01C00h]
+    movzx EBP, AH
+    shr EAX, 16
+    movzx ECX, AL
+    xor EDX, [RDI + RBP*4 + 01800h]
+    movzx EBP, AH
+    mov EAX, [RDI + RCX*4 + 01400h]
+    add RSI, 8
+    xor EAX, [RDI + RBP*4 + 01000h]
+    movzx ECX, BL
+    xor EAX,EDX
+
+    cmp RSI, R9
+    jne main_loop
+    xor EAX, [RSI]
+
+
+  
+  crc_end:
+
+    test R8, R8
+    jz fl_end
+  fl:
+    CRC1b
+    jnz fl
+  fl_end:
+
+    pop RBP
+    pop RDI
+    pop RSI
+    pop RBX
+    ret
+CrcUpdateT8 ENDP
+
+end
new file mode 100644
--- /dev/null
+++ b/modules/lib7z/LZMASDK/Asm/x86/7zCrcT8U.asm
@@ -0,0 +1,101 @@
+.386
+.model flat
+
+_TEXT$00   SEGMENT PARA PUBLIC 'CODE'
+
+CRC1b macro
+    movzx EDX, BYTE PTR [ESI]
+    inc ESI
+    movzx EBX, AL
+    xor EDX, EBX
+    shr EAX, 8
+    xor EAX, [EBP + EDX * 4]
+    dec EDI
+endm
+
+data_size equ (4 + 4*4)
+crc_table equ (data_size + 4)
+
+align 16
+public @CrcUpdateT8@16
+@CrcUpdateT8@16:
+    push EBX
+    push ESI
+    push EDI
+    push EBP
+
+    mov EAX, ECX
+    mov ESI, EDX
+    mov EDI, [ESP + data_size]
+    mov EBP, [ESP + crc_table]
+
+    test EDI, EDI
+    jz sl_end
+  sl:
+    test ESI, 7
+    jz sl_end
+    CRC1b
+    jnz sl
+  sl_end:
+
+    cmp EDI, 16
+    jb crc_end
+    mov [ESP + data_size], EDI
+    sub EDI, 8
+    and EDI, NOT 7
+    sub [ESP + data_size], EDI
+
+    add EDI, ESI
+    xor EAX, [ESI]
+    mov EBX, [ESI + 4]
+    movzx ECX, BL
+    align 16
+  main_loop:
+    mov EDX, [EBP + ECX*4 + 0C00h]
+    movzx ECX, BH
+    xor EDX, [EBP + ECX*4 + 0800h]
+    shr EBX, 16
+    movzx ECX, BL
+    xor EDX, [EBP + ECX*4 + 0400h]
+    xor EDX, [ESI + 8]
+    movzx ECX, AL
+    movzx EBX, BH
+    xor EDX, [EBP + EBX*4 + 0000h]
+
+    mov EBX, [ESI + 12]
+
+    xor EDX, [EBP + ECX*4 + 01C00h]
+    movzx ECX, AH
+    add ESI, 8
+    shr EAX, 16
+    xor EDX, [EBP + ECX*4 + 01800h]
+    movzx ECX, AL
+    xor EDX, [EBP + ECX*4 + 01400h]
+    movzx ECX, AH
+    mov EAX, [EBP + ECX*4 + 01000h]
+    movzx ECX, BL
+    xor EAX,EDX
+
+    cmp ESI, EDI
+    jne main_loop
+    xor EAX, [ESI]
+
+    mov EDI, [ESP + data_size]
+
+  crc_end:
+
+    test EDI, EDI
+    jz fl_end
+  fl:
+    CRC1b
+    jnz fl
+  fl_end:
+
+    pop EBP
+    pop EDI
+    pop ESI
+    pop EBX
+    ret 8
+
+
+end
new file mode 100644
--- /dev/null
+++ b/modules/lib7z/LZMASDK/C/7z.h
@@ -0,0 +1,201 @@
+/* 7z.h -- 7z interface
+2009-08-17 : Igor Pavlov : Public domain */
+
+#ifndef __7Z_H
+#define __7Z_H
+
+#include "7zBuf.h"
+
+EXTERN_C_BEGIN
+
+#define k7zStartHeaderSize 0x20
+#define k7zSignatureSize 6
+extern Byte k7zSignature[k7zSignatureSize];
+#define k7zMajorVersion 0
+
+enum EIdEnum
+{
+  k7zIdEnd,
+  k7zIdHeader,
+  k7zIdArchiveProperties,
+  k7zIdAdditionalStreamsInfo,
+  k7zIdMainStreamsInfo,
+  k7zIdFilesInfo,
+  k7zIdPackInfo,
+  k7zIdUnpackInfo,
+  k7zIdSubStreamsInfo,
+  k7zIdSize,
+  k7zIdCRC,
+  k7zIdFolder,
+  k7zIdCodersUnpackSize,
+  k7zIdNumUnpackStream,
+  k7zIdEmptyStream,
+  k7zIdEmptyFile,
+  k7zIdAnti,
+  k7zIdName,
+  k7zIdCTime,
+  k7zIdATime,
+  k7zIdMTime,
+  k7zIdWinAttributes,
+  k7zIdComment,
+  k7zIdEncodedHeader,
+  k7zIdStartPos,
+  k7zIdDummy
+};
+
+typedef struct
+{
+  UInt32 NumInStreams;
+  UInt32 NumOutStreams;
+  UInt64 MethodID;
+  CBuf Props;
+} CSzCoderInfo;
+
+void SzCoderInfo_Init(CSzCoderInfo *p);
+void SzCoderInfo_Free(CSzCoderInfo *p, ISzAlloc *alloc);
+
+typedef struct
+{
+  UInt32 InIndex;
+  UInt32 OutIndex;
+} CSzBindPair;
+
+typedef struct
+{
+  CSzCoderInfo *Coders;
+  CSzBindPair *BindPairs;
+  UInt32 *PackStreams;
+  UInt64 *UnpackSizes;
+  UInt32 NumCoders;
+  UInt32 NumBindPairs;
+  UInt32 NumPackStreams;
+  int UnpackCRCDefined;
+  UInt32 UnpackCRC;
+
+  UInt32 NumUnpackStreams;
+} CSzFolder;
+
+void SzFolder_Init(CSzFolder *p);
+UInt64 SzFolder_GetUnpackSize(CSzFolder *p);
+int SzFolder_FindBindPairForInStream(CSzFolder *p, UInt32 inStreamIndex);
+UInt32 SzFolder_GetNumOutStreams(CSzFolder *p);
+UInt64 SzFolder_GetUnpackSize(CSzFolder *p);
+
+SRes SzFolder_Decode(const CSzFolder *folder, const UInt64 *packSizes,
+    ILookInStream *stream, UInt64 startPos,
+    Byte *outBuffer, size_t outSize, ISzAlloc *allocMain);
+
+typedef struct
+{
+  UInt32 Low;
+  UInt32 High;
+} CNtfsFileTime;
+
+typedef struct
+{
+  CNtfsFileTime MTime;
+  UInt64 Size;
+  UInt32 Crc;
+  Byte HasStream;
+  Byte IsDir;
+  Byte IsAnti;
+  Byte CrcDefined;
+  Byte MTimeDefined;
+} CSzFileItem;
+
+void SzFile_Init(CSzFileItem *p);
+
+typedef struct
+{
+  UInt64 *PackSizes;
+  Byte *PackCRCsDefined;
+  UInt32 *PackCRCs;
+  CSzFolder *Folders;
+  CSzFileItem *Files;
+  UInt32 NumPackStreams;
+  UInt32 NumFolders;
+  UInt32 NumFiles;
+} CSzAr;
+
+void SzAr_Init(CSzAr *p);
+void SzAr_Free(CSzAr *p, ISzAlloc *alloc);
+
+
+/*
+  SzExtract extracts file from archive
+
+  *outBuffer must be 0 before first call for each new archive.
+
+  Extracting cache:
+    If you need to decompress more than one file, you can send
+    these values from previous call:
+      *blockIndex,
+      *outBuffer,
+      *outBufferSize
+    You can consider "*outBuffer" as cache of solid block. If your archive is solid,
+    it will increase decompression speed.
+  
+    If you use external function, you can declare these 3 cache variables
+    (blockIndex, outBuffer, outBufferSize) as static in that external function.
+    
+    Free *outBuffer and set *outBuffer to 0, if you want to flush cache.
+*/
+
+typedef struct
+{
+  CSzAr db;
+  
+  UInt64 startPosAfterHeader;
+  UInt64 dataPos;
+
+  UInt32 *FolderStartPackStreamIndex;
+  UInt64 *PackStreamStartPositions;
+  UInt32 *FolderStartFileIndex;
+  UInt32 *FileIndexToFolderIndexMap;
+
+  size_t *FileNameOffsets; /* in 2-byte steps */
+  CBuf FileNames;  /* UTF-16-LE */
+} CSzArEx;
+
+void SzArEx_Init(CSzArEx *p);
+void SzArEx_Free(CSzArEx *p, ISzAlloc *alloc);
+UInt64 SzArEx_GetFolderStreamPos(const CSzArEx *p, UInt32 folderIndex, UInt32 indexInFolder);
+int SzArEx_GetFolderFullPackSize(const CSzArEx *p, UInt32 folderIndex, UInt64 *resSize);
+
+/*
+if dest == NULL, the return value specifies the required size of the buffer,
+  in 16-bit characters, including the null-terminating character.
+if dest != NULL, the return value specifies the number of 16-bit characters that
+  are written to the dest, including the null-terminating character. */
+
+size_t SzArEx_GetFileNameUtf16(const CSzArEx *p, size_t fileIndex, UInt16 *dest);
+
+SRes SzArEx_Extract(
+    const CSzArEx *db,
+    ILookInStream *inStream,
+    UInt32 fileIndex,         /* index of file */
+    UInt32 *blockIndex,       /* index of solid block */
+    Byte **outBuffer,         /* pointer to pointer to output buffer (allocated with allocMain) */
+    size_t *outBufferSize,    /* buffer size for output buffer */
+    size_t *offset,           /* offset of stream for required file in *outBuffer */
+    size_t *outSizeProcessed, /* size of file in *outBuffer */
+    ISzAlloc *allocMain,
+    ISzAlloc *allocTemp);
+
+
+/*
+SzArEx_Open Errors:
+SZ_ERROR_NO_ARCHIVE
+SZ_ERROR_ARCHIVE
+SZ_ERROR_UNSUPPORTED
+SZ_ERROR_MEM
+SZ_ERROR_CRC
+SZ_ERROR_INPUT_EOF
+SZ_ERROR_FAIL
+*/
+
+SRes SzArEx_Open(CSzArEx *p, ILookInStream *inStream, ISzAlloc *allocMain, ISzAlloc *allocTemp);
+
+EXTERN_C_END
+
+#endif
new file mode 100644
--- /dev/null
+++ b/modules/lib7z/LZMASDK/C/7zBuf.c
@@ -0,0 +1,36 @@
+/* 7zBuf.c -- Byte Buffer
+2008-03-28
+Igor Pavlov
+Public domain */
+
+#include "7zBuf.h"
+
+void Buf_Init(CBuf *p)
+{
+  p->data = 0;
+  p->size = 0;
+}
+
+int Buf_Create(CBuf *p, size_t size, ISzAlloc *alloc)
+{
+  p->size = 0;
+  if (size == 0)
+  {
+    p->data = 0;
+    return 1;
+  }
+  p->data = (Byte *)alloc->Alloc(alloc, size);
+  if (p->data != 0)
+  {
+    p->size = size;
+    return 1;
+  }
+  return 0;
+}
+
+void Buf_Free(CBuf *p, ISzAlloc *alloc)
+{
+  alloc->Free(alloc, p->data);
+  p->data = 0;
+  p->size = 0;
+}
new file mode 100644
--- /dev/null
+++ b/modules/lib7z/LZMASDK/C/7zBuf.h
@@ -0,0 +1,39 @@
+/* 7zBuf.h -- Byte Buffer
+2009-02-07 : Igor Pavlov : Public domain */
+
+#ifndef __7Z_BUF_H
+#define __7Z_BUF_H
+
+#include "Types.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+typedef struct
+{
+  Byte *data;
+  size_t size;
+} CBuf;
+
+void Buf_Init(CBuf *p);
+int Buf_Create(CBuf *p, size_t size, ISzAlloc *alloc);
+void Buf_Free(CBuf *p, ISzAlloc *alloc);
+
+typedef struct
+{
+  Byte *data;
+  size_t size;
+  size_t pos;
+} CDynBuf;
+
+void DynBuf_Construct(CDynBuf *p);
+void DynBuf_SeekToBeg(CDynBuf *p);
+int DynBuf_Write(CDynBuf *p, const Byte *buf, size_t size, ISzAlloc *alloc);
+void DynBuf_Free(CDynBuf *p, ISzAlloc *alloc);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
new file mode 100644
--- /dev/null
+++ b/modules/lib7z/LZMASDK/C/7zBuf2.c
@@ -0,0 +1,45 @@
+/* 7zBuf2.c -- Byte Buffer
+2008-10-04 : Igor Pavlov : Public domain */
+
+#include <string.h>
+#include "7zBuf.h"
+
+void DynBuf_Construct(CDynBuf *p)
+{
+  p->data = 0;
+  p->size = 0;
+  p->pos = 0;
+}
+
+void DynBuf_SeekToBeg(CDynBuf *p)
+{
+  p->pos = 0;
+}
+
+int DynBuf_Write(CDynBuf *p, const Byte *buf, size_t size, ISzAlloc *alloc)
+{
+  if (size > p->size - p->pos)
+  {
+    size_t newSize = p->pos + size;
+    Byte *data;
+    newSize += newSize / 4;
+    data = (Byte *)alloc->Alloc(alloc, newSize);
+    if (data == 0)
+      return 0;
+    p->size = newSize;
+    memcpy(data, p->data, p->pos);
+    alloc->Free(alloc, p->data);
+    p->data = data;
+  }
+  memcpy(p->data + p->pos, buf, size);
+  p->pos += size;
+  return 1;
+}
+
+void DynBuf_Free(CDynBuf *p, ISzAlloc *alloc)
+{
+  alloc->Free(alloc, p->data);
+  p->data = 0;
+  p->size = 0;
+  p->pos = 0;
+}
new file mode 100644
--- /dev/null
+++ b/modules/lib7z/LZMASDK/C/7zCrc.c
@@ -0,0 +1,35 @@
+/* 7zCrc.c -- CRC32 calculation
+2008-08-05
+Igor Pavlov
+Public domain */
+
+#include "7zCrc.h"
+
+#define kCrcPoly 0xEDB88320
+UInt32 g_CrcTable[256];
+
+void MY_FAST_CALL CrcGenerateTable(void)
+{
+  UInt32 i;
+  for (i = 0; i < 256; i++)
+  {
+    UInt32 r = i;
+    int j;
+    for (j = 0; j < 8; j++)
+      r = (r >> 1) ^ (kCrcPoly & ~((r & 1) - 1));
+    g_CrcTable[i] = r;
+  }
+}
+
+UInt32 MY_FAST_CALL CrcUpdate(UInt32 v, const void *data, size_t size)
+{
+  const Byte *p = (const Byte *)data;
+  for (; size > 0 ; size--, p++)
+    v = CRC_UPDATE_BYTE(v, *p);
+  return v;
+}
+
+UInt32 MY_FAST_CALL CrcCalc(const void *data, size_t size)
+{
+  return CrcUpdate(CRC_INIT_VAL, data, size) ^ 0xFFFFFFFF;
+}
new file mode 100644
--- /dev/null
+++ b/modules/lib7z/LZMASDK/C/7zCrc.h
@@ -0,0 +1,30 @@
+/* 7zCrc.h -- CRC32 calculation
+2009-02-07 : Igor Pavlov : Public domain */
+
+#ifndef __7Z_CRC_H
+#define __7Z_CRC_H
+
+#include <stddef.h>
+
+#include "Types.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+extern UInt32 g_CrcTable[];
+
+void MY_FAST_CALL CrcGenerateTable(void);
+
+#define CRC_INIT_VAL 0xFFFFFFFF
+#define CRC_GET_DIGEST(crc) ((crc) ^ 0xFFFFFFFF)
+#define CRC_UPDATE_BYTE(crc, b) (g_CrcTable[((crc) ^ (b)) & 0xFF] ^ ((crc) >> 8))
+
+UInt32 MY_FAST_CALL CrcUpdate(UInt32 crc, const void *data, size_t size);
+UInt32 MY_FAST_CALL CrcCalc(const void *data, size_t size);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
new file mode 100644
--- /dev/null
+++ b/modules/lib7z/LZMASDK/C/7zCrcT8.c
@@ -0,0 +1,43 @@
+/* 7zCrcT8.c -- CRC32 calculation with 8 tables
+2008-03-19
+Igor Pavlov
+Public domain */
+
+#include "7zCrc.h"
+
+#define kCrcPoly 0xEDB88320
+#define CRC_NUM_TABLES 8
+
+UInt32 g_CrcTable[256 * CRC_NUM_TABLES];
+
+void MY_FAST_CALL CrcGenerateTable()
+{
+  UInt32 i;
+  for (i = 0; i < 256; i++)
+  {
+    UInt32 r = i;
+    int j;
+    for (j = 0; j < 8; j++)
+      r = (r >> 1) ^ (kCrcPoly & ~((r & 1) - 1));
+    g_CrcTable[i] = r;
+  }
+  #if CRC_NUM_TABLES > 1
+  for (; i < 256 * CRC_NUM_TABLES; i++)
+  {
+    UInt32 r = g_CrcTable[i - 256];
+    g_CrcTable[i] = g_CrcTable[r & 0xFF] ^ (r >> 8);
+  }
+  #endif
+}
+
+UInt32 MY_FAST_CALL CrcUpdateT8(UInt32 v, const void *data, size_t size, const UInt32 *table);
+
+UInt32 MY_FAST_CALL CrcUpdate(UInt32 v, const void *data, size_t size)
+{
+  return CrcUpdateT8(v, data, size, g_CrcTable);
+}
+
+UInt32 MY_FAST_CALL CrcCalc(const void *data, size_t size)
+{
+  return CrcUpdateT8(CRC_INIT_VAL, data, size, g_CrcTable) ^ 0xFFFFFFFF;
+}
new file mode 100644
--- /dev/null
+++ b/modules/lib7z/LZMASDK/C/7zDec.c
@@ -0,0 +1,310 @@
+/* 7zDec.c -- Decoding from 7z folder
+2009-08-16 : Igor Pavlov : Public domain */
+
+#include <string.h>
+
+#include "7z.h"
+
+#include "Bcj2.h"
+#include "Bra.h"
+#include "LzmaDec.h"
+#include "Lzma2Dec.h"
+
+#define k_Copy 0
+#define k_LZMA2 0x21
+#define k_LZMA 0x30101
+#define k_BCJ 0x03030103
+#define k_BCJ2 0x0303011B
+
+static SRes SzDecodeLzma(CSzCoderInfo *coder, UInt64 inSize, ILookInStream *inStream,
+    Byte *outBuffer, SizeT outSize, ISzAlloc *allocMain)
+{
+  CLzmaDec state;
+  SRes res = SZ_OK;
+
+  LzmaDec_Construct(&state);
+  RINOK(LzmaDec_AllocateProbs(&state, coder->Props.data, (unsigned)coder->Props.size, allocMain));
+  state.dic = outBuffer;
+  state.dicBufSize = outSize;
+  LzmaDec_Init(&state);
+
+  for (;;)
+  {
+    Byte *inBuf = NULL;
+    size_t lookahead = (1 << 18);
+    if (lookahead > inSize)
+      lookahead = (size_t)inSize;
+    res = inStream->Look((void *)inStream, (void **)&inBuf, &lookahead);
+    if (res != SZ_OK)
+      break;
+
+    {
+      SizeT inProcessed = (SizeT)lookahead, dicPos = state.dicPos;
+      ELzmaStatus status;
+      res = LzmaDec_DecodeToDic(&state, outSize, inBuf, &inProcessed, LZMA_FINISH_END, &status);
+      lookahead -= inProcessed;
+      inSize -= inProcessed;
+      if (res != SZ_OK)
+        break;
+      if (state.dicPos == state.dicBufSize || (inProcessed == 0 && dicPos == state.dicPos))
+      {
+        if (state.dicBufSize != outSize || lookahead != 0 ||
+            (status != LZMA_STATUS_FINISHED_WITH_MARK &&
+             status != LZMA_STATUS_MAYBE_FINISHED_WITHOUT_MARK))
+          res = SZ_ERROR_DATA;
+        break;
+      }
+      res = inStream->Skip((void *)inStream, inProcessed);
+      if (res != SZ_OK)
+        break;
+    }
+  }
+
+  LzmaDec_FreeProbs(&state, allocMain);
+  return res;
+}
+
+static SRes SzDecodeLzma2(CSzCoderInfo *coder, UInt64 inSize, ILookInStream *inStream,
+    Byte *outBuffer, SizeT outSize, ISzAlloc *allocMain)
+{
+  CLzma2Dec state;
+  SRes res = SZ_OK;
+
+  Lzma2Dec_Construct(&state);
+  if (coder->Props.size != 1)
+    return SZ_ERROR_DATA;
+  RINOK(Lzma2Dec_AllocateProbs(&state, coder->Props.data[0], allocMain));
+  state.decoder.dic = outBuffer;
+  state.decoder.dicBufSize = outSize;
+  Lzma2Dec_Init(&state);
+
+  for (;;)
+  {
+    Byte *inBuf = NULL;
+    size_t lookahead = (1 << 18);
+    if (lookahead > inSize)
+      lookahead = (size_t)inSize;
+    res = inStream->Look((void *)inStream, (void **)&inBuf, &lookahead);
+    if (res != SZ_OK)
+      break;
+
+    {
+      SizeT inProcessed = (SizeT)lookahead, dicPos = state.decoder.dicPos;
+      ELzmaStatus status;
+      res = Lzma2Dec_DecodeToDic(&state, outSize, inBuf, &inProcessed, LZMA_FINISH_END, &status);
+      lookahead -= inProcessed;
+      inSize -= inProcessed;
+      if (res != SZ_OK)
+        break;
+      if (state.decoder.dicPos == state.decoder.dicBufSize || (inProcessed == 0 && dicPos == state.decoder.dicPos))
+      {
+        if (state.decoder.dicBufSize != outSize || lookahead != 0 ||
+            (status != LZMA_STATUS_FINISHED_WITH_MARK))
+          res = SZ_ERROR_DATA;
+        break;
+      }
+      res = inStream->Skip((void *)inStream, inProcessed);
+      if (res != SZ_OK)
+        break;
+    }
+  }
+
+  Lzma2Dec_FreeProbs(&state, allocMain);
+  return res;
+}
+
+static SRes SzDecodeCopy(UInt64 inSize, ILookInStream *inStream, Byte *outBuffer)
+{
+  while (inSize > 0)
+  {
+    void *inBuf;
+    size_t curSize = (1 << 18);
+    if (curSize > inSize)
+      curSize = (size_t)inSize;
+    RINOK(inStream->Look((void *)inStream, (void **)&inBuf, &curSize));
+    if (curSize == 0)
+      return SZ_ERROR_INPUT_EOF;
+    memcpy(outBuffer, inBuf, curSize);
+    outBuffer += curSize;
+    inSize -= curSize;
+    RINOK(inStream->Skip((void *)inStream, curSize));
+  }
+  return SZ_OK;
+}
+
+#define IS_UNSUPPORTED_METHOD(m) ((m) != k_Copy && (m) != k_LZMA && (m) != k_LZMA2)
+#define IS_UNSUPPORTED_CODER(c) (IS_UNSUPPORTED_METHOD(c.MethodID) || c.NumInStreams != 1 || c.NumOutStreams != 1)
+#define IS_NO_BCJ(c) (c.MethodID != k_BCJ || c.NumInStreams != 1 || c.NumOutStreams != 1)
+#define IS_NO_BCJ2(c) (c.MethodID != k_BCJ2 || c.NumInStreams != 4 || c.NumOutStreams != 1)
+
+static SRes CheckSupportedFolder(const CSzFolder *f)
+{
+  if (f->NumCoders < 1 || f->NumCoders > 4)
+    return SZ_ERROR_UNSUPPORTED;
+  if (IS_UNSUPPORTED_CODER(f->Coders[0]))
+    return SZ_ERROR_UNSUPPORTED;
+  if (f->NumCoders == 1)
+  {
+    if (f->NumPackStreams != 1 || f->PackStreams[0] != 0 || f->NumBindPairs != 0)
+      return SZ_ERROR_UNSUPPORTED;
+    return SZ_OK;
+  }
+  if (f->NumCoders == 2)
+  {
+    if (IS_NO_BCJ(f->Coders[1]) ||
+        f->NumPackStreams != 1 || f->PackStreams[0] != 0 ||
+        f->NumBindPairs != 1 ||
+        f->BindPairs[0].InIndex != 1 || f->BindPairs[0].OutIndex != 0)
+      return SZ_ERROR_UNSUPPORTED;
+    return SZ_OK;
+  }
+  if (f->NumCoders == 4)
+  {
+    if (IS_UNSUPPORTED_CODER(f->Coders[1]) ||
+        IS_UNSUPPORTED_CODER(f->Coders[2]) ||
+        IS_NO_BCJ2(f->Coders[3]))
+      return SZ_ERROR_UNSUPPORTED;
+    if (f->NumPackStreams != 4 ||
+        f->PackStreams[0] != 2 ||
+        f->PackStreams[1] != 6 ||
+        f->PackStreams[2] != 1 ||
+        f->PackStreams[3] != 0 ||
+        f->NumBindPairs != 3 ||
+        f->BindPairs[0].InIndex != 5 || f->BindPairs[0].OutIndex != 0 ||
+        f->BindPairs[1].InIndex != 4 || f->BindPairs[1].OutIndex != 1 ||
+        f->BindPairs[2].InIndex != 3 || f->BindPairs[2].OutIndex != 2)
+      return SZ_ERROR_UNSUPPORTED;
+    return SZ_OK;
+  }
+  return SZ_ERROR_UNSUPPORTED;
+}
+
+static UInt64 GetSum(const UInt64 *values, UInt32 index)
+{
+  UInt64 sum = 0;
+  UInt32 i;
+  for (i = 0; i < index; i++)
+    sum += values[i];
+  return sum;
+}
+
+static SRes SzFolder_Decode2(const CSzFolder *folder, const UInt64 *packSizes,
+    ILookInStream *inStream, UInt64 startPos,
+    Byte *outBuffer, SizeT outSize, ISzAlloc *allocMain,
+    Byte *tempBuf[])
+{
+  UInt32 ci;
+  SizeT tempSizes[3] = { 0, 0, 0};
+  SizeT tempSize3 = 0;
+  Byte *tempBuf3 = 0;
+
+  RINOK(CheckSupportedFolder(folder));
+
+  for (ci = 0; ci < folder->NumCoders; ci++)
+  {
+    CSzCoderInfo *coder = &folder->Coders[ci];
+
+    if (coder->MethodID == k_Copy || coder->MethodID == k_LZMA || coder->MethodID == k_LZMA2)
+    {
+      UInt32 si = 0;
+      UInt64 offset;
+      UInt64 inSize;
+      Byte *outBufCur = outBuffer;
+      SizeT outSizeCur = outSize;
+      if (folder->NumCoders == 4)
+      {
+        UInt32 indices[] = { 3, 2, 0 };
+        UInt64 unpackSize = folder->UnpackSizes[ci];
+        si = indices[ci];
+        if (ci < 2)
+        {
+          Byte *temp;
+          outSizeCur = (SizeT)unpackSize;
+          if (outSizeCur != unpackSize)
+            return SZ_ERROR_MEM;
+          temp = (Byte *)IAlloc_Alloc(allocMain, outSizeCur);
+          if (temp == 0 && outSizeCur != 0)
+            return SZ_ERROR_MEM;
+          outBufCur = tempBuf[1 - ci] = temp;
+          tempSizes[1 - ci] = outSizeCur;
+        }
+        else if (ci == 2)
+        {
+          if (unpackSize > outSize) /* check it */
+            return SZ_ERROR_PARAM;
+          tempBuf3 = outBufCur = outBuffer + (outSize - (size_t)unpackSize);
+          tempSize3 = outSizeCur = (SizeT)unpackSize;
+        }
+        else
+          return SZ_ERROR_UNSUPPORTED;
+      }
+      offset = GetSum(packSizes, si);
+      inSize = packSizes[si];
+      RINOK(LookInStream_SeekTo(inStream, startPos + offset));
+
+      if (coder->MethodID == k_Copy)
+      {
+        if (inSize != outSizeCur) /* check it */
+          return SZ_ERROR_DATA;
+        RINOK(SzDecodeCopy(inSize, inStream, outBufCur));
+      }
+      else if (coder->MethodID == k_LZMA)
+      {
+        RINOK(SzDecodeLzma(coder, inSize, inStream, outBufCur, outSizeCur, allocMain));
+      }
+      else
+      {
+        RINOK(SzDecodeLzma2(coder, inSize, inStream, outBufCur, outSizeCur, allocMain));
+      }
+    }
+    else if (coder->MethodID == k_BCJ)
+    {
+      UInt32 state;
+      if (ci != 1)
+        return SZ_ERROR_UNSUPPORTED;
+      x86_Convert_Init(state);
+      x86_Convert(outBuffer, outSize, 0, &state, 0);
+    }
+    else if (coder->MethodID == k_BCJ2)
+    {
+      UInt64 offset = GetSum(packSizes, 1);
+      UInt64 s3Size = packSizes[1];
+      SRes res;
+      if (ci != 3)
+        return SZ_ERROR_UNSUPPORTED;
+      RINOK(LookInStream_SeekTo(inStream, startPos + offset));
+      tempSizes[2] = (SizeT)s3Size;
+      if (tempSizes[2] != s3Size)
+        return SZ_ERROR_MEM;
+      tempBuf[2] = (Byte *)IAlloc_Alloc(allocMain, tempSizes[2]);
+      if (tempBuf[2] == 0 && tempSizes[2] != 0)
+        return SZ_ERROR_MEM;
+      res = SzDecodeCopy(s3Size, inStream, tempBuf[2]);
+      RINOK(res)
+
+      res = Bcj2_Decode(
+          tempBuf3, tempSize3,
+          tempBuf[0], tempSizes[0],
+          tempBuf[1], tempSizes[1],
+          tempBuf[2], tempSizes[2],
+          outBuffer, outSize);
+      RINOK(res)
+    }
+    else
+      return SZ_ERROR_UNSUPPORTED;
+  }
+  return SZ_OK;
+}
+
+SRes SzFolder_Decode(const CSzFolder *folder, const UInt64 *packSizes,
+    ILookInStream *inStream, UInt64 startPos,
+    Byte *outBuffer, size_t outSize, ISzAlloc *allocMain)
+{
+  Byte *tempBuf[3] = { 0, 0, 0};
+  int i;
+  SRes res = SzFolder_Decode2(folder, packSizes, inStream, startPos,
+      outBuffer, (SizeT)outSize, allocMain, tempBuf);
+  for (i = 0; i < 3; i++)
+    IAlloc_Free(allocMain, tempBuf[i]);
+  return res;
+}
new file mode 100644
--- /dev/null
+++ b/modules/lib7z/LZMASDK/C/7zFile.c
@@ -0,0 +1,277 @@
+/* 7zFile.c -- File IO
+2009-08-16 : Igor Pavlov : Public domain */
+
+#include "7zFile.h"
+
+#ifndef USE_WINDOWS_FILE
+
+#include <errno.h>
+
+#endif
+
+#ifdef USE_WINDOWS_FILE
+
+/*
+   ReadFile and WriteFile functions in Windows have BUG:
+   If you Read or Write 64MB or more (probably min_failure_size = 64MB - 32KB + 1)
+   from/to Network file, it returns ERROR_NO_SYSTEM_RESOURCES
+   (Insufficient system resources exist to complete the requested service).
+   Probably in some version of Windows there are problems with other sizes:
+   for 32 MB (maybe also for 16 MB).
+   And message can be "Network connection was lost"
+*/
+
+#define kChunkSizeMax (1 << 22)
+
+#endif
+
+void File_Construct(CSzFile *p)
+{
+  #ifdef USE_WINDOWS_FILE
+  p->handle = INVALID_HANDLE_VALUE;
+  #else
+  p->file = NULL;
+  #endif
+}
+
+static WRes File_Open(CSzFile *p, const char *name, int writeMode)
+{
+  #ifdef USE_WINDOWS_FILE
+  p->handle = CreateFileA(name,
+      writeMode ? GENERIC_WRITE : GENERIC_READ,
+      FILE_SHARE_READ, NULL,
+      writeMode ? CREATE_ALWAYS : OPEN_EXISTING,
+      FILE_ATTRIBUTE_NORMAL, NULL);
+  return (p->handle != INVALID_HANDLE_VALUE) ? 0 : GetLastError();
+  #else
+  p->file = fopen(name, writeMode ? "wb+" : "rb");
+  return (p->file != 0) ? 0 : errno;
+  #endif
+}
+
+WRes InFile_Open(CSzFile *p, const char *name) { return File_Open(p, name, 0); }
+WRes OutFile_Open(CSzFile *p, const char *name) { return File_Open(p, name, 1); }
+
+#ifdef USE_WINDOWS_FILE
+static WRes File_OpenW(CSzFile *p, const WCHAR *name, int writeMode)
+{
+  p->handle = CreateFileW(name,
+      writeMode ? GENERIC_WRITE : GENERIC_READ,
+      FILE_SHARE_READ, NULL,
+      writeMode ? CREATE_ALWAYS : OPEN_EXISTING,
+      FILE_ATTRIBUTE_NORMAL, NULL);
+  return (p->handle != INVALID_HANDLE_VALUE) ? 0 : GetLastError();
+}
+WRes InFile_OpenW(CSzFile *p, const WCHAR *name) { return File_OpenW(p, name, 0); }
+WRes OutFile_OpenW(CSzFile *p, const WCHAR *name) { return File_OpenW(p, name, 1); }
+#endif
+
+WRes File_Close(CSzFile *p)
+{
+  #ifdef USE_WINDOWS_FILE
+  if (p->handle != INVALID_HANDLE_VALUE)
+  {
+    if (!CloseHandle(p->handle))
+      return GetLastError();
+    p->handle = INVALID_HANDLE_VALUE;
+  }
+  #else
+  if (p->file != NULL)
+  {
+    int res = fclose(p->file);
+    if (res != 0)
+      return res;
+    p->file = NULL;
+  }
+  #endif
+  return 0;
+}
+
+WRes File_Read(CSzFile *p, void *data, size_t *size)
+{
+  size_t originalSize = *size;
+  if (originalSize == 0)
+    return 0;
+
+  #ifdef USE_WINDOWS_FILE
+
+  *size = 0;
+  do
+  {
+    DWORD curSize = (originalSize > kChunkSizeMax) ? kChunkSizeMax : (DWORD)originalSize;
+    DWORD processed = 0;
+    BOOL res = ReadFile(p->handle, data, curSize, &processed, NULL);
+    data = (void *)((Byte *)data + processed);
+    originalSize -= processed;
+    *size += processed;
+    if (!res)
+      return GetLastError();
+    if (processed == 0)
+      break;
+  }
+  while (originalSize > 0);
+  return 0;
+
+  #else
+  
+  *size = fread(data, 1, originalSize, p->file);
+  if (*size == originalSize)
+    return 0;
+  return ferror(p->file);
+  
+  #endif
+}
+
+WRes File_Write(CSzFile *p, const void *data, size_t *size)
+{
+  size_t originalSize = *size;
+  if (originalSize == 0)
+    return 0;
+  
+  #ifdef USE_WINDOWS_FILE
+
+  *size = 0;
+  do
+  {
+    DWORD curSize = (originalSize > kChunkSizeMax) ? kChunkSizeMax : (DWORD)originalSize;
+    DWORD processed = 0;
+    BOOL res = WriteFile(p->handle, data, curSize, &processed, NULL);
+    data = (void *)((Byte *)data + processed);
+    originalSize -= processed;
+    *size += processed;
+    if (!res)
+      return GetLastError();
+    if (processed == 0)
+      break;
+  }
+  while (originalSize > 0);
+  return 0;
+
+  #else
+
+  *size = fwrite(data, 1, originalSize, p->file);
+  if (*size == originalSize)
+    return 0;
+  return ferror(p->file);
+  
+  #endif
+}
+
+WRes File_Seek(CSzFile *p, Int64 *pos, ESzSeek origin)
+{
+  #ifdef USE_WINDOWS_FILE
+
+  LARGE_INTEGER value;
+  DWORD moveMethod;
+  value.LowPart = (DWORD)*pos;
+  value.HighPart = (LONG)((UInt64)*pos >> 16 >> 16); /* for case when UInt64 is 32-bit only */
+  switch (origin)
+  {
+    case SZ_SEEK_SET: moveMethod = FILE_BEGIN; break;
+    case SZ_SEEK_CUR: moveMethod = FILE_CURRENT; break;
+    case SZ_SEEK_END: moveMethod = FILE_END; break;
+    default: return ERROR_INVALID_PARAMETER;
+  }
+  value.LowPart = SetFilePointer(p->handle, value.LowPart, &value.HighPart, moveMethod);
+  if (value.LowPart == 0xFFFFFFFF)
+  {
+    WRes res = GetLastError();
+    if (res != NO_ERROR)
+      return res;
+  }
+  *pos = ((Int64)value.HighPart << 32) | value.LowPart;
+  return 0;
+
+  #else
+  
+  int moveMethod;
+  int res;
+  switch (origin)
+  {
+    case SZ_SEEK_SET: moveMethod = SEEK_SET; break;
+    case SZ_SEEK_CUR: moveMethod = SEEK_CUR; break;
+    case SZ_SEEK_END: moveMethod = SEEK_END; break;
+    default: return 1;
+  }
+  res = fseek(p->file, (long)*pos, moveMethod);
+  *pos = ftell(p->file);
+  return res;
+  
+  #endif
+}
+
+WRes File_GetLength(CSzFile *p, UInt64 *length)
+{
+  #ifdef USE_WINDOWS_FILE
+  
+  DWORD sizeHigh;
+  DWORD sizeLow = GetFileSize(p->handle, &sizeHigh);
+  if (sizeLow == 0xFFFFFFFF)
+  {
+    DWORD res = GetLastError();
+    if (res != NO_ERROR)
+      return res;
+  }
+  *length = (((UInt64)sizeHigh) << 32) + sizeLow;
+  return 0;
+  
+  #else
+  
+  long pos = ftell(p->file);
+  int res = fseek(p->file, 0, SEEK_END);
+  *length = ftell(p->file);
+  fseek(p->file, pos, SEEK_SET);
+  return res;
+  
+  #endif
+}
+
+
+/* ---------- FileSeqInStream ---------- */
+
+static SRes FileSeqInStream_Read(void *pp, void *buf, size_t *size)
+{
+  CFileSeqInStream *p = (CFileSeqInStream *)pp;
+  return File_Read(&p->file, buf, size) == 0 ? SZ_OK : SZ_ERROR_READ;
+}
+
+void FileSeqInStream_CreateVTable(CFileSeqInStream *p)
+{
+  p->s.Read = FileSeqInStream_Read;
+}
+
+
+/* ---------- FileInStream ---------- */
+
+static SRes FileInStream_Read(void *pp, void *buf, size_t *size)
+{
+  CFileInStream *p = (CFileInStream *)pp;
+  return (File_Read(&p->file, buf, size) == 0) ? SZ_OK : SZ_ERROR_READ;
+}
+
+static SRes FileInStream_Seek(void *pp, Int64 *pos, ESzSeek origin)
+{
+  CFileInStream *p = (CFileInStream *)pp;
+  return File_Seek(&p->file, pos, origin);
+}
+
+void FileInStream_CreateVTable(CFileInStream *p)
+{
+  p->s.Read = FileInStream_Read;
+  p->s.Seek = FileInStream_Seek;
+}
+
+
+/* ---------- FileOutStream ---------- */
+
+static size_t FileOutStream_Write(void *pp, const void *data, size_t size)
+{
+  CFileOutStream *p = (CFileOutStream *)pp;
+  File_Write(&p->file, data, &size);
+  return size;
+}
+
+void FileOutStream_CreateVTable(CFileOutStream *p)
+{
+  p->s.Write = FileOutStream_Write;
+}
new file mode 100644
--- /dev/null
+++ b/modules/lib7z/LZMASDK/C/7zFile.h
@@ -0,0 +1,81 @@
+/* 7zFile.h -- File IO
+2009-08-16 : Igor Pavlov : Public domain */
+
+#ifndef __7Z_FILE_H
+#define __7Z_FILE_H
+
+#ifdef _WIN32
+#define USE_WINDOWS_FILE
+#endif
+
+#ifdef USE_WINDOWS_FILE
+#include <windows.h>
+#else
+#include <stdio.h>
+#endif
+
+#include "Types.h"
+
+EXTERN_C_BEGIN
+
+/* ---------- File ---------- */
+
+typedef struct
+{
+  #ifdef USE_WINDOWS_FILE
+  HANDLE handle;
+  #else
+  FILE *file;
+  #endif
+} CSzFile;
+
+void File_Construct(CSzFile *p);
+WRes InFile_Open(CSzFile *p, const char *name);
+WRes OutFile_Open(CSzFile *p, const char *name);
+#ifdef USE_WINDOWS_FILE
+WRes InFile_OpenW(CSzFile *p, const WCHAR *name);
+WRes OutFile_OpenW(CSzFile *p, const WCHAR *name);
+#endif
+WRes File_Close(CSzFile *p);
+
+/* reads max(*size, remain file's size) bytes */
+WRes File_Read(CSzFile *p, void *data, size_t *size);
+
+/* writes *size bytes */
+WRes File_Write(CSzFile *p, const void *data, size_t *size);
+
+WRes File_Seek(CSzFile *p, Int64 *pos, ESzSeek origin);
+WRes File_GetLength(CSzFile *p, UInt64 *length);
+
+
+/* ---------- FileInStream ---------- */
+
+typedef struct
+{
+  ISeqInStream s;
+  CSzFile file;
+} CFileSeqInStream;
+
+void FileSeqInStream_CreateVTable(CFileSeqInStream *p);
+
+
+typedef struct
+{
+  ISeekInStream s;
+  CSzFile file;
+} CFileInStream;
+
+void FileInStream_CreateVTable(CFileInStream *p);
+
+
+typedef struct
+{
+  ISeqOutStream s;
+  CSzFile file;
+} CFileOutStream;
+
+void FileOutStream_CreateVTable(CFileOutStream *p);
+
+EXTERN_C_END
+
+#endif
new file mode 100644
--- /dev/null
+++ b/modules/lib7z/LZMASDK/C/7zIn.c
@@ -0,0 +1,1376 @@
+/* 7zIn.c -- 7z Input functions
+2009-08-17 : Igor Pavlov : Public domain */
+
+#include <string.h>
+
+#include "7z.h"
+#include "7zCrc.h"
+#include "CpuArch.h"
+
+Byte k7zSignature[k7zSignatureSize] = {'7', 'z', 0xBC, 0xAF, 0x27, 0x1C};
+
+#define RINOM(x) { if ((x) == 0) return SZ_ERROR_MEM; }
+
+#define NUM_FOLDER_CODERS_MAX 32
+#define NUM_CODER_STREAMS_MAX 32
+
+void SzCoderInfo_Init(CSzCoderInfo *p)
+{
+  Buf_Init(&p->Props);
+}
+
+void SzCoderInfo_Free(CSzCoderInfo *p, ISzAlloc *alloc)
+{
+  Buf_Free(&p->Props, alloc);
+  SzCoderInfo_Init(p);
+}
+
+void SzFolder_Init(CSzFolder *p)
+{
+  p->Coders = 0;
+  p->BindPairs = 0;
+  p->PackStreams = 0;
+  p->UnpackSizes = 0;
+  p->NumCoders = 0;
+  p->NumBindPairs = 0;
+  p->NumPackStreams = 0;
+  p->UnpackCRCDefined = 0;
+  p->UnpackCRC = 0;
+  p->NumUnpackStreams = 0;
+}
+
+void SzFolder_Free(CSzFolder *p, ISzAlloc *alloc)
+{
+  UInt32 i;
+  if (p->Coders)
+    for (i = 0; i < p->NumCoders; i++)
+      SzCoderInfo_Free(&p->Coders[i], alloc);
+  IAlloc_Free(alloc, p->Coders);
+  IAlloc_Free(alloc, p->BindPairs);
+  IAlloc_Free(alloc, p->PackStreams);
+  IAlloc_Free(alloc, p->UnpackSizes);
+  SzFolder_Init(p);
+}
+
+UInt32 SzFolder_GetNumOutStreams(CSzFolder *p)
+{
+  UInt32 result = 0;
+  UInt32 i;
+  for (i = 0; i < p->NumCoders; i++)
+    result += p->Coders[i].NumOutStreams;
+  return result;
+}
+
+int SzFolder_FindBindPairForInStream(CSzFolder *p, UInt32 inStreamIndex)
+{
+  UInt32 i;
+  for (i = 0; i < p->NumBindPairs; i++)
+    if (p->BindPairs[i].InIndex == inStreamIndex)
+      return i;
+  return -1;
+}
+
+
+int SzFolder_FindBindPairForOutStream(CSzFolder *p, UInt32 outStreamIndex)
+{
+  UInt32 i;
+  for (i = 0; i < p->NumBindPairs; i++)
+    if (p->BindPairs[i].OutIndex == outStreamIndex)
+      return i;
+  return -1;
+}
+
+UInt64 SzFolder_GetUnpackSize(CSzFolder *p)
+{
+  int i = (int)SzFolder_GetNumOutStreams(p);
+  if (i == 0)
+    return 0;
+  for (i--; i >= 0; i--)
+    if (SzFolder_FindBindPairForOutStream(p, i) < 0)
+      return p->UnpackSizes[i];
+  /* throw 1; */
+  return 0;
+}
+
+void SzFile_Init(CSzFileItem *p)
+{
+  p->HasStream = 1;
+  p->IsDir = 0;
+  p->IsAnti = 0;
+  p->CrcDefined = 0;
+  p->MTimeDefined = 0;
+}
+
+void SzAr_Init(CSzAr *p)
+{
+  p->PackSizes = 0;
+  p->PackCRCsDefined = 0;
+  p->PackCRCs = 0;
+  p->Folders = 0;
+  p->Files = 0;
+  p->NumPackStreams = 0;
+  p->NumFolders = 0;
+  p->NumFiles = 0;
+}
+
+void SzAr_Free(CSzAr *p, ISzAlloc *alloc)
+{
+  UInt32 i;
+  if (p->Folders)
+    for (i = 0; i < p->NumFolders; i++)
+      SzFolder_Free(&p->Folders[i], alloc);
+
+  IAlloc_Free(alloc, p->PackSizes);
+  IAlloc_Free(alloc, p->PackCRCsDefined);
+  IAlloc_Free(alloc, p->PackCRCs);
+  IAlloc_Free(alloc, p->Folders);
+  IAlloc_Free(alloc, p->Files);
+  SzAr_Init(p);
+}
+
+
+void SzArEx_Init(CSzArEx *p)
+{
+  SzAr_Init(&p->db);
+  p->FolderStartPackStreamIndex = 0;
+  p->PackStreamStartPositions = 0;
+  p->FolderStartFileIndex = 0;
+  p->FileIndexToFolderIndexMap = 0;
+  p->FileNameOffsets = 0;
+  Buf_Init(&p->FileNames);
+}
+
+void SzArEx_Free(CSzArEx *p, ISzAlloc *alloc)
+{
+  IAlloc_Free(alloc, p->FolderStartPackStreamIndex);
+  IAlloc_Free(alloc, p->PackStreamStartPositions);
+  IAlloc_Free(alloc, p->FolderStartFileIndex);
+  IAlloc_Free(alloc, p->FileIndexToFolderIndexMap);
+
+  IAlloc_Free(alloc, p->FileNameOffsets);
+  Buf_Free(&p->FileNames, alloc);
+
+  SzAr_Free(&p->db, alloc);
+  SzArEx_Init(p);
+}
+
+/*
+UInt64 GetFolderPackStreamSize(int folderIndex, int streamIndex) const
+{
+  return PackSizes[FolderStartPackStreamIndex[folderIndex] + streamIndex];
+}
+
+UInt64 GetFilePackSize(int fileIndex) const
+{
+  int folderIndex = FileIndexToFolderIndexMap[fileIndex];
+  if (folderIndex >= 0)
+  {
+    const CSzFolder &folderInfo = Folders[folderIndex];
+    if (FolderStartFileIndex[folderIndex] == fileIndex)
+    return GetFolderFullPackSize(folderIndex);
+  }
+  return 0;
+}
+*/
+
+#define MY_ALLOC(T, p, size, alloc) { if ((size) == 0) p = 0; else \
+  if ((p = (T *)IAlloc_Alloc(alloc, (size) * sizeof(T))) == 0) return SZ_ERROR_MEM; }
+
+static SRes SzArEx_Fill(CSzArEx *p, ISzAlloc *alloc)
+{
+  UInt32 startPos = 0;
+  UInt64 startPosSize = 0;
+  UInt32 i;
+  UInt32 folderIndex = 0;
+  UInt32 indexInFolder = 0;
+  MY_ALLOC(UInt32, p->FolderStartPackStreamIndex, p->db.NumFolders, alloc);
+  for (i = 0; i < p->db.NumFolders; i++)
+  {
+    p->FolderStartPackStreamIndex[i] = startPos;
+    startPos += p->db.Folders[i].NumPackStreams;
+  }
+
+  MY_ALLOC(UInt64, p->PackStreamStartPositions, p->db.NumPackStreams, alloc);
+
+  for (i = 0; i < p->db.NumPackStreams; i++)
+  {
+    p->PackStreamStartPositions[i] = startPosSize;
+    startPosSize += p->db.PackSizes[i];
+  }
+
+  MY_ALLOC(UInt32, p->FolderStartFileIndex, p->db.NumFolders, alloc);
+  MY_ALLOC(UInt32, p->FileIndexToFolderIndexMap, p->db.NumFiles, alloc);
+
+  for (i = 0; i < p->db.NumFiles; i++)
+  {
+    CSzFileItem *file = p->db.Files + i;
+    int emptyStream = !file->HasStream;
+    if (emptyStream && indexInFolder == 0)
+    {
+      p->FileIndexToFolderIndexMap[i] = (UInt32)-1;
+      continue;
+    }
+    if (indexInFolder == 0)
+    {
+      /*
+      v3.13 incorrectly worked with empty folders
+      v4.07: Loop for skipping empty folders
+      */
+      for (;;)
+      {
+        if (folderIndex >= p->db.NumFolders)
+          return SZ_ERROR_ARCHIVE;
+        p->FolderStartFileIndex[folderIndex] = i;
+        if (p->db.Folders[folderIndex].NumUnpackStreams != 0)
+          break;
+        folderIndex++;
+      }
+    }
+    p->FileIndexToFolderIndexMap[i] = folderIndex;
+    if (emptyStream)
+      continue;
+    indexInFolder++;
+    if (indexInFolder >= p->db.Folders[folderIndex].NumUnpackStreams)
+    {
+      folderIndex++;
+      indexInFolder = 0;
+    }
+  }
+  return SZ_OK;
+}
+
+
+UInt64 SzArEx_GetFolderStreamPos(const CSzArEx *p, UInt32 folderIndex, UInt32 indexInFolder)
+{
+  return p->dataPos +
+    p->PackStreamStartPositions[p->FolderStartPackStreamIndex[folderIndex] + indexInFolder];
+}
+
+int SzArEx_GetFolderFullPackSize(const CSzArEx *p, UInt32 folderIndex, UInt64 *resSize)
+{
+  UInt32 packStreamIndex = p->FolderStartPackStreamIndex[folderIndex];
+  CSzFolder *folder = p->db.Folders + folderIndex;
+  UInt64 size = 0;
+  UInt32 i;
+  for (i = 0; i < folder->NumPackStreams; i++)
+  {
+    UInt64 t = size + p->db.PackSizes[packStreamIndex + i];
+    if (t < size) /* check it */
+      return SZ_ERROR_FAIL;
+    size = t;
+  }
+  *resSize = size;
+  return SZ_OK;
+}
+
+
+/*
+SRes SzReadTime(const CObjectVector<CBuf> &dataVector,
+    CObjectVector<CSzFileItem> &files, UInt64 type)
+{
+  CBoolVector boolVector;
+  RINOK(ReadBoolVector2(files.Size(), boolVector))
+
+  CStreamSwitch streamSwitch;
+  RINOK(streamSwitch.Set(this, &dataVector));
+
+  for (int i = 0; i < files.Size(); i++)
+  {
+    CSzFileItem &file = files[i];
+    CArchiveFileTime fileTime;
+    bool defined = boolVector[i];
+    if (defined)
+    {
+      UInt32 low, high;
+      RINOK(SzReadUInt32(low));
+      RINOK(SzReadUInt32(high));
+      fileTime.dwLowDateTime = low;
+      fileTime.dwHighDateTime = high;
+    }
+    switch(type)
+    {
+      case k7zIdCTime: file.IsCTimeDefined = defined; if (defined) file.CTime = fileTime; break;
+      case k7zIdATime: file.IsATimeDefined = defined; if (defined) file.ATime = fileTime; break;
+      case k7zIdMTime: file.IsMTimeDefined = defined; if (defined) file.MTime = fileTime; break;
+    }
+  }
+  return SZ_OK;
+}
+*/
+
+static int TestSignatureCandidate(Byte *testBytes)
+{
+  size_t i;
+  for (i = 0; i < k7zSignatureSize; i++)
+    if (testBytes[i] != k7zSignature[i])
+      return 0;
+  return 1;
+}
+
+typedef struct _CSzState
+{
+  Byte *Data;
+  size_t Size;
+}CSzData;
+
+static SRes SzReadByte(CSzData *sd, Byte *b)
+{
+  if (sd->Size == 0)
+    return SZ_ERROR_ARCHIVE;
+  sd->Size--;
+  *b = *sd->Data++;
+  return SZ_OK;
+}
+
+static SRes SzReadBytes(CSzData *sd, Byte *data, size_t size)
+{
+  size_t i;
+  for (i = 0; i < size; i++)
+  {
+    RINOK(SzReadByte(sd, data + i));
+  }
+  return SZ_OK;
+}
+
+static SRes SzReadUInt32(CSzData *sd, UInt32 *value)
+{
+  int i;
+  *value = 0;
+  for (i = 0; i < 4; i++)
+  {
+    Byte b;
+    RINOK(SzReadByte(sd, &b));
+    *value |= ((UInt32)(b) << (8 * i));
+  }
+  return SZ_OK;
+}
+
+static SRes SzReadNumber(CSzData *sd, UInt64 *value)
+{
+  Byte firstByte;
+  Byte mask = 0x80;
+  int i;
+  RINOK(SzReadByte(sd, &firstByte));
+  *value = 0;
+  for (i = 0; i < 8; i++)
+  {
+    Byte b;
+    if ((firstByte & mask) == 0)
+    {
+      UInt64 highPart = firstByte & (mask - 1);
+      *value += (highPart << (8 * i));
+      return SZ_OK;
+    }
+    RINOK(SzReadByte(sd, &b));
+    *value |= ((UInt64)b << (8 * i));
+    mask >>= 1;
+  }
+  return SZ_OK;
+}
+
+static SRes SzReadNumber32(CSzData *sd, UInt32 *value)
+{
+  UInt64 value64;
+  RINOK(SzReadNumber(sd, &value64));
+  if (value64 >= 0x80000000)
+    return SZ_ERROR_UNSUPPORTED;
+  if (value64 >= ((UInt64)(1) << ((sizeof(size_t) - 1) * 8 + 2)))
+    return SZ_ERROR_UNSUPPORTED;
+  *value = (UInt32)value64;
+  return SZ_OK;
+}
+
+static SRes SzReadID(CSzData *sd, UInt64 *value)
+{
+  return SzReadNumber(sd, value);
+}
+
+static SRes SzSkeepDataSize(CSzData *sd, UInt64 size)
+{
+  if (size > sd->Size)
+    return SZ_ERROR_ARCHIVE;
+  sd->Size -= (size_t)size;
+  sd->Data += (size_t)size;
+  return SZ_OK;
+}
+
+static SRes SzSkeepData(CSzData *sd)
+{
+  UInt64 size;
+  RINOK(SzReadNumber(sd, &size));
+  return SzSkeepDataSize(sd, size);
+}
+
+static SRes SzReadArchiveProperties(CSzData *sd)
+{
+  for (;;)
+  {
+    UInt64 type;
+    RINOK(SzReadID(sd, &type));
+    if (type == k7zIdEnd)
+      break;
+    SzSkeepData(sd);
+  }
+  return SZ_OK;
+}
+
+static SRes SzWaitAttribute(CSzData *sd, UInt64 attribute)
+{
+  for (;;)
+  {
+    UInt64 type;
+    RINOK(SzReadID(sd, &type));
+    if (type == attribute)
+      return SZ_OK;
+    if (type == k7zIdEnd)
+      return SZ_ERROR_ARCHIVE;
+    RINOK(SzSkeepData(sd));
+  }
+}
+
+static SRes SzReadBoolVector(CSzData *sd, size_t numItems, Byte **v, ISzAlloc *alloc)
+{
+  Byte b = 0;
+  Byte mask = 0;
+  size_t i;
+  MY_ALLOC(Byte, *v, numItems, alloc);
+  for (i = 0; i < numItems; i++)
+  {
+    if (mask == 0)
+    {
+      RINOK(SzReadByte(sd, &b));
+      mask = 0x80;
+    }
+    (*v)[i] = (Byte)(((b & mask) != 0) ? 1 : 0);
+    mask >>= 1;
+  }
+  return SZ_OK;
+}
+
+static SRes SzReadBoolVector2(CSzData *sd, size_t numItems, Byte **v, ISzAlloc *alloc)
+{
+  Byte allAreDefined;
+  size_t i;
+  RINOK(SzReadByte(sd, &allAreDefined));
+  if (allAreDefined == 0)
+    return SzReadBoolVector(sd, numItems, v, alloc);
+  MY_ALLOC(Byte, *v, numItems, alloc);
+  for (i = 0; i < numItems; i++)
+    (*v)[i] = 1;
+  return SZ_OK;
+}
+
+static SRes SzReadHashDigests(
+    CSzData *sd,
+    size_t numItems,
+    Byte **digestsDefined,
+    UInt32 **digests,
+    ISzAlloc *alloc)
+{
+  size_t i;
+  RINOK(SzReadBoolVector2(sd, numItems, digestsDefined, alloc));
+  MY_ALLOC(UInt32, *digests, numItems, alloc);
+  for (i = 0; i < numItems; i++)
+    if ((*digestsDefined)[i])
+    {
+      RINOK(SzReadUInt32(sd, (*digests) + i));
+    }
+  return SZ_OK;
+}
+
+static SRes SzReadPackInfo(
+    CSzData *sd,
+    UInt64 *dataOffset,
+    UInt32 *numPackStreams,
+    UInt64 **packSizes,
+    Byte **packCRCsDefined,
+    UInt32 **packCRCs,
+    ISzAlloc *alloc)
+{
+  UInt32 i;
+  RINOK(SzReadNumber(sd, dataOffset));
+  RINOK(SzReadNumber32(sd, numPackStreams));
+
+  RINOK(SzWaitAttribute(sd, k7zIdSize));
+
+  MY_ALLOC(UInt64, *packSizes, (size_t)*numPackStreams, alloc);
+
+  for (i = 0; i < *numPackStreams; i++)
+  {
+    RINOK(SzReadNumber(sd, (*packSizes) + i));
+  }
+
+  for (;;)
+  {
+    UInt64 type;
+    RINOK(SzReadID(sd, &type));
+    if (type == k7zIdEnd)
+      break;
+    if (type == k7zIdCRC)
+    {
+      RINOK(SzReadHashDigests(sd, (size_t)*numPackStreams, packCRCsDefined, packCRCs, alloc));
+      continue;
+    }
+    RINOK(SzSkeepData(sd));
+  }
+  if (*packCRCsDefined == 0)
+  {
+    MY_ALLOC(Byte, *packCRCsDefined, (size_t)*numPackStreams, alloc);
+    MY_ALLOC(UInt32, *packCRCs, (size_t)*numPackStreams, alloc);
+    for (i = 0; i < *numPackStreams; i++)
+    {
+      (*packCRCsDefined)[i] = 0;
+      (*packCRCs)[i] = 0;
+    }
+  }
+  return SZ_OK;
+}
+
+static SRes SzReadSwitch(CSzData *sd)
+{
+  Byte external;
+  RINOK(SzReadByte(sd, &external));
+  return (external == 0) ? SZ_OK: SZ_ERROR_UNSUPPORTED;
+}
+
+static SRes SzGetNextFolderItem(CSzData *sd, CSzFolder *folder, ISzAlloc *alloc)
+{
+  UInt32 numCoders, numBindPairs, numPackStreams, i;
+  UInt32 numInStreams = 0, numOutStreams = 0;
+  
+  RINOK(SzReadNumber32(sd, &numCoders));
+  if (numCoders > NUM_FOLDER_CODERS_MAX)
+    return SZ_ERROR_UNSUPPORTED;
+  folder->NumCoders = numCoders;
+  
+  MY_ALLOC(CSzCoderInfo, folder->Coders, (size_t)numCoders, alloc);
+
+  for (i = 0; i < numCoders; i++)
+    SzCoderInfo_Init(folder->Coders + i);
+
+  for (i = 0; i < numCoders; i++)
+  {
+    Byte mainByte;
+    CSzCoderInfo *coder = folder->Coders + i;
+    {
+      unsigned idSize, j;
+      Byte longID[15];
+      RINOK(SzReadByte(sd, &mainByte));
+      idSize = (unsigned)(mainByte & 0xF);
+      RINOK(SzReadBytes(sd, longID, idSize));
+      if (idSize > sizeof(coder->MethodID))
+        return SZ_ERROR_UNSUPPORTED;
+      coder->MethodID = 0;
+      for (j = 0; j < idSize; j++)
+        coder->MethodID |= (UInt64)longID[idSize - 1 - j] << (8 * j);
+
+      if ((mainByte & 0x10) != 0)
+      {
+        RINOK(SzReadNumber32(sd, &coder->NumInStreams));
+        RINOK(SzReadNumber32(sd, &coder->NumOutStreams));
+        if (coder->NumInStreams > NUM_CODER_STREAMS_MAX ||
+            coder->NumOutStreams > NUM_CODER_STREAMS_MAX)
+          return SZ_ERROR_UNSUPPORTED;
+      }
+      else
+      {
+        coder->NumInStreams = 1;
+        coder->NumOutStreams = 1;
+      }
+      if ((mainByte & 0x20) != 0)
+      {
+        UInt64 propertiesSize = 0;
+        RINOK(SzReadNumber(sd, &propertiesSize));
+        if (!Buf_Create(&coder->Props, (size_t)propertiesSize, alloc))
+          return SZ_ERROR_MEM;
+        RINOK(SzReadBytes(sd, coder->Props.data, (size_t)propertiesSize));
+      }
+    }
+    while ((mainByte & 0x80) != 0)
+    {
+      RINOK(SzReadByte(sd, &mainByte));
+      RINOK(SzSkeepDataSize(sd, (mainByte & 0xF)));
+      if ((mainByte & 0x10) != 0)
+      {
+        UInt32 n;
+        RINOK(SzReadNumber32(sd, &n));
+        RINOK(SzReadNumber32(sd, &n));
+      }
+      if ((mainByte & 0x20) != 0)
+      {
+        UInt64 propertiesSize = 0;
+        RINOK(SzReadNumber(sd, &propertiesSize));
+        RINOK(SzSkeepDataSize(sd, propertiesSize));
+      }
+    }
+    numInStreams += coder->NumInStreams;
+    numOutStreams += coder->NumOutStreams;
+  }
+
+  if (numOutStreams == 0)
+    return SZ_ERROR_UNSUPPORTED;
+
+  folder->NumBindPairs = numBindPairs = numOutStreams - 1;
+  MY_ALLOC(CSzBindPair, folder->BindPairs, (size_t)numBindPairs, alloc);
+
+  for (i = 0; i < numBindPairs; i++)
+  {
+    CSzBindPair *bp = folder->BindPairs + i;
+    RINOK(SzReadNumber32(sd, &bp->InIndex));
+    RINOK(SzReadNumber32(sd, &bp->OutIndex));
+  }
+
+  if (numInStreams < numBindPairs)
+    return SZ_ERROR_UNSUPPORTED;
+
+  folder->NumPackStreams = numPackStreams = numInStreams - numBindPairs;
+  MY_ALLOC(UInt32, folder->PackStreams, (size_t)numPackStreams, alloc);
+
+  if (numPackStreams == 1)
+  {
+    for (i = 0; i < numInStreams ; i++)
+      if (SzFolder_FindBindPairForInStream(folder, i) < 0)
+        break;
+    if (i == numInStreams)
+      return SZ_ERROR_UNSUPPORTED;
+    folder->PackStreams[0] = i;
+  }
+  else
+    for (i = 0; i < numPackStreams; i++)
+    {
+      RINOK(SzReadNumber32(sd, folder->PackStreams + i));
+    }
+  return SZ_OK;
+}
+
+static SRes SzReadUnpackInfo(
+    CSzData *sd,
+    UInt32 *numFolders,
+    CSzFolder **folders,  /* for alloc */
+    ISzAlloc *alloc,
+    ISzAlloc *allocTemp)
+{
+  UInt32 i;
+  RINOK(SzWaitAttribute(sd, k7zIdFolder));
+  RINOK(SzReadNumber32(sd, numFolders));
+  {
+    RINOK(SzReadSwitch(sd));
+
+    MY_ALLOC(CSzFolder, *folders, (size_t)*numFolders, alloc);
+
+    for (i = 0; i < *numFolders; i++)
+      SzFolder_Init((*folders) + i);
+
+    for (i = 0; i < *numFolders; i++)
+    {
+      RINOK(SzGetNextFolderItem(sd, (*folders) + i, alloc));
+    }
+  }
+
+  RINOK(SzWaitAttribute(sd, k7zIdCodersUnpackSize));
+
+  for (i = 0; i < *numFolders; i++)
+  {
+    UInt32 j;
+    CSzFolder *folder = (*folders) + i;
+    UInt32 numOutStreams = SzFolder_GetNumOutStreams(folder);
+
+    MY_ALLOC(UInt64, folder->UnpackSizes, (size_t)numOutStreams, alloc);
+
+    for (j = 0; j < numOutStreams; j++)
+    {
+      RINOK(SzReadNumber(sd, folder->UnpackSizes + j));
+    }
+  }
+
+  for (;;)
+  {
+    UInt64 type;
+    RINOK(SzReadID(sd, &type));
+    if (type == k7zIdEnd)
+      return SZ_OK;
+    if (type == k7zIdCRC)
+    {
+      SRes res;
+      Byte *crcsDefined = 0;
+      UInt32 *crcs = 0;
+      res = SzReadHashDigests(sd, *numFolders, &crcsDefined, &crcs, allocTemp);
+      if (res == SZ_OK)
+      {
+        for (i = 0; i < *numFolders; i++)
+        {
+          CSzFolder *folder = (*folders) + i;
+          folder->UnpackCRCDefined = crcsDefined[i];
+          folder->UnpackCRC = crcs[i];
+        }
+      }
+      IAlloc_Free(allocTemp, crcs);
+      IAlloc_Free(allocTemp, crcsDefined);
+      RINOK(res);
+      continue;
+    }
+    RINOK(SzSkeepData(sd));
+  }
+}
+
+static SRes SzReadSubStreamsInfo(
+    CSzData *sd,
+    UInt32 numFolders,
+    CSzFolder *folders,
+    UInt32 *numUnpackStreams,
+    UInt64 **unpackSizes,
+    Byte **digestsDefined,
+    UInt32 **digests,
+    ISzAlloc *allocTemp)
+{
+  UInt64 type = 0;
+  UInt32 i;
+  UInt32 si = 0;
+  UInt32 numDigests = 0;
+
+  for (i = 0; i < numFolders; i++)
+    folders[i].NumUnpackStreams = 1;
+  *numUnpackStreams = numFolders;
+
+  for (;;)
+  {
+    RINOK(SzReadID(sd, &type));
+    if (type == k7zIdNumUnpackStream)
+    {
+      *numUnpackStreams = 0;
+      for (i = 0; i < numFolders; i++)
+      {
+        UInt32 numStreams;
+        RINOK(SzReadNumber32(sd, &numStreams));
+        folders[i].NumUnpackStreams = numStreams;
+        *numUnpackStreams += numStreams;
+      }
+      continue;
+    }
+    if (type == k7zIdCRC || type == k7zIdSize)
+      break;
+    if (type == k7zIdEnd)
+      break;
+    RINOK(SzSkeepData(sd));
+  }
+
+  if (*numUnpackStreams == 0)
+  {
+    *unpackSizes = 0;
+    *digestsDefined = 0;
+    *digests = 0;
+  }
+  else
+  {
+    *unpackSizes = (UInt64 *)IAlloc_Alloc(allocTemp, (size_t)*numUnpackStreams * sizeof(UInt64));
+    RINOM(*unpackSizes);
+    *digestsDefined = (Byte *)IAlloc_Alloc(allocTemp, (size_t)*numUnpackStreams * sizeof(Byte));
+    RINOM(*digestsDefined);
+    *digests = (UInt32 *)IAlloc_Alloc(allocTemp, (size_t)*numUnpackStreams * sizeof(UInt32));
+    RINOM(*digests);
+  }
+
+  for (i = 0; i < numFolders; i++)
+  {
+    /*
+    v3.13 incorrectly worked with empty folders
+    v4.07: we check that folder is empty
+    */
+    UInt64 sum = 0;
+    UInt32 j;
+    UInt32 numSubstreams = folders[i].NumUnpackStreams;
+    if (numSubstreams == 0)
+      continue;
+    if (type == k7zIdSize)
+    for (j = 1; j < numSubstreams; j++)
+    {
+      UInt64 size;
+      RINOK(SzReadNumber(sd, &size));
+      (*unpackSizes)[si++] = size;
+      sum += size;
+    }
+    (*unpackSizes)[si++] = SzFolder_GetUnpackSize(folders + i) - sum;
+  }
+  if (type == k7zIdSize)
+  {
+    RINOK(SzReadID(sd, &type));
+  }
+
+  for (i = 0; i < *numUnpackStreams; i++)
+  {
+    (*digestsDefined)[i] = 0;
+    (*digests)[i] = 0;
+  }
+
+
+  for (i = 0; i < numFolders; i++)
+  {
+    UInt32 numSubstreams = folders[i].NumUnpackStreams;
+    if (numSubstreams != 1 || !folders[i].UnpackCRCDefined)
+      numDigests += numSubstreams;
+  }
+
+ 
+  si = 0;
+  for (;;)
+  {
+    if (type == k7zIdCRC)
+    {
+      int digestIndex = 0;
+      Byte *digestsDefined2 = 0;
+      UInt32 *digests2 = 0;
+      SRes res = SzReadHashDigests(sd, numDigests, &digestsDefined2, &digests2, allocTemp);
+      if (res == SZ_OK)
+      {
+        for (i = 0; i < numFolders; i++)
+        {
+          CSzFolder *folder = folders + i;
+          UInt32 numSubstreams = folder->NumUnpackStreams;
+          if (numSubstreams == 1 && folder->UnpackCRCDefined)
+          {
+            (*digestsDefined)[si] = 1;
+            (*digests)[si] = folder->UnpackCRC;
+            si++;
+          }
+          else
+          {
+            UInt32 j;
+            for (j = 0; j < numSubstreams; j++, digestIndex++)
+            {
+              (*digestsDefined)[si] = digestsDefined2[digestIndex];
+              (*digests)[si] = digests2[digestIndex];
+              si++;
+            }
+          }
+        }
+      }
+      IAlloc_Free(allocTemp, digestsDefined2);
+      IAlloc_Free(allocTemp, digests2);
+      RINOK(res);
+    }
+    else if (type == k7zIdEnd)
+      return SZ_OK;
+    else
+    {
+      RINOK(SzSkeepData(sd));
+    }
+    RINOK(SzReadID(sd, &type));
+  }
+}
+
+
+static SRes SzReadStreamsInfo(
+    CSzData *sd,
+    UInt64 *dataOffset,
+    CSzAr *p,
+    UInt32 *numUnpackStreams,
+    UInt64 **unpackSizes, /* allocTemp */
+    Byte **digestsDefined,   /* allocTemp */
+    UInt32 **digests,        /* allocTemp */
+    ISzAlloc *alloc,
+    ISzAlloc *allocTemp)
+{
+  for (;;)
+  {
+    UInt64 type;
+    RINOK(SzReadID(sd, &type));
+    if ((UInt64)(int)type != type)
+      return SZ_ERROR_UNSUPPORTED;
+    switch((int)type)
+    {
+      case k7zIdEnd:
+        return SZ_OK;
+      case k7zIdPackInfo:
+      {
+        RINOK(SzReadPackInfo(sd, dataOffset, &p->NumPackStreams,
+            &p->PackSizes, &p->PackCRCsDefined, &p->PackCRCs, alloc));
+        break;
+      }
+      case k7zIdUnpackInfo:
+      {
+        RINOK(SzReadUnpackInfo(sd, &p->NumFolders, &p->Folders, alloc, allocTemp));
+        break;
+      }
+      case k7zIdSubStreamsInfo:
+      {
+        RINOK(SzReadSubStreamsInfo(sd, p->NumFolders, p->Folders,
+            numUnpackStreams, unpackSizes, digestsDefined, digests, allocTemp));
+        break;
+      }
+      default:
+        return SZ_ERROR_UNSUPPORTED;
+    }
+  }
+}
+
+size_t SzArEx_GetFileNameUtf16(const CSzArEx *p, size_t fileIndex, UInt16 *dest)
+{
+  size_t len = p->FileNameOffsets[fileIndex + 1] - p->FileNameOffsets[fileIndex];
+  if (dest != 0)
+  {
+    size_t i;
+    const Byte *src = p->FileNames.data + (p->FileNameOffsets[fileIndex] * 2);
+    for (i = 0; i < len; i++)
+      dest[i] = GetUi16(src + i * 2);
+  }
+  return len;
+}
+
+static SRes SzReadFileNames(const Byte *p, size_t size, UInt32 numFiles, size_t *sizes)
+{
+  UInt32 i;
+  size_t pos = 0;
+  for (i = 0; i < numFiles; i++)
+  {
+    sizes[i] = pos;
+    for (;;)
+    {
+      if (pos >= size)
+        return SZ_ERROR_ARCHIVE;
+      if (p[pos * 2] == 0 && p[pos * 2 + 1] == 0)
+        break;
+      pos++;
+    }
+    pos++;
+  }
+  sizes[i] = pos;
+  return (pos == size) ? SZ_OK : SZ_ERROR_ARCHIVE;
+}
+
+static SRes SzReadHeader2(
+    CSzArEx *p,   /* allocMain */
+    CSzData *sd,
+    UInt64 **unpackSizes,  /* allocTemp */
+    Byte **digestsDefined,    /* allocTemp */
+    UInt32 **digests,         /* allocTemp */
+    Byte **emptyStreamVector, /* allocTemp */
+    Byte **emptyFileVector,   /* allocTemp */
+    Byte **lwtVector,         /* allocTemp */
+    ISzAlloc *allocMain,
+    ISzAlloc *allocTemp)
+{
+  UInt64 type;
+  UInt32 numUnpackStreams = 0;
+  UInt32 numFiles = 0;
+  CSzFileItem *files = 0;
+  UInt32 numEmptyStreams = 0;
+  UInt32 i;
+
+  RINOK(SzReadID(sd, &type));
+
+  if (type == k7zIdArchiveProperties)
+  {
+    RINOK(SzReadArchiveProperties(sd));
+    RINOK(SzReadID(sd, &type));
+  }
+ 
+ 
+  if (type == k7zIdMainStreamsInfo)
+  {
+    RINOK(SzReadStreamsInfo(sd,
+        &p->dataPos,
+        &p->db,
+        &numUnpackStreams,
+        unpackSizes,
+        digestsDefined,
+        digests, allocMain, allocTemp));
+    p->dataPos += p->startPosAfterHeader;
+    RINOK(SzReadID(sd, &type));
+  }
+
+  if (type == k7zIdEnd)
+    return SZ_OK;
+  if (type != k7zIdFilesInfo)
+    return SZ_ERROR_ARCHIVE;
+  
+  RINOK(SzReadNumber32(sd, &numFiles));
+  p->db.NumFiles = numFiles;
+
+  MY_ALLOC(CSzFileItem, files, (size_t)numFiles, allocMain);
+
+  p->db.Files = files;
+  for (i = 0; i < numFiles; i++)
+    SzFile_Init(files + i);
+
+  for (;;)
+  {
+    UInt64 type;
+    UInt64 size;
+    RINOK(SzReadID(sd, &type));
+    if (type == k7zIdEnd)
+      break;
+    RINOK(SzReadNumber(sd, &size));
+    if (size > sd->Size)
+      return SZ_ERROR_ARCHIVE;
+    if ((UInt64)(int)type != type)
+    {
+      RINOK(SzSkeepDataSize(sd, size));
+    }
+    else
+    switch((int)type)
+    {
+      case k7zIdName:
+      {
+        size_t namesSize;
+        RINOK(SzReadSwitch(sd));
+        namesSize = (size_t)size - 1;
+        if ((namesSize & 1) != 0)
+          return SZ_ERROR_ARCHIVE;
+        if (!Buf_Create(&p->FileNames, namesSize, allocMain))
+          return SZ_ERROR_MEM;
+        MY_ALLOC(size_t, p->FileNameOffsets, numFiles + 1, allocMain);
+        memcpy(p->FileNames.data, sd->Data, namesSize);
+        RINOK(SzReadFileNames(sd->Data, namesSize >> 1, numFiles, p->FileNameOffsets))
+        break;
+      }
+      case k7zIdEmptyStream:
+      {
+        RINOK(SzReadBoolVector(sd, numFiles, emptyStreamVector, allocTemp));
+        numEmptyStreams = 0;
+        for (i = 0; i < numFiles; i++)
+          if ((*emptyStreamVector)[i])
+            numEmptyStreams++;
+        break;
+      }
+      case k7zIdEmptyFile:
+      {
+        RINOK(SzReadBoolVector(sd, numEmptyStreams, emptyFileVector, allocTemp));
+        break;
+      }
+      case k7zIdMTime:
+      {
+        RINOK(SzReadBoolVector2(sd, numFiles, lwtVector, allocTemp));
+        RINOK(SzReadSwitch(sd));
+        for (i = 0; i < numFiles; i++)
+        {
+          CSzFileItem *f = &files[i];
+          Byte defined = (*lwtVector)[i];
+          f->MTimeDefined = defined;
+          f->MTime.Low = f->MTime.High = 0;
+          if (defined)
+          {
+            RINOK(SzReadUInt32(sd, &f->MTime.Low));
+            RINOK(SzReadUInt32(sd, &f->MTime.High));
+          }
+        }
+        break;
+      }
+      default:
+      {
+        RINOK(SzSkeepDataSize(sd, size));
+      }
+    }
+  }
+
+  {
+    UInt32 emptyFileIndex = 0;
+    UInt32 sizeIndex = 0;
+    for (i = 0; i < numFiles; i++)
+    {
+      CSzFileItem *file = files + i;
+      file->IsAnti = 0;
+      if (*emptyStreamVector == 0)
+        file->HasStream = 1;
+      else
+        file->HasStream = (Byte)((*emptyStreamVector)[i] ? 0 : 1);
+      if (file->HasStream)
+      {
+        file->IsDir = 0;
+        file->Size = (*unpackSizes)[sizeIndex];
+        file->Crc = (*digests)[sizeIndex];
+        file->CrcDefined = (Byte)(*digestsDefined)[sizeIndex];
+        sizeIndex++;
+      }
+      else
+      {
+        if (*emptyFileVector == 0)
+          file->IsDir = 1;
+        else
+          file->IsDir = (Byte)((*emptyFileVector)[emptyFileIndex] ? 0 : 1);
+        emptyFileIndex++;
+        file->Size = 0;
+        file->Crc = 0;
+        file->CrcDefined = 0;
+      }
+    }
+  }
+  return SzArEx_Fill(p, allocMain);
+}
+
+static SRes SzReadHeader(
+    CSzArEx *p,
+    CSzData *sd,
+    ISzAlloc *allocMain,
+    ISzAlloc *allocTemp)
+{
+  UInt64 *unpackSizes = 0;
+  Byte *digestsDefined = 0;
+  UInt32 *digests = 0;
+  Byte *emptyStreamVector = 0;
+  Byte *emptyFileVector = 0;
+  Byte *lwtVector = 0;
+  SRes res = SzReadHeader2(p, sd,
+      &unpackSizes, &digestsDefined, &digests,
+      &emptyStreamVector, &emptyFileVector, &lwtVector,
+      allocMain, allocTemp);
+  IAlloc_Free(allocTemp, unpackSizes);
+  IAlloc_Free(allocTemp, digestsDefined);
+  IAlloc_Free(allocTemp, digests);
+  IAlloc_Free(allocTemp, emptyStreamVector);
+  IAlloc_Free(allocTemp, emptyFileVector);
+  IAlloc_Free(allocTemp, lwtVector);
+  return res;
+}
+
+static SRes SzReadAndDecodePackedStreams2(
+    ILookInStream *inStream,
+    CSzData *sd,
+    CBuf *outBuffer,
+    UInt64 baseOffset,
+    CSzAr *p,
+    UInt64 **unpackSizes,
+    Byte **digestsDefined,
+    UInt32 **digests,
+    ISzAlloc *allocTemp)
+{
+
+  UInt32 numUnpackStreams = 0;
+  UInt64 dataStartPos;
+  CSzFolder *folder;
+  UInt64 unpackSize;
+  SRes res;
+
+  RINOK(SzReadStreamsInfo(sd, &dataStartPos, p,
+      &numUnpackStreams,  unpackSizes, digestsDefined, digests,
+      allocTemp, allocTemp));
+  
+  dataStartPos += baseOffset;
+  if (p->NumFolders != 1)
+    return SZ_ERROR_ARCHIVE;
+
+  folder = p->Folders;
+  unpackSize = SzFolder_GetUnpackSize(folder);
+  
+  RINOK(LookInStream_SeekTo(inStream, dataStartPos));
+
+  if (!Buf_Create(outBuffer, (size_t)unpackSize, allocTemp))
+    return SZ_ERROR_MEM;
+  
+  res = SzFolder_Decode(folder, p->PackSizes,
+          inStream, dataStartPos,
+          outBuffer->data, (size_t)unpackSize, allocTemp);
+  RINOK(res);
+  if (folder->UnpackCRCDefined)
+    if (CrcCalc(outBuffer->data, (size_t)unpackSize) != folder->UnpackCRC)
+      return SZ_ERROR_CRC;
+  return SZ_OK;
+}
+
+static SRes SzReadAndDecodePackedStreams(
+    ILookInStream *inStream,
+    CSzData *sd,
+    CBuf *outBuffer,
+    UInt64 baseOffset,
+    ISzAlloc *allocTemp)
+{
+  CSzAr p;
+  UInt64 *unpackSizes = 0;
+  Byte *digestsDefined = 0;
+  UInt32 *digests = 0;
+  SRes res;
+  SzAr_Init(&p);
+  res = SzReadAndDecodePackedStreams2(inStream, sd, outBuffer, baseOffset,
+    &p, &unpackSizes, &digestsDefined, &digests,
+    allocTemp);
+  SzAr_Free(&p, allocTemp);
+  IAlloc_Free(allocTemp, unpackSizes);
+  IAlloc_Free(allocTemp, digestsDefined);
+  IAlloc_Free(allocTemp, digests);
+  return res;
+}
+
+static SRes SzArEx_Open2(
+    CSzArEx *p,
+    ILookInStream *inStream,
+    ISzAlloc *allocMain,
+    ISzAlloc *allocTemp)
+{
+  Byte header[k7zStartHeaderSize];
+  UInt64 nextHeaderOffset, nextHeaderSize;
+  size_t nextHeaderSizeT;
+  UInt32 nextHeaderCRC;
+  CBuf buffer;
+  SRes res;
+
+  RINOK(LookInStream_Read2(inStream, header, k7zStartHeaderSize, SZ_ERROR_NO_ARCHIVE));
+
+  if (!TestSignatureCandidate(header))
+    return SZ_ERROR_NO_ARCHIVE;
+  if (header[6] != k7zMajorVersion)
+    return SZ_ERROR_UNSUPPORTED;
+
+  nextHeaderOffset = GetUi64(header + 12);
+  nextHeaderSize = GetUi64(header + 20);
+  nextHeaderCRC = GetUi32(header + 28);
+
+  p->startPosAfterHeader = k7zStartHeaderSize;
+  
+  if (CrcCalc(header + 12, 20) != GetUi32(header + 8))
+    return SZ_ERROR_CRC;
+
+  nextHeaderSizeT = (size_t)nextHeaderSize;
+  if (nextHeaderSizeT != nextHeaderSize)
+    return SZ_ERROR_MEM;
+  if (nextHeaderSizeT == 0)
+    return SZ_OK;
+  if (nextHeaderOffset > nextHeaderOffset + nextHeaderSize ||
+      nextHeaderOffset > nextHeaderOffset + nextHeaderSize + k7zStartHeaderSize)
+    return SZ_ERROR_NO_ARCHIVE;
+
+  {
+    Int64 pos = 0;
+    RINOK(inStream->Seek(inStream, &pos, SZ_SEEK_END));
+    if ((UInt64)pos < nextHeaderOffset ||
+        (UInt64)pos < k7zStartHeaderSize + nextHeaderOffset ||
+        (UInt64)pos < k7zStartHeaderSize + nextHeaderOffset + nextHeaderSize)
+      return SZ_ERROR_INPUT_EOF;
+  }
+
+  RINOK(LookInStream_SeekTo(inStream, k7zStartHeaderSize + nextHeaderOffset));
+
+  if (!Buf_Create(&buffer, nextHeaderSizeT, allocTemp))
+    return SZ_ERROR_MEM;
+
+  res = LookInStream_Read(inStream, buffer.data, nextHeaderSizeT);
+  if (res == SZ_OK)
+  {
+    res = SZ_ERROR_ARCHIVE;
+    if (CrcCalc(buffer.data, nextHeaderSizeT) == nextHeaderCRC)
+    {
+      CSzData sd;
+      UInt64 type;
+      sd.Data = buffer.data;
+      sd.Size = buffer.size;
+      res = SzReadID(&sd, &type);
+      if (res == SZ_OK)
+      {
+        if (type == k7zIdEncodedHeader)
+        {
+          CBuf outBuffer;
+          Buf_Init(&outBuffer);
+          res = SzReadAndDecodePackedStreams(inStream, &sd, &outBuffer, p->startPosAfterHeader, allocTemp);
+          if (res != SZ_OK)
+            Buf_Free(&outBuffer, allocTemp);
+          else
+          {
+            Buf_Free(&buffer, allocTemp);
+            buffer.data = outBuffer.data;
+            buffer.size = outBuffer.size;
+            sd.Data = buffer.data;
+            sd.Size = buffer.size;
+            res = SzReadID(&sd, &type);
+          }
+        }
+      }
+      if (res == SZ_OK)
+      {
+        if (type == k7zIdHeader)
+          res = SzReadHeader(p, &sd, allocMain, allocTemp);
+        else
+          res = SZ_ERROR_UNSUPPORTED;
+      }
+    }
+  }
+  Buf_Free(&buffer, allocTemp);
+  return res;
+}
+
+SRes SzArEx_Open(CSzArEx *p, ILookInStream *inStream, ISzAlloc *allocMain, ISzAlloc *allocTemp)
+{
+  SRes res = SzArEx_Open2(p, inStream, allocMain, allocTemp);
+  if (res != SZ_OK)
+    SzArEx_Free(p, allocMain);
+  return res;
+}
+
+SRes SzArEx_Extract(
+    const CSzArEx *p,
+    ILookInStream *inStream,
+    UInt32 fileIndex,
+    UInt32 *blockIndex,
+    Byte **outBuffer,
+    size_t *outBufferSize,
+    size_t *offset,
+    size_t *outSizeProcessed,
+    ISzAlloc *allocMain,
+    ISzAlloc *allocTemp)
+{
+  UInt32 folderIndex = p->FileIndexToFolderIndexMap[fileIndex];
+  SRes res = SZ_OK;
+  *offset = 0;
+  *outSizeProcessed = 0;
+  if (folderIndex == (UInt32)-1)
+  {
+    IAlloc_Free(allocMain, *outBuffer);
+    *blockIndex = folderIndex;
+    *outBuffer = 0;
+    *outBufferSize = 0;
+    return SZ_OK;
+  }
+
+  if (*outBuffer == 0 || *blockIndex != folderIndex)
+  {
+    CSzFolder *folder = p->db.Folders + folderIndex;
+    UInt64 unpackSizeSpec = SzFolder_GetUnpackSize(folder);
+    size_t unpackSize = (size_t)unpackSizeSpec;
+    UInt64 startOffset = SzArEx_GetFolderStreamPos(p, folderIndex, 0);
+
+    if (unpackSize != unpackSizeSpec)
+      return SZ_ERROR_MEM;
+    *blockIndex = folderIndex;
+    IAlloc_Free(allocMain, *outBuffer);
+    *outBuffer = 0;
+    
+    RINOK(LookInStream_SeekTo(inStream, startOffset));
+    
+    if (res == SZ_OK)
+    {
+      *outBufferSize = unpackSize;
+      if (unpackSize != 0)
+      {
+        *outBuffer = (Byte *)IAlloc_Alloc(allocMain, unpackSize);
+        if (*outBuffer == 0)
+          res = SZ_ERROR_MEM;
+      }
+      if (res == SZ_OK)
+      {
+        res = SzFolder_Decode(folder,
+          p->db.PackSizes + p->FolderStartPackStreamIndex[folderIndex],
+          inStream, startOffset,
+          *outBuffer, unpackSize, allocTemp);
+        if (res == SZ_OK)
+        {
+          if (folder->UnpackCRCDefined)
+          {
+            if (CrcCalc(*outBuffer, unpackSize) != folder->UnpackCRC)
+              res = SZ_ERROR_CRC;
+          }
+        }
+      }
+    }
+  }
+  if (res == SZ_OK)
+  {
+    UInt32 i;
+    CSzFileItem *fileItem = p->db.Files + fileIndex;
+    *offset = 0;
+    for (i = p->FolderStartFileIndex[folderIndex]; i < fileIndex; i++)
+      *offset += (UInt32)p->db.Files[i].Size;
+    *outSizeProcessed = (size_t)fileItem->Size;
+    if (*offset + *outSizeProcessed > *outBufferSize)
+      return SZ_ERROR_FAIL;
+    if (fileItem->CrcDefined && CrcCalc(*outBuffer + *offset, *outSizeProcessed) != fileItem->Crc)
+      res = SZ_ERROR_CRC;
+  }
+  return res;
+}
new file mode 100644
--- /dev/null
+++ b/modules/lib7z/LZMASDK/C/7zStream.c
@@ -0,0 +1,169 @@
+/* 7zStream.c -- 7z Stream functions
+2008-11-23 : Igor Pavlov : Public domain */
+
+#include <string.h>
+
+#include "Types.h"
+
+SRes SeqInStream_Read2(ISeqInStream *stream, void *buf, size_t size, SRes errorType)
+{
+  while (size != 0)
+  {
+    size_t processed = size;
+    RINOK(stream->Read(stream, buf, &processed));
+    if (processed == 0)
+      return errorType;
+    buf = (void *)((Byte *)buf + processed);
+    size -= processed;
+  }
+  return SZ_OK;
+}
+
+SRes SeqInStream_Read(ISeqInStream *stream, void *buf, size_t size)
+{
+  return SeqInStream_Read2(stream, buf, size, SZ_ERROR_INPUT_EOF);
+}
+
+SRes SeqInStream_ReadByte(ISeqInStream *stream, Byte *buf)
+{
+  size_t processed = 1;
+  RINOK(stream->Read(stream, buf, &processed));
+  return (processed == 1) ? SZ_OK : SZ_ERROR_INPUT_EOF;
+}
+
+SRes LookInStream_SeekTo(ILookInStream *stream, UInt64 offset)
+{
+  Int64 t = offset;
+  return stream->Seek(stream, &t, SZ_SEEK_SET);
+}
+
+SRes LookInStream_LookRead(ILookInStream *stream, void *buf, size_t *size)
+{
+  void *lookBuf;
+  if (*size == 0)
+    return SZ_OK;
+  RINOK(stream->Look(stream, &lookBuf, size));
+  memcpy(buf, lookBuf, *size);
+  return stream->Skip(stream, *size);
+}
+
+SRes LookInStream_Read2(ILookInStream *stream, void *buf, size_t size, SRes errorType)
+{
+  while (size != 0)
+  {
+    size_t processed = size;
+    RINOK(stream->Read(stream, buf, &processed));
+    if (processed == 0)
+      return errorType;
+    buf = (void *)((Byte *)buf + processed);
+    size -= processed;
+  }
+  return SZ_OK;
+}
+
+SRes LookInStream_Read(ILookInStream *stream, void *buf, size_t size)
+{
+  return LookInStream_Read2(stream, buf, size, SZ_ERROR_INPUT_EOF);
+}
+
+static SRes LookToRead_Look_Lookahead(void *pp, void **buf, size_t *size)
+{
+  SRes res = SZ_OK;
+  CLookToRead *p = (CLookToRead *)pp;
+  size_t size2 = p->size - p->pos;
+  if (size2 == 0 && *size > 0)
+  {
+    p->pos = 0;
+    size2 = LookToRead_BUF_SIZE;
+    res = p->realStream->Read(p->realStream, p->buf, &size2);
+    p->size = size2;
+  }
+  if (size2 < *size)
+    *size = size2;
+  *buf = p->buf + p->pos;
+  return res;
+}
+
+static SRes LookToRead_Look_Exact(void *pp, void **buf, size_t *size)
+{
+  SRes res = SZ_OK;
+  CLookToRead *p = (CLookToRead *)pp;
+  size_t size2 = p->size - p->pos;
+  if (size2 == 0 && *size > 0)
+  {
+    p->pos = 0;
+    if (*size > LookToRead_BUF_SIZE)
+      *size = LookToRead_BUF_SIZE;
+    res = p->realStream->Read(p->realStream, p->buf, size);
+    size2 = p->size = *size;
+  }
+  if (size2 < *size)
+    *size = size2;
+  *buf = p->buf + p->pos;
+  return res;
+}
+
+static SRes LookToRead_Skip(void *pp, size_t offset)
+{
+  CLookToRead *p = (CLookToRead *)pp;
+  p->pos += offset;
+  return SZ_OK;
+}
+
+static SRes LookToRead_Read(void *pp, void *buf, size_t *size)
+{
+  CLookToRead *p = (CLookToRead *)pp;
+  size_t rem = p->size - p->pos;
+  if (rem == 0)
+    return p->realStream->Read(p->realStream, buf, size);
+  if (rem > *size)
+    rem = *size;
+  memcpy(buf, p->buf + p->pos, rem);
+  p->pos += rem;
+  *size = rem;
+  return SZ_OK;
+}
+
+static SRes LookToRead_Seek(void *pp, Int64 *pos, ESzSeek origin)
+{
+  CLookToRead *p = (CLookToRead *)pp;
+  p->pos = p->size = 0;
+  return p->realStream->Seek(p->realStream, pos, origin);
+}
+
+void LookToRead_CreateVTable(CLookToRead *p, int lookahead)
+{
+  p->s.Look = lookahead ?
+      LookToRead_Look_Lookahead :
+      LookToRead_Look_Exact;
+  p->s.Skip = LookToRead_Skip;
+  p->s.Read = LookToRead_Read;
+  p->s.Seek = LookToRead_Seek;
+}
+
+void LookToRead_Init(CLookToRead *p)
+{
+  p->pos = p->size = 0;
+}
+
+static SRes SecToLook_Read(void *pp, void *buf, size_t *size)
+{
+  CSecToLook *p = (CSecToLook *)pp;
+  return LookInStream_LookRead(p->realStream, buf, size);
+}
+
+void SecToLook_CreateVTable(CSecToLook *p)
+{
+  p->s.Read = SecToLook_Read;
+}
+
+static SRes SecToRead_Read(void *pp, void *buf, size_t *size)
+{
+  CSecToRead *p = (CSecToRead *)pp;
+  return p->realStream->Read(p->realStream, buf, size);
+}
+
+void SecToRead_CreateVTable(CSecToRead *p)
+{
+  p->s.Read = SecToRead_Read;
+}
new file mode 100644
--- /dev/null
+++ b/modules/lib7z/LZMASDK/C/7zVersion.h
@@ -0,0 +1,7 @@
+#define MY_VER_MAJOR 9
+#define MY_VER_MINOR 07
+#define MY_VER_BUILD 0
+#define MY_VERSION "9.07 beta"
+#define MY_DATE "2009-08-29"
+#define MY_COPYRIGHT ": Igor Pavlov : Public domain"
+#define MY_VERSION_COPYRIGHT_DATE MY_VERSION " " MY_COPYRIGHT " : " MY_DATE
new file mode 100644
--- /dev/null
+++ b/modules/lib7z/LZMASDK/C/Alloc.c
@@ -0,0 +1,127 @@
+/* Alloc.c -- Memory allocation functions
+2008-09-24
+Igor Pavlov
+Public domain */
+
+#ifdef _WIN32
+#include <windows.h>
+#endif
+#include <stdlib.h>
+
+#include "Alloc.h"
+
+/* #define _SZ_ALLOC_DEBUG */
+
+/* use _SZ_ALLOC_DEBUG to debug alloc/free operations */
+#ifdef _SZ_ALLOC_DEBUG
+#include <stdio.h>
+int g_allocCount = 0;
+int g_allocCountMid = 0;
+int g_allocCountBig = 0;
+#endif
+
+void *MyAlloc(size_t size)
+{
+  if (size == 0)
+    return 0;
+  #ifdef _SZ_ALLOC_DEBUG
+  {
+    void *p = malloc(size);
+    fprintf(stderr, "\nAlloc %10d bytes, count = %10d,  addr = %8X", size, g_allocCount++, (unsigned)p);
+    return p;
+  }
+  #else
+  return malloc(size);
+  #endif
+}
+
+void MyFree(void *address)
+{
+  #ifdef _SZ_ALLOC_DEBUG
+  if (address != 0)
+    fprintf(stderr, "\nFree; count = %10d,  addr = %8X", --g_allocCount, (unsigned)address);
+  #endif
+  free(address);
+}
+
+#ifdef _WIN32
+
+void *MidAlloc(size_t size)
+{
+  if (size == 0)
+    return 0;
+  #ifdef _SZ_ALLOC_DEBUG
+  fprintf(stderr, "\nAlloc_Mid %10d bytes;  count = %10d", size, g_allocCountMid++);
+  #endif
+  return VirtualAlloc(0, size, MEM_COMMIT, PAGE_READWRITE);
+}
+
+void MidFree(void *address)
+{
+  #ifdef _SZ_ALLOC_DEBUG
+  if (address != 0)
+    fprintf(stderr, "\nFree_Mid; count = %10d", --g_allocCountMid);
+  #endif
+  if (address == 0)
+    return;
+  VirtualFree(address, 0, MEM_RELEASE);
+}
+
+#ifndef MEM_LARGE_PAGES
+#undef _7ZIP_LARGE_PAGES
+#endif
+
+#ifdef _7ZIP_LARGE_PAGES
+SIZE_T g_LargePageSize = 0;
+typedef SIZE_T (WINAPI *GetLargePageMinimumP)();
+#endif
+
+void SetLargePageSize()
+{
+  #ifdef _7ZIP_LARGE_PAGES
+  SIZE_T size = 0;
+  GetLargePageMinimumP largePageMinimum = (GetLargePageMinimumP)
+        GetProcAddress(GetModuleHandle(TEXT("kernel32.dll")), "GetLargePageMinimum");
+  if (largePageMinimum == 0)
+    return;
+  size = largePageMinimum();
+  if (size == 0 || (size & (size - 1)) != 0)
+    return;
+  g_LargePageSize = size;
+  #endif
+}
+
+
+void *BigAlloc(size_t size)
+{
+  if (size == 0)
+    return 0;
+  #ifdef _SZ_ALLOC_DEBUG
+  fprintf(stderr, "\nAlloc_Big %10d bytes;  count = %10d", size, g_allocCountBig++);
+  #endif
+  
+  #ifdef _7ZIP_LARGE_PAGES
+  if (g_LargePageSize != 0 && g_LargePageSize <= (1 << 30) && size >= (1 << 18))
+  {
+    void *res = VirtualAlloc(0, (size + g_LargePageSize - 1) & (~(g_LargePageSize - 1)),
+        MEM_COMMIT | MEM_LARGE_PAGES, PAGE_READWRITE);
+    if (res != 0)
+      return res;
+  }
+  #endif
+  return VirtualAlloc(0, size, MEM_COMMIT, PAGE_READWRITE);
+}
+
+void BigFree(void *address)
+{
+  #ifdef _SZ_ALLOC_DEBUG
+  if (address != 0)
+    fprintf(stderr, "\nFree_Big; count = %10d", --g_allocCountBig);
+  #endif
+  
+  if (address == 0)
+    return;
+  VirtualFree(address, 0, MEM_RELEASE);
+}
+
+#endif
new file mode 100644
--- /dev/null
+++ b/modules/lib7z/LZMASDK/C/Alloc.h
@@ -0,0 +1,38 @@
+/* Alloc.h -- Memory allocation functions
+2009-02-07 : Igor Pavlov : Public domain */
+
+#ifndef __COMMON_ALLOC_H
+#define __COMMON_ALLOC_H
+
+#include <stddef.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+void *MyAlloc(size_t size);
+void MyFree(void *address);
+
+#ifdef _WIN32
+
+void SetLargePageSize();
+
+void *MidAlloc(size_t size);
+void MidFree(void *address);
+void *BigAlloc(size_t size);
+void BigFree(void *address);
+
+#else
+
+#define MidAlloc(size) MyAlloc(size)
+#define MidFree(address) MyFree(address)
+#define BigAlloc(size) MyAlloc(size)
+#define BigFree(address) MyFree(address)
+
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
new file mode 100644
--- /dev/null
+++ b/modules/lib7z/LZMASDK/C/Bcj2.c
@@ -0,0 +1,132 @@
+/* Bcj2.c -- Converter for x86 code (BCJ2)
+2008-10-04 : Igor Pavlov : Public domain */
+
+#include "Bcj2.h"
+
+#ifdef _LZMA_PROB32
+#define CProb UInt32
+#else
+#define CProb UInt16
+#endif
+
+#define IsJcc(b0, b1) ((b0) == 0x0F && ((b1) & 0xF0) == 0x80)
+#define IsJ(b0, b1) ((b1 & 0xFE) == 0xE8 || IsJcc(b0, b1))
+
+#define kNumTopBits 24
+#define kTopValue ((UInt32)1 << kNumTopBits)
+
+#define kNumBitModelTotalBits 11
+#define kBitModelTotal (1 << kNumBitModelTotalBits)
+#define kNumMoveBits 5
+
+#define RC_READ_BYTE (*buffer++)
+#define RC_TEST { if (buffer == bufferLim) return SZ_ERROR_DATA; }
+#define RC_INIT2 code = 0; range = 0xFFFFFFFF; \
+  { int i; for (i = 0; i < 5; i++) { RC_TEST; code = (code << 8) | RC_READ_BYTE; }}
+
+#define NORMALIZE if (range < kTopValue) { RC_TEST; range <<= 8; code = (code << 8) | RC_READ_BYTE; }
+
+#define IF_BIT_0(p) ttt = *(p); bound = (range >> kNumBitModelTotalBits) * ttt; if (code < bound)
+#define UPDATE_0(p) range = bound; *(p) = (CProb)(ttt + ((kBitModelTotal - ttt) >> kNumMoveBits)); NORMALIZE;
+#define UPDATE_1(p) range -= bound; code -= bound; *(p) = (CProb)(ttt - (ttt >> kNumMoveBits)); NORMALIZE;
+
+int Bcj2_Decode(
+    const Byte *buf0, SizeT size0,
+    const Byte *buf1, SizeT size1,
+    const Byte *buf2, SizeT size2,
+    const Byte *buf3, SizeT size3,
+    Byte *outBuf, SizeT outSize)
+{
+  CProb p[256 + 2];
+  SizeT inPos = 0, outPos = 0;
+
+  const Byte *buffer, *bufferLim;
+  UInt32 range, code;
+  Byte prevByte = 0;
+
+  unsigned int i;
+  for (i = 0; i < sizeof(p) / sizeof(p[0]); i++)
+    p[i] = kBitModelTotal >> 1;
+
+  buffer = buf3;
+  bufferLim = buffer + size3;
+  RC_INIT2
+
+  if (outSize == 0)
+    return SZ_OK;
+
+  for (;;)
+  {
+    Byte b;
+    CProb *prob;
+    UInt32 bound;
+    UInt32 ttt;
+
+    SizeT limit = size0 - inPos;
+    if (outSize - outPos < limit)
+      limit = outSize - outPos;
+    while (limit != 0)
+    {
+      Byte b = buf0[inPos];
+      outBuf[outPos++] = b;
+      if (IsJ(prevByte, b))
+        break;
+      inPos++;
+      prevByte = b;
+      limit--;
+    }
+
+    if (limit == 0 || outPos == outSize)
+      break;
+
+    b = buf0[inPos++];
+
+    if (b == 0xE8)
+      prob = p + prevByte;
+    else if (b == 0xE9)
+      prob = p + 256;
+    else
+      prob = p + 257;
+
+    IF_BIT_0(prob)
+    {
+      UPDATE_0(prob)
+      prevByte = b;
+    }
+    else
+    {
+      UInt32 dest;
+      const Byte *v;
+      UPDATE_1(prob)
+      if (b == 0xE8)
+      {
+        v = buf1;
+        if (size1 < 4)
+          return SZ_ERROR_DATA;
+        buf1 += 4;
+        size1 -= 4;
+      }
+      else
+      {
+        v = buf2;
+        if (size2 < 4)
+          return SZ_ERROR_DATA;
+        buf2 += 4;
+        size2 -= 4;
+      }
+      dest = (((UInt32)v[0] << 24) | ((UInt32)v[1] << 16) |
+          ((UInt32)v[2] << 8) | ((UInt32)v[3])) - ((UInt32)outPos + 4);
+      outBuf[outPos++] = (Byte)dest;
+      if (outPos == outSize)
+        break;
+      outBuf[outPos++] = (Byte)(dest >> 8);
+      if (outPos == outSize)
+        break;
+      outBuf[outPos++] = (Byte)(dest >> 16);
+      if (outPos == outSize)
+        break;
+      outBuf[outPos++] = prevByte = (Byte)(dest >> 24);
+    }
+  }
+  return (outPos == outSize) ? SZ_OK : SZ_ERROR_DATA;
+}
new file mode 100644
--- /dev/null
+++ b/modules/lib7z/LZMASDK/C/Bcj2.h
@@ -0,0 +1,38 @@
+/* Bcj2.h -- Converter for x86 code (BCJ2)
+2009-02-07 : Igor Pavlov : Public domain */
+
+#ifndef __BCJ2_H
+#define __BCJ2_H
+
+#include "Types.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+Conditions:
+  outSize <= FullOutputSize,
+  where FullOutputSize is full size of output stream of x86_2 filter.
+
+If buf0 overlaps outBuf, there are two required conditions:
+  1) (buf0 >= outBuf)
+  2) (buf0 + size0 >= outBuf + FullOutputSize).
+
+Returns:
+  SZ_OK
+  SZ_ERROR_DATA - Data error
+*/
+
+int Bcj2_Decode(
+    const Byte *buf0, SizeT size0,
+    const Byte *buf1, SizeT size1,
+    const Byte *buf2, SizeT size2,
+    const Byte *buf3, SizeT size3,
+    Byte *outBuf, SizeT outSize);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
new file mode 100644
--- /dev/null
+++ b/modules/lib7z/LZMASDK/C/Bra.c
@@ -0,0 +1,133 @@
+/* Bra.c -- Converters for RISC code
+2008-10-04 : Igor Pavlov : Public domain */
+
+#include "Bra.h"
+
+SizeT ARM_Convert(Byte *data, SizeT size, UInt32 ip, int encoding)
+{
+  SizeT i;
+  if (size < 4)
+    return 0;
+  size -= 4;
+  ip += 8;
+  for (i = 0; i <= size; i += 4)
+  {
+    if (data[i + 3] == 0xEB)
+    {
+      UInt32 dest;
+      UInt32 src = ((UInt32)data[i + 2] << 16) | ((UInt32)data[i + 1] << 8) | (data[i + 0]);
+      src <<= 2;
+      if (encoding)
+        dest = ip + (UInt32)i + src;
+      else
+        dest = src - (ip + (UInt32)i);
+      dest >>= 2;
+      data[i + 2] = (Byte)(dest >> 16);
+      data[i + 1] = (Byte)(dest >> 8);
+      data[i + 0] = (Byte)dest;
+    }
+  }
+  return i;
+}
+
+SizeT ARMT_Convert(Byte *data, SizeT size, UInt32 ip, int encoding)
+{
+  SizeT i;
+  if (size < 4)
+    return 0;
+  size -= 4;
+  ip += 4;
+  for (i = 0; i <= size; i += 2)
+  {
+    if ((data[i + 1] & 0xF8) == 0xF0 &&
+        (data[i + 3] & 0xF8) == 0xF8)
+    {
+      UInt32 dest;
+      UInt32 src =
+        (((UInt32)data[i + 1] & 0x7) << 19) |
+        ((UInt32)data[i + 0] << 11) |
+        (((UInt32)data[i + 3] & 0x7) << 8) |
+        (data[i + 2]);
+      
+      src <<= 1;
+      if (encoding)
+        dest = ip + (UInt32)i + src;
+      else
+        dest = src - (ip + (UInt32)i);
+      dest >>= 1;
+      
+      data[i + 1] = (Byte)(0xF0 | ((dest >> 19) & 0x7));
+      data[i + 0] = (Byte)(dest >> 11);
+      data[i + 3] = (Byte)(0xF8 | ((dest >> 8) & 0x7));
+      data[i + 2] = (Byte)dest;
+      i += 2;
+    }
+  }
+  return i;
+}
+
+SizeT PPC_Convert(Byte *data, SizeT size, UInt32 ip, int encoding)
+{
+  SizeT i;
+  if (size < 4)
+    return 0;
+  size -= 4;
+  for (i = 0; i <= size; i += 4)
+  {
+    if ((data[i] >> 2) == 0x12 && (data[i + 3] & 3) == 1)
+    {
+      UInt32 src = ((UInt32)(data[i + 0] & 3) << 24) |
+        ((UInt32)data[i + 1] << 16) |
+        ((UInt32)data[i + 2] << 8) |
+        ((UInt32)data[i + 3] & (~3));
+      
+      UInt32 dest;
+      if (encoding)
+        dest = ip + (UInt32)i + src;
+      else
+        dest = src - (ip + (UInt32)i);
+      data[i + 0] = (Byte)(0x48 | ((dest >> 24) &  0x3));
+      data[i + 1] = (Byte)(dest >> 16);
+      data[i + 2] = (Byte)(dest >> 8);
+      data[i + 3] &= 0x3;
+      data[i + 3] |= dest;
+    }
+  }
+  return i;
+}
+
+SizeT SPARC_Convert(Byte *data, SizeT size, UInt32 ip, int encoding)
+{
+  UInt32 i;
+  if (size < 4)
+    return 0;
+  size -= 4;
+  for (i = 0; i <= size; i += 4)
+  {
+    if (data[i] == 0x40 && (data[i + 1] & 0xC0) == 0x00 ||
+        data[i] == 0x7F && (data[i + 1] & 0xC0) == 0xC0)
+    {
+      UInt32 src =
+        ((UInt32)data[i + 0] << 24) |
+        ((UInt32)data[i + 1] << 16) |
+        ((UInt32)data[i + 2] << 8) |
+        ((UInt32)data[i + 3]);
+      UInt32 dest;
+      
+      src <<= 2;
+      if (encoding)
+        dest = ip + i + src;
+      else
+        dest = src - (ip + i);
+      dest >>= 2;
+      
+      dest = (((0 - ((dest >> 22) & 1)) << 22) & 0x3FFFFFFF) | (dest & 0x3FFFFF) | 0x40000000;
+
+      data[i + 0] = (Byte)(dest >> 24);
+      data[i + 1] = (Byte)(dest >> 16);
+      data[i + 2] = (Byte)(dest >> 8);
+      data[i + 3] = (Byte)dest;
+    }
+  }
+  return i;
+}
new file mode 100644
--- /dev/null
+++ b/modules/lib7z/LZMASDK/C/Bra.h
@@ -0,0 +1,68 @@
+/* Bra.h -- Branch converters for executables
+2009-02-07 : Igor Pavlov : Public domain */
+
+#ifndef __BRA_H
+#define __BRA_H
+
+#include "Types.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+These functions convert relative addresses to absolute addresses
+in CALL instructions to increase the compression ratio.
+  
+  In:
+    data     - data buffer
+    size     - size of data
+    ip       - current virtual Instruction Pinter (IP) value
+    state    - state variable for x86 converter
+    encoding - 0 (for decoding), 1 (for encoding)
+  
+  Out:
+    state    - state variable for x86 converter
+
+  Returns:
+    The number of processed bytes. If you call these functions with multiple calls,
+    you must start next call with first byte after block of processed bytes.
+  
+  Type   Endian  Alignment  LookAhead
+  
+  x86    little      1          4
+  ARMT   little      2          2
+  ARM    little      4          0
+  PPC     big        4          0
+  SPARC   big        4          0
+  IA64   little     16          0
+
+  size must be >= Alignment + LookAhead, if it's not last block.
+  If (size < Alignment + LookAhead), converter returns 0.
+
+  Example:
+
+    UInt32 ip = 0;
+    for ()
+    {
+      ; size must be >= Alignment + LookAhead, if it's not last block
+      SizeT processed = Convert(data, size, ip, 1);
+      data += processed;
+      size -= processed;
+      ip += processed;
+    }
+*/
+
+#define x86_Convert_Init(state) { state = 0; }
+SizeT x86_Convert(Byte *data, SizeT size, UInt32 ip, UInt32 *state, int encoding);
+SizeT ARM_Convert(Byte *data, SizeT size, UInt32 ip, int encoding);
+SizeT ARMT_Convert(Byte *data, SizeT size, UInt32 ip, int encoding);
+SizeT PPC_Convert(Byte *data, SizeT size, UInt32 ip, int encoding);
+SizeT SPARC_Convert(Byte *data, SizeT size, UInt32 ip, int encoding);
+SizeT IA64_Convert(Byte *data, SizeT size, UInt32 ip, int encoding);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
new file mode 100644
--- /dev/null
+++ b/modules/lib7z/LZMASDK/C/Bra86.c
@@ -0,0 +1,85 @@
+/* Bra86.c -- Converter for x86 code (BCJ)
+2008-10-04 : Igor Pavlov : Public domain */
+
+#include "Bra.h"
+
+#define Test86MSByte(b) ((b) == 0 || (b) == 0xFF)
+
+const Byte kMaskToAllowedStatus[8] = {1, 1, 1, 0, 1, 0, 0, 0};
+const Byte kMaskToBitNumber[8] = {0, 1, 2, 2, 3, 3, 3, 3};
+
+SizeT x86_Convert(Byte *data, SizeT size, UInt32 ip, UInt32 *state, int encoding)
+{
+  SizeT bufferPos = 0, prevPosT;
+  UInt32 prevMask = *state & 0x7;
+  if (size < 5)
+    return 0;
+  ip += 5;
+  prevPosT = (SizeT)0 - 1;
+
+  for (;;)
+  {
+    Byte *p = data + bufferPos;
+    Byte *limit = data + size - 4;
+    for (; p < limit; p++)
+      if ((*p & 0xFE) == 0xE8)
+        break;
+    bufferPos = (SizeT)(p - data);
+    if (p >= limit)
+      break;
+    prevPosT = bufferPos - prevPosT;
+    if (prevPosT > 3)
+      prevMask = 0;
+    else
+    {
+      prevMask = (prevMask << ((int)prevPosT - 1)) & 0x7;
+      if (prevMask != 0)
+      {
+        Byte b = p[4 - kMaskToBitNumber[prevMask]];
+        if (!kMaskToAllowedStatus[prevMask] || Test86MSByte(b))
+        {
+          prevPosT = bufferPos;
+          prevMask = ((prevMask << 1) & 0x7) | 1;
+          bufferPos++;
+          continue;
+        }
+      }
+    }
+    prevPosT = bufferPos;
+
+    if (Test86MSByte(p[4]))
+    {
+      UInt32 src = ((UInt32)p[4] << 24) | ((UInt32)p[3] << 16) | ((UInt32)p[2] << 8) | ((UInt32)p[1]);
+      UInt32 dest;
+      for (;;)
+      {
+        Byte b;
+        int index;
+        if (encoding)
+          dest = (ip + (UInt32)bufferPos) + src;
+        else
+          dest = src - (ip + (UInt32)bufferPos);
+        if (prevMask == 0)
+          break;
+        index = kMaskToBitNumber[prevMask] * 8;
+        b = (Byte)(dest >> (24 - index));
+        if (!Test86MSByte(b))
+          break;
+        src = dest ^ ((1 << (32 - index)) - 1);
+      }
+      p[4] = (Byte)(~(((dest >> 24) & 1) - 1));
+      p[3] = (Byte)(dest >> 16);
+      p[2] = (Byte)(dest >> 8);
+      p[1] = (Byte)dest;
+      bufferPos += 5;
+    }
+    else
+    {
+      prevMask = ((prevMask << 1) & 0x7) | 1;
+      bufferPos++;
+    }
+  }
+  prevPosT = bufferPos - prevPosT;
+  *state = ((prevPosT > 3) ? 0 : ((prevMask << ((int)prevPosT - 1)) & 0x7));
+  return bufferPos;
+}
new file mode 100644
--- /dev/null
+++ b/modules/lib7z/LZMASDK/C/BraIA64.c
@@ -0,0 +1,67 @@
+/* BraIA64.c -- Converter for IA-64 code
+2008-10-04 : Igor Pavlov : Public domain */
+
+#include "Bra.h"
+
+static const Byte kBranchTable[32] =
+{
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+  4, 4, 6, 6, 0, 0, 7, 7,
+  4, 4, 0, 0, 4, 4, 0, 0
+};
+
+SizeT IA64_Convert(Byte *data, SizeT size, UInt32 ip, int encoding)
+{
+  SizeT i;
+  if (size < 16)
+    return 0;
+  size -= 16;
+  for (i = 0; i <= size; i += 16)
+  {
+    UInt32 instrTemplate = data[i] & 0x1F;
+    UInt32 mask = kBranchTable[instrTemplate];
+    UInt32 bitPos = 5;
+    int slot;
+    for (slot = 0; slot < 3; slot++, bitPos += 41)
+    {
+      UInt32 bytePos, bitRes;
+      UInt64 instruction, instNorm;
+      int j;
+      if (((mask >> slot) & 1) == 0)
+        continue;
+      bytePos = (bitPos >> 3);
+      bitRes = bitPos & 0x7;
+      instruction = 0;
+      for (j = 0; j < 6; j++)
+        instruction += (UInt64)data[i + j + bytePos] << (8 * j);
+
+      instNorm = instruction >> bitRes;
+      if (((instNorm >> 37) & 0xF) == 0x5 && ((instNorm >> 9) & 0x7) == 0)
+      {
+        UInt32 src = (UInt32)((instNorm >> 13) & 0xFFFFF);
+        UInt32 dest;
+        src |= ((UInt32)(instNorm >> 36) & 1) << 20;
+        
+        src <<= 4;
+        
+        if (encoding)
+          dest = ip + (UInt32)i + src;
+        else
+          dest = src - (ip + (UInt32)i);
+        
+        dest >>= 4;
+        
+        instNorm &= ~((UInt64)(0x8FFFFF) << 13);
+        instNorm |= ((UInt64)(dest & 0xFFFFF) << 13);
+        instNorm |= ((UInt64)(dest & 0x100000) << (36 - 20));
+        
+        instruction &= (1 << bitRes) - 1;
+        instruction |= (instNorm << bitRes);
+        for (j = 0; j < 6; j++)
+          data[i + j + bytePos] = (Byte)(instruction >> (8 * j));
+      }
+    }
+  }
+  return i;
+}
new file mode 100644
--- /dev/null
+++ b/modules/lib7z/LZMASDK/C/CpuArch.h
@@ -0,0 +1,92 @@
+/* CpuArch.h
+2009-08-11 : Igor Pavlov : Public domain */
+
+#ifndef __CPU_ARCH_H
+#define __CPU_ARCH_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+LITTLE_ENDIAN_UNALIGN means:
+  1) CPU is LITTLE_ENDIAN
+  2) it's allowed to make unaligned memory accesses
+if LITTLE_ENDIAN_UNALIGN is not defined, it means that we don't know
+about these properties of platform.
+*/
+
+#if defined(_M_X64) || defined(_M_AMD64) || defined(__x86_64__)
+#define MY_CPU_AMD64
+#endif
+
+#if defined(MY_CPU_AMD64) || defined(_M_IA64)
+#define MY_CPU_64BIT
+#endif
+
+#if defined(_M_IX86) || defined(__i386__) || defined(MY_CPU_AMD64)
+#define MY_CPU_X86_OR_AMD64
+#endif
+
+#if defined(MY_CPU_X86_OR_AMD64)
+#define LITTLE_ENDIAN_UNALIGN
+#endif
+
+#ifdef LITTLE_ENDIAN_UNALIGN
+
+#define GetUi16(p) (*(const UInt16 *)(p))
+#define GetUi32(p) (*(const UInt32 *)(p))
+#define GetUi64(p) (*(const UInt64 *)(p))
+#define SetUi16(p, d) *(UInt16 *)(p) = (d);
+#define SetUi32(p, d) *(UInt32 *)(p) = (d);
+
+#else
+
+#define GetUi16(p) (((const Byte *)(p))[0] | ((UInt16)((const Byte *)(p))[1] << 8))
+
+#define GetUi32(p) ( \
+             ((const Byte *)(p))[0]        | \
+    ((UInt32)((const Byte *)(p))[1] <<  8) | \
+    ((UInt32)((const Byte *)(p))[2] << 16) | \
+    ((UInt32)((const Byte *)(p))[3] << 24))
+
+#define GetUi64(p) (GetUi32(p) | ((UInt64)GetUi32(((const Byte *)(p)) + 4) << 32))
+
+#define SetUi16(p, d) { UInt32 _x_ = (d); \
+    ((Byte *)(p))[0] = (Byte)_x_; \
+    ((Byte *)(p))[1] = (Byte)(_x_ >> 8); }
+
+#define SetUi32(p, d) { UInt32 _x_ = (d); \
+    ((Byte *)(p))[0] = (Byte)_x_; \
+    ((Byte *)(p))[1] = (Byte)(_x_ >> 8); \
+    ((Byte *)(p))[2] = (Byte)(_x_ >> 16); \
+    ((Byte *)(p))[3] = (Byte)(_x_ >> 24); }
+
+#endif
+
+#if defined(LITTLE_ENDIAN_UNALIGN) && defined(_WIN64) && (_MSC_VER >= 1300)
+
+#pragma intrinsic(_byteswap_ulong)
+#pragma intrinsic(_byteswap_uint64)
+#define GetBe32(p) _byteswap_ulong(*(const UInt32 *)(const Byte *)(p))
+#define GetBe64(p) _byteswap_uint64(*(const UInt64 *)(const Byte *)(p))
+
+#else
+
+#define GetBe32(p) ( \
+    ((UInt32)((const Byte *)(p))[0] << 24) | \
+    ((UInt32)((const Byte *)(p))[1] << 16) | \
+    ((UInt32)((const Byte *)(p))[2] <<  8) | \
+             ((const Byte *)(p))[3] )
+
+#define GetBe64(p) (((UInt64)GetBe32(p) << 32) | GetBe32(((const Byte *)(p)) + 4))
+
+#endif
+
+#define GetBe16(p) (((UInt16)((const Byte *)(p))[0] << 8) | ((const Byte *)(p))[1])
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
new file mode 100644
--- /dev/null
+++ b/modules/lib7z/LZMASDK/C/Delta.c
@@ -0,0 +1,62 @@
+/* Delta.c -- Delta converter
+2009-05-26 : Igor Pavlov : Public domain */
+
+#include "Delta.h"
+
+void Delta_Init(Byte *state)
+{
+  unsigned i;
+  for (i = 0; i < DELTA_STATE_SIZE; i++)
+    state[i] = 0;
+}
+
+static void MyMemCpy(Byte *dest, const Byte *src, unsigned size)
+{
+  unsigned i;
+  for (i = 0; i < size; i++)
+    dest[i] = src[i];
+}
+
+void Delta_Encode(Byte *state, unsigned delta, Byte *data, SizeT size)
+{
+  Byte buf[DELTA_STATE_SIZE];
+  unsigned j = 0;
+  MyMemCpy(buf, state, delta);
+  {
+    SizeT i;
+    for (i = 0; i < size;)
+    {
+      for (j = 0; j < delta && i < size; i++, j++)
+      {
+        Byte b = data[i];
+        data[i] = (Byte)(b - buf[j]);
+        buf[j] = b;
+      }
+    }
+  }
+  if (j == delta)
+    j = 0;
+  MyMemCpy(state, buf + j, delta - j);
+  MyMemCpy(state + delta - j, buf, j);
+}
+
+void Delta_Decode(Byte *state, unsigned delta, Byte *data, SizeT size)
+{
+  Byte buf[DELTA_STATE_SIZE];
+  unsigned j = 0;
+  MyMemCpy(buf, state, delta);
+  {
+    SizeT i;
+    for (i = 0; i < size;)
+    {
+      for (j = 0; j < delta && i < size; i++, j++)
+      {
+        buf[j] = data[i] = (Byte)(buf[j] + data[i]);
+      }
+    }
+  }
+  if (j == delta)
+    j = 0;
+  MyMemCpy(state, buf + j, delta - j);
+  MyMemCpy(state + delta - j, buf, j);
+}
new file mode 100644
--- /dev/null
+++ b/modules/lib7z/LZMASDK/C/Delta.h
@@ -0,0 +1,23 @@
+/* Delta.h -- Delta converter
+2009-04-15 : Igor Pavlov : Public domain */
+
+#ifndef __DELTA_H
+#define __DELTA_H
+
+#include "Types.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define DELTA_STATE_SIZE 256
+
+void Delta_Init(Byte *state);
+void Delta_Encode(Byte *state, unsigned delta, Byte *data, SizeT size);
+void Delta_Decode(Byte *state, unsigned delta, Byte *data, SizeT size);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
new file mode 100644
--- /dev/null
+++ b/modules/lib7z/LZMASDK/C/LzFind.c
@@ -0,0 +1,761 @@
+/* LzFind.c -- Match finder for LZ algorithms
+2009-04-22 : Igor Pavlov : Public domain */
+
+#include <string.h>
+
+#include "LzFind.h"
+#include "LzHash.h"
+
+#define kEmptyHashValue 0
+#define kMaxValForNormalize ((UInt32)0xFFFFFFFF)
+#define kNormalizeStepMin (1 << 10) /* it must be power of 2 */
+#define kNormalizeMask (~(kNormalizeStepMin - 1))
+#define kMaxHistorySize ((UInt32)3 << 30)
+
+#define kStartMaxLen 3
+
+static void LzInWindow_Free(CMatchFinder *p, ISzAlloc *alloc)
+{
+  if (!p->directInput)
+  {
+    alloc->Free(alloc, p->bufferBase);
+    p->bufferBase = 0;
+  }
+}
+
+/* keepSizeBefore + keepSizeAfter + keepSizeReserv must be < 4G) */
+
+static int LzInWindow_Create(CMatchFinder *p, UInt32 keepSizeReserv, ISzAlloc *alloc)
+{
+  UInt32 blockSize = p->keepSizeBefore + p->keepSizeAfter + keepSizeReserv;
+  if (p->directInput)
+  {
+    p->blockSize = blockSize;
+    return 1;
+  }
+  if (p->bufferBase == 0 || p->blockSize != blockSize)
+  {
+    LzInWindow_Free(p, alloc);
+    p->blockSize = blockSize;
+    p->bufferBase = (Byte *)alloc->Alloc(alloc, (size_t)blockSize);
+  }
+  return (p->bufferBase != 0);
+}
+
+Byte *MatchFinder_GetPointerToCurrentPos(CMatchFinder *p) { return p->buffer; }
+Byte MatchFinder_GetIndexByte(CMatchFinder *p, Int32 index) { return p->buffer[index]; }
+
+UInt32 MatchFinder_GetNumAvailableBytes(CMatchFinder *p) { return p->streamPos - p->pos; }
+
+void MatchFinder_ReduceOffsets(CMatchFinder *p, UInt32 subValue)
+{
+  p->posLimit -= subValue;
+  p->pos -= subValue;
+  p->streamPos -= subValue;
+}
+
+static void MatchFinder_ReadBlock(CMatchFinder *p)
+{
+  if (p->streamEndWasReached || p->result != SZ_OK)
+    return;
+  if (p->directInput)
+  {
+    UInt32 curSize = 0xFFFFFFFF - p->streamPos;
+    if (curSize > p->directInputRem)
+      curSize = (UInt32)p->directInputRem;
+    p->directInputRem -= curSize;
+    p->streamPos += curSize;
+    if (p->directInputRem == 0)
+      p->streamEndWasReached = 1;
+    return;
+  }
+  for (;;)
+  {
+    Byte *dest = p->buffer + (p->streamPos - p->pos);
+    size_t size = (p->bufferBase + p->blockSize - dest);
+    if (size == 0)
+      return;
+    p->result = p->stream->Read(p->stream, dest, &size);
+    if (p->result != SZ_OK)
+      return;
+    if (size == 0)
+    {
+      p->streamEndWasReached = 1;
+      return;
+    }
+    p->streamPos += (UInt32)size;
+    if (p->streamPos - p->pos > p->keepSizeAfter)
+      return;
+  }
+}
+
+void MatchFinder_MoveBlock(CMatchFinder *p)
+{
+  memmove(p->bufferBase,
+    p->buffer - p->keepSizeBefore,
+    (size_t)(p->streamPos - p->pos + p->keepSizeBefore));
+  p->buffer = p->bufferBase + p->keepSizeBefore;
+}
+
+int MatchFinder_NeedMove(CMatchFinder *p)
+{
+  if (p->directInput)
+    return 0;
+  /* if (p->streamEndWasReached) return 0; */
+  return ((size_t)(p->bufferBase + p->blockSize - p->buffer) <= p->keepSizeAfter);
+}
+
+void MatchFinder_ReadIfRequired(CMatchFinder *p)
+{
+  if (p->streamEndWasReached)
+    return;
+  if (p->keepSizeAfter >= p->streamPos - p->pos)
+    MatchFinder_ReadBlock(p);
+}
+
+static void MatchFinder_CheckAndMoveAndRead(CMatchFinder *p)
+{
+  if (MatchFinder_NeedMove(p))
+    MatchFinder_MoveBlock(p);
+  MatchFinder_ReadBlock(p);
+}
+
+static void MatchFinder_SetDefaultSettings(CMatchFinder *p)
+{
+  p->cutValue = 32;
+  p->btMode = 1;
+  p->numHashBytes = 4;
+  p->bigHash = 0;
+}
+
+#define kCrcPoly 0xEDB88320
+
+void MatchFinder_Construct(CMatchFinder *p)
+{
+  UInt32 i;
+  p->bufferBase = 0;
+  p->directInput = 0;
+  p->hash = 0;
+  MatchFinder_SetDefaultSettings(p);
+
+  for (i = 0; i < 256; i++)
+  {
+    UInt32 r = i;
+    int j;
+    for (j = 0; j < 8; j++)
+      r = (r >> 1) ^ (kCrcPoly & ~((r & 1) - 1));
+    p->crc[i] = r;
+  }
+}
+
+static void MatchFinder_FreeThisClassMemory(CMatchFinder *p, ISzAlloc *alloc)
+{
+  alloc->Free(alloc, p->hash);
+  p->hash = 0;
+}
+
+void MatchFinder_Free(CMatchFinder *p, ISzAlloc *alloc)
+{
+  MatchFinder_FreeThisClassMemory(p, alloc);
+  LzInWindow_Free(p, alloc);
+}
+
+static CLzRef* AllocRefs(UInt32 num, ISzAlloc *alloc)
+{
+  size_t sizeInBytes = (size_t)num * sizeof(CLzRef);
+  if (sizeInBytes / sizeof(CLzRef) != num)
+    return 0;
+  return (CLzRef *)alloc->Alloc(alloc, sizeInBytes);
+}
+
+int MatchFinder_Create(CMatchFinder *p, UInt32 historySize,
+    UInt32 keepAddBufferBefore, UInt32 matchMaxLen, UInt32 keepAddBufferAfter,
+    ISzAlloc *alloc)
+{
+  UInt32 sizeReserv;
+  if (historySize > kMaxHistorySize)
+  {
+    MatchFinder_Free(p, alloc);
+    return 0;
+  }
+  sizeReserv = historySize >> 1;
+  if (historySize > ((UInt32)2 << 30))
+    sizeReserv = historySize >> 2;
+  sizeReserv += (keepAddBufferBefore + matchMaxLen + keepAddBufferAfter) / 2 + (1 << 19);
+
+  p->keepSizeBefore = historySize + keepAddBufferBefore + 1;
+  p->keepSizeAfter = matchMaxLen + keepAddBufferAfter;
+  /* we need one additional byte, since we use MoveBlock after pos++ and before dictionary using */
+  if (LzInWindow_Create(p, sizeReserv, alloc))
+  {
+    UInt32 newCyclicBufferSize = historySize + 1;
+    UInt32 hs;
+    p->matchMaxLen = matchMaxLen;
+    {
+      p->fixedHashSize = 0;
+      if (p->numHashBytes == 2)
+        hs = (1 << 16) - 1;
+      else
+      {
+        hs = historySize - 1;
+        hs |= (hs >> 1);
+        hs |= (hs >> 2);
+        hs |= (hs >> 4);
+        hs |= (hs >> 8);
+        hs >>= 1;
+        hs |= 0xFFFF; /* don't change it! It's required for Deflate */
+        if (hs > (1 << 24))
+        {
+          if (p->numHashBytes == 3)
+            hs = (1 << 24) - 1;
+          else
+            hs >>= 1;
+        }
+      }
+      p->hashMask = hs;
+      hs++;
+      if (p->numHashBytes > 2) p->fixedHashSize += kHash2Size;
+      if (p->numHashBytes > 3) p->fixedHashSize += kHash3Size;
+      if (p->numHashBytes > 4) p->fixedHashSize += kHash4Size;
+      hs += p->fixedHashSize;
+    }
+
+    {
+      UInt32 prevSize = p->hashSizeSum + p->numSons;
+      UInt32 newSize;
+      p->historySize = historySize;
+      p->hashSizeSum = hs;
+      p->cyclicBufferSize = newCyclicBufferSize;
+      p->numSons = (p->btMode ? newCyclicBufferSize * 2 : newCyclicBufferSize);
+      newSize = p->hashSizeSum + p->numSons;
+      if (p->hash != 0 && prevSize == newSize)
+        return 1;
+      MatchFinder_FreeThisClassMemory(p, alloc);
+      p->hash = AllocRefs(newSize, alloc);
+      if (p->hash != 0)
+      {
+        p->son = p->hash + p->hashSizeSum;
+        return 1;
+      }
+    }
+  }
+  MatchFinder_Free(p, alloc);
+  return 0;
+}
+
+static void MatchFinder_SetLimits(CMatchFinder *p)
+{
+  UInt32 limit = kMaxValForNormalize - p->pos;
+  UInt32 limit2 = p->cyclicBufferSize - p->cyclicBufferPos;
+  if (limit2 < limit)
+    limit = limit2;
+  limit2 = p->streamPos - p->pos;
+  if (limit2 <= p->keepSizeAfter)
+  {
+    if (limit2 > 0)
+      limit2 = 1;
+  }
+  else
+    limit2 -= p->keepSizeAfter;
+  if (limit2 < limit)
+    limit = limit2;
+  {
+    UInt32 lenLimit = p->streamPos - p->pos;
+    if (lenLimit > p->matchMaxLen)
+      lenLimit = p->matchMaxLen;
+    p->lenLimit = lenLimit;
+  }
+  p->posLimit = p->pos + limit;
+}
+
+void MatchFinder_Init(CMatchFinder *p)
+{
+  UInt32 i;
+  for (i = 0; i < p->hashSizeSum; i++)
+    p->hash[i] = kEmptyHashValue;
+  p->cyclicBufferPos = 0;
+  p->buffer = p->bufferBase;
+  p->pos = p->streamPos = p->cyclicBufferSize;
+  p->result = SZ_OK;
+  p->streamEndWasReached = 0;
+  MatchFinder_ReadBlock(p);
+  MatchFinder_SetLimits(p);
+}
+
+static UInt32 MatchFinder_GetSubValue(CMatchFinder *p)
+{
+  return (p->pos - p->historySize - 1) & kNormalizeMask;
+}
+
+void MatchFinder_Normalize3(UInt32 subValue, CLzRef *items, UInt32 numItems)
+{
+  UInt32 i;
+  for (i = 0; i < numItems; i++)
+  {
+    UInt32 value = items[i];
+    if (value <= subValue)
+      value = kEmptyHashValue;
+    else
+      value -= subValue;
+    items[i] = value;
+  }
+}
+
+static void MatchFinder_Normalize(CMatchFinder *p)
+{
+  UInt32 subValue = MatchFinder_GetSubValue(p);
+  MatchFinder_Normalize3(subValue, p->hash, p->hashSizeSum + p->numSons);
+  MatchFinder_ReduceOffsets(p, subValue);
+}
+
+static void MatchFinder_CheckLimits(CMatchFinder *p)
+{
+  if (p->pos == kMaxValForNormalize)
+    MatchFinder_Normalize(p);
+  if (!p->streamEndWasReached && p->keepSizeAfter == p->streamPos - p->pos)
+    MatchFinder_CheckAndMoveAndRead(p);
+  if (p->cyclicBufferPos == p->cyclicBufferSize)
+    p->cyclicBufferPos = 0;
+  MatchFinder_SetLimits(p);
+}
+
+static UInt32 * Hc_GetMatchesSpec(UInt32 lenLimit, UInt32 curMatch, UInt32 pos, const Byte *cur, CLzRef *son,
+    UInt32 _cyclicBufferPos, UInt32 _cyclicBufferSize, UInt32 cutValue,
+    UInt32 *distances, UInt32 maxLen)
+{
+  son[_cyclicBufferPos] = curMatch;
+  for (;;)
+  {
+    UInt32 delta = pos - curMatch;
+    if (cutValue-- == 0 || delta >= _cyclicBufferSize)
+      return distances;
+    {
+      const Byte *pb = cur - delta;
+      curMatch = son[_cyclicBufferPos - delta + ((delta > _cyclicBufferPos) ? _cyclicBufferSize : 0)];
+      if (pb[maxLen] == cur[maxLen] && *pb == *cur)
+      {
+        UInt32 len = 0;
+        while (++len != lenLimit)
+          if (pb[len] != cur[len])
+            break;
+        if (maxLen < len)
+        {
+          *distances++ = maxLen = len;
+          *distances++ = delta - 1;
+          if (len == lenLimit)
+            return distances;
+        }
+      }
+    }
+  }
+}
+
+UInt32 * GetMatchesSpec1(UInt32 lenLimit, UInt32 curMatch, UInt32 pos, const Byte *cur, CLzRef *son,
+    UInt32 _cyclicBufferPos, UInt32 _cyclicBufferSize, UInt32 cutValue,
+    UInt32 *distances, UInt32 maxLen)
+{
+  CLzRef *ptr0 = son + (_cyclicBufferPos << 1) + 1;
+  CLzRef *ptr1 = son + (_cyclicBufferPos << 1);
+  UInt32 len0 = 0, len1 = 0;
+  for (;;)
+  {
+    UInt32 delta = pos - curMatch;
+    if (cutValue-- == 0 || delta >= _cyclicBufferSize)
+    {
+      *ptr0 = *ptr1 = kEmptyHashValue;
+      return distances;
+    }
+    {
+      CLzRef *pair = son + ((_cyclicBufferPos - delta + ((delta > _cyclicBufferPos) ? _cyclicBufferSize : 0)) << 1);
+      const Byte *pb = cur - delta;
+      UInt32 len = (len0 < len1 ? len0 : len1);
+      if (pb[len] == cur[len])
+      {
+        if (++len != lenLimit && pb[len] == cur[len])
+          while (++len != lenLimit)
+            if (pb[len] != cur[len])
+              break;
+        if (maxLen < len)
+        {
+          *distances++ = maxLen = len;
+          *distances++ = delta - 1;
+          if (len == lenLimit)
+          {
+            *ptr1 = pair[0];
+            *ptr0 = pair[1];
+            return distances;
+          }
+        }
+      }
+      if (pb[len] < cur[len])
+      {
+        *ptr1 = curMatch;
+        ptr1 = pair + 1;
+        curMatch = *ptr1;
+        len1 = len;
+      }
+      else
+      {
+        *ptr0 = curMatch;
+        ptr0 = pair;
+        curMatch = *ptr0;
+        len0 = len;
+      }
+    }
+  }
+}
+
+static void SkipMatchesSpec(UInt32 lenLimit, UInt32 curMatch, UInt32 pos, const Byte *cur, CLzRef *son,
+    UInt32 _cyclicBufferPos, UInt32 _cyclicBufferSize, UInt32 cutValue)
+{
+  CLzRef *ptr0 = son + (_cyclicBufferPos << 1) + 1;
+  CLzRef *ptr1 = son + (_cyclicBufferPos << 1);
+  UInt32 len0 = 0, len1 = 0;
+  for (;;)
+  {
+    UInt32 delta = pos - curMatch;
+    if (cutValue-- == 0 || delta >= _cyclicBufferSize)
+    {
+      *ptr0 = *ptr1 = kEmptyHashValue;
+      return;
+    }
+    {
+      CLzRef *pair = son + ((_cyclicBufferPos - delta + ((delta > _cyclicBufferPos) ? _cyclicBufferSize : 0)) << 1);
+      const Byte *pb = cur - delta;
+      UInt32 len = (len0 < len1 ? len0 : len1);
+      if (pb[len] == cur[len])
+      {
+        while (++len != lenLimit)
+          if (pb[len] != cur[len])
+            break;
+        {
+          if (len == lenLimit)
+          {
+            *ptr1 = pair[0];
+            *ptr0 = pair[1];
+            return;
+          }
+        }
+      }
+      if (pb[len] < cur[len])
+      {
+        *ptr1 = curMatch;
+        ptr1 = pair + 1;
+        curMatch = *ptr1;
+        len1 = len;
+      }
+      else
+      {
+        *ptr0 = curMatch;
+        ptr0 = pair;
+        curMatch = *ptr0;
+        len0 = len;
+      }
+    }
+  }
+}
+
+#define MOVE_POS \
+  ++p->cyclicBufferPos; \
+  p->buffer++; \
+  if (++p->pos == p->posLimit) MatchFinder_CheckLimits(p);
+
+#define MOVE_POS_RET MOVE_POS return offset;
+
+static void MatchFinder_MovePos(CMatchFinder *p) { MOVE_POS; }
+
+#define GET_MATCHES_HEADER2(minLen, ret_op) \
+  UInt32 lenLimit; UInt32 hashValue; const Byte *cur; UInt32 curMatch; \
+  lenLimit = p->lenLimit; { if (lenLimit < minLen) { MatchFinder_MovePos(p); ret_op; }} \
+  cur = p->buffer;
+
+#define GET_MATCHES_HEADER(minLen) GET_MATCHES_HEADER2(minLen, return 0)
+#define SKIP_HEADER(minLen)        GET_MATCHES_HEADER2(minLen, continue)
+
+#define MF_PARAMS(p) p->pos, p->buffer, p->son, p->cyclicBufferPos, p->cyclicBufferSize, p->cutValue
+
+#define GET_MATCHES_FOOTER(offset, maxLen) \
+  offset = (UInt32)(GetMatchesSpec1(lenLimit, curMatch, MF_PARAMS(p), \
+  distances + offset, maxLen) - distances); MOVE_POS_RET;
+
+#define SKIP_FOOTER \
+  SkipMatchesSpec(lenLimit, curMatch, MF_PARAMS(p)); MOVE_POS;
+
+static UInt32 Bt2_MatchFinder_GetMatches(CMatchFinder *p, UInt32 *distances)
+{
+  UInt32 offset;
+  GET_MATCHES_HEADER(2)
+  HASH2_CALC;
+  curMatch = p->hash[hashValue];
+  p->hash[hashValue] = p->pos;
+  offset = 0;
+  GET_MATCHES_FOOTER(offset, 1)
+}
+
+UInt32 Bt3Zip_MatchFinder_GetMatches(CMatchFinder *p, UInt32 *distances)
+{
+  UInt32 offset;
+  GET_MATCHES_HEADER(3)
+  HASH_ZIP_CALC;
+  curMatch = p->hash[hashValue];
+  p->hash[hashValue] = p->pos;
+  offset = 0;
+  GET_MATCHES_FOOTER(offset, 2)
+}
+
+static UInt32 Bt3_MatchFinder_GetMatches(CMatchFinder *p, UInt32 *distances)
+{
+  UInt32 hash2Value, delta2, maxLen, offset;
+  GET_MATCHES_HEADER(3)
+
+  HASH3_CALC;
+
+  delta2 = p->pos - p->hash[hash2Value];
+  curMatch = p->hash[kFix3HashSize + hashValue];
+  
+  p->hash[hash2Value] =
+  p->hash[kFix3HashSize + hashValue] = p->pos;
+
+
+  maxLen = 2;
+  offset = 0;
+  if (delta2 < p->cyclicBufferSize && *(cur - delta2) == *cur)
+  {
+    for (; maxLen != lenLimit; maxLen++)
+      if (cur[(ptrdiff_t)maxLen - delta2] != cur[maxLen])
+        break;
+    distances[0] = maxLen;
+    distances[1] = delta2 - 1;
+    offset = 2;
+    if (maxLen == lenLimit)
+    {
+      SkipMatchesSpec(lenLimit, curMatch, MF_PARAMS(p));
+      MOVE_POS_RET;
+    }
+  }
+  GET_MATCHES_FOOTER(offset, maxLen)
+}
+
+static UInt32 Bt4_MatchFinder_GetMatches(CMatchFinder *p, UInt32 *distances)
+{
+  UInt32 hash2Value, hash3Value, delta2, delta3, maxLen, offset;
+  GET_MATCHES_HEADER(4)
+
+  HASH4_CALC;
+
+  delta2 = p->pos - p->hash[                hash2Value];
+  delta3 = p->pos - p->hash[kFix3HashSize + hash3Value];
+  curMatch = p->hash[kFix4HashSize + hashValue];
+  
+  p->hash[                hash2Value] =
+  p->hash[kFix3HashSize + hash3Value] =
+  p->hash[kFix4HashSize + hashValue] = p->pos;
+
+  maxLen = 1;
+  offset = 0;
+  if (delta2 < p->cyclicBufferSize && *(cur - delta2) == *cur)
+  {
+    distances[0] = maxLen = 2;
+    distances[1] = delta2 - 1;
+    offset = 2;
+  }
+  if (delta2 != delta3 && delta3 < p->cyclicBufferSize && *(cur - delta3) == *cur)
+  {
+    maxLen = 3;
+    distances[offset + 1] = delta3 - 1;
+    offset += 2;
+    delta2 = delta3;
+  }
+  if (offset != 0)
+  {
+    for (; maxLen != lenLimit; maxLen++)
+      if (cur[(ptrdiff_t)maxLen - delta2] != cur[maxLen])
+        break;
+    distances[offset - 2] = maxLen;
+    if (maxLen == lenLimit)
+    {
+      SkipMatchesSpec(lenLimit, curMatch, MF_PARAMS(p));
+      MOVE_POS_RET;
+    }
+  }
+  if (maxLen < 3)
+    maxLen = 3;
+  GET_MATCHES_FOOTER(offset, maxLen)
+}
+
+static UInt32 Hc4_MatchFinder_GetMatches(CMatchFinder *p, UInt32 *distances)
+{
+  UInt32 hash2Value, hash3Value, delta2, delta3, maxLen, offset;
+  GET_MATCHES_HEADER(4)
+
+  HASH4_CALC;
+
+  delta2 = p->pos - p->hash[                hash2Value];
+  delta3 = p->pos - p->hash[kFix3HashSize + hash3Value];
+  curMatch = p->hash[kFix4HashSize + hashValue];
+
+  p->hash[                hash2Value] =
+  p->hash[kFix3HashSize + hash3Value] =
+  p->hash[kFix4HashSize + hashValue] = p->pos;
+
+  maxLen = 1;
+  offset = 0;
+  if (delta2 < p->cyclicBufferSize && *(cur - delta2) == *cur)
+  {
+    distances[0] = maxLen = 2;
+    distances[1] = delta2 - 1;
+    offset = 2;
+  }
+  if (delta2 != delta3 && delta3 < p->cyclicBufferSize && *(cur - delta3) == *cur)
+  {
+    maxLen = 3;
+    distances[offset + 1] = delta3 - 1;
+    offset += 2;
+    delta2 = delta3;
+  }
+  if (offset != 0)
+  {
+    for (; maxLen != lenLimit; maxLen++)
+      if (cur[(ptrdiff_t)maxLen - delta2] != cur[maxLen])
+        break;
+    distances[offset - 2] = maxLen;
+    if (maxLen == lenLimit)
+    {
+      p->son[p->cyclicBufferPos] = curMatch;
+      MOVE_POS_RET;
+    }
+  }
+  if (maxLen < 3)
+    maxLen = 3;
+  offset = (UInt32)(Hc_GetMatchesSpec(lenLimit, curMatch, MF_PARAMS(p),
+    distances + offset, maxLen) - (distances));
+  MOVE_POS_RET
+}
+
+UInt32 Hc3Zip_MatchFinder_GetMatches(CMatchFinder *p, UInt32 *distances)
+{
+  UInt32 offset;
+  GET_MATCHES_HEADER(3)
+  HASH_ZIP_CALC;
+  curMatch = p->hash[hashValue];
+  p->hash[hashValue] = p->pos;
+  offset = (UInt32)(Hc_GetMatchesSpec(lenLimit, curMatch, MF_PARAMS(p),
+    distances, 2) - (distances));
+  MOVE_POS_RET
+}
+
+static void Bt2_MatchFinder_Skip(CMatchFinder *p, UInt32 num)
+{
+  do
+  {
+    SKIP_HEADER(2)
+    HASH2_CALC;
+    curMatch = p->hash[hashValue];
+    p->hash[hashValue] = p->pos;
+    SKIP_FOOTER
+  }
+  while (--num != 0);
+}
+
+void Bt3Zip_MatchFinder_Skip(CMatchFinder *p, UInt32 num)
+{
+  do
+  {
+    SKIP_HEADER(3)
+    HASH_ZIP_CALC;
+    curMatch = p->hash[hashValue];
+    p->hash[hashValue] = p->pos;
+    SKIP_FOOTER
+  }
+  while (--num != 0);
+}
+
+static void Bt3_MatchFinder_Skip(CMatchFinder *p, UInt32 num)
+{
+  do
+  {
+    UInt32 hash2Value;
+    SKIP_HEADER(3)
+    HASH3_CALC;
+    curMatch = p->hash[kFix3HashSize + hashValue];
+    p->hash[hash2Value] =
+    p->hash[kFix3HashSize + hashValue] = p->pos;
+    SKIP_FOOTER
+  }
+  while (--num != 0);
+}
+
+static void Bt4_MatchFinder_Skip(CMatchFinder *p, UInt32 num)
+{
+  do
+  {
+    UInt32 hash2Value, hash3Value;
+    SKIP_HEADER(4)
+    HASH4_CALC;
+    curMatch = p->hash[kFix4HashSize + hashValue];
+    p->hash[                hash2Value] =
+    p->hash[kFix3HashSize + hash3Value] = p->pos;
+    p->hash[kFix4HashSize + hashValue] = p->pos;
+    SKIP_FOOTER
+  }
+  while (--num != 0);
+}
+
+static void Hc4_MatchFinder_Skip(CMatchFinder *p, UInt32 num)
+{
+  do
+  {
+    UInt32 hash2Value, hash3Value;
+    SKIP_HEADER(4)
+    HASH4_CALC;
+    curMatch = p->hash[kFix4HashSize + hashValue];
+    p->hash[                hash2Value] =
+    p->hash[kFix3HashSize + hash3Value] =
+    p->hash[kFix4HashSize + hashValue] = p->pos;
+    p->son[p->cyclicBufferPos] = curMatch;
+    MOVE_POS
+  }
+  while (--num != 0);
+}
+
+void Hc3Zip_MatchFinder_Skip(CMatchFinder *p, UInt32 num)
+{
+  do
+  {
+    SKIP_HEADER(3)
+    HASH_ZIP_CALC;
+    curMatch = p->hash[hashValue];
+    p->hash[hashValue] = p->pos;
+    p->son[p->cyclicBufferPos] = curMatch;
+    MOVE_POS
+  }
+  while (--num != 0);
+}
+
+void MatchFinder_CreateVTable(CMatchFinder *p, IMatchFinder *vTable)
+{
+  vTable->Init = (Mf_Init_Func)MatchFinder_Init;
+  vTable->GetIndexByte = (Mf_GetIndexByte_Func)MatchFinder_GetIndexByte;
+  vTable->GetNumAvailableBytes = (Mf_GetNumAvailableBytes_Func)MatchFinder_GetNumAvailableBytes;
+  vTable->GetPointerToCurrentPos = (Mf_GetPointerToCurrentPos_Func)MatchFinder_GetPointerToCurrentPos;
+  if (!p->btMode)
+  {
+    vTable->GetMatches = (Mf_GetMatches_Func)Hc4_MatchFinder_GetMatches;
+    vTable->Skip = (Mf_Skip_Func)Hc4_MatchFinder_Skip;
+  }
+  else if (p->numHashBytes == 2)
+  {
+    vTable->GetMatches = (Mf_GetMatches_Func)Bt2_MatchFinder_GetMatches;
+    vTable->Skip = (Mf_Skip_Func)Bt2_MatchFinder_Skip;
+  }
+  else if (p->numHashBytes == 3)
+  {
+    vTable->GetMatches = (Mf_GetMatches_Func)Bt3_MatchFinder_GetMatches;
+    vTable->Skip = (Mf_Skip_Func)Bt3_MatchFinder_Skip;
+  }
+  else
+  {
+    vTable->GetMatches = (Mf_GetMatches_Func)Bt4_MatchFinder_GetMatches;
+    vTable->Skip = (Mf_Skip_Func)Bt4_MatchFinder_Skip;
+  }
+}
new file mode 100644
--- /dev/null
+++ b/modules/lib7z/LZMASDK/C/LzFind.h
@@ -0,0 +1,115 @@
+/* LzFind.h -- Match finder for LZ algorithms
+2009-04-22 : Igor Pavlov : Public domain */
+
+#ifndef __LZ_FIND_H
+#define __LZ_FIND_H
+
+#include "Types.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+typedef UInt32 CLzRef;
+
+typedef struct _CMatchFinder
+{
+  Byte *buffer;
+  UInt32 pos;
+  UInt32 posLimit;
+  UInt32 streamPos;
+  UInt32 lenLimit;
+
+  UInt32 cyclicBufferPos;
+  UInt32 cyclicBufferSize; /* it must be = (historySize + 1) */
+
+  UInt32 matchMaxLen;
+  CLzRef *hash;
+  CLzRef *son;
+  UInt32 hashMask;
+  UInt32 cutValue;
+
+  Byte *bufferBase;
+  ISeqInStream *stream;
+  int streamEndWasReached;
+
+  UInt32 blockSize;
+  UInt32 keepSizeBefore;
+  UInt32 keepSizeAfter;
+
+  UInt32 numHashBytes;
+  int directInput;
+  size_t directInputRem;
+  int btMode;
+  int bigHash;
+  UInt32 historySize;
+  UInt32 fixedHashSize;
+  UInt32 hashSizeSum;
+  UInt32 numSons;
+  SRes result;
+  UInt32 crc[256];
+} CMatchFinder;
+
+#define Inline_MatchFinder_GetPointerToCurrentPos(p) ((p)->buffer)
+#define Inline_MatchFinder_GetIndexByte(p, index) ((p)->buffer[(Int32)(index)])
+
+#define Inline_MatchFinder_GetNumAvailableBytes(p) ((p)->streamPos - (p)->pos)
+
+int MatchFinder_NeedMove(CMatchFinder *p);
+Byte *MatchFinder_GetPointerToCurrentPos(CMatchFinder *p);
+void MatchFinder_MoveBlock(CMatchFinder *p);
+void MatchFinder_ReadIfRequired(CMatchFinder *p);
+
+void MatchFinder_Construct(CMatchFinder *p);
+
+/* Conditions:
+     historySize <= 3 GB
+     keepAddBufferBefore + matchMaxLen + keepAddBufferAfter < 511MB
+*/
+int MatchFinder_Create(CMatchFinder *p, UInt32 historySize,
+    UInt32 keepAddBufferBefore, UInt32 matchMaxLen, UInt32 keepAddBufferAfter,
+    ISzAlloc *alloc);
+void MatchFinder_Free(CMatchFinder *p, ISzAlloc *alloc);
+void MatchFinder_Normalize3(UInt32 subValue, CLzRef *items, UInt32 numItems);
+void MatchFinder_ReduceOffsets(CMatchFinder *p, UInt32 subValue);
+
+UInt32 * GetMatchesSpec1(UInt32 lenLimit, UInt32 curMatch, UInt32 pos, const Byte *buffer, CLzRef *son,
+    UInt32 _cyclicBufferPos, UInt32 _cyclicBufferSize, UInt32 _cutValue,
+    UInt32 *distances, UInt32 maxLen);
+
+/*
+Conditions:
+  Mf_GetNumAvailableBytes_Func must be called before each Mf_GetMatchLen_Func.
+  Mf_GetPointerToCurrentPos_Func's result must be used only before any other function
+*/
+
+typedef void (*Mf_Init_Func)(void *object);
+typedef Byte (*Mf_GetIndexByte_Func)(void *object, Int32 index);
+typedef UInt32 (*Mf_GetNumAvailableBytes_Func)(void *object);
+typedef const Byte * (*Mf_GetPointerToCurrentPos_Func)(void *object);
+typedef UInt32 (*Mf_GetMatches_Func)(void *object, UInt32 *distances);
+typedef void (*Mf_Skip_Func)(void *object, UInt32);
+
+typedef struct _IMatchFinder
+{
+  Mf_Init_Func Init;
+  Mf_GetIndexByte_Func GetIndexByte;
+  Mf_GetNumAvailableBytes_Func GetNumAvailableBytes;
+  Mf_GetPointerToCurrentPos_Func GetPointerToCurrentPos;
+  Mf_GetMatches_Func GetMatches;
+  Mf_Skip_Func Skip;
+} IMatchFinder;
+
+void MatchFinder_CreateVTable(CMatchFinder *p, IMatchFinder *vTable);
+
+void MatchFinder_Init(CMatchFinder *p);
+UInt32 Bt3Zip_MatchFinder_GetMatches(CMatchFinder *p, UInt32 *distances);
+UInt32 Hc3Zip_MatchFinder_GetMatches(CMatchFinder *p, UInt32 *distances);
+void Bt3Zip_MatchFinder_Skip(CMatchFinder *p, UInt32 num);
+void Hc3Zip_MatchFinder_Skip(CMatchFinder *p, UInt32 num);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
new file mode 100644
--- /dev/null
+++ b/modules/lib7z/LZMASDK/C/LzFindMt.c
@@ -0,0 +1,793 @@
+/* LzFindMt.c -- multithreaded Match finder for LZ algorithms
+2009-05-26 : Igor Pavlov : Public domain */
+
+#include "LzHash.h"
+
+#include "LzFindMt.h"
+
+void MtSync_Construct(CMtSync *p)
+{
+  p->wasCreated = False;
+  p->csWasInitialized = False;
+  p->csWasEntered = False;
+  Thread_Construct(&p->thread);
+  Event_Construct(&p->canStart);
+  Event_Construct(&p->wasStarted);
+  Event_Construct(&p->wasStopped);
+  Semaphore_Construct(&p->freeSemaphore);
+  Semaphore_Construct(&p->filledSemaphore);
+}
+
+void MtSync_GetNextBlock(CMtSync *p)
+{
+  if (p->needStart)
+  {
+    p->numProcessedBlocks = 1;
+    p->needStart = False;
+    p->stopWriting = False;
+    p->exit = False;
+    Event_Reset(&p->wasStarted);
+    Event_Reset(&p->wasStopped);
+
+    Event_Set(&p->canStart);
+    Event_Wait(&p->wasStarted);
+  }
+  else
+  {
+    CriticalSection_Leave(&p->cs);
+    p->csWasEntered = False;
+    p->numProcessedBlocks++;
+    Semaphore_Release1(&p->freeSemaphore);
+  }
+  Semaphore_Wait(&p->filledSemaphore);
+  CriticalSection_Enter(&p->cs);
+  p->csWasEntered = True;
+}
+
+/* MtSync_StopWriting must be called if Writing was started */
+
+void MtSync_StopWriting(CMtSync *p)
+{
+  UInt32 myNumBlocks = p->numProcessedBlocks;
+  if (!Thread_WasCreated(&p->thread) || p->needStart)
+    return;
+  p->stopWriting = True;
+  if (p->csWasEntered)
+  {
+    CriticalSection_Leave(&p->cs);
+    p->csWasEntered = False;
+  }
+  Semaphore_Release1(&p->freeSemaphore);
+ 
+  Event_Wait(&p->wasStopped);
+
+  while (myNumBlocks++ != p->numProcessedBlocks)
+  {
+    Semaphore_Wait(&p->filledSemaphore);
+    Semaphore_Release1(&p->freeSemaphore);
+  }
+  p->needStart = True;
+}
+
+void MtSync_Destruct(CMtSync *p)
+{
+  if (Thread_WasCreated(&p->thread))
+  {
+    MtSync_StopWriting(p);
+    p->exit = True;
+    if (p->needStart)
+      Event_Set(&p->canStart);
+    Thread_Wait(&p->thread);
+    Thread_Close(&p->thread);
+  }
+  if (p->csWasInitialized)
+  {
+    CriticalSection_Delete(&p->cs);
+    p->csWasInitialized = False;
+  }
+
+  Event_Close(&p->canStart);
+  Event_Close(&p->wasStarted);
+  Event_Close(&p->wasStopped);
+  Semaphore_Close(&p->freeSemaphore);
+  Semaphore_Close(&p->filledSemaphore);
+
+  p->wasCreated = False;
+}
+
+#define RINOK_THREAD(x) { if ((x) != 0) return SZ_ERROR_THREAD; }
+
+static SRes MtSync_Create2(CMtSync *p, unsigned (MY_STD_CALL *startAddress)(void *), void *obj, UInt32 numBlocks)
+{
+  if (p->wasCreated)
+    return SZ_OK;
+
+  RINOK_THREAD(CriticalSection_Init(&p->cs));
+  p->csWasInitialized = True;
+
+  RINOK_THREAD(AutoResetEvent_CreateNotSignaled(&p->canStart));
+  RINOK_THREAD(AutoResetEvent_CreateNotSignaled(&p->wasStarted));
+  RINOK_THREAD(AutoResetEvent_CreateNotSignaled(&p->wasStopped));
+  
+  RINOK_THREAD(Semaphore_Create(&p->freeSemaphore, numBlocks, numBlocks));
+  RINOK_THREAD(Semaphore_Create(&p->filledSemaphore, 0, numBlocks));
+
+  p->needStart = True;
+  
+  RINOK_THREAD(Thread_Create(&p->thread, startAddress, obj));
+  p->wasCreated = True;
+  return SZ_OK;
+}
+
+static SRes MtSync_Create(CMtSync *p, unsigned (MY_STD_CALL *startAddress)(void *), void *obj, UInt32 numBlocks)
+{
+  SRes res = MtSync_Create2(p, startAddress, obj, numBlocks);
+  if (res != SZ_OK)
+    MtSync_Destruct(p);
+  return res;
+}
+
+void MtSync_Init(CMtSync *p) { p->needStart = True; }
+
+#define kMtMaxValForNormalize 0xFFFFFFFF
+
+#define DEF_GetHeads2(name, v, action) \
+static void GetHeads ## name(const Byte *p, UInt32 pos, \
+UInt32 *hash, UInt32 hashMask, UInt32 *heads, UInt32 numHeads, const UInt32 *crc) \
+{ action; for (; numHeads != 0; numHeads--) { \
+const UInt32 value = (v); p++; *heads++ = pos - hash[value]; hash[value] = pos++;  } }
+
+#define DEF_GetHeads(name, v) DEF_GetHeads2(name, v, ;)
+
+DEF_GetHeads2(2,  (p[0] | ((UInt32)p[1] << 8)), hashMask = hashMask; crc = crc; )
+DEF_GetHeads(3,  (crc[p[0]] ^ p[1] ^ ((UInt32)p[2] << 8)) & hashMask)
+DEF_GetHeads(4,  (crc[p[0]] ^ p[1] ^ ((UInt32)p[2] << 8) ^ (crc[p[3]] << 5)) & hashMask)
+DEF_GetHeads(4b, (crc[p[0]] ^ p[1] ^ ((UInt32)p[2] << 8) ^ ((UInt32)p[3] << 16)) & hashMask)
+/* DEF_GetHeads(5,  (crc[p[0]] ^ p[1] ^ ((UInt32)p[2] << 8) ^ (crc[p[3]] << 5) ^ (crc[p[4]] << 3)) & hashMask) */
+
+void HashThreadFunc(CMatchFinderMt *mt)
+{
+  CMtSync *p = &mt->hashSync;
+  for (;;)
+  {
+    UInt32 numProcessedBlocks = 0;
+    Event_Wait(&p->canStart);
+    Event_Set(&p->wasStarted);
+    for (;;)
+    {
+      if (p->exit)
+        return;
+      if (p->stopWriting)
+      {
+        p->numProcessedBlocks = numProcessedBlocks;
+        Event_Set(&p->wasStopped);
+        break;
+      }
+
+      {
+        CMatchFinder *mf = mt->MatchFinder;
+        if (MatchFinder_NeedMove(mf))
+        {
+          CriticalSection_Enter(&mt->btSync.cs);
+          CriticalSection_Enter(&mt->hashSync.cs);
+          {
+            const Byte *beforePtr = MatchFinder_GetPointerToCurrentPos(mf);
+            const Byte *afterPtr;
+            MatchFinder_MoveBlock(mf);
+            afterPtr = MatchFinder_GetPointerToCurrentPos(mf);
+            mt->pointerToCurPos -= beforePtr - afterPtr;
+            mt->buffer -= beforePtr - afterPtr;
+          }
+          CriticalSection_Leave(&mt->btSync.cs);
+          CriticalSection_Leave(&mt->hashSync.cs);
+          continue;
+        }
+
+        Semaphore_Wait(&p->freeSemaphore);
+
+        MatchFinder_ReadIfRequired(mf);
+        if (mf->pos > (kMtMaxValForNormalize - kMtHashBlockSize))
+        {
+          UInt32 subValue = (mf->pos - mf->historySize - 1);
+          MatchFinder_ReduceOffsets(mf, subValue);
+          MatchFinder_Normalize3(subValue, mf->hash + mf->fixedHashSize, mf->hashMask + 1);
+        }
+        {
+          UInt32 *heads = mt->hashBuf + ((numProcessedBlocks++) & kMtHashNumBlocksMask) * kMtHashBlockSize;
+          UInt32 num = mf->streamPos - mf->pos;
+          heads[0] = 2;
+          heads[1] = num;
+          if (num >= mf->numHashBytes)
+          {
+            num = num - mf->numHashBytes + 1;
+            if (num > kMtHashBlockSize - 2)
+              num = kMtHashBlockSize - 2;
+            mt->GetHeadsFunc(mf->buffer, mf->pos, mf->hash + mf->fixedHashSize, mf->hashMask, heads + 2, num, mf->crc);
+            heads[0] += num;
+          }
+          mf->pos += num;
+          mf->buffer += num;
+        }
+      }
+
+      Semaphore_Release1(&p->filledSemaphore);
+    }
+  }
+}
+
+void MatchFinderMt_GetNextBlock_Hash(CMatchFinderMt *p)
+{
+  MtSync_GetNextBlock(&p->hashSync);
+  p->hashBufPosLimit = p->hashBufPos = ((p->hashSync.numProcessedBlocks - 1) & kMtHashNumBlocksMask) * kMtHashBlockSize;
+  p->hashBufPosLimit += p->hashBuf[p->hashBufPos++];
+  p->hashNumAvail = p->hashBuf[p->hashBufPos++];
+}
+
+#define kEmptyHashValue 0
+
+/* #define MFMT_GM_INLINE */
+
+#ifdef MFMT_GM_INLINE
+
+#define NO_INLINE MY_FAST_CALL
+
+Int32 NO_INLINE GetMatchesSpecN(UInt32 lenLimit, UInt32 pos, const Byte *cur, CLzRef *son,
+    UInt32 _cyclicBufferPos, UInt32 _cyclicBufferSize, UInt32 _cutValue,
+    UInt32 *_distances, UInt32 _maxLen, const UInt32 *hash, Int32 limit, UInt32 size, UInt32 *posRes)
+{
+  do
+  {
+  UInt32 *distances = _distances + 1;
+  UInt32 curMatch = pos - *hash++;
+
+  CLzRef *ptr0 = son + (_cyclicBufferPos << 1) + 1;
+  CLzRef *ptr1 = son + (_cyclicBufferPos << 1);
+  UInt32 len0 = 0, len1 = 0;
+  UInt32 cutValue = _cutValue;
+  UInt32 maxLen = _maxLen;
+  for (;;)
+  {
+    UInt32 delta = pos - curMatch;
+    if (cutValue-- == 0 || delta >= _cyclicBufferSize)
+    {
+      *ptr0 = *ptr1 = kEmptyHashValue;
+      break;
+    }
+    {
+      CLzRef *pair = son + ((_cyclicBufferPos - delta + ((delta > _cyclicBufferPos) ? _cyclicBufferSize : 0)) << 1);
+      const Byte *pb = cur - delta;
+      UInt32 len = (len0 < len1 ? len0 : len1);
+      if (pb[len] == cur[len])
+      {
+        if (++len != lenLimit && pb[len] == cur[len])
+          while (++len != lenLimit)
+            if (pb[len] != cur[len])
+              break;
+        if (maxLen < len)
+        {
+          *distances++ = maxLen = len;
+          *distances++ = delta - 1;
+          if (len == lenLimit)
+          {
+            *ptr1 = pair[0];
+            *ptr0 = pair[1];
+            break;
+          }
+        }
+      }
+      if (pb[len] < cur[len])
+      {
+        *ptr1 = curMatch;
+        ptr1 = pair + 1;
+        curMatch = *ptr1;
+        len1 = len;
+      }
+      else
+      {
+        *ptr0 = curMatch;
+        ptr0 = pair;
+        curMatch = *ptr0;
+        len0 = len;
+      }
+    }
+  }
+  pos++;
+  _cyclicBufferPos++;
+  cur++;
+  {
+    UInt32 num = (UInt32)(distances - _distances);
+    *_distances = num - 1;
+    _distances += num;
+    limit -= num;
+  }
+  }
+  while (limit > 0 && --size != 0);
+  *posRes = pos;
+  return limit;
+}
+
+#endif
+
+void BtGetMatches(CMatchFinderMt *p, UInt32 *distances)
+{
+  UInt32 numProcessed = 0;
+  UInt32 curPos = 2;
+  UInt32 limit = kMtBtBlockSize - (p->matchMaxLen * 2);
+  distances[1] = p->hashNumAvail;
+  while (curPos < limit)
+  {
+    if (p->hashBufPos == p->hashBufPosLimit)
+    {
+      MatchFinderMt_GetNextBlock_Hash(p);
+      distances[1] = numProcessed + p->hashNumAvail;
+      if (p->hashNumAvail >= p->numHashBytes)
+        continue;
+      for (; p->hashNumAvail != 0; p->hashNumAvail--)
+        distances[curPos++] = 0;
+      break;
+    }
+    {
+      UInt32 size = p->hashBufPosLimit - p->hashBufPos;
+      UInt32 lenLimit = p->matchMaxLen;
+      UInt32 pos = p->pos;
+      UInt32 cyclicBufferPos = p->cyclicBufferPos;
+      if (lenLimit >= p->hashNumAvail)
+        lenLimit = p->hashNumAvail;
+      {
+        UInt32 size2 = p->hashNumAvail - lenLimit + 1;
+        if (size2 < size)
+          size = size2;
+