From f2902217b38cf2e16e851ae84d61247f8e828180 Mon Sep 17 00:00:00 2001
From: wolfbeast <mcwerewolf@wolfbeast.com>
Date: Mon, 25 Mar 2019 17:53:14 +0100
Subject: Update the 7z installer stub source to 18.05.

Tag #1022
---
 other-licenses/7zstub/src/CS/7zip/Common/CRC.cs    |   55 +
 .../7zstub/src/CS/7zip/Common/CommandLineParser.cs |  274 ++++
 .../7zstub/src/CS/7zip/Common/InBuffer.cs          |   72 +
 .../7zstub/src/CS/7zip/Common/OutBuffer.cs         |   47 +
 .../7zstub/src/CS/7zip/Compress/LZ/IMatchFinder.cs |   24 +
 .../7zstub/src/CS/7zip/Compress/LZ/LzBinTree.cs    |  367 +++++
 .../7zstub/src/CS/7zip/Compress/LZ/LzInWindow.cs   |  132 ++
 .../7zstub/src/CS/7zip/Compress/LZ/LzOutWindow.cs  |  110 ++
 .../7zstub/src/CS/7zip/Compress/LZMA/LzmaBase.cs   |   76 +
 .../src/CS/7zip/Compress/LZMA/LzmaDecoder.cs       |  398 ++++++
 .../src/CS/7zip/Compress/LZMA/LzmaEncoder.cs       | 1480 ++++++++++++++++++++
 .../src/CS/7zip/Compress/LzmaAlone/LzmaAlone.cs    |  364 +++++
 .../CS/7zip/Compress/LzmaAlone/LzmaAlone.csproj    |   90 ++
 .../src/CS/7zip/Compress/LzmaAlone/LzmaAlone.sln   |   20 +
 .../src/CS/7zip/Compress/LzmaAlone/LzmaBench.cs    |  340 +++++
 .../Compress/LzmaAlone/Properties/AssemblyInfo.cs  |   29 +
 .../Compress/LzmaAlone/Properties/Resources.cs     |   70 +
 .../7zip/Compress/LzmaAlone/Properties/Settings.cs |   42 +
 .../src/CS/7zip/Compress/RangeCoder/RangeCoder.cs  |  234 ++++
 .../CS/7zip/Compress/RangeCoder/RangeCoderBit.cs   |  117 ++
 .../7zip/Compress/RangeCoder/RangeCoderBitTree.cs  |  157 +++
 other-licenses/7zstub/src/CS/7zip/ICoder.cs        |  157 +++
 22 files changed, 4655 insertions(+)
 create mode 100644 other-licenses/7zstub/src/CS/7zip/Common/CRC.cs
 create mode 100644 other-licenses/7zstub/src/CS/7zip/Common/CommandLineParser.cs
 create mode 100644 other-licenses/7zstub/src/CS/7zip/Common/InBuffer.cs
 create mode 100644 other-licenses/7zstub/src/CS/7zip/Common/OutBuffer.cs
 create mode 100644 other-licenses/7zstub/src/CS/7zip/Compress/LZ/IMatchFinder.cs
 create mode 100644 other-licenses/7zstub/src/CS/7zip/Compress/LZ/LzBinTree.cs
 create mode 100644 other-licenses/7zstub/src/CS/7zip/Compress/LZ/LzInWindow.cs
 create mode 100644 other-licenses/7zstub/src/CS/7zip/Compress/LZ/LzOutWindow.cs
 create mode 100644 other-licenses/7zstub/src/CS/7zip/Compress/LZMA/LzmaBase.cs
 create mode 100644 other-licenses/7zstub/src/CS/7zip/Compress/LZMA/LzmaDecoder.cs
 create mode 100644 other-licenses/7zstub/src/CS/7zip/Compress/LZMA/LzmaEncoder.cs
 create mode 100644 other-licenses/7zstub/src/CS/7zip/Compress/LzmaAlone/LzmaAlone.cs
 create mode 100644 other-licenses/7zstub/src/CS/7zip/Compress/LzmaAlone/LzmaAlone.csproj
 create mode 100644 other-licenses/7zstub/src/CS/7zip/Compress/LzmaAlone/LzmaAlone.sln
 create mode 100644 other-licenses/7zstub/src/CS/7zip/Compress/LzmaAlone/LzmaBench.cs
 create mode 100644 other-licenses/7zstub/src/CS/7zip/Compress/LzmaAlone/Properties/AssemblyInfo.cs
 create mode 100644 other-licenses/7zstub/src/CS/7zip/Compress/LzmaAlone/Properties/Resources.cs
 create mode 100644 other-licenses/7zstub/src/CS/7zip/Compress/LzmaAlone/Properties/Settings.cs
 create mode 100644 other-licenses/7zstub/src/CS/7zip/Compress/RangeCoder/RangeCoder.cs
 create mode 100644 other-licenses/7zstub/src/CS/7zip/Compress/RangeCoder/RangeCoderBit.cs
 create mode 100644 other-licenses/7zstub/src/CS/7zip/Compress/RangeCoder/RangeCoderBitTree.cs
 create mode 100644 other-licenses/7zstub/src/CS/7zip/ICoder.cs

