         XCTAssertEqual(newEntries[0].data, data)
     }
 
+    func test2() throws {
+        let dict = [
+            "SWCompression/Tests/TAR": "value",
+            "key": "valuevaluevaluevaluevaluevaluevaluevaluevaluevaluevaluevaluevaluevaluevaluevaluevaluevalue22"
+        ]
+
+        var info = TarEntryInfo(name: "symbolic-link", type: .symbolicLink)
+        info.accessTime = Date(timeIntervalSince1970: 1)
+        info.creationTime = Date(timeIntervalSince1970: 2)
+        info.modificationTime = Date(timeIntervalSince1970: 0)
+        info.permissions = Permissions(rawValue: 420)
+        info.permissions?.insert(.executeOwner)
+        info.ownerID = 250
+        info.groupID = 250
+        info.ownerUserName = "testUserName"
+        info.ownerGroupName = "testGroupName"
+        info.deviceMajorNumber = 1
+        info.deviceMinorNumber = 2
+        info.charset = "UTF-8"
+        info.comment = "some comment..."
+        info.linkName = "file"
+        info.unknownExtendedHeaderRecords = dict
+        let entry = TarEntry(info: info, data: Data())
+
+        let containerData = try TarWriterTests.generateContainerData([entry])
+        XCTAssertEqual(try TarContainer.formatOf(container: containerData), .pax)
+        let newInfo = try TarContainer.open(container: containerData)[0].info
+
+        XCTAssertEqual(newInfo.name, "symbolic-link")
+        XCTAssertEqual(newInfo.type, .symbolicLink)
+        XCTAssertEqual(newInfo.permissions?.rawValue, 484)
+        XCTAssertEqual(newInfo.ownerID, 250)
+        XCTAssertEqual(newInfo.groupID, 250)
+        XCTAssertEqual(newInfo.size, 0)
+        XCTAssertEqual(newInfo.modificationTime?.timeIntervalSince1970, 0)
+        XCTAssertEqual(newInfo.linkName, "file")
+        XCTAssertEqual(newInfo.ownerUserName, "testUserName")
+        XCTAssertEqual(newInfo.ownerGroupName, "testGroupName")
+        XCTAssertEqual(newInfo.deviceMajorNumber, 1)
+        XCTAssertEqual(newInfo.deviceMinorNumber, 2)
+        XCTAssertEqual(newInfo.accessTime?.timeIntervalSince1970, 1)
+        XCTAssertEqual(newInfo.creationTime?.timeIntervalSince1970, 2)
+        XCTAssertEqual(newInfo.charset, "UTF-8")
+        XCTAssertEqual(newInfo.comment, "some comment...")
+        XCTAssertEqual(newInfo.unknownExtendedHeaderRecords, dict)
+    }
+
+    func testLongName() throws {
+        var info = TarEntryInfo(name: "", type: .regular)
+        info.name = "path/to/"
+        info.name.append(String(repeating: "readme/", count: 15))
+        info.name.append("readme.txt")
+        let entry = TarEntry(info: info, data: Data())
+
+        let containerData = try TarWriterTests.generateContainerData([entry])
+        XCTAssertEqual(try TarContainer.formatOf(container: containerData), .pax)
+        let newInfo = try TarContainer.open(container: containerData)[0].info
+
+        // This name should fit into ustar format using "prefix" field
+        XCTAssertEqual(newInfo.name, info.name)
+    }
+
+    func testVeryLongName() throws {
+        var info = TarEntryInfo(name: "", type: .regular)
+        info.name = "path/to/"
+        info.name.append(String(repeating: "readme/", count: 25))
+        info.name.append("readme.txt")
+        let entry = TarEntry(info: info, data: Data())
+
+        let containerData = try TarWriterTests.generateContainerData([entry])
+        XCTAssertEqual(try TarContainer.formatOf(container: containerData), .pax)
+        let newInfo = try TarContainer.open(container: containerData)[0].info
+
+        XCTAssertEqual(newInfo.name, info.name)
+    }
+
+    func testLongDirectoryName() throws {
+        // Tests what happens to the filename's trailing slash when "prefix" field is used.
+        var info = TarEntryInfo(name: "", type: .regular)
+        info.name = "path/to/"
+        info.name.append(String(repeating: "readme/", count: 15))
+        let entry = TarEntry(info: info, data: Data())
+
+        let containerData = try TarWriterTests.generateContainerData([entry])
+        XCTAssertEqual(try TarContainer.formatOf(container: containerData), .pax)
+        let newInfo = try TarContainer.open(container: containerData)[0].info
+
+        XCTAssertEqual(newInfo.name, info.name)
+    }
+
+    func testUnicode() throws {
+        let date = Date(timeIntervalSince1970: 1300000)
+        var info = TarEntryInfo(name: "ссылка", type: .symbolicLink)
+        info.accessTime = date
+        info.creationTime = date
+        info.modificationTime = date
+        info.permissions = Permissions(rawValue: 420)
+        info.ownerID = 501
+        info.groupID = 20
+        info.ownerUserName = "timofeysolomko"
+        info.ownerGroupName = "staff"
+        info.deviceMajorNumber = 1
+        info.deviceMinorNumber = 2
+        info.comment = "комментарий"
+        info.linkName = "путь/к/файлу"
+        let entry = TarEntry(info: info, data: Data())
+
+        let containerData = try TarWriterTests.generateContainerData([entry])
+        XCTAssertEqual(try TarContainer.formatOf(container: containerData), .pax)
+        let newInfo = try TarContainer.open(container: containerData)[0].info
+
+        XCTAssertEqual(newInfo.name, "ссылка")
+        XCTAssertEqual(newInfo.type, .symbolicLink)
+        XCTAssertEqual(newInfo.permissions?.rawValue, 420)
+        XCTAssertEqual(newInfo.ownerID, 501)
+        XCTAssertEqual(newInfo.groupID, 20)
+        XCTAssertEqual(newInfo.size, 0)
+        XCTAssertEqual(newInfo.modificationTime?.timeIntervalSince1970, 1300000)
+        XCTAssertEqual(newInfo.linkName, "путь/к/файлу")
+        XCTAssertEqual(newInfo.ownerUserName, "timofeysolomko")
+        XCTAssertEqual(newInfo.ownerGroupName, "staff")
+        XCTAssertEqual(newInfo.accessTime?.timeIntervalSince1970, 1300000)
+        XCTAssertEqual(newInfo.creationTime?.timeIntervalSince1970, 1300000)
+        XCTAssertEqual(newInfo.comment, "комментарий")
+    }
+
+    func testUstar() throws {
+        // This set of settings should result in the container which uses only ustar TAR format features.
+        let date = Date(timeIntervalSince1970: 1300000)
+        var info = TarEntryInfo(name: "file.txt", type: .regular)
+        info.permissions = Permissions(rawValue: 420)
+        info.ownerID = 501
+        info.groupID = 20
+        info.modificationTime = date
+        let entry = TarEntry(info: info, data: Data())
+
+        let containerData = try TarWriterTests.generateContainerData([entry], format: .ustar)
+        XCTAssertEqual(try TarContainer.formatOf(container: containerData), .ustar)
+        let newInfo = try TarContainer.open(container: containerData)[0].info
+
+        XCTAssertEqual(newInfo.name, "file.txt")
+        XCTAssertEqual(newInfo.type, .regular)
+        XCTAssertEqual(newInfo.permissions?.rawValue, 420)
+        XCTAssertEqual(newInfo.ownerID, 501)
+        XCTAssertEqual(newInfo.groupID, 20)
+        XCTAssertEqual(newInfo.size, 0)
+        XCTAssertEqual(newInfo.modificationTime?.timeIntervalSince1970, 1300000)
+        XCTAssertEqual(newInfo.linkName, "")
+        XCTAssertEqual(newInfo.ownerUserName, "")
+        XCTAssertEqual(newInfo.ownerGroupName, "")
+        XCTAssertNil(newInfo.accessTime)
+        XCTAssertNil(newInfo.creationTime)
+        XCTAssertNil(newInfo.comment)
+    }
+
+    func testNegativeMtime() throws {
+        let date = Date(timeIntervalSince1970: -1300000)
+        var info = TarEntryInfo(name: "file.txt", type: .regular)
+        info.modificationTime = date
+        let entry = TarEntry(info: info, data: Data())
+
+        let containerData = try TarWriterTests.generateContainerData([entry])
+        XCTAssertEqual(try TarContainer.formatOf(container: containerData), .pax)
+        let newInfo = try TarContainer.open(container: containerData)[0].info
+
+        XCTAssertEqual(newInfo.name, "file.txt")
+        XCTAssertEqual(newInfo.type, .regular)
+        XCTAssertEqual(newInfo.size, 0)
+        XCTAssertEqual(newInfo.modificationTime?.timeIntervalSince1970, -1300000)
+        XCTAssertEqual(newInfo.linkName, "")
+        XCTAssertEqual(newInfo.ownerUserName, "")
+        XCTAssertEqual(newInfo.ownerGroupName, "")
+        XCTAssertNil(newInfo.permissions)
+        XCTAssertNil(newInfo.ownerID)
+        XCTAssertNil(newInfo.groupID)
+        XCTAssertNil(newInfo.accessTime)
+        XCTAssertNil(newInfo.creationTime)
+        XCTAssertNil(newInfo.comment)
+    }
+
+    func testBigUid() throws {
+        // Int.max tests that base-256 encoding of integer fields works in the edge case.
+        for uid in [(1 << 32) - 1, Int.max] {
+            var info = TarEntryInfo(name: "file.txt", type: .regular)
+            info.ownerID = uid
+            let entry = TarEntry(info: info, data: Data())
+
+            let containerData = try TarWriterTests.generateContainerData([entry])
+            XCTAssertEqual(try TarContainer.formatOf(container: containerData), .pax)
+            let newInfo = try TarContainer.open(container: containerData)[0].info
+
+            XCTAssertEqual(newInfo.name, "file.txt")
+            XCTAssertEqual(newInfo.type, .regular)
+            XCTAssertEqual(newInfo.size, 0)
+            XCTAssertEqual(newInfo.ownerID, uid)
+            XCTAssertEqual(newInfo.linkName, "")
+            XCTAssertEqual(newInfo.ownerUserName, "")
+            XCTAssertEqual(newInfo.ownerGroupName, "")
+            XCTAssertNil(newInfo.permissions)
+            XCTAssertNil(newInfo.groupID)
+            XCTAssertNil(newInfo.accessTime)
+            XCTAssertNil(newInfo.creationTime)
+            XCTAssertNil(newInfo.modificationTime)
+            XCTAssertNil(newInfo.comment)
+        }
+    }
+
+    func testGnuLongName() throws {
+        var info = TarEntryInfo(name: "", type: .regular)
+        info.name = "path/to/"
+        info.name.append(String(repeating: "name/", count: 25))
+        info.name.append("name.txt")
+        let entry = TarEntry(info: info, data: Data())
+
+        let containerData = try TarWriterTests.generateContainerData([entry], format: .gnu)
+        XCTAssertEqual(try TarContainer.formatOf(container: containerData), .gnu)
+        let newInfo = try TarContainer.open(container: containerData)[0].info
+
+        XCTAssertEqual(newInfo.name, info.name)
+    }
+
+    func testGnuLongLinkName() throws {
+        var info = TarEntryInfo(name: "", type: .symbolicLink)
+        info.name = "link"
+        info.linkName = "path/to/"
+        info.linkName.append(String(repeating: "name/", count: 25))
+        info.linkName.append("name.txt")
+        let entry = TarEntry(info: info, data: Data())
+
+        let containerData = try TarWriterTests.generateContainerData([entry], format: .gnu)
+        XCTAssertEqual(try TarContainer.formatOf(container: containerData), .gnu)
+        let newInfo = try TarContainer.open(container: containerData)[0].info
+
+        XCTAssertEqual(newInfo.name, info.name)
+    }
+
+    func testGnuBothLongNames() throws {
+        var info = TarEntryInfo(name: "", type: .symbolicLink)
+        info.name = "path/to/"
+        info.name.append(String(repeating: "name/", count: 25))
+        info.name.append("name.txt")
+        info.linkName = "path/to/"
+        info.linkName.append(String(repeating: "link/", count: 25))
+        info.linkName.append("link.txt")
+        let entry = TarEntry(info: info, data: Data())
+
+        let containerData = try TarWriterTests.generateContainerData([entry], format: .gnu)
+        XCTAssertEqual(try TarContainer.formatOf(container: containerData), .gnu)
+        let newInfo = try TarContainer.open(container: containerData)[0].info
+
+        XCTAssertEqual(newInfo.name, info.name)
+    }
+
+    func testGnuTimes() throws {
+        var info = TarEntryInfo(name: "dir", type: .directory)
+        info.ownerUserName = "tsolomko"
+        info.ownerGroupName = "staff"
+        info.ownerID = 501
+        info.groupID = 20
+        info.permissions = Permissions(rawValue: 420)
+        // We have to convert time interval to int, since tar can't store fractional timestamps, so we lose in accuracy.
+        let intTimeInterval = Int(Date().timeIntervalSince1970)
+        let date = Date(timeIntervalSince1970: Double(intTimeInterval))
+        info.modificationTime = date
+        info.creationTime = date
+        info.accessTime = date
+        let entry = TarEntry(info: info, data: Data())
+
+        let containerData = try TarWriterTests.generateContainerData([entry], format: .gnu)
+        XCTAssertEqual(try TarContainer.formatOf(container: containerData), .gnu)
+        let newEntries = try TarContainer.open(container: containerData)
+
+        XCTAssertEqual(newEntries.count, 1)
+        XCTAssertEqual(newEntries[0].info.name, "dir")
+        XCTAssertEqual(newEntries[0].info.type, .directory)
+        XCTAssertEqual(newEntries[0].info.size, 0)
+        XCTAssertEqual(newEntries[0].info.ownerUserName, "tsolomko")
+        XCTAssertEqual(newEntries[0].info.ownerGroupName, "staff")
+        XCTAssertEqual(newEntries[0].info.ownerID, 501)
+        XCTAssertEqual(newEntries[0].info.groupID, 20)
+        XCTAssertEqual(newEntries[0].info.permissions, Permissions(rawValue: 420))
+        XCTAssertEqual(newEntries[0].info.modificationTime, date)
+        XCTAssertEqual(newEntries[0].info.creationTime, date)
+        XCTAssertEqual(newEntries[0].info.accessTime, date)
+        XCTAssertNil(newEntries[0].info.comment)
+    }
+
 }

        let data = Data("Hello, World!\n".utf8)
        let entry = TarEntry(info: info, data: data)

        let tempFileUrl = URL(fileURLWithPath: NSTemporaryDirectory()).appendingPathComponent(UUID().uuidString, isDirectory: false)
        try "".write(to: tempFileUrl, atomically: true, encoding: .utf8)
        let handle = try FileHandle(forWritingTo: tempFileUrl)
        var writer = TarWriter(fileHandle: handle)
        try writer.append(entry)
        try writer.finalize()
        try handle.closeCompat()
        let containerData = try Data(contentsOf: tempFileUrl)
        XCTAssertEqual(try TarContainer.formatOf(container: containerData), .pax)
        let newEntries = try TarContainer.open(container: containerData)



