         }
         self.lengths = newLengths.sorted()
 
-        self.minBits = 16
-        self.maxBits = -1
-
-        self.populateHuffmanSymbols()
-        self.minMaxBits()
-    }
-
-    private mutating func populateHuffmanSymbols() {
-        // Auxiliarly subfunction, which computes reversed order of bits in a number
+        // Calculates symbols for all lengths in the table
         func reverse(bits: Int, in symbol: Int) -> Int {
+            // Auxiliarly subfunction, which computes reversed order of bits in a number
             // This is some weird magic
             var a = 1 << 0
             var b = 1 << (bits - 1)


        // Calculates symbol and reversedSymbol properties for each length in 'lengths' array
        // This is done with the help of some weird magic
        var bits = -1
        var symbol = -1
        for index in 0..<self.lengths.count {
            symbol += 1
            let length = self.lengths[index]
            if length.bits != bits {
                symbol <<= (length.bits - bits)
                bits = length.bits
            }
            self.lengths[index].symbol = symbol
            self.lengths[index].reversedSymbol = reverse(bits: bits, in: symbol)
        }
    }

    private mutating func minMaxBits() {
        // Finds minimum and maximum bits in the entire table of lengths
        (self.minBits, self.maxBits) = self.lengths.reduce((16, -1)) {
            (tuple: (Int, Int), length: HuffmanLength) -> (Int, Int) in
            return (min(tuple.0, length.bits), max(tuple.1, length.bits))
        }
    }

}

struct HuffmanLength: Comparable, CustomStringConvertible {


import Foundation

class HuffmanTable: CustomStringConvertible {

    var lengths: [HuffmanLength]

