public void TestBasicArithmeticCodingRoundtrip2()
        {
            const string testString   = "ユチエフ-8は素晴らしいです";
            var          data         = Encoding.UTF8.GetBytes(testString);
            var          frequencies  = ArithmeticCoder.CalculateFrequencies(data);
            var          encodedData  = ArithmeticCoder.Encode(data, frequencies);
            var          decodedData  = ArithmeticCoder.Decode(encodedData, frequencies, data.Length);
            var          resultString = Encoding.UTF8.GetString(decodedData);

            Console.WriteLine("{0} {1} {2}", data.Length, encodedData.Length, decodedData.Length);
            Console.WriteLine(encodedData.Aggregate("", (s, b) => s + ", " + b));
            Console.WriteLine(testString);
            Console.WriteLine(resultString);
            Assert.LessOrEqual(encodedData.Length, data.Length);
            Assert.AreEqual(testString, resultString);
        }
        /// <summary>
        /// Decodes a symbol using the <paramref name="coder"/> with the provided
        /// <paramref name="model"/>.
        /// </summary>
        public static TSymbolType Decode <TSymbolType>(this ArithmeticCoder coder, IModel <TSymbolType> model,
                                                       ReadBitDelegate bitReader)
            where TSymbolType : struct
        {
            // read value
            uint value = coder.DecodeTarget(model.TotalFrequencies);

            // determine symbol
            RangeSymbol <TSymbolType> rangeSymbol = model.Decode(value);

            // adapt decoder
            coder.Decode(rangeSymbol.Range, bitReader);

            // update model
            model.Update(rangeSymbol.Symbol);

            return(rangeSymbol.Symbol);
        }