bulk copy of latest physfs to our misc/libphysfs since this seems to fix an off-by-1 error reliably hit in readln read of 1 byte probably introduced in the addition of the buffered read. Whether this is excessive or whether libphysfs should even be maintained by us is another matter. But at least we shouldn't crash
authornemo
Mon, 10 Apr 2017 12:06:43 -0400
changeset 12213 bb5522e88ab2
parent 12212 ea891871f481
child 12214 facbc3c6e166
bulk copy of latest physfs to our misc/libphysfs since this seems to fix an off-by-1 error reliably hit in readln read of 1 byte probably introduced in the addition of the buffered read. Whether this is excessive or whether libphysfs should even be maintained by us is another matter. But at least we shouldn't crash
misc/libphysfs/archiver_dir.c
misc/libphysfs/archiver_grp.c
misc/libphysfs/archiver_hog.c
misc/libphysfs/archiver_iso9660.c
misc/libphysfs/archiver_lzma.c
misc/libphysfs/archiver_mvl.c
misc/libphysfs/archiver_qpak.c
misc/libphysfs/archiver_slb.c
misc/libphysfs/archiver_unpacked.c
misc/libphysfs/archiver_wad.c
misc/libphysfs/archiver_zip.c
misc/libphysfs/lzma/7zC.txt
misc/libphysfs/lzma/7zFormat.txt
misc/libphysfs/lzma/C/7zCrc.c
misc/libphysfs/lzma/C/7zCrc.h
misc/libphysfs/lzma/C/7zCrcT8.c
misc/libphysfs/lzma/C/Alloc.c
misc/libphysfs/lzma/C/Alloc.h
misc/libphysfs/lzma/C/Archive/7z/7zAlloc.c
misc/libphysfs/lzma/C/Archive/7z/7zAlloc.h
misc/libphysfs/lzma/C/Archive/7z/7zBuffer.c
misc/libphysfs/lzma/C/Archive/7z/7zBuffer.h
misc/libphysfs/lzma/C/Archive/7z/7zDecode.c
misc/libphysfs/lzma/C/Archive/7z/7zDecode.h
misc/libphysfs/lzma/C/Archive/7z/7zExtract.c
misc/libphysfs/lzma/C/Archive/7z/7zExtract.h
misc/libphysfs/lzma/C/Archive/7z/7zHeader.c
misc/libphysfs/lzma/C/Archive/7z/7zHeader.h
misc/libphysfs/lzma/C/Archive/7z/7zIn.c
misc/libphysfs/lzma/C/Archive/7z/7zIn.h
misc/libphysfs/lzma/C/Archive/7z/7zItem.c
misc/libphysfs/lzma/C/Archive/7z/7zItem.h
misc/libphysfs/lzma/C/Archive/7z/7zMain.c
misc/libphysfs/lzma/C/Archive/7z/7zMethodID.c
misc/libphysfs/lzma/C/Archive/7z/7zMethodID.h
misc/libphysfs/lzma/C/Archive/7z/7z_C.dsp
misc/libphysfs/lzma/C/Archive/7z/7z_C.dsw
misc/libphysfs/lzma/C/Archive/7z/makefile
misc/libphysfs/lzma/C/Archive/7z/makefile.gcc
misc/libphysfs/lzma/C/Compress/Branch/BranchARM.c
misc/libphysfs/lzma/C/Compress/Branch/BranchARM.h
misc/libphysfs/lzma/C/Compress/Branch/BranchARMThumb.c
misc/libphysfs/lzma/C/Compress/Branch/BranchARMThumb.h
misc/libphysfs/lzma/C/Compress/Branch/BranchIA64.c
misc/libphysfs/lzma/C/Compress/Branch/BranchIA64.h
misc/libphysfs/lzma/C/Compress/Branch/BranchPPC.c
misc/libphysfs/lzma/C/Compress/Branch/BranchPPC.h
misc/libphysfs/lzma/C/Compress/Branch/BranchSPARC.c
misc/libphysfs/lzma/C/Compress/Branch/BranchSPARC.h
misc/libphysfs/lzma/C/Compress/Branch/BranchTypes.h
misc/libphysfs/lzma/C/Compress/Branch/BranchX86.c
misc/libphysfs/lzma/C/Compress/Branch/BranchX86.h
misc/libphysfs/lzma/C/Compress/Branch/BranchX86_2.c
misc/libphysfs/lzma/C/Compress/Branch/BranchX86_2.h
misc/libphysfs/lzma/C/Compress/Huffman/HuffmanEncode.c
misc/libphysfs/lzma/C/Compress/Huffman/HuffmanEncode.h
misc/libphysfs/lzma/C/Compress/Lz/LzHash.h
misc/libphysfs/lzma/C/Compress/Lz/MatchFinder.c
misc/libphysfs/lzma/C/Compress/Lz/MatchFinder.h
misc/libphysfs/lzma/C/Compress/Lz/MatchFinderMt.c
misc/libphysfs/lzma/C/Compress/Lz/MatchFinderMt.h
misc/libphysfs/lzma/C/Compress/Lzma/LzmaDecode.c
misc/libphysfs/lzma/C/Compress/Lzma/LzmaDecode.h
misc/libphysfs/lzma/C/Compress/Lzma/LzmaDecodeSize.c
misc/libphysfs/lzma/C/Compress/Lzma/LzmaStateDecode.c
misc/libphysfs/lzma/C/Compress/Lzma/LzmaStateDecode.h
misc/libphysfs/lzma/C/Compress/Lzma/LzmaStateTest.c
misc/libphysfs/lzma/C/Compress/Lzma/LzmaTest.c
misc/libphysfs/lzma/C/Compress/Lzma/LzmaTypes.h
misc/libphysfs/lzma/C/CpuArch.h
misc/libphysfs/lzma/C/IStream.h
misc/libphysfs/lzma/C/Sort.c
misc/libphysfs/lzma/C/Sort.h
misc/libphysfs/lzma/C/Threads.c
misc/libphysfs/lzma/C/Threads.h
misc/libphysfs/lzma/C/Types.h
misc/libphysfs/lzma/CPP/7zip/Archive/7z/7z.ico
misc/libphysfs/lzma/CPP/7zip/Archive/7z/7zCompressionMode.cpp
misc/libphysfs/lzma/CPP/7zip/Archive/7z/7zCompressionMode.h
misc/libphysfs/lzma/CPP/7zip/Archive/7z/7zDecode.cpp
misc/libphysfs/lzma/CPP/7zip/Archive/7z/7zDecode.h
misc/libphysfs/lzma/CPP/7zip/Archive/7z/7zEncode.cpp
misc/libphysfs/lzma/CPP/7zip/Archive/7z/7zEncode.h
misc/libphysfs/lzma/CPP/7zip/Archive/7z/7zExtract.cpp
misc/libphysfs/lzma/CPP/7zip/Archive/7z/7zFolderInStream.cpp
misc/libphysfs/lzma/CPP/7zip/Archive/7z/7zFolderInStream.h
misc/libphysfs/lzma/CPP/7zip/Archive/7z/7zFolderOutStream.cpp
misc/libphysfs/lzma/CPP/7zip/Archive/7z/7zFolderOutStream.h
misc/libphysfs/lzma/CPP/7zip/Archive/7z/7zHandler.cpp
misc/libphysfs/lzma/CPP/7zip/Archive/7z/7zHandler.h
misc/libphysfs/lzma/CPP/7zip/Archive/7z/7zHandlerOut.cpp
misc/libphysfs/lzma/CPP/7zip/Archive/7z/7zHeader.cpp
misc/libphysfs/lzma/CPP/7zip/Archive/7z/7zHeader.h
misc/libphysfs/lzma/CPP/7zip/Archive/7z/7zIn.cpp
misc/libphysfs/lzma/CPP/7zip/Archive/7z/7zIn.h
misc/libphysfs/lzma/CPP/7zip/Archive/7z/7zItem.h
misc/libphysfs/lzma/CPP/7zip/Archive/7z/7zOut.cpp
misc/libphysfs/lzma/CPP/7zip/Archive/7z/7zOut.h
misc/libphysfs/lzma/CPP/7zip/Archive/7z/7zProperties.cpp
misc/libphysfs/lzma/CPP/7zip/Archive/7z/7zProperties.h
misc/libphysfs/lzma/CPP/7zip/Archive/7z/7zRegister.cpp
misc/libphysfs/lzma/CPP/7zip/Archive/7z/7zSpecStream.cpp
misc/libphysfs/lzma/CPP/7zip/Archive/7z/7zSpecStream.h
misc/libphysfs/lzma/CPP/7zip/Archive/7z/7zUpdate.cpp
misc/libphysfs/lzma/CPP/7zip/Archive/7z/7zUpdate.h
misc/libphysfs/lzma/CPP/7zip/Archive/7z/StdAfx.cpp
misc/libphysfs/lzma/CPP/7zip/Archive/7z/StdAfx.h
misc/libphysfs/lzma/CPP/7zip/Archive/Archive.def
misc/libphysfs/lzma/CPP/7zip/Archive/Archive2.def
misc/libphysfs/lzma/CPP/7zip/Archive/ArchiveExports.cpp
misc/libphysfs/lzma/CPP/7zip/Archive/Common/CoderMixer2.cpp
misc/libphysfs/lzma/CPP/7zip/Archive/Common/CoderMixer2.h
misc/libphysfs/lzma/CPP/7zip/Archive/Common/CoderMixer2MT.cpp
misc/libphysfs/lzma/CPP/7zip/Archive/Common/CoderMixer2MT.h
misc/libphysfs/lzma/CPP/7zip/Archive/Common/CrossThreadProgress.cpp
misc/libphysfs/lzma/CPP/7zip/Archive/Common/CrossThreadProgress.h
misc/libphysfs/lzma/CPP/7zip/Archive/Common/DummyOutStream.cpp
misc/libphysfs/lzma/CPP/7zip/Archive/Common/DummyOutStream.h
misc/libphysfs/lzma/CPP/7zip/Archive/Common/HandlerOut.cpp
misc/libphysfs/lzma/CPP/7zip/Archive/Common/HandlerOut.h
misc/libphysfs/lzma/CPP/7zip/Archive/Common/InStreamWithCRC.cpp
misc/libphysfs/lzma/CPP/7zip/Archive/Common/InStreamWithCRC.h
misc/libphysfs/lzma/CPP/7zip/Archive/Common/ItemNameUtils.cpp
misc/libphysfs/lzma/CPP/7zip/Archive/Common/ItemNameUtils.h
misc/libphysfs/lzma/CPP/7zip/Archive/Common/MultiStream.cpp
misc/libphysfs/lzma/CPP/7zip/Archive/Common/MultiStream.h
misc/libphysfs/lzma/CPP/7zip/Archive/Common/OutStreamWithCRC.cpp
misc/libphysfs/lzma/CPP/7zip/Archive/Common/OutStreamWithCRC.h
misc/libphysfs/lzma/CPP/7zip/Archive/Common/ParseProperties.cpp
misc/libphysfs/lzma/CPP/7zip/Archive/Common/ParseProperties.h
misc/libphysfs/lzma/CPP/7zip/Archive/DllExports2.cpp
misc/libphysfs/lzma/CPP/7zip/Archive/IArchive.h
misc/libphysfs/lzma/CPP/7zip/Bundles/Alone7z/Alone.dsp
misc/libphysfs/lzma/CPP/7zip/Bundles/Alone7z/Alone.dsw
misc/libphysfs/lzma/CPP/7zip/Bundles/Alone7z/StdAfx.cpp
misc/libphysfs/lzma/CPP/7zip/Bundles/Alone7z/StdAfx.h
misc/libphysfs/lzma/CPP/7zip/Bundles/Alone7z/makefile
misc/libphysfs/lzma/CPP/7zip/Bundles/Alone7z/resource.rc
misc/libphysfs/lzma/CPP/7zip/Bundles/Format7zExtractR/StdAfx.cpp
misc/libphysfs/lzma/CPP/7zip/Bundles/Format7zExtractR/StdAfx.h
misc/libphysfs/lzma/CPP/7zip/Bundles/Format7zExtractR/makefile
misc/libphysfs/lzma/CPP/7zip/Bundles/Format7zExtractR/resource.rc
misc/libphysfs/lzma/CPP/7zip/Bundles/Format7zR/StdAfx.cpp
misc/libphysfs/lzma/CPP/7zip/Bundles/Format7zR/StdAfx.h
misc/libphysfs/lzma/CPP/7zip/Bundles/Format7zR/makefile
misc/libphysfs/lzma/CPP/7zip/Bundles/Format7zR/resource.rc
misc/libphysfs/lzma/CPP/7zip/Common/CreateCoder.cpp
misc/libphysfs/lzma/CPP/7zip/Common/CreateCoder.h
misc/libphysfs/lzma/CPP/7zip/Common/FilePathAutoRename.cpp
misc/libphysfs/lzma/CPP/7zip/Common/FilePathAutoRename.h
misc/libphysfs/lzma/CPP/7zip/Common/FileStreams.cpp
misc/libphysfs/lzma/CPP/7zip/Common/FileStreams.h
misc/libphysfs/lzma/CPP/7zip/Common/FilterCoder.cpp
misc/libphysfs/lzma/CPP/7zip/Common/FilterCoder.h
misc/libphysfs/lzma/CPP/7zip/Common/InBuffer.cpp
misc/libphysfs/lzma/CPP/7zip/Common/InBuffer.h
misc/libphysfs/lzma/CPP/7zip/Common/InOutTempBuffer.cpp
misc/libphysfs/lzma/CPP/7zip/Common/InOutTempBuffer.h
misc/libphysfs/lzma/CPP/7zip/Common/LimitedStreams.cpp
misc/libphysfs/lzma/CPP/7zip/Common/LimitedStreams.h
misc/libphysfs/lzma/CPP/7zip/Common/LockedStream.cpp
misc/libphysfs/lzma/CPP/7zip/Common/LockedStream.h
misc/libphysfs/lzma/CPP/7zip/Common/MethodId.cpp
misc/libphysfs/lzma/CPP/7zip/Common/MethodId.h
misc/libphysfs/lzma/CPP/7zip/Common/MethodProps.cpp
misc/libphysfs/lzma/CPP/7zip/Common/MethodProps.h
misc/libphysfs/lzma/CPP/7zip/Common/OffsetStream.cpp
misc/libphysfs/lzma/CPP/7zip/Common/OffsetStream.h
misc/libphysfs/lzma/CPP/7zip/Common/OutBuffer.cpp
misc/libphysfs/lzma/CPP/7zip/Common/OutBuffer.h
misc/libphysfs/lzma/CPP/7zip/Common/ProgressUtils.cpp
misc/libphysfs/lzma/CPP/7zip/Common/ProgressUtils.h
misc/libphysfs/lzma/CPP/7zip/Common/RegisterArc.h
misc/libphysfs/lzma/CPP/7zip/Common/RegisterCodec.h
misc/libphysfs/lzma/CPP/7zip/Common/StdAfx.h
misc/libphysfs/lzma/CPP/7zip/Common/StreamBinder.cpp
misc/libphysfs/lzma/CPP/7zip/Common/StreamBinder.h
misc/libphysfs/lzma/CPP/7zip/Common/StreamObjects.cpp
misc/libphysfs/lzma/CPP/7zip/Common/StreamObjects.h
misc/libphysfs/lzma/CPP/7zip/Common/StreamUtils.cpp
misc/libphysfs/lzma/CPP/7zip/Common/StreamUtils.h
misc/libphysfs/lzma/CPP/7zip/Common/VirtThread.cpp
misc/libphysfs/lzma/CPP/7zip/Common/VirtThread.h
misc/libphysfs/lzma/CPP/7zip/Compress/Branch/ARM.cpp
misc/libphysfs/lzma/CPP/7zip/Compress/Branch/ARM.h
misc/libphysfs/lzma/CPP/7zip/Compress/Branch/ARMThumb.cpp
misc/libphysfs/lzma/CPP/7zip/Compress/Branch/ARMThumb.h
misc/libphysfs/lzma/CPP/7zip/Compress/Branch/BCJ2Register.cpp
misc/libphysfs/lzma/CPP/7zip/Compress/Branch/BCJRegister.cpp
misc/libphysfs/lzma/CPP/7zip/Compress/Branch/BranchCoder.cpp
misc/libphysfs/lzma/CPP/7zip/Compress/Branch/BranchCoder.h
misc/libphysfs/lzma/CPP/7zip/Compress/Branch/BranchRegister.cpp
misc/libphysfs/lzma/CPP/7zip/Compress/Branch/IA64.cpp
misc/libphysfs/lzma/CPP/7zip/Compress/Branch/IA64.h
misc/libphysfs/lzma/CPP/7zip/Compress/Branch/PPC.cpp
misc/libphysfs/lzma/CPP/7zip/Compress/Branch/PPC.h
misc/libphysfs/lzma/CPP/7zip/Compress/Branch/SPARC.cpp
misc/libphysfs/lzma/CPP/7zip/Compress/Branch/SPARC.h
misc/libphysfs/lzma/CPP/7zip/Compress/Branch/StdAfx.cpp
misc/libphysfs/lzma/CPP/7zip/Compress/Branch/StdAfx.h
misc/libphysfs/lzma/CPP/7zip/Compress/Branch/x86.cpp
misc/libphysfs/lzma/CPP/7zip/Compress/Branch/x86.h
misc/libphysfs/lzma/CPP/7zip/Compress/Branch/x86_2.cpp
misc/libphysfs/lzma/CPP/7zip/Compress/Branch/x86_2.h
misc/libphysfs/lzma/CPP/7zip/Compress/ByteSwap/ByteSwap.cpp
misc/libphysfs/lzma/CPP/7zip/Compress/ByteSwap/ByteSwap.h
misc/libphysfs/lzma/CPP/7zip/Compress/ByteSwap/ByteSwapRegister.cpp
misc/libphysfs/lzma/CPP/7zip/Compress/ByteSwap/StdAfx.cpp
misc/libphysfs/lzma/CPP/7zip/Compress/ByteSwap/StdAfx.h
misc/libphysfs/lzma/CPP/7zip/Compress/CodecExports.cpp
misc/libphysfs/lzma/CPP/7zip/Compress/Copy/CopyCoder.cpp
misc/libphysfs/lzma/CPP/7zip/Compress/Copy/CopyCoder.h
misc/libphysfs/lzma/CPP/7zip/Compress/Copy/CopyRegister.cpp
misc/libphysfs/lzma/CPP/7zip/Compress/Copy/StdAfx.cpp
misc/libphysfs/lzma/CPP/7zip/Compress/Copy/StdAfx.h
misc/libphysfs/lzma/CPP/7zip/Compress/LZ/LZOutWindow.cpp
misc/libphysfs/lzma/CPP/7zip/Compress/LZ/LZOutWindow.h
misc/libphysfs/lzma/CPP/7zip/Compress/LZ/StdAfx.h
misc/libphysfs/lzma/CPP/7zip/Compress/LZMA/LZMA.h
misc/libphysfs/lzma/CPP/7zip/Compress/LZMA/LZMADecoder.cpp
misc/libphysfs/lzma/CPP/7zip/Compress/LZMA/LZMADecoder.h
misc/libphysfs/lzma/CPP/7zip/Compress/LZMA/LZMAEncoder.cpp
misc/libphysfs/lzma/CPP/7zip/Compress/LZMA/LZMAEncoder.h
misc/libphysfs/lzma/CPP/7zip/Compress/LZMA/LZMARegister.cpp
misc/libphysfs/lzma/CPP/7zip/Compress/LZMA/StdAfx.cpp
misc/libphysfs/lzma/CPP/7zip/Compress/LZMA/StdAfx.h
misc/libphysfs/lzma/CPP/7zip/Compress/LZMA_Alone/AloneLZMA.dsp
misc/libphysfs/lzma/CPP/7zip/Compress/LZMA_Alone/AloneLZMA.dsw
misc/libphysfs/lzma/CPP/7zip/Compress/LZMA_Alone/LzmaAlone.cpp
misc/libphysfs/lzma/CPP/7zip/Compress/LZMA_Alone/LzmaBench.cpp
misc/libphysfs/lzma/CPP/7zip/Compress/LZMA_Alone/LzmaBench.h
misc/libphysfs/lzma/CPP/7zip/Compress/LZMA_Alone/LzmaBenchCon.cpp
misc/libphysfs/lzma/CPP/7zip/Compress/LZMA_Alone/LzmaBenchCon.h
misc/libphysfs/lzma/CPP/7zip/Compress/LZMA_Alone/LzmaRam.cpp
misc/libphysfs/lzma/CPP/7zip/Compress/LZMA_Alone/LzmaRam.h
misc/libphysfs/lzma/CPP/7zip/Compress/LZMA_Alone/LzmaRamDecode.c
misc/libphysfs/lzma/CPP/7zip/Compress/LZMA_Alone/LzmaRamDecode.h
misc/libphysfs/lzma/CPP/7zip/Compress/LZMA_Alone/StdAfx.cpp
misc/libphysfs/lzma/CPP/7zip/Compress/LZMA_Alone/StdAfx.h
misc/libphysfs/lzma/CPP/7zip/Compress/LZMA_Alone/makefile
misc/libphysfs/lzma/CPP/7zip/Compress/LZMA_Alone/makefile.gcc
misc/libphysfs/lzma/CPP/7zip/Compress/RangeCoder/RangeCoder.h
misc/libphysfs/lzma/CPP/7zip/Compress/RangeCoder/RangeCoderBit.cpp
misc/libphysfs/lzma/CPP/7zip/Compress/RangeCoder/RangeCoderBit.h
misc/libphysfs/lzma/CPP/7zip/Compress/RangeCoder/RangeCoderBitTree.h
misc/libphysfs/lzma/CPP/7zip/Compress/RangeCoder/RangeCoderOpt.h
misc/libphysfs/lzma/CPP/7zip/Compress/RangeCoder/StdAfx.h
misc/libphysfs/lzma/CPP/7zip/ICoder.h
misc/libphysfs/lzma/CPP/7zip/IDecl.h
misc/libphysfs/lzma/CPP/7zip/IPassword.h
misc/libphysfs/lzma/CPP/7zip/IProgress.h
misc/libphysfs/lzma/CPP/7zip/IStream.h
misc/libphysfs/lzma/CPP/7zip/MyVersion.h
misc/libphysfs/lzma/CPP/7zip/MyVersionInfo.rc
misc/libphysfs/lzma/CPP/7zip/PropID.h
misc/libphysfs/lzma/CPP/7zip/UI/Client7z/Client7z.cpp
misc/libphysfs/lzma/CPP/7zip/UI/Client7z/Client7z.dsp
misc/libphysfs/lzma/CPP/7zip/UI/Client7z/Client7z.dsw
misc/libphysfs/lzma/CPP/7zip/UI/Client7z/StdAfx.cpp
misc/libphysfs/lzma/CPP/7zip/UI/Client7z/StdAfx.h
misc/libphysfs/lzma/CPP/7zip/UI/Client7z/makefile
misc/libphysfs/lzma/CPP/7zip/UI/Common/ArchiveCommandLine.cpp
misc/libphysfs/lzma/CPP/7zip/UI/Common/ArchiveCommandLine.h
misc/libphysfs/lzma/CPP/7zip/UI/Common/ArchiveExtractCallback.cpp
misc/libphysfs/lzma/CPP/7zip/UI/Common/ArchiveExtractCallback.h
misc/libphysfs/lzma/CPP/7zip/UI/Common/ArchiveName.cpp
misc/libphysfs/lzma/CPP/7zip/UI/Common/ArchiveName.h
misc/libphysfs/lzma/CPP/7zip/UI/Common/ArchiveOpenCallback.cpp
misc/libphysfs/lzma/CPP/7zip/UI/Common/ArchiveOpenCallback.h
misc/libphysfs/lzma/CPP/7zip/UI/Common/DefaultName.cpp
misc/libphysfs/lzma/CPP/7zip/UI/Common/DefaultName.h
misc/libphysfs/lzma/CPP/7zip/UI/Common/DirItem.h
misc/libphysfs/lzma/CPP/7zip/UI/Common/EnumDirItems.cpp
misc/libphysfs/lzma/CPP/7zip/UI/Common/EnumDirItems.h
misc/libphysfs/lzma/CPP/7zip/UI/Common/ExitCode.h
misc/libphysfs/lzma/CPP/7zip/UI/Common/Extract.cpp
misc/libphysfs/lzma/CPP/7zip/UI/Common/Extract.h
misc/libphysfs/lzma/CPP/7zip/UI/Common/ExtractMode.h
misc/libphysfs/lzma/CPP/7zip/UI/Common/ExtractingFilePath.cpp
misc/libphysfs/lzma/CPP/7zip/UI/Common/ExtractingFilePath.h
misc/libphysfs/lzma/CPP/7zip/UI/Common/IFileExtractCallback.h
misc/libphysfs/lzma/CPP/7zip/UI/Common/LoadCodecs.cpp
misc/libphysfs/lzma/CPP/7zip/UI/Common/LoadCodecs.h
misc/libphysfs/lzma/CPP/7zip/UI/Common/OpenArchive.cpp
misc/libphysfs/lzma/CPP/7zip/UI/Common/OpenArchive.h
misc/libphysfs/lzma/CPP/7zip/UI/Common/PropIDUtils.cpp
misc/libphysfs/lzma/CPP/7zip/UI/Common/PropIDUtils.h
misc/libphysfs/lzma/CPP/7zip/UI/Common/Property.h
misc/libphysfs/lzma/CPP/7zip/UI/Common/SetProperties.cpp
misc/libphysfs/lzma/CPP/7zip/UI/Common/SetProperties.h
misc/libphysfs/lzma/CPP/7zip/UI/Common/SortUtils.cpp
misc/libphysfs/lzma/CPP/7zip/UI/Common/SortUtils.h
misc/libphysfs/lzma/CPP/7zip/UI/Common/TempFiles.cpp
misc/libphysfs/lzma/CPP/7zip/UI/Common/TempFiles.h
misc/libphysfs/lzma/CPP/7zip/UI/Common/Update.cpp
misc/libphysfs/lzma/CPP/7zip/UI/Common/Update.h
misc/libphysfs/lzma/CPP/7zip/UI/Common/UpdateAction.cpp
misc/libphysfs/lzma/CPP/7zip/UI/Common/UpdateAction.h
misc/libphysfs/lzma/CPP/7zip/UI/Common/UpdateCallback.cpp
misc/libphysfs/lzma/CPP/7zip/UI/Common/UpdateCallback.h
misc/libphysfs/lzma/CPP/7zip/UI/Common/UpdatePair.cpp
misc/libphysfs/lzma/CPP/7zip/UI/Common/UpdatePair.h
misc/libphysfs/lzma/CPP/7zip/UI/Common/UpdateProduce.cpp
misc/libphysfs/lzma/CPP/7zip/UI/Common/UpdateProduce.h
misc/libphysfs/lzma/CPP/7zip/UI/Common/WorkDir.cpp
misc/libphysfs/lzma/CPP/7zip/UI/Common/WorkDir.h
misc/libphysfs/lzma/CPP/7zip/UI/Common/ZipRegistry.h
misc/libphysfs/lzma/CPP/7zip/UI/Console/ConsoleClose.cpp
misc/libphysfs/lzma/CPP/7zip/UI/Console/ConsoleClose.h
misc/libphysfs/lzma/CPP/7zip/UI/Console/ExtractCallbackConsole.cpp
misc/libphysfs/lzma/CPP/7zip/UI/Console/ExtractCallbackConsole.h
misc/libphysfs/lzma/CPP/7zip/UI/Console/List.cpp
misc/libphysfs/lzma/CPP/7zip/UI/Console/List.h
misc/libphysfs/lzma/CPP/7zip/UI/Console/Main.cpp
misc/libphysfs/lzma/CPP/7zip/UI/Console/MainAr.cpp
misc/libphysfs/lzma/CPP/7zip/UI/Console/OpenCallbackConsole.cpp
misc/libphysfs/lzma/CPP/7zip/UI/Console/OpenCallbackConsole.h
misc/libphysfs/lzma/CPP/7zip/UI/Console/PercentPrinter.cpp
misc/libphysfs/lzma/CPP/7zip/UI/Console/PercentPrinter.h
misc/libphysfs/lzma/CPP/7zip/UI/Console/StdAfx.cpp
misc/libphysfs/lzma/CPP/7zip/UI/Console/StdAfx.h
misc/libphysfs/lzma/CPP/7zip/UI/Console/UpdateCallbackConsole.cpp
misc/libphysfs/lzma/CPP/7zip/UI/Console/UpdateCallbackConsole.h
misc/libphysfs/lzma/CPP/7zip/UI/Console/UserInputUtils.cpp
misc/libphysfs/lzma/CPP/7zip/UI/Console/UserInputUtils.h
misc/libphysfs/lzma/CPP/7zip/UI/Console/afxres.h
misc/libphysfs/lzma/CPP/Build.mak
misc/libphysfs/lzma/CPP/Common/AutoPtr.h
misc/libphysfs/lzma/CPP/Common/Buffer.h
misc/libphysfs/lzma/CPP/Common/CRC.cpp
misc/libphysfs/lzma/CPP/Common/C_FileIO.cpp
misc/libphysfs/lzma/CPP/Common/C_FileIO.h
misc/libphysfs/lzma/CPP/Common/ComTry.h
misc/libphysfs/lzma/CPP/Common/CommandLineParser.cpp
misc/libphysfs/lzma/CPP/Common/CommandLineParser.h
misc/libphysfs/lzma/CPP/Common/Defs.h
misc/libphysfs/lzma/CPP/Common/DynamicBuffer.h
misc/libphysfs/lzma/CPP/Common/IntToString.cpp
misc/libphysfs/lzma/CPP/Common/IntToString.h
misc/libphysfs/lzma/CPP/Common/ListFileUtils.cpp
misc/libphysfs/lzma/CPP/Common/ListFileUtils.h
misc/libphysfs/lzma/CPP/Common/MyCom.h
misc/libphysfs/lzma/CPP/Common/MyException.h
misc/libphysfs/lzma/CPP/Common/MyGuidDef.h
misc/libphysfs/lzma/CPP/Common/MyInitGuid.h
misc/libphysfs/lzma/CPP/Common/MyString.cpp
misc/libphysfs/lzma/CPP/Common/MyString.h
misc/libphysfs/lzma/CPP/Common/MyUnknown.h
misc/libphysfs/lzma/CPP/Common/MyVector.cpp
misc/libphysfs/lzma/CPP/Common/MyVector.h
misc/libphysfs/lzma/CPP/Common/MyWindows.h
misc/libphysfs/lzma/CPP/Common/NewHandler.cpp
misc/libphysfs/lzma/CPP/Common/NewHandler.h
misc/libphysfs/lzma/CPP/Common/StdAfx.h
misc/libphysfs/lzma/CPP/Common/StdInStream.cpp
misc/libphysfs/lzma/CPP/Common/StdInStream.h
misc/libphysfs/lzma/CPP/Common/StdOutStream.cpp
misc/libphysfs/lzma/CPP/Common/StdOutStream.h
misc/libphysfs/lzma/CPP/Common/StringConvert.cpp
misc/libphysfs/lzma/CPP/Common/StringConvert.h
misc/libphysfs/lzma/CPP/Common/StringToInt.cpp
misc/libphysfs/lzma/CPP/Common/StringToInt.h
misc/libphysfs/lzma/CPP/Common/Types.h
misc/libphysfs/lzma/CPP/Common/UTFConvert.cpp
misc/libphysfs/lzma/CPP/Common/UTFConvert.h
misc/libphysfs/lzma/CPP/Common/Wildcard.cpp
misc/libphysfs/lzma/CPP/Common/Wildcard.h
misc/libphysfs/lzma/CPP/Windows/DLL.cpp
misc/libphysfs/lzma/CPP/Windows/DLL.h
misc/libphysfs/lzma/CPP/Windows/Defs.h
misc/libphysfs/lzma/CPP/Windows/Error.cpp
misc/libphysfs/lzma/CPP/Windows/Error.h
misc/libphysfs/lzma/CPP/Windows/FileDir.cpp
misc/libphysfs/lzma/CPP/Windows/FileDir.h
misc/libphysfs/lzma/CPP/Windows/FileFind.cpp
misc/libphysfs/lzma/CPP/Windows/FileFind.h
misc/libphysfs/lzma/CPP/Windows/FileIO.cpp
misc/libphysfs/lzma/CPP/Windows/FileIO.h
misc/libphysfs/lzma/CPP/Windows/FileMapping.cpp
misc/libphysfs/lzma/CPP/Windows/FileMapping.h
misc/libphysfs/lzma/CPP/Windows/FileName.cpp
misc/libphysfs/lzma/CPP/Windows/FileName.h
misc/libphysfs/lzma/CPP/Windows/Handle.h
misc/libphysfs/lzma/CPP/Windows/MemoryLock.cpp
misc/libphysfs/lzma/CPP/Windows/MemoryLock.h
misc/libphysfs/lzma/CPP/Windows/PropVariant.cpp
misc/libphysfs/lzma/CPP/Windows/PropVariant.h
misc/libphysfs/lzma/CPP/Windows/PropVariantConversions.cpp
misc/libphysfs/lzma/CPP/Windows/PropVariantConversions.h
misc/libphysfs/lzma/CPP/Windows/StdAfx.h
misc/libphysfs/lzma/CPP/Windows/Synchronization.cpp
misc/libphysfs/lzma/CPP/Windows/Synchronization.h
misc/libphysfs/lzma/CPP/Windows/System.cpp
misc/libphysfs/lzma/CPP/Windows/System.h
misc/libphysfs/lzma/CPP/Windows/Thread.h
misc/libphysfs/lzma/CPP/Windows/Time.h
misc/libphysfs/lzma/CS/7zip/Common/CRC.cs
misc/libphysfs/lzma/CS/7zip/Common/CommandLineParser.cs
misc/libphysfs/lzma/CS/7zip/Common/InBuffer.cs
misc/libphysfs/lzma/CS/7zip/Common/OutBuffer.cs
misc/libphysfs/lzma/CS/7zip/Compress/LZ/IMatchFinder.cs
misc/libphysfs/lzma/CS/7zip/Compress/LZ/LzBinTree.cs
misc/libphysfs/lzma/CS/7zip/Compress/LZ/LzInWindow.cs
misc/libphysfs/lzma/CS/7zip/Compress/LZ/LzOutWindow.cs
misc/libphysfs/lzma/CS/7zip/Compress/LZMA/LzmaBase.cs
misc/libphysfs/lzma/CS/7zip/Compress/LZMA/LzmaDecoder.cs
misc/libphysfs/lzma/CS/7zip/Compress/LZMA/LzmaEncoder.cs
misc/libphysfs/lzma/CS/7zip/Compress/LzmaAlone/LzmaAlone.cs
misc/libphysfs/lzma/CS/7zip/Compress/LzmaAlone/LzmaAlone.csproj
misc/libphysfs/lzma/CS/7zip/Compress/LzmaAlone/LzmaAlone.sln
misc/libphysfs/lzma/CS/7zip/Compress/LzmaAlone/LzmaBench.cs
misc/libphysfs/lzma/CS/7zip/Compress/LzmaAlone/Properties/AssemblyInfo.cs
misc/libphysfs/lzma/CS/7zip/Compress/LzmaAlone/Properties/Resources.cs
misc/libphysfs/lzma/CS/7zip/Compress/LzmaAlone/Properties/Settings.cs
misc/libphysfs/lzma/CS/7zip/Compress/RangeCoder/RangeCoder.cs
misc/libphysfs/lzma/CS/7zip/Compress/RangeCoder/RangeCoderBit.cs
misc/libphysfs/lzma/CS/7zip/Compress/RangeCoder/RangeCoderBitTree.cs
misc/libphysfs/lzma/CS/7zip/ICoder.cs
misc/libphysfs/lzma/Java/SevenZip/CRC.java
misc/libphysfs/lzma/Java/SevenZip/Compression/LZ/BinTree.java
misc/libphysfs/lzma/Java/SevenZip/Compression/LZ/InWindow.java
misc/libphysfs/lzma/Java/SevenZip/Compression/LZ/OutWindow.java
misc/libphysfs/lzma/Java/SevenZip/Compression/LZMA/Base.java
misc/libphysfs/lzma/Java/SevenZip/Compression/LZMA/Decoder.java
misc/libphysfs/lzma/Java/SevenZip/Compression/LZMA/Encoder.java
misc/libphysfs/lzma/Java/SevenZip/Compression/RangeCoder/BitTreeDecoder.java
misc/libphysfs/lzma/Java/SevenZip/Compression/RangeCoder/BitTreeEncoder.java
misc/libphysfs/lzma/Java/SevenZip/Compression/RangeCoder/Decoder.java
misc/libphysfs/lzma/Java/SevenZip/Compression/RangeCoder/Encoder.java
misc/libphysfs/lzma/Java/SevenZip/ICodeProgress.java
misc/libphysfs/lzma/Java/SevenZip/LzmaAlone.java
misc/libphysfs/lzma/Java/SevenZip/LzmaBench.java
misc/libphysfs/lzma/LGPL.txt
misc/libphysfs/lzma/Methods.txt
misc/libphysfs/lzma/history.txt
misc/libphysfs/lzma/lzma.txt
misc/libphysfs/physfs.c
misc/libphysfs/physfs.h
misc/libphysfs/physfs_casefolding.h
misc/libphysfs/physfs_internal.h
misc/libphysfs/physfs_miniz.h
misc/libphysfs/physfs_platforms.h
misc/libphysfs/physfs_unicode.c
misc/libphysfs/platform_beos.cpp
misc/libphysfs/platform_macosx.c
misc/libphysfs/platform_posix.c
misc/libphysfs/platform_unix.c
misc/libphysfs/platform_windows.c
misc/libphysfs/platform_winrt.cpp
--- a/misc/libphysfs/archiver_dir.c	Mon Apr 10 09:05:16 2017 -0400
+++ b/misc/libphysfs/archiver_dir.c	Mon Apr 10 12:06:43 2017 -0400
@@ -43,10 +43,9 @@
     char *retval = NULL;
     const size_t namelen = strlen(name);
     const size_t seplen = 1;
-    int exists = 0;
 
     assert(io == NULL);  /* shouldn't create an Io for these. */
-    BAIL_IF_MACRO(!__PHYSFS_platformStat(name, &exists, &st), ERRPASS, NULL);
+    BAIL_IF_MACRO(!__PHYSFS_platformStat(name, &st), ERRPASS, NULL);
     if (st.filetype != PHYSFS_FILETYPE_DIRECTORY)
         BAIL_MACRO(PHYSFS_ERR_UNSUPPORTED, NULL);
 
@@ -66,8 +65,8 @@
 } /* DIR_openArchive */
 
 
-static void DIR_enumerateFiles(PHYSFS_Dir *opaque, const char *dname,
-                               int omitSymLinks, PHYSFS_EnumFilesCallback cb,
+static void DIR_enumerateFiles(void *opaque, const char *dname,
+                               PHYSFS_EnumFilesCallback cb,
                                const char *origdir, void *callbackdata)
 {
     char *d;
@@ -75,38 +74,28 @@
     CVT_TO_DEPENDENT(d, opaque, dname);
     if (d != NULL)
     {
-        __PHYSFS_platformEnumerateFiles(d, omitSymLinks, cb,
-                                        origdir, callbackdata);
+        __PHYSFS_platformEnumerateFiles(d, cb, origdir, callbackdata);
         __PHYSFS_smallFree(d);
     } /* if */
 } /* DIR_enumerateFiles */
 
 
-static PHYSFS_Io *doOpen(PHYSFS_Dir *opaque, const char *name,
-                         const int mode, int *fileExists)
+static PHYSFS_Io *doOpen(void *opaque, const char *name, const int mode)
 {
-    char *f;
     PHYSFS_Io *io = NULL;
-    int existtmp = 0;
+    char *f = NULL;
 
     CVT_TO_DEPENDENT(f, opaque, name);
     BAIL_IF_MACRO(!f, ERRPASS, NULL);
 
-    if (fileExists == NULL)
-        fileExists = &existtmp;
-
     io = __PHYSFS_createNativeIo(f, mode);
     if (io == NULL)
     {
         const PHYSFS_ErrorCode err = PHYSFS_getLastErrorCode();
         PHYSFS_Stat statbuf;
-        __PHYSFS_platformStat(f, fileExists, &statbuf);
-        __PHYSFS_setError(err);
+        __PHYSFS_platformStat(f, &statbuf);
+        PHYSFS_setErrorCode(err);
     } /* if */
-    else
-    {
-        *fileExists = 1;
-    } /* else */
 
     __PHYSFS_smallFree(f);
 
@@ -114,25 +103,25 @@
 } /* doOpen */
 
 
-static PHYSFS_Io *DIR_openRead(PHYSFS_Dir *opaque, const char *fnm, int *exist)
+static PHYSFS_Io *DIR_openRead(void *opaque, const char *filename)
 {
-    return doOpen(opaque, fnm, 'r', exist);
+    return doOpen(opaque, filename, 'r');
 } /* DIR_openRead */
 
 
-static PHYSFS_Io *DIR_openWrite(PHYSFS_Dir *opaque, const char *filename)
+static PHYSFS_Io *DIR_openWrite(void *opaque, const char *filename)
 {
-    return doOpen(opaque, filename, 'w', NULL);
+    return doOpen(opaque, filename, 'w');
 } /* DIR_openWrite */
 
 
-static PHYSFS_Io *DIR_openAppend(PHYSFS_Dir *opaque, const char *filename)
+static PHYSFS_Io *DIR_openAppend(void *opaque, const char *filename)
 {
-    return doOpen(opaque, filename, 'a', NULL);
+    return doOpen(opaque, filename, 'a');
 } /* DIR_openAppend */
 
 
-static int DIR_remove(PHYSFS_Dir *opaque, const char *name)
+static int DIR_remove(void *opaque, const char *name)
 {
     int retval;
     char *f;
@@ -145,7 +134,7 @@
 } /* DIR_remove */
 
 
-static int DIR_mkdir(PHYSFS_Dir *opaque, const char *name)
+static int DIR_mkdir(void *opaque, const char *name)
 {
     int retval;
     char *f;
@@ -158,21 +147,20 @@
 } /* DIR_mkdir */
 
 
-static void DIR_closeArchive(PHYSFS_Dir *opaque)
+static void DIR_closeArchive(void *opaque)
 {
     allocator.Free(opaque);
 } /* DIR_closeArchive */
 
 
-static int DIR_stat(PHYSFS_Dir *opaque, const char *name,
-                    int *exists, PHYSFS_Stat *stat)
+static int DIR_stat(void *opaque, const char *name, PHYSFS_Stat *stat)
 {
     int retval = 0;
     char *d;
 
     CVT_TO_DEPENDENT(d, opaque, name);
     BAIL_IF_MACRO(!d, ERRPASS, 0);
-    retval = __PHYSFS_platformStat(d, exists, stat);
+    retval = __PHYSFS_platformStat(d, stat);
     __PHYSFS_smallFree(d);
     return retval;
 } /* DIR_stat */
@@ -180,22 +168,24 @@
 
 const PHYSFS_Archiver __PHYSFS_Archiver_DIR =
 {
+    CURRENT_PHYSFS_ARCHIVER_API_VERSION,
     {
         "",
         "Non-archive, direct filesystem I/O",
         "Ryan C. Gordon <icculus@icculus.org>",
-        "http://icculus.org/physfs/",
+        "https://icculus.org/physfs/",
+        1,  /* supportsSymlinks */
     },
-    DIR_openArchive,        /* openArchive() method    */
-    DIR_enumerateFiles,     /* enumerateFiles() method */
-    DIR_openRead,           /* openRead() method       */
-    DIR_openWrite,          /* openWrite() method      */
-    DIR_openAppend,         /* openAppend() method     */
-    DIR_remove,             /* remove() method         */
-    DIR_mkdir,              /* mkdir() method          */
-    DIR_closeArchive,       /* closeArchive() method   */
-    DIR_stat                /* stat() method           */
+    DIR_openArchive,
+    DIR_enumerateFiles,
+    DIR_openRead,
+    DIR_openWrite,
+    DIR_openAppend,
+    DIR_remove,
+    DIR_mkdir,
+    DIR_stat,
+    DIR_closeArchive
 };
 
-/* end of dir.c ... */
+/* end of archiver_dir.c ... */
 
--- a/misc/libphysfs/archiver_grp.c	Mon Apr 10 09:05:16 2017 -0400
+++ b/misc/libphysfs/archiver_grp.c	Mon Apr 10 12:06:43 2017 -0400
@@ -87,24 +87,26 @@
 
 const PHYSFS_Archiver __PHYSFS_Archiver_GRP =
 {
+    CURRENT_PHYSFS_ARCHIVER_API_VERSION,
     {
         "GRP",
         "Build engine Groupfile format",
         "Ryan C. Gordon <icculus@icculus.org>",
-        "http://icculus.org/physfs/",
+        "https://icculus.org/physfs/",
+        0,  /* supportsSymlinks */
     },
-    GRP_openArchive,        /* openArchive() method    */
-    UNPK_enumerateFiles,    /* enumerateFiles() method */
-    UNPK_openRead,          /* openRead() method       */
-    UNPK_openWrite,         /* openWrite() method      */
-    UNPK_openAppend,        /* openAppend() method     */
-    UNPK_remove,            /* remove() method         */
-    UNPK_mkdir,             /* mkdir() method          */
-    UNPK_closeArchive,      /* closeArchive() method   */
-    UNPK_stat               /* stat() method           */
+    GRP_openArchive,
+    UNPK_enumerateFiles,
+    UNPK_openRead,
+    UNPK_openWrite,
+    UNPK_openAppend,
+    UNPK_remove,
+    UNPK_mkdir,
+    UNPK_stat,
+    UNPK_closeArchive
 };
 
 #endif  /* defined PHYSFS_SUPPORTS_GRP */
 
-/* end of grp.c ... */
+/* end of archiver_grp.c ... */
 
--- a/misc/libphysfs/archiver_hog.c	Mon Apr 10 09:05:16 2017 -0400
+++ b/misc/libphysfs/archiver_hog.c	Mon Apr 10 12:06:43 2017 -0400
@@ -93,24 +93,26 @@
 
 const PHYSFS_Archiver __PHYSFS_Archiver_HOG =
 {
+    CURRENT_PHYSFS_ARCHIVER_API_VERSION,
     {
         "HOG",
         "Descent I/II HOG file format",
         "Bradley Bell <btb@icculus.org>",
-        "http://icculus.org/physfs/",
+        "https://icculus.org/physfs/",
+        0,  /* supportsSymlinks */
     },
-    HOG_openArchive,         /* openArchive() method    */
-    UNPK_enumerateFiles,     /* enumerateFiles() method */
-    UNPK_openRead,           /* openRead() method       */
-    UNPK_openWrite,          /* openWrite() method      */
-    UNPK_openAppend,         /* openAppend() method     */
-    UNPK_remove,             /* remove() method         */
-    UNPK_mkdir,              /* mkdir() method          */
-    UNPK_closeArchive,       /* closeArchive() method   */
-    UNPK_stat                /* stat() method           */
+    HOG_openArchive,
+    UNPK_enumerateFiles,
+    UNPK_openRead,
+    UNPK_openWrite,
+    UNPK_openAppend,
+    UNPK_remove,
+    UNPK_mkdir,
+    UNPK_stat,
+    UNPK_closeArchive
 };
 
 #endif  /* defined PHYSFS_SUPPORTS_HOG */
 
-/* end of hog.c ... */
+/* end of archiver_hog.c ... */
 
--- a/misc/libphysfs/archiver_iso9660.c	Mon Apr 10 09:05:16 2017 -0400
+++ b/misc/libphysfs/archiver_iso9660.c	Mon Apr 10 12:06:43 2017 -0400
@@ -291,8 +291,8 @@
         for(;pos < descriptor->filenamelen; pos++)
             if (descriptor->filename[pos] == ';')
                 lastfound = pos;
-        BAIL_IF_MACRO(lastfound < 1, PHYSFS_ERR_NO_SUCH_PATH /* !!! FIXME: PHYSFS_ERR_BAD_FILENAME */, -1);
-        BAIL_IF_MACRO(lastfound == (descriptor->filenamelen -1), PHYSFS_ERR_NO_SUCH_PATH /* !!! PHYSFS_ERR_BAD_FILENAME */, -1);
+        BAIL_IF_MACRO(lastfound < 1, PHYSFS_ERR_NOT_FOUND /* !!! FIXME: PHYSFS_ERR_BAD_FILENAME */, -1);
+        BAIL_IF_MACRO(lastfound == (descriptor->filenamelen -1), PHYSFS_ERR_NOT_FOUND /* !!! PHYSFS_ERR_BAD_FILENAME */, -1);
         strncpy(filename, descriptor->filename, lastfound);
         if (filename[lastfound - 1] == '.')
             filename[lastfound - 1] = '\0'; /* consume trailing ., as done in all implementations */
@@ -398,7 +398,7 @@
  * a file needs to branch to the directory extent sooner or later.
  */
 static int iso_find_dir_entry(ISO9660Handle *handle,const char *path,
-                              ISO9660FileDescriptor *descriptor, int *exists)
+                              ISO9660FileDescriptor *descriptor)
 {
     char *subpath = 0;
     PHYSFS_uint64 readpos, end_of_dir;
@@ -409,7 +409,6 @@
 
     strcpy(pathcopy, path);
     mypath = pathcopy;
-    *exists = 0;
 
     readpos = handle->rootdirstart;
     end_of_dir = handle->rootdirstart + handle->rootdirsize;
@@ -442,10 +441,7 @@
         if (strcmp(filename, mypath) == 0)
         {
             if ( (subpath == 0) || (subpath[0] == 0) )
-            {
-                *exists = 1;
                 return 0;  /* no subpaths left and we found the entry */
-            } /* if */
 
             if (descriptor->flags.directory)
             {
@@ -458,12 +454,14 @@
             } /* if */
             else
             {
+                /* !!! FIXME: set PHYSFS_ERR_NOT_FOUND? */
                 /* we're at a file but have a remaining subpath -> no match */
                 return 0;
             } /* else */
         } /* if */
     } /* while */
 
+    /* !!! FIXME: set PHYSFS_ERR_NOT_FOUND? */
     return 0;
 } /* iso_find_dir_entry */
 
@@ -555,7 +553,7 @@
 
     /* Skip system area to magic number in Volume descriptor */
     BAIL_IF_MACRO(!io->seek(io, 32769), ERRPASS, NULL);
-    BAIL_IF_MACRO(!io->read(io, magicnumber, 5) != 5, ERRPASS, NULL);
+    BAIL_IF_MACRO(io->read(io, magicnumber, 5) != 5, ERRPASS, NULL);
     if (memcmp(magicnumber, "CD001", 6) != 0)
         BAIL_MACRO(PHYSFS_ERR_UNSUPPORTED, NULL);
 
@@ -638,7 +636,7 @@
 } /* ISO9660_openArchive */
 
 
-static void ISO9660_closeArchive(PHYSFS_Dir *opaque)
+static void ISO9660_closeArchive(void *opaque)
 {
     ISO9660Handle *handle = (ISO9660Handle*) opaque;
     handle->io->destroy(handle->io);
@@ -766,8 +764,7 @@
 } /* iso_file_open_foreign */
 
 
-static PHYSFS_Io *ISO9660_openRead(PHYSFS_Dir *opaque, const char *filename,
-                                   int *exists)
+static PHYSFS_Io *ISO9660_openRead(void *opaque, const char *filename)
 {
     PHYSFS_Io *retval = NULL;
     ISO9660Handle *handle = (ISO9660Handle*) opaque;
@@ -783,9 +780,8 @@
     GOTO_IF_MACRO(retval == 0, PHYSFS_ERR_OUT_OF_MEMORY, errorhandling);
 
     /* find file descriptor */
-    rc = iso_find_dir_entry(handle, filename, &descriptor, exists);
+    rc = iso_find_dir_entry(handle, filename, &descriptor);
     GOTO_IF_MACRO(rc, ERRPASS, errorhandling);
-    GOTO_IF_MACRO(!*exists, PHYSFS_ERR_NO_SUCH_PATH, errorhandling);
 
     fhandle->startblock = descriptor.extentpos + descriptor.extattributelen;
     fhandle->filesize = descriptor.datalen;
@@ -816,8 +812,7 @@
  * Information gathering functions
  ******************************************************************************/
 
-static void ISO9660_enumerateFiles(PHYSFS_Dir *opaque, const char *dname,
-                                   int omitSymLinks,
+static void ISO9660_enumerateFiles(void *opaque, const char *dname,
                                    PHYSFS_EnumFilesCallback cb,
                                    const char *origdir, void *callbackdata)
 {
@@ -836,9 +831,7 @@
     else
     {
         printf("pfad %s\n",dname);
-        int exists = 0;
-        BAIL_IF_MACRO(iso_find_dir_entry(handle,dname, &descriptor, &exists), ERRPASS,);
-        BAIL_IF_MACRO(!exists, ERRPASS, );
+        BAIL_IF_MACRO(iso_find_dir_entry(handle,dname, &descriptor), ERRPASS,);
         BAIL_IF_MACRO(!descriptor.flags.directory, ERRPASS,);
 
         readpos = descriptor.extentpos * 2048;
@@ -873,15 +866,12 @@
 } /* ISO9660_enumerateFiles */
 
 
-static int ISO9660_stat(PHYSFS_Dir *opaque, const char *name, int *exists,
-                        PHYSFS_Stat *stat)
+static int ISO9660_stat(void *opaque, const char *name, PHYSFS_Stat *stat)
 {
     ISO9660Handle *handle = (ISO9660Handle*) opaque;
     ISO9660FileDescriptor descriptor;
     ISO9660ExtAttributeRec extattr;
-    BAIL_IF_MACRO(iso_find_dir_entry(handle, name, &descriptor, exists), ERRPASS, -1);
-    if (!*exists)
-        return 0;
+    BAIL_IF_MACRO(iso_find_dir_entry(handle, name, &descriptor), ERRPASS, -1);
 
     stat->readonly = 1;
 
@@ -920,25 +910,25 @@
  * Not supported functions
  ******************************************************************************/
 
-static PHYSFS_Io *ISO9660_openWrite(PHYSFS_Dir *opaque, const char *name)
+static PHYSFS_Io *ISO9660_openWrite(void *opaque, const char *name)
 {
     BAIL_MACRO(PHYSFS_ERR_READ_ONLY, NULL);
 } /* ISO9660_openWrite */
 
 
-static PHYSFS_Io *ISO9660_openAppend(PHYSFS_Dir *opaque, const char *name)
+static PHYSFS_Io *ISO9660_openAppend(void *opaque, const char *name)
 {
     BAIL_MACRO(PHYSFS_ERR_READ_ONLY, NULL);
 } /* ISO9660_openAppend */
 
 
-static int ISO9660_remove(PHYSFS_Dir *opaque, const char *name)
+static int ISO9660_remove(void *opaque, const char *name)
 {
     BAIL_MACRO(PHYSFS_ERR_READ_ONLY, 0);
 } /* ISO9660_remove */
 
 
-static int ISO9660_mkdir(PHYSFS_Dir *opaque, const char *name)
+static int ISO9660_mkdir(void *opaque, const char *name)
 {
     BAIL_MACRO(PHYSFS_ERR_READ_ONLY, 0);
 } /* ISO9660_mkdir */
@@ -946,21 +936,23 @@
 
 const PHYSFS_Archiver __PHYSFS_Archiver_ISO9660 =
 {
+    CURRENT_PHYSFS_ARCHIVER_API_VERSION,
     {
         "ISO",
         "ISO9660 image file",
         "Christoph Nelles <evilazrael@evilazrael.de>",
-        "http://www.evilazrael.de/",
+        "https://www.evilazrael.de/",
+        0,  /* supportsSymlinks */
     },
-    ISO9660_openArchive,        /* openArchive() method    */
-    ISO9660_enumerateFiles,     /* enumerateFiles() method */
-    ISO9660_openRead,           /* openRead() method       */
-    ISO9660_openWrite,          /* openWrite() method      */
-    ISO9660_openAppend,         /* openAppend() method     */
-    ISO9660_remove,             /* remove() method         */
-    ISO9660_mkdir,              /* mkdir() method          */
-    ISO9660_closeArchive,       /* closeArchive() method   */
-    ISO9660_stat                /* stat() method           */
+    ISO9660_openArchive,
+    ISO9660_enumerateFiles,
+    ISO9660_openRead,
+    ISO9660_openWrite,
+    ISO9660_openAppend,
+    ISO9660_remove,
+    ISO9660_mkdir,
+    ISO9660_stat,
+    ISO9660_closeArchive
 };
 
 #endif  /* defined PHYSFS_SUPPORTS_ISO9660 */
--- a/misc/libphysfs/archiver_lzma.c	Mon Apr 10 09:05:16 2017 -0400
+++ b/misc/libphysfs/archiver_lzma.c	Mon Apr 10 12:06:43 2017 -0400
@@ -124,7 +124,7 @@
 SZ_RESULT SzFileReadImp(void *object, void *buffer, size_t size,
                         size_t *processedSize)
 {
-    FileInputStream *s = (FileInputStream *)((unsigned long)object - offsetof(FileInputStream, inStream)); /* HACK! */
+    FileInputStream *s = (FileInputStream *)((size_t)object - offsetof(FileInputStream, inStream)); /* HACK! */
     const size_t processedSizeLoc = s->io->read(s->io, buffer, size);
     if (processedSize != NULL)
         *processedSize = processedSizeLoc;
@@ -139,7 +139,7 @@
  */
 SZ_RESULT SzFileSeekImp(void *object, CFileSize pos)
 {
-    FileInputStream *s = (FileInputStream *)((unsigned long)object - offsetof(FileInputStream, inStream)); /* HACK! */
+    FileInputStream *s = (FileInputStream *)((size_t)object - offsetof(FileInputStream, inStream)); /* HACK! */
     if (s->io->seek(s->io, (PHYSFS_uint64) pos))
         return SZ_OK;
     return SZE_FAIL;
@@ -205,7 +205,7 @@
 {
     LZMAfile *file = bsearch(name, archive->files, archive->db.Database.NumFiles, sizeof(*archive->files), lzma_file_cmp_stdlib); /* FIXME: Should become __PHYSFS_search!!! */
 
-    BAIL_IF_MACRO(file == NULL, PHYSFS_ERR_NO_SUCH_PATH, NULL);
+    BAIL_IF_MACRO(file == NULL, PHYSFS_ERR_NOT_FOUND, NULL);
 
     return file;
 } /* lzma_find_file */
@@ -291,25 +291,25 @@
         case SZ_OK: /* Same as LZMA_RESULT_OK */
             break;
         case SZE_DATA_ERROR: /* Same as LZMA_RESULT_DATA_ERROR */
-            __PHYSFS_setError(PHYSFS_ERR_CORRUPT); /*!!!FIXME: was "PHYSFS_ERR_DATA_ERROR" */
+            PHYSFS_setErrorCode(PHYSFS_ERR_CORRUPT); /*!!!FIXME: was "PHYSFS_ERR_DATA_ERROR" */
             break;
         case SZE_OUTOFMEMORY:
-            __PHYSFS_setError(PHYSFS_ERR_OUT_OF_MEMORY);
+            PHYSFS_setErrorCode(PHYSFS_ERR_OUT_OF_MEMORY);
             break;
         case SZE_CRC_ERROR:
-            __PHYSFS_setError(PHYSFS_ERR_CORRUPT);
+            PHYSFS_setErrorCode(PHYSFS_ERR_CORRUPT);
             break;
         case SZE_NOTIMPL:
-            __PHYSFS_setError(PHYSFS_ERR_UNSUPPORTED);
+            PHYSFS_setErrorCode(PHYSFS_ERR_UNSUPPORTED);
             break;
         case SZE_FAIL:
-            __PHYSFS_setError(PHYSFS_ERR_OTHER_ERROR);  /* !!! FIXME: right? */
+            PHYSFS_setErrorCode(PHYSFS_ERR_OTHER_ERROR);  /* !!! FIXME: right? */
             break;
         case SZE_ARCHIVE_ERROR:
-            __PHYSFS_setError(PHYSFS_ERR_CORRUPT);  /* !!! FIXME: right? */
+            PHYSFS_setErrorCode(PHYSFS_ERR_CORRUPT);  /* !!! FIXME: right? */
             break;
         default:
-            __PHYSFS_setError(PHYSFS_ERR_OTHER_ERROR);
+            PHYSFS_setErrorCode(PHYSFS_ERR_OTHER_ERROR);
     } /* switch */
 
     return rc;
@@ -531,8 +531,8 @@
 } /* doEnumCallback */
 
 
-static void LZMA_enumerateFiles(PHYSFS_Dir *opaque, const char *dname,
-                                int omitSymLinks, PHYSFS_EnumFilesCallback cb,
+static void LZMA_enumerateFiles(void *opaque, const char *dname,
+                                PHYSFS_EnumFilesCallback cb,
                                 const char *origdir, void *callbackdata)
 {
     size_t dlen = strlen(dname),
@@ -551,7 +551,7 @@
             file = archive->files;
         }
 
-    BAIL_IF_MACRO(file == NULL, PHYSFS_ERR_NO_SUCH_PATH, );
+    BAIL_IF_MACRO(file == NULL, PHYSFS_ERR_NOT_FOUND, );
 
     while (file < lastFile)
     {
@@ -575,15 +575,13 @@
 } /* LZMA_enumerateFiles */
 
 
-static PHYSFS_Io *LZMA_openRead(PHYSFS_Dir *opaque, const char *name,
-                                int *fileExists)
+static PHYSFS_Io *LZMA_openRead(void *opaque, const char *name)
 {
     LZMAarchive *archive = (LZMAarchive *) opaque;
     LZMAfile *file = lzma_find_file(archive, name);
     PHYSFS_Io *io = NULL;
 
-    *fileExists = (file != NULL);
-    BAIL_IF_MACRO(file == NULL, PHYSFS_ERR_NO_SUCH_PATH, NULL);
+    BAIL_IF_MACRO(file == NULL, PHYSFS_ERR_NOT_FOUND, NULL);
     BAIL_IF_MACRO(file->folder == NULL, PHYSFS_ERR_NOT_A_FILE, NULL);
 
     file->position = 0;
@@ -598,19 +596,19 @@
 } /* LZMA_openRead */
 
 
-static PHYSFS_Io *LZMA_openWrite(PHYSFS_Dir *opaque, const char *filename)
+static PHYSFS_Io *LZMA_openWrite(void *opaque, const char *filename)
 {
     BAIL_MACRO(PHYSFS_ERR_READ_ONLY, NULL);
 } /* LZMA_openWrite */
 
 
-static PHYSFS_Io *LZMA_openAppend(PHYSFS_Dir *opaque, const char *filename)
+static PHYSFS_Io *LZMA_openAppend(void *opaque, const char *filename)
 {
     BAIL_MACRO(PHYSFS_ERR_READ_ONLY, NULL);
 } /* LZMA_openAppend */
 
 
-static void LZMA_closeArchive(PHYSFS_Dir *opaque)
+static void LZMA_closeArchive(void *opaque)
 {
     LZMAarchive *archive = (LZMAarchive *) opaque;
 
@@ -628,24 +626,22 @@
 } /* LZMA_closeArchive */
 
 
-static int LZMA_remove(PHYSFS_Dir *opaque, const char *name)
+static int LZMA_remove(void *opaque, const char *name)
 {
     BAIL_MACRO(PHYSFS_ERR_READ_ONLY, 0);
 } /* LZMA_remove */
 
 
-static int LZMA_mkdir(PHYSFS_Dir *opaque, const char *name)
+static int LZMA_mkdir(void *opaque, const char *name)
 {
     BAIL_MACRO(PHYSFS_ERR_READ_ONLY, 0);
 } /* LZMA_mkdir */
 
-static int LZMA_stat(PHYSFS_Dir *opaque, const char *filename,
-                     int *exists, PHYSFS_Stat *stat)
+static int LZMA_stat(void *opaque, const char *filename, PHYSFS_Stat *stat)
 {
     const LZMAarchive *archive = (const LZMAarchive *) opaque;
     const LZMAfile *file = lzma_find_file(archive, filename);
 
-    *exists = (file != 0);
     if (!file)
         return 0;
 
@@ -678,24 +674,26 @@
 
 const PHYSFS_Archiver __PHYSFS_Archiver_LZMA =
 {
+    CURRENT_PHYSFS_ARCHIVER_API_VERSION,
     {
         "7Z",
         "LZMA (7zip) format",
         "Dennis Schridde <devurandom@gmx.net>",
-        "http://icculus.org/physfs/",
+        "https://icculus.org/physfs/",
+        0,  /* supportsSymlinks */
     },
-    LZMA_openArchive,        /* openArchive() method    */
-    LZMA_enumerateFiles,     /* enumerateFiles() method */
-    LZMA_openRead,           /* openRead() method       */
-    LZMA_openWrite,          /* openWrite() method      */
-    LZMA_openAppend,         /* openAppend() method     */
-    LZMA_remove,             /* remove() method         */
-    LZMA_mkdir,              /* mkdir() method          */
-    LZMA_closeArchive,       /* closeArchive() method   */
-    LZMA_stat                /* stat() method           */
+    LZMA_openArchive,
+    LZMA_enumerateFiles,
+    LZMA_openRead,
+    LZMA_openWrite,
+    LZMA_openAppend,
+    LZMA_remove,
+    LZMA_mkdir,
+    LZMA_stat,
+    LZMA_closeArchive
 };
 
 #endif  /* defined PHYSFS_SUPPORTS_7Z */
 
-/* end of lzma.c ... */
+/* end of archiver_lzma.c ... */
 
--- a/misc/libphysfs/archiver_mvl.c	Mon Apr 10 09:05:16 2017 -0400
+++ b/misc/libphysfs/archiver_mvl.c	Mon Apr 10 12:06:43 2017 -0400
@@ -80,24 +80,26 @@
 
 const PHYSFS_Archiver __PHYSFS_Archiver_MVL =
 {
+    CURRENT_PHYSFS_ARCHIVER_API_VERSION,
     {
         "MVL",
         "Descent II Movielib format",
         "Bradley Bell <btb@icculus.org>",
-        "http://icculus.org/physfs/",
+        "https://icculus.org/physfs/",
+        0,  /* supportsSymlinks */
     },
-    MVL_openArchive,        /* openArchive() method    */
-    UNPK_enumerateFiles,     /* enumerateFiles() method */
-    UNPK_openRead,           /* openRead() method       */
-    UNPK_openWrite,          /* openWrite() method      */
-    UNPK_openAppend,         /* openAppend() method     */
-    UNPK_remove,             /* remove() method         */
-    UNPK_mkdir,              /* mkdir() method          */
-    UNPK_closeArchive,       /* closeArchive() method   */
-    UNPK_stat                /* stat() method           */
+    MVL_openArchive,
+    UNPK_enumerateFiles,
+    UNPK_openRead,
+    UNPK_openWrite,
+    UNPK_openAppend,
+    UNPK_remove,
+    UNPK_mkdir,
+    UNPK_stat,
+    UNPK_closeArchive
 };
 
 #endif  /* defined PHYSFS_SUPPORTS_MVL */
 
-/* end of mvl.c ... */
+/* end of archiver_mvl.c ... */
 
--- a/misc/libphysfs/archiver_qpak.c	Mon Apr 10 09:05:16 2017 -0400
+++ b/misc/libphysfs/archiver_qpak.c	Mon Apr 10 12:06:43 2017 -0400
@@ -96,24 +96,26 @@
 
 const PHYSFS_Archiver __PHYSFS_Archiver_QPAK =
 {
+    CURRENT_PHYSFS_ARCHIVER_API_VERSION,
     {
         "PAK",
         "Quake I/II format",
         "Ryan C. Gordon <icculus@icculus.org>",
-        "http://icculus.org/physfs/",
+        "https://icculus.org/physfs/",
+        0,  /* supportsSymlinks */
     },
-    QPAK_openArchive,       /* openArchive() method    */
-    UNPK_enumerateFiles,    /* enumerateFiles() method */
-    UNPK_openRead,          /* openRead() method       */
-    UNPK_openWrite,         /* openWrite() method      */
-    UNPK_openAppend,        /* openAppend() method     */
-    UNPK_remove,            /* remove() method         */
-    UNPK_mkdir,             /* mkdir() method          */
-    UNPK_closeArchive,       /* closeArchive() method   */
-    UNPK_stat               /* stat() method           */
+    QPAK_openArchive,
+    UNPK_enumerateFiles,
+    UNPK_openRead,
+    UNPK_openWrite,
+    UNPK_openAppend,
+    UNPK_remove,
+    UNPK_mkdir,
+    UNPK_stat,
+    UNPK_closeArchive
 };
 
 #endif  /* defined PHYSFS_SUPPORTS_QPAK */
 
-/* end of qpak.c ... */
+/* end of archiver_qpak.c ... */
 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/misc/libphysfs/archiver_slb.c	Mon Apr 10 12:06:43 2017 -0400
@@ -0,0 +1,126 @@
+/*
+ * SLB support routines for PhysicsFS.
+ *
+ * This driver handles SLB archives ("slab files"). This uncompressed format
+ * is used in I-War / Independence War and Independence War: Defiance.
+ *
+ * The format begins with four zero bytes (version?), the file count and the
+ * location of the table of contents. Each ToC entry contains a 64-byte buffer
+ * containing a zero-terminated filename, the offset of the data, and its size.
+ * All the filenames begin with the separator character '\'. 
+ *
+ * Please see the file LICENSE.txt in the source's root directory.
+ *
+ * This file written by Aleksi Nurmi, based on the GRP archiver by
+ * Ryan C. Gordon.
+ */
+
+#define __PHYSICSFS_INTERNAL__
+#include "physfs_internal.h"
+
+#if PHYSFS_SUPPORTS_SLB
+
+static UNPKentry *slbLoadEntries(PHYSFS_Io *io, PHYSFS_uint32 fileCount)
+{
+    UNPKentry *entries = NULL;
+    UNPKentry *entry = NULL;
+
+    entries = (UNPKentry *) allocator.Malloc(sizeof (UNPKentry) * fileCount);
+    BAIL_IF_MACRO(entries == NULL, PHYSFS_ERR_OUT_OF_MEMORY, NULL);
+
+    for (entry = entries; fileCount > 0; fileCount--, entry++)
+    {
+        char *ptr;
+
+        /* don't include the '\' in the beginning */
+        char backslash;
+        GOTO_IF_MACRO(!__PHYSFS_readAll(io, &backslash, 1), ERRPASS, failed);
+        GOTO_IF_MACRO(backslash != '\\', ERRPASS, failed);
+
+        /* read the rest of the buffer, 63 bytes */
+        GOTO_IF_MACRO(!__PHYSFS_readAll(io, &entry->name, 63), ERRPASS, failed);
+        entry->name[63] = '\0'; /* in case the name lacks the null terminator */
+
+        /* convert backslashes */
+        for (ptr = entry->name; *ptr; ptr++)
+        {
+            if (*ptr == '\\')
+                *ptr = '/';
+        } /* for */
+
+        GOTO_IF_MACRO(!__PHYSFS_readAll(io, &entry->startPos, 4),
+                      ERRPASS, failed);
+        entry->startPos = PHYSFS_swapULE32(entry->startPos);
+
+        GOTO_IF_MACRO(!__PHYSFS_readAll(io, &entry->size, 4), ERRPASS, failed);
+        entry->size = PHYSFS_swapULE32(entry->size);
+    } /* for */
+    
+    return entries;
+
+failed:
+    allocator.Free(entries);
+    return NULL;
+
+} /* slbLoadEntries */
+
+
+static void *SLB_openArchive(PHYSFS_Io *io, const char *name, int forWriting)
+{
+    PHYSFS_uint32 version;
+    PHYSFS_uint32 count = 0;
+    PHYSFS_uint32 tocPos = 0;
+    UNPKentry *entries = NULL;
+
+    assert(io != NULL);  /* shouldn't ever happen. */
+
+    BAIL_IF_MACRO(forWriting, PHYSFS_ERR_READ_ONLY, NULL);
+
+    BAIL_IF_MACRO(!__PHYSFS_readAll(io, &version, sizeof(version)),
+                  ERRPASS, NULL);
+    version = PHYSFS_swapULE32(version);
+    BAIL_IF_MACRO(version != 0, ERRPASS, NULL);
+
+    BAIL_IF_MACRO(!__PHYSFS_readAll(io, &count, sizeof(count)), ERRPASS, NULL);
+    count = PHYSFS_swapULE32(count);
+
+    /* offset of the table of contents */
+    BAIL_IF_MACRO(!__PHYSFS_readAll(io, &tocPos, sizeof(tocPos)),
+                  ERRPASS, NULL);
+    tocPos = PHYSFS_swapULE32(tocPos);
+    
+    /* seek to the table of contents */
+    BAIL_IF_MACRO(!io->seek(io, tocPos), ERRPASS, NULL);
+
+    entries = slbLoadEntries(io, count);
+    BAIL_IF_MACRO(!entries, ERRPASS, NULL);
+
+    return UNPK_openArchive(io, entries, count);
+} /* SLB_openArchive */
+
+
+const PHYSFS_Archiver __PHYSFS_Archiver_SLB =
+{
+    CURRENT_PHYSFS_ARCHIVER_API_VERSION,
+    {
+        "SLB",
+        "I-War / Independence War Slab file",
+        "Aleksi Nurmi <aleksi.nurmi@gmail.com>",
+        "https://bitbucket.org/ahnurmi/",
+        0,  /* supportsSymlinks */
+    },
+    SLB_openArchive,
+    UNPK_enumerateFiles,
+    UNPK_openRead,
+    UNPK_openWrite,
+    UNPK_openAppend,
+    UNPK_remove,
+    UNPK_mkdir,
+    UNPK_stat,
+    UNPK_closeArchive
+};
+
+#endif  /* defined PHYSFS_SUPPORTS_SLB */
+
+/* end of archiver_slb.c ... */
+
--- a/misc/libphysfs/archiver_unpacked.c	Mon Apr 10 09:05:16 2017 -0400
+++ b/misc/libphysfs/archiver_unpacked.c	Mon Apr 10 12:06:43 2017 -0400
@@ -7,7 +7,7 @@
  *
  * RULES: Archive entries must be uncompressed, must not have separate subdir
  *  entries (but can have subdirs), must be case insensitive LOW ASCII
- *  filenames <= 56 bytes. No symlinks, etc. We can relax some of these rules
+ *  filenames <= 64 bytes. No symlinks, etc. We can relax some of these rules
  *  as necessary.
  *
  * Please see the file LICENSE.txt in the source's root directory.
@@ -34,7 +34,7 @@
 } UNPKfileinfo;
 
 
-void UNPK_closeArchive(PHYSFS_Dir *opaque)
+void UNPK_closeArchive(void *opaque)
 {
     UNPKinfo *info = ((UNPKinfo *) opaque);
     info->io->destroy(info->io);
@@ -200,7 +200,7 @@
                 rc = -1;
             else if (ch > '/')
                 rc = 1;
-            else
+            else 
             {
                 if (stop_on_first_find) /* Just checking dir's existance? */
                     return middle;
@@ -242,8 +242,8 @@
 } /* doEnumCallback */
 
 
-void UNPK_enumerateFiles(PHYSFS_Dir *opaque, const char *dname,
-                         int omitSymLinks, PHYSFS_EnumFilesCallback cb,
+void UNPK_enumerateFiles(void *opaque, const char *dname,
+                         PHYSFS_EnumFilesCallback cb,
                          const char *origdir, void *callbackdata)
 {
     UNPKinfo *info = ((UNPKinfo *) opaque);
@@ -293,7 +293,7 @@
 
 /*
  * This will find the UNPKentry associated with a path in platform-independent
- *  notation. Directories don't have UNPKentries associated with them, but
+ *  notation. Directories don't have UNPKentries associated with them, but 
  *  (*isDir) will be set to non-zero if a dir was hit.
  */
 static UNPKentry *findEntry(const UNPKinfo *info, const char *path, int *isDir)
@@ -340,19 +340,18 @@
     if (isDir != NULL)
         *isDir = 0;
 
-    BAIL_MACRO(PHYSFS_ERR_NO_SUCH_PATH, NULL);
+    BAIL_MACRO(PHYSFS_ERR_NOT_FOUND, NULL);
 } /* findEntry */
 
 
-PHYSFS_Io *UNPK_openRead(PHYSFS_Dir *opaque, const char *fnm, int *fileExists)
+PHYSFS_Io *UNPK_openRead(void *opaque, const char *name)
 {
     PHYSFS_Io *retval = NULL;
     UNPKinfo *info = (UNPKinfo *) opaque;
     UNPKfileinfo *finfo = NULL;
     int isdir = 0;
-    UNPKentry *entry = findEntry(info, fnm, &isdir);
+    UNPKentry *entry = findEntry(info, name, &isdir);
 
-    *fileExists = (entry != NULL);
     GOTO_IF_MACRO(isdir, PHYSFS_ERR_NOT_A_FILE, UNPK_openRead_failed);
     GOTO_IF_MACRO(!entry, ERRPASS, UNPK_openRead_failed);
 
@@ -390,32 +389,31 @@
 } /* UNPK_openRead */
 
 
-PHYSFS_Io *UNPK_openWrite(PHYSFS_Dir *opaque, const char *name)
+PHYSFS_Io *UNPK_openWrite(void *opaque, const char *name)
 {
     BAIL_MACRO(PHYSFS_ERR_READ_ONLY, NULL);
 } /* UNPK_openWrite */
 
 
-PHYSFS_Io *UNPK_openAppend(PHYSFS_Dir *opaque, const char *name)
+PHYSFS_Io *UNPK_openAppend(void *opaque, const char *name)
 {
     BAIL_MACRO(PHYSFS_ERR_READ_ONLY, NULL);
 } /* UNPK_openAppend */
 
 
-int UNPK_remove(PHYSFS_Dir *opaque, const char *name)
+int UNPK_remove(void *opaque, const char *name)
 {
     BAIL_MACRO(PHYSFS_ERR_READ_ONLY, 0);
 } /* UNPK_remove */
 
 
-int UNPK_mkdir(PHYSFS_Dir *opaque, const char *name)
+int UNPK_mkdir(void *opaque, const char *name)
 {
     BAIL_MACRO(PHYSFS_ERR_READ_ONLY, 0);
 } /* UNPK_mkdir */
 
 
-int UNPK_stat(PHYSFS_Dir *opaque, const char *filename,
-              int *exists, PHYSFS_Stat *stat)
+int UNPK_stat(void *opaque, const char *filename, PHYSFS_Stat *stat)
 {
     int isDir = 0;
     const UNPKinfo *info = (const UNPKinfo *) opaque;
@@ -423,19 +421,16 @@
 
     if (isDir)
     {
-        *exists = 1;
         stat->filetype = PHYSFS_FILETYPE_DIRECTORY;
         stat->filesize = 0;
     } /* if */
     else if (entry != NULL)
     {
-        *exists = 1;
         stat->filetype = PHYSFS_FILETYPE_REGULAR;
         stat->filesize = entry->size;
     } /* else if */
     else
     {
-        *exists = 0;
         return 0;
     } /* else */
 
@@ -448,8 +443,7 @@
 } /* UNPK_stat */
 
 
-PHYSFS_Dir *UNPK_openArchive(PHYSFS_Io *io, UNPKentry *e,
-                             const PHYSFS_uint32 num)
+void *UNPK_openArchive(PHYSFS_Io *io, UNPKentry *e, const PHYSFS_uint32 num)
 {
     UNPKinfo *info = (UNPKinfo *) allocator.Malloc(sizeof (UNPKinfo));
     if (info == NULL)
--- a/misc/libphysfs/archiver_wad.c	Mon Apr 10 09:05:16 2017 -0400
+++ b/misc/libphysfs/archiver_wad.c	Mon Apr 10 12:06:43 2017 -0400
@@ -1,7 +1,7 @@
 /*
  * WAD support routines for PhysicsFS.
  *
- * This driver handles DOOM engine archives ("wads").
+ * This driver handles DOOM engine archives ("wads"). 
  * This format (but not this driver) was designed by id Software for use
  *  with the DOOM engine.
  * The specs of the format are from the unofficial doom specs v1.666
@@ -28,7 +28,7 @@
  *    (c) an 8-byte ASCII string, the name of the lump, padded with zeros.
  *        For example, the "DEMO1" entry in hexadecimal would be
  *        (44 45 4D 4F 31 00 00 00)
- *
+ * 
  * Note that there is no way to tell if an opened WAD archive is a
  *  IWAD or PWAD with this archiver.
  * I couldn't think of a way to provide that information, without being too
@@ -104,24 +104,26 @@
 
 const PHYSFS_Archiver __PHYSFS_Archiver_WAD =
 {
+    CURRENT_PHYSFS_ARCHIVER_API_VERSION,
     {
         "WAD",
         "DOOM engine format",
         "Travis Wells <traviswells@mchsi.com>",
         "http://www.3dmm2.com/doom/",
+        0,  /* supportsSymlinks */
     },
-    WAD_openArchive,        /* openArchive() method    */
-    UNPK_enumerateFiles,     /* enumerateFiles() method */
-    UNPK_openRead,           /* openRead() method       */
-    UNPK_openWrite,          /* openWrite() method      */
-    UNPK_openAppend,         /* openAppend() method     */
-    UNPK_remove,             /* remove() method         */
-    UNPK_mkdir,              /* mkdir() method          */
-    UNPK_closeArchive,       /* closeArchive() method   */
-    UNPK_stat                /* stat() method           */
+    WAD_openArchive,
+    UNPK_enumerateFiles,
+    UNPK_openRead,
+    UNPK_openWrite,
+    UNPK_openAppend,
+    UNPK_remove,
+    UNPK_mkdir,
+    UNPK_stat,
+    UNPK_closeArchive
 };
 
 #endif  /* defined PHYSFS_SUPPORTS_WAD */
 
-/* end of wad.c ... */
+/* end of archiver_wad.c ... */
 
--- a/misc/libphysfs/archiver_zip.c	Mon Apr 10 09:05:16 2017 -0400
+++ b/misc/libphysfs/archiver_zip.c	Mon Apr 10 12:06:43 2017 -0400
@@ -15,12 +15,7 @@
 #include <errno.h>
 #include <time.h>
 
-#define USE_MINIZ 1
-#if USE_MINIZ
 #include "physfs_miniz.h"
-#else
-#include <zlib.h>
-#endif
 
 /*
  * A buffer of ZIP_READBUFSIZE is allocated for each compressed file opened,
@@ -51,6 +46,7 @@
     ZIP_UNRESOLVED_SYMLINK,
     ZIP_RESOLVING,
     ZIP_RESOLVED,
+    ZIP_DIRECTORY,
     ZIP_BROKEN_FILE,
     ZIP_BROKEN_SYMLINK
 } ZipResolveType;
@@ -67,11 +63,16 @@
     PHYSFS_uint64 offset;               /* offset of data in archive      */
     PHYSFS_uint16 version;              /* version made by                */
     PHYSFS_uint16 version_needed;       /* version needed to extract      */
+    PHYSFS_uint16 general_bits;         /* general purpose bits           */
     PHYSFS_uint16 compression_method;   /* compression method             */
     PHYSFS_uint32 crc;                  /* crc-32                         */
     PHYSFS_uint64 compressed_size;      /* compressed size                */
     PHYSFS_uint64 uncompressed_size;    /* uncompressed size              */
     PHYSFS_sint64 last_mod_time;        /* last file mod time             */
+    PHYSFS_uint32 dos_mod_time;         /* original MS-DOS style mod time */
+    struct _ZIPentry *hashnext;         /* next item in this hash bucket  */
+    struct _ZIPentry *children;         /* linked list of kids, if dir    */
+    struct _ZIPentry *sibling;          /* next item in same dir          */
 } ZIPentry;
 
 /*
@@ -79,10 +80,12 @@
  */
 typedef struct
 {
-    PHYSFS_Io *io;
-    int zip64;                /* non-zero if this is a Zip64 archive. */
-    PHYSFS_uint64 entryCount; /* Number of files in ZIP.              */
-    ZIPentry *entries;        /* info on all files in ZIP.            */
+    PHYSFS_Io *io;            /* the i/o interface for this archive.    */
+    ZIPentry root;            /* root of directory tree.                */
+    ZIPentry **hash;          /* all entries hashed for fast lookup.    */
+    size_t hashBuckets;       /* number of buckets in hash.             */
+    int zip64;                /* non-zero if this is a Zip64 archive.   */
+    int has_crypto;           /* non-zero if any entry uses encryption. */
 } ZIPinfo;
 
 /*
@@ -95,6 +98,8 @@
     PHYSFS_uint32 compressed_position;    /* offset in compressed data. */
     PHYSFS_uint32 uncompressed_position;  /* tell() position.           */
     PHYSFS_uint8 *buffer;                 /* decompression buffer.      */
+    PHYSFS_uint32 crypto_keys[3];         /* for "traditional" crypto.  */
+    PHYSFS_uint32 initial_crypto_keys[3]; /* for "traditional" crypto.  */
     z_stream stream;                      /* zlib stream state.         */
 } ZIPfileinfo;
 
@@ -115,6 +120,103 @@
 #define UNIX_FILETYPE_MASK    0170000
 #define UNIX_FILETYPE_SYMLINK 0120000
 
+#define ZIP_GENERAL_BITS_TRADITIONAL_CRYPTO   (1 << 0)
+#define ZIP_GENERAL_BITS_IGNORE_LOCAL_HEADER  (1 << 3)
+
+/* support for "traditional" PKWARE encryption. */
+static int zip_entry_is_tradional_crypto(const ZIPentry *entry)
+{
+    return (entry->general_bits & ZIP_GENERAL_BITS_TRADITIONAL_CRYPTO) != 0;
+} /* zip_entry_is_traditional_crypto */
+
+static int zip_entry_ignore_local_header(const ZIPentry *entry)
+{
+    return (entry->general_bits & ZIP_GENERAL_BITS_IGNORE_LOCAL_HEADER) != 0;
+} /* zip_entry_is_traditional_crypto */
+
+static PHYSFS_uint32 zip_crypto_crc32(const PHYSFS_uint32 crc, const PHYSFS_uint8 val)
+{
+    int i;
+    PHYSFS_uint32 xorval = (crc ^ ((PHYSFS_uint32) val)) & 0xFF;
+    for (i = 0; i < 8; i++)
+        xorval = ((xorval & 1) ? (0xEDB88320 ^ (xorval >> 1)) : (xorval >> 1));
+    return xorval ^ (crc >> 8);
+} /* zip_crc32 */
+
+static void zip_update_crypto_keys(PHYSFS_uint32 *keys, const PHYSFS_uint8 val)
+{
+    keys[0] = zip_crypto_crc32(keys[0], val);
+    keys[1] = keys[1] + (keys[0] & 0x000000FF);
+    keys[1] = (keys[1] * 134775813) + 1;
+    keys[2] = zip_crypto_crc32(keys[2], (PHYSFS_uint8) ((keys[1] >> 24) & 0xFF));
+} /* zip_update_crypto_keys */
+
+static PHYSFS_uint8 zip_decrypt_byte(const PHYSFS_uint32 *keys)
+{
+    const PHYSFS_uint16 tmp = keys[2] | 2;
+    return (PHYSFS_uint8) ((tmp * (tmp ^ 1)) >> 8);
+} /* zip_decrypt_byte */
+
+static PHYSFS_sint64 zip_read_decrypt(ZIPfileinfo *finfo, void *buf, PHYSFS_uint64 len)
+{
+    PHYSFS_Io *io = finfo->io;
+    const PHYSFS_sint64 br = io->read(io, buf, len);
+
+    /* Decompression the new data if necessary. */
+    if (zip_entry_is_tradional_crypto(finfo->entry) && (br > 0))
+    {
+        PHYSFS_uint32 *keys = finfo->crypto_keys;
+        PHYSFS_uint8 *ptr = (PHYSFS_uint8 *) buf;
+        PHYSFS_sint64 i;
+        for (i = 0; i < br; i++, ptr++)
+        {
+            const PHYSFS_uint8 ch = *ptr ^ zip_decrypt_byte(keys);
+            zip_update_crypto_keys(keys, ch);
+            *ptr = ch;
+        } /* for */
+    } /* if  */
+
+    return br;
+} /* zip_read_decrypt */
+
+static int zip_prep_crypto_keys(ZIPfileinfo *finfo, const PHYSFS_uint8 *crypto_header, const PHYSFS_uint8 *password)
+{
+    /* It doesn't appear to be documented in PKWare's APPNOTE.TXT, but you
+       need to use a different byte in the header to verify the password
+       if general purpose bit 3 is set. Discovered this from Info-Zip.
+       That's what the (verifier) value is doing, below. */
+
+    PHYSFS_uint32 *keys = finfo->crypto_keys;
+    const ZIPentry *entry = finfo->entry;
+    const int usedate = zip_entry_ignore_local_header(entry);
+    const PHYSFS_uint8 verifier = (PHYSFS_uint8) ((usedate ? (entry->dos_mod_time >> 8) : (entry->crc >> 24)) & 0xFF);
+    PHYSFS_uint8 finalbyte = 0;
+    int i = 0;
+
+    /* initialize vector with defaults, then password, then header. */
+    keys[0] = 305419896;
+    keys[1] = 591751049;
+    keys[2] = 878082192;
+
+    while (*password)
+        zip_update_crypto_keys(keys, *(password++));
+
+    for (i = 0; i < 12; i++)
+    {
+        const PHYSFS_uint8 c = crypto_header[i] ^ zip_decrypt_byte(keys);
+        zip_update_crypto_keys(keys, c);
+        finalbyte = c;
+    } /* for */
+
+    /* you have a 1/256 chance of passing this test incorrectly. :/ */
+    if (finalbyte != verifier)
+        BAIL_MACRO(PHYSFS_ERR_BAD_PASSWORD, 0);
+
+    /* save the initial vector for seeking purposes. Not secure!! */
+    memcpy(finfo->initial_crypto_keys, finfo->crypto_keys, 12);
+    return 1;
+} /* zip_prep_crypto_keys */
+
 
 /*
  * Bridge physfs allocation functions to zlib's format...
@@ -163,10 +265,17 @@
  */
 static int zlib_err(const int rc)
 {
-    __PHYSFS_setError(zlib_error_code(rc));
+    PHYSFS_setErrorCode(zlib_error_code(rc));
     return rc;
 } /* zlib_err */
 
+/*
+ * Hash a string for lookup an a ZIPinfo hashtable.
+ */
+static inline PHYSFS_uint32 zip_hash_string(const ZIPinfo *info, const char *s)
+{
+    return __PHYSFS_hashString(s, strlen(s)) % info->hashBuckets;
+} /* zip_hash_string */
 
 /*
  * Read an unsigned 64-bit int and swap to native byte order.
@@ -206,7 +315,6 @@
 static PHYSFS_sint64 ZIP_read(PHYSFS_Io *_io, void *buf, PHYSFS_uint64 len)
 {
     ZIPfileinfo *finfo = (ZIPfileinfo *) _io->opaque;
-    PHYSFS_Io *io = finfo->io;
     ZIPentry *entry = finfo->entry;
     PHYSFS_sint64 retval = 0;
     PHYSFS_sint64 maxread = (PHYSFS_sint64) len;
@@ -219,7 +327,7 @@
     BAIL_IF_MACRO(maxread == 0, ERRPASS, 0);    /* quick rejection. */
 
     if (entry->compression_method == COMPMETH_NONE)
-        retval = io->read(io, buf, maxread);
+        retval = zip_read_decrypt(finfo, buf, maxread);
     else
     {
         finfo->stream.next_out = buf;
@@ -240,7 +348,7 @@
                     if (br > ZIP_READBUFSIZE)
                         br = ZIP_READBUFSIZE;
 
-                    br = io->read(io, finfo->buffer, (PHYSFS_uint64) br);
+                    br = zip_read_decrypt(finfo, finfo->buffer, (PHYSFS_uint64) br);
                     if (br <= 0)
                         break;
 
@@ -282,12 +390,13 @@
     ZIPfileinfo *finfo = (ZIPfileinfo *) _io->opaque;
     ZIPentry *entry = finfo->entry;
     PHYSFS_Io *io = finfo->io;
+    const int encrypted = zip_entry_is_tradional_crypto(entry);
 
     BAIL_IF_MACRO(offset > entry->uncompressed_size, PHYSFS_ERR_PAST_EOF, 0);
 
-    if (entry->compression_method == COMPMETH_NONE)
+    if (!encrypted && (entry->compression_method == COMPMETH_NONE))
     {
-        const PHYSFS_sint64 newpos = offset + entry->offset;
+        PHYSFS_sint64 newpos = offset + entry->offset;
         BAIL_IF_MACRO(!io->seek(io, newpos), ERRPASS, 0);
         finfo->uncompressed_position = (PHYSFS_uint32) offset;
     } /* if */
@@ -308,13 +417,16 @@
             if (zlib_err(inflateInit2(&str, -MAX_WBITS)) != Z_OK)
                 return 0;
 
-            if (!io->seek(io, entry->offset))
+            if (!io->seek(io, entry->offset + (encrypted ? 12 : 0)))
                 return 0;
 
             inflateEnd(&finfo->stream);
             inflateCopy(&finfo->stream, &str);
             inflateEnd(&str);
             finfo->uncompressed_position = finfo->compressed_position = 0;
+
+            if (encrypted)
+                memcpy(finfo->crypto_keys, finfo->initial_crypto_keys, 12);
         } /* if */
 
         while (finfo->uncompressed_position != offset)
@@ -435,7 +547,7 @@
     int found = 0;
 
     filelen = io->length(io);
-    BAIL_IF_MACRO(filelen == -1, ERRPASS, 0);
+    BAIL_IF_MACRO(filelen == -1, ERRPASS, -1);
 
     /*
      * Jump to the end of the file and start reading backwards.
@@ -489,7 +601,7 @@
                 (buf[i + 3] == 0x06) )
             {
                 found = 1;  /* that's the signature! */
-                break;
+                break;  
             } /* if */
         } /* for */
 
@@ -537,71 +649,35 @@
 } /* isZip */
 
 
-static void zip_free_entries(ZIPentry *entries, PHYSFS_uint64 max)
+/* Find the ZIPentry for a path in platform-independent notation. */
+static ZIPentry *zip_find_entry(ZIPinfo *info, const char *path)
 {
-    PHYSFS_uint64 i;
-    for (i = 0; i < max; i++)
+    PHYSFS_uint32 hashval;
+    ZIPentry *prev = NULL;
+    ZIPentry *retval;
+
+    if (*path == '\0')
+        return &info->root;
+
+    hashval = zip_hash_string(info, path);
+    for (retval = info->hash[hashval]; retval; retval = retval->hashnext)
     {
-        ZIPentry *entry = &entries[i];
-        if (entry->name != NULL)
-            allocator.Free(entry->name);
+        if (strcmp(retval->name, path) == 0)
+        {
+            if (prev != NULL)  /* move this to the front of the list */
+            {
+                prev->hashnext = retval->hashnext;
+                retval->hashnext = info->hash[hashval];
+                info->hash[hashval] = retval;
+            } /* if */
+
+            return retval;
+        } /* if */
+
+        prev = retval;
     } /* for */
 
-    allocator.Free(entries);
-} /* zip_free_entries */
-
-
-/*
- * This will find the ZIPentry associated with a path in platform-independent
- *  notation. Directories don't have ZIPentries associated with them, but
- *  (*isDir) will be set to non-zero if a dir was hit.
- */
-static ZIPentry *zip_find_entry(const ZIPinfo *info, const char *path,
-                                int *isDir)
-{
-    ZIPentry *a = info->entries;
-    PHYSFS_sint32 pathlen = (PHYSFS_sint32) strlen(path);
-    PHYSFS_sint64 lo = 0;
-    PHYSFS_sint64 hi = (PHYSFS_sint64) (info->entryCount - 1);
-    PHYSFS_sint64 middle;
-    const char *thispath = NULL;
-    int rc;
-
-    while (lo <= hi)
-    {
-        middle = lo + ((hi - lo) / 2);
-        thispath = a[middle].name;
-        rc = strncmp(path, thispath, pathlen);
-
-        if (rc > 0)
-            lo = middle + 1;
-
-        else if (rc < 0)
-            hi = middle - 1;
-
-        else /* substring match...might be dir or entry or nothing. */
-        {
-            if (isDir != NULL)
-            {
-                *isDir = (thispath[pathlen] == '/');
-                if (*isDir)
-                    return NULL;
-            } /* if */
-
-            if (thispath[pathlen] == '\0') /* found entry? */
-                return &a[middle];
-            /* adjust search params, try again. */
-            else if (thispath[pathlen] > '/')
-                hi = middle - 1;
-            else
-                lo = middle + 1;
-        } /* if */
-    } /* while */
-
-    if (isDir != NULL)
-        *isDir = 0;
-
-    BAIL_MACRO(PHYSFS_ERR_NO_SUCH_PATH, NULL);
+    BAIL_MACRO(PHYSFS_ERR_NOT_FOUND, NULL);
 } /* zip_find_entry */
 
 
@@ -693,7 +769,7 @@
     ZIPentry *entry;
 
     zip_expand_symlink_path(path);
-    entry = zip_find_entry(info, path, NULL);
+    entry = zip_find_entry(info, path);
     if (entry != NULL)
     {
         if (!zip_resolve(io, info, entry))  /* recursive! */
@@ -725,7 +801,7 @@
 
     path = (char *) __PHYSFS_smallAlloc(size + 1);
     BAIL_IF_MACRO(!path, PHYSFS_ERR_OUT_OF_MEMORY, 0);
-
+    
     if (entry->compression_method == COMPMETH_NONE)
         rc = __PHYSFS_readAll(io, path, size);
 
@@ -788,6 +864,10 @@
      *  possible that's a Zip64 thing.
      */
 
+    /* !!! FIXME: apparently these are zero if general purpose bit 3 is set,
+       !!! FIXME:  which is probably true for Jar files, fwiw, but we don't
+       !!! FIXME:  care about these values anyhow. */
+
     BAIL_IF_MACRO(!io->seek(io, entry->offset), ERRPASS, 0);
     BAIL_IF_MACRO(!readui32(io, &ui32), ERRPASS, 0);
     BAIL_IF_MACRO(ui32 != ZIP_LOCAL_FILE_SIG, PHYSFS_ERR_CORRUPT, 0);
@@ -819,7 +899,10 @@
 static int zip_resolve(PHYSFS_Io *io, ZIPinfo *info, ZIPentry *entry)
 {
     int retval = 1;
-    ZipResolveType resolve_type = entry->resolved;
+    const ZipResolveType resolve_type = entry->resolved;
+
+    if (resolve_type == ZIP_DIRECTORY)
+        return 1;   /* we're good. */
 
     /* Don't bother if we've failed to resolve this entry before. */
     BAIL_IF_MACRO(resolve_type == ZIP_BROKEN_FILE, PHYSFS_ERR_CORRUPT, 0);
@@ -861,6 +944,77 @@
 } /* zip_resolve */
 
 
+static int zip_hash_entry(ZIPinfo *info, ZIPentry *entry);
+
+/* Fill in missing parent directories. */
+static ZIPentry *zip_hash_ancestors(ZIPinfo *info, char *name)
+{
+    ZIPentry *retval = &info->root;
+    char *sep = strrchr(name, '/');
+
+    if (sep)
+    {
+        const size_t namelen = (sep - name) + 1;
+
+        *sep = '\0';  /* chop off last piece. */
+        retval = zip_find_entry(info, name);
+        *sep = '/';
+
+        if (retval != NULL)
+        {
+            if (retval->resolved != ZIP_DIRECTORY)
+                BAIL_MACRO(PHYSFS_ERR_CORRUPT, NULL);
+            return retval;  /* already hashed. */
+        } /* if */
+
+        /* okay, this is a new dir. Build and hash us. */
+        retval = (ZIPentry *) allocator.Malloc(sizeof (ZIPentry) + namelen);
+        BAIL_IF_MACRO(!retval, PHYSFS_ERR_OUT_OF_MEMORY, NULL);
+        memset(retval, '\0', sizeof (*retval));
+        retval->name = ((char *) retval) + sizeof (ZIPentry);
+        memcpy(retval->name, name, namelen);
+        retval->name[namelen] = '\0';
+        retval->resolved = ZIP_DIRECTORY;
+        if (!zip_hash_entry(info, retval))
+        {
+            allocator.Free(retval);
+            return NULL;
+        } /* if */
+    } /* else */
+
+    return retval;
+} /* zip_hash_ancestors */
+
+
+static int zip_hash_entry(ZIPinfo *info, ZIPentry *entry)
+{
+    PHYSFS_uint32 hashval;
+    ZIPentry *parent;
+
+    assert(!zip_find_entry(info, entry->name));  /* checked elsewhere */
+
+    parent = zip_hash_ancestors(info, entry->name);
+    if (!parent)
+        return 0;
+
+    hashval = zip_hash_string(info, entry->name);
+    entry->hashnext = info->hash[hashval];
+    info->hash[hashval] = entry;
+
+    entry->sibling = parent->children;
+    parent->children = entry;
+    return 1;
+} /* zip_hash_entry */
+
+
+static int zip_entry_is_symlink(const ZIPentry *entry)
+{
+    return ((entry->resolved == ZIP_UNRESOLVED_SYMLINK) ||
+            (entry->resolved == ZIP_BROKEN_SYMLINK) ||
+            (entry->symlink));
+} /* zip_entry_is_symlink */
+
+
 static int zip_version_does_symlinks(PHYSFS_uint32 version)
 {
     int retval = 0;
@@ -893,14 +1047,6 @@
 } /* zip_version_does_symlinks */
 
 
-static int zip_entry_is_symlink(const ZIPentry *entry)
-{
-    return ((entry->resolved == ZIP_UNRESOLVED_SYMLINK) ||
-            (entry->resolved == ZIP_BROKEN_SYMLINK) ||
-            (entry->symlink));
-} /* zip_entry_is_symlink */
-
-
 static int zip_has_symlink_attr(ZIPentry *entry, PHYSFS_uint32 extern_attr)
 {
     PHYSFS_uint16 xattr = ((extern_attr >> 16) & 0xFFFF);
@@ -936,9 +1082,11 @@
 } /* zip_dos_time_to_physfs_time */
 
 
-static int zip_load_entry(PHYSFS_Io *io, const int zip64, ZIPentry *entry,
-                          PHYSFS_uint64 ofs_fixup)
+static ZIPentry *zip_load_entry(PHYSFS_Io *io, const int zip64,
+                                const PHYSFS_uint64 ofs_fixup)
 {
+    ZIPentry entry;
+    ZIPentry *retval = NULL;
     PHYSFS_uint16 fnamelen, extralen, commentlen;
     PHYSFS_uint32 external_attr;
     PHYSFS_uint32 starting_disk;
@@ -947,43 +1095,57 @@
     PHYSFS_uint32 ui32;
     PHYSFS_sint64 si64;
 
+    memset(&entry, '\0', sizeof (entry));
+
     /* sanity check with central directory signature... */
-    BAIL_IF_MACRO(!readui32(io, &ui32), ERRPASS, 0);
-    BAIL_IF_MACRO(ui32 != ZIP_CENTRAL_DIR_SIG, PHYSFS_ERR_CORRUPT, 0);
+    if (!readui32(io, &ui32)) return NULL;
+    BAIL_IF_MACRO(ui32 != ZIP_CENTRAL_DIR_SIG, PHYSFS_ERR_CORRUPT, NULL);
 
     /* Get the pertinent parts of the record... */
-    BAIL_IF_MACRO(!readui16(io, &entry->version), ERRPASS, 0);
-    BAIL_IF_MACRO(!readui16(io, &entry->version_needed), ERRPASS, 0);
-    BAIL_IF_MACRO(!readui16(io, &ui16), ERRPASS, 0);  /* general bits */
-    BAIL_IF_MACRO(!readui16(io, &entry->compression_method), ERRPASS, 0);
-    BAIL_IF_MACRO(!readui32(io, &ui32), ERRPASS, 0);
-    entry->last_mod_time = zip_dos_time_to_physfs_time(ui32);
-    BAIL_IF_MACRO(!readui32(io, &entry->crc), ERRPASS, 0);
-    BAIL_IF_MACRO(!readui32(io, &ui32), ERRPASS, 0);
-    entry->compressed_size = (PHYSFS_uint64) ui32;
-    BAIL_IF_MACRO(!readui32(io, &ui32), ERRPASS, 0);
-    entry->uncompressed_size = (PHYSFS_uint64) ui32;
-    BAIL_IF_MACRO(!readui16(io, &fnamelen), ERRPASS, 0);
-    BAIL_IF_MACRO(!readui16(io, &extralen), ERRPASS, 0);
-    BAIL_IF_MACRO(!readui16(io, &commentlen), ERRPASS, 0);
-    BAIL_IF_MACRO(!readui16(io, &ui16), ERRPASS, 0);
+    if (!readui16(io, &entry.version)) return NULL;
+    if (!readui16(io, &entry.version_needed)) return NULL;
+    if (!readui16(io, &entry.general_bits)) return NULL;  /* general bits */
+    if (!readui16(io, &entry.compression_method)) return NULL;
+    if (!readui32(io, &entry.dos_mod_time)) return NULL;
+    entry.last_mod_time = zip_dos_time_to_physfs_time(entry.dos_mod_time);
+    if (!readui32(io, &entry.crc)) return NULL;
+    if (!readui32(io, &ui32)) return NULL;
+    entry.compressed_size = (PHYSFS_uint64) ui32;
+    if (!readui32(io, &ui32)) return NULL;
+    entry.uncompressed_size = (PHYSFS_uint64) ui32;
+    if (!readui16(io, &fnamelen)) return NULL;
+    if (!readui16(io, &extralen)) return NULL;
+    if (!readui16(io, &commentlen)) return NULL;
+    if (!readui16(io, &ui16)) return NULL;
     starting_disk = (PHYSFS_uint32) ui16;
-    BAIL_IF_MACRO(!readui16(io, &ui16), ERRPASS, 0);  /* internal file attribs */
-    BAIL_IF_MACRO(!readui32(io, &external_attr), ERRPASS, 0);
-    BAIL_IF_MACRO(!readui32(io, &ui32), ERRPASS, 0);
+    if (!readui16(io, &ui16)) return NULL;  /* internal file attribs */
+    if (!readui32(io, &external_attr)) return NULL;
+    if (!readui32(io, &ui32)) return NULL;
     offset = (PHYSFS_uint64) ui32;
 
-    entry->symlink = NULL;  /* will be resolved later, if necessary. */
-    entry->resolved = (zip_has_symlink_attr(entry, external_attr)) ?
-                            ZIP_UNRESOLVED_SYMLINK : ZIP_UNRESOLVED_FILE;
+    retval = (ZIPentry *) allocator.Malloc(sizeof (ZIPentry) + fnamelen + 1);
+    BAIL_IF_MACRO(retval == NULL, PHYSFS_ERR_OUT_OF_MEMORY, 0);
+    memcpy(retval, &entry, sizeof (*retval));
+    retval->name = ((char *) retval) + sizeof (ZIPentry);
 
-    entry->name = (char *) allocator.Malloc(fnamelen + 1);
-    BAIL_IF_MACRO(entry->name == NULL, PHYSFS_ERR_OUT_OF_MEMORY, 0);
-    if (!__PHYSFS_readAll(io, entry->name, fnamelen))
+    if (!__PHYSFS_readAll(io, retval->name, fnamelen))
         goto zip_load_entry_puked;
 
-    entry->name[fnamelen] = '\0';  /* null-terminate the filename. */
-    zip_convert_dos_path(entry, entry->name);
+    retval->name[fnamelen] = '\0';  /* null-terminate the filename. */
+    zip_convert_dos_path(retval, retval->name);
+
+    retval->symlink = NULL;  /* will be resolved later, if necessary. */
+
+    if (retval->name[fnamelen - 1] == '/')
+    {
+        retval->name[fnamelen - 1] = '\0';
+        retval->resolved = ZIP_DIRECTORY;
+    } /* if */
+    else
+    {
+        retval->resolved = (zip_has_symlink_attr(&entry, external_attr)) ?
+                                ZIP_UNRESOLVED_SYMLINK : ZIP_UNRESOLVED_FILE;
+    } /* else */
 
     si64 = io->tell(io);
     if (si64 == -1)
@@ -996,8 +1158,8 @@
     if ( (zip64) &&
          ((offset == 0xFFFFFFFF) ||
           (starting_disk == 0xFFFFFFFF) ||
-          (entry->compressed_size == 0xFFFFFFFF) ||
-          (entry->uncompressed_size == 0xFFFFFFFF)) )
+          (retval->compressed_size == 0xFFFFFFFF) ||
+          (retval->uncompressed_size == 0xFFFFFFFF)) )
     {
         int found = 0;
         PHYSFS_uint16 sig, len;
@@ -1023,18 +1185,18 @@
 
         GOTO_IF_MACRO(!found, PHYSFS_ERR_CORRUPT, zip_load_entry_puked);
 
-        if (entry->uncompressed_size == 0xFFFFFFFF)
+        if (retval->uncompressed_size == 0xFFFFFFFF)
         {
             GOTO_IF_MACRO(len < 8, PHYSFS_ERR_CORRUPT, zip_load_entry_puked);
-            if (!readui64(io, &entry->uncompressed_size))
+            if (!readui64(io, &retval->uncompressed_size))
                 goto zip_load_entry_puked;
             len -= 8;
         } /* if */
 
-        if (entry->compressed_size == 0xFFFFFFFF)
+        if (retval->compressed_size == 0xFFFFFFFF)
         {
             GOTO_IF_MACRO(len < 8, PHYSFS_ERR_CORRUPT, zip_load_entry_puked);
-            if (!readui64(io, &entry->compressed_size))
+            if (!readui64(io, &retval->compressed_size))
                 goto zip_load_entry_puked;
             len -= 8;
         } /* if */
@@ -1060,69 +1222,74 @@
 
     GOTO_IF_MACRO(starting_disk != 0, PHYSFS_ERR_CORRUPT, zip_load_entry_puked);
 
-    entry->offset = offset + ofs_fixup;
+    retval->offset = offset + ofs_fixup;
 
     /* seek to the start of the next entry in the central directory... */
     if (!io->seek(io, si64 + extralen + commentlen))
         goto zip_load_entry_puked;
 
-    return 1;  /* success. */
+    return retval;  /* success. */
 
 zip_load_entry_puked:
-    allocator.Free(entry->name);
-    return 0;  /* failure. */
+    allocator.Free(retval);
+    return NULL;  /* failure. */
 } /* zip_load_entry */
 
 
-static int zip_entry_cmp(void *_a, size_t one, size_t two)
-{
-    if (one != two)
-    {
-        const ZIPentry *a = (const ZIPentry *) _a;
-        return strcmp(a[one].name, a[two].name);
-    } /* if */
-
-    return 0;
-} /* zip_entry_cmp */
-
-
-static void zip_entry_swap(void *_a, size_t one, size_t two)
+/* This leaves things allocated on error; the caller will clean up the mess. */
+static int zip_load_entries(ZIPinfo *info,
+                            const PHYSFS_uint64 data_ofs,
+                            const PHYSFS_uint64 central_ofs,
+                            const PHYSFS_uint64 entry_count)
 {
-    if (one != two)
-    {
-        ZIPentry tmp;
-        ZIPentry *first = &(((ZIPentry *) _a)[one]);
-        ZIPentry *second = &(((ZIPentry *) _a)[two]);
-        memcpy(&tmp, first, sizeof (ZIPentry));
-        memcpy(first, second, sizeof (ZIPentry));
-        memcpy(second, &tmp, sizeof (ZIPentry));
-    } /* if */
-} /* zip_entry_swap */
-
-
-static int zip_load_entries(PHYSFS_Io *io, ZIPinfo *info,
-                            const PHYSFS_uint64 data_ofs,
-                            const PHYSFS_uint64 central_ofs)
-{
-    const PHYSFS_uint64 max = info->entryCount;
+    PHYSFS_Io *io = info->io;
     const int zip64 = info->zip64;
     PHYSFS_uint64 i;
 
-    BAIL_IF_MACRO(!io->seek(io, central_ofs), ERRPASS, 0);
+    if (!io->seek(io, central_ofs))
+        return 0;
 
-    info->entries = (ZIPentry *) allocator.Malloc(sizeof (ZIPentry) * max);
-    BAIL_IF_MACRO(!info->entries, PHYSFS_ERR_OUT_OF_MEMORY, 0);
+    for (i = 0; i < entry_count; i++)
+    {
+        ZIPentry *entry = zip_load_entry(io, zip64, data_ofs);
+        ZIPentry *find;
+
+        if (!entry)
+            return 0;
 
-    for (i = 0; i < max; i++)
-    {
-        if (!zip_load_entry(io, zip64, &info->entries[i], data_ofs))
+        find = zip_find_entry(info, entry->name);
+        if (find != NULL)  /* duplicate? */
         {
-            zip_free_entries(info->entries, i);
+            if (find->last_mod_time != 0)  /* duplicate? */
+            {
+                allocator.Free(entry);
+                BAIL_MACRO(PHYSFS_ERR_CORRUPT, 0);
+            } /* if */
+            else  /* we filled this in as a placeholder. Update it. */
+            {
+                find->offset = entry->offset;
+                find->version = entry->version;
+                find->version_needed = entry->version_needed;
+                find->compression_method = entry->compression_method;
+                find->crc = entry->crc;
+                find->compressed_size = entry->compressed_size;
+                find->uncompressed_size = entry->uncompressed_size;
+                find->last_mod_time = entry->last_mod_time;
+                allocator.Free(entry);
+                continue;
+            } /* else */
+        } /* if */
+
+        if (!zip_hash_entry(info, entry))
+        {
+            allocator.Free(entry);
             return 0;
         } /* if */
+
+        if (zip_entry_is_tradional_crypto(entry))
+            info->has_crypto = 1;
     } /* for */
 
-    __PHYSFS_sort(info->entries, (size_t) max, zip_entry_cmp, zip_entry_swap);
     return 1;
 } /* zip_load_entries */
 
@@ -1182,36 +1349,47 @@
     /*  Just try moving back at most 256k. Oh well. */
     if ((offset < pos) && (pos > 4))
     {
-        /* we assume you can eat this stack if you handle Zip64 files. */
-        PHYSFS_uint8 buf[256 * 1024];
+        const PHYSFS_uint64 maxbuflen = 256 * 1024;
         PHYSFS_uint64 len = pos - offset;
+        PHYSFS_uint8 *buf = NULL;
         PHYSFS_sint32 i;
 
-        if (len > sizeof (buf))
-            len = sizeof (buf);
+        if (len > maxbuflen)
+            len = maxbuflen;
+
+        buf = (PHYSFS_uint8 *) __PHYSFS_smallAlloc(len);
+        BAIL_IF_MACRO(!buf, PHYSFS_ERR_OUT_OF_MEMORY, -1);
 
-        BAIL_IF_MACRO(!io->seek(io, pos - len), ERRPASS, -1);
-        BAIL_IF_MACRO(!__PHYSFS_readAll(io, buf, len), ERRPASS, -1);
+        if (!io->seek(io, pos - len) || !__PHYSFS_readAll(io, buf, len))
+        {
+            __PHYSFS_smallFree(buf);
+            return -1;  /* error was set elsewhere. */
+        } /* if */
+
         for (i = (PHYSFS_sint32) (len - 4); i >= 0; i--)
         {
-            if (buf[i] != 0x50)
-                continue;
-            if ( (buf[i+1] == 0x4b) &&
-                 (buf[i+2] == 0x06) &&
-                 (buf[i+3] == 0x06) )
+            if ( (buf[i] == 0x50) && (buf[i+1] == 0x4b) &&
+                 (buf[i+2] == 0x06) && (buf[i+3] == 0x06) )
+            {
+                __PHYSFS_smallFree(buf);
                 return pos - (len - i);
+            } /* if */
         } /* for */
+
+        __PHYSFS_smallFree(buf);
     } /* if */
 
     BAIL_MACRO(PHYSFS_ERR_CORRUPT, -1);  /* didn't find it. */
 } /* zip64_find_end_of_central_dir */
 
 
-static int zip64_parse_end_of_central_dir(PHYSFS_Io *io, ZIPinfo *info,
+static int zip64_parse_end_of_central_dir(ZIPinfo *info,
                                           PHYSFS_uint64 *data_start,
                                           PHYSFS_uint64 *dir_ofs,
+                                          PHYSFS_uint64 *entry_count,
                                           PHYSFS_sint64 pos)
 {
+    PHYSFS_Io *io = info->io;
     PHYSFS_uint64 ui64;
     PHYSFS_uint32 ui32;
     PHYSFS_uint16 ui16;
@@ -1279,8 +1457,8 @@
     BAIL_IF_MACRO(!readui64(io, &ui64), ERRPASS, 0);
 
     /* total number of entries in the central dir */
-    BAIL_IF_MACRO(!readui64(io, &info->entryCount), ERRPASS, 0);
-    BAIL_IF_MACRO(ui64 != info->entryCount, PHYSFS_ERR_CORRUPT, 0);
+    BAIL_IF_MACRO(!readui64(io, entry_count), ERRPASS, 0);
+    BAIL_IF_MACRO(ui64 != *entry_count, PHYSFS_ERR_CORRUPT, 0);
 
     /* size of the central directory */
     BAIL_IF_MACRO(!readui64(io, &ui64), ERRPASS, 0);
@@ -1300,10 +1478,12 @@
 } /* zip64_parse_end_of_central_dir */
 
 
-static int zip_parse_end_of_central_dir(PHYSFS_Io *io, ZIPinfo *info,
+static int zip_parse_end_of_central_dir(ZIPinfo *info,
                                         PHYSFS_uint64 *data_start,
-                                        PHYSFS_uint64 *dir_ofs)
+                                        PHYSFS_uint64 *dir_ofs,
+                                        PHYSFS_uint64 *entry_count)
 {
+    PHYSFS_Io *io = info->io;
     PHYSFS_uint16 entryCount16;
     PHYSFS_uint32 offset32;
     PHYSFS_uint32 ui32;
@@ -1323,10 +1503,12 @@
 
     /* Seek back to see if "Zip64 end of central directory locator" exists. */
     /* this record is 20 bytes before end-of-central-dir */
-    rc = zip64_parse_end_of_central_dir(io, info, data_start, dir_ofs, pos-20);
-    BAIL_IF_MACRO(rc == 0, ERRPASS, 0);
-    if (rc == 1)
-        return 1;  /* we're done here. */
+    rc = zip64_parse_end_of_central_dir(info, data_start, dir_ofs,
+                                        entry_count, pos - 20);
+
+    /* Error or success? Bounce out of here. Keep going if not zip64. */
+    if ((rc == 0) || (rc == 1))
+        return rc;
 
     assert(rc == -1);  /* no error, just not a Zip64 archive. */
 
@@ -1348,7 +1530,7 @@
     BAIL_IF_MACRO(!readui16(io, &entryCount16), ERRPASS, 0);
     BAIL_IF_MACRO(ui16 != entryCount16, PHYSFS_ERR_CORRUPT, 0);
 
-    info->entryCount = entryCount16;
+    *entry_count = entryCount16;
 
     /* size of the central directory */
     BAIL_IF_MACRO(!readui32(io, &ui32), ERRPASS, 0);
@@ -1385,11 +1567,30 @@
 } /* zip_parse_end_of_central_dir */
 
 
+static int zip_alloc_hashtable(ZIPinfo *info, const PHYSFS_uint64 entry_count)
+{
+    size_t alloclen;
+
+    info->hashBuckets = (size_t) (entry_count / 5);
+    if (!info->hashBuckets)
+        info->hashBuckets = 1;
+
+    alloclen = info->hashBuckets * sizeof (ZIPentry *);
+    info->hash = (ZIPentry **) allocator.Malloc(alloclen);
+    BAIL_IF_MACRO(!info->hash, PHYSFS_ERR_OUT_OF_MEMORY, 0);
+    memset(info->hash, '\0', alloclen);
+
+    return 1;
+} /* zip_alloc_hashtable */
+
+static void ZIP_closeArchive(void *opaque);
+
 static void *ZIP_openArchive(PHYSFS_Io *io, const char *name, int forWriting)
 {
     ZIPinfo *info = NULL;
-    PHYSFS_uint64 data_start;
-    PHYSFS_uint64 cent_dir_ofs;
+    PHYSFS_uint64 dstart;  /* data start */
+    PHYSFS_uint64 cdir_ofs;  /* central dir offset */
+    PHYSFS_uint64 entry_count;
 
     assert(io != NULL);  /* shouldn't ever happen. */
 
@@ -1399,138 +1600,40 @@
     info = (ZIPinfo *) allocator.Malloc(sizeof (ZIPinfo));
     BAIL_IF_MACRO(!info, PHYSFS_ERR_OUT_OF_MEMORY, NULL);
     memset(info, '\0', sizeof (ZIPinfo));
+    info->root.resolved = ZIP_DIRECTORY;
     info->io = io;
 
-    if (!zip_parse_end_of_central_dir(io, info, &data_start, &cent_dir_ofs))
+    if (!zip_parse_end_of_central_dir(info, &dstart, &cdir_ofs, &entry_count))
+        goto ZIP_openarchive_failed;
+    else if (!zip_alloc_hashtable(info, entry_count))
+        goto ZIP_openarchive_failed;
+    else if (!zip_load_entries(info, dstart, cdir_ofs, entry_count))
         goto ZIP_openarchive_failed;
 
-    if (!zip_load_entries(io, info, data_start, cent_dir_ofs))
-        goto ZIP_openarchive_failed;
-
+    assert(info->root.sibling == NULL);
     return info;
 
 ZIP_openarchive_failed:
-    if (info != NULL)
-        allocator.Free(info);
-
+    info->io = NULL;  /* don't let ZIP_closeArchive destroy (io). */
+    ZIP_closeArchive(info);
     return NULL;
 } /* ZIP_openArchive */
 
 
-static PHYSFS_sint64 zip_find_start_of_dir(ZIPinfo *info, const char *path,
-                                            int stop_on_first_find)
-{
-    PHYSFS_sint64 lo = 0;
-    PHYSFS_sint64 hi = (PHYSFS_sint64) (info->entryCount - 1);
-    PHYSFS_sint64 middle;
-    PHYSFS_uint32 dlen = (PHYSFS_uint32) strlen(path);
-    PHYSFS_sint64 retval = -1;
-    const char *name;
-    int rc;
-
-    if (*path == '\0')  /* root dir? */
-        return 0;
-
-    if ((dlen > 0) && (path[dlen - 1] == '/')) /* ignore trailing slash. */
-        dlen--;
-
-    while (lo <= hi)
-    {
-        middle = lo + ((hi - lo) / 2);
-        name = info->entries[middle].name;
-        rc = strncmp(path, name, dlen);
-        if (rc == 0)
-        {
-            char ch = name[dlen];
-            if ('/' < ch) /* make sure this isn't just a substr match. */
-                rc = -1;
-            else if ('/' > ch)
-                rc = 1;
-            else
-            {
-                if (stop_on_first_find) /* Just checking dir's existance? */
-                    return middle;
-
-                if (name[dlen + 1] == '\0') /* Skip initial dir entry. */
-                    return (middle + 1);
-
-                /* there might be more entries earlier in the list. */
-                retval = middle;
-                hi = middle - 1;
-            } /* else */
-        } /* if */
-
-        if (rc > 0)
-            lo = middle + 1;
-        else
-            hi = middle - 1;
-    } /* while */
-
-    return retval;
-} /* zip_find_start_of_dir */
-
-
-/*
- * Moved to seperate function so we can use alloca then immediately throw
- *  away the allocated stack space...
- */
-static void doEnumCallback(PHYSFS_EnumFilesCallback cb, void *callbackdata,
-                           const char *odir, const char *str, PHYSFS_sint32 ln)
-{
-    char *newstr = __PHYSFS_smallAlloc(ln + 1);
-    if (newstr == NULL)
-        return;
-
-    memcpy(newstr, str, ln);
-    newstr[ln] = '\0';
-    cb(callbackdata, odir, newstr);
-    __PHYSFS_smallFree(newstr);
-} /* doEnumCallback */
-
-
-static void ZIP_enumerateFiles(PHYSFS_Dir *opaque, const char *dname,
-                               int omitSymLinks, PHYSFS_EnumFilesCallback cb,
+static void ZIP_enumerateFiles(void *opaque, const char *dname,
+                               PHYSFS_EnumFilesCallback cb,
                                const char *origdir, void *callbackdata)
 {
     ZIPinfo *info = ((ZIPinfo *) opaque);
-    PHYSFS_sint32 dlen, dlen_inc;
-    PHYSFS_sint64 i, max;
-
-    i = zip_find_start_of_dir(info, dname, 0);
-    if (i == -1)  /* no such directory. */
-        return;
-
-    dlen = (PHYSFS_sint32) strlen(dname);
-    if ((dlen > 0) && (dname[dlen - 1] == '/')) /* ignore trailing slash. */
-        dlen--;
-
-    dlen_inc = ((dlen > 0) ? 1 : 0) + dlen;
-    max = (PHYSFS_sint64) info->entryCount;
-    while (i < max)
+    const ZIPentry *entry = zip_find_entry(info, dname);
+    if (entry && (entry->resolved == ZIP_DIRECTORY))
     {
-        char *e = info->entries[i].name;
-        if ((dlen) && ((strncmp(e, dname, dlen) != 0) || (e[dlen] != '/')))
-            break;  /* past end of this dir; we're done. */
-
-        if ((omitSymLinks) && (zip_entry_is_symlink(&info->entries[i])))
-            i++;
-        else
+        for (entry = entry->children; entry; entry = entry->sibling)
         {
-            char *add = e + dlen_inc;
-            char *ptr = strchr(add, '/');
-            PHYSFS_sint32 ln = (PHYSFS_sint32) ((ptr) ? ptr-add : strlen(add));
-            doEnumCallback(cb, callbackdata, origdir, add, ln);
-            ln += dlen_inc;  /* point past entry to children... */
-
-            /* increment counter and skip children of subdirs... */
-            while ((++i < max) && (ptr != NULL))
-            {
-                char *e_new = info->entries[i].name;
-                if ((strncmp(e, e_new, ln) != 0) || (e_new[ln] != '/'))
-                    break;
-            } /* while */
-        } /* else */
-    } /* while */
+            const char *ptr = strrchr(entry->name, '/');
+            cb(callbackdata, origdir, ptr ? ptr + 1 : entry->name);
+        } /* for */
+    } /* if */
 } /* ZIP_enumerateFiles */
 
 
@@ -1561,15 +1664,33 @@
 } /* zip_get_io */
 
 
-static PHYSFS_Io *ZIP_openRead(PHYSFS_Dir *opaque, const char *fnm,
-                               int *fileExists)
+static PHYSFS_Io *ZIP_openRead(void *opaque, const char *filename)
 {
     PHYSFS_Io *retval = NULL;
     ZIPinfo *info = (ZIPinfo *) opaque;
-    ZIPentry *entry = zip_find_entry(info, fnm, NULL);
+    ZIPentry *entry = zip_find_entry(info, filename);
     ZIPfileinfo *finfo = NULL;
+    PHYSFS_Io *io = NULL;
+    PHYSFS_uint8 *password = NULL;
+    int i;
 
-    *fileExists = (entry != NULL);
+    /* if not found, see if maybe "$PASSWORD" is appended. */
+    if ((!entry) && (info->has_crypto))
+    {
+        const char *ptr = strrchr(filename, '$');
+        if (ptr != NULL)
+        {
+            const PHYSFS_uint64 len = (PHYSFS_uint64) (ptr - filename);
+            char *str = (char *) __PHYSFS_smallAlloc(len + 1);
+            BAIL_IF_MACRO(!str, PHYSFS_ERR_OUT_OF_MEMORY, NULL);
+            memcpy(str, filename, len);
+            str[len] = '\0';
+            entry = zip_find_entry(info, str);
+            __PHYSFS_smallFree(str);
+            password = (PHYSFS_uint8 *) (ptr + 1);
+        } /* if */
+    } /* if */
+
     BAIL_IF_MACRO(!entry, ERRPASS, NULL);
 
     retval = (PHYSFS_Io *) allocator.Malloc(sizeof (PHYSFS_Io));
@@ -1579,8 +1700,9 @@
     GOTO_IF_MACRO(!finfo, PHYSFS_ERR_OUT_OF_MEMORY, ZIP_openRead_failed);
     memset(finfo, '\0', sizeof (ZIPfileinfo));
 
-    finfo->io = zip_get_io(info->io, info, entry);
-    GOTO_IF_MACRO(!finfo->io, ERRPASS, ZIP_openRead_failed);
+    io = zip_get_io(info->io, info, entry);
+    GOTO_IF_MACRO(!io, ERRPASS, ZIP_openRead_failed);
+    finfo->io = io;
     finfo->entry = ((entry->symlink != NULL) ? entry->symlink : entry);
     initializeZStream(&finfo->stream);
 
@@ -1593,6 +1715,18 @@
             goto ZIP_openRead_failed;
     } /* if */
 
+    if (!zip_entry_is_tradional_crypto(entry))
+        GOTO_IF_MACRO(password != NULL, PHYSFS_ERR_BAD_PASSWORD, ZIP_openRead_failed);
+    else
+    {
+        PHYSFS_uint8 crypto_header[12];
+        GOTO_IF_MACRO(password == NULL, PHYSFS_ERR_BAD_PASSWORD, ZIP_openRead_failed);
+        if (io->read(io, crypto_header, 12) != 12)
+            goto ZIP_openRead_failed;
+        else if (!zip_prep_crypto_keys(finfo, crypto_header, password))
+            goto ZIP_openRead_failed;
+    } /* if */
+
     memcpy(retval, &ZIP_Io, sizeof (PHYSFS_Io));
     retval->opaque = finfo;
 
@@ -1620,53 +1754,74 @@
 } /* ZIP_openRead */
 
 
-static PHYSFS_Io *ZIP_openWrite(PHYSFS_Dir *opaque, const char *filename)
+static PHYSFS_Io *ZIP_openWrite(void *opaque, const char *filename)
 {
     BAIL_MACRO(PHYSFS_ERR_READ_ONLY, NULL);
 } /* ZIP_openWrite */
 
 
-static PHYSFS_Io *ZIP_openAppend(PHYSFS_Dir *opaque, const char *filename)
+static PHYSFS_Io *ZIP_openAppend(void *opaque, const char *filename)
 {
     BAIL_MACRO(PHYSFS_ERR_READ_ONLY, NULL);
 } /* ZIP_openAppend */
 
 
-static void ZIP_closeArchive(PHYSFS_Dir *opaque)
+static void ZIP_closeArchive(void *opaque)
 {
-    ZIPinfo *zi = (ZIPinfo *) (opaque);
-    zi->io->destroy(zi->io);
-    zip_free_entries(zi->entries, zi->entryCount);
-    allocator.Free(zi);
+    ZIPinfo *info = (ZIPinfo *) (opaque);
+
+    if (!info)
+        return;
+
+    if (info->io)
+        info->io->destroy(info->io);
+
+    assert(info->root.sibling == NULL);
+    assert(info->hash || (info->root.children == NULL));
+
+    if (info->hash)
+    {
+        size_t i;
+        for (i = 0; i < info->hashBuckets; i++)
+        {
+            ZIPentry *entry;
+            ZIPentry *next;
+            for (entry = info->hash[i]; entry; entry = next)
+            {
+                next = entry->hashnext;
+                allocator.Free(entry);
+            } /* for */
+        } /* for */
+        allocator.Free(info->hash);
+    } /* if */
+
+    allocator.Free(info);
 } /* ZIP_closeArchive */
 
 
-static int ZIP_remove(PHYSFS_Dir *opaque, const char *name)
+static int ZIP_remove(void *opaque, const char *name)
 {
     BAIL_MACRO(PHYSFS_ERR_READ_ONLY, 0);
 } /* ZIP_remove */
 
 
-static int ZIP_mkdir(PHYSFS_Dir *opaque, const char *name)
+static int ZIP_mkdir(void *opaque, const char *name)
 {
     BAIL_MACRO(PHYSFS_ERR_READ_ONLY, 0);
 } /* ZIP_mkdir */
 
 
-static int ZIP_stat(PHYSFS_Dir *opaque, const char *filename, int *exists,
-                    PHYSFS_Stat *stat)
+static int ZIP_stat(void *opaque, const char *filename, PHYSFS_Stat *stat)
 {
-    int isDir = 0;
-    const ZIPinfo *info = (const ZIPinfo *) opaque;
-    const ZIPentry *entry = zip_find_entry(info, filename, &isDir);
+    ZIPinfo *info = (ZIPinfo *) opaque;
+    const ZIPentry *entry = zip_find_entry(info, filename);
 
     /* !!! FIXME: does this need to resolve entries here? */
 
-    *exists = isDir || (entry != 0);
-    if (!*exists)
+    if (entry == NULL)
         return 0;
 
-    if (isDir)
+    else if (entry->resolved == ZIP_DIRECTORY)
     {
         stat->filesize = 0;
         stat->filetype = PHYSFS_FILETYPE_DIRECTORY;
@@ -1695,24 +1850,26 @@
 
 const PHYSFS_Archiver __PHYSFS_Archiver_ZIP =
 {
+    CURRENT_PHYSFS_ARCHIVER_API_VERSION,
     {
         "ZIP",
         "PkZip/WinZip/Info-Zip compatible",
         "Ryan C. Gordon <icculus@icculus.org>",
-        "http://icculus.org/physfs/",
+        "https://icculus.org/physfs/",
+        1,  /* supportsSymlinks */
     },
-    ZIP_openArchive,        /* openArchive() method    */
-    ZIP_enumerateFiles,     /* enumerateFiles() method */
-    ZIP_openRead,           /* openRead() method       */
-    ZIP_openWrite,          /* openWrite() method      */
-    ZIP_openAppend,         /* openAppend() method     */
-    ZIP_remove,             /* remove() method         */
-    ZIP_mkdir,              /* mkdir() method          */
-    ZIP_closeArchive,       /* closeArchive() method   */
-    ZIP_stat                /* stat() method           */
+    ZIP_openArchive,
+    ZIP_enumerateFiles,
+    ZIP_openRead,
+    ZIP_openWrite,
+    ZIP_openAppend,
+    ZIP_remove,
+    ZIP_mkdir,
+    ZIP_stat,
+    ZIP_closeArchive
 };
 
 #endif  /* defined PHYSFS_SUPPORTS_ZIP */
 
-/* end of zip.c ... */
+/* end of archiver_zip.c ... */
 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/misc/libphysfs/lzma/7zC.txt	Mon Apr 10 12:06:43 2017 -0400
@@ -0,0 +1,237 @@
+7z ANSI-C Decoder 4.48
+----------------------
+
+7z ANSI-C Decoder 4.48 Copyright (C) 1999-2006 Igor Pavlov
+
+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
+-------
+
+Read lzma.txt for information about license.
+
+
+Files
+---------------------
+
+7zAlloc.*    - Allocate and Free
+7zBuffer.*   - Buffer structure
+7zCrc.*      - CRC32 code
+7zDecode.*   - Low level memory->memory decoding
+7zExtract.*  - High level stream->memory decoding
+7zHeader.*   - .7z format constants
+7zIn.*       - .7z archive opening
+7zItem.*     - .7z structures
+7zMain.c     - Test application
+7zMethodID.* - MethodID structure
+7zTypes.h    - Base types and constants
+
+
+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
+----------------------
+
+.7z Decoder can be compiled in one of two modes:
+
+1) Default mode. In that mode 7z Decoder will read full compressed 
+   block to RAM before decompressing.
+  
+2) Mode with defined _LZMA_IN_CB. In that mode 7z Decoder can read
+   compressed block by parts. And you can specify desired buffer size. 
+   So memory requirements can be reduced. But decompressing speed will 
+   be 5-10% lower and code size is slightly larger.
+
+   
+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 ISzInStream interface */
+  CArchiveDatabaseEx db;       /* 7z archive database structure */
+  ISzAlloc allocImp;           /* memory functions for main pool */
+  ISzAlloc allocTempImp;       /* memory functions for temporary pool */
+
+2) call InitCrcTable(); function to initialize CRC structures.
+
+3) call SzArDbExInit(&db); function to initialize db structures.
+
+4) call SzArchiveOpen(inStream, &db, &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.
+SzArchiveOpen function allocates and frees temporary structures by "allocTemp" functions.
+
+5) List items or Extract items
+
+  Listing code:
+  ~~~~~~~~~~~~~
+    {
+      UInt32 i;
+      for (i = 0; i < db.Database.NumFiles; i++)
+      {
+        CFileItem *f = db.Database.Files + i;
+        printf("%10d  %s\n", (int)f->Size, f->Name);
+      }
+    }
+
+  Extracting code:
+  ~~~~~~~~~~~~~~~~
+
+  SZ_RESULT SzExtract(
+    ISzInStream *inStream, 
+    CArchiveDatabaseEx *db,
+    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 SzArDbExFree(&db, allocImp.Free) to free allocated items in "db".
+
+
+
+
+Memory requirements for .7z decoding 
+------------------------------------
+
+Memory usage for Archive opening:
+  - Temporary pool:
+     - Memory for compressed .7z headers (if _LZMA_IN_CB is not defined)
+     - 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 compressed solid block (if _LZMA_IN_CB is not defined)
+     - 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. 
+  
+
+If _LZMA_IN_CB is defined, 7z Decoder will not allocate memory for 
+compressed blocks. Instead of this, you must allocate buffer with desired 
+size before calling 7z Decoder. Use 7zMain.c as example.
+
+
+
+EXIT codes
+-----------
+
+7z Decoder functions can return one of the following codes:
+
+#define SZ_OK (0)
+#define SZE_DATA_ERROR (1)
+#define SZE_OUTOFMEMORY (2)
+#define SZE_CRC_ERROR (3)
+
+#define SZE_NOTIMPL (4)
+#define SZE_FAIL (5)
+
+#define SZE_ARCHIVE_ERROR (6)
+
+
+
+LZMA Defines
+------------
+
+_LZMA_IN_CB       - Use special callback mode for input stream to reduce memory requirements
+
+_SZ_FILE_SIZE_32  - define it if you need only support for files smaller than 4 GB
+_SZ_NO_INT_64     - define it if your compiler doesn't support long long int or __int64.
+
+_LZMA_PROB32      - it can increase LZMA decompressing speed on some 32-bit CPUs.
+
+_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/support.html
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/misc/libphysfs/lzma/7zFormat.txt	Mon Apr 10 12:06:43 2017 -0400
@@ -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
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/misc/libphysfs/lzma/C/7zCrc.c	Mon Apr 10 12:06:43 2017 -0400
@@ -0,0 +1,32 @@
+/* 7zCrc.c */
+
+#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;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/misc/libphysfs/lzma/C/7zCrc.h	Mon Apr 10 12:06:43 2017 -0400
@@ -0,0 +1,21 @@
+/* 7zCrc.h */
+
+#ifndef __7Z_CRC_H
+#define __7Z_CRC_H
+
+#include <stddef.h>
+
+#include "Types.h"
+
+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);
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/misc/libphysfs/lzma/C/7zCrcT8.c	Mon Apr 10 12:06:43 2017 -0400
@@ -0,0 +1,40 @@
+/* 7zCrcT8.c */
+
+#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;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/misc/libphysfs/lzma/C/Alloc.c	Mon Apr 10 12:06:43 2017 -0400
@@ -0,0 +1,119 @@
+/* Alloc.c */
+
+#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
+  fprintf(stderr, "\nAlloc %10d bytes; count = %10d", size, g_allocCount++);
+  #endif
+  return malloc(size);
+}
+
+void MyFree(void *address)
+{
+  #ifdef _SZ_ALLOC_DEBUG
+  if (address != 0)
+    fprintf(stderr, "\nFree; count = %10d", --g_allocCount);
+  #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
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/misc/libphysfs/lzma/C/Alloc.h	Mon Apr 10 12:06:43 2017 -0400
@@ -0,0 +1,29 @@
+/* Alloc.h */
+
+#ifndef __COMMON_ALLOC_H
+#define __COMMON_ALLOC_H
+
+#include <stddef.h>
+
+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
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/misc/libphysfs/lzma/C/Archive/7z/7zAlloc.c	Mon Apr 10 12:06:43 2017 -0400
@@ -0,0 +1,70 @@
+/* 7zAlloc.c */
+
+#include <stdlib.h>
+#include "7zAlloc.h"
+
+/* #define _SZ_ALLOC_DEBUG */
+/* use _SZ_ALLOC_DEBUG to debug alloc/free operations */
+
+#ifdef _SZ_ALLOC_DEBUG
+
+#ifdef _WIN32
+#include <windows.h>
+#endif
+#include <stdio.h>
+int g_allocCount = 0;
+int g_allocCountTemp = 0;
+#endif
+
+void *SzAlloc(size_t size)
+{
+  if (size == 0)
+    return 0;
+  #ifdef _SZ_ALLOC_DEBUG
+  fprintf(stderr, "\nAlloc %10d bytes; count = %10d", size, g_allocCount);
+  g_allocCount++;
+  #endif
+  return malloc(size);
+}
+
+void SzFree(void *address)
+{
+  #ifdef _SZ_ALLOC_DEBUG
+  if (address != 0)
+  {
+    g_allocCount--;
+    fprintf(stderr, "\nFree; count = %10d", g_allocCount);
+  }
+  #endif
+  free(address);
+}
+
+void *SzAllocTemp(size_t size)
+{
+  if (size == 0)
+    return 0;
+  #ifdef _SZ_ALLOC_DEBUG
+  fprintf(stderr, "\nAlloc_temp %10d bytes;  count = %10d", size, g_allocCountTemp);
+  g_allocCountTemp++;
+  #ifdef _WIN32
+  return HeapAlloc(GetProcessHeap(), 0, size);
+  #endif
+  #endif
+  return malloc(size);
+}
+
+void SzFreeTemp(void *address)
+{
+  #ifdef _SZ_ALLOC_DEBUG
+  if (address != 0)
+  {
+    g_allocCountTemp--;
+    fprintf(stderr, "\nFree_temp; count = %10d", g_allocCountTemp);
+  }
+  #ifdef _WIN32
+  HeapFree(GetProcessHeap(), 0, address);
+  return;
+  #endif
+  #endif
+  free(address);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/misc/libphysfs/lzma/C/Archive/7z/7zAlloc.h	Mon Apr 10 12:06:43 2017 -0400
@@ -0,0 +1,20 @@
+/* 7zAlloc.h */
+
+#ifndef __7Z_ALLOC_H
+#define __7Z_ALLOC_H
+
+#include <stddef.h>
+
+typedef struct _ISzAlloc
+{
+  void *(*Alloc)(size_t size);
+  void (*Free)(void *address); /* address can be 0 */
+} ISzAlloc;
+
+void *SzAlloc(size_t size);
+void SzFree(void *address);
+
+void *SzAllocTemp(size_t size);
+void SzFreeTemp(void *address);
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/misc/libphysfs/lzma/C/Archive/7z/7zBuffer.c	Mon Apr 10 12:06:43 2017 -0400
@@ -0,0 +1,29 @@
+/* 7zBuffer.c */
+
+#include "7zBuffer.h"
+#include "7zAlloc.h"
+
+void SzByteBufferInit(CSzByteBuffer *buffer)
+{
+  buffer->Capacity = 0;
+  buffer->Items = 0;
+}
+
+int SzByteBufferCreate(CSzByteBuffer *buffer, size_t newCapacity, void * (*allocFunc)(size_t size))
+{
+  buffer->Capacity = newCapacity;
+  if (newCapacity == 0)
+  {
+    buffer->Items = 0;
+    return 1;
+  }
+  buffer->Items = (Byte *)allocFunc(newCapacity);
+  return (buffer->Items != 0);
+}
+
+void SzByteBufferFree(CSzByteBuffer *buffer, void (*freeFunc)(void *))
+{
+  freeFunc(buffer->Items);
+  buffer->Items = 0;
+  buffer->Capacity = 0;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/misc/libphysfs/lzma/C/Archive/7z/7zBuffer.h	Mon Apr 10 12:06:43 2017 -0400
@@ -0,0 +1,19 @@
+/* 7zBuffer.h */
+
+#ifndef __7Z_BUFFER_H
+#define __7Z_BUFFER_H
+
+#include <stddef.h>
+#include "../../Types.h"
+
+typedef struct _CSzByteBuffer
+{
+  size_t Capacity;
+  Byte *Items;
+}CSzByteBuffer;
+
+void SzByteBufferInit(CSzByteBuffer *buffer);
+int SzByteBufferCreate(CSzByteBuffer *buffer, size_t newCapacity, void * (*allocFunc)(size_t size));
+void SzByteBufferFree(CSzByteBuffer *buffer, void (*freeFunc)(void *));
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/misc/libphysfs/lzma/C/Archive/7z/7zDecode.c	Mon Apr 10 12:06:43 2017 -0400
@@ -0,0 +1,345 @@
+/* 7zDecode.c */
+
+#include <memory.h>
+
+/* BEGIN PHYSFS CHANGE */
+#include <string.h>
+/* END PHYSFS CHANGE */
+
+#include "7zDecode.h"
+#ifdef _SZ_ONE_DIRECTORY
+#include "LzmaDecode.h"
+#else
+#include "../../Compress/Lzma/LzmaDecode.h"
+#include "../../Compress/Branch/BranchX86.h"
+#include "../../Compress/Branch/BranchX86_2.h"
+#endif
+
+#define k_Copy 0
+#define k_LZMA 0x30101
+#define k_BCJ 0x03030103
+#define k_BCJ2 0x0303011B
+
+#ifdef _LZMA_IN_CB
+
+typedef struct _CLzmaInCallbackImp
+{
+  ILzmaInCallback InCallback;
+  ISzInStream *InStream;
+  CFileSize Size;
+} CLzmaInCallbackImp;
+
+int LzmaReadImp(void *object, const unsigned char **buffer, SizeT *size)
+{
+  CLzmaInCallbackImp *cb = (CLzmaInCallbackImp *)object;
+  size_t processedSize;
+  SZ_RESULT res;
+  size_t curSize = (1 << 20);
+  if (curSize > cb->Size)
+    curSize = (size_t)cb->Size;
+  *size = 0;
+  res = cb->InStream->Read((void *)cb->InStream, (void **)buffer, curSize, &processedSize);
+  *size = (SizeT)processedSize;
+  if (processedSize > curSize)
+    return (int)SZE_FAIL;
+  cb->Size -= processedSize;
+  if (res == SZ_OK)
+    return 0;
+  return (int)res;
+}
+
+#endif
+
+SZ_RESULT SzDecodeLzma(CCoderInfo *coder, CFileSize inSize,
+    #ifdef _LZMA_IN_CB
+    ISzInStream *inStream,
+    #else
+    const Byte *inBuffer,
+    #endif
+    Byte *outBuffer, size_t outSize, ISzAlloc *allocMain)
+{
+  #ifdef _LZMA_IN_CB
+  CLzmaInCallbackImp lzmaCallback;
+  #else
+  SizeT inProcessed;
+  #endif
+  
+  CLzmaDecoderState state;  /* it's about 24-80 bytes structure, if int is 32-bit */
+  int result;
+  SizeT outSizeProcessedLoc;
+  
+  #ifdef _LZMA_IN_CB
+  lzmaCallback.Size = inSize;
+  lzmaCallback.InStream = inStream;
+  lzmaCallback.InCallback.Read = LzmaReadImp;
+  #endif
+  
+  if (LzmaDecodeProperties(&state.Properties, coder->Properties.Items, 
+      (unsigned)coder->Properties.Capacity) != LZMA_RESULT_OK)
+    return SZE_FAIL;
+  
+  state.Probs = (CProb *)allocMain->Alloc(LzmaGetNumProbs(&state.Properties) * sizeof(CProb));
+  if (state.Probs == 0)
+    return SZE_OUTOFMEMORY;
+  
+  #ifdef _LZMA_OUT_READ
+  if (state.Properties.DictionarySize == 0)
+    state.Dictionary = 0;
+  else
+  {
+    state.Dictionary = (unsigned char *)allocMain->Alloc(state.Properties.DictionarySize);
+    if (state.Dictionary == 0)
+    {
+      allocMain->Free(state.Probs);
+      return SZE_OUTOFMEMORY;
+    }
+  }
+  LzmaDecoderInit(&state);
+  #endif
+  
+  result = LzmaDecode(&state,
+  #ifdef _LZMA_IN_CB
+    &lzmaCallback.InCallback,
+  #else
+    inBuffer, (SizeT)inSize, &inProcessed,
+  #endif
+    outBuffer, (SizeT)outSize, &outSizeProcessedLoc);
+  allocMain->Free(state.Probs);
+  #ifdef _LZMA_OUT_READ
+  allocMain->Free(state.Dictionary);
+  #endif
+  if (result == LZMA_RESULT_DATA_ERROR)
+    return SZE_DATA_ERROR;
+  if (result != LZMA_RESULT_OK)
+    return SZE_FAIL;
+  return (outSizeProcessedLoc == outSize) ? SZ_OK : SZE_DATA_ERROR;
+}
+
+#ifdef _LZMA_IN_CB
+SZ_RESULT SzDecodeCopy(CFileSize inSize, ISzInStream *inStream, Byte *outBuffer)
+{
+  while (inSize > 0)
+  {
+    void *inBuffer;
+    size_t processedSize, curSize = (1 << 18);
+    if (curSize > inSize)
+      curSize = (size_t)(inSize);
+    RINOK(inStream->Read((void *)inStream, (void **)&inBuffer, curSize, &processedSize));
+    if (processedSize == 0)
+      return SZE_DATA_ERROR;
+    if (processedSize > curSize)
+      return SZE_FAIL;
+    memcpy(outBuffer, inBuffer, processedSize);
+    outBuffer += processedSize;
+    inSize -= processedSize;
+  }
+  return SZ_OK;
+}
+#endif
+
+#define IS_UNSUPPORTED_METHOD(m) ((m) != k_Copy && (m) != k_LZMA)
+#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)
+
+SZ_RESULT CheckSupportedFolder(const CFolder *f)
+{
+  if (f->NumCoders < 1 || f->NumCoders > 4)
+    return SZE_NOTIMPL;
+  if (IS_UNSUPPORTED_CODER(f->Coders[0]))
+    return SZE_NOTIMPL;
+  if (f->NumCoders == 1)
+  {
+    if (f->NumPackStreams != 1 || f->PackStreams[0] != 0 || f->NumBindPairs != 0)
+      return SZE_NOTIMPL;
+    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 SZE_NOTIMPL;
+    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 SZE_NOTIMPL;
+    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 SZE_NOTIMPL;
+    return SZ_OK;
+  }
+  return SZE_NOTIMPL;
+}
+
+CFileSize GetSum(const CFileSize *values, UInt32 index)
+{
+  CFileSize sum = 0;
+  UInt32 i;
+  for (i = 0; i < index; i++)
+    sum += values[i];
+  return sum;
+}
+
+SZ_RESULT SzDecode2(const CFileSize *packSizes, const CFolder *folder,
+    #ifdef _LZMA_IN_CB
+    ISzInStream *inStream, CFileSize startPos,
+    #else
+    const Byte *inBuffer,
+    #endif
+    Byte *outBuffer, size_t outSize, ISzAlloc *allocMain,
+    Byte *tempBuf[])
+{
+  UInt32 ci;
+  size_t tempSizes[3] = { 0, 0, 0};
+  size_t tempSize3 = 0;
+  Byte *tempBuf3 = 0;
+
+  RINOK(CheckSupportedFolder(folder));
+
+  for (ci = 0; ci < folder->NumCoders; ci++)
+  {
+    CCoderInfo *coder = &folder->Coders[ci];
+
+    if (coder->MethodID == k_Copy || coder->MethodID == k_LZMA)
+    {
+      UInt32 si = 0;
+      CFileSize offset;
+      CFileSize inSize;
+      Byte *outBufCur = outBuffer;
+      size_t outSizeCur = outSize;
+      if (folder->NumCoders == 4)
+      {
+        UInt32 indices[] = { 3, 2, 0 };
+        CFileSize unpackSize = folder->UnPackSizes[ci];
+        si = indices[ci];
+        if (ci < 2)
+        {
+          Byte *temp;
+          outSizeCur = (size_t)unpackSize;
+          if (outSizeCur != unpackSize)
+            return SZE_OUTOFMEMORY;
+          temp = (Byte *)allocMain->Alloc(outSizeCur);
+          if (temp == 0 && outSizeCur != 0)
+            return SZE_OUTOFMEMORY;
+          outBufCur = tempBuf[1 - ci] = temp;
+          tempSizes[1 - ci] = outSizeCur;
+        }
+        else if (ci == 2)
+        {
+          if (unpackSize > outSize)
+            return SZE_OUTOFMEMORY;
+          tempBuf3 = outBufCur = outBuffer + (outSize - (size_t)unpackSize);
+          tempSize3 = outSizeCur = (size_t)unpackSize;
+        }
+        else
+          return SZE_NOTIMPL;
+      }
+      offset = GetSum(packSizes, si);
+      inSize = packSizes[si];
+      #ifdef _LZMA_IN_CB
+      RINOK(inStream->Seek(inStream, startPos + offset));
+      #endif
+
+      if (coder->MethodID == k_Copy)
+      {
+        if (inSize != outSizeCur)
+          return SZE_DATA_ERROR;
+        
+        #ifdef _LZMA_IN_CB
+        RINOK(SzDecodeCopy(inSize, inStream, outBufCur));
+        #else
+        memcpy(outBufCur, inBuffer + (size_t)offset, (size_t)inSize);
+        #endif
+      }
+      else
+      {
+        SZ_RESULT res = SzDecodeLzma(coder, inSize,
+            #ifdef _LZMA_IN_CB
+            inStream,
+            #else
+            inBuffer + (size_t)offset,
+            #endif
+            outBufCur, outSizeCur, allocMain);
+        RINOK(res)
+      }
+    }
+    else if (coder->MethodID == k_BCJ)
+    {
+      UInt32 state;
+      if (ci != 1)
+        return SZE_NOTIMPL;
+      x86_Convert_Init(state);
+      x86_Convert(outBuffer, outSize, 0, &state, 0);
+    }
+    else if (coder->MethodID == k_BCJ2)
+    {
+      CFileSize offset = GetSum(packSizes, 1);
+      CFileSize s3Size = packSizes[1];
+      SZ_RESULT res;
+      if (ci != 3)
+        return SZE_NOTIMPL;
+
+      #ifdef _LZMA_IN_CB
+      RINOK(inStream->Seek(inStream, startPos + offset));
+      tempSizes[2] = (size_t)s3Size;
+      if (tempSizes[2] != s3Size)
+        return SZE_OUTOFMEMORY;
+      tempBuf[2] = (Byte *)allocMain->Alloc(tempSizes[2]);
+      if (tempBuf[2] == 0 && tempSizes[2] != 0)
+        return SZE_OUTOFMEMORY;
+      res = SzDecodeCopy(s3Size, inStream, tempBuf[2]);
+      RINOK(res)
+      #endif
+
+      res = x86_2_Decode(
+          tempBuf3, tempSize3, 
+          tempBuf[0], tempSizes[0], 
+          tempBuf[1], tempSizes[1], 
+          #ifdef _LZMA_IN_CB
+          tempBuf[2], tempSizes[2], 
+          #else
+          inBuffer + (size_t)offset, (size_t)s3Size, 
+          #endif
+          outBuffer, outSize);
+      RINOK(res)
+    }
+    else 
+      return SZE_NOTIMPL;
+  }
+  return SZ_OK;
+}
+
+SZ_RESULT SzDecode(const CFileSize *packSizes, const CFolder *folder,
+    #ifdef _LZMA_IN_CB
+    ISzInStream *inStream, CFileSize startPos,
+    #else
+    const Byte *inBuffer,
+    #endif
+    Byte *outBuffer, size_t outSize, ISzAlloc *allocMain)
+{
+  Byte *tempBuf[3] = { 0, 0, 0};
+  int i;
+  SZ_RESULT res = SzDecode2(packSizes, folder,
+      #ifdef _LZMA_IN_CB
+      inStream, startPos,
+      #else
+      inBuffer,
+      #endif
+      outBuffer, outSize, allocMain, tempBuf);
+  for (i = 0; i < 3; i++)
+    allocMain->Free(tempBuf[i]);
+  return res;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/misc/libphysfs/lzma/C/Archive/7z/7zDecode.h	Mon Apr 10 12:06:43 2017 -0400
@@ -0,0 +1,20 @@
+/* 7zDecode.h */
+
+#ifndef __7Z_DECODE_H
+#define __7Z_DECODE_H
+
+#include "7zItem.h"
+#include "7zAlloc.h"
+#ifdef _LZMA_IN_CB
+#include "7zIn.h"
+#endif
+
+SZ_RESULT SzDecode(const CFileSize *packSizes, const CFolder *folder,
+    #ifdef _LZMA_IN_CB
+    ISzInStream *stream, CFileSize startPos,
+    #else
+    const Byte *inBuffer,
+    #endif
+    Byte *outBuffer, size_t outSize, ISzAlloc *allocMain);
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/misc/libphysfs/lzma/C/Archive/7z/7zExtract.c	Mon Apr 10 12:06:43 2017 -0400
@@ -0,0 +1,119 @@
+/* 7zExtract.c */
+
+#include "7zExtract.h"
+#include "7zDecode.h"
+#include "../../7zCrc.h"
+
+SZ_RESULT SzExtract(
+    ISzInStream *inStream, 
+    CArchiveDatabaseEx *db,
+    UInt32 fileIndex,
+    UInt32 *blockIndex,
+    Byte **outBuffer, 
+    size_t *outBufferSize,
+    size_t *offset, 
+    size_t *outSizeProcessed, 
+    ISzAlloc *allocMain,
+    ISzAlloc *allocTemp)
+{
+  UInt32 folderIndex = db->FileIndexToFolderIndexMap[fileIndex];
+  SZ_RESULT res = SZ_OK;
+  *offset = 0;
+  *outSizeProcessed = 0;
+  if (folderIndex == (UInt32)-1)
+  {
+    allocMain->Free(*outBuffer);
+    *blockIndex = folderIndex;
+    *outBuffer = 0;
+    *outBufferSize = 0;
+    return SZ_OK;
+  }
+
+  if (*outBuffer == 0 || *blockIndex != folderIndex)
+  {
+    CFolder *folder = db->Database.Folders + folderIndex;
+    CFileSize unPackSizeSpec = SzFolderGetUnPackSize(folder);
+    size_t unPackSize = (size_t)unPackSizeSpec;
+    CFileSize startOffset = SzArDbGetFolderStreamPos(db, folderIndex, 0);
+    #ifndef _LZMA_IN_CB
+    Byte *inBuffer = 0;
+    size_t processedSize;
+    CFileSize packSizeSpec;
+    size_t packSize;
+    RINOK(SzArDbGetFolderFullPackSize(db, folderIndex, &packSizeSpec));
+    packSize = (size_t)packSizeSpec;
+    if (packSize != packSizeSpec)
+      return SZE_OUTOFMEMORY;
+    #endif
+    if (unPackSize != unPackSizeSpec)
+      return SZE_OUTOFMEMORY;
+    *blockIndex = folderIndex;
+    allocMain->Free(*outBuffer);
+    *outBuffer = 0;
+    
+    RINOK(inStream->Seek(inStream, startOffset));
+    
+    #ifndef _LZMA_IN_CB
+    if (packSize != 0)
+    {
+      inBuffer = (Byte *)allocTemp->Alloc(packSize);
+      if (inBuffer == 0)
+        return SZE_OUTOFMEMORY;
+    }
+    res = inStream->Read(inStream, inBuffer, packSize, &processedSize);
+    if (res == SZ_OK && processedSize != packSize)
+      res = SZE_FAIL;
+    #endif
+    if (res == SZ_OK)
+    {
+      *outBufferSize = unPackSize;
+      if (unPackSize != 0)
+      {
+        *outBuffer = (Byte *)allocMain->Alloc(unPackSize);
+        if (*outBuffer == 0)
+          res = SZE_OUTOFMEMORY;
+      }
+      if (res == SZ_OK)
+      {
+        res = SzDecode(db->Database.PackSizes + 
+          db->FolderStartPackStreamIndex[folderIndex], folder, 
+          #ifdef _LZMA_IN_CB
+          inStream, startOffset, 
+          #else
+          inBuffer, 
+          #endif
+          *outBuffer, unPackSize, allocTemp);
+        if (res == SZ_OK)
+        {
+          if (folder->UnPackCRCDefined)
+          {
+            if (CrcCalc(*outBuffer, unPackSize) != folder->UnPackCRC)
+              res = SZE_CRC_ERROR;
+          }
+        }
+      }
+    }
+    #ifndef _LZMA_IN_CB
+    allocTemp->Free(inBuffer);
+    #endif
+  }
+  if (res == SZ_OK)
+  {
+    UInt32 i; 
+    CFileItem *fileItem = db->Database.Files + fileIndex;
+    *offset = 0;
+    for(i = db->FolderStartFileIndex[folderIndex]; i < fileIndex; i++)
+      *offset += (UInt32)db->Database.Files[i].Size;
+    *outSizeProcessed = (size_t)fileItem->Size;
+    if (*offset + *outSizeProcessed > *outBufferSize)
+      return SZE_FAIL;
+    {
+      if (fileItem->IsFileCRCDefined)
+      {
+        if (CrcCalc(*outBuffer + *offset, *outSizeProcessed) != fileItem->FileCRC)
+          res = SZE_CRC_ERROR;
+      }
+    }
+  }
+  return res;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/misc/libphysfs/lzma/C/Archive/7z/7zExtract.h	Mon Apr 10 12:06:43 2017 -0400
@@ -0,0 +1,40 @@
+/* 7zExtract.h */
+
+#ifndef __7Z_EXTRACT_H
+#define __7Z_EXTRACT_H
+
+#include "7zIn.h"
+
+/*
+  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.
+*/
+
+SZ_RESULT SzExtract(
+    ISzInStream *inStream, 
+    CArchiveDatabaseEx *db,
+    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);
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/misc/libphysfs/lzma/C/Archive/7z/7zHeader.c	Mon Apr 10 12:06:43 2017 -0400
@@ -0,0 +1,5 @@
+/*  7zHeader.c */
+
+#include "7zHeader.h"
+
+Byte k7zSignature[k7zSignatureSize] = {'7', 'z', 0xBC, 0xAF, 0x27, 0x1C};
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/misc/libphysfs/lzma/C/Archive/7z/7zHeader.h	Mon Apr 10 12:06:43 2017 -0400
@@ -0,0 +1,55 @@
+/* 7zHeader.h */
+
+#ifndef __7Z_HEADER_H
+#define __7Z_HEADER_H
+
+#include "../../Types.h"
+
+#define k7zSignatureSize 6
+extern Byte k7zSignature[k7zSignatureSize];
+
+#define k7zMajorVersion 0
+
+#define k7zStartHeaderSize 0x20
+
+enum EIdEnum
+{
+  k7zIdEnd,
+    
+  k7zIdHeader,
+    
+  k7zIdArchiveProperties,
+    
+  k7zIdAdditionalStreamsInfo,
+  k7zIdMainStreamsInfo,
+  k7zIdFilesInfo,
+  
+  k7zIdPackInfo,
+  k7zIdUnPackInfo,
+  k7zIdSubStreamsInfo,
+  
+  k7zIdSize,
+  k7zIdCRC,
+  
+  k7zIdFolder,
+  
+  k7zIdCodersUnPackSize,
+  k7zIdNumUnPackStream,
+  
+  k7zIdEmptyStream,
+  k7zIdEmptyFile,
+  k7zIdAnti,
+  
+  k7zIdName,
+  k7zIdCreationTime,
+  k7zIdLastAccessTime,
+  k7zIdLastWriteTime,
+  k7zIdWinAttributes,
+  k7zIdComment,
+  
+  k7zIdEncodedHeader,
+  
+  k7zIdStartPos
+};
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/misc/libphysfs/lzma/C/Archive/7z/7zIn.c	Mon Apr 10 12:06:43 2017 -0400
@@ -0,0 +1,1314 @@
+/* 7zIn.c */
+
+#include "7zIn.h"
+#include "7zDecode.h"
+#include "../../7zCrc.h"
+
+#define RINOM(x) { if((x) == 0) return SZE_OUTOFMEMORY; }
+
+void SzArDbExInit(CArchiveDatabaseEx *db)
+{
+  SzArchiveDatabaseInit(&db->Database);
+  db->FolderStartPackStreamIndex = 0;
+  db->PackStreamStartPositions = 0;
+  db->FolderStartFileIndex = 0;
+  db->FileIndexToFolderIndexMap = 0;
+}
+
+void SzArDbExFree(CArchiveDatabaseEx *db, void (*freeFunc)(void *))
+{
+  freeFunc(db->FolderStartPackStreamIndex);
+  freeFunc(db->PackStreamStartPositions);
+  freeFunc(db->FolderStartFileIndex);
+  freeFunc(db->FileIndexToFolderIndexMap);
+  SzArchiveDatabaseFree(&db->Database, freeFunc);
+  SzArDbExInit(db);
+}
+
+/*
+CFileSize GetFolderPackStreamSize(int folderIndex, int streamIndex) const 
+{
+  return PackSizes[FolderStartPackStreamIndex[folderIndex] + streamIndex];
+}
+
+CFileSize GetFilePackSize(int fileIndex) const
+{
+  int folderIndex = FileIndexToFolderIndexMap[fileIndex];
+  if (folderIndex >= 0)
+  {
+    const CFolder &folderInfo = Folders[folderIndex];
+    if (FolderStartFileIndex[folderIndex] == fileIndex)
+    return GetFolderFullPackSize(folderIndex);
+  }
+  return 0;
+}
+*/
+
+#define MY_ALLOC(T, p, size, allocFunc) { if ((size) == 0) p = 0; else \
+  if ((p = (T *)allocFunc((size) * sizeof(T))) == 0) return SZE_OUTOFMEMORY; }
+
+SZ_RESULT SzArDbExFill(CArchiveDatabaseEx *db, void * (*allocFunc)(size_t size))
+{
+  UInt32 startPos = 0;
+  CFileSize startPosSize = 0;
+  UInt32 i;
+  UInt32 folderIndex = 0;
+  UInt32 indexInFolder = 0;
+  MY_ALLOC(UInt32, db->FolderStartPackStreamIndex, db->Database.NumFolders, allocFunc);
+  for(i = 0; i < db->Database.NumFolders; i++)
+  {
+    db->FolderStartPackStreamIndex[i] = startPos;
+    startPos += db->Database.Folders[i].NumPackStreams;
+  }
+
+  MY_ALLOC(CFileSize, db->PackStreamStartPositions, db->Database.NumPackStreams, allocFunc);
+
+  for(i = 0; i < db->Database.NumPackStreams; i++)
+  {
+    db->PackStreamStartPositions[i] = startPosSize;
+    startPosSize += db->Database.PackSizes[i];
+  }
+
+  MY_ALLOC(UInt32, db->FolderStartFileIndex, db->Database.NumFolders, allocFunc);
+  MY_ALLOC(UInt32, db->FileIndexToFolderIndexMap, db->Database.NumFiles, allocFunc);
+
+  for (i = 0; i < db->Database.NumFiles; i++)
+  {
+    CFileItem *file = db->Database.Files + i;
+    int emptyStream = !file->HasStream;
+    if (emptyStream && indexInFolder == 0)
+    {
+      db->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 >= db->Database.NumFolders)
+          return SZE_ARCHIVE_ERROR;
+        db->FolderStartFileIndex[folderIndex] = i;
+        if (db->Database.Folders[folderIndex].NumUnPackStreams != 0)
+          break;
+        folderIndex++;
+      }
+    }
+    db->FileIndexToFolderIndexMap[i] = folderIndex;
+    if (emptyStream)
+      continue;
+    indexInFolder++;
+    if (indexInFolder >= db->Database.Folders[folderIndex].NumUnPackStreams)
+    {
+      folderIndex++;
+      indexInFolder = 0;
+    }
+  }
+  return SZ_OK;
+}
+
+
+CFileSize SzArDbGetFolderStreamPos(CArchiveDatabaseEx *db, UInt32 folderIndex, UInt32 indexInFolder)
+{
+  return db->ArchiveInfo.DataStartPosition + 
+    db->PackStreamStartPositions[db->FolderStartPackStreamIndex[folderIndex] + indexInFolder];
+}
+
+int SzArDbGetFolderFullPackSize(CArchiveDatabaseEx *db, UInt32 folderIndex, CFileSize *resSize)
+{
+  UInt32 packStreamIndex = db->FolderStartPackStreamIndex[folderIndex];
+  CFolder *folder = db->Database.Folders + folderIndex;
+  CFileSize size = 0;
+  UInt32 i;
+  for (i = 0; i < folder->NumPackStreams; i++)
+  {
+    CFileSize t = size + db->Database.PackSizes[packStreamIndex + i];
+    if (t < size)
+      return SZE_FAIL;
+    size = t;
+  }
+  *resSize = size;
+  return SZ_OK;
+}
+
+
+/*
+SZ_RESULT SzReadTime(const CObjectVector<CSzByteBuffer> &dataVector,
+    CObjectVector<CFileItem> &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++)
+  {
+    CFileItem &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 k7zIdCreationTime:
+        file.IsCreationTimeDefined = defined;
+        if (defined)
+          file.CreationTime = fileTime;
+        break;
+      case k7zIdLastWriteTime:
+        file.IsLastWriteTimeDefined = defined;
+        if (defined)
+          file.LastWriteTime = fileTime;
+        break;
+      case k7zIdLastAccessTime:
+        file.IsLastAccessTimeDefined = defined;
+        if (defined)
+          file.LastAccessTime = fileTime;
+        break;
+    }
+  }
+  return SZ_OK;
+}
+*/
+
+SZ_RESULT SafeReadDirect(ISzInStream *inStream, Byte *data, size_t size)
+{
+  #ifdef _LZMA_IN_CB
+  while (size > 0)
+  {
+    void *inBufferSpec;
+    size_t processedSize;
+    const Byte *inBuffer;
+    RINOK(inStream->Read(inStream, (void **)&inBufferSpec, size, &processedSize));
+    inBuffer = (const Byte *)inBufferSpec;
+    if (processedSize == 0 || processedSize > size)
+      return SZE_FAIL;
+    size -= processedSize;
+    do
+    {
+      *data++ = *inBuffer++;
+    }
+    while (--processedSize != 0);
+  }
+  #else
+  size_t processedSize;
+  RINOK(inStream->Read(inStream, data, size, &processedSize));
+  if (processedSize != size)
+    return SZE_FAIL;
+  #endif
+  return SZ_OK;
+}
+
+SZ_RESULT SafeReadDirectByte(ISzInStream *inStream, Byte *data)
+{
+  return SafeReadDirect(inStream, data, 1);
+}
+
+SZ_RESULT SafeReadDirectUInt32(ISzInStream *inStream, UInt32 *value, UInt32 *crc)
+{
+  int i;
+  *value = 0;
+  for (i = 0; i < 4; i++)
+  {
+    Byte b;
+    RINOK(SafeReadDirectByte(inStream, &b));
+    *value |= ((UInt32)b << (8 * i));
+    *crc = CRC_UPDATE_BYTE(*crc, b);
+  }
+  return SZ_OK;
+}
+
+SZ_RESULT SafeReadDirectUInt64(ISzInStream *inStream, UInt64 *value, UInt32 *crc)
+{
+  int i;
+  *value = 0;
+  for (i = 0; i < 8; i++)
+  {
+    Byte b;
+    RINOK(SafeReadDirectByte(inStream, &b));
+    *value |= ((UInt64)b << (8 * i));
+    *crc = CRC_UPDATE_BYTE(*crc, b);
+  }
+  return SZ_OK;
+}
+
+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;
+
+SZ_RESULT SzReadByte(CSzData *sd, Byte *b)
+{
+  if (sd->Size == 0)
+    return SZE_ARCHIVE_ERROR;
+  sd->Size--;
+  *b = *sd->Data++;
+  return SZ_OK;
+}
+
+SZ_RESULT 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;
+}
+
+SZ_RESULT 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;
+}
+
+SZ_RESULT 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;
+}
+
+SZ_RESULT SzReadSize(CSzData *sd, CFileSize *value)
+{
+  UInt64 value64;
+  RINOK(SzReadNumber(sd, &value64));
+  *value = (CFileSize)value64;
+  return SZ_OK;
+}
+
+SZ_RESULT SzReadNumber32(CSzData *sd, UInt32 *value)
+{
+  UInt64 value64;
+  RINOK(SzReadNumber(sd, &value64));
+  if (value64 >= 0x80000000)
+    return SZE_NOTIMPL;
+  if (value64 >= ((UInt64)(1) << ((sizeof(size_t) - 1) * 8 + 2)))
+    return SZE_NOTIMPL;
+  *value = (UInt32)value64;
+  return SZ_OK;
+}
+
+SZ_RESULT SzReadID(CSzData *sd, UInt64 *value) 
+{ 
+  return SzReadNumber(sd, value); 
+}
+
+SZ_RESULT SzSkeepDataSize(CSzData *sd, UInt64 size)
+{
+  if (size > sd->Size)
+    return SZE_ARCHIVE_ERROR;
+  sd->Size -= (size_t)size;
+  sd->Data += (size_t)size;
+  return SZ_OK;
+}
+
+SZ_RESULT SzSkeepData(CSzData *sd)
+{
+  UInt64 size;
+  RINOK(SzReadNumber(sd, &size));
+  return SzSkeepDataSize(sd, size);
+}
+
+SZ_RESULT SzReadArchiveProperties(CSzData *sd)
+{
+  for (;;)
+  {
+    UInt64 type;
+    RINOK(SzReadID(sd, &type));
+    if (type == k7zIdEnd)
+      break;
+    SzSkeepData(sd);
+  }
+  return SZ_OK;
+}
+
+SZ_RESULT SzWaitAttribute(CSzData *sd, UInt64 attribute)
+{
+  for (;;)
+  {
+    UInt64 type;
+    RINOK(SzReadID(sd, &type));
+    if (type == attribute)
+      return SZ_OK;
+    if (type == k7zIdEnd)
+      return SZE_ARCHIVE_ERROR;
+    RINOK(SzSkeepData(sd));
+  }
+}
+
+SZ_RESULT SzReadBoolVector(CSzData *sd, size_t numItems, Byte **v, void * (*allocFunc)(size_t size))
+{
+  Byte b = 0;
+  Byte mask = 0;
+  size_t i;
+  MY_ALLOC(Byte, *v, numItems, allocFunc);
+  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;
+}
+
+SZ_RESULT SzReadBoolVector2(CSzData *sd, size_t numItems, Byte **v, void * (*allocFunc)(size_t size))
+{
+  Byte allAreDefined;
+  size_t i;
+  RINOK(SzReadByte(sd, &allAreDefined));
+  if (allAreDefined == 0)
+    return SzReadBoolVector(sd, numItems, v, allocFunc);
+  MY_ALLOC(Byte, *v, numItems, allocFunc);
+  for(i = 0; i < numItems; i++)
+    (*v)[i] = 1;
+  return SZ_OK;
+}
+
+SZ_RESULT SzReadHashDigests(
+    CSzData *sd, 
+    size_t numItems,
+    Byte **digestsDefined, 
+    UInt32 **digests, 
+    void * (*allocFunc)(size_t size))
+{
+  size_t i;
+  RINOK(SzReadBoolVector2(sd, numItems, digestsDefined, allocFunc));
+  MY_ALLOC(UInt32, *digests, numItems, allocFunc);
+  for(i = 0; i < numItems; i++)
+    if ((*digestsDefined)[i])
+    {
+      RINOK(SzReadUInt32(sd, (*digests) + i));
+    }
+  return SZ_OK;
+}
+
+SZ_RESULT SzReadPackInfo(
+    CSzData *sd, 
+    CFileSize *dataOffset,
+    UInt32 *numPackStreams,
+    CFileSize **packSizes,
+    Byte **packCRCsDefined,
+    UInt32 **packCRCs,
+    void * (*allocFunc)(size_t size))
+{
+  UInt32 i;
+  RINOK(SzReadSize(sd, dataOffset));
+  RINOK(SzReadNumber32(sd, numPackStreams));
+
+  RINOK(SzWaitAttribute(sd, k7zIdSize));
+
+  MY_ALLOC(CFileSize, *packSizes, (size_t)*numPackStreams, allocFunc);
+
+  for(i = 0; i < *numPackStreams; i++)
+  {
+    RINOK(SzReadSize(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, allocFunc)); 
+      continue;
+    }
+    RINOK(SzSkeepData(sd));
+  }
+  if (*packCRCsDefined == 0)
+  {
+    MY_ALLOC(Byte, *packCRCsDefined, (size_t)*numPackStreams, allocFunc);
+    MY_ALLOC(UInt32, *packCRCs, (size_t)*numPackStreams, allocFunc);
+    for(i = 0; i < *numPackStreams; i++)
+    {
+      (*packCRCsDefined)[i] = 0;
+      (*packCRCs)[i] = 0;
+    }
+  }
+  return SZ_OK;
+}
+
+SZ_RESULT SzReadSwitch(CSzData *sd)
+{
+  Byte external;
+  RINOK(SzReadByte(sd, &external));
+  return (external == 0) ? SZ_OK: SZE_ARCHIVE_ERROR;
+}
+
+SZ_RESULT SzGetNextFolderItem(CSzData *sd, CFolder *folder, void * (*allocFunc)(size_t size))
+{
+  UInt32 numCoders;
+  UInt32 numBindPairs;
+  UInt32 numPackedStreams;
+  UInt32 i;
+  UInt32 numInStreams = 0;
+  UInt32 numOutStreams = 0;
+  RINOK(SzReadNumber32(sd, &numCoders));
+  folder->NumCoders = numCoders;
+
+  MY_ALLOC(CCoderInfo, folder->Coders, (size_t)numCoders, allocFunc);
+
+  for (i = 0; i < numCoders; i++)
+    SzCoderInfoInit(folder->Coders + i);
+
+  for (i = 0; i < numCoders; i++)
+  {
+    Byte mainByte;
+    CCoderInfo *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 SZE_NOTIMPL;
+      coder->MethodID = 0;
+      for (j = 0; j < idSize; j++)
+        coder->MethodID |= (CMethodID)longID[idSize - 1 - j] << (8 * j);
+
+      if ((mainByte & 0x10) != 0)
+      {
+        RINOK(SzReadNumber32(sd, &coder->NumInStreams));
+        RINOK(SzReadNumber32(sd, &coder->NumOutStreams));
+      }
+      else
+      {
+        coder->NumInStreams = 1;
+        coder->NumOutStreams = 1;
+      }
+      if ((mainByte & 0x20) != 0)
+      {
+        UInt64 propertiesSize = 0;
+        RINOK(SzReadNumber(sd, &propertiesSize));
+        if (!SzByteBufferCreate(&coder->Properties, (size_t)propertiesSize, allocFunc))
+          return SZE_OUTOFMEMORY;
+        RINOK(SzReadBytes(sd, coder->Properties.Items, (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 += (UInt32)coder->NumInStreams;
+    numOutStreams += (UInt32)coder->NumOutStreams;
+  }
+
+  numBindPairs = numOutStreams - 1;
+  folder->NumBindPairs = numBindPairs;
+
+
+  MY_ALLOC(CBindPair, folder->BindPairs, (size_t)numBindPairs, allocFunc);
+
+  for (i = 0; i < numBindPairs; i++)
+  {
+    CBindPair *bindPair = folder->BindPairs + i;;
+    RINOK(SzReadNumber32(sd, &bindPair->InIndex));
+    RINOK(SzReadNumber32(sd, &bindPair->OutIndex)); 
+  }
+
+  numPackedStreams = numInStreams - (UInt32)numBindPairs;
+
+  folder->NumPackStreams = numPackedStreams;
+  MY_ALLOC(UInt32, folder->PackStreams, (size_t)numPackedStreams, allocFunc);
+
+  if (numPackedStreams == 1)
+  {
+    UInt32 j;
+    UInt32 pi = 0;
+    for (j = 0; j < numInStreams; j++)
+      if (SzFolderFindBindPairForInStream(folder, j) < 0)
+      {
+        folder->PackStreams[pi++] = j;
+        break;
+      }
+  }
+  else
+    for(i = 0; i < numPackedStreams; i++)
+    {
+      RINOK(SzReadNumber32(sd, folder->PackStreams + i));
+    }
+  return SZ_OK;
+}
+
+SZ_RESULT SzReadUnPackInfo(
+    CSzData *sd, 
+    UInt32 *numFolders,
+    CFolder **folders,  /* for allocFunc */
+    void * (*allocFunc)(size_t size),
+    ISzAlloc *allocTemp)
+{
+  UInt32 i;
+  RINOK(SzWaitAttribute(sd, k7zIdFolder));
+  RINOK(SzReadNumber32(sd, numFolders));
+  {
+    RINOK(SzReadSwitch(sd));
+
+    MY_ALLOC(CFolder, *folders, (size_t)*numFolders, allocFunc);
+
+    for(i = 0; i < *numFolders; i++)
+      SzFolderInit((*folders) + i);
+
+    for(i = 0; i < *numFolders; i++)
+    {
+      RINOK(SzGetNextFolderItem(sd, (*folders) + i, allocFunc));
+    }
+  }
+
+  RINOK(SzWaitAttribute(sd, k7zIdCodersUnPackSize));
+
+  for(i = 0; i < *numFolders; i++)
+  {
+    UInt32 j;
+    CFolder *folder = (*folders) + i;
+    UInt32 numOutStreams = SzFolderGetNumOutStreams(folder);
+
+    MY_ALLOC(CFileSize, folder->UnPackSizes, (size_t)numOutStreams, allocFunc);
+
+    for(j = 0; j < numOutStreams; j++)
+    {
+      RINOK(SzReadSize(sd, folder->UnPackSizes + j));
+    }
+  }
+
+  for (;;)
+  {
+    UInt64 type;
+    RINOK(SzReadID(sd, &type));
+    if (type == k7zIdEnd)
+      return SZ_OK;
+    if (type == k7zIdCRC)
+    {
+      SZ_RESULT res;
+      Byte *crcsDefined = 0;
+      UInt32 *crcs = 0;
+      res = SzReadHashDigests(sd, *numFolders, &crcsDefined, &crcs, allocTemp->Alloc); 
+      if (res == SZ_OK)
+      {
+        for(i = 0; i < *numFolders; i++)
+        {
+          CFolder *folder = (*folders) + i;
+          folder->UnPackCRCDefined = crcsDefined[i];
+          folder->UnPackCRC = crcs[i];
+        }
+      }
+      allocTemp->Free(crcs);
+      allocTemp->Free(crcsDefined);
+      RINOK(res);
+      continue;
+    }
+    RINOK(SzSkeepData(sd));
+  }
+}
+
+SZ_RESULT SzReadSubStreamsInfo(
+    CSzData *sd, 
+    UInt32 numFolders,
+    CFolder *folders,
+    UInt32 *numUnPackStreams,
+    CFileSize **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 = (CFileSize *)allocTemp->Alloc((size_t)*numUnPackStreams * sizeof(CFileSize));
+    RINOM(*unPackSizes);
+    *digestsDefined = (Byte *)allocTemp->Alloc((size_t)*numUnPackStreams * sizeof(Byte));
+    RINOM(*digestsDefined);
+    *digests = (UInt32 *)allocTemp->Alloc((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
+    */
+    CFileSize sum = 0;
+    UInt32 j;
+    UInt32 numSubstreams = folders[i].NumUnPackStreams;
+    if (numSubstreams == 0)
+      continue;
+    if (type == k7zIdSize)
+    for (j = 1; j < numSubstreams; j++)
+    {
+      CFileSize size;
+      RINOK(SzReadSize(sd, &size));
+      (*unPackSizes)[si++] = size;
+      sum += size;
+    }
+    (*unPackSizes)[si++] = SzFolderGetUnPackSize(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;
+      SZ_RESULT res = SzReadHashDigests(sd, numDigests, &digestsDefined2, &digests2, allocTemp->Alloc);
+      if (res == SZ_OK)
+      {
+        for (i = 0; i < numFolders; i++)
+        {
+          CFolder *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++;
+            }
+          }
+        }
+      }
+      allocTemp->Free(digestsDefined2);
+      allocTemp->Free(digests2);
+      RINOK(res);
+    }
+    else if (type == k7zIdEnd)
+      return SZ_OK;
+    else
+    {
+      RINOK(SzSkeepData(sd));
+    }
+    RINOK(SzReadID(sd, &type));
+  }
+}
+
+
+SZ_RESULT SzReadStreamsInfo(
+    CSzData *sd, 
+    CFileSize *dataOffset,
+    CArchiveDatabase *db,
+    UInt32 *numUnPackStreams,
+    CFileSize **unPackSizes, /* allocTemp */
+    Byte **digestsDefined,   /* allocTemp */
+    UInt32 **digests,        /* allocTemp */
+    void * (*allocFunc)(size_t size),
+    ISzAlloc *allocTemp)
+{
+  for (;;)
+  {
+    UInt64 type;
+    RINOK(SzReadID(sd, &type));
+    if ((UInt64)(int)type != type)
+      return SZE_FAIL;
+    switch((int)type)
+    {
+      case k7zIdEnd:
+        return SZ_OK;
+      case k7zIdPackInfo:
+      {
+        RINOK(SzReadPackInfo(sd, dataOffset, &db->NumPackStreams, 
+            &db->PackSizes, &db->PackCRCsDefined, &db->PackCRCs, allocFunc));
+        break;
+      }
+      case k7zIdUnPackInfo:
+      {
+        RINOK(SzReadUnPackInfo(sd, &db->NumFolders, &db->Folders, allocFunc, allocTemp));
+        break;
+      }
+      case k7zIdSubStreamsInfo:
+      {
+        RINOK(SzReadSubStreamsInfo(sd, db->NumFolders, db->Folders, 
+            numUnPackStreams, unPackSizes, digestsDefined, digests, allocTemp));
+        break;
+      }
+      default:
+        return SZE_FAIL;
+    }
+  }
+}
+
+Byte kUtf8Limits[5] = { 0xC0, 0xE0, 0xF0, 0xF8, 0xFC };
+
+SZ_RESULT SzReadFileNames(CSzData *sd, UInt32 numFiles, CFileItem *files, 
+    void * (*allocFunc)(size_t size))
+{
+  UInt32 i;
+  for(i = 0; i < numFiles; i++)
+  {
+    UInt32 len = 0;
+    UInt32 pos = 0;
+    CFileItem *file = files + i;
+    while(pos + 2 <= sd->Size)
+    {
+      int numAdds;
+      UInt32 value = (UInt32)(sd->Data[pos] | (((UInt32)sd->Data[pos + 1]) << 8));
+      pos += 2;
+      len++;
+      if (value == 0)
+        break;
+      if (value < 0x80)
+        continue;
+      if (value >= 0xD800 && value < 0xE000)
+      {
+        UInt32 c2;
+        if (value >= 0xDC00)
+          return SZE_ARCHIVE_ERROR;
+        if (pos + 2 > sd->Size)
+          return SZE_ARCHIVE_ERROR;
+        c2 = (UInt32)(sd->Data[pos] | (((UInt32)sd->Data[pos + 1]) << 8));
+        pos += 2;
+        if (c2 < 0xDC00 || c2 >= 0xE000)
+          return SZE_ARCHIVE_ERROR;
+        value = ((value - 0xD800) << 10) | (c2 - 0xDC00);
+      }
+      for (numAdds = 1; numAdds < 5; numAdds++)
+        if (value < (((UInt32)1) << (numAdds * 5 + 6)))
+          break;
+      len += numAdds;
+    }
+
+    MY_ALLOC(char, file->Name, (size_t)len, allocFunc);
+
+    len = 0;
+    while(2 <= sd->Size)
+    {
+      int numAdds;
+      UInt32 value = (UInt32)(sd->Data[0] | (((UInt32)sd->Data[1]) << 8));
+      SzSkeepDataSize(sd, 2);
+      if (value < 0x80)
+      {
+        file->Name[len++] = (char)value;
+        if (value == 0)
+          break;
+        continue;
+      }
+      if (value >= 0xD800 && value < 0xE000)
+      {
+        UInt32 c2 = (UInt32)(sd->Data[0] | (((UInt32)sd->Data[1]) << 8));
+        SzSkeepDataSize(sd, 2);
+        value = ((value - 0xD800) << 10) | (c2 - 0xDC00);
+      }
+      for (numAdds = 1; numAdds < 5; numAdds++)
+        if (value < (((UInt32)1) << (numAdds * 5 + 6)))
+          break;
+      file->Name[len++] = (char)(kUtf8Limits[numAdds - 1] + (value >> (6 * numAdds)));
+      do
+      {
+        numAdds--;
+        file->Name[len++] = (char)(0x80 + ((value >> (6 * numAdds)) & 0x3F));
+      }
+      while(numAdds > 0);
+
+      len += numAdds;
+    }
+  }
+  return SZ_OK;
+}
+
+SZ_RESULT SzReadHeader2(
+    CSzData *sd, 
+    CArchiveDatabaseEx *db,   /* allocMain */
+    CFileSize **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;
+  CFileItem *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,
+        &db->ArchiveInfo.DataStartPosition,
+        &db->Database, 
+        &numUnPackStreams,
+        unPackSizes,
+        digestsDefined,
+        digests, allocMain->Alloc, allocTemp));
+    db->ArchiveInfo.DataStartPosition += db->ArchiveInfo.StartPositionAfterHeader;
+    RINOK(SzReadID(sd, &type));
+  }
+
+  if (type == k7zIdEnd)
+    return SZ_OK;
+  if (type != k7zIdFilesInfo)
+    return SZE_ARCHIVE_ERROR;
+  
+  RINOK(SzReadNumber32(sd, &numFiles));
+  db->Database.NumFiles = numFiles;
+
+  MY_ALLOC(CFileItem, files, (size_t)numFiles, allocMain->Alloc);
+
+  db->Database.Files = files;
+  for(i = 0; i < numFiles; i++)
+    SzFileInit(files + i);
+
+  for (;;)
+  {
+    UInt64 type;
+    UInt64 size;
+    RINOK(SzReadID(sd, &type));
+    if (type == k7zIdEnd)
+      break;
+    RINOK(SzReadNumber(sd, &size));
+
+    if ((UInt64)(int)type != type)
+    {
+      RINOK(SzSkeepDataSize(sd, size));
+    }
+    else
+    switch((int)type)
+    {
+      case k7zIdName:
+      {
+        RINOK(SzReadSwitch(sd));
+        RINOK(SzReadFileNames(sd, numFiles, files, allocMain->Alloc))
+        break;
+      }
+      case k7zIdEmptyStream:
+      {
+        RINOK(SzReadBoolVector(sd, numFiles, emptyStreamVector, allocTemp->Alloc));
+        numEmptyStreams = 0;
+        for (i = 0; i < numFiles; i++)
+          if ((*emptyStreamVector)[i])
+            numEmptyStreams++;
+        break;
+      }
+      case k7zIdEmptyFile:
+      {
+        RINOK(SzReadBoolVector(sd, numEmptyStreams, emptyFileVector, allocTemp->Alloc));
+        break;
+      }
+      case k7zIdLastWriteTime:
+      {
+        RINOK(SzReadBoolVector2(sd, numFiles, lwtVector, allocTemp->Alloc));
+        RINOK(SzReadSwitch(sd));
+        for (i = 0; i < numFiles; i++)
+        {
+          CFileItem *f = &files[i];
+          Byte defined = (*lwtVector)[i];
+          f->IsLastWriteTimeDefined = defined;
+          f->LastWriteTime.Low = f->LastWriteTime.High = 0;
+          if (defined)
+          {
+            RINOK(SzReadUInt32(sd, &f->LastWriteTime.Low));
+            RINOK(SzReadUInt32(sd, &f->LastWriteTime.High));
+          }
+        }
+        break;
+      }
+      default:
+      {
+        RINOK(SzSkeepDataSize(sd, size));
+      }
+    }
+  }
+
+  {
+    UInt32 emptyFileIndex = 0;
+    UInt32 sizeIndex = 0;
+    for(i = 0; i < numFiles; i++)
+    {
+      CFileItem *file = files + i;
+      file->IsAnti = 0;
+      if (*emptyStreamVector == 0)
+        file->HasStream = 1;
+      else
+        file->HasStream = (Byte)((*emptyStreamVector)[i] ? 0 : 1);
+      if(file->HasStream)
+      {
+        file->IsDirectory = 0;
+        file->Size = (*unPackSizes)[sizeIndex];
+        file->FileCRC = (*digests)[sizeIndex];
+        file->IsFileCRCDefined = (Byte)(*digestsDefined)[sizeIndex];
+        sizeIndex++;
+      }
+      else
+      {
+        if (*emptyFileVector == 0)
+          file->IsDirectory = 1;
+        else
+          file->IsDirectory = (Byte)((*emptyFileVector)[emptyFileIndex] ? 0 : 1);
+        emptyFileIndex++;
+        file->Size = 0;
+        file->IsFileCRCDefined = 0;
+      }
+    }
+  }
+  return SzArDbExFill(db, allocMain->Alloc);
+}
+
+SZ_RESULT SzReadHeader(
+    CSzData *sd, 
+    CArchiveDatabaseEx *db, 
+    ISzAlloc *allocMain, 
+    ISzAlloc *allocTemp)
+{
+  CFileSize *unPackSizes = 0;
+  Byte *digestsDefined = 0;
+  UInt32 *digests = 0;
+  Byte *emptyStreamVector = 0;
+  Byte *emptyFileVector = 0;
+  Byte *lwtVector = 0;
+  SZ_RESULT res = SzReadHeader2(sd, db, 
+      &unPackSizes, &digestsDefined, &digests,
+      &emptyStreamVector, &emptyFileVector, &lwtVector, 
+      allocMain, allocTemp);
+  allocTemp->Free(unPackSizes);
+  allocTemp->Free(digestsDefined);
+  allocTemp->Free(digests);
+  allocTemp->Free(emptyStreamVector);
+  allocTemp->Free(emptyFileVector);
+  allocTemp->Free(lwtVector);
+  return res;
+} 
+
+SZ_RESULT SzReadAndDecodePackedStreams2(
+    ISzInStream *inStream, 
+    CSzData *sd,
+    CSzByteBuffer *outBuffer,
+    CFileSize baseOffset, 
+    CArchiveDatabase *db,
+    CFileSize **unPackSizes,
+    Byte **digestsDefined,
+    UInt32 **digests,
+    #ifndef _LZMA_IN_CB
+    Byte **inBuffer,
+    #endif
+    ISzAlloc *allocTemp)
+{
+
+  UInt32 numUnPackStreams = 0;
+  CFileSize dataStartPos;
+  CFolder *folder;
+  #ifndef _LZMA_IN_CB
+  CFileSize packSize = 0;
+  UInt32 i = 0;
+  #endif
+  CFileSize unPackSize;
+  SZ_RESULT res;
+
+  RINOK(SzReadStreamsInfo(sd, &dataStartPos, db,
+      &numUnPackStreams,  unPackSizes, digestsDefined, digests, 
+      allocTemp->Alloc, allocTemp));
+  
+  dataStartPos += baseOffset;
+  if (db->NumFolders != 1)
+    return SZE_ARCHIVE_ERROR;
+
+  folder = db->Folders;
+  unPackSize = SzFolderGetUnPackSize(folder);
+  
+  RINOK(inStream->Seek(inStream, dataStartPos));
+
+  #ifndef _LZMA_IN_CB
+  for (i = 0; i < db->NumPackStreams; i++)
+    packSize += db->PackSizes[i];
+
+  MY_ALLOC(Byte, *inBuffer, (size_t)packSize, allocTemp->Alloc);
+
+  RINOK(SafeReadDirect(inStream, *inBuffer, (size_t)packSize));
+  #endif
+
+  if (!SzByteBufferCreate(outBuffer, (size_t)unPackSize, allocTemp->Alloc))
+    return SZE_OUTOFMEMORY;
+  
+  res = SzDecode(db->PackSizes, folder, 
+          #ifdef _LZMA_IN_CB
+          inStream, dataStartPos, 
+          #else
+          *inBuffer, 
+          #endif
+          outBuffer->Items, (size_t)unPackSize, allocTemp);
+  RINOK(res)
+  if (folder->UnPackCRCDefined)
+    if (CrcCalc(outBuffer->Items, (size_t)unPackSize) != folder->UnPackCRC)
+      return SZE_FAIL;
+  return SZ_OK;
+}
+
+SZ_RESULT SzReadAndDecodePackedStreams(
+    ISzInStream *inStream, 
+    CSzData *sd,
+    CSzByteBuffer *outBuffer,
+    CFileSize baseOffset, 
+    ISzAlloc *allocTemp)
+{
+  CArchiveDatabase db;
+  CFileSize *unPackSizes = 0;
+  Byte *digestsDefined = 0;
+  UInt32 *digests = 0;
+  #ifndef _LZMA_IN_CB
+  Byte *inBuffer = 0;
+  #endif
+  SZ_RESULT res;
+  SzArchiveDatabaseInit(&db);
+  res = SzReadAndDecodePackedStreams2(inStream, sd, outBuffer, baseOffset, 
+    &db, &unPackSizes, &digestsDefined, &digests, 
+    #ifndef _LZMA_IN_CB
+    &inBuffer,
+    #endif
+    allocTemp);
+  SzArchiveDatabaseFree(&db, allocTemp->Free);
+  allocTemp->Free(unPackSizes);
+  allocTemp->Free(digestsDefined);
+  allocTemp->Free(digests);
+  #ifndef _LZMA_IN_CB
+  allocTemp->Free(inBuffer);
+  #endif
+  return res;
+}
+
+SZ_RESULT SzArchiveOpen2(
+    ISzInStream *inStream, 
+    CArchiveDatabaseEx *db,
+    ISzAlloc *allocMain, 
+    ISzAlloc *allocTemp)
+{
+  Byte signature[k7zSignatureSize];
+  Byte version;
+  UInt32 crcFromArchive;
+  UInt64 nextHeaderOffset;
+  UInt64 nextHeaderSize;
+  UInt32 nextHeaderCRC;
+  UInt32 crc = 0;
+  CFileSize pos = 0;
+  CSzByteBuffer buffer;
+  CSzData sd;
+  SZ_RESULT res;
+
+  RINOK(SafeReadDirect(inStream, signature, k7zSignatureSize));
+
+  if (!TestSignatureCandidate(signature))
+    return SZE_ARCHIVE_ERROR;
+
+  /*
+  db.Clear();
+  db.ArchiveInfo.StartPosition = _arhiveBeginStreamPosition;
+  */
+  RINOK(SafeReadDirectByte(inStream, &version));
+  if (version != k7zMajorVersion)
+    return SZE_ARCHIVE_ERROR;
+  RINOK(SafeReadDirectByte(inStream, &version));
+
+  RINOK(SafeReadDirectUInt32(inStream, &crcFromArchive, &crc));
+
+  crc = CRC_INIT_VAL;
+  RINOK(SafeReadDirectUInt64(inStream, &nextHeaderOffset, &crc));
+  RINOK(SafeReadDirectUInt64(inStream, &nextHeaderSize, &crc));
+  RINOK(SafeReadDirectUInt32(inStream, &nextHeaderCRC, &crc));
+
+  pos = k7zStartHeaderSize;
+  db->ArchiveInfo.StartPositionAfterHeader = pos;
+  
+  if (CRC_GET_DIGEST(crc) != crcFromArchive)
+    return SZE_ARCHIVE_ERROR;
+
+  if (nextHeaderSize == 0)
+    return SZ_OK;
+
+  RINOK(inStream->Seek(inStream, (CFileSize)(pos + nextHeaderOffset)));
+
+  if (!SzByteBufferCreate(&buffer, (size_t)nextHeaderSize, allocTemp->Alloc))
+    return SZE_OUTOFMEMORY;
+
+  res = SafeReadDirect(inStream, buffer.Items, (size_t)nextHeaderSize);
+  if (res == SZ_OK)
+  {
+    res = SZE_ARCHIVE_ERROR;
+    if (CrcCalc(buffer.Items, (UInt32)nextHeaderSize) == nextHeaderCRC)
+    {
+      for (;;)
+      {
+        UInt64 type;
+        sd.Data = buffer.Items;
+        sd.Size = buffer.Capacity;
+        res = SzReadID(&sd, &type);
+        if (res != SZ_OK)
+          break;
+        if (type == k7zIdHeader)
+        {
+          res = SzReadHeader(&sd, db, allocMain, allocTemp);
+          break;
+        }
+        if (type != k7zIdEncodedHeader)
+        {
+          res = SZE_ARCHIVE_ERROR;
+          break;
+        }
+        {
+          CSzByteBuffer outBuffer;
+          res = SzReadAndDecodePackedStreams(inStream, &sd, &outBuffer, 
+              db->ArchiveInfo.StartPositionAfterHeader, 
+              allocTemp);
+          if (res != SZ_OK)
+          {
+            SzByteBufferFree(&outBuffer, allocTemp->Free);
+            break;
+          }
+          SzByteBufferFree(&buffer, allocTemp->Free);
+          buffer.Items = outBuffer.Items;
+          buffer.Capacity = outBuffer.Capacity;
+        }
+      }
+    }
+  }
+  SzByteBufferFree(&buffer, allocTemp->Free);
+  return res;
+}
+
+SZ_RESULT SzArchiveOpen(
+    ISzInStream *inStream, 
+    CArchiveDatabaseEx *db,
+    ISzAlloc *allocMain, 
+    ISzAlloc *allocTemp)
+{
+  SZ_RESULT res = SzArchiveOpen2(inStream, db, allocMain, allocTemp);
+  if (res != SZ_OK)
+    SzArDbExFree(db, allocMain->Free);
+  return res;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/misc/libphysfs/lzma/C/Archive/7z/7zIn.h	Mon Apr 10 12:06:43 2017 -0400
@@ -0,0 +1,55 @@
+/* 7zIn.h */
+
+#ifndef __7Z_IN_H
+#define __7Z_IN_H
+
+#include "7zHeader.h"
+#include "7zItem.h"
+#include "7zAlloc.h"
+ 
+typedef struct _CInArchiveInfo
+{
+  CFileSize StartPositionAfterHeader; 
+  CFileSize DataStartPosition;
+}CInArchiveInfo;
+
+typedef struct _CArchiveDatabaseEx
+{
+  CArchiveDatabase Database;
+  CInArchiveInfo ArchiveInfo;
+  UInt32 *FolderStartPackStreamIndex;
+  CFileSize *PackStreamStartPositions;
+  UInt32 *FolderStartFileIndex;
+  UInt32 *FileIndexToFolderIndexMap;
+}CArchiveDatabaseEx;
+
+void SzArDbExInit(CArchiveDatabaseEx *db);
+void SzArDbExFree(CArchiveDatabaseEx *db, void (*freeFunc)(void *));
+CFileSize SzArDbGetFolderStreamPos(CArchiveDatabaseEx *db, UInt32 folderIndex, UInt32 indexInFolder);
+int SzArDbGetFolderFullPackSize(CArchiveDatabaseEx *db, UInt32 folderIndex, CFileSize *resSize);
+
+typedef struct _ISzInStream
+{
+  #ifdef _LZMA_IN_CB
+  SZ_RESULT (*Read)(
+      void *object,           /* pointer to ISzInStream itself */
+      void **buffer,          /* out: pointer to buffer with data */
+      size_t maxRequiredSize, /* max required size to read */
+      size_t *processedSize); /* real processed size. 
+                                 processedSize can be less than maxRequiredSize.
+                                 If processedSize == 0, then there are no more 
+                                 bytes in stream. */
+  #else
+  SZ_RESULT (*Read)(void *object, void *buffer, size_t size, size_t *processedSize);
+  #endif
+  SZ_RESULT (*Seek)(void *object, CFileSize pos);
+} ISzInStream;
+
+ 
+int SzArchiveOpen(
+    ISzInStream *inStream, 
+    CArchiveDatabaseEx *db,
+    ISzAlloc *allocMain, 
+    ISzAlloc *allocTemp);
+ 
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/misc/libphysfs/lzma/C/Archive/7z/7zItem.c	Mon Apr 10 12:06:43 2017 -0400
@@ -0,0 +1,134 @@
+/* 7zItem.c */
+
+#include "7zItem.h"
+#include "7zAlloc.h"
+
+void SzCoderInfoInit(CCoderInfo *coder)
+{
+  SzByteBufferInit(&coder->Properties);
+}
+
+void SzCoderInfoFree(CCoderInfo *coder, void (*freeFunc)(void *p))
+{
+  SzByteBufferFree(&coder->Properties, freeFunc);
+  SzCoderInfoInit(coder);
+}
+
+void SzFolderInit(CFolder *folder)
+{
+  folder->NumCoders = 0;
+  folder->Coders = 0;
+  folder->NumBindPairs = 0;
+  folder->BindPairs = 0;
+  folder->NumPackStreams = 0;
+  folder->PackStreams = 0;
+  folder->UnPackSizes = 0;
+  folder->UnPackCRCDefined = 0;
+  folder->UnPackCRC = 0;
+  folder->NumUnPackStreams = 0;
+}
+
+void SzFolderFree(CFolder *folder, void (*freeFunc)(void *p))
+{
+  UInt32 i;
+  for (i = 0; i < folder->NumCoders; i++)
+    SzCoderInfoFree(&folder->Coders[i], freeFunc);
+  freeFunc(folder->Coders);
+  freeFunc(folder->BindPairs);
+  freeFunc(folder->PackStreams);
+  freeFunc(folder->UnPackSizes);
+  SzFolderInit(folder);
+}
+
+UInt32 SzFolderGetNumOutStreams(CFolder *folder)
+{
+  UInt32 result = 0;
+  UInt32 i;
+  for (i = 0; i < folder->NumCoders; i++)
+    result += folder->Coders[i].NumOutStreams;
+  return result;
+}
+
+int SzFolderFindBindPairForInStream(CFolder *folder, UInt32 inStreamIndex)
+{
+  UInt32 i;
+  for(i = 0; i < folder->NumBindPairs; i++)
+    if (folder->BindPairs[i].InIndex == inStreamIndex)
+      return i;
+  return -1;
+}
+
+
+int SzFolderFindBindPairForOutStream(CFolder *folder, UInt32 outStreamIndex)
+{
+  UInt32 i;
+  for(i = 0; i < folder->NumBindPairs; i++)
+    if (folder->BindPairs[i].OutIndex == outStreamIndex)
+      return i;
+  return -1;
+}
+
+CFileSize SzFolderGetUnPackSize(CFolder *folder)
+{ 
+  int i = (int)SzFolderGetNumOutStreams(folder);
+  if (i == 0)
+    return 0;
+  for (i--; i >= 0; i--)
+    if (SzFolderFindBindPairForOutStream(folder, i) < 0)
+      return folder->UnPackSizes[i];
+  /* throw 1; */
+  return 0;
+}
+
+/*
+int FindPackStreamArrayIndex(int inStreamIndex) const
+{
+  for(int i = 0; i < PackStreams.Size(); i++)
+  if (PackStreams[i] == inStreamIndex)
+    return i;
+  return -1;
+}
+*/
+
+void SzFileInit(CFileItem *fileItem)
+{
+  fileItem->IsFileCRCDefined = 0;
+  fileItem->HasStream = 1;
+  fileItem->IsDirectory = 0;
+  fileItem->IsAnti = 0;
+  fileItem->IsLastWriteTimeDefined = 0;
+  fileItem->Name = 0;
+}
+
+void SzFileFree(CFileItem *fileItem, void (*freeFunc)(void *p))
+{
+  freeFunc(fileItem->Name);
+  SzFileInit(fileItem);
+}
+
+void SzArchiveDatabaseInit(CArchiveDatabase *db)
+{
+  db->NumPackStreams = 0;
+  db->PackSizes = 0;
+  db->PackCRCsDefined = 0;
+  db->PackCRCs = 0;
+  db->NumFolders = 0;
+  db->Folders = 0;
+  db->NumFiles = 0;
+  db->Files = 0;
+}
+
+void SzArchiveDatabaseFree(CArchiveDatabase *db, void (*freeFunc)(void *))
+{
+  UInt32 i;
+  for (i = 0; i < db->NumFolders; i++)
+    SzFolderFree(&db->Folders[i], freeFunc);
+  for (i = 0; i < db->NumFiles; i++)
+    SzFileFree(&db->Files[i], freeFunc);
+  freeFunc(db->PackSizes);
+  freeFunc(db->PackCRCsDefined);
+  freeFunc(db->PackCRCs);
+  freeFunc(db->Folders);
+  freeFunc(db->Files);
+  SzArchiveDatabaseInit(db);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/misc/libphysfs/lzma/C/Archive/7z/7zItem.h	Mon Apr 10 12:06:43 2017 -0400
@@ -0,0 +1,95 @@
+/* 7zItem.h */
+
+#ifndef __7Z_ITEM_H
+#define __7Z_ITEM_H
+
+#include "7zMethodID.h"
+#include "7zHeader.h"
+#include "7zBuffer.h"
+
+typedef struct _CCoderInfo
+{
+  UInt32 NumInStreams;
+  UInt32 NumOutStreams;
+  CMethodID MethodID;
+  CSzByteBuffer Properties;
+}CCoderInfo;
+
+void SzCoderInfoInit(CCoderInfo *coder);
+void SzCoderInfoFree(CCoderInfo *coder, void (*freeFunc)(void *p));
+
+typedef struct _CBindPair
+{
+  UInt32 InIndex;
+  UInt32 OutIndex;
+}CBindPair;
+
+typedef struct _CFolder
+{
+  UInt32 NumCoders;
+  CCoderInfo *Coders;
+  UInt32 NumBindPairs;
+  CBindPair *BindPairs;
+  UInt32 NumPackStreams; 
+  UInt32 *PackStreams;
+  CFileSize *UnPackSizes;
+  int UnPackCRCDefined;
+  UInt32 UnPackCRC;
+
+  UInt32 NumUnPackStreams;
+}CFolder;
+
+void SzFolderInit(CFolder *folder);
+CFileSize SzFolderGetUnPackSize(CFolder *folder);
+int SzFolderFindBindPairForInStream(CFolder *folder, UInt32 inStreamIndex);
+UInt32 SzFolderGetNumOutStreams(CFolder *folder);
+CFileSize SzFolderGetUnPackSize(CFolder *folder);
+
+typedef struct _CArchiveFileTime
+{
+  UInt32 Low;
+  UInt32 High;
+} CArchiveFileTime;
+
+typedef struct _CFileItem
+{
+  CArchiveFileTime LastWriteTime;
+  /*
+  CFileSize StartPos;
+  UInt32 Attributes; 
+  */
+  CFileSize Size;
+  UInt32 FileCRC;
+  char *Name;
+
+  Byte IsFileCRCDefined;
+  Byte HasStream;
+  Byte IsDirectory;
+  Byte IsAnti;
+  Byte IsLastWriteTimeDefined;
+  /*
+  int AreAttributesDefined;
+  int IsLastWriteTimeDefined;
+  int IsStartPosDefined;
+  */
+}CFileItem;
+
+void SzFileInit(CFileItem *fileItem);
+
+typedef struct _CArchiveDatabase
+{
+  UInt32 NumPackStreams;
+  CFileSize *PackSizes;
+  Byte *PackCRCsDefined;
+  UInt32 *PackCRCs;
+  UInt32 NumFolders;
+  CFolder *Folders;
+  UInt32 NumFiles;
+  CFileItem *Files;
+}CArchiveDatabase;
+
+void SzArchiveDatabaseInit(CArchiveDatabase *db);
+void SzArchiveDatabaseFree(CArchiveDatabase *db, void (*freeFunc)(void *));
+
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/misc/libphysfs/lzma/C/Archive/7z/7zMain.c	Mon Apr 10 12:06:43 2017 -0400
@@ -0,0 +1,428 @@
+/* 
+7zMain.c
+Test application for 7z Decoder
+LZMA SDK 4.43 Copyright (c) 1999-2006 Igor Pavlov (2006-06-04)
+*/
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#ifdef _WIN32
+#define USE_WINDOWS_FUNCTIONS
+#endif
+
+#ifdef USE_WINDOWS_FUNCTIONS
+#include <windows.h>
+#endif
+
+#include "7zIn.h"
+#include "7zExtract.h"
+
+#include "../../7zCrc.h"
+
+
+#ifdef USE_WINDOWS_FUNCTIONS
+typedef HANDLE MY_FILE_HANDLE;
+#else
+typedef FILE *MY_FILE_HANDLE;
+#endif
+
+void ConvertNumberToString(CFileSize value, char *s)
+{
+  char temp[32];
+  int pos = 0;
+  do 
+  {
+    temp[pos++] = (char)('0' + (int)(value % 10));
+    value /= 10;
+  }
+  while (value != 0);
+  do
+    *s++ = temp[--pos];
+  while(pos > 0);
+  *s = '\0';
+}
+
+#define PERIOD_4 (4 * 365 + 1)
+#define PERIOD_100 (PERIOD_4 * 25 - 1)
+#define PERIOD_400 (PERIOD_100 * 4 + 1)
+
+void ConvertFileTimeToString(CArchiveFileTime *ft, char *s)
+{
+  unsigned year, mon, day, hour, min, sec;
+  UInt64 v64 = ft->Low | ((UInt64)ft->High << 32);
+  Byte ms[] = { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
+  unsigned temp;
+  UInt32 v; 
+  v64 /= 10000000;
+  sec = (unsigned)(v64 % 60);
+  v64 /= 60;
+  min = (unsigned)(v64 % 60);
+  v64 /= 60;
+  hour = (unsigned)(v64 % 24);
+  v64 /= 24;
+
+  v = (UInt32)v64;
+
+  year = (unsigned)(1601 + v / PERIOD_400 * 400);
+  v %= PERIOD_400;
+
+  temp = (unsigned)(v / PERIOD_100);
+  if (temp == 4)
+    temp = 3;
+  year += temp * 100;
+  v -= temp * PERIOD_100;
+
+  temp = v / PERIOD_4;
+  if (temp == 25)
+    temp = 24;
+  year += temp * 4;
+  v -= temp * PERIOD_4;
+
+  temp = v / 365;
+  if (temp == 4)
+    temp = 3;
+  year += temp;
+  v -= temp * 365;
+
+  if (year % 4 == 0 && (year % 100 != 0 || year % 400 == 0))
+    ms[1] = 29;
+  for (mon = 1; mon <= 12; mon++)
+  {
+    unsigned s = ms[mon - 1];
+    if (v < s)
+      break;
+    v -= s;
+  }
+  day = (unsigned)v + 1;
+  sprintf(s, "%04d-%02d-%02d %02d:%02d:%02d", year, mon, day, hour, min, sec);
+}
+
+
+#ifdef USE_WINDOWS_FUNCTIONS
+/*
+   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).
+*/
+#define kChunkSizeMax (1 << 24)
+#endif
+
+size_t MyReadFile(MY_FILE_HANDLE file, void *data, size_t size)
+{ 
+  if (size == 0)
+    return 0;
+  #ifdef USE_WINDOWS_FUNCTIONS
+  {
+    size_t processedSize = 0;
+    do
+    {
+      DWORD curSize = (size > kChunkSizeMax) ? kChunkSizeMax : (DWORD)size;
+      DWORD processedLoc = 0;
+      BOOL res = ReadFile(file, data, curSize, &processedLoc, NULL);
+      data = (void *)((unsigned char *)data + processedLoc);
+      size -= processedLoc;
+      processedSize += processedLoc;
+      if (!res || processedLoc == 0)
+        break;
+    }
+    while (size > 0);
+    return processedSize;
+  }
+  #else
+  return fread(data, 1, size, file); 
+  #endif
+}
+
+size_t MyWriteFile(MY_FILE_HANDLE file, void *data, size_t size)
+{ 
+  if (size == 0)
+    return 0;
+  #ifdef USE_WINDOWS_FUNCTIONS
+  {
+    size_t processedSize = 0;
+    do
+    {
+      DWORD curSize = (size > kChunkSizeMax) ? kChunkSizeMax : (DWORD)size;
+      DWORD processedLoc = 0;
+      BOOL res = WriteFile(file, data, curSize, &processedLoc, NULL);
+      data = (void *)((unsigned char *)data + processedLoc);
+      size -= processedLoc;
+      processedSize += processedLoc;
+      if (!res)
+        break;
+    }
+    while (size > 0);
+    return processedSize;
+  }
+  #else
+  return fwrite(data, 1, size, file); 
+  #endif
+}
+
+int MyCloseFile(MY_FILE_HANDLE file)
+{ 
+  #ifdef USE_WINDOWS_FUNCTIONS
+  return (CloseHandle(file) != FALSE) ? 0 : 1;
+  #else
+  return fclose(file); 
+  #endif
+}
+
+typedef struct _CFileInStream
+{
+  ISzInStream InStream;
+  MY_FILE_HANDLE File;
+} CFileInStream;
+
+#ifdef _LZMA_IN_CB
+
+#define kBufferSize (1 << 12)
+Byte g_Buffer[kBufferSize];
+
+SZ_RESULT SzFileReadImp(void *object, void **buffer, size_t maxRequiredSize, size_t *processedSize)
+{
+  CFileInStream *s = (CFileInStream *)object;
+  size_t processedSizeLoc;
+  if (maxRequiredSize > kBufferSize)
+    maxRequiredSize = kBufferSize;
+  processedSizeLoc = MyReadFile(s->File, g_Buffer, maxRequiredSize);
+  *buffer = g_Buffer;
+  if (processedSize != 0)
+    *processedSize = processedSizeLoc;
+  return SZ_OK;
+}
+
+#else
+
+SZ_RESULT SzFileReadImp(void *object, void *buffer, size_t size, size_t *processedSize)
+{
+  CFileInStream *s = (CFileInStream *)object;
+  size_t processedSizeLoc = MyReadFile(s->File, buffer, size);
+  if (processedSize != 0)
+    *processedSize = processedSizeLoc;
+  return SZ_OK;
+}
+
+#endif
+
+SZ_RESULT SzFileSeekImp(void *object, CFileSize pos)
+{
+  CFileInStream *s = (CFileInStream *)object;
+
+  #ifdef USE_WINDOWS_FUNCTIONS
+  {
+    LARGE_INTEGER value;
+    value.LowPart = (DWORD)pos;
+    value.HighPart = (LONG)((UInt64)pos >> 32);
+    #ifdef _SZ_FILE_SIZE_32
+    /* VC 6.0 has bug with >> 32 shifts. */
+    value.HighPart = 0;
+    #endif
+    value.LowPart = SetFilePointer(s->File, value.LowPart, &value.HighPart, FILE_BEGIN);
+    if (value.LowPart == 0xFFFFFFFF)
+      if(GetLastError() != NO_ERROR) 
+        return SZE_FAIL;
+    return SZ_OK;
+  }
+  #else
+  int res = fseek(s->File, (long)pos, SEEK_SET);
+  if (res == 0)
+    return SZ_OK;
+  return SZE_FAIL;
+  #endif
+}
+
+void PrintError(char *sz)
+{
+  printf("\nERROR: %s\n", sz);
+}
+
+int main(int numargs, char *args[])
+{
+  CFileInStream archiveStream;
+  CArchiveDatabaseEx db;
+  SZ_RESULT res;
+  ISzAlloc allocImp;
+  ISzAlloc allocTempImp;
+
+  printf("\n7z ANSI-C Decoder 4.48  Copyright (c) 1999-2007 Igor Pavlov  2007-06-21\n");
+  if (numargs == 1)
+  {
+    printf(
+      "\nUsage: 7zDec <command> <archive_name>\n\n"
+      "<Commands>\n"
+      "  e: Extract files from archive\n"
+      "  l: List contents of archive\n"
+      "  t: Test integrity of archive\n");
+    return 0;
+  }
+  if (numargs < 3)
+  {
+    PrintError("incorrect command");
+    return 1;
+  }
+
+  archiveStream.File = 
+  #ifdef USE_WINDOWS_FUNCTIONS
+  CreateFile(args[2], GENERIC_READ, FILE_SHARE_READ, 
+      NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
+  if (archiveStream.File == INVALID_HANDLE_VALUE)
+  #else
+  archiveStream.File = fopen(args[2], "rb");
+  if (archiveStream.File == 0)
+  #endif
+  {
+    PrintError("can not open input file");
+    return 1;
+  }
+
+  archiveStream.InStream.Read = SzFileReadImp;
+  archiveStream.InStream.Seek = SzFileSeekImp;
+
+  allocImp.Alloc = SzAlloc;
+  allocImp.Free = SzFree;
+
+  allocTempImp.Alloc = SzAllocTemp;
+  allocTempImp.Free = SzFreeTemp;
+
+  CrcGenerateTable();
+
+  SzArDbExInit(&db);
+  res = SzArchiveOpen(&archiveStream.InStream, &db, &allocImp, &allocTempImp);
+  if (res == SZ_OK)
+  {
+    char *command = args[1];
+    int listCommand = 0;
+    int testCommand = 0;
+    int extractCommand = 0;
+    if (strcmp(command, "l") == 0)
+      listCommand = 1;
+    if (strcmp(command, "t") == 0)
+      testCommand = 1;
+    else if (strcmp(command, "e") == 0)
+      extractCommand = 1;
+
+    if (listCommand)
+    {
+      UInt32 i;
+      for (i = 0; i < db.Database.NumFiles; i++)
+      {
+        CFileItem *f = db.Database.Files + i;
+        char s[32], t[32];
+        ConvertNumberToString(f->Size, s);
+        if (f->IsLastWriteTimeDefined)
+          ConvertFileTimeToString(&f->LastWriteTime, t);
+        else
+          strcpy(t, "                   ");
+
+        printf("%10s %s  %s\n", s, t, f->Name);
+      }
+    }
+    else if (testCommand || extractCommand)
+    {
+      UInt32 i;
+
+      /*
+      if you need cache, use these 3 variables.
+      if you use external function, you can make these variable as static.
+      */
+      UInt32 blockIndex = 0xFFFFFFFF; /* it can have any value before first call (if outBuffer = 0) */
+      Byte *outBuffer = 0; /* it must be 0 before first call for each new archive. */
+      size_t outBufferSize = 0;  /* it can have any value before first call (if outBuffer = 0) */
+
+      printf("\n");
+      for (i = 0; i < db.Database.NumFiles; i++)
+      {
+        size_t offset;
+        size_t outSizeProcessed;
+        CFileItem *f = db.Database.Files + i;
+        if (f->IsDirectory)
+          printf("Directory ");
+        else
+          printf(testCommand ? 
+            "Testing   ":
+            "Extracting");
+        printf(" %s", f->Name);
+        if (f->IsDirectory)
+        {
+          printf("\n");
+          continue;
+        }
+        res = SzExtract(&archiveStream.InStream, &db, i, 
+            &blockIndex, &outBuffer, &outBufferSize, 
+            &offset, &outSizeProcessed, 
+            &allocImp, &allocTempImp);
+        if (res != SZ_OK)
+          break;
+        if (!testCommand)
+        {
+          MY_FILE_HANDLE outputHandle;
+          size_t processedSize;
+          char *fileName = f->Name;
+          size_t nameLen = strlen(f->Name);
+          for (; nameLen > 0; nameLen--)
+            if (f->Name[nameLen - 1] == '/')
+            {
+              fileName = f->Name + nameLen;
+              break;
+            }
+            
+          outputHandle = 
+          #ifdef USE_WINDOWS_FUNCTIONS
+            CreateFile(fileName, GENERIC_WRITE, FILE_SHARE_READ, 
+                NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
+          if (outputHandle == INVALID_HANDLE_VALUE)
+          #else
+          fopen(fileName, "wb+");
+          if (outputHandle == 0)
+          #endif
+          {
+            PrintError("can not open output file");
+            res = SZE_FAIL;
+            break;
+          }
+          processedSize = MyWriteFile(outputHandle, outBuffer + offset, outSizeProcessed);
+          if (processedSize != outSizeProcessed)
+          {
+            PrintError("can not write output file");
+            res = SZE_FAIL;
+            break;
+          }
+          if (MyCloseFile(outputHandle))
+          {
+            PrintError("can not close output file");
+            res = SZE_FAIL;
+            break;
+          }
+        }
+        printf("\n");
+      }
+      allocImp.Free(outBuffer);
+    }
+    else
+    {
+      PrintError("incorrect command");
+      res = SZE_FAIL;
+    }
+  }
+  SzArDbExFree(&db, allocImp.Free);
+
+  MyCloseFile(archiveStream.File);
+  if (res == SZ_OK)
+  {
+    printf("\nEverything is Ok\n");
+    return 0;
+  }
+  if (res == (SZ_RESULT)SZE_NOTIMPL)
+    PrintError("decoder doesn't support this archive");
+  else if (res == (SZ_RESULT)SZE_OUTOFMEMORY)
+    PrintError("can not allocate memory");
+  else if (res == (SZ_RESULT)SZE_CRC_ERROR)
+    PrintError("CRC error");
+  else     
+    printf("\nERROR #%d\n", res);
+  return 1;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/misc/libphysfs/lzma/C/Archive/7z/7zMethodID.c	Mon Apr 10 12:06:43 2017 -0400
@@ -0,0 +1,10 @@
+/* 7zMethodID.c */
+
+#include "7zMethodID.h"
+
+/*
+int AreMethodsEqual(CMethodID *a1, CMethodID *a2)
+{
+  return (*a1 == *a2) ? 1 : 0;
+}
+*/
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/misc/libphysfs/lzma/C/Archive/7z/7zMethodID.h	Mon Apr 10 12:06:43 2017 -0400
@@ -0,0 +1,10 @@
+/* 7zMethodID.h */
+
+#ifndef __7Z_METHOD_ID_H
+#define __7Z_METHOD_ID_H
+
+#include "../../Types.h"
+
+typedef UInt64 CMethodID;
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/misc/libphysfs/lzma/C/Archive/7z/7z_C.dsp	Mon Apr 10 12:06:43 2017 -0400
@@ -0,0 +1,211 @@
+# Microsoft Developer Studio Project File - Name="7z_C" - Package Owner=<4>
+# Microsoft Developer Studio Generated Build File, Format Version 6.00
+# ** DO NOT EDIT **
+
+# TARGTYPE "Win32 (x86) Console Application" 0x0103
+
+CFG=7z_C - Win32 Debug
+!MESSAGE This is not a valid makefile. To build this project using NMAKE,
+!MESSAGE use the Export Makefile command and run
+!MESSAGE 
+!MESSAGE NMAKE /f "7z_C.mak".
+!MESSAGE 
+!MESSAGE You can specify a configuration when running NMAKE
+!MESSAGE by defining the macro CFG on the command line. For example:
+!MESSAGE 
+!MESSAGE NMAKE /f "7z_C.mak" CFG="7z_C - Win32 Debug"
+!MESSAGE 
+!MESSAGE Possible choices for configuration are:
+!MESSAGE 
+!MESSAGE "7z_C - Win32 Release" (based on "Win32 (x86) Console Application")
+!MESSAGE "7z_C - Win32 Debug" (based on "Win32 (x86) Console Application")
+!MESSAGE 
+
+# Begin Project
+# PROP AllowPerConfigDependencies 0
+# PROP Scc_ProjName ""
+# PROP Scc_LocalPath ""
+CPP=cl.exe
+RSC=rc.exe
+
+!IF  "$(CFG)" == "7z_C - Win32 Release"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 0
+# PROP BASE Output_Dir "Release"
+# PROP BASE Intermediate_Dir "Release"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 0
+# PROP Output_Dir "Release"
+# PROP Intermediate_Dir "Release"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
+# ADD CPP /nologo /MD /W4 /GX /O2 /D "NDEBUG" /D "WIN32" /D "_CONSOLE" /D "_MBCS" /D "_LZMA_PROB32" /D "_LZMA_IN_CB" /YX /FD /c
+# ADD BASE RSC /l 0x419 /d "NDEBUG"
+# ADD RSC /l 0x419 /d "NDEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386
+# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 /out:"Release/7zDec.exe" /opt:NOWIN98
+# SUBTRACT LINK32 /pdb:none
+
+!ELSEIF  "$(CFG)" == "7z_C - Win32 Debug"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 1
+# PROP BASE Output_Dir "Debug"
+# PROP BASE Intermediate_Dir "Debug"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 1
+# PROP Output_Dir "Debug"
+# PROP Intermediate_Dir "Debug"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c
+# ADD CPP /nologo /W4 /Gm /GX /ZI /Od /D "_DEBUG" /D "WIN32" /D "_CONSOLE" /D "_MBCS" /D "_LZMA_PROB32" /D "_LZMA_IN_CB" /YX /FD /GZ /c
+# ADD BASE RSC /l 0x419 /d "_DEBUG"
+# ADD RSC /l 0x419 /d "_DEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept
+# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /out:"Debug/7zDec.exe" /pdbtype:sept
+
+!ENDIF 
+
+# Begin Target
+
+# Name "7z_C - Win32 Release"
+# Name "7z_C - Win32 Debug"
+# Begin Group "LZMA"
+
+# PROP Default_Filter ""
+# Begin Source File
+
+SOURCE=..\..\Compress\Lzma\LzmaDecode.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Compress\Lzma\LzmaDecode.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Compress\Lzma\LzmaTypes.h
+# End Source File
+# End Group
+# Begin Group "Common"
+
+# PROP Default_Filter ""
+# Begin Source File
+
+SOURCE=..\..\7zCrc.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\7zCrc.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Types.h
+# End Source File
+# End Group
+# Begin Group "Branch"
+
+# PROP Default_Filter ""
+# Begin Source File
+
+SOURCE=..\..\Compress\Branch\BranchTypes.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Compress\Branch\BranchX86.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Compress\Branch\BranchX86.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Compress\Branch\BranchX86_2.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Compress\Branch\BranchX86_2.h
+# End Source File
+# End Group
+# Begin Source File
+
+SOURCE=.\7zAlloc.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\7zAlloc.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\7zBuffer.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\7zBuffer.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\7zDecode.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\7zDecode.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\7zExtract.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\7zExtract.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\7zHeader.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\7zHeader.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\7zIn.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\7zIn.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\7zItem.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\7zItem.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\7zMain.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\7zMethodID.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\7zMethodID.h
+# End Source File
+# End Target
+# End Project
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/misc/libphysfs/lzma/C/Archive/7z/7z_C.dsw	Mon Apr 10 12:06:43 2017 -0400
@@ -0,0 +1,29 @@
+Microsoft Developer Studio Workspace File, Format Version 6.00
+# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE!
+
+###############################################################################
+
+Project: "7z_C"=.\7z_C.dsp - Package Owner=<4>
+
+Package=<5>
+{{{
+}}}
+
+Package=<4>
+{{{
+}}}
+
+###############################################################################
+
+Global:
+
+Package=<5>
+{{{
+}}}
+
+Package=<3>
+{{{
+}}}
+
+###############################################################################
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/misc/libphysfs/lzma/C/Archive/7z/makefile	Mon Apr 10 12:06:43 2017 -0400
@@ -0,0 +1,74 @@
+PROG = 7zDec.exe
+
+!IFDEF CPU
+LIBS = $(LIBS) bufferoverflowU.lib 
+CFLAGS = $(CFLAGS) -GS- -Zc:forScope -WX -GS- -Gy -W4 
+!ENDIF
+
+!IFNDEF O
+!IFDEF CPU
+O=$(CPU)
+!ELSE
+O=O
+!ENDIF
+!ENDIF
+
+CFLAGS = $(CFLAGS) -nologo -c -Fo$O/ -D_LZMA_IN_CB
+CFLAGS_O1 = $(CFLAGS) -O1
+CFLAGS_O2 = $(CFLAGS) -O2
+
+LFLAGS = $(LFLAGS) -nologo -OPT:NOWIN98 -OPT:REF
+
+PROGPATH = $O\$(PROG)
+
+COMPL_O1   = $(CPP) $(CFLAGS_O1) $**
+COMPL_O2   = $(CPP) $(CFLAGS_O2) $**
+COMPL      = $(CPP) $(CFLAGS_O1) $**
+
+C_OBJS = \
+  $O\7zCrc.obj \
+
+
+7Z_OBJS = \
+  $O\7zAlloc.obj \
+  $O\7zBuffer.obj \
+  $O\7zDecode.obj \
+  $O\7zExtract.obj \
+  $O\7zHeader.obj \
+  $O\7zIn.obj \
+  $O\7zItem.obj \
+  $O\7zMain.obj \
+  $O\7zMethodID.obj \
+
+OBJS = \
+  $(7Z_OBJS) \
+  $O\LzmaDecode.obj \
+  $O\BranchX86.obj \
+  $O\BranchX86_2.obj \
+  $(C_OBJS) \
+
+all: $(PROGPATH) 
+
+clean:
+	-del /Q $(PROGPATH) $O\*.exe $O\*.dll $O\*.obj $O\*.lib $O\*.exp $O\*.res $O\*.pch 
+
+$O:
+	if not exist "$O" mkdir "$O"
+
+$(PROGPATH): $O $(OBJS)
+	link $(LFLAGS) -out:$(PROGPATH) $(OBJS) $(LIBS)
+
+
+$(7Z_OBJS): $(*B).c
+	$(COMPL)
+$O\LzmaDecode.obj: ../../Compress/Lzma/$(*B).c
+	$(COMPL_O2)
+
+$O\BranchX86.obj: ../../Compress/Branch/$(*B).c
+	$(COMPL_O2)
+
+$O\BranchX86_2.obj: ../../Compress/Branch/$(*B).c
+	$(COMPL_O2)
+
+$(C_OBJS): ../../$(*B).c
+	$(COMPL_O2)
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/misc/libphysfs/lzma/C/Archive/7z/makefile.gcc	Mon Apr 10 12:06:43 2017 -0400
@@ -0,0 +1,55 @@
+PROG = 7zDec
+CXX = g++
+LIB = 
+RM = rm -f
+CFLAGS = -c -O2 -Wall -D_LZMA_IN_CB
+
+OBJS = 7zAlloc.o 7zBuffer.o 7zCrc.o 7zDecode.o 7zExtract.o 7zHeader.o 7zIn.o 7zItem.o 7zMain.o 7zMethodID.o LzmaDecode.o BranchX86.o BranchX86_2.o
+
+all: $(PROG)
+
+$(PROG): $(OBJS)
+	$(CXX) -o $(PROG) $(LDFLAGS) $(OBJS) $(LIB)
+
+7zAlloc.o: 7zAlloc.c
+	$(CXX) $(CFLAGS) 7zAlloc.c
+
+7zBuffer.o: 7zBuffer.c
+	$(CXX) $(CFLAGS) 7zBuffer.c
+
+7zCrc.o: ../../7zCrc.c
+	$(CXX) $(CFLAGS) ../../7zCrc.c
+
+7zDecode.o: 7zDecode.c
+	$(CXX) $(CFLAGS) 7zDecode.c
+
+7zExtract.o: 7zExtract.c
+	$(CXX) $(CFLAGS) 7zExtract.c
+
+7zHeader.o: 7zHeader.c
+	$(CXX) $(CFLAGS) 7zHeader.c
+
+7zIn.o: 7zIn.c
+	$(CXX) $(CFLAGS) 7zIn.c
+
+7zItem.o: 7zItem.c
+	$(CXX) $(CFLAGS) 7zItem.c
+
+7zMain.o: 7zMain.c
+	$(CXX) $(CFLAGS) 7zMain.c
+
+7zMethodID.o: 7zMethodID.c
+	$(CXX) $(CFLAGS) 7zMethodID.c
+
+LzmaDecode.o: ../../Compress/Lzma/LzmaDecode.c
+	$(CXX) $(CFLAGS) ../../Compress/Lzma/LzmaDecode.c
+
+BranchX86.o: ../../Compress/Branch/BranchX86.c
+	$(CXX) $(CFLAGS) ../../Compress/Branch/BranchX86.c
+
+BranchX86_2.o: ../../Compress/Branch/BranchX86_2.c
+	$(CXX) $(CFLAGS) ../../Compress/Branch/BranchX86_2.c
+
+clean:
+	-$(RM) $(PROG) $(OBJS)
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/misc/libphysfs/lzma/C/Compress/Branch/BranchARM.c	Mon Apr 10 12:06:43 2017 -0400
@@ -0,0 +1,26 @@
+/* BranchARM.c */
+
+#include "BranchARM.h"
+
+UInt32 ARM_Convert(Byte *data, UInt32 size, UInt32 nowPos, int encoding)
+{
+  UInt32 i;
+  for (i = 0; i + 4 <= size; i += 4)
+  {
+    if (data[i + 3] == 0xEB)
+    {
+      UInt32 dest;
+      UInt32 src = (data[i + 2] << 16) | (data[i + 1] << 8) | (data[i + 0]);
+      src <<= 2;
+      if (encoding)
+        dest = nowPos + i + 8 + src;
+      else
+        dest = src - (nowPos + i + 8);
+      dest >>= 2;
+      data[i + 2] = (Byte)(dest >> 16);
+      data[i + 1] = (Byte)(dest >> 8);
+      data[i + 0] = (Byte)dest;
+    }
+  }
+  return i;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/misc/libphysfs/lzma/C/Compress/Branch/BranchARM.h	Mon Apr 10 12:06:43 2017 -0400
@@ -0,0 +1,10 @@
+/* BranchARM.h */
+
+#ifndef __BRANCH_ARM_H
+#define __BRANCH_ARM_H
+
+#include "BranchTypes.h"
+
+UInt32 ARM_Convert(Byte *data, UInt32 size, UInt32 nowPos, int encoding);
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/misc/libphysfs/lzma/C/Compress/Branch/BranchARMThumb.c	Mon Apr 10 12:06:43 2017 -0400
@@ -0,0 +1,35 @@
+/* BranchARMThumb.c */
+
+#include "BranchARMThumb.h"
+
+UInt32 ARMThumb_Convert(Byte *data, UInt32 size, UInt32 nowPos, int encoding)
+{
+  UInt32 i;
+  for (i = 0; i + 4 <= size; i += 2)
+  {
+    if ((data[i + 1] & 0xF8) == 0xF0 && 
+        (data[i + 3] & 0xF8) == 0xF8)
+    {
+      UInt32 dest;
+      UInt32 src = 
+        ((data[i + 1] & 0x7) << 19) |
+        (data[i + 0] << 11) |
+        ((data[i + 3] & 0x7) << 8) |
+        (data[i + 2]);
+      
+      src <<= 1;
+      if (encoding)
+        dest = nowPos + i + 4 + src;
+      else
+        dest = src - (nowPos + i + 4);
+      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;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/misc/libphysfs/lzma/C/Compress/Branch/BranchARMThumb.h	Mon Apr 10 12:06:43 2017 -0400
@@ -0,0 +1,10 @@
+/* BranchARMThumb.h */
+
+#ifndef __BRANCH_ARM_THUMB_H
+#define __BRANCH_ARM_THUMB_H
+
+#include "BranchTypes.h"
+
+UInt32 ARMThumb_Convert(Byte *data, UInt32 size, UInt32 nowPos, int encoding);
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/misc/libphysfs/lzma/C/Compress/Branch/BranchIA64.c	Mon Apr 10 12:06:43 2017 -0400
@@ -0,0 +1,66 @@
+/* BranchIA64.c */
+
+#include "BranchIA64.h"
+
+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 
+};
+
+UInt32 IA64_Convert(Byte *data, UInt32 size, UInt32 nowPos, int encoding)
+{
+  UInt32 i;
+  for (i = 0; i + 16 <= 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 
+        /* &&  (instNorm & 0x3F)== 0 */
+        )
+      {
+        UInt32 src = (UInt32)((instNorm >> 13) & 0xFFFFF);
+        UInt32 dest;
+        src |= ((UInt32)(instNorm >> 36) & 1) << 20;
+        
+        src <<= 4;
+        
+        if (encoding)
+          dest = nowPos + i + src;
+        else
+          dest = src - (nowPos + 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;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/misc/libphysfs/lzma/C/Compress/Branch/BranchIA64.h	Mon Apr 10 12:06:43 2017 -0400
@@ -0,0 +1,10 @@
+/* BranchIA64.h */
+
+#ifndef __BRANCH_IA64_H
+#define __BRANCH_IA64_H
+
+#include "BranchTypes.h"
+
+UInt32 IA64_Convert(Byte *data, UInt32 size, UInt32 nowPos, int encoding);
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/misc/libphysfs/lzma/C/Compress/Branch/BranchPPC.c	Mon Apr 10 12:06:43 2017 -0400
@@ -0,0 +1,36 @@
+/* BranchPPC.c */
+
+#include "BranchPPC.h"
+
+UInt32 PPC_B_Convert(Byte *data, UInt32 size, UInt32 nowPos, int encoding)
+{
+  UInt32 i;
+  for (i = 0; i + 4 <= size; i += 4)
+  {
+    /* PowerPC branch 6(48) 24(Offset) 1(Abs) 1(Link) */
+    if ((data[i] >> 2) == 0x12 && 
+    (
+      (data[i + 3] & 3) == 1 
+      /* || (data[i+3] & 3) == 3 */
+      )
+    )
+    {
+      UInt32 src = ((data[i + 0] & 3) << 24) |
+        (data[i + 1] << 16) |
+        (data[i + 2] << 8) |
+        (data[i + 3] & (~3));
+      
+      UInt32 dest;
+      if (encoding)
+        dest = nowPos + i + src;
+      else
+        dest = src - (nowPos + 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;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/misc/libphysfs/lzma/C/Compress/Branch/BranchPPC.h	Mon Apr 10 12:06:43 2017 -0400
@@ -0,0 +1,10 @@
+/* BranchPPC.h */
+
+#ifndef __BRANCH_PPC_H
+#define __BRANCH_PPC_H
+
+#include "BranchTypes.h"
+
+UInt32 PPC_B_Convert(Byte *data, UInt32 size, UInt32 nowPos, int encoding);
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/misc/libphysfs/lzma/C/Compress/Branch/BranchSPARC.c	Mon Apr 10 12:06:43 2017 -0400
@@ -0,0 +1,36 @@
+/* BranchSPARC.c */
+
+#include "BranchSPARC.h"
+
+UInt32 SPARC_Convert(Byte *data, UInt32 size, UInt32 nowPos, int encoding)
+{
+  UInt32 i;
+  for (i = 0; i + 4 <= 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 = nowPos + i + src;
+      else
+        dest = src - (nowPos + 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;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/misc/libphysfs/lzma/C/Compress/Branch/BranchSPARC.h	Mon Apr 10 12:06:43 2017 -0400
@@ -0,0 +1,10 @@
+/* BranchSPARC.h */
+
+#ifndef __BRANCH_SPARC_H
+#define __BRANCH_SPARC_H
+
+#include "BranchTypes.h"
+
+UInt32 SPARC_Convert(Byte *data, UInt32 size, UInt32 nowPos, int encoding);
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/misc/libphysfs/lzma/C/Compress/Branch/BranchTypes.h	Mon Apr 10 12:06:43 2017 -0400
@@ -0,0 +1,51 @@
+/* BranchTypes.h */
+
+#ifndef __BRANCHTYPES_H
+#define __BRANCHTYPES_H
+
+#ifndef _7ZIP_BYTE_DEFINED
+#define _7ZIP_BYTE_DEFINED
+typedef unsigned char Byte;
+#endif 
+
+#ifndef _7ZIP_UINT16_DEFINED
+#define _7ZIP_UINT16_DEFINED
+typedef unsigned short UInt16;
+#endif 
+
+#ifndef _7ZIP_UINT32_DEFINED
+#define _7ZIP_UINT32_DEFINED
+#ifdef _LZMA_UINT32_IS_ULONG
+typedef unsigned long UInt32;
+#else
+typedef unsigned int UInt32;
+#endif
+#endif
+
+#ifndef _7ZIP_UINT64_DEFINED
+#define _7ZIP_UINT64_DEFINED
+#ifdef _SZ_NO_INT_64
+typedef unsigned long UInt64;
+#else
+#if defined(_MSC_VER) || defined(__BORLANDC__)
+typedef unsigned __int64 UInt64;
+#else
+typedef unsigned long long int UInt64;
+#endif
+#endif
+#endif
+
+/* #define _LZMA_NO_SYSTEM_SIZE_T */
+/* You can use it, if you don't want <stddef.h> */
+
+#ifndef _7ZIP_SIZET_DEFINED
+#define _7ZIP_SIZET_DEFINED
+#ifdef _LZMA_NO_SYSTEM_SIZE_T
+typedef UInt32 SizeT;
+#else
+#include <stddef.h>
+typedef size_t SizeT;
+#endif
+#endif
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/misc/libphysfs/lzma/C/Compress/Branch/BranchX86.c	Mon Apr 10 12:06:43 2017 -0400
@@ -0,0 +1,84 @@
+/* BranchX86.c */
+
+#include "BranchX86.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 *buffer, SizeT endPos, UInt32 nowPos, UInt32 *prevMaskMix, int encoding)
+{
+  SizeT bufferPos = 0, prevPosT;
+  UInt32 prevMask = *prevMaskMix & 0x7;
+  if (endPos < 5)
+    return 0;
+  nowPos += 5;
+  prevPosT = (SizeT)0 - 1;
+
+  for(;;)
+  {
+    Byte *p = buffer + bufferPos;
+    Byte *limit = buffer + endPos - 4;
+    for (; p < limit; p++)
+      if ((*p & 0xFE) == 0xE8)
+        break;
+    bufferPos = (SizeT)(p - buffer);
+    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 = (nowPos + (UInt32)bufferPos) + src;
+        else
+          dest = src - (nowPos + (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;
+  *prevMaskMix = ((prevPosT > 3) ? 0 : ((prevMask << ((int)prevPosT - 1)) & 0x7));
+  return bufferPos;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/misc/libphysfs/lzma/C/Compress/Branch/BranchX86.h	Mon Apr 10 12:06:43 2017 -0400
@@ -0,0 +1,12 @@
+/* BranchX86.h */
+
+#ifndef __BRANCHX86_H
+#define __BRANCHX86_H
+
+#include "BranchTypes.h"
+
+#define x86_Convert_Init(state) { state = 0; }
+
+SizeT x86_Convert(Byte *buffer, SizeT endPos, UInt32 nowPos, UInt32 *state, int encoding);
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/misc/libphysfs/lzma/C/Compress/Branch/BranchX86_2.c	Mon Apr 10 12:06:43 2017 -0400
@@ -0,0 +1,135 @@
+// BranchX86_2.c
+
+#include "BranchX86_2.h"
+
+#include "../../Alloc.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_INIT2 Code = 0; Range = 0xFFFFFFFF; \
+  { int i; for(i = 0; i < 5; i++) { RC_TEST; Code = (Code << 8) | RC_READ_BYTE; }}
+
+#define RC_TEST { if (Buffer == BufferLim) return BCJ2_RESULT_DATA_ERROR; }
+
+#define RC_INIT(buffer, bufferSize) Buffer = buffer; BufferLim = buffer + bufferSize; RC_INIT2
+ 
+#define RC_NORMALIZE if (Range < kTopValue) { RC_TEST; Range <<= 8; Code = (Code << 8) | RC_READ_BYTE; }
+
+#define IfBit0(p) RC_NORMALIZE; bound = (Range >> kNumBitModelTotalBits) * *(p); if (Code < bound)
+#define UpdateBit0(p) Range = bound; *(p) += (kBitModelTotal - *(p)) >> kNumMoveBits;
+#define UpdateBit1(p) Range -= bound; Code -= bound; *(p) -= (*(p)) >> kNumMoveBits;
+// #define UpdateBit0(p) Range = bound; *(p) = (CProb)(*(p) + ((kBitModelTotal - *(p)) >> kNumMoveBits));
+// #define UpdateBit1(p) Range -= bound; Code -= bound; *(p) = (CProb)(*(p) - (*(p) >> kNumMoveBits));
+
+int x86_2_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; 
+  RC_INIT(buf3, size3);
+
+  if (outSize == 0)
+    return BCJ2_RESULT_OK;
+
+  for (;;)
+  {
+    Byte b;
+    CProb *prob;
+    UInt32 bound;
+
+    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;
+
+    IfBit0(prob)
+    {
+      UpdateBit0(prob)
+      prevByte = b;
+    }
+    else
+    {
+      UInt32 dest;
+      const Byte *v;
+      UpdateBit1(prob)
+      if (b == 0xE8)
+      {
+        v = buf1;
+        if (size1 < 4)
+          return BCJ2_RESULT_DATA_ERROR;
+        buf1 += 4;
+        size1 -= 4;
+      }
+      else
+      {
+        v = buf2;
+        if (size2 < 4)
+          return BCJ2_RESULT_DATA_ERROR;
+        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) ? BCJ2_RESULT_OK : BCJ2_RESULT_DATA_ERROR;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/misc/libphysfs/lzma/C/Compress/Branch/BranchX86_2.h	Mon Apr 10 12:06:43 2017 -0400
@@ -0,0 +1,28 @@
+// BranchX86_2.h
+
+#ifndef __BRANCHX86_2_H
+#define __BRANCHX86_2_H
+
+#include "BranchTypes.h"
+
+#define BCJ2_RESULT_OK 0
+#define BCJ2_RESULT_DATA_ERROR 1
+
+/*
+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).
+*/
+
+int x86_2_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);
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/misc/libphysfs/lzma/C/Compress/Huffman/HuffmanEncode.c	Mon Apr 10 12:06:43 2017 -0400
@@ -0,0 +1,146 @@
+/* Compress/HuffmanEncode.c */
+
+#include "HuffmanEncode.h"
+#include "../../Sort.h"
+
+#define kMaxLen 16
+#define NUM_BITS 10
+#define MASK ((1 << NUM_BITS) - 1)
+
+#define NUM_COUNTERS 64
+
+/* use BLOCK_SORT_EXTERNAL_FLAGS if blockSize > 1M */
+#define HUFFMAN_SPEED_OPT
+
+void Huffman_Generate(const UInt32 *freqs, UInt32 *p, Byte *lens, UInt32 numSymbols, UInt32 maxLen)
+{
+  UInt32 num = 0;
+  /* if (maxLen > 10) maxLen = 10; */
+  {
+    UInt32 i;
+    
+    #ifdef HUFFMAN_SPEED_OPT
+    
+    UInt32 counters[NUM_COUNTERS];
+    for (i = 0; i < NUM_COUNTERS; i++) 
+      counters[i] = 0;
+    for (i = 0; i < numSymbols; i++) 
+    {
+      UInt32 freq = freqs[i];
+      counters[(freq < NUM_COUNTERS - 1) ? freq : NUM_COUNTERS - 1]++;
+    }
+ 
+    for (i = 1; i < NUM_COUNTERS; i++) 
+    {
+      UInt32 temp = counters[i];
+      counters[i] = num;
+      num += temp;
+    }
+
+    for (i = 0; i < numSymbols; i++) 
+    {
+      UInt32 freq = freqs[i];
+      if (freq == 0)
+        lens[i] = 0;
+      else
+        p[counters[((freq < NUM_COUNTERS - 1) ? freq : NUM_COUNTERS - 1)]++] = i | (freq << NUM_BITS);
+    }
+    counters[0] = 0;
+    HeapSort(p + counters[NUM_COUNTERS - 2], counters[NUM_COUNTERS - 1] - counters[NUM_COUNTERS - 2]);
+    
+    #else
+
+    for (i = 0; i < numSymbols; i++) 
+    {
+      UInt32 freq = freqs[i];
+      if (freq == 0)
+        lens[i] = 0;
+      else
+        p[num++] = i | (freq << NUM_BITS);
+    }
+    HeapSort(p, num);
+
+    #endif
+  }
+
+  if (num < 2) 
+  {
+    int minCode = 0;
+    int maxCode = 1;
+    if (num == 1)
+    {
+      maxCode = p[0] & MASK;
+      if (maxCode == 0)
+        maxCode++;
+    }
+    p[minCode] = 0;
+    p[maxCode] = 1;
+    lens[minCode] = lens[maxCode] = 1;
+    return;
+  }
+  
+  {
+    UInt32 b, e, i;
+  
+    i = b = e = 0;
+    do 
+    {
+      UInt32 n, m, freq;
+      n = (i != num && (b == e || (p[i] >> NUM_BITS) <= (p[b] >> NUM_BITS))) ? i++ : b++;
+      freq = (p[n] & ~MASK);
+      p[n] = (p[n] & MASK) | (e << NUM_BITS);
+      m = (i != num && (b == e || (p[i] >> NUM_BITS) <= (p[b] >> NUM_BITS))) ? i++ : b++;
+      freq += (p[m] & ~MASK);
+      p[m] = (p[m] & MASK) | (e << NUM_BITS);
+      p[e] = (p[e] & MASK) | freq;
+      e++;
+    } 
+    while (num - e > 1);
+    
+    {
+      UInt32 lenCounters[kMaxLen + 1];
+      for (i = 0; i <= kMaxLen; i++) 
+        lenCounters[i] = 0;
+      
+      p[--e] &= MASK;
+      lenCounters[1] = 2;
+      while (e > 0) 
+      {
+        UInt32 len = (p[p[--e] >> NUM_BITS] >> NUM_BITS) + 1;
+        p[e] = (p[e] & MASK) | (len << NUM_BITS);
+        if (len >= maxLen) 
+          for (len = maxLen - 1; lenCounters[len] == 0; len--);
+        lenCounters[len]--;
+        lenCounters[len + 1] += 2;
+      }
+      
+      {
+        UInt32 len;
+        i = 0;
+        for (len = maxLen; len != 0; len--) 
+        {
+          UInt32 num;
+          for (num = lenCounters[len]; num != 0; num--) 
+            lens[p[i++] & MASK] = (Byte)len;
+        }
+      }
+      
+      {
+        UInt32 nextCodes[kMaxLen + 1];
+        {
+          UInt32 code = 0;
+          UInt32 len;
+          for (len = 1; len <= kMaxLen; len++) 
+            nextCodes[len] = code = (code + lenCounters[len - 1]) << 1;
+        }
+        /* if (code + lenCounters[kMaxLen] - 1 != (1 << kMaxLen) - 1) throw 1; */
+
+        {
+          UInt32 i;
+          for (i = 0; i < numSymbols; i++) 
+            p[i] = nextCodes[lens[i]]++;
+        }
+      }
+    }
+  }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/misc/libphysfs/lzma/C/Compress/Huffman/HuffmanEncode.h	Mon Apr 10 12:06:43 2017 -0400
@@ -0,0 +1,18 @@
+/* Compress/HuffmanEncode.h */
+
+#ifndef __COMPRESS_HUFFMANENCODE_H
+#define __COMPRESS_HUFFMANENCODE_H
+
+#include "../../Types.h"
+
+/*
+Conditions:
+  num <= 1024 = 2 ^ NUM_BITS
+  Sum(freqs) < 4M = 2 ^ (32 - NUM_BITS)
+  maxLen <= 16 = kMaxLen
+  Num_Items(p) >= HUFFMAN_TEMP_SIZE(num)
+*/
+ 
+void Huffman_Generate(const UInt32 *freqs, UInt32 *p, Byte *lens, UInt32 num, UInt32 maxLen);
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/misc/libphysfs/lzma/C/Compress/Lz/LzHash.h	Mon Apr 10 12:06:43 2017 -0400
@@ -0,0 +1,53 @@
+/* LzHash.h */
+
+#ifndef __C_LZHASH_H
+#define __C_LZHASH_H
+
+#define kHash2Size (1 << 10)
+#define kHash3Size (1 << 16)
+#define kHash4Size (1 << 20)
+
+#define kFix3HashSize (kHash2Size)
+#define kFix4HashSize (kHash2Size + kHash3Size)
+#define kFix5HashSize (kHash2Size + kHash3Size + kHash4Size)
+
+#define HASH2_CALC hashValue = cur[0] | ((UInt32)cur[1] << 8);
+
+#define HASH3_CALC { \
+  UInt32 temp = g_CrcTable[cur[0]] ^ cur[1]; \
+  hash2Value = temp & (kHash2Size - 1); \
+  hashValue = (temp ^ ((UInt32)cur[2] << 8)) & p->hashMask; }
+
+#define HASH4_CALC { \
+  UInt32 temp = g_CrcTable[cur[0]] ^ cur[1]; \
+  hash2Value = temp & (kHash2Size - 1); \
+  hash3Value = (temp ^ ((UInt32)cur[2] << 8)) & (kHash3Size - 1); \
+  hashValue = (temp ^ ((UInt32)cur[2] << 8) ^ (g_CrcTable[cur[3]] << 5)) & p->hashMask; }
+
+#define HASH5_CALC { \
+  UInt32 temp = g_CrcTable[cur[0]] ^ cur[1]; \
+  hash2Value = temp & (kHash2Size - 1); \
+  hash3Value = (temp ^ ((UInt32)cur[2] << 8)) & (kHash3Size - 1); \
+  hash4Value = (temp ^ ((UInt32)cur[2] << 8) ^ (g_CrcTable[cur[3]] << 5)); \
+  hashValue = (hash4Value ^ (g_CrcTable[cur[4]] << 3)) & p->hashMask; \
+  hash4Value &= (kHash4Size - 1); }
+
+/* #define HASH_ZIP_CALC hashValue = ((cur[0] | ((UInt32)cur[1] << 8)) ^ g_CrcTable[cur[2]]) & 0xFFFF; */
+#define HASH_ZIP_CALC hashValue = ((cur[2] | ((UInt32)cur[0] << 8)) ^ g_CrcTable[cur[1]]) & 0xFFFF;
+
+
+#define MT_HASH2_CALC \
+  hash2Value = (g_CrcTable[cur[0]] ^ cur[1]) & (kHash2Size - 1);
+
+#define MT_HASH3_CALC { \
+  UInt32 temp = g_CrcTable[cur[0]] ^ cur[1]; \
+  hash2Value = temp & (kHash2Size - 1); \
+  hash3Value = (temp ^ ((UInt32)cur[2] << 8)) & (kHash3Size - 1); }
+
+#define MT_HASH4_CALC { \
+  UInt32 temp = g_CrcTable[cur[0]] ^ cur[1]; \
+  hash2Value = temp & (kHash2Size - 1); \
+  hash3Value = (temp ^ ((UInt32)cur[2] << 8)) & (kHash3Size - 1); \
+  hash4Value = (temp ^ ((UInt32)cur[2] << 8) ^ (g_CrcTable[cur[3]] << 5)) & (kHash4Size - 1); }
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/misc/libphysfs/lzma/C/Compress/Lz/MatchFinder.c	Mon Apr 10 12:06:43 2017 -0400
@@ -0,0 +1,742 @@
+/* MatchFinder.c */
+/* Please call InitCrcTable before */
+
+#include <string.h>
+
+#include "MatchFinder.h"
+#include "LzHash.h"
+
+#include "../../7zCrc.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
+
+void LzInWindow_Free(CMatchFinder *p, ISzAlloc *alloc)
+{
+  if (!p->directInput)
+  {
+    alloc->Free(p->bufferBase);
+    p->bufferBase = 0;
+  }
+}
+
+/* keepSizeBefore + keepSizeAfter + keepSizeReserv must be < 4G) */
+
+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(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;
+}
+
+void MatchFinder_ReadBlock(CMatchFinder *p)
+{
+  if (p->streamEndWasReached || p->result != SZ_OK)
+    return;
+  for (;;)
+  {
+    Byte *dest = p->buffer + (p->streamPos - p->pos);
+    UInt32 numReadBytes;
+    UInt32 size = (UInt32)(p->bufferBase + p->blockSize - dest);
+    if (size == 0)
+      return;
+    p->result = p->stream->Read(p->stream, dest, size, &numReadBytes);
+    if (p->result != SZ_OK)
+      return;
+    if (numReadBytes == 0)
+    {
+      p->streamEndWasReached = 1;
+      return;
+    }
+    p->streamPos += numReadBytes;
+    if (p->streamPos - p->pos > p->keepSizeAfter)
+      return;
+  }
+}
+
+void MatchFinder_MoveBlock(CMatchFinder *p)
+{
+  memmove(p->bufferBase, 
+    p->buffer - p->keepSizeBefore, 
+    p->streamPos - p->pos + p->keepSizeBefore);
+  p->buffer = p->bufferBase + p->keepSizeBefore;
+}
+
+int MatchFinder_NeedMove(CMatchFinder *p)
+{
+  /* 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);
+}
+
+void MatchFinder_CheckAndMoveAndRead(CMatchFinder *p)
+{
+  if (MatchFinder_NeedMove(p))
+    MatchFinder_MoveBlock(p);
+  MatchFinder_ReadBlock(p);
+}
+
+void MatchFinder_SetDefaultSettings(CMatchFinder *p)
+{
+  p->cutValue = 32;
+  p->btMode = 1;
+  p->numHashBytes = 4;
+  /* p->skipModeBits = 0; */
+  p->directInput = 0;
+  p->bigHash = 0;
+}
+
+void MatchFinder_Construct(CMatchFinder *p)
+{
+  p->bufferBase = 0;
+  p->directInput = 0;
+  p->hash = 0;
+  MatchFinder_SetDefaultSettings(p);
+}
+
+void MatchFinder_FreeThisClassMemory(CMatchFinder *p, ISzAlloc *alloc)
+{
+  alloc->Free(p->hash);
+  p->hash = 0;
+}
+
+void MatchFinder_Free(CMatchFinder *p, ISzAlloc *alloc)
+{
+  MatchFinder_FreeThisClassMemory(p, alloc);
+  LzInWindow_Free(p, alloc);
+}
+
+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(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 /* >> p->skipModeBits */) + 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 >>= p->skipModeBits; */
+        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;
+}
+
+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);
+}
+
+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;
+  }
+}
+
+void MatchFinder_Normalize(CMatchFinder *p)
+{
+  UInt32 subValue = MatchFinder_GetSubValue(p);
+  MatchFinder_Normalize3(subValue, p->hash, p->hashSizeSum + p->numSons);
+  MatchFinder_ReduceOffsets(p, subValue);
+}
+
+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);
+}
+
+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;
+      }
+    }
+  }
+}
+
+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;
+
+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;
+
+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)
+}
+
+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)
+}
+
+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)
+}
+
+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
+}
+
+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);
+}
+
+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);
+}
+
+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);
+}
+
+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;
+  }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/misc/libphysfs/lzma/C/Compress/Lz/MatchFinder.h	Mon Apr 10 12:06:43 2017 -0400
@@ -0,0 +1,106 @@
+/* MatchFinder.h */
+
+#ifndef __MATCHFINDER_H
+#define __MATCHFINDER_H
+
+#include "../../IStream.h"
+
+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;
+  int btMode;
+  /* int skipModeBits; */
+  int bigHash;
+  UInt32 historySize;
+  UInt32 fixedHashSize;
+  UInt32 hashSizeSum;
+  UInt32 numSons;
+
+  HRes result;
+} 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);
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/misc/libphysfs/lzma/C/Compress/Lz/MatchFinderMt.c	Mon Apr 10 12:06:43 2017 -0400
@@ -0,0 +1,806 @@
+/* MatchFinderMt.c */
+
+#ifdef _WIN32
+#define USE_ALLOCA
+#endif
+
+#ifdef USE_ALLOCA
+#ifdef _WIN32
+#include <malloc.h>
+#else
+#include <stdlib.h>
+#endif
+#endif
+
+#include "../../7zCrc.h"
+#include "LzHash.h"
+
+#include "MatchFinderMt.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;
+}
+
+HRes MtSync_Create2(CMtSync *p, unsigned (StdCall *startAddress)(void *), void *obj, UInt32 numBlocks)
+{
+  if (p->wasCreated)
+    return SZ_OK;
+
+  RINOK(CriticalSection_Init(&p->cs));
+  p->csWasInitialized = True;
+
+  RINOK(AutoResetEvent_CreateNotSignaled(&p->canStart));
+  RINOK(AutoResetEvent_CreateNotSignaled(&p->wasStarted));
+  RINOK(AutoResetEvent_CreateNotSignaled(&p->wasStopped));
+  
+  RINOK(Semaphore_Create(&p->freeSemaphore, numBlocks, numBlocks));
+  RINOK(Semaphore_Create(&p->filledSemaphore, 0, numBlocks));
+
+  p->needStart = True;
+  
+  RINOK(Thread_Create(&p->thread, startAddress, obj));
+  p->wasCreated = True;
+  return SZ_OK;
+}
+
+HRes MtSync_Create(CMtSync *p, unsigned (StdCall *startAddress)(void *), void *obj, UInt32 numBlocks)
+{
+  HRes 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_GetHeads(name, v) \
+static void GetHeads ## name(const Byte *p, UInt32 pos, \
+UInt32 *hash, UInt32 hashMask, UInt32 *heads, UInt32 numHeads) { \
+for (; numHeads != 0; numHeads--) { \
+const UInt32 value = (v); p++; *heads++ = pos - hash[value]; hash[value] = pos++;  } }
+
+DEF_GetHeads(2,  (p[0] | ((UInt32)p[1] << 8)) & hashMask)
+DEF_GetHeads(3,  (g_CrcTable[p[0]] ^ p[1] ^ ((UInt32)p[2] << 8)) & hashMask)
+DEF_GetHeads(4,  (g_CrcTable[p[0]] ^ p[1] ^ ((UInt32)p[2] << 8) ^ (g_CrcTable[p[3]] << 5)) & hashMask)
+DEF_GetHeads(4b, (g_CrcTable[p[0]] ^ p[1] ^ ((UInt32)p[2] << 8) ^ ((UInt32)p[3] << 16)) & hashMask)
+DEF_GetHeads(5,  (g_CrcTable[p[0]] ^ p[1] ^ ((UInt32)p[2] << 8) ^ (g_CrcTable[p[3]] << 5) ^ (g_CrcTable[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);
+            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
+
+#if _MSC_VER >= 1300
+#define NO_INLINE __declspec(noinline) __fastcall 
+#else
+#ifdef _MSC_VER
+#define NO_INLINE __fastcall 
+#endif
+#endif
+
+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;
+        size2 = p->cyclicBufferSize - cyclicBufferPos;
+        if (size2 < size)
+          size = size2;
+      }
+      #ifndef MFMT_GM_INLINE
+      while (curPos < limit && size-- != 0)
+      {
+        UInt32 *startDistances = distances + curPos;
+        UInt32 num = (UInt32)(GetMatchesSpec1(lenLimit, pos - p->hashBuf[p->hashBufPos++], 
+          pos, p->buffer, p->son, cyclicBufferPos, p->cyclicBufferSize, p->cutValue, 
+          startDistances + 1, p->numHashBytes - 1) - startDistances);
+        *startDistances = num - 1;
+        curPos += num;
+        cyclicBufferPos++;
+        pos++;
+        p->buffer++;
+      }
+      #else
+      {
+        UInt32 posRes;
+        curPos = limit - GetMatchesSpecN(lenLimit, pos, p->buffer, p->son, cyclicBufferPos, p->cyclicBufferSize, p->cutValue, 
+          distances + curPos, p->numHashBytes - 1, p->hashBuf + p->hashBufPos, (Int32)(limit - curPos) , size, &posRes);
+        p->hashBufPos += posRes - pos;
+        cyclicBufferPos += posRes - pos;
+        p->buffer += posRes - pos;
+        pos = posRes;
+      }
+      #endif
+
+      numProcessed += pos - p->pos;
+      p->hashNumAvail -= pos - p->pos;
+      p->pos = pos;
+      if (cyclicBufferPos == p->cyclicBufferSize)
+        cyclicBufferPos = 0;
+      p->cyclicBufferPos = cyclicBufferPos;
+    }
+  }
+  distances[0] = curPos;
+}
+
+void BtFillBlock(CMatchFinderMt *p, UInt32 globalBlockIndex)
+{
+  CMtSync *sync = &p->hashSync;
+  if (!sync->needStart)
+  {
+    CriticalSection_Enter(&sync->cs);
+    sync->csWasEntered = True;
+  }
+  
+  BtGetMatches(p, p->btBuf + (globalBlockIndex & kMtBtNumBlocksMask) * kMtBtBlockSize);
+
+  if (p->pos > kMtMaxValForNormalize - kMtBtBlockSize)
+  {
+    UInt32 subValue = p->pos - p->cyclicBufferSize;
+    MatchFinder_Normalize3(subValue, p->son, p->cyclicBufferSize * 2);
+    p->pos -= subValue;
+  }
+
+  if (!sync->needStart)
+  {
+    CriticalSection_Leave(&sync->cs);
+    sync->csWasEntered = False;
+  }
+}
+
+void BtThreadFunc(CMatchFinderMt *mt)
+{
+  CMtSync *p = &mt->btSync;
+  for (;;)
+  {
+    UInt32 blockIndex = 0;
+    Event_Wait(&p->canStart);
+    Event_Set(&p->wasStarted);
+    for (;;)
+    {
+      if (p->exit)
+        return;
+      if (p->stopWriting)
+      {
+        p->numProcessedBlocks = blockIndex;
+        MtSync_StopWriting(&mt->hashSync);
+        Event_Set(&p->wasStopped);
+        break;
+      }
+      Semaphore_Wait(&p->freeSemaphore);
+      BtFillBlock(mt, blockIndex++);
+      Semaphore_Release1(&p->filledSemaphore);
+    }
+  }
+}
+
+void MatchFinderMt_Construct(CMatchFinderMt *p)
+{
+  p->hashBuf = 0;
+  MtSync_Construct(&p->hashSync);
+  MtSync_Construct(&p->btSync);
+}
+
+void MatchFinderMt_FreeMem(CMatchFinderMt *p, ISzAlloc *alloc)
+{
+  alloc->Free(p->hashBuf);
+  p->hashBuf = 0;
+}
+
+void MatchFinderMt_Destruct(CMatchFinderMt *p, ISzAlloc *alloc)
+{
+  MtSync_Destruct(&p->hashSync);
+  MtSync_Destruct(&p->btSync);
+  MatchFinderMt_FreeMem(p, alloc);
+}
+
+#define kHashBufferSize (kMtHashBlockSize * kMtHashNumBlocks)
+#define kBtBufferSize (kMtBtBlockSize * kMtBtNumBlocks)
+
+static unsigned StdCall HashThreadFunc2(void *p) { HashThreadFunc((CMatchFinderMt *)p);  return 0; }
+static unsigned StdCall BtThreadFunc2(void *p) 
+{ 
+  #ifdef USE_ALLOCA
+  alloca(0x180);
+  #endif
+  BtThreadFunc((CMatchFinderMt *)p); 
+  return 0; 
+}
+
+HRes MatchFinderMt_Create(CMatchFinderMt *p, UInt32 historySize, UInt32 keepAddBufferBefore, 
+    UInt32 matchMaxLen, UInt32 keepAddBufferAfter, ISzAlloc *alloc)
+{ 
+  CMatchFinder *mf = p->MatchFinder;
+  p->historySize = historySize;
+  if (kMtBtBlockSize <= matchMaxLen * 4)
+    return E_INVALIDARG;
+  if (p->hashBuf == 0)
+  {
+    p->hashBuf = (UInt32 *)alloc->Alloc((kHashBufferSize + kBtBufferSize) * sizeof(UInt32));
+    if (p->hashBuf == 0)
+      return SZE_OUTOFMEMORY;
+    p->btBuf = p->hashBuf + kHashBufferSize;
+  }
+  keepAddBufferBefore += (kHashBufferSize + kBtBufferSize);
+  keepAddBufferAfter += kMtHashBlockSize;
+  if (!MatchFinder_Create(mf, historySize, keepAddBufferBefore, matchMaxLen, keepAddBufferAfter, alloc))
+    return SZE_OUTOFMEMORY;
+
+  RINOK(MtSync_Create(&p->hashSync, HashThreadFunc2, p, kMtHashNumBlocks));
+  RINOK(MtSync_Create(&p->btSync, BtThreadFunc2, p, kMtBtNumBlocks));
+  return SZ_OK;
+}
+
+/* Call it after ReleaseStream / SetStream */
+void MatchFinderMt_Init(CMatchFinderMt *p)
+{ 
+  CMatchFinder *mf = p->MatchFinder;
+  p->btBufPos = p->btBufPosLimit = 0;
+  p->hashBufPos = p->hashBufPosLimit = 0;
+  MatchFinder_Init(mf);
+  p->pointerToCurPos = MatchFinder_GetPointerToCurrentPos(mf);
+  p->btNumAvailBytes = 0;
+  p->lzPos = p->historySize + 1;
+
+  p->hash = mf->hash;
+  p->fixedHashSize = mf->fixedHashSize;
+
+  p->son = mf->son;
+  p->matchMaxLen = mf->matchMaxLen;
+  p->numHashBytes = mf->numHashBytes;
+  p->pos = mf->pos;
+  p->buffer = mf->buffer;
+  p->cyclicBufferPos = mf->cyclicBufferPos;
+  p->cyclicBufferSize = mf->cyclicBufferSize;
+  p->cutValue = mf->cutValue;
+}
+
+/* ReleaseStream is required to finish multithreading */
+void MatchFinderMt_ReleaseStream(CMatchFinderMt *p)
+{ 
+  MtSync_StopWriting(&p->btSync);
+  /* p->MatchFinder->ReleaseStream(); */
+}
+
+void MatchFinderMt_Normalize(CMatchFinderMt *p)
+{
+  MatchFinder_Normalize3(p->lzPos - p->historySize - 1, p->hash, p->fixedHashSize);
+  p->lzPos = p->historySize + 1;
+}
+
+void MatchFinderMt_GetNextBlock_Bt(CMatchFinderMt *p)
+{
+  UInt32 blockIndex;
+  MtSync_GetNextBlock(&p->btSync);
+  blockIndex = ((p->btSync.numProcessedBlocks - 1) & kMtBtNumBlocksMask);
+  p->btBufPosLimit = p->btBufPos = blockIndex * kMtBtBlockSize;
+  p->btBufPosLimit += p->btBuf[p->btBufPos++];
+  p->btNumAvailBytes = p->btBuf[p->btBufPos++];
+  if (p->lzPos >= kMtMaxValForNormalize - kMtBtBlockSize) 
+    MatchFinderMt_Normalize(p);
+}
+
+const Byte * MatchFinderMt_GetPointerToCurrentPos(CMatchFinderMt *p)
+{
+  return p->pointerToCurPos;
+}
+
+#define GET_NEXT_BLOCK_IF_REQUIRED if (p->btBufPos == p->btBufPosLimit) MatchFinderMt_GetNextBlock_Bt(p);
+
+UInt32 MatchFinderMt_GetNumAvailableBytes(CMatchFinderMt *p)
+{ 
+  GET_NEXT_BLOCK_IF_REQUIRED;
+  return p->btNumAvailBytes;
+}
+
+Byte MatchFinderMt_GetIndexByte(CMatchFinderMt *p, Int32 index)
+{ 
+  return p->pointerToCurPos[index]; 
+}
+
+UInt32 * MixMatches2(CMatchFinderMt *p, UInt32 matchMinPos, UInt32 *distances)
+{
+  UInt32 hash2Value, curMatch2;
+  UInt32 *hash = p->hash;
+  const Byte *cur = p->pointerToCurPos;
+  UInt32 lzPos = p->lzPos; 
+  MT_HASH2_CALC
+      
+  curMatch2 = hash[hash2Value];
+  hash[hash2Value] = lzPos;
+
+  if (curMatch2 >= matchMinPos) 
+    if (cur[(ptrdiff_t)curMatch2 - lzPos] == cur[0])
+    {
+      *distances++ = 2; 
+      *distances++ = lzPos - curMatch2 - 1;
+    }
+  return distances;
+}
+
+UInt32 * MixMatches3(CMatchFinderMt *p, UInt32 matchMinPos, UInt32 *distances)
+{
+  UInt32 hash2Value, hash3Value, curMatch2, curMatch3;
+  UInt32 *hash = p->hash;
+  const Byte *cur = p->pointerToCurPos;
+  UInt32 lzPos = p->lzPos; 
+  MT_HASH3_CALC
+
+  curMatch2 = hash[                hash2Value];
+  curMatch3 = hash[kFix3HashSize + hash3Value];
+  
+  hash[                hash2Value] = 
+  hash[kFix3HashSize + hash3Value] = 
+    lzPos;
+
+  if (curMatch2 >= matchMinPos && cur[(ptrdiff_t)curMatch2 - lzPos] == cur[0])
+  { 
+    distances[1] = lzPos - curMatch2 - 1;
+    if (cur[(ptrdiff_t)curMatch2 - lzPos + 2] == cur[2])
+    {
+      distances[0] = 3;
+      return distances + 2;
+    }
+    distances[0] = 2; 
+    distances += 2;
+  }
+  if (curMatch3 >= matchMinPos && cur[(ptrdiff_t)curMatch3 - lzPos] == cur[0])
+  { 
+    *distances++ = 3; 
+    *distances++ = lzPos - curMatch3 - 1; 
+  }
+  return distances;
+}
+
+/*
+UInt32 *MixMatches4(CMatchFinderMt *p, UInt32 matchMinPos, UInt32 *distances)
+{
+  UInt32 hash2Value, hash3Value, hash4Value, curMatch2, curMatch3, curMatch4;
+  UInt32 *hash = p->hash;
+  const Byte *cur = p->pointerToCurPos;
+  UInt32 lzPos = p->lzPos; 
+  MT_HASH4_CALC
+      
+  curMatch2 = hash[                hash2Value];
+  curMatch3 = hash[kFix3HashSize + hash3Value];
+  curMatch4 = hash[kFix4HashSize + hash4Value];
+  
+  hash[                hash2Value] = 
+  hash[kFix3HashSize + hash3Value] = 
+  hash[kFix4HashSize + hash4Value] = 
+    lzPos;
+
+  if (curMatch2 >= matchMinPos && cur[(ptrdiff_t)curMatch2 - lzPos] == cur[0])
+  {
+    distances[1] = lzPos - curMatch2 - 1;
+    if (cur[(ptrdiff_t)curMatch2 - lzPos + 2] == cur[2])
+    {
+      distances[0] =  (cur[(ptrdiff_t)curMatch2 - lzPos + 3] == cur[3]) ? 4 : 3;
+      return distances + 2;
+    }
+    distances[0] = 2;
+    distances += 2;
+  }
+  if (curMatch3 >= matchMinPos && cur[(ptrdiff_t)curMatch3 - lzPos] == cur[0])
+  {
+    distances[1] = lzPos - curMatch3 - 1;
+    if (cur[(ptrdiff_t)curMatch3 - lzPos + 3] == cur[3])
+    {
+      distances[0] = 4;
+      return distances + 2;
+    }
+    distances[0] = 3;
+    distances += 2;
+  }
+
+  if (curMatch4 >= matchMinPos)
+    if (
+      cur[(ptrdiff_t)curMatch4 - lzPos] == cur[0] &&
+      cur[(ptrdiff_t)curMatch4 - lzPos + 3] == cur[3]
+      )
+    {
+      *distances++ = 4;
+      *distances++ = lzPos - curMatch4 - 1;
+    }
+  return distances;
+}
+*/
+
+#define INCREASE_LZ_POS p->lzPos++; p->pointerToCurPos++;
+
+UInt32 MatchFinderMt2_GetMatches(CMatchFinderMt *p, UInt32 *distances)
+{ 
+  const UInt32 *btBuf = p->btBuf + p->btBufPos;
+  UInt32 len = *btBuf++;
+  p->btBufPos += 1 + len;
+  p->btNumAvailBytes--;
+  {
+    UInt32 i;
+    for (i = 0; i < len; i += 2)
+    {
+      *distances++ = *btBuf++;
+      *distances++ = *btBuf++;
+    }
+  }
+  INCREASE_LZ_POS
+  return len;
+}
+
+UInt32 MatchFinderMt_GetMatches(CMatchFinderMt *p, UInt32 *distances)
+{ 
+  const UInt32 *btBuf = p->btBuf + p->btBufPos;
+  UInt32 len = *btBuf++;
+  p->btBufPos += 1 + len;
+
+  if (len == 0)
+  {
+    if (p->btNumAvailBytes-- >= 4) 
+      len = (UInt32)(p->MixMatchesFunc(p, p->lzPos - p->historySize, distances) - (distances));
+  }
+  else
+  {
+    /* Condition: there are matches in btBuf with length < p->numHashBytes */
+    UInt32 *distances2;
+    p->btNumAvailBytes--;
+    distances2 = p->MixMatchesFunc(p, p->lzPos - btBuf[1], distances);
+    do 
+    {
+      *distances2++ = *btBuf++;
+      *distances2++ = *btBuf++;
+    }
+    while ((len -= 2) != 0);
+    len  = (UInt32)(distances2 - (distances));
+  }
+  INCREASE_LZ_POS
+  return len;
+}
+
+#define SKIP_HEADER2  do { GET_NEXT_BLOCK_IF_REQUIRED
+#define SKIP_HEADER(n) SKIP_HEADER2 if (p->btNumAvailBytes-- >= (n)) { const Byte *cur = p->pointerToCurPos; UInt32 *hash = p->hash;
+#define SKIP_FOOTER } INCREASE_LZ_POS p->btBufPos += p->btBuf[p->btBufPos] + 1; } while(--num != 0);
+
+void MatchFinderMt0_Skip(CMatchFinderMt *p, UInt32 num)
+{ 
+  SKIP_HEADER2 { p->btNumAvailBytes--;
+  SKIP_FOOTER
+}
+
+void MatchFinderMt2_Skip(CMatchFinderMt *p, UInt32 num)
+{ 
+  SKIP_HEADER(2)
+      UInt32 hash2Value;
+      MT_HASH2_CALC
+      hash[hash2Value] = p->lzPos;
+  SKIP_FOOTER
+}
+
+void MatchFinderMt3_Skip(CMatchFinderMt *p, UInt32 num)
+{ 
+  SKIP_HEADER(3)
+      UInt32 hash2Value, hash3Value;
+      MT_HASH3_CALC
+      hash[kFix3HashSize + hash3Value] = 
+      hash[                hash2Value] = 
+        p->lzPos;
+  SKIP_FOOTER
+}
+
+/*
+void MatchFinderMt4_Skip(CMatchFinderMt *p, UInt32 num)
+{ 
+  SKIP_HEADER(4)
+      UInt32 hash2Value, hash3Value, hash4Value;
+      MT_HASH4_CALC
+      hash[kFix4HashSize + hash4Value] = 
+      hash[kFix3HashSize + hash3Value] = 
+      hash[                hash2Value] = 
+        p->lzPos;
+  SKIP_FOOTER
+}
+*/
+
+void MatchFinderMt_CreateVTable(CMatchFinderMt *p, IMatchFinder *vTable)
+{
+  vTable->Init = (Mf_Init_Func)MatchFinderMt_Init;
+  vTable->GetIndexByte = (Mf_GetIndexByte_Func)MatchFinderMt_GetIndexByte;
+  vTable->GetNumAvailableBytes = (Mf_GetNumAvailableBytes_Func)MatchFinderMt_GetNumAvailableBytes;
+  vTable->GetPointerToCurrentPos = (Mf_GetPointerToCurrentPos_Func)MatchFinderMt_GetPointerToCurrentPos;
+  vTable->GetMatches = (Mf_GetMatches_Func)MatchFinderMt_GetMatches;
+  switch(p->MatchFinder->numHashBytes)
+  {
+    case 2:
+      p->GetHeadsFunc = GetHeads2;
+      p->MixMatchesFunc = (Mf_Mix_Matches)0;
+      vTable->Skip = (Mf_Skip_Func)MatchFinderMt0_Skip;
+      vTable->GetMatches = (Mf_GetMatches_Func)MatchFinderMt2_GetMatches;
+      break;
+    case 3:
+      p->GetHeadsFunc = GetHeads3;
+      p->MixMatchesFunc = (Mf_Mix_Matches)MixMatches2;
+      vTable->Skip = (Mf_Skip_Func)MatchFinderMt2_Skip;
+      break;
+    default:
+    /* case 4: */
+      p->GetHeadsFunc = p->MatchFinder->bigHash ? GetHeads4b : GetHeads4;
+      /* p->GetHeadsFunc = GetHeads4; */
+      p->MixMatchesFunc = (Mf_Mix_Matches)MixMatches3;
+      vTable->Skip = (Mf_Skip_Func)MatchFinderMt3_Skip;
+      break;
+    /*
+    default:
+      p->GetHeadsFunc = GetHeads5;
+      p->MixMatchesFunc = (Mf_Mix_Matches)MixMatches4;
+      vTable->Skip = (Mf_Skip_Func)MatchFinderMt4_Skip;
+      break;
+    */
+  }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/misc/libphysfs/lzma/C/Compress/Lz/MatchFinderMt.h	Mon Apr 10 12:06:43 2017 -0400
@@ -0,0 +1,95 @@
+/* MatchFinderMt.h */
+
+#ifndef __MATCHFINDERMT_H
+#define __MATCHFINDERMT_H
+
+#include "../../Threads.h"
+#include "MatchFinder.h"
+
+#define kMtHashBlockSize (1 << 13)
+#define kMtHashNumBlocks (1 << 3)
+#define kMtHashNumBlocksMask (kMtHashNumBlocks - 1)
+
+#define kMtBtBlockSize (1 << 14)
+#define kMtBtNumBlocks (1 << 6)
+#define kMtBtNumBlocksMask (kMtBtNumBlocks - 1)
+
+typedef struct _CMtSync
+{
+  Bool wasCreated;
+  Bool needStart;
+  Bool exit;
+  Bool stopWriting;
+
+  CThread thread;
+  CAutoResetEvent canStart;
+  CAutoResetEvent wasStarted;
+  CAutoResetEvent wasStopped;
+  CSemaphore freeSemaphore;
+  CSemaphore filledSemaphore;
+  Bool csWasInitialized;
+  Bool csWasEntered;
+  CCriticalSection cs;
+  UInt32 numProcessedBlocks;
+} CMtSync;
+
+typedef UInt32 * (*Mf_Mix_Matches)(void *p, UInt32 matchMinPos, UInt32 *distances);
+
+/* kMtCacheLineDummy must be >= size_of_CPU_cache_line */
+#define kMtCacheLineDummy 128
+
+typedef void (*Mf_GetHeads)(const Byte *buffer, UInt32 pos,
+  UInt32 *hash, UInt32 hashMask, UInt32 *heads, UInt32 numHeads);
+
+typedef struct _CMatchFinderMt
+{
+  /* LZ */
+  const Byte *pointerToCurPos;
+  UInt32 *btBuf;
+  UInt32 btBufPos;
+  UInt32 btBufPosLimit;
+  UInt32 lzPos;
+  UInt32 btNumAvailBytes;
+
+  UInt32 *hash;
+  UInt32 fixedHashSize;
+  UInt32 historySize;
+
+  Mf_Mix_Matches MixMatchesFunc;
+  
+  /* LZ + BT */
+  CMtSync btSync;
+  Byte btDummy[kMtCacheLineDummy];
+
+  /* BT */
+  UInt32 *hashBuf;
+  UInt32 hashBufPos;
+  UInt32 hashBufPosLimit;
+  UInt32 hashNumAvail;
+
+  CLzRef *son;
+  UInt32 matchMaxLen;
+  UInt32 numHashBytes;
+  UInt32 pos;
+  Byte *buffer;
+  UInt32 cyclicBufferPos;
+  UInt32 cyclicBufferSize; /* it must be historySize + 1 */
+  UInt32 cutValue;
+
+  /* BT + Hash */
+  CMtSync hashSync;
+  /* Byte hashDummy[kMtCacheLineDummy]; */
+  
+  /* Hash */
+  Mf_GetHeads GetHeadsFunc;
+  CMatchFinder *MatchFinder;
+} CMatchFinderMt;
+
+void MatchFinderMt_Construct(CMatchFinderMt *p);
+void MatchFinderMt_Destruct(CMatchFinderMt *p, ISzAlloc *alloc);
+HRes MatchFinderMt_Create(CMatchFinderMt *p, UInt32 historySize, UInt32 keepAddBufferBefore, 
+    UInt32 matchMaxLen, UInt32 keepAddBufferAfter, ISzAlloc *alloc);
+void MatchFinderMt_CreateVTable(CMatchFinderMt *p, IMatchFinder *vTable);
+void MatchFinderMt_ReleaseStream(CMatchFinderMt *p);
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/misc/libphysfs/lzma/C/Compress/Lzma/LzmaDecode.c	Mon Apr 10 12:06:43 2017 -0400
@@ -0,0 +1,584 @@
+/*
+  LzmaDecode.c
+  LZMA Decoder (optimized for Speed version)
+  
+  LZMA SDK 4.40 Copyright (c) 1999-2006 Igor Pavlov (2006-05-01)
+  http://www.7-zip.org/
+
+  LZMA SDK is licensed under two licenses:
+  1) GNU Lesser General Public License (GNU LGPL)
+  2) Common Public License (CPL)
+  It means that you can select one of these two licenses and 
+  follow rules of that license.
+
+  SPECIAL EXCEPTION:
+  Igor Pavlov, as the author of this Code, expressly permits you to 
+  statically or dynamically link your Code (or bind by name) to the 
+  interfaces of this file without subjecting your linked Code to the 
+  terms of the CPL or GNU LGPL. Any modifications or additions 
+  to this file, however, are subject to the LGPL or CPL terms.
+*/
+
+#include "LzmaDecode.h"
+
+#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_INIT2 Code = 0; Range = 0xFFFFFFFF; \
+  { int i; for(i = 0; i < 5; i++) { RC_TEST; Code = (Code << 8) | RC_READ_BYTE; }}
+
+#ifdef _LZMA_IN_CB
+
+#define RC_TEST { if (Buffer == BufferLim) \
+  { SizeT size; int result = InCallback->Read(InCallback, &Buffer, &size); if (result != LZMA_RESULT_OK) return result; \
+  BufferLim = Buffer + size; if (size == 0) return LZMA_RESULT_DATA_ERROR; }}
+
+#define RC_INIT Buffer = BufferLim = 0; RC_INIT2
+
+#else
+
+#define RC_TEST { if (Buffer == BufferLim) return LZMA_RESULT_DATA_ERROR; }
+
+#define RC_INIT(buffer, bufferSize) Buffer = buffer; BufferLim = buffer + bufferSize; RC_INIT2
+ 
+#endif
+
+#define RC_NORMALIZE if (Range < kTopValue) { RC_TEST; Range <<= 8; Code = (Code << 8) | RC_READ_BYTE; }
+
+#define IfBit0(p) RC_NORMALIZE; bound = (Range >> kNumBitModelTotalBits) * *(p); if (Code < bound)
+#define UpdateBit0(p) Range = bound; *(p) += (kBitModelTotal - *(p)) >> kNumMoveBits;
+#define UpdateBit1(p) Range -= bound; Code -= bound; *(p) -= (*(p)) >> kNumMoveBits;
+
+#define RC_GET_BIT2(p, mi, A0, A1) IfBit0(p) \
+  { UpdateBit0(p); mi <<= 1; A0; } else \
+  { UpdateBit1(p); mi = (mi + mi) + 1; A1; } 
+  
+#define RC_GET_BIT(p, mi) RC_GET_BIT2(p, mi, ; , ;)               
+
+#define RangeDecoderBitTreeDecode(probs, numLevels, res) \
+  { int i = numLevels; res = 1; \
+  do { CProb *p = probs + res; RC_GET_BIT(p, res) } while(--i != 0); \
+  res -= (1 << numLevels); }
+
+
+#define kNumPosBitsMax 4
+#define kNumPosStatesMax (1 << kNumPosBitsMax)
+
+#define kLenNumLowBits 3
+#define kLenNumLowSymbols (1 << kLenNumLowBits)
+#define kLenNumMidBits 3
+#define kLenNumMidSymbols (1 << kLenNumMidBits)
+#define kLenNumHighBits 8
+#define kLenNumHighSymbols (1 << kLenNumHighBits)
+
+#define LenChoice 0
+#define LenChoice2 (LenChoice + 1)
+#define LenLow (LenChoice2 + 1)
+#define LenMid (LenLow + (kNumPosStatesMax << kLenNumLowBits))
+#define LenHigh (LenMid + (kNumPosStatesMax << kLenNumMidBits))
+#define kNumLenProbs (LenHigh + kLenNumHighSymbols) 
+
+
+#define kNumStates 12
+#define kNumLitStates 7
+
+#define kStartPosModelIndex 4
+#define kEndPosModelIndex 14
+#define kNumFullDistances (1 << (kEndPosModelIndex >> 1))
+
+#define kNumPosSlotBits 6
+#define kNumLenToPosStates 4
+
+#define kNumAlignBits 4
+#define kAlignTableSize (1 << kNumAlignBits)
+
+#define kMatchMinLen 2
+
+#define IsMatch 0
+#define IsRep (IsMatch + (kNumStates << kNumPosBitsMax))
+#define IsRepG0 (IsRep + kNumStates)
+#define IsRepG1 (IsRepG0 + kNumStates)
+#define IsRepG2 (IsRepG1 + kNumStates)
+#define IsRep0Long (IsRepG2 + kNumStates)
+#define PosSlot (IsRep0Long + (kNumStates << kNumPosBitsMax))
+#define SpecPos (PosSlot + (kNumLenToPosStates << kNumPosSlotBits))
+#define Align (SpecPos + kNumFullDistances - kEndPosModelIndex)
+#define LenCoder (Align + kAlignTableSize)
+#define RepLenCoder (LenCoder + kNumLenProbs)
+#define Literal (RepLenCoder + kNumLenProbs)
+
+#if Literal != LZMA_BASE_SIZE
+StopCompilingDueBUG
+#endif
+
+int LzmaDecodeProperties(CLzmaProperties *propsRes, const unsigned char *propsData, int size)
+{
+  unsigned char prop0;
+  if (size < LZMA_PROPERTIES_SIZE)
+    return LZMA_RESULT_DATA_ERROR;
+  prop0 = propsData[0];
+  if (prop0 >= (9 * 5 * 5))
+    return LZMA_RESULT_DATA_ERROR;
+  {
+    for (propsRes->pb = 0; prop0 >= (9 * 5); propsRes->pb++, prop0 -= (9 * 5));
+    for (propsRes->lp = 0; prop0 >= 9; propsRes->lp++, prop0 -= 9);
+    propsRes->lc = prop0;
+    /*
+    unsigned char remainder = (unsigned char)(prop0 / 9);
+    propsRes->lc = prop0 % 9;
+    propsRes->pb = remainder / 5;
+    propsRes->lp = remainder % 5;
+    */
+  }
+
+  #ifdef _LZMA_OUT_READ
+  {
+    int i;
+    propsRes->DictionarySize = 0;
+    for (i = 0; i < 4; i++)
+      propsRes->DictionarySize += (UInt32)(propsData[1 + i]) << (i * 8);
+    if (propsRes->DictionarySize == 0)
+      propsRes->DictionarySize = 1;
+  }
+  #endif
+  return LZMA_RESULT_OK;
+}
+
+#define kLzmaStreamWasFinishedId (-1)
+
+int LzmaDecode(CLzmaDecoderState *vs,
+    #ifdef _LZMA_IN_CB
+    ILzmaInCallback *InCallback,
+    #else
+    const unsigned char *inStream, SizeT inSize, SizeT *inSizeProcessed,
+    #endif
+    unsigned char *outStream, SizeT outSize, SizeT *outSizeProcessed)
+{
+  CProb *p = vs->Probs;
+  SizeT nowPos = 0;
+  Byte previousByte = 0;
+  UInt32 posStateMask = (1 << (vs->Properties.pb)) - 1;
+  UInt32 literalPosMask = (1 << (vs->Properties.lp)) - 1;
+  int lc = vs->Properties.lc;
+
+  #ifdef _LZMA_OUT_READ
+  
+  UInt32 Range = vs->Range;
+  UInt32 Code = vs->Code;
+  #ifdef _LZMA_IN_CB
+  const Byte *Buffer = vs->Buffer;
+  const Byte *BufferLim = vs->BufferLim;
+  #else
+  const Byte *Buffer = inStream;
+  const Byte *BufferLim = inStream + inSize;
+  #endif
+  int state = vs->State;
+  UInt32 rep0 = vs->Reps[0], rep1 = vs->Reps[1], rep2 = vs->Reps[2], rep3 = vs->Reps[3];
+  int len = vs->RemainLen;
+  UInt32 globalPos = vs->GlobalPos;
+  UInt32 distanceLimit = vs->DistanceLimit;
+
+  Byte *dictionary = vs->Dictionary;
+  UInt32 dictionarySize = vs->Properties.DictionarySize;
+  UInt32 dictionaryPos = vs->DictionaryPos;
+
+  Byte tempDictionary[4];
+
+  #ifndef _LZMA_IN_CB
+  *inSizeProcessed = 0;
+  #endif
+  *outSizeProcessed = 0;
+  if (len == kLzmaStreamWasFinishedId)
+    return LZMA_RESULT_OK;
+
+  if (dictionarySize == 0)
+  {
+    dictionary = tempDictionary;
+    dictionarySize = 1;
+    tempDictionary[0] = vs->TempDictionary[0];
+  }
+
+  if (len == kLzmaNeedInitId)
+  {
+    {
+      UInt32 numProbs = Literal + ((UInt32)LZMA_LIT_SIZE << (lc + vs->Properties.lp));
+      UInt32 i;
+      for (i = 0; i < numProbs; i++)
+        p[i] = kBitModelTotal >> 1; 
+      rep0 = rep1 = rep2 = rep3 = 1;
+      state = 0;
+      globalPos = 0;
+      distanceLimit = 0;
+      dictionaryPos = 0;
+      dictionary[dictionarySize - 1] = 0;
+      #ifdef _LZMA_IN_CB
+      RC_INIT;
+      #else
+      RC_INIT(inStream, inSize);
+      #endif
+    }
+    len = 0;
+  }
+  while(len != 0 && nowPos < outSize)
+  {
+    UInt32 pos = dictionaryPos - rep0;
+    if (pos >= dictionarySize)
+      pos += dictionarySize;
+    outStream[nowPos++] = dictionary[dictionaryPos] = dictionary[pos];
+    if (++dictionaryPos == dictionarySize)
+      dictionaryPos = 0;
+    len--;
+  }
+  if (dictionaryPos == 0)
+    previousByte = dictionary[dictionarySize - 1];
+  else
+    previousByte = dictionary[dictionaryPos - 1];
+
+  #else /* if !_LZMA_OUT_READ */
+
+  int state = 0;
+  UInt32 rep0 = 1, rep1 = 1, rep2 = 1, rep3 = 1;
+  int len = 0;
+  const Byte *Buffer;
+  const Byte *BufferLim;
+  UInt32 Range;
+  UInt32 Code;
+
+  #ifndef _LZMA_IN_CB
+  *inSizeProcessed = 0;
+  #endif
+  *outSizeProcessed = 0;
+
+  {
+    UInt32 i;
+    UInt32 numProbs = Literal + ((UInt32)LZMA_LIT_SIZE << (lc + vs->Properties.lp));
+    for (i = 0; i < numProbs; i++)
+      p[i] = kBitModelTotal >> 1;
+  }
+  
+  #ifdef _LZMA_IN_CB
+  RC_INIT;
+  #else
+  RC_INIT(inStream, inSize);
+  #endif
+
+  #endif /* _LZMA_OUT_READ */
+
+  while(nowPos < outSize)
+  {
+    CProb *prob;
+    UInt32 bound;
+    int posState = (int)(
+        (nowPos 
+        #ifdef _LZMA_OUT_READ
+        + globalPos
+        #endif
+        )
+        & posStateMask);
+
+    prob = p + IsMatch + (state << kNumPosBitsMax) + posState;
+    IfBit0(prob)
+    {
+      int symbol = 1;
+      UpdateBit0(prob)
+      prob = p + Literal + (LZMA_LIT_SIZE * 
+        (((
+        (nowPos 
+        #ifdef _LZMA_OUT_READ
+        + globalPos
+        #endif
+        )
+        & literalPosMask) << lc) + (previousByte >> (8 - lc))));
+
+      if (state >= kNumLitStates)
+      {
+        int matchByte;
+        #ifdef _LZMA_OUT_READ
+        UInt32 pos = dictionaryPos - rep0;
+        if (pos >= dictionarySize)
+          pos += dictionarySize;
+        matchByte = dictionary[pos];
+        #else
+        matchByte = outStream[nowPos - rep0];
+        #endif
+        do
+        {
+          int bit;
+          CProb *probLit;
+          matchByte <<= 1;
+          bit = (matchByte & 0x100);
+          probLit = prob + 0x100 + bit + symbol;
+          RC_GET_BIT2(probLit, symbol, if (bit != 0) break, if (bit == 0) break)
+        }
+        while (symbol < 0x100);
+      }
+      while (symbol < 0x100)
+      {
+        CProb *probLit = prob + symbol;
+        RC_GET_BIT(probLit, symbol)
+      }
+      previousByte = (Byte)symbol;
+
+      outStream[nowPos++] = previousByte;
+      #ifdef _LZMA_OUT_READ
+      if (distanceLimit < dictionarySize)
+        distanceLimit++;
+
+      dictionary[dictionaryPos] = previousByte;
+      if (++dictionaryPos == dictionarySize)
+        dictionaryPos = 0;
+      #endif
+      if (state < 4) state = 0;
+      else if (state < 10) state -= 3;
+      else state -= 6;
+    }
+    else             
+    {
+      UpdateBit1(prob);
+      prob = p + IsRep + state;
+      IfBit0(prob)
+      {
+        UpdateBit0(prob);
+        rep3 = rep2;
+        rep2 = rep1;
+        rep1 = rep0;
+        state = state < kNumLitStates ? 0 : 3;
+        prob = p + LenCoder;
+      }
+      else
+      {
+        UpdateBit1(prob);
+        prob = p + IsRepG0 + state;
+        IfBit0(prob)
+        {
+          UpdateBit0(prob);
+          prob = p + IsRep0Long + (state << kNumPosBitsMax) + posState;
+          IfBit0(prob)
+          {
+            #ifdef _LZMA_OUT_READ
+            UInt32 pos;
+            #endif
+            UpdateBit0(prob);
+            
+            #ifdef _LZMA_OUT_READ
+            if (distanceLimit == 0)
+            #else
+            if (nowPos == 0)
+            #endif
+              return LZMA_RESULT_DATA_ERROR;
+            
+            state = state < kNumLitStates ? 9 : 11;
+            #ifdef _LZMA_OUT_READ
+            pos = dictionaryPos - rep0;
+            if (pos >= dictionarySize)
+              pos += dictionarySize;
+            previousByte = dictionary[pos];
+            dictionary[dictionaryPos] = previousByte;
+            if (++dictionaryPos == dictionarySize)
+              dictionaryPos = 0;
+            #else
+            previousByte = outStream[nowPos - rep0];
+            #endif
+            outStream[nowPos++] = previousByte;
+            #ifdef _LZMA_OUT_READ
+            if (distanceLimit < dictionarySize)
+              distanceLimit++;
+            #endif
+
+            continue;
+          }
+          else
+          {
+            UpdateBit1(prob);
+          }
+        }
+        else
+        {
+          UInt32 distance;
+          UpdateBit1(prob);
+          prob = p + IsRepG1 + state;
+          IfBit0(prob)
+          {
+            UpdateBit0(prob);
+            distance = rep1;
+          }
+          else 
+          {
+            UpdateBit1(prob);
+            prob = p + IsRepG2 + state;
+            IfBit0(prob)
+            {
+              UpdateBit0(prob);
+              distance = rep2;
+            }
+            else
+            {
+              UpdateBit1(prob);
+              distance = rep3;
+              rep3 = rep2;
+            }
+            rep2 = rep1;
+          }
+          rep1 = rep0;
+          rep0 = distance;
+        }
+        state = state < kNumLitStates ? 8 : 11;
+        prob = p + RepLenCoder;
+      }
+      {
+        int numBits, offset;
+        CProb *probLen = prob + LenChoice;
+        IfBit0(probLen)
+        {
+          UpdateBit0(probLen);
+          probLen = prob + LenLow + (posState << kLenNumLowBits);
+          offset = 0;
+          numBits = kLenNumLowBits;
+        }
+        else
+        {
+          UpdateBit1(probLen);
+          probLen = prob + LenChoice2;
+          IfBit0(probLen)
+          {
+            UpdateBit0(probLen);
+            probLen = prob + LenMid + (posState << kLenNumMidBits);
+            offset = kLenNumLowSymbols;
+            numBits = kLenNumMidBits;
+          }
+          else
+          {
+            UpdateBit1(probLen);
+            probLen = prob + LenHigh;
+            offset = kLenNumLowSymbols + kLenNumMidSymbols;
+            numBits = kLenNumHighBits;
+          }
+        }
+        RangeDecoderBitTreeDecode(probLen, numBits, len);
+        len += offset;
+      }
+
+      if (state < 4)
+      {
+        int posSlot;
+        state += kNumLitStates;
+        prob = p + PosSlot +
+            ((len < kNumLenToPosStates ? len : kNumLenToPosStates - 1) << 
+            kNumPosSlotBits);
+        RangeDecoderBitTreeDecode(prob, kNumPosSlotBits, posSlot);
+        if (posSlot >= kStartPosModelIndex)
+        {
+          int numDirectBits = ((posSlot >> 1) - 1);
+          rep0 = (2 | ((UInt32)posSlot & 1));
+          if (posSlot < kEndPosModelIndex)
+          {
+            rep0 <<= numDirectBits;
+            prob = p + SpecPos + rep0 - posSlot - 1;
+          }
+          else
+          {
+            numDirectBits -= kNumAlignBits;
+            do
+            {
+              RC_NORMALIZE
+              Range >>= 1;
+              rep0 <<= 1;
+              if (Code >= Range)
+              {
+                Code -= Range;
+                rep0 |= 1;
+              }
+            }
+            while (--numDirectBits != 0);
+            prob = p + Align;
+            rep0 <<= kNumAlignBits;
+            numDirectBits = kNumAlignBits;
+          }
+          {
+            int i = 1;
+            int mi = 1;
+            do
+            {
+              CProb *prob3 = prob + mi;
+              RC_GET_BIT2(prob3, mi, ; , rep0 |= i);
+              i <<= 1;
+            }
+            while(--numDirectBits != 0);
+          }
+        }
+        else
+          rep0 = posSlot;
+        if (++rep0 == (UInt32)(0))
+        {
+          /* it's for stream version */
+          len = kLzmaStreamWasFinishedId;
+          break;
+        }
+      }
+
+      len += kMatchMinLen;
+      #ifdef _LZMA_OUT_READ
+      if (rep0 > distanceLimit) 
+      #else
+      if (rep0 > nowPos)
+      #endif
+        return LZMA_RESULT_DATA_ERROR;
+
+      #ifdef _LZMA_OUT_READ
+      if (dictionarySize - distanceLimit > (UInt32)len)
+        distanceLimit += len;
+      else
+        distanceLimit = dictionarySize;
+      #endif
+
+      do
+      {
+        #ifdef _LZMA_OUT_READ
+        UInt32 pos = dictionaryPos - rep0;
+        if (pos >= dictionarySize)
+          pos += dictionarySize;
+        previousByte = dictionary[pos];
+        dictionary[dictionaryPos] = previousByte;
+        if (++dictionaryPos == dictionarySize)
+          dictionaryPos = 0;
+        #else
+        previousByte = outStream[nowPos - rep0];
+        #endif
+        len--;
+        outStream[nowPos++] = previousByte;
+      }
+      while(len != 0 && nowPos < outSize);
+    }
+  }
+  RC_NORMALIZE;
+
+  #ifdef _LZMA_OUT_READ
+  vs->Range = Range;
+  vs->Code = Code;
+  vs->DictionaryPos = dictionaryPos;
+  vs->GlobalPos = globalPos + (UInt32)nowPos;
+  vs->DistanceLimit = distanceLimit;
+  vs->Reps[0] = rep0;
+  vs->Reps[1] = rep1;
+  vs->Reps[2] = rep2;
+  vs->Reps[3] = rep3;
+  vs->State = state;
+  vs->RemainLen = len;
+  vs->TempDictionary[0] = tempDictionary[0];
+  #endif
+
+  #ifdef _LZMA_IN_CB
+  vs->Buffer = Buffer;
+  vs->BufferLim = BufferLim;
+  #else
+  *inSizeProcessed = (SizeT)(Buffer - inStream);
+  #endif
+  *outSizeProcessed = nowPos;
+  return LZMA_RESULT_OK;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/misc/libphysfs/lzma/C/Compress/Lzma/LzmaDecode.h	Mon Apr 10 12:06:43 2017 -0400
@@ -0,0 +1,113 @@
+/* 
+  LzmaDecode.h
+  LZMA Decoder interface
+
+  LZMA SDK 4.40 Copyright (c) 1999-2006 Igor Pavlov (2006-05-01)
+  http://www.7-zip.org/
+
+  LZMA SDK is licensed under two licenses:
+  1) GNU Lesser General Public License (GNU LGPL)
+  2) Common Public License (CPL)
+  It means that you can select one of these two licenses and 
+  follow rules of that license.
+
+  SPECIAL EXCEPTION:
+  Igor Pavlov, as the author of this code, expressly permits you to 
+  statically or dynamically link your code (or bind by name) to the 
+  interfaces of this file without subjecting your linked code to the 
+  terms of the CPL or GNU LGPL. Any modifications or additions 
+  to this file, however, are subject to the LGPL or CPL terms.
+*/
+
+#ifndef __LZMADECODE_H
+#define __LZMADECODE_H
+
+#include "LzmaTypes.h"
+
+/* #define _LZMA_IN_CB */
+/* Use callback for input data */
+
+/* #define _LZMA_OUT_READ */
+/* Use read function for output data */
+
+/* #define _LZMA_PROB32 */
+/* It can increase speed on some 32-bit CPUs, 
+   but memory usage will be doubled in that case */
+
+/* #define _LZMA_LOC_OPT */
+/* Enable local speed optimizations inside code */
+
+#ifdef _LZMA_PROB32
+#define CProb UInt32
+#else
+#define CProb UInt16
+#endif
+
+#define LZMA_RESULT_OK 0
+#define LZMA_RESULT_DATA_ERROR 1
+
+#ifdef _LZMA_IN_CB
+typedef struct _ILzmaInCallback
+{
+  int (*Read)(void *object, const unsigned char **buffer, SizeT *bufferSize);
+} ILzmaInCallback;
+#endif
+
+#define LZMA_BASE_SIZE 1846
+#define LZMA_LIT_SIZE 768
+
+#define LZMA_PROPERTIES_SIZE 5
+
+typedef struct _CLzmaProperties
+{
+  int lc;
+  int lp;
+  int pb;
+  #ifdef _LZMA_OUT_READ
+  UInt32 DictionarySize;
+  #endif
+}CLzmaProperties;
+
+int LzmaDecodeProperties(CLzmaProperties *propsRes, const unsigned char *propsData, int size);
+
+#define LzmaGetNumProbs(Properties) (LZMA_BASE_SIZE + (LZMA_LIT_SIZE << ((Properties)->lc + (Properties)->lp)))
+
+#define kLzmaNeedInitId (-2)
+
+typedef struct _CLzmaDecoderState
+{
+  CLzmaProperties Properties;
+  CProb *Probs;
+
+  #ifdef _LZMA_IN_CB
+  const unsigned char *Buffer;
+  const unsigned char *BufferLim;
+  #endif
+
+  #ifdef _LZMA_OUT_READ
+  unsigned char *Dictionary;
+  UInt32 Range;
+  UInt32 Code;
+  UInt32 DictionaryPos;
+  UInt32 GlobalPos;
+  UInt32 DistanceLimit;
+  UInt32 Reps[4];
+  int State;
+  int RemainLen;
+  unsigned char TempDictionary[4];
+  #endif
+} CLzmaDecoderState;
+
+#ifdef _LZMA_OUT_READ
+#define LzmaDecoderInit(vs) { (vs)->RemainLen = kLzmaNeedInitId; }
+#endif
+
+int LzmaDecode(CLzmaDecoderState *vs,
+    #ifdef _LZMA_IN_CB
+    ILzmaInCallback *inCallback,
+    #else
+    const unsigned char *inStream, SizeT inSize, SizeT *inSizeProcessed,
+    #endif
+    unsigned char *outStream, SizeT outSize, SizeT *outSizeProcessed);
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/misc/libphysfs/lzma/C/Compress/Lzma/LzmaDecodeSize.c	Mon Apr 10 12:06:43 2017 -0400
@@ -0,0 +1,712 @@
+/*
+  LzmaDecodeSize.c
+  LZMA Decoder (optimized for Size version)
+  
+  LZMA SDK 4.40 Copyright (c) 1999-2006 Igor Pavlov (2006-05-01)
+  http://www.7-zip.org/
+
+  LZMA SDK is licensed under two licenses:
+  1) GNU Lesser General Public License (GNU LGPL)
+  2) Common Public License (CPL)
+  It means that you can select one of these two licenses and 
+  follow rules of that license.
+
+  SPECIAL EXCEPTION:
+  Igor Pavlov, as the author of this code, expressly permits you to 
+  statically or dynamically link your code (or bind by name) to the 
+  interfaces of this file without subjecting your linked code to the 
+  terms of the CPL or GNU LGPL. Any modifications or additions 
+  to this file, however, are subject to the LGPL or CPL terms.
+*/
+
+#include "LzmaDecode.h"
+
+#define kNumTopBits 24
+#define kTopValue ((UInt32)1 << kNumTopBits)
+
+#define kNumBitModelTotalBits 11
+#define kBitModelTotal (1 << kNumBitModelTotalBits)
+#define kNumMoveBits 5
+
+typedef struct _CRangeDecoder
+{
+  const Byte *Buffer;
+  const Byte *BufferLim;
+  UInt32 Range;
+  UInt32 Code;
+  #ifdef _LZMA_IN_CB
+  ILzmaInCallback *InCallback;
+  int Result;
+  #endif
+  int ExtraBytes;
+} CRangeDecoder;
+
+Byte RangeDecoderReadByte(CRangeDecoder *rd)
+{
+  if (rd->Buffer == rd->BufferLim)
+  {
+    #ifdef _LZMA_IN_CB
+    SizeT size;
+    rd->Result = rd->InCallback->Read(rd->InCallback, &rd->Buffer, &size);
+    rd->BufferLim = rd->Buffer + size;
+    if (size == 0)
+    #endif
+    {
+      rd->ExtraBytes = 1;
+      return 0xFF;
+    }
+  }
+  return (*rd->Buffer++);
+}
+
+/* #define ReadByte (*rd->Buffer++) */
+#define ReadByte (RangeDecoderReadByte(rd))
+
+void RangeDecoderInit(CRangeDecoder *rd
+  #ifndef _LZMA_IN_CB
+    , const Byte *stream, SizeT bufferSize
+  #endif
+    )
+{
+  int i;
+  #ifdef _LZMA_IN_CB
+  rd->Buffer = rd->BufferLim = 0;
+  #else
+  rd->Buffer = stream;
+  rd->BufferLim = stream + bufferSize;
+  #endif
+  rd->ExtraBytes = 0;
+  rd->Code = 0;
+  rd->Range = (0xFFFFFFFF);
+  for(i = 0; i < 5; i++)
+    rd->Code = (rd->Code << 8) | ReadByte;
+}
+
+#define RC_INIT_VAR UInt32 range = rd->Range; UInt32 code = rd->Code;        
+#define RC_FLUSH_VAR rd->Range = range; rd->Code = code;
+#define RC_NORMALIZE if (range < kTopValue) { range <<= 8; code = (code << 8) | ReadByte; }
+
+UInt32 RangeDecoderDecodeDirectBits(CRangeDecoder *rd, int numTotalBits)
+{
+  RC_INIT_VAR
+  UInt32 result = 0;
+  int i;
+  for (i = numTotalBits; i != 0; i--)
+  {
+    /* UInt32 t; */
+    range >>= 1;
+
+    result <<= 1;
+    if (code >= range)
+    {
+      code -= range;
+      result |= 1;
+    }
+    /*
+    t = (code - range) >> 31;
+    t &= 1;
+    code -= range & (t - 1);
+    result = (result + result) | (1 - t);
+    */
+    RC_NORMALIZE
+  }
+  RC_FLUSH_VAR
+  return result;
+}
+
+int RangeDecoderBitDecode(CProb *prob, CRangeDecoder *rd)
+{
+  UInt32 bound = (rd->Range >> kNumBitModelTotalBits) * *prob;
+  if (rd->Code < bound)
+  {
+    rd->Range = bound;
+    *prob += (kBitModelTotal - *prob) >> kNumMoveBits;
+    if (rd->Range < kTopValue)
+    {
+      rd->Code = (rd->Code << 8) | ReadByte;
+      rd->Range <<= 8;
+    }
+    return 0;
+  }
+  else
+  {
+    rd->Range -= bound;
+    rd->Code -= bound;
+    *prob -= (*prob) >> kNumMoveBits;
+    if (rd->Range < kTopValue)
+    {
+      rd->Code = (rd->Code << 8) | ReadByte;
+      rd->Range <<= 8;
+    }
+    return 1;
+  }
+}
+
+#define RC_GET_BIT2(prob, mi, A0, A1) \
+  UInt32 bound = (range >> kNumBitModelTotalBits) * *prob; \
+  if (code < bound) \
+    { A0; range = bound; *prob += (kBitModelTotal - *prob) >> kNumMoveBits; mi <<= 1; } \
+  else \
+    { A1; range -= bound; code -= bound; *prob -= (*prob) >> kNumMoveBits; mi = (mi + mi) + 1; } \
+  RC_NORMALIZE
+
+#define RC_GET_BIT(prob, mi) RC_GET_BIT2(prob, mi, ; , ;)               
+
+int RangeDecoderBitTreeDecode(CProb *probs, int numLevels, CRangeDecoder *rd)
+{
+  int mi = 1;
+  int i;
+  #ifdef _LZMA_LOC_OPT
+  RC_INIT_VAR
+  #endif
+  for(i = numLevels; i != 0; i--)
+  {
+    #ifdef _LZMA_LOC_OPT
+    CProb *prob = probs + mi;
+    RC_GET_BIT(prob, mi)
+    #else
+    mi = (mi + mi) + RangeDecoderBitDecode(probs + mi, rd);
+    #endif
+  }
+  #ifdef _LZMA_LOC_OPT
+  RC_FLUSH_VAR
+  #endif
+  return mi - (1 << numLevels);
+}
+
+int RangeDecoderReverseBitTreeDecode(CProb *probs, int numLevels, CRangeDecoder *rd)
+{
+  int mi = 1;
+  int i;
+  int symbol = 0;
+  #ifdef _LZMA_LOC_OPT
+  RC_INIT_VAR
+  #endif
+  for(i = 0; i < numLevels; i++)
+  {
+    #ifdef _LZMA_LOC_OPT
+    CProb *prob = probs + mi;
+    RC_GET_BIT2(prob, mi, ; , symbol |= (1 << i))
+    #else
+    int bit = RangeDecoderBitDecode(probs + mi, rd);
+    mi = mi + mi + bit;
+    symbol |= (bit << i);
+    #endif
+  }
+  #ifdef _LZMA_LOC_OPT
+  RC_FLUSH_VAR
+  #endif
+  return symbol;
+}
+
+Byte LzmaLiteralDecode(CProb *probs, CRangeDecoder *rd)
+{ 
+  int symbol = 1;
+  #ifdef _LZMA_LOC_OPT
+  RC_INIT_VAR
+  #endif
+  do
+  {
+    #ifdef _LZMA_LOC_OPT
+    CProb *prob = probs + symbol;
+    RC_GET_BIT(prob, symbol)
+    #else
+    symbol = (symbol + symbol) | RangeDecoderBitDecode(probs + symbol, rd);
+    #endif
+  }
+  while (symbol < 0x100);
+  #ifdef _LZMA_LOC_OPT
+  RC_FLUSH_VAR
+  #endif
+  return symbol;
+}
+
+Byte LzmaLiteralDecodeMatch(CProb *probs, CRangeDecoder *rd, Byte matchByte)
+{ 
+  int symbol = 1;
+  #ifdef _LZMA_LOC_OPT
+  RC_INIT_VAR
+  #endif
+  do
+  {
+    int bit;
+    int matchBit = (matchByte >> 7) & 1;
+    matchByte <<= 1;
+    #ifdef _LZMA_LOC_OPT
+    {
+      CProb *prob = probs + 0x100 + (matchBit << 8) + symbol;
+      RC_GET_BIT2(prob, symbol, bit = 0, bit = 1)
+    }
+    #else
+    bit = RangeDecoderBitDecode(probs + 0x100 + (matchBit << 8) + symbol, rd);
+    symbol = (symbol << 1) | bit;
+    #endif
+    if (matchBit != bit)
+    {
+      while (symbol < 0x100)
+      {
+        #ifdef _LZMA_LOC_OPT
+        CProb *prob = probs + symbol;
+        RC_GET_BIT(prob, symbol)
+        #else
+        symbol = (symbol + symbol) | RangeDecoderBitDecode(probs + symbol, rd);
+        #endif
+      }
+      break;
+    }
+  }
+  while (symbol < 0x100);
+  #ifdef _LZMA_LOC_OPT
+  RC_FLUSH_VAR
+  #endif
+  return symbol;
+}
+
+#define kNumPosBitsMax 4
+#define kNumPosStatesMax (1 << kNumPosBitsMax)
+
+#define kLenNumLowBits 3
+#define kLenNumLowSymbols (1 << kLenNumLowBits)
+#define kLenNumMidBits 3
+#define kLenNumMidSymbols (1 << kLenNumMidBits)
+#define kLenNumHighBits 8
+#define kLenNumHighSymbols (1 << kLenNumHighBits)
+
+#define LenChoice 0
+#define LenChoice2 (LenChoice + 1)
+#define LenLow (LenChoice2 + 1)
+#define LenMid (LenLow + (kNumPosStatesMax << kLenNumLowBits))
+#define LenHigh (LenMid + (kNumPosStatesMax << kLenNumMidBits))
+#define kNumLenProbs (LenHigh + kLenNumHighSymbols) 
+
+int LzmaLenDecode(CProb *p, CRangeDecoder *rd, int posState)
+{
+  if(RangeDecoderBitDecode(p + LenChoice, rd) == 0)
+    return RangeDecoderBitTreeDecode(p + LenLow +
+        (posState << kLenNumLowBits), kLenNumLowBits, rd);
+  if(RangeDecoderBitDecode(p + LenChoice2, rd) == 0)
+    return kLenNumLowSymbols + RangeDecoderBitTreeDecode(p + LenMid +
+        (posState << kLenNumMidBits), kLenNumMidBits, rd);
+  return kLenNumLowSymbols + kLenNumMidSymbols + 
+      RangeDecoderBitTreeDecode(p + LenHigh, kLenNumHighBits, rd);
+}
+
+#define kNumStates 12
+#define kNumLitStates 7
+
+#define kStartPosModelIndex 4
+#define kEndPosModelIndex 14
+#define kNumFullDistances (1 << (kEndPosModelIndex >> 1))
+
+#define kNumPosSlotBits 6
+#define kNumLenToPosStates 4
+
+#define kNumAlignBits 4
+#define kAlignTableSize (1 << kNumAlignBits)
+
+#define kMatchMinLen 2
+
+#define IsMatch 0
+#define IsRep (IsMatch + (kNumStates << kNumPosBitsMax))
+#define IsRepG0 (IsRep + kNumStates)
+#define IsRepG1 (IsRepG0 + kNumStates)
+#define IsRepG2 (IsRepG1 + kNumStates)
+#define IsRep0Long (IsRepG2 + kNumStates)
+#define PosSlot (IsRep0Long + (kNumStates << kNumPosBitsMax))
+#define SpecPos (PosSlot + (kNumLenToPosStates << kNumPosSlotBits))
+#define Align (SpecPos + kNumFullDistances - kEndPosModelIndex)
+#define LenCoder (Align + kAlignTableSize)
+#define RepLenCoder (LenCoder + kNumLenProbs)
+#define Literal (RepLenCoder + kNumLenProbs)
+
+#if Literal != LZMA_BASE_SIZE
+StopCompilingDueBUG
+#endif
+
+int LzmaDecodeProperties(CLzmaProperties *propsRes, const unsigned char *propsData, int size)
+{
+  unsigned char prop0;
+  if (size < LZMA_PROPERTIES_SIZE)
+    return LZMA_RESULT_DATA_ERROR;
+  prop0 = propsData[0];
+  if (prop0 >= (9 * 5 * 5))
+    return LZMA_RESULT_DATA_ERROR;
+  {
+    for (propsRes->pb = 0; prop0 >= (9 * 5); propsRes->pb++, prop0 -= (9 * 5));
+    for (propsRes->lp = 0; prop0 >= 9; propsRes->lp++, prop0 -= 9);
+    propsRes->lc = prop0;
+    /*
+    unsigned char remainder = (unsigned char)(prop0 / 9);
+    propsRes->lc = prop0 % 9;
+    propsRes->pb = remainder / 5;
+    propsRes->lp = remainder % 5;
+    */
+  }
+
+  #ifdef _LZMA_OUT_READ
+  {
+    int i;
+    propsRes->DictionarySize = 0;
+    for (i = 0; i < 4; i++)
+      propsRes->DictionarySize += (UInt32)(propsData[1 + i]) << (i * 8);
+    if (propsRes->DictionarySize == 0)
+      propsRes->DictionarySize = 1;
+  }
+  #endif
+  return LZMA_RESULT_OK;
+}
+
+#define kLzmaStreamWasFinishedId (-1)
+
+int LzmaDecode(CLzmaDecoderState *vs,
+    #ifdef _LZMA_IN_CB
+    ILzmaInCallback *InCallback,
+    #else
+    const unsigned char *inStream, SizeT inSize, SizeT *inSizeProcessed,
+    #endif
+    unsigned char *outStream, SizeT outSize, SizeT *outSizeProcessed)
+{
+  CProb *p = vs->Probs;
+  SizeT nowPos = 0;
+  Byte previousByte = 0;
+  UInt32 posStateMask = (1 << (vs->Properties.pb)) - 1;
+  UInt32 literalPosMask = (1 << (vs->Properties.lp)) - 1;
+  int lc = vs->Properties.lc;
+  CRangeDecoder rd;
+
+  #ifdef _LZMA_OUT_READ
+  
+  int state = vs->State;
+  UInt32 rep0 = vs->Reps[0], rep1 = vs->Reps[1], rep2 = vs->Reps[2], rep3 = vs->Reps[3];
+  int len = vs->RemainLen;
+  UInt32 globalPos = vs->GlobalPos;
+  UInt32 distanceLimit = vs->DistanceLimit;
+
+  Byte *dictionary = vs->Dictionary;
+  UInt32 dictionarySize = vs->Properties.DictionarySize;
+  UInt32 dictionaryPos = vs->DictionaryPos;
+
+  Byte tempDictionary[4];
+
+  rd.Range = vs->Range;
+  rd.Code = vs->Code;
+  #ifdef _LZMA_IN_CB
+  rd.InCallback = InCallback;
+  rd.Buffer = vs->Buffer;
+  rd.BufferLim = vs->BufferLim;
+  #else
+  rd.Buffer = inStream;
+  rd.BufferLim = inStream + inSize;
+  #endif
+
+  #ifndef _LZMA_IN_CB
+  *inSizeProcessed = 0;
+  #endif
+  *outSizeProcessed = 0;
+  if (len == kLzmaStreamWasFinishedId)
+    return LZMA_RESULT_OK;
+
+  if (dictionarySize == 0)
+  {
+    dictionary = tempDictionary;
+    dictionarySize = 1;
+    tempDictionary[0] = vs->TempDictionary[0];
+  }
+
+  if (len == kLzmaNeedInitId)
+  {
+    {
+      UInt32 numProbs = Literal + ((UInt32)LZMA_LIT_SIZE << (lc + vs->Properties.lp));
+      UInt32 i;
+      for (i = 0; i < numProbs; i++)
+        p[i] = kBitModelTotal >> 1; 
+      rep0 = rep1 = rep2 = rep3 = 1;
+      state = 0;
+      globalPos = 0;
+      distanceLimit = 0;
+      dictionaryPos = 0;
+      dictionary[dictionarySize - 1] = 0;
+      RangeDecoderInit(&rd
+          #ifndef _LZMA_IN_CB
+          , inStream, inSize
+          #endif
+          );
+      #ifdef _LZMA_IN_CB
+      if (rd.Result != LZMA_RESULT_OK)
+        return rd.Result;
+      #endif
+      if (rd.ExtraBytes != 0)
+        return LZMA_RESULT_DATA_ERROR;
+    }
+    len = 0;
+  }
+  while(len != 0 && nowPos < outSize)
+  {
+    UInt32 pos = dictionaryPos - rep0;
+    if (pos >= dictionarySize)
+      pos += dictionarySize;
+    outStream[nowPos++] = dictionary[dictionaryPos] = dictionary[pos];
+    if (++dictionaryPos == dictionarySize)
+      dictionaryPos = 0;
+    len--;
+  }
+  if (dictionaryPos == 0)
+    previousByte = dictionary[dictionarySize - 1];
+  else
+    previousByte = dictionary[dictionaryPos - 1];
+
+  #ifdef _LZMA_IN_CB
+  rd.Result = LZMA_RESULT_OK;
+  #endif
+  rd.ExtraBytes = 0;
+
+  #else /* if !_LZMA_OUT_READ */
+
+  int state = 0;
+  UInt32 rep0 = 1, rep1 = 1, rep2 = 1, rep3 = 1;
+  int len = 0;
+
+  #ifndef _LZMA_IN_CB
+  *inSizeProcessed = 0;
+  #endif
+  *outSizeProcessed = 0;
+
+  {
+    UInt32 i;
+    UInt32 numProbs = Literal + ((UInt32)LZMA_LIT_SIZE << (lc + vs->Properties.lp));
+    for (i = 0; i < numProbs; i++)
+      p[i] = kBitModelTotal >> 1;
+  }
+  
+  #ifdef _LZMA_IN_CB
+  rd.InCallback = InCallback;
+  #endif
+  RangeDecoderInit(&rd
+      #ifndef _LZMA_IN_CB
+      , inStream, inSize
+      #endif
+      );
+
+  #ifdef _LZMA_IN_CB
+  if (rd.Result != LZMA_RESULT_OK)
+    return rd.Result;
+  #endif
+  if (rd.ExtraBytes != 0)
+    return LZMA_RESULT_DATA_ERROR;
+
+  #endif /* _LZMA_OUT_READ */
+
+
+  while(nowPos < outSize)
+  {
+    int posState = (int)(
+        (nowPos 
+        #ifdef _LZMA_OUT_READ
+        + globalPos
+        #endif
+        )
+        & posStateMask);
+    #ifdef _LZMA_IN_CB
+    if (rd.Result != LZMA_RESULT_OK)
+      return rd.Result;
+    #endif
+    if (rd.ExtraBytes != 0)
+      return LZMA_RESULT_DATA_ERROR;
+    if (RangeDecoderBitDecode(p + IsMatch + (state << kNumPosBitsMax) + posState, &rd) == 0)
+    {
+      CProb *probs = p + Literal + (LZMA_LIT_SIZE * 
+        (((
+        (nowPos 
+        #ifdef _LZMA_OUT_READ
+        + globalPos
+        #endif
+        )
+        & literalPosMask) << lc) + (previousByte >> (8 - lc))));
+
+      if (state >= kNumLitStates)
+      {
+        Byte matchByte;
+        #ifdef _LZMA_OUT_READ
+        UInt32 pos = dictionaryPos - rep0;
+        if (pos >= dictionarySize)
+          pos += dictionarySize;
+        matchByte = dictionary[pos];
+        #else
+        matchByte = outStream[nowPos - rep0];
+        #endif
+        previousByte = LzmaLiteralDecodeMatch(probs, &rd, matchByte);
+      }
+      else
+        previousByte = LzmaLiteralDecode(probs, &rd);
+      outStream[nowPos++] = previousByte;
+      #ifdef _LZMA_OUT_READ
+      if (distanceLimit < dictionarySize)
+        distanceLimit++;
+
+      dictionary[dictionaryPos] = previousByte;
+      if (++dictionaryPos == dictionarySize)
+        dictionaryPos = 0;
+      #endif
+      if (state < 4) state = 0;
+      else if (state < 10) state -= 3;
+      else state -= 6;
+    }
+    else             
+    {
+      if (RangeDecoderBitDecode(p + IsRep + state, &rd) == 1)
+      {
+        if (RangeDecoderBitDecode(p + IsRepG0 + state, &rd) == 0)
+        {
+          if (RangeDecoderBitDecode(p + IsRep0Long + (state << kNumPosBitsMax) + posState, &rd) == 0)
+          {
+            #ifdef _LZMA_OUT_READ
+            UInt32 pos;
+            #endif
+      
+            #ifdef _LZMA_OUT_READ
+            if (distanceLimit == 0)
+            #else
+            if (nowPos == 0)
+            #endif
+              return LZMA_RESULT_DATA_ERROR;
+
+            state = state < 7 ? 9 : 11;
+            #ifdef _LZMA_OUT_READ
+            pos = dictionaryPos - rep0;
+            if (pos >= dictionarySize)
+              pos += dictionarySize;
+            previousByte = dictionary[pos];
+            dictionary[dictionaryPos] = previousByte;
+            if (++dictionaryPos == dictionarySize)
+              dictionaryPos = 0;
+            #else
+            previousByte = outStream[nowPos - rep0];
+            #endif
+            outStream[nowPos++] = previousByte;
+
+            #ifdef _LZMA_OUT_READ
+            if (distanceLimit < dictionarySize)
+              distanceLimit++;
+            #endif
+            continue;
+          }
+        }
+        else
+        {
+          UInt32 distance;
+          if(RangeDecoderBitDecode(p + IsRepG1 + state, &rd) == 0)
+            distance = rep1;
+          else 
+          {
+            if(RangeDecoderBitDecode(p + IsRepG2 + state, &rd) == 0)
+              distance = rep2;
+            else
+            {
+              distance = rep3;
+              rep3 = rep2;
+            }
+            rep2 = rep1;
+          }
+          rep1 = rep0;
+          rep0 = distance;
+        }
+        len = LzmaLenDecode(p + RepLenCoder, &rd, posState);
+        state = state < 7 ? 8 : 11;
+      }
+      else
+      {
+        int posSlot;
+        rep3 = rep2;
+        rep2 = rep1;
+        rep1 = rep0;
+        state = state < 7 ? 7 : 10;
+        len = LzmaLenDecode(p + LenCoder, &rd, posState);
+        posSlot = RangeDecoderBitTreeDecode(p + PosSlot +
+            ((len < kNumLenToPosStates ? len : kNumLenToPosStates - 1) << 
+            kNumPosSlotBits), kNumPosSlotBits, &rd);
+        if (posSlot >= kStartPosModelIndex)
+        {
+          int numDirectBits = ((posSlot >> 1) - 1);
+          rep0 = ((2 | ((UInt32)posSlot & 1)) << numDirectBits);
+          if (posSlot < kEndPosModelIndex)
+          {
+            rep0 += RangeDecoderReverseBitTreeDecode(
+                p + SpecPos + rep0 - posSlot - 1, numDirectBits, &rd);
+          }
+          else
+          {
+            rep0 += RangeDecoderDecodeDirectBits(&rd, 
+                numDirectBits - kNumAlignBits) << kNumAlignBits;
+            rep0 += RangeDecoderReverseBitTreeDecode(p + Align, kNumAlignBits, &rd);
+          }
+        }
+        else
+          rep0 = posSlot;
+        if (++rep0 == (UInt32)(0))
+        {
+          /* it's for stream version */
+          len = kLzmaStreamWasFinishedId;
+          break;
+        }
+      }
+
+      len += kMatchMinLen;
+      #ifdef _LZMA_OUT_READ
+      if (rep0 > distanceLimit) 
+      #else
+      if (rep0 > nowPos)
+      #endif
+        return LZMA_RESULT_DATA_ERROR;
+
+      #ifdef _LZMA_OUT_READ
+      if (dictionarySize - distanceLimit > (UInt32)len)
+        distanceLimit += len;
+      else
+        distanceLimit = dictionarySize;
+      #endif
+
+      do
+      {
+        #ifdef _LZMA_OUT_READ
+        UInt32 pos = dictionaryPos - rep0;
+        if (pos >= dictionarySize)
+          pos += dictionarySize;
+        previousByte = dictionary[pos];
+        dictionary[dictionaryPos] = previousByte;
+        if (++dictionaryPos == dictionarySize)
+          dictionaryPos = 0;
+        #else
+        previousByte = outStream[nowPos - rep0];
+        #endif
+        len--;
+        outStream[nowPos++] = previousByte;
+      }
+      while(len != 0 && nowPos < outSize);
+    }
+  }
+
+
+  #ifdef _LZMA_OUT_READ
+  vs->Range = rd.Range;
+  vs->Code = rd.Code;
+  vs->DictionaryPos = dictionaryPos;
+  vs->GlobalPos = globalPos + (UInt32)nowPos;
+  vs->DistanceLimit = distanceLimit;
+  vs->Reps[0] = rep0;
+  vs->Reps[1] = rep1;
+  vs->Reps[2] = rep2;
+  vs->Reps[3] = rep3;
+  vs->State = state;
+  vs->RemainLen = len;
+  vs->TempDictionary[0] = tempDictionary[0];
+  #endif
+
+  #ifdef _LZMA_IN_CB
+  vs->Buffer = rd.Buffer;
+  vs->BufferLim = rd.BufferLim;
+  #else
+  *inSizeProcessed = (SizeT)(rd.Buffer - inStream);
+  #endif
+  *outSizeProcessed = nowPos;
+  return LZMA_RESULT_OK;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/misc/libphysfs/lzma/C/Compress/Lzma/LzmaStateDecode.c	Mon Apr 10 12:06:43 2017 -0400
@@ -0,0 +1,521 @@
+/*
+  LzmaStateDecode.c
+  LZMA Decoder (State version)
+  
+  LZMA SDK 4.40 Copyright (c) 1999-2006 Igor Pavlov (2006-05-01)
+  http://www.7-zip.org/
+
+  LZMA SDK is licensed under two licenses:
+  1) GNU Lesser General Public License (GNU LGPL)
+  2) Common Public License (CPL)
+  It means that you can select one of these two licenses and 
+  follow rules of that license.
+
+  SPECIAL EXCEPTION:
+  Igor Pavlov, as the author of this Code, expressly permits you to 
+  statically or dynamically link your Code (or bind by name) to the 
+  interfaces of this file without subjecting your linked Code to the 
+  terms of the CPL or GNU LGPL. Any modifications or additions 
+  to this file, however, are subject to the LGPL or CPL terms.
+*/
+
+#include "LzmaStateDecode.h"
+
+#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_INIT Code = 0; Range = 0xFFFFFFFF; \
+  { int i; for(i = 0; i < 5; i++) { Code = (Code << 8) | RC_READ_BYTE; }}
+
+#define RC_NORMALIZE if (Range < kTopValue) { Range <<= 8; Code = (Code << 8) | RC_READ_BYTE; }
+
+#define IfBit0(p) RC_NORMALIZE; bound = (Range >> kNumBitModelTotalBits) * *(p); if (Code < bound)
+#define UpdateBit0(p) Range = bound; *(p) += (kBitModelTotal - *(p)) >> kNumMoveBits;
+#define UpdateBit1(p) Range -= bound; Code -= bound; *(p) -= (*(p)) >> kNumMoveBits;
+
+#define RC_GET_BIT2(p, mi, A0, A1) IfBit0(p) \
+  { UpdateBit0(p); mi <<= 1; A0; } else \
+  { UpdateBit1(p); mi = (mi + mi) + 1; A1; } 
+  
+#define RC_GET_BIT(p, mi) RC_GET_BIT2(p, mi, ; , ;)               
+
+#define RangeDecoderBitTreeDecode(probs, numLevels, res) \
+  { int i = numLevels; res = 1; \
+  do { CProb *p = probs + res; RC_GET_BIT(p, res) } while(--i != 0); \
+  res -= (1 << numLevels); }
+
+
+#define kNumPosBitsMax 4
+#define kNumPosStatesMax (1 << kNumPosBitsMax)
+
+#define kLenNumLowBits 3
+#define kLenNumLowSymbols (1 << kLenNumLowBits)
+#define kLenNumMidBits 3
+#define kLenNumMidSymbols (1 << kLenNumMidBits)
+#define kLenNumHighBits 8
+#define kLenNumHighSymbols (1 << kLenNumHighBits)
+
+#define LenChoice 0
+#define LenChoice2 (LenChoice + 1)
+#define LenLow (LenChoice2 + 1)
+#define LenMid (LenLow + (kNumPosStatesMax << kLenNumLowBits))
+#define LenHigh (LenMid + (kNumPosStatesMax << kLenNumMidBits))
+#define kNumLenProbs (LenHigh + kLenNumHighSymbols) 
+
+
+#define kNumStates 12
+#define kNumLitStates 7
+
+#define kStartPosModelIndex 4
+#define kEndPosModelIndex 14
+#define kNumFullDistances (1 << (kEndPosModelIndex >> 1))
+
+#define kNumPosSlotBits 6
+#define kNumLenToPosStates 4
+
+#define kNumAlignBits 4
+#define kAlignTableSize (1 << kNumAlignBits)
+
+#define kMatchMinLen 2
+
+#define IsMatch 0
+#define IsRep (IsMatch + (kNumStates << kNumPosBitsMax))
+#define IsRepG0 (IsRep + kNumStates)
+#define IsRepG1 (IsRepG0 + kNumStates)
+#define IsRepG2 (IsRepG1 + kNumStates)
+#define IsRep0Long (IsRepG2 + kNumStates)
+#define PosSlot (IsRep0Long + (kNumStates << kNumPosBitsMax))
+#define SpecPos (PosSlot + (kNumLenToPosStates << kNumPosSlotBits))
+#define Align (SpecPos + kNumFullDistances - kEndPosModelIndex)
+#define LenCoder (Align + kAlignTableSize)
+#define RepLenCoder (LenCoder + kNumLenProbs)
+#define Literal (RepLenCoder + kNumLenProbs)
+
+#if Literal != LZMA_BASE_SIZE
+StopCompilingDueBUG
+#endif
+
+/* kRequiredInBufferSize = number of required input bytes for worst case: 
+   longest match with longest distance.
+   kLzmaInBufferSize must be larger than kRequiredInBufferSize 
+   23 bits = 2 (match select) + 10 (len) + 6 (distance) + 4(align) + 1 (RC_NORMALIZE)
+*/
+
+#define kRequiredInBufferSize ((23 * (kNumBitModelTotalBits - kNumMoveBits + 1) + 26 + 9) / 8)
+
+#define kLzmaStreamWasFinishedId (-1)
+
+int LzmaDecodeProperties(CLzmaProperties *propsRes, const unsigned char *propsData, int size)
+{
+  unsigned char prop0;
+  if (size < LZMA_PROPERTIES_SIZE)
+    return LZMA_RESULT_DATA_ERROR;
+  prop0 = propsData[0];
+  if (prop0 >= (9 * 5 * 5))
+    return LZMA_RESULT_DATA_ERROR;
+  {
+    for (propsRes->pb = 0; prop0 >= (9 * 5); propsRes->pb++, prop0 -= (9 * 5));
+    for (propsRes->lp = 0; prop0 >= 9; propsRes->lp++, prop0 -= 9);
+    propsRes->lc = prop0;
+    /*
+    unsigned char remainder = (unsigned char)(prop0 / 9);
+    propsRes->lc = prop0 % 9;
+    propsRes->pb = remainder / 5;
+    propsRes->lp = remainder % 5;
+    */
+  }
+
+  {
+    int i;
+    propsRes->DictionarySize = 0;
+    for (i = 0; i < 4; i++)
+      propsRes->DictionarySize += (UInt32)(propsData[1 + i]) << (i * 8);
+    if (propsRes->DictionarySize == 0)
+      propsRes->DictionarySize = 1;
+    return LZMA_RESULT_OK;
+  }
+}
+
+int LzmaDecode(
+    CLzmaDecoderState *vs,
+    const unsigned char *inStream, SizeT inSize, SizeT *inSizeProcessed,
+    unsigned char *outStream, SizeT outSize, SizeT *outSizeProcessed,
+    int finishDecoding)
+{
+  UInt32 Range = vs->Range;
+  UInt32 Code = vs->Code;
+
+  unsigned char *Buffer = vs->Buffer;
+  int BufferSize = vs->BufferSize; /* don't change it to unsigned int */
+  CProb *p = vs->Probs;
+
+  int state = vs->State;
+  unsigned char previousByte;
+  UInt32 rep0 = vs->Reps[0], rep1 = vs->Reps[1], rep2 = vs->Reps[2], rep3 = vs->Reps[3];
+  SizeT nowPos = 0;
+  UInt32 posStateMask = (1 << (vs->Properties.pb)) - 1;
+  UInt32 literalPosMask = (1 << (vs->Properties.lp)) - 1;
+  int lc = vs->Properties.lc;
+  int len = vs->RemainLen;
+  UInt32 globalPos = vs->GlobalPos;
+  UInt32 distanceLimit = vs->DistanceLimit;
+
+  unsigned char *dictionary = vs->Dictionary;
+  UInt32 dictionarySize = vs->Properties.DictionarySize;
+  UInt32 dictionaryPos = vs->DictionaryPos;
+
+  unsigned char tempDictionary[4];
+
+  (*inSizeProcessed) = 0;
+  (*outSizeProcessed) = 0;
+  if (len == kLzmaStreamWasFinishedId)
+    return LZMA_RESULT_OK;
+
+  if (dictionarySize == 0)
+  {
+    dictionary = tempDictionary;
+    dictionarySize = 1;
+    tempDictionary[0] = vs->TempDictionary[0];
+  }
+
+  if (len == kLzmaNeedInitId)
+  {
+    while (inSize > 0 && BufferSize < kLzmaInBufferSize)
+    {
+      Buffer[BufferSize++] = *inStream++;
+      (*inSizeProcessed)++;
+      inSize--;
+    }
+    if (BufferSize < 5)
+    {
+      vs->BufferSize = BufferSize;
+      return finishDecoding ? LZMA_RESULT_DATA_ERROR : LZMA_RESULT_OK;
+    }
+    {
+      UInt32 numProbs = Literal + ((UInt32)LZMA_LIT_SIZE << (lc + vs->Properties.lp));
+      UInt32 i;
+      for (i = 0; i < numProbs; i++)
+        p[i] = kBitModelTotal >> 1; 
+      rep0 = rep1 = rep2 = rep3 = 1;
+      state = 0;
+      globalPos = 0;
+      distanceLimit = 0;
+      dictionaryPos = 0;
+      dictionary[dictionarySize - 1] = 0;
+      RC_INIT;
+    }
+    len = 0;
+  }
+  while(len != 0 && nowPos < outSize)
+  {
+    UInt32 pos = dictionaryPos - rep0;
+    if (pos >= dictionarySize)
+      pos += dictionarySize;
+    outStream[nowPos++] = dictionary[dictionaryPos] = dictionary[pos];
+    if (++dictionaryPos == dictionarySize)
+      dictionaryPos = 0;
+    len--;
+  }
+  if (dictionaryPos == 0)
+    previousByte = dictionary[dictionarySize - 1];
+  else
+    previousByte = dictionary[dictionaryPos - 1];
+
+  for (;;)
+  {
+    int bufferPos = (int)(Buffer - vs->Buffer);
+    if (BufferSize - bufferPos < kRequiredInBufferSize)
+    {
+      int i;
+      BufferSize -= bufferPos;
+      if (BufferSize < 0)
+        return LZMA_RESULT_DATA_ERROR;
+      for (i = 0; i < BufferSize; i++)
+        vs->Buffer[i] = Buffer[i];
+      Buffer = vs->Buffer;
+      while (inSize > 0 && BufferSize < kLzmaInBufferSize)
+      {
+        Buffer[BufferSize++] = *inStream++;
+        (*inSizeProcessed)++;
+        inSize--;
+      }
+      if (BufferSize < kRequiredInBufferSize && !finishDecoding)
+        break;
+    }
+    if (nowPos >= outSize)
+      break;
+    {
+    CProb *prob;
+    UInt32 bound;
+    int posState = (int)((nowPos + globalPos) & posStateMask);
+
+    prob = p + IsMatch + (state << kNumPosBitsMax) + posState;
+    IfBit0(prob)
+    {
+      int symbol = 1;
+      UpdateBit0(prob)
+      prob = p + Literal + (LZMA_LIT_SIZE * 
+        ((((nowPos + globalPos)& literalPosMask) << lc) + (previousByte >> (8 - lc))));
+
+      if (state >= kNumLitStates)
+      {
+        int matchByte;
+        UInt32 pos = dictionaryPos - rep0;
+        if (pos >= dictionarySize)
+          pos += dictionarySize;
+        matchByte = dictionary[pos];
+        do
+        {
+          int bit;
+          CProb *probLit;
+          matchByte <<= 1;
+          bit = (matchByte & 0x100);
+          probLit = prob + 0x100 + bit + symbol;
+          RC_GET_BIT2(probLit, symbol, if (bit != 0) break, if (bit == 0) break)
+        }
+        while (symbol < 0x100);
+      }
+      while (symbol < 0x100)
+      {
+        CProb *probLit = prob + symbol;
+        RC_GET_BIT(probLit, symbol)
+      }
+      previousByte = (unsigned char)symbol;
+
+      outStream[nowPos++] = previousByte;
+      if (distanceLimit < dictionarySize)
+        distanceLimit++;
+
+      dictionary[dictionaryPos] = previousByte;
+      if (++dictionaryPos == dictionarySize)
+        dictionaryPos = 0;
+      if (state < 4) state = 0;
+      else if (state < 10) state -= 3;
+      else state -= 6;
+    }
+    else             
+    {
+      UpdateBit1(prob);
+      prob = p + IsRep + state;
+      IfBit0(prob)
+      {
+        UpdateBit0(prob);
+        rep3 = rep2;
+        rep2 = rep1;
+        rep1 = rep0;
+        state = state < kNumLitStates ? 0 : 3;
+        prob = p + LenCoder;
+      }
+      else
+      {
+        UpdateBit1(prob);
+        prob = p + IsRepG0 + state;
+        IfBit0(prob)
+        {
+          UpdateBit0(prob);
+          prob = p + IsRep0Long + (state << kNumPosBitsMax) + posState;
+          IfBit0(prob)
+          {
+            UInt32 pos;
+            UpdateBit0(prob);
+            if (distanceLimit == 0)
+              return LZMA_RESULT_DATA_ERROR;
+            if (distanceLimit < dictionarySize)
+              distanceLimit++;
+            state = state < kNumLitStates ? 9 : 11;
+            pos = dictionaryPos - rep0;
+            if (pos >= dictionarySize)
+              pos += dictionarySize;
+            previousByte = dictionary[pos];
+            dictionary[dictionaryPos] = previousByte;
+            if (++dictionaryPos == dictionarySize)
+              dictionaryPos = 0;
+            outStream[nowPos++] = previousByte;
+            continue;
+          }
+          else
+          {
+            UpdateBit1(prob);
+          }
+        }
+        else
+        {
+          UInt32 distance;
+          UpdateBit1(prob);
+          prob = p + IsRepG1 + state;
+          IfBit0(prob)
+          {
+            UpdateBit0(prob);
+            distance = rep1;
+          }
+          else 
+          {
+            UpdateBit1(prob);
+            prob = p + IsRepG2 + state;
+            IfBit0(prob)
+            {
+              UpdateBit0(prob);
+              distance = rep2;
+            }
+            else
+            {
+              UpdateBit1(prob);
+              distance = rep3;
+              rep3 = rep2;
+            }
+            rep2 = rep1;
+          }
+          rep1 = rep0;
+          rep0 = distance;
+        }
+        state = state < kNumLitStates ? 8 : 11;
+        prob = p + RepLenCoder;
+      }
+      {
+        int numBits, offset;
+        CProb *probLen = prob + LenChoice;
+        IfBit0(probLen)
+        {
+          UpdateBit0(probLen);
+          probLen = prob + LenLow + (posState << kLenNumLowBits);
+          offset = 0;
+          numBits = kLenNumLowBits;
+        }
+        else
+        {
+          UpdateBit1(probLen);
+          probLen = prob + LenChoice2;
+          IfBit0(probLen)
+          {
+            UpdateBit0(probLen);
+            probLen = prob + LenMid + (posState << kLenNumMidBits);
+            offset = kLenNumLowSymbols;
+            numBits = kLenNumMidBits;
+          }
+          else
+          {
+            UpdateBit1(probLen);
+            probLen = prob + LenHigh;
+            offset = kLenNumLowSymbols + kLenNumMidSymbols;
+            numBits = kLenNumHighBits;
+          }
+        }
+        RangeDecoderBitTreeDecode(probLen, numBits, len);
+        len += offset;
+      }
+
+      if (state < 4)
+      {
+        int posSlot;
+        state += kNumLitStates;
+        prob = p + PosSlot +
+            ((len < kNumLenToPosStates ? len : kNumLenToPosStates - 1) << 
+            kNumPosSlotBits);
+        RangeDecoderBitTreeDecode(prob, kNumPosSlotBits, posSlot);
+        if (posSlot >= kStartPosModelIndex)
+        {
+          int numDirectBits = ((posSlot >> 1) - 1);
+          rep0 = (2 | ((UInt32)posSlot & 1));
+          if (posSlot < kEndPosModelIndex)
+          {
+            rep0 <<= numDirectBits;
+            prob = p + SpecPos + rep0 - posSlot - 1;
+          }
+          else
+          {
+            numDirectBits -= kNumAlignBits;
+            do
+            {
+              RC_NORMALIZE
+              Range >>= 1;
+              rep0 <<= 1;
+              if (Code >= Range)
+              {
+                Code -= Range;
+                rep0 |= 1;
+              }
+            }
+            while (--numDirectBits != 0);
+            prob = p + Align;
+            rep0 <<= kNumAlignBits;
+            numDirectBits = kNumAlignBits;
+          }
+          {
+            int i = 1;
+            int mi = 1;
+            do
+            {
+              CProb *prob3 = prob + mi;
+              RC_GET_BIT2(prob3, mi, ; , rep0 |= i);
+              i <<= 1;
+            }
+            while(--numDirectBits != 0);
+          }
+        }
+        else
+          rep0 = posSlot;
+        if (++rep0 == (UInt32)(0))
+        {
+          /* it's for stream version */
+          len = kLzmaStreamWasFinishedId;
+          break;
+        }
+      }
+
+      len += kMatchMinLen;
+      if (rep0 > distanceLimit) 
+        return LZMA_RESULT_DATA_ERROR;
+      if (dictionarySize - distanceLimit > (UInt32)len)
+        distanceLimit += len;
+      else
+        distanceLimit = dictionarySize;
+
+      do
+      {
+        UInt32 pos = dictionaryPos - rep0;
+        if (pos >= dictionarySize)
+          pos += dictionarySize;
+        previousByte = dictionary[pos];
+        dictionary[dictionaryPos] = previousByte;
+        if (++dictionaryPos == dictionarySize)
+          dictionaryPos = 0;
+        len--;
+        outStream[nowPos++] = previousByte;
+      }
+      while(len != 0 && nowPos < outSize);
+    }
+    }
+  }
+  RC_NORMALIZE;
+
+  BufferSize -= (int)(Buffer - vs->Buffer);
+  if (BufferSize < 0)
+    return LZMA_RESULT_DATA_ERROR;
+  {
+    int i;
+    for (i = 0; i < BufferSize; i++)
+      vs->Buffer[i] = Buffer[i];
+  }
+  vs->BufferSize = BufferSize;
+  vs->Range = Range;
+  vs->Code = Code;
+  vs->DictionaryPos = dictionaryPos;
+  vs->GlobalPos = (UInt32)(globalPos + nowPos);
+  vs->DistanceLimit = distanceLimit;
+  vs->Reps[0] = rep0;
+  vs->Reps[1] = rep1;
+  vs->Reps[2] = rep2;
+  vs->Reps[3] = rep3;
+  vs->State = state;
+  vs->RemainLen = len;
+  vs->TempDictionary[0] = tempDictionary[0];
+
+  (*outSizeProcessed) = nowPos;
+  return LZMA_RESULT_OK;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/misc/libphysfs/lzma/C/Compress/Lzma/LzmaStateDecode.h	Mon Apr 10 12:06:43 2017 -0400
@@ -0,0 +1,96 @@
+/* 
+  LzmaStateDecode.h
+  LZMA Decoder interface (State version)
+
+  LZMA SDK 4.40 Copyright (c) 1999-2006 Igor Pavlov (2006-05-01)
+  http://www.7-zip.org/
+
+  LZMA SDK is licensed under two licenses:
+  1) GNU Lesser General Public License (GNU LGPL)
+  2) Common Public License (CPL)
+  It means that you can select one of these two licenses and 
+  follow rules of that license.
+
+  SPECIAL EXCEPTION:
+  Igor Pavlov, as the author of this code, expressly permits you to 
+  statically or dynamically link your code (or bind by name) to the 
+  interfaces of this file without subjecting your linked code to the 
+  terms of the CPL or GNU LGPL. Any modifications or additions 
+  to this file, however, are subject to the LGPL or CPL terms.
+*/
+
+#ifndef __LZMASTATEDECODE_H
+#define __LZMASTATEDECODE_H
+
+#include "LzmaTypes.h"
+
+/* #define _LZMA_PROB32 */
+/* It can increase speed on some 32-bit CPUs, 
+   but memory usage will be doubled in that case */
+
+#ifdef _LZMA_PROB32
+#define CProb UInt32
+#else
+#define CProb UInt16
+#endif
+
+#define LZMA_RESULT_OK 0
+#define LZMA_RESULT_DATA_ERROR 1
+
+#define LZMA_BASE_SIZE 1846
+#define LZMA_LIT_SIZE 768
+
+#define LZMA_PROPERTIES_SIZE 5
+
+typedef struct _CLzmaProperties
+{
+  int lc;
+  int lp;
+  int pb;
+  UInt32 DictionarySize;
+}CLzmaProperties;
+
+int LzmaDecodeProperties(CLzmaProperties *propsRes, const unsigned char *propsData, int size);
+
+#define LzmaGetNumProbs(lzmaProps) (LZMA_BASE_SIZE + (LZMA_LIT_SIZE << ((lzmaProps)->lc + (lzmaProps)->lp)))
+
+#define kLzmaInBufferSize 64   /* don't change it. it must be larger than kRequiredInBufferSize */
+
+#define kLzmaNeedInitId (-2)
+
+typedef struct _CLzmaDecoderState
+{
+  CLzmaProperties Properties;
+  CProb *Probs;
+  unsigned char *Dictionary;
+
+  unsigned char Buffer[kLzmaInBufferSize];
+  int BufferSize;
+
+  UInt32 Range;
+  UInt32 Code;
+  UInt32 DictionaryPos;
+  UInt32 GlobalPos;
+  UInt32 DistanceLimit;
+  UInt32 Reps[4];
+  int State;
+  int RemainLen;  /* -2: decoder needs internal initialization
+                     -1: stream was finished, 
+                      0: ok
+                    > 0: need to write RemainLen bytes as match Reps[0],
+                  */
+  unsigned char TempDictionary[4];  /* it's required when DictionarySize = 0 */
+} CLzmaDecoderState;
+
+#define LzmaDecoderInit(vs) { (vs)->RemainLen = kLzmaNeedInitId; (vs)->BufferSize = 0; }
+
+/* LzmaDecode: decoding from input stream to output stream.
+  If finishDecoding != 0, then there are no more bytes in input stream
+  after inStream[inSize - 1]. */
+
+int LzmaDecode(CLzmaDecoderState *vs,
+    const unsigned char *inStream, SizeT inSize,  SizeT *inSizeProcessed,
+    unsigned char *outStream, SizeT outSize, SizeT *outSizeProcessed,
+    int finishDecoding);
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/misc/libphysfs/lzma/C/Compress/Lzma/LzmaStateTest.c	Mon Apr 10 12:06:43 2017 -0400
@@ -0,0 +1,195 @@
+/* 
+LzmaStateTest.c
+Test application for LZMA Decoder (State version)
+
+This file written and distributed to public domain by Igor Pavlov.
+This file is part of LZMA SDK 4.26 (2005-08-02)
+*/
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "LzmaStateDecode.h"
+
+const char *kCantReadMessage = "Can not read input file";
+const char *kCantWriteMessage = "Can not write output file";
+const char *kCantAllocateMessage = "Can not allocate memory";
+
+#define kInBufferSize (1 << 15)
+#define kOutBufferSize (1 << 15)
+
+unsigned char g_InBuffer[kInBufferSize];
+unsigned char g_OutBuffer[kOutBufferSize];
+
+size_t MyReadFile(FILE *file, void *data, size_t size)
+  { return fread(data, 1, size, file); }
+
+int MyReadFileAndCheck(FILE *file, void *data, size_t size)
+  { return (MyReadFile(file, data, size) == size); }
+
+int PrintError(char *buffer, const char *message)
+{
+  sprintf(buffer + strlen(buffer), "\nError: ");
+  sprintf(buffer + strlen(buffer), message);
+  return 1;
+}
+
+int main3(FILE *inFile, FILE *outFile, char *rs)
+{
+  /* We use two 32-bit integers to construct 64-bit integer for file size.
+     You can remove outSizeHigh, if you don't need >= 4GB supporting,
+     or you can use UInt64 outSize, if your compiler supports 64-bit integers*/
+  UInt32 outSize = 0;
+  UInt32 outSizeHigh = 0; 
+  
+  int waitEOS = 1; 
+  /* waitEOS = 1, if there is no uncompressed size in headers, 
+   so decoder will wait EOS (End of Stream Marker) in compressed stream */
+
+  int i;
+  int res = 0;
+  CLzmaDecoderState state;  /* it's about 140 bytes structure, if int is 32-bit */
+  unsigned char properties[LZMA_PROPERTIES_SIZE];
+  SizeT inAvail = 0;
+  unsigned char *inBuffer = 0;
+
+  if (sizeof(UInt32) < 4)
+    return PrintError(rs, "LZMA decoder needs correct UInt32");
+
+  /* Read LZMA properties for compressed stream */
+
+  if (!MyReadFileAndCheck(inFile, properties, sizeof(properties)))
+    return PrintError(rs, kCantReadMessage);
+
+  /* Read uncompressed size */
+  
+  for (i = 0; i < 8; i++)
+  {
+    unsigned char b;
+    if (!MyReadFileAndCheck(inFile, &b, 1))
+      return PrintError(rs, kCantReadMessage);
+    if (b != 0xFF)
+      waitEOS = 0;
+    if (i < 4)
+      outSize += (UInt32)(b) << (i * 8);
+    else
+      outSizeHigh += (UInt32)(b) << ((i - 4) * 8);
+  }
+
+  /* Decode LZMA properties and allocate memory */
+  
+  if (LzmaDecodeProperties(&state.Properties, properties, LZMA_PROPERTIES_SIZE) != LZMA_RESULT_OK)
+    return PrintError(rs, "Incorrect stream properties");
+  state.Probs = (CProb *)malloc(LzmaGetNumProbs(&state.Properties) * sizeof(CProb));
+  if (state.Probs == 0)
+    return PrintError(rs, kCantAllocateMessage);
+  
+  if (state.Properties.DictionarySize == 0)
+    state.Dictionary = 0;
+  else
+  {
+    state.Dictionary = (unsigned char *)malloc(state.Properties.DictionarySize);
+    if (state.Dictionary == 0)
+    {
+      free(state.Probs);
+      return PrintError(rs, kCantAllocateMessage);
+    }
+  }
+  
+  /* Decompress */
+  
+  LzmaDecoderInit(&state);
+  
+  do
+  {
+    SizeT inProcessed, outProcessed;
+    int finishDecoding;
+    UInt32 outAvail = kOutBufferSize;
+    if (!waitEOS && outSizeHigh == 0 && outAvail > outSize)
+      outAvail = outSize;
+    if (inAvail == 0)
+    {
+      inAvail = (SizeT)MyReadFile(inFile, g_InBuffer, kInBufferSize);
+      inBuffer = g_InBuffer;
+    }
+    finishDecoding = (inAvail == 0);
+    res = LzmaDecode(&state,
+        inBuffer, inAvail, &inProcessed,
+        g_OutBuffer, outAvail, &outProcessed,
+        finishDecoding);
+    if (res != 0)
+    {
+      sprintf(rs + strlen(rs), "\nDecoding error = %d\n", res);
+      res = 1;
+      break;
+    }
+    inAvail -= inProcessed;
+    inBuffer += inProcessed;
+    
+    if (outFile != 0)  
+      if (fwrite(g_OutBuffer, 1, outProcessed, outFile) != outProcessed)
+      {
+        PrintError(rs, kCantWriteMessage);
+        res = 1;
+        break;
+      }
+      
+    if (outSize < outProcessed)
+      outSizeHigh--;
+    outSize -= (UInt32)outProcessed;
+    outSize &= 0xFFFFFFFF;
+
+    if (outProcessed == 0 && finishDecoding)
+    {
+      if (!waitEOS && (outSize != 0 || outSizeHigh != 0))
+        res = 1;
+      break;
+    }
+  }
+  while ((outSize != 0 && outSizeHigh == 0) || outSizeHigh != 0  || waitEOS);
+
+  free(state.Dictionary);
+  free(state.Probs);
+  return res;
+}
+
+int main2(int numArgs, const char *args[], char *rs)
+{
+  FILE *inFile = 0;
+  FILE *outFile = 0;
+  int res;
+
+  sprintf(rs + strlen(rs), "\nLZMA Decoder 4.26 Copyright (c) 1999-2005 Igor Pavlov  2005-08-02\n");
+  if (numArgs < 2 || numArgs > 3)
+  {
+    sprintf(rs + strlen(rs), "\nUsage:  lzmadec file.lzma [outFile]\n");
+    return 1;
+  }
+
+  inFile = fopen(args[1], "rb");
+  if (inFile == 0)
+    return PrintError(rs, "Can not open input file");
+
+  if (numArgs > 2)
+  {
+    outFile = fopen(args[2], "wb+");
+    if (outFile == 0)
+      return PrintError(rs, "Can not open output file");
+  }
+
+  res = main3(inFile, outFile, rs);
+
+  if (outFile != 0)
+    fclose(outFile);
+  fclose(inFile);
+  return res;
+}
+
+int main(int numArgs, const char *args[])
+{
+  char rs[800] = { 0 };
+  int res = main2(numArgs, args, rs);
+  printf(rs);
+  return res;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/misc/libphysfs/lzma/C/Compress/Lzma/LzmaTest.c	Mon Apr 10 12:06:43 2017 -0400
@@ -0,0 +1,342 @@
+/* 
+LzmaTest.c
+Test application for LZMA Decoder
+
+This file written and distributed to public domain by Igor Pavlov.
+This file is part of LZMA SDK 4.26 (2005-08-05)
+*/
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "LzmaDecode.h"
+
+const char *kCantReadMessage = "Can not read input file";
+const char *kCantWriteMessage = "Can not write output file";
+const char *kCantAllocateMessage = "Can not allocate memory";
+
+size_t MyReadFile(FILE *file, void *data, size_t size)
+{ 
+  if (size == 0)
+    return 0;
+  return fread(data, 1, size, file); 
+}
+
+int MyReadFileAndCheck(FILE *file, void *data, size_t size)
+  { return (MyReadFile(file, data, size) == size);} 
+
+size_t MyWriteFile(FILE *file, const void *data, size_t size)
+{ 
+  if (size == 0)
+    return 0;
+  return fwrite(data, 1, size, file); 
+}
+
+int MyWriteFileAndCheck(FILE *file, const void *data, size_t size)
+  { return (MyWriteFile(file, data, size) == size); }
+
+#ifdef _LZMA_IN_CB
+#define kInBufferSize (1 << 15)
+typedef struct _CBuffer
+{
+  ILzmaInCallback InCallback;
+  FILE *File;
+  unsigned char Buffer[kInBufferSize];
+} CBuffer;
+
+int LzmaReadCompressed(void *object, const unsigned char **buffer, SizeT *size)
+{
+  CBuffer *b = (CBuffer *)object;
+  *buffer = b->Buffer;
+  *size = (SizeT)MyReadFile(b->File, b->Buffer, kInBufferSize);
+  return LZMA_RESULT_OK;
+}
+CBuffer g_InBuffer;
+
+#endif
+
+#ifdef _LZMA_OUT_READ
+#define kOutBufferSize (1 << 15)
+unsigned char g_OutBuffer[kOutBufferSize];
+#endif
+
+int PrintError(char *buffer, const char *message)
+{
+  sprintf(buffer + strlen(buffer), "\nError: ");
+  sprintf(buffer + strlen(buffer), message);
+  return 1;
+}
+
+int main3(FILE *inFile, FILE *outFile, char *rs)
+{
+  /* We use two 32-bit integers to construct 64-bit integer for file size.
+     You can remove outSizeHigh, if you don't need >= 4GB supporting,
+     or you can use UInt64 outSize, if your compiler supports 64-bit integers*/
+  UInt32 outSize = 0;
+  UInt32 outSizeHigh = 0;
+  #ifndef _LZMA_OUT_READ
+  SizeT outSizeFull;
+  unsigned char *outStream;
+  #endif
+  
+  int waitEOS = 1; 
+  /* waitEOS = 1, if there is no uncompressed size in headers, 
+   so decoder will wait EOS (End of Stream Marker) in compressed stream */
+
+  #ifndef _LZMA_IN_CB
+  SizeT compressedSize;
+  unsigned char *inStream;
+  #endif
+
+  CLzmaDecoderState state;  /* it's about 24-80 bytes structure, if int is 32-bit */
+  unsigned char properties[LZMA_PROPERTIES_SIZE];
+
+  int res;
+
+  #ifdef _LZMA_IN_CB
+  g_InBuffer.File = inFile;
+  #endif
+
+  if (sizeof(UInt32) < 4)
+    return PrintError(rs, "LZMA decoder needs correct UInt32");
+
+  #ifndef _LZMA_IN_CB
+  {
+    long length;
+    fseek(inFile, 0, SEEK_END);
+    length = ftell(inFile);
+    fseek(inFile, 0, SEEK_SET);
+    if ((long)(SizeT)length != length)
+      return PrintError(rs, "Too big compressed stream");
+    compressedSize = (SizeT)(length - (LZMA_PROPERTIES_SIZE + 8));
+  }
+  #endif
+
+  /* Read LZMA properties for compressed stream */
+
+  if (!MyReadFileAndCheck(inFile, properties, sizeof(properties)))
+    return PrintError(rs, kCantReadMessage);
+
+  /* Read uncompressed size */
+
+  {
+    int i;
+    for (i = 0; i < 8; i++)
+    {
+      unsigned char b;
+      if (!MyReadFileAndCheck(inFile, &b, 1))
+        return PrintError(rs, kCantReadMessage);
+      if (b != 0xFF)
+        waitEOS = 0;
+      if (i < 4)
+        outSize += (UInt32)(b) << (i * 8);
+      else
+        outSizeHigh += (UInt32)(b) << ((i - 4) * 8);
+    }
+    
+    #ifndef _LZMA_OUT_READ
+    if (waitEOS)
+      return PrintError(rs, "Stream with EOS marker is not supported");
+    outSizeFull = (SizeT)outSize;
+    if (sizeof(SizeT) >= 8)
+      outSizeFull |= (((SizeT)outSizeHigh << 16) << 16);
+    else if (outSizeHigh != 0 || (UInt32)(SizeT)outSize != outSize)
+      return PrintError(rs, "Too big uncompressed stream");
+    #endif
+  }
+
+  /* Decode LZMA properties and allocate memory */
+  
+  if (LzmaDecodeProperties(&state.Properties, properties, LZMA_PROPERTIES_SIZE) != LZMA_RESULT_OK)
+    return PrintError(rs, "Incorrect stream properties");
+  state.Probs = (CProb *)malloc(LzmaGetNumProbs(&state.Properties) * sizeof(CProb));
+
+  #ifdef _LZMA_OUT_READ
+  if (state.Properties.DictionarySize == 0)
+    state.Dictionary = 0;
+  else
+    state.Dictionary = (unsigned char *)malloc(state.Properties.DictionarySize);
+  #else
+  if (outSizeFull == 0)
+    outStream = 0;
+  else
+    outStream = (unsigned char *)malloc(outSizeFull);
+  #endif
+
+  #ifndef _LZMA_IN_CB
+  if (compressedSize == 0)
+    inStream = 0;
+  else
+    inStream = (unsigned char *)malloc(compressedSize);
+  #endif
+
+  if (state.Probs == 0 
+    #ifdef _LZMA_OUT_READ
+    || (state.Dictionary == 0 && state.Properties.DictionarySize != 0)
+    #else
+    || (outStream == 0 && outSizeFull != 0)
+    #endif
+    #ifndef _LZMA_IN_CB
+    || (inStream == 0 && compressedSize != 0)
+    #endif
+    )
+  {
+    free(state.Probs);
+    #ifdef _LZMA_OUT_READ
+    free(state.Dictionary);
+    #else
+    free(outStream);
+    #endif
+    #ifndef _LZMA_IN_CB
+    free(inStream);
+    #endif
+    return PrintError(rs, kCantAllocateMessage);
+  }
+
+  /* Decompress */
+
+  #ifdef _LZMA_IN_CB
+  g_InBuffer.InCallback.Read = LzmaReadCompressed;
+  #else
+  if (!MyReadFileAndCheck(inFile, inStream, compressedSize))
+    return PrintError(rs, kCantReadMessage);
+  #endif
+
+  #ifdef _LZMA_OUT_READ
+  {
+    #ifndef _LZMA_IN_CB
+    SizeT inAvail = compressedSize;
+    const unsigned char *inBuffer = inStream;
+    #endif
+    LzmaDecoderInit(&state);
+    do
+    {
+      #ifndef _LZMA_IN_CB
+      SizeT inProcessed;
+      #endif
+      SizeT outProcessed;
+      SizeT outAvail = kOutBufferSize;
+      if (!waitEOS && outSizeHigh == 0 && outAvail > outSize)
+        outAvail = (SizeT)outSize;
+      res = LzmaDecode(&state,
+        #ifdef _LZMA_IN_CB
+        &g_InBuffer.InCallback,
+        #else
+        inBuffer, inAvail, &inProcessed,
+        #endif
+        g_OutBuffer, outAvail, &outProcessed);
+      if (res != 0)
+      {
+        sprintf(rs + strlen(rs), "\nDecoding error = %d\n", res);
+        res = 1;
+        break;
+      }
+      #ifndef _LZMA_IN_CB
+      inAvail -= inProcessed;
+      inBuffer += inProcessed;
+      #endif
+      
+      if (outFile != 0)  
+        if (!MyWriteFileAndCheck(outFile, g_OutBuffer, (size_t)outProcessed))
+        {
+          PrintError(rs, kCantWriteMessage);
+          res = 1;
+          break;
+        }
+        
+      if (outSize < outProcessed)
+        outSizeHigh--;
+      outSize -= (UInt32)outProcessed;
+      outSize &= 0xFFFFFFFF;
+        
+      if (outProcessed == 0)
+      {
+        if (!waitEOS && (outSize != 0 || outSizeHigh != 0))
+          res = 1;
+        break;
+      }
+    }
+    while ((outSize != 0 && outSizeHigh == 0) || outSizeHigh != 0  || waitEOS);
+  }
+
+  #else
+  {
+    #ifndef _LZMA_IN_CB
+    SizeT inProcessed;
+    #endif
+    SizeT outProcessed;
+    res = LzmaDecode(&state,
+      #ifdef _LZMA_IN_CB
+      &g_InBuffer.InCallback,
+      #else
+      inStream, compressedSize, &inProcessed,
+      #endif
+      outStream, outSizeFull, &outProcessed);
+    if (res != 0)
+    {
+      sprintf(rs + strlen(rs), "\nDecoding error = %d\n", res);
+      res = 1;
+    }
+    else if (outFile != 0)
+    {
+      if (!MyWriteFileAndCheck(outFile, outStream, (size_t)outProcessed))
+      {
+        PrintError(rs, kCantWriteMessage);
+        res = 1;
+      }
+    }
+  }
+  #endif
+
+  free(state.Probs);
+  #ifdef _LZMA_OUT_READ
+  free(state.Dictionary);
+  #else
+  free(outStream);
+  #endif
+  #ifndef _LZMA_IN_CB
+  free(inStream);
+  #endif
+  return res;
+}
+
+int main2(int numArgs, const char *args[], char *rs)
+{
+  FILE *inFile = 0;
+  FILE *outFile = 0;
+  int res;
+
+  sprintf(rs + strlen(rs), "\nLZMA Decoder 4.26 Copyright (c) 1999-2005 Igor Pavlov  2005-08-05\n");
+  if (numArgs < 2 || numArgs > 3)
+  {
+    sprintf(rs + strlen(rs), "\nUsage:  lzmadec file.lzma [outFile]\n");
+    return 1;
+  }
+
+  inFile = fopen(args[1], "rb");
+  if (inFile == 0)
+    return PrintError(rs, "Can not open input file");
+
+  if (numArgs > 2)
+  {
+    outFile = fopen(args[2], "wb+");
+    if (outFile == 0)
+      return PrintError(rs, "Can not open output file");
+  }
+
+  res = main3(inFile, outFile, rs);
+
+  if (outFile != 0)
+    fclose(outFile);
+  fclose(inFile);
+  return res;
+}
+
+int main(int numArgs, const char *args[])
+{
+  char rs[800] = { 0 };
+  int res = main2(numArgs, args, rs);
+  printf(rs);
+  return res;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/misc/libphysfs/lzma/C/Compress/Lzma/LzmaTypes.h	Mon Apr 10 12:06:43 2017 -0400
@@ -0,0 +1,45 @@
+/* 
+LzmaTypes.h 
+
+Types for LZMA Decoder
+
+This file written and distributed to public domain by Igor Pavlov.
+This file is part of LZMA SDK 4.40 (2006-05-01)
+*/
+
+#ifndef __LZMATYPES_H
+#define __LZMATYPES_H
+
+#ifndef _7ZIP_BYTE_DEFINED
+#define _7ZIP_BYTE_DEFINED
+typedef unsigned char Byte;
+#endif 
+
+#ifndef _7ZIP_UINT16_DEFINED
+#define _7ZIP_UINT16_DEFINED
+typedef unsigned short UInt16;
+#endif 
+
+#ifndef _7ZIP_UINT32_DEFINED
+#define _7ZIP_UINT32_DEFINED
+#ifdef _LZMA_UINT32_IS_ULONG
+typedef unsigned long UInt32;
+#else
+typedef unsigned int UInt32;
+#endif
+#endif 
+
+/* #define _LZMA_NO_SYSTEM_SIZE_T */
+/* You can use it, if you don't want <stddef.h> */
+
+#ifndef _7ZIP_SIZET_DEFINED
+#define _7ZIP_SIZET_DEFINED
+#ifdef _LZMA_NO_SYSTEM_SIZE_T
+typedef UInt32 SizeT;
+#else
+#include <stddef.h>
+typedef size_t SizeT;
+#endif
+#endif
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/misc/libphysfs/lzma/C/CpuArch.h	Mon Apr 10 12:06:43 2017 -0400
@@ -0,0 +1,18 @@
+/* CpuArch.h */
+
+#ifndef __CPUARCH_H
+#define __CPUARCH_H
+
+/* 
+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_IX86) || defined(_M_X64) || defined(_M_AMD64) || defined(__i386__) || defined(__x86_64__)
+#define LITTLE_ENDIAN_UNALIGN
+#endif
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/misc/libphysfs/lzma/C/IStream.h	Mon Apr 10 12:06:43 2017 -0400
@@ -0,0 +1,19 @@
+/* IStream.h */
+
+#ifndef __C_ISTREAM_H
+#define __C_ISTREAM_H
+
+#include "Types.h"
+
+typedef struct _ISeqInStream
+{
+  HRes (*Read)(void *object, void *data, UInt32 size, UInt32 *processedSize);
+} ISeqInStream;
+
+typedef struct _ISzAlloc
+{
+  void *(*Alloc)(size_t size);
+  void (*Free)(void *address); /* address can be 0 */
+} ISzAlloc;
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/misc/libphysfs/lzma/C/Sort.c	Mon Apr 10 12:06:43 2017 -0400
@@ -0,0 +1,92 @@
+/* Sort.c */
+
+#include "Sort.h"
+
+#define HeapSortDown(p, k, size, temp) \
+  { for (;;) { \
+    UInt32 s = (k << 1); \
+    if (s > size) break; \
+    if (s < size && p[s + 1] > p[s]) s++; \
+    if (temp >= p[s]) break; \
+    p[k] = p[s]; k = s; \
+  } p[k] = temp; }
+
+void HeapSort(UInt32 *p, UInt32 size)
+{
+  if (size <= 1)
+    return;
+  p--;
+  {
+    UInt32 i = size / 2;
+    do
+    {
+      UInt32 temp = p[i];
+      UInt32 k = i;
+      HeapSortDown(p, k, size, temp)
+    }
+    while(--i != 0);
+  }
+  /*
+  do
+  {
+    UInt32 k = 1;
+    UInt32 temp = p[size];
+    p[size--] = p[1];
+    HeapSortDown(p, k, size, temp)
+  }
+  while (size > 1);
+  */
+  while (size > 3)
+  {
+    UInt32 temp = p[size];
+    UInt32 k = (p[3] > p[2]) ? 3 : 2;
+    p[size--] = p[1];
+    p[1] = p[k]; 
+    HeapSortDown(p, k, size, temp)
+  }
+  {
+    UInt32 temp = p[size];
+    p[size] = p[1];
+    if (size > 2 && p[2] < temp)
+    {
+      p[1] = p[2];
+      p[2] = temp;
+    }
+    else
+      p[1] = temp;
+  }
+}
+
+/*
+#define HeapSortRefDown(p, vals, n, size, temp) \
+  { UInt32 k = n; UInt32 val = vals[temp]; for (;;) { \
+    UInt32 s = (k << 1); \
+    if (s > size) break; \
+    if (s < size && vals[p[s + 1]] > vals[p[s]]) s++; \
+    if (val >= vals[p[s]]) break; \
+    p[k] = p[s]; k = s; \
+  } p[k] = temp; }
+
+void HeapSortRef(UInt32 *p, UInt32 *vals, UInt32 size)
+{
+  if (size <= 1)
+    return;
+  p--;
+  {
+    UInt32 i = size / 2;
+    do
+    {
+      UInt32 temp = p[i];
+      HeapSortRefDown(p, vals, i, size, temp);
+    }
+    while(--i != 0);
+  }
+  do
+  {
+    UInt32 temp = p[size];
+    p[size--] = p[1];
+    HeapSortRefDown(p, vals, 1, size, temp);
+  }
+  while (size > 1);
+}
+*/
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/misc/libphysfs/lzma/C/Sort.h	Mon Apr 10 12:06:43 2017 -0400
@@ -0,0 +1,11 @@
+/* Sort.h */
+
+#ifndef __7Z_Sort_H
+#define __7Z_Sort_H
+
+#include "Types.h"
+
+void HeapSort(UInt32 *p, UInt32 size);
+/* void HeapSortRef(UInt32 *p, UInt32 *vals, UInt32 size); */
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/misc/libphysfs/lzma/C/Threads.c	Mon Apr 10 12:06:43 2017 -0400
@@ -0,0 +1,106 @@
+/* Threads.c */
+
+#include "Threads.h"
+#include <process.h>
+
+HRes GetError()
+{
+  DWORD res = GetLastError();
+  return (res) ? (HRes)(res) : SZE_FAIL;
+}
+
+HRes BoolToHRes(int v) { return v ? SZ_OK : GetError(); }
+HRes BOOLToHRes(BOOL v) { return v ? SZ_OK : GetError(); }
+
+HRes MyCloseHandle(HANDLE *h)
+{
+  if (*h != NULL)
+    if (!CloseHandle(*h))
+      return GetError();
+  *h = NULL;
+  return SZ_OK;
+}
+
+HRes Thread_Create(CThread *thread, THREAD_FUNC_RET_TYPE (THREAD_FUNC_CALL_TYPE *startAddress)(void *), LPVOID parameter)
+{ 
+  unsigned threadId; /* Windows Me/98/95: threadId parameter may not be NULL in _beginthreadex/CreateThread functions */
+  thread->handle = 
+    /* CreateThread(0, 0, startAddress, parameter, 0, &threadId); */
+    (HANDLE)_beginthreadex(NULL, 0, startAddress, parameter, 0, &threadId);
+    /* maybe we must use errno here, but probably GetLastError() is also OK. */
+  return BoolToHRes(thread->handle != 0);
+}
+
+HRes WaitObject(HANDLE h)
+{
+  return (HRes)WaitForSingleObject(h, INFINITE); 
+}
+
+HRes Thread_Wait(CThread *thread)
+{
+  if (thread->handle == NULL)
+    return 1;
+  return WaitObject(thread->handle); 
+}
+
+HRes Thread_Close(CThread *thread)
+{
+  return MyCloseHandle(&thread->handle);
+}
+
+HRes Event_Create(CEvent *p, BOOL manualReset, int initialSignaled)
+{
+  p->handle = CreateEvent(NULL, manualReset, (initialSignaled ? TRUE : FALSE), NULL);
+  return BoolToHRes(p->handle != 0);
+}
+
+HRes ManualResetEvent_Create(CManualResetEvent *p, int initialSignaled)
+  { return Event_Create(p, TRUE, initialSignaled); }
+HRes ManualResetEvent_CreateNotSignaled(CManualResetEvent *p) 
+  { return ManualResetEvent_Create(p, 0); }
+
+HRes AutoResetEvent_Create(CAutoResetEvent *p, int initialSignaled)
+  { return Event_Create(p, FALSE, initialSignaled); }
+HRes AutoResetEvent_CreateNotSignaled(CAutoResetEvent *p) 
+  { return AutoResetEvent_Create(p, 0); }
+
+HRes Event_Set(CEvent *p) { return BOOLToHRes(SetEvent(p->handle)); }
+HRes Event_Reset(CEvent *p) { return BOOLToHRes(ResetEvent(p->handle)); }
+HRes Event_Wait(CEvent *p) { return WaitObject(p->handle); }
+HRes Event_Close(CEvent *p) { return MyCloseHandle(&p->handle); }
+
+
+HRes Semaphore_Create(CSemaphore *p, UInt32 initiallyCount, UInt32 maxCount)
+{
+  p->handle = CreateSemaphore(NULL, (LONG)initiallyCount, (LONG)maxCount, NULL);
+  return BoolToHRes(p->handle != 0);
+}
+
+HRes Semaphore_Release(CSemaphore *p, LONG releaseCount, LONG *previousCount) 
+{ 
+  return BOOLToHRes(ReleaseSemaphore(p->handle, releaseCount, previousCount)); 
+}
+HRes Semaphore_ReleaseN(CSemaphore *p, UInt32 releaseCount)
+{
+  return Semaphore_Release(p, (LONG)releaseCount, NULL);
+}
+HRes Semaphore_Release1(CSemaphore *p)
+{
+  return Semaphore_ReleaseN(p, 1);
+}
+
+HRes Semaphore_Wait(CSemaphore *p) { return WaitObject(p->handle); }
+HRes Semaphore_Close(CSemaphore *p) { return MyCloseHandle(&p->handle); }
+
+HRes CriticalSection_Init(CCriticalSection *p)
+{
+  /* InitializeCriticalSection can raise only STATUS_NO_MEMORY exception */
+  __try 
+  { 
+    InitializeCriticalSection(p); 
+    /* InitializeCriticalSectionAndSpinCount(p, 0); */
+  }  
+  __except (EXCEPTION_EXECUTE_HANDLER) { return SZE_OUTOFMEMORY; }
+  return SZ_OK;
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/misc/libphysfs/lzma/C/Threads.h	Mon Apr 10 12:06:43 2017 -0400
@@ -0,0 +1,69 @@
+/* Threads.h */
+
+#ifndef __7Z_THRESDS_H
+#define __7Z_THRESDS_H
+
+#include <windows.h>
+
+#include "Types.h"
+
+typedef struct _CThread
+{
+  HANDLE handle;
+} CThread;
+
+#define Thread_Construct(thread) (thread)->handle = NULL
+#define Thread_WasCreated(thread) ((thread)->handle != NULL)
+ 
+typedef unsigned THREAD_FUNC_RET_TYPE;
+#define THREAD_FUNC_CALL_TYPE StdCall
+#define THREAD_FUNC_DECL THREAD_FUNC_RET_TYPE THREAD_FUNC_CALL_TYPE
+
+HRes Thread_Create(CThread *thread, THREAD_FUNC_RET_TYPE (THREAD_FUNC_CALL_TYPE *startAddress)(void *), LPVOID parameter);
+HRes Thread_Wait(CThread *thread);
+HRes Thread_Close(CThread *thread);
+
+typedef struct _CEvent
+{
+  HANDLE handle;
+} CEvent;
+
+typedef CEvent CAutoResetEvent;
+typedef CEvent CManualResetEvent;
+
+#define Event_Construct(event) (event)->handle = NULL
+#define Event_IsCreated(event) ((event)->handle != NULL)
+
+HRes ManualResetEvent_Create(CManualResetEvent *event, int initialSignaled);
+HRes ManualResetEvent_CreateNotSignaled(CManualResetEvent *event);
+HRes AutoResetEvent_Create(CAutoResetEvent *event, int initialSignaled);
+HRes AutoResetEvent_CreateNotSignaled(CAutoResetEvent *event);
+HRes Event_Set(CEvent *event);
+HRes Event_Reset(CEvent *event);
+HRes Event_Wait(CEvent *event);
+HRes Event_Close(CEvent *event);
+
+
+typedef struct _CSemaphore
+{
+  HANDLE handle;
+} CSemaphore;
+
+#define Semaphore_Construct(p) (p)->handle = NULL
+
+HRes Semaphore_Create(CSemaphore *p, UInt32 initiallyCount, UInt32 maxCount);
+HRes Semaphore_ReleaseN(CSemaphore *p, UInt32 num);
+HRes Semaphore_Release1(CSemaphore *p);
+HRes Semaphore_Wait(CSemaphore *p);
+HRes Semaphore_Close(CSemaphore *p);
+
+
+typedef CRITICAL_SECTION CCriticalSection;
+
+HRes CriticalSection_Init(CCriticalSection *p);
+#define CriticalSection_Delete(p) DeleteCriticalSection(p)
+#define CriticalSection_Enter(p) EnterCriticalSection(p)
+#define CriticalSection_Leave(p) LeaveCriticalSection(p)
+
+#endif
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/misc/libphysfs/lzma/C/Types.h	Mon Apr 10 12:06:43 2017 -0400
@@ -0,0 +1,100 @@
+/* 7zTypes.h */
+
+#ifndef __C_TYPES_H
+#define __C_TYPES_H
+
+#ifndef _7ZIP_BYTE_DEFINED
+#define _7ZIP_BYTE_DEFINED
+typedef unsigned char Byte;
+#endif 
+
+#ifndef _7ZIP_UINT16_DEFINED
+#define _7ZIP_UINT16_DEFINED
+typedef unsigned short UInt16;
+#endif 
+
+#ifndef _7ZIP_UINT32_DEFINED
+#define _7ZIP_UINT32_DEFINED
+#ifdef _LZMA_UINT32_IS_ULONG
+typedef unsigned long UInt32;
+#else
+typedef unsigned int UInt32;
+#endif
+#endif 
+
+#ifndef _7ZIP_INT32_DEFINED
+#define _7ZIP_INT32_DEFINED
+#ifdef _LZMA_INT32_IS_ULONG
+typedef long Int32;
+#else
+typedef int Int32;
+#endif
+#endif 
+
+/* #define _SZ_NO_INT_64 */
+/* define it your compiler doesn't support long long int */
+
+#ifndef _7ZIP_UINT64_DEFINED
+#define _7ZIP_UINT64_DEFINED
+#ifdef _SZ_NO_INT_64
+typedef unsigned long UInt64;
+#else
+#if defined(_MSC_VER) || defined(__BORLANDC__)
+typedef unsigned __int64 UInt64;
+#else
+typedef unsigned long long int UInt64;
+#endif
+#endif
+#endif
+
+
+/* #define _SZ_FILE_SIZE_32 */
+/* You can define _SZ_FILE_SIZE_32, if you don't need support for files larger than 4 GB*/
+
+#ifndef CFileSize
+#ifdef _SZ_FILE_SIZE_32
+typedef UInt32 CFileSize; 
+#else
+typedef UInt64 CFileSize; 
+#endif
+#endif
+
+#define SZ_RESULT int
+
+typedef int HRes;
+#define RES_OK (0)
+
+#define SZ_OK (0)
+#define SZE_DATA_ERROR (1)
+#define SZE_CRC_ERROR (3)
+#define SZE_ARCHIVE_ERROR (6)
+
+#define SZE_OUTOFMEMORY (0x8007000EL)
+#define SZE_NOTIMPL (0x80004001L)
+#define SZE_FAIL (0x80004005L)
+#define SZE_INVALIDARG (0x80070057L)
+
+
+#ifndef RINOK
+#define RINOK(x) { HRes __result_ = (x); if(__result_ != 0) return __result_; }
+#endif
+
+typedef int Bool;
+#define True 1
+#define False 0
+
+#ifdef _MSC_VER
+#define StdCall __stdcall 
+#else
+#define StdCall
+#endif
+
+#if _MSC_VER >= 1300
+#define MY_FAST_CALL __declspec(noinline) __fastcall 
+#elif defined( _MSC_VER)
+#define MY_FAST_CALL __fastcall 
+#else
+#define MY_FAST_CALL
+#endif
+
+#endif
Binary file misc/libphysfs/lzma/CPP/7zip/Archive/7z/7z.ico has changed
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/misc/libphysfs/lzma/CPP/7zip/Archive/7z/7zCompressionMode.cpp	Mon Apr 10 12:06:43 2017 -0400
@@ -0,0 +1,3 @@
+// CompressionMethod.cpp
+
+#include "StdAfx.h"
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/misc/libphysfs/lzma/CPP/7zip/Archive/7z/7zCompressionMode.h	Mon Apr 10 12:06:43 2017 -0400
@@ -0,0 +1,50 @@
+// 7zCompressionMode.h
+
+#ifndef __7Z_COMPRESSION_MODE_H
+#define __7Z_COMPRESSION_MODE_H
+
+#include "../../../Common/MyString.h"
+
+#include "../../../Windows/PropVariant.h"
+
+#include "../../Common/MethodProps.h"
+
+namespace NArchive {
+namespace N7z {
+
+struct CMethodFull: public CMethod
+{
+  UInt32 NumInStreams;
+  UInt32 NumOutStreams;
+  bool IsSimpleCoder() const { return (NumInStreams == 1) && (NumOutStreams == 1); }
+};
+
+struct CBind
+{
+  UInt32 InCoder;
+  UInt32 InStream;
+  UInt32 OutCoder;
+  UInt32 OutStream;
+};
+
+struct CCompressionMethodMode
+{
+  CObjectVector<CMethodFull> Methods;
+  CRecordVector<CBind> Binds;
+  #ifdef COMPRESS_MT
+  UInt32 NumThreads;
+  #endif
+  bool PasswordIsDefined;
+  UString Password;
+
+  bool IsEmpty() const { return (Methods.IsEmpty() && !PasswordIsDefined); }
+  CCompressionMethodMode(): PasswordIsDefined(false)
+      #ifdef COMPRESS_MT
+      , NumThreads(1) 
+      #endif
+  {}
+};
+
+}}
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/misc/libphysfs/lzma/CPP/7zip/Archive/7z/7zDecode.cpp	Mon Apr 10 12:06:43 2017 -0400
@@ -0,0 +1,330 @@
+// 7zDecode.cpp
+
+#include "StdAfx.h"
+
+#include "7zDecode.h"
+
+#include "../../IPassword.h"
+#include "../../Common/LockedStream.h"
+#include "../../Common/StreamObjects.h"
+#include "../../Common/ProgressUtils.h"
+#include "../../Common/LimitedStreams.h"
+#include "../../Common/CreateCoder.h"
+#include "../../Common/FilterCoder.h"
+
+namespace NArchive {
+namespace N7z {
+
+static void ConvertFolderItemInfoToBindInfo(const CFolder &folder,
+    CBindInfoEx &bindInfo)
+{
+  bindInfo.Clear();
+  int i;
+  for (i = 0; i < folder.BindPairs.Size(); i++)
+  {
+    NCoderMixer::CBindPair bindPair;
+    bindPair.InIndex = (UInt32)folder.BindPairs[i].InIndex;
+    bindPair.OutIndex = (UInt32)folder.BindPairs[i].OutIndex;
+    bindInfo.BindPairs.Add(bindPair);
+  }
+  UInt32 outStreamIndex = 0;
+  for (i = 0; i < folder.Coders.Size(); i++)
+  {
+    NCoderMixer::CCoderStreamsInfo coderStreamsInfo;
+    const CCoderInfo &coderInfo = folder.Coders[i];
+    coderStreamsInfo.NumInStreams = (UInt32)coderInfo.NumInStreams;
+    coderStreamsInfo.NumOutStreams = (UInt32)coderInfo.NumOutStreams;
+    bindInfo.Coders.Add(coderStreamsInfo);
+    bindInfo.CoderMethodIDs.Add(coderInfo.MethodID);
+    for (UInt32 j = 0; j < coderStreamsInfo.NumOutStreams; j++, outStreamIndex++)
+      if (folder.FindBindPairForOutStream(outStreamIndex) < 0)
+        bindInfo.OutStreams.Add(outStreamIndex);
+  }
+  for (i = 0; i < folder.PackStreams.Size(); i++)
+    bindInfo.InStreams.Add((UInt32)folder.PackStreams[i]);
+}
+
+static bool AreCodersEqual(const NCoderMixer::CCoderStreamsInfo &a1, 
+    const NCoderMixer::CCoderStreamsInfo &a2)
+{
+  return (a1.NumInStreams == a2.NumInStreams) &&
+    (a1.NumOutStreams == a2.NumOutStreams);
+}
+
+static bool AreBindPairsEqual(const NCoderMixer::CBindPair &a1, const NCoderMixer::CBindPair &a2)
+{
+  return (a1.InIndex == a2.InIndex) &&
+    (a1.OutIndex == a2.OutIndex);
+}
+
+static bool AreBindInfoExEqual(const CBindInfoEx &a1, const CBindInfoEx &a2)
+{
+  if (a1.Coders.Size() != a2.Coders.Size())
+    return false;
+  int i;
+  for (i = 0; i < a1.Coders.Size(); i++)
+    if (!AreCodersEqual(a1.Coders[i], a2.Coders[i]))
+      return false;
+  if (a1.BindPairs.Size() != a2.BindPairs.Size())
+    return false;
+  for (i = 0; i < a1.BindPairs.Size(); i++)
+    if (!AreBindPairsEqual(a1.BindPairs[i], a2.BindPairs[i]))
+      return false;
+  for (i = 0; i < a1.CoderMethodIDs.Size(); i++)
+    if (a1.CoderMethodIDs[i] != a2.CoderMethodIDs[i])
+      return false;
+  if (a1.InStreams.Size() != a2.InStreams.Size())
+    return false;
+  if (a1.OutStreams.Size() != a2.OutStreams.Size())
+    return false;
+  return true;
+}
+
+CDecoder::CDecoder(bool multiThread)
+{
+  #ifndef _ST_MODE
+  multiThread = true;
+  #endif
+  _multiThread = multiThread;
+  _bindInfoExPrevIsDefined = false;
+}
+
+HRESULT CDecoder::Decode(
+    DECL_EXTERNAL_CODECS_LOC_VARS
+    IInStream *inStream,
+    UInt64 startPos,
+    const UInt64 *packSizes,
+    const CFolder &folderInfo, 
+    ISequentialOutStream *outStream,
+    ICompressProgressInfo *compressProgress
+    #ifndef _NO_CRYPTO
+    , ICryptoGetTextPassword *getTextPassword
+    #endif
+    #ifdef COMPRESS_MT
+    , bool mtMode, UInt32 numThreads
+    #endif
+    )
+{
+  CObjectVector< CMyComPtr<ISequentialInStream> > inStreams;
+  
+  CLockedInStream lockedInStream;
+  lockedInStream.Init(inStream);
+  
+  for (int j = 0; j < folderInfo.PackStreams.Size(); j++)
+  {
+    CLockedSequentialInStreamImp *lockedStreamImpSpec = new 
+        CLockedSequentialInStreamImp;
+    CMyComPtr<ISequentialInStream> lockedStreamImp = lockedStreamImpSpec;
+    lockedStreamImpSpec->Init(&lockedInStream, startPos);
+    startPos += packSizes[j];
+    
+    CLimitedSequentialInStream *streamSpec = new 
+        CLimitedSequentialInStream;
+    CMyComPtr<ISequentialInStream> inStream = streamSpec;
+    streamSpec->SetStream(lockedStreamImp);
+    streamSpec->Init(packSizes[j]);
+    inStreams.Add(inStream);
+  }
+  
+  int numCoders = folderInfo.Coders.Size();
+  
+  CBindInfoEx bindInfo;
+  ConvertFolderItemInfoToBindInfo(folderInfo, bindInfo);
+  bool createNewCoders;
+  if (!_bindInfoExPrevIsDefined)
+    createNewCoders = true;
+  else
+    createNewCoders = !AreBindInfoExEqual(bindInfo, _bindInfoExPrev);
+  if (createNewCoders)
+  {
+    int i;
+    _decoders.Clear();
+    // _decoders2.Clear();
+    
+    _mixerCoder.Release();
+
+    if (_multiThread)
+    {
+      _mixerCoderMTSpec = new NCoderMixer::CCoderMixer2MT;
+      _mixerCoder = _mixerCoderMTSpec;
+      _mixerCoderCommon = _mixerCoderMTSpec;
+    }
+    else
+    {
+      #ifdef _ST_MODE
+      _mixerCoderSTSpec = new NCoderMixer::CCoderMixer2ST;
+      _mixerCoder = _mixerCoderSTSpec;
+      _mixerCoderCommon = _mixerCoderSTSpec;
+      #endif
+    }
+    RINOK(_mixerCoderCommon->SetBindInfo(bindInfo));
+    
+    for (i = 0; i < numCoders; i++)
+    {
+      const CCoderInfo &coderInfo = folderInfo.Coders[i];
+
+  
+      CMyComPtr<ICompressCoder> decoder;
+      CMyComPtr<ICompressCoder2> decoder2;
+      RINOK(CreateCoder(
+          EXTERNAL_CODECS_LOC_VARS
+          coderInfo.MethodID, decoder, decoder2, false));
+      CMyComPtr<IUnknown> decoderUnknown;
+      if (coderInfo.IsSimpleCoder())
+      {
+        if (decoder == 0)
+          return E_NOTIMPL;
+
+        decoderUnknown = (IUnknown *)decoder;
+        
+        if (_multiThread)
+          _mixerCoderMTSpec->AddCoder(decoder);
+        #ifdef _ST_MODE
+        else
+          _mixerCoderSTSpec->AddCoder(decoder, false);
+        #endif
+      }
+      else
+      {
+        if (decoder2 == 0)
+          return E_NOTIMPL;
+        decoderUnknown = (IUnknown *)decoder2;
+        if (_multiThread)
+          _mixerCoderMTSpec->AddCoder2(decoder2);
+        #ifdef _ST_MODE
+        else
+          _mixerCoderSTSpec->AddCoder2(decoder2, false);
+        #endif
+      }
+      _decoders.Add(decoderUnknown);
+      #ifdef EXTERNAL_CODECS
+      CMyComPtr<ISetCompressCodecsInfo> setCompressCodecsInfo;
+      decoderUnknown.QueryInterface(IID_ISetCompressCodecsInfo, (void **)&setCompressCodecsInfo);
+      if (setCompressCodecsInfo)
+      {
+        RINOK(setCompressCodecsInfo->SetCompressCodecsInfo(codecsInfo));
+      }
+      #endif
+    }
+    _bindInfoExPrev = bindInfo;
+    _bindInfoExPrevIsDefined = true;
+  }
+  int i;
+  _mixerCoderCommon->ReInit();
+  
+  UInt32 packStreamIndex = 0, unPackStreamIndex = 0;
+  UInt32 coderIndex = 0;
+  // UInt32 coder2Index = 0;
+  
+  for (i = 0; i < numCoders; i++)
+  {
+    const CCoderInfo &coderInfo = folderInfo.Coders[i];
+    CMyComPtr<IUnknown> &decoder = _decoders[coderIndex];
+    
+    {
+      CMyComPtr<ICompressSetDecoderProperties2> setDecoderProperties;
+      decoder.QueryInterface(IID_ICompressSetDecoderProperties2, &setDecoderProperties);
+      if (setDecoderProperties)
+      {
+        const CByteBuffer &properties = coderInfo.Properties;
+        size_t size = properties.GetCapacity();
+        if (size > 0xFFFFFFFF)
+          return E_NOTIMPL;
+        if (size > 0)
+        {
+          RINOK(setDecoderProperties->SetDecoderProperties2((const Byte *)properties, (UInt32)size));
+        }
+      }
+    }
+
+    #ifdef COMPRESS_MT
+    if (mtMode)
+    {
+      CMyComPtr<ICompressSetCoderMt> setCoderMt;
+      decoder.QueryInterface(IID_ICompressSetCoderMt, &setCoderMt);
+      if (setCoderMt)
+      {
+        RINOK(setCoderMt->SetNumberOfThreads(numThreads));
+      }
+    }
+    #endif
+
+    #ifndef _NO_CRYPTO
+    {
+      CMyComPtr<ICryptoSetPassword> cryptoSetPassword;
+      decoder.QueryInterface(IID_ICryptoSetPassword, &cryptoSetPassword);
+      if (cryptoSetPassword)
+      {
+        if (getTextPassword == 0)
+          return E_FAIL;
+        CMyComBSTR password;
+        RINOK(getTextPassword->CryptoGetTextPassword(&password));
+        CByteBuffer buffer;
+        UString unicodePassword(password);
+        const UInt32 sizeInBytes = unicodePassword.Length() * 2;
+        buffer.SetCapacity(sizeInBytes);
+        for (int i = 0; i < unicodePassword.Length(); i++)
+        {
+          wchar_t c = unicodePassword[i];
+          ((Byte *)buffer)[i * 2] = (Byte)c;
+          ((Byte *)buffer)[i * 2 + 1] = (Byte)(c >> 8);
+        }
+        RINOK(cryptoSetPassword->CryptoSetPassword(
+          (const Byte *)buffer, sizeInBytes));
+      }
+    }
+    #endif
+
+    coderIndex++;
+    
+    UInt32 numInStreams = (UInt32)coderInfo.NumInStreams;
+    UInt32 numOutStreams = (UInt32)coderInfo.NumOutStreams;
+    CRecordVector<const UInt64 *> packSizesPointers;
+    CRecordVector<const UInt64 *> unPackSizesPointers;
+    packSizesPointers.Reserve(numInStreams);
+    unPackSizesPointers.Reserve(numOutStreams);
+    UInt32 j;
+    for (j = 0; j < numOutStreams; j++, unPackStreamIndex++)
+      unPackSizesPointers.Add(&folderInfo.UnPackSizes[unPackStreamIndex]);
+    
+    for (j = 0; j < numInStreams; j++, packStreamIndex++)
+    {
+      int bindPairIndex = folderInfo.FindBindPairForInStream(packStreamIndex);
+      if (bindPairIndex >= 0)
+        packSizesPointers.Add(
+        &folderInfo.UnPackSizes[(UInt32)folderInfo.BindPairs[bindPairIndex].OutIndex]);
+      else
+      {
+        int index = folderInfo.FindPackStreamArrayIndex(packStreamIndex);
+        if (index < 0)
+          return E_FAIL;
+        packSizesPointers.Add(&packSizes[index]);
+      }
+    }
+    
+    _mixerCoderCommon->SetCoderInfo(i, 
+        &packSizesPointers.Front(), 
+        &unPackSizesPointers.Front());
+  }
+  UInt32 mainCoder, temp;
+  bindInfo.FindOutStream(bindInfo.OutStreams[0], mainCoder, temp);
+
+  if (_multiThread)
+    _mixerCoderMTSpec->SetProgressCoderIndex(mainCoder);
+  /*
+  else
+    _mixerCoderSTSpec->SetProgressCoderIndex(mainCoder);;
+  */
+  
+  if (numCoders == 0)
+    return 0;
+  CRecordVector<ISequentialInStream *> inStreamPointers;
+  inStreamPointers.Reserve(inStreams.Size());
+  for (i = 0; i < inStreams.Size(); i++)
+    inStreamPointers.Add(inStreams[i]);
+  ISequentialOutStream *outStreamPointer = outStream;
+  return _mixerCoder->Code(&inStreamPointers.Front(), NULL, 
+    inStreams.Size(), &outStreamPointer, NULL, 1, compressProgress);
+}
+
+}}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/misc/libphysfs/lzma/CPP/7zip/Archive/7z/7zDecode.h	Mon Apr 10 12:06:43 2017 -0400
@@ -0,0 +1,68 @@
+// 7zDecode.h
+
+#ifndef __7Z_DECODE_H
+#define __7Z_DECODE_H
+
+#include "../../IStream.h"
+#include "../../IPassword.h"
+
+#include "../Common/CoderMixer2.h"
+#include "../Common/CoderMixer2MT.h"
+#ifdef _ST_MODE
+#include "../Common/CoderMixer2ST.h"
+#endif
+
+#include "../../Common/CreateCoder.h"
+
+#include "7zItem.h"
+
+namespace NArchive {
+namespace N7z {
+
+struct CBindInfoEx: public NCoderMixer::CBindInfo
+{
+  CRecordVector<CMethodId> CoderMethodIDs;
+  void Clear()
+  {
+    CBindInfo::Clear();
+    CoderMethodIDs.Clear();
+  }
+};
+
+class CDecoder
+{
+  bool _bindInfoExPrevIsDefined;
+  CBindInfoEx _bindInfoExPrev;
+  
+  bool _multiThread;
+  #ifdef _ST_MODE
+  NCoderMixer::CCoderMixer2ST *_mixerCoderSTSpec;
+  #endif
+  NCoderMixer::CCoderMixer2MT *_mixerCoderMTSpec;
+  NCoderMixer::CCoderMixer2 *_mixerCoderCommon;
+  
+  CMyComPtr<ICompressCoder2> _mixerCoder;
+  CObjectVector<CMyComPtr<IUnknown> > _decoders;
+  // CObjectVector<CMyComPtr<ICompressCoder2> > _decoders2;
+public:
+  CDecoder(bool multiThread);
+  HRESULT Decode(
+      DECL_EXTERNAL_CODECS_LOC_VARS
+      IInStream *inStream,
+      UInt64 startPos,
+      const UInt64 *packSizes,
+      const CFolder &folder, 
+      ISequentialOutStream *outStream,
+      ICompressProgressInfo *compressProgress
+      #ifndef _NO_CRYPTO
+      , ICryptoGetTextPassword *getTextPasswordSpec
+      #endif
+      #ifdef COMPRESS_MT
+      , bool mtMode, UInt32 numThreads
+      #endif
+      );
+};
+
+}}
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/misc/libphysfs/lzma/CPP/7zip/Archive/7z/7zEncode.cpp	Mon Apr 10 12:06:43 2017 -0400
@@ -0,0 +1,453 @@
+// Encode.cpp
+
+#include "StdAfx.h"
+
+#include "7zEncode.h"
+#include "7zSpecStream.h"
+
+#include "../../IPassword.h"
+#include "../../Common/ProgressUtils.h"
+#include "../../Common/LimitedStreams.h"
+#include "../../Common/InOutTempBuffer.h"
+#include "../../Common/StreamObjects.h"
+#include "../../Common/CreateCoder.h"
+#include "../../Common/FilterCoder.h"
+
+static const UInt64 k_AES = 0x06F10701;
+static const UInt64 k_BCJ  = 0x03030103;
+static const UInt64 k_BCJ2 = 0x0303011B;
+
+namespace NArchive {
+namespace N7z {
+
+static void ConvertBindInfoToFolderItemInfo(const NCoderMixer::CBindInfo &bindInfo,
+    const CRecordVector<CMethodId> decompressionMethods,
+    CFolder &folder)
+{
+  folder.Coders.Clear();
+  // bindInfo.CoderMethodIDs.Clear();
+  // folder.OutStreams.Clear();
+  folder.PackStreams.Clear();
+  folder.BindPairs.Clear();
+  int i;
+  for (i = 0; i < bindInfo.BindPairs.Size(); i++)
+  {
+    CBindPair bindPair;
+    bindPair.InIndex = bindInfo.BindPairs[i].InIndex;
+    bindPair.OutIndex = bindInfo.BindPairs[i].OutIndex;
+    folder.BindPairs.Add(bindPair);
+  }
+  for (i = 0; i < bindInfo.Coders.Size(); i++)
+  {
+    CCoderInfo coderInfo;
+    const NCoderMixer::CCoderStreamsInfo &coderStreamsInfo = bindInfo.Coders[i];
+    coderInfo.NumInStreams = coderStreamsInfo.NumInStreams;
+    coderInfo.NumOutStreams = coderStreamsInfo.NumOutStreams;
+    coderInfo.MethodID = decompressionMethods[i];
+    folder.Coders.Add(coderInfo);
+  }
+  for (i = 0; i < bindInfo.InStreams.Size(); i++)
+    folder.PackStreams.Add(bindInfo.InStreams[i]);
+}
+
+HRESULT CEncoder::CreateMixerCoder(
+    DECL_EXTERNAL_CODECS_LOC_VARS
+    const UInt64 *inSizeForReduce)
+{
+  _mixerCoderSpec = new NCoderMixer::CCoderMixer2MT;
+  _mixerCoder = _mixerCoderSpec;
+  RINOK(_mixerCoderSpec->SetBindInfo(_bindInfo));
+  for (int i = 0; i < _options.Methods.Size(); i++)
+  {
+    const CMethodFull &methodFull = _options.Methods[i];
+    _codersInfo.Add(CCoderInfo());
+    CCoderInfo &encodingInfo = _codersInfo.Back();
+    encodingInfo.MethodID = methodFull.Id;
+    CMyComPtr<ICompressCoder> encoder;
+    CMyComPtr<ICompressCoder2> encoder2;
+    
+
+    RINOK(CreateCoder(
+        EXTERNAL_CODECS_LOC_VARS
+        methodFull.Id, encoder, encoder2, true));
+
+    if (!encoder && !encoder2)
+      return E_FAIL;
+
+    CMyComPtr<IUnknown> encoderCommon = encoder ? (IUnknown *)encoder : (IUnknown *)encoder2;
+   
+    #ifdef COMPRESS_MT
+    {
+      CMyComPtr<ICompressSetCoderMt> setCoderMt;
+      encoderCommon.QueryInterface(IID_ICompressSetCoderMt, &setCoderMt);
+      if (setCoderMt)
+      {
+        RINOK(setCoderMt->SetNumberOfThreads(_options.NumThreads));
+      }
+    }
+    #endif
+        
+
+    RINOK(SetMethodProperties(methodFull, inSizeForReduce, encoderCommon));
+
+    /*
+    CMyComPtr<ICryptoResetSalt> resetSalt;
+    encoderCommon.QueryInterface(IID_ICryptoResetSalt, (void **)&resetSalt);
+    if (resetSalt != NULL)
+    {
+      resetSalt->ResetSalt();
+    }
+    */
+
+    #ifdef EXTERNAL_CODECS
+    CMyComPtr<ISetCompressCodecsInfo> setCompressCodecsInfo;
+    encoderCommon.QueryInterface(IID_ISetCompressCodecsInfo, (void **)&setCompressCodecsInfo);
+    if (setCompressCodecsInfo)
+    {
+      RINOK(setCompressCodecsInfo->SetCompressCodecsInfo(codecsInfo));
+    }
+    #endif
+    
+    CMyComPtr<ICryptoSetPassword> cryptoSetPassword;
+    encoderCommon.QueryInterface(IID_ICryptoSetPassword, &cryptoSetPassword);
+
+    if (cryptoSetPassword)
+    {
+      CByteBuffer buffer;
+      const UInt32 sizeInBytes = _options.Password.Length() * 2;
+      buffer.SetCapacity(sizeInBytes);
+      for (int i = 0; i < _options.Password.Length(); i++)
+      {
+        wchar_t c = _options.Password[i];
+        ((Byte *)buffer)[i * 2] = (Byte)c;
+        ((Byte *)buffer)[i * 2 + 1] = (Byte)(c >> 8);
+      }
+      RINOK(cryptoSetPassword->CryptoSetPassword((const Byte *)buffer, sizeInBytes));
+    }
+
+    if (encoder)
+      _mixerCoderSpec->AddCoder(encoder);
+    else
+      _mixerCoderSpec->AddCoder2(encoder2);
+  }
+  return S_OK;
+}
+
+HRESULT CEncoder::Encode(
+    DECL_EXTERNAL_CODECS_LOC_VARS
+    ISequentialInStream *inStream,
+    const UInt64 *inStreamSize, const UInt64 *inSizeForReduce,
+    CFolder &folderItem,
+    ISequentialOutStream *outStream,
+    CRecordVector<UInt64> &packSizes,
+    ICompressProgressInfo *compressProgress)
+{
+  RINOK(EncoderConstr());
+
+  if (_mixerCoderSpec == NULL)
+  {
+    RINOK(CreateMixerCoder(EXTERNAL_CODECS_LOC_VARS inSizeForReduce));
+  }
+  _mixerCoderSpec->ReInit();
+  // _mixerCoderSpec->SetCoderInfo(0, NULL, NULL, progress);
+
+  CObjectVector<CInOutTempBuffer> inOutTempBuffers;
+  CObjectVector<CSequentialOutTempBufferImp *> tempBufferSpecs;
+  CObjectVector<CMyComPtr<ISequentialOutStream> > tempBuffers;
+  int numMethods = _bindInfo.Coders.Size();
+  int i;
+  for (i = 1; i < _bindInfo.OutStreams.Size(); i++)
+  {
+    inOutTempBuffers.Add(CInOutTempBuffer());
+    inOutTempBuffers.Back().Create();
+    inOutTempBuffers.Back().InitWriting();
+  }
+  for (i = 1; i < _bindInfo.OutStreams.Size(); i++)
+  {
+    CSequentialOutTempBufferImp *tempBufferSpec = 
+        new CSequentialOutTempBufferImp;
+    CMyComPtr<ISequentialOutStream> tempBuffer = tempBufferSpec;
+    tempBufferSpec->Init(&inOutTempBuffers[i - 1]);
+    tempBuffers.Add(tempBuffer);
+    tempBufferSpecs.Add(tempBufferSpec);
+  }
+
+  for (i = 0; i < numMethods; i++)
+    _mixerCoderSpec->SetCoderInfo(i, NULL, NULL);
+
+  if (_bindInfo.InStreams.IsEmpty())
+    return E_FAIL;
+  UInt32 mainCoderIndex, mainStreamIndex;
+  _bindInfo.FindInStream(_bindInfo.InStreams[0], mainCoderIndex, mainStreamIndex);
+  
+  if (inStreamSize != NULL)
+  {
+    CRecordVector<const UInt64 *> sizePointers;
+    for (UInt32 i = 0; i < _bindInfo.Coders[mainCoderIndex].NumInStreams; i++)
+      if (i == mainStreamIndex)
+        sizePointers.Add(inStreamSize);
+      else
+        sizePointers.Add(NULL);
+    _mixerCoderSpec->SetCoderInfo(mainCoderIndex, &sizePointers.Front(), NULL);
+  }
+
+  
+  // UInt64 outStreamStartPos;
+  // RINOK(stream->Seek(0, STREAM_SEEK_CUR, &outStreamStartPos));
+  
+  CSequentialInStreamSizeCount2 *inStreamSizeCountSpec = 
+      new CSequentialInStreamSizeCount2;
+  CMyComPtr<ISequentialInStream> inStreamSizeCount = inStreamSizeCountSpec;
+  CSequentialOutStreamSizeCount *outStreamSizeCountSpec = 
+      new CSequentialOutStreamSizeCount;
+  CMyComPtr<ISequentialOutStream> outStreamSizeCount = outStreamSizeCountSpec;
+
+  inStreamSizeCountSpec->Init(inStream);
+  outStreamSizeCountSpec->SetStream(outStream);
+  outStreamSizeCountSpec->Init();
+
+  CRecordVector<ISequentialInStream *> inStreamPointers;
+  CRecordVector<ISequentialOutStream *> outStreamPointers;
+  inStreamPointers.Add(inStreamSizeCount);
+  outStreamPointers.Add(outStreamSizeCount);
+  for (i = 1; i < _bindInfo.OutStreams.Size(); i++)
+    outStreamPointers.Add(tempBuffers[i - 1]);
+
+  for (i = 0; i < _codersInfo.Size(); i++)
+  {
+    CCoderInfo &encodingInfo = _codersInfo[i];
+    
+    CMyComPtr<ICryptoResetInitVector> resetInitVector;
+    _mixerCoderSpec->_coders[i].QueryInterface(IID_ICryptoResetInitVector, (void **)&resetInitVector);
+    if (resetInitVector != NULL)
+    {
+      resetInitVector->ResetInitVector();
+    }
+
+    CMyComPtr<ICompressWriteCoderProperties> writeCoderProperties;
+    _mixerCoderSpec->_coders[i].QueryInterface(IID_ICompressWriteCoderProperties, (void **)&writeCoderProperties);
+    if (writeCoderProperties != NULL)
+    {
+      CSequentialOutStreamImp *outStreamSpec = new CSequentialOutStreamImp;
+      CMyComPtr<ISequentialOutStream> outStream(outStreamSpec);
+      outStreamSpec->Init();
+      writeCoderProperties->WriteCoderProperties(outStream);
+      size_t size = outStreamSpec->GetSize();
+      encodingInfo.Properties.SetCapacity(size);
+      memmove(encodingInfo.Properties, outStreamSpec->GetBuffer(), size);
+    }
+  }
+
+  UInt32 progressIndex = mainCoderIndex;
+
+  for (i = 0; i < _codersInfo.Size(); i++)
+  {
+    const CCoderInfo &e = _codersInfo[i];
+    if ((e.MethodID == k_BCJ || e.MethodID == k_BCJ2) && i + 1 < _codersInfo.Size())
+      progressIndex = i + 1;
+  }
+
+  _mixerCoderSpec->SetProgressCoderIndex(progressIndex);
+  
+  RINOK(_mixerCoder->Code(&inStreamPointers.Front(), NULL, 1,
+    &outStreamPointers.Front(), NULL, outStreamPointers.Size(), compressProgress));
+  
+  ConvertBindInfoToFolderItemInfo(_decompressBindInfo, _decompressionMethods,
+      folderItem);
+  
+  packSizes.Add(outStreamSizeCountSpec->GetSize());
+  
+  for (i = 1; i < _bindInfo.OutStreams.Size(); i++)
+  {
+    CInOutTempBuffer &inOutTempBuffer = inOutTempBuffers[i - 1];
+    inOutTempBuffer.FlushWrite();
+    inOutTempBuffer.InitReading();
+    inOutTempBuffer.WriteToStream(outStream);
+    packSizes.Add(inOutTempBuffer.GetDataSize());
+  }
+  
+  for (i = 0; i < (int)_bindReverseConverter->NumSrcInStreams; i++)
+  {
+    int binder = _bindInfo.FindBinderForInStream(
+        _bindReverseConverter->DestOutToSrcInMap[i]);
+    UInt64 streamSize;
+    if (binder < 0)
+      streamSize = inStreamSizeCountSpec->GetSize();
+    else
+      streamSize = _mixerCoderSpec->GetWriteProcessedSize(binder);
+    folderItem.UnPackSizes.Add(streamSize);
+  }
+  for (i = numMethods - 1; i >= 0; i--)
+    folderItem.Coders[numMethods - 1 - i].Properties = _codersInfo[i].Properties;
+  return S_OK;
+}
+
+
+CEncoder::CEncoder(const CCompressionMethodMode &options):
+  _bindReverseConverter(0),
+  _constructed(false)
+{
+  if (options.IsEmpty())
+    throw 1;
+
+  _options = options;
+  _mixerCoderSpec = NULL;
+}
+
+HRESULT CEncoder::EncoderConstr()
+{
+  if (_constructed)
+    return S_OK;
+  if (_options.Methods.IsEmpty())
+  {
+    // it has only password method;
+    if (!_options.PasswordIsDefined)
+      throw 1;
+    if (!_options.Binds.IsEmpty())
+      throw 1;
+    NCoderMixer::CCoderStreamsInfo coderStreamsInfo;
+    CMethodFull method;
+    
+    method.NumInStreams = 1;
+    method.NumOutStreams = 1;
+    coderStreamsInfo.NumInStreams = 1;
+    coderStreamsInfo.NumOutStreams = 1;
+    method.Id = k_AES;
+    
+    _options.Methods.Add(method);
+    _bindInfo.Coders.Add(coderStreamsInfo);
+  
+    _bindInfo.InStreams.Add(0);
+    _bindInfo.OutStreams.Add(0);
+  }
+  else
+  {
+
+  UInt32 numInStreams = 0, numOutStreams = 0;
+  int i;
+  for (i = 0; i < _options.Methods.Size(); i++)
+  {
+    const CMethodFull &methodFull = _options.Methods[i];
+    NCoderMixer::CCoderStreamsInfo coderStreamsInfo;
+    coderStreamsInfo.NumInStreams = methodFull.NumOutStreams;
+    coderStreamsInfo.NumOutStreams = methodFull.NumInStreams;
+    if (_options.Binds.IsEmpty())
+    {
+      if (i < _options.Methods.Size() - 1)
+      {
+        NCoderMixer::CBindPair bindPair;
+        bindPair.InIndex = numInStreams + coderStreamsInfo.NumInStreams;
+        bindPair.OutIndex = numOutStreams;
+        _bindInfo.BindPairs.Add(bindPair);
+      }
+      else
+        _bindInfo.OutStreams.Insert(0, numOutStreams);
+      for (UInt32 j = 1; j < coderStreamsInfo.NumOutStreams; j++)
+        _bindInfo.OutStreams.Add(numOutStreams + j);
+    }
+    
+    numInStreams += coderStreamsInfo.NumInStreams;
+    numOutStreams += coderStreamsInfo.NumOutStreams;
+
+    _bindInfo.Coders.Add(coderStreamsInfo);
+  }
+
+  if (!_options.Binds.IsEmpty())
+  {
+    for (i = 0; i < _options.Binds.Size(); i++)
+    {
+      NCoderMixer::CBindPair bindPair;
+      const CBind &bind = _options.Binds[i];
+      bindPair.InIndex = _bindInfo.GetCoderInStreamIndex(bind.InCoder) + bind.InStream;
+      bindPair.OutIndex = _bindInfo.GetCoderOutStreamIndex(bind.OutCoder) + bind.OutStream;
+      _bindInfo.BindPairs.Add(bindPair);
+    }
+    for (i = 0; i < (int)numOutStreams; i++)
+      if (_bindInfo.FindBinderForOutStream(i) == -1)
+        _bindInfo.OutStreams.Add(i);
+  }
+
+  for (i = 0; i < (int)numInStreams; i++)
+    if (_bindInfo.FindBinderForInStream(i) == -1)
+      _bindInfo.InStreams.Add(i);
+
+  if (_bindInfo.InStreams.IsEmpty())
+    throw 1; // this is error
+
+  // Make main stream first in list
+  int inIndex = _bindInfo.InStreams[0];
+  for (;;)
+  {
+    UInt32 coderIndex, coderStreamIndex;
+    _bindInfo.FindInStream(inIndex, coderIndex, coderStreamIndex);
+    UInt32 outIndex = _bindInfo.GetCoderOutStreamIndex(coderIndex);
+    int binder = _bindInfo.FindBinderForOutStream(outIndex);
+    if (binder >= 0)
+    {
+      inIndex = _bindInfo.BindPairs[binder].InIndex;
+      continue;
+    }
+    for (i = 0; i < _bindInfo.OutStreams.Size(); i++)
+      if (_bindInfo.OutStreams[i] == outIndex)
+      {
+        _bindInfo.OutStreams.Delete(i);
+        _bindInfo.OutStreams.Insert(0, outIndex);
+        break;
+      }
+    break;
+  }
+
+  if (_options.PasswordIsDefined)
+  {
+    int numCryptoStreams = _bindInfo.OutStreams.Size();
+
+    for (i = 0; i < numCryptoStreams; i++)
+    {
+      NCoderMixer::CBindPair bindPair;
+      bindPair.InIndex = numInStreams + i;
+      bindPair.OutIndex = _bindInfo.OutStreams[i];
+      _bindInfo.BindPairs.Add(bindPair);
+    }
+    _bindInfo.OutStreams.Clear();
+
+    /*
+    if (numCryptoStreams == 0)
+      numCryptoStreams = 1;
+    */
+
+    for (i = 0; i < numCryptoStreams; i++)
+    {
+      NCoderMixer::CCoderStreamsInfo coderStreamsInfo;
+      CMethodFull method;
+      method.NumInStreams = 1;
+      method.NumOutStreams = 1;
+      coderStreamsInfo.NumInStreams = method.NumOutStreams;
+      coderStreamsInfo.NumOutStreams = method.NumInStreams;
+      method.Id = k_AES;
+
+      _options.Methods.Add(method);
+      _bindInfo.Coders.Add(coderStreamsInfo);
+      _bindInfo.OutStreams.Add(numOutStreams + i);
+    }
+  }
+
+  }
+
+  for (int i = _options.Methods.Size() - 1; i >= 0; i--)
+  {
+    const CMethodFull &methodFull = _options.Methods[i];
+    _decompressionMethods.Add(methodFull.Id);
+  }
+
+  _bindReverseConverter = new NCoderMixer::CBindReverseConverter(_bindInfo);
+  _bindReverseConverter->CreateReverseBindInfo(_decompressBindInfo);
+  _constructed = true;
+  return S_OK;
+}
+
+CEncoder::~CEncoder()
+{
+  delete _bindReverseConverter;
+}
+
+}}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/misc/libphysfs/lzma/CPP/7zip/Archive/7z/7zEncode.h	Mon Apr 10 12:06:43 2017 -0400
@@ -0,0 +1,55 @@
+// 7zEncode.h
+
+#ifndef __7Z_ENCODE_H
+#define __7Z_ENCODE_H
+
+// #include "../../Common/StreamObjects.h"
+
+#include "7zCompressionMode.h"
+
+#include "../Common/CoderMixer2.h"
+#include "../Common/CoderMixer2MT.h"
+#ifdef _ST_MODE
+#include "../Common/CoderMixer2ST.h"
+#endif
+#include "7zItem.h"
+
+#include "../../Common/CreateCoder.h"
+
+namespace NArchive {
+namespace N7z {
+
+class CEncoder
+{
+  NCoderMixer::CCoderMixer2MT *_mixerCoderSpec;
+  CMyComPtr<ICompressCoder2> _mixerCoder;
+
+  CObjectVector<CCoderInfo> _codersInfo;
+
+  CCompressionMethodMode _options;
+  NCoderMixer::CBindInfo _bindInfo;
+  NCoderMixer::CBindInfo _decompressBindInfo;
+  NCoderMixer::CBindReverseConverter *_bindReverseConverter;
+  CRecordVector<CMethodId> _decompressionMethods;
+
+  HRESULT CreateMixerCoder(DECL_EXTERNAL_CODECS_LOC_VARS
+      const UInt64 *inSizeForReduce);
+
+  bool _constructed;
+public:
+  CEncoder(const CCompressionMethodMode &options);
+  ~CEncoder();
+  HRESULT EncoderConstr();
+  HRESULT Encode(
+      DECL_EXTERNAL_CODECS_LOC_VARS
+      ISequentialInStream *inStream,
+      const UInt64 *inStreamSize, const UInt64 *inSizeForReduce,
+      CFolder &folderItem,
+      ISequentialOutStream *outStream,
+      CRecordVector<UInt64> &packSizes,
+      ICompressProgressInfo *compressProgress);
+};
+
+}}
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/misc/libphysfs/lzma/CPP/7zip/Archive/7z/7zExtract.cpp	Mon Apr 10 12:06:43 2017 -0400
@@ -0,0 +1,269 @@
+// 7zExtract.cpp
+
+#include "StdAfx.h"
+
+#include "7zHandler.h"
+#include "7zFolderOutStream.h"
+#include "7zDecode.h"
+// #include "7z1Decode.h"
+
+#include "../../../Common/ComTry.h"
+#include "../../Common/StreamObjects.h"
+#include "../../Common/ProgressUtils.h"
+#include "../../Common/LimitedStreams.h"
+
+namespace NArchive {
+namespace N7z {
+
+struct CExtractFolderInfo
+{
+  #ifdef _7Z_VOL
+  int VolumeIndex;
+  #endif
+  CNum FileIndex;
+  CNum FolderIndex;
+  CBoolVector ExtractStatuses;
+  UInt64 UnPackSize;
+  CExtractFolderInfo(
+    #ifdef _7Z_VOL
+    int volumeIndex, 
+    #endif
+    CNum fileIndex, CNum folderIndex): 
+    #ifdef _7Z_VOL
+    VolumeIndex(volumeIndex),
+    #endif
+    FileIndex(fileIndex),
+    FolderIndex(folderIndex), 
+    UnPackSize(0) 
+  {
+    if (fileIndex != kNumNoIndex)
+    {
+      ExtractStatuses.Reserve(1);
+      ExtractStatuses.Add(true);
+    }
+  };
+};
+
+STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems,
+    Int32 testModeSpec, IArchiveExtractCallback *extractCallbackSpec)
+{
+  COM_TRY_BEGIN
+  bool testMode = (testModeSpec != 0);
+  CMyComPtr<IArchiveExtractCallback> extractCallback = extractCallbackSpec;
+  UInt64 importantTotalUnPacked = 0;
+
+  bool allFilesMode = (numItems == UInt32(-1));
+  if (allFilesMode)
+    numItems = 
+    #ifdef _7Z_VOL
+    _refs.Size();
+    #else
+    _database.Files.Size();
+    #endif
+
+  if(numItems == 0)
+    return S_OK;
+
+  /*
+  if(_volumes.Size() != 1)
+    return E_FAIL;
+  const CVolume &volume = _volumes.Front();
+  const CArchiveDatabaseEx &_database = volume.Database;
+  IInStream *_inStream = volume.Stream;
+  */
+  
+  CObjectVector<CExtractFolderInfo> extractFolderInfoVector;
+  for(UInt32 ii = 0; ii < numItems; ii++)
+  {
+    // UInt32 fileIndex = allFilesMode ? indexIndex : indices[indexIndex];
+    UInt32 ref2Index = allFilesMode ? ii : indices[ii];
+    // const CRef2 &ref2 = _refs[ref2Index];
+
+    // for(UInt32 ri = 0; ri < ref2.Refs.Size(); ri++)
+    {
+      #ifdef _7Z_VOL
+      // const CRef &ref = ref2.Refs[ri];
+      const CRef &ref = _refs[ref2Index];
+
+      int volumeIndex = ref.VolumeIndex;
+      const CVolume &volume = _volumes[volumeIndex];
+      const CArchiveDatabaseEx &database = volume.Database;
+      UInt32 fileIndex = ref.ItemIndex;
+      #else
+      const CArchiveDatabaseEx &database = _database;
+      UInt32 fileIndex = ref2Index;
+      #endif
+
+      CNum folderIndex = database.FileIndexToFolderIndexMap[fileIndex];
+      if (folderIndex == kNumNoIndex)
+      {
+        extractFolderInfoVector.Add(CExtractFolderInfo(
+            #ifdef _7Z_VOL
+            volumeIndex, 
+            #endif
+            fileIndex, kNumNoIndex));
+        continue;
+      }
+      if (extractFolderInfoVector.IsEmpty() || 
+        folderIndex != extractFolderInfoVector.Back().FolderIndex 
+        #ifdef _7Z_VOL
+        || volumeIndex != extractFolderInfoVector.Back().VolumeIndex
+        #endif
+        )
+      {
+        extractFolderInfoVector.Add(CExtractFolderInfo(
+            #ifdef _7Z_VOL
+            volumeIndex, 
+            #endif
+            kNumNoIndex, folderIndex));
+        const CFolder &folderInfo = database.Folders[folderIndex];
+        UInt64 unPackSize = folderInfo.GetUnPackSize();
+        importantTotalUnPacked += unPackSize;
+        extractFolderInfoVector.Back().UnPackSize = unPackSize;
+      }
+      
+      CExtractFolderInfo &efi = extractFolderInfoVector.Back();
+      
+      // const CFolderInfo &folderInfo = m_dam_Folders[folderIndex];
+      CNum startIndex = database.FolderStartFileIndex[folderIndex];
+      for (CNum index = efi.ExtractStatuses.Size();
+          index <= fileIndex - startIndex; index++)
+      {
+        // UInt64 unPackSize = _database.Files[startIndex + index].UnPackSize;
+        // Count partial_folder_size
+        // efi.UnPackSize += unPackSize;
+        // importantTotalUnPacked += unPackSize;
+        efi.ExtractStatuses.Add(index == fileIndex - startIndex);
+      }
+    }
+  }
+
+  extractCallback->SetTotal(importantTotalUnPacked);
+
+  CDecoder decoder(
+    #ifdef _ST_MODE
+    false
+    #else
+    true
+    #endif
+    );
+  // CDecoder1 decoder;
+
+  UInt64 currentTotalPacked = 0;
+  UInt64 currentTotalUnPacked = 0;
+  UInt64 totalFolderUnPacked;
+  UInt64 totalFolderPacked;
+
+  CLocalProgress *lps = new CLocalProgress;
+  CMyComPtr<ICompressProgressInfo> progress = lps;
+  lps->Init(extractCallback, false);
+
+  for(int i = 0; i < extractFolderInfoVector.Size(); i++, 
+      currentTotalUnPacked += totalFolderUnPacked,
+      currentTotalPacked += totalFolderPacked)
+  {
+    lps->OutSize = currentTotalUnPacked;
+    lps->InSize = currentTotalPacked;
+    RINOK(lps->SetCur());
+    
+    const CExtractFolderInfo &efi = extractFolderInfoVector[i];
+    totalFolderUnPacked = efi.UnPackSize;
+
+    totalFolderPacked = 0;
+
+    CFolderOutStream *folderOutStream = new CFolderOutStream;
+    CMyComPtr<ISequentialOutStream> outStream(folderOutStream);
+
+    #ifdef _7Z_VOL
+    const CVolume &volume = _volumes[efi.VolumeIndex];
+    const CArchiveDatabaseEx &database = volume.Database;
+    #else
+    const CArchiveDatabaseEx &database = _database;
+    #endif
+
+    CNum startIndex;
+    if (efi.FileIndex != kNumNoIndex)
+      startIndex = efi.FileIndex;
+    else
+      startIndex = database.FolderStartFileIndex[efi.FolderIndex];
+
+
+    HRESULT result = folderOutStream->Init(&database, 
+        #ifdef _7Z_VOL
+        volume.StartRef2Index, 
+        #else
+        0,
+        #endif
+        startIndex, 
+        &efi.ExtractStatuses, extractCallback, testMode, _crcSize != 0);
+
+    RINOK(result);
+
+    if (efi.FileIndex != kNumNoIndex)
+      continue;
+
+    CNum folderIndex = efi.FolderIndex;
+    const CFolder &folderInfo = database.Folders[folderIndex];
+
+    totalFolderPacked = _database.GetFolderFullPackSize(folderIndex);
+
+    CNum packStreamIndex = database.FolderStartPackStreamIndex[folderIndex];
+    UInt64 folderStartPackPos = database.GetFolderStreamPos(folderIndex, 0);
+
+    #ifndef _NO_CRYPTO
+    CMyComPtr<ICryptoGetTextPassword> getTextPassword;
+    if (extractCallback)
+      extractCallback.QueryInterface(IID_ICryptoGetTextPassword, &getTextPassword);
+    #endif
+
+    try
+    {
+      HRESULT result = decoder.Decode(
+          EXTERNAL_CODECS_VARS
+          #ifdef _7Z_VOL
+          volume.Stream,
+          #else
+          _inStream,
+          #endif
+          folderStartPackPos, 
+          &database.PackSizes[packStreamIndex],
+          folderInfo,
+          outStream,
+          progress
+          #ifndef _NO_CRYPTO
+          , getTextPassword
+          #endif
+          #ifdef COMPRESS_MT
+          , true, _numThreads
+          #endif
+          );
+
+      if (result == S_FALSE)
+      {
+        RINOK(folderOutStream->FlushCorrupted(NArchive::NExtract::NOperationResult::kDataError));
+        continue;
+      }
+      if (result == E_NOTIMPL)
+      {
+        RINOK(folderOutStream->FlushCorrupted(NArchive::NExtract::NOperationResult::kUnSupportedMethod));
+        continue;
+      }
+      if (result != S_OK)
+        return result;
+      if (folderOutStream->WasWritingFinished() != S_OK)
+      {
+        RINOK(folderOutStream->FlushCorrupted(NArchive::NExtract::NOperationResult::kDataError));
+        continue;
+      }
+    }
+    catch(...)
+    {
+      RINOK(folderOutStream->FlushCorrupted(NArchive::NExtract::NOperationResult::kDataError));
+      continue;
+    }
+  }
+  return S_OK;
+  COM_TRY_END
+}
+
+}}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/misc/libphysfs/lzma/CPP/7zip/Archive/7z/7zFolderInStream.cpp	Mon Apr 10 12:06:43 2017 -0400
@@ -0,0 +1,130 @@
+// 7zFolderInStream.cpp
+
+#include "StdAfx.h"
+
+#include "7zFolderInStream.h"
+
+namespace NArchive {
+namespace N7z {
+
+CFolderInStream::CFolderInStream()
+{
+  _inStreamWithHashSpec = new CSequentialInStreamWithCRC;
+  _inStreamWithHash = _inStreamWithHashSpec;
+}
+
+void CFolderInStream::Init(IArchiveUpdateCallback *updateCallback, 
+    const UInt32 *fileIndices, UInt32 numFiles)
+{
+  _updateCallback = updateCallback;
+  _numFiles = numFiles;
+  _fileIndex = 0;
+  _fileIndices = fileIndices;
+  Processed.Clear();
+  CRCs.Clear();
+  Sizes.Clear();
+  _fileIsOpen = false;
+  _currentSizeIsDefined = false;
+}
+
+HRESULT CFolderInStream::OpenStream()
+{
+  _filePos = 0;
+  while (_fileIndex < _numFiles)
+  {
+    _currentSizeIsDefined = false;
+    CMyComPtr<ISequentialInStream> stream;
+    HRESULT result = _updateCallback->GetStream(_fileIndices[_fileIndex], &stream);
+    if (result != S_OK && result != S_FALSE)
+      return result;
+    _fileIndex++;
+    _inStreamWithHashSpec->SetStream(stream);
+    _inStreamWithHashSpec->Init();
+    if (!stream)
+    {
+      RINOK(_updateCallback->SetOperationResult(NArchive::NUpdate::NOperationResult::kOK));
+      Sizes.Add(0);
+      Processed.Add(result == S_OK);
+      AddDigest();
+      continue;
+    }
+    CMyComPtr<IStreamGetSize> streamGetSize;
+    if (stream.QueryInterface(IID_IStreamGetSize, &streamGetSize) == S_OK)
+    {
+      if(streamGetSize)
+      {
+        _currentSizeIsDefined = true;
+        RINOK(streamGetSize->GetSize(&_currentSize));
+      }
+    }
+
+    _fileIsOpen = true;
+    return S_OK;
+  }
+  return S_OK;
+}
+
+void CFolderInStream::AddDigest()
+{
+  CRCs.Add(_inStreamWithHashSpec->GetCRC());
+}
+
+HRESULT CFolderInStream::CloseStream()
+{
+  RINOK(_updateCallback->SetOperationResult(NArchive::NUpdate::NOperationResult::kOK));
+  _inStreamWithHashSpec->ReleaseStream();
+  _fileIsOpen = false;
+  Processed.Add(true);
+  Sizes.Add(_filePos);
+  AddDigest();
+  return S_OK;
+}
+
+STDMETHODIMP CFolderInStream::Read(void *data, UInt32 size, UInt32 *processedSize)
+{
+  UInt32 realProcessedSize = 0;
+  while ((_fileIndex < _numFiles || _fileIsOpen) && size > 0)
+  {
+    if (_fileIsOpen)
+    {
+      UInt32 localProcessedSize;
+      RINOK(_inStreamWithHash->Read(
+          ((Byte *)data) + realProcessedSize, size, &localProcessedSize));
+      if (localProcessedSize == 0)
+      {
+        RINOK(CloseStream());
+        continue;
+      }
+      realProcessedSize += localProcessedSize;
+      _filePos += localProcessedSize;
+      size -= localProcessedSize;
+      break;
+    }
+    else
+    {
+      RINOK(OpenStream());
+    }
+  }
+  if (processedSize != 0)
+    *processedSize = realProcessedSize;
+  return S_OK;
+}
+
+STDMETHODIMP CFolderInStream::GetSubStreamSize(UInt64 subStream, UInt64 *value)
+{
+  *value = 0;
+  int subStreamIndex = (int)subStream;
+  if (subStreamIndex < 0 || subStream > Sizes.Size())
+    return E_FAIL;
+  if (subStreamIndex < Sizes.Size())
+  {
+    *value= Sizes[subStreamIndex];
+    return S_OK;
+  }
+  if (!_currentSizeIsDefined)
+    return S_FALSE;
+  *value = _currentSize;
+  return S_OK;
+}
+
+}}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/misc/libphysfs/lzma/CPP/7zip/Archive/7z/7zFolderInStream.h	Mon Apr 10 12:06:43 2017 -0400
@@ -0,0 +1,66 @@
+// 7z/FolderInStream.h
+
+#ifndef __7Z_FOLDERINSTREAM_H
+#define __7Z_FOLDERINSTREAM_H
+
+#include "7zItem.h"
+#include "7zHeader.h"
+
+#include "../IArchive.h"
+#include "../Common/InStreamWithCRC.h"
+#include "../../IStream.h"
+#include "../../ICoder.h"
+
+namespace NArchive {
+namespace N7z {
+
+class CFolderInStream: 
+  public ISequentialInStream,
+  public ICompressGetSubStreamSize,
+  public CMyUnknownImp
+{
+public:
+
+  MY_UNKNOWN_IMP1(ICompressGetSubStreamSize)
+
+  CFolderInStream();
+
+  STDMETHOD(Read)(void *data, UInt32 size, UInt32 *processedSize);
+
+  STDMETHOD(GetSubStreamSize)(UInt64 subStream, UInt64 *value);
+private:
+  CSequentialInStreamWithCRC *_inStreamWithHashSpec;
+  CMyComPtr<ISequentialInStream> _inStreamWithHash;
+  CMyComPtr<IArchiveUpdateCallback> _updateCallback;
+
+  bool _currentSizeIsDefined;
+  UInt64 _currentSize;
+
+  bool _fileIsOpen;
+  UInt64 _filePos;
+
+  const UInt32 *_fileIndices;
+  UInt32 _numFiles;
+  UInt32 _fileIndex;
+
+  HRESULT OpenStream();
+  HRESULT CloseStream();
+  void AddDigest();
+public:
+  void Init(IArchiveUpdateCallback *updateCallback, 
+      const UInt32 *fileIndices, UInt32 numFiles);
+  CRecordVector<bool> Processed;
+  CRecordVector<UInt32> CRCs;
+  CRecordVector<UInt64> Sizes;
+  UInt64 GetFullSize() const
+  {
+    UInt64 size = 0;
+    for (int i = 0; i < Sizes.Size(); i++)      
+      size += Sizes[i];
+    return size;
+  }
+};
+
+}}
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/misc/libphysfs/lzma/CPP/7zip/Archive/7z/7zFolderOutStream.cpp	Mon Apr 10 12:06:43 2017 -0400
@@ -0,0 +1,165 @@
+// 7zFolderOutStream.cpp
+
+#include "StdAfx.h"
+
+#include "7zFolderOutStream.h"
+
+namespace NArchive {
+namespace N7z {
+
+CFolderOutStream::CFolderOutStream()
+{
+  _outStreamWithHashSpec = new COutStreamWithCRC;
+  _outStreamWithHash = _outStreamWithHashSpec;
+}
+
+HRESULT CFolderOutStream::Init(
+    const CArchiveDatabaseEx *archiveDatabase,
+    UInt32 ref2Offset,
+    UInt32 startIndex,
+    const CBoolVector *extractStatuses, 
+    IArchiveExtractCallback *extractCallback,
+    bool testMode,
+    bool checkCrc)
+{
+  _archiveDatabase = archiveDatabase;
+  _ref2Offset = ref2Offset;
+  _startIndex = startIndex;
+
+  _extractStatuses = extractStatuses;
+  _extractCallback = extractCallback;
+  _testMode = testMode;
+
+  _checkCrc = checkCrc;
+
+  _currentIndex = 0;
+  _fileIsOpen = false;
+  return WriteEmptyFiles();
+}
+
+HRESULT CFolderOutStream::OpenFile()
+{
+  Int32 askMode;
+  if((*_extractStatuses)[_currentIndex])
+    askMode = _testMode ? 
+        NArchive::NExtract::NAskMode::kTest :
+        NArchive::NExtract::NAskMode::kExtract;
+  else
+    askMode = NArchive::NExtract::NAskMode::kSkip;
+  CMyComPtr<ISequentialOutStream> realOutStream;
+
+  UInt32 index = _startIndex + _currentIndex;
+  RINOK(_extractCallback->GetStream(_ref2Offset + index, &realOutStream, askMode));
+
+  _outStreamWithHashSpec->SetStream(realOutStream);
+  _outStreamWithHashSpec->Init(_checkCrc);
+  if (askMode == NArchive::NExtract::NAskMode::kExtract &&
+      (!realOutStream)) 
+  {
+    const CFileItem &fileInfo = _archiveDatabase->Files[index];
+    if (!fileInfo.IsAnti && !fileInfo.IsDirectory)
+      askMode = NArchive::NExtract::NAskMode::kSkip;
+  }
+  return _extractCallback->PrepareOperation(askMode);
+}
+
+HRESULT CFolderOutStream::WriteEmptyFiles()
+{
+  for(;_currentIndex < _extractStatuses->Size(); _currentIndex++)
+  {
+    UInt32 index = _startIndex + _currentIndex;
+    const CFileItem &fileInfo = _archiveDatabase->Files[index];
+    if (!fileInfo.IsAnti && !fileInfo.IsDirectory && fileInfo.UnPackSize != 0)
+      return S_OK;
+    RINOK(OpenFile());
+    RINOK(_extractCallback->SetOperationResult(
+        NArchive::NExtract::NOperationResult::kOK));
+    _outStreamWithHashSpec->ReleaseStream();
+  }
+  return S_OK;
+}
+
+STDMETHODIMP CFolderOutStream::Write(const void *data, 
+    UInt32 size, UInt32 *processedSize)
+{
+  UInt32 realProcessedSize = 0;
+  while(_currentIndex < _extractStatuses->Size())
+  {
+    if (_fileIsOpen)
+    {
+      UInt32 index = _startIndex + _currentIndex;
+      const CFileItem &fileInfo = _archiveDatabase->Files[index];
+      UInt64 fileSize = fileInfo.UnPackSize;
+      
+      UInt32 numBytesToWrite = (UInt32)MyMin(fileSize - _filePos, 
+          UInt64(size - realProcessedSize));
+      
+      UInt32 processedSizeLocal;
+      RINOK(_outStreamWithHash->Write((const Byte *)data + realProcessedSize, 
+            numBytesToWrite, &processedSizeLocal));
+
+      _filePos += processedSizeLocal;
+      realProcessedSize += processedSizeLocal;
+      if (_filePos == fileSize)
+      {
+        bool digestsAreEqual;
+        if (fileInfo.IsFileCRCDefined && _checkCrc)
+          digestsAreEqual = fileInfo.FileCRC == _outStreamWithHashSpec->GetCRC();
+        else
+          digestsAreEqual = true;
+
+        RINOK(_extractCallback->SetOperationResult(
+            digestsAreEqual ? 
+            NArchive::NExtract::NOperationResult::kOK :
+            NArchive::NExtract::NOperationResult::kCRCError));
+        _outStreamWithHashSpec->ReleaseStream();
+        _fileIsOpen = false;
+        _currentIndex++;
+      }
+      if (realProcessedSize == size)
+      {
+        if (processedSize != NULL)
+          *processedSize = realProcessedSize;
+        return WriteEmptyFiles();
+      }
+    }
+    else
+    {
+      RINOK(OpenFile());
+      _fileIsOpen = true;
+      _filePos = 0;
+    }
+  }
+  if (processedSize != NULL)
+    *processedSize = size;
+  return S_OK;
+}
+
+HRESULT CFolderOutStream::FlushCorrupted(Int32 resultEOperationResult)
+{
+  while(_currentIndex < _extractStatuses->Size())
+  {
+    if (_fileIsOpen)
+    {
+      RINOK(_extractCallback->SetOperationResult(resultEOperationResult));
+      _outStreamWithHashSpec->ReleaseStream();
+      _fileIsOpen = false;
+      _currentIndex++;
+    }
+    else
+    {
+      RINOK(OpenFile());
+      _fileIsOpen = true;
+    }
+  }
+  return S_OK;
+}
+
+HRESULT CFolderOutStream::WasWritingFinished()
+{
+  if (_currentIndex == _extractStatuses->Size())
+    return S_OK;
+  return E_FAIL;
+}
+
+}}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/misc/libphysfs/lzma/CPP/7zip/Archive/7z/7zFolderOutStream.h	Mon Apr 10 12:06:43 2017 -0400
@@ -0,0 +1,60 @@
+// 7zFolderOutStream.h
+
+#ifndef __7Z_FOLDEROUTSTREAM_H
+#define __7Z_FOLDEROUTSTREAM_H
+
+#include "7zIn.h"
+
+#include "../../IStream.h"
+#include "../IArchive.h"
+#include "../Common/OutStreamWithCRC.h"
+
+namespace NArchive {
+namespace N7z {
+
+class CFolderOutStream: 
+  public ISequentialOutStream,
+  public CMyUnknownImp
+{
+public:
+  MY_UNKNOWN_IMP
+  
+  CFolderOutStream();
+
+  STDMETHOD(Write)(const void *data, UInt32 size, UInt32 *processedSize);
+private:
+
+  COutStreamWithCRC *_outStreamWithHashSpec;
+  CMyComPtr<ISequentialOutStream> _outStreamWithHash;
+  const CArchiveDatabaseEx *_archiveDatabase;
+  const CBoolVector *_extractStatuses;
+  UInt32 _startIndex;
+  UInt32 _ref2Offset;
+  int _currentIndex;
+  // UInt64 _currentDataPos;
+  CMyComPtr<IArchiveExtractCallback> _extractCallback;
+  bool _testMode;
+
+  bool _fileIsOpen;
+
+  bool _checkCrc;
+  UInt64 _filePos;
+
+  HRESULT OpenFile();
+  HRESULT WriteEmptyFiles();
+public:
+  HRESULT Init(
+      const CArchiveDatabaseEx *archiveDatabase,
+      UInt32 ref2Offset,
+      UInt32 startIndex,
+      const CBoolVector *extractStatuses, 
+      IArchiveExtractCallback *extractCallback,
+      bool testMode,
+      bool checkCrc);
+  HRESULT FlushCorrupted(Int32 resultEOperationResult);
+  HRESULT WasWritingFinished();
+};
+
+}}
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/misc/libphysfs/lzma/CPP/7zip/Archive/7z/7zHandler.cpp	Mon Apr 10 12:06:43 2017 -0400
@@ -0,0 +1,793 @@
+// 7zHandler.cpp
+
+#include "StdAfx.h"
+
+#include "7zHandler.h"
+#include "7zProperties.h"
+
+#include "../../../Common/IntToString.h"
+#include "../../../Common/ComTry.h"
+#include "../../../Windows/Defs.h"
+
+#include "../Common/ItemNameUtils.h"
+#ifdef _7Z_VOL
+#include "../Common/MultiStream.h"
+#endif
+
+#ifdef __7Z_SET_PROPERTIES
+#ifdef EXTRACT_ONLY
+#include "../Common/ParseProperties.h"
+#endif
+#endif
+
+#ifdef COMPRESS_MT
+#include "../../../Windows/System.h"
+#endif
+
+using namespace NWindows;
+
+extern UString ConvertMethodIdToString(UInt64 id);
+
+namespace NArchive {
+namespace N7z {
+
+CHandler::CHandler()
+{
+  _crcSize = 4;
+
+  #ifdef EXTRACT_ONLY
+  #ifdef COMPRESS_MT
+  _numThreads = NWindows::NSystem::GetNumberOfProcessors();
+  #endif
+  #else
+  Init();
+  #endif
+}
+
+STDMETHODIMP CHandler::GetNumberOfItems(UInt32 *numItems)
+{
+  *numItems = 
+  #ifdef _7Z_VOL
+  _refs.Size();
+  #else
+  *numItems = _database.Files.Size();
+  #endif
+  return S_OK;
+}
+
+#ifdef _SFX
+
+IMP_IInArchive_ArcProps_NO
+
+STDMETHODIMP CHandler::GetNumberOfProperties(UInt32 * /* numProperties */)
+{
+  return E_NOTIMPL;
+}
+
+STDMETHODIMP CHandler::GetPropertyInfo(UInt32 /* index */,     
+      BSTR * /* name */, PROPID * /* propID */, VARTYPE * /* varType */)
+{
+  return E_NOTIMPL;
+}
+
+
+#else
+
+STATPROPSTG kArcProps[] = 
+{
+  { NULL, kpidMethod, VT_BSTR},
+  { NULL, kpidSolid, VT_BOOL},
+  { NULL, kpidNumBlocks, VT_UI4}
+};
+
+STDMETHODIMP CHandler::GetArchiveProperty(PROPID propID, PROPVARIANT *value)
+{
+  COM_TRY_BEGIN
+  NWindows::NCOM::CPropVariant prop;
+  switch(propID)
+  {
+    case kpidMethod:
+    {
+      UString resString;
+      CRecordVector<UInt64> ids;
+      int i;
+      for (i = 0; i < _database.Folders.Size(); i++)
+      {
+        const CFolder &f = _database.Folders[i];
+        for (int j = f.Coders.Size() - 1; j >= 0; j--)
+          ids.AddToUniqueSorted(f.Coders[j].MethodID);
+      }
+
+      for (i = 0; i < ids.Size(); i++)
+      {
+        UInt64 id = ids[i];
+        UString methodName;
+        /* bool methodIsKnown = */ FindMethod(EXTERNAL_CODECS_VARS id, methodName);
+        if (methodName.IsEmpty())
+          methodName = ConvertMethodIdToString(id);
+        if (!resString.IsEmpty())
+          resString += L' ';
+        resString += methodName;
+      }
+      prop = resString; 
+      break;
+    }
+    case kpidSolid: prop = _database.IsSolid(); break;
+    case kpidNumBlocks: prop = (UInt32)_database.Folders.Size(); break;
+  }
+  prop.Detach(value);
+  return S_OK;
+  COM_TRY_END
+}
+
+IMP_IInArchive_ArcProps
+
+#endif
+
+static void MySetFileTime(bool timeDefined, FILETIME unixTime, NWindows::NCOM::CPropVariant &prop)
+{
+  if (timeDefined)
+    prop = unixTime;
+}
+
+#ifndef _SFX
+
+static UString ConvertUInt32ToString(UInt32 value)
+{
+  wchar_t buffer[32];
+  ConvertUInt64ToString(value, buffer);
+  return buffer;
+}
+
+static UString GetStringForSizeValue(UInt32 value)
+{
+  for (int i = 31; i >= 0; i--)
+    if ((UInt32(1) << i) == value)
+      return ConvertUInt32ToString(i);
+  UString result;
+  if (value % (1 << 20) == 0)
+  {
+    result += ConvertUInt32ToString(value >> 20);
+    result += L"m";
+  }
+  else if (value % (1 << 10) == 0)
+  {
+    result += ConvertUInt32ToString(value >> 10);
+    result += L"k";
+  }
+  else
+  {
+    result += ConvertUInt32ToString(value);
+    result += L"b";
+  }
+  return result;
+}
+
+static const UInt64 k_Copy = 0x0;
+static const UInt64 k_LZMA  = 0x030101;
+static const UInt64 k_PPMD  = 0x030401;
+
+static wchar_t GetHex(Byte value)
+{
+  return (wchar_t)((value < 10) ? (L'0' + value) : (L'A' + (value - 10)));
+}
+static inline UString GetHex2(Byte value)
+{
+  UString result;
+  result += GetHex((Byte)(value >> 4));
+  result += GetHex((Byte)(value & 0xF));
+  return result;
+}
+
+#endif
+
+static const UInt64 k_AES  = 0x06F10701;
+
+#ifndef _SFX
+static inline UInt32 GetUInt32FromMemLE(const Byte *p)
+{
+  return p[0] | (((UInt32)p[1]) << 8) | (((UInt32)p[2]) << 16) | (((UInt32)p[3]) << 24);
+}
+#endif
+
+bool CHandler::IsEncrypted(UInt32 index2) const
+{
+  CNum folderIndex = _database.FileIndexToFolderIndexMap[index2];
+  if (folderIndex != kNumNoIndex)
+  {
+    const CFolder &folderInfo = _database.Folders[folderIndex];
+    for (int i = folderInfo.Coders.Size() - 1; i >= 0; i--)
+      if (folderInfo.Coders[i].MethodID == k_AES)
+        return true;
+  }
+  return false;
+}
+
+STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID,  PROPVARIANT *value)
+{
+  COM_TRY_BEGIN
+  NWindows::NCOM::CPropVariant prop;
+  
+  /*
+  const CRef2 &ref2 = _refs[index];
+  if (ref2.Refs.IsEmpty())
+    return E_FAIL;
+  const CRef &ref = ref2.Refs.Front();
+  */
+  
+  #ifdef _7Z_VOL
+  const CRef &ref = _refs[index];
+  const CVolume &volume = _volumes[ref.VolumeIndex];
+  const CArchiveDatabaseEx &_database = volume.Database;
+  UInt32 index2 = ref.ItemIndex;
+  const CFileItem &item = _database.Files[index2];
+  #else
+  const CFileItem &item = _database.Files[index];
+  UInt32 index2 = index;
+  #endif
+
+  switch(propID)
+  {
+    case kpidPath:
+    {
+      if (!item.Name.IsEmpty())
+        prop = NItemName::GetOSName(item.Name);
+      break;
+    }
+    case kpidIsFolder:
+      prop = item.IsDirectory;
+      break;
+    case kpidSize:
+    {
+      prop = item.UnPackSize;
+      // prop = ref2.UnPackSize;
+      break;
+    }
+    case kpidPosition:
+    {
+      /*
+      if (ref2.Refs.Size() > 1)
+        prop = ref2.StartPos;
+      else
+      */
+        if (item.IsStartPosDefined)
+          prop = item.StartPos;
+      break;
+    }
+    case kpidPackedSize:
+    {
+      // prop = ref2.PackSize;
+      {
+        CNum folderIndex = _database.FileIndexToFolderIndexMap[index2];
+        if (folderIndex != kNumNoIndex)
+        {
+          if (_database.FolderStartFileIndex[folderIndex] == (CNum)index2)
+            prop = _database.GetFolderFullPackSize(folderIndex);
+          /*
+          else
+            prop = (UInt64)0;
+          */
+        }
+        else
+          prop = (UInt64)0;
+      }
+      break;
+    }
+    case kpidLastAccessTime:
+      MySetFileTime(item.IsLastAccessTimeDefined, item.LastAccessTime, prop);
+      break;
+    case kpidCreationTime:
+      MySetFileTime(item.IsCreationTimeDefined, item.CreationTime, prop);
+      break;
+    case kpidLastWriteTime:
+      MySetFileTime(item.IsLastWriteTimeDefined, item.LastWriteTime, prop);
+      break;
+    case kpidAttributes:
+      if (item.AreAttributesDefined)
+        prop = item.Attributes;
+      break;
+    case kpidCRC:
+      if (item.IsFileCRCDefined)
+        prop = item.FileCRC;
+      break;
+    case kpidEncrypted:
+    {
+      prop = IsEncrypted(index2);
+      break;
+    }
+    #ifndef _SFX
+    case kpidMethod:
+      {
+        CNum folderIndex = _database.FileIndexToFolderIndexMap[index2];
+        if (folderIndex != kNumNoIndex)
+        {
+          const CFolder &folderInfo = _database.Folders[folderIndex];
+          UString methodsString;
+          for (int i = folderInfo.Coders.Size() - 1; i >= 0; i--)
+          {
+            const CCoderInfo &coderInfo = folderInfo.Coders[i];
+            if (!methodsString.IsEmpty())
+              methodsString += L' ';
+
+            {
+              UString methodName;
+              bool methodIsKnown = FindMethod(
+                  EXTERNAL_CODECS_VARS 
+                  coderInfo.MethodID, methodName);
+
+              if (methodIsKnown)
+              {
+                methodsString += methodName;
+                if (coderInfo.MethodID == k_LZMA)
+                {
+                  if (coderInfo.Properties.GetCapacity() >= 5)
+                  {
+                    methodsString += L":";
+                    UInt32 dicSize = GetUInt32FromMemLE(
+                      ((const Byte *)coderInfo.Properties + 1));
+                    methodsString += GetStringForSizeValue(dicSize);
+                  }
+                }
+                else if (coderInfo.MethodID == k_PPMD)
+                {
+                  if (coderInfo.Properties.GetCapacity() >= 5)
+                  {
+                    Byte order = *(const Byte *)coderInfo.Properties;
+                    methodsString += L":o";
+                    methodsString += ConvertUInt32ToString(order);
+                    methodsString += L":mem";
+                    UInt32 dicSize = GetUInt32FromMemLE(
+                      ((const Byte *)coderInfo.Properties + 1));
+                    methodsString += GetStringForSizeValue(dicSize);
+                  }
+                }
+                else if (coderInfo.MethodID == k_AES)
+                {
+                  if (coderInfo.Properties.GetCapacity() >= 1)
+                  {
+                    methodsString += L":";
+                    const Byte *data = (const Byte *)coderInfo.Properties;
+                    Byte firstByte = *data++;
+                    UInt32 numCyclesPower = firstByte & 0x3F;
+                    methodsString += ConvertUInt32ToString(numCyclesPower);
+                    /*
+                    if ((firstByte & 0xC0) != 0)
+                    {
+                      methodsString += L":";
+                      return S_OK;
+                      UInt32 saltSize = (firstByte >> 7) & 1;
+                      UInt32 ivSize = (firstByte >> 6) & 1;
+                      if (coderInfo.Properties.GetCapacity() >= 2)
+                      {
+                        Byte secondByte = *data++;
+                        saltSize += (secondByte >> 4);
+                        ivSize += (secondByte & 0x0F);
+                      }
+                    }
+                    */
+                  }
+                }
+                else
+                {
+                  if (coderInfo.Properties.GetCapacity() > 0)
+                  {
+                    methodsString += L":[";
+                    for (size_t bi = 0; bi < coderInfo.Properties.GetCapacity(); bi++)
+                    {
+                      if (bi > 5 && bi + 1 < coderInfo.Properties.GetCapacity())
+                      {
+                        methodsString += L"..";
+                        break;
+                      }
+                      else
+                        methodsString += GetHex2(coderInfo.Properties[bi]);
+                    }
+                    methodsString += L"]";
+                  }
+                }
+              }
+              else
+              {
+                methodsString += ConvertMethodIdToString(coderInfo.MethodID);
+              }
+            }
+          }
+          prop = methodsString;
+        }
+      }
+      break;
+    case kpidBlock:
+      {
+        CNum folderIndex = _database.FileIndexToFolderIndexMap[index2];
+        if (folderIndex != kNumNoIndex)
+          prop = (UInt32)folderIndex;
+      }
+      break;
+    case kpidPackedSize0:
+    case kpidPackedSize1:
+    case kpidPackedSize2:
+    case kpidPackedSize3:
+    case kpidPackedSize4:
+      {
+        CNum folderIndex = _database.FileIndexToFolderIndexMap[index2];
+        if (folderIndex != kNumNoIndex)
+        {
+          const CFolder &folderInfo = _database.Folders[folderIndex];
+          if (_database.FolderStartFileIndex[folderIndex] == (CNum)index2 &&
+              folderInfo.PackStreams.Size() > (int)(propID - kpidPackedSize0))
+          {
+            prop = _database.GetFolderPackStreamSize(folderIndex, propID - kpidPackedSize0);
+          }
+          else
+            prop = (UInt64)0;
+        }
+        else
+          prop = (UInt64)0;
+      }
+      break;
+    #endif
+    case kpidIsAnti:
+      prop = item.IsAnti;
+      break;
+  }
+  prop.Detach(value);
+  return S_OK;
+  COM_TRY_END
+}
+
+#ifdef _7Z_VOL
+
+static const wchar_t *kExt = L"7z";
+static const wchar_t *kAfterPart = L".7z";
+
+class CVolumeName
+{
+  bool _first;
+  UString _unchangedPart;
+  UString _changedPart;    
+  UString _afterPart;    
+public:
+  bool InitName(const UString &name)
+  {
+    _first = true;
+    int dotPos = name.ReverseFind('.');
+    UString basePart = name;
+    if (dotPos >= 0)
+    {
+      UString ext = name.Mid(dotPos + 1);
+      if (ext.CompareNoCase(kExt)==0 || 
+        ext.CompareNoCase(L"EXE") == 0)
+      {
+        _afterPart = kAfterPart;
+        basePart = name.Left(dotPos);
+      }
+    }
+
+    int numLetters = 1;
+    bool splitStyle = false;
+    if (basePart.Right(numLetters) == L"1")
+    {
+      while (numLetters < basePart.Length())
+      {
+        if (basePart[basePart.Length() - numLetters - 1] != '0')
+          break;
+        numLetters++;
+      }
+    }
+    else 
+      return false;
+    _unchangedPart = basePart.Left(basePart.Length() - numLetters);
+    _changedPart = basePart.Right(numLetters);
+    return true;
+  }
+
+  UString GetNextName()
+  {
+    UString newName; 
+    // if (_newStyle || !_first)
+    {
+      int i;
+      int numLetters = _changedPart.Length();
+      for (i = numLetters - 1; i >= 0; i--)
+      {
+        wchar_t c = _changedPart[i];
+        if (c == L'9')
+        {
+          c = L'0';
+          newName = c + newName;
+          if (i == 0)
+            newName = UString(L'1') + newName;
+          continue;
+        }
+        c++;
+        newName = UString(c) + newName;
+        i--;
+        for (; i >= 0; i--)
+          newName = _changedPart[i] + newName;
+        break;
+      }
+      _changedPart = newName;
+    }
+    _first = false;
+    return _unchangedPart + _changedPart + _afterPart;
+  }
+};
+
+#endif
+
+STDMETHODIMP CHandler::Open(IInStream *stream,
+    const UInt64 *maxCheckStartPosition, 
+    IArchiveOpenCallback *openArchiveCallback)
+{
+  COM_TRY_BEGIN
+  Close();
+  #ifndef _SFX
+  _fileInfoPopIDs.Clear();
+  #endif
+  try
+  {
+    CMyComPtr<IArchiveOpenCallback> openArchiveCallbackTemp = openArchiveCallback;
+    #ifdef _7Z_VOL
+    CVolumeName seqName;
+
+    CMyComPtr<IArchiveOpenVolumeCallback> openVolumeCallback;
+    #endif
+
+    #ifndef _NO_CRYPTO
+    CMyComPtr<ICryptoGetTextPassword> getTextPassword;
+    if (openArchiveCallback)
+    {
+      openArchiveCallbackTemp.QueryInterface(
+          IID_ICryptoGetTextPassword, &getTextPassword);
+    }
+    #endif
+    #ifdef _7Z_VOL
+    if (openArchiveCallback)
+    {
+      openArchiveCallbackTemp.QueryInterface(IID_IArchiveOpenVolumeCallback, &openVolumeCallback);
+    }
+    for (;;)
+    {
+      CMyComPtr<IInStream> inStream;
+      if (!_volumes.IsEmpty())
+      {
+        if (!openVolumeCallback)
+          break;
+        if(_volumes.Size() == 1)
+        {
+          UString baseName;
+          {
+            NCOM::CPropVariant prop;
+            RINOK(openVolumeCallback->GetProperty(kpidName, &prop));
+            if (prop.vt != VT_BSTR)
+              break;
+            baseName = prop.bstrVal;
+          }
+          seqName.InitName(baseName);
+        }
+
+        UString fullName = seqName.GetNextName();
+        HRESULT result = openVolumeCallback->GetStream(fullName, &inStream);
+        if (result == S_FALSE)
+          break;
+        if (result != S_OK)
+          return result;
+        if (!stream)
+          break;
+      }
+      else
+        inStream = stream;
+
+      CInArchive archive;
+      RINOK(archive.Open(inStream, maxCheckStartPosition));
+
+      _volumes.Add(CVolume());
+      CVolume &volume = _volumes.Back();
+      CArchiveDatabaseEx &database = volume.Database;
+      volume.Stream = inStream;
+      volume.StartRef2Index = _refs.Size();
+
+      HRESULT result = archive.ReadDatabase(database
+          #ifndef _NO_CRYPTO
+          , getTextPassword
+          #endif
+          );
+      if (result != S_OK)
+      {
+        _volumes.Clear();
+        return result;
+      }
+      database.Fill();
+      for(int i = 0; i < database.Files.Size(); i++)
+      {
+        CRef refNew;
+        refNew.VolumeIndex = _volumes.Size() - 1;
+        refNew.ItemIndex = i;
+        _refs.Add(refNew);
+        /*
+        const CFileItem &file = database.Files[i];
+        int j;
+        */
+        /*
+        for (j = _refs.Size() - 1; j >= 0; j--)
+        {
+          CRef2 &ref2 = _refs[j];
+          const CRef &ref = ref2.Refs.Back();
+          const CVolume &volume2 = _volumes[ref.VolumeIndex];
+          const CArchiveDatabaseEx &database2 = volume2.Database;
+          const CFileItem &file2 = database2.Files[ref.ItemIndex];
+          if (file2.Name.CompareNoCase(file.Name) == 0)
+          {
+            if (!file.IsStartPosDefined)
+              continue;
+            if (file.StartPos != ref2.StartPos + ref2.UnPackSize)
+              continue;
+            ref2.Refs.Add(refNew);
+            break;
+          }
+        }
+        */
+        /*
+        j = -1;
+        if (j < 0)
+        {
+          CRef2 ref2New;
+          ref2New.Refs.Add(refNew);
+          j = _refs.Add(ref2New);
+        }
+        CRef2 &ref2 = _refs[j];
+        ref2.UnPackSize += file.UnPackSize;
+        ref2.PackSize += database.GetFilePackSize(i);
+        if (ref2.Refs.Size() == 1 && file.IsStartPosDefined)
+          ref2.StartPos = file.StartPos;
+        */
+      }
+      if (database.Files.Size() != 1)
+        break;
+      const CFileItem &file = database.Files.Front();
+      if (!file.IsStartPosDefined)
+        break;
+    }
+    #else
+    CInArchive archive;
+    RINOK(archive.Open(stream, maxCheckStartPosition));
+    HRESULT result = archive.ReadDatabase(
+      EXTERNAL_CODECS_VARS
+      _database
+      #ifndef _NO_CRYPTO
+      , getTextPassword
+      #endif
+      );
+    RINOK(result);
+    _database.Fill();
+    _inStream = stream;
+    #endif
+  }
+  catch(...)
+  {
+    Close();
+    return S_FALSE;
+  }
+  // _inStream = stream;
+  #ifndef _SFX
+  FillPopIDs();
+  #endif
+  return S_OK;
+  COM_TRY_END
+}
+
+STDMETHODIMP CHandler::Close()
+{
+  COM_TRY_BEGIN
+  #ifdef _7Z_VOL
+  _volumes.Clear();
+  _refs.Clear();
+  #else
+  _inStream.Release();
+  _database.Clear();
+  #endif
+  return S_OK;
+  COM_TRY_END
+}
+
+#ifdef _7Z_VOL
+STDMETHODIMP CHandler::GetStream(UInt32 index, ISequentialInStream **stream)
+{
+  if (index != 0)
+    return E_INVALIDARG;
+  *stream = 0;
+  CMultiStream *streamSpec = new CMultiStream;
+  CMyComPtr<ISequentialInStream> streamTemp = streamSpec;
+  
+  UInt64 pos = 0;
+  const UString *fileName;
+  for (int i = 0; i < _refs.Size(); i++)
+  {
+    const CRef &ref = _refs[i];
+    const CVolume &volume = _volumes[ref.VolumeIndex];
+    const CArchiveDatabaseEx &database = volume.Database;
+    const CFileItem &file = database.Files[ref.ItemIndex];
+    if (i == 0)
+      fileName = &file.Name;
+    else
+      if (fileName->Compare(file.Name) != 0)
+        return S_FALSE;
+    if (!file.IsStartPosDefined)
+      return S_FALSE;
+    if (file.StartPos != pos)
+      return S_FALSE;
+    CNum folderIndex = database.FileIndexToFolderIndexMap[ref.ItemIndex];
+    if (folderIndex == kNumNoIndex)
+    {
+      if (file.UnPackSize != 0)
+        return E_FAIL;
+      continue;
+    }
+    if (database.NumUnPackStreamsVector[folderIndex] != 1)
+      return S_FALSE;
+    const CFolder &folder = database.Folders[folderIndex];
+    if (folder.Coders.Size() != 1)
+      return S_FALSE;
+    const CCoderInfo &coder = folder.Coders.Front();
+    if (coder.NumInStreams != 1 || coder.NumOutStreams != 1)
+      return S_FALSE;
+    if (coder.MethodID != k_Copy)
+      return S_FALSE;
+
+    pos += file.UnPackSize;
+    CMultiStream::CSubStreamInfo subStreamInfo;
+    subStreamInfo.Stream = volume.Stream;
+    subStreamInfo.Pos = database.GetFolderStreamPos(folderIndex, 0);
+    subStreamInfo.Size = file.UnPackSize;
+    streamSpec->Streams.Add(subStreamInfo);
+  }
+  streamSpec->Init();
+  *stream = streamTemp.Detach();
+  return S_OK;
+}
+#endif
+
+
+#ifdef __7Z_SET_PROPERTIES
+#ifdef EXTRACT_ONLY
+
+STDMETHODIMP CHandler::SetProperties(const wchar_t **names, const PROPVARIANT *values, Int32 numProperties)
+{
+  COM_TRY_BEGIN
+  #ifdef COMPRESS_MT
+  const UInt32 numProcessors = NSystem::GetNumberOfProcessors();
+  _numThreads = numProcessors;
+  #endif
+
+  for (int i = 0; i < numProperties; i++)
+  {
+    UString name = names[i];
+    name.MakeUpper();
+    if (name.IsEmpty())
+      return E_INVALIDARG;
+    const PROPVARIANT &value = values[i];
+    UInt32 number;
+    int index = ParseStringToUInt32(name, number);
+    if (index == 0)
+    {
+      if(name.Left(2).CompareNoCase(L"MT") == 0)
+      {
+        #ifdef COMPRESS_MT
+        RINOK(ParseMtProp(name.Mid(2), value, numProcessors, _numThreads));
+        #endif
+        continue;
+      }
+      else
+        return E_INVALIDARG;
+    }
+  }
+  return S_OK;
+  COM_TRY_END
+}  
+
+#endif
+#endif
+
+IMPL_ISetCompressCodecsInfo
+
+}}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/misc/libphysfs/lzma/CPP/7zip/Archive/7z/7zHandler.h	Mon Apr 10 12:06:43 2017 -0400
@@ -0,0 +1,146 @@
+// 7z/Handler.h
+
+#ifndef __7Z_HANDLER_H
+#define __7Z_HANDLER_H
+
+#include "../../ICoder.h"
+#include "../IArchive.h"
+#include "7zIn.h"
+
+#include "7zCompressionMode.h"
+
+#include "../../Common/CreateCoder.h"
+
+#ifndef EXTRACT_ONLY
+#include "../Common/HandlerOut.h"
+#endif
+
+namespace NArchive {
+namespace N7z {
+
+#ifdef _7Z_VOL
+struct CRef
+{
+  int VolumeIndex;
+  int ItemIndex;
+};
+
+struct CVolume
+{
+  int StartRef2Index;
+  CMyComPtr<IInStream> Stream;
+  CArchiveDatabaseEx Database;
+};
+#endif
+
+#ifndef __7Z_SET_PROPERTIES
+
+#ifdef EXTRACT_ONLY
+#ifdef COMPRESS_MT
+#define __7Z_SET_PROPERTIES
+#endif
+#else 
+#define __7Z_SET_PROPERTIES
+#endif
+
+#endif
+
+
+class CHandler: 
+  #ifndef EXTRACT_ONLY
+  public NArchive::COutHandler,
+  #endif
+  public IInArchive,
+  #ifdef _7Z_VOL
+  public IInArchiveGetStream,
+  #endif
+  #ifdef __7Z_SET_PROPERTIES
+  public ISetProperties, 
+  #endif
+  #ifndef EXTRACT_ONLY
+  public IOutArchive, 
+  #endif
+  PUBLIC_ISetCompressCodecsInfo
+  public CMyUnknownImp
+{
+public:
+  MY_QUERYINTERFACE_BEGIN2(IInArchive)
+  #ifdef _7Z_VOL
+  MY_QUERYINTERFACE_ENTRY(IInArchiveGetStream)
+  #endif
+  #ifdef __7Z_SET_PROPERTIES
+  MY_QUERYINTERFACE_ENTRY(ISetProperties)
+  #endif
+  #ifndef EXTRACT_ONLY
+  MY_QUERYINTERFACE_ENTRY(IOutArchive)
+  #endif
+  QUERY_ENTRY_ISetCompressCodecsInfo
+  MY_QUERYINTERFACE_END
+  MY_ADDREF_RELEASE
+
+  INTERFACE_IInArchive(;)
+
+  #ifdef _7Z_VOL
+  STDMETHOD(GetStream)(UInt32 index, ISequentialInStream **stream);  
+  #endif
+
+  #ifdef __7Z_SET_PROPERTIES
+  STDMETHOD(SetProperties)(const wchar_t **names, const PROPVARIANT *values, Int32 numProperties);
+  #endif
+
+  #ifndef EXTRACT_ONLY
+  INTERFACE_IOutArchive(;)
+  #endif
+
+  DECL_ISetCompressCodecsInfo
+
+  CHandler();
+
+private:
+  #ifdef _7Z_VOL
+  CObjectVector<CVolume> _volumes;
+  CObjectVector<CRef> _refs;
+  #else
+  CMyComPtr<IInStream> _inStream;
+  NArchive::N7z::CArchiveDatabaseEx _database;
+  #endif
+
+  #ifdef EXTRACT_ONLY
+  
+  #ifdef COMPRESS_MT
+  UInt32 _numThreads;
+  #endif
+
+  UInt32 _crcSize;
+
+  #else
+  
+  CRecordVector<CBind> _binds;
+
+  HRESULT SetPassword(CCompressionMethodMode &methodMode, IArchiveUpdateCallback *updateCallback);
+
+  HRESULT SetCompressionMethod(CCompressionMethodMode &method,
+      CObjectVector<COneMethodInfo> &methodsInfo
+      #ifdef COMPRESS_MT
+      , UInt32 numThreads
+      #endif
+      );
+
+  HRESULT SetCompressionMethod(
+      CCompressionMethodMode &method,
+      CCompressionMethodMode &headerMethod);
+
+  #endif
+
+  bool IsEncrypted(UInt32 index2) const;
+  #ifndef _SFX
+
+  CRecordVector<UInt64> _fileInfoPopIDs;
+  void FillPopIDs();
+
+  #endif
+};
+
+}}
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/misc/libphysfs/lzma/CPP/7zip/Archive/7z/7zHandlerOut.cpp	Mon Apr 10 12:06:43 2017 -0400
@@ -0,0 +1,464 @@
+// 7zHandlerOut.cpp
+
+#include "StdAfx.h"
+
+#include "7zHandler.h"
+#include "7zOut.h"
+#include "7zUpdate.h"
+
+#include "../../../Windows/PropVariant.h"
+
+#include "../../../Common/ComTry.h"
+#include "../../../Common/StringToInt.h"
+#include "../../IPassword.h"
+#include "../../ICoder.h"
+
+#include "../Common/ItemNameUtils.h"
+#include "../Common/ParseProperties.h"
+
+using namespace NWindows;
+
+namespace NArchive {
+namespace N7z {
+
+static const wchar_t *kLZMAMethodName = L"LZMA";
+static const wchar_t *kCopyMethod = L"Copy";
+static const wchar_t *kDefaultMethodName = kLZMAMethodName;
+
+static const UInt32 kLzmaAlgorithmX5 = 1;
+static const wchar_t *kLzmaMatchFinderForHeaders = L"BT2";
+static const UInt32 kDictionaryForHeaders = 1 << 20;
+static const UInt32 kNumFastBytesForHeaders = 273;
+static const UInt32 kAlgorithmForHeaders = kLzmaAlgorithmX5;
+
+static inline bool IsCopyMethod(const UString &methodName)
+  { return (methodName.CompareNoCase(kCopyMethod) == 0); }
+
+STDMETHODIMP CHandler::GetFileTimeType(UInt32 *type)
+{
+  *type = NFileTimeType::kWindows;
+  return S_OK;
+}
+
+HRESULT CHandler::SetPassword(CCompressionMethodMode &methodMode,
+    IArchiveUpdateCallback *updateCallback)
+{
+  CMyComPtr<ICryptoGetTextPassword2> getTextPassword;
+  if (!getTextPassword)
+  {
+    CMyComPtr<IArchiveUpdateCallback> udateCallback2(updateCallback);
+    udateCallback2.QueryInterface(IID_ICryptoGetTextPassword2, &getTextPassword);
+  }
+  
+  if (getTextPassword)
+  {
+    CMyComBSTR password;
+    Int32 passwordIsDefined;
+    RINOK(getTextPassword->CryptoGetTextPassword2(
+        &passwordIsDefined, &password));
+    methodMode.PasswordIsDefined = IntToBool(passwordIsDefined);
+    if (methodMode.PasswordIsDefined)
+      methodMode.Password = password;
+  }
+  else
+    methodMode.PasswordIsDefined = false;
+  return S_OK;
+}
+
+HRESULT CHandler::SetCompressionMethod(
+    CCompressionMethodMode &methodMode,
+    CCompressionMethodMode &headerMethod)
+{
+  HRESULT res = SetCompressionMethod(methodMode, _methods
+  #ifdef COMPRESS_MT
+  , _numThreads
+  #endif
+  );
+  RINOK(res);
+  methodMode.Binds = _binds;
+
+  if (_compressHeaders)
+  {
+    // headerMethod.Methods.Add(methodMode.Methods.Back());
+
+    CObjectVector<COneMethodInfo> headerMethodInfoVector;
+    COneMethodInfo oneMethodInfo;
+    oneMethodInfo.MethodName = kLZMAMethodName;
+    {
+      CProp property;
+      property.Id = NCoderPropID::kMatchFinder;
+      property.Value = kLzmaMatchFinderForHeaders;
+      oneMethodInfo.Properties.Add(property);
+    }
+    {
+      CProp property;
+      property.Id = NCoderPropID::kAlgorithm;
+      property.Value = kAlgorithmForHeaders;
+      oneMethodInfo.Properties.Add(property);
+    }
+    {
+      CProp property;
+      property.Id = NCoderPropID::kNumFastBytes;
+      property.Value = UInt32(kNumFastBytesForHeaders);
+      oneMethodInfo.Properties.Add(property);
+    }
+    {
+      CProp property;
+      property.Id = NCoderPropID::kDictionarySize;
+      property.Value = UInt32(kDictionaryForHeaders);
+      oneMethodInfo.Properties.Add(property);
+    }
+    headerMethodInfoVector.Add(oneMethodInfo);
+    HRESULT res = SetCompressionMethod(headerMethod, headerMethodInfoVector
+      #ifdef COMPRESS_MT
+      ,1
+      #endif
+    );
+    RINOK(res);
+  }
+  return S_OK;
+}
+
+HRESULT CHandler::SetCompressionMethod(
+    CCompressionMethodMode &methodMode,
+    CObjectVector<COneMethodInfo> &methodsInfo
+    #ifdef COMPRESS_MT
+    , UInt32 numThreads
+    #endif
+    )
+{
+  UInt32 level = _level;
+  
+  if (methodsInfo.IsEmpty())
+  {
+    COneMethodInfo oneMethodInfo;
+    oneMethodInfo.MethodName = ((level == 0) ? kCopyMethod : kDefaultMethodName);
+    methodsInfo.Add(oneMethodInfo);
+  }
+
+  bool needSolid = false;
+  for(int i = 0; i < methodsInfo.Size(); i++)
+  {
+    COneMethodInfo &oneMethodInfo = methodsInfo[i];
+    SetCompressionMethod2(oneMethodInfo
+      #ifdef COMPRESS_MT
+      , numThreads
+      #endif
+      );
+
+    if (!IsCopyMethod(oneMethodInfo.MethodName))
+      needSolid = true;
+
+    CMethodFull methodFull;
+
+    if (!FindMethod(
+        EXTERNAL_CODECS_VARS
+        oneMethodInfo.MethodName, methodFull.Id, methodFull.NumInStreams, methodFull.NumOutStreams))
+      return E_INVALIDARG;
+    methodFull.Properties = oneMethodInfo.Properties;
+    methodMode.Methods.Add(methodFull);
+
+    if (!_numSolidBytesDefined)
+    {
+      for (int j = 0; j < methodFull.Properties.Size(); j++)
+      {
+        const CProp &prop = methodFull.Properties[j];
+        if ((prop.Id == NCoderPropID::kDictionarySize || 
+             prop.Id == NCoderPropID::kUsedMemorySize) && prop.Value.vt == VT_UI4)
+        {
+          _numSolidBytes = ((UInt64)prop.Value.ulVal) << 7;
+          const UInt64 kMinSize = (1 << 24);
+          if (_numSolidBytes < kMinSize)
+            _numSolidBytes = kMinSize;
+          _numSolidBytesDefined = true;
+          break;
+        }
+      }
+    }
+  }
+
+  if (!needSolid && !_numSolidBytesDefined)
+  {
+    _numSolidBytesDefined = true;
+    _numSolidBytes  = 0;
+  }
+  return S_OK;
+}
+
+static HRESULT GetTime(IArchiveUpdateCallback *updateCallback, int index, PROPID propID, CArchiveFileTime &filetime, bool &filetimeIsDefined)
+{
+  filetimeIsDefined = false;
+  NCOM::CPropVariant propVariant;
+  RINOK(updateCallback->GetProperty(index, propID, &propVariant));
+  if (propVariant.vt == VT_FILETIME)
+  {
+    filetime = propVariant.filetime;
+    filetimeIsDefined = true;
+  }
+  else if (propVariant.vt != VT_EMPTY)
+    return E_INVALIDARG;
+  return S_OK;
+}
+
+STDMETHODIMP CHandler::UpdateItems(ISequentialOutStream *outStream, UInt32 numItems,
+    IArchiveUpdateCallback *updateCallback)
+{
+  COM_TRY_BEGIN
+
+  const CArchiveDatabaseEx *database = 0;
+  #ifdef _7Z_VOL
+  if(_volumes.Size() > 1)
+    return E_FAIL;
+  const CVolume *volume = 0;
+  if (_volumes.Size() == 1)
+  {
+    volume = &_volumes.Front();
+    database = &volume->Database;
+  }
+  #else
+  if (_inStream != 0)
+    database = &_database;
+  #endif
+
+  // CRecordVector<bool> compressStatuses;
+  CObjectVector<CUpdateItem> updateItems;
+  // CRecordVector<UInt32> copyIndices;
+  
+  // CMyComPtr<IUpdateCallback2> updateCallback2;
+  // updateCallback->QueryInterface(&updateCallback2);
+
+  for(UInt32 i = 0; i < numItems; i++)
+  {
+    Int32 newData;
+    Int32 newProperties;
+    UInt32 indexInArchive;
+    if (!updateCallback)
+      return E_FAIL;
+    RINOK(updateCallback->GetUpdateItemInfo(i,
+        &newData, &newProperties, &indexInArchive));
+    CUpdateItem updateItem;
+    updateItem.NewProperties = IntToBool(newProperties);
+    updateItem.NewData = IntToBool(newData);
+    updateItem.IndexInArchive = indexInArchive;
+    updateItem.IndexInClient = i;
+    updateItem.IsAnti = false;
+    updateItem.Size = 0;
+
+    if (updateItem.IndexInArchive != -1)
+    {
+      const CFileItem &fileItem = database->Files[updateItem.IndexInArchive];
+      updateItem.Name = fileItem.Name;
+      updateItem.IsDirectory = fileItem.IsDirectory;
+      updateItem.Size = fileItem.UnPackSize;
+      updateItem.IsAnti = fileItem.IsAnti;
+      
+      updateItem.CreationTime = fileItem.CreationTime;
+      updateItem.IsCreationTimeDefined = fileItem.IsCreationTimeDefined;
+      updateItem.LastWriteTime = fileItem.LastWriteTime;
+      updateItem.IsLastWriteTimeDefined = fileItem.IsLastWriteTimeDefined;
+      updateItem.LastAccessTime = fileItem.LastAccessTime;
+      updateItem.IsLastAccessTimeDefined = fileItem.IsLastAccessTimeDefined;
+    }
+
+    if (updateItem.NewProperties)
+    {
+      bool nameIsDefined;
+      bool folderStatusIsDefined;
+      {
+        NCOM::CPropVariant propVariant;
+        RINOK(updateCallback->GetProperty(i, kpidAttributes, &propVariant));
+        if (propVariant.vt == VT_EMPTY)
+          updateItem.AttributesAreDefined = false;
+        else if (propVariant.vt != VT_UI4)
+          return E_INVALIDARG;
+        else
+        {
+          updateItem.Attributes = propVariant.ulVal;
+          updateItem.AttributesAreDefined = true;
+        }
+      }
+      
+      RINOK(GetTime(updateCallback, i, kpidCreationTime, updateItem.CreationTime, updateItem.IsCreationTimeDefined));
+      RINOK(GetTime(updateCallback, i, kpidLastWriteTime, updateItem.LastWriteTime , updateItem.IsLastWriteTimeDefined));
+      RINOK(GetTime(updateCallback, i, kpidLastAccessTime, updateItem.LastAccessTime, updateItem.IsLastAccessTimeDefined));
+
+      {
+        NCOM::CPropVariant propVariant;
+        RINOK(updateCallback->GetProperty(i, kpidPath, &propVariant));
+        if (propVariant.vt == VT_EMPTY)
+          nameIsDefined = false;
+        else if (propVariant.vt != VT_BSTR)
+          return E_INVALIDARG;
+        else
+        {
+          updateItem.Name = NItemName::MakeLegalName(propVariant.bstrVal);
+          nameIsDefined = true;
+        }
+      }
+      {
+        NCOM::CPropVariant propVariant;
+        RINOK(updateCallback->GetProperty(i, kpidIsFolder, &propVariant));
+        if (propVariant.vt == VT_EMPTY)
+          folderStatusIsDefined = false;
+        else if (propVariant.vt != VT_BOOL)
+          return E_INVALIDARG;
+        else
+        {
+          updateItem.IsDirectory = (propVariant.boolVal != VARIANT_FALSE);
+          folderStatusIsDefined = true;
+        }
+      }
+
+      {
+        NCOM::CPropVariant propVariant;
+        RINOK(updateCallback->GetProperty(i, kpidIsAnti, &propVariant));
+        if (propVariant.vt == VT_EMPTY)
+          updateItem.IsAnti = false;
+        else if (propVariant.vt != VT_BOOL)
+          return E_INVALIDARG;
+        else
+          updateItem.IsAnti = (propVariant.boolVal != VARIANT_FALSE);
+      }
+
+      if (updateItem.IsAnti)
+      {
+        updateItem.AttributesAreDefined = false;
+
+        updateItem.IsCreationTimeDefined = false;
+        updateItem.IsLastWriteTimeDefined = false;
+        updateItem.IsLastAccessTimeDefined = false;
+        
+        updateItem.Size = 0;
+      }
+
+      if (!folderStatusIsDefined && updateItem.AttributesAreDefined)
+        updateItem.SetDirectoryStatusFromAttributes();
+    }
+
+    if (updateItem.NewData)
+    {
+      NCOM::CPropVariant propVariant;
+      RINOK(updateCallback->GetProperty(i, kpidSize, &propVariant));
+      if (propVariant.vt != VT_UI8)
+        return E_INVALIDARG;
+      updateItem.Size = (UInt64)propVariant.uhVal.QuadPart;
+      if (updateItem.Size != 0 && updateItem.IsAnti)
+        return E_INVALIDARG;
+    }
+    updateItems.Add(updateItem);
+  }
+
+  CCompressionMethodMode methodMode, headerMethod;
+  RINOK(SetCompressionMethod(methodMode, headerMethod));
+  #ifdef COMPRESS_MT
+  methodMode.NumThreads = _numThreads;
+  headerMethod.NumThreads = 1;
+  #endif
+
+  RINOK(SetPassword(methodMode, updateCallback));
+
+  bool compressMainHeader = _compressHeaders;  // check it
+
+  if (methodMode.PasswordIsDefined)
+  {
+    compressMainHeader = true; 
+    if(_encryptHeaders)
+      RINOK(SetPassword(headerMethod, updateCallback));
+  }
+
+  if (numItems < 2)
+    compressMainHeader = false;
+
+  CUpdateOptions options;
+  options.Method = &methodMode;
+  options.HeaderMethod = (_compressHeaders || 
+      (methodMode.PasswordIsDefined && _encryptHeaders)) ? 
+      &headerMethod : 0;
+  options.UseFilters = _level != 0 && _autoFilter;
+  options.MaxFilter = _level >= 8;
+
+  options.HeaderOptions.CompressMainHeader = compressMainHeader;
+  options.HeaderOptions.WriteModified = WriteModified;
+  options.HeaderOptions.WriteCreated = WriteCreated;
+  options.HeaderOptions.WriteAccessed = WriteAccessed;
+  
+  options.NumSolidFiles = _numSolidFiles;
+  options.NumSolidBytes = _numSolidBytes;
+  options.SolidExtension = _solidExtension;
+  options.RemoveSfxBlock = _removeSfxBlock;
+  options.VolumeMode = _volumeMode;
+  return Update(
+      EXTERNAL_CODECS_VARS
+      #ifdef _7Z_VOL
+      volume ? volume->Stream: 0, 
+      volume ? database: 0, 
+      #else
+      _inStream, 
+      database,
+      #endif
+      updateItems, outStream, updateCallback, options);
+  COM_TRY_END
+}
+
+static HRESULT GetBindInfoPart(UString &srcString, UInt32 &coder, UInt32 &stream)
+{
+  stream = 0;
+  int index = ParseStringToUInt32(srcString, coder);
+  if (index == 0)
+    return E_INVALIDARG;
+  srcString.Delete(0, index);
+  if (srcString[0] == 'S')
+  {
+    srcString.Delete(0);
+    int index = ParseStringToUInt32(srcString, stream);
+    if (index == 0)
+      return E_INVALIDARG;
+    srcString.Delete(0, index);
+  }
+  return S_OK;
+}
+
+static HRESULT GetBindInfo(UString &srcString, CBind &bind)
+{
+  RINOK(GetBindInfoPart(srcString, bind.OutCoder, bind.OutStream));
+  if (srcString[0] != ':')
+    return E_INVALIDARG;
+  srcString.Delete(0);
+  RINOK(GetBindInfoPart(srcString, bind.InCoder, bind.InStream));
+  if (!srcString.IsEmpty())
+    return E_INVALIDARG;
+  return S_OK;
+}
+
+STDMETHODIMP CHandler::SetProperties(const wchar_t **names, const PROPVARIANT *values, Int32 numProperties)
+{
+  COM_TRY_BEGIN
+  _binds.Clear();
+  BeforeSetProperty();
+
+  for (int i = 0; i < numProperties; i++)
+  {
+    UString name = names[i];
+    name.MakeUpper();
+    if (name.IsEmpty())
+      return E_INVALIDARG;
+
+    const PROPVARIANT &value = values[i];
+
+    if (name[0] == 'B')
+    {
+      name.Delete(0);
+      CBind bind;
+      RINOK(GetBindInfo(name, bind));
+      _binds.Add(bind);
+      continue;
+    }
+
+    RINOK(SetProperty(name, value));
+  }
+
+  return S_OK;
+  COM_TRY_END
+}  
+
+}}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/misc/libphysfs/lzma/CPP/7zip/Archive/7z/7zHeader.cpp	Mon Apr 10 12:06:43 2017 -0400
@@ -0,0 +1,27 @@
+// 7z/Header.cpp
+
+#include "StdAfx.h"
+#include "7zHeader.h"
+
+namespace NArchive {
+namespace N7z {
+
+Byte kSignature[kSignatureSize] = {'7' + 1, 'z', 0xBC, 0xAF, 0x27, 0x1C};
+#ifdef _7Z_VOL
+Byte kFinishSignature[kSignatureSize] = {'7' + 1, 'z', 0xBC, 0xAF, 0x27, 0x1C + 1};
+#endif
+
+class SignatureInitializer
+{
+public:
+  SignatureInitializer() 
+  { 
+    kSignature[0]--; 
+    #ifdef _7Z_VOL
+    kFinishSignature[0]--;
+    #endif
+  };
+} g_SignatureInitializer;
+
+}}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/misc/libphysfs/lzma/CPP/7zip/Archive/7z/7zHeader.h	Mon Apr 10 12:06:43 2017 -0400
@@ -0,0 +1,96 @@
+// 7z/7zHeader.h
+
+#ifndef __7Z_HEADER_H
+#define __7Z_HEADER_H
+
+#include "../../../Common/Types.h"
+
+namespace NArchive {
+namespace N7z {
+
+const int kSignatureSize = 6;
+extern Byte kSignature[kSignatureSize];
+
+// #define _7Z_VOL
+// 7z-MultiVolume is not finished yet.
+// It can work already, but I still do not like some 
+// things of that new multivolume format.
+// So please keep it commented.
+
+#ifdef _7Z_VOL
+extern Byte kFinishSignature[kSignatureSize];
+#endif
+
+struct CArchiveVersion
+{
+  Byte Major;
+  Byte Minor;
+};
+
+const Byte kMajorVersion = 0;
+
+struct CStartHeader
+{
+  UInt64 NextHeaderOffset;
+  UInt64 NextHeaderSize;
+  UInt32 NextHeaderCRC;
+};
+
+const UInt32 kStartHeaderSize = 20;
+
+#ifdef _7Z_VOL
+struct CFinishHeader: public CStartHeader
+{
+  UInt64 ArchiveStartOffset;  // data offset from end if that struct
+  UInt64 AdditionalStartBlockSize; // start  signature & start header size
+};
+
+const UInt32 kFinishHeaderSize = kStartHeaderSize + 16;
+#endif
+
+namespace NID
+{
+  enum EEnum
+  {
+    kEnd,
+
+    kHeader,
+
+    kArchiveProperties,
+    
+    kAdditionalStreamsInfo,
+    kMainStreamsInfo,
+    kFilesInfo,
+    
+    kPackInfo,
+    kUnPackInfo,
+    kSubStreamsInfo,
+
+    kSize,
+    kCRC,
+
+    kFolder,
+
+    kCodersUnPackSize,
+    kNumUnPackStream,
+
+    kEmptyStream,
+    kEmptyFile,
+    kAnti,
+
+    kName,
+    kCreationTime,
+    kLastAccessTime,
+    kLastWriteTime,
+    kWinAttributes,
+    kComment,
+
+    kEncodedHeader,
+
+    kStartPos
+  };
+}
+
+}}
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/misc/libphysfs/lzma/CPP/7zip/Archive/7z/7zIn.cpp	Mon Apr 10 12:06:43 2017 -0400
@@ -0,0 +1,1206 @@
+// 7zIn.cpp
+
+#include "StdAfx.h"
+
+#include "7zIn.h"
+#include "7zDecode.h"
+#include "../../Common/StreamObjects.h"
+#include "../../Common/StreamUtils.h"
+extern "C" 
+{ 
+#include "../../../../C/7zCrc.h"
+}
+
+// define FORMAT_7Z_RECOVERY if you want to recover multivolume archives with empty StartHeader 
+#ifndef _SFX
+#define FORMAT_7Z_RECOVERY
+#endif
+
+namespace NArchive {
+namespace N7z {
+
+class CInArchiveException {};
+
+static void ThrowException() { throw CInArchiveException(); }
+static inline void ThrowEndOfData()   { ThrowException(); }
+static inline void ThrowUnsupported() { ThrowException(); }
+static inline void ThrowIncorrect()   { ThrowException(); }
+static inline void ThrowUnsupportedVersion() { ThrowException(); }
+
+/*
+class CInArchiveException
+{
+public:
+  enum CCauseType
+  {
+    kUnsupportedVersion = 0,
+    kUnsupported,
+    kIncorrect, 
+    kEndOfData,
+  } Cause;
+  CInArchiveException(CCauseType cause): Cause(cause) {};
+};
+
+static void ThrowException(CInArchiveException::CCauseType c) { throw CInArchiveException(c); }
+static void ThrowEndOfData()   { ThrowException(CInArchiveException::kEndOfData); }
+static void ThrowUnsupported() { ThrowException(CInArchiveException::kUnsupported); }
+static void ThrowIncorrect()   { ThrowException(CInArchiveException::kIncorrect); }
+static void ThrowUnsupportedVersion() { ThrowException(CInArchiveException::kUnsupportedVersion); }
+*/
+
+class CStreamSwitch
+{
+  CInArchive *_archive;
+  bool _needRemove;
+public:
+  CStreamSwitch(): _needRemove(false) {}
+  ~CStreamSwitch() { Remove(); }
+  void Remove();
+  void Set(CInArchive *archive, const Byte *data, size_t size);
+  void Set(CInArchive *archive, const CByteBuffer &byteBuffer);
+  void Set(CInArchive *archive, const CObjectVector<CByteBuffer> *dataVector);
+};
+
+void CStreamSwitch::Remove()
+{
+  if (_needRemove)
+  {
+    _archive->DeleteByteStream();
+    _needRemove = false;
+  }
+}
+
+void CStreamSwitch::Set(CInArchive *archive, const Byte *data, size_t size)
+{
+  Remove();
+  _archive = archive;
+  _archive->AddByteStream(data, size);
+  _needRemove = true;
+}
+
+void CStreamSwitch::Set(CInArchive *archive, const CByteBuffer &byteBuffer)
+{
+  Set(archive, byteBuffer, byteBuffer.GetCapacity());
+}
+
+void CStreamSwitch::Set(CInArchive *archive, const CObjectVector<CByteBuffer> *dataVector)
+{
+  Remove();
+  Byte external = archive->ReadByte();
+  if (external != 0)
+  {
+    int dataIndex = (int)archive->ReadNum();
+    if (dataIndex < 0 || dataIndex >= dataVector->Size())
+      ThrowIncorrect();
+    Set(archive, (*dataVector)[dataIndex]);
+  }
+}
+
+#if defined(_M_IX86) || defined(_M_X64) || defined(_M_AMD64) || defined(__i386__) || defined(__x86_64__)
+#define SZ_LITTLE_ENDIAN_UNALIGN
+#endif
+
+#ifdef SZ_LITTLE_ENDIAN_UNALIGN
+static inline UInt16 GetUInt16FromMem(const Byte *p) { return *(const UInt16 *)p; }
+static inline UInt32 GetUInt32FromMem(const Byte *p) { return *(const UInt32 *)p; }
+static inline UInt64 GetUInt64FromMem(const Byte *p) { return *(const UInt64 *)p; }
+#else
+static inline UInt16 GetUInt16FromMem(const Byte *p) { return p[0] | ((UInt16)p[1] << 8); }
+static inline UInt32 GetUInt32FromMem(const Byte *p) { return p[0] | ((UInt32)p[1] << 8) | ((UInt32)p[2] << 16) | ((UInt32)p[3] << 24); }
+static inline UInt64 GetUInt64FromMem(const Byte *p) { return GetUInt32FromMem(p) | ((UInt64)GetUInt32FromMem(p + 4) << 32); }
+#endif
+
+Byte CInByte2::ReadByte()
+{
+  if (_pos >= _size)
+    ThrowEndOfData();
+  return _buffer[_pos++];
+}
+
+void CInByte2::ReadBytes(Byte *data, size_t size)
+{
+  if (size > _size - _pos)
+    ThrowEndOfData();
+  for (size_t i = 0; i < size; i++)
+    data[i] = _buffer[_pos++];
+}
+
+void CInByte2::SkeepData(UInt64 size)
+{
+  if (size > _size - _pos)
+    ThrowEndOfData();
+}
+
+void CInByte2::SkeepData()
+{
+  SkeepData(ReadNumber());
+}
+
+UInt64 CInByte2::ReadNumber()
+{
+  if (_pos >= _size)
+    ThrowEndOfData();
+  Byte firstByte = _buffer[_pos++];
+  Byte mask = 0x80;
+  UInt64 value = 0;
+  for (int i = 0; i < 8; i++)
+  {
+    if ((firstByte & mask) == 0)
+    {
+      UInt64 highPart = firstByte & (mask - 1);
+      value += (highPart << (i * 8));
+      return value;
+    }
+    if (_pos >= _size)
+      ThrowEndOfData();
+    value |= ((UInt64)_buffer[_pos++] << (8 * i));
+    mask >>= 1;
+  }
+  return value;
+}
+
+CNum CInByte2::ReadNum()
+{ 
+  UInt64 value = ReadNumber(); 
+  if (value > kNumMax)
+    ThrowUnsupported();
+  return (CNum)value;
+}
+
+UInt32 CInByte2::ReadUInt32()
+{
+  if (_pos + 4 > _size)
+    ThrowEndOfData();
+  UInt32 res = GetUInt32FromMem(_buffer + _pos);
+  _pos += 4;
+  return res;
+}
+
+UInt64 CInByte2::ReadUInt64()
+{
+  if (_pos + 8 > _size)
+    ThrowEndOfData();
+  UInt64 res = GetUInt64FromMem(_buffer + _pos);
+  _pos += 8;
+  return res;
+}
+
+void CInByte2::ReadString(UString &s)
+{
+  const Byte *buf = _buffer + _pos;
+  size_t rem = (_size - _pos) / 2 * 2;
+  {
+    size_t i;
+    for (i = 0; i < rem; i += 2)
+      if (buf[i] == 0 && buf[i + 1] == 0)
+        break;
+    if (i == rem)
+      ThrowEndOfData();
+    rem = i;
+  }
+  int len = (int)(rem / 2);
+  if (len < 0 || (size_t)len * 2 != rem)
+    ThrowUnsupported();
+  wchar_t *p = s.GetBuffer(len);
+  int i;
+  for (i = 0; i < len; i++, buf += 2) 
+    p[i] = (wchar_t)GetUInt16FromMem(buf);
+  p[i] = 0;
+  s.ReleaseBuffer(len);
+  _pos += rem + 2;
+}
+
+static inline bool TestSignatureCandidate(const Byte *p)
+{
+  for (int i = 0; i < kSignatureSize; i++)
+    if (p[i] != kSignature[i])
+      return false;
+  return (p[0x1A] == 0 && p[0x1B] == 0);
+}
+
+HRESULT CInArchive::FindAndReadSignature(IInStream *stream, const UInt64 *searchHeaderSizeLimit)
+{
+  UInt32 processedSize; 
+  RINOK(ReadStream(stream, _header, kHeaderSize, &processedSize));
+  if (processedSize != kHeaderSize)
+    return S_FALSE;
+  if (TestSignatureCandidate(_header))
+    return S_OK;
+
+  CByteBuffer byteBuffer;
+  const UInt32 kBufferSize = (1 << 16);
+  byteBuffer.SetCapacity(kBufferSize);
+  Byte *buffer = byteBuffer;
+  UInt32 numPrevBytes = kHeaderSize - 1;
+  memcpy(buffer, _header + 1, numPrevBytes);
+  UInt64 curTestPos = _arhiveBeginStreamPosition + 1;
+  for (;;)
+  {
+    if (searchHeaderSizeLimit != NULL)
+      if (curTestPos - _arhiveBeginStreamPosition > *searchHeaderSizeLimit)
+        break;
+    UInt32 numReadBytes = kBufferSize - numPrevBytes;
+    RINOK(stream->Read(buffer + numPrevBytes, numReadBytes, &processedSize));
+    UInt32 numBytesInBuffer = numPrevBytes + processedSize;
+    if (numBytesInBuffer < kHeaderSize)
+      break;
+    UInt32 numTests = numBytesInBuffer - kHeaderSize + 1;
+    for(UInt32 pos = 0; pos < numTests; pos++, curTestPos++)
+    { 
+      if (TestSignatureCandidate(buffer + pos))
+      {
+        memcpy(_header, buffer + pos, kHeaderSize);
+        _arhiveBeginStreamPosition = curTestPos;
+        return stream->Seek(curTestPos + kHeaderSize, STREAM_SEEK_SET, NULL);
+      }
+    }
+    numPrevBytes = numBytesInBuffer - numTests;
+    memmove(buffer, buffer + numTests, numPrevBytes);
+  }
+  return S_FALSE;
+}
+
+// S_FALSE means that file is not archive
+HRESULT CInArchive::Open(IInStream *stream, const UInt64 *searchHeaderSizeLimit)
+{
+  Close();
+  RINOK(stream->Seek(0, STREAM_SEEK_CUR, &_arhiveBeginStreamPosition))
+  RINOK(FindAndReadSignature(stream, searchHeaderSizeLimit));
+  _stream = stream;
+  return S_OK;
+}
+  
+void CInArchive::Close()
+{
+  _stream.Release();
+}
+
+void CInArchive::ReadArchiveProperties(CInArchiveInfo & /* archiveInfo */)
+{
+  for (;;)
+  {
+    if (ReadID() == NID::kEnd)
+      break;
+    SkeepData();
+  }
+}
+
+void CInArchive::GetNextFolderItem(CFolder &folder)
+{
+  CNum numCoders = ReadNum();
+
+  folder.Coders.Clear();
+  folder.Coders.Reserve((int)numCoders);
+  CNum numInStreams = 0;
+  CNum numOutStreams = 0;
+  CNum i;
+  for (i = 0; i < numCoders; i++)
+  {
+    folder.Coders.Add(CCoderInfo());
+    CCoderInfo &coder = folder.Coders.Back();
+
+    {
+      Byte mainByte = ReadByte();
+      int idSize = (mainByte & 0xF);
+      Byte longID[15];
+      ReadBytes(longID, idSize);
+      if (idSize > 8)
+        ThrowUnsupported();
+      UInt64 id = 0;
+      for (int j = 0; j < idSize; j++)
+        id |= (UInt64)longID[idSize - 1 - j] << (8 * j);
+      coder.MethodID = id;
+
+      if ((mainByte & 0x10) != 0)
+      {
+        coder.NumInStreams = ReadNum();
+        coder.NumOutStreams = ReadNum();
+      }
+      else
+      {
+        coder.NumInStreams = 1;
+        coder.NumOutStreams = 1;
+      }
+      if ((mainByte & 0x20) != 0)
+      {
+        CNum propertiesSize = ReadNum();
+        coder.Properties.SetCapacity((size_t)propertiesSize);
+        ReadBytes((Byte *)coder.Properties, (size_t)propertiesSize);
+      }
+      if ((mainByte & 0x80) != 0)
+        ThrowUnsupported();
+    }
+    numInStreams += coder.NumInStreams;
+    numOutStreams += coder.NumOutStreams;
+  }
+
+  CNum numBindPairs;
+  numBindPairs = numOutStreams - 1;
+  folder.BindPairs.Clear();
+  folder.BindPairs.Reserve(numBindPairs);
+  for (i = 0; i < numBindPairs; i++)
+  {
+    CBindPair bindPair;
+    bindPair.InIndex = ReadNum();
+    bindPair.OutIndex = ReadNum(); 
+    folder.BindPairs.Add(bindPair);
+  }
+
+  CNum numPackedStreams = numInStreams - numBindPairs;
+  folder.PackStreams.Reserve(numPackedStreams);
+  if (numPackedStreams == 1)
+  {
+    for (CNum j = 0; j < numInStreams; j++)
+      if (folder.FindBindPairForInStream(j) < 0)
+      {
+        folder.PackStreams.Add(j);
+        break;
+      }
+  }
+  else
+    for(i = 0; i < numPackedStreams; i++)
+      folder.PackStreams.Add(ReadNum());
+}
+
+void CInArchive::WaitAttribute(UInt64 attribute)
+{
+  for (;;)
+  {
+    UInt64 type = ReadID();
+    if (type == attribute)
+      return;
+    if (type == NID::kEnd)
+      ThrowIncorrect();
+    SkeepData();
+  }
+}
+
+void CInArchive::ReadHashDigests(int numItems,
+    CRecordVector<bool> &digestsDefined, 
+    CRecordVector<UInt32> &digests)
+{
+  ReadBoolVector2(numItems, digestsDefined);
+  digests.Clear();
+  digests.Reserve(numItems);
+  for(int i = 0; i < numItems; i++)
+  {
+    UInt32 crc = 0;
+    if (digestsDefined[i])
+      crc = ReadUInt32();
+    digests.Add(crc);
+  }
+}
+
+void CInArchive::ReadPackInfo(
+    UInt64 &dataOffset,
+    CRecordVector<UInt64> &packSizes,
+    CRecordVector<bool> &packCRCsDefined,
+    CRecordVector<UInt32> &packCRCs)
+{
+  dataOffset = ReadNumber();
+  CNum numPackStreams = ReadNum();
+
+  WaitAttribute(NID::kSize);
+  packSizes.Clear();
+  packSizes.Reserve(numPackStreams);
+  for (CNum i = 0; i < numPackStreams; i++)
+    packSizes.Add(ReadNumber());
+
+  UInt64 type;
+  for (;;)
+  {
+    type = ReadID();
+    if (type == NID::kEnd)
+      break;
+    if (type == NID::kCRC)
+    {
+      ReadHashDigests(numPackStreams, packCRCsDefined, packCRCs); 
+      continue;
+    }
+    SkeepData();
+  }
+  if (packCRCsDefined.IsEmpty())
+  {
+    packCRCsDefined.Reserve(numPackStreams);
+    packCRCsDefined.Clear();
+    packCRCs.Reserve(numPackStreams);
+    packCRCs.Clear();
+    for(CNum i = 0; i < numPackStreams; i++)
+    {
+      packCRCsDefined.Add(false);
+      packCRCs.Add(0);
+    }
+  }
+}
+
+void CInArchive::ReadUnPackInfo(
+    const CObjectVector<CByteBuffer> *dataVector,
+    CObjectVector<CFolder> &folders)
+{
+  WaitAttribute(NID::kFolder);
+  CNum numFolders = ReadNum();
+
+  {
+    CStreamSwitch streamSwitch;
+    streamSwitch.Set(this, dataVector);
+    folders.Clear();
+    folders.Reserve(numFolders);
+    for(CNum i = 0; i < numFolders; i++)
+    {
+      folders.Add(CFolder());
+      GetNextFolderItem(folders.Back());
+    }
+  }
+
+  WaitAttribute(NID::kCodersUnPackSize);
+
+  CNum i;
+  for (i = 0; i < numFolders; i++)
+  {
+    CFolder &folder = folders[i];
+    CNum numOutStreams = folder.GetNumOutStreams();
+    folder.UnPackSizes.Reserve(numOutStreams);
+    for (CNum j = 0; j < numOutStreams; j++)
+      folder.UnPackSizes.Add(ReadNumber());
+  }
+
+  for (;;)
+  {
+    UInt64 type = ReadID();
+    if (type == NID::kEnd)
+      return;
+    if (type == NID::kCRC)
+    {
+      CRecordVector<bool> crcsDefined;
+      CRecordVector<UInt32> crcs;
+      ReadHashDigests(numFolders, crcsDefined, crcs); 
+      for(i = 0; i < numFolders; i++)
+      {
+        CFolder &folder = folders[i];
+        folder.UnPackCRCDefined = crcsDefined[i];
+        folder.UnPackCRC = crcs[i];
+      }
+      continue;
+    }
+    SkeepData();
+  }
+}
+
+void CInArchive::ReadSubStreamsInfo(
+    const CObjectVector<CFolder> &folders,
+    CRecordVector<CNum> &numUnPackStreamsInFolders,
+    CRecordVector<UInt64> &unPackSizes,
+    CRecordVector<bool> &digestsDefined, 
+    CRecordVector<UInt32> &digests)
+{
+  numUnPackStreamsInFolders.Clear();
+  numUnPackStreamsInFolders.Reserve(folders.Size());
+  UInt64 type;
+  for (;;)
+  {
+    type = ReadID();
+    if (type == NID::kNumUnPackStream)
+    {
+      for(int i = 0; i < folders.Size(); i++)
+        numUnPackStreamsInFolders.Add(ReadNum());
+      continue;
+    }
+    if (type == NID::kCRC || type == NID::kSize)
+      break;
+    if (type == NID::kEnd)
+      break;
+    SkeepData();
+  }
+
+  if (numUnPackStreamsInFolders.IsEmpty())
+    for(int i = 0; i < folders.Size(); i++)
+      numUnPackStreamsInFolders.Add(1);
+
+  int i;
+  for(i = 0; i < numUnPackStreamsInFolders.Size(); i++)
+  {
+    // v3.13 incorrectly worked with empty folders
+    // v4.07: we check that folder is empty
+    CNum numSubstreams = numUnPackStreamsInFolders[i];
+    if (numSubstreams == 0)
+      continue;
+    UInt64 sum = 0;
+    for (CNum j = 1; j < numSubstreams; j++)
+      if (type == NID::kSize)
+      {
+        UInt64 size = ReadNumber();
+        unPackSizes.Add(size);
+        sum += size;
+      }
+    unPackSizes.Add(folders[i].GetUnPackSize() - sum);
+  }
+  if (type == NID::kSize)
+    type = ReadID();
+
+  int numDigests = 0;
+  int numDigestsTotal = 0;
+  for(i = 0; i < folders.Size(); i++)
+  {
+    CNum numSubstreams = numUnPackStreamsInFolders[i];
+    if (numSubstreams != 1 || !folders[i].UnPackCRCDefined)
+      numDigests += numSubstreams;
+    numDigestsTotal += numSubstreams;
+  }
+
+  for (;;)
+  {
+    if (type == NID::kCRC)
+    {
+      CRecordVector<bool> digestsDefined2; 
+      CRecordVector<UInt32> digests2;
+      ReadHashDigests(numDigests, digestsDefined2, digests2);
+      int digestIndex = 0;
+      for (i = 0; i < folders.Size(); i++)
+      {
+        CNum numSubstreams = numUnPackStreamsInFolders[i];
+        const CFolder &folder = folders[i];
+        if (numSubstreams == 1 && folder.UnPackCRCDefined)
+        {
+          digestsDefined.Add(true);
+          digests.Add(folder.UnPackCRC);
+        }
+        else
+          for (CNum j = 0; j < numSubstreams; j++, digestIndex++)
+          {
+            digestsDefined.Add(digestsDefined2[digestIndex]);
+            digests.Add(digests2[digestIndex]);
+          }
+      }
+    }
+    else if (type == NID::kEnd)
+    {
+      if (digestsDefined.IsEmpty())
+      {
+        digestsDefined.Clear();
+        digests.Clear();
+        for (int i = 0; i < numDigestsTotal; i++)
+        {
+          digestsDefined.Add(false);
+          digests.Add(0);
+        }
+      }
+      return;
+    }
+    else
+      SkeepData();
+    type = ReadID();
+  }
+}
+
+void CInArchive::ReadStreamsInfo(
+    const CObjectVector<CByteBuffer> *dataVector,
+    UInt64 &dataOffset,
+    CRecordVector<UInt64> &packSizes,
+    CRecordVector<bool> &packCRCsDefined,
+    CRecordVector<UInt32> &packCRCs,
+    CObjectVector<CFolder> &folders,
+    CRecordVector<CNum> &numUnPackStreamsInFolders,
+    CRecordVector<UInt64> &unPackSizes,
+    CRecordVector<bool> &digestsDefined, 
+    CRecordVector<UInt32> &digests)
+{
+  for (;;)
+  {
+    UInt64 type = ReadID();
+    if (type > ((UInt32)1 << 30))
+      ThrowIncorrect();
+    switch((UInt32)type)
+    {
+      case NID::kEnd:
+        return;
+      case NID::kPackInfo:
+      {
+        ReadPackInfo(dataOffset, packSizes, packCRCsDefined, packCRCs);
+        break;
+      }
+      case NID::kUnPackInfo:
+      {
+        ReadUnPackInfo(dataVector, folders);
+        break;
+      }
+      case NID::kSubStreamsInfo:
+      {
+        ReadSubStreamsInfo(folders, numUnPackStreamsInFolders,
+            unPackSizes, digestsDefined, digests);
+        break;
+      }
+      default:
+        ThrowIncorrect();
+    }
+  }
+}
+
+void CInArchive::ReadBoolVector(int numItems, CBoolVector &v)
+{
+  v.Clear();
+  v.Reserve(numItems);
+  Byte b = 0;
+  Byte mask = 0;
+  for(int i = 0; i < numItems; i++)
+  {
+    if (mask == 0)
+    {
+      b = ReadByte();
+      mask = 0x80;
+    }
+    v.Add((b & mask) != 0);
+    mask >>= 1;
+  }
+}
+
+void CInArchive::ReadBoolVector2(int numItems, CBoolVector &v)
+{
+  Byte allAreDefined = ReadByte();
+  if (allAreDefined == 0)
+  {
+    ReadBoolVector(numItems, v);
+    return;
+  }
+  v.Clear();
+  v.Reserve(numItems);
+  for (int i = 0; i < numItems; i++)
+    v.Add(true);
+}
+
+void CInArchive::ReadTime(const CObjectVector<CByteBuffer> &dataVector,
+    CObjectVector<CFileItem> &files, UInt32 type)
+{
+  CBoolVector boolVector;
+  ReadBoolVector2(files.Size(), boolVector);
+
+  CStreamSwitch streamSwitch;
+  streamSwitch.Set(this, &dataVector);
+
+  for(int i = 0; i < files.Size(); i++)
+  {
+    CFileItem &file = files[i];
+    CArchiveFileTime fileTime;
+    fileTime.dwLowDateTime = 0;
+    fileTime.dwHighDateTime = 0;
+    bool defined = boolVector[i];
+    if (defined)
+    {
+      fileTime.dwLowDateTime = ReadUInt32();
+      fileTime.dwHighDateTime = ReadUInt32();
+    }
+    switch(type)
+    {
+      case NID::kCreationTime:
+        file.IsCreationTimeDefined = defined;
+        if (defined)
+          file.CreationTime = fileTime;
+        break;
+      case NID::kLastWriteTime:
+        file.IsLastWriteTimeDefined = defined;
+        if (defined)
+          file.LastWriteTime = fileTime;
+        break;
+      case NID::kLastAccessTime:
+        file.IsLastAccessTimeDefined = defined;
+        if (defined)
+          file.LastAccessTime = fileTime;
+        break;
+    }
+  }
+}
+
+HRESULT CInArchive::ReadAndDecodePackedStreams(
+    DECL_EXTERNAL_CODECS_LOC_VARS
+    UInt64 baseOffset, 
+    UInt64 &dataOffset, CObjectVector<CByteBuffer> &dataVector
+    #ifndef _NO_CRYPTO
+    , ICryptoGetTextPassword *getTextPassword
+    #endif
+    )
+{
+  CRecordVector<UInt64> packSizes;
+  CRecordVector<bool> packCRCsDefined;
+  CRecordVector<UInt32> packCRCs;
+  CObjectVector<CFolder> folders;
+  
+  CRecordVector<CNum> numUnPackStreamsInFolders;
+  CRecordVector<UInt64> unPackSizes;
+  CRecordVector<bool> digestsDefined;
+  CRecordVector<UInt32> digests;
+  
+  ReadStreamsInfo(NULL, 
+    dataOffset,
+    packSizes, 
+    packCRCsDefined, 
+    packCRCs, 
+    folders,
+    numUnPackStreamsInFolders,
+    unPackSizes,
+    digestsDefined, 
+    digests);
+  
+  // database.ArchiveInfo.DataStartPosition2 += database.ArchiveInfo.StartPositionAfterHeader;
+  
+  CNum packIndex = 0;
+  CDecoder decoder(
+    #ifdef _ST_MODE
+    false
+    #else
+    true
+    #endif
+    );
+  UInt64 dataStartPos = baseOffset + dataOffset;
+  for(int i = 0; i < folders.Size(); i++)
+  {
+    const CFolder &folder = folders[i];
+    dataVector.Add(CByteBuffer());
+    CByteBuffer &data = dataVector.Back();
+    UInt64 unPackSize64 = folder.GetUnPackSize();
+    size_t unPackSize = (size_t)unPackSize64;
+    if (unPackSize != unPackSize64)
+      ThrowUnsupported();
+    data.SetCapacity(unPackSize);
+    
+    CSequentialOutStreamImp2 *outStreamSpec = new CSequentialOutStreamImp2;
+    CMyComPtr<ISequentialOutStream> outStream = outStreamSpec;
+    outStreamSpec->Init(data, unPackSize);
+    
+    HRESULT result = decoder.Decode(
+      EXTERNAL_CODECS_LOC_VARS
+      _stream, dataStartPos, 
+      &packSizes[packIndex], folder, outStream, NULL
+      #ifndef _NO_CRYPTO
+      , getTextPassword
+      #endif
+      #ifdef COMPRESS_MT
+      , false, 1
+      #endif
+      );
+    RINOK(result);
+    
+    if (folder.UnPackCRCDefined)
+      if (CrcCalc(data, unPackSize) != folder.UnPackCRC)
+        ThrowIncorrect();
+      for (int j = 0; j < folder.PackStreams.Size(); j++)
+        dataStartPos += packSizes[packIndex++];
+  }
+  return S_OK;
+}
+
+HRESULT CInArchive::ReadHeader(
+    DECL_EXTERNAL_CODECS_LOC_VARS
+    CArchiveDatabaseEx &database
+    #ifndef _NO_CRYPTO
+    , ICryptoGetTextPassword *getTextPassword
+    #endif
+    )
+{
+  UInt64 type = ReadID();
+
+  if (type == NID::kArchiveProperties)
+  {
+    ReadArchiveProperties(database.ArchiveInfo);
+    type = ReadID();
+  }
+ 
+  CObjectVector<CByteBuffer> dataVector;
+  
+  if (type == NID::kAdditionalStreamsInfo)
+  {
+    HRESULT result = ReadAndDecodePackedStreams(
+        EXTERNAL_CODECS_LOC_VARS
+        database.ArchiveInfo.StartPositionAfterHeader, 
+        database.ArchiveInfo.DataStartPosition2,
+        dataVector
+        #ifndef _NO_CRYPTO
+        , getTextPassword
+        #endif
+        );
+    RINOK(result);
+    database.ArchiveInfo.DataStartPosition2 += database.ArchiveInfo.StartPositionAfterHeader;
+    type = ReadID();
+  }
+
+  CRecordVector<UInt64> unPackSizes;
+  CRecordVector<bool> digestsDefined;
+  CRecordVector<UInt32> digests;
+  
+  if (type == NID::kMainStreamsInfo)
+  {
+    ReadStreamsInfo(&dataVector,
+        database.ArchiveInfo.DataStartPosition,
+        database.PackSizes, 
+        database.PackCRCsDefined, 
+        database.PackCRCs, 
+        database.Folders,
+        database.NumUnPackStreamsVector,
+        unPackSizes,
+        digestsDefined,
+        digests);
+    database.ArchiveInfo.DataStartPosition += database.ArchiveInfo.StartPositionAfterHeader;
+    type = ReadID();
+  }
+  else
+  {
+    for(int i = 0; i < database.Folders.Size(); i++)
+    {
+      database.NumUnPackStreamsVector.Add(1);
+      CFolder &folder = database.Folders[i];
+      unPackSizes.Add(folder.GetUnPackSize());
+      digestsDefined.Add(folder.UnPackCRCDefined);
+      digests.Add(folder.UnPackCRC);
+    }
+  }
+
+  database.Files.Clear();
+
+  if (type == NID::kEnd)
+    return S_OK;
+  if (type != NID::kFilesInfo)
+    ThrowIncorrect();
+  
+  CNum numFiles = ReadNum();
+  database.Files.Reserve(numFiles);
+  CNum i;
+  for(i = 0; i < numFiles; i++)
+    database.Files.Add(CFileItem());
+
+  database.ArchiveInfo.FileInfoPopIDs.Add(NID::kSize);
+  if (!database.PackSizes.IsEmpty())
+    database.ArchiveInfo.FileInfoPopIDs.Add(NID::kPackInfo);
+  if (numFiles > 0  && !digests.IsEmpty())
+    database.ArchiveInfo.FileInfoPopIDs.Add(NID::kCRC);
+
+  CBoolVector emptyStreamVector;
+  emptyStreamVector.Reserve((int)numFiles);
+  for(i = 0; i < numFiles; i++)
+    emptyStreamVector.Add(false);
+  CBoolVector emptyFileVector;
+  CBoolVector antiFileVector;
+  CNum numEmptyStreams = 0;
+
+  for (;;)
+  {
+    UInt64 type = ReadID();
+    if (type == NID::kEnd)
+      break;
+    UInt64 size = ReadNumber();
+    bool isKnownType = true;
+    if (type > ((UInt32)1 << 30))
+      isKnownType = false;
+    else switch((UInt32)type)
+    {
+      case NID::kName:
+      {
+        CStreamSwitch streamSwitch;
+        streamSwitch.Set(this, &dataVector);
+        for(int i = 0; i < database.Files.Size(); i++)
+          _inByteBack->ReadString(database.Files[i].Name);
+        break;
+      }
+      case NID::kWinAttributes:
+      {
+        CBoolVector boolVector;
+        ReadBoolVector2(database.Files.Size(), boolVector);
+        CStreamSwitch streamSwitch;
+        streamSwitch.Set(this, &dataVector);
+        for(i = 0; i < numFiles; i++)
+        {
+          CFileItem &file = database.Files[i];
+          file.AreAttributesDefined = boolVector[i];
+          if (file.AreAttributesDefined)
+            file.Attributes = ReadUInt32();
+        }
+        break;
+      }
+      case NID::kStartPos:
+      {
+        CBoolVector boolVector;
+        ReadBoolVector2(database.Files.Size(), boolVector);
+        CStreamSwitch streamSwitch;
+        streamSwitch.Set(this, &dataVector);
+        for(i = 0; i < numFiles; i++)
+        {
+          CFileItem &file = database.Files[i];
+          file.IsStartPosDefined = boolVector[i];
+          if (file.IsStartPosDefined)
+            file.StartPos = ReadUInt64();
+        }
+        break;
+      }
+      case NID::kEmptyStream:
+      {
+        ReadBoolVector(numFiles, emptyStreamVector);
+        for (i = 0; i < (CNum)emptyStreamVector.Size(); i++)
+          if (emptyStreamVector[i])
+            numEmptyStreams++;
+        emptyFileVector.Reserve(numEmptyStreams);
+        antiFileVector.Reserve(numEmptyStreams);
+        for (i = 0; i < numEmptyStreams; i++)
+        {
+          emptyFileVector.Add(false);
+          antiFileVector.Add(false);
+        }
+        break;
+      }
+      case NID::kEmptyFile:
+      {
+        ReadBoolVector(numEmptyStreams, emptyFileVector);
+        break;
+      }
+      case NID::kAnti:
+      {
+        ReadBoolVector(numEmptyStreams, antiFileVector);
+        break;
+      }
+      case NID::kCreationTime:
+      case NID::kLastWriteTime:
+      case NID::kLastAccessTime:
+      {
+        ReadTime(dataVector, database.Files, (UInt32)type);
+        break;
+      }
+      default:
+        isKnownType = false;
+    }
+    if (isKnownType)
+      database.ArchiveInfo.FileInfoPopIDs.Add(type);
+    else
+      SkeepData(size);
+  }
+
+  CNum emptyFileIndex = 0;
+  CNum sizeIndex = 0;
+  for(i = 0; i < numFiles; i++)
+  {
+    CFileItem &file = database.Files[i];
+    file.HasStream = !emptyStreamVector[i];
+    if(file.HasStream)
+    {
+      file.IsDirectory = false;
+      file.IsAnti = false;
+      file.UnPackSize = unPackSizes[sizeIndex];
+      file.FileCRC = digests[sizeIndex];
+      file.IsFileCRCDefined = digestsDefined[sizeIndex];
+      sizeIndex++;
+    }
+    else
+    {
+      file.IsDirectory = !emptyFileVector[emptyFileIndex];
+      file.IsAnti = antiFileVector[emptyFileIndex];
+      emptyFileIndex++;
+      file.UnPackSize = 0;
+      file.IsFileCRCDefined = false;
+    }
+  }
+  return S_OK;
+}
+
+
+void CArchiveDatabaseEx::FillFolderStartPackStream()
+{
+  FolderStartPackStreamIndex.Clear();
+  FolderStartPackStreamIndex.Reserve(Folders.Size());
+  CNum startPos = 0;
+  for(int i = 0; i < Folders.Size(); i++)
+  {
+    FolderStartPackStreamIndex.Add(startPos);
+    startPos += (CNum)Folders[i].PackStreams.Size();
+  }
+}
+
+void CArchiveDatabaseEx::FillStartPos()
+{
+  PackStreamStartPositions.Clear();
+  PackStreamStartPositions.Reserve(PackSizes.Size());
+  UInt64 startPos = 0;
+  for(int i = 0; i < PackSizes.Size(); i++)
+  {
+    PackStreamStartPositions.Add(startPos);
+    startPos += PackSizes[i];
+  }
+}
+
+void CArchiveDatabaseEx::FillFolderStartFileIndex()
+{
+  FolderStartFileIndex.Clear();
+  FolderStartFileIndex.Reserve(Folders.Size());
+  FileIndexToFolderIndexMap.Clear();
+  FileIndexToFolderIndexMap.Reserve(Files.Size());
+  
+  int folderIndex = 0;
+  CNum indexInFolder = 0;
+  for (int i = 0; i < Files.Size(); i++)
+  {
+    const CFileItem &file = Files[i];
+    bool emptyStream = !file.HasStream;
+    if (emptyStream && indexInFolder == 0)
+    {
+      FileIndexToFolderIndexMap.Add(kNumNoIndex);
+      continue;
+    }
+    if (indexInFolder == 0)
+    {
+      // v3.13 incorrectly worked with empty folders
+      // v4.07: Loop for skipping empty folders
+      for (;;)
+      {
+        if (folderIndex >= Folders.Size())
+          ThrowIncorrect();
+        FolderStartFileIndex.Add(i); // check it
+        if (NumUnPackStreamsVector[folderIndex] != 0)
+          break;
+        folderIndex++;
+      }
+    }
+    FileIndexToFolderIndexMap.Add(folderIndex);
+    if (emptyStream)
+      continue;
+    indexInFolder++;
+    if (indexInFolder >= NumUnPackStreamsVector[folderIndex])
+    {
+      folderIndex++;
+      indexInFolder = 0;
+    }
+  }
+}
+
+HRESULT CInArchive::ReadDatabase2(
+    DECL_EXTERNAL_CODECS_LOC_VARS
+    CArchiveDatabaseEx &database
+    #ifndef _NO_CRYPTO
+    , ICryptoGetTextPassword *getTextPassword
+    #endif
+    )
+{
+  database.Clear();
+  database.ArchiveInfo.StartPosition = _arhiveBeginStreamPosition;
+
+  database.ArchiveInfo.Version.Major = _header[6];
+  database.ArchiveInfo.Version.Minor = _header[7];
+
+  if (database.ArchiveInfo.Version.Major != kMajorVersion)
+    ThrowUnsupportedVersion();
+
+  UInt32 crcFromArchive = GetUInt32FromMem(_header + 8);
+  UInt64 nextHeaderOffset = GetUInt64FromMem(_header + 0xC);
+  UInt64 nextHeaderSize = GetUInt64FromMem(_header + 0x14);
+  UInt32 nextHeaderCRC =  GetUInt32FromMem(_header + 0x1C);
+  UInt32 crc = CrcCalc(_header + 0xC, 20);
+
+  #ifdef FORMAT_7Z_RECOVERY
+  if (crcFromArchive == 0 && nextHeaderOffset == 0 && nextHeaderSize == 0 && nextHeaderCRC == 0)
+  {
+    UInt64 cur, cur2;
+    RINOK(_stream->Seek(0, STREAM_SEEK_CUR, &cur));
+    const int kCheckSize = 500;
+    Byte buf[kCheckSize];
+    RINOK(_stream->Seek(0, STREAM_SEEK_END, &cur2));
+    int checkSize = kCheckSize;
+    if (cur2 - cur < kCheckSize)
+      checkSize = (int)(cur2 - cur);
+    RINOK(_stream->Seek(-checkSize, STREAM_SEEK_END, &cur2));
+    
+    UInt32 realProcessedSize;
+    RINOK(_stream->Read(buf, (UInt32)kCheckSize, &realProcessedSize));
+
+    int i;
+    for (i = (int)realProcessedSize - 2; i >= 0; i--)
+      if (buf[i] == 0x17 && buf[i + 1] == 0x6 || buf[i] == 0x01 && buf[i + 1] == 0x04)
+        break;
+    if (i < 0)
+      return S_FALSE;
+    nextHeaderSize = realProcessedSize - i;
+    nextHeaderOffset = cur2 - cur + i;
+    nextHeaderCRC = CrcCalc(buf + i, (size_t)nextHeaderSize);
+    RINOK(_stream->Seek(cur, STREAM_SEEK_SET, NULL));
+  }
+  #endif
+
+  #ifdef FORMAT_7Z_RECOVERY
+  crcFromArchive = crc;
+  #endif
+
+  database.ArchiveInfo.StartPositionAfterHeader = _arhiveBeginStreamPosition + kHeaderSize;
+
+  if (crc != crcFromArchive)
+    ThrowIncorrect();
+
+  if (nextHeaderSize == 0)
+    return S_OK;
+
+  if (nextHeaderSize > (UInt64)0xFFFFFFFF)
+    return S_FALSE;
+
+  RINOK(_stream->Seek(nextHeaderOffset, STREAM_SEEK_CUR, NULL));
+
+  CByteBuffer buffer2;
+  buffer2.SetCapacity((size_t)nextHeaderSize);
+
+  UInt32 realProcessedSize;
+  RINOK(_stream->Read(buffer2, (UInt32)nextHeaderSize, &realProcessedSize));
+  if (realProcessedSize != (UInt32)nextHeaderSize)
+    return S_FALSE;
+  if (CrcCalc(buffer2, (UInt32)nextHeaderSize) != nextHeaderCRC)
+    ThrowIncorrect();
+  
+  CStreamSwitch streamSwitch;
+  streamSwitch.Set(this, buffer2);
+  
+  CObjectVector<CByteBuffer> dataVector;
+  
+  for (;;)
+  {
+    UInt64 type = ReadID();
+    if (type == NID::kHeader)
+      break;
+    if (type != NID::kEncodedHeader)
+      ThrowIncorrect();
+    HRESULT result = ReadAndDecodePackedStreams(
+        EXTERNAL_CODECS_LOC_VARS
+        database.ArchiveInfo.StartPositionAfterHeader, 
+        database.ArchiveInfo.DataStartPosition2,
+        dataVector
+        #ifndef _NO_CRYPTO
+        , getTextPassword
+        #endif
+        );
+    RINOK(result);
+    if (dataVector.Size() == 0)
+      return S_OK;
+    if (dataVector.Size() > 1)
+      ThrowIncorrect();
+    streamSwitch.Remove();
+    streamSwitch.Set(this, dataVector.Front());
+  }
+
+  return ReadHeader(
+    EXTERNAL_CODECS_LOC_VARS
+    database
+    #ifndef _NO_CRYPTO
+    , getTextPassword
+    #endif
+    );
+}
+
+HRESULT CInArchive::ReadDatabase(
+    DECL_EXTERNAL_CODECS_LOC_VARS
+    CArchiveDatabaseEx &database
+    #ifndef _NO_CRYPTO
+    , ICryptoGetTextPassword *getTextPassword
+    #endif
+    )
+{
+  try
+  {
+    return ReadDatabase2(
+      EXTERNAL_CODECS_LOC_VARS database
+      #ifndef _NO_CRYPTO
+      , getTextPassword
+      #endif
+      );
+  }
+  catch(CInArchiveException &) { return S_FALSE; }
+}
+
+}}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/misc/libphysfs/lzma/CPP/7zip/Archive/7z/7zIn.h	Mon Apr 10 12:06:43 2017 -0400
@@ -0,0 +1,235 @@
+// 7zIn.h
+
+#ifndef __7Z_IN_H
+#define __7Z_IN_H
+
+#include "../../../Common/MyCom.h"
+#include "../../IStream.h"
+#include "../../IPassword.h"
+#include "../../Common/CreateCoder.h"
+#include "../../Common/InBuffer.h"
+
+#include "7zItem.h"
+ 
+namespace NArchive {
+namespace N7z {
+  
+struct CInArchiveInfo
+{
+  CArchiveVersion Version;
+  UInt64 StartPosition;
+  UInt64 StartPositionAfterHeader;
+  UInt64 DataStartPosition;
+  UInt64 DataStartPosition2;
+  CRecordVector<UInt64> FileInfoPopIDs;
+  void Clear()
+  {
+    FileInfoPopIDs.Clear();
+  }
+};
+
+struct CArchiveDatabaseEx: public CArchiveDatabase
+{
+  CInArchiveInfo ArchiveInfo;
+  CRecordVector<UInt64> PackStreamStartPositions;
+  CRecordVector<CNum> FolderStartPackStreamIndex;
+  CRecordVector<CNum> FolderStartFileIndex;
+  CRecordVector<CNum> FileIndexToFolderIndexMap;
+
+  void Clear()
+  {
+    CArchiveDatabase::Clear();
+    ArchiveInfo.Clear();
+    PackStreamStartPositions.Clear();
+    FolderStartPackStreamIndex.Clear();
+    FolderStartFileIndex.Clear();
+    FileIndexToFolderIndexMap.Clear();
+  }
+
+  void FillFolderStartPackStream();
+  void FillStartPos();
+  void FillFolderStartFileIndex();
+
+  void Fill()
+  {
+    FillFolderStartPackStream();
+    FillStartPos();
+    FillFolderStartFileIndex();
+  }
+  
+  UInt64 GetFolderStreamPos(int folderIndex, int indexInFolder) const
+  {
+    return ArchiveInfo.DataStartPosition +
+        PackStreamStartPositions[FolderStartPackStreamIndex[folderIndex] + indexInFolder];
+  }
+  
+  UInt64 GetFolderFullPackSize(int folderIndex) const 
+  {
+    CNum packStreamIndex = FolderStartPackStreamIndex[folderIndex];
+    const CFolder &folder = Folders[folderIndex];
+    UInt64 size = 0;
+    for (int i = 0; i < folder.PackStreams.Size(); i++)
+      size += PackSizes[packStreamIndex + i];
+    return size;
+  }
+  
+  UInt64 GetFolderPackStreamSize(int folderIndex, int streamIndex) const 
+  {
+    return PackSizes[FolderStartPackStreamIndex[folderIndex] + streamIndex];
+  }
+
+  UInt64 GetFilePackSize(CNum fileIndex) const
+  {
+    CNum folderIndex = FileIndexToFolderIndexMap[fileIndex];
+    if (folderIndex != kNumNoIndex)
+      if (FolderStartFileIndex[folderIndex] == fileIndex)
+        return GetFolderFullPackSize(folderIndex);
+    return 0;
+  }
+};
+
+class CInByte2
+{
+  const Byte *_buffer;
+  size_t _size;
+  size_t _pos;
+public:
+  void Init(const Byte *buffer, size_t size)
+  {
+    _buffer = buffer;
+    _size = size;
+    _pos = 0;
+  }
+  Byte ReadByte();
+  void ReadBytes(Byte *data, size_t size);
+  void SkeepData(UInt64 size);
+  void SkeepData();
+  UInt64 ReadNumber();
+  CNum ReadNum();
+  UInt32 ReadUInt32();
+  UInt64 ReadUInt64();
+  void ReadString(UString &s);
+};
+
+class CStreamSwitch;
+
+const UInt32 kHeaderSize = 32;
+
+class CInArchive
+{
+  friend class CStreamSwitch;
+
+  CMyComPtr<IInStream> _stream;
+
+  CObjectVector<CInByte2> _inByteVector;
+  CInByte2 *_inByteBack;
+ 
+  UInt64 _arhiveBeginStreamPosition;
+
+  Byte _header[kHeaderSize];
+
+  void AddByteStream(const Byte *buffer, size_t size)
+  {
+    _inByteVector.Add(CInByte2());
+    _inByteBack = &_inByteVector.Back();
+    _inByteBack->Init(buffer, size);
+  }
+  
+  void DeleteByteStream()
+  {
+    _inByteVector.DeleteBack();
+    if (!_inByteVector.IsEmpty())
+      _inByteBack = &_inByteVector.Back();
+  }
+
+private:
+  HRESULT FindAndReadSignature(IInStream *stream, const UInt64 *searchHeaderSizeLimit);
+  
+  void ReadBytes(Byte *data, size_t size) { _inByteBack->ReadBytes(data, size); }
+  Byte ReadByte() { return _inByteBack->ReadByte(); }
+  UInt64 ReadNumber() { return _inByteBack->ReadNumber(); }
+  CNum ReadNum() { return _inByteBack->ReadNum(); }
+  UInt64 ReadID() { return _inByteBack->ReadNumber(); }
+  UInt32 ReadUInt32() { return _inByteBack->ReadUInt32(); }
+  UInt64 ReadUInt64() { return _inByteBack->ReadUInt64(); }
+  void SkeepData(UInt64 size) { _inByteBack->SkeepData(size); }
+  void SkeepData() { _inByteBack->SkeepData(); }
+  void WaitAttribute(UInt64 attribute);
+
+  void ReadArchiveProperties(CInArchiveInfo &archiveInfo);
+  void GetNextFolderItem(CFolder &itemInfo);
+  void ReadHashDigests(int numItems,
+      CRecordVector<bool> &digestsDefined, CRecordVector<UInt32> &digests);
+  
+  void ReadPackInfo(
+      UInt64 &dataOffset,
+      CRecordVector<UInt64> &packSizes,
+      CRecordVector<bool> &packCRCsDefined,
+      CRecordVector<UInt32> &packCRCs);
+  
+  void ReadUnPackInfo(
+      const CObjectVector<CByteBuffer> *dataVector,
+      CObjectVector<CFolder> &folders);
+  
+  void ReadSubStreamsInfo(
+      const CObjectVector<CFolder> &folders,
+      CRecordVector<CNum> &numUnPackStreamsInFolders,
+      CRecordVector<UInt64> &unPackSizes,
+      CRecordVector<bool> &digestsDefined, 
+      CRecordVector<UInt32> &digests);
+
+  void ReadStreamsInfo(
+      const CObjectVector<CByteBuffer> *dataVector,
+      UInt64 &dataOffset,
+      CRecordVector<UInt64> &packSizes,
+      CRecordVector<bool> &packCRCsDefined,
+      CRecordVector<UInt32> &packCRCs,
+      CObjectVector<CFolder> &folders,
+      CRecordVector<CNum> &numUnPackStreamsInFolders,
+      CRecordVector<UInt64> &unPackSizes,
+      CRecordVector<bool> &digestsDefined, 
+      CRecordVector<UInt32> &digests);
+
+
+  void ReadBoolVector(int numItems, CBoolVector &v);
+  void ReadBoolVector2(int numItems, CBoolVector &v);
+  void ReadTime(const CObjectVector<CByteBuffer> &dataVector,
+      CObjectVector<CFileItem> &files, UInt32 type);
+  HRESULT ReadAndDecodePackedStreams(
+      DECL_EXTERNAL_CODECS_LOC_VARS
+      UInt64 baseOffset, UInt64 &dataOffset,
+      CObjectVector<CByteBuffer> &dataVector
+      #ifndef _NO_CRYPTO
+      , ICryptoGetTextPassword *getTextPassword
+      #endif
+      );
+  HRESULT ReadHeader(
+      DECL_EXTERNAL_CODECS_LOC_VARS
+      CArchiveDatabaseEx &database
+      #ifndef _NO_CRYPTO
+      ,ICryptoGetTextPassword *getTextPassword
+      #endif
+      );
+  HRESULT ReadDatabase2(
+      DECL_EXTERNAL_CODECS_LOC_VARS
+      CArchiveDatabaseEx &database 
+      #ifndef _NO_CRYPTO
+      ,ICryptoGetTextPassword *getTextPassword
+      #endif
+      );
+public:
+  HRESULT Open(IInStream *stream, const UInt64 *searchHeaderSizeLimit); // S_FALSE means is not archive
+  void Close();
+
+  HRESULT ReadDatabase(
+      DECL_EXTERNAL_CODECS_LOC_VARS
+      CArchiveDatabaseEx &database 
+      #ifndef _NO_CRYPTO
+      ,ICryptoGetTextPassword *getTextPassword
+      #endif
+      );
+};
+  
+}}
+  
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/misc/libphysfs/lzma/CPP/7zip/Archive/7z/7zItem.h	Mon Apr 10 12:06:43 2017 -0400
@@ -0,0 +1,184 @@
+// 7zItem.h
+
+#ifndef __7Z_ITEM_H
+#define __7Z_ITEM_H
+
+#include "../../../Common/Buffer.h"
+#include "../../../Common/MyString.h"
+#include "../../Common/MethodId.h"
+#include "7zHeader.h"
+
+namespace NArchive {
+namespace N7z {
+
+typedef UInt32 CNum;
+const CNum kNumMax     = 0x7FFFFFFF;
+const CNum kNumNoIndex = 0xFFFFFFFF;
+
+struct CCoderInfo
+{
+  CMethodId MethodID;
+  CByteBuffer Properties;
+  CNum NumInStreams;
+  CNum NumOutStreams;
+  bool IsSimpleCoder() const { return (NumInStreams == 1) && (NumOutStreams == 1); }
+};
+
+struct CBindPair
+{
+  CNum InIndex;
+  CNum OutIndex;
+};
+
+struct CFolder
+{
+  CObjectVector<CCoderInfo> Coders;
+  CRecordVector<CBindPair> BindPairs;
+  CRecordVector<CNum> PackStreams;
+  CRecordVector<UInt64> UnPackSizes;
+  UInt32 UnPackCRC;
+  bool UnPackCRCDefined;
+
+  CFolder(): UnPackCRCDefined(false) {}
+
+  UInt64 GetUnPackSize() const // test it
+  { 
+    if (UnPackSizes.IsEmpty())
+      return 0;
+    for (int i = UnPackSizes.Size() - 1; i >= 0; i--)
+      if (FindBindPairForOutStream(i) < 0)
+        return UnPackSizes[i];
+    throw 1;
+  }
+
+  CNum GetNumOutStreams() const
+  {
+    CNum result = 0;
+    for (int i = 0; i < Coders.Size(); i++)
+      result += Coders[i].NumOutStreams;
+    return result;
+  }
+
+  int FindBindPairForInStream(CNum inStreamIndex) const
+  {
+    for(int i = 0; i < BindPairs.Size(); i++)
+      if (BindPairs[i].InIndex == inStreamIndex)
+        return i;
+    return -1;
+  }
+  int FindBindPairForOutStream(CNum outStreamIndex) const
+  {
+    for(int i = 0; i < BindPairs.Size(); i++)
+      if (BindPairs[i].OutIndex == outStreamIndex)
+        return i;
+    return -1;
+  }
+  int FindPackStreamArrayIndex(CNum inStreamIndex) const
+  {
+    for(int i = 0; i < PackStreams.Size(); i++)
+      if (PackStreams[i] == inStreamIndex)
+        return i;
+    return -1;
+  }
+};
+
+typedef FILETIME CArchiveFileTime;
+
+class CFileItem
+{
+public:
+  CArchiveFileTime CreationTime;
+  CArchiveFileTime LastWriteTime;
+  CArchiveFileTime LastAccessTime;
+  UInt64 UnPackSize;
+  UInt64 StartPos;
+  UInt32 Attributes;
+  UInt32 FileCRC;
+  UString Name;
+
+  bool HasStream; // Test it !!! it means that there is 
+                  // stream in some folder. It can be empty stream
+  bool IsDirectory;
+  bool IsAnti;
+  bool IsFileCRCDefined;
+  bool AreAttributesDefined;
+  bool IsCreationTimeDefined;
+  bool IsLastWriteTimeDefined;
+  bool IsLastAccessTimeDefined;
+  bool IsStartPosDefined;
+
+  /*
+  const bool HasStream() const { 
+      return !IsDirectory && !IsAnti && UnPackSize != 0; }
+  */
+  CFileItem(): 
+    HasStream(true),
+    IsDirectory(false),
+    IsAnti(false),
+    IsFileCRCDefined(false),
+    AreAttributesDefined(false), 
+    IsCreationTimeDefined(false), 
+    IsLastWriteTimeDefined(false), 
+    IsLastAccessTimeDefined(false),
+    IsStartPosDefined(false)
+      {}
+  void SetAttributes(UInt32 attributes) 
+  { 
+    AreAttributesDefined = true;
+    Attributes = attributes;
+  }
+  void SetCreationTime(const CArchiveFileTime &creationTime) 
+  { 
+    IsCreationTimeDefined = true;
+    CreationTime = creationTime;
+  }
+  void SetLastWriteTime(const CArchiveFileTime &lastWriteTime) 
+  {
+    IsLastWriteTimeDefined = true;
+    LastWriteTime = lastWriteTime;
+  }
+  void SetLastAccessTime(const CArchiveFileTime &lastAccessTime) 
+  { 
+    IsLastAccessTimeDefined = true;
+    LastAccessTime = lastAccessTime;
+  }
+};
+
+struct CArchiveDatabase
+{
+  CRecordVector<UInt64> PackSizes;
+  CRecordVector<bool> PackCRCsDefined;
+  CRecordVector<UInt32> PackCRCs;
+  CObjectVector<CFolder> Folders;
+  CRecordVector<CNum> NumUnPackStreamsVector;
+  CObjectVector<CFileItem> Files;
+  void Clear()
+  {
+    PackSizes.Clear();
+    PackCRCsDefined.Clear();
+    PackCRCs.Clear();
+    Folders.Clear();
+    NumUnPackStreamsVector.Clear();
+    Files.Clear();
+  }
+  bool IsEmpty() const
+  {
+    return (PackSizes.IsEmpty() && 
+      PackCRCsDefined.IsEmpty() && 
+      PackCRCs.IsEmpty() && 
+      Folders.IsEmpty() && 
+      NumUnPackStreamsVector.IsEmpty() && 
+      Files.IsEmpty());
+  }
+  bool IsSolid() const
+  {
+    for (int i = 0; i < NumUnPackStreamsVector.Size(); i++)
+      if (NumUnPackStreamsVector[i] > 1)
+        return true;
+    return false;
+  }
+};
+
+}}
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/misc/libphysfs/lzma/CPP/7zip/Archive/7z/7zOut.cpp	Mon Apr 10 12:06:43 2017 -0400
@@ -0,0 +1,1026 @@
+// 7zOut.cpp
+
+#include "StdAfx.h"
+
+#include "../../../Common/AutoPtr.h"
+#include "../../Common/StreamObjects.h"
+
+#include "7zOut.h"
+
+extern "C" 
+{ 
+#include "../../../../C/7zCrc.h"
+}
+
+static HRESULT WriteBytes(ISequentialOutStream *stream, const void *data, size_t size)
+{
+  while (size > 0)
+  {
+    UInt32 curSize = (UInt32)MyMin(size, (size_t)0xFFFFFFFF);
+    UInt32 processedSize;
+    RINOK(stream->Write(data, curSize, &processedSize));
+    if(processedSize == 0)
+      return E_FAIL;
+    data = (const void *)((const Byte *)data + processedSize);
+    size -= processedSize;
+  }
+  return S_OK;
+}
+
+namespace NArchive {
+namespace N7z {
+
+HRESULT COutArchive::WriteDirect(const void *data, UInt32 size)
+{
+  return ::WriteBytes(SeqStream, data, size);
+}
+
+UInt32 CrcUpdateUInt32(UInt32 crc, UInt32 value)
+{
+  for (int i = 0; i < 4; i++, value >>= 8)
+    crc = CRC_UPDATE_BYTE(crc, (Byte)value);
+  return crc;
+}
+
+UInt32 CrcUpdateUInt64(UInt32 crc, UInt64 value)
+{
+  for (int i = 0; i < 8; i++, value >>= 8)
+    crc = CRC_UPDATE_BYTE(crc, (Byte)value);
+  return crc;
+}
+
+HRESULT COutArchive::WriteDirectUInt32(UInt32 value)
+{
+  for (int i = 0; i < 4; i++)
+  {
+    RINOK(WriteDirectByte((Byte)value));
+    value >>= 8;
+  }
+  return S_OK;
+}
+
+HRESULT COutArchive::WriteDirectUInt64(UInt64 value)
+{
+  for (int i = 0; i < 8; i++)
+  {
+    RINOK(WriteDirectByte((Byte)value));
+    value >>= 8;
+  }
+  return S_OK;
+}
+
+HRESULT COutArchive::WriteSignature()
+{
+  RINOK(WriteDirect(kSignature, kSignatureSize));
+  RINOK(WriteDirectByte(kMajorVersion));
+  return WriteDirectByte(2);
+}
+
+#ifdef _7Z_VOL
+HRESULT COutArchive::WriteFinishSignature()
+{
+  RINOK(WriteDirect(kFinishSignature, kSignatureSize));
+  CArchiveVersion av;
+  av.Major = kMajorVersion;
+  av.Minor = 2;
+  RINOK(WriteDirectByte(av.Major));
+  return WriteDirectByte(av.Minor);
+}
+#endif
+
+HRESULT COutArchive::WriteStartHeader(const CStartHeader &h)
+{
+  UInt32 crc = CRC_INIT_VAL;
+  crc = CrcUpdateUInt64(crc, h.NextHeaderOffset);
+  crc = CrcUpdateUInt64(crc, h.NextHeaderSize);
+  crc = CrcUpdateUInt32(crc, h.NextHeaderCRC);
+  RINOK(WriteDirectUInt32(CRC_GET_DIGEST(crc)));
+  RINOK(WriteDirectUInt64(h.NextHeaderOffset));
+  RINOK(WriteDirectUInt64(h.NextHeaderSize));
+  return WriteDirectUInt32(h.NextHeaderCRC);
+}
+
+#ifdef _7Z_VOL
+HRESULT COutArchive::WriteFinishHeader(const CFinishHeader &h)
+{
+  CCRC crc;
+  crc.UpdateUInt64(h.NextHeaderOffset);
+  crc.UpdateUInt64(h.NextHeaderSize);
+  crc.UpdateUInt32(h.NextHeaderCRC);
+  crc.UpdateUInt64(h.ArchiveStartOffset);
+  crc.UpdateUInt64(h.AdditionalStartBlockSize);
+  RINOK(WriteDirectUInt32(crc.GetDigest()));
+  RINOK(WriteDirectUInt64(h.NextHeaderOffset));
+  RINOK(WriteDirectUInt64(h.NextHeaderSize));
+  RINOK(WriteDirectUInt32(h.NextHeaderCRC));
+  RINOK(WriteDirectUInt64(h.ArchiveStartOffset));
+  return WriteDirectUInt64(h.AdditionalStartBlockSize);
+}
+#endif
+
+HRESULT COutArchive::Create(ISequentialOutStream *stream, bool endMarker)
+{
+  Close();
+  #ifdef _7Z_VOL
+  // endMarker = false;
+  _endMarker = endMarker;
+  #endif
+  SeqStream = stream;
+  if (!endMarker)
+  {
+    SeqStream.QueryInterface(IID_IOutStream, &Stream);
+    if (!Stream)
+    {
+      return E_NOTIMPL;
+      // endMarker = true;
+    }
+  }
+  #ifdef _7Z_VOL
+  if (endMarker)
+  {
+    /*
+    CStartHeader sh;
+    sh.NextHeaderOffset = (UInt32)(Int32)-1;
+    sh.NextHeaderSize = (UInt32)(Int32)-1;
+    sh.NextHeaderCRC = 0;
+    WriteStartHeader(sh);
+    */
+  }
+  else
+  #endif
+  {
+    if (!Stream)
+      return E_FAIL;
+    RINOK(WriteSignature());
+    RINOK(Stream->Seek(0, STREAM_SEEK_CUR, &_prefixHeaderPos));
+  }
+  return S_OK;
+}
+
+void COutArchive::Close()
+{
+  SeqStream.Release();
+  Stream.Release();
+}
+
+HRESULT COutArchive::SkeepPrefixArchiveHeader()
+{
+  #ifdef _7Z_VOL
+  if (_endMarker)
+    return S_OK;
+  #endif
+  return Stream->Seek(24, STREAM_SEEK_CUR, NULL);
+}
+
+HRESULT COutArchive::WriteBytes(const void *data, size_t size)
+{
+  if (_mainMode)
+  {
+    if (_dynamicMode)
+      _dynamicBuffer.Write(data, size);
+    else
+      _outByte.WriteBytes(data, size);
+    _crc = CrcUpdate(_crc, data, size);
+  }
+  else
+  {
+    if (_countMode)
+      _countSize += size;
+    else
+      RINOK(_outByte2.Write(data, size));
+  }
+  return S_OK;
+}
+
+HRESULT COutArchive::WriteBytes(const CByteBuffer &data)
+{
+  return WriteBytes(data, data.GetCapacity());
+}
+
+HRESULT COutArchive::WriteByte(Byte b)
+{
+  return WriteBytes(&b, 1);
+}
+
+HRESULT COutArchive::WriteUInt32(UInt32 value)
+{
+  for (int i = 0; i < 4; i++)
+  {
+    RINOK(WriteByte((Byte)value));
+    value >>= 8;
+  }
+  return S_OK;
+}
+
+HRESULT COutArchive::WriteNumber(UInt64 value)
+{
+  Byte firstByte = 0;
+  Byte mask = 0x80;
+  int i;
+  for (i = 0; i < 8; i++)
+  {
+    if (value < ((UInt64(1) << ( 7  * (i + 1)))))
+    {
+      firstByte |= Byte(value >> (8 * i));
+      break;
+    }
+    firstByte |= mask;
+    mask >>= 1;
+  }
+  RINOK(WriteByte(firstByte));
+  for (;i > 0; i--)
+  {
+    RINOK(WriteByte((Byte)value));
+    value >>= 8;
+  }
+  return S_OK;
+}
+
+#ifdef _7Z_VOL
+static UInt32 GetBigNumberSize(UInt64 value)
+{
+  int i;
+  for (i = 0; i < 8; i++)
+    if (value < ((UInt64(1) << ( 7  * (i + 1)))))
+      break;
+  return 1 + i;
+}
+
+UInt32 COutArchive::GetVolHeadersSize(UInt64 dataSize, int nameLength, bool props)
+{
+  UInt32 result = GetBigNumberSize(dataSize) * 2 + 41;
+  if (nameLength != 0)
+  {
+    nameLength = (nameLength + 1) * 2;
+    result += nameLength + GetBigNumberSize(nameLength) + 2;
+  }
+  if (props)
+  {
+    result += 20;
+  }
+  if (result >= 128)
+    result++;
+  result += kSignatureSize + 2 + kFinishHeaderSize;
+  return result;
+}
+
+UInt64 COutArchive::GetVolPureSize(UInt64 volSize, int nameLength, bool props)
+{
+  UInt32 headersSizeBase = COutArchive::GetVolHeadersSize(1, nameLength, props);
+  int testSize;
+  if (volSize > headersSizeBase)
+    testSize = volSize - headersSizeBase;
+  else
+    testSize = 1;
+  UInt32 headersSize = COutArchive::GetVolHeadersSize(testSize, nameLength, props);
+  UInt64 pureSize = 1;
+  if (volSize > headersSize)
+    pureSize = volSize - headersSize;
+  return pureSize;
+}
+#endif
+
+HRESULT COutArchive::WriteFolder(const CFolder &folder)
+{
+  RINOK(WriteNumber(folder.Coders.Size()));
+  int i;
+  for (i = 0; i < folder.Coders.Size(); i++)
+  {
+    const CCoderInfo &coder = folder.Coders[i];
+    {
+      size_t propertiesSize = coder.Properties.GetCapacity();
+      
+      UInt64 id = coder.MethodID; 
+      int idSize;
+      for (idSize = 1; idSize < sizeof(id); idSize++)
+        if ((id >> (8 * idSize)) == 0)
+          break;
+      BYTE longID[15];
+      for (int t = idSize - 1; t >= 0 ; t--, id >>= 8)
+        longID[t] = (Byte)(id & 0xFF);
+      Byte b;
+      b = (Byte)(idSize & 0xF);
+      bool isComplex = !coder.IsSimpleCoder();
+      b |= (isComplex ? 0x10 : 0);
+      b |= ((propertiesSize != 0) ? 0x20 : 0 );
+      RINOK(WriteByte(b));
+      RINOK(WriteBytes(longID, idSize));
+      if (isComplex)
+      {
+        RINOK(WriteNumber(coder.NumInStreams));
+        RINOK(WriteNumber(coder.NumOutStreams));
+      }
+      if (propertiesSize == 0)
+        continue;
+      RINOK(WriteNumber(propertiesSize));
+      RINOK(WriteBytes(coder.Properties, propertiesSize));
+    }
+  }
+  for (i = 0; i < folder.BindPairs.Size(); i++)
+  {
+    const CBindPair &bindPair = folder.BindPairs[i];
+    RINOK(WriteNumber(bindPair.InIndex));
+    RINOK(WriteNumber(bindPair.OutIndex));
+  }
+  if (folder.PackStreams.Size() > 1)
+    for (i = 0; i < folder.PackStreams.Size(); i++)
+    {
+      RINOK(WriteNumber(folder.PackStreams[i]));
+    }
+  return S_OK;
+}
+
+HRESULT COutArchive::WriteBoolVector(const CBoolVector &boolVector)
+{
+  Byte b = 0;
+  Byte mask = 0x80;
+  for(int i = 0; i < boolVector.Size(); i++)
+  {
+    if (boolVector[i])
+      b |= mask;
+    mask >>= 1;
+    if (mask == 0)
+    {
+      RINOK(WriteByte(b));
+      mask = 0x80;
+      b = 0;
+    }
+  }
+  if (mask != 0x80)
+  {
+    RINOK(WriteByte(b));
+  }
+  return S_OK;
+}
+
+
+HRESULT COutArchive::WriteHashDigests(
+    const CRecordVector<bool> &digestsDefined,
+    const CRecordVector<UInt32> &digests)
+{
+  int numDefined = 0;
+  int i;
+  for(i = 0; i < digestsDefined.Size(); i++)
+    if (digestsDefined[i])
+      numDefined++;
+  if (numDefined == 0)
+    return S_OK;
+
+  RINOK(WriteByte(NID::kCRC));
+  if (numDefined == digestsDefined.Size())
+  {
+    RINOK(WriteByte(1));
+  }
+  else
+  {
+    RINOK(WriteByte(0));
+    RINOK(WriteBoolVector(digestsDefined));
+  }
+  for(i = 0; i < digests.Size(); i++)
+  {
+    if(digestsDefined[i])
+      RINOK(WriteUInt32(digests[i]));
+  }
+  return S_OK;
+}
+
+HRESULT COutArchive::WritePackInfo(
+    UInt64 dataOffset,
+    const CRecordVector<UInt64> &packSizes,
+    const CRecordVector<bool> &packCRCsDefined,
+    const CRecordVector<UInt32> &packCRCs)
+{
+  if (packSizes.IsEmpty())
+    return S_OK;
+  RINOK(WriteByte(NID::kPackInfo));
+  RINOK(WriteNumber(dataOffset));
+  RINOK(WriteNumber(packSizes.Size()));
+  RINOK(WriteByte(NID::kSize));
+  for(int i = 0; i < packSizes.Size(); i++)
+    RINOK(WriteNumber(packSizes[i]));
+
+  RINOK(WriteHashDigests(packCRCsDefined, packCRCs));
+  
+  return WriteByte(NID::kEnd);
+}
+
+HRESULT COutArchive::WriteUnPackInfo(const CObjectVector<CFolder> &folders)
+{
+  if (folders.IsEmpty())
+    return S_OK;
+
+  RINOK(WriteByte(NID::kUnPackInfo));
+
+  RINOK(WriteByte(NID::kFolder));
+  RINOK(WriteNumber(folders.Size()));
+  {
+    RINOK(WriteByte(0));
+    for(int i = 0; i < folders.Size(); i++)
+      RINOK(WriteFolder(folders[i]));
+  }
+  
+  RINOK(WriteByte(NID::kCodersUnPackSize));
+  int i;
+  for(i = 0; i < folders.Size(); i++)
+  {
+    const CFolder &folder = folders[i];
+    for (int j = 0; j < folder.UnPackSizes.Size(); j++)
+      RINOK(WriteNumber(folder.UnPackSizes[j]));
+  }
+
+  CRecordVector<bool> unPackCRCsDefined;
+  CRecordVector<UInt32> unPackCRCs;
+  for(i = 0; i < folders.Size(); i++)
+  {
+    const CFolder &folder = folders[i];
+    unPackCRCsDefined.Add(folder.UnPackCRCDefined);
+    unPackCRCs.Add(folder.UnPackCRC);
+  }
+  RINOK(WriteHashDigests(unPackCRCsDefined, unPackCRCs));
+
+  return WriteByte(NID::kEnd);
+}
+
+HRESULT COutArchive::WriteSubStreamsInfo(
+    const CObjectVector<CFolder> &folders,
+    const CRecordVector<CNum> &numUnPackStreamsInFolders,
+    const CRecordVector<UInt64> &unPackSizes,
+    const CRecordVector<bool> &digestsDefined,
+    const CRecordVector<UInt32> &digests)
+{
+  RINOK(WriteByte(NID::kSubStreamsInfo));
+
+  int i;
+  for(i = 0; i < numUnPackStreamsInFolders.Size(); i++)
+  {
+    if (numUnPackStreamsInFolders[i] != 1)
+    {
+      RINOK(WriteByte(NID::kNumUnPackStream));
+      for(i = 0; i < numUnPackStreamsInFolders.Size(); i++)
+        RINOK(WriteNumber(numUnPackStreamsInFolders[i]));
+      break;
+    }
+  }
+ 
+
+  bool needFlag = true;
+  CNum index = 0;
+  for(i = 0; i < numUnPackStreamsInFolders.Size(); i++)
+    for (CNum j = 0; j < numUnPackStreamsInFolders[i]; j++)
+    {
+      if (j + 1 != numUnPackStreamsInFolders[i])
+      {
+        if (needFlag)
+          RINOK(WriteByte(NID::kSize));
+        needFlag = false;
+        RINOK(WriteNumber(unPackSizes[index]));
+      }
+      index++;
+    }
+
+  CRecordVector<bool> digestsDefined2;
+  CRecordVector<UInt32> digests2;
+
+  int digestIndex = 0;
+  for (i = 0; i < folders.Size(); i++)
+  {
+    int numSubStreams = (int)numUnPackStreamsInFolders[i];
+    if (numSubStreams == 1 && folders[i].UnPackCRCDefined)
+      digestIndex++;
+    else
+      for (int j = 0; j < numSubStreams; j++, digestIndex++)
+      {
+        digestsDefined2.Add(digestsDefined[digestIndex]);
+        digests2.Add(digests[digestIndex]);
+      }
+  }
+  RINOK(WriteHashDigests(digestsDefined2, digests2));
+  return WriteByte(NID::kEnd);
+}
+
+HRESULT COutArchive::WriteTime(
+    const CObjectVector<CFileItem> &files, Byte type)
+{
+  /////////////////////////////////////////////////
+  // CreationTime
+  CBoolVector boolVector;
+  boolVector.Reserve(files.Size());
+  bool thereAreDefined = false;
+  bool allDefined = true;
+  int i;
+  for(i = 0; i < files.Size(); i++)
+  {
+    const CFileItem &item = files[i];
+    bool defined;
+    switch(type)
+    {
+      case NID::kCreationTime:
+        defined = item.IsCreationTimeDefined;
+        break;
+      case NID::kLastWriteTime:
+        defined = item.IsLastWriteTimeDefined;
+        break;
+      case NID::kLastAccessTime:
+        defined = item.IsLastAccessTimeDefined;
+        break;
+      default:
+        throw 1;
+    }
+    boolVector.Add(defined);
+    thereAreDefined = (thereAreDefined || defined);
+    allDefined = (allDefined && defined);
+  }
+  if (!thereAreDefined)
+    return S_OK;
+  RINOK(WriteByte(type));
+  size_t dataSize = 1 + 1;
+    dataSize += files.Size() * 8;
+  if (allDefined)
+  {
+    RINOK(WriteNumber(dataSize));
+    WriteByte(1);
+  }
+  else
+  {
+    RINOK(WriteNumber(1 + (boolVector.Size() + 7) / 8 + dataSize));
+    WriteByte(0);
+    RINOK(WriteBoolVector(boolVector));
+  }
+  RINOK(WriteByte(0));
+  for(i = 0; i < files.Size(); i++)
+  {
+    if (boolVector[i])
+    {
+      const CFileItem &item = files[i];
+      CArchiveFileTime timeValue;
+      timeValue.dwLowDateTime = 0;
+      timeValue.dwHighDateTime = 0;
+      switch(type)
+      {
+        case NID::kCreationTime:
+          timeValue = item.CreationTime;
+          break;
+        case NID::kLastWriteTime:
+          timeValue = item.LastWriteTime;
+          break;
+        case NID::kLastAccessTime:
+          timeValue = item.LastAccessTime;
+          break;
+      }
+      RINOK(WriteUInt32(timeValue.dwLowDateTime));
+      RINOK(WriteUInt32(timeValue.dwHighDateTime));
+    }
+  }
+  return S_OK;
+}
+
+HRESULT COutArchive::EncodeStream(
+    DECL_EXTERNAL_CODECS_LOC_VARS
+    CEncoder &encoder, const Byte *data, size_t dataSize,
+    CRecordVector<UInt64> &packSizes, CObjectVector<CFolder> &folders)
+{
+  CSequentialInStreamImp *streamSpec = new CSequentialInStreamImp;
+  CMyComPtr<ISequentialInStream> stream = streamSpec;
+  streamSpec->Init(data, dataSize);
+  CFolder folderItem;
+  folderItem.UnPackCRCDefined = true;
+  folderItem.UnPackCRC = CrcCalc(data, dataSize);
+  UInt64 dataSize64 = dataSize;
+  RINOK(encoder.Encode(
+      EXTERNAL_CODECS_LOC_VARS
+      stream, NULL, &dataSize64, folderItem, SeqStream, packSizes, NULL))
+  folders.Add(folderItem);
+  return S_OK;
+}
+
+HRESULT COutArchive::EncodeStream(
+    DECL_EXTERNAL_CODECS_LOC_VARS
+    CEncoder &encoder, const CByteBuffer &data, 
+    CRecordVector<UInt64> &packSizes, CObjectVector<CFolder> &folders)
+{
+  return EncodeStream(
+      EXTERNAL_CODECS_LOC_VARS
+      encoder, data, data.GetCapacity(), packSizes, folders);
+}
+
+static void WriteUInt32ToBuffer(Byte *data, UInt32 value)
+{
+  for (int i = 0; i < 4; i++)
+  {
+    *data++ = (Byte)value;
+    value >>= 8;
+  }
+}
+
+static void WriteUInt64ToBuffer(Byte *data, UInt64 value)
+{
+  for (int i = 0; i < 8; i++)
+  {
+    *data++ = (Byte)value;
+    value >>= 8;
+  }
+}
+
+
+HRESULT COutArchive::WriteHeader(
+    const CArchiveDatabase &database,
+    const CHeaderOptions &headerOptions,
+    UInt64 &headerOffset)
+{
+  int i;
+  
+  /////////////////////////////////
+  // Names
+
+  CNum numDefinedNames = 0;
+  size_t namesDataSize = 0;
+  for(i = 0; i < database.Files.Size(); i++)
+  {
+    const UString &name = database.Files[i].Name;
+    if (!name.IsEmpty())
+      numDefinedNames++;
+    namesDataSize += (name.Length() + 1) * 2;
+  }
+
+  CByteBuffer namesData;
+  if (numDefinedNames > 0)
+  {
+    namesData.SetCapacity((size_t)namesDataSize);
+    size_t pos = 0;
+    for(int i = 0; i < database.Files.Size(); i++)
+    {
+      const UString &name = database.Files[i].Name;
+      for (int t = 0; t < name.Length(); t++)
+      {
+        wchar_t c = name[t];
+        namesData[pos++] = Byte(c);
+        namesData[pos++] = Byte(c >> 8);
+      }
+      namesData[pos++] = 0;
+      namesData[pos++] = 0;
+    }
+  }
+
+  /////////////////////////////////
+  // Write Attributes
+  CBoolVector attributesBoolVector;
+  attributesBoolVector.Reserve(database.Files.Size());
+  int numDefinedAttributes = 0;
+  for(i = 0; i < database.Files.Size(); i++)
+  {
+    bool defined = database.Files[i].AreAttributesDefined;
+    attributesBoolVector.Add(defined);
+    if (defined)
+      numDefinedAttributes++;
+  }
+
+  CByteBuffer attributesData;
+  if (numDefinedAttributes > 0)
+  {
+    attributesData.SetCapacity(numDefinedAttributes * 4);
+    size_t pos = 0;
+    for(i = 0; i < database.Files.Size(); i++)
+    {
+      const CFileItem &file = database.Files[i];
+      if (file.AreAttributesDefined)
+      {
+        WriteUInt32ToBuffer(attributesData + pos, file.Attributes);
+        pos += 4;
+      }
+    }
+  }
+
+  /////////////////////////////////
+  // Write StartPos
+  CBoolVector startsBoolVector;
+  startsBoolVector.Reserve(database.Files.Size());
+  int numDefinedStarts = 0;
+  for(i = 0; i < database.Files.Size(); i++)
+  {
+    bool defined = database.Files[i].IsStartPosDefined;
+    startsBoolVector.Add(defined);
+    if (defined)
+      numDefinedStarts++;
+  }
+
+  CByteBuffer startsData;
+  if (numDefinedStarts > 0)
+  {
+    startsData.SetCapacity(numDefinedStarts * 8);
+    size_t pos = 0;
+    for(i = 0; i < database.Files.Size(); i++)
+    {
+      const CFileItem &file = database.Files[i];
+      if (file.IsStartPosDefined)
+      {
+        WriteUInt64ToBuffer(startsData + pos, file.StartPos);
+        pos += 8;
+      }
+    }
+  }
+  
+  /////////////////////////////////
+  // Write Last Write Time
+  // /*
+  CNum numDefinedLastWriteTimes = 0;
+  for(i = 0; i < database.Files.Size(); i++)
+    if (database.Files[i].IsLastWriteTimeDefined)
+      numDefinedLastWriteTimes++;
+
+  if (numDefinedLastWriteTimes > 0)
+  {
+    CByteBuffer lastWriteTimeData;
+    lastWriteTimeData.SetCapacity(numDefinedLastWriteTimes * 8);
+    size_t pos = 0;
+    for(i = 0; i < database.Files.Size(); i++)
+    {
+      const CFileItem &file = database.Files[i];
+      if (file.IsLastWriteTimeDefined)
+      {
+        WriteUInt32ToBuffer(lastWriteTimeData + pos, file.LastWriteTime.dwLowDateTime);
+        pos += 4;
+        WriteUInt32ToBuffer(lastWriteTimeData + pos, file.LastWriteTime.dwHighDateTime);
+        pos += 4;
+      }
+    }
+  }
+  // */
+  
+
+  UInt64 packedSize = 0;
+  for(i = 0; i < database.PackSizes.Size(); i++)
+    packedSize += database.PackSizes[i];
+
+  headerOffset = packedSize;
+
+  _mainMode = true;
+
+  _outByte.SetStream(SeqStream);
+  _outByte.Init();
+  _crc = CRC_INIT_VAL;
+
+
+  RINOK(WriteByte(NID::kHeader));
+
+  // Archive Properties
+
+  if (database.Folders.Size() > 0)
+  {
+    RINOK(WriteByte(NID::kMainStreamsInfo));
+    RINOK(WritePackInfo(0, database.PackSizes, 
+        database.PackCRCsDefined,
+        database.PackCRCs));
+
+    RINOK(WriteUnPackInfo(database.Folders));
+
+    CRecordVector<UInt64> unPackSizes;
+    CRecordVector<bool> digestsDefined;
+    CRecordVector<UInt32> digests;
+    for (i = 0; i < database.Files.Size(); i++)
+    {
+      const CFileItem &file = database.Files[i];
+      if (!file.HasStream)
+        continue;
+      unPackSizes.Add(file.UnPackSize);
+      digestsDefined.Add(file.IsFileCRCDefined);
+      digests.Add(file.FileCRC);
+    }
+
+    RINOK(WriteSubStreamsInfo(
+        database.Folders,
+        database.NumUnPackStreamsVector,
+        unPackSizes,
+        digestsDefined,
+        digests));
+    RINOK(WriteByte(NID::kEnd));
+  }
+
+  if (database.Files.IsEmpty())
+  {
+    RINOK(WriteByte(NID::kEnd));
+    return _outByte.Flush();
+  }
+
+  RINOK(WriteByte(NID::kFilesInfo));
+  RINOK(WriteNumber(database.Files.Size()));
+
+  CBoolVector emptyStreamVector;
+  emptyStreamVector.Reserve(database.Files.Size());
+  int numEmptyStreams = 0;
+  for(i = 0; i < database.Files.Size(); i++)
+    if (database.Files[i].HasStream)
+      emptyStreamVector.Add(false);
+    else
+    {
+      emptyStreamVector.Add(true);
+      numEmptyStreams++;
+    }
+  if (numEmptyStreams > 0)
+  {
+    RINOK(WriteByte(NID::kEmptyStream));
+    RINOK(WriteNumber((emptyStreamVector.Size() + 7) / 8));
+    RINOK(WriteBoolVector(emptyStreamVector));
+
+    CBoolVector emptyFileVector, antiVector;
+    emptyFileVector.Reserve(numEmptyStreams);
+    antiVector.Reserve(numEmptyStreams);
+    CNum numEmptyFiles = 0, numAntiItems = 0;
+    for(i = 0; i < database.Files.Size(); i++)
+    {
+      const CFileItem &file = database.Files[i];
+      if (!file.HasStream)
+      {
+        emptyFileVector.Add(!file.IsDirectory);
+        if (!file.IsDirectory)
+          numEmptyFiles++;
+        antiVector.Add(file.IsAnti);
+        if (file.IsAnti)
+          numAntiItems++;
+      }
+    }
+
+    if (numEmptyFiles > 0)
+    {
+      RINOK(WriteByte(NID::kEmptyFile));
+      RINOK(WriteNumber((emptyFileVector.Size() + 7) / 8));
+      RINOK(WriteBoolVector(emptyFileVector));
+    }
+
+    if (numAntiItems > 0)
+    {
+      RINOK(WriteByte(NID::kAnti));
+      RINOK(WriteNumber((antiVector.Size() + 7) / 8));
+      RINOK(WriteBoolVector(antiVector));
+    }
+  }
+
+  if (numDefinedNames > 0)
+  {
+    /////////////////////////////////////////////////
+    RINOK(WriteByte(NID::kName));
+    {
+      RINOK(WriteNumber(1 + namesData.GetCapacity()));
+      RINOK(WriteByte(0));
+      RINOK(WriteBytes(namesData));
+    }
+
+  }
+
+  if (headerOptions.WriteCreated)
+  {
+    RINOK(WriteTime(database.Files, NID::kCreationTime));
+  }
+  if (headerOptions.WriteModified)
+  {
+    RINOK(WriteTime(database.Files, NID::kLastWriteTime));
+  }
+  if (headerOptions.WriteAccessed)
+  {
+    RINOK(WriteTime(database.Files, NID::kLastAccessTime));
+  }
+
+  if (numDefinedAttributes > 0)
+  {
+    RINOK(WriteByte(NID::kWinAttributes));
+    size_t size = 2;
+    if (numDefinedAttributes != database.Files.Size())
+      size += (attributesBoolVector.Size() + 7) / 8 + 1;
+      size += attributesData.GetCapacity();
+
+    RINOK(WriteNumber(size));
+    if (numDefinedAttributes == database.Files.Size())
+    {
+      RINOK(WriteByte(1));
+    }
+    else
+    {
+      RINOK(WriteByte(0));
+      RINOK(WriteBoolVector(attributesBoolVector));
+    }
+
+    {
+      RINOK(WriteByte(0));
+      RINOK(WriteBytes(attributesData));
+    }
+  }
+
+  if (numDefinedStarts > 0)
+  {
+    RINOK(WriteByte(NID::kStartPos));
+    size_t size = 2;
+    if (numDefinedStarts != database.Files.Size())
+      size += (startsBoolVector.Size() + 7) / 8 + 1;
+      size += startsData.GetCapacity();
+
+    RINOK(WriteNumber(size));
+    if (numDefinedStarts == database.Files.Size())
+    {
+      RINOK(WriteByte(1));
+    }
+    else
+    {
+      RINOK(WriteByte(0));
+      RINOK(WriteBoolVector(startsBoolVector));
+    }
+
+    {
+      RINOK(WriteByte(0));
+      RINOK(WriteBytes(startsData));
+    }
+  }
+
+  RINOK(WriteByte(NID::kEnd)); // for files
+  RINOK(WriteByte(NID::kEnd)); // for headers
+
+  return _outByte.Flush();
+}
+
+HRESULT COutArchive::WriteDatabase(
+    DECL_EXTERNAL_CODECS_LOC_VARS
+    const CArchiveDatabase &database,
+    const CCompressionMethodMode *options, 
+    const CHeaderOptions &headerOptions)
+{
+  UInt64 headerOffset;
+  UInt32 headerCRC;
+  UInt64 headerSize;
+  if (database.IsEmpty())
+  {
+    headerSize = 0;
+    headerOffset = 0;
+    headerCRC = CrcCalc(0, 0);
+  }
+  else
+  {
+    _dynamicBuffer.Init();
+    _dynamicMode = false;
+
+    if (options != 0)
+      if (options->IsEmpty())
+        options = 0;
+    if (options != 0)
+      if (options->PasswordIsDefined || headerOptions.CompressMainHeader)
+        _dynamicMode = true;
+    RINOK(WriteHeader(database, headerOptions, headerOffset));
+
+    if (_dynamicMode)
+    {
+      CCompressionMethodMode encryptOptions;
+      encryptOptions.PasswordIsDefined = options->PasswordIsDefined;
+      encryptOptions.Password = options->Password;
+      CEncoder encoder(headerOptions.CompressMainHeader ? *options : encryptOptions);
+      CRecordVector<UInt64> packSizes;
+      CObjectVector<CFolder> folders;
+      RINOK(EncodeStream(
+          EXTERNAL_CODECS_LOC_VARS
+          encoder, _dynamicBuffer, 
+          _dynamicBuffer.GetSize(), packSizes, folders));
+      _dynamicMode = false;
+      _mainMode = true;
+      
+      _outByte.SetStream(SeqStream);
+      _outByte.Init();
+      _crc = CRC_INIT_VAL;
+      
+      if (folders.Size() == 0)
+        throw 1;
+
+      RINOK(WriteID(NID::kEncodedHeader));
+      RINOK(WritePackInfo(headerOffset, packSizes, 
+        CRecordVector<bool>(), CRecordVector<UInt32>()));
+      RINOK(WriteUnPackInfo(folders));
+      RINOK(WriteByte(NID::kEnd));
+      for (int i = 0; i < packSizes.Size(); i++)
+        headerOffset += packSizes[i];
+      RINOK(_outByte.Flush());
+    }
+    headerCRC = CRC_GET_DIGEST(_crc);
+    headerSize = _outByte.GetProcessedSize();
+  }
+  #ifdef _7Z_VOL
+  if (_endMarker)
+  {
+    CFinishHeader h;
+    h.NextHeaderSize = headerSize;
+    h.NextHeaderCRC = headerCRC;
+    h.NextHeaderOffset = 
+        UInt64(0) - (headerSize + 
+        4 + kFinishHeaderSize);
+    h.ArchiveStartOffset = h.NextHeaderOffset - headerOffset;
+    h.AdditionalStartBlockSize = 0;
+    RINOK(WriteFinishHeader(h));
+    return WriteFinishSignature();
+  }
+  else
+  #endif
+  {
+    CStartHeader h;
+    h.NextHeaderSize = headerSize;
+    h.NextHeaderCRC = headerCRC;
+    h.NextHeaderOffset = headerOffset;
+    RINOK(Stream->Seek(_prefixHeaderPos, STREAM_SEEK_SET, NULL));
+    return WriteStartHeader(h);
+  }
+}
+
+}}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/misc/libphysfs/lzma/CPP/7zip/Archive/7z/7zOut.h	Mon Apr 10 12:06:43 2017 -0400
@@ -0,0 +1,193 @@
+// 7z/Out.h
+
+#ifndef __7Z_OUT_H
+#define __7Z_OUT_H
+
+#include "7zHeader.h"
+#include "7zItem.h"
+#include "7zCompressionMode.h"
+#include "7zEncode.h"
+
+#include "../../Common/OutBuffer.h"
+#include "../../../Common/DynamicBuffer.h"
+
+namespace NArchive {
+namespace N7z {
+
+class CWriteBufferLoc
+{
+  Byte *_data;
+  size_t _size;
+  size_t _pos;
+public:
+  CWriteBufferLoc(): _size(0), _pos(0) {}
+  void Init(Byte *data, size_t size)  
+  { 
+    _pos = 0;
+    _data = data;
+    _size = size; 
+  }
+  HRESULT Write(const void *data, size_t size)
+  {
+    if (_pos + size > _size)
+      return E_FAIL;
+    memmove(_data + _pos, data, size);
+    _pos += size;
+    return S_OK; 
+  }
+};
+
+class CWriteDynamicBuffer
+{
+  CByteDynamicBuffer _buffer;
+  size_t _pos;
+public:
+  CWriteDynamicBuffer(): _pos(0) {}
+  void Init()  
+  { 
+    _pos = 0;
+  }
+  void Write(const void *data, size_t size)
+  {
+    if (_pos + size > _buffer.GetCapacity())
+      _buffer.EnsureCapacity(_pos + size);
+    memmove(((Byte *)_buffer) +_pos, data, size);
+    _pos += size;
+  }
+  operator Byte *() { return (Byte *)_buffer; };
+  operator const Byte *() const { return (const Byte *)_buffer; };
+  size_t GetSize() const { return _pos; }
+};
+
+struct CHeaderOptions
+{
+  // bool UseAdditionalHeaderStreams;
+  bool CompressMainHeader;
+  bool WriteModified;
+  bool WriteCreated;
+  bool WriteAccessed;
+
+  CHeaderOptions(): 
+      // UseAdditionalHeaderStreams(false), 
+      CompressMainHeader(true),
+      WriteModified(true),
+      WriteCreated(false),
+      WriteAccessed(false) {} 
+};
+
+class COutArchive
+{
+  UInt64 _prefixHeaderPos;
+
+  HRESULT WriteDirect(const void *data, UInt32 size);
+  HRESULT WriteDirectByte(Byte b) { return WriteDirect(&b, 1); }
+  HRESULT WriteDirectUInt32(UInt32 value);
+  HRESULT WriteDirectUInt64(UInt64 value);
+  
+  HRESULT WriteBytes(const void *data, size_t size);
+  HRESULT WriteBytes(const CByteBuffer &data);
+  HRESULT WriteByte(Byte b);
+  HRESULT WriteUInt32(UInt32 value);
+  HRESULT WriteNumber(UInt64 value);
+  HRESULT WriteID(UInt64 value) { return WriteNumber(value); }
+
+  HRESULT WriteFolder(const CFolder &folder);
+  HRESULT WriteFileHeader(const CFileItem &itemInfo);
+  HRESULT WriteBoolVector(const CBoolVector &boolVector);
+  HRESULT WriteHashDigests(
+      const CRecordVector<bool> &digestsDefined,
+      const CRecordVector<UInt32> &hashDigests);
+
+  HRESULT WritePackInfo(
+      UInt64 dataOffset,
+      const CRecordVector<UInt64> &packSizes,
+      const CRecordVector<bool> &packCRCsDefined,
+      const CRecordVector<UInt32> &packCRCs);
+
+  HRESULT WriteUnPackInfo(const CObjectVector<CFolder> &folders);
+
+  HRESULT WriteSubStreamsInfo(
+      const CObjectVector<CFolder> &folders,
+      const CRecordVector<CNum> &numUnPackStreamsInFolders,
+      const CRecordVector<UInt64> &unPackSizes,
+      const CRecordVector<bool> &digestsDefined,
+      const CRecordVector<UInt32> &hashDigests);
+
+  /*
+  HRESULT WriteStreamsInfo(
+      UInt64 dataOffset,
+      const CRecordVector<UInt64> &packSizes,
+      const CRecordVector<bool> &packCRCsDefined,
+      const CRecordVector<UInt32> &packCRCs,
+      bool externalFolders,
+      UInt64 externalFoldersStreamIndex,
+      const CObjectVector<CFolder> &folders,
+      const CRecordVector<CNum> &numUnPackStreamsInFolders,
+      const CRecordVector<UInt64> &unPackSizes,
+      const CRecordVector<bool> &digestsDefined,
+      const CRecordVector<UInt32> &hashDigests);
+  */
+
+
+  HRESULT WriteTime(const CObjectVector<CFileItem> &files, Byte type);
+
+  HRESULT EncodeStream(
+      DECL_EXTERNAL_CODECS_LOC_VARS
+      CEncoder &encoder, const Byte *data, size_t dataSize,
+      CRecordVector<UInt64> &packSizes, CObjectVector<CFolder> &folders);
+  HRESULT EncodeStream(
+      DECL_EXTERNAL_CODECS_LOC_VARS
+      CEncoder &encoder, const CByteBuffer &data, 
+      CRecordVector<UInt64> &packSizes, CObjectVector<CFolder> &folders);
+  HRESULT WriteHeader(
+      const CArchiveDatabase &database,
+      const CHeaderOptions &headerOptions,
+      UInt64 &headerOffset);
+  
+  bool _mainMode;
+
+  bool _dynamicMode;
+
+  bool _countMode;
+  size_t _countSize;
+  COutBuffer _outByte;
+  CWriteBufferLoc _outByte2;
+  CWriteDynamicBuffer _dynamicBuffer;
+  UInt32 _crc;
+
+  #ifdef _7Z_VOL
+  bool _endMarker;
+  #endif
+
+  HRESULT WriteSignature();
+  #ifdef _7Z_VOL
+  HRESULT WriteFinishSignature();
+  #endif
+  HRESULT WriteStartHeader(const CStartHeader &h);
+  #ifdef _7Z_VOL
+  HRESULT WriteFinishHeader(const CFinishHeader &h);
+  #endif
+  CMyComPtr<IOutStream> Stream;
+public:
+
+  COutArchive() { _outByte.Create(1 << 16); }
+  CMyComPtr<ISequentialOutStream> SeqStream;
+  HRESULT Create(ISequentialOutStream *stream, bool endMarker);
+  void Close();
+  HRESULT SkeepPrefixArchiveHeader();
+  HRESULT WriteDatabase(
+      DECL_EXTERNAL_CODECS_LOC_VARS
+      const CArchiveDatabase &database,
+      const CCompressionMethodMode *options, 
+      const CHeaderOptions &headerOptions);
+
+  #ifdef _7Z_VOL
+  static UInt32 GetVolHeadersSize(UInt64 dataSize, int nameLength = 0, bool props = false);
+  static UInt64 GetVolPureSize(UInt64 volSize, int nameLength = 0, bool props = false);
+  #endif
+
+};
+
+}}
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/misc/libphysfs/lzma/CPP/7zip/Archive/7z/7zProperties.cpp	Mon Apr 10 12:06:43 2017 -0400
@@ -0,0 +1,162 @@
+// 7zProperties.cpp
+
+#include "StdAfx.h"
+
+#include "7zProperties.h"
+#include "7zHeader.h"
+#include "7zHandler.h"
+
+// #define _MULTI_PACK
+
+namespace NArchive {
+namespace N7z {
+
+struct CPropMap
+{
+  UInt64 FilePropID;
+  STATPROPSTG StatPROPSTG;
+};
+
+CPropMap kPropMap[] = 
+{
+  { NID::kName, NULL, kpidPath, VT_BSTR},
+  { NID::kSize, NULL, kpidSize, VT_UI8},
+  { NID::kPackInfo, NULL, kpidPackedSize, VT_UI8},
+  
+  #ifdef _MULTI_PACK
+  { 100, L"Pack0", kpidPackedSize0, VT_UI8},
+  { 101, L"Pack1", kpidPackedSize1, VT_UI8},
+  { 102, L"Pack2", kpidPackedSize2, VT_UI8},
+  { 103, L"Pack3", kpidPackedSize3, VT_UI8},
+  { 104, L"Pack4", kpidPackedSize4, VT_UI8},
+  #endif
+
+  { NID::kCreationTime, NULL, kpidCreationTime, VT_FILETIME},
+  { NID::kLastWriteTime, NULL, kpidLastWriteTime, VT_FILETIME},
+  { NID::kLastAccessTime, NULL, kpidLastAccessTime, VT_FILETIME},
+  { NID::kWinAttributes, NULL, kpidAttributes, VT_UI4},
+  { NID::kStartPos, NULL, kpidPosition, VT_UI4},
+
+  { NID::kCRC, NULL, kpidCRC, VT_UI4},
+  
+  { NID::kAnti, NULL, kpidIsAnti, VT_BOOL},
+  // { 97, NULL, kpidSolid, VT_BOOL},
+  #ifndef _SFX
+  { 98, NULL, kpidMethod, VT_BSTR},
+  { 99, NULL, kpidBlock, VT_UI4}
+  #endif
+};
+
+static const int kPropMapSize = sizeof(kPropMap) / sizeof(kPropMap[0]);
+
+static int FindPropInMap(UInt64 filePropID)
+{
+  for (int i = 0; i < kPropMapSize; i++)
+    if (kPropMap[i].FilePropID == filePropID)
+      return i;
+  return -1;
+}
+
+static void CopyOneItem(CRecordVector<UInt64> &src, 
+    CRecordVector<UInt64> &dest, UInt32 item)
+{
+  for (int i = 0; i < src.Size(); i++)
+    if (src[i] == item)
+    {
+      dest.Add(item);
+      src.Delete(i);
+      return;
+    }
+}
+
+static void RemoveOneItem(CRecordVector<UInt64> &src, UInt32 item)
+{
+  for (int i = 0; i < src.Size(); i++)
+    if (src[i] == item)
+    {
+      src.Delete(i);
+      return;
+    }
+}
+
+static void InsertToHead(CRecordVector<UInt64> &dest, UInt32 item)
+{
+  for (int i = 0; i < dest.Size(); i++)
+    if (dest[i] == item)
+    {
+      dest.Delete(i);
+      break;
+    }
+  dest.Insert(0, item);
+}
+
+void CHandler::FillPopIDs()
+{ 
+  _fileInfoPopIDs.Clear();
+
+  #ifdef _7Z_VOL
+  if(_volumes.Size() < 1)
+    return;
+  const CVolume &volume = _volumes.Front();
+  const CArchiveDatabaseEx &_database = volume.Database;
+  #endif
+
+  CRecordVector<UInt64> fileInfoPopIDs = _database.ArchiveInfo.FileInfoPopIDs;
+
+  RemoveOneItem(fileInfoPopIDs, NID::kEmptyStream);
+  RemoveOneItem(fileInfoPopIDs, NID::kEmptyFile);
+
+  CopyOneItem(fileInfoPopIDs, _fileInfoPopIDs, NID::kName);
+  CopyOneItem(fileInfoPopIDs, _fileInfoPopIDs, NID::kAnti);
+  CopyOneItem(fileInfoPopIDs, _fileInfoPopIDs, NID::kSize);
+  CopyOneItem(fileInfoPopIDs, _fileInfoPopIDs, NID::kPackInfo);
+  CopyOneItem(fileInfoPopIDs, _fileInfoPopIDs, NID::kCreationTime);
+  CopyOneItem(fileInfoPopIDs, _fileInfoPopIDs, NID::kLastWriteTime);
+  CopyOneItem(fileInfoPopIDs, _fileInfoPopIDs, NID::kLastAccessTime);
+  CopyOneItem(fileInfoPopIDs, _fileInfoPopIDs, NID::kWinAttributes);
+  CopyOneItem(fileInfoPopIDs, _fileInfoPopIDs, NID::kCRC);
+  CopyOneItem(fileInfoPopIDs, _fileInfoPopIDs, NID::kComment);
+  _fileInfoPopIDs += fileInfoPopIDs; 
+ 
+  #ifndef _SFX
+  _fileInfoPopIDs.Add(98);
+  _fileInfoPopIDs.Add(99);
+  #endif
+  #ifdef _MULTI_PACK
+  _fileInfoPopIDs.Add(100);
+  _fileInfoPopIDs.Add(101);
+  _fileInfoPopIDs.Add(102);
+  _fileInfoPopIDs.Add(103);
+  _fileInfoPopIDs.Add(104);
+  #endif
+
+  #ifndef _SFX
+  InsertToHead(_fileInfoPopIDs, NID::kLastWriteTime);
+  InsertToHead(_fileInfoPopIDs, NID::kPackInfo);
+  InsertToHead(_fileInfoPopIDs, NID::kSize);
+  InsertToHead(_fileInfoPopIDs, NID::kName);
+  #endif
+}
+
+STDMETHODIMP CHandler::GetNumberOfProperties(UInt32 *numProperties)
+{
+  *numProperties = _fileInfoPopIDs.Size();
+  return S_OK;
+}
+
+STDMETHODIMP CHandler::GetPropertyInfo(UInt32 index,     
+      BSTR *name, PROPID *propID, VARTYPE *varType)
+{
+  if((int)index >= _fileInfoPopIDs.Size())
+    return E_INVALIDARG;
+  int indexInMap = FindPropInMap(_fileInfoPopIDs[index]);
+  if (indexInMap == -1)
+    return E_INVALIDARG;
+  const STATPROPSTG &srcItem = kPropMap[indexInMap].StatPROPSTG;
+  *propID = srcItem.propid;
+  *varType = srcItem.vt;
+  *name = 0;
+  return S_OK;
+}
+
+}}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/misc/libphysfs/lzma/CPP/7zip/Archive/7z/7zProperties.h	Mon Apr 10 12:06:43 2017 -0400
@@ -0,0 +1,22 @@
+// 7zProperties.h
+
+#ifndef __7Z_PROPERTIES_H
+#define __7Z_PROPERTIES_H
+
+#include "../../PropID.h"
+
+namespace NArchive {
+namespace N7z {
+
+enum
+{
+  kpidPackedSize0 = kpidUserDefined,
+  kpidPackedSize1, 
+  kpidPackedSize2,
+  kpidPackedSize3,
+  kpidPackedSize4
+};
+
+}}
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/misc/libphysfs/lzma/CPP/7zip/Archive/7z/7zRegister.cpp	Mon Apr 10 12:06:43 2017 -0400
@@ -0,0 +1,18 @@
+// 7zRegister.cpp
+
+#include "StdAfx.h"
+
+#include "../../Common/RegisterArc.h"
+
+#include "7zHandler.h"
+static IInArchive *CreateArc() { return new NArchive::N7z::CHandler;  }
+#ifndef EXTRACT_ONLY
+static IOutArchive *CreateArcOut() { return new NArchive::N7z::CHandler;  }
+#else
+#define CreateArcOut 0
+#endif
+
+static CArcInfo g_ArcInfo =
+  { L"7z", L"7z", 0, 7, {'7' + 1 , 'z', 0xBC, 0xAF, 0x27, 0x1C}, 6, false, CreateArc, CreateArcOut };
+
+REGISTER_ARC_DEC_SIG(7z)
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/misc/libphysfs/lzma/CPP/7zip/Archive/7z/7zSpecStream.cpp	Mon Apr 10 12:06:43 2017 -0400
@@ -0,0 +1,24 @@
+// 7zSpecStream.cpp
+
+#include "StdAfx.h"
+
+#include "7zSpecStream.h"
+
+STDMETHODIMP CSequentialInStreamSizeCount2::Read(void *data, UInt32 size, UInt32 *processedSize)
+{
+  UInt32 realProcessedSize;
+  HRESULT result = _stream->Read(data, size, &realProcessedSize);
+  _size += realProcessedSize;
+  if (processedSize != 0)
+    *processedSize = realProcessedSize;
+  return result; 
+}
+
+STDMETHODIMP CSequentialInStreamSizeCount2::GetSubStreamSize(
+    UInt64 subStream, UInt64 *value)
+{
+  if (_getSubStreamSize == NULL)
+    return E_NOTIMPL;
+  return  _getSubStreamSize->GetSubStreamSize(subStream, value);
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/misc/libphysfs/lzma/CPP/7zip/Archive/7z/7zSpecStream.h	Mon Apr 10 12:06:43 2017 -0400
@@ -0,0 +1,35 @@
+// 7zSpecStream.h
+
+#ifndef __7Z_SPEC_STREAM_H
+#define __7Z_SPEC_STREAM_H
+
+#include "../../IStream.h"
+#include "../../ICoder.h"
+#include "../../../Common/MyCom.h"
+
+class CSequentialInStreamSizeCount2: 
+  public ISequentialInStream,
+  public ICompressGetSubStreamSize,
+  public CMyUnknownImp
+{
+  CMyComPtr<ISequentialInStream> _stream;
+  CMyComPtr<ICompressGetSubStreamSize> _getSubStreamSize;
+  UInt64 _size;
+public:
+  void Init(ISequentialInStream *stream)
+  {
+    _stream = stream;
+    _getSubStreamSize = 0;
+    _stream.QueryInterface(IID_ICompressGetSubStreamSize, &_getSubStreamSize);
+    _size = 0;
+  }
+  UInt64 GetSize() const { return _size; }
+
+  MY_UNKNOWN_IMP1(ICompressGetSubStreamSize)
+
+  STDMETHOD(Read)(void *data, UInt32 size, UInt32 *processedSize);
+
+  STDMETHOD(GetSubStreamSize)(UInt64 subStream, UInt64 *value);
+};
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/misc/libphysfs/lzma/CPP/7zip/Archive/7z/7zUpdate.cpp	Mon Apr 10 12:06:43 2017 -0400
@@ -0,0 +1,1029 @@
+// UpdateMain.cpp
+
+#include "StdAfx.h"
+
+#include "7zUpdate.h"
+#include "7zFolderInStream.h"
+#include "7zEncode.h"
+#include "7zHandler.h"
+#include "7zOut.h"
+
+#include "../../Compress/Copy/CopyCoder.h"
+#include "../../Common/ProgressUtils.h"
+#include "../../Common/LimitedStreams.h"
+#include "../../Common/LimitedStreams.h"
+#include "../Common/ItemNameUtils.h"
+
+namespace NArchive {
+namespace N7z {
+
+static const wchar_t *kMatchFinderForBCJ2_LZMA = L"BT2";
+static const UInt32 kDictionaryForBCJ2_LZMA = 1 << 20;
+static const UInt32 kAlgorithmForBCJ2_LZMA = 1;
+static const UInt32 kNumFastBytesForBCJ2_LZMA = 64;
+
+static HRESULT WriteRange(IInStream *inStream, ISequentialOutStream *outStream, 
+    UInt64 position, UInt64 size, ICompressProgressInfo *progress)
+{
+  RINOK(inStream->Seek(position, STREAM_SEEK_SET, 0));
+  CLimitedSequentialInStream *streamSpec = new CLimitedSequentialInStream;
+  CMyComPtr<CLimitedSequentialInStream> inStreamLimited(streamSpec);
+  streamSpec->SetStream(inStream);
+  streamSpec->Init(size);
+
+  NCompress::CCopyCoder *copyCoderSpec = new NCompress::CCopyCoder;
+  CMyComPtr<ICompressCoder> copyCoder = copyCoderSpec;
+  RINOK(copyCoder->Code(inStreamLimited, outStream, NULL, NULL, progress));
+  return (copyCoderSpec->TotalSize == size ? S_OK : E_FAIL);
+}
+
+static int GetReverseSlashPos(const UString &name)
+{
+  int slashPos = name.ReverseFind(L'/');
+  #ifdef _WIN32
+  int slash1Pos = name.ReverseFind(L'\\');
+  slashPos = MyMax(slashPos, slash1Pos);
+  #endif
+  return slashPos;
+}
+
+int CUpdateItem::GetExtensionPos() const
+{
+  int slashPos = GetReverseSlashPos(Name);
+  int dotPos = Name.ReverseFind(L'.');
+  if (dotPos < 0 || (dotPos < slashPos && slashPos >= 0))
+    return Name.Length();
+  return dotPos + 1;
+}
+
+UString CUpdateItem::GetExtension() const
+{
+  return Name.Mid(GetExtensionPos());
+}
+
+#define RINOZ(x) { int __tt = (x); if (__tt != 0) return __tt; }
+
+static int CompareBuffers(const CByteBuffer &a1, const CByteBuffer &a2)
+{
+  size_t c1 = a1.GetCapacity();
+  size_t c2 = a2.GetCapacity();
+  RINOZ(MyCompare(c1, c2));
+  for (size_t i = 0; i < c1; i++)
+    RINOZ(MyCompare(a1[i], a2[i]));
+  return 0;
+}
+
+static int CompareCoders(const CCoderInfo &c1, const CCoderInfo &c2)
+{
+  RINOZ(MyCompare(c1.NumInStreams, c2.NumInStreams));
+  RINOZ(MyCompare(c1.NumOutStreams, c2.NumOutStreams));
+  RINOZ(MyCompare(c1.MethodID, c2.MethodID));
+  return CompareBuffers(c1.Properties, c2.Properties);
+}
+
+static int CompareBindPairs(const CBindPair &b1, const CBindPair &b2)
+{
+  RINOZ(MyCompare(b1.InIndex, b2.InIndex));
+  return MyCompare(b1.OutIndex, b2.OutIndex);
+}
+
+static int CompareFolders(const CFolder &f1, const CFolder &f2)
+{
+  int s1 = f1.Coders.Size();
+  int s2 = f2.Coders.Size();
+  RINOZ(MyCompare(s1, s2));
+  int i;
+  for (i = 0; i < s1; i++)
+    RINOZ(CompareCoders(f1.Coders[i], f2.Coders[i]));
+  s1 = f1.BindPairs.Size();
+  s2 = f2.BindPairs.Size();
+  RINOZ(MyCompare(s1, s2));
+  for (i = 0; i < s1; i++)
+    RINOZ(CompareBindPairs(f1.BindPairs[i], f2.BindPairs[i]));
+  return 0;
+}
+
+static int CompareFiles(const CFileItem &f1, const CFileItem &f2)
+{
+  return MyStringCompareNoCase(f1.Name, f2.Name);
+}
+
+static int CompareFolderRefs(const int *p1, const int *p2, void *param)
+{
+  int i1 = *p1;
+  int i2 = *p2;
+  const CArchiveDatabaseEx &db = *(const CArchiveDatabaseEx *)param;
+  RINOZ(CompareFolders(
+      db.Folders[i1],
+      db.Folders[i2]));
+  RINOZ(MyCompare(
+      db.NumUnPackStreamsVector[i1],
+      db.NumUnPackStreamsVector[i2]));
+  if (db.NumUnPackStreamsVector[i1] == 0)
+    return 0;
+  return CompareFiles(
+      db.Files[db.FolderStartFileIndex[i1]],
+      db.Files[db.FolderStartFileIndex[i2]]);
+}
+
+////////////////////////////////////////////////////////////
+
+static int CompareEmptyItems(const int *p1, const int *p2, void *param)
+{
+  const CObjectVector<CUpdateItem> &updateItems = *(const CObjectVector<CUpdateItem> *)param;
+  const CUpdateItem &u1 = updateItems[*p1];
+  const CUpdateItem &u2 = updateItems[*p2];
+  if (u1.IsDirectory != u2.IsDirectory)
+    return (u1.IsDirectory) ? 1 : -1;
+  if (u1.IsDirectory)
+  {
+    if (u1.IsAnti != u2.IsAnti)
+      return (u1.IsAnti ? 1 : -1);
+    int n = MyStringCompareNoCase(u1.Name, u2.Name);
+    return -n;
+  }
+  if (u1.IsAnti != u2.IsAnti)
+    return (u1.IsAnti ? 1 : -1);
+  return MyStringCompareNoCase(u1.Name, u2.Name);
+}
+
+static const char *g_Exts = 
+  " lzma 7z ace arc arj bz bz2 deb lzo lzx gz pak rpm sit tgz tbz tbz2 tgz cab ha lha lzh rar zoo" 
+  " zip jar ear war msi"
+  " 3gp avi mov mpeg mpg mpe wmv"
+  " aac ape fla flac la mp3 m4a mp4 ofr ogg pac ra rm rka shn swa tta wv wma wav"
+  " swf "
+  " chm hxi hxs"
+  " gif jpeg jpg jp2 png tiff  bmp ico psd psp"
+  " awg ps eps cgm dxf svg vrml wmf emf ai md"
+  " cad dwg pps key sxi"
+  " max 3ds"
+  " iso bin nrg mdf img pdi tar cpio xpi"
+  " vfd vhd vud vmc vsv"
+  " vmdk dsk nvram vmem vmsd vmsn vmss vmtm"
+  " inl inc idl acf asa h hpp hxx c cpp cxx rc java cs pas bas vb cls ctl frm dlg def" 
+  " f77 f f90 f95"
+  " asm sql manifest dep "
+  " mak clw csproj vcproj sln dsp dsw "
+  " class "
+  " bat cmd"
+  " xml xsd xsl xslt hxk hxc htm html xhtml xht mht mhtml htw asp aspx css cgi jsp shtml"
+  " awk sed hta js php php3 php4 php5 phptml pl pm py pyo rb sh tcl vbs"
+  " text txt tex ans asc srt reg ini doc docx mcw dot rtf hlp xls xlr xlt xlw ppt pdf"
+  " sxc sxd sxi sxg sxw stc sti stw stm odt ott odg otg odp otp ods ots odf"
+  " abw afp cwk lwp wpd wps wpt wrf wri"
+  " abf afm bdf fon mgf otf pcf pfa snf ttf"
+  " dbf mdb nsf ntf wdb db fdb gdb"
+  " exe dll ocx vbx sfx sys tlb awx com obj lib out o so "
+  " pdb pch idb ncb opt";
+
+int GetExtIndex(const char *ext)
+{
+  int extIndex = 1;
+  const char *p = g_Exts;
+  for (;;)
+  {
+    char c = *p++;
+    if (c == 0)
+      return extIndex;
+    if (c == ' ')
+      continue;
+    int pos = 0;
+    for (;;)
+    {
+      char c2 = ext[pos++];
+      if (c2 == 0 && (c == 0 || c == ' '))
+        return extIndex;
+      if (c != c2)
+        break;
+      c = *p++;
+    }
+    extIndex++;
+    for (;;)
+    {
+      if (c == 0)
+        return extIndex;
+      if (c == ' ')
+        break;
+      c = *p++;
+    }
+  }
+}
+
+struct CRefItem
+{
+  UInt32 Index;
+  const CUpdateItem *UpdateItem;
+  UInt32 ExtensionPos;
+  UInt32 NamePos;
+  int ExtensionIndex;
+  CRefItem(UInt32 index, const CUpdateItem &updateItem, bool sortByType):
+    Index(index),
+    UpdateItem(&updateItem),
+    ExtensionPos(0),
+    NamePos(0),
+    ExtensionIndex(0)
+  {
+    if (sortByType)
+    {
+      int slashPos = GetReverseSlashPos(updateItem.Name);
+      NamePos = ((slashPos >= 0) ? (slashPos + 1) : 0);
+      int dotPos = updateItem.Name.ReverseFind(L'.');
+      if (dotPos < 0 || (dotPos < slashPos && slashPos >= 0))
+        ExtensionPos = updateItem.Name.Length();
+      else 
+      {
+        ExtensionPos = dotPos + 1;
+        UString us = updateItem.Name.Mid(ExtensionPos);
+        if (!us.IsEmpty())
+        {
+          us.MakeLower();
+          int i;
+          AString s;
+          for (i = 0; i < us.Length(); i++)
+          {
+            wchar_t c = us[i];
+            if (c >= 0x80)
+              break;
+            s += (char)c;
+          }
+          if (i == us.Length())
+            ExtensionIndex = GetExtIndex(s);
+          else
+            ExtensionIndex = 0;
+        }
+      }
+    }
+  }
+};
+
+static int CompareUpdateItems(const CRefItem *p1, const CRefItem *p2, void *param)
+{
+  const CRefItem &a1 = *p1;
+  const CRefItem &a2 = *p2;
+  const CUpdateItem &u1 = *a1.UpdateItem;
+  const CUpdateItem &u2 = *a2.UpdateItem;
+  int n;
+  if (u1.IsDirectory != u2.IsDirectory)
+    return (u1.IsDirectory) ? 1 : -1;
+  if (u1.IsDirectory)
+  {
+    if (u1.IsAnti != u2.IsAnti)
+      return (u1.IsAnti ? 1 : -1);
+    n = MyStringCompareNoCase(u1.Name, u2.Name);
+    return -n;
+  }
+  bool sortByType = *(bool *)param;
+  if (sortByType)
+  {
+    RINOZ(MyCompare(a1.ExtensionIndex, a2.ExtensionIndex))
+    RINOZ(MyStringCompareNoCase(u1.Name + a1.ExtensionPos, u2.Name + a2.ExtensionPos));
+    RINOZ(MyStringCompareNoCase(u1.Name + a1.NamePos, u2.Name + a2.NamePos));
+    if (u1.IsLastWriteTimeDefined && u2.IsLastWriteTimeDefined)
+      RINOZ(CompareFileTime(&u1.LastWriteTime, &u2.LastWriteTime));
+    RINOZ(MyCompare(u1.Size, u2.Size))
+  }
+  return MyStringCompareNoCase(u1.Name, u2.Name);
+}
+
+struct CSolidGroup
+{
+  CCompressionMethodMode Method;
+  CRecordVector<UInt32> Indices;
+};
+
+static wchar_t *g_ExeExts[] =
+{
+  L"dll",
+  L"exe",
+  L"ocx",
+  L"sfx",
+  L"sys"
+};
+
+static bool IsExeFile(const UString &ext)
+{
+  for (int i = 0; i < sizeof(g_ExeExts) / sizeof(g_ExeExts[0]); i++)
+    if (ext.CompareNoCase(g_ExeExts[i]) == 0)
+      return true;
+  return false;
+}
+
+static const UInt64 k_LZMA  = 0x030101;
+static const UInt64 k_BCJ   = 0x03030103;
+static const UInt64 k_BCJ2  = 0x0303011B;
+
+static bool GetMethodFull(UInt64 methodID, 
+    UInt32 numInStreams, CMethodFull &methodResult)
+{
+  methodResult.Id = methodID;
+  methodResult.NumInStreams = numInStreams;
+  methodResult.NumOutStreams = 1;
+  return true;
+}
+
+static bool MakeExeMethod(const CCompressionMethodMode &method, 
+    bool bcj2Filter, CCompressionMethodMode &exeMethod)
+{
+  exeMethod = method;
+  if (bcj2Filter)
+  {
+    CMethodFull methodFull;
+    if (!GetMethodFull(k_BCJ2, 4, methodFull))
+      return false;
+    exeMethod.Methods.Insert(0, methodFull);
+    if (!GetMethodFull(k_LZMA, 1, methodFull))
+      return false;
+    {
+      CProp property;
+      property.Id = NCoderPropID::kAlgorithm;
+      property.Value = kAlgorithmForBCJ2_LZMA;
+      methodFull.Properties.Add(property);
+    }
+    {
+      CProp property;
+      property.Id = NCoderPropID::kMatchFinder;
+      property.Value = kMatchFinderForBCJ2_LZMA;
+      methodFull.Properties.Add(property);
+    }
+    {
+      CProp property;
+      property.Id = NCoderPropID::kDictionarySize;
+      property.Value = kDictionaryForBCJ2_LZMA;
+      methodFull.Properties.Add(property);
+    }
+    {
+      CProp property;
+      property.Id = NCoderPropID::kNumFastBytes;
+      property.Value = kNumFastBytesForBCJ2_LZMA;
+      methodFull.Properties.Add(property);
+    }
+
+    exeMethod.Methods.Add(methodFull);
+    exeMethod.Methods.Add(methodFull);
+    CBind bind;
+
+    bind.OutCoder = 0;
+    bind.InStream = 0;
+
+    bind.InCoder = 1;
+    bind.OutStream = 0;
+    exeMethod.Binds.Add(bind);
+
+    bind.InCoder = 2;
+    bind.OutStream = 1;
+    exeMethod.Binds.Add(bind);
+
+    bind.InCoder = 3;
+    bind.OutStream = 2;
+    exeMethod.Binds.Add(bind);
+  }
+  else
+  {
+    CMethodFull methodFull;
+    if (!GetMethodFull(k_BCJ, 1, methodFull))
+      return false;
+    exeMethod.Methods.Insert(0, methodFull);
+    CBind bind;
+    bind.OutCoder = 0;
+    bind.InStream = 0;
+    bind.InCoder = 1;
+    bind.OutStream = 0;
+    exeMethod.Binds.Add(bind);
+  }
+  return true;
+}   
+
+static void SplitFilesToGroups(
+    const CCompressionMethodMode &method, 
+    bool useFilters, bool maxFilter,
+    const CObjectVector<CUpdateItem> &updateItems,
+    CObjectVector<CSolidGroup> &groups)
+{
+  if (method.Methods.Size() != 1 || method.Binds.Size() != 0)
+    useFilters = false;
+  groups.Clear();
+  groups.Add(CSolidGroup());
+  groups.Add(CSolidGroup());
+  CSolidGroup &generalGroup = groups[0];
+  CSolidGroup &exeGroup = groups[1];
+  generalGroup.Method = method;
+  int i;
+  for (i = 0; i < updateItems.Size(); i++)
+  {
+    const CUpdateItem &updateItem = updateItems[i];
+    if (!updateItem.NewData)
+      continue;
+    if (!updateItem.HasStream())
+      continue;
+    if (useFilters)
+    {
+      const UString name = updateItem.Name;
+      int dotPos = name.ReverseFind(L'.');
+      if (dotPos >= 0)
+      {
+        UString ext = name.Mid(dotPos + 1);
+        if (IsExeFile(ext))
+        {
+          exeGroup.Indices.Add(i);
+          continue;
+        }
+      }
+    }
+    generalGroup.Indices.Add(i);
+  }
+  if (exeGroup.Indices.Size() > 0)
+    if (!MakeExeMethod(method, maxFilter, exeGroup.Method))
+      exeGroup.Method = method;
+  for (i = 0; i < groups.Size();)
+    if (groups[i].Indices.Size() == 0)
+      groups.Delete(i);
+    else
+      i++;
+}
+
+static void FromUpdateItemToFileItem(const CUpdateItem &updateItem, 
+    CFileItem &file)
+{
+  file.Name = NItemName::MakeLegalName(updateItem.Name);
+  if (updateItem.AttributesAreDefined)
+    file.SetAttributes(updateItem.Attributes);
+  
+  if (updateItem.IsCreationTimeDefined)
+    file.SetCreationTime(updateItem.CreationTime);
+  if (updateItem.IsLastWriteTimeDefined)
+    file.SetLastWriteTime(updateItem.LastWriteTime);
+  if (updateItem.IsLastAccessTimeDefined)
+    file.SetLastAccessTime(updateItem.LastAccessTime);
+  
+  file.UnPackSize = updateItem.Size;
+  file.IsDirectory = updateItem.IsDirectory;
+  file.IsAnti = updateItem.IsAnti;
+  file.HasStream = updateItem.HasStream();
+}
+
+static HRESULT Update2(
+    DECL_EXTERNAL_CODECS_LOC_VARS
+    IInStream *inStream,
+    const CArchiveDatabaseEx *database,
+    const CObjectVector<CUpdateItem> &updateItems,
+    ISequentialOutStream *seqOutStream,
+    IArchiveUpdateCallback *updateCallback,
+    const CUpdateOptions &options)
+{
+  UInt64 numSolidFiles = options.NumSolidFiles;
+  if (numSolidFiles == 0)
+    numSolidFiles = 1;
+  /*
+  CMyComPtr<IOutStream> outStream;
+  RINOK(seqOutStream->QueryInterface(IID_IOutStream, (void **)&outStream));
+  if (!outStream)
+    return E_NOTIMPL;
+  */
+
+  UInt64 startBlockSize = database != 0 ? database->ArchiveInfo.StartPosition: 0;
+  if (startBlockSize > 0 && !options.RemoveSfxBlock)
+  {
+    RINOK(WriteRange(inStream, seqOutStream, 0, startBlockSize, NULL));
+  }
+
+  CRecordVector<int> fileIndexToUpdateIndexMap;
+  if (database != 0)
+  {
+    fileIndexToUpdateIndexMap.Reserve(database->Files.Size());
+    for (int i = 0; i < database->Files.Size(); i++)
+      fileIndexToUpdateIndexMap.Add(-1);
+  }
+  int i;
+  for(i = 0; i < updateItems.Size(); i++)
+  {
+    int index = updateItems[i].IndexInArchive;
+    if (index != -1)
+      fileIndexToUpdateIndexMap[index] = i;
+  }
+
+  CRecordVector<int> folderRefs;
+  if (database != 0)
+  {
+    for(i = 0; i < database->Folders.Size(); i++)
+    {
+      CNum indexInFolder = 0;
+      CNum numCopyItems = 0;
+      CNum numUnPackStreams = database->NumUnPackStreamsVector[i];
+      for (CNum fileIndex = database->FolderStartFileIndex[i];
+      indexInFolder < numUnPackStreams; fileIndex++)
+      {
+        if (database->Files[fileIndex].HasStream)
+        {
+          indexInFolder++;
+          int updateIndex = fileIndexToUpdateIndexMap[fileIndex];
+          if (updateIndex >= 0)
+            if (!updateItems[updateIndex].NewData)
+              numCopyItems++;
+        }
+      }
+      if (numCopyItems != numUnPackStreams && numCopyItems != 0)
+        return E_NOTIMPL; // It needs repacking !!!
+      if (numCopyItems > 0)
+        folderRefs.Add(i);
+    }
+    folderRefs.Sort(CompareFolderRefs, (void *)database);
+  }
+
+  CArchiveDatabase newDatabase;
+
+  ////////////////////////////
+
+  COutArchive archive;
+  RINOK(archive.Create(seqOutStream, false));
+  RINOK(archive.SkeepPrefixArchiveHeader());
+  UInt64 complexity = 0;
+  for(i = 0; i < folderRefs.Size(); i++)
+    complexity += database->GetFolderFullPackSize(folderRefs[i]);
+  UInt64 inSizeForReduce = 0;
+  for(i = 0; i < updateItems.Size(); i++)
+  {
+    const CUpdateItem &updateItem = updateItems[i];
+    if (updateItem.NewData)
+    {
+      complexity += updateItem.Size;
+      if (numSolidFiles == 1)
+      {
+        if (updateItem.Size > inSizeForReduce)
+          inSizeForReduce = updateItem.Size;
+      }
+      else
+        inSizeForReduce += updateItem.Size;
+    }
+  }
+  RINOK(updateCallback->SetTotal(complexity));
+  complexity = 0;
+  RINOK(updateCallback->SetCompleted(&complexity));
+
+
+  CLocalProgress *lps = new CLocalProgress;
+  CMyComPtr<ICompressProgressInfo> progress = lps;
+  lps->Init(updateCallback, true);
+
+  /////////////////////////////////////////
+  // Write Copy Items
+
+  for(i = 0; i < folderRefs.Size(); i++)
+  {
+    int folderIndex = folderRefs[i];
+    
+    lps->ProgressOffset = complexity;
+    UInt64 packSize = database->GetFolderFullPackSize(folderIndex);
+    RINOK(WriteRange(inStream, archive.SeqStream,
+        database->GetFolderStreamPos(folderIndex, 0), packSize, progress));
+    complexity += packSize;
+    
+    const CFolder &folder = database->Folders[folderIndex];
+    CNum startIndex = database->FolderStartPackStreamIndex[folderIndex];
+    for (int j = 0; j < folder.PackStreams.Size(); j++)
+    {
+      newDatabase.PackSizes.Add(database->PackSizes[startIndex + j]);
+      // newDatabase.PackCRCsDefined.Add(database.PackCRCsDefined[startIndex + j]);
+      // newDatabase.PackCRCs.Add(database.PackCRCs[startIndex + j]);
+    }
+    newDatabase.Folders.Add(folder);
+
+    CNum numUnPackStreams = database->NumUnPackStreamsVector[folderIndex];
+    newDatabase.NumUnPackStreamsVector.Add(numUnPackStreams);
+
+    CNum indexInFolder = 0;
+    for (CNum fi = database->FolderStartFileIndex[folderIndex];
+        indexInFolder < numUnPackStreams; fi++)
+    {
+      CFileItem file = database->Files[fi];
+      if (file.HasStream)
+      {
+        indexInFolder++;
+        int updateIndex = fileIndexToUpdateIndexMap[fi];
+        if (updateIndex >= 0)
+        {
+          const CUpdateItem &updateItem = updateItems[updateIndex];
+          if (updateItem.NewProperties)
+          {
+            CFileItem file2;
+            FromUpdateItemToFileItem(updateItem, file2);
+            file2.UnPackSize = file.UnPackSize;
+            file2.FileCRC = file.FileCRC;
+            file2.IsFileCRCDefined = file.IsFileCRCDefined;
+            file2.HasStream = file.HasStream;
+            file = file2;
+          }
+        }
+        newDatabase.Files.Add(file);
+      }
+    }
+  }
+
+  /////////////////////////////////////////
+  // Compress New Files
+
+  CObjectVector<CSolidGroup> groups;
+  SplitFilesToGroups(*options.Method, options.UseFilters, options.MaxFilter, 
+      updateItems, groups);
+
+  const UInt32 kMinReduceSize = (1 << 16);
+  if (inSizeForReduce < kMinReduceSize)
+    inSizeForReduce = kMinReduceSize;
+
+  for (int groupIndex = 0; groupIndex < groups.Size(); groupIndex++)
+  {
+    const CSolidGroup &group = groups[groupIndex];
+    int numFiles = group.Indices.Size();
+    if (numFiles == 0)
+      continue;
+    CRecordVector<CRefItem> refItems;
+    refItems.Reserve(numFiles);
+    bool sortByType = (numSolidFiles > 1);
+    for (i = 0; i < numFiles; i++)
+      refItems.Add(CRefItem(group.Indices[i], updateItems[group.Indices[i]], sortByType));
+    refItems.Sort(CompareUpdateItems, (void *)&sortByType);
+    
+    CRecordVector<UInt32> indices;
+    indices.Reserve(numFiles);
+
+    for (i = 0; i < numFiles; i++)
+    {
+      UInt32 index = refItems[i].Index;
+      indices.Add(index);
+      /*
+      const CUpdateItem &updateItem = updateItems[index];
+      CFileItem file;
+      if (updateItem.NewProperties)
+        FromUpdateItemToFileItem(updateItem, file);
+      else
+        file = database.Files[updateItem.IndexInArchive];
+      if (file.IsAnti || file.IsDirectory)
+        return E_FAIL;
+      newDatabase.Files.Add(file);
+      */
+    }
+    
+    CEncoder encoder(group.Method);
+
+    for (i = 0; i < numFiles;)
+    {
+      UInt64 totalSize = 0;
+      int numSubFiles;
+      UString prevExtension;
+      for (numSubFiles = 0; i + numSubFiles < numFiles && 
+          numSubFiles < numSolidFiles; numSubFiles++)
+      {
+        const CUpdateItem &updateItem = updateItems[indices[i + numSubFiles]];
+        totalSize += updateItem.Size;
+        if (totalSize > options.NumSolidBytes)
+          break;
+        if (options.SolidExtension)
+        {
+          UString ext = updateItem.GetExtension();
+          if (numSubFiles == 0)
+            prevExtension = ext;
+          else
+            if (ext.CompareNoCase(prevExtension) != 0)
+              break;
+        }
+      }
+      if (numSubFiles < 1)
+        numSubFiles = 1;
+
+      CFolderInStream *inStreamSpec = new CFolderInStream;
+      CMyComPtr<ISequentialInStream> solidInStream(inStreamSpec);
+      inStreamSpec->Init(updateCallback, &indices[i], numSubFiles);
+      
+      CFolder folderItem;
+
+      int startPackIndex = newDatabase.PackSizes.Size();
+      RINOK(encoder.Encode(
+          EXTERNAL_CODECS_LOC_VARS
+          solidInStream, NULL, &inSizeForReduce, folderItem, 
+          archive.SeqStream, newDatabase.PackSizes, progress));
+
+      for (; startPackIndex < newDatabase.PackSizes.Size(); startPackIndex++)
+        lps->OutSize += newDatabase.PackSizes[startPackIndex];
+
+      lps->InSize += folderItem.GetUnPackSize();
+      // for()
+      // newDatabase.PackCRCsDefined.Add(false);
+      // newDatabase.PackCRCs.Add(0);
+      
+      newDatabase.Folders.Add(folderItem);
+      
+      CNum numUnPackStreams = 0;
+      for (int subIndex = 0; subIndex < numSubFiles; subIndex++)
+      {
+        const CUpdateItem &updateItem = updateItems[indices[i + subIndex]];
+        CFileItem file;
+        if (updateItem.NewProperties)
+          FromUpdateItemToFileItem(updateItem, file);
+        else
+          file = database->Files[updateItem.IndexInArchive];
+        if (file.IsAnti || file.IsDirectory)
+          return E_FAIL;
+        
+        /*
+        CFileItem &file = newDatabase.Files[
+              startFileIndexInDatabase + i + subIndex];
+        */
+        if (!inStreamSpec->Processed[subIndex])
+        {
+          continue;
+          // file.Name += L".locked";
+        }
+
+        file.FileCRC = inStreamSpec->CRCs[subIndex];
+        file.UnPackSize = inStreamSpec->Sizes[subIndex];
+        if (file.UnPackSize != 0)
+        {
+          file.IsFileCRCDefined = true;
+          file.HasStream = true;
+          numUnPackStreams++;
+        }
+        else
+        {
+          file.IsFileCRCDefined = false;
+          file.HasStream = false;
+        }
+        newDatabase.Files.Add(file);
+      }
+      // numUnPackStreams = 0 is very bad case for locked files
+      // v3.13 doesn't understand it.
+      newDatabase.NumUnPackStreamsVector.Add(numUnPackStreams);
+      i += numSubFiles;
+    }
+  }
+
+  {
+    /////////////////////////////////////////
+    // Write Empty Files & Folders
+    
+    CRecordVector<int> emptyRefs;
+    for(i = 0; i < updateItems.Size(); i++)
+    {
+      const CUpdateItem &updateItem = updateItems[i];
+      if (updateItem.NewData)
+      {
+        if (updateItem.HasStream())
+          continue;
+      }
+      else
+        if (updateItem.IndexInArchive != -1)
+          if (database->Files[updateItem.IndexInArchive].HasStream)
+            continue;
+      emptyRefs.Add(i);
+    }
+    emptyRefs.Sort(CompareEmptyItems, (void *)&updateItems);
+    for(i = 0; i < emptyRefs.Size(); i++)
+    {
+      const CUpdateItem &updateItem = updateItems[emptyRefs[i]];
+      CFileItem file;
+      if (updateItem.NewProperties)
+        FromUpdateItemToFileItem(updateItem, file);
+      else
+        file = database->Files[updateItem.IndexInArchive];
+      newDatabase.Files.Add(file);
+    }
+  }
+    
+  /*
+  if (newDatabase.Files.Size() != updateItems.Size())
+    return E_FAIL;
+  */
+
+  return archive.WriteDatabase(EXTERNAL_CODECS_LOC_VARS
+      newDatabase, options.HeaderMethod, options.HeaderOptions);
+}
+
+#ifdef _7Z_VOL
+
+static const UInt64 k_Copy = 0x0;
+
+static HRESULT WriteVolumeHeader(COutArchive &archive, CFileItem &file, const CUpdateOptions &options)
+{
+  CCoderInfo coder;
+  coder.NumInStreams = coder.NumOutStreams = 1;
+  coder.MethodID = k_Copy;
+  
+  CFolder folder;
+  folder.Coders.Add(coder);
+  folder.PackStreams.Add(0);
+  
+  CNum numUnPackStreams = 0;
+  if (file.UnPackSize != 0)
+  {
+    file.IsFileCRCDefined = true;
+    file.HasStream = true;
+    numUnPackStreams++;
+  }
+  else
+  {
+    throw 1;
+    file.IsFileCRCDefined = false;
+    file.HasStream = false;
+  }
+  folder.UnPackSizes.Add(file.UnPackSize);
+  
+  CArchiveDatabase newDatabase;
+  newDatabase.Files.Add(file);
+  newDatabase.Folders.Add(folder);
+  newDatabase.NumUnPackStreamsVector.Add(numUnPackStreams);
+  newDatabase.PackSizes.Add(file.UnPackSize);
+  newDatabase.PackCRCsDefined.Add(false);
+  newDatabase.PackCRCs.Add(file.FileCRC);
+  
+  return archive.WriteDatabase(newDatabase, 
+      options.HeaderMethod, 
+      false, 
+      false);
+}
+
+HRESULT UpdateVolume(
+    IInStream *inStream,
+    const CArchiveDatabaseEx *database,
+    CObjectVector<CUpdateItem> &updateItems,
+    ISequentialOutStream *seqOutStream,
+    IArchiveUpdateCallback *updateCallback,
+    const CUpdateOptions &options)
+{
+  if (updateItems.Size() != 1)
+    return E_NOTIMPL;
+
+  CMyComPtr<IArchiveUpdateCallback2> volumeCallback;
+  RINOK(updateCallback->QueryInterface(IID_IArchiveUpdateCallback2, (void **)&volumeCallback));
+  if (!volumeCallback)
+    return E_NOTIMPL;
+
+  CMyComPtr<ISequentialInStream> fileStream;
+  HRESULT result = updateCallback->GetStream(0, &fileStream);
+  if (result != S_OK && result != S_FALSE)
+    return result;
+  if (result == S_FALSE)
+    return E_FAIL;
+  
+  CFileItem file;
+  
+  const CUpdateItem &updateItem = updateItems[0];
+  if (updateItem.NewProperties)
+    FromUpdateItemToFileItem(updateItem, file);
+  else
+    file = database->Files[updateItem.IndexInArchive];
+  if (file.IsAnti || file.IsDirectory)
+    return E_FAIL;
+
+  UInt64 complexity = 0;
+  file.IsStartPosDefined = true;
+  file.StartPos = 0;
+  for (UInt64 volumeIndex = 0; true; volumeIndex++)
+  { 
+    UInt64 volSize;
+    RINOK(volumeCallback->GetVolumeSize(volumeIndex, &volSize));
+    UInt64 pureSize = COutArchive::GetVolPureSize(volSize, file.Name.Length(), true);
+    CMyComPtr<ISequentialOutStream> volumeStream;
+    RINOK(volumeCallback->GetVolumeStream(volumeIndex, &volumeStream));
+   
+    COutArchive archive;
+    RINOK(archive.Create(volumeStream, true));
+    RINOK(archive.SkeepPrefixArchiveHeader());
+        
+    CSequentialInStreamWithCRC *inCrcStreamSpec = new CSequentialInStreamWithCRC;
+    CMyComPtr<ISequentialInStream> inCrcStream = inCrcStreamSpec;
+    inCrcStreamSpec->Init(fileStream);
+
+    RINOK(WriteRange(inCrcStream, volumeStream, pureSize, updateCallback, complexity));
+    file.UnPackSize = inCrcStreamSpec->GetSize();
+    if (file.UnPackSize == 0)
+      break;
+    file.FileCRC = inCrcStreamSpec->GetCRC();
+    RINOK(WriteVolumeHeader(archive, file, options));
+    file.StartPos += file.UnPackSize;
+    if (file.UnPackSize < pureSize)
+      break;
+  }
+  return S_OK;
+}
+
+class COutVolumeStream: 
+  public ISequentialOutStream,
+  public CMyUnknownImp
+{
+  int _volIndex;
+  UInt64 _volSize;
+  UInt64 _curPos;
+  CMyComPtr<ISequentialOutStream> _volumeStream;
+  COutArchive _archive;
+  CCRC _crc;
+
+public:
+  MY_UNKNOWN_IMP
+
+  CFileItem _file;
+  CUpdateOptions _options;
+  CMyComPtr<IArchiveUpdateCallback2> VolumeCallback;
+  void Init(IArchiveUpdateCallback2 *volumeCallback, 
+      const UString &name)  
+  { 
+    _file.Name = name;
+    _file.IsStartPosDefined = true;
+    _file.StartPos = 0;
+    
+    VolumeCallback = volumeCallback;
+    _volIndex = 0;
+    _volSize = 0;
+  }
+  
+  HRESULT Flush();
+  STDMETHOD(Write)(const void *data, UInt32 size, UInt32 *processedSize);
+};
+
+HRESULT COutVolumeStream::Flush()
+{
+  if (_volumeStream)
+  {
+    _file.UnPackSize = _curPos;
+    _file.FileCRC = _crc.GetDigest();
+    RINOK(WriteVolumeHeader(_archive, _file, _options));
+    _archive.Close();
+    _volumeStream.Release();
+    _file.StartPos += _file.UnPackSize;
+  }
+  return S_OK;
+}
+
+STDMETHODIMP COutVolumeStream::Write(const void *data, UInt32 size, UInt32 *processedSize)
+{
+  if(processedSize != NULL)
+    *processedSize = 0;
+  while(size > 0)
+  {
+    if (!_volumeStream)
+    {
+      RINOK(VolumeCallback->GetVolumeSize(_volIndex, &_volSize));
+      RINOK(VolumeCallback->GetVolumeStream(_volIndex, &_volumeStream));
+      _volIndex++;
+      _curPos = 0;
+      RINOK(_archive.Create(_volumeStream, true));
+      RINOK(_archive.SkeepPrefixArchiveHeader());
+      _crc.Init();
+      continue;
+    }
+    UInt64 pureSize = COutArchive::GetVolPureSize(_volSize, _file.Name.Length());
+    UInt32 curSize = (UInt32)MyMin(UInt64(size), pureSize - _curPos);
+
+    _crc.Update(data, curSize);
+    UInt32 realProcessed;
+    RINOK(_volumeStream->Write(data, curSize, &realProcessed))
+    data = (void *)((Byte *)data + realProcessed);
+    size -= realProcessed;
+    if(processedSize != NULL)
+      *processedSize += realProcessed;
+    _curPos += realProcessed;
+    if (realProcessed != curSize && realProcessed == 0)
+      return E_FAIL;
+    if (_curPos == pureSize)
+    {
+      RINOK(Flush());
+    }
+  }
+  return S_OK;
+}
+
+#endif
+
+HRESULT Update(
+    DECL_EXTERNAL_CODECS_LOC_VARS
+    IInStream *inStream,
+    const CArchiveDatabaseEx *database,
+    const CObjectVector<CUpdateItem> &updateItems,
+    ISequentialOutStream *seqOutStream,
+    IArchiveUpdateCallback *updateCallback,
+    const CUpdateOptions &options)
+{
+  #ifdef _7Z_VOL
+  if (seqOutStream)
+  #endif
+    return Update2(
+        EXTERNAL_CODECS_LOC_VARS
+        inStream, database, updateItems,
+        seqOutStream, updateCallback, options);
+  #ifdef _7Z_VOL
+  if (options.VolumeMode)
+    return UpdateVolume(inStream, database, updateItems,
+      seqOutStream, updateCallback, options);
+  COutVolumeStream *volStreamSpec = new COutVolumeStream;
+  CMyComPtr<ISequentialOutStream> volStream = volStreamSpec;
+  CMyComPtr<IArchiveUpdateCallback2> volumeCallback;
+  RINOK(updateCallback->QueryInterface(IID_IArchiveUpdateCallback2, (void **)&volumeCallback));
+  if (!volumeCallback)
+    return E_NOTIMPL;
+  volStreamSpec->Init(volumeCallback, L"a.7z");
+  volStreamSpec->_options = options;
+  RINOK(Update2(inStream, database, updateItems,
+    volStream, updateCallback, options));
+  return volStreamSpec->Flush();
+  #endif
+}
+
+}}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/misc/libphysfs/lzma/CPP/7zip/Archive/7z/7zUpdate.h	Mon Apr 10 12:06:43 2017 -0400
@@ -0,0 +1,80 @@
+// 7zUpdate.h
+
+#ifndef __7Z_UPDATE_H
+#define __7Z_UPDATE_H
+
+#include "7zIn.h"
+#include "7zOut.h"
+#include "7zCompressionMode.h"
+
+#include "../IArchive.h"
+
+namespace NArchive {
+namespace N7z {
+
+struct CUpdateItem
+{
+  bool NewData;
+  bool NewProperties;
+  int IndexInArchive;
+  int IndexInClient;
+  
+  UInt32 Attributes;
+  FILETIME CreationTime;
+  FILETIME LastWriteTime;
+  FILETIME LastAccessTime;
+
+  UInt64 Size;
+  UString Name;
+  
+  bool IsAnti;
+  bool IsDirectory;
+
+  bool IsCreationTimeDefined;
+  bool IsLastWriteTimeDefined;
+  bool IsLastAccessTimeDefined;
+  bool AttributesAreDefined;
+
+  bool HasStream() const 
+    { return !IsDirectory && !IsAnti && Size != 0; }
+  CUpdateItem():  
+      IsAnti(false), 
+      AttributesAreDefined(false), 
+      IsCreationTimeDefined(false), 
+      IsLastWriteTimeDefined(false), 
+      IsLastAccessTimeDefined(false)
+      {}
+  void SetDirectoryStatusFromAttributes()
+    { IsDirectory = ((Attributes & FILE_ATTRIBUTE_DIRECTORY) != 0); };
+
+  int GetExtensionPos() const;
+  UString GetExtension() const;
+};
+
+struct CUpdateOptions
+{
+  const CCompressionMethodMode *Method;
+  const CCompressionMethodMode *HeaderMethod;
+  bool UseFilters;
+  bool MaxFilter;
+
+  CHeaderOptions HeaderOptions;
+
+  UInt64 NumSolidFiles;
+  UInt64 NumSolidBytes;
+  bool SolidExtension;
+  bool RemoveSfxBlock;
+  bool VolumeMode;
+};
+
+HRESULT Update(
+    DECL_EXTERNAL_CODECS_LOC_VARS
+    IInStream *inStream,
+    const CArchiveDatabaseEx *database,
+    const CObjectVector<CUpdateItem> &updateItems,
+    ISequentialOutStream *seqOutStream,
+    IArchiveUpdateCallback *updateCallback,
+    const CUpdateOptions &options);
+}}
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/misc/libphysfs/lzma/CPP/7zip/Archive/7z/StdAfx.cpp	Mon Apr 10 12:06:43 2017 -0400
@@ -0,0 +1,3 @@
+// StdAfx.cpp
+
+#include "StdAfx.h"
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/misc/libphysfs/lzma/CPP/7zip/Archive/7z/StdAfx.h	Mon Apr 10 12:06:43 2017 -0400
@@ -0,0 +1,9 @@
+// StdAfx.h
+
+#ifndef __STDAFX_H
+#define __STDAFX_H
+
+#include "../../../Common/MyWindows.h"
+#include "../../../Common/NewHandler.h"
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/misc/libphysfs/lzma/CPP/7zip/Archive/Archive.def	Mon Apr 10 12:06:43 2017 -0400
@@ -0,0 +1,6 @@
+EXPORTS
+  CreateObject PRIVATE
+  GetHandlerProperty PRIVATE
+  GetNumberOfFormats PRIVATE
+  GetHandlerProperty2 PRIVATE
+  CreateObject PRIVATE
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/misc/libphysfs/lzma/CPP/7zip/Archive/Archive2.def	Mon Apr 10 12:06:43 2017 -0400
@@ -0,0 +1,9 @@
+EXPORTS
+  CreateObject PRIVATE
+  GetHandlerProperty PRIVATE
+  GetNumberOfFormats PRIVATE
+  GetHandlerProperty2 PRIVATE
+  CreateObject PRIVATE
+  GetNumberOfMethods PRIVATE
+  GetMethodProperty PRIVATE
+  SetLargePageMode PRIVATE
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/misc/libphysfs/lzma/CPP/7zip/Archive/ArchiveExports.cpp	Mon Apr 10 12:06:43 2017 -0400
@@ -0,0 +1,130 @@
+// ArchiveExports.cpp
+
+#include "StdAfx.h"
+
+#include "../../Common/ComTry.h"
+#include "../../Common/Types.h"
+#include "../../Windows/PropVariant.h"
+#include "../Common/RegisterArc.h"
+
+#include "IArchive.h"
+#include "../ICoder.h"
+#include "../IPassword.h"
+
+static const unsigned int kNumArcsMax = 32;
+static unsigned int g_NumArcs = 0;
+static const CArcInfo *g_Arcs[kNumArcsMax]; 
+void RegisterArc(const CArcInfo *arcInfo) 
+{ 
+  if (g_NumArcs < kNumArcsMax)
+    g_Arcs[g_NumArcs++] = arcInfo; 
+}
+
+DEFINE_GUID(CLSID_CArchiveHandler, 
+0x23170F69, 0x40C1, 0x278A, 0x10, 0x00, 0x00, 0x01, 0x10, 0x00, 0x00, 0x00);
+
+#define CLS_ARC_ID_ITEM(cls) ((cls).Data4[5])
+
+static inline HRESULT SetPropString(const char *s, unsigned int size, PROPVARIANT *value)
+{
+  if ((value->bstrVal = ::SysAllocStringByteLen(s, size)) != 0)
+    value->vt = VT_BSTR;
+  return S_OK;
+}
+
+static inline HRESULT SetPropGUID(const GUID &guid, PROPVARIANT *value)
+{
+  return SetPropString((const char *)&guid, sizeof(GUID), value);
+}
+
+int FindFormatCalssId(const GUID *clsID)
+{
+  GUID cls = *clsID;
+  CLS_ARC_ID_ITEM(cls) = 0;
+  if (cls != CLSID_CArchiveHandler)
+    return -1;
+  Byte id = CLS_ARC_ID_ITEM(*clsID);
+  for (UInt32 i = 0; i < g_NumArcs; i++)
+    if (g_Arcs[i]->ClassId == id)
+      return i;
+  return -1;
+}
+
+STDAPI CreateArchiver(const GUID *clsid, const GUID *iid, void **outObject)
+{
+  COM_TRY_BEGIN
+  {
+    int needIn = (*iid == IID_IInArchive);
+    int needOut = (*iid == IID_IOutArchive);
+    if (!needIn && !needOut)
+      return E_NOINTERFACE;
+    int formatIndex = FindFormatCalssId(clsid);
+    if (formatIndex < 0)
+      return CLASS_E_CLASSNOTAVAILABLE;
+    
+    const CArcInfo &arc = *g_Arcs[formatIndex];
+    if (needIn)
+    {
+      *outObject = arc.CreateInArchive();
+      ((IInArchive *)*outObject)->AddRef();
+    }
+    else
+    {
+      if (!arc.CreateOutArchive)
+        return CLASS_E_CLASSNOTAVAILABLE;
+      *outObject = arc.CreateOutArchive();
+      ((IOutArchive *)*outObject)->AddRef();
+    }
+  }
+  COM_TRY_END
+  return S_OK;
+}
+
+STDAPI GetHandlerProperty2(UInt32 formatIndex, PROPID propID, PROPVARIANT *value)
+{
+  if (formatIndex >= g_NumArcs)
+    return E_INVALIDARG;
+  const CArcInfo &arc = *g_Arcs[formatIndex];
+  NWindows::NCOM::CPropVariant prop;
+  switch(propID)
+  {
+    case NArchive::kName:
+      prop = arc.Name;
+      break;
+    case NArchive::kClassID:
+    {
+      GUID clsId = CLSID_CArchiveHandler;
+      CLS_ARC_ID_ITEM(clsId) = arc.ClassId;
+      return SetPropGUID(clsId, value);
+    }
+    case NArchive::kExtension:
+      if (arc.Ext != 0)
+        prop = arc.Ext;
+      break;
+    case NArchive::kAddExtension:
+      if (arc.AddExt != 0)
+        prop = arc.AddExt;
+      break;
+    case NArchive::kUpdate:
+      prop = (bool)(arc.CreateOutArchive != 0);
+      break;
+    case NArchive::kKeepName:
+      prop = arc.KeepName;
+      break;
+    case NArchive::kStartSignature:
+      return SetPropString((const char *)arc.Signature, arc.SignatureSize, value);
+  }
+  prop.Detach(value);
+  return S_OK;
+}
+
+STDAPI GetHandlerProperty(PROPID propID, PROPVARIANT *value)
+{
+  return GetHandlerProperty2(0, propID, value);
+}
+
+STDAPI GetNumberOfFormats(UINT32 *numFormats)
+{
+  *numFormats = g_NumArcs;
+  return S_OK;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/misc/libphysfs/lzma/CPP/7zip/Archive/Common/CoderMixer2.cpp	Mon Apr 10 12:06:43 2017 -0400
@@ -0,0 +1,121 @@
+// CoderMixer2.cpp
+
+#include "StdAfx.h"
+
+#include "CoderMixer2.h"
+
+namespace NCoderMixer {
+
+CBindReverseConverter::CBindReverseConverter(const CBindInfo &srcBindInfo):
+  _srcBindInfo(srcBindInfo)
+{
+  srcBindInfo.GetNumStreams(NumSrcInStreams, _numSrcOutStreams);
+
+  UInt32  j;
+  for (j = 0; j < NumSrcInStreams; j++)
+  {
+    _srcInToDestOutMap.Add(0);
+    DestOutToSrcInMap.Add(0);
+  }
+  for (j = 0; j < _numSrcOutStreams; j++)
+  {
+    _srcOutToDestInMap.Add(0);
+    _destInToSrcOutMap.Add(0);
+  }
+
+  UInt32 destInOffset = 0;
+  UInt32 destOutOffset = 0;
+  UInt32 srcInOffset = NumSrcInStreams;
+  UInt32 srcOutOffset = _numSrcOutStreams;
+
+  for (int i = srcBindInfo.Coders.Size() - 1; i >= 0; i--)
+  {
+    const CCoderStreamsInfo &srcCoderInfo = srcBindInfo.Coders[i];
+
+    srcInOffset -= srcCoderInfo.NumInStreams;
+    srcOutOffset -= srcCoderInfo.NumOutStreams;
+    
+    UInt32 j;
+    for (j = 0; j < srcCoderInfo.NumInStreams; j++, destOutOffset++)
+    {
+      UInt32 index = srcInOffset + j;
+      _srcInToDestOutMap[index] = destOutOffset;
+      DestOutToSrcInMap[destOutOffset] = index;
+    }
+    for (j = 0; j < srcCoderInfo.NumOutStreams; j++, destInOffset++)
+    {
+      UInt32 index = srcOutOffset + j;
+      _srcOutToDestInMap[index] = destInOffset;
+      _destInToSrcOutMap[destInOffset] = index;
+    }
+  }
+}
+
+void CBindReverseConverter::CreateReverseBindInfo(CBindInfo &destBindInfo)
+{
+  destBindInfo.Coders.Clear();
+  destBindInfo.BindPairs.Clear();
+  destBindInfo.InStreams.Clear();
+  destBindInfo.OutStreams.Clear();
+
+  int i;
+  for (i = _srcBindInfo.Coders.Size() - 1; i >= 0; i--)
+  {
+    const CCoderStreamsInfo &srcCoderInfo = _srcBindInfo.Coders[i];
+    CCoderStreamsInfo destCoderInfo;
+    destCoderInfo.NumInStreams = srcCoderInfo.NumOutStreams;
+    destCoderInfo.NumOutStreams = srcCoderInfo.NumInStreams;
+    destBindInfo.Coders.Add(destCoderInfo);
+  }
+  for (i = _srcBindInfo.BindPairs.Size() - 1; i >= 0; i--)
+  {
+    const CBindPair &srcBindPair = _srcBindInfo.BindPairs[i];
+    CBindPair destBindPair;
+    destBindPair.InIndex = _srcOutToDestInMap[srcBindPair.OutIndex];
+    destBindPair.OutIndex = _srcInToDestOutMap[srcBindPair.InIndex];
+    destBindInfo.BindPairs.Add(destBindPair);
+  }
+  for (i = 0; i < _srcBindInfo.InStreams.Size(); i++)
+    destBindInfo.OutStreams.Add(_srcInToDestOutMap[_srcBindInfo.InStreams[i]]);
+  for (i = 0; i < _srcBindInfo.OutStreams.Size(); i++)
+    destBindInfo.InStreams.Add(_srcOutToDestInMap[_srcBindInfo.OutStreams[i]]);
+}
+
+CCoderInfo2::CCoderInfo2(UInt32 numInStreams, UInt32 numOutStreams): 
+    NumInStreams(numInStreams),
+    NumOutStreams(numOutStreams)
+{
+  InSizes.Reserve(NumInStreams);
+  InSizePointers.Reserve(NumInStreams);
+  OutSizePointers.Reserve(NumOutStreams);
+  OutSizePointers.Reserve(NumOutStreams);
+}
+
+static void SetSizes(const UInt64 **srcSizes, CRecordVector<UInt64> &sizes, 
+    CRecordVector<const UInt64 *> &sizePointers, UInt32 numItems)
+{
+  sizes.Clear();
+  sizePointers.Clear();
+  for(UInt32 i = 0; i < numItems; i++)
+  {
+    if (srcSizes == 0 || srcSizes[i] == NULL)
+    {
+      sizes.Add(0);
+      sizePointers.Add(NULL);
+    }
+    else
+    {
+      sizes.Add(*srcSizes[i]);
+      sizePointers.Add(&sizes.Back());
+    }
+  }
+}
+
+void CCoderInfo2::SetCoderInfo(const UInt64 **inSizes,
+      const UInt64 **outSizes)
+{
+  SetSizes(inSizes, InSizes, InSizePointers, NumInStreams);
+  SetSizes(outSizes, OutSizes, OutSizePointers, NumOutStreams);
+}
+
+}  
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/misc/libphysfs/lzma/CPP/7zip/Archive/Common/CoderMixer2.h	Mon Apr 10 12:06:43 2017 -0400
@@ -0,0 +1,174 @@
+// CoderMixer2.h
+
+#ifndef __CODER_MIXER2_H
+#define __CODER_MIXER2_H
+
+#include "../../../Common/MyVector.h"
+#include "../../../Common/Types.h"
+#include "../../../Common/MyCom.h"
+#include "../../ICoder.h"
+
+namespace NCoderMixer {
+
+struct CBindPair
+{
+  UInt32 InIndex;
+  UInt32 OutIndex;
+};
+
+struct CCoderStreamsInfo
+{
+  UInt32 NumInStreams;
+  UInt32 NumOutStreams;
+};
+
+struct CBindInfo
+{
+  CRecordVector<CCoderStreamsInfo> Coders;
+  CRecordVector<CBindPair> BindPairs;
+  CRecordVector<UInt32> InStreams;
+  CRecordVector<UInt32> OutStreams;
+
+  void Clear()
+  {
+    Coders.Clear();
+    BindPairs.Clear();
+    InStreams.Clear();
+    OutStreams.Clear();
+  }
+
+  /*
+  UInt32 GetCoderStartOutStream(UInt32 coderIndex) const
+  {
+    UInt32 numOutStreams = 0;
+    for (UInt32 i = 0; i < coderIndex; i++)
+      numOutStreams += Coders[i].NumOutStreams;
+    return numOutStreams;
+  }
+  */
+
+
+  void GetNumStreams(UInt32 &numInStreams, UInt32 &numOutStreams) const
+  {
+    numInStreams = 0;
+    numOutStreams = 0;
+    for (int i = 0; i < Coders.Size(); i++)
+    {
+      const CCoderStreamsInfo &coderStreamsInfo = Coders[i];
+      numInStreams += coderStreamsInfo.NumInStreams;
+      numOutStreams += coderStreamsInfo.NumOutStreams;
+    }
+  }
+
+  int FindBinderForInStream(UInt32 inStream) const
+  {
+    for (int i = 0; i < BindPairs.Size(); i++)
+      if (BindPairs[i].InIndex == inStream)
+        return i;
+    return -1;
+  }
+  int FindBinderForOutStream(UInt32 outStream) const
+  {
+    for (int i = 0; i < BindPairs.Size(); i++)
+      if (BindPairs[i].OutIndex == outStream)
+        return i;
+    return -1;
+  }
+
+  UInt32 GetCoderInStreamIndex(UInt32 coderIndex) const
+  {
+    UInt32 streamIndex = 0;
+    for (UInt32 i = 0; i < coderIndex; i++)
+      streamIndex += Coders[i].NumInStreams;
+    return streamIndex;
+  }
+
+  UInt32 GetCoderOutStreamIndex(UInt32 coderIndex) const
+  {
+    UInt32 streamIndex = 0;
+    for (UInt32 i = 0; i < coderIndex; i++)
+      streamIndex += Coders[i].NumOutStreams;
+    return streamIndex;
+  }
+
+
+  void FindInStream(UInt32 streamIndex, UInt32 &coderIndex, 
+      UInt32 &coderStreamIndex) const
+  {
+    for (coderIndex = 0; coderIndex < (UInt32)Coders.Size(); coderIndex++)
+    {
+      UInt32 curSize = Coders[coderIndex].NumInStreams;
+      if (streamIndex < curSize)
+      {
+        coderStreamIndex = streamIndex;
+        return;
+      }
+      streamIndex -= curSize;
+    }
+    throw 1;
+  }
+  void FindOutStream(UInt32 streamIndex, UInt32 &coderIndex, 
+      UInt32 &coderStreamIndex) const
+  {
+    for (coderIndex = 0; coderIndex < (UInt32)Coders.Size(); coderIndex++)
+    {
+      UInt32 curSize = Coders[coderIndex].NumOutStreams;
+      if (streamIndex < curSize)
+      {
+        coderStreamIndex = streamIndex;
+        return;
+      }
+      streamIndex -= curSize;
+    }
+    throw 1;
+  }
+};
+
+class CBindReverseConverter
+{
+  UInt32 _numSrcOutStreams;
+  NCoderMixer::CBindInfo _srcBindInfo;
+  CRecordVector<UInt32> _srcInToDestOutMap;
+  CRecordVector<UInt32> _srcOutToDestInMap;
+  CRecordVector<UInt32> _destInToSrcOutMap;
+public:
+  UInt32 NumSrcInStreams;
+  CRecordVector<UInt32> DestOutToSrcInMap;
+
+  CBindReverseConverter(const NCoderMixer::CBindInfo &srcBindInfo);
+  void CreateReverseBindInfo(NCoderMixer::CBindInfo &destBindInfo);
+};
+
+struct CCoderInfo2
+{
+  CMyComPtr<ICompressCoder> Coder;
+  CMyComPtr<ICompressCoder2> Coder2;
+  UInt32 NumInStreams;
+  UInt32 NumOutStreams;
+
+  CRecordVector<UInt64> InSizes;
+  CRecordVector<UInt64> OutSizes;
+  CRecordVector<const UInt64 *> InSizePointers;
+  CRecordVector<const UInt64 *> OutSizePointers;
+
+  CCoderInfo2(UInt32 numInStreams, UInt32 numOutStreams);
+  void SetCoderInfo(const UInt64 **inSizes, const UInt64 **outSizes);
+
+  HRESULT QueryInterface(REFGUID iid, void** pp) const
+  {
+    IUnknown *p = Coder ? (IUnknown *)Coder : (IUnknown *)Coder2;
+    return p->QueryInterface(iid, pp);
+  }
+};
+
+class CCoderMixer2
+{
+public:
+  virtual HRESULT SetBindInfo(const CBindInfo &bindInfo) = 0;
+  virtual void ReInit() = 0;
+  virtual void SetCoderInfo(UInt32 coderIndex, const UInt64 **inSizes, const UInt64 **outSizes) = 0;
+};
+
+}
+#endif
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/misc/libphysfs/lzma/CPP/7zip/Archive/Common/CoderMixer2MT.cpp	Mon Apr 10 12:06:43 2017 -0400
@@ -0,0 +1,228 @@
+// CoderMixer2MT.cpp
+
+#include "StdAfx.h"
+
+#include "CoderMixer2MT.h"
+
+namespace NCoderMixer {
+
+CCoder2::CCoder2(UInt32 numInStreams, UInt32 numOutStreams): 
+    CCoderInfo2(numInStreams, numOutStreams)
+{
+  InStreams.Reserve(NumInStreams);
+  InStreamPointers.Reserve(NumInStreams);
+  OutStreams.Reserve(NumOutStreams);
+  OutStreamPointers.Reserve(NumOutStreams);
+}
+
+void CCoder2::Execute() { Code(NULL); }
+
+void CCoder2::Code(ICompressProgressInfo *progress)
+{
+  InStreamPointers.Clear();
+  OutStreamPointers.Clear();
+  UInt32 i;
+  for (i = 0; i < NumInStreams; i++)
+  {
+    if (InSizePointers[i] != NULL)
+      InSizePointers[i] = &InSizes[i];
+    InStreamPointers.Add((ISequentialInStream *)InStreams[i]);
+  }
+  for (i = 0; i < NumOutStreams; i++)
+  {
+    if (OutSizePointers[i] != NULL)
+      OutSizePointers[i] = &OutSizes[i];
+    OutStreamPointers.Add((ISequentialOutStream *)OutStreams[i]);
+  }
+  if (Coder)
+    Result = Coder->Code(InStreamPointers[0], OutStreamPointers[0], 
+        InSizePointers[0], OutSizePointers[0], progress);
+  else
+    Result = Coder2->Code(&InStreamPointers.Front(), &InSizePointers.Front(), NumInStreams,
+      &OutStreamPointers.Front(), &OutSizePointers.Front(), NumOutStreams, progress);
+  {
+    int i;
+    for (i = 0; i < InStreams.Size(); i++)
+      InStreams[i].Release();
+    for (i = 0; i < OutStreams.Size(); i++)
+      OutStreams[i].Release();
+  }
+}
+
+static void SetSizes(const UInt64 **srcSizes, CRecordVector<UInt64> &sizes, 
+    CRecordVector<const UInt64 *> &sizePointers, UInt32 numItems)
+{
+  sizes.Clear();
+  sizePointers.Clear();
+  for(UInt32 i = 0; i < numItems; i++)
+  {
+    if (srcSizes == 0 || srcSizes[i] == NULL)
+    {
+      sizes.Add(0);
+      sizePointers.Add(NULL);
+    }
+    else
+    {
+      sizes.Add(*srcSizes[i]);
+      sizePointers.Add(&sizes.Back());
+    }
+  }
+}
+
+
+void CCoder2::SetCoderInfo(const UInt64 **inSizes, const UInt64 **outSizes)
+{
+  SetSizes(inSizes, InSizes, InSizePointers, NumInStreams);
+  SetSizes(outSizes, OutSizes, OutSizePointers, NumOutStreams);
+}
+
+//////////////////////////////////////
+// CCoderMixer2MT
+
+HRESULT CCoderMixer2MT::SetBindInfo(const CBindInfo &bindInfo)
+{  
+  _bindInfo = bindInfo; 
+  _streamBinders.Clear();
+  for(int i = 0; i < _bindInfo.BindPairs.Size(); i++)
+  {
+    _streamBinders.Add(CStreamBinder());
+    RINOK(_streamBinders.Back().CreateEvents());
+  }
+  return S_OK;
+}
+
+void CCoderMixer2MT::AddCoderCommon()
+{
+  const CCoderStreamsInfo &c = _bindInfo.Coders[_coders.Size()];
+  CCoder2 threadCoderInfo(c.NumInStreams, c.NumOutStreams);
+  _coders.Add(threadCoderInfo);
+}
+
+void CCoderMixer2MT::AddCoder(ICompressCoder *coder)
+{
+  AddCoderCommon();
+  _coders.Back().Coder = coder;
+}
+
+void CCoderMixer2MT::AddCoder2(ICompressCoder2 *coder)
+{
+  AddCoderCommon();
+  _coders.Back().Coder2 = coder;
+}
+
+
+void CCoderMixer2MT::ReInit()
+{
+  for(int i = 0; i < _streamBinders.Size(); i++)
+    _streamBinders[i].ReInit();
+}
+
+
+HRESULT CCoderMixer2MT::Init(ISequentialInStream **inStreams, ISequentialOutStream **outStreams) 
+{
+  /*
+  if (_coders.Size() != _bindInfo.Coders.Size())
+    throw 0;
+  */
+  int i;
+  for(i = 0; i < _coders.Size(); i++)
+  {
+    CCoder2 &coderInfo = _coders[i];
+    const CCoderStreamsInfo &coderStreamsInfo = _bindInfo.Coders[i];
+    coderInfo.InStreams.Clear();
+    UInt32 j;
+    for(j = 0; j < coderStreamsInfo.NumInStreams; j++)
+      coderInfo.InStreams.Add(NULL);
+    coderInfo.OutStreams.Clear();
+    for(j = 0; j < coderStreamsInfo.NumOutStreams; j++)
+      coderInfo.OutStreams.Add(NULL);
+  }
+
+  for(i = 0; i < _bindInfo.BindPairs.Size(); i++)
+  {
+    const CBindPair &bindPair = _bindInfo.BindPairs[i];
+    UInt32 inCoderIndex, inCoderStreamIndex;
+    UInt32 outCoderIndex, outCoderStreamIndex;
+    _bindInfo.FindInStream(bindPair.InIndex, inCoderIndex, inCoderStreamIndex);
+    _bindInfo.FindOutStream(bindPair.OutIndex, outCoderIndex, outCoderStreamIndex);
+
+    _streamBinders[i].CreateStreams(
+        &_coders[inCoderIndex].InStreams[inCoderStreamIndex],
+        &_coders[outCoderIndex].OutStreams[outCoderStreamIndex]);
+  }
+
+  for(i = 0; i < _bindInfo.InStreams.Size(); i++)
+  {
+    UInt32 inCoderIndex, inCoderStreamIndex;
+    _bindInfo.FindInStream(_bindInfo.InStreams[i], inCoderIndex, inCoderStreamIndex);
+    _coders[inCoderIndex].InStreams[inCoderStreamIndex] = inStreams[i];
+  }
+  
+  for(i = 0; i < _bindInfo.OutStreams.Size(); i++)
+  {
+    UInt32 outCoderIndex, outCoderStreamIndex;
+    _bindInfo.FindOutStream(_bindInfo.OutStreams[i], outCoderIndex, outCoderStreamIndex);
+    _coders[outCoderIndex].OutStreams[outCoderStreamIndex] = outStreams[i];
+  }
+  return S_OK;
+}
+
+HRESULT CCoderMixer2MT::ReturnIfError(HRESULT code)
+{
+  for (int i = 0; i < _coders.Size(); i++)
+    if (_coders[i].Result == code)
+      return code;
+  return S_OK;
+}
+
+STDMETHODIMP CCoderMixer2MT::Code(ISequentialInStream **inStreams,
+      const UInt64 ** /* inSizes */, 
+      UInt32 numInStreams,
+      ISequentialOutStream **outStreams, 
+      const UInt64 ** /* outSizes */,
+      UInt32 numOutStreams,
+      ICompressProgressInfo *progress)
+{
+  if (numInStreams != (UInt32)_bindInfo.InStreams.Size() ||
+      numOutStreams != (UInt32)_bindInfo.OutStreams.Size())
+    return E_INVALIDARG;
+
+  Init(inStreams, outStreams);
+
+  int i;
+  for (i = 0; i < _coders.Size(); i++)
+    if (i != _progressCoderIndex)
+    {
+      RINOK(_coders[i].Create());
+    }
+
+  for (i = 0; i < _coders.Size(); i++)
+    if (i != _progressCoderIndex)
+      _coders[i].Start();
+
+  _coders[_progressCoderIndex].Code(progress);
+
+  for (i = 0; i < _coders.Size(); i++)
+    if (i != _progressCoderIndex)
+      _coders[i].WaitFinish();
+
+  RINOK(ReturnIfError(E_ABORT));
+  RINOK(ReturnIfError(E_OUTOFMEMORY));
+  RINOK(ReturnIfError(S_FALSE));
+
+  for (i = 0; i < _coders.Size(); i++)
+  {
+    HRESULT result = _coders[i].Result;
+    if (result != S_OK && result != E_FAIL)
+      return result;
+  }
+  for (i = 0; i < _coders.Size(); i++)
+  {
+    HRESULT result = _coders[i].Result;
+    if (result != S_OK)
+      return result;
+  }
+  return S_OK;
+}
+
+}  
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/misc/libphysfs/lzma/CPP/7zip/Archive/Common/CoderMixer2MT.h	Mon Apr 10 12:06:43 2017 -0400
@@ -0,0 +1,80 @@
+// CoderMixer2MT.h
+
+#ifndef __CODER_MIXER2_MT_H
+#define __CODER_MIXER2_MT_H
+
+#include "CoderMixer2.h"
+#include "../../../Common/MyCom.h"
+#include "../../Common/StreamBinder.h"
+#include "../../Common/VirtThread.h"
+
+namespace NCoderMixer {
+
+struct CCoder2: public CCoderInfo2, public CVirtThread
+{
+  HRESULT Result;
+  CObjectVector< CMyComPtr<ISequentialInStream> > InStreams;
+  CObjectVector< CMyComPtr<ISequentialOutStream> > OutStreams;
+  CRecordVector<ISequentialInStream*> InStreamPointers;
+  CRecordVector<ISequentialOutStream*> OutStreamPointers;
+
+  CCoder2(UInt32 numInStreams, UInt32 numOutStreams);
+  void SetCoderInfo(const UInt64 **inSizes, const UInt64 **outSizes);
+  virtual void Execute();
+  void Code(ICompressProgressInfo *progress);
+};
+
+
+/*
+  SetBindInfo()
+  for each coder
+    AddCoder[2]()
+  SetProgressIndex(UInt32 coderIndex);
+ 
+  for each file
+  {
+    ReInit()
+    for each coder
+      SetCoderInfo  
+    Code
+  }
+*/
+
+class CCoderMixer2MT:
+  public ICompressCoder2,
+  public CCoderMixer2,
+  public CMyUnknownImp
+{
+  CBindInfo _bindInfo;
+  CObjectVector<CStreamBinder> _streamBinders;
+  int _progressCoderIndex;
+
+  void AddCoderCommon();
+  HRESULT Init(ISequentialInStream **inStreams, ISequentialOutStream **outStreams);
+  HRESULT ReturnIfError(HRESULT code);
+public:
+  CObjectVector<CCoder2> _coders;
+  MY_UNKNOWN_IMP
+
+  STDMETHOD(Code)(ISequentialInStream **inStreams,
+      const UInt64 **inSizes, 
+      UInt32 numInStreams,
+      ISequentialOutStream **outStreams, 
+      const UInt64 **outSizes,
+      UInt32 numOutStreams,
+      ICompressProgressInfo *progress);
+
+  HRESULT SetBindInfo(const CBindInfo &bindInfo);
+  void AddCoder(ICompressCoder *coder);
+  void AddCoder2(ICompressCoder2 *coder);
+  void SetProgressCoderIndex(int coderIndex) {  _progressCoderIndex = coderIndex; }
+
+  void ReInit();
+  void SetCoderInfo(UInt32 coderIndex, const UInt64 **inSizes, const UInt64 **outSizes)
+    {  _coders[coderIndex].SetCoderInfo(inSizes, outSizes); }
+  UInt64 GetWriteProcessedSize(UInt32 binderIndex) const
+    {  return _streamBinders[binderIndex].ProcessedSize; }
+};
+
+}
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/misc/libphysfs/lzma/CPP/7zip/Archive/Common/CrossThreadProgress.cpp	Mon Apr 10 12:06:43 2017 -0400
@@ -0,0 +1,15 @@
+// CrossThreadProgress.cpp
+
+#include "StdAfx.h"
+
+#include "CrossThreadProgress.h"
+
+STDMETHODIMP CCrossThreadProgress::SetRatioInfo(const UInt64 *inSize, const UInt64 *outSize)
+{
+  InSize = inSize;
+  OutSize = outSize;
+  ProgressEvent.Set();
+  WaitEvent.Lock();
+  return Result;
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/misc/libphysfs/lzma/CPP/7zip/Archive/Common/CrossThreadProgress.h	Mon Apr 10 12:06:43 2017 -0400
@@ -0,0 +1,37 @@
+// CrossThreadProgress.h
+
+#ifndef __CROSSTHREADPROGRESS_H
+#define __CROSSTHREADPROGRESS_H
+
+#include "../../ICoder.h"
+#include "../../../Windows/Synchronization.h"
+#include "../../../Common/MyCom.h"
+
+class CCrossThreadProgress: 
+  public ICompressProgressInfo,
+  public CMyUnknownImp
+{
+public:
+  const UInt64 *InSize;
+  const UInt64 *OutSize;
+  HRESULT Result;
+  NWindows::NSynchronization::CAutoResetEvent ProgressEvent;
+  NWindows::NSynchronization::CAutoResetEvent WaitEvent;
+
+  HRes Create()
+  {
+    RINOK(ProgressEvent.CreateIfNotCreated());
+    return WaitEvent.CreateIfNotCreated();
+  }
+  void Init()
+  {
+    ProgressEvent.Reset();
+    WaitEvent.Reset();
+  }
+
+  MY_UNKNOWN_IMP
+
+  STDMETHOD(SetRatioInfo)(const UInt64 *inSize, const UInt64 *outSize);
+};
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/misc/libphysfs/lzma/CPP/7zip/Archive/Common/DummyOutStream.cpp	Mon Apr 10 12:06:43 2017 -0400
@@ -0,0 +1,22 @@
+// DummyOutStream.cpp
+
+#include "StdAfx.h"
+
+#include "DummyOutStream.h"
+
+STDMETHODIMP CDummyOutStream::Write(const void *data,  UInt32 size, UInt32 *processedSize)
+{
+  UInt32 realProcessedSize;
+  HRESULT result;
+  if(!_stream)
+  {
+    realProcessedSize = size;
+    result = S_OK;
+  }
+  else
+    result = _stream->Write(data, size, &realProcessedSize);
+  _size += realProcessedSize;
+  if(processedSize != NULL)
+    *processedSize = realProcessedSize;
+  return result;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/misc/libphysfs/lzma/CPP/7zip/Archive/Common/DummyOutStream.h	Mon Apr 10 12:06:43 2017 -0400
@@ -0,0 +1,23 @@
+// DummyOutStream.h
+
+#ifndef __DUMMYOUTSTREAM_H
+#define __DUMMYOUTSTREAM_H
+
+#include "../../IStream.h"
+#include "Common/MyCom.h"
+
+class CDummyOutStream: 
+  public ISequentialOutStream,
+  public CMyUnknownImp
+{
+  CMyComPtr<ISequentialOutStream> _stream;
+  UInt64 _size;
+public:
+  void SetStream(ISequentialOutStream *outStream) { _stream = outStream; }
+  void Init() { _size = 0; }
+  MY_UNKNOWN_IMP
+  STDMETHOD(Write)(const void *data, UInt32 size, UInt32 *processedSize);
+  UInt64 GetSize() const { return _size; }
+};
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/misc/libphysfs/lzma/CPP/7zip/Archive/Common/HandlerOut.cpp	Mon Apr 10 12:06:43 2017 -0400
@@ -0,0 +1,618 @@
+// HandlerOutCommon.cpp
+
+#include "StdAfx.h"
+
+#include "HandlerOut.h"
+#include "../../../Windows/PropVariant.h"
+#include "../../../Common/StringToInt.h"
+#include "../../ICoder.h"
+#include "../Common/ParseProperties.h"
+
+#ifdef COMPRESS_MT
+#include "../../../Windows/System.h"
+#endif
+
+using namespace NWindows;
+
+namespace NArchive {
+
+static const wchar_t *kCopyMethod = L"Copy";
+static const wchar_t *kLZMAMethodName = L"LZMA";
+static const wchar_t *kLZMA2MethodName = L"LZMA2";
+static const wchar_t *kBZip2MethodName = L"BZip2";
+static const wchar_t *kPpmdMethodName = L"PPMd";
+static const wchar_t *kDeflateMethodName = L"Deflate";
+static const wchar_t *kDeflate64MethodName = L"Deflate64";
+
+static const wchar_t *kLzmaMatchFinderX1 = L"HC4";
+static const wchar_t *kLzmaMatchFinderX5 = L"BT4";
+
+static const UInt32 kLzmaAlgoX1 = 0;
+static const UInt32 kLzmaAlgoX5 = 1;
+
+static const UInt32 kLzmaDicSizeX1 = 1 << 16;
+static const UInt32 kLzmaDicSizeX3 = 1 << 20;
+static const UInt32 kLzmaDicSizeX5 = 1 << 24;
+static const UInt32 kLzmaDicSizeX7 = 1 << 25;
+static const UInt32 kLzmaDicSizeX9 = 1 << 26;
+
+static const UInt32 kLzmaFastBytesX1 = 32;
+static const UInt32 kLzmaFastBytesX7 = 64;
+
+static const UInt32 kPpmdMemSizeX1 = (1 << 22);
+static const UInt32 kPpmdMemSizeX5 = (1 << 24);
+static const UInt32 kPpmdMemSizeX7 = (1 << 26);
+static const UInt32 kPpmdMemSizeX9 = (192 << 20);
+
+static const UInt32 kPpmdOrderX1 = 4;
+static const UInt32 kPpmdOrderX5 = 6;
+static const UInt32 kPpmdOrderX7 = 16;
+static const UInt32 kPpmdOrderX9 = 32;
+
+static const UInt32 kDeflateAlgoX1 = 0;
+static const UInt32 kDeflateAlgoX5 = 1;
+
+static const UInt32 kDeflateFastBytesX1 = 32;
+static const UInt32 kDeflateFastBytesX7 = 64;
+static const UInt32 kDeflateFastBytesX9 = 128;
+
+static const UInt32 kDeflatePassesX1 = 1;
+static const UInt32 kDeflatePassesX7 = 3;
+static const UInt32 kDeflatePassesX9 = 10;
+
+static const UInt32 kBZip2NumPassesX1 = 1;
+static const UInt32 kBZip2NumPassesX7 = 2;
+static const UInt32 kBZip2NumPassesX9 = 7;
+
+static const UInt32 kBZip2DicSizeX1 = 100000;
+static const UInt32 kBZip2DicSizeX3 = 500000;
+static const UInt32 kBZip2DicSizeX5 = 900000;
+
+static const wchar_t *kDefaultMethodName = kLZMAMethodName;
+
+static const wchar_t *kLzmaMatchFinderForHeaders = L"BT2";
+static const UInt32 kDictionaryForHeaders = 1 << 20;
+static const UInt32 kNumFastBytesForHeaders = 273;
+static const UInt32 kAlgorithmForHeaders = kLzmaAlgoX5;
+
+static bool AreEqual(const UString &methodName, const wchar_t *s)
+  { return (methodName.CompareNoCase(s) == 0); }
+
+static inline bool IsLZMAMethod(const UString &methodName)
+{ 
+  return 
+    AreEqual(methodName, kLZMAMethodName) || 
+    AreEqual(methodName, kLZMA2MethodName); 
+}
+
+static inline bool IsBZip2Method(const UString &methodName)
+  { return AreEqual(methodName, kBZip2MethodName); }
+
+static inline bool IsPpmdMethod(const UString &methodName)
+  { return AreEqual(methodName, kPpmdMethodName); }
+
+static inline bool IsDeflateMethod(const UString &methodName)
+{ 
+  return 
+    AreEqual(methodName, kDeflateMethodName) || 
+    AreEqual(methodName, kDeflate64MethodName); 
+}
+
+struct CNameToPropID
+{
+  PROPID PropID;
+  VARTYPE VarType;
+  const wchar_t *Name;
+};
+
+CNameToPropID g_NameToPropID[] = 
+{
+  { NCoderPropID::kOrder, VT_UI4, L"O" },
+  { NCoderPropID::kPosStateBits, VT_UI4, L"PB" },
+  { NCoderPropID::kLitContextBits, VT_UI4, L"LC" },
+  { NCoderPropID::kLitPosBits, VT_UI4, L"LP" },
+  { NCoderPropID::kEndMarker, VT_BOOL, L"eos" },
+
+  { NCoderPropID::kNumPasses, VT_UI4, L"Pass" },
+  { NCoderPropID::kNumFastBytes, VT_UI4, L"fb" },
+  { NCoderPropID::kMatchFinderCycles, VT_UI4, L"mc" },
+  { NCoderPropID::kAlgorithm, VT_UI4, L"a" },
+  { NCoderPropID::kMatchFinder, VT_BSTR, L"mf" },
+  { NCoderPropID::kNumThreads, VT_UI4, L"mt" }
+};
+
+static bool ConvertProperty(PROPVARIANT srcProp, VARTYPE varType, NCOM::CPropVariant &destProp)
+{
+  if (varType == srcProp.vt)
+  {
+    destProp = srcProp;
+    return true;
+  }
+  if (varType == VT_UI1)
+  {
+    if (srcProp.vt == VT_UI4)
+    {
+      UInt32 value = srcProp.ulVal;
+      if (value > 0xFF)
+        return false;
+      destProp = (Byte)value;
+      return true;
+    }
+  }
+  else if (varType == VT_BOOL)
+  {
+    bool res;
+    if (SetBoolProperty(res, srcProp) != S_OK)
+      return false;
+    destProp = res;
+    return true;
+  }
+  return false;
+}
+    
+static int FindPropIdFromStringName(const UString &name)
+{
+  for (int i = 0; i < sizeof(g_NameToPropID) / sizeof(g_NameToPropID[0]); i++)
+    if (name.CompareNoCase(g_NameToPropID[i].Name) == 0)
+      return i;
+  return -1;
+}
+
+static void SetOneMethodProp(COneMethodInfo &oneMethodInfo, PROPID propID, 
+    const NWindows::NCOM::CPropVariant &value)
+{
+  for (int j = 0; j < oneMethodInfo.Properties.Size(); j++)
+    if (oneMethodInfo.Properties[j].Id == propID)
+      return;
+  CProp property;
+  property.Id = propID;
+  property.Value = value;
+  oneMethodInfo.Properties.Add(property);
+}
+
+void COutHandler::SetCompressionMethod2(COneMethodInfo &oneMethodInfo
+    #ifdef COMPRESS_MT
+    , UInt32 numThreads
+    #endif
+    )
+{
+  UInt32 level = _level;
+  if (oneMethodInfo.MethodName.IsEmpty())
+    oneMethodInfo.MethodName = kDefaultMethodName;
+  
+  if (IsLZMAMethod(oneMethodInfo.MethodName))
+  {
+    UInt32 dicSize = 
+      (level >= 9 ? kLzmaDicSizeX9 : 
+      (level >= 7 ? kLzmaDicSizeX7 : 
+      (level >= 5 ? kLzmaDicSizeX5 : 
+      (level >= 3 ? kLzmaDicSizeX3 : 
+                    kLzmaDicSizeX1)))); 
+    
+    UInt32 algo = 
+      (level >= 5 ? kLzmaAlgoX5 : 
+                    kLzmaAlgoX1); 
+    
+    UInt32 fastBytes = 
+      (level >= 7 ? kLzmaFastBytesX7 : 
+                    kLzmaFastBytesX1); 
+    
+    const wchar_t *matchFinder = 
+      (level >= 5 ? kLzmaMatchFinderX5 : 
+                    kLzmaMatchFinderX1); 
+    
+    SetOneMethodProp(oneMethodInfo, NCoderPropID::kDictionarySize, dicSize);
+    SetOneMethodProp(oneMethodInfo, NCoderPropID::kAlgorithm, algo);
+    SetOneMethodProp(oneMethodInfo, NCoderPropID::kNumFastBytes, fastBytes);
+    SetOneMethodProp(oneMethodInfo, NCoderPropID::kMatchFinder, matchFinder);
+    #ifdef COMPRESS_MT
+    SetOneMethodProp(oneMethodInfo, NCoderPropID::kNumThreads, numThreads);
+    #endif
+  }
+  else if (IsDeflateMethod(oneMethodInfo.MethodName))
+  {
+    UInt32 fastBytes = 
+      (level >= 9 ? kDeflateFastBytesX9 : 
+      (level >= 7 ? kDeflateFastBytesX7 : 
+                    kDeflateFastBytesX1));
+    
+    UInt32 numPasses = 
+      (level >= 9 ? kDeflatePassesX9 :  
+      (level >= 7 ? kDeflatePassesX7 : 
+                    kDeflatePassesX1));
+    
+    UInt32 algo = 
+      (level >= 5 ? kDeflateAlgoX5 : 
+                    kDeflateAlgoX1); 
+    
+    SetOneMethodProp(oneMethodInfo, NCoderPropID::kAlgorithm, algo);
+    SetOneMethodProp(oneMethodInfo, NCoderPropID::kNumFastBytes, fastBytes);
+    SetOneMethodProp(oneMethodInfo, NCoderPropID::kNumPasses, numPasses);
+  }
+  else if (IsBZip2Method(oneMethodInfo.MethodName))
+  {
+    UInt32 numPasses = 
+      (level >= 9 ? kBZip2NumPassesX9 : 
+      (level >= 7 ? kBZip2NumPassesX7 :  
+                    kBZip2NumPassesX1));
+    
+    UInt32 dicSize = 
+      (level >= 5 ? kBZip2DicSizeX5 : 
+      (level >= 3 ? kBZip2DicSizeX3 : 
+                    kBZip2DicSizeX1));
+    
+    SetOneMethodProp(oneMethodInfo, NCoderPropID::kNumPasses, numPasses);
+    SetOneMethodProp(oneMethodInfo, NCoderPropID::kDictionarySize, dicSize);
+    #ifdef COMPRESS_MT
+    SetOneMethodProp(oneMethodInfo, NCoderPropID::kNumThreads, numThreads);
+    #endif
+  }
+  else if (IsPpmdMethod(oneMethodInfo.MethodName))
+  {
+    UInt32 useMemSize = 
+      (level >= 9 ? kPpmdMemSizeX9 : 
+      (level >= 7 ? kPpmdMemSizeX7 : 
+      (level >= 5 ? kPpmdMemSizeX5 : 
+                    kPpmdMemSizeX1)));
+    
+    UInt32 order = 
+      (level >= 9 ? kPpmdOrderX9 : 
+      (level >= 7 ? kPpmdOrderX7 : 
+      (level >= 5 ? kPpmdOrderX5 : 
+                    kPpmdOrderX1)));
+    
+    SetOneMethodProp(oneMethodInfo, NCoderPropID::kUsedMemorySize, useMemSize);
+    SetOneMethodProp(oneMethodInfo, NCoderPropID::kOrder, order);
+  }
+}
+
+static void SplitParams(const UString &srcString, UStringVector &subStrings)
+{
+  subStrings.Clear();
+  UString name;
+  int len = srcString.Length();
+  if (len == 0)
+    return;
+  for (int i = 0; i < len; i++)
+  {
+    wchar_t c = srcString[i];
+    if (c == L':')
+    {
+      subStrings.Add(name);
+      name.Empty();
+    }
+    else
+      name += c;
+  }
+  subStrings.Add(name);
+}
+
+static void SplitParam(const UString &param, UString &name, UString &value)
+{
+  int eqPos = param.Find(L'=');
+  if (eqPos >= 0)
+  {
+    name = param.Left(eqPos);
+    value = param.Mid(eqPos + 1);
+    return;
+  }
+  for(int i = 0; i < param.Length(); i++)
+  {
+    wchar_t c = param[i];
+    if (c >= L'0' && c <= L'9')
+    {
+      name = param.Left(i);
+      value = param.Mid(i);
+      return;
+    }
+  }
+  name = param;
+}
+
+HRESULT COutHandler::SetParam(COneMethodInfo &oneMethodInfo, const UString &name, const UString &value)
+{
+  CProp property;
+  if (
+    name.CompareNoCase(L"D") == 0 || 
+    name.CompareNoCase(L"MEM") == 0)
+  {
+    UInt32 dicSize;
+    RINOK(ParsePropDictionaryValue(value, dicSize));
+    if (name.CompareNoCase(L"D") == 0)
+      property.Id = NCoderPropID::kDictionarySize;
+    else
+      property.Id = NCoderPropID::kUsedMemorySize;
+    property.Value = dicSize;
+    oneMethodInfo.Properties.Add(property);
+  }
+  else
+  {
+    int index = FindPropIdFromStringName(name);
+    if (index < 0)
+      return E_INVALIDARG;
+    
+    const CNameToPropID &nameToPropID = g_NameToPropID[index];
+    property.Id = nameToPropID.PropID;
+    
+    NCOM::CPropVariant propValue;
+    
+    if (nameToPropID.VarType == VT_BSTR)
+      propValue = value;
+    else if (nameToPropID.VarType == VT_BOOL)
+    {
+      bool res;
+      if (!StringToBool(value, res))
+        return E_INVALIDARG;
+      propValue = res;
+    }
+    else
+    {
+      UInt32 number;
+      if (ParseStringToUInt32(value, number) == value.Length())
+        propValue = number;
+      else
+        propValue = value;
+    }
+    
+    if (!ConvertProperty(propValue, nameToPropID.VarType, property.Value))
+      return E_INVALIDARG;
+    
+    oneMethodInfo.Properties.Add(property);
+  }
+  return S_OK;
+}
+
+HRESULT COutHandler::SetParams(COneMethodInfo &oneMethodInfo, const UString &srcString)
+{
+  UStringVector params;
+  SplitParams(srcString, params);
+  if (params.Size() > 0)
+    oneMethodInfo.MethodName = params[0];
+  for (int i = 1; i < params.Size(); i++)
+  {
+    const UString &param = params[i];
+    UString name, value;
+    SplitParam(param, name, value);
+    RINOK(SetParam(oneMethodInfo, name, value));
+  }
+  return S_OK;
+}
+
+HRESULT COutHandler::SetSolidSettings(const UString &s)
+{
+  bool res;
+  if (StringToBool(s, res))
+  {
+    if (res)
+      InitSolid();
+    else
+      _numSolidFiles = 1;
+    return S_OK;
+  }
+  UString s2 = s;
+  s2.MakeUpper();
+  for (int i = 0; i < s2.Length();)
+  {
+    const wchar_t *start = ((const wchar_t *)s2) + i;
+    const wchar_t *end;
+    UInt64 v = ConvertStringToUInt64(start, &end);
+    if (start == end)
+    {
+      if (s2[i++] != 'E')
+        return E_INVALIDARG;
+      _solidExtension = true;
+      continue;
+    }
+    i += (int)(end - start);
+    if (i == s2.Length())
+      return E_INVALIDARG;
+    wchar_t c = s2[i++];
+    switch(c)
+    {
+      case 'F':
+        if (v < 1)
+          v = 1;
+        _numSolidFiles = v;
+        break;
+      case 'B':
+        _numSolidBytes = v;
+        _numSolidBytesDefined = true;
+        break;
+      case 'K':
+        _numSolidBytes = (v << 10);
+        _numSolidBytesDefined = true;
+        break;
+      case 'M':
+        _numSolidBytes = (v << 20);
+        _numSolidBytesDefined = true;
+        break;
+      case 'G':
+        _numSolidBytes = (v << 30);
+        _numSolidBytesDefined = true;
+        break;
+      default:
+        return E_INVALIDARG;
+    }
+  }
+  return S_OK;
+}
+
+HRESULT COutHandler::SetSolidSettings(const PROPVARIANT &value)
+{
+  switch(value.vt)
+  {
+    case VT_EMPTY:
+      InitSolid();
+      return S_OK;
+    case VT_BSTR:
+      return SetSolidSettings(value.bstrVal);
+    default:
+      return E_INVALIDARG;
+  }
+}
+
+void COutHandler::Init()
+{
+  _removeSfxBlock = false;
+  _compressHeaders = true;
+  _encryptHeaders = false;
+  
+  WriteModified = true;
+  WriteCreated = false;
+  WriteAccessed = false;
+  
+  #ifdef COMPRESS_MT
+  _numThreads = NWindows::NSystem::GetNumberOfProcessors();
+  #endif
+  
+  _level = 5;
+  _autoFilter = true;
+  _volumeMode = false;
+  _crcSize = 4;
+  InitSolid();
+}
+
+void COutHandler::BeforeSetProperty()
+{
+  Init();
+  #ifdef COMPRESS_MT
+  numProcessors = NSystem::GetNumberOfProcessors();
+  #endif
+
+  mainDicSize = 0xFFFFFFFF;
+  mainDicMethodIndex = 0xFFFFFFFF;
+  minNumber = 0;
+  _crcSize = 4;
+}
+
+HRESULT COutHandler::SetProperty(const wchar_t *nameSpec, const PROPVARIANT &value)
+{
+  UString name = nameSpec;
+  name.MakeUpper();
+  if (name.IsEmpty())
+    return E_INVALIDARG;
+  
+  if (name[0] == 'X')
+  {
+    name.Delete(0);
+    _level = 9;
+    return ParsePropValue(name, value, _level);
+  }
+  
+  if (name[0] == L'S')
+  {
+    name.Delete(0);
+    if (name.IsEmpty())
+      return SetSolidSettings(value);
+    if (value.vt != VT_EMPTY)
+      return E_INVALIDARG;
+    return SetSolidSettings(name);
+  }
+  
+  if (name == L"CRC")
+  {
+    _crcSize = 4;
+    name.Delete(0, 3);
+    return ParsePropValue(name, value, _crcSize);
+  }
+  
+  UInt32 number;
+  int index = ParseStringToUInt32(name, number);
+  UString realName = name.Mid(index);
+  if (index == 0)
+  {
+    if(name.Left(2).CompareNoCase(L"MT") == 0)
+    {
+      #ifdef COMPRESS_MT
+      RINOK(ParseMtProp(name.Mid(2), value, numProcessors, _numThreads));
+      #endif
+      return S_OK;
+    }
+    if (name.CompareNoCase(L"RSFX") == 0)
+      return SetBoolProperty(_removeSfxBlock, value);
+    if (name.CompareNoCase(L"F") == 0)
+      return SetBoolProperty(_autoFilter, value);
+    if (name.CompareNoCase(L"HC") == 0)
+      return SetBoolProperty(_compressHeaders, value);
+    if (name.CompareNoCase(L"HCF") == 0)
+    {
+      bool compressHeadersFull = true;
+      RINOK(SetBoolProperty(compressHeadersFull, value));
+      if (!compressHeadersFull)
+        return E_INVALIDARG;
+      return S_OK;
+    }
+    if (name.CompareNoCase(L"HE") == 0)
+      return SetBoolProperty(_encryptHeaders, value);
+    if (name.CompareNoCase(L"TM") == 0)
+      return SetBoolProperty(WriteModified, value);
+    if (name.CompareNoCase(L"TC") == 0)
+      return SetBoolProperty(WriteCreated, value);
+    if (name.CompareNoCase(L"TA") == 0)
+      return SetBoolProperty(WriteAccessed, value);
+    if (name.CompareNoCase(L"V") == 0)
+      return SetBoolProperty(_volumeMode, value);
+    number = 0;
+  }
+  if (number > 10000)
+    return E_FAIL;
+  if (number < minNumber)
+    return E_INVALIDARG;
+  number -= minNumber;
+  for(int j = _methods.Size(); j <= (int)number; j++)
+  {
+    COneMethodInfo oneMethodInfo;
+    _methods.Add(oneMethodInfo);
+  }
+  
+  COneMethodInfo &oneMethodInfo = _methods[number];
+  
+  if (realName.Length() == 0)
+  {
+    if (value.vt != VT_BSTR)
+      return E_INVALIDARG;
+    
+    RINOK(SetParams(oneMethodInfo, value.bstrVal));
+  }
+  else
+  {
+    CProp property;
+    if (realName.Left(1).CompareNoCase(L"D") == 0)
+    {
+      UInt32 dicSize;
+      RINOK(ParsePropDictionaryValue(realName.Mid(1), value, dicSize));
+      property.Id = NCoderPropID::kDictionarySize;
+      property.Value = dicSize;
+      oneMethodInfo.Properties.Add(property);
+      if (number <= mainDicMethodIndex)
+        mainDicSize = dicSize;
+    }
+    else if (realName.Left(3).CompareNoCase(L"MEM") == 0)
+    {
+      UInt32 dicSize;
+      RINOK(ParsePropDictionaryValue(realName.Mid(3), value, dicSize));
+      property.Id = NCoderPropID::kUsedMemorySize;
+      property.Value = dicSize;
+      oneMethodInfo.Properties.Add(property);
+      if (number <= mainDicMethodIndex)
+        mainDicSize = dicSize;
+    }
+    else
+    {
+      int index = FindPropIdFromStringName(realName);
+      if (index < 0)
+        return E_INVALIDARG;
+      
+      const CNameToPropID &nameToPropID = g_NameToPropID[index];
+      property.Id = nameToPropID.PropID;
+      
+      if (!ConvertProperty(value, nameToPropID.VarType, property.Value))
+        return E_INVALIDARG;
+      
+      oneMethodInfo.Properties.Add(property);
+    }
+  }
+  return S_OK;
+}  
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/misc/libphysfs/lzma/CPP/7zip/Archive/Common/HandlerOut.h	Mon Apr 10 12:06:43 2017 -0400
@@ -0,0 +1,86 @@
+// HandlerOut.h
+
+#ifndef __HANDLER_OUT_H
+#define __HANDLER_OUT_H
+
+#include "../../Common/MethodProps.h"
+#include "../../Common/CreateCoder.h"
+
+namespace NArchive {
+
+struct COneMethodInfo
+{
+  CObjectVector<CProp> Properties;
+  UString MethodName;
+};
+
+class COutHandler
+{
+public:
+  HRESULT SetProperty(const wchar_t *name, const PROPVARIANT &value);
+  
+  HRESULT SetSolidSettings(const UString &s);
+  HRESULT SetSolidSettings(const PROPVARIANT &value);
+
+  #ifdef COMPRESS_MT
+  UInt32 _numThreads;
+  #endif
+
+  UInt32 _crcSize;
+
+  CObjectVector<COneMethodInfo> _methods;
+  bool _removeSfxBlock;
+  
+  UInt64 _numSolidFiles; 
+  UInt64 _numSolidBytes;
+  bool _numSolidBytesDefined;
+  bool _solidExtension;
+
+  bool _compressHeaders;
+  bool _encryptHeaders;
+
+  bool WriteModified;
+  bool WriteCreated;
+  bool WriteAccessed;
+
+  bool _autoFilter;
+  UInt32 _level;
+
+  bool _volumeMode;
+
+  HRESULT SetParam(COneMethodInfo &oneMethodInfo, const UString &name, const UString &value);
+  HRESULT SetParams(COneMethodInfo &oneMethodInfo, const UString &srcString);
+
+  void SetCompressionMethod2(COneMethodInfo &oneMethodInfo
+      #ifdef COMPRESS_MT
+      , UInt32 numThreads
+      #endif
+      );
+
+  void InitSolidFiles() { _numSolidFiles = (UInt64)(Int64)(-1); }
+  void InitSolidSize()  { _numSolidBytes = (UInt64)(Int64)(-1); }
+  void InitSolid()
+  {
+    InitSolidFiles();
+    InitSolidSize();
+    _solidExtension = false;
+    _numSolidBytesDefined = false;
+  }
+
+  void Init();
+
+  COutHandler() { Init(); }
+
+  void BeforeSetProperty();
+
+  UInt32 minNumber;
+  UInt32 numProcessors;
+  UInt32 mainDicSize;
+  UInt32 mainDicMethodIndex;
+
+  DECL_EXTERNAL_CODECS_VARS
+};
+
+}
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/misc/libphysfs/lzma/CPP/7zip/Archive/Common/InStreamWithCRC.cpp	Mon Apr 10 12:06:43 2017 -0400
@@ -0,0 +1,40 @@
+// InStreamWithCRC.cpp
+
+#include "StdAfx.h"
+
+#include "InStreamWithCRC.h"
+
+STDMETHODIMP CSequentialInStreamWithCRC::Read(void *data, UInt32 size, UInt32 *processedSize)
+{
+  UInt32 realProcessedSize;
+  HRESULT result = _stream->Read(data, size, &realProcessedSize);
+  _size += realProcessedSize;
+  if (size > 0 && realProcessedSize == 0)
+    _wasFinished = true;
+  _crc = CrcUpdate(_crc, data, realProcessedSize);
+  if(processedSize != NULL)
+    *processedSize = realProcessedSize;
+  return result;
+}
+
+STDMETHODIMP CInStreamWithCRC::Read(void *data, UInt32 size, UInt32 *processedSize)
+{
+  UInt32 realProcessedSize;
+  HRESULT result = _stream->Read(data, size, &realProcessedSize);
+  if (size > 0 && realProcessedSize == 0)
+    _wasFinished = true;
+  _size += realProcessedSize;
+  _crc = CrcUpdate(_crc, data, realProcessedSize);
+  if(processedSize != NULL)
+    *processedSize = realProcessedSize;
+  return result;
+}
+
+STDMETHODIMP CInStreamWithCRC::Seek(Int64 offset, UInt32 seekOrigin, UInt64 *newPosition)
+{
+  if (seekOrigin != STREAM_SEEK_SET || offset != 0)
+    return E_FAIL;
+  _size = 0;
+  _crc = CRC_INIT_VAL;
+  return _stream->Seek(offset, seekOrigin, newPosition);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/misc/libphysfs/lzma/CPP/7zip/Archive/Common/InStreamWithCRC.h	Mon Apr 10 12:06:43 2017 -0400
@@ -0,0 +1,69 @@
+// InStreamWithCRC.h
+
+#ifndef __INSTREAMWITHCRC_H
+#define __INSTREAMWITHCRC_H
+
+#include "../../../Common/MyCom.h"
+#include "../../IStream.h"
+
+extern "C" 
+{ 
+#include "../../../../C/7zCrc.h"
+}
+
+class CSequentialInStreamWithCRC: 
+  public ISequentialInStream,
+  public CMyUnknownImp
+{
+public:
+  MY_UNKNOWN_IMP
+
+  STDMETHOD(Read)(void *data, UInt32 size, UInt32 *processedSize);
+private:
+  CMyComPtr<ISequentialInStream> _stream;
+  UInt64 _size;
+  UInt32 _crc;
+  bool _wasFinished;
+public:
+  void SetStream(ISequentialInStream *stream) { _stream = stream;  }
+  void Init()
+  {
+    _size = 0;
+    _wasFinished = false;
+    _crc = CRC_INIT_VAL;
+  }
+  void ReleaseStream() { _stream.Release(); }
+  UInt32 GetCRC() const { return CRC_GET_DIGEST(_crc); }
+  UInt64 GetSize() const { return _size; }
+  bool WasFinished() const { return _wasFinished; }
+};
+
+class CInStreamWithCRC: 
+  public IInStream,
+  public CMyUnknownImp
+{
+public:
+  MY_UNKNOWN_IMP1(IInStream)
+
+  STDMETHOD(Read)(void *data, UInt32 size, UInt32 *processedSize);
+  STDMETHOD(Seek)(Int64 offset, UInt32 seekOrigin, UInt64 *newPosition);
+private:
+  CMyComPtr<IInStream> _stream;
+  UInt64 _size;
+  UInt32 _crc;
+  bool _wasFinished;
+public:
+  void SetStream(IInStream *stream) { _stream = stream;  }
+  void Init()
+  {
+    _size = 0;
+    _wasFinished = false;
+    _crc = CRC_INIT_VAL;
+  }
+  void ReleaseStream() { _stream.Release(); }
+  UInt32 GetCRC() const { return CRC_GET_DIGEST(_crc); }
+  UInt64 GetSize() const { return _size; }
+  bool WasFinished() const { return _wasFinished; }
+};
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/misc/libphysfs/lzma/CPP/7zip/Archive/Common/ItemNameUtils.cpp	Mon Apr 10 12:06:43 2017 -0400
@@ -0,0 +1,59 @@
+// Archive/Common/ItemNameUtils.cpp
+
+#include "StdAfx.h"
+
+#include "ItemNameUtils.h"
+
+namespace NArchive {
+namespace NItemName {
+
+static const wchar_t kOSDirDelimiter = WCHAR_PATH_SEPARATOR;
+static const wchar_t kDirDelimiter = L'/';
+
+UString MakeLegalName(const UString &name)
+{
+  UString zipName = name;
+  zipName.Replace(kOSDirDelimiter, kDirDelimiter);
+  return zipName;
+}
+
+UString GetOSName(const UString &name)
+{
+  UString newName = name;
+  newName.Replace(kDirDelimiter, kOSDirDelimiter);
+  return newName;
+}
+
+UString GetOSName2(const UString &name)
+{
+  if (name.IsEmpty())
+    return UString();
+  UString newName = GetOSName(name);
+  if (newName[newName.Length() - 1] == kOSDirDelimiter)
+    newName.Delete(newName.Length() - 1);
+  return newName;
+}
+
+bool HasTailSlash(const AString &name, UINT codePage)
+{
+  if (name.IsEmpty())
+    return false;
+  LPCSTR prev = 
+  #ifdef _WIN32
+    CharPrevExA((WORD)codePage, name, &name[name.Length()], 0);
+  #else
+    (LPCSTR)(name) + (name.Length() - 1);
+  #endif
+  return (*prev == '/');
+}
+
+#ifndef _WIN32
+UString WinNameToOSName(const UString &name)
+{
+  UString newName = name;
+  newName.Replace(L'\\', kOSDirDelimiter);
+  return newName;
+}
+#endif
+
+}}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/misc/libphysfs/lzma/CPP/7zip/Archive/Common/ItemNameUtils.h	Mon Apr 10 12:06:43 2017 -0400
@@ -0,0 +1,24 @@
+// Archive/Common/ItemNameUtils.h
+
+#ifndef __ARCHIVE_ITEMNAMEUTILS_H
+#define __ARCHIVE_ITEMNAMEUTILS_H
+
+#include "../../../Common/MyString.h"
+
+namespace NArchive {
+namespace NItemName {
+
+  UString MakeLegalName(const UString &name);
+  UString GetOSName(const UString &name);
+  UString GetOSName2(const UString &name);
+  bool HasTailSlash(const AString &name, UINT codePage);
+
+  #ifdef _WIN32
+  inline UString WinNameToOSName(const UString &name)  { return name; }
+  #else
+  UString WinNameToOSName(const UString &name);
+  #endif
+
+}}
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/misc/libphysfs/lzma/CPP/7zip/Archive/Common/MultiStream.cpp	Mon Apr 10 12:06:43 2017 -0400
@@ -0,0 +1,201 @@
+// MultiStream.cpp
+
+#include "StdAfx.h"
+
+#include "MultiStream.h"
+
+STDMETHODIMP CMultiStream::Read(void *data, UInt32 size, UInt32 *processedSize)
+{
+  if(processedSize != NULL)
+    *processedSize = 0;
+  while(_streamIndex < Streams.Size() && size > 0)
+  {
+    CSubStreamInfo &s = Streams[_streamIndex];
+    if (_pos == s.Size)
+    {
+      _streamIndex++;
+      _pos = 0;
+      continue;
+    }
+    RINOK(s.Stream->Seek(s.Pos + _pos, STREAM_SEEK_SET, 0));
+    UInt32 sizeToRead = UInt32(MyMin((UInt64)size, s.Size - _pos));
+    UInt32 realProcessed;
+    HRESULT result = s.Stream->Read(data, sizeToRead, &realProcessed);
+    data = (void *)((Byte *)data + realProcessed);
+    size -= realProcessed;
+    if(processedSize != NULL)
+      *processedSize += realProcessed;
+    _pos += realProcessed;
+    _seekPos += realProcessed;
+    RINOK(result);
+    break;
+  }
+  return S_OK;
+}
+  
+STDMETHODIMP CMultiStream::Seek(Int64 offset, UInt32 seekOrigin, 
+    UInt64 *newPosition)
+{
+  UInt64 newPos;
+  switch(seekOrigin)
+  {
+    case STREAM_SEEK_SET:
+      newPos = offset;
+      break;
+    case STREAM_SEEK_CUR:
+      newPos = _seekPos + offset;
+      break;
+    case STREAM_SEEK_END:
+      newPos = _totalLength + offset;
+      break;
+    default:
+      return STG_E_INVALIDFUNCTION;
+  }
+  _seekPos = 0;
+  for (_streamIndex = 0; _streamIndex < Streams.Size(); _streamIndex++)
+  {
+    UInt64 size = Streams[_streamIndex].Size;
+    if (newPos < _seekPos + size)
+    {
+      _pos = newPos - _seekPos;
+      _seekPos += _pos;
+      if (newPosition != 0)
+        *newPosition = newPos;
+      return S_OK;
+    }
+    _seekPos += size;
+  }
+  if (newPos == _seekPos)
+  {
+    if (newPosition != 0)
+      *newPosition = newPos;
+    return S_OK;
+  }
+  return E_FAIL;
+}
+
+
+/*
+class COutVolumeStream: 
+  public ISequentialOutStream,
+  public CMyUnknownImp
+{
+  int _volIndex;
+  UInt64 _volSize;
+  UInt64 _curPos;
+  CMyComPtr<ISequentialOutStream> _volumeStream;
+  COutArchive _archive;
+  CCRC _crc;
+
+public:
+  MY_UNKNOWN_IMP
+
+  CFileItem _file;
+  CUpdateOptions _options;
+  CMyComPtr<IArchiveUpdateCallback2> VolumeCallback;
+  void Init(IArchiveUpdateCallback2 *volumeCallback, 
+      const UString &name)  
+  { 
+    _file.Name = name;
+    _file.IsStartPosDefined = true;
+    _file.StartPos = 0;
+    
+    VolumeCallback = volumeCallback;
+    _volIndex = 0;
+    _volSize = 0;
+  }
+  
+  HRESULT Flush();
+  STDMETHOD(Write)(const void *data, UInt32 size, UInt32 *processedSize);
+};
+
+HRESULT COutVolumeStream::Flush()
+{
+  if (_volumeStream)
+  {
+    _file.UnPackSize = _curPos;
+    _file.FileCRC = _crc.GetDigest();
+    RINOK(WriteVolumeHeader(_archive, _file, _options));
+    _archive.Close();
+    _volumeStream.Release();
+    _file.StartPos += _file.UnPackSize;
+  }
+  return S_OK;
+}
+*/
+
+/*
+STDMETHODIMP COutMultiStream::Write(const void *data, UInt32 size, UInt32 *processedSize)
+{
+  if(processedSize != NULL)
+    *processedSize = 0;
+  while(size > 0)
+  {
+    if (_streamIndex >= Streams.Size())
+    {
+      CSubStreamInfo subStream;
+      RINOK(VolumeCallback->GetVolumeSize(Streams.Size(), &subStream.Size));
+      RINOK(VolumeCallback->GetVolumeStream(Streams.Size(), &subStream.Stream));
+      subStream.Pos = 0;
+      Streams.Add(subStream);
+      continue;
+    }
+    CSubStreamInfo &subStream = Streams[_streamIndex];
+    if (_offsetPos >= subStream.Size)
+    {
+      _offsetPos -= subStream.Size;
+      _streamIndex++;
+      continue;
+    }
+    if (_offsetPos != subStream.Pos)
+    {
+      CMyComPtr<IOutStream> outStream;
+      RINOK(subStream.Stream.QueryInterface(IID_IOutStream, &outStream));
+      RINOK(outStream->Seek(_offsetPos, STREAM_SEEK_SET, NULL));
+      subStream.Pos = _offsetPos;
+    }
+
+    UInt32 curSize = (UInt32)MyMin((UInt64)size, subStream.Size - subStream.Pos);
+    UInt32 realProcessed;
+    RINOK(subStream.Stream->Write(data, curSize, &realProcessed));
+    data = (void *)((Byte *)data + realProcessed);
+    size -= realProcessed;
+    subStream.Pos += realProcessed;
+    _offsetPos += realProcessed;
+    _absPos += realProcessed;
+    if (_absPos > _length)
+      _length = _absPos;
+    if(processedSize != NULL)
+      *processedSize += realProcessed;
+    if (subStream.Pos == subStream.Size)
+    {
+      _streamIndex++;
+      _offsetPos = 0;
+    }
+    if (realProcessed != curSize && realProcessed == 0)
+      return E_FAIL;
+  }
+  return S_OK;
+}
+
+STDMETHODIMP COutMultiStream::Seek(Int64 offset, UInt32 seekOrigin, UInt64 *newPosition)
+{
+  if(seekOrigin >= 3)
+    return STG_E_INVALIDFUNCTION;
+  switch(seekOrigin)
+  {
+    case STREAM_SEEK_SET:
+      _absPos = offset;
+      break;
+    case STREAM_SEEK_CUR:
+      _absPos += offset;
+      break;
+    case STREAM_SEEK_END:
+      _absPos = _length + offset;
+      break;
+  }
+  _offsetPos = _absPos;
+  _streamIndex = 0;
+  return S_OK;
+}
+*/
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/misc/libphysfs/lzma/CPP/7zip/Archive/Common/MultiStream.h	Mon Apr 10 12:06:43 2017 -0400
@@ -0,0 +1,76 @@
+// MultiStream.h
+
+#ifndef __MULTISTREAM_H
+#define __MULTISTREAM_H
+
+#include "../../../Common/MyCom.h"
+#include "../../../Common/MyVector.h"
+#include "../../Archive/IArchive.h"
+
+class CMultiStream: 
+  public IInStream,
+  public CMyUnknownImp
+{
+  int _streamIndex;
+  UInt64 _pos;
+  UInt64 _seekPos;
+  UInt64 _totalLength;
+public:
+  struct CSubStreamInfo
+  {
+    CMyComPtr<IInStream> Stream;
+    UInt64 Pos;
+    UInt64 Size;
+  };
+  CObjectVector<CSubStreamInfo> Streams;
+  void Init()
+  {
+    _streamIndex = 0;
+    _pos = 0;
+    _seekPos = 0;
+    _totalLength = 0;
+    for (int i = 0; i < Streams.Size(); i++)
+      _totalLength += Streams[i].Size;
+  }
+
+  MY_UNKNOWN_IMP1(IInStream)
+
+  STDMETHOD(Read)(void *data, UInt32 size, UInt32 *processedSize);
+  STDMETHOD(Seek)(Int64 offset, UInt32 seekOrigin, UInt64 *newPosition);
+};
+
+/*
+class COutMultiStream: 
+  public IOutStream,
+  public CMyUnknownImp
+{
+  int _streamIndex; // required stream
+  UInt64 _offsetPos; // offset from start of _streamIndex index
+  UInt64 _absPos;
+  UInt64 _length;
+
+  struct CSubStreamInfo
+  {
+    CMyComPtr<ISequentialOutStream> Stream;
+    UInt64 Size;
+    UInt64 Pos;
+ };
+  CObjectVector<CSubStreamInfo> Streams;
+public:
+  CMyComPtr<IArchiveUpdateCallback2> VolumeCallback;
+  void Init()
+  {
+    _streamIndex = 0;
+    _offsetPos = 0;
+    _absPos = 0;
+    _length = 0;
+  }
+
+  MY_UNKNOWN_IMP1(IOutStream)
+
+  STDMETHOD(Write)(const void *data, UInt32 size, UInt32 *processedSize);
+  STDMETHOD(Seek)(Int64 offset, UInt32 seekOrigin, UInt64 *newPosition);
+};
+*/
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/misc/libphysfs/lzma/CPP/7zip/Archive/Common/OutStreamWithCRC.cpp	Mon Apr 10 12:06:43 2017 -0400
@@ -0,0 +1,24 @@
+// OutStreamWithCRC.cpp
+
+#include "StdAfx.h"
+
+#include "OutStreamWithCRC.h"
+
+STDMETHODIMP COutStreamWithCRC::Write(const void *data, UInt32 size, UInt32 *processedSize)
+{
+  UInt32 realProcessedSize;
+  HRESULT result;
+  if(!_stream)
+  {
+    realProcessedSize = size;
+    result = S_OK;
+  }
+  else
+    result = _stream->Write(data, size, &realProcessedSize);
+  if (_calculate)
+    _crc = CrcUpdate(_crc, data, realProcessedSize);
+  _size += realProcessedSize;
+  if(processedSize != NULL)
+    *processedSize = realProcessedSize;
+  return result;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/misc/libphysfs/lzma/CPP/7zip/Archive/Common/OutStreamWithCRC.h	Mon Apr 10 12:06:43 2017 -0400
@@ -0,0 +1,38 @@
+// OutStreamWithCRC.h
+
+#ifndef __OUTSTREAMWITHCRC_H
+#define __OUTSTREAMWITHCRC_H
+
+#include "../../../Common/MyCom.h"
+#include "../../IStream.h"
+
+extern "C" 
+{ 
+#include "../../../../C/7zCrc.h"
+}
+
+class COutStreamWithCRC: 
+  public ISequentialOutStream,
+  public CMyUnknownImp
+{
+  CMyComPtr<ISequentialOutStream> _stream;
+  UInt64 _size;
+  UInt32 _crc;
+  bool _calculate;
+public:
+  MY_UNKNOWN_IMP
+  STDMETHOD(Write)(const void *data, UInt32 size, UInt32 *processedSize);
+  void SetStream(ISequentialOutStream *stream) { _stream = stream; }
+  void ReleaseStream() { _stream.Release(); }
+  void Init(bool calculate = true)
+  {
+    _size = 0;
+    _calculate = calculate;
+    _crc = CRC_INIT_VAL;
+  }
+  void InitCRC() { _crc = CRC_INIT_VAL; }
+  UInt64 GetSize() const { return _size; }
+  UInt32 GetCRC() const { return CRC_GET_DIGEST(_crc); }
+};
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/misc/libphysfs/lzma/CPP/7zip/Archive/Common/ParseProperties.cpp	Mon Apr 10 12:06:43 2017 -0400
@@ -0,0 +1,174 @@
+// ParseProperties.cpp
+
+#include "StdAfx.h"
+
+#include "ParseProperties.h"
+
+#include "Common/StringToInt.h"
+#include "Common/MyCom.h"
+
+HRESULT ParsePropValue(const UString &name, const PROPVARIANT &prop, UInt32 &resValue)
+{
+  if (prop.vt == VT_UI4)
+  {
+    if (!name.IsEmpty())
+      return E_INVALIDARG;
+    resValue = prop.ulVal;
+  }
+  else if (prop.vt == VT_EMPTY)
+  {
+    if(!name.IsEmpty())
+    {
+      const wchar_t *start = name;
+      const wchar_t *end;
+      UInt64 v = ConvertStringToUInt64(start, &end);
+      if (end - start != name.Length())
+        return E_INVALIDARG;
+      resValue = (UInt32)v;
+    }
+  }
+  else
+    return E_INVALIDARG;
+  return S_OK;
+}
+
+static const int kLogarithmicSizeLimit = 32;
+static const wchar_t kByteSymbol = L'B';
+static const wchar_t kKiloByteSymbol = L'K';
+static const wchar_t kMegaByteSymbol = L'M';
+
+HRESULT ParsePropDictionaryValue(const UString &srcStringSpec, UInt32 &dicSize)
+{
+  UString srcString = srcStringSpec;
+  srcString.MakeUpper();
+
+  const wchar_t *start = srcString;
+  const wchar_t *end;
+  UInt64 number = ConvertStringToUInt64(start, &end);
+  int numDigits = (int)(end - start);
+  if (numDigits == 0 || srcString.Length() > numDigits + 1)
+    return E_INVALIDARG;
+  if (srcString.Length() == numDigits)
+  {
+    if (number >= kLogarithmicSizeLimit)
+      return E_INVALIDARG;
+    dicSize = (UInt32)1 << (int)number;
+    return S_OK;
+  }
+  switch (srcString[numDigits])
+  {
+    case kByteSymbol:
+      if (number >= ((UInt64)1 << kLogarithmicSizeLimit))
+        return E_INVALIDARG;
+      dicSize = (UInt32)number;
+      break;
+    case kKiloByteSymbol:
+      if (number >= ((UInt64)1 << (kLogarithmicSizeLimit - 10)))
+        return E_INVALIDARG;
+      dicSize = (UInt32)(number << 10);
+      break;
+    case kMegaByteSymbol:
+      if (number >= ((UInt64)1 << (kLogarithmicSizeLimit - 20)))
+        return E_INVALIDARG;
+      dicSize = (UInt32)(number << 20);
+      break;
+    default:
+      return E_INVALIDARG;
+  }
+  return S_OK;
+}
+
+HRESULT ParsePropDictionaryValue(const UString &name, const PROPVARIANT &prop, UInt32 &resValue)
+{
+  if (name.IsEmpty())
+  {
+    if (prop.vt == VT_UI4)
+    {
+      UInt32 logDicSize = prop.ulVal;
+      if (logDicSize >= 32)
+        return E_INVALIDARG;
+      resValue = (UInt32)1 << logDicSize;
+      return S_OK;
+    }
+    if (prop.vt == VT_BSTR)
+      return ParsePropDictionaryValue(prop.bstrVal, resValue);
+    return E_INVALIDARG;
+  }
+  return ParsePropDictionaryValue(name, resValue);
+}
+
+bool StringToBool(const UString &s, bool &res)
+{
+  if (s.IsEmpty() || s.CompareNoCase(L"ON") == 0)
+  {
+    res = true;
+    return true;
+  }
+  if (s.CompareNoCase(L"OFF") == 0)
+  {
+    res = false;
+    return true;
+  }
+  return false;
+}
+
+HRESULT SetBoolProperty(bool &dest, const PROPVARIANT &value)
+{
+  switch(value.vt)
+  {
+    case VT_EMPTY:
+      dest = true;
+      return S_OK;
+    /*
+    case VT_UI4:
+      dest = (value.ulVal != 0);
+      break;
+    */
+    case VT_BSTR:
+      return StringToBool(value.bstrVal, dest) ?  S_OK : E_INVALIDARG;
+  }
+  return E_INVALIDARG;
+}
+
+int ParseStringToUInt32(const UString &srcString, UInt32 &number)
+{
+  const wchar_t *start = srcString;
+  const wchar_t *end;
+  UInt64 number64 = ConvertStringToUInt64(start, &end);
+  if (number64 > 0xFFFFFFFF) 
+  {
+    number = 0;
+    return 0;
+  }
+  number = (UInt32)number64;
+  return (int)(end - start);
+}
+
+HRESULT ParseMtProp(const UString &name, const PROPVARIANT &prop, UInt32 defaultNumThreads, UInt32 &numThreads)
+{
+  if (name.IsEmpty())
+  {
+    switch(prop.vt)
+    {
+      case VT_UI4:
+        numThreads = prop.ulVal;
+        break;
+      default:
+      {
+        bool val; 
+        RINOK(SetBoolProperty(val, prop));
+        numThreads = (val ? defaultNumThreads : 1);
+        break;
+      }
+    }
+  }
+  else
+  {
+    UInt32 number;
+    int index = ParseStringToUInt32(name, number);
+    if (index != name.Length())
+      return E_INVALIDARG;
+    numThreads = number;
+  }
+  return S_OK;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/misc/libphysfs/lzma/CPP/7zip/Archive/Common/ParseProperties.h	Mon Apr 10 12:06:43 2017 -0400
@@ -0,0 +1,18 @@
+// ParseProperties.h
+
+#ifndef __PARSEPROPERTIES_H
+#define __PARSEPROPERTIES_H
+
+#include "Common/MyString.h"
+#include "Common/Types.h"
+
+HRESULT ParsePropValue(const UString &name, const PROPVARIANT &prop, UInt32 &resValue);
+HRESULT ParsePropDictionaryValue(const UString &srcStringSpec, UInt32 &dicSize);
+HRESULT ParsePropDictionaryValue(const UString &name, const PROPVARIANT &prop, UInt32 &resValue);
+
+bool StringToBool(const UString &s, bool &res);
+HRESULT SetBoolProperty(bool &dest, const PROPVARIANT &value);
+int ParseStringToUInt32(const UString &srcString, UInt32 &number);
+HRESULT ParseMtProp(const UString &name, const PROPVARIANT &prop, UInt32 defaultNumThreads, UInt32 &numThreads);
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/misc/libphysfs/lzma/CPP/7zip/Archive/DllExports2.cpp	Mon Apr 10 12:06:43 2017 -0400
@@ -0,0 +1,82 @@
+// DLLExports.cpp
+
+#include "StdAfx.h"
+
+#include "../../Common/MyInitGuid.h"
+#include "../../Common/ComTry.h"
+#include "../../Common/Types.h"
+#include "../../Windows/PropVariant.h"
+#if defined(_WIN32) && defined(_7ZIP_LARGE_PAGES)
+extern "C" 
+{ 
+#include "../../../C/Alloc.h"
+}
+#endif
+
+#include "IArchive.h"
+#include "../ICoder.h"
+#include "../IPassword.h"
+
+HINSTANCE g_hInstance;
+#ifndef _UNICODE
+#ifdef _WIN32
+bool g_IsNT = false;
+static bool IsItWindowsNT()
+{
+  OSVERSIONINFO versionInfo;
+  versionInfo.dwOSVersionInfoSize = sizeof(versionInfo);
+  if (!::GetVersionEx(&versionInfo)) 
+    return false;
+  return (versionInfo.dwPlatformId == VER_PLATFORM_WIN32_NT);
+}
+#endif
+#endif
+
+extern "C"
+BOOL WINAPI DllMain(HINSTANCE hInstance, DWORD dwReason, LPVOID /*lpReserved*/)
+{
+  if (dwReason == DLL_PROCESS_ATTACH)
+  {
+    g_hInstance = hInstance;
+    #ifndef _UNICODE
+    #ifdef _WIN32
+    g_IsNT = IsItWindowsNT();
+    #endif
+    #endif
+  }
+  return TRUE;
+}
+
+DEFINE_GUID(CLSID_CArchiveHandler, 
+0x23170F69, 0x40C1, 0x278A, 0x10, 0x00, 0x00, 0x01, 0x10, 0x00, 0x00, 0x00);
+
+static const UInt16 kDecodeId = 0x2790;
+
+DEFINE_GUID(CLSID_CCodec, 
+0x23170F69, 0x40C1, kDecodeId, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00);
+
+STDAPI CreateCoder(const GUID *clsid, const GUID *iid, void **outObject);
+STDAPI CreateArchiver(const GUID *classID, const GUID *iid, void **outObject);
+
+STDAPI CreateObject(const GUID *clsid, const GUID *iid, void **outObject)
+{
+  // COM_TRY_BEGIN
+  *outObject = 0;
+  if (*iid == IID_ICompressCoder || *iid == IID_ICompressCoder2 || *iid == IID_ICompressFilter)
+  {
+    return CreateCoder(clsid, iid, outObject);
+  }
+  else
+  {
+    return CreateArchiver(clsid, iid, outObject);
+  }
+  // COM_TRY_END
+}
+
+STDAPI SetLargePageMode()
+{
+  #if defined(_WIN32) && defined(_7ZIP_LARGE_PAGES)
+  SetLargePageSize();
+  #endif
+  return S_OK;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/misc/libphysfs/lzma/CPP/7zip/Archive/IArchive.h	Mon Apr 10 12:06:43 2017 -0400
@@ -0,0 +1,207 @@
+// IArchive.h
+
+#ifndef __IARCHIVE_H
+#define __IARCHIVE_H
+
+#include "../IStream.h"
+#include "../IProgress.h"
+#include "../PropID.h"
+
+#define ARCHIVE_INTERFACE_SUB(i, base, x) DECL_INTERFACE_SUB(i, base, 6, x)
+#define ARCHIVE_INTERFACE(i, x) ARCHIVE_INTERFACE_SUB(i, IUnknown, x)
+
+namespace NFileTimeType
+{
+  enum EEnum
+  {
+    kWindows,
+    kUnix,
+    kDOS
+  };
+}
+
+namespace NArchive
+{
+  enum 
+  {
+    kName = 0,
+    kClassID,
+    kExtension,
+    kAddExtension,
+    kUpdate,
+    kKeepName,
+    kStartSignature,
+    kFinishSignature,
+    kAssociate
+  };
+
+  namespace NExtract
+  {
+    namespace NAskMode
+    {
+      enum 
+      {
+        kExtract = 0,
+        kTest,
+        kSkip
+      };
+    }
+    namespace NOperationResult
+    {
+      enum 
+      {
+        kOK = 0,
+        kUnSupportedMethod,
+        kDataError,
+        kCRCError
+      };
+    }
+  }
+  namespace NUpdate
+  {
+    namespace NOperationResult
+    {
+      enum 
+      {
+        kOK = 0,
+        kError
+      };
+    }
+  }
+}
+
+ARCHIVE_INTERFACE(IArchiveOpenCallback, 0x10)
+{
+  STDMETHOD(SetTotal)(const UInt64 *files, const UInt64 *bytes) PURE;
+  STDMETHOD(SetCompleted)(const UInt64 *files, const UInt64 *bytes) PURE;
+};
+
+
+ARCHIVE_INTERFACE_SUB(IArchiveExtractCallback, IProgress, 0x20)
+{
+  STDMETHOD(GetStream)(UInt32 index, ISequentialOutStream **outStream, 
+      Int32 askExtractMode) PURE;
+  // GetStream OUT: S_OK - OK, S_FALSE - skeep this file
+  STDMETHOD(PrepareOperation)(Int32 askExtractMode) PURE;
+  STDMETHOD(SetOperationResult)(Int32 resultEOperationResult) PURE;
+};
+
+
+ARCHIVE_INTERFACE(IArchiveOpenVolumeCallback, 0x30)
+{
+  STDMETHOD(GetProperty)(PROPID propID, PROPVARIANT *value) PURE;
+  STDMETHOD(GetStream)(const wchar_t *name, IInStream **inStream) PURE;
+};
+
+
+ARCHIVE_INTERFACE(IInArchiveGetStream, 0x40)
+{
+  STDMETHOD(GetStream)(UInt32 index, ISequentialInStream **stream) PURE;  
+};
+
+
+ARCHIVE_INTERFACE(IArchiveOpenSetSubArchiveName, 0x50)
+{
+  STDMETHOD(SetSubArchiveName)(const wchar_t *name) PURE;
+};
+
+
+/*
+IInArchive::Extract:
+  indices must be sorted 
+  numItems = 0xFFFFFFFF means "all files"
+  testMode != 0 means "test files without writing to outStream"
+*/
+
+#define INTERFACE_IInArchive(x) \
+  STDMETHOD(Open)(IInStream *stream, const UInt64 *maxCheckStartPosition, IArchiveOpenCallback *openArchiveCallback) x; \
+  STDMETHOD(Close)() x; \
+  STDMETHOD(GetNumberOfItems)(UInt32 *numItems) x; \
+  STDMETHOD(GetProperty)(UInt32 index, PROPID propID, PROPVARIANT *value) x; \
+  STDMETHOD(Extract)(const UInt32* indices, UInt32 numItems, Int32 testMode, IArchiveExtractCallback *extractCallback) x; \
+  STDMETHOD(GetArchiveProperty)(PROPID propID, PROPVARIANT *value) x; \
+  STDMETHOD(GetNumberOfProperties)(UInt32 *numProperties) x; \
+  STDMETHOD(GetPropertyInfo)(UInt32 index, BSTR *name, PROPID *propID, VARTYPE *varType) x; \
+  STDMETHOD(GetNumberOfArchiveProperties)(UInt32 *numProperties) x; \
+  STDMETHOD(GetArchivePropertyInfo)(UInt32 index, BSTR *name, PROPID *propID, VARTYPE *varType) x;
+
+ARCHIVE_INTERFACE(IInArchive, 0x60)
+{
+  INTERFACE_IInArchive(PURE)
+};
+
+
+ARCHIVE_INTERFACE_SUB(IArchiveUpdateCallback, IProgress, 0x80)
+{
+  STDMETHOD(GetUpdateItemInfo)(UInt32 index, 
+      Int32 *newData, // 1 - new data, 0 - old data
+      Int32 *newProperties, // 1 - new properties, 0 - old properties
+      UInt32 *indexInArchive // -1 if there is no in archive, or if doesn't matter
+      ) PURE;
+  STDMETHOD(GetProperty)(UInt32 index, PROPID propID, PROPVARIANT *value) PURE;
+  STDMETHOD(GetStream)(UInt32 index, ISequentialInStream **inStream) PURE;
+  STDMETHOD(SetOperationResult)(Int32 operationResult) PURE;
+};
+
+
+ARCHIVE_INTERFACE_SUB(IArchiveUpdateCallback2, IArchiveUpdateCallback, 0x82)
+{
+  STDMETHOD(GetVolumeSize)(UInt32 index, UInt64 *size) PURE;
+  STDMETHOD(GetVolumeStream)(UInt32 index, ISequentialOutStream **volumeStream) PURE;
+};
+
+
+#define INTERFACE_IOutArchive(x) \
+  STDMETHOD(UpdateItems)(ISequentialOutStream *outStream, UInt32 numItems, IArchiveUpdateCallback *updateCallback) x; \
+  STDMETHOD(GetFileTimeType)(UInt32 *type) x;
+
+ARCHIVE_INTERFACE(IOutArchive, 0xA0)
+{
+  INTERFACE_IOutArchive(PURE)
+};
+
+
+ARCHIVE_INTERFACE(ISetProperties, 0x03)
+{
+  STDMETHOD(SetProperties)(const wchar_t **names, const PROPVARIANT *values, Int32 numProperties) PURE;
+};
+
+
+#define IMP_IInArchive_GetProp(k) \
+  (UInt32 index, BSTR *name, PROPID *propID, VARTYPE *varType) \
+    { if(index >= sizeof(k) / sizeof(k[0])) return E_INVALIDARG; \
+    const STATPROPSTG &srcItem = k[index]; \
+    *propID = srcItem.propid; *varType = srcItem.vt; *name = 0; return S_OK; } \
+
+#define IMP_IInArchive_GetProp_WITH_NAME(k) \
+  (UInt32 index, BSTR *name, PROPID *propID, VARTYPE *varType) \
+    { if(index >= sizeof(k) / sizeof(k[0])) return E_INVALIDARG; \
+    const STATPROPSTG &srcItem = k[index]; \
+    *propID = srcItem.propid; *varType = srcItem.vt; \
+    if (srcItem.lpwstrName == 0) *name = 0; else *name = ::SysAllocString(srcItem.lpwstrName); return S_OK; } \
+
+#define IMP_IInArchive_Props \
+  STDMETHODIMP CHandler::GetNumberOfProperties(UInt32 *numProperties) \
+    { *numProperties = sizeof(kProps) / sizeof(kProps[0]); return S_OK; } \
+  STDMETHODIMP CHandler::GetPropertyInfo IMP_IInArchive_GetProp(kProps)
+
+#define IMP_IInArchive_Props_WITH_NAME \
+  STDMETHODIMP CHandler::GetNumberOfProperties(UInt32 *numProperties) \
+    { *numProperties = sizeof(kProps) / sizeof(kProps[0]); return S_OK; } \
+  STDMETHODIMP CHandler::GetPropertyInfo IMP_IInArchive_GetProp_WITH_NAME(kProps)
+
+
+#define IMP_IInArchive_ArcProps \
+  STDMETHODIMP CHandler::GetNumberOfArchiveProperties(UInt32 *numProperties) \
+    { *numProperties = sizeof(kArcProps) / sizeof(kArcProps[0]); return S_OK; } \
+  STDMETHODIMP CHandler::GetArchivePropertyInfo IMP_IInArchive_GetProp(kArcProps)
+
+#define IMP_IInArchive_ArcProps_NO \
+  STDMETHODIMP CHandler::GetNumberOfArchiveProperties(UInt32 *numProperties) \
+    { *numProperties = 0; return S_OK; } \
+  STDMETHODIMP CHandler::GetArchivePropertyInfo(UInt32, BSTR *, PROPID *, VARTYPE *) \
+    { return E_NOTIMPL; } \
+  STDMETHODIMP CHandler::GetArchiveProperty(PROPID, PROPVARIANT *value) \
+    { value->vt = VT_EMPTY; return S_OK; } 
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/misc/libphysfs/lzma/CPP/7zip/Bundles/Alone7z/Alone.dsp	Mon Apr 10 12:06:43 2017 -0400
@@ -0,0 +1,1453 @@
+# Microsoft Developer Studio Project File - Name="Alone" - Package Owner=<4>
+# Microsoft Developer Studio Generated Build File, Format Version 6.00
+# ** DO NOT EDIT **
+
+# TARGTYPE "Win32 (x86) Console Application" 0x0103
+
+CFG=Alone - Win32 DebugU
+!MESSAGE This is not a valid makefile. To build this project using NMAKE,
+!MESSAGE use the Export Makefile command and run
+!MESSAGE 
+!MESSAGE NMAKE /f "Alone.mak".
+!MESSAGE 
+!MESSAGE You can specify a configuration when running NMAKE
+!MESSAGE by defining the macro CFG on the command line. For example:
+!MESSAGE 
+!MESSAGE NMAKE /f "Alone.mak" CFG="Alone - Win32 DebugU"
+!MESSAGE 
+!MESSAGE Possible choices for configuration are:
+!MESSAGE 
+!MESSAGE "Alone - Win32 Release" (based on "Win32 (x86) Console Application")
+!MESSAGE "Alone - Win32 Debug" (based on "Win32 (x86) Console Application")
+!MESSAGE "Alone - Win32 ReleaseU" (based on "Win32 (x86) Console Application")
+!MESSAGE "Alone - Win32 DebugU" (based on "Win32 (x86) Console Application")
+!MESSAGE 
+
+# Begin Project
+# PROP AllowPerConfigDependencies 0
+# PROP Scc_ProjName ""
+# PROP Scc_LocalPath ""
+CPP=cl.exe
+RSC=rc.exe
+
+!IF  "$(CFG)" == "Alone - Win32 Release"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 0
+# PROP BASE Output_Dir "Release"
+# PROP BASE Intermediate_Dir "Release"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 0
+# PROP Output_Dir "Release"
+# PROP Intermediate_Dir "Release"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
+# ADD CPP /nologo /Gz /MT /W3 /GX /O1 /I "..\..\..\\" /D "NDEBUG" /D "_MBCS" /D "WIN32" /D "_CONSOLE" /D "COMPRESS_MF_MT" /D "COMPRESS_MT" /D "_NO_CRYPTO" /D "BREAK_HANDLER" /D "BENCH_MT" /Yu"StdAfx.h" /FD /c
+# ADD BASE RSC /l 0x419 /d "NDEBUG"
+# ADD RSC /l 0x419 /d "NDEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386
+# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 /out:"c:\UTIL\7zr.exe" /opt:NOWIN98
+# SUBTRACT LINK32 /pdb:none
+
+!ELSEIF  "$(CFG)" == "Alone - Win32 Debug"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 1
+# PROP BASE Output_Dir "Debug"
+# PROP BASE Intermediate_Dir "Debug"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 1
+# PROP Output_Dir "Debug"
+# PROP Intermediate_Dir "Debug"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c
+# ADD CPP /nologo /Gz /MDd /W3 /Gm /GX /ZI /Od /I "..\..\..\\" /D "_DEBUG" /D "_MBCS" /D "WIN32" /D "_CONSOLE" /D "COMPRESS_MF_MT" /D "COMPRESS_MT" /D "_NO_CRYPTO" /D "BREAK_HANDLER" /D "BENCH_MT" /Yu"StdAfx.h" /FD /GZ /c
+# ADD BASE RSC /l 0x419 /d "_DEBUG"
+# ADD RSC /l 0x419 /d "_DEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept
+# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /out:"c:\UTIL\7zr.exe" /pdbtype:sept
+
+!ELSEIF  "$(CFG)" == "Alone - Win32 ReleaseU"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 0
+# PROP BASE Output_Dir "ReleaseU"
+# PROP BASE Intermediate_Dir "ReleaseU"
+# PROP BASE Ignore_Export_Lib 0
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 0
+# PROP Output_Dir "ReleaseU"
+# PROP Intermediate_Dir "ReleaseU"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /MD /W3 /GX /O2 /D "NDEBUG" /D "WIN32" /D "_CONSOLE" /D "EXCLUDE_COM" /D "NO_REGISTRY" /D "FORMAT_7Z" /D "FORMAT_BZIP2" /D "FORMAT_ZIP" /D "FORMAT_TAR" /D "FORMAT_GZIP" /D "COMPRESS_LZMA" /D "COMPRESS_BCJ_X86" /D "COMPRESS_BCJ2" /D "COMPRESS_COPY" /D "COMPRESS_MF_PAT" /D "COMPRESS_MF_BT" /D "COMPRESS_PPMD" /D "COMPRESS_DEFLATE" /D "COMPRESS_IMPLODE" /D "COMPRESS_BZIP2" /D "CRYPTO_ZIP" /Yu"StdAfx.h" /FD /c
+# ADD CPP /nologo /Gz /MD /W3 /GX /O1 /I "..\..\..\\" /D "NDEBUG" /D "UNICODE" /D "_UNICODE" /D "WIN32" /D "_CONSOLE" /D "COMPRESS_MF_MT" /D "COMPRESS_MT" /D "_NO_CRYPTO" /D "BREAK_HANDLER" /D "BENCH_MT" /Yu"StdAfx.h" /FD /c
+# ADD BASE RSC /l 0x419 /d "NDEBUG"
+# ADD RSC /l 0x419 /d "NDEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 /out:"c:\UTIL\7za.exe" /opt:NOWIN98
+# SUBTRACT BASE LINK32 /pdb:none
+# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 /out:"c:\UTIL\7zr.exe" /opt:NOWIN98
+# SUBTRACT LINK32 /pdb:none
+
+!ELSEIF  "$(CFG)" == "Alone - Win32 DebugU"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 1
+# PROP BASE Output_Dir "DebugU"
+# PROP BASE Intermediate_Dir "DebugU"
+# PROP BASE Ignore_Export_Lib 0
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 1
+# PROP Output_Dir "DebugU"
+# PROP Intermediate_Dir "DebugU"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "_DEBUG" /D "WIN32" /D "_CONSOLE" /D "EXCLUDE_COM" /D "NO_REGISTRY" /D "FORMAT_7Z" /D "FORMAT_BZIP2" /D "FORMAT_ZIP" /D "FORMAT_TAR" /D "FORMAT_GZIP" /D "COMPRESS_LZMA" /D "COMPRESS_BCJ_X86" /D "COMPRESS_BCJ2" /D "COMPRESS_COPY" /D "COMPRESS_MF_PAT" /D "COMPRESS_MF_BT" /D "COMPRESS_PPMD" /D "COMPRESS_DEFLATE" /D "COMPRESS_IMPLODE" /D "COMPRESS_BZIP2" /D "CRYPTO_ZIP" /D "_MBCS" /Yu"StdAfx.h" /FD /GZ /c
+# ADD CPP /nologo /Gz /W4 /Gm /GX /ZI /Od /I "..\..\..\\" /D "_DEBUG" /D "_UNICODE" /D "UNICODE" /D "WIN32" /D "_CONSOLE" /D "COMPRESS_MF_MT" /D "COMPRESS_MT" /D "_NO_CRYPTO" /D "BREAK_HANDLER" /D "BENCH_MT" /Yu"StdAfx.h" /FD /GZ /c
+# ADD BASE RSC /l 0x419 /d "_DEBUG"
+# ADD RSC /l 0x419 /d "_DEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /out:"c:\UTIL\7za.exe" /pdbtype:sept
+# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /out:"c:\UTIL\7zr.exe" /pdbtype:sept
+
+!ENDIF 
+
+# Begin Target
+
+# Name "Alone - Win32 Release"
+# Name "Alone - Win32 Debug"
+# Name "Alone - Win32 ReleaseU"
+# Name "Alone - Win32 DebugU"
+# Begin Group "Console"
+
+# PROP Default_Filter ""
+# Begin Source File
+
+SOURCE=..\..\UI\Console\ArError.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\UI\Console\CompressionMode.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\UI\Console\ConsoleClose.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\UI\Console\ConsoleClose.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\UI\Console\ExtractCallbackConsole.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\UI\Console\ExtractCallbackConsole.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\UI\Console\List.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\UI\Console\List.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\UI\Console\Main.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\UI\Console\MainAr.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\UI\Console\OpenCallbackConsole.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\UI\Console\OpenCallbackConsole.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\UI\Console\PercentPrinter.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\UI\Console\PercentPrinter.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\UI\Console\UpdateCallbackConsole.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\UI\Console\UpdateCallbackConsole.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\UI\Console\UserInputUtils.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\UI\Console\UserInputUtils.h
+# End Source File
+# End Group
+# Begin Group "Spec"
+
+# PROP Default_Filter ""
+# Begin Source File
+
+SOURCE=.\resource.rc
+# End Source File
+# Begin Source File
+
+SOURCE=.\StdAfx.cpp
+# ADD CPP /Yc"StdAfx.h"
+# End Source File
+# Begin Source File
+
+SOURCE=.\StdAfx.h
+# End Source File
+# End Group
+# Begin Group "Common"
+
+# PROP Default_Filter ""
+# Begin Source File
+
+SOURCE=..\..\..\Common\AutoPtr.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Common\Buffer.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Common\CommandLineParser.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Common\CommandLineParser.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Common\ComTry.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Common\CRC.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Common\Defs.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Common\DynamicBuffer.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Common\IntToString.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Common\IntToString.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Common\ListFileUtils.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Common\ListFileUtils.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Common\MyCom.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Common\MyException.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Common\MyGuidDef.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Common\MyInitGuid.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Common\MyString.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Common\MyString.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Common\MyUnknown.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Common\MyVector.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Common\MyVector.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Common\MyWindows.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Common\MyWindows.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Common\NewHandler.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Common\NewHandler.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Common\Random.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Common\Random.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Common\StdInStream.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Common\StdInStream.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Common\StdOutStream.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Common\StdOutStream.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Common\StringConvert.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Common\StringConvert.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Common\StringToInt.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Common\StringToInt.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Common\Types.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Common\UTFConvert.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Common\UTFConvert.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Common\Wildcard.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Common\Wildcard.h
+# End Source File
+# End Group
+# Begin Group "Windows"
+
+# PROP Default_Filter ""
+# Begin Source File
+
+SOURCE=..\..\..\Windows\Defs.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Windows\Device.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Windows\DLL.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Windows\DLL.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Windows\Error.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Windows\Error.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Windows\FileDir.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Windows\FileDir.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Windows\FileFind.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Windows\FileFind.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Windows\FileIO.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Windows\FileIO.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Windows\FileName.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Windows\FileName.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Windows\Handle.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Windows\MemoryLock.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Windows\MemoryLock.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Windows\PropVariant.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Windows\PropVariant.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Windows\PropVariantConversions.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Windows\PropVariantConversions.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Windows\Synchronization.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Windows\Synchronization.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Windows\System.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Windows\System.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Windows\Thread.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Windows\Time.h
+# End Source File
+# End Group
+# Begin Group "7zip Common"
+
+# PROP Default_Filter ""
+# Begin Source File
+
+SOURCE=..\..\Common\CreateCoder.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Common\CreateCoder.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Archive\Common\CrossThreadProgress.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Archive\Common\CrossThreadProgress.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Common\FilePathAutoRename.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Common\FilePathAutoRename.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Common\FileStreams.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Common\FileStreams.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Common\FilterCoder.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Common\FilterCoder.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Common\InBuffer.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Common\InBuffer.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Common\InOutTempBuffer.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Common\InOutTempBuffer.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Common\LimitedStreams.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Common\LimitedStreams.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Common\LockedStream.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Common\LockedStream.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Common\LSBFDecoder.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Common\LSBFDecoder.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Common\LSBFEncoder.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Common\LSBFEncoder.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Common\MethodId.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Common\MethodId.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Common\MethodProps.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Common\MethodProps.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Common\MSBFDecoder.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Common\MSBFEncoder.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Common\OffsetStream.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Common\OffsetStream.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Common\OutBuffer.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Common\OutBuffer.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Common\ProgressMt.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Common\ProgressMt.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Common\ProgressUtils.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Common\ProgressUtils.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Common\RegisterArc.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Common\RegisterCodec.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Common\StreamBinder.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Common\StreamBinder.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Common\StreamObjects.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Common\StreamObjects.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Common\StreamUtils.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Common\StreamUtils.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Common\VirtThread.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Common\VirtThread.h
+# End Source File
+# End Group
+# Begin Group "Compress"
+
+# PROP Default_Filter ""
+# Begin Group "Branch"
+
+# PROP Default_Filter ""
+# Begin Source File
+
+SOURCE=..\..\Compress\Branch\BranchCoder.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Compress\Branch\BranchCoder.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Compress\Branch\Coder.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Compress\Branch\x86.cpp
+
+!IF  "$(CFG)" == "Alone - Win32 Release"
+
+# ADD CPP /O2
+# SUBTRACT CPP /YX /Yc /Yu
+
+!ELSEIF  "$(CFG)" == "Alone - Win32 Debug"
+
+!ELSEIF  "$(CFG)" == "Alone - Win32 ReleaseU"
+
+# ADD CPP /O2
+# SUBTRACT CPP /YX /Yc /Yu
+
+!ELSEIF  "$(CFG)" == "Alone - Win32 DebugU"
+
+!ENDIF 
+
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Compress\Branch\x86.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Compress\Branch\x86_2.cpp
+
+!IF  "$(CFG)" == "Alone - Win32 Release"
+
+# ADD CPP /O2
+# SUBTRACT CPP /YX /Yc /Yu
+
+!ELSEIF  "$(CFG)" == "Alone - Win32 Debug"
+
+!ELSEIF  "$(CFG)" == "Alone - Win32 ReleaseU"
+
+# ADD CPP /O2
+# SUBTRACT CPP /YX /Yc /Yu
+
+!ELSEIF  "$(CFG)" == "Alone - Win32 DebugU"
+
+!ENDIF 
+
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Compress\Branch\x86_2.h
+# End Source File
+# End Group
+# Begin Group "Copy"
+
+# PROP Default_Filter ""
+# Begin Source File
+
+SOURCE=..\..\Compress\Copy\CopyCoder.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Compress\Copy\CopyCoder.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Compress\Copy\CopyRegister.cpp
+# End Source File
+# End Group
+# Begin Group "LZ"
+
+# PROP Default_Filter ""
+# Begin Source File
+
+SOURCE=..\..\Compress\LZ\LZOutWindow.cpp
+
+!IF  "$(CFG)" == "Alone - Win32 Release"
+
+# ADD CPP /O1
+
+!ELSEIF  "$(CFG)" == "Alone - Win32 Debug"
+
+!ELSEIF  "$(CFG)" == "Alone - Win32 ReleaseU"
+
+# ADD CPP /O1
+
+!ELSEIF  "$(CFG)" == "Alone - Win32 DebugU"
+
+!ENDIF 
+
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Compress\LZ\LZOutWindow.h
+# End Source File
+# End Group
+# Begin Group "LZMA"
+
+# PROP Default_Filter ""
+# Begin Source File
+
+SOURCE=..\..\Compress\LZMA\LZMA.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Compress\LZMA\LZMADecoder.cpp
+
+!IF  "$(CFG)" == "Alone - Win32 Release"
+
+# ADD CPP /O2
+# SUBTRACT CPP /YX /Yc /Yu
+
+!ELSEIF  "$(CFG)" == "Alone - Win32 Debug"
+
+!ELSEIF  "$(CFG)" == "Alone - Win32 ReleaseU"
+
+# ADD CPP /O2
+# SUBTRACT CPP /YX /Yc /Yu
+
+!ELSEIF  "$(CFG)" == "Alone - Win32 DebugU"
+
+!ENDIF 
+
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Compress\LZMA\LZMADecoder.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Compress\LZMA\LZMAEncoder.cpp
+
+!IF  "$(CFG)" == "Alone - Win32 Release"
+
+# ADD CPP /O2
+# SUBTRACT CPP /YX /Yc /Yu
+
+!ELSEIF  "$(CFG)" == "Alone - Win32 Debug"
+
+!ELSEIF  "$(CFG)" == "Alone - Win32 ReleaseU"
+
+# ADD CPP /O2
+# SUBTRACT CPP /YX /Yc /Yu
+
+!ELSEIF  "$(CFG)" == "Alone - Win32 DebugU"
+
+!ENDIF 
+
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Compress\LZMA\LZMAEncoder.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Compress\LZMA\LZMARegister.cpp
+# End Source File
+# End Group
+# Begin Group "RangeCoder"
+
+# PROP Default_Filter ""
+# Begin Source File
+
+SOURCE=..\..\Compress\RangeCoder\RangeCoder.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Compress\RangeCoder\RangeCoderBit.cpp
+
+!IF  "$(CFG)" == "Alone - Win32 Release"
+
+# ADD CPP /O1
+
+!ELSEIF  "$(CFG)" == "Alone - Win32 Debug"
+
+!ELSEIF  "$(CFG)" == "Alone - Win32 ReleaseU"
+
+# ADD CPP /O1
+
+!ELSEIF  "$(CFG)" == "Alone - Win32 DebugU"
+
+!ENDIF 
+
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Compress\RangeCoder\RangeCoderBit.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Compress\RangeCoder\RangeCoderBitTree.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Compress\RangeCoder\RangeCoderOpt.h
+# End Source File
+# End Group
+# Begin Group "LZMA_Alone"
+
+# PROP Default_Filter ""
+# Begin Source File
+
+SOURCE=..\..\Compress\LZMA_Alone\LzmaBench.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Compress\LZMA_Alone\LzmaBench.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Compress\LZMA_Alone\LzmaBenchCon.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Compress\LZMA_Alone\LzmaBenchCon.h
+# End Source File
+# End Group
+# End Group
+# Begin Group "Archive"
+
+# PROP Default_Filter ""
+# Begin Group "7z"
+
+# PROP Default_Filter ""
+# Begin Source File
+
+SOURCE=..\..\Archive\7z\7zCompressionMode.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Archive\7z\7zCompressionMode.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Archive\7z\7zDecode.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Archive\7z\7zDecode.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Archive\7z\7zEncode.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Archive\7z\7zEncode.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Archive\7z\7zExtract.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Archive\7z\7zFolderInStream.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Archive\7z\7zFolderInStream.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Archive\7z\7zFolderOutStream.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Archive\7z\7zFolderOutStream.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Archive\7z\7zHandler.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Archive\7z\7zHandler.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Archive\7z\7zHandlerOut.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Archive\7z\7zHeader.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Archive\7z\7zHeader.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Archive\7z\7zIn.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Archive\7z\7zIn.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Archive\7z\7zItem.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Archive\7z\7zOut.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Archive\7z\7zOut.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Archive\7z\7zProperties.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Archive\7z\7zProperties.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Archive\7z\7zRegister.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Archive\7z\7zSpecStream.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Archive\7z\7zSpecStream.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Archive\7z\7zUpdate.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Archive\7z\7zUpdate.h
+# End Source File
+# End Group
+# Begin Group "Archive Common"
+
+# PROP Default_Filter ""
+# Begin Source File
+
+SOURCE=..\..\Archive\Common\CoderMixer2.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Archive\Common\CoderMixer2.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Archive\Common\CoderMixer2MT.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Archive\Common\CoderMixer2MT.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Archive\Common\DummyOutStream.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Archive\Common\DummyOutStream.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Archive\Common\HandlerOut.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Archive\Common\HandlerOut.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Archive\Common\InStreamWithCRC.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Archive\Common\InStreamWithCRC.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Archive\Common\ItemNameUtils.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Archive\Common\ItemNameUtils.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Archive\Common\MultiStream.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Archive\Common\MultiStream.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Archive\Common\OutStreamWithCRC.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Archive\Common\OutStreamWithCRC.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Archive\Common\ParseProperties.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Archive\Common\ParseProperties.h
+# End Source File
+# End Group
+# Begin Group "split"
+
+# PROP Default_Filter ""
+# Begin Source File
+
+SOURCE=..\..\Archive\Split\SplitHandler.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Archive\Split\SplitHandler.h
+# End Source File
+# End Group
+# End Group
+# Begin Group "UI Common"
+
+# PROP Default_Filter ""
+# Begin Source File
+
+SOURCE=..\..\UI\Common\ArchiveCommandLine.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\UI\Common\ArchiveCommandLine.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\UI\Common\ArchiveExtractCallback.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\UI\Common\ArchiveExtractCallback.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\UI\Common\ArchiveOpenCallback.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\UI\Common\ArchiveOpenCallback.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\UI\Common\DefaultName.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\UI\Common\DefaultName.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\UI\Common\EnumDirItems.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\UI\Common\EnumDirItems.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\UI\Common\Extract.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\UI\Common\Extract.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\UI\Common\ExtractingFilePath.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\UI\Common\ExtractingFilePath.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\UI\Common\LoadCodecs.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\UI\Common\LoadCodecs.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\UI\Common\OpenArchive.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\UI\Common\OpenArchive.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\UI\Common\Property.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\UI\Common\PropIDUtils.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\UI\Common\PropIDUtils.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\UI\Common\SetProperties.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\UI\Common\SetProperties.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\UI\Common\SortUtils.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\UI\Common\SortUtils.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\UI\Common\TempFiles.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\UI\Common\TempFiles.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\UI\Common\Update.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\UI\Common\Update.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\UI\Common\UpdateAction.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\UI\Common\UpdateAction.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\UI\Common\UpdateCallback.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\UI\Common\UpdateCallback.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\UI\Common\UpdatePair.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\UI\Common\UpdatePair.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\UI\Common\UpdateProduce.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\UI\Common\UpdateProduce.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\UI\Common\WorkDir.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\UI\Common\WorkDir.h
+# End Source File
+# End Group
+# Begin Group "7-zip"
+
+# PROP Default_Filter ""
+# Begin Source File
+
+SOURCE=..\..\ICoder.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\IMyUnknown.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\IPassword.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\IProgress.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\IStream.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\PropID.h
+# End Source File
+# End Group
+# Begin Group "C"
+
+# PROP Default_Filter ""
+# Begin Group "C Branch"
+
+# PROP Default_Filter ""
+# Begin Source File
+
+SOURCE=..\..\..\..\C\Compress\Branch\BranchARM.c
+# SUBTRACT CPP /YX /Yc /Yu
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\..\C\Compress\Branch\BranchARM.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\..\C\Compress\Branch\BranchARMThumb.c
+# SUBTRACT CPP /YX /Yc /Yu
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\..\C\Compress\Branch\BranchARMThumb.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\..\C\Compress\Branch\BranchIA64.c
+# SUBTRACT CPP /YX /Yc /Yu
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\..\C\Compress\Branch\BranchIA64.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\..\C\Compress\Branch\BranchPPC.c
+# SUBTRACT CPP /YX /Yc /Yu
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\..\C\Compress\Branch\BranchPPC.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\..\C\Compress\Branch\BranchSPARC.c
+# SUBTRACT CPP /YX /Yc /Yu
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\..\C\Compress\Branch\BranchSPARC.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\..\C\Compress\Branch\BranchTypes.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\..\C\Compress\Branch\BranchX86.c
+# SUBTRACT CPP /YX /Yc /Yu
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\..\C\Compress\Branch\BranchX86.h
+# End Source File
+# End Group
+# Begin Source File
+
+SOURCE=..\..\..\..\C\7zCrc.c
+# SUBTRACT CPP /YX /Yc /Yu
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\..\C\7zCrc.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\..\C\Alloc.c
+# SUBTRACT CPP /YX /Yc /Yu
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\..\C\Alloc.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\..\C\IStream.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\..\C\Compress\Lz\LzHash.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\..\C\Compress\Lz\MatchFinder.c
+# SUBTRACT CPP /YX /Yc /Yu
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\..\C\Compress\Lz\MatchFinder.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\..\C\Compress\Lz\MatchFinderMt.c
+# SUBTRACT CPP /YX /Yc /Yu
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\..\C\Compress\Lz\MatchFinderMt.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\..\C\Threads.c
+# SUBTRACT CPP /YX /Yc /Yu
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\..\C\Threads.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\..\C\Types.h
+# End Source File
+# End Group
+# End Target
+# End Project
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/misc/libphysfs/lzma/CPP/7zip/Bundles/Alone7z/Alone.dsw	Mon Apr 10 12:06:43 2017 -0400
@@ -0,0 +1,29 @@
+Microsoft Developer Studio Workspace File, Format Version 6.00
+# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE!
+
+###############################################################################
+
+Project: "Alone"=.\Alone.dsp - Package Owner=<4>
+
+Package=<5>
+{{{
+}}}
+
+Package=<4>
+{{{
+}}}
+
+###############################################################################
+
+Global:
+
+Package=<5>
+{{{
+}}}
+
+Package=<3>
+{{{
+}}}
+
+###############################################################################
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/misc/libphysfs/lzma/CPP/7zip/Bundles/Alone7z/StdAfx.cpp	Mon Apr 10 12:06:43 2017 -0400
@@ -0,0 +1,3 @@
+// StdAfx.cpp
+
+#include "StdAfx.h"
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/misc/libphysfs/lzma/CPP/7zip/Bundles/Alone7z/StdAfx.h	Mon Apr 10 12:06:43 2017 -0400
@@ -0,0 +1,9 @@
+// StdAfx.h
+
+#ifndef __STDAFX_H
+#define __STDAFX_H
+
+#include "../../../Common/MyWindows.h"
+#include "../../../Common/NewHandler.h"
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/misc/libphysfs/lzma/CPP/7zip/Bundles/Alone7z/makefile	Mon Apr 10 12:06:43 2017 -0400
@@ -0,0 +1,236 @@
+PROG = 7za.exe
+LIBS = $(LIBS) user32.lib oleaut32.lib Advapi32.lib
+
+CFLAGS = $(CFLAGS) -I ../../../ \
+  -D_NO_CRYPTO \
+  -DWIN_LONG_PATH \
+  -DCOMPRESS_MT \
+  -DCOMPRESS_MF_MT \
+  -D_NO_CRYPTO \
+  -DBREAK_HANDLER \
+  -DBENCH_MT \
+
+
+CONSOLE_OBJS = \
+  $O\ConsoleClose.obj \
+  $O\ExtractCallbackConsole.obj \
+  $O\List.obj \
+  $O\Main.obj \
+  $O\MainAr.obj \
+  $O\OpenCallbackConsole.obj \
+  $O\PercentPrinter.obj \
+  $O\UpdateCallbackConsole.obj \
+  $O\UserInputUtils.obj \
+
+COMMON_OBJS = \
+  $O\CommandLineParser.obj \
+  $O\CRC.obj \
+  $O\IntToString.obj \
+  $O\ListFileUtils.obj \
+  $O\NewHandler.obj \
+  $O\StdInStream.obj \
+  $O\StdOutStream.obj \
+  $O\MyString.obj \
+  $O\StringConvert.obj \
+  $O\StringToInt.obj \
+  $O\UTFConvert.obj \
+  $O\MyVector.obj \
+  $O\Wildcard.obj \
+
+WIN_OBJS = \
+  $O\DLL.obj \
+  $O\Error.obj \
+  $O\FileDir.obj \
+  $O\FileFind.obj \
+  $O\FileIO.obj \
+  $O\FileName.obj \
+  $O\MemoryLock.obj \
+  $O\PropVariant.obj \
+  $O\PropVariantConversions.obj \
+  $O\Synchronization.obj \
+  $O\System.obj \
+
+7ZIP_COMMON_OBJS = \
+  $O\CreateCoder.obj \
+  $O\FilePathAutoRename.obj \
+  $O\FileStreams.obj \
+  $O\InBuffer.obj \
+  $O\InOutTempBuffer.obj \
+  $O\FilterCoder.obj \
+  $O\LimitedStreams.obj \
+  $O\LockedStream.obj \
+  $O\MethodId.obj \
+  $O\MethodProps.obj \
+  $O\OffsetStream.obj \
+  $O\OutBuffer.obj \
+  $O\ProgressUtils.obj \
+  $O\StreamBinder.obj \
+  $O\StreamObjects.obj \
+  $O\StreamUtils.obj \
+  $O\VirtThread.obj \
+
+UI_COMMON_OBJS = \
+  $O\ArchiveCommandLine.obj \
+  $O\ArchiveExtractCallback.obj \
+  $O\ArchiveOpenCallback.obj \
+  $O\DefaultName.obj \
+  $O\EnumDirItems.obj \
+  $O\Extract.obj \
+  $O\ExtractingFilePath.obj \
+  $O\LoadCodecs.obj \
+  $O\OpenArchive.obj \
+  $O\PropIDUtils.obj \
+  $O\SetProperties.obj \
+  $O\SortUtils.obj \
+  $O\TempFiles.obj \
+  $O\Update.obj \
+  $O\UpdateAction.obj \
+  $O\UpdateCallback.obj \
+  $O\UpdatePair.obj \
+  $O\UpdateProduce.obj \
+  $O\WorkDir.obj \
+
+AR_COMMON_OBJS = \
+  $O\CoderMixer2.obj \
+  $O\CoderMixer2MT.obj \
+  $O\CrossThreadProgress.obj \
+  $O\DummyOutStream.obj \
+  $O\HandlerOut.obj \
+  $O\InStreamWithCRC.obj \
+  $O\ItemNameUtils.obj \
+  $O\MultiStream.obj \
+  $O\OutStreamWithCRC.obj \
+  $O\ParseProperties.obj \
+
+
+7Z_OBJS = \
+  $O\7zCompressionMode.obj \
+  $O\7zDecode.obj \
+  $O\7zEncode.obj \
+  $O\7zExtract.obj \
+  $O\7zFolderInStream.obj \
+  $O\7zFolderOutStream.obj \
+  $O\7zHandler.obj \
+  $O\7zHandlerOut.obj \
+  $O\7zHeader.obj \
+  $O\7zIn.obj \
+  $O\7zOut.obj \
+  $O\7zProperties.obj \
+  $O\7zRegister.obj \
+  $O\7zSpecStream.obj \
+  $O\7zUpdate.obj \
+
+
+BRANCH_OPT_OBJS = \
+  $O\BranchCoder.obj \
+  $O\x86.obj \
+  $O\x86_2.obj \
+  $O\ARM.obj \
+  $O\ARMThumb.obj \
+  $O\IA64.obj \
+  $O\PPC.obj \
+  $O\SPARC.obj \
+  $O\BranchRegister.obj \
+  $O\BCJRegister.obj \
+  $O\BCJ2Register.obj \
+
+SWAP_OPT_OBJS = \
+  $O\ByteSwap.obj \
+  $O\ByteSwapRegister.obj \
+
+COPY_OBJS = \
+  $O\CopyCoder.obj \
+  $O\CopyRegister.obj \
+
+LZ_OBJS = \
+  $O\LZOutWindow.obj \
+
+LZMA_OPT_OBJS = \
+  $O\LZMADecoder.obj \
+  $O\LZMAEncoder.obj \
+  $O\LZMARegister.obj \
+
+LZMA_BENCH_OBJS = \
+  $O\LzmaBench.obj \
+  $O\LzmaBenchCon.obj \
+
+C_OBJS = \
+  $O\Alloc.obj \
+  $O\7zCrc.obj \
+  $O\Sort.obj \
+  $O\Threads.obj \
+
+C_LZ_OBJS = \
+  $O\MatchFinder.obj \
+  $O\MatchFinderMt.obj \
+
+C_BRANCH_OBJS = \
+  $O\BranchARM.obj \
+  $O\BranchARMThumb.obj \
+  $O\BranchIA64.obj \
+  $O\BranchPPC.obj \
+  $O\BranchSPARC.obj \
+  $O\BranchX86.obj \
+
+OBJS = \
+  $O\StdAfx.obj \
+  $(CONSOLE_OBJS) \
+  $(COMMON_OBJS) \
+  $(WIN_OBJS) \
+  $(7ZIP_COMMON_OBJS) \
+  $(UI_COMMON_OBJS) \
+  $(AR_COMMON_OBJS) \
+  $(7Z_OBJS) \
+  $(BRANCH_OPT_OBJS) \
+  $(SWAP_OPT_OBJS) \
+  $(COPY_OBJS) \
+  $(LZ_OBJS) \
+  $(LZMA_OPT_OBJS) \
+  $(LZMA_BENCH_OBJS) \
+  $(C_OBJS) \
+  $(C_LZ_OBJS) \
+  $(C_BRANCH_OBJS) \
+  $O\RangeCoderBit.obj \
+  $(CRC_OBJS) \
+  $O\resource.res
+
+
+!include "../../../Build.mak"
+
+$(CONSOLE_OBJS): ../../UI/Console/$(*B).cpp
+	$(COMPL)
+
+$(COMMON_OBJS): ../../../Common/$(*B).cpp
+	$(COMPL)
+$(WIN_OBJS): ../../../Windows/$(*B).cpp
+	$(COMPL)
+$(7ZIP_COMMON_OBJS): ../../Common/$(*B).cpp
+	$(COMPL)
+$(UI_COMMON_OBJS): ../../UI/Common/$(*B).cpp
+	$(COMPL)
+$(AR_COMMON_OBJS): ../../Archive/Common/$(*B).cpp
+	$(COMPL)
+
+$(7Z_OBJS): ../../Archive/7z/$(*B).cpp
+	$(COMPL)
+$(BRANCH_OPT_OBJS): ../../Compress/Branch/$(*B).cpp
+	$(COMPL_O2)
+$(SWAP_OPT_OBJS): ../../Compress/ByteSwap/$(*B).cpp
+	$(COMPL_O2)
+$(COPY_OBJS): ../../Compress/Copy/$(*B).cpp
+	$(COMPL)
+$(LZ_OBJS): ../../Compress/LZ/$(*B).cpp
+	$(COMPL)
+$(LZMA_OPT_OBJS): ../../Compress/LZMA/$(*B).cpp
+	$(COMPL_O2)
+$(LZMA_BENCH_OBJS): ../../Compress/LZMA_Alone/$(*B).cpp
+	$(COMPL)
+$O\RangeCoderBit.obj: ../../Compress/RangeCoder/$(*B).cpp
+	$(COMPL)
+
+$(C_OBJS): ../../../../C/$(*B).c
+	$(COMPL_O2)
+$(C_LZ_OBJS): ../../../../C/Compress/Lz/$(*B).c
+	$(COMPL_O2)
+$(C_BRANCH_OBJS): ../../../../C/Compress/Branch/$(*B).c
+	$(COMPL_O2)
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/misc/libphysfs/lzma/CPP/7zip/Bundles/Alone7z/resource.rc	Mon Apr 10 12:06:43 2017 -0400
@@ -0,0 +1,3 @@
+#include "../../MyVersionInfo.rc"
+
+MY_VERSION_INFO_APP("7-Zip Standalone Console", "7za")
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/misc/libphysfs/lzma/CPP/7zip/Bundles/Format7zExtractR/StdAfx.cpp	Mon Apr 10 12:06:43 2017 -0400
@@ -0,0 +1,3 @@
+// StdAfx.cpp
+
+#include "StdAfx.h"
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/misc/libphysfs/lzma/CPP/7zip/Bundles/Format7zExtractR/StdAfx.h	Mon Apr 10 12:06:43 2017 -0400
@@ -0,0 +1,9 @@
+// StdAfx.h
+
+#ifndef __STDAFX_H
+#define __STDAFX_H
+
+#include "../../../Common/MyWindows.h"
+#include "../../../Common/NewHandler.h"
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/misc/libphysfs/lzma/CPP/7zip/Bundles/Format7zExtractR/makefile	Mon Apr 10 12:06:43 2017 -0400
@@ -0,0 +1,165 @@
+PROG = 7zxr.dll
+DEF_FILE = ../../Archive/Archive2.def
+LIBS = $(LIBS) user32.lib oleaut32.lib
+CFLAGS = $(CFLAGS) -I ../../../ \
+  -DEXTRACT_ONLY \
+  -DCOMPRESS_MT \
+  -D_NO_CRYPTO
+
+COMMON_OBJS = \
+  $O\CRC.obj \
+  $O\IntToString.obj \
+  $O\NewHandler.obj \
+  $O\MyString.obj \
+  $O\StringConvert.obj \
+  $O\StringToInt.obj \
+  $O\MyVector.obj \
+  $O\Wildcard.obj \
+
+WIN_OBJS = \
+  $O\FileDir.obj \
+  $O\FileFind.obj \
+  $O\FileIO.obj \
+  $O\PropVariant.obj \
+  $O\Synchronization.obj \
+  $O\System.obj \
+
+7ZIP_COMMON_OBJS = \
+  $O\CreateCoder.obj \
+  $O\InBuffer.obj \
+  $O\InOutTempBuffer.obj \
+  $O\FilterCoder.obj \
+  $O\LimitedStreams.obj \
+  $O\LockedStream.obj \
+  $O\MethodId.obj \
+  $O\MethodProps.obj \
+  $O\OutBuffer.obj \
+  $O\ProgressUtils.obj \
+  $O\StreamBinder.obj \
+  $O\StreamObjects.obj \
+  $O\StreamUtils.obj \
+  $O\VirtThread.obj \
+
+AR_OBJS = \
+  $O\ArchiveExports.obj \
+  $O\DllExports2.obj \
+
+AR_COMMON_OBJS = \
+  $O\CoderMixer2.obj \
+  $O\CoderMixer2MT.obj \
+  $O\CrossThreadProgress.obj \
+  $O\HandlerOut.obj \
+  $O\ItemNameUtils.obj \
+  $O\OutStreamWithCRC.obj \
+  $O\ParseProperties.obj \
+
+
+7Z_OBJS = \
+  $O\7zCompressionMode.obj \
+  $O\7zDecode.obj \
+  $O\7zExtract.obj \
+  $O\7zFolderOutStream.obj \
+  $O\7zHandler.obj \
+  $O\7zHeader.obj \
+  $O\7zIn.obj \
+  $O\7zProperties.obj \
+  $O\7zRegister.obj \
+
+
+COMPRESS_OBJS = \
+  $O\CodecExports.obj \
+
+SWAP_OPT_OBJS = \
+  $O\ByteSwap.obj \
+  $O\ByteSwapRegister.obj \
+
+BRANCH_OPT_OBJS = \
+  $O\BranchCoder.obj \
+  $O\x86.obj \
+  $O\x86_2.obj \
+  $O\ARM.obj \
+  $O\ARMThumb.obj \
+  $O\IA64.obj \
+  $O\PPC.obj \
+  $O\SPARC.obj \
+  $O\BranchRegister.obj \
+  $O\BCJRegister.obj \
+  $O\BCJ2Register.obj \
+
+COPY_OBJS = \
+  $O\CopyCoder.obj \
+  $O\CopyRegister.obj \
+
+LZ_OBJS = \
+  $O\LZOutWindow.obj \
+
+LZMA_OPT_OBJS = \
+  $O\LZMADecoder.obj \
+  $O\LZMARegister.obj \
+
+C_OBJS = \
+  $O\Alloc.obj \
+  $O\7zCrc.obj \
+  $O\Threads.obj \
+
+C_BRANCH_OBJS = \
+  $O\BranchARM.obj \
+  $O\BranchARMThumb.obj \
+  $O\BranchIA64.obj \
+  $O\BranchPPC.obj \
+  $O\BranchSPARC.obj \
+  $O\BranchX86.obj \
+
+OBJS = \
+  $O\StdAfx.obj \
+  $(CONSOLE_OBJS) \
+  $(COMMON_OBJS) \
+  $(WIN_OBJS) \
+  $(7ZIP_COMMON_OBJS) \
+  $(AR_OBJS) \
+  $(AR_COMMON_OBJS) \
+  $(7Z_OBJS) \
+  $(COMPRESS_OBJS) \
+  $(BRANCH_OPT_OBJS) \
+  $(SWAP_OPT_OBJS) \
+  $(COPY_OBJS) \
+  $(LZ_OBJS) \
+  $(LZMA_OPT_OBJS) \
+  $(C_OBJS) \
+  $(C_BRANCH_OBJS) \
+  $O\resource.res
+
+
+!include "../../../Build.mak"
+
+$(COMMON_OBJS): ../../../Common/$(*B).cpp
+	$(COMPL)
+$(WIN_OBJS): ../../../Windows/$(*B).cpp
+	$(COMPL)
+$(7ZIP_COMMON_OBJS): ../../Common/$(*B).cpp
+	$(COMPL)
+$(AR_OBJS): ../../Archive/$(*B).cpp
+	$(COMPL)
+$(AR_COMMON_OBJS): ../../Archive/Common/$(*B).cpp
+	$(COMPL)
+
+$(7Z_OBJS): ../../Archive/7z/$(*B).cpp
+	$(COMPL)
+
+$(COMPRESS_OBJS): ../../Compress/$(*B).cpp
+	$(COMPL)
+$(BRANCH_OPT_OBJS): ../../Compress/Branch/$(*B).cpp
+	$(COMPL_O2)
+$(SWAP_OPT_OBJS): ../../Compress/ByteSwap/$(*B).cpp
+	$(COMPL_O2)
+$(COPY_OBJS): ../../Compress/Copy/$(*B).cpp
+	$(COMPL)
+$(LZ_OBJS): ../../Compress/LZ/$(*B).cpp
+	$(COMPL)
+$(LZMA_OPT_OBJS): ../../Compress/LZMA/$(*B).cpp
+	$(COMPL_O2)
+
+$(C_OBJS): ../../../../C/$(*B).c
+	$(COMPL_O2)
+$(C_BRANCH_OBJS): ../../../../C/Compress/Branch/$(*B).c
+	$(COMPL_O2)
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/misc/libphysfs/lzma/CPP/7zip/Bundles/Format7zExtractR/resource.rc	Mon Apr 10 12:06:43 2017 -0400
@@ -0,0 +1,5 @@
+#include "../../MyVersionInfo.rc"
+
+MY_VERSION_INFO_DLL("7z Standalone Extracting Plugin", "7zxr")
+
+101  ICON  "../../Archive/7z/7z.ico"
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/misc/libphysfs/lzma/CPP/7zip/Bundles/Format7zR/StdAfx.cpp	Mon Apr 10 12:06:43 2017 -0400
@@ -0,0 +1,3 @@
+// StdAfx.cpp
+
+#include "StdAfx.h"
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/misc/libphysfs/lzma/CPP/7zip/Bundles/Format7zR/StdAfx.h	Mon Apr 10 12:06:43 2017 -0400
@@ -0,0 +1,9 @@
+// StdAfx.h
+
+#ifndef __STDAFX_H
+#define __STDAFX_H
+
+#include "../../../Common/MyWindows.h"
+#include "../../../Common/NewHandler.h"
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/misc/libphysfs/lzma/CPP/7zip/Bundles/Format7zR/makefile	Mon Apr 10 12:06:43 2017 -0400
@@ -0,0 +1,188 @@
+PROG = 7zra.dll
+DEF_FILE = ../../Archive/Archive2.def
+LIBS = $(LIBS) user32.lib oleaut32.lib
+CFLAGS = $(CFLAGS) -I ../../../ \
+  -DCOMPRESS_MT \
+  -DCOMPRESS_MF_MT \
+  -D_NO_CRYPTO
+
+COMMON_OBJS = \
+  $O\CRC.obj \
+  $O\IntToString.obj \
+  $O\NewHandler.obj \
+  $O\MyString.obj \
+  $O\StringConvert.obj \
+  $O\StringToInt.obj \
+  $O\MyVector.obj \
+  $O\Wildcard.obj \
+
+WIN_OBJS = \
+  $O\FileDir.obj \
+  $O\FileFind.obj \
+  $O\FileIO.obj \
+  $O\PropVariant.obj \
+  $O\Synchronization.obj \
+  $O\System.obj \
+
+7ZIP_COMMON_OBJS = \
+  $O\CreateCoder.obj \
+  $O\InBuffer.obj \
+  $O\InOutTempBuffer.obj \
+  $O\FilterCoder.obj \
+  $O\LimitedStreams.obj \
+  $O\LockedStream.obj \
+  $O\MethodId.obj \
+  $O\MethodProps.obj \
+  $O\OutBuffer.obj \
+  $O\ProgressUtils.obj \
+  $O\StreamBinder.obj \
+  $O\StreamObjects.obj \
+  $O\StreamUtils.obj \
+  $O\VirtThread.obj \
+
+AR_OBJS = \
+  $O\ArchiveExports.obj \
+  $O\DllExports2.obj \
+
+AR_COMMON_OBJS = \
+  $O\CoderMixer2.obj \
+  $O\CoderMixer2MT.obj \
+  $O\CrossThreadProgress.obj \
+  $O\HandlerOut.obj \
+  $O\InStreamWithCRC.obj \
+  $O\ItemNameUtils.obj \
+  $O\OutStreamWithCRC.obj \
+  $O\ParseProperties.obj \
+
+
+7Z_OBJS = \
+  $O\7zCompressionMode.obj \
+  $O\7zDecode.obj \
+  $O\7zEncode.obj \
+  $O\7zExtract.obj \
+  $O\7zFolderInStream.obj \
+  $O\7zFolderOutStream.obj \
+  $O\7zHandler.obj \
+  $O\7zHandlerOut.obj \
+  $O\7zHeader.obj \
+  $O\7zIn.obj \
+  $O\7zOut.obj \
+  $O\7zProperties.obj \
+  $O\7zSpecStream.obj \
+  $O\7zUpdate.obj \
+  $O\7zRegister.obj \
+
+
+COMPRESS_OBJS = \
+  $O\CodecExports.obj \
+
+BRANCH_OPT_OBJS = \
+  $O\BranchCoder.obj \
+  $O\x86.obj \
+  $O\x86_2.obj \
+  $O\ARM.obj \
+  $O\ARMThumb.obj \
+  $O\IA64.obj \
+  $O\PPC.obj \
+  $O\SPARC.obj \
+  $O\BranchRegister.obj \
+  $O\BCJRegister.obj \
+  $O\BCJ2Register.obj \
+
+SWAP_OPT_OBJS = \
+  $O\ByteSwap.obj \
+  $O\ByteSwapRegister.obj \
+
+COPY_OBJS = \
+  $O\CopyCoder.obj \
+  $O\CopyRegister.obj \
+
+LZ_OBJS = \
+  $O\LZOutWindow.obj \
+
+LZMA_OPT_OBJS = \
+  $O\LZMADecoder.obj \
+  $O\LZMAEncoder.obj \
+  $O\LZMARegister.obj \
+
+C_OBJS = \
+  $O\Alloc.obj \
+  $O\7zCrc.obj \
+  $O\Sort.obj \
+  $O\Threads.obj \
+
+C_LZ_OBJS = \
+  $O\MatchFinder.obj \
+  $O\MatchFinderMt.obj \
+
+C_BRANCH_OBJS = \
+  $O\BranchARM.obj \
+  $O\BranchARMThumb.obj \
+  $O\BranchIA64.obj \
+  $O\BranchPPC.obj \
+  $O\BranchSPARC.obj \
+  $O\BranchX86.obj \
+
+OBJS = \
+  $O\StdAfx.obj \
+  $(CONSOLE_OBJS) \
+  $(COMMON_OBJS) \
+  $(WIN_OBJS) \
+  $(7ZIP_COMMON_OBJS) \
+  $(AR_OBJS) \
+  $(AR_COMMON_OBJS) \
+  $(7Z_OBJS) \
+  $(BZIP2_OBJS) \
+  $(BZIP2_OPT_OBJS) \
+  $(COMPRESS_OBJS) \
+  $(BRANCH_OPT_OBJS) \
+  $(SWAP_OPT_OBJS) \
+  $(COPY_OBJS) \
+  $(DEFLATE_OPT_OBJS) \
+  $(LZ_OBJS) \
+  $(LZMA_OPT_OBJS) \
+  $(PPMD_OPT_OBJS) \
+  $(C_OBJS) \
+  $(C_LZ_OBJS) \
+  $(C_BRANCH_OBJS) \
+  $O\RangeCoderBit.obj \
+  $O\resource.res
+
+
+!include "../../../Build.mak"
+
+$(COMMON_OBJS): ../../../Common/$(*B).cpp
+	$(COMPL)
+$(WIN_OBJS): ../../../Windows/$(*B).cpp
+	$(COMPL)
+$(7ZIP_COMMON_OBJS): ../../Common/$(*B).cpp
+	$(COMPL)
+$(AR_OBJS): ../../Archive/$(*B).cpp
+	$(COMPL)
+$(AR_COMMON_OBJS): ../../Archive/Common/$(*B).cpp
+	$(COMPL)
+
+$(7Z_OBJS): ../../Archive/7z/$(*B).cpp
+	$(COMPL)
+
+$(COMPRESS_OBJS): ../../Compress/$(*B).cpp
+	$(COMPL)
+$(BRANCH_OPT_OBJS): ../../Compress/Branch/$(*B).cpp
+	$(COMPL_O2)
+$(SWAP_OPT_OBJS): ../../Compress/ByteSwap/$(*B).cpp
+	$(COMPL_O2)
+$(COPY_OBJS): ../../Compress/Copy/$(*B).cpp
+	$(COMPL)
+$(LZ_OBJS): ../../Compress/LZ/$(*B).cpp
+	$(COMPL)
+$(LZMA_OPT_OBJS): ../../Compress/LZMA/$(*B).cpp
+	$(COMPL_O2)
+$O\RangeCoderBit.obj: ../../Compress/RangeCoder/$(*B).cpp
+	$(COMPL)
+
+$(C_OBJS): ../../../../C/$(*B).c
+	$(COMPL_O2)
+$(C_LZ_OBJS): ../../../../C/Compress/Lz/$(*B).c
+	$(COMPL_O2)
+$(C_BRANCH_OBJS): ../../../../C/Compress/Branch/$(*B).c
+	$(COMPL_O2)
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/misc/libphysfs/lzma/CPP/7zip/Bundles/Format7zR/resource.rc	Mon Apr 10 12:06:43 2017 -0400
@@ -0,0 +1,5 @@
+#include "../../MyVersionInfo.rc"
+
+MY_VERSION_INFO_DLL("7z Standalone Plugin", "7zr")
+
+101  ICON  "../../Archive/7z/7z.ico"
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/misc/libphysfs/lzma/CPP/7zip/Common/CreateCoder.cpp	Mon Apr 10 12:06:43 2017 -0400
@@ -0,0 +1,292 @@
+// CreateCoder.cpp
+
+#include "StdAfx.h"
+
+#include "CreateCoder.h"
+
+#include "../../Windows/PropVariant.h"
+#include "../../Windows/Defs.h"
+#include "FilterCoder.h"
+#include "RegisterCodec.h"
+
+static const unsigned int kNumCodecsMax = 64;
+unsigned int g_NumCodecs = 0;
+const CCodecInfo *g_Codecs[kNumCodecsMax]; 
+void RegisterCodec(const CCodecInfo *codecInfo) 
+{ 
+  if (g_NumCodecs < kNumCodecsMax)
+    g_Codecs[g_NumCodecs++] = codecInfo; 
+}
+
+#ifdef EXTERNAL_CODECS
+static HRESULT ReadNumberOfStreams(ICompressCodecsInfo *codecsInfo, UInt32 index, PROPID propID, UInt32 &res)
+{
+  NWindows::NCOM::CPropVariant prop;
+  RINOK(codecsInfo->GetProperty(index, propID, &prop));
+  if (prop.vt == VT_EMPTY)
+    res = 1;
+  else if (prop.vt == VT_UI4)
+    res = prop.ulVal;
+  else
+    return E_INVALIDARG;
+  return S_OK;
+}
+
+static HRESULT ReadIsAssignedProp(ICompressCodecsInfo *codecsInfo, UInt32 index, PROPID propID, bool &res)
+{
+  NWindows::NCOM::CPropVariant prop;
+  RINOK(codecsInfo->GetProperty(index, propID, &prop));
+  if (prop.vt == VT_EMPTY)
+    res = true;
+  else if (prop.vt == VT_BOOL)
+    res = VARIANT_BOOLToBool(prop.boolVal);
+  else
+    return E_INVALIDARG;
+  return S_OK;
+}
+
+HRESULT LoadExternalCodecs(ICompressCodecsInfo *codecsInfo, CObjectVector<CCodecInfoEx> &externalCodecs)
+{
+  UInt32 num;
+  RINOK(codecsInfo->GetNumberOfMethods(&num));
+  for (UInt32 i = 0; i < num; i++)
+  {
+    CCodecInfoEx info;
+    NWindows::NCOM::CPropVariant prop;
+    RINOK(codecsInfo->GetProperty(i, NMethodPropID::kID, &prop));
+    // if (prop.vt != VT_BSTR)
+    // info.Id.IDSize = (Byte)SysStringByteLen(prop.bstrVal);
+    // memmove(info.Id.ID, prop.bstrVal, info.Id.IDSize);
+    if (prop.vt != VT_UI8)
+    {
+      continue; // old Interface 
+      // return E_INVALIDARG;
+    }
+    info.Id = prop.uhVal.QuadPart;
+    prop.Clear();
+    
+    RINOK(codecsInfo->GetProperty(i, NMethodPropID::kName, &prop));
+    if (prop.vt == VT_BSTR)
+      info.Name = prop.bstrVal;
+    else if (prop.vt != VT_EMPTY)
+      return E_INVALIDARG;;
+    
+    RINOK(ReadNumberOfStreams(codecsInfo, i, NMethodPropID::kInStreams, info.NumInStreams));
+    RINOK(ReadNumberOfStreams(codecsInfo, i, NMethodPropID::kOutStreams, info.NumOutStreams));
+    RINOK(ReadIsAssignedProp(codecsInfo, i, NMethodPropID::kEncoderIsAssigned, info.EncoderIsAssigned));
+    RINOK(ReadIsAssignedProp(codecsInfo, i, NMethodPropID::kDecoderIsAssigned, info.DecoderIsAssigned));
+    
+    externalCodecs.Add(info);
+  }
+  return S_OK;
+}
+
+#endif
+
+bool FindMethod(
+  #ifdef EXTERNAL_CODECS
+  ICompressCodecsInfo * /* codecsInfo */, const CObjectVector<CCodecInfoEx> *externalCodecs,
+  #endif
+  const UString &name,
+  CMethodId &methodId, UInt32 &numInStreams, UInt32 &numOutStreams)
+{
+  UInt32 i;
+  for (i = 0; i < g_NumCodecs; i++)
+  {
+    const CCodecInfo &codec = *g_Codecs[i]; 
+    if (name.CompareNoCase(codec.Name) == 0)
+    {
+      methodId = codec.Id;
+      numInStreams = codec.NumInStreams;
+      numOutStreams = 1;
+      return true;
+    }
+  }
+  #ifdef EXTERNAL_CODECS
+  if (externalCodecs)
+    for (i = 0; i < (UInt32)externalCodecs->Size(); i++)
+    {
+      const CCodecInfoEx &codec = (*externalCodecs)[i]; 
+      if (codec.Name.CompareNoCase(name) == 0)
+      {
+        methodId = codec.Id;
+        numInStreams = codec.NumInStreams;
+        numOutStreams = codec.NumOutStreams;
+        return true;
+      }
+    }
+  #endif
+  return false;
+}
+
+bool FindMethod(
+  #ifdef EXTERNAL_CODECS
+  ICompressCodecsInfo * /* codecsInfo */, const CObjectVector<CCodecInfoEx> *externalCodecs,
+  #endif
+  CMethodId methodId, UString &name)
+{
+  UInt32 i;
+  for (i = 0; i < g_NumCodecs; i++)
+  {
+    const CCodecInfo &codec = *g_Codecs[i]; 
+    if (methodId == codec.Id)
+    {
+      name = codec.Name;
+      return true;
+    }
+  }
+  #ifdef EXTERNAL_CODECS
+  if (externalCodecs)
+    for (i = 0; i < (UInt32)externalCodecs->Size(); i++)
+    {
+      const CCodecInfoEx &codec = (*externalCodecs)[i]; 
+      if (methodId == codec.Id)
+      {
+        name = codec.Name;
+        return true;
+      }
+    }
+  #endif
+  return false;
+}
+
+HRESULT CreateCoder(
+  DECL_EXTERNAL_CODECS_LOC_VARS
+  CMethodId methodId,
+  CMyComPtr<ICompressFilter> &filter,
+  CMyComPtr<ICompressCoder> &coder,
+  CMyComPtr<ICompressCoder2> &coder2,
+  bool encode, bool onlyCoder)
+{
+  bool created = false;
+  UInt32 i;
+  for (i = 0; i < g_NumCodecs; i++)
+  {
+    const CCodecInfo &codec = *g_Codecs[i]; 
+    if (codec.Id == methodId)
+    {
+      if (encode)
+      {
+        if (codec.CreateEncoder)
+        {
+          void *p = codec.CreateEncoder();
+          if (codec.IsFilter) filter = (ICompressFilter *)p;
+          else if (codec.NumInStreams == 1) coder = (ICompressCoder *)p;
+          else coder2 = (ICompressCoder2 *)p;
+          created = (p != 0);
+          break;
+        }
+      }
+      else
+        if (codec.CreateDecoder)
+        {
+          void *p = codec.CreateDecoder();
+          if (codec.IsFilter) filter = (ICompressFilter *)p;
+          else if (codec.NumInStreams == 1) coder = (ICompressCoder *)p;
+          else coder2 = (ICompressCoder2 *)p;
+          created = (p != 0);
+          break;
+        }
+    }
+  }
+
+  #ifdef EXTERNAL_CODECS
+  if (!created && externalCodecs)
+    for (i = 0; i < (UInt32)externalCodecs->Size(); i++)
+    {
+      const CCodecInfoEx &codec = (*externalCodecs)[i]; 
+      if (codec.Id == methodId)
+      {
+        if (encode)
+        {
+          if (codec.EncoderIsAssigned)
+          {
+            if (codec.IsSimpleCodec())
+            {
+              HRESULT result = codecsInfo->CreateEncoder(i, &IID_ICompressCoder, (void **)&coder);
+              if (result != S_OK && result != E_NOINTERFACE && result != CLASS_E_CLASSNOTAVAILABLE) 
+                return result;
+              if (!coder)
+              {
+                RINOK(codecsInfo->CreateEncoder(i, &IID_ICompressFilter, (void **)&filter));
+              }
+            }
+            else
+            {
+              RINOK(codecsInfo->CreateEncoder(i, &IID_ICompressCoder2, (void **)&coder2));
+            }
+            break;
+          }
+        }
+        else
+          if (codec.DecoderIsAssigned)
+          {
+            if (codec.IsSimpleCodec())
+            {
+              HRESULT result = codecsInfo->CreateDecoder(i, &IID_ICompressCoder, (void **)&coder);
+              if (result != S_OK && result != E_NOINTERFACE && result != CLASS_E_CLASSNOTAVAILABLE) 
+                return result;
+              if (!coder)
+              {
+                RINOK(codecsInfo->CreateDecoder(i, &IID_ICompressFilter, (void **)&filter));
+              }
+            }
+            else
+            {
+              RINOK(codecsInfo->CreateDecoder(i, &IID_ICompressCoder2, (void **)&coder2));
+            }
+            break;
+          }
+      }
+    }
+  #endif
+
+  if (onlyCoder && filter)
+  {
+    CFilterCoder *coderSpec = new CFilterCoder;
+    coder = coderSpec;
+    coderSpec->Filter = filter;
+  }
+  return S_OK;
+}
+
+HRESULT CreateCoder(
+  DECL_EXTERNAL_CODECS_LOC_VARS
+  CMethodId methodId,
+  CMyComPtr<ICompressCoder> &coder, 
+  CMyComPtr<ICompressCoder2> &coder2,
+  bool encode)
+{
+  CMyComPtr<ICompressFilter> filter;
+  return CreateCoder(
+    EXTERNAL_CODECS_LOC_VARS
+    methodId,
+    filter, coder, coder2, encode, true);
+}
+
+HRESULT CreateCoder(
+  DECL_EXTERNAL_CODECS_LOC_VARS
+  CMethodId methodId,
+  CMyComPtr<ICompressCoder> &coder, bool encode)
+{
+  CMyComPtr<ICompressFilter> filter;
+  CMyComPtr<ICompressCoder2> coder2;
+  return CreateCoder(
+    EXTERNAL_CODECS_LOC_VARS
+    methodId,
+    coder, coder2, encode);
+}
+
+HRESULT CreateFilter(
+  DECL_EXTERNAL_CODECS_LOC_VARS
+  CMethodId methodId,
+  CMyComPtr<ICompressFilter> &filter,
+  bool encode)
+{
+  CMyComPtr<ICompressCoder> coder;
+  CMyComPtr<ICompressCoder2> coder2;
+  return CreateCoder(
+    EXTERNAL_CODECS_LOC_VARS
+    methodId,
+    filter, coder, coder2, encode, false);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/misc/libphysfs/lzma/CPP/7zip/Common/CreateCoder.h	Mon Apr 10 12:06:43 2017 -0400
@@ -0,0 +1,98 @@
+// CreateCoder.h
+
+#ifndef __CREATECODER_H
+#define __CREATECODER_H
+
+#include "Common/MyCom.h"
+#include "Common/MyString.h"
+#include "../ICoder.h"
+
+#include "MethodId.h"
+
+#ifdef EXTERNAL_CODECS
+
+struct CCodecInfoEx
+{
+  UString Name;
+  CMethodId Id;
+  UInt32 NumInStreams;
+  UInt32 NumOutStreams;
+  bool EncoderIsAssigned;
+  bool DecoderIsAssigned;
+  bool IsSimpleCodec() const { return NumOutStreams == 1 && NumInStreams == 1; }
+  CCodecInfoEx(): EncoderIsAssigned(false), DecoderIsAssigned(false) {}
+};
+
+HRESULT LoadExternalCodecs(ICompressCodecsInfo *codecsInfo, CObjectVector<CCodecInfoEx> &externalCodecs);
+
+#define PUBLIC_ISetCompressCodecsInfo public ISetCompressCodecsInfo,
+#define QUERY_ENTRY_ISetCompressCodecsInfo MY_QUERYINTERFACE_ENTRY(ISetCompressCodecsInfo)
+#define DECL_ISetCompressCodecsInfo STDMETHOD(SetCompressCodecsInfo)(ICompressCodecsInfo *compressCodecsInfo);
+#define IMPL_ISetCompressCodecsInfo2(x) \
+STDMETHODIMP x::SetCompressCodecsInfo(ICompressCodecsInfo *compressCodecsInfo) { \
+  COM_TRY_BEGIN _codecsInfo = compressCodecsInfo;  return LoadExternalCodecs(_codecsInfo, _externalCodecs); COM_TRY_END }
+#define IMPL_ISetCompressCodecsInfo IMPL_ISetCompressCodecsInfo2(CHandler)
+
+#define EXTERNAL_CODECS_VARS2 _codecsInfo, &_externalCodecs
+
+#define DECL_EXTERNAL_CODECS_VARS CMyComPtr<ICompressCodecsInfo> _codecsInfo; CObjectVector<CCodecInfoEx> _externalCodecs;
+#define EXTERNAL_CODECS_VARS EXTERNAL_CODECS_VARS2,
+
+#define DECL_EXTERNAL_CODECS_LOC_VARS2 ICompressCodecsInfo *codecsInfo, const CObjectVector<CCodecInfoEx> *externalCodecs
+#define EXTERNAL_CODECS_LOC_VARS2 codecsInfo, externalCodecs
+
+#define DECL_EXTERNAL_CODECS_LOC_VARS DECL_EXTERNAL_CODECS_LOC_VARS2,
+#define EXTERNAL_CODECS_LOC_VARS EXTERNAL_CODECS_LOC_VARS2,
+
+#else
+
+#define PUBLIC_ISetCompressCodecsInfo
+#define QUERY_ENTRY_ISetCompressCodecsInfo
+#define DECL_ISetCompressCodecsInfo
+#define IMPL_ISetCompressCodecsInfo
+#define EXTERNAL_CODECS_VARS2
+#define DECL_EXTERNAL_CODECS_VARS
+#define EXTERNAL_CODECS_VARS EXTERNAL_CODECS_VARS2
+#define DECL_EXTERNAL_CODECS_LOC_VARS2
+#define EXTERNAL_CODECS_LOC_VARS2
+#define DECL_EXTERNAL_CODECS_LOC_VARS
+#define EXTERNAL_CODECS_LOC_VARS
+
+#endif
+
+bool FindMethod(
+  DECL_EXTERNAL_CODECS_LOC_VARS
+  const UString &name, CMethodId &methodId, UInt32 &numInStreams, UInt32 &numOutStreams);
+
+bool FindMethod(
+  DECL_EXTERNAL_CODECS_LOC_VARS
+  CMethodId methodId, UString &name);
+
+
+HRESULT CreateCoder(
+  DECL_EXTERNAL_CODECS_LOC_VARS
+  CMethodId methodId,
+  CMyComPtr<ICompressFilter> &filter,
+  CMyComPtr<ICompressCoder> &coder,
+  CMyComPtr<ICompressCoder2> &coder2,
+  bool encode, bool onlyCoder);
+
+HRESULT CreateCoder(
+  DECL_EXTERNAL_CODECS_LOC_VARS
+  CMethodId methodId,
+  CMyComPtr<ICompressCoder> &coder,
+  CMyComPtr<ICompressCoder2> &coder2,
+  bool encode);
+
+HRESULT CreateCoder(
+  DECL_EXTERNAL_CODECS_LOC_VARS
+  CMethodId methodId, 
+  CMyComPtr<ICompressCoder> &coder, bool encode);
+
+HRESULT CreateFilter(
+  DECL_EXTERNAL_CODECS_LOC_VARS
+  CMethodId methodId,
+  CMyComPtr<ICompressFilter> &filter,
+  bool encode);
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/misc/libphysfs/lzma/CPP/7zip/Common/FilePathAutoRename.cpp	Mon Apr 10 12:06:43 2017 -0400
@@ -0,0 +1,57 @@
+// FilePathAutoRename.cpp
+
+#include "StdAfx.h"
+#include "FilePathAutoRename.h"
+
+#include "Common/Defs.h"
+#include "Common/IntToString.h"
+
+#include "Windows/FileName.h"
+#include "Windows/FileFind.h"
+
+using namespace NWindows;
+
+static bool MakeAutoName(const UString &name, 
+    const UString &extension, int value, UString &path)
+{
+  wchar_t number[32];
+  ConvertUInt64ToString(value, number);
+  path = name;
+  path += number;
+  path += extension;
+  return NFile::NFind::DoesFileExist(path);
+}
+
+bool AutoRenamePath(UString &fullProcessedPath)
+{
+  UString path;
+  int dotPos = fullProcessedPath.ReverseFind(L'.');
+
+  int slashPos = fullProcessedPath.ReverseFind(L'/');
+  #ifdef _WIN32
+  int slash1Pos = fullProcessedPath.ReverseFind(L'\\');
+  slashPos = MyMax(slashPos, slash1Pos);
+  #endif
+
+  UString name, extension;
+  if (dotPos > slashPos &&  dotPos > 0)
+  {
+    name = fullProcessedPath.Left(dotPos);
+    extension = fullProcessedPath.Mid(dotPos);
+  }
+  else
+    name = fullProcessedPath;
+  name += L'_';
+  int indexLeft = 1, indexRight = (1 << 30);
+  while (indexLeft != indexRight)
+  {
+    int indexMid = (indexLeft + indexRight) / 2;
+    if (MakeAutoName(name, extension, indexMid, path))
+      indexLeft = indexMid + 1;
+    else
+      indexRight = indexMid;
+  }
+  if (MakeAutoName(name, extension, indexRight, fullProcessedPath))
+    return false;
+  return true;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/misc/libphysfs/lzma/CPP/7zip/Common/FilePathAutoRename.h	Mon Apr 10 12:06:43 2017 -0400
@@ -0,0 +1,10 @@
+// Util/FilePathAutoRename.h
+
+#ifndef __FILEPATHAUTORENAME_H
+#define __FILEPATHAUTORENAME_H
+
+#include "Common/MyString.h"
+
+bool AutoRenamePath(UString &fullProcessedPath);
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/misc/libphysfs/lzma/CPP/7zip/Common/FileStreams.cpp	Mon Apr 10 12:06:43 2017 -0400
@@ -0,0 +1,261 @@
+// FileStreams.cpp
+
+#include "StdAfx.h"
+
+#ifndef _WIN32
+#include <fcntl.h>
+#include <unistd.h>
+#include <errno.h>
+#endif
+
+#include "FileStreams.h"
+
+static inline HRESULT ConvertBoolToHRESULT(bool result)
+{
+  #ifdef _WIN32
+  if (result)
+    return S_OK;
+  DWORD lastError = ::GetLastError();
+  if (lastError == 0)
+    return E_FAIL;
+  return lastError;
+  #else
+  return result ? S_OK: E_FAIL;
+  #endif
+}
+
+bool CInFileStream::Open(LPCTSTR fileName)
+{
+  return File.Open(fileName);
+}
+
+#ifdef USE_WIN_FILE
+#ifndef _UNICODE
+bool CInFileStream::Open(LPCWSTR fileName)
+{
+  return File.Open(fileName);
+}
+#endif
+#endif
+
+bool CInFileStream::OpenShared(LPCTSTR fileName, bool shareForWrite)
+{
+  return File.OpenShared(fileName, shareForWrite);
+}
+
+#ifdef USE_WIN_FILE
+#ifndef _UNICODE
+bool CInFileStream::OpenShared(LPCWSTR fileName, bool shareForWrite)
+{
+  return File.OpenShared(fileName, shareForWrite);
+}
+#endif
+#endif
+
+STDMETHODIMP CInFileStream::Read(void *data, UInt32 size, UInt32 *processedSize)
+{
+  #ifdef USE_WIN_FILE
+  
+  UInt32 realProcessedSize;
+  bool result = File.ReadPart(data, size, realProcessedSize);
+  if(processedSize != NULL)
+    *processedSize = realProcessedSize;
+  return ConvertBoolToHRESULT(result);
+  
+  #else
+  
+  if(processedSize != NULL)
+    *processedSize = 0;
+  ssize_t res = File.Read(data, (size_t)size);
+  if (res == -1)
+    return E_FAIL;
+  if(processedSize != NULL)
+    *processedSize = (UInt32)res;
+  return S_OK;
+
+  #endif
+}
+
+#ifndef _WIN32_WCE
+STDMETHODIMP CStdInFileStream::Read(void *data, UInt32 size, UInt32 *processedSize)
+{
+  #ifdef _WIN32
+  UInt32 realProcessedSize;
+  BOOL res = ::ReadFile(GetStdHandle(STD_INPUT_HANDLE), 
+      data, size, (DWORD *)&realProcessedSize, NULL);
+  if(processedSize != NULL)
+    *processedSize = realProcessedSize;
+  if (res == FALSE && GetLastError() == ERROR_BROKEN_PIPE)
+    return S_OK;
+  return ConvertBoolToHRESULT(res != FALSE);
+  
+  #else
+
+  if(processedSize != NULL)
+    *processedSize = 0;
+  ssize_t res;
+  do 
+  {
+    res = read(0, data, (size_t)size);
+  } 
+  while (res < 0 && (errno == EINTR));
+  if (res == -1)
+    return E_FAIL;
+  if(processedSize != NULL)
+    *processedSize = (UInt32)res;
+  return S_OK;
+  
+  #endif
+}
+  
+#endif
+
+STDMETHODIMP CInFileStream::Seek(Int64 offset, UInt32 seekOrigin, 
+    UInt64 *newPosition)
+{
+  if(seekOrigin >= 3)
+    return STG_E_INVALIDFUNCTION;
+
+  #ifdef USE_WIN_FILE
+
+  UInt64 realNewPosition;
+  bool result = File.Seek(offset, seekOrigin, realNewPosition);
+  if(newPosition != NULL)
+    *newPosition = realNewPosition;
+  return ConvertBoolToHRESULT(result);
+  
+  #else
+  
+  off_t res = File.Seek(offset, seekOrigin);
+  if (res == -1)
+    return E_FAIL;
+  if(newPosition != NULL)
+    *newPosition = (UInt64)res;
+  return S_OK;
+  
+  #endif
+}
+
+STDMETHODIMP CInFileStream::GetSize(UInt64 *size)
+{
+  return ConvertBoolToHRESULT(File.GetLength(*size));
+}
+
+
+//////////////////////////
+// COutFileStream
+
+HRESULT COutFileStream::Close()
+{
+  return ConvertBoolToHRESULT(File.Close());
+}
+
+STDMETHODIMP COutFileStream::Write(const void *data, UInt32 size, UInt32 *processedSize)
+{
+  #ifdef USE_WIN_FILE
+
+  UInt32 realProcessedSize;
+  bool result = File.WritePart(data, size, realProcessedSize);
+  ProcessedSize += realProcessedSize;
+  if(processedSize != NULL)
+    *processedSize = realProcessedSize;
+  return ConvertBoolToHRESULT(result);
+  
+  #else
+  
+  if(processedSize != NULL)
+    *processedSize = 0;
+  ssize_t res = File.Write(data, (size_t)size);
+  if (res == -1)
+    return E_FAIL;
+  if(processedSize != NULL)
+    *processedSize = (UInt32)res;
+  ProcessedSize += res;
+  return S_OK;
+  
+  #endif
+}
+  
+STDMETHODIMP COutFileStream::Seek(Int64 offset, UInt32 seekOrigin, UInt64 *newPosition)
+{
+  if(seekOrigin >= 3)
+    return STG_E_INVALIDFUNCTION;
+  #ifdef USE_WIN_FILE
+
+  UInt64 realNewPosition;
+  bool result = File.Seek(offset, seekOrigin, realNewPosition);
+  if(newPosition != NULL)
+    *newPosition = realNewPosition;
+  return ConvertBoolToHRESULT(result);
+  
+  #else
+  
+  off_t res = File.Seek(offset, seekOrigin);
+  if (res == -1)
+    return E_FAIL;
+  if(newPosition != NULL)
+    *newPosition = (UInt64)res;
+  return S_OK;
+  
+  #endif
+}
+
+STDMETHODIMP COutFileStream::SetSize(Int64 newSize)
+{
+  #ifdef USE_WIN_FILE
+  UInt64 currentPos;
+  if(!File.Seek(0, FILE_CURRENT, currentPos))
+    return E_FAIL;
+  bool result = File.SetLength(newSize);
+  UInt64 currentPos2;
+  result = result && File.Seek(currentPos, currentPos2);
+  return result ? S_OK : E_FAIL;
+  #else
+  return E_FAIL;
+  #endif
+}
+
+#ifndef _WIN32_WCE
+STDMETHODIMP CStdOutFileStream::Write(const void *data, UInt32 size, UInt32 *processedSize)
+{
+  if(processedSize != NULL)
+    *processedSize = 0;
+
+  #ifdef _WIN32
+  UInt32 realProcessedSize;
+  BOOL res = TRUE;
+  if (size > 0)
+  {
+    // Seems that Windows doesn't like big amounts writing to stdout.
+    // So we limit portions by 32KB.
+    UInt32 sizeTemp = (1 << 15); 
+    if (sizeTemp > size)
+      sizeTemp = size;
+    res = ::WriteFile(GetStdHandle(STD_OUTPUT_HANDLE), 
+        data, sizeTemp, (DWORD *)&realProcessedSize, NULL);
+    size -= realProcessedSize;
+    data = (const void *)((const Byte *)data + realProcessedSize);
+    if(processedSize != NULL)
+      *processedSize += realProcessedSize;
+  }
+  return ConvertBoolToHRESULT(res != FALSE);
+
+  #else
+  
+  ssize_t res;
+  do 
+  {
+    res = write(1, data, (size_t)size);
+  } 
+  while (res < 0 && (errno == EINTR));
+  if (res == -1)
+    return E_FAIL;
+  if(processedSize != NULL)
+    *processedSize = (UInt32)res;
+  return S_OK;
+  
+  return S_OK;
+  #endif
+}
+  
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/misc/libphysfs/lzma/CPP/7zip/Common/FileStreams.h	Mon Apr 10 12:06:43 2017 -0400
@@ -0,0 +1,143 @@
+// FileStreams.h
+
+#ifndef __FILESTREAMS_H
+#define __FILESTREAMS_H
+
+#ifdef _WIN32
+#define USE_WIN_FILE
+#endif
+
+#ifdef USE_WIN_FILE
+#include "../../Windows/FileIO.h"
+#else
+#include "../../Common/C_FileIO.h"
+#endif
+
+#include "../IStream.h"
+#include "../../Common/MyCom.h"
+
+class CInFileStream: 
+  public IInStream,
+  public IStreamGetSize,
+  public CMyUnknownImp
+{
+public:
+  #ifdef USE_WIN_FILE
+  NWindows::NFile::NIO::CInFile File;
+  #else
+  NC::NFile::NIO::CInFile File;
+  #endif
+  CInFileStream() {}
+  virtual ~CInFileStream() {}
+
+  bool Open(LPCTSTR fileName);
+  #ifdef USE_WIN_FILE
+  #ifndef _UNICODE
+  bool Open(LPCWSTR fileName);
+  #endif
+  #endif
+
+  bool OpenShared(LPCTSTR fileName, bool shareForWrite);
+  #ifdef USE_WIN_FILE
+  #ifndef _UNICODE
+  bool OpenShared(LPCWSTR fileName, bool shareForWrite);
+  #endif
+  #endif
+
+  MY_UNKNOWN_IMP2(IInStream, IStreamGetSize)
+
+  STDMETHOD(Read)(void *data, UInt32 size, UInt32 *processedSize);
+  STDMETHOD(Seek)(Int64 offset, UInt32 seekOrigin, UInt64 *newPosition);
+
+  STDMETHOD(GetSize)(UInt64 *size);
+};
+
+#ifndef _WIN32_WCE
+class CStdInFileStream: 
+  public ISequentialInStream,
+  public CMyUnknownImp
+{
+public:
+  // HANDLE File;
+  // CStdInFileStream() File(INVALID_HANDLE_VALUE): {}
+  // void Open() { File = GetStdHandle(STD_INPUT_HANDLE); };
+  MY_UNKNOWN_IMP
+
+  virtual ~CStdInFileStream() {}
+  STDMETHOD(Read)(void *data, UInt32 size, UInt32 *processedSize);
+};
+#endif
+
+class COutFileStream: 
+  public IOutStream,
+  public CMyUnknownImp
+{
+  #ifdef USE_WIN_FILE
+  NWindows::NFile::NIO::COutFile File;
+  #else
+  NC::NFile::NIO::COutFile File;
+  #endif
+public:
+  virtual ~COutFileStream() {}
+  bool Create(LPCTSTR fileName, bool createAlways)
+  {
+    ProcessedSize = 0;
+    return File.Create(fileName, createAlways);
+  }
+  bool Open(LPCTSTR fileName, DWORD creationDisposition)
+  {
+    ProcessedSize = 0;
+    return File.Open(fileName, creationDisposition);
+  }
+  #ifdef USE_WIN_FILE
+  #ifndef _UNICODE
+  bool Create(LPCWSTR fileName, bool createAlways)
+  {
+    ProcessedSize = 0;
+    return File.Create(fileName, createAlways);
+  }
+  bool Open(LPCWSTR fileName, DWORD creationDisposition)
+  {
+    ProcessedSize = 0;
+    return File.Open(fileName, creationDisposition);
+  }
+  #endif
+  #endif
+
+  HRESULT Close();
+  
+  UInt64 ProcessedSize;
+
+  #ifdef USE_WIN_FILE
+  bool SetTime(const FILETIME *creationTime, const FILETIME *lastAccessTime, const FILETIME *lastWriteTime)
+  {
+    return File.SetTime(creationTime, lastAccessTime, lastWriteTime);
+  }
+  bool SetLastWriteTime(const FILETIME *lastWriteTime)
+  {
+    return File.SetLastWriteTime(lastWriteTime);
+  }
+  #endif
+
+
+  MY_UNKNOWN_IMP1(IOutStream)
+
+  STDMETHOD(Write)(const void *data, UInt32 size, UInt32 *processedSize);
+  STDMETHOD(Seek)(Int64 offset, UInt32 seekOrigin, UInt64 *newPosition);
+  STDMETHOD(SetSize)(Int64 newSize);
+};
+
+#ifndef _WIN32_WCE
+class CStdOutFileStream: 
+  public ISequentialOutStream,
+  public CMyUnknownImp
+{
+public:
+  MY_UNKNOWN_IMP
+
+  virtual ~CStdOutFileStream() {}
+  STDMETHOD(Write)(const void *data, UInt32 size, UInt32 *processedSize);
+};
+#endif
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/misc/libphysfs/lzma/CPP/7zip/Common/FilterCoder.cpp	Mon Apr 10 12:06:43 2017 -0400
@@ -0,0 +1,264 @@
+// FilterCoder.cpp
+
+#include "StdAfx.h"
+
+#include "FilterCoder.h"
+extern "C" 
+{ 
+#include "../../../C/Alloc.h"
+}
+#include "../../Common/Defs.h"
+#include "StreamUtils.h"
+
+static const UInt32 kBufferSize = 1 << 17;
+
+CFilterCoder::CFilterCoder()
+{ 
+  _buffer = (Byte *)::MidAlloc(kBufferSize); 
+}
+
+CFilterCoder::~CFilterCoder() 
+{ 
+  ::MidFree(_buffer); 
+}
+
+HRESULT CFilterCoder::WriteWithLimit(ISequentialOutStream *outStream, UInt32 size)
+{
+  if (_outSizeIsDefined)
+  {
+    UInt64 remSize = _outSize - _nowPos64;
+    if (size > remSize)
+      size = (UInt32)remSize;
+  }
+  UInt32 processedSize = 0;
+  RINOK(WriteStream(outStream, _buffer, size, &processedSize));
+  if (size != processedSize)
+    return E_FAIL;
+  _nowPos64 += processedSize;
+  return S_OK;
+}
+
+
+STDMETHODIMP CFilterCoder::Code(ISequentialInStream *inStream,
+      ISequentialOutStream *outStream, const UInt64 * /* inSize */, const UInt64 *outSize,
+      ICompressProgressInfo *progress)
+{
+  RINOK(Init());
+  UInt32 bufferPos = 0;
+  _outSizeIsDefined = (outSize != 0);
+  if (_outSizeIsDefined)
+    _outSize = *outSize;
+
+  while(NeedMore())
+  {
+    UInt32 processedSize;
+    
+    // Change it: It can be optimized using ReadPart
+    RINOK(ReadStream(inStream, _buffer + bufferPos, kBufferSize - bufferPos, &processedSize));
+    
+    UInt32 endPos = bufferPos + processedSize;
+
+    bufferPos = Filter->Filter(_buffer, endPos);
+    if (bufferPos > endPos)
+    {
+      for (; endPos< bufferPos; endPos++)
+        _buffer[endPos] = 0;
+      bufferPos = Filter->Filter(_buffer, endPos);
+    }
+
+    if (bufferPos == 0)
+    {
+      if (endPos > 0)
+        return WriteWithLimit(outStream, endPos);
+      return S_OK;
+    }
+    RINOK(WriteWithLimit(outStream, bufferPos));
+    if (progress != NULL)
+    {
+      RINOK(progress->SetRatioInfo(&_nowPos64, &_nowPos64));
+    }
+    UInt32 i = 0;
+    while(bufferPos < endPos)
+      _buffer[i++] = _buffer[bufferPos++];
+    bufferPos = i;
+  }
+  return S_OK;
+}
+
+// #ifdef _ST_MODE
+STDMETHODIMP CFilterCoder::SetOutStream(ISequentialOutStream *outStream)
+{
+  _bufferPos = 0;
+  _outStream = outStream;
+  return Init();
+}
+
+STDMETHODIMP CFilterCoder::ReleaseOutStream()
+{
+  _outStream.Release();
+  return S_OK;
+};
+
+
+STDMETHODIMP CFilterCoder::Write(const void *data, UInt32 size, UInt32 *processedSize)
+{
+  UInt32 processedSizeTotal = 0;
+  while(size > 0)
+  {
+    UInt32 sizeMax = kBufferSize - _bufferPos;
+    UInt32 sizeTemp = size;
+    if (sizeTemp > sizeMax)
+      sizeTemp = sizeMax;
+    memmove(_buffer + _bufferPos, data, sizeTemp);
+    size -= sizeTemp;
+    processedSizeTotal += sizeTemp;
+    data = (const Byte *)data + sizeTemp;
+    UInt32 endPos = _bufferPos + sizeTemp;
+    _bufferPos = Filter->Filter(_buffer, endPos);
+    if (_bufferPos == 0)
+    {
+      _bufferPos = endPos;
+      break;
+    }
+    if (_bufferPos > endPos)
+    {
+      if (size != 0)
+        return E_FAIL;
+      break;
+    }
+    RINOK(WriteWithLimit(_outStream, _bufferPos));
+    UInt32 i = 0;
+    while(_bufferPos < endPos)
+      _buffer[i++] = _buffer[_bufferPos++];
+    _bufferPos = i;
+  }
+  if (processedSize != NULL)
+    *processedSize = processedSizeTotal;
+  return S_OK;
+}
+
+STDMETHODIMP CFilterCoder::Flush()
+{
+  if (_bufferPos != 0)
+  {
+    UInt32 endPos = Filter->Filter(_buffer, _bufferPos);
+    if (endPos > _bufferPos)
+    {
+      for (; _bufferPos < endPos; _bufferPos++)
+        _buffer[_bufferPos] = 0;
+      if (Filter->Filter(_buffer, endPos) != endPos)
+        return E_FAIL;
+    }
+    UInt32 processedSize;
+    RINOK(WriteStream(_outStream, _buffer, _bufferPos, &processedSize));
+    if (_bufferPos != processedSize)
+      return E_FAIL;
+    _bufferPos = 0;
+  }
+  CMyComPtr<IOutStreamFlush> flush;
+  _outStream.QueryInterface(IID_IOutStreamFlush, &flush);
+  if (flush)
+    return  flush->Flush();
+  return S_OK;
+}
+
+
+STDMETHODIMP CFilterCoder::SetInStream(ISequentialInStream *inStream)
+{
+  _convertedPosBegin = _convertedPosEnd = _bufferPos = 0;
+  _inStream = inStream;
+  return Init();
+}
+
+STDMETHODIMP CFilterCoder::ReleaseInStream()
+{
+  _inStream.Release();
+  return S_OK;
+};
+
+STDMETHODIMP CFilterCoder::Read(void *data, UInt32 size, UInt32 *processedSize)
+{
+  UInt32 processedSizeTotal = 0;
+  while(size > 0)
+  {
+    if (_convertedPosBegin != _convertedPosEnd)
+    {
+      UInt32 sizeTemp = MyMin(size, _convertedPosEnd - _convertedPosBegin);
+      memmove(data, _buffer + _convertedPosBegin, sizeTemp);
+      _convertedPosBegin += sizeTemp;
+      data = (void *)((Byte *)data + sizeTemp);
+      size -= sizeTemp;
+      processedSizeTotal += sizeTemp;
+      break;
+    }
+    int i;
+    for (i = 0; _convertedPosEnd + i < _bufferPos; i++)
+      _buffer[i] = _buffer[i + _convertedPosEnd];
+    _bufferPos = i;
+    _convertedPosBegin = _convertedPosEnd = 0;
+    UInt32 processedSizeTemp;
+    UInt32 size0 = kBufferSize - _bufferPos;
+    // Optimize it:
+    RINOK(ReadStream(_inStream, _buffer + _bufferPos, size0, &processedSizeTemp));
+    _bufferPos = _bufferPos + processedSizeTemp;
+    _convertedPosEnd = Filter->Filter(_buffer, _bufferPos);
+    if (_convertedPosEnd == 0)
+    {
+      if (_bufferPos == 0)
+        break;
+      else
+      {
+        _convertedPosEnd = _bufferPos; // check it
+        continue;
+      }
+    }
+    if (_convertedPosEnd > _bufferPos)
+    {
+      for (; _bufferPos < _convertedPosEnd; _bufferPos++)
+        _buffer[_bufferPos] = 0;
+      _convertedPosEnd = Filter->Filter(_buffer, _bufferPos);
+    }
+  }
+  if (processedSize != NULL)
+    *processedSize = processedSizeTotal;
+  return S_OK;
+}
+
+// #endif // _ST_MODE
+
+#ifndef _NO_CRYPTO
+STDMETHODIMP CFilterCoder::CryptoSetPassword(const Byte *data, UInt32 size)
+{
+  return _setPassword->CryptoSetPassword(data, size);
+}
+#endif
+
+#ifndef EXTRACT_ONLY
+STDMETHODIMP CFilterCoder::SetCoderProperties(const PROPID *propIDs, 
+      const PROPVARIANT *properties, UInt32 numProperties)
+{
+  return _SetCoderProperties->SetCoderProperties(propIDs, properties, numProperties);
+}
+
+STDMETHODIMP CFilterCoder::WriteCoderProperties(ISequentialOutStream *outStream)
+{
+  return _writeCoderProperties->WriteCoderProperties(outStream);
+}
+
+/*
+STDMETHODIMP CFilterCoder::ResetSalt()
+{
+  return _CryptoResetSalt->ResetSalt();
+}
+*/
+
+STDMETHODIMP CFilterCoder::ResetInitVector()
+{
+  return _CryptoResetInitVector->ResetInitVector();
+}
+#endif
+
+STDMETHODIMP CFilterCoder::SetDecoderProperties2(const Byte *data, UInt32 size)
+{
+  return _setDecoderProperties->SetDecoderProperties2(data, size);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/misc/libphysfs/lzma/CPP/7zip/Common/FilterCoder.h	Mon Apr 10 12:06:43 2017 -0400
@@ -0,0 +1,143 @@
+// FilterCoder.h
+
+#ifndef __FILTERCODER_H
+#define __FILTERCODER_H
+
+#include "../../Common/MyCom.h"
+#include "../ICoder.h"
+#include "../IPassword.h"
+
+#define MY_QUERYINTERFACE_ENTRY_AG(i, sub0, sub) if (iid == IID_ ## i) \
+{ if (!sub) RINOK(sub0->QueryInterface(IID_ ## i, (void **)&sub)) \
+*outObject = (void *)(i *)this; AddRef(); return S_OK; } 
+
+class CFilterCoder:
+  public ICompressCoder,
+  // #ifdef _ST_MODE
+  public ICompressSetInStream,
+  public ISequentialInStream,
+  public ICompressSetOutStream,
+  public ISequentialOutStream,
+  public IOutStreamFlush,
+  // #endif
+
+  #ifndef _NO_CRYPTO
+  public ICryptoSetPassword,
+  #endif
+  #ifndef EXTRACT_ONLY
+  public ICompressSetCoderProperties,
+  public ICompressWriteCoderProperties,
+  // public ICryptoResetSalt,
+  public ICryptoResetInitVector,
+  #endif
+  public ICompressSetDecoderProperties2,
+  public CMyUnknownImp
+{
+protected:
+  Byte *_buffer;
+  // #ifdef _ST_MODE
+  CMyComPtr<ISequentialInStream> _inStream;
+  CMyComPtr<ISequentialOutStream> _outStream;
+  UInt32 _bufferPos;
+  UInt32 _convertedPosBegin;
+  UInt32 _convertedPosEnd;
+  // #endif
+  bool _outSizeIsDefined;
+  UInt64 _outSize;
+  UInt64 _nowPos64;
+
+  HRESULT Init() 
+  { 
+    _nowPos64 = 0;
+    _outSizeIsDefined = false;
+    return Filter->Init(); 
+  }
+
+  CMyComPtr<ICryptoSetPassword> _setPassword;
+  #ifndef EXTRACT_ONLY
+  CMyComPtr<ICompressSetCoderProperties> _SetCoderProperties;
+  CMyComPtr<ICompressWriteCoderProperties> _writeCoderProperties;
+  // CMyComPtr<ICryptoResetSalt> _CryptoResetSalt;
+  CMyComPtr<ICryptoResetInitVector> _CryptoResetInitVector;
+  #endif
+  CMyComPtr<ICompressSetDecoderProperties2> _setDecoderProperties;
+public:
+  CMyComPtr<ICompressFilter> Filter;
+
+  CFilterCoder();
+  ~CFilterCoder();
+  HRESULT WriteWithLimit(ISequentialOutStream *outStream, UInt32 size);
+  bool NeedMore() const  
+    { return (!_outSizeIsDefined || (_nowPos64 < _outSize)); }
+
+public:
+  MY_QUERYINTERFACE_BEGIN
+    MY_QUERYINTERFACE_ENTRY(ICompressCoder)
+    // #ifdef _ST_MODE
+    MY_QUERYINTERFACE_ENTRY(ICompressSetInStream)
+    MY_QUERYINTERFACE_ENTRY(ISequentialInStream)
+
+    MY_QUERYINTERFACE_ENTRY(ICompressSetOutStream)
+    MY_QUERYINTERFACE_ENTRY(ISequentialOutStream)
+    MY_QUERYINTERFACE_ENTRY(IOutStreamFlush)
+    // #endif
+
+    #ifndef _NO_CRYPTO
+    MY_QUERYINTERFACE_ENTRY_AG(ICryptoSetPassword, Filter, _setPassword)
+    #endif
+
+    #ifndef EXTRACT_ONLY
+    MY_QUERYINTERFACE_ENTRY_AG(ICompressSetCoderProperties, Filter, _SetCoderProperties)
+    MY_QUERYINTERFACE_ENTRY_AG(ICompressWriteCoderProperties, Filter, _writeCoderProperties)
+    // MY_QUERYINTERFACE_ENTRY_AG(ICryptoResetSalt, Filter, _CryptoResetSalt)
+    MY_QUERYINTERFACE_ENTRY_AG(ICryptoResetInitVector, Filter, _CryptoResetInitVector)
+    #endif
+
+    MY_QUERYINTERFACE_ENTRY_AG(ICompressSetDecoderProperties2, Filter, _setDecoderProperties)
+  MY_QUERYINTERFACE_END
+  MY_ADDREF_RELEASE
+  STDMETHOD(Code)(ISequentialInStream *inStream,
+      ISequentialOutStream *outStream, const UInt64 *inSize, const UInt64 *outSize,
+      ICompressProgressInfo *progress);
+  // #ifdef _ST_MODE
+  STDMETHOD(ReleaseInStream)();
+  STDMETHOD(SetInStream)(ISequentialInStream *inStream);
+  STDMETHOD(Read)(void *data, UInt32 size, UInt32 *processedSize); \
+  STDMETHOD(SetOutStream)(ISequentialOutStream *outStream);
+  STDMETHOD(ReleaseOutStream)();
+  STDMETHOD(Write)(const void *data, UInt32 size, UInt32 *processedSize);
+  STDMETHOD(Flush)();
+  // #endif
+
+  #ifndef _NO_CRYPTO
+  STDMETHOD(CryptoSetPassword)(const Byte *data, UInt32 size);
+  #endif
+  #ifndef EXTRACT_ONLY
+  STDMETHOD(SetCoderProperties)(const PROPID *propIDs, 
+      const PROPVARIANT *properties, UInt32 numProperties);
+  STDMETHOD(WriteCoderProperties)(ISequentialOutStream *outStream);
+  // STDMETHOD(ResetSalt)();
+  STDMETHOD(ResetInitVector)();
+  #endif
+  STDMETHOD(SetDecoderProperties2)(const Byte *data, UInt32 size);
+};
+
+// #ifdef _ST_MODE
+class CInStreamReleaser
+{
+public:
+  CFilterCoder *FilterCoder;
+  CInStreamReleaser(): FilterCoder(0) {}
+  ~CInStreamReleaser() { if (FilterCoder) FilterCoder->ReleaseInStream(); }
+};
+
+class COutStreamReleaser
+{
+public:
+  CFilterCoder *FilterCoder;
+  COutStreamReleaser(): FilterCoder(0) {}
+  ~COutStreamReleaser() { if (FilterCoder) FilterCoder->ReleaseOutStream(); }
+};
+// #endif
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/misc/libphysfs/lzma/CPP/7zip/Common/InBuffer.cpp	Mon Apr 10 12:06:43 2017 -0400
@@ -0,0 +1,83 @@
+// InBuffer.cpp
+
+#include "StdAfx.h"
+
+#include "InBuffer.h"
+
+extern "C"
+{
+  #include "../../../C/Alloc.h"
+}
+
+CInBuffer::CInBuffer(): 
+  _buffer(0), 
+  _bufferLimit(0), 
+  _bufferBase(0), 
+  _stream(0),
+  _bufferSize(0)
+{}
+
+bool CInBuffer::Create(UInt32 bufferSize)
+{
+  const UInt32 kMinBlockSize = 1;
+  if (bufferSize < kMinBlockSize)
+    bufferSize = kMinBlockSize;
+  if (_bufferBase != 0 && _bufferSize == bufferSize)
+    return true;
+  Free();
+  _bufferSize = bufferSize;
+  _bufferBase = (Byte *)::MidAlloc(bufferSize);
+  return (_bufferBase != 0);
+}
+
+void CInBuffer::Free()
+{
+  ::MidFree(_bufferBase);
+  _bufferBase = 0;
+}
+
+void CInBuffer::SetStream(ISequentialInStream *stream)
+{
+  _stream = stream;
+}
+
+void CInBuffer::Init()
+{
+  _processedSize = 0;
+  _buffer = _bufferBase;
+  _bufferLimit = _buffer;
+  _wasFinished = false;
+  #ifdef _NO_EXCEPTIONS
+  ErrorCode = S_OK;
+  #endif
+}
+
+bool CInBuffer::ReadBlock()
+{
+  #ifdef _NO_EXCEPTIONS
+  if (ErrorCode != S_OK)
+    return false;
+  #endif
+  if (_wasFinished)
+    return false;
+  _processedSize += (_buffer - _bufferBase);
+  UInt32 numProcessedBytes;
+  HRESULT result = _stream->Read(_bufferBase, _bufferSize, &numProcessedBytes);
+  #ifdef _NO_EXCEPTIONS
+  ErrorCode = result;
+  #else
+  if (result != S_OK)
+    throw CInBufferException(result);
+  #endif
+  _buffer = _bufferBase;
+  _bufferLimit = _buffer + numProcessedBytes;
+  _wasFinished = (numProcessedBytes == 0);
+  return (!_wasFinished);
+}
+
+Byte CInBuffer::ReadBlock2()
+{
+  if(!ReadBlock())
+    return 0xFF;
+  return *_buffer++;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/misc/libphysfs/lzma/CPP/7zip/Common/InBuffer.h	Mon Apr 10 12:06:43 2017 -0400
@@ -0,0 +1,75 @@
+// InBuffer.h
+
+#ifndef __INBUFFER_H
+#define __INBUFFER_H
+
+#include "../IStream.h"
+#include "../../Common/MyCom.h"
+#include "../../Common/MyException.h"
+
+#ifndef _NO_EXCEPTIONS
+struct CInBufferException: public CSystemException 
+{
+  CInBufferException(HRESULT errorCode): CSystemException(errorCode) {} 
+};
+#endif
+
+class CInBuffer
+{
+  Byte *_buffer;
+  Byte *_bufferLimit;
+  Byte *_bufferBase;
+  CMyComPtr<ISequentialInStream> _stream;
+  UInt64 _processedSize;
+  UInt32 _bufferSize;
+  bool _wasFinished;
+
+  bool ReadBlock();
+  Byte ReadBlock2();
+
+public:
+  #ifdef _NO_EXCEPTIONS
+  HRESULT ErrorCode;
+  #endif
+
+  CInBuffer();
+  ~CInBuffer() { Free(); }
+
+  bool Create(UInt32 bufferSize);
+  void Free();
+  
+  void SetStream(ISequentialInStream *stream);
+  void Init();
+  void ReleaseStream() { _stream.Release(); }
+
+  bool ReadByte(Byte &b)
+  {
+    if(_buffer >= _bufferLimit)
+      if(!ReadBlock())
+        return false;
+    b = *_buffer++;
+    return true;
+  }
+  Byte ReadByte()
+  {
+    if(_buffer >= _bufferLimit)
+      return ReadBlock2();
+    return *_buffer++;
+  }
+  void ReadBytes(void *data, UInt32 size, UInt32 &processedSize)
+  {
+    for(processedSize = 0; processedSize < size; processedSize++)
+      if (!ReadByte(((Byte *)data)[processedSize]))
+        return;
+  }
+  bool ReadBytes(void *data, UInt32 size)
+  {
+    UInt32 processedSize;
+    ReadBytes(data, size, processedSize);
+    return (processedSize == size);
+  }
+  UInt64 GetProcessedSize() const { return _processedSize + (_buffer - _bufferBase); }
+  bool WasFinished() const { return _wasFinished; }
+};
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/misc/libphysfs/lzma/CPP/7zip/Common/InOutTempBuffer.cpp	Mon Apr 10 12:06:43 2017 -0400
@@ -0,0 +1,122 @@
+// InOutTempBuffer.cpp
+
+#include "StdAfx.h"
+
+#include "InOutTempBuffer.h"
+#include "../../Common/Defs.h"
+// #include "Windows/Defs.h"
+
+#include "StreamUtils.h"
+
+using namespace NWindows;
+using namespace NFile;
+using namespace NDirectory;
+
+static UInt32 kTmpBufferMemorySize = (1 << 20);
+
+static LPCTSTR kTempFilePrefixString = TEXT("iot");
+
+CInOutTempBuffer::CInOutTempBuffer():
+  _buffer(NULL)
+{
+}
+
+void CInOutTempBuffer::Create()
+{
+  _buffer = new Byte[kTmpBufferMemorySize];
+}
+
+CInOutTempBuffer::~CInOutTempBuffer()
+{
+  delete []_buffer;
+}
+void CInOutTempBuffer::InitWriting()
+{
+  _bufferPosition = 0;
+  _tmpFileCreated = false;
+  _fileSize = 0;
+}
+
+bool CInOutTempBuffer::WriteToFile(const void *data, UInt32 size)
+{
+  if (size == 0)
+    return true;
+  if(!_tmpFileCreated)
+  {
+    CSysString tempDirPath;
+    if(!MyGetTempPath(tempDirPath))
+      return false;
+    if (_tempFile.Create(tempDirPath, kTempFilePrefixString, _tmpFileName) == 0)
+      return false;
+    // _outFile.SetOpenCreationDispositionCreateAlways();
+    if(!_outFile.Create(_tmpFileName, true))
+      return false;
+    _tmpFileCreated = true;
+  }
+  UInt32 processedSize;
+  if(!_outFile.Write(data, size, processedSize))
+    return false;
+  _fileSize += processedSize;
+  return (processedSize == size);
+}
+
+bool CInOutTempBuffer::FlushWrite()
+{
+  return _outFile.Close();
+}
+
+bool CInOutTempBuffer::Write(const void *data, UInt32 size)
+{
+  if(_bufferPosition < kTmpBufferMemorySize)
+  {
+    UInt32 curSize = MyMin(kTmpBufferMemorySize - _bufferPosition, size);
+    memmove(_buffer + _bufferPosition, (const Byte *)data, curSize);
+    _bufferPosition += curSize;
+    size -= curSize;
+    data = ((const Byte *)data) + curSize;
+    _fileSize += curSize;
+  }
+  return WriteToFile(data, size);
+}
+
+bool CInOutTempBuffer::InitReading()
+{
+  _currentPositionInBuffer = 0;
+  if(_tmpFileCreated)
+    return _inFile.Open(_tmpFileName);
+  return true;
+}
+
+HRESULT CInOutTempBuffer::WriteToStream(ISequentialOutStream *stream)
+{
+  if (_currentPositionInBuffer < _bufferPosition)
+  {
+    UInt32 sizeToWrite = _bufferPosition - _currentPositionInBuffer;
+    RINOK(WriteStream(stream, _buffer + _currentPositionInBuffer, sizeToWrite, NULL));
+    _currentPositionInBuffer += sizeToWrite;
+  }
+  if (!_tmpFileCreated)
+    return true;
+  for (;;)
+  {
+    UInt32 localProcessedSize;
+    if (!_inFile.ReadPart(_buffer, kTmpBufferMemorySize, localProcessedSize))
+      return E_FAIL;
+    if (localProcessedSize == 0)
+      return S_OK;
+    RINOK(WriteStream(stream, _buffer, localProcessedSize, NULL));
+  }
+}
+
+STDMETHODIMP CSequentialOutTempBufferImp::Write(const void *data, UInt32 size, UInt32 *processedSize)
+{
+  if (!_buffer->Write(data, size))
+  {
+    if (processedSize != NULL)
+      *processedSize = 0;
+    return E_FAIL;
+  }
+  if (processedSize != NULL)
+    *processedSize = size;
+  return S_OK;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/misc/libphysfs/lzma/CPP/7zip/Common/InOutTempBuffer.h	Mon Apr 10 12:06:43 2017 -0400
@@ -0,0 +1,55 @@
+// Util/InOutTempBuffer.h
+
+#ifndef __IN_OUT_TEMP_BUFFER_H
+#define __IN_OUT_TEMP_BUFFER_H
+
+#include "../../Windows/FileIO.h"
+#include "../../Windows/FileDir.h"
+#include "../../Common/MyCom.h"
+
+#include "../IStream.h"
+
+class CInOutTempBuffer
+{
+  NWindows::NFile::NDirectory::CTempFile _tempFile;
+  NWindows::NFile::NIO::COutFile _outFile;
+  NWindows::NFile::NIO::CInFile _inFile;
+  Byte *_buffer;
+  UInt32 _bufferPosition;
+  UInt32 _currentPositionInBuffer;
+  CSysString _tmpFileName;
+  bool _tmpFileCreated;
+
+  UInt64 _fileSize;
+
+  bool WriteToFile(const void *data, UInt32 size);
+public:
+  CInOutTempBuffer();
+  ~CInOutTempBuffer();
+  void Create();
+
+  void InitWriting();
+  bool Write(const void *data, UInt32 size);
+  UInt64 GetDataSize() const { return _fileSize; }
+  bool FlushWrite();
+  bool InitReading();
+  HRESULT WriteToStream(ISequentialOutStream *stream);
+};
+
+class CSequentialOutTempBufferImp: 
+  public ISequentialOutStream,
+  public CMyUnknownImp
+{
+  CInOutTempBuffer *_buffer;
+public:
+  // CSequentialOutStreamImp(): _size(0) {}
+  // UInt32 _size;
+  void Init(CInOutTempBuffer *buffer)  { _buffer = buffer; }
+  // UInt32 GetSize() const { return _size; }
+
+  MY_UNKNOWN_IMP
+
+  STDMETHOD(Write)(const void *data, UInt32 size, UInt32 *processedSize);
+};
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/misc/libphysfs/lzma/CPP/7zip/Common/LimitedStreams.cpp	Mon Apr 10 12:06:43 2017 -0400
@@ -0,0 +1,24 @@
+// LimitedStreams.cpp
+
+#include "StdAfx.h"
+
+#include "LimitedStreams.h"
+#include "../../Common/Defs.h"
+
+STDMETHODIMP CLimitedSequentialInStream::Read(void *data, UInt32 size, UInt32 *processedSize)
+{
+  UInt32 realProcessedSize = 0;
+  UInt32 sizeToRead = (UInt32)MyMin((_size - _pos), (UInt64)size);
+  HRESULT result = S_OK;
+  if (sizeToRead > 0)
+  {
+    result = _stream->Read(data, sizeToRead, &realProcessedSize);
+    _pos += realProcessedSize;
+    if (realProcessedSize == 0)
+      _wasFinished = true;
+  }
+  if(processedSize != NULL)
+    *processedSize = realProcessedSize;
+  return result;
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/misc/libphysfs/lzma/CPP/7zip/Common/LimitedStreams.h	Mon Apr 10 12:06:43 2017 -0400
@@ -0,0 +1,33 @@
+// LimitedStreams.h
+
+#ifndef __LIMITEDSTREAMS_H
+#define __LIMITEDSTREAMS_H
+
+#include "../../Common/MyCom.h"
+#include "../IStream.h"
+
+class CLimitedSequentialInStream: 
+  public ISequentialInStream,
+  public CMyUnknownImp
+{
+  CMyComPtr<ISequentialInStream> _stream;
+  UInt64 _size;
+  UInt64 _pos;
+  bool _wasFinished;
+public:
+  void SetStream(ISequentialInStream *stream) { _stream = stream; }
+  void Init(UInt64 streamSize)  
+  { 
+    _size = streamSize; 
+    _pos = 0; 
+    _wasFinished = false; 
+  }
+ 
+  MY_UNKNOWN_IMP
+
+  STDMETHOD(Read)(void *data, UInt32 size, UInt32 *processedSize);
+  UInt64 GetSize() const { return _pos; }
+  bool WasFinished() const { return _wasFinished; }
+};
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/misc/libphysfs/lzma/CPP/7zip/Common/LockedStream.cpp	Mon Apr 10 12:06:43 2017 -0400
@@ -0,0 +1,23 @@
+// LockedStream.cpp
+
+#include "StdAfx.h"
+
+#include "LockedStream.h"
+
+HRESULT CLockedInStream::Read(UInt64 startPos, void *data, UInt32 size, 
+  UInt32 *processedSize)
+{
+  NWindows::NSynchronization::CCriticalSectionLock lock(_criticalSection);
+  RINOK(_stream->Seek(startPos, STREAM_SEEK_SET, NULL));
+  return _stream->Read(data, size, processedSize);
+}
+
+STDMETHODIMP CLockedSequentialInStreamImp::Read(void *data, UInt32 size, UInt32 *processedSize)
+{
+  UInt32 realProcessedSize = 0;
+  HRESULT result = _lockedInStream->Read(_pos, data, size, &realProcessedSize);
+  _pos += realProcessedSize;
+  if (processedSize != NULL)
+    *processedSize = realProcessedSize;
+  return result;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/misc/libphysfs/lzma/CPP/7zip/Common/LockedStream.h	Mon Apr 10 12:06:43 2017 -0400
@@ -0,0 +1,38 @@
+// LockedStream.h
+
+#ifndef __LOCKEDSTREAM_H
+#define __LOCKEDSTREAM_H
+
+#include "../../Windows/Synchronization.h"
+#include "../../Common/MyCom.h"
+#include "../IStream.h"
+
+class CLockedInStream
+{
+  CMyComPtr<IInStream> _stream;
+  NWindows::NSynchronization::CCriticalSection _criticalSection;
+public:
+  void Init(IInStream *stream)
+    { _stream = stream; }
+  HRESULT Read(UInt64 startPos, void *data, UInt32 size, UInt32 *processedSize);
+};
+
+class CLockedSequentialInStreamImp: 
+  public ISequentialInStream,
+  public CMyUnknownImp
+{
+  CLockedInStream *_lockedInStream;
+  UInt64 _pos;
+public:
+  void Init(CLockedInStream *lockedInStream, UInt64 startPos)
+  {
+    _lockedInStream = lockedInStream;
+    _pos = startPos;
+  }
+
+  MY_UNKNOWN_IMP
+
+  STDMETHOD(Read)(void *data, UInt32 size, UInt32 *processedSize);
+};
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/misc/libphysfs/lzma/CPP/7zip/Common/MethodId.cpp	Mon Apr 10 12:06:43 2017 -0400
@@ -0,0 +1,27 @@
+// MethodId.cpp
+
+#include "StdAfx.h"
+
+#include "MethodId.h"
+#include "../../Common/MyString.h"
+
+static inline wchar_t GetHex(Byte value)
+{
+  return (wchar_t)((value < 10) ? ('0' + value) : ('A' + (value - 10)));
+}
+
+UString ConvertMethodIdToString(UInt64 id)
+{
+  wchar_t s[32];
+  int len = 32;
+  s[--len] = 0;
+  do
+  {
+    s[--len] = GetHex((Byte)id & 0xF);
+    id >>= 4;
+    s[--len] = GetHex((Byte)id & 0xF);
+    id >>= 4;
+  }
+  while (id != 0);
+  return s + len;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/misc/libphysfs/lzma/CPP/7zip/Common/MethodId.h	Mon Apr 10 12:06:43 2017 -0400
@@ -0,0 +1,10 @@
+// MethodId.h
+
+#ifndef __7Z_METHOD_ID_H
+#define __7Z_METHOD_ID_H
+
+#include "../../Common/Types.h"
+
+typedef UInt64 CMethodId;
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/misc/libphysfs/lzma/CPP/7zip/Common/MethodProps.cpp	Mon Apr 10 12:06:43 2017 -0400
@@ -0,0 +1,96 @@
+// MethodProps.cpp
+
+#include "StdAfx.h"
+
+#include "MethodProps.h"
+#include "../../Common/MyCom.h"
+
+static UInt64 k_LZMA = 0x030101;
+// static UInt64 k_LZMA2 = 0x030102;
+
+HRESULT SetMethodProperties(const CMethod &method, const UInt64 *inSizeForReduce, IUnknown *coder)
+{
+  bool tryReduce = false;
+  UInt32 reducedDictionarySize = 1 << 10;
+  if (inSizeForReduce != 0 && (method.Id == k_LZMA /* || methodFull.MethodID == k_LZMA2 */))
+  {
+    for (;;)
+    {
+      const UInt32 step = (reducedDictionarySize >> 1);
+      if (reducedDictionarySize >= *inSizeForReduce)
+      {
+        tryReduce = true;
+        break;
+      }
+      reducedDictionarySize += step;
+      if (reducedDictionarySize >= *inSizeForReduce)
+      {
+        tryReduce = true;
+        break;
+      }
+      if (reducedDictionarySize >= ((UInt32)3 << 30))
+        break;
+      reducedDictionarySize += step;
+    }
+  }
+
+  {
+    int numProperties = method.Properties.Size();
+    CMyComPtr<ICompressSetCoderProperties> setCoderProperties;
+    coder->QueryInterface(IID_ICompressSetCoderProperties, (void **)&setCoderProperties);
+    if (setCoderProperties == NULL)
+    {
+      if (numProperties != 0)
+        return E_INVALIDARG;
+    }
+    else
+    {
+      CRecordVector<PROPID> propIDs;
+      NWindows::NCOM::CPropVariant *values = new NWindows::NCOM::CPropVariant[numProperties];
+      HRESULT res = S_OK;
+      try
+      {
+        for (int i = 0; i < numProperties; i++)
+        {
+          const CProp &prop = method.Properties[i];
+          propIDs.Add(prop.Id);
+          NWindows::NCOM::CPropVariant &value = values[i];
+          value = prop.Value;
+          // if (tryReduce && prop.Id == NCoderPropID::kDictionarySize && value.vt == VT_UI4 && reducedDictionarySize < value.ulVal)
+          if (tryReduce)
+            if (prop.Id == NCoderPropID::kDictionarySize)
+              if (value.vt == VT_UI4)
+                if (reducedDictionarySize < value.ulVal)
+            value.ulVal = reducedDictionarySize;
+        }
+        CMyComPtr<ICompressSetCoderProperties> setCoderProperties;
+        coder->QueryInterface(IID_ICompressSetCoderProperties, (void **)&setCoderProperties);
+        res = setCoderProperties->SetCoderProperties(&propIDs.Front(), values, numProperties);
+      }
+      catch(...)
+      {
+        delete []values;
+        throw;
+      }
+      delete []values;
+      RINOK(res);
+    }
+  }
+ 
+  /*
+  CMyComPtr<ICompressWriteCoderProperties> writeCoderProperties;
+  coder->QueryInterface(IID_ICompressWriteCoderProperties, (void **)&writeCoderProperties);
+  if (writeCoderProperties != NULL)
+  {
+    CSequentialOutStreamImp *outStreamSpec = new CSequentialOutStreamImp;
+    CMyComPtr<ISequentialOutStream> outStream(outStreamSpec);
+    outStreamSpec->Init();
+    RINOK(writeCoderProperties->WriteCoderProperties(outStream));
+    size_t size = outStreamSpec->GetSize();
+    filterProps.SetCapacity(size);
+    memmove(filterProps, outStreamSpec->GetBuffer(), size);
+  }
+  */
+  return S_OK;
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/misc/libphysfs/lzma/CPP/7zip/Common/MethodProps.h	Mon Apr 10 12:06:43 2017 -0400
@@ -0,0 +1,41 @@
+// MethodProps.h
+
+#ifndef __7Z_METHOD_PROPS_H
+#define __7Z_METHOD_PROPS_H
+
+#include "MethodId.h"
+
+#include "../../Windows/PropVariant.h"
+#include "../../Common/MyVector.h"
+#include "../ICoder.h"
+
+struct CProp
+{
+  PROPID Id;
+  NWindows::NCOM::CPropVariant Value;
+};
+
+struct CMethod
+{
+  CMethodId Id;
+  CObjectVector<CProp> Properties;
+};
+
+struct CMethodsMode
+{
+  CObjectVector<CMethod> Methods;
+  #ifdef COMPRESS_MT
+  UInt32 NumThreads;
+  #endif
+
+  CMethodsMode()
+      #ifdef COMPRESS_MT
+      : NumThreads(1) 
+      #endif
+  {}
+  bool IsEmpty() const { return Methods.IsEmpty() ; }
+};
+
+HRESULT SetMethodProperties(const CMethod &method, const UInt64 *inSizeForReduce, IUnknown *coder);
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/misc/libphysfs/lzma/CPP/7zip/Common/OffsetStream.cpp	Mon Apr 10 12:06:43 2017 -0400
@@ -0,0 +1,35 @@
+// OffsetStream.cpp
+
+#include "StdAfx.h"
+
+#include "Common/Defs.h"
+#include "OffsetStream.h"
+
+HRESULT COffsetOutStream::Init(IOutStream *stream, UInt64 offset)
+{
+  _offset = offset;
+  _stream = stream;
+  return _stream->Seek(offset, STREAM_SEEK_SET, NULL);
+}
+
+STDMETHODIMP COffsetOutStream::Write(const void *data, UInt32 size, UInt32 *processedSize)
+{
+  return _stream->Write(data, size, processedSize);
+}
+
+STDMETHODIMP COffsetOutStream::Seek(Int64 offset, UInt32 seekOrigin, 
+    UInt64 *newPosition)
+{
+  UInt64 absoluteNewPosition;
+  if (seekOrigin == STREAM_SEEK_SET)
+    offset += _offset;
+  HRESULT result = _stream->Seek(offset, seekOrigin, &absoluteNewPosition);
+  if (newPosition != NULL)
+    *newPosition = absoluteNewPosition - _offset;
+  return result;
+}
+
+STDMETHODIMP COffsetOutStream::SetSize(Int64 newSize)
+{
+  return _stream->SetSize(_offset + newSize);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/misc/libphysfs/lzma/CPP/7zip/Common/OffsetStream.h	Mon Apr 10 12:06:43 2017 -0400
@@ -0,0 +1,25 @@
+// OffsetStream.h
+
+#ifndef __OFFSETSTREAM_H
+#define __OFFSETSTREAM_H
+
+#include "Common/MyCom.h"
+#include "../IStream.h"
+
+class COffsetOutStream: 
+  public IOutStream,
+  public CMyUnknownImp
+{
+  UInt64 _offset;
+  CMyComPtr<IOutStream> _stream;
+public:
+  HRESULT Init(IOutStream *stream, UInt64 offset);
+  
+  MY_UNKNOWN_IMP
+
+  STDMETHOD(Write)(const void *data, UInt32 size, UInt32 *processedSize);
+  STDMETHOD(Seek)(Int64 offset, UInt32 seekOrigin, UInt64 *newPosition);
+  STDMETHOD(SetSize)(Int64 newSize);
+};
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/misc/libphysfs/lzma/CPP/7zip/Common/OutBuffer.cpp	Mon Apr 10 12:06:43 2017 -0400
@@ -0,0 +1,119 @@
+// OutByte.cpp
+
+#include "StdAfx.h"
+
+#include "OutBuffer.h"
+
+extern "C"
+{
+  #include "../../../C/Alloc.h"
+}
+
+bool COutBuffer::Create(UInt32 bufferSize)
+{
+  const UInt32 kMinBlockSize = 1;
+  if (bufferSize < kMinBlockSize)
+    bufferSize = kMinBlockSize;
+  if (_buffer != 0 && _bufferSize == bufferSize)
+    return true;
+  Free();
+  _bufferSize = bufferSize;
+  _buffer = (Byte *)::MidAlloc(bufferSize);
+  return (_buffer != 0);
+}
+
+void COutBuffer::Free()
+{
+  ::MidFree(_buffer);
+  _buffer = 0;
+}
+
+void COutBuffer::SetStream(ISequentialOutStream *stream)
+{
+  _stream = stream;
+}
+
+void COutBuffer::Init()
+{
+  _streamPos = 0;
+  _limitPos = _bufferSize;
+  _pos = 0;
+  _processedSize = 0;
+  _overDict = false;
+  #ifdef _NO_EXCEPTIONS
+  ErrorCode = S_OK;
+  #endif
+}
+
+UInt64 COutBuffer::GetProcessedSize() const
+{ 
+  UInt64 res = _processedSize + _pos - _streamPos;
+  if (_streamPos > _pos) 
+    res += _bufferSize;
+  return res;
+}
+
+
+HRESULT COutBuffer::FlushPart()
+{
+  // _streamPos < _bufferSize
+  UInt32 size = (_streamPos >= _pos) ? (_bufferSize - _streamPos) : (_pos - _streamPos);
+  HRESULT result = S_OK;
+  #ifdef _NO_EXCEPTIONS
+  result = ErrorCode;
+  #endif
+  if (_buffer2 != 0)
+  {
+    memmove(_buffer2, _buffer + _streamPos, size);
+    _buffer2 += size;
+  }
+
+  if (_stream != 0
+      #ifdef _NO_EXCEPTIONS
+      && (ErrorCode == S_OK)
+      #endif
+     )
+  {
+    UInt32 processedSize = 0;
+    result = _stream->Write(_buffer + _streamPos, size, &processedSize);
+    size = processedSize;
+  }
+  _streamPos += size;
+  if (_streamPos == _bufferSize)
+    _streamPos = 0;
+  if (_pos == _bufferSize)
+  {
+    _overDict = true;
+    _pos = 0;
+  }
+  _limitPos = (_streamPos > _pos) ? _streamPos : _bufferSize;
+  _processedSize += size;
+  return result;
+}
+
+HRESULT COutBuffer::Flush()
+{
+  #ifdef _NO_EXCEPTIONS
+  if (ErrorCode != S_OK)
+    return ErrorCode;
+  #endif
+
+  while(_streamPos != _pos)
+  {
+    HRESULT result = FlushPart();
+    if (result != S_OK)
+      return result;
+  }
+  return S_OK;
+}
+
+void COutBuffer::FlushWithCheck()
+{
+  HRESULT result = Flush();
+  #ifdef _NO_EXCEPTIONS
+  ErrorCode = result;
+  #else
+  if (result != S_OK)
+    throw COutBufferException(result);
+  #endif
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/misc/libphysfs/lzma/CPP/7zip/Common/OutBuffer.h	Mon Apr 10 12:06:43 2017 -0400
@@ -0,0 +1,64 @@
+// OutBuffer.h
+
+#ifndef __OUTBUFFER_H
+#define __OUTBUFFER_H
+
+#include "../IStream.h"
+#include "../../Common/MyCom.h"
+#include "../../Common/MyException.h"
+
+#ifndef _NO_EXCEPTIONS
+struct COutBufferException: public CSystemException 
+{ 
+  COutBufferException(HRESULT errorCode): CSystemException(errorCode) {} 
+};
+#endif
+
+class COutBuffer
+{
+protected:
+  Byte *_buffer;
+  UInt32 _pos;
+  UInt32 _limitPos;
+  UInt32 _streamPos;
+  UInt32 _bufferSize;
+  CMyComPtr<ISequentialOutStream> _stream;
+  UInt64 _processedSize;
+  Byte  *_buffer2;
+  bool _overDict;
+
+  HRESULT FlushPart();
+public:
+  #ifdef _NO_EXCEPTIONS
+  HRESULT ErrorCode;
+  #endif
+
+  COutBuffer(): _buffer(0), _pos(0), _stream(0), _buffer2(0) {}
+  ~COutBuffer() { Free(); }
+  
+  bool Create(UInt32 bufferSize);
+  void Free();
+
+  void SetMemStream(Byte *buffer) { _buffer2 = buffer; }
+  void SetStream(ISequentialOutStream *stream);
+  void Init();
+  HRESULT Flush();
+  void FlushWithCheck();
+  void ReleaseStream() {  _stream.Release(); }
+
+  void WriteByte(Byte b)
+  {
+    _buffer[_pos++] = b;
+    if(_pos == _limitPos)
+      FlushWithCheck();
+  }
+  void WriteBytes(const void *data, size_t size)
+  {
+    for (size_t i = 0; i < size; i++)
+      WriteByte(((const Byte *)data)[i]);
+  }
+
+  UInt64 GetProcessedSize() const;
+};
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/misc/libphysfs/lzma/CPP/7zip/Common/ProgressUtils.cpp	Mon Apr 10 12:06:43 2017 -0400
@@ -0,0 +1,42 @@
+// ProgressUtils.h
+
+#include "StdAfx.h"
+
+#include "ProgressUtils.h"
+
+CLocalProgress::CLocalProgress()
+{
+  ProgressOffset = InSize = OutSize = 0;
+  SendRatio = SendProgress = true;
+}
+
+void CLocalProgress::Init(IProgress *progress, bool inSizeIsMain)
+{
+  _ratioProgress.Release();
+  _progress = progress;
+  _progress.QueryInterface(IID_ICompressProgressInfo, &_ratioProgress);
+  _inSizeIsMain = inSizeIsMain;
+}
+
+STDMETHODIMP CLocalProgress::SetRatioInfo(const UInt64 *inSize, const UInt64 *outSize)
+{
+  UInt64 inSizeNew = InSize, outSizeNew = OutSize;
+  if (inSize)
+    inSizeNew += (*inSize);
+  if (outSize)
+    outSizeNew += (*outSize);
+  if (SendRatio && _ratioProgress)
+  {
+    RINOK(_ratioProgress->SetRatioInfo(&inSizeNew, &outSizeNew));
+  }
+  inSizeNew += ProgressOffset;
+  outSizeNew += ProgressOffset;
+  if (SendProgress)
+    return _progress->SetCompleted(_inSizeIsMain ? &inSizeNew : &outSizeNew);
+  return S_OK;
+}
+
+HRESULT CLocalProgress::SetCur()
+{
+  return SetRatioInfo(NULL, NULL);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/misc/libphysfs/lzma/CPP/7zip/Common/ProgressUtils.h	Mon Apr 10 12:06:43 2017 -0400
@@ -0,0 +1,34 @@
+// ProgressUtils.h
+
+#ifndef __PROGRESSUTILS_H
+#define __PROGRESSUTILS_H
+
+#include "../../Common/MyCom.h"
+
+#include "../ICoder.h"
+#include "../IProgress.h"
+
+class CLocalProgress: 
+  public ICompressProgressInfo,
+  public CMyUnknownImp
+{
+  CMyComPtr<IProgress> _progress;
+  CMyComPtr<ICompressProgressInfo> _ratioProgress;
+  bool _inSizeIsMain;
+public:
+  UInt64 ProgressOffset;
+  UInt64 InSize;
+  UInt64 OutSize;
+  bool SendRatio;
+  bool SendProgress;
+
+  CLocalProgress();
+  void Init(IProgress *progress, bool inSizeIsMain);
+  HRESULT SetCur();
+
+  MY_UNKNOWN_IMP
+
+  STDMETHOD(SetRatioInfo)(const UInt64 *inSize, const UInt64 *outSize);
+};
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/misc/libphysfs/lzma/CPP/7zip/Common/RegisterArc.h	Mon Apr 10 12:06:43 2017 -0400
@@ -0,0 +1,36 @@
+// RegisterArc.h
+
+#ifndef __REGISTERARC_H
+#define __REGISTERARC_H
+
+#include "../Archive/IArchive.h"
+
+typedef IInArchive * (*CreateInArchiveP)();
+typedef IOutArchive * (*CreateOutArchiveP)();
+
+struct CArcInfo
+{
+  const wchar_t *Name;
+  const wchar_t *Ext;
+  const wchar_t *AddExt;
+  Byte ClassId;
+  Byte Signature[16];
+  int SignatureSize;
+  bool KeepName;
+  CreateInArchiveP CreateInArchive;
+  CreateOutArchiveP CreateOutArchive;
+};
+
+void RegisterArc(const CArcInfo *arcInfo);
+
+#define REGISTER_ARC_NAME(x) CRegister ## x 
+
+#define REGISTER_ARC_DEC_SIG(x) struct REGISTER_ARC_NAME(x) { \
+    REGISTER_ARC_NAME(x)() { g_ArcInfo.Signature[0]--; RegisterArc(&g_ArcInfo); }}; \
+    static REGISTER_ARC_NAME(x) g_RegisterArc;
+
+#define REGISTER_ARC(x) struct REGISTER_ARC_NAME(x) { \
+    REGISTER_ARC_NAME(x)() { RegisterArc(&g_ArcInfo); }}; \
+    static REGISTER_ARC_NAME(x) g_RegisterArc;
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/misc/libphysfs/lzma/CPP/7zip/Common/RegisterCodec.h	Mon Apr 10 12:06:43 2017 -0400
@@ -0,0 +1,33 @@
+// RegisterCodec.h
+
+#ifndef __REGISTERCODEC_H
+#define __REGISTERCODEC_H
+
+#include "../Common/MethodId.h"
+
+typedef void * (*CreateCodecP)();
+struct CCodecInfo
+{
+  CreateCodecP CreateDecoder;
+  CreateCodecP CreateEncoder;
+  CMethodId Id;
+  const wchar_t *Name;
+  UInt32 NumInStreams;
+  bool IsFilter;
+};
+
+void RegisterCodec(const CCodecInfo *codecInfo);
+
+#define REGISTER_CODEC_NAME(x) CRegisterCodec ## x 
+
+#define REGISTER_CODEC(x) struct REGISTER_CODEC_NAME(x) { \
+    REGISTER_CODEC_NAME(x)() { RegisterCodec(&g_CodecInfo); }}; \
+    static REGISTER_CODEC_NAME(x) g_RegisterCodec;
+
+#define REGISTER_CODECS_NAME(x) CRegisterCodecs ## x 
+#define REGISTER_CODECS(x) struct REGISTER_CODECS_NAME(x) { \
+    REGISTER_CODECS_NAME(x)() { for (int i = 0; i < sizeof(g_CodecsInfo) / sizeof(g_CodecsInfo[0]); i++) \
+    RegisterCodec(&g_CodecsInfo[i]); }}; \
+    static REGISTER_CODECS_NAME(x) g_RegisterCodecs;
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/misc/libphysfs/lzma/CPP/7zip/Common/StdAfx.h	Mon Apr 10 12:06:43 2017 -0400
@@ -0,0 +1,9 @@
+// StdAfx.h
+
+#ifndef __STDAFX_H
+#define __STDAFX_H
+
+#include "../../Common/MyWindows.h"
+#include "../../Common/NewHandler.h"
+
+#endif 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/misc/libphysfs/lzma/CPP/7zip/Common/StreamBinder.cpp	Mon Apr 10 12:06:43 2017 -0400
@@ -0,0 +1,150 @@
+// StreamBinder.cpp
+
+#include "StdAfx.h"
+
+#include "StreamBinder.h"
+#include "../../Common/Defs.h"
+#include "../../Common/MyCom.h"
+
+using namespace NWindows;
+using namespace NSynchronization;
+
+class CSequentialInStreamForBinder: 
+  public ISequentialInStream,
+  public CMyUnknownImp
+{
+public:
+  MY_UNKNOWN_IMP
+
+  STDMETHOD(Read)(void *data, UInt32 size, UInt32 *processedSize);
+private:
+  CStreamBinder *m_StreamBinder;
+public:
+  ~CSequentialInStreamForBinder() { m_StreamBinder->CloseRead(); }
+  void SetBinder(CStreamBinder *streamBinder) { m_StreamBinder = streamBinder; }
+};
+
+STDMETHODIMP CSequentialInStreamForBinder::Read(void *data, UInt32 size, UInt32 *processedSize)
+  { return m_StreamBinder->Read(data, size, processedSize); }
+
+class CSequentialOutStreamForBinder: 
+  public ISequentialOutStream,
+  public CMyUnknownImp
+{
+public:
+  MY_UNKNOWN_IMP
+
+  STDMETHOD(Write)(const void *data, UInt32 size, UInt32 *processedSize);
+
+private:
+  CStreamBinder *m_StreamBinder;
+public:
+  ~CSequentialOutStreamForBinder() {  m_StreamBinder->CloseWrite(); }
+  void SetBinder(CStreamBinder *streamBinder) { m_StreamBinder = streamBinder; }
+};
+
+STDMETHODIMP CSequentialOutStreamForBinder::Write(const void *data, UInt32 size, UInt32 *processedSize)
+  { return m_StreamBinder->Write(data, size, processedSize); }
+
+
+//////////////////////////
+// CStreamBinder
+// (_thereAreBytesToReadEvent && _bufferSize == 0) means that stream is finished.
+
+HRes CStreamBinder::CreateEvents()
+{
+  RINOK(_allBytesAreWritenEvent.Create(true));
+  RINOK(_thereAreBytesToReadEvent.Create());
+  return _readStreamIsClosedEvent.Create();
+}
+
+void CStreamBinder::ReInit()
+{
+  _thereAreBytesToReadEvent.Reset();
+  _readStreamIsClosedEvent.Reset();
+  ProcessedSize = 0;
+}
+
+
+  
+void CStreamBinder::CreateStreams(ISequentialInStream **inStream, 
+      ISequentialOutStream **outStream)
+{
+  CSequentialInStreamForBinder *inStreamSpec = new 
+      CSequentialInStreamForBinder;
+  CMyComPtr<ISequentialInStream> inStreamLoc(inStreamSpec);
+  inStreamSpec->SetBinder(this);
+  *inStream = inStreamLoc.Detach();
+
+  CSequentialOutStreamForBinder *outStreamSpec = new 
+      CSequentialOutStreamForBinder;
+  CMyComPtr<ISequentialOutStream> outStreamLoc(outStreamSpec);
+  outStreamSpec->SetBinder(this);
+  *outStream = outStreamLoc.Detach();
+
+  _buffer = NULL;
+  _bufferSize= 0;
+  ProcessedSize = 0;
+}
+
+HRESULT CStreamBinder::Read(void *data, UInt32 size, UInt32 *processedSize)
+{
+  UInt32 sizeToRead = size;
+  if (size > 0)
+  {
+    RINOK(_thereAreBytesToReadEvent.Lock());
+    sizeToRead = MyMin(_bufferSize, size);
+    if (_bufferSize > 0)
+    {
+      MoveMemory(data, _buffer, sizeToRead);
+      _buffer = ((const Byte *)_buffer) + sizeToRead;
+      _bufferSize -= sizeToRead;
+      if (_bufferSize == 0)
+      {
+        _thereAreBytesToReadEvent.Reset();
+        _allBytesAreWritenEvent.Set();
+      }
+    }
+  }
+  if (processedSize != NULL)
+    *processedSize = sizeToRead;
+  ProcessedSize += sizeToRead;
+  return S_OK;
+}
+
+void CStreamBinder::CloseRead()
+{
+  _readStreamIsClosedEvent.Set();
+}
+
+HRESULT CStreamBinder::Write(const void *data, UInt32 size, UInt32 *processedSize)
+{
+  if (size > 0)
+  {
+    _buffer = data;
+    _bufferSize = size;
+    _allBytesAreWritenEvent.Reset();
+    _thereAreBytesToReadEvent.Set();
+
+    HANDLE events[2]; 
+    events[0] = _allBytesAreWritenEvent;
+    events[1] = _readStreamIsClosedEvent; 
+    DWORD waitResult = ::WaitForMultipleObjects(2, events, FALSE, INFINITE);
+    if (waitResult != WAIT_OBJECT_0 + 0)
+    {
+      // ReadingWasClosed = true;
+      return S_FALSE;
+    }
+    // if(!_allBytesAreWritenEvent.Lock())
+    //   return E_FAIL;
+  }
+  if (processedSize != NULL)
+    *processedSize = size;
+  return S_OK;
+}
+
+void CStreamBinder::CloseWrite()
+{
+  // _bufferSize must be = 0
+  _thereAreBytesToReadEvent.Set();
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/misc/libphysfs/lzma/CPP/7zip/Common/StreamBinder.h	Mon Apr 10 12:06:43 2017 -0400
@@ -0,0 +1,32 @@
+// StreamBinder.h
+
+#ifndef __STREAMBINDER_H
+#define __STREAMBINDER_H
+
+#include "../IStream.h"
+#include "../../Windows/Synchronization.h"
+
+class CStreamBinder
+{
+  NWindows::NSynchronization::CManualResetEvent _allBytesAreWritenEvent;
+  NWindows::NSynchronization::CManualResetEvent _thereAreBytesToReadEvent;
+  NWindows::NSynchronization::CManualResetEvent _readStreamIsClosedEvent;
+  UInt32 _bufferSize;
+  const void *_buffer;
+public:
+  // bool ReadingWasClosed;
+  UInt64 ProcessedSize;
+  CStreamBinder() {}
+  HRes CreateEvents();
+
+  void CreateStreams(ISequentialInStream **inStream, 
+      ISequentialOutStream **outStream);
+  HRESULT Read(void *data, UInt32 size, UInt32 *processedSize);
+  void CloseRead();
+
+  HRESULT Write(const void *data, UInt32 size, UInt32 *processedSize);
+  void CloseWrite();
+  void ReInit();
+};
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/misc/libphysfs/lzma/CPP/7zip/Common/StreamObjects.cpp	Mon Apr 10 12:06:43 2017 -0400
@@ -0,0 +1,68 @@
+// StreamObjects.cpp
+
+#include "StdAfx.h"
+
+#include "StreamObjects.h"
+#include "../../Common/Defs.h"
+
+
+STDMETHODIMP CSequentialInStreamImp::Read(void *data, UInt32 size, UInt32 *processedSize)
+{
+  UInt32 numBytesToRead = (UInt32)(MyMin(_pos + size, _size) - _pos);
+  memmove(data, _dataPointer + _pos, numBytesToRead);
+  _pos += numBytesToRead;
+  if(processedSize != NULL)
+    *processedSize = numBytesToRead;
+  return S_OK;
+}
+
+
+void CWriteBuffer::Write(const void *data, size_t size)
+{
+  size_t newCapacity = _size + size;
+  _buffer.EnsureCapacity(newCapacity);
+  memmove(_buffer + _size, data, size);
+  _size += size;
+}
+
+STDMETHODIMP CSequentialOutStreamImp::Write(const void *data, UInt32 size, UInt32 *processedSize)
+{
+  _writeBuffer.Write(data, size);
+  if(processedSize != NULL)
+    *processedSize = size;
+  return S_OK; 
+}
+
+STDMETHODIMP CSequentialOutStreamImp2::Write(const void *data, UInt32 size, UInt32 *processedSize)
+{
+  UInt32 newSize = size;
+  if (_pos + size > _size)
+    newSize = (UInt32)(_size - _pos);
+  memmove(_buffer + _pos, data, newSize);
+  if(processedSize != NULL)
+    *processedSize = newSize;
+  _pos += newSize;
+  if (newSize != size)
+    return E_FAIL;
+  return S_OK; 
+}
+
+STDMETHODIMP CSequentialInStreamSizeCount::Read(void *data, UInt32 size, UInt32 *processedSize)
+{
+  UInt32 realProcessedSize;
+  HRESULT result = _stream->Read(data, size, &realProcessedSize);
+  _size += realProcessedSize;
+  if (processedSize != 0)
+    *processedSize = realProcessedSize;
+  return result; 
+}
+
+STDMETHODIMP CSequentialOutStreamSizeCount::Write(const void *data, UInt32 size, UInt32 *processedSize)
+{
+  UInt32 realProcessedSize;
+  HRESULT result = _stream->Write(data, size, &realProcessedSize);
+  _size += realProcessedSize;
+  if (processedSize != 0)
+    *processedSize = realProcessedSize;
+  return result; 
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/misc/libphysfs/lzma/CPP/7zip/Common/StreamObjects.h	Mon Apr 10 12:06:43 2017 -0400
@@ -0,0 +1,117 @@
+// StreamObjects.h
+
+#ifndef __STREAMOBJECTS_H
+#define __STREAMOBJECTS_H
+
+#include "../../Common/DynamicBuffer.h"
+#include "../../Common/MyCom.h"
+#include "../IStream.h"
+
+class CSequentialInStreamImp: 
+  public ISequentialInStream,
+  public CMyUnknownImp
+{
+  const Byte *_dataPointer;
+  size_t _size;
+  size_t _pos;
+
+public:
+  void Init(const Byte *dataPointer, size_t size)
+  {
+    _dataPointer = dataPointer;
+    _size = size;
+    _pos = 0;
+  }
+
+  MY_UNKNOWN_IMP
+
+  STDMETHOD(Read)(void *data, UInt32 size, UInt32 *processedSize);
+};
+
+
+class CWriteBuffer
+{
+  CByteDynamicBuffer _buffer;
+  size_t _size;
+public:
+  CWriteBuffer(): _size(0) {}
+  void Init() { _size = 0;  }
+  void Write(const void *data, size_t size);
+  size_t GetSize() const { return _size; }
+  const CByteDynamicBuffer& GetBuffer() const { return _buffer; }
+};
+
+class CSequentialOutStreamImp: 
+  public ISequentialOutStream,
+  public CMyUnknownImp
+{
+  CWriteBuffer _writeBuffer;
+public:
+  void Init() { _writeBuffer.Init(); }
+  size_t GetSize() const { return _writeBuffer.GetSize(); }
+  const CByteDynamicBuffer& GetBuffer() const { return _writeBuffer.GetBuffer(); }
+
+  MY_UNKNOWN_IMP
+
+  STDMETHOD(Write)(const void *data, UInt32 size, UInt32 *processedSize);
+};
+
+class CSequentialOutStreamImp2: 
+  public ISequentialOutStream,
+  public CMyUnknownImp
+{
+  Byte *_buffer;
+  size_t _size;
+  size_t _pos;
+public:
+
+  void Init(Byte *buffer, size_t size)  
+  { 
+    _buffer = buffer;
+    _pos = 0;
+    _size = size; 
+  }
+
+  size_t GetPos() const { return _pos; }
+
+  MY_UNKNOWN_IMP
+
+  STDMETHOD(Write)(const void *data, UInt32 size, UInt32 *processedSize);
+};
+
+class CSequentialInStreamSizeCount: 
+  public ISequentialInStream,
+  public CMyUnknownImp
+{
+  CMyComPtr<ISequentialInStream> _stream;
+  UInt64 _size;
+public:
+  void Init(ISequentialInStream *stream)
+  {
+    _stream = stream;
+    _size = 0;
+  }
+  UInt64 GetSize() const { return _size; }
+
+  MY_UNKNOWN_IMP
+
+  STDMETHOD(Read)(void *data, UInt32 size, UInt32 *processedSize);
+};
+
+class CSequentialOutStreamSizeCount: 
+  public ISequentialOutStream,
+  public CMyUnknownImp
+{
+  CMyComPtr<ISequentialOutStream> _stream;
+  UInt64 _size;
+public:
+  void SetStream(ISequentialOutStream *stream) { _stream = stream; }
+  void Init() { _size = 0; }
+  UInt64 GetSize() const { return _size; }
+
+  MY_UNKNOWN_IMP
+
+  STDMETHOD(Write)(const void *data, UInt32 size, UInt32 *processedSize);
+};
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/misc/libphysfs/lzma/CPP/7zip/Common/StreamUtils.cpp	Mon Apr 10 12:06:43 2017 -0400
@@ -0,0 +1,44 @@
+// StreamUtils.cpp
+
+#include "StdAfx.h"
+
+#include "../../Common/MyCom.h"
+#include "StreamUtils.h"
+
+HRESULT ReadStream(ISequentialInStream *stream, void *data, UInt32 size, UInt32 *processedSize)
+{
+  if (processedSize != 0)
+    *processedSize = 0;
+  while(size != 0)
+  {
+    UInt32 processedSizeLoc; 
+    HRESULT res = stream->Read(data, size, &processedSizeLoc);
+    if (processedSize != 0)
+      *processedSize += processedSizeLoc;
+    data = (Byte *)((Byte *)data + processedSizeLoc);
+    size -= processedSizeLoc;
+    RINOK(res);
+    if (processedSizeLoc == 0)
+      return S_OK;
+  }
+  return S_OK;
+}
+
+HRESULT WriteStream(ISequentialOutStream *stream, const void *data, UInt32 size, UInt32 *processedSize)
+{
+  if (processedSize != 0)
+    *processedSize = 0;
+  while(size != 0)
+  {
+    UInt32 processedSizeLoc; 
+    HRESULT res = stream->Write(data, size, &processedSizeLoc);
+    if (processedSize != 0)
+      *processedSize += processedSizeLoc;
+    data = (const void *)((const Byte *)data + processedSizeLoc);
+    size -= processedSizeLoc;
+    RINOK(res);
+    if (processedSizeLoc == 0)
+      return E_FAIL;
+  }
+  return S_OK;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/misc/libphysfs/lzma/CPP/7zip/Common/StreamUtils.h	Mon Apr 10 12:06:43 2017 -0400
@@ -0,0 +1,11 @@
+// StreamUtils.h
+
+#ifndef __STREAMUTILS_H
+#define __STREAMUTILS_H
+
+#include "../IStream.h"
+
+HRESULT ReadStream(ISequentialInStream *stream, void *data, UInt32 size, UInt32 *processedSize);
+HRESULT WriteStream(ISequentialOutStream *stream, const void *data, UInt32 size, UInt32 *processedSize);
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/misc/libphysfs/lzma/CPP/7zip/Common/VirtThread.cpp	Mon Apr 10 12:06:43 2017 -0400
@@ -0,0 +1,45 @@
+// VirtThread.cpp
+
+#include "StdAfx.h"
+
+#include "VirtThread.h"
+
+static THREAD_FUNC_DECL CoderThread(void *p)
+{
+  for (;;)
+  {
+    CVirtThread *t = (CVirtThread *)p;
+    t->StartEvent.Lock();
+    if (t->ExitEvent)
+      return 0;
+    t->Execute();
+    t->FinishedEvent.Set();
+  }
+}
+
+HRes CVirtThread::Create()
+{
+  RINOK(StartEvent.CreateIfNotCreated());
+  RINOK(FinishedEvent.CreateIfNotCreated());
+  StartEvent.Reset();
+  FinishedEvent.Reset();
+  ExitEvent = false;
+  if (Thread.IsCreated())
+    return S_OK;
+  return Thread.Create(CoderThread, this);
+}
+
+void CVirtThread::Start()
+{
+  ExitEvent = false;
+  StartEvent.Set();
+}
+
+CVirtThread::~CVirtThread()
+{
+  ExitEvent = true;
+  if (StartEvent.IsCreated())
+    StartEvent.Set();
+  Thread.Wait();
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/misc/libphysfs/lzma/CPP/7zip/Common/VirtThread.h	Mon Apr 10 12:06:43 2017 -0400
@@ -0,0 +1,23 @@
+// VirtThread.h
+
+#ifndef __VIRTTHREAD_H
+#define __VIRTTHREAD_H
+
+#include "../../Windows/Synchronization.h"
+#include "../../Windows/Thread.h"
+
+struct CVirtThread
+{
+  NWindows::NSynchronization::CAutoResetEvent StartEvent;
+  NWindows::NSynchronization::CAutoResetEvent FinishedEvent;
+  NWindows::CThread Thread;
+  bool ExitEvent;
+
+  ~CVirtThread();
+  HRes Create();
+  void Start();
+  void WaitFinish() { FinishedEvent.Lock(); } 
+  virtual void Execute() = 0;
+};
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/misc/libphysfs/lzma/CPP/7zip/Compress/Branch/ARM.cpp	Mon Apr 10 12:06:43 2017 -0400
@@ -0,0 +1,19 @@
+// ARM.cpp
+
+#include "StdAfx.h"
+#include "ARM.h"
+
+extern "C" 
+{ 
+#include "../../../../C/Compress/Branch/BranchARM.h"
+}
+
+UInt32 CBC_ARM_Encoder::SubFilter(Byte *data, UInt32 size)
+{
+  return ::ARM_Convert(data, size, _bufferPos, 1);
+}
+
+UInt32 CBC_ARM_Decoder::SubFilter(Byte *data, UInt32 size)
+{
+  return ::ARM_Convert(data, size, _bufferPos, 0);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/misc/libphysfs/lzma/CPP/7zip/Compress/Branch/ARM.h	Mon Apr 10 12:06:43 2017 -0400
@@ -0,0 +1,10 @@
+// ARM.h
+
+#ifndef __ARM_H
+#define __ARM_H
+
+#include "BranchCoder.h"
+
+MyClassA(BC_ARM, 0x05, 1)
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/misc/libphysfs/lzma/CPP/7zip/Compress/Branch/ARMThumb.cpp	Mon Apr 10 12:06:43 2017 -0400
@@ -0,0 +1,20 @@
+// ARMThumb.cpp
+
+#include "StdAfx.h"
+
+#include "ARMThumb.h"
+
+extern "C" 
+{ 
+#include "../../../../C/Compress/Branch/BranchARMThumb.h"
+}
+
+UInt32 CBC_ARMThumb_Encoder::SubFilter(Byte *data, UInt32 size)
+{
+  return ::ARMThumb_Convert(data, size, _bufferPos, 1);
+}
+
+UInt32 CBC_ARMThumb_Decoder::SubFilter(Byte *data, UInt32 size)
+{
+  return ::ARMThumb_Convert(data, size, _bufferPos, 0);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/misc/libphysfs/lzma/CPP/7zip/Compress/Branch/ARMThumb.h	Mon Apr 10 12:06:43 2017 -0400
@@ -0,0 +1,10 @@
+// ARMThumb.h
+
+#ifndef __ARMTHUMB_H
+#define __ARMTHUMB_H
+
+#include "BranchCoder.h"
+
+MyClassA(BC_ARMThumb, 0x07, 1)
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/misc/libphysfs/lzma/CPP/7zip/Compress/Branch/BCJ2Register.cpp	Mon Apr 10 12:06:43 2017 -0400
@@ -0,0 +1,18 @@
+// BranchRegister.cpp
+
+#include "StdAfx.h"
+
+#include "../../Common/RegisterCodec.h"
+
+#include "x86_2.h"
+static void *CreateCodec() { return (void *)(ICompressCoder2 *)(new NCompress::NBcj2::CDecoder()); }
+#ifndef EXTRACT_ONLY
+static void *CreateCodecOut() { return (void *)(ICompressCoder2 *)(new NCompress::NBcj2::CEncoder());  }
+#else
+#define CreateCodecOut 0
+#endif
+
+static CCodecInfo g_CodecInfo =
+  { CreateCodec, CreateCodecOut, 0x0303011B, L"BCJ2", 4, false };
+
+REGISTER_CODEC(BCJ2)
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/misc/libphysfs/lzma/CPP/7zip/Compress/Branch/BCJRegister.cpp	Mon Apr 10 12:06:43 2017 -0400
@@ -0,0 +1,18 @@
+// BranchRegister.cpp
+
+#include "StdAfx.h"
+
+#include "../../Common/RegisterCodec.h"
+
+#include "x86.h"
+static void *CreateCodec() { return (void *)(ICompressFilter *)(new CBCJ_x86_Decoder()); }
+#ifndef EXTRACT_ONLY
+static void *CreateCodecOut() { return (void *)(ICompressFilter *)(new CBCJ_x86_Encoder());  }
+#else
+#define CreateCodecOut 0
+#endif
+
+static CCodecInfo g_CodecInfo =
+  { CreateCodec, CreateCodecOut, 0x03030103, L"BCJ", 1, true };
+
+REGISTER_CODEC(BCJ)
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/misc/libphysfs/lzma/CPP/7zip/Compress/Branch/BranchCoder.cpp	Mon Apr 10 12:06:43 2017 -0400
@@ -0,0 +1,18 @@
+// BranchCoder.cpp
+
+#include "StdAfx.h"
+#include "BranchCoder.h"
+
+STDMETHODIMP CBranchConverter::Init()
+{
+  _bufferPos = 0;
+  SubInit();
+  return S_OK;
+}
+
+STDMETHODIMP_(UInt32) CBranchConverter::Filter(Byte *data, UInt32 size)
+{
+  UInt32 processedSize = SubFilter(data, size);
+  _bufferPos += processedSize;
+  return processedSize;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/misc/libphysfs/lzma/CPP/7zip/Compress/Branch/BranchCoder.h	Mon Apr 10 12:06:43 2017 -0400
@@ -0,0 +1,45 @@
+// BranchCoder.h
+
+#ifndef __BRANCH_CODER_H
+#define __BRANCH_CODER_H
+
+#include "Common/MyCom.h"
+#include "Common/Types.h"
+
+#include "../../ICoder.h"
+
+class CBranchConverter:
+  public ICompressFilter,
+  public CMyUnknownImp
+{
+protected:
+  UInt32 _bufferPos;
+  virtual void SubInit() {}
+  virtual UInt32 SubFilter(Byte *data, UInt32 size) = 0;
+public:
+  MY_UNKNOWN_IMP;
+  STDMETHOD(Init)();
+  STDMETHOD_(UInt32, Filter)(Byte *data, UInt32 size);
+};
+
+#define MyClassEncoderA(Name) class C ## Name: public CBranchConverter \
+  { public: UInt32 SubFilter(Byte *data, UInt32 size); }; 
+
+#define MyClassDecoderA(Name) class C ## Name: public CBranchConverter \
+  { public: UInt32 SubFilter(Byte *data, UInt32 size); }; 
+
+#define MyClassEncoderB(Name, ADD_ITEMS, ADD_INIT) class C ## Name: public CBranchConverter, public ADD_ITEMS \
+  { public: UInt32 SubFilter(Byte *data, UInt32 size); ADD_INIT}; 
+
+#define MyClassDecoderB(Name, ADD_ITEMS, ADD_INIT) class C ## Name: public CBranchConverter, public ADD_ITEMS \
+  { public: UInt32 SubFilter(Byte *data, UInt32 size); ADD_INIT}; 
+
+#define MyClassA(Name, id, subId)  \
+MyClassEncoderA(Name ## _Encoder) \
+MyClassDecoderA(Name ## _Decoder)
+
+#define MyClassB(Name, id, subId, ADD_ITEMS, ADD_INIT)  \
+MyClassEncoderB(Name ## _Encoder, ADD_ITEMS, ADD_INIT) \
+MyClassDecoderB(Name ## _Decoder, ADD_ITEMS, ADD_INIT)
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/misc/libphysfs/lzma/CPP/7zip/Compress/Branch/BranchRegister.cpp	Mon Apr 10 12:06:43 2017 -0400
@@ -0,0 +1,34 @@
+// BranchRegister.cpp
+
+#include "StdAfx.h"
+
+#include "../../Common/RegisterCodec.h"
+
+#include "PPC.h"
+#include "IA64.h"
+#include "ARM.h"
+#include "ARMThumb.h"
+#include "SPARC.h"
+
+#define CREATE_CODEC(x) \
+  static void *CreateCodec ## x() { return (void *)(ICompressFilter *)(new C ## x ## _Decoder); } \
+  static void *CreateCodec ## x ## Out() { return (void *)(ICompressFilter *)(new C ## x ## _Encoder); }
+
+CREATE_CODEC(BC_PPC_B)
+CREATE_CODEC(BC_IA64)
+CREATE_CODEC(BC_ARM)
+CREATE_CODEC(BC_ARMThumb)
+CREATE_CODEC(BC_SPARC)
+
+#define METHOD_ITEM(x, id1, id2, name) { CreateCodec ## x, CreateCodec ## x ## Out, 0x03030000 + (id1 * 256) + id2, name, 1, true  }
+
+static CCodecInfo g_CodecsInfo[] =
+{
+  METHOD_ITEM(BC_PPC_B,   0x02, 0x05, L"BC_PPC_B"),
+  METHOD_ITEM(BC_IA64,    0x04, 1, L"BC_IA64"),
+  METHOD_ITEM(BC_ARM,     0x05, 1, L"BC_ARM"),
+  METHOD_ITEM(BC_ARMThumb,0x07, 1, L"BC_ARMThumb"),
+  METHOD_ITEM(BC_SPARC,   0x08, 0x05, L"BC_SPARC")
+};
+
+REGISTER_CODECS(Branch)
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/misc/libphysfs/lzma/CPP/7zip/Compress/Branch/IA64.cpp	Mon Apr 10 12:06:43 2017 -0400
@@ -0,0 +1,19 @@
+// IA64.cpp
+
+#include "StdAfx.h"
+#include "IA64.h"
+
+extern "C" 
+{ 
+#include "../../../../C/Compress/Branch/BranchIA64.h"
+}
+
+UInt32 CBC_IA64_Encoder::SubFilter(Byte *data, UInt32 size)
+{
+  return ::IA64_Convert(data, size, _bufferPos, 1);
+}
+
+UInt32 CBC_IA64_Decoder::SubFilter(Byte *data, UInt32 size)
+{
+  return ::IA64_Convert(data, size, _bufferPos, 0);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/misc/libphysfs/lzma/CPP/7zip/Compress/Branch/IA64.h	Mon Apr 10 12:06:43 2017 -0400
@@ -0,0 +1,10 @@
+// IA64.h
+
+#ifndef __IA64_H
+#define __IA64_H
+
+#include "BranchCoder.h"
+
+MyClassA(BC_IA64, 0x04, 1)
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/misc/libphysfs/lzma/CPP/7zip/Compress/Branch/PPC.cpp	Mon Apr 10 12:06:43 2017 -0400
@@ -0,0 +1,19 @@
+// PPC.cpp
+
+#include "StdAfx.h"
+#include "PPC.h"
+
+extern "C" 
+{ 
+#include "../../../../C/Compress/Branch/BranchPPC.h"
+}
+
+UInt32 CBC_PPC_B_Encoder::SubFilter(Byte *data, UInt32 size)
+{
+  return ::PPC_B_Convert(data, size, _bufferPos, 1);
+}
+
+UInt32 CBC_PPC_B_Decoder::SubFilter(Byte *data, UInt32 size)
+{
+  return ::PPC_B_Convert(data, size, _bufferPos, 0);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/misc/libphysfs/lzma/CPP/7zip/Compress/Branch/PPC.h	Mon Apr 10 12:06:43 2017 -0400
@@ -0,0 +1,10 @@
+// PPC.h
+
+#ifndef __PPC_H
+#define __PPC_H
+
+#include "BranchCoder.h"
+
+MyClassA(BC_PPC_B, 0x02, 5)
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/misc/libphysfs/lzma/CPP/7zip/Compress/Branch/SPARC.cpp	Mon Apr 10 12:06:43 2017 -0400
@@ -0,0 +1,19 @@
+// SPARC.cpp
+
+#include "StdAfx.h"
+#include "SPARC.h"
+
+extern "C" 
+{ 
+#include "../../../../C/Compress/Branch/BranchSPARC.h"
+}
+
+UInt32 CBC_SPARC_Encoder::SubFilter(Byte *data, UInt32 size)
+{
+  return ::SPARC_Convert(data, size, _bufferPos, 1);
+}
+
+UInt32 CBC_SPARC_Decoder::SubFilter(Byte *data, UInt32 size)
+{
+  return ::SPARC_Convert(data, size, _bufferPos, 0);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/misc/libphysfs/lzma/CPP/7zip/Compress/Branch/SPARC.h	Mon Apr 10 12:06:43 2017 -0400
@@ -0,0 +1,10 @@
+// SPARC.h
+
+#ifndef __SPARC_H
+#define __SPARC_H
+
+#include "BranchCoder.h"
+
+MyClassA(BC_SPARC, 0x08, 5)
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/misc/libphysfs/lzma/CPP/7zip/Compress/Branch/StdAfx.cpp	Mon Apr 10 12:06:43 2017 -0400
@@ -0,0 +1,3 @@
+// StdAfx.cpp
+
+#include "StdAfx.h"
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/misc/libphysfs/lzma/CPP/7zip/Compress/Branch/StdAfx.h	Mon Apr 10 12:06:43 2017 -0400
@@ -0,0 +1,8 @@
+// StdAfx.h
+
+#ifndef __STDAFX_H
+#define __STDAFX_H
+
+#include "../../../Common/MyWindows.h"
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/misc/libphysfs/lzma/CPP/7zip/Compress/Branch/x86.cpp	Mon Apr 10 12:06:43 2017 -0400
@@ -0,0 +1,14 @@
+// x86.cpp
+
+#include "StdAfx.h"
+#include "x86.h"
+
+UInt32 CBCJ_x86_Encoder::SubFilter(Byte *data, UInt32 size)
+{
+  return (UInt32)::x86_Convert(data, size, _bufferPos, &_prevMask, 1);
+}
+
+UInt32 CBCJ_x86_Decoder::SubFilter(Byte *data, UInt32 size)
+{
+  return (UInt32)::x86_Convert(data, size, _bufferPos, &_prevMask, 0);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/misc/libphysfs/lzma/CPP/7zip/Compress/Branch/x86.h	Mon Apr 10 12:06:43 2017 -0400
@@ -0,0 +1,21 @@
+// x86.h
+
+#ifndef __X86_H
+#define __X86_H
+
+#include "BranchCoder.h"
+extern "C" 
+{ 
+#include "../../../../C/Compress/Branch/BranchX86.h"
+}
+
+struct CBranch86
+{
+  UInt32 _prevMask;
+  void x86Init() { x86_Convert_Init(_prevMask); }
+};
+
+MyClassB(BCJ_x86, 0x01, 3, CBranch86 , 
+    virtual void SubInit() { x86Init(); })
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/misc/libphysfs/lzma/CPP/7zip/Compress/Branch/x86_2.cpp	Mon Apr 10 12:06:43 2017 -0400
@@ -0,0 +1,392 @@
+// x86_2.cpp
+
+#include "StdAfx.h"
+#include "x86_2.h"
+
+extern "C" 
+{ 
+#include "../../../../C/Alloc.h"
+}
+
+namespace NCompress {
+namespace NBcj2 {
+
+inline bool IsJcc(Byte b0, Byte b1) { return (b0 == 0x0F && (b1 & 0xF0) == 0x80); }
+inline bool IsJ(Byte b0, Byte b1) { return ((b1 & 0xFE) == 0xE8 || IsJcc(b0, b1)); }
+inline unsigned GetIndex(Byte b0, Byte b1) { return ((b1 == 0xE8) ? b0 : ((b1 == 0xE9) ? 256 : 257)); }
+
+#ifndef EXTRACT_ONLY
+
+static const int kBufferSize = 1 << 17;
+
+static bool inline Test86MSByte(Byte b)
+{
+  return (b == 0 || b == 0xFF);
+}
+
+bool CEncoder::Create()
+{
+  if (!_mainStream.Create(1 << 16))
+    return false;
+  if (!_callStream.Create(1 << 20))
+    return false;
+  if (!_jumpStream.Create(1 << 20))
+    return false;
+  if (!_rangeEncoder.Create(1 << 20))
+    return false;
+  if (_buffer == 0)
+  {
+    _buffer = (Byte *)MidAlloc(kBufferSize);
+    if (_buffer == 0)
+      return false;
+  }
+  return true;
+}
+
+CEncoder::~CEncoder()
+{
+  ::MidFree(_buffer);
+}
+
+HRESULT CEncoder::Flush()
+{
+  RINOK(_mainStream.Flush());
+  RINOK(_callStream.Flush());
+  RINOK(_jumpStream.Flush());
+  _rangeEncoder.FlushData();
+  return _rangeEncoder.FlushStream();
+}
+
+const UInt32 kDefaultLimit = (1 << 24);
+
+HRESULT CEncoder::CodeReal(ISequentialInStream **inStreams,
+      const UInt64 **inSizes,
+      UInt32 numInStreams,
+      ISequentialOutStream **outStreams,
+      const UInt64 ** /* outSizes */,
+      UInt32 numOutStreams,
+      ICompressProgressInfo *progress)
+{
+  if (numInStreams != 1 || numOutStreams != 4)
+    return E_INVALIDARG;
+
+  if (!Create())
+    return E_OUTOFMEMORY;
+
+  bool sizeIsDefined = false;
+  UInt64 inSize = 0;
+  if (inSizes != NULL)
+    if (inSizes[0] != NULL)
+    {
+      inSize = *inSizes[0];
+      if (inSize <= kDefaultLimit)
+        sizeIsDefined = true;
+    }
+
+  ISequentialInStream *inStream = inStreams[0];
+
+  _mainStream.SetStream(outStreams[0]);
+  _mainStream.Init();
+  _callStream.SetStream(outStreams[1]);
+  _callStream.Init();
+  _jumpStream.SetStream(outStreams[2]);
+  _jumpStream.Init();
+  _rangeEncoder.SetStream(outStreams[3]);
+  _rangeEncoder.Init();
+  for (int i = 0; i < 256 + 2; i++)
+    _statusEncoder[i].Init();
+  CCoderReleaser releaser(this);
+
+  CMyComPtr<ICompressGetSubStreamSize> getSubStreamSize;
+  {
+    inStream->QueryInterface(IID_ICompressGetSubStreamSize, (void **)&getSubStreamSize);
+  }
+
+  UInt32 nowPos = 0;
+  UInt64 nowPos64 = 0;
+  UInt32 bufferPos = 0;
+
+  Byte prevByte = 0;
+
+  UInt64 subStreamIndex = 0;
+  UInt64 subStreamStartPos  = 0;
+  UInt64 subStreamEndPos = 0;
+
+  for (;;)
+  {
+    UInt32 processedSize = 0;
+    for (;;)
+    {
+      UInt32 size = kBufferSize - (bufferPos + processedSize);
+      UInt32 processedSizeLoc;
+      if (size == 0)
+        break;
+      RINOK(inStream->Read(_buffer + bufferPos + processedSize, size, &processedSizeLoc));
+      if (processedSizeLoc == 0)
+        break;
+      processedSize += processedSizeLoc;
+    }
+    UInt32 endPos = bufferPos + processedSize;
+    
+    if (endPos < 5)
+    {
+      // change it 
+      for (bufferPos = 0; bufferPos < endPos; bufferPos++)
+      {
+        Byte b = _buffer[bufferPos];
+        _mainStream.WriteByte(b);
+        UInt32 index;
+        if (b == 0xE8)
+          index = prevByte;
+        else if (b == 0xE9)
+          index = 256;
+        else if (IsJcc(prevByte, b))
+          index = 257;
+        else
+        {
+          prevByte = b;
+          continue;
+        }
+        _statusEncoder[index].Encode(&_rangeEncoder, 0);
+        prevByte = b;
+      }
+      return Flush();
+    }
+
+    bufferPos = 0;
+
+    UInt32 limit = endPos - 5;
+    while(bufferPos <= limit)
+    {
+      Byte b = _buffer[bufferPos];
+      _mainStream.WriteByte(b);
+      if (!IsJ(prevByte, b))
+      {
+        bufferPos++;
+        prevByte = b;
+        continue;
+      }
+      Byte nextByte = _buffer[bufferPos + 4];
+      UInt32 src = 
+        (UInt32(nextByte) << 24) |
+        (UInt32(_buffer[bufferPos + 3]) << 16) |
+        (UInt32(_buffer[bufferPos + 2]) << 8) |
+        (_buffer[bufferPos + 1]);
+      UInt32 dest = (nowPos + bufferPos + 5) + src;
+      // if (Test86MSByte(nextByte))
+      bool convert;
+      if (getSubStreamSize != NULL)
+      {
+        UInt64 currentPos = (nowPos64 + bufferPos);
+        while (subStreamEndPos < currentPos)
+        {
+          UInt64 subStreamSize;
+          HRESULT result = getSubStreamSize->GetSubStreamSize(subStreamIndex, &subStreamSize);
+          if (result == S_OK)
+          {
+            subStreamStartPos = subStreamEndPos;
+            subStreamEndPos += subStreamSize;          
+            subStreamIndex++;
+          }
+          else if (result == S_FALSE || result == E_NOTIMPL)
+          {
+            getSubStreamSize.Release();
+            subStreamStartPos = 0;
+            subStreamEndPos = subStreamStartPos - 1;          
+          }
+          else
+            return result;
+        }
+        if (getSubStreamSize == NULL)
+        {
+          if (sizeIsDefined)
+            convert = (dest < inSize);
+          else
+            convert = Test86MSByte(nextByte);
+        }
+        else if (subStreamEndPos - subStreamStartPos > kDefaultLimit)
+          convert = Test86MSByte(nextByte);
+        else
+        {
+          UInt64 dest64 = (currentPos + 5) + Int64(Int32(src));
+          convert = (dest64 >= subStreamStartPos && dest64 < subStreamEndPos);
+        }
+      }
+      else if (sizeIsDefined)
+        convert = (dest < inSize);
+      else
+        convert = Test86MSByte(nextByte);
+      unsigned index = GetIndex(prevByte, b);
+      if (convert)
+      {
+        _statusEncoder[index].Encode(&_rangeEncoder, 1);
+        bufferPos += 5;
+        COutBuffer &s = (b == 0xE8) ? _callStream : _jumpStream;
+        for (int i = 24; i >= 0; i -= 8)
+          s.WriteByte((Byte)(dest >> i));
+        prevByte = nextByte;
+      }
+      else
+      {
+        _statusEncoder[index].Encode(&_rangeEncoder, 0);
+        bufferPos++;
+        prevByte = b;
+      }
+    }
+    nowPos += bufferPos;
+    nowPos64 += bufferPos;
+
+    if (progress != NULL)
+    {
+      /*
+      const UInt64 compressedSize = 
+        _mainStream.GetProcessedSize() + 
+        _callStream.GetProcessedSize() +
+        _jumpStream.GetProcessedSize() +
+        _rangeEncoder.GetProcessedSize();
+      */
+      RINOK(progress->SetRatioInfo(&nowPos64, NULL));
+    }
+ 
+    UInt32 i = 0;
+    while(bufferPos < endPos)
+      _buffer[i++] = _buffer[bufferPos++];
+    bufferPos = i;
+  }
+}
+
+STDMETHODIMP CEncoder::Code(ISequentialInStream **inStreams,
+      const UInt64 **inSizes,
+      UInt32 numInStreams,
+      ISequentialOutStream **outStreams,
+      const UInt64 **outSizes,
+      UInt32 numOutStreams,
+      ICompressProgressInfo *progress)
+{
+  try
+  {
+    return CodeReal(inStreams, inSizes, numInStreams,
+      outStreams, outSizes,numOutStreams, progress);
+  }
+  catch(const COutBufferException &e) { return e.ErrorCode; }
+  catch(...) { return S_FALSE; }
+}
+
+#endif
+
+HRESULT CDecoder::CodeReal(ISequentialInStream **inStreams,
+      const UInt64 ** /* inSizes */,
+      UInt32 numInStreams,
+      ISequentialOutStream **outStreams,
+      const UInt64 ** /* outSizes */,
+      UInt32 numOutStreams,
+      ICompressProgressInfo *progress)
+{
+  if (numInStreams != 4 || numOutStreams != 1)
+    return E_INVALIDARG;
+
+  if (!_mainInStream.Create(1 << 16))
+    return E_OUTOFMEMORY;
+  if (!_callStream.Create(1 << 20))
+    return E_OUTOFMEMORY;
+  if (!_jumpStream.Create(1 << 16))
+    return E_OUTOFMEMORY;
+  if (!_rangeDecoder.Create(1 << 20))
+    return E_OUTOFMEMORY;
+  if (!_outStream.Create(1 << 16))
+    return E_OUTOFMEMORY;
+
+  _mainInStream.SetStream(inStreams[0]);
+  _callStream.SetStream(inStreams[1]);
+  _jumpStream.SetStream(inStreams[2]);
+  _rangeDecoder.SetStream(inStreams[3]);
+  _outStream.SetStream(outStreams[0]);
+
+  _mainInStream.Init();
+  _callStream.Init();
+  _jumpStream.Init();
+  _rangeDecoder.Init();
+  _outStream.Init();
+
+  for (int i = 0; i < 256 + 2; i++)
+    _statusDecoder[i].Init();
+
+  CCoderReleaser releaser(this);
+
+  Byte prevByte = 0;
+  UInt32 processedBytes = 0;
+  for (;;)
+  {
+    if (processedBytes >= (1 << 20) && progress != NULL)
+    {
+      /*
+      const UInt64 compressedSize = 
+        _mainInStream.GetProcessedSize() + 
+        _callStream.GetProcessedSize() +
+        _jumpStream.GetProcessedSize() +
+        _rangeDecoder.GetProcessedSize();
+      */
+      const UInt64 nowPos64 = _outStream.GetProcessedSize();
+      RINOK(progress->SetRatioInfo(NULL, &nowPos64));
+      processedBytes = 0;
+    }
+    UInt32 i;
+    Byte b = 0;
+    const UInt32 kBurstSize = (1 << 18);
+    for (i = 0; i < kBurstSize; i++)
+    {
+      if (!_mainInStream.ReadByte(b))
+        return Flush();
+      _outStream.WriteByte(b);
+      if (IsJ(prevByte, b))
+        break;
+      prevByte = b;
+    }
+    processedBytes += i;
+    if (i == kBurstSize)
+      continue;
+    unsigned index = GetIndex(prevByte, b);
+    if (_statusDecoder[index].Decode(&_rangeDecoder) == 1)
+    {
+      UInt32 src = 0;
+      CInBuffer &s = (b == 0xE8) ? _callStream : _jumpStream;
+      for (int i = 0; i < 4; i++)
+      {
+        Byte b0;
+        if(!s.ReadByte(b0))
+          return S_FALSE;
+        src <<= 8;
+        src |= ((UInt32)b0);
+      }
+      UInt32 dest = src - (UInt32(_outStream.GetProcessedSize()) + 4) ;
+      _outStream.WriteByte((Byte)(dest));
+      _outStream.WriteByte((Byte)(dest >> 8));
+      _outStream.WriteByte((Byte)(dest >> 16));
+      _outStream.WriteByte((Byte)(dest >> 24));
+      prevByte = (Byte)(dest >> 24);
+      processedBytes += 4;
+    }
+    else
+      prevByte = b;
+  }
+}
+
+STDMETHODIMP CDecoder::Code(ISequentialInStream **inStreams,
+      const UInt64 **inSizes,
+      UInt32 numInStreams,
+      ISequentialOutStream **outStreams,
+      const UInt64 **outSizes,
+      UInt32 numOutStreams,
+      ICompressProgressInfo *progress)
+{
+  try
+  {
+    return CodeReal(inStreams, inSizes, numInStreams,
+        outStreams, outSizes,numOutStreams, progress);
+  }
+  catch(const CInBufferException &e) { return e.ErrorCode; }
+  catch(const COutBufferException &e) { return e.ErrorCode; }
+  catch(...) { return S_FALSE; }
+}
+
+}}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/misc/libphysfs/lzma/CPP/7zip/Compress/Branch/x86_2.h	Mon Apr 10 12:06:43 2017 -0400
@@ -0,0 +1,123 @@
+// x86_2.h
+
+#ifndef __BRANCH_X86_2_H
+#define __BRANCH_X86_2_H
+
+#include "../../../Common/MyCom.h"
+#include "../RangeCoder/RangeCoderBit.h"
+#include "../../ICoder.h"
+
+namespace NCompress {
+namespace NBcj2 {
+
+const int kNumMoveBits = 5;
+
+#ifndef EXTRACT_ONLY
+
+class CEncoder:
+  public ICompressCoder2,
+  public CMyUnknownImp
+{
+  Byte *_buffer;
+public:
+  CEncoder(): _buffer(0) {};
+  ~CEncoder();
+  bool Create();
+
+  COutBuffer _mainStream;
+  COutBuffer _callStream;
+  COutBuffer _jumpStream;
+  NCompress::NRangeCoder::CEncoder _rangeEncoder;
+  NCompress::NRangeCoder::CBitEncoder<kNumMoveBits> _statusEncoder[256 + 2];
+
+  HRESULT Flush();
+  void ReleaseStreams()
+  {
+    _mainStream.ReleaseStream();
+    _callStream.ReleaseStream();
+    _jumpStream.ReleaseStream();
+    _rangeEncoder.ReleaseStream();
+  }
+
+  class CCoderReleaser
+  {
+    CEncoder *_coder;
+  public:
+    CCoderReleaser(CEncoder *coder): _coder(coder) {}
+    ~CCoderReleaser() {  _coder->ReleaseStreams(); }
+  };
+
+public: 
+
+  MY_UNKNOWN_IMP
+
+  HRESULT CodeReal(ISequentialInStream **inStreams,
+      const UInt64 **inSizes,
+      UInt32 numInStreams,
+      ISequentialOutStream **outStreams,
+      const UInt64 **outSizes,
+      UInt32 numOutStreams,
+      ICompressProgressInfo *progress);
+  STDMETHOD(Code)(ISequentialInStream **inStreams,
+      const UInt64 **inSizes,
+      UInt32 numInStreams,
+      ISequentialOutStream **outStreams,
+      const UInt64 **outSizes,
+      UInt32 numOutStreams,
+      ICompressProgressInfo *progress);
+}; 
+
+#endif
+
+class CDecoder:
+  public ICompressCoder2,
+  public CMyUnknownImp
+{ 
+public:
+  CInBuffer _mainInStream;
+  CInBuffer _callStream;
+  CInBuffer _jumpStream;
+  NCompress::NRangeCoder::CDecoder _rangeDecoder;
+  NCompress::NRangeCoder::CBitDecoder<kNumMoveBits> _statusDecoder[256 + 2];
+
+  COutBuffer _outStream;
+
+  void ReleaseStreams()
+  {
+    _mainInStream.ReleaseStream();
+    _callStream.ReleaseStream();
+    _jumpStream.ReleaseStream();
+    _rangeDecoder.ReleaseStream();
+    _outStream.ReleaseStream();
+  }
+
+  HRESULT Flush() { return _outStream.Flush(); }
+  class CCoderReleaser
+  {
+    CDecoder *_coder;
+  public:
+    CCoderReleaser(CDecoder *coder): _coder(coder) {}
+    ~CCoderReleaser()  { _coder->ReleaseStreams(); }
+  };
+
+public: 
+  MY_UNKNOWN_IMP
+  HRESULT CodeReal(ISequentialInStream **inStreams,
+      const UInt64 **inSizes,
+      UInt32 numInStreams,
+      ISequentialOutStream **outStreams,
+      const UInt64 **outSizes,
+      UInt32 numOutStreams,
+      ICompressProgressInfo *progress);
+  STDMETHOD(Code)(ISequentialInStream **inStreams,
+      const UInt64 **inSizes,
+      UInt32 numInStreams,
+      ISequentialOutStream **outStreams,
+      const UInt64 **outSizes,
+      UInt32 numOutStreams,
+      ICompressProgressInfo *progress);
+}; 
+
+}}
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/misc/libphysfs/lzma/CPP/7zip/Compress/ByteSwap/ByteSwap.cpp	Mon Apr 10 12:06:43 2017 -0400
@@ -0,0 +1,38 @@
+// ByteSwap.cpp
+
+#include "StdAfx.h"
+
+#include "ByteSwap.h"
+
+STDMETHODIMP CByteSwap2::Init() { return S_OK; }
+
+STDMETHODIMP_(UInt32) CByteSwap2::Filter(Byte *data, UInt32 size)
+{
+  const UInt32 kStep = 2;
+  UInt32 i;
+  for (i = 0; i + kStep <= size; i += kStep)
+  {
+    Byte b = data[i];
+    data[i] = data[i + 1];
+    data[i + 1] = b;
+  }
+  return i;
+}
+
+STDMETHODIMP CByteSwap4::Init() { return S_OK; }
+
+STDMETHODIMP_(UInt32) CByteSwap4::Filter(Byte *data, UInt32 size)
+{
+  const UInt32 kStep = 4;
+  UInt32 i;
+  for (i = 0; i + kStep <= size; i += kStep)
+  {
+    Byte b0 = data[i];
+    Byte b1 = data[i + 1];
+    data[i] = data[i + 3];
+    data[i + 1] = data[i + 2];
+    data[i + 2] = b1;
+    data[i + 3] = b0;
+  }
+  return i;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/misc/libphysfs/lzma/CPP/7zip/Compress/ByteSwap/ByteSwap.h	Mon Apr 10 12:06:43 2017 -0400
@@ -0,0 +1,37 @@
+// ByteSwap.h
+
+#ifndef __BYTESWAP_H
+#define __BYTESWAP_H
+
+#include "../../ICoder.h"
+#include "Common/MyCom.h"
+
+// {23170F69-40C1-278B-0203-020000000000}
+DEFINE_GUID(CLSID_CCompressConvertByteSwap2, 
+0x23170F69, 0x40C1, 0x278B, 0x02, 0x03, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00);
+
+// {23170F69-40C1-278B-0203-040000000000}
+DEFINE_GUID(CLSID_CCompressConvertByteSwap4, 
+0x23170F69, 0x40C1, 0x278B, 0x02, 0x03, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00);
+
+class CByteSwap2: 
+  public ICompressFilter,
+  public CMyUnknownImp
+{
+public:
+  MY_UNKNOWN_IMP
+  STDMETHOD(Init)();
+  STDMETHOD_(UInt32, Filter)(Byte *data, UInt32 size);
+};
+
+class CByteSwap4: 
+  public ICompressFilter,
+  public CMyUnknownImp
+{
+public:
+  MY_UNKNOWN_IMP
+  STDMETHOD(Init)();
+  STDMETHOD_(UInt32, Filter)(Byte *data, UInt32 size);
+};
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/misc/libphysfs/lzma/CPP/7zip/Compress/ByteSwap/ByteSwapRegister.cpp	Mon Apr 10 12:06:43 2017 -0400
@@ -0,0 +1,17 @@
+// ByteSwapRegister.cpp
+
+#include "StdAfx.h"
+
+#include "../../Common/RegisterCodec.h"
+
+#include "ByteSwap.h"
+static void *CreateCodec2() { return (void *)(ICompressFilter *)(new CByteSwap2); }
+static void *CreateCodec4() { return (void *)(ICompressFilter *)(new CByteSwap4); }
+
+static CCodecInfo g_CodecsInfo[] =
+{
+  { CreateCodec2, CreateCodec4, 0x020302, L"Swap2", 1, true },
+  { CreateCodec4, CreateCodec4, 0x020304, L"Swap4", 1, true }
+};
+
+REGISTER_CODECS(ByteSwap)
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/misc/libphysfs/lzma/CPP/7zip/Compress/ByteSwap/StdAfx.cpp	Mon Apr 10 12:06:43 2017 -0400
@@ -0,0 +1,3 @@
+// StdAfx.cpp
+
+#include "StdAfx.h"
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/misc/libphysfs/lzma/CPP/7zip/Compress/ByteSwap/StdAfx.h	Mon Apr 10 12:06:43 2017 -0400
@@ -0,0 +1,8 @@
+// StdAfx.h
+
+#ifndef __STDAFX_H
+#define __STDAFX_H
+
+#include "../../../Common/MyWindows.h"
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/misc/libphysfs/lzma/CPP/7zip/Compress/CodecExports.cpp	Mon Apr 10 12:06:43 2017 -0400
@@ -0,0 +1,157 @@
+// CodecExports.cpp
+
+#include "StdAfx.h"
+
+#include "../../Common/ComTry.h"
+#include "../../Windows/PropVariant.h"
+#include "../Common/RegisterCodec.h"
+#include "../ICoder.h"
+
+extern unsigned int g_NumCodecs;
+extern const CCodecInfo *g_Codecs[]; 
+
+static const UInt16 kDecodeId = 0x2790;
+
+DEFINE_GUID(CLSID_CCodec, 
+0x23170F69, 0x40C1, kDecodeId, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00);
+
+static inline HRESULT SetPropString(const char *s, unsigned int size, PROPVARIANT *value)
+{
+  if ((value->bstrVal = ::SysAllocStringByteLen(s, size)) != 0)
+    value->vt = VT_BSTR;
+  return S_OK;
+}
+
+static inline HRESULT SetPropGUID(const GUID &guid, PROPVARIANT *value)
+{
+  return SetPropString((const char *)&guid, sizeof(GUID), value);
+}
+
+static HRESULT SetClassID(CMethodId id, bool encode, PROPVARIANT *value)
+{
+  GUID clsId = CLSID_CCodec;
+  for (int i = 0; i < sizeof(id); i++, id >>= 8)
+    clsId.Data4[i] = (Byte)(id & 0xFF);
+  if (encode)
+    clsId.Data3++;
+  return SetPropGUID(clsId, value);
+}
+
+static HRESULT FindCodecClassId(const GUID *clsID, UInt32 isCoder2, bool isFilter, bool &encode, int &index)
+{
+  index = -1;
+  if (clsID->Data1 != CLSID_CCodec.Data1 || 
+      clsID->Data2 != CLSID_CCodec.Data2 ||
+      (clsID->Data3 & ~1) != kDecodeId)
+    return S_OK;
+  encode = (clsID->Data3 != kDecodeId);
+  UInt64 id = 0;
+  for (int j = 0; j < 8; j++)
+    id |= ((UInt64)clsID->Data4[j]) << (8 * j);
+  for (UInt32 i = 0; i < g_NumCodecs; i++)
+  {
+    const CCodecInfo &codec = *g_Codecs[i];
+    if (id != codec.Id || encode && !codec.CreateEncoder || !encode && !codec.CreateDecoder)
+      continue;
+    if (!isFilter && codec.IsFilter || isFilter && !codec.IsFilter ||
+        codec.NumInStreams != 1 && !isCoder2 || codec.NumInStreams == 1 && isCoder2)
+      return E_NOINTERFACE;
+    index = i;
+    return S_OK;
+  }
+  return S_OK;
+}
+
+STDAPI CreateCoder2(bool encode, UInt32 index, const GUID *iid, void **outObject)
+{
+  COM_TRY_BEGIN
+  *outObject = 0;
+  bool isCoder = (*iid == IID_ICompressCoder) != 0;
+  bool isCoder2 = (*iid == IID_ICompressCoder2) != 0;
+  bool isFilter = (*iid == IID_ICompressFilter) != 0;
+  const CCodecInfo &codec = *g_Codecs[index];
+  if (!isFilter && codec.IsFilter || isFilter && !codec.IsFilter ||
+      codec.NumInStreams != 1 && !isCoder2 || codec.NumInStreams == 1 && isCoder2)
+    return E_NOINTERFACE;
+  if (encode)
+  {
+    if (!codec.CreateEncoder)
+      return CLASS_E_CLASSNOTAVAILABLE;
+    *outObject = codec.CreateEncoder();
+  }
+  else
+  {
+    if (!codec.CreateDecoder)
+      return CLASS_E_CLASSNOTAVAILABLE;
+    *outObject = codec.CreateDecoder();
+  }
+  if (isCoder)
+    ((ICompressCoder *)*outObject)->AddRef();
+  else if (isCoder2)
+    ((ICompressCoder2 *)*outObject)->AddRef();
+  else
+    ((ICompressFilter *)*outObject)->AddRef();
+  return S_OK;
+  COM_TRY_END
+}
+
+STDAPI CreateCoder(const GUID *clsid, const GUID *iid, void **outObject)
+{
+  *outObject = 0;
+  bool isCoder = (*iid == IID_ICompressCoder) != 0;
+  bool isCoder2 = (*iid == IID_ICompressCoder2) != 0;
+  bool isFilter = (*iid == IID_ICompressFilter) != 0;
+  if (!isCoder && !isCoder2 && !isFilter)
+    return E_NOINTERFACE;
+  bool encode;
+  int codecIndex;
+  HRESULT res = FindCodecClassId(clsid, isCoder2, isFilter, encode, codecIndex);
+  if (res != S_OK)
+    return res;
+  if (codecIndex < 0)
+    return CLASS_E_CLASSNOTAVAILABLE;
+  return CreateCoder2(encode, codecIndex, iid, outObject);
+}
+
+STDAPI GetMethodProperty(UInt32 codecIndex, PROPID propID, PROPVARIANT *value)
+{
+  ::VariantClear((VARIANTARG *)value);
+  const CCodecInfo &codec = *g_Codecs[codecIndex];
+  switch(propID)
+  {
+    case NMethodPropID::kID:
+    {
+      value->uhVal.QuadPart = (UInt64)codec.Id;
+      value->vt = VT_UI8;
+      break;
+    }
+    case NMethodPropID::kName:
+      if ((value->bstrVal = ::SysAllocString(codec.Name)) != 0)
+        value->vt = VT_BSTR;
+      break;
+    case NMethodPropID::kDecoder:
+      if (codec.CreateDecoder)
+        return SetClassID(codec.Id, false, value);
+      break;
+    case NMethodPropID::kEncoder:
+      if (codec.CreateEncoder)
+        return SetClassID(codec.Id, true, value);
+      break;
+    case NMethodPropID::kInStreams:
+    {
+      if (codec.NumInStreams != 1)
+      {
+        value->vt = VT_UI4;
+        value->ulVal = codec.NumInStreams;
+      }
+      break;
+    }
+  }
+  return S_OK;
+}
+
+STDAPI GetNumberOfMethods(UINT32 *numCodecs)
+{
+  *numCodecs = g_NumCodecs;
+  return S_OK;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/misc/libphysfs/lzma/CPP/7zip/Compress/Copy/CopyCoder.cpp	Mon Apr 10 12:06:43 2017 -0400
@@ -0,0 +1,62 @@
+// Compress/CopyCoder.cpp
+
+#include "StdAfx.h"
+
+extern "C" 
+{ 
+#include "../../../../C/Alloc.h"
+}
+
+#include "CopyCoder.h"
+#include "../../Common/StreamUtils.h"
+
+namespace NCompress {
+
+static const UInt32 kBufferSize = 1 << 17;
+
+CCopyCoder::~CCopyCoder()
+{
+  ::MidFree(_buffer);
+}
+
+STDMETHODIMP CCopyCoder::Code(ISequentialInStream *inStream,
+    ISequentialOutStream *outStream, 
+    const UInt64 * /* inSize */, const UInt64 *outSize,
+    ICompressProgressInfo *progress)
+{
+  if (_buffer == 0)
+  {
+    _buffer = (Byte *)::MidAlloc(kBufferSize);
+    if (_buffer == 0)
+      return E_OUTOFMEMORY;
+  }
+
+  TotalSize = 0;
+  for (;;)
+  {
+    UInt32 realProcessedSize;
+    UInt32 size = kBufferSize;
+    if (outSize != 0)
+      if (size > *outSize - TotalSize)
+        size = (UInt32)(*outSize - TotalSize);
+    RINOK(inStream->Read(_buffer, size, &realProcessedSize));
+    if (realProcessedSize == 0)
+      break;
+    RINOK(WriteStream(outStream, _buffer, realProcessedSize, NULL));
+    TotalSize += realProcessedSize;
+    if (progress != NULL)
+    {
+      RINOK(progress->SetRatioInfo(&TotalSize, &TotalSize));
+    }
+  }
+  return S_OK;
+}
+
+STDMETHODIMP CCopyCoder::GetInStreamProcessedSize(UInt64 *value)
+{
+  *value = TotalSize;
+  return S_OK;
+}
+
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/misc/libphysfs/lzma/CPP/7zip/Compress/Copy/CopyCoder.h	Mon Apr 10 12:06:43 2017 -0400
@@ -0,0 +1,33 @@
+// Compress/CopyCoder.h
+
+#ifndef __COMPRESS_COPYCODER_H
+#define __COMPRESS_COPYCODER_H
+
+#include "../../ICoder.h"
+#include "../../../Common/MyCom.h"
+
+namespace NCompress {
+
+class CCopyCoder: 
+  public ICompressCoder,
+  public ICompressGetInStreamProcessedSize,
+  public CMyUnknownImp
+{
+  Byte *_buffer;
+public:
+  UInt64 TotalSize;
+  CCopyCoder(): TotalSize(0) , _buffer(0) {};
+  ~CCopyCoder();
+
+  MY_UNKNOWN_IMP1(ICompressGetInStreamProcessedSize)
+
+  STDMETHOD(Code)(ISequentialInStream *inStream,
+      ISequentialOutStream *outStream, 
+      const UInt64 *inSize, const UInt64 *outSize,
+      ICompressProgressInfo *progress);
+  STDMETHOD(GetInStreamProcessedSize)(UInt64 *value);
+};
+
+}
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/misc/libphysfs/lzma/CPP/7zip/Compress/Copy/CopyRegister.cpp	Mon Apr 10 12:06:43 2017 -0400
@@ -0,0 +1,13 @@
+// LZMARegister.cpp
+
+#include "StdAfx.h"
+
+#include "../../Common/RegisterCodec.h"
+
+#include "CopyCoder.h"
+static void *CreateCodec() { return (void *)(ICompressCoder *)(new NCompress::CCopyCoder); }
+
+static CCodecInfo g_CodecInfo =
+{ CreateCodec, CreateCodec, 0x00, L"Copy", 1, false };
+
+REGISTER_CODEC(Copy)
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/misc/libphysfs/lzma/CPP/7zip/Compress/Copy/StdAfx.cpp	Mon Apr 10 12:06:43 2017 -0400
@@ -0,0 +1,3 @@
+// StdAfx.cpp
+
+#include "StdAfx.h"
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/misc/libphysfs/lzma/CPP/7zip/Compress/Copy/StdAfx.h	Mon Apr 10 12:06:43 2017 -0400
@@ -0,0 +1,8 @@
+// StdAfx.h
+
+#ifndef __STDAFX_H
+#define __STDAFX_H
+
+#include "../../../Common/MyWindows.h"
+
+#endif 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/misc/libphysfs/lzma/CPP/7zip/Compress/LZ/LZOutWindow.cpp	Mon Apr 10 12:06:43 2017 -0400
@@ -0,0 +1,16 @@
+// LZOutWindow.cpp
+
+#include "StdAfx.h"
+
+#include "LZOutWindow.h"
+
+void CLZOutWindow::Init(bool solid)
+{
+  if(!solid)
+    COutBuffer::Init();
+  #ifdef _NO_EXCEPTIONS
+  ErrorCode = S_OK;
+  #endif
+}
+
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/misc/libphysfs/lzma/CPP/7zip/Compress/LZ/LZOutWindow.h	Mon Apr 10 12:06:43 2017 -0400
@@ -0,0 +1,65 @@
+// LZOutWindow.h
+
+#ifndef __LZ_OUT_WINDOW_H
+#define __LZ_OUT_WINDOW_H
+
+#include "../../IStream.h"
+#include "../../Common/OutBuffer.h"
+
+#ifndef _NO_EXCEPTIONS
+typedef COutBufferException CLZOutWindowException;
+#endif
+
+class CLZOutWindow: public COutBuffer
+{
+public:
+  void Init(bool solid = false);
+  
+  // distance >= 0, len > 0, 
+  bool CopyBlock(UInt32 distance, UInt32 len)
+  {
+    UInt32 pos = _pos - distance - 1;
+    if (distance >= _pos)
+    {
+      if (!_overDict || distance >= _bufferSize)
+        return false;
+      pos += _bufferSize;
+    }
+    if (_limitPos - _pos > len && _bufferSize - pos > len)
+    {
+      const Byte *src = _buffer + pos;
+      Byte *dest = _buffer + _pos;
+      _pos += len;
+      do
+        *dest++ = *src++;
+      while(--len != 0);
+    }
+    else do
+    {
+      if (pos == _bufferSize)
+        pos = 0;
+      _buffer[_pos++] = _buffer[pos++];
+      if (_pos == _limitPos)
+        FlushWithCheck();  
+    }
+    while(--len != 0);
+    return true;
+  }
+  
+  void PutByte(Byte b)
+  {
+    _buffer[_pos++] = b;
+    if (_pos == _limitPos)
+      FlushWithCheck();  
+  }
+  
+  Byte GetByte(UInt32 distance) const
+  {
+    UInt32 pos = _pos - distance - 1;
+    if (pos >= _bufferSize)
+      pos += _bufferSize;
+    return _buffer[pos]; 
+  }
+};
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/misc/libphysfs/lzma/CPP/7zip/Compress/LZ/StdAfx.h	Mon Apr 10 12:06:43 2017 -0400
@@ -0,0 +1,6 @@
+// StdAfx.h
+
+#ifndef __STDAFX_H
+#define __STDAFX_H
+
+#endif 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/misc/libphysfs/lzma/CPP/7zip/Compress/LZMA/LZMA.h	Mon Apr 10 12:06:43 2017 -0400
@@ -0,0 +1,82 @@
+// LZMA.h
+
+#ifndef __LZMA_H
+#define __LZMA_H
+
+namespace NCompress {
+namespace NLZMA {
+
+const UInt32 kNumRepDistances = 4;
+
+const int kNumStates = 12;
+
+const Byte kLiteralNextStates[kNumStates] = {0, 0, 0, 0, 1, 2, 3, 4,  5,  6,   4, 5};
+const Byte kMatchNextStates[kNumStates]   = {7, 7, 7, 7, 7, 7, 7, 10, 10, 10, 10, 10};
+const Byte kRepNextStates[kNumStates]     = {8, 8, 8, 8, 8, 8, 8, 11, 11, 11, 11, 11};
+const Byte kShortRepNextStates[kNumStates]= {9, 9, 9, 9, 9, 9, 9, 11, 11, 11, 11, 11};
+
+class CState
+{
+public:
+  Byte Index;
+  void Init() { Index = 0; }
+  void UpdateChar() { Index = kLiteralNextStates[Index]; }
+  void UpdateMatch() { Index = kMatchNextStates[Index]; }
+  void UpdateRep() { Index = kRepNextStates[Index]; }
+  void UpdateShortRep() { Index = kShortRepNextStates[Index]; }
+  bool IsCharState() const { return Index < 7; }
+};
+
+const int kNumPosSlotBits = 6; 
+const int kDicLogSizeMin = 0; 
+const int kDicLogSizeMax = 32; 
+const int kDistTableSizeMax = kDicLogSizeMax * 2; 
+
+const UInt32 kNumLenToPosStates = 4;
+
+inline UInt32 GetLenToPosState(UInt32 len)
+{
+  len -= 2;
+  if (len < kNumLenToPosStates)
+    return len;
+  return kNumLenToPosStates - 1;
+}
+
+namespace NLength {
+
+const int kNumPosStatesBitsMax = 4;
+const UInt32 kNumPosStatesMax = (1 << kNumPosStatesBitsMax);
+
+const int kNumPosStatesBitsEncodingMax = 4;
+const UInt32 kNumPosStatesEncodingMax = (1 << kNumPosStatesBitsEncodingMax);
+
+const int kNumLowBits = 3;
+const int kNumMidBits = 3;
+const int kNumHighBits = 8;
+const UInt32 kNumLowSymbols = 1 << kNumLowBits;
+const UInt32 kNumMidSymbols = 1 << kNumMidBits;
+const UInt32 kNumSymbolsTotal = kNumLowSymbols + kNumMidSymbols + (1 << kNumHighBits);
+
+}
+
+const UInt32 kMatchMinLen = 2;
+const UInt32 kMatchMaxLen = kMatchMinLen + NLength::kNumSymbolsTotal - 1;
+
+const int kNumAlignBits = 4;
+const UInt32 kAlignTableSize = 1 << kNumAlignBits;
+const UInt32 kAlignMask = (kAlignTableSize - 1);
+
+const UInt32 kStartPosModelIndex = 4;
+const UInt32 kEndPosModelIndex = 14;
+const UInt32 kNumPosModels = kEndPosModelIndex - kStartPosModelIndex;
+
+const UInt32 kNumFullDistances = 1 << (kEndPosModelIndex / 2);
+
+const int kNumLitPosStatesBitsEncodingMax = 4;
+const int kNumLitContextBitsMax = 8;
+
+const int kNumMoveBits = 5;
+
+}}
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/misc/libphysfs/lzma/CPP/7zip/Compress/LZMA/LZMADecoder.cpp	Mon Apr 10 12:06:43 2017 -0400
@@ -0,0 +1,338 @@
+// LZMADecoder.cpp
+
+#include "StdAfx.h"
+
+#include "LZMADecoder.h"
+#include "../../../Common/Defs.h"
+
+namespace NCompress {
+namespace NLZMA {
+
+const int kLenIdFinished = -1;
+const int kLenIdNeedInit = -2;
+
+void CDecoder::Init()
+{
+  { 
+    for(int i = 0; i < kNumStates; i++)
+    {
+      for (UInt32 j = 0; j <= _posStateMask; j++)
+      {
+        _isMatch[i][j].Init();
+        _isRep0Long[i][j].Init();
+      }
+      _isRep[i].Init();
+      _isRepG0[i].Init();
+      _isRepG1[i].Init();
+      _isRepG2[i].Init();
+    }
+  }
+  { 
+    for (UInt32 i = 0; i < kNumLenToPosStates; i++)
+    _posSlotDecoder[i].Init();
+  }
+  { 
+    for(UInt32 i = 0; i < kNumFullDistances - kEndPosModelIndex; i++)
+      _posDecoders[i].Init();
+  }
+  _posAlignDecoder.Init();
+  _lenDecoder.Init(_posStateMask + 1);
+  _repMatchLenDecoder.Init(_posStateMask + 1);
+  _literalDecoder.Init();
+
+  _state.Init();
+  _reps[0] = _reps[1] = _reps[2] = _reps[3] = 0;
+}
+
+HRESULT CDecoder::CodeSpec(UInt32 curSize)
+{
+  if (_outSizeDefined)
+  {
+    const UInt64 rem = _outSize - _outWindowStream.GetProcessedSize();
+    if (curSize > rem)
+      curSize = (UInt32)rem;
+  }
+
+  if (_remainLen == kLenIdFinished)
+    return S_OK;
+  if (_remainLen == kLenIdNeedInit)
+  {
+    _rangeDecoder.Init();
+    Init();
+    _remainLen = 0;
+  }
+  if (curSize == 0)
+    return S_OK;
+
+  UInt32 rep0 = _reps[0];
+  UInt32 rep1 = _reps[1];
+  UInt32 rep2 = _reps[2];
+  UInt32 rep3 = _reps[3];
+  CState state = _state;
+  Byte previousByte;
+
+  while(_remainLen > 0 && curSize > 0)
+  {
+    previousByte = _outWindowStream.GetByte(rep0);
+    _outWindowStream.PutByte(previousByte);
+    _remainLen--;
+    curSize--;
+  }
+  UInt64 nowPos64 = _outWindowStream.GetProcessedSize();
+  if (nowPos64 == 0)
+    previousByte = 0;
+  else
+    previousByte = _outWindowStream.GetByte(0);
+
+  while(curSize > 0)
+  {
+    {
+      #ifdef _NO_EXCEPTIONS
+      if (_rangeDecoder.Stream.ErrorCode != S_OK)
+        return _rangeDecoder.Stream.ErrorCode;
+      #endif
+      if (_rangeDecoder.Stream.WasFinished())
+        return S_FALSE;
+      UInt32 posState = UInt32(nowPos64) & _posStateMask;
+      if (_isMatch[state.Index][posState].Decode(&_rangeDecoder) == 0)
+      {
+        if(!state.IsCharState())
+          previousByte = _literalDecoder.DecodeWithMatchByte(&_rangeDecoder, 
+              (UInt32)nowPos64, previousByte, _outWindowStream.GetByte(rep0));
+        else
+          previousByte = _literalDecoder.DecodeNormal(&_rangeDecoder, 
+              (UInt32)nowPos64, previousByte);
+        _outWindowStream.PutByte(previousByte);
+        state.UpdateChar();
+        curSize--;
+        nowPos64++;
+      }
+      else             
+      {
+        UInt32 len;
+        if(_isRep[state.Index].Decode(&_rangeDecoder) == 1)
+        {
+          len = 0;
+          if(_isRepG0[state.Index].Decode(&_rangeDecoder) == 0)
+          {
+            if(_isRep0Long[state.Index][posState].Decode(&_rangeDecoder) == 0)
+            {
+              state.UpdateShortRep();
+              len = 1;
+            }
+          }
+          else
+          {
+            UInt32 distance;
+            if(_isRepG1[state.Index].Decode(&_rangeDecoder) == 0)
+              distance = rep1;
+            else 
+            {
+              if (_isRepG2[state.Index].Decode(&_rangeDecoder) == 0)
+                distance = rep2;
+              else
+              {
+                distance = rep3;
+                rep3 = rep2;
+              }
+              rep2 = rep1;
+            }
+            rep1 = rep0;
+            rep0 = distance;
+          }
+          if (len == 0)
+          {
+            len = _repMatchLenDecoder.Decode(&_rangeDecoder, posState) + kMatchMinLen;
+            state.UpdateRep();
+          }
+        }
+        else
+        {
+          rep3 = rep2;
+          rep2 = rep1;
+          rep1 = rep0;
+          len = kMatchMinLen + _lenDecoder.Decode(&_rangeDecoder, posState);
+          state.UpdateMatch();
+          UInt32 posSlot = _posSlotDecoder[GetLenToPosState(len)].Decode(&_rangeDecoder);
+          if (posSlot >= kStartPosModelIndex)
+          {
+            UInt32 numDirectBits = (posSlot >> 1) - 1;
+            rep0 = ((2 | (posSlot & 1)) << numDirectBits);
+
+            if (posSlot < kEndPosModelIndex)
+              rep0 += NRangeCoder::ReverseBitTreeDecode(_posDecoders + 
+                  rep0 - posSlot - 1, &_rangeDecoder, numDirectBits);
+            else
+            {
+              rep0 += (_rangeDecoder.DecodeDirectBits(
+                  numDirectBits - kNumAlignBits) << kNumAlignBits);
+              rep0 += _posAlignDecoder.ReverseDecode(&_rangeDecoder);
+              if (rep0 == 0xFFFFFFFF)
+              {
+                _remainLen = kLenIdFinished;
+                return S_OK;
+              }
+            }
+          }
+          else
+            rep0 = posSlot;
+        }
+        UInt32 locLen = len;
+        if (len > curSize)
+          locLen = (UInt32)curSize;
+        if (!_outWindowStream.CopyBlock(rep0, locLen))
+          return S_FALSE;
+        previousByte = _outWindowStream.GetByte(0);
+        curSize -= locLen;
+        nowPos64 += locLen;
+        len -= locLen;
+        if (len != 0)
+        {
+          _remainLen = (Int32)len;
+          break;
+        }
+
+        #ifdef _NO_EXCEPTIONS
+        if (_outWindowStream.ErrorCode != S_OK)
+          return _outWindowStream.ErrorCode;
+        #endif
+      }
+    }
+  }
+  if (_rangeDecoder.Stream.WasFinished())
+    return S_FALSE;
+  _reps[0] = rep0;
+  _reps[1] = rep1;
+  _reps[2] = rep2;
+  _reps[3] = rep3;
+  _state = state;
+
+  return S_OK;
+}
+
+STDMETHODIMP CDecoder::CodeReal(ISequentialInStream *inStream,
+    ISequentialOutStream *outStream, 
+    const UInt64 *, const UInt64 *outSize,
+    ICompressProgressInfo *progress)
+{
+  SetInStream(inStream);
+  _outWindowStream.SetStream(outStream);
+  SetOutStreamSize(outSize);
+  CDecoderFlusher flusher(this);
+
+  for (;;)
+  {
+    UInt32 curSize = 1 << 18;
+    RINOK(CodeSpec(curSize));
+    if (_remainLen == kLenIdFinished)
+      break;
+    if (progress != NULL)
+    {
+      UInt64 inSize = _rangeDecoder.GetProcessedSize();
+      UInt64 nowPos64 = _outWindowStream.GetProcessedSize();
+      RINOK(progress->SetRatioInfo(&inSize, &nowPos64));
+    }
+    if (_outSizeDefined)
+      if (_outWindowStream.GetProcessedSize() >= _outSize)
+        break;
+  } 
+  flusher.NeedFlush = false;
+  return Flush();
+}
+
+
+#ifdef _NO_EXCEPTIONS
+
+#define LZMA_TRY_BEGIN
+#define LZMA_TRY_END
+
+#else
+
+#define LZMA_TRY_BEGIN try { 
+#define LZMA_TRY_END } \
+  catch(const CInBufferException &e)  { return e.ErrorCode; } \
+  catch(const CLZOutWindowException &e)  { return e.ErrorCode; } \
+  catch(...) { return S_FALSE; }
+
+#endif
+
+
+STDMETHODIMP CDecoder::Code(ISequentialInStream *inStream,
+      ISequentialOutStream *outStream, const UInt64 *inSize, const UInt64 *outSize,
+      ICompressProgressInfo *progress)
+{
+  LZMA_TRY_BEGIN
+  return CodeReal(inStream, outStream, inSize, outSize, progress); 
+  LZMA_TRY_END
+}
+
+STDMETHODIMP CDecoder::SetDecoderProperties2(const Byte *properties, UInt32 size)
+{
+  if (size < 5)
+    return E_INVALIDARG;
+  int lc = properties[0] % 9;
+  Byte remainder = (Byte)(properties[0] / 9);
+  int lp = remainder % 5;
+  int pb = remainder / 5;
+  if (pb > NLength::kNumPosStatesBitsMax)
+    return E_INVALIDARG;
+  _posStateMask = (1 << pb) - 1;
+  UInt32 dictionarySize = 0;
+  for (int i = 0; i < 4; i++)
+    dictionarySize += ((UInt32)(properties[1 + i])) << (i * 8);
+  if (!_outWindowStream.Create(dictionarySize))
+    return E_OUTOFMEMORY;
+  if (!_literalDecoder.Create(lp, lc))
+    return E_OUTOFMEMORY;
+  if (!_rangeDecoder.Create(1 << 20))
+    return E_OUTOFMEMORY;
+  return S_OK;
+}
+
+STDMETHODIMP CDecoder::GetInStreamProcessedSize(UInt64 *value)
+{
+  *value = _rangeDecoder.GetProcessedSize();
+  return S_OK;
+}
+
+STDMETHODIMP CDecoder::SetInStream(ISequentialInStream *inStream)
+{
+  _rangeDecoder.SetStream(inStream);
+  return S_OK;
+}
+
+STDMETHODIMP CDecoder::ReleaseInStream()
+{
+  _rangeDecoder.ReleaseStream();
+  return S_OK;
+}
+
+STDMETHODIMP CDecoder::SetOutStreamSize(const UInt64 *outSize)
+{
+  _outSizeDefined = (outSize != NULL);
+  if (_outSizeDefined)
+    _outSize = *outSize;
+  _remainLen = kLenIdNeedInit;
+  _outWindowStream.Init();
+  return S_OK;
+}
+
+#ifndef NO_READ_FROM_CODER
+
+STDMETHODIMP CDecoder::Read(void *data, UInt32 size, UInt32 *processedSize)
+{
+  LZMA_TRY_BEGIN
+  if (processedSize)
+    *processedSize = 0;
+  const UInt64 startPos = _outWindowStream.GetProcessedSize();
+  _outWindowStream.SetMemStream((Byte *)data);
+  RINOK(CodeSpec(size));
+  if (processedSize)
+    *processedSize = (UInt32)(_outWindowStream.GetProcessedSize() - startPos);
+  return Flush();
+  LZMA_TRY_END
+}
+
+#endif
+
+}}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/misc/libphysfs/lzma/CPP/7zip/Compress/LZMA/LZMADecoder.h	Mon Apr 10 12:06:43 2017 -0400
@@ -0,0 +1,255 @@
+// LZMA/Decoder.h
+
+#ifndef __LZMA_DECODER_H
+#define __LZMA_DECODER_H
+
+#include "../../../Common/MyCom.h"
+#include "../../ICoder.h"
+#include "../LZ/LZOutWindow.h"
+#include "../RangeCoder/RangeCoderBitTree.h"
+
+extern "C"
+{
+  #include "../../../../C/Alloc.h"
+}
+
+#include "LZMA.h"
+
+namespace NCompress {
+namespace NLZMA {
+
+typedef NRangeCoder::CBitDecoder<kNumMoveBits> CMyBitDecoder;
+
+class CLiteralDecoder2
+{
+  CMyBitDecoder _decoders[0x300];
+public:
+  void Init()
+  {
+    for (int i = 0; i < 0x300; i++)
+      _decoders[i].Init();
+  }
+  Byte DecodeNormal(NRangeCoder::CDecoder *rangeDecoder)
+  {
+    UInt32 symbol = 1;
+    RC_INIT_VAR
+    do
+    {
+      // symbol = (symbol << 1) | _decoders[0][symbol].Decode(rangeDecoder);
+      RC_GETBIT(kNumMoveBits, _decoders[symbol].Prob, symbol)
+    }
+    while (symbol < 0x100);
+    RC_FLUSH_VAR
+    return (Byte)symbol;
+  }
+  Byte DecodeWithMatchByte(NRangeCoder::CDecoder *rangeDecoder, Byte matchByte)
+  {
+    UInt32 symbol = 1;
+    RC_INIT_VAR
+    do
+    {
+      UInt32 matchBit = (matchByte >> 7) & 1;
+      matchByte <<= 1;
+      // UInt32 bit = _decoders[1 + matchBit][symbol].Decode(rangeDecoder);
+      // symbol = (symbol << 1) | bit;
+      UInt32 bit;
+      RC_GETBIT2(kNumMoveBits, _decoders[0x100 + (matchBit << 8) + symbol].Prob, symbol, 
+          bit = 0, bit = 1)
+      if (matchBit != bit)
+      {
+        while (symbol < 0x100)
+        {
+          // symbol = (symbol << 1) | _decoders[0][symbol].Decode(rangeDecoder);
+          RC_GETBIT(kNumMoveBits, _decoders[symbol].Prob, symbol)
+        }
+        break;
+      }
+    }
+    while (symbol < 0x100);
+    RC_FLUSH_VAR
+    return (Byte)symbol;
+  }
+};
+
+class CLiteralDecoder
+{
+  CLiteralDecoder2 *_coders;
+  int _numPrevBits;
+  int _numPosBits;
+  UInt32 _posMask;
+public:
+  CLiteralDecoder(): _coders(0) {}
+  ~CLiteralDecoder()  { Free(); }
+  void Free()
+  { 
+    MyFree(_coders);
+    _coders = 0;
+  }
+  bool Create(int numPosBits, int numPrevBits)
+  {
+    if (_coders == 0 || (numPosBits + numPrevBits) != 
+        (_numPrevBits + _numPosBits) )
+    {
+      Free();
+      UInt32 numStates = 1 << (numPosBits + numPrevBits);
+      _coders = (CLiteralDecoder2 *)MyAlloc(numStates * sizeof(CLiteralDecoder2));
+    }
+    _numPosBits = numPosBits;
+    _posMask = (1 << numPosBits) - 1;
+    _numPrevBits = numPrevBits;
+    return (_coders != 0);
+  }
+  void Init()
+  {
+    UInt32 numStates = 1 << (_numPrevBits + _numPosBits);
+    for (UInt32 i = 0; i < numStates; i++)
+      _coders[i].Init();
+  }
+  UInt32 GetState(UInt32 pos, Byte prevByte) const
+    { return ((pos & _posMask) << _numPrevBits) + (prevByte >> (8 - _numPrevBits)); }
+  Byte DecodeNormal(NRangeCoder::CDecoder *rangeDecoder, UInt32 pos, Byte prevByte)
+    { return _coders[GetState(pos, prevByte)].DecodeNormal(rangeDecoder); }
+  Byte DecodeWithMatchByte(NRangeCoder::CDecoder *rangeDecoder, UInt32 pos, Byte prevByte, Byte matchByte)
+    { return _coders[GetState(pos, prevByte)].DecodeWithMatchByte(rangeDecoder, matchByte); }
+};
+
+namespace NLength {
+
+class CDecoder
+{
+  CMyBitDecoder _choice;
+  CMyBitDecoder _choice2;
+  NRangeCoder::CBitTreeDecoder<kNumMoveBits, kNumLowBits>  _lowCoder[kNumPosStatesMax];
+  NRangeCoder::CBitTreeDecoder<kNumMoveBits, kNumMidBits>  _midCoder[kNumPosStatesMax];
+  NRangeCoder::CBitTreeDecoder<kNumMoveBits, kNumHighBits> _highCoder; 
+public:
+  void Init(UInt32 numPosStates)
+  {
+    _choice.Init();
+    _choice2.Init();
+    for (UInt32 posState = 0; posState < numPosStates; posState++)
+    {
+      _lowCoder[posState].Init();
+      _midCoder[posState].Init();
+    }
+    _highCoder.Init();
+  }
+  UInt32 Decode(NRangeCoder::CDecoder *rangeDecoder, UInt32 posState)
+  {
+    if(_choice.Decode(rangeDecoder) == 0)
+      return _lowCoder[posState].Decode(rangeDecoder);
+    if(_choice2.Decode(rangeDecoder) == 0)
+      return kNumLowSymbols + _midCoder[posState].Decode(rangeDecoder);
+    return kNumLowSymbols + kNumMidSymbols + _highCoder.Decode(rangeDecoder);
+  }
+};
+
+}
+
+class CDecoder: 
+  public ICompressCoder,
+  public ICompressSetDecoderProperties2,
+  public ICompressGetInStreamProcessedSize,
+  #ifndef NO_READ_FROM_CODER
+  public ICompressSetInStream,
+  public ICompressSetOutStreamSize,
+  public ISequentialInStream,
+  #endif
+  public CMyUnknownImp
+{
+  CLZOutWindow _outWindowStream;
+  NRangeCoder::CDecoder _rangeDecoder;
+
+  CMyBitDecoder _isMatch[kNumStates][NLength::kNumPosStatesMax];
+  CMyBitDecoder _isRep[kNumStates];
+  CMyBitDecoder _isRepG0[kNumStates];
+  CMyBitDecoder _isRepG1[kNumStates];
+  CMyBitDecoder _isRepG2[kNumStates];
+  CMyBitDecoder _isRep0Long[kNumStates][NLength::kNumPosStatesMax];
+
+  NRangeCoder::CBitTreeDecoder<kNumMoveBits, kNumPosSlotBits> _posSlotDecoder[kNumLenToPosStates];
+
+  CMyBitDecoder _posDecoders[kNumFullDistances - kEndPosModelIndex];
+  NRangeCoder::CBitTreeDecoder<kNumMoveBits, kNumAlignBits> _posAlignDecoder;
+  
+  NLength::CDecoder _lenDecoder;
+  NLength::CDecoder _repMatchLenDecoder;
+
+  CLiteralDecoder _literalDecoder;
+
+  UInt32 _posStateMask;
+
+  ///////////////////
+  // State
+  UInt32 _reps[4];
+  CState _state;
+  Int32 _remainLen; // -1 means end of stream. // -2 means need Init
+  UInt64 _outSize;
+  bool _outSizeDefined;
+
+  void Init();
+  HRESULT CodeSpec(UInt32 size);
+public:
+
+  #ifndef NO_READ_FROM_CODER
+  MY_UNKNOWN_IMP5(
+      ICompressSetDecoderProperties2, 
+      ICompressGetInStreamProcessedSize,
+      ICompressSetInStream, 
+      ICompressSetOutStreamSize, 
+      ISequentialInStream)
+  #else
+  MY_UNKNOWN_IMP2(
+      ICompressSetDecoderProperties2,
+      ICompressGetInStreamProcessedSize)
+  #endif
+
+  void ReleaseStreams()
+  {
+    _outWindowStream.ReleaseStream();
+    ReleaseInStream();
+  }
+
+  class CDecoderFlusher
+  {
+    CDecoder *_decoder;
+  public:
+    bool NeedFlush;
+    CDecoderFlusher(CDecoder *decoder): _decoder(decoder), NeedFlush(true) {}
+    ~CDecoderFlusher() 
+    { 
+      if (NeedFlush)
+        _decoder->Flush();
+      _decoder->ReleaseStreams(); 
+    }
+  };
+
+  HRESULT Flush() {  return _outWindowStream.Flush(); }  
+
+  STDMETHOD(CodeReal)(ISequentialInStream *inStream,
+      ISequentialOutStream *outStream, const UInt64 *inSize, const UInt64 *outSize,
+      ICompressProgressInfo *progress);
+  
+  STDMETHOD(Code)(ISequentialInStream *inStream,
+      ISequentialOutStream *outStream, const UInt64 *inSize, const UInt64 *outSize,
+      ICompressProgressInfo *progress);
+
+  STDMETHOD(SetDecoderProperties2)(const Byte *data, UInt32 size);
+
+  STDMETHOD(GetInStreamProcessedSize)(UInt64 *value);
+
+  STDMETHOD(SetInStream)(ISequentialInStream *inStream);
+  STDMETHOD(ReleaseInStream)();
+  STDMETHOD(SetOutStreamSize)(const UInt64 *outSize);
+
+  #ifndef NO_READ_FROM_CODER
+  STDMETHOD(Read)(void *data, UInt32 size, UInt32 *processedSize);
+  #endif
+
+  CDecoder(): _outSizeDefined(false) {}
+  virtual ~CDecoder() {}
+};
+
+}}
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/misc/libphysfs/lzma/CPP/7zip/Compress/LZMA/LZMAEncoder.cpp	Mon Apr 10 12:06:43 2017 -0400
@@ -0,0 +1,1547 @@
+// LZMA/Encoder.cpp
+
+#include "StdAfx.h"
+
+#include <stdio.h>
+
+#ifdef _WIN32
+#define USE_ALLOCA
+#endif
+
+#ifdef USE_ALLOCA
+#ifdef _WIN32
+#include <malloc.h>
+#else
+#include <stdlib.h>
+#endif
+#endif
+
+#include "../../../Common/Defs.h"
+#include "../../Common/StreamUtils.h"
+
+#include "LZMAEncoder.h"
+
+// extern "C" { #include "../../../../C/7zCrc.h" }
+
+// #define SHOW_STAT
+
+
+namespace NCompress {
+namespace NLZMA {
+
+// struct CCrcInit { CCrcInit() { InitCrcTable(); } } g_CrcInit;
+
+const int kDefaultDictionaryLogSize = 22;
+const UInt32 kNumFastBytesDefault = 0x20;
+
+#ifndef LZMA_LOG_BSR
+Byte g_FastPos[1 << kNumLogBits];
+
+class CFastPosInit
+{
+public:
+  CFastPosInit() { Init(); }
+  void Init()
+  {
+    const Byte kFastSlots = kNumLogBits * 2;
+    int c = 2;
+    g_FastPos[0] = 0;
+    g_FastPos[1] = 1;
+
+    for (Byte slotFast = 2; slotFast < kFastSlots; slotFast++)
+    {
+      UInt32 k = (1 << ((slotFast >> 1) - 1));
+      for (UInt32 j = 0; j < k; j++, c++)
+        g_FastPos[c] = slotFast;
+    }
+  }
+} g_FastPosInit;
+#endif
+
+void CLiteralEncoder2::Encode(NRangeCoder::CEncoder *rangeEncoder, Byte symbol)
+{
+  UInt32 context = 1;
+  int i = 8;
+  do 
+  {
+    i--;
+    UInt32 bit = (symbol >> i) & 1;
+    _encoders[context].Encode(rangeEncoder, bit);
+    context = (context << 1) | bit;
+  }
+  while(i != 0);
+}
+
+void CLiteralEncoder2::EncodeMatched(NRangeCoder::CEncoder *rangeEncoder, 
+    Byte matchByte, Byte symbol)
+{
+  UInt32 context = 1;
+  int i = 8;
+  do 
+  {
+    i--;
+    UInt32 bit = (symbol >> i) & 1;
+    UInt32 matchBit = (matchByte >> i) & 1;
+    _encoders[0x100 + (matchBit << 8) + context].Encode(rangeEncoder, bit);
+    context = (context << 1) | bit;
+    if (matchBit != bit)
+    {
+      while(i != 0)
+      {
+        i--;
+        UInt32 bit = (symbol >> i) & 1;
+        _encoders[context].Encode(rangeEncoder, bit);
+        context = (context << 1) | bit;
+      }
+      break;
+    }
+  }
+  while(i != 0);
+}
+
+UInt32 CLiteralEncoder2::GetPrice(bool matchMode, Byte matchByte, Byte symbol) const
+{
+  UInt32 price = 0;
+  UInt32 context = 1;
+  int i = 8;
+  if (matchMode)
+  {
+    do 
+    {
+      i--;
+      UInt32 matchBit = (matchByte >> i) & 1;
+      UInt32 bit = (symbol >> i) & 1;
+      price += _encoders[0x100 + (matchBit << 8) + context].GetPrice(bit);
+      context = (context << 1) | bit;
+      if (matchBit != bit)
+        break;
+    }
+    while (i != 0);
+  }
+  while(i != 0)
+  {
+    i--;
+    UInt32 bit = (symbol >> i) & 1;
+    price += _encoders[context].GetPrice(bit);
+    context = (context << 1) | bit;
+  }
+  return price;
+};
+
+
+namespace NLength {
+
+void CEncoder::Init(UInt32 numPosStates)
+{
+  _choice.Init();
+  _choice2.Init();
+  for (UInt32 posState = 0; posState < numPosStates; posState++)
+  {
+    _lowCoder[posState].Init();
+    _midCoder[posState].Init();
+  }
+  _highCoder.Init();
+}
+
+void CEncoder::Encode(NRangeCoder::CEncoder *rangeEncoder, UInt32 symbol, UInt32 posState)
+{
+  if(symbol < kNumLowSymbols)
+  {
+    _choice.Encode(rangeEncoder, 0);
+    _lowCoder[posState].Encode(rangeEncoder, symbol);
+  }
+  else
+  {
+    _choice.Encode(rangeEncoder, 1);
+    if(symbol < kNumLowSymbols + kNumMidSymbols)
+    {
+      _choice2.Encode(rangeEncoder, 0);
+      _midCoder[posState].Encode(rangeEncoder, symbol - kNumLowSymbols);
+    }
+    else
+    {
+      _choice2.Encode(rangeEncoder, 1);
+      _highCoder.Encode(rangeEncoder, symbol - kNumLowSymbols - kNumMidSymbols);
+    }
+  }
+}
+
+void CEncoder::SetPrices(UInt32 posState, UInt32 numSymbols, UInt32 *prices) const
+{
+  UInt32 a0 = _choice.GetPrice0();
+  UInt32 a1 = _choice.GetPrice1();
+  UInt32 b0 = a1 + _choice2.GetPrice0();
+  UInt32 b1 = a1 + _choice2.GetPrice1();
+  UInt32 i = 0;
+  for (i = 0; i < kNumLowSymbols; i++)
+  {
+    if (i >= numSymbols)
+      return;
+    prices[i] = a0 + _lowCoder[posState].GetPrice(i);
+  }
+  for (; i < kNumLowSymbols + kNumMidSymbols; i++)
+  {
+    if (i >= numSymbols)
+      return;
+    prices[i] = b0 + _midCoder[posState].GetPrice(i - kNumLowSymbols);
+  }
+  for (; i < numSymbols; i++)
+    prices[i] = b1 + _highCoder.GetPrice(i - kNumLowSymbols - kNumMidSymbols);
+}
+
+}
+
+CEncoder::CEncoder():
+  _numFastBytes(kNumFastBytesDefault),
+  _distTableSize(kDefaultDictionaryLogSize * 2),
+  _posStateBits(2),
+  _posStateMask(4 - 1),
+  _numLiteralPosStateBits(0),
+  _numLiteralContextBits(3),
+  _dictionarySize(1 << kDefaultDictionaryLogSize),
+  _matchFinderCycles(0),
+  #ifdef COMPRESS_MF_MT
+  _multiThread(false),
+  #endif
+  _writeEndMark(false)
+{
+  MatchFinder_Construct(&_matchFinderBase);
+  // _maxMode = false;
+  _fastMode = false;
+  #ifdef COMPRESS_MF_MT
+  MatchFinderMt_Construct(&_matchFinderMt);
+  _matchFinderMt.MatchFinder = &_matchFinderBase;
+  #endif
+}
+
+
+static void *SzAlloc(size_t size) { return BigAlloc(size); }
+static void SzFree(void *address) { BigFree(address); }
+ISzAlloc g_Alloc = { SzAlloc, SzFree };
+
+CEncoder::~CEncoder()
+{
+  #ifdef COMPRESS_MF_MT
+  MatchFinderMt_Destruct(&_matchFinderMt, &g_Alloc);
+  #endif
+  MatchFinder_Free(&_matchFinderBase, &g_Alloc);
+}
+
+static const UInt32 kBigHashDicLimit = (UInt32)1 << 24;
+
+HRESULT CEncoder::Create()
+{
+  if (!_rangeEncoder.Create(1 << 20))
+    return E_OUTOFMEMORY;
+  bool btMode = (_matchFinderBase.btMode != 0);
+  #ifdef COMPRESS_MF_MT
+  _mtMode = (_multiThread && !_fastMode && btMode);
+  #endif
+  
+  if (!_literalEncoder.Create(_numLiteralPosStateBits, _numLiteralContextBits))
+    return E_OUTOFMEMORY;
+
+  _matchFinderBase.bigHash = (_dictionarySize > kBigHashDicLimit);
+
+  UInt32 numCycles = 16 + (_numFastBytes >> 1);
+  if (!btMode)
+    numCycles >>= 1;
+  if (_matchFinderCycles != 0)
+    numCycles = _matchFinderCycles;
+  _matchFinderBase.cutValue = numCycles;
+  #ifdef COMPRESS_MF_MT
+  if (_mtMode)
+  {
+    RINOK(MatchFinderMt_Create(&_matchFinderMt, _dictionarySize, kNumOpts, _numFastBytes, kMatchMaxLen, &g_Alloc));
+    _matchFinderObj = &_matchFinderMt;
+    MatchFinderMt_CreateVTable(&_matchFinderMt, &_matchFinder);
+  }
+  else
+  #endif
+  {
+    if (!MatchFinder_Create(&_matchFinderBase, _dictionarySize, kNumOpts, _numFastBytes, kMatchMaxLen, &g_Alloc))
+      return E_OUTOFMEMORY;
+    _matchFinderObj = &_matchFinderBase;
+    MatchFinder_CreateVTable(&_matchFinderBase, &_matchFinder);
+  }
+  return S_OK;
+}
+
+inline wchar_t GetUpperChar(wchar_t c)
+{
+  if (c >= 'a' && c <= 'z')
+    c -= 0x20;
+  return c;
+}
+
+static int ParseMatchFinder(const wchar_t *s, int *btMode, UInt32 *numHashBytes /* , int *skipModeBits */)
+{
+  wchar_t c = GetUpperChar(*s++);
+  if (c == L'H')
+  {
+    if (GetUpperChar(*s++) != L'C')
+      return 0;
+    int numHashBytesLoc = (int)(*s++ - L'0');
+    if (numHashBytesLoc < 4 || numHashBytesLoc > 4)
+      return 0;
+    if (*s++ != 0)
+      return 0;
+    *btMode = 0;
+    *numHashBytes = numHashBytesLoc;
+    return 1;
+  }
+  if (c != L'B')
+    return 0;
+
+  if (GetUpperChar(*s++) != L'T')
+    return 0;
+  int numHashBytesLoc = (int)(*s++ - L'0');
+  if (numHashBytesLoc < 2 || numHashBytesLoc > 4)
+    return 0;
+  c = GetUpperChar(*s++);
+  /*
+  int skipModeBitsLoc = 0;
+  if (c == L'D')
+  {
+    skipModeBitsLoc = 2;
+    c = GetUpperChar(*s++);
+  }
+  */
+  if (c != L'\0')
+    return 0;
+  *btMode = 1;
+  *numHashBytes = numHashBytesLoc;
+  // *skipModeBits = skipModeBitsLoc;
+  return 1;
+}
+
+STDMETHODIMP CEncoder::SetCoderProperties(const PROPID *propIDs, 
+    const PROPVARIANT *properties, UInt32 numProperties)
+{
+  for (UInt32 i = 0; i < numProperties; i++)
+  {
+    const PROPVARIANT &prop = properties[i];
+    switch(propIDs[i])
+    {
+      case NCoderPropID::kNumFastBytes:
+      {
+        if (prop.vt != VT_UI4)
+          return E_INVALIDARG;
+        UInt32 numFastBytes = prop.ulVal;
+        if(numFastBytes < 5 || numFastBytes > kMatchMaxLen)
+          return E_INVALIDARG;
+        _numFastBytes = numFastBytes;
+        break;
+      }
+      case NCoderPropID::kMatchFinderCycles:
+      {
+        if (prop.vt != VT_UI4)
+          return E_INVALIDARG;
+        _matchFinderCycles = prop.ulVal;
+        break;
+      }
+      case NCoderPropID::kAlgorithm:
+      {
+        if (prop.vt != VT_UI4)
+          return E_INVALIDARG;
+        UInt32 maximize = prop.ulVal;
+        _fastMode = (maximize == 0); 
+        // _maxMode = (maximize >= 2);
+        break;
+      }
+      case NCoderPropID::kMatchFinder:
+      {
+        if (prop.vt != VT_BSTR)
+          return E_INVALIDARG;
+        if (!ParseMatchFinder(prop.bstrVal, &_matchFinderBase.btMode, &_matchFinderBase.numHashBytes /* , &_matchFinderBase.skipModeBits */))
+          return E_INVALIDARG;
+        break;
+      }
+      case NCoderPropID::kMultiThread:
+      {
+        if (prop.vt != VT_BOOL)
+          return E_INVALIDARG;
+        #ifdef COMPRESS_MF_MT
+        Bool newMultiThread = (prop.boolVal == VARIANT_TRUE);
+        if (newMultiThread != _multiThread)
+        {
+          ReleaseMatchFinder();
+          _multiThread = newMultiThread;
+        }
+        #endif
+        break;
+      }
+      case NCoderPropID::kNumThreads:
+      {
+        if (prop.vt != VT_UI4)
+          return E_INVALIDARG;
+        #ifdef COMPRESS_MF_MT
+        Bool newMultiThread = (prop.ulVal > 1) ? True : False;
+        if (newMultiThread != _multiThread)
+        {
+          ReleaseMatchFinder();
+          _multiThread = newMultiThread;
+        }
+        #endif
+        break;
+      }
+      case NCoderPropID::kDictionarySize:
+      {
+        const int kDicLogSizeMaxCompress = 30; // must be <= ((kNumLogBits - 1) * 2) + 7 = 31;
+        if (prop.vt != VT_UI4)
+          return E_INVALIDARG;
+        UInt32 dictionarySize = prop.ulVal;
+        if (dictionarySize < UInt32(1 << kDicLogSizeMin) ||
+            dictionarySize > UInt32(1 << kDicLogSizeMaxCompress))
+          return E_INVALIDARG;
+        _dictionarySize = dictionarySize;
+        UInt32 dicLogSize;
+        for(dicLogSize = 0; dicLogSize < (UInt32)kDicLogSizeMaxCompress; dicLogSize++)
+          if (dictionarySize <= (UInt32(1) << dicLogSize))
+            break;
+        _distTableSize = dicLogSize * 2;
+        break;
+      }
+      case NCoderPropID::kPosStateBits:
+      {
+        if (prop.vt != VT_UI4)
+          return E_INVALIDARG;
+        UInt32 value = prop.ulVal;
+        if (value > (UInt32)NLength::kNumPosStatesBitsEncodingMax)
+          return E_INVALIDARG;
+        _posStateBits = value;
+        _posStateMask = (1 << _posStateBits) - 1;
+        break;
+      }
+      case NCoderPropID::kLitPosBits:
+      {
+        if (prop.vt != VT_UI4)
+          return E_INVALIDARG;
+        UInt32 value = prop.ulVal;
+        if (value > (UInt32)kNumLitPosStatesBitsEncodingMax)
+          return E_INVALIDARG;
+        _numLiteralPosStateBits = value;
+        break;
+      }
+      case NCoderPropID::kLitContextBits:
+      {
+        if (prop.vt != VT_UI4)
+          return E_INVALIDARG;
+        UInt32 value = prop.ulVal;
+        if (value > (UInt32)kNumLitContextBitsMax)
+          return E_INVALIDARG;
+        _numLiteralContextBits = value;
+        break;
+      }
+      case NCoderPropID::kEndMarker:
+      {
+        if (prop.vt != VT_BOOL)
+          return E_INVALIDARG;
+        SetWriteEndMarkerMode(prop.boolVal == VARIANT_TRUE);
+        break;
+      }
+      default:
+        return E_INVALIDARG;
+    }
+  }
+  return S_OK;
+}
+
+STDMETHODIMP CEncoder::WriteCoderProperties(ISequentialOutStream *outStream)
+{ 
+  const UInt32 kPropSize = 5;
+  Byte properties[kPropSize];
+  properties[0] = (Byte)((_posStateBits * 5 + _numLiteralPosStateBits) * 9 + _numLiteralContextBits);
+  for (int i = 0; i < 4; i++)
+    properties[1 + i] = Byte(_dictionarySize >> (8 * i));
+  return WriteStream(outStream, properties, kPropSize, NULL);
+}
+
+STDMETHODIMP CEncoder::SetOutStream(ISequentialOutStream *outStream)
+{
+  _rangeEncoder.SetStream(outStream);
+  return S_OK;
+}
+
+STDMETHODIMP CEncoder::ReleaseOutStream()
+{
+  _rangeEncoder.ReleaseStream();
+  return S_OK;
+}
+
+HRESULT CEncoder::Init()
+{
+  CBaseState::Init();
+
+  _rangeEncoder.Init();
+
+  for(int i = 0; i < kNumStates; i++)
+  {
+    for (UInt32 j = 0; j <= _posStateMask; j++)
+    {
+      _isMatch[i][j].Init();
+      _isRep0Long[i][j].Init();
+    }
+    _isRep[i].Init();
+    _isRepG0[i].Init();
+    _isRepG1[i].Init();
+    _isRepG2[i].Init();
+  }
+
+  _literalEncoder.Init();
+
+  {
+    for(UInt32 i = 0; i < kNumLenToPosStates; i++)
+      _posSlotEncoder[i].Init();
+  }
+  {
+    for(UInt32 i = 0; i < kNumFullDistances - kEndPosModelIndex; i++)
+      _posEncoders[i].Init();
+  }
+
+  _lenEncoder.Init(1 << _posStateBits);
+  _repMatchLenEncoder.Init(1 << _posStateBits);
+
+  _posAlignEncoder.Init();
+
+  _longestMatchWasFound = false;
+  _optimumEndIndex = 0;
+  _optimumCurrentIndex = 0;
+  _additionalOffset = 0;
+
+  return S_OK;
+}
+
+#ifdef SHOW_STAT
+static int ttt = 0;
+#endif
+
+void CEncoder::MovePos(UInt32 num)
+{
+  #ifdef SHOW_STAT
+  ttt += num;
+  printf("\n MovePos %d", num);
+  #endif
+  if (num != 0)
+  {
+    _additionalOffset += num;
+    _matchFinder.Skip(_matchFinderObj, num);
+  }
+}
+
+UInt32 CEncoder::Backward(UInt32 &backRes, UInt32 cur)
+{
+  _optimumEndIndex = cur;
+  UInt32 posMem = _optimum[cur].PosPrev;
+  UInt32 backMem = _optimum[cur].BackPrev;
+  do
+  {
+    if (_optimum[cur].Prev1IsChar)
+    {
+      _optimum[posMem].MakeAsChar();
+      _optimum[posMem].PosPrev = posMem - 1;
+      if (_optimum[cur].Prev2)
+      {
+        _optimum[posMem - 1].Prev1IsChar = false;
+        _optimum[posMem - 1].PosPrev = _optimum[cur].PosPrev2;
+        _optimum[posMem - 1].BackPrev = _optimum[cur].BackPrev2;
+      }
+    }
+    UInt32 posPrev = posMem;
+    UInt32 backCur = backMem;
+
+    backMem = _optimum[posPrev].BackPrev;
+    posMem = _optimum[posPrev].PosPrev;
+
+    _optimum[posPrev].BackPrev = backCur;
+    _optimum[posPrev].PosPrev = cur;
+    cur = posPrev;
+  }
+  while(cur != 0);
+  backRes = _optimum[0].BackPrev;
+  _optimumCurrentIndex  = _optimum[0].PosPrev;
+  return _optimumCurrentIndex; 
+}
+
+/*
+Out:
+  (lenRes == 1) && (backRes == 0xFFFFFFFF) means Literal
+*/
+
+UInt32 CEncoder::GetOptimum(UInt32 position, UInt32 &backRes)
+{
+  if(_optimumEndIndex != _optimumCurrentIndex)
+  {
+    const COptimal &optimum = _optimum[_optimumCurrentIndex];
+    UInt32 lenRes = optimum.PosPrev - _optimumCurrentIndex;
+    backRes = optimum.BackPrev;
+    _optimumCurrentIndex = optimum.PosPrev;
+    return lenRes;
+  }
+  _optimumCurrentIndex = _optimumEndIndex = 0;
+  
+  UInt32 numAvailableBytes = _matchFinder.GetNumAvailableBytes(_matchFinderObj);
+
+  UInt32 lenMain, numDistancePairs;
+  if (!_longestMatchWasFound)
+  {
+    lenMain = ReadMatchDistances(numDistancePairs);
+  }
+  else
+  {
+    lenMain = _longestMatchLength;
+    numDistancePairs = _numDistancePairs;
+    _longestMatchWasFound = false;
+  }
+
+  const Byte *data = _matchFinder.GetPointerToCurrentPos(_matchFinderObj) - 1;
+  if (numAvailableBytes < 2)
+  {
+    backRes = (UInt32)(-1);
+    return 1;
+  }
+  if (numAvailableBytes > kMatchMaxLen)
+    numAvailableBytes = kMatchMaxLen;
+
+  UInt32 reps[kNumRepDistances];
+  UInt32 repLens[kNumRepDistances];
+  UInt32 repMaxIndex = 0;
+  UInt32 i;
+  for(i = 0; i < kNumRepDistances; i++)
+  {
+    reps[i] = _repDistances[i];
+    const Byte *data2 = data - (reps[i] + 1);
+    if (data[0] != data2[0] || data[1] != data2[1])
+    {
+      repLens[i] = 0;
+      continue;
+    }
+    UInt32 lenTest;
+    for (lenTest = 2; lenTest < numAvailableBytes && data[lenTest] == data2[lenTest]; lenTest++);
+    repLens[i] = lenTest;
+    if (lenTest > repLens[repMaxIndex])
+      repMaxIndex = i;
+  }
+  if(repLens[repMaxIndex] >= _numFastBytes)
+  {
+    backRes = repMaxIndex;
+    UInt32 lenRes = repLens[repMaxIndex];
+    MovePos(lenRes - 1);
+    return lenRes;
+  }
+
+  UInt32 *matchDistances = _matchDistances;
+  if(lenMain >= _numFastBytes)
+  {
+    backRes = matchDistances[numDistancePairs - 1] + kNumRepDistances; 
+    MovePos(lenMain - 1);
+    return lenMain;
+  }
+  Byte currentByte = *data;
+  Byte matchByte = *(data - (reps[0] + 1));
+
+  if(lenMain < 2 && currentByte != matchByte && repLens[repMaxIndex] < 2)
+  {
+    backRes = (UInt32)-1;
+    return 1;
+  }
+
+  _optimum[0].State = _state;
+
+  UInt32 posState = (position & _posStateMask);
+
+  _optimum[1].Price = _isMatch[_state.Index][posState].GetPrice0() + 
+      _literalEncoder.GetSubCoder(position, _previousByte)->GetPrice(!_state.IsCharState(), matchByte, currentByte);
+  _optimum[1].MakeAsChar();
+
+  UInt32 matchPrice = _isMatch[_state.Index][posState].GetPrice1();
+  UInt32 repMatchPrice = matchPrice + _isRep[_state.Index].GetPrice1();
+
+  if(matchByte == currentByte)
+  {
+    UInt32 shortRepPrice = repMatchPrice + GetRepLen1Price(_state, posState);
+    if(shortRepPrice < _optimum[1].Price)
+    {
+      _optimum[1].Price = shortRepPrice;
+      _optimum[1].MakeAsShortRep();
+    }
+  }
+  UInt32 lenEnd = ((lenMain >= repLens[repMaxIndex]) ? lenMain : repLens[repMaxIndex]);
+
+  if(lenEnd < 2)
+  {
+    backRes = _optimum[1].BackPrev;
+    return 1;
+  }
+
+  _optimum[1].PosPrev = 0;
+  for (i = 0; i < kNumRepDistances; i++)
+    _optimum[0].Backs[i] = reps[i];
+
+  UInt32 len = lenEnd;
+  do
+    _optimum[len--].Price = kIfinityPrice;
+  while (len >= 2);
+
+  for(i = 0; i < kNumRepDistances; i++)
+  {
+    UInt32 repLen = repLens[i];
+    if (repLen < 2)
+      continue;
+    UInt32 price = repMatchPrice + GetPureRepPrice(i, _state, posState);
+    do
+    {
+      UInt32 curAndLenPrice = price + _repMatchLenEncoder.GetPrice(repLen - 2, posState);
+      COptimal &optimum = _optimum[repLen];
+      if (curAndLenPrice < optimum.Price) 
+      {
+        optimum.Price = curAndLenPrice;
+        optimum.PosPrev = 0;
+        optimum.BackPrev = i;
+        optimum.Prev1IsChar = false;
+      }
+    }
+    while(--repLen >= 2);
+  }
+
+  UInt32 normalMatchPrice = matchPrice + _isRep[_state.Index].GetPrice0();
+
+  len = ((repLens[0] >= 2) ? repLens[0] + 1 : 2);
+  if (len <= lenMain)
+  {
+    UInt32 offs = 0;
+    while (len > matchDistances[offs])
+      offs += 2;
+    for(; ; len++)
+    {
+      UInt32 distance = matchDistances[offs + 1];
+      UInt32 curAndLenPrice = normalMatchPrice + GetPosLenPrice(distance, len, posState);
+      COptimal &optimum = _optimum[len];
+      if (curAndLenPrice < optimum.Price) 
+      {
+        optimum.Price = curAndLenPrice;
+        optimum.PosPrev = 0;
+        optimum.BackPrev = distance + kNumRepDistances;
+        optimum.Prev1IsChar = false;
+      }
+      if (len == matchDistances[offs])
+      {
+        offs += 2;
+        if (offs == numDistancePairs)
+          break;
+      }
+    }
+  }
+
+  UInt32 cur = 0;
+
+  for (;;)
+  {
+    cur++;
+    if(cur == lenEnd)
+    {
+      return Backward(backRes, cur);
+    }
+    UInt32 numAvailableBytesFull = _matchFinder.GetNumAvailableBytes(_matchFinderObj);
+    UInt32 newLen, numDistancePairs;
+    newLen = ReadMatchDistances(numDistancePairs);
+    if(newLen >= _numFastBytes)
+    {
+      _numDistancePairs = numDistancePairs;
+      _longestMatchLength = newLen;
+      _longestMatchWasFound = true;
+      return Backward(backRes, cur);
+    }
+    position++;
+    COptimal &curOptimum = _optimum[cur];
+    UInt32 posPrev = curOptimum.PosPrev;
+    CState state;
+    if (curOptimum.Prev1IsChar)
+    {
+      posPrev--;
+      if (curOptimum.Prev2)
+      {
+        state = _optimum[curOptimum.PosPrev2].State;
+        if (curOptimum.BackPrev2 < kNumRepDistances)
+          state.UpdateRep();
+        else
+          state.UpdateMatch();
+      }
+      else
+        state = _optimum[posPrev].State;
+      state.UpdateChar();
+    }
+    else
+      state = _optimum[posPrev].State;
+    if (posPrev == cur - 1)
+    {
+      if (curOptimum.IsShortRep())
+        state.UpdateShortRep();
+      else
+        state.UpdateChar();
+    }
+    else
+    {
+      UInt32 pos;
+      if (curOptimum.Prev1IsChar && curOptimum.Prev2)
+      {
+        posPrev = curOptimum.PosPrev2;
+        pos = curOptimum.BackPrev2;
+        state.UpdateRep();
+      }
+      else
+      {
+        pos = curOptimum.BackPrev;
+        if (pos < kNumRepDistances)
+          state.UpdateRep();
+        else
+          state.UpdateMatch();
+      }
+      const COptimal &prevOptimum = _optimum[posPrev];
+      if (pos < kNumRepDistances)
+      {
+        reps[0] = prevOptimum.Backs[pos];
+        UInt32 i;
+        for(i = 1; i <= pos; i++)
+          reps[i] = prevOptimum.Backs[i - 1];
+        for(; i < kNumRepDistances; i++)
+          reps[i] = prevOptimum.Backs[i];
+      }
+      else
+      {
+        reps[0] = (pos - kNumRepDistances);
+        for(UInt32 i = 1; i < kNumRepDistances; i++)
+          reps[i] = prevOptimum.Backs[i - 1];
+      }
+    }
+    curOptimum.State = state;
+    for(UInt32 i = 0; i < kNumRepDistances; i++)
+      curOptimum.Backs[i] = reps[i];
+    UInt32 curPrice = curOptimum.Price; 
+    const Byte *data = _matchFinder.GetPointerToCurrentPos(_matchFinderObj) - 1;
+    const Byte currentByte = *data;
+    const Byte matchByte = *(data - (reps[0] + 1));
+
+    UInt32 posState = (position & _posStateMask);
+
+    UInt32 curAnd1Price = curPrice +
+        _isMatch[state.Index][posState].GetPrice0() +
+        _literalEncoder.GetSubCoder(position, *(data - 1))->GetPrice(!state.IsCharState(), matchByte, currentByte);
+
+    COptimal &nextOptimum = _optimum[cur + 1];
+
+    bool nextIsChar = false;
+    if (curAnd1Price < nextOptimum.Price) 
+    {
+      nextOptimum.Price = curAnd1Price;
+      nextOptimum.PosPrev = cur;
+      nextOptimum.MakeAsChar();
+      nextIsChar = true;
+    }
+
+    UInt32 matchPrice = curPrice + _isMatch[state.Index][posState].GetPrice1();
+    UInt32 repMatchPrice = matchPrice + _isRep[state.Index].GetPrice1();
+    
+    if(matchByte == currentByte &&
+        !(nextOptimum.PosPrev < cur && nextOptimum.BackPrev == 0))
+    {
+      UInt32 shortRepPrice = repMatchPrice + GetRepLen1Price(state, posState);
+      if(shortRepPrice <= nextOptimum.Price)
+      {
+        nextOptimum.Price = shortRepPrice;
+        nextOptimum.PosPrev = cur;
+        nextOptimum.MakeAsShortRep();
+        nextIsChar = true;
+      }
+    }
+    /*
+    if(newLen == 2 && matchDistances[2] >= kDistLimit2) // test it maybe set 2000 ?
+      continue;
+    */
+
+    numAvailableBytesFull = MyMin(kNumOpts - 1 - cur, numAvailableBytesFull);
+    UInt32 numAvailableBytes = numAvailableBytesFull;
+
+    if (numAvailableBytes < 2)
+      continue;
+    if (numAvailableBytes > _numFastBytes)
+      numAvailableBytes = _numFastBytes;
+    if (!nextIsChar && matchByte != currentByte) // speed optimization
+    {
+      // try Literal + rep0
+      const Byte *data2 = data - (reps[0] + 1);
+      UInt32 limit = MyMin(numAvailableBytesFull, _numFastBytes + 1);
+      UInt32 temp;
+      for (temp = 1; temp < limit && data[temp] == data2[temp]; temp++);
+      UInt32 lenTest2 = temp - 1;
+      if (lenTest2 >= 2)
+      {
+        CState state2 = state;
+        state2.UpdateChar();
+        UInt32 posStateNext = (position + 1) & _posStateMask;
+        UInt32 nextRepMatchPrice = curAnd1Price + 
+            _isMatch[state2.Index][posStateNext].GetPrice1() +
+            _isRep[state2.Index].GetPrice1();
+        // for (; lenTest2 >= 2; lenTest2--)
+        {
+          UInt32 offset = cur + 1 + lenTest2;
+          while(lenEnd < offset)
+            _optimum[++lenEnd].Price = kIfinityPrice;
+          UInt32 curAndLenPrice = nextRepMatchPrice + GetRepPrice(
+              0, lenTest2, state2, posStateNext);
+          COptimal &optimum = _optimum[offset];
+          if (curAndLenPrice < optimum.Price) 
+          {
+            optimum.Price = curAndLenPrice;
+            optimum.PosPrev = cur + 1;
+            optimum.BackPrev = 0;
+            optimum.Prev1IsChar = true;
+            optimum.Prev2 = false;
+          }
+        }
+      }
+    }
+    
+    UInt32 startLen = 2; // speed optimization 
+    for(UInt32 repIndex = 0; repIndex < kNumRepDistances; repIndex++)
+    {
+      // UInt32 repLen = _matchFinder.GetMatchLen(0 - 1, reps[repIndex], newLen); // test it;
+      const Byte *data2 = data - (reps[repIndex] + 1);
+      if (data[0] != data2[0] || data[1] != data2[1])
+        continue;
+      UInt32 lenTest;
+      for (lenTest = 2; lenTest < numAvailableBytes && data[lenTest] == data2[lenTest]; lenTest++);
+      while(lenEnd < cur + lenTest)
+        _optimum[++lenEnd].Price = kIfinityPrice;
+      UInt32 lenTestTemp = lenTest;
+      UInt32 price = repMatchPrice + GetPureRepPrice(repIndex, state, posState);
+      do
+      {
+        UInt32 curAndLenPrice = price + _repMatchLenEncoder.GetPrice(lenTest - 2, posState);
+        COptimal &optimum = _optimum[cur + lenTest];
+        if (curAndLenPrice < optimum.Price) 
+        {
+          optimum.Price = curAndLenPrice;
+          optimum.PosPrev = cur;
+          optimum.BackPrev = repIndex;
+          optimum.Prev1IsChar = false;
+        }
+      }
+      while(--lenTest >= 2);
+      lenTest = lenTestTemp;
+      
+      if (repIndex == 0)
+        startLen = lenTest + 1;
+        
+      // if (_maxMode)
+        {
+          UInt32 lenTest2 = lenTest + 1;
+          UInt32 limit = MyMin(numAvailableBytesFull, lenTest2 + _numFastBytes);
+          for (; lenTest2 < limit && data[lenTest2] == data2[lenTest2]; lenTest2++);
+          lenTest2 -= lenTest + 1;
+          if (lenTest2 >= 2)
+          {
+            CState state2 = state;
+            state2.UpdateRep();
+            UInt32 posStateNext = (position + lenTest) & _posStateMask;
+            UInt32 curAndLenCharPrice = 
+                price + _repMatchLenEncoder.GetPrice(lenTest - 2, posState) + 
+                _isMatch[state2.Index][posStateNext].GetPrice0() +
+                _literalEncoder.GetSubCoder(position + lenTest, data[lenTest - 1])->GetPrice(
+                true, data2[lenTest], data[lenTest]);
+            state2.UpdateChar();
+            posStateNext = (position + lenTest + 1) & _posStateMask;
+            UInt32 nextRepMatchPrice = curAndLenCharPrice + 
+                _isMatch[state2.Index][posStateNext].GetPrice1() +
+                _isRep[state2.Index].GetPrice1();
+            
+            // for(; lenTest2 >= 2; lenTest2--)
+            {
+              UInt32 offset = cur + lenTest + 1 + lenTest2;
+              while(lenEnd < offset)
+                _optimum[++lenEnd].Price = kIfinityPrice;
+              UInt32 curAndLenPrice = nextRepMatchPrice + GetRepPrice(
+                  0, lenTest2, state2, posStateNext);
+              COptimal &optimum = _optimum[offset];
+              if (curAndLenPrice < optimum.Price) 
+              {
+                optimum.Price = curAndLenPrice;
+                optimum.PosPrev = cur + lenTest + 1;
+                optimum.BackPrev = 0;
+                optimum.Prev1IsChar = true;
+                optimum.Prev2 = true;
+                optimum.PosPrev2 = cur;
+                optimum.BackPrev2 = repIndex;
+              }
+            }
+          }
+        }
+      }
+    
+    //    for(UInt32 lenTest = 2; lenTest <= newLen; lenTest++)
+    if (newLen > numAvailableBytes)
+    {
+      newLen = numAvailableBytes;
+      for (numDistancePairs = 0; newLen > matchDistances[numDistancePairs]; numDistancePairs += 2);
+      matchDistances[numDistancePairs] = newLen;
+      numDistancePairs += 2;
+    }
+    if (newLen >= startLen)
+    {
+      UInt32 normalMatchPrice = matchPrice + _isRep[state.Index].GetPrice0();
+      while(lenEnd < cur + newLen)
+        _optimum[++lenEnd].Price = kIfinityPrice;
+
+      UInt32 offs = 0;
+      while(startLen > matchDistances[offs])
+        offs += 2;
+      UInt32 curBack = matchDistances[offs + 1];
+      UInt32 posSlot = GetPosSlot2(curBack);
+      for(UInt32 lenTest = /*2*/ startLen; ; lenTest++)
+      {
+        UInt32 curAndLenPrice = normalMatchPrice;
+        UInt32 lenToPosState = GetLenToPosState(lenTest);
+        if (curBack < kNumFullDistances)
+          curAndLenPrice += _distancesPrices[lenToPosState][curBack];
+        else
+          curAndLenPrice += _posSlotPrices[lenToPosState][posSlot] + _alignPrices[curBack & kAlignMask];
+  
+        curAndLenPrice += _lenEncoder.GetPrice(lenTest - kMatchMinLen, posState);
+        
+        COptimal &optimum = _optimum[cur + lenTest];
+        if (curAndLenPrice < optimum.Price) 
+        {
+          optimum.Price = curAndLenPrice;
+          optimum.PosPrev = cur;
+          optimum.BackPrev = curBack + kNumRepDistances;
+          optimum.Prev1IsChar = false;
+        }
+
+        if (/*_maxMode && */lenTest == matchDistances[offs])
+        {
+          // Try Match + Literal + Rep0
+          const Byte *data2 = data - (curBack + 1);
+          UInt32 lenTest2 = lenTest + 1;
+          UInt32 limit = MyMin(numAvailableBytesFull, lenTest2 + _numFastBytes);
+          for (; lenTest2 < limit && data[lenTest2] == data2[lenTest2]; lenTest2++);
+          lenTest2 -= lenTest + 1;
+          if (lenTest2 >= 2)
+          {
+            CState state2 = state;
+            state2.UpdateMatch();
+            UInt32 posStateNext = (position + lenTest) & _posStateMask;
+            UInt32 curAndLenCharPrice = curAndLenPrice + 
+                _isMatch[state2.Index][posStateNext].GetPrice0() +
+                _literalEncoder.GetSubCoder(position + lenTest, data[lenTest - 1])->GetPrice( 
+                true, data2[lenTest], data[lenTest]);
+            state2.UpdateChar();
+            posStateNext = (posStateNext + 1) & _posStateMask;
+            UInt32 nextRepMatchPrice = curAndLenCharPrice + 
+                _isMatch[state2.Index][posStateNext].GetPrice1() +
+                _isRep[state2.Index].GetPrice1();
+            
+            // for(; lenTest2 >= 2; lenTest2--)
+            {
+              UInt32 offset = cur + lenTest + 1 + lenTest2;
+              while(lenEnd < offset)
+                _optimum[++lenEnd].Price = kIfinityPrice;
+              UInt32 curAndLenPrice = nextRepMatchPrice + GetRepPrice(0, lenTest2, state2, posStateNext);
+              COptimal &optimum = _optimum[offset];
+              if (curAndLenPrice < optimum.Price) 
+              {
+                optimum.Price = curAndLenPrice;
+                optimum.PosPrev = cur + lenTest + 1;
+                optimum.BackPrev = 0;
+                optimum.Prev1IsChar = true;
+                optimum.Prev2 = true;
+                optimum.PosPrev2 = cur;
+                optimum.BackPrev2 = curBack + kNumRepDistances;
+              }
+            }
+          }
+          offs += 2;
+          if (offs == numDistancePairs)
+            break;
+          curBack = matchDistances[offs + 1];
+          if (curBack >= kNumFullDistances)
+            posSlot = GetPosSlot2(curBack);
+        }
+      }
+    }
+  }
+}
+
+static inline bool ChangePair(UInt32 smallDist, UInt32 bigDist)
+{
+  return ((bigDist >> 7) > smallDist);
+}
+
+UInt32 CEncoder::ReadMatchDistances(UInt32 &numDistancePairs)
+{
+  UInt32 lenRes = 0;
+  numDistancePairs = _matchFinder.GetMatches(_matchFinderObj, _matchDistances);
+  #ifdef SHOW_STAT
+  printf("\n i = %d numPairs = %d    ", ttt, numDistancePairs / 2);
+  if (ttt >= 61994)
+    ttt = ttt;
+
+  ttt++;
+  for (UInt32 i = 0; i < numDistancePairs; i += 2)
+    printf("%2d %6d   | ", _matchDistances[i], _matchDistances[i + 1]);
+  #endif
+  if (numDistancePairs > 0)
+  {
+    lenRes = _matchDistances[numDistancePairs - 2];
+    if (lenRes == _numFastBytes)
+    {
+      UInt32 numAvail = _matchFinder.GetNumAvailableBytes(_matchFinderObj) + 1;
+      const Byte *pby = _matchFinder.GetPointerToCurrentPos(_matchFinderObj) - 1;
+      UInt32 distance = _matchDistances[numDistancePairs - 1] + 1;
+      if (numAvail > kMatchMaxLen)
+        numAvail = kMatchMaxLen;
+
+      const Byte *pby2 = pby - distance;
+      for (; lenRes < numAvail && pby[lenRes] == pby2[lenRes]; lenRes++);
+    }
+  }
+  _additionalOffset++;
+  return lenRes;
+}
+
+UInt32 CEncoder::GetOptimumFast(UInt32 &backRes)
+{
+  UInt32 numAvailableBytes = _matchFinder.GetNumAvailableBytes(_matchFinderObj);
+  UInt32 lenMain, numDistancePairs;
+  if (!_longestMatchWasFound)
+  {
+    lenMain = ReadMatchDistances(numDistancePairs);
+  }
+  else
+  {
+    lenMain = _longestMatchLength;
+    numDistancePairs = _numDistancePairs;
+    _longestMatchWasFound = false;
+  }
+
+  const Byte *data = _matchFinder.GetPointerToCurrentPos(_matchFinderObj) - 1;
+  if (numAvailableBytes > kMatchMaxLen)
+    numAvailableBytes = kMatchMaxLen;
+  if (numAvailableBytes < 2)
+  {
+    backRes = (UInt32)(-1);
+    return 1;
+  }
+
+  UInt32 repLens[kNumRepDistances];
+  UInt32 repMaxIndex = 0;
+
+  for(UInt32 i = 0; i < kNumRepDistances; i++)
+  {
+    const Byte *data2 = data - (_repDistances[i] + 1);
+    if (data[0] != data2[0] || data[1] != data2[1])
+    {
+      repLens[i] = 0;
+      continue;
+    }
+    UInt32 len;
+    for (len = 2; len < numAvailableBytes && data[len] == data2[len]; len++);
+    if(len >= _numFastBytes)
+    {
+      backRes = i;
+      MovePos(len - 1);
+      return len;
+    }
+    repLens[i] = len;
+    if (len > repLens[repMaxIndex])
+      repMaxIndex = i;
+  }
+  UInt32 *matchDistances = _matchDistances;
+  if(lenMain >= _numFastBytes)
+  {
+    backRes = matchDistances[numDistancePairs - 1] + kNumRepDistances; 
+    MovePos(lenMain - 1);
+    return lenMain;
+  }
+
+  UInt32 backMain = 0; // for GCC
+  if (lenMain >= 2)
+  {
+    backMain = matchDistances[numDistancePairs - 1];
+    while (numDistancePairs > 2 && lenMain == matchDistances[numDistancePairs - 4] + 1)
+    {
+      if (!ChangePair(matchDistances[numDistancePairs - 3], backMain))
+        break;
+      numDistancePairs -= 2;
+      lenMain = matchDistances[numDistancePairs - 2];
+      backMain = matchDistances[numDistancePairs - 1];
+    }
+    if (lenMain == 2 && backMain >= 0x80)
+      lenMain = 1;
+  }
+
+  if (repLens[repMaxIndex] >= 2)
+  {
+    if (repLens[repMaxIndex] + 1 >= lenMain || 
+        repLens[repMaxIndex] + 2 >= lenMain && (backMain > (1 << 9)) ||
+        repLens[repMaxIndex] + 3 >= lenMain && (backMain > (1 << 15)))
+    {
+      backRes = repMaxIndex;
+      UInt32 lenRes = repLens[repMaxIndex];
+      MovePos(lenRes - 1);
+      return lenRes;
+    }
+  }
+  
+  if (lenMain >= 2 && numAvailableBytes > 2)
+  {
+    numAvailableBytes = _matchFinder.GetNumAvailableBytes(_matchFinderObj);
+    _longestMatchLength = ReadMatchDistances(_numDistancePairs);
+    if (_longestMatchLength >= 2)
+    {
+      UInt32 newDistance = matchDistances[_numDistancePairs - 1];
+      if (_longestMatchLength >= lenMain && newDistance < backMain || 
+          _longestMatchLength == lenMain + 1 && !ChangePair(backMain, newDistance) ||
+          _longestMatchLength > lenMain + 1 ||
+          _longestMatchLength + 1 >= lenMain && lenMain >= 3 && ChangePair(newDistance, backMain))
+      {
+        _longestMatchWasFound = true;
+        backRes = UInt32(-1);
+        return 1;
+      }
+    }
+    data = _matchFinder.GetPointerToCurrentPos(_matchFinderObj) - 1;
+    for(UInt32 i = 0; i < kNumRepDistances; i++)
+    {
+      const Byte *data2 = data - (_repDistances[i] + 1);
+      if (data[1] != data2[1] || data[2] != data2[2])
+      {
+        repLens[i] = 0;
+        continue;
+      }
+      UInt32 len;
+      for (len = 2; len < numAvailableBytes && data[len] == data2[len]; len++);
+      if (len + 1 >= lenMain)
+      {
+        _longestMatchWasFound = true;
+        backRes = UInt32(-1);
+        return 1;
+      }
+    }
+    backRes = backMain + kNumRepDistances; 
+    MovePos(lenMain - 2);
+    return lenMain;
+  }
+  backRes = UInt32(-1);
+  return 1;
+}
+
+HRESULT CEncoder::Flush(UInt32 nowPos)
+{
+  // ReleaseMFStream();
+  if (_matchFinderBase.result != SZ_OK)
+    return _matchFinderBase.result;
+  WriteEndMarker(nowPos & _posStateMask);
+  _rangeEncoder.FlushData();
+  return _rangeEncoder.FlushStream();
+}
+
+void CEncoder::WriteEndMarker(UInt32 posState)
+{
+  // This function for writing End Mark for stream version of LZMA. 
+  // In current version this feature is not used.
+  if (!_writeEndMark)
+    return;
+
+  _isMatch[_state.Index][posState].Encode(&_rangeEncoder, 1);
+  _isRep[_state.Index].Encode(&_rangeEncoder, 0);
+  _state.UpdateMatch();
+  UInt32 len = kMatchMinLen; // kMatchMaxLen;
+  _lenEncoder.Encode(&_rangeEncoder, len - kMatchMinLen, posState, !_fastMode);
+  UInt32 posSlot = (1 << kNumPosSlotBits)  - 1;
+  UInt32 lenToPosState = GetLenToPosState(len);
+  _posSlotEncoder[lenToPosState].Encode(&_rangeEncoder, posSlot);
+  UInt32 footerBits = 30;
+  UInt32 posReduced = (UInt32(1) << footerBits) - 1;
+  _rangeEncoder.EncodeDirectBits(posReduced >> kNumAlignBits, footerBits - kNumAlignBits);
+  _posAlignEncoder.ReverseEncode(&_rangeEncoder, posReduced & kAlignMask);
+}
+
+HRESULT CEncoder::CodeReal(ISequentialInStream *inStream,
+      ISequentialOutStream *outStream, 
+      const UInt64 *inSize, const UInt64 *outSize,
+      ICompressProgressInfo *progress)
+{
+  // _needReleaseMFStream = false;
+  #ifdef COMPRESS_MF_MT
+  #ifdef USE_ALLOCA
+  alloca(0x300);
+  #endif
+  #endif
+  CCoderReleaser coderReleaser(this);
+  RINOK(SetStreams(inStream, outStream, inSize, outSize));
+  for (;;)
+  {
+    UInt64 processedInSize;
+    UInt64 processedOutSize;
+    Int32 finished;
+    RINOK(CodeOneBlock(&processedInSize, &processedOutSize, &finished));
+    if (finished != 0)
+      break;
+    if (progress != 0)
+    {
+      RINOK(progress->SetRatioInfo(&processedInSize, &processedOutSize));
+    }
+  }
+  return S_OK;
+}
+
+HRESULT CEncoder::SetStreams(ISequentialInStream *inStream,
+      ISequentialOutStream *outStream, 
+      const UInt64 * /* inSize */, const UInt64 * /* outSize */)
+{
+  _inStream = inStream;
+  _finished = false;
+  RINOK(Create());
+  RINOK(SetOutStream(outStream));
+  RINOK(Init());
+  
+  if (!_fastMode)
+  {
+    FillDistancesPrices();
+    FillAlignPrices();
+  }
+
+  _lenEncoder.SetTableSize(_numFastBytes + 1 - kMatchMinLen);
+  _lenEncoder.UpdateTables(1 << _posStateBits);
+  _repMatchLenEncoder.SetTableSize(_numFastBytes + 1 - kMatchMinLen);
+  _repMatchLenEncoder.UpdateTables(1 << _posStateBits);
+
+  nowPos64 = 0;
+  return S_OK;
+}
+
+static HRes MyRead(void *object, void *data, UInt32 size, UInt32 *processedSize)
+{
+  return (HRes)((CSeqInStream *)object)->RealStream->Read(data, size, processedSize);
+}
+
+HRESULT CEncoder::CodeOneBlock(UInt64 *inSize, UInt64 *outSize, Int32 *finished)
+{
+  if (_inStream != 0)
+  {
+    _seqInStream.RealStream = _inStream;
+    _seqInStream.SeqInStream.Read = MyRead;
+    _matchFinderBase.stream = &_seqInStream.SeqInStream;
+    _matchFinder.Init(_matchFinderObj);
+    _needReleaseMFStream = true;
+    _inStream = 0;
+  }
+
+
+  *finished = 1;
+  if (_finished)
+    return _matchFinderBase.result;
+  _finished = true;
+
+  if (nowPos64 == 0)
+  {
+    if (_matchFinder.GetNumAvailableBytes(_matchFinderObj) == 0)
+      return Flush((UInt32)nowPos64);
+    UInt32 len, numDistancePairs;
+    len = ReadMatchDistances(numDistancePairs);
+    UInt32 posState = UInt32(nowPos64) & _posStateMask;
+    _isMatch[_state.Index][posState].Encode(&_rangeEncoder, 0);
+    _state.UpdateChar();
+    Byte curByte = _matchFinder.GetIndexByte(_matchFinderObj, 0 - _additionalOffset);
+    _literalEncoder.GetSubCoder(UInt32(nowPos64), _previousByte)->Encode(&_rangeEncoder, curByte);
+    _previousByte = curByte;
+    _additionalOffset--;
+    nowPos64++;
+  }
+
+  UInt32 nowPos32 = (UInt32)nowPos64;
+  UInt32 progressPosValuePrev = nowPos32;
+
+  if (_matchFinder.GetNumAvailableBytes(_matchFinderObj) == 0)
+    return Flush(nowPos32);
+
+  for (;;)
+  {
+    #ifdef _NO_EXCEPTIONS
+    if (_rangeEncoder.Stream.ErrorCode != S_OK)
+      return _rangeEncoder.Stream.ErrorCode;
+    #endif
+    UInt32 pos, len;
+
+    if (_fastMode)
+      len = GetOptimumFast(pos);
+    else
+      len = GetOptimum(nowPos32, pos);
+
+    UInt32 posState = nowPos32 & _posStateMask;
+    if(len == 1 && pos == 0xFFFFFFFF)
+    {
+      _isMatch[_state.Index][posState].Encode(&_rangeEncoder, 0);
+      Byte curByte = _matchFinder.GetIndexByte(_matchFinderObj, 0 - _additionalOffset);
+      CLiteralEncoder2 *subCoder = _literalEncoder.GetSubCoder(nowPos32, _previousByte);
+      if(_state.IsCharState())
+        subCoder->Encode(&_rangeEncoder, curByte);
+      else
+      {
+        Byte matchByte = _matchFinder.GetIndexByte(_matchFinderObj, 0 - _repDistances[0] - 1 - _additionalOffset);
+        subCoder->EncodeMatched(&_rangeEncoder, matchByte, curByte);
+      }
+      _state.UpdateChar();
+      _previousByte = curByte;
+    }
+    else
+    {
+      _isMatch[_state.Index][posState].Encode(&_rangeEncoder, 1);
+      if(pos < kNumRepDistances)
+      {
+        _isRep[_state.Index].Encode(&_rangeEncoder, 1);
+        if(pos == 0)
+        {
+          _isRepG0[_state.Index].Encode(&_rangeEncoder, 0);
+          _isRep0Long[_state.Index][posState].Encode(&_rangeEncoder, ((len == 1) ? 0 : 1));
+        }
+        else
+        {
+          UInt32 distance = _repDistances[pos];
+          _isRepG0[_state.Index].Encode(&_rangeEncoder, 1);
+          if (pos == 1)
+            _isRepG1[_state.Index].Encode(&_rangeEncoder, 0);
+          else
+          {
+            _isRepG1[_state.Index].Encode(&_rangeEncoder, 1);
+            _isRepG2[_state.Index].Encode(&_rangeEncoder, pos - 2);
+            if (pos == 3)
+              _repDistances[3] = _repDistances[2];
+            _repDistances[2] = _repDistances[1];
+          }
+          _repDistances[1] = _repDistances[0];
+          _repDistances[0] = distance;
+        }
+        if (len == 1)
+          _state.UpdateShortRep();
+        else
+        {
+          _repMatchLenEncoder.Encode(&_rangeEncoder, len - kMatchMinLen, posState, !_fastMode);
+          _state.UpdateRep();
+        }
+      }
+      else
+      {
+        _isRep[_state.Index].Encode(&_rangeEncoder, 0);
+        _state.UpdateMatch();
+        _lenEncoder.Encode(&_rangeEncoder, len - kMatchMinLen, posState, !_fastMode);
+        pos -= kNumRepDistances;
+        UInt32 posSlot = GetPosSlot(pos);
+        _posSlotEncoder[GetLenToPosState(len)].Encode(&_rangeEncoder, posSlot);
+        
+        if (posSlot >= kStartPosModelIndex)
+        {
+          UInt32 footerBits = ((posSlot >> 1) - 1);
+          UInt32 base = ((2 | (posSlot & 1)) << footerBits);
+          UInt32 posReduced = pos - base;
+
+          if (posSlot < kEndPosModelIndex)
+            NRangeCoder::ReverseBitTreeEncode(_posEncoders + base - posSlot - 1, 
+                &_rangeEncoder, footerBits, posReduced);
+          else
+          {
+            _rangeEncoder.EncodeDirectBits(posReduced >> kNumAlignBits, footerBits - kNumAlignBits);
+            _posAlignEncoder.ReverseEncode(&_rangeEncoder, posReduced & kAlignMask);
+            _alignPriceCount++;
+          }
+        }
+        _repDistances[3] = _repDistances[2];
+        _repDistances[2] = _repDistances[1];
+        _repDistances[1] = _repDistances[0];
+        _repDistances[0] = pos;
+        _matchPriceCount++;
+      }
+      _previousByte = _matchFinder.GetIndexByte(_matchFinderObj, len - 1 - _additionalOffset);
+    }
+    _additionalOffset -= len;
+    nowPos32 += len;
+    if (_additionalOffset == 0)
+    {
+      if (!_fastMode)
+      {
+        if (_matchPriceCount >= (1 << 7))
+          FillDistancesPrices();
+        if (_alignPriceCount >= kAlignTableSize)
+          FillAlignPrices();
+      }
+      if (_matchFinder.GetNumAvailableBytes(_matchFinderObj) == 0)
+        return Flush(nowPos32);
+      if (nowPos32 - progressPosValuePrev >= (1 << 14))
+      {
+        nowPos64 += nowPos32 - progressPosValuePrev;
+        *inSize = nowPos64;
+        *outSize = _rangeEncoder.GetProcessedSize();
+        _finished = false;
+        *finished = 0;
+        return _matchFinderBase.result;
+      }
+    }
+  }
+}
+
+STDMETHODIMP CEncoder::Code(ISequentialInStream *inStream,
+    ISequentialOutStream *outStream, const UInt64 *inSize, const UInt64 *outSize,
+    ICompressProgressInfo *progress)
+{
+  #ifndef _NO_EXCEPTIONS
+  try 
+  { 
+  #endif
+    return CodeReal(inStream, outStream, inSize, outSize, progress); 
+  #ifndef _NO_EXCEPTIONS
+  }
+  catch(const COutBufferException &e) { return e.ErrorCode; }
+  catch(...) { return E_FAIL; }
+  #endif
+}
+  
+void CEncoder::FillDistancesPrices()
+{
+  UInt32 tempPrices[kNumFullDistances];
+  for (UInt32 i = kStartPosModelIndex; i < kNumFullDistances; i++)
+  { 
+    UInt32 posSlot = GetPosSlot(i);
+    UInt32 footerBits = ((posSlot >> 1) - 1);
+    UInt32 base = ((2 | (posSlot & 1)) << footerBits);
+    tempPrices[i] = NRangeCoder::ReverseBitTreeGetPrice(_posEncoders + 
+      base - posSlot - 1, footerBits, i - base);
+  }
+
+  for (UInt32 lenToPosState = 0; lenToPosState < kNumLenToPosStates; lenToPosState++)
+  {
+    UInt32 posSlot;
+    NRangeCoder::CBitTreeEncoder<kNumMoveBits, kNumPosSlotBits> &encoder = _posSlotEncoder[lenToPosState];
+    UInt32 *posSlotPrices = _posSlotPrices[lenToPosState];
+    for (posSlot = 0; posSlot < _distTableSize; posSlot++)
+      posSlotPrices[posSlot] = encoder.GetPrice(posSlot);
+    for (posSlot = kEndPosModelIndex; posSlot < _distTableSize; posSlot++)
+      posSlotPrices[posSlot] += ((((posSlot >> 1) - 1) - kNumAlignBits) << NRangeCoder::kNumBitPriceShiftBits);
+
+    UInt32 *distancesPrices = _distancesPrices[lenToPosState];
+    UInt32 i;
+    for (i = 0; i < kStartPosModelIndex; i++)
+      distancesPrices[i] = posSlotPrices[i];
+    for (; i < kNumFullDistances; i++)
+      distancesPrices[i] = posSlotPrices[GetPosSlot(i)] + tempPrices[i];
+  }
+  _matchPriceCount = 0;
+}
+
+void CEncoder::FillAlignPrices()
+{
+  for (UInt32 i = 0; i < kAlignTableSize; i++)
+    _alignPrices[i] = _posAlignEncoder.ReverseGetPrice(i);
+  _alignPriceCount = 0;
+}
+
+}}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/misc/libphysfs/lzma/CPP/7zip/Compress/LZMA/LZMAEncoder.h	Mon Apr 10 12:06:43 2017 -0400
@@ -0,0 +1,465 @@
+// LZMA/Encoder.h
+
+#ifndef __LZMA_ENCODER_H
+#define __LZMA_ENCODER_H
+
+#include "../../../Common/MyCom.h"
+#include "../../ICoder.h"
+
+extern "C"
+{
+  #include "../../../../C/Alloc.h"
+  #include "../../../../C/Compress/Lz/MatchFinder.h"
+  #ifdef COMPRESS_MF_MT
+  #include "../../../../C/Compress/Lz/MatchFinderMt.h"
+  #endif
+}
+
+#include "../RangeCoder/RangeCoderBitTree.h"
+
+#include "LZMA.h"
+
+namespace NCompress {
+namespace NLZMA {
+
+typedef NRangeCoder::CBitEncoder<kNumMoveBits> CMyBitEncoder;
+
+class CBaseState
+{
+protected:
+  CState _state;
+  Byte _previousByte;
+  UInt32 _repDistances[kNumRepDistances];
+  void Init()
+  {
+    _state.Init();
+    _previousByte = 0;
+    for(UInt32 i = 0 ; i < kNumRepDistances; i++)
+      _repDistances[i] = 0;
+  }
+};
+
+struct COptimal
+{
+  CState State;
+
+  bool Prev1IsChar;
+  bool Prev2;
+
+  UInt32 PosPrev2;
+  UInt32 BackPrev2;     
+
+  UInt32 Price;    
+  UInt32 PosPrev;         // posNext;
+  UInt32 BackPrev;     
+  UInt32 Backs[kNumRepDistances];
+  void MakeAsChar() { BackPrev = UInt32(-1); Prev1IsChar = false; }
+  void MakeAsShortRep() { BackPrev = 0; ; Prev1IsChar = false; }
+  bool IsShortRep() { return (BackPrev == 0); }
+};
+
+
+// #define LZMA_LOG_BRANCH
+
+#if _MSC_VER >= 1400
+// Must give gain in core 2. but slower ~2% on k8.
+// #define LZMA_LOG_BSR
+#endif
+
+#ifndef LZMA_LOG_BSR
+static const int kNumLogBits = 13; // don't change it !
+extern Byte g_FastPos[];
+#endif
+inline UInt32 GetPosSlot(UInt32 pos)
+{
+  #ifdef LZMA_LOG_BSR
+  if (pos < 2)
+    return pos;
+  unsigned long index;
+  _BitScanReverse(&index, pos);
+  return (index + index) + ((pos >> (index - 1)) & 1);
+  #else
+  if (pos < (1 << kNumLogBits))
+    return g_FastPos[pos];
+  if (pos < (1 << (kNumLogBits * 2 - 1)))
+    return g_FastPos[pos >> (kNumLogBits - 1)] + (kNumLogBits - 1) * 2;
+  return g_FastPos[pos >> (kNumLogBits - 1) * 2] + (kNumLogBits - 1) * 4;
+  #endif
+}
+
+inline UInt32 GetPosSlot2(UInt32 pos)
+{
+  #ifdef LZMA_LOG_BSR
+  unsigned long index;
+  _BitScanReverse(&index, pos);
+  return (index + index) + ((pos >> (index - 1)) & 1);
+  #else
+  #ifdef LZMA_LOG_BRANCH
+  if (pos < (1 << (kNumLogBits + 6)))
+    return g_FastPos[pos >> 6] + 12;
+  if (pos < (1 << (kNumLogBits * 2 + 5)))
+    return g_FastPos[pos >> (kNumLogBits + 5)] + (kNumLogBits + 5) * 2;
+  return g_FastPos[pos >> (kNumLogBits * 2 + 4)] + (kNumLogBits * 2 + 4) * 2;
+  #else
+  // it's faster with VC6-32bit.
+  UInt32 s = 6 + ((kNumLogBits - 1) & (UInt32)((Int32)(((1 << (kNumLogBits + 6)) - 1) -  pos) >> 31));
+  return g_FastPos[pos >> s] + (s * 2);
+  #endif
+  #endif
+}
+
+const UInt32 kIfinityPrice = 0xFFFFFFF;
+
+const UInt32 kNumOpts = 1 << 12;
+
+
+class CLiteralEncoder2
+{
+  CMyBitEncoder _encoders[0x300];
+public:
+  void Init()
+  {
+    for (int i = 0; i < 0x300; i++)
+      _encoders[i].Init();
+  }
+  void Encode(NRangeCoder::CEncoder *rangeEncoder, Byte symbol);
+  void EncodeMatched(NRangeCoder::CEncoder *rangeEncoder, Byte matchByte, Byte symbol);
+  UInt32 GetPrice(bool matchMode, Byte matchByte, Byte symbol) const;
+};
+
+class CLiteralEncoder
+{
+  CLiteralEncoder2 *_coders;
+  int _numPrevBits;
+  int _numPosBits;
+  UInt32 _posMask;
+public:
+  CLiteralEncoder(): _coders(0) {}
+  ~CLiteralEncoder()  { Free(); }
+  void Free()
+  { 
+    MyFree(_coders);
+    _coders = 0;
+  }
+  bool Create(int numPosBits, int numPrevBits)
+  {
+    if (_coders == 0 || (numPosBits + numPrevBits) != (_numPrevBits + _numPosBits))
+    {
+      Free();
+      UInt32 numStates = 1 << (numPosBits + numPrevBits);
+      _coders = (CLiteralEncoder2 *)MyAlloc(numStates * sizeof(CLiteralEncoder2));
+    }
+    _numPosBits = numPosBits;
+    _posMask = (1 << numPosBits) - 1;
+    _numPrevBits = numPrevBits;
+    return (_coders != 0);
+  }
+  void Init()
+  {
+    UInt32 numStates = 1 << (_numPrevBits + _numPosBits);
+    for (UInt32 i = 0; i < numStates; i++)
+      _coders[i].Init();
+  }
+  CLiteralEncoder2 *GetSubCoder(UInt32 pos, Byte prevByte)
+    { return &_coders[((pos & _posMask) << _numPrevBits) + (prevByte >> (8 - _numPrevBits))]; }
+};
+
+namespace NLength {
+
+class CEncoder
+{
+  CMyBitEncoder _choice;
+  CMyBitEncoder _choice2;
+  NRangeCoder::CBitTreeEncoder<kNumMoveBits, kNumLowBits> _lowCoder[kNumPosStatesEncodingMax];
+  NRangeCoder::CBitTreeEncoder<kNumMoveBits, kNumMidBits> _midCoder[kNumPosStatesEncodingMax];
+  NRangeCoder::CBitTreeEncoder<kNumMoveBits, kNumHighBits> _highCoder;
+public:
+  void Init(UInt32 numPosStates);
+  void Encode(NRangeCoder::CEncoder *rangeEncoder, UInt32 symbol, UInt32 posState);
+  void SetPrices(UInt32 posState, UInt32 numSymbols, UInt32 *prices) const;
+};
+
+const UInt32 kNumSpecSymbols = kNumLowSymbols + kNumMidSymbols;
+
+class CPriceTableEncoder: public CEncoder
+{
+  UInt32 _prices[kNumPosStatesEncodingMax][kNumSymbolsTotal];
+  UInt32 _tableSize;
+  UInt32 _counters[kNumPosStatesEncodingMax];
+public:
+  void SetTableSize(UInt32 tableSize) { _tableSize = tableSize;  }
+  UInt32 GetPrice(UInt32 symbol, UInt32 posState) const { return _prices[posState][symbol]; }
+  void UpdateTable(UInt32 posState)
+  {
+    SetPrices(posState, _tableSize, _prices[posState]);
+    _counters[posState] = _tableSize;
+  }
+  void UpdateTables(UInt32 numPosStates)
+  {
+    for (UInt32 posState = 0; posState < numPosStates; posState++)
+      UpdateTable(posState);
+  }
+  void Encode(NRangeCoder::CEncoder *rangeEncoder, UInt32 symbol, UInt32 posState, bool updatePrice)
+  {
+    CEncoder::Encode(rangeEncoder, symbol, posState);
+    if (updatePrice)
+      if (--_counters[posState] == 0)
+        UpdateTable(posState);
+  }
+};
+
+}
+
+typedef struct _CSeqInStream
+{
+  ISeqInStream SeqInStream;
+  CMyComPtr<ISequentialInStream> RealStream;
+} CSeqInStream;
+
+
+class CEncoder : 
+  public ICompressCoder,
+  public ICompressSetOutStream,
+  public ICompressSetCoderProperties,
+  public ICompressWriteCoderProperties,
+  public CBaseState,
+  public CMyUnknownImp
+{
+  NRangeCoder::CEncoder _rangeEncoder;
+
+  IMatchFinder _matchFinder;
+  void *_matchFinderObj;
+  
+  #ifdef COMPRESS_MF_MT
+  Bool _multiThread;
+  Bool _mtMode;
+  CMatchFinderMt _matchFinderMt;
+  #endif
+
+  CMatchFinder _matchFinderBase;
+  #ifdef COMPRESS_MF_MT
+  Byte _pad1[kMtCacheLineDummy];
+  #endif
+
+  COptimal _optimum[kNumOpts];
+
+  CMyBitEncoder _isMatch[kNumStates][NLength::kNumPosStatesEncodingMax];
+  CMyBitEncoder _isRep[kNumStates];
+  CMyBitEncoder _isRepG0[kNumStates];
+  CMyBitEncoder _isRepG1[kNumStates];
+  CMyBitEncoder _isRepG2[kNumStates];
+  CMyBitEncoder _isRep0Long[kNumStates][NLength::kNumPosStatesEncodingMax];
+
+  NRangeCoder::CBitTreeEncoder<kNumMoveBits, kNumPosSlotBits> _posSlotEncoder[kNumLenToPosStates];
+
+  CMyBitEncoder _posEncoders[kNumFullDistances - kEndPosModelIndex];
+  NRangeCoder::CBitTreeEncoder<kNumMoveBits, kNumAlignBits> _posAlignEncoder;
+  
+  NLength::CPriceTableEncoder _lenEncoder;
+  NLength::CPriceTableEncoder _repMatchLenEncoder;
+
+  CLiteralEncoder _literalEncoder;
+
+  UInt32 _matchDistances[kMatchMaxLen * 2 + 2 + 1];
+
+  bool _fastMode;
+  // bool _maxMode;
+  UInt32 _numFastBytes;
+  UInt32 _longestMatchLength;    
+  UInt32 _numDistancePairs;
+
+  UInt32 _additionalOffset;
+
+  UInt32 _optimumEndIndex;
+  UInt32 _optimumCurrentIndex;
+
+  bool _longestMatchWasFound;
+
+  UInt32 _posSlotPrices[kNumLenToPosStates][kDistTableSizeMax];
+  
+  UInt32 _distancesPrices[kNumLenToPosStates][kNumFullDistances];
+
+  UInt32 _alignPrices[kAlignTableSize];
+  UInt32 _alignPriceCount;
+
+  UInt32 _distTableSize;
+
+  UInt32 _posStateBits;
+  UInt32 _posStateMask;
+  UInt32 _numLiteralPosStateBits;
+  UInt32 _numLiteralContextBits;
+
+  UInt32 _dictionarySize;
+
+  UInt32 _matchPriceCount;
+  UInt64 nowPos64;
+  bool _finished;
+  ISequentialInStream *_inStream;
+
+  CSeqInStream _seqInStream;
+
+  UInt32 _matchFinderCycles;
+  // int _numSkip
+
+  bool _writeEndMark;
+
+  bool _needReleaseMFStream;
+
+  void ReleaseMatchFinder()
+  {
+    _matchFinder.Init = 0;
+    _seqInStream.RealStream.Release();
+  }
+
+  void ReleaseMFStream()
+  {
+    if (_matchFinderObj && _needReleaseMFStream)
+    {
+      #ifdef COMPRESS_MF_MT
+      if (_mtMode)
+        MatchFinderMt_ReleaseStream(&_matchFinderMt);
+      #endif
+      _needReleaseMFStream = false;
+    }
+    _seqInStream.RealStream.Release();
+  }
+  
+  UInt32 ReadMatchDistances(UInt32 &numDistancePairs);
+
+  void MovePos(UInt32 num);
+  UInt32 GetRepLen1Price(CState state, UInt32 posState) const
+  {
+    return _isRepG0[state.Index].GetPrice0() +
+        _isRep0Long[state.Index][posState].GetPrice0();
+  }
+  
+  UInt32 GetPureRepPrice(UInt32 repIndex, CState state, UInt32 posState) const
+  {
+    UInt32 price;
+    if(repIndex == 0)
+    {
+      price = _isRepG0[state.Index].GetPrice0();
+      price += _isRep0Long[state.Index][posState].GetPrice1();
+    }
+    else
+    {
+      price = _isRepG0[state.Index].GetPrice1();
+      if (repIndex == 1)
+        price += _isRepG1[state.Index].GetPrice0();
+      else
+      {
+        price += _isRepG1[state.Index].GetPrice1();
+        price += _isRepG2[state.Index].GetPrice(repIndex - 2);
+      }
+    }
+    return price;
+  }
+  UInt32 GetRepPrice(UInt32 repIndex, UInt32 len, CState state, UInt32 posState) const
+  {
+    return _repMatchLenEncoder.GetPrice(len - kMatchMinLen, posState) +
+        GetPureRepPrice(repIndex, state, posState);
+  }
+  /*
+  UInt32 GetPosLen2Price(UInt32 pos, UInt32 posState) const
+  {
+    if (pos >= kNumFullDistances)
+      return kIfinityPrice;
+    return _distancesPrices[0][pos] + _lenEncoder.GetPrice(0, posState);
+  }
+  UInt32 GetPosLen3Price(UInt32 pos, UInt32 len, UInt32 posState) const
+  {
+    UInt32 price;
+    UInt32 lenToPosState = GetLenToPosState(len);
+    if (pos < kNumFullDistances)
+      price = _distancesPrices[lenToPosState][pos];
+    else
+      price = _posSlotPrices[lenToPosState][GetPosSlot2(pos)] + 
+          _alignPrices[pos & kAlignMask];
+    return price + _lenEncoder.GetPrice(len - kMatchMinLen, posState);
+  }
+  */
+  UInt32 GetPosLenPrice(UInt32 pos, UInt32 len, UInt32 posState) const
+  {
+    UInt32 price;
+    UInt32 lenToPosState = GetLenToPosState(len);
+    if (pos < kNumFullDistances)
+      price = _distancesPrices[lenToPosState][pos];
+    else
+      price = _posSlotPrices[lenToPosState][GetPosSlot2(pos)] + 
+          _alignPrices[pos & kAlignMask];
+    return price + _lenEncoder.GetPrice(len - kMatchMinLen, posState);
+  }
+
+  UInt32 Backward(UInt32 &backRes, UInt32 cur);
+  UInt32 GetOptimum(UInt32 position, UInt32 &backRes);
+  UInt32 GetOptimumFast(UInt32 &backRes);
+
+  void FillDistancesPrices();
+  void FillAlignPrices();
+    
+  void ReleaseStreams()
+  {
+    ReleaseMFStream();
+    ReleaseOutStream();
+  }
+
+  HRESULT Flush(UInt32 nowPos);
+  class CCoderReleaser
+  {
+    CEncoder *_coder;
+  public:
+    CCoderReleaser(CEncoder *coder): _coder(coder) {}
+    ~CCoderReleaser() { _coder->ReleaseStreams(); }
+  };
+  friend class CCoderReleaser;
+
+  void WriteEndMarker(UInt32 posState);
+
+public:
+  CEncoder();
+  void SetWriteEndMarkerMode(bool writeEndMarker)
+    { _writeEndMark= writeEndMarker; }
+
+  HRESULT Create();
+
+  MY_UNKNOWN_IMP3(
+      ICompressSetOutStream,
+      ICompressSetCoderProperties,
+      ICompressWriteCoderProperties
+      )
+    
+  HRESULT Init();
+  
+  // ICompressCoder interface
+  HRESULT SetStreams(ISequentialInStream *inStream,
+      ISequentialOutStream *outStream,
+      const UInt64 *inSize, const UInt64 *outSize);
+  HRESULT CodeOneBlock(UInt64 *inSize, UInt64 *outSize, Int32 *finished);
+
+  HRESULT CodeReal(ISequentialInStream *inStream,
+      ISequentialOutStream *outStream, 
+      const UInt64 *inSize, const UInt64 *outSize,
+      ICompressProgressInfo *progress);
+
+  // ICompressCoder interface
+  STDMETHOD(Code)(ISequentialInStream *inStream,
+      ISequentialOutStream *outStream, 
+      const UInt64 *inSize, const UInt64 *outSize,
+      ICompressProgressInfo *progress);
+
+  // ICompressSetCoderProperties2
+  STDMETHOD(SetCoderProperties)(const PROPID *propIDs, 
+      const PROPVARIANT *properties, UInt32 numProperties);
+  
+  // ICompressWriteCoderProperties
+  STDMETHOD(WriteCoderProperties)(ISequentialOutStream *outStream);
+
+  STDMETHOD(SetOutStream)(ISequentialOutStream *outStream);
+  STDMETHOD(ReleaseOutStream)();
+
+  virtual ~CEncoder();
+};
+
+}}
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/misc/libphysfs/lzma/CPP/7zip/Compress/LZMA/LZMARegister.cpp	Mon Apr 10 12:06:43 2017 -0400
@@ -0,0 +1,19 @@
+// LZMARegister.cpp
+
+#include "StdAfx.h"
+
+#include "../../Common/RegisterCodec.h"
+
+#include "LZMADecoder.h"
+static void *CreateCodec() { return (void *)(ICompressCoder *)(new NCompress::NLZMA::CDecoder); }
+#ifndef EXTRACT_ONLY
+#include "LZMAEncoder.h"
+static void *CreateCodecOut() { return (void *)(ICompressCoder *)(new NCompress::NLZMA::CEncoder);  }
+#else
+#define CreateCodecOut 0
+#endif
+
+static CCodecInfo g_CodecInfo =
+  { CreateCodec, CreateCodecOut, 0x030101, L"LZMA", 1, false };
+
+REGISTER_CODEC(LZMA)
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/misc/libphysfs/lzma/CPP/7zip/Compress/LZMA/StdAfx.cpp	Mon Apr 10 12:06:43 2017 -0400
@@ -0,0 +1,3 @@
+// StdAfx.cpp
+
+#include "StdAfx.h"
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/misc/libphysfs/lzma/CPP/7zip/Compress/LZMA/StdAfx.h	Mon Apr 10 12:06:43 2017 -0400
@@ -0,0 +1,8 @@
+// StdAfx.h
+
+#ifndef __STDAFX_H
+#define __STDAFX_H
+
+#include "../../../Common/MyWindows.h"
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/misc/libphysfs/lzma/CPP/7zip/Compress/LZMA_Alone/AloneLZMA.dsp	Mon Apr 10 12:06:43 2017 -0400
@@ -0,0 +1,504 @@
+# Microsoft Developer Studio Project File - Name="AloneLZMA" - Package Owner=<4>
+# Microsoft Developer Studio Generated Build File, Format Version 6.00
+# ** DO NOT EDIT **
+
+# TARGTYPE "Win32 (x86) Console Application" 0x0103
+
+CFG=AloneLZMA - Win32 DebugU
+!MESSAGE This is not a valid makefile. To build this project using NMAKE,
+!MESSAGE use the Export Makefile command and run
+!MESSAGE 
+!MESSAGE NMAKE /f "AloneLZMA.mak".
+!MESSAGE 
+!MESSAGE You can specify a configuration when running NMAKE
+!MESSAGE by defining the macro CFG on the command line. For example:
+!MESSAGE 
+!MESSAGE NMAKE /f "AloneLZMA.mak" CFG="AloneLZMA - Win32 DebugU"
+!MESSAGE 
+!MESSAGE Possible choices for configuration are:
+!MESSAGE 
+!MESSAGE "AloneLZMA - Win32 Release" (based on "Win32 (x86) Console Application")
+!MESSAGE "AloneLZMA - Win32 Debug" (based on "Win32 (x86) Console Application")
+!MESSAGE "AloneLZMA - Win32 ReleaseU" (based on "Win32 (x86) Console Application")
+!MESSAGE "AloneLZMA - Win32 DebugU" (based on "Win32 (x86) Console Application")
+!MESSAGE 
+
+# Begin Project
+# PROP AllowPerConfigDependencies 0
+# PROP Scc_ProjName ""
+# PROP Scc_LocalPath ""
+CPP=cl.exe
+RSC=rc.exe
+
+!IF  "$(CFG)" == "AloneLZMA - Win32 Release"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 0
+# PROP BASE Output_Dir "Release"
+# PROP BASE Intermediate_Dir "Release"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 0
+# PROP Output_Dir "Release"
+# PROP Intermediate_Dir "Release"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
+# ADD CPP /nologo /MT /W3 /GX /O2 /I "..\..\..\\" /D "NDEBUG" /D "_MBCS" /D "WIN32" /D "_CONSOLE" /D "COMPRESS_MF_MT" /D "BENCH_MT" /FAcs /Yu"StdAfx.h" /FD /c
+# ADD BASE RSC /l 0x419 /d "NDEBUG"
+# ADD RSC /l 0x419 /d "NDEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386
+# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 /out:"c:\UTIL\lzma.exe" /opt:NOWIN98
+# SUBTRACT LINK32 /pdb:none
+
+!ELSEIF  "$(CFG)" == "AloneLZMA - Win32 Debug"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 1
+# PROP BASE Output_Dir "Debug"
+# PROP BASE Intermediate_Dir "Debug"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 1
+# PROP Output_Dir "Debug"
+# PROP Intermediate_Dir "Debug"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c
+# ADD CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /I "..\..\..\\" /D "_DEBUG" /D "_MBCS" /D "WIN32" /D "_CONSOLE" /D "COMPRESS_MF_MT" /D "BENCH_MT" /Yu"StdAfx.h" /FD /GZ /c
+# ADD BASE RSC /l 0x419 /d "_DEBUG"
+# ADD RSC /l 0x419 /d "_DEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept
+# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /out:"c:\UTIL\lzma.exe" /pdbtype:sept
+
+!ELSEIF  "$(CFG)" == "AloneLZMA - Win32 ReleaseU"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 0
+# PROP BASE Output_Dir "ReleaseU"
+# PROP BASE Intermediate_Dir "ReleaseU"
+# PROP BASE Ignore_Export_Lib 0
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 0
+# PROP Output_Dir "ReleaseU"
+# PROP Intermediate_Dir "ReleaseU"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /MD /W3 /GX /O2 /D "NDEBUG" /D "WIN32" /D "_CONSOLE" /D "EXCLUDE_COM" /D "NO_REGISTRY" /D "FORMAT_7Z" /D "FORMAT_BZIP2" /D "FORMAT_ZIP" /D "FORMAT_TAR" /D "FORMAT_GZIP" /D "COMPRESS_LZMA" /D "COMPRESS_BCJ_X86" /D "COMPRESS_BCJ2" /D "COMPRESS_COPY" /D "COMPRESS_MF_PAT" /D "COMPRESS_MF_BT" /D "COMPRESS_PPMD" /D "COMPRESS_DEFLATE" /D "COMPRESS_IMPLODE" /D "COMPRESS_BZIP2" /D "CRYPTO_ZIP" /Yu"StdAfx.h" /FD /c
+# ADD CPP /nologo /MD /W3 /GX /O2 /I "..\..\..\\" /D "NDEBUG" /D "UNICODE" /D "_UNICODE" /D "WIN32" /D "_CONSOLE" /D "COMPRESS_MF_MT" /D "BENCH_MT" /Yu"StdAfx.h" /FD /c
+# ADD BASE RSC /l 0x419 /d "NDEBUG"
+# ADD RSC /l 0x419 /d "NDEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 /out:"c:\UTIL\7za2.exe" /opt:NOWIN98
+# SUBTRACT BASE LINK32 /pdb:none
+# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 /out:"c:\UTIL\lzma.exe" /opt:NOWIN98
+# SUBTRACT LINK32 /pdb:none
+
+!ELSEIF  "$(CFG)" == "AloneLZMA - Win32 DebugU"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 1
+# PROP BASE Output_Dir "DebugU"
+# PROP BASE Intermediate_Dir "DebugU"
+# PROP BASE Ignore_Export_Lib 0
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 1
+# PROP Output_Dir "DebugU"
+# PROP Intermediate_Dir "DebugU"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "_DEBUG" /D "WIN32" /D "_CONSOLE" /D "EXCLUDE_COM" /D "NO_REGISTRY" /D "FORMAT_7Z" /D "FORMAT_BZIP2" /D "FORMAT_ZIP" /D "FORMAT_TAR" /D "FORMAT_GZIP" /D "COMPRESS_LZMA" /D "COMPRESS_BCJ_X86" /D "COMPRESS_BCJ2" /D "COMPRESS_COPY" /D "COMPRESS_MF_PAT" /D "COMPRESS_MF_BT" /D "COMPRESS_PPMD" /D "COMPRESS_DEFLATE" /D "COMPRESS_IMPLODE" /D "COMPRESS_BZIP2" /D "CRYPTO_ZIP" /D "_MBCS" /Yu"StdAfx.h" /FD /GZ /c
+# ADD CPP /nologo /W3 /Gm /GX /ZI /Od /I "..\..\..\\" /D "_DEBUG" /D "_UNICODE" /D "UNICODE" /D "WIN32" /D "_CONSOLE" /D "COMPRESS_MF_MT" /D "BENCH_MT" /Yu"StdAfx.h" /FD /GZ /c
+# ADD BASE RSC /l 0x419 /d "_DEBUG"
+# ADD RSC /l 0x419 /d "_DEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /out:"c:\UTIL\7za2.exe" /pdbtype:sept
+# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /out:"c:\UTIL\lzma.exe" /pdbtype:sept
+
+!ENDIF 
+
+# Begin Target
+
+# Name "AloneLZMA - Win32 Release"
+# Name "AloneLZMA - Win32 Debug"
+# Name "AloneLZMA - Win32 ReleaseU"
+# Name "AloneLZMA - Win32 DebugU"
+# Begin Group "Spec"
+
+# PROP Default_Filter ""
+# Begin Source File
+
+SOURCE=.\StdAfx.cpp
+# ADD CPP /Yc"StdAfx.h"
+# End Source File
+# Begin Source File
+
+SOURCE=.\StdAfx.h
+# End Source File
+# End Group
+# Begin Group "Compress"
+
+# PROP Default_Filter ""
+# Begin Group "LZMA"
+
+# PROP Default_Filter ""
+# Begin Source File
+
+SOURCE=..\LZMA\LZMA.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\LZMA\LZMADecoder.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\LZMA\LZMADecoder.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\LZMA\LZMAEncoder.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\LZMA\LZMAEncoder.h
+# End Source File
+# End Group
+# Begin Group "RangeCoder"
+
+# PROP Default_Filter ""
+# Begin Source File
+
+SOURCE=..\RangeCoder\RangeCoder.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\RangeCoder\RangeCoderBit.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\RangeCoder\RangeCoderBit.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\RangeCoder\RangeCoderBitTree.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\RangeCoder\RangeCoderOpt.h
+# End Source File
+# End Group
+# Begin Group "LZ"
+
+# PROP Default_Filter ""
+# Begin Source File
+
+SOURCE=..\LZ\LZOutWindow.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\LZ\LZOutWindow.h
+# End Source File
+# End Group
+# End Group
+# Begin Group "Windows"
+
+# PROP Default_Filter ""
+# Begin Source File
+
+SOURCE=..\..\..\Windows\FileIO.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Windows\FileIO.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Windows\Synchronization.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Windows\Synchronization.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Windows\System.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Windows\System.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Windows\Thread.h
+# End Source File
+# End Group
+# Begin Group "Common"
+
+# PROP Default_Filter ""
+# Begin Source File
+
+SOURCE=..\..\..\Common\CommandLineParser.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Common\CommandLineParser.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Common\CRC.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Common\Defs.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Windows\Defs.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Common\IntToString.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Common\IntToString.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Common\MyCom.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Common\MyString.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Common\MyString.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Common\MyVector.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Common\MyVector.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Common\MyWindows.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Common\NewHandler.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Common\NewHandler.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Common\StringConvert.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Common\StringConvert.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Common\StringToInt.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Common\StringToInt.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Common\Types.h
+# End Source File
+# End Group
+# Begin Group "7zip Common"
+
+# PROP Default_Filter ""
+# Begin Source File
+
+SOURCE=..\..\Common\FileStreams.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Common\FileStreams.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Common\InBuffer.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Common\InBuffer.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Common\OutBuffer.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Common\OutBuffer.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Common\StreamUtils.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Common\StreamUtils.h
+# End Source File
+# End Group
+# Begin Group "C"
+
+# PROP Default_Filter ""
+# Begin Group "C-Lz"
+
+# PROP Default_Filter ""
+# Begin Source File
+
+SOURCE=..\..\..\..\C\Compress\Lz\MatchFinder.c
+# SUBTRACT CPP /YX /Yc /Yu
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\..\C\Compress\Lz\MatchFinder.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\..\C\Compress\Lz\MatchFinderMt.c
+# SUBTRACT CPP /YX /Yc /Yu
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\..\C\Compress\Lz\MatchFinderMt.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\..\C\Threads.c
+# SUBTRACT CPP /YX /Yc /Yu
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\..\C\Threads.h
+# End Source File
+# End Group
+# Begin Group "LZMA_C"
+
+# PROP Default_Filter ""
+# Begin Source File
+
+SOURCE=..\..\..\..\C\Compress\Lzma\LzmaDecode.c
+# SUBTRACT CPP /YX /Yc /Yu
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\..\C\Compress\Lzma\LzmaDecode.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\..\C\Compress\Lzma\LzmaTypes.h
+# End Source File
+# End Group
+# Begin Group "Branch"
+
+# PROP Default_Filter ""
+# Begin Source File
+
+SOURCE=..\..\..\..\C\Compress\Branch\BranchTypes.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\..\C\Compress\Branch\BranchX86.c
+# SUBTRACT CPP /YX /Yc /Yu
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\..\C\Compress\Branch\BranchX86.h
+# End Source File
+# End Group
+# Begin Source File
+
+SOURCE=..\..\..\..\C\7zCrc.c
+# SUBTRACT CPP /YX /Yc /Yu
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\..\C\7zCrc.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\..\C\Alloc.c
+# SUBTRACT CPP /YX /Yc /Yu
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\..\C\Alloc.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\..\C\Types.h
+# End Source File
+# End Group
+# Begin Source File
+
+SOURCE=..\..\ICoder.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\LzmaAlone.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\LzmaBench.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\LzmaBench.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\LzmaBenchCon.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\LzmaBenchCon.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\LzmaRam.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\LzmaRam.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\LzmaRamDecode.c
+# SUBTRACT CPP /YX /Yc /Yu
+# End Source File
+# Begin Source File
+
+SOURCE=.\LzmaRamDecode.h
+# End Source File
+# End Target
+# End Project
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/misc/libphysfs/lzma/CPP/7zip/Compress/LZMA_Alone/AloneLZMA.dsw	Mon Apr 10 12:06:43 2017 -0400
@@ -0,0 +1,29 @@
+Microsoft Developer Studio Workspace File, Format Version 6.00
+# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE!
+
+###############################################################################
+
+Project: "AloneLZMA"=.\AloneLZMA.dsp - Package Owner=<4>
+
+Package=<5>
+{{{
+}}}
+
+Package=<4>
+{{{
+}}}
+
+###############################################################################
+
+Global:
+
+Package=<5>
+{{{
+}}}
+
+Package=<3>
+{{{
+}}}
+
+###############################################################################
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/misc/libphysfs/lzma/CPP/7zip/Compress/LZMA_Alone/LzmaAlone.cpp	Mon Apr 10 12:06:43 2017 -0400
@@ -0,0 +1,554 @@
+// LzmaAlone.cpp
+
+#include "StdAfx.h"
+
+#include "../../../Common/MyWindows.h"
+#include "../../../Common/MyInitGuid.h"
+
+#include <stdio.h>
+
+#if defined(_WIN32) || defined(OS2) || defined(MSDOS)
+#include <fcntl.h>
+#include <io.h>
+#define MY_SET_BINARY_MODE(file) _setmode(_fileno(file), O_BINARY)
+#else
+#define MY_SET_BINARY_MODE(file)
+#endif
+
+#include "../../../Common/CommandLineParser.h"
+#include "../../../Common/StringConvert.h"
+#include "../../../Common/StringToInt.h"
+
+#include "../../Common/FileStreams.h"
+#include "../../Common/StreamUtils.h"
+
+#include "../LZMA/LZMADecoder.h"
+#include "../LZMA/LZMAEncoder.h"
+
+#include "LzmaBenchCon.h"
+#include "LzmaRam.h"
+
+#ifdef COMPRESS_MF_MT
+#include "../../../Windows/System.h"
+#endif
+
+#include "../../MyVersion.h"
+
+extern "C"
+{
+#include "LzmaRamDecode.h"
+}
+
+using namespace NCommandLineParser;
+
+#ifdef _WIN32
+bool g_IsNT = false;
+static inline bool IsItWindowsNT()
+{
+  OSVERSIONINFO versionInfo;
+  versionInfo.dwOSVersionInfoSize = sizeof(versionInfo);
+  if (!::GetVersionEx(&versionInfo)) 
+    return false;
+  return (versionInfo.dwPlatformId == VER_PLATFORM_WIN32_NT);
+}
+#endif
+
+static const char *kCantAllocate = "Can not allocate memory";
+static const char *kReadError = "Read error";
+static const char *kWriteError = "Write error";
+
+namespace NKey {
+enum Enum
+{
+  kHelp1 = 0,
+  kHelp2,
+  kMode,
+  kDictionary,
+  kFastBytes,
+  kMatchFinderCycles,
+  kLitContext,
+  kLitPos,
+  kPosBits,
+  kMatchFinder,
+  kMultiThread,
+  kEOS,
+  kStdIn,
+  kStdOut,
+  kFilter86
+};
+}
+
+static const CSwitchForm kSwitchForms[] = 
+{
+  { L"?",  NSwitchType::kSimple, false },
+  { L"H",  NSwitchType::kSimple, false },
+  { L"A", NSwitchType::kUnLimitedPostString, false, 1 },
+  { L"D", NSwitchType::kUnLimitedPostString, false, 1 },
+  { L"FB", NSwitchType::kUnLimitedPostString, false, 1 },
+  { L"MC", NSwitchType::kUnLimitedPostString, false, 1 },
+  { L"LC", NSwitchType::kUnLimitedPostString, false, 1 },
+  { L"LP", NSwitchType::kUnLimitedPostString, false, 1 },
+  { L"PB", NSwitchType::kUnLimitedPostString, false, 1 },
+  { L"MF", NSwitchType::kUnLimitedPostString, false, 1 },
+  { L"MT", NSwitchType::kUnLimitedPostString, false, 0 },
+  { L"EOS", NSwitchType::kSimple, false },
+  { L"SI",  NSwitchType::kSimple, false },
+  { L"SO",  NSwitchType::kSimple, false },
+  { L"F86",  NSwitchType::kPostChar, false, 0, 0, L"+" }
+};
+
+static const int kNumSwitches = sizeof(kSwitchForms) / sizeof(kSwitchForms[0]);
+
+static void PrintHelp()
+{
+  fprintf(stderr, "\nUsage:  LZMA <e|d> inputFile outputFile [<switches>...]\n"
+             "  e: encode file\n"
+             "  d: decode file\n"
+             "  b: Benchmark\n"
+    "<Switches>\n"
+    "  -a{N}:  set compression mode - [0, 1], default: 1 (max)\n"
+    "  -d{N}:  set dictionary - [0,30], default: 23 (8MB)\n"
+    "  -fb{N}: set number of fast bytes - [5, 273], default: 128\n"
+    "  -mc{N}: set number of cycles for match finder\n"
+    "  -lc{N}: set number of literal context bits - [0, 8], default: 3\n"
+    "  -lp{N}: set number of literal pos bits - [0, 4], default: 0\n"
+    "  -pb{N}: set number of pos bits - [0, 4], default: 2\n"
+    "  -mf{MF_ID}: set Match Finder: [bt2, bt3, bt4, hc4], default: bt4\n"
+    "  -mt{N}: set number of CPU threads\n"
+    "  -eos:   write End Of Stream marker\n"
+    "  -si:    read data from stdin\n"
+    "  -so:    write data to stdout\n"
+    );
+}
+
+static void PrintHelpAndExit(const char *s)
+{
+  fprintf(stderr, "\nError: %s\n\n", s);
+  PrintHelp();
+  throw -1;
+}
+
+static void IncorrectCommand()
+{
+  PrintHelpAndExit("Incorrect command");
+}
+
+static void WriteArgumentsToStringList(int numArguments, const char *arguments[], 
+    UStringVector &strings)
+{
+  for(int i = 1; i < numArguments; i++)
+    strings.Add(MultiByteToUnicodeString(arguments[i]));
+}
+
+static bool GetNumber(const wchar_t *s, UInt32 &value)
+{
+  value = 0;
+  if (MyStringLen(s) == 0)
+    return false;
+  const wchar_t *end;
+  UInt64 res = ConvertStringToUInt64(s, &end);
+  if (*end != L'\0')
+    return false;
+  if (res > 0xFFFFFFFF)
+    return false;
+  value = UInt32(res);
+  return true;
+}
+
+int main2(int n, const char *args[])
+{
+  #ifdef _WIN32
+  g_IsNT = IsItWindowsNT();
+  #endif
+
+  fprintf(stderr, "\nLZMA " MY_VERSION_COPYRIGHT_DATE "\n");
+
+  if (n == 1)
+  {
+    PrintHelp();
+    return 0;
+  }
+
+  bool unsupportedTypes = (sizeof(Byte) != 1 || sizeof(UInt32) < 4 || sizeof(UInt64) < 4);
+  if (unsupportedTypes)
+  {
+    fprintf(stderr, "Unsupported base types. Edit Common/Types.h and recompile");
+    return 1;
+  }   
+
+  UStringVector commandStrings;
+  WriteArgumentsToStringList(n, args, commandStrings);
+  CParser parser(kNumSwitches);
+  try
+  {
+    parser.ParseStrings(kSwitchForms, commandStrings);
+  }
+  catch(...) 
+  {
+    IncorrectCommand();
+  }
+
+  if(parser[NKey::kHelp1].ThereIs || parser[NKey::kHelp2].ThereIs)
+  {
+    PrintHelp();
+    return 0;
+  }
+  const UStringVector &nonSwitchStrings = parser.NonSwitchStrings;
+
+  int paramIndex = 0;
+  if (paramIndex >= nonSwitchStrings.Size())
+    IncorrectCommand();
+  const UString &command = nonSwitchStrings[paramIndex++]; 
+
+  bool dictionaryIsDefined = false;
+  UInt32 dictionary = (UInt32)-1;
+  if(parser[NKey::kDictionary].ThereIs)
+  {
+    UInt32 dicLog;
+    if (!GetNumber(parser[NKey::kDictionary].PostStrings[0], dicLog))
+      IncorrectCommand();
+    dictionary = 1 << dicLog;
+    dictionaryIsDefined = true;
+  }
+  UString mf = L"BT4";
+  if (parser[NKey::kMatchFinder].ThereIs)
+    mf = parser[NKey::kMatchFinder].PostStrings[0];
+
+  UInt32 numThreads = (UInt32)-1;
+
+  #ifdef COMPRESS_MF_MT
+  if (parser[NKey::kMultiThread].ThereIs)
+  {
+    UInt32 numCPUs = NWindows::NSystem::GetNumberOfProcessors();
+    const UString &s = parser[NKey::kMultiThread].PostStrings[0];
+    if (s.IsEmpty())
+      numThreads = numCPUs;
+    else
+      if (!GetNumber(s, numThreads))
+        IncorrectCommand();
+  }
+  #endif
+
+  if (command.CompareNoCase(L"b") == 0)
+  {
+    const UInt32 kNumDefaultItereations = 1;
+    UInt32 numIterations = kNumDefaultItereations;
+    {
+      if (paramIndex < nonSwitchStrings.Size())
+        if (!GetNumber(nonSwitchStrings[paramIndex++], numIterations))
+          numIterations = kNumDefaultItereations;
+    }
+    return LzmaBenchCon(stderr, numIterations, numThreads, dictionary);
+  }
+
+  if (numThreads == (UInt32)-1)
+    numThreads = 1;
+
+  bool encodeMode = false;
+  if (command.CompareNoCase(L"e") == 0)
+    encodeMode = true;
+  else if (command.CompareNoCase(L"d") == 0)
+    encodeMode = false;
+  else
+    IncorrectCommand();
+
+  bool stdInMode = parser[NKey::kStdIn].ThereIs;
+  bool stdOutMode = parser[NKey::kStdOut].ThereIs;
+
+  CMyComPtr<ISequentialInStream> inStream;
+  CInFileStream *inStreamSpec = 0;
+  if (stdInMode)
+  {
+    inStream = new CStdInFileStream;
+    MY_SET_BINARY_MODE(stdin);
+  }
+  else
+  {
+    if (paramIndex >= nonSwitchStrings.Size())
+      IncorrectCommand();
+    const UString &inputName = nonSwitchStrings[paramIndex++]; 
+    inStreamSpec = new CInFileStream;
+    inStream = inStreamSpec;
+    if (!inStreamSpec->Open(GetSystemString(inputName)))
+    {
+      fprintf(stderr, "\nError: can not open input file %s\n", 
+          (const char *)GetOemString(inputName));
+      return 1;
+    }
+  }
+
+  CMyComPtr<ISequentialOutStream> outStream;
+  COutFileStream *outStreamSpec = NULL;
+  if (stdOutMode)
+  {
+    outStream = new CStdOutFileStream;
+    MY_SET_BINARY_MODE(stdout);
+  }
+  else
+  {
+    if (paramIndex >= nonSwitchStrings.Size())
+      IncorrectCommand();
+    const UString &outputName = nonSwitchStrings[paramIndex++]; 
+    outStreamSpec = new COutFileStream;
+    outStream = outStreamSpec;
+    if (!outStreamSpec->Create(GetSystemString(outputName), true))
+    {
+      fprintf(stderr, "\nError: can not open output file %s\n", 
+        (const char *)GetOemString(outputName));
+      return 1;
+    }
+  }
+
+  if (parser[NKey::kFilter86].ThereIs)
+  {
+    // -f86 switch is for x86 filtered mode: BCJ + LZMA.
+    if (parser[NKey::kEOS].ThereIs || stdInMode)
+      throw "Can not use stdin in this mode";
+    UInt64 fileSize;
+    inStreamSpec->File.GetLength(fileSize);
+    if (fileSize > 0xF0000000)
+      throw "File is too big";
+    UInt32 inSize = (UInt32)fileSize;
+    Byte *inBuffer = 0;
+    if (inSize != 0)
+    {
+      inBuffer = (Byte *)MyAlloc((size_t)inSize); 
+      if (inBuffer == 0)
+        throw kCantAllocate;
+    }
+    
+    UInt32 processedSize;
+    if (ReadStream(inStream, inBuffer, (UInt32)inSize, &processedSize) != S_OK)
+      throw "Can not read";
+    if ((UInt32)inSize != processedSize)
+      throw "Read size error";
+
+    Byte *outBuffer = 0;
+    size_t outSizeProcessed;
+    if (encodeMode)
+    {
+      // we allocate 105% of original size for output buffer
+      size_t outSize = (size_t)fileSize / 20 * 21 + (1 << 16);
+      if (outSize != 0)
+      {
+        outBuffer = (Byte *)MyAlloc((size_t)outSize); 
+        if (outBuffer == 0)
+          throw kCantAllocate;
+      }
+      if (!dictionaryIsDefined)
+        dictionary = 1 << 23;
+      int res = LzmaRamEncode(inBuffer, inSize, outBuffer, outSize, &outSizeProcessed, 
+          dictionary, parser[NKey::kFilter86].PostCharIndex == 0 ? SZ_FILTER_YES : SZ_FILTER_AUTO);
+      if (res != 0)
+      {
+        fprintf(stderr, "\nEncoder error = %d\n", (int)res);
+        return 1;
+      }
+    }
+    else
+    {
+      size_t outSize;
+      if (LzmaRamGetUncompressedSize(inBuffer, inSize, &outSize) != 0)
+        throw "data error";
+      if (outSize != 0)
+      {
+        outBuffer = (Byte *)MyAlloc(outSize); 
+        if (outBuffer == 0)
+          throw kCantAllocate;
+      }
+      int res = LzmaRamDecompress(inBuffer, inSize, outBuffer, outSize, &outSizeProcessed, malloc, free);
+      if (res != 0)
+        throw "LzmaDecoder error";
+    }
+    if (WriteStream(outStream, outBuffer, (UInt32)outSizeProcessed, &processedSize) != S_OK)
+      throw kWriteError;
+    MyFree(outBuffer);
+    MyFree(inBuffer);
+    return 0;
+  }
+
+
+  UInt64 fileSize;
+  if (encodeMode)
+  {
+    NCompress::NLZMA::CEncoder *encoderSpec = new NCompress::NLZMA::CEncoder;
+    CMyComPtr<ICompressCoder> encoder = encoderSpec;
+
+    if (!dictionaryIsDefined)
+      dictionary = 1 << 23;
+
+    UInt32 posStateBits = 2;
+    UInt32 litContextBits = 3; // for normal files
+    // UInt32 litContextBits = 0; // for 32-bit data
+    UInt32 litPosBits = 0;
+    // UInt32 litPosBits = 2; // for 32-bit data
+    UInt32 algorithm = 1;
+    UInt32 numFastBytes = 128;
+    UInt32 matchFinderCycles = 16 + numFastBytes / 2;
+    bool matchFinderCyclesDefined = false;
+
+    bool eos = parser[NKey::kEOS].ThereIs || stdInMode;
+ 
+    if(parser[NKey::kMode].ThereIs)
+      if (!GetNumber(parser[NKey::kMode].PostStrings[0], algorithm))
+        IncorrectCommand();
+
+    if(parser[NKey::kFastBytes].ThereIs)
+      if (!GetNumber(parser[NKey::kFastBytes].PostStrings[0], numFastBytes))
+        IncorrectCommand();
+    matchFinderCyclesDefined = parser[NKey::kMatchFinderCycles].ThereIs;
+    if (matchFinderCyclesDefined)
+      if (!GetNumber(parser[NKey::kMatchFinderCycles].PostStrings[0], matchFinderCycles))
+        IncorrectCommand();
+    if(parser[NKey::kLitContext].ThereIs)
+      if (!GetNumber(parser[NKey::kLitContext].PostStrings[0], litContextBits))
+        IncorrectCommand();
+    if(parser[NKey::kLitPos].ThereIs)
+      if (!GetNumber(parser[NKey::kLitPos].PostStrings[0], litPosBits))
+        IncorrectCommand();
+    if(parser[NKey::kPosBits].ThereIs)
+      if (!GetNumber(parser[NKey::kPosBits].PostStrings[0], posStateBits))
+        IncorrectCommand();
+
+    PROPID propIDs[] = 
+    {
+      NCoderPropID::kDictionarySize,
+      NCoderPropID::kPosStateBits,
+      NCoderPropID::kLitContextBits,
+      NCoderPropID::kLitPosBits,
+      NCoderPropID::kAlgorithm,
+      NCoderPropID::kNumFastBytes,
+      NCoderPropID::kMatchFinder,
+      NCoderPropID::kEndMarker,
+      NCoderPropID::kNumThreads,
+      NCoderPropID::kMatchFinderCycles,
+    };
+    const int kNumPropsMax = sizeof(propIDs) / sizeof(propIDs[0]);
+
+    PROPVARIANT properties[kNumPropsMax];
+    for (int p = 0; p < 6; p++)
+      properties[p].vt = VT_UI4;
+
+    properties[0].ulVal = (UInt32)dictionary;
+    properties[1].ulVal = (UInt32)posStateBits;
+    properties[2].ulVal = (UInt32)litContextBits;
+    properties[3].ulVal = (UInt32)litPosBits;
+    properties[4].ulVal = (UInt32)algorithm;
+    properties[5].ulVal = (UInt32)numFastBytes;
+
+    properties[6].vt = VT_BSTR;
+    properties[6].bstrVal = (BSTR)(const wchar_t *)mf;
+
+    properties[7].vt = VT_BOOL;
+    properties[7].boolVal = eos ? VARIANT_TRUE : VARIANT_FALSE;
+
+    properties[8].vt = VT_UI4;
+    properties[8].ulVal = (UInt32)numThreads;
+
+    // it must be last in property list
+    properties[9].vt = VT_UI4;
+    properties[9].ulVal = (UInt32)matchFinderCycles;
+
+    int numProps = kNumPropsMax;
+    if (!matchFinderCyclesDefined)
+      numProps--;
+
+    if (encoderSpec->SetCoderProperties(propIDs, properties, numProps) != S_OK)
+      IncorrectCommand();
+    encoderSpec->WriteCoderProperties(outStream);
+
+    if (eos || stdInMode)
+      fileSize = (UInt64)(Int64)-1;
+    else
+      inStreamSpec->File.GetLength(fileSize);
+
+    for (int i = 0; i < 8; i++)
+    {
+      Byte b = Byte(fileSize >> (8 * i));
+      if (outStream->Write(&b, 1, 0) != S_OK)
+      {
+        fprintf(stderr, kWriteError);
+        return 1;
+      }
+    }
+    HRESULT result = encoder->Code(inStream, outStream, 0, 0, 0);
+    if (result == E_OUTOFMEMORY)
+    {
+      fprintf(stderr, "\nError: Can not allocate memory\n");
+      return 1;
+    }   
+    else if (result != S_OK)
+    {
+      fprintf(stderr, "\nEncoder error = %X\n", (unsigned int)result);
+      return 1;
+    }   
+  }
+  else
+  {
+    NCompress::NLZMA::CDecoder *decoderSpec = new NCompress::NLZMA::CDecoder;
+    CMyComPtr<ICompressCoder> decoder = decoderSpec;
+    const UInt32 kPropertiesSize = 5;
+    Byte properties[kPropertiesSize];
+    UInt32 processedSize;
+    if (ReadStream(inStream, properties, kPropertiesSize, &processedSize) != S_OK)
+    {
+      fprintf(stderr, kReadError);
+      return 1;
+    }
+    if (processedSize != kPropertiesSize)
+    {
+      fprintf(stderr, kReadError);
+      return 1;
+    }
+    if (decoderSpec->SetDecoderProperties2(properties, kPropertiesSize) != S_OK)
+    {
+      fprintf(stderr, "SetDecoderProperties error");
+      return 1;
+    }
+    fileSize = 0;
+    for (int i = 0; i < 8; i++)
+    {
+      Byte b;
+      if (inStream->Read(&b, 1, &processedSize) != S_OK)
+      {
+        fprintf(stderr, kReadError);
+        return 1;
+      }
+      if (processedSize != 1)
+      {
+        fprintf(stderr, kReadError);
+        return 1;
+      }
+      fileSize |= ((UInt64)b) << (8 * i);
+    }
+    if (decoder->Code(inStream, outStream, 0, &fileSize, 0) != S_OK)
+    {
+      fprintf(stderr, "Decoder error");
+      return 1;
+    }   
+  }
+  if (outStreamSpec != NULL)
+  {
+    if (outStreamSpec->Close() != S_OK)
+    {
+      fprintf(stderr, "File closing error");
+      return 1;
+    }
+  }
+  return 0;
+}
+
+int main(int n, const char *args[])
+{
+  try { return main2(n, args); }
+  catch(const char *s) 
+  { 
+    fprintf(stderr, "\nError: %s\n", s);
+    return 1; 
+  }
+  catch(...) 
+  { 
+    fprintf(stderr, "\nError\n");
+    return 1; 
+  }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/misc/libphysfs/lzma/CPP/7zip/Compress/LZMA_Alone/LzmaBench.cpp	Mon Apr 10 12:06:43 2017 -0400
@@ -0,0 +1,1024 @@
+// LzmaBench.cpp
+
+#include "StdAfx.h"
+
+#include "LzmaBench.h"
+
+#ifndef _WIN32
+#define USE_POSIX_TIME
+#define USE_POSIX_TIME2
+#endif
+
+#ifdef USE_POSIX_TIME
+#include <time.h>
+#ifdef USE_POSIX_TIME2
+#include <sys/time.h>
+#endif
+#endif
+
+#ifdef _WIN32
+#define USE_ALLOCA
+#endif
+
+#ifdef USE_ALLOCA
+#ifdef _WIN32
+#include <malloc.h>
+#else
+#include <stdlib.h>
+#endif
+#endif
+
+extern "C" 
+{ 
+#include "../../../../C/Alloc.h"
+#include "../../../../C/7zCrc.h"
+}
+#include "../../../Common/MyCom.h"
+#include "../../ICoder.h"
+
+#ifdef BENCH_MT
+#include "../../../Windows/Thread.h"
+#include "../../../Windows/Synchronization.h"
+#endif
+
+#ifdef EXTERNAL_LZMA
+#include "../../../Windows/PropVariant.h"
+#else
+#include "../LZMA/LZMADecoder.h"
+#include "../LZMA/LZMAEncoder.h"
+#endif
+
+static const UInt32 kUncompressMinBlockSize = 1 << 26;
+static const UInt32 kAdditionalSize = (1 << 16);
+static const UInt32 kCompressedAdditionalSize = (1 << 10);
+static const UInt32 kMaxLzmaPropSize = 5;
+
+class CBaseRandomGenerator
+{
+  UInt32 A1;
+  UInt32 A2;
+public:
+  CBaseRandomGenerator() { Init(); }
+  void Init() { A1 = 362436069; A2 = 521288629;}
+  UInt32 GetRnd() 
+  {
+    return 
+      ((A1 = 36969 * (A1 & 0xffff) + (A1 >> 16)) << 16) +
+      ((A2 = 18000 * (A2 & 0xffff) + (A2 >> 16)) );
+  }
+};
+
+class CBenchBuffer
+{
+public:
+  size_t BufferSize;
+  Byte *Buffer;
+  CBenchBuffer(): Buffer(0) {} 
+  virtual ~CBenchBuffer() { Free(); }
+  void Free() 
+  { 
+    ::MidFree(Buffer);
+    Buffer = 0;
+  }
+  bool Alloc(size_t bufferSize) 
+  {
+    if (Buffer != 0 && BufferSize == bufferSize)
+      return true;
+    Free();
+    Buffer = (Byte *)::MidAlloc(bufferSize);
+    BufferSize = bufferSize;
+    return (Buffer != 0);
+  }
+};
+
+class CBenchRandomGenerator: public CBenchBuffer
+{
+  CBaseRandomGenerator *RG;
+public:
+  void Set(CBaseRandomGenerator *rg) { RG = rg; }
+  UInt32 GetVal(UInt32 &res, int numBits) 
+  {
+    UInt32 val = res & (((UInt32)1 << numBits) - 1);
+    res >>= numBits;
+    return val;
+  }
+  UInt32 GetLen(UInt32 &res) 
+  { 
+    UInt32 len = GetVal(res, 2);
+    return GetVal(res, 1 + len);
+  }
+  void Generate()
+  {
+    UInt32 pos = 0;
+    UInt32 rep0 = 1;
+    while (pos < BufferSize)
+    {
+      UInt32 res = RG->GetRnd();
+      res >>= 1;
+      if (GetVal(res, 1) == 0 || pos < 1024)
+        Buffer[pos++] = (Byte)(res & 0xFF);
+      else
+      {
+        UInt32 len;
+        len = 1 + GetLen(res);
+        if (GetVal(res, 3) != 0)
+        {
+          len += GetLen(res);
+          do
+          {
+            UInt32 ppp = GetVal(res, 5) + 6;
+            res = RG->GetRnd();
+            if (ppp > 30)
+              continue;
+            rep0 = /* (1 << ppp) +*/  GetVal(res, ppp);
+            res = RG->GetRnd();
+          }
+          while (rep0 >= pos);
+          rep0++;
+        }
+
+        for (UInt32 i = 0; i < len && pos < BufferSize; i++, pos++)
+          Buffer[pos] = Buffer[pos - rep0];
+      }
+    }
+  }
+};
+
+
+class CBenchmarkInStream: 
+  public ISequentialInStream,
+  public CMyUnknownImp
+{
+  const Byte *Data;
+  size_t Pos;
+  size_t Size;
+public:
+  MY_UNKNOWN_IMP
+  void Init(const Byte *data, size_t size)
+  {
+    Data = data;
+    Size = size;
+    Pos = 0;
+  }
+  STDMETHOD(Read)(void *data, UInt32 size, UInt32 *processedSize);
+};
+
+STDMETHODIMP CBenchmarkInStream::Read(void *data, UInt32 size, UInt32 *processedSize)
+{
+  size_t remain = Size - Pos;
+  UInt32 kMaxBlockSize = (1 << 20);
+  if (size > kMaxBlockSize)
+    size = kMaxBlockSize;
+  if (size > remain)
+    size = (UInt32)remain;
+  for (UInt32 i = 0; i < size; i++)
+    ((Byte *)data)[i] = Data[Pos + i];
+  Pos += size;
+  if(processedSize != NULL)
+    *processedSize = size;
+  return S_OK;
+}
+  
+class CBenchmarkOutStream: 
+  public ISequentialOutStream,
+  public CBenchBuffer,
+  public CMyUnknownImp
+{
+  // bool _overflow;
+public:
+  UInt32 Pos;
+  // CBenchmarkOutStream(): _overflow(false) {} 
+  void Init() 
+  {
+    // _overflow = false;
+    Pos = 0;
+  }
+  MY_UNKNOWN_IMP
+  STDMETHOD(Write)(const void *data, UInt32 size, UInt32 *processedSize);
+};
+
+STDMETHODIMP CBenchmarkOutStream::Write(const void *data, UInt32 size, UInt32 *processedSize)
+{
+  size_t curSize = BufferSize - Pos;
+  if (curSize > size)
+    curSize = size;
+  memcpy(Buffer + Pos, data, curSize);
+  Pos += (UInt32)curSize;
+  if(processedSize != NULL)
+    *processedSize = (UInt32)curSize;
+  if (curSize != size)
+  {
+    // _overflow = true;
+    return E_FAIL;
+  }
+  return S_OK;
+}
+  
+class CCrcOutStream: 
+  public ISequentialOutStream,
+  public CMyUnknownImp
+{
+public:
+  UInt32 Crc;
+  MY_UNKNOWN_IMP
+  void Init() { Crc = CRC_INIT_VAL; }
+  STDMETHOD(Write)(const void *data, UInt32 size, UInt32 *processedSize);
+};
+
+STDMETHODIMP CCrcOutStream::Write(const void *data, UInt32 size, UInt32 *processedSize)
+{
+  Crc = CrcUpdate(Crc, data, size);
+  if (processedSize != NULL)
+    *processedSize = size;
+  return S_OK;
+}
+  
+static UInt64 GetTimeCount()
+{
+  #ifdef USE_POSIX_TIME
+  #ifdef USE_POSIX_TIME2
+  timeval v;
+  if (gettimeofday(&v, 0) == 0)
+    return (UInt64)(v.tv_sec) * 1000000 + v.tv_usec;
+  return (UInt64)time(NULL) * 1000000;
+  #else
+  return time(NULL);
+  #endif
+  #else
+  /*
+  LARGE_INTEGER value;
+  if (::QueryPerformanceCounter(&value))
+    return value.QuadPart;
+  */
+  return GetTickCount();
+  #endif 
+}
+
+static UInt64 GetFreq()
+{
+  #ifdef USE_POSIX_TIME
+  #ifdef USE_POSIX_TIME2
+  return 1000000;
+  #else
+  return 1;
+  #endif 
+  #else
+  /*
+  LARGE_INTEGER value;
+  if (::QueryPerformanceFrequency(&value))
+    return value.QuadPart;
+  */
+  return 1000;
+  #endif 
+}
+
+#ifndef USE_POSIX_TIME
+static inline UInt64 GetTime64(const FILETIME &t) { return ((UInt64)t.dwHighDateTime << 32) | t.dwLowDateTime; }
+#endif
+static UInt64 GetUserTime()
+{
+  #ifdef USE_POSIX_TIME
+  return clock();
+  #else
+  FILETIME creationTime, exitTime, kernelTime, userTime;
+  if (::GetProcessTimes(::GetCurrentProcess(), &creationTime, &exitTime, &kernelTime, &userTime) != 0)
+    return GetTime64(userTime) + GetTime64(kernelTime);
+  return (UInt64)GetTickCount() * 10000;
+  #endif 
+}
+
+static UInt64 GetUserFreq()
+{
+  #ifdef USE_POSIX_TIME
+  return CLOCKS_PER_SEC;
+  #else
+  return 10000000;
+  #endif 
+}
+
+class CBenchProgressStatus
+{
+  #ifdef BENCH_MT
+  NWindows::NSynchronization::CCriticalSection CS;  
+  #endif
+public:
+  HRESULT Res;
+  bool EncodeMode;
+  void SetResult(HRESULT res) 
+  {
+    #ifdef BENCH_MT
+    NWindows::NSynchronization::CCriticalSectionLock lock(CS);
+    #endif
+    Res = res;
+  }
+  HRESULT GetResult()
+  {
+    #ifdef BENCH_MT
+    NWindows::NSynchronization::CCriticalSectionLock lock(CS);
+    #endif
+    return Res;
+  }
+};
+
+class CBenchProgressInfo:
+  public ICompressProgressInfo,
+  public CMyUnknownImp
+{
+public:
+  CBenchProgressStatus *Status;
+  CBenchInfo BenchInfo;
+  HRESULT Res;
+  IBenchCallback *callback;
+  CBenchProgressInfo(): callback(0) {}
+  MY_UNKNOWN_IMP
+  STDMETHOD(SetRatioInfo)(const UInt64 *inSize, const UInt64 *outSize);
+};
+
+void SetStartTime(CBenchInfo &bi)
+{
+  bi.GlobalFreq = GetFreq();
+  bi.UserFreq = GetUserFreq();
+  bi.GlobalTime = ::GetTimeCount();
+  bi.UserTime = ::GetUserTime();
+}
+
+void SetFinishTime(const CBenchInfo &biStart, CBenchInfo &dest)
+{
+  dest.GlobalFreq = GetFreq();
+  dest.UserFreq = GetUserFreq();
+  dest.GlobalTime = ::GetTimeCount() - biStart.GlobalTime;
+  dest.UserTime = ::GetUserTime() - biStart.UserTime;
+}
+
+STDMETHODIMP CBenchProgressInfo::SetRatioInfo(const UInt64 *inSize, const UInt64 *outSize)
+{
+  HRESULT res = Status->GetResult();
+  if (res != S_OK)
+    return res;
+  if (!callback)
+    return res;
+  CBenchInfo info = BenchInfo;
+  SetFinishTime(BenchInfo, info);
+  if (Status->EncodeMode)
+  {
+    info.UnpackSize = *inSize;
+    info.PackSize = *outSize;
+    res = callback->SetEncodeResult(info, false);
+  }
+  else
+  {
+    info.PackSize = BenchInfo.PackSize + *inSize;
+    info.UnpackSize = BenchInfo.UnpackSize + *outSize;
+    res = callback->SetDecodeResult(info, false);
+  }
+  if (res != S_OK)
+    Status->SetResult(res);
+  return res;
+}
+
+static const int kSubBits = 8;
+
+static UInt32 GetLogSize(UInt32 size)
+{
+  for (int i = kSubBits; i < 32; i++)
+    for (UInt32 j = 0; j < (1 << kSubBits); j++)
+      if (size <= (((UInt32)1) << i) + (j << (i - kSubBits)))
+        return (i << kSubBits) + j;
+  return (32 << kSubBits);
+}
+
+static void NormalizeVals(UInt64 &v1, UInt64 &v2)
+{
+  while (v1 > 1000000)
+  {
+    v1 >>= 1;
+    v2 >>= 1;
+  }
+}
+
+UInt64 GetUsage(const CBenchInfo &info)
+{
+  UInt64 userTime = info.UserTime;
+  UInt64 userFreq = info.UserFreq;
+  UInt64 globalTime = info.GlobalTime;
+  UInt64 globalFreq = info.GlobalFreq;
+  NormalizeVals(userTime, userFreq);
+  NormalizeVals(globalFreq, globalTime);
+  if (userFreq == 0)
+    userFreq = 1;
+  if (globalTime == 0)
+    globalTime = 1;
+  return userTime * globalFreq * 1000000 / userFreq / globalTime;
+}
+
+UInt64 GetRatingPerUsage(const CBenchInfo &info, UInt64 rating)
+{
+  UInt64 userTime = info.UserTime;
+  UInt64 userFreq = info.UserFreq;
+  UInt64 globalTime = info.GlobalTime;
+  UInt64 globalFreq = info.GlobalFreq;
+  NormalizeVals(userFreq, userTime);
+  NormalizeVals(globalTime, globalFreq);
+  if (globalFreq == 0)
+    globalFreq = 1;
+  if (userTime == 0)
+    userTime = 1;
+  return userFreq * globalTime / globalFreq *  rating / userTime;
+}
+
+static UInt64 MyMultDiv64(UInt64 value, UInt64 elapsedTime, UInt64 freq)
+{
+  UInt64 elTime = elapsedTime;
+  NormalizeVals(freq, elTime);
+  if (elTime == 0)
+    elTime = 1;
+  return value * freq / elTime;
+}
+
+UInt64 GetCompressRating(UInt32 dictionarySize, UInt64 elapsedTime, UInt64 freq, UInt64 size)
+{
+  UInt64 t = GetLogSize(dictionarySize) - (kBenchMinDicLogSize << kSubBits);
+  // UInt64 numCommandsForOne = 1000 + ((t * t * 7) >> (2 * kSubBits)); // AMD K8
+  UInt64 numCommandsForOne = 870 + ((t * t * 5) >> (2 * kSubBits)); // Intel Core2
+
+  UInt64 numCommands = (UInt64)(size) * numCommandsForOne;
+  return MyMultDiv64(numCommands, elapsedTime, freq);
+}
+
+UInt64 GetDecompressRating(UInt64 elapsedTime, UInt64 freq, UInt64 outSize, UInt64 inSize, UInt32 numIterations)
+{
+  // UInt64 numCommands = (inSize * 216 + outSize * 14) * numIterations; // AMD K8
+  UInt64 numCommands = (inSize * 220 + outSize * 8) * numIterations; // Intel Core2
+  return MyMultDiv64(numCommands, elapsedTime, freq);
+}
+
+#ifdef EXTERNAL_LZMA
+typedef UInt32 (WINAPI * CreateObjectPointer)(const GUID *clsID, 
+    const GUID *interfaceID, void **outObject);
+#endif
+
+struct CEncoderInfo;
+
+struct CEncoderInfo
+{
+  #ifdef BENCH_MT
+  NWindows::CThread thread[2];
+  #endif
+  CMyComPtr<ICompressCoder> encoder;
+  CBenchProgressInfo *progressInfoSpec[2];
+  CMyComPtr<ICompressProgressInfo> progressInfo[2];
+  UInt32 NumIterations;
+  #ifdef USE_ALLOCA
+  size_t AllocaSize;
+  #endif
+
+  struct CDecoderInfo
+  {
+    CEncoderInfo *Encoder;
+    UInt32 DecoderIndex;
+    #ifdef USE_ALLOCA
+    size_t AllocaSize;
+    #endif
+    bool CallbackMode;
+  };
+  CDecoderInfo decodersInfo[2];
+
+  CMyComPtr<ICompressCoder> decoders[2];
+  HRESULT Results[2];
+  CBenchmarkOutStream *outStreamSpec;
+  CMyComPtr<ISequentialOutStream> outStream;
+  IBenchCallback *callback;
+  UInt32 crc;
+  UInt32 kBufferSize;
+  UInt32 compressedSize;
+  CBenchRandomGenerator rg;
+  CBenchmarkOutStream *propStreamSpec;
+  CMyComPtr<ISequentialOutStream> propStream;
+  HRESULT Init(UInt32 dictionarySize, UInt32 numThreads, CBaseRandomGenerator *rg);
+  HRESULT Encode();
+  HRESULT Decode(UInt32 decoderIndex);
+
+  CEncoderInfo(): outStreamSpec(0), callback(0), propStreamSpec(0) {}
+
+  #ifdef BENCH_MT
+  static THREAD_FUNC_DECL EncodeThreadFunction(void *param)
+  {
+    CEncoderInfo *encoder = (CEncoderInfo *)param;
+    #ifdef USE_ALLOCA
+    alloca(encoder->AllocaSize);
+    #endif
+    HRESULT res = encoder->Encode();
+    encoder->Results[0] = res;
+    if (res != S_OK)
+      encoder->progressInfoSpec[0]->Status->SetResult(res);
+
+    return 0;
+  }
+  static THREAD_FUNC_DECL DecodeThreadFunction(void *param)
+  {
+    CDecoderInfo *decoder = (CDecoderInfo *)param;
+    #ifdef USE_ALLOCA
+    alloca(decoder->AllocaSize);
+    #endif
+    CEncoderInfo *encoder = decoder->Encoder;
+    encoder->Results[decoder->DecoderIndex] = encoder->Decode(decoder->DecoderIndex);
+    return 0;
+  }
+
+  HRESULT CreateEncoderThread()
+  {
+    return thread[0].Create(EncodeThreadFunction, this);
+  }
+
+  HRESULT CreateDecoderThread(int index, bool callbackMode
+      #ifdef USE_ALLOCA
+      , size_t allocaSize
+      #endif
+      )
+  {
+    CDecoderInfo &decoder = decodersInfo[index];
+    decoder.DecoderIndex = index;
+    decoder.Encoder = this;
+    #ifdef USE_ALLOCA
+    decoder.AllocaSize = allocaSize;
+    #endif
+    decoder.CallbackMode = callbackMode;
+    return thread[index].Create(DecodeThreadFunction, &decoder);
+  }
+  #endif
+};
+
+HRESULT CEncoderInfo::Init(UInt32 dictionarySize, UInt32 numThreads, CBaseRandomGenerator *rgLoc)
+{
+  rg.Set(rgLoc);
+  kBufferSize = dictionarySize + kAdditionalSize;
+  UInt32 kCompressedBufferSize = (kBufferSize / 2) + kCompressedAdditionalSize;
+  if (!rg.Alloc(kBufferSize))
+    return E_OUTOFMEMORY;
+  rg.Generate();
+  crc = CrcCalc(rg.Buffer, rg.BufferSize);
+
+  outStreamSpec = new CBenchmarkOutStream;
+  if (!outStreamSpec->Alloc(kCompressedBufferSize))
+    return E_OUTOFMEMORY;
+
+  outStream = outStreamSpec;
+
+  propStreamSpec = 0;
+  if (!propStream)
+  {
+    propStreamSpec = new CBenchmarkOutStream;
+    propStream = propStreamSpec;
+  }
+  if (!propStreamSpec->Alloc(kMaxLzmaPropSize))
+    return E_OUTOFMEMORY;
+  propStreamSpec->Init();
+  
+  PROPID propIDs[] = 
+  { 
+    NCoderPropID::kDictionarySize, 
+    NCoderPropID::kMultiThread
+  };
+  const int kNumProps = sizeof(propIDs) / sizeof(propIDs[0]);
+  PROPVARIANT properties[kNumProps];
+  properties[0].vt = VT_UI4;
+  properties[0].ulVal = (UInt32)dictionarySize;
+
+  properties[1].vt = VT_BOOL;
+  properties[1].boolVal = (numThreads > 1) ? VARIANT_TRUE : VARIANT_FALSE;
+
+  {
+    CMyComPtr<ICompressSetCoderProperties> setCoderProperties;
+    RINOK(encoder.QueryInterface(IID_ICompressSetCoderProperties, &setCoderProperties));
+    if (!setCoderProperties)
+      return E_FAIL;
+    RINOK(setCoderProperties->SetCoderProperties(propIDs, properties, kNumProps));
+
+    CMyComPtr<ICompressWriteCoderProperties> writeCoderProperties;
+    encoder.QueryInterface(IID_ICompressWriteCoderProperties, &writeCoderProperties);
+    if (writeCoderProperties)
+    {
+      RINOK(writeCoderProperties->WriteCoderProperties(propStream));
+    }
+  }
+  return S_OK;
+}
+
+HRESULT CEncoderInfo::Encode()
+{
+  CBenchmarkInStream *inStreamSpec = new CBenchmarkInStream;
+  CMyComPtr<ISequentialInStream> inStream = inStreamSpec;
+  inStreamSpec->Init(rg.Buffer, rg.BufferSize);
+  outStreamSpec->Init();
+
+  RINOK(encoder->Code(inStream, outStream, 0, 0, progressInfo[0]));
+  compressedSize = outStreamSpec->Pos;
+  encoder.Release();
+  return S_OK;
+}
+
+HRESULT CEncoderInfo::Decode(UInt32 decoderIndex)
+{
+  CBenchmarkInStream *inStreamSpec = new CBenchmarkInStream;
+  CMyComPtr<ISequentialInStream> inStream = inStreamSpec;
+  CMyComPtr<ICompressCoder> &decoder = decoders[decoderIndex];
+
+  CMyComPtr<ICompressSetDecoderProperties2> compressSetDecoderProperties;
+  decoder.QueryInterface(IID_ICompressSetDecoderProperties2, &compressSetDecoderProperties);
+  if (!compressSetDecoderProperties)
+    return E_FAIL;
+
+  CCrcOutStream *crcOutStreamSpec = new CCrcOutStream;
+  CMyComPtr<ISequentialOutStream> crcOutStream = crcOutStreamSpec;
+    
+  CBenchProgressInfo *pi = progressInfoSpec[decoderIndex];
+  pi->BenchInfo.UnpackSize = 0;
+  pi->BenchInfo.PackSize = 0;
+
+  for (UInt32 j = 0; j < NumIterations; j++)
+  {
+    inStreamSpec->Init(outStreamSpec->Buffer, compressedSize);
+    crcOutStreamSpec->Init();
+    
+    RINOK(compressSetDecoderProperties->SetDecoderProperties2(propStreamSpec->Buffer, propStreamSpec->Pos));
+    UInt64 outSize = kBufferSize;
+    RINOK(decoder->Code(inStream, crcOutStream, 0, &outSize, progressInfo[decoderIndex]));
+    if (CRC_GET_DIGEST(crcOutStreamSpec->Crc) != crc)
+      return S_FALSE;
+    pi->BenchInfo.UnpackSize += kBufferSize;
+    pi->BenchInfo.PackSize += compressedSize;
+  }
+  decoder.Release();
+  return S_OK;
+}
+
+static const UInt32 kNumThreadsMax = (1 << 16);
+
+struct CBenchEncoders
+{
+  CEncoderInfo *encoders;
+  CBenchEncoders(UInt32 num): encoders(0) { encoders = new CEncoderInfo[num]; }
+  ~CBenchEncoders() { delete []encoders; }
+};
+
+HRESULT LzmaBench(
+  #ifdef EXTERNAL_LZMA
+  CCodecs *codecs,
+  #endif
+  UInt32 numThreads, UInt32 dictionarySize, IBenchCallback *callback)
+{
+  UInt32 numEncoderThreads = 
+    #ifdef BENCH_MT
+    (numThreads > 1 ? numThreads / 2 : 1);
+    #else
+    1;
+    #endif
+  UInt32 numSubDecoderThreads = 
+    #ifdef BENCH_MT
+    (numThreads > 1 ? 2 : 1);
+    #else
+    1;
+    #endif
+  if (dictionarySize < (1 << kBenchMinDicLogSize) || numThreads < 1 || numEncoderThreads > kNumThreadsMax)
+  {
+    return E_INVALIDARG;
+  }
+
+  CBenchEncoders encodersSpec(numEncoderThreads);
+  CEncoderInfo *encoders = encodersSpec.encoders;
+
+  #ifdef EXTERNAL_LZMA
+  UString name = L"LZMA";
+  #endif
+
+  UInt32 i;
+  for (i = 0; i < numEncoderThreads; i++)
+  {
+    CEncoderInfo &encoder = encoders[i];
+    encoder.callback = (i == 0) ? callback : 0;
+
+    #ifdef EXTERNAL_LZMA
+    RINOK(codecs->CreateCoder(name, true, encoder.encoder));
+    #else
+    encoder.encoder = new NCompress::NLZMA::CEncoder;
+    #endif
+    for (UInt32 j = 0; j < numSubDecoderThreads; j++)
+    {
+      #ifdef EXTERNAL_LZMA
+      RINOK(codecs->CreateCoder(name, false, encoder.decoders[j]));
+      #else
+      encoder.decoders[j] = new NCompress::NLZMA::CDecoder;
+      #endif
+    }
+  }
+
+  CBaseRandomGenerator rg;
+  rg.Init();
+  for (i = 0; i < numEncoderThreads; i++)
+  {
+    RINOK(encoders[i].Init(dictionarySize, numThreads, &rg));
+  }
+
+  CBenchProgressStatus status;
+  status.Res = S_OK;
+  status.EncodeMode = true;
+
+  for (i = 0; i < numEncoderThreads; i++)
+  {
+    CEncoderInfo &encoder = encoders[i];
+    for (int j = 0; j < 2; j++)
+    {
+      encoder.progressInfo[j] = encoder.progressInfoSpec[j] = new CBenchProgressInfo;
+      encoder.progressInfoSpec[j]->Status = &status;
+    }
+    if (i == 0)
+    {
+      encoder.progressInfoSpec[0]->callback = callback;
+      encoder.progressInfoSpec[0]->BenchInfo.NumIterations = numEncoderThreads;
+      SetStartTime(encoder.progressInfoSpec[0]->BenchInfo);
+    }
+
+    #ifdef BENCH_MT
+    if (numEncoderThreads > 1)
+    {
+      #ifdef USE_ALLOCA
+      encoder.AllocaSize = (i * 16 * 21) & 0x7FF;
+      #endif
+      RINOK(encoder.CreateEncoderThread())
+    }
+    else
+    #endif
+    {
+      RINOK(encoder.Encode());
+    }
+  }
+  #ifdef BENCH_MT
+  if (numEncoderThreads > 1)
+    for (i = 0; i < numEncoderThreads; i++)
+      encoders[i].thread[0].Wait();
+  #endif
+
+  RINOK(status.Res);
+
+  CBenchInfo info;
+
+  SetFinishTime(encoders[0].progressInfoSpec[0]->BenchInfo, info);
+  info.UnpackSize = 0;
+  info.PackSize = 0;
+  info.NumIterations = 1; // progressInfoSpec->NumIterations;
+  for (i = 0; i < numEncoderThreads; i++)
+  {
+    CEncoderInfo &encoder = encoders[i];
+    info.UnpackSize += encoder.kBufferSize;
+    info.PackSize += encoder.compressedSize;
+  }
+  RINOK(callback->SetEncodeResult(info, true));
+
+
+  status.Res = S_OK;
+  status.EncodeMode = false;
+
+  UInt32 numDecoderThreads = numEncoderThreads * numSubDecoderThreads;
+  for (i = 0; i < numEncoderThreads; i++)
+  {
+    CEncoderInfo &encoder = encoders[i];
+    encoder.NumIterations = 2 + kUncompressMinBlockSize / encoder.kBufferSize;
+
+    if (i == 0)
+    {
+      encoder.progressInfoSpec[0]->callback = callback;
+      encoder.progressInfoSpec[0]->BenchInfo.NumIterations = numDecoderThreads;
+      SetStartTime(encoder.progressInfoSpec[0]->BenchInfo);
+    }
+
+    #ifdef BENCH_MT
+    if (numDecoderThreads > 1)
+    {
+      for (UInt32 j = 0; j < numSubDecoderThreads; j++)
+      {
+        size_t allocaSize = ((i * numSubDecoderThreads + j) * 16 * 21) & 0x7FF;
+        HRESULT res = encoder.CreateDecoderThread(j, (i == 0 && j == 0)
+            #ifdef USE_ALLOCA
+            , allocaSize
+            #endif
+            );
+        RINOK(res);
+      }
+    }
+    else
+    #endif
+    {
+      RINOK(encoder.Decode(0));
+    }
+  }
+  #ifdef BENCH_MT
+  HRESULT res = S_OK;
+  if (numDecoderThreads > 1)
+    for (i = 0; i < numEncoderThreads; i++)
+      for (UInt32 j = 0; j < numSubDecoderThreads; j++)
+      {
+        CEncoderInfo &encoder = encoders[i];
+        encoder.thread[j].Wait();
+        if (encoder.Results[j] != S_OK)
+          res = encoder.Results[j];
+      }
+  RINOK(res);
+  #endif
+  RINOK(status.Res);
+  SetFinishTime(encoders[0].progressInfoSpec[0]->BenchInfo, info);
+  info.UnpackSize = 0;
+  info.PackSize = 0;
+  info.NumIterations = numSubDecoderThreads * encoders[0].NumIterations;
+  for (i = 0; i < numEncoderThreads; i++)
+  {
+    CEncoderInfo &encoder = encoders[i];
+    info.UnpackSize += encoder.kBufferSize;
+    info.PackSize += encoder.compressedSize;
+  }
+  RINOK(callback->SetDecodeResult(info, false));
+  RINOK(callback->SetDecodeResult(info, true));
+  return S_OK;
+}
+
+
+inline UInt64 GetLZMAUsage(bool multiThread, UInt32 dictionary)
+{ 
+  UInt32 hs = dictionary - 1;
+  hs |= (hs >> 1);
+  hs |= (hs >> 2);
+  hs |= (hs >> 4);
+  hs |= (hs >> 8);
+  hs >>= 1;
+  hs |= 0xFFFF;
+  if (hs > (1 << 24))
+    hs >>= 1;
+  hs++;
+  return ((hs + (1 << 16)) + (UInt64)dictionary * 2) * 4 + (UInt64)dictionary * 3 / 2 + 
+      (1 << 20) + (multiThread ? (6 << 20) : 0);
+}
+
+UInt64 GetBenchMemoryUsage(UInt32 numThreads, UInt32 dictionary)
+{
+  const UInt32 kBufferSize = dictionary;
+  const UInt32 kCompressedBufferSize = (kBufferSize / 2);
+  UInt32 numSubThreads = (numThreads > 1) ? 2 : 1;
+  UInt32 numBigThreads = numThreads / numSubThreads;
+  return (kBufferSize + kCompressedBufferSize +
+    GetLZMAUsage((numThreads > 1), dictionary) + (2 << 20)) * numBigThreads;
+}
+
+static bool CrcBig(const void *data, UInt32 size, UInt32 numCycles, UInt32 crcBase)
+{
+  for (UInt32 i = 0; i < numCycles; i++)
+    if (CrcCalc(data, size) != crcBase)
+      return false;
+  return true;
+}
+
+#ifdef BENCH_MT
+struct CCrcInfo
+{
+  NWindows::CThread Thread;
+  const Byte *Data;
+  UInt32 Size;
+  UInt32 NumCycles;
+  UInt32 Crc;
+  bool Res;
+  void Wait()
+  {
+    Thread.Wait();
+    Thread.Close();
+  }
+};
+
+static THREAD_FUNC_DECL CrcThreadFunction(void *param)
+{
+  CCrcInfo *p = (CCrcInfo *)param;
+  p->Res = CrcBig(p->Data, p->Size, p->NumCycles, p->Crc);
+  return 0;
+}
+
+struct CCrcThreads
+{
+  UInt32 NumThreads;
+  CCrcInfo *Items;
+  CCrcThreads(): Items(0), NumThreads(0) {}
+  void WaitAll()
+  {
+    for (UInt32 i = 0; i < NumThreads; i++)
+      Items[i].Wait();
+    NumThreads = 0;
+  }
+  ~CCrcThreads() 
+  { 
+    WaitAll();
+    delete []Items; 
+  }
+};
+#endif
+
+static UInt32 CrcCalc1(const Byte *buf, UInt32 size)
+{
+  UInt32 crc = CRC_INIT_VAL;;
+  for (UInt32 i = 0; i < size; i++)
+    crc = CRC_UPDATE_BYTE(crc, buf[i]);
+  return CRC_GET_DIGEST(crc);
+}
+
+static void RandGen(Byte *buf, UInt32 size, CBaseRandomGenerator &RG)
+{
+  for (UInt32 i = 0; i < size; i++)
+    buf[i] = (Byte)RG.GetRnd();
+}
+
+static UInt32 RandGenCrc(Byte *buf, UInt32 size, CBaseRandomGenerator &RG)
+{
+  RandGen(buf, size, RG);
+  return CrcCalc1(buf, size);
+}
+
+bool CrcInternalTest()
+{
+  CBenchBuffer buffer;
+  const UInt32 kBufferSize0 = (1 << 8);
+  const UInt32 kBufferSize1 = (1 << 10);
+  const UInt32 kCheckSize = (1 << 5);
+  if (!buffer.Alloc(kBufferSize0 + kBufferSize1))
+    return false;
+  Byte *buf = buffer.Buffer;
+  UInt32 i;
+  for (i = 0; i < kBufferSize0; i++)
+    buf[i] = (Byte)i;
+  UInt32 crc1 = CrcCalc1(buf, kBufferSize0);
+  if (crc1 != 0x29058C73)
+    return false;
+  CBaseRandomGenerator RG;
+  RandGen(buf + kBufferSize0, kBufferSize1, RG);
+  for (i = 0; i < kBufferSize0 + kBufferSize1 - kCheckSize; i++)
+    for (UInt32 j = 0; j < kCheckSize; j++)
+      if (CrcCalc1(buf + i, j) != CrcCalc(buf + i, j))
+        return false;
+  return true;
+}
+
+HRESULT CrcBench(UInt32 numThreads, UInt32 bufferSize, UInt64 &speed)
+{
+  if (numThreads == 0)
+    numThreads = 1;
+
+  CBenchBuffer buffer;
+  size_t totalSize = (size_t)bufferSize * numThreads;
+  if (totalSize / numThreads != bufferSize)
+    return E_OUTOFMEMORY;
+  if (!buffer.Alloc(totalSize))
+    return E_OUTOFMEMORY;
+
+  Byte *buf = buffer.Buffer;
+  CBaseRandomGenerator RG;
+  UInt32 numCycles = ((UInt32)1 << 30) / ((bufferSize >> 2) + 1) + 1;
+
+  UInt64 timeVal;
+  #ifdef BENCH_MT
+  CCrcThreads threads;
+  if (numThreads > 1)
+  {
+    threads.Items = new CCrcInfo[numThreads];
+    UInt32 i;
+    for (i = 0; i < numThreads; i++)
+    {
+      CCrcInfo &info = threads.Items[i];
+      Byte *data = buf + (size_t)bufferSize * i;
+      info.Data = data;
+      info.NumCycles = numCycles;
+      info.Size = bufferSize;
+      info.Crc = RandGenCrc(data, bufferSize, RG);
+    }
+    timeVal = GetTimeCount();
+    for (i = 0; i < numThreads; i++)
+    {
+      CCrcInfo &info = threads.Items[i];
+      RINOK(info.Thread.Create(CrcThreadFunction, &info));
+      threads.NumThreads++;
+    }
+    threads.WaitAll();
+    for (i = 0; i < numThreads; i++)
+      if (!threads.Items[i].Res)
+        return S_FALSE;
+  }
+  else
+  #endif
+  {
+    UInt32 crc = RandGenCrc(buf, bufferSize, RG);
+    timeVal = GetTimeCount();
+    if (!CrcBig(buf, bufferSize, numCycles, crc))
+      return S_FALSE;
+  }
+  timeVal = GetTimeCount() - timeVal;
+  if (timeVal == 0)
+    timeVal = 1;
+
+  UInt64 size = (UInt64)numCycles * totalSize;
+  speed = MyMultDiv64(size, timeVal, GetFreq());
+  return S_OK;
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/misc/libphysfs/lzma/CPP/7zip/Compress/LZMA_Alone/LzmaBench.h	Mon Apr 10 12:06:43 2017 -0400
@@ -0,0 +1,48 @@
+// LzmaBench.h
+
+#ifndef __LZMABENCH_H
+#define __LZMABENCH_H
+
+#include <stdio.h>
+#include "../../../Common/Types.h"
+#ifdef EXTERNAL_LZMA
+#include "../../UI/Common/LoadCodecs.h"
+#endif
+
+struct CBenchInfo
+{
+  UInt64 GlobalTime;
+  UInt64 GlobalFreq; 
+  UInt64 UserTime; 
+  UInt64 UserFreq;
+  UInt64 UnpackSize;
+  UInt64 PackSize;
+  UInt32 NumIterations;
+  CBenchInfo(): NumIterations(0) {}
+};
+
+struct IBenchCallback
+{
+  virtual HRESULT SetEncodeResult(const CBenchInfo &info, bool final) = 0;
+  virtual HRESULT SetDecodeResult(const CBenchInfo &info, bool final) = 0;
+};
+
+UInt64 GetUsage(const CBenchInfo &benchOnfo);
+UInt64 GetRatingPerUsage(const CBenchInfo &info, UInt64 rating);
+UInt64 GetCompressRating(UInt32 dictionarySize, UInt64 elapsedTime, UInt64 freq, UInt64 size);
+UInt64 GetDecompressRating(UInt64 elapsedTime, UInt64 freq, UInt64 outSize, UInt64 inSize, UInt32 numIterations);
+
+HRESULT LzmaBench(
+  #ifdef EXTERNAL_LZMA
+  CCodecs *codecs,
+  #endif
+  UInt32 numThreads, UInt32 dictionarySize, IBenchCallback *callback);
+
+const int kBenchMinDicLogSize = 18;
+
+UInt64 GetBenchMemoryUsage(UInt32 numThreads, UInt32 dictionary);
+
+bool CrcInternalTest();
+HRESULT CrcBench(UInt32 numThreads, UInt32 bufferSize, UInt64 &speed);
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/misc/libphysfs/lzma/CPP/7zip/Compress/LZMA_Alone/LzmaBenchCon.cpp	Mon Apr 10 12:06:43 2017 -0400
@@ -0,0 +1,311 @@
+// LzmaBenchCon.cpp
+
+#include "StdAfx.h"
+
+#include <stdio.h>
+
+#include "LzmaBench.h"
+#include "LzmaBenchCon.h"
+#include "../../../Common/IntToString.h"
+
+#if defined(BENCH_MT) || defined(_WIN32)
+#include "../../../Windows/System.h"
+#endif
+
+#ifdef BREAK_HANDLER
+#include "../../UI/Console/ConsoleClose.h"
+#endif
+#include "../../../Common/MyCom.h"
+
+struct CTotalBenchRes
+{
+  UInt64 NumIterations;
+  UInt64 Rating;
+  UInt64 Usage;
+  UInt64 RPU;
+  void Init() { NumIterations = 0; Rating = 0; Usage = 0; RPU = 0; }
+  void Normalize() 
+  { 
+    if (NumIterations == 0) 
+      return;
+    Rating /= NumIterations; 
+    Usage /= NumIterations; 
+    RPU /= NumIterations; 
+    NumIterations = 1;
+  }
+  void SetMid(const CTotalBenchRes &r1, const CTotalBenchRes &r2) 
+  { 
+    Rating = (r1.Rating + r2.Rating) / 2; 
+    Usage = (r1.Usage + r2.Usage) / 2;
+    RPU = (r1.RPU + r2.RPU) / 2;
+    NumIterations = (r1.NumIterations + r2.NumIterations) / 2;
+  }
+};
+
+struct CBenchCallback: public IBenchCallback
+{
+  CTotalBenchRes EncodeRes;
+  CTotalBenchRes DecodeRes;
+  FILE *f;
+  void Init() { EncodeRes.Init(); DecodeRes.Init(); }
+  void Normalize() { EncodeRes.Normalize(); DecodeRes.Normalize(); }
+  UInt32 dictionarySize;
+  HRESULT SetEncodeResult(const CBenchInfo &info, bool final);
+  HRESULT SetDecodeResult(const CBenchInfo &info, bool final);
+};
+
+static void NormalizeVals(UInt64 &v1, UInt64 &v2)
+{
+  while (v1 > 1000000)
+  {
+    v1 >>= 1;
+    v2 >>= 1;
+  }
+}
+
+static UInt64 MyMultDiv64(UInt64 value, UInt64 elapsedTime, UInt64 freq)
+{
+  UInt64 elTime = elapsedTime;
+  NormalizeVals(freq, elTime);
+  if (elTime == 0)
+    elTime = 1;
+  return value * freq / elTime;
+}
+
+static void PrintNumber(FILE *f, UInt64 value, int size)
+{
+  char s[32];
+  ConvertUInt64ToString(value, s);
+  fprintf(f, " ");
+  for (int len = (int)strlen(s); len < size; len++)
+    fprintf(f, " ");
+  fprintf(f, "%s", s);
+}
+
+static void PrintRating(FILE *f, UInt64 rating)
+{
+  PrintNumber(f, rating / 1000000, 6);
+}
+
+static void PrintResults(FILE *f, UInt64 usage, UInt64 rpu, UInt64 rating)
+{
+  PrintNumber(f, (usage + 5000) / 10000, 5);
+  PrintRating(f, rpu);
+  PrintRating(f, rating);
+}
+
+
+static void PrintResults(FILE *f, const CBenchInfo &info, UInt64 rating, CTotalBenchRes &res)
+{
+  UInt64 speed = MyMultDiv64(info.UnpackSize, info.GlobalTime, info.GlobalFreq);
+  PrintNumber(f, speed / 1024, 7);
+  UInt64 usage = GetUsage(info);
+  UInt64 rpu = GetRatingPerUsage(info, rating);
+  PrintResults(f, usage, rpu, rating);
+  res.NumIterations++;
+  res.RPU += rpu;
+  res.Rating += rating;
+  res.Usage += usage;
+}
+
+static void PrintTotals(FILE *f, const CTotalBenchRes &res)
+{
+  fprintf(f, "       ");
+  PrintResults(f, res.Usage, res.RPU, res.Rating);
+}
+
+
+HRESULT CBenchCallback::SetEncodeResult(const CBenchInfo &info, bool final)
+{
+  #ifdef BREAK_HANDLER
+  if (NConsoleClose::TestBreakSignal())
+    return E_ABORT;
+  #endif
+
+  if (final)
+  {
+    UInt64 rating = GetCompressRating(dictionarySize, info.GlobalTime, info.GlobalFreq, info.UnpackSize);
+    PrintResults(f, info, rating, EncodeRes);
+  }
+  return S_OK;
+}
+
+static const char *kSep = "  | ";
+
+
+HRESULT CBenchCallback::SetDecodeResult(const CBenchInfo &info, bool final)
+{
+  #ifdef BREAK_HANDLER
+  if (NConsoleClose::TestBreakSignal())
+    return E_ABORT;
+  #endif
+  if (final)
+  {
+    UInt64 rating = GetDecompressRating(info.GlobalTime, info.GlobalFreq, info.UnpackSize, info.PackSize, info.NumIterations);
+    fprintf(f, kSep);
+    CBenchInfo info2 = info;
+    info2.UnpackSize *= info2.NumIterations;
+    info2.PackSize *= info2.NumIterations;
+    info2.NumIterations = 1;
+    PrintResults(f, info2, rating, DecodeRes);
+  }
+  return S_OK;
+}
+
+static void PrintRequirements(FILE *f, const char *sizeString, UInt64 size, const char *threadsString, UInt32 numThreads)
+{
+  fprintf(f, "\nRAM %s ", sizeString);
+  PrintNumber(f, (size >> 20), 5);
+  fprintf(f, " MB,  # %s %3d", threadsString, (unsigned int)numThreads);
+}
+
+HRESULT LzmaBenchCon(
+  #ifdef EXTERNAL_LZMA
+  CCodecs *codecs,
+  #endif
+  FILE *f, UInt32 numIterations, UInt32 numThreads, UInt32 dictionary)
+{
+  if (!CrcInternalTest())
+    return S_FALSE;
+  #ifdef BENCH_MT
+  UInt64 ramSize = NWindows::NSystem::GetRamSize();  // 
+  UInt32 numCPUs = NWindows::NSystem::GetNumberOfProcessors();
+  PrintRequirements(f, "size: ", ramSize, "CPU hardware threads:", numCPUs);
+  if (numThreads == (UInt32)-1)
+    numThreads = numCPUs;
+  if (numThreads > 1)
+    numThreads &= ~1;
+  if (dictionary == (UInt32)-1)
+  {
+    int dicSizeLog;
+    for (dicSizeLog = 25; dicSizeLog > kBenchMinDicLogSize; dicSizeLog--)
+      if (GetBenchMemoryUsage(numThreads, ((UInt32)1 << dicSizeLog)) + (8 << 20) <= ramSize)
+        break;
+    dictionary = (1 << dicSizeLog);
+  }
+  #else
+  if (dictionary == (UInt32)-1)
+    dictionary = (1 << 22);
+  numThreads = 1;
+  #endif
+
+  PrintRequirements(f, "usage:", GetBenchMemoryUsage(numThreads, dictionary), "Benchmark threads:   ", numThreads);
+
+  CBenchCallback callback;
+  callback.Init();
+  callback.f = f;
+  
+  fprintf(f, "\n\nDict        Compressing          |        Decompressing\n   ");
+  int j;
+  for (j = 0; j < 2; j++)
+  {
+    fprintf(f, "   Speed Usage    R/U Rating");
+    if (j == 0)
+      fprintf(f, kSep);
+  }
+  fprintf(f, "\n   ");
+  for (j = 0; j < 2; j++)
+  {
+    fprintf(f, "    KB/s     %%   MIPS   MIPS");
+    if (j == 0)
+      fprintf(f, kSep);
+  }
+  fprintf(f, "\n\n");
+  for (UInt32 i = 0; i < numIterations; i++)
+  {
+    const int kStartDicLog = 22;
+    int pow = (dictionary < ((UInt32)1 << kStartDicLog)) ? kBenchMinDicLogSize : kStartDicLog;
+    while (((UInt32)1 << pow) > dictionary)
+      pow--;
+    for (; ((UInt32)1 << pow) <= dictionary; pow++)
+    {
+      fprintf(f, "%2d:", pow);
+      callback.dictionarySize = (UInt32)1 << pow;
+      HRESULT res = LzmaBench(
+        #ifdef EXTERNAL_LZMA
+        codecs,
+        #endif
+        numThreads, callback.dictionarySize, &callback);
+      fprintf(f, "\n");
+      RINOK(res);
+    }
+  }
+  callback.Normalize();
+  fprintf(f, "----------------------------------------------------------------\nAvr:");
+  PrintTotals(f, callback.EncodeRes);
+  fprintf(f, "     ");
+  PrintTotals(f, callback.DecodeRes);
+  fprintf(f, "\nTot:");
+  CTotalBenchRes midRes;
+  midRes.SetMid(callback.EncodeRes, callback.DecodeRes);
+  PrintTotals(f, midRes);
+  fprintf(f, "\n");
+  return S_OK;
+}
+
+struct CTempValues
+{
+  UInt64 *Values;
+  CTempValues(UInt32 num) { Values = new UInt64[num]; }
+  ~CTempValues() { delete []Values; }
+};
+
+HRESULT CrcBenchCon(FILE *f, UInt32 numIterations, UInt32 numThreads, UInt32 dictionary)
+{
+  if (!CrcInternalTest())
+    return S_FALSE;
+
+  #ifdef BENCH_MT
+  UInt64 ramSize = NWindows::NSystem::GetRamSize();
+  UInt32 numCPUs = NWindows::NSystem::GetNumberOfProcessors();
+  PrintRequirements(f, "size: ", ramSize, "CPU hardware threads:", numCPUs);
+  if (numThreads == (UInt32)-1)
+    numThreads = numCPUs;
+  #else
+  numThreads = 1;
+  #endif
+  if (dictionary == (UInt32)-1)
+    dictionary = (1 << 24);
+
+  CTempValues speedTotals(numThreads);
+  fprintf(f, "\n\nSize");
+  for (UInt32 ti = 0; ti < numThreads; ti++)
+  {
+    fprintf(f, " %5d", ti + 1);
+    speedTotals.Values[ti] = 0;
+  }
+  fprintf(f, "\n\n");
+
+  UInt64 numSteps = 0;
+  for (UInt32 i = 0; i < numIterations; i++)
+  {
+    for (int pow = 10; pow < 32; pow++)
+    {
+      UInt32 bufSize = (UInt32)1 << pow;
+      if (bufSize > dictionary)
+        break;
+      fprintf(f, "%2d: ", pow);
+      UInt64 speed;
+      for (UInt32 ti = 0; ti < numThreads; ti++)
+      {
+        #ifdef BREAK_HANDLER
+        if (NConsoleClose::TestBreakSignal())
+          return E_ABORT;
+        #endif
+        RINOK(CrcBench(ti + 1, bufSize, speed));
+        PrintNumber(f, (speed >> 20), 5);
+        speedTotals.Values[ti] += speed;
+      }
+      fprintf(f, "\n");
+      numSteps++;
+    }
+  }
+  if (numSteps != 0)
+  {
+    fprintf(f, "\nAvg:");
+    for (UInt32 ti = 0; ti < numThreads; ti++)
+      PrintNumber(f, ((speedTotals.Values[ti] / numSteps) >> 20), 5);
+    fprintf(f, "\n");
+  }
+  return S_OK;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/misc/libphysfs/lzma/CPP/7zip/Compress/LZMA_Alone/LzmaBenchCon.h	Mon Apr 10 12:06:43 2017 -0400
@@ -0,0 +1,20 @@
+// LzmaBenchCon.h
+
+#ifndef __LZMABENCHCON_H
+#define __LZMABENCHCON_H
+
+#include <stdio.h>
+#include "../../../Common/Types.h"
+#ifdef EXTERNAL_LZMA
+#include "../../UI/Common/LoadCodecs.h"
+#endif
+HRESULT LzmaBenchCon(
+  #ifdef EXTERNAL_LZMA
+  CCodecs *codecs,
+  #endif
+  FILE *f, UInt32 numIterations, UInt32 numThreads, UInt32 dictionary);
+
+HRESULT CrcBenchCon(FILE *f, UInt32 numIterations, UInt32 numThreads, UInt32 dictionary);
+
+#endif
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/misc/libphysfs/lzma/CPP/7zip/Compress/LZMA_Alone/LzmaRam.cpp	Mon Apr 10 12:06:43 2017 -0400
@@ -0,0 +1,226 @@
+// LzmaRam.cpp
+
+#include "StdAfx.h"
+#include "../../../Common/Types.h"
+#include "../LZMA/LZMADecoder.h"
+#include "../LZMA/LZMAEncoder.h"
+#include "LzmaRam.h"
+
+extern "C"
+{
+  #include "../../../../C/Compress/Branch/BranchX86.h"
+}
+
+class CInStreamRam: 
+  public ISequentialInStream,
+  public CMyUnknownImp
+{
+  const Byte *Data;
+  size_t Size;
+  size_t Pos;
+public:
+  MY_UNKNOWN_IMP
+  void Init(const Byte *data, size_t size)
+  {
+    Data = data;
+    Size = size;
+    Pos = 0;
+  }
+  STDMETHOD(Read)(void *data, UInt32 size, UInt32 *processedSize);
+};
+
+STDMETHODIMP CInStreamRam::Read(void *data, UInt32 size, UInt32 *processedSize)
+{
+  if (size > (Size - Pos))
+    size = (UInt32)(Size - Pos);
+  for (UInt32 i = 0; i < size; i++)
+    ((Byte *)data)[i] = Data[Pos + i];
+  Pos += size;
+  if(processedSize != NULL)
+    *processedSize = size;
+  return S_OK;
+}
+  
+class COutStreamRam: 
+  public ISequentialOutStream,
+  public CMyUnknownImp
+{
+  size_t Size;
+public:
+  Byte *Data;
+  size_t Pos;
+  bool Overflow;
+  void Init(Byte *data, size_t size)
+  {
+    Data = data;
+    Size = size;
+    Pos = 0;
+    Overflow = false;
+  }
+  void SetPos(size_t pos)
+  {
+    Overflow = false;
+    Pos = pos;
+  }
+  MY_UNKNOWN_IMP
+  HRESULT WriteByte(Byte b)
+  {
+    if (Pos >= Size)
+    {
+      Overflow = true;
+      return E_FAIL;
+    }
+    Data[Pos++] = b;
+    return S_OK;
+  }
+  STDMETHOD(Write)(const void *data, UInt32 size, UInt32 *processedSize);
+};
+
+STDMETHODIMP COutStreamRam::Write(const void *data, UInt32 size, UInt32 *processedSize)
+{
+  UInt32 i;
+  for (i = 0; i < size && Pos < Size; i++)
+    Data[Pos++] = ((const Byte *)data)[i];
+  if(processedSize != NULL)
+    *processedSize = i;
+  if (i != size)
+  {
+    Overflow = true;
+    return E_FAIL;
+  }
+  return S_OK;
+}
+  
+#define SZ_RAM_E_FAIL (1)
+#define SZ_RAM_E_OUTOFMEMORY (2)
+#define SZE_OUT_OVERFLOW (3)
+
+int LzmaRamEncode(
+    const Byte *inBuffer, size_t inSize, 
+    Byte *outBuffer, size_t outSize, size_t *outSizeProcessed, 
+    UInt32 dictionarySize, ESzFilterMode filterMode)
+{
+  #ifndef _NO_EXCEPTIONS
+  try { 
+  #endif
+
+  *outSizeProcessed = 0;
+  const size_t kIdSize = 1;
+  const size_t kLzmaPropsSize = 5;
+  const size_t kMinDestSize = kIdSize + kLzmaPropsSize + 8;
+  if (outSize < kMinDestSize)
+    return SZE_OUT_OVERFLOW;
+  NCompress::NLZMA::CEncoder *encoderSpec = new NCompress::NLZMA::CEncoder;
+  CMyComPtr<ICompressCoder> encoder = encoderSpec;
+
+  PROPID propIDs[] = 
+  { 
+    NCoderPropID::kAlgorithm,
+    NCoderPropID::kDictionarySize,  
+    NCoderPropID::kNumFastBytes,
+  };
+  const int kNumProps = sizeof(propIDs) / sizeof(propIDs[0]);
+  PROPVARIANT properties[kNumProps];
+  properties[0].vt = VT_UI4;
+  properties[1].vt = VT_UI4;
+  properties[2].vt = VT_UI4;
+  properties[0].ulVal = (UInt32)2;
+  properties[1].ulVal = (UInt32)dictionarySize;
+  properties[2].ulVal = (UInt32)64;
+
+  if (encoderSpec->SetCoderProperties(propIDs, properties, kNumProps) != S_OK)
+    return 1;
+  
+  COutStreamRam *outStreamSpec = new COutStreamRam;
+  if (outStreamSpec == 0)
+    return SZ_RAM_E_OUTOFMEMORY;
+  CMyComPtr<ISequentialOutStream> outStream = outStreamSpec;
+  CInStreamRam *inStreamSpec = new CInStreamRam;
+  if (inStreamSpec == 0)
+    return SZ_RAM_E_OUTOFMEMORY;
+  CMyComPtr<ISequentialInStream> inStream = inStreamSpec;
+
+  outStreamSpec->Init(outBuffer, outSize);
+  if (outStreamSpec->WriteByte(0) != S_OK)
+    return SZE_OUT_OVERFLOW;
+
+  if (encoderSpec->WriteCoderProperties(outStream) != S_OK)
+    return SZE_OUT_OVERFLOW;
+  if (outStreamSpec->Pos != kIdSize + kLzmaPropsSize)
+    return 1;
+  
+  int i;
+  for (i = 0; i < 8; i++)
+  {
+    UInt64 t = (UInt64)(inSize);
+    if (outStreamSpec->WriteByte((Byte)((t) >> (8 * i))) != S_OK)
+      return SZE_OUT_OVERFLOW;
+  }
+
+  Byte *filteredStream = 0;
+
+  bool useFilter = (filterMode != SZ_FILTER_NO);
+  if (useFilter)
+  {
+    if (inSize != 0)
+    {
+      filteredStream = (Byte *)MyAlloc(inSize);
+      if (filteredStream == 0)
+        return SZ_RAM_E_OUTOFMEMORY;
+      memmove(filteredStream, inBuffer, inSize);
+    }
+    UInt32 x86State;
+    x86_Convert_Init(x86State);
+    x86_Convert(filteredStream, (SizeT)inSize, 0, &x86State, 1);
+  }
+  
+  size_t minSize = 0;
+  int numPasses = (filterMode == SZ_FILTER_AUTO) ? 3 : 1;
+  bool bestIsFiltered = false;
+  int mainResult = 0;
+  size_t startPos = outStreamSpec->Pos;
+  for (i = 0; i < numPasses; i++)
+  {
+    if (numPasses > 1 && i == numPasses - 1 && !bestIsFiltered)
+      break;
+    outStreamSpec->SetPos(startPos);
+    bool curModeIsFiltered = false;
+    if (useFilter && i == 0)
+      curModeIsFiltered = true;
+    if (numPasses > 1 && i == numPasses - 1)
+      curModeIsFiltered = true;
+
+    inStreamSpec->Init(curModeIsFiltered ? filteredStream : inBuffer, inSize);
+    
+    HRESULT lzmaResult = encoder->Code(inStream, outStream, 0, 0, 0);
+    
+    mainResult = 0;
+    if (lzmaResult == E_OUTOFMEMORY)
+    {
+      mainResult = SZ_RAM_E_OUTOFMEMORY;
+      break;
+    } 
+    if (i == 0 || outStreamSpec->Pos <= minSize)
+    {
+      minSize = outStreamSpec->Pos;
+      bestIsFiltered = curModeIsFiltered;
+    }
+    if (outStreamSpec->Overflow)
+      mainResult = SZE_OUT_OVERFLOW;
+    else if (lzmaResult != S_OK)
+    {
+      mainResult = SZ_RAM_E_FAIL;
+      break;
+    } 
+  }
+  *outSizeProcessed = outStreamSpec->Pos;
+  if (bestIsFiltered)
+    outBuffer[0] = 1;
+  if (useFilter)
+    MyFree(filteredStream);
+  return mainResult;
+  
+  #ifndef _NO_EXCEPTIONS
+  } catch(...) { return SZ_RAM_E_OUTOFMEMORY; }
+  #endif
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/misc/libphysfs/lzma/CPP/7zip/Compress/LZMA_Alone/LzmaRam.h	Mon Apr 10 12:06:43 2017 -0400
@@ -0,0 +1,46 @@
+// LzmaRam.h
+
+#ifndef __LzmaRam_h
+#define __LzmaRam_h
+
+#include <stdlib.h>
+#include "../../../Common/Types.h"
+
+/*
+LzmaRamEncode: BCJ + LZMA RAM->RAM compressing.
+It uses .lzma format, but it writes one additional byte to .lzma file:
+  0: - no filter
+  1: - x86(BCJ) filter.
+
+To provide best compression ratio dictionarySize mustbe >= inSize
+
+LzmaRamEncode allocates Data with MyAlloc/BigAlloc functions.
+RAM Requirements:
+  RamSize = dictionarySize * 9.5 + 6MB + FilterBlockSize 
+    FilterBlockSize = 0, if useFilter == false
+    FilterBlockSize = inSize, if useFilter == true
+
+  Return code:
+    0 - OK
+    1 - Unspecified Error
+    2 - Memory allocating error
+    3 - Output buffer OVERFLOW
+
+If you use SZ_FILTER_AUTO mode, then encoder will use 2 or 3 passes:
+  2 passes when FILTER_NO provides better compression.
+  3 passes when FILTER_YES provides better compression.
+*/
+
+enum ESzFilterMode 
+{
+  SZ_FILTER_NO,
+  SZ_FILTER_YES,
+  SZ_FILTER_AUTO
+};
+
+int LzmaRamEncode(
+    const Byte *inBuffer, size_t inSize, 
+    Byte *outBuffer, size_t outSize, size_t *outSizeProcessed, 
+    UInt32 dictionarySize, ESzFilterMode filterMode);
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/misc/libphysfs/lzma/CPP/7zip/Compress/LZMA_Alone/LzmaRamDecode.c	Mon Apr 10 12:06:43 2017 -0400
@@ -0,0 +1,78 @@
+/* LzmaRamDecode.c */
+
+#include "LzmaRamDecode.h"
+#ifdef _SZ_ONE_DIRECTORY
+#include "LzmaDecode.h"
+#include "BranchX86.h"
+#else
+#include "../../../../C/Compress/Lzma/LzmaDecode.h"
+#include "../../../../C/Compress/Branch/BranchX86.h"
+#endif
+
+#define LZMA_PROPS_SIZE 14
+#define LZMA_SIZE_OFFSET 6
+
+int LzmaRamGetUncompressedSize(
+    const unsigned char *inBuffer, 
+    size_t inSize, 
+    size_t *outSize)
+{
+  unsigned int i;
+  if (inSize < LZMA_PROPS_SIZE)
+    return 1;
+  *outSize = 0;
+  for(i = 0; i < sizeof(size_t); i++)
+    *outSize += ((size_t)inBuffer[LZMA_SIZE_OFFSET + i]) << (8 * i);
+  for(; i < 8; i++)
+    if (inBuffer[LZMA_SIZE_OFFSET + i] != 0)
+      return 1;
+  return 0;
+}
+
+#define SZE_DATA_ERROR (1)
+#define SZE_OUTOFMEMORY (2)
+
+int LzmaRamDecompress(
+    const unsigned char *inBuffer, 
+    size_t inSize,
+    unsigned char *outBuffer,
+    size_t outSize,
+    size_t *outSizeProcessed,
+    void * (*allocFunc)(size_t size), 
+    void (*freeFunc)(void *))
+{
+  CLzmaDecoderState state;  /* it's about 24 bytes structure, if int is 32-bit */
+  int result;
+  SizeT outSizeProcessedLoc;
+  SizeT inProcessed;
+  int useFilter;
+  
+  if (inSize < LZMA_PROPS_SIZE)
+    return 1;
+  useFilter = inBuffer[0];
+
+  *outSizeProcessed = 0;
+  if (useFilter > 1)
+    return 1;
+
+  if (LzmaDecodeProperties(&state.Properties, inBuffer + 1, LZMA_PROPERTIES_SIZE) != LZMA_RESULT_OK)
+    return 1;
+  state.Probs = (CProb *)allocFunc(LzmaGetNumProbs(&state.Properties) * sizeof(CProb));
+  if (state.Probs == 0)
+    return SZE_OUTOFMEMORY;
+  
+  result = LzmaDecode(&state,
+    inBuffer + LZMA_PROPS_SIZE, (SizeT)inSize - LZMA_PROPS_SIZE, &inProcessed,
+    outBuffer, (SizeT)outSize, &outSizeProcessedLoc);
+  freeFunc(state.Probs);
+  if (result != LZMA_RESULT_OK)
+    return 1;
+  *outSizeProcessed = (size_t)outSizeProcessedLoc;
+  if (useFilter == 1)
+  {
+    UInt32 x86State;
+    x86_Convert_Init(x86State);
+    x86_Convert(outBuffer, (SizeT)outSizeProcessedLoc, 0, &x86State, 0);
+  }
+  return 0;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/misc/libphysfs/lzma/CPP/7zip/Compress/LZMA_Alone/LzmaRamDecode.h	Mon Apr 10 12:06:43 2017 -0400
@@ -0,0 +1,55 @@
+/* LzmaRamDecode.h */
+
+#ifndef __LzmaRamDecode_h
+#define __LzmaRamDecode_h
+
+#include <stdlib.h>
+
+/*
+LzmaRamGetUncompressedSize:
+  In: 
+    inBuffer - input data
+    inSize   - input data size
+  Out: 
+    outSize  - uncompressed size
+  Return code:
+    0 - OK
+    1 - Error in headers
+*/
+
+int LzmaRamGetUncompressedSize(
+    const unsigned char *inBuffer, 
+    size_t inSize,
+    size_t *outSize);
+
+
+/*
+LzmaRamDecompress:
+  In: 
+    inBuffer  - input data
+    inSize    - input data size
+    outBuffer - output data
+    outSize   - output size
+    allocFunc - alloc function (can be malloc)
+    freeFunc  - free function (can be free)
+  Out: 
+    outSizeProcessed - processed size
+  Return code:
+    0 - OK
+    1 - Error in headers / data stream
+    2 - Memory allocating error
+
+Memory requirements depend from properties of LZMA stream.
+With default lzma settings it's about 16 KB.
+*/
+
+int LzmaRamDecompress(
+    const unsigned char *inBuffer, 
+    size_t inSize,
+    unsigned char *outBuffer,
+    size_t outSize,
+    size_t *outSizeProcessed,
+    void * (*allocFunc)(size_t size), 
+    void (*freeFunc)(void *));
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/misc/libphysfs/lzma/CPP/7zip/Compress/LZMA_Alone/StdAfx.cpp	Mon Apr 10 12:06:43 2017 -0400
@@ -0,0 +1,3 @@
+// StdAfx.cpp
+
+#include "StdAfx.h"
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/misc/libphysfs/lzma/CPP/7zip/Compress/LZMA_Alone/StdAfx.h	Mon Apr 10 12:06:43 2017 -0400
@@ -0,0 +1,8 @@
+// StdAfx.h
+
+#ifndef __STDAFX_H
+#define __STDAFX_H
+
+#include "../../../Common/MyWindows.h"
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/misc/libphysfs/lzma/CPP/7zip/Compress/LZMA_Alone/makefile	Mon Apr 10 12:06:43 2017 -0400
@@ -0,0 +1,136 @@
+PROG = lzma.exe
+CFLAGS = $(CFLAGS) \
+  -DCOMPRESS_MF_MT \
+  -DBENCH_MT \
+
+LIBS = $(LIBS) oleaut32.lib user32.lib
+
+!IFDEF CPU
+LIBS = $(LIBS) bufferoverflowU.lib 
+CFLAGS = $(CFLAGS) -GS- -Zc:forScope -W4 -Wp64 -DUNICODE -D_UNICODE
+!ENDIF
+
+!IFNDEF O
+!IFDEF CPU
+O=$(CPU)
+!ELSE
+O=O
+!ENDIF
+!ENDIF
+
+!IFDEF MY_STATIC_LINK
+!IFNDEF MY_SINGLE_THREAD
+CFLAGS = $(CFLAGS) -MT
+!ENDIF
+!ELSE
+CFLAGS = $(CFLAGS) -MD
+!ENDIF
+
+CFLAGS = $(CFLAGS) -nologo -EHsc -c -Fo$O/
+CFLAGS_O1 = $(CFLAGS) -O1
+CFLAGS_O2 = $(CFLAGS) -O2
+
+LFLAGS = $(LFLAGS) -nologo -OPT:NOWIN98
+
+PROGPATH = $O\$(PROG)
+
+COMPL_O1   = $(CPP) $(CFLAGS_O1) $**
+COMPL_O2   = $(CPP) $(CFLAGS_O2) $**
+COMPL      = $(CPP) $(CFLAGS_O1) $**
+
+
+LZMA_OBJS = \
+  $O\LzmaAlone.obj \
+  $O\LzmaBench.obj \
+  $O\LzmaBenchCon.obj \
+  $O\LzmaRam.obj \
+
+LZMA_OPT_OBJS = \
+  $O\LZMADecoder.obj \
+  $O\LZMAEncoder.obj \
+
+COMMON_OBJS = \
+  $O\CommandLineParser.obj \
+  $O\CRC.obj \
+  $O\IntToString.obj \
+  $O\MyString.obj \
+  $O\StringConvert.obj \
+  $O\StringToInt.obj \
+  $O\MyVector.obj
+
+WIN_OBJS = \
+  $O\System.obj
+
+7ZIP_COMMON_OBJS = \
+  $O\InBuffer.obj \
+  $O\OutBuffer.obj \
+  $O\StreamUtils.obj \
+
+LZ_OBJS = \
+  $O\LZOutWindow.obj \
+
+C_OBJS = \
+  $O\Alloc.obj \
+  $O\7zCrc.obj \
+  $O\Threads.obj \
+
+C_LZ_OBJS = \
+  $O\MatchFinder.obj \
+  $O\MatchFinderMt.obj \
+
+OBJS = \
+  $(LZMA_OBJS) \
+  $(LZMA_OPT_OBJS) \
+  $(COMMON_OBJS) \
+  $(WIN_OBJS) \
+  $(7ZIP_COMMON_OBJS) \
+  $(LZ_OBJS) \
+  $(C_OBJS) \
+  $(C_LZ_OBJS) \
+  $O\LzmaRamDecode.obj \
+  $O\LzmaDecode.obj \
+  $O\FileStreams.obj \
+  $O\FileIO.obj \
+  $O\RangeCoderBit.obj \
+  $O\BranchX86.obj \
+
+all: $(PROGPATH) 
+
+clean:
+	-del /Q $(PROGPATH) $O\*.exe $O\*.dll $O\*.obj $O\*.lib $O\*.exp $O\*.res $O\*.pch 
+
+$O:
+	if not exist "$O" mkdir "$O"
+
+$(PROGPATH): $O $(OBJS)
+	link $(LFLAGS) -out:$(PROGPATH) $(OBJS) $(LIBS)
+
+
+$(LZMA_OBJS): $(*B).cpp
+	$(COMPL)
+$(LZMA_OPT_OBJS): ../LZMA/$(*B).cpp
+	$(COMPL_O2)
+$(COMMON_OBJS): ../../../Common/$(*B).cpp
+	$(COMPL)
+$(WIN_OBJS): ../../../Windows/$(*B).cpp
+	$(COMPL)
+$(7ZIP_COMMON_OBJS): ../../Common/$(*B).cpp
+	$(COMPL)
+$(LZ_OBJS): ../LZ/$(*B).cpp
+	$(COMPL)
+$O\RangeCoderBit.obj: ../RangeCoder/$(*B).cpp
+	$(COMPL)
+$O\LzmaRamDecode.obj: LzmaRamDecode.c
+	$(COMPL_O1)
+$O\LzmaDecode.obj: ../../../../C/Compress/Lzma/LzmaDecode.c
+	$(COMPL_O2)
+$O\BranchX86.obj: ../../../../C/Compress/Branch/BranchX86.c
+	$(COMPL_O2)
+$O\FileStreams.obj: ../../Common/FileStreams.cpp
+	$(COMPL)
+$O\FileIO.obj: ../../../Windows/FileIO.cpp
+	$(COMPL)
+$(C_OBJS): ../../../../C/$(*B).c
+	$(COMPL_O2)
+$(C_LZ_OBJS): ../../../../C/Compress/Lz/$(*B).c
+	$(COMPL_O2)
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/misc/libphysfs/lzma/CPP/7zip/Compress/LZMA_Alone/makefile.gcc	Mon Apr 10 12:06:43 2017 -0400
@@ -0,0 +1,139 @@
+PROG = lzma
+CXX = g++ -O2 -Wall
+CXX_C = gcc -O2 -Wall
+LIB = -lm
+RM = rm -f
+CFLAGS = -c
+
+ifdef SystemDrive
+IS_MINGW = 1
+endif
+
+ifdef IS_MINGW
+FILE_IO =FileIO
+FILE_IO_2 =Windows/$(FILE_IO)
+LIB2 = -luuid 
+else
+FILE_IO =C_FileIO
+FILE_IO_2 =Common/$(FILE_IO)
+endif
+
+OBJS = \
+  LzmaAlone.o \
+  LzmaBench.o \
+  LzmaBenchCon.o \
+  LzmaRam.o \
+  LZMADecoder.o \
+  LZMAEncoder.o \
+  LZOutWindow.o \
+  RangeCoderBit.o \
+  InBuffer.o \
+  OutBuffer.o \
+  FileStreams.o \
+  StreamUtils.o \
+  $(FILE_IO).o \
+  CommandLineParser.o \
+  CRC.o \
+  IntToString.o \
+  MyString.o \
+  StringConvert.o \
+  StringToInt.o \
+  MyVector.o \
+  7zCrc.o \
+  Alloc.o \
+  BranchX86.o \
+  MatchFinder.o \
+  LzmaDecode.o \
+  LzmaRamDecode.o \
+
+
+all: $(PROG)
+
+$(PROG): $(OBJS)
+	$(CXX) -o $(PROG) $(LDFLAGS) $(OBJS) $(LIB) $(LIB2)
+
+LzmaAlone.o: LzmaAlone.cpp
+	$(CXX) $(CFLAGS) LzmaAlone.cpp
+
+LzmaBench.o: LzmaBench.cpp
+	$(CXX) $(CFLAGS) LzmaBench.cpp
+
+LzmaBenchCon.o: LzmaBenchCon.cpp
+	$(CXX) $(CFLAGS) LzmaBenchCon.cpp
+
+LzmaRam.o: LzmaRam.cpp
+	$(CXX) $(CFLAGS) LzmaRam.cpp
+
+LZMADecoder.o: ../LZMA/LZMADecoder.cpp
+	$(CXX) $(CFLAGS) ../LZMA/LZMADecoder.cpp
+
+LZMAEncoder.o: ../LZMA/LZMAEncoder.cpp
+	$(CXX) $(CFLAGS) ../LZMA/LZMAEncoder.cpp
+
+LZOutWindow.o: ../LZ/LZOutWindow.cpp
+	$(CXX) $(CFLAGS) ../LZ/LZOutWindow.cpp
+
+RangeCoderBit.o: ../RangeCoder/RangeCoderBit.cpp
+	$(CXX) $(CFLAGS) ../RangeCoder/RangeCoderBit.cpp
+
+InBuffer.o: ../../Common/InBuffer.cpp
+	$(CXX) $(CFLAGS) ../../Common/InBuffer.cpp
+
+OutBuffer.o: ../../Common/OutBuffer.cpp
+	$(CXX) $(CFLAGS) ../../Common/OutBuffer.cpp
+
+FileStreams.o: ../../Common/FileStreams.cpp
+	$(CXX) $(CFLAGS) ../../Common/FileStreams.cpp
+
+StreamUtils.o: ../../Common/StreamUtils.cpp
+	$(CXX) $(CFLAGS) ../../Common/StreamUtils.cpp
+
+$(FILE_IO).o: ../../../$(FILE_IO_2).cpp
+	$(CXX) $(CFLAGS) ../../../$(FILE_IO_2).cpp
+
+
+CommandLineParser.o: ../../../Common/CommandLineParser.cpp
+	$(CXX) $(CFLAGS) ../../../Common/CommandLineParser.cpp
+
+CRC.o: ../../../Common/CRC.cpp
+	$(CXX) $(CFLAGS) ../../../Common/CRC.cpp
+
+MyWindows.o: ../../../Common/MyWindows.cpp
+	$(CXX) $(CFLAGS) ../../../Common/MyWindows.cpp
+
+IntToString.o: ../../../Common/IntToString.cpp
+	$(CXX) $(CFLAGS) ../../../Common/IntToString.cpp
+
+MyString.o: ../../../Common/MyString.cpp
+	$(CXX) $(CFLAGS) ../../../Common/MyString.cpp
+
+StringConvert.o: ../../../Common/StringConvert.cpp
+	$(CXX) $(CFLAGS) ../../../Common/StringConvert.cpp
+
+StringToInt.o: ../../../Common/StringToInt.cpp
+	$(CXX) $(CFLAGS) ../../../Common/StringToInt.cpp
+
+MyVector.o: ../../../Common/MyVector.cpp
+	$(CXX) $(CFLAGS) ../../../Common/MyVector.cpp
+
+7zCrc.o: ../../../../C/7zCrc.c
+	$(CXX_C) $(CFLAGS) ../../../../C/7zCrc.c
+
+Alloc.o: ../../../../C/Alloc.c
+	$(CXX_C) $(CFLAGS) ../../../../C/Alloc.c
+
+BranchX86.o: ../../../../C/Compress/Branch/BranchX86.c
+	$(CXX_C) $(CFLAGS) ../../../../C/Compress/Branch/BranchX86.c
+
+MatchFinder.o: ../../../../C/Compress/Lz/MatchFinder.c
+	$(CXX_C) $(CFLAGS) ../../../../C/Compress/Lz/MatchFinder.c
+
+LzmaDecode.o: ../../../../C/Compress/Lzma/LzmaDecode.c
+	$(CXX_C) $(CFLAGS) ../../../../C/Compress/Lzma/LzmaDecode.c
+
+LzmaRamDecode.o: LzmaRamDecode.c
+	$(CXX_C) $(CFLAGS) LzmaRamDecode.c
+
+clean:
+	-$(RM) $(PROG) $(OBJS)
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/misc/libphysfs/lzma/CPP/7zip/Compress/RangeCoder/RangeCoder.h	Mon Apr 10 12:06:43 2017 -0400
@@ -0,0 +1,205 @@
+// Compress/RangeCoder/RangeCoder.h
+
+#ifndef __COMPRESS_RANGECODER_H
+#define __COMPRESS_RANGECODER_H
+
+#include "../../Common/InBuffer.h"
+#include "../../Common/OutBuffer.h"
+
+namespace NCompress {
+namespace NRangeCoder {
+
+const int kNumTopBits = 24;
+const UInt32 kTopValue = (1 << kNumTopBits);
+
+class CEncoder
+{
+  UInt32 _cacheSize;
+  Byte _cache;
+public:
+  UInt64 Low;
+  UInt32 Range;
+  COutBuffer Stream;
+  bool Create(UInt32 bufferSize) { return Stream.Create(bufferSize); }
+
+  void SetStream(ISequentialOutStream *stream) { Stream.SetStream(stream); }
+  void Init()
+  {
+    Stream.Init();
+    Low = 0;
+    Range = 0xFFFFFFFF;
+    _cacheSize = 1;
+    _cache = 0;
+  }
+
+  void FlushData()
+  {
+    // Low += 1; 
+    for(int i = 0; i < 5; i++)
+      ShiftLow();
+  }
+
+  HRESULT FlushStream() { return Stream.Flush();  }
+
+  void ReleaseStream() { Stream.ReleaseStream(); }
+
+  void Encode(UInt32 start, UInt32 size, UInt32 total)
+  {
+    Low += start * (Range /= total);
+    Range *= size;
+    while (Range < kTopValue)
+    {
+      Range <<= 8;
+      ShiftLow();
+    }
+  }
+
+  void ShiftLow()
+  {
+    if ((UInt32)Low < (UInt32)0xFF000000 || (int)(Low >> 32) != 0) 
+    {
+      Byte temp = _cache;
+      do
+      {
+        Stream.WriteByte((Byte)(temp + (Byte)(Low >> 32)));
+        temp = 0xFF;
+      }
+      while(--_cacheSize != 0);
+      _cache = (Byte)((UInt32)Low >> 24);                      
+    } 
+    _cacheSize++;                               
+    Low = (UInt32)Low << 8;                           
+  }
+  
+  void EncodeDirectBits(UInt32 value, int numTotalBits)
+  {
+    for (int i = numTotalBits - 1; i >= 0; i--)
+    {
+      Range >>= 1;
+      if (((value >> i) & 1) == 1)
+        Low += Range;
+      if (Range < kTopValue)
+      {
+        Range <<= 8;
+        ShiftLow();
+      }
+    }
+  }
+
+  void EncodeBit(UInt32 size0, UInt32 numTotalBits, UInt32 symbol)
+  {
+    UInt32 newBound = (Range >> numTotalBits) * size0;
+    if (symbol == 0)
+      Range = newBound;
+    else
+    {
+      Low += newBound;
+      Range -= newBound;
+    }
+    while (Range < kTopValue)
+    {
+      Range <<= 8;
+      ShiftLow();
+    }
+  }
+
+  UInt64 GetProcessedSize() {  return Stream.GetProcessedSize() + _cacheSize + 4; }
+};
+
+class CDecoder
+{
+public:
+  CInBuffer Stream;
+  UInt32 Range;
+  UInt32 Code;
+  bool Create(UInt32 bufferSize) { return Stream.Create(bufferSize); }
+
+  void Normalize()
+  {
+    while (Range < kTopValue)
+    {
+      Code = (Code << 8) | Stream.ReadByte();
+      Range <<= 8;
+    }
+  }
+  
+  void SetStream(ISequentialInStream *stream) { Stream.SetStream(stream); }
+  void Init()
+  {
+    Stream.Init();
+    Code = 0;
+    Range = 0xFFFFFFFF;
+    for(int i = 0; i < 5; i++)
+      Code = (Code << 8) | Stream.ReadByte();
+  }
+
+  void ReleaseStream() { Stream.ReleaseStream(); }
+
+  UInt32 GetThreshold(UInt32 total)
+  {
+    return (Code) / ( Range /= total);
+  }
+
+  void Decode(UInt32 start, UInt32 size)
+  {
+    Code -= start * Range;
+    Range *= size;
+    Normalize();
+  }
+
+  UInt32 DecodeDirectBits(int numTotalBits)
+  {
+    UInt32 range = Range;
+    UInt32 code = Code;        
+    UInt32 result = 0;
+    for (int i = numTotalBits; i != 0; i--)
+    {
+      range >>= 1;
+      /*
+      result <<= 1;
+      if (code >= range)
+      {
+        code -= range;
+        result |= 1;
+      }
+      */
+      UInt32 t = (code - range) >> 31;
+      code -= range & (t - 1);
+      result = (result << 1) | (1 - t);
+
+      if (range < kTopValue)
+      {
+        code = (code << 8) | Stream.ReadByte();
+        range <<= 8; 
+      }
+    }
+    Range = range;
+    Code = code;
+    return result;
+  }
+
+  UInt32 DecodeBit(UInt32 size0, UInt32 numTotalBits)
+  {
+    UInt32 newBound = (Range >> numTotalBits) * size0;
+    UInt32 symbol;
+    if (Code < newBound)
+    {
+      symbol = 0;
+      Range = newBound;
+    }
+    else
+    {
+      symbol = 1;
+      Code -= newBound;
+      Range -= newBound;
+    }
+    Normalize();
+    return symbol;
+  }
+
+  UInt64 GetProcessedSize() {return Stream.GetProcessedSize(); }
+};
+
+}}
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/misc/libphysfs/lzma/CPP/7zip/Compress/RangeCoder/RangeCoderBit.cpp	Mon Apr 10 12:06:43 2017 -0400
@@ -0,0 +1,80 @@
+// Compress/RangeCoder/RangeCoderBit.cpp
+
+#include "StdAfx.h"
+
+#include "RangeCoderBit.h"
+
+namespace NCompress {
+namespace NRangeCoder {
+
+UInt32 CPriceTables::ProbPrices[kBitModelTotal >> kNumMoveReducingBits];
+static CPriceTables g_PriceTables;
+
+CPriceTables::CPriceTables() { Init(); }
+
+void CPriceTables::Init()
+{
+  const int kNumBits = (kNumBitModelTotalBits - kNumMoveReducingBits);
+  for(int i = kNumBits - 1; i >= 0; i--)
+  {
+    UInt32 start = 1 << (kNumBits - i - 1);
+    UInt32 end = 1 << (kNumBits - i);
+    for (UInt32 j = start; j < end; j++)
+      ProbPrices[j] = (i << kNumBitPriceShiftBits) + 
+          (((end - j) << kNumBitPriceShiftBits) >> (kNumBits - i - 1));
+  }
+
+  /*
+  // simplest: bad solution
+  for(UInt32 i = 1; i < (kBitModelTotal >> kNumMoveReducingBits) - 1; i++)
+    ProbPrices[i] = kBitPrice;
+  */
+  
+  /*
+  const double kDummyMultMid = (1.0 / kBitPrice) / 2;
+  const double kDummyMultMid = 0;
+  // float solution
+  double ln2 = log(double(2));
+  double lnAll = log(double(kBitModelTotal >> kNumMoveReducingBits));
+  for(UInt32 i = 1; i < (kBitModelTotal >> kNumMoveReducingBits) - 1; i++)
+    ProbPrices[i] = UInt32((fabs(lnAll - log(double(i))) / ln2 + kDummyMultMid) * kBitPrice);
+  */
+  
+  /*
+  // experimental, slow, solution:
+  for(UInt32 i = 1; i < (kBitModelTotal >> kNumMoveReducingBits) - 1; i++)
+  {
+    const int kCyclesBits = 5;
+    const UInt32 kCycles = (1 << kCyclesBits);
+
+    UInt32 range = UInt32(-1);
+    UInt32 bitCount = 0;
+    for (UInt32 j = 0; j < kCycles; j++)
+    {
+      range >>= (kNumBitModelTotalBits - kNumMoveReducingBits);
+      range *= i;
+      while(range < (1 << 31))
+      {
+        range <<= 1;
+        bitCount++;
+      }
+    }
+    bitCount <<= kNumBitPriceShiftBits;
+    range -= (1 << 31);
+    for (int k = kNumBitPriceShiftBits - 1; k >= 0; k--)
+    {
+      range <<= 1;
+      if (range > (1 << 31))
+      {
+        bitCount += (1 << k);
+        range -= (1 << 31);
+      }
+    }
+    ProbPrices[i] = (bitCount 
+      // + (1 << (kCyclesBits - 1))
+      ) >> kCyclesBits;
+  }
+  */
+}
+
+}}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/misc/libphysfs/lzma/CPP/7zip/Compress/RangeCoder/RangeCoderBit.h	Mon Apr 10 12:06:43 2017 -0400
@@ -0,0 +1,120 @@
+// Compress/RangeCoder/RangeCoderBit.h
+
+#ifndef __COMPRESS_RANGECODER_BIT_H
+#define __COMPRESS_RANGECODER_BIT_H
+
+#include "RangeCoder.h"
+
+namespace NCompress {
+namespace NRangeCoder {
+
+const int kNumBitModelTotalBits  = 11;
+const UInt32 kBitModelTotal = (1 << kNumBitModelTotalBits);
+
+const int kNumMoveReducingBits = 2;
+
+const int kNumBitPriceShiftBits = 6;
+const UInt32 kBitPrice = 1 << kNumBitPriceShiftBits;
+
+class CPriceTables
+{
+public:
+  static UInt32 ProbPrices[kBitModelTotal >> kNumMoveReducingBits];
+  static void Init();
+  CPriceTables();
+};
+
+template <int numMoveBits>
+class CBitModel
+{
+public:
+  UInt32 Prob;
+  void UpdateModel(UInt32 symbol)
+  {
+    /*
+    Prob -= (Prob + ((symbol - 1) & ((1 << numMoveBits) - 1))) >> numMoveBits;
+    Prob += (1 - symbol) << (kNumBitModelTotalBits - numMoveBits);
+    */
+    if (symbol == 0)
+      Prob += (kBitModelTotal - Prob) >> numMoveBits;
+    else
+      Prob -= (Prob) >> numMoveBits;
+  }
+public:
+  void Init() { Prob = kBitModelTotal / 2; }
+};
+
+template <int numMoveBits>
+class CBitEncoder: public CBitModel<numMoveBits>
+{
+public:
+  void Encode(CEncoder *encoder, UInt32 symbol)
+  {
+    /*
+    encoder->EncodeBit(this->Prob, kNumBitModelTotalBits, symbol);
+    this->UpdateModel(symbol);
+    */
+    UInt32 newBound = (encoder->Range >> kNumBitModelTotalBits) * this->Prob;
+    if (symbol == 0)
+    {
+      encoder->Range = newBound;
+      this->Prob += (kBitModelTotal - this->Prob) >> numMoveBits;
+    }
+    else
+    {
+      encoder->Low += newBound;
+      encoder->Range -= newBound;
+      this->Prob -= (this->Prob) >> numMoveBits;
+    }
+    if (encoder->Range < kTopValue)
+    {
+      encoder->Range <<= 8;
+      encoder->ShiftLow();
+    }
+  }
+  UInt32 GetPrice(UInt32 symbol) const
+  {
+    return CPriceTables::ProbPrices[
+      (((this->Prob - symbol) ^ ((-(int)symbol))) & (kBitModelTotal - 1)) >> kNumMoveReducingBits];
+  }
+  UInt32 GetPrice0() const { return CPriceTables::ProbPrices[this->Prob >> kNumMoveReducingBits]; }
+  UInt32 GetPrice1() const { return CPriceTables::ProbPrices[(kBitModelTotal - this->Prob) >> kNumMoveReducingBits]; }
+};
+
+
+template <int numMoveBits>
+class CBitDecoder: public CBitModel<numMoveBits>
+{
+public:
+  UInt32 Decode(CDecoder *decoder)
+  {
+    UInt32 newBound = (decoder->Range >> kNumBitModelTotalBits) * this->Prob;
+    if (decoder->Code < newBound)
+    {
+      decoder->Range = newBound;
+      this->Prob += (kBitModelTotal - this->Prob) >> numMoveBits;
+      if (decoder->Range < kTopValue)
+      {
+        decoder->Code = (decoder->Code << 8) | decoder->Stream.ReadByte();
+        decoder->Range <<= 8;
+      }
+      return 0;
+    }
+    else
+    {
+      decoder->Range -= newBound;
+      decoder->Code -= newBound;
+      this->Prob -= (this->Prob) >> numMoveBits;
+      if (decoder->Range < kTopValue)
+      {
+        decoder->Code = (decoder->Code << 8) | decoder->Stream.ReadByte();
+        decoder->Range <<= 8;
+      }
+      return 1;
+    }
+  }
+};
+
+}}
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/misc/libphysfs/lzma/CPP/7zip/Compress/RangeCoder/RangeCoderBitTree.h	Mon Apr 10 12:06:43 2017 -0400
@@ -0,0 +1,161 @@
+// Compress/RangeCoder/RangeCoderBitTree.h
+
+#ifndef __COMPRESS_RANGECODER_BIT_TREE_H
+#define __COMPRESS_RANGECODER_BIT_TREE_H
+
+#include "RangeCoderBit.h"
+#include "RangeCoderOpt.h"
+
+namespace NCompress {
+namespace NRangeCoder {
+
+template <int numMoveBits, int NumBitLevels>
+class CBitTreeEncoder
+{
+  CBitEncoder<numMoveBits> Models[1 << NumBitLevels];
+public:
+  void Init()
+  {
+    for(UInt32 i = 1; i < (1 << NumBitLevels); i++)
+      Models[i].Init();
+  }
+  void Encode(CEncoder *rangeEncoder, UInt32 symbol)
+  {
+    UInt32 modelIndex = 1;
+    for (int bitIndex = NumBitLevels; bitIndex != 0 ;)
+    {
+      bitIndex--;
+      UInt32 bit = (symbol >> bitIndex) & 1;
+      Models[modelIndex].Encode(rangeEncoder, bit);
+      modelIndex = (modelIndex << 1) | bit;
+    }
+  };
+  void ReverseEncode(CEncoder *rangeEncoder, UInt32 symbol)
+  {
+    UInt32 modelIndex = 1;
+    for (int i = 0; i < NumBitLevels; i++)
+    {
+      UInt32 bit = symbol & 1;
+      Models[modelIndex].Encode(rangeEncoder, bit);
+      modelIndex = (modelIndex << 1) | bit;
+      symbol >>= 1;
+    }
+  }
+  UInt32 GetPrice(UInt32 symbol) const
+  {
+    symbol |= (1 << NumBitLevels);
+    UInt32 price = 0;
+    while (symbol != 1)
+    {
+      price += Models[symbol >> 1].GetPrice(symbol & 1);
+      symbol >>= 1;
+    }
+    return price;
+  }
+  UInt32 ReverseGetPrice(UInt32 symbol) const
+  {
+    UInt32 price = 0;
+    UInt32 modelIndex = 1;
+    for (int i = NumBitLevels; i != 0; i--)
+    {
+      UInt32 bit = symbol & 1;
+      symbol >>= 1;
+      price += Models[modelIndex].GetPrice(bit);
+      modelIndex = (modelIndex << 1) | bit;
+    }
+    return price;
+  }
+};
+
+template <int numMoveBits, int NumBitLevels>
+class CBitTreeDecoder
+{
+  CBitDecoder<numMoveBits> Models[1 << NumBitLevels];
+public:
+  void Init()
+  {
+    for(UInt32 i = 1; i < (1 << NumBitLevels); i++)
+      Models[i].Init();
+  }
+  UInt32 Decode(CDecoder *rangeDecoder)
+  {
+    UInt32 modelIndex = 1;
+    RC_INIT_VAR
+    for(int bitIndex = NumBitLevels; bitIndex != 0; bitIndex--)
+    {
+      // modelIndex = (modelIndex << 1) + Models[modelIndex].Decode(rangeDecoder);
+      RC_GETBIT(numMoveBits, Models[modelIndex].Prob, modelIndex)
+    }
+    RC_FLUSH_VAR
+    return modelIndex - (1 << NumBitLevels);
+  };
+  UInt32 ReverseDecode(CDecoder *rangeDecoder)
+  {
+    UInt32 modelIndex = 1;
+    UInt32 symbol = 0;
+    RC_INIT_VAR
+    for(int bitIndex = 0; bitIndex < NumBitLevels; bitIndex++)
+    {
+      // UInt32 bit = Models[modelIndex].Decode(rangeDecoder);
+      // modelIndex <<= 1;
+      // modelIndex += bit;
+      // symbol |= (bit << bitIndex);
+      RC_GETBIT2(numMoveBits, Models[modelIndex].Prob, modelIndex, ; , symbol |= (1 << bitIndex))
+    }
+    RC_FLUSH_VAR
+    return symbol;
+  }
+};
+
+template <int numMoveBits>
+void ReverseBitTreeEncode(CBitEncoder<numMoveBits> *Models, 
+    CEncoder *rangeEncoder, int NumBitLevels, UInt32 symbol)
+{
+  UInt32 modelIndex = 1;
+  for (int i = 0; i < NumBitLevels; i++)
+  {
+    UInt32 bit = symbol & 1;
+    Models[modelIndex].Encode(rangeEncoder, bit);
+    modelIndex = (modelIndex << 1) | bit;
+    symbol >>= 1;
+  }
+}
+
+template <int numMoveBits>
+UInt32 ReverseBitTreeGetPrice(CBitEncoder<numMoveBits> *Models, 
+    UInt32 NumBitLevels, UInt32 symbol)
+{
+  UInt32 price = 0;
+  UInt32 modelIndex = 1;
+  for (int i = NumBitLevels; i != 0; i--)
+  {
+    UInt32 bit = symbol & 1;
+    symbol >>= 1;
+    price += Models[modelIndex].GetPrice(bit);
+    modelIndex = (modelIndex << 1) | bit;
+  }
+  return price;
+}
+
+template <int numMoveBits>
+UInt32 ReverseBitTreeDecode(CBitDecoder<numMoveBits> *Models, 
+    CDecoder *rangeDecoder, int NumBitLevels)
+{
+  UInt32 modelIndex = 1;
+  UInt32 symbol = 0;
+  RC_INIT_VAR
+  for(int bitIndex = 0; bitIndex < NumBitLevels; bitIndex++)
+  {
+    // UInt32 bit = Models[modelIndex].Decode(rangeDecoder);
+    // modelIndex <<= 1;
+    // modelIndex += bit;
+    // symbol |= (bit << bitIndex);
+    RC_GETBIT2(numMoveBits, Models[modelIndex].Prob, modelIndex, ; , symbol |= (1 << bitIndex))
+  }
+  RC_FLUSH_VAR
+  return symbol;
+}
+
+}}
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/misc/libphysfs/lzma/CPP/7zip/Compress/RangeCoder/RangeCoderOpt.h	Mon Apr 10 12:06:43 2017 -0400
@@ -0,0 +1,31 @@
+// Compress/RangeCoder/RangeCoderOpt.h
+
+#ifndef __COMPRESS_RANGECODER_OPT_H
+#define __COMPRESS_RANGECODER_OPT_H
+
+#define RC_INIT_VAR \
+  UInt32 range = rangeDecoder->Range; \
+  UInt32 code = rangeDecoder->Code;        
+
+#define RC_FLUSH_VAR \
+  rangeDecoder->Range = range; \
+  rangeDecoder->Code = code;
+
+#define RC_NORMALIZE \
+  if (range < NCompress::NRangeCoder::kTopValue) \
+    { code = (code << 8) | rangeDecoder->Stream.ReadByte(); range <<= 8; }
+
+#define RC_GETBIT2(numMoveBits, prob, mi, A0, A1) \
+  { UInt32 bound = (range >> NCompress::NRangeCoder::kNumBitModelTotalBits) * prob; \
+  if (code < bound) \
+  { A0; range = bound; \
+    prob += (NCompress::NRangeCoder::kBitModelTotal - prob) >> numMoveBits; \
+    mi <<= 1; } \
+  else \
+  { A1; range -= bound; code -= bound; prob -= (prob) >> numMoveBits; \
+    mi = (mi + mi) + 1; }} \
+  RC_NORMALIZE
+
+#define RC_GETBIT(numMoveBits, prob, mi) RC_GETBIT2(numMoveBits, prob, mi, ; , ;)
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/misc/libphysfs/lzma/CPP/7zip/Compress/RangeCoder/StdAfx.h	Mon Apr 10 12:06:43 2017 -0400
@@ -0,0 +1,6 @@
+// StdAfx.h
+
+#ifndef __STDAFX_H
+#define __STDAFX_H
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/misc/libphysfs/lzma/CPP/7zip/ICoder.h	Mon Apr 10 12:06:43 2017 -0400
@@ -0,0 +1,185 @@
+// ICoder.h
+
+#ifndef __ICODER_H
+#define __ICODER_H
+
+#include "IStream.h"
+
+#define CODER_INTERFACE(i, x) DECL_INTERFACE(i, 4, x)
+
+CODER_INTERFACE(ICompressProgressInfo, 0x04)
+{
+  STDMETHOD(SetRatioInfo)(const UInt64 *inSize, const UInt64 *outSize) PURE;
+};
+
+CODER_INTERFACE(ICompressCoder, 0x05)
+{
+  STDMETHOD(Code)(ISequentialInStream *inStream,
+      ISequentialOutStream *outStream, 
+      const UInt64 *inSize, 
+      const UInt64 *outSize,
+      ICompressProgressInfo *progress) PURE;
+};
+
+CODER_INTERFACE(ICompressCoder2, 0x18)
+{
+  STDMETHOD(Code)(ISequentialInStream **inStreams,
+      const UInt64 **inSizes, 
+      UInt32 numInStreams,
+      ISequentialOutStream **outStreams, 
+      const UInt64 **outSizes,
+      UInt32 numOutStreams,
+      ICompressProgressInfo *progress) PURE;
+};
+
+namespace NCoderPropID
+{
+  enum EEnum
+  {
+    kDictionarySize = 0x400,
+    kUsedMemorySize,
+    kOrder,
+    kPosStateBits = 0x440,
+    kLitContextBits,
+    kLitPosBits,
+    kNumFastBytes = 0x450,
+    kMatchFinder,
+    kMatchFinderCycles,
+    kNumPasses = 0x460, 
+    kAlgorithm = 0x470,
+    kMultiThread = 0x480,
+    kNumThreads,
+    kEndMarker = 0x490
+  };
+}
+
+CODER_INTERFACE(ICompressSetCoderProperties, 0x20)
+{
+  STDMETHOD(SetCoderProperties)(const PROPID *propIDs, 
+      const PROPVARIANT *properties, UInt32 numProperties) PURE;
+};
+
+/*
+CODER_INTERFACE(ICompressSetCoderProperties, 0x21)
+{
+  STDMETHOD(SetDecoderProperties)(ISequentialInStream *inStream) PURE;
+};
+*/
+
+CODER_INTERFACE(ICompressSetDecoderProperties2, 0x22)
+{
+  STDMETHOD(SetDecoderProperties2)(const Byte *data, UInt32 size) PURE;
+};
+
+CODER_INTERFACE(ICompressWriteCoderProperties, 0x23)
+{
+  STDMETHOD(WriteCoderProperties)(ISequentialOutStream *outStreams) PURE;
+};
+
+CODER_INTERFACE(ICompressGetInStreamProcessedSize, 0x24)
+{
+  STDMETHOD(GetInStreamProcessedSize)(UInt64 *value) PURE;
+};
+
+CODER_INTERFACE(ICompressSetCoderMt, 0x25)
+{
+  STDMETHOD(SetNumberOfThreads)(UInt32 numThreads) PURE;
+};
+
+CODER_INTERFACE(ICompressGetSubStreamSize, 0x30)
+{
+  STDMETHOD(GetSubStreamSize)(UInt64 subStream, UInt64 *value) PURE;
+};
+
+CODER_INTERFACE(ICompressSetInStream, 0x31)
+{
+  STDMETHOD(SetInStream)(ISequentialInStream *inStream) PURE;
+  STDMETHOD(ReleaseInStream)() PURE;
+};
+
+CODER_INTERFACE(ICompressSetOutStream, 0x32)
+{
+  STDMETHOD(SetOutStream)(ISequentialOutStream *outStream) PURE;
+  STDMETHOD(ReleaseOutStream)() PURE;
+};
+
+CODER_INTERFACE(ICompressSetInStreamSize, 0x33)
+{
+  STDMETHOD(SetInStreamSize)(const UInt64 *inSize) PURE;
+};
+
+CODER_INTERFACE(ICompressSetOutStreamSize, 0x34)
+{
+  STDMETHOD(SetOutStreamSize)(const UInt64 *outSize) PURE;
+};
+
+CODER_INTERFACE(ICompressFilter, 0x40)
+{
+  STDMETHOD(Init)() PURE;
+  STDMETHOD_(UInt32, Filter)(Byte *data, UInt32 size) PURE;
+  // Filter return outSize (UInt32)
+  // if (outSize <= size): Filter have converted outSize bytes
+  // if (outSize > size): Filter have not converted anything.
+  //      and it needs at least outSize bytes to convert one block 
+  //      (it's for crypto block algorithms).
+};
+
+CODER_INTERFACE(ICompressCodecsInfo, 0x60)
+{
+  STDMETHOD(GetNumberOfMethods)(UInt32 *numMethods) PURE;
+  STDMETHOD(GetProperty)(UInt32 index, PROPID propID, PROPVARIANT *value) PURE;
+  STDMETHOD(CreateDecoder)(UInt32 index, const GUID *iid, void **coder) PURE;
+  STDMETHOD(CreateEncoder)(UInt32 index, const GUID *iid, void **coder) PURE;
+};
+CODER_INTERFACE(ISetCompressCodecsInfo, 0x61)
+{
+  STDMETHOD(SetCompressCodecsInfo)(ICompressCodecsInfo *compressCodecsInfo) PURE;
+};
+
+CODER_INTERFACE(ICryptoProperties, 0x80)
+{
+  STDMETHOD(SetKey)(const Byte *data, UInt32 size) PURE;
+  STDMETHOD(SetInitVector)(const Byte *data, UInt32 size) PURE;
+};
+
+/*
+CODER_INTERFACE(ICryptoResetSalt, 0x88)
+{
+  STDMETHOD(ResetSalt)() PURE;
+};
+*/
+
+CODER_INTERFACE(ICryptoResetInitVector, 0x8C)
+{
+  STDMETHOD(ResetInitVector)() PURE;
+};
+
+CODER_INTERFACE(ICryptoSetPassword, 0x90)
+{
+  STDMETHOD(CryptoSetPassword)(const Byte *data, UInt32 size) PURE;
+};
+
+CODER_INTERFACE(ICryptoSetCRC, 0xA0)
+{
+  STDMETHOD(CryptoSetCRC)(UInt32 crc) PURE;
+};
+
+//////////////////////
+// It's for DLL file
+namespace NMethodPropID
+{
+  enum EEnum
+  {
+    kID,
+    kName,
+    kDecoder,
+    kEncoder,
+    kInStreams,
+    kOutStreams,
+    kDescription,
+    kDecoderIsAssigned,
+    kEncoderIsAssigned
+  };
+}
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/misc/libphysfs/lzma/CPP/7zip/IDecl.h	Mon Apr 10 12:06:43 2017 -0400
@@ -0,0 +1,15 @@
+// IDecl.h
+
+#ifndef __IDECL_H
+#define __IDECL_H
+
+#include "../Common/MyUnknown.h"
+
+#define DECL_INTERFACE_SUB(i, base, groupId, subId) \
+DEFINE_GUID(IID_ ## i, \
+0x23170F69, 0x40C1, 0x278A, 0, 0, 0, (groupId), 0, (subId), 0, 0); \
+struct i: public base
+
+#define DECL_INTERFACE(i, groupId, subId) DECL_INTERFACE_SUB(i, IUnknown, groupId, subId)
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/misc/libphysfs/lzma/CPP/7zip/IPassword.h	Mon Apr 10 12:06:43 2017 -0400
@@ -0,0 +1,24 @@
+// IPassword.h
+
+#ifndef __IPASSWORD_H
+#define __IPASSWORD_H
+
+#include "../Common/MyUnknown.h"
+#include "../Common/Types.h"
+
+#include "IDecl.h"
+
+#define PASSWORD_INTERFACE(i, x) DECL_INTERFACE(i, 5, x)
+
+PASSWORD_INTERFACE(ICryptoGetTextPassword, 0x10)
+{
+  STDMETHOD(CryptoGetTextPassword)(BSTR *password) PURE;
+};
+
+PASSWORD_INTERFACE(ICryptoGetTextPassword2, 0x11)
+{
+  STDMETHOD(CryptoGetTextPassword2)(Int32 *passwordIsDefined, BSTR *password) PURE;
+};
+
+#endif
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/misc/libphysfs/lzma/CPP/7zip/IProgress.h	Mon Apr 10 12:06:43 2017 -0400
@@ -0,0 +1,30 @@
+// Interface/IProgress.h
+
+#ifndef __IPROGRESS_H
+#define __IPROGRESS_H
+
+#include "../Common/MyUnknown.h"
+#include "../Common/Types.h"
+
+#include "IDecl.h"
+
+DECL_INTERFACE(IProgress, 0, 5)
+{
+  STDMETHOD(SetTotal)(UInt64 total) PURE;
+  STDMETHOD(SetCompleted)(const UInt64 *completeValue) PURE;
+};
+
+/*
+// {23170F69-40C1-278A-0000-000000050002}
+DEFINE_GUID(IID_IProgress2, 
+0x23170F69, 0x40C1, 0x278A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x00, 0x02);
+MIDL_INTERFACE("23170F69-40C1-278A-0000-000000050002")
+IProgress2: public IUnknown
+{
+public:
+  STDMETHOD(SetTotal)(const UInt64 *total) PURE;
+  STDMETHOD(SetCompleted)(const UInt64 *completeValue) PURE;
+};
+*/
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/misc/libphysfs/lzma/CPP/7zip/IStream.h	Mon Apr 10 12:06:43 2017 -0400
@@ -0,0 +1,58 @@
+// IStream.h
+
+#ifndef __ISTREAM_H
+#define __ISTREAM_H
+
+#include "../Common/MyUnknown.h"
+#include "../Common/Types.h"
+
+#include "IDecl.h"
+
+#define STREAM_INTERFACE_SUB(i, base, x) DECL_INTERFACE_SUB(i, base, 3, x)
+#define STREAM_INTERFACE(i, x) STREAM_INTERFACE_SUB(i, IUnknown, x)
+
+STREAM_INTERFACE(ISequentialInStream, 0x01)
+{
+  STDMETHOD(Read)(void *data, UInt32 size, UInt32 *processedSize) PURE;
+  /*
+  Out: if size != 0, return_value = S_OK and (*processedSize == 0),
+    then there are no more bytes in stream.
+  if (size > 0) && there are bytes in stream, 
+  this function must read at least 1 byte.
+  This function is allowed to read less than number of remaining bytes in stream.
+  You must call Read function in loop, if you need exact amount of data
+  */
+};
+
+STREAM_INTERFACE(ISequentialOutStream, 0x02)
+{
+  STDMETHOD(Write)(const void *data, UInt32 size, UInt32 *processedSize) PURE;
+  /*
+  if (size > 0) this function must write at least 1 byte.
+  This function is allowed to write less than "size".
+  You must call Write function in loop, if you need to write exact amount of data
+  */
+};
+
+STREAM_INTERFACE_SUB(IInStream, ISequentialInStream, 0x03)
+{
+  STDMETHOD(Seek)(Int64 offset, UInt32 seekOrigin, UInt64 *newPosition) PURE;
+};
+
+STREAM_INTERFACE_SUB(IOutStream, ISequentialOutStream, 0x04)
+{
+  STDMETHOD(Seek)(Int64 offset, UInt32 seekOrigin, UInt64 *newPosition) PURE;
+  STDMETHOD(SetSize)(Int64 newSize) PURE;
+};
+
+STREAM_INTERFACE(IStreamGetSize, 0x06)
+{
+  STDMETHOD(GetSize)(UInt64 *size) PURE;
+};
+
+STREAM_INTERFACE(IOutStreamFlush, 0x07)
+{
+  STDMETHOD(Flush)() PURE;
+};
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/misc/libphysfs/lzma/CPP/7zip/MyVersion.h	Mon Apr 10 12:06:43 2017 -0400
@@ -0,0 +1,8 @@
+#define MY_VER_MAJOR 4
+#define MY_VER_MINOR 57
+#define MY_VER_BUILD 0
+#define MY_VERSION "4.57"
+#define MY_7ZIP_VERSION "7-Zip 4.57"
+#define MY_DATE "2007-12-06"
+#define MY_COPYRIGHT "Copyright (c) 1999-2007 Igor Pavlov"
+#define MY_VERSION_COPYRIGHT_DATE MY_VERSION "  " MY_COPYRIGHT "  " MY_DATE
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/misc/libphysfs/lzma/CPP/7zip/MyVersionInfo.rc	Mon Apr 10 12:06:43 2017 -0400
@@ -0,0 +1,45 @@
+#include <WinVer.h>
+#include "MyVersion.h"
+
+#define MY_VER MY_VER_MAJOR,MY_VER_MINOR,MY_VER_BUILD,0
+
+#ifdef DEBUG
+#define DBG_FL VS_FF_DEBUG
+#else
+#define DBG_FL 0
+#endif
+
+#define MY_VERSION_INFO(fileType, descr, intName, origName)  \
+LANGUAGE 9, 1 \
+1 VERSIONINFO \
+  FILEVERSION MY_VER \
+  PRODUCTVERSION MY_VER \
+  FILEFLAGSMASK VS_FFI_FILEFLAGSMASK \
+  FILEFLAGS DBG_FL \
+  FILEOS VOS_NT_WINDOWS32 \
+  FILETYPE fileType \
+  FILESUBTYPE 0x0L \
+BEGIN \
+    BLOCK "StringFileInfo" \
+    BEGIN  \
+        BLOCK "040904b0" \
+        BEGIN \
+            VALUE "CompanyName", "Igor Pavlov" \
+            VALUE "FileDescription", descr \
+            VALUE "FileVersion", MY_VERSION  \
+            VALUE "InternalName", intName \
+            VALUE "LegalCopyright", MY_COPYRIGHT \
+            VALUE "OriginalFilename", origName \
+            VALUE "ProductName", "7-Zip" \
+            VALUE "ProductVersion", MY_VERSION \
+        END \
+    END \
+    BLOCK "VarFileInfo" \
+    BEGIN \
+        VALUE "Translation", 0x409, 1200 \
+    END \
+END
+
+#define MY_VERSION_INFO_APP(descr, intName) MY_VERSION_INFO(VFT_APP, descr, intName, intName ".exe")
+
+#define MY_VERSION_INFO_DLL(descr, intName) MY_VERSION_INFO(VFT_DLL, descr, intName, intName ".dll")
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/misc/libphysfs/lzma/CPP/7zip/PropID.h	Mon Apr 10 12:06:43 2017 -0400
@@ -0,0 +1,60 @@
+// Interface/PropID.h
+
+#ifndef __INTERFACE_PROPID_H
+#define __INTERFACE_PROPID_H
+
+enum
+{
+  kpidNoProperty = 0,
+  
+  kpidHandlerItemIndex = 2,
+  kpidPath,
+  kpidName,
+  kpidExtension,
+  kpidIsFolder,
+  kpidSize,
+  kpidPackedSize,
+  kpidAttributes,
+  kpidCreationTime,
+  kpidLastAccessTime,
+  kpidLastWriteTime,
+  kpidSolid, 
+  kpidCommented, 
+  kpidEncrypted, 
+  kpidSplitBefore, 
+  kpidSplitAfter, 
+  kpidDictionarySize, 
+  kpidCRC, 
+  kpidType,
+  kpidIsAnti,
+  kpidMethod,
+  kpidHostOS,
+  kpidFileSystem,
+  kpidUser,
+  kpidGroup,
+  kpidBlock,
+  kpidComment,
+  kpidPosition,
+  kpidPrefix,
+  kpidNumSubFolders,
+  kpidNumSubFiles,
+  kpidUnpackVer,
+  kpidVolume,
+  kpidIsVolume,
+  kpidOffset,
+  kpidLinks,
+  kpidNumBlocks,
+  kpidNumVolumes,
+
+  kpidTotalSize = 0x1100,
+  kpidFreeSpace, 
+  kpidClusterSize,
+  kpidVolumeName,
+
+  kpidLocalName = 0x1200,
+  kpidProvider,
+
+  kpidUserDefined = 0x10000
+};
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/misc/libphysfs/lzma/CPP/7zip/UI/Client7z/Client7z.cpp	Mon Apr 10 12:06:43 2017 -0400
@@ -0,0 +1,880 @@
+// Client7z.cpp
+
+#include "StdAfx.h"
+
+#include "Common/MyInitGuid.h"
+#include "Common/StringConvert.h"
+#include "Common/IntToString.h"
+
+#include "Windows/PropVariant.h"
+#include "Windows/PropVariantConversions.h"
+#include "Windows/DLL.h"
+#include "Windows/FileDir.h"
+#include "Windows/FileName.h"
+#include "Windows/FileFind.h"
+
+#include "../../Common/FileStreams.h"
+#include "../../Archive/IArchive.h"
+#include "../../IPassword.h"
+#include "../../MyVersion.h"
+
+
+// {23170F69-40C1-278A-1000-000110070000}
+DEFINE_GUID(CLSID_CFormat7z, 
+  0x23170F69, 0x40C1, 0x278A, 0x10, 0x00, 0x00, 0x01, 0x10, 0x07, 0x00, 0x00);
+
+using namespace NWindows;
+
+#define kDllName "7z.dll"
+
+static const char *kCopyrightString = MY_7ZIP_VERSION
+" ("  kDllName " client) "  
+MY_COPYRIGHT " " MY_DATE;
+
+static const char *kHelpString = 
+"Usage: Client7z.exe [a | l | x ] archive.7z [fileName ...]\n"
+"Examples:\n"
+"  Client7z.exe a archive.7z f1.txt f2.txt  : compress two files to archive.7z\n"
+"  Client7z.exe l archive.7z   : List contents of archive.7z\n"
+"  Client7z.exe x archive.7z   : eXtract files from archive.7z\n";
+
+
+typedef UINT32 (WINAPI * CreateObjectFunc)(
+    const GUID *clsID, 
+    const GUID *interfaceID, 
+    void **outObject);
+
+#ifdef _WIN32
+#ifndef _UNICODE
+bool g_IsNT = false;
+static inline bool IsItWindowsNT()
+{
+  OSVERSIONINFO versionInfo;
+  versionInfo.dwOSVersionInfoSize = sizeof(versionInfo);
+  if (!::GetVersionEx(&versionInfo)) 
+    return false;
+  return (versionInfo.dwPlatformId == VER_PLATFORM_WIN32_NT);
+}
+#endif
+#endif
+
+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();
+}
+
+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, kpidIsFolder, 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;
+  }
+  CMyComBSTR tempName(Password);
+  *password = tempName.Detach();
+  return S_OK;
+}
+
+
+//////////////////////////////////////////////////////////////
+// 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 arcvhive
+  UString _diskFilePath;   // full path to file on disk
+  bool _extractMode;
+  struct CProcessedFileInfo
+  {
+    FILETIME UTCLastWriteTime;
+    UInt32 Attributes;
+    bool IsDirectory;
+    bool AttributesAreDefined;
+    bool UTCLastWriteTimeIsDefined;
+  } _processedFileInfo;
+
+  COutFileStream *_outFileStreamSpec;
+  CMyComPtr<ISequentialOutStream> _outFileStream;
+
+public:
+  void Init(IInArchive *archiveHandler, const UString &directoryPath);
+
+  UInt64 NumErrors;
+  bool PasswordIsDefined;
+  UString Password;
+
+  CArchiveExtractCallback() : PasswordIsDefined(false) {}
+};
+
+void CArchiveExtractCallback::Init(IInArchive *archiveHandler, const UString &directoryPath)
+{
+  NumErrors = 0;
+  _archiveHandler = archiveHandler;
+  _directoryPath = directoryPath;
+  NFile::NName::NormalizeDirPathPrefix(_directoryPath);
+}
+
+STDMETHODIMP CArchiveExtractCallback::SetTotal(UInt64 /* size */)
+{
+  return S_OK;
+}
+
+STDMETHODIMP CArchiveExtractCallback::SetCompleted(const UInt64 * /* completeValue */)
+{
+  return S_OK;
+}
+
+STDMETHODIMP CArchiveExtractCallback::GetStream(UInt32 index, 
+    ISequentialOutStream **outStream, Int32 askExtractMode)
+{
+  *outStream = 0;
+  _outFileStream.Release();
+
+  {
+    // Get Name
+    NCOM::CPropVariant propVariant;
+    RINOK(_archiveHandler->GetProperty(index, kpidPath, &propVariant));
+    
+    UString fullPath;
+    if(propVariant.vt == VT_EMPTY)
+      fullPath = kEmptyFileAlias;
+    else 
+    {
+      if(propVariant.vt != VT_BSTR)
+        return E_FAIL;
+      fullPath = propVariant.bstrVal;
+    }
+    _filePath = fullPath;
+  }
+
+  if (askExtractMode != NArchive::NExtract::NAskMode::kExtract)
+    return S_OK;
+
+  {
+    // Get Attributes
+    NCOM::CPropVariant propVariant;
+    RINOK(_archiveHandler->GetProperty(index, kpidAttributes, &propVariant));
+    if (propVariant.vt == VT_EMPTY)
+    {
+      _processedFileInfo.Attributes = 0;
+      _processedFileInfo.AttributesAreDefined = false;
+    }
+    else
+    {
+      if (propVariant.vt != VT_UI4)
+        throw "incorrect item";
+      _processedFileInfo.Attributes = propVariant.ulVal;
+      _processedFileInfo.AttributesAreDefined = true;
+    }
+  }
+
+  RINOK(IsArchiveItemFolder(_archiveHandler, index, _processedFileInfo.IsDirectory));
+
+  {
+    // Get Modified Time
+    NCOM::CPropVariant propVariant;
+    RINOK(_archiveHandler->GetProperty(index, kpidLastWriteTime, &propVariant));
+    _processedFileInfo.UTCLastWriteTimeIsDefined = false;
+    switch(propVariant.vt)
+    {
+      case VT_EMPTY:
+        // _processedFileInfo.UTCLastWriteTime = _utcLastWriteTimeDefault;
+        break;
+      case VT_FILETIME:
+        _processedFileInfo.UTCLastWriteTime = propVariant.filetime;
+        _processedFileInfo.UTCLastWriteTimeIsDefined = true;
+        break;
+      default:
+        return E_FAIL;
+    }
+
+  }
+  {
+    // Get Size
+    NCOM::CPropVariant propVariant;
+    RINOK(_archiveHandler->GetProperty(index, kpidSize, &propVariant));
+    bool newFileSizeDefined = (propVariant.vt != VT_EMPTY);
+    UInt64 newFileSize;
+    if (newFileSizeDefined)
+      newFileSize = ConvertPropVariantToUInt64(propVariant);
+  }
+
+  
+  {
+    // 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.IsDirectory)
+  {
+    NFile::NDirectory::CreateComplexDirectory(fullProcessedPath);
+  }
+  else
+  {
+    NFile::NFind::CFileInfoW fileInfo;
+    if(NFile::NFind::FindFile(fullProcessedPath, fileInfo))
+    {
+      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;
+  };
+  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);
+  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.UTCLastWriteTimeIsDefined)
+      _outFileStreamSpec->SetLastWriteTime(&_processedFileInfo.UTCLastWriteTime);
+    RINOK(_outFileStreamSpec->Close());
+  }
+  _outFileStream.Release();
+  if (_extractMode && _processedFileInfo.AttributesAreDefined)
+    NFile::NDirectory::MySetFileAttributes(_diskFilePath, _processedFileInfo.Attributes);
+  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;
+  }
+  CMyComBSTR tempName(Password);
+  *password = tempName.Detach();
+  return S_OK;
+}
+
+
+
+//////////////////////////////////////////////////////////////
+// Archive Creating callback class
+
+struct CDirItem
+{ 
+  UInt32 Attributes;
+  FILETIME CreationTime;
+  FILETIME LastAccessTime;
+  FILETIME LastWriteTime;
+  UInt64 Size;
+  UString Name;
+  UString FullPath;
+  bool IsDirectory() const { return (Attributes & FILE_ATTRIBUTE_DIRECTORY) != 0 ; }
+};
+
+class CArchiveUpdateCallback: 
+  public IArchiveUpdateCallback2,
+  public ICryptoGetTextPassword2,
+  public CMyUnknownImp
+{
+public:
+  MY_UNKNOWN_IMP2(IArchiveUpdateCallback2, ICryptoGetTextPassword2)
+
+  // IProgress
+  STDMETHOD(SetTotal)(UInt64 size);
+  STDMETHOD(SetCompleted)(const UInt64 *completeValue);
+
+  // IUpdateCallback2
+  STDMETHOD(EnumProperties)(IEnumSTATPROPSTG **enumerator);  
+  STDMETHOD(GetUpdateItemInfo)(UInt32 index, 
+      Int32 *newData, Int32 *newProperties, UInt32 *indexInArchive);
+  STDMETHOD(GetProperty)(UInt32 index, PROPID propID, PROPVARIANT *value);
+  STDMETHOD(GetStream)(UInt32 index, ISequentialInStream **inStream);
+  STDMETHOD(SetOperationResult)(Int32 operationResult);
+  STDMETHOD(GetVolumeSize)(UInt32 index, UInt64 *size);
+  STDMETHOD(GetVolumeStream)(UInt32 index, ISequentialOutStream **volumeStream);
+
+  STDMETHOD(CryptoGetTextPassword2)(Int32 *passwordIsDefined, BSTR *password);
+
+public:
+  CRecordVector<UInt64> VolumesSizes;
+  UString VolName;
+  UString VolExt;
+
+  UString DirPrefix;
+  const CObjectVector<CDirItem> *DirItems;
+
+  bool PasswordIsDefined;
+  UString Password;
+  bool AskPassword;
+
+  bool m_NeedBeClosed;
+
+  UStringVector FailedFiles;
+  CRecordVector<HRESULT> FailedCodes;
+
+  CArchiveUpdateCallback(): PasswordIsDefined(false), AskPassword(false), DirItems(0) {};
+
+  ~CArchiveUpdateCallback() { Finilize(); }
+  HRESULT Finilize();
+
+  void Init(const CObjectVector<CDirItem> *dirItems)
+  {
+    DirItems = dirItems;
+    m_NeedBeClosed = false;
+    FailedFiles.Clear();
+    FailedCodes.Clear();
+  }
+};
+
+STDMETHODIMP CArchiveUpdateCallback::SetTotal(UInt64 /* size */)
+{
+  return S_OK;
+}
+
+STDMETHODIMP CArchiveUpdateCallback::SetCompleted(const UInt64 * /* completeValue */)
+{
+  return S_OK;
+}
+
+
+STDMETHODIMP CArchiveUpdateCallback::EnumProperties(IEnumSTATPROPSTG ** /* enumerator */)
+{
+  return E_NOTIMPL;
+}
+
+STDMETHODIMP CArchiveUpdateCallback::GetUpdateItemInfo(UInt32 /* index */, 
+      Int32 *newData, Int32 *newProperties, UInt32 *indexInArchive)
+{
+  if(newData != NULL)
+    *newData = BoolToInt(true);
+  if(newProperties != NULL)
+    *newProperties = BoolToInt(true);
+  if(indexInArchive != NULL)
+    *indexInArchive = UInt32(-1);
+  return S_OK;
+}
+
+STDMETHODIMP CArchiveUpdateCallback::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *value)
+{
+  NWindows::NCOM::CPropVariant propVariant;
+  
+  if (propID == kpidIsAnti)
+  {
+    propVariant = false;
+    propVariant.Detach(value);
+    return S_OK;
+  }
+
+  {
+    const CDirItem &dirItem = (*DirItems)[index];
+    switch(propID)
+    {
+      case kpidPath:
+        propVariant = dirItem.Name;
+        break;
+      case kpidIsFolder:
+        propVariant = dirItem.IsDirectory();
+        break;
+      case kpidSize:
+        propVariant = dirItem.Size;
+        break;
+      case kpidAttributes:
+        propVariant = dirItem.Attributes;
+        break;
+      case kpidLastAccessTime:
+        propVariant = dirItem.LastAccessTime;
+        break;
+      case kpidCreationTime:
+        propVariant = dirItem.CreationTime;
+        break;
+      case kpidLastWriteTime:
+        propVariant = dirItem.LastWriteTime;
+        break;
+    }
+  }
+  propVariant.Detach(value);
+  return S_OK;
+}
+
+HRESULT CArchiveUpdateCallback::Finilize()
+{
+  if (m_NeedBeClosed)
+  {
+    PrintNewLine();
+    m_NeedBeClosed = false;
+  }
+  return S_OK;
+}
+
+static void GetStream2(const wchar_t *name)
+{
+  PrintString("Compressing  ");
+  if (name[0] == 0)
+    name = kEmptyFileAlias;
+  PrintString(name);
+}
+
+STDMETHODIMP CArchiveUpdateCallback::GetStream(UInt32 index, ISequentialInStream **inStream)
+{
+  RINOK(Finilize());
+
+  const CDirItem &dirItem = (*DirItems)[index];
+  GetStream2(dirItem.Name);
+ 
+  if(dirItem.IsDirectory())
+    return S_OK;
+
+  {
+    CInFileStream *inStreamSpec = new CInFileStream;
+    CMyComPtr<ISequentialInStream> inStreamLoc(inStreamSpec);
+    UString path = DirPrefix + dirItem.FullPath;
+    if(!inStreamSpec->Open(path))
+    {
+      DWORD sysError = ::GetLastError();
+      FailedCodes.Add(sysError);
+      FailedFiles.Add(path);
+      // if (systemError == ERROR_SHARING_VIOLATION)
+      {
+        PrintNewLine();
+        PrintError("WARNING: can't open file");
+        // PrintString(NError::MyFormatMessageW(systemError));
+        return S_FALSE;
+      }
+      // return sysError;
+    }
+    *inStream = inStreamLoc.Detach();
+  }
+  return S_OK;
+}
+
+STDMETHODIMP CArchiveUpdateCallback::SetOperationResult(Int32 /* operationResult */)
+{
+  m_NeedBeClosed = true;
+  return S_OK;
+}
+
+STDMETHODIMP CArchiveUpdateCallback::GetVolumeSize(UInt32 index, UInt64 *size)
+{
+  if (VolumesSizes.Size() == 0)
+    return S_FALSE;
+  if (index >= (UInt32)VolumesSizes.Size())
+    index = VolumesSizes.Size() - 1;
+  *size = VolumesSizes[index];
+  return S_OK;
+}
+
+STDMETHODIMP CArchiveUpdateCallback::GetVolumeStream(UInt32 index, ISequentialOutStream **volumeStream)
+{
+  wchar_t temp[32];
+  ConvertUInt64ToString(index + 1, temp);
+  UString res = temp;
+  while (res.Length() < 2)
+    res = UString(L'0') + res;
+  UString fileName = VolName;
+  fileName += L'.';
+  fileName += res;
+  fileName += VolExt;
+  COutFileStream *streamSpec = new COutFileStream;
+  CMyComPtr<ISequentialOutStream> streamLoc(streamSpec);
+  if(!streamSpec->Create(fileName, false))
+    return ::GetLastError();
+  *volumeStream = streamLoc.Detach();
+  return S_OK;
+}
+
+STDMETHODIMP CArchiveUpdateCallback::CryptoGetTextPassword2(Int32 *passwordIsDefined, BSTR *password)
+{
+  if (!PasswordIsDefined) 
+  {
+    if (AskPassword)
+    {
+      // You can ask real password here from user
+      // Password = GetPassword(OutStream); 
+      // PasswordIsDefined = true;
+      PrintError("Password is not defined");
+      return E_ABORT;
+    }
+  }
+  *passwordIsDefined = BoolToInt(PasswordIsDefined);
+  CMyComBSTR tempName(Password);
+  *password = tempName.Detach();
+  return S_OK;
+}
+
+
+
+//////////////////////////////////////////////////////////////////////////
+// Main function
+
+int 
+#ifdef _MSC_VER
+__cdecl 
+#endif
+main(int argc, char* argv[])
+{
+  #ifdef _WIN32
+  #ifndef _UNICODE
+  g_IsNT = IsItWindowsNT();
+  #endif
+  #endif
+
+  PrintStringLn(kCopyrightString);
+
+  if (argc < 3)
+  {
+    PrintStringLn(kHelpString);
+    return 1;
+  }
+  NWindows::NDLL::CLibrary library;
+  if (!library.Load(TEXT(kDllName)))
+  {
+    PrintError("Can not load library");
+    return 1;
+  }
+  CreateObjectFunc createObjectFunc = (CreateObjectFunc)library.GetProcAddress("CreateObject");
+  if (createObjectFunc == 0)
+  {
+    PrintError("Can not get CreateObject");
+    return 1;
+  }
+
+  AString command = argv[1];
+  UString archiveName = GetUnicodeString(argv[2], CP_OEMCP);
+  if (command.CompareNoCase("a") == 0)
+  {
+    // create archive command
+    if (argc < 4)
+    {
+      PrintStringLn(kHelpString);
+      return 1;
+    }
+    CObjectVector<CDirItem> dirItems;
+    int i;
+    for (i = 3; i < argc; i++)
+    {
+      CDirItem item;
+      UString name = GetUnicodeString(argv[i], CP_OEMCP);
+      
+      NFile::NFind::CFileInfoW fileInfo;
+      if (!NFile::NFind::FindFile(name, fileInfo))
+      {
+        PrintString(UString(L"Can't find file") + name);
+        return 1;
+      }
+
+      item.Attributes = fileInfo.Attributes;
+      item.Size = fileInfo.Size;
+      item.CreationTime = fileInfo.CreationTime;
+      item.LastAccessTime = fileInfo.LastAccessTime;
+      item.LastWriteTime = fileInfo.LastWriteTime;
+      item.Name = name;
+      item.FullPath = name;
+      dirItems.Add(item);
+    }
+    COutFileStream *outFileStreamSpec = new COutFileStream;
+    CMyComPtr<IOutStream> outFileStream = outFileStreamSpec;
+    if (!outFileStreamSpec->Create(archiveName, false))
+    {
+      PrintError("can't create archive file");
+      return 1;
+    }
+
+    CMyComPtr<IOutArchive> outArchive;
+    if (createObjectFunc(&CLSID_CFormat7z, &IID_IOutArchive, (void **)&outArchive) != S_OK)
+    {
+      PrintError("Can not get class object");
+      return 1;
+    }
+
+    CArchiveUpdateCallback *updateCallbackSpec = new CArchiveUpdateCallback;
+    CMyComPtr<IArchiveUpdateCallback2> updateCallback(updateCallbackSpec);
+    updateCallbackSpec->Init(&dirItems);
+    // updateCallbackSpec->PasswordIsDefined = true;
+    // updateCallbackSpec->Password = L"1";
+
+    HRESULT result = outArchive->UpdateItems(outFileStream, dirItems.Size(), updateCallback);
+    updateCallbackSpec->Finilize();
+    if (result != S_OK)
+    {
+      PrintError("Update Error");
+      return 1;
+    }
+    for (i = 0; i < updateCallbackSpec->FailedFiles.Size(); i++)
+    {
+      PrintNewLine();
+      PrintString((UString)L"Error for file: " + updateCallbackSpec->FailedFiles[i]);
+    }
+    if (updateCallbackSpec->FailedFiles.Size() != 0)
+      return 1;
+  }
+  else
+  {
+    if (argc != 3)
+    {
+      PrintStringLn(kHelpString);
+      return 1;
+    }
+
+    bool listCommand;
+    if (command.CompareNoCase("l") == 0)
+      listCommand = true;
+    else if (command.CompareNoCase("x") == 0)
+      listCommand = false;
+    else
+    {
+      PrintError("incorrect command");
+      return 1;
+    }
+  
+    CMyComPtr<IInArchive> archive;
+    if (createObjectFunc(&CLSID_CFormat7z, &IID_IInArchive, (void **)&archive) != S_OK)
+    {
+      PrintError("Can not get class object");
+      return 1;
+    }
+    
+    CInFileStream *fileSpec = new CInFileStream;
+    CMyComPtr<IInStream> file = fileSpec;
+    
+    if (!fileSpec->Open(archiveName))
+    {
+      PrintError("Can not open archive file");
+      return 1;
+    }
+
+    {
+      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 1;
+      }
+    }
+    
+    if (listCommand)
+    {
+      // List command
+      UInt32 numItems = 0;
+      archive->GetNumberOfItems(&numItems);  
+      for (UInt32 i = 0; i < numItems; i++)
+      {
+        {
+          // Get uncompressed size of file
+          NWindows::NCOM::CPropVariant propVariant;
+          archive->GetProperty(i, kpidSize, &propVariant);
+          UString s = ConvertPropVariantToString(propVariant);
+          PrintString(s);
+          PrintString("  ");
+        }
+        {
+          // Get name of file
+          NWindows::NCOM::CPropVariant propVariant;
+          archive->GetProperty(i, kpidPath, &propVariant);
+          UString s = ConvertPropVariantToString(propVariant);
+          PrintString(s);
+        }
+        PrintString("\n");
+      }
+    }
+    else
+    {
+      // Extract command
+      CArchiveExtractCallback *extractCallbackSpec = new CArchiveExtractCallback;
+      CMyComPtr<IArchiveExtractCallback> extractCallback(extractCallbackSpec);
+      extractCallbackSpec->Init(archive, L""); // second parameter is output folder path
+      extractCallbackSpec->PasswordIsDefined = false;
+      // extractCallbackSpec->PasswordIsDefined = true;
+      // extractCallbackSpec->Password = L"1";
+      HRESULT result = archive->Extract(NULL, (UInt32)(Int32)(-1), false, extractCallback);
+      if (result != S_OK)
+      {
+        PrintError("Extract Error");
+        return 1;
+      }
+    }
+  }
+  return 0;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/misc/libphysfs/lzma/CPP/7zip/UI/Client7z/Client7z.dsp	Mon Apr 10 12:06:43 2017 -0400
@@ -0,0 +1,226 @@
+# Microsoft Developer Studio Project File - Name="Client7z" - Package Owner=<4>
+# Microsoft Developer Studio Generated Build File, Format Version 6.00
+# ** DO NOT EDIT **
+
+# TARGTYPE "Win32 (x86) Console Application" 0x0103
+
+CFG=Client7z - Win32 Debug
+!MESSAGE This is not a valid makefile. To build this project using NMAKE,
+!MESSAGE use the Export Makefile command and run
+!MESSAGE 
+!MESSAGE NMAKE /f "Client7z.mak".
+!MESSAGE 
+!MESSAGE You can specify a configuration when running NMAKE
+!MESSAGE by defining the macro CFG on the command line. For example:
+!MESSAGE 
+!MESSAGE NMAKE /f "Client7z.mak" CFG="Client7z - Win32 Debug"
+!MESSAGE 
+!MESSAGE Possible choices for configuration are:
+!MESSAGE 
+!MESSAGE "Client7z - Win32 Release" (based on "Win32 (x86) Console Application")
+!MESSAGE "Client7z - Win32 Debug" (based on "Win32 (x86) Console Application")
+!MESSAGE 
+
+# Begin Project
+# PROP AllowPerConfigDependencies 0
+# PROP Scc_ProjName ""
+# PROP Scc_LocalPath ""
+CPP=cl.exe
+RSC=rc.exe
+
+!IF  "$(CFG)" == "Client7z - Win32 Release"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 0
+# PROP BASE Output_Dir "Release"
+# PROP BASE Intermediate_Dir "Release"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 0
+# PROP Output_Dir "Release"
+# PROP Intermediate_Dir "Release"
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /Yu"stdafx.h" /FD /c
+# ADD CPP /nologo /MD /W3 /GX /O2 /I "..\..\..\\" /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /Yu"stdafx.h" /FD /c
+# ADD BASE RSC /l 0x419 /d "NDEBUG"
+# ADD RSC /l 0x419 /d "NDEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386
+# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386
+
+!ELSEIF  "$(CFG)" == "Client7z - Win32 Debug"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 1
+# PROP BASE Output_Dir "Debug"
+# PROP BASE Intermediate_Dir "Debug"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 1
+# PROP Output_Dir "Debug"
+# PROP Intermediate_Dir "Debug"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /Yu"stdafx.h" /FD /GZ /c
+# ADD CPP /nologo /W3 /Gm /GX /ZI /Od /I "..\..\..\\" /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /Yu"stdafx.h" /FD /GZ /c
+# ADD BASE RSC /l 0x419 /d "_DEBUG"
+# ADD RSC /l 0x419 /d "_DEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept
+# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept
+
+!ENDIF 
+
+# Begin Target
+
+# Name "Client7z - Win32 Release"
+# Name "Client7z - Win32 Debug"
+# Begin Group "Spec"
+
+# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"
+# Begin Source File
+
+SOURCE=.\StdAfx.cpp
+# ADD CPP /Yc"stdafx.h"
+# End Source File
+# Begin Source File
+
+SOURCE=.\StdAfx.h
+# End Source File
+# End Group
+# Begin Group "Windows"
+
+# PROP Default_Filter ""
+# Begin Source File
+
+SOURCE=..\..\..\Windows\DLL.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Windows\DLL.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Windows\FileDir.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Windows\FileDir.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Windows\FileFind.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Windows\FileFind.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Windows\FileIO.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Windows\FileIO.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Windows\FileName.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Windows\FileName.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Windows\PropVariant.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Windows\PropVariant.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Windows\PropVariantConversions.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Windows\PropVariantConversions.h
+# End Source File
+# End Group
+# Begin Group "Common"
+
+# PROP Default_Filter ""
+# Begin Source File
+
+SOURCE=..\..\..\Common\IntToString.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Common\IntToString.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Common\MyString.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Common\MyString.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Common\MyVector.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Common\MyVector.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Common\NewHandler.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Common\NewHandler.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Common\StringConvert.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Common\StringConvert.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Common\Wildcard.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Common\Wildcard.h
+# End Source File
+# End Group
+# Begin Group "7zip Common"
+
+# PROP Default_Filter ""
+# Begin Source File
+
+SOURCE=..\..\Common\FileStreams.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Common\FileStreams.h
+# End Source File
+# End Group
+# Begin Source File
+
+SOURCE=.\Client7z.cpp
+# End Source File
+# End Target
+# End Project
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/misc/libphysfs/lzma/CPP/7zip/UI/Client7z/Client7z.dsw	Mon Apr 10 12:06:43 2017 -0400
@@ -0,0 +1,29 @@
+Microsoft Developer Studio Workspace File, Format Version 6.00
+# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE!
+
+###############################################################################
+
+Project: "Client7z"=.\Client7z.dsp - Package Owner=<4>
+
+Package=<5>
+{{{
+}}}
+
+Package=<4>
+{{{
+}}}
+
+###############################################################################
+
+Global:
+
+Package=<5>
+{{{
+}}}
+
+Package=<3>
+{{{
+}}}
+
+###############################################################################
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/misc/libphysfs/lzma/CPP/7zip/UI/Client7z/StdAfx.cpp	Mon Apr 10 12:06:43 2017 -0400
@@ -0,0 +1,3 @@
+// StdAfx.cpp
+
+#include "StdAfx.h"
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/misc/libphysfs/lzma/CPP/7zip/UI/Client7z/StdAfx.h	Mon Apr 10 12:06:43 2017 -0400
@@ -0,0 +1,9 @@
+// StdAfx.h
+
+#ifndef __STDAFX_H
+#define __STDAFX_H
+
+#include <windows.h>
+#include <stdio.h>
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/misc/libphysfs/lzma/CPP/7zip/UI/Client7z/makefile	Mon Apr 10 12:06:43 2017 -0400
@@ -0,0 +1,45 @@
+PROG = 7z.exe
+LIBS = $(LIBS) user32.lib oleaut32.lib advapi32.lib
+CFLAGS = $(CFLAGS) -I ../../../
+
+CONSOLE_OBJS = \
+  $O\Client7z.obj \
+
+COMMON_OBJS = \
+  $O\IntToString.obj \
+  $O\NewHandler.obj \
+  $O\MyString.obj \
+  $O\StringConvert.obj \
+  $O\StringToInt.obj \
+  $O\MyVector.obj \
+  $O\Wildcard.obj \
+
+WIN_OBJS = \
+  $O\DLL.obj \
+  $O\FileDir.obj \
+  $O\FileFind.obj \
+  $O\FileIO.obj \
+  $O\FileName.obj \
+  $O\PropVariant.obj \
+  $O\PropVariantConversions.obj \
+
+7ZIP_COMMON_OBJS = \
+  $O\FileStreams.obj \
+
+OBJS = \
+  $O\StdAfx.obj \
+  $(CONSOLE_OBJS) \
+  $(COMMON_OBJS) \
+  $(WIN_OBJS) \
+  $(7ZIP_COMMON_OBJS) \
+
+!include "../../../Build.mak"
+
+$(CONSOLE_OBJS): $(*B).cpp
+	$(COMPL)
+$(COMMON_OBJS): ../../../Common/$(*B).cpp
+	$(COMPL)
+$(WIN_OBJS): ../../../Windows/$(*B).cpp
+	$(COMPL)
+$(7ZIP_COMMON_OBJS): ../../Common/$(*B).cpp
+	$(COMPL)
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/misc/libphysfs/lzma/CPP/7zip/UI/Common/ArchiveCommandLine.cpp	Mon Apr 10 12:06:43 2017 -0400
@@ -0,0 +1,1003 @@
+// ArchiveCommandLine.cpp
+
+#include "StdAfx.h"
+
+#ifdef _WIN32
+#include <io.h>
+#endif
+#include <stdio.h>
+
+#include "Common/ListFileUtils.h"
+#include "Common/StringConvert.h"
+#include "Common/StringToInt.h"
+
+#include "Windows/FileName.h"
+#include "Windows/FileDir.h"
+#ifdef _WIN32
+#include "Windows/FileMapping.h"
+#include "Windows/Synchronization.h"
+#endif
+
+#include "ArchiveCommandLine.h"
+#include "UpdateAction.h"
+#include "Update.h"
+#include "SortUtils.h"
+#include "EnumDirItems.h"
+
+extern bool g_CaseSensitive;
+
+#if _MSC_VER >= 1400
+#define MY_isatty_fileno(x) _isatty(_fileno(x))
+#else
+#define MY_isatty_fileno(x) isatty(fileno(x))
+#endif
+
+#define MY_IS_TERMINAL(x) (MY_isatty_fileno(x) != 0); 
+
+using namespace NCommandLineParser;
+using namespace NWindows;
+using namespace NFile;
+
+namespace NKey {
+enum Enum
+{
+  kHelp1 = 0,
+  kHelp2,
+  kHelp3,
+  kDisableHeaders,
+  kDisablePercents,
+  kArchiveType,
+  kYes,
+  kPassword,
+  kProperty,
+  kOutputDir,
+  kWorkingDir,
+  kInclude,
+  kExclude,
+  kArInclude,
+  kArExclude,
+  kNoArName,
+  kUpdate,
+  kVolume,
+  kRecursed,
+  kSfx,
+  kStdIn,
+  kStdOut,
+  kOverwrite,
+  kEmail,
+  kShowDialog,
+  kLargePages,
+  kCharSet,
+  kTechMode,
+  kShareForWrite,
+  kCaseSensitive
+};
+
+}
+
+
+static const wchar_t kRecursedIDChar = 'R';
+static const wchar_t *kRecursedPostCharSet = L"0-";
+
+namespace NRecursedPostCharIndex {
+  enum EEnum 
+  {
+    kWildCardRecursionOnly = 0, 
+    kNoRecursion = 1
+  };
+}
+
+static const char kImmediateNameID = '!';
+static const char kMapNameID = '#';
+static const char kFileListID = '@';
+
+static const char kSomeCludePostStringMinSize = 2; // at least <@|!><N>ame must be
+static const char kSomeCludeAfterRecursedPostStringMinSize = 2; // at least <@|!><N>ame must be
+
+static const wchar_t *kOverwritePostCharSet = L"asut";
+
+NExtract::NOverwriteMode::EEnum k_OverwriteModes[] =
+{
+  NExtract::NOverwriteMode::kWithoutPrompt,
+  NExtract::NOverwriteMode::kSkipExisting,
+  NExtract::NOverwriteMode::kAutoRename,
+  NExtract::NOverwriteMode::kAutoRenameExisting
+};
+
+static const CSwitchForm kSwitchForms[] = 
+  {
+    { L"?",  NSwitchType::kSimple, false },
+    { L"H",  NSwitchType::kSimple, false },
+    { L"-HELP",  NSwitchType::kSimple, false },
+    { L"BA", NSwitchType::kSimple, false },
+    { L"BD", NSwitchType::kSimple, false },
+    { L"T",  NSwitchType::kUnLimitedPostString, false, 1 },
+    { L"Y",  NSwitchType::kSimple, false },
+    { L"P",  NSwitchType::kUnLimitedPostString, false, 0 },
+    { L"M",  NSwitchType::kUnLimitedPostString, true, 1 },
+    { L"O",  NSwitchType::kUnLimitedPostString, false, 1 },
+    { L"W",  NSwitchType::kUnLimitedPostString, false, 0 },
+    { L"I",  NSwitchType::kUnLimitedPostString, true, kSomeCludePostStringMinSize},
+    { L"X",  NSwitchType::kUnLimitedPostString, true, kSomeCludePostStringMinSize},
+    { L"AI", NSwitchType::kUnLimitedPostString, true, kSomeCludePostStringMinSize},
+    { L"AX", NSwitchType::kUnLimitedPostString, true, kSomeCludePostStringMinSize},
+    { L"AN", NSwitchType::kSimple, false },
+    { L"U",  NSwitchType::kUnLimitedPostString, true, 1},
+    { L"V",  NSwitchType::kUnLimitedPostString, true, 1},
+    { L"R",  NSwitchType::kPostChar, false, 0, 0, kRecursedPostCharSet },
+    { L"SFX", NSwitchType::kUnLimitedPostString, false, 0 },
+    { L"SI", NSwitchType::kUnLimitedPostString, false, 0 },
+    { L"SO", NSwitchType::kSimple, false, 0 },
+    { L"AO", NSwitchType::kPostChar, false, 1, 1, kOverwritePostCharSet},
+    { L"SEML", NSwitchType::kUnLimitedPostString, false, 0},
+    { L"AD",  NSwitchType::kSimple, false },
+    { L"SLP", NSwitchType::kUnLimitedPostString, false, 0},
+    { L"SCS", NSwitchType::kUnLimitedPostString, false, 0},
+    { L"SLT", NSwitchType::kSimple, false },
+    { L"SSW", NSwitchType::kSimple, false },
+    { L"SSC", NSwitchType::kPostChar, false, 0, 0, L"-" }
+  };
+
+static const CCommandForm g_CommandForms[] = 
+{
+  { L"A", false },
+  { L"U", false },
+  { L"D", false },
+  { L"T", false },
+  { L"E", false },
+  { L"X", false },
+  { L"L", false },
+  { L"B", false },
+  { L"I", false }
+};
+
+static const int kNumCommandForms = sizeof(g_CommandForms) /  sizeof(g_CommandForms[0]);
+
+static const wchar_t *kUniversalWildcard = L"*";
+static const int kMinNonSwitchWords = 1;
+static const int kCommandIndex = 0;
+
+// ---------------------------
+// exception messages
+
+static const char *kUserErrorMessage  = "Incorrect command line";
+static const char *kIncorrectListFile = "Incorrect item in listfile.\nCheck charset encoding and -scs switch.";
+static const char *kIncorrectWildCardInListFile = "Incorrect wildcard in listfile";
+static const char *kIncorrectWildCardInCommandLine  = "Incorrect wildcard in command line";
+static const char *kTerminalOutError = "I won't write compressed data to a terminal";
+static const char *kSameTerminalError = "I won't write data and program's messages to same terminal";
+
+static void ThrowException(const char *errorMessage)
+{
+  throw CArchiveCommandLineException(errorMessage);
+};
+
+static void ThrowUserErrorException()
+{
+  ThrowException(kUserErrorMessage);
+};
+
+// ---------------------------
+
+bool CArchiveCommand::IsFromExtractGroup() const
+{
+  switch(CommandType)
+  {
+    case NCommandType::kTest:
+    case NCommandType::kExtract:
+    case NCommandType::kFullExtract:
+      return true;
+    default:
+      return false;
+  }
+}
+
+NExtract::NPathMode::EEnum CArchiveCommand::GetPathMode() const
+{
+  switch(CommandType)
+  {
+    case NCommandType::kTest:
+    case NCommandType::kFullExtract:
+      return NExtract::NPathMode::kFullPathnames;
+    default:
+      return NExtract::NPathMode::kNoPathnames;
+  }
+}
+
+bool CArchiveCommand::IsFromUpdateGroup() const
+{
+  return (CommandType == NCommandType::kAdd || 
+    CommandType == NCommandType::kUpdate ||
+    CommandType == NCommandType::kDelete);
+}
+
+static NRecursedType::EEnum GetRecursedTypeFromIndex(int index)
+{
+  switch (index)
+  {
+    case NRecursedPostCharIndex::kWildCardRecursionOnly: 
+      return NRecursedType::kWildCardOnlyRecursed;
+    case NRecursedPostCharIndex::kNoRecursion: 
+      return NRecursedType::kNonRecursed;
+    default:
+      return NRecursedType::kRecursed;
+  }
+}
+
+static bool ParseArchiveCommand(const UString &commandString, CArchiveCommand &command)
+{
+  UString commandStringUpper = commandString;
+  commandStringUpper.MakeUpper();
+  UString postString;
+  int commandIndex = ParseCommand(kNumCommandForms, g_CommandForms, commandStringUpper, 
+      postString) ;
+  if (commandIndex < 0)
+    return false;
+  command.CommandType = (NCommandType::EEnum)commandIndex;
+  return true;
+}
+
+// ------------------------------------------------------------------
+// filenames functions
+
+static bool AddNameToCensor(NWildcard::CCensor &wildcardCensor, 
+    const UString &name, bool include, NRecursedType::EEnum type)
+{
+  bool isWildCard = DoesNameContainWildCard(name);
+  bool recursed = false;
+
+  switch (type)
+  {
+    case NRecursedType::kWildCardOnlyRecursed:
+      recursed = isWildCard;
+      break;
+    case NRecursedType::kRecursed:
+      recursed = true;
+      break;
+    case NRecursedType::kNonRecursed:
+      recursed = false;
+      break;
+  }
+  wildcardCensor.AddItem(include, name, recursed);
+  return true;
+}
+
+static void AddToCensorFromListFile(NWildcard::CCensor &wildcardCensor, 
+    LPCWSTR fileName, bool include, NRecursedType::EEnum type, UINT codePage)
+{
+  UStringVector names;
+  if (!ReadNamesFromListFile(fileName, names, codePage))
+    throw kIncorrectListFile;
+  for (int i = 0; i < names.Size(); i++)
+    if (!AddNameToCensor(wildcardCensor, names[i], include, type))
+      throw kIncorrectWildCardInListFile;
+}
+
+static void AddCommandLineWildCardToCensr(NWildcard::CCensor &wildcardCensor, 
+    const UString &name, bool include, NRecursedType::EEnum recursedType)
+{
+  if (!AddNameToCensor(wildcardCensor, name, include, recursedType))
+    throw kIncorrectWildCardInCommandLine;
+}
+
+static void AddToCensorFromNonSwitchesStrings(
+    int startIndex,
+    NWildcard::CCensor &wildcardCensor, 
+    const UStringVector &nonSwitchStrings, NRecursedType::EEnum type, 
+    bool thereAreSwitchIncludes, UINT codePage)
+{
+  if(nonSwitchStrings.Size() == startIndex && (!thereAreSwitchIncludes)) 
+    AddCommandLineWildCardToCensr(wildcardCensor, kUniversalWildcard, true, type);
+  for(int i = startIndex; i < nonSwitchStrings.Size(); i++)
+  {
+    const UString &s = nonSwitchStrings[i];
+    if (s[0] == kFileListID)
+      AddToCensorFromListFile(wildcardCensor, s.Mid(1), true, type, codePage);
+    else
+      AddCommandLineWildCardToCensr(wildcardCensor, s, true, type);
+  }
+}
+
+#ifdef _WIN32
+static void ParseMapWithPaths(NWildcard::CCensor &wildcardCensor, 
+    const UString &switchParam, bool include, 
+    NRecursedType::EEnum commonRecursedType)
+{
+  int splitPos = switchParam.Find(L':');
+  if (splitPos < 0)
+    ThrowUserErrorException();
+  UString mappingName = switchParam.Left(splitPos);
+  
+  UString switchParam2 = switchParam.Mid(splitPos + 1);
+  splitPos = switchParam2.Find(L':');
+  if (splitPos < 0)
+    ThrowUserErrorException();
+  
+  UString mappingSize = switchParam2.Left(splitPos);
+  UString eventName = switchParam2.Mid(splitPos + 1);
+  
+  UInt64 dataSize64 = ConvertStringToUInt64(mappingSize, NULL);
+  UInt32 dataSize = (UInt32)dataSize64;
+  {
+    CFileMapping fileMapping;
+    if (!fileMapping.Open(FILE_MAP_READ, false, GetSystemString(mappingName)))
+      ThrowException("Can not open mapping");
+    LPVOID data = fileMapping.MapViewOfFile(FILE_MAP_READ, 0, dataSize);
+    if (data == NULL)
+      ThrowException("MapViewOfFile error");
+    try
+    {
+      const wchar_t *curData = (const wchar_t *)data;
+      if (*curData != 0)
+        ThrowException("Incorrect mapping data");
+      UInt32 numChars = dataSize / sizeof(wchar_t);
+      UString name;
+      for (UInt32 i = 1; i < numChars; i++)
+      {
+        wchar_t c = curData[i];
+        if (c == L'\0')
+        {
+          AddCommandLineWildCardToCensr(wildcardCensor, 
+              name, include, commonRecursedType);
+          name.Empty();
+        }
+        else
+          name += c;
+      }
+      if (!name.IsEmpty())
+        ThrowException("data error");
+    }
+    catch(...)
+    {
+      UnmapViewOfFile(data);
+      throw;
+    }
+    UnmapViewOfFile(data);
+  }
+  
+  {
+    NSynchronization::CManualResetEvent event;
+    if (event.Open(EVENT_MODIFY_STATE, false, GetSystemString(eventName)) == S_OK)
+      event.Set();
+  }
+}
+#endif
+
+static void AddSwitchWildCardsToCensor(NWildcard::CCensor &wildcardCensor, 
+    const UStringVector &strings, bool include, 
+    NRecursedType::EEnum commonRecursedType, UINT codePage)
+{
+  for(int i = 0; i < strings.Size(); i++)
+  {
+    const UString &name = strings[i];
+    NRecursedType::EEnum recursedType;
+    int pos = 0;
+    if (name.Length() < kSomeCludePostStringMinSize)
+      ThrowUserErrorException();
+    if (::MyCharUpper(name[pos]) == kRecursedIDChar)
+    {
+      pos++;
+      int index = UString(kRecursedPostCharSet).Find(name[pos]);
+      recursedType = GetRecursedTypeFromIndex(index);
+      if (index >= 0)
+        pos++;
+    }
+    else
+      recursedType = commonRecursedType;
+    if (name.Length() < pos + kSomeCludeAfterRecursedPostStringMinSize)
+      ThrowUserErrorException();
+    UString tail = name.Mid(pos + 1);
+    if (name[pos] == kImmediateNameID)
+      AddCommandLineWildCardToCensr(wildcardCensor, tail, include, recursedType);
+    else if (name[pos] == kFileListID)
+      AddToCensorFromListFile(wildcardCensor, tail, include, recursedType, codePage);
+    #ifdef _WIN32
+    else if (name[pos] == kMapNameID)
+      ParseMapWithPaths(wildcardCensor, tail, include, recursedType);
+    #endif
+    else
+      ThrowUserErrorException();
+  }
+}
+
+#ifdef _WIN32
+
+// This code converts all short file names to long file names.
+
+static void ConvertToLongName(const UString &prefix, UString &name)
+{
+  if (name.IsEmpty() || DoesNameContainWildCard(name))
+    return;
+  NFind::CFileInfoW fileInfo;
+  if (NFind::FindFile(prefix + name, fileInfo))
+    name = fileInfo.Name;
+}
+
+static void ConvertToLongNames(const UString &prefix, CObjectVector<NWildcard::CItem> &items)
+{
+  for (int i = 0; i < items.Size(); i++)
+  {
+    NWildcard::CItem &item = items[i];
+    if (item.Recursive || item.PathParts.Size() != 1)
+      continue;
+    ConvertToLongName(prefix, item.PathParts.Front());
+  }
+}
+
+static void ConvertToLongNames(const UString &prefix, NWildcard::CCensorNode &node)
+{
+  ConvertToLongNames(prefix, node.IncludeItems);
+  ConvertToLongNames(prefix, node.ExcludeItems);
+  int i;
+  for (i = 0; i < node.SubNodes.Size(); i++)
+    ConvertToLongName(prefix, node.SubNodes[i].Name);
+  // mix folders with same name
+  for (i = 0; i < node.SubNodes.Size(); i++)
+  {
+    NWildcard::CCensorNode &nextNode1 = node.SubNodes[i];
+    for (int j = i + 1; j < node.SubNodes.Size();)
+    {
+      const NWildcard::CCensorNode &nextNode2 = node.SubNodes[j];
+      if (nextNode1.Name.CompareNoCase(nextNode2.Name) == 0)
+      {
+        nextNode1.IncludeItems += nextNode2.IncludeItems;
+        nextNode1.ExcludeItems += nextNode2.ExcludeItems;
+        node.SubNodes.Delete(j);
+      }
+      else
+        j++;
+    }
+  }
+  for (i = 0; i < node.SubNodes.Size(); i++)
+  {
+    NWildcard::CCensorNode &nextNode = node.SubNodes[i];
+    ConvertToLongNames(prefix + nextNode.Name + wchar_t(NFile::NName::kDirDelimiter), nextNode); 
+  }
+}
+
+static void ConvertToLongNames(NWildcard::CCensor &censor)
+{
+  for (int i = 0; i < censor.Pairs.Size(); i++)
+  {
+    NWildcard::CPair &pair = censor.Pairs[i];
+    ConvertToLongNames(pair.Prefix, pair.Head);
+  }
+}
+
+#endif
+
+static NUpdateArchive::NPairAction::EEnum GetUpdatePairActionType(int i)
+{
+  switch(i)
+  {
+    case NUpdateArchive::NPairAction::kIgnore: return NUpdateArchive::NPairAction::kIgnore;
+    case NUpdateArchive::NPairAction::kCopy: return NUpdateArchive::NPairAction::kCopy;
+    case NUpdateArchive::NPairAction::kCompress: return NUpdateArchive::NPairAction::kCompress;
+    case NUpdateArchive::NPairAction::kCompressAsAnti: return NUpdateArchive::NPairAction::kCompressAsAnti;
+  }
+  throw 98111603;
+}
+
+const UString kUpdatePairStateIDSet = L"PQRXYZW";
+const int kUpdatePairStateNotSupportedActions[] = {2, 2, 1, -1, -1, -1, -1};
+
+const UString kUpdatePairActionIDSet = L"0123"; //Ignore, Copy, Compress, Create Anti
+
+const wchar_t *kUpdateIgnoreItselfPostStringID = L"-"; 
+const wchar_t kUpdateNewArchivePostCharID = '!'; 
+
+
+static bool ParseUpdateCommandString2(const UString &command, 
+    NUpdateArchive::CActionSet &actionSet, UString &postString)
+{
+  for(int i = 0; i < command.Length();)
+  {
+    wchar_t c = MyCharUpper(command[i]);
+    int statePos = kUpdatePairStateIDSet.Find(c);
+    if (statePos < 0)
+    {
+      postString = command.Mid(i);
+      return true;
+    }
+    i++;
+    if (i >= command.Length())
+      return false;
+    int actionPos = kUpdatePairActionIDSet.Find(::MyCharUpper(command[i]));
+    if (actionPos < 0)
+      return false;
+    actionSet.StateActions[statePos] = GetUpdatePairActionType(actionPos);
+    if (kUpdatePairStateNotSupportedActions[statePos] == actionPos)
+      return false;
+    i++;
+  }
+  postString.Empty();
+  return true;
+}
+
+static void ParseUpdateCommandString(CUpdateOptions &options, 
+    const UStringVector &updatePostStrings, 
+    const NUpdateArchive::CActionSet &defaultActionSet)
+{
+  for(int i = 0; i < updatePostStrings.Size(); i++)
+  {
+    const UString &updateString = updatePostStrings[i];
+    if(updateString.CompareNoCase(kUpdateIgnoreItselfPostStringID) == 0)
+    {
+      if(options.UpdateArchiveItself)
+      {
+        options.UpdateArchiveItself = false;
+        options.Commands.Delete(0);
+      }
+    }
+    else
+    {
+      NUpdateArchive::CActionSet actionSet = defaultActionSet;
+
+      UString postString;
+      if (!ParseUpdateCommandString2(updateString, actionSet, postString))
+        ThrowUserErrorException();
+      if(postString.IsEmpty())
+      {
+        if(options.UpdateArchiveItself)
+          options.Commands[0].ActionSet = actionSet;
+      }
+      else
+      {
+        if(MyCharUpper(postString[0]) != kUpdateNewArchivePostCharID)
+          ThrowUserErrorException();
+        CUpdateArchiveCommand uc;
+        UString archivePath = postString.Mid(1);
+        if (archivePath.IsEmpty())
+          ThrowUserErrorException();
+        uc.UserArchivePath = archivePath;
+        uc.ActionSet = actionSet;
+        options.Commands.Add(uc);
+      }
+    }
+  }
+}
+
+static const char kByteSymbol = 'B';
+static const char kKiloSymbol = 'K';
+static const char kMegaSymbol = 'M';
+static const char kGigaSymbol = 'G';
+
+static bool ParseComplexSize(const UString &src, UInt64 &result)
+{
+  UString s = src;
+  s.MakeUpper();
+
+  const wchar_t *start = s;
+  const wchar_t *end;
+  UInt64 number = ConvertStringToUInt64(start, &end);
+  int numDigits = (int)(end - start);
+  if (numDigits == 0 || s.Length() > numDigits + 1)
+    return false;
+  if (s.Length() == numDigits)
+  {
+    result = number;
+    return true;
+  }
+  int numBits;
+  switch (s[numDigits])
+  {
+    case kByteSymbol:
+      result = number;
+      return true;
+    case kKiloSymbol:
+      numBits = 10;
+      break;
+    case kMegaSymbol:
+      numBits = 20;
+      break;
+    case kGigaSymbol:
+      numBits = 30;
+      break;
+    default:
+      return false;
+  }
+  if (number >= ((UInt64)1 << (64 - numBits)))
+    return false;
+  result = number << numBits;
+  return true;
+}
+
+static void SetAddCommandOptions(
+    NCommandType::EEnum commandType, 
+    const CParser &parser, 
+    CUpdateOptions &options)
+{
+  NUpdateArchive::CActionSet defaultActionSet;
+  switch(commandType)
+  {
+    case NCommandType::kAdd: 
+      defaultActionSet = NUpdateArchive::kAddActionSet;
+      break;
+    case NCommandType::kDelete: 
+      defaultActionSet = NUpdateArchive::kDeleteActionSet;
+      break;
+    default: 
+      defaultActionSet = NUpdateArchive::kUpdateActionSet;
+  }
+  
+  options.UpdateArchiveItself = true;
+  
+  options.Commands.Clear();
+  CUpdateArchiveCommand updateMainCommand;
+  updateMainCommand.ActionSet = defaultActionSet;
+  options.Commands.Add(updateMainCommand);
+  if(parser[NKey::kUpdate].ThereIs)
+    ParseUpdateCommandString(options, parser[NKey::kUpdate].PostStrings, 
+        defaultActionSet);
+  if(parser[NKey::kWorkingDir].ThereIs)
+  {
+    const UString &postString = parser[NKey::kWorkingDir].PostStrings[0];
+    if (postString.IsEmpty())
+      NDirectory::MyGetTempPath(options.WorkingDir);
+    else
+      options.WorkingDir = postString;
+  }
+  options.SfxMode = parser[NKey::kSfx].ThereIs;
+  if (options.SfxMode)
+    options.SfxModule = parser[NKey::kSfx].PostStrings[0];
+
+  if (parser[NKey::kVolume].ThereIs)
+  {
+    const UStringVector &sv = parser[NKey::kVolume].PostStrings;
+    for (int i = 0; i < sv.Size(); i++)
+    {
+      UInt64 size;
+      if (!ParseComplexSize(sv[i], size))
+        ThrowException("Incorrect volume size");
+      options.VolumesSizes.Add(size);
+    }
+  }
+}
+
+static void SetMethodOptions(const CParser &parser, CObjectVector<CProperty> &properties)
+{
+  if (parser[NKey::kProperty].ThereIs)
+  {
+    // options.MethodMode.Properties.Clear();
+    for(int i = 0; i < parser[NKey::kProperty].PostStrings.Size(); i++)
+    {
+      CProperty property;
+      const UString &postString = parser[NKey::kProperty].PostStrings[i];
+      int index = postString.Find(L'=');
+      if (index < 0)
+        property.Name = postString;
+      else
+      {
+        property.Name = postString.Left(index);
+        property.Value = postString.Mid(index + 1);
+      }
+      properties.Add(property);
+    }
+  }
+}
+
+CArchiveCommandLineParser::CArchiveCommandLineParser(): 
+  parser(sizeof(kSwitchForms) / sizeof(kSwitchForms[0])) {}
+
+void CArchiveCommandLineParser::Parse1(const UStringVector &commandStrings,
+    CArchiveCommandLineOptions &options)
+{
+  try
+  {
+    parser.ParseStrings(kSwitchForms, commandStrings);
+  }
+  catch(...) 
+  {
+    ThrowUserErrorException();
+  }
+
+  options.IsInTerminal = MY_IS_TERMINAL(stdin);
+  options.IsStdOutTerminal = MY_IS_TERMINAL(stdout);
+  options.IsStdErrTerminal = MY_IS_TERMINAL(stderr);
+  options.StdOutMode = parser[NKey::kStdOut].ThereIs;
+  options.EnableHeaders = !parser[NKey::kDisableHeaders].ThereIs;
+  options.HelpMode = parser[NKey::kHelp1].ThereIs || parser[NKey::kHelp2].ThereIs  || parser[NKey::kHelp3].ThereIs;
+
+  #ifdef _WIN32
+  options.LargePages = false;
+  if (parser[NKey::kLargePages].ThereIs)
+  {
+    const UString &postString = parser[NKey::kLargePages].PostStrings.Front();
+    if (postString.IsEmpty())
+      options.LargePages = true;
+  }
+  #endif
+}
+
+struct CCodePagePair
+{
+  const wchar_t *Name;
+  UINT CodePage;
+};
+
+static CCodePagePair g_CodePagePairs[] = 
+{
+  { L"UTF-8", CP_UTF8 },
+  { L"WIN",   CP_ACP },
+  { L"DOS",   CP_OEMCP }
+};
+
+static const int kNumCodePages = sizeof(g_CodePagePairs) / sizeof(g_CodePagePairs[0]);
+
+static bool ConvertStringToUInt32(const wchar_t *s, UInt32 &v)
+{
+  const wchar_t *end;
+  UInt64 number = ConvertStringToUInt64(s, &end);
+  if (*end != 0)
+    return false;
+  if (number > (UInt32)0xFFFFFFFF)
+    return false;
+  v = (UInt32)number;
+  return true;
+}
+
+void CArchiveCommandLineParser::Parse2(CArchiveCommandLineOptions &options)
+{
+  const UStringVector &nonSwitchStrings = parser.NonSwitchStrings;
+  int numNonSwitchStrings = nonSwitchStrings.Size();
+  if(numNonSwitchStrings < kMinNonSwitchWords)  
+    ThrowUserErrorException();
+
+  if (!ParseArchiveCommand(nonSwitchStrings[kCommandIndex], options.Command))
+    ThrowUserErrorException();
+
+  options.TechMode = parser[NKey::kTechMode].ThereIs;
+
+  if (parser[NKey::kCaseSensitive].ThereIs)
+    g_CaseSensitive = (parser[NKey::kCaseSensitive].PostCharIndex < 0);
+
+  NRecursedType::EEnum recursedType;
+  if (parser[NKey::kRecursed].ThereIs)
+    recursedType = GetRecursedTypeFromIndex(parser[NKey::kRecursed].PostCharIndex);
+  else
+    recursedType = NRecursedType::kNonRecursed;
+
+  UINT codePage = CP_UTF8;
+  if (parser[NKey::kCharSet].ThereIs)
+  {
+    UString name = parser[NKey::kCharSet].PostStrings.Front();
+    name.MakeUpper();
+    int i;
+    for (i = 0; i < kNumCodePages; i++)
+    {
+      const CCodePagePair &pair = g_CodePagePairs[i];
+      if (name.Compare(pair.Name) == 0)
+      {
+        codePage = pair.CodePage;
+        break;
+      }
+    }
+    if (i >= kNumCodePages)
+      ThrowUserErrorException();
+  }
+
+  bool thereAreSwitchIncludes = false;
+  if (parser[NKey::kInclude].ThereIs)
+  {
+    thereAreSwitchIncludes = true;
+    AddSwitchWildCardsToCensor(options.WildcardCensor, 
+        parser[NKey::kInclude].PostStrings, true, recursedType, codePage);
+  }
+  if (parser[NKey::kExclude].ThereIs)
+    AddSwitchWildCardsToCensor(options.WildcardCensor, 
+        parser[NKey::kExclude].PostStrings, false, recursedType, codePage);
+ 
+  int curCommandIndex = kCommandIndex + 1;
+  bool thereIsArchiveName = !parser[NKey::kNoArName].ThereIs && 
+      options.Command.CommandType != NCommandType::kBenchmark && 
+      options.Command.CommandType != NCommandType::kInfo;
+  if (thereIsArchiveName)
+  {
+    if(curCommandIndex >= numNonSwitchStrings)  
+      ThrowUserErrorException();
+    options.ArchiveName = nonSwitchStrings[curCommandIndex++];
+  }
+
+  AddToCensorFromNonSwitchesStrings(
+      curCommandIndex, options.WildcardCensor, 
+      nonSwitchStrings, recursedType, thereAreSwitchIncludes, codePage);
+
+  options.YesToAll = parser[NKey::kYes].ThereIs;
+
+  bool isExtractGroupCommand = options.Command.IsFromExtractGroup();
+
+  options.PasswordEnabled = parser[NKey::kPassword].ThereIs;
+
+  if(options.PasswordEnabled)
+    options.Password = parser[NKey::kPassword].PostStrings[0];
+
+  options.StdInMode = parser[NKey::kStdIn].ThereIs;
+  options.ShowDialog = parser[NKey::kShowDialog].ThereIs;
+
+  if(isExtractGroupCommand || options.Command.CommandType == NCommandType::kList)
+  {
+    if (options.StdInMode)
+      ThrowException("Reading archives from stdin is not implemented");
+    if (!options.WildcardCensor.AllAreRelative())
+      ThrowException("Cannot use absolute pathnames for this command");
+
+    NWildcard::CCensor archiveWildcardCensor;
+
+    if (parser[NKey::kArInclude].ThereIs)
+    {
+      AddSwitchWildCardsToCensor(archiveWildcardCensor, 
+        parser[NKey::kArInclude].PostStrings, true, NRecursedType::kNonRecursed, codePage);
+    }
+    if (parser[NKey::kArExclude].ThereIs)
+      AddSwitchWildCardsToCensor(archiveWildcardCensor, 
+      parser[NKey::kArExclude].PostStrings, false, NRecursedType::kNonRecursed, codePage);
+
+    if (thereIsArchiveName)
+      AddCommandLineWildCardToCensr(archiveWildcardCensor, options.ArchiveName, true, NRecursedType::kNonRecursed);
+
+    #ifdef _WIN32
+    ConvertToLongNames(archiveWildcardCensor);
+    #endif
+
+    archiveWildcardCensor.ExtendExclude();
+
+    CObjectVector<CDirItem> dirItems;
+    {
+      UStringVector errorPaths;
+      CRecordVector<DWORD> errorCodes;
+      HRESULT res = EnumerateItems(archiveWildcardCensor, dirItems, NULL, errorPaths, errorCodes);
+      if (res != S_OK || errorPaths.Size() > 0)
+        throw "cannot find archive";
+    }
+    UStringVector archivePaths;
+    int i;
+    for (i = 0; i < dirItems.Size(); i++)
+    {
+      const CDirItem &dirItem = dirItems[i];
+      if (!dirItem.IsDirectory())
+        archivePaths.Add(dirItem.FullPath);
+    }
+
+    if (archivePaths.Size() == 0)
+      throw "there is no such archive";
+
+    UStringVector archivePathsFull;
+
+    for (i = 0; i < archivePaths.Size(); i++)
+    {
+      UString fullPath;
+      NFile::NDirectory::MyGetFullPathName(archivePaths[i], fullPath);
+      archivePathsFull.Add(fullPath);
+    }
+    CIntVector indices;
+    SortFileNames(archivePathsFull, indices);
+    options.ArchivePathsSorted.Reserve(indices.Size());
+    options.ArchivePathsFullSorted.Reserve(indices.Size());
+    for (i = 0; i < indices.Size(); i++)
+    {
+      options.ArchivePathsSorted.Add(archivePaths[indices[i]]);
+      options.ArchivePathsFullSorted.Add(archivePathsFull[indices[i]]);
+    }
+
+    if (isExtractGroupCommand)
+    {
+      SetMethodOptions(parser, options.ExtractProperties); 
+      if (options.StdOutMode && options.IsStdOutTerminal && options.IsStdErrTerminal)
+        throw kSameTerminalError;
+      if(parser[NKey::kOutputDir].ThereIs)
+      {
+        options.OutputDir = parser[NKey::kOutputDir].PostStrings[0];
+        NFile::NName::NormalizeDirPathPrefix(options.OutputDir);
+      }
+
+      options.OverwriteMode = NExtract::NOverwriteMode::kAskBefore;
+      if(parser[NKey::kOverwrite].ThereIs)
+        options.OverwriteMode = 
+            k_OverwriteModes[parser[NKey::kOverwrite].PostCharIndex];
+      else if (options.YesToAll)
+        options.OverwriteMode = NExtract::NOverwriteMode::kWithoutPrompt;
+    }
+  }
+  else if(options.Command.IsFromUpdateGroup())
+  {
+    CUpdateOptions &updateOptions = options.UpdateOptions;
+
+    if(parser[NKey::kArchiveType].ThereIs)
+      options.ArcType = parser[NKey::kArchiveType].PostStrings[0];
+
+    SetAddCommandOptions(options.Command.CommandType, parser, updateOptions); 
+    
+    SetMethodOptions(parser, updateOptions.MethodMode.Properties); 
+
+    if (parser[NKey::kShareForWrite].ThereIs)
+      updateOptions.OpenShareForWrite = true;
+
+    options.EnablePercents = !parser[NKey::kDisablePercents].ThereIs;
+
+    if (options.EnablePercents)
+    {
+      if ((options.StdOutMode && !options.IsStdErrTerminal) || 
+         (!options.StdOutMode && !options.IsStdOutTerminal))  
+        options.EnablePercents = false;
+    }
+
+    updateOptions.EMailMode = parser[NKey::kEmail].ThereIs;
+    if (updateOptions.EMailMode)
+    {
+      updateOptions.EMailAddress = parser[NKey::kEmail].PostStrings.Front();
+      if (updateOptions.EMailAddress.Length() > 0)
+        if (updateOptions.EMailAddress[0] == L'.')
+        {
+          updateOptions.EMailRemoveAfter = true;
+          updateOptions.EMailAddress.Delete(0);
+        }
+    }
+
+    updateOptions.StdOutMode = options.StdOutMode;
+    updateOptions.StdInMode = options.StdInMode;
+
+    if (updateOptions.StdOutMode && updateOptions.EMailMode)
+      throw "stdout mode and email mode cannot be combined";
+    if (updateOptions.StdOutMode && options.IsStdOutTerminal)
+      throw kTerminalOutError;
+    if(updateOptions.StdInMode)
+      updateOptions.StdInFileName = parser[NKey::kStdIn].PostStrings.Front();
+
+    #ifdef _WIN32
+    ConvertToLongNames(options.WildcardCensor);
+    #endif
+  }
+  else if(options.Command.CommandType == NCommandType::kBenchmark)
+  {
+    options.NumThreads = (UInt32)-1;
+    options.DictionarySize = (UInt32)-1;
+    options.NumIterations = 1;
+    if (curCommandIndex < numNonSwitchStrings)  
+    {
+      if (!ConvertStringToUInt32(nonSwitchStrings[curCommandIndex++], options.NumIterations))
+        ThrowUserErrorException();
+    }
+    for (int i = 0; i < parser[NKey::kProperty].PostStrings.Size(); i++)
+    {
+      UString postString = parser[NKey::kProperty].PostStrings[i];
+      postString.MakeUpper();
+      if (postString.Length() < 2)
+        ThrowUserErrorException();
+      if (postString[0] == 'D')
+      {
+        int pos = 1;
+        if (postString[pos] == '=')
+          pos++;
+        UInt32 logSize;
+        if (!ConvertStringToUInt32((const wchar_t *)postString + pos, logSize))
+          ThrowUserErrorException();
+        if (logSize > 31)
+          ThrowUserErrorException();
+        options.DictionarySize = 1 << logSize;
+      }
+      else if (postString[0] == 'M' && postString[1] == 'T' )
+      {
+        int pos = 2;
+        if (postString[pos] == '=')
+          pos++;
+        if (postString[pos] != 0)
+          if (!ConvertStringToUInt32((const wchar_t *)postString + pos, options.NumThreads))
+            ThrowUserErrorException();
+      }
+      else if (postString[0] == 'M' && postString[1] == '=' )
+      {
+        int pos = 2;
+        if (postString[pos] != 0)
+          options.Method = postString.Mid(2);
+      }
+      else
+        ThrowUserErrorException();
+    }
+  }
+  else if(options.Command.CommandType == NCommandType::kInfo)
+  {
+  }
+  else 
+    ThrowUserErrorException();
+  options.WildcardCensor.ExtendExclude();
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/misc/libphysfs/lzma/CPP/7zip/UI/Common/ArchiveCommandLine.h	Mon Apr 10 12:06:43 2017 -0400
@@ -0,0 +1,104 @@
+// ArchiveCommandLine.h
+
+#ifndef __ARCHIVECOMMANDLINE_H
+#define __ARCHIVECOMMANDLINE_H
+
+#include "Common/Wildcard.h"
+#include "Common/CommandLineParser.h"
+
+#include "Extract.h"
+#include "Update.h"
+
+struct CArchiveCommandLineException: public AString
+{
+  CArchiveCommandLineException(const char *errorMessage): AString(errorMessage) {}
+};
+
+namespace NCommandType { enum EEnum
+{
+  kAdd = 0,
+  kUpdate,
+  kDelete,
+  kTest,
+  kExtract,
+  kFullExtract,
+  kList,
+  kBenchmark,
+  kInfo
+};}
+
+namespace NRecursedType { enum EEnum
+{
+  kRecursed,
+  kWildCardOnlyRecursed,
+  kNonRecursed
+};}
+
+struct CArchiveCommand
+{
+  NCommandType::EEnum CommandType;
+  bool IsFromExtractGroup() const;
+  bool IsFromUpdateGroup() const;
+  bool IsTestMode() const { return CommandType == NCommandType::kTest; }
+  NExtract::NPathMode::EEnum GetPathMode() const;
+};
+
+struct CArchiveCommandLineOptions
+{
+  bool HelpMode;
+
+  #ifdef _WIN32
+  bool LargePages;
+  #endif
+
+  bool IsInTerminal;
+  bool IsStdOutTerminal;
+  bool IsStdErrTerminal;
+  bool StdInMode;
+  bool StdOutMode;
+  bool EnableHeaders;
+
+  bool YesToAll;
+  bool ShowDialog;
+  // NWildcard::CCensor ArchiveWildcardCensor;
+  NWildcard::CCensor WildcardCensor;
+
+  CArchiveCommand Command; 
+  UString ArchiveName;
+
+  bool PasswordEnabled;
+  UString Password;
+
+  bool TechMode;
+  // Extract
+  bool AppendName;
+  UString OutputDir;
+  NExtract::NOverwriteMode::EEnum OverwriteMode;
+  UStringVector ArchivePathsSorted;
+  UStringVector ArchivePathsFullSorted;
+  CObjectVector<CProperty> ExtractProperties;
+
+  CUpdateOptions UpdateOptions;
+  UString ArcType;
+  bool EnablePercents;
+
+  // Benchmark 
+  UInt32 NumIterations;
+  UInt32 NumThreads;
+  UInt32 DictionarySize;
+  UString Method;
+
+
+  CArchiveCommandLineOptions(): StdInMode(false), StdOutMode(false) {};
+};
+
+class CArchiveCommandLineParser
+{
+  NCommandLineParser::CParser parser;
+public:
+  CArchiveCommandLineParser();
+  void Parse1(const UStringVector &commandStrings, CArchiveCommandLineOptions &options);
+  void Parse2(CArchiveCommandLineOptions &options);
+};
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/misc/libphysfs/lzma/CPP/7zip/UI/Common/ArchiveExtractCallback.cpp	Mon Apr 10 12:06:43 2017 -0400
@@ -0,0 +1,479 @@
+// ArchiveExtractCallback.cpp
+
+#include "StdAfx.h"
+
+#include "ArchiveExtractCallback.h"
+
+#include "Common/Wildcard.h"
+#include "Common/StringConvert.h"
+#include "Common/ComTry.h"
+
+#include "Windows/FileDir.h"
+#include "Windows/FileFind.h"
+#include "Windows/Time.h"
+#include "Windows/Defs.h"
+#include "Windows/PropVariant.h"
+
+#include "Windows/PropVariantConversions.h"
+
+#include "../../Common/FilePathAutoRename.h"
+
+#include "../Common/ExtractingFilePath.h"
+#include "OpenArchive.h"
+
+using namespace NWindows;
+
+static const wchar_t *kCantAutoRename = L"ERROR: Can not create file with auto name";
+static const wchar_t *kCantRenameFile = L"ERROR: Can not rename existing file ";
+static const wchar_t *kCantDeleteOutputFile = L"ERROR: Can not delete output file ";
+
+
+void CArchiveExtractCallback::Init(
+    IInArchive *archiveHandler,
+    IFolderArchiveExtractCallback *extractCallback2,
+    bool stdOutMode,
+    const UString &directoryPath, 
+    const UStringVector &removePathParts,
+    const UString &itemDefaultName,
+    const FILETIME &utcLastWriteTimeDefault,
+    UInt32 attributesDefault,
+    UInt64 packSize)
+{
+  _stdOutMode = stdOutMode;
+  _numErrors = 0;
+  _unpTotal = 1;
+  _packTotal = packSize;
+
+  _extractCallback2 = extractCallback2;
+  _compressProgress.Release();
+  _extractCallback2.QueryInterface(IID_ICompressProgressInfo, &_compressProgress);
+
+  LocalProgressSpec->Init(extractCallback2, true);
+  LocalProgressSpec->SendProgress = false;
+
+  _itemDefaultName = itemDefaultName;
+  _utcLastWriteTimeDefault = utcLastWriteTimeDefault;
+  _attributesDefault = attributesDefault;
+  _removePathParts = removePathParts;
+  _archiveHandler = archiveHandler;
+  _directoryPath = directoryPath;
+  NFile::NName::NormalizeDirPathPrefix(_directoryPath);
+}
+
+STDMETHODIMP CArchiveExtractCallback::SetTotal(UInt64 size)
+{
+  COM_TRY_BEGIN
+  _unpTotal = size;
+  if (!_multiArchives && _extractCallback2)
+    return _extractCallback2->SetTotal(size);
+  return S_OK;
+  COM_TRY_END
+}
+
+static void NormalizeVals(UInt64 &v1, UInt64 &v2)
+{
+  const UInt64 kMax = (UInt64)1 << 31;
+  while (v1 > kMax)
+  {
+    v1 >>= 1;
+    v2 >>= 1;
+  }
+}
+
+static UInt64 MyMultDiv64(UInt64 unpCur, UInt64 unpTotal, UInt64 packTotal)
+{
+  NormalizeVals(packTotal, unpTotal);
+  NormalizeVals(unpCur, unpTotal);
+  if (unpTotal == 0)
+    unpTotal = 1;
+  return unpCur * packTotal / unpTotal;
+}
+
+STDMETHODIMP CArchiveExtractCallback::SetCompleted(const UInt64 *completeValue)
+{
+  COM_TRY_BEGIN
+  if (!_extractCallback2)
+    return S_OK;
+
+  if (_multiArchives)
+  {
+    if (completeValue != NULL)
+    {
+      UInt64 packCur = LocalProgressSpec->InSize + MyMultDiv64(*completeValue, _unpTotal, _packTotal);
+      return _extractCallback2->SetCompleted(&packCur);
+    }
+  }
+  return _extractCallback2->SetCompleted(completeValue);
+  COM_TRY_END
+}
+
+STDMETHODIMP CArchiveExtractCallback::SetRatioInfo(const UInt64 *inSize, const UInt64 *outSize)
+{
+  COM_TRY_BEGIN
+  return _localProgress->SetRatioInfo(inSize, outSize);
+  COM_TRY_END
+}
+
+void CArchiveExtractCallback::CreateComplexDirectory(const UStringVector &dirPathParts, UString &fullPath)
+{
+  fullPath = _directoryPath;
+  for(int i = 0; i < dirPathParts.Size(); i++)
+  {
+    if (i > 0)
+      fullPath += wchar_t(NFile::NName::kDirDelimiter);
+    fullPath += dirPathParts[i];
+    NFile::NDirectory::MyCreateDirectory(fullPath);
+  }
+}
+
+static UString MakePathNameFromParts(const UStringVector &parts)
+{
+  UString result;
+  for(int i = 0; i < parts.Size(); i++)
+  {
+    if(i != 0)
+      result += wchar_t(NFile::NName::kDirDelimiter);
+    result += parts[i];
+  }
+  return result;
+}
+
+
+HRESULT CArchiveExtractCallback::GetTime(int index, PROPID propID, FILETIME &filetime, bool &filetimeIsDefined)
+{
+  filetimeIsDefined = false;
+  NCOM::CPropVariant prop;
+  RINOK(_archiveHandler->GetProperty(index, propID, &prop));
+  if (prop.vt == VT_FILETIME)
+  {
+    filetime = prop.filetime;
+    filetimeIsDefined = (filetime.dwHighDateTime != 0 || filetime.dwLowDateTime != 0);
+  }
+  else if (prop.vt != VT_EMPTY)
+    return E_FAIL;
+  return S_OK;
+}
+
+STDMETHODIMP CArchiveExtractCallback::GetStream(UInt32 index, ISequentialOutStream **outStream, Int32 askExtractMode)
+{
+  COM_TRY_BEGIN
+  *outStream = 0;
+  _outFileStream.Release();
+
+  _encrypted = false;
+  _isSplit = false;
+  _curSize = 0;
+
+  UString fullPath;
+
+  RINOK(GetArchiveItemPath(_archiveHandler, index, _itemDefaultName, fullPath));
+  RINOK(IsArchiveItemFolder(_archiveHandler, index, _processedFileInfo.IsDirectory));
+
+  _filePath = fullPath;
+
+  {
+    NCOM::CPropVariant prop;
+    RINOK(_archiveHandler->GetProperty(index, kpidPosition, &prop));
+    if (prop.vt != VT_EMPTY)
+    {
+      if (prop.vt != VT_UI8)
+        return E_FAIL;
+      _position = prop.uhVal.QuadPart;
+      _isSplit = true;
+    }
+  }
+    
+  RINOK(IsArchiveItemProp(_archiveHandler, index, kpidEncrypted, _encrypted));
+
+  bool newFileSizeDefined;
+  UInt64 newFileSize;
+  {
+    NCOM::CPropVariant prop;
+    RINOK(_archiveHandler->GetProperty(index, kpidSize, &prop));
+    newFileSizeDefined = (prop.vt != VT_EMPTY);
+    if (newFileSizeDefined)
+    {
+      newFileSize = ConvertPropVariantToUInt64(prop);
+      _curSize = newFileSize;
+    }
+  }
+
+  if(askExtractMode == NArchive::NExtract::NAskMode::kExtract)
+  {
+    if (_stdOutMode)
+    {
+      CMyComPtr<ISequentialOutStream> outStreamLoc = new CStdOutFileStream;
+      *outStream = outStreamLoc.Detach();
+      return S_OK;
+    }
+
+    {
+      NCOM::CPropVariant prop;
+      RINOK(_archiveHandler->GetProperty(index, kpidAttributes, &prop));
+      if (prop.vt == VT_EMPTY)
+      {
+        _processedFileInfo.Attributes = _attributesDefault;
+        _processedFileInfo.AttributesAreDefined = false;
+      }
+      else
+      {
+        if (prop.vt != VT_UI4)
+          return E_FAIL;
+        _processedFileInfo.Attributes = prop.ulVal;
+        _processedFileInfo.AttributesAreDefined = true;
+      }
+    }
+
+    RINOK(GetTime(index, kpidCreationTime, _processedFileInfo.CreationTime,
+        _processedFileInfo.IsCreationTimeDefined));
+    RINOK(GetTime(index, kpidLastWriteTime, _processedFileInfo.LastWriteTime, 
+        _processedFileInfo.IsLastWriteTimeDefined));
+    RINOK(GetTime(index, kpidLastAccessTime, _processedFileInfo.LastAccessTime,
+        _processedFileInfo.IsLastAccessTimeDefined));
+
+    bool isAnti = false;
+    RINOK(IsArchiveItemProp(_archiveHandler, index, kpidIsAnti, isAnti));
+
+    UStringVector pathParts; 
+    SplitPathToParts(fullPath, pathParts);
+    
+    if(pathParts.IsEmpty())
+      return E_FAIL;
+    int numRemovePathParts = 0;
+    switch(_pathMode)
+    {
+      case NExtract::NPathMode::kFullPathnames:
+        break;
+      case NExtract::NPathMode::kCurrentPathnames:
+      {
+        numRemovePathParts = _removePathParts.Size();
+        if (pathParts.Size() <= numRemovePathParts)
+          return E_FAIL;
+        for (int i = 0; i < numRemovePathParts; i++)
+          if (_removePathParts[i].CompareNoCase(pathParts[i]) != 0)
+            return E_FAIL;
+        break;
+      }
+      case NExtract::NPathMode::kNoPathnames:
+      {
+        numRemovePathParts = pathParts.Size() - 1;
+        break;
+      }
+    }
+    pathParts.Delete(0, numRemovePathParts);
+    MakeCorrectPath(pathParts);
+    UString processedPath = MakePathNameFromParts(pathParts);
+    if (!isAnti)
+    {
+      if (!_processedFileInfo.IsDirectory)
+      {
+        if (!pathParts.IsEmpty())
+          pathParts.DeleteBack();
+      }
+    
+      if (!pathParts.IsEmpty())
+      {
+        UString fullPathNew;
+        CreateComplexDirectory(pathParts, fullPathNew);
+        if (_processedFileInfo.IsDirectory)
+          NFile::NDirectory::SetDirTime(fullPathNew, 
+            (WriteCreated && _processedFileInfo.IsCreationTimeDefined) ? &_processedFileInfo.CreationTime : NULL, 
+            (WriteAccessed && _processedFileInfo.IsLastAccessTimeDefined) ? &_processedFileInfo.LastAccessTime : NULL, 
+            (WriteModified && _processedFileInfo.IsLastWriteTimeDefined) ? &_processedFileInfo.LastWriteTime : &_utcLastWriteTimeDefault);
+      }
+    }
+
+
+    UString fullProcessedPath = _directoryPath + processedPath;
+
+    if(_processedFileInfo.IsDirectory)
+    {
+      _diskFilePath = fullProcessedPath;
+      if (isAnti)
+        NFile::NDirectory::MyRemoveDirectory(_diskFilePath);
+      return S_OK;
+    }
+
+    if (!_isSplit)
+    {
+    NFile::NFind::CFileInfoW fileInfo;
+    if(NFile::NFind::FindFile(fullProcessedPath, fileInfo))
+    {
+      switch(_overwriteMode)
+      {
+        case NExtract::NOverwriteMode::kSkipExisting:
+          return S_OK;
+        case NExtract::NOverwriteMode::kAskBefore:
+        {
+          Int32 overwiteResult;
+          RINOK(_extractCallback2->AskOverwrite(
+              fullProcessedPath, &fileInfo.LastWriteTime, &fileInfo.Size, fullPath, 
+              _processedFileInfo.IsLastWriteTimeDefined ? &_processedFileInfo.LastWriteTime : NULL, 
+              newFileSizeDefined ? &newFileSize : NULL, 
+              &overwiteResult))
+
+          switch(overwiteResult)
+          {
+            case NOverwriteAnswer::kCancel:
+              return E_ABORT;
+            case NOverwriteAnswer::kNo:
+              return S_OK;
+            case NOverwriteAnswer::kNoToAll:
+              _overwriteMode = NExtract::NOverwriteMode::kSkipExisting;
+              return S_OK;
+            case NOverwriteAnswer::kYesToAll:
+              _overwriteMode = NExtract::NOverwriteMode::kWithoutPrompt;
+              break;
+            case NOverwriteAnswer::kYes:
+              break;
+            case NOverwriteAnswer::kAutoRename:
+              _overwriteMode = NExtract::NOverwriteMode::kAutoRename;
+              break;
+            default:
+              return E_FAIL;
+          }
+        }
+      }
+      if (_overwriteMode == NExtract::NOverwriteMode::kAutoRename)
+      {
+        if (!AutoRenamePath(fullProcessedPath))
+        {
+          UString message = UString(kCantAutoRename) + fullProcessedPath;
+          RINOK(_extractCallback2->MessageError(message));
+          return E_FAIL;
+        }
+      }
+      else if (_overwriteMode == NExtract::NOverwriteMode::kAutoRenameExisting)
+      {
+        UString existPath = fullProcessedPath;
+        if (!AutoRenamePath(existPath))
+        {
+          UString message = kCantAutoRename + fullProcessedPath;
+          RINOK(_extractCallback2->MessageError(message));
+          return E_FAIL;
+        }
+        if(!NFile::NDirectory::MyMoveFile(fullProcessedPath, existPath))
+        {
+          UString message = UString(kCantRenameFile) + fullProcessedPath;
+          RINOK(_extractCallback2->MessageError(message));
+          return E_FAIL;
+        }
+      }
+      else
+        if (!NFile::NDirectory::DeleteFileAlways(fullProcessedPath))
+        {
+          UString message = UString(kCantDeleteOutputFile) +  fullProcessedPath;
+          RINOK(_extractCallback2->MessageError(message));
+          return S_OK;
+          // return E_FAIL;
+        }
+    }
+    }
+    if (!isAnti)
+    {
+      _outFileStreamSpec = new COutFileStream;
+      CMyComPtr<ISequentialOutStream> outStreamLoc(_outFileStreamSpec);
+      if (!_outFileStreamSpec->Open(fullProcessedPath, _isSplit ? OPEN_ALWAYS: CREATE_ALWAYS))
+      {
+        // if (::GetLastError() != ERROR_FILE_EXISTS || !isSplit)
+        {
+          UString message = L"can not open output file " + fullProcessedPath;
+          RINOK(_extractCallback2->MessageError(message));
+          return S_OK;
+        }
+      }
+      if (_isSplit)
+      {
+        RINOK(_outFileStreamSpec->Seek(_position, STREAM_SEEK_SET, NULL));
+      }
+      _outFileStream = outStreamLoc;
+      *outStream = outStreamLoc.Detach();
+    }
+    _diskFilePath = fullProcessedPath;
+  }
+  else
+  {
+    *outStream = NULL;
+  }
+  return S_OK;
+  COM_TRY_END
+}
+
+STDMETHODIMP CArchiveExtractCallback::PrepareOperation(Int32 askExtractMode)
+{
+  COM_TRY_BEGIN
+  _extractMode = false;
+  switch (askExtractMode)
+  {
+    case NArchive::NExtract::NAskMode::kExtract:
+      _extractMode = true;
+  };
+  return _extractCallback2->PrepareOperation(_filePath, _processedFileInfo.IsDirectory, 
+      askExtractMode, _isSplit ? &_position: 0);
+  COM_TRY_END
+}
+
+STDMETHODIMP CArchiveExtractCallback::SetOperationResult(Int32 operationResult)
+{
+  COM_TRY_BEGIN
+  switch(operationResult)
+  {
+    case NArchive::NExtract::NOperationResult::kOK:
+    case NArchive::NExtract::NOperationResult::kUnSupportedMethod:
+    case NArchive::NExtract::NOperationResult::kCRCError:
+    case NArchive::NExtract::NOperationResult::kDataError:
+      break;
+    default:
+      _outFileStream.Release();
+      return E_FAIL;
+  }
+  if (_outFileStream != NULL)
+  {
+    _outFileStreamSpec->SetTime(
+        (WriteCreated && _processedFileInfo.IsCreationTimeDefined) ? &_processedFileInfo.CreationTime : NULL, 
+        (WriteAccessed && _processedFileInfo.IsLastAccessTimeDefined) ? &_processedFileInfo.LastAccessTime : NULL, 
+        (WriteModified && _processedFileInfo.IsLastWriteTimeDefined) ? &_processedFileInfo.LastWriteTime : &_utcLastWriteTimeDefault);
+    _curSize = _outFileStreamSpec->ProcessedSize;
+    RINOK(_outFileStreamSpec->Close());
+    _outFileStream.Release();
+  }
+  UnpackSize += _curSize;
+  if (_processedFileInfo.IsDirectory)
+    NumFolders++;
+  else
+    NumFiles++;
+
+  if (_extractMode && _processedFileInfo.AttributesAreDefined)
+    NFile::NDirectory::MySetFileAttributes(_diskFilePath, _processedFileInfo.Attributes);
+  RINOK(_extractCallback2->SetOperationResult(operationResult, _encrypted));
+  return S_OK;
+  COM_TRY_END
+}
+
+/*
+STDMETHODIMP CArchiveExtractCallback::GetInStream(
+    const wchar_t *name, ISequentialInStream **inStream)
+{
+  COM_TRY_BEGIN
+  CInFileStream *inFile = new CInFileStream;
+  CMyComPtr<ISequentialInStream> inStreamTemp = inFile;
+  if (!inFile->Open(_srcDirectoryPrefix + name))
+    return ::GetLastError();
+  *inStream = inStreamTemp.Detach();
+  return S_OK;
+  COM_TRY_END
+}
+*/
+
+STDMETHODIMP CArchiveExtractCallback::CryptoGetTextPassword(BSTR *password)
+{
+  COM_TRY_BEGIN
+  if (!_cryptoGetTextPassword)
+  {
+    RINOK(_extractCallback2.QueryInterface(IID_ICryptoGetTextPassword, 
+        &_cryptoGetTextPassword));
+  }
+  return _cryptoGetTextPassword->CryptoGetTextPassword(password);
+  COM_TRY_END
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/misc/libphysfs/lzma/CPP/7zip/UI/Common/ArchiveExtractCallback.h	Mon Apr 10 12:06:43 2017 -0400
@@ -0,0 +1,139 @@
+// ArchiveExtractCallback.h
+
+#ifndef __ARCHIVEEXTRACTCALLBACK_H
+#define __ARCHIVEEXTRACTCALLBACK_H
+
+#include "../../Archive/IArchive.h"
+#include "IFileExtractCallback.h"
+
+#include "Common/MyString.h"
+#include "Common/MyCom.h"
+
+#include "../../Common/FileStreams.h"
+#include "../../Common/ProgressUtils.h"
+#include "../../IPassword.h"
+
+#include "ExtractMode.h"
+
+class CArchiveExtractCallback: 
+  public IArchiveExtractCallback,
+  // public IArchiveVolumeExtractCallback,
+  public ICryptoGetTextPassword,
+  public ICompressProgressInfo,
+  public CMyUnknownImp
+{
+public:
+  MY_UNKNOWN_IMP2(ICryptoGetTextPassword, ICompressProgressInfo)
+  // COM_INTERFACE_ENTRY(IArchiveVolumeExtractCallback)
+
+  // IProgress
+  STDMETHOD(SetTotal)(UInt64 size);
+  STDMETHOD(SetCompleted)(const UInt64 *completeValue);
+  STDMETHOD(SetRatioInfo)(const UInt64 *inSize, const UInt64 *outSize);
+
+  // IExtractCallBack
+  STDMETHOD(GetStream)(UInt32 index, ISequentialOutStream **outStream, Int32 askExtractMode);
+  STDMETHOD(PrepareOperation)(Int32 askExtractMode);
+  STDMETHOD(SetOperationResult)(Int32 resultEOperationResult);
+
+  // IArchiveVolumeExtractCallback
+  // STDMETHOD(GetInStream)(const wchar_t *name, ISequentialInStream **inStream);
+
+  // ICryptoGetTextPassword
+  STDMETHOD(CryptoGetTextPassword)(BSTR *aPassword);
+
+private:
+  CMyComPtr<IInArchive> _archiveHandler;
+  CMyComPtr<IFolderArchiveExtractCallback> _extractCallback2;
+  CMyComPtr<ICompressProgressInfo> _compressProgress;
+  CMyComPtr<ICryptoGetTextPassword> _cryptoGetTextPassword;
+  UString _directoryPath;
+  NExtract::NPathMode::EEnum _pathMode;
+  NExtract::NOverwriteMode::EEnum _overwriteMode;
+
+  UString _filePath;
+  UInt64 _position;
+  bool _isSplit;
+
+  UString _diskFilePath;
+
+  bool _extractMode;
+
+  bool WriteModified;
+  bool WriteCreated;
+  bool WriteAccessed;
+
+  bool _encrypted;
+
+  struct CProcessedFileInfo
+  {
+    FILETIME CreationTime;
+    FILETIME LastWriteTime;
+    FILETIME LastAccessTime;
+    UInt32 Attributes;
+  
+    bool IsCreationTimeDefined;
+    bool IsLastWriteTimeDefined;
+    bool IsLastAccessTimeDefined;
+
+    bool IsDirectory;
+    bool AttributesAreDefined;
+  } _processedFileInfo;
+
+  UInt64 _curSize;
+  COutFileStream *_outFileStreamSpec;
+  CMyComPtr<ISequentialOutStream> _outFileStream;
+  UStringVector _removePathParts;
+
+  UString _itemDefaultName;
+  FILETIME _utcLastWriteTimeDefault;
+  UInt32 _attributesDefault;
+  bool _stdOutMode;
+
+  void CreateComplexDirectory(const UStringVector &dirPathParts, UString &fullPath);
+  HRESULT GetTime(int index, PROPID propID, FILETIME &filetime, bool &filetimeIsDefined);
+public:
+  CArchiveExtractCallback():
+      WriteModified(true),
+      WriteCreated(false),
+      WriteAccessed(false),
+      _multiArchives(false)
+  {
+    LocalProgressSpec = new CLocalProgress();
+    _localProgress = LocalProgressSpec;
+  }
+
+  CLocalProgress *LocalProgressSpec;
+  CMyComPtr<ICompressProgressInfo> _localProgress;
+  UInt64 _packTotal;
+  UInt64 _unpTotal;
+
+  bool _multiArchives;
+  UInt64 NumFolders;
+  UInt64 NumFiles;
+  UInt64 UnpackSize;
+  
+  void InitForMulti(bool multiArchives, 
+      NExtract::NPathMode::EEnum pathMode,
+      NExtract::NOverwriteMode::EEnum overwriteMode) 
+  { 
+    _multiArchives = multiArchives; NumFolders = NumFiles = UnpackSize = 0; 
+    _pathMode = pathMode;
+    _overwriteMode = overwriteMode;
+  }
+
+  void Init(
+      IInArchive *archiveHandler, 
+      IFolderArchiveExtractCallback *extractCallback2,
+      bool stdOutMode,
+      const UString &directoryPath,
+      const UStringVector &removePathParts,
+      const UString &itemDefaultName,
+      const FILETIME &utcLastWriteTimeDefault, 
+      UInt32 attributesDefault,
+      UInt64 packSize);
+
+  UInt64 _numErrors;
+};
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/misc/libphysfs/lzma/CPP/7zip/UI/Common/ArchiveName.cpp	Mon Apr 10 12:06:43 2017 -0400
@@ -0,0 +1,46 @@
+// ArchiveName.cpp
+
+#include "StdAfx.h"
+
+#include "Windows/FileFind.h"
+#include "Windows/FileDir.h"
+
+using namespace NWindows;
+
+UString CreateArchiveName(const UString &srcName, bool fromPrev, bool keepName)
+{
+  UString resultName = L"Archive";
+  if (fromPrev)
+  {
+    UString dirPrefix;
+    if (NFile::NDirectory::GetOnlyDirPrefix(srcName, dirPrefix))
+    {
+      if (dirPrefix.Length() > 0)
+        if (dirPrefix[dirPrefix.Length() - 1] == '\\')
+        {
+          dirPrefix.Delete(dirPrefix.Length() - 1);
+          NFile::NFind::CFileInfoW fileInfo;
+          if (NFile::NFind::FindFile(dirPrefix, fileInfo))
+            resultName = fileInfo.Name;
+        }
+    }
+  }
+  else
+  {
+    NFile::NFind::CFileInfoW fileInfo;
+    if (!NFile::NFind::FindFile(srcName, fileInfo))
+      return resultName;
+    resultName = fileInfo.Name;
+    if (!fileInfo.IsDirectory() && !keepName)
+    {
+      int dotPos = resultName.ReverseFind('.');
+      if (dotPos > 0)
+      {
+        UString archiveName2 = resultName.Left(dotPos);
+        if (archiveName2.ReverseFind('.') < 0)
+          resultName = archiveName2;
+      }
+    }
+  }
+  return resultName;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/misc/libphysfs/lzma/CPP/7zip/UI/Common/ArchiveName.h	Mon Apr 10 12:06:43 2017 -0400
@@ -0,0 +1,10 @@
+// ArchiveName.h
+
+#ifndef __ARCHIVENAME_H
+#define __ARCHIVENAME_H
+
+#include "Common/MyString.h"
+
+UString CreateArchiveName(const UString &srcName, bool fromPrev, bool keepName);
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/misc/libphysfs/lzma/CPP/7zip/UI/Common/ArchiveOpenCallback.cpp	Mon Apr 10 12:06:43 2017 -0400
@@ -0,0 +1,137 @@
+// ArchiveOpenCallback.cpp
+
+#include "StdAfx.h"
+
+#include "ArchiveOpenCallback.h"
+
+#include "Common/StringConvert.h"
+#include "Common/ComTry.h"
+#include "Windows/PropVariant.h"
+
+#include "../../Common/FileStreams.h"
+
+using namespace NWindows;
+
+STDMETHODIMP COpenCallbackImp::SetTotal(const UInt64 *files, const UInt64 *bytes)
+{
+  COM_TRY_BEGIN
+  if (!Callback)
+    return S_OK;
+  return Callback->SetTotal(files, bytes);
+  COM_TRY_END
+}
+
+STDMETHODIMP COpenCallbackImp::SetCompleted(const UInt64 *files, const UInt64 *bytes)
+{
+  COM_TRY_BEGIN
+  if (!Callback)
+    return S_OK;
+  return Callback->SetTotal(files, bytes);
+  COM_TRY_END
+}
+  
+STDMETHODIMP COpenCallbackImp::GetProperty(PROPID propID, PROPVARIANT *value)
+{
+  COM_TRY_BEGIN
+  NCOM::CPropVariant propVariant;
+  if (_subArchiveMode)
+  {
+    switch(propID)
+    {
+      case kpidName:
+        propVariant = _subArchiveName;
+        break;
+    }
+    propVariant.Detach(value);
+    return S_OK;
+  }
+  switch(propID)
+  {
+    case kpidName:
+      propVariant = _fileInfo.Name;
+      break;
+    case kpidIsFolder:
+      propVariant = _fileInfo.IsDirectory();
+      break;
+    case kpidSize:
+      propVariant = _fileInfo.Size;
+      break;
+    case kpidAttributes:
+      propVariant = (UInt32)_fileInfo.Attributes;
+      break;
+    case kpidLastAccessTime:
+      propVariant = _fileInfo.LastAccessTime;
+      break;
+    case kpidCreationTime:
+      propVariant = _fileInfo.CreationTime;
+      break;
+    case kpidLastWriteTime:
+      propVariant = _fileInfo.LastWriteTime;
+      break;
+    }
+  propVariant.Detach(value);
+  return S_OK;
+  COM_TRY_END
+}
+
+int COpenCallbackImp::FindName(const UString &name)
+{
+  for (int i = 0; i < FileNames.Size(); i++)
+    if (name.CompareNoCase(FileNames[i]) == 0)
+      return i;
+  return -1;
+}
+
+struct CInFileStreamVol: public CInFileStream
+{
+  UString Name;
+  COpenCallbackImp *OpenCallbackImp;
+  CMyComPtr<IArchiveOpenCallback> OpenCallbackRef;
+  ~CInFileStreamVol()
+  {
+    int index = OpenCallbackImp->FindName(Name);
+    if (index >= 0)
+      OpenCallbackImp->FileNames.Delete(index);
+  }
+};
+
+STDMETHODIMP COpenCallbackImp::GetStream(const wchar_t *name, IInStream **inStream)
+{
+  COM_TRY_BEGIN
+  if (_subArchiveMode)
+    return S_FALSE;
+  if (Callback)
+  {
+    RINOK(Callback->CheckBreak());
+  }
+  *inStream = NULL;
+  UString fullPath = _folderPrefix + name;
+  if (!NFile::NFind::FindFile(fullPath, _fileInfo))
+    return S_FALSE;
+  if (_fileInfo.IsDirectory())
+    return S_FALSE;
+  CInFileStreamVol *inFile = new CInFileStreamVol;
+  CMyComPtr<IInStream> inStreamTemp = inFile;
+  if (!inFile->Open(fullPath))
+    return ::GetLastError();
+  *inStream = inStreamTemp.Detach();
+  inFile->Name = name;
+  inFile->OpenCallbackImp = this;
+  inFile->OpenCallbackRef = this;
+  FileNames.Add(name);
+  TotalSize += _fileInfo.Size;
+  return S_OK;
+  COM_TRY_END
+}
+
+#ifndef _NO_CRYPTO
+STDMETHODIMP COpenCallbackImp::CryptoGetTextPassword(BSTR *password)
+{
+  COM_TRY_BEGIN
+  if (!Callback)
+    return E_NOTIMPL;
+  return Callback->CryptoGetTextPassword(password);
+  COM_TRY_END
+}
+#endif
+  
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/misc/libphysfs/lzma/CPP/7zip/UI/Common/ArchiveOpenCallback.h	Mon Apr 10 12:06:43 2017 -0400
@@ -0,0 +1,93 @@
+// ArchiveOpenCallback.h
+
+#ifndef __ARCHIVE_OPEN_CALLBACK_H
+#define __ARCHIVE_OPEN_CALLBACK_H
+
+#include "Common/MyString.h"
+#include "Common/MyCom.h"
+#include "Windows/FileFind.h"
+
+#ifndef _NO_CRYPTO
+#include "../../IPassword.h"
+#endif  
+#include "../../Archive/IArchive.h"
+
+struct IOpenCallbackUI
+{
+  virtual HRESULT CheckBreak() = 0;
+  virtual HRESULT SetTotal(const UInt64 *files, const UInt64 *bytes) = 0;
+  virtual HRESULT SetCompleted(const UInt64 *files, const UInt64 *bytes) = 0;
+  #ifndef _NO_CRYPTO
+  virtual HRESULT CryptoGetTextPassword(BSTR *password) = 0;
+  virtual HRESULT GetPasswordIfAny(UString &password) = 0;
+  virtual bool WasPasswordAsked() = 0;
+  virtual void ClearPasswordWasAskedFlag() = 0;
+  #endif  
+};
+
+class COpenCallbackImp: 
+  public IArchiveOpenCallback,
+  public IArchiveOpenVolumeCallback,
+  public IArchiveOpenSetSubArchiveName,
+  #ifndef _NO_CRYPTO
+  public ICryptoGetTextPassword,
+  #endif  
+  public CMyUnknownImp
+{
+public:
+  #ifndef _NO_CRYPTO
+  MY_UNKNOWN_IMP3(
+      IArchiveOpenVolumeCallback, 
+      ICryptoGetTextPassword,
+      IArchiveOpenSetSubArchiveName
+      )
+  #else
+  MY_UNKNOWN_IMP2(
+      IArchiveOpenVolumeCallback, 
+      IArchiveOpenSetSubArchiveName
+      )
+  #endif
+
+  STDMETHOD(SetTotal)(const UInt64 *files, const UInt64 *bytes);
+  STDMETHOD(SetCompleted)(const UInt64 *files, const UInt64 *bytes);
+
+  // IArchiveOpenVolumeCallback
+  STDMETHOD(GetProperty)(PROPID propID, PROPVARIANT *value);
+  STDMETHOD(GetStream)(const wchar_t *name, IInStream **inStream);
+
+  #ifndef _NO_CRYPTO
+  // ICryptoGetTextPassword
+  STDMETHOD(CryptoGetTextPassword)(BSTR *password);
+  #endif
+
+  STDMETHOD(SetSubArchiveName(const wchar_t *name))
+  {
+    _subArchiveMode = true;
+    _subArchiveName = name;
+    return  S_OK;
+  }
+
+private:
+  UString _folderPrefix;
+  NWindows::NFile::NFind::CFileInfoW _fileInfo;
+  bool _subArchiveMode;
+  UString _subArchiveName;
+public:
+  UStringVector FileNames;
+  IOpenCallbackUI *Callback;
+  UInt64 TotalSize;
+
+  COpenCallbackImp(): Callback(NULL) {}
+  void Init(const UString &folderPrefix,  const UString &fileName)
+  {
+    _folderPrefix = folderPrefix;
+    if (!NWindows::NFile::NFind::FindFile(_folderPrefix + fileName, _fileInfo))
+      throw 1;
+    FileNames.Clear();
+    _subArchiveMode = false;
+    TotalSize = 0;
+  }
+  int FindName(const UString &name);
+};
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/misc/libphysfs/lzma/CPP/7zip/UI/Common/DefaultName.cpp	Mon Apr 10 12:06:43 2017 -0400
@@ -0,0 +1,26 @@
+// DefaultName.cpp
+
+#include "StdAfx.h"
+
+#include "DefaultName.h"
+
+static const wchar_t *kEmptyFileAlias = L"[Content]";
+
+UString GetDefaultName2(const UString &fileName, 
+    const UString &extension, const UString &addSubExtension)
+{
+  int extLength = extension.Length();
+  int fileNameLength = fileName.Length();
+  if (fileNameLength > extLength + 1)
+  {
+    int dotPos = fileNameLength - (extLength + 1);
+    if (fileName[dotPos] == '.')
+      if (extension.CompareNoCase(fileName.Mid(dotPos + 1)) == 0)
+        return fileName.Left(dotPos) + addSubExtension;
+  }
+  int dotPos = fileName.ReverseFind(L'.');
+  if (dotPos > 0)
+    return fileName.Left(dotPos) + addSubExtension;
+  return kEmptyFileAlias;
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/misc/libphysfs/lzma/CPP/7zip/UI/Common/DefaultName.h	Mon Apr 10 12:06:43 2017 -0400
@@ -0,0 +1,11 @@
+// DefaultName.h
+
+#ifndef __DEFAULTNAME_H
+#define __DEFAULTNAME_H
+
+#include "Common/MyString.h"
+
+UString GetDefaultName2(const UString &fileName, 
+    const UString &extension, const UString &addSubExtension);
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/misc/libphysfs/lzma/CPP/7zip/UI/Common/DirItem.h	Mon Apr 10 12:06:43 2017 -0400
@@ -0,0 +1,34 @@
+// DirItem.h
+
+#ifndef __DIR_ITEM_H
+#define __DIR_ITEM_H
+
+#include "Common/MyString.h"
+#include "Common/Types.h"
+
+struct CDirItem
+{ 
+  UInt32 Attributes;
+  FILETIME CreationTime;
+  FILETIME LastAccessTime;
+  FILETIME LastWriteTime;
+  UInt64 Size;
+  UString Name;
+  UString FullPath;
+  bool IsDirectory() const { return (Attributes & FILE_ATTRIBUTE_DIRECTORY) != 0 ; }
+};
+
+struct CArchiveItem
+{ 
+  bool IsDirectory;
+  // DWORD Attributes;
+  // NWindows::NCOM::CPropVariant LastWriteTime;
+  FILETIME LastWriteTime;
+  bool SizeIsDefined;
+  UInt64 Size;
+  UString Name;
+  bool Censored;
+  int IndexInServer;
+};
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/misc/libphysfs/lzma/CPP/7zip/UI/Common/EnumDirItems.cpp	Mon Apr 10 12:06:43 2017 -0400
@@ -0,0 +1,281 @@
+// EnumDirItems.cpp
+
+#include "StdAfx.h"
+
+#include "Common/StringConvert.h"
+#include "Common/Wildcard.h"
+#include "Common/MyCom.h"
+
+#include "EnumDirItems.h"
+
+using namespace NWindows;
+using namespace NFile;
+using namespace NName;
+
+void AddDirFileInfo(
+    const UString &prefix,        // prefix for logical path
+    const UString &fullPathName,  // path on disk: can be relative to some basePrefix
+    const NFind::CFileInfoW &fileInfo, 
+    CObjectVector<CDirItem> &dirItems)
+{
+  CDirItem item;
+  item.Attributes = fileInfo.Attributes;
+  item.Size = fileInfo.Size;
+  item.CreationTime = fileInfo.CreationTime;
+  item.LastAccessTime = fileInfo.LastAccessTime;
+  item.LastWriteTime = fileInfo.LastWriteTime;
+  item.Name = prefix + fileInfo.Name;
+  item.FullPath = fullPathName;
+  dirItems.Add(item);
+}
+
+static void EnumerateDirectory(
+    const UString &baseFolderPrefix,  // base (disk) prefix for scanning  
+    const UString &directory,         // additional disk prefix starting from baseFolderPrefix
+    const UString &prefix,            // logical prefix
+    CObjectVector<CDirItem> &dirItems,
+    UStringVector &errorPaths,
+    CRecordVector<DWORD> &errorCodes)
+{
+  NFind::CEnumeratorW enumerator(baseFolderPrefix + directory + wchar_t(kAnyStringWildcard));
+  for (;;)
+  { 
+    NFind::CFileInfoW fileInfo;
+    bool found;
+    if (!enumerator.Next(fileInfo, found))
+    {
+      errorCodes.Add(::GetLastError());
+      errorPaths.Add(baseFolderPrefix + directory);
+      return;
+    }
+    if (!found)
+      break;
+    AddDirFileInfo(prefix, directory + fileInfo.Name, fileInfo, dirItems);
+    if (fileInfo.IsDirectory())
+    {
+      EnumerateDirectory(baseFolderPrefix, directory + fileInfo.Name + wchar_t(kDirDelimiter), 
+          prefix + fileInfo.Name + wchar_t(kDirDelimiter), dirItems, errorPaths, errorCodes);
+    }
+  }
+}
+
+void EnumerateDirItems(
+    const UString &baseFolderPrefix,   // base (disk) prefix for scanning  
+    const UStringVector &fileNames,    // names relative to baseFolderPrefix
+    const UString &archiveNamePrefix, 
+    CObjectVector<CDirItem> &dirItems,
+    UStringVector &errorPaths,
+    CRecordVector<DWORD> &errorCodes)
+{
+  for(int i = 0; i < fileNames.Size(); i++)
+  {
+    const UString &fileName = fileNames[i];
+    NFind::CFileInfoW fileInfo;
+    if (!NFind::FindFile(baseFolderPrefix + fileName, fileInfo))
+    {
+      errorCodes.Add(::GetLastError());
+      errorPaths.Add(baseFolderPrefix + fileName);
+      continue;
+    }
+    AddDirFileInfo(archiveNamePrefix, fileName, fileInfo, dirItems);
+    if (fileInfo.IsDirectory())
+    {
+      EnumerateDirectory(baseFolderPrefix, fileName + wchar_t(kDirDelimiter), 
+          archiveNamePrefix + fileInfo.Name +  wchar_t(kDirDelimiter), 
+          dirItems, errorPaths, errorCodes);
+    }
+  }
+}
+
+static HRESULT EnumerateDirItems(
+    const NWildcard::CCensorNode &curNode, 
+    const UString &diskPrefix,        // full disk path prefix 
+    const UString &archivePrefix,     // prefix from root
+    const UStringVector &addArchivePrefix,  // prefix from curNode
+    CObjectVector<CDirItem> &dirItems, 
+    bool enterToSubFolders,
+    IEnumDirItemCallback *callback,
+    UStringVector &errorPaths,
+    CRecordVector<DWORD> &errorCodes)
+{
+  if (!enterToSubFolders)
+    if (curNode.NeedCheckSubDirs())
+      enterToSubFolders = true;
+  if (callback)
+    RINOK(callback->CheckBreak());
+
+  // try direct_names case at first
+  if (addArchivePrefix.IsEmpty() && !enterToSubFolders)
+  {
+    // check that all names are direct
+    int i;
+    for (i = 0; i < curNode.IncludeItems.Size(); i++)
+    {
+      const NWildcard::CItem &item = curNode.IncludeItems[i];
+      if (item.Recursive || item.PathParts.Size() != 1)
+        break;
+      const UString &name = item.PathParts.Front();
+      if (name.IsEmpty() || DoesNameContainWildCard(name))
+        break;
+    }
+    if (i == curNode.IncludeItems.Size())
+    {
+      // all names are direct (no wildcards)
+      // so we don't need file_system's dir enumerator
+      CRecordVector<bool> needEnterVector;
+      for (i = 0; i < curNode.IncludeItems.Size(); i++)
+      {
+        const NWildcard::CItem &item = curNode.IncludeItems[i];
+        const UString &name = item.PathParts.Front();
+        const UString fullPath = diskPrefix + name;
+        NFind::CFileInfoW fileInfo;
+        if (!NFind::FindFile(fullPath, fileInfo))
+        {
+          errorCodes.Add(::GetLastError());
+          errorPaths.Add(fullPath);
+          continue;
+        }
+        bool isDir = fileInfo.IsDirectory();
+        if (isDir && !item.ForDir || !isDir && !item.ForFile)
+        {
+          errorCodes.Add((DWORD)E_FAIL);
+          errorPaths.Add(fullPath);
+          continue;
+        }
+        const UString realName = fileInfo.Name;
+        const UString realDiskPath = diskPrefix + realName;
+        {
+          UStringVector pathParts;
+          pathParts.Add(fileInfo.Name);
+          if (curNode.CheckPathToRoot(false, pathParts, !isDir))
+            continue;
+        }
+        AddDirFileInfo(archivePrefix, realDiskPath, fileInfo, dirItems);
+        if (!isDir)
+          continue;
+        
+        UStringVector addArchivePrefixNew;
+        const NWildcard::CCensorNode *nextNode = 0;
+        int index = curNode.FindSubNode(name);
+        if (index >= 0)
+        {
+          for (int t = needEnterVector.Size(); t <= index; t++)
+            needEnterVector.Add(true);
+          needEnterVector[index] = false;
+          nextNode = &curNode.SubNodes[index];
+        }
+        else
+        {
+          nextNode = &curNode;
+          addArchivePrefixNew.Add(name); // don't change it to realName. It's for shortnames support
+        }
+        RINOK(EnumerateDirItems(*nextNode,   
+            realDiskPath + wchar_t(kDirDelimiter), 
+            archivePrefix + realName + wchar_t(kDirDelimiter), 
+            addArchivePrefixNew, dirItems, true, callback, errorPaths, errorCodes));
+      }
+      for (i = 0; i < curNode.SubNodes.Size(); i++)
+      {
+        if (i < needEnterVector.Size())
+          if (!needEnterVector[i])
+            continue;
+        const NWildcard::CCensorNode &nextNode = curNode.SubNodes[i];
+        const UString fullPath = diskPrefix + nextNode.Name;
+        NFind::CFileInfoW fileInfo;
+        if (!NFind::FindFile(fullPath, fileInfo))
+        {
+          if (!nextNode.AreThereIncludeItems())
+            continue;
+          errorCodes.Add(::GetLastError());
+          errorPaths.Add(fullPath);
+          continue;
+        }
+        if (!fileInfo.IsDirectory())
+        {
+          errorCodes.Add((DWORD)E_FAIL);
+          errorPaths.Add(fullPath);
+          continue;
+        }
+        RINOK(EnumerateDirItems(nextNode, 
+            diskPrefix + fileInfo.Name + wchar_t(kDirDelimiter), 
+            archivePrefix + fileInfo.Name + wchar_t(kDirDelimiter), 
+            UStringVector(), dirItems, false, callback, errorPaths, errorCodes));
+      }
+      return S_OK;
+    }
+  }
+
+
+  NFind::CEnumeratorW enumerator(diskPrefix + wchar_t(kAnyStringWildcard));
+  for (;;)
+  {
+    NFind::CFileInfoW fileInfo;
+    bool found;
+    if (!enumerator.Next(fileInfo, found))
+    {
+      errorCodes.Add(::GetLastError());
+      errorPaths.Add(diskPrefix);
+      break;
+    }
+    if (!found)
+      break;
+
+    if (callback)
+      RINOK(callback->CheckBreak());
+    const UString &name = fileInfo.Name;
+    bool enterToSubFolders2 = enterToSubFolders;
+    UStringVector addArchivePrefixNew = addArchivePrefix;
+    addArchivePrefixNew.Add(name);
+    {
+      UStringVector addArchivePrefixNewTemp(addArchivePrefixNew);
+      if (curNode.CheckPathToRoot(false, addArchivePrefixNewTemp, !fileInfo.IsDirectory()))
+        continue;
+    }
+    if (curNode.CheckPathToRoot(true, addArchivePrefixNew, !fileInfo.IsDirectory()))
+    {
+      AddDirFileInfo(archivePrefix, diskPrefix + name, fileInfo, dirItems);
+      if (fileInfo.IsDirectory())
+        enterToSubFolders2 = true;
+    }
+    if (!fileInfo.IsDirectory())
+      continue;
+
+    const NWildcard::CCensorNode *nextNode = 0;
+    if (addArchivePrefix.IsEmpty())
+    {
+      int index = curNode.FindSubNode(name);
+      if (index >= 0)
+        nextNode = &curNode.SubNodes[index];
+    }
+    if (!enterToSubFolders2 && nextNode == 0)
+      continue;
+
+    addArchivePrefixNew = addArchivePrefix;
+    if (nextNode == 0)
+    {
+      nextNode = &curNode;
+      addArchivePrefixNew.Add(name);
+    }
+    RINOK(EnumerateDirItems(*nextNode,   
+        diskPrefix + name + wchar_t(kDirDelimiter), 
+        archivePrefix + name + wchar_t(kDirDelimiter), 
+        addArchivePrefixNew, dirItems, enterToSubFolders2, callback, errorPaths, errorCodes));
+  }
+  return S_OK;
+}
+
+HRESULT EnumerateItems(
+    const NWildcard::CCensor &censor, 
+    CObjectVector<CDirItem> &dirItems, 
+    IEnumDirItemCallback *callback,
+    UStringVector &errorPaths,
+    CRecordVector<DWORD> &errorCodes)
+{
+  for (int i = 0; i < censor.Pairs.Size(); i++)
+  {
+    const NWildcard::CPair &pair = censor.Pairs[i];
+    RINOK(EnumerateDirItems(pair.Head, pair.Prefix, L"", UStringVector(), dirItems, false, 
+        callback, errorPaths, errorCodes));
+  }
+  return S_OK;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/misc/libphysfs/lzma/CPP/7zip/UI/Common/EnumDirItems.h	Mon Apr 10 12:06:43 2017 -0400
@@ -0,0 +1,39 @@
+// EnumDirItems.h
+
+#ifndef __ENUM_DIR_ITEMS_H
+#define __ENUM_DIR_ITEMS_H
+
+#include "Common/Wildcard.h"
+#include "DirItem.h"
+
+#include "Windows/FileFind.h"
+
+void AddDirFileInfo(
+    const UString &prefix, 
+    const UString &fullPathName,
+    const NWindows::NFile::NFind::CFileInfoW &fileInfo, 
+    CObjectVector<CDirItem> &dirItems);
+
+
+void EnumerateDirItems(
+    const UString &baseFolderPrefix,
+    const UStringVector &fileNames,
+    const UString &archiveNamePrefix, 
+    CObjectVector<CDirItem> &dirItems, 
+    UStringVector &errorPaths,
+    CRecordVector<DWORD> &errorCodes);
+
+struct IEnumDirItemCallback
+{
+  virtual HRESULT CheckBreak() { return  S_OK; }
+};
+
+
+HRESULT EnumerateItems(
+    const NWildcard::CCensor &censor, 
+    CObjectVector<CDirItem> &dirItems, 
+    IEnumDirItemCallback *callback, 
+    UStringVector &errorPaths,
+    CRecordVector<DWORD> &errorCodes);
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/misc/libphysfs/lzma/CPP/7zip/UI/Common/ExitCode.h	Mon Apr 10 12:06:43 2017 -0400
@@ -0,0 +1,27 @@
+// ExitCode.h
+
+#ifndef __EXIT_CODE_H
+#define __EXIT_CODE_H
+
+namespace NExitCode {
+
+enum EEnum {
+
+  kSuccess       = 0,     // Successful operation
+  kWarning       = 1,     // Non fatal error(s) occurred
+  kFatalError    = 2,     // A fatal error occurred
+  // kCRCError      = 3,     // A CRC error occurred when unpacking     
+  // kLockedArchive = 4,     // Attempt to modify an archive previously locked
+  // kWriteError    = 5,     // Write to disk error
+  // kOpenError     = 6,     // Open file error
+  kUserError     = 7,     // Command line option error
+  kMemoryError   = 8,     // Not enough memory for operation
+  // kCreateFileError = 9,     // Create file error
+  
+  kUserBreak     = 255   // User stopped the process
+
+};
+
+}
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/misc/libphysfs/lzma/CPP/7zip/UI/Common/Extract.cpp	Mon Apr 10 12:06:43 2017 -0400
@@ -0,0 +1,187 @@
+// Extract.cpp
+
+#include "StdAfx.h"
+
+#include "Extract.h"
+
+#include "Windows/Defs.h"
+#include "Windows/FileDir.h"
+
+#include "OpenArchive.h"
+#include "SetProperties.h"
+
+using namespace NWindows;
+
+HRESULT DecompressArchive(
+    IInArchive *archive,
+    UInt64 packSize,
+    const UString &defaultName,
+    const NWildcard::CCensorNode &wildcardCensor,
+    const CExtractOptions &options,
+    IExtractCallbackUI *callback,
+    CArchiveExtractCallback *extractCallbackSpec,
+    UString &errorMessage)
+{
+  CRecordVector<UInt32> realIndices;
+  UInt32 numItems;
+  RINOK(archive->GetNumberOfItems(&numItems));
+
+  for(UInt32 i = 0; i < numItems; i++)
+  {
+    UString filePath;
+    RINOK(GetArchiveItemPath(archive, i, options.DefaultItemName, filePath));
+    bool isFolder;
+    RINOK(IsArchiveItemFolder(archive, i, isFolder));
+    if (!wildcardCensor.CheckPath(filePath, !isFolder))
+      continue;
+    realIndices.Add(i);
+  }
+  if (realIndices.Size() == 0)
+  {
+    callback->ThereAreNoFiles();
+    return S_OK;
+  }
+
+  UStringVector removePathParts;
+
+  UString outDir = options.OutputDir;
+  outDir.Replace(L"*", defaultName);
+  if(!outDir.IsEmpty())
+    if(!NFile::NDirectory::CreateComplexDirectory(outDir))
+    {
+      HRESULT res = ::GetLastError();
+      if (res == S_OK)
+        res = E_FAIL;
+      errorMessage = ((UString)L"Can not create output directory ") + outDir;
+      return res;
+    }
+
+  extractCallbackSpec->Init(
+      archive, 
+      callback,
+      options.StdOutMode,
+      outDir, 
+      removePathParts, 
+      options.DefaultItemName, 
+      options.ArchiveFileInfo.LastWriteTime,
+      options.ArchiveFileInfo.Attributes,
+      packSize);
+
+  #ifdef COMPRESS_MT
+  RINOK(SetProperties(archive, options.Properties));
+  #endif
+
+  HRESULT result = archive->Extract(&realIndices.Front(), 
+    realIndices.Size(), options.TestMode? 1: 0, extractCallbackSpec);
+
+  return callback->ExtractResult(result);
+}
+
+HRESULT DecompressArchives(
+    CCodecs *codecs,
+    UStringVector &archivePaths, UStringVector &archivePathsFull,    
+    const NWildcard::CCensorNode &wildcardCensor,
+    const CExtractOptions &optionsSpec,
+    IOpenCallbackUI *openCallback,
+    IExtractCallbackUI *extractCallback, 
+    UString &errorMessage, 
+    CDecompressStat &stat)
+{
+  stat.Clear();
+  CExtractOptions options = optionsSpec;
+  int i;
+  UInt64 totalPackSize = 0;
+  CRecordVector<UInt64> archiveSizes;
+  for (i = 0; i < archivePaths.Size(); i++)
+  {
+    const UString &archivePath = archivePaths[i];
+    NFile::NFind::CFileInfoW archiveFileInfo;
+    if (!NFile::NFind::FindFile(archivePath, archiveFileInfo))
+      throw "there is no such archive";
+    if (archiveFileInfo.IsDirectory())
+      throw "can't decompress folder";
+    archiveSizes.Add(archiveFileInfo.Size);
+    totalPackSize += archiveFileInfo.Size;
+  }
+  CArchiveExtractCallback *extractCallbackSpec = new CArchiveExtractCallback;
+  CMyComPtr<IArchiveExtractCallback> ec(extractCallbackSpec);
+  bool multi = (archivePaths.Size() > 1);
+  extractCallbackSpec->InitForMulti(multi, options.PathMode, options.OverwriteMode);
+  if (multi)
+  {
+    RINOK(extractCallback->SetTotal(totalPackSize));  
+  }
+  for (i = 0; i < archivePaths.Size(); i++)
+  {
+    const UString &archivePath = archivePaths[i];
+    NFile::NFind::CFileInfoW archiveFileInfo;
+    if (!NFile::NFind::FindFile(archivePath, archiveFileInfo))
+      throw "there is no such archive";
+
+    if (archiveFileInfo.IsDirectory())
+      throw "there is no such archive";
+
+    options.ArchiveFileInfo = archiveFileInfo;
+
+    #ifndef _NO_CRYPTO
+    openCallback->ClearPasswordWasAskedFlag();
+    #endif
+
+    RINOK(extractCallback->BeforeOpen(archivePath));
+    CArchiveLink archiveLink;
+    HRESULT result = MyOpenArchive(codecs, archivePath, archiveLink, openCallback);
+
+    bool crypted = false;
+    #ifndef _NO_CRYPTO
+    crypted = openCallback->WasPasswordAsked();
+    #endif
+
+    RINOK(extractCallback->OpenResult(archivePath, result, crypted));
+    if (result != S_OK)
+      continue;
+
+    for (int v = 0; v < archiveLink.VolumePaths.Size(); v++)
+    {
+      int index = archivePathsFull.FindInSorted(archiveLink.VolumePaths[v]);
+      if (index >= 0 && index > i)
+      {
+        archivePaths.Delete(index);
+        archivePathsFull.Delete(index);
+        totalPackSize -= archiveSizes[index];
+        archiveSizes.Delete(index);
+      }
+    }
+    if (archiveLink.VolumePaths.Size() != 0)
+    {
+      totalPackSize += archiveLink.VolumesSize;
+      RINOK(extractCallback->SetTotal(totalPackSize));  
+    }
+
+    #ifndef _NO_CRYPTO
+    UString password;
+    RINOK(openCallback->GetPasswordIfAny(password));
+    if (!password.IsEmpty())
+    {
+      RINOK(extractCallback->SetPassword(password));
+    }
+    #endif
+
+    options.DefaultItemName = archiveLink.GetDefaultItemName();
+    RINOK(DecompressArchive(
+        archiveLink.GetArchive(), 
+        archiveFileInfo.Size + archiveLink.VolumesSize,
+        archiveLink.GetDefaultItemName(),
+        wildcardCensor, options, extractCallback, extractCallbackSpec, errorMessage));
+    extractCallbackSpec->LocalProgressSpec->InSize += archiveFileInfo.Size + 
+        archiveLink.VolumesSize;
+    extractCallbackSpec->LocalProgressSpec->OutSize = extractCallbackSpec->UnpackSize;
+    if (!errorMessage.IsEmpty())
+      return E_FAIL;
+  }
+  stat.NumFolders = extractCallbackSpec->NumFolders;
+  stat.NumFiles = extractCallbackSpec->NumFiles;
+  stat.UnpackSize = extractCallbackSpec->UnpackSize;
+  stat.NumArchives = archivePaths.Size();
+  stat.PackSize = extractCallbackSpec->LocalProgressSpec->InSize;
+  return S_OK;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/misc/libphysfs/lzma/CPP/7zip/UI/Common/Extract.h	Mon Apr 10 12:06:43 2017 -0400
@@ -0,0 +1,77 @@
+// Extract.h
+
+#ifndef __EXTRACT_H
+#define __EXTRACT_H
+
+#include "Common/Wildcard.h"
+#include "Windows/FileFind.h"
+
+#include "../../Archive/IArchive.h"
+
+#include "ArchiveExtractCallback.h"
+#include "ArchiveOpenCallback.h"
+#include "ExtractMode.h"
+#include "Property.h"
+
+#include "../Common/LoadCodecs.h"
+
+class CExtractOptions
+{
+public:
+  bool StdOutMode;
+  bool TestMode;
+  NExtract::NPathMode::EEnum PathMode;
+
+  UString OutputDir;
+  bool YesToAll;
+  UString DefaultItemName;
+  NWindows::NFile::NFind::CFileInfoW ArchiveFileInfo;
+  
+  // bool ShowDialog;
+  // bool PasswordEnabled;
+  // UString Password;
+  #ifdef COMPRESS_MT
+  CObjectVector<CProperty> Properties;
+  #endif
+
+  NExtract::NOverwriteMode::EEnum OverwriteMode;
+
+  #ifdef EXTERNAL_CODECS
+  CCodecs *Codecs;
+  #endif
+
+  CExtractOptions(): 
+      StdOutMode(false), 
+      YesToAll(false), 
+      TestMode(false),
+      PathMode(NExtract::NPathMode::kFullPathnames),
+      OverwriteMode(NExtract::NOverwriteMode::kAskBefore)
+      {}
+
+  /*
+    bool FullPathMode() const { return (ExtractMode == NExtractMode::kTest) || 
+    (ExtractMode == NExtractMode::kFullPath); }
+  */
+};
+
+struct CDecompressStat
+{
+  UInt64 NumArchives;
+  UInt64 UnpackSize;
+  UInt64 PackSize;
+  UInt64 NumFolders;
+  UInt64 NumFiles;
+  void Clear() { NumArchives = PackSize = UnpackSize = NumFolders = NumFiles = 0; }
+};
+
+HRESULT DecompressArchives(
+    CCodecs *codecs,
+    UStringVector &archivePaths, UStringVector &archivePathsFull,
+    const NWildcard::CCensorNode &wildcardCensor,
+    const CExtractOptions &options,
+    IOpenCallbackUI *openCallback,
+    IExtractCallbackUI *extractCallback,
+    UString &errorMessage, 
+    CDecompressStat &stat);
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/misc/libphysfs/lzma/CPP/7zip/UI/Common/ExtractMode.h	Mon Apr 10 12:06:43 2017 -0400
@@ -0,0 +1,31 @@
+// ExtractMode.h
+
+#ifndef __EXTRACT_MODE_H
+#define __EXTRACT_MODE_H
+
+namespace NExtract {
+  
+  namespace NPathMode
+  {
+    enum EEnum
+    {
+      kFullPathnames,
+      kCurrentPathnames,
+      kNoPathnames
+    };
+  }
+  
+  namespace NOverwriteMode
+  {
+    enum EEnum
+    {
+      kAskBefore,
+      kWithoutPrompt,
+      kSkipExisting,
+      kAutoRename,
+      kAutoRenameExisting
+    };
+  }
+}  
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/misc/libphysfs/lzma/CPP/7zip/UI/Common/ExtractingFilePath.cpp	Mon Apr 10 12:06:43 2017 -0400
@@ -0,0 +1,96 @@
+// ExtractingFilePath.cpp
+
+#include "StdAfx.h"
+#include "ExtractingFilePath.h"
+
+static UString ReplaceIncorrectChars(const UString &s)
+{
+  #ifdef _WIN32
+  UString res;
+  for (int i = 0; i < s.Length(); i++)
+  {
+    wchar_t c = s[i];
+    if (c < 0x20 || c == '*' || c == '?' || c == '<' || c == '>'  || c == '|' || c == ':' || c == '"')
+      c = '_';
+    res += c;
+  }
+  return res;
+  #else
+  return s;
+  #endif
+}
+
+#ifdef _WIN32
+static const wchar_t *g_ReservedNames[] =
+{
+  L"CON", L"PRN", L"AUX", L"NUL"
+};
+
+static bool CheckTail(const UString &name, int len)
+{
+  int dotPos = name.Find(L'.');
+  if (dotPos < 0)
+    dotPos = name.Length();
+  UString s = name.Left(dotPos);
+  s.TrimRight();
+  return (s.Length() != len);
+}
+
+static bool CheckNameNum(const UString &name, const wchar_t *reservedName)
+{
+  int len = MyStringLen(reservedName);
+  if (name.Length() <= len)
+    return true;
+  if (name.Left(len).CompareNoCase(reservedName) != 0)
+    return true;
+  wchar_t c = name[len];
+  if (c < L'0' || c > L'9')
+    return true;
+  return CheckTail(name, len + 1);
+}
+
+static bool IsSupportedName(const UString &name)
+{
+  for (int i = 0; i < sizeof(g_ReservedNames) / sizeof(g_ReservedNames[0]); i++)
+  {
+    const wchar_t *reservedName = g_ReservedNames[i];
+    int len = MyStringLen(reservedName);
+    if (name.Length() < len)
+      continue;
+    if (name.Left(len).CompareNoCase(reservedName) != 0)
+      continue;
+    if (!CheckTail(name, len))
+      return false;
+  }
+  if (!CheckNameNum(name, L"COM"))
+    return false;
+  return CheckNameNum(name, L"LPT");
+}
+#endif
+
+static UString GetCorrectFileName(const UString &path)
+{
+  if (path == L".." || path == L".")
+    return UString();
+  return ReplaceIncorrectChars(path);
+}
+
+void MakeCorrectPath(UStringVector &pathParts)
+{
+  for (int i = 0; i < pathParts.Size();)
+  {
+    UString &s = pathParts[i];
+    s = GetCorrectFileName(s);
+    if (s.IsEmpty())
+      pathParts.Delete(i);
+    else
+    {
+      #ifdef _WIN32
+      if (!IsSupportedName(s))
+        s = (UString)L"_" + s;
+      #endif
+      i++;
+    }
+  }
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/misc/libphysfs/lzma/CPP/7zip/UI/Common/ExtractingFilePath.h	Mon Apr 10 12:06:43 2017 -0400
@@ -0,0 +1,10 @@
+// ExtractingFilePath.h
+
+#ifndef __EXTRACTINGFILEPATH_H
+#define __EXTRACTINGFILEPATH_H
+
+#include "Common/MyString.h"
+
+void MakeCorrectPath(UStringVector &pathParts);
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/misc/libphysfs/lzma/CPP/7zip/UI/Common/IFileExtractCallback.h	Mon Apr 10 12:06:43 2017 -0400
@@ -0,0 +1,43 @@
+// IFileExtractCallback.h
+
+#ifndef __IFILEEXTRACTCALLBACK_H
+#define __IFILEEXTRACTCALLBACK_H
+
+#include "Common/MyString.h"
+#include "../../IDecl.h"
+
+namespace NOverwriteAnswer
+{
+  enum EEnum
+  {
+    kYes,
+    kYesToAll,
+    kNo,
+    kNoToAll,
+    kAutoRename,
+    kCancel
+  };
+}
+
+DECL_INTERFACE_SUB(IFolderArchiveExtractCallback, IProgress, 0x01, 0x07)
+{
+public:
+  STDMETHOD(AskOverwrite)(
+      const wchar_t *existName, const FILETIME *existTime, const UInt64 *existSize,
+      const wchar_t *newName, const FILETIME *newTime, const UInt64 *newSize,
+      Int32 *answer) PURE;
+  STDMETHOD(PrepareOperation)(const wchar_t *name, bool isFolder, Int32 askExtractMode, const UInt64 *position) PURE;
+  STDMETHOD(MessageError)(const wchar_t *message) PURE;
+  STDMETHOD(SetOperationResult)(Int32 operationResult, bool encrypted) PURE;
+};
+
+struct IExtractCallbackUI: IFolderArchiveExtractCallback
+{
+  virtual HRESULT BeforeOpen(const wchar_t *name) = 0;
+  virtual HRESULT OpenResult(const wchar_t *name, HRESULT result, bool encrypted) = 0;
+  virtual HRESULT ThereAreNoFiles() = 0;
+  virtual HRESULT ExtractResult(HRESULT result) = 0;
+  virtual HRESULT SetPassword(const UString &password) = 0;
+};
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/misc/libphysfs/lzma/CPP/7zip/UI/Common/LoadCodecs.cpp	Mon Apr 10 12:06:43 2017 -0400
@@ -0,0 +1,644 @@
+// LoadCodecs.cpp
+
+#include "StdAfx.h"
+
+#include "LoadCodecs.h"
+
+#include "../../../Common/MyCom.h"
+#ifdef NEW_FOLDER_INTERFACE
+#include "../../../Common/StringToInt.h"
+#endif
+#include "../../../Windows/PropVariant.h"
+
+#include "../../ICoder.h"
+#include "../../Common/RegisterArc.h"
+
+#ifdef EXTERNAL_CODECS
+#include "../../../Windows/FileFind.h"
+#include "../../../Windows/DLL.h"
+#ifdef NEW_FOLDER_INTERFACE
+#include "../../../Windows/ResourceString.h"
+static const UINT kIconTypesResId = 100;
+#endif
+
+#ifdef _WIN32
+#include "Windows/Registry.h"
+#endif
+
+using namespace NWindows;
+using namespace NFile;
+
+#ifdef _WIN32
+extern HINSTANCE g_hInstance;
+#endif
+
+static CSysString GetLibraryFolderPrefix()
+{
+  #ifdef _WIN32
+  TCHAR fullPath[MAX_PATH + 1];
+  ::GetModuleFileName(g_hInstance, fullPath, MAX_PATH);
+  CSysString path = fullPath;
+  int pos = path.ReverseFind(TEXT(CHAR_PATH_SEPARATOR));
+  return path.Left(pos + 1);
+  #else
+  return CSysString(); // FIX IT
+  #endif
+}
+
+#define kCodecsFolderName TEXT("Codecs")
+#define kFormatsFolderName TEXT("Formats")
+static TCHAR *kMainDll = TEXT("7z.dll");
+
+#ifdef _WIN32
+static LPCTSTR kRegistryPath = TEXT("Software\\7-zip");
+static LPCTSTR kProgramPathValue = TEXT("Path");
+static bool ReadPathFromRegistry(HKEY baseKey, CSysString &path)
+{
+  NRegistry::CKey key;
+  if(key.Open(baseKey, kRegistryPath, KEY_READ) == ERROR_SUCCESS)
+    if (key.QueryValue(kProgramPathValue, path) == ERROR_SUCCESS)
+    {
+      NName::NormalizeDirPathPrefix(path);
+      return true;
+    }
+  return false;
+}
+
+#endif
+
+CSysString GetBaseFolderPrefixFromRegistry()
+{
+  CSysString moduleFolderPrefix = GetLibraryFolderPrefix();
+  NFind::CFileInfo fileInfo;
+  if (NFind::FindFile(moduleFolderPrefix + kMainDll, fileInfo))
+    if (!fileInfo.IsDirectory())
+      return moduleFolderPrefix;
+  if (NFind::FindFile(moduleFolderPrefix + kCodecsFolderName, fileInfo))
+    if (fileInfo.IsDirectory())
+      return moduleFolderPrefix;
+  if (NFind::FindFile(moduleFolderPrefix + kFormatsFolderName, fileInfo))
+    if (fileInfo.IsDirectory())
+      return moduleFolderPrefix;
+  #ifdef _WIN32
+  CSysString path;
+  if (ReadPathFromRegistry(HKEY_CURRENT_USER, path))
+    return path;
+  if (ReadPathFromRegistry(HKEY_LOCAL_MACHINE, path))
+    return path;
+  #endif
+  return moduleFolderPrefix;
+}
+
+typedef UInt32 (WINAPI *GetNumberOfMethodsFunc)(UInt32 *numMethods);
+typedef UInt32 (WINAPI *GetNumberOfFormatsFunc)(UInt32 *numFormats);
+typedef UInt32 (WINAPI *GetHandlerPropertyFunc)(PROPID propID, PROPVARIANT *value);
+typedef UInt32 (WINAPI *GetHandlerPropertyFunc2)(UInt32 index, PROPID propID, PROPVARIANT *value);
+typedef UInt32 (WINAPI *CreateObjectFunc)(const GUID *clsID, const GUID *iid, void **outObject);
+typedef UInt32 (WINAPI *SetLargePageModeFunc)();
+
+
+static HRESULT GetCoderClass(GetMethodPropertyFunc getMethodProperty, UInt32 index, 
+    PROPID propId, CLSID &clsId, bool &isAssigned)
+{
+  NWindows::NCOM::CPropVariant prop;
+  isAssigned = false;
+  RINOK(getMethodProperty(index, propId, &prop));
+  if (prop.vt == VT_BSTR)
+  {
+    isAssigned = true;
+    clsId = *(const GUID *)prop.bstrVal;
+  }
+  else if (prop.vt != VT_EMPTY)
+    return E_FAIL;
+  return S_OK;
+}
+
+HRESULT CCodecs::LoadCodecs()
+{
+  CCodecLib &lib = Libs.Back();
+  lib.GetMethodProperty = (GetMethodPropertyFunc)lib.Lib.GetProcAddress("GetMethodProperty");
+  if (lib.GetMethodProperty == NULL)
+    return S_OK;
+
+  UInt32 numMethods = 1;
+  GetNumberOfMethodsFunc getNumberOfMethodsFunc = (GetNumberOfMethodsFunc)lib.Lib.GetProcAddress("GetNumberOfMethods");
+  if (getNumberOfMethodsFunc != NULL)
+  {
+    RINOK(getNumberOfMethodsFunc(&numMethods));
+  }
+
+  for(UInt32 i = 0; i < numMethods; i++)
+  {
+    CDllCodecInfo info;
+    info.LibIndex = Libs.Size() - 1;
+    info.CodecIndex = i;
+
+    RINOK(GetCoderClass(lib.GetMethodProperty, i, NMethodPropID::kEncoder, info.Encoder, info.EncoderIsAssigned));
+    RINOK(GetCoderClass(lib.GetMethodProperty, i, NMethodPropID::kDecoder, info.Decoder, info.DecoderIsAssigned));
+
+    Codecs.Add(info);
+  }
+  return S_OK;
+}
+
+static HRESULT ReadProp(
+    GetHandlerPropertyFunc getProp, 
+    GetHandlerPropertyFunc2 getProp2, 
+    UInt32 index, PROPID propID, NCOM::CPropVariant &prop)
+{
+  if (getProp2)
+    return getProp2(index, propID, &prop);;
+  return getProp(propID, &prop);
+}
+
+static HRESULT ReadBoolProp(
+    GetHandlerPropertyFunc getProp, 
+    GetHandlerPropertyFunc2 getProp2, 
+    UInt32 index, PROPID propID, bool &res)
+{
+  NCOM::CPropVariant prop;
+  RINOK(ReadProp(getProp, getProp2, index, propID, prop));
+  if (prop.vt == VT_BOOL)
+    res = VARIANT_BOOLToBool(prop.boolVal);
+  else if (prop.vt != VT_EMPTY)
+    return E_FAIL;
+  return S_OK;
+}
+
+static HRESULT ReadStringProp(
+    GetHandlerPropertyFunc getProp, 
+    GetHandlerPropertyFunc2 getProp2, 
+    UInt32 index, PROPID propID, UString &res)
+{
+  NCOM::CPropVariant prop;
+  RINOK(ReadProp(getProp, getProp2, index, propID, prop));
+  if (prop.vt == VT_BSTR)
+    res = prop.bstrVal;
+  else if (prop.vt != VT_EMPTY)
+    return E_FAIL;
+  return S_OK;
+}
+
+#endif
+
+static const unsigned int kNumArcsMax = 32;
+static unsigned int g_NumArcs = 0;
+static const CArcInfo *g_Arcs[kNumArcsMax]; 
+void RegisterArc(const CArcInfo *arcInfo) 
+{ 
+  if (g_NumArcs < kNumArcsMax)
+    g_Arcs[g_NumArcs++] = arcInfo; 
+}
+
+static void SplitString(const UString &srcString, UStringVector &destStrings)
+{
+  destStrings.Clear();
+  UString s;
+  int len = srcString.Length();
+  if (len == 0)
+    return;
+  for (int i = 0; i < len; i++)
+  {
+    wchar_t c = srcString[i];
+    if (c == L' ')
+    {
+      if (!s.IsEmpty())
+      {
+        destStrings.Add(s);
+        s.Empty();
+      }
+    }
+    else
+      s += c;
+  }
+  if (!s.IsEmpty())
+    destStrings.Add(s);
+}
+
+void CArcInfoEx::AddExts(const wchar_t* ext, const wchar_t* addExt)
+{
+  UStringVector exts, addExts;
+  SplitString(ext, exts);
+  if (addExt != 0)
+    SplitString(addExt, addExts);
+  for (int i = 0; i < exts.Size(); i++)
+  {
+    CArcExtInfo extInfo;
+    extInfo.Ext = exts[i];
+    if (i < addExts.Size())
+    {
+      extInfo.AddExt = addExts[i];
+      if (extInfo.AddExt == L"*")
+        extInfo.AddExt.Empty();
+    }
+    Exts.Add(extInfo);
+  }
+}
+
+#ifdef EXTERNAL_CODECS
+
+HRESULT CCodecs::LoadFormats()
+{
+  const NDLL::CLibrary &lib = Libs.Back().Lib;
+  GetHandlerPropertyFunc getProp = 0;
+  GetHandlerPropertyFunc2 getProp2 = (GetHandlerPropertyFunc2)
+      lib.GetProcAddress("GetHandlerProperty2");
+  if (getProp2 == NULL)
+  {
+    getProp = (GetHandlerPropertyFunc)
+        lib.GetProcAddress("GetHandlerProperty");
+    if (getProp == NULL)
+      return S_OK;
+  }
+
+  UInt32 numFormats = 1;
+  GetNumberOfFormatsFunc getNumberOfFormats = (GetNumberOfFormatsFunc)
+    lib.GetProcAddress("GetNumberOfFormats");
+  if (getNumberOfFormats != NULL)
+  {
+    RINOK(getNumberOfFormats(&numFormats));
+  }
+  if (getProp2 == NULL)
+    numFormats = 1;
+
+  for(UInt32 i = 0; i < numFormats; i++)
+  {
+    CArcInfoEx item;
+    item.LibIndex = Libs.Size() - 1;
+    item.FormatIndex = i;
+
+    RINOK(ReadStringProp(getProp, getProp2, i, NArchive::kName, item.Name));
+
+    NCOM::CPropVariant prop;
+    if (ReadProp(getProp, getProp2, i, NArchive::kClassID, prop) != S_OK)
+      continue;
+    if (prop.vt != VT_BSTR)
+      continue;
+    item.ClassID = *(const GUID *)prop.bstrVal;
+    prop.Clear();
+
+    UString ext, addExt;
+    RINOK(ReadStringProp(getProp, getProp2, i, NArchive::kExtension, ext));
+    RINOK(ReadStringProp(getProp, getProp2, i, NArchive::kAddExtension, addExt));
+    item.AddExts(ext, addExt);
+
+    ReadBoolProp(getProp, getProp2, i, NArchive::kUpdate, item.UpdateEnabled);
+    if (item.UpdateEnabled)
+      ReadBoolProp(getProp, getProp2, i, NArchive::kKeepName, item.KeepName);
+    
+    if (ReadProp(getProp, getProp2, i, NArchive::kStartSignature, prop) == S_OK)
+      if (prop.vt == VT_BSTR)
+      {
+        UINT len = ::SysStringByteLen(prop.bstrVal);
+        item.StartSignature.SetCapacity(len);
+        memmove(item.StartSignature, prop.bstrVal, len);
+      }
+    Formats.Add(item);
+  }
+  return S_OK;
+}
+
+#ifdef NEW_FOLDER_INTERFACE
+void CCodecLib::LoadIcons()
+{
+  UString iconTypes = MyLoadStringW((HMODULE)Lib, kIconTypesResId);
+  UStringVector pairs;
+  SplitString(iconTypes, pairs);
+  for (int i = 0; i < pairs.Size(); i++)
+  {
+    const UString &s = pairs[i];
+    int pos = s.Find(L':');
+    if (pos < 0)
+      continue;
+    CIconPair iconPair;
+    const wchar_t *end;
+    UString num = s.Mid(pos + 1);
+    iconPair.IconIndex = (UInt32)ConvertStringToUInt64(num, &end);
+    if (*end != L'\0')
+      continue;
+    iconPair.Ext = s.Left(pos);
+    IconPairs.Add(iconPair);
+  }
+}
+
+int CCodecLib::FindIconIndex(const UString &ext) const
+{
+  for (int i = 0; i < IconPairs.Size(); i++)
+  {
+    const CIconPair &pair = IconPairs[i];
+    if (ext.CompareNoCase(pair.Ext) == 0)
+      return pair.IconIndex;
+  }
+  return -1;
+}
+#endif
+
+#ifdef _7ZIP_LARGE_PAGES
+extern "C" 
+{
+  extern SIZE_T g_LargePageSize;
+}
+#endif
+
+HRESULT CCodecs::LoadDll(const CSysString &dllPath)
+{
+  {
+    NDLL::CLibrary library;
+    if (!library.LoadEx(dllPath, LOAD_LIBRARY_AS_DATAFILE))
+      return S_OK;
+  }
+  Libs.Add(CCodecLib());
+  CCodecLib &lib = Libs.Back();
+  #ifdef NEW_FOLDER_INTERFACE
+  lib.Path = dllPath;
+  #endif
+  bool used = false;
+  HRESULT res = S_OK;
+  if (lib.Lib.Load(dllPath))
+  {
+    #ifdef NEW_FOLDER_INTERFACE
+    lib.LoadIcons();
+    #endif
+
+    #ifdef _7ZIP_LARGE_PAGES
+    if (g_LargePageSize != 0)
+    {
+      SetLargePageModeFunc setLargePageMode = (SetLargePageModeFunc)lib.Lib.GetProcAddress("SetLargePageMode");
+      if (setLargePageMode != 0)
+        setLargePageMode();
+    }
+    #endif
+
+    lib.CreateObject = (CreateObjectFunc)lib.Lib.GetProcAddress("CreateObject");
+    if (lib.CreateObject != 0)
+    {
+      int startSize = Codecs.Size();
+      res = LoadCodecs();
+      used = (Codecs.Size() != startSize);
+      if (res == S_OK)
+      {
+        startSize = Formats.Size();
+        res = LoadFormats();
+        used = used || (Formats.Size() != startSize);
+      }
+    }
+  }
+  if (!used)
+    Libs.DeleteBack();
+  return res;
+}
+
+HRESULT CCodecs::LoadDllsFromFolder(const CSysString &folderPrefix)
+{
+  NFile::NFind::CEnumerator enumerator(folderPrefix + CSysString(TEXT("*")));
+  NFile::NFind::CFileInfo fileInfo;
+  while (enumerator.Next(fileInfo))
+  {
+    if (fileInfo.IsDirectory())
+      continue;
+    RINOK(LoadDll(folderPrefix + fileInfo.Name));
+  }
+  return S_OK;
+}
+
+#endif
+
+#ifndef _SFX
+static inline void SetBuffer(CByteBuffer &bb, const Byte *data, int size)
+{
+  bb.SetCapacity(size);
+  memmove((Byte *)bb, data, size);
+}
+#endif
+
+HRESULT CCodecs::Load()
+{
+  Formats.Clear();
+  #ifdef EXTERNAL_CODECS
+  Codecs.Clear();
+  #endif
+  for (UInt32 i = 0; i < g_NumArcs; i++)
+  {
+    const CArcInfo &arc = *g_Arcs[i];
+    CArcInfoEx item;
+    item.Name = arc.Name;
+    item.CreateInArchive = arc.CreateInArchive;
+    item.CreateOutArchive = arc.CreateOutArchive;
+    item.AddExts(arc.Ext, arc.AddExt);
+    item.UpdateEnabled = (arc.CreateOutArchive != 0);
+    item.KeepName = arc.KeepName;
+
+    #ifndef _SFX
+    SetBuffer(item.StartSignature, arc.Signature, arc.SignatureSize);
+    #endif
+    Formats.Add(item);
+  }
+  #ifdef EXTERNAL_CODECS
+  const CSysString baseFolder = GetBaseFolderPrefixFromRegistry();
+  RINOK(LoadDll(baseFolder + kMainDll));
+  RINOK(LoadDllsFromFolder(baseFolder + kCodecsFolderName TEXT(STRING_PATH_SEPARATOR)));
+  RINOK(LoadDllsFromFolder(baseFolder + kFormatsFolderName TEXT(STRING_PATH_SEPARATOR)));
+  #endif
+  return S_OK;
+}
+
+int CCodecs::FindFormatForArchiveName(const UString &archivePath) const
+{
+  int slashPos1 = archivePath.ReverseFind(L'\\');
+  int slashPos2 = archivePath.ReverseFind(L'.');
+  int dotPos = archivePath.ReverseFind(L'.');
+  if (dotPos < 0 || dotPos < slashPos1 || dotPos < slashPos2)
+    return -1;
+  UString ext = archivePath.Mid(dotPos + 1);
+  for (int i = 0; i < Formats.Size(); i++)
+  {
+    const CArcInfoEx &arc = Formats[i];
+    if (!arc.UpdateEnabled)
+      continue;
+    // if (arc.FindExtension(ext) >= 0)
+    UString mainExt = arc.GetMainExt();
+    if (!mainExt.IsEmpty() && ext.CompareNoCase(mainExt) == 0)
+      return i;
+  }
+  return -1;
+}
+
+int CCodecs::FindFormatForArchiveType(const UString &arcType) const
+{
+  for (int i = 0; i < Formats.Size(); i++)
+  {
+    const CArcInfoEx &arc = Formats[i];
+    if (!arc.UpdateEnabled)
+      continue;
+    if (arc.Name.CompareNoCase(arcType) == 0)
+      return i;
+  }
+  return -1;
+}
+
+#ifdef EXTERNAL_CODECS
+
+#ifdef EXPORT_CODECS
+extern unsigned int g_NumCodecs;
+STDAPI CreateCoder2(bool encode, UInt32 index, const GUID *iid, void **outObject);
+STDAPI GetMethodProperty(UInt32 codecIndex, PROPID propID, PROPVARIANT *value);
+// STDAPI GetNumberOfMethods(UINT32 *numCodecs);
+#endif
+
+STDMETHODIMP CCodecs::GetNumberOfMethods(UINT32 *numMethods)
+{
+  *numMethods = 
+      #ifdef EXPORT_CODECS
+      g_NumCodecs + 
+      #endif
+      Codecs.Size();
+  return S_OK;
+}
+
+STDMETHODIMP CCodecs::GetProperty(UINT32 index, PROPID propID, PROPVARIANT *value)
+{
+  #ifdef EXPORT_CODECS
+  if (index < g_NumCodecs)
+    return GetMethodProperty(index, propID, value);
+  #endif
+
+  const CDllCodecInfo &ci = Codecs[index 
+      #ifdef EXPORT_CODECS
+      - g_NumCodecs
+      #endif
+      ];
+
+  if (propID == NMethodPropID::kDecoderIsAssigned)
+  {
+    NWindows::NCOM::CPropVariant propVariant;
+    propVariant = ci.DecoderIsAssigned;
+    propVariant.Detach(value);
+    return S_OK;
+  }
+  if (propID == NMethodPropID::kEncoderIsAssigned)
+  {
+    NWindows::NCOM::CPropVariant propVariant;
+    propVariant = ci.EncoderIsAssigned;
+    propVariant.Detach(value);
+    return S_OK;
+  }
+  return Libs[ci.LibIndex].GetMethodProperty(ci.CodecIndex, propID, value);
+}
+
+STDMETHODIMP CCodecs::CreateDecoder(UINT32 index, const GUID *iid, void **coder)
+{
+  #ifdef EXPORT_CODECS
+  if (index < g_NumCodecs)
+    return CreateCoder2(false, index, iid, coder);
+  #endif
+  const CDllCodecInfo &ci = Codecs[index 
+      #ifdef EXPORT_CODECS
+      - g_NumCodecs
+      #endif
+      ];
+  if (ci.DecoderIsAssigned)
+    return Libs[ci.LibIndex].CreateObject(&ci.Decoder, iid, (void **)coder);
+  return S_OK;
+}
+
+STDMETHODIMP CCodecs::CreateEncoder(UINT32 index, const GUID *iid, void **coder)
+{
+  #ifdef EXPORT_CODECS
+  if (index < g_NumCodecs)
+    return CreateCoder2(true, index, iid, coder);
+  #endif
+  const CDllCodecInfo &ci = Codecs[index 
+      #ifdef EXPORT_CODECS
+      - g_NumCodecs
+      #endif
+      ];
+  if (ci.EncoderIsAssigned)
+    return Libs[ci.LibIndex].CreateObject(&ci.Encoder, iid, (void **)coder);
+  return S_OK;
+}
+
+HRESULT CCodecs::CreateCoder(const UString &name, bool encode, CMyComPtr<ICompressCoder> &coder) const
+{ 
+  for (int i = 0; i < Codecs.Size(); i++)
+  {
+    const CDllCodecInfo &codec = Codecs[i];
+    if (encode && !codec.EncoderIsAssigned || !encode && !codec.DecoderIsAssigned)
+      continue;
+    const CCodecLib &lib = Libs[codec.LibIndex];
+    UString res;
+    NWindows::NCOM::CPropVariant prop;
+    RINOK(lib.GetMethodProperty(codec.CodecIndex, NMethodPropID::kName, &prop));
+    if (prop.vt == VT_BSTR)
+      res = prop.bstrVal;
+    else if (prop.vt != VT_EMPTY)
+      continue;
+    if (name.CompareNoCase(res) == 0)
+      return lib.CreateObject(encode ? &codec.Encoder : &codec.Decoder, &IID_ICompressCoder, (void **)&coder);
+  }
+  return CLASS_E_CLASSNOTAVAILABLE;
+}
+
+int CCodecs::GetCodecLibIndex(UInt32 index)
+{
+  #ifdef EXPORT_CODECS
+  if (index < g_NumCodecs)
+    return -1;
+  #endif
+  #ifdef EXTERNAL_CODECS
+  const CDllCodecInfo &ci = Codecs[index 
+      #ifdef EXPORT_CODECS
+      - g_NumCodecs
+      #endif
+      ];
+  return ci.LibIndex;
+  #else
+  return -1;
+  #endif
+}
+
+bool CCodecs::GetCodecEncoderIsAssigned(UInt32 index)
+{
+  #ifdef EXPORT_CODECS
+  if (index < g_NumCodecs)
+  {
+    NWindows::NCOM::CPropVariant prop;
+    if (GetProperty(index, NMethodPropID::kEncoder, &prop) == S_OK)
+      if (prop.vt != VT_EMPTY)
+        return true;
+    return false;
+  }
+  #endif
+  #ifdef EXTERNAL_CODECS
+  const CDllCodecInfo &ci = Codecs[index 
+      #ifdef EXPORT_CODECS
+      - g_NumCodecs
+      #endif
+      ];
+  return ci.EncoderIsAssigned;
+  #else
+  return false;
+  #endif
+}
+
+HRESULT CCodecs::GetCodecId(UInt32 index, UInt64 &id)
+{
+  UString s;
+  NWindows::NCOM::CPropVariant prop;
+  RINOK(GetProperty(index, NMethodPropID::kID, &prop));
+  if (prop.vt != VT_UI8)
+    return E_INVALIDARG;
+  id = prop.uhVal.QuadPart;
+  return S_OK;
+}
+
+UString CCodecs::GetCodecName(UInt32 index)
+{
+  UString s;
+  NWindows::NCOM::CPropVariant prop;
+  if (GetProperty(index, NMethodPropID::kName, &prop) == S_OK)
+    if (prop.vt == VT_BSTR)
+      s = prop.bstrVal;
+  return s;
+}
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/misc/libphysfs/lzma/CPP/7zip/UI/Common/LoadCodecs.h	Mon Apr 10 12:06:43 2017 -0400
@@ -0,0 +1,215 @@
+// LoadCodecs.h
+
+#ifndef __LOADCODECS_H
+#define __LOADCODECS_H
+
+#include "../../../Common/Types.h"
+#include "../../../Common/MyCom.h"
+#include "../../../Common/MyString.h"
+#include "../../../Common/Buffer.h"
+#include "../../ICoder.h"
+
+#ifdef EXTERNAL_CODECS
+#include "../../../Windows/DLL.h"
+#endif
+
+struct CDllCodecInfo
+{
+  CLSID Encoder;
+  CLSID Decoder;
+  bool EncoderIsAssigned;
+  bool DecoderIsAssigned;
+  int LibIndex;
+  UInt32 CodecIndex;
+};
+
+#include "../../Archive/IArchive.h"
+
+typedef IInArchive * (*CreateInArchiveP)();
+typedef IOutArchive * (*CreateOutArchiveP)();
+
+struct CArcExtInfo
+{
+  UString Ext;
+  UString AddExt;
+  CArcExtInfo() {}
+  CArcExtInfo(const UString &ext): Ext(ext) {}
+  CArcExtInfo(const UString &ext, const UString &addExt): Ext(ext), AddExt(addExt) {}
+};
+
+
+struct CArcInfoEx
+{
+  #ifdef EXTERNAL_CODECS
+  int LibIndex;
+  UInt32 FormatIndex;
+  CLSID ClassID;
+  #endif
+  bool UpdateEnabled;
+  CreateInArchiveP CreateInArchive;
+  CreateOutArchiveP CreateOutArchive;
+  UString Name;
+  CObjectVector<CArcExtInfo> Exts;
+  #ifndef _SFX
+  CByteBuffer StartSignature;
+  // CByteBuffer FinishSignature;
+  #ifdef NEW_FOLDER_INTERFACE
+  UStringVector AssociateExts;
+  #endif
+  #endif
+  bool KeepName;
+  UString GetMainExt() const
+  {
+    if (Exts.IsEmpty())
+      return UString();
+    return Exts[0].Ext;
+  }
+  int FindExtension(const UString &ext) const
+  {
+    for (int i = 0; i < Exts.Size(); i++)
+      if (ext.CompareNoCase(Exts[i].Ext) == 0)
+        return i;
+    return -1;
+  }
+  UString GetAllExtensions() const
+  {
+    UString s;
+    for (int i = 0; i < Exts.Size(); i++)
+    {
+      if (i > 0)
+        s += ' ';
+      s += Exts[i].Ext;
+    }
+    return s;
+  }
+
+  void AddExts(const wchar_t* ext, const wchar_t* addExt);
+
+  CArcInfoEx(): 
+    #ifdef EXTERNAL_CODECS
+    LibIndex(-1),
+    #endif
+    UpdateEnabled(false),
+    CreateInArchive(0), CreateOutArchive(0),
+    KeepName(false)
+    #ifndef _SFX
+    #endif
+  {}
+};
+
+#ifdef EXTERNAL_CODECS
+typedef UInt32 (WINAPI *GetMethodPropertyFunc)(UInt32 index, PROPID propID, PROPVARIANT *value);
+typedef UInt32 (WINAPI *CreateObjectFunc)(const GUID *clsID, const GUID *interfaceID, void **outObject);
+
+
+struct CCodecLib
+{
+  NWindows::NDLL::CLibrary Lib;
+  GetMethodPropertyFunc GetMethodProperty;
+  CreateObjectFunc CreateObject;
+  #ifdef NEW_FOLDER_INTERFACE
+  struct CIconPair
+  {
+    UString Ext;
+    UInt32 IconIndex;
+  };
+  CSysString Path;
+  CObjectVector<CIconPair> IconPairs;
+  void LoadIcons();
+  int FindIconIndex(const UString &ext) const;
+  #endif
+  CCodecLib(): GetMethodProperty(0) {}
+};
+#endif
+
+class CCodecs:
+  #ifdef EXTERNAL_CODECS
+  public ICompressCodecsInfo,
+  #else
+  public IUnknown,
+  #endif
+  public CMyUnknownImp
+{
+public:  
+  #ifdef EXTERNAL_CODECS
+  CObjectVector<CCodecLib> Libs;
+  CObjectVector<CDllCodecInfo> Codecs;
+  HRESULT LoadCodecs();
+  HRESULT LoadFormats();
+  HRESULT LoadDll(const CSysString &path);
+  HRESULT LoadDllsFromFolder(const CSysString &folderPrefix);
+
+  HRESULT CreateArchiveHandler(const CArcInfoEx &ai, void **archive, bool outHandler) const
+  {
+    return Libs[ai.LibIndex].CreateObject(&ai.ClassID, outHandler ? &IID_IOutArchive : &IID_IInArchive, (void **)archive);
+  }
+  #endif
+
+public:
+  CObjectVector<CArcInfoEx> Formats;
+  HRESULT Load();
+  int FindFormatForArchiveName(const UString &archivePath) const;
+  int FindFormatForArchiveType(const UString &arcType) const;
+
+  MY_UNKNOWN_IMP
+
+  #ifdef EXTERNAL_CODECS
+  STDMETHOD(GetNumberOfMethods)(UINT32 *numMethods);
+  STDMETHOD(GetProperty)(UINT32 index, PROPID propID, PROPVARIANT *value);
+  STDMETHOD(CreateDecoder)(UINT32 index, const GUID *interfaceID, void **coder);
+  STDMETHOD(CreateEncoder)(UINT32 index, const GUID *interfaceID, void **coder);
+  #endif
+
+  int GetCodecLibIndex(UInt32 index);
+  bool GetCodecEncoderIsAssigned(UInt32 index);
+  HRESULT GetCodecId(UInt32 index, UInt64 &id);
+  UString GetCodecName(UInt32 index);
+
+  HRESULT CreateInArchive(int formatIndex, CMyComPtr<IInArchive> &archive) const
+  { 
+    const CArcInfoEx &ai = Formats[formatIndex]; 
+    #ifdef EXTERNAL_CODECS
+    if (ai.LibIndex < 0)
+    #endif
+    {
+      archive = ai.CreateInArchive();
+      return S_OK;
+    }
+    #ifdef EXTERNAL_CODECS
+    return CreateArchiveHandler(ai, (void **)&archive, false); 
+    #endif
+  }
+  HRESULT CreateOutArchive(int formatIndex, CMyComPtr<IOutArchive> &archive) const
+  { 
+    const CArcInfoEx &ai = Formats[formatIndex]; 
+    #ifdef EXTERNAL_CODECS
+    if (ai.LibIndex < 0)
+    #endif
+    {
+      archive = ai.CreateOutArchive();
+      return S_OK;
+    }
+    #ifdef EXTERNAL_CODECS
+    return CreateArchiveHandler(ai, (void **)&archive, true); 
+    #endif
+  }
+  int FindOutFormatFromName(const UString &name) const
+  {
+    for (int i = 0; i < Formats.Size(); i++)
+    {
+      const CArcInfoEx &arc = Formats[i];
+      if (!arc.UpdateEnabled)
+        continue;
+      if (arc.Name.CompareNoCase(name) == 0)
+        return i;
+    }
+    return -1;
+  }
+
+  #ifdef EXTERNAL_CODECS
+  HRESULT CreateCoder(const UString &name, bool encode, CMyComPtr<ICompressCoder> &coder) const;
+  #endif
+
+};
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/misc/libphysfs/lzma/CPP/7zip/UI/Common/OpenArchive.cpp	Mon Apr 10 12:06:43 2017 -0400
@@ -0,0 +1,461 @@
+// OpenArchive.cpp
+
+#include "StdAfx.h"
+
+#include "OpenArchive.h"
+
+#include "Common/Wildcard.h"
+
+#include "Windows/FileName.h"
+#include "Windows/FileDir.h"
+#include "Windows/Defs.h"
+#include "Windows/PropVariant.h"
+
+#include "../../Common/FileStreams.h"
+#include "../../Common/StreamUtils.h"
+
+#include "Common/StringConvert.h"
+
+#include "DefaultName.h"
+
+using namespace NWindows;
+
+HRESULT GetArchiveItemPath(IInArchive *archive, UInt32 index, UString &result)
+{
+  NCOM::CPropVariant prop;
+  RINOK(archive->GetProperty(index, kpidPath, &prop));
+  if(prop.vt == VT_BSTR)
+    result = prop.bstrVal;
+  else if (prop.vt == VT_EMPTY)
+    result.Empty();
+  else
+    return E_FAIL;
+  return S_OK;
+}
+
+HRESULT GetArchiveItemPath(IInArchive *archive, UInt32 index, const UString &defaultName, UString &result)
+{
+  RINOK(GetArchiveItemPath(archive, index, result));
+  if (result.IsEmpty())
+    result = defaultName;
+  return S_OK;
+}
+
+HRESULT GetArchiveItemFileTime(IInArchive *archive, UInt32 index, 
+    const FILETIME &defaultFileTime, FILETIME &fileTime)
+{
+  NCOM::CPropVariant prop;
+  RINOK(archive->GetProperty(index, kpidLastWriteTime, &prop));
+  if (prop.vt == VT_FILETIME)
+    fileTime = prop.filetime;
+  else if (prop.vt == VT_EMPTY)
+    fileTime = defaultFileTime;
+  else
+    return E_FAIL;
+  return S_OK;
+}
+
+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;
+}
+
+HRESULT IsArchiveItemFolder(IInArchive *archive, UInt32 index, bool &result)
+{
+  return IsArchiveItemProp(archive, index, kpidIsFolder, result);
+}
+
+HRESULT IsArchiveItemAnti(IInArchive *archive, UInt32 index, bool &result)
+{
+  return IsArchiveItemProp(archive, index, kpidIsAnti, result);
+}
+
+// Static-SFX (for Linux) can be big.
+const UInt64 kMaxCheckStartPosition = 1 << 22;
+
+HRESULT ReOpenArchive(IInArchive *archive, const UString &fileName, IArchiveOpenCallback *openArchiveCallback)
+{
+  CInFileStream *inStreamSpec = new CInFileStream;
+  CMyComPtr<IInStream> inStream(inStreamSpec);
+  inStreamSpec->Open(fileName);
+  return archive->Open(inStream, &kMaxCheckStartPosition, openArchiveCallback);
+}
+
+#ifndef _SFX
+static inline bool TestSignature(const Byte *p1, const Byte *p2, size_t size)
+{
+  for (size_t i = 0; i < size; i++)
+    if (p1[i] != p2[i])
+      return false;
+  return true;
+}
+#endif
+
+HRESULT OpenArchive(
+    CCodecs *codecs,
+    IInStream *inStream,
+    const UString &fileName, 
+    IInArchive **archiveResult, 
+    int &formatIndex,
+    UString &defaultItemName,
+    IArchiveOpenCallback *openArchiveCallback)
+{
+  *archiveResult = NULL;
+  UString extension;
+  {
+    int dotPos = fileName.ReverseFind(L'.');
+    if (dotPos >= 0)
+      extension = fileName.Mid(dotPos + 1);
+  }
+  CIntVector orderIndices;
+  int i;
+  int numFinded = 0;
+  for (i = 0; i < codecs->Formats.Size(); i++)
+    if (codecs->Formats[i].FindExtension(extension) >= 0)
+      orderIndices.Insert(numFinded++, i);
+    else
+      orderIndices.Add(i);
+  
+  #ifndef _SFX
+  if (numFinded != 1)
+  {
+    CIntVector orderIndices2;
+    CByteBuffer byteBuffer;
+    const UInt32 kBufferSize = (200 << 10);
+    byteBuffer.SetCapacity(kBufferSize);
+    Byte *buffer = byteBuffer;
+    RINOK(inStream->Seek(0, STREAM_SEEK_SET, NULL));
+    UInt32 processedSize;
+    RINOK(ReadStream(inStream, buffer, kBufferSize, &processedSize));
+    for (UInt32 pos = 0; pos < processedSize; pos++)
+    {
+      for (int i = 0; i < orderIndices.Size(); i++)
+      {
+        int index = orderIndices[i];
+        const CArcInfoEx &ai = codecs->Formats[index];
+        const CByteBuffer &sig = ai.StartSignature;
+        if (sig.GetCapacity() == 0)
+          continue;
+        if (pos + sig.GetCapacity() > processedSize)
+          continue;
+        if (TestSignature(buffer + pos, sig, sig.GetCapacity()))
+        {
+          orderIndices2.Add(index);
+          orderIndices.Delete(i--);
+        }
+      }
+    }
+    orderIndices2 += orderIndices;
+    orderIndices = orderIndices2;
+  }
+  else if (extension == L"000" || extension == L"001")
+  {
+    CByteBuffer byteBuffer;
+    const UInt32 kBufferSize = (1 << 10);
+    byteBuffer.SetCapacity(kBufferSize);
+    Byte *buffer = byteBuffer;
+    RINOK(inStream->Seek(0, STREAM_SEEK_SET, NULL));
+    UInt32 processedSize;
+    RINOK(ReadStream(inStream, buffer, kBufferSize, &processedSize));
+    if (processedSize >= 16)
+    {
+      Byte kRarHeader[] = {0x52 , 0x61, 0x72, 0x21, 0x1a, 0x07, 0x00};
+      if (TestSignature(buffer, kRarHeader, 7) && buffer[9] == 0x73 && (buffer[10] && 1) != 0)
+      {
+        for (int i = 0; i < orderIndices.Size(); i++)
+        {
+          int index = orderIndices[i];
+          const CArcInfoEx &ai = codecs->Formats[index];
+          if (ai.Name.CompareNoCase(L"rar") != 0)
+            continue;
+          orderIndices.Delete(i--);
+          orderIndices.Insert(0, index);
+          break;
+        }
+      }
+    }
+  }
+  #endif
+
+  HRESULT badResult = S_OK;
+  for(i = 0; i < orderIndices.Size(); i++)
+  {
+    inStream->Seek(0, STREAM_SEEK_SET, NULL);
+
+    CMyComPtr<IInArchive> archive;
+
+    formatIndex = orderIndices[i];
+    RINOK(codecs->CreateInArchive(formatIndex, archive));
+    if (!archive)
+      continue;
+
+    #ifdef EXTERNAL_CODECS
+    {
+      CMyComPtr<ISetCompressCodecsInfo> setCompressCodecsInfo;
+      archive.QueryInterface(IID_ISetCompressCodecsInfo, (void **)&setCompressCodecsInfo);
+      if (setCompressCodecsInfo)
+      {
+        RINOK(setCompressCodecsInfo->SetCompressCodecsInfo(codecs));
+      }
+    }
+    #endif
+
+    HRESULT result = archive->Open(inStream, &kMaxCheckStartPosition, openArchiveCallback);
+    if (result == S_FALSE)
+      continue;
+    if(result != S_OK)
+    {
+      badResult = result;
+      if(result == E_ABORT)
+        break;
+      continue;
+    }
+    *archiveResult = archive.Detach();
+    const CArcInfoEx &format = codecs->Formats[formatIndex];
+    if (format.Exts.Size() == 0)
+    {
+      defaultItemName = GetDefaultName2(fileName, L"", L"");
+    }
+    else
+    {
+      int subExtIndex = format.FindExtension(extension);
+      if (subExtIndex < 0)
+        subExtIndex = 0;
+      defaultItemName = GetDefaultName2(fileName, 
+          format.Exts[subExtIndex].Ext, 
+          format.Exts[subExtIndex].AddExt);
+    }
+    return S_OK;
+  }
+  if (badResult != S_OK)
+    return badResult;
+  return S_FALSE;
+}
+
+HRESULT OpenArchive(
+    CCodecs *codecs,
+    const UString &filePath, 
+    IInArchive **archiveResult, 
+    int &formatIndex,
+    UString &defaultItemName,
+    IArchiveOpenCallback *openArchiveCallback)
+{
+  CInFileStream *inStreamSpec = new CInFileStream;
+  CMyComPtr<IInStream> inStream(inStreamSpec);
+  if (!inStreamSpec->Open(filePath))
+    return GetLastError();
+  return OpenArchive(codecs, inStream, ExtractFileNameFromPath(filePath),
+    archiveResult, formatIndex,
+    defaultItemName, openArchiveCallback);
+}
+
+static void MakeDefaultName(UString &name)
+{
+  int dotPos = name.ReverseFind(L'.');
+  if (dotPos < 0)
+    return;
+  UString ext = name.Mid(dotPos + 1);
+  if (ext.IsEmpty())
+    return;
+  for (int pos = 0; pos < ext.Length(); pos++)
+    if (ext[pos] < L'0' || ext[pos] > L'9')
+      return;
+  name = name.Left(dotPos);
+}
+
+HRESULT OpenArchive(
+    CCodecs *codecs,
+    const UString &fileName, 
+    IInArchive **archive0, 
+    IInArchive **archive1, 
+    int &formatIndex0,
+    int &formatIndex1,
+    UString &defaultItemName0,
+    UString &defaultItemName1,
+    IArchiveOpenCallback *openArchiveCallback)
+{
+  HRESULT result = OpenArchive(codecs, fileName, 
+      archive0, formatIndex0, defaultItemName0, openArchiveCallback);
+  RINOK(result);
+  CMyComPtr<IInArchiveGetStream> getStream;
+  result = (*archive0)->QueryInterface(IID_IInArchiveGetStream, (void **)&getStream);
+  if (result != S_OK || getStream == 0)
+    return S_OK;
+
+  CMyComPtr<ISequentialInStream> subSeqStream;
+  result = getStream->GetStream(0, &subSeqStream);
+  if (result != S_OK)
+    return S_OK;
+
+  CMyComPtr<IInStream> subStream;
+  if (subSeqStream.QueryInterface(IID_IInStream, &subStream) != S_OK)
+    return S_OK;
+  if (!subStream)
+    return S_OK;
+
+  UInt32 numItems;
+  RINOK((*archive0)->GetNumberOfItems(&numItems));
+  if (numItems < 1)
+    return S_OK;
+
+  UString subPath;
+  RINOK(GetArchiveItemPath(*archive0, 0, subPath))
+  if (subPath.IsEmpty())
+  {
+    MakeDefaultName(defaultItemName0);
+    subPath = defaultItemName0;
+    const CArcInfoEx &format = codecs->Formats[formatIndex0];
+    if (format.Name.CompareNoCase(L"7z") == 0)
+    {
+      if (subPath.Right(3).CompareNoCase(L".7z") != 0)
+        subPath += L".7z";
+    }
+  }
+  else
+    subPath = ExtractFileNameFromPath(subPath);
+
+  CMyComPtr<IArchiveOpenSetSubArchiveName> setSubArchiveName;
+  openArchiveCallback->QueryInterface(IID_IArchiveOpenSetSubArchiveName, (void **)&setSubArchiveName);
+  if (setSubArchiveName)
+    setSubArchiveName->SetSubArchiveName(subPath);
+
+  result = OpenArchive(codecs, subStream, subPath,
+      archive1, formatIndex1, defaultItemName1, openArchiveCallback);
+  return S_OK;
+}
+
+static void SetCallback(const UString &archiveName,
+    IOpenCallbackUI *openCallbackUI, CMyComPtr<IArchiveOpenCallback> &openCallback)
+{
+  COpenCallbackImp *openCallbackSpec = new COpenCallbackImp;
+  openCallback = openCallbackSpec;
+  openCallbackSpec->Callback = openCallbackUI;
+
+  UString fullName;
+  int fileNamePartStartIndex;
+  NFile::NDirectory::MyGetFullPathName(archiveName, fullName, fileNamePartStartIndex);
+  openCallbackSpec->Init(
+      fullName.Left(fileNamePartStartIndex), 
+      fullName.Mid(fileNamePartStartIndex));
+}
+
+HRESULT MyOpenArchive(
+    CCodecs *codecs, 
+    const UString &archiveName,
+    IInArchive **archive, UString &defaultItemName, IOpenCallbackUI *openCallbackUI)
+{
+  CMyComPtr<IArchiveOpenCallback> openCallback;
+  SetCallback(archiveName, openCallbackUI, openCallback);
+  int formatInfo;
+  return OpenArchive(codecs, archiveName, archive, formatInfo, defaultItemName, openCallback);
+}
+
+HRESULT MyOpenArchive(
+    CCodecs *codecs,
+    const UString &archiveName,
+    IInArchive **archive0,
+    IInArchive **archive1,
+    UString &defaultItemName0,
+    UString &defaultItemName1,
+    UStringVector &volumePaths,
+    UInt64 &volumesSize,
+    IOpenCallbackUI *openCallbackUI)
+{
+  volumesSize = 0;
+  COpenCallbackImp *openCallbackSpec = new COpenCallbackImp;
+  CMyComPtr<IArchiveOpenCallback> openCallback = openCallbackSpec;
+  openCallbackSpec->Callback = openCallbackUI;
+
+  UString fullName;
+  int fileNamePartStartIndex;
+  NFile::NDirectory::MyGetFullPathName(archiveName, fullName, fileNamePartStartIndex);
+  UString prefix = fullName.Left(fileNamePartStartIndex);
+  UString name = fullName.Mid(fileNamePartStartIndex);
+  openCallbackSpec->Init(prefix, name);
+
+  int formatIndex0, formatIndex1;
+  RINOK(OpenArchive(codecs, archiveName,
+      archive0, 
+      archive1, 
+      formatIndex0, 
+      formatIndex1, 
+      defaultItemName0,
+      defaultItemName1,
+      openCallback));
+  volumePaths.Add(prefix + name);
+  for (int i = 0; i < openCallbackSpec->FileNames.Size(); i++)
+    volumePaths.Add(prefix + openCallbackSpec->FileNames[i]);
+  volumesSize = openCallbackSpec->TotalSize;
+  return S_OK;
+}
+
+HRESULT CArchiveLink::Close()
+{
+  if (Archive1 != 0)
+    RINOK(Archive1->Close());
+  if (Archive0 != 0)
+    RINOK(Archive0->Close());
+  IsOpen = false;
+  return S_OK;
+}
+
+void CArchiveLink::Release()
+{
+  IsOpen = false;
+  Archive1.Release();
+  Archive0.Release();
+}
+
+HRESULT OpenArchive(
+    CCodecs *codecs,
+    const UString &archiveName,
+    CArchiveLink &archiveLink,
+    IArchiveOpenCallback *openCallback)
+{
+  HRESULT res = OpenArchive(codecs, archiveName, 
+    &archiveLink.Archive0, &archiveLink.Archive1, 
+    archiveLink.FormatIndex0, archiveLink.FormatIndex1, 
+    archiveLink.DefaultItemName0, archiveLink.DefaultItemName1, 
+    openCallback);
+  archiveLink.IsOpen = (res == S_OK);
+  return res;
+}
+
+HRESULT MyOpenArchive(CCodecs *codecs,
+    const UString &archiveName, 
+    CArchiveLink &archiveLink,
+    IOpenCallbackUI *openCallbackUI)
+{
+  HRESULT res = MyOpenArchive(codecs, archiveName,
+    &archiveLink.Archive0, &archiveLink.Archive1, 
+    archiveLink.DefaultItemName0, archiveLink.DefaultItemName1, 
+    archiveLink.VolumePaths,
+    archiveLink.VolumesSize,
+    openCallbackUI);
+  archiveLink.IsOpen = (res == S_OK);
+  return res;
+}
+
+HRESULT ReOpenArchive(CCodecs *codecs, CArchiveLink &archiveLink, const UString &fileName)
+{
+  if (archiveLink.GetNumLevels() > 1)
+    return E_NOTIMPL;
+
+  if (archiveLink.GetNumLevels() == 0)
+    return MyOpenArchive(codecs, fileName, archiveLink, 0);
+
+  CMyComPtr<IArchiveOpenCallback> openCallback;
+  SetCallback(fileName, NULL, openCallback);
+
+  HRESULT res = ReOpenArchive(archiveLink.GetArchive(), fileName, openCallback);
+  archiveLink.IsOpen = (res == S_OK);
+  return res;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/misc/libphysfs/lzma/CPP/7zip/UI/Common/OpenArchive.h	Mon Apr 10 12:06:43 2017 -0400
@@ -0,0 +1,130 @@
+// OpenArchive.h
+
+#ifndef __OPENARCHIVE_H
+#define __OPENARCHIVE_H
+
+#include "Common/MyString.h"
+#include "Windows/FileFind.h"
+
+#include "../../Archive/IArchive.h"
+#include "LoadCodecs.h"
+#include "ArchiveOpenCallback.h"
+
+HRESULT GetArchiveItemPath(IInArchive *archive, UInt32 index, UString &result);
+HRESULT GetArchiveItemPath(IInArchive *archive, UInt32 index, const UString &defaultName, UString &result);
+HRESULT GetArchiveItemFileTime(IInArchive *archive, UInt32 index, 
+    const FILETIME &defaultFileTime, FILETIME &fileTime);
+HRESULT IsArchiveItemProp(IInArchive *archive, UInt32 index, PROPID propID, bool &result);
+HRESULT IsArchiveItemFolder(IInArchive *archive, UInt32 index, bool &result);
+HRESULT IsArchiveItemAnti(IInArchive *archive, UInt32 index, bool &result);
+
+struct ISetSubArchiveName
+{
+  virtual void SetSubArchiveName(const wchar_t *name) = 0;
+};
+
+HRESULT OpenArchive(
+    CCodecs *codecs,
+    IInStream *inStream,
+    const UString &fileName, 
+    IInArchive **archiveResult, 
+    int &formatIndex,
+    UString &defaultItemName,
+    IArchiveOpenCallback *openArchiveCallback);
+
+HRESULT OpenArchive(
+    CCodecs *codecs,
+    const UString &filePath, 
+    IInArchive **archive, 
+    int &formatIndex,
+    UString &defaultItemName,
+    IArchiveOpenCallback *openArchiveCallback);
+
+HRESULT OpenArchive(
+    CCodecs *codecs,
+    const UString &filePath, 
+    IInArchive **archive0, 
+    IInArchive **archive1, 
+    int &formatIndex0,
+    int &formatIndex1,
+    UString &defaultItemName0,
+    UString &defaultItemName1,
+    IArchiveOpenCallback *openArchiveCallback);
+
+
+HRESULT ReOpenArchive(IInArchive *archive, const UString &fileName, IArchiveOpenCallback *openArchiveCallback);
+
+HRESULT MyOpenArchive(
+    CCodecs *codecs,
+    const UString &archiveName, 
+    IInArchive **archive,
+    UString &defaultItemName,
+    IOpenCallbackUI *openCallbackUI);
+
+HRESULT MyOpenArchive(
+    CCodecs *codecs,
+    const UString &archiveName, 
+    IInArchive **archive0,
+    IInArchive **archive1,
+    UString &defaultItemName0,
+    UString &defaultItemName1,
+    UStringVector &volumePaths,
+    UInt64 &volumesSize,
+    IOpenCallbackUI *openCallbackUI);
+
+struct CArchiveLink
+{
+  CMyComPtr<IInArchive> Archive0;
+  CMyComPtr<IInArchive> Archive1;
+  UString DefaultItemName0;
+  UString DefaultItemName1;
+
+  int FormatIndex0;
+  int FormatIndex1;
+  
+  UStringVector VolumePaths;
+
+  UInt64 VolumesSize;
+
+  int GetNumLevels() const
+  { 
+    int result = 0;
+    if (Archive0)
+    {
+      result++;
+      if (Archive1)
+        result++;
+    }
+    return result;
+  }
+
+  bool IsOpen;
+
+  CArchiveLink(): IsOpen(false), VolumesSize(0) {};
+
+  IInArchive *GetArchive() { return Archive1 != 0 ? Archive1: Archive0; }
+  UString GetDefaultItemName()  { return Archive1 != 0 ? DefaultItemName1: DefaultItemName0; }
+  int GetArchiverIndex() const { return Archive1 != 0 ? FormatIndex1: FormatIndex0; }
+  HRESULT Close();
+  void Release();
+};
+
+HRESULT OpenArchive(
+    CCodecs *codecs,
+    const UString &archiveName, 
+    CArchiveLink &archiveLink,
+    IArchiveOpenCallback *openCallback);
+
+HRESULT MyOpenArchive(
+    CCodecs *codecs,
+    const UString &archiveName, 
+    CArchiveLink &archiveLink,
+    IOpenCallbackUI *openCallbackUI);
+
+HRESULT ReOpenArchive(
+    CCodecs *codecs,
+    CArchiveLink &archiveLink, 
+    const UString &fileName);
+
+#endif
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/misc/libphysfs/lzma/CPP/7zip/UI/Common/PropIDUtils.cpp	Mon Apr 10 12:06:43 2017 -0400
@@ -0,0 +1,89 @@
+// PropIDUtils.cpp
+
+#include "StdAfx.h"
+
+#include "PropIDUtils.h"
+
+#include "Common/IntToString.h"
+#include "Common/StringConvert.h"
+
+#include "Windows/FileFind.h"
+#include "Windows/PropVariantConversions.h"
+
+#include "../../PropID.h"
+
+using namespace NWindows;
+
+static UString ConvertUInt32ToString(UInt32 value)
+{
+  wchar_t buffer[32];
+  ConvertUInt64ToString(value, buffer);
+  return buffer;
+}
+
+static void ConvertUInt32ToHex(UInt32 value, wchar_t *s)
+{
+  for (int i = 0; i < 8; i++)
+  {
+    int t = value & 0xF;
+    value >>= 4;
+    s[7 - i] = (wchar_t)((t < 10) ? (L'0' + t) : (L'A' + (t - 10)));
+  }
+  s[8] = L'\0';
+}
+
+UString ConvertPropertyToString(const PROPVARIANT &propVariant, PROPID propID, bool full)
+{
+  switch(propID)
+  {
+    case kpidCreationTime:
+    case kpidLastWriteTime:
+    case kpidLastAccessTime:
+    {
+      if (propVariant.vt != VT_FILETIME)
+        return UString(); // It is error;
+      FILETIME localFileTime;
+      if (propVariant.filetime.dwHighDateTime == 0 && 
+          propVariant.filetime.dwLowDateTime == 0)
+        return UString();
+      if (!::FileTimeToLocalFileTime(&propVariant.filetime, &localFileTime))
+        return UString(); // It is error;
+      return ConvertFileTimeToString(localFileTime, true, full);
+    }
+    case kpidCRC:
+    {
+      if(propVariant.vt != VT_UI4)
+        break;
+      wchar_t temp[12];
+      ConvertUInt32ToHex(propVariant.ulVal, temp);
+      return temp;
+    }
+    case kpidAttributes:
+    {
+      if(propVariant.vt != VT_UI4)
+        break;
+      UString result;
+      UInt32 attributes = propVariant.ulVal;
+      if (NFile::NFind::NAttributes::IsReadOnly(attributes)) result += L'R';
+      if (NFile::NFind::NAttributes::IsHidden(attributes)) result += L'H';
+      if (NFile::NFind::NAttributes::IsSystem(attributes)) result += L'S';
+      if (NFile::NFind::NAttributes::IsDirectory(attributes)) result += L'D';
+      if (NFile::NFind::NAttributes::IsArchived(attributes)) result += L'A';
+      if (NFile::NFind::NAttributes::IsCompressed(attributes)) result += L'C';
+      if (NFile::NFind::NAttributes::IsEncrypted(attributes)) result += L'E';
+      return result;
+    }
+    case kpidDictionarySize:
+    {
+      if(propVariant.vt != VT_UI4)
+        break;
+      UInt32 size = propVariant.ulVal;
+      if (size % (1 << 20) == 0)
+        return ConvertUInt32ToString(size >> 20) + L"MB";
+      if (size % (1 << 10) == 0)
+        return ConvertUInt32ToString(size >> 10) + L"KB";
+      return ConvertUInt32ToString(size);
+    }
+  }
+  return ConvertPropVariantToString(propVariant);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/misc/libphysfs/lzma/CPP/7zip/UI/Common/PropIDUtils.h	Mon Apr 10 12:06:43 2017 -0400
@@ -0,0 +1,10 @@
+// PropIDUtils.h
+
+#ifndef __PROPIDUTILS_H
+#define __PROPIDUTILS_H
+
+#include "Common/MyString.h"
+
+UString ConvertPropertyToString(const PROPVARIANT &propVariant, PROPID propID, bool full = true);
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/misc/libphysfs/lzma/CPP/7zip/UI/Common/Property.h	Mon Apr 10 12:06:43 2017 -0400
@@ -0,0 +1,14 @@
+// Property.h
+
+#ifndef __PROPERTY_H
+#define __PROPERTY_H
+
+#include "Common/MyString.h"
+
+struct CProperty
+{
+  UString Name;
+  UString Value;
+};
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/misc/libphysfs/lzma/CPP/7zip/UI/Common/SetProperties.cpp	Mon Apr 10 12:06:43 2017 -0400
@@ -0,0 +1,65 @@
+// SetProperties.cpp
+
+#include "StdAfx.h"
+
+#include "SetProperties.h"
+
+#include "Windows/PropVariant.h"
+#include "Common/MyString.h"
+#include "Common/StringToInt.h"
+#include "Common/MyCom.h"
+
+#include "../../Archive/IArchive.h"
+
+using namespace NWindows;
+using namespace NCOM;
+
+static void ParseNumberString(const UString &s, NCOM::CPropVariant &prop)
+{
+  const wchar_t *endPtr;
+  UInt64 result = ConvertStringToUInt64(s, &endPtr);
+  if (endPtr - (const wchar_t *)s != s.Length())
+    prop = s;
+  else if (result <= 0xFFFFFFFF)
+    prop = (UInt32)result;
+  else 
+    prop = result;
+}
+
+HRESULT SetProperties(IUnknown *unknown, const CObjectVector<CProperty> &properties)
+{
+  if (properties.IsEmpty())
+    return S_OK;
+  CMyComPtr<ISetProperties> setProperties;
+  unknown->QueryInterface(IID_ISetProperties, (void **)&setProperties);
+  if (!setProperties)
+    return S_OK;
+
+  UStringVector realNames;
+  CPropVariant *values = new CPropVariant[properties.Size()];
+  try
+  {
+    int i;
+    for(i = 0; i < properties.Size(); i++)
+    {
+      const CProperty &property = properties[i];
+      NCOM::CPropVariant propVariant;
+      if (!property.Value.IsEmpty())
+        ParseNumberString(property.Value, propVariant);
+      realNames.Add(property.Name);
+      values[i] = propVariant;
+    }
+    CRecordVector<const wchar_t *> names;
+    for(i = 0; i < realNames.Size(); i++)
+      names.Add((const wchar_t *)realNames[i]);
+    
+    RINOK(setProperties->SetProperties(&names.Front(), values, names.Size()));
+  }
+  catch(...)
+  {
+    delete []values;
+    throw;
+  }
+  delete []values;
+  return S_OK;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/misc/libphysfs/lzma/CPP/7zip/UI/Common/SetProperties.h	Mon Apr 10 12:06:43 2017 -0400
@@ -0,0 +1,10 @@
+// SetProperties.h
+
+#ifndef __SETPROPERTIES_H
+#define __SETPROPERTIES_H
+
+#include "Property.h"
+
+HRESULT SetProperties(IUnknown *unknown, const CObjectVector<CProperty> &properties);
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/misc/libphysfs/lzma/CPP/7zip/UI/Common/SortUtils.cpp	Mon Apr 10 12:06:43 2017 -0400
@@ -0,0 +1,22 @@
+// SortUtils.cpp
+
+#include "StdAfx.h"
+
+#include "SortUtils.h"
+#include "Common/Wildcard.h"
+
+static int CompareStrings(const int *p1, const int *p2, void *param)
+{
+  const UStringVector &strings = *(const UStringVector *)param;
+  return CompareFileNames(strings[*p1], strings[*p2]);
+}
+
+void SortFileNames(const UStringVector &strings, CIntVector &indices)
+{
+  indices.Clear();
+  int numItems = strings.Size();
+  indices.Reserve(numItems);
+  for(int i = 0; i < numItems; i++)
+    indices.Add(i);
+  indices.Sort(CompareStrings, (void *)&strings);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/misc/libphysfs/lzma/CPP/7zip/UI/Common/SortUtils.h	Mon Apr 10 12:06:43 2017 -0400
@@ -0,0 +1,10 @@
+// SortUtils.h
+
+#ifndef __SORTUTLS_H
+#define __SORTUTLS_H
+
+#include "Common/MyString.h"
+
+void SortFileNames(const UStringVector &strings, CIntVector &indices);
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/misc/libphysfs/lzma/CPP/7zip/UI/Common/TempFiles.cpp	Mon Apr 10 12:06:43 2017 -0400
@@ -0,0 +1,22 @@
+// TempFiles.cpp
+
+#include "StdAfx.h"
+
+#include "TempFiles.h"
+
+#include "Windows/FileDir.h"
+#include "Windows/FileIO.h"
+
+using namespace NWindows;
+using namespace NFile;
+
+void CTempFiles::Clear()
+{
+  while(!Paths.IsEmpty())
+  {
+    NDirectory::DeleteFileAlways((LPCWSTR)Paths.Back());
+    Paths.DeleteBack();
+  }
+}
+
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/misc/libphysfs/lzma/CPP/7zip/UI/Common/TempFiles.h	Mon Apr 10 12:06:43 2017 -0400
@@ -0,0 +1,16 @@
+// TempFiles.h
+
+#ifndef __TEMPFILES_H
+#define __TEMPFILES_H
+
+#include "Common/MyString.h"
+
+class CTempFiles
+{
+  void Clear();
+public:
+  UStringVector Paths;
+  ~CTempFiles() { Clear(); }
+};
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/misc/libphysfs/lzma/CPP/7zip/UI/Common/Update.cpp	Mon Apr 10 12:06:43 2017 -0400
@@ -0,0 +1,852 @@
+// Update.cpp
+
+#include "StdAfx.h"
+
+#ifdef _WIN32
+#include <mapi.h>
+#endif
+
+#include "Update.h"
+
+#include "Common/IntToString.h"
+#include "Common/StringConvert.h"
+#include "Common/CommandLineParser.h"
+
+#ifdef _WIN32
+#include "Windows/DLL.h"
+#endif
+
+#include "Windows/Defs.h"
+#include "Windows/FileDir.h"
+#include "Windows/FileFind.h"
+#include "Windows/FileName.h"
+#include "Windows/PropVariant.h"
+#include "Windows/PropVariantConversions.h"
+// #include "Windows/Synchronization.h"
+
+#include "../../Common/FileStreams.h"
+#include "../../Compress/Copy/CopyCoder.h"
+
+#include "../Common/DirItem.h"
+#include "../Common/EnumDirItems.h"
+#include "../Common/UpdateProduce.h"
+#include "../Common/OpenArchive.h"
+
+#include "TempFiles.h"
+#include "UpdateCallback.h"
+#include "EnumDirItems.h"
+#include "SetProperties.h"
+
+static const char *kUpdateIsNotSupoorted = 
+  "update operations are not supported for this archive";
+
+using namespace NCommandLineParser;
+using namespace NWindows;
+using namespace NCOM;
+using namespace NFile;
+using namespace NName;
+
+static const wchar_t *kTempFolderPrefix = L"7zE";
+
+using namespace NUpdateArchive;
+
+static HRESULT CopyBlock(ISequentialInStream *inStream, ISequentialOutStream *outStream)
+{
+  CMyComPtr<ICompressCoder> copyCoder = new NCompress::CCopyCoder;
+  return copyCoder->Code(inStream, outStream, NULL, NULL, NULL);
+}
+
+class COutMultiVolStream: 
+  public IOutStream,
+  public CMyUnknownImp
+{
+  int _streamIndex; // required stream
+  UInt64 _offsetPos; // offset from start of _streamIndex index
+  UInt64 _absPos;
+  UInt64 _length;
+
+  struct CSubStreamInfo
+  {
+    COutFileStream *StreamSpec;
+    CMyComPtr<IOutStream> Stream;
+    UString Name;
+    UInt64 Pos;
+    UInt64 RealSize;
+  };
+  CObjectVector<CSubStreamInfo> Streams;
+public:
+  // CMyComPtr<IArchiveUpdateCallback2> VolumeCallback;
+  CRecordVector<UInt64> Sizes;
+  UString Prefix;
+  CTempFiles *TempFiles;
+
+  void Init()
+  {
+    _streamIndex = 0;
+    _offsetPos = 0;
+    _absPos = 0;
+    _length = 0;
+  }
+
+  HRESULT Close(); 
+
+  MY_UNKNOWN_IMP1(IOutStream)
+
+  STDMETHOD(Write)(const void *data, UInt32 size, UInt32 *processedSize);
+  STDMETHOD(Seek)(Int64 offset, UInt32 seekOrigin, UInt64 *newPosition);
+  STDMETHOD(SetSize)(Int64 newSize);
+};
+
+// static NSynchronization::CCriticalSection g_TempPathsCS;
+
+HRESULT COutMultiVolStream::Close()
+{
+  HRESULT res = S_OK;
+  for (int i = 0; i < Streams.Size(); i++)
+  {
+    CSubStreamInfo &s = Streams[i];
+    if (s.StreamSpec)
+    {
+      HRESULT res2 = s.StreamSpec->Close();
+      if (res2 != S_OK)
+        res = res2;
+    }
+  }
+  return res;
+}
+
+STDMETHODIMP COutMultiVolStream::Write(const void *data, UInt32 size, UInt32 *processedSize)
+{
+  if(processedSize != NULL)
+    *processedSize = 0;
+  while(size > 0)
+  {
+    if (_streamIndex >= Streams.Size())
+    {
+      CSubStreamInfo subStream;
+
+      wchar_t temp[32];
+      ConvertUInt64ToString(_streamIndex + 1, temp);
+      UString res = temp;
+      while (res.Length() < 3)
+        res = UString(L'0') + res;
+      UString name = Prefix + res;
+      subStream.StreamSpec = new COutFileStream;
+      subStream.Stream = subStream.StreamSpec;
+      if(!subStream.StreamSpec->Create(name, false))
+        return ::GetLastError();
+      {
+        // NSynchronization::CCriticalSectionLock lock(g_TempPathsCS);
+        TempFiles->Paths.Add(name);
+      }
+
+      subStream.Pos = 0;
+      subStream.RealSize = 0;
+      subStream.Name = name;
+      Streams.Add(subStream);
+      continue;
+    }
+    CSubStreamInfo &subStream = Streams[_streamIndex];
+
+    int index = _streamIndex;
+    if (index >= Sizes.Size())
+      index = Sizes.Size() - 1;
+    UInt64 volSize = Sizes[index];
+
+    if (_offsetPos >= volSize)
+    {
+      _offsetPos -= volSize;
+      _streamIndex++;
+      continue;
+    }
+    if (_offsetPos != subStream.Pos)
+    {
+      // CMyComPtr<IOutStream> outStream;
+      // RINOK(subStream.Stream.QueryInterface(IID_IOutStream, &outStream));
+      RINOK(subStream.Stream->Seek(_offsetPos, STREAM_SEEK_SET, NULL));
+      subStream.Pos = _offsetPos;
+    }
+
+    UInt32 curSize = (UInt32)MyMin((UInt64)size, volSize - subStream.Pos);
+    UInt32 realProcessed;
+    RINOK(subStream.Stream->Write(data, curSize, &realProcessed));
+    data = (void *)((Byte *)data + realProcessed);
+    size -= realProcessed;
+    subStream.Pos += realProcessed;
+    _offsetPos += realProcessed;
+    _absPos += realProcessed;
+    if (_absPos > _length)
+      _length = _absPos;
+    if (_offsetPos > subStream.RealSize)
+      subStream.RealSize = _offsetPos;
+    if(processedSize != NULL)
+      *processedSize += realProcessed;
+    if (subStream.Pos == volSize)
+    {
+      _streamIndex++;
+      _offsetPos = 0;
+    }
+    if (realProcessed == 0 && curSize != 0)
+      return E_FAIL;
+    break;
+  }
+  return S_OK;
+}
+
+STDMETHODIMP COutMultiVolStream::Seek(Int64 offset, UInt32 seekOrigin, UInt64 *newPosition)
+{
+  if(seekOrigin >= 3)
+    return STG_E_INVALIDFUNCTION;
+  switch(seekOrigin)
+  {
+    case STREAM_SEEK_SET:
+      _absPos = offset;
+      break;
+    case STREAM_SEEK_CUR:
+      _absPos += offset;
+      break;
+    case STREAM_SEEK_END:
+      _absPos = _length + offset;
+      break;
+  }
+  _offsetPos = _absPos;
+  if (newPosition != NULL)
+    *newPosition = _absPos;
+  _streamIndex = 0;
+  return S_OK;
+}
+
+STDMETHODIMP COutMultiVolStream::SetSize(Int64 newSize)
+{
+  if (newSize < 0)
+    return E_INVALIDARG;
+  int i = 0;
+  while (i < Streams.Size())
+  {
+    CSubStreamInfo &subStream = Streams[i++];
+    if ((UInt64)newSize < subStream.RealSize)
+    {
+      RINOK(subStream.Stream->SetSize(newSize));
+      subStream.RealSize = newSize;
+      break;
+    }
+    newSize -= subStream.RealSize;
+  }
+  while (i < Streams.Size())
+  {
+    {
+      CSubStreamInfo &subStream = Streams.Back();
+      subStream.Stream.Release();
+      NDirectory::DeleteFileAlways(subStream.Name);
+    }
+    Streams.DeleteBack();
+  }
+  _offsetPos = _absPos;
+  _streamIndex = 0;
+  _length = newSize;
+  return S_OK;
+}
+
+static const wchar_t *kDefaultArchiveType = L"7z";
+static const wchar_t *kSFXExtension =
+  #ifdef _WIN32
+    L"exe";
+  #else
+    L"";
+  #endif
+
+bool CUpdateOptions::Init(const CCodecs *codecs, const UString &arcPath, const UString &arcType)
+{
+  if (!arcType.IsEmpty())
+    MethodMode.FormatIndex = codecs->FindFormatForArchiveType(arcType);
+  else
+  {
+    MethodMode.FormatIndex = codecs->FindFormatForArchiveName(arcPath);
+    if (MethodMode.FormatIndex < 0)
+      MethodMode.FormatIndex = codecs->FindFormatForArchiveType(kDefaultArchiveType);
+  }
+  if (MethodMode.FormatIndex < 0)
+    return false;
+  const CArcInfoEx &arcInfo = codecs->Formats[MethodMode.FormatIndex];
+  UString typeExt = arcInfo.GetMainExt();
+  UString ext = typeExt;
+  if (SfxMode)
+    ext = kSFXExtension;
+  ArchivePath.BaseExtension = ext;
+  ArchivePath.VolExtension = typeExt;
+  ArchivePath.ParseFromPath(arcPath);
+  for (int i = 0; i < Commands.Size(); i++)
+  {
+    CUpdateArchiveCommand &uc = Commands[i];
+    uc.ArchivePath.BaseExtension = ext;
+    uc.ArchivePath.VolExtension = typeExt;
+    uc.ArchivePath.ParseFromPath(uc.UserArchivePath);
+  }
+  return true;
+}
+
+
+static HRESULT Compress(
+    CCodecs *codecs,
+    const CActionSet &actionSet, 
+    IInArchive *archive,
+    const CCompressionMethodMode &compressionMethod,
+    CArchivePath &archivePath, 
+    const CObjectVector<CArchiveItem> &archiveItems,
+    bool shareForWrite,
+    bool stdInMode,
+    /* const UString & stdInFileName, */
+    bool stdOutMode,
+    const CObjectVector<CDirItem> &dirItems,
+    bool sfxMode,
+    const UString &sfxModule,
+    const CRecordVector<UInt64> &volumesSizes,
+    CTempFiles &tempFiles,
+    CUpdateErrorInfo &errorInfo,
+    IUpdateCallbackUI *callback)
+{
+  CMyComPtr<IOutArchive> outArchive;
+  if(archive != NULL)
+  {
+    CMyComPtr<IInArchive> archive2 = archive;
+    HRESULT result = archive2.QueryInterface(IID_IOutArchive, &outArchive);
+    if(result != S_OK)
+      throw kUpdateIsNotSupoorted;
+  }
+  else
+  {
+    RINOK(codecs->CreateOutArchive(compressionMethod.FormatIndex, outArchive));
+
+    #ifdef EXTERNAL_CODECS
+    {
+      CMyComPtr<ISetCompressCodecsInfo> setCompressCodecsInfo;
+      outArchive.QueryInterface(IID_ISetCompressCodecsInfo, (void **)&setCompressCodecsInfo);
+      if (setCompressCodecsInfo)
+      {
+        RINOK(setCompressCodecsInfo->SetCompressCodecsInfo(codecs));
+      }
+    }
+    #endif
+  }
+  if (outArchive == 0)
+    throw kUpdateIsNotSupoorted;
+  
+  NFileTimeType::EEnum fileTimeType;
+  UInt32 value;
+  RINOK(outArchive->GetFileTimeType(&value));
+
+  switch(value)
+  {
+    case NFileTimeType::kWindows:
+    case NFileTimeType::kDOS:
+    case NFileTimeType::kUnix:
+      fileTimeType = NFileTimeType::EEnum(value);
+      break;
+    default:
+      return E_FAIL;
+  }
+
+  CObjectVector<CUpdatePair> updatePairs;
+  GetUpdatePairInfoList(dirItems, archiveItems, fileTimeType, updatePairs); // must be done only once!!!
+  
+  CObjectVector<CUpdatePair2> updatePairs2;
+  UpdateProduce(updatePairs, actionSet, updatePairs2);
+
+  UInt32 numFiles = 0;
+  for (int i = 0; i < updatePairs2.Size(); i++)
+    if (updatePairs2[i].NewData)
+      numFiles++;
+  
+  RINOK(callback->SetNumFiles(numFiles));
+
+  
+  CArchiveUpdateCallback *updateCallbackSpec = new CArchiveUpdateCallback;
+  CMyComPtr<IArchiveUpdateCallback> updateCallback(updateCallbackSpec);
+  
+  updateCallbackSpec->ShareForWrite = shareForWrite;
+  updateCallbackSpec->StdInMode = stdInMode;
+  updateCallbackSpec->Callback = callback;
+  updateCallbackSpec->DirItems = &dirItems;
+  updateCallbackSpec->ArchiveItems = &archiveItems;
+  updateCallbackSpec->UpdatePairs = &updatePairs2;
+
+  CMyComPtr<ISequentialOutStream> outStream;
+
+  const UString &archiveName = archivePath.GetFinalPath();
+  if (!stdOutMode)
+  {
+    UString resultPath;
+    int pos;
+    if(!NFile::NDirectory::MyGetFullPathName(archiveName, resultPath, pos))
+      throw 1417161;
+    NFile::NDirectory::CreateComplexDirectory(resultPath.Left(pos));
+  }
+
+  COutFileStream *outStreamSpec = NULL;
+  COutMultiVolStream *volStreamSpec = NULL;
+
+  if (volumesSizes.Size() == 0)
+  {
+    if (stdOutMode)
+      outStream = new CStdOutFileStream;
+    else
+    {
+      outStreamSpec = new COutFileStream;
+      outStream = outStreamSpec;
+      bool isOK = false;
+      UString realPath;
+      for (int i = 0; i < (1 << 16); i++)
+      {
+        if (archivePath.Temp)
+        {
+          if (i > 0)
+          {
+            wchar_t s[32];
+            ConvertUInt64ToString(i, s);
+            archivePath.TempPostfix = s;
+          }
+          realPath = archivePath.GetTempPath();
+        }
+        else
+          realPath = archivePath.GetFinalPath();
+        if (outStreamSpec->Create(realPath, false))
+        {
+          tempFiles.Paths.Add(realPath);
+          isOK = true;
+          break;
+        }
+        if (::GetLastError() != ERROR_FILE_EXISTS)
+          break;
+        if (!archivePath.Temp)
+          break;
+      }
+      if (!isOK)
+      {
+        errorInfo.SystemError = ::GetLastError();
+        errorInfo.FileName = realPath;
+        errorInfo.Message = L"Can not open file";
+        return E_FAIL;
+      }
+    }
+  }
+  else
+  {
+    if (stdOutMode)
+      return E_FAIL;
+    volStreamSpec = new COutMultiVolStream;
+    outStream = volStreamSpec;
+    volStreamSpec->Sizes = volumesSizes;
+    volStreamSpec->Prefix = archivePath.GetFinalPath() + UString(L".");
+    volStreamSpec->TempFiles = &tempFiles;
+    volStreamSpec->Init();
+
+    /*
+    updateCallbackSpec->VolumesSizes = volumesSizes;
+    updateCallbackSpec->VolName = archivePath.Prefix + archivePath.Name;
+    if (!archivePath.VolExtension.IsEmpty())
+      updateCallbackSpec->VolExt = UString(L'.') + archivePath.VolExtension;
+    */
+  }
+
+  RINOK(SetProperties(outArchive, compressionMethod.Properties));
+
+  if (sfxMode)
+  {
+    CInFileStream *sfxStreamSpec = new CInFileStream;
+    CMyComPtr<IInStream> sfxStream(sfxStreamSpec);
+    if (!sfxStreamSpec->Open(sfxModule))
+    {
+      errorInfo.SystemError = ::GetLastError();
+      errorInfo.Message = L"Can't open sfx module";
+      errorInfo.FileName = sfxModule;
+      return E_FAIL;
+    }
+
+    CMyComPtr<ISequentialOutStream> sfxOutStream;
+    COutFileStream *outStreamSpec = NULL;
+    if (volumesSizes.Size() == 0)
+      sfxOutStream = outStream;
+    else
+    {
+      outStreamSpec = new COutFileStream;
+      sfxOutStream = outStreamSpec;
+      UString realPath = archivePath.GetFinalPath();
+      if (!outStreamSpec->Create(realPath, false))
+      {
+        errorInfo.SystemError = ::GetLastError();
+        errorInfo.FileName = realPath;
+        errorInfo.Message = L"Can not open file";
+        return E_FAIL;
+      }
+    }
+    RINOK(CopyBlock(sfxStream, sfxOutStream));
+    if (outStreamSpec)
+    {
+      RINOK(outStreamSpec->Close());
+    }
+  }
+
+  HRESULT result = outArchive->UpdateItems(outStream, updatePairs2.Size(), updateCallback);
+  callback->Finilize();
+  RINOK(result);
+  if (outStreamSpec)
+    result = outStreamSpec->Close();
+  else if (volStreamSpec)
+    result = volStreamSpec->Close();
+  return result;
+}
+
+HRESULT EnumerateInArchiveItems(const NWildcard::CCensor &censor,
+    IInArchive *archive,
+    const UString &defaultItemName,
+    const NWindows::NFile::NFind::CFileInfoW &archiveFileInfo,
+    CObjectVector<CArchiveItem> &archiveItems)
+{
+  archiveItems.Clear();
+  UInt32 numItems;
+  RINOK(archive->GetNumberOfItems(&numItems));
+  archiveItems.Reserve(numItems);
+  for(UInt32 i = 0; i < numItems; i++)
+  {
+    CArchiveItem ai;
+
+    RINOK(GetArchiveItemPath(archive, i, ai.Name));
+    RINOK(IsArchiveItemFolder(archive, i, ai.IsDirectory));
+    ai.Censored = censor.CheckPath(ai.Name.IsEmpty() ? defaultItemName : ai.Name, !ai.IsDirectory);
+    RINOK(GetArchiveItemFileTime(archive, i, 
+        archiveFileInfo.LastWriteTime, ai.LastWriteTime));
+
+    CPropVariant propertySize;
+    RINOK(archive->GetProperty(i, kpidSize, &propertySize));
+    ai.SizeIsDefined = (propertySize.vt != VT_EMPTY);
+    if (ai.SizeIsDefined)
+      ai.Size = ConvertPropVariantToUInt64(propertySize);
+
+    ai.IndexInServer = i;
+    archiveItems.Add(ai);
+  }
+  return S_OK;
+}
+
+
+static HRESULT UpdateWithItemLists(
+    CCodecs *codecs,
+    CUpdateOptions &options,
+    IInArchive *archive, 
+    const CObjectVector<CArchiveItem> &archiveItems,
+    const CObjectVector<CDirItem> &dirItems,
+    CTempFiles &tempFiles,
+    CUpdateErrorInfo &errorInfo,
+    IUpdateCallbackUI2 *callback)
+{
+  for(int i = 0; i < options.Commands.Size(); i++)
+  {
+    CUpdateArchiveCommand &command = options.Commands[i];
+    if (options.StdOutMode)
+    {
+      RINOK(callback->StartArchive(0, archive != 0));
+    }
+    else
+    {
+      RINOK(callback->StartArchive(command.ArchivePath.GetFinalPath(), 
+          i == 0 && options.UpdateArchiveItself && archive != 0));
+    }
+
+    RINOK(Compress(
+        codecs,
+        command.ActionSet, archive,
+        options.MethodMode, 
+        command.ArchivePath, 
+        archiveItems, 
+        options.OpenShareForWrite,
+        options.StdInMode, 
+        /* options.StdInFileName, */
+        options.StdOutMode,
+        dirItems, 
+        options.SfxMode, options.SfxModule, 
+        options.VolumesSizes,
+        tempFiles,
+        errorInfo, callback));
+
+    RINOK(callback->FinishArchive());
+  }
+  return S_OK;
+}
+
+#ifdef _WIN32
+class CCurrentDirRestorer
+{
+  UString m_CurrentDirectory;
+public:
+  CCurrentDirRestorer()
+    { NFile::NDirectory::MyGetCurrentDirectory(m_CurrentDirectory); }
+  ~CCurrentDirRestorer()
+    { RestoreDirectory();}
+  bool RestoreDirectory()
+    { return BOOLToBool(NFile::NDirectory::MySetCurrentDirectory(m_CurrentDirectory)); }
+};
+#endif
+
+struct CEnumDirItemUpdateCallback: public IEnumDirItemCallback
+{
+  IUpdateCallbackUI2 *Callback;
+  HRESULT CheckBreak() { return Callback->CheckBreak(); }
+};
+
+HRESULT UpdateArchive(
+    CCodecs *codecs,
+    const NWildcard::CCensor &censor, 
+    CUpdateOptions &options,
+    CUpdateErrorInfo &errorInfo,
+    IOpenCallbackUI *openCallback,
+    IUpdateCallbackUI2 *callback)
+{
+  if (options.StdOutMode && options.EMailMode)
+    return E_FAIL;
+
+  if (options.VolumesSizes.Size() > 0 && (options.EMailMode || options.SfxMode))
+    return E_NOTIMPL;
+
+  if (options.SfxMode)
+  {
+    CProperty property;
+    property.Name = L"rsfx";
+    property.Value = L"on";
+    options.MethodMode.Properties.Add(property);
+    if (options.SfxModule.IsEmpty())
+    {
+      errorInfo.Message = L"sfx file is not specified";
+      return E_FAIL;
+    }
+    UString name = options.SfxModule;
+    if (!NDirectory::MySearchPath(NULL, name, NULL, options.SfxModule))
+    {
+      errorInfo.Message = L"can't find specified sfx module";
+      return E_FAIL;
+    }
+  }
+
+  const UString archiveName = options.ArchivePath.GetFinalPath();
+
+  UString defaultItemName;
+  NFind::CFileInfoW archiveFileInfo;
+
+  CArchiveLink archiveLink;
+  IInArchive *archive = 0;
+  if (NFind::FindFile(archiveName, archiveFileInfo))
+  {
+    if (archiveFileInfo.IsDirectory())
+      throw "there is no such archive";
+    if (options.VolumesSizes.Size() > 0)
+      return E_NOTIMPL;
+    HRESULT result = MyOpenArchive(codecs, archiveName, archiveLink, openCallback);
+    RINOK(callback->OpenResult(archiveName, result));
+    RINOK(result);
+    if (archiveLink.VolumePaths.Size() > 1)
+    {
+      errorInfo.SystemError = (DWORD)E_NOTIMPL;
+      errorInfo.Message = L"Updating for multivolume archives is not implemented";
+      return E_NOTIMPL;
+    }
+    archive = archiveLink.GetArchive();
+    defaultItemName = archiveLink.GetDefaultItemName();
+  }
+  else
+  {
+    /*
+    if (archiveType.IsEmpty())
+      throw "type of archive is not specified";
+    */
+  }
+
+  CObjectVector<CDirItem> dirItems;
+  if (options.StdInMode)
+  {
+    CDirItem item;
+    item.FullPath = item.Name = options.StdInFileName;
+    item.Size = (UInt64)(Int64)-1;
+    item.Attributes = 0;
+    SYSTEMTIME st;
+    FILETIME ft;
+    GetSystemTime(&st);
+    SystemTimeToFileTime(&st, &ft);
+    item.CreationTime = item.LastAccessTime = item.LastWriteTime = ft;
+    dirItems.Add(item);
+  }
+  else
+  {
+    bool needScanning = false;
+    for(int i = 0; i < options.Commands.Size(); i++)
+      if (options.Commands[i].ActionSet.NeedScanning())
+        needScanning = true;
+    if (needScanning)
+    {
+      CEnumDirItemUpdateCallback enumCallback;
+      enumCallback.Callback = callback;
+      RINOK(callback->StartScanning());
+      UStringVector errorPaths;
+      CRecordVector<DWORD> errorCodes;
+      HRESULT res = EnumerateItems(censor, dirItems, &enumCallback, errorPaths, errorCodes);
+      for (int i = 0; i < errorPaths.Size(); i++)
+      {
+        RINOK(callback->CanNotFindError(errorPaths[i], errorCodes[i]));
+      }
+      if(res != S_OK) 
+      {
+        errorInfo.Message = L"Scanning error";
+        // errorInfo.FileName = errorPath;
+        return res;
+      }
+      RINOK(callback->FinishScanning());
+    }
+  }
+
+  UString tempDirPrefix;
+  bool usesTempDir = false;
+  
+  #ifdef _WIN32
+  NDirectory::CTempDirectoryW tempDirectory;
+  if (options.EMailMode && options.EMailRemoveAfter)
+  {
+    tempDirectory.Create(kTempFolderPrefix);
+    tempDirPrefix = tempDirectory.GetPath();
+    NormalizeDirPathPrefix(tempDirPrefix);
+    usesTempDir = true;
+  }
+  #endif
+
+  CTempFiles tempFiles;
+
+  bool createTempFile = false;
+  if(!options.StdOutMode && options.UpdateArchiveItself)
+  {
+    CArchivePath &ap = options.Commands[0].ArchivePath;
+    ap = options.ArchivePath;
+    // if ((archive != 0 && !usesTempDir) || !options.WorkingDir.IsEmpty())
+    if ((archive != 0 || !options.WorkingDir.IsEmpty()) && !usesTempDir && options.VolumesSizes.Size() == 0)
+    {
+      createTempFile = true;
+      ap.Temp = true;
+      if (!options.WorkingDir.IsEmpty())
+      {
+        ap.TempPrefix = options.WorkingDir;
+        NormalizeDirPathPrefix(ap.TempPrefix);
+      }
+    }
+  }
+
+  for(int i = 0; i < options.Commands.Size(); i++)
+  {
+    CArchivePath &ap = options.Commands[i].ArchivePath;
+    if (usesTempDir)
+    {
+      // Check it
+      ap.Prefix = tempDirPrefix;
+      // ap.Temp = true;
+      // ap.TempPrefix = tempDirPrefix;
+    }
+    if (i > 0 || !createTempFile)
+    {
+      const UString &path = ap.GetFinalPath();
+      if (NFind::DoesFileExist(path))
+      {
+        errorInfo.SystemError = 0;
+        errorInfo.Message = L"File already exists";
+        errorInfo.FileName = path;
+        return E_FAIL;
+      }
+    }
+  }
+
+  CObjectVector<CArchiveItem> archiveItems;
+  if (archive != NULL)
+  {
+    RINOK(EnumerateInArchiveItems(censor, 
+        archive, defaultItemName, archiveFileInfo, archiveItems));
+  }
+
+  RINOK(UpdateWithItemLists(codecs, options, archive, archiveItems, dirItems, 
+      tempFiles, errorInfo, callback));
+
+  if (archive != NULL)
+  {
+    RINOK(archiveLink.Close());
+    archiveLink.Release();
+  }
+
+  tempFiles.Paths.Clear();
+  if(createTempFile)
+  {
+    try
+    {
+      CArchivePath &ap = options.Commands[0].ArchivePath;
+      const UString &tempPath = ap.GetTempPath();
+      if (archive != NULL)
+        if (!NDirectory::DeleteFileAlways(archiveName))
+        {
+          errorInfo.SystemError = ::GetLastError();
+          errorInfo.Message = L"delete file error";
+          errorInfo.FileName = archiveName;
+          return E_FAIL;
+        }
+      if (!NDirectory::MyMoveFile(tempPath, archiveName))
+      {
+        errorInfo.SystemError = ::GetLastError();
+        errorInfo.Message = L"move file error";
+        errorInfo.FileName = tempPath;
+        errorInfo.FileName2 = archiveName;
+        return E_FAIL;
+      }
+    }
+    catch(...)
+    {
+      throw;
+    }
+  }
+
+  #ifdef _WIN32
+  if (options.EMailMode)
+  {
+    NDLL::CLibrary mapiLib;
+    if (!mapiLib.Load(TEXT("Mapi32.dll")))
+    {
+      errorInfo.SystemError = ::GetLastError();
+      errorInfo.Message = L"can not load Mapi32.dll";
+      return E_FAIL;
+    }
+    LPMAPISENDDOCUMENTS fnSend = (LPMAPISENDDOCUMENTS)
+        mapiLib.GetProcAddress("MAPISendDocuments");
+    if (fnSend == 0)
+    {
+      errorInfo.SystemError = ::GetLastError();
+      errorInfo.Message = L"can not find MAPISendDocuments function";
+      return E_FAIL;
+    }
+    UStringVector fullPaths;
+    int i;
+    for(i = 0; i < options.Commands.Size(); i++)
+    {
+      CArchivePath &ap = options.Commands[i].ArchivePath;
+      UString arcPath;
+      if(!NFile::NDirectory::MyGetFullPathName(ap.GetFinalPath(), arcPath))
+      {
+        errorInfo.SystemError = ::GetLastError();
+        return E_FAIL;
+      }
+      fullPaths.Add(arcPath);
+    }
+    CCurrentDirRestorer curDirRestorer;
+    for(i = 0; i < fullPaths.Size(); i++)
+    {
+      UString arcPath = fullPaths[i];
+      UString fileName = ExtractFileNameFromPath(arcPath);
+      AString path = GetAnsiString(arcPath);
+      AString name = GetAnsiString(fileName);
+      // Warning!!! MAPISendDocuments function changes Current directory
+      fnSend(0, ";", (LPSTR)(LPCSTR)path, (LPSTR)(LPCSTR)name, 0); 
+    }
+  }
+  #endif
+  return S_OK;
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/misc/libphysfs/lzma/CPP/7zip/UI/Common/Update.h	Mon Apr 10 12:06:43 2017 -0400
@@ -0,0 +1,165 @@
+// Update.h
+
+#ifndef __UPDATE_H
+#define __UPDATE_H
+
+#include "Common/Wildcard.h"
+#include "Windows/FileFind.h"
+#include "../../Archive/IArchive.h"
+
+#include "UpdateAction.h"
+#include "ArchiveOpenCallback.h"
+#include "UpdateCallback.h"
+#include "Property.h"
+#include "LoadCodecs.h"
+
+struct CArchivePath
+{
+  UString Prefix;   // path(folder) prefix including slash
+  UString Name; // base name
+  UString BaseExtension; // archive type extension or "exe" extension 
+  UString VolExtension;  // archive type extension for volumes
+
+  bool Temp;
+  UString TempPrefix;  // path(folder) for temp location
+  UString TempPostfix;
+
+  CArchivePath(): Temp(false) {};
+  
+  void ParseFromPath(const UString &path)
+  {
+    SplitPathToParts(path, Prefix, Name);
+    if (Name.IsEmpty())
+      return;
+    int dotPos = Name.ReverseFind(L'.');
+    if (dotPos <= 0)
+      return;
+    if (dotPos == Name.Length() - 1)
+    {
+      Name = Name.Left(dotPos);
+      BaseExtension.Empty();
+      return;
+    }
+    if (BaseExtension.CompareNoCase(Name.Mid(dotPos + 1)) == 0)
+    {
+      BaseExtension = Name.Mid(dotPos + 1);
+      Name = Name.Left(dotPos);
+    }
+    else
+      BaseExtension.Empty();
+  }
+
+  UString GetPathWithoutExt() const
+  {
+    return Prefix + Name;
+  }
+
+  UString GetFinalPath() const
+  {
+    UString path = GetPathWithoutExt();
+    if (!BaseExtension.IsEmpty())
+      path += UString(L'.') + BaseExtension;
+    return path;
+  }
+
+  
+  UString GetTempPath() const
+  {
+    UString path = TempPrefix + Name;
+    if (!BaseExtension.IsEmpty())
+      path += UString(L'.') + BaseExtension;
+    path += L".tmp";
+    path += TempPostfix;
+    return path; 
+  }
+};
+
+struct CUpdateArchiveCommand
+{
+  UString UserArchivePath;
+  CArchivePath ArchivePath;
+  NUpdateArchive::CActionSet ActionSet;
+};
+
+struct CCompressionMethodMode
+{
+  int FormatIndex;
+  CObjectVector<CProperty> Properties;
+  CCompressionMethodMode(): FormatIndex(-1) {}
+};
+
+struct CUpdateOptions
+{
+  CCompressionMethodMode MethodMode;
+
+  CObjectVector<CUpdateArchiveCommand> Commands;
+  bool UpdateArchiveItself;
+  CArchivePath ArchivePath;
+  
+  bool SfxMode;
+  UString SfxModule;
+  
+  bool OpenShareForWrite;
+
+  bool StdInMode;
+  UString StdInFileName;
+  bool StdOutMode;
+  
+  bool EMailMode;
+  bool EMailRemoveAfter;
+  UString EMailAddress;
+
+  UString WorkingDir;
+
+  bool Init(const CCodecs *codecs, const UString &arcPath, const UString &arcType);
+
+  CUpdateOptions():
+    UpdateArchiveItself(true),
+    SfxMode(false),
+    StdInMode(false),
+    StdOutMode(false),
+    EMailMode(false),
+    EMailRemoveAfter(false),
+    OpenShareForWrite(false)
+      {};
+  CRecordVector<UInt64> VolumesSizes;
+};
+
+struct CErrorInfo
+{
+  DWORD SystemError;
+  UString FileName;
+  UString FileName2;
+  UString Message;
+  // UStringVector ErrorPaths;
+  // CRecordVector<DWORD> ErrorCodes;
+  CErrorInfo(): SystemError(0) {};
+};
+
+struct CUpdateErrorInfo: public CErrorInfo
+{
+};
+
+#define INTERFACE_IUpdateCallbackUI2(x) \
+  INTERFACE_IUpdateCallbackUI(x) \
+  virtual HRESULT OpenResult(const wchar_t *name, HRESULT result) x; \
+  virtual HRESULT StartScanning() x; \
+  virtual HRESULT CanNotFindError(const wchar_t *name, DWORD systemError) x; \
+  virtual HRESULT FinishScanning() x; \
+  virtual HRESULT StartArchive(const wchar_t *name, bool updating) x; \
+  virtual HRESULT FinishArchive() x; \
+
+struct IUpdateCallbackUI2: public IUpdateCallbackUI
+{
+  INTERFACE_IUpdateCallbackUI2(=0)
+};
+
+HRESULT UpdateArchive(
+    CCodecs *codecs,
+    const NWildcard::CCensor &censor, 
+    CUpdateOptions &options,
+    CUpdateErrorInfo &errorInfo,
+    IOpenCallbackUI *openCallback,
+    IUpdateCallbackUI2 *callback);
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/misc/libphysfs/lzma/CPP/7zip/UI/Common/UpdateAction.cpp	Mon Apr 10 12:06:43 2017 -0400
@@ -0,0 +1,64 @@
+// UpdateAction.cpp
+
+#include "StdAfx.h"
+
+#include "UpdateAction.h"
+
+namespace NUpdateArchive {
+
+const CActionSet kAddActionSet = 
+{
+  NPairAction::kCopy,
+  NPairAction::kCopy,
+  NPairAction::kCompress,
+  NPairAction::kCompress,
+  NPairAction::kCompress,
+  NPairAction::kCompress,
+  NPairAction::kCompress
+};
+
+const CActionSet kUpdateActionSet = 
+{
+  NPairAction::kCopy,
+  NPairAction::kCopy,
+  NPairAction::kCompress,
+  NPairAction::kCopy,
+  NPairAction::kCompress,
+  NPairAction::kCopy,
+  NPairAction::kCompress
+};
+
+const CActionSet kFreshActionSet = 
+{
+  NPairAction::kCopy,
+  NPairAction::kCopy,
+  NPairAction::kIgnore,
+  NPairAction::kCopy,
+  NPairAction::kCompress,
+  NPairAction::kCopy,
+  NPairAction::kCompress
+};
+
+const CActionSet kSynchronizeActionSet = 
+{
+  NPairAction::kCopy,
+  NPairAction::kIgnore,
+  NPairAction::kCompress,
+  NPairAction::kCopy,
+  NPairAction::kCompress,
+  NPairAction::kCopy,
+  NPairAction::kCompress,
+};
+
+const CActionSet kDeleteActionSet = 
+{
+  NPairAction::kCopy,
+  NPairAction::kIgnore,
+  NPairAction::kIgnore,
+  NPairAction::kIgnore,
+  NPairAction::kIgnore,
+  NPairAction::kIgnore,
+  NPairAction::kIgnore
+};
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/misc/libphysfs/lzma/CPP/7zip/UI/Common/UpdateAction.h	Mon Apr 10 12:06:43 2017 -0400
@@ -0,0 +1,57 @@
+// UpdateAction.h
+
+#ifndef __UPDATE_ACTION_H
+#define __UPDATE_ACTION_H
+
+namespace NUpdateArchive {
+
+  namespace NPairState 
+  {
+    const int kNumValues = 7;
+    enum EEnum
+    {
+      kNotMasked = 0,
+      kOnlyInArchive,
+      kOnlyOnDisk,
+      kNewInArchive,
+      kOldInArchive,
+      kSameFiles,
+      kUnknowNewerFiles
+    };
+  }
+  namespace NPairAction
+  {
+    enum EEnum
+    {
+      kIgnore = 0,
+      kCopy,
+      kCompress,
+      kCompressAsAnti
+    };
+  }
+  struct CActionSet
+  {
+    NPairAction::EEnum StateActions[NPairState::kNumValues];
+    bool NeedScanning() const
+    {
+      int i;
+      for (i = 0; i < NPairState::kNumValues; i++)
+        if (StateActions[i] == NPairAction::kCompress)
+          return true;
+      for (i = 1; i < NPairState::kNumValues; i++)
+        if (StateActions[i] != NPairAction::kIgnore)
+          return true;
+      return false;
+    }
+  };
+  extern const CActionSet kAddActionSet;
+  extern const CActionSet kUpdateActionSet;
+  extern const CActionSet kFreshActionSet;
+  extern const CActionSet kSynchronizeActionSet;
+  extern const CActionSet kDeleteActionSet;
+};
+
+
+#endif
+
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/misc/libphysfs/lzma/CPP/7zip/UI/Common/UpdateCallback.cpp	Mon Apr 10 12:06:43 2017 -0400
@@ -0,0 +1,267 @@
+// UpdateCallback.cpp
+
+#include "StdAfx.h"
+
+#include "UpdateCallback.h"
+
+#include "Common/StringConvert.h"
+#include "Common/IntToString.h"
+#include "Common/Defs.h"
+#include "Common/ComTry.h"
+
+#include "Windows/PropVariant.h"
+
+#include "../../Common/FileStreams.h"
+
+using namespace NWindows;
+
+CArchiveUpdateCallback::CArchiveUpdateCallback():
+  Callback(0),
+  ShareForWrite(false),
+  StdInMode(false),
+  DirItems(0),
+  ArchiveItems(0),
+  UpdatePairs(0)
+  {}
+
+
+STDMETHODIMP CArchiveUpdateCallback::SetTotal(UInt64 size)
+{
+  COM_TRY_BEGIN
+  return Callback->SetTotal(size);
+  COM_TRY_END
+}
+
+STDMETHODIMP CArchiveUpdateCallback::SetCompleted(const UInt64 *completeValue)
+{
+  COM_TRY_BEGIN
+  return Callback->SetCompleted(completeValue);
+  COM_TRY_END
+}
+
+STDMETHODIMP CArchiveUpdateCallback::SetRatioInfo(const UInt64 *inSize, const UInt64 *outSize)
+{
+  COM_TRY_BEGIN
+  return Callback->SetRatioInfo(inSize, outSize);
+  COM_TRY_END
+}
+
+
+/*
+STATPROPSTG kProperties[] = 
+{
+  { NULL, kpidPath, VT_BSTR},
+  { NULL, kpidIsFolder, VT_BOOL},
+  { NULL, kpidSize, VT_UI8},
+  { NULL, kpidLastAccessTime, VT_FILETIME},
+  { NULL, kpidCreationTime, VT_FILETIME},
+  { NULL, kpidLastWriteTime, VT_FILETIME},
+  { NULL, kpidAttributes, VT_UI4},
+  { NULL, kpidIsAnti, VT_BOOL}
+};
+*/
+
+STDMETHODIMP CArchiveUpdateCallback::EnumProperties(IEnumSTATPROPSTG **)
+{
+  return E_NOTIMPL;
+  /*
+  return CStatPropEnumerator::CreateEnumerator(kProperties, 
+      sizeof(kProperties) / sizeof(kProperties[0]), enumerator);
+  */
+}
+
+STDMETHODIMP CArchiveUpdateCallback::GetUpdateItemInfo(UInt32 index, 
+      Int32 *newData, Int32 *newProperties, UInt32 *indexInArchive)
+{
+  COM_TRY_BEGIN
+  RINOK(Callback->CheckBreak());
+  const CUpdatePair2 &updatePair = (*UpdatePairs)[index];
+  if(newData != NULL)
+    *newData = BoolToInt(updatePair.NewData);
+  if(newProperties != NULL)
+    *newProperties = BoolToInt(updatePair.NewProperties);
+  if(indexInArchive != NULL)
+  {
+    if (updatePair.ExistInArchive)
+    {
+      if (ArchiveItems == 0)
+        *indexInArchive = updatePair.ArchiveItemIndex;
+      else
+        *indexInArchive = (*ArchiveItems)[updatePair.ArchiveItemIndex].IndexInServer;
+    }
+    else
+      *indexInArchive = UInt32(-1);
+  }
+  return S_OK;
+  COM_TRY_END
+}
+
+STDMETHODIMP CArchiveUpdateCallback::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *value)
+{
+  COM_TRY_BEGIN
+  const CUpdatePair2 &updatePair = (*UpdatePairs)[index];
+  NWindows::NCOM::CPropVariant propVariant;
+  
+  if (propID == kpidIsAnti)
+  {
+    propVariant = updatePair.IsAnti;
+    propVariant.Detach(value);
+    return S_OK;
+  }
+
+  if (updatePair.IsAnti)
+  {
+    switch(propID)
+    {
+      case kpidIsFolder:
+      case kpidPath:
+        break;
+      case kpidSize:
+        propVariant = (UInt64)0;
+        propVariant.Detach(value);
+        return S_OK;
+      default:
+        propVariant.Detach(value);
+        return S_OK;
+    }
+  }
+  
+  if(updatePair.ExistOnDisk)
+  {
+    const CDirItem &dirItem = (*DirItems)[updatePair.DirItemIndex];
+    switch(propID)
+    {
+      case kpidPath:
+        propVariant = dirItem.Name;
+        break;
+      case kpidIsFolder:
+        propVariant = dirItem.IsDirectory();
+        break;
+      case kpidSize:
+        propVariant = dirItem.Size;
+        break;
+      case kpidAttributes:
+        propVariant = dirItem.Attributes;
+        break;
+      case kpidLastAccessTime:
+        propVariant = dirItem.LastAccessTime;
+        break;
+      case kpidCreationTime:
+        propVariant = dirItem.CreationTime;
+        break;
+      case kpidLastWriteTime:
+        propVariant = dirItem.LastWriteTime;
+        break;
+    }
+  }
+  else
+  {
+    if (propID == kpidPath)
+    {
+      if (updatePair.NewNameIsDefined)
+      {
+        propVariant = updatePair.NewName;
+        propVariant.Detach(value);
+        return S_OK;
+      }
+    }
+    if (updatePair.ExistInArchive && Archive)
+    {
+      UInt32 indexInArchive;
+      if (ArchiveItems == 0)
+        indexInArchive = updatePair.ArchiveItemIndex;
+      else
+        indexInArchive = (*ArchiveItems)[updatePair.ArchiveItemIndex].IndexInServer;
+      return Archive->GetProperty(indexInArchive, propID, value);
+    }
+  }
+  propVariant.Detach(value);
+  return S_OK;
+  COM_TRY_END
+}
+
+STDMETHODIMP CArchiveUpdateCallback::GetStream(UInt32 index, ISequentialInStream **inStream)
+{
+  COM_TRY_BEGIN
+  const CUpdatePair2 &updatePair = (*UpdatePairs)[index];
+  if(!updatePair.NewData)
+    return E_FAIL;
+  
+  RINOK(Callback->CheckBreak());
+  RINOK(Callback->Finilize());
+
+  if(updatePair.IsAnti)
+  {
+    return Callback->GetStream((*ArchiveItems)[updatePair.ArchiveItemIndex].Name, true);
+  }
+  const CDirItem &dirItem = (*DirItems)[updatePair.DirItemIndex];
+  RINOK(Callback->GetStream(dirItem.Name, false));
+ 
+  if(dirItem.IsDirectory())
+    return S_OK;
+
+  if (StdInMode)
+  {
+    CStdInFileStream *inStreamSpec = new CStdInFileStream;
+    CMyComPtr<ISequentialInStream> inStreamLoc(inStreamSpec);
+    *inStream = inStreamLoc.Detach();
+  }
+  else
+  {
+    CInFileStream *inStreamSpec = new CInFileStream;
+    CMyComPtr<ISequentialInStream> inStreamLoc(inStreamSpec);
+    UString path = DirPrefix + dirItem.FullPath;
+    if(!inStreamSpec->OpenShared(path, ShareForWrite))
+    {
+      return Callback->OpenFileError(path, ::GetLastError());
+    }
+    *inStream = inStreamLoc.Detach();
+  }
+  return S_OK;
+  COM_TRY_END
+}
+
+STDMETHODIMP CArchiveUpdateCallback::SetOperationResult(Int32 operationResult)
+{
+  COM_TRY_BEGIN
+  return Callback->SetOperationResult(operationResult);
+  COM_TRY_END
+}
+
+STDMETHODIMP CArchiveUpdateCallback::GetVolumeSize(UInt32 index, UInt64 *size)
+{
+  if (VolumesSizes.Size() == 0)
+    return S_FALSE;
+  if (index >= (UInt32)VolumesSizes.Size())
+    index = VolumesSizes.Size() - 1;
+  *size = VolumesSizes[index];
+  return S_OK;
+}
+
+STDMETHODIMP CArchiveUpdateCallback::GetVolumeStream(UInt32 index, ISequentialOutStream **volumeStream)
+{
+  COM_TRY_BEGIN
+  wchar_t temp[32];
+  ConvertUInt64ToString(index + 1, temp);
+  UString res = temp;
+  while (res.Length() < 2)
+    res = UString(L'0') + res;
+  UString fileName = VolName;
+  fileName += L'.';
+  fileName += res;
+  fileName += VolExt;
+  COutFileStream *streamSpec = new COutFileStream;
+  CMyComPtr<ISequentialOutStream> streamLoc(streamSpec);
+  if(!streamSpec->Create(fileName, false))
+    return ::GetLastError();
+  *volumeStream = streamLoc.Detach();
+  return S_OK;
+  COM_TRY_END
+}
+
+STDMETHODIMP CArchiveUpdateCallback::CryptoGetTextPassword2(Int32 *passwordIsDefined, BSTR *password)
+{
+  COM_TRY_BEGIN
+  return Callback->CryptoGetTextPassword2(passwordIsDefined, password);
+  COM_TRY_END
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/misc/libphysfs/lzma/CPP/7zip/UI/Common/UpdateCallback.h	Mon Apr 10 12:06:43 2017 -0400
@@ -0,0 +1,82 @@
+// UpdateCallback.h
+
+#ifndef __UPDATECALLBACK_H
+#define __UPDATECALLBACK_H
+
+#include "Common/MyCom.h"
+#include "Common/MyString.h"
+
+#include "../../IPassword.h"
+#include "../../ICoder.h"
+
+#include "../Common/UpdatePair.h"
+#include "../Common/UpdateProduce.h"
+
+#define INTERFACE_IUpdateCallbackUI(x) \
+  virtual HRESULT SetTotal(UInt64 size) x; \
+  virtual HRESULT SetCompleted(const UInt64 *completeValue) x; \
+  virtual HRESULT SetRatioInfo(const UInt64 *inSize, const UInt64 *outSize) x; \
+  virtual HRESULT CheckBreak() x; \
+  virtual HRESULT Finilize() x; \
+  virtual HRESULT SetNumFiles(UInt64 numFiles) x; \
+  virtual HRESULT GetStream(const wchar_t *name, bool isAnti) x; \
+  virtual HRESULT OpenFileError(const wchar_t *name, DWORD systemError) x; \
+  virtual HRESULT SetOperationResult(Int32 operationResult) x; \
+  virtual HRESULT CryptoGetTextPassword2(Int32 *passwordIsDefined, BSTR *password) x; \
+
+  // virtual HRESULT CloseProgress() { return S_OK; };
+
+struct IUpdateCallbackUI
+{
+  INTERFACE_IUpdateCallbackUI(=0)
+};
+
+class CArchiveUpdateCallback: 
+  public IArchiveUpdateCallback2,
+  public ICryptoGetTextPassword2,
+  public ICompressProgressInfo,
+  public CMyUnknownImp
+{
+public:
+  MY_UNKNOWN_IMP3(
+      IArchiveUpdateCallback2, 
+      ICryptoGetTextPassword2,
+      ICompressProgressInfo)
+
+  // IProgress
+  STDMETHOD(SetTotal)(UInt64 size);
+  STDMETHOD(SetCompleted)(const UInt64 *completeValue);
+  STDMETHOD(SetRatioInfo)(const UInt64 *inSize, const UInt64 *outSize);
+
+  // IUpdateCallback
+  STDMETHOD(EnumProperties)(IEnumSTATPROPSTG **enumerator);  
+  STDMETHOD(GetUpdateItemInfo)(UInt32 index, 
+      Int32 *newData, Int32 *newProperties, UInt32 *indexInArchive);
+  STDMETHOD(GetProperty)(UInt32 index, PROPID propID, PROPVARIANT *value);
+  STDMETHOD(GetStream)(UInt32 index, ISequentialInStream **inStream);
+  STDMETHOD(SetOperationResult)(Int32 operationResult);
+
+  STDMETHOD(GetVolumeSize)(UInt32 index, UInt64 *size);
+  STDMETHOD(GetVolumeStream)(UInt32 index, ISequentialOutStream **volumeStream);
+
+  STDMETHOD(CryptoGetTextPassword2)(Int32 *passwordIsDefined, BSTR *password);
+
+public:
+  CRecordVector<UInt64> VolumesSizes;
+  UString VolName;
+  UString VolExt;
+
+  IUpdateCallbackUI *Callback;
+
+  UString DirPrefix;
+  bool ShareForWrite;
+  bool StdInMode;
+  const CObjectVector<CDirItem> *DirItems;
+  const CObjectVector<CArchiveItem> *ArchiveItems;
+  const CObjectVector<CUpdatePair2> *UpdatePairs;
+  CMyComPtr<IInArchive> Archive;
+
+  CArchiveUpdateCallback();
+};
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/misc/libphysfs/lzma/CPP/7zip/UI/Common/UpdatePair.cpp	Mon Apr 10 12:06:43 2017 -0400
@@ -0,0 +1,166 @@
+// UpdatePair.cpp
+
+#include "StdAfx.h"
+
+#include <time.h>
+
+#include "Common/Defs.h"
+#include "Common/Wildcard.h"
+#include "Windows/Time.h"
+
+#include "UpdatePair.h"
+#include "SortUtils.h"
+
+using namespace NWindows;
+using namespace NTime;
+
+static int MyCompareTime(NFileTimeType::EEnum fileTimeType, 
+    const FILETIME &time1, const FILETIME &time2)
+{
+  switch(fileTimeType)
+  {
+    case NFileTimeType::kWindows:
+      return ::CompareFileTime(&time1, &time2);
+    case NFileTimeType::kUnix:
+      {
+        UInt32 unixTime1, unixTime2;
+        if (!FileTimeToUnixTime(time1, unixTime1))
+        {
+          unixTime1 = 0;
+          // throw 4191614;
+        }
+        if (!FileTimeToUnixTime(time2, unixTime2))
+        {
+          unixTime2 = 0;
+          // throw 4191615;
+        }
+        return MyCompare(unixTime1, unixTime2);
+      }
+    case NFileTimeType::kDOS:
+      {
+        UInt32 dosTime1, dosTime2;
+        FileTimeToDosTime(time1, dosTime1);
+        FileTimeToDosTime(time2, dosTime2);
+        /*
+        if (!FileTimeToDosTime(time1, dosTime1))
+          throw 4191616;
+        if (!FileTimeToDosTime(time2, dosTime2))
+          throw 4191617;
+        */
+        return MyCompare(dosTime1, dosTime2);
+      }
+  }
+  throw 4191618;
+}
+
+static const wchar_t *kDuplicateFileNameMessage = L"Duplicate filename:";
+
+/*
+static const char *kNotCensoredCollisionMessaged = "Internal file name collision:\n";
+static const char *kSameTimeChangedSizeCollisionMessaged = 
+    "Collision between files with same date/time and different sizes:\n";
+*/
+
+static void TestDuplicateString(const UStringVector &strings, const CIntVector &indices)
+{
+  for(int i = 0; i + 1 < indices.Size(); i++)
+    if (CompareFileNames(strings[indices[i]], strings[indices[i + 1]]) == 0)
+    {
+      UString message = kDuplicateFileNameMessage;
+      message += L"\n";
+      message += strings[indices[i]];
+      message += L"\n";
+      message += strings[indices[i + 1]];
+      throw message;
+    }
+}
+
+void GetUpdatePairInfoList(
+    const CObjectVector<CDirItem> &dirItems, 
+    const CObjectVector<CArchiveItem> &archiveItems,
+    NFileTimeType::EEnum fileTimeType,
+    CObjectVector<CUpdatePair> &updatePairs)
+{
+  CIntVector dirIndices, archiveIndices;
+  UStringVector dirNames, archiveNames;
+  
+  int numDirItems = dirItems.Size(); 
+  int i;
+  for(i = 0; i < numDirItems; i++)
+    dirNames.Add(dirItems[i].Name);
+  SortFileNames(dirNames, dirIndices);
+  TestDuplicateString(dirNames, dirIndices);
+
+  int numArchiveItems = archiveItems.Size(); 
+  for(i = 0; i < numArchiveItems; i++)
+    archiveNames.Add(archiveItems[i].Name);
+  SortFileNames(archiveNames, archiveIndices);
+  TestDuplicateString(archiveNames, archiveIndices);
+  
+  int dirItemIndex = 0, archiveItemIndex = 0; 
+  CUpdatePair pair;
+  while(dirItemIndex < numDirItems && archiveItemIndex < numArchiveItems)
+  {
+    int dirItemIndex2 = dirIndices[dirItemIndex],
+        archiveItemIndex2 = archiveIndices[archiveItemIndex]; 
+    const CDirItem &dirItem = dirItems[dirItemIndex2];
+    const CArchiveItem &archiveItem = archiveItems[archiveItemIndex2];
+    int compareResult = CompareFileNames(dirItem.Name, archiveItem.Name);
+    if (compareResult < 0)
+    {
+        pair.State = NUpdateArchive::NPairState::kOnlyOnDisk;
+        pair.DirItemIndex = dirItemIndex2;
+        dirItemIndex++;
+    }
+    else if (compareResult > 0)
+    {
+      pair.State = archiveItem.Censored ? 
+        NUpdateArchive::NPairState::kOnlyInArchive: NUpdateArchive::NPairState::kNotMasked;
+      pair.ArchiveItemIndex = archiveItemIndex2;
+      archiveItemIndex++;
+    }
+    else
+    {
+      if (!archiveItem.Censored)
+        throw 1082022;; // TTString(kNotCensoredCollisionMessaged + dirItem.Name);
+      pair.DirItemIndex = dirItemIndex2;
+      pair.ArchiveItemIndex = archiveItemIndex2;
+      switch (MyCompareTime(fileTimeType, dirItem.LastWriteTime, archiveItem.LastWriteTime))
+      {
+        case -1:
+          pair.State = NUpdateArchive::NPairState::kNewInArchive;
+          break;
+        case 1:
+          pair.State = NUpdateArchive::NPairState::kOldInArchive;
+          break;
+        default:
+          if (archiveItem.SizeIsDefined)
+            if (dirItem.Size != archiveItem.Size)
+              // throw 1082034; // kSameTimeChangedSizeCollisionMessaged;
+              pair.State = NUpdateArchive::NPairState::kUnknowNewerFiles;
+            else
+              pair.State = NUpdateArchive::NPairState::kSameFiles;
+          else
+              pair.State = NUpdateArchive::NPairState::kUnknowNewerFiles;
+      }
+      dirItemIndex++;
+      archiveItemIndex++;
+    }
+    updatePairs.Add(pair);
+  }
+  for(;dirItemIndex < numDirItems; dirItemIndex++)
+  {
+    pair.State = NUpdateArchive::NPairState::kOnlyOnDisk;
+    pair.DirItemIndex = dirIndices[dirItemIndex];
+    updatePairs.Add(pair);
+  }
+  for(;archiveItemIndex < numArchiveItems; archiveItemIndex++)
+  {
+    int archiveItemIndex2 = archiveIndices[archiveItemIndex]; 
+    const CArchiveItem &archiveItem = archiveItems[archiveItemIndex2];
+    pair.State = archiveItem.Censored ?  
+        NUpdateArchive::NPairState::kOnlyInArchive: NUpdateArchive::NPairState::kNotMasked;
+    pair.ArchiveItemIndex = archiveItemIndex2;
+    updatePairs.Add(pair);
+  }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/misc/libphysfs/lzma/CPP/7zip/UI/Common/UpdatePair.h	Mon Apr 10 12:06:43 2017 -0400
@@ -0,0 +1,24 @@
+// UpdatePair.h
+
+#ifndef __UPDATE_PAIR_H
+#define __UPDATE_PAIR_H
+
+#include "DirItem.h"
+#include "UpdateAction.h"
+
+#include "../../Archive/IArchive.h"
+
+struct CUpdatePair
+{
+  NUpdateArchive::NPairState::EEnum State;
+  int ArchiveItemIndex;
+  int DirItemIndex;
+};
+
+void GetUpdatePairInfoList(
+    const CObjectVector<CDirItem> &dirItems,
+    const CObjectVector<CArchiveItem> &archiveItems,
+    NFileTimeType::EEnum fileTimeType,
+    CObjectVector<CUpdatePair> &updatePairs);
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/misc/libphysfs/lzma/CPP/7zip/UI/Common/UpdateProduce.cpp	Mon Apr 10 12:06:43 2017 -0400
@@ -0,0 +1,63 @@
+// UpdateProduce.cpp
+
+#include "StdAfx.h"
+
+#include "UpdateProduce.h"
+
+using namespace NUpdateArchive;
+
+static const char *kUpdateActionSetCollision =
+    "Internal collision in update action set";
+
+void UpdateProduce(
+    const CObjectVector<CUpdatePair> &updatePairs,
+    const NUpdateArchive::CActionSet &actionSet,
+    CObjectVector<CUpdatePair2> &operationChain)
+{
+  for(int i = 0; i < updatePairs.Size(); i++)
+  {
+    // CUpdateArchiveRange aRange;
+    const CUpdatePair &pair = updatePairs[i];
+
+    CUpdatePair2 pair2;
+    pair2.IsAnti = false;
+    pair2.ArchiveItemIndex = pair.ArchiveItemIndex;
+    pair2.DirItemIndex = pair.DirItemIndex;
+    pair2.ExistInArchive = (pair.State != NPairState::kOnlyOnDisk);
+    pair2.ExistOnDisk = (pair.State != NPairState::kOnlyInArchive && pair.State != NPairState::kNotMasked);
+    switch(actionSet.StateActions[pair.State])
+    {
+      case NPairAction::kIgnore:
+        /*
+        if (pair.State != NPairState::kOnlyOnDisk)
+          IgnoreArchiveItem(m_ArchiveItems[pair.ArchiveItemIndex]);
+        // cout << "deleting";
+        */
+        break;
+      case NPairAction::kCopy:
+        {
+          if (pair.State == NPairState::kOnlyOnDisk)
+            throw kUpdateActionSetCollision;
+          pair2.NewData = pair2.NewProperties = false;
+          operationChain.Add(pair2);
+          break;
+        }
+      case NPairAction::kCompress:
+        {
+          if (pair.State == NPairState::kOnlyInArchive || 
+            pair.State == NPairState::kNotMasked)
+            throw kUpdateActionSetCollision;
+          pair2.NewData = pair2.NewProperties = true;
+          operationChain.Add(pair2);
+          break;
+        }
+      case NPairAction::kCompressAsAnti:
+        {
+          pair2.IsAnti = true;
+          pair2.NewData = pair2.NewProperties = true;
+          operationChain.Add(pair2);
+          break;
+        }
+    }
+  }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/misc/libphysfs/lzma/CPP/7zip/UI/Common/UpdateProduce.h	Mon Apr 10 12:06:43 2017 -0400
@@ -0,0 +1,31 @@
+// UpdateProduce.h
+
+#ifndef __UPDATE_PRODUCE_H
+#define __UPDATE_PRODUCE_H
+
+#include "UpdatePair.h"
+
+struct CUpdatePair2
+{
+  // bool OperationIsCompress;
+  bool NewData;
+  bool NewProperties;
+
+  bool ExistInArchive;
+  bool ExistOnDisk;
+  bool IsAnti;
+  int ArchiveItemIndex;
+  int DirItemIndex;
+
+  bool NewNameIsDefined;
+  UString NewName;
+
+  CUpdatePair2(): NewNameIsDefined(false) {}
+};
+
+void UpdateProduce(
+    const CObjectVector<CUpdatePair> &updatePairs,
+    const NUpdateArchive::CActionSet &actionSet,
+    CObjectVector<CUpdatePair2> &operationChain);
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/misc/libphysfs/lzma/CPP/7zip/UI/Common/WorkDir.cpp	Mon Apr 10 12:06:43 2017 -0400
@@ -0,0 +1,64 @@
+// WorkDir.cpp
+
+#include "StdAfx.h"
+
+#include "WorkDir.h"
+
+#include "Common/StringConvert.h"
+#include "Common/Wildcard.h"
+
+#include "Windows/FileName.h"
+#include "Windows/FileDir.h"
+
+static inline UINT GetCurrentCodePage() 
+  { return ::AreFileApisANSI() ? CP_ACP : CP_OEMCP; } 
+
+using namespace NWindows;
+using namespace NFile;
+using namespace NName;
+
+UString GetWorkDir(const NWorkDir::CInfo &workDirInfo, const UString &path)
+{
+  NWorkDir::NMode::EEnum mode = workDirInfo.Mode;
+  if (workDirInfo.ForRemovableOnly)
+  {
+    mode = NWorkDir::NMode::kCurrent;
+    UString prefix = path.Left(3);
+    if (prefix[1] == L':' && prefix[2] == L'\\')
+    {
+      UINT driveType = GetDriveType(GetSystemString(prefix, GetCurrentCodePage()));
+      if (driveType == DRIVE_CDROM || driveType == DRIVE_REMOVABLE)
+        mode = workDirInfo.Mode;
+    }
+    /*
+    CParsedPath parsedPath;
+    parsedPath.ParsePath(archiveName);
+    UINT driveType = GetDriveType(parsedPath.Prefix);
+    if ((driveType != DRIVE_CDROM) && (driveType != DRIVE_REMOVABLE))
+      mode = NZipSettings::NWorkDir::NMode::kCurrent;
+    */
+  }
+  switch(mode)
+  {
+    case NWorkDir::NMode::kCurrent:
+    {
+      return ExtractDirPrefixFromPath(path);
+    }
+    case NWorkDir::NMode::kSpecified:
+    {
+      UString tempDir = workDirInfo.Path;
+      NormalizeDirPathPrefix(tempDir);
+      return tempDir;
+    }
+    default:
+    {
+      UString tempDir;
+      if(!NFile::NDirectory::MyGetTempPath(tempDir))
+        throw 141717;
+      return tempDir;
+    }
+  }
+}
+
+
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/misc/libphysfs/lzma/CPP/7zip/UI/Common/WorkDir.h	Mon Apr 10 12:06:43 2017 -0400
@@ -0,0 +1,10 @@
+// WorkDir.h
+
+#ifndef __WORKDIR_H
+#define __WORKDIR_H
+
+#include "ZipRegistry.h"
+
+UString GetWorkDir(const NWorkDir::CInfo &workDirInfo, const UString &path);
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/misc/libphysfs/lzma/CPP/7zip/UI/Common/ZipRegistry.h	Mon Apr 10 12:06:43 2017 -0400
@@ -0,0 +1,98 @@
+// ZipRegistry.h
+
+#ifndef __ZIPREGISTRY_H
+#define __ZIPREGISTRY_H
+
+#include "Common/MyString.h"
+#include "Common/Types.h"
+#include "ExtractMode.h"
+
+namespace NExtract
+{
+  struct CInfo
+  {
+    NPathMode::EEnum PathMode;
+    NOverwriteMode::EEnum OverwriteMode;
+    UStringVector Paths;
+    bool ShowPassword;
+  };
+}
+
+namespace NCompression {
+  
+  struct CFormatOptions
+  {
+    CSysString FormatID;
+    UString Options;
+    UString Method;
+    UString EncryptionMethod;
+    UInt32 Level;
+    UInt32 Dictionary;
+    UInt32 Order;
+    UInt32 BlockLogSize;
+    UInt32 NumThreads;
+    void ResetForLevelChange() 
+    { 
+      BlockLogSize = NumThreads = Level = Dictionary = Order = UInt32(-1); 
+      Method.Empty();
+      // EncryptionMethod.Empty();
+      // Options.Empty();
+    }
+    CFormatOptions() { ResetForLevelChange(); }
+  };
+
+  struct CInfo
+  {
+    UStringVector HistoryArchives;
+    UInt32 Level;
+    UString ArchiveType;
+
+    CObjectVector<CFormatOptions> FormatOptionsVector;
+
+    bool ShowPassword;
+    bool EncryptHeaders;
+  };
+}
+
+namespace NWorkDir{
+  
+  namespace NMode
+  {
+    enum EEnum
+    {
+      kSystem,
+      kCurrent,
+      kSpecified
+    };
+  }
+  struct CInfo
+  {
+    NMode::EEnum Mode;
+    UString Path;
+    bool ForRemovableOnly;
+    void SetForRemovableOnlyDefault() { ForRemovableOnly = true; }
+    void SetDefault()
+    {
+      Mode = NMode::kSystem;
+      Path.Empty();
+      SetForRemovableOnlyDefault();
+    }
+  };
+}
+
+void SaveExtractionInfo(const NExtract::CInfo &info);
+void ReadExtractionInfo(NExtract::CInfo &info);
+
+void SaveCompressionInfo(const NCompression::CInfo &info);
+void ReadCompressionInfo(NCompression::CInfo &info);
+
+void SaveWorkDirInfo(const NWorkDir::CInfo &info);
+void ReadWorkDirInfo(NWorkDir::CInfo &info);
+
+void SaveCascadedMenu(bool enabled);
+bool ReadCascadedMenu();
+
+void SaveContextMenuStatus(UInt32 value);
+bool ReadContextMenuStatus(UInt32 &value);
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/misc/libphysfs/lzma/CPP/7zip/UI/Console/ConsoleClose.cpp	Mon Apr 10 12:06:43 2017 -0400
@@ -0,0 +1,63 @@
+// ConsoleClose.cpp
+
+#include "StdAfx.h"
+
+#include "ConsoleClose.h"
+
+static int g_BreakCounter = 0;
+static const int kBreakAbortThreshold = 2;
+
+namespace NConsoleClose {
+
+static BOOL WINAPI HandlerRoutine(DWORD ctrlType)
+{
+  if (ctrlType == CTRL_LOGOFF_EVENT)
+  {
+    // printf("\nCTRL_LOGOFF_EVENT\n");
+    return TRUE;
+  }
+
+  g_BreakCounter++;
+  if (g_BreakCounter < kBreakAbortThreshold)
+    return TRUE;
+  return FALSE;
+  /*
+  switch(ctrlType)
+  {
+    case CTRL_C_EVENT:
+    case CTRL_BREAK_EVENT:
+      if (g_BreakCounter < kBreakAbortThreshold)
+      return TRUE;
+  }
+  return FALSE;
+  */
+}
+
+bool TestBreakSignal()
+{
+  /*
+  if (g_BreakCounter > 0)
+    return true;
+  */
+  return (g_BreakCounter > 0);
+}
+
+void CheckCtrlBreak()
+{
+  if (TestBreakSignal())
+    throw CCtrlBreakException();
+}
+
+CCtrlHandlerSetter::CCtrlHandlerSetter()
+{
+  if(!SetConsoleCtrlHandler(HandlerRoutine, TRUE))
+    throw "SetConsoleCtrlHandler fails";
+}
+
+CCtrlHandlerSetter::~CCtrlHandlerSetter()
+{
+  if(!SetConsoleCtrlHandler(HandlerRoutine, FALSE))
+    throw "SetConsoleCtrlHandler fails";
+}
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/misc/libphysfs/lzma/CPP/7zip/UI/Console/ConsoleClose.h	Mon Apr 10 12:06:43 2017 -0400
@@ -0,0 +1,24 @@
+// ConsoleCloseUtils.h
+
+#ifndef __CONSOLECLOSEUTILS_H
+#define __CONSOLECLOSEUTILS_H
+
+namespace NConsoleClose {
+
+bool TestBreakSignal();
+
+class CCtrlHandlerSetter
+{
+public:
+  CCtrlHandlerSetter();
+  virtual ~CCtrlHandlerSetter();
+};
+
+class CCtrlBreakException 
+{};
+
+void CheckCtrlBreak();
+
+}
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/misc/libphysfs/lzma/CPP/7zip/UI/Console/ExtractCallbackConsole.cpp	Mon Apr 10 12:06:43 2017 -0400
@@ -0,0 +1,235 @@
+// ExtractCallbackConsole.h
+
+#include "StdAfx.h"
+
+#include "ExtractCallbackConsole.h"
+#include "UserInputUtils.h"
+#include "ConsoleClose.h"
+
+#include "Common/Wildcard.h"
+
+#include "Windows/FileDir.h"
+#include "Windows/FileFind.h"
+#include "Windows/Time.h"
+#include "Windows/Defs.h"
+#include "Windows/PropVariant.h"
+#include "Windows/Error.h"
+#include "Windows/PropVariantConversions.h"
+
+#include "../../Common/FilePathAutoRename.h"
+
+#include "../Common/ExtractingFilePath.h"
+
+using namespace NWindows;
+using namespace NFile;
+using namespace NDirectory;
+
+static const char *kTestingString    =  "Testing     ";
+static const char *kExtractingString =  "Extracting  ";
+static const char *kSkippingString   =  "Skipping    ";
+
+// static const char *kCantAutoRename = "can not create file with auto name\n";
+// static const char *kCantRenameFile = "can not rename existing file\n";
+// static const char *kCantDeleteOutputFile = "can not delete output file ";
+static const char *kError = "ERROR: ";
+static const char *kMemoryExceptionMessage = "Can't allocate required memory!";
+
+static const char *kProcessing = "Processing archive: ";
+static const char *kEverythingIsOk = "Everything is Ok";
+static const char *kNoFiles = "No files to process";
+
+static const char *kUnsupportedMethod = "Unsupported Method";
+static const char *kCrcFailed = "CRC Failed";
+static const char *kCrcFailedEncrypted = "CRC Failed in encrypted file. Wrong password?";
+static const char *kDataError = "Data Error";
+static const char *kDataErrorEncrypted = "Data Error in encrypted file. Wrong password?";
+static const char *kUnknownError = "Unknown Error";
+
+STDMETHODIMP CExtractCallbackConsole::SetTotal(UInt64)
+{
+  if (NConsoleClose::TestBreakSignal())
+    return E_ABORT;
+  return S_OK;
+}
+
+STDMETHODIMP CExtractCallbackConsole::SetCompleted(const UInt64 *)
+{
+  if (NConsoleClose::TestBreakSignal())
+    return E_ABORT;
+  return S_OK;
+}
+
+STDMETHODIMP CExtractCallbackConsole::AskOverwrite(
+    const wchar_t *existName, const FILETIME *, const UInt64 *,
+    const wchar_t *newName, const FILETIME *, const UInt64 *,
+    Int32 *answer)
+{
+  (*OutStream) << "file " << existName << 
+    "\nalready exists. Overwrite with " << endl;
+  (*OutStream) << newName;
+  
+  NUserAnswerMode::EEnum overwriteAnswer = ScanUserYesNoAllQuit(OutStream);
+  
+  switch(overwriteAnswer)
+  {
+    case NUserAnswerMode::kQuit:
+      return E_ABORT;
+    case NUserAnswerMode::kNo:
+      *answer = NOverwriteAnswer::kNo;
+      break;
+    case NUserAnswerMode::kNoAll:
+      *answer = NOverwriteAnswer::kNoToAll;
+      break;
+    case NUserAnswerMode::kYesAll:
+      *answer = NOverwriteAnswer::kYesToAll;
+      break;
+    case NUserAnswerMode::kYes:
+      *answer = NOverwriteAnswer::kYes;
+      break;
+    case NUserAnswerMode::kAutoRename:
+      *answer = NOverwriteAnswer::kAutoRename;
+      break;
+    default:
+      return E_FAIL;
+  }
+  return S_OK;
+}
+
+STDMETHODIMP CExtractCallbackConsole::PrepareOperation(const wchar_t *name, bool /* isFolder */, Int32 askExtractMode, const UInt64 *position)
+{
+  switch (askExtractMode)
+  {
+    case NArchive::NExtract::NAskMode::kExtract:
+      (*OutStream) << kExtractingString;
+      break;
+    case NArchive::NExtract::NAskMode::kTest:
+      (*OutStream) << kTestingString;
+      break;
+    case NArchive::NExtract::NAskMode::kSkip:
+      (*OutStream) << kSkippingString;
+      break;
+  };
+  (*OutStream) << name;
+  if (position != 0)
+    (*OutStream) << " <" << *position << ">";
+  return S_OK;
+}
+
+STDMETHODIMP CExtractCallbackConsole::MessageError(const wchar_t *message)
+{
+  (*OutStream) << message << endl;
+  NumFileErrorsInCurrentArchive++;
+  NumFileErrors++;
+  return S_OK;
+}
+
+STDMETHODIMP CExtractCallbackConsole::SetOperationResult(Int32 operationResult, bool encrypted)
+{
+  switch(operationResult)
+  {
+    case NArchive::NExtract::NOperationResult::kOK:
+      break;
+    default:
+    {
+      NumFileErrorsInCurrentArchive++;
+      NumFileErrors++;
+      (*OutStream) << "     ";
+      switch(operationResult)
+      {
+        case NArchive::NExtract::NOperationResult::kUnSupportedMethod:
+          (*OutStream) << kUnsupportedMethod;
+          break;
+        case NArchive::NExtract::NOperationResult::kCRCError:
+          (*OutStream) << (encrypted ? kCrcFailedEncrypted: kCrcFailed);
+          break;
+        case NArchive::NExtract::NOperationResult::kDataError:
+          (*OutStream) << (encrypted ? kDataErrorEncrypted : kDataError);
+          break;
+        default:
+          (*OutStream) << kUnknownError;
+      }
+    }
+  }
+  (*OutStream) << endl;
+  return S_OK;
+}
+
+STDMETHODIMP CExtractCallbackConsole::CryptoGetTextPassword(BSTR *password)
+{
+  if (!PasswordIsDefined)
+  {
+    Password = GetPassword(OutStream); 
+    PasswordIsDefined = true;
+  }
+  CMyComBSTR tempName(Password);
+  *password = tempName.Detach();
+  return S_OK;
+}
+
+HRESULT CExtractCallbackConsole::BeforeOpen(const wchar_t *name)
+{
+  NumArchives++;
+  NumFileErrorsInCurrentArchive = 0;
+  (*OutStream) << endl << kProcessing << name << endl;
+  return S_OK;
+}
+
+HRESULT CExtractCallbackConsole::OpenResult(const wchar_t * /* name */, HRESULT result, bool encrypted)
+{
+  (*OutStream) << endl;
+  if (result != S_OK)
+  {
+    (*OutStream) << "Error: ";
+    if (encrypted)
+      (*OutStream) << "Can not open encrypted archive. Wrong password?";
+    else
+      (*OutStream) << "Can not open file as archive";
+    (*OutStream) << endl;
+    NumArchiveErrors++;
+  }
+  return S_OK;
+}
+  
+HRESULT CExtractCallbackConsole::ThereAreNoFiles()
+{
+  (*OutStream) << endl << kNoFiles << endl;
+  return S_OK;
+}
+
+HRESULT CExtractCallbackConsole::ExtractResult(HRESULT result)
+{
+  if (result == S_OK)
+  {
+    (*OutStream) << endl;
+    if (NumFileErrorsInCurrentArchive == 0)
+      (*OutStream) << kEverythingIsOk << endl;
+    else 
+    {
+      NumArchiveErrors++;
+      (*OutStream) << "Sub items Errors: " << NumFileErrorsInCurrentArchive << endl;
+    }
+  }
+  if (result == S_OK)
+    return result;
+  NumArchiveErrors++;
+  if (result == E_ABORT || result == ERROR_DISK_FULL)
+    return result;
+  (*OutStream) << endl << kError;
+  if (result == E_OUTOFMEMORY)
+    (*OutStream) << kMemoryExceptionMessage;
+  else
+  {
+    UString message;
+    NError::MyFormatMessage(result, message);
+    (*OutStream) << message;
+  }
+  (*OutStream) << endl;
+  return S_OK;
+}
+
+HRESULT CExtractCallbackConsole::SetPassword(const UString &password)
+{
+  PasswordIsDefined = true;
+  Password = password;
+  return S_OK;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/misc/libphysfs/lzma/CPP/7zip/UI/Console/ExtractCallbackConsole.h	Mon Apr 10 12:06:43 2017 -0400
@@ -0,0 +1,65 @@
+// ExtractCallbackConsole.h
+
+#ifndef __EXTRACTCALLBACKCONSOLE_H
+#define __EXTRACTCALLBACKCONSOLE_H
+
+#include "Common/MyString.h"
+#include "Common/StdOutStream.h"
+#include "../../Common/FileStreams.h"
+#include "../../IPassword.h"
+#include "../../Archive/IArchive.h"
+#include "../Common/ArchiveExtractCallback.h"
+
+class CExtractCallbackConsole: 
+  public IExtractCallbackUI,
+  public ICryptoGetTextPassword,
+  public CMyUnknownImp
+{
+public:
+  MY_UNKNOWN_IMP2(IFolderArchiveExtractCallback, ICryptoGetTextPassword)
+
+  STDMETHOD(SetTotal)(UInt64 total);
+  STDMETHOD(SetCompleted)(const UInt64 *completeValue);
+
+  // IFolderArchiveExtractCallback
+  STDMETHOD(AskOverwrite)(
+      const wchar_t *existName, const FILETIME *existTime, const UInt64 *existSize,
+      const wchar_t *newName, const FILETIME *newTime, const UInt64 *newSize,
+      Int32 *answer);
+  STDMETHOD (PrepareOperation)(const wchar_t *name, bool isFolder, Int32 askExtractMode, const UInt64 *position);
+
+  STDMETHOD(MessageError)(const wchar_t *message);
+  STDMETHOD(SetOperationResult)(Int32 operationResult, bool encrypted);
+
+  // ICryptoGetTextPassword
+  STDMETHOD(CryptoGetTextPassword)(BSTR *password);
+
+  HRESULT BeforeOpen(const wchar_t *name);
+  HRESULT OpenResult(const wchar_t *name, HRESULT result, bool encrypted);
+  HRESULT ThereAreNoFiles();
+  HRESULT ExtractResult(HRESULT result);
+
+  HRESULT SetPassword(const UString &password);
+
+public:
+  bool PasswordIsDefined;
+  UString Password;
+  
+  UInt64 NumArchives;
+  UInt64 NumArchiveErrors;
+  UInt64 NumFileErrors;
+  UInt64 NumFileErrorsInCurrentArchive;
+
+  CStdOutStream *OutStream;
+
+  void Init()
+  {
+    NumArchives = 0;
+    NumArchiveErrors = 0;
+    NumFileErrors = 0;
+    NumFileErrorsInCurrentArchive = 0;
+  }
+
+};
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/misc/libphysfs/lzma/CPP/7zip/UI/Console/List.cpp	Mon Apr 10 12:06:43 2017 -0400
@@ -0,0 +1,579 @@
+// List.cpp
+
+#include "StdAfx.h"
+
+#include "List.h"
+#include "ConsoleClose.h"
+
+#include "Common/StringConvert.h"
+#include "Common/StdOutStream.h"
+#include "Common/IntToString.h"
+#include "Common/MyCom.h"
+
+#include "Windows/PropVariant.h"
+#include "Windows/Defs.h"
+#include "Windows/PropVariantConversions.h"
+#include "Windows/FileDir.h"
+
+#include "../../Archive/IArchive.h"
+
+#include "../Common/PropIDUtils.h"
+#include "../Common/OpenArchive.h"
+
+#include "OpenCallbackConsole.h"
+
+using namespace NWindows;
+
+struct CPropIdToName
+{
+  PROPID PropID;
+  const wchar_t *Name;
+};
+
+static CPropIdToName kPropIdToName[] =  
+{
+  { kpidPath, L"Path" },
+  { kpidName, L"Name" },
+  { kpidIsFolder, L"Folder" }, 
+  { kpidSize, L"Size" },
+  { kpidPackedSize, L"Packed Size" },
+  { kpidAttributes, L"Attributes" },
+  { kpidCreationTime, L"Created" },
+  { kpidLastAccessTime, L"Accessed" },
+  { kpidLastWriteTime, L"Modified" },
+  { kpidSolid, L"Solid" },
+  { kpidCommented, L"Commented" },
+  { kpidEncrypted, L"Encrypted" },
+  { kpidSplitBefore, L"Split Before" },
+  { kpidSplitAfter, L"Split After" },
+  { kpidDictionarySize, L"Dictionary Size" },
+  { kpidCRC, L"CRC" },
+  { kpidType, L"Type" },
+  { kpidIsAnti, L"Anti" },
+  { kpidMethod, L"Method" },
+  { kpidHostOS, L"Host OS" },
+  { kpidFileSystem, L"File System" },
+  { kpidUser, L"User" },
+  { kpidGroup, L"Group" },
+  { kpidBlock, L"Block" },
+  { kpidComment, L"Comment" },
+  { kpidPosition, L"Position" },
+  { kpidPrefix, L"Prefix" },
+  { kpidNumSubFolders, L"Folders" },
+  { kpidNumSubFiles, L"Files" },
+  { kpidUnpackVer, L"Version" },
+  { kpidVolume, L"Volume" },
+  { kpidIsVolume, L"Multivolume" },
+  { kpidOffset, L"Offset" },
+  { kpidLinks, L"Links" },
+  { kpidNumBlocks, L"Blocks" },
+  { kpidNumVolumes, L"Volumes" }
+};
+
+static const char kEmptyAttributeChar = '.';
+static const char kDirectoryAttributeChar = 'D';
+static const char kReadonlyAttributeChar  = 'R';
+static const char kHiddenAttributeChar    = 'H';
+static const char kSystemAttributeChar    = 'S';
+static const char kArchiveAttributeChar   = 'A';
+
+static const char *kListing = "Listing archive: ";
+static const wchar_t *kFilesMessage = L"files";
+static const wchar_t *kDirsMessage = L"folders";
+
+static void GetAttributesString(DWORD wa, bool directory, char *s)
+{
+  s[0] = ((wa & FILE_ATTRIBUTE_DIRECTORY) != 0 || directory) ? 
+      kDirectoryAttributeChar: kEmptyAttributeChar;
+  s[1] = ((wa & FILE_ATTRIBUTE_READONLY) != 0)? 
+      kReadonlyAttributeChar: kEmptyAttributeChar;
+  s[2] = ((wa & FILE_ATTRIBUTE_HIDDEN) != 0) ? 
+      kHiddenAttributeChar: kEmptyAttributeChar;
+  s[3] = ((wa & FILE_ATTRIBUTE_SYSTEM) != 0) ? 
+      kSystemAttributeChar: kEmptyAttributeChar;
+  s[4] = ((wa & FILE_ATTRIBUTE_ARCHIVE) != 0) ? 
+      kArchiveAttributeChar: kEmptyAttributeChar;
+  s[5] = '\0';
+}
+
+enum EAdjustment
+{
+  kLeft,
+  kCenter,
+  kRight
+};
+
+struct CFieldInfo
+{
+  PROPID PropID;
+  UString Name;
+  EAdjustment TitleAdjustment;
+  EAdjustment TextAdjustment;
+  int PrefixSpacesWidth;
+  int Width;
+};
+
+struct CFieldInfoInit
+{
+  PROPID PropID;
+  const wchar_t *Name;
+  EAdjustment TitleAdjustment;
+  EAdjustment TextAdjustment;
+  int PrefixSpacesWidth;
+  int Width;
+};
+
+CFieldInfoInit kStandardFieldTable[] = 
+{
+  { kpidLastWriteTime, L"   Date      Time", kLeft, kLeft, 0, 19 },
+  { kpidAttributes, L"Attr", kRight, kCenter, 1, 5 },
+  { kpidSize, L"Size", kRight, kRight, 1, 12 },
+  { kpidPackedSize, L"Compressed", kRight, kRight, 1, 12 },
+  { kpidPath, L"Name", kLeft, kLeft, 2, 24 }
+};
+
+void PrintSpaces(int numSpaces)
+{
+  for (int i = 0; i < numSpaces; i++)
+    g_StdOut << ' ';
+}
+
+void PrintString(EAdjustment adjustment, int width, const UString &textString)
+{
+  const int numSpaces = width - textString.Length();
+  int numLeftSpaces = 0;
+  switch (adjustment)
+  {
+    case kLeft:
+      numLeftSpaces = 0;
+      break;
+    case kCenter:
+      numLeftSpaces = numSpaces / 2;
+      break;
+    case kRight:
+      numLeftSpaces = numSpaces;
+      break;
+  }
+  PrintSpaces(numLeftSpaces);
+  g_StdOut << textString;
+  PrintSpaces(numSpaces - numLeftSpaces);
+}
+
+class CFieldPrinter
+{
+  CObjectVector<CFieldInfo> _fields;
+public:
+  void Clear() { _fields.Clear(); }
+  void Init(const CFieldInfoInit *standardFieldTable, int numItems);
+  HRESULT Init(IInArchive *archive);
+  void PrintTitle();
+  void PrintTitleLines();
+  HRESULT PrintItemInfo(IInArchive *archive, 
+      const UString &defaultItemName,
+      const NWindows::NFile::NFind::CFileInfoW &archiveFileInfo,
+      UInt32 index,
+      bool techMode);
+  HRESULT PrintSummaryInfo(UInt64 numFiles, UInt64 numDirs, 
+      const UInt64 *size, const UInt64 *compressedSize);
+};
+
+void CFieldPrinter::Init(const CFieldInfoInit *standardFieldTable, int numItems)
+{
+  Clear();
+  for (int i = 0; i < numItems; i++)
+  {
+    CFieldInfo fieldInfo;
+    const CFieldInfoInit &fieldInfoInit = standardFieldTable[i];
+    fieldInfo.PropID = fieldInfoInit.PropID;
+    fieldInfo.Name = fieldInfoInit.Name;
+    fieldInfo.TitleAdjustment = fieldInfoInit.TitleAdjustment;
+    fieldInfo.TextAdjustment = fieldInfoInit.TextAdjustment;
+    fieldInfo.PrefixSpacesWidth = fieldInfoInit.PrefixSpacesWidth;
+    fieldInfo.Width = fieldInfoInit.Width;
+    _fields.Add(fieldInfo);
+  }
+}
+
+static UString GetPropName(PROPID propID, BSTR name)
+{
+  for (int i = 0; i < sizeof(kPropIdToName) / sizeof(kPropIdToName[0]); i++)
+  {
+    const CPropIdToName &propIdToName = kPropIdToName[i];
+    if (propIdToName.PropID == propID)
+      return propIdToName.Name;
+  }
+  if (name)
+    return name;
+  return L"?";
+}
+
+HRESULT CFieldPrinter::Init(IInArchive *archive)
+{
+  Clear();
+  UInt32 numProps;
+  RINOK(archive->GetNumberOfProperties(&numProps));
+  for (UInt32 i = 0; i < numProps; i++)
+  {
+    CMyComBSTR name;
+    PROPID propID;
+    VARTYPE vt;
+    RINOK(archive->GetPropertyInfo(i, &name, &propID, &vt));
+    CFieldInfo fieldInfo;
+    fieldInfo.PropID = propID;
+    fieldInfo.Name = GetPropName(propID, name);
+    _fields.Add(fieldInfo);
+  }
+  return S_OK;
+}
+
+void CFieldPrinter::PrintTitle()
+{
+  for (int i = 0; i < _fields.Size(); i++)
+  {
+    const CFieldInfo &fieldInfo = _fields[i];
+    PrintSpaces(fieldInfo.PrefixSpacesWidth);
+    PrintString(fieldInfo.TitleAdjustment, 
+      ((fieldInfo.PropID == kpidPath) ? 0: fieldInfo.Width), fieldInfo.Name);
+  }
+}
+
+void CFieldPrinter::PrintTitleLines()
+{
+  for (int i = 0; i < _fields.Size(); i++)
+  {
+    const CFieldInfo &fieldInfo = _fields[i];
+    PrintSpaces(fieldInfo.PrefixSpacesWidth);
+    for (int i = 0; i < fieldInfo.Width; i++)
+      g_StdOut << '-';
+  }
+}
+
+
+BOOL IsFileTimeZero(CONST FILETIME *lpFileTime)
+{
+  return (lpFileTime->dwLowDateTime == 0) && (lpFileTime->dwHighDateTime == 0);
+}
+
+static const char *kEmptyTimeString = "                   ";
+void PrintTime(const NCOM::CPropVariant &propVariant)
+{
+  if (propVariant.vt != VT_FILETIME)
+    throw "incorrect item";
+  if (IsFileTimeZero(&propVariant.filetime))
+    g_StdOut << kEmptyTimeString;
+  else
+  {
+    FILETIME localFileTime;
+    if (!FileTimeToLocalFileTime(&propVariant.filetime, &localFileTime))
+      throw "FileTimeToLocalFileTime error";
+    char s[32];
+    if (ConvertFileTimeToString(localFileTime, s, true, true))
+      g_StdOut << s;
+    else
+      g_StdOut << kEmptyTimeString;
+  }
+}
+
+HRESULT CFieldPrinter::PrintItemInfo(IInArchive *archive, 
+    const UString &defaultItemName, 
+    const NWindows::NFile::NFind::CFileInfoW &archiveFileInfo,
+    UInt32 index,
+    bool techMode)
+{
+  /*
+  if (techMode)
+  {
+    g_StdOut << "Index = ";
+    g_StdOut << (UInt64)index;
+    g_StdOut << endl;
+  }
+  */
+  for (int i = 0; i < _fields.Size(); i++)
+  {
+    const CFieldInfo &fieldInfo = _fields[i];
+    if (!techMode)
+      PrintSpaces(fieldInfo.PrefixSpacesWidth);
+
+    NCOM::CPropVariant propVariant;
+    RINOK(archive->GetProperty(index, fieldInfo.PropID, &propVariant));
+    if (techMode)
+    {
+      g_StdOut << fieldInfo.Name << " = ";
+    }
+    int width = (fieldInfo.PropID == kpidPath) ? 0: fieldInfo.Width;
+    if (propVariant.vt == VT_EMPTY)
+    {
+      switch(fieldInfo.PropID)
+      {
+        case kpidPath:
+          propVariant = defaultItemName;
+          break;
+        case kpidLastWriteTime:
+          propVariant = archiveFileInfo.LastWriteTime;
+          break;
+        default:
+          if (techMode)
+            g_StdOut << endl;
+          else
+            PrintSpaces(width);
+          continue;
+      }
+    }
+    if (fieldInfo.PropID == kpidLastWriteTime)
+    {
+      PrintTime(propVariant);
+    }
+    else if (fieldInfo.PropID == kpidAttributes)
+    {
+      if (propVariant.vt != VT_UI4)
+        throw "incorrect item";
+      UInt32 attributes = propVariant.ulVal;
+      bool isFolder;
+      RINOK(IsArchiveItemFolder(archive, index, isFolder));
+      char s[8];
+      GetAttributesString(attributes, isFolder, s);
+      g_StdOut << s;
+    }
+    else if (propVariant.vt == VT_BSTR)
+    {
+      if (techMode)
+        g_StdOut << propVariant.bstrVal;
+      else
+        PrintString(fieldInfo.TextAdjustment, width, propVariant.bstrVal);
+    }
+    else
+    {
+      UString s = ConvertPropertyToString(propVariant, fieldInfo.PropID);
+      s.Replace(wchar_t(0xA), L' '); 
+      s.Replace(wchar_t(0xD), L' '); 
+
+      if (techMode)
+        g_StdOut << s;
+      else
+        PrintString(fieldInfo.TextAdjustment, width, s);
+    }
+    if (techMode)
+      g_StdOut << endl;
+  }
+  return S_OK;
+}
+
+void PrintNumberString(EAdjustment adjustment, int width, const UInt64 *value)
+{
+  wchar_t textString[32] = { 0 };
+  if (value != NULL)
+    ConvertUInt64ToString(*value, textString);
+  PrintString(adjustment, width, textString);
+}
+
+
+HRESULT CFieldPrinter::PrintSummaryInfo(UInt64 numFiles, UInt64 numDirs, 
+    const UInt64 *size, const UInt64 *compressedSize)
+{
+  for (int i = 0; i < _fields.Size(); i++)
+  {
+    const CFieldInfo &fieldInfo = _fields[i];
+    PrintSpaces(fieldInfo.PrefixSpacesWidth);
+    NCOM::CPropVariant propVariant;
+    if (fieldInfo.PropID == kpidSize)
+      PrintNumberString(fieldInfo.TextAdjustment, fieldInfo.Width, size);
+    else if (fieldInfo.PropID == kpidPackedSize)
+      PrintNumberString(fieldInfo.TextAdjustment, fieldInfo.Width, compressedSize);
+    else if (fieldInfo.PropID == kpidPath)
+    {
+      wchar_t textString[32];
+      ConvertUInt64ToString(numFiles, textString);
+      UString temp = textString;
+      temp += L" ";
+      temp += kFilesMessage;
+      temp += L", ";
+      ConvertUInt64ToString(numDirs, textString);
+      temp += textString;
+      temp += L" ";
+      temp += kDirsMessage;
+      PrintString(fieldInfo.TextAdjustment, 0, temp);
+    }
+    else 
+      PrintString(fieldInfo.TextAdjustment, fieldInfo.Width, L"");
+  }
+  return S_OK;
+}
+
+bool GetUInt64Value(IInArchive *archive, UInt32 index, PROPID propID, UInt64 &value)
+{
+  NCOM::CPropVariant propVariant;
+  if (archive->GetProperty(index, propID, &propVariant) != S_OK)
+    throw "GetPropertyValue error";
+  if (propVariant.vt == VT_EMPTY)
+    return false;
+  value = ConvertPropVariantToUInt64(propVariant);
+  return true;
+}
+
+HRESULT ListArchives(
+    CCodecs *codecs,
+    UStringVector &archivePaths, UStringVector &archivePathsFull,
+    const NWildcard::CCensorNode &wildcardCensor,
+    bool enableHeaders, bool techMode, bool &passwordEnabled, UString &password, UInt64 &numErrors)
+{
+  numErrors = 0;
+  CFieldPrinter fieldPrinter;
+  if (!techMode)
+    fieldPrinter.Init(kStandardFieldTable, sizeof(kStandardFieldTable) / sizeof(kStandardFieldTable[0]));
+
+  UInt64 numFiles2 = 0, numDirs2 = 0, totalPackSize2 = 0, totalUnPackSize2 = 0;
+  UInt64 *totalPackSizePointer2 = 0, *totalUnPackSizePointer2 = 0;
+  for (int i = 0; i < archivePaths.Size(); i++)
+  {
+    const UString &archiveName = archivePaths[i];
+    NFile::NFind::CFileInfoW archiveFileInfo;
+    if (!NFile::NFind::FindFile(archiveName, archiveFileInfo) || archiveFileInfo.IsDirectory())
+    {
+      g_StdOut << endl << "Error: " << archiveName << " is not archive" << endl;
+      numErrors++;
+      continue;
+    }
+    if (archiveFileInfo.IsDirectory())
+    {
+      g_StdOut << endl << "Error: " << archiveName << " is not file" << endl;
+      numErrors++;
+      continue;
+    }
+
+    CArchiveLink archiveLink;
+
+    COpenCallbackConsole openCallback;
+    openCallback.OutStream = &g_StdOut;
+    openCallback.PasswordIsDefined = passwordEnabled;
+    openCallback.Password = password;
+
+    HRESULT result = MyOpenArchive(codecs, archiveName, archiveLink, &openCallback);
+    if (result != S_OK)
+    {
+      g_StdOut << endl << "Error: " << archiveName << " is not supported archive" << endl;
+      numErrors++;
+      continue;
+    }
+
+    for (int v = 0; v < archiveLink.VolumePaths.Size(); v++)
+    {
+      int index = archivePathsFull.FindInSorted(archiveLink.VolumePaths[v]);
+      if (index >= 0 && index > i)
+      {
+        archivePaths.Delete(index);
+        archivePathsFull.Delete(index);
+      }
+    }
+
+    IInArchive *archive = archiveLink.GetArchive();
+    const UString defaultItemName = archiveLink.GetDefaultItemName();
+
+    if (enableHeaders)
+    {
+      g_StdOut << endl << kListing << archiveName << endl << endl;
+
+      UInt32 numProps;
+      if (archive->GetNumberOfArchiveProperties(&numProps) == S_OK)
+      {
+        for (UInt32 i = 0; i < numProps; i++)
+        {
+          CMyComBSTR name;
+          PROPID propID;
+          VARTYPE vt;
+          if (archive->GetArchivePropertyInfo(i, &name, &propID, &vt) != S_OK)
+            continue;
+          NCOM::CPropVariant prop;
+          if (archive->GetArchiveProperty(propID, &prop) != S_OK)
+            continue;
+          UString s = ConvertPropertyToString(prop, propID);
+          if (!s.IsEmpty())
+            g_StdOut << GetPropName(propID, name) << " = " << s << endl;
+        }
+      }
+      if (techMode)
+        g_StdOut << "----------\n";
+      if (numProps > 0)
+        g_StdOut << endl;
+    }
+
+    if (enableHeaders && !techMode)
+    {
+      fieldPrinter.PrintTitle();
+      g_StdOut << endl;
+      fieldPrinter.PrintTitleLines();
+      g_StdOut << endl;
+    }
+
+    if (techMode)
+    {
+      RINOK(fieldPrinter.Init(archive));
+    }
+    UInt64 numFiles = 0, numDirs = 0, totalPackSize = 0, totalUnPackSize = 0;
+    UInt64 *totalPackSizePointer = 0, *totalUnPackSizePointer = 0;
+    UInt32 numItems;
+    RINOK(archive->GetNumberOfItems(&numItems));
+    for(UInt32 i = 0; i < numItems; i++)
+    {
+      if (NConsoleClose::TestBreakSignal())
+        return E_ABORT;
+
+      UString filePath;
+      RINOK(GetArchiveItemPath(archive, i, defaultItemName, filePath));
+
+      bool isFolder;
+      RINOK(IsArchiveItemFolder(archive, i, isFolder));
+      if (!wildcardCensor.CheckPath(filePath, !isFolder))
+        continue;
+      
+      fieldPrinter.PrintItemInfo(archive, defaultItemName, archiveFileInfo, i, techMode);
+      
+      UInt64 packSize, unpackSize;
+      if (!GetUInt64Value(archive, i, kpidSize, unpackSize))
+        unpackSize = 0;
+      else
+        totalUnPackSizePointer = &totalUnPackSize;
+      if (!GetUInt64Value(archive, i, kpidPackedSize, packSize))
+        packSize = 0;
+      else
+        totalPackSizePointer = &totalPackSize;
+      
+      g_StdOut << endl;
+
+      if (isFolder)
+        numDirs++;
+      else
+        numFiles++;
+      totalPackSize += packSize;
+      totalUnPackSize += unpackSize;
+    }
+    if (enableHeaders && !techMode)
+    {
+      fieldPrinter.PrintTitleLines();
+      g_StdOut << endl;
+      fieldPrinter.PrintSummaryInfo(numFiles, numDirs, totalUnPackSizePointer, totalPackSizePointer);
+      g_StdOut << endl;
+    }
+    if (totalPackSizePointer != 0)
+    {
+      totalPackSizePointer2 = &totalPackSize2;
+      totalPackSize2 += totalPackSize;
+    }
+    if (totalUnPackSizePointer != 0)
+    {
+      totalUnPackSizePointer2 = &totalUnPackSize2;
+      totalUnPackSize2 += totalUnPackSize;
+    }
+    numFiles2 += numFiles;
+    numDirs2 += numDirs;
+  }
+  if (enableHeaders && !techMode && archivePaths.Size() > 1)
+  {
+    g_StdOut << endl;
+    fieldPrinter.PrintTitleLines();
+    g_StdOut << endl;
+    fieldPrinter.PrintSummaryInfo(numFiles2, numDirs2, totalUnPackSizePointer2, totalPackSizePointer2);
+    g_StdOut << endl;
+    g_StdOut << "Archives: " << archivePaths.Size() << endl;
+  }
+  return S_OK;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/misc/libphysfs/lzma/CPP/7zip/UI/Console/List.h	Mon Apr 10 12:06:43 2017 -0400
@@ -0,0 +1,16 @@
+// List.h
+
+#ifndef __LIST_H
+#define __LIST_H
+
+#include "Common/Wildcard.h"
+#include "../Common/LoadCodecs.h"
+
+HRESULT ListArchives(
+    CCodecs *codecs,
+    UStringVector &archivePaths, UStringVector &archivePathsFull,
+    const NWildcard::CCensorNode &wildcardCensor,
+    bool enableHeaders, bool techMode, bool &passwordEnabled, UString &password, UInt64 &errors);
+
+#endif
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/misc/libphysfs/lzma/CPP/7zip/UI/Console/Main.cpp	Mon Apr 10 12:06:43 2017 -0400
@@ -0,0 +1,563 @@
+// Main.cpp
+
+#include "StdAfx.h"
+
+#include "Common/MyInitGuid.h"
+
+#include "Common/CommandLineParser.h"
+#include "Common/MyException.h"
+#include "Common/IntToString.h"
+#include "Common/StdOutStream.h"
+#include "Common/StringConvert.h"
+#include "Common/StringToInt.h"
+
+#include "Windows/FileDir.h"
+#include "Windows/FileName.h"
+#include "Windows/Defs.h"
+#include "Windows/Error.h"
+#ifdef _WIN32
+#include "Windows/MemoryLock.h"
+#endif
+
+#include "../../IPassword.h"
+#include "../../ICoder.h"
+#include "../Common/UpdateAction.h"
+#include "../Common/Update.h"
+#include "../Common/Extract.h"
+#include "../Common/ArchiveCommandLine.h"
+#include "../Common/ExitCode.h"
+#ifdef EXTERNAL_CODECS
+#include "../Common/LoadCodecs.h"
+#endif
+
+#include "../../Compress/LZMA_Alone/LzmaBenchCon.h"
+
+#include "List.h"
+#include "OpenCallbackConsole.h"
+#include "ExtractCallbackConsole.h"
+#include "UpdateCallbackConsole.h"
+
+#include "../../MyVersion.h"
+
+#if defined( _WIN32) && defined( _7ZIP_LARGE_PAGES)
+extern "C" 
+{ 
+#include "../../../../C/Alloc.h"
+}
+#endif
+
+using namespace NWindows;
+using namespace NFile;
+using namespace NCommandLineParser;
+
+HINSTANCE g_hInstance = 0;
+extern CStdOutStream *g_StdStream;
+
+static const char *kCopyrightString = "\n7-Zip"
+#ifndef EXTERNAL_CODECS
+" (A)"
+#endif
+
+#ifdef _WIN64
+" [64]"
+#endif
+
+" " MY_VERSION_COPYRIGHT_DATE "\n";
+
+static const char *kHelpString = 
+    "\nUsage: 7z"
+#ifdef _NO_CRYPTO
+    "r"
+#else
+#ifndef EXTERNAL_CODECS
+    "a"
+#endif
+#endif
+    " <command> [<switches>...] <archive_name> [<file_names>...]\n"
+    "       [<@listfiles...>]\n"
+    "\n"
+    "<Commands>\n"
+    "  a: Add files to archive\n"
+    "  b: Benchmark\n"
+    "  d: Delete files from archive\n"
+    "  e: Extract files from archive (without using directory names)\n"
+    "  l: List contents of archive\n"
+//    "  l[a|t][f]: List contents of archive\n"
+//    "    a - with Additional fields\n"
+//    "    t - with all fields\n"
+//    "    f - with Full pathnames\n"
+    "  t: Test integrity of archive\n"
+    "  u: Update files to archive\n"
+    "  x: eXtract files with full paths\n"
+    "<Switches>\n"
+    "  -ai[r[-|0]]{@listfile|!wildcard}: Include archives\n"
+    "  -ax[r[-|0]]{@listfile|!wildcard}: eXclude archives\n"
+    "  -bd: Disable percentage indicator\n"
+    "  -i[r[-|0]]{@listfile|!wildcard}: Include filenames\n"
+    "  -m{Parameters}: set compression Method\n"
+    "  -o{Directory}: set Output directory\n"
+    "  -p{Password}: set Password\n"
+    "  -r[-|0]: Recurse subdirectories\n"
+    "  -scs{UTF-8 | WIN | DOS}: set charset for list files\n"
+    "  -sfx[{name}]: Create SFX archive\n"
+    "  -si[{name}]: read data from stdin\n"
+    "  -slt: show technical information for l (List) command\n"
+    "  -so: write data to stdout\n"
+    "  -ssc[-]: set sensitive case mode\n"
+    "  -ssw: compress shared files\n"
+    "  -t{Type}: Set type of archive\n"
+    "  -v{Size}[b|k|m|g]: Create volumes\n"
+    "  -u[-][p#][q#][r#][x#][y#][z#][!newArchiveName]: Update options\n"
+    "  -w[{path}]: assign Work directory. Empty path means a temporary directory\n"
+    "  -x[r[-|0]]]{@listfile|!wildcard}: eXclude filenames\n"
+    "  -y: assume Yes on all queries\n";
+
+// ---------------------------
+// exception messages
+
+static const char *kEverythingIsOk = "Everything is Ok";
+static const char *kUserErrorMessage  = "Incorrect command line"; // NExitCode::kUserError
+
+static const wchar_t *kDefaultSfxModule = L"7zCon.sfx";
+
+static void ShowMessageAndThrowException(CStdOutStream &s, LPCSTR message, NExitCode::EEnum code)
+{
+  s << message << endl;
+  throw code;
+}
+
+static void PrintHelpAndExit(CStdOutStream &s) // yyy
+{
+  s << kHelpString;
+  ShowMessageAndThrowException(s, kUserErrorMessage, NExitCode::kUserError);
+}
+
+#ifndef _WIN32
+static void GetArguments(int numArguments, const char *arguments[], UStringVector &parts)
+{
+  parts.Clear();
+  for(int i = 0; i < numArguments; i++)
+  {
+    UString s = MultiByteToUnicodeString(arguments[i]);
+    parts.Add(s);
+  }
+}
+#endif
+
+static void ShowCopyrightAndHelp(CStdOutStream &s, bool needHelp)
+{
+  s << kCopyrightString;
+  // s << "# CPUs: " << (UInt64)NWindows::NSystem::GetNumberOfProcessors() << "\n";
+  if (needHelp) 
+    s << kHelpString;
+}
+
+#ifdef EXTERNAL_CODECS
+static void PrintString(CStdOutStream &stdStream, const AString &s, int size)
+{
+  int len = s.Length();
+  stdStream << s;
+  for (int i = len; i < size; i++)
+    stdStream << ' ';
+}
+#endif
+
+static void PrintString(CStdOutStream &stdStream, const UString &s, int size)
+{
+  int len = s.Length();
+  stdStream << s;
+  for (int i = len; i < size; i++)
+    stdStream << ' ';
+}
+
+static inline char GetHex(Byte value)
+{
+  return (char)((value < 10) ? ('0' + value) : ('A' + (value - 10)));
+}
+
+int Main2(
+  #ifndef _WIN32  
+  int numArguments, const char *arguments[]
+  #endif
+)
+{
+  #ifdef _WIN32  
+  SetFileApisToOEM();
+  #endif
+  
+  UStringVector commandStrings;
+  #ifdef _WIN32  
+  NCommandLineParser::SplitCommandLine(GetCommandLineW(), commandStrings);
+  #else
+  GetArguments(numArguments, arguments, commandStrings);
+  #endif
+
+  if(commandStrings.Size() == 1)
+  {
+    ShowCopyrightAndHelp(g_StdOut, true);
+    return 0;
+  }
+  commandStrings.Delete(0);
+
+  CArchiveCommandLineOptions options;
+
+  CArchiveCommandLineParser parser;
+
+  parser.Parse1(commandStrings, options);
+
+  if(options.HelpMode)
+  {
+    ShowCopyrightAndHelp(g_StdOut, true);
+    return 0;
+  }
+
+  #if defined(_WIN32) && defined(_7ZIP_LARGE_PAGES)
+  if (options.LargePages)
+  {
+    SetLargePageSize();
+    NSecurity::EnableLockMemoryPrivilege();
+  }
+  #endif
+
+  CStdOutStream &stdStream = options.StdOutMode ? g_StdErr : g_StdOut;
+  g_StdStream = &stdStream;
+
+  if (options.EnableHeaders)
+    ShowCopyrightAndHelp(stdStream, false);
+
+  parser.Parse2(options);
+
+  CCodecs *codecs = new CCodecs;
+  CMyComPtr<
+    #ifdef EXTERNAL_CODECS
+    ICompressCodecsInfo
+    #else
+    IUnknown
+    #endif
+    > compressCodecsInfo = codecs;
+  HRESULT result = codecs->Load();
+  if (result != S_OK)
+    throw CSystemException(result);
+
+  bool isExtractGroupCommand = options.Command.IsFromExtractGroup();
+  if (options.Command.CommandType == NCommandType::kInfo)
+  {
+    stdStream << endl << "Formats:" << endl;
+    int i;
+    for (i = 0; i < codecs->Formats.Size(); i++)
+    {
+      const CArcInfoEx &arc = codecs->Formats[i];
+      #ifdef EXTERNAL_CODECS
+      if (arc.LibIndex >= 0)
+      {
+        char s[32];
+        ConvertUInt64ToString(arc.LibIndex, s);
+        PrintString(stdStream, s, 2);
+      }
+      else
+      #endif
+        stdStream << "  ";
+      stdStream << ' ';
+      stdStream << (char)(arc.UpdateEnabled ? 'C' : ' ');
+      stdStream << (char)(arc.KeepName ? 'K' : ' ');
+      stdStream << "  ";
+      PrintString(stdStream, arc.Name, 6);
+      stdStream << "  ";
+      UString s;
+      for (int t = 0; t < arc.Exts.Size(); t++)
+      {
+        const CArcExtInfo &ext = arc.Exts[t];
+        s += ext.Ext;
+        if (!ext.AddExt.IsEmpty())
+        {
+          s += L" (";
+          s += ext.AddExt;
+          s += L')';
+        }
+        s += L' ';
+      }
+      PrintString(stdStream, s, 14);
+      stdStream << "  ";
+      const CByteBuffer &sig = arc.StartSignature;
+      for (size_t j = 0; j < sig.GetCapacity(); j++)
+      {
+        Byte b = sig[j];
+        if (b > 0x20 && b < 0x80)
+        {
+          stdStream << (char)b;
+        }
+        else
+        {
+          stdStream << GetHex((Byte)((b >> 4) & 0xF));
+          stdStream << GetHex((Byte)(b & 0xF));
+        }
+        stdStream << ' ';
+      }
+      stdStream << endl;
+    }
+    stdStream << endl << "Codecs:" << endl;
+
+    #ifdef EXTERNAL_CODECS
+    UINT32 numMethods;
+    if (codecs->GetNumberOfMethods(&numMethods) == S_OK)
+    for (UInt32 j = 0; j < numMethods; j++)
+    {
+      int libIndex = codecs->GetCodecLibIndex(j);
+      if (libIndex >= 0)
+      {
+        char s[32];
+        ConvertUInt64ToString(libIndex, s);
+        PrintString(stdStream, s, 2);
+      }
+      else
+        stdStream << "  ";
+      stdStream << ' ';
+      stdStream << (char)(codecs->GetCodecEncoderIsAssigned(j) ? 'C' : ' ');
+      UInt64 id;
+      stdStream << "  ";
+      HRESULT res = codecs->GetCodecId(j, id);
+      if (res != S_OK)
+        id = (UInt64)(Int64)-1;
+      char s[32];
+      ConvertUInt64ToString(id, s, 16);
+      PrintString(stdStream, s, 8);
+      stdStream << "  ";
+      PrintString(stdStream, codecs->GetCodecName(j), 11);
+      stdStream << endl;
+      /*
+      if (res != S_OK)
+        throw "incorrect Codec ID";
+      */
+    }
+    #endif
+    return S_OK;
+  }
+  else if (options.Command.CommandType == NCommandType::kBenchmark)
+  {
+    if (options.Method.CompareNoCase(L"CRC") == 0)
+    {
+      HRESULT res = CrcBenchCon((FILE *)stdStream, options.NumIterations, options.NumThreads, options.DictionarySize);
+      if (res != S_OK)
+      {
+        if (res == S_FALSE)
+        {
+          stdStream << "\nCRC Error\n";
+          return NExitCode::kFatalError;
+        }
+        throw CSystemException(res);
+      }
+    }
+    else
+    {
+      HRESULT res = LzmaBenchCon(
+        #ifdef EXTERNAL_LZMA
+        codecs,
+        #endif
+        (FILE *)stdStream, options.NumIterations, options.NumThreads, options.DictionarySize);
+      if (res != S_OK)
+      {
+        if (res == S_FALSE)
+        {
+          stdStream << "\nDecoding Error\n";
+          return NExitCode::kFatalError;
+        }
+        throw CSystemException(res);
+      }
+    }
+  }
+  else if (isExtractGroupCommand || options.Command.CommandType == NCommandType::kList)
+  {
+    if(isExtractGroupCommand)
+    {
+      CExtractCallbackConsole *ecs = new CExtractCallbackConsole;
+      CMyComPtr<IFolderArchiveExtractCallback> extractCallback = ecs;
+
+      ecs->OutStream = &stdStream;
+      ecs->PasswordIsDefined = options.PasswordEnabled;
+      ecs->Password = options.Password;
+      ecs->Init();
+
+      COpenCallbackConsole openCallback;
+      openCallback.OutStream = &stdStream;
+      openCallback.PasswordIsDefined = options.PasswordEnabled;
+      openCallback.Password = options.Password;
+
+      CExtractOptions eo;
+      eo.StdOutMode = options.StdOutMode;
+      eo.PathMode = options.Command.GetPathMode();
+      eo.TestMode = options.Command.IsTestMode();
+      eo.OverwriteMode = options.OverwriteMode;
+      eo.OutputDir = options.OutputDir;
+      eo.YesToAll = options.YesToAll;
+      #ifdef COMPRESS_MT
+      eo.Properties = options.ExtractProperties;
+      #endif
+      UString errorMessage;
+      CDecompressStat stat;
+      HRESULT result = DecompressArchives(
+          codecs,
+          options.ArchivePathsSorted, 
+          options.ArchivePathsFullSorted,
+          options.WildcardCensor.Pairs.Front().Head, 
+          eo, &openCallback, ecs, errorMessage, stat);
+      if (!errorMessage.IsEmpty())
+      {
+        stdStream << endl << "Error: " << errorMessage;
+        if (result == S_OK)
+          result = E_FAIL;
+      }
+
+      stdStream << endl;
+      if (ecs->NumArchives > 1)
+        stdStream << "Archives: " << ecs->NumArchives << endl;
+      if (ecs->NumArchiveErrors != 0 || ecs->NumFileErrors != 0)
+      {
+        if (ecs->NumArchives > 1)
+        {
+          stdStream << endl;
+          if (ecs->NumArchiveErrors != 0)
+            stdStream << "Archive Errors: " << ecs->NumArchiveErrors << endl;
+          if (ecs->NumFileErrors != 0)
+            stdStream << "Sub items Errors: " << ecs->NumFileErrors << endl;
+        }
+        if (result != S_OK)
+          throw CSystemException(result);
+        return NExitCode::kFatalError;
+      }
+      if (result != S_OK)
+        throw CSystemException(result);
+      if (stat.NumFolders != 0)
+        stdStream << "Folders: " << stat.NumFolders << endl;
+      if (stat.NumFiles != 1 || stat.NumFolders != 0)
+          stdStream << "Files: " << stat.NumFiles << endl;
+      stdStream 
+           << "Size:       " << stat.UnpackSize << endl
+           << "Compressed: " << stat.PackSize << endl;
+    }
+    else
+    {
+      UInt64 numErrors = 0;
+      HRESULT result = ListArchives(
+          codecs,
+          options.ArchivePathsSorted, 
+          options.ArchivePathsFullSorted,
+          options.WildcardCensor.Pairs.Front().Head, 
+          options.EnableHeaders, 
+          options.TechMode,
+          options.PasswordEnabled, 
+          options.Password, numErrors);
+      if (numErrors > 0)
+      {
+        g_StdOut << endl << "Errors: " << numErrors;
+        return NExitCode::kFatalError;
+      }
+      if (result != S_OK)
+        throw CSystemException(result);
+    }
+  }
+  else if(options.Command.IsFromUpdateGroup())
+  {
+    UString workingDir;
+
+    CUpdateOptions &uo = options.UpdateOptions;
+    if (uo.SfxMode && uo.SfxModule.IsEmpty())
+      uo.SfxModule = kDefaultSfxModule;
+
+    bool passwordIsDefined = 
+        options.PasswordEnabled && !options.Password.IsEmpty();
+
+    COpenCallbackConsole openCallback;
+    openCallback.OutStream = &stdStream;
+    openCallback.PasswordIsDefined = passwordIsDefined;
+    openCallback.Password = options.Password;
+
+    CUpdateCallbackConsole callback;
+    callback.EnablePercents = options.EnablePercents;
+    callback.PasswordIsDefined = passwordIsDefined;
+    callback.AskPassword = options.PasswordEnabled && options.Password.IsEmpty();
+    callback.Password = options.Password;
+    callback.StdOutMode = uo.StdOutMode;
+    callback.Init(&stdStream);
+
+    CUpdateErrorInfo errorInfo;
+
+    if (!uo.Init(codecs, options.ArchiveName, options.ArcType))
+      throw "Unsupported archive type";
+    HRESULT result = UpdateArchive(codecs, 
+        options.WildcardCensor, uo, 
+        errorInfo, &openCallback, &callback);
+
+    int exitCode = NExitCode::kSuccess;
+    if (callback.CantFindFiles.Size() > 0)
+    {
+      stdStream << endl;
+      stdStream << "WARNINGS for files:" << endl << endl;
+      int numErrors = callback.CantFindFiles.Size();
+      for (int i = 0; i < numErrors; i++)
+      {
+        stdStream << callback.CantFindFiles[i] << " : ";
+        stdStream << NError::MyFormatMessageW(callback.CantFindCodes[i]) << endl;
+      }
+      stdStream << "----------------" << endl;
+      stdStream << "WARNING: Cannot find " << numErrors << " file";
+      if (numErrors > 1)
+        stdStream << "s";
+      stdStream << endl;
+      exitCode = NExitCode::kWarning;
+    }
+
+    if (result != S_OK)
+    {
+      UString message;
+      if (!errorInfo.Message.IsEmpty())
+      {
+        message += errorInfo.Message;
+        message += L"\n";
+      }
+      if (!errorInfo.FileName.IsEmpty())
+      {
+        message += errorInfo.FileName;
+        message += L"\n";
+      }
+      if (!errorInfo.FileName2.IsEmpty())
+      {
+        message += errorInfo.FileName2;
+        message += L"\n";
+      }
+      if (errorInfo.SystemError != 0)
+      {
+        message += NError::MyFormatMessageW(errorInfo.SystemError);
+        message += L"\n";
+      }
+      if (!message.IsEmpty())
+        stdStream << L"\nError:\n" << message;
+      throw CSystemException(result);
+    }
+    int numErrors = callback.FailedFiles.Size();
+    if (numErrors == 0)
+    {
+      if (callback.CantFindFiles.Size() == 0)
+        stdStream << kEverythingIsOk << endl;
+    }
+    else
+    {
+      stdStream << endl;
+      stdStream << "WARNINGS for files:" << endl << endl;
+      for (int i = 0; i < numErrors; i++)
+      {
+        stdStream << callback.FailedFiles[i] << " : ";
+        stdStream << NError::MyFormatMessageW(callback.FailedCodes[i]) << endl;
+      }
+      stdStream << "----------------" << endl;
+      stdStream << "WARNING: Cannot open " << numErrors << " file";
+      if (numErrors > 1)
+        stdStream << "s";
+      stdStream << endl;
+      exitCode = NExitCode::kWarning;
+    }
+    return exitCode;
+  }
+  else 
+    PrintHelpAndExit(stdStream);
+  return 0;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/misc/libphysfs/lzma/CPP/7zip/UI/Console/MainAr.cpp	Mon Apr 10 12:06:43 2017 -0400
@@ -0,0 +1,161 @@
+// MainAr.cpp
+
+#include "StdAfx.h"
+
+// #include <locale.h>
+
+#include "Windows/Error.h"
+
+#include "Common/StdOutStream.h"
+#include "Common/NewHandler.h"
+#include "Common/MyException.h"
+#include "Common/StringConvert.h"
+
+#include "../Common/ExitCode.h"
+#include "../Common/ArchiveCommandLine.h"
+#include "ConsoleClose.h"
+
+using namespace NWindows;
+
+CStdOutStream *g_StdStream = 0;
+
+#ifdef _WIN32
+#ifndef _UNICODE
+bool g_IsNT = false;
+#endif
+#if !defined(_UNICODE) || !defined(_WIN64)
+static inline bool IsItWindowsNT()
+{
+  OSVERSIONINFO versionInfo;
+  versionInfo.dwOSVersionInfoSize = sizeof(versionInfo);
+  if (!::GetVersionEx(&versionInfo)) 
+    return false;
+  return (versionInfo.dwPlatformId == VER_PLATFORM_WIN32_NT);
+}
+#endif
+#endif
+
+extern int Main2(
+  #ifndef _WIN32  
+  int numArguments, const char *arguments[]
+  #endif
+);
+
+static const char *kExceptionErrorMessage = "\n\nError:\n";
+static const char *kUserBreak  = "\nBreak signaled\n";
+
+static const char *kMemoryExceptionMessage = "\n\nERROR: Can't allocate required memory!\n";
+static const char *kUnknownExceptionMessage = "\n\nUnknown Error\n";
+static const char *kInternalExceptionMessage = "\n\nInternal Error #";
+
+int 
+#ifdef _MSC_VER
+__cdecl 
+#endif
+main
+(
+#ifndef _WIN32  
+int numArguments, const char *arguments[]
+#endif
+)
+{
+  g_StdStream = &g_StdOut;
+  #ifdef _WIN32
+  
+  #ifdef _UNICODE
+  #ifndef _WIN64
+  if (!IsItWindowsNT())
+  {
+    (*g_StdStream) << "This program requires Windows NT/2000/XP/2003/Vista";
+    return NExitCode::kFatalError;
+  }
+  #endif
+  #else
+  g_IsNT = IsItWindowsNT();
+  #endif
+  
+  #endif
+
+  // setlocale(LC_COLLATE, ".OCP");
+  NConsoleClose::CCtrlHandlerSetter ctrlHandlerSetter;
+  int res = 0;
+  try
+  {
+    res = Main2(
+#ifndef _WIN32
+      numArguments, arguments
+#endif
+    );
+  }
+  catch(const CNewException &)
+  {
+    (*g_StdStream) << kMemoryExceptionMessage;
+    return (NExitCode::kMemoryError);
+  }
+  catch(const NConsoleClose::CCtrlBreakException &)
+  {
+    (*g_StdStream) << endl << kUserBreak;
+    return (NExitCode::kUserBreak);
+  }
+  catch(const CArchiveCommandLineException &e)
+  {
+    (*g_StdStream) << kExceptionErrorMessage << e << endl;
+    return (NExitCode::kUserError);
+  }
+  catch(const CSystemException &systemError)
+  {
+    if (systemError.ErrorCode == E_OUTOFMEMORY)
+    {
+      (*g_StdStream) << kMemoryExceptionMessage;
+      return (NExitCode::kMemoryError);
+    }
+    if (systemError.ErrorCode == E_ABORT)
+    {
+      (*g_StdStream) << endl << kUserBreak;
+      return (NExitCode::kUserBreak);
+    }
+    UString message;
+    NError::MyFormatMessage(systemError.ErrorCode, message);
+    (*g_StdStream) << endl << endl << "System error:" << endl << 
+        message << endl;
+    return (NExitCode::kFatalError);
+  }
+  catch(NExitCode::EEnum &exitCode)
+  {
+    (*g_StdStream) << kInternalExceptionMessage << exitCode << endl;
+    return (exitCode);
+  }
+  /*
+  catch(const NExitCode::CMultipleErrors &multipleErrors)
+  {
+    (*g_StdStream) << endl << multipleErrors.NumErrors << " errors" << endl;
+    return (NExitCode::kFatalError);
+  }
+  */
+  catch(const UString &s)
+  {
+    (*g_StdStream) << kExceptionErrorMessage << s << endl;
+    return (NExitCode::kFatalError);
+  }
+  catch(const AString &s)
+  {
+    (*g_StdStream) << kExceptionErrorMessage << s << endl;
+    return (NExitCode::kFatalError);
+  }
+  catch(const char *s)
+  {
+    (*g_StdStream) << kExceptionErrorMessage << s << endl;
+    return (NExitCode::kFatalError);
+  }
+  catch(int t)
+  {
+    (*g_StdStream) << kInternalExceptionMessage << t << endl;
+    return (NExitCode::kFatalError);
+  }
+  catch(...)
+  {
+    (*g_StdStream) << kUnknownExceptionMessage;
+    return (NExitCode::kFatalError);
+  }
+  return  res;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/misc/libphysfs/lzma/CPP/7zip/UI/Console/OpenCallbackConsole.cpp	Mon Apr 10 12:06:43 2017 -0400
@@ -0,0 +1,58 @@
+// OpenCallbackConsole.cpp
+
+#include "StdAfx.h"
+
+#include "OpenCallbackConsole.h"
+
+#include "ConsoleClose.h"
+#include "UserInputUtils.h"
+
+HRESULT COpenCallbackConsole::CheckBreak()
+{
+  if (NConsoleClose::TestBreakSignal())
+    return E_ABORT;
+  return S_OK;
+}
+
+HRESULT COpenCallbackConsole::SetTotal(const UInt64 *, const UInt64 *)
+{
+  return CheckBreak();
+}
+
+HRESULT COpenCallbackConsole::SetCompleted(const UInt64 *, const UInt64 *)
+{
+  return CheckBreak();
+}
+ 
+HRESULT COpenCallbackConsole::CryptoGetTextPassword(BSTR *password)
+{
+  PasswordWasAsked = true;
+  RINOK(CheckBreak());
+  if (!PasswordIsDefined)
+  {
+    Password = GetPassword(OutStream); 
+    PasswordIsDefined = true;
+  }
+  CMyComBSTR temp(Password);
+  *password = temp.Detach();
+  return S_OK;
+}
+
+HRESULT COpenCallbackConsole::GetPasswordIfAny(UString &password)
+{
+  if (PasswordIsDefined)
+    password = Password;
+  return S_OK;
+}
+
+bool COpenCallbackConsole::WasPasswordAsked()
+{
+  return PasswordWasAsked;
+}
+
+void COpenCallbackConsole::ClearPasswordWasAskedFlag()
+{
+  PasswordWasAsked = false;
+}
+
+  
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/misc/libphysfs/lzma/CPP/7zip/UI/Console/OpenCallbackConsole.h	Mon Apr 10 12:06:43 2017 -0400
@@ -0,0 +1,27 @@
+// OpenCallbackConsole.h
+
+#ifndef __OPENCALLBACKCONSOLE_H
+#define __OPENCALLBACKCONSOLE_H
+
+#include "Common/StdOutStream.h"
+#include "../Common/ArchiveOpenCallback.h"
+
+class COpenCallbackConsole: public IOpenCallbackUI
+{
+public:
+  HRESULT CheckBreak();
+  HRESULT SetTotal(const UInt64 *files, const UInt64 *bytes);
+  HRESULT SetCompleted(const UInt64 *files, const UInt64 *bytes);
+  HRESULT CryptoGetTextPassword(BSTR *password);
+  HRESULT GetPasswordIfAny(UString &password);
+  bool WasPasswordAsked();
+  void ClearPasswordWasAskedFlag();
+  
+  CStdOutStream *OutStream;
+  bool PasswordIsDefined;
+  UString Password;
+  bool PasswordWasAsked;
+  COpenCallbackConsole(): PasswordIsDefined(false), PasswordWasAsked(false) {}
+};
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/misc/libphysfs/lzma/CPP/7zip/UI/Console/PercentPrinter.cpp	Mon Apr 10 12:06:43 2017 -0400
@@ -0,0 +1,90 @@
+// PercentPrinter.cpp
+
+#include "StdAfx.h"
+
+#include "Common/IntToString.h"
+#include "Common/MyString.h"
+
+#include "PercentPrinter.h"
+
+const int kPaddingSize = 2;
+const int kPercentsSize = 4;
+const int kMaxExtraSize = kPaddingSize + 32 + kPercentsSize;
+
+static void ClearPrev(char *p, int num)
+{
+  int i;
+  for (i = 0; i < num; i++) *p++ = '\b';
+  for (i = 0; i < num; i++) *p++ = ' ';
+  for (i = 0; i < num; i++) *p++ = '\b';
+  *p = '\0';
+}
+
+void CPercentPrinter::ClosePrint()
+{
+  if (m_NumExtraChars == 0)
+    return;
+  char s[kMaxExtraSize * 3 + 1];
+  ClearPrev(s, m_NumExtraChars);
+  (*OutStream) << s;
+  m_NumExtraChars = 0;
+}
+
+void CPercentPrinter::PrintString(const char *s)
+{
+  ClosePrint();
+  (*OutStream) << s;
+}
+
+void CPercentPrinter::PrintString(const wchar_t *s)
+{
+  ClosePrint();
+  (*OutStream) << s;
+}
+
+void CPercentPrinter::PrintNewLine()
+{
+  ClosePrint();
+  (*OutStream) << "\n";
+}
+
+void CPercentPrinter::RePrintRatio()
+{
+  char s[32];
+  ConvertUInt64ToString(((m_Total == 0) ? 0 : (m_CurValue * 100 / m_Total)), s);
+  int size = (int)strlen(s);
+  s[size++] = '%';
+  s[size] = '\0';
+
+  int extraSize = kPaddingSize + MyMax(size, kPercentsSize);
+  if (extraSize < m_NumExtraChars)
+    extraSize = m_NumExtraChars;
+
+  char fullString[kMaxExtraSize * 3];
+  char *p = fullString;
+  int i;
+  if (m_NumExtraChars == 0)
+  {
+    for (i = 0; i < extraSize; i++) 
+      *p++ = ' ';
+    m_NumExtraChars = extraSize;
+  }
+
+  for (i = 0; i < m_NumExtraChars; i++) 
+    *p++ = '\b';
+  m_NumExtraChars = extraSize;
+  for (; size < m_NumExtraChars; size++)
+    *p++ = ' ';
+  MyStringCopy(p, s);
+  (*OutStream) << fullString;
+  OutStream->Flush(); 
+  m_PrevValue = m_CurValue;
+}
+
+void CPercentPrinter::PrintRatio()
+{
+  if (m_CurValue < m_PrevValue + m_MinStepSize && 
+      m_CurValue + m_MinStepSize > m_PrevValue && m_NumExtraChars != 0)
+    return;
+  RePrintRatio();
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/misc/libphysfs/lzma/CPP/7zip/UI/Console/PercentPrinter.h	Mon Apr 10 12:06:43 2017 -0400
@@ -0,0 +1,31 @@
+// PercentPrinter.h
+
+#ifndef __PERCENTPRINTER_H
+#define __PERCENTPRINTER_H
+
+#include "Common/Types.h"
+#include "Common/StdOutStream.h"
+
+class CPercentPrinter
+{
+  UInt64 m_MinStepSize;
+  UInt64 m_PrevValue;
+  UInt64 m_CurValue;
+  UInt64 m_Total;
+  int m_NumExtraChars;
+public:
+  CStdOutStream *OutStream;
+
+  CPercentPrinter(UInt64 minStepSize = 1): m_MinStepSize(minStepSize), 
+      m_PrevValue(0), m_CurValue(0), m_Total(1), m_NumExtraChars(0) {}
+  void SetTotal(UInt64 total) { m_Total = total; m_PrevValue = 0; }
+  void SetRatio(UInt64 doneValue) { m_CurValue = doneValue; }
+  void PrintString(const char *s);
+  void PrintString(const wchar_t *s);
+  void PrintNewLine();
+  void ClosePrint();
+  void RePrintRatio();
+  void PrintRatio();
+};
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/misc/libphysfs/lzma/CPP/7zip/UI/Console/StdAfx.cpp	Mon Apr 10 12:06:43 2017 -0400
@@ -0,0 +1,3 @@
+// StdAfx.cpp
+
+#include "StdAfx.h"
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/misc/libphysfs/lzma/CPP/7zip/UI/Console/StdAfx.h	Mon Apr 10 12:06:43 2017 -0400
@@ -0,0 +1,9 @@
+// StdAfx.h
+
+#ifndef __STDAFX_H
+#define __STDAFX_H
+
+#include "../../../Common/MyWindows.h"
+#include "../../../Common/NewHandler.h"
+
+#endif 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/misc/libphysfs/lzma/CPP/7zip/UI/Console/UpdateCallbackConsole.cpp	Mon Apr 10 12:06:43 2017 -0400
@@ -0,0 +1,208 @@
+// UpdateCallbackConsole.cpp
+
+#include "StdAfx.h"
+
+#include "UpdateCallbackConsole.h"
+
+#include "Windows/Error.h"
+#ifdef COMPRESS_MT
+#include "Windows/Synchronization.h"
+#endif
+
+#include "ConsoleClose.h"
+#include "UserInputUtils.h"
+
+using namespace NWindows;
+
+#ifdef COMPRESS_MT
+static NSynchronization::CCriticalSection g_CriticalSection;
+#define MT_LOCK NSynchronization::CCriticalSectionLock lock(g_CriticalSection);
+#else
+#define MT_LOCK
+#endif
+
+static const wchar_t *kEmptyFileAlias = L"[Content]";
+
+static const char *kCreatingArchiveMessage = "Creating archive ";
+static const char *kUpdatingArchiveMessage = "Updating archive ";
+static const char *kScanningMessage = "Scanning";
+
+
+HRESULT CUpdateCallbackConsole::OpenResult(const wchar_t *name, HRESULT result)
+{
+  (*OutStream) << endl;
+  if (result != S_OK)
+    (*OutStream) << "Error: " << name << " is not supported archive" << endl;
+  return S_OK;
+}
+
+HRESULT CUpdateCallbackConsole::StartScanning()
+{
+  (*OutStream) << kScanningMessage;
+  return S_OK;
+}
+
+HRESULT CUpdateCallbackConsole::CanNotFindError(const wchar_t *name, DWORD systemError)
+{
+  CantFindFiles.Add(name);
+  CantFindCodes.Add(systemError);
+  // m_PercentPrinter.ClosePrint();
+  if (!m_WarningsMode)
+  {
+    (*OutStream) << endl << endl;
+    m_PercentPrinter.PrintNewLine();
+    m_WarningsMode = true;
+  }
+  m_PercentPrinter.PrintString(name);
+  m_PercentPrinter.PrintString(":  WARNING: ");
+  m_PercentPrinter.PrintString(NError::MyFormatMessageW(systemError));
+  m_PercentPrinter.PrintNewLine();
+  return S_OK;
+}
+
+HRESULT CUpdateCallbackConsole::FinishScanning()
+{
+  (*OutStream) << endl << endl;
+  return S_OK;
+}
+
+HRESULT CUpdateCallbackConsole::StartArchive(const wchar_t *name, bool updating)
+{
+  if(updating)
+    (*OutStream) << kUpdatingArchiveMessage;
+  else
+    (*OutStream) << kCreatingArchiveMessage; 
+  if (name != 0)
+    (*OutStream) << name;
+  else
+    (*OutStream) << "StdOut";
+  (*OutStream) << endl << endl;
+  return S_OK;
+}
+
+HRESULT CUpdateCallbackConsole::FinishArchive()
+{
+  (*OutStream) << endl;
+  return S_OK;
+}
+
+HRESULT CUpdateCallbackConsole::CheckBreak()
+{
+  if (NConsoleClose::TestBreakSignal())
+    return E_ABORT;
+  return S_OK;
+}
+
+HRESULT CUpdateCallbackConsole::Finilize()
+{
+  MT_LOCK
+  if (m_NeedBeClosed)
+  {
+    if (EnablePercents)
+    {
+      m_PercentPrinter.ClosePrint();
+    }
+    if (!StdOutMode && m_NeedNewLine)
+    {
+      m_PercentPrinter.PrintNewLine();
+      m_NeedNewLine = false;
+    }
+    m_NeedBeClosed = false;
+  }
+  return S_OK;
+}
+
+HRESULT CUpdateCallbackConsole::SetNumFiles(UInt64 /* numFiles */)
+{
+  return S_OK;
+}
+
+HRESULT CUpdateCallbackConsole::SetTotal(UInt64 size)
+{
+  MT_LOCK
+  if (EnablePercents)
+    m_PercentPrinter.SetTotal(size);
+  return S_OK;
+}
+
+HRESULT CUpdateCallbackConsole::SetCompleted(const UInt64 *completeValue)
+{
+  MT_LOCK
+  if (completeValue != NULL)
+  {
+    if (EnablePercents)
+    {
+      m_PercentPrinter.SetRatio(*completeValue);
+      m_PercentPrinter.PrintRatio();
+      m_NeedBeClosed = true;
+    }
+  }
+  if (NConsoleClose::TestBreakSignal())
+    return E_ABORT;
+  return S_OK;
+}
+
+HRESULT CUpdateCallbackConsole::SetRatioInfo(const UInt64 * /* inSize */, const UInt64 * /* outSize */)
+{
+  /*
+  if (NConsoleClose::TestBreakSignal())
+    return E_ABORT;
+  */
+  return S_OK;
+}
+
+HRESULT CUpdateCallbackConsole::GetStream(const wchar_t *name, bool isAnti)
+{
+  MT_LOCK
+  if (StdOutMode)
+    return S_OK;
+  if(isAnti)
+    m_PercentPrinter.PrintString("Anti item    ");
+  else
+    m_PercentPrinter.PrintString("Compressing  ");
+  if (name[0] == 0)
+    name = kEmptyFileAlias;
+  m_PercentPrinter.PrintString(name);
+  if (EnablePercents)
+    m_PercentPrinter.RePrintRatio();
+  return S_OK;
+}
+
+HRESULT CUpdateCallbackConsole::OpenFileError(const wchar_t *name, DWORD systemError)
+{
+  MT_LOCK
+  FailedCodes.Add(systemError);
+  FailedFiles.Add(name);
+  // if (systemError == ERROR_SHARING_VIOLATION)
+  {
+    m_PercentPrinter.ClosePrint();
+    m_PercentPrinter.PrintNewLine();
+    m_PercentPrinter.PrintString("WARNING: ");
+    m_PercentPrinter.PrintString(NError::MyFormatMessageW(systemError));
+    return S_FALSE;
+  }
+  // return systemError;
+}
+
+HRESULT CUpdateCallbackConsole::SetOperationResult(Int32 )
+{
+  m_NeedBeClosed = true;
+  m_NeedNewLine = true;
+  return S_OK;  
+}
+
+HRESULT CUpdateCallbackConsole::CryptoGetTextPassword2(Int32 *passwordIsDefined, BSTR *password)
+{
+  if (!PasswordIsDefined) 
+  {
+    if (AskPassword)
+    {
+      Password = GetPassword(OutStream); 
+      PasswordIsDefined = true;
+    }
+  }
+  *passwordIsDefined = BoolToInt(PasswordIsDefined);
+  CMyComBSTR tempName(Password);
+  *password = tempName.Detach();
+  return S_OK;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/misc/libphysfs/lzma/CPP/7zip/UI/Console/UpdateCallbackConsole.h	Mon Apr 10 12:06:43 2017 -0400
@@ -0,0 +1,58 @@
+// UpdateCallbackConsole.h
+
+#ifndef __UPDATECALLBACKCONSOLE_H
+#define __UPDATECALLBACKCONSOLE_H
+
+#include "Common/MyString.h"
+#include "Common/StdOutStream.h"
+#include "PercentPrinter.h"
+#include "../Common/Update.h"
+
+class CUpdateCallbackConsole: public IUpdateCallbackUI2
+{
+  CPercentPrinter m_PercentPrinter;
+  bool m_NeedBeClosed;
+  bool m_NeedNewLine;
+
+  bool m_WarningsMode;
+
+  CStdOutStream *OutStream;
+public:
+  bool EnablePercents;
+  bool StdOutMode;
+
+  bool PasswordIsDefined;
+  UString Password;
+  bool AskPassword;
+
+
+  CUpdateCallbackConsole(): 
+      m_PercentPrinter(1 << 16),
+      PasswordIsDefined(false),
+      AskPassword(false),
+      StdOutMode(false),
+      EnablePercents(true),
+      m_WarningsMode(false)
+      {}
+  
+  ~CUpdateCallbackConsole() { Finilize(); }
+  void Init(CStdOutStream *outStream)
+  {
+    m_NeedBeClosed = false;
+    m_NeedNewLine = false;
+    FailedFiles.Clear();
+    FailedCodes.Clear();
+    OutStream = outStream;
+    m_PercentPrinter.OutStream = outStream;
+  }
+
+  INTERFACE_IUpdateCallbackUI2(;)
+
+  UStringVector FailedFiles;
+  CRecordVector<HRESULT> FailedCodes;
+
+  UStringVector CantFindFiles;
+  CRecordVector<HRESULT> CantFindCodes;
+};
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/misc/libphysfs/lzma/CPP/7zip/UI/Console/UserInputUtils.cpp	Mon Apr 10 12:06:43 2017 -0400
@@ -0,0 +1,58 @@
+// UserInputUtils.cpp
+
+#include "StdAfx.h"
+
+#include "Common/StdInStream.h"
+#include "Common/StringConvert.h"
+
+#include "UserInputUtils.h"
+
+static const char kYes = 'Y';
+static const char kNo = 'N';
+static const char kYesAll = 'A';
+static const char kNoAll = 'S';
+static const char kAutoRename = 'U';
+static const char kQuit = 'Q';
+
+static const char *kFirstQuestionMessage = "?\n";
+static const char *kHelpQuestionMessage = 
+  "(Y)es / (N)o / (A)lways / (S)kip all / A(u)to rename / (Q)uit? ";
+
+// return true if pressed Quite;
+// in: anAll
+// out: anAll, anYes;
+
+NUserAnswerMode::EEnum ScanUserYesNoAllQuit(CStdOutStream *outStream)
+{
+  (*outStream) << kFirstQuestionMessage;
+  for(;;)
+  {
+    (*outStream) << kHelpQuestionMessage;
+    AString scannedString = g_StdIn.ScanStringUntilNewLine();
+    scannedString.Trim();
+    if(!scannedString.IsEmpty())
+      switch(::MyCharUpper(scannedString[0]))
+      {
+        case kYes:
+          return NUserAnswerMode::kYes;
+        case kNo:
+          return NUserAnswerMode::kNo;
+        case kYesAll:
+          return NUserAnswerMode::kYesAll;
+        case kNoAll:
+          return NUserAnswerMode::kNoAll;
+        case kAutoRename:
+          return NUserAnswerMode::kAutoRename;
+        case kQuit:
+          return NUserAnswerMode::kQuit;
+      }
+  }
+}
+
+UString GetPassword(CStdOutStream *outStream)
+{
+  (*outStream) << "\nEnter password:";
+  outStream->Flush();
+  AString oemPassword = g_StdIn.ScanStringUntilNewLine();
+  return MultiByteToUnicodeString(oemPassword, CP_OEMCP); 
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/misc/libphysfs/lzma/CPP/7zip/UI/Console/UserInputUtils.h	Mon Apr 10 12:06:43 2017 -0400
@@ -0,0 +1,24 @@
+// UserInputUtils.h
+
+#ifndef __USERINPUTUTILS_H
+#define __USERINPUTUTILS_H
+
+#include "Common/StdOutStream.h"
+
+namespace NUserAnswerMode {
+
+enum EEnum
+{
+  kYes,
+  kNo,
+  kYesAll,
+  kNoAll,
+  kAutoRename,
+  kQuit
+};
+}
+
+NUserAnswerMode::EEnum ScanUserYesNoAllQuit(CStdOutStream *outStream);
+UString GetPassword(CStdOutStream *outStream);
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/misc/libphysfs/lzma/CPP/7zip/UI/Console/afxres.h	Mon Apr 10 12:06:43 2017 -0400
@@ -0,0 +1,1 @@
+#include <winresrc.h>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/misc/libphysfs/lzma/CPP/Build.mak	Mon Apr 10 12:06:43 2017 -0400
@@ -0,0 +1,68 @@
+!IFDEF CPU
+LIBS = $(LIBS) bufferoverflowU.lib 
+CFLAGS = $(CFLAGS) -GS- -Zc:forScope
+!ENDIF
+
+!IFNDEF O
+!IFDEF CPU
+O=$(CPU)
+!ELSE
+O=O
+!ENDIF
+!ENDIF
+
+!IF "$(CPU)" != "IA64"
+!IF "$(CPU)" != "AMD64"
+MY_ML = ml
+!ELSE
+MY_ML = ml64
+!ENDIF
+!ENDIF
+
+COMPL_ASM = $(MY_ML) -c -Fo$O/ $**
+
+CFLAGS = $(CFLAGS) -nologo -c -Fo$O/ -EHsc -Gz -WX -Gy
+
+!IFDEF MY_STATIC_LINK
+!IFNDEF MY_SINGLE_THREAD
+CFLAGS = $(CFLAGS) -MT
+!ENDIF
+!ELSE
+CFLAGS = $(CFLAGS) -MD
+!ENDIF
+
+!IFDEF NEW_COMPILER
+CFLAGS_O1 = $(CFLAGS) -O1 -W4 -Wp64
+CFLAGS_O2 = $(CFLAGS) -O2 -W4 -Wp64
+!ELSE
+CFLAGS_O1 = $(CFLAGS) -O1 -W3
+CFLAGS_O2 = $(CFLAGS) -O2 -W3
+!ENDIF
+
+LFLAGS = $(LFLAGS) -nologo -OPT:NOWIN98 -OPT:REF 
+
+!IFDEF DEF_FILE
+LFLAGS = $(LFLAGS) -DLL -DEF:$(DEF_FILE)
+!ENDIF
+
+PROGPATH = $O\$(PROG)
+
+COMPL_O1   = $(CPP) $(CFLAGS_O1) $**
+COMPL_O2   = $(CPP) $(CFLAGS_O2) $**
+COMPL_PCH  = $(CPP) $(CFLAGS_O1) -Yc"StdAfx.h" -Fp$O/a.pch $** 
+COMPL      = $(CPP) $(CFLAGS_O1) -Yu"StdAfx.h" -Fp$O/a.pch $**
+
+all: $(PROGPATH) 
+
+clean:
+	-del /Q $(PROGPATH) $O\*.exe $O\*.dll $O\*.obj $O\*.lib $O\*.exp $O\*.res $O\*.pch 
+
+$O:
+	if not exist "$O" mkdir "$O"
+
+$(PROGPATH): $O $(OBJS) $(DEF_FILE)
+	link $(LFLAGS) -out:$(PROGPATH) $(OBJS) $(LIBS)
+$O\resource.res: $(*B).rc
+	rc -fo$@ $**
+$O\StdAfx.obj: $(*B).cpp
+	$(COMPL_PCH)
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/misc/libphysfs/lzma/CPP/Common/AutoPtr.h	Mon Apr 10 12:06:43 2017 -0400
@@ -0,0 +1,35 @@
+// Common/AutoPtr.h
+
+#ifndef __COMMON_AUTOPTR_H
+#define __COMMON_AUTOPTR_H
+
+template<class T> class CMyAutoPtr
+{
+  T *_p;
+public:
+  CMyAutoPtr(T *p = 0) : _p(p) {}
+  CMyAutoPtr(CMyAutoPtr<T>& p): _p(p.release()) {}
+  CMyAutoPtr<T>& operator=(CMyAutoPtr<T>& p) 
+  {
+    reset(p.release());
+    return (*this);
+  }
+  ~CMyAutoPtr() { delete _p; }
+  T& operator*() const { return *_p; }
+  // T* operator->() const { return (&**this); }
+  T* get() const { return _p; }
+  T* release()
+  {
+    T *tmp = _p;
+    _p = 0;
+    return tmp;
+  }
+  void reset(T* p = 0)
+  {
+    if (p != _p)
+      delete _p;
+    _p = p;
+  }
+};
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/misc/libphysfs/lzma/CPP/Common/Buffer.h	Mon Apr 10 12:06:43 2017 -0400
@@ -0,0 +1,77 @@
+// Common/Buffer.h
+
+#ifndef __COMMON_BUFFER_H
+#define __COMMON_BUFFER_H
+
+#include "Defs.h"
+
+template <class T> class CBuffer
+{    
+protected:
+  size_t _capacity;
+  T *_items;
+public:
+  void Free()
+  {
+    delete []_items;
+    _items = 0;
+    _capacity = 0;
+  }
+  CBuffer(): _capacity(0), _items(0) {};
+  CBuffer(const CBuffer &buffer): _capacity(0), _items(0) { *this = buffer; }
+  CBuffer(size_t size): _items(0),  _capacity(0) {  SetCapacity(size); }
+  virtual ~CBuffer() { delete []_items; }
+  operator T *() { return _items; };
+  operator const T *() const { return _items; };
+  size_t GetCapacity() const { return  _capacity; }
+  void SetCapacity(size_t newCapacity)
+  {
+    if (newCapacity == _capacity)
+      return;
+    T *newBuffer;
+    if (newCapacity > 0)
+    {
+      newBuffer = new T[newCapacity];
+      if(_capacity > 0)
+        memmove(newBuffer, _items, MyMin(_capacity, newCapacity) * sizeof(T));
+    }
+    else
+      newBuffer = 0;
+    delete []_items;
+    _items = newBuffer;
+    _capacity = newCapacity;
+  }
+  CBuffer& operator=(const CBuffer &buffer)
+  {
+    Free();
+    if(buffer._capacity > 0)
+    {
+      SetCapacity(buffer._capacity);
+      memmove(_items, buffer._items, buffer._capacity * sizeof(T));
+    }
+    return *this;
+  }
+};
+
+template <class T>
+bool operator==(const CBuffer<T>& b1, const CBuffer<T>& b2)
+{
+  if (b1.GetCapacity() != b2.GetCapacity())
+    return false;
+  for (size_t i = 0; i < b1.GetCapacity(); i++)
+    if (b1[i] != b2[i])
+      return false;
+  return true;
+}
+
+template <class T>
+bool operator!=(const CBuffer<T>& b1, const CBuffer<T>& b2)
+{
+  return !(b1 == b2);
+}
+
+typedef CBuffer<char> CCharBuffer;
+typedef CBuffer<wchar_t> CWCharBuffer;
+typedef CBuffer<unsigned char> CByteBuffer;
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/misc/libphysfs/lzma/CPP/Common/CRC.cpp	Mon Apr 10 12:06:43 2017 -0400
@@ -0,0 +1,14 @@
+// Common/CRC.cpp
+
+#include "StdAfx.h"
+
+extern "C" 
+{ 
+#include "../../C/7zCrc.h"
+}
+
+class CCRCTableInit
+{
+public:
+  CCRCTableInit() { CrcGenerateTable(); }
+} g_CRCTableInit;
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/misc/libphysfs/lzma/CPP/Common/C_FileIO.cpp	Mon Apr 10 12:06:43 2017 -0400
@@ -0,0 +1,88 @@
+// Common/C_FileIO.h
+
+#include "C_FileIO.h"
+
+#include <fcntl.h>
+#include <unistd.h>
+
+namespace NC {
+namespace NFile {
+namespace NIO {
+
+bool CFileBase::OpenBinary(const char *name, int flags)
+{
+  #ifdef O_BINARY
+  flags |= O_BINARY;
+  #endif
+  Close();
+  _handle = ::open(name, flags, 0666);
+  return _handle != -1;
+}
+
+bool CFileBase::Close()
+{
+  if(_handle == -1)
+    return true;
+  if (close(_handle) != 0)
+    return false;
+  _handle = -1;
+  return true;
+}
+
+bool CFileBase::GetLength(UInt64 &length) const
+{
+  off_t curPos = Seek(0, SEEK_CUR);
+  off_t lengthTemp = Seek(0, SEEK_END);
+  Seek(curPos, SEEK_SET);
+  length = (UInt64)lengthTemp;
+  return true;
+}
+
+off_t CFileBase::Seek(off_t distanceToMove, int moveMethod) const
+{
+  return ::lseek(_handle, distanceToMove, moveMethod);
+}
+
+/////////////////////////
+// CInFile
+
+bool CInFile::Open(const char *name)
+{
+  return CFileBase::OpenBinary(name, O_RDONLY);
+}
+
+bool CInFile::OpenShared(const char *name, bool)
+{
+  return Open(name);
+}
+
+ssize_t CInFile::Read(void *data, size_t size)
+{
+  return read(_handle, data, size);
+}
+
+/////////////////////////
+// COutFile
+
+bool COutFile::Create(const char *name, bool createAlways)
+{
+  if (createAlways)
+  {
+    Close();
+    _handle = ::creat(name, 0666);
+    return _handle != -1;
+  }
+  return OpenBinary(name, O_CREAT | O_EXCL | O_WRONLY);
+}
+
+bool COutFile::Open(const char *name, DWORD creationDisposition)
+{
+  return Create(name, false);
+}
+
+ssize_t COutFile::Write(const void *data, size_t size)
+{
+  return write(_handle, data, size);
+}
+
+}}}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/misc/libphysfs/lzma/CPP/Common/C_FileIO.h	Mon Apr 10 12:06:43 2017 -0400
@@ -0,0 +1,47 @@
+// Common/C_FileIO.h
+
+#ifndef __COMMON_C_FILEIO_H
+#define __COMMON_C_FILEIO_H
+
+#include <stdio.h>
+#include <sys/types.h>
+
+#include "Types.h"
+#include "MyWindows.h"
+
+namespace NC {
+namespace NFile {
+namespace NIO {
+
+class CFileBase
+{
+protected:
+  int _handle;
+  bool OpenBinary(const char *name, int flags);
+public:
+  CFileBase(): _handle(-1) {};
+  ~CFileBase() { Close(); }
+  bool Close();
+  bool GetLength(UInt64 &length) const;
+  off_t Seek(off_t distanceToMove, int moveMethod) const;
+};
+
+class CInFile: public CFileBase
+{
+public:
+  bool Open(const char *name);
+  bool OpenShared(const char *name, bool shareForWrite);
+  ssize_t Read(void *data, size_t size);
+};
+
+class COutFile: public CFileBase
+{
+public:
+  bool Create(const char *name, bool createAlways);
+  bool Open(const char *name, DWORD creationDisposition);
+  ssize_t Write(const void *data, size_t size);
+};
+
+}}}
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/misc/libphysfs/lzma/CPP/Common/ComTry.h	Mon Apr 10 12:06:43 2017 -0400
@@ -0,0 +1,17 @@
+// ComTry.h
+
+#ifndef __COM_TRY_H
+#define __COM_TRY_H
+
+#include "MyWindows.h"
+// #include "Exception.h"
+// #include "NewHandler.h"
+
+#define COM_TRY_BEGIN try {
+#define COM_TRY_END } catch(...) { return E_OUTOFMEMORY; }
+  
+  // catch(const CNewException &) { return E_OUTOFMEMORY; }\
+  // catch(const CSystemException &e) { return e.ErrorCode; }\
+  // catch(...) { return E_FAIL; }
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/misc/libphysfs/lzma/CPP/Common/CommandLineParser.cpp	Mon Apr 10 12:06:43 2017 -0400
@@ -0,0 +1,232 @@
+// CommandLineParser.cpp
+
+#include "StdAfx.h"
+
+#include "CommandLineParser.h"
+
+namespace NCommandLineParser {
+
+void SplitCommandLine(const UString &src, UString &dest1, UString &dest2)
+{
+  dest1.Empty();
+  dest2.Empty();
+  bool quoteMode = false;
+  int i;
+  for (i = 0; i < src.Length(); i++)
+  {
+    wchar_t c = src[i];
+    if (c == L'\"')
+      quoteMode = !quoteMode;
+    else if (c == L' ' && !quoteMode)
+    {
+      i++;
+      break;
+    }
+    else 
+      dest1 += c;
+  }
+  dest2 = src.Mid(i);
+}
+
+void SplitCommandLine(const UString &s, UStringVector &parts)
+{
+  UString sTemp = s;
+  sTemp.Trim();
+  parts.Clear();
+  for (;;)
+  {
+    UString s1, s2;
+    SplitCommandLine(sTemp, s1, s2);
+    // s1.Trim();
+    // s2.Trim();
+    if (!s1.IsEmpty())
+      parts.Add(s1);
+    if (s2.IsEmpty())
+      break;
+    sTemp = s2;
+  }
+}
+
+
+static const wchar_t kSwitchID1 = '-';
+// static const wchar_t kSwitchID2 = '/';
+
+static const wchar_t kSwitchMinus = '-';
+static const wchar_t *kStopSwitchParsing = L"--";
+
+static bool IsItSwitchChar(wchar_t c)
+{ 
+  return (c == kSwitchID1 /*|| c == kSwitchID2 */); 
+}
+
+CParser::CParser(int numSwitches):
+  _numSwitches(numSwitches)
+{
+  _switches = new CSwitchResult[_numSwitches];
+}
+
+CParser::~CParser()
+{
+  delete []_switches;
+}
+
+void CParser::ParseStrings(const CSwitchForm *switchForms, 
+  const UStringVector &commandStrings)
+{
+  int numCommandStrings = commandStrings.Size();
+  bool stopSwitch = false;
+  for (int i = 0; i < numCommandStrings; i++)
+  {
+    const UString &s = commandStrings[i];
+    if (stopSwitch)
+      NonSwitchStrings.Add(s);
+    else
+      if (s == kStopSwitchParsing)
+        stopSwitch = true;
+      else
+        if (!ParseString(s, switchForms))
+          NonSwitchStrings.Add(s);
+  }
+}
+
+// if string contains switch then function updates switch structures
+// out: (string is a switch)
+bool CParser::ParseString(const UString &s, const CSwitchForm *switchForms)
+{
+  int len = s.Length();
+  if (len == 0) 
+    return false;
+  int pos = 0;
+  if (!IsItSwitchChar(s[pos]))
+    return false;
+  while(pos < len)
+  {
+    if (IsItSwitchChar(s[pos]))
+      pos++;
+    const int kNoLen = -1;
+    int matchedSwitchIndex = 0; // GCC Warning
+    int maxLen = kNoLen;
+    for(int switchIndex = 0; switchIndex < _numSwitches; switchIndex++)
+    {
+      int switchLen = MyStringLen(switchForms[switchIndex].IDString);
+      if (switchLen <= maxLen || pos + switchLen > len) 
+        continue;
+
+      UString temp = s + pos;
+      temp = temp.Left(switchLen);
+      if(temp.CompareNoCase(switchForms[switchIndex].IDString) == 0)
+      // if(_strnicmp(switchForms[switchIndex].IDString, LPCSTR(s) + pos, switchLen) == 0)
+      {
+        matchedSwitchIndex = switchIndex;
+        maxLen = switchLen;
+      }
+    }
+    if (maxLen == kNoLen)
+      throw "maxLen == kNoLen";
+    CSwitchResult &matchedSwitch = _switches[matchedSwitchIndex];
+    const CSwitchForm &switchForm = switchForms[matchedSwitchIndex];
+    if ((!switchForm.Multi) && matchedSwitch.ThereIs)
+      throw "switch must be single";
+    matchedSwitch.ThereIs = true;
+    pos += maxLen;
+    int tailSize = len - pos;
+    NSwitchType::EEnum type = switchForm.Type;
+    switch(type)
+    {
+      case NSwitchType::kPostMinus:
+        {
+          if (tailSize == 0)
+            matchedSwitch.WithMinus = false;
+          else
+          {
+            matchedSwitch.WithMinus = (s[pos] == kSwitchMinus);
+            if (matchedSwitch.WithMinus)
+              pos++;
+          }
+          break;
+        }
+      case NSwitchType::kPostChar:
+        {
+          if (tailSize < switchForm.MinLen)
+            throw "switch is not full";
+          UString set = switchForm.PostCharSet;
+          const int kEmptyCharValue = -1;
+          if (tailSize == 0)
+            matchedSwitch.PostCharIndex = kEmptyCharValue;
+          else
+          {
+            int index = set.Find(s[pos]);
+            if (index < 0)
+              matchedSwitch.PostCharIndex =  kEmptyCharValue;
+            else
+            {
+              matchedSwitch.PostCharIndex = index;
+              pos++;
+            }
+          }
+          break;
+        }
+      case NSwitchType::kLimitedPostString: 
+      case NSwitchType::kUnLimitedPostString: 
+        {
+          int minLen = switchForm.MinLen;
+          if (tailSize < minLen)
+            throw "switch is not full";
+          if (type == NSwitchType::kUnLimitedPostString)
+          {
+            matchedSwitch.PostStrings.Add(s.Mid(pos));
+            return true;
+          }
+          int maxLen = switchForm.MaxLen;
+          UString stringSwitch = s.Mid(pos, minLen);
+          pos += minLen;
+          for(int i = minLen; i < maxLen && pos < len; i++, pos++)
+          {
+            wchar_t c = s[pos];
+            if (IsItSwitchChar(c))
+              break;
+            stringSwitch += c;
+          }
+          matchedSwitch.PostStrings.Add(stringSwitch);
+          break;
+        }
+      case NSwitchType::kSimple:
+          break;
+    }
+  }
+  return true;
+}
+
+const CSwitchResult& CParser::operator[](size_t index) const
+{
+  return _switches[index];
+}
+
+/////////////////////////////////
+// Command parsing procedures
+
+int ParseCommand(int numCommandForms, const CCommandForm *commandForms, 
+    const UString &commandString, UString &postString)
+{
+  for(int i = 0; i < numCommandForms; i++)
+  {
+    const UString id = commandForms[i].IDString;
+    if (commandForms[i].PostStringMode)
+    {
+      if(commandString.Find(id) == 0)
+      {
+        postString = commandString.Mid(id.Length());
+        return i;
+      }
+    }
+    else
+      if (commandString == id)
+      {
+        postString.Empty();
+        return i;
+      }
+  }
+  return -1;
+}
+   
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/misc/libphysfs/lzma/CPP/Common/CommandLineParser.h	Mon Apr 10 12:06:43 2017 -0400
@@ -0,0 +1,72 @@
+// Common/CommandLineParser.h
+
+#ifndef __COMMON_COMMANDLINEPARSER_H
+#define __COMMON_COMMANDLINEPARSER_H
+
+#include "MyString.h"
+
+namespace NCommandLineParser {
+
+void SplitCommandLine(const UString &src, UString &dest1, UString &dest2);
+void SplitCommandLine(const UString &s, UStringVector &parts);
+
+namespace NSwitchType {
+  enum EEnum
+  { 
+    kSimple,
+    kPostMinus,
+    kLimitedPostString,
+    kUnLimitedPostString,
+    kPostChar
+  };
+}
+
+struct CSwitchForm
+{
+  const wchar_t *IDString;
+  NSwitchType::EEnum Type;
+  bool Multi;
+  int MinLen;
+  int MaxLen;
+  const wchar_t *PostCharSet;
+};
+
+struct CSwitchResult
+{
+  bool ThereIs;
+  bool WithMinus;
+  UStringVector PostStrings;
+  int PostCharIndex;
+  CSwitchResult(): ThereIs(false) {};
+};
+  
+class CParser
+{
+  int _numSwitches;
+  CSwitchResult *_switches;
+  bool ParseString(const UString &s, const CSwitchForm *switchForms); 
+public:
+  UStringVector NonSwitchStrings;
+  CParser(int numSwitches);
+  ~CParser();
+  void ParseStrings(const CSwitchForm *switchForms, 
+    const UStringVector &commandStrings);
+  const CSwitchResult& operator[](size_t index) const;
+};
+
+/////////////////////////////////
+// Command parsing procedures
+
+struct CCommandForm
+{
+  wchar_t *IDString;
+  bool PostStringMode;
+};
+
+// Returns: Index of form and postString; -1, if there is no match
+int ParseCommand(int numCommandForms, const CCommandForm *commandForms, 
+    const UString &commandString, UString &postString);
+
+}
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/misc/libphysfs/lzma/CPP/Common/Defs.h	Mon Apr 10 12:06:43 2017 -0400
@@ -0,0 +1,20 @@
+// Common/Defs.h
+
+#ifndef __COMMON_DEFS_H
+#define __COMMON_DEFS_H
+
+template <class T> inline T MyMin(T a, T b)
+  {  return a < b ? a : b; }
+template <class T> inline T MyMax(T a, T b)
+  {  return a > b ? a : b; }
+
+template <class T> inline int MyCompare(T a, T b)
+  {  return a < b ? -1 : (a == b ? 0 : 1); }
+
+inline int BoolToInt(bool value)
+  { return (value ? 1: 0); }
+
+inline bool IntToBool(int value)
+  { return (value != 0); }
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/misc/libphysfs/lzma/CPP/Common/DynamicBuffer.h	Mon Apr 10 12:06:43 2017 -0400
@@ -0,0 +1,47 @@
+// Common/DynamicBuffer.h
+
+#ifndef __COMMON_DYNAMICBUFFER_H
+#define __COMMON_DYNAMICBUFFER_H
+
+#include "Buffer.h"
+
+template <class T> class CDynamicBuffer: public CBuffer<T>
+{    
+  void GrowLength(size_t size)
+  {
+    size_t delta;
+    if (this->_capacity > 64)
+      delta = this->_capacity / 4;
+    else if (this->_capacity > 8)
+      delta = 16;
+    else
+      delta = 4;
+    delta = MyMax(delta, size);
+    SetCapacity(this->_capacity + delta);
+  }
+public:
+  CDynamicBuffer(): CBuffer<T>() {};
+  CDynamicBuffer(const CDynamicBuffer &buffer): CBuffer<T>(buffer) {};
+  CDynamicBuffer(size_t size): CBuffer<T>(size) {};
+  CDynamicBuffer& operator=(const CDynamicBuffer &buffer)
+  {
+    this->Free();
+    if(buffer._capacity > 0)
+    {
+      SetCapacity(buffer._capacity);
+      memmove(this->_items, buffer._items, buffer._capacity * sizeof(T));
+    }
+    return *this;
+  }
+  void EnsureCapacity(size_t capacity)
+  {
+    if (this->_capacity < capacity)
+      GrowLength(capacity - this->_capacity);
+  }
+};
+
+typedef CDynamicBuffer<char> CCharDynamicBuffer;
+typedef CDynamicBuffer<wchar_t> CWCharDynamicBuffer;
+typedef CDynamicBuffer<unsigned char> CByteDynamicBuffer;
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/misc/libphysfs/lzma/CPP/Common/IntToString.cpp	Mon Apr 10 12:06:43 2017 -0400
@@ -0,0 +1,63 @@
+// Common/IntToString.cpp
+
+#include "StdAfx.h"
+
+#include "IntToString.h"
+
+void ConvertUInt64ToString(UInt64 value, char *s, UInt32 base)
+{
+  if (base < 2 || base > 36)
+  {
+    *s = '\0';
+    return;
+  }
+  char temp[72];
+  int pos = 0;
+  do 
+  {
+    int delta = (int)(value % base);
+    temp[pos++] = (char)((delta < 10) ? ('0' + delta) : ('a' + (delta - 10)));
+    value /= base;
+  }
+  while (value != 0);
+  do
+    *s++ = temp[--pos];
+  while(pos > 0);
+  *s = '\0';
+}
+
+void ConvertUInt64ToString(UInt64 value, wchar_t *s)
+{
+  wchar_t temp[32];
+  int pos = 0;
+  do 
+  {
+    temp[pos++] = (wchar_t)(L'0' + (int)(value % 10));
+    value /= 10;
+  }
+  while (value != 0);
+  do 
+    *s++ = temp[--pos];
+  while(pos > 0);
+  *s = L'\0';
+}
+
+void ConvertInt64ToString(Int64 value, char *s)
+{
+  if (value < 0)
+  {
+    *s++ = '-';
+    value = -value;
+  }
+  ConvertUInt64ToString(value, s);
+}
+
+void ConvertInt64ToString(Int64 value, wchar_t *s)
+{
+  if (value < 0)
+  {
+    *s++ = L'-';
+    value = -value;
+  }
+  ConvertUInt64ToString(value, s);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/misc/libphysfs/lzma/CPP/Common/IntToString.h	Mon Apr 10 12:06:43 2017 -0400
@@ -0,0 +1,15 @@
+// Common/IntToString.h
+
+#ifndef __COMMON_INTTOSTRING_H
+#define __COMMON_INTTOSTRING_H
+
+#include <stddef.h>
+#include "Types.h"
+
+void ConvertUInt64ToString(UInt64 value, char *s, UInt32 base = 10);
+void ConvertUInt64ToString(UInt64 value, wchar_t *s);
+
+void ConvertInt64ToString(Int64 value, char *s);
+void ConvertInt64ToString(Int64 value, wchar_t *s);
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/misc/libphysfs/lzma/CPP/Common/ListFileUtils.cpp	Mon Apr 10 12:06:43 2017 -0400
@@ -0,0 +1,74 @@
+// Common/ListFileUtils.cpp
+
+#include "StdAfx.h"
+
+#include "../Windows/FileIO.h"
+
+#include "ListFileUtils.h"
+#include "StringConvert.h"
+#include "UTFConvert.h"
+
+static const char kQuoteChar     = '\"';
+static void RemoveQuote(UString &s)
+{
+  if (s.Length() >= 2)
+    if (s[0] == kQuoteChar && s[s.Length() - 1] == kQuoteChar)
+      s = s.Mid(1, s.Length() - 2);
+}
+
+bool ReadNamesFromListFile(LPCWSTR fileName, UStringVector &resultStrings, UINT codePage)
+{
+  NWindows::NFile::NIO::CInFile file;
+  if (!file.Open(fileName))
+    return false;
+  UInt64 length;
+  if (!file.GetLength(length))
+    return false;
+  if (length > ((UInt32)1 << 31))
+    return false;
+  AString s;
+  char *p = s.GetBuffer((int)length + 1);
+  UInt32 processed;
+  if (!file.Read(p, (UInt32)length, processed))
+    return false;
+  p[(UInt32)length] = 0;
+  s.ReleaseBuffer();
+  file.Close();
+
+  UString u;
+  #ifdef CP_UTF8
+  if (codePage == CP_UTF8)
+  {
+    if (!ConvertUTF8ToUnicode(s, u))
+      return false;
+  }
+  else
+  #endif
+    u = MultiByteToUnicodeString(s, codePage);
+  if (!u.IsEmpty())
+  {
+    if (u[0] == 0xFEFF)
+      u.Delete(0);
+  }
+
+  UString t;
+  for(int i = 0; i < u.Length(); i++)
+  {
+    wchar_t c = u[i];
+    if (c == L'\n' || c == 0xD)
+    {
+      t.Trim();
+      RemoveQuote(t);
+      if (!t.IsEmpty())
+        resultStrings.Add(t);
+      t.Empty();
+    }
+    else
+      t += c;
+  }
+  t.Trim();
+  RemoveQuote(t);
+  if (!t.IsEmpty())
+    resultStrings.Add(t);
+  return true;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/misc/libphysfs/lzma/CPP/Common/ListFileUtils.h	Mon Apr 10 12:06:43 2017 -0400
@@ -0,0 +1,11 @@
+// Common/ListFileUtils.h
+
+#ifndef __COMMON_LISTFILEUTILS_H
+#define __COMMON_LISTFILEUTILS_H
+
+#include "MyString.h"
+#include "Types.h"
+
+bool ReadNamesFromListFile(LPCWSTR fileName, UStringVector &strings, UINT codePage = CP_OEMCP);
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/misc/libphysfs/lzma/CPP/Common/MyCom.h	Mon Apr 10 12:06:43 2017 -0400
@@ -0,0 +1,218 @@
+// MyCom.h
+
+#ifndef __MYCOM_H
+#define __MYCOM_H
+
+#include "MyWindows.h"
+
+#ifndef RINOK
+#define RINOK(x) { HRESULT __result_ = (x); if(__result_ != S_OK) return __result_; }
+#endif
+
+template <class T>
+class CMyComPtr
+{
+  T* _p;
+public:
+  // typedef T _PtrClass;
+  CMyComPtr() { _p = NULL;}
+  CMyComPtr(T* p) {if ((_p = p) != NULL) p->AddRef(); }
+  CMyComPtr(const CMyComPtr<T>& lp)
+  {
+    if ((_p = lp._p) != NULL)
+      _p->AddRef();
+  }
+  ~CMyComPtr() { if (_p) _p->Release(); }
+  void Release() { if (_p) { _p->Release(); _p = NULL; } }
+  operator T*() const {  return (T*)_p;  }
+  // T& operator*() const {  return *_p; }
+  T** operator&() { return &_p; }
+  T* operator->() const { return _p; }
+  T* operator=(T* p) 
+  { 
+    if (p != 0)
+      p->AddRef();
+    if (_p) 
+      _p->Release();
+    _p = p;
+    return p;
+  }
+  T* operator=(const CMyComPtr<T>& lp) { return (*this = lp._p); }
+  bool operator!() const { return (_p == NULL); }
+  // bool operator==(T* pT) const {  return _p == pT; }
+  // Compare two objects for equivalence
+  void Attach(T* p2)
+  {
+    Release();
+    _p = p2;
+  }
+  T* Detach()
+  {
+    T* pt = _p;
+    _p = NULL;
+    return pt;
+  }
+  #ifdef _WIN32
+  HRESULT CoCreateInstance(REFCLSID rclsid, REFIID iid, LPUNKNOWN pUnkOuter = NULL, DWORD dwClsContext = CLSCTX_ALL)
+  {
+    return ::CoCreateInstance(rclsid, pUnkOuter, dwClsContext, iid, (void**)&_p);
+  }
+  #endif
+  /*
+  HRESULT CoCreateInstance(LPCOLESTR szProgID, LPUNKNOWN pUnkOuter = NULL, DWORD dwClsContext = CLSCTX_ALL)
+  {
+    CLSID clsid;
+    HRESULT hr = CLSIDFromProgID(szProgID, &clsid);
+    ATLASSERT(_p == NULL);
+    if (SUCCEEDED(hr))
+      hr = ::CoCreateInstance(clsid, pUnkOuter, dwClsContext, __uuidof(T), (void**)&_p);
+    return hr;
+  }
+  */
+  template <class Q>
+  HRESULT QueryInterface(REFGUID iid, Q** pp) const
+  {
+    return _p->QueryInterface(iid, (void**)pp);
+  }
+};
+
+//////////////////////////////////////////////////////////
+
+class CMyComBSTR
+{
+public:
+  BSTR m_str;
+  CMyComBSTR() { m_str = NULL; }
+  CMyComBSTR(LPCOLESTR pSrc) {  m_str = ::SysAllocString(pSrc);  }
+  // CMyComBSTR(int nSize) { m_str = ::SysAllocStringLen(NULL, nSize); }
+  // CMyComBSTR(int nSize, LPCOLESTR sz) { m_str = ::SysAllocStringLen(sz, nSize);  }
+  CMyComBSTR(const CMyComBSTR& src) { m_str = src.MyCopy(); }
+  /*
+  CMyComBSTR(REFGUID src)
+  {
+    LPOLESTR szGuid;
+    StringFromCLSID(src, &szGuid);
+    m_str = ::SysAllocString(szGuid);
+    CoTaskMemFree(szGuid);
+  }
+  */
+  ~CMyComBSTR() { ::SysFreeString(m_str); }
+  CMyComBSTR& operator=(const CMyComBSTR& src)
+  {
+    if (m_str != src.m_str)
+    {
+      if (m_str)
+        ::SysFreeString(m_str);
+      m_str = src.MyCopy();
+    }
+    return *this;
+  }
+  CMyComBSTR& operator=(LPCOLESTR pSrc)
+  {
+    ::SysFreeString(m_str);
+    m_str = ::SysAllocString(pSrc);
+    return *this;
+  }
+  unsigned int Length() const { return ::SysStringLen(m_str); }
+  operator BSTR() const { return m_str; }
+  BSTR* operator&() { return &m_str; }
+  BSTR MyCopy() const 
+  { 
+    int byteLen = ::SysStringByteLen(m_str);
+    BSTR res = ::SysAllocStringByteLen(NULL, byteLen);
+    memmove(res, m_str, byteLen);
+    return res;
+  }
+  void Attach(BSTR src) {  m_str = src; }
+  BSTR Detach()
+  {
+    BSTR s = m_str;
+    m_str = NULL;
+    return s;
+  }
+  void Empty()
+  {
+    ::SysFreeString(m_str);
+    m_str = NULL;
+  }
+  bool operator!() const {  return (m_str == NULL); }
+};
+
+
+//////////////////////////////////////////////////////////
+
+class CMyUnknownImp
+{
+public:
+  ULONG __m_RefCount;
+  CMyUnknownImp(): __m_RefCount(0) {}
+};
+
+#define MY_QUERYINTERFACE_BEGIN STDMETHOD(QueryInterface) \
+    (REFGUID iid, void **outObject) { 
+
+#define MY_QUERYINTERFACE_ENTRY(i) if (iid == IID_ ## i) \
+    { *outObject = (void *)(i *)this; AddRef(); return S_OK; }
+
+#define MY_QUERYINTERFACE_ENTRY_UNKNOWN(i) if (iid == IID_IUnknown) \
+    { *outObject = (void *)(IUnknown *)(i *)this; AddRef(); return S_OK; }
+
+#define MY_QUERYINTERFACE_BEGIN2(i) MY_QUERYINTERFACE_BEGIN \
+    MY_QUERYINTERFACE_ENTRY_UNKNOWN(i) \
+    MY_QUERYINTERFACE_ENTRY(i)
+
+#define MY_QUERYINTERFACE_END return E_NOINTERFACE; }
+
+#define MY_ADDREF_RELEASE \
+STDMETHOD_(ULONG, AddRef)() { return ++__m_RefCount; } \
+STDMETHOD_(ULONG, Release)() { if (--__m_RefCount != 0)  \
+  return __m_RefCount; delete this; return 0; }
+
+#define MY_UNKNOWN_IMP_SPEC(i) \
+  MY_QUERYINTERFACE_BEGIN \
+  i \
+  MY_QUERYINTERFACE_END \
+  MY_ADDREF_RELEASE
+
+
+#define MY_UNKNOWN_IMP MY_QUERYINTERFACE_BEGIN \
+  MY_QUERYINTERFACE_ENTRY_UNKNOWN(IUnknown) \
+  MY_QUERYINTERFACE_END \
+  MY_ADDREF_RELEASE
+
+#define MY_UNKNOWN_IMP1(i) MY_UNKNOWN_IMP_SPEC( \
+  MY_QUERYINTERFACE_ENTRY_UNKNOWN(i) \
+  MY_QUERYINTERFACE_ENTRY(i) \
+  )
+
+#define MY_UNKNOWN_IMP2(i1, i2) MY_UNKNOWN_IMP_SPEC( \
+  MY_QUERYINTERFACE_ENTRY_UNKNOWN(i1) \
+  MY_QUERYINTERFACE_ENTRY(i1) \
+  MY_QUERYINTERFACE_ENTRY(i2) \
+  )
+
+#define MY_UNKNOWN_IMP3(i1, i2, i3) MY_UNKNOWN_IMP_SPEC( \
+  MY_QUERYINTERFACE_ENTRY_UNKNOWN(i1) \
+  MY_QUERYINTERFACE_ENTRY(i1) \
+  MY_QUERYINTERFACE_ENTRY(i2) \
+  MY_QUERYINTERFACE_ENTRY(i3) \
+  )
+
+#define MY_UNKNOWN_IMP4(i1, i2, i3, i4) MY_UNKNOWN_IMP_SPEC( \
+  MY_QUERYINTERFACE_ENTRY_UNKNOWN(i1) \
+  MY_QUERYINTERFACE_ENTRY(i1) \
+  MY_QUERYINTERFACE_ENTRY(i2) \
+  MY_QUERYINTERFACE_ENTRY(i3) \
+  MY_QUERYINTERFACE_ENTRY(i4) \
+  )
+
+#define MY_UNKNOWN_IMP5(i1, i2, i3, i4, i5) MY_UNKNOWN_IMP_SPEC( \
+  MY_QUERYINTERFACE_ENTRY_UNKNOWN(i1) \
+  MY_QUERYINTERFACE_ENTRY(i1) \
+  MY_QUERYINTERFACE_ENTRY(i2) \
+  MY_QUERYINTERFACE_ENTRY(i3) \
+  MY_QUERYINTERFACE_ENTRY(i4) \
+  MY_QUERYINTERFACE_ENTRY(i5) \
+  )
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/misc/libphysfs/lzma/CPP/Common/MyException.h	Mon Apr 10 12:06:43 2017 -0400
@@ -0,0 +1,14 @@
+// Common/Exception.h
+
+#ifndef __COMMON_EXCEPTION_H
+#define __COMMON_EXCEPTION_H
+
+#include "MyWindows.h"
+
+struct CSystemException
+{
+  HRESULT ErrorCode;
+  CSystemException(HRESULT errorCode): ErrorCode(errorCode) {}
+};
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/misc/libphysfs/lzma/CPP/Common/MyGuidDef.h	Mon Apr 10 12:06:43 2017 -0400
@@ -0,0 +1,54 @@
+// Common/MyGuidDef.h
+
+#ifndef GUID_DEFINED
+#define GUID_DEFINED
+
+#include "Types.h"
+
+typedef struct {
+  UInt32 Data1;
+  UInt16 Data2;
+  UInt16 Data3;
+  unsigned char Data4[8];
+} GUID;
+
+#ifdef __cplusplus
+#define REFGUID const GUID &
+#else
+#define REFGUID const GUID *
+#endif
+
+#define REFCLSID REFGUID
+#define REFIID REFGUID
+
+#ifdef __cplusplus
+inline int operator==(REFGUID g1, REFGUID g2)
+{ 
+  for (int i = 0; i < (int)sizeof(g1); i++)
+    if (((unsigned char *)&g1)[i] != ((unsigned char *)&g2)[i])
+      return 0;
+  return 1;
+}
+inline int operator!=(REFGUID g1, REFGUID g2) { return !(g1 == g2); }
+#endif
+
+#ifdef __cplusplus
+  #define MY_EXTERN_C extern "C"
+#else
+  #define MY_EXTERN_C extern
+#endif
+
+#endif // GUID_DEFINED
+
+
+#ifdef DEFINE_GUID
+#undef DEFINE_GUID
+#endif
+
+#ifdef INITGUID
+  #define DEFINE_GUID(name, l, w1, w2, b1, b2, b3, b4, b5, b6, b7, b8) \
+    MY_EXTERN_C const GUID name = { l, w1, w2, { b1, b2,  b3,  b4,  b5,  b6,  b7,  b8 } }
+#else
+  #define DEFINE_GUID(name, l, w1, w2, b1, b2, b3, b4, b5, b6, b7, b8) \
+    MY_EXTERN_C const GUID name
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/misc/libphysfs/lzma/CPP/Common/MyInitGuid.h	Mon Apr 10 12:06:43 2017 -0400
@@ -0,0 +1,15 @@
+// Common/MyInitGuid.h
+
+#ifndef __COMMON_MYINITGUID_H
+#define __COMMON_MYINITGUID_H
+
+#ifdef _WIN32
+#include <initguid.h>
+#else
+#define INITGUID
+#include "MyGuidDef.h"
+DEFINE_GUID(IID_IUnknown,
+0x00000000, 0x0000, 0x0000, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46);
+#endif
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/misc/libphysfs/lzma/CPP/Common/MyString.cpp	Mon Apr 10 12:06:43 2017 -0400
@@ -0,0 +1,198 @@
+// Common/MyString.cpp
+
+#include "StdAfx.h"
+
+#ifdef _WIN32
+#include "StringConvert.h"
+#else
+#include <ctype.h>
+#endif
+
+#include "MyString.h"
+
+
+#ifdef _WIN32
+
+#ifndef _UNICODE
+
+wchar_t MyCharUpper(wchar_t c)
+{
+  if (c == 0)
+    return 0;
+  wchar_t *res = CharUpperW((LPWSTR)(UINT_PTR)(unsigned int)c);
+  if (res != 0 || ::GetLastError() != ERROR_CALL_NOT_IMPLEMENTED)
+    return (wchar_t)(unsigned int)(UINT_PTR)res;
+  const int kBufferSize = 4;
+  char s[kBufferSize + 1];
+  int numChars = ::WideCharToMultiByte(CP_ACP, 0, &c, 1, s, kBufferSize, 0, 0);
+  if (numChars == 0 || numChars > kBufferSize)
+    return c;
+  s[numChars] = 0;
+  ::CharUpperA(s);
+  ::MultiByteToWideChar(CP_ACP, 0, s, numChars, &c, 1);
+  return c;
+}
+
+wchar_t MyCharLower(wchar_t c)
+{
+  if (c == 0)
+    return 0;
+  wchar_t *res = CharLowerW((LPWSTR)(UINT_PTR)(unsigned int)c);
+  if (res != 0 || ::GetLastError() != ERROR_CALL_NOT_IMPLEMENTED)
+    return (wchar_t)(unsigned int)(UINT_PTR)res;
+  const int kBufferSize = 4;
+  char s[kBufferSize + 1];
+  int numChars = ::WideCharToMultiByte(CP_ACP, 0, &c, 1, s, kBufferSize, 0, 0);
+  if (numChars == 0 || numChars > kBufferSize)
+    return c;
+  s[numChars] = 0;
+  ::CharLowerA(s);
+  ::MultiByteToWideChar(CP_ACP, 0, s, numChars, &c, 1);
+  return c;
+}
+
+wchar_t * MyStringUpper(wchar_t *s)
+{
+  if (s == 0)
+    return 0;
+  wchar_t *res = CharUpperW(s);
+  if (res != 0 || ::GetLastError() != ERROR_CALL_NOT_IMPLEMENTED)
+    return res;
+  AString a = UnicodeStringToMultiByte(s);
+  a.MakeUpper();
+  return MyStringCopy(s, (const wchar_t *)MultiByteToUnicodeString(a));
+}
+
+wchar_t * MyStringLower(wchar_t *s)
+{ 
+  if (s == 0)
+    return 0;
+  wchar_t *res = CharLowerW(s);
+  if (res != 0 || ::GetLastError() != ERROR_CALL_NOT_IMPLEMENTED)
+    return res;
+  AString a = UnicodeStringToMultiByte(s);
+  a.MakeLower();
+  return MyStringCopy(s, (const wchar_t *)MultiByteToUnicodeString(a));
+}
+
+#endif
+
+/*
+inline int ConvertCompareResult(int r) { return r - 2; }
+
+int MyStringCollate(const wchar_t *s1, const wchar_t *s2)
+{ 
+  int res = CompareStringW(
+        LOCALE_USER_DEFAULT, SORT_STRINGSORT, s1, -1, s2, -1); 
+  #ifdef _UNICODE
+  return ConvertCompareResult(res);
+  #else
+  if (res != 0 || ::GetLastError() != ERROR_CALL_NOT_IMPLEMENTED)
+    return ConvertCompareResult(res);
+  return MyStringCollate(UnicodeStringToMultiByte(s1), 
+        UnicodeStringToMultiByte(s2));
+  #endif
+}
+
+#ifndef _WIN32_WCE
+int MyStringCollate(const char *s1, const char *s2)
+{ 
+  return ConvertCompareResult(CompareStringA(
+    LOCALE_USER_DEFAULT, SORT_STRINGSORT, s1, -1, s2, -1)); 
+}
+
+int MyStringCollateNoCase(const char *s1, const char *s2)
+{ 
+  return ConvertCompareResult(CompareStringA(
+    LOCALE_USER_DEFAULT, NORM_IGNORECASE | SORT_STRINGSORT, s1, -1, s2, -1)); 
+}
+#endif
+
+int MyStringCollateNoCase(const wchar_t *s1, const wchar_t *s2)
+{ 
+  int res = CompareStringW(
+        LOCALE_USER_DEFAULT, NORM_IGNORECASE | SORT_STRINGSORT, s1, -1, s2, -1); 
+  #ifdef _UNICODE
+  return ConvertCompareResult(res);
+  #else
+  if (res != 0 || ::GetLastError() != ERROR_CALL_NOT_IMPLEMENTED)
+    return ConvertCompareResult(res);
+  return MyStringCollateNoCase(UnicodeStringToMultiByte(s1), 
+      UnicodeStringToMultiByte(s2));
+  #endif
+}
+*/
+
+#else
+
+wchar_t MyCharUpper(wchar_t c)
+{
+  return toupper(c);
+}
+
+/*
+int MyStringCollateNoCase(const wchar_t *s1, const wchar_t *s2)
+{ 
+  for (;;)
+  {
+    wchar_t c1 = *s1++;
+    wchar_t c2 = *s2++;
+    wchar_t u1 = MyCharUpper(c1);
+    wchar_t u2 = MyCharUpper(c2);
+
+    if (u1 < u2) return -1;
+    if (u1 > u2) return 1;
+    if (u1 == 0) return 0;
+  }
+}
+*/
+
+#endif
+
+int MyStringCompare(const char *s1, const char *s2)
+{ 
+  for (;;)
+  {
+    unsigned char c1 = (unsigned char)*s1++;
+    unsigned char c2 = (unsigned char)*s2++;
+    if (c1 < c2) return -1;
+    if (c1 > c2) return 1;
+    if (c1 == 0) return 0;
+  }
+}
+
+int MyStringCompare(const wchar_t *s1, const wchar_t *s2)
+{ 
+  for (;;)
+  {
+    wchar_t c1 = *s1++;
+    wchar_t c2 = *s2++;
+    if (c1 < c2) return -1;
+    if (c1 > c2) return 1;
+    if (c1 == 0) return 0;
+  }
+}
+
+int MyStringCompareNoCase(const wchar_t *s1, const wchar_t *s2)
+{ 
+  for (;;)
+  {
+    wchar_t c1 = *s1++;
+    wchar_t c2 = *s2++;
+    if (c1 != c2)
+    {
+      wchar_t u1 = MyCharUpper(c1);
+      wchar_t u2 = MyCharUpper(c2);
+      if (u1 < u2) return -1;
+      if (u1 > u2) return 1;
+    }
+    if (c1 == 0) return 0;
+  }
+}
+
+#ifdef _WIN32
+int MyStringCompareNoCase(const char *s1, const char *s2)
+{ 
+  return MyStringCompareNoCase(MultiByteToUnicodeString(s1), MultiByteToUnicodeString(s2));
+}
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/misc/libphysfs/lzma/CPP/Common/MyString.h	Mon Apr 10 12:06:43 2017 -0400
@@ -0,0 +1,636 @@
+// Common/String.h
+
+#ifndef __COMMON_STRING_H
+#define __COMMON_STRING_H
+
+#include <string.h>
+// #include <wchar.h>
+
+#include "MyVector.h"
+
+#ifdef _WIN32
+#include "MyWindows.h"
+#endif
+
+template <class T>
+inline int MyStringLen(const T *s)
+{ 
+  int i;
+  for (i = 0; s[i] != '\0'; i++);
+  return i;
+}
+
+template <class T>
+inline T * MyStringCopy(T *dest, const T *src)
+{ 
+  T *destStart = dest;
+  while((*dest++ = *src++) != 0);
+  return destStart;
+}
+
+inline wchar_t* MyStringGetNextCharPointer(wchar_t *p)
+  { return (p + 1); }
+inline const wchar_t* MyStringGetNextCharPointer(const wchar_t *p)
+  { return (p + 1); }
+inline wchar_t* MyStringGetPrevCharPointer(const wchar_t *, wchar_t *p)
+  { return (p - 1); }
+inline const wchar_t* MyStringGetPrevCharPointer(const wchar_t *, const wchar_t *p)
+  { return (p - 1); }
+
+#ifdef _WIN32
+
+inline char* MyStringGetNextCharPointer(char *p)
+  { return CharNextA(p); }
+inline const char* MyStringGetNextCharPointer(const char *p)
+  { return CharNextA(p); }
+
+inline char* MyStringGetPrevCharPointer(char *base, char *p)
+  { return CharPrevA(base, p); }
+inline const char* MyStringGetPrevCharPointer(const char *base, const char *p)
+  { return CharPrevA(base, p); }
+
+inline char MyCharUpper(char c)
+  { return (char)(unsigned int)(UINT_PTR)CharUpperA((LPSTR)(UINT_PTR)(unsigned int)(unsigned char)c); }
+#ifdef _UNICODE
+inline wchar_t MyCharUpper(wchar_t c)
+  { return (wchar_t)(unsigned int)(UINT_PTR)CharUpperW((LPWSTR)(UINT_PTR)(unsigned int)c); }
+#else
+wchar_t MyCharUpper(wchar_t c);
+#endif
+
+inline char MyCharLower(char c)
+  { return (char)(unsigned int)(UINT_PTR)CharLowerA((LPSTR)(UINT_PTR)(unsigned int)(unsigned char)c); }
+#ifdef _UNICODE
+inline wchar_t MyCharLower(wchar_t c)
+  { return (wchar_t)(unsigned int)(UINT_PTR)CharLowerW((LPWSTR)(UINT_PTR)(unsigned int)c); }
+#else
+wchar_t MyCharLower(wchar_t c);
+#endif
+
+inline char * MyStringUpper(char *s) { return CharUpperA(s); }
+#ifdef _UNICODE
+inline wchar_t * MyStringUpper(wchar_t *s) { return CharUpperW(s); }
+#else
+wchar_t * MyStringUpper(wchar_t *s);
+#endif
+
+inline char * MyStringLower(char *s) { return CharLowerA(s); }
+#ifdef _UNICODE
+inline wchar_t * MyStringLower(wchar_t *s) { return CharLowerW(s); }
+#else
+wchar_t * MyStringLower(wchar_t *s);
+#endif
+
+#else // Standard-C
+wchar_t MyCharUpper(wchar_t c);
+#endif
+
+//////////////////////////////////////
+// Compare
+
+/*
+#ifndef _WIN32_WCE
+int MyStringCollate(const char *s1, const char *s2);
+int MyStringCollateNoCase(const char *s1, const char *s2);
+#endif
+int MyStringCollate(const wchar_t *s1, const wchar_t *s2);
+int MyStringCollateNoCase(const wchar_t *s1, const wchar_t *s2);
+*/
+
+int MyStringCompare(const char *s1, const char  *s2);
+int MyStringCompare(const wchar_t *s1, const wchar_t *s2);
+
+#ifdef _WIN32
+int MyStringCompareNoCase(const char *s1, const char  *s2);
+#endif
+
+int MyStringCompareNoCase(const wchar_t *s1, const wchar_t *s2);
+
+template <class T>
+class CStringBase
+{
+  void TrimLeftWithCharSet(const CStringBase &charSet)
+  {
+    const T *p = _chars;
+    while (charSet.Find(*p) >= 0 && (*p != 0))
+      p = GetNextCharPointer(p);
+    Delete(0, (int)(p - _chars));
+  }
+  void TrimRightWithCharSet(const CStringBase &charSet)
+  {
+    const T *p = _chars;
+    const T *pLast = NULL;
+    while (*p != 0)
+    {
+      if (charSet.Find(*p) >= 0)
+      {
+        if (pLast == NULL)
+          pLast = p;
+      }
+      else
+        pLast = NULL;
+      p = GetNextCharPointer(p);
+    }
+    if(pLast != NULL)
+    {
+      int i = (int)(pLast - _chars);
+      Delete(i, _length - i);
+    }
+
+  }
+  void MoveItems(int destIndex, int srcIndex)
+  {
+    memmove(_chars + destIndex, _chars + srcIndex, 
+        sizeof(T) * (_length - srcIndex + 1));
+  }
+  
+  void InsertSpace(int &index, int size)
+  {
+    CorrectIndex(index);
+    GrowLength(size);
+    MoveItems(index + size, index);
+  }
+
+  static T *GetNextCharPointer(T *p)
+    { return MyStringGetNextCharPointer(p); }
+  static const T *GetNextCharPointer(const T *p)
+    { return MyStringGetNextCharPointer(p); }
+  static T *GetPrevCharPointer(T *base, T *p)
+    { return MyStringGetPrevCharPointer(base, p); }
+  static const T *GetPrevCharPointer(const T *base, const T *p)
+    { return MyStringGetPrevCharPointer(base, p); }
+protected:
+  T *_chars;
+  int _length;
+  int _capacity;
+  
+  void SetCapacity(int newCapacity)
+  {
+    int realCapacity = newCapacity + 1;
+    if(realCapacity == _capacity)
+      return;
+    /*
+    const int kMaxStringSize = 0x20000000;
+    #ifndef _WIN32_WCE
+    if(newCapacity > kMaxStringSize || newCapacity < _length)
+      throw 1052337;
+    #endif
+    */
+    T *newBuffer = new T[realCapacity];
+    if(_capacity > 0)
+    {
+      for (int i = 0; i < (_length + 1); i++)
+        newBuffer[i] = _chars[i];
+      delete []_chars;
+      _chars = newBuffer;
+    }
+    else
+    {
+      _chars = newBuffer;
+      _chars[0] = 0;
+    }
+    _capacity = realCapacity;
+  }
+
+  void GrowLength(int n)
+  {
+    int freeSize = _capacity - _length - 1;
+    if (n <= freeSize) 
+      return;
+    int delta;
+    if (_capacity > 64)
+      delta = _capacity / 2;
+    else if (_capacity > 8)
+      delta = 16;
+    else
+      delta = 4;
+    if (freeSize + delta < n)
+      delta = n - freeSize;
+    SetCapacity(_capacity + delta);
+  }
+
+  void CorrectIndex(int &index) const
+  {
+    if (index > _length)
+      index = _length;
+  }
+
+public:
+  CStringBase(): _chars(0), _length(0), _capacity(0)
+    { SetCapacity(16 - 1); }
+  CStringBase(T c):  _chars(0), _length(0), _capacity(0)
+  {
+    SetCapacity(1);
+    _chars[0] = c;
+    _chars[1] = 0;
+    _length = 1;
+  }
+  CStringBase(const T *chars): _chars(0), _length(0), _capacity(0)
+  {
+    int length = MyStringLen(chars);
+    SetCapacity(length);
+    MyStringCopy(_chars, chars); // can be optimized by memove()
+    _length = length;
+  }
+  CStringBase(const CStringBase &s):  _chars(0), _length(0), _capacity(0)
+  {
+    SetCapacity(s._length);
+    MyStringCopy(_chars, s._chars);
+    _length = s._length;
+  }
+  ~CStringBase() {  delete []_chars; }
+
+  operator const T*() const { return _chars;} 
+
+  // The minimum size of the character buffer in characters. 
+  // This value does not include space for a null terminator.
+  T* GetBuffer(int minBufLength)
+  {
+    if(minBufLength >= _capacity)
+      SetCapacity(minBufLength + 1);
+    return _chars;
+  }
+  void ReleaseBuffer() { ReleaseBuffer(MyStringLen(_chars)); }
+  void ReleaseBuffer(int newLength)
+  {
+    /*
+    #ifndef _WIN32_WCE
+    if(newLength >= _capacity)
+      throw 282217;
+    #endif
+    */
+    _chars[newLength] = 0;
+    _length = newLength;
+  }
+
+  CStringBase& operator=(T c)
+  {
+    Empty();
+    SetCapacity(1);
+    _chars[0] = c;
+    _chars[1] = 0;
+    _length = 1;
+    return *this;
+  }
+  CStringBase& operator=(const T *chars)
+  {
+    Empty();
+    int length = MyStringLen(chars);
+    SetCapacity(length);
+    MyStringCopy(_chars, chars);
+    _length = length; 
+    return *this;
+  }  
+  CStringBase& operator=(const CStringBase& s)
+  {
+    if(&s == this)
+      return *this;
+    Empty();
+    SetCapacity(s._length);
+    MyStringCopy(_chars, s._chars);
+    _length = s._length;
+    return *this;
+  }
+  
+  CStringBase& operator+=(T c)
+  {
+    GrowLength(1);
+    _chars[_length] = c;
+    _chars[++_length] = 0;
+    return *this;
+  }
+  CStringBase& operator+=(const T *s)
+  {
+    int len = MyStringLen(s);
+    GrowLength(len);
+    MyStringCopy(_chars + _length, s);
+    _length += len;
+    return *this;
+  }
+  CStringBase& operator+=(const CStringBase &s)
+  {
+    GrowLength(s._length);
+    MyStringCopy(_chars + _length, s._chars);
+    _length += s._length;
+    return *this;
+  }
+  void Empty()
+  {
+    _length = 0;
+    _chars[0] = 0;
+  }
+  int Length() const { return _length; }
+  bool IsEmpty() const { return (_length == 0); }
+
+  CStringBase Mid(int startIndex) const
+    { return Mid(startIndex, _length - startIndex); }
+  CStringBase Mid(int startIndex, int count ) const
+  {
+    if (startIndex + count > _length)
+      count = _length - startIndex;
+    
+    if (startIndex == 0 && startIndex + count == _length)
+      return *this;
+    
+    CStringBase<T> result;
+    result.SetCapacity(count);
+    // MyStringNCopy(result._chars, _chars + startIndex, count);
+    for (int i = 0; i < count; i++)
+      result._chars[i] = _chars[startIndex + i];
+    result._chars[count] = 0;
+    result._length = count;
+    return result;
+  }
+  CStringBase Left(int count) const
+    { return Mid(0, count); }
+  CStringBase Right(int count) const
+  {
+    if (count > _length)
+      count = _length;
+    return Mid(_length - count, count);
+  }
+
+  void MakeUpper()
+    { MyStringUpper(_chars); }
+  void MakeLower()
+    { MyStringLower(_chars); }
+
+  int Compare(const CStringBase& s) const
+    { return MyStringCompare(_chars, s._chars); }
+
+  int Compare(const T *s) const
+    { return MyStringCompare(_chars, s); }
+
+  int CompareNoCase(const CStringBase& s) const
+    { return MyStringCompareNoCase(_chars, s._chars); }
+
+  int CompareNoCase(const T *s) const
+    { return MyStringCompareNoCase(_chars, s); }
+
+  /*
+  int Collate(const CStringBase& s) const
+    { return MyStringCollate(_chars, s._chars); }
+  int CollateNoCase(const CStringBase& s) const
+    { return MyStringCollateNoCase(_chars, s._chars); }
+  */
+
+  int Find(T c) const { return Find(c, 0); }
+  int Find(T c, int startIndex) const
+  {
+    T *p = _chars + startIndex;
+    for (;;)
+    {
+      if (*p == c)
+        return (int)(p - _chars);
+      if (*p == 0)
+        return -1;
+      p = GetNextCharPointer(p);
+    }
+  }
+  int Find(const CStringBase &s) const { return Find(s, 0); }
+  int Find(const CStringBase &s, int startIndex) const
+  {
+    if (s.IsEmpty())
+      return startIndex;
+    for (; startIndex < _length; startIndex++)
+    {
+      int j;
+      for (j = 0; j < s._length && startIndex + j < _length; j++)
+        if (_chars[startIndex+j] != s._chars[j])
+          break;
+      if (j == s._length)
+        return startIndex;
+    }
+    return -1;
+  }
+  int ReverseFind(T c) const
+  {
+    if (_length == 0)
+      return -1;
+    T *p = _chars + _length - 1;
+    for (;;)
+    {
+      if (*p == c)
+        return (int)(p - _chars);
+      if (p == _chars)
+        return -1;
+      p = GetPrevCharPointer(_chars, p);
+    }
+  }
+  int FindOneOf(const CStringBase &s) const
+  {
+    for(int i = 0; i < _length; i++)
+      if (s.Find(_chars[i]) >= 0)
+        return i;
+      return -1;
+  }
+
+  void TrimLeft(T c)
+  {
+    const T *p = _chars;
+    while (c == *p)
+      p = GetNextCharPointer(p);
+    Delete(0, p - _chars);
+  }
+  private:
+  CStringBase GetTrimDefaultCharSet()
+  {
+    CStringBase<T> charSet;
+    charSet += (T)' ';
+    charSet += (T)'\n';
+    charSet += (T)'\t';
+    return charSet;
+  }
+  public:
+
+  void TrimLeft()
+  {
+    TrimLeftWithCharSet(GetTrimDefaultCharSet());
+  }
+  void TrimRight()
+  {
+    TrimRightWithCharSet(GetTrimDefaultCharSet());
+  }
+  void TrimRight(T c)
+  {
+    const T *p = _chars;
+    const T *pLast = NULL;
+    while (*p != 0)
+    {
+      if (*p == c)
+      {
+        if (pLast == NULL)
+          pLast = p;
+      }
+      else
+        pLast = NULL;
+      p = GetNextCharPointer(p);
+    }
+    if(pLast != NULL)
+    {
+      int i = pLast - _chars;
+      Delete(i, _length - i);
+    }
+  }
+  void Trim()
+  {
+    TrimRight();
+    TrimLeft();
+  }
+
+  int Insert(int index, T c)
+  {
+    InsertSpace(index, 1);
+    _chars[index] = c;
+    _length++;
+    return _length;
+  }
+  int Insert(int index, const CStringBase &s)
+  {
+    CorrectIndex(index);
+    if (s.IsEmpty())
+      return _length;
+    int numInsertChars = s.Length();
+    InsertSpace(index, numInsertChars);
+    for(int i = 0; i < numInsertChars; i++)
+      _chars[index + i] = s[i];
+    _length += numInsertChars;
+    return _length;
+  }
+
+  // !!!!!!!!!!!!!!! test it if newChar = '\0'
+  int Replace(T oldChar, T newChar)
+  {
+    if (oldChar == newChar)
+      return 0;
+    int number  = 0;
+    int pos  = 0;
+    while (pos < Length())
+    {
+      pos = Find(oldChar, pos);
+      if (pos < 0) 
+        break;
+      _chars[pos] = newChar;
+      pos++;
+      number++;
+    }
+    return number;
+  }
+  int Replace(const CStringBase &oldString, const CStringBase &newString)
+  {
+    if (oldString.IsEmpty())
+      return 0;
+    if (oldString == newString)
+      return 0;
+    int oldStringLength = oldString.Length();
+    int newStringLength = newString.Length();
+    int number  = 0;
+    int pos  = 0;
+    while (pos < _length)
+    {
+      pos = Find(oldString, pos);
+      if (pos < 0) 
+        break;
+      Delete(pos, oldStringLength);
+      Insert(pos, newString);
+      pos += newStringLength;
+      number++;
+    }
+    return number;
+  }
+  int Delete(int index, int count = 1 )
+  {
+    if (index + count > _length)
+      count = _length - index;
+    if (count > 0)
+    {
+      MoveItems(index, index + count);
+      _length -= count;
+    }
+    return _length;
+  }
+};
+
+template <class T>
+CStringBase<T> operator+(const CStringBase<T>& s1, const CStringBase<T>& s2)
+{
+  CStringBase<T> result(s1);
+  result += s2;
+  return result; 
+}
+
+template <class T>
+CStringBase<T> operator+(const CStringBase<T>& s, T c)
+{
+  CStringBase<T> result(s);
+  result += c;
+  return result; 
+}
+
+template <class T>
+CStringBase<T> operator+(T c, const CStringBase<T>& s)
+{
+  CStringBase<T> result(c);
+  result += s;
+  return result; 
+}
+
+template <class T>
+CStringBase<T> operator+(const CStringBase<T>& s, const T * chars)
+{
+  CStringBase<T> result(s);
+  result += chars;
+  return result; 
+}
+
+template <class T>
+CStringBase<T> operator+(const T * chars, const CStringBase<T>& s)
+{
+  CStringBase<T> result(chars);
+  result += s;
+  return result; 
+}
+
+template <class T>
+bool operator==(const CStringBase<T>& s1, const CStringBase<T>& s2)
+  { return (s1.Compare(s2) == 0); }
+
+template <class T>
+bool operator<(const CStringBase<T>& s1, const CStringBase<T>& s2)
+  { return (s1.Compare(s2) < 0); }
+
+template <class T>
+bool operator==(const T *s1, const CStringBase<T>& s2)
+  { return (s2.Compare(s1) == 0); }
+
+template <class T>
+bool operator==(const CStringBase<T>& s1, const T *s2)
+  { return (s1.Compare(s2) == 0); }
+
+template <class T>
+bool operator!=(const CStringBase<T>& s1, const CStringBase<T>& s2)
+  { return (s1.Compare(s2) != 0); }
+
+template <class T>
+bool operator!=(const T *s1, const CStringBase<T>& s2)
+  { return (s2.Compare(s1) != 0); }
+
+template <class T>
+bool operator!=(const CStringBase<T>& s1, const T *s2)
+  { return (s1.Compare(s2) != 0); }
+
+typedef CStringBase<char> AString;
+typedef CStringBase<wchar_t> UString;
+
+typedef CObjectVector<AString> AStringVector;
+typedef CObjectVector<UString> UStringVector;
+
+#ifdef _UNICODE
+  typedef UString CSysString;
+#else
+  typedef AString CSysString;
+#endif
+
+typedef CObjectVector<CSysString> CSysStringVector;
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/misc/libphysfs/lzma/CPP/Common/MyUnknown.h	Mon Apr 10 12:06:43 2017 -0400
@@ -0,0 +1,24 @@
+// MyUnknown.h
+
+#ifndef __MYUNKNOWN_H
+#define __MYUNKNOWN_H
+
+#ifdef _WIN32
+
+#ifdef _WIN32_WCE
+#if (_WIN32_WCE > 300)
+#include <basetyps.h>
+#else
+#define MIDL_INTERFACE(x) struct 
+#endif
+#else
+#include <basetyps.h>
+#endif
+
+#include <unknwn.h>
+
+#else 
+#include "MyWindows.h"
+#endif
+  
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/misc/libphysfs/lzma/CPP/Common/MyVector.cpp	Mon Apr 10 12:06:43 2017 -0400
@@ -0,0 +1,78 @@
+// Common/MyVector.cpp
+
+#include "StdAfx.h"
+
+#include <string.h>
+
+#include "MyVector.h"
+
+CBaseRecordVector::~CBaseRecordVector() { Free(); }
+
+void CBaseRecordVector::Free()
+{ 
+  delete []((unsigned char *)_items); 
+  _capacity = 0;
+  _size = 0;
+  _items = 0;
+}
+
+void CBaseRecordVector::Clear() { DeleteFrom(0); }
+void CBaseRecordVector::DeleteBack() { Delete(_size - 1); }
+void CBaseRecordVector::DeleteFrom(int index) { Delete(index, _size - index); }
+
+void CBaseRecordVector::ReserveOnePosition()
+{
+  if (_size != _capacity)
+    return;
+  int delta;
+  if (_capacity > 64)
+    delta = _capacity / 2;
+  else if (_capacity > 8)
+    delta = 8;
+  else
+    delta = 4;
+  Reserve(_capacity + delta);
+}
+
+void CBaseRecordVector::Reserve(int newCapacity)
+{
+  if (newCapacity <= _capacity)
+    return;
+  if ((unsigned)newCapacity >= ((unsigned)1 << (sizeof(unsigned) * 8 - 1)))
+    throw 1052353;
+  size_t newSize = (size_t)(unsigned)newCapacity * _itemSize;
+  if (newSize / _itemSize != (size_t)(unsigned)newCapacity)
+    throw 1052354;
+  unsigned char *p = new unsigned char[newSize];
+  if (p == 0)
+    throw 1052355;
+  int numRecordsToMove = _capacity;
+  memmove(p, _items, _itemSize * numRecordsToMove);
+  delete [](unsigned char *)_items;
+  _items = p;
+  _capacity = newCapacity;
+}
+
+void CBaseRecordVector::MoveItems(int destIndex, int srcIndex)
+{
+  memmove(((unsigned char *)_items) + destIndex * _itemSize, 
+    ((unsigned char  *)_items) + srcIndex * _itemSize, 
+    _itemSize * (_size - srcIndex));
+}
+
+void CBaseRecordVector::InsertOneItem(int index)
+{
+  ReserveOnePosition();
+  MoveItems(index + 1, index);
+  _size++;
+}
+
+void CBaseRecordVector::Delete(int index, int num)
+{
+  TestIndexAndCorrectNum(index, num);
+  if (num > 0)
+  {
+    MoveItems(index, index + num);
+    _size -= num;
+  }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/misc/libphysfs/lzma/CPP/Common/MyVector.h	Mon Apr 10 12:06:43 2017 -0400
@@ -0,0 +1,254 @@
+// Common/Vector.h
+
+#ifndef __COMMON_VECTOR_H
+#define __COMMON_VECTOR_H
+
+#include "Defs.h"
+
+class CBaseRecordVector
+{
+  void MoveItems(int destIndex, int srcIndex);
+protected:
+  int _capacity;
+  int _size;
+  void *_items;
+  size_t _itemSize;
+  
+  void ReserveOnePosition();
+  void InsertOneItem(int index);
+  void TestIndexAndCorrectNum(int index, int &num) const
+    { if (index + num > _size) num = _size - index; } 
+public:
+  CBaseRecordVector(size_t itemSize):
+      _capacity(0), _size(0), _items(0), _itemSize(itemSize) {}
+  virtual ~CBaseRecordVector();
+  void Free();
+  int Size() const { return _size; }
+  bool IsEmpty() const { return (_size == 0); }
+  void Reserve(int newCapacity);
+  virtual void Delete(int index, int num = 1);
+  void Clear();
+  void DeleteFrom(int index);
+  void DeleteBack();
+};
+
+template <class T>
+class CRecordVector: public CBaseRecordVector
+{
+public:
+  CRecordVector():CBaseRecordVector(sizeof(T)){};
+  CRecordVector(const CRecordVector &v):
+    CBaseRecordVector(sizeof(T)) { *this = v;}
+  CRecordVector& operator=(const CRecordVector &v)
+  {
+    Clear();
+    return (*this += v);
+  }
+  CRecordVector& operator+=(const CRecordVector &v)
+  {
+    int size = v.Size();
+    Reserve(Size() + size);
+    for(int i = 0; i < size; i++)
+      Add(v[i]);
+    return *this;
+  }
+  int Add(T item)
+  {
+    ReserveOnePosition();
+    ((T *)_items)[_size] = item;
+    return _size++;
+  }
+  void Insert(int index, T item)
+  {
+    InsertOneItem(index);
+    ((T *)_items)[index] = item;
+  }
+  // T* GetPointer() const { return (T*)_items; }
+  // operator const T *() const { return _items; };
+  const T& operator[](int index) const { return ((T *)_items)[index]; }
+  T& operator[](int index) { return ((T *)_items)[index]; }
+  const T& Front() const { return operator[](0); }
+  T& Front()   { return operator[](0); }
+  const T& Back() const { return operator[](_size - 1); }
+  T& Back()   { return operator[](_size - 1); }
+
+  void Swap(int i, int j)
+  {
+    T temp = operator[](i);
+    operator[](i) = operator[](j);
+    operator[](j) = temp;
+  }
+
+  int FindInSorted(const T& item) const
+  {
+    int left = 0, right = Size(); 
+    while (left != right)
+    {
+      int mid = (left + right) / 2;
+      const T& midValue = (*this)[mid];
+      if (item == midValue)
+        return mid;
+      if (item < midValue)
+        right = mid;
+      else
+        left = mid + 1;
+    }
+    return -1;
+  }
+
+  int AddToUniqueSorted(const T& item)
+  {
+    int left = 0, right = Size(); 
+    while (left != right)
+    {
+      int mid = (left + right) / 2;
+      const T& midValue = (*this)[mid];
+      if (item == midValue)
+        return mid;
+      if (item < midValue)
+        right = mid;
+      else
+        left = mid + 1;
+    }
+    Insert(right, item);
+    return right;
+  }
+
+  static void SortRefDown(T* p, int k, int size, int (*compare)(const T*, const T*, void *), void *param)
+  { 
+    T temp = p[k];
+    for (;;)
+    {
+      int s = (k << 1);
+      if (s > size)
+        break;
+      if (s < size && compare(p + s + 1, p + s, param) > 0)
+        s++;
+      if (compare(&temp, p + s, param) >= 0)
+        break;
+      p[k] = p[s]; 
+      k = s;
+    } 
+    p[k] = temp; 
+  }
+
+  void Sort(int (*compare)(const T*, const T*, void *), void *param)
+  {
+    int size = _size;
+    if (size <= 1)
+      return;
+    T* p = (&Front()) - 1;
+    {
+      int i = size / 2;
+      do
+        SortRefDown(p, i, size, compare, param);
+      while(--i != 0);
+    }
+    do
+    {
+      T temp = p[size];
+      p[size--] = p[1];
+      p[1] = temp;
+      SortRefDown(p, 1, size, compare, param);
+    }
+    while (size > 1);
+  }
+};
+
+typedef CRecordVector<int> CIntVector;
+typedef CRecordVector<unsigned int> CUIntVector;
+typedef CRecordVector<bool> CBoolVector;
+typedef CRecordVector<unsigned char> CByteVector;
+typedef CRecordVector<void *> CPointerVector;
+
+template <class T>
+class CObjectVector: public CPointerVector
+{
+public:
+  CObjectVector(){};
+  ~CObjectVector() { Clear(); }
+  CObjectVector(const CObjectVector &objectVector)
+    { *this = objectVector; }
+  CObjectVector& operator=(const CObjectVector &objectVector)
+  {
+    Clear();
+    return (*this += objectVector);
+  }
+  CObjectVector& operator+=(const CObjectVector &objectVector)
+  {
+    int size = objectVector.Size();
+    Reserve(Size() + size);
+    for(int i = 0; i < size; i++)
+      Add(objectVector[i]);
+    return *this;
+  }
+  const T& operator[](int index) const { return *((T *)CPointerVector::operator[](index)); }
+  T& operator[](int index) { return *((T *)CPointerVector::operator[](index)); }
+  T& Front() { return operator[](0); }
+  const T& Front() const { return operator[](0); }
+  T& Back() { return operator[](_size - 1); }
+  const T& Back() const { return operator[](_size - 1); }
+  int Add(const T& item)
+    { return CPointerVector::Add(new T(item)); }
+  void Insert(int index, const T& item)
+    { CPointerVector::Insert(index, new T(item)); }
+  virtual void Delete(int index, int num = 1)
+  {
+    TestIndexAndCorrectNum(index, num);
+    for(int i = 0; i < num; i++)
+      delete (T *)(((void **)_items)[index + i]);
+    CPointerVector::Delete(index, num);
+  }
+  int Find(const T& item) const
+  {
+    for(int i = 0; i < Size(); i++)
+      if (item == (*this)[i])
+        return i;
+      return -1;
+  }
+  int FindInSorted(const T& item) const
+  {
+    int left = 0, right = Size(); 
+    while (left != right)
+    {
+      int mid = (left + right) / 2;
+      const T& midValue = (*this)[mid];
+      if (item == midValue)
+        return mid;
+      if (item < midValue)
+        right = mid;
+      else
+        left = mid + 1;
+    }
+    return -1;
+  }
+  int AddToSorted(const T& item)
+  {
+    int left = 0, right = Size(); 
+    while (left != right)
+    {
+      int mid = (left + right) / 2;
+      const T& midValue = (*this)[mid];
+      if (item == midValue)
+      {
+        right = mid + 1;
+        break;
+      }
+      if (item < midValue)
+        right = mid;
+      else
+        left = mid + 1;
+    }
+    Insert(right, item);
+    return right;
+  }
+
+  void Sort(int (*compare)(void *const *, void *const *, void *), void *param) 
+    { CPointerVector::Sort(compare, param); }
+
+  static int CompareObjectItems(void *const *a1, void *const *a2, void * /* param */)
+    { return MyCompare(*(*((const T **)a1)), *(*((const T **)a2))); }
+  void Sort() { CPointerVector::Sort(CompareObjectItems, 0); }
+};
+
+#endif 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/misc/libphysfs/lzma/CPP/Common/MyWindows.h	Mon Apr 10 12:06:43 2017 -0400
@@ -0,0 +1,214 @@
+// MyWindows.h
+
+#ifndef __MYWINDOWS_H
+#define __MYWINDOWS_H
+
+#ifdef _WIN32
+
+#include <windows.h>
+
+#define CHAR_PATH_SEPARATOR '\\'
+#define WCHAR_PATH_SEPARATOR L'\\'
+#define STRING_PATH_SEPARATOR "\\"
+#define WSTRING_PATH_SEPARATOR L"\\"
+
+#else
+
+#define CHAR_PATH_SEPARATOR '/'
+#define WCHAR_PATH_SEPARATOR L'/'
+#define STRING_PATH_SEPARATOR "/"
+#define WSTRING_PATH_SEPARATOR L"/"
+
+#include <stddef.h> // for wchar_t
+#include <string.h>
+
+#include "MyGuidDef.h"
+
+typedef char CHAR;
+typedef unsigned char UCHAR;
+
+#undef BYTE
+typedef unsigned char BYTE;
+
+typedef short SHORT;
+typedef unsigned short USHORT;
+
+#undef WORD
+typedef unsigned short WORD;
+typedef short VARIANT_BOOL;
+
+typedef int INT;
+typedef Int32 INT32;
+typedef unsigned int UINT;
+typedef UInt32 UINT32;
+typedef INT32 LONG;   // LONG, ULONG and DWORD must be 32-bit
+typedef UINT32 ULONG;
+
+#undef DWORD
+typedef UINT32 DWORD;
+
+typedef Int64 LONGLONG;
+typedef UInt64 ULONGLONG;
+
+typedef struct LARGE_INTEGER { LONGLONG QuadPart; }LARGE_INTEGER;
+typedef struct _ULARGE_INTEGER { ULONGLONG QuadPart;} ULARGE_INTEGER;
+
+typedef const CHAR *LPCSTR;
+typedef CHAR TCHAR;
+typedef const TCHAR *LPCTSTR;
+typedef wchar_t WCHAR;
+typedef WCHAR OLECHAR;
+typedef const WCHAR *LPCWSTR;
+typedef OLECHAR *BSTR;
+typedef const OLECHAR *LPCOLESTR;
+typedef OLECHAR *LPOLESTR;
+
+typedef struct _FILETIME
+{
+  DWORD dwLowDateTime;
+  DWORD dwHighDateTime;
+}FILETIME;
+
+#define HRESULT LONG
+#define FAILED(Status) ((HRESULT)(Status)<0)
+typedef ULONG PROPID;
+typedef LONG SCODE;
+
+#define S_OK    ((HRESULT)0x00000000L)
+#define S_FALSE ((HRESULT)0x00000001L)
+#define E_NOTIMPL ((HRESULT)0x80004001L)
+#define E_NOINTERFACE ((HRESULT)0x80004002L)
+#define E_ABORT ((HRESULT)0x80004004L)
+#define E_FAIL ((HRESULT)0x80004005L)
+#define STG_E_INVALIDFUNCTION ((HRESULT)0x80030001L)
+#define E_OUTOFMEMORY ((HRESULT)0x8007000EL)
+#define E_INVALIDARG ((HRESULT)0x80070057L)
+
+#ifdef _MSC_VER
+#define STDMETHODCALLTYPE __stdcall 
+#else
+#define STDMETHODCALLTYPE 
+#endif
+
+#define STDMETHOD_(t, f) virtual t STDMETHODCALLTYPE f
+#define STDMETHOD(f) STDMETHOD_(HRESULT, f)
+#define STDMETHODIMP_(type) type STDMETHODCALLTYPE
+#define STDMETHODIMP STDMETHODIMP_(HRESULT)
+
+#define PURE = 0
+
+#define MIDL_INTERFACE(x) struct 
+
+#ifdef __cplusplus
+
+DEFINE_GUID(IID_IUnknown,
+0x00000000, 0x0000, 0x0000, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46);
+struct IUnknown
+{
+  STDMETHOD(QueryInterface) (REFIID iid, void **outObject) PURE;
+  STDMETHOD_(ULONG, AddRef)() PURE;
+  STDMETHOD_(ULONG, Release)() PURE;
+  #ifndef _WIN32
+  virtual ~IUnknown() {}
+  #endif
+};
+
+typedef IUnknown *LPUNKNOWN;
+
+#endif
+
+#define VARIANT_TRUE ((VARIANT_BOOL)-1)
+#define VARIANT_FALSE ((VARIANT_BOOL)0)
+
+enum VARENUM
+{
+  VT_EMPTY = 0,
+  VT_NULL = 1,
+  VT_I2 = 2,
+  VT_I4 = 3,
+  VT_R4 = 4,
+  VT_R8 = 5,
+  VT_CY = 6,
+  VT_DATE = 7,
+  VT_BSTR = 8,
+  VT_DISPATCH = 9,
+  VT_ERROR = 10,
+  VT_BOOL = 11,
+  VT_VARIANT = 12,
+  VT_UNKNOWN = 13,
+  VT_DECIMAL = 14,
+  VT_I1 = 16,
+  VT_UI1 = 17,
+  VT_UI2 = 18,
+  VT_UI4 = 19,
+  VT_I8 = 20,
+  VT_UI8 = 21,
+  VT_INT = 22,
+  VT_UINT = 23,
+  VT_VOID = 24,
+  VT_HRESULT = 25,
+  VT_FILETIME = 64
+};
+
+typedef unsigned short VARTYPE;
+typedef WORD PROPVAR_PAD1;
+typedef WORD PROPVAR_PAD2;
+typedef WORD PROPVAR_PAD3;
+
+#ifdef __cplusplus
+
+typedef struct tagPROPVARIANT
+{
+  VARTYPE vt;
+  PROPVAR_PAD1 wReserved1;
+  PROPVAR_PAD2 wReserved2;
+  PROPVAR_PAD3 wReserved3;
+  union 
+  {
+    CHAR cVal;
+    UCHAR bVal;
+    SHORT iVal;
+    USHORT uiVal;
+    LONG lVal;
+    ULONG ulVal;
+    INT intVal;
+    UINT uintVal;
+    LARGE_INTEGER hVal;
+    ULARGE_INTEGER uhVal;
+    VARIANT_BOOL boolVal;
+    SCODE scode;
+    FILETIME filetime;
+    BSTR bstrVal;
+  };
+} PROPVARIANT;
+
+typedef PROPVARIANT tagVARIANT;
+typedef tagVARIANT VARIANT;
+typedef VARIANT VARIANTARG;
+
+MY_EXTERN_C HRESULT VariantClear(VARIANTARG *prop);
+MY_EXTERN_C HRESULT VariantCopy(VARIANTARG *dest, VARIANTARG *src);
+
+#endif
+
+MY_EXTERN_C BSTR SysAllocStringByteLen(LPCSTR psz, UINT len);
+MY_EXTERN_C BSTR SysAllocString(const OLECHAR *sz);
+MY_EXTERN_C void SysFreeString(BSTR bstr);
+MY_EXTERN_C UINT SysStringByteLen(BSTR bstr);
+MY_EXTERN_C UINT SysStringLen(BSTR bstr);
+
+MY_EXTERN_C DWORD GetLastError();
+MY_EXTERN_C LONG CompareFileTime(const FILETIME* ft1, const FILETIME* ft2);
+
+#define CP_ACP    0
+#define CP_OEMCP  1
+
+typedef enum tagSTREAM_SEEK
+{
+  STREAM_SEEK_SET = 0,
+  STREAM_SEEK_CUR = 1,
+  STREAM_SEEK_END = 2
+} STREAM_SEEK;
+
+#endif
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/misc/libphysfs/lzma/CPP/Common/NewHandler.cpp	Mon Apr 10 12:06:43 2017 -0400
@@ -0,0 +1,116 @@
+// NewHandler.cpp
+ 
+#include "StdAfx.h"
+
+#include <stdlib.h>
+
+#include "NewHandler.h"
+
+// #define DEBUG_MEMORY_LEAK
+
+#ifndef DEBUG_MEMORY_LEAK
+
+#ifdef _WIN32
+void * 
+#ifdef _MSC_VER
+__cdecl 
+#endif
+operator new(size_t size)
+{
+  // void *p = ::HeapAlloc(::GetProcessHeap(), 0, size);
+  void *p = ::malloc(size);
+  if (p == 0)
+    throw CNewException();
+  return p;
+}
+
+void 
+#ifdef _MSC_VER
+__cdecl 
+#endif
+operator delete(void *p) throw()
+{
+  /*
+  if (p == 0)
+    return;
+  ::HeapFree(::GetProcessHeap(), 0, p);
+  */
+  ::free(p);
+}
+#endif
+
+#else
+
+#pragma init_seg(lib)
+const int kDebugSize = 1000000;
+static void *a[kDebugSize];
+static int index = 0;
+
+static int numAllocs = 0;
+void * __cdecl operator new(size_t size)
+{
+  numAllocs++;
+  void *p = HeapAlloc(GetProcessHeap(), 0, size);
+  if (index == 40)
+  {
+    int t = 1;
+  }
+  if (index < kDebugSize)
+  {
+    a[index] = p;
+    index++;
+  }
+  if (p == 0)
+    throw CNewException();
+  printf("Alloc %6d, size = %8d\n", numAllocs, size);
+  return p;
+}
+
+class CC
+{
+public:
+  CC()
+  {
+    for (int i = 0; i < kDebugSize; i++)
+      a[i] = 0;
+  }
+  ~CC()
+  {
+    for (int i = 0; i < kDebugSize; i++)
+      if (a[i] != 0)
+        return;
+  }
+} g_CC;
+
+
+void __cdecl operator delete(void *p)
+{
+  if (p == 0)
+    return;
+  /*
+  for (int i = 0; i < index; i++)
+    if (a[i] == p)
+      a[i] = 0;
+  */
+  HeapFree(GetProcessHeap(), 0, p);
+  numAllocs--;
+  printf("Free %d\n", numAllocs);
+}
+
+#endif
+
+/*
+int MemErrorVC(size_t)
+{
+  throw CNewException();
+  // return 1;
+}
+CNewHandlerSetter::CNewHandlerSetter()
+{
+  // MemErrorOldVCFunction = _set_new_handler(MemErrorVC);
+}
+CNewHandlerSetter::~CNewHandlerSetter()
+{
+  // _set_new_handler(MemErrorOldVCFunction);
+}
+*/
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/misc/libphysfs/lzma/CPP/Common/NewHandler.h	Mon Apr 10 12:06:43 2017 -0400
@@ -0,0 +1,16 @@
+// Common/NewHandler.h
+
+#ifndef __COMMON_NEWHANDLER_H
+#define __COMMON_NEWHANDLER_H
+
+class CNewException {};
+
+#ifdef _WIN32
+void 
+#ifdef _MSC_VER
+__cdecl 
+#endif
+operator delete(void *p) throw();
+#endif 
+
+#endif 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/misc/libphysfs/lzma/CPP/Common/StdAfx.h	Mon Apr 10 12:06:43 2017 -0400
@@ -0,0 +1,9 @@
+// StdAfx.h
+
+#ifndef __STDAFX_H
+#define __STDAFX_H
+
+// #include "MyWindows.h"
+#include "NewHandler.h"
+
+#endif 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/misc/libphysfs/lzma/CPP/Common/StdInStream.cpp	Mon Apr 10 12:06:43 2017 -0400
@@ -0,0 +1,84 @@
+// Common/StdInStream.cpp
+
+#include "StdAfx.h"
+
+#include <tchar.h>
+#include "StdInStream.h"
+
+#ifdef _MSC_VER
+// "was declared deprecated" disabling
+#pragma warning(disable : 4996 )
+#endif
+
+static const char kIllegalChar = '\0';
+static const char kNewLineChar = '\n';
+
+static const char *kEOFMessage = "Unexpected end of input stream";
+static const char *kReadErrorMessage  ="Error reading input stream"; 
+static const char *kIllegalCharMessage = "Illegal character in input stream";
+
+static LPCTSTR kFileOpenMode = TEXT("r");
+
+CStdInStream g_StdIn(stdin);
+
+bool CStdInStream::Open(LPCTSTR fileName)
+{
+  Close();
+  _stream = _tfopen(fileName, kFileOpenMode);
+  _streamIsOpen = (_stream != 0);
+  return _streamIsOpen;
+}
+
+bool CStdInStream::Close()
+{
+  if(!_streamIsOpen)
+    return true;
+  _streamIsOpen = (fclose(_stream) != 0);
+  return !_streamIsOpen;
+}
+
+CStdInStream::~CStdInStream()
+{
+  Close();
+}
+
+AString CStdInStream::ScanStringUntilNewLine()
+{
+  AString s;
+  for (;;)
+  {
+    int intChar = GetChar();
+    if(intChar == EOF)
+      throw kEOFMessage;
+    char c = char(intChar);
+    if (c == kIllegalChar)
+      throw kIllegalCharMessage;
+    if(c == kNewLineChar)
+      break;
+    s += c;
+  }
+  return s;
+}
+
+void CStdInStream::ReadToString(AString &resultString)
+{
+  resultString.Empty();
+  int c;
+  while((c = GetChar()) != EOF)
+    resultString += char(c);
+}
+
+bool CStdInStream::Eof()
+{
+  return (feof(_stream) != 0);
+}
+
+int CStdInStream::GetChar()
+{
+  int c = fgetc(_stream); // getc() doesn't work in BeOS?
+  if(c == EOF && !Eof())
+    throw kReadErrorMessage;
+  return c;
+}
+
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/misc/libphysfs/lzma/CPP/Common/StdInStream.h	Mon Apr 10 12:06:43 2017 -0400
@@ -0,0 +1,31 @@
+// Common/StdInStream.h
+
+#ifndef __COMMON_STDINSTREAM_H
+#define __COMMON_STDINSTREAM_H
+
+#include <stdio.h>
+
+#include "MyString.h"
+#include "Types.h"
+
+class CStdInStream 
+{
+  bool _streamIsOpen;
+  FILE *_stream;
+public:
+  CStdInStream(): _streamIsOpen(false) {};
+  CStdInStream(FILE *stream): _streamIsOpen(false), _stream(stream) {};
+  ~CStdInStream();
+  bool Open(LPCTSTR fileName);
+  bool Close();
+
+  AString ScanStringUntilNewLine();
+  void ReadToString(AString &resultString);
+
+  bool Eof();
+  int GetChar();
+};
+
+extern CStdInStream g_StdIn;
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/misc/libphysfs/lzma/CPP/Common/StdOutStream.cpp	Mon Apr 10 12:06:43 2017 -0400
@@ -0,0 +1,93 @@
+// Common/StdOutStream.cpp
+
+#include "StdAfx.h"
+
+#include <tchar.h>
+
+#include "StdOutStream.h"
+#include "IntToString.h"
+#include "StringConvert.h"
+
+#ifdef _MSC_VER
+// "was declared deprecated" disabling
+#pragma warning(disable : 4996 )
+#endif
+
+static const char kNewLineChar =  '\n';
+
+static const char *kFileOpenMode = "wt";
+
+CStdOutStream  g_StdOut(stdout);
+CStdOutStream  g_StdErr(stderr);
+
+bool CStdOutStream::Open(const char *fileName)
+{
+  Close();
+  _stream = fopen(fileName, kFileOpenMode);
+  _streamIsOpen = (_stream != 0);
+  return _streamIsOpen;
+}
+
+bool CStdOutStream::Close()
+{
+  if(!_streamIsOpen)
+    return true;
+  if (fclose(_stream) != 0)
+    return false;
+  _stream = 0;
+  _streamIsOpen = false;
+  return true;
+}
+
+bool CStdOutStream::Flush()
+{
+  return (fflush(_stream) == 0);
+}
+
+CStdOutStream::~CStdOutStream ()
+{
+  Close();
+}
+
+CStdOutStream & CStdOutStream::operator<<(CStdOutStream & (*aFunction)(CStdOutStream  &))
+{
+  (*aFunction)(*this);    
+  return *this;
+}
+
+CStdOutStream & endl(CStdOutStream & outStream)
+{
+  return outStream << kNewLineChar;
+}
+
+CStdOutStream & CStdOutStream::operator<<(const char *string)
+{
+  fputs(string, _stream);
+  return *this;
+}
+
+CStdOutStream & CStdOutStream::operator<<(const wchar_t *string)
+{
+  *this << (const char *)UnicodeStringToMultiByte(string, CP_OEMCP);
+  return *this;
+}
+
+CStdOutStream & CStdOutStream::operator<<(char c)
+{
+  fputc(c, _stream);
+  return *this;
+}
+
+CStdOutStream & CStdOutStream::operator<<(int number)
+{
+  char textString[32];
+  ConvertInt64ToString(number, textString);
+  return operator<<(textString);
+}
+
+CStdOutStream & CStdOutStream::operator<<(UInt64 number)
+{
+  char textString[32];
+  ConvertUInt64ToString(number, textString);
+  return operator<<(textString);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/misc/libphysfs/lzma/CPP/Common/StdOutStream.h	Mon Apr 10 12:06:43 2017 -0400
@@ -0,0 +1,35 @@
+// Common/StdOutStream.h
+
+#ifndef __COMMON_STDOUTSTREAM_H
+#define __COMMON_STDOUTSTREAM_H
+
+#include <stdio.h>
+
+#include "Types.h"
+
+class CStdOutStream 
+{
+  bool _streamIsOpen;
+  FILE *_stream;
+public:
+  CStdOutStream (): _streamIsOpen(false), _stream(0) {};
+  CStdOutStream (FILE *stream): _streamIsOpen(false), _stream(stream) {};
+  ~CStdOutStream ();
+  operator FILE *() { return _stream; }
+  bool Open(const char *fileName);
+  bool Close();
+  bool Flush();
+  CStdOutStream & operator<<(CStdOutStream & (* aFunction)(CStdOutStream  &));
+  CStdOutStream & operator<<(const char *string);
+  CStdOutStream & operator<<(const wchar_t *string);
+  CStdOutStream & operator<<(char c);
+  CStdOutStream & operator<<(int number);
+  CStdOutStream & operator<<(UInt64 number);
+};
+
+CStdOutStream & endl(CStdOutStream & outStream);
+
+extern CStdOutStream g_StdOut;
+extern CStdOutStream g_StdErr;
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/misc/libphysfs/lzma/CPP/Common/StringConvert.cpp	Mon Apr 10 12:06:43 2017 -0400
@@ -0,0 +1,94 @@
+// Common/StringConvert.cpp
+
+#include "StdAfx.h"
+
+#include "StringConvert.h"
+
+#ifndef _WIN32
+#include <stdlib.h>
+#endif
+
+#ifdef _WIN32
+UString MultiByteToUnicodeString(const AString &srcString, UINT codePage)
+{
+  UString resultString;
+  if(!srcString.IsEmpty())
+  {
+    int numChars = MultiByteToWideChar(codePage, 0, srcString, 
+      srcString.Length(), resultString.GetBuffer(srcString.Length()), 
+      srcString.Length() + 1);
+    #ifndef _WIN32_WCE
+    if(numChars == 0)
+      throw 282228;
+    #endif
+    resultString.ReleaseBuffer(numChars);
+  }
+  return resultString;
+}
+
+AString UnicodeStringToMultiByte(const UString &srcString, UINT codePage)
+{
+  AString resultString;
+  if(!srcString.IsEmpty())
+  {
+    int numRequiredBytes = srcString.Length() * 2;
+    char defaultChar = '_';
+    int numChars = WideCharToMultiByte(codePage, 0, srcString, 
+      srcString.Length(), resultString.GetBuffer(numRequiredBytes), 
+      numRequiredBytes + 1, &defaultChar, NULL);
+    #ifndef _WIN32_WCE
+    if(numChars == 0)
+      throw 282229;
+    #endif
+    resultString.ReleaseBuffer(numChars);
+  }
+  return resultString;
+}
+
+#ifndef _WIN32_WCE
+AString SystemStringToOemString(const CSysString &srcString)
+{
+  AString result;
+  CharToOem(srcString, result.GetBuffer(srcString.Length() * 2));
+  result.ReleaseBuffer();
+  return result;
+}
+#endif
+
+#else
+
+UString MultiByteToUnicodeString(const AString &srcString, UINT codePage)
+{
+  UString resultString;
+  for (int i = 0; i < srcString.Length(); i++)
+    resultString += wchar_t(srcString[i]);
+  /*
+  if(!srcString.IsEmpty())
+  {
+    int numChars = mbstowcs(resultString.GetBuffer(srcString.Length()), srcString, srcString.Length() + 1);
+    if (numChars < 0) throw "Your environment does not support UNICODE";
+    resultString.ReleaseBuffer(numChars);
+  }
+  */
+  return resultString;
+}
+
+AString UnicodeStringToMultiByte(const UString &srcString, UINT codePage)
+{
+  AString resultString;
+  for (int i = 0; i < srcString.Length(); i++)
+    resultString += char(srcString[i]);
+  /*
+  if(!srcString.IsEmpty())
+  {
+    int numRequiredBytes = srcString.Length() * 6 + 1;
+    int numChars = wcstombs(resultString.GetBuffer(numRequiredBytes), srcString, numRequiredBytes);
+    if (numChars < 0) throw "Your environment does not support UNICODE";
+    resultString.ReleaseBuffer(numChars);
+  }
+  */
+  return resultString;
+}
+
+#endif
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/misc/libphysfs/lzma/CPP/Common/StringConvert.h	Mon Apr 10 12:06:43 2017 -0400
@@ -0,0 +1,71 @@
+// Common/StringConvert.h
+
+#ifndef __COMMON_STRINGCONVERT_H
+#define __COMMON_STRINGCONVERT_H
+
+#include "MyWindows.h"
+#include "MyString.h"
+#include "Types.h"
+
+UString MultiByteToUnicodeString(const AString &srcString, UINT codePage = CP_ACP);
+AString UnicodeStringToMultiByte(const UString &srcString, UINT codePage = CP_ACP);
+
+inline const wchar_t* GetUnicodeString(const wchar_t* unicodeString)
+  { return unicodeString; }
+inline const UString& GetUnicodeString(const UString &unicodeString)
+  { return unicodeString; }
+inline UString GetUnicodeString(const AString &ansiString)
+  { return MultiByteToUnicodeString(ansiString); }
+inline UString GetUnicodeString(const AString &multiByteString, UINT codePage)
+  { return MultiByteToUnicodeString(multiByteString, codePage); }
+inline const wchar_t* GetUnicodeString(const wchar_t* unicodeString, UINT)
+  { return unicodeString; }
+inline const UString& GetUnicodeString(const UString &unicodeString, UINT)
+  { return unicodeString; }
+
+inline const char* GetAnsiString(const char* ansiString)
+  { return ansiString; }
+inline const AString& GetAnsiString(const AString &ansiString)
+  { return ansiString; }
+inline AString GetAnsiString(const UString &unicodeString)
+  { return UnicodeStringToMultiByte(unicodeString); }
+
+inline const char* GetOemString(const char* oemString)
+  { return oemString; }
+inline const AString& GetOemString(const AString &oemString)
+  { return oemString; }
+inline AString GetOemString(const UString &unicodeString)
+  { return UnicodeStringToMultiByte(unicodeString, CP_OEMCP); }
+
+
+#ifdef _UNICODE
+  inline const wchar_t* GetSystemString(const wchar_t* unicodeString)
+    { return unicodeString;}
+  inline const UString& GetSystemString(const UString &unicodeString)
+    { return unicodeString;}
+  inline const wchar_t* GetSystemString(const wchar_t* unicodeString, UINT /* codePage */)
+    { return unicodeString;}
+  inline const UString& GetSystemString(const UString &unicodeString, UINT /* codePage */)
+    { return unicodeString;}
+  inline UString GetSystemString(const AString &multiByteString, UINT codePage)
+    { return MultiByteToUnicodeString(multiByteString, codePage);}
+  inline UString GetSystemString(const AString &multiByteString)
+    { return MultiByteToUnicodeString(multiByteString);}
+#else
+  inline const char* GetSystemString(const char *ansiString)
+    { return ansiString; }
+  inline const AString& GetSystemString(const AString &multiByteString, UINT)
+    { return multiByteString; }
+  inline const char * GetSystemString(const char *multiByteString, UINT)
+    { return multiByteString; }
+  inline AString GetSystemString(const UString &unicodeString)
+    { return UnicodeStringToMultiByte(unicodeString); }
+  inline AString GetSystemString(const UString &unicodeString, UINT codePage)
+    { return UnicodeStringToMultiByte(unicodeString, codePage); }
+#endif
+
+#ifndef _WIN32_WCE
+AString SystemStringToOemString(const CSysString &srcString);
+#endif
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/misc/libphysfs/lzma/CPP/Common/StringToInt.cpp	Mon Apr 10 12:06:43 2017 -0400
@@ -0,0 +1,68 @@
+// Common/StringToInt.cpp
+
+#include "StdAfx.h"
+
+#include "StringToInt.h"
+
+UInt64 ConvertStringToUInt64(const char *s, const char **end)
+{
+  UInt64 result = 0;
+  for (;;)
+  {
+    char c = *s;
+    if (c < '0' || c > '9')
+    {
+      if (end != NULL)
+        *end = s;
+      return result;
+    }
+    result *= 10;
+    result += (c - '0');
+    s++;
+  }
+}
+
+UInt64 ConvertOctStringToUInt64(const char *s, const char **end)
+{
+  UInt64 result = 0;
+  for (;;)
+  {
+    char c = *s;
+    if (c < '0' || c > '7')
+    {
+      if (end != NULL)
+        *end = s;
+      return result;
+    }
+    result <<= 3;
+    result += (c - '0');
+    s++;
+  }
+}
+
+
+UInt64 ConvertStringToUInt64(const wchar_t *s, const wchar_t **end)
+{
+  UInt64 result = 0;
+  for (;;)
+  {
+    wchar_t c = *s;
+    if (c < '0' || c > '9')
+    {
+      if (end != NULL)
+        *end = s;
+      return result;
+    }
+    result *= 10;
+    result += (c - '0');
+    s++;
+  }
+}
+
+
+Int64 ConvertStringToInt64(const char *s, const char **end)
+{
+  if (*s == '-')
+    return -(Int64)ConvertStringToUInt64(s + 1, end);
+  return ConvertStringToUInt64(s, end);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/misc/libphysfs/lzma/CPP/Common/StringToInt.h	Mon Apr 10 12:06:43 2017 -0400
@@ -0,0 +1,17 @@
+// Common/StringToInt.h
+
+#ifndef __COMMON_STRINGTOINT_H
+#define __COMMON_STRINGTOINT_H
+
+#include <string.h>
+#include "Types.h"
+
+UInt64 ConvertStringToUInt64(const char *s, const char **end);
+UInt64 ConvertOctStringToUInt64(const char *s, const char **end);
+UInt64 ConvertStringToUInt64(const wchar_t *s, const wchar_t **end);
+
+Int64 ConvertStringToInt64(const char *s, const char **end);
+
+#endif
+
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/misc/libphysfs/lzma/CPP/Common/Types.h	Mon Apr 10 12:06:43 2017 -0400
@@ -0,0 +1,57 @@
+// Common/Types.h
+
+#ifndef __COMMON_TYPES_H
+#define __COMMON_TYPES_H
+
+#ifndef _7ZIP_BYTE_DEFINED
+#define _7ZIP_BYTE_DEFINED
+typedef unsigned char Byte;
+#endif 
+
+#ifndef _7ZIP_INT16_DEFINED
+#define _7ZIP_INT16_DEFINED
+typedef short Int16;
+#endif 
+
+#ifndef _7ZIP_UINT16_DEFINED
+#define _7ZIP_UINT16_DEFINED
+typedef unsigned short UInt16;
+#endif 
+
+#ifndef _7ZIP_INT32_DEFINED
+#define _7ZIP_INT32_DEFINED
+typedef int Int32;
+#endif 
+
+#ifndef _7ZIP_UINT32_DEFINED
+#define _7ZIP_UINT32_DEFINED
+typedef unsigned int UInt32;
+#endif 
+
+#ifdef _MSC_VER
+
+#ifndef _7ZIP_INT64_DEFINED
+#define _7ZIP_INT64_DEFINED
+typedef __int64 Int64;
+#endif 
+
+#ifndef _7ZIP_UINT64_DEFINED
+#define _7ZIP_UINT64_DEFINED
+typedef unsigned __int64 UInt64;
+#endif 
+
+#else
+
+#ifndef _7ZIP_INT64_DEFINED
+#define _7ZIP_INT64_DEFINED
+typedef long long int Int64;
+#endif 
+
+#ifndef _7ZIP_UINT64_DEFINED
+#define _7ZIP_UINT64_DEFINED
+typedef unsigned long long int UInt64;
+#endif 
+
+#endif
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/misc/libphysfs/lzma/CPP/Common/UTFConvert.cpp	Mon Apr 10 12:06:43 2017 -0400
@@ -0,0 +1,91 @@
+// UTFConvert.cpp
+
+#include "StdAfx.h"
+
+#include "UTFConvert.h"
+#include "Types.h"
+
+static Byte kUtf8Limits[5] = { 0xC0, 0xE0, 0xF0, 0xF8, 0xFC };
+
+// These functions are for UTF8 <-> UTF16 conversion.
+
+bool ConvertUTF8ToUnicode(const AString &src, UString &dest)
+{
+  dest.Empty();
+  for(int i = 0; i < src.Length();)
+  {
+    Byte c = (Byte)src[i++];
+    if (c < 0x80)
+    {
+      dest += (wchar_t)c;
+      continue;
+    }
+    if(c < 0xC0)
+      return false;
+    int numAdds;
+    for (numAdds = 1; numAdds < 5; numAdds++)
+      if (c < kUtf8Limits[numAdds])
+        break;
+    UInt32 value = (c - kUtf8Limits[numAdds - 1]);
+    do
+    {
+      if (i >= src.Length())
+        return false;
+      Byte c2 = (Byte)src[i++];
+      if (c2 < 0x80 || c2 >= 0xC0)
+        return false;
+      value <<= 6;
+      value |= (c2 - 0x80);
+      numAdds--;
+    }
+    while(numAdds > 0);
+    if (value < 0x10000)
+      dest += (wchar_t)(value);
+    else
+    {
+      value -= 0x10000;
+      if (value >= 0x100000)
+        return false;
+      dest += (wchar_t)(0xD800 + (value >> 10));
+      dest += (wchar_t)(0xDC00 + (value & 0x3FF));
+    }
+  }
+  return true; 
+}
+
+bool ConvertUnicodeToUTF8(const UString &src, AString &dest)
+{
+  dest.Empty();
+  for(int i = 0; i < src.Length();)
+  {
+    UInt32 value = (UInt32)src[i++];
+    if (value < 0x80)
+    {
+      dest += (char)value;
+      continue;
+    }
+    if (value >= 0xD800 && value < 0xE000)
+    {
+      if (value >= 0xDC00)
+        return false;
+      if (i >= src.Length())
+        return false;
+      UInt32 c2 = (UInt32)src[i++];
+      if (c2 < 0xDC00 || c2 >= 0xE000)
+        return false;
+      value = ((value - 0xD800) << 10) | (c2 - 0xDC00);
+    }
+    int numAdds;
+    for (numAdds = 1; numAdds < 5; numAdds++)
+      if (value < (((UInt32)1) << (numAdds * 5 + 6)))
+        break;
+    dest += (char)(kUtf8Limits[numAdds - 1] + (value >> (6 * numAdds)));
+    do
+    {
+      numAdds--;
+      dest += (char)(0x80 + ((value >> (6 * numAdds)) & 0x3F));
+    }
+    while(numAdds > 0);
+  }
+  return true;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/misc/libphysfs/lzma/CPP/Common/UTFConvert.h	Mon Apr 10 12:06:43 2017 -0400
@@ -0,0 +1,11 @@
+// Common/UTFConvert.h
+
+#ifndef __COMMON_UTFCONVERT_H
+#define __COMMON_UTFCONVERT_H
+
+#include "MyString.h"
+
+bool ConvertUTF8ToUnicode(const AString &utfString, UString &resultString);
+bool ConvertUnicodeToUTF8(const UString &unicodeString, AString &resultString);
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/misc/libphysfs/lzma/CPP/Common/Wildcard.cpp	Mon Apr 10 12:06:43 2017 -0400
@@ -0,0 +1,458 @@
+// Common/Wildcard.cpp
+
+#include "StdAfx.h"
+
+#include "Wildcard.h"
+
+bool g_CaseSensitive = 
+  #ifdef _WIN32
+    false;
+  #else
+    true;
+  #endif
+
+static const wchar_t kAnyCharsChar = L'*';
+static const wchar_t kAnyCharChar = L'?';
+
+#ifdef _WIN32
+static const wchar_t kDirDelimiter1 = L'\\';
+#endif
+static const wchar_t kDirDelimiter2 = L'/';
+
+static const UString kWildCardCharSet = L"?*";
+
+static const UString kIllegalWildCardFileNameChars=
+  L"\x1\x2\x3\x4\x5\x6\x7\x8\x9\xA\xB\xC\xD\xE\xF"
+  L"\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1A\x1B\x1C\x1D\x1E\x1F"
+  L"\"/:<>\\|";
+
+
+static inline bool IsCharDirLimiter(wchar_t c)
+{
+  return (
+    #ifdef _WIN32
+    c == kDirDelimiter1 || 
+    #endif
+    c == kDirDelimiter2);
+}
+
+int CompareFileNames(const UString &s1, const UString &s2)
+{
+  if (g_CaseSensitive)
+    return s1.Compare(s2);
+  return s1.CompareNoCase(s2);
+}
+
+// -----------------------------------------
+// this function compares name with mask
+// ? - any char
+// * - any char or empty
+
+static bool EnhancedMaskTest(const wchar_t *mask, const wchar_t *name)
+{
+  for (;;)
+  {
+    wchar_t m = *mask;
+    wchar_t c = *name;
+    if (m == 0) 
+      return (c == 0);
+    if (m == kAnyCharsChar)
+    {
+      if (EnhancedMaskTest(mask + 1, name))
+        return true;
+      if (c == 0) 
+        return false;
+    }
+    else
+    {
+      if (m == kAnyCharChar)
+      {
+        if (c == 0) 
+          return false;
+      }
+      else if (m != c)
+        if (g_CaseSensitive || MyCharUpper(m) != MyCharUpper(c))
+          return false;
+      mask++;
+    }
+    name++;
+  }
+}
+
+// --------------------------------------------------
+// Splits path to strings
+
+void SplitPathToParts(const UString &path, UStringVector &pathParts)
+{
+  pathParts.Clear();
+  UString name;
+  int len = path.Length();
+  if (len == 0)
+    return;
+  for (int i = 0; i < len; i++)
+  {
+    wchar_t c = path[i];
+    if (IsCharDirLimiter(c))
+    {
+      pathParts.Add(name);
+      name.Empty();
+    }
+    else
+      name += c;
+  }
+  pathParts.Add(name);
+}
+
+void SplitPathToParts(const UString &path, UString &dirPrefix, UString &name)
+{
+  int i;
+  for(i = path.Length() - 1; i >= 0; i--)
+    if(IsCharDirLimiter(path[i]))
+      break;
+  dirPrefix = path.Left(i + 1);
+  name = path.Mid(i + 1);
+}
+
+UString ExtractDirPrefixFromPath(const UString &path)
+{
+  int i;
+  for(i = path.Length() - 1; i >= 0; i--)
+    if(IsCharDirLimiter(path[i]))
+      break;
+  return path.Left(i + 1);
+}
+
+UString ExtractFileNameFromPath(const UString &path)
+{
+  int i;
+  for(i = path.Length() - 1; i >= 0; i--)
+    if(IsCharDirLimiter(path[i]))
+      break;
+  return path.Mid(i + 1);
+}
+
+
+bool CompareWildCardWithName(const UString &mask, const UString &name)
+{
+  return EnhancedMaskTest(mask, name);
+}
+
+bool DoesNameContainWildCard(const UString &path)
+{
+  return (path.FindOneOf(kWildCardCharSet) >= 0);
+}
+
+
+// ----------------------------------------------------------'
+// NWildcard
+
+namespace NWildcard {
+
+
+/*
+M = MaskParts.Size();
+N = TestNameParts.Size();
+
+                           File                          Dir
+ForFile     req   M<=N  [N-M, N)                          -
+         nonreq   M=N   [0, M)                            -  
+ 
+ForDir      req   M<N   [0, M) ... [N-M-1, N-1)  same as ForBoth-File
+         nonreq         [0, M)                   same as ForBoth-File
+
+ForBoth     req   m<=N  [0, M) ... [N-M, N)      same as ForBoth-File
+         nonreq         [0, M)                   same as ForBoth-File
+
+*/
+
+bool CItem::CheckPath(const UStringVector &pathParts, bool isFile) const
+{
+  if (!isFile && !ForDir)
+    return false;
+  int delta = (int)pathParts.Size() - (int)PathParts.Size();
+  if (delta < 0)
+    return false;
+  int start = 0;
+  int finish = 0;
+  if (isFile)
+  {
+    if (!ForDir && !Recursive && delta !=0)
+      return false;
+    if (!ForFile && delta == 0)
+      return false;
+    if (!ForDir && Recursive)
+      start = delta;
+  }
+  if (Recursive)
+  {
+    finish = delta;
+    if (isFile && !ForFile)
+      finish = delta - 1;
+  }
+  for (int d = start; d <= finish; d++)
+  {
+    int i;
+    for (i = 0; i < PathParts.Size(); i++)
+      if (!CompareWildCardWithName(PathParts[i], pathParts[i + d]))
+        break;
+    if (i == PathParts.Size())
+      return true;
+  }
+  return false;
+}
+
+int CCensorNode::FindSubNode(const UString &name) const
+{
+  for (int i = 0; i < SubNodes.Size(); i++)
+    if (CompareFileNames(SubNodes[i].Name, name) == 0)
+      return i;
+  return -1;
+}
+
+void CCensorNode::AddItemSimple(bool include, CItem &item)
+{
+  if (include)
+    IncludeItems.Add(item);
+  else
+    ExcludeItems.Add(item);
+}
+
+void CCensorNode::AddItem(bool include, CItem &item)
+{
+  if (item.PathParts.Size() <= 1)
+  {
+    AddItemSimple(include, item);
+    return;
+  }
+  const UString &front = item.PathParts.Front();
+  if (DoesNameContainWildCard(front))
+  {
+    AddItemSimple(include, item);
+    return;
+  }
+  int index = FindSubNode(front);
+  if (index < 0)
+    index = SubNodes.Add(CCensorNode(front, this));
+  item.PathParts.Delete(0);
+  SubNodes[index].AddItem(include, item);
+}
+
+void CCensorNode::AddItem(bool include, const UString &path, bool recursive, bool forFile, bool forDir)
+{
+  CItem item;
+  SplitPathToParts(path, item.PathParts);
+  item.Recursive = recursive;
+  item.ForFile = forFile;
+  item.ForDir = forDir;
+  AddItem(include, item);
+}
+
+bool CCensorNode::NeedCheckSubDirs() const
+{
+  for (int i = 0; i < IncludeItems.Size(); i++)
+  {
+    const CItem &item = IncludeItems[i];
+    if (item.Recursive || item.PathParts.Size() > 1)
+      return true;
+  }
+  return false;
+}
+
+bool CCensorNode::AreThereIncludeItems() const
+{
+  if (IncludeItems.Size() > 0)
+    return true;
+  for (int i = 0; i < SubNodes.Size(); i++)
+    if (SubNodes[i].AreThereIncludeItems())
+      return true;
+  return false;
+}
+
+bool CCensorNode::CheckPathCurrent(bool include, const UStringVector &pathParts, bool isFile) const
+{
+  const CObjectVector<CItem> &items = include ? IncludeItems : ExcludeItems;
+  for (int i = 0; i < items.Size(); i++)
+    if (items[i].CheckPath(pathParts, isFile))
+      return true;
+  return false;
+}
+
+bool CCensorNode::CheckPath(UStringVector &pathParts, bool isFile, bool &include) const
+{
+  if (CheckPathCurrent(false, pathParts, isFile))
+  {
+    include = false;
+    return true;
+  }
+  include = true;
+  bool finded = CheckPathCurrent(true, pathParts, isFile);
+  if (pathParts.Size() == 1)
+    return finded;
+  int index = FindSubNode(pathParts.Front());
+  if (index >= 0)
+  {
+    UStringVector pathParts2 = pathParts;
+    pathParts2.Delete(0);
+    if (SubNodes[index].CheckPath(pathParts2, isFile, include))
+      return true;
+  }
+  return finded;
+}
+
+bool CCensorNode::CheckPath(const UString &path, bool isFile, bool &include) const
+{
+  UStringVector pathParts; 
+  SplitPathToParts(path, pathParts);
+  return CheckPath(pathParts, isFile, include);
+}
+
+bool CCensorNode::CheckPath(const UString &path, bool isFile) const
+{
+  bool include;
+  if(CheckPath(path, isFile, include))
+    return include;
+  return false;
+}
+
+bool CCensorNode::CheckPathToRoot(bool include, UStringVector &pathParts, bool isFile) const
+{
+  if (CheckPathCurrent(include, pathParts, isFile))
+    return true;
+  if (Parent == 0)
+    return false;
+  pathParts.Insert(0, Name);
+  return Parent->CheckPathToRoot(include, pathParts, isFile);
+}
+
+/*
+bool CCensorNode::CheckPathToRoot(bool include, const UString &path, bool isFile) const
+{
+  UStringVector pathParts; 
+  SplitPathToParts(path, pathParts);
+  return CheckPathToRoot(include, pathParts, isFile);
+}
+*/
+
+void CCensorNode::AddItem2(bool include, const UString &path, bool recursive)
+{
+  if (path.IsEmpty())
+    return;
+  bool forFile = true;
+  bool forFolder = true;
+  UString path2 = path;
+  if (IsCharDirLimiter(path[path.Length() - 1]))
+  {
+    path2.Delete(path.Length() - 1);
+    forFile = false;
+  }
+  AddItem(include, path2, recursive, forFile, forFolder);
+}
+
+void CCensorNode::ExtendExclude(const CCensorNode &fromNodes)
+{
+  ExcludeItems += fromNodes.ExcludeItems;
+  for (int i = 0; i < fromNodes.SubNodes.Size(); i++)
+  {
+    const CCensorNode &node = fromNodes.SubNodes[i];
+    int subNodeIndex = FindSubNode(node.Name);
+    if (subNodeIndex < 0)
+      subNodeIndex = SubNodes.Add(CCensorNode(node.Name, this));
+    SubNodes[subNodeIndex].ExtendExclude(node);
+  }
+}
+
+int CCensor::FindPrefix(const UString &prefix) const
+{
+  for (int i = 0; i < Pairs.Size(); i++)
+    if (CompareFileNames(Pairs[i].Prefix, prefix) == 0)
+      return i;
+  return -1;
+}
+
+void CCensor::AddItem(bool include, const UString &path, bool recursive)
+{
+  UStringVector pathParts;
+  SplitPathToParts(path, pathParts);
+  bool forFile = true;
+  if (pathParts.Back().IsEmpty())
+  {
+    forFile = false;
+    pathParts.DeleteBack();
+  }
+  const UString &front = pathParts.Front();
+  bool isAbs = false;
+  if (front.IsEmpty())
+    isAbs = true;
+  else if (front.Length() == 2 && front[1] == L':')
+    isAbs = true;
+  else
+  {
+    for (int i = 0; i < pathParts.Size(); i++)
+    {
+      const UString &part = pathParts[i];
+      if (part == L".." || part == L".")
+      {
+        isAbs = true;
+        break;
+      }
+    }
+  }
+  int numAbsParts = 0;
+  if (isAbs)
+    if (pathParts.Size() > 1)
+      numAbsParts = pathParts.Size() - 1;
+    else
+      numAbsParts = 1;
+  UString prefix;
+  for (int i = 0; i < numAbsParts; i++)
+  {
+    const UString &front = pathParts.Front();
+    if (DoesNameContainWildCard(front))
+      break;
+    prefix += front;
+    prefix += WCHAR_PATH_SEPARATOR;
+    pathParts.Delete(0);
+  }
+  int index = FindPrefix(prefix);
+  if (index < 0)
+    index = Pairs.Add(CPair(prefix));
+
+  CItem item;
+  item.PathParts = pathParts;
+  item.ForDir = true;
+  item.ForFile = forFile;
+  item.Recursive = recursive;
+  Pairs[index].Head.AddItem(include, item);
+}
+
+bool CCensor::CheckPath(const UString &path, bool isFile) const
+{
+  bool finded = false;
+  for (int i = 0; i < Pairs.Size(); i++)
+  {
+    bool include;
+    if (Pairs[i].Head.CheckPath(path, isFile, include))
+    {
+      if (!include)
+        return false;
+      finded = true;
+    }
+  }
+  return finded;
+}
+
+void CCensor::ExtendExclude()
+{
+  int i;
+  for (i = 0; i < Pairs.Size(); i++)
+    if (Pairs[i].Prefix.IsEmpty())
+      break;
+  if (i == Pairs.Size())
+    return;
+  int index = i;
+  for (i = 0; i < Pairs.Size(); i++)
+    if (index != i)
+      Pairs[i].Head.ExtendExclude(Pairs[index].Head);
+}
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/misc/libphysfs/lzma/CPP/Common/Wildcard.h	Mon Apr 10 12:06:43 2017 -0400
@@ -0,0 +1,80 @@
+// Common/Wildcard.h
+
+#ifndef __COMMON_WILDCARD_H
+#define __COMMON_WILDCARD_H
+
+#include "MyString.h"
+
+int CompareFileNames(const UString &s1, const UString &s2);
+
+void SplitPathToParts(const UString &path, UStringVector &pathParts);
+void SplitPathToParts(const UString &path, UString &dirPrefix, UString &name);
+UString ExtractDirPrefixFromPath(const UString &path);
+UString ExtractFileNameFromPath(const UString &path);
+bool DoesNameContainWildCard(const UString &path);
+bool CompareWildCardWithName(const UString &mask, const UString &name);
+
+namespace NWildcard {
+
+struct CItem
+{
+  UStringVector PathParts;
+  bool Recursive;
+  bool ForFile;
+  bool ForDir;
+  bool CheckPath(const UStringVector &pathParts, bool isFile) const;
+};
+
+class CCensorNode
+{
+  CCensorNode *Parent;
+  bool CheckPathCurrent(bool include, const UStringVector &pathParts, bool isFile) const;
+  void AddItemSimple(bool include, CItem &item);
+  bool CheckPath(UStringVector &pathParts, bool isFile, bool &include) const;
+public:
+  CCensorNode(): Parent(0) { };
+  CCensorNode(const UString &name, CCensorNode *parent): Name(name), Parent(parent) { };
+  UString Name;
+  CObjectVector<CCensorNode> SubNodes;
+  CObjectVector<CItem> IncludeItems;
+  CObjectVector<CItem> ExcludeItems;
+
+  int FindSubNode(const UString &path) const;
+
+  void AddItem(bool include, CItem &item);
+  void AddItem(bool include, const UString &path, bool recursive, bool forFile, bool forDir);
+  void AddItem2(bool include, const UString &path, bool recursive);
+
+  bool NeedCheckSubDirs() const;
+  bool AreThereIncludeItems() const;
+
+  bool CheckPath(const UString &path, bool isFile, bool &include) const;
+  bool CheckPath(const UString &path, bool isFile) const;
+
+  bool CheckPathToRoot(bool include, UStringVector &pathParts, bool isFile) const;
+  // bool CheckPathToRoot(const UString &path, bool isFile, bool include) const;
+  void ExtendExclude(const CCensorNode &fromNodes);
+};
+
+struct CPair
+{
+  UString Prefix;
+  CCensorNode Head;
+  CPair(const UString &prefix): Prefix(prefix) { };
+};
+
+class CCensor
+{
+  int FindPrefix(const UString &prefix) const;
+public:
+  CObjectVector<CPair> Pairs;
+  bool AllAreRelative() const
+    { return (Pairs.Size() == 1 && Pairs.Front().Prefix.IsEmpty()); }
+  void AddItem(bool include, const UString &path, bool recursive);
+  bool CheckPath(const UString &path, bool isFile) const;
+  void ExtendExclude();
+};
+
+}
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/misc/libphysfs/lzma/CPP/Windows/DLL.cpp	Mon Apr 10 12:06:43 2017 -0400
@@ -0,0 +1,115 @@
+// Windows/DLL.cpp
+
+#include "StdAfx.h"
+
+#include "DLL.h"
+#include "Defs.h"
+#ifndef _UNICODE
+#include "../Common/StringConvert.h"
+#endif
+
+#ifndef _UNICODE
+extern bool g_IsNT;
+#endif
+
+namespace NWindows {
+namespace NDLL {
+
+CLibrary::~CLibrary()
+{
+  Free();
+}
+
+bool CLibrary::Free()
+{
+  if (_module == 0)
+    return true;
+  // MessageBox(0, TEXT(""), TEXT("Free"), 0);
+  // Sleep(5000);
+  if (!::FreeLibrary(_module))
+    return false;
+  _module = 0;
+  return true;
+}
+
+bool CLibrary::LoadOperations(HMODULE newModule)
+{
+  if (newModule == NULL)
+    return false;
+  if(!Free())
+    return false;
+  _module = newModule;
+  return true;
+}
+
+bool CLibrary::LoadEx(LPCTSTR fileName, DWORD flags)
+{
+  // MessageBox(0, fileName, TEXT("LoadEx"), 0);
+  return LoadOperations(::LoadLibraryEx(fileName, NULL, flags));
+}
+
+bool CLibrary::Load(LPCTSTR fileName)
+{
+  // MessageBox(0, fileName, TEXT("Load"), 0);
+  // Sleep(5000);
+  // OutputDebugString(fileName);
+  // OutputDebugString(TEXT("\n"));
+  return LoadOperations(::LoadLibrary(fileName));
+}
+
+#ifndef _UNICODE
+static inline UINT GetCurrentCodePage() { return ::AreFileApisANSI() ? CP_ACP : CP_OEMCP; } 
+CSysString GetSysPath(LPCWSTR sysPath)
+  { return UnicodeStringToMultiByte(sysPath, GetCurrentCodePage()); }
+
+bool CLibrary::LoadEx(LPCWSTR fileName, DWORD flags)
+{
+  if (g_IsNT)
+    return LoadOperations(::LoadLibraryExW(fileName, NULL, flags));
+  return LoadEx(GetSysPath(fileName), flags);
+}
+bool CLibrary::Load(LPCWSTR fileName)
+{
+  if (g_IsNT)
+    return LoadOperations(::LoadLibraryW(fileName));
+  return Load(GetSysPath(fileName));
+}
+#endif
+
+bool MyGetModuleFileName(HMODULE hModule, CSysString &result)
+{
+  result.Empty();
+  TCHAR fullPath[MAX_PATH + 2];
+  DWORD size = ::GetModuleFileName(hModule, fullPath, MAX_PATH + 1);
+  if (size <= MAX_PATH && size != 0)
+  {
+    result = fullPath;
+    return true;
+  }
+  return false;
+}
+
+#ifndef _UNICODE
+bool MyGetModuleFileName(HMODULE hModule, UString &result)
+{
+  result.Empty();
+  if (g_IsNT)
+  {
+    wchar_t fullPath[MAX_PATH + 2];
+    DWORD size = ::GetModuleFileNameW(hModule, fullPath, MAX_PATH + 1);
+    if (size <= MAX_PATH && size != 0)
+    {
+      result = fullPath;
+      return true;
+    }
+    return false;
+  }
+  CSysString resultSys;
+  if (!MyGetModuleFileName(hModule, resultSys))
+    return false;
+  result = MultiByteToUnicodeString(resultSys, GetCurrentCodePage());
+  return true;
+}
+#endif
+
+}}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/misc/libphysfs/lzma/CPP/Windows/DLL.h	Mon Apr 10 12:06:43 2017 -0400
@@ -0,0 +1,54 @@
+// Windows/DLL.h
+
+#ifndef __WINDOWS_DLL_H
+#define __WINDOWS_DLL_H
+
+#include "../Common/MyString.h"
+
+namespace NWindows {
+namespace NDLL {
+
+class CLibrary
+{
+  bool LoadOperations(HMODULE newModule);
+protected:
+  HMODULE _module;
+public:
+  operator HMODULE() const { return _module; }
+  HMODULE* operator&() { return &_module; }
+
+  CLibrary():_module(NULL) {};
+  ~CLibrary();
+  void Attach(HMODULE m)
+  {
+    Free();
+    _module = m;
+  }
+  HMODULE Detach()
+  {
+    HMODULE m = _module;
+    _module = NULL;
+    return m;
+  }
+
+  // operator HMODULE() const { return _module; };
+  bool IsLoaded() const { return (_module != NULL); };
+  bool Free();
+  bool LoadEx(LPCTSTR fileName, DWORD flags = LOAD_LIBRARY_AS_DATAFILE);
+  bool Load(LPCTSTR fileName);
+  #ifndef _UNICODE
+  bool LoadEx(LPCWSTR fileName, DWORD flags = LOAD_LIBRARY_AS_DATAFILE);
+  bool Load(LPCWSTR fileName);
+  #endif
+  FARPROC GetProcAddress(LPCSTR procName) const
+    { return ::GetProcAddress(_module, procName); }
+};
+
+bool MyGetModuleFileName(HMODULE hModule, CSysString &result);
+#ifndef _UNICODE
+bool MyGetModuleFileName(HMODULE hModule, UString &result);
+#endif
+
+}}
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/misc/libphysfs/lzma/CPP/Windows/Defs.h	Mon Apr 10 12:06:43 2017 -0400
@@ -0,0 +1,23 @@
+// Windows/Defs.h
+
+#ifndef __WINDOWS_DEFS_H
+#define __WINDOWS_DEFS_H
+
+inline bool BOOLToBool(BOOL value)
+  { return (value != FALSE); }
+
+#ifdef _WIN32
+inline bool LRESULTToBool(LRESULT value)
+  { return (value != FALSE); }
+#endif
+
+inline BOOL BoolToBOOL(bool value)
+  { return (value ? TRUE: FALSE); }
+
+inline VARIANT_BOOL BoolToVARIANT_BOOL(bool value)
+  { return (value ? VARIANT_TRUE: VARIANT_FALSE); }
+
+inline bool VARIANT_BOOLToBool(VARIANT_BOOL value)
+  { return (value != VARIANT_FALSE); }
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/misc/libphysfs/lzma/CPP/Windows/Error.cpp	Mon Apr 10 12:06:43 2017 -0400
@@ -0,0 +1,50 @@
+// Windows/Error.h
+
+#include "StdAfx.h"
+
+#include "Windows/Error.h"
+#ifndef _UNICODE
+#include "Common/StringConvert.h"
+#endif
+
+#ifndef _UNICODE
+extern bool g_IsNT;
+#endif
+
+namespace NWindows {
+namespace NError {
+
+bool MyFormatMessage(DWORD messageID, CSysString &message)
+{
+  LPVOID msgBuf;
+  if(::FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | 
+      FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS,
+      NULL,messageID, 0, (LPTSTR) &msgBuf,0, NULL) == 0)
+    return false;
+  message = (LPCTSTR)msgBuf;
+  ::LocalFree(msgBuf);
+  return true;
+}
+
+#ifndef _UNICODE
+bool MyFormatMessage(DWORD messageID, UString &message)
+{
+  if (g_IsNT)
+  {
+    LPVOID msgBuf;
+    if(::FormatMessageW(FORMAT_MESSAGE_ALLOCATE_BUFFER | 
+        FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS,
+        NULL, messageID, 0, (LPWSTR) &msgBuf, 0, NULL) == 0)
+      return false;
+    message = (LPCWSTR)msgBuf;
+    ::LocalFree(msgBuf);
+    return true;
+  }
+  CSysString messageSys;
+  bool result = MyFormatMessage(messageID, messageSys);
+  message = GetUnicodeString(messageSys);
+  return result;
+}
+#endif
+
+}}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/misc/libphysfs/lzma/CPP/Windows/Error.h	Mon Apr 10 12:06:43 2017 -0400
@@ -0,0 +1,33 @@
+// Windows/Error.h
+
+#ifndef __WINDOWS_ERROR_H
+#define __WINDOWS_ERROR_H
+
+#include "Common/MyString.h"
+
+namespace NWindows {
+namespace NError {
+
+bool MyFormatMessage(DWORD messageID, CSysString &message);
+inline CSysString MyFormatMessage(DWORD messageID)
+{
+  CSysString message;
+  MyFormatMessage(messageID, message);
+  return message;
+}
+#ifdef _UNICODE
+inline UString MyFormatMessageW(DWORD messageID)
+  { return MyFormatMessage(messageID); }
+#else
+bool MyFormatMessage(DWORD messageID, UString &message);
+inline UString MyFormatMessageW(DWORD messageID)
+{
+  UString message;
+  MyFormatMessage(messageID, message);
+  return message;
+}
+#endif
+
+}}
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/misc/libphysfs/lzma/CPP/Windows/FileDir.cpp	Mon Apr 10 12:06:43 2017 -0400
@@ -0,0 +1,841 @@
+// Windows/FileDir.cpp
+
+#include "StdAfx.h"
+
+#include "FileDir.h"
+#include "FileName.h"
+#include "FileFind.h"
+#include "Defs.h"
+#ifndef _UNICODE
+#include "../Common/StringConvert.h"
+#endif
+
+#ifndef _UNICODE
+extern bool g_IsNT;
+#endif
+
+namespace NWindows {
+namespace NFile {
+
+#if defined(WIN_LONG_PATH) && defined(_UNICODE)
+#define WIN_LONG_PATH2
+#endif
+
+// SetCurrentDirectory doesn't support \\?\ prefix
+
+#ifdef WIN_LONG_PATH
+bool GetLongPathBase(LPCWSTR fileName, UString &res);
+bool GetLongPath(LPCWSTR fileName, UString &res);
+#endif
+
+namespace NDirectory {
+
+#ifndef _UNICODE
+static inline UINT GetCurrentCodePage() { return ::AreFileApisANSI() ? CP_ACP : CP_OEMCP; } 
+static UString GetUnicodePath(const CSysString &sysPath)
+  { return MultiByteToUnicodeString(sysPath, GetCurrentCodePage()); }
+static CSysString GetSysPath(LPCWSTR sysPath)
+  { return UnicodeStringToMultiByte(sysPath, GetCurrentCodePage()); }
+#endif
+
+bool MyGetWindowsDirectory(CSysString &path)
+{
+  UINT needLength = ::GetWindowsDirectory(path.GetBuffer(MAX_PATH + 1), MAX_PATH + 1);
+  path.ReleaseBuffer();
+  return (needLength > 0 && needLength <= MAX_PATH);
+}
+
+bool MyGetSystemDirectory(CSysString &path)
+{
+  UINT needLength = ::GetSystemDirectory(path.GetBuffer(MAX_PATH + 1), MAX_PATH + 1);
+  path.ReleaseBuffer();
+  return (needLength > 0 && needLength <= MAX_PATH);
+}
+
+#ifndef _UNICODE
+bool MyGetWindowsDirectory(UString &path)
+{
+  if (g_IsNT)
+  {
+    UINT needLength = ::GetWindowsDirectoryW(path.GetBuffer(MAX_PATH + 1), MAX_PATH + 1);
+    path.ReleaseBuffer();
+    return (needLength > 0 && needLength <= MAX_PATH);
+  }
+  CSysString sysPath;
+  if (!MyGetWindowsDirectory(sysPath))
+    return false;
+  path = GetUnicodePath(sysPath);
+  return true;
+}
+
+bool MyGetSystemDirectory(UString &path)
+{
+  if (g_IsNT)
+  {
+    UINT needLength = ::GetSystemDirectoryW(path.GetBuffer(MAX_PATH + 1), MAX_PATH + 1);
+    path.ReleaseBuffer();
+    return (needLength > 0 && needLength <= MAX_PATH);
+  }
+  CSysString sysPath;
+  if (!MyGetSystemDirectory(sysPath))
+    return false;
+  path = GetUnicodePath(sysPath);
+  return true;
+}
+#endif
+
+bool SetDirTime(LPCWSTR fileName, const FILETIME *creationTime, const FILETIME *lastAccessTime, const FILETIME *lastWriteTime)
+{
+  #ifndef _UNICODE
+  if (!g_IsNT)
+  {
+    ::SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
+    return false;
+  }
+  #endif 
+  HANDLE hDir = ::CreateFileW(fileName, GENERIC_WRITE,
+      FILE_SHARE_READ | FILE_SHARE_WRITE,
+      NULL, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, NULL);
+  #ifdef WIN_LONG_PATH
+  if (hDir == INVALID_HANDLE_VALUE)
+  {
+    UString longPath;
+    if (GetLongPath(fileName, longPath))
+      hDir = ::CreateFileW(longPath, GENERIC_WRITE,
+        FILE_SHARE_READ | FILE_SHARE_WRITE,
+        NULL, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, NULL);
+  }
+  #endif
+
+  bool res = false;
+  if (hDir != INVALID_HANDLE_VALUE)
+  {
+    res = BOOLToBool(::SetFileTime(hDir, creationTime, lastAccessTime, lastWriteTime));
+    ::CloseHandle(hDir);
+  }
+  return res;
+}
+
+bool MySetFileAttributes(LPCTSTR fileName, DWORD fileAttributes)
+{
+  if (::SetFileAttributes(fileName, fileAttributes))
+    return true;
+  #ifdef WIN_LONG_PATH2
+  UString longPath;
+  if (GetLongPath(fileName, longPath))
+    return BOOLToBool(::SetFileAttributesW(longPath, fileAttributes));
+  #endif
+  return false;
+}
+
+bool MyRemoveDirectory(LPCTSTR pathName)
+{ 
+  if (::RemoveDirectory(pathName))
+    return true;
+  #ifdef WIN_LONG_PATH2
+  UString longPath;
+  if (GetLongPath(pathName, longPath))
+    return BOOLToBool(::RemoveDirectoryW(longPath));
+  #endif
+  return false;
+}
+
+#ifdef WIN_LONG_PATH
+bool GetLongPaths(LPCWSTR s1, LPCWSTR s2, UString &d1, UString &d2)
+{
+  if (!GetLongPathBase(s1, d1) || !GetLongPathBase(s2, d2))
+    return false;
+  if (d1.IsEmpty() && d2.IsEmpty()) return false;
+  if (d1.IsEmpty()) d1 = s1;
+  if (d2.IsEmpty()) d2 = s2;
+  return true;
+}
+#endif
+
+bool MyMoveFile(LPCTSTR existFileName, LPCTSTR newFileName)
+{ 
+  if (::MoveFile(existFileName, newFileName))
+    return true;
+  #ifdef WIN_LONG_PATH2
+  UString d1, d2;
+  if (GetLongPaths(existFileName, newFileName, d1, d2)) 
+    return BOOLToBool(::MoveFileW(d1, d2));
+  #endif
+  return false;
+}
+
+#ifndef _UNICODE
+bool MySetFileAttributes(LPCWSTR fileName, DWORD fileAttributes)
+{  
+  if (!g_IsNT)
+    return MySetFileAttributes(GetSysPath(fileName), fileAttributes);
+  if (::SetFileAttributesW(fileName, fileAttributes))
+    return true;
+  #ifdef WIN_LONG_PATH
+  UString longPath;
+  if (GetLongPath(fileName, longPath))
+    return BOOLToBool(::SetFileAttributesW(longPath, fileAttributes));
+  #endif
+  return false;
+}
+
+
+bool MyRemoveDirectory(LPCWSTR pathName)
+{  
+  if (!g_IsNT)
+    return MyRemoveDirectory(GetSysPath(pathName));
+  if (::RemoveDirectoryW(pathName))
+    return true;
+  #ifdef WIN_LONG_PATH
+  UString longPath;
+  if (GetLongPath(pathName, longPath))
+    return BOOLToBool(::RemoveDirectoryW(longPath));
+  #endif
+  return false;
+}
+
+bool MyMoveFile(LPCWSTR existFileName, LPCWSTR newFileName)
+{  
+  if (!g_IsNT)
+    return MyMoveFile(GetSysPath(existFileName), GetSysPath(newFileName));
+  if (::MoveFileW(existFileName, newFileName))
+    return true;
+  #ifdef WIN_LONG_PATH
+  UString d1, d2;
+  if (GetLongPaths(existFileName, newFileName, d1, d2)) 
+    return BOOLToBool(::MoveFileW(d1, d2));
+  #endif
+  return false;
+}
+#endif
+
+bool MyCreateDirectory(LPCTSTR pathName) 
+{ 
+  if (::CreateDirectory(pathName, NULL))
+    return true;
+  #ifdef WIN_LONG_PATH2
+  if (::GetLastError() != ERROR_ALREADY_EXISTS)
+  {
+    UString longPath;
+    if (GetLongPath(pathName, longPath))
+      return BOOLToBool(::CreateDirectoryW(longPath, NULL));
+  }
+  #endif
+  return false;
+}
+
+#ifndef _UNICODE
+bool MyCreateDirectory(LPCWSTR pathName)
+{  
+  if (!g_IsNT)
+    return MyCreateDirectory(GetSysPath(pathName));
+  if (::CreateDirectoryW(pathName, NULL))
+    return true;
+  #ifdef WIN_LONG_PATH
+  if (::GetLastError() != ERROR_ALREADY_EXISTS)
+  {
+    UString longPath;
+    if (GetLongPath(pathName, longPath))
+      return BOOLToBool(::CreateDirectoryW(longPath, NULL));
+  }
+  #endif
+  return false;
+}
+#endif
+
+/*
+bool CreateComplexDirectory(LPCTSTR pathName)
+{
+  NName::CParsedPath path;
+  path.ParsePath(pathName);
+  CSysString fullPath = path.Prefix;
+  DWORD errorCode = ERROR_SUCCESS;
+  for(int i = 0; i < path.PathParts.Size(); i++)
+  {
+    const CSysString &string = path.PathParts[i];
+    if(string.IsEmpty())
+    {
+      if(i != path.PathParts.Size() - 1)
+        return false;
+      return true;
+    }
+    fullPath += path.PathParts[i];
+    if (!MyCreateDirectory(fullPath))
+    {
+      DWORD errorCode = GetLastError();
+      if(errorCode != ERROR_ALREADY_EXISTS)
+        return false;
+    }
+    fullPath += NName::kDirDelimiter;
+  }
+  return true;
+}
+*/
+
+bool CreateComplexDirectory(LPCTSTR _aPathName)
+{
+  CSysString pathName = _aPathName;
+  int pos = pathName.ReverseFind(TEXT(CHAR_PATH_SEPARATOR));
+  if (pos > 0 && pos == pathName.Length() - 1)
+  {
+    if (pathName.Length() == 3 && pathName[1] == ':')
+      return true; // Disk folder;
+    pathName.Delete(pos);
+  }
+  CSysString pathName2 = pathName;
+  pos = pathName.Length();
+  for (;;)
+  {
+    if(MyCreateDirectory(pathName))
+      break;
+    if (::GetLastError() == ERROR_ALREADY_EXISTS)
+    {
+      NFind::CFileInfo fileInfo;
+      if (!NFind::FindFile(pathName, fileInfo)) // For network folders
+        return true;
+      if (!fileInfo.IsDirectory())
+        return false;
+      break;
+    }
+    pos = pathName.ReverseFind(TEXT(CHAR_PATH_SEPARATOR));
+    if (pos < 0 || pos == 0)
+      return false;
+    if (pathName[pos - 1] == ':')
+      return false;
+    pathName = pathName.Left(pos);
+  }
+  pathName = pathName2;
+  while(pos < pathName.Length())
+  {
+    pos = pathName.Find(TEXT(CHAR_PATH_SEPARATOR), pos + 1);
+    if (pos < 0)
+      pos = pathName.Length();
+    if (!MyCreateDirectory(pathName.Left(pos)))
+      return false;
+  }
+  return true;
+}
+
+#ifndef _UNICODE
+
+bool CreateComplexDirectory(LPCWSTR _aPathName)
+{
+  UString pathName = _aPathName;
+  int pos = pathName.ReverseFind(WCHAR_PATH_SEPARATOR);
+  if (pos > 0 && pos == pathName.Length() - 1)
+  {
+    if (pathName.Length() == 3 && pathName[1] == L':')
+      return true; // Disk folder;
+    pathName.Delete(pos);
+  }
+  UString pathName2 = pathName;
+  pos = pathName.Length();
+  for (;;)
+  {
+    if(MyCreateDirectory(pathName))
+      break;
+    if (::GetLastError() == ERROR_ALREADY_EXISTS)
+    {
+      NFind::CFileInfoW fileInfo;
+      if (!NFind::FindFile(pathName, fileInfo)) // For network folders
+        return true;
+      if (!fileInfo.IsDirectory())
+        return false;
+      break;
+    }
+    pos = pathName.ReverseFind(WCHAR_PATH_SEPARATOR);
+    if (pos < 0 || pos == 0)
+      return false;
+    if (pathName[pos - 1] == L':')
+      return false;
+    pathName = pathName.Left(pos);
+  }
+  pathName = pathName2;
+  while(pos < pathName.Length())
+  {
+    pos = pathName.Find(WCHAR_PATH_SEPARATOR, pos + 1);
+    if (pos < 0)
+      pos = pathName.Length();
+    if (!MyCreateDirectory(pathName.Left(pos)))
+      return false;
+  }
+  return true;
+}
+
+#endif
+
+bool DeleteFileAlways(LPCTSTR name)
+{
+  if (!MySetFileAttributes(name, 0))
+    return false;
+  if (::DeleteFile(name))
+    return true;
+  #ifdef WIN_LONG_PATH2
+  UString longPath;
+  if (GetLongPath(name, longPath))
+    return BOOLToBool(::DeleteFileW(longPath));
+  #endif
+  return false;
+}
+
+#ifndef _UNICODE
+bool DeleteFileAlways(LPCWSTR name)
+{  
+  if (!g_IsNT)
+    return DeleteFileAlways(GetSysPath(name));
+  if (!MySetFileAttributes(name, 0))
+    return false;
+  if (::DeleteFileW(name))
+    return true;
+  #ifdef WIN_LONG_PATH
+  UString longPath;
+  if (GetLongPath(name, longPath))
+    return BOOLToBool(::DeleteFileW(longPath));
+  #endif
+  return false;
+}
+#endif
+
+static bool RemoveDirectorySubItems2(const CSysString pathPrefix, const NFind::CFileInfo &fileInfo)
+{
+  if(fileInfo.IsDirectory())
+    return RemoveDirectoryWithSubItems(pathPrefix + fileInfo.Name);
+  return DeleteFileAlways(pathPrefix + fileInfo.Name);
+}
+
+bool RemoveDirectoryWithSubItems(const CSysString &path)
+{
+  NFind::CFileInfo fileInfo;
+  CSysString pathPrefix = path + NName::kDirDelimiter;
+  {
+    NFind::CEnumerator enumerator(pathPrefix + TCHAR(NName::kAnyStringWildcard));
+    while(enumerator.Next(fileInfo))
+      if (!RemoveDirectorySubItems2(pathPrefix, fileInfo))
+        return false;
+  }
+  if (!MySetFileAttributes(path, 0))
+    return false;
+  return MyRemoveDirectory(path);
+}
+
+#ifndef _UNICODE
+static bool RemoveDirectorySubItems2(const UString pathPrefix, const NFind::CFileInfoW &fileInfo)
+{
+  if(fileInfo.IsDirectory())
+    return RemoveDirectoryWithSubItems(pathPrefix + fileInfo.Name);
+  return DeleteFileAlways(pathPrefix + fileInfo.Name);
+}
+bool RemoveDirectoryWithSubItems(const UString &path)
+{
+  NFind::CFileInfoW fileInfo;
+  UString pathPrefix = path + UString(NName::kDirDelimiter);
+  {
+    NFind::CEnumeratorW enumerator(pathPrefix + UString(NName::kAnyStringWildcard));
+    while(enumerator.Next(fileInfo))
+      if (!RemoveDirectorySubItems2(pathPrefix, fileInfo))
+        return false;
+  }
+  if (!MySetFileAttributes(path, 0))
+    return false;
+  return MyRemoveDirectory(path);
+}
+#endif
+
+#ifndef _WIN32_WCE
+
+bool MyGetShortPathName(LPCTSTR longPath, CSysString &shortPath)
+{
+  DWORD needLength = ::GetShortPathName(longPath, shortPath.GetBuffer(MAX_PATH + 1), MAX_PATH + 1);
+  shortPath.ReleaseBuffer();
+  return (needLength > 0 && needLength < MAX_PATH);
+}
+
+bool MyGetFullPathName(LPCTSTR fileName, CSysString &resultPath, int &fileNamePartStartIndex)
+{
+  resultPath.Empty();
+  LPTSTR fileNamePointer = 0;
+  LPTSTR buffer = resultPath.GetBuffer(MAX_PATH);
+  DWORD needLength = ::GetFullPathName(fileName, MAX_PATH + 1, buffer, &fileNamePointer);
+  resultPath.ReleaseBuffer();
+  if (needLength == 0)
+    return false;
+  if (needLength >= MAX_PATH)
+  {
+    #ifdef WIN_LONG_PATH2
+    needLength++;
+    buffer = resultPath.GetBuffer(needLength + 1);
+    DWORD needLength2 = ::GetFullPathNameW(fileName, needLength, buffer, &fileNamePointer);
+    resultPath.ReleaseBuffer();
+    if (needLength2 == 0 || needLength2 > needLength)
+    #endif
+      return false;
+  }
+  if (fileNamePointer == 0)
+    fileNamePartStartIndex = lstrlen(fileName);
+  else
+    fileNamePartStartIndex = (int)(fileNamePointer - buffer);
+  return true;
+}
+
+#ifndef _UNICODE
+bool MyGetFullPathName(LPCWSTR fileName, UString &resultPath, int &fileNamePartStartIndex)
+{
+  resultPath.Empty();
+  if (g_IsNT)
+  {
+    LPWSTR fileNamePointer = 0;
+    LPWSTR buffer = resultPath.GetBuffer(MAX_PATH);
+    DWORD needLength = ::GetFullPathNameW(fileName, MAX_PATH + 1, buffer, &fileNamePointer);
+    resultPath.ReleaseBuffer();
+    if (needLength == 0)
+      return false;
+    if (needLength >= MAX_PATH)
+    {
+      #ifdef WIN_LONG_PATH
+      needLength++;
+      buffer = resultPath.GetBuffer(needLength + 1);
+      DWORD needLength2 = ::GetFullPathNameW(fileName, needLength, buffer, &fileNamePointer);
+      resultPath.ReleaseBuffer();
+      if (needLength2 == 0 || needLength2 > needLength)
+      #endif
+        return false;
+    }
+    if (fileNamePointer == 0)
+      fileNamePartStartIndex = MyStringLen(fileName);
+    else
+      fileNamePartStartIndex = (int)(fileNamePointer - buffer);
+  }
+  else
+  {
+    CSysString sysPath;
+    if (!MyGetFullPathName(GetSysPath(fileName), sysPath, fileNamePartStartIndex))
+      return false;
+    UString resultPath1 = GetUnicodePath(sysPath.Left(fileNamePartStartIndex));
+    UString resultPath2 = GetUnicodePath(sysPath.Mid(fileNamePartStartIndex));
+    fileNamePartStartIndex = resultPath1.Length();
+    resultPath = resultPath1 + resultPath2;
+  }
+  return true;
+}
+#endif
+
+
+bool MyGetFullPathName(LPCTSTR fileName, CSysString &path)
+{
+  int index;
+  return MyGetFullPathName(fileName, path, index);
+}
+
+#ifndef _UNICODE
+bool MyGetFullPathName(LPCWSTR fileName, UString &path)
+{
+  int index;
+  return MyGetFullPathName(fileName, path, index);
+}
+#endif
+
+bool GetOnlyName(LPCTSTR fileName, CSysString &resultName)
+{
+  int index;
+  if (!MyGetFullPathName(fileName, resultName, index))
+    return false;
+  resultName = resultName.Mid(index);
+  return true;
+}
+
+#ifndef _UNICODE
+bool GetOnlyName(LPCWSTR fileName, UString &resultName)
+{
+  int index;
+  if (!MyGetFullPathName(fileName, resultName, index))
+    return false;
+  resultName = resultName.Mid(index);
+  return true;
+}
+#endif
+
+bool GetOnlyDirPrefix(LPCTSTR fileName, CSysString &resultName)
+{
+  int index;
+  if (!MyGetFullPathName(fileName, resultName, index))
+    return false;
+  resultName = resultName.Left(index);
+  return true;
+}
+
+#ifndef _UNICODE
+bool GetOnlyDirPrefix(LPCWSTR fileName, UString &resultName)
+{
+  int index;
+  if (!MyGetFullPathName(fileName, resultName, index))
+    return false;
+  resultName = resultName.Left(index);
+  return true;
+}
+#endif
+
+bool MyGetCurrentDirectory(CSysString &path)
+{
+  DWORD needLength = ::GetCurrentDirectory(MAX_PATH + 1, path.GetBuffer(MAX_PATH + 1));
+  path.ReleaseBuffer();
+  return (needLength > 0 && needLength <= MAX_PATH);
+}
+
+#ifndef _UNICODE
+bool MySetCurrentDirectory(LPCWSTR path)
+{
+  if (g_IsNT)
+    return BOOLToBool(::SetCurrentDirectoryW(path));
+  return MySetCurrentDirectory(GetSysPath(path));
+}
+bool MyGetCurrentDirectory(UString &path)
+{
+  if (g_IsNT)
+  {
+    DWORD needLength = ::GetCurrentDirectoryW(MAX_PATH + 1, path.GetBuffer(MAX_PATH + 1));
+    path.ReleaseBuffer();
+    return (needLength > 0 && needLength <= MAX_PATH);
+  }
+  CSysString sysPath;
+  if (!MyGetCurrentDirectory(sysPath))
+    return false;
+  path = GetUnicodePath(sysPath);
+  return true;
+}
+#endif
+#endif
+
+bool MySearchPath(LPCTSTR path, LPCTSTR fileName, LPCTSTR extension, 
+  CSysString &resultPath, UINT32 &filePart)
+{
+  LPTSTR filePartPointer;
+  DWORD value = ::SearchPath(path, fileName, extension, 
+    MAX_PATH, resultPath.GetBuffer(MAX_PATH + 1), &filePartPointer);
+  filePart = (UINT32)(filePartPointer - (LPCTSTR)resultPath);
+  resultPath.ReleaseBuffer();
+  return (value > 0 && value <= MAX_PATH);
+}
+
+#ifndef _UNICODE
+bool MySearchPath(LPCWSTR path, LPCWSTR fileName, LPCWSTR extension, 
+  UString &resultPath, UINT32 &filePart)
+{
+  if (g_IsNT)
+  {
+    LPWSTR filePartPointer = 0;
+    DWORD value = ::SearchPathW(path, fileName, extension, 
+        MAX_PATH, resultPath.GetBuffer(MAX_PATH + 1), &filePartPointer);
+    filePart = (UINT32)(filePartPointer - (LPCWSTR)resultPath);
+    resultPath.ReleaseBuffer();
+    return (value > 0 && value <= MAX_PATH);
+  }
+  
+  CSysString sysPath;
+  if (!MySearchPath(
+      path != 0 ? (LPCTSTR)GetSysPath(path): 0,
+      fileName != 0 ? (LPCTSTR)GetSysPath(fileName): 0,
+      extension != 0 ? (LPCTSTR)GetSysPath(extension): 0,
+      sysPath, filePart))
+    return false;
+  UString resultPath1 = GetUnicodePath(sysPath.Left(filePart));
+  UString resultPath2 = GetUnicodePath(sysPath.Mid(filePart));
+  filePart = resultPath1.Length();
+  resultPath = resultPath1 + resultPath2;
+  return true;
+}
+#endif
+
+bool MyGetTempPath(CSysString &path)
+{
+  DWORD needLength = ::GetTempPath(MAX_PATH + 1, path.GetBuffer(MAX_PATH + 1));
+  path.ReleaseBuffer();
+  return (needLength > 0 && needLength <= MAX_PATH);
+}
+
+#ifndef _UNICODE
+bool MyGetTempPath(UString &path)
+{
+  path.Empty();
+  if (g_IsNT)
+  {
+    DWORD needLength = ::GetTempPathW(MAX_PATH + 1, path.GetBuffer(MAX_PATH + 1));
+    path.ReleaseBuffer();
+    return (needLength > 0 && needLength <= MAX_PATH);
+  }
+  CSysString sysPath;
+  if (!MyGetTempPath(sysPath))
+    return false;
+  path = GetUnicodePath(sysPath);
+  return true;
+}
+#endif
+
+UINT MyGetTempFileName(LPCTSTR dirPath, LPCTSTR prefix, CSysString &path)
+{
+  UINT number = ::GetTempFileName(dirPath, prefix, 0, path.GetBuffer(MAX_PATH + 1));
+  path.ReleaseBuffer();
+  return number;
+}
+
+#ifndef _UNICODE
+UINT MyGetTempFileName(LPCWSTR dirPath, LPCWSTR prefix, UString &path)
+{
+  if (g_IsNT)
+  {
+    UINT number = ::GetTempFileNameW(dirPath, prefix, 0, path.GetBuffer(MAX_PATH));
+    path.ReleaseBuffer();
+    return number;
+  }
+  CSysString sysPath;
+  UINT number = MyGetTempFileName(
+      dirPath ? (LPCTSTR)GetSysPath(dirPath): 0, 
+      prefix ? (LPCTSTR)GetSysPath(prefix): 0, 
+      sysPath);
+  path = GetUnicodePath(sysPath);
+  return number;
+}
+#endif
+
+UINT CTempFile::Create(LPCTSTR dirPath, LPCTSTR prefix, CSysString &resultPath)
+{
+  Remove();
+  UINT number = MyGetTempFileName(dirPath, prefix, resultPath);
+  if(number != 0)
+  {
+    _fileName = resultPath;
+    _mustBeDeleted = true;
+  }
+  return number;
+}
+
+bool CTempFile::Create(LPCTSTR prefix, CSysString &resultPath)
+{
+  CSysString tempPath;
+  if (!MyGetTempPath(tempPath))
+    return false;
+  if (Create(tempPath, prefix, resultPath) != 0)
+    return true;
+  if (!MyGetWindowsDirectory(tempPath))
+    return false;
+  return (Create(tempPath, prefix, resultPath) != 0);
+}
+
+bool CTempFile::Remove()
+{
+  if (!_mustBeDeleted)
+    return true;
+  _mustBeDeleted = !DeleteFileAlways(_fileName);
+  return !_mustBeDeleted;
+}
+
+#ifndef _UNICODE
+
+UINT CTempFileW::Create(LPCWSTR dirPath, LPCWSTR prefix, UString &resultPath)
+{
+  Remove();
+  UINT number = MyGetTempFileName(dirPath, prefix, resultPath);
+  if(number != 0)
+  {
+    _fileName = resultPath;
+    _mustBeDeleted = true;
+  }
+  return number;
+}
+
+bool CTempFileW::Create(LPCWSTR prefix, UString &resultPath)
+{
+  UString tempPath;
+  if (!MyGetTempPath(tempPath))
+    return false;
+  if (Create(tempPath, prefix, resultPath) != 0)
+    return true;
+  if (!MyGetWindowsDirectory(tempPath))
+    return false;
+  return (Create(tempPath, prefix, resultPath) != 0);
+}
+
+bool CTempFileW::Remove()
+{
+  if (!_mustBeDeleted)
+    return true;
+  _mustBeDeleted = !DeleteFileAlways(_fileName);
+  return !_mustBeDeleted;
+}
+
+#endif
+
+bool CreateTempDirectory(LPCTSTR prefix, CSysString &dirName)
+{
+  /*
+  CSysString prefix = tempPath + prefixChars;
+  CRandom random;
+  random.Init();
+  */
+  for (;;)
+  {
+    CTempFile tempFile;
+    if (!tempFile.Create(prefix, dirName))
+      return false;
+    if (!::DeleteFile(dirName))
+      return false;
+    /*
+    UINT32 randomNumber = random.Generate();
+    TCHAR randomNumberString[32];
+    _stprintf(randomNumberString, _T("%04X"), randomNumber);
+    dirName = prefix + randomNumberString;
+    */
+    if(NFind::DoesFileExist(dirName))
+      continue;
+    if (MyCreateDirectory(dirName))
+      return true;
+    if (::GetLastError() != ERROR_ALREADY_EXISTS)
+      return false;
+  }
+}
+
+bool CTempDirectory::Create(LPCTSTR prefix)
+{ 
+  Remove();
+  return (_mustBeDeleted = CreateTempDirectory(prefix, _tempDir)); 
+}
+
+#ifndef _UNICODE
+
+bool CreateTempDirectory(LPCWSTR prefix, UString &dirName)
+{
+  /*
+  CSysString prefix = tempPath + prefixChars;
+  CRandom random;
+  random.Init();
+  */
+  for (;;)
+  {
+    CTempFileW tempFile;
+    if (!tempFile.Create(prefix, dirName))
+      return false;
+    if (!DeleteFileAlways(dirName))
+      return false;
+    /*
+    UINT32 randomNumber = random.Generate();
+    TCHAR randomNumberString[32];
+    _stprintf(randomNumberString, _T("%04X"), randomNumber);
+    dirName = prefix + randomNumberString;
+    */
+    if(NFind::DoesFileExist(dirName))
+      continue;
+    if (MyCreateDirectory(dirName))
+      return true;
+    if (::GetLastError() != ERROR_ALREADY_EXISTS)
+      return false;
+  }
+}
+
+bool CTempDirectoryW::Create(LPCWSTR prefix)
+{ 
+  Remove();
+  return (_mustBeDeleted = CreateTempDirectory(prefix, _tempDir)); 
+}
+
+#endif
+
+}}}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/misc/libphysfs/lzma/CPP/Windows/FileDir.h	Mon Apr 10 12:06:43 2017 -0400
@@ -0,0 +1,178 @@
+// Windows/FileDir.h
+
+#ifndef __WINDOWS_FILEDIR_H
+#define __WINDOWS_FILEDIR_H
+
+#include "../Common/MyString.h"
+#include "Defs.h"
+
+namespace NWindows {
+namespace NFile {
+namespace NDirectory {
+
+#ifdef WIN_LONG_PATH
+bool GetLongPaths(LPCWSTR s1, LPCWSTR s2, UString &d1, UString &d2);
+#endif
+
+bool MyGetWindowsDirectory(CSysString &path);
+bool MyGetSystemDirectory(CSysString &path);
+#ifndef _UNICODE
+bool MyGetWindowsDirectory(UString &path);
+bool MyGetSystemDirectory(UString &path);
+#endif
+
+bool SetDirTime(LPCWSTR fileName, const FILETIME *creationTime, const FILETIME *lastAccessTime, const FILETIME *lastWriteTime);
+
+bool MySetFileAttributes(LPCTSTR fileName, DWORD fileAttributes);
+bool MyMoveFile(LPCTSTR existFileName, LPCTSTR newFileName);
+bool MyRemoveDirectory(LPCTSTR pathName);
+bool MyCreateDirectory(LPCTSTR pathName);
+bool CreateComplexDirectory(LPCTSTR pathName);
+bool DeleteFileAlways(LPCTSTR name);
+bool RemoveDirectoryWithSubItems(const CSysString &path);
+
+#ifndef _UNICODE
+bool MySetFileAttributes(LPCWSTR fileName, DWORD fileAttributes);
+bool MyMoveFile(LPCWSTR existFileName, LPCWSTR newFileName);
+bool MyRemoveDirectory(LPCWSTR pathName);
+bool MyCreateDirectory(LPCWSTR pathName);
+bool CreateComplexDirectory(LPCWSTR pathName);
+bool DeleteFileAlways(LPCWSTR name);
+bool RemoveDirectoryWithSubItems(const UString &path);
+#endif
+
+#ifndef _WIN32_WCE
+bool MyGetShortPathName(LPCTSTR longPath, CSysString &shortPath);
+
+bool MyGetFullPathName(LPCTSTR fileName, CSysString &resultPath, 
+    int &fileNamePartStartIndex);
+bool MyGetFullPathName(LPCTSTR fileName, CSysString &resultPath);
+bool GetOnlyName(LPCTSTR fileName, CSysString &resultName);
+bool GetOnlyDirPrefix(LPCTSTR fileName, CSysString &resultName);
+#ifndef _UNICODE
+bool MyGetFullPathName(LPCWSTR fileName, UString &resultPath, 
+    int &fileNamePartStartIndex);
+bool MyGetFullPathName(LPCWSTR fileName, UString &resultPath);
+bool GetOnlyName(LPCWSTR fileName, UString &resultName);
+bool GetOnlyDirPrefix(LPCWSTR fileName, UString &resultName);
+#endif
+
+inline bool MySetCurrentDirectory(LPCTSTR path)
+  { return BOOLToBool(::SetCurrentDirectory(path)); }
+bool MyGetCurrentDirectory(CSysString &resultPath);
+#ifndef _UNICODE
+bool MySetCurrentDirectory(LPCWSTR path);
+bool MyGetCurrentDirectory(UString &resultPath);
+#endif
+#endif
+
+bool MySearchPath(LPCTSTR path, LPCTSTR fileName, LPCTSTR extension, 
+  CSysString &resultPath, UINT32 &filePart);
+#ifndef _UNICODE
+bool MySearchPath(LPCWSTR path, LPCWSTR fileName, LPCWSTR extension, 
+  UString &resultPath, UINT32 &filePart);
+#endif
+
+inline bool MySearchPath(LPCTSTR path, LPCTSTR fileName, LPCTSTR extension, 
+  CSysString &resultPath)
+{
+  UINT32 value;
+  return MySearchPath(path, fileName, extension, resultPath, value);
+}
+
+#ifndef _UNICODE
+inline bool MySearchPath(LPCWSTR path, LPCWSTR fileName, LPCWSTR extension, 
+  UString &resultPath)
+{
+  UINT32 value;
+  return MySearchPath(path, fileName, extension, resultPath, value);
+}
+#endif
+
+bool MyGetTempPath(CSysString &resultPath);
+#ifndef _UNICODE
+bool MyGetTempPath(UString &resultPath);
+#endif
+
+UINT MyGetTempFileName(LPCTSTR dirPath, LPCTSTR prefix, CSysString &resultPath);
+#ifndef _UNICODE
+UINT MyGetTempFileName(LPCWSTR dirPath, LPCWSTR prefix, UString &resultPath);
+#endif
+
+class CTempFile
+{
+  bool _mustBeDeleted;
+  CSysString _fileName;
+public:
+  CTempFile(): _mustBeDeleted(false) {}
+  ~CTempFile() { Remove(); }
+  void DisableDeleting() { _mustBeDeleted = false; }
+  UINT Create(LPCTSTR dirPath, LPCTSTR prefix, CSysString &resultPath);
+  bool Create(LPCTSTR prefix, CSysString &resultPath);
+  bool Remove();
+};
+
+#ifdef _UNICODE
+typedef CTempFile CTempFileW;
+#else
+class CTempFileW
+{
+  bool _mustBeDeleted;
+  UString _fileName;
+public:
+  CTempFileW(): _mustBeDeleted(false) {}
+  ~CTempFileW() { Remove(); }
+  void DisableDeleting() { _mustBeDeleted = false; }
+  UINT Create(LPCWSTR dirPath, LPCWSTR prefix, UString &resultPath);
+  bool Create(LPCWSTR prefix, UString &resultPath);
+  bool Remove();
+};
+#endif
+
+bool CreateTempDirectory(LPCTSTR prefixChars, CSysString &dirName);
+
+class CTempDirectory
+{
+  bool _mustBeDeleted;
+  CSysString _tempDir;
+public:
+  const CSysString &GetPath() const { return _tempDir; }
+  CTempDirectory(): _mustBeDeleted(false) {}
+  ~CTempDirectory() { Remove();  }
+  bool Create(LPCTSTR prefix) ;
+  bool Remove()
+  {
+    if (!_mustBeDeleted)
+      return true;
+    _mustBeDeleted = !RemoveDirectoryWithSubItems(_tempDir);
+    return (!_mustBeDeleted);
+  }
+  void DisableDeleting() { _mustBeDeleted = false; }
+};
+
+#ifdef _UNICODE
+typedef CTempDirectory CTempDirectoryW;
+#else
+class CTempDirectoryW
+{
+  bool _mustBeDeleted;
+  UString _tempDir;
+public:
+  const UString &GetPath() const { return _tempDir; }
+  CTempDirectoryW(): _mustBeDeleted(false) {}
+  ~CTempDirectoryW() { Remove();  }
+  bool Create(LPCWSTR prefix) ;
+  bool Remove()
+  {
+    if (!_mustBeDeleted)
+      return true;
+    _mustBeDeleted = !RemoveDirectoryWithSubItems(_tempDir);
+    return (!_mustBeDeleted);
+  }
+  void DisableDeleting() { _mustBeDeleted = false; }
+};
+#endif
+
+}}}
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/misc/libphysfs/lzma/CPP/Windows/FileFind.cpp	Mon Apr 10 12:06:43 2017 -0400
@@ -0,0 +1,408 @@
+// Windows/FileFind.cpp
+
+#include "StdAfx.h"
+
+#include "FileFind.h"
+#ifndef _UNICODE
+#include "../Common/StringConvert.h"
+#endif
+
+#ifndef _UNICODE
+extern bool g_IsNT;
+#endif
+
+namespace NWindows {
+namespace NFile {
+
+#if defined(WIN_LONG_PATH) && defined(_UNICODE)
+#define WIN_LONG_PATH2
+#endif
+
+bool GetLongPath(LPCWSTR fileName, UString &res);
+
+namespace NFind {
+
+static const TCHAR kDot = TEXT('.');
+
+bool CFileInfo::IsDots() const
+{ 
+  if (!IsDirectory() || Name.IsEmpty())
+    return false;
+  if (Name[0] != kDot)
+    return false;
+  return Name.Length() == 1 || (Name[1] == kDot && Name.Length() == 2);
+}
+
+#ifndef _UNICODE
+bool CFileInfoW::IsDots() const
+{ 
+  if (!IsDirectory() || Name.IsEmpty())
+    return false;
+  if (Name[0] != kDot)
+    return false;
+  return Name.Length() == 1 || (Name[1] == kDot && Name.Length() == 2);
+}
+#endif
+
+static void ConvertWIN32_FIND_DATA_To_FileInfo(
+    const WIN32_FIND_DATA &findData,
+    CFileInfo &fileInfo)
+{
+  fileInfo.Attributes = findData.dwFileAttributes; 
+  fileInfo.CreationTime = findData.ftCreationTime;  
+  fileInfo.LastAccessTime = findData.ftLastAccessTime; 
+  fileInfo.LastWriteTime = findData.ftLastWriteTime;
+  fileInfo.Size  = (((UInt64)findData.nFileSizeHigh) << 32) + findData.nFileSizeLow; 
+  fileInfo.Name = findData.cFileName;
+  #ifndef _WIN32_WCE
+  fileInfo.ReparseTag = findData.dwReserved0;
+  #else
+  fileInfo.ObjectID = findData.dwOID;
+  #endif
+}
+
+#ifndef _UNICODE
+
+static inline UINT GetCurrentCodePage() { return ::AreFileApisANSI() ? CP_ACP : CP_OEMCP; } 
+
+static void ConvertWIN32_FIND_DATA_To_FileInfo(
+    const WIN32_FIND_DATAW &findData,
+    CFileInfoW &fileInfo)
+{
+  fileInfo.Attributes = findData.dwFileAttributes; 
+  fileInfo.CreationTime = findData.ftCreationTime;  
+  fileInfo.LastAccessTime = findData.ftLastAccessTime; 
+  fileInfo.LastWriteTime = findData.ftLastWriteTime;
+  fileInfo.Size  = (((UInt64)findData.nFileSizeHigh) << 32) + findData.nFileSizeLow; 
+  fileInfo.Name = findData.cFileName;
+  #ifndef _WIN32_WCE
+  fileInfo.ReparseTag = findData.dwReserved0;
+  #else
+  fileInfo.ObjectID = findData.dwOID;
+  #endif
+}
+
+static void ConvertWIN32_FIND_DATA_To_FileInfo(
+    const WIN32_FIND_DATA &findData,
+    CFileInfoW &fileInfo)
+{
+  fileInfo.Attributes = findData.dwFileAttributes; 
+  fileInfo.CreationTime = findData.ftCreationTime;  
+  fileInfo.LastAccessTime = findData.ftLastAccessTime; 
+  fileInfo.LastWriteTime = findData.ftLastWriteTime;
+  fileInfo.Size  = (((UInt64)findData.nFileSizeHigh) << 32) + findData.nFileSizeLow; 
+  fileInfo.Name = GetUnicodeString(findData.cFileName, GetCurrentCodePage());
+  #ifndef _WIN32_WCE
+  fileInfo.ReparseTag = findData.dwReserved0;
+  #else
+  fileInfo.ObjectID = findData.dwOID;
+  #endif
+}
+#endif
+  
+////////////////////////////////
+// CFindFile
+
+bool CFindFile::Close()
+{
+  if (_handle == INVALID_HANDLE_VALUE)
+    return true;
+  if (!::FindClose(_handle))
+    return false;
+  _handle = INVALID_HANDLE_VALUE;
+  return true;
+}
+
+          
+bool CFindFile::FindFirst(LPCTSTR wildcard, CFileInfo &fileInfo)
+{
+  if (!Close())
+    return false;
+  WIN32_FIND_DATA findData;
+  _handle = ::FindFirstFile(wildcard, &findData);
+  #ifdef WIN_LONG_PATH2
+  if (_handle == INVALID_HANDLE_VALUE)
+  {
+    UString longPath;
+    if (GetLongPath(wildcard, longPath))
+      _handle = ::FindFirstFileW(longPath, &findData);
+  }
+  #endif
+  if (_handle == INVALID_HANDLE_VALUE)
+    return false;
+  ConvertWIN32_FIND_DATA_To_FileInfo(findData, fileInfo);
+  return true;
+}
+
+#ifndef _UNICODE
+bool CFindFile::FindFirst(LPCWSTR wildcard, CFileInfoW &fileInfo)
+{
+  if (!Close())
+    return false;
+  if (g_IsNT)
+  {
+    WIN32_FIND_DATAW findData;
+    _handle = ::FindFirstFileW(wildcard, &findData);
+    #ifdef WIN_LONG_PATH
+    if (_handle == INVALID_HANDLE_VALUE)
+    {
+      UString longPath;
+      if (GetLongPath(wildcard, longPath))
+        _handle = ::FindFirstFileW(longPath, &findData);
+    }
+    #endif
+    if (_handle != INVALID_HANDLE_VALUE)
+      ConvertWIN32_FIND_DATA_To_FileInfo(findData, fileInfo);
+  }
+  else
+  {
+    WIN32_FIND_DATAA findData;
+    _handle = ::FindFirstFileA(UnicodeStringToMultiByte(wildcard, 
+        GetCurrentCodePage()), &findData);
+    if (_handle != INVALID_HANDLE_VALUE)
+      ConvertWIN32_FIND_DATA_To_FileInfo(findData, fileInfo);
+  }
+  return (_handle != INVALID_HANDLE_VALUE);
+}
+#endif
+
+bool CFindFile::FindNext(CFileInfo &fileInfo)
+{
+  WIN32_FIND_DATA findData;
+  bool result = BOOLToBool(::FindNextFile(_handle, &findData));
+  if (result)
+    ConvertWIN32_FIND_DATA_To_FileInfo(findData, fileInfo);
+  return result;
+}
+
+#ifndef _UNICODE
+bool CFindFile::FindNext(CFileInfoW &fileInfo)
+{
+  if (g_IsNT)
+  {
+    WIN32_FIND_DATAW findData;
+    if (!::FindNextFileW(_handle, &findData))
+      return false;
+    ConvertWIN32_FIND_DATA_To_FileInfo(findData, fileInfo);
+  }
+  else
+  {
+    WIN32_FIND_DATAA findData;
+    if (!::FindNextFileA(_handle, &findData))
+      return false;
+    ConvertWIN32_FIND_DATA_To_FileInfo(findData, fileInfo);
+  }
+  return true;
+}
+#endif
+
+bool FindFile(LPCTSTR wildcard, CFileInfo &fileInfo)
+{
+  CFindFile finder;
+  return finder.FindFirst(wildcard, fileInfo);
+}
+
+#ifndef _UNICODE
+bool FindFile(LPCWSTR wildcard, CFileInfoW &fileInfo)
+{
+  CFindFile finder;
+  return finder.FindFirst(wildcard, fileInfo);
+}
+#endif
+
+bool DoesFileExist(LPCTSTR name)
+{
+  CFileInfo fileInfo;
+  return FindFile(name, fileInfo);
+}
+
+#ifndef _UNICODE
+bool DoesFileExist(LPCWSTR name)
+{
+  CFileInfoW fileInfo;
+  return FindFile(name, fileInfo);
+}
+#endif
+
+/////////////////////////////////////
+// CEnumerator
+
+bool CEnumerator::NextAny(CFileInfo &fileInfo)
+{
+  if (_findFile.IsHandleAllocated())
+    return _findFile.FindNext(fileInfo);
+  else
+    return _findFile.FindFirst(_wildcard, fileInfo);
+}
+
+bool CEnumerator::Next(CFileInfo &fileInfo)
+{
+  for (;;)
+  {
+    if (!NextAny(fileInfo))
+      return false;
+    if (!fileInfo.IsDots())
+      return true;
+  }
+}
+
+bool CEnumerator::Next(CFileInfo &fileInfo, bool &found)
+{
+  if (Next(fileInfo))
+  {
+    found = true;
+    return true;
+  }
+  found = false;
+  return (::GetLastError() == ERROR_NO_MORE_FILES);
+}
+
+#ifndef _UNICODE
+bool CEnumeratorW::NextAny(CFileInfoW &fileInfo)
+{
+  if (_findFile.IsHandleAllocated())
+    return _findFile.FindNext(fileInfo);
+  else
+    return _findFile.FindFirst(_wildcard, fileInfo);
+}
+
+bool CEnumeratorW::Next(CFileInfoW &fileInfo)
+{
+  for (;;)
+  {
+    if (!NextAny(fileInfo))
+      return false;
+    if (!fileInfo.IsDots())
+      return true;
+  }
+}
+
+bool CEnumeratorW::Next(CFileInfoW &fileInfo, bool &found)
+{
+  if (Next(fileInfo))
+  {
+    found = true;
+    return true;
+  }
+  found = false;
+  return (::GetLastError() == ERROR_NO_MORE_FILES);
+}
+
+#endif
+
+////////////////////////////////
+// CFindChangeNotification
+// FindFirstChangeNotification can return 0. MSDN doesn't tell about it.
+
+bool CFindChangeNotification::Close()
+{
+  if (!IsHandleAllocated())
+    return true;
+  if (!::FindCloseChangeNotification(_handle))
+    return false;
+  _handle = INVALID_HANDLE_VALUE;
+  return true;
+}
+           
+HANDLE CFindChangeNotification::FindFirst(LPCTSTR pathName, bool watchSubtree, DWORD notifyFilter)
+{
+  _handle = ::FindFirstChangeNotification(pathName, BoolToBOOL(watchSubtree), notifyFilter);
+  #ifdef WIN_LONG_PATH2
+  if (!IsHandleAllocated())
+  {
+    UString longPath;
+    if (GetLongPath(pathName, longPath))
+      _handle = ::FindFirstChangeNotificationW(longPath, BoolToBOOL(watchSubtree), notifyFilter);
+  }
+  #endif
+  return _handle;
+}
+
+#ifndef _UNICODE
+HANDLE CFindChangeNotification::FindFirst(LPCWSTR pathName, bool watchSubtree, DWORD notifyFilter)
+{
+  if (!g_IsNT)
+    return FindFirst(UnicodeStringToMultiByte(pathName, GetCurrentCodePage()), watchSubtree, notifyFilter);
+  _handle = ::FindFirstChangeNotificationW(pathName, BoolToBOOL(watchSubtree), notifyFilter);
+  #ifdef WIN_LONG_PATH
+  if (!IsHandleAllocated())
+  {
+    UString longPath;
+    if (GetLongPath(pathName, longPath))
+      _handle = ::FindFirstChangeNotificationW(longPath, BoolToBOOL(watchSubtree), notifyFilter);
+  }
+  #endif
+  return _handle;
+}
+#endif
+
+#ifndef _WIN32_WCE
+bool MyGetLogicalDriveStrings(CSysStringVector &driveStrings)
+{
+  driveStrings.Clear();
+  UINT32 size = GetLogicalDriveStrings(0, NULL); 
+  if (size == 0)
+    return false;
+  CSysString buffer;
+  UINT32 newSize = GetLogicalDriveStrings(size, buffer.GetBuffer(size)); 
+  if (newSize == 0)
+    return false;
+  if (newSize > size)
+    return false;
+  CSysString string;
+  for(UINT32 i = 0; i < newSize; i++)
+  {
+    TCHAR c = buffer[i];
+    if (c == TEXT('\0'))
+    {
+      driveStrings.Add(string);
+      string.Empty();
+    }
+    else
+      string += c;
+  }
+  if (!string.IsEmpty())
+    return false;
+  return true;
+}
+
+#ifndef _UNICODE
+bool MyGetLogicalDriveStrings(UStringVector &driveStrings)
+{
+  driveStrings.Clear();
+  if (g_IsNT)
+  {
+    UINT32 size = GetLogicalDriveStringsW(0, NULL); 
+    if (size == 0)
+      return false;
+    UString buffer;
+    UINT32 newSize = GetLogicalDriveStringsW(size, buffer.GetBuffer(size)); 
+    if (newSize == 0)
+      return false;
+    if (newSize > size)
+      return false;
+    UString string;
+    for(UINT32 i = 0; i < newSize; i++)
+    {
+      WCHAR c = buffer[i];
+      if (c == L'\0')
+      {
+        driveStrings.Add(string);
+        string.Empty();
+      }
+      else
+        string += c;
+    }
+    return string.IsEmpty();
+  }
+  CSysStringVector driveStringsA;
+  bool res = MyGetLogicalDriveStrings(driveStringsA);
+  for (int i = 0; i < driveStringsA.Size(); i++)
+    driveStrings.Add(GetUnicodeString(driveStringsA[i]));
+  return res;
+}
+#endif
+
+#endif
+
+}}}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/misc/libphysfs/lzma/CPP/Windows/FileFind.h	Mon Apr 10 12:06:43 2017 -0400
@@ -0,0 +1,153 @@
+// Windows/FileFind.h
+
+#ifndef __WINDOWS_FILEFIND_H
+#define __WINDOWS_FILEFIND_H
+
+#include "../Common/MyString.h"
+#include "../Common/Types.h"
+#include "FileName.h"
+#include "Defs.h"
+
+namespace NWindows {
+namespace NFile {
+namespace NFind {
+
+namespace NAttributes
+{
+  inline bool IsReadOnly(DWORD attributes) { return (attributes & FILE_ATTRIBUTE_READONLY) != 0; }
+  inline bool IsHidden(DWORD attributes) { return (attributes & FILE_ATTRIBUTE_HIDDEN) != 0; }
+  inline bool IsSystem(DWORD attributes) { return (attributes & FILE_ATTRIBUTE_SYSTEM) != 0; }
+  inline bool IsDirectory(DWORD attributes) { return (attributes & FILE_ATTRIBUTE_DIRECTORY) != 0; }
+  inline bool IsArchived(DWORD attributes) { return (attributes & FILE_ATTRIBUTE_ARCHIVE) != 0; }
+  inline bool IsCompressed(DWORD attributes) { return (attributes & FILE_ATTRIBUTE_COMPRESSED) != 0; }
+  inline bool IsEncrypted(DWORD attributes) { return (attributes & FILE_ATTRIBUTE_ENCRYPTED) != 0; }
+}
+
+class CFileInfoBase
+{ 
+  bool MatchesMask(UINT32 mask) const  { return ((Attributes & mask) != 0); }
+public:
+  DWORD Attributes;
+  FILETIME CreationTime;  
+  FILETIME LastAccessTime; 
+  FILETIME LastWriteTime;
+  UInt64 Size;
+  
+  #ifndef _WIN32_WCE
+  UINT32 ReparseTag;
+  #else
+  DWORD ObjectID; 
+  #endif
+
+  bool IsArchived() const { return MatchesMask(FILE_ATTRIBUTE_ARCHIVE); }
+  bool IsCompressed() const { return MatchesMask(FILE_ATTRIBUTE_COMPRESSED); }
+  bool IsDirectory() const { return MatchesMask(FILE_ATTRIBUTE_DIRECTORY); }
+  bool IsEncrypted() const { return MatchesMask(FILE_ATTRIBUTE_ENCRYPTED); }
+  bool IsHidden() const { return MatchesMask(FILE_ATTRIBUTE_HIDDEN); }
+  bool IsNormal() const { return MatchesMask(FILE_ATTRIBUTE_NORMAL); }
+  bool IsOffline() const { return MatchesMask(FILE_ATTRIBUTE_OFFLINE); }
+  bool IsReadOnly() const { return MatchesMask(FILE_ATTRIBUTE_READONLY); }
+  bool HasReparsePoint() const { return MatchesMask(FILE_ATTRIBUTE_REPARSE_POINT); }
+  bool IsSparse() const { return MatchesMask(FILE_ATTRIBUTE_SPARSE_FILE); }
+  bool IsSystem() const { return MatchesMask(FILE_ATTRIBUTE_SYSTEM); }
+  bool IsTemporary() const { return MatchesMask(FILE_ATTRIBUTE_TEMPORARY); }
+};
+
+class CFileInfo: public CFileInfoBase
+{ 
+public:
+  CSysString Name;
+  bool IsDots() const;
+};
+
+#ifdef _UNICODE
+typedef CFileInfo CFileInfoW;
+#else
+class CFileInfoW: public CFileInfoBase
+{ 
+public:
+  UString Name;
+  bool IsDots() const;
+};
+#endif
+
+class CFindFile
+{
+  friend class CEnumerator;
+  HANDLE _handle;
+public:
+  bool IsHandleAllocated() const { return _handle != INVALID_HANDLE_VALUE; }
+  CFindFile(): _handle(INVALID_HANDLE_VALUE) {}
+  ~CFindFile() {  Close(); }
+  bool FindFirst(LPCTSTR wildcard, CFileInfo &fileInfo);
+  bool FindNext(CFileInfo &fileInfo);
+  #ifndef _UNICODE
+  bool FindFirst(LPCWSTR wildcard, CFileInfoW &fileInfo);
+  bool FindNext(CFileInfoW &fileInfo);
+  #endif
+  bool Close();
+};
+
+bool FindFile(LPCTSTR wildcard, CFileInfo &fileInfo);
+
+bool DoesFileExist(LPCTSTR name);
+#ifndef _UNICODE
+bool FindFile(LPCWSTR wildcard, CFileInfoW &fileInfo);
+bool DoesFileExist(LPCWSTR name);
+#endif
+
+class CEnumerator
+{
+  CFindFile _findFile;
+  CSysString _wildcard;
+  bool NextAny(CFileInfo &fileInfo);
+public:
+  CEnumerator(): _wildcard(NName::kAnyStringWildcard) {}
+  CEnumerator(const CSysString &wildcard): _wildcard(wildcard) {}
+  bool Next(CFileInfo &fileInfo);
+  bool Next(CFileInfo &fileInfo, bool &found);
+};
+
+#ifdef _UNICODE
+typedef CEnumerator CEnumeratorW;
+#else
+class CEnumeratorW
+{
+  CFindFile _findFile;
+  UString _wildcard;
+  bool NextAny(CFileInfoW &fileInfo);
+public:
+  CEnumeratorW(): _wildcard(NName::kAnyStringWildcard) {}
+  CEnumeratorW(const UString &wildcard): _wildcard(wildcard) {}
+  bool Next(CFileInfoW &fileInfo);
+  bool Next(CFileInfoW &fileInfo, bool &found);
+};
+#endif
+
+class CFindChangeNotification
+{
+  HANDLE _handle;
+public:
+  operator HANDLE () { return _handle; }
+  bool IsHandleAllocated() const { return _handle != INVALID_HANDLE_VALUE && _handle != 0; }
+  CFindChangeNotification(): _handle(INVALID_HANDLE_VALUE) {}
+  ~CFindChangeNotification() { Close(); }
+  bool Close();
+  HANDLE FindFirst(LPCTSTR pathName, bool watchSubtree, DWORD notifyFilter);
+  #ifndef _UNICODE
+  HANDLE FindFirst(LPCWSTR pathName, bool watchSubtree, DWORD notifyFilter);
+  #endif
+  bool FindNext() { return BOOLToBool(::FindNextChangeNotification(_handle)); }
+};
+
+#ifndef _WIN32_WCE
+bool MyGetLogicalDriveStrings(CSysStringVector &driveStrings);
+#ifndef _UNICODE
+bool MyGetLogicalDriveStrings(UStringVector &driveStrings);
+#endif
+#endif
+
+}}}
+
+#endif
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/misc/libphysfs/lzma/CPP/Windows/FileIO.cpp	Mon Apr 10 12:06:43 2017 -0400
@@ -0,0 +1,318 @@
+// Windows/FileIO.cpp
+
+#include "StdAfx.h"
+
+#include "FileIO.h"
+#include "Defs.h"
+#ifdef WIN_LONG_PATH
+#include "../Common/MyString.h"
+#endif
+#ifndef _UNICODE
+#include "../Common/StringConvert.h"
+#endif
+
+#ifndef _UNICODE
+extern bool g_IsNT;
+#endif
+
+namespace NWindows {
+namespace NFile {
+
+#if defined(WIN_LONG_PATH) && defined(_UNICODE)
+#define WIN_LONG_PATH2
+#endif
+
+#ifdef WIN_LONG_PATH
+bool GetLongPathBase(LPCWSTR s, UString &res)
+{
+  res.Empty();
+  int len = MyStringLen(s);
+  wchar_t c = s[0];
+  if (len < 1 || c == L'\\' || c == L'.' && (len == 1 || len == 2 && s[1] == L'.'))
+    return true;
+  UString curDir;
+  bool isAbs = false;
+  if (len > 3)
+    isAbs = (s[1] == L':' && s[2] == L'\\' && (c >= L'a' && c <= L'z' || c >= L'A' && c <= L'Z'));
+
+  if (!isAbs)
+    {
+      DWORD needLength = ::GetCurrentDirectoryW(MAX_PATH + 1, curDir.GetBuffer(MAX_PATH + 1));
+      curDir.ReleaseBuffer();
+      if (needLength == 0 || needLength > MAX_PATH)
+        return false;
+      if (curDir[curDir.Length() - 1] != L'\\')
+        curDir += L'\\';
+    }
+  res = UString(L"\\\\?\\") + curDir + s;
+  return true;
+}
+
+bool GetLongPath(LPCWSTR path, UString &longPath)
+{
+  if (GetLongPathBase(path, longPath)) 
+    return !longPath.IsEmpty();
+  return false;
+}
+#endif
+
+namespace NIO {
+
+CFileBase::~CFileBase() { Close(); }
+
+bool CFileBase::Create(LPCTSTR fileName, DWORD desiredAccess,
+    DWORD shareMode, DWORD creationDisposition, DWORD flagsAndAttributes)
+{
+  if (!Close())
+    return false;
+  _handle = ::CreateFile(fileName, desiredAccess, shareMode, 
+      (LPSECURITY_ATTRIBUTES)NULL, creationDisposition, 
+      flagsAndAttributes, (HANDLE)NULL);
+  #ifdef WIN_LONG_PATH2
+  if (_handle == INVALID_HANDLE_VALUE)
+  {
+    UString longPath;
+    if (GetLongPath(fileName, longPath))
+      _handle = ::CreateFileW(longPath, desiredAccess, shareMode, 
+        (LPSECURITY_ATTRIBUTES)NULL, creationDisposition, 
+        flagsAndAttributes, (HANDLE)NULL);
+  }
+  #endif
+  return (_handle != INVALID_HANDLE_VALUE);
+}
+
+#ifndef _UNICODE
+bool CFileBase::Create(LPCWSTR fileName, DWORD desiredAccess,
+    DWORD shareMode, DWORD creationDisposition, DWORD flagsAndAttributes)
+{
+  if (!g_IsNT)
+    return Create(UnicodeStringToMultiByte(fileName, ::AreFileApisANSI() ? CP_ACP : CP_OEMCP), 
+      desiredAccess, shareMode, creationDisposition, flagsAndAttributes);
+  if (!Close())
+    return false;
+  _handle = ::CreateFileW(fileName, desiredAccess, shareMode, 
+    (LPSECURITY_ATTRIBUTES)NULL, creationDisposition, 
+    flagsAndAttributes, (HANDLE)NULL);
+  #ifdef WIN_LONG_PATH
+  if (_handle == INVALID_HANDLE_VALUE)
+  {
+    UString longPath;
+    if (GetLongPath(fileName, longPath))
+      _handle = ::CreateFileW(longPath, desiredAccess, shareMode, 
+        (LPSECURITY_ATTRIBUTES)NULL, creationDisposition, 
+        flagsAndAttributes, (HANDLE)NULL);
+  }
+  #endif
+  return (_handle != INVALID_HANDLE_VALUE);
+}
+#endif
+
+bool CFileBase::Close()
+{
+  if (_handle == INVALID_HANDLE_VALUE)
+    return true;
+  if (!::CloseHandle(_handle))
+    return false;
+  _handle = INVALID_HANDLE_VALUE;
+  return true;
+}
+
+bool CFileBase::GetPosition(UInt64 &position) const
+{
+  return Seek(0, FILE_CURRENT, position);
+}
+
+bool CFileBase::GetLength(UInt64 &length) const
+{
+  DWORD sizeHigh;
+  DWORD sizeLow = ::GetFileSize(_handle, &sizeHigh);
+  if(sizeLow == 0xFFFFFFFF)
+    if(::GetLastError() != NO_ERROR)
+      return false;
+  length = (((UInt64)sizeHigh) << 32) + sizeLow;
+  return true;
+}
+
+bool CFileBase::Seek(Int64 distanceToMove, DWORD moveMethod, UInt64 &newPosition) const
+{
+  LARGE_INTEGER value;
+  value.QuadPart = distanceToMove;
+  value.LowPart = ::SetFilePointer(_handle, value.LowPart, &value.HighPart, moveMethod);
+  if (value.LowPart == 0xFFFFFFFF)
+    if(::GetLastError() != NO_ERROR) 
+      return false;
+  newPosition = value.QuadPart;
+  return true;
+}
+
+bool CFileBase::Seek(UInt64 position, UInt64 &newPosition)
+{
+  return Seek(position, FILE_BEGIN, newPosition);
+}
+
+bool CFileBase::SeekToBegin()
+{
+  UInt64 newPosition;
+  return Seek(0, newPosition);
+}
+
+bool CFileBase::SeekToEnd(UInt64 &newPosition)
+{
+  return Seek(0, FILE_END, newPosition);
+}
+
+bool CFileBase::GetFileInformation(CByHandleFileInfo &fileInfo) const
+{
+  BY_HANDLE_FILE_INFORMATION winFileInfo;
+  if(!::GetFileInformationByHandle(_handle, &winFileInfo))
+    return false;
+  fileInfo.Attributes = winFileInfo.dwFileAttributes;
+  fileInfo.CreationTime = winFileInfo.ftCreationTime;
+  fileInfo.LastAccessTime = winFileInfo.ftLastAccessTime;
+  fileInfo.LastWriteTime = winFileInfo.ftLastWriteTime;
+  fileInfo.VolumeSerialNumber = winFileInfo.dwFileAttributes; 
+  fileInfo.Size = (((UInt64)winFileInfo.nFileSizeHigh) << 32) +  winFileInfo.nFileSizeLow;
+  fileInfo.NumberOfLinks = winFileInfo.nNumberOfLinks;
+  fileInfo.FileIndex = (((UInt64)winFileInfo.nFileIndexHigh) << 32) + winFileInfo.nFileIndexLow;
+  return true;
+}
+
+/////////////////////////
+// CInFile
+
+bool CInFile::Open(LPCTSTR fileName, DWORD shareMode, DWORD creationDisposition, DWORD flagsAndAttributes)
+  { return Create(fileName, GENERIC_READ, shareMode, creationDisposition, flagsAndAttributes); }
+
+bool CInFile::OpenShared(LPCTSTR fileName, bool shareForWrite)
+{ return Open(fileName, FILE_SHARE_READ | (shareForWrite ? FILE_SHARE_WRITE : 0), OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL); }
+
+bool CInFile::Open(LPCTSTR fileName)
+  { return OpenShared(fileName, false); }
+
+#ifndef _UNICODE
+bool CInFile::Open(LPCWSTR fileName, DWORD shareMode, DWORD creationDisposition, DWORD flagsAndAttributes)
+  { return Create(fileName, GENERIC_READ, shareMode, creationDisposition, flagsAndAttributes); }
+
+bool CInFile::OpenShared(LPCWSTR fileName, bool shareForWrite)
+{ return Open(fileName, FILE_SHARE_READ | (shareForWrite ? FILE_SHARE_WRITE : 0), OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL); }
+
+bool CInFile::Open(LPCWSTR fileName)
+  { return OpenShared(fileName, false); }
+#endif
+
+// 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"
+
+static UInt32 kChunkSizeMax = (1 << 22);
+
+bool CInFile::ReadPart(void *data, UInt32 size, UInt32 &processedSize)
+{
+  if (size > kChunkSizeMax)
+    size = kChunkSizeMax;
+  DWORD processedLoc = 0;
+  bool res = BOOLToBool(::ReadFile(_handle, data, size, &processedLoc, NULL));
+  processedSize = (UInt32)processedLoc;
+  return res;
+}
+
+bool CInFile::Read(void *data, UInt32 size, UInt32 &processedSize)
+{
+  processedSize = 0;
+  do
+  {
+    UInt32 processedLoc = 0;
+    bool res = ReadPart(data, size, processedLoc);
+    processedSize += processedLoc;
+    if (!res)
+      return false;
+    if (processedLoc == 0)
+      return true;
+    data = (void *)((unsigned char *)data + processedLoc);
+    size -= processedLoc;
+  }
+  while (size > 0);
+  return true;
+}
+
+/////////////////////////
+// COutFile
+
+bool COutFile::Open(LPCTSTR fileName, DWORD shareMode, DWORD creationDisposition, DWORD flagsAndAttributes)
+  { return CFileBase::Create(fileName, GENERIC_WRITE, shareMode, creationDisposition, flagsAndAttributes); }
+
+static inline DWORD GetCreationDisposition(bool createAlways)
+  { return createAlways? CREATE_ALWAYS: CREATE_NEW; }
+
+bool COutFile::Open(LPCTSTR fileName, DWORD creationDisposition)
+  { return Open(fileName, FILE_SHARE_READ, creationDisposition, FILE_ATTRIBUTE_NORMAL); }
+
+bool COutFile::Create(LPCTSTR fileName, bool createAlways)
+  { return Open(fileName, GetCreationDisposition(createAlways)); }
+
+#ifndef _UNICODE
+
+bool COutFile::Open(LPCWSTR fileName, DWORD shareMode, DWORD creationDisposition, DWORD flagsAndAttributes)
+  { return CFileBase::Create(fileName, GENERIC_WRITE, shareMode,      creationDisposition, flagsAndAttributes); }
+
+bool COutFile::Open(LPCWSTR fileName, DWORD creationDisposition)
+  { return Open(fileName, FILE_SHARE_READ,  creationDisposition, FILE_ATTRIBUTE_NORMAL); }
+
+bool COutFile::Create(LPCWSTR fileName, bool createAlways)
+  { return Open(fileName, GetCreationDisposition(createAlways)); }
+
+#endif
+
+bool COutFile::SetTime(const FILETIME *creationTime, const FILETIME *lastAccessTime, const FILETIME *lastWriteTime)
+  { return BOOLToBool(::SetFileTime(_handle, creationTime, lastAccessTime, lastWriteTime)); }
+
+bool COutFile::SetLastWriteTime(const FILETIME *lastWriteTime)
+  {  return SetTime(NULL, NULL, lastWriteTime); }
+
+bool COutFile::WritePart(const void *data, UInt32 size, UInt32 &processedSize)
+{
+  if (size > kChunkSizeMax)
+    size = kChunkSizeMax;
+  DWORD processedLoc = 0;
+  bool res = BOOLToBool(::WriteFile(_handle, data, size, &processedLoc, NULL));
+  processedSize = (UInt32)processedLoc;
+  return res;
+}
+
+bool COutFile::Write(const void *data, UInt32 size, UInt32 &processedSize)
+{
+  processedSize = 0;
+  do
+  {
+    UInt32 processedLoc = 0;
+    bool res = WritePart(data, size, processedLoc);
+    processedSize += processedLoc;
+    if (!res)
+      return false;
+    if (processedLoc == 0)
+      return true;
+    data = (const void *)((const unsigned char *)data + processedLoc);
+    size -= processedLoc;
+  }
+  while (size > 0);
+  return true;
+}
+
+bool COutFile::SetEndOfFile() { return BOOLToBool(::SetEndOfFile(_handle)); }
+
+bool COutFile::SetLength(UInt64 length)
+{
+  UInt64 newPosition;
+  if(!Seek(length, newPosition))
+    return false;
+  if(newPosition != length)
+    return false;
+  return SetEndOfFile();
+}
+
+}}}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/misc/libphysfs/lzma/CPP/Windows/FileIO.h	Mon Apr 10 12:06:43 2017 -0400
@@ -0,0 +1,99 @@
+// Windows/FileIO.h
+
+#ifndef __WINDOWS_FILEIO_H
+#define __WINDOWS_FILEIO_H
+
+#include "../Common/Types.h"
+
+namespace NWindows {
+namespace NFile {
+namespace NIO {
+
+struct CByHandleFileInfo
+{ 
+  DWORD    Attributes; 
+  FILETIME CreationTime; 
+  FILETIME LastAccessTime; 
+  FILETIME LastWriteTime; 
+  DWORD    VolumeSerialNumber; 
+  UInt64   Size;
+  DWORD    NumberOfLinks; 
+  UInt64   FileIndex; 
+};
+
+class CFileBase
+{
+protected:
+  HANDLE _handle;
+  bool Create(LPCTSTR fileName, DWORD desiredAccess,
+      DWORD shareMode, DWORD creationDisposition,  DWORD flagsAndAttributes);
+  #ifndef _UNICODE
+  bool Create(LPCWSTR fileName, DWORD desiredAccess,
+      DWORD shareMode, DWORD creationDisposition,  DWORD flagsAndAttributes);
+  #endif
+
+public:
+  CFileBase(): _handle(INVALID_HANDLE_VALUE){};
+  ~CFileBase();
+
+  bool Close();
+
+  bool GetPosition(UInt64 &position) const;
+  bool GetLength(UInt64 &length) const;
+
+  bool Seek(Int64 distanceToMove, DWORD moveMethod, UInt64 &newPosition) const;
+  bool Seek(UInt64 position, UInt64 &newPosition); 
+  bool SeekToBegin(); 
+  bool SeekToEnd(UInt64 &newPosition); 
+  
+  bool GetFileInformation(CByHandleFileInfo &fileInfo) const;
+};
+
+class CInFile: public CFileBase
+{
+public:
+  bool Open(LPCTSTR fileName, DWORD shareMode, DWORD creationDisposition, DWORD flagsAndAttributes);
+  bool OpenShared(LPCTSTR fileName, bool shareForWrite);
+  bool Open(LPCTSTR fileName);
+  #ifndef _UNICODE
+  bool Open(LPCWSTR fileName, DWORD shareMode, DWORD creationDisposition, DWORD flagsAndAttributes);
+  bool OpenShared(LPCWSTR fileName, bool shareForWrite);
+  bool Open(LPCWSTR fileName);
+  #endif
+  bool ReadPart(void *data, UInt32 size, UInt32 &processedSize);
+  bool Read(void *data, UInt32 size, UInt32 &processedSize);
+};
+
+class COutFile: public CFileBase
+{
+  // DWORD m_CreationDisposition;
+public:
+  // COutFile(): m_CreationDisposition(CREATE_NEW){};
+  bool Open(LPCTSTR fileName, DWORD shareMode, DWORD creationDisposition, DWORD flagsAndAttributes);
+  bool Open(LPCTSTR fileName, DWORD creationDisposition);
+  bool Create(LPCTSTR fileName, bool createAlways);
+
+  #ifndef _UNICODE
+  bool Open(LPCWSTR fileName, DWORD shareMode, DWORD creationDisposition, DWORD flagsAndAttributes);
+  bool Open(LPCWSTR fileName, DWORD creationDisposition);
+  bool Create(LPCWSTR fileName, bool createAlways);
+  #endif
+
+  /*
+  void SetOpenCreationDisposition(DWORD creationDisposition)
+    { m_CreationDisposition = creationDisposition; }
+  void SetOpenCreationDispositionCreateAlways()
+    { m_CreationDisposition = CREATE_ALWAYS; }
+  */
+
+  bool SetTime(const FILETIME *creationTime, const FILETIME *lastAccessTime, const FILETIME *lastWriteTime);
+  bool SetLastWriteTime(const FILETIME *lastWriteTime);
+  bool WritePart(const void *data, UInt32 size, UInt32 &processedSize);
+  bool Write(const void *data, UInt32 size, UInt32 &processedSize);
+  bool SetEndOfFile();
+  bool SetLength(UInt64 length);
+};
+
+}}}
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/misc/libphysfs/lzma/CPP/Windows/FileMapping.cpp	Mon Apr 10 12:06:43 2017 -0400
@@ -0,0 +1,14 @@
+// Windows/FileMapping.cpp
+
+#include "StdAfx.h"
+
+#include "Windows/FileMapping.h"
+
+namespace NWindows {
+namespace NFile {
+namespace NMapping {
+
+
+
+
+}}}
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/misc/libphysfs/lzma/CPP/Windows/FileMapping.h	Mon Apr 10 12:06:43 2017 -0400
@@ -0,0 +1,50 @@
+// Windows/FileMapping.h
+
+#ifndef __WINDOWS_FILEMAPPING_H
+#define __WINDOWS_FILEMAPPING_H
+
+#include "Windows/Handle.h"
+#include "Windows/Defs.h"
+
+namespace NWindows {
+// namespace NFile {
+// namespace NMapping {
+
+class CFileMapping: public CHandle
+{
+public:
+  bool Create(HANDLE file, LPSECURITY_ATTRIBUTES attributes,
+    DWORD protect, UINT64 maximumSize, LPCTSTR name)
+  {
+    _handle = ::CreateFileMapping(file, attributes,
+      protect, DWORD(maximumSize >> 32), DWORD(maximumSize), name);
+    return (_handle != NULL);
+  }
+
+  bool Open(DWORD desiredAccess, bool inheritHandle, LPCTSTR name)
+  {
+    _handle = ::OpenFileMapping(desiredAccess, BoolToBOOL(inheritHandle), name);
+    return (_handle != NULL);
+  }
+
+  LPVOID MapViewOfFile(DWORD desiredAccess, UINT64 fileOffset, 
+      SIZE_T numberOfBytesToMap)
+  {
+    return ::MapViewOfFile(_handle, desiredAccess, 
+        DWORD(fileOffset >> 32), DWORD(fileOffset), numberOfBytesToMap);
+  }
+
+  LPVOID MapViewOfFileEx(DWORD desiredAccess, UINT64 fileOffset, 
+      SIZE_T numberOfBytesToMap, LPVOID baseAddress)
+  {
+    return ::MapViewOfFileEx(_handle, desiredAccess, 
+      DWORD(fileOffset >> 32), DWORD(fileOffset), 
+      numberOfBytesToMap, baseAddress);
+  }
+  
+
+};
+
+}
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/misc/libphysfs/lzma/CPP/Windows/FileName.cpp	Mon Apr 10 12:06:43 2017 -0400
@@ -0,0 +1,54 @@
+// Windows/FileName.cpp
+
+#include "StdAfx.h"
+
+#include "Windows/FileName.h"
+#include "Common/Wildcard.h"
+
+namespace NWindows {
+namespace NFile {
+namespace NName {
+
+void NormalizeDirPathPrefix(CSysString &dirPath)
+{
+  if (dirPath.IsEmpty())
+    return;
+  if (dirPath.ReverseFind(kDirDelimiter) != dirPath.Length() - 1)
+    dirPath += kDirDelimiter;
+}
+
+#ifndef _UNICODE
+void NormalizeDirPathPrefix(UString &dirPath)
+{
+  if (dirPath.IsEmpty())
+    return;
+  if (dirPath.ReverseFind(wchar_t(kDirDelimiter)) != dirPath.Length() - 1)
+    dirPath += wchar_t(kDirDelimiter);
+}
+#endif
+
+#ifdef _WIN32
+
+const wchar_t kExtensionDelimiter = L'.';
+
+void SplitNameToPureNameAndExtension(const UString &fullName, 
+    UString &pureName, UString &extensionDelimiter, UString &extension)
+{
+  int index = fullName.ReverseFind(kExtensionDelimiter);
+  if (index < 0)
+  {
+    pureName = fullName;
+    extensionDelimiter.Empty();
+    extension.Empty();
+  }
+  else
+  {
+    pureName = fullName.Left(index);
+    extensionDelimiter = kExtensionDelimiter;
+    extension = fullName.Mid(index + 1);
+  }
+}
+
+#endif
+
+}}}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/misc/libphysfs/lzma/CPP/Windows/FileName.h	Mon Apr 10 12:06:43 2017 -0400
@@ -0,0 +1,27 @@
+// Windows/FileName.h
+
+#ifndef __WINDOWS_FILENAME_H
+#define __WINDOWS_FILENAME_H
+
+#include "../Common/MyString.h"
+
+namespace NWindows {
+namespace NFile {
+namespace NName {
+
+const TCHAR kDirDelimiter = CHAR_PATH_SEPARATOR;
+const TCHAR kAnyStringWildcard = '*';
+
+void NormalizeDirPathPrefix(CSysString &dirPath); // ensures that it ended with '\\'
+#ifndef _UNICODE
+void NormalizeDirPathPrefix(UString &dirPath); // ensures that it ended with '\\'
+#endif
+
+#ifdef _WIN32
+void SplitNameToPureNameAndExtension(const UString &fullName, 
+    UString &pureName, UString &extensionDelimiter, UString &extension); 
+#endif
+
+}}}
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/misc/libphysfs/lzma/CPP/Windows/Handle.h	Mon Apr 10 12:06:43 2017 -0400
@@ -0,0 +1,37 @@
+// Windows/Handle.h
+
+#ifndef __WINDOWS_HANDLE_H
+#define __WINDOWS_HANDLE_H
+
+namespace NWindows {
+
+class CHandle
+{
+protected:
+  HANDLE _handle;
+public:
+  operator HANDLE() { return _handle; }
+  CHandle(): _handle(NULL) {}
+  ~CHandle() { Close(); }
+  bool Close()
+  {
+    if (_handle == NULL)
+      return true;
+    if (!::CloseHandle(_handle))
+      return false;
+    _handle = NULL;
+    return true;
+  }
+  void Attach(HANDLE handle) 
+    { _handle = handle; }
+  HANDLE Detach() 
+  { 
+    HANDLE handle = _handle;
+    _handle = NULL; 
+    return handle;
+  }
+};
+
+}
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/misc/libphysfs/lzma/CPP/Windows/MemoryLock.cpp	Mon Apr 10 12:06:43 2017 -0400
@@ -0,0 +1,78 @@
+// Common/MemoryLock.cpp
+
+#include "StdAfx.h"
+
+namespace NWindows {
+namespace NSecurity {
+
+#ifndef _UNICODE
+typedef BOOL (WINAPI * OpenProcessTokenP)(HANDLE ProcessHandle, DWORD DesiredAccess, PHANDLE TokenHandle);
+typedef BOOL (WINAPI * LookupPrivilegeValueP)(LPCTSTR lpSystemName, LPCTSTR lpName, PLUID  lpLuid);
+typedef BOOL (WINAPI * AdjustTokenPrivilegesP)(HANDLE TokenHandle, BOOL DisableAllPrivileges,
+    PTOKEN_PRIVILEGES NewState, DWORD BufferLength, PTOKEN_PRIVILEGES PreviousState,PDWORD ReturnLength);
+#endif
+
+#ifdef _UNICODE
+bool EnableLockMemoryPrivilege(
+#else
+static bool EnableLockMemoryPrivilege2(HMODULE hModule,
+#endif
+bool enable)
+{
+  #ifndef _UNICODE
+  if (hModule == NULL)
+    return false;
+  OpenProcessTokenP openProcessToken = (OpenProcessTokenP)GetProcAddress(hModule, "OpenProcessToken");
+  LookupPrivilegeValueP lookupPrivilegeValue = (LookupPrivilegeValueP)GetProcAddress(hModule, "LookupPrivilegeValueA" );
+  AdjustTokenPrivilegesP adjustTokenPrivileges = (AdjustTokenPrivilegesP)GetProcAddress(hModule, "AdjustTokenPrivileges");
+  if (openProcessToken == NULL || adjustTokenPrivileges == NULL || lookupPrivilegeValue == NULL)
+    return false;
+  #endif
+
+  HANDLE token;
+  if (!
+    #ifdef _UNICODE
+    ::OpenProcessToken
+    #else
+    openProcessToken
+    #endif
+    (::GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES, &token))
+    return false;
+  TOKEN_PRIVILEGES tp;
+  bool res = false;
+  if (
+    #ifdef _UNICODE
+    ::LookupPrivilegeValue
+    #else
+    lookupPrivilegeValue
+    #endif
+    (NULL, SE_LOCK_MEMORY_NAME, &(tp.Privileges[0].Luid)))
+  {
+    tp.PrivilegeCount = 1;
+    tp.Privileges[0].Attributes = enable ? SE_PRIVILEGE_ENABLED: 0;
+    if (
+      #ifdef _UNICODE
+      ::AdjustTokenPrivileges
+      #else
+      adjustTokenPrivileges
+      #endif
+      (token, FALSE, &tp, 0, NULL, NULL))
+      res = (GetLastError() == ERROR_SUCCESS);
+  }
+  ::CloseHandle(token);
+  return res;
+}
+
+#ifndef _UNICODE
+bool EnableLockMemoryPrivilege(bool enable)
+{
+  HMODULE hModule = LoadLibrary(TEXT("Advapi32.dll"));
+  if(hModule == NULL)
+    return false;
+  bool res = EnableLockMemoryPrivilege2(hModule, enable);
+  ::FreeLibrary(hModule);
+  return res;
+}
+#endif
+
+}}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/misc/libphysfs/lzma/CPP/Windows/MemoryLock.h	Mon Apr 10 12:06:43 2017 -0400
@@ -0,0 +1,13 @@
+// Windows/MemoryLock.h
+
+#ifndef __WINDOWS_MEMORYLOCK_H
+#define __WINDOWS_MEMORYLOCK_H
+
+namespace NWindows {
+namespace NSecurity {
+
+bool EnableLockMemoryPrivilege(bool enable = true);
+
+}}
+
+#endif 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/misc/libphysfs/lzma/CPP/Windows/PropVariant.cpp	Mon Apr 10 12:06:43 2017 -0400
@@ -0,0 +1,312 @@
+// Windows/PropVariant.cpp
+
+#include "StdAfx.h"
+
+#include "PropVariant.h"
+
+#include "../Common/Defs.h"
+
+namespace NWindows {
+namespace NCOM {
+
+CPropVariant::CPropVariant(const PROPVARIANT& varSrc)
+{
+  vt = VT_EMPTY;
+  InternalCopy(&varSrc);
+}
+
+CPropVariant::CPropVariant(const CPropVariant& varSrc)
+{
+  vt = VT_EMPTY;
+  InternalCopy(&varSrc);
+}
+
+CPropVariant::CPropVariant(BSTR bstrSrc)
+{
+  vt = VT_EMPTY;
+  *this = bstrSrc;
+}
+
+CPropVariant::CPropVariant(LPCOLESTR lpszSrc)
+{
+  vt = VT_EMPTY;
+  *this = lpszSrc;
+}
+
+CPropVariant& CPropVariant::operator=(const CPropVariant& varSrc)
+{
+  InternalCopy(&varSrc);
+  return *this;
+}
+CPropVariant& CPropVariant::operator=(const PROPVARIANT& varSrc)
+{
+  InternalCopy(&varSrc);
+  return *this;
+}
+
+CPropVariant& CPropVariant::operator=(BSTR bstrSrc)
+{
+  *this = (LPCOLESTR)bstrSrc;
+  return *this;
+}
+
+CPropVariant& CPropVariant::operator=(LPCOLESTR lpszSrc)
+{
+  InternalClear();
+  vt = VT_BSTR;
+  wReserved1 = 0;
+  bstrVal = ::SysAllocString(lpszSrc);
+  if (bstrVal == NULL && lpszSrc != NULL)
+  {
+    vt = VT_ERROR;
+    scode = E_OUTOFMEMORY;
+  }
+  return *this;
+}
+
+
+CPropVariant& CPropVariant::operator=(bool bSrc)
+{
+  if (vt != VT_BOOL)
+  {
+    InternalClear();
+    vt = VT_BOOL;
+  }
+  boolVal = bSrc ? VARIANT_TRUE : VARIANT_FALSE;
+  return *this;
+}
+
+CPropVariant& CPropVariant::operator=(UInt32 value)
+{
+  if (vt != VT_UI4)
+  {
+    InternalClear();
+    vt = VT_UI4;
+  }
+  ulVal = value;
+  return *this;
+}
+
+CPropVariant& CPropVariant::operator=(UInt64 value)
+{
+  if (vt != VT_UI8)
+  {
+    InternalClear();
+    vt = VT_UI8;
+  }
+  uhVal.QuadPart = value;
+  return *this;
+}
+
+CPropVariant& CPropVariant::operator=(const FILETIME &value)
+{
+  if (vt != VT_FILETIME)
+  {
+    InternalClear();
+    vt = VT_FILETIME;
+  }
+  filetime = value;
+  return *this;
+}
+
+CPropVariant& CPropVariant::operator=(Int32 value)
+{
+  if (vt != VT_I4)
+  {
+    InternalClear();
+    vt = VT_I4;
+  }
+  lVal = value;
+  
+  return *this;
+}
+
+CPropVariant& CPropVariant::operator=(Byte value)
+{
+  if (vt != VT_UI1)
+  {
+    InternalClear();
+    vt = VT_UI1;
+  }
+  bVal = value;
+  return *this;
+}
+
+CPropVariant& CPropVariant::operator=(Int16 value)
+{
+  if (vt != VT_I2)
+  {
+    InternalClear();
+    vt = VT_I2;
+  }
+  iVal = value;
+  return *this;
+}
+
+/*
+CPropVariant& CPropVariant::operator=(LONG value)
+{
+  if (vt != VT_I4)
+  {
+    InternalClear();
+    vt = VT_I4;
+  }
+  lVal = value;
+  return *this;
+}
+*/
+
+static HRESULT MyPropVariantClear(PROPVARIANT *propVariant) 
+{ 
+  switch(propVariant->vt)
+  {
+    case VT_UI1:
+    case VT_I1:
+    case VT_I2:
+    case VT_UI2:
+    case VT_BOOL:
+    case VT_I4:
+    case VT_UI4:
+    case VT_R4:
+    case VT_INT:
+    case VT_UINT:
+    case VT_ERROR:
+    case VT_FILETIME:
+    case VT_UI8:
+    case VT_R8:
+    case VT_CY:
+    case VT_DATE:
+      propVariant->vt = VT_EMPTY;
+      propVariant->wReserved1 = 0; 
+      return S_OK;
+  }
+  return ::VariantClear((VARIANTARG *)propVariant); 
+}
+
+HRESULT CPropVariant::Clear() 
+{ 
+  return MyPropVariantClear(this);
+}
+
+HRESULT CPropVariant::Copy(const PROPVARIANT* pSrc) 
+{ 
+  ::VariantClear((tagVARIANT *)this); 
+  switch(pSrc->vt)
+  {
+    case VT_UI1:
+    case VT_I1:
+    case VT_I2:
+    case VT_UI2:
+    case VT_BOOL:
+    case VT_I4:
+    case VT_UI4:
+    case VT_R4:
+    case VT_INT:
+    case VT_UINT:
+    case VT_ERROR:
+    case VT_FILETIME:
+    case VT_UI8:
+    case VT_R8:
+    case VT_CY:
+    case VT_DATE:
+      memmove((PROPVARIANT*)this, pSrc, sizeof(PROPVARIANT));
+      return S_OK;
+  }
+  return ::VariantCopy((tagVARIANT *)this, (tagVARIANT *)(pSrc)); 
+}
+
+
+HRESULT CPropVariant::Attach(PROPVARIANT* pSrc)
+{
+  HRESULT hr = Clear();
+  if (FAILED(hr))
+    return hr;
+  memcpy(this, pSrc, sizeof(PROPVARIANT));
+  pSrc->vt = VT_EMPTY;
+  return S_OK;
+}
+
+HRESULT CPropVariant::Detach(PROPVARIANT* pDest)
+{
+  HRESULT hr = MyPropVariantClear(pDest);
+  if (FAILED(hr))
+    return hr;
+  memcpy(pDest, this, sizeof(PROPVARIANT));
+  vt = VT_EMPTY;
+  return S_OK;
+}
+
+HRESULT CPropVariant::InternalClear()
+{
+  HRESULT hr = Clear();
+  if (FAILED(hr))
+  {
+    vt = VT_ERROR;
+    scode = hr;
+  }
+  return hr;
+}
+
+void CPropVariant::InternalCopy(const PROPVARIANT* pSrc)
+{
+  HRESULT hr = Copy(pSrc);
+  if (FAILED(hr))
+  {
+    vt = VT_ERROR;
+    scode = hr;
+  }
+}
+
+int CPropVariant::Compare(const CPropVariant &a)
+{
+  if(vt != a.vt)
+    return 0; // it's mean some bug
+  switch (vt)
+  {
+    case VT_EMPTY:
+      return 0;
+    
+    /*
+    case VT_I1:
+      return MyCompare(cVal, a.cVal);
+    */
+    case VT_UI1:
+      return MyCompare(bVal, a.bVal);
+
+    case VT_I2:
+      return MyCompare(iVal, a.iVal);
+    case VT_UI2:
+      return MyCompare(uiVal, a.uiVal);
+    
+    case VT_I4:
+      return MyCompare(lVal, a.lVal);
+    /*
+    case VT_INT:
+      return MyCompare(intVal, a.intVal);
+    */
+    case VT_UI4:
+      return MyCompare(ulVal, a.ulVal);
+    /*
+    case VT_UINT:
+      return MyCompare(uintVal, a.uintVal);
+    */
+    case VT_I8:
+      return MyCompare(hVal.QuadPart, a.hVal.QuadPart);
+    case VT_UI8:
+      return MyCompare(uhVal.QuadPart, a.uhVal.QuadPart);
+
+    case VT_BOOL:    
+      return -MyCompare(boolVal, a.boolVal);
+
+    case VT_FILETIME:
+      return ::CompareFileTime(&filetime, &a.filetime);
+    case VT_BSTR:
+      return 0; // Not implemented 
+      // return MyCompare(aPropVarint.cVal);
+
+    default:
+      return 0;
+  }
+}
+
+}}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/misc/libphysfs/lzma/CPP/Windows/PropVariant.h	Mon Apr 10 12:06:43 2017 -0400
@@ -0,0 +1,57 @@
+// Windows/PropVariant.h
+
+#ifndef __WINDOWS_PROPVARIANT_H
+#define __WINDOWS_PROPVARIANT_H
+
+#include "../Common/MyWindows.h"
+#include "../Common/Types.h"
+
+namespace NWindows {
+namespace NCOM {
+
+class CPropVariant : public tagPROPVARIANT
+{
+public:
+  CPropVariant() { vt = VT_EMPTY; wReserved1 = 0; }
+  ~CPropVariant() { Clear(); }
+  CPropVariant(const PROPVARIANT& varSrc);
+  CPropVariant(const CPropVariant& varSrc);
+  CPropVariant(BSTR bstrSrc);
+  CPropVariant(LPCOLESTR lpszSrc);
+  CPropVariant(bool bSrc) { vt = VT_BOOL; wReserved1 = 0; boolVal = (bSrc ? VARIANT_TRUE : VARIANT_FALSE); };
+  CPropVariant(UInt32 value) { vt = VT_UI4; wReserved1 = 0; ulVal = value; }
+  CPropVariant(UInt64 value) { vt = VT_UI8; wReserved1 = 0; uhVal = *(ULARGE_INTEGER*)&value; }
+  CPropVariant(const FILETIME &value) { vt = VT_FILETIME; wReserved1 = 0; filetime = value; }
+  CPropVariant(Int32 value) { vt = VT_I4; wReserved1 = 0; lVal = value; }
+  CPropVariant(Byte value) { vt = VT_UI1; wReserved1 = 0; bVal = value; }
+  CPropVariant(Int16 value) { vt = VT_I2; wReserved1 = 0; iVal = value; }
+  // CPropVariant(LONG value, VARTYPE vtSrc = VT_I4) { vt = vtSrc; lVal = value; }
+
+  CPropVariant& operator=(const CPropVariant& varSrc);
+  CPropVariant& operator=(const PROPVARIANT& varSrc);
+  CPropVariant& operator=(BSTR bstrSrc);
+  CPropVariant& operator=(LPCOLESTR lpszSrc);
+  CPropVariant& operator=(bool bSrc);
+  CPropVariant& operator=(UInt32 value);
+  CPropVariant& operator=(UInt64 value);
+  CPropVariant& operator=(const FILETIME &value);
+
+  CPropVariant& operator=(Int32 value);
+  CPropVariant& operator=(Byte value);
+  CPropVariant& operator=(Int16 value);
+  // CPropVariant& operator=(LONG  value);
+
+  HRESULT Clear();
+  HRESULT Copy(const PROPVARIANT* pSrc);
+  HRESULT Attach(PROPVARIANT* pSrc);
+  HRESULT Detach(PROPVARIANT* pDest);
+
+  HRESULT InternalClear();
+  void InternalCopy(const PROPVARIANT* pSrc);
+
+  int Compare(const CPropVariant &a1);
+};
+
+}}
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/misc/libphysfs/lzma/CPP/Windows/PropVariantConversions.cpp	Mon Apr 10 12:06:43 2017 -0400
@@ -0,0 +1,150 @@
+// PropVariantConversions.cpp
+
+#include "StdAfx.h"
+
+// #include <stdio.h>
+
+#include "PropVariantConversions.h"
+
+#include "Windows/Defs.h"
+
+#include "Common/StringConvert.h"
+#include "Common/IntToString.h"
+
+static UString ConvertUInt64ToString(UInt64 value)
+{
+  wchar_t buffer[32];
+  ConvertUInt64ToString(value, buffer);
+  return buffer;
+}
+
+static UString ConvertInt64ToString(Int64 value)
+{
+  wchar_t buffer[32];
+  ConvertInt64ToString(value, buffer);
+  return buffer;
+}
+
+static char *UIntToStringSpec(UInt32 value, char *s, int numPos)
+{
+  char temp[16];
+  int pos = 0;
+  do 
+  {
+    temp[pos++] = (char)('0' + value % 10);
+    value /= 10;
+  }
+  while (value != 0);
+  int i;
+  for (i = 0; i < numPos - pos; i++)
+    *s++ = '0';
+  do
+    *s++ = temp[--pos];
+  while (pos > 0);
+  *s = '\0';
+  return s;
+}
+
+bool ConvertFileTimeToString(const FILETIME &ft, char *s, bool includeTime, bool includeSeconds)
+{
+  s[0] = '\0';
+  SYSTEMTIME st;
+  if(!BOOLToBool(FileTimeToSystemTime(&ft, &st)))
+    return false;
+  s = UIntToStringSpec(st.wYear, s, 4);
+  *s++ = '-';
+  s = UIntToStringSpec(st.wMonth, s, 2);
+  *s++ = '-';
+  s = UIntToStringSpec(st.wDay, s, 2);
+  if (includeTime)
+  {
+    *s++ = ' ';
+    s = UIntToStringSpec(st.wHour, s, 2);
+    *s++ = ':';
+    s = UIntToStringSpec(st.wMinute, s, 2);
+    if (includeSeconds)
+    {
+      *s++ = ':';
+      UIntToStringSpec(st.wSecond, s, 2);
+    }
+  }
+  /*
+  sprintf(s, "%04d-%02d-%02d", st.wYear, st.wMonth, st.wDay);
+  if (includeTime)
+  {
+    sprintf(s + strlen(s), " %02d:%02d", st.wHour, st.wMinute);
+    if (includeSeconds)
+      sprintf(s + strlen(s), ":%02d", st.wSecond);
+  }
+  */
+  return true;
+}
+
+UString ConvertFileTimeToString(const FILETIME &fileTime, bool includeTime, bool includeSeconds)
+{
+  char s[32];
+  ConvertFileTimeToString(fileTime, s,  includeTime, includeSeconds);
+  return GetUnicodeString(s);
+}
+ 
+
+UString ConvertPropVariantToString(const PROPVARIANT &propVariant)
+{
+  switch (propVariant.vt)
+  {
+    case VT_EMPTY:
+      return UString();
+    case VT_BSTR:
+      return propVariant.bstrVal;
+    case VT_UI1:
+      return ConvertUInt64ToString(propVariant.bVal);
+    case VT_UI2:
+      return ConvertUInt64ToString(propVariant.uiVal);
+    case VT_UI4:
+      return ConvertUInt64ToString(propVariant.ulVal);
+    case VT_UI8:
+      return ConvertUInt64ToString(propVariant.uhVal.QuadPart);
+    case VT_FILETIME:
+      return ConvertFileTimeToString(propVariant.filetime, true, true);
+    /*
+    case VT_I1:
+      return ConvertInt64ToString(propVariant.cVal);
+    */
+    case VT_I2:
+      return ConvertInt64ToString(propVariant.iVal);
+    case VT_I4:
+      return ConvertInt64ToString(propVariant.lVal);
+    case VT_I8:
+      return ConvertInt64ToString(propVariant.hVal.QuadPart);
+
+    case VT_BOOL:
+      return VARIANT_BOOLToBool(propVariant.boolVal) ? L"+" : L"-";
+    default:
+      #ifndef _WIN32_WCE
+      throw 150245;
+      #else
+      return UString();
+      #endif
+  }
+}
+
+UInt64 ConvertPropVariantToUInt64(const PROPVARIANT &propVariant)
+{
+  switch (propVariant.vt)
+  {
+    case VT_UI1:
+      return propVariant.bVal;
+    case VT_UI2:
+      return propVariant.uiVal;
+    case VT_UI4:
+      return propVariant.ulVal;
+    case VT_UI8:
+      return (UInt64)propVariant.uhVal.QuadPart;
+    default:
+      #ifndef _WIN32_WCE
+      throw 151199;
+      #else
+      return 0;
+      #endif
+  }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/misc/libphysfs/lzma/CPP/Windows/PropVariantConversions.h	Mon Apr 10 12:06:43 2017 -0400
@@ -0,0 +1,14 @@
+// Windows/PropVariantConversions.h
+
+#ifndef __PROPVARIANTCONVERSIONS_H
+#define __PROPVARIANTCONVERSIONS_H
+
+#include "Common/Types.h"
+#include "Common/MyString.h"
+
+bool ConvertFileTimeToString(const FILETIME &ft, char *s, bool includeTime = true, bool includeSeconds = true);
+UString ConvertFileTimeToString(const FILETIME &ft, bool includeTime = true, bool includeSeconds = true);
+UString ConvertPropVariantToString(const PROPVARIANT &propVariant);
+UInt64 ConvertPropVariantToUInt64(const PROPVARIANT &propVariant);
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/misc/libphysfs/lzma/CPP/Windows/StdAfx.h	Mon Apr 10 12:06:43 2017 -0400
@@ -0,0 +1,9 @@
+// StdAfx.h
+
+#ifndef __STDAFX_H
+#define __STDAFX_H
+
+#include "../Common/MyWindows.h"
+#include "../Common/NewHandler.h"
+
+#endif 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/misc/libphysfs/lzma/CPP/Windows/Synchronization.cpp	Mon Apr 10 12:06:43 2017 -0400
@@ -0,0 +1,10 @@
+// Windows/Synchronization.cpp
+
+#include "StdAfx.h"
+
+#include "Synchronization.h"
+
+namespace NWindows {
+namespace NSynchronization {
+
+}}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/misc/libphysfs/lzma/CPP/Windows/Synchronization.h	Mon Apr 10 12:06:43 2017 -0400
@@ -0,0 +1,168 @@
+// Windows/Synchronization.h
+
+#ifndef __WINDOWS_SYNCHRONIZATION_H
+#define __WINDOWS_SYNCHRONIZATION_H
+
+#include "Defs.h"
+
+extern "C" 
+{ 
+#include "../../C/Threads.h"
+}
+
+#ifdef _WIN32
+#include "Handle.h"
+#endif
+
+namespace NWindows {
+namespace NSynchronization {
+
+class CBaseEvent
+{
+protected:
+  ::CEvent _object;
+public:
+  bool IsCreated() { return Event_IsCreated(&_object) != 0; }
+  operator HANDLE() { return _object.handle; }
+  CBaseEvent() { Event_Construct(&_object); }
+  ~CBaseEvent() { Close(); }
+  HRes Close() { return Event_Close(&_object); }
+  #ifdef _WIN32
+  HRes Create(bool manualReset, bool initiallyOwn, LPCTSTR name = NULL,
+      LPSECURITY_ATTRIBUTES securityAttributes = NULL)
+  {
+    _object.handle = ::CreateEvent(securityAttributes, BoolToBOOL(manualReset),
+        BoolToBOOL(initiallyOwn), name);
+    if (_object.handle != 0)
+      return 0;
+    return ::GetLastError();
+  }
+  HRes Open(DWORD desiredAccess, bool inheritHandle, LPCTSTR name)
+  {
+    _object.handle = ::OpenEvent(desiredAccess, BoolToBOOL(inheritHandle), name);
+    if (_object.handle != 0)
+      return 0;
+    return ::GetLastError();
+  }
+  #endif
+
+  HRes Set() { return Event_Set(&_object); }
+  // bool Pulse() { return BOOLToBool(::PulseEvent(_handle)); }
+  HRes Reset() { return Event_Reset(&_object); }
+  HRes Lock() { return Event_Wait(&_object); }
+};
+
+class CManualResetEvent: public CBaseEvent
+{
+public:
+  HRes Create(bool initiallyOwn = false)
+  {
+    return ManualResetEvent_Create(&_object, initiallyOwn ? 1: 0);
+  }
+  HRes CreateIfNotCreated()
+  {
+    if (IsCreated())
+      return 0;
+    return ManualResetEvent_CreateNotSignaled(&_object);
+  }
+  #ifdef _WIN32
+  HRes CreateWithName(bool initiallyOwn, LPCTSTR name)
+  {
+    return CBaseEvent::Create(true, initiallyOwn, name);
+  }
+  #endif
+};
+
+class CAutoResetEvent: public CBaseEvent
+{
+public:
+  HRes Create()
+  {
+    return AutoResetEvent_CreateNotSignaled(&_object);
+  }
+  HRes CreateIfNotCreated()
+  {
+    if (IsCreated())
+      return 0;
+    return AutoResetEvent_CreateNotSignaled(&_object);
+  }
+};
+
+#ifdef _WIN32
+class CObject: public CHandle
+{
+public:
+  HRes Lock(DWORD timeoutInterval = INFINITE)
+    { return (::WaitForSingleObject(_handle, timeoutInterval) == WAIT_OBJECT_0 ? 0 : ::GetLastError()); }
+};
+class CMutex: public CObject
+{
+public:
+  HRes Create(bool initiallyOwn, LPCTSTR name = NULL,
+      LPSECURITY_ATTRIBUTES securityAttributes = NULL)
+  {
+    _handle = ::CreateMutex(securityAttributes, BoolToBOOL(initiallyOwn), name);
+    if (_handle != 0)
+      return 0;
+    return ::GetLastError();
+  }
+  HRes Open(DWORD desiredAccess, bool inheritHandle, LPCTSTR name)
+  {
+    _handle = ::OpenMutex(desiredAccess, BoolToBOOL(inheritHandle), name);
+    if (_handle != 0)
+      return 0;
+    return ::GetLastError();
+  }
+  HRes Release() 
+  { 
+    return ::ReleaseMutex(_handle) ? 0 : ::GetLastError();
+  }
+};
+class CMutexLock
+{
+  CMutex *_object;
+public:
+  CMutexLock(CMutex &object): _object(&object) { _object->Lock(); } 
+  ~CMutexLock() { _object->Release(); }
+};
+#endif
+
+class CSemaphore
+{
+  ::CSemaphore _object;
+public:
+  CSemaphore() { Semaphore_Construct(&_object); }
+  ~CSemaphore() { Close(); }
+  HRes Close() {  return Semaphore_Close(&_object); }
+  operator HANDLE() { return _object.handle; }
+  HRes Create(UInt32 initiallyCount, UInt32 maxCount)
+  {
+    return Semaphore_Create(&_object, initiallyCount, maxCount);
+  }
+  HRes Release() { return Semaphore_Release1(&_object); }
+  HRes Release(UInt32 releaseCount) { return Semaphore_ReleaseN(&_object, releaseCount); }
+  HRes Lock() { return Semaphore_Wait(&_object); }
+};
+
+class CCriticalSection
+{
+  ::CCriticalSection _object;
+public:
+  CCriticalSection() { CriticalSection_Init(&_object); }
+  ~CCriticalSection() { CriticalSection_Delete(&_object); }
+  void Enter() { CriticalSection_Enter(&_object); }
+  void Leave() { CriticalSection_Leave(&_object); }
+};
+
+class CCriticalSectionLock
+{
+  CCriticalSection *_object;
+  void Unlock()  { _object->Leave(); }
+public:
+  CCriticalSectionLock(CCriticalSection &object): _object(&object) {_object->Enter(); } 
+  ~CCriticalSectionLock() { Unlock(); }
+};
+
+}}
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/misc/libphysfs/lzma/CPP/Windows/System.cpp	Mon Apr 10 12:06:43 2017 -0400
@@ -0,0 +1,64 @@
+// Windows/System.cpp
+
+#include "StdAfx.h"
+
+#include "System.h"
+
+namespace NWindows {
+namespace NSystem {
+
+UInt32 GetNumberOfProcessors()
+{
+  SYSTEM_INFO systemInfo;
+  GetSystemInfo(&systemInfo);
+  return (UInt32)systemInfo.dwNumberOfProcessors;
+}
+
+#if !defined(_WIN64) && defined(__GNUC__)
+
+typedef struct _MY_MEMORYSTATUSEX {
+  DWORD dwLength;
+  DWORD dwMemoryLoad;
+  DWORDLONG ullTotalPhys;
+  DWORDLONG ullAvailPhys;
+  DWORDLONG ullTotalPageFile;
+  DWORDLONG ullAvailPageFile;
+  DWORDLONG ullTotalVirtual;
+  DWORDLONG ullAvailVirtual;
+  DWORDLONG ullAvailExtendedVirtual;
+} MY_MEMORYSTATUSEX, *MY_LPMEMORYSTATUSEX;
+
+#else
+
+#define MY_MEMORYSTATUSEX MEMORYSTATUSEX
+#define MY_LPMEMORYSTATUSEX LPMEMORYSTATUSEX
+
+#endif
+
+typedef BOOL (WINAPI *GlobalMemoryStatusExP)(MY_LPMEMORYSTATUSEX lpBuffer);
+
+UInt64 GetRamSize()
+{
+  MY_MEMORYSTATUSEX stat;
+  stat.dwLength = sizeof(stat);
+  #ifdef _WIN64
+  if (!::GlobalMemoryStatusEx(&stat))
+    return 0;
+  return stat.ullTotalPhys;
+  #else
+  GlobalMemoryStatusExP globalMemoryStatusEx = (GlobalMemoryStatusExP)
+        ::GetProcAddress(::GetModuleHandle(TEXT("kernel32.dll")),
+        "GlobalMemoryStatusEx");
+  if (globalMemoryStatusEx != 0)
+    if (globalMemoryStatusEx(&stat))
+      return stat.ullTotalPhys;
+  {
+    MEMORYSTATUS stat;
+    stat.dwLength = sizeof(stat);
+    GlobalMemoryStatus(&stat);
+    return stat.dwTotalPhys;
+  }
+  #endif
+}
+
+}}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/misc/libphysfs/lzma/CPP/Windows/System.h	Mon Apr 10 12:06:43 2017 -0400
@@ -0,0 +1,16 @@
+// Windows/System.h
+
+#ifndef __WINDOWS_SYSTEM_H
+#define __WINDOWS_SYSTEM_H
+
+#include "../Common/Types.h"
+
+namespace NWindows {
+namespace NSystem {
+
+UInt32 GetNumberOfProcessors();
+UInt64 GetRamSize();
+
+}}
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/misc/libphysfs/lzma/CPP/Windows/Thread.h	Mon Apr 10 12:06:43 2017 -0400
@@ -0,0 +1,38 @@
+// Windows/Thread.h
+
+#ifndef __WINDOWS_THREAD_H
+#define __WINDOWS_THREAD_H
+
+#include "Defs.h"
+
+extern "C" 
+{ 
+#include "../../C/Threads.h"
+}
+
+namespace NWindows {
+
+class CThread
+{
+  ::CThread thread;
+public:
+  CThread() { Thread_Construct(&thread); }
+  ~CThread() { Close(); }
+  bool IsCreated() { return Thread_WasCreated(&thread) != 0; }
+  HRes Close()  { return Thread_Close(&thread); }
+  HRes Create(THREAD_FUNC_RET_TYPE (THREAD_FUNC_CALL_TYPE *startAddress)(void *), LPVOID parameter)
+    { return Thread_Create(&thread, startAddress, parameter); }
+  HRes Wait() { return Thread_Wait(&thread); }
+  
+  #ifdef _WIN32
+  DWORD Resume() { return ::ResumeThread(thread.handle); }
+  DWORD Suspend() { return ::SuspendThread(thread.handle); }
+  bool Terminate(DWORD exitCode) { return BOOLToBool(::TerminateThread(thread.handle, exitCode)); }
+  int GetPriority() { return ::GetThreadPriority(thread.handle); }
+  bool SetPriority(int priority) { return BOOLToBool(::SetThreadPriority(thread.handle, priority)); }
+  #endif
+};
+
+}
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/misc/libphysfs/lzma/CPP/Windows/Time.h	Mon Apr 10 12:06:43 2017 -0400
@@ -0,0 +1,66 @@
+// Windows/Time.h
+
+#ifndef __WINDOWS_TIME_H
+#define __WINDOWS_TIME_H
+
+#include "Common/Types.h"
+#include "Windows/Defs.h"
+
+namespace NWindows {
+namespace NTime {
+
+inline bool DosTimeToFileTime(UInt32 dosTime, FILETIME &fileTime)
+{
+  return BOOLToBool(::DosDateTimeToFileTime(UInt16(dosTime >> 16), 
+      UInt16(dosTime & 0xFFFF), &fileTime));
+}
+
+const UInt32 kHighDosTime = 0xFF9FBF7D;
+const UInt32 kLowDosTime = 0x210000;
+
+inline bool FileTimeToDosTime(const FILETIME &fileTime, UInt32 &dosTime)
+{
+  WORD datePart, timePart;
+  if (!::FileTimeToDosDateTime(&fileTime, &datePart, &timePart))
+  {
+    if (fileTime.dwHighDateTime >= 0x01C00000) // 2000
+      dosTime = kHighDosTime;
+    else
+      dosTime = kLowDosTime;
+    return false;
+  }
+  dosTime = (((UInt32)datePart) << 16) + timePart;
+  return true;
+}
+
+const UInt32 kNumTimeQuantumsInSecond = 10000000;
+const UInt64 kUnixTimeStartValue = ((UInt64)kNumTimeQuantumsInSecond) * 60 * 60 * 24 * 134774;
+
+inline void UnixTimeToFileTime(UInt32 unixTime, FILETIME &fileTime)
+{
+  UInt64 v = kUnixTimeStartValue + ((UInt64)unixTime) * kNumTimeQuantumsInSecond;
+  fileTime.dwLowDateTime = (DWORD)v;
+  fileTime.dwHighDateTime = (DWORD)(v >> 32);
+}
+
+inline bool FileTimeToUnixTime(const FILETIME &fileTime, UInt32 &unixTime)
+{
+  UInt64 winTime = (((UInt64)fileTime.dwHighDateTime) << 32) + fileTime.dwLowDateTime;
+  if (winTime < kUnixTimeStartValue)
+  {
+    unixTime = 0;
+    return false;
+  }
+  winTime = (winTime - kUnixTimeStartValue) / kNumTimeQuantumsInSecond;
+  if (winTime > 0xFFFFFFFF)
+  {
+    unixTime = 0xFFFFFFFF;
+    return false;
+  }
+  unixTime = (UInt32)winTime;
+  return true;
+}
+
+}}
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/misc/libphysfs/lzma/CS/7zip/Common/CRC.cs	Mon Apr 10 12:06:43 2017 -0400
@@ -0,0 +1,55 @@
+// Common/CRC.cs
+
+namespace SevenZip
+{
+	class CRC
+	{
+		public static readonly uint[] Table;
+
+		static CRC()
+		{
+			Table = new uint[256];
+			const uint kPoly = 0xEDB88320;
+			for (uint i = 0; i < 256; i++)
+			{
+				uint r = i;
+				for (int j = 0; j < 8; j++)
+					if ((r & 1) != 0)
+						r = (r >> 1) ^ kPoly;
+					else
+						r >>= 1;
+				Table[i] = r;
+			}
+		}
+
+		uint _value = 0xFFFFFFFF;
+
+		public void Init() { _value = 0xFFFFFFFF; }
+
+		public void UpdateByte(byte b)
+		{
+			_value = Table[(((byte)(_value)) ^ b)] ^ (_value >> 8);
+		}
+
+		public void Update(byte[] data, uint offset, uint size)
+		{
+			for (uint i = 0; i < size; i++)
+				_value = Table[(((byte)(_value)) ^ data[offset + i])] ^ (_value >> 8);
+		}
+
+		public uint GetDigest() { return _value ^ 0xFFFFFFFF; }
+
+		static uint CalculateDigest(byte[] data, uint offset, uint size)
+		{
+			CRC crc = new CRC();
+			// crc.Init();
+			crc.Update(data, offset, size);
+			return crc.GetDigest();
+		}
+
+		static bool VerifyDigest(uint digest, byte[] data, uint offset, uint size)
+		{
+			return (CalculateDigest(data, offset, size) == digest);
+		}
+	}
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/misc/libphysfs/lzma/CS/7zip/Common/CommandLineParser.cs	Mon Apr 10 12:06:43 2017 -0400
@@ -0,0 +1,274 @@
+// CommandLineParser.cs
+
+using System;
+using System.Collections;
+
+namespace SevenZip.CommandLineParser
+{
+	public enum SwitchType
+	{
+		Simple,
+		PostMinus,
+		LimitedPostString,
+		UnLimitedPostString,
+		PostChar
+	}
+
+	public class SwitchForm
+	{
+		public string IDString;
+		public SwitchType Type;
+		public bool Multi;
+		public int MinLen;
+		public int MaxLen;
+		public string PostCharSet;
+
+		public SwitchForm(string idString, SwitchType type, bool multi,
+			int minLen, int maxLen, string postCharSet)
+		{
+			IDString = idString;
+			Type = type;
+			Multi = multi;
+			MinLen = minLen;
+			MaxLen = maxLen;
+			PostCharSet = postCharSet;
+		}
+		public SwitchForm(string idString, SwitchType type, bool multi, int minLen):
+			this(idString, type, multi, minLen, 0, "")
+		{
+		}
+		public SwitchForm(string idString, SwitchType type, bool multi):
+			this(idString, type, multi, 0)
+		{
+		}
+	}
+
+	public class SwitchResult
+	{
+		public bool ThereIs;
+		public bool WithMinus;
+		public ArrayList PostStrings = new ArrayList();
+		public int PostCharIndex;
+		public SwitchResult()
+		{
+			ThereIs = false;
+		}
+	}
+
+	public class Parser
+	{
+		public ArrayList NonSwitchStrings = new ArrayList();
+		SwitchResult[] _switches;
+
+		public Parser(int numSwitches)
+		{
+			_switches = new SwitchResult[numSwitches];
+			for (int i = 0; i < numSwitches; i++)
+				_switches[i] = new SwitchResult();
+		}
+
+		bool ParseString(string srcString, SwitchForm[] switchForms)
+		{
+			int len = srcString.Length;
+			if (len == 0)
+				return false;
+			int pos = 0;
+			if (!IsItSwitchChar(srcString[pos]))
+				return false;
+			while (pos < len)
+			{
+				if (IsItSwitchChar(srcString[pos]))
+					pos++;
+				const int kNoLen = -1;
+				int matchedSwitchIndex = 0;
+				int maxLen = kNoLen;
+				for (int switchIndex = 0; switchIndex < _switches.Length; switchIndex++)
+				{
+					int switchLen = switchForms[switchIndex].IDString.Length;
+					if (switchLen <= maxLen || pos + switchLen > len)
+						continue;
+					if (String.Compare(switchForms[switchIndex].IDString, 0,
+							srcString, pos, switchLen, true) == 0)
+					{
+						matchedSwitchIndex = switchIndex;
+						maxLen = switchLen;
+					}
+				}
+				if (maxLen == kNoLen)
+					throw new Exception("maxLen == kNoLen");
+				SwitchResult matchedSwitch = _switches[matchedSwitchIndex];
+				SwitchForm switchForm = switchForms[matchedSwitchIndex];
+				if ((!switchForm.Multi) && matchedSwitch.ThereIs)
+					throw new Exception("switch must be single");
+				matchedSwitch.ThereIs = true;
+				pos += maxLen;
+				int tailSize = len - pos;
+				SwitchType type = switchForm.Type;
+				switch (type)
+				{
+					case SwitchType.PostMinus:
+						{
+							if (tailSize == 0)
+								matchedSwitch.WithMinus = false;
+							else
+							{
+								matchedSwitch.WithMinus = (srcString[pos] == kSwitchMinus);
+								if (matchedSwitch.WithMinus)
+									pos++;
+							}
+							break;
+						}
+					case SwitchType.PostChar:
+						{
+							if (tailSize < switchForm.MinLen)
+								throw new Exception("switch is not full");
+							string charSet = switchForm.PostCharSet;
+							const int kEmptyCharValue = -1;
+							if (tailSize == 0)
+								matchedSwitch.PostCharIndex = kEmptyCharValue;
+							else
+							{
+								int index = charSet.IndexOf(srcString[pos]);
+								if (index < 0)
+									matchedSwitch.PostCharIndex = kEmptyCharValue;
+								else
+								{
+									matchedSwitch.PostCharIndex = index;
+									pos++;
+								}
+							}
+							break;
+						}
+					case SwitchType.LimitedPostString:
+					case SwitchType.UnLimitedPostString:
+						{
+							int minLen = switchForm.MinLen;
+							if (tailSize < minLen)
+								throw new Exception("switch is not full");
+							if (type == SwitchType.UnLimitedPostString)
+							{
+								matchedSwitch.PostStrings.Add(srcString.Substring(pos));
+								return true;
+							}
+							String stringSwitch = srcString.Substring(pos, minLen);
+							pos += minLen;
+							for (int i = minLen; i < switchForm.MaxLen && pos < len; i++, pos++)
+							{
+								char c = srcString[pos];
+								if (IsItSwitchChar(c))
+									break;
+								stringSwitch += c;
+							}
+							matchedSwitch.PostStrings.Add(stringSwitch);
+							break;
+						}
+				}
+			}
+			return true;
+
+		}
+
+		public void ParseStrings(SwitchForm[] switchForms, string[] commandStrings)
+		{
+			int numCommandStrings = commandStrings.Length;
+			bool stopSwitch = false;
+			for (int i = 0; i < numCommandStrings; i++)
+			{
+				string s = commandStrings[i];
+				if (stopSwitch)
+					NonSwitchStrings.Add(s);
+				else
+					if (s == kStopSwitchParsing)
+					stopSwitch = true;
+				else
+					if (!ParseString(s, switchForms))
+					NonSwitchStrings.Add(s);
+			}
+		}
+
+		public SwitchResult this[int index] { get { return _switches[index]; } }
+
+		public static int ParseCommand(CommandForm[] commandForms, string commandString,
+			out string postString)
+		{
+			for (int i = 0; i < commandForms.Length; i++)
+			{
+				string id = commandForms[i].IDString;
+				if (commandForms[i].PostStringMode)
+				{
+					if (commandString.IndexOf(id) == 0)
+					{
+						postString = commandString.Substring(id.Length);
+						return i;
+					}
+				}
+				else
+					if (commandString == id)
+				{
+					postString = "";
+					return i;
+				}
+			}
+			postString = "";
+			return -1;
+		}
+
+		static bool ParseSubCharsCommand(int numForms, CommandSubCharsSet[] forms,
+			string commandString, ArrayList indices)
+		{
+			indices.Clear();
+			int numUsedChars = 0;
+			for (int i = 0; i < numForms; i++)
+			{
+				CommandSubCharsSet charsSet = forms[i];
+				int currentIndex = -1;
+				int len = charsSet.Chars.Length;
+				for (int j = 0; j < len; j++)
+				{
+					char c = charsSet.Chars[j];
+					int newIndex = commandString.IndexOf(c);
+					if (newIndex >= 0)
+					{
+						if (currentIndex >= 0)
+							return false;
+						if (commandString.IndexOf(c, newIndex + 1) >= 0)
+							return false;
+						currentIndex = j;
+						numUsedChars++;
+					}
+				}
+				if (currentIndex == -1 && !charsSet.EmptyAllowed)
+					return false;
+				indices.Add(currentIndex);
+			}
+			return (numUsedChars == commandString.Length);
+		}
+		const char kSwitchID1 = '-';
+		const char kSwitchID2 = '/';
+
+		const char kSwitchMinus = '-';
+		const string kStopSwitchParsing = "--";
+
+		static bool IsItSwitchChar(char c)
+		{
+			return (c == kSwitchID1 || c == kSwitchID2);
+		}
+	}
+
+	public class CommandForm
+	{
+		public string IDString = "";
+		public bool PostStringMode = false;
+		public CommandForm(string idString, bool postStringMode)
+		{
+			IDString = idString;
+			PostStringMode = postStringMode;
+		}
+	}
+
+	class CommandSubCharsSet
+	{
+		public string Chars = "";
+		public bool EmptyAllowed = false;
+	}
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/misc/libphysfs/lzma/CS/7zip/Common/InBuffer.cs	Mon Apr 10 12:06:43 2017 -0400
@@ -0,0 +1,72 @@
+// InBuffer.cs
+
+namespace SevenZip.Buffer
+{
+	public class InBuffer
+	{
+		byte[] m_Buffer;
+		uint m_Pos;
+		uint m_Limit;
+		uint m_BufferSize;
+		System.IO.Stream m_Stream;
+		bool m_StreamWasExhausted;
+		ulong m_ProcessedSize;
+
+		public InBuffer(uint bufferSize)
+		{
+			m_Buffer = new byte[bufferSize];
+			m_BufferSize = bufferSize;
+		}
+
+		public void Init(System.IO.Stream stream)
+		{
+			m_Stream = stream;
+			m_ProcessedSize = 0;
+			m_Limit = 0;
+			m_Pos = 0;
+			m_StreamWasExhausted = false;
+		}
+
+		public bool ReadBlock()
+		{
+			if (m_StreamWasExhausted)
+				return false;
+			m_ProcessedSize += m_Pos;
+			int aNumProcessedBytes = m_Stream.Read(m_Buffer, 0, (int)m_BufferSize);
+			m_Pos = 0;
+			m_Limit = (uint)aNumProcessedBytes;
+			m_StreamWasExhausted = (aNumProcessedBytes == 0);
+			return (!m_StreamWasExhausted);
+		}
+
+
+		public void ReleaseStream()
+		{
+			// m_Stream.Close(); 
+			m_Stream = null;
+		}
+
+		public bool ReadByte(byte b) // check it
+		{
+			if (m_Pos >= m_Limit)
+				if (!ReadBlock())
+					return false;
+			b = m_Buffer[m_Pos++];
+			return true;
+		}
+
+		public byte ReadByte()
+		{
+			// return (byte)m_Stream.ReadByte();
+			if (m_Pos >= m_Limit)
+				if (!ReadBlock())
+					return 0xFF;
+			return m_Buffer[m_Pos++];
+		}
+
+		public ulong GetProcessedSize()
+		{
+			return m_ProcessedSize + m_Pos;
+		}
+	}
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/misc/libphysfs/lzma/CS/7zip/Common/OutBuffer.cs	Mon Apr 10 12:06:43 2017 -0400
@@ -0,0 +1,47 @@
+// OutBuffer.cs
+
+namespace SevenZip.Buffer
+{
+	public class OutBuffer
+	{
+		byte[] m_Buffer;
+		uint m_Pos;
+		uint m_BufferSize;
+		System.IO.Stream m_Stream;
+		ulong m_ProcessedSize;
+
+		public OutBuffer(uint bufferSize)
+		{
+			m_Buffer = new byte[bufferSize];
+			m_BufferSize = bufferSize;
+		}
+
+		public void SetStream(System.IO.Stream stream) { m_Stream = stream; }
+		public void FlushStream() { m_Stream.Flush(); }
+		public void CloseStream() { m_Stream.Close(); }
+		public void ReleaseStream() { m_Stream = null; }
+
+		public void Init()
+		{
+			m_ProcessedSize = 0;
+			m_Pos = 0;
+		}
+
+		public void WriteByte(byte b)
+		{
+			m_Buffer[m_Pos++] = b;
+			if (m_Pos >= m_BufferSize)
+				FlushData();
+		}
+
+		public void FlushData()
+		{
+			if (m_Pos == 0)
+				return;
+			m_Stream.Write(m_Buffer, 0, (int)m_Pos);
+			m_Pos = 0;
+		}
+
+		public ulong GetProcessedSize() { return m_ProcessedSize + m_Pos; }
+	}
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/misc/libphysfs/lzma/CS/7zip/Compress/LZ/IMatchFinder.cs	Mon Apr 10 12:06:43 2017 -0400
@@ -0,0 +1,24 @@
+// IMatchFinder.cs
+
+using System;
+
+namespace SevenZip.Compression.LZ
+{
+	interface IInWindowStream
+	{
+		void SetStream(System.IO.Stream inStream);
+		void Init();
+		void ReleaseStream();
+		Byte GetIndexByte(Int32 index);
+		UInt32 GetMatchLen(Int32 index, UInt32 distance, UInt32 limit);
+		UInt32 GetNumAvailableBytes();
+	}
+
+	interface IMatchFinder : IInWindowStream
+	{
+		void Create(UInt32 historySize, UInt32 keepAddBufferBefore,
+				UInt32 matchMaxLen, UInt32 keepAddBufferAfter);
+		UInt32 GetMatches(UInt32[] distances);
+		void Skip(UInt32 num);
+	}
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/misc/libphysfs/lzma/CS/7zip/Compress/LZ/LzBinTree.cs	Mon Apr 10 12:06:43 2017 -0400
@@ -0,0 +1,367 @@
+// LzBinTree.cs
+
+using System;
+
+namespace SevenZip.Compression.LZ
+{
+	public class BinTree : InWindow, IMatchFinder
+	{
+		UInt32 _cyclicBufferPos;
+		UInt32 _cyclicBufferSize = 0;
+		UInt32 _matchMaxLen;
+
+		UInt32[] _son;
+		UInt32[] _hash;
+
+		UInt32 _cutValue = 0xFF;
+		UInt32 _hashMask;
+		UInt32 _hashSizeSum = 0;
+
+		bool HASH_ARRAY = true;
+
+		const UInt32 kHash2Size = 1 << 10;
+		const UInt32 kHash3Size = 1 << 16;
+		const UInt32 kBT2HashSize = 1 << 16;
+		const UInt32 kStartMaxLen = 1;
+		const UInt32 kHash3Offset = kHash2Size;
+		const UInt32 kEmptyHashValue = 0;
+		const UInt32 kMaxValForNormalize = ((UInt32)1 << 31) - 1;
+	
+		UInt32 kNumHashDirectBytes = 0;
+		UInt32 kMinMatchCheck = 4;
+		UInt32 kFixHashSize = kHash2Size + kHash3Size;
+		
+		public void SetType(int numHashBytes)
+		{
+			HASH_ARRAY = (numHashBytes > 2);
+			if (HASH_ARRAY)
+			{
+				kNumHashDirectBytes = 0;
+				kMinMatchCheck = 4;
+				kFixHashSize = kHash2Size + kHash3Size;
+			}
+			else
+			{
+				kNumHashDirectBytes = 2;
+				kMinMatchCheck = 2 + 1;
+				kFixHashSize = 0;
+			}
+		}
+
+		public new void SetStream(System.IO.Stream stream) { base.SetStream(stream); }
+		public new void ReleaseStream() { base.ReleaseStream(); }
+		
+		public new void Init()
+		{
+			base.Init();
+			for (UInt32 i = 0; i < _hashSizeSum; i++)
+				_hash[i] = kEmptyHashValue;
+			_cyclicBufferPos = 0;
+			ReduceOffsets(-1);
+		}
+
+		public new void MovePos()
+		{
+			if (++_cyclicBufferPos >= _cyclicBufferSize)
+				_cyclicBufferPos = 0;
+			base.MovePos();
+			if (_pos == kMaxValForNormalize)
+				Normalize();
+		}
+
+		public new Byte GetIndexByte(Int32 index) { return base.GetIndexByte(index); }
+
+		public new UInt32 GetMatchLen(Int32 index, UInt32 distance, UInt32 limit)
+		{ return base.GetMatchLen(index, distance, limit); }
+
+		public new UInt32 GetNumAvailableBytes() { return base.GetNumAvailableBytes(); }
+
+		public void Create(UInt32 historySize, UInt32 keepAddBufferBefore,
+				UInt32 matchMaxLen, UInt32 keepAddBufferAfter)
+		{
+			if (historySize > kMaxValForNormalize - 256)
+				throw new Exception();
+			_cutValue = 16 + (matchMaxLen >> 1);
+				
+			UInt32 windowReservSize = (historySize + keepAddBufferBefore +
+					matchMaxLen + keepAddBufferAfter) / 2 + 256;
+
+			base.Create(historySize + keepAddBufferBefore, matchMaxLen + keepAddBufferAfter, windowReservSize);
+
+			_matchMaxLen = matchMaxLen;
+
+			UInt32 cyclicBufferSize = historySize + 1;
+			if (_cyclicBufferSize != cyclicBufferSize)
+				_son = new UInt32[(_cyclicBufferSize = cyclicBufferSize) * 2];
+
+			UInt32 hs = kBT2HashSize;
+
+			if (HASH_ARRAY)
+			{
+				hs = historySize - 1;
+				hs |= (hs >> 1);
+				hs |= (hs >> 2);
+				hs |= (hs >> 4);
+				hs |= (hs >> 8);
+				hs >>= 1;
+				hs |= 0xFFFF;
+				if (hs > (1 << 24))
+					hs >>= 1;
+				_hashMask = hs;
+				hs++;
+				hs += kFixHashSize;
+			}
+			if (hs != _hashSizeSum)
+				_hash = new UInt32[_hashSizeSum = hs];
+		}
+
+		public UInt32 GetMatches(UInt32[] distances)
+		{
+			UInt32 lenLimit;
+			if (_pos + _matchMaxLen <= _streamPos)
+				lenLimit = _matchMaxLen;
+			else
+			{
+				lenLimit = _streamPos - _pos;
+				if (lenLimit < kMinMatchCheck)
+				{
+					MovePos();
+					return 0;
+				}
+			}
+
+			UInt32 offset = 0;
+			UInt32 matchMinPos = (_pos > _cyclicBufferSize) ? (_pos - _cyclicBufferSize) : 0;
+			UInt32 cur = _bufferOffset + _pos;
+			UInt32 maxLen = kStartMaxLen; // to avoid items for len < hashSize;
+			UInt32 hashValue, hash2Value = 0, hash3Value = 0;
+
+			if (HASH_ARRAY)
+			{
+				UInt32 temp = CRC.Table[_bufferBase[cur]] ^ _bufferBase[cur + 1];
+				hash2Value = temp & (kHash2Size - 1);
+				temp ^= ((UInt32)(_bufferBase[cur + 2]) << 8);
+				hash3Value = temp & (kHash3Size - 1);
+				hashValue = (temp ^ (CRC.Table[_bufferBase[cur + 3]] << 5)) & _hashMask;
+			}
+			else
+				hashValue = _bufferBase[cur] ^ ((UInt32)(_bufferBase[cur + 1]) << 8);
+
+			UInt32 curMatch = _hash[kFixHashSize + hashValue];
+			if (HASH_ARRAY)
+			{
+				UInt32 curMatch2 = _hash[hash2Value];
+				UInt32 curMatch3 = _hash[kHash3Offset + hash3Value];
+				_hash[hash2Value] = _pos;
+				_hash[kHash3Offset + hash3Value] = _pos;
+				if (curMatch2 > matchMinPos)
+					if (_bufferBase[_bufferOffset + curMatch2] == _bufferBase[cur])
+					{
+						distances[offset++] = maxLen = 2;
+						distances[offset++] = _pos - curMatch2 - 1;
+					}
+				if (curMatch3 > matchMinPos)
+					if (_bufferBase[_bufferOffset + curMatch3] == _bufferBase[cur])
+					{
+						if (curMatch3 == curMatch2)
+							offset -= 2;
+						distances[offset++] = maxLen = 3;
+						distances[offset++] = _pos - curMatch3 - 1;
+						curMatch2 = curMatch3;
+					}
+				if (offset != 0 && curMatch2 == curMatch)
+				{
+					offset -= 2;
+					maxLen = kStartMaxLen;
+				}
+			}
+
+			_hash[kFixHashSize + hashValue] = _pos;
+
+			UInt32 ptr0 = (_cyclicBufferPos << 1) + 1;
+			UInt32 ptr1 = (_cyclicBufferPos << 1);
+
+			UInt32 len0, len1;
+			len0 = len1 = kNumHashDirectBytes;
+			
+			if (kNumHashDirectBytes != 0)
+			{
+				if (curMatch > matchMinPos)
+				{
+					if (_bufferBase[_bufferOffset + curMatch + kNumHashDirectBytes] !=
+							_bufferBase[cur + kNumHashDirectBytes])
+					{
+						distances[offset++] = maxLen = kNumHashDirectBytes;
+						distances[offset++] = _pos - curMatch - 1;
+					}
+				}
+			}
+			
+			UInt32 count = _cutValue;
+			
+			while(true)
+			{
+				if(curMatch <= matchMinPos || count-- == 0)
+				{
+					_son[ptr0] = _son[ptr1] = kEmptyHashValue;
+					break;
+				}
+				UInt32 delta = _pos - curMatch;
+				UInt32 cyclicPos = ((delta <= _cyclicBufferPos) ?
+							(_cyclicBufferPos - delta) :
+							(_cyclicBufferPos - delta + _cyclicBufferSize)) << 1;
+
+				UInt32 pby1 = _bufferOffset + curMatch;
+				UInt32 len = Math.Min(len0, len1);
+				if (_bufferBase[pby1 + len] == _bufferBase[cur + len])
+				{
+					while(++len != lenLimit)
+						if (_bufferBase[pby1 + len] != _bufferBase[cur + len])
+							break;
+					if (maxLen < len)
+					{
+						distances[offset++] = maxLen = len;
+						distances[offset++] = delta - 1;
+						if (len == lenLimit)
+						{
+							_son[ptr1] = _son[cyclicPos];
+							_son[ptr0] = _son[cyclicPos + 1];
+							break;
+						}
+					}
+				}
+				if (_bufferBase[pby1 + len] < _bufferBase[cur + len])
+				{
+					_son[ptr1] = curMatch;
+					ptr1 = cyclicPos + 1;
+					curMatch = _son[ptr1];
+					len1 = len;
+				}
+				else
+				{
+					_son[ptr0] = curMatch;
+					ptr0 = cyclicPos;
+					curMatch = _son[ptr0];
+					len0 = len;
+				}
+			}
+			MovePos();
+			return offset;
+		}
+
+		public void Skip(UInt32 num)
+		{
+			do
+			{
+				UInt32 lenLimit;
+				if (_pos + _matchMaxLen <= _streamPos)
+					lenLimit = _matchMaxLen;
+				else
+				{
+					lenLimit = _streamPos - _pos;
+					if (lenLimit < kMinMatchCheck)
+					{
+						MovePos();
+						continue;
+					}
+				}
+
+				UInt32 matchMinPos = (_pos > _cyclicBufferSize) ? (_pos - _cyclicBufferSize) : 0;
+				UInt32 cur = _bufferOffset + _pos;
+
+				UInt32 hashValue;
+
+				if (HASH_ARRAY)
+				{
+					UInt32 temp = CRC.Table[_bufferBase[cur]] ^ _bufferBase[cur + 1];
+					UInt32 hash2Value = temp & (kHash2Size - 1);
+					_hash[hash2Value] = _pos;
+					temp ^= ((UInt32)(_bufferBase[cur + 2]) << 8);
+					UInt32 hash3Value = temp & (kHash3Size - 1);
+					_hash[kHash3Offset + hash3Value] = _pos;
+					hashValue = (temp ^ (CRC.Table[_bufferBase[cur + 3]] << 5)) & _hashMask;
+				}
+				else
+					hashValue = _bufferBase[cur] ^ ((UInt32)(_bufferBase[cur + 1]) << 8);
+
+				UInt32 curMatch = _hash[kFixHashSize + hashValue];
+				_hash[kFixHashSize + hashValue] = _pos;
+
+				UInt32 ptr0 = (_cyclicBufferPos << 1) + 1;
+				UInt32 ptr1 = (_cyclicBufferPos << 1);
+
+				UInt32 len0, len1;
+				len0 = len1 = kNumHashDirectBytes;
+
+				UInt32 count = _cutValue;
+				while (true)
+				{
+					if (curMatch <= matchMinPos || count-- == 0)
+					{
+						_son[ptr0] = _son[ptr1] = kEmptyHashValue;
+						break;
+					}
+
+					UInt32 delta = _pos - curMatch;
+					UInt32 cyclicPos = ((delta <= _cyclicBufferPos) ?
+								(_cyclicBufferPos - delta) :
+								(_cyclicBufferPos - delta + _cyclicBufferSize)) << 1;
+
+					UInt32 pby1 = _bufferOffset + curMatch;
+					UInt32 len = Math.Min(len0, len1);
+					if (_bufferBase[pby1 + len] == _bufferBase[cur + len])
+					{
+						while (++len != lenLimit)
+							if (_bufferBase[pby1 + len] != _bufferBase[cur + len])
+								break;
+						if (len == lenLimit)
+						{
+							_son[ptr1] = _son[cyclicPos];
+							_son[ptr0] = _son[cyclicPos + 1];
+							break;
+						}
+					}
+					if (_bufferBase[pby1 + len] < _bufferBase[cur + len])
+					{
+						_son[ptr1] = curMatch;
+						ptr1 = cyclicPos + 1;
+						curMatch = _son[ptr1];
+						len1 = len;
+					}
+					else
+					{
+						_son[ptr0] = curMatch;
+						ptr0 = cyclicPos;
+						curMatch = _son[ptr0];
+						len0 = len;
+					}
+				}
+				MovePos();
+			}
+			while (--num != 0);
+		}
+
+		void NormalizeLinks(UInt32[] items, UInt32 numItems, UInt32 subValue)
+		{
+			for (UInt32 i = 0; i < numItems; i++)
+			{
+				UInt32 value = items[i];
+				if (value <= subValue)
+					value = kEmptyHashValue;
+				else
+					value -= subValue;
+				items[i] = value;
+			}
+		}
+
+		void Normalize()
+		{
+			UInt32 subValue = _pos - _cyclicBufferSize;
+			NormalizeLinks(_son, _cyclicBufferSize * 2, subValue);
+			NormalizeLinks(_hash, _hashSizeSum, subValue);
+			ReduceOffsets((Int32)subValue);
+		}
+
+		public void SetCutValue(UInt32 cutValue) { _cutValue = cutValue; }
+	}
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/misc/libphysfs/lzma/CS/7zip/Compress/LZ/LzInWindow.cs	Mon Apr 10 12:06:43 2017 -0400
@@ -0,0 +1,132 @@
+// LzInWindow.cs
+
+using System;
+
+namespace SevenZip.Compression.LZ
+{
+	public class InWindow
+	{
+		public Byte[] _bufferBase = null; // pointer to buffer with data
+		System.IO.Stream _stream;
+		UInt32 _posLimit; // offset (from _buffer) of first byte when new block reading must be done
+		bool _streamEndWasReached; // if (true) then _streamPos shows real end of stream
+
+		UInt32 _pointerToLastSafePosition;
+
+		public UInt32 _bufferOffset;
+
+		public UInt32 _blockSize; // Size of Allocated memory block
+		public UInt32 _pos; // offset (from _buffer) of curent byte
+		UInt32 _keepSizeBefore; // how many BYTEs must be kept in buffer before _pos
+		UInt32 _keepSizeAfter; // how many BYTEs must be kept buffer after _pos
+		public UInt32 _streamPos; // offset (from _buffer) of first not read byte from Stream
+
+		public void MoveBlock()
+		{
+			UInt32 offset = (UInt32)(_bufferOffset) + _pos - _keepSizeBefore;
+			// we need one additional byte, since MovePos moves on 1 byte.
+			if (offset > 0)
+				offset--;
+			
+			UInt32 numBytes = (UInt32)(_bufferOffset) + _streamPos - offset;
+
+			// check negative offset ????
+			for (UInt32 i = 0; i < numBytes; i++)
+				_bufferBase[i] = _bufferBase[offset + i];
+			_bufferOffset -= offset;
+		}
+
+		public virtual void ReadBlock()
+		{
+			if (_streamEndWasReached)
+				return;
+			while (true)
+			{
+				int size = (int)((0 - _bufferOffset) + _blockSize - _streamPos);
+				if (size == 0)
+					return;
+				int numReadBytes = _stream.Read(_bufferBase, (int)(_bufferOffset + _streamPos), size);
+				if (numReadBytes == 0)
+				{
+					_posLimit = _streamPos;
+					UInt32 pointerToPostion = _bufferOffset + _posLimit;
+					if (pointerToPostion > _pointerToLastSafePosition)
+						_posLimit = (UInt32)(_pointerToLastSafePosition - _bufferOffset);
+
+					_streamEndWasReached = true;
+					return;
+				}
+				_streamPos += (UInt32)numReadBytes;
+				if (_streamPos >= _pos + _keepSizeAfter)
+					_posLimit = _streamPos - _keepSizeAfter;
+			}
+		}
+
+		void Free() { _bufferBase = null; }
+
+		public void Create(UInt32 keepSizeBefore, UInt32 keepSizeAfter, UInt32 keepSizeReserv)
+		{
+			_keepSizeBefore = keepSizeBefore;
+			_keepSizeAfter = keepSizeAfter;
+			UInt32 blockSize = keepSizeBefore + keepSizeAfter + keepSizeReserv;
+			if (_bufferBase == null || _blockSize != blockSize)
+			{
+				Free();
+				_blockSize = blockSize;
+				_bufferBase = new Byte[_blockSize];
+			}
+			_pointerToLastSafePosition = _blockSize - keepSizeAfter;
+		}
+
+		public void SetStream(System.IO.Stream stream) { _stream = stream; }
+		public void ReleaseStream() { _stream = null; }
+
+		public void Init()
+		{
+			_bufferOffset = 0;
+			_pos = 0;
+			_streamPos = 0;
+			_streamEndWasReached = false;
+			ReadBlock();
+		}
+
+		public void MovePos()
+		{
+			_pos++;
+			if (_pos > _posLimit)
+			{
+				UInt32 pointerToPostion = _bufferOffset + _pos;
+				if (pointerToPostion > _pointerToLastSafePosition)
+					MoveBlock();
+				ReadBlock();
+			}
+		}
+
+		public Byte GetIndexByte(Int32 index) { return _bufferBase[_bufferOffset + _pos + index]; }
+
+		// index + limit have not to exceed _keepSizeAfter;
+		public UInt32 GetMatchLen(Int32 index, UInt32 distance, UInt32 limit)
+		{
+			if (_streamEndWasReached)
+				if ((_pos + index) + limit > _streamPos)
+					limit = _streamPos - (UInt32)(_pos + index);
+			distance++;
+			// Byte *pby = _buffer + (size_t)_pos + index;
+			UInt32 pby = _bufferOffset + _pos + (UInt32)index;
+
+			UInt32 i;
+			for (i = 0; i < limit && _bufferBase[pby + i] == _bufferBase[pby + i - distance]; i++);
+			return i;
+		}
+
+		public UInt32 GetNumAvailableBytes() { return _streamPos - _pos; }
+
+		public void ReduceOffsets(Int32 subValue)
+		{
+			_bufferOffset += (UInt32)subValue;
+			_posLimit -= (UInt32)subValue;
+			_pos -= (UInt32)subValue;
+			_streamPos -= (UInt32)subValue;
+		}
+	}
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/misc/libphysfs/lzma/CS/7zip/Compress/LZ/LzOutWindow.cs	Mon Apr 10 12:06:43 2017 -0400
@@ -0,0 +1,110 @@
+// LzOutWindow.cs
+
+namespace SevenZip.Compression.LZ
+{
+	public class OutWindow
+	{
+		byte[] _buffer = null;
+		uint _pos;
+		uint _windowSize = 0;
+		uint _streamPos;
+		System.IO.Stream _stream;
+
+		public uint TrainSize = 0;
+
+		public void Create(uint windowSize)
+		{
+			if (_windowSize != windowSize)
+			{
+				// System.GC.Collect();
+				_buffer = new byte[windowSize];
+			}
+			_windowSize = windowSize;
+			_pos = 0;
+			_streamPos = 0;
+		}
+
+		public void Init(System.IO.Stream stream, bool solid)
+		{
+			ReleaseStream();
+			_stream = stream;
+			if (!solid)
+			{
+				_streamPos = 0;
+				_pos = 0;
+				TrainSize = 0;
+			}
+		}
+	
+		public bool Train(System.IO.Stream stream)
+		{
+			long len = stream.Length;
+			uint size = (len < _windowSize) ? (uint)len : _windowSize;
+			TrainSize = size;
+			stream.Position = len - size;
+			_streamPos = _pos = 0;
+			while (size > 0)
+			{
+				uint curSize = _windowSize - _pos;
+				if (size < curSize)
+					curSize = size;
+				int numReadBytes = stream.Read(_buffer, (int)_pos, (int)curSize);
+				if (numReadBytes == 0)
+					return false;
+				size -= (uint)numReadBytes;
+				_pos += (uint)numReadBytes;
+				_streamPos += (uint)numReadBytes;
+				if (_pos == _windowSize)
+					_streamPos = _pos = 0;
+			}
+			return true;
+		}
+
+		public void ReleaseStream()
+		{
+			Flush();
+			_stream = null;
+		}
+
+		public void Flush()
+		{
+			uint size = _pos - _streamPos;
+			if (size == 0)
+				return;
+			_stream.Write(_buffer, (int)_streamPos, (int)size);
+			if (_pos >= _windowSize)
+				_pos = 0;
+			_streamPos = _pos;
+		}
+
+		public void CopyBlock(uint distance, uint len)
+		{
+			uint pos = _pos - distance - 1;
+			if (pos >= _windowSize)
+				pos += _windowSize;
+			for (; len > 0; len--)
+			{
+				if (pos >= _windowSize)
+					pos = 0;
+				_buffer[_pos++] = _buffer[pos++];
+				if (_pos >= _windowSize)
+					Flush();
+			}
+		}
+
+		public void PutByte(byte b)
+		{
+			_buffer[_pos++] = b;
+			if (_pos >= _windowSize)
+				Flush();
+		}
+
+		public byte GetByte(uint distance)
+		{
+			uint pos = _pos - distance - 1;
+			if (pos >= _windowSize)
+				pos += _windowSize;
+			return _buffer[pos];
+		}
+	}
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/misc/libphysfs/lzma/CS/7zip/Compress/LZMA/LzmaBase.cs	Mon Apr 10 12:06:43 2017 -0400
@@ -0,0 +1,76 @@
+// LzmaBase.cs
+
+namespace SevenZip.Compression.LZMA
+{
+	internal abstract class Base
+	{
+		public const uint kNumRepDistances = 4;
+		public const uint kNumStates = 12;
+
+		// static byte []kLiteralNextStates  = {0, 0, 0, 0, 1, 2, 3, 4,  5,  6,   4, 5};
+		// static byte []kMatchNextStates    = {7, 7, 7, 7, 7, 7, 7, 10, 10, 10, 10, 10};
+		// static byte []kRepNextStates      = {8, 8, 8, 8, 8, 8, 8, 11, 11, 11, 11, 11};
+		// static byte []kShortRepNextStates = {9, 9, 9, 9, 9, 9, 9, 11, 11, 11, 11, 11};
+
+		public struct State
+		{
+			public uint Index;
+			public void Init() { Index = 0; }
+			public void UpdateChar()
+			{
+				if (Index < 4) Index = 0;
+				else if (Index < 10) Index -= 3;
+				else Index -= 6;
+			}
+			public void UpdateMatch() { Index = (uint)(Index < 7 ? 7 : 10); }
+			public void UpdateRep() { Index = (uint)(Index < 7 ? 8 : 11); }
+			public void UpdateShortRep() { Index = (uint)(Index < 7 ? 9 : 11); }
+			public bool IsCharState() { return Index < 7; }
+		}
+
+		public const int kNumPosSlotBits = 6;
+		public const int kDicLogSizeMin = 0;
+		// public const int kDicLogSizeMax = 30;
+		// public const uint kDistTableSizeMax = kDicLogSizeMax * 2;
+
+		public const int kNumLenToPosStatesBits = 2; // it's for speed optimization
+		public const uint kNumLenToPosStates = 1 << kNumLenToPosStatesBits;
+
+		public const uint kMatchMinLen = 2;
+
+		public static uint GetLenToPosState(uint len)
+		{
+			len -= kMatchMinLen;
+			if (len < kNumLenToPosStates)
+				return len;
+			return (uint)(kNumLenToPosStates - 1);
+		}
+
+		public const int kNumAlignBits = 4;
+		public const uint kAlignTableSize = 1 << kNumAlignBits;
+		public const uint kAlignMask = (kAlignTableSize - 1);
+
+		public const uint kStartPosModelIndex = 4;
+		public const uint kEndPosModelIndex = 14;
+		public const uint kNumPosModels = kEndPosModelIndex - kStartPosModelIndex;
+
+		public const uint kNumFullDistances = 1 << ((int)kEndPosModelIndex / 2);
+
+		public const uint kNumLitPosStatesBitsEncodingMax = 4;
+		public const uint kNumLitContextBitsMax = 8;
+
+		public const int kNumPosStatesBitsMax = 4;
+		public const uint kNumPosStatesMax = (1 << kNumPosStatesBitsMax);
+		public const int kNumPosStatesBitsEncodingMax = 4;
+		public const uint kNumPosStatesEncodingMax = (1 << kNumPosStatesBitsEncodingMax);
+
+		public const int kNumLowLenBits = 3;
+		public const int kNumMidLenBits = 3;
+		public const int kNumHighLenBits = 8;
+		public const uint kNumLowLenSymbols = 1 << kNumLowLenBits;
+		public const uint kNumMidLenSymbols = 1 << kNumMidLenBits;
+		public const uint kNumLenSymbols = kNumLowLenSymbols + kNumMidLenSymbols +
+				(1 << kNumHighLenBits);
+		public const uint kMatchMaxLen = kMatchMinLen + kNumLenSymbols - 1;
+	}
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/misc/libphysfs/lzma/CS/7zip/Compress/LZMA/LzmaDecoder.cs	Mon Apr 10 12:06:43 2017 -0400
@@ -0,0 +1,398 @@
+// LzmaDecoder.cs
+
+using System;
+
+namespace SevenZip.Compression.LZMA
+{
+	using RangeCoder;
+
+	public class Decoder : ICoder, ISetDecoderProperties // ,System.IO.Stream
+	{
+		class LenDecoder
+		{
+			BitDecoder m_Choice = new BitDecoder();
+			BitDecoder m_Choice2 = new BitDecoder();
+			BitTreeDecoder[] m_LowCoder = new BitTreeDecoder[Base.kNumPosStatesMax];
+			BitTreeDecoder[] m_MidCoder = new BitTreeDecoder[Base.kNumPosStatesMax];
+			BitTreeDecoder m_HighCoder = new BitTreeDecoder(Base.kNumHighLenBits);
+			uint m_NumPosStates = 0;
+
+			public void Create(uint numPosStates)
+			{
+				for (uint posState = m_NumPosStates; posState < numPosStates; posState++)
+				{
+					m_LowCoder[posState] = new BitTreeDecoder(Base.kNumLowLenBits);
+					m_MidCoder[posState] = new BitTreeDecoder(Base.kNumMidLenBits);
+				}
+				m_NumPosStates = numPosStates;
+			}
+
+			public void Init()
+			{
+				m_Choice.Init();
+				for (uint posState = 0; posState < m_NumPosStates; posState++)
+				{
+					m_LowCoder[posState].Init();
+					m_MidCoder[posState].Init();
+				}
+				m_Choice2.Init();
+				m_HighCoder.Init();
+			}
+
+			public uint Decode(RangeCoder.Decoder rangeDecoder, uint posState)
+			{
+				if (m_Choice.Decode(rangeDecoder) == 0)
+					return m_LowCoder[posState].Decode(rangeDecoder);
+				else
+				{
+					uint symbol = Base.kNumLowLenSymbols;
+					if (m_Choice2.Decode(rangeDecoder) == 0)
+						symbol += m_MidCoder[posState].Decode(rangeDecoder);
+					else
+					{
+						symbol += Base.kNumMidLenSymbols;
+						symbol += m_HighCoder.Decode(rangeDecoder);
+					}
+					return symbol;
+				}
+			}
+		}
+
+		class LiteralDecoder
+		{
+			struct Decoder2
+			{
+				BitDecoder[] m_Decoders;
+				public void Create() { m_Decoders = new BitDecoder[0x300]; }
+				public void Init() { for (int i = 0; i < 0x300; i++) m_Decoders[i].Init(); }
+
+				public byte DecodeNormal(RangeCoder.Decoder rangeDecoder)
+				{
+					uint symbol = 1;
+					do
+						symbol = (symbol << 1) | m_Decoders[symbol].Decode(rangeDecoder);
+					while (symbol < 0x100);
+					return (byte)symbol;
+				}
+
+				public byte DecodeWithMatchByte(RangeCoder.Decoder rangeDecoder, byte matchByte)
+				{
+					uint symbol = 1;
+					do
+					{
+						uint matchBit = (uint)(matchByte >> 7) & 1;
+						matchByte <<= 1;
+						uint bit = m_Decoders[((1 + matchBit) << 8) + symbol].Decode(rangeDecoder);
+						symbol = (symbol << 1) | bit;
+						if (matchBit != bit)
+						{
+							while (symbol < 0x100)
+								symbol = (symbol << 1) | m_Decoders[symbol].Decode(rangeDecoder);
+							break;
+						}
+					}
+					while (symbol < 0x100);
+					return (byte)symbol;
+				}
+			}
+
+			Decoder2[] m_Coders;
+			int m_NumPrevBits;
+			int m_NumPosBits;
+			uint m_PosMask;
+
+			public void Create(int numPosBits, int numPrevBits)
+			{
+				if (m_Coders != null && m_NumPrevBits == numPrevBits &&
+					m_NumPosBits == numPosBits)
+					return;
+				m_NumPosBits = numPosBits;
+				m_PosMask = ((uint)1 << numPosBits) - 1;
+				m_NumPrevBits = numPrevBits;
+				uint numStates = (uint)1 << (m_NumPrevBits + m_NumPosBits);
+				m_Coders = new Decoder2[numStates];
+				for (uint i = 0; i < numStates; i++)
+					m_Coders[i].Create();
+			}
+
+			public void Init()
+			{
+				uint numStates = (uint)1 << (m_NumPrevBits + m_NumPosBits);
+				for (uint i = 0; i < numStates; i++)
+					m_Coders[i].Init();
+			}
+
+			uint GetState(uint pos, byte prevByte)
+			{ return ((pos & m_PosMask) << m_NumPrevBits) + (uint)(prevByte >> (8 - m_NumPrevBits)); }
+
+			public byte DecodeNormal(RangeCoder.Decoder rangeDecoder, uint pos, byte prevByte)
+			{ return m_Coders[GetState(pos, prevByte)].DecodeNormal(rangeDecoder); }
+
+			public byte DecodeWithMatchByte(RangeCoder.Decoder rangeDecoder, uint pos, byte prevByte, byte matchByte)
+			{ return m_Coders[GetState(pos, prevByte)].DecodeWithMatchByte(rangeDecoder, matchByte); }
+		};
+
+		LZ.OutWindow m_OutWindow = new LZ.OutWindow();
+		RangeCoder.Decoder m_RangeDecoder = new RangeCoder.Decoder();
+
+		BitDecoder[] m_IsMatchDecoders = new BitDecoder[Base.kNumStates << Base.kNumPosStatesBitsMax];
+		BitDecoder[] m_IsRepDecoders = new BitDecoder[Base.kNumStates];
+		BitDecoder[] m_IsRepG0Decoders = new BitDecoder[Base.kNumStates];
+		BitDecoder[] m_IsRepG1Decoders = new BitDecoder[Base.kNumStates];
+		BitDecoder[] m_IsRepG2Decoders = new BitDecoder[Base.kNumStates];
+		BitDecoder[] m_IsRep0LongDecoders = new BitDecoder[Base.kNumStates << Base.kNumPosStatesBitsMax];
+
+		BitTreeDecoder[] m_PosSlotDecoder = new BitTreeDecoder[Base.kNumLenToPosStates];
+		BitDecoder[] m_PosDecoders = new BitDecoder[Base.kNumFullDistances - Base.kEndPosModelIndex];
+
+		BitTreeDecoder m_PosAlignDecoder = new BitTreeDecoder(Base.kNumAlignBits);
+
+		LenDecoder m_LenDecoder = new LenDecoder();
+		LenDecoder m_RepLenDecoder = new LenDecoder();
+
+		LiteralDecoder m_LiteralDecoder = new LiteralDecoder();
+
+		uint m_DictionarySize;
+		uint m_DictionarySizeCheck;
+
+		uint m_PosStateMask;
+
+		public Decoder()
+		{
+			m_DictionarySize = 0xFFFFFFFF;
+			for (int i = 0; i < Base.kNumLenToPosStates; i++)
+				m_PosSlotDecoder[i] = new BitTreeDecoder(Base.kNumPosSlotBits);
+		}
+
+		void SetDictionarySize(uint dictionarySize)
+		{
+			if (m_DictionarySize != dictionarySize)
+			{
+				m_DictionarySize = dictionarySize;
+				m_DictionarySizeCheck = Math.Max(m_DictionarySize, 1);
+				uint blockSize = Math.Max(m_DictionarySizeCheck, (1 << 12));
+				m_OutWindow.Create(blockSize);
+			}
+		}
+
+		void SetLiteralProperties(int lp, int lc)
+		{
+			if (lp > 8)
+				throw new InvalidParamException();
+			if (lc > 8)
+				throw new InvalidParamException();
+			m_LiteralDecoder.Create(lp, lc);
+		}
+
+		void SetPosBitsProperties(int pb)
+		{
+			if (pb > Base.kNumPosStatesBitsMax)
+				throw new InvalidParamException();
+			uint numPosStates = (uint)1 << pb;
+			m_LenDecoder.Create(numPosStates);
+			m_RepLenDecoder.Create(numPosStates);
+			m_PosStateMask = numPosStates - 1;
+		}
+
+		bool _solid = false;
+		void Init(System.IO.Stream inStream, System.IO.Stream outStream)
+		{
+			m_RangeDecoder.Init(inStream);
+			m_OutWindow.Init(outStream, _solid);
+
+			uint i;
+			for (i = 0; i < Base.kNumStates; i++)
+			{
+				for (uint j = 0; j <= m_PosStateMask; j++)
+				{
+					uint index = (i << Base.kNumPosStatesBitsMax) + j;
+					m_IsMatchDecoders[index].Init();
+					m_IsRep0LongDecoders[index].Init();
+				}
+				m_IsRepDecoders[i].Init();
+				m_IsRepG0Decoders[i].Init();
+				m_IsRepG1Decoders[i].Init();
+				m_IsRepG2Decoders[i].Init();
+			}
+
+			m_LiteralDecoder.Init();
+			for (i = 0; i < Base.kNumLenToPosStates; i++)
+				m_PosSlotDecoder[i].Init();
+			// m_PosSpecDecoder.Init();
+			for (i = 0; i < Base.kNumFullDistances - Base.kEndPosModelIndex; i++)
+				m_PosDecoders[i].Init();
+
+			m_LenDecoder.Init();
+			m_RepLenDecoder.Init();
+			m_PosAlignDecoder.Init();
+		}
+
+		public void Code(System.IO.Stream inStream, System.IO.Stream outStream,
+			Int64 inSize, Int64 outSize, ICodeProgress progress)
+		{
+			Init(inStream, outStream);
+
+			Base.State state = new Base.State();
+			state.Init();
+			uint rep0 = 0, rep1 = 0, rep2 = 0, rep3 = 0;
+
+			UInt64 nowPos64 = 0;
+			UInt64 outSize64 = (UInt64)outSize;
+			if (nowPos64 < outSize64)
+			{
+				if (m_IsMatchDecoders[state.Index << Base.kNumPosStatesBitsMax].Decode(m_RangeDecoder) != 0)
+					throw new DataErrorException();
+				state.UpdateChar();
+				byte b = m_LiteralDecoder.DecodeNormal(m_RangeDecoder, 0, 0);
+				m_OutWindow.PutByte(b);
+				nowPos64++;
+			}
+			while (nowPos64 < outSize64)
+			{
+				// UInt64 next = Math.Min(nowPos64 + (1 << 18), outSize64);
+					// while(nowPos64 < next)
+				{
+					uint posState = (uint)nowPos64 & m_PosStateMask;
+					if (m_IsMatchDecoders[(state.Index << Base.kNumPosStatesBitsMax) + posState].Decode(m_RangeDecoder) == 0)
+					{
+						byte b;
+						byte prevByte = m_OutWindow.GetByte(0);
+						if (!state.IsCharState())
+							b = m_LiteralDecoder.DecodeWithMatchByte(m_RangeDecoder,
+								(uint)nowPos64, prevByte, m_OutWindow.GetByte(rep0));
+						else
+							b = m_LiteralDecoder.DecodeNormal(m_RangeDecoder, (uint)nowPos64, prevByte);
+						m_OutWindow.PutByte(b);
+						state.UpdateChar();
+						nowPos64++;
+					}
+					else
+					{
+						uint len;
+						if (m_IsRepDecoders[state.Index].Decode(m_RangeDecoder) == 1)
+						{
+							if (m_IsRepG0Decoders[state.Index].Decode(m_RangeDecoder) == 0)
+							{
+								if (m_IsRep0LongDecoders[(state.Index << Base.kNumPosStatesBitsMax) + posState].Decode(m_RangeDecoder) == 0)
+								{
+									state.UpdateShortRep();
+									m_OutWindow.PutByte(m_OutWindow.GetByte(rep0));
+									nowPos64++;
+									continue;
+								}
+							}
+							else
+							{
+								UInt32 distance;
+								if (m_IsRepG1Decoders[state.Index].Decode(m_RangeDecoder) == 0)
+								{
+									distance = rep1;
+								}
+								else
+								{
+									if (m_IsRepG2Decoders[state.Index].Decode(m_RangeDecoder) == 0)
+										distance = rep2;
+									else
+									{
+										distance = rep3;
+										rep3 = rep2;
+									}
+									rep2 = rep1;
+								}
+								rep1 = rep0;
+								rep0 = distance;
+							}
+							len = m_RepLenDecoder.Decode(m_RangeDecoder, posState) + Base.kMatchMinLen;
+							state.UpdateRep();
+						}
+						else
+						{
+							rep3 = rep2;
+							rep2 = rep1;
+							rep1 = rep0;
+							len = Base.kMatchMinLen + m_LenDecoder.Decode(m_RangeDecoder, posState);
+							state.UpdateMatch();
+							uint posSlot = m_PosSlotDecoder[Base.GetLenToPosState(len)].Decode(m_RangeDecoder);
+							if (posSlot >= Base.kStartPosModelIndex)
+							{
+								int numDirectBits = (int)((posSlot >> 1) - 1);
+								rep0 = ((2 | (posSlot & 1)) << numDirectBits);
+								if (posSlot < Base.kEndPosModelIndex)
+									rep0 += BitTreeDecoder.ReverseDecode(m_PosDecoders,
+											rep0 - posSlot - 1, m_RangeDecoder, numDirectBits);
+								else
+								{
+									rep0 += (m_RangeDecoder.DecodeDirectBits(
+										numDirectBits - Base.kNumAlignBits) << Base.kNumAlignBits);
+									rep0 += m_PosAlignDecoder.ReverseDecode(m_RangeDecoder);
+								}
+							}
+							else
+								rep0 = posSlot;
+						}
+						if (rep0 >= m_OutWindow.TrainSize + nowPos64 || rep0 >= m_DictionarySizeCheck)
+						{
+							if (rep0 == 0xFFFFFFFF)
+								break;
+							throw new DataErrorException();
+						}
+						m_OutWindow.CopyBlock(rep0, len);
+						nowPos64 += len;
+					}
+				}
+			}
+			m_OutWindow.Flush();
+			m_OutWindow.ReleaseStream();
+			m_RangeDecoder.ReleaseStream();
+		}
+
+		public void SetDecoderProperties(byte[] properties)
+		{
+			if (properties.Length < 5)
+				throw new InvalidParamException();
+			int lc = properties[0] % 9;
+			int remainder = properties[0] / 9;
+			int lp = remainder % 5;
+			int pb = remainder / 5;
+			if (pb > Base.kNumPosStatesBitsMax)
+				throw new InvalidParamException();
+			UInt32 dictionarySize = 0;
+			for (int i = 0; i < 4; i++)
+				dictionarySize += ((UInt32)(properties[1 + i])) << (i * 8);
+			SetDictionarySize(dictionarySize);
+			SetLiteralProperties(lp, lc);
+			SetPosBitsProperties(pb);
+		}
+
+		public bool Train(System.IO.Stream stream)
+		{
+			_solid = true;
+			return m_OutWindow.Train(stream);
+		}
+
+		/*
+		public override bool CanRead { get { return true; }}
+		public override bool CanWrite { get { return true; }}
+		public override bool CanSeek { get { return true; }}
+		public override long Length { get { return 0; }}
+		public override long Position
+		{
+			get { return 0;	}
+			set { }
+		}
+		public override void Flush() { }
+		public override int Read(byte[] buffer, int offset, int count) 
+		{
+			return 0;
+		}
+		public override void Write(byte[] buffer, int offset, int count)
+		{
+		}
+		public override long Seek(long offset, System.IO.SeekOrigin origin)
+		{
+			return 0;
+		}
+		public override void SetLength(long value) {}
+		*/
+	}
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/misc/libphysfs/lzma/CS/7zip/Compress/LZMA/LzmaEncoder.cs	Mon Apr 10 12:06:43 2017 -0400
@@ -0,0 +1,1480 @@
+// LzmaEncoder.cs
+
+using System;
+
+namespace SevenZip.Compression.LZMA
+{
+	using RangeCoder;
+
+	public class Encoder : ICoder, ISetCoderProperties, IWriteCoderProperties
+	{
+		enum EMatchFinderType
+		{
+			BT2,
+			BT4,
+		};
+
+		const UInt32 kIfinityPrice = 0xFFFFFFF;
+
+		static Byte[] g_FastPos = new Byte[1 << 11];
+
+		static Encoder()
+		{
+			const Byte kFastSlots = 22;
+			int c = 2;
+			g_FastPos[0] = 0;
+			g_FastPos[1] = 1;
+			for (Byte slotFast = 2; slotFast < kFastSlots; slotFast++)
+			{
+				UInt32 k = ((UInt32)1 << ((slotFast >> 1) - 1));
+				for (UInt32 j = 0; j < k; j++, c++)
+					g_FastPos[c] = slotFast;
+			}
+		}
+
+		static UInt32 GetPosSlot(UInt32 pos)
+		{
+			if (pos < (1 << 11))
+				return g_FastPos[pos];
+			if (pos < (1 << 21))
+				return (UInt32)(g_FastPos[pos >> 10] + 20);
+			return (UInt32)(g_FastPos[pos >> 20] + 40);
+		}
+
+		static UInt32 GetPosSlot2(UInt32 pos)
+		{
+			if (pos < (1 << 17))
+				return (UInt32)(g_FastPos[pos >> 6] + 12);
+			if (pos < (1 << 27))
+				return (UInt32)(g_FastPos[pos >> 16] + 32);
+			return (UInt32)(g_FastPos[pos >> 26] + 52);
+		}
+
+		Base.State _state = new Base.State();
+		Byte _previousByte;
+		UInt32[] _repDistances = new UInt32[Base.kNumRepDistances];
+
+		void BaseInit()
+		{
+			_state.Init();
+			_previousByte = 0;
+			for (UInt32 i = 0; i < Base.kNumRepDistances; i++)
+				_repDistances[i] = 0;
+		}
+
+		const int kDefaultDictionaryLogSize = 22;
+		const UInt32 kNumFastBytesDefault = 0x20;
+
+		class LiteralEncoder
+		{
+			public struct Encoder2
+			{
+				BitEncoder[] m_Encoders;
+
+				public void Create() { m_Encoders = new BitEncoder[0x300]; }
+
+				public void Init() { for (int i = 0; i < 0x300; i++) m_Encoders[i].Init(); }
+
+				public void Encode(RangeCoder.Encoder rangeEncoder, byte symbol)
+				{
+					uint context = 1;
+					for (int i = 7; i >= 0; i--)
+					{
+						uint bit = (uint)((symbol >> i) & 1);
+						m_Encoders[context].Encode(rangeEncoder, bit);
+						context = (context << 1) | bit;
+					}
+				}
+
+				public void EncodeMatched(RangeCoder.Encoder rangeEncoder, byte matchByte, byte symbol)
+				{
+					uint context = 1;
+					bool same = true;
+					for (int i = 7; i >= 0; i--)
+					{
+						uint bit = (uint)((symbol >> i) & 1);
+						uint state = context;
+						if (same)
+						{
+							uint matchBit = (uint)((matchByte >> i) & 1);
+							state += ((1 + matchBit) << 8);
+							same = (matchBit == bit);
+						}
+						m_Encoders[state].Encode(rangeEncoder, bit);
+						context = (context << 1) | bit;
+					}
+				}
+
+				public uint GetPrice(bool matchMode, byte matchByte, byte symbol)
+				{
+					uint price = 0;
+					uint context = 1;
+					int i = 7;
+					if (matchMode)
+					{
+						for (; i >= 0; i--)
+						{
+							uint matchBit = (uint)(matchByte >> i) & 1;
+							uint bit = (uint)(symbol >> i) & 1;
+							price += m_Encoders[((1 + matchBit) << 8) + context].GetPrice(bit);
+							context = (context << 1) | bit;
+							if (matchBit != bit)
+							{
+								i--;
+								break;
+							}
+						}
+					}
+					for (; i >= 0; i--)
+					{
+						uint bit = (uint)(symbol >> i) & 1;
+						price += m_Encoders[context].GetPrice(bit);
+						context = (context << 1) | bit;
+					}
+					return price;
+				}
+			}
+
+			Encoder2[] m_Coders;
+			int m_NumPrevBits;
+			int m_NumPosBits;
+			uint m_PosMask;
+
+			public void Create(int numPosBits, int numPrevBits)
+			{
+				if (m_Coders != null && m_NumPrevBits == numPrevBits && m_NumPosBits == numPosBits)
+					return;
+				m_NumPosBits = numPosBits;
+				m_PosMask = ((uint)1 << numPosBits) - 1;
+				m_NumPrevBits = numPrevBits;
+				uint numStates = (uint)1 << (m_NumPrevBits + m_NumPosBits);
+				m_Coders = new Encoder2[numStates];
+				for (uint i = 0; i < numStates; i++)
+					m_Coders[i].Create();
+			}
+
+			public void Init()
+			{
+				uint numStates = (uint)1 << (m_NumPrevBits + m_NumPosBits);
+				for (uint i = 0; i < numStates; i++)
+					m_Coders[i].Init();
+			}
+
+			public Encoder2 GetSubCoder(UInt32 pos, Byte prevByte)
+			{ return m_Coders[((pos & m_PosMask) << m_NumPrevBits) + (uint)(prevByte >> (8 - m_NumPrevBits))]; }
+		}
+
+		class LenEncoder
+		{
+			RangeCoder.BitEncoder _choice = new RangeCoder.BitEncoder();
+			RangeCoder.BitEncoder _choice2 = new RangeCoder.BitEncoder();
+			RangeCoder.BitTreeEncoder[] _lowCoder = new RangeCoder.BitTreeEncoder[Base.kNumPosStatesEncodingMax];
+			RangeCoder.BitTreeEncoder[] _midCoder = new RangeCoder.BitTreeEncoder[Base.kNumPosStatesEncodingMax];
+			RangeCoder.BitTreeEncoder _highCoder = new RangeCoder.BitTreeEncoder(Base.kNumHighLenBits);
+
+			public LenEncoder()
+			{
+				for (UInt32 posState = 0; posState < Base.kNumPosStatesEncodingMax; posState++)
+				{
+					_lowCoder[posState] = new RangeCoder.BitTreeEncoder(Base.kNumLowLenBits);
+					_midCoder[posState] = new RangeCoder.BitTreeEncoder(Base.kNumMidLenBits);
+				}
+			}
+
+			public void Init(UInt32 numPosStates)
+			{
+				_choice.Init();
+				_choice2.Init();
+				for (UInt32 posState = 0; posState < numPosStates; posState++)
+				{
+					_lowCoder[posState].Init();
+					_midCoder[posState].Init();
+				}
+				_highCoder.Init();
+			}
+
+			public void Encode(RangeCoder.Encoder rangeEncoder, UInt32 symbol, UInt32 posState)
+			{
+				if (symbol < Base.kNumLowLenSymbols)
+				{
+					_choice.Encode(rangeEncoder, 0);
+					_lowCoder[posState].Encode(rangeEncoder, symbol);
+				}
+				else
+				{
+					symbol -= Base.kNumLowLenSymbols;
+					_choice.Encode(rangeEncoder, 1);
+					if (symbol < Base.kNumMidLenSymbols)
+					{
+						_choice2.Encode(rangeEncoder, 0);
+						_midCoder[posState].Encode(rangeEncoder, symbol);
+					}
+					else
+					{
+						_choice2.Encode(rangeEncoder, 1);
+						_highCoder.Encode(rangeEncoder, symbol - Base.kNumMidLenSymbols);
+					}
+				}
+			}
+
+			public void SetPrices(UInt32 posState, UInt32 numSymbols, UInt32[] prices, UInt32 st)
+			{
+				UInt32 a0 = _choice.GetPrice0();
+				UInt32 a1 = _choice.GetPrice1();
+				UInt32 b0 = a1 + _choice2.GetPrice0();
+				UInt32 b1 = a1 + _choice2.GetPrice1();
+				UInt32 i = 0;
+				for (i = 0; i < Base.kNumLowLenSymbols; i++)
+				{
+					if (i >= numSymbols)
+						return;
+					prices[st + i] = a0 + _lowCoder[posState].GetPrice(i);
+				}
+				for (; i < Base.kNumLowLenSymbols + Base.kNumMidLenSymbols; i++)
+				{
+					if (i >= numSymbols)
+						return;
+					prices[st + i] = b0 + _midCoder[posState].GetPrice(i - Base.kNumLowLenSymbols);
+				}
+				for (; i < numSymbols; i++)
+					prices[st + i] = b1 + _highCoder.GetPrice(i - Base.kNumLowLenSymbols - Base.kNumMidLenSymbols);
+			}
+		};
+
+		const UInt32 kNumLenSpecSymbols = Base.kNumLowLenSymbols + Base.kNumMidLenSymbols;
+
+		class LenPriceTableEncoder : LenEncoder
+		{
+			UInt32[] _prices = new UInt32[Base.kNumLenSymbols << Base.kNumPosStatesBitsEncodingMax];
+			UInt32 _tableSize;
+			UInt32[] _counters = new UInt32[Base.kNumPosStatesEncodingMax];
+
+			public void SetTableSize(UInt32 tableSize) { _tableSize = tableSize; }
+
+			public UInt32 GetPrice(UInt32 symbol, UInt32 posState)
+			{
+				return _prices[posState * Base.kNumLenSymbols + symbol];
+			}
+
+			void UpdateTable(UInt32 posState)
+			{
+				SetPrices(posState, _tableSize, _prices, posState * Base.kNumLenSymbols);
+				_counters[posState] = _tableSize;
+			}
+
+			public void UpdateTables(UInt32 numPosStates)
+			{
+				for (UInt32 posState = 0; posState < numPosStates; posState++)
+					UpdateTable(posState);
+			}
+
+			public new void Encode(RangeCoder.Encoder rangeEncoder, UInt32 symbol, UInt32 posState)
+			{
+				base.Encode(rangeEncoder, symbol, posState);
+				if (--_counters[posState] == 0)
+					UpdateTable(posState);
+			}
+		}
+
+		const UInt32 kNumOpts = 1 << 12;
+		class Optimal
+		{
+			public Base.State State;
+
+			public bool Prev1IsChar;
+			public bool Prev2;
+
+			public UInt32 PosPrev2;
+			public UInt32 BackPrev2;
+
+			public UInt32 Price;
+			public UInt32 PosPrev;
+			public UInt32 BackPrev;
+
+			public UInt32 Backs0;
+			public UInt32 Backs1;
+			public UInt32 Backs2;
+			public UInt32 Backs3;
+
+			public void MakeAsChar() { BackPrev = 0xFFFFFFFF; Prev1IsChar = false; }
+			public void MakeAsShortRep() { BackPrev = 0; ; Prev1IsChar = false; }
+			public bool IsShortRep() { return (BackPrev == 0); }
+		};
+		Optimal[] _optimum = new Optimal[kNumOpts];
+		LZ.IMatchFinder _matchFinder = null;
+		RangeCoder.Encoder _rangeEncoder = new RangeCoder.Encoder();
+
+		RangeCoder.BitEncoder[] _isMatch = new RangeCoder.BitEncoder[Base.kNumStates << Base.kNumPosStatesBitsMax];
+		RangeCoder.BitEncoder[] _isRep = new RangeCoder.BitEncoder[Base.kNumStates];
+		RangeCoder.BitEncoder[] _isRepG0 = new RangeCoder.BitEncoder[Base.kNumStates];
+		RangeCoder.BitEncoder[] _isRepG1 = new RangeCoder.BitEncoder[Base.kNumStates];
+		RangeCoder.BitEncoder[] _isRepG2 = new RangeCoder.BitEncoder[Base.kNumStates];
+		RangeCoder.BitEncoder[] _isRep0Long = new RangeCoder.BitEncoder[Base.kNumStates << Base.kNumPosStatesBitsMax];
+
+		RangeCoder.BitTreeEncoder[] _posSlotEncoder = new RangeCoder.BitTreeEncoder[Base.kNumLenToPosStates];
+		
+		RangeCoder.BitEncoder[] _posEncoders = new RangeCoder.BitEncoder[Base.kNumFullDistances - Base.kEndPosModelIndex];
+		RangeCoder.BitTreeEncoder _posAlignEncoder = new RangeCoder.BitTreeEncoder(Base.kNumAlignBits);
+
+		LenPriceTableEncoder _lenEncoder = new LenPriceTableEncoder();
+		LenPriceTableEncoder _repMatchLenEncoder = new LenPriceTableEncoder();
+
+		LiteralEncoder _literalEncoder = new LiteralEncoder();
+
+		UInt32[] _matchDistances = new UInt32[Base.kMatchMaxLen * 2 + 2];
+		
+		UInt32 _numFastBytes = kNumFastBytesDefault;
+		UInt32 _longestMatchLength;
+		UInt32 _numDistancePairs;
+
+		UInt32 _additionalOffset;
+
+		UInt32 _optimumEndIndex;
+		UInt32 _optimumCurrentIndex;
+
+		bool _longestMatchWasFound;
+
+		UInt32[] _posSlotPrices = new UInt32[1 << (Base.kNumPosSlotBits + Base.kNumLenToPosStatesBits)];
+		UInt32[] _distancesPrices = new UInt32[Base.kNumFullDistances << Base.kNumLenToPosStatesBits];
+		UInt32[] _alignPrices = new UInt32[Base.kAlignTableSize];
+		UInt32 _alignPriceCount;
+
+		UInt32 _distTableSize = (kDefaultDictionaryLogSize * 2);
+
+		int _posStateBits = 2;
+		UInt32 _posStateMask = (4 - 1);
+		int _numLiteralPosStateBits = 0;
+		int _numLiteralContextBits = 3;
+
+		UInt32 _dictionarySize = (1 << kDefaultDictionaryLogSize);
+		UInt32 _dictionarySizePrev = 0xFFFFFFFF;
+		UInt32 _numFastBytesPrev = 0xFFFFFFFF;
+
+		Int64 nowPos64;
+		bool _finished;
+		System.IO.Stream _inStream;
+
+		EMatchFinderType _matchFinderType = EMatchFinderType.BT4;
+		bool _writeEndMark = false;
+		
+		bool _needReleaseMFStream;
+
+		void Create()
+		{
+			if (_matchFinder == null)
+			{
+				LZ.BinTree bt = new LZ.BinTree();
+				int numHashBytes = 4;
+				if (_matchFinderType == EMatchFinderType.BT2)
+					numHashBytes = 2;
+				bt.SetType(numHashBytes);
+				_matchFinder = bt;
+			}
+			_literalEncoder.Create(_numLiteralPosStateBits, _numLiteralContextBits);
+
+			if (_dictionarySize == _dictionarySizePrev && _numFastBytesPrev == _numFastBytes)
+				return;
+			_matchFinder.Create(_dictionarySize, kNumOpts, _numFastBytes, Base.kMatchMaxLen + 1);
+			_dictionarySizePrev = _dictionarySize;
+			_numFastBytesPrev = _numFastBytes;
+		}
+
+		public Encoder()
+		{
+			for (int i = 0; i < kNumOpts; i++)
+				_optimum[i] = new Optimal();
+			for (int i = 0; i < Base.kNumLenToPosStates; i++)
+				_posSlotEncoder[i] = new RangeCoder.BitTreeEncoder(Base.kNumPosSlotBits);
+		}
+
+		void SetWriteEndMarkerMode(bool writeEndMarker)
+		{
+			_writeEndMark = writeEndMarker;
+		}
+
+		void Init()
+		{
+			BaseInit();
+			_rangeEncoder.Init();
+
+			uint i;
+			for (i = 0; i < Base.kNumStates; i++)
+			{
+				for (uint j = 0; j <= _posStateMask; j++)
+				{
+					uint complexState = (i << Base.kNumPosStatesBitsMax) + j;
+					_isMatch[complexState].Init();
+					_isRep0Long[complexState].Init();
+				}
+				_isRep[i].Init();
+				_isRepG0[i].Init();
+				_isRepG1[i].Init();
+				_isRepG2[i].Init();
+			}
+			_literalEncoder.Init();
+			for (i = 0; i < Base.kNumLenToPosStates; i++)
+				_posSlotEncoder[i].Init();
+			for (i = 0; i < Base.kNumFullDistances - Base.kEndPosModelIndex; i++)
+				_posEncoders[i].Init();
+
+			_lenEncoder.Init((UInt32)1 << _posStateBits);
+			_repMatchLenEncoder.Init((UInt32)1 << _posStateBits);
+
+			_posAlignEncoder.Init();
+
+			_longestMatchWasFound = false;
+			_optimumEndIndex = 0;
+			_optimumCurrentIndex = 0;
+			_additionalOffset = 0;
+		}
+
+		void ReadMatchDistances(out UInt32 lenRes, out UInt32 numDistancePairs)
+		{
+			lenRes = 0;
+			numDistancePairs = _matchFinder.GetMatches(_matchDistances);
+			if (numDistancePairs > 0)
+			{
+				lenRes = _matchDistances[numDistancePairs - 2];
+				if (lenRes == _numFastBytes)
+					lenRes += _matchFinder.GetMatchLen((int)lenRes - 1, _matchDistances[numDistancePairs - 1],
+						Base.kMatchMaxLen - lenRes);
+			}
+			_additionalOffset++;
+		}
+
+
+		void MovePos(UInt32 num)
+		{
+			if (num > 0)
+			{
+				_matchFinder.Skip(num);
+				_additionalOffset += num;
+			}
+		}
+
+		UInt32 GetRepLen1Price(Base.State state, UInt32 posState)
+		{
+			return _isRepG0[state.Index].GetPrice0() +
+					_isRep0Long[(state.Index << Base.kNumPosStatesBitsMax) + posState].GetPrice0();
+		}
+
+		UInt32 GetPureRepPrice(UInt32 repIndex, Base.State state, UInt32 posState)
+		{
+			UInt32 price;
+			if (repIndex == 0)
+			{
+				price = _isRepG0[state.Index].GetPrice0();
+				price += _isRep0Long[(state.Index << Base.kNumPosStatesBitsMax) + posState].GetPrice1();
+			}
+			else
+			{
+				price = _isRepG0[state.Index].GetPrice1();
+				if (repIndex == 1)
+					price += _isRepG1[state.Index].GetPrice0();
+				else
+				{
+					price += _isRepG1[state.Index].GetPrice1();
+					price += _isRepG2[state.Index].GetPrice(repIndex - 2);
+				}
+			}
+			return price;
+		}
+
+		UInt32 GetRepPrice(UInt32 repIndex, UInt32 len, Base.State state, UInt32 posState)
+		{
+			UInt32 price = _repMatchLenEncoder.GetPrice(len - Base.kMatchMinLen, posState);
+			return price + GetPureRepPrice(repIndex, state, posState);
+		}
+	
+		UInt32 GetPosLenPrice(UInt32 pos, UInt32 len, UInt32 posState)
+		{
+			UInt32 price;
+			UInt32 lenToPosState = Base.GetLenToPosState(len);
+			if (pos < Base.kNumFullDistances)
+				price = _distancesPrices[(lenToPosState * Base.kNumFullDistances) + pos];
+			else
+				price = _posSlotPrices[(lenToPosState << Base.kNumPosSlotBits) + GetPosSlot2(pos)] +
+					_alignPrices[pos & Base.kAlignMask];
+			return price + _lenEncoder.GetPrice(len - Base.kMatchMinLen, posState);
+		}
+
+		UInt32 Backward(out UInt32 backRes, UInt32 cur)
+		{
+			_optimumEndIndex = cur;
+			UInt32 posMem = _optimum[cur].PosPrev;
+			UInt32 backMem = _optimum[cur].BackPrev;
+			do
+			{
+				if (_optimum[cur].Prev1IsChar)
+				{
+					_optimum[posMem].MakeAsChar();
+					_optimum[posMem].PosPrev = posMem - 1;
+					if (_optimum[cur].Prev2)
+					{
+						_optimum[posMem - 1].Prev1IsChar = false;
+						_optimum[posMem - 1].PosPrev = _optimum[cur].PosPrev2;
+						_optimum[posMem - 1].BackPrev = _optimum[cur].BackPrev2;
+					}
+				}
+				UInt32 posPrev = posMem;
+				UInt32 backCur = backMem;
+
+				backMem = _optimum[posPrev].BackPrev;
+				posMem = _optimum[posPrev].PosPrev;
+
+				_optimum[posPrev].BackPrev = backCur;
+				_optimum[posPrev].PosPrev = cur;
+				cur = posPrev;
+			}
+			while (cur > 0);
+			backRes = _optimum[0].BackPrev;
+			_optimumCurrentIndex = _optimum[0].PosPrev;
+			return _optimumCurrentIndex;
+		}
+
+		UInt32[] reps = new UInt32[Base.kNumRepDistances];
+		UInt32[] repLens = new UInt32[Base.kNumRepDistances];
+
+
+		UInt32 GetOptimum(UInt32 position, out UInt32 backRes)
+		{
+			if (_optimumEndIndex != _optimumCurrentIndex)
+			{
+				UInt32 lenRes = _optimum[_optimumCurrentIndex].PosPrev - _optimumCurrentIndex;
+				backRes = _optimum[_optimumCurrentIndex].BackPrev;
+				_optimumCurrentIndex = _optimum[_optimumCurrentIndex].PosPrev;
+				return lenRes;
+			}
+			_optimumCurrentIndex = _optimumEndIndex = 0;
+
+			UInt32 lenMain, numDistancePairs;
+			if (!_longestMatchWasFound)
+			{
+				ReadMatchDistances(out lenMain, out numDistancePairs);
+			}
+			else
+			{
+				lenMain = _longestMatchLength;
+				numDistancePairs = _numDistancePairs;
+				_longestMatchWasFound = false;
+			}
+
+			UInt32 numAvailableBytes = _matchFinder.GetNumAvailableBytes() + 1;
+			if (numAvailableBytes < 2)
+			{
+				backRes = 0xFFFFFFFF;
+				return 1;
+			}
+			if (numAvailableBytes > Base.kMatchMaxLen)
+				numAvailableBytes = Base.kMatchMaxLen;
+
+			UInt32 repMaxIndex = 0;
+			UInt32 i;			
+			for (i = 0; i < Base.kNumRepDistances; i++)
+			{
+				reps[i] = _repDistances[i];
+				repLens[i] = _matchFinder.GetMatchLen(0 - 1, reps[i], Base.kMatchMaxLen);
+				if (repLens[i] > repLens[repMaxIndex])
+					repMaxIndex = i;
+			}
+			if (repLens[repMaxIndex] >= _numFastBytes)
+			{
+				backRes = repMaxIndex;
+				UInt32 lenRes = repLens[repMaxIndex];
+				MovePos(lenRes - 1);
+				return lenRes;
+			}
+
+			if (lenMain >= _numFastBytes)
+			{
+				backRes = _matchDistances[numDistancePairs - 1] + Base.kNumRepDistances;
+				MovePos(lenMain - 1);
+				return lenMain;
+			}
+			
+			Byte currentByte = _matchFinder.GetIndexByte(0 - 1);
+			Byte matchByte = _matchFinder.GetIndexByte((Int32)(0 - _repDistances[0] - 1 - 1));
+
+			if (lenMain < 2 && currentByte != matchByte && repLens[repMaxIndex] < 2)
+			{
+				backRes = (UInt32)0xFFFFFFFF;
+				return 1;
+			}
+
+			_optimum[0].State = _state;
+
+			UInt32 posState = (position & _posStateMask);
+
+			_optimum[1].Price = _isMatch[(_state.Index << Base.kNumPosStatesBitsMax) + posState].GetPrice0() +
+					_literalEncoder.GetSubCoder(position, _previousByte).GetPrice(!_state.IsCharState(), matchByte, currentByte);
+			_optimum[1].MakeAsChar();
+
+			UInt32 matchPrice = _isMatch[(_state.Index << Base.kNumPosStatesBitsMax) + posState].GetPrice1();
+			UInt32 repMatchPrice = matchPrice + _isRep[_state.Index].GetPrice1();
+
+			if (matchByte == currentByte)
+			{
+				UInt32 shortRepPrice = repMatchPrice + GetRepLen1Price(_state, posState);
+				if (shortRepPrice < _optimum[1].Price)
+				{
+					_optimum[1].Price = shortRepPrice;
+					_optimum[1].MakeAsShortRep();
+				}
+			}
+
+			UInt32 lenEnd = ((lenMain >= repLens[repMaxIndex]) ? lenMain : repLens[repMaxIndex]);
+
+			if(lenEnd < 2)
+			{
+				backRes = _optimum[1].BackPrev;
+				return 1;
+			}
+			
+			_optimum[1].PosPrev = 0;
+
+			_optimum[0].Backs0 = reps[0];
+			_optimum[0].Backs1 = reps[1];
+			_optimum[0].Backs2 = reps[2];
+			_optimum[0].Backs3 = reps[3];
+
+			UInt32 len = lenEnd;
+			do
+				_optimum[len--].Price = kIfinityPrice;
+			while (len >= 2);
+
+			for (i = 0; i < Base.kNumRepDistances; i++)
+			{
+				UInt32 repLen = repLens[i];
+				if (repLen < 2)
+					continue;
+				UInt32 price = repMatchPrice + GetPureRepPrice(i, _state, posState);
+				do
+				{
+					UInt32 curAndLenPrice = price + _repMatchLenEncoder.GetPrice(repLen - 2, posState);
+					Optimal optimum = _optimum[repLen];
+					if (curAndLenPrice < optimum.Price)
+					{
+						optimum.Price = curAndLenPrice;
+						optimum.PosPrev = 0;
+						optimum.BackPrev = i;
+						optimum.Prev1IsChar = false;
+					}
+				}
+				while (--repLen >= 2);
+			}
+
+			UInt32 normalMatchPrice = matchPrice + _isRep[_state.Index].GetPrice0();
+			
+			len = ((repLens[0] >= 2) ? repLens[0] + 1 : 2);
+			if (len <= lenMain)
+			{
+				UInt32 offs = 0;
+				while (len > _matchDistances[offs])
+					offs += 2;
+				for (; ; len++)
+				{
+					UInt32 distance = _matchDistances[offs + 1];
+					UInt32 curAndLenPrice = normalMatchPrice + GetPosLenPrice(distance, len, posState);
+					Optimal optimum = _optimum[len];
+					if (curAndLenPrice < optimum.Price)
+					{
+						optimum.Price = curAndLenPrice;
+						optimum.PosPrev = 0;
+						optimum.BackPrev = distance + Base.kNumRepDistances;
+						optimum.Prev1IsChar = false;
+					}
+					if (len == _matchDistances[offs])
+					{
+						offs += 2;
+						if (offs == numDistancePairs)
+							break;
+					}
+				}
+			}
+
+			UInt32 cur = 0;
+
+			while (true)
+			{
+				cur++;
+				if (cur == lenEnd)
+					return Backward(out backRes, cur);
+				UInt32 newLen;
+				ReadMatchDistances(out newLen, out numDistancePairs);
+				if (newLen >= _numFastBytes)
+				{
+					_numDistancePairs = numDistancePairs;
+					_longestMatchLength = newLen;
+					_longestMatchWasFound = true;
+					return Backward(out backRes, cur);
+				}
+				position++;
+				UInt32 posPrev = _optimum[cur].PosPrev;
+				Base.State state;
+				if (_optimum[cur].Prev1IsChar)
+				{
+					posPrev--;
+					if (_optimum[cur].Prev2)
+					{
+						state = _optimum[_optimum[cur].PosPrev2].State;
+						if (_optimum[cur].BackPrev2 < Base.kNumRepDistances)
+							state.UpdateRep();
+						else
+							state.UpdateMatch();
+					}
+					else
+						state = _optimum[posPrev].State;
+					state.UpdateChar();
+				}
+				else
+					state = _optimum[posPrev].State;
+				if (posPrev == cur - 1)
+				{
+					if (_optimum[cur].IsShortRep())
+						state.UpdateShortRep();
+					else
+						state.UpdateChar();
+				}
+				else
+				{
+					UInt32 pos;
+					if (_optimum[cur].Prev1IsChar && _optimum[cur].Prev2)
+					{
+						posPrev = _optimum[cur].PosPrev2;
+						pos = _optimum[cur].BackPrev2;
+						state.UpdateRep();
+					}
+					else
+					{
+						pos = _optimum[cur].BackPrev;
+						if (pos < Base.kNumRepDistances)
+							state.UpdateRep();
+						else
+							state.UpdateMatch();
+					}
+					Optimal opt = _optimum[posPrev];
+					if (pos < Base.kNumRepDistances)
+					{
+						if (pos == 0)
+						{
+							reps[0] = opt.Backs0;
+							reps[1] = opt.Backs1;
+							reps[2] = opt.Backs2;
+							reps[3] = opt.Backs3;
+						}
+						else if (pos == 1)
+						{
+							reps[0] = opt.Backs1;
+							reps[1] = opt.Backs0;
+							reps[2] = opt.Backs2;
+							reps[3] = opt.Backs3;
+						}
+						else if (pos == 2)
+						{
+							reps[0] = opt.Backs2;
+							reps[1] = opt.Backs0;
+							reps[2] = opt.Backs1;
+							reps[3] = opt.Backs3;
+						}
+						else
+						{
+							reps[0] = opt.Backs3;
+							reps[1] = opt.Backs0;
+							reps[2] = opt.Backs1;
+							reps[3] = opt.Backs2;
+						}
+					}
+					else
+					{
+						reps[0] = (pos - Base.kNumRepDistances);
+						reps[1] = opt.Backs0;
+						reps[2] = opt.Backs1;
+						reps[3] = opt.Backs2;
+					}
+				}
+				_optimum[cur].State = state;
+				_optimum[cur].Backs0 = reps[0];
+				_optimum[cur].Backs1 = reps[1];
+				_optimum[cur].Backs2 = reps[2];
+				_optimum[cur].Backs3 = reps[3];
+				UInt32 curPrice = _optimum[cur].Price;
+
+				currentByte = _matchFinder.GetIndexByte(0 - 1);
+				matchByte = _matchFinder.GetIndexByte((Int32)(0 - reps[0] - 1 - 1));
+
+				posState = (position & _posStateMask);
+
+				UInt32 curAnd1Price = curPrice +
+					_isMatch[(state.Index << Base.kNumPosStatesBitsMax) + posState].GetPrice0() +
+					_literalEncoder.GetSubCoder(position, _matchFinder.GetIndexByte(0 - 2)).
+					GetPrice(!state.IsCharState(), matchByte, currentByte);
+
+				Optimal nextOptimum = _optimum[cur + 1];
+
+				bool nextIsChar = false;
+				if (curAnd1Price < nextOptimum.Price)
+				{
+					nextOptimum.Price = curAnd1Price;
+					nextOptimum.PosPrev = cur;
+					nextOptimum.MakeAsChar();
+					nextIsChar = true;
+				}
+
+				matchPrice = curPrice + _isMatch[(state.Index << Base.kNumPosStatesBitsMax) + posState].GetPrice1();
+				repMatchPrice = matchPrice + _isRep[state.Index].GetPrice1();
+
+				if (matchByte == currentByte &&
+					!(nextOptimum.PosPrev < cur && nextOptimum.BackPrev == 0))
+				{
+					UInt32 shortRepPrice = repMatchPrice + GetRepLen1Price(state, posState);
+					if (shortRepPrice <= nextOptimum.Price)
+					{
+						nextOptimum.Price = shortRepPrice;
+						nextOptimum.PosPrev = cur;
+						nextOptimum.MakeAsShortRep();
+						nextIsChar = true;
+					}
+				}
+
+				UInt32 numAvailableBytesFull = _matchFinder.GetNumAvailableBytes() + 1;
+				numAvailableBytesFull = Math.Min(kNumOpts - 1 - cur, numAvailableBytesFull);
+				numAvailableBytes = numAvailableBytesFull;
+
+				if (numAvailableBytes < 2)
+					continue;
+				if (numAvailableBytes > _numFastBytes)
+					numAvailableBytes = _numFastBytes;
+				if (!nextIsChar && matchByte != currentByte)
+				{
+					// try Literal + rep0
+					UInt32 t = Math.Min(numAvailableBytesFull - 1, _numFastBytes);
+					UInt32 lenTest2 = _matchFinder.GetMatchLen(0, reps[0], t);
+					if (lenTest2 >= 2)
+					{
+						Base.State state2 = state;
+						state2.UpdateChar();
+						UInt32 posStateNext = (position + 1) & _posStateMask;
+						UInt32 nextRepMatchPrice = curAnd1Price +
+							_isMatch[(state2.Index << Base.kNumPosStatesBitsMax) + posStateNext].GetPrice1() +
+							_isRep[state2.Index].GetPrice1();
+						{
+							UInt32 offset = cur + 1 + lenTest2;
+							while (lenEnd < offset)
+								_optimum[++lenEnd].Price = kIfinityPrice;
+							UInt32 curAndLenPrice = nextRepMatchPrice + GetRepPrice(
+								0, lenTest2, state2, posStateNext);
+							Optimal optimum = _optimum[offset];
+							if (curAndLenPrice < optimum.Price)
+							{
+								optimum.Price = curAndLenPrice;
+								optimum.PosPrev = cur + 1;
+								optimum.BackPrev = 0;
+								optimum.Prev1IsChar = true;
+								optimum.Prev2 = false;
+							}
+						}
+					}
+				}
+
+				UInt32 startLen = 2; // speed optimization 
+
+				for (UInt32 repIndex = 0; repIndex < Base.kNumRepDistances; repIndex++)
+				{
+					UInt32 lenTest = _matchFinder.GetMatchLen(0 - 1, reps[repIndex], numAvailableBytes);
+					if (lenTest < 2)
+						continue;
+					UInt32 lenTestTemp = lenTest;
+					do
+					{
+						while (lenEnd < cur + lenTest)
+							_optimum[++lenEnd].Price = kIfinityPrice;
+						UInt32 curAndLenPrice = repMatchPrice + GetRepPrice(repIndex, lenTest, state, posState);
+						Optimal optimum = _optimum[cur + lenTest];
+						if (curAndLenPrice < optimum.Price)
+						{
+							optimum.Price = curAndLenPrice;
+							optimum.PosPrev = cur;
+							optimum.BackPrev = repIndex;
+							optimum.Prev1IsChar = false;
+						}
+					}
+					while(--lenTest >= 2);
+					lenTest = lenTestTemp;
+
+					if (repIndex == 0)
+						startLen = lenTest + 1;
+
+					// if (_maxMode)
+					if (lenTest < numAvailableBytesFull)
+					{
+						UInt32 t = Math.Min(numAvailableBytesFull - 1 - lenTest, _numFastBytes);
+						UInt32 lenTest2 = _matchFinder.GetMatchLen((Int32)lenTest, reps[repIndex], t);
+						if (lenTest2 >= 2)
+						{
+							Base.State state2 = state;
+							state2.UpdateRep();
+							UInt32 posStateNext = (position + lenTest) & _posStateMask;
+							UInt32 curAndLenCharPrice = 
+									repMatchPrice + GetRepPrice(repIndex, lenTest, state, posState) + 
+									_isMatch[(state2.Index << Base.kNumPosStatesBitsMax) + posStateNext].GetPrice0() +
+									_literalEncoder.GetSubCoder(position + lenTest, 
+									_matchFinder.GetIndexByte((Int32)lenTest - 1 - 1)).GetPrice(true,
+									_matchFinder.GetIndexByte((Int32)((Int32)lenTest - 1 - (Int32)(reps[repIndex] + 1))), 
+									_matchFinder.GetIndexByte((Int32)lenTest - 1));
+							state2.UpdateChar();
+							posStateNext = (position + lenTest + 1) & _posStateMask;
+							UInt32 nextMatchPrice = curAndLenCharPrice + _isMatch[(state2.Index << Base.kNumPosStatesBitsMax) + posStateNext].GetPrice1();
+							UInt32 nextRepMatchPrice = nextMatchPrice + _isRep[state2.Index].GetPrice1();
+							
+							// for(; lenTest2 >= 2; lenTest2--)
+							{
+								UInt32 offset = lenTest + 1 + lenTest2;
+								while(lenEnd < cur + offset)
+									_optimum[++lenEnd].Price = kIfinityPrice;
+								UInt32 curAndLenPrice = nextRepMatchPrice + GetRepPrice(0, lenTest2, state2, posStateNext);
+								Optimal optimum = _optimum[cur + offset];
+								if (curAndLenPrice < optimum.Price) 
+								{
+									optimum.Price = curAndLenPrice;
+									optimum.PosPrev = cur + lenTest + 1;
+									optimum.BackPrev = 0;
+									optimum.Prev1IsChar = true;
+									optimum.Prev2 = true;
+									optimum.PosPrev2 = cur;
+									optimum.BackPrev2 = repIndex;
+								}
+							}
+						}
+					}
+				}
+
+				if (newLen > numAvailableBytes)
+				{
+					newLen = numAvailableBytes;
+					for (numDistancePairs = 0; newLen > _matchDistances[numDistancePairs]; numDistancePairs += 2) ;
+					_matchDistances[numDistancePairs] = newLen;
+					numDistancePairs += 2;
+				}
+				if (newLen >= startLen)
+				{
+					normalMatchPrice = matchPrice + _isRep[state.Index].GetPrice0();
+					while (lenEnd < cur + newLen)
+						_optimum[++lenEnd].Price = kIfinityPrice;
+
+					UInt32 offs = 0;
+					while (startLen > _matchDistances[offs])
+						offs += 2;
+
+					for (UInt32 lenTest = startLen; ; lenTest++)
+					{
+						UInt32 curBack = _matchDistances[offs + 1];
+						UInt32 curAndLenPrice = normalMatchPrice + GetPosLenPrice(curBack, lenTest, posState);
+						Optimal optimum = _optimum[cur + lenTest];
+						if (curAndLenPrice < optimum.Price)
+						{
+							optimum.Price = curAndLenPrice;
+							optimum.PosPrev = cur;
+							optimum.BackPrev = curBack + Base.kNumRepDistances;
+							optimum.Prev1IsChar = false;
+						}
+
+						if (lenTest == _matchDistances[offs])
+						{
+							if (lenTest < numAvailableBytesFull)
+							{
+								UInt32 t = Math.Min(numAvailableBytesFull - 1 - lenTest, _numFastBytes);
+								UInt32 lenTest2 = _matchFinder.GetMatchLen((Int32)lenTest, curBack, t);
+								if (lenTest2 >= 2)
+								{
+									Base.State state2 = state;
+									state2.UpdateMatch();
+									UInt32 posStateNext = (position + lenTest) & _posStateMask;
+									UInt32 curAndLenCharPrice = curAndLenPrice +
+										_isMatch[(state2.Index << Base.kNumPosStatesBitsMax) + posStateNext].GetPrice0() +
+										_literalEncoder.GetSubCoder(position + lenTest,
+										_matchFinder.GetIndexByte((Int32)lenTest - 1 - 1)).
+										GetPrice(true,
+										_matchFinder.GetIndexByte((Int32)lenTest - (Int32)(curBack + 1) - 1),
+										_matchFinder.GetIndexByte((Int32)lenTest - 1));
+									state2.UpdateChar();
+									posStateNext = (position + lenTest + 1) & _posStateMask;
+									UInt32 nextMatchPrice = curAndLenCharPrice + _isMatch[(state2.Index << Base.kNumPosStatesBitsMax) + posStateNext].GetPrice1();
+									UInt32 nextRepMatchPrice = nextMatchPrice + _isRep[state2.Index].GetPrice1();
+
+									UInt32 offset = lenTest + 1 + lenTest2;
+									while (lenEnd < cur + offset)
+										_optimum[++lenEnd].Price = kIfinityPrice;
+									curAndLenPrice = nextRepMatchPrice + GetRepPrice(0, lenTest2, state2, posStateNext);
+									optimum = _optimum[cur + offset];
+									if (curAndLenPrice < optimum.Price)
+									{
+										optimum.Price = curAndLenPrice;
+										optimum.PosPrev = cur + lenTest + 1;
+										optimum.BackPrev = 0;
+										optimum.Prev1IsChar = true;
+										optimum.Prev2 = true;
+										optimum.PosPrev2 = cur;
+										optimum.BackPrev2 = curBack + Base.kNumRepDistances;
+									}
+								}
+							}
+							offs += 2;
+							if (offs == numDistancePairs)
+								break;
+						}
+					}
+				}
+			}
+		}
+
+		bool ChangePair(UInt32 smallDist, UInt32 bigDist)
+		{
+			const int kDif = 7;
+			return (smallDist < ((UInt32)(1) << (32 - kDif)) && bigDist >= (smallDist << kDif));
+		}
+
+		void WriteEndMarker(UInt32 posState)
+		{
+			if (!_writeEndMark)
+				return;
+
+			_isMatch[(_state.Index << Base.kNumPosStatesBitsMax) + posState].Encode(_rangeEncoder, 1);
+			_isRep[_state.Index].Encode(_rangeEncoder, 0);
+			_state.UpdateMatch();
+			UInt32 len = Base.kMatchMinLen;
+			_lenEncoder.Encode(_rangeEncoder, len - Base.kMatchMinLen, posState);
+			UInt32 posSlot = (1 << Base.kNumPosSlotBits) - 1;
+			UInt32 lenToPosState = Base.GetLenToPosState(len);
+			_posSlotEncoder[lenToPosState].Encode(_rangeEncoder, posSlot);
+			int footerBits = 30;
+			UInt32 posReduced = (((UInt32)1) << footerBits) - 1;
+			_rangeEncoder.EncodeDirectBits(posReduced >> Base.kNumAlignBits, footerBits - Base.kNumAlignBits);
+			_posAlignEncoder.ReverseEncode(_rangeEncoder, posReduced & Base.kAlignMask);
+		}
+
+		void Flush(UInt32 nowPos)
+		{
+			ReleaseMFStream();
+			WriteEndMarker(nowPos & _posStateMask);
+			_rangeEncoder.FlushData();
+			_rangeEncoder.FlushStream();
+		}
+
+		public void CodeOneBlock(out Int64 inSize, out Int64 outSize, out bool finished)
+		{
+			inSize = 0;
+			outSize = 0;
+			finished = true;
+
+			if (_inStream != null)
+			{
+				_matchFinder.SetStream(_inStream);
+				_matchFinder.Init();
+				_needReleaseMFStream = true;
+				_inStream = null;
+				if (_trainSize > 0)
+					_matchFinder.Skip(_trainSize);
+			}
+
+			if (_finished)
+				return;
+			_finished = true;
+
+
+			Int64 progressPosValuePrev = nowPos64;
+			if (nowPos64 == 0)
+			{
+				if (_matchFinder.GetNumAvailableBytes() == 0)
+				{
+					Flush((UInt32)nowPos64);
+					return;
+				}
+				UInt32 len, numDistancePairs; // it's not used
+				ReadMatchDistances(out len, out numDistancePairs);
+				UInt32 posState = (UInt32)(nowPos64) & _posStateMask;
+				_isMatch[(_state.Index << Base.kNumPosStatesBitsMax) + posState].Encode(_rangeEncoder, 0);
+				_state.UpdateChar();
+				Byte curByte = _matchFinder.GetIndexByte((Int32)(0 - _additionalOffset));
+				_literalEncoder.GetSubCoder((UInt32)(nowPos64), _previousByte).Encode(_rangeEncoder, curByte);
+				_previousByte = curByte;
+				_additionalOffset--;
+				nowPos64++;
+			}
+			if (_matchFinder.GetNumAvailableBytes() == 0)
+			{
+				Flush((UInt32)nowPos64);
+				return;
+			}
+			while (true)
+			{
+				UInt32 pos;
+				UInt32 len = GetOptimum((UInt32)nowPos64, out pos);
+				
+				UInt32 posState = ((UInt32)nowPos64) & _posStateMask;
+				UInt32 complexState = (_state.Index << Base.kNumPosStatesBitsMax) + posState;
+				if (len == 1 && pos == 0xFFFFFFFF)
+				{
+					_isMatch[complexState].Encode(_rangeEncoder, 0);
+					Byte curByte = _matchFinder.GetIndexByte((Int32)(0 - _additionalOffset));
+					LiteralEncoder.Encoder2 subCoder = _literalEncoder.GetSubCoder((UInt32)nowPos64, _previousByte);
+					if (!_state.IsCharState())
+					{
+						Byte matchByte = _matchFinder.GetIndexByte((Int32)(0 - _repDistances[0] - 1 - _additionalOffset));
+						subCoder.EncodeMatched(_rangeEncoder, matchByte, curByte);
+					}
+					else
+						subCoder.Encode(_rangeEncoder, curByte);
+					_previousByte = curByte;
+					_state.UpdateChar();
+				}
+				else
+				{
+					_isMatch[complexState].Encode(_rangeEncoder, 1);
+					if (pos < Base.kNumRepDistances)
+					{
+						_isRep[_state.Index].Encode(_rangeEncoder, 1);
+						if (pos == 0)
+						{
+							_isRepG0[_state.Index].Encode(_rangeEncoder, 0);
+							if (len == 1)
+								_isRep0Long[complexState].Encode(_rangeEncoder, 0);
+							else
+								_isRep0Long[complexState].Encode(_rangeEncoder, 1);
+						}
+						else
+						{
+							_isRepG0[_state.Index].Encode(_rangeEncoder, 1);
+							if (pos == 1)
+								_isRepG1[_state.Index].Encode(_rangeEncoder, 0);
+							else
+							{
+								_isRepG1[_state.Index].Encode(_rangeEncoder, 1);
+								_isRepG2[_state.Index].Encode(_rangeEncoder, pos - 2);
+							}
+						}
+						if (len == 1)
+							_state.UpdateShortRep();
+						else
+						{
+							_repMatchLenEncoder.Encode(_rangeEncoder, len - Base.kMatchMinLen, posState);
+							_state.UpdateRep();
+						}
+						UInt32 distance = _repDistances[pos];
+						if (pos != 0)
+						{
+							for (UInt32 i = pos; i >= 1; i--)
+								_repDistances[i] = _repDistances[i - 1];
+							_repDistances[0] = distance;
+						}
+					}
+					else
+					{
+						_isRep[_state.Index].Encode(_rangeEncoder, 0);
+						_state.UpdateMatch();
+						_lenEncoder.Encode(_rangeEncoder, len - Base.kMatchMinLen, posState);
+						pos -= Base.kNumRepDistances;
+						UInt32 posSlot = GetPosSlot(pos);
+						UInt32 lenToPosState = Base.GetLenToPosState(len);
+						_posSlotEncoder[lenToPosState].Encode(_rangeEncoder, posSlot);
+
+						if (posSlot >= Base.kStartPosModelIndex)
+						{
+							int footerBits = (int)((posSlot >> 1) - 1);
+							UInt32 baseVal = ((2 | (posSlot & 1)) << footerBits);
+							UInt32 posReduced = pos - baseVal;
+
+							if (posSlot < Base.kEndPosModelIndex)
+								RangeCoder.BitTreeEncoder.ReverseEncode(_posEncoders,
+										baseVal - posSlot - 1, _rangeEncoder, footerBits, posReduced);
+							else
+							{
+								_rangeEncoder.EncodeDirectBits(posReduced >> Base.kNumAlignBits, footerBits - Base.kNumAlignBits);
+								_posAlignEncoder.ReverseEncode(_rangeEncoder, posReduced & Base.kAlignMask);
+								_alignPriceCount++;
+							}
+						}
+						UInt32 distance = pos;
+						for (UInt32 i = Base.kNumRepDistances - 1; i >= 1; i--)
+							_repDistances[i] = _repDistances[i - 1];
+						_repDistances[0] = distance;
+						_matchPriceCount++;
+					}
+					_previousByte = _matchFinder.GetIndexByte((Int32)(len - 1 - _additionalOffset));
+				}
+				_additionalOffset -= len;
+				nowPos64 += len;
+				if (_additionalOffset == 0)
+				{
+					// if (!_fastMode)
+					if (_matchPriceCount >= (1 << 7))
+						FillDistancesPrices();
+					if (_alignPriceCount >= Base.kAlignTableSize)
+						FillAlignPrices();
+					inSize = nowPos64;
+					outSize = _rangeEncoder.GetProcessedSizeAdd();
+					if (_matchFinder.GetNumAvailableBytes() == 0)
+					{
+						Flush((UInt32)nowPos64);
+						return;
+					}
+
+					if (nowPos64 - progressPosValuePrev >= (1 << 12))
+					{
+						_finished = false;
+						finished = false;
+						return;
+					}
+				}
+			}
+		}
+
+		void ReleaseMFStream()
+		{
+			if (_matchFinder != null && _needReleaseMFStream)
+			{
+				_matchFinder.ReleaseStream();
+				_needReleaseMFStream = false;
+			}
+		}
+
+		void SetOutStream(System.IO.Stream outStream) { _rangeEncoder.SetStream(outStream); }
+		void ReleaseOutStream() { _rangeEncoder.ReleaseStream(); }
+
+		void ReleaseStreams()
+		{
+			ReleaseMFStream();
+			ReleaseOutStream();
+		}
+
+		void SetStreams(System.IO.Stream inStream, System.IO.Stream outStream,
+				Int64 inSize, Int64 outSize)
+		{
+			_inStream = inStream;
+			_finished = false;
+			Create();
+			SetOutStream(outStream);
+			Init();
+
+			// if (!_fastMode)
+			{
+				FillDistancesPrices();
+				FillAlignPrices();
+			}
+
+			_lenEncoder.SetTableSize(_numFastBytes + 1 - Base.kMatchMinLen);
+			_lenEncoder.UpdateTables((UInt32)1 << _posStateBits);
+			_repMatchLenEncoder.SetTableSize(_numFastBytes + 1 - Base.kMatchMinLen);
+			_repMatchLenEncoder.UpdateTables((UInt32)1 << _posStateBits);
+
+			nowPos64 = 0;
+		}
+
+
+		public void Code(System.IO.Stream inStream, System.IO.Stream outStream,
+			Int64 inSize, Int64 outSize, ICodeProgress progress)
+		{
+			_needReleaseMFStream = false;
+			try
+			{
+				SetStreams(inStream, outStream, inSize, outSize);
+				while (true)
+				{
+					Int64 processedInSize;
+					Int64 processedOutSize;
+					bool finished;
+					CodeOneBlock(out processedInSize, out processedOutSize, out finished);
+					if (finished)
+						return;
+					if (progress != null)
+					{
+						progress.SetProgress(processedInSize, processedOutSize);
+					}
+				}
+			}
+			finally
+			{
+				ReleaseStreams();
+			}
+		}
+
+		const int kPropSize = 5;
+		Byte[] properties = new Byte[kPropSize];
+
+		public void WriteCoderProperties(System.IO.Stream outStream)
+		{
+			properties[0] = (Byte)((_posStateBits * 5 + _numLiteralPosStateBits) * 9 + _numLiteralContextBits);
+			for (int i = 0; i < 4; i++)
+				properties[1 + i] = (Byte)(_dictionarySize >> (8 * i));
+			outStream.Write(properties, 0, kPropSize);
+		}
+		
+		UInt32[] tempPrices = new UInt32[Base.kNumFullDistances];
+		UInt32 _matchPriceCount;
+
+		void FillDistancesPrices()
+		{
+			for (UInt32 i = Base.kStartPosModelIndex; i < Base.kNumFullDistances; i++)
+			{ 
+				UInt32 posSlot = GetPosSlot(i);
+				int footerBits = (int)((posSlot >> 1) - 1);
+				UInt32 baseVal = ((2 | (posSlot & 1)) << footerBits);
+				tempPrices[i] = BitTreeEncoder.ReverseGetPrice(_posEncoders, 
+					baseVal - posSlot - 1, footerBits, i - baseVal);
+			}
+
+			for (UInt32 lenToPosState = 0; lenToPosState < Base.kNumLenToPosStates; lenToPosState++)
+			{
+				UInt32 posSlot;
+				RangeCoder.BitTreeEncoder encoder = _posSlotEncoder[lenToPosState];
+			
+				UInt32 st = (lenToPosState << Base.kNumPosSlotBits);
+				for (posSlot = 0; posSlot < _distTableSize; posSlot++)
+					_posSlotPrices[st + posSlot] = encoder.GetPrice(posSlot);
+				for (posSlot = Base.kEndPosModelIndex; posSlot < _distTableSize; posSlot++)
+					_posSlotPrices[st + posSlot] += ((((posSlot >> 1) - 1) - Base.kNumAlignBits) << RangeCoder.BitEncoder.kNumBitPriceShiftBits);
+
+				UInt32 st2 = lenToPosState * Base.kNumFullDistances;
+				UInt32 i;
+				for (i = 0; i < Base.kStartPosModelIndex; i++)
+					_distancesPrices[st2 + i] = _posSlotPrices[st + i];
+				for (; i < Base.kNumFullDistances; i++)
+					_distancesPrices[st2 + i] = _posSlotPrices[st + GetPosSlot(i)] + tempPrices[i];
+			}
+			_matchPriceCount = 0;
+		}
+
+		void FillAlignPrices()
+		{
+			for (UInt32 i = 0; i < Base.kAlignTableSize; i++)
+				_alignPrices[i] = _posAlignEncoder.ReverseGetPrice(i);
+			_alignPriceCount = 0;
+		}
+
+
+		static string[] kMatchFinderIDs = 
+		{
+			"BT2",
+			"BT4",
+		};
+
+		static int FindMatchFinder(string s)
+		{
+			for (int m = 0; m < kMatchFinderIDs.Length; m++)
+				if (s == kMatchFinderIDs[m])
+					return m;
+			return -1;
+		}
+	
+		public void SetCoderProperties(CoderPropID[] propIDs, object[] properties)
+		{
+			for (UInt32 i = 0; i < properties.Length; i++)
+			{
+				object prop = properties[i];
+				switch (propIDs[i])
+				{
+					case CoderPropID.NumFastBytes:
+					{
+						if (!(prop is Int32))
+							throw new InvalidParamException();
+						Int32 numFastBytes = (Int32)prop;
+						if (numFastBytes < 5 || numFastBytes > Base.kMatchMaxLen)
+							throw new InvalidParamException();
+						_numFastBytes = (UInt32)numFastBytes;
+						break;
+					}
+					case CoderPropID.Algorithm:
+					{
+						/*
+						if (!(prop is Int32))
+							throw new InvalidParamException();
+						Int32 maximize = (Int32)prop;
+						_fastMode = (maximize == 0);
+						_maxMode = (maximize >= 2);
+						*/
+						break;
+					}
+					case CoderPropID.MatchFinder:
+					{
+						if (!(prop is String))
+							throw new InvalidParamException();
+						EMatchFinderType matchFinderIndexPrev = _matchFinderType;
+						int m = FindMatchFinder(((string)prop).ToUpper());
+						if (m < 0)
+							throw new InvalidParamException();
+						_matchFinderType = (EMatchFinderType)m;
+						if (_matchFinder != null && matchFinderIndexPrev != _matchFinderType)
+							{
+							_dictionarySizePrev = 0xFFFFFFFF;
+							_matchFinder = null;
+							}
+						break;
+					}
+					case CoderPropID.DictionarySize:
+					{
+						const int kDicLogSizeMaxCompress = 30;
+						if (!(prop is Int32))
+							throw new InvalidParamException(); ;
+						Int32 dictionarySize = (Int32)prop;
+						if (dictionarySize < (UInt32)(1 << Base.kDicLogSizeMin) ||
+							dictionarySize > (UInt32)(1 << kDicLogSizeMaxCompress))
+							throw new InvalidParamException();
+						_dictionarySize = (UInt32)dictionarySize;
+						int dicLogSize;
+						for (dicLogSize = 0; dicLogSize < (UInt32)kDicLogSizeMaxCompress; dicLogSize++)
+							if (dictionarySize <= ((UInt32)(1) << dicLogSize))
+								break;
+						_distTableSize = (UInt32)dicLogSize * 2;
+						break;
+					}
+					case CoderPropID.PosStateBits:
+					{
+						if (!(prop is Int32))
+							throw new InvalidParamException();
+						Int32 v = (Int32)prop;
+						if (v < 0 || v > (UInt32)Base.kNumPosStatesBitsEncodingMax)
+							throw new InvalidParamException();
+						_posStateBits = (int)v;
+						_posStateMask = (((UInt32)1) << (int)_posStateBits) - 1;
+						break;
+					}
+					case CoderPropID.LitPosBits:
+					{
+						if (!(prop is Int32))
+							throw new InvalidParamException();
+						Int32 v = (Int32)prop;
+						if (v < 0 || v > (UInt32)Base.kNumLitPosStatesBitsEncodingMax)
+							throw new InvalidParamException();
+						_numLiteralPosStateBits = (int)v;
+						break;
+					}
+					case CoderPropID.LitContextBits:
+					{
+						if (!(prop is Int32))
+							throw new InvalidParamException();
+						Int32 v = (Int32)prop;
+						if (v < 0 || v > (UInt32)Base.kNumLitContextBitsMax)
+							throw new InvalidParamException(); ;
+						_numLiteralContextBits = (int)v;
+						break;
+					}
+					case CoderPropID.EndMarker:
+					{
+						if (!(prop is Boolean))
+							throw new InvalidParamException();
+						SetWriteEndMarkerMode((Boolean)prop);
+						break;
+					}
+					default:
+						throw new InvalidParamException();
+				}
+			}
+		}
+
+		uint _trainSize = 0;
+		public void SetTrainSize(uint trainSize)
+		{
+			_trainSize = trainSize;
+		}
+		
+	}
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/misc/libphysfs/lzma/CS/7zip/Compress/LzmaAlone/LzmaAlone.cs	Mon Apr 10 12:06:43 2017 -0400
@@ -0,0 +1,364 @@
+using System;
+using System.IO;
+namespace SevenZip
+{
+	using CommandLineParser;
+	
+	public class CDoubleStream: Stream
+	{
+		public System.IO.Stream s1;
+		public System.IO.Stream s2;
+		public int fileIndex;
+		public long skipSize;
+		
+		public override bool CanRead { get { return true; }}
+		public override bool CanWrite { get { return false; }}
+		public override bool CanSeek { get { return false; }}
+		public override long Length { get { return s1.Length + s2.Length - skipSize; } }
+		public override long Position
+		{
+			get { return 0;	}
+			set { }
+		}
+		public override void Flush() { }
+		public override int Read(byte[] buffer, int offset, int count) 
+		{
+			int numTotal = 0;
+			while (count > 0)
+			{
+				if (fileIndex == 0)
+				{
+					int num = s1.Read(buffer, offset, count);
+					offset += num;
+					count -= num;
+					numTotal += num;
+					if (num == 0)
+						fileIndex++;
+				}
+				if (fileIndex == 1)
+				{
+					numTotal += s2.Read(buffer, offset, count);
+					return numTotal;
+				}
+			}
+			return numTotal;
+		}
+		public override void Write(byte[] buffer, int offset, int count)
+		{
+			throw (new Exception("can't Write"));
+		}
+		public override long Seek(long offset, System.IO.SeekOrigin origin)
+		{
+			throw (new Exception("can't Seek"));
+		}
+		public override void SetLength(long value)
+		{
+			throw (new Exception("can't SetLength"));
+		}
+	}
+	
+	class LzmaAlone
+	{
+		enum Key
+		{
+			Help1 = 0,
+			Help2,
+			Mode,
+			Dictionary,
+			FastBytes,
+			LitContext,
+			LitPos,
+			PosBits,
+			MatchFinder,
+			EOS,
+			StdIn,
+			StdOut,
+			Train
+		};
+
+		static void PrintHelp()
+		{
+			System.Console.WriteLine("\nUsage:  LZMA <e|d> [<switches>...] inputFile outputFile\n" +
+				"  e: encode file\n" +
+				"  d: decode file\n" +
+				"  b: Benchmark\n" +
+				"<Switches>\n" +
+				// "  -a{N}:  set compression mode - [0, 1], default: 1 (max)\n" +
+				"  -d{N}:  set dictionary - [0, 29], default: 23 (8MB)\n" +
+				"  -fb{N}: set number of fast bytes - [5, 273], default: 128\n" +
+				"  -lc{N}: set number of literal context bits - [0, 8], default: 3\n" +
+				"  -lp{N}: set number of literal pos bits - [0, 4], default: 0\n" +
+				"  -pb{N}: set number of pos bits - [0, 4], default: 2\n" +
+				"  -mf{MF_ID}: set Match Finder: [bt2, bt4], default: bt4\n" +
+				"  -eos:   write End Of Stream marker\n"
+				// + "  -si:    read data from stdin\n"
+				// + "  -so:    write data to stdout\n"
+				);
+		}
+
+		static bool GetNumber(string s, out Int32 v)
+		{
+			v = 0;
+			for (int i = 0; i < s.Length; i++)
+			{
+				char c = s[i];
+				if (c < '0' || c > '9')
+					return false;
+				v *= 10;
+				v += (Int32)(c - '0');
+			}
+			return true;
+		}
+
+		static int IncorrectCommand()
+		{
+			throw (new Exception("Command line error"));
+			// System.Console.WriteLine("\nCommand line error\n");
+			// return 1;
+		}
+		static int Main2(string[] args)
+		{
+			System.Console.WriteLine("\nLZMA# 4.49 Copyright (c) 1999-2007 Igor Pavlov  2006-07-05\n");
+
+			if (args.Length == 0)
+			{
+				PrintHelp();
+				return 0;
+			}
+
+			SwitchForm[] kSwitchForms = new SwitchForm[13];
+			int sw = 0;
+			kSwitchForms[sw++] = new SwitchForm("?", SwitchType.Simple, false);
+			kSwitchForms[sw++] = new SwitchForm("H", SwitchType.Simple, false);
+			kSwitchForms[sw++] = new SwitchForm("A", SwitchType.UnLimitedPostString, false, 1);
+			kSwitchForms[sw++] = new SwitchForm("D", SwitchType.UnLimitedPostString, false, 1);
+			kSwitchForms[sw++] = new SwitchForm("FB", SwitchType.UnLimitedPostString, false, 1);
+			kSwitchForms[sw++] = new SwitchForm("LC", SwitchType.UnLimitedPostString, false, 1);
+			kSwitchForms[sw++] = new SwitchForm("LP", SwitchType.UnLimitedPostString, false, 1);
+			kSwitchForms[sw++] = new SwitchForm("PB", SwitchType.UnLimitedPostString, false, 1);
+			kSwitchForms[sw++] = new SwitchForm("MF", SwitchType.UnLimitedPostString, false, 1);
+			kSwitchForms[sw++] = new SwitchForm("EOS", SwitchType.Simple, false);
+			kSwitchForms[sw++] = new SwitchForm("SI", SwitchType.Simple, false);
+			kSwitchForms[sw++] = new SwitchForm("SO", SwitchType.Simple, false);
+			kSwitchForms[sw++] = new SwitchForm("T", SwitchType.UnLimitedPostString, false, 1);
+
+
+			Parser parser = new Parser(sw);
+			try
+			{
+				parser.ParseStrings(kSwitchForms, args);
+			}
+			catch
+			{
+				return IncorrectCommand();
+			}
+
+			if (parser[(int)Key.Help1].ThereIs || parser[(int)Key.Help2].ThereIs)
+			{
+				PrintHelp();
+				return 0;
+			}
+
+			System.Collections.ArrayList nonSwitchStrings = parser.NonSwitchStrings;
+
+			int paramIndex = 0;
+			if (paramIndex >= nonSwitchStrings.Count)
+				return IncorrectCommand();
+			string command = (string)nonSwitchStrings[paramIndex++];
+			command = command.ToLower();
+
+			bool dictionaryIsDefined = false;
+			Int32 dictionary = 1 << 21;
+			if (parser[(int)Key.Dictionary].ThereIs)
+			{
+				Int32 dicLog;
+				if (!GetNumber((string)parser[(int)Key.Dictionary].PostStrings[0], out dicLog))
+					IncorrectCommand();
+				dictionary = (Int32)1 << dicLog;
+				dictionaryIsDefined = true;
+			}
+			string mf = "bt4";
+			if (parser[(int)Key.MatchFinder].ThereIs)
+				mf = (string)parser[(int)Key.MatchFinder].PostStrings[0];
+			mf = mf.ToLower();
+
+			if (command == "b")
+			{
+				const Int32 kNumDefaultItereations = 10;
+				Int32 numIterations = kNumDefaultItereations;
+				if (paramIndex < nonSwitchStrings.Count)
+					if (!GetNumber((string)nonSwitchStrings[paramIndex++], out numIterations))
+						numIterations = kNumDefaultItereations;
+				return LzmaBench.LzmaBenchmark(numIterations, (UInt32)dictionary);
+			}
+
+			string train = "";
+			if (parser[(int)Key.Train].ThereIs)
+				train = (string)parser[(int)Key.Train].PostStrings[0];
+
+			bool encodeMode = false;
+			if (command == "e")
+				encodeMode = true;
+			else if (command == "d")
+				encodeMode = false;
+			else
+				IncorrectCommand();
+
+			bool stdInMode = parser[(int)Key.StdIn].ThereIs;
+			bool stdOutMode = parser[(int)Key.StdOut].ThereIs;
+
+			Stream inStream = null;
+			if (stdInMode)
+			{
+				throw (new Exception("Not implemeted"));
+			}
+			else
+			{
+				if (paramIndex >= nonSwitchStrings.Count)
+					IncorrectCommand();
+				string inputName = (string)nonSwitchStrings[paramIndex++];
+				inStream = new FileStream(inputName, FileMode.Open, FileAccess.Read);
+			}
+
+			FileStream outStream = null;
+			if (stdOutMode)
+			{
+				throw (new Exception("Not implemeted"));
+			}
+			else
+			{
+				if (paramIndex >= nonSwitchStrings.Count)
+					IncorrectCommand();
+				string outputName = (string)nonSwitchStrings[paramIndex++];
+				outStream = new FileStream(outputName, FileMode.Create, FileAccess.Write);
+			}
+
+			FileStream trainStream = null;
+			if (train.Length != 0)
+				trainStream = new FileStream(train, FileMode.Open, FileAccess.Read);
+
+			if (encodeMode)
+			{
+				if (!dictionaryIsDefined)
+					dictionary = 1 << 23;
+
+				Int32 posStateBits = 2;
+				Int32 litContextBits = 3; // for normal files
+				// UInt32 litContextBits = 0; // for 32-bit data
+				Int32 litPosBits = 0;
+				// UInt32 litPosBits = 2; // for 32-bit data
+				Int32 algorithm = 2;
+				Int32 numFastBytes = 128;
+
+				bool eos = parser[(int)Key.EOS].ThereIs || stdInMode;
+
+				if (parser[(int)Key.Mode].ThereIs)
+					if (!GetNumber((string)parser[(int)Key.Mode].PostStrings[0], out algorithm))
+						IncorrectCommand();
+
+				if (parser[(int)Key.FastBytes].ThereIs)
+					if (!GetNumber((string)parser[(int)Key.FastBytes].PostStrings[0], out numFastBytes))
+						IncorrectCommand();
+				if (parser[(int)Key.LitContext].ThereIs)
+					if (!GetNumber((string)parser[(int)Key.LitContext].PostStrings[0], out litContextBits))
+						IncorrectCommand();
+				if (parser[(int)Key.LitPos].ThereIs)
+					if (!GetNumber((string)parser[(int)Key.LitPos].PostStrings[0], out litPosBits))
+						IncorrectCommand();
+				if (parser[(int)Key.PosBits].ThereIs)
+					if (!GetNumber((string)parser[(int)Key.PosBits].PostStrings[0], out posStateBits))
+						IncorrectCommand();
+
+				CoderPropID[] propIDs = 
+				{
+					CoderPropID.DictionarySize,
+					CoderPropID.PosStateBits,
+					CoderPropID.LitContextBits,
+					CoderPropID.LitPosBits,
+					CoderPropID.Algorithm,
+					CoderPropID.NumFastBytes,
+					CoderPropID.MatchFinder,
+					CoderPropID.EndMarker
+				};
+				object[] properties = 
+				{
+					(Int32)(dictionary),
+					(Int32)(posStateBits),
+					(Int32)(litContextBits),
+					(Int32)(litPosBits),
+					(Int32)(algorithm),
+					(Int32)(numFastBytes),
+					mf,
+					eos
+				};
+
+				Compression.LZMA.Encoder encoder = new Compression.LZMA.Encoder();
+				encoder.SetCoderProperties(propIDs, properties);
+				encoder.WriteCoderProperties(outStream);
+				Int64 fileSize;
+				if (eos || stdInMode)
+					fileSize = -1;
+				else
+					fileSize = inStream.Length;
+				for (int i = 0; i < 8; i++)
+					outStream.WriteByte((Byte)(fileSize >> (8 * i)));
+				if (trainStream != null)
+				{
+					CDoubleStream doubleStream = new CDoubleStream();
+					doubleStream.s1 = trainStream;
+					doubleStream.s2 = inStream;
+					doubleStream.fileIndex = 0;
+					inStream = doubleStream;
+					long trainFileSize = trainStream.Length;
+					doubleStream.skipSize = 0;
+					if (trainFileSize > dictionary)
+						doubleStream.skipSize = trainFileSize - dictionary;
+					trainStream.Seek(doubleStream.skipSize, SeekOrigin.Begin);
+					encoder.SetTrainSize((uint)(trainFileSize - doubleStream.skipSize));
+				}
+				encoder.Code(inStream, outStream, -1, -1, null);
+			}
+			else if (command == "d")
+			{
+				byte[] properties = new byte[5];
+				if (inStream.Read(properties, 0, 5) != 5)
+					throw (new Exception("input .lzma is too short"));
+				Compression.LZMA.Decoder decoder = new Compression.LZMA.Decoder();
+				decoder.SetDecoderProperties(properties);
+				if (trainStream != null)
+				{
+					if (!decoder.Train(trainStream))
+						throw (new Exception("can't train"));
+				}
+				long outSize = 0;
+				for (int i = 0; i < 8; i++)
+				{
+					int v = inStream.ReadByte();
+					if (v < 0)
+						throw (new Exception("Can't Read 1"));
+					outSize |= ((long)(byte)v) << (8 * i);
+				}
+				long compressedSize = inStream.Length - inStream.Position;
+				decoder.Code(inStream, outStream, compressedSize, outSize, null);
+			}
+			else
+				throw (new Exception("Command Error"));
+			return 0;
+		}
+
+		[STAThread]
+		static int Main(string[] args)
+		{
+			try
+			{
+				return Main2(args);
+			}
+			catch (Exception e)
+			{
+				Console.WriteLine("{0} Caught exception #1.", e);
+				// throw e;
+				return 1;
+			}
+		}
+	}
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/misc/libphysfs/lzma/CS/7zip/Compress/LzmaAlone/LzmaAlone.csproj	Mon Apr 10 12:06:43 2017 -0400
@@ -0,0 +1,90 @@
+<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+  <PropertyGroup>
+    <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
+    <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
+    <ProductVersion>8.0.50727</ProductVersion>
+    <SchemaVersion>2.0</SchemaVersion>
+    <ProjectGuid>{CE33DF18-F9C8-4D6F-9057-DBB4DB96E973}</ProjectGuid>
+    <OutputType>Exe</OutputType>
+    <RootNamespace>LzmaAlone</RootNamespace>
+    <AssemblyName>Lzma#</AssemblyName>
+    <WarningLevel>4</WarningLevel>
+  </PropertyGroup>
+  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
+    <DebugSymbols>true</DebugSymbols>
+    <DebugType>full</DebugType>
+    <Optimize>false</Optimize>
+    <OutputPath>.\bin\Debug\</OutputPath>
+    <DefineConstants>DEBUG;TRACE</DefineConstants>
+  </PropertyGroup>
+  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
+    <DebugSymbols>false</DebugSymbols>
+    <Optimize>true</Optimize>
+    <OutputPath>.\bin\Release\</OutputPath>
+    <DefineConstants>TRACE</DefineConstants>
+    <PlatformTarget>AnyCPU</PlatformTarget>
+  </PropertyGroup>
+  <ItemGroup>
+    <Reference Include="System" />
+    <Reference Include="System.Data" />
+    <Reference Include="System.Xml" />
+  </ItemGroup>
+  <ItemGroup>
+    <Compile Include="..\..\Common\CommandLineParser.cs">
+      <Link>Common\CommandLineParser.cs</Link>
+    </Compile>
+    <Compile Include="..\..\Common\CRC.cs">
+      <Link>Common\CRC.cs</Link>
+    </Compile>
+    <Compile Include="..\..\ICoder.cs">
+      <Link>ICoder.cs</Link>
+    </Compile>
+    <Compile Include="..\LZ\IMatchFinder.cs">
+      <Link>LZ\IMatchFinder.cs</Link>
+    </Compile>
+    <Compile Include="..\LZ\LzBinTree.cs">
+      <Link>LZ\LzBinTree.cs</Link>
+    </Compile>
+    <Compile Include="..\LZ\LzInWindow.cs">
+      <Link>LZ\LzInWindow.cs</Link>
+    </Compile>
+    <Compile Include="..\LZ\LzOutWindow.cs">
+      <Link>LZ\LzOutWindow.cs</Link>
+    </Compile>
+    <Compile Include="..\LZMA\LzmaBase.cs">
+      <Link>LZMA\LzmaBase.cs</Link>
+    </Compile>
+    <Compile Include="..\LZMA\LzmaDecoder.cs">
+      <Link>LZMA\LzmaDecoder.cs</Link>
+    </Compile>
+    <Compile Include="..\LZMA\LzmaEncoder.cs">
+      <Link>LZMA\LzmaEncoder.cs</Link>
+    </Compile>
+    <Compile Include="..\RangeCoder\RangeCoder.cs">
+      <Link>RangeCoder\RangeCoder.cs</Link>
+    </Compile>
+    <Compile Include="..\RangeCoder\RangeCoderBit.cs">
+      <Link>RangeCoder\RangeCoderBit.cs</Link>
+    </Compile>
+    <Compile Include="..\RangeCoder\RangeCoderBitTree.cs">
+      <Link>RangeCoder\RangeCoderBitTree.cs</Link>
+    </Compile>
+    <Compile Include="LzmaAlone.cs">
+      <SubType>Code</SubType>
+    </Compile>
+    <Compile Include="LzmaBench.cs">
+      <SubType>Code</SubType>
+    </Compile>
+    <Compile Include="Properties\AssemblyInfo.cs" />
+    <Compile Include="Properties\Settings.cs">
+      <AutoGen>True</AutoGen>
+      <DependentUpon>Settings.settings</DependentUpon>
+    </Compile>
+    <None Include="Properties\Settings.settings">
+      <Generator>SettingsSingleFileGenerator</Generator>
+      <LastGenOutput>Settings.cs</LastGenOutput>
+    </None>
+    <AppDesigner Include="Properties\" />
+  </ItemGroup>
+  <Import Project="$(MSBuildBinPath)\Microsoft.CSHARP.Targets" />
+</Project>
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/misc/libphysfs/lzma/CS/7zip/Compress/LzmaAlone/LzmaAlone.sln	Mon Apr 10 12:06:43 2017 -0400
@@ -0,0 +1,20 @@
+
+Microsoft Visual Studio Solution File, Format Version 9.00
+# Visual C# Express 2005
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "LzmaAlone", "LzmaAlone.csproj", "{CE33DF18-F9C8-4D6F-9057-DBB4DB96E973}"
+EndProject
+Global
+	GlobalSection(SolutionConfigurationPlatforms) = preSolution
+		Debug|Any CPU = Debug|Any CPU
+		Release|Any CPU = Release|Any CPU
+	EndGlobalSection
+	GlobalSection(ProjectConfigurationPlatforms) = postSolution
+		{CE33DF18-F9C8-4D6F-9057-DBB4DB96E973}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+		{CE33DF18-F9C8-4D6F-9057-DBB4DB96E973}.Debug|Any CPU.Build.0 = Debug|Any CPU
+		{CE33DF18-F9C8-4D6F-9057-DBB4DB96E973}.Release|Any CPU.ActiveCfg = Release|Any CPU
+		{CE33DF18-F9C8-4D6F-9057-DBB4DB96E973}.Release|Any CPU.Build.0 = Release|Any CPU
+	EndGlobalSection
+	GlobalSection(SolutionProperties) = preSolution
+		HideSolutionNode = FALSE
+	EndGlobalSection
+EndGlobal
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/misc/libphysfs/lzma/CS/7zip/Compress/LzmaAlone/LzmaBench.cs	Mon Apr 10 12:06:43 2017 -0400
@@ -0,0 +1,340 @@
+// LzmaBench.cs
+
+using System;
+using System.IO;
+
+namespace SevenZip
+{
+	/// <summary>
+	/// LZMA Benchmark
+	/// </summary>
+	internal abstract class LzmaBench
+	{
+		const UInt32 kAdditionalSize = (6 << 20);
+		const UInt32 kCompressedAdditionalSize = (1 << 10);
+		const UInt32 kMaxLzmaPropSize = 10;
+
+		class CRandomGenerator
+		{
+			UInt32 A1;
+			UInt32 A2;
+			public CRandomGenerator() { Init(); }
+			public void Init() { A1 = 362436069; A2 = 521288629; }
+			public UInt32 GetRnd()
+			{
+				return
+					((A1 = 36969 * (A1 & 0xffff) + (A1 >> 16)) << 16) ^
+					((A2 = 18000 * (A2 & 0xffff) + (A2 >> 16)));
+			}
+		};
+
+		class CBitRandomGenerator
+		{
+			CRandomGenerator RG = new CRandomGenerator();
+			UInt32 Value;
+			int NumBits;
+			public void Init()
+			{
+				Value = 0;
+				NumBits = 0;
+			}
+			public UInt32 GetRnd(int numBits)
+			{
+				UInt32 result;
+				if (NumBits > numBits)
+				{
+					result = Value & (((UInt32)1 << numBits) - 1);
+					Value >>= numBits;
+					NumBits -= numBits;
+					return result;
+				}
+				numBits -= NumBits;
+				result = (Value << numBits);
+				Value = RG.GetRnd();
+				result |= Value & (((UInt32)1 << numBits) - 1);
+				Value >>= numBits;
+				NumBits = 32 - numBits;
+				return result;
+			}
+		};
+
+		class CBenchRandomGenerator
+		{
+			CBitRandomGenerator RG = new CBitRandomGenerator();
+			UInt32 Pos;
+			UInt32 Rep0;
+			
+			public UInt32 BufferSize;
+			public Byte[] Buffer = null;
+
+			public CBenchRandomGenerator() { }
+
+			public void Set(UInt32 bufferSize)
+			{
+				Buffer = new Byte[bufferSize];
+				Pos = 0;
+				BufferSize = bufferSize;
+			}
+			UInt32 GetRndBit() { return RG.GetRnd(1); }
+			UInt32 GetLogRandBits(int numBits)
+			{
+				UInt32 len = RG.GetRnd(numBits);
+				return RG.GetRnd((int)len);
+			}
+			UInt32 GetOffset()
+			{
+				if (GetRndBit() == 0)
+					return GetLogRandBits(4);
+				return (GetLogRandBits(4) << 10) | RG.GetRnd(10);
+			}
+			UInt32 GetLen1() { return RG.GetRnd(1 + (int)RG.GetRnd(2)); }
+			UInt32 GetLen2() { return RG.GetRnd(2 + (int)RG.GetRnd(2)); }
+			public void Generate()
+			{
+				RG.Init();
+				Rep0 = 1;
+				while (Pos < BufferSize)
+				{
+					if (GetRndBit() == 0 || Pos < 1)
+						Buffer[Pos++] = (Byte)RG.GetRnd(8);
+					else
+					{
+						UInt32 len;
+						if (RG.GetRnd(3) == 0)
+							len = 1 + GetLen1();
+						else
+						{
+							do
+								Rep0 = GetOffset();
+							while (Rep0 >= Pos);
+							Rep0++;
+							len = 2 + GetLen2();
+						}
+						for (UInt32 i = 0; i < len && Pos < BufferSize; i++, Pos++)
+							Buffer[Pos] = Buffer[Pos - Rep0];
+					}
+				}
+			}
+		};
+
+		class CrcOutStream : System.IO.Stream
+		{
+			public CRC CRC = new CRC();
+			public void Init() { CRC.Init(); }
+			public UInt32 GetDigest() { return CRC.GetDigest(); }
+
+			public override bool CanRead { get { return false; } }
+			public override bool CanSeek { get { return false; } }
+			public override bool CanWrite { get { return true; } }
+			public override Int64 Length { get { return 0; } }
+			public override Int64 Position { get { return 0; } set { } }
+			public override void Flush() { }
+			public override long Seek(long offset, SeekOrigin origin) { return 0; }
+			public override void SetLength(long value) { }
+			public override int Read(byte[] buffer, int offset, int count) { return 0; }
+
+			public override void WriteByte(byte b)
+			{
+				CRC.UpdateByte(b);
+			}
+			public override void Write(byte[] buffer, int offset, int count)
+			{
+				CRC.Update(buffer, (uint)offset, (uint)count);
+			}
+		};
+
+		class CProgressInfo : ICodeProgress
+		{
+			public Int64 ApprovedStart;
+			public Int64 InSize;
+			public System.DateTime Time;
+			public void Init() { InSize = 0; }
+			public void SetProgress(Int64 inSize, Int64 outSize)
+			{
+				if (inSize >= ApprovedStart && InSize == 0)
+				{
+					Time = DateTime.UtcNow;
+					InSize = inSize;
+				}
+			}
+		}
+		const int kSubBits = 8;
+
+		static UInt32 GetLogSize(UInt32 size)
+		{
+			for (int i = kSubBits; i < 32; i++)
+				for (UInt32 j = 0; j < (1 << kSubBits); j++)
+					if (size <= (((UInt32)1) << i) + (j << (i - kSubBits)))
+						return (UInt32)(i << kSubBits) + j;
+			return (32 << kSubBits);
+		}
+
+		static UInt64 MyMultDiv64(UInt64 value, UInt64 elapsedTime)
+		{
+			UInt64 freq = TimeSpan.TicksPerSecond;
+			UInt64 elTime = elapsedTime;
+			while (freq > 1000000)
+			{
+				freq >>= 1;
+				elTime >>= 1;
+			}
+			if (elTime == 0)
+				elTime = 1;
+			return value * freq / elTime;
+		}
+
+		static UInt64 GetCompressRating(UInt32 dictionarySize, UInt64 elapsedTime, UInt64 size)
+		{
+			UInt64 t = GetLogSize(dictionarySize) - (18 << kSubBits);
+			UInt64 numCommandsForOne = 1060 + ((t * t * 10) >> (2 * kSubBits));
+			UInt64 numCommands = (UInt64)(size) * numCommandsForOne;
+			return MyMultDiv64(numCommands, elapsedTime);
+		}
+
+		static UInt64 GetDecompressRating(UInt64 elapsedTime, UInt64 outSize, UInt64 inSize)
+		{
+			UInt64 numCommands = inSize * 220 + outSize * 20;
+			return MyMultDiv64(numCommands, elapsedTime);
+		}
+
+		static UInt64 GetTotalRating(
+			UInt32 dictionarySize,
+			UInt64 elapsedTimeEn, UInt64 sizeEn,
+			UInt64 elapsedTimeDe,
+			UInt64 inSizeDe, UInt64 outSizeDe)
+		{
+			return (GetCompressRating(dictionarySize, elapsedTimeEn, sizeEn) +
+				GetDecompressRating(elapsedTimeDe, inSizeDe, outSizeDe)) / 2;
+		}
+
+		static void PrintValue(UInt64 v)
+		{
+			string s = v.ToString();
+			for (int i = 0; i + s.Length < 6; i++)
+				System.Console.Write(" ");
+			System.Console.Write(s);
+		}
+
+		static void PrintRating(UInt64 rating)
+		{
+			PrintValue(rating / 1000000);
+			System.Console.Write(" MIPS");
+		}
+
+		static void PrintResults(
+			UInt32 dictionarySize,
+			UInt64 elapsedTime,
+			UInt64 size,
+			bool decompressMode, UInt64 secondSize)
+		{
+			UInt64 speed = MyMultDiv64(size, elapsedTime);
+			PrintValue(speed / 1024);
+			System.Console.Write(" KB/s  ");
+			UInt64 rating;
+			if (decompressMode)
+				rating = GetDecompressRating(elapsedTime, size, secondSize);
+			else
+				rating = GetCompressRating(dictionarySize, elapsedTime, size);
+			PrintRating(rating);
+		}
+
+		static public int LzmaBenchmark(Int32 numIterations, UInt32 dictionarySize)
+		{
+			if (numIterations <= 0)
+				return 0;
+			if (dictionarySize < (1 << 18))
+			{
+				System.Console.WriteLine("\nError: dictionary size for benchmark must be >= 19 (512 KB)");
+				return 1;
+			}
+			System.Console.Write("\n       Compressing                Decompressing\n\n");
+
+			Compression.LZMA.Encoder encoder = new Compression.LZMA.Encoder();
+			Compression.LZMA.Decoder decoder = new Compression.LZMA.Decoder();
+
+
+			CoderPropID[] propIDs = 
+			{ 
+				CoderPropID.DictionarySize,
+			};
+			object[] properties = 
+			{
+				(Int32)(dictionarySize),
+			};
+
+			UInt32 kBufferSize = dictionarySize + kAdditionalSize;
+			UInt32 kCompressedBufferSize = (kBufferSize / 2) + kCompressedAdditionalSize;
+
+			encoder.SetCoderProperties(propIDs, properties);
+			System.IO.MemoryStream propStream = new System.IO.MemoryStream();
+			encoder.WriteCoderProperties(propStream);
+			byte[] propArray = propStream.ToArray();
+
+			CBenchRandomGenerator rg = new CBenchRandomGenerator();
+
+			rg.Set(kBufferSize);
+			rg.Generate();
+			CRC crc = new CRC();
+			crc.Init();
+			crc.Update(rg.Buffer, 0, rg.BufferSize);
+
+			CProgressInfo progressInfo = new CProgressInfo();
+			progressInfo.ApprovedStart = dictionarySize;
+
+			UInt64 totalBenchSize = 0;
+			UInt64 totalEncodeTime = 0;
+			UInt64 totalDecodeTime = 0;
+			UInt64 totalCompressedSize = 0;
+
+			MemoryStream inStream = new MemoryStream(rg.Buffer, 0, (int)rg.BufferSize);
+			MemoryStream compressedStream = new MemoryStream((int)kCompressedBufferSize);
+			CrcOutStream crcOutStream = new CrcOutStream();
+			for (Int32 i = 0; i < numIterations; i++)
+			{
+				progressInfo.Init();
+				inStream.Seek(0, SeekOrigin.Begin);
+				compressedStream.Seek(0, SeekOrigin.Begin);
+				encoder.Code(inStream, compressedStream, -1, -1, progressInfo);
+				TimeSpan sp2 = DateTime.UtcNow - progressInfo.Time;
+				UInt64 encodeTime = (UInt64)sp2.Ticks;
+
+				long compressedSize = compressedStream.Position;
+				if (progressInfo.InSize == 0)
+					throw (new Exception("Internal ERROR 1282"));
+
+				UInt64 decodeTime = 0;
+				for (int j = 0; j < 2; j++)
+				{
+					compressedStream.Seek(0, SeekOrigin.Begin);
+					crcOutStream.Init();
+
+					decoder.SetDecoderProperties(propArray);
+					UInt64 outSize = kBufferSize;
+					System.DateTime startTime = DateTime.UtcNow;
+					decoder.Code(compressedStream, crcOutStream, 0, (Int64)outSize, null);
+					TimeSpan sp = (DateTime.UtcNow - startTime);
+					decodeTime = (ulong)sp.Ticks;
+					if (crcOutStream.GetDigest() != crc.GetDigest())
+						throw (new Exception("CRC Error"));
+				}
+				UInt64 benchSize = kBufferSize - (UInt64)progressInfo.InSize;
+				PrintResults(dictionarySize, encodeTime, benchSize, false, 0);
+				System.Console.Write("     ");
+				PrintResults(dictionarySize, decodeTime, kBufferSize, true, (ulong)compressedSize);
+				System.Console.WriteLine();
+
+				totalBenchSize += benchSize;
+				totalEncodeTime += encodeTime;
+				totalDecodeTime += decodeTime;
+				totalCompressedSize += (ulong)compressedSize;
+			}
+			System.Console.WriteLine("---------------------------------------------------");
+			PrintResults(dictionarySize, totalEncodeTime, totalBenchSize, false, 0);
+			System.Console.Write("     ");
+			PrintResults(dictionarySize, totalDecodeTime,
+					kBufferSize * (UInt64)numIterations, true, totalCompressedSize);
+			System.Console.WriteLine("    Average");
+			return 0;
+		}
+	}
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/misc/libphysfs/lzma/CS/7zip/Compress/LzmaAlone/Properties/AssemblyInfo.cs	Mon Apr 10 12:06:43 2017 -0400
@@ -0,0 +1,29 @@
+#region Using directives
+
+using System.Reflection;
+using System.Runtime.CompilerServices;
+
+#endregion
+
+// General Information about an assembly is controlled through the following 
+// set of attributes. Change these attribute values to modify the information
+// associated with an assembly.
+[assembly: AssemblyTitle("LZMA#")]
+[assembly: AssemblyDescription("")]
+[assembly: AssemblyConfiguration("")]
+[assembly: AssemblyCompany("Igor Pavlov")]
+[assembly: AssemblyProduct("LZMA# SDK")]
+[assembly: AssemblyCopyright("Copyright @ Igor Pavlov 1999-2004")]
+[assembly: AssemblyTrademark("")]
+[assembly: AssemblyCulture("")]
+
+// Version information for an assembly consists of the following four values:
+//
+//      Major Version
+//      Minor Version 
+//      Build Number
+//      Revision
+//
+// You can specify all the values or you can default the Revision and Build Numbers 
+// by using the '*' as shown below:
+[assembly: AssemblyVersion("4.12.*")]
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/misc/libphysfs/lzma/CS/7zip/Compress/LzmaAlone/Properties/Resources.cs	Mon Apr 10 12:06:43 2017 -0400
@@ -0,0 +1,70 @@
+//------------------------------------------------------------------------------
+// <autogenerated>
+//     This code was generated by a tool.
+//     Runtime Version:2.0.40607.42
+//
+//     Changes to this file may cause incorrect behavior and will be lost if
+//     the code is regenerated.
+// </autogenerated>
+//------------------------------------------------------------------------------
+
+namespace LzmaAlone.Properties
+{
+	using System;
+	using System.IO;
+	using System.Resources;
+
+	/// <summary>
+	///    A strongly-typed resource class, for looking up localized strings, etc.
+	/// </summary>
+	// This class was auto-generated by the Strongly Typed Resource Builder
+	// class via a tool like ResGen or Visual Studio.NET.
+	// To add or remove a member, edit your .ResX file then rerun ResGen
+	// with the /str option, or rebuild your VS project.
+	class Resources
+	{
+
+		private static System.Resources.ResourceManager _resMgr;
+
+		private static System.Globalization.CultureInfo _resCulture;
+
+		/*FamANDAssem*/
+		internal Resources()
+		{
+		}
+
+		/// <summary>
+		///    Returns the cached ResourceManager instance used by this class.
+		/// </summary>
+		[System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Advanced)]
+		public static System.Resources.ResourceManager ResourceManager
+		{
+			get
+			{
+				if ((_resMgr == null))
+				{
+					System.Resources.ResourceManager temp = new System.Resources.ResourceManager("Resources", typeof(Resources).Assembly);
+					_resMgr = temp;
+				}
+				return _resMgr;
+			}
+		}
+
+		/// <summary>
+		///    Overrides the current thread's CurrentUICulture property for all
+		///    resource lookups using this strongly typed resource class.
+		/// </summary>
+		[System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Advanced)]
+		public static System.Globalization.CultureInfo Culture
+		{
+			get
+			{
+				return _resCulture;
+			}
+			set
+			{
+				_resCulture = value;
+			}
+		}
+	}
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/misc/libphysfs/lzma/CS/7zip/Compress/LzmaAlone/Properties/Settings.cs	Mon Apr 10 12:06:43 2017 -0400
@@ -0,0 +1,42 @@
+//------------------------------------------------------------------------------
+// <autogenerated>
+//     This code was generated by a tool.
+//     Runtime Version:2.0.40607.42
+//
+//     Changes to this file may cause incorrect behavior and will be lost if
+//     the code is regenerated.
+// </autogenerated>
+//------------------------------------------------------------------------------
+
+namespace LzmaAlone.Properties
+{
+	public partial class Settings : System.Configuration.ApplicationSettingsBase
+	{
+		private static Settings m_Value;
+
+		private static object m_SyncObject = new object();
+
+		public static Settings Value
+		{
+			get
+			{
+				if ((Settings.m_Value == null))
+				{
+					System.Threading.Monitor.Enter(Settings.m_SyncObject);
+					if ((Settings.m_Value == null))
+					{
+						try
+						{
+							Settings.m_Value = new Settings();
+						}
+						finally
+						{
+							System.Threading.Monitor.Exit(Settings.m_SyncObject);
+						}
+					}
+				}
+				return Settings.m_Value;
+			}
+		}
+	}
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/misc/libphysfs/lzma/CS/7zip/Compress/RangeCoder/RangeCoder.cs	Mon Apr 10 12:06:43 2017 -0400
@@ -0,0 +1,234 @@
+using System;
+
+namespace SevenZip.Compression.RangeCoder
+{
+	class Encoder
+	{
+		public const uint kTopValue = (1 << 24);
+
+		System.IO.Stream Stream;
+
+		public UInt64 Low;
+		public uint Range;
+		uint _cacheSize;
+		byte _cache;
+
+		long StartPosition;
+
+		public void SetStream(System.IO.Stream stream)
+		{
+			Stream = stream;
+		}
+
+		public void ReleaseStream()
+		{
+			Stream = null;
+		}
+
+		public void Init()
+		{
+			StartPosition = Stream.Position;
+
+			Low = 0;
+			Range = 0xFFFFFFFF;
+			_cacheSize = 1;
+			_cache = 0;
+		}
+
+		public void FlushData()
+		{
+			for (int i = 0; i < 5; i++)
+				ShiftLow();
+		}
+
+		public void FlushStream()
+		{
+			Stream.Flush();
+		}
+
+		public void CloseStream()
+		{
+			Stream.Close();
+		}
+
+		public void Encode(uint start, uint size, uint total)
+		{
+			Low += start * (Range /= total);
+			Range *= size;
+			while (Range < kTopValue)
+			{
+				Range <<= 8;
+				ShiftLow();
+			}
+		}
+
+		public void ShiftLow()
+		{
+			if ((uint)Low < (uint)0xFF000000 || (uint)(Low >> 32) == 1)
+			{
+				byte temp = _cache;
+				do
+				{
+					Stream.WriteByte((byte)(temp + (Low >> 32)));
+					temp = 0xFF;
+				}
+				while (--_cacheSize != 0);
+				_cache = (byte)(((uint)Low) >> 24);
+			}
+			_cacheSize++;
+			Low = ((uint)Low) << 8;
+		}
+
+		public void EncodeDirectBits(uint v, int numTotalBits)
+		{
+			for (int i = numTotalBits - 1; i >= 0; i--)
+			{
+				Range >>= 1;
+				if (((v >> i) & 1) == 1)
+					Low += Range;
+				if (Range < kTopValue)
+				{
+					Range <<= 8;
+					ShiftLow();
+				}
+			}
+		}
+
+		public void EncodeBit(uint size0, int numTotalBits, uint symbol)
+		{
+			uint newBound = (Range >> numTotalBits) * size0;
+			if (symbol == 0)
+				Range = newBound;
+			else
+			{
+				Low += newBound;
+				Range -= newBound;
+			}
+			while (Range < kTopValue)
+			{
+				Range <<= 8;
+				ShiftLow();
+			}
+		}
+
+		public long GetProcessedSizeAdd()
+		{
+			return _cacheSize +
+				Stream.Position - StartPosition + 4;
+			// (long)Stream.GetProcessedSize();
+		}
+	}
+
+	class Decoder
+	{
+		public const uint kTopValue = (1 << 24);
+		public uint Range;
+		public uint Code;
+		// public Buffer.InBuffer Stream = new Buffer.InBuffer(1 << 16);
+		public System.IO.Stream Stream;
+
+		public void Init(System.IO.Stream stream)
+		{
+			// Stream.Init(stream);
+			Stream = stream;
+
+			Code = 0;
+			Range = 0xFFFFFFFF;
+			for (int i = 0; i < 5; i++)
+				Code = (Code << 8) | (byte)Stream.ReadByte();
+		}
+
+		public void ReleaseStream()
+		{
+			// Stream.ReleaseStream();
+			Stream = null;
+		}
+
+		public void CloseStream()
+		{
+			Stream.Close();
+		}
+
+		public void Normalize()
+		{
+			while (Range < kTopValue)
+			{
+				Code = (Code << 8) | (byte)Stream.ReadByte();
+				Range <<= 8;
+			}
+		}
+
+		public void Normalize2()
+		{
+			if (Range < kTopValue)
+			{
+				Code = (Code << 8) | (byte)Stream.ReadByte();
+				Range <<= 8;
+			}
+		}
+
+		public uint GetThreshold(uint total)
+		{
+			return Code / (Range /= total);
+		}
+
+		public void Decode(uint start, uint size, uint total)
+		{
+			Code -= start * Range;
+			Range *= size;
+			Normalize();
+		}
+
+		public uint DecodeDirectBits(int numTotalBits)
+		{
+			uint range = Range;
+			uint code = Code;
+			uint result = 0;
+			for (int i = numTotalBits; i > 0; i--)
+			{
+				range >>= 1;
+				/*
+				result <<= 1;
+				if (code >= range)
+				{
+					code -= range;
+					result |= 1;
+				}
+				*/
+				uint t = (code - range) >> 31;
+				code -= range & (t - 1);
+				result = (result << 1) | (1 - t);
+
+				if (range < kTopValue)
+				{
+					code = (code << 8) | (byte)Stream.ReadByte();
+					range <<= 8;
+				}
+			}
+			Range = range;
+			Code = code;
+			return result;
+		}
+
+		public uint DecodeBit(uint size0, int numTotalBits)
+		{
+			uint newBound = (Range >> numTotalBits) * size0;
+			uint symbol;
+			if (Code < newBound)
+			{
+				symbol = 0;
+				Range = newBound;
+			}
+			else
+			{
+				symbol = 1;
+				Code -= newBound;
+				Range -= newBound;
+			}
+			Normalize();
+			return symbol;
+		}
+
+		// ulong GetProcessedSize() {return Stream.GetProcessedSize(); }
+	}
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/misc/libphysfs/lzma/CS/7zip/Compress/RangeCoder/RangeCoderBit.cs	Mon Apr 10 12:06:43 2017 -0400
@@ -0,0 +1,117 @@
+using System;
+
+namespace SevenZip.Compression.RangeCoder
+{
+	struct BitEncoder
+	{
+		public const int kNumBitModelTotalBits = 11;
+		public const uint kBitModelTotal = (1 << kNumBitModelTotalBits);
+		const int kNumMoveBits = 5;
+		const int kNumMoveReducingBits = 2;
+		public const int kNumBitPriceShiftBits = 6;
+
+		uint Prob;
+
+		public void Init() { Prob = kBitModelTotal >> 1; }
+
+		public void UpdateModel(uint symbol)
+		{
+			if (symbol == 0)
+				Prob += (kBitModelTotal - Prob) >> kNumMoveBits;
+			else
+				Prob -= (Prob) >> kNumMoveBits;
+		}
+
+		public void Encode(Encoder encoder, uint symbol)
+		{
+			// encoder.EncodeBit(Prob, kNumBitModelTotalBits, symbol);
+			// UpdateModel(symbol);
+			uint newBound = (encoder.Range >> kNumBitModelTotalBits) * Prob;
+			if (symbol == 0)
+			{
+				encoder.Range = newBound;
+				Prob += (kBitModelTotal - Prob) >> kNumMoveBits;
+			}
+			else
+			{
+				encoder.Low += newBound;
+				encoder.Range -= newBound;
+				Prob -= (Prob) >> kNumMoveBits;
+			}
+			if (encoder.Range < Encoder.kTopValue)
+			{
+				encoder.Range <<= 8;
+				encoder.ShiftLow();
+			}
+		}
+
+		private static UInt32[] ProbPrices = new UInt32[kBitModelTotal >> kNumMoveReducingBits];
+
+		static BitEncoder()
+		{
+			const int kNumBits = (kNumBitModelTotalBits - kNumMoveReducingBits);
+			for (int i = kNumBits - 1; i >= 0; i--)
+			{
+				UInt32 start = (UInt32)1 << (kNumBits - i - 1);
+				UInt32 end = (UInt32)1 << (kNumBits - i);
+				for (UInt32 j = start; j < end; j++)
+					ProbPrices[j] = ((UInt32)i << kNumBitPriceShiftBits) +
+						(((end - j) << kNumBitPriceShiftBits) >> (kNumBits - i - 1));
+			}
+		}
+
+		public uint GetPrice(uint symbol)
+		{
+			return ProbPrices[(((Prob - symbol) ^ ((-(int)symbol))) & (kBitModelTotal - 1)) >> kNumMoveReducingBits];
+		}
+	  public uint GetPrice0() { return ProbPrices[Prob >> kNumMoveReducingBits]; }
+		public uint GetPrice1() { return ProbPrices[(kBitModelTotal - Prob) >> kNumMoveReducingBits]; }
+	}
+
+	struct BitDecoder
+	{
+		public const int kNumBitModelTotalBits = 11;
+		public const uint kBitModelTotal = (1 << kNumBitModelTotalBits);
+		const int kNumMoveBits = 5;
+
+		uint Prob;
+
+		public void UpdateModel(int numMoveBits, uint symbol)
+		{
+			if (symbol == 0)
+				Prob += (kBitModelTotal - Prob) >> numMoveBits;
+			else
+				Prob -= (Prob) >> numMoveBits;
+		}
+
+		public void Init() { Prob = kBitModelTotal >> 1; }
+
+		public uint Decode(RangeCoder.Decoder rangeDecoder)
+		{
+			uint newBound = (uint)(rangeDecoder.Range >> kNumBitModelTotalBits) * (uint)Prob;
+			if (rangeDecoder.Code < newBound)
+			{
+				rangeDecoder.Range = newBound;
+				Prob += (kBitModelTotal - Prob) >> kNumMoveBits;
+				if (rangeDecoder.Range < Decoder.kTopValue)
+				{
+					rangeDecoder.Code = (rangeDecoder.Code << 8) | (byte)rangeDecoder.Stream.ReadByte();
+					rangeDecoder.Range <<= 8;
+				}
+				return 0;
+			}
+			else
+			{
+				rangeDecoder.Range -= newBound;
+				rangeDecoder.Code -= newBound;
+				Prob -= (Prob) >> kNumMoveBits;
+				if (rangeDecoder.Range < Decoder.kTopValue)
+				{
+					rangeDecoder.Code = (rangeDecoder.Code << 8) | (byte)rangeDecoder.Stream.ReadByte();
+					rangeDecoder.Range <<= 8;
+				}
+				return 1;
+			}
+		}
+	}
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/misc/libphysfs/lzma/CS/7zip/Compress/RangeCoder/RangeCoderBitTree.cs	Mon Apr 10 12:06:43 2017 -0400
@@ -0,0 +1,157 @@
+using System;
+
+namespace SevenZip.Compression.RangeCoder
+{
+	struct BitTreeEncoder
+	{
+		BitEncoder[] Models;
+		int NumBitLevels;
+
+		public BitTreeEncoder(int numBitLevels)
+		{
+			NumBitLevels = numBitLevels;
+			Models = new BitEncoder[1 << numBitLevels];
+		}
+
+		public void Init()
+		{
+			for (uint i = 1; i < (1 << NumBitLevels); i++)
+				Models[i].Init();
+		}
+
+		public void Encode(Encoder rangeEncoder, UInt32 symbol)
+		{
+			UInt32 m = 1;
+			for (int bitIndex = NumBitLevels; bitIndex > 0; )
+			{
+				bitIndex--;
+				UInt32 bit = (symbol >> bitIndex) & 1;
+				Models[m].Encode(rangeEncoder, bit);
+				m = (m << 1) | bit;
+			}
+		}
+
+		public void ReverseEncode(Encoder rangeEncoder, UInt32 symbol)
+		{
+			UInt32 m = 1;
+			for (UInt32 i = 0; i < NumBitLevels; i++)
+			{
+				UInt32 bit = symbol & 1;
+				Models[m].Encode(rangeEncoder, bit);
+				m = (m << 1) | bit;
+				symbol >>= 1;
+			}
+		}
+
+		public UInt32 GetPrice(UInt32 symbol)
+		{
+			UInt32 price = 0;
+			UInt32 m = 1;
+			for (int bitIndex = NumBitLevels; bitIndex > 0; )
+			{
+				bitIndex--;
+				UInt32 bit = (symbol >> bitIndex) & 1;
+				price += Models[m].GetPrice(bit);
+				m = (m << 1) + bit;
+			}
+			return price;
+		}
+
+		public UInt32 ReverseGetPrice(UInt32 symbol)
+		{
+			UInt32 price = 0;
+			UInt32 m = 1;
+			for (int i = NumBitLevels; i > 0; i--)
+			{
+				UInt32 bit = symbol & 1;
+				symbol >>= 1;
+				price += Models[m].GetPrice(bit);
+				m = (m << 1) | bit;
+			}
+			return price;
+		}
+
+		public static UInt32 ReverseGetPrice(BitEncoder[] Models, UInt32 startIndex,
+			int NumBitLevels, UInt32 symbol)
+		{
+			UInt32 price = 0;
+			UInt32 m = 1;
+			for (int i = NumBitLevels; i > 0; i--)
+			{
+				UInt32 bit = symbol & 1;
+				symbol >>= 1;
+				price += Models[startIndex + m].GetPrice(bit);
+				m = (m << 1) | bit;
+			}
+			return price;
+		}
+
+		public static void ReverseEncode(BitEncoder[] Models, UInt32 startIndex,
+			Encoder rangeEncoder, int NumBitLevels, UInt32 symbol)
+		{
+			UInt32 m = 1;
+			for (int i = 0; i < NumBitLevels; i++)
+			{
+				UInt32 bit = symbol & 1;
+				Models[startIndex + m].Encode(rangeEncoder, bit);
+				m = (m << 1) | bit;
+				symbol >>= 1;
+			}
+		}
+	}
+
+	struct BitTreeDecoder
+	{
+		BitDecoder[] Models;
+		int NumBitLevels;
+
+		public BitTreeDecoder(int numBitLevels)
+		{
+			NumBitLevels = numBitLevels;
+			Models = new BitDecoder[1 << numBitLevels];
+		}
+
+		public void Init()
+		{
+			for (uint i = 1; i < (1 << NumBitLevels); i++)
+				Models[i].Init();
+		}
+
+		public uint Decode(RangeCoder.Decoder rangeDecoder)
+		{
+			uint m = 1;
+			for (int bitIndex = NumBitLevels; bitIndex > 0; bitIndex--)
+				m = (m << 1) + Models[m].Decode(rangeDecoder);
+			return m - ((uint)1 << NumBitLevels);
+		}
+
+		public uint ReverseDecode(RangeCoder.Decoder rangeDecoder)
+		{
+			uint m = 1;
+			uint symbol = 0;
+			for (int bitIndex = 0; bitIndex < NumBitLevels; bitIndex++)
+			{
+				uint bit = Models[m].Decode(rangeDecoder);
+				m <<= 1;
+				m += bit;
+				symbol |= (bit << bitIndex);
+			}
+			return symbol;
+		}
+
+		public static uint ReverseDecode(BitDecoder[] Models, UInt32 startIndex,
+			RangeCoder.Decoder rangeDecoder, int NumBitLevels)
+		{
+			uint m = 1;
+			uint symbol = 0;
+			for (int bitIndex = 0; bitIndex < NumBitLevels; bitIndex++)
+			{
+				uint bit = Models[startIndex + m].Decode(rangeDecoder);
+				m <<= 1;
+				m += bit;
+				symbol |= (bit << bitIndex);
+			}
+			return symbol;
+		}
+	}
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/misc/libphysfs/lzma/CS/7zip/ICoder.cs	Mon Apr 10 12:06:43 2017 -0400
@@ -0,0 +1,145 @@
+// ICoder.h
+
+using System;
+
+namespace SevenZip
+{
+	/// <summary>
+	/// The exception that is thrown when an error in input stream occurs during decoding.
+	/// </summary>
+	class DataErrorException : ApplicationException
+	{
+		public DataErrorException(): base("Data Error") { }
+	}
+
+	/// <summary>
+	/// The exception that is thrown when the value of an argument is outside the allowable range.
+	/// </summary>
+	class InvalidParamException : ApplicationException
+	{
+		public InvalidParamException(): base("Invalid Parameter") { }
+	}
+
+	public interface ICodeProgress
+	{
+		/// <summary>
+		/// Callback progress.
+		/// </summary>
+		/// <param name="inSize">
+		/// input size. -1 if unknown.
+		/// </param>
+		/// <param name="outSize">
+		/// output size. -1 if unknown.
+		/// </param>
+		void SetProgress(Int64 inSize, Int64 outSize);
+	};
+
+	public interface ICoder
+	{
+		/// <summary>
+		/// Codes streams.
+		/// </summary>
+		/// <param name="inStream">
+		/// input Stream.
+		/// </param>
+		/// <param name="outStream">
+		/// output Stream.
+		/// </param>
+		/// <param name="inSize">
+		/// input Size. -1 if unknown.
+		/// </param>
+		/// <param name="outSize">
+		/// output Size. -1 if unknown.
+		/// </param>
+		/// <param name="progress">
+		/// callback progress reference.
+		/// </param>
+		/// <exception cref="SevenZip.DataErrorException">
+		/// if input stream is not valid
+		/// </exception>
+		void Code(System.IO.Stream inStream, System.IO.Stream outStream,
+			Int64 inSize, Int64 outSize, ICodeProgress progress);
+	};
+
+	/*
+	public interface ICoder2
+	{
+		 void Code(ISequentialInStream []inStreams,
+				const UInt64 []inSizes, 
+				ISequentialOutStream []outStreams, 
+				UInt64 []outSizes,
+				ICodeProgress progress);
+	};
+  */
+
+	/// <summary>
+	/// Provides the fields that represent properties idenitifiers for compressing.
+	/// </summary>
+	public enum CoderPropID
+	{
+		/// <summary>
+		/// Specifies size of dictionary.
+		/// </summary>
+		DictionarySize = 0x400,
+		/// <summary>
+		/// Specifies size of memory for PPM*.
+		/// </summary>
+		UsedMemorySize,
+		/// <summary>
+		/// Specifies order for PPM methods.
+		/// </summary>
+		Order,
+		/// <summary>
+		/// Specifies number of postion state bits for LZMA (0 <= x <= 4).
+		/// </summary>
+		PosStateBits = 0x440,
+		/// <summary>
+		/// Specifies number of literal context bits for LZMA (0 <= x <= 8).
+		/// </summary>
+		LitContextBits,
+		/// <summary>
+		/// Specifies number of literal position bits for LZMA (0 <= x <= 4).
+		/// </summary>
+		LitPosBits,
+		/// <summary>
+		/// Specifies number of fast bytes for LZ*.
+		/// </summary>
+		NumFastBytes = 0x450,
+		/// <summary>
+		/// Specifies match finder. LZMA: "BT2", "BT4" or "BT4B".
+		/// </summary>
+		MatchFinder,
+		/// <summary>
+		/// Specifies number of passes.
+		/// </summary>
+		NumPasses = 0x460,
+		/// <summary>
+		/// Specifies number of algorithm.
+		/// </summary>
+		Algorithm = 0x470,
+		/// <summary>
+		/// Specifies multithread mode.
+		/// </summary>
+		MultiThread = 0x480,
+		/// <summary>
+		/// Specifies mode with end marker.
+		/// </summary>
+		EndMarker = 0x490
+	};
+
+
+	public interface ISetCoderProperties
+	{
+		void SetCoderProperties(CoderPropID[] propIDs, object[] properties);
+	};
+
+	public interface IWriteCoderProperties
+	{
+		void WriteCoderProperties(System.IO.Stream outStream);
+	}
+
+	public interface ISetDecoderProperties
+	{
+		void SetDecoderProperties(byte[] properties);
+	}
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/misc/libphysfs/lzma/Java/SevenZip/CRC.java	Mon Apr 10 12:06:43 2017 -0400
@@ -0,0 +1,52 @@
+// SevenZip/CRC.java
+
+package SevenZip;
+
+public class CRC
+{
+	static public int[] Table = new int[256];
+	
+	static
+	{
+		for (int i = 0; i < 256; i++)
+		{
+			int r = i;
+			for (int j = 0; j < 8; j++)
+				if ((r & 1) != 0)
+					r = (r >>> 1) ^ 0xEDB88320;
+				else
+					r >>>= 1;
+			Table[i] = r;
+		}
+	}
+	
+	int _value = -1;
+	
+	public void Init()
+	{
+		_value = -1;
+	}
+	
+	public void Update(byte[] data, int offset, int size)
+	{
+		for (int i = 0; i < size; i++)
+			_value = Table[(_value ^ data[offset + i]) & 0xFF] ^ (_value >>> 8);
+	}
+	
+	public void Update(byte[] data)
+	{
+		int size = data.length;
+		for (int i = 0; i < size; i++)
+			_value = Table[(_value ^ data[i]) & 0xFF] ^ (_value >>> 8);
+	}
+	
+	public void UpdateByte(int b)
+	{
+		_value = Table[(_value ^ b) & 0xFF] ^ (_value >>> 8);
+	}
+	
+	public int GetDigest()
+	{
+		return _value ^ (-1);
+	}
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/misc/libphysfs/lzma/Java/SevenZip/Compression/LZ/BinTree.java	Mon Apr 10 12:06:43 2017 -0400
@@ -0,0 +1,382 @@
+// LZ.BinTree
+
+package SevenZip.Compression.LZ;
+import java.io.IOException;
+
+
+public class BinTree extends InWindow
+{
+	int _cyclicBufferPos;
+	int _cyclicBufferSize = 0;
+	int _matchMaxLen;
+	
+	int[] _son;
+	int[] _hash;
+	
+	int _cutValue = 0xFF;
+	int _hashMask;
+	int _hashSizeSum = 0;
+	
+	boolean HASH_ARRAY = true;
+
+	static final int kHash2Size = 1 << 10;
+	static final int kHash3Size = 1 << 16;
+	static final int kBT2HashSize = 1 << 16;
+	static final int kStartMaxLen = 1;
+	static final int kHash3Offset = kHash2Size;
+	static final int kEmptyHashValue = 0;
+	static final int kMaxValForNormalize = (1 << 30) - 1;
+	
+	int kNumHashDirectBytes = 0;
+	int kMinMatchCheck = 4;
+	int kFixHashSize = kHash2Size + kHash3Size;
+
+	public void SetType(int numHashBytes)
+	{
+		HASH_ARRAY = (numHashBytes > 2);
+		if (HASH_ARRAY)
+		{
+			kNumHashDirectBytes = 0;
+			kMinMatchCheck = 4;
+			kFixHashSize = kHash2Size + kHash3Size;
+		}
+		else
+		{
+			kNumHashDirectBytes = 2;
+			kMinMatchCheck = 2 + 1;
+			kFixHashSize = 0;
+		}
+	}
+	
+
+	
+
+	public void Init() throws IOException
+	{
+		super.Init();
+		for (int i = 0; i < _hashSizeSum; i++)
+			_hash[i] = kEmptyHashValue;
+		_cyclicBufferPos = 0;
+		ReduceOffsets(-1);
+	}
+	
+	public void MovePos() throws IOException
+	{
+		if (++_cyclicBufferPos >= _cyclicBufferSize)
+			_cyclicBufferPos = 0;
+		super.MovePos();
+		if (_pos == kMaxValForNormalize)
+			Normalize();
+	}
+	
+
+	
+	
+	
+	
+	
+	
+	public boolean Create(int historySize, int keepAddBufferBefore,
+			int matchMaxLen, int keepAddBufferAfter)
+	{
+		if (historySize > kMaxValForNormalize - 256)
+			return false;
+		_cutValue = 16 + (matchMaxLen >> 1);
+
+		int windowReservSize = (historySize + keepAddBufferBefore +
+				matchMaxLen + keepAddBufferAfter) / 2 + 256;
+		
+		super.Create(historySize + keepAddBufferBefore, matchMaxLen + keepAddBufferAfter, windowReservSize);
+		
+		_matchMaxLen = matchMaxLen;
+
+		int cyclicBufferSize = historySize + 1;
+		if (_cyclicBufferSize != cyclicBufferSize)
+			_son = new int[(_cyclicBufferSize = cyclicBufferSize) * 2];
+
+		int hs = kBT2HashSize;
+
+		if (HASH_ARRAY)
+		{
+			hs = historySize - 1;
+			hs |= (hs >> 1);
+			hs |= (hs >> 2);
+			hs |= (hs >> 4);
+			hs |= (hs >> 8);
+			hs >>= 1;
+			hs |= 0xFFFF;
+			if (hs > (1 << 24))
+				hs >>= 1;
+			_hashMask = hs;
+			hs++;
+			hs += kFixHashSize;
+		}
+		if (hs != _hashSizeSum)
+			_hash = new int [_hashSizeSum = hs];
+		return true;
+	}
+	public int GetMatches(int[] distances) throws IOException
+	{
+		int lenLimit;
+		if (_pos + _matchMaxLen <= _streamPos)
+			lenLimit = _matchMaxLen;
+		else
+		{
+			lenLimit = _streamPos - _pos;
+			if (lenLimit < kMinMatchCheck)
+			{
+				MovePos();
+				return 0;
+			}
+		}
+
+		int offset = 0;
+		int matchMinPos = (_pos > _cyclicBufferSize) ? (_pos - _cyclicBufferSize) : 0;
+		int cur = _bufferOffset + _pos;
+		int maxLen = kStartMaxLen; // to avoid items for len < hashSize;
+		int hashValue, hash2Value = 0, hash3Value = 0;
+		
+		if (HASH_ARRAY)
+		{
+			int temp = CrcTable[_bufferBase[cur] & 0xFF] ^ (_bufferBase[cur + 1] & 0xFF);
+			hash2Value = temp & (kHash2Size - 1);
+			temp ^= ((int)(_bufferBase[cur + 2] & 0xFF) << 8);
+			hash3Value = temp & (kHash3Size - 1);
+			hashValue = (temp ^ (CrcTable[_bufferBase[cur + 3] & 0xFF] << 5)) & _hashMask;
+		}
+		else
+			hashValue = ((_bufferBase[cur] & 0xFF) ^ ((int)(_bufferBase[cur + 1] & 0xFF) << 8));
+
+		int curMatch = _hash[kFixHashSize + hashValue];
+		if (HASH_ARRAY)
+		{
+			int curMatch2 = _hash[hash2Value];
+			int curMatch3 = _hash[kHash3Offset + hash3Value];
+			_hash[hash2Value] = _pos;
+			_hash[kHash3Offset + hash3Value] = _pos;
+			if (curMatch2 > matchMinPos)
+				if (_bufferBase[_bufferOffset + curMatch2] == _bufferBase[cur])
+				{
+					distances[offset++] = maxLen = 2;
+					distances[offset++] = _pos - curMatch2 - 1;
+				}
+			if (curMatch3 > matchMinPos)
+				if (_bufferBase[_bufferOffset + curMatch3] == _bufferBase[cur])
+				{
+					if (curMatch3 == curMatch2)
+						offset -= 2;
+					distances[offset++] = maxLen = 3;
+					distances[offset++] = _pos - curMatch3 - 1;
+					curMatch2 = curMatch3;
+				}
+			if (offset != 0 && curMatch2 == curMatch)
+			{
+				offset -= 2;
+				maxLen = kStartMaxLen;
+			}
+		}
+
+		_hash[kFixHashSize + hashValue] = _pos;
+
+		int ptr0 = (_cyclicBufferPos << 1) + 1;
+		int ptr1 = (_cyclicBufferPos << 1);
+
+		int len0, len1;
+		len0 = len1 = kNumHashDirectBytes;
+
+		if (kNumHashDirectBytes != 0)
+		{
+			if (curMatch > matchMinPos)
+			{
+				if (_bufferBase[_bufferOffset + curMatch + kNumHashDirectBytes] !=
+						_bufferBase[cur + kNumHashDirectBytes])
+				{
+					distances[offset++] = maxLen = kNumHashDirectBytes;
+					distances[offset++] = _pos - curMatch - 1;
+				}
+			}
+		}
+
+		int count = _cutValue;
+
+		while (true)
+		{
+			if (curMatch <= matchMinPos || count-- == 0)
+			{
+				_son[ptr0] = _son[ptr1] = kEmptyHashValue;
+				break;
+			}
+			int delta = _pos - curMatch;
+			int cyclicPos = ((delta <= _cyclicBufferPos) ?
+				(_cyclicBufferPos - delta) :
+				(_cyclicBufferPos - delta + _cyclicBufferSize)) << 1;
+
+			int pby1 = _bufferOffset + curMatch;
+			int len = Math.min(len0, len1);
+			if (_bufferBase[pby1 + len] == _bufferBase[cur + len])
+			{
+				while(++len != lenLimit)
+					if (_bufferBase[pby1 + len] != _bufferBase[cur + len])
+						break;
+				if (maxLen < len)
+				{
+					distances[offset++] = maxLen = len;
+					distances[offset++] = delta - 1;
+					if (len == lenLimit)
+					{
+						_son[ptr1] = _son[cyclicPos];
+						_son[ptr0] = _son[cyclicPos + 1];
+						break;
+					}
+				}
+			}
+			if ((_bufferBase[pby1 + len] & 0xFF) < (_bufferBase[cur + len] & 0xFF))
+			{
+				_son[ptr1] = curMatch;
+				ptr1 = cyclicPos + 1;
+				curMatch = _son[ptr1];
+				len1 = len;
+			}
+			else
+			{
+				_son[ptr0] = curMatch;
+				ptr0 = cyclicPos;
+				curMatch = _son[ptr0];
+				len0 = len;
+			}
+		}
+		MovePos();
+		return offset;
+	}
+
+	public void Skip(int num) throws IOException
+	{
+		do
+		{
+			int lenLimit;
+			if (_pos + _matchMaxLen <= _streamPos)
+			lenLimit = _matchMaxLen;
+			else
+			{
+				lenLimit = _streamPos - _pos;
+				if (lenLimit < kMinMatchCheck)
+				{
+					MovePos();
+					continue;
+				}
+			}
+
+			int matchMinPos = (_pos > _cyclicBufferSize) ? (_pos - _cyclicBufferSize) : 0;
+			int cur = _bufferOffset + _pos;
+			
+			int hashValue;
+
+			if (HASH_ARRAY)
+			{
+				int temp = CrcTable[_bufferBase[cur] & 0xFF] ^ (_bufferBase[cur + 1] & 0xFF);
+				int hash2Value = temp & (kHash2Size - 1);
+				_hash[hash2Value] = _pos;
+				temp ^= ((int)(_bufferBase[cur + 2] & 0xFF) << 8);
+				int hash3Value = temp & (kHash3Size - 1);
+				_hash[kHash3Offset + hash3Value] = _pos;
+				hashValue = (temp ^ (CrcTable[_bufferBase[cur + 3] & 0xFF] << 5)) & _hashMask;
+			}
+			else
+				hashValue = ((_bufferBase[cur] & 0xFF) ^ ((int)(_bufferBase[cur + 1] & 0xFF) << 8));
+
+			int curMatch = _hash[kFixHashSize + hashValue];
+			_hash[kFixHashSize + hashValue] = _pos;
+
+			int ptr0 = (_cyclicBufferPos << 1) + 1;
+			int ptr1 = (_cyclicBufferPos << 1);
+
+			int len0, len1;
+			len0 = len1 = kNumHashDirectBytes;
+
+			int count = _cutValue;
+			while (true)
+			{
+				if (curMatch <= matchMinPos || count-- == 0)
+				{
+					_son[ptr0] = _son[ptr1] = kEmptyHashValue;
+					break;
+				}
+
+				int delta = _pos - curMatch;
+				int cyclicPos = ((delta <= _cyclicBufferPos) ?
+					(_cyclicBufferPos - delta) :
+					(_cyclicBufferPos - delta + _cyclicBufferSize)) << 1;
+
+				int pby1 = _bufferOffset + curMatch;
+				int len = Math.min(len0, len1);
+				if (_bufferBase[pby1 + len] == _bufferBase[cur + len])
+				{
+					while (++len != lenLimit)
+						if (_bufferBase[pby1 + len] != _bufferBase[cur + len])
+							break;
+					if (len == lenLimit)
+					{
+						_son[ptr1] = _son[cyclicPos];
+						_son[ptr0] = _son[cyclicPos + 1];
+						break;
+					}
+				}
+				if ((_bufferBase[pby1 + len] & 0xFF) < (_bufferBase[cur + len] & 0xFF))
+				{
+					_son[ptr1] = curMatch;
+					ptr1 = cyclicPos + 1;
+					curMatch = _son[ptr1];
+					len1 = len;
+				}
+				else
+				{
+					_son[ptr0] = curMatch;
+					ptr0 = cyclicPos;
+					curMatch = _son[ptr0];
+					len0 = len;
+				}
+			}
+			MovePos();
+		}
+		while (--num != 0);
+	}
+	
+	void NormalizeLinks(int[] items, int numItems, int subValue)
+	{
+		for (int i = 0; i < numItems; i++)
+		{
+			int value = items[i];
+			if (value <= subValue)
+				value = kEmptyHashValue;
+			else
+				value -= subValue;
+			items[i] = value;
+		}
+	}
+	
+	void Normalize()
+	{
+		int subValue = _pos - _cyclicBufferSize;
+		NormalizeLinks(_son, _cyclicBufferSize * 2, subValue);
+		NormalizeLinks(_hash, _hashSizeSum, subValue);
+		ReduceOffsets(subValue);
+	}
+	
+	public void SetCutValue(int cutValue) { _cutValue = cutValue; }
+
+	private static final int[] CrcTable = new int[256];
+
+	static
+	{
+		for (int i = 0; i < 256; i++)
+		{
+			int r = i;
+			for (int j = 0; j < 8; j++)
+				if ((r & 1) != 0)
+					r = (r >>> 1) ^ 0xEDB88320;
+				else
+					r >>>= 1;
+			CrcTable[i] = r;
+		}
+	}
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/misc/libphysfs/lzma/Java/SevenZip/Compression/LZ/InWindow.java	Mon Apr 10 12:06:43 2017 -0400
@@ -0,0 +1,131 @@
+// LZ.InWindow
+
+package SevenZip.Compression.LZ;
+
+import java.io.IOException;
+
+public class InWindow
+{
+	public byte[] _bufferBase; // pointer to buffer with data
+	java.io.InputStream _stream;
+	int _posLimit;  // offset (from _buffer) of first byte when new block reading must be done
+	boolean _streamEndWasReached; // if (true) then _streamPos shows real end of stream
+	
+	int _pointerToLastSafePosition;
+	
+	public int _bufferOffset;
+	
+	public int _blockSize;  // Size of Allocated memory block
+	public int _pos;             // offset (from _buffer) of curent byte
+	int _keepSizeBefore;  // how many BYTEs must be kept in buffer before _pos
+	int _keepSizeAfter;   // how many BYTEs must be kept buffer after _pos
+	public int _streamPos;   // offset (from _buffer) of first not read byte from Stream
+	
+	public void MoveBlock()
+	{
+		int offset = _bufferOffset + _pos - _keepSizeBefore;
+		// we need one additional byte, since MovePos moves on 1 byte.
+		if (offset > 0)
+			offset--;
+
+		int numBytes = _bufferOffset + _streamPos - offset;
+		
+		// check negative offset ????
+		for (int i = 0; i < numBytes; i++)
+			_bufferBase[i] = _bufferBase[offset + i];
+		_bufferOffset -= offset;
+	}
+	
+	public void ReadBlock() throws IOException
+	{
+		if (_streamEndWasReached)
+			return;
+		while (true)
+		{
+			int size = (0 - _bufferOffset) + _blockSize - _streamPos;
+			if (size == 0)
+				return;
+			int numReadBytes = _stream.read(_bufferBase, _bufferOffset + _streamPos, size);
+			if (numReadBytes == -1)
+			{
+				_posLimit = _streamPos;
+				int pointerToPostion = _bufferOffset + _posLimit;
+				if (pointerToPostion > _pointerToLastSafePosition)
+					_posLimit = _pointerToLastSafePosition - _bufferOffset;
+				
+				_streamEndWasReached = true;
+				return;
+			}
+			_streamPos += numReadBytes;
+			if (_streamPos >= _pos + _keepSizeAfter)
+				_posLimit = _streamPos - _keepSizeAfter;
+		}
+	}
+	
+	void Free() { _bufferBase = null; }
+	
+	public void Create(int keepSizeBefore, int keepSizeAfter, int keepSizeReserv)
+	{
+		_keepSizeBefore = keepSizeBefore;
+		_keepSizeAfter = keepSizeAfter;
+		int blockSize = keepSizeBefore + keepSizeAfter + keepSizeReserv;
+		if (_bufferBase == null || _blockSize != blockSize)
+		{
+			Free();
+			_blockSize = blockSize;
+			_bufferBase = new byte[_blockSize];
+		}
+		_pointerToLastSafePosition = _blockSize - keepSizeAfter;
+	}
+	
+	public void SetStream(java.io.InputStream stream) { _stream = stream; 	}
+	public void ReleaseStream() { _stream = null; }
+
+	public void Init() throws IOException
+	{
+		_bufferOffset = 0;
+		_pos = 0;
+		_streamPos = 0;
+		_streamEndWasReached = false;
+		ReadBlock();
+	}
+	
+	public void MovePos() throws IOException
+	{
+		_pos++;
+		if (_pos > _posLimit)
+		{
+			int pointerToPostion = _bufferOffset + _pos;
+			if (pointerToPostion > _pointerToLastSafePosition)
+				MoveBlock();
+			ReadBlock();
+		}
+	}
+	
+	public byte GetIndexByte(int index)	{ return _bufferBase[_bufferOffset + _pos + index]; }
+	
+	// index + limit have not to exceed _keepSizeAfter;
+	public int GetMatchLen(int index, int distance, int limit)
+	{
+		if (_streamEndWasReached)
+			if ((_pos + index) + limit > _streamPos)
+				limit = _streamPos - (_pos + index);
+		distance++;
+		// Byte *pby = _buffer + (size_t)_pos + index;
+		int pby = _bufferOffset + _pos + index;
+		
+		int i;
+		for (i = 0; i < limit && _bufferBase[pby + i] == _bufferBase[pby + i - distance]; i++);
+		return i;
+	}
+	
+	public int GetNumAvailableBytes()	{ return _streamPos - _pos; }
+	
+	public void ReduceOffsets(int subValue)
+	{
+		_bufferOffset += subValue;
+		_posLimit -= subValue;
+		_pos -= subValue;
+		_streamPos -= subValue;
+	}
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/misc/libphysfs/lzma/Java/SevenZip/Compression/LZ/OutWindow.java	Mon Apr 10 12:06:43 2017 -0400
@@ -0,0 +1,85 @@
+// LZ.OutWindow
+
+package SevenZip.Compression.LZ;
+
+import java.io.IOException;
+
+public class OutWindow
+{
+	byte[] _buffer;
+	int _pos;
+	int _windowSize = 0;
+	int _streamPos;
+	java.io.OutputStream _stream;
+	
+	public void Create(int windowSize)
+	{
+		if (_buffer == null || _windowSize != windowSize)
+			_buffer = new byte[windowSize];
+		_windowSize = windowSize;
+		_pos = 0;
+		_streamPos = 0;
+	}
+	
+	public void SetStream(java.io.OutputStream stream) throws IOException
+	{
+		ReleaseStream();
+		_stream = stream;
+	}
+	
+	public void ReleaseStream() throws IOException
+	{
+		Flush();
+		_stream = null;
+	}
+	
+	public void Init(boolean solid)
+	{
+		if (!solid)
+		{
+			_streamPos = 0;
+			_pos = 0;
+		}
+	}
+	
+	public void Flush() throws IOException
+	{
+		int size = _pos - _streamPos;
+		if (size == 0)
+			return;
+		_stream.write(_buffer, _streamPos, size);
+		if (_pos >= _windowSize)
+			_pos = 0;
+		_streamPos = _pos;
+	}
+	
+	public void CopyBlock(int distance, int len) throws IOException
+	{
+		int pos = _pos - distance - 1;
+		if (pos < 0)
+			pos += _windowSize;
+		for (; len != 0; len--)
+		{
+			if (pos >= _windowSize)
+				pos = 0;
+			_buffer[_pos++] = _buffer[pos++];
+			if (_pos >= _windowSize)
+				Flush();
+		}
+	}
+	
+	public void PutByte(byte b) throws IOException
+	{
+		_buffer[_pos++] = b;
+		if (_pos >= _windowSize)
+			Flush();
+	}
+	
+	public byte GetByte(int distance)
+	{
+		int pos = _pos - distance - 1;
+		if (pos < 0)
+			pos += _windowSize;
+		return _buffer[pos];
+	}
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/misc/libphysfs/lzma/Java/SevenZip/Compression/LZMA/Base.java	Mon Apr 10 12:06:43 2017 -0400
@@ -0,0 +1,88 @@
+// Base.java
+
+package SevenZip.Compression.LZMA;
+
+public class Base
+{
+	public static final int kNumRepDistances = 4;
+	public static final int kNumStates = 12;
+	
+	public static final int StateInit()
+	{
+		return 0;
+	}
+	
+	public static final int StateUpdateChar(int index)
+	{
+		if (index < 4) 
+			return 0;
+		if (index < 10) 
+			return index - 3;
+		return index - 6;
+	}
+	
+	public static final int StateUpdateMatch(int index)
+	{
+		return (index < 7 ? 7 : 10); 
+	}
+
+	public static final int StateUpdateRep(int index)
+	{ 
+		return (index < 7 ? 8 : 11); 
+	}
+	
+	public static final int StateUpdateShortRep(int index)
+	{ 
+		return (index < 7 ? 9 : 11); 
+	}
+
+	public static final boolean StateIsCharState(int index)
+	{ 
+		return index < 7; 
+	}
+	
+	public static final int kNumPosSlotBits = 6;
+	public static final int kDicLogSizeMin = 0;
+	// public static final int kDicLogSizeMax = 28;
+	// public static final int kDistTableSizeMax = kDicLogSizeMax * 2;
+	
+	public static final int kNumLenToPosStatesBits = 2; // it's for speed optimization
+	public static final int kNumLenToPosStates = 1 << kNumLenToPosStatesBits;
+	
+	public static final int kMatchMinLen = 2;
+	
+	public static final int GetLenToPosState(int len)
+	{
+		len -= kMatchMinLen;
+		if (len < kNumLenToPosStates)
+			return len;
+		return (int)(kNumLenToPosStates - 1);
+	}
+	
+	public static final int kNumAlignBits = 4;
+	public static final int kAlignTableSize = 1 << kNumAlignBits;
+	public static final int kAlignMask = (kAlignTableSize - 1);
+	
+	public static final int kStartPosModelIndex = 4;
+	public static final int kEndPosModelIndex = 14;
+	public static final int kNumPosModels = kEndPosModelIndex - kStartPosModelIndex;
+	
+	public static final  int kNumFullDistances = 1 << (kEndPosModelIndex / 2);
+	
+	public static final  int kNumLitPosStatesBitsEncodingMax = 4;
+	public static final  int kNumLitContextBitsMax = 8;
+	
+	public static final  int kNumPosStatesBitsMax = 4;
+	public static final  int kNumPosStatesMax = (1 << kNumPosStatesBitsMax);
+	public static final  int kNumPosStatesBitsEncodingMax = 4;
+	public static final  int kNumPosStatesEncodingMax = (1 << kNumPosStatesBitsEncodingMax);
+	
+	public static final  int kNumLowLenBits = 3;
+	public static final  int kNumMidLenBits = 3;
+	public static final  int kNumHighLenBits = 8;
+	public static final  int kNumLowLenSymbols = 1 << kNumLowLenBits;
+	public static final  int kNumMidLenSymbols = 1 << kNumMidLenBits;
+	public static final  int kNumLenSymbols = kNumLowLenSymbols + kNumMidLenSymbols +
+			(1 << kNumHighLenBits);
+	public static final  int kMatchMaxLen = kMatchMinLen + kNumLenSymbols - 1;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/misc/libphysfs/lzma/Java/SevenZip/Compression/LZMA/Decoder.java	Mon Apr 10 12:06:43 2017 -0400
@@ -0,0 +1,329 @@
+package SevenZip.Compression.LZMA;
+
+import SevenZip.Compression.RangeCoder.BitTreeDecoder;
+import SevenZip.Compression.LZMA.Base;
+import SevenZip.Compression.LZ.OutWindow;
+import java.io.IOException;
+
+public class Decoder
+{
+	class LenDecoder
+	{
+		short[] m_Choice = new short[2];
+		BitTreeDecoder[] m_LowCoder = new BitTreeDecoder[Base.kNumPosStatesMax];
+		BitTreeDecoder[] m_MidCoder = new BitTreeDecoder[Base.kNumPosStatesMax];
+		BitTreeDecoder m_HighCoder = new BitTreeDecoder(Base.kNumHighLenBits);
+		int m_NumPosStates = 0;
+		
+		public void Create(int numPosStates)
+		{
+			for (; m_NumPosStates < numPosStates; m_NumPosStates++)
+			{
+				m_LowCoder[m_NumPosStates] = new BitTreeDecoder(Base.kNumLowLenBits);
+				m_MidCoder[m_NumPosStates] = new BitTreeDecoder(Base.kNumMidLenBits);
+			}
+		}
+		
+		public void Init()
+		{
+			SevenZip.Compression.RangeCoder.Decoder.InitBitModels(m_Choice);
+			for (int posState = 0; posState < m_NumPosStates; posState++)
+			{
+				m_LowCoder[posState].Init();
+				m_MidCoder[posState].Init();
+			}
+			m_HighCoder.Init();
+		}
+		
+		public int Decode(SevenZip.Compression.RangeCoder.Decoder rangeDecoder, int posState) throws IOException
+		{
+			if (rangeDecoder.DecodeBit(m_Choice, 0) == 0)
+				return m_LowCoder[posState].Decode(rangeDecoder);
+			int symbol = Base.kNumLowLenSymbols;
+			if (rangeDecoder.DecodeBit(m_Choice, 1) == 0)
+				symbol += m_MidCoder[posState].Decode(rangeDecoder);
+			else
+				symbol += Base.kNumMidLenSymbols + m_HighCoder.Decode(rangeDecoder);
+			return symbol;
+		}
+	}
+	
+	class LiteralDecoder
+	{
+		class Decoder2
+		{
+			short[] m_Decoders = new short[0x300];
+			
+			public void Init()
+			{
+				SevenZip.Compression.RangeCoder.Decoder.InitBitModels(m_Decoders);
+			}
+			
+			public byte DecodeNormal(SevenZip.Compression.RangeCoder.Decoder rangeDecoder) throws IOException
+			{
+				int symbol = 1;
+				do
+					symbol = (symbol << 1) | rangeDecoder.DecodeBit(m_Decoders, symbol);
+				while (symbol < 0x100);
+				return (byte)symbol;
+			}
+			
+			public byte DecodeWithMatchByte(SevenZip.Compression.RangeCoder.Decoder rangeDecoder, byte matchByte) throws IOException
+			{
+				int symbol = 1;
+				do
+				{
+					int matchBit = (matchByte >> 7) & 1;
+					matchByte <<= 1;
+					int bit = rangeDecoder.DecodeBit(m_Decoders, ((1 + matchBit) << 8) + symbol);
+					symbol = (symbol << 1) | bit;
+					if (matchBit != bit)
+					{
+						while (symbol < 0x100)
+							symbol = (symbol << 1) | rangeDecoder.DecodeBit(m_Decoders, symbol);
+						break;
+					}
+				}
+				while (symbol < 0x100);
+				return (byte)symbol;
+			}
+		}
+		
+		Decoder2[] m_Coders;
+		int m_NumPrevBits;
+		int m_NumPosBits;
+		int m_PosMask;
+		
+		public void Create(int numPosBits, int numPrevBits)
+		{
+			if (m_Coders != null && m_NumPrevBits == numPrevBits && m_NumPosBits == numPosBits)
+				return;
+			m_NumPosBits = numPosBits;
+			m_PosMask = (1 << numPosBits) - 1;
+			m_NumPrevBits = numPrevBits;
+			int numStates = 1 << (m_NumPrevBits + m_NumPosBits);
+			m_Coders = new Decoder2[numStates];
+			for (int i = 0; i < numStates; i++)
+				m_Coders[i] = new Decoder2();
+		}
+		
+		public void Init()
+		{
+			int numStates = 1 << (m_NumPrevBits + m_NumPosBits);
+			for (int i = 0; i < numStates; i++)
+				m_Coders[i].Init();
+		}
+		
+		Decoder2 GetDecoder(int pos, byte prevByte)
+		{
+			return m_Coders[((pos & m_PosMask) << m_NumPrevBits) + ((prevByte & 0xFF) >>> (8 - m_NumPrevBits))];
+		}
+	}
+	
+	OutWindow m_OutWindow = new OutWindow();
+	SevenZip.Compression.RangeCoder.Decoder m_RangeDecoder = new SevenZip.Compression.RangeCoder.Decoder();
+	
+	short[] m_IsMatchDecoders = new short[Base.kNumStates << Base.kNumPosStatesBitsMax];
+	short[] m_IsRepDecoders = new short[Base.kNumStates];
+	short[] m_IsRepG0Decoders = new short[Base.kNumStates];
+	short[] m_IsRepG1Decoders = new short[Base.kNumStates];
+	short[] m_IsRepG2Decoders = new short[Base.kNumStates];
+	short[] m_IsRep0LongDecoders = new short[Base.kNumStates << Base.kNumPosStatesBitsMax];
+	
+	BitTreeDecoder[] m_PosSlotDecoder = new BitTreeDecoder[Base.kNumLenToPosStates];
+	short[] m_PosDecoders = new short[Base.kNumFullDistances - Base.kEndPosModelIndex];
+	
+	BitTreeDecoder m_PosAlignDecoder = new BitTreeDecoder(Base.kNumAlignBits);
+	
+	LenDecoder m_LenDecoder = new LenDecoder();
+	LenDecoder m_RepLenDecoder = new LenDecoder();
+	
+	LiteralDecoder m_LiteralDecoder = new LiteralDecoder();
+	
+	int m_DictionarySize = -1;
+	int m_DictionarySizeCheck =  -1;
+	
+	int m_PosStateMask;
+	
+	public Decoder()
+	{
+		for (int i = 0; i < Base.kNumLenToPosStates; i++)
+			m_PosSlotDecoder[i] = new BitTreeDecoder(Base.kNumPosSlotBits);
+	}
+	
+	boolean SetDictionarySize(int dictionarySize)
+	{
+		if (dictionarySize < 0)
+			return false;
+		if (m_DictionarySize != dictionarySize)
+		{
+			m_DictionarySize = dictionarySize;
+			m_DictionarySizeCheck = Math.max(m_DictionarySize, 1);
+			m_OutWindow.Create(Math.max(m_DictionarySizeCheck, (1 << 12)));
+		}
+		return true;
+	}
+	
+	boolean SetLcLpPb(int lc, int lp, int pb)
+	{
+		if (lc > Base.kNumLitContextBitsMax || lp > 4 || pb > Base.kNumPosStatesBitsMax)
+			return false;
+		m_LiteralDecoder.Create(lp, lc);
+		int numPosStates = 1 << pb;
+		m_LenDecoder.Create(numPosStates);
+		m_RepLenDecoder.Create(numPosStates);
+		m_PosStateMask = numPosStates - 1;
+		return true;
+	}
+	
+	void Init() throws IOException
+	{
+		m_OutWindow.Init(false);
+		
+		SevenZip.Compression.RangeCoder.Decoder.InitBitModels(m_IsMatchDecoders);
+		SevenZip.Compression.RangeCoder.Decoder.InitBitModels(m_IsRep0LongDecoders);
+		SevenZip.Compression.RangeCoder.Decoder.InitBitModels(m_IsRepDecoders);
+		SevenZip.Compression.RangeCoder.Decoder.InitBitModels(m_IsRepG0Decoders);
+		SevenZip.Compression.RangeCoder.Decoder.InitBitModels(m_IsRepG1Decoders);
+		SevenZip.Compression.RangeCoder.Decoder.InitBitModels(m_IsRepG2Decoders);
+		SevenZip.Compression.RangeCoder.Decoder.InitBitModels(m_PosDecoders);
+		
+		m_LiteralDecoder.Init();
+		int i;
+		for (i = 0; i < Base.kNumLenToPosStates; i++)
+			m_PosSlotDecoder[i].Init();
+		m_LenDecoder.Init();
+		m_RepLenDecoder.Init();
+		m_PosAlignDecoder.Init();
+		m_RangeDecoder.Init();
+	}
+	
+	public boolean Code(java.io.InputStream inStream, java.io.OutputStream outStream,
+			long outSize) throws IOException
+	{
+		m_RangeDecoder.SetStream(inStream);
+		m_OutWindow.SetStream(outStream);
+		Init();
+		
+		int state = Base.StateInit();
+		int rep0 = 0, rep1 = 0, rep2 = 0, rep3 = 0;
+		
+		long nowPos64 = 0;
+		byte prevByte = 0;
+		while (outSize < 0 || nowPos64 < outSize)
+		{
+			int posState = (int)nowPos64 & m_PosStateMask;
+			if (m_RangeDecoder.DecodeBit(m_IsMatchDecoders, (state << Base.kNumPosStatesBitsMax) + posState) == 0)
+			{
+				LiteralDecoder.Decoder2 decoder2 = m_LiteralDecoder.GetDecoder((int)nowPos64, prevByte);
+				if (!Base.StateIsCharState(state))
+					prevByte = decoder2.DecodeWithMatchByte(m_RangeDecoder, m_OutWindow.GetByte(rep0));
+				else
+					prevByte = decoder2.DecodeNormal(m_RangeDecoder);
+				m_OutWindow.PutByte(prevByte);
+				state = Base.StateUpdateChar(state);
+				nowPos64++;
+			}
+			else
+			{
+				int len;
+				if (m_RangeDecoder.DecodeBit(m_IsRepDecoders, state) == 1)
+				{
+					len = 0;
+					if (m_RangeDecoder.DecodeBit(m_IsRepG0Decoders, state) == 0)
+					{
+						if (m_RangeDecoder.DecodeBit(m_IsRep0LongDecoders, (state << Base.kNumPosStatesBitsMax) + posState) == 0)
+						{
+							state = Base.StateUpdateShortRep(state);
+							len = 1;
+						}
+					}
+					else
+					{
+						int distance;
+						if (m_RangeDecoder.DecodeBit(m_IsRepG1Decoders, state) == 0)
+							distance = rep1;
+						else
+						{
+							if (m_RangeDecoder.DecodeBit(m_IsRepG2Decoders, state) == 0)
+								distance = rep2;
+							else
+							{
+								distance = rep3;
+								rep3 = rep2;
+							}
+							rep2 = rep1;
+						}
+						rep1 = rep0;
+						rep0 = distance;
+					}
+					if (len == 0)
+					{
+						len = m_RepLenDecoder.Decode(m_RangeDecoder, posState) + Base.kMatchMinLen;
+						state = Base.StateUpdateRep(state);
+					}
+				}
+				else
+				{
+					rep3 = rep2;
+					rep2 = rep1;
+					rep1 = rep0;
+					len = Base.kMatchMinLen + m_LenDecoder.Decode(m_RangeDecoder, posState);
+					state = Base.StateUpdateMatch(state);
+					int posSlot = m_PosSlotDecoder[Base.GetLenToPosState(len)].Decode(m_RangeDecoder);
+					if (posSlot >= Base.kStartPosModelIndex)
+					{
+						int numDirectBits = (posSlot >> 1) - 1;
+						rep0 = ((2 | (posSlot & 1)) << numDirectBits);
+						if (posSlot < Base.kEndPosModelIndex)
+							rep0 += BitTreeDecoder.ReverseDecode(m_PosDecoders,
+									rep0 - posSlot - 1, m_RangeDecoder, numDirectBits);
+						else
+						{
+							rep0 += (m_RangeDecoder.DecodeDirectBits(
+									numDirectBits - Base.kNumAlignBits) << Base.kNumAlignBits);
+							rep0 += m_PosAlignDecoder.ReverseDecode(m_RangeDecoder);
+							if (rep0 < 0)
+							{
+								if (rep0 == -1)
+									break;
+								return false;
+							}
+						}
+					}
+					else
+						rep0 = posSlot;
+				}
+				if (rep0 >= nowPos64 || rep0 >= m_DictionarySizeCheck)
+				{
+					// m_OutWindow.Flush();
+					return false;
+				}
+				m_OutWindow.CopyBlock(rep0, len);
+				nowPos64 += len;
+				prevByte = m_OutWindow.GetByte(0);
+			}
+		}
+		m_OutWindow.Flush();
+		m_OutWindow.ReleaseStream();
+		m_RangeDecoder.ReleaseStream();
+		return true;
+	}
+	
+	public boolean SetDecoderProperties(byte[] properties)
+	{
+		if (properties.length < 5)
+			return false;
+		int val = properties[0] & 0xFF;
+		int lc = val % 9;
+		int remainder = val / 9;
+		int lp = remainder % 5;
+		int pb = remainder / 5;
+		int dictionarySize = 0;
+		for (int i = 0; i < 4; i++)
+			dictionarySize += ((int)(properties[1 + i]) & 0xFF) << (i * 8);
+		if (!SetLcLpPb(lc, lp, pb))
+			return false;
+		return SetDictionarySize(dictionarySize);
+	}
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/misc/libphysfs/lzma/Java/SevenZip/Compression/LZMA/Encoder.java	Mon Apr 10 12:06:43 2017 -0400
@@ -0,0 +1,1416 @@
+package SevenZip.Compression.LZMA;
+
+import SevenZip.Compression.RangeCoder.BitTreeEncoder;
+import SevenZip.Compression.LZMA.Base;
+import SevenZip.Compression.LZ.BinTree;
+import SevenZip.ICodeProgress;
+import java.io.IOException;
+
+public class Encoder
+{
+	public static final int EMatchFinderTypeBT2 = 0;
+	public static final int EMatchFinderTypeBT4 = 1;
+
+
+
+
+	static final int kIfinityPrice = 0xFFFFFFF;
+
+	static byte[] g_FastPos = new byte[1 << 11];
+
+	static
+	{
+		int kFastSlots = 22;
+		int c = 2;
+		g_FastPos[0] = 0;
+		g_FastPos[1] = 1;
+		for (int slotFast = 2; slotFast < kFastSlots; slotFast++)
+		{
+			int k = (1 << ((slotFast >> 1) - 1));
+			for (int j = 0; j < k; j++, c++)
+				g_FastPos[c] = (byte)slotFast;
+		}
+	}
+
+	static int GetPosSlot(int pos)
+	{
+		if (pos < (1 << 11))
+			return g_FastPos[pos];
+		if (pos < (1 << 21))
+			return (g_FastPos[pos >> 10] + 20);
+		return (g_FastPos[pos >> 20] + 40);
+	}
+
+	static int GetPosSlot2(int pos)
+	{
+		if (pos < (1 << 17))
+			return (g_FastPos[pos >> 6] + 12);
+		if (pos < (1 << 27))
+			return (g_FastPos[pos >> 16] + 32);
+		return (g_FastPos[pos >> 26] + 52);
+	}
+
+	int _state = Base.StateInit();
+	byte _previousByte;
+	int[] _repDistances = new int[Base.kNumRepDistances];
+
+	void BaseInit()
+	{
+		_state = Base.StateInit();
+		_previousByte = 0;
+		for (int i = 0; i < Base.kNumRepDistances; i++)
+			_repDistances[i] = 0;
+	}
+
+	static final int kDefaultDictionaryLogSize = 22;
+	static final int kNumFastBytesDefault = 0x20;
+
+	class LiteralEncoder
+	{
+		class Encoder2
+		{
+			short[] m_Encoders = new short[0x300];
+
+			public void Init() { SevenZip.Compression.RangeCoder.Encoder.InitBitModels(m_Encoders); }
+
+
+
+			public void Encode(SevenZip.Compression.RangeCoder.Encoder rangeEncoder, byte symbol) throws IOException
+			{
+				int context = 1;
+				for (int i = 7; i >= 0; i--)
+				{
+					int bit = ((symbol >> i) & 1);
+					rangeEncoder.Encode(m_Encoders, context, bit);
+					context = (context << 1) | bit;
+				}
+			}
+
+			public void EncodeMatched(SevenZip.Compression.RangeCoder.Encoder rangeEncoder, byte matchByte, byte symbol) throws IOException
+			{
+				int context = 1;
+				boolean same = true;
+				for (int i = 7; i >= 0; i--)
+				{
+					int bit = ((symbol >> i) & 1);
+					int state = context;
+					if (same)
+					{
+						int matchBit = ((matchByte >> i) & 1);
+						state += ((1 + matchBit) << 8);
+						same = (matchBit == bit);
+					}
+					rangeEncoder.Encode(m_Encoders, state, bit);
+					context = (context << 1) | bit;
+				}
+			}
+
+			public int GetPrice(boolean matchMode, byte matchByte, byte symbol)
+			{
+				int price = 0;
+				int context = 1;
+				int i = 7;
+				if (matchMode)
+				{
+					for (; i >= 0; i--)
+					{
+						int matchBit = (matchByte >> i) & 1;
+						int bit = (symbol >> i) & 1;
+						price += SevenZip.Compression.RangeCoder.Encoder.GetPrice(m_Encoders[((1 + matchBit) << 8) + context], bit);
+						context = (context << 1) | bit;
+						if (matchBit != bit)
+						{
+							i--;
+							break;
+						}
+					}
+				}
+				for (; i >= 0; i--)
+				{
+					int bit = (symbol >> i) & 1;
+					price += SevenZip.Compression.RangeCoder.Encoder.GetPrice(m_Encoders[context], bit);
+					context = (context << 1) | bit;
+				}
+				return price;
+			}
+		}
+
+		Encoder2[] m_Coders;
+		int m_NumPrevBits;
+		int m_NumPosBits;
+		int m_PosMask;
+
+		public void Create(int numPosBits, int numPrevBits)
+		{
+			if (m_Coders != null && m_NumPrevBits == numPrevBits && m_NumPosBits == numPosBits)
+				return;
+			m_NumPosBits = numPosBits;
+			m_PosMask = (1 << numPosBits) - 1;
+			m_NumPrevBits = numPrevBits;
+			int numStates = 1 << (m_NumPrevBits + m_NumPosBits);
+			m_Coders = new Encoder2[numStates];
+			for (int i = 0; i < numStates; i++)
+				m_Coders[i] = new Encoder2();
+		}
+
+		public void Init()
+		{
+			int numStates = 1 << (m_NumPrevBits + m_NumPosBits);
+			for (int i = 0; i < numStates; i++)
+				m_Coders[i].Init();
+		}
+
+		public Encoder2 GetSubCoder(int pos, byte prevByte)
+		{ return m_Coders[((pos & m_PosMask) << m_NumPrevBits) + ((prevByte & 0xFF) >>> (8 - m_NumPrevBits))]; }
+	}
+
+	class LenEncoder
+	{
+		short[] _choice = new short[2];
+		BitTreeEncoder[] _lowCoder = new BitTreeEncoder[Base.kNumPosStatesEncodingMax];
+		BitTreeEncoder[] _midCoder = new BitTreeEncoder[Base.kNumPosStatesEncodingMax];
+		BitTreeEncoder _highCoder = new BitTreeEncoder(Base.kNumHighLenBits);
+
+
+		public LenEncoder()
+		{
+			for (int posState = 0; posState < Base.kNumPosStatesEncodingMax; posState++)
+			{
+				_lowCoder[posState] = new BitTreeEncoder(Base.kNumLowLenBits);
+				_midCoder[posState] = new BitTreeEncoder(Base.kNumMidLenBits);
+			}
+		}
+
+		public void Init(int numPosStates)
+		{
+			SevenZip.Compression.RangeCoder.Encoder.InitBitModels(_choice);
+
+			for (int posState = 0; posState < numPosStates; posState++)
+			{
+				_lowCoder[posState].Init();
+				_midCoder[posState].Init();
+			}
+			_highCoder.Init();
+		}
+
+		public void Encode(SevenZip.Compression.RangeCoder.Encoder rangeEncoder, int symbol, int posState) throws IOException
+		{
+			if (symbol < Base.kNumLowLenSymbols)
+			{
+				rangeEncoder.Encode(_choice, 0, 0);
+				_lowCoder[posState].Encode(rangeEncoder, symbol);
+			}
+			else
+			{
+				symbol -= Base.kNumLowLenSymbols;
+				rangeEncoder.Encode(_choice, 0, 1);
+				if (symbol < Base.kNumMidLenSymbols)
+				{
+					rangeEncoder.Encode(_choice, 1, 0);
+					_midCoder[posState].Encode(rangeEncoder, symbol);
+				}
+				else
+				{
+					rangeEncoder.Encode(_choice, 1, 1);
+					_highCoder.Encode(rangeEncoder, symbol - Base.kNumMidLenSymbols);
+				}
+			}
+		}
+
+		public void SetPrices(int posState, int numSymbols, int[] prices, int st)
+		{
+			int a0 = SevenZip.Compression.RangeCoder.Encoder.GetPrice0(_choice[0]);
+			int a1 = SevenZip.Compression.RangeCoder.Encoder.GetPrice1(_choice[0]);
+			int b0 = a1 + SevenZip.Compression.RangeCoder.Encoder.GetPrice0(_choice[1]);
+			int b1 = a1 + SevenZip.Compression.RangeCoder.Encoder.GetPrice1(_choice[1]);
+			int i = 0;
+			for (i = 0; i < Base.kNumLowLenSymbols; i++)
+			{
+				if (i >= numSymbols)
+					return;
+				prices[st + i] = a0 + _lowCoder[posState].GetPrice(i);
+			}
+			for (; i < Base.kNumLowLenSymbols + Base.kNumMidLenSymbols; i++)
+			{
+				if (i >= numSymbols)
+					return;
+				prices[st + i] = b0 + _midCoder[posState].GetPrice(i - Base.kNumLowLenSymbols);
+			}
+			for (; i < numSymbols; i++)
+				prices[st + i] = b1 + _highCoder.GetPrice(i - Base.kNumLowLenSymbols - Base.kNumMidLenSymbols);
+		}
+	};
+
+	public static final int kNumLenSpecSymbols = Base.kNumLowLenSymbols + Base.kNumMidLenSymbols;
+
+	class LenPriceTableEncoder extends LenEncoder
+	{
+		int[] _prices = new int[Base.kNumLenSymbols<<Base.kNumPosStatesBitsEncodingMax];
+		int _tableSize;
+		int[] _counters = new int[Base.kNumPosStatesEncodingMax];
+
+		public void SetTableSize(int tableSize) { _tableSize = tableSize; }
+
+		public int GetPrice(int symbol, int posState)
+		{
+			return _prices[posState * Base.kNumLenSymbols + symbol];
+		}
+
+		void UpdateTable(int posState)
+		{
+			SetPrices(posState, _tableSize, _prices, posState * Base.kNumLenSymbols);
+			_counters[posState] = _tableSize;
+		}
+
+		public void UpdateTables(int numPosStates)
+		{
+			for (int posState = 0; posState < numPosStates; posState++)
+				UpdateTable(posState);
+		}
+
+		public void Encode(SevenZip.Compression.RangeCoder.Encoder rangeEncoder, int symbol, int posState) throws IOException
+		{
+			super.Encode(rangeEncoder, symbol, posState);
+			if (--_counters[posState] == 0)
+				UpdateTable(posState);
+		}
+	}
+
+	static final int kNumOpts = 1 << 12;
+	class Optimal
+	{
+		public int State;
+
+		public boolean Prev1IsChar;
+		public boolean Prev2;
+
+		public int PosPrev2;
+		public int BackPrev2;
+
+		public int Price;
+		public int PosPrev;
+		public int BackPrev;
+
+		public int Backs0;
+		public int Backs1;
+		public int Backs2;
+		public int Backs3;
+
+		public void MakeAsChar() { BackPrev = -1; Prev1IsChar = false; }
+		public void MakeAsShortRep() { BackPrev = 0; ; Prev1IsChar = false; }
+		public boolean IsShortRep() { return (BackPrev == 0); }
+	};
+	Optimal[] _optimum = new Optimal[kNumOpts];
+	SevenZip.Compression.LZ.BinTree _matchFinder = null;
+	SevenZip.Compression.RangeCoder.Encoder _rangeEncoder = new SevenZip.Compression.RangeCoder.Encoder();
+
+	short[] _isMatch = new short[Base.kNumStates<<Base.kNumPosStatesBitsMax];
+	short[] _isRep = new short[Base.kNumStates];
+	short[] _isRepG0 = new short[Base.kNumStates];
+	short[] _isRepG1 = new short[Base.kNumStates];
+	short[] _isRepG2 = new short[Base.kNumStates];
+	short[] _isRep0Long = new short[Base.kNumStates<<Base.kNumPosStatesBitsMax];
+
+	BitTreeEncoder[] _posSlotEncoder = new BitTreeEncoder[Base.kNumLenToPosStates]; // kNumPosSlotBits
+
+	short[] _posEncoders = new short[Base.kNumFullDistances-Base.kEndPosModelIndex];
+	BitTreeEncoder _posAlignEncoder = new BitTreeEncoder(Base.kNumAlignBits);
+
+	LenPriceTableEncoder _lenEncoder = new LenPriceTableEncoder();
+	LenPriceTableEncoder _repMatchLenEncoder = new LenPriceTableEncoder();
+
+	LiteralEncoder _literalEncoder = new LiteralEncoder();
+
+	int[] _matchDistances = new int[Base.kMatchMaxLen*2+2];
+
+	int _numFastBytes = kNumFastBytesDefault;
+	int _longestMatchLength;
+	int _numDistancePairs;
+
+	int _additionalOffset;
+
+	int _optimumEndIndex;
+	int _optimumCurrentIndex;
+
+	boolean _longestMatchWasFound;
+
+	int[] _posSlotPrices = new int[1<<(Base.kNumPosSlotBits+Base.kNumLenToPosStatesBits)];
+	int[] _distancesPrices = new int[Base.kNumFullDistances<<Base.kNumLenToPosStatesBits];
+	int[] _alignPrices = new int[Base.kAlignTableSize];
+	int _alignPriceCount;
+
+	int _distTableSize = (kDefaultDictionaryLogSize * 2);
+
+	int _posStateBits = 2;
+	int _posStateMask = (4 - 1);
+	int _numLiteralPosStateBits = 0;
+	int _numLiteralContextBits = 3;
+
+	int _dictionarySize = (1 << kDefaultDictionaryLogSize);
+	int _dictionarySizePrev = -1;
+	int _numFastBytesPrev = -1;
+
+	long nowPos64;
+	boolean _finished;
+	java.io.InputStream _inStream;
+
+	int _matchFinderType = EMatchFinderTypeBT4;
+	boolean _writeEndMark = false;
+
+	boolean _needReleaseMFStream = false;
+
+	void Create()
+	{
+		if (_matchFinder == null)
+		{
+			SevenZip.Compression.LZ.BinTree bt = new SevenZip.Compression.LZ.BinTree();
+			int numHashBytes = 4;
+			if (_matchFinderType == EMatchFinderTypeBT2)
+				numHashBytes = 2;
+			bt.SetType(numHashBytes);
+			_matchFinder = bt;
+		}
+		_literalEncoder.Create(_numLiteralPosStateBits, _numLiteralContextBits);
+
+		if (_dictionarySize == _dictionarySizePrev && _numFastBytesPrev == _numFastBytes)
+			return;
+		_matchFinder.Create(_dictionarySize, kNumOpts, _numFastBytes, Base.kMatchMaxLen + 1);
+		_dictionarySizePrev = _dictionarySize;
+		_numFastBytesPrev = _numFastBytes;
+	}
+
+	public Encoder()
+	{
+		for (int i = 0; i < kNumOpts; i++)
+			_optimum[i] = new Optimal();
+		for (int i = 0; i < Base.kNumLenToPosStates; i++)
+			_posSlotEncoder[i] = new BitTreeEncoder(Base.kNumPosSlotBits);
+	}
+
+	void SetWriteEndMarkerMode(boolean writeEndMarker)
+	{
+		_writeEndMark = writeEndMarker;
+	}
+
+	void Init()
+	{
+		BaseInit();
+		_rangeEncoder.Init();
+
+		SevenZip.Compression.RangeCoder.Encoder.InitBitModels(_isMatch);
+		SevenZip.Compression.RangeCoder.Encoder.InitBitModels(_isRep0Long);
+		SevenZip.Compression.RangeCoder.Encoder.InitBitModels(_isRep);
+		SevenZip.Compression.RangeCoder.Encoder.InitBitModels(_isRepG0);
+		SevenZip.Compression.RangeCoder.Encoder.InitBitModels(_isRepG1);
+		SevenZip.Compression.RangeCoder.Encoder.InitBitModels(_isRepG2);
+		SevenZip.Compression.RangeCoder.Encoder.InitBitModels(_posEncoders);
+
+
+
+
+
+
+
+		_literalEncoder.Init();
+		for (int i = 0; i < Base.kNumLenToPosStates; i++)
+			_posSlotEncoder[i].Init();
+
+
+
+		_lenEncoder.Init(1 << _posStateBits);
+		_repMatchLenEncoder.Init(1 << _posStateBits);
+
+		_posAlignEncoder.Init();
+
+		_longestMatchWasFound = false;
+		_optimumEndIndex = 0;
+		_optimumCurrentIndex = 0;
+		_additionalOffset = 0;
+	}
+
+	int ReadMatchDistances() throws java.io.IOException
+	{
+		int lenRes = 0;
+		_numDistancePairs = _matchFinder.GetMatches(_matchDistances);
+		if (_numDistancePairs > 0)
+		{
+			lenRes = _matchDistances[_numDistancePairs - 2];
+			if (lenRes == _numFastBytes)
+				lenRes += _matchFinder.GetMatchLen((int)lenRes - 1, _matchDistances[_numDistancePairs - 1],
+					Base.kMatchMaxLen - lenRes);
+		}
+		_additionalOffset++;
+		return lenRes;
+	}
+
+	void MovePos(int num) throws java.io.IOException
+	{
+		if (num > 0)
+		{
+			_matchFinder.Skip(num);
+			_additionalOffset += num;
+		}
+	}
+
+	int GetRepLen1Price(int state, int posState)
+	{
+		return SevenZip.Compression.RangeCoder.Encoder.GetPrice0(_isRepG0[state]) +
+				SevenZip.Compression.RangeCoder.Encoder.GetPrice0(_isRep0Long[(state << Base.kNumPosStatesBitsMax) + posState]);
+	}
+
+	int GetPureRepPrice(int repIndex, int state, int posState)
+	{
+		int price;
+		if (repIndex == 0)
+		{
+			price = SevenZip.Compression.RangeCoder.Encoder.GetPrice0(_isRepG0[state]);
+			price += SevenZip.Compression.RangeCoder.Encoder.GetPrice1(_isRep0Long[(state << Base.kNumPosStatesBitsMax) + posState]);
+		}
+		else
+		{
+			price = SevenZip.Compression.RangeCoder.Encoder.GetPrice1(_isRepG0[state]);
+			if (repIndex == 1)
+				price += SevenZip.Compression.RangeCoder.Encoder.GetPrice0(_isRepG1[state]);
+			else
+			{
+				price += SevenZip.Compression.RangeCoder.Encoder.GetPrice1(_isRepG1[state]);
+				price += SevenZip.Compression.RangeCoder.Encoder.GetPrice(_isRepG2[state], repIndex - 2);
+			}
+		}
+		return price;
+	}
+
+	int GetRepPrice(int repIndex, int len, int state, int posState)
+	{
+		int price = _repMatchLenEncoder.GetPrice(len - Base.kMatchMinLen, posState);
+		return price + GetPureRepPrice(repIndex, state, posState);
+	}
+
+	int GetPosLenPrice(int pos, int len, int posState)
+	{
+		int price;
+		int lenToPosState = Base.GetLenToPosState(len);
+		if (pos < Base.kNumFullDistances)
+			price = _distancesPrices[(lenToPosState * Base.kNumFullDistances) + pos];
+		else
+			price = _posSlotPrices[(lenToPosState << Base.kNumPosSlotBits) + GetPosSlot2(pos)] +
+				_alignPrices[pos & Base.kAlignMask];
+		return price + _lenEncoder.GetPrice(len - Base.kMatchMinLen, posState);
+	}
+
+	int Backward(int cur)
+	{
+		_optimumEndIndex = cur;
+		int posMem = _optimum[cur].PosPrev;
+		int backMem = _optimum[cur].BackPrev;
+		do
+		{
+			if (_optimum[cur].Prev1IsChar)
+			{
+				_optimum[posMem].MakeAsChar();
+				_optimum[posMem].PosPrev = posMem - 1;
+				if (_optimum[cur].Prev2)
+				{
+					_optimum[posMem - 1].Prev1IsChar = false;
+					_optimum[posMem - 1].PosPrev = _optimum[cur].PosPrev2;
+					_optimum[posMem - 1].BackPrev = _optimum[cur].BackPrev2;
+				}
+			}
+			int posPrev = posMem;
+			int backCur = backMem;
+
+			backMem = _optimum[posPrev].BackPrev;
+			posMem = _optimum[posPrev].PosPrev;
+
+			_optimum[posPrev].BackPrev = backCur;
+			_optimum[posPrev].PosPrev = cur;
+			cur = posPrev;
+		}
+		while (cur > 0);
+		backRes = _optimum[0].BackPrev;
+		_optimumCurrentIndex = _optimum[0].PosPrev;
+		return _optimumCurrentIndex;
+	}
+
+	int[] reps = new int[Base.kNumRepDistances];
+	int[] repLens = new int[Base.kNumRepDistances];
+	int backRes;
+
+	int GetOptimum(int position) throws IOException
+	{
+		if (_optimumEndIndex != _optimumCurrentIndex)
+		{
+			int lenRes = _optimum[_optimumCurrentIndex].PosPrev - _optimumCurrentIndex;
+			backRes = _optimum[_optimumCurrentIndex].BackPrev;
+			_optimumCurrentIndex = _optimum[_optimumCurrentIndex].PosPrev;
+			return lenRes;
+		}
+		_optimumCurrentIndex = _optimumEndIndex = 0;
+
+		int lenMain, numDistancePairs;
+		if (!_longestMatchWasFound)
+		{
+			lenMain = ReadMatchDistances();
+		}
+		else
+		{
+			lenMain = _longestMatchLength;
+			_longestMatchWasFound = false;
+		}
+		numDistancePairs = _numDistancePairs;
+
+		int numAvailableBytes = _matchFinder.GetNumAvailableBytes() + 1;
+		if (numAvailableBytes < 2)
+		{
+			backRes = -1;
+			return 1;
+		}
+		if (numAvailableBytes > Base.kMatchMaxLen)
+			numAvailableBytes = Base.kMatchMaxLen;
+
+		int repMaxIndex = 0;
+		int i;
+		for (i = 0; i < Base.kNumRepDistances; i++)
+		{
+			reps[i] = _repDistances[i];
+			repLens[i] = _matchFinder.GetMatchLen(0 - 1, reps[i], Base.kMatchMaxLen);
+			if (repLens[i] > repLens[repMaxIndex])
+				repMaxIndex = i;
+		}
+		if (repLens[repMaxIndex] >= _numFastBytes)
+		{
+			backRes = repMaxIndex;
+			int lenRes = repLens[repMaxIndex];
+			MovePos(lenRes - 1);
+			return lenRes;
+		}
+
+		if (lenMain >= _numFastBytes)
+		{
+			backRes = _matchDistances[numDistancePairs - 1] + Base.kNumRepDistances;
+			MovePos(lenMain - 1);
+			return lenMain;
+		}
+
+		byte currentByte = _matchFinder.GetIndexByte(0 - 1);
+		byte matchByte = _matchFinder.GetIndexByte(0 - _repDistances[0] - 1 - 1);
+
+		if (lenMain < 2 && currentByte != matchByte && repLens[repMaxIndex] < 2)
+		{
+			backRes = -1;
+			return 1;
+		}
+
+		_optimum[0].State = _state;
+
+		int posState = (position & _posStateMask);
+
+		_optimum[1].Price = SevenZip.Compression.RangeCoder.Encoder.GetPrice0(_isMatch[(_state << Base.kNumPosStatesBitsMax) + posState]) +
+				_literalEncoder.GetSubCoder(position, _previousByte).GetPrice(!Base.StateIsCharState(_state), matchByte, currentByte);
+		_optimum[1].MakeAsChar();
+
+		int matchPrice = SevenZip.Compression.RangeCoder.Encoder.GetPrice1(_isMatch[(_state << Base.kNumPosStatesBitsMax) + posState]);
+		int repMatchPrice = matchPrice + SevenZip.Compression.RangeCoder.Encoder.GetPrice1(_isRep[_state]);
+
+		if (matchByte == currentByte)
+		{
+			int shortRepPrice = repMatchPrice + GetRepLen1Price(_state, posState);
+			if (shortRepPrice < _optimum[1].Price)
+			{
+				_optimum[1].Price = shortRepPrice;
+				_optimum[1].MakeAsShortRep();
+			}
+		}
+
+		int lenEnd = ((lenMain >= repLens[repMaxIndex]) ? lenMain : repLens[repMaxIndex]);
+
+		if (lenEnd < 2)
+		{
+			backRes = _optimum[1].BackPrev;
+			return 1;
+		}
+
+		_optimum[1].PosPrev = 0;
+
+		_optimum[0].Backs0 = reps[0];
+		_optimum[0].Backs1 = reps[1];
+		_optimum[0].Backs2 = reps[2];
+		_optimum[0].Backs3 = reps[3];
+
+		int len = lenEnd;
+		do
+			_optimum[len--].Price = kIfinityPrice;
+		while (len >= 2);
+
+		for (i = 0; i < Base.kNumRepDistances; i++)
+		{
+			int repLen = repLens[i];
+			if (repLen < 2)
+				continue;
+			int price = repMatchPrice + GetPureRepPrice(i, _state, posState);
+			do
+			{
+				int curAndLenPrice = price + _repMatchLenEncoder.GetPrice(repLen - 2, posState);
+				Optimal optimum = _optimum[repLen];
+				if (curAndLenPrice < optimum.Price)
+				{
+					optimum.Price = curAndLenPrice;
+					optimum.PosPrev = 0;
+					optimum.BackPrev = i;
+					optimum.Prev1IsChar = false;
+				}
+			}
+			while (--repLen >= 2);
+		}
+
+		int normalMatchPrice = matchPrice + SevenZip.Compression.RangeCoder.Encoder.GetPrice0(_isRep[_state]);
+
+		len = ((repLens[0] >= 2) ? repLens[0] + 1 : 2);
+		if (len <= lenMain)
+		{
+			int offs = 0;
+			while (len > _matchDistances[offs])
+				offs += 2;
+			for (; ; len++)
+			{
+				int distance = _matchDistances[offs + 1];
+				int curAndLenPrice = normalMatchPrice + GetPosLenPrice(distance, len, posState);
+				Optimal optimum = _optimum[len];
+				if (curAndLenPrice < optimum.Price)
+				{
+					optimum.Price = curAndLenPrice;
+					optimum.PosPrev = 0;
+					optimum.BackPrev = distance + Base.kNumRepDistances;
+					optimum.Prev1IsChar = false;
+				}
+				if (len == _matchDistances[offs])
+				{
+					offs += 2;
+					if (offs == numDistancePairs)
+						break;
+				}
+			}
+		}
+
+		int cur = 0;
+
+		while (true)
+		{
+			cur++;
+			if (cur == lenEnd)
+				return Backward(cur);
+			int newLen = ReadMatchDistances();
+			numDistancePairs = _numDistancePairs;
+			if (newLen >= _numFastBytes)
+			{
+
+				_longestMatchLength = newLen;
+				_longestMatchWasFound = true;
+				return Backward(cur);
+			}
+			position++;
+			int posPrev = _optimum[cur].PosPrev;
+			int state;
+			if (_optimum[cur].Prev1IsChar)
+			{
+				posPrev--;
+				if (_optimum[cur].Prev2)
+				{
+					state = _optimum[_optimum[cur].PosPrev2].State;
+					if (_optimum[cur].BackPrev2 < Base.kNumRepDistances)
+						state = Base.StateUpdateRep(state);
+					else
+						state = Base.StateUpdateMatch(state);
+				}
+				else
+					state = _optimum[posPrev].State;
+				state = Base.StateUpdateChar(state);
+			}
+			else
+				state = _optimum[posPrev].State;
+			if (posPrev == cur - 1)
+			{
+				if (_optimum[cur].IsShortRep())
+					state = Base.StateUpdateShortRep(state);
+				else
+					state = Base.StateUpdateChar(state);
+			}
+			else
+			{
+				int pos;
+				if (_optimum[cur].Prev1IsChar && _optimum[cur].Prev2)
+				{
+					posPrev = _optimum[cur].PosPrev2;
+					pos = _optimum[cur].BackPrev2;
+					state = Base.StateUpdateRep(state);
+				}
+				else
+				{
+					pos = _optimum[cur].BackPrev;
+					if (pos < Base.kNumRepDistances)
+						state = Base.StateUpdateRep(state);
+					else
+						state = Base.StateUpdateMatch(state);
+				}
+				Optimal opt = _optimum[posPrev];
+				if (pos < Base.kNumRepDistances)
+				{
+					if (pos == 0)
+					{
+						reps[0] = opt.Backs0;
+						reps[1] = opt.Backs1;
+						reps[2] = opt.Backs2;
+						reps[3] = opt.Backs3;
+					}
+					else if (pos == 1)
+					{
+						reps[0] = opt.Backs1;
+						reps[1] = opt.Backs0;
+						reps[2] = opt.Backs2;
+						reps[3] = opt.Backs3;
+					}
+					else if (pos == 2)
+					{
+						reps[0] = opt.Backs2;
+						reps[1] = opt.Backs0;
+						reps[2] = opt.Backs1;
+						reps[3] = opt.Backs3;
+					}
+					else
+					{
+						reps[0] = opt.Backs3;
+						reps[1] = opt.Backs0;
+						reps[2] = opt.Backs1;
+						reps[3] = opt.Backs2;
+					}
+				}
+				else
+				{
+					reps[0] = (pos - Base.kNumRepDistances);
+					reps[1] = opt.Backs0;
+					reps[2] = opt.Backs1;
+					reps[3] = opt.Backs2;
+				}
+			}
+			_optimum[cur].State = state;
+			_optimum[cur].Backs0 = reps[0];
+			_optimum[cur].Backs1 = reps[1];
+			_optimum[cur].Backs2 = reps[2];
+			_optimum[cur].Backs3 = reps[3];
+			int curPrice = _optimum[cur].Price;
+
+			currentByte = _matchFinder.GetIndexByte(0 - 1);
+			matchByte = _matchFinder.GetIndexByte(0 - reps[0] - 1 - 1);
+
+			posState = (position & _posStateMask);
+
+			int curAnd1Price = curPrice +
+				SevenZip.Compression.RangeCoder.Encoder.GetPrice0(_isMatch[(state << Base.kNumPosStatesBitsMax) + posState]) +
+				_literalEncoder.GetSubCoder(position, _matchFinder.GetIndexByte(0 - 2)).
+				GetPrice(!Base.StateIsCharState(state), matchByte, currentByte);
+
+			Optimal nextOptimum = _optimum[cur + 1];
+
+			boolean nextIsChar = false;
+			if (curAnd1Price < nextOptimum.Price)
+			{
+				nextOptimum.Price = curAnd1Price;
+				nextOptimum.PosPrev = cur;
+				nextOptimum.MakeAsChar();
+				nextIsChar = true;
+			}
+
+			matchPrice = curPrice + SevenZip.Compression.RangeCoder.Encoder.GetPrice1(_isMatch[(state << Base.kNumPosStatesBitsMax) + posState]);
+			repMatchPrice = matchPrice + SevenZip.Compression.RangeCoder.Encoder.GetPrice1(_isRep[state]);
+
+			if (matchByte == currentByte &&
+				!(nextOptimum.PosPrev < cur && nextOptimum.BackPrev == 0))
+			{
+				int shortRepPrice = repMatchPrice + GetRepLen1Price(state, posState);
+				if (shortRepPrice <= nextOptimum.Price)
+				{
+					nextOptimum.Price = shortRepPrice;
+					nextOptimum.PosPrev = cur;
+					nextOptimum.MakeAsShortRep();
+					nextIsChar = true;
+				}
+			}
+
+			int numAvailableBytesFull = _matchFinder.GetNumAvailableBytes() + 1;
+			numAvailableBytesFull = Math.min(kNumOpts - 1 - cur, numAvailableBytesFull);
+			numAvailableBytes = numAvailableBytesFull;
+
+			if (numAvailableBytes < 2)
+				continue;
+			if (numAvailableBytes > _numFastBytes)
+				numAvailableBytes = _numFastBytes;
+			if (!nextIsChar && matchByte != currentByte)
+			{
+				// try Literal + rep0
+				int t = Math.min(numAvailableBytesFull - 1, _numFastBytes);
+				int lenTest2 = _matchFinder.GetMatchLen(0, reps[0], t);
+				if (lenTest2 >= 2)
+				{
+					int state2 = Base.StateUpdateChar(state);
+
+					int posStateNext = (position + 1) & _posStateMask;
+					int nextRepMatchPrice = curAnd1Price +
+						SevenZip.Compression.RangeCoder.Encoder.GetPrice1(_isMatch[(state2 << Base.kNumPosStatesBitsMax) + posStateNext]) +
+						SevenZip.Compression.RangeCoder.Encoder.GetPrice1(_isRep[state2]);
+					{
+						int offset = cur + 1 + lenTest2;
+						while (lenEnd < offset)
+							_optimum[++lenEnd].Price = kIfinityPrice;
+						int curAndLenPrice = nextRepMatchPrice + GetRepPrice(
+								0, lenTest2, state2, posStateNext);
+						Optimal optimum = _optimum[offset];
+						if (curAndLenPrice < optimum.Price)
+						{
+							optimum.Price = curAndLenPrice;
+							optimum.PosPrev = cur + 1;
+							optimum.BackPrev = 0;
+							optimum.Prev1IsChar = true;
+							optimum.Prev2 = false;
+						}
+					}
+				}
+			}
+
+			int startLen = 2; // speed optimization 
+
+			for (int repIndex = 0; repIndex < Base.kNumRepDistances; repIndex++)
+			{
+				int lenTest = _matchFinder.GetMatchLen(0 - 1, reps[repIndex], numAvailableBytes);
+				if (lenTest < 2)
+					continue;
+				int lenTestTemp = lenTest;
+				do
+				{
+					while (lenEnd < cur + lenTest)
+						_optimum[++lenEnd].Price = kIfinityPrice;
+					int curAndLenPrice = repMatchPrice + GetRepPrice(repIndex, lenTest, state, posState);
+					Optimal optimum = _optimum[cur + lenTest];
+					if (curAndLenPrice < optimum.Price)
+					{
+						optimum.Price = curAndLenPrice;
+						optimum.PosPrev = cur;
+						optimum.BackPrev = repIndex;
+						optimum.Prev1IsChar = false;
+					}
+				}
+				while (--lenTest >= 2);
+				lenTest = lenTestTemp;
+
+				if (repIndex == 0)
+					startLen = lenTest + 1;
+
+				// if (_maxMode)
+				if (lenTest < numAvailableBytesFull)
+				{
+					int t = Math.min(numAvailableBytesFull - 1 - lenTest, _numFastBytes);
+					int lenTest2 = _matchFinder.GetMatchLen(lenTest, reps[repIndex], t);
+					if (lenTest2 >= 2)
+					{
+						int state2 = Base.StateUpdateRep(state);
+
+						int posStateNext = (position + lenTest) & _posStateMask;
+						int curAndLenCharPrice =
+								repMatchPrice + GetRepPrice(repIndex, lenTest, state, posState) +
+								SevenZip.Compression.RangeCoder.Encoder.GetPrice0(_isMatch[(state2 << Base.kNumPosStatesBitsMax) + posStateNext]) +
+								_literalEncoder.GetSubCoder(position + lenTest,
+								_matchFinder.GetIndexByte(lenTest - 1 - 1)).GetPrice(true,
+								_matchFinder.GetIndexByte(lenTest - 1 - (reps[repIndex] + 1)),
+								_matchFinder.GetIndexByte(lenTest - 1));
+						state2 = Base.StateUpdateChar(state2);
+						posStateNext = (position + lenTest + 1) & _posStateMask;
+						int nextMatchPrice = curAndLenCharPrice + SevenZip.Compression.RangeCoder.Encoder.GetPrice1(_isMatch[(state2 << Base.kNumPosStatesBitsMax) + posStateNext]);
+						int nextRepMatchPrice = nextMatchPrice + SevenZip.Compression.RangeCoder.Encoder.GetPrice1(_isRep[state2]);
+
+						// for(; lenTest2 >= 2; lenTest2--)
+						{
+							int offset = lenTest + 1 + lenTest2;
+							while (lenEnd < cur + offset)
+								_optimum[++lenEnd].Price = kIfinityPrice;
+							int curAndLenPrice = nextRepMatchPrice + GetRepPrice(0, lenTest2, state2, posStateNext);
+							Optimal optimum = _optimum[cur + offset];
+							if (curAndLenPrice < optimum.Price)
+							{
+								optimum.Price = curAndLenPrice;
+								optimum.PosPrev = cur + lenTest + 1;
+								optimum.BackPrev = 0;
+								optimum.Prev1IsChar = true;
+								optimum.Prev2 = true;
+								optimum.PosPrev2 = cur;
+								optimum.BackPrev2 = repIndex;
+							}
+						}
+					}
+				}
+			}
+
+			if (newLen > numAvailableBytes)
+			{
+				newLen = numAvailableBytes;
+				for (numDistancePairs = 0; newLen > _matchDistances[numDistancePairs]; numDistancePairs += 2) ;
+				_matchDistances[numDistancePairs] = newLen;
+				numDistancePairs += 2;
+			}
+			if (newLen >= startLen)
+			{
+				normalMatchPrice = matchPrice + SevenZip.Compression.RangeCoder.Encoder.GetPrice0(_isRep[state]);
+				while (lenEnd < cur + newLen)
+					_optimum[++lenEnd].Price = kIfinityPrice;
+
+				int offs = 0;
+				while (startLen > _matchDistances[offs])
+					offs += 2;
+
+				for (int lenTest = startLen; ; lenTest++)
+				{
+					int curBack = _matchDistances[offs + 1];
+					int curAndLenPrice = normalMatchPrice + GetPosLenPrice(curBack, lenTest, posState);
+					Optimal optimum = _optimum[cur + lenTest];
+					if (curAndLenPrice < optimum.Price)
+					{
+						optimum.Price = curAndLenPrice;
+						optimum.PosPrev = cur;
+						optimum.BackPrev = curBack + Base.kNumRepDistances;
+						optimum.Prev1IsChar = false;
+					}
+
+					if (lenTest == _matchDistances[offs])
+					{
+						if (lenTest < numAvailableBytesFull)
+						{
+							int t = Math.min(numAvailableBytesFull - 1 - lenTest, _numFastBytes);
+							int lenTest2 = _matchFinder.GetMatchLen(lenTest, curBack, t);
+							if (lenTest2 >= 2)
+							{
+								int state2 = Base.StateUpdateMatch(state);
+
+								int posStateNext = (position + lenTest) & _posStateMask;
+								int curAndLenCharPrice = curAndLenPrice +
+									SevenZip.Compression.RangeCoder.Encoder.GetPrice0(_isMatch[(state2 << Base.kNumPosStatesBitsMax) + posStateNext]) +
+									_literalEncoder.GetSubCoder(position + lenTest,
+									_matchFinder.GetIndexByte(lenTest - 1 - 1)).
+									GetPrice(true,
+									_matchFinder.GetIndexByte(lenTest - (curBack + 1) - 1),
+									_matchFinder.GetIndexByte(lenTest - 1));
+								state2 = Base.StateUpdateChar(state2);
+								posStateNext = (position + lenTest + 1) & _posStateMask;
+								int nextMatchPrice = curAndLenCharPrice + SevenZip.Compression.RangeCoder.Encoder.GetPrice1(_isMatch[(state2 << Base.kNumPosStatesBitsMax) + posStateNext]);
+								int nextRepMatchPrice = nextMatchPrice + SevenZip.Compression.RangeCoder.Encoder.GetPrice1(_isRep[state2]);
+
+								int offset = lenTest + 1 + lenTest2;
+								while (lenEnd < cur + offset)
+									_optimum[++lenEnd].Price = kIfinityPrice;
+								curAndLenPrice = nextRepMatchPrice + GetRepPrice(0, lenTest2, state2, posStateNext);
+								optimum = _optimum[cur + offset];
+								if (curAndLenPrice < optimum.Price)
+								{
+									optimum.Price = curAndLenPrice;
+									optimum.PosPrev = cur + lenTest + 1;
+									optimum.BackPrev = 0;
+									optimum.Prev1IsChar = true;
+									optimum.Prev2 = true;
+									optimum.PosPrev2 = cur;
+									optimum.BackPrev2 = curBack + Base.kNumRepDistances;
+								}
+							}
+						}
+						offs += 2;
+						if (offs == numDistancePairs)
+							break;
+					}
+				}
+			}
+		}
+	}
+
+	boolean ChangePair(int smallDist, int bigDist)
+	{
+		int kDif = 7;
+		return (smallDist < (1 << (32 - kDif)) && bigDist >= (smallDist << kDif));
+	}
+
+	void WriteEndMarker(int posState) throws IOException
+	{
+		if (!_writeEndMark)
+			return;
+
+		_rangeEncoder.Encode(_isMatch, (_state << Base.kNumPosStatesBitsMax) + posState, 1);
+		_rangeEncoder.Encode(_isRep, _state, 0);
+		_state = Base.StateUpdateMatch(_state);
+		int len = Base.kMatchMinLen;
+		_lenEncoder.Encode(_rangeEncoder, len - Base.kMatchMinLen, posState);
+		int posSlot = (1 << Base.kNumPosSlotBits) - 1;
+		int lenToPosState = Base.GetLenToPosState(len);
+		_posSlotEncoder[lenToPosState].Encode(_rangeEncoder, posSlot);
+		int footerBits = 30;
+		int posReduced = (1 << footerBits) - 1;
+		_rangeEncoder.EncodeDirectBits(posReduced >> Base.kNumAlignBits, footerBits - Base.kNumAlignBits);
+		_posAlignEncoder.ReverseEncode(_rangeEncoder, posReduced & Base.kAlignMask);
+	}
+
+	void Flush(int nowPos) throws IOException
+	{
+		ReleaseMFStream();
+		WriteEndMarker(nowPos & _posStateMask);
+		_rangeEncoder.FlushData();
+		_rangeEncoder.FlushStream();
+	}
+
+	public void CodeOneBlock(long[] inSize, long[] outSize, boolean[] finished) throws IOException
+	{
+		inSize[0] = 0;
+		outSize[0] = 0;
+		finished[0] = true;
+
+		if (_inStream != null)
+		{
+			_matchFinder.SetStream(_inStream);
+			_matchFinder.Init();
+			_needReleaseMFStream = true;
+			_inStream = null;
+		}
+
+		if (_finished)
+			return;
+		_finished = true;
+
+
+		long progressPosValuePrev = nowPos64;
+		if (nowPos64 == 0)
+		{
+			if (_matchFinder.GetNumAvailableBytes() == 0)
+			{
+				Flush((int)nowPos64);
+				return;
+			}
+
+			ReadMatchDistances();
+			int posState = (int)(nowPos64) & _posStateMask;
+			_rangeEncoder.Encode(_isMatch, (_state << Base.kNumPosStatesBitsMax) + posState, 0);
+			_state = Base.StateUpdateChar(_state);
+			byte curByte = _matchFinder.GetIndexByte(0 - _additionalOffset);
+			_literalEncoder.GetSubCoder((int)(nowPos64), _previousByte).Encode(_rangeEncoder, curByte);
+			_previousByte = curByte;
+			_additionalOffset--;
+			nowPos64++;
+		}
+		if (_matchFinder.GetNumAvailableBytes() == 0)
+		{
+			Flush((int)nowPos64);
+			return;
+		}
+		while (true)
+		{
+
+			int len = GetOptimum((int)nowPos64);
+			int pos = backRes;
+			int posState = ((int)nowPos64) & _posStateMask;
+			int complexState = (_state << Base.kNumPosStatesBitsMax) + posState;
+			if (len == 1 && pos == -1)
+			{
+				_rangeEncoder.Encode(_isMatch, complexState, 0);
+				byte curByte = _matchFinder.GetIndexByte((int)(0 - _additionalOffset));
+				LiteralEncoder.Encoder2 subCoder = _literalEncoder.GetSubCoder((int)nowPos64, _previousByte);
+				if (!Base.StateIsCharState(_state))
+				{
+					byte matchByte = _matchFinder.GetIndexByte((int)(0 - _repDistances[0] - 1 - _additionalOffset));
+					subCoder.EncodeMatched(_rangeEncoder, matchByte, curByte);
+				}
+				else
+					subCoder.Encode(_rangeEncoder, curByte);
+				_previousByte = curByte;
+				_state = Base.StateUpdateChar(_state);
+			}
+			else
+			{
+				_rangeEncoder.Encode(_isMatch, complexState, 1);
+				if (pos < Base.kNumRepDistances)
+				{
+					_rangeEncoder.Encode(_isRep, _state, 1);
+					if (pos == 0)
+					{
+						_rangeEncoder.Encode(_isRepG0, _state, 0);
+						if (len == 1)
+							_rangeEncoder.Encode(_isRep0Long, complexState, 0);
+						else
+							_rangeEncoder.Encode(_isRep0Long, complexState, 1);
+					}
+					else
+					{
+						_rangeEncoder.Encode(_isRepG0, _state, 1);
+						if (pos == 1)
+							_rangeEncoder.Encode(_isRepG1, _state, 0);
+						else
+						{
+							_rangeEncoder.Encode(_isRepG1, _state, 1);
+							_rangeEncoder.Encode(_isRepG2, _state, pos - 2);
+						}
+					}
+					if (len == 1)
+						_state = Base.StateUpdateShortRep(_state);
+					else
+					{
+						_repMatchLenEncoder.Encode(_rangeEncoder, len - Base.kMatchMinLen, posState);
+						_state = Base.StateUpdateRep(_state);
+					}
+					int distance = _repDistances[pos];
+					if (pos != 0)
+					{
+						for (int i = pos; i >= 1; i--)
+							_repDistances[i] = _repDistances[i - 1];
+						_repDistances[0] = distance;
+					}
+				}
+				else
+				{
+					_rangeEncoder.Encode(_isRep, _state, 0);
+					_state = Base.StateUpdateMatch(_state);
+					_lenEncoder.Encode(_rangeEncoder, len - Base.kMatchMinLen, posState);
+					pos -= Base.kNumRepDistances;
+					int posSlot = GetPosSlot(pos);
+					int lenToPosState = Base.GetLenToPosState(len);
+					_posSlotEncoder[lenToPosState].Encode(_rangeEncoder, posSlot);
+
+					if (posSlot >= Base.kStartPosModelIndex)
+					{
+						int footerBits = (int)((posSlot >> 1) - 1);
+						int baseVal = ((2 | (posSlot & 1)) << footerBits);
+						int posReduced = pos - baseVal;
+
+						if (posSlot < Base.kEndPosModelIndex)
+							BitTreeEncoder.ReverseEncode(_posEncoders,
+									baseVal - posSlot - 1, _rangeEncoder, footerBits, posReduced);
+						else
+						{
+							_rangeEncoder.EncodeDirectBits(posReduced >> Base.kNumAlignBits, footerBits - Base.kNumAlignBits);
+							_posAlignEncoder.ReverseEncode(_rangeEncoder, posReduced & Base.kAlignMask);
+							_alignPriceCount++;
+						}
+					}
+					int distance = pos;
+					for (int i = Base.kNumRepDistances - 1; i >= 1; i--)
+						_repDistances[i] = _repDistances[i - 1];
+					_repDistances[0] = distance;
+					_matchPriceCount++;
+				}
+				_previousByte = _matchFinder.GetIndexByte(len - 1 - _additionalOffset);
+			}
+			_additionalOffset -= len;
+			nowPos64 += len;
+			if (_additionalOffset == 0)
+			{
+				// if (!_fastMode)
+				if (_matchPriceCount >= (1 << 7))
+					FillDistancesPrices();
+				if (_alignPriceCount >= Base.kAlignTableSize)
+					FillAlignPrices();
+				inSize[0] = nowPos64;
+				outSize[0] = _rangeEncoder.GetProcessedSizeAdd();
+				if (_matchFinder.GetNumAvailableBytes() == 0)
+				{
+					Flush((int)nowPos64);
+					return;
+				}
+
+				if (nowPos64 - progressPosValuePrev >= (1 << 12))
+				{
+					_finished = false;
+					finished[0] = false;
+					return;
+				}
+			}
+		}
+	}
+
+	void ReleaseMFStream()
+	{
+		if (_matchFinder != null && _needReleaseMFStream)
+		{
+			_matchFinder.ReleaseStream();
+			_needReleaseMFStream = false;
+		}
+	}
+
+	void SetOutStream(java.io.OutputStream outStream)
+	{ _rangeEncoder.SetStream(outStream); }
+	void ReleaseOutStream()
+	{ _rangeEncoder.ReleaseStream(); }
+
+	void ReleaseStreams()
+	{
+		ReleaseMFStream();
+		ReleaseOutStream();
+	}
+
+	void SetStreams(java.io.InputStream inStream, java.io.OutputStream outStream,
+			long inSize, long outSize)
+	{
+		_inStream = inStream;
+		_finished = false;
+		Create();
+		SetOutStream(outStream);
+		Init();
+
+		// if (!_fastMode)
+		{
+			FillDistancesPrices();
+			FillAlignPrices();
+		}
+
+		_lenEncoder.SetTableSize(_numFastBytes + 1 - Base.kMatchMinLen);
+		_lenEncoder.UpdateTables(1 << _posStateBits);
+		_repMatchLenEncoder.SetTableSize(_numFastBytes + 1 - Base.kMatchMinLen);
+		_repMatchLenEncoder.UpdateTables(1 << _posStateBits);
+
+		nowPos64 = 0;
+	}
+
+	long[] processedInSize = new long[1]; long[] processedOutSize = new long[1]; boolean[] finished = new boolean[1];
+	public void Code(java.io.InputStream inStream, java.io.OutputStream outStream,
+			long inSize, long outSize, ICodeProgress progress) throws IOException
+	{
+		_needReleaseMFStream = false;
+		try
+		{
+			SetStreams(inStream, outStream, inSize, outSize);
+			while (true)
+			{
+
+
+
+				CodeOneBlock(processedInSize, processedOutSize, finished);
+				if (finished[0])
+					return;
+				if (progress != null)
+				{
+					progress.SetProgress(processedInSize[0], processedOutSize[0]);
+				}
+			}
+		}
+		finally
+		{
+			ReleaseStreams();
+		}
+	}
+
+	public static final int kPropSize = 5;
+	byte[] properties = new byte[kPropSize];
+
+	public void WriteCoderProperties(java.io.OutputStream outStream) throws IOException
+	{
+		properties[0] = (byte)((_posStateBits * 5 + _numLiteralPosStateBits) * 9 + _numLiteralContextBits);
+		for (int i = 0; i < 4; i++)
+			properties[1 + i] = (byte)(_dictionarySize >> (8 * i));
+		outStream.write(properties, 0, kPropSize);
+	}
+
+	int[] tempPrices = new int[Base.kNumFullDistances];
+	int _matchPriceCount;
+
+	void FillDistancesPrices()
+	{
+		for (int i = Base.kStartPosModelIndex; i < Base.kNumFullDistances; i++)
+		{
+			int posSlot = GetPosSlot(i);
+			int footerBits = (int)((posSlot >> 1) - 1);
+			int baseVal = ((2 | (posSlot & 1)) << footerBits);
+			tempPrices[i] = BitTreeEncoder.ReverseGetPrice(_posEncoders,
+				baseVal - posSlot - 1, footerBits, i - baseVal);
+		}
+
+		for (int lenToPosState = 0; lenToPosState < Base.kNumLenToPosStates; lenToPosState++)
+		{
+			int posSlot;
+			BitTreeEncoder encoder = _posSlotEncoder[lenToPosState];
+
+			int st = (lenToPosState << Base.kNumPosSlotBits);
+			for (posSlot = 0; posSlot < _distTableSize; posSlot++)
+				_posSlotPrices[st + posSlot] = encoder.GetPrice(posSlot);
+			for (posSlot = Base.kEndPosModelIndex; posSlot < _distTableSize; posSlot++)
+				_posSlotPrices[st + posSlot] += ((((posSlot >> 1) - 1) - Base.kNumAlignBits) << SevenZip.Compression.RangeCoder.Encoder.kNumBitPriceShiftBits);
+
+			int st2 = lenToPosState * Base.kNumFullDistances;
+			int i;
+			for (i = 0; i < Base.kStartPosModelIndex; i++)
+				_distancesPrices[st2 + i] = _posSlotPrices[st + i];
+			for (; i < Base.kNumFullDistances; i++)
+				_distancesPrices[st2 + i] = _posSlotPrices[st + GetPosSlot(i)] + tempPrices[i];
+		}
+		_matchPriceCount = 0;
+	}
+
+	void FillAlignPrices()
+	{
+		for (int i = 0; i < Base.kAlignTableSize; i++)
+			_alignPrices[i] = _posAlignEncoder.ReverseGetPrice(i);
+		_alignPriceCount = 0;
+	}
+
+
+	public boolean SetAlgorithm(int algorithm)
+	{
+		/*
+		_fastMode = (algorithm == 0);
+		_maxMode = (algorithm >= 2);
+		*/
+		return true;
+	}
+
+	public boolean SetDictionarySize(int dictionarySize)
+	{
+		int kDicLogSizeMaxCompress = 29;
+		if (dictionarySize < (1 << Base.kDicLogSizeMin) || dictionarySize > (1 << kDicLogSizeMaxCompress))
+			return false;
+		_dictionarySize = dictionarySize;
+		int dicLogSize;
+		for (dicLogSize = 0; dictionarySize > (1 << dicLogSize); dicLogSize++) ;
+		_distTableSize = dicLogSize * 2;
+		return true;
+	}
+
+	public boolean SeNumFastBytes(int numFastBytes)
+	{
+		if (numFastBytes < 5 || numFastBytes > Base.kMatchMaxLen)
+			return false;
+		_numFastBytes = numFastBytes;
+		return true;
+	}
+
+	public boolean SetMatchFinder(int matchFinderIndex)
+	{
+		if (matchFinderIndex < 0 || matchFinderIndex > 2)
+			return false;
+		int matchFinderIndexPrev = _matchFinderType;
+		_matchFinderType = matchFinderIndex;
+		if (_matchFinder != null && matchFinderIndexPrev != _matchFinderType)
+		{
+			_dictionarySizePrev = -1;
+			_matchFinder = null;
+		}
+		return true;
+	}
+
+	public boolean SetLcLpPb(int lc, int lp, int pb)
+	{
+		if (
+				lp < 0 || lp > Base.kNumLitPosStatesBitsEncodingMax ||
+				lc < 0 || lc > Base.kNumLitContextBitsMax ||
+				pb < 0 || pb > Base.kNumPosStatesBitsEncodingMax)
+			return false;
+		_numLiteralPosStateBits = lp;
+		_numLiteralContextBits = lc;
+		_posStateBits = pb;
+		_posStateMask = ((1) << _posStateBits) - 1;
+		return true;
+	}
+
+	public void SetEndMarkerMode(boolean endMarkerMode)
+	{
+		_writeEndMark = endMarkerMode;
+	}
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/misc/libphysfs/lzma/Java/SevenZip/Compression/RangeCoder/BitTreeDecoder.java	Mon Apr 10 12:06:43 2017 -0400
@@ -0,0 +1,55 @@
+package SevenZip.Compression.RangeCoder;
+
+public class BitTreeDecoder
+{
+	short[] Models;
+	int NumBitLevels;
+	
+	public BitTreeDecoder(int numBitLevels)
+	{
+		NumBitLevels = numBitLevels;
+		Models = new short[1 << numBitLevels];
+	}
+	
+	public void Init()
+	{
+		Decoder.InitBitModels(Models);
+	}
+	
+	public int Decode(Decoder rangeDecoder) throws java.io.IOException
+	{
+		int m = 1;
+		for (int bitIndex = NumBitLevels; bitIndex != 0; bitIndex--)
+			m = (m << 1) + rangeDecoder.DecodeBit(Models, m);
+		return m - (1 << NumBitLevels);
+	}
+	
+	public int ReverseDecode(Decoder rangeDecoder) throws java.io.IOException
+	{
+		int m = 1;
+		int symbol = 0;
+		for (int bitIndex = 0; bitIndex < NumBitLevels; bitIndex++)
+		{
+			int bit = rangeDecoder.DecodeBit(Models, m);
+			m <<= 1;
+			m += bit;
+			symbol |= (bit << bitIndex);
+		}
+		return symbol;
+	}
+	
+	public static int ReverseDecode(short[] Models, int startIndex,
+			Decoder rangeDecoder, int NumBitLevels) throws java.io.IOException
+	{
+		int m = 1;
+		int symbol = 0;
+		for (int bitIndex = 0; bitIndex < NumBitLevels; bitIndex++)
+		{
+			int bit = rangeDecoder.DecodeBit(Models, startIndex + m);
+			m <<= 1;
+			m += bit;
+			symbol |= (bit << bitIndex);
+		}
+		return symbol;
+	}
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/misc/libphysfs/lzma/Java/SevenZip/Compression/RangeCoder/BitTreeEncoder.java	Mon Apr 10 12:06:43 2017 -0400
@@ -0,0 +1,99 @@
+package SevenZip.Compression.RangeCoder;
+import java.io.IOException;
+
+public class BitTreeEncoder
+{
+	short[] Models;
+	int NumBitLevels;
+	
+	public BitTreeEncoder(int numBitLevels)
+	{
+		NumBitLevels = numBitLevels;
+		Models = new short[1 << numBitLevels];
+	}
+	
+	public void Init()
+	{
+		Decoder.InitBitModels(Models);
+	}
+	
+	public void Encode(Encoder rangeEncoder, int symbol) throws IOException
+	{
+		int m = 1;
+		for (int bitIndex = NumBitLevels; bitIndex != 0; )
+		{
+			bitIndex--;
+			int bit = (symbol >>> bitIndex) & 1;
+			rangeEncoder.Encode(Models, m, bit);
+			m = (m << 1) | bit;
+		}
+	}
+	
+	public void ReverseEncode(Encoder rangeEncoder, int symbol) throws IOException
+	{
+		int m = 1;
+		for (int  i = 0; i < NumBitLevels; i++)
+		{
+			int bit = symbol & 1;
+			rangeEncoder.Encode(Models, m, bit);
+			m = (m << 1) | bit;
+			symbol >>= 1;
+		}
+	}
+	
+	public int GetPrice(int symbol)
+	{
+		int price = 0;
+		int m = 1;
+		for (int bitIndex = NumBitLevels; bitIndex != 0; )
+		{
+			bitIndex--;
+			int bit = (symbol >>> bitIndex) & 1;
+			price += Encoder.GetPrice(Models[m], bit);
+			m = (m << 1) + bit;
+		}
+		return price;
+	}
+	
+	public int ReverseGetPrice(int symbol)
+	{
+		int price = 0;
+		int m = 1;
+		for (int i = NumBitLevels; i != 0; i--)
+		{
+			int bit = symbol & 1;
+			symbol >>>= 1;
+			price += Encoder.GetPrice(Models[m], bit);
+			m = (m << 1) | bit;
+		}
+		return price;
+	}
+	
+	public static int ReverseGetPrice(short[] Models, int startIndex,
+			int NumBitLevels, int symbol)
+	{
+		int price = 0;
+		int m = 1;
+		for (int i = NumBitLevels; i != 0; i--)
+		{
+			int bit = symbol & 1;
+			symbol >>>= 1;
+			price += Encoder.GetPrice(Models[startIndex + m], bit);
+			m = (m << 1) | bit;
+		}
+		return price;
+	}
+	
+	public static void ReverseEncode(short[] Models, int startIndex,
+			Encoder rangeEncoder, int NumBitLevels, int symbol) throws IOException
+	{
+		int m = 1;
+		for (int i = 0; i < NumBitLevels; i++)
+		{
+			int bit = symbol & 1;
+			rangeEncoder.Encode(Models, startIndex + m, bit);
+			m = (m << 1) | bit;
+			symbol >>= 1;
+		}
+	}
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/misc/libphysfs/lzma/Java/SevenZip/Compression/RangeCoder/Decoder.java	Mon Apr 10 12:06:43 2017 -0400
@@ -0,0 +1,88 @@
+package SevenZip.Compression.RangeCoder;
+import java.io.IOException;
+
+public class Decoder
+{
+	static final int kTopMask = ~((1 << 24) - 1);
+	
+	static final int kNumBitModelTotalBits = 11;
+	static final int kBitModelTotal = (1 << kNumBitModelTotalBits);
+	static final int kNumMoveBits = 5;
+	
+	int Range;
+	int Code;
+
+	java.io.InputStream Stream;
+	
+	public final void SetStream(java.io.InputStream stream)
+	{ 
+		Stream = stream; 
+	}
+	
+	public final void ReleaseStream()
+	{ 
+		Stream = null; 
+	}
+	
+	public final void Init() throws IOException
+	{
+		Code = 0;
+		Range = -1;
+		for (int i = 0; i < 5; i++)
+			Code = (Code << 8) | Stream.read();
+	}
+	
+	public final int DecodeDirectBits(int numTotalBits) throws IOException
+	{
+		int result = 0;
+		for (int i = numTotalBits; i != 0; i--)
+		{
+			Range >>>= 1;
+			int t = ((Code - Range) >>> 31);
+			Code -= Range & (t - 1);
+			result = (result << 1) | (1 - t);
+			
+			if ((Range & kTopMask) == 0)
+			{
+				Code = (Code << 8) | Stream.read();
+				Range <<= 8;
+			}
+		}
+		return result;
+	}
+	
+	public int DecodeBit(short []probs, int index) throws IOException
+	{
+		int prob = probs[index];
+		int newBound = (Range >>> kNumBitModelTotalBits) * prob;
+		if ((Code ^ 0x80000000) < (newBound ^ 0x80000000))
+		{
+			Range = newBound;
+			probs[index] = (short)(prob + ((kBitModelTotal - prob) >>> kNumMoveBits));
+			if ((Range & kTopMask) == 0)
+			{
+				Code = (Code << 8) | Stream.read();
+				Range <<= 8;
+			}
+			return 0;
+		}
+		else
+		{
+			Range -= newBound;
+			Code -= newBound;
+			probs[index] = (short)(prob - ((prob) >>> kNumMoveBits));
+			if ((Range & kTopMask) == 0)
+			{
+				Code = (Code << 8) | Stream.read();
+				Range <<= 8;
+			}
+			return 1;
+		}
+	}
+	
+	public static void InitBitModels(short []probs)
+	{
+		for (int i = 0; i < probs.length; i++)
+			probs[i] = (kBitModelTotal >>> 1);
+	}
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/misc/libphysfs/lzma/Java/SevenZip/Compression/RangeCoder/Encoder.java	Mon Apr 10 12:06:43 2017 -0400
@@ -0,0 +1,151 @@
+package SevenZip.Compression.RangeCoder;
+import java.io.IOException;
+
+public class Encoder
+{
+	static final int kTopMask = ~((1 << 24) - 1);
+	
+	static final int kNumBitModelTotalBits = 11;
+	static final int kBitModelTotal = (1 << kNumBitModelTotalBits);
+	static final int kNumMoveBits = 5;
+	
+	java.io.OutputStream Stream;
+
+	long Low;
+	int Range;
+	int _cacheSize;
+	int _cache;
+	
+	long _position;
+	
+	public void SetStream(java.io.OutputStream stream)
+	{
+		Stream = stream;
+	}
+	
+	public void ReleaseStream()
+	{
+		Stream = null;
+	}
+	
+	public void Init()
+	{
+		_position = 0;
+		Low = 0;
+		Range = -1;
+		_cacheSize = 1;
+		_cache = 0;
+	}
+	
+	public void FlushData() throws IOException
+	{
+		for (int i = 0; i < 5; i++)
+			ShiftLow();
+	}
+	
+	public void FlushStream() throws IOException
+	{
+		Stream.flush();
+	}
+	
+	public void ShiftLow() throws IOException
+	{
+		int LowHi = (int)(Low >>> 32);
+		if (LowHi != 0 || Low < 0xFF000000L)
+		{
+			_position += _cacheSize;
+			int temp = _cache;
+			do
+			{
+				Stream.write(temp + LowHi);
+				temp = 0xFF;
+			}
+			while(--_cacheSize != 0);
+			_cache = (((int)Low) >>> 24);
+		}
+		_cacheSize++;
+		Low = (Low & 0xFFFFFF) << 8;
+	}
+	
+	public void EncodeDirectBits(int v, int numTotalBits) throws IOException
+	{
+		for (int i = numTotalBits - 1; i >= 0; i--)
+		{
+			Range >>>= 1;
+			if (((v >>> i) & 1) == 1)
+				Low += Range;
+			if ((Range & Encoder.kTopMask) == 0)
+			{
+				Range <<= 8;
+				ShiftLow();
+			}
+		}
+	}
+	
+	
+	public long GetProcessedSizeAdd()
+	{
+		return _cacheSize + _position + 4;
+	}
+	
+	
+	
+	static final int kNumMoveReducingBits = 2;
+	public static final int kNumBitPriceShiftBits = 6;
+	
+	public static void InitBitModels(short []probs)
+	{
+		for (int i = 0; i < probs.length; i++)
+			probs[i] = (kBitModelTotal >>> 1);
+	}
+	
+	public void Encode(short []probs, int index, int symbol) throws IOException
+	{
+		int prob = probs[index];
+		int newBound = (Range >>> kNumBitModelTotalBits) * prob;
+		if (symbol == 0)
+		{
+			Range = newBound;
+			probs[index] = (short)(prob + ((kBitModelTotal - prob) >>> kNumMoveBits));
+		}
+		else
+		{
+			Low += (newBound & 0xFFFFFFFFL);
+			Range -= newBound;
+			probs[index] = (short)(prob - ((prob) >>> kNumMoveBits));
+		}
+		if ((Range & kTopMask) == 0)
+		{
+			Range <<= 8;
+			ShiftLow();
+		}
+	}
+	
+	private static int[] ProbPrices = new int[kBitModelTotal >>> kNumMoveReducingBits];
+	
+	static
+	{
+		int kNumBits = (kNumBitModelTotalBits - kNumMoveReducingBits);
+		for (int i = kNumBits - 1; i >= 0; i--)
+		{
+			int start = 1 << (kNumBits - i - 1);
+			int end = 1 << (kNumBits - i);
+			for (int j = start; j < end; j++)
+				ProbPrices[j] = (i << kNumBitPriceShiftBits) +
+						(((end - j) << kNumBitPriceShiftBits) >>> (kNumBits - i - 1));
+		}
+	}
+	
+	static public int GetPrice(int Prob, int symbol)
+	{
+		return ProbPrices[(((Prob - symbol) ^ ((-symbol))) & (kBitModelTotal - 1)) >>> kNumMoveReducingBits];
+	}
+	static public int GetPrice0(int Prob)
+	{ 
+		return ProbPrices[Prob >>> kNumMoveReducingBits]; 
+	}
+	static public int GetPrice1(int Prob)
+	{ 
+		return ProbPrices[(kBitModelTotal - Prob) >>> kNumMoveReducingBits]; 
+	}
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/misc/libphysfs/lzma/Java/SevenZip/ICodeProgress.java	Mon Apr 10 12:06:43 2017 -0400
@@ -0,0 +1,6 @@
+package SevenZip;
+
+public interface ICodeProgress
+{
+	public void SetProgress(long inSize, long outSize);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/misc/libphysfs/lzma/Java/SevenZip/LzmaAlone.java	Mon Apr 10 12:06:43 2017 -0400
@@ -0,0 +1,253 @@
+package SevenZip;
+
+public class LzmaAlone
+{
+	static public class CommandLine
+	{
+		public static final int kEncode = 0;
+		public static final int kDecode = 1;
+		public static final int kBenchmak = 2;
+		
+		public int Command = -1;
+		public int NumBenchmarkPasses = 10;
+		
+		public int DictionarySize = 1 << 23;
+		public boolean DictionarySizeIsDefined = false;
+		
+		public int Lc = 3;
+		public int Lp = 0;
+		public int Pb = 2;
+		
+		public int Fb = 128;
+		public boolean FbIsDefined = false;
+		
+		public boolean Eos = false;
+		
+		public int Algorithm = 2;
+		public int MatchFinder = 1;
+		
+		public String InFile;
+		public String OutFile;
+		
+		boolean ParseSwitch(String s)
+		{
+			if (s.startsWith("d"))
+			{
+				DictionarySize = 1 << Integer.parseInt(s.substring(1));
+				DictionarySizeIsDefined = true;
+			}
+			else if (s.startsWith("fb"))
+			{
+				Fb = Integer.parseInt(s.substring(2));
+				FbIsDefined = true;
+			}
+			else if (s.startsWith("a"))
+				Algorithm = Integer.parseInt(s.substring(1));
+			else if (s.startsWith("lc"))
+				Lc = Integer.parseInt(s.substring(2));
+			else if (s.startsWith("lp"))
+				Lp = Integer.parseInt(s.substring(2));
+			else if (s.startsWith("pb"))
+				Pb = Integer.parseInt(s.substring(2));
+			else if (s.startsWith("eos"))
+				Eos = true;
+			else if (s.startsWith("mf"))
+			{
+				String mfs = s.substring(2);
+				if (mfs.equals("bt2"))
+					MatchFinder = 0;
+				else if (mfs.equals("bt4"))
+					MatchFinder = 1;
+				else if (mfs.equals("bt4b"))
+					MatchFinder = 2;
+				else
+					return false;
+			}
+			else
+				return false;
+			return true;
+		}
+		
+		public boolean Parse(String[] args) throws Exception
+		{
+			int pos = 0;
+			boolean switchMode = true;
+			for (int i = 0; i < args.length; i++)
+			{
+				String s = args[i];
+				if (s.length() == 0)
+					return false;
+				if (switchMode)
+				{
+					if (s.compareTo("--") == 0)
+					{
+						switchMode = false;
+						continue;
+					}
+					if (s.charAt(0) == '-')
+					{
+						String sw = s.substring(1).toLowerCase();
+						if (sw.length() == 0)
+							return false;
+						try
+						{
+							if (!ParseSwitch(sw))
+								return false;
+						}
+						catch (NumberFormatException e)
+						{
+							return false;
+						}
+						continue;
+					}
+				}
+				if (pos == 0)
+				{
+					if (s.equalsIgnoreCase("e"))
+						Command = kEncode;
+					else if (s.equalsIgnoreCase("d"))
+						Command = kDecode;
+					else if (s.equalsIgnoreCase("b"))
+						Command = kBenchmak;
+					else
+						return false;
+				}
+				else if(pos == 1)
+				{
+					if (Command == kBenchmak)
+					{
+						try
+						{
+							NumBenchmarkPasses = Integer.parseInt(s);
+							if (NumBenchmarkPasses < 1)
+								return false;
+						}
+						catch (NumberFormatException e)
+						{
+							return false;
+						}
+					}
+					else
+						InFile = s;
+				}
+				else if(pos == 2)
+					OutFile = s;
+				else
+					return false;
+				pos++;
+				continue;
+			}
+			return true;
+		}
+	}
+	
+	
+	static void PrintHelp()
+	{
+		System.out.println(
+				"\nUsage:  LZMA <e|d> [<switches>...] inputFile outputFile\n" +
+				"  e: encode file\n" +
+				"  d: decode file\n" +
+				"  b: Benchmark\n" +
+				"<Switches>\n" +
+				// "  -a{N}:  set compression mode - [0, 1], default: 1 (max)\n" +
+				"  -d{N}:  set dictionary - [0,28], default: 23 (8MB)\n" +
+				"  -fb{N}: set number of fast bytes - [5, 273], default: 128\n" +
+				"  -lc{N}: set number of literal context bits - [0, 8], default: 3\n" +
+				"  -lp{N}: set number of literal pos bits - [0, 4], default: 0\n" +
+				"  -pb{N}: set number of pos bits - [0, 4], default: 2\n" +
+				"  -mf{MF_ID}: set Match Finder: [bt2, bt4], default: bt4\n" +
+				"  -eos:   write End Of Stream marker\n"
+				);
+	}
+	
+	public static void main(String[] args) throws Exception
+	{
+		System.out.println("\nLZMA (Java) 4.42 Copyright (c) 1999-2006 Igor Pavlov  2006-05-15\n");
+		
+		if (args.length < 1)
+		{
+			PrintHelp();
+			return;
+		}
+		
+		CommandLine params = new CommandLine();
+		if (!params.Parse(args))
+		{
+			System.out.println("\nIncorrect command");
+			return;
+		}
+		
+		if (params.Command == CommandLine.kBenchmak)
+		{
+			int dictionary = (1 << 21);
+			if (params.DictionarySizeIsDefined)
+				dictionary = params.DictionarySize;
+			if (params.MatchFinder > 1)
+				throw new Exception("Unsupported match finder");
+			SevenZip.LzmaBench.LzmaBenchmark(params.NumBenchmarkPasses, dictionary);
+		}
+		else if (params.Command == CommandLine.kEncode || params.Command == CommandLine.kDecode)
+		{
+			java.io.File inFile = new java.io.File(params.InFile);
+			java.io.File outFile = new java.io.File(params.OutFile);
+			
+			java.io.BufferedInputStream inStream  = new java.io.BufferedInputStream(new java.io.FileInputStream(inFile));
+			java.io.BufferedOutputStream outStream = new java.io.BufferedOutputStream(new java.io.FileOutputStream(outFile));
+			
+			boolean eos = false;
+			if (params.Eos)
+				eos = true;
+			if (params.Command == CommandLine.kEncode)
+			{
+				SevenZip.Compression.LZMA.Encoder encoder = new SevenZip.Compression.LZMA.Encoder();
+				if (!encoder.SetAlgorithm(params.Algorithm))
+					throw new Exception("Incorrect compression mode");
+				if (!encoder.SetDictionarySize(params.DictionarySize))
+					throw new Exception("Incorrect dictionary size");
+				if (!encoder.SeNumFastBytes(params.Fb))
+					throw new Exception("Incorrect -fb value");
+				if (!encoder.SetMatchFinder(params.MatchFinder))
+					throw new Exception("Incorrect -mf value");
+				if (!encoder.SetLcLpPb(params.Lc, params.Lp, params.Pb))
+					throw new Exception("Incorrect -lc or -lp or -pb value");
+				encoder.SetEndMarkerMode(eos);
+				encoder.WriteCoderProperties(outStream);
+				long fileSize;
+				if (eos)
+					fileSize = -1;
+				else
+					fileSize = inFile.length();
+				for (int i = 0; i < 8; i++)
+					outStream.write((int)(fileSize >>> (8 * i)) & 0xFF);
+				encoder.Code(inStream, outStream, -1, -1, null);
+			}
+			else
+			{
+				int propertiesSize = 5;
+				byte[] properties = new byte[propertiesSize];
+				if (inStream.read(properties, 0, propertiesSize) != propertiesSize)
+					throw new Exception("input .lzma file is too short");
+				SevenZip.Compression.LZMA.Decoder decoder = new SevenZip.Compression.LZMA.Decoder();
+				if (!decoder.SetDecoderProperties(properties))
+					throw new Exception("Incorrect stream properties");
+				long outSize = 0;
+				for (int i = 0; i < 8; i++)
+				{
+					int v = inStream.read();
+					if (v < 0)
+						throw new Exception("Can't read stream size");
+					outSize |= ((long)v) << (8 * i);
+				}
+				if (!decoder.Code(inStream, outStream, outSize))
+					throw new Exception("Error in data stream");
+			}
+			outStream.flush();
+			outStream.close();
+			inStream.close();
+		}
+		else
+			throw new Exception("Incorrect command");
+		return;
+	}
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/misc/libphysfs/lzma/Java/SevenZip/LzmaBench.java	Mon Apr 10 12:06:43 2017 -0400
@@ -0,0 +1,392 @@
+package SevenZip;
+
+import java.io.ByteArrayOutputStream;
+import java.io.ByteArrayInputStream;
+import java.io.IOException;
+
+public class LzmaBench
+{
+	static final int kAdditionalSize = (1 << 21);
+	static final int kCompressedAdditionalSize = (1 << 10);
+	
+	static class CRandomGenerator
+	{
+		int A1;
+		int A2;
+		public CRandomGenerator() { Init(); }
+		public void Init() { A1 = 362436069; A2 = 521288629; }
+		public int GetRnd()
+		{
+			return
+				((A1 = 36969 * (A1 & 0xffff) + (A1 >>> 16)) << 16) ^
+				((A2 = 18000 * (A2 & 0xffff) + (A2 >>> 16)));
+		}
+	};
+	
+	static class CBitRandomGenerator
+	{
+		CRandomGenerator RG = new CRandomGenerator();
+		int Value;
+		int NumBits;
+		public void Init()
+		{
+			Value = 0;
+			NumBits = 0;
+		}
+		public int GetRnd(int numBits)
+		{
+			int result;
+			if (NumBits > numBits)
+			{
+				result = Value & ((1 << numBits) - 1);
+				Value >>>= numBits;
+				NumBits -= numBits;
+				return result;
+			}
+			numBits -= NumBits;
+			result = (Value << numBits);
+			Value = RG.GetRnd();
+			result |= Value & (((int)1 << numBits) - 1);
+			Value >>>= numBits;
+			NumBits = 32 - numBits;
+			return result;
+		}
+	};
+	
+	static class CBenchRandomGenerator
+	{
+		CBitRandomGenerator RG = new CBitRandomGenerator();
+		int Pos;
+		int Rep0;
+
+		public int BufferSize;
+		public byte[] Buffer = null;
+
+		public CBenchRandomGenerator() { }
+		public void Set(int bufferSize)
+		{
+			Buffer = new byte[bufferSize];
+			Pos = 0;
+			BufferSize = bufferSize;
+		}
+		int GetRndBit() { return RG.GetRnd(1); }
+		int GetLogRandBits(int numBits)
+		{
+			int len = RG.GetRnd(numBits);
+			return RG.GetRnd((int)len);
+		}
+		int GetOffset()
+		{
+			if (GetRndBit() == 0)
+				return GetLogRandBits(4);
+			return (GetLogRandBits(4) << 10) | RG.GetRnd(10);
+		}
+		int GetLen1() { return RG.GetRnd(1 + (int)RG.GetRnd(2)); }
+		int GetLen2() { return RG.GetRnd(2 + (int)RG.GetRnd(2)); }
+		public void Generate()
+		{
+			RG.Init();
+			Rep0 = 1;
+			while (Pos < BufferSize)
+			{
+				if (GetRndBit() == 0 || Pos < 1)
+					Buffer[Pos++] = (byte)(RG.GetRnd(8));
+				else
+				{
+					int len;
+					if (RG.GetRnd(3) == 0)
+						len = 1 + GetLen1();
+					else
+					{
+						do
+							Rep0 = GetOffset();
+						while (Rep0 >= Pos);
+						Rep0++;
+						len = 2 + GetLen2();
+					}
+					for (int i = 0; i < len && Pos < BufferSize; i++, Pos++)
+						Buffer[Pos] = Buffer[Pos - Rep0];
+				}
+			}
+		}
+	};
+	
+	static class CrcOutStream extends java.io.OutputStream
+	{
+		public CRC CRC = new CRC();
+		
+		public void Init()
+		{ 
+			CRC.Init(); 
+		}
+		public int GetDigest()
+		{ 
+			return CRC.GetDigest(); 
+		}
+		public void write(byte[] b)
+		{
+			CRC.Update(b);
+		}
+		public void write(byte[] b, int off, int len)
+		{
+			CRC.Update(b, off, len);
+		}
+		public void write(int b)
+		{
+			CRC.UpdateByte(b);
+		}
+	};
+
+	static class MyOutputStream extends java.io.OutputStream
+	{
+		byte[] _buffer;
+		int _size;
+		int _pos;
+		
+		public MyOutputStream(byte[] buffer)
+		{
+			_buffer = buffer;
+			_size = _buffer.length;
+		}
+		
+		public void reset()
+		{ 
+			_pos = 0; 
+		}
+		
+		public void write(int b) throws IOException
+		{
+			if (_pos >= _size)
+				throw new IOException("Error");
+			_buffer[_pos++] = (byte)b;
+		}
+		
+		public int size()
+		{
+			return _pos;
+		}
+	};
+
+	static class MyInputStream extends java.io.InputStream
+	{
+		byte[] _buffer;
+		int _size;
+		int _pos;
+		
+		public MyInputStream(byte[] buffer, int size)
+		{
+			_buffer = buffer;
+			_size = size;
+		}
+		
+		public void reset()
+		{ 
+			_pos = 0; 
+		}
+		
+		public int read()
+		{
+			if (_pos >= _size)
+				return -1;
+			return _buffer[_pos++] & 0xFF;
+		}
+	};
+	
+	static class CProgressInfo implements ICodeProgress
+	{
+		public long ApprovedStart;
+		public long InSize;
+		public long Time;
+		public void Init()
+		{ InSize = 0; }
+		public void SetProgress(long inSize, long outSize)
+		{
+			if (inSize >= ApprovedStart && InSize == 0)
+			{
+				Time = System.currentTimeMillis();
+				InSize = inSize;
+			}
+		}
+	}
+	static final int kSubBits = 8;
+	
+	static int GetLogSize(int size)
+	{
+		for (int i = kSubBits; i < 32; i++)
+			for (int j = 0; j < (1 << kSubBits); j++)
+				if (size <= ((1) << i) + (j << (i - kSubBits)))
+					return (i << kSubBits) + j;
+		return (32 << kSubBits);
+	}
+	
+	static long MyMultDiv64(long value, long elapsedTime)
+	{
+		long freq = 1000; // ms
+		long elTime = elapsedTime;
+		while (freq > 1000000)
+		{
+			freq >>>= 1;
+			elTime >>>= 1;
+		}
+		if (elTime == 0)
+			elTime = 1;
+		return value * freq / elTime;
+	}
+	
+	static long GetCompressRating(int dictionarySize, long elapsedTime, long size)
+	{
+		long t = GetLogSize(dictionarySize) - (18 << kSubBits);
+		long numCommandsForOne = 1060 + ((t * t * 10) >> (2 * kSubBits));
+		long numCommands = (long)(size) * numCommandsForOne;
+		return MyMultDiv64(numCommands, elapsedTime);
+	}
+	
+	static long GetDecompressRating(long elapsedTime, long outSize, long inSize)
+	{
+		long numCommands = inSize * 220 + outSize * 20;
+		return MyMultDiv64(numCommands, elapsedTime);
+	}
+	
+	static long GetTotalRating(
+			int dictionarySize,
+			long elapsedTimeEn, long sizeEn,
+			long elapsedTimeDe,
+			long inSizeDe, long outSizeDe)
+	{
+		return (GetCompressRating(dictionarySize, elapsedTimeEn, sizeEn) +
+				GetDecompressRating(elapsedTimeDe, inSizeDe, outSizeDe)) / 2;
+	}
+	
+	static void PrintValue(long v)
+	{
+		String s = "";
+		s += v;
+		for (int i = 0; i + s.length() < 6; i++)
+			System.out.print(" ");
+		System.out.print(s);
+	}
+	
+	static void PrintRating(long rating)
+	{
+		PrintValue(rating / 1000000);
+		System.out.print(" MIPS");
+	}
+	
+	static void PrintResults(
+			int dictionarySize,
+			long elapsedTime,
+			long size,
+			boolean decompressMode, long secondSize)
+	{
+		long speed = MyMultDiv64(size, elapsedTime);
+		PrintValue(speed / 1024);
+		System.out.print(" KB/s  ");
+		long rating;
+		if (decompressMode)
+			rating = GetDecompressRating(elapsedTime, size, secondSize);
+		else
+			rating = GetCompressRating(dictionarySize, elapsedTime, size);
+		PrintRating(rating);
+	}
+	
+	static public int LzmaBenchmark(int numIterations, int dictionarySize) throws Exception
+	{
+		if (numIterations <= 0)
+			return 0;
+		if (dictionarySize < (1 << 18))
+		{
+			System.out.println("\nError: dictionary size for benchmark must be >= 18 (256 KB)");
+			return 1;
+		}
+		System.out.print("\n       Compressing                Decompressing\n\n");
+		
+		SevenZip.Compression.LZMA.Encoder encoder = new SevenZip.Compression.LZMA.Encoder();
+		SevenZip.Compression.LZMA.Decoder decoder = new SevenZip.Compression.LZMA.Decoder();
+		
+		if (!encoder.SetDictionarySize(dictionarySize))
+			throw new Exception("Incorrect dictionary size");
+		
+		int kBufferSize = dictionarySize + kAdditionalSize;
+		int kCompressedBufferSize = (kBufferSize / 2) + kCompressedAdditionalSize;
+		
+		ByteArrayOutputStream propStream = new ByteArrayOutputStream();
+		encoder.WriteCoderProperties(propStream);
+		byte[] propArray = propStream.toByteArray();
+		decoder.SetDecoderProperties(propArray);
+		
+		CBenchRandomGenerator rg = new CBenchRandomGenerator();
+
+		rg.Set(kBufferSize);
+		rg.Generate();
+		CRC crc = new CRC();
+		crc.Init();
+		crc.Update(rg.Buffer, 0, rg.BufferSize);
+		
+		CProgressInfo progressInfo = new CProgressInfo();
+		progressInfo.ApprovedStart = dictionarySize;
+		
+		long totalBenchSize = 0;
+		long totalEncodeTime = 0;
+		long totalDecodeTime = 0;
+		long totalCompressedSize = 0;
+		
+		MyInputStream inStream = new MyInputStream(rg.Buffer, rg.BufferSize);
+
+		byte[] compressedBuffer = new byte[kCompressedBufferSize];
+		MyOutputStream compressedStream = new MyOutputStream(compressedBuffer);
+		CrcOutStream crcOutStream = new CrcOutStream();
+		MyInputStream inputCompressedStream = null;
+		int compressedSize = 0;
+		for (int i = 0; i < numIterations; i++)
+		{
+			progressInfo.Init();
+			inStream.reset();
+			compressedStream.reset();
+			encoder.Code(inStream, compressedStream, -1, -1, progressInfo);
+			long encodeTime = System.currentTimeMillis() - progressInfo.Time;
+			
+			if (i == 0)
+			{
+				compressedSize = compressedStream.size();
+				inputCompressedStream = new MyInputStream(compressedBuffer, compressedSize);
+			}
+			else if (compressedSize != compressedStream.size())
+				throw (new Exception("Encoding error"));
+				
+			if (progressInfo.InSize == 0)
+				throw (new Exception("Internal ERROR 1282"));
+
+			long decodeTime = 0;
+			for (int j = 0; j < 2; j++)
+			{
+				inputCompressedStream.reset();
+				crcOutStream.Init();
+				
+				long outSize = kBufferSize;
+				long startTime = System.currentTimeMillis();
+				if (!decoder.Code(inputCompressedStream, crcOutStream, outSize))
+					throw (new Exception("Decoding Error"));;
+				decodeTime = System.currentTimeMillis() - startTime;
+				if (crcOutStream.GetDigest() != crc.GetDigest())
+					throw (new Exception("CRC Error"));
+			}
+			long benchSize = kBufferSize - (long)progressInfo.InSize;
+			PrintResults(dictionarySize, encodeTime, benchSize, false, 0);
+			System.out.print("     ");
+			PrintResults(dictionarySize, decodeTime, kBufferSize, true, compressedSize);
+			System.out.println();
+			
+			totalBenchSize += benchSize;
+			totalEncodeTime += encodeTime;
+			totalDecodeTime += decodeTime;
+			totalCompressedSize += compressedSize;
+		}
+		System.out.println("---------------------------------------------------");
+		PrintResults(dictionarySize, totalEncodeTime, totalBenchSize, false, 0);
+		System.out.print("     ");
+		PrintResults(dictionarySize, totalDecodeTime,
+				kBufferSize * (long)numIterations, true, totalCompressedSize);
+		System.out.println("    Average");
+		return 0;
+	}
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/misc/libphysfs/lzma/LGPL.txt	Mon Apr 10 12:06:43 2017 -0400
@@ -0,0 +1,504 @@
+      GNU LESSER GENERAL PUBLIC LICENSE
+           Version 2.1, February 1999
+
+ Copyright (C) 1991, 1999 Free Software Foundation, Inc.
+     59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+[This is the first released version of the Lesser GPL.  It also counts
+ as the successor of the GNU Library Public License, version 2, hence
+ the version number 2.1.]
+
+          Preamble
+
+  The licenses for most software are designed to take away your
+freedom to share and change it.  By contrast, the GNU General Public
+Licenses are intended to guarantee your freedom to share and change
+free software--to make sure the software is free for all its users.
+
+  This license, the Lesser General Public License, applies to some
+specially designated software packages--typically libraries--of the
+Free Software Foundation and other authors who decide to use it.  You
+can use it too, but we suggest you first think carefully about whether
+this license or the ordinary General Public License is the better
+strategy to use in any particular case, based on the explanations below.
+
+  When we speak of free software, we are referring to freedom of use,
+not price.  Our General Public Licenses are designed to make sure that
+you have the freedom to distribute copies of free software (and charge
+for this service if you wish); that you receive source code or can get
+it if you want it; that you can change the software and use pieces of
+it in new free programs; and that you are informed that you can do
+these things.
+
+  To protect your rights, we need to make restrictions that forbid
+distributors to deny you these rights or to ask you to surrender these
+rights.  These restrictions translate to certain responsibilities for
+you if you distribute copies of the library or if you modify it.
+
+  For example, if you distribute copies of the library, whether gratis
+or for a fee, you must give the recipients all the rights that we gave
+you.  You must make sure that they, too, receive or can get the source
+code.  If you link other code with the library, you must provide
+complete object files to the recipients, so that they can relink them
+with the library after making changes to the library and recompiling
+it.  And you must show them these terms so they know their rights.
+
+  We protect your rights with a two-step method: (1) we copyright the
+library, and (2) we offer you this license, which gives you legal
+permission to copy, distribute and/or modify the library.
+
+  To protect each distributor, we want to make it very clear that
+there is no warranty for the free library.  Also, if the library is
+modified by someone else and passed on, the recipients should know
+that what they have is not the original version, so that the original
+author's reputation will not be affected by problems that might be
+introduced by others.
+
+  Finally, software patents pose a constant threat to the existence of
+any free program.  We wish to make sure that a company cannot
+effectively restrict the users of a free program by obtaining a
+restrictive license from a patent holder.  Therefore, we insist that
+any patent license obtained for a version of the library must be
+consistent with the full freedom of use specified in this license.
+
+  Most GNU software, including some libraries, is covered by the
+ordinary GNU General Public License.  This license, the GNU Lesser
+General Public License, applies to certain designated libraries, and
+is quite different from the ordinary General Public License.  We use
+this license for certain libraries in order to permit linking those
+libraries into non-free programs.
+
+  When a program is linked with a library, whether statically or using
+a shared library, the combination of the two is legally speaking a
+combined work, a derivative of the original library.  The ordinary
+General Public License therefore permits such linking only if the
+entire combination fits its criteria of freedom.  The Lesser General
+Public License permits more lax criteria for linking other code with
+the library.
+
+  We call this license the "Lesser" General Public License because it
+does Less to protect the user's freedom than the ordinary General
+Public License.  It also provides other free software developers Less
+of an advantage over competing non-free programs.  These disadvantages
+are the reason we use the ordinary General Public License for many
+libraries.  However, the Lesser license provides advantages in certain
+special circumstances.
+
+  For example, on rare occasions, there may be a special need to
+encourage the widest possible use of a certain library, so that it becomes
+a de-facto standard.  To achieve this, non-free programs must be
+allowed to use the library.  A more frequent case is that a free
+library does the same job as widely used non-free libraries.  In this
+case, there is little to gain by limiting the free library to free
+software only, so we use the Lesser General Public License.
+
+  In other cases, permission to use a particular library in non-free
+programs enables a greater number of people to use a large body of
+free software.  For example, permission to use the GNU C Library in
+non-free programs enables many more people to use the whole GNU
+operating system, as well as its variant, the GNU/Linux operating
+system.
+
+  Although the Lesser General Public License is Less protective of the
+users' freedom, it does ensure that the user of a program that is
+linked with the Library has the freedom and the wherewithal to run
+that program using a modified version of the Library.
+
+  The precise terms and conditions for copying, distribution and
+modification follow.  Pay close attention to the difference between a
+"work based on the library" and a "work that uses the library".  The
+former contains code derived from the library, whereas the latter must
+be combined with the library in order to run.
+
+      GNU LESSER GENERAL PUBLIC LICENSE
+   TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
+
+  0. This License Agreement applies to any software library or other
+program which contains a notice placed by the copyright holder or
+other authorized party saying it may be distributed under the terms of
+this Lesser General Public License (also called "this License").
+Each licensee is addressed as "you".
+
+  A "library" means a collection of software functions and/or data
+prepared so as to be conveniently linked with application programs
+(which use some of those functions and data) to form executables.
+
+  The "Library", below, refers to any such software library or work
+which has been distributed under these terms.  A "work based on the
+Library" means either the Library or any derivative work under
+copyright law: that is to say, a work containing the Library or a
+portion of it, either verbatim or with modifications and/or translated
+straightforwardly into another language.  (Hereinafter, translation is
+included without limitation in the term "modification".)
+
+  "Source code" for a work means the preferred form of the work for
+making modifications to it.  For a library, complete source code means
+all the source code for all modules it contains, plus any associated
+interface definition files, plus the scripts used to control compilation
+and installation of the library.
+
+  Activities other than copying, distribution and modification are not
+covered by this License; they are outside its scope.  The act of
+running a program using the Library is not restricted, and output from
+such a program is covered only if its contents constitute a work based
+on the Library (independent of the use of the Library in a tool for
+writing it).  Whether that is true depends on what the Library does
+and what the program that uses the Library does.
+  
+  1. You may copy and distribute verbatim copies of the Library's
+complete source code as you receive it, in any medium, provided that
+you conspicuously and appropriately publish on each copy an
+appropriate copyright notice and disclaimer of warranty; keep intact
+all the notices that refer to this License and to the absence of any
+warranty; and distribute a copy of this License along with the
+Library.
+
+  You may charge a fee for the physical act of transferring a copy,
+and you may at your option offer warranty protection in exchange for a
+fee.
+
+  2. You may modify your copy or copies of the Library or any portion
+of it, thus forming a work based on the Library, and copy and
+distribute such modifications or work under the terms of Section 1
+above, provided that you also meet all of these conditions:
+
+    a) The modified work must itself be a software library.
+
+    b) You must cause the files modified to carry prominent notices
+    stating that you changed the files and the date of any change.
+
+    c) You must cause the whole of the work to be licensed at no
+    charge to all third parties under the terms of this License.
+
+    d) If a facility in the modified Library refers to a function or a
+    table of data to be supplied by an application program that uses
+    the facility, other than as an argument passed when the facility
+    is invoked, then you must make a good faith effort to ensure that,
+    in the event an application does not supply such function or
+    table, the facility still operates, and performs whatever part of
+    its purpose remains meaningful.
+
+    (For example, a function in a library to compute square roots has
+    a purpose that is entirely well-defined independent of the
+    application.  Therefore, Subsection 2d requires that any
+    application-supplied function or table used by this function must
+    be optional: if the application does not supply it, the square
+    root function must still compute square roots.)
+
+These requirements apply to the modified work as a whole.  If
+identifiable sections of that work are not derived from the Library,
+and can be reasonably considered independent and separate works in
+themselves, then this License, and its terms, do not apply to those
+sections when you distribute them as separate works.  But when you
+distribute the same sections as part of a whole which is a work based
+on the Library, the distribution of the whole must be on the terms of
+this License, whose permissions for other licensees extend to the
+entire whole, and thus to each and every part regardless of who wrote
+it.
+
+Thus, it is not the intent of this section to claim rights or contest
+your rights to work written entirely by you; rather, the intent is to
+exercise the right to control the distribution of derivative or
+collective works based on the Library.
+
+In addition, mere aggregation of another work not based on the Library
+with the Library (or with a work based on the Library) on a volume of
+a storage or distribution medium does not bring the other work under
+the scope of this License.
+
+  3. You may opt to apply the terms of the ordinary GNU General Public
+License instead of this License to a given copy of the Library.  To do
+this, you must alter all the notices that refer to this License, so
+that they refer to the ordinary GNU General Public License, version 2,
+instead of to this License.  (If a newer version than version 2 of the
+ordinary GNU General Public License has appeared, then you can specify
+that version instead if you wish.)  Do not make any other change in
+these notices.
+
+  Once this change is made in a given copy, it is irreversible for
+that copy, so the ordinary GNU General Public License applies to all
+subsequent copies and derivative works made from that copy.
+
+  This option is useful when you wish to copy part of the code of
+the Library into a program that is not a library.
+
+  4. You may copy and distribute the Library (or a portion or
+derivative of it, under Section 2) in object code or executable form
+under the terms of Sections 1 and 2 above provided that you accompany
+it with the complete corresponding machine-readable source code, which
+must be distributed under the terms of Sections 1 and 2 above on a
+medium customarily used for software interchange.
+
+  If distribution of object code is made by offering access to copy
+from a designated place, then offering equivalent access to copy the
+source code from the same place satisfies the requirement to
+distribute the source code, even though third parties are not
+compelled to copy the source along with the object code.
+
+  5. A program that contains no derivative of any portion of the
+Library, but is designed to work with the Library by being compiled or
+linked with it, is called a "work that uses the Library".  Such a
+work, in isolation, is not a derivative work of the Library, and
+therefore falls outside the scope of this License.
+
+  However, linking a "work that uses the Library" with the Library
+creates an executable that is a derivative of the Library (because it
+contains portions of the Library), rather than a "work that uses the
+library".  The executable is therefore covered by this License.
+Section 6 states terms for distribution of such executables.
+
+  When a "work that uses the Library" uses material from a header file
+that is part of the Library, the object code for the work may be a
+derivative work of the Library even though the source code is not.
+Whether this is true is especially significant if the work can be
+linked without the Library, or if the work is itself a library.  The
+threshold for this to be true is not precisely defined by law.
+
+  If such an object file uses only numerical parameters, data
+structure layouts and accessors, and small macros and small inline
+functions (ten lines or less in length), then the use of the object
+file is unrestricted, regardless of whether it is legally a derivative
+work.  (Executables containing this object code plus portions of the
+Library will still fall under Section 6.)
+
+  Otherwise, if the work is a derivative of the Library, you may
+distribute the object code for the work under the terms of Section 6.
+Any executables containing that work also fall under Section 6,
+whether or not they are linked directly with the Library itself.
+
+  6. As an exception to the Sections above, you may also combine or
+link a "work that uses the Library" with the Library to produce a
+work containing portions of the Library, and distribute that work
+under terms of your choice, provided that the terms permit
+modification of the work for the customer's own use and reverse
+engineering for debugging such modifications.
+
+  You must give prominent notice with each copy of the work that the
+Library is used in it and that the Library and its use are covered by
+this License.  You must supply a copy of this License.  If the work
+during execution displays copyright notices, you must include the
+copyright notice for the Library among them, as well as a reference
+directing the user to the copy of this License.  Also, you must do one
+of these things:
+
+    a) Accompany the work with the complete corresponding
+    machine-readable source code for the Library including whatever
+    changes were used in the work (which must be distributed under
+    Sections 1 and 2 above); and, if the work is an executable linked
+    with the Library, with the complete machine-readable "work that
+    uses the Library", as object code and/or source code, so that the
+    user can modify the Library and then relink to produce a modified
+    executable containing the modified Library.  (It is understood
+    that the user who changes the contents of definitions files in the
+    Library will not necessarily be able to recompile the application
+    to use the modified definitions.)
+
+    b) Use a suitable shared library mechanism for linking with the
+    Library.  A suitable mechanism is one that (1) uses at run time a
+    copy of the library already present on the user's computer system,
+    rather than copying library functions into the executable, and (2)
+    will operate properly with a modified version of the library, if
+    the user installs one, as long as the modified version is
+    interface-compatible with the version that the work was made with.
+
+    c) Accompany the work with a written offer, valid for at
+    least three years, to give the same user the materials
+    specified in Subsection 6a, above, for a charge no more
+    than the cost of performing this distribution.
+
+    d) If distribution of the work is made by offering access to copy
+    from a designated place, offer equivalent access to copy the above
+    specified materials from the same place.
+
+    e) Verify that the user has already received a copy of these
+    materials or that you have already sent this user a copy.
+
+  For an executable, the required form of the "work that uses the
+Library" must include any data and utility programs needed for
+reproducing the executable from it.  However, as a special exception,
+the materials to be distributed need not include anything that is
+normally distributed (in either source or binary form) with the major
+components (compiler, kernel, and so on) of the operating system on
+which the executable runs, unless that component itself accompanies
+the executable.
+
+  It may happen that this requirement contradicts the license
+restrictions of other proprietary libraries that do not normally
+accompany the operating system.  Such a contradiction means you cannot
+use both them and the Library together in an executable that you
+distribute.
+
+  7. You may place library facilities that are a work based on the
+Library side-by-side in a single library together with other library
+facilities not covered by this License, and distribute such a combined
+library, provided that the separate distribution of the work based on
+the Library and of the other library facilities is otherwise
+permitted, and provided that you do these two things:
+
+    a) Accompany the combined library with a copy of the same work
+    based on the Library, uncombined with any other library
+    facilities.  This must be distributed under the terms of the
+    Sections above.
+
+    b) Give prominent notice with the combined library of the fact
+    that part of it is a work based on the Library, and explaining
+    where to find the accompanying uncombined form of the same work.
+
+  8. You may not copy, modify, sublicense, link with, or distribute
+the Library except as expressly provided under this License.  Any
+attempt otherwise to copy, modify, sublicense, link with, or
+distribute the Library is void, and will automatically terminate your
+rights under this License.  However, parties who have received copies,
+or rights, from you under this License will not have their licenses
+terminated so long as such parties remain in full compliance.
+
+  9. You are not required to accept this License, since you have not
+signed it.  However, nothing else grants you permission to modify or
+distribute the Library or its derivative works.  These actions are
+prohibited by law if you do not accept this License.  Therefore, by
+modifying or distributing the Library (or any work based on the
+Library), you indicate your acceptance of this License to do so, and
+all its terms and conditions for copying, distributing or modifying
+the Library or works based on it.
+
+  10. Each time you redistribute the Library (or any work based on the
+Library), the recipient automatically receives a license from the
+original licensor to copy, distribute, link with or modify the Library
+subject to these terms and conditions.  You may not impose any further
+restrictions on the recipients' exercise of the rights granted herein.
+You are not responsible for enforcing compliance by third parties with
+this License.
+
+  11. If, as a consequence of a court judgment or allegation of patent
+infringement or for any other reason (not limited to patent issues),
+conditions are imposed on you (whether by court order, agreement or
+otherwise) that contradict the conditions of this License, they do not
+excuse you from the conditions of this License.  If you cannot
+distribute so as to satisfy simultaneously your obligations under this
+License and any other pertinent obligations, then as a consequence you
+may not distribute the Library at all.  For example, if a patent
+license would not permit royalty-free redistribution of the Library by
+all those who receive copies directly or indirectly through you, then
+the only way you could satisfy both it and this License would be to
+refrain entirely from distribution of the Library.
+
+If any portion of this section is held invalid or unenforceable under any
+particular circumstance, the balance of the section is intended to apply,
+and the section as a whole is intended to apply in other circumstances.
+
+It is not the purpose of this section to induce you to infringe any
+patents or other property right claims or to contest validity of any
+such claims; this section has the sole purpose of protecting the
+integrity of the free software distribution system which is
+implemented by public license practices.  Many people have made
+generous contributions to the wide range of software distributed
+through that system in reliance on consistent application of that
+system; it is up to the author/donor to decide if he or she is willing
+to distribute software through any other system and a licensee cannot
+impose that choice.
+
+This section is intended to make thoroughly clear what is believed to
+be a consequence of the rest of this License.
+
+  12. If the distribution and/or use of the Library is restricted in
+certain countries either by patents or by copyrighted interfaces, the
+original copyright holder who places the Library under this License may add
+an explicit geographical distribution limitation excluding those countries,
+so that distribution is permitted only in or among countries not thus
+excluded.  In such case, this License incorporates the limitation as if
+written in the body of this License.
+
+  13. The Free Software Foundation may publish revised and/or new
+versions of the Lesser General Public License from time to time.
+Such new versions will be similar in spirit to the present version,
+but may differ in detail to address new problems or concerns.
+
+Each version is given a distinguishing version number.  If the Library
+specifies a version number of this License which applies to it and
+"any later version", you have the option of following the terms and
+conditions either of that version or of any later version published by
+the Free Software Foundation.  If the Library does not specify a
+license version number, you may choose any version ever published by
+the Free Software Foundation.
+
+  14. If you wish to incorporate parts of the Library into other free
+programs whose distribution conditions are incompatible with these,
+write to the author to ask for permission.  For software which is
+copyrighted by the Free Software Foundation, write to the Free
+Software Foundation; we sometimes make exceptions for this.  Our
+decision will be guided by the two goals of preserving the free status
+of all derivatives of our free software and of promoting the sharing
+and reuse of software generally.
+
+          NO WARRANTY
+
+  15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO
+WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW.
+EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR
+OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY
+KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+PURPOSE.  THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE
+LIBRARY IS WITH YOU.  SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME
+THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
+
+  16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN
+WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY
+AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU
+FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR
+CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE
+LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING
+RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A
+FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF
+SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
+DAMAGES.
+
+         END OF TERMS AND CONDITIONS
+
+           How to Apply These Terms to Your New Libraries
+
+  If you develop a new library, and you want it to be of the greatest
+possible use to the public, we recommend making it free software that
+everyone can redistribute and change.  You can do so by permitting
+redistribution under these terms (or, alternatively, under the terms of the
+ordinary General Public License).
+
+  To apply these terms, attach the following notices to the library.  It is
+safest to attach them to the start of each source file to most effectively
+convey the exclusion of warranty; and each file should have at least the
+"copyright" line and a pointer to where the full notice is found.
+
+    <one line to give the library's name and a brief idea of what it does.>
+    Copyright (C) <year>  <name of author>
+
+    This library is free software; you can redistribute it and/or
+    modify it under the terms of the GNU Lesser General Public
+    License as published by the Free Software Foundation; either
+    version 2.1 of the License, or (at your option) any later version.
+
+    This library is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+    Lesser General Public License for more details.
+
+    You should have received a copy of the GNU Lesser General Public
+    License along with this library; if not, write to the Free Software
+    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+
+Also add information on how to contact you by electronic and paper mail.
+
+You should also get your employer (if you work as a programmer) or your
+school, if any, to sign a "copyright disclaimer" for the library, if
+necessary.  Here is a sample; alter the names:
+
+  Yoyodyne, Inc., hereby disclaims all copyright interest in the
+  library `Frob' (a library for tweaking knobs) written by James Random Hacker.
+
+  <signature of Ty Coon>, 1 April 1990
+  Ty Coon, President of Vice
+
+That's all there is to it!
+
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/misc/libphysfs/lzma/Methods.txt	Mon Apr 10 12:06:43 2017 -0400
@@ -0,0 +1,141 @@
+7-Zip method IDs (4.56)
+-----------------------
+
+Each compression or crypto method in 7z has unique binary value (ID).
+The length of ID in bytes is arbitrary but it can not exceed 63 bits (8 bytes).
+
+If you want to add some new ID, you have two ways:
+1) Write request for allocating IDs to 7-zip developers.
+2) Generate 8-bytes ID:
+
+    7F ZZ ZZ ZZ ZZ ZZ MM MM 
+
+    7F              - Prefix for random IDs (1 byte)
+    ZZ ZZ ZZ ZZ ZZ  - Developer ID (5 bytes). Use real random bytes. 
+                      
+    MM MM           - Method ID (2 bytes)
+
+    You can notify 7-Zip developers about your Developer ID / Method ID.
+
+    Note: Use new ID only if old codec can not decode data encoded with new version.
+
+
+List of defined IDs
+-------------------
+      
+00 - Copy
+01 - Reserved
+02 - Common
+   03 Swap
+      - 2 Swap2
+      - 4 Swap4
+   04 Delta (subject to change)
+
+03 - 7z
+   01 - LZMA
+      01 - Version
+  
+   03 - Branch
+      01 - x86
+         03  - BCJ
+         1B  - BCJ2
+      02 - PPC
+         05 - BC_PPC_B (Big Endian)
+      03 - Alpha
+         01 - BC_Alpha
+      04 - IA64
+         01 - BC_IA64
+      05 - ARM
+         01 - BC_ARM
+      06 - M68
+         05 - BC_M68_B (Big Endian)
+      07 - ARM Thumb
+         01 - BC_ARMThumb
+      08 - SPARC
+         05 - BC_SPARC
+
+   04 - PPMD
+      01 - Version
+
+   7F -
+      01 - experimental methods.
+
+   80 - reserved for independent developers
+
+   E0 - Random IDs
+
+04 - Misc
+   00 - Reserved
+   01 - Zip
+      00 - Copy (not used). Use {00} instead
+      01 - Shrink
+      06 - Implode
+      08 - Deflate
+      09 - Deflate64
+      12 - BZip2 (not used). Use {04 02 02} instead
+   02 - BZip
+      02 - BZip2
+   03 - Rar
+      01 - Rar15
+      02 - Rar20
+      03 - Rar29
+   04 - Arj
+      01 - Arj (1,2,3)
+      02 - Arj 4
+   05 - Z
+   06 - Lzh
+   07 - Reserved for 7z
+   08 - Cab
+   09 - NSIS
+      01 - DeflateNSIS
+      02 - BZip2NSIS
+
+
+06 - Crypto 
+   00 - 
+   01 - AES
+      0x - AES-128
+      4x - AES-192
+      8x - AES-256
+      Cx - AES
+
+      x0 - ECB
+      x1 - CBC
+      x2 - CFB
+      x3 - OFB
+
+   07 - Reserved
+   0F - Reserved
+
+   F0 - Misc Ciphers (Real Ciphers without hashing algo)
+
+   F1 - Misc Ciphers (Combine)
+      01 - Zip
+         01 - Main Zip crypto algo
+      03 - RAR
+         02 - 
+         03 - Rar29 AES-128 + (modified SHA-1)
+      07 - 7z
+         01 - AES-256 + SHA-256
+
+07 - Hash (subject to change)
+   00 - 
+   01 - CRC
+   02 - SHA-1
+   03 - SHA-256
+   04 - SHA-384
+   05 - SHA-512
+
+   F0 - Misc Hash
+
+   F1 - Misc
+      03 - RAR
+         03 - Rar29 Password Hashing (modified SHA1)
+      07 - 7z 
+         01 - SHA-256 Password Hashing
+    
+   
+
+
+---
+End of document
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/misc/libphysfs/lzma/history.txt	Mon Apr 10 12:06:43 2017 -0400
@@ -0,0 +1,198 @@
+HISTORY of the LZMA SDK
+-----------------------
+
+  4.57           2007-12-12
+  -------------------------
+    - Speed optimizations in Ñ++ LZMA Decoder. 
+    - Small changes for more compatibility with some C/C++ compilers.
+
+  
+  4.49 beta      2007-07-05
+  -------------------------
+    - .7z ANSI-C Decoder:
+         - now it supports BCJ and BCJ2 filters
+         - now it supports files larger than 4 GB.
+         - now it supports "Last Write Time" field for files.
+    - C++ code for .7z archives compressing/decompressing from 7-zip 
+      was included to LZMA SDK.
+      
+
+  4.43           2006-06-04
+  -------------------------
+    - Small changes for more compatibility with some C/C++ compilers.
+      
+
+  4.42           2006-05-15
+  -------------------------
+    - Small changes in .h files in ANSI-C version.
+      
+
+  4.39 beta      2006-04-14
+  -------------------------
+    - Bug in versions 4.33b:4.38b was fixed:
+      C++ version of LZMA encoder could not correctly compress 
+      files larger than 2 GB with HC4 match finder (-mfhc4).
+      
+
+  4.37 beta      2005-04-06
+  -------------------------
+    - Fixes in C++ code: code could no be compiled if _NO_EXCEPTIONS was defined. 
+
+  
+  4.35 beta      2005-03-02
+  -------------------------
+    - Bug was fixed in C++ version of LZMA Decoder:
+       If encoded stream was corrupted, decoder could access memory 
+       outside of allocated range.
+
+  
+  4.34 beta      2006-02-27
+  -------------------------
+    - Compressing speed and memory requirements for compressing were increased
+    - LZMA now can use only these match finders: HC4, BT2, BT3, BT4
+
+  
+  4.32           2005-12-09
+  -------------------------
+    - Java version of LZMA SDK was included
+
+
+  4.30           2005-11-20
+  -------------------------
+    - Compression ratio was improved in -a2 mode
+    - Speed optimizations for compressing in -a2 mode
+    - -fb switch now supports values up to 273
+    - Bug in 7z_C (7zIn.c) was fixed:
+      It used Alloc/Free functions from different memory pools.
+      So if program used two memory pools, it worked incorrectly.
+    - 7z_C: .7z format supporting was improved
+    - LZMA# SDK (C#.NET version) was included
+
+
+  4.27 (Updated) 2005-09-21
+  -------------------------
+   - Some GUIDs/interfaces in C++ were changed.
+     IStream.h:
+       ISequentialInStream::Read now works as old ReadPart
+       ISequentialOutStream::Write now works as old WritePart
+
+  
+  4.27           2005-08-07
+  -------------------------
+    - Bug in LzmaDecodeSize.c was fixed:
+       if _LZMA_IN_CB and _LZMA_OUT_READ were defined,
+       decompressing worked incorrectly.
+
+
+  4.26           2005-08-05
+  -------------------------
+    - Fixes in 7z_C code and LzmaTest.c:
+      previous versions could work incorrectly,
+      if malloc(0) returns 0
+
+
+  4.23           2005-06-29
+  -------------------------
+    - Small fixes in C++ code
+
+
+  4.22           2005-06-10
+  -------------------------
+    - Small fixes
+
+
+  4.21           2005-06-08
+  -------------------------
+    - Interfaces for ANSI-C LZMA Decoder (LzmaDecode.c) were changed
+    - New additional version of ANSI-C LZMA Decoder with zlib-like interface:
+        - LzmaStateDecode.h
+        - LzmaStateDecode.c
+        - LzmaStateTest.c
+    - ANSI-C LZMA Decoder now can decompress files larger than 4 GB
+
+  
+  4.17           2005-04-18
+  -------------------------
+    - New example for RAM->RAM compressing/decompressing: 
+      LZMA + BCJ (filter for x86 code):
+        - LzmaRam.h
+        - LzmaRam.cpp
+        - LzmaRamDecode.h
+        - LzmaRamDecode.c
+        - -f86 switch for lzma.exe
+
+  
+  4.16           2005-03-29
+  -------------------------
+    - Bug was fixed in LzmaDecode.c (ANSI-C LZMA Decoder): 
+       If _LZMA_OUT_READ was defined, and if encoded stream was corrupted,
+       decoder could access memory outside of allocated range.
+    - Speed optimization of ANSI-C LZMA Decoder (now it's about 20% faster).
+      Old version of LZMA Decoder now is in file LzmaDecodeSize.c. 
+      LzmaDecodeSize.c can provide slightly smaller code than LzmaDecode.c
+    - Small speed optimization in LZMA C++ code
+    - filter for SPARC's code was added
+    - Simplified version of .7z ANSI-C Decoder was included
+
+
+  4.06           2004-09-05
+  -------------------------
+    - Bug in v4.05 was fixed:
+        LZMA-Encoder didn't release output stream in some cases.
+
+
+  4.05           2004-08-25
+  -------------------------
+    - Source code of filters for x86, IA-64, ARM, ARM-Thumb 
+      and PowerPC code was included to SDK
+    - Some internal minor changes
+
+
+  4.04           2004-07-28
+  -------------------------
+    - More compatibility with some C++ compilers
+
+
+  4.03           2004-06-18
+  -------------------------
+    - "Benchmark" command was added. It measures compressing 
+      and decompressing speed and shows rating values. 
+      Also it checks hardware errors.
+
+
+  4.02           2004-06-10
+  -------------------------
+    - C++ LZMA Encoder/Decoder code now is more portable
+      and it can be compiled by GCC on Linux.
+
+
+  4.01           2004-02-15
+  -------------------------
+    - Some detection of data corruption was enabled.
+        LzmaDecode.c / RangeDecoderReadByte
+        .....
+        {
+          rd->ExtraBytes = 1;
+          return 0xFF;
+        }
+
+
+  4.00           2004-02-13
+  -------------------------
+    - Original version of LZMA SDK
+
+
+
+HISTORY of the LZMA
+-------------------
+  2001-2007:  Improvements to LZMA compressing/decompressing code, 
+              keeping compatibility with original LZMA format
+  1996-2001:  Development of LZMA compression format
+
+  Some milestones:
+
+  2001-08-30: LZMA compression was added to 7-Zip
+  1999-01-02: First version of 7-Zip was released
+  
+
+End of document
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/misc/libphysfs/lzma/lzma.txt	Mon Apr 10 12:06:43 2017 -0400
@@ -0,0 +1,663 @@
+LZMA SDK 4.57
+-------------
+
+LZMA SDK   Copyright (C) 1999-2007 Igor Pavlov
+
+LZMA SDK provides the documentation, samples, header files, libraries, 
+and tools you need to develop applications that use LZMA compression.
+
+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.
+
+LZMA is an improved version of famous LZ77 compression algorithm. 
+It was improved in way of maximum increasing of compression ratio,
+keeping high decompression speed and low memory requirements for 
+decompressing.
+
+
+
+LICENSE
+-------
+
+LZMA SDK is available under any of the following licenses:
+
+1) GNU Lesser General Public License (GNU LGPL)
+2) Common Public License (CPL)
+3) Simplified license for unmodified code (read SPECIAL EXCEPTION) 
+4) Proprietary license 
+
+It means that you can select one of these four options and follow rules of that license.
+
+
+1,2) GNU LGPL and CPL licenses are pretty similar and both these
+licenses are classified as 
+ - "Free software licenses" at http://www.gnu.org/ 
+ - "OSI-approved" at http://www.opensource.org/
+
+
+3) SPECIAL EXCEPTION
+
+Igor Pavlov, as the author of this code, expressly permits you 
+to statically or dynamically link your code (or bind by name) 
+to the files from LZMA SDK without subjecting your linked 
+code to the terms of the CPL or GNU LGPL. 
+Any modifications or additions to files from LZMA SDK, however, 
+are subject to the GNU LGPL or CPL terms.
+
+SPECIAL EXCEPTION allows you to use LZMA SDK in applications with closed code, 
+while you keep LZMA SDK code unmodified.
+
+
+SPECIAL EXCEPTION #2: Igor Pavlov, as the author of this code, expressly permits 
+you to use this code under the same terms and conditions contained in the License 
+Agreement you have for any previous version of LZMA SDK developed by Igor Pavlov.
+
+SPECIAL EXCEPTION #2 allows owners of proprietary licenses to use latest version 
+of LZMA SDK as update for previous versions.
+
+
+SPECIAL EXCEPTION #3: Igor Pavlov, as the author of this code, expressly permits 
+you to use code of the following files: 
+BranchTypes.h, LzmaTypes.h, LzmaTest.c, LzmaStateTest.c, LzmaAlone.cpp, 
+LzmaAlone.cs, LzmaAlone.java
+as public domain code. 
+
+
+4) Proprietary license
+
+LZMA SDK also can be available under a proprietary license which 
+can include:
+
+1) Right to modify code without subjecting modified code to the 
+terms of the CPL or GNU LGPL
+2) Technical support for code
+
+To request such proprietary license or any additional consultations,
+send email message from that page:
+http://www.7-zip.org/support.html
+
+
+You should have received a copy of the GNU Lesser General Public
+License along with this library; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+
+You should have received a copy of the Common Public License
+along with this library.
+
+
+LZMA SDK Contents
+-----------------
+
+LZMA SDK includes:
+
+  - C++ source code of LZMA compressing and decompressing
+  - ANSI-C compatible source code for LZMA decompressing
+  - C# source code for LZMA compressing and decompressing
+  - Java source code for LZMA compressing and decompressing
+  - Compiled file->file LZMA compressing/decompressing program for Windows system
+
+ANSI-C LZMA decompression code was ported from original C++ sources to C.
+Also it was simplified and optimized for code size. 
+But it is fully compatible with LZMA from 7-Zip.
+
+
+UNIX/Linux version 
+------------------
+To compile C++ version of file->file LZMA, go to directory
+C/7zip/Compress/LZMA_Alone 
+and type "make" or "make clean all" to recompile all.
+
+In some UNIX/Linux versions you must compile LZMA with static libraries.
+To compile with static libraries, change string in makefile
+LIB = -lm
+to string  
+LIB = -lm -static
+
+
+Files
+---------------------
+C        - C source code
+CPP      - CPP source code
+CS       - C# source code
+Java     - Java source code
+lzma.txt - LZMA SDK description (this file)
+7zFormat.txt - 7z Format description
+7zC.txt  - 7z ANSI-C Decoder description (this file)
+methods.txt  - Compression method IDs for .7z
+LGPL.txt - GNU Lesser General Public License
+CPL.html - Common Public License
+lzma.exe - Compiled file->file LZMA encoder/decoder for Windows
+history.txt - history of the LZMA SDK
+
+
+Source code structure
+---------------------
+
+C  - C files
+    Compress - files related to compression/decompression
+      Lz     - files related to LZ (Lempel-Ziv) compression algorithm
+      Lzma   - ANSI-C compatible LZMA decompressor
+
+        LzmaDecode.h  - interface for LZMA decoding on ANSI-C
+        LzmaDecode.c      - LZMA decoding on ANSI-C (new fastest version)
+        LzmaDecodeSize.c  - LZMA decoding on ANSI-C (old size-optimized version)
+        LzmaTest.c        - test application that decodes LZMA encoded file
+        LzmaTypes.h       - basic types for LZMA Decoder
+        LzmaStateDecode.h - interface for LZMA decoding (State version)
+        LzmaStateDecode.c - LZMA decoding on ANSI-C (State version)
+        LzmaStateTest.c   - test application (State version)
+
+      Branch       - Filters for x86, IA-64, ARM, ARM-Thumb, PowerPC and SPARC code
+
+    Archive - files related to archiving
+      7z_C     - 7z ANSI-C Decoder
+
+
+CPP -- CPP files
+
+  Common  - common files for C++ projects
+  Windows - common files for Windows related code
+  7zip    - files related to 7-Zip Project
+
+    Common   - common files for 7-Zip
+
+    Compress - files related to compression/decompression
+
+      LZ     - files related to LZ (Lempel-Ziv) compression algorithm
+
+      Copy         - Copy coder
+      RangeCoder   - Range Coder (special code of compression/decompression)
+      LZMA         - LZMA compression/decompression on C++
+      LZMA_Alone   - file->file LZMA compression/decompression
+
+      Branch       - Filters for x86, IA-64, ARM, ARM-Thumb, PowerPC and SPARC code
+
+    Archive - files related to archiving
+
+      Common   - common files for archive handling
+      7z       - 7z C++ Encoder/Decoder
+
+    Bundles    - Modules that are bundles of other modules
+  
+      Alone7z           - 7zr.exe: Standalone version of 7z.exe that supports only 7z/LZMA/BCJ/BCJ2
+      Format7zR         - 7zr.dll: Reduced version of 7za.dll: extracting/compressing to 7z/LZMA/BCJ/BCJ2
+      Format7zExtractR  - 7zxr.dll: Reduced version of 7zxa.dll: extracting from 7z/LZMA/BCJ/BCJ2.
+
+    UI        - User Interface files
+         
+      Client7z - Test application for 7za.dll,  7zr.dll, 7zxr.dll
+      Common   - Common UI files
+      Console  - Code for console archiver
+
+
+
+CS - C# files
+  7zip
+    Common   - some common files for 7-Zip
+    Compress - files related to compression/decompression
+      LZ     - files related to LZ (Lempel-Ziv) compression algorithm
+      LZMA         - LZMA compression/decompression
+      LzmaAlone    - file->file LZMA compression/decompression
+      RangeCoder   - Range Coder (special code of compression/decompression)
+
+Java  - Java files
+  SevenZip
+    Compression    - files related to compression/decompression
+      LZ           - files related to LZ (Lempel-Ziv) compression algorithm
+      LZMA         - LZMA compression/decompression
+      RangeCoder   - Range Coder (special code of compression/decompression)
+
+C/C++ source code of LZMA SDK is part of 7-Zip project.
+
+You can find ANSI-C LZMA decompressing code at folder 
+  C/7zip/Compress/Lzma
+7-Zip doesn't use that ANSI-C LZMA code and that code was developed 
+specially for this SDK. And files from C/7zip/Compress/Lzma do not need 
+files from other directories of SDK for compiling.
+
+7-Zip source code can be downloaded from 7-Zip's SourceForge page:
+
+  http://sourceforge.net/projects/sevenzip/
+
+
+LZMA features
+-------------
+  - Variable dictionary size (up to 1 GB)
+  - Estimated compressing speed: about 1 MB/s on 1 GHz CPU
+  - Estimated decompressing speed: 
+      - 8-12 MB/s on 1 GHz Intel Pentium 3 or AMD Athlon
+      - 500-1000 KB/s on 100 MHz ARM, MIPS, PowerPC or other simple RISC
+  - Small memory requirements for decompressing (8-32 KB + DictionarySize)
+  - Small code size for decompressing: 2-8 KB (depending from 
+    speed optimizations) 
+
+LZMA decoder uses only integer operations and can be 
+implemented in any modern 32-bit CPU (or on 16-bit CPU with some conditions).
+
+Some critical operations that affect to speed of LZMA decompression:
+  1) 32*16 bit integer multiply
+  2) Misspredicted branches (penalty mostly depends from pipeline length)
+  3) 32-bit shift and arithmetic operations
+
+Speed of LZMA decompressing mostly depends from CPU speed.
+Memory speed has no big meaning. But if your CPU has small data cache, 
+overall weight of memory speed will slightly increase.
+
+
+How To Use
+----------
+
+Using LZMA encoder/decoder executable
+--------------------------------------
+
+Usage:  LZMA <e|d> inputFile outputFile [<switches>...]
+
+  e: encode file
+
+  d: decode file
+
+  b: Benchmark. There are two tests: compressing and decompressing 
+     with LZMA method. Benchmark shows rating in MIPS (million 
+     instructions per second). Rating value is calculated from 
+     measured speed and it is normalized with AMD Athlon 64 X2 CPU
+     results. Also Benchmark checks possible hardware errors (RAM 
+     errors in most cases). Benchmark uses these settings:
+     (-a1, -d21, -fb32, -mfbt4). You can change only -d. Also you 
+     can change number of iterations. Example for 30 iterations:
+       LZMA b 30
+     Default number of iterations is 10.
+
+<Switches>
+  
+
+  -a{N}:  set compression mode 0 = fast, 1 = normal
+          default: 1 (normal)
+
+  d{N}:   Sets Dictionary size - [0, 30], default: 23 (8MB)
+          The maximum value for dictionary size is 1 GB = 2^30 bytes.
+          Dictionary size is calculated as DictionarySize = 2^N bytes. 
+          For decompressing file compressed by LZMA method with dictionary 
+          size D = 2^N you need about D bytes of memory (RAM).
+
+  -fb{N}: set number of fast bytes - [5, 273], default: 128
+          Usually big number gives a little bit better compression ratio 
+          and slower compression process.
+
+  -lc{N}: set number of literal context bits - [0, 8], default: 3
+          Sometimes lc=4 gives gain for big files.
+
+  -lp{N}: set number of literal pos bits - [0, 4], default: 0
+          lp switch is intended for periodical data when period is 
+          equal 2^N. For example, for 32-bit (4 bytes) 
+          periodical data you can use lp=2. Often it's better to set lc0, 
+          if you change lp switch.
+
+  -pb{N}: set number of pos bits - [0, 4], default: 2
+          pb switch is intended for periodical data 
+          when period is equal 2^N.
+
+  -mf{MF_ID}: set Match Finder. Default: bt4. 
+              Algorithms from hc* group doesn't provide good compression 
+              ratio, but they often works pretty fast in combination with 
+              fast mode (-a0).
+
+              Memory requirements depend from dictionary size 
+              (parameter "d" in table below). 
+
+               MF_ID     Memory                   Description
+
+                bt2    d *  9.5 + 4MB  Binary Tree with 2 bytes hashing.
+                bt3    d * 11.5 + 4MB  Binary Tree with 3 bytes hashing.
+                bt4    d * 11.5 + 4MB  Binary Tree with 4 bytes hashing.
+                hc4    d *  7.5 + 4MB  Hash Chain with 4 bytes hashing.
+
+  -eos:   write End Of Stream marker. By default LZMA doesn't write 
+          eos marker, since LZMA decoder knows uncompressed size 
+          stored in .lzma file header.
+
+  -si:    Read data from stdin (it will write End Of Stream marker).
+  -so:    Write data to stdout
+
+
+Examples:
+
+1) LZMA e file.bin file.lzma -d16 -lc0 
+
+compresses file.bin to file.lzma with 64 KB dictionary (2^16=64K)  
+and 0 literal context bits. -lc0 allows to reduce memory requirements 
+for decompression.
+
+
+2) LZMA e file.bin file.lzma -lc0 -lp2
+
+compresses file.bin to file.lzma with settings suitable 
+for 32-bit periodical data (for example, ARM or MIPS code).
+
+3) LZMA d file.lzma file.bin
+
+decompresses file.lzma to file.bin.
+
+
+Compression ratio hints
+-----------------------
+
+Recommendations
+---------------
+
+To increase compression ratio for LZMA compressing it's desirable 
+to have aligned data (if it's possible) and also it's desirable to locate
+data in such order, where code is grouped in one place and data is 
+grouped in other place (it's better than such mixing: code, data, code,
+data, ...).
+
+
+Using Filters
+-------------
+You can increase compression ratio for some data types, using
+special filters before compressing. For example, it's possible to 
+increase compression ratio on 5-10% for code for those CPU ISAs: 
+x86, IA-64, ARM, ARM-Thumb, PowerPC, SPARC.
+
+You can find C/C++ source code of such filters in folder "7zip/Compress/Branch"
+
+You can check compression ratio gain of these filters with such 
+7-Zip commands (example for ARM code):
+No filter:
+  7z a a1.7z a.bin -m0=lzma
+
+With filter for little-endian ARM code:
+  7z a a2.7z a.bin -m0=bc_arm -m1=lzma        
+
+With filter for big-endian ARM code (using additional Swap4 filter):
+  7z a a3.7z a.bin -m0=swap4 -m1=bc_arm -m2=lzma
+
+It works in such manner:
+Compressing    = Filter_encoding + LZMA_encoding
+Decompressing  = LZMA_decoding + Filter_decoding
+
+Compressing and decompressing speed of such filters is very high,
+so it will not increase decompressing time too much.
+Moreover, it reduces decompression time for LZMA_decoding, 
+since compression ratio with filtering is higher.
+
+These filters convert CALL (calling procedure) instructions 
+from relative offsets to absolute addresses, so such data becomes more 
+compressible. Source code of these CALL filters is pretty simple
+(about 20 lines of C++), so you can convert it from C++ version yourself.
+
+For some ISAs (for example, for MIPS) it's impossible to get gain from such filter.
+
+
+LZMA compressed file format
+---------------------------
+Offset Size Description
+  0     1   Special LZMA properties for compressed data
+  1     4   Dictionary size (little endian)
+  5     8   Uncompressed size (little endian). -1 means unknown size
+ 13         Compressed data
+
+
+ANSI-C LZMA Decoder
+~~~~~~~~~~~~~~~~~~~
+
+To compile ANSI-C LZMA Decoder you can use one of the following files sets:
+1) LzmaDecode.h + LzmaDecode.c + LzmaTest.c  (fastest version)
+2) LzmaDecode.h + LzmaDecodeSize.c + LzmaTest.c  (old size-optimized version)
+3) LzmaStateDecode.h + LzmaStateDecode.c + LzmaStateTest.c  (zlib-like interface)
+
+
+Memory requirements for LZMA decoding
+-------------------------------------
+
+LZMA decoder doesn't allocate memory itself, so you must 
+allocate memory and send it to LZMA.
+
+Stack usage of LZMA decoding function for local variables is not 
+larger than 200 bytes.
+
+How To decompress data
+----------------------
+
+LZMA Decoder (ANSI-C version) now supports 5 interfaces:
+1) Single-call Decompressing
+2) Single-call Decompressing with input stream callback
+3) Multi-call Decompressing with output buffer
+4) Multi-call Decompressing with input callback and output buffer
+5) Multi-call State Decompressing (zlib-like interface)
+
+Variant-5 is similar to Variant-4, but Variant-5 doesn't use callback functions.
+
+Decompressing steps
+-------------------
+
+1) read LZMA properties (5 bytes):
+   unsigned char properties[LZMA_PROPERTIES_SIZE];
+
+2) read uncompressed size (8 bytes, little-endian)
+
+3) Decode properties:
+
+  CLzmaDecoderState state;  /* it's 24-140 bytes structure, if int is 32-bit */
+
+  if (LzmaDecodeProperties(&state.Properties, properties, LZMA_PROPERTIES_SIZE) != LZMA_RESULT_OK)
+    return PrintError(rs, "Incorrect stream properties");
+
+4) Allocate memory block for internal Structures:
+
+  state.Probs = (CProb *)malloc(LzmaGetNumProbs(&state.Properties) * sizeof(CProb));
+  if (state.Probs == 0)
+    return PrintError(rs, kCantAllocateMessage);
+
+  LZMA decoder uses array of CProb variables as internal structure.
+  By default, CProb is unsigned_short. But you can define _LZMA_PROB32 to make 
+  it unsigned_int. It can increase speed on some 32-bit CPUs, but memory 
+  usage will be doubled in that case.
+
+
+5) Main Decompressing
+
+You must use one of the following interfaces:
+
+5.1 Single-call Decompressing
+-----------------------------
+When to use: RAM->RAM decompressing
+Compile files: LzmaDecode.h, LzmaDecode.c
+Compile defines: no defines
+Memory Requirements:
+  - Input buffer: compressed size
+  - Output buffer: uncompressed size
+  - LZMA Internal Structures (~16 KB for default settings) 
+
+Interface:
+  int res = LzmaDecode(&state, 
+      inStream, compressedSize, &inProcessed,
+      outStream, outSize, &outProcessed);
+
+
+5.2 Single-call Decompressing with input stream callback
+--------------------------------------------------------
+When to use: File->RAM or Flash->RAM decompressing.
+Compile files: LzmaDecode.h, LzmaDecode.c
+Compile defines: _LZMA_IN_CB
+Memory Requirements:
+  - Buffer for input stream: any size (for example, 16 KB)
+  - Output buffer: uncompressed size
+  - LZMA Internal Structures (~16 KB for default settings) 
+
+Interface:
+  typedef struct _CBuffer
+  {
+    ILzmaInCallback InCallback;
+    FILE *File;
+    unsigned char Buffer[kInBufferSize];
+  } CBuffer;
+
+  int LzmaReadCompressed(void *object, const unsigned char **buffer, SizeT *size)
+  {
+    CBuffer *bo = (CBuffer *)object;
+    *buffer = bo->Buffer;
+    *size = MyReadFile(bo->File, bo->Buffer, kInBufferSize);
+    return LZMA_RESULT_OK;
+  }
+
+  CBuffer g_InBuffer;
+
+  g_InBuffer.File = inFile;
+  g_InBuffer.InCallback.Read = LzmaReadCompressed;
+  int res = LzmaDecode(&state, 
+      &g_InBuffer.InCallback,
+      outStream, outSize, &outProcessed);
+
+
+5.3 Multi-call decompressing with output buffer
+-----------------------------------------------
+When to use: RAM->File decompressing 
+Compile files: LzmaDecode.h, LzmaDecode.c
+Compile defines: _LZMA_OUT_READ
+Memory Requirements:
+ - Input buffer: compressed size
+ - Buffer for output stream: any size (for example, 16 KB)
+ - LZMA Internal Structures (~16 KB for default settings) 
+ - LZMA dictionary (dictionary size is encoded in stream properties)
+ 
+Interface:
+
+  state.Dictionary = (unsigned char *)malloc(state.Properties.DictionarySize);
+
+  LzmaDecoderInit(&state);
+  do
+  {
+    LzmaDecode(&state,
+      inBuffer, inAvail, &inProcessed,
+      g_OutBuffer, outAvail, &outProcessed);
+    inAvail -= inProcessed;
+    inBuffer += inProcessed;
+  }
+  while you need more bytes
+
+  see LzmaTest.c for more details.
+
+
+5.4 Multi-call decompressing with input callback and output buffer
+------------------------------------------------------------------
+When to use: File->File decompressing 
+Compile files: LzmaDecode.h, LzmaDecode.c
+Compile defines: _LZMA_IN_CB, _LZMA_OUT_READ
+Memory Requirements:
+ - Buffer for input stream: any size (for example, 16 KB)
+ - Buffer for output stream: any size (for example, 16 KB)
+ - LZMA Internal Structures (~16 KB for default settings) 
+ - LZMA dictionary (dictionary size is encoded in stream properties)
+ 
+Interface:
+
+  state.Dictionary = (unsigned char *)malloc(state.Properties.DictionarySize);
+ 
+  LzmaDecoderInit(&state);
+  do
+  {
+    LzmaDecode(&state,
+      &bo.InCallback,
+      g_OutBuffer, outAvail, &outProcessed);
+  }
+  while you need more bytes
+
+  see LzmaTest.c for more details:
+
+
+5.5 Multi-call State Decompressing (zlib-like interface)
+------------------------------------------------------------------
+When to use: file->file decompressing 
+Compile files: LzmaStateDecode.h, LzmaStateDecode.c
+Compile defines:
+Memory Requirements:
+ - Buffer for input stream: any size (for example, 16 KB)
+ - Buffer for output stream: any size (for example, 16 KB)
+ - LZMA Internal Structures (~16 KB for default settings) 
+ - LZMA dictionary (dictionary size is encoded in stream properties)
+ 
+Interface:
+
+  state.Dictionary = (unsigned char *)malloc(state.Properties.DictionarySize);
+
+  
+  LzmaDecoderInit(&state);
+  do
+  {
+    res = LzmaDecode(&state,
+      inBuffer, inAvail, &inProcessed,
+      g_OutBuffer, outAvail, &outProcessed,
+      finishDecoding);
+    inAvail -= inProcessed;
+    inBuffer += inProcessed;
+  }
+  while you need more bytes
+
+  see LzmaStateTest.c for more details:
+
+
+6) Free all allocated blocks
+
+
+Note
+----
+LzmaDecodeSize.c is size-optimized version of LzmaDecode.c.
+But compiled code of LzmaDecodeSize.c can be larger than 
+compiled code of LzmaDecode.c. So it's better to use 
+LzmaDecode.c in most cases.
+
+
+EXIT codes
+-----------
+
+LZMA decoder can return one of the following codes:
+
+#define LZMA_RESULT_OK 0
+#define LZMA_RESULT_DATA_ERROR 1
+
+If you use callback function for input data and you return some 
+error code, LZMA Decoder also returns that code.
+
+
+
+LZMA Defines
+------------
+
+_LZMA_IN_CB    - Use callback for input data
+
+_LZMA_OUT_READ - Use read function for output data
+
+_LZMA_LOC_OPT  - Enable local speed optimizations inside code.
+                 _LZMA_LOC_OPT is only for LzmaDecodeSize.c (size-optimized version).
+                 _LZMA_LOC_OPT doesn't affect LzmaDecode.c (speed-optimized version)
+                 and LzmaStateDecode.c
+
+_LZMA_PROB32   - It can increase speed on some 32-bit CPUs, 
+                 but memory usage will be doubled in that case
+
+_LZMA_UINT32_IS_ULONG  - Define it if int is 16-bit on your compiler
+                         and long is 32-bit.
+
+_LZMA_SYSTEM_SIZE_T  - Define it if you want to use system's size_t.
+                       You can use it to enable 64-bit sizes supporting
+
+
+
+C++ LZMA Encoder/Decoder 
+~~~~~~~~~~~~~~~~~~~~~~~~
+C++ LZMA code use COM-like interfaces. So if you want to use it, 
+you can study basics of COM/OLE.
+
+By default, LZMA Encoder contains all Match Finders.
+But for compressing it's enough to have just one of them.
+So for reducing size of compressing code you can define:
+  #define COMPRESS_MF_BT
+  #define COMPRESS_MF_BT4
+and it will use only bt4 match finder.
+
+
+---
+
+http://www.7-zip.org
+http://www.7-zip.org/support.html
--- a/misc/libphysfs/physfs.c	Mon Apr 10 09:05:16 2017 -0400
+++ b/misc/libphysfs/physfs.c	Mon Apr 10 12:06:43 2017 -0400
@@ -46,48 +46,6 @@
 } ErrState;
 
 
-/* The various i/o drivers...some of these may not be compiled in. */
-extern const PHYSFS_Archiver __PHYSFS_Archiver_ZIP;
-extern const PHYSFS_Archiver __PHYSFS_Archiver_LZMA;
-extern const PHYSFS_Archiver __PHYSFS_Archiver_GRP;
-extern const PHYSFS_Archiver __PHYSFS_Archiver_QPAK;
-extern const PHYSFS_Archiver __PHYSFS_Archiver_HOG;
-extern const PHYSFS_Archiver __PHYSFS_Archiver_MVL;
-extern const PHYSFS_Archiver __PHYSFS_Archiver_WAD;
-extern const PHYSFS_Archiver __PHYSFS_Archiver_DIR;
-extern const PHYSFS_Archiver __PHYSFS_Archiver_ISO9660;
-
-static const PHYSFS_Archiver *staticArchivers[] =
-{
-#if PHYSFS_SUPPORTS_ZIP
-    &__PHYSFS_Archiver_ZIP,
-#endif
-#if PHYSFS_SUPPORTS_7Z
-    &__PHYSFS_Archiver_LZMA,
-#endif
-#if PHYSFS_SUPPORTS_GRP
-    &__PHYSFS_Archiver_GRP,
-#endif
-#if PHYSFS_SUPPORTS_QPAK
-    &__PHYSFS_Archiver_QPAK,
-#endif
-#if PHYSFS_SUPPORTS_HOG
-    &__PHYSFS_Archiver_HOG,
-#endif
-#if PHYSFS_SUPPORTS_MVL
-    &__PHYSFS_Archiver_MVL,
-#endif
-#if PHYSFS_SUPPORTS_WAD
-    &__PHYSFS_Archiver_WAD,
-#endif
-#if PHYSFS_SUPPORTS_ISO9660
-    &__PHYSFS_Archiver_ISO9660,
-#endif
-    NULL
-};
-
-
-
 /* General PhysicsFS state ... */
 static int initialized = 0;
 static ErrState *errorStates = NULL;
@@ -101,6 +59,7 @@
 static int allowSymLinks = 0;
 static const PHYSFS_Archiver **archivers = NULL;
 static const PHYSFS_ArchiveInfo **archiveInfo = NULL;
+static volatile size_t numArchivers = 0;
 
 /* mutexes ... */
 static void *errorLock = NULL;     /* protects error message list.        */
@@ -486,7 +445,7 @@
     memcpy(retval, io, sizeof (PHYSFS_Io));
     retval->opaque = newfh;
     return retval;
-
+    
 handleIo_dupe_failed:
     if (newfh)
     {
@@ -580,7 +539,7 @@
 
     if (ecd.errcode)
     {
-        __PHYSFS_setError(ecd.errcode);
+        PHYSFS_setErrorCode(ecd.errcode);
         return NULL;
     } /* if */
 
@@ -655,7 +614,7 @@
 {
     /*
      * Quicksort w/ Bubblesort fallback algorithm inspired by code from here:
-     *   http://www.cs.ubc.ca/spider/harrison/Java/sorting-demo.html
+     *   https://www.cs.ubc.ca/spider/harrison/Java/sorting-demo.html
      */
     if (max > 0)
         __PHYSFS_quick_sort(entries, 0, max - 1, cmpfn, swapfn);
@@ -692,7 +651,64 @@
 } /* findErrorForCurrentThread */
 
 
-void __PHYSFS_setError(const PHYSFS_ErrorCode errcode)
+/* this doesn't reset the error state. */
+static inline PHYSFS_ErrorCode currentErrorCode(void)
+{
+    const ErrState *err = findErrorForCurrentThread();
+    return err ? err->code : PHYSFS_ERR_OK;
+} /* currentErrorCode */
+
+
+PHYSFS_ErrorCode PHYSFS_getLastErrorCode(void)
+{
+    ErrState *err = findErrorForCurrentThread();
+    const PHYSFS_ErrorCode retval = (err) ? err->code : PHYSFS_ERR_OK;
+    if (err)
+        err->code = PHYSFS_ERR_OK;
+    return retval;
+} /* PHYSFS_getLastErrorCode */
+
+
+PHYSFS_DECL const char *PHYSFS_getErrorByCode(PHYSFS_ErrorCode code)
+{
+    switch (code)
+    {
+        case PHYSFS_ERR_OK: return "no error";
+        case PHYSFS_ERR_OTHER_ERROR: return "unknown error";
+        case PHYSFS_ERR_OUT_OF_MEMORY: return "out of memory";
+        case PHYSFS_ERR_NOT_INITIALIZED: return "not initialized";
+        case PHYSFS_ERR_IS_INITIALIZED: return "already initialized";
+        case PHYSFS_ERR_ARGV0_IS_NULL: return "argv[0] is NULL";
+        case PHYSFS_ERR_UNSUPPORTED: return "unsupported";
+        case PHYSFS_ERR_PAST_EOF: return "past end of file";
+        case PHYSFS_ERR_FILES_STILL_OPEN: return "files still open";
+        case PHYSFS_ERR_INVALID_ARGUMENT: return "invalid argument";
+        case PHYSFS_ERR_NOT_MOUNTED: return "not mounted";
+        case PHYSFS_ERR_NOT_FOUND: return "not found";
+        case PHYSFS_ERR_SYMLINK_FORBIDDEN: return "symlinks are forbidden";
+        case PHYSFS_ERR_NO_WRITE_DIR: return "write directory is not set";
+        case PHYSFS_ERR_OPEN_FOR_READING: return "file open for reading";
+        case PHYSFS_ERR_OPEN_FOR_WRITING: return "file open for writing";
+        case PHYSFS_ERR_NOT_A_FILE: return "not a file";
+        case PHYSFS_ERR_READ_ONLY: return "read-only filesystem";
+        case PHYSFS_ERR_CORRUPT: return "corrupted";
+        case PHYSFS_ERR_SYMLINK_LOOP: return "infinite symbolic link loop";
+        case PHYSFS_ERR_IO: return "i/o error";
+        case PHYSFS_ERR_PERMISSION: return "permission denied";
+        case PHYSFS_ERR_NO_SPACE: return "no space available for writing";
+        case PHYSFS_ERR_BAD_FILENAME: return "filename is illegal or insecure";
+        case PHYSFS_ERR_BUSY: return "tried to modify a file the OS needs";
+        case PHYSFS_ERR_DIR_NOT_EMPTY: return "directory isn't empty";
+        case PHYSFS_ERR_OS_ERROR: return "OS reported an error";
+        case PHYSFS_ERR_DUPLICATE: return "duplicate resource";
+        case PHYSFS_ERR_BAD_PASSWORD: return "bad password";
+    } /* switch */
+
+    return NULL;  /* don't know this error code. */
+} /* PHYSFS_getErrorByCode */
+
+
+void PHYSFS_setErrorCode(PHYSFS_ErrorCode errcode)
 {
     ErrState *err;
 
@@ -720,59 +736,6 @@
     } /* if */
 
     err->code = errcode;
-} /* __PHYSFS_setError */
-
-
-PHYSFS_ErrorCode PHYSFS_getLastErrorCode(void)
-{
-    ErrState *err = findErrorForCurrentThread();
-    const PHYSFS_ErrorCode retval = (err) ? err->code : PHYSFS_ERR_OK;
-    if (err)
-        err->code = PHYSFS_ERR_OK;
-    return retval;
-} /* PHYSFS_getLastErrorCode */
-
-
-PHYSFS_DECL const char *PHYSFS_getErrorByCode(PHYSFS_ErrorCode code)
-{
-    switch (code)
-    {
-        case PHYSFS_ERR_OK: return "no error";
-        case PHYSFS_ERR_OTHER_ERROR: return "unknown error";
-        case PHYSFS_ERR_OUT_OF_MEMORY: return "out of memory";
-        case PHYSFS_ERR_NOT_INITIALIZED: return "not initialized";
-        case PHYSFS_ERR_IS_INITIALIZED: return "already initialized";
-        case PHYSFS_ERR_ARGV0_IS_NULL: return "argv[0] is NULL";
-        case PHYSFS_ERR_UNSUPPORTED: return "unsupported";
-        case PHYSFS_ERR_PAST_EOF: return "past end of file";
-        case PHYSFS_ERR_FILES_STILL_OPEN: return "files still open";
-        case PHYSFS_ERR_INVALID_ARGUMENT: return "invalid argument";
-        case PHYSFS_ERR_NOT_MOUNTED: return "not mounted";
-        case PHYSFS_ERR_NO_SUCH_PATH: return "no such path";
-        case PHYSFS_ERR_SYMLINK_FORBIDDEN: return "symlinks are forbidden";
-        case PHYSFS_ERR_NO_WRITE_DIR: return "write directory is not set";
-        case PHYSFS_ERR_OPEN_FOR_READING: return "file open for reading";
-        case PHYSFS_ERR_OPEN_FOR_WRITING: return "file open for writing";
-        case PHYSFS_ERR_NOT_A_FILE: return "not a file";
-        case PHYSFS_ERR_READ_ONLY: return "read-only filesystem";
-        case PHYSFS_ERR_CORRUPT: return "corrupted";
-        case PHYSFS_ERR_SYMLINK_LOOP: return "infinite symbolic link loop";
-        case PHYSFS_ERR_IO: return "i/o error";
-        case PHYSFS_ERR_PERMISSION: return "permission denied";
-        case PHYSFS_ERR_NO_SPACE: return "no space available for writing";
-        case PHYSFS_ERR_BAD_FILENAME: return "filename is illegal or insecure";
-        case PHYSFS_ERR_BUSY: return "tried to modify a file the OS needs";
-        case PHYSFS_ERR_DIR_NOT_EMPTY: return "directory isn't empty";
-        case PHYSFS_ERR_OS_ERROR: return "OS reported an error";
-    } /* switch */
-
-    return NULL;  /* don't know this error code. */
-} /* PHYSFS_getErrorByCode */
-
-
-void PHYSFS_setErrorCode(PHYSFS_ErrorCode code)
-{
-    __PHYSFS_setError(code);
 } /* PHYSFS_setErrorCode */
 
 
@@ -866,18 +829,21 @@
     DirHandle *retval = NULL;
     const PHYSFS_Archiver **i;
     const char *ext;
+    int created_io = 0;
 
     assert((io != NULL) || (d != NULL));
 
     if (io == NULL)
     {
         /* DIR gets first shot (unlike the rest, it doesn't deal with files). */
+        extern const PHYSFS_Archiver __PHYSFS_Archiver_DIR;
         retval = tryOpenDir(io, &__PHYSFS_Archiver_DIR, d, forWriting);
         if (retval != NULL)
             return retval;
 
         io = __PHYSFS_createNativeIo(d, forWriting ? 'w' : 'r');
         BAIL_IF_MACRO(!io, ERRPASS, 0);
+        created_io = 1;
     } /* if */
 
     ext = find_filename_extension(d);
@@ -886,14 +852,14 @@
         /* Look for archivers with matching file extensions first... */
         for (i = archivers; (*i != NULL) && (retval == NULL); i++)
         {
-            if (__PHYSFS_stricmpASCII(ext, (*i)->info.extension) == 0)
+            if (__PHYSFS_utf8stricmp(ext, (*i)->info.extension) == 0)
                 retval = tryOpenDir(io, *i, d, forWriting);
         } /* for */
 
         /* failing an exact file extension match, try all the others... */
         for (i = archivers; (*i != NULL) && (retval == NULL); i++)
         {
-            if (__PHYSFS_stricmpASCII(ext, (*i)->info.extension) != 0)
+            if (__PHYSFS_utf8stricmp(ext, (*i)->info.extension) != 0)
                 retval = tryOpenDir(io, *i, d, forWriting);
         } /* for */
     } /* if */
@@ -904,6 +870,9 @@
             retval = tryOpenDir(io, *i, d, forWriting);
     } /* else */
 
+    if ((!retval) && (created_io))
+        io->destroy(io);
+
     BAIL_IF_MACRO(!retval, PHYSFS_ERR_UNSUPPORTED, NULL);
     return retval;
 } /* openDirectory */
@@ -1121,32 +1090,52 @@
 } /* initializeMutexes */
 
 
-static void setDefaultAllocator(void);
+static int doRegisterArchiver(const PHYSFS_Archiver *_archiver);
 
 static int initStaticArchivers(void)
 {
-    const size_t numStaticArchivers = __PHYSFS_ARRAYLEN(staticArchivers);
-    const size_t len = numStaticArchivers * sizeof (void *);
-    size_t i;
-
-    assert(numStaticArchivers > 0);  /* seriously, none at all?! */
-    assert(staticArchivers[numStaticArchivers - 1] == NULL);
-
-    archiveInfo = (const PHYSFS_ArchiveInfo **) allocator.Malloc(len);
-    BAIL_IF_MACRO(!archiveInfo, PHYSFS_ERR_OUT_OF_MEMORY, 0);
-    archivers = (const PHYSFS_Archiver **) allocator.Malloc(len);
-    BAIL_IF_MACRO(!archivers, PHYSFS_ERR_OUT_OF_MEMORY, 0);
-
-    for (i = 0; i < numStaticArchivers - 1; i++)
-        archiveInfo[i] = &staticArchivers[i]->info;
-    archiveInfo[numStaticArchivers - 1] = NULL;
-
-    memcpy(archivers, staticArchivers, len);
+    #define REGISTER_STATIC_ARCHIVER(arc) { \
+        extern const PHYSFS_Archiver __PHYSFS_Archiver_##arc; \
+        if (!doRegisterArchiver(&__PHYSFS_Archiver_##arc)) { \
+            return 0; \
+        } \
+    }
+
+    #if PHYSFS_SUPPORTS_ZIP
+        REGISTER_STATIC_ARCHIVER(ZIP);
+    #endif
+    #if PHYSFS_SUPPORTS_7Z
+        REGISTER_STATIC_ARCHIVER(LZMA);
+    #endif
+    #if PHYSFS_SUPPORTS_GRP
+        REGISTER_STATIC_ARCHIVER(GRP);
+    #endif
+    #if PHYSFS_SUPPORTS_QPAK
+        REGISTER_STATIC_ARCHIVER(QPAK);
+    #endif
+    #if PHYSFS_SUPPORTS_HOG
+        REGISTER_STATIC_ARCHIVER(HOG);
+    #endif
+    #if PHYSFS_SUPPORTS_MVL
+        REGISTER_STATIC_ARCHIVER(MVL);
+    #endif
+    #if PHYSFS_SUPPORTS_WAD
+        REGISTER_STATIC_ARCHIVER(WAD);
+    #endif
+    #if PHYSFS_SUPPORTS_SLB
+        REGISTER_STATIC_ARCHIVER(SLB);
+    #endif
+    #if PHYSFS_SUPPORTS_ISO9660
+        REGISTER_STATIC_ARCHIVER(ISO9660);
+    #endif
+
+    #undef REGISTER_STATIC_ARCHIVER
 
     return 1;
 } /* initStaticArchivers */
 
 
+static void setDefaultAllocator(void);
 static int doDeinit(void);
 
 int PHYSFS_init(const char *argv0)
@@ -1183,7 +1172,7 @@
     initialized = 1;
 
     /* This makes sure that the error subsystem is initialized. */
-    __PHYSFS_setError(PHYSFS_getLastErrorCode());
+    PHYSFS_setErrorCode(PHYSFS_getLastErrorCode());
 
     return 1;
 
@@ -1204,7 +1193,7 @@
         PHYSFS_Io *io = i->io;
         next = i->next;
 
-        if (!io->flush(io))
+        if (io->flush && !io->flush(io))
         {
             *list = i;
             return 0;
@@ -1239,14 +1228,70 @@
 } /* freeSearchPath */
 
 
+/* MAKE SURE you hold stateLock before calling this! */
+static int archiverInUse(const PHYSFS_Archiver *arc, const DirHandle *list)
+{
+    const DirHandle *i;
+    for (i = list; i != NULL; i = i->next)
+    {
+        if (i->funcs == arc)
+            return 1;
+    } /* for */
+
+    return 0;  /* not in use */
+} /* archiverInUse */
+
+
+/* MAKE SURE you hold stateLock before calling this! */
+static int doDeregisterArchiver(const size_t idx)
+{
+    const size_t len = (numArchivers - idx) * sizeof (void *);
+    const PHYSFS_ArchiveInfo *info = archiveInfo[idx];
+    const PHYSFS_Archiver *arc = archivers[idx];
+
+    /* make sure nothing is still using this archiver */
+    if (archiverInUse(arc, searchPath) || archiverInUse(arc, writeDir))
+        BAIL_MACRO(PHYSFS_ERR_FILES_STILL_OPEN, 0);
+
+    allocator.Free((void *) info->extension);
+    allocator.Free((void *) info->description);
+    allocator.Free((void *) info->author);
+    allocator.Free((void *) info->url);
+    allocator.Free((void *) arc);
+
+    memmove(&archiveInfo[idx], &archiveInfo[idx+1], len);
+    memmove(&archivers[idx], &archivers[idx+1], len);
+
+    assert(numArchivers > 0);
+    numArchivers--;
+
+    return 1;
+} /* doDeregisterArchiver */
+
+
+/* Does NOT hold the state lock; we're shutting down. */
+static void freeArchivers(void)
+{
+    while (numArchivers > 0)
+    {
+        if (!doDeregisterArchiver(numArchivers - 1))
+            assert(!"nothing should be mounted during shutdown.");
+    } /* while */
+
+    allocator.Free(archivers);
+    allocator.Free(archiveInfo);
+    archivers = NULL;
+    archiveInfo = NULL;
+} /* freeArchivers */
+
+
 static int doDeinit(void)
 {
-    BAIL_IF_MACRO(!__PHYSFS_platformDeinit(), ERRPASS, 0);
-
     closeFileHandleList(&openWriteList);
     BAIL_IF_MACRO(!PHYSFS_setWriteDir(NULL), PHYSFS_ERR_FILES_STILL_OPEN, 0);
 
     freeSearchPath();
+    freeArchivers();
     freeErrorStates();
 
     if (baseDir != NULL)
@@ -1289,6 +1334,10 @@
         allocator.Deinit();
 
     errorLock = stateLock = NULL;
+
+    /* !!! FIXME: what on earth are you supposed to do if this fails? */
+    BAIL_IF_MACRO(!__PHYSFS_platformDeinit(), ERRPASS, 0);
+
     return 1;
 } /* doDeinit */
 
@@ -1306,6 +1355,143 @@
 } /* PHYSFS_isInit */
 
 
+char *__PHYSFS_strdup(const char *str)
+{
+    char *retval = (char *) allocator.Malloc(strlen(str) + 1);
+    if (retval)
+        strcpy(retval, str);
+    return retval;
+} /* __PHYSFS_strdup */
+
+
+PHYSFS_uint32 __PHYSFS_hashString(const char *str, size_t len)
+{
+    PHYSFS_uint32 hash = 5381;
+    while (len--)
+        hash = ((hash << 5) + hash) ^ *(str++);
+    return hash;
+} /* __PHYSFS_hashString */
+
+
+/* MAKE SURE you hold stateLock before calling this! */
+static int doRegisterArchiver(const PHYSFS_Archiver *_archiver)
+{
+    const PHYSFS_uint32 maxver = CURRENT_PHYSFS_ARCHIVER_API_VERSION;
+    const size_t len = (numArchivers + 2) * sizeof (void *);
+    PHYSFS_Archiver *archiver = NULL;
+    PHYSFS_ArchiveInfo *info = NULL;
+    const char *ext = NULL;
+    void *ptr = NULL;
+    size_t i;
+
+    BAIL_IF_MACRO(!_archiver, PHYSFS_ERR_INVALID_ARGUMENT, 0);
+    BAIL_IF_MACRO(_archiver->version > maxver, PHYSFS_ERR_UNSUPPORTED, 0);
+    BAIL_IF_MACRO(!_archiver->info.extension, PHYSFS_ERR_INVALID_ARGUMENT, 0);
+    BAIL_IF_MACRO(!_archiver->info.description, PHYSFS_ERR_INVALID_ARGUMENT, 0);
+    BAIL_IF_MACRO(!_archiver->info.author, PHYSFS_ERR_INVALID_ARGUMENT, 0);
+    BAIL_IF_MACRO(!_archiver->info.url, PHYSFS_ERR_INVALID_ARGUMENT, 0);
+    BAIL_IF_MACRO(!_archiver->openArchive, PHYSFS_ERR_INVALID_ARGUMENT, 0);
+    BAIL_IF_MACRO(!_archiver->enumerateFiles, PHYSFS_ERR_INVALID_ARGUMENT, 0);
+    BAIL_IF_MACRO(!_archiver->openRead, PHYSFS_ERR_INVALID_ARGUMENT, 0);
+    BAIL_IF_MACRO(!_archiver->openWrite, PHYSFS_ERR_INVALID_ARGUMENT, 0);
+    BAIL_IF_MACRO(!_archiver->openAppend, PHYSFS_ERR_INVALID_ARGUMENT, 0);
+    BAIL_IF_MACRO(!_archiver->remove, PHYSFS_ERR_INVALID_ARGUMENT, 0);
+    BAIL_IF_MACRO(!_archiver->mkdir, PHYSFS_ERR_INVALID_ARGUMENT, 0);
+    BAIL_IF_MACRO(!_archiver->closeArchive, PHYSFS_ERR_INVALID_ARGUMENT, 0);
+    BAIL_IF_MACRO(!_archiver->stat, PHYSFS_ERR_INVALID_ARGUMENT, 0);
+
+    ext = _archiver->info.extension;
+    for (i = 0; i < numArchivers; i++)
+    {
+        if (__PHYSFS_utf8stricmp(archiveInfo[i]->extension, ext) == 0)
+            BAIL_MACRO(PHYSFS_ERR_DUPLICATE, 0);  /* !!! FIXME: better error? ERR_IN_USE? */
+    } /* for */
+
+    /* make a copy of the data. */
+    archiver = (PHYSFS_Archiver *) allocator.Malloc(sizeof (*archiver));
+    GOTO_IF_MACRO(!archiver, PHYSFS_ERR_OUT_OF_MEMORY, regfailed);
+
+    /* Must copy sizeof (OLD_VERSION_OF_STRUCT) when version changes! */
+    memcpy(archiver, _archiver, sizeof (*archiver));
+
+    info = (PHYSFS_ArchiveInfo *) &archiver->info;
+    memset(info, '\0', sizeof (*info));  /* NULL in case an alloc fails. */
+    #define CPYSTR(item) \
+        info->item = __PHYSFS_strdup(_archiver->info.item); \
+        GOTO_IF_MACRO(!info->item, PHYSFS_ERR_OUT_OF_MEMORY, regfailed);
+    CPYSTR(extension);
+    CPYSTR(description);
+    CPYSTR(author);
+    CPYSTR(url);
+    info->supportsSymlinks = _archiver->info.supportsSymlinks;
+    #undef CPYSTR
+
+    ptr = allocator.Realloc(archiveInfo, len);
+    GOTO_IF_MACRO(!ptr, PHYSFS_ERR_OUT_OF_MEMORY, regfailed);
+    archiveInfo = (const PHYSFS_ArchiveInfo **) ptr;
+
+    ptr = allocator.Realloc(archivers, len);
+    GOTO_IF_MACRO(!ptr, PHYSFS_ERR_OUT_OF_MEMORY, regfailed);
+    archivers = (const PHYSFS_Archiver **) ptr;
+
+    archiveInfo[numArchivers] = info;
+    archiveInfo[numArchivers + 1] = NULL;
+
+    archivers[numArchivers] = archiver;
+    archivers[numArchivers + 1] = NULL;
+
+    numArchivers++;
+
+    return 1;
+
+regfailed:
+    if (info != NULL)
+    {
+        allocator.Free((void *) info->extension);
+        allocator.Free((void *) info->description);
+        allocator.Free((void *) info->author);
+        allocator.Free((void *) info->url);
+    } /* if */
+    allocator.Free(archiver);
+
+    return 0;
+} /* doRegisterArchiver */
+
+
+int PHYSFS_registerArchiver(const PHYSFS_Archiver *archiver)
+{
+    int retval;
+    BAIL_IF_MACRO(!initialized, PHYSFS_ERR_NOT_INITIALIZED, 0);
+    __PHYSFS_platformGrabMutex(stateLock);
+    retval = doRegisterArchiver(archiver);
+    __PHYSFS_platformReleaseMutex(stateLock);
+    return retval;
+} /* PHYSFS_registerArchiver */
+
+
+int PHYSFS_deregisterArchiver(const char *ext)
+{
+    size_t i;
+
+    BAIL_IF_MACRO(!initialized, PHYSFS_ERR_NOT_INITIALIZED, 0);
+    BAIL_IF_MACRO(!ext, PHYSFS_ERR_INVALID_ARGUMENT, 0);
+
+    __PHYSFS_platformGrabMutex(stateLock);
+    for (i = 0; i < numArchivers; i++)
+    {
+        if (__PHYSFS_utf8stricmp(archiveInfo[i]->extension, ext) == 0)
+        {
+            const int retval = doDeregisterArchiver(i);
+            __PHYSFS_platformReleaseMutex(stateLock);
+            return retval;
+        } /* if */
+    } /* for */
+    __PHYSFS_platformReleaseMutex(stateLock);
+
+    BAIL_MACRO(PHYSFS_ERR_NOT_FOUND, 0);
+} /* PHYSFS_deregisterArchiver */
+
+
 const PHYSFS_ArchiveInfo **PHYSFS_supportedArchiveTypes(void)
 {
     BAIL_IF_MACRO(!initialized, PHYSFS_ERR_NOT_INITIALIZED, NULL);
@@ -1351,7 +1537,6 @@
     PHYSFS_Stat statbuf;
     char *ptr = NULL;
     char *endstr = NULL;
-    int exists = 0;
 
     BAIL_IF_MACRO(!initialized, PHYSFS_ERR_NOT_INITIALIZED, 0);
     BAIL_IF_MACRO(!org, PHYSFS_ERR_INVALID_ARGUMENT, NULL);
@@ -1368,7 +1553,7 @@
     assert(*endstr == dirsep);
     *endstr = '\0';  /* mask out the final dirsep for now. */
 
-    if (!__PHYSFS_platformStat(prefDir, &exists, &statbuf))
+    if (!__PHYSFS_platformStat(prefDir, &statbuf))
     {
         for (ptr = strchr(prefDir, dirsep); ptr; ptr = strchr(ptr+1, dirsep))
         {
@@ -1698,7 +1883,7 @@
             if ((l > extlen) && ((*i)[l - extlen - 1] == '.'))
             {
                 ext = (*i) + (l - extlen);
-                if (__PHYSFS_stricmpASCII(ext, archiveExt) == 0)
+                if (__PHYSFS_utf8stricmp(ext, archiveExt) == 0)
                     setSaneCfgAddPath(*i, l, dirsep, archivesFirst);
             } /* if */
         } /* for */
@@ -1759,12 +1944,12 @@
         size_t len = strlen(fname);
         assert(mntpntlen > 1); /* root mount points should be NULL. */
         /* not under the mountpoint, so skip this archive. */
-        BAIL_IF_MACRO(len < mntpntlen-1, PHYSFS_ERR_NO_SUCH_PATH, 0);
+        BAIL_IF_MACRO(len < mntpntlen-1, PHYSFS_ERR_NOT_FOUND, 0);
         /* !!! FIXME: Case insensitive? */
         retval = strncmp(h->mountPoint, fname, mntpntlen-1);
-        BAIL_IF_MACRO(retval != 0, PHYSFS_ERR_NO_SUCH_PATH, 0);
+        BAIL_IF_MACRO(retval != 0, PHYSFS_ERR_NOT_FOUND, 0);
         if (len > mntpntlen-1)  /* corner case... */
-            BAIL_IF_MACRO(fname[mntpntlen-1]!='/', PHYSFS_ERR_NO_SUCH_PATH, 0);
+            BAIL_IF_MACRO(fname[mntpntlen-1]!='/', PHYSFS_ERR_NOT_FOUND, 0);
         fname += mntpntlen-1;  /* move to start of actual archive path. */
         if (*fname == '/')
             fname++;
@@ -1782,9 +1967,12 @@
             end = strchr(start, '/');
 
             if (end != NULL) *end = '\0';
-            rc = h->funcs->stat(h->opaque, fname, &retval, &statbuf);
+            rc = h->funcs->stat(h->opaque, fname, &statbuf);
             if (rc)
                 rc = (statbuf.filetype == PHYSFS_FILETYPE_SYMLINK);
+            else if (currentErrorCode() == PHYSFS_ERR_NOT_FOUND)
+                retval = 0;
+
             if (end != NULL) *end = '/';
 
             /* insecure path (has a disallowed symlink in it)? */
@@ -1840,7 +2028,9 @@
         if (exists)
         {
             PHYSFS_Stat statbuf;
-            const int rc = h->funcs->stat(h->opaque, dname, &exists, &statbuf);
+            const int rc = h->funcs->stat(h->opaque, dname, &statbuf);
+            if ((!rc) && (currentErrorCode() == PHYSFS_ERR_NOT_FOUND))
+                exists = 0;
             retval = ((rc) && (statbuf.filetype == PHYSFS_FILETYPE_DIRECTORY));
         } /* if */
 
@@ -1937,11 +2127,9 @@
             else if (verifyPath(i, &arcfname, 0))
             {
                 PHYSFS_Stat statbuf;
-                int exists = 0;
-                if (i->funcs->stat(i->opaque, arcfname, &exists, &statbuf))
+                if (i->funcs->stat(i->opaque, arcfname, &statbuf))
                 {
-                    if (exists)
-                        retval = i->dirName;
+                    retval = i->dirName;
                     break;
                 } /* if */
             } /* if */
@@ -2060,6 +2248,40 @@
 } /* enumerateFromMountPoint */
 
 
+typedef struct SymlinkFilterData
+{
+    PHYSFS_EnumFilesCallback callback;
+    void *callbackData;
+    DirHandle *dirhandle;
+} SymlinkFilterData;
+
+/* !!! FIXME: broken if in a virtual mountpoint (stat call fails). */
+static void enumCallbackFilterSymLinks(void *_data, const char *origdir,
+                                       const char *fname)
+{
+    const char *trimmedDir = (*origdir == '/') ? (origdir+1) : origdir;
+    const size_t slen = strlen(trimmedDir) + strlen(fname) + 2;
+    char *path = (char *) __PHYSFS_smallAlloc(slen);
+
+    if (path != NULL)
+    {
+        SymlinkFilterData *data = (SymlinkFilterData *) _data;
+        const DirHandle *dh = data->dirhandle;
+        PHYSFS_Stat statbuf;
+
+        sprintf(path, "%s%s%s", trimmedDir, *trimmedDir ? "/" : "", fname);
+        if (dh->funcs->stat(dh->opaque, path, &statbuf))
+        {
+            /* Pass it on to the application if it's not a symlink. */
+            if (statbuf.filetype != PHYSFS_FILETYPE_SYMLINK)
+                data->callback(data->callbackData, origdir, fname);
+        } /* if */
+
+        __PHYSFS_smallFree(path);
+    } /* if */
+} /* enumCallbackFilterSymLinks */
+
+
 /* !!! FIXME: this should report error conditions. */
 void PHYSFS_enumerateFilesCallback(const char *_fname,
                                    PHYSFS_EnumFilesCallback callback,
@@ -2078,10 +2300,17 @@
     if (sanitizePlatformIndependentPath(_fname, fname))
     {
         DirHandle *i;
-        int noSyms;
+        SymlinkFilterData filterdata;
 
         __PHYSFS_platformGrabMutex(stateLock);
-        noSyms = !allowSymLinks;
+
+        if (!allowSymLinks)
+        {
+            memset(&filterdata, '\0', sizeof (filterdata));
+            filterdata.callback = callback;
+            filterdata.callbackData = data;
+        } /* if */
+
         for (i = searchPath; i != NULL; i = i->next)
         {
             char *arcfname = fname;
@@ -2090,8 +2319,18 @@
 
             else if (verifyPath(i, &arcfname, 0))
             {
-                i->funcs->enumerateFiles(i->opaque, arcfname, noSyms,
-                                         callback, _fname, data);
+                if ((!allowSymLinks) && (i->funcs->info.supportsSymlinks))
+                {
+                    filterdata.dirhandle = i;
+                    i->funcs->enumerateFiles(i->opaque, arcfname,
+                                             enumCallbackFilterSymLinks,
+                                             _fname, &filterdata);
+                } /* if */
+                else
+                {
+                    i->funcs->enumerateFiles(i->opaque, arcfname,
+                                             callback, _fname, data);
+                } /* else */
             } /* else if */
         } /* for */
         __PHYSFS_platformReleaseMutex(stateLock);
@@ -2212,20 +2451,19 @@
 
     if (sanitizePlatformIndependentPath(_fname, fname))
     {
-        int fileExists = 0;
         DirHandle *i = NULL;
         PHYSFS_Io *io = NULL;
 
         __PHYSFS_platformGrabMutex(stateLock);
 
-        GOTO_IF_MACRO(!searchPath, PHYSFS_ERR_NO_SUCH_PATH, openReadEnd);
-
-        for (i = searchPath; (i != NULL) && (!fileExists); i = i->next)
+        GOTO_IF_MACRO(!searchPath, PHYSFS_ERR_NOT_FOUND, openReadEnd);
+
+        for (i = searchPath; i != NULL; i = i->next)
         {
             char *arcfname = fname;
             if (verifyPath(i, &arcfname, 0))
             {
-                io = i->funcs->openRead(i->opaque, arcfname, &fileExists);
+                io = i->funcs->openRead(i->opaque, arcfname);
                 if (io)
                     break;
             } /* if */
@@ -2330,20 +2568,21 @@
         memcpy(buffer, fh->buffer + fh->bufpos, (size_t) len);
         fh->bufpos += (PHYSFS_uint32) len;
         return (PHYSFS_sint64) len;
-    } /* else if */
-
-    if (buffered > 0) /* partially in the buffer... */
+    } /* if */
+
+    else if (buffered > 0) /* partially in the buffer... */
     {
         memcpy(buffer, fh->buffer + fh->bufpos, (size_t) buffered);
         buffer = ((PHYSFS_uint8 *) buffer) + buffered;
         len -= buffered;
         retval = buffered;
-        fh->buffill = fh->bufpos = 0;
     } /* if */
 
     /* if you got here, the buffer is drained and we still need bytes. */
     assert(len > 0);
 
+    fh->buffill = fh->bufpos = 0;
+
     io = fh->io;
     if (len >= fh->bufsize)  /* need more than the buffer takes. */
     {
@@ -2582,7 +2821,7 @@
     rc = io->write(io, fh->buffer + fh->bufpos, fh->buffill - fh->bufpos);
     BAIL_IF_MACRO(rc <= 0, ERRPASS, 0);
     fh->bufpos = fh->buffill = 0;
-    return io->flush(io);
+    return io->flush ? io->flush(io) : 1;
 } /* PHYSFS_flush */
 
 
@@ -2592,11 +2831,11 @@
     char *fname;
     size_t len;
 
-    BAIL_IF_MACRO(!_fname, PHYSFS_ERR_INVALID_ARGUMENT, -1);
-    BAIL_IF_MACRO(!stat, PHYSFS_ERR_INVALID_ARGUMENT, -1);
+    BAIL_IF_MACRO(!_fname, PHYSFS_ERR_INVALID_ARGUMENT, 0);
+    BAIL_IF_MACRO(!stat, PHYSFS_ERR_INVALID_ARGUMENT, 0);
     len = strlen(_fname) + 1;
     fname = (char *) __PHYSFS_smallAlloc(len);
-    BAIL_IF_MACRO(!fname, PHYSFS_ERR_OUT_OF_MEMORY, -1);
+    BAIL_IF_MACRO(!fname, PHYSFS_ERR_OUT_OF_MEMORY, 0);
 
     /* set some sane defaults... */
     stat->filesize = -1;
@@ -2634,7 +2873,9 @@
                     /* !!! FIXME: this test is wrong and should be elsewhere. */
                     stat->readonly = !(writeDir &&
                                  (strcmp(writeDir->dirName, i->dirName) == 0));
-                    retval = i->funcs->stat(i->opaque, arcfname, &exists, stat);
+                    retval = i->funcs->stat(i->opaque, arcfname, stat);
+                    if ((retval) || (currentErrorCode() != PHYSFS_ERR_NOT_FOUND))
+                        exists = 1;
                 } /* else if */
             } /* for */
             __PHYSFS_platformReleaseMutex(stateLock);
--- a/misc/libphysfs/physfs.h	Mon Apr 10 09:05:16 2017 -0400
+++ b/misc/libphysfs/physfs.h	Mon Apr 10 12:06:43 2017 -0400
@@ -8,7 +8,7 @@
  * \mainpage PhysicsFS
  *
  * The latest version of PhysicsFS can be found at:
- *     http://icculus.org/physfs/
+ *     https://icculus.org/physfs/
  *
  * PhysicsFS; a portable, flexible file i/o abstraction.
  *
@@ -20,10 +20,6 @@
  *   - It's flexible. Archives (.ZIP files) can be used transparently as
  *      directory structures.
  *
- * This system is largely inspired by Quake 3's PK3 files and the related
- *  fs_* cvars. If you've ever tinkered with these, then this API will be
- *  familiar to you.
- *
  * With PhysicsFS, you have a single writing directory and multiple
  *  directories (the "search path") for reading. You can think of this as a
  *  filesystem within a filesystem. If (on Windows) you were to set the
@@ -128,9 +124,9 @@
  *
  * PhysicsFS is mostly thread safe. The error messages returned by
  *  PHYSFS_getLastError() are unique by thread, and library-state-setting
- *  functions are mutex'd. For efficiency, individual file accesses are
- *  not locked, so you can not safely read/write/seek/close/etc the same
- *  file from two threads at the same time. Other race conditions are bugs
+ *  functions are mutex'd. For efficiency, individual file accesses are 
+ *  not locked, so you can not safely read/write/seek/close/etc the same 
+ *  file from two threads at the same time. Other race conditions are bugs 
  *  that should be reported/patched.
  *
  * While you CAN use stdio/syscall file access in a program that has PHYSFS_*
@@ -403,6 +399,8 @@
  *          supported.
  *
  * \sa PHYSFS_supportedArchiveTypes
+ * \sa PHYSFS_registerArchiver
+ * \sa PHYSFS_deregisterArchiver
  */
 typedef struct PHYSFS_ArchiveInfo
 {
@@ -410,6 +408,7 @@
     const char *description; /**< Human-readable archive description. */
     const char *author;      /**< Person who did support for this archive. */
     const char *url;         /**< URL related to this archive */
+    int supportsSymlinks;    /**< non-zero if archive offers symbolic links. */
 } PHYSFS_ArchiveInfo;
 
 
@@ -577,9 +576,13 @@
  *
  * The return values are pointers to internal memory, and should
  *  be considered READ ONLY, and never freed. The returned values are
- *  valid until the next call to PHYSFS_deinit().
+ *  valid until the next call to PHYSFS_deinit(), PHYSFS_registerArchiver(),
+ *  or PHYSFS_deregisterArchiver().
  *
  *   \return READ ONLY Null-terminated array of READ ONLY structures.
+ *
+ * \sa PHYSFS_registerArchiver
+ * \sa PHYSFS_deregisterArchiver
  */
 PHYSFS_DECL const PHYSFS_ArchiveInfo **PHYSFS_supportedArchiveTypes(void);
 
@@ -1094,8 +1097,9 @@
  * We've got [z.sav].
  * We've got [w.sav].\endverbatim
  *
- * Feel free to sort the list however you like. We only promise there will
- *  be no duplicates, but not what order the final list will come back in.
+ * Feel free to sort the list however you like. However, the returned data
+ *  will always contain no duplicates, and will be always sorted in alphabetic
+ *  (rather: Unicode) order for you.
  *
  * Don't forget to call PHYSFS_freeList() with the return value from this
  *  function when you are done with it.
@@ -1546,7 +1550,7 @@
  *    \param val value to convert
  *   \return converted value.
  *
- * \warning Remember, PHYSFS_uint64 is only 32 bits on platforms without
+ * \warning Remember, PHYSFS_sint64 is only 32 bits on platforms without
  *          any sort of 64-bit support.
  */
 PHYSFS_DECL PHYSFS_sint64 PHYSFS_swapSLE64(PHYSFS_sint64 val);
@@ -1629,7 +1633,7 @@
  *    \param val value to convert
  *   \return converted value.
  *
- * \warning Remember, PHYSFS_uint64 is only 32 bits on platforms without
+ * \warning Remember, PHYSFS_sint64 is only 32 bits on platforms without
  *          any sort of 64-bit support.
  */
 PHYSFS_DECL PHYSFS_sint64 PHYSFS_swapSBE64(PHYSFS_sint64 val);
@@ -1993,7 +1997,7 @@
  *   \return zero on failure, non-zero on success. On failure, you can
  *           find out what went wrong from PHYSFS_getLastError().
  *
- * \warning Remember, PHYSFS_uint64 is only 32 bits on platforms without
+ * \warning Remember, PHYSFS_sint64 is only 32 bits on platforms without
  *          any sort of 64-bit support.
  */
 PHYSFS_DECL int PHYSFS_writeSLE64(PHYSFS_File *file, PHYSFS_sint64 val);
@@ -2029,7 +2033,7 @@
  *   \return zero on failure, non-zero on success. On failure, you can
  *           find out what went wrong from PHYSFS_getLastError().
  *
- * \warning Remember, PHYSFS_uint64 is only 32 bits on platforms without
+ * \warning Remember, PHYSFS_sint64 is only 32 bits on platforms without
  *          any sort of 64-bit support.
  */
 PHYSFS_DECL int PHYSFS_writeSBE64(PHYSFS_File *file, PHYSFS_sint64 val);
@@ -2604,10 +2608,10 @@
  */
 typedef enum PHYSFS_FileType
 {
-    PHYSFS_FILETYPE_REGULAR, /**< a normal file */
-    PHYSFS_FILETYPE_DIRECTORY, /**< a directory */
-    PHYSFS_FILETYPE_SYMLINK, /**< a symlink */
-    PHYSFS_FILETYPE_OTHER /**< something completely different like a device */
+	PHYSFS_FILETYPE_REGULAR, /**< a normal file */
+	PHYSFS_FILETYPE_DIRECTORY, /**< a directory */
+	PHYSFS_FILETYPE_SYMLINK, /**< a symlink */
+	PHYSFS_FILETYPE_OTHER /**< something completely different like a device */
 } PHYSFS_FileType;
 
 /**
@@ -2628,12 +2632,12 @@
  */
 typedef struct PHYSFS_Stat
 {
-    PHYSFS_sint64 filesize; /**< size in bytes, -1 for non-files and unknown */
-    PHYSFS_sint64 modtime;  /**< last modification time */
-    PHYSFS_sint64 createtime; /**< like modtime, but for file creation time */
-    PHYSFS_sint64 accesstime; /**< like modtime, but for file access time */
-    PHYSFS_FileType filetype; /**< File? Directory? Symlink? */
-    int readonly; /**< non-zero if read only, zero if writable. */
+	PHYSFS_sint64 filesize; /**< size in bytes, -1 for non-files and unknown */
+	PHYSFS_sint64 modtime;  /**< last modification time */
+	PHYSFS_sint64 createtime; /**< like modtime, but for file creation time */
+	PHYSFS_sint64 accesstime; /**< like modtime, but for file access time */
+	PHYSFS_FileType filetype; /**< File? Directory? Symlink? */
+	int readonly; /**< non-zero if read only, zero if writable. */
 } PHYSFS_Stat;
 
 /**
@@ -3133,7 +3137,7 @@
     PHYSFS_ERR_FILES_STILL_OPEN, /**< Files still open.                     */
     PHYSFS_ERR_INVALID_ARGUMENT, /**< Bad parameter passed to an function.  */
     PHYSFS_ERR_NOT_MOUNTED,      /**< Requested archive/dir not mounted.    */
-    PHYSFS_ERR_NO_SUCH_PATH,     /**< No such file, directory, or parent.   */
+    PHYSFS_ERR_NOT_FOUND,        /**< File (or whatever) not found.         */
     PHYSFS_ERR_SYMLINK_FORBIDDEN,/**< Symlink seen when not permitted.      */
     PHYSFS_ERR_NO_WRITE_DIR,     /**< No write dir has been specified.      */
     PHYSFS_ERR_OPEN_FOR_READING, /**< Wrote to a file opened for reading.   */
@@ -3148,7 +3152,9 @@
     PHYSFS_ERR_BAD_FILENAME,     /**< Filename is bogus/insecure.           */
     PHYSFS_ERR_BUSY,             /**< Tried to modify a file the OS needs.  */
     PHYSFS_ERR_DIR_NOT_EMPTY,    /**< Tried to delete dir with files in it. */
-    PHYSFS_ERR_OS_ERROR          /**< Unspecified OS-level error.           */
+    PHYSFS_ERR_OS_ERROR,         /**< Unspecified OS-level error.           */
+    PHYSFS_ERR_DUPLICATE,        /**< Duplicate entry.                      */
+    PHYSFS_ERR_BAD_PASSWORD      /**< Bad password.                         */
 } PHYSFS_ErrorCode;
 
 
@@ -3311,9 +3317,224 @@
 PHYSFS_DECL const char *PHYSFS_getPrefDir(const char *org, const char *app);
 
 
+/**
+ * \struct PHYSFS_Archiver
+ * \brief Abstract interface to provide support for user-defined archives.
+ *
+ * \warning This is advanced, hardcore stuff. You don't need this unless you
+ *          really know what you're doing. Most apps will not need this.
+ *
+ * Historically, PhysicsFS provided a means to mount various archive file
+ *  formats, and physical directories in the native filesystem. However,
+ *  applications have been limited to the file formats provided by the
+ *  library. This interface allows an application to provide their own
+ *  archive file types.
+ *
+ * Conceptually, a PHYSFS_Archiver provides directory entries, while
+ *  PHYSFS_Io provides data streams for those directory entries. The most
+ *  obvious use of PHYSFS_Archiver is to provide support for an archive
+ *  file type that isn't provided by PhysicsFS directly: perhaps some
+ *  proprietary format that only your application needs to understand.
+ *
+ * Internally, all the built-in archive support uses this interface, so the
+ *  best examples for building a PHYSFS_Archiver is the source code to
+ *  PhysicsFS itself.
+ *
+ * An archiver is added to the system with PHYSFS_registerArchiver(), and then
+ *  it will be available for use automatically with PHYSFS_mount(); if a
+ *  given archive can be handled with your archiver, it will be given control
+ *  as appropriate.
+ *
+ * These methods deal with dir handles. You have one instance of your
+ *  archiver, and it generates a unique, opaque handle for each opened
+ *  archive in its openArchive() method. Since the lifetime of an Archiver
+ *  (not an archive) is generally the entire lifetime of the process, and it's
+ *  assumed to be a singleton, we do not provide any instance data for the
+ *  archiver itself; the app can just use some static variables if necessary.
+ *
+ * Symlinks should always be followed (except in stat()); PhysicsFS will
+ *  use the stat() method to check for symlinks and make a judgement on
+ *  whether to continue to call other methods based on that.
+ *
+ * Archivers, when necessary, should set the PhysicsFS error state with
+ *  PHYSFS_setErrorCode() before returning. PhysicsFS will pass these errors
+ *  back to the application unmolested in most cases.
+ *
+ * Thread safety: TO BE DECIDED.  !!! FIXME
+ *
+ * \sa PHYSFS_registerArchiver
+ * \sa PHYSFS_deregisterArchiver
+ * \sa PHYSFS_supportedArchiveTypes
+ */
+typedef struct PHYSFS_Archiver
+{
+
+// !!! FIXME: split read/write interfaces?
+
+    /**
+     * \brief Binary compatibility information.
+     *
+     * This must be set to zero at this time. Future versions of this
+     *  struct will increment this field, so we know what a given
+     *  implementation supports. We'll presumably keep supporting older
+     *  versions as we offer new features, though.
+     */
+    PHYSFS_uint32 version;
+
+    /**
+     * \brief Basic info about this archiver.
+     *
+     * This is used to identify your archive, and is returned in
+     *  PHYSFS_supportedArchiveTypes().
+     */
+    PHYSFS_ArchiveInfo info;
+
+// !!! FIXME: documentation: \brief?
+    /**
+     * \brief
+     *
+     * Open an archive provided by (io).
+     *  (name) is a filename associated with (io), but doesn't necessarily
+     *  map to anything, let alone a real filename. This possibly-
+     *  meaningless name is in platform-dependent notation.
+     * (forWrite) is non-zero if this is to be used for
+     *  the write directory, and zero if this is to be used for an
+     *  element of the search path.
+     * Return NULL on failure. We ignore any error code you set here;
+     *  when PHYSFS_mount() returns, the error will be PHYSFS_ERR_UNSUPPORTED
+     *  (no Archivers could handle this data).  // !!! FIXME: yeah?
+     *  Returns non-NULL on success. The pointer returned will be
+     *  passed as the "opaque" parameter for later calls.
+     */
+    void *(*openArchive)(PHYSFS_Io *io, const char *name, int forWrite);
+
+    /**
+     * List all files in (dirname). Each file is passed to (cb),
+     *  where a copy is made if appropriate, so you should dispose of
+     *  it properly upon return from the callback.
+     * If you have a failure, report as much as you can.
+     *  (dirname) is in platform-independent notation.
+     */
+    void (*enumerateFiles)(void *opaque, const char *dirname,
+                           PHYSFS_EnumFilesCallback cb,
+                           const char *origdir, void *callbackdata);
+
+    /**
+     * Open file for reading.
+     *  This filename, (fnm), is in platform-independent notation.
+     * If you can't handle multiple opens of the same file,
+     *  you can opt to fail for the second call.
+     * Fail if the file does not exist.
+     * Returns NULL on failure, and calls PHYSFS_setErrorCode().
+     *  Returns non-NULL on success. The pointer returned will be
+     *  passed as the "opaque" parameter for later file calls.
+     */
+    PHYSFS_Io *(*openRead)(void *opaque, const char *fnm);
+
+    /**
+     * Open file for writing.
+     * If the file does not exist, it should be created. If it exists,
+     *  it should be truncated to zero bytes. The writing
+     *  offset should be the start of the file.
+     * This filename is in platform-independent notation.
+     * If you can't handle multiple opens of the same file,
+     *  you can opt to fail for the second call.
+     * Returns NULL on failure, and calls PHYSFS_setErrorCode().
+     *  Returns non-NULL on success. The pointer returned will be
+     *  passed as the "opaque" parameter for later file calls.
+     */
+    PHYSFS_Io *(*openWrite)(void *opaque, const char *filename);
+
+    /**
+     * Open file for appending.
+     * If the file does not exist, it should be created. The writing
+     *  offset should be the end of the file.
+     * This filename is in platform-independent notation.
+     * If you can't handle multiple opens of the same file,
+     *  you can opt to fail for the second call.
+     * Returns NULL on failure, and calls PHYSFS_setErrorCode().
+     *  Returns non-NULL on success. The pointer returned will be
+     *  passed as the "opaque" parameter for later file calls.
+     */
+    PHYSFS_Io *(*openAppend)(void *opaque, const char *filename);
+
+    /**
+     * Delete a file in the archive/directory.
+     *  Return non-zero on success, zero on failure.
+     *  This filename is in platform-independent notation.
+     *  This method may be NULL.
+     * On failure, call PHYSFS_setErrorCode().
+     */
+    int (*remove)(void *opaque, const char *filename);
+
+    /**
+     * Create a directory in the archive/directory.
+     *  If the application is trying to make multiple dirs, PhysicsFS
+     *  will split them up into multiple calls before passing them to
+     *  your driver.
+     *  Return non-zero on success, zero on failure.
+     *  This filename is in platform-independent notation.
+     *  This method may be NULL.
+     * On failure, call PHYSFS_setErrorCode().
+     */
+    int (*mkdir)(void *opaque, const char *filename);
+
+    /**
+     * Obtain basic file metadata.
+     *  Returns non-zero on success, zero on failure.
+     *  On failure, call PHYSFS_setErrorCode().
+     */
+    int (*stat)(void *opaque, const char *fn, PHYSFS_Stat *stat);
+
+    /**
+     * Close directories/archives, and free any associated memory,
+     *  including the original PHYSFS_Io and (opaque) itself, if
+     *  applicable. Implementation can assume that it won't be called if
+     *  there are still files open from this archive.
+     */
+    void (*closeArchive)(void *opaque);
+} PHYSFS_Archiver;
+
+/**
+ * \fn int PHYSFS_registerArchiver(const PHYSFS_Archiver *archiver)
+ * \brief Add a new archiver to the system.
+ *
+ * !!! FIXME: write me.
+ *
+ * You may not have two archivers that handle the same extension. If you are
+ *  going to have a clash, you can deregister the other archiver (including
+ *  built-in ones) with PHYSFS_deregisterArchiver().
+ *
+ * The data in (archiver) is copied; you may free this pointer when this
+ *  function returns.
+ *
+ *   \param archiver The archiver to register.
+ *  \return Zero on error, non-zero on success.
+ *
+ * \sa PHYSFS_Archiver
+ * \sa PHYSFS_deregisterArchiver
+ */
+PHYSFS_DECL int PHYSFS_registerArchiver(const PHYSFS_Archiver *archiver);
+
+/**
+ * \fn int PHYSFS_deregisterArchiver(const char *ext)
+ * \brief Remove an archiver from the system.
+ *
+ * !!! FIXME: write me.
+ *
+ * This fails if there are any archives still open that use this archiver.
+ *
+ *   \param ext Filename extension that the archiver handles.
+ *  \return Zero on error, non-zero on success.
+ *
+ * \sa PHYSFS_Archiver
+ * \sa PHYSFS_registerArchiver
+ */
+PHYSFS_DECL int PHYSFS_deregisterArchiver(const char *ext);
+
+
 /* Everything above this line is part of the PhysicsFS 2.1 API. */
 
-
 #ifdef __cplusplus
 }
 #endif
--- a/misc/libphysfs/physfs_casefolding.h	Mon Apr 10 09:05:16 2017 -0400
+++ b/misc/libphysfs/physfs_casefolding.h	Mon Apr 10 12:06:43 2017 -0400
@@ -1,5 +1,5 @@
 /*
- * This file is part of PhysicsFS (http://icculus.org/physfs/)
+ * This file is part of PhysicsFS (https://icculus.org/physfs/)
  *
  * This data generated by physfs/extras/makecasefoldhashtable.pl ...
  * Do not manually edit this file!
--- a/misc/libphysfs/physfs_internal.h	Mon Apr 10 09:05:16 2017 -0400
+++ b/misc/libphysfs/physfs_internal.h	Mon Apr 10 12:06:43 2017 -0400
@@ -114,6 +114,9 @@
 #ifndef PHYSFS_SUPPORTS_WAD
 #define PHYSFS_SUPPORTS_WAD 0
 #endif
+#ifndef PHYSFS_SUPPORTS_SLB
+#define PHYSFS_SUPPORTS_SLB 0
+#endif
 #ifndef PHYSFS_SUPPORTS_ISO9660
 #define PHYSFS_SUPPORTS_ISO9660 0
 #endif
@@ -121,162 +124,27 @@
 /* The latest supported PHYSFS_Io::version value. */
 #define CURRENT_PHYSFS_IO_API_VERSION 0
 
-/* Opaque data for file and dir handlers... */
-typedef void PHYSFS_Dir;
-
-typedef struct
-{
-    /*
-     * Basic info about this archiver...
-     */
-    const PHYSFS_ArchiveInfo info;
-
-
-    /*
-     * DIRECTORY ROUTINES:
-     * These functions are for dir handles. Generate a handle with the
-     *  openArchive() method, then pass it as the "opaque" PHYSFS_Dir to the
-     *  others.
-     *
-     * Symlinks should always be followed (except in stat()); PhysicsFS will
-     *  use the stat() method to check for symlinks and make a judgement on
-     *  whether to continue to call other methods based on that.
-     */
-
-        /*
-         * Open a dirhandle for dir/archive data provided by (io).
-         *  (name) is a filename associated with (io), but doesn't necessarily
-         *  map to anything, let alone a real filename. This possibly-
-         *  meaningless name is in platform-dependent notation.
-         * (forWrite) is non-zero if this is to be used for
-         *  the write directory, and zero if this is to be used for an
-         *  element of the search path.
-         * Returns NULL on failure. We ignore any error code you set here.
-         *  Returns non-NULL on success. The pointer returned will be
-         *  passed as the "opaque" parameter for later calls.
-         */
-    PHYSFS_Dir *(*openArchive)(PHYSFS_Io *io, const char *name, int forWrite);
-
-        /*
-         * List all files in (dirname). Each file is passed to (cb),
-         *  where a copy is made if appropriate, so you should dispose of
-         *  it properly upon return from the callback.
-         * You should omit symlinks if (omitSymLinks) is non-zero.
-         * If you have a failure, report as much as you can.
-         *  (dirname) is in platform-independent notation.
-         */
-    void (*enumerateFiles)(PHYSFS_Dir *opaque, const char *dirname,
-                           int omitSymLinks, PHYSFS_EnumFilesCallback cb,
-                           const char *origdir, void *callbackdata);
-
-        /*
-         * Open file for reading.
-         *  This filename, (fnm), is in platform-independent notation.
-         * If you can't handle multiple opens of the same file,
-         *  you can opt to fail for the second call.
-         * Fail if the file does not exist.
-         * Returns NULL on failure, and calls __PHYSFS_setError().
-         *  Returns non-NULL on success. The pointer returned will be
-         *  passed as the "opaque" parameter for later file calls.
-         *
-         * Regardless of success or failure, please set *exists to
-         *  non-zero if the file existed (even if it's a broken symlink!),
-         *  zero if it did not.
-         */
-    PHYSFS_Io *(*openRead)(PHYSFS_Dir *opaque, const char *fnm, int *exists);
+/* The latest supported PHYSFS_Archiver::version value. */
+#define CURRENT_PHYSFS_ARCHIVER_API_VERSION 0
 
-        /*
-         * Open file for writing.
-         * If the file does not exist, it should be created. If it exists,
-         *  it should be truncated to zero bytes. The writing
-         *  offset should be the start of the file.
-         * This filename is in platform-independent notation.
-         * If you can't handle multiple opens of the same file,
-         *  you can opt to fail for the second call.
-         * Returns NULL on failure, and calls __PHYSFS_setError().
-         *  Returns non-NULL on success. The pointer returned will be
-         *  passed as the "opaque" parameter for later file calls.
-         */
-    PHYSFS_Io *(*openWrite)(PHYSFS_Dir *opaque, const char *filename);
-
-        /*
-         * Open file for appending.
-         * If the file does not exist, it should be created. The writing
-         *  offset should be the end of the file.
-         * This filename is in platform-independent notation.
-         * If you can't handle multiple opens of the same file,
-         *  you can opt to fail for the second call.
-         * Returns NULL on failure, and calls __PHYSFS_setError().
-         *  Returns non-NULL on success. The pointer returned will be
-         *  passed as the "opaque" parameter for later file calls.
-         */
-    PHYSFS_Io *(*openAppend)(PHYSFS_Dir *opaque, const char *filename);
-
-        /*
-         * Delete a file in the archive/directory.
-         *  Return non-zero on success, zero on failure.
-         *  This filename is in platform-independent notation.
-         *  This method may be NULL.
-         * On failure, call __PHYSFS_setError().
-         */
-    int (*remove)(PHYSFS_Dir *opaque, const char *filename);
-
-        /*
-         * Create a directory in the archive/directory.
-         *  If the application is trying to make multiple dirs, PhysicsFS
-         *  will split them up into multiple calls before passing them to
-         *  your driver.
-         *  Return non-zero on success, zero on failure.
-         *  This filename is in platform-independent notation.
-         *  This method may be NULL.
-         * On failure, call __PHYSFS_setError().
-         */
-    int (*mkdir)(PHYSFS_Dir *opaque, const char *filename);
-
-        /*
-         * Close directories/archives, and free any associated memory,
-         *  including the original PHYSFS_Io and (opaque) itself, if
-         *  applicable. Implementation can assume that it won't be called if
-         *  there are still files open from this archive.
-         */
-    void (*closeArchive)(PHYSFS_Dir *opaque);
-
-        /*
-         * Obtain basic file metadata.
-         *  Returns non-zero on success, zero on failure.
-         *  On failure, call __PHYSFS_setError().
-         */
-    int (*stat)(PHYSFS_Dir *opaque, const char *fn,
-                int *exists, PHYSFS_Stat *stat);
-} PHYSFS_Archiver;
-
-
-/*
- * Call this to set the message returned by PHYSFS_getLastError().
- *  Please only use the ERR_* constants above, or add new constants to the
- *  above group, but I want these all in one place.
- *
- * Calling this with a NULL argument is a safe no-op.
- */
-void __PHYSFS_setError(const PHYSFS_ErrorCode err);
-
-
-/* This byteorder stuff was lifted from SDL. http://www.libsdl.org/ */
+/* This byteorder stuff was lifted from SDL. https://www.libsdl.org/ */
 #define PHYSFS_LIL_ENDIAN  1234
 #define PHYSFS_BIG_ENDIAN  4321
 
-#if  defined(__i386__) || defined(__ia64__) || \
-     defined(_M_IX86) || defined(_M_IA64) || defined(_M_X64) || \
-    (defined(__alpha__) || defined(__alpha)) || \
-     defined(__arm__) || defined(ARM) || \
-    (defined(__mips__) && defined(__MIPSEL__)) || \
-     defined(__SYMBIAN32__) || \
-     defined(__x86_64__) || \
-     defined(__LITTLE_ENDIAN__)
-#define PHYSFS_BYTEORDER    PHYSFS_LIL_ENDIAN
+#ifdef __linux__
+#include <endian.h>
+#define PHYSFS_BYTEORDER  __BYTE_ORDER
+#else /* __linux__ */
+#if defined(__hppa__) || \
+    defined(__m68k__) || defined(mc68000) || defined(_M_M68K) || \
+    (defined(__MIPS__) && defined(__MISPEB__)) || \
+    defined(__ppc__) || defined(__POWERPC__) || defined(_M_PPC) || \
+    defined(__sparc__)
+#define PHYSFS_BYTEORDER   PHYSFS_BIG_ENDIAN
 #else
-#define PHYSFS_BYTEORDER    PHYSFS_BIG_ENDIAN
+#define PHYSFS_BYTEORDER   PHYSFS_LIL_ENDIAN
 #endif
+#endif /* __linux__ */
 
 
 /*
@@ -296,8 +164,6 @@
  *  a QuickSort and BubbleSort internally.
  * (cmpfn) is used to determine ordering, and (swapfn) does the actual
  *  swapping of elements in the list.
- *
- *  See zip.c for an example.
  */
 void __PHYSFS_sort(void *entries, size_t max,
                    int (*cmpfn)(void *, size_t, size_t),
@@ -310,14 +176,14 @@
 #define ERRPASS PHYSFS_ERR_OK
 
 /* These get used all over for lessening code clutter. */
-#define BAIL_MACRO(e, r) do { if (e) __PHYSFS_setError(e); return r; } while (0)
-#define BAIL_IF_MACRO(c, e, r) do { if (c) { if (e) __PHYSFS_setError(e); return r; } } while (0)
-#define BAIL_MACRO_MUTEX(e, m, r) do { if (e) __PHYSFS_setError(e); __PHYSFS_platformReleaseMutex(m); return r; } while (0)
-#define BAIL_IF_MACRO_MUTEX(c, e, m, r) do { if (c) { if (e) __PHYSFS_setError(e); __PHYSFS_platformReleaseMutex(m); return r; } } while (0)
-#define GOTO_MACRO(e, g) do { if (e) __PHYSFS_setError(e); goto g; } while (0)
-#define GOTO_IF_MACRO(c, e, g) do { if (c) { if (e) __PHYSFS_setError(e); goto g; } } while (0)
-#define GOTO_MACRO_MUTEX(e, m, g) do { if (e) __PHYSFS_setError(e); __PHYSFS_platformReleaseMutex(m); goto g; } while (0)
-#define GOTO_IF_MACRO_MUTEX(c, e, m, g) do { if (c) { if (e) __PHYSFS_setError(e); __PHYSFS_platformReleaseMutex(m); goto g; } } while (0)
+#define BAIL_MACRO(e, r) do { if (e) PHYSFS_setErrorCode(e); return r; } while (0)
+#define BAIL_IF_MACRO(c, e, r) do { if (c) { if (e) PHYSFS_setErrorCode(e); return r; } } while (0)
+#define BAIL_MACRO_MUTEX(e, m, r) do { if (e) PHYSFS_setErrorCode(e); __PHYSFS_platformReleaseMutex(m); return r; } while (0)
+#define BAIL_IF_MACRO_MUTEX(c, e, m, r) do { if (c) { if (e) PHYSFS_setErrorCode(e); __PHYSFS_platformReleaseMutex(m); return r; } } while (0)
+#define GOTO_MACRO(e, g) do { if (e) PHYSFS_setErrorCode(e); goto g; } while (0)
+#define GOTO_IF_MACRO(c, e, g) do { if (c) { if (e) PHYSFS_setErrorCode(e); goto g; } } while (0)
+#define GOTO_MACRO_MUTEX(e, m, g) do { if (e) PHYSFS_setErrorCode(e); __PHYSFS_platformReleaseMutex(m); goto g; } while (0)
+#define GOTO_IF_MACRO_MUTEX(c, e, m, g) do { if (c) { if (e) PHYSFS_setErrorCode(e); __PHYSFS_platformReleaseMutex(m); goto g; } } while (0)
 
 #define __PHYSFS_ARRAYLEN(x) ( (sizeof (x)) / (sizeof (x[0])) )
 
@@ -381,6 +247,16 @@
  */
 int __PHYSFS_strnicmpASCII(const char *s1, const char *s2, PHYSFS_uint32 l);
 
+/*
+ * Like strdup(), but uses the current PhysicsFS allocator.
+ */
+char *__PHYSFS_strdup(const char *str);
+
+/*
+ * Give a hash value for a C string (uses djb's xor hashing algorithm).
+ */
+PHYSFS_uint32 __PHYSFS_hashString(const char *str, size_t len);
+
 
 /*
  * The current allocator. Not valid before PHYSFS_init is called!
@@ -417,22 +293,22 @@
 
 typedef struct
 {
-    char name[56];
+    char name[64];
     PHYSFS_uint32 startPos;
     PHYSFS_uint32 size;
 } UNPKentry;
 
-void UNPK_closeArchive(PHYSFS_Dir *opaque);
-PHYSFS_Dir *UNPK_openArchive(PHYSFS_Io *io,UNPKentry *e,const PHYSFS_uint32 n);
-void UNPK_enumerateFiles(PHYSFS_Dir *opaque, const char *dname,
-                         int omitSymLinks, PHYSFS_EnumFilesCallback cb,
+void UNPK_closeArchive(void *opaque);
+void *UNPK_openArchive(PHYSFS_Io *io,UNPKentry *e,const PHYSFS_uint32 n);
+void UNPK_enumerateFiles(void *opaque, const char *dname,
+                         PHYSFS_EnumFilesCallback cb,
                          const char *origdir, void *callbackdata);
-PHYSFS_Io *UNPK_openRead(PHYSFS_Dir *opaque, const char *fnm, int *fileExists);
-PHYSFS_Io *UNPK_openWrite(PHYSFS_Dir *opaque, const char *name);
-PHYSFS_Io *UNPK_openAppend(PHYSFS_Dir *opaque, const char *name);
-int UNPK_remove(PHYSFS_Dir *opaque, const char *name);
-int UNPK_mkdir(PHYSFS_Dir *opaque, const char *name);
-int UNPK_stat(PHYSFS_Dir *opaque, const char *fn, int *exist, PHYSFS_Stat *st);
+PHYSFS_Io *UNPK_openRead(void *opaque, const char *name);
+PHYSFS_Io *UNPK_openWrite(void *opaque, const char *name);
+PHYSFS_Io *UNPK_openAppend(void *opaque, const char *name);
+int UNPK_remove(void *opaque, const char *name);
+int UNPK_mkdir(void *opaque, const char *name);
+int UNPK_stat(void *opaque, const char *fn, PHYSFS_Stat *st);
 
 
 /*--------------------------------------------------------------------------*/
@@ -489,7 +365,7 @@
  *  a unique file handle; this is frequently employed to prevent race
  *  conditions in the archivers.
  *
- * Call __PHYSFS_setError() and return (NULL) if the file can't be opened.
+ * Call PHYSFS_setErrorCode() and return (NULL) if the file can't be opened.
  */
 void *__PHYSFS_platformOpenRead(const char *filename);
 
@@ -506,7 +382,7 @@
  *
  * Opening a file for write multiple times has undefined results.
  *
- * Call __PHYSFS_setError() and return (NULL) if the file can't be opened.
+ * Call PHYSFS_setErrorCode() and return (NULL) if the file can't be opened.
  */
 void *__PHYSFS_platformOpenWrite(const char *filename);
 
@@ -524,7 +400,7 @@
  *
  * Opening a file for append multiple times has undefined results.
  *
- * Call __PHYSFS_setError() and return (NULL) if the file can't be opened.
+ * Call PHYSFS_setErrorCode() and return (NULL) if the file can't be opened.
  */
 void *__PHYSFS_platformOpenAppend(const char *filename);
 
@@ -536,7 +412,7 @@
  *  immediately after those bytes.
  *  On success, return (len) and position the file pointer immediately past
  *  the end of the last read byte. Return (-1) if there is a catastrophic
- *  error, and call __PHYSFS_setError() to describe the problem; the file
+ *  error, and call PHYSFS_setErrorCode() to describe the problem; the file
  *  pointer should not move in such a case. A partial read is success; only
  *  return (-1) on total failure; presumably, the next read call after a
  *  partial read will fail as such.
@@ -549,7 +425,7 @@
  *  8-bit bytes from the area pointed to by (buffer). If there is a problem,
  *  return the number of bytes written, and position the file pointer
  *  immediately after those bytes. Return (-1) if there is a catastrophic
- *  error, and call __PHYSFS_setError() to describe the problem; the file
+ *  error, and call PHYSFS_setErrorCode() to describe the problem; the file
  *  pointer should not move in such a case. A partial write is success; only
  *  return (-1) on total failure; presumably, the next write call after a
  *  partial write will fail as such.
@@ -565,7 +441,7 @@
  *
  * Not all file types can seek; this is to be expected by the caller.
  *
- * On error, call __PHYSFS_setError() and return zero. On success, return
+ * On error, call PHYSFS_setErrorCode() and return zero. On success, return
  *  a non-zero value.
  */
 int __PHYSFS_platformSeek(void *opaque, PHYSFS_uint64 pos);
@@ -578,7 +454,7 @@
  *
  * Not all file types can "tell"; this is to be expected by the caller.
  *
- * On error, call __PHYSFS_setError() and return -1. On success, return >= 0.
+ * On error, call PHYSFS_setErrorCode() and return -1. On success, return >= 0.
  */
 PHYSFS_sint64 __PHYSFS_platformTell(void *opaque);
 
@@ -589,7 +465,7 @@
  * The caller expects that this information may not be available for all
  *  file types on all platforms.
  *
- * Return -1 if you can't do it, and call __PHYSFS_setError(). Otherwise,
+ * Return -1 if you can't do it, and call PHYSFS_setErrorCode(). Otherwise,
  *  return the file length in 8-bit bytes.
  */
 PHYSFS_sint64 __PHYSFS_platformFileLength(void *handle);
@@ -598,7 +474,7 @@
 /*
  * !!! FIXME: comment me.
  */
-int __PHYSFS_platformStat(const char *fn, int *exists, PHYSFS_Stat *stat);
+int __PHYSFS_platformStat(const char *fn, PHYSFS_Stat *stat);
 
 /*
  * Flush any pending writes to disk. (opaque) should be cast to whatever data
@@ -672,14 +548,13 @@
 
 /*
  * Enumerate a directory of files. This follows the rules for the
- *  PHYSFS_Archiver->enumerateFiles() method (see above), except that the
+ *  PHYSFS_Archiver::enumerateFiles() method, except that the
  *  (dirName) that is passed to this function is converted to
  *  platform-DEPENDENT notation by the caller. The PHYSFS_Archiver version
  *  uses platform-independent notation. Note that ".", "..", and other
- *  metaentries should always be ignored.
+ *  meta-entries should always be ignored.
  */
 void __PHYSFS_platformEnumerateFiles(const char *dirname,
-                                     int omitSymLinks,
                                      PHYSFS_EnumFilesCallback callback,
                                      const char *origdir,
                                      void *callbackdata);
@@ -726,27 +601,27 @@
 /*
  * Grab possession of a platform-specific mutex. Mutexes should be recursive;
  *  that is, the same thread should be able to call this function multiple
- *  times in a row without causing a deadlock. This function should block
+ *  times in a row without causing a deadlock. This function should block 
  *  until a thread can gain possession of the mutex.
  *
- * Return non-zero if the mutex was grabbed, zero if there was an
- *  unrecoverable problem grabbing it (this should not be a matter of
- *  timing out! We're talking major system errors; block until the mutex
+ * Return non-zero if the mutex was grabbed, zero if there was an 
+ *  unrecoverable problem grabbing it (this should not be a matter of 
+ *  timing out! We're talking major system errors; block until the mutex 
  *  is available otherwise.)
  *
- * _DO NOT_ call __PHYSFS_setError() in here! Since setError calls this
+ * _DO NOT_ call PHYSFS_setErrorCode() in here! Since setErrorCode calls this
  *  function, you'll cause an infinite recursion. This means you can't
  *  use the BAIL_*MACRO* macros, either.
  */
 int __PHYSFS_platformGrabMutex(void *mutex);
 
 /*
- * Relinquish possession of the mutex when this method has been called
+ * Relinquish possession of the mutex when this method has been called 
  *  once for each time that platformGrabMutex was called. Once possession has
  *  been released, the next thread in line to grab the mutex (if any) may
  *  proceed.
  *
- * _DO NOT_ call __PHYSFS_setError() in here! Since setError calls this
+ * _DO NOT_ call PHYSFS_setErrorCode() in here! Since setErrorCode calls this
  *  function, you'll cause an infinite recursion. This means you can't
  *  use the BAIL_*MACRO* macros, either.
  */
--- a/misc/libphysfs/physfs_miniz.h	Mon Apr 10 09:05:16 2017 -0400
+++ b/misc/libphysfs/physfs_miniz.h	Mon Apr 10 12:06:43 2017 -0400
@@ -1,7 +1,7 @@
 /* tinfl.c v1.11 - public domain inflate with zlib header parsing/adler32 checking (inflate-only subset of miniz.c)
    See "unlicense" statement at the end of this file.
    Rich Geldreich <richgel99@gmail.com>, last updated May 20, 2011
-   Implements RFC 1950: http://www.ietf.org/rfc/rfc1950.txt and RFC 1951: http://www.ietf.org/rfc/rfc1951.txt
+   Implements RFC 1950: https://www.ietf.org/rfc/rfc1950.txt and RFC 1951: https://www.ietf.org/rfc/rfc1951.txt
 
    The entire decompressor coroutine is implemented in tinfl_decompress(). The other functions are optional high-level helpers.
 */
@@ -12,7 +12,7 @@
 typedef PHYSFS_sint16 mz_int16;
 typedef PHYSFS_uint16 mz_uint16;
 typedef PHYSFS_uint32 mz_uint32;
-typedef unsigned int mz_uint;
+typedef unsigned int mz_uint; 
 typedef PHYSFS_uint64 mz_uint64;
 
 /* For more compatibility with zlib, miniz.c uses unsigned long for some parameters/struct members. */
@@ -266,7 +266,10 @@
       {
         mz_uint8 *p = r->m_tables[0].m_code_size; mz_uint i;
         r->m_table_sizes[0] = 288; r->m_table_sizes[1] = 32; TINFL_MEMSET(r->m_tables[1].m_code_size, 5, 32);
-        for ( i = 0; i <= 143; ++i) *p++ = 8; for ( ; i <= 255; ++i) *p++ = 9; for ( ; i <= 279; ++i) *p++ = 7; for ( ; i <= 287; ++i) *p++ = 8;
+        for ( i = 0; i <= 143; ++i) *p++ = 8;
+        for ( ; i <= 255; ++i) *p++ = 9;
+        for ( ; i <= 279; ++i) *p++ = 7;
+        for ( ; i <= 287; ++i) *p++ = 8;
       }
       else
       {
@@ -670,7 +673,7 @@
 
 #endif /* #ifndef TINFL_HEADER_FILE_ONLY */
 
-/*
+/* 
   This is free and unencumbered software released into the public domain.
 
   Anyone is free to copy, modify, publish, use, compile, sell, or
@@ -694,5 +697,5 @@
   ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
   OTHER DEALINGS IN THE SOFTWARE.
 
-  For more information, please refer to <http://unlicense.org/>
+  For more information, please refer to <https://unlicense.org/>
 */
--- a/misc/libphysfs/physfs_platforms.h	Mon Apr 10 09:05:16 2017 -0400
+++ b/misc/libphysfs/physfs_platforms.h	Mon Apr 10 12:06:43 2017 -0400
@@ -21,6 +21,10 @@
 #  define PHYSFS_PLATFORM_POSIX 1
 #elif (defined _WIN32_WCE) || (defined _WIN64_WCE)
 #  error PocketPC support was dropped from PhysicsFS 2.1. Sorry.
+#elif ((defined WINAPI_FAMILY) && WINAPI_FAMILY == WINAPI_FAMILY_APP)
+#   define PHYSFS_PLATFORM_WINRT 1
+#   define PHYSFS_NO_CDROM_SUPPORT 1
+#   define PHYSFS_PLATFORM_WINDOWS 1
 #elif (((defined _WIN32) || (defined _WIN64)) && (!defined __CYGWIN__))
 #  define PHYSFS_PLATFORM_WINDOWS 1
 #elif (defined OS2)
@@ -35,6 +39,11 @@
 #  define PHYSFS_PLATFORM_POSIX 1
 #elif defined(macintosh)
 #  error Classic Mac OS support was dropped from PhysicsFS 2.0. Move to OS X.
+#elif defined(ANDROID)
+#  define PHYSFS_PLATFORM_LINUX 1
+#  define PHYSFS_PLATFORM_UNIX 1
+#  define PHYSFS_PLATFORM_POSIX 1
+#  define PHYSFS_NO_CDROM_SUPPORT 1
 #elif defined(__linux)
 #  define PHYSFS_PLATFORM_LINUX 1
 #  define PHYSFS_PLATFORM_UNIX 1
@@ -43,7 +52,12 @@
 #  define PHYSFS_PLATFORM_SOLARIS 1
 #  define PHYSFS_PLATFORM_UNIX 1
 #  define PHYSFS_PLATFORM_POSIX 1
-#elif defined(__FreeBSD__) || defined(__NetBSD__) || defined(__OpenBSD__) || defined(__bsdi__) || defined(__DragonFly__)
+#elif defined(__FreeBSD__) || defined(__DragonFly__)
+#  define PHYSFS_PLATFORM_FREEBSD 1
+#  define PHYSFS_PLATFORM_BSD 1
+#  define PHYSFS_PLATFORM_UNIX 1
+#  define PHYSFS_PLATFORM_POSIX 1
+#elif defined(__NetBSD__) || defined(__OpenBSD__) || defined(__bsdi__)
 #  define PHYSFS_PLATFORM_BSD 1
 #  define PHYSFS_PLATFORM_UNIX 1
 #  define PHYSFS_PLATFORM_POSIX 1
--- a/misc/libphysfs/physfs_unicode.c	Mon Apr 10 09:05:16 2017 -0400
+++ b/misc/libphysfs/physfs_unicode.c	Mon Apr 10 12:06:43 2017 -0400
@@ -4,7 +4,7 @@
 
 /*
  * From rfc3629, the UTF-8 spec:
- *  http://www.ietf.org/rfc/rfc3629.txt
+ *  https://www.ietf.org/rfc/rfc3629.txt
  *
  *   Char. number range  |        UTF-8 octet sequence
  *      (hexadecimal)    |              (binary)
@@ -447,11 +447,27 @@
 static int utf8codepointcmp(const PHYSFS_uint32 cp1, const PHYSFS_uint32 cp2)
 {
     PHYSFS_uint32 folded1[3], folded2[3];
+
+    if (cp1 == cp2)
+        return 0;  /* obviously matches. */
+
     locate_case_fold_mapping(cp1, folded1);
     locate_case_fold_mapping(cp2, folded2);
-    return ( (folded1[0] == folded2[0]) &&
-             (folded1[1] == folded2[1]) &&
-             (folded1[2] == folded2[2]) );
+
+    if (folded1[0] < folded2[0])
+        return -1;
+    else if (folded1[0] > folded2[0])
+        return 1;
+    else if (folded1[1] < folded2[1])
+        return -1;
+    else if (folded1[1] > folded2[1])
+        return 1;
+    else if (folded1[2] < folded2[2])
+        return -1;
+    else if (folded1[2] > folded2[2])
+        return 1;
+
+    return 0;  /* complete match. */
 } /* utf8codepointcmp */
 
 
@@ -461,8 +477,11 @@
     {
         const PHYSFS_uint32 cp1 = utf8codepoint(&str1);
         const PHYSFS_uint32 cp2 = utf8codepoint(&str2);
-        if (!utf8codepointcmp(cp1, cp2)) break;
-        if (cp1 == 0) return 1;
+        const int rc = utf8codepointcmp(cp1, cp2);
+        if (rc != 0)
+            return rc;
+        else if (cp1 == 0)
+            break;  /* complete match. */
     } /* while */
 
     return 0;
@@ -475,12 +494,15 @@
     {
         const PHYSFS_uint32 cp1 = utf8codepoint(&str1);
         const PHYSFS_uint32 cp2 = utf8codepoint(&str2);
-        if (!utf8codepointcmp(cp1, cp2)) return 0;
-        if (cp1 == 0) return 1;
+        const int rc = utf8codepointcmp(cp1, cp2);
+        if (rc != 0)
+            return rc;
+        else if (cp1 == 0)
+            return 0;
         n--;
     } /* while */
 
-    return 1;  /* matched to n chars. */
+    return 0;  /* matched to n chars. */
 } /* __PHYSFS_utf8strnicmp */
 
 
--- a/misc/libphysfs/platform_beos.cpp	Mon Apr 10 09:05:16 2017 -0400
+++ b/misc/libphysfs/platform_beos.cpp	Mon Apr 10 12:06:43 2017 -0400
@@ -87,7 +87,7 @@
 
     /*
      * This function is lifted from Simple Directmedia Layer (SDL):
-     *  http://www.libsdl.org/  ... this is zlib-licensed code, too.
+     *  https://www.libsdl.org/  ... this is zlib-licensed code, too.
      */
 static void tryDir(const char *d, PHYSFS_StringCallback callback, void *data)
 {
--- a/misc/libphysfs/platform_macosx.c	Mon Apr 10 09:05:16 2017 -0400
+++ b/misc/libphysfs/platform_macosx.c	Mon Apr 10 12:06:43 2017 -0400
@@ -29,58 +29,14 @@
 #include "physfs_internal.h"
 
 
-#if defined(__APPLE__)
-#if defined(TARGET_OS_MAC) && MAC_OS_X_VERSION_MAX_ALLOWED <= MAC_OS_X_VERSION_10_4
-/* __eprintf shouldn't have been made visible from libstdc++, or anywhere, but
-   on Mac OS X 10.4 it was defined in libstdc++.6.0.3.dylib; so on that platform
-   we have to keep defining it to keep binary compatibility.
-   We can't just put the libgcc version in the export list, because that
-   doesn't work; once a symbol is marked as hidden, it stays that way.  */
-
-void __eprintf (const char *string, const char *expression,
-            unsigned int line, const char *filename)
-{
-    fprintf(stderr, string, expression, line, filename);
-    fflush(stderr);
-    abort();
-}
-
-
-/* apparently libssp is missing from 10.4 SDK
-   code from http://wiki.osdev.org/GCC_Stack_Smashing_Protector */
-void * __stack_chk_guard = NULL;
-
-void __stack_chk_guard_setup()
-{
-    unsigned char * p;
-    p = (unsigned char *) &__stack_chk_guard;
-
-    /* If you have the ability to generate random numbers in your kernel then use them,
-       otherwise for 32-bit code: *p = 0x00000aff; */
-    *p = random();
-}
-
-void __attribute__((noreturn)) __stack_chk_fail()
-{
-    /* put your panic function or similar in here */
-    unsigned char * vid = (unsigned char *)0xB8000;
-    vid[1] = 7;
-    for(;;)
-    vid[0]++;
-}
-
-#endif
-#endif /* __APPLE__ */
-
-
 /* Wrap PHYSFS_Allocator in a CFAllocator... */
 static CFAllocatorRef cfallocator = NULL;
 
-static CFStringRef cfallocDesc(const void *info)
+static CFStringRef cfallocCopyDesc(const void *info)
 {
     return CFStringCreateWithCString(cfallocator, "PhysicsFS",
                                      kCFStringEncodingASCII);
-} /* cfallocDesc */
+} /* cfallocCopyDesc */
 
 
 static void *cfallocMalloc(CFIndex allocSize, CFOptionFlags hint, void *info)
@@ -109,7 +65,7 @@
     /* set up a CFAllocator, so Carbon can use the physfs allocator, too. */
     CFAllocatorContext ctx;
     memset(&ctx, '\0', sizeof (ctx));
-    ctx.copyDescription = cfallocDesc;
+    ctx.copyDescription = cfallocCopyDesc;
     ctx.allocate = cfallocMalloc;
     ctx.reallocate = cfallocRealloc;
     ctx.deallocate = cfallocFree;
@@ -132,7 +88,7 @@
 
 /*
  * Code based on sample from Apple Developer Connection:
- *  http://developer.apple.com/samplecode/Sample_Code/Devices_and_Hardware/Disks/VolumeToBSDNode/VolumeToBSDNode.c.htm
+ *  https://developer.apple.com/samplecode/Sample_Code/Devices_and_Hardware/Disks/VolumeToBSDNode/VolumeToBSDNode.c.htm
  */
 
 #if !defined(PHYSFS_NO_CDROM_SUPPORT)
@@ -144,7 +100,7 @@
 
     if (!IOObjectConformsTo(service, kIOMediaClass))
         return 0;
-
+        
     wholeMedia = IORegistryEntryCreateCFProperty(service,
                                                  CFSTR(kIOMediaWholeKey),
                                                  cfallocator, 0);
@@ -180,7 +136,7 @@
 
     rc = IORegistryEntryCreateIterator(service, kIOServicePlane,
              kIORegistryIterateRecursively | kIORegistryIterateParents, &iter);
-
+    
     if (!iter)
         return 0;
 
@@ -204,7 +160,7 @@
         } /* if */
         IOObjectRelease(service);
     } while ((service = IOIteratorNext(iter)) && (!retval));
-
+                
     IOObjectRelease(iter);
     IOObjectRelease(service);
 
--- a/misc/libphysfs/platform_posix.c	Mon Apr 10 09:05:16 2017 -0400
+++ b/misc/libphysfs/platform_posix.c	Mon Apr 10 12:06:43 2017 -0400
@@ -41,9 +41,9 @@
         case ELOOP: return PHYSFS_ERR_SYMLINK_LOOP;
         case EMLINK: return PHYSFS_ERR_NO_SPACE;
         case ENAMETOOLONG: return PHYSFS_ERR_BAD_FILENAME;
-        case ENOENT: return PHYSFS_ERR_NO_SUCH_PATH;
+        case ENOENT: return PHYSFS_ERR_NOT_FOUND;
         case ENOSPC: return PHYSFS_ERR_NO_SPACE;
-        case ENOTDIR: return PHYSFS_ERR_NO_SUCH_PATH;
+        case ENOTDIR: return PHYSFS_ERR_NOT_FOUND;
         case EISDIR: return PHYSFS_ERR_NOT_A_FILE;
         case EROFS: return PHYSFS_ERR_READ_ONLY;
         case ETXTBSY: return PHYSFS_ERR_BUSY;
@@ -83,7 +83,7 @@
             } /* if */
         } /* if */
     } /* if */
-
+    
     return retval;
 } /* getUserDirByUID */
 
@@ -122,31 +122,13 @@
 
 
 void __PHYSFS_platformEnumerateFiles(const char *dirname,
-                                     int omitSymLinks,
                                      PHYSFS_EnumFilesCallback callback,
                                      const char *origdir,
                                      void *callbackdata)
 {
     DIR *dir;
     struct dirent *ent;
-    int bufsize = 0;
     char *buf = NULL;
-    int dlen = 0;
-
-    if (omitSymLinks)  /* !!! FIXME: this malloc sucks. */
-    {
-        dlen = strlen(dirname);
-        bufsize = dlen + 256;
-        buf = (char *) allocator.Malloc(bufsize);
-        if (buf == NULL)
-            return;
-        strcpy(buf, dirname);
-        if (buf[dlen - 1] != '/')
-        {
-            buf[dlen++] = '/';
-            buf[dlen] = '\0';
-        } /* if */
-    } /* if */
 
     errno = 0;
     dir = opendir(dirname);
@@ -160,35 +142,9 @@
     {
         if (strcmp(ent->d_name, ".") == 0)
             continue;
-
-        if (strcmp(ent->d_name, "..") == 0)
+        else if (strcmp(ent->d_name, "..") == 0)
             continue;
 
-        if (omitSymLinks)
-        {
-            PHYSFS_Stat statbuf;
-            int exists = 0;
-            char *p;
-            int len = strlen(ent->d_name) + dlen + 1;
-            if (len > bufsize)
-            {
-                p = (char *) allocator.Realloc(buf, len);
-                if (p == NULL)
-                    continue;
-                buf = p;
-                bufsize = len;
-            } /* if */
-
-            strcpy(buf + dlen, ent->d_name);
-
-            if (!__PHYSFS_platformStat(buf, &exists, &statbuf))
-                continue;
-            else if (!exists)
-                continue;  /* probably can't happen, but just in case. */
-            else if (statbuf.filetype == PHYSFS_FILETYPE_SYMLINK)
-                continue;
-        } /* if */
-
         callback(callbackdata, origdir, ent->d_name);
     } /* while */
 
@@ -323,7 +279,8 @@
 int __PHYSFS_platformFlush(void *opaque)
 {
     const int fd = *((int *) opaque);
-    BAIL_IF_MACRO(fsync(fd) == -1, errcodeFromErrno(), 0);
+    if ((fcntl(fd, F_GETFL) & O_ACCMODE) != O_RDONLY)
+        BAIL_IF_MACRO(fsync(fd) == -1, errcodeFromErrno(), 0);
     return 1;
 } /* __PHYSFS_platformFlush */
 
@@ -343,17 +300,11 @@
 } /* __PHYSFS_platformDelete */
 
 
-int __PHYSFS_platformStat(const char *filename, int *exists, PHYSFS_Stat *st)
+int __PHYSFS_platformStat(const char *filename, PHYSFS_Stat *st)
 {
     struct stat statbuf;
 
-    if (lstat(filename, &statbuf) == -1)
-    {
-        *exists = (errno != ENOENT);
-        BAIL_MACRO(errcodeFromErrno(), 0);
-    } /* if */
-
-    *exists = 1;
+    BAIL_IF_MACRO(lstat(filename, &statbuf) == -1, errcodeFromErrno(), 0);
 
     if (S_ISREG(statbuf.st_mode))
     {
@@ -367,6 +318,12 @@
         st->filesize = 0;
     } /* else if */
 
+    else if(S_ISLNK(statbuf.st_mode))
+    {
+        st->filetype = PHYSFS_FILETYPE_SYMLINK;
+        st->filesize = 0;
+    } /* else if */
+
     else
     {
         st->filetype = PHYSFS_FILETYPE_OTHER;
--- a/misc/libphysfs/platform_unix.c	Mon Apr 10 09:05:16 2017 -0400
+++ b/misc/libphysfs/platform_unix.c	Mon Apr 10 12:06:43 2017 -0400
@@ -13,6 +13,7 @@
 
 #include <ctype.h>
 #include <unistd.h>
+#include <stdlib.h>
 #include <sys/types.h>
 #include <pwd.h>
 #include <sys/stat.h>
@@ -20,6 +21,7 @@
 #include <dirent.h>
 #include <time.h>
 #include <errno.h>
+#include <limits.h>
 
 #if PHYSFS_PLATFORM_LINUX && !defined(PHYSFS_HAVE_MNTENT_H)
 #define PHYSFS_HAVE_MNTENT_H 1
@@ -171,7 +173,7 @@
 
         binlen = strlen(bin);
         size = strlen(start) + binlen + 2;
-        if (size > alloc_size)
+        if (size >= alloc_size)
         {
             char *x = (char *) allocator.Realloc(exe, size);
             if (!x)
@@ -193,7 +195,7 @@
 
         if (access(exe, X_OK) == 0)  /* Exists as executable? We're done. */
         {
-            exe[size - binlen - 1] = '\0'; /* chop off filename, leave '/' */
+            exe[(size - binlen) - 1] = '\0'; /* chop off filename, leave '/' */
             return exe;
         } /* if */
 
@@ -244,20 +246,45 @@
     char *retval = NULL;
     const char *envr = NULL;
 
-    /*
-     * Try to avoid using argv0 unless forced to. If there's a Linux-like
-     *  /proc filesystem, you can get the full path to the current process from
-     *  the /proc/self/exe symlink.
+    /* Try to avoid using argv0 unless forced to. Try system-specific stuff. */
+    
+    #if PHYSFS_PLATFORM_FREEBSD
+    {
+        char fullpath[PATH_MAX];
+        size_t buflen = sizeof (fullpath);
+        int mib[4] = { CTL_KERN, KERN_PROC, KERN_PROC_PATHNAME, -1 };
+        if (sysctl(mib, 4, fullpath, &buflen, NULL, 0) != -1)
+            retval = __PHYSFS_strdup(fullpath);
+    }
+    #elif PHYSFS_PLATFORM_SOLARIS
+    {
+        const char *path = getexecname();
+        if ((path != NULL) && (path[0] == '/'))  /* must be absolute path... */
+            retval = __PHYSFS_strdup(path);
+    }
+    #endif
+
+    if (retval)
+        return retval;   /* already got it. */
+
+    /* If there's a Linux-like /proc filesystem, you can get the full path to
+     *  the current process from a symlink in there.
      */
-    retval = readSymLink("/proc/self/exe");
-    if (retval == NULL)
+
+    if (access("/proc", F_OK) == 0)
     {
-        /* older kernels don't have /proc/self ... try PID version... */
-        const unsigned long long pid = (unsigned long long) getpid();
-        char path[64];
-        const int rc = (int) snprintf(path,sizeof(path),"/proc/%llu/exe",pid);
-        if ( (rc > 0) && (rc < sizeof(path)) )
-            retval = readSymLink(path);
+        retval = readSymLink("/proc/self/exe");
+        if (!retval) retval = readSymLink("/proc/curproc/file");
+        if (!retval) retval = readSymLink("/proc/curproc/exe");
+        if (retval == NULL)
+        {
+            /* older kernels don't have /proc/self ... try PID version... */
+            const unsigned long long pid = (unsigned long long) getpid();
+            char path[64];
+            const int rc = (int) snprintf(path,sizeof(path),"/proc/%llu/exe",pid);
+            if ( (rc > 0) && (rc < sizeof(path)) )
+                retval = readSymLink(path);
+        } /* if */
     } /* if */
 
     if (retval != NULL)  /* chop off filename. */
@@ -272,7 +299,7 @@
         } /* else */
     } /* if */
 
-    /* No /proc/self/exe, but we have an argv[0] we can parse? */
+    /* No /proc/self/exe, etc, but we have an argv[0] we can parse? */
     if ((retval == NULL) && (argv0 != NULL))
     {
         /* fast path: default behaviour can handle this. */
@@ -310,7 +337,7 @@
      *  This isn't strictly correct, but the results are relatively sane
      *  in any case.
      *
-     * http://standards.freedesktop.org/basedir-spec/basedir-spec-latest.html
+     * https://standards.freedesktop.org/basedir-spec/basedir-spec-latest.html
      */
     const char *envr = getenv("XDG_DATA_HOME");
     const char *append = "/";
--- a/misc/libphysfs/platform_windows.c	Mon Apr 10 09:05:16 2017 -0400
+++ b/misc/libphysfs/platform_windows.c	Mon Apr 10 12:06:43 2017 -0400
@@ -10,6 +10,7 @@
 #include "physfs_platforms.h"
 
 #ifdef PHYSFS_PLATFORM_WINDOWS
+#ifndef PHYSFS_PLATFORM_WINRT
 
 /* Forcibly disable UNICODE macro, since we manage this ourselves. */
 #ifdef UNICODE
@@ -124,13 +125,13 @@
         case ERROR_INVALID_NAME: return PHYSFS_ERR_BAD_FILENAME;
         case ERROR_BAD_PATHNAME: return PHYSFS_ERR_BAD_FILENAME;
         case ERROR_DIRECTORY: return PHYSFS_ERR_BAD_FILENAME;
-        case ERROR_FILE_NOT_FOUND: return PHYSFS_ERR_NO_SUCH_PATH;
-        case ERROR_PATH_NOT_FOUND: return PHYSFS_ERR_NO_SUCH_PATH;
-        case ERROR_DELETE_PENDING: return PHYSFS_ERR_NO_SUCH_PATH;
-        case ERROR_INVALID_DRIVE: return PHYSFS_ERR_NO_SUCH_PATH;
+        case ERROR_FILE_NOT_FOUND: return PHYSFS_ERR_NOT_FOUND;
+        case ERROR_PATH_NOT_FOUND: return PHYSFS_ERR_NOT_FOUND;
+        case ERROR_DELETE_PENDING: return PHYSFS_ERR_NOT_FOUND;
+        case ERROR_INVALID_DRIVE: return PHYSFS_ERR_NOT_FOUND;
         case ERROR_HANDLE_DISK_FULL: return PHYSFS_ERR_NO_SPACE;
         case ERROR_DISK_FULL: return PHYSFS_ERR_NO_SPACE;
-        /* !!! FIXME: ?? case ENOTDIR: return PHYSFS_ERR_NO_SUCH_PATH; */
+        /* !!! FIXME: ?? case ENOTDIR: return PHYSFS_ERR_NOT_FOUND; */
         /* !!! FIXME: ?? case EISDIR: return PHYSFS_ERR_NOT_A_FILE; */
         case ERROR_WRITE_PROTECT: return PHYSFS_ERR_READ_ONLY;
         case ERROR_LOCK_VIOLATION: return PHYSFS_ERR_BUSY;
@@ -171,7 +172,7 @@
         stem(SEM_FAILCRITICALERRORS, &oldErrorMode);
     else
         oldErrorMode = SetErrorMode(SEM_FAILCRITICALERRORS);
-
+    
     /* Do detection. This may block if a disc is spinning up. */
     for (i = 'A'; i <= 'Z'; i++)
     {
@@ -369,7 +370,7 @@
         } /* while */
 
         if ((ptr == modpath) && (*ptr != '\\'))
-            __PHYSFS_setError(PHYSFS_ERR_OTHER_ERROR);  /* oh well. */
+            PHYSFS_setErrorCode(PHYSFS_ERR_OTHER_ERROR);  /* oh well. */
         else
         {
             *(ptr+1) = '\0';  /* chop off filename. */
@@ -412,6 +413,7 @@
     } /* if */
 
     sprintf(retval, "%s\\%s\\%s\\", utf8, org, app);
+    allocator.Free(utf8);
     return retval;
 } /* __PHYSFS_platformCalcPrefDir */
 
@@ -443,7 +445,7 @@
          *  psize. Also note that the second parameter can't be
          *  NULL or the function fails.
          */
-        rc = pGetDir(accessToken, &dummy, &psize);
+    	rc = pGetDir(accessToken, &dummy, &psize);
         assert(!rc);  /* !!! FIXME: handle this gracefully. */
         (void) rc;
 
@@ -478,16 +480,7 @@
     return ( (void *) ((size_t) GetCurrentThreadId()) );
 } /* __PHYSFS_platformGetThreadID */
 
-
-static int isSymlinkAttrs(const DWORD attr, const DWORD tag)
-{
-    return ( (attr & FILE_ATTRIBUTE_REPARSE_POINT) &&
-             (tag == PHYSFS_IO_REPARSE_TAG_SYMLINK) );
-} /* isSymlinkAttrs */
-
-
 void __PHYSFS_platformEnumerateFiles(const char *dirname,
-                                     int omitSymLinks,
                                      PHYSFS_EnumFilesCallback callback,
                                      const char *origdir,
                                      void *callbackdata)
@@ -529,8 +522,6 @@
 
     do
     {
-        const DWORD attr = entw.dwFileAttributes;
-        const DWORD tag = entw.dwReserved0;
         const WCHAR *fn = entw.cFileName;
         char *utf8;
 
@@ -538,8 +529,6 @@
             continue;
         if ((fn[0] == '.') && (fn[1] == '.') && (fn[2] == '\0'))
             continue;
-        if ((omitSymLinks) && (isSymlinkAttrs(attr, tag)))
-            continue;
 
         utf8 = unicodeToUtf8Heap(fn);
         if (utf8 != NULL)
@@ -720,7 +709,7 @@
     {
         BAIL_MACRO(errcodeFromWinApi(), 0);
     } /* if */
-
+    
     return 1;  /* No error occured */
 } /* __PHYSFS_platformSeek */
 
@@ -876,7 +865,8 @@
     return retval;
 } /* FileTimeToPhysfsTime */
 
-int __PHYSFS_platformStat(const char *filename, int *exists, PHYSFS_Stat *stat)
+
+int __PHYSFS_platformStat(const char *filename, PHYSFS_Stat *st)
 {
     WIN32_FILE_ATTRIBUTE_DATA winstat;
     WCHAR *wstr = NULL;
@@ -887,37 +877,36 @@
     BAIL_IF_MACRO(!wstr, PHYSFS_ERR_OUT_OF_MEMORY, 0);
     rc = GetFileAttributesExW(wstr, GetFileExInfoStandard, &winstat);
     err = (!rc) ? GetLastError() : 0;
-    *exists = ((err != ERROR_FILE_NOT_FOUND) && (err != ERROR_PATH_NOT_FOUND));
     __PHYSFS_smallFree(wstr);
     BAIL_IF_MACRO(!rc, errcodeFromWinApiError(err), 0);
 
-    stat->modtime = FileTimeToPhysfsTime(&winstat.ftLastWriteTime);
-    stat->accesstime = FileTimeToPhysfsTime(&winstat.ftLastAccessTime);
-    stat->createtime = FileTimeToPhysfsTime(&winstat.ftCreationTime);
+    st->modtime = FileTimeToPhysfsTime(&winstat.ftLastWriteTime);
+    st->accesstime = FileTimeToPhysfsTime(&winstat.ftLastAccessTime);
+    st->createtime = FileTimeToPhysfsTime(&winstat.ftCreationTime);
 
     if(winstat.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
     {
-        stat->filetype = PHYSFS_FILETYPE_DIRECTORY;
-        stat->filesize = 0;
+        st->filetype = PHYSFS_FILETYPE_DIRECTORY;
+        st->filesize = 0;
     } /* if */
 
     else if(winstat.dwFileAttributes & (FILE_ATTRIBUTE_OFFLINE | FILE_ATTRIBUTE_DEVICE))
     {
         /* !!! FIXME: what are reparse points? */
-        stat->filetype = PHYSFS_FILETYPE_OTHER;
+        st->filetype = PHYSFS_FILETYPE_OTHER;
         /* !!! FIXME: don't rely on this */
-        stat->filesize = 0;
+        st->filesize = 0;
     } /* else if */
 
     /* !!! FIXME: check for symlinks on Vista. */
 
     else
     {
-        stat->filetype = PHYSFS_FILETYPE_REGULAR;
-        stat->filesize = (((PHYSFS_uint64) winstat.nFileSizeHigh) << 32) | winstat.nFileSizeLow;
+        st->filetype = PHYSFS_FILETYPE_REGULAR;
+        st->filesize = (((PHYSFS_uint64) winstat.nFileSizeHigh) << 32) | winstat.nFileSizeLow;
     } /* else */
 
-    stat->readonly = ((winstat.dwFileAttributes & FILE_ATTRIBUTE_READONLY) != 0);
+    st->readonly = ((winstat.dwFileAttributes & FILE_ATTRIBUTE_READONLY) != 0);
 
     return 1;
 } /* __PHYSFS_platformStat */
@@ -930,6 +919,7 @@
 } /* __PHYSFS_platformSetDefaultAllocator */
 
 #endif  /* PHYSFS_PLATFORM_WINDOWS */
+#endif  /* PHYSFS_PLATFORM_WINRT */
 
 /* end of windows.c ... */
 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/misc/libphysfs/platform_winrt.cpp	Mon Apr 10 12:06:43 2017 -0400
@@ -0,0 +1,676 @@
+/*
+* Windows Runtime support routines for PhysicsFS.
+*
+* Please see the file LICENSE.txt in the source's root directory.
+*
+*  This file is based on "platform_windows.c" by Ryan C. Gordon and Gregory S. Read.
+*  Windows Runtime-specific additions and changes are made by Martin "T-Bone" Ahrnbom. 
+*
+* Instructions for setting up PhysFS in a WinRT Universal 8.1 app in Visual Studio 2013:
+* (hopefully these instructions will be somewhat valid with Windows 10 Apps as well...)
+*
+*  1. In Visual Studio 2013 (or later?), hit File -> New -> Project...
+*  2. On the left, navigate to Templates -> Visual C++ -> Store Apps -> Universal Apps
+*  3. In the middle of the window, select "DLL (Universal Apps)"
+*  4. Near the bottom, give the project a name (like PhysFS-WinRT) and choose a location
+*  5. In the Solution Explorer (to the right typically), delete all .cpp and .h files in
+*     PhysFS-WinRT.Shared except targetver.h.
+*  6. In Windows Explorer, find the "src" folder of the PhysFS source code. Select all files
+* 	  in the folder (ignore the "lzma" folder, we're not including 7Zip support because it's messy to compile).
+*	  Drag and drop all of the source files onto PhysFS-WinRT-Shared in Visual Studio.
+*  7. In Windows Explorer, find the file called "physfs.h". Copy this file into a folder of its own somewhere.
+*	  I suggest naming that folder "include". This will be your "include" folder for any projects using PhysFS.
+*  8. In the Solution Explorer, right click on PhysFS-WinRT.Windows and select Properties. Make sure that "Configuration" is set to 
+*     "All Configurations" and "Platform" is set to "All Platforms" near the top of the window.
+*  9. On the left, select "Precompiled Headers". Change "Precompiled Header" from "Use (/Yu)" to "Not Using Precompiled Headers".
+* 10. On the left, navigate to Configuration Properties -> C/C++ -> Preprocessor. In Preprocessor Definitions, add "_CRT_SECURE_NO_WARNINGS"
+* 11. Hit the OK button.
+* 12. Repeat steps 8-11 but for PhysFS-WinRT.WindowsPhone.
+* 13. In the Solution Explorer, find "platform_winrt.cpp" in PhysFS-WinRT.Shared. Right click on it and select "Properties". 
+* 14. On the left, navigate to Configuration Properties -> C/C++ -> General. On the right, change "Consume Windows Runtime Extensions"
+*	  from "No" to "Yes (/ZW)". Hit "OK".
+* 15. Near the top of the Visual Studio window, select BUILD -> Batch Build... Hit "Select All", and then "Build".
+* 16. Now you have a bunch of .dll and .lib files, as well as an include folder that you can use in your projects!
+* 17. ???
+* 18. Profit!
+*/
+
+/* !!! FIXME: remove the tabstops from this file. */
+/* !!! FIXME: maybe just merge this back into platform_windows.c? */
+
+#define __PHYSICSFS_INTERNAL__
+#include "physfs_platforms.h"
+
+#ifdef PHYSFS_PLATFORM_WINRT
+
+#include "physfs_internal.h"
+
+#include <windows.h>
+#include <errno.h>
+#include <ctype.h>
+#include <time.h>
+
+#define LOWORDER_UINT64(pos) ((PHYSFS_uint32) (pos & 0xFFFFFFFF))
+#define HIGHORDER_UINT64(pos) ((PHYSFS_uint32) ((pos >> 32) & 0xFFFFFFFF))
+
+
+/*
+* Users without the platform SDK don't have this defined.  The original docs
+*  for SetFilePointer() just said to compare with 0xFFFFFFFF, so this should
+*  work as desired.
+*/
+#define PHYSFS_INVALID_SET_FILE_POINTER  0xFFFFFFFF
+
+/* just in case... */
+#define PHYSFS_INVALID_FILE_ATTRIBUTES   0xFFFFFFFF
+
+/* Not defined before the Vista SDK. */
+#define PHYSFS_IO_REPARSE_TAG_SYMLINK    0xA000000C
+
+
+#define UTF8_TO_UNICODE_STACK_MACRO(w_assignto, str) { \
+    if (str == NULL) \
+        w_assignto = NULL; \
+    else { \
+        const PHYSFS_uint64 len = (PHYSFS_uint64) ((strlen(str) + 1) * 2); \
+        w_assignto = (WCHAR *) __PHYSFS_smallAlloc(len); \
+        if (w_assignto != NULL) \
+            PHYSFS_utf8ToUtf16(str, (PHYSFS_uint16 *) w_assignto, len); \
+    } \
+} \
+
+/* Note this counts WCHARs, not codepoints! */
+static PHYSFS_uint64 wStrLen(const WCHAR *wstr)
+{
+	PHYSFS_uint64 len = 0;
+	while (*(wstr++))
+		len++;
+	return len;
+} /* wStrLen */
+
+/* !!! FIXME: do we really need readonly? If not, do we need this struct? */
+typedef struct
+{
+	HANDLE handle;
+	int readonly;
+} WinApiFile;
+
+static HANDLE detectCDThreadHandle = NULL;
+static HWND detectCDHwnd = 0;
+static volatile int initialDiscDetectionComplete = 0;
+static volatile DWORD drivesWithMediaBitmap = 0;
+
+
+static PHYSFS_ErrorCode errcodeFromWinApiError(const DWORD err)
+{
+	/*
+	* win32 error codes are sort of a tricky thing; Microsoft intentionally
+	*  doesn't list which ones a given API might trigger, there are several
+	*  with overlapping and unclear meanings...and there's 16 thousand of
+	*  them in Windows 7. It looks like the ones we care about are in the
+	*  first 500, but I can't say this list is perfect; we might miss
+	*  important values or misinterpret others.
+	*
+	* Don't treat this list as anything other than a work in progress.
+	*/
+	switch (err)
+	{
+	case ERROR_SUCCESS: return PHYSFS_ERR_OK;
+	case ERROR_ACCESS_DENIED: return PHYSFS_ERR_PERMISSION;
+	case ERROR_NETWORK_ACCESS_DENIED: return PHYSFS_ERR_PERMISSION;
+	case ERROR_NOT_READY: return PHYSFS_ERR_IO;
+	case ERROR_CRC: return PHYSFS_ERR_IO;
+	case ERROR_SEEK: return PHYSFS_ERR_IO;
+	case ERROR_SECTOR_NOT_FOUND: return PHYSFS_ERR_IO;
+	case ERROR_NOT_DOS_DISK: return PHYSFS_ERR_IO;
+	case ERROR_WRITE_FAULT: return PHYSFS_ERR_IO;
+	case ERROR_READ_FAULT: return PHYSFS_ERR_IO;
+	case ERROR_DEV_NOT_EXIST: return PHYSFS_ERR_IO;
+		/* !!! FIXME: ?? case ELOOP: return PHYSFS_ERR_SYMLINK_LOOP; */
+	case ERROR_BUFFER_OVERFLOW: return PHYSFS_ERR_BAD_FILENAME;
+	case ERROR_INVALID_NAME: return PHYSFS_ERR_BAD_FILENAME;
+	case ERROR_BAD_PATHNAME: return PHYSFS_ERR_BAD_FILENAME;
+	case ERROR_DIRECTORY: return PHYSFS_ERR_BAD_FILENAME;
+	case ERROR_FILE_NOT_FOUND: return PHYSFS_ERR_NOT_FOUND;
+	case ERROR_PATH_NOT_FOUND: return PHYSFS_ERR_NOT_FOUND;
+	case ERROR_DELETE_PENDING: return PHYSFS_ERR_NOT_FOUND;
+	case ERROR_INVALID_DRIVE: return PHYSFS_ERR_NOT_FOUND;
+	case ERROR_HANDLE_DISK_FULL: return PHYSFS_ERR_NO_SPACE;
+	case ERROR_DISK_FULL: return PHYSFS_ERR_NO_SPACE;
+		/* !!! FIXME: ?? case ENOTDIR: return PHYSFS_ERR_NOT_FOUND; */
+		/* !!! FIXME: ?? case EISDIR: return PHYSFS_ERR_NOT_A_FILE; */
+	case ERROR_WRITE_PROTECT: return PHYSFS_ERR_READ_ONLY;
+	case ERROR_LOCK_VIOLATION: return PHYSFS_ERR_BUSY;
+	case ERROR_SHARING_VIOLATION: return PHYSFS_ERR_BUSY;
+	case ERROR_CURRENT_DIRECTORY: return PHYSFS_ERR_BUSY;
+	case ERROR_DRIVE_LOCKED: return PHYSFS_ERR_BUSY;
+	case ERROR_PATH_BUSY: return PHYSFS_ERR_BUSY;
+	case ERROR_BUSY: return PHYSFS_ERR_BUSY;
+	case ERROR_NOT_ENOUGH_MEMORY: return PHYSFS_ERR_OUT_OF_MEMORY;
+	case ERROR_OUTOFMEMORY: return PHYSFS_ERR_OUT_OF_MEMORY;
+	case ERROR_DIR_NOT_EMPTY: return PHYSFS_ERR_DIR_NOT_EMPTY;
+	default: return PHYSFS_ERR_OS_ERROR;
+	} /* switch */
+} /* errcodeFromWinApiError */
+
+static inline PHYSFS_ErrorCode errcodeFromWinApi(void)
+{
+	return errcodeFromWinApiError(GetLastError());
+} /* errcodeFromWinApi */
+
+
+typedef BOOL(WINAPI *fnSTEM)(DWORD, LPDWORD b);
+
+static DWORD pollDiscDrives(void)
+{
+	// We don't do discs
+	return 0;
+} /* pollDiscDrives */
+
+
+static LRESULT CALLBACK detectCDWndProc(HWND hwnd, UINT msg,
+	WPARAM wp, LPARAM lparam)
+{
+	return FALSE;
+} /* detectCDWndProc */
+
+
+static DWORD WINAPI detectCDThread(LPVOID lpParameter)
+{
+	return 0;
+} /* detectCDThread */
+
+
+void __PHYSFS_platformDetectAvailableCDs(PHYSFS_StringCallback cb, void *data)
+{
+	return;
+} /* __PHYSFS_platformDetectAvailableCDs */
+
+
+static char *unicodeToUtf8Heap(const WCHAR *w_str)
+{
+	char *retval = NULL;
+	if (w_str != NULL)
+	{
+		void *ptr = NULL;
+		const PHYSFS_uint64 len = (wStrLen(w_str) * 4) + 1;
+		retval = (char*)allocator.Malloc(len);
+		BAIL_IF_MACRO(!retval, PHYSFS_ERR_OUT_OF_MEMORY, NULL);
+		PHYSFS_utf8FromUtf16((const PHYSFS_uint16 *)w_str, retval, len);
+		ptr = allocator.Realloc(retval, strlen(retval) + 1); /* shrink. */
+		if (ptr != NULL)
+			retval = (char *)ptr;
+	} /* if */
+	return retval;
+} /* unicodeToUtf8Heap */
+
+char *__PHYSFS_platformCalcBaseDir(const char *argv0)
+{
+	const wchar_t* path = Windows::ApplicationModel::Package::Current->InstalledLocation->Path->Data();
+	wchar_t path2[1024];
+	wcscpy_s(path2, path);
+	wcscat_s(path2, L"\\");
+	return unicodeToUtf8Heap(path2);
+
+} /* __PHYSFS_platformCalcBaseDir */
+
+
+char *__PHYSFS_platformCalcPrefDir(const char *org, const char *app)
+{
+	const wchar_t* path = Windows::Storage::ApplicationData::Current->LocalFolder->Path->Data();
+	wchar_t path2[1024];
+	wcscpy_s(path2, path);
+	wcscat_s(path2, L"\\");
+	return unicodeToUtf8Heap(path2);
+} /* __PHYSFS_platformCalcPrefDir */
+
+
+char *__PHYSFS_platformCalcUserDir(void)
+{
+	return __PHYSFS_platformCalcPrefDir(NULL, NULL);
+} /* __PHYSFS_platformCalcUserDir */
+
+
+void *__PHYSFS_platformGetThreadID(void)
+{
+	return ((void *)((size_t)GetCurrentThreadId()));
+} /* __PHYSFS_platformGetThreadID */
+
+
+static int isSymlinkAttrs(const DWORD attr, const DWORD tag)
+{
+	return ((attr & FILE_ATTRIBUTE_REPARSE_POINT) &&
+		(tag == PHYSFS_IO_REPARSE_TAG_SYMLINK));
+} /* isSymlinkAttrs */
+
+
+void __PHYSFS_platformEnumerateFiles(const char *dirname,
+	PHYSFS_EnumFilesCallback callback,
+	const char *origdir,
+	void *callbackdata)
+{
+
+	HANDLE dir = INVALID_HANDLE_VALUE;
+	WIN32_FIND_DATAW entw;
+	size_t len = strlen(dirname);
+	char *searchPath = NULL;
+	WCHAR *wSearchPath = NULL;
+
+	/* Allocate a new string for path, maybe '\\', "*", and NULL terminator */
+	searchPath = (char *)__PHYSFS_smallAlloc(len + 3);
+	if (searchPath == NULL)
+		return;
+
+	/* Copy current dirname */
+	strcpy(searchPath, dirname);
+
+	/* if there's no '\\' at the end of the path, stick one in there. */
+	if (searchPath[len - 1] != '\\')
+	{
+		searchPath[len++] = '\\';
+		searchPath[len] = '\0';
+	} /* if */
+
+	/* Append the "*" to the end of the string */
+	strcat(searchPath, "*");
+
+	UTF8_TO_UNICODE_STACK_MACRO(wSearchPath, searchPath);
+	if (!wSearchPath)
+		return;  /* oh well. */
+
+	//dir = FindFirstFileW(wSearchPath, &entw);
+	dir = FindFirstFileExW(wSearchPath, FindExInfoStandard, &entw, FindExSearchNameMatch, NULL, 0);
+
+	__PHYSFS_smallFree(wSearchPath);
+	__PHYSFS_smallFree(searchPath);
+	if (dir == INVALID_HANDLE_VALUE)
+		return;
+
+	do
+	{
+		const DWORD attr = entw.dwFileAttributes;
+		const DWORD tag = entw.dwReserved0;
+		const WCHAR *fn = entw.cFileName;
+		char *utf8;
+
+		if ((fn[0] == '.') && (fn[1] == '\0'))
+			continue;
+		if ((fn[0] == '.') && (fn[1] == '.') && (fn[2] == '\0'))
+			continue;
+
+		utf8 = unicodeToUtf8Heap(fn);
+		if (utf8 != NULL)
+		{
+			callback(callbackdata, origdir, utf8);
+			allocator.Free(utf8);
+		} /* if */
+	} while (FindNextFileW(dir, &entw) != 0);
+
+	FindClose(dir);
+} /* __PHYSFS_platformEnumerateFiles */
+
+
+int __PHYSFS_platformMkDir(const char *path)
+{
+	WCHAR *wpath;
+	DWORD rc;
+	UTF8_TO_UNICODE_STACK_MACRO(wpath, path);
+	rc = CreateDirectoryW(wpath, NULL);
+	__PHYSFS_smallFree(wpath);
+	BAIL_IF_MACRO(rc == 0, errcodeFromWinApi(), 0);
+	return 1;
+} /* __PHYSFS_platformMkDir */
+
+
+int __PHYSFS_platformInit(void)
+{
+	return 1;  /* It's all good */
+} /* __PHYSFS_platformInit */
+
+
+int __PHYSFS_platformDeinit(void)
+{
+	return 1; /* It's all good */
+} /* __PHYSFS_platformDeinit */
+
+
+static void *doOpen(const char *fname, DWORD mode, DWORD creation, int rdonly)
+{
+	HANDLE fileh;
+	WinApiFile *retval;
+	WCHAR *wfname;
+
+	UTF8_TO_UNICODE_STACK_MACRO(wfname, fname);
+	BAIL_IF_MACRO(!wfname, PHYSFS_ERR_OUT_OF_MEMORY, NULL);
+	//fileh = CreateFileW(wfname, mode, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, creation, FILE_ATTRIBUTE_NORMAL, NULL);
+	fileh = CreateFile2(wfname, mode, FILE_SHARE_READ | FILE_SHARE_WRITE, creation, NULL);
+	__PHYSFS_smallFree(wfname);
+
+	BAIL_IF_MACRO(fileh == INVALID_HANDLE_VALUE, errcodeFromWinApi(), NULL);
+
+	retval = (WinApiFile *)allocator.Malloc(sizeof(WinApiFile));
+	if (!retval)
+	{
+		CloseHandle(fileh);
+		BAIL_MACRO(PHYSFS_ERR_OUT_OF_MEMORY, NULL);
+	} /* if */
+
+	retval->readonly = rdonly;
+	retval->handle = fileh;
+	return retval;
+} /* doOpen */
+
+
+void *__PHYSFS_platformOpenRead(const char *filename)
+{
+	return doOpen(filename, GENERIC_READ, OPEN_EXISTING, 1);
+} /* __PHYSFS_platformOpenRead */
+
+
+void *__PHYSFS_platformOpenWrite(const char *filename)
+{
+	return doOpen(filename, GENERIC_WRITE, CREATE_ALWAYS, 0);
+} /* __PHYSFS_platformOpenWrite */
+
+
+void *__PHYSFS_platformOpenAppend(const char *filename)
+{
+	void *retval = doOpen(filename, GENERIC_WRITE, OPEN_ALWAYS, 0);
+	if (retval != NULL)
+	{
+		HANDLE h = ((WinApiFile *)retval)->handle;
+		//DWORD rc = SetFilePointer(h, 0, NULL, FILE_END);
+		const LARGE_INTEGER zero = { 0 };
+		DWORD rc = SetFilePointerEx(h, zero, NULL, FILE_END);
+		if (rc == PHYSFS_INVALID_SET_FILE_POINTER)
+		{
+			const PHYSFS_ErrorCode err = errcodeFromWinApi();
+			CloseHandle(h);
+			allocator.Free(retval);
+			BAIL_MACRO(err, NULL);
+		} /* if */
+	} /* if */
+
+	return retval;
+} /* __PHYSFS_platformOpenAppend */
+
+
+PHYSFS_sint64 __PHYSFS_platformRead(void *opaque, void *buf, PHYSFS_uint64 len)
+{
+	HANDLE Handle = ((WinApiFile *)opaque)->handle;
+	PHYSFS_sint64 totalRead = 0;
+
+	if (!__PHYSFS_ui64FitsAddressSpace(len))
+		BAIL_MACRO(PHYSFS_ERR_INVALID_ARGUMENT, -1);
+
+	while (len > 0)
+	{
+		const DWORD thislen = (len > 0xFFFFFFFF) ? 0xFFFFFFFF : (DWORD)len;
+		DWORD numRead = 0;
+		if (!ReadFile(Handle, buf, thislen, &numRead, NULL))
+			BAIL_MACRO(errcodeFromWinApi(), -1);
+		len -= (PHYSFS_uint64)numRead;
+		totalRead += (PHYSFS_sint64)numRead;
+		if (numRead != thislen)
+			break;
+	} /* while */
+	
+	return totalRead;
+} /* __PHYSFS_platformRead */
+
+
+PHYSFS_sint64 __PHYSFS_platformWrite(void *opaque, const void *buffer,
+	PHYSFS_uint64 len)
+{
+	HANDLE Handle = ((WinApiFile *)opaque)->handle;
+	PHYSFS_sint64 totalWritten = 0;
+
+	if (!__PHYSFS_ui64FitsAddressSpace(len))
+		BAIL_MACRO(PHYSFS_ERR_INVALID_ARGUMENT, -1);
+
+	while (len > 0)
+	{
+		const DWORD thislen = (len > 0xFFFFFFFF) ? 0xFFFFFFFF : (DWORD)len;
+		DWORD numWritten = 0;
+		if (!WriteFile(Handle, buffer, thislen, &numWritten, NULL))
+			BAIL_MACRO(errcodeFromWinApi(), -1);
+		len -= (PHYSFS_uint64)numWritten;
+		totalWritten += (PHYSFS_sint64)numWritten;
+		if (numWritten != thislen)
+			break;
+	} /* while */
+
+	return totalWritten;
+} /* __PHYSFS_platformWrite */
+
+
+int __PHYSFS_platformSeek(void *opaque, PHYSFS_uint64 pos)
+{
+	HANDLE Handle = ((WinApiFile *)opaque)->handle;
+	BOOL rc;
+
+	LARGE_INTEGER li;
+	li.LowPart = LOWORDER_UINT64(pos);
+	li.HighPart = HIGHORDER_UINT64(pos);
+
+	rc = SetFilePointerEx(Handle, li, NULL, FILE_BEGIN);
+
+	if (!rc && (GetLastError() != NO_ERROR))
+	{
+		BAIL_MACRO(errcodeFromWinApi(), 0);
+	} /* if */
+
+	return 1;  /* No error occured */
+} /* __PHYSFS_platformSeek */
+
+
+PHYSFS_sint64 __PHYSFS_platformTell(void *opaque)
+{
+	HANDLE Handle = ((WinApiFile *)opaque)->handle;
+	PHYSFS_sint64 retval;
+	BOOL rc;
+
+	LARGE_INTEGER zero;
+	zero.QuadPart = 0;
+	LARGE_INTEGER out;
+
+	rc = SetFilePointerEx(Handle, zero, &out, FILE_CURRENT);
+	if (!rc)
+	{
+		BAIL_MACRO(errcodeFromWinApi(), -1);
+	} /* if */
+	else
+	{
+		retval = out.QuadPart;
+		assert(retval >= 0);
+	} /* else */
+
+	return retval;
+} /* __PHYSFS_platformTell */
+
+
+PHYSFS_sint64 __PHYSFS_platformFileLength(void *opaque)
+{
+	HANDLE Handle = ((WinApiFile *)opaque)->handle;
+	PHYSFS_sint64 retval;
+
+	FILE_STANDARD_INFO file_info = { 0 };
+	const BOOL res = GetFileInformationByHandleEx(Handle, FileStandardInfo, &file_info, sizeof(file_info));
+	if (res) {
+		retval = file_info.EndOfFile.QuadPart;
+		assert(retval >= 0);
+	}
+	else {
+		PHYSFS_setErrorCode(PHYSFS_ERR_NOT_FOUND);
+	}
+
+	
+	return retval;
+} /* __PHYSFS_platformFileLength */
+
+
+int __PHYSFS_platformFlush(void *opaque)
+{
+	WinApiFile *fh = ((WinApiFile *)opaque);
+	if (!fh->readonly)
+		BAIL_IF_MACRO(!FlushFileBuffers(fh->handle), errcodeFromWinApi(), 0);
+
+	return 1;
+} /* __PHYSFS_platformFlush */
+
+
+void __PHYSFS_platformClose(void *opaque)
+{
+	HANDLE Handle = ((WinApiFile *)opaque)->handle;
+	(void)CloseHandle(Handle); /* ignore errors. You should have flushed! */
+	allocator.Free(opaque);
+} /* __PHYSFS_platformClose */
+
+
+static int doPlatformDelete(LPWSTR wpath)
+{
+	//const int isdir = (GetFileAttributesW(wpath) & FILE_ATTRIBUTE_DIRECTORY);
+	int isdir = 0;
+	WIN32_FILE_ATTRIBUTE_DATA file_info;
+	const BOOL res = GetFileAttributesEx(wpath, GetFileExInfoStandard, &file_info);
+	if (res) {
+		isdir = (file_info.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY);
+	}
+
+	const BOOL rc = (isdir) ? RemoveDirectoryW(wpath) : DeleteFileW(wpath);
+	BAIL_IF_MACRO(!rc, errcodeFromWinApi(), 0);
+	return 1;   /* if you made it here, it worked. */
+} /* doPlatformDelete */
+
+
+int __PHYSFS_platformDelete(const char *path)
+{
+	int retval = 0;
+	LPWSTR wpath = NULL;
+	UTF8_TO_UNICODE_STACK_MACRO(wpath, path);
+	BAIL_IF_MACRO(!wpath, PHYSFS_ERR_OUT_OF_MEMORY, 0);
+	retval = doPlatformDelete(wpath);
+	__PHYSFS_smallFree(wpath);
+	return retval;
+} /* __PHYSFS_platformDelete */
+
+
+void *__PHYSFS_platformCreateMutex(void)
+{
+	LPCRITICAL_SECTION lpcs;
+	lpcs = (LPCRITICAL_SECTION)allocator.Malloc(sizeof(CRITICAL_SECTION));
+	BAIL_IF_MACRO(!lpcs, PHYSFS_ERR_OUT_OF_MEMORY, NULL);
+	//InitializeCriticalSection(lpcs);
+	InitializeCriticalSectionEx(lpcs, 2000, 0);
+	return lpcs;
+} /* __PHYSFS_platformCreateMutex */
+
+
+void __PHYSFS_platformDestroyMutex(void *mutex)
+{
+	DeleteCriticalSection((LPCRITICAL_SECTION)mutex);
+	allocator.Free(mutex);
+} /* __PHYSFS_platformDestroyMutex */
+
+
+int __PHYSFS_platformGrabMutex(void *mutex)
+{
+	EnterCriticalSection((LPCRITICAL_SECTION)mutex);
+	return 1;
+} /* __PHYSFS_platformGrabMutex */
+
+
+void __PHYSFS_platformReleaseMutex(void *mutex)
+{
+	LeaveCriticalSection((LPCRITICAL_SECTION)mutex);
+} /* __PHYSFS_platformReleaseMutex */
+
+
+static PHYSFS_sint64 FileTimeToPhysfsTime(const FILETIME *ft)
+{
+	SYSTEMTIME st_utc;
+	SYSTEMTIME st_localtz;
+	TIME_ZONE_INFORMATION tzi;
+	DWORD tzid;
+	PHYSFS_sint64 retval;
+	struct tm tm;
+	BOOL rc;
+
+	BAIL_IF_MACRO(!FileTimeToSystemTime(ft, &st_utc), errcodeFromWinApi(), -1);
+	tzid = GetTimeZoneInformation(&tzi);
+	BAIL_IF_MACRO(tzid == TIME_ZONE_ID_INVALID, errcodeFromWinApi(), -1);
+	rc = SystemTimeToTzSpecificLocalTime(&tzi, &st_utc, &st_localtz);
+	BAIL_IF_MACRO(!rc, errcodeFromWinApi(), -1);
+
+	/* Convert to a format that mktime() can grok... */
+	tm.tm_sec = st_localtz.wSecond;
+	tm.tm_min = st_localtz.wMinute;
+	tm.tm_hour = st_localtz.wHour;
+	tm.tm_mday = st_localtz.wDay;
+	tm.tm_mon = st_localtz.wMonth - 1;
+	tm.tm_year = st_localtz.wYear - 1900;
+	tm.tm_wday = -1 /*st_localtz.wDayOfWeek*/;
+	tm.tm_yday = -1;
+	tm.tm_isdst = -1;
+
+	/* Convert to a format PhysicsFS can grok... */
+	retval = (PHYSFS_sint64)mktime(&tm);
+	BAIL_IF_MACRO(retval == -1, PHYSFS_ERR_OS_ERROR, -1);
+	return retval;
+} /* FileTimeToPhysfsTime */
+
+
+int __PHYSFS_platformStat(const char *filename, PHYSFS_Stat *st)
+{
+	WIN32_FILE_ATTRIBUTE_DATA winstat;
+	WCHAR *wstr = NULL;
+	DWORD err = 0;
+	BOOL rc = 0;
+
+	UTF8_TO_UNICODE_STACK_MACRO(wstr, filename);
+	BAIL_IF_MACRO(!wstr, PHYSFS_ERR_OUT_OF_MEMORY, 0);
+	rc = GetFileAttributesExW(wstr, GetFileExInfoStandard, &winstat);
+	err = (!rc) ? GetLastError() : 0;
+	__PHYSFS_smallFree(wstr);
+	BAIL_IF_MACRO(!rc, errcodeFromWinApiError(err), 0);
+
+	st->modtime = FileTimeToPhysfsTime(&winstat.ftLastWriteTime);
+	st->accesstime = FileTimeToPhysfsTime(&winstat.ftLastAccessTime);
+	st->createtime = FileTimeToPhysfsTime(&winstat.ftCreationTime);
+
+	if (winstat.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
+	{
+		st->filetype = PHYSFS_FILETYPE_DIRECTORY;
+		st->filesize = 0;
+	} /* if */
+
+	else if (winstat.dwFileAttributes & (FILE_ATTRIBUTE_OFFLINE | FILE_ATTRIBUTE_DEVICE))
+	{
+		/* !!! FIXME: what are reparse points? */
+		st->filetype = PHYSFS_FILETYPE_OTHER;
+		/* !!! FIXME: don't rely on this */
+		st->filesize = 0;
+	} /* else if */
+
+	/* !!! FIXME: check for symlinks on Vista. */
+
+	else
+	{
+		st->filetype = PHYSFS_FILETYPE_REGULAR;
+		st->filesize = (((PHYSFS_uint64)winstat.nFileSizeHigh) << 32) | winstat.nFileSizeLow;
+	} /* else */
+
+	st->readonly = ((winstat.dwFileAttributes & FILE_ATTRIBUTE_READONLY) != 0);
+
+	return 1;
+} /* __PHYSFS_platformStat */
+
+
+/* !!! FIXME: Don't use C runtime for allocators? */
+int __PHYSFS_platformSetDefaultAllocator(PHYSFS_Allocator *a)
+{
+	return 0;  /* just use malloc() and friends. */
+} /* __PHYSFS_platformSetDefaultAllocator */
+
+
+#endif /* PHYSFS_PLATFORM_WINRT */
\ No newline at end of file