class TarWriterTests: XCTestCase {

    private static let tempDir = URL(fileURLWithPath: NSTemporaryDirectory())
        .appendingPathComponent("TestSWCompression-" + UUID().uuidString, isDirectory: true)

    class override func setUp() {
        do {
            try FileManager.default.createDirectory(at: tempDir, withIntermediateDirectories: true, attributes: nil)
        } catch let error {
            fatalError("TarWriterTests.setUp(): unable to create temporary directory: \(error)")
        }
    }

    class override func tearDown() {
        do {
            try FileManager.default.removeItem(at: tempDir)
        } catch let error {
            fatalError("TarWriterTests.tearDown(): unable to remove temporary directory: \(error)")
        }
    }

    private static func generateContainerData(_ entries: [TarEntry], format: TarContainer.Format = .pax) throws -> Data {
        let tempFileUrl = tempDir.appendingPathComponent(UUID().uuidString, isDirectory: false)
        try "".write(to: tempFileUrl, atomically: true, encoding: .utf8)
        let handle = try FileHandle(forWritingTo: tempFileUrl)
        var writer = TarWriter(fileHandle: handle, format: format)
        for entry in entries {
            try writer.append(entry)
        }
        try writer.finalize()
        try handle.closeCompat()
        return try Data(contentsOf: tempFileUrl)
    }

    func test1() throws {
        var info = TarEntryInfo(name: "file.txt", type: .regular)
        info.ownerUserName = "timofeysolomko"
        info.ownerGroupName = "staff"
