 +*   Compression using a digested Dictionary.
 +*   Faster startup than ZSTD_compress_usingDict(), recommended when same dictionary is used multiple times.
 +*   Note that compression level is decided during dictionary creation */
-+size_t ZSTD_compress_usingCDict(ZSTD_CCtx* cctx,
-+								void* dst, size_t dstCapacity,
-+								const void* src, size_t srcSize,
-+								const ZSTD_CDict* cdict)
++size_t ZSTD_compress_usingCDict(ZSTD_CCtx *cctx, void *dst, size_t dstCapacity, const void *src, size_t srcSize, const ZSTD_CDict *cdict)
 +{
 +	CHECK_F(ZSTD_compressBegin_usingCDict(cctx, cdict, srcSize));
 +
-+	if (cdict->refContext->params.fParams.contentSizeFlag==1) {
++	if (cdict->refContext->params.fParams.contentSizeFlag == 1) {
 +		cctx->params.fParams.contentSizeFlag = 1;
 +		cctx->frameContentSize = srcSize;
 +	} else {

+				matchEndIdx = matchIndex + (U32)matchLength;
+		}
+
+		if (ip+matchLength == iend)   /* equal : no way to know if inf or sup */
+			break;   /* drop , to guarantee consistency ; miss a bit of compression, but other solutions can corrupt the tree */
+
+		if (match[matchLength] < ip[matchLength]) {  /* necessarily within correct buffer */
+			/* match is smaller than curr */
+			*smallerPtr = matchIndex;             /* update smaller idx */
+			commonLengthSmaller = matchLength;    /* all smaller will now have at least this guaranteed common length */
+			if (matchIndex <= btLow) { smallerPtr=&dummy32; break; }   /* beyond tree size, stop the search */
+			smallerPtr = nextPtr+1;               /* new "smaller" => larger of match */
+			matchIndex = nextPtr[1];              /* new matchIndex larger than previous (closer to curr) */
+		} else {
+			/* match is larger than curr */
+			*largerPtr = matchIndex;
+			commonLengthLarger = matchLength;
+			if (matchIndex <= btLow) { largerPtr=&dummy32; break; }   /* beyond tree size, stop the search */
+			largerPtr = nextPtr;
+			matchIndex = nextPtr[0];
+	}   }
+
+	*smallerPtr = *largerPtr = 0;
+	if (bestLength > 384) return MIN(192, (U32)(bestLength - 384));   /* speed optimization */
+	if (matchEndIdx > curr + 8) return matchEndIdx - curr - 8;
+	return 1;
+}
+
+
+static size_t ZSTD_insertBtAndFindBestMatch (
+						ZSTD_CCtx* zc,
+						const BYTE* const ip, const BYTE* const iend,
+						size_t* offsetPtr,
+						U32 nbCompares, const U32 mls,
+						U32 extDict)
+{
+	U32*   const hashTable = zc->hashTable;
+	U32    const hashLog = zc->params.cParams.hashLog;
+	size_t const h  = ZSTD_hashPtr(ip, hashLog, mls);
+	U32*   const bt = zc->chainTable;
+	U32    const btLog  = zc->params.cParams.chainLog - 1;
+	U32    const btMask = (1 << btLog) - 1;
+	U32 matchIndex  = hashTable[h];
+	size_t commonLengthSmaller=0, commonLengthLarger=0;
+	const BYTE* const base = zc->base;
+	const BYTE* const dictBase = zc->dictBase;
+	const U32 dictLimit = zc->dictLimit;
+	const BYTE* const dictEnd = dictBase + dictLimit;
+	const BYTE* const prefixStart = base + dictLimit;
+	const U32 curr = (U32)(ip-base);
+	const U32 btLow = btMask >= curr ? 0 : curr - btMask;
+	const U32 windowLow = zc->lowLimit;
+	U32* smallerPtr = bt + 2*(curr&btMask);
+	U32* largerPtr  = bt + 2*(curr&btMask) + 1;
+	U32 matchEndIdx = curr+8;
+	U32 dummy32;   /* to be nullified at the end */
+	size_t bestLength = 0;
+
+	hashTable[h] = curr;   /* Update Hash Table */
+
+	while (nbCompares-- && (matchIndex > windowLow)) {
+		U32* const nextPtr = bt + 2*(matchIndex & btMask);
+		size_t matchLength = MIN(commonLengthSmaller, commonLengthLarger);   /* guaranteed minimum nb of common bytes */
+		const BYTE* match;
+
+		if ((!extDict) || (matchIndex+matchLength >= dictLimit)) {
+			match = base + matchIndex;
+			if (match[matchLength] == ip[matchLength])
+				matchLength += ZSTD_count(ip+matchLength+1, match+matchLength+1, iend) +1;
+		} else {
+			match = dictBase + matchIndex;
+			matchLength += ZSTD_count_2segments(ip+matchLength, match+matchLength, iend, dictEnd, prefixStart);
+			if (matchIndex+matchLength >= dictLimit)
+				match = base + matchIndex;   /* to prepare for next usage of match[matchLength] */
+		}
+
+		if (matchLength > bestLength) {
+			if (matchLength > matchEndIdx - matchIndex)
+				matchEndIdx = matchIndex + (U32)matchLength;
+			if ( (4*(int)(matchLength-bestLength)) > (int)(ZSTD_highbit32(curr-matchIndex+1) - ZSTD_highbit32((U32)offsetPtr[0]+1)) )
+				bestLength = matchLength, *offsetPtr = ZSTD_REP_MOVE + curr - matchIndex;
+			if (ip+matchLength == iend)   /* equal : no way to know if inf or sup */
+				break;   /* drop, to guarantee consistency (miss a little bit of compression) */
+		}
+
+		if (match[matchLength] < ip[matchLength]) {
+			/* match is smaller than curr */
+			*smallerPtr = matchIndex;             /* update smaller idx */
+			commonLengthSmaller = matchLength;    /* all smaller will now have at least this guaranteed common length */
+			if (matchIndex <= btLow) { smallerPtr=&dummy32; break; }   /* beyond tree size, stop the search */
+			smallerPtr = nextPtr+1;               /* new "smaller" => larger of match */
+			matchIndex = nextPtr[1];              /* new matchIndex larger than previous (closer to curr) */
+		} else {
+			/* match is larger than curr */
+			*largerPtr = matchIndex;
+			commonLengthLarger = matchLength;
+			if (matchIndex <= btLow) { largerPtr=&dummy32; break; }   /* beyond tree size, stop the search */
+			largerPtr = nextPtr;
+			matchIndex = nextPtr[0];
+	}   }
+
+	*smallerPtr = *largerPtr = 0;
+
+	zc->nextToUpdate = (matchEndIdx > curr + 8) ? matchEndIdx - 8 : curr+1;
+	return bestLength;
+}
+
+
+static void ZSTD_updateTree(ZSTD_CCtx* zc, const BYTE* const ip, const BYTE* const iend, const U32 nbCompares, const U32 mls)
+{
+	const BYTE* const base = zc->base;
+	const U32 target = (U32)(ip - base);
+	U32 idx = zc->nextToUpdate;
+
+	while(idx < target)
+		idx += ZSTD_insertBt1(zc, base+idx, mls, iend, nbCompares, 0);
+}
+
+/** ZSTD_BtFindBestMatch() : Tree updater, providing best match */
+static size_t ZSTD_BtFindBestMatch (
+						ZSTD_CCtx* zc,
+						const BYTE* const ip, const BYTE* const iLimit,
+						size_t* offsetPtr,
+						const U32 maxNbAttempts, const U32 mls)
+{
+	if (ip < zc->base + zc->nextToUpdate) return 0;   /* skipped area */
+	ZSTD_updateTree(zc, ip, iLimit, maxNbAttempts, mls);
+	return ZSTD_insertBtAndFindBestMatch(zc, ip, iLimit, offsetPtr, maxNbAttempts, mls, 0);
+}
+
+
+static size_t ZSTD_BtFindBestMatch_selectMLS (
+						ZSTD_CCtx* zc,   /* Index table will be updated */
+						const BYTE* ip, const BYTE* const iLimit,
+						size_t* offsetPtr,
+						const U32 maxNbAttempts, const U32 matchLengthSearch)
+{
+	switch(matchLengthSearch)
+	{
+	default : /* includes case 3 */
+	case 4 : return ZSTD_BtFindBestMatch(zc, ip, iLimit, offsetPtr, maxNbAttempts, 4);
+	case 5 : return ZSTD_BtFindBestMatch(zc, ip, iLimit, offsetPtr, maxNbAttempts, 5);
+	case 7 :
+	case 6 : return ZSTD_BtFindBestMatch(zc, ip, iLimit, offsetPtr, maxNbAttempts, 6);
+	}
+}
+
+
+static void ZSTD_updateTree_extDict(ZSTD_CCtx* zc, const BYTE* const ip, const BYTE* const iend, const U32 nbCompares, const U32 mls)
+{
+	const BYTE* const base = zc->base;
+	const U32 target = (U32)(ip - base);
+	U32 idx = zc->nextToUpdate;
+
+	while (idx < target) idx += ZSTD_insertBt1(zc, base+idx, mls, iend, nbCompares, 1);
+}
+
+
+/** Tree updater, providing best match */
+static size_t ZSTD_BtFindBestMatch_extDict (
+						ZSTD_CCtx* zc,
+						const BYTE* const ip, const BYTE* const iLimit,
+						size_t* offsetPtr,
+						const U32 maxNbAttempts, const U32 mls)
+{
+	if (ip < zc->base + zc->nextToUpdate) return 0;   /* skipped area */
+	ZSTD_updateTree_extDict(zc, ip, iLimit, maxNbAttempts, mls);
+	return ZSTD_insertBtAndFindBestMatch(zc, ip, iLimit, offsetPtr, maxNbAttempts, mls, 1);
+}
+
+
+static size_t ZSTD_BtFindBestMatch_selectMLS_extDict (
+						ZSTD_CCtx* zc,   /* Index table will be updated */
+						const BYTE* ip, const BYTE* const iLimit,
+						size_t* offsetPtr,
+						const U32 maxNbAttempts, const U32 matchLengthSearch)
+{
+	switch(matchLengthSearch)
+	{
+	default : /* includes case 3 */
+	case 4 : return ZSTD_BtFindBestMatch_extDict(zc, ip, iLimit, offsetPtr, maxNbAttempts, 4);
+	case 5 : return ZSTD_BtFindBestMatch_extDict(zc, ip, iLimit, offsetPtr, maxNbAttempts, 5);
+	case 7 :
+	case 6 : return ZSTD_BtFindBestMatch_extDict(zc, ip, iLimit, offsetPtr, maxNbAttempts, 6);
+	}
+}
+
+
+
+/* *********************************
+*  Hash Chain
+***********************************/
+#define NEXT_IN_CHAIN(d, mask)   chainTable[(d) & mask]
+
+/* Update chains up to ip (excluded)
+   Assumption : always within prefix (i.e. not within extDict) */
+FORCE_INLINE
+U32 ZSTD_insertAndFindFirstIndex (ZSTD_CCtx* zc, const BYTE* ip, U32 mls)
+{
+	U32* const hashTable  = zc->hashTable;
+	const U32 hashLog = zc->params.cParams.hashLog;
+	U32* const chainTable = zc->chainTable;
+	const U32 chainMask = (1 << zc->params.cParams.chainLog) - 1;
+	const BYTE* const base = zc->base;
+	const U32 target = (U32)(ip - base);
+	U32 idx = zc->nextToUpdate;
+
+	while(idx < target) { /* catch up */
+		size_t const h = ZSTD_hashPtr(base+idx, hashLog, mls);
+		NEXT_IN_CHAIN(idx, chainMask) = hashTable[h];
+		hashTable[h] = idx;
+		idx++;

+MODULE_DESCRIPTION("Zstd Decompressor");
diff --git a/lib/zstd/entropy_common.c b/lib/zstd/entropy_common.c
new file mode 100644
index 0000000..b354fc2
--- /dev/null
+++ b/lib/zstd/entropy_common.c
@@ -0,0 +1,244 @@
+/*
+ * Common functions of New Generation Entropy library
+ * Copyright (C) 2016, Yann Collet.
