                 guard codeOfByte.count > 0
                     else { throw DeflateError.SymbolNotFound }
                 bitWriter.write(bits: codeOfByte)
-            case .lengthDistance(let length, let distance, let lengthSymbol, let distanceSymbol):
-                let lengthExtra = length - HuffmanTree.Constants.lengthBase[lengthSymbol - 257]
-                let extraLengthBitsCount = (257 <= lengthSymbol && lengthSymbol <= 260) || lengthSymbol == 285 ?
-                    0 : (((lengthSymbol - 257) >> 2) - 1)
-
-                let codeOfLength = mainLiterals.code(symbol: lengthSymbol)
+            case .lengthDistance(let ld):
+                let codeOfLength = mainLiterals.code(symbol: ld.lengthSymbol)
                 guard codeOfLength.count > 0
                     else { throw DeflateError.SymbolNotFound }
                 bitWriter.write(bits: codeOfLength)
-                bitWriter.write(number: lengthExtra, bitsCount: extraLengthBitsCount)
-
-                let distanceExtra = distance - HuffmanTree.Constants.distanceBase[distanceSymbol]
-                let extraDistanceBitsCount = distanceSymbol == 0 || distanceSymbol == 1 ? 0 : ((distanceSymbol >> 1) - 1)
-
-                let codeOfDistance = mainDistances.code(symbol: distanceSymbol)
+                bitWriter.write(number: ld.lengthExtraBits, bitsCount: ld.lengthExtraBitsCount)
+
+                let codeOfDistance = mainDistances.code(symbol: ld.distanceSymbol)
                 guard codeOfDistance.count > 0
                     else { throw DeflateError.SymbolNotFound }
                 bitWriter.write(bits: codeOfDistance)
-                bitWriter.write(number: distanceExtra, bitsCount: extraDistanceBitsCount)
+                bitWriter.write(number: ld.distanceExtraBits, bitsCount: ld.distanceExtraBitsCount)
             }
         }
 

        return bitWriter.buffer
    }

    private enum BLDCode: CustomStringConvertible {
        case byte(UInt8)
        case lengthDistance(Int, Int, Int, Int)

        var description: String {
            switch self {
            case .byte(let byte):
                return "raw symbol: \(byte)"
            case .lengthDistance(let length, let distance, let lengthSymbol, let distanceSymbol):
                return "length: \(length), length symbol: \(lengthSymbol), distance: \(distance), distance symbol: \(distanceSymbol)"
            }
        }
    }

        let staticHuffmanBlockSize = bitsCount % 8 == 0 ? bitsCount / 8 : bitsCount / 8 + 1

        if uncompBlockSize <= staticHuffmanBlockSize {
            // If according to our calculations static huffman will not make output smaller than input,
            // we fallback to creating uncompressed block.
            // In this case dynamic Huffman encoding can be efficient.
            // TODO: Implement dynamic Huffman code!