(limited to 'other-licenses/7zstub/src/CS')

diff --git a/other-licenses/7zstub/src/CS/7zip/Common/CRC.cs b/other-licenses/7zstub/src/CS/7zip/Common/CRC.cs
new file mode 100644
index 000000000..62bb8478b
--- /dev/null
+++ b/other-licenses/7zstub/src/CS/7zip/Common/CRC.cs
@@ -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);
+		}
+	}
+}
diff --git a/other-licenses/7zstub/src/CS/7zip/Common/CommandLineParser.cs b/other-licenses/7zstub/src/CS/7zip/Common/CommandLineParser.cs
new file mode 100644
index 000000000..b46f6f209
--- /dev/null
+++ b/other-licenses/7zstub/src/CS/7zip/Common/CommandLineParser.cs
@@ -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;
+	}
+}
diff --git a/other-licenses/7zstub/src/CS/7zip/Common/InBuffer.cs b/other-licenses/7zstub/src/CS/7zip/Common/InBuffer.cs
new file mode 100644
index 000000000..9c47c73ae
--- /dev/null
+++ b/other-licenses/7zstub/src/CS/7zip/Common/InBuffer.cs
@@ -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;
+		}
+	}
+}
diff --git a/other-licenses/7zstub/src/CS/7zip/Common/OutBuffer.cs b/other-licenses/7zstub/src/CS/7zip/Common/OutBuffer.cs
new file mode 100644
index 000000000..c205aa634
--- /dev/null
+++ b/other-licenses/7zstub/src/CS/7zip/Common/OutBuffer.cs
@@ -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; }
+	}
+}
diff --git a/other-licenses/7zstub/src/CS/7zip/Compress/LZ/IMatchFinder.cs b/other-licenses/7zstub/src/CS/7zip/Compress/LZ/IMatchFinder.cs
new file mode 100644
index 000000000..30fab8650
--- /dev/null
+++ b/other-licenses/7zstub/src/CS/7zip/Compress/LZ/IMatchFinder.cs
@@ -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);
+	}
+}
diff --git a/other-licenses/7zstub/src/CS/7zip/Compress/LZ/LzBinTree.cs b/other-licenses/7zstub/src/CS/7zip/Compress/LZ/LzBinTree.cs
new file mode 100644
index 000000000..7a9ca2092
--- /dev/null
+++ b/other-licenses/7zstub/src/CS/7zip/Compress/LZ/LzBinTree.cs
@@ -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; }
+	}
+}
diff --git a/other-licenses/7zstub/src/CS/7zip/Compress/LZ/LzInWindow.cs b/other-licenses/7zstub/src/CS/7zip/Compress/LZ/LzInWindow.cs
new file mode 100644
index 000000000..f1974cef5
--- /dev/null
+++ b/other-licenses/7zstub/src/CS/7zip/Compress/LZ/LzInWindow.cs
@@ -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;
+		}
+	}
+}
diff --git a/other-licenses/7zstub/src/CS/7zip/Compress/LZ/LzOutWindow.cs b/other-licenses/7zstub/src/CS/7zip/Compress/LZ/LzOutWindow.cs
new file mode 100644
index 000000000..84914f0d9
--- /dev/null
+++ b/other-licenses/7zstub/src/CS/7zip/Compress/LZ/LzOutWindow.cs
@@ -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];
+		}
+	}
+}
diff --git a/other-licenses/7zstub/src/CS/7zip/Compress/LZMA/LzmaBase.cs b/other-licenses/7zstub/src/CS/7zip/Compress/LZMA/LzmaBase.cs
new file mode 100644
index 000000000..8447a2a0f
--- /dev/null
+++ b/other-licenses/7zstub/src/CS/7zip/Compress/LZMA/LzmaBase.cs
@@ -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;
+	}
+}
diff --git a/other-licenses/7zstub/src/CS/7zip/Compress/LZMA/LzmaDecoder.cs b/other-licenses/7zstub/src/CS/7zip/Compress/LZMA/LzmaDecoder.cs
new file mode 100644
index 000000000..00bfe6380
--- /dev/null
+++ b/other-licenses/7zstub/src/CS/7zip/Compress/LZMA/LzmaDecoder.cs
@@ -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) {}
+		*/
+	}
+}
diff --git a/other-licenses/7zstub/src/CS/7zip/Compress/LZMA/LzmaEncoder.cs b/other-licenses/7zstub/src/CS/7zip/Compress/LZMA/LzmaEncoder.cs
new file mode 100644
index 000000000..6dc2708bd
--- /dev/null
+++ b/other-licenses/7zstub/src/CS/7zip/Compress/LZMA/LzmaEncoder.cs
@@ -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)) & 0xFF);
+			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;
+		}
+		
+	}
+}
diff --git a/other-licenses/7zstub/src/CS/7zip/Compress/LzmaAlone/LzmaAlone.cs b/other-licenses/7zstub/src/CS/7zip/Compress/LzmaAlone/LzmaAlone.cs
new file mode 100644
index 000000000..8aa446267
--- /dev/null
+++ b/other-licenses/7zstub/src/CS/7zip/Compress/LzmaAlone/LzmaAlone.cs
@@ -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.61  2008-11-23\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;
+			}
+		}
+	}
+}
diff --git a/other-licenses/7zstub/src/CS/7zip/Compress/LzmaAlone/LzmaAlone.csproj b/other-licenses/7zstub/src/CS/7zip/Compress/LzmaAlone/LzmaAlone.csproj
new file mode 100644
index 000000000..ceb707350
--- /dev/null
+++ b/other-licenses/7zstub/src/CS/7zip/Compress/LzmaAlone/LzmaAlone.csproj
@@ -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
diff --git a/other-licenses/7zstub/src/CS/7zip/Compress/LzmaAlone/LzmaAlone.sln b/other-licenses/7zstub/src/CS/7zip/Compress/LzmaAlone/LzmaAlone.sln
new file mode 100644
index 000000000..a96ee3e43
--- /dev/null
+++ b/other-licenses/7zstub/src/CS/7zip/Compress/LzmaAlone/LzmaAlone.sln
@@ -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
diff --git a/other-licenses/7zstub/src/CS/7zip/Compress/LzmaAlone/LzmaBench.cs b/other-licenses/7zstub/src/CS/7zip/Compress/LzmaAlone/LzmaBench.cs
new file mode 100644
index 000000000..6a1ffe246
--- /dev/null
+++ b/other-licenses/7zstub/src/CS/7zip/Compress/LzmaAlone/LzmaBench.cs
@@ -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;
+		}
+	}
+}
diff --git a/other-licenses/7zstub/src/CS/7zip/Compress/LzmaAlone/Properties/AssemblyInfo.cs b/other-licenses/7zstub/src/CS/7zip/Compress/LzmaAlone/Properties/AssemblyInfo.cs
new file mode 100644
index 000000000..a394aee87
--- /dev/null
+++ b/other-licenses/7zstub/src/CS/7zip/Compress/LzmaAlone/Properties/AssemblyInfo.cs
@@ -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.*")]
diff --git a/other-licenses/7zstub/src/CS/7zip/Compress/LzmaAlone/Properties/Resources.cs b/other-licenses/7zstub/src/CS/7zip/Compress/LzmaAlone/Properties/Resources.cs
new file mode 100644
index 000000000..efe4ee9af
--- /dev/null
+++ b/other-licenses/7zstub/src/CS/7zip/Compress/LzmaAlone/Properties/Resources.cs
@@ -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;
+			}
+		}
+	}
+}
diff --git a/other-licenses/7zstub/src/CS/7zip/Compress/LzmaAlone/Properties/Settings.cs b/other-licenses/7zstub/src/CS/7zip/Compress/LzmaAlone/Properties/Settings.cs
new file mode 100644
index 000000000..1281fd2e0
--- /dev/null
+++ b/other-licenses/7zstub/src/CS/7zip/Compress/LzmaAlone/Properties/Settings.cs
@@ -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;
+			}
+		}
+	}
+}
diff --git a/other-licenses/7zstub/src/CS/7zip/Compress/RangeCoder/RangeCoder.cs b/other-licenses/7zstub/src/CS/7zip/Compress/RangeCoder/RangeCoder.cs
new file mode 100644
index 000000000..4ced2477e
--- /dev/null
+++ b/other-licenses/7zstub/src/CS/7zip/Compress/RangeCoder/RangeCoder.cs
@@ -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(); }
+	}
+}
diff --git a/other-licenses/7zstub/src/CS/7zip/Compress/RangeCoder/RangeCoderBit.cs b/other-licenses/7zstub/src/CS/7zip/Compress/RangeCoder/RangeCoderBit.cs
new file mode 100644
index 000000000..000a5a078
--- /dev/null
+++ b/other-licenses/7zstub/src/CS/7zip/Compress/RangeCoder/RangeCoderBit.cs
@@ -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;
+			}
+		}
+	}
+}
diff --git a/other-licenses/7zstub/src/CS/7zip/Compress/RangeCoder/RangeCoderBitTree.cs b/other-licenses/7zstub/src/CS/7zip/Compress/RangeCoder/RangeCoderBitTree.cs
new file mode 100644
index 000000000..3309c14a5
--- /dev/null
+++ b/other-licenses/7zstub/src/CS/7zip/Compress/RangeCoder/RangeCoderBitTree.cs
@@ -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;
+		}
+	}
+}
diff --git a/other-licenses/7zstub/src/CS/7zip/ICoder.cs b/other-licenses/7zstub/src/CS/7zip/ICoder.cs
new file mode 100644
index 000000000..875cb2739
--- /dev/null
+++ b/other-licenses/7zstub/src/CS/7zip/ICoder.cs
@@ -0,0 +1,157 @@
+// 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 default property.
+		/// </summary>
+		DefaultProp = 0,
+		/// <summary>
+		/// Specifies size of dictionary.
+		/// </summary>
+		DictionarySize,
+		/// <summary>
+		/// Specifies size of memory for PPM*.
+		/// </summary>
+		UsedMemorySize,
+		/// <summary>
+		/// Specifies order for PPM methods.
+		/// </summary>
+		Order,
+		/// <summary>
+		/// Specifies Block Size.
+		/// </summary>
+		BlockSize,
+		/// <summary>
+		/// Specifies number of postion state bits for LZMA (0 <= x <= 4).
+		/// </summary>
+		PosStateBits,
+		/// <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,
+		/// <summary>
+		/// Specifies match finder. LZMA: "BT2", "BT4" or "BT4B".
+		/// </summary>
+		MatchFinder,
+		/// <summary>
+		/// Specifies the number of match finder cyckes.
+		/// </summary>
+		MatchFinderCycles,
+		/// <summary>
+		/// Specifies number of passes.
+		/// </summary>
+		NumPasses,
+		/// <summary>
+		/// Specifies number of algorithm.
+		/// </summary>
+		Algorithm,
+		/// <summary>
+		/// Specifies the number of threads.
+		/// </summary>
+		NumThreads,
+		/// <summary>
+		/// Specifies mode with end marker.
+		/// </summary>
+		EndMarker
+	};
+
+
+	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);
+	}
+}
-- 
cgit v1.2.3