diff --git a/lib/cmp_icu_new.c b/lib/cmp_icu_new.c
index f4bec3665d54726e3910055fc0f20a0f02053aca..d69ab0f543b238e26dfb11f6736a6c6cdec356fc 100644
--- a/lib/cmp_icu_new.c
+++ b/lib/cmp_icu_new.c
@@ -307,8 +307,8 @@ static int encode_normal(uint32_t value, int stream_len,
 
 
 /**
- * @brief subtract the model from the data and encode the result and put it into
- *	bitstream, for outlier use the zero escape symbol mechanism
+ * @brief subtract the model from the data, encode the result and put it into
+ *	bitstream, for encodeing outlier use the zero escape symbol mechanism
  *
  * @param data		data to encode
  * @param model		model of the data (0 if not used)
@@ -316,9 +316,11 @@ static int encode_normal(uint32_t value, int stream_len,
  * @param setup		pointer to the encoder setup
  *
  * @returns the bit length of the bitstream with the added encoded value on
- *	success; negative on error
+ *	success; negative on error, CMP_ERROR_SAMLL_BUF if the bitstream buffer
+ *	is too small to put the value in the bitstream
  *
  * @note no check if data or model are in the allowed range
+ * @note no check if the setup->outlier_par is in the allowed range
  */
 
 static int encode_value_zero(uint32_t data, uint32_t model, int stream_len,
@@ -328,13 +330,13 @@ static int encode_value_zero(uint32_t data, uint32_t model, int stream_len,
 
 	data = map_to_pos(data, setup->max_value_bits);
 
-	/* For performance reasons we check if there is an outlier before adding
-	 * one to the data, than the other way around:
+	/* For performance reasons, we check to see if there is an outlier
+	 * before adding one, rather than the other way around:
 	 * data++;
 	 * if (data < setup->outlier_par && data != 0)
 	 *	return ...
 	 */
-	if (data < (setup->outlier_par - 1)) {
+	if (data < (setup->outlier_par - 1)) { /* detect r */
 		data++; /* add 1 to every value so we can use 0 as escape symbol */
 		return encode_normal(data, stream_len, setup);
 	}
@@ -355,74 +357,57 @@ static int encode_value_zero(uint32_t data, uint32_t model, int stream_len,
 }
 
 
-static int cal_multi_offset(unsigned int unencoded_data)
-{
-	if (unencoded_data <= 0x3)
-		return 0;
-	if (unencoded_data <= 0xF)
-		return 1;
-	if (unencoded_data <= 0x3F)
-		return 2;
-	if (unencoded_data <= 0xFF)
-		return 3;
-	if (unencoded_data <= 0x3FF)
-		return 4;
-	if (unencoded_data <= 0xFFF)
-		return 5;
-	if (unencoded_data <= 0x3FFF)
-		return 6;
-	if (unencoded_data <= 0xFFFF)
-		return 7;
-	if (unencoded_data <= 0x3FFFF)
-		return 8;
-	if (unencoded_data <= 0xFFFFF)
-		return 9;
-	if (unencoded_data <= 0x3FFFFF)
-		return 10;
-	if (unencoded_data <= 0xFFFFFF)
-		return 11;
-	if (unencoded_data <= 0x3FFFFFF)
-		return 12;
-	if (unencoded_data <= 0xFFFFFFF)
-		return 13;
-	if (unencoded_data <= 0x3FFFFFFF)
-		return 14;
-	else
-		return 15;
-}
-
+/**
+ * @brief subtract the model from the data, encode the result and put it into
+ *	bitstream, for encoding outlier use the multi escape symbol mechanism
+ *
+ * @param data		data to encode
+ * @param model		model of the data (0 if not used)
+ * @param stream_len	length of the bitstream in bits
+ * @param setup		pointer to the encoder setup
+ *
+ * @returns the bit length of the bitstream with the added encoded value on
+ *	success; negative on error, CMP_ERROR_SAMLL_BUF if the bitstream buffer
+ *	is too small to put the value in the bitstream
+ *
+ * @note no check if data or model are in the allowed range
+ * @note no check if the setup->outlier_par is in the allowed ragne
+ */
 
-#if 0
 static int encode_value_multi(uint32_t data, uint32_t model, int stream_len,
 			      struct encoder_setupt *setup)
 {
 	uint32_t unencoded_data;
 	unsigned int unencoded_data_len;
-	uint32_t escape_sym;
-	uint32_t escape_sym_offset;
+	uint32_t escape_sym, escape_sym_offset;
 
 	data -= model; /* possible underflow is intended */
 
 	data = map_to_pos(data, setup->max_value_bits);
 
-	if (data < setup->outlier_par)
+	if (data < setup->outlier_par) /* detect non-outlier */
 		return  encode_normal(data, stream_len, setup);
+
 	/*
 	 * In this mode we put the difference between the data and the spillover
 	 * threshold value (unencoded_data) after a encoded escape symbol, which
 	 * indicate that the next codeword is unencoded.
 	 * We use different escape symbol depended on the size the needed bit of
 	 * unencoded data:
-	 * 0, 1, 2 bits needed for unencoded data -> escape symbol is spill + 0
-	 * 3, 4 bits needed for unencoded data -> escape symbol is spill + 1
-	 * ..
+	 * 0, 1, 2 bits needed for unencoded data -> escape symbol is outlier_par + 0
+	 * 3, 4 bits needed for unencoded data -> escape symbol is outlier_par + 1
+	 * 5, 6 bits needed for unencoded data -> escape symbol is outlier_par + 2
+	 * and so on
 	 */
-
 	unencoded_data = data - setup->outlier_par;
 
-	escape_sym_offset = cal_multi_offset(unencoded_data);
-	escape_sym  = setup->outlier_par + escape_sym_offset;
-	unencoded_data_len = (escape_sym_offset + 1) * 2;
+	if (!unencoded_data) /* catch __builtin_clz(0) because the result is undefined.*/
+		escape_sym_offset = 0;
+	else
+		escape_sym_offset = (31U - (uint32_t)__builtin_clz(unencoded_data)) >> 1;
+
+	escape_sym = setup->outlier_par + escape_sym_offset;
+	unencoded_data_len = (escape_sym_offset + 1U) << 1;
 
 	/* put the escape symbol in the bitstream */
 	stream_len = encode_normal(escape_sym, stream_len, setup);
@@ -435,4 +420,3 @@ static int encode_value_multi(uint32_t data, uint32_t model, int stream_len,
 
 	return stream_len;
 }
-#endif
diff --git a/test/cmp_icu/test_cmp_icu_new.c b/test/cmp_icu/test_cmp_icu_new.c
index 986b7b648a0f73c5ab800860afa720fc72f37502..a0d9109e72c3dd25a971ce47e6179dce6cfb8ede 100644
--- a/test/cmp_icu/test_cmp_icu_new.c
+++ b/test/cmp_icu/test_cmp_icu_new.c
@@ -8,8 +8,8 @@
 
 
 /**
-* @test map_to_pos
-*/
+ * @test map_to_pos
+ */
 
 void test_map_to_pos(void)
 {
@@ -780,7 +780,7 @@ void test_encode_value_zero(void)
 	TEST_ASSERT_EQUAL_HEX(0xFFFFFFFF, bitstream[2]);
 
 	/* maximum negative value to encode */
-	data = -32U; model = 0;
+	data = 0; model = 32;
 	stream_len = encode_value_zero(data, model, stream_len, &setup);
 	TEST_ASSERT_EQUAL_INT(53, stream_len);
 	TEST_ASSERT_EQUAL_HEX(0xFFFFFFFE, bitstream[0]);
@@ -795,8 +795,100 @@ void test_encode_value_zero(void)
 	setup.max_bit_len = 32;
 	data = 31; model = 0;
 	stream_len = encode_value_zero(data, model, stream_len, &setup);
-	TEST_ASSERT_EQUAL_INT(-2, stream_len);
+	TEST_ASSERT_EQUAL_INT(CMP_ERROR_SAMLL_BUF, stream_len);
 	TEST_ASSERT_EQUAL_HEX(0, bitstream[0]);
 	TEST_ASSERT_EQUAL_HEX(0, bitstream[1]);
 	TEST_ASSERT_EQUAL_HEX(0, bitstream[2]);
 }
+
+
+/**
+ * @test encode_value_multi
+ */
+
+void test_encode_value_multi(void)
+{
+	uint32_t data, model;
+	int stream_len;
+	struct encoder_setupt setup = {0};
+	uint32_t bitstream[4] = {0};
+
+	/* setup the setup */
+	setup.encoder_par1 = 1;
+	setup.encoder_par2 = (uint32_t)ilog_2(setup.encoder_par1);
+	setup.outlier_par = 16;
+	setup.max_value_bits = 32;
+	setup.generate_cw = Rice_encoder;
+	setup.bitstream_adr = bitstream;
+	setup.max_bit_len = sizeof(bitstream) * CHAR_BIT;
+
+	stream_len = 0;
+
+	data = 0; model = 0;
+	stream_len = encode_value_multi(data, model, stream_len, &setup);
+	TEST_ASSERT_EQUAL_INT(1, stream_len);
+	TEST_ASSERT_EQUAL_HEX(0x00000000, bitstream[0]);
+	TEST_ASSERT_EQUAL_HEX(0x00000000, bitstream[1]);
+	TEST_ASSERT_EQUAL_HEX(0x00000000, bitstream[2]);
+	TEST_ASSERT_EQUAL_HEX(0x00000000, bitstream[3]);
+
+	data = 0; model = 1;
+	stream_len = encode_value_multi(data, model, stream_len, &setup);
+	TEST_ASSERT_EQUAL_INT(3, stream_len);
+	TEST_ASSERT_EQUAL_HEX(0x40000000, bitstream[0]);
+	TEST_ASSERT_EQUAL_HEX(0x00000000, bitstream[1]);
+	TEST_ASSERT_EQUAL_HEX(0x00000000, bitstream[2]);
+	TEST_ASSERT_EQUAL_HEX(0x00000000, bitstream[3]);
+
+	data = 1+23; model = 0+23;
+	stream_len = encode_value_multi(data, model, stream_len, &setup);
+	TEST_ASSERT_EQUAL_INT(6, stream_len);
+	TEST_ASSERT_EQUAL_HEX(0x58000000, bitstream[0]);
+	TEST_ASSERT_EQUAL_HEX(0x00000000, bitstream[1]);
+	TEST_ASSERT_EQUAL_HEX(0x00000000, bitstream[2]);
+	TEST_ASSERT_EQUAL_HEX(0x00000000, bitstream[3]);
+
+	/* highest value without multi outlier encoding */
+	data = 0+42; model = 8+42;
+	stream_len = encode_value_multi(data, model, stream_len, &setup);
+	TEST_ASSERT_EQUAL_INT(22, stream_len);
+	TEST_ASSERT_EQUAL_HEX(0x5BFFF800, bitstream[0]);
+	TEST_ASSERT_EQUAL_HEX(0x00000000, bitstream[1]);
+	TEST_ASSERT_EQUAL_HEX(0x00000000, bitstream[2]);
+	TEST_ASSERT_EQUAL_HEX(0x00000000, bitstream[3]);
+
+	/* lowest value with multi outlier encoding */
+	data = 8+42; model = 0+42;
+	stream_len = encode_value_multi(data, model, stream_len, &setup);
+	TEST_ASSERT_EQUAL_INT(41, stream_len);
+	TEST_ASSERT_EQUAL_HEX(0x5BFFFBFF, bitstream[0]);
+	TEST_ASSERT_EQUAL_HEX(0xFC000000, bitstream[1]);
+	TEST_ASSERT_EQUAL_HEX(0x00000000, bitstream[2]);
+	TEST_ASSERT_EQUAL_HEX(0x00000000, bitstream[3]);
+
+	/* highest value with multi outlier encoding */
+	data = INT32_MIN; model = 0;
+	stream_len = encode_value_multi(data, model, stream_len, &setup);
+	TEST_ASSERT_EQUAL_INT(105, stream_len);
+	TEST_ASSERT_EQUAL_HEX(0x5BFFFBFF, bitstream[0]);
+	TEST_ASSERT_EQUAL_HEX(0xFC7FFFFF, bitstream[1]);
+	TEST_ASSERT_EQUAL_HEX(0xFF7FFFFF, bitstream[2]);
+	TEST_ASSERT_EQUAL_HEX(0xF7800000, bitstream[3]);
+
+	/* small buffer error */
+	data = 0; model = 38;
+	stream_len = encode_value_multi(data, model, stream_len, &setup);
+	TEST_ASSERT_EQUAL_INT(CMP_ERROR_SAMLL_BUF, stream_len);
+
+	/* small buffer error when creating the multi escape symbol*/
+	bitstream[0] = 0;
+	bitstream[1] = 0;
+	setup.max_bit_len = 32;
+
+	stream_len = 32;
+	data = 31; model = 0;
+	stream_len = encode_value_multi(data, model, stream_len, &setup);
+	TEST_ASSERT_EQUAL_INT(CMP_ERROR_SAMLL_BUF, stream_len);
+	TEST_ASSERT_EQUAL_HEX(0, bitstream[0]);
+	TEST_ASSERT_EQUAL_HEX(0, bitstream[1]);
+}