{"diffoscope-json-version": 1, "source1": "/input1", "source2": "/input2", "unified_diff": null, "details": [{"source1": "zipinfo {}", "source2": "zipinfo {}", "unified_diff": "@@ -1,8 +1,8 @@\n-Zip file size: 34198 bytes, number of entries: 33\n+Zip file size: 34340 bytes, number of entries: 33\n -rw-r--r--  2.0 unx       64 b- defN 20-Apr-01 08:04 META-INF/MANIFEST.MF\n drwxr-xr-x  2.0 unx        0 b- stor 20-Apr-01 08:04 META-INF/\n drwxr-xr-x  2.0 unx        0 b- stor 20-Apr-01 08:04 org/\n drwxr-xr-x  2.0 unx        0 b- stor 20-Apr-01 08:04 org/apache/\n drwxr-xr-x  2.0 unx        0 b- stor 20-Apr-01 08:04 org/apache/dubbo/\n drwxr-xr-x  2.0 unx        0 b- stor 20-Apr-01 08:04 org/apache/dubbo/remoting/\n drwxr-xr-x  2.0 unx        0 b- stor 20-Apr-01 08:04 org/apache/dubbo/remoting/transport/\n@@ -13,23 +13,23 @@\n drwxr-xr-x  2.0 unx        0 b- stor 20-Apr-01 08:04 META-INF/maven/\n drwxr-xr-x  2.0 unx        0 b- stor 20-Apr-01 08:04 META-INF/maven/org.apache.dubbo/\n drwxr-xr-x  2.0 unx        0 b- stor 20-Apr-01 08:04 META-INF/maven/org.apache.dubbo/dubbo-remoting-netty4/\n -rw-r--r--  2.0 unx     2767 b- defN 20-Apr-01 08:04 META-INF/DEPENDENCIES\n -rw-r--r--  2.0 unx    11358 b- defN 20-Apr-01 08:04 META-INF/LICENSE\n -rw-r--r--  2.0 unx      178 b- defN 20-Apr-01 08:04 META-INF/NOTICE\n -rw-r--r--  2.0 unx    10214 b- defN 20-Apr-01 08:04 org/apache/dubbo/remoting/transport/netty4/NettyBackedChannelBuffer.java\n--rw-r--r--  2.0 unx     8769 b- defN 20-Apr-01 08:04 org/apache/dubbo/remoting/transport/netty4/NettyChannel.java\n--rw-r--r--  2.0 unx     9286 b- defN 20-Apr-01 08:04 org/apache/dubbo/remoting/transport/netty4/NettyClient.java\n--rw-r--r--  2.0 unx     6249 b- defN 20-Apr-01 08:04 org/apache/dubbo/remoting/transport/netty4/NettyClientHandler.java\n--rw-r--r--  2.0 unx     3547 b- defN 20-Apr-01 08:04 org/apache/dubbo/remoting/transport/netty4/NettyCodecAdapter.java\n--rw-r--r--  2.0 unx     2654 b- defN 20-Apr-01 08:04 org/apache/dubbo/remoting/transport/netty4/NettyEventLoopFactory.java\n--rw-r--r--  2.0 unx     7939 b- defN 20-Apr-01 08:04 org/apache/dubbo/remoting/transport/netty4/NettyServer.java\n--rw-r--r--  2.0 unx     5243 b- defN 20-Apr-01 08:04 org/apache/dubbo/remoting/transport/netty4/NettyServerHandler.java\n--rw-r--r--  2.0 unx     1614 b- defN 20-Apr-01 08:04 org/apache/dubbo/remoting/transport/netty4/NettyTransporter.java\n--rw-r--r--  2.0 unx     5550 b- defN 20-Apr-01 08:04 org/apache/dubbo/remoting/transport/netty4/SslContexts.java\n--rw-r--r--  2.0 unx     5835 b- defN 20-Apr-01 08:04 org/apache/dubbo/remoting/transport/netty4/SslHandlerInitializer.java\n+-rw-r--r--  2.0 unx     9045 b- defN 20-Apr-01 08:04 org/apache/dubbo/remoting/transport/netty4/NettyChannel.java\n+-rw-r--r--  2.0 unx     9503 b- defN 20-Apr-01 08:04 org/apache/dubbo/remoting/transport/netty4/NettyClient.java\n+-rw-r--r--  2.0 unx     6410 b- defN 20-Apr-01 08:04 org/apache/dubbo/remoting/transport/netty4/NettyClientHandler.java\n+-rw-r--r--  2.0 unx     3648 b- defN 20-Apr-01 08:04 org/apache/dubbo/remoting/transport/netty4/NettyCodecAdapter.java\n+-rw-r--r--  2.0 unx     2714 b- defN 20-Apr-01 08:04 org/apache/dubbo/remoting/transport/netty4/NettyEventLoopFactory.java\n+-rw-r--r--  2.0 unx     8141 b- defN 20-Apr-01 08:04 org/apache/dubbo/remoting/transport/netty4/NettyServer.java\n+-rw-r--r--  2.0 unx     5381 b- defN 20-Apr-01 08:04 org/apache/dubbo/remoting/transport/netty4/NettyServerHandler.java\n+-rw-r--r--  2.0 unx     1657 b- defN 20-Apr-01 08:04 org/apache/dubbo/remoting/transport/netty4/NettyTransporter.java\n+-rw-r--r--  2.0 unx     5671 b- defN 20-Apr-01 08:04 org/apache/dubbo/remoting/transport/netty4/SslContexts.java\n+-rw-r--r--  2.0 unx     5976 b- defN 20-Apr-01 08:04 org/apache/dubbo/remoting/transport/netty4/SslHandlerInitializer.java\n -rw-r--r--  2.0 unx     2243 b- defN 20-Apr-01 08:04 org/apache/dubbo/remoting/transport/netty4/logging/FormattingTuple.java\n--rw-r--r--  2.0 unx    14622 b- defN 20-Apr-01 08:04 org/apache/dubbo/remoting/transport/netty4/logging/MessageFormatter.java\n+-rw-r--r--  2.0 unx    15032 b- defN 20-Apr-01 08:04 org/apache/dubbo/remoting/transport/netty4/logging/MessageFormatter.java\n -rw-r--r--  2.0 unx      133 b- defN 20-Apr-01 08:04 META-INF/dubbo/internal/org.apache.dubbo.remoting.Transporter\n--rw-r--r--  2.0 unx     2399 b- defN 20-Apr-01 08:04 META-INF/maven/org.apache.dubbo/dubbo-remoting-netty4/pom.xml\n+-rw-r--r--  2.0 unx     2340 b- defN 20-Apr-01 08:04 META-INF/maven/org.apache.dubbo/dubbo-remoting-netty4/pom.xml\n -rw-r--r--  2.0 unx       76 b- defN 20-Apr-01 08:04 META-INF/maven/org.apache.dubbo/dubbo-remoting-netty4/pom.properties\n-33 files, 100740 bytes uncompressed, 28768 bytes compressed:  71.4%\n+33 files, 102551 bytes uncompressed, 28910 bytes compressed:  71.8%\n"}, {"source1": "zipdetails --redact --scan --utc {}", "source2": "zipdetails --redact --scan --utc {}", "unified_diff": "@@ -337,1334 +337,1334 @@\n 1DB4 Extract Zip Spec      14 (20) '2.0'\n 1DB5 Extract OS            00 (0) 'MS-DOS'\n 1DB6 General Purpose Flag  0800 (2048)\n      [Bits 1-2]            0 'Normal Compression'\n      [Bit 11]              1 'Language Encoding'\n 1DB8 Compression Method    0008 (8) 'Deflated'\n 1DBA Modification Time     50814080 (1350647936) 'Wed Apr  1 08:04:00 2020'\n-1DBE CRC                   CD460ADB (3443919579)\n-1DC2 Compressed Size       0000096A (2410)\n-1DC6 Uncompressed Size     00002241 (8769)\n+1DBE CRC                   EADF50E0 (3940503776)\n+1DC2 Compressed Size       0000097F (2431)\n+1DC6 Uncompressed Size     00002355 (9045)\n 1DCA Filename Length       003C (60)\n 1DCC Extra Length          0000 (0)\n 1DCE Filename              'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX'\n #\n # WARNING: Offset 0x1DCE: Filename 'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX'\n #          Zero length filename\n #\n 1E0A PAYLOAD\n \n-2774 LOCAL HEADER #20      04034B50 (67324752)\n-2778 Extract Zip Spec      14 (20) '2.0'\n-2779 Extract OS            00 (0) 'MS-DOS'\n-277A General Purpose Flag  0800 (2048)\n+2789 LOCAL HEADER #20      04034B50 (67324752)\n+278D Extract Zip Spec      14 (20) '2.0'\n+278E Extract OS            00 (0) 'MS-DOS'\n+278F General Purpose Flag  0800 (2048)\n      [Bits 1-2]            0 'Normal Compression'\n      [Bit 11]              1 'Language Encoding'\n-277C Compression Method    0008 (8) 'Deflated'\n-277E Modification Time     50814080 (1350647936) 'Wed Apr  1 08:04:00 2020'\n-2782 CRC                   17148ACF (387222223)\n-2786 Compressed Size       00000AB8 (2744)\n-278A Uncompressed Size     00002446 (9286)\n-278E Filename Length       003B (59)\n-2790 Extra Length          0000 (0)\n-2792 Filename              'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX'\n+2791 Compression Method    0008 (8) 'Deflated'\n+2793 Modification Time     50814080 (1350647936) 'Wed Apr  1 08:04:00 2020'\n+2797 CRC                   1CB2BCAF (481475759)\n+279B Compressed Size       00000AC6 (2758)\n+279F Uncompressed Size     0000251F (9503)\n+27A3 Filename Length       003B (59)\n+27A5 Extra Length          0000 (0)\n+27A7 Filename              'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX'\n #\n-# WARNING: Offset 0x2792: Filename 'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX'\n+# WARNING: Offset 0x27A7: Filename 'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX'\n #          Zero length filename\n #\n-27CD PAYLOAD\n+27E2 PAYLOAD\n \n-3285 LOCAL HEADER #21      04034B50 (67324752)\n-3289 Extract Zip Spec      14 (20) '2.0'\n-328A Extract OS            00 (0) 'MS-DOS'\n-328B General Purpose Flag  0800 (2048)\n+32A8 LOCAL HEADER #21      04034B50 (67324752)\n+32AC Extract Zip Spec      14 (20) '2.0'\n+32AD Extract OS            00 (0) 'MS-DOS'\n+32AE General Purpose Flag  0800 (2048)\n      [Bits 1-2]            0 'Normal Compression'\n      [Bit 11]              1 'Language Encoding'\n-328D Compression Method    0008 (8) 'Deflated'\n-328F Modification Time     50814080 (1350647936) 'Wed Apr  1 08:04:00 2020'\n-3293 CRC                   15F2B7F5 (368228341)\n-3297 Compressed Size       0000074A (1866)\n-329B Uncompressed Size     00001869 (6249)\n-329F Filename Length       0042 (66)\n-32A1 Extra Length          0000 (0)\n-32A3 Filename              'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX'\n+32B0 Compression Method    0008 (8) 'Deflated'\n+32B2 Modification Time     50814080 (1350647936) 'Wed Apr  1 08:04:00 2020'\n+32B6 CRC                   7DE2A421 (2112005153)\n+32BA Compressed Size       0000075A (1882)\n+32BE Uncompressed Size     0000190A (6410)\n+32C2 Filename Length       0042 (66)\n+32C4 Extra Length          0000 (0)\n+32C6 Filename              'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX'\n #\n-# WARNING: Offset 0x32A3: Filename 'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX'\n+# WARNING: Offset 0x32C6: Filename 'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX'\n #          Zero length filename\n #\n-32E5 PAYLOAD\n+3308 PAYLOAD\n \n-3A2F LOCAL HEADER #22      04034B50 (67324752)\n-3A33 Extract Zip Spec      14 (20) '2.0'\n-3A34 Extract OS            00 (0) 'MS-DOS'\n-3A35 General Purpose Flag  0800 (2048)\n+3A62 LOCAL HEADER #22      04034B50 (67324752)\n+3A66 Extract Zip Spec      14 (20) '2.0'\n+3A67 Extract OS            00 (0) 'MS-DOS'\n+3A68 General Purpose Flag  0800 (2048)\n      [Bits 1-2]            0 'Normal Compression'\n      [Bit 11]              1 'Language Encoding'\n-3A37 Compression Method    0008 (8) 'Deflated'\n-3A39 Modification Time     50814080 (1350647936) 'Wed Apr  1 08:04:00 2020'\n-3A3D CRC                   BA9CD18D (3130839437)\n-3A41 Compressed Size       000004BF (1215)\n-3A45 Uncompressed Size     00000DDB (3547)\n-3A49 Filename Length       0041 (65)\n-3A4B Extra Length          0000 (0)\n-3A4D Filename              'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX'\n+3A6A Compression Method    0008 (8) 'Deflated'\n+3A6C Modification Time     50814080 (1350647936) 'Wed Apr  1 08:04:00 2020'\n+3A70 CRC                   3BA2E25A (1000530522)\n+3A74 Compressed Size       000004C9 (1225)\n+3A78 Uncompressed Size     00000E40 (3648)\n+3A7C Filename Length       0041 (65)\n+3A7E Extra Length          0000 (0)\n+3A80 Filename              'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX'\n #\n-# WARNING: Offset 0x3A4D: Filename 'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX'\n+# WARNING: Offset 0x3A80: Filename 'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX'\n #          Zero length filename\n #\n-3A8E PAYLOAD\n+3AC1 PAYLOAD\n \n-3F4D LOCAL HEADER #23      04034B50 (67324752)\n-3F51 Extract Zip Spec      14 (20) '2.0'\n-3F52 Extract OS            00 (0) 'MS-DOS'\n-3F53 General Purpose Flag  0800 (2048)\n+3F8A LOCAL HEADER #23      04034B50 (67324752)\n+3F8E Extract Zip Spec      14 (20) '2.0'\n+3F8F Extract OS            00 (0) 'MS-DOS'\n+3F90 General Purpose Flag  0800 (2048)\n      [Bits 1-2]            0 'Normal Compression'\n      [Bit 11]              1 'Language Encoding'\n-3F55 Compression Method    0008 (8) 'Deflated'\n-3F57 Modification Time     50814080 (1350647936) 'Wed Apr  1 08:04:00 2020'\n-3F5B CRC                   16F071B0 (384856496)\n-3F5F Compressed Size       000003CA (970)\n-3F63 Uncompressed Size     00000A5E (2654)\n-3F67 Filename Length       0045 (69)\n-3F69 Extra Length          0000 (0)\n-3F6B Filename              'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX'\n+3F92 Compression Method    0008 (8) 'Deflated'\n+3F94 Modification Time     50814080 (1350647936) 'Wed Apr  1 08:04:00 2020'\n+3F98 CRC                   1E5B2A86 (509291142)\n+3F9C Compressed Size       000003D1 (977)\n+3FA0 Uncompressed Size     00000A9A (2714)\n+3FA4 Filename Length       0045 (69)\n+3FA6 Extra Length          0000 (0)\n+3FA8 Filename              'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX'\n #\n-# WARNING: Offset 0x3F6B: Filename 'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX'\n+# WARNING: Offset 0x3FA8: Filename 'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX'\n #          Zero length filename\n #\n-3FB0 PAYLOAD\n+3FED PAYLOAD\n \n-437A LOCAL HEADER #24      04034B50 (67324752)\n-437E Extract Zip Spec      14 (20) '2.0'\n-437F Extract OS            00 (0) 'MS-DOS'\n-4380 General Purpose Flag  0800 (2048)\n+43BE LOCAL HEADER #24      04034B50 (67324752)\n+43C2 Extract Zip Spec      14 (20) '2.0'\n+43C3 Extract OS            00 (0) 'MS-DOS'\n+43C4 General Purpose Flag  0800 (2048)\n      [Bits 1-2]            0 'Normal Compression'\n      [Bit 11]              1 'Language Encoding'\n-4382 Compression Method    0008 (8) 'Deflated'\n-4384 Modification Time     50814080 (1350647936) 'Wed Apr  1 08:04:00 2020'\n-4388 CRC                   99FF093E (2583628094)\n-438C Compressed Size       00000923 (2339)\n-4390 Uncompressed Size     00001F03 (7939)\n-4394 Filename Length       003B (59)\n-4396 Extra Length          0000 (0)\n-4398 Filename              'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX'\n+43C6 Compression Method    0008 (8) 'Deflated'\n+43C8 Modification Time     50814080 (1350647936) 'Wed Apr  1 08:04:00 2020'\n+43CC CRC                   1CDD10AA (484249770)\n+43D0 Compressed Size       00000935 (2357)\n+43D4 Uncompressed Size     00001FCD (8141)\n+43D8 Filename Length       003B (59)\n+43DA Extra Length          0000 (0)\n+43DC Filename              'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX'\n #\n-# WARNING: Offset 0x4398: Filename 'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX'\n+# WARNING: Offset 0x43DC: Filename 'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX'\n #          Zero length filename\n #\n-43D3 PAYLOAD\n+4417 PAYLOAD\n \n-4CF6 LOCAL HEADER #25      04034B50 (67324752)\n-4CFA Extract Zip Spec      14 (20) '2.0'\n-4CFB Extract OS            00 (0) 'MS-DOS'\n-4CFC General Purpose Flag  0800 (2048)\n+4D4C LOCAL HEADER #25      04034B50 (67324752)\n+4D50 Extract Zip Spec      14 (20) '2.0'\n+4D51 Extract OS            00 (0) 'MS-DOS'\n+4D52 General Purpose Flag  0800 (2048)\n      [Bits 1-2]            0 'Normal Compression'\n      [Bit 11]              1 'Language Encoding'\n-4CFE Compression Method    0008 (8) 'Deflated'\n-4D00 Modification Time     50814080 (1350647936) 'Wed Apr  1 08:04:00 2020'\n-4D04 CRC                   7ED127C7 (2127636423)\n-4D08 Compressed Size       000005D7 (1495)\n-4D0C Uncompressed Size     0000147B (5243)\n-4D10 Filename Length       0042 (66)\n-4D12 Extra Length          0000 (0)\n-4D14 Filename              'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX'\n+4D54 Compression Method    0008 (8) 'Deflated'\n+4D56 Modification Time     50814080 (1350647936) 'Wed Apr  1 08:04:00 2020'\n+4D5A CRC                   52A8EAC6 (1386801862)\n+4D5E Compressed Size       000005E0 (1504)\n+4D62 Uncompressed Size     00001505 (5381)\n+4D66 Filename Length       0042 (66)\n+4D68 Extra Length          0000 (0)\n+4D6A Filename              'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX'\n #\n-# WARNING: Offset 0x4D14: Filename 'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX'\n+# WARNING: Offset 0x4D6A: Filename 'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX'\n #          Zero length filename\n #\n-4D56 PAYLOAD\n+4DAC PAYLOAD\n \n-532D LOCAL HEADER #26      04034B50 (67324752)\n-5331 Extract Zip Spec      14 (20) '2.0'\n-5332 Extract OS            00 (0) 'MS-DOS'\n-5333 General Purpose Flag  0800 (2048)\n+538C LOCAL HEADER #26      04034B50 (67324752)\n+5390 Extract Zip Spec      14 (20) '2.0'\n+5391 Extract OS            00 (0) 'MS-DOS'\n+5392 General Purpose Flag  0800 (2048)\n      [Bits 1-2]            0 'Normal Compression'\n      [Bit 11]              1 'Language Encoding'\n-5335 Compression Method    0008 (8) 'Deflated'\n-5337 Modification Time     50814080 (1350647936) 'Wed Apr  1 08:04:00 2020'\n-533B CRC                   4AAC1D37 (1252793655)\n-533F Compressed Size       000002CA (714)\n-5343 Uncompressed Size     0000064E (1614)\n-5347 Filename Length       0040 (64)\n-5349 Extra Length          0000 (0)\n-534B Filename              'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX'\n+5394 Compression Method    0008 (8) 'Deflated'\n+5396 Modification Time     50814080 (1350647936) 'Wed Apr  1 08:04:00 2020'\n+539A CRC                   1AC58108 (449151240)\n+539E Compressed Size       000002D4 (724)\n+53A2 Uncompressed Size     00000679 (1657)\n+53A6 Filename Length       0040 (64)\n+53A8 Extra Length          0000 (0)\n+53AA Filename              'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX'\n #\n-# WARNING: Offset 0x534B: Filename 'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX'\n+# WARNING: Offset 0x53AA: Filename 'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX'\n #          Zero length filename\n #\n-538B PAYLOAD\n+53EA PAYLOAD\n \n-5655 LOCAL HEADER #27      04034B50 (67324752)\n-5659 Extract Zip Spec      14 (20) '2.0'\n-565A Extract OS            00 (0) 'MS-DOS'\n-565B General Purpose Flag  0800 (2048)\n+56BE LOCAL HEADER #27      04034B50 (67324752)\n+56C2 Extract Zip Spec      14 (20) '2.0'\n+56C3 Extract OS            00 (0) 'MS-DOS'\n+56C4 General Purpose Flag  0800 (2048)\n      [Bits 1-2]            0 'Normal Compression'\n      [Bit 11]              1 'Language Encoding'\n-565D Compression Method    0008 (8) 'Deflated'\n-565F Modification Time     50814080 (1350647936) 'Wed Apr  1 08:04:00 2020'\n-5663 CRC                   155577E8 (357922792)\n-5667 Compressed Size       00000614 (1556)\n-566B Uncompressed Size     000015AE (5550)\n-566F Filename Length       003B (59)\n-5671 Extra Length          0000 (0)\n-5673 Filename              'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX'\n+56C6 Compression Method    0008 (8) 'Deflated'\n+56C8 Modification Time     50814080 (1350647936) 'Wed Apr  1 08:04:00 2020'\n+56CC CRC                   377C624A (930898506)\n+56D0 Compressed Size       00000621 (1569)\n+56D4 Uncompressed Size     00001627 (5671)\n+56D8 Filename Length       003B (59)\n+56DA Extra Length          0000 (0)\n+56DC Filename              'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX'\n #\n-# WARNING: Offset 0x5673: Filename 'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX'\n+# WARNING: Offset 0x56DC: Filename 'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX'\n #          Zero length filename\n #\n-56AE PAYLOAD\n+5717 PAYLOAD\n \n-5CC2 LOCAL HEADER #28      04034B50 (67324752)\n-5CC6 Extract Zip Spec      14 (20) '2.0'\n-5CC7 Extract OS            00 (0) 'MS-DOS'\n-5CC8 General Purpose Flag  0800 (2048)\n+5D38 LOCAL HEADER #28      04034B50 (67324752)\n+5D3C Extract Zip Spec      14 (20) '2.0'\n+5D3D Extract OS            00 (0) 'MS-DOS'\n+5D3E General Purpose Flag  0800 (2048)\n      [Bits 1-2]            0 'Normal Compression'\n      [Bit 11]              1 'Language Encoding'\n-5CCA Compression Method    0008 (8) 'Deflated'\n-5CCC Modification Time     50814080 (1350647936) 'Wed Apr  1 08:04:00 2020'\n-5CD0 CRC                   FC50D2E5 (4233155301)\n-5CD4 Compressed Size       000005BE (1470)\n-5CD8 Uncompressed Size     000016CB (5835)\n-5CDC Filename Length       0045 (69)\n-5CDE Extra Length          0000 (0)\n-5CE0 Filename              'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX'\n+5D40 Compression Method    0008 (8) 'Deflated'\n+5D42 Modification Time     50814080 (1350647936) 'Wed Apr  1 08:04:00 2020'\n+5D46 CRC                   37334079 (926105721)\n+5D4A Compressed Size       000005C9 (1481)\n+5D4E Uncompressed Size     00001758 (5976)\n+5D52 Filename Length       0045 (69)\n+5D54 Extra Length          0000 (0)\n+5D56 Filename              'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX'\n #\n-# WARNING: Offset 0x5CE0: Filename 'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX'\n+# WARNING: Offset 0x5D56: Filename 'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX'\n #          Zero length filename\n #\n-5D25 PAYLOAD\n+5D9B PAYLOAD\n \n-62E3 LOCAL HEADER #29      04034B50 (67324752)\n-62E7 Extract Zip Spec      14 (20) '2.0'\n-62E8 Extract OS            00 (0) 'MS-DOS'\n-62E9 General Purpose Flag  0800 (2048)\n+6364 LOCAL HEADER #29      04034B50 (67324752)\n+6368 Extract Zip Spec      14 (20) '2.0'\n+6369 Extract OS            00 (0) 'MS-DOS'\n+636A General Purpose Flag  0800 (2048)\n      [Bits 1-2]            0 'Normal Compression'\n      [Bit 11]              1 'Language Encoding'\n-62EB Compression Method    0008 (8) 'Deflated'\n-62ED Modification Time     50814080 (1350647936) 'Wed Apr  1 08:04:00 2020'\n-62F1 CRC                   58FEAB57 (1493085015)\n-62F5 Compressed Size       000003A4 (932)\n-62F9 Uncompressed Size     000008C3 (2243)\n-62FD Filename Length       0047 (71)\n-62FF Extra Length          0000 (0)\n-6301 Filename              'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX'\n+636C Compression Method    0008 (8) 'Deflated'\n+636E Modification Time     50814080 (1350647936) 'Wed Apr  1 08:04:00 2020'\n+6372 CRC                   58FEAB57 (1493085015)\n+6376 Compressed Size       000003A4 (932)\n+637A Uncompressed Size     000008C3 (2243)\n+637E Filename Length       0047 (71)\n+6380 Extra Length          0000 (0)\n+6382 Filename              'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX'\n #\n-# WARNING: Offset 0x6301: Filename 'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX'\n+# WARNING: Offset 0x6382: Filename 'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX'\n #          Zero length filename\n #\n-6348 PAYLOAD\n+63C9 PAYLOAD\n \n-66EC LOCAL HEADER #30      04034B50 (67324752)\n-66F0 Extract Zip Spec      14 (20) '2.0'\n-66F1 Extract OS            00 (0) 'MS-DOS'\n-66F2 General Purpose Flag  0800 (2048)\n+676D LOCAL HEADER #30      04034B50 (67324752)\n+6771 Extract Zip Spec      14 (20) '2.0'\n+6772 Extract OS            00 (0) 'MS-DOS'\n+6773 General Purpose Flag  0800 (2048)\n      [Bits 1-2]            0 'Normal Compression'\n      [Bit 11]              1 'Language Encoding'\n-66F4 Compression Method    0008 (8) 'Deflated'\n-66F6 Modification Time     50814080 (1350647936) 'Wed Apr  1 08:04:00 2020'\n-66FA CRC                   BC1F87C6 (3156182982)\n-66FE Compressed Size       00000D44 (3396)\n-6702 Uncompressed Size     0000391E (14622)\n-6706 Filename Length       0048 (72)\n-6708 Extra Length          0000 (0)\n-670A Filename              'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX'\n+6775 Compression Method    0008 (8) 'Deflated'\n+6777 Modification Time     50814080 (1350647936) 'Wed Apr  1 08:04:00 2020'\n+677B CRC                   A355BCB4 (2740305076)\n+677F Compressed Size       00000D58 (3416)\n+6783 Uncompressed Size     00003AB8 (15032)\n+6787 Filename Length       0048 (72)\n+6789 Extra Length          0000 (0)\n+678B Filename              'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX'\n #\n-# WARNING: Offset 0x670A: Filename 'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX'\n+# WARNING: Offset 0x678B: Filename 'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX'\n #          Zero length filename\n #\n-6752 PAYLOAD\n+67D3 PAYLOAD\n \n-7496 LOCAL HEADER #31      04034B50 (67324752)\n-749A Extract Zip Spec      14 (20) '2.0'\n-749B Extract OS            00 (0) 'MS-DOS'\n-749C General Purpose Flag  0800 (2048)\n+752B LOCAL HEADER #31      04034B50 (67324752)\n+752F Extract Zip Spec      14 (20) '2.0'\n+7530 Extract OS            00 (0) 'MS-DOS'\n+7531 General Purpose Flag  0800 (2048)\n      [Bits 1-2]            0 'Normal Compression'\n      [Bit 11]              1 'Language Encoding'\n-749E Compression Method    0008 (8) 'Deflated'\n-74A0 Modification Time     50814080 (1350647936) 'Wed Apr  1 08:04:00 2020'\n-74A4 CRC                   8F7CA09F (2407309471)\n-74A8 Compressed Size       0000003F (63)\n-74AC Uncompressed Size     00000085 (133)\n-74B0 Filename Length       003D (61)\n-74B2 Extra Length          0000 (0)\n-74B4 Filename              'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX'\n+7533 Compression Method    0008 (8) 'Deflated'\n+7535 Modification Time     50814080 (1350647936) 'Wed Apr  1 08:04:00 2020'\n+7539 CRC                   8F7CA09F (2407309471)\n+753D Compressed Size       0000003F (63)\n+7541 Uncompressed Size     00000085 (133)\n+7545 Filename Length       003D (61)\n+7547 Extra Length          0000 (0)\n+7549 Filename              'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX'\n #\n-# WARNING: Offset 0x74B4: Filename 'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX'\n+# WARNING: Offset 0x7549: Filename 'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX'\n #          Zero length filename\n #\n-74F1 PAYLOAD               XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX\n+7586 PAYLOAD               XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX\n \n-7530 LOCAL HEADER #32      04034B50 (67324752)\n-7534 Extract Zip Spec      14 (20) '2.0'\n-7535 Extract OS            00 (0) 'MS-DOS'\n-7536 General Purpose Flag  0800 (2048)\n+75C5 LOCAL HEADER #32      04034B50 (67324752)\n+75C9 Extract Zip Spec      14 (20) '2.0'\n+75CA Extract OS            00 (0) 'MS-DOS'\n+75CB General Purpose Flag  0800 (2048)\n      [Bits 1-2]            0 'Normal Compression'\n      [Bit 11]              1 'Language Encoding'\n-7538 Compression Method    0008 (8) 'Deflated'\n-753A Modification Time     50814080 (1350647936) 'Wed Apr  1 08:04:00 2020'\n-753E CRC                   2E65EAC2 (778431170)\n-7542 Compressed Size       000003B1 (945)\n-7546 Uncompressed Size     0000095F (2399)\n-754A Filename Length       003D (61)\n-754C Extra Length          0000 (0)\n-754E Filename              'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX'\n+75CD Compression Method    0008 (8) 'Deflated'\n+75CF Modification Time     50814080 (1350647936) 'Wed Apr  1 08:04:00 2020'\n+75D3 CRC                   1D29AE65 (489270885)\n+75D7 Compressed Size       000003AA (938)\n+75DB Uncompressed Size     00000924 (2340)\n+75DF Filename Length       003D (61)\n+75E1 Extra Length          0000 (0)\n+75E3 Filename              'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX'\n #\n-# WARNING: Offset 0x754E: Filename 'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX'\n+# WARNING: Offset 0x75E3: Filename 'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX'\n #          Zero length filename\n #\n-758B PAYLOAD\n+7620 PAYLOAD\n \n-793C LOCAL HEADER #33      04034B50 (67324752)\n-7940 Extract Zip Spec      14 (20) '2.0'\n-7941 Extract OS            00 (0) 'MS-DOS'\n-7942 General Purpose Flag  0800 (2048)\n+79CA LOCAL HEADER #33      04034B50 (67324752)\n+79CE Extract Zip Spec      14 (20) '2.0'\n+79CF Extract OS            00 (0) 'MS-DOS'\n+79D0 General Purpose Flag  0800 (2048)\n      [Bits 1-2]            0 'Normal Compression'\n      [Bit 11]              1 'Language Encoding'\n-7944 Compression Method    0008 (8) 'Deflated'\n-7946 Modification Time     50814080 (1350647936) 'Wed Apr  1 08:04:00 2020'\n-794A CRC                   E328D6D4 (3811104468)\n-794E Compressed Size       0000004A (74)\n-7952 Uncompressed Size     0000004C (76)\n-7956 Filename Length       0044 (68)\n-7958 Extra Length          0000 (0)\n-795A Filename              'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX'\n+79D2 Compression Method    0008 (8) 'Deflated'\n+79D4 Modification Time     50814080 (1350647936) 'Wed Apr  1 08:04:00 2020'\n+79D8 CRC                   E328D6D4 (3811104468)\n+79DC Compressed Size       0000004A (74)\n+79E0 Uncompressed Size     0000004C (76)\n+79E4 Filename Length       0044 (68)\n+79E6 Extra Length          0000 (0)\n+79E8 Filename              'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX'\n #\n-# WARNING: Offset 0x795A: Filename 'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX'\n+# WARNING: Offset 0x79E8: Filename 'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX'\n #          Zero length filename\n #\n-799E PAYLOAD               XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX\n+7A2C PAYLOAD               XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX\n \n-79E8 CENTRAL HEADER #1     02014B50 (33639248)\n-79EC Created Zip Spec      14 (20) '2.0'\n-79ED Created OS            03 (3) 'Unix'\n-79EE Extract Zip Spec      14 (20) '2.0'\n-79EF Extract OS            00 (0) 'MS-DOS'\n-79F0 General Purpose Flag  0800 (2048)\n+7A76 CENTRAL HEADER #1     02014B50 (33639248)\n+7A7A Created Zip Spec      14 (20) '2.0'\n+7A7B Created OS            03 (3) 'Unix'\n+7A7C Extract Zip Spec      14 (20) '2.0'\n+7A7D Extract OS            00 (0) 'MS-DOS'\n+7A7E General Purpose Flag  0800 (2048)\n      [Bits 1-2]            0 'Normal Compression'\n      [Bit 11]              1 'Language Encoding'\n-79F2 Compression Method    0008 (8) 'Deflated'\n-79F4 Modification Time     50814080 (1350647936) 'Wed Apr  1 08:04:00 2020'\n-79F8 CRC                   A689EB18 (2794056472)\n-79FC Compressed Size       00000042 (66)\n-7A00 Uncompressed Size     00000040 (64)\n-7A04 Filename Length       0014 (20)\n-7A06 Extra Length          0000 (0)\n-7A08 Comment Length        0000 (0)\n-7A0A Disk Start            0000 (0)\n-7A0C Int File Attributes   0000 (0)\n+7A80 Compression Method    0008 (8) 'Deflated'\n+7A82 Modification Time     50814080 (1350647936) 'Wed Apr  1 08:04:00 2020'\n+7A86 CRC                   A689EB18 (2794056472)\n+7A8A Compressed Size       00000042 (66)\n+7A8E Uncompressed Size     00000040 (64)\n+7A92 Filename Length       0014 (20)\n+7A94 Extra Length          0000 (0)\n+7A96 Comment Length        0000 (0)\n+7A98 Disk Start            0000 (0)\n+7A9A Int File Attributes   0000 (0)\n      [Bit 0]               0 'Binary Data'\n-7A0E Ext File Attributes   81A40000 (2175008768)\n+7A9C Ext File Attributes   81A40000 (2175008768)\n      [Bits 16-24]          01A4 (420) 'Unix attrib: rw-r--r--'\n      [Bits 28-31]          08 (8) 'Regular File'\n-7A12 Local Header Offset   00000000 (0)\n-7A16 Filename              'XXXXXXXXXXXXXXXXXXXX'\n+7AA0 Local Header Offset   00000000 (0)\n+7AA4 Filename              'XXXXXXXXXXXXXXXXXXXX'\n #\n-# WARNING: Offset 0x7A16: Filename 'XXXXXXXXXXXXXXXXXXXX'\n+# WARNING: Offset 0x7AA4: Filename 'XXXXXXXXXXXXXXXXXXXX'\n #          Zero length filename\n #\n \n-7A2A CENTRAL HEADER #2     02014B50 (33639248)\n-7A2E Created Zip Spec      14 (20) '2.0'\n-7A2F Created OS            03 (3) 'Unix'\n-7A30 Extract Zip Spec      0A (10) '1.0'\n-7A31 Extract OS            00 (0) 'MS-DOS'\n-7A32 General Purpose Flag  0800 (2048)\n-     [Bit 11]              1 'Language Encoding'\n-7A34 Compression Method    0000 (0) 'Stored'\n-7A36 Modification Time     50814080 (1350647936) 'Wed Apr  1 08:04:00 2020'\n-7A3A CRC                   00000000 (0)\n-7A3E Compressed Size       00000000 (0)\n-7A42 Uncompressed Size     00000000 (0)\n-7A46 Filename Length       0009 (9)\n-7A48 Extra Length          0000 (0)\n-7A4A Comment Length        0000 (0)\n-7A4C Disk Start            0000 (0)\n-7A4E Int File Attributes   0000 (0)\n+7AB8 CENTRAL HEADER #2     02014B50 (33639248)\n+7ABC Created Zip Spec      14 (20) '2.0'\n+7ABD Created OS            03 (3) 'Unix'\n+7ABE Extract Zip Spec      0A (10) '1.0'\n+7ABF Extract OS            00 (0) 'MS-DOS'\n+7AC0 General Purpose Flag  0800 (2048)\n+     [Bit 11]              1 'Language Encoding'\n+7AC2 Compression Method    0000 (0) 'Stored'\n+7AC4 Modification Time     50814080 (1350647936) 'Wed Apr  1 08:04:00 2020'\n+7AC8 CRC                   00000000 (0)\n+7ACC Compressed Size       00000000 (0)\n+7AD0 Uncompressed Size     00000000 (0)\n+7AD4 Filename Length       0009 (9)\n+7AD6 Extra Length          0000 (0)\n+7AD8 Comment Length        0000 (0)\n+7ADA Disk Start            0000 (0)\n+7ADC Int File Attributes   0000 (0)\n      [Bit 0]               0 'Binary Data'\n-7A50 Ext File Attributes   41ED0010 (1106051088)\n+7ADE Ext File Attributes   41ED0010 (1106051088)\n      [Bit 4]               Directory\n      [Bits 16-24]          01ED (493) 'Unix attrib: rwxr-xr-x'\n      [Bits 28-31]          04 (4) 'Directory'\n-7A54 Local Header Offset   00000074 (116)\n-7A58 Filename              'XXXXXXXXX'\n+7AE2 Local Header Offset   00000074 (116)\n+7AE6 Filename              'XXXXXXXXX'\n #\n-# WARNING: Offset 0x7A58: Filename 'XXXXXXXXX'\n+# WARNING: Offset 0x7AE6: Filename 'XXXXXXXXX'\n #          Zero length filename\n #\n-# ERROR: Offset 0x7A58: Directory 'XXXXXXXXX' must end in a '/'\n+# ERROR: Offset 0x7AE6: Directory 'XXXXXXXXX' must end in a '/'\n #        'External Attributes' flag this as a directory\n #\n-# WARNING: Offset 0x7A30: 'Extract Zip Spec' is '1.0'. Need value >= '2.0' for Directory 'XXXXXXXXX'\n+# WARNING: Offset 0x7ABE: 'Extract Zip Spec' is '1.0'. Need value >= '2.0' for Directory 'XXXXXXXXX'\n #\n \n-7A61 CENTRAL HEADER #3     02014B50 (33639248)\n-7A65 Created Zip Spec      14 (20) '2.0'\n-7A66 Created OS            03 (3) 'Unix'\n-7A67 Extract Zip Spec      0A (10) '1.0'\n-7A68 Extract OS            00 (0) 'MS-DOS'\n-7A69 General Purpose Flag  0800 (2048)\n-     [Bit 11]              1 'Language Encoding'\n-7A6B Compression Method    0000 (0) 'Stored'\n-7A6D Modification Time     50814080 (1350647936) 'Wed Apr  1 08:04:00 2020'\n-7A71 CRC                   00000000 (0)\n-7A75 Compressed Size       00000000 (0)\n-7A79 Uncompressed Size     00000000 (0)\n-7A7D Filename Length       0004 (4)\n-7A7F Extra Length          0000 (0)\n-7A81 Comment Length        0000 (0)\n-7A83 Disk Start            0000 (0)\n-7A85 Int File Attributes   0000 (0)\n+7AEF CENTRAL HEADER #3     02014B50 (33639248)\n+7AF3 Created Zip Spec      14 (20) '2.0'\n+7AF4 Created OS            03 (3) 'Unix'\n+7AF5 Extract Zip Spec      0A (10) '1.0'\n+7AF6 Extract OS            00 (0) 'MS-DOS'\n+7AF7 General Purpose Flag  0800 (2048)\n+     [Bit 11]              1 'Language Encoding'\n+7AF9 Compression Method    0000 (0) 'Stored'\n+7AFB Modification Time     50814080 (1350647936) 'Wed Apr  1 08:04:00 2020'\n+7AFF CRC                   00000000 (0)\n+7B03 Compressed Size       00000000 (0)\n+7B07 Uncompressed Size     00000000 (0)\n+7B0B Filename Length       0004 (4)\n+7B0D Extra Length          0000 (0)\n+7B0F Comment Length        0000 (0)\n+7B11 Disk Start            0000 (0)\n+7B13 Int File Attributes   0000 (0)\n      [Bit 0]               0 'Binary Data'\n-7A87 Ext File Attributes   41ED0010 (1106051088)\n+7B15 Ext File Attributes   41ED0010 (1106051088)\n      [Bit 4]               Directory\n      [Bits 16-24]          01ED (493) 'Unix attrib: rwxr-xr-x'\n      [Bits 28-31]          04 (4) 'Directory'\n-7A8B Local Header Offset   0000009B (155)\n-7A8F Filename              'XXXX'\n+7B19 Local Header Offset   0000009B (155)\n+7B1D Filename              'XXXX'\n #\n-# WARNING: Offset 0x7A8F: Filename 'XXXX'\n+# WARNING: Offset 0x7B1D: Filename 'XXXX'\n #          Zero length filename\n #\n-# ERROR: Offset 0x7A8F: Directory 'XXXX' must end in a '/'\n+# ERROR: Offset 0x7B1D: Directory 'XXXX' must end in a '/'\n #        'External Attributes' flag this as a directory\n #\n-# WARNING: Offset 0x7A67: 'Extract Zip Spec' is '1.0'. Need value >= '2.0' for Directory 'XXXX'\n+# WARNING: Offset 0x7AF5: 'Extract Zip Spec' is '1.0'. Need value >= '2.0' for Directory 'XXXX'\n #\n \n-7A93 CENTRAL HEADER #4     02014B50 (33639248)\n-7A97 Created Zip Spec      14 (20) '2.0'\n-7A98 Created OS            03 (3) 'Unix'\n-7A99 Extract Zip Spec      0A (10) '1.0'\n-7A9A Extract OS            00 (0) 'MS-DOS'\n-7A9B General Purpose Flag  0800 (2048)\n-     [Bit 11]              1 'Language Encoding'\n-7A9D Compression Method    0000 (0) 'Stored'\n-7A9F Modification Time     50814080 (1350647936) 'Wed Apr  1 08:04:00 2020'\n-7AA3 CRC                   00000000 (0)\n-7AA7 Compressed Size       00000000 (0)\n-7AAB Uncompressed Size     00000000 (0)\n-7AAF Filename Length       000B (11)\n-7AB1 Extra Length          0000 (0)\n-7AB3 Comment Length        0000 (0)\n-7AB5 Disk Start            0000 (0)\n-7AB7 Int File Attributes   0000 (0)\n+7B21 CENTRAL HEADER #4     02014B50 (33639248)\n+7B25 Created Zip Spec      14 (20) '2.0'\n+7B26 Created OS            03 (3) 'Unix'\n+7B27 Extract Zip Spec      0A (10) '1.0'\n+7B28 Extract OS            00 (0) 'MS-DOS'\n+7B29 General Purpose Flag  0800 (2048)\n+     [Bit 11]              1 'Language Encoding'\n+7B2B Compression Method    0000 (0) 'Stored'\n+7B2D Modification Time     50814080 (1350647936) 'Wed Apr  1 08:04:00 2020'\n+7B31 CRC                   00000000 (0)\n+7B35 Compressed Size       00000000 (0)\n+7B39 Uncompressed Size     00000000 (0)\n+7B3D Filename Length       000B (11)\n+7B3F Extra Length          0000 (0)\n+7B41 Comment Length        0000 (0)\n+7B43 Disk Start            0000 (0)\n+7B45 Int File Attributes   0000 (0)\n      [Bit 0]               0 'Binary Data'\n-7AB9 Ext File Attributes   41ED0010 (1106051088)\n+7B47 Ext File Attributes   41ED0010 (1106051088)\n      [Bit 4]               Directory\n      [Bits 16-24]          01ED (493) 'Unix attrib: rwxr-xr-x'\n      [Bits 28-31]          04 (4) 'Directory'\n-7ABD Local Header Offset   000000BD (189)\n-7AC1 Filename              'XXXXXXXXXXX'\n+7B4B Local Header Offset   000000BD (189)\n+7B4F Filename              'XXXXXXXXXXX'\n #\n-# WARNING: Offset 0x7AC1: Filename 'XXXXXXXXXXX'\n+# WARNING: Offset 0x7B4F: Filename 'XXXXXXXXXXX'\n #          Zero length filename\n #\n-# ERROR: Offset 0x7AC1: Directory 'XXXXXXXXXXX' must end in a '/'\n+# ERROR: Offset 0x7B4F: Directory 'XXXXXXXXXXX' must end in a '/'\n #        'External Attributes' flag this as a directory\n #\n-# WARNING: Offset 0x7A99: 'Extract Zip Spec' is '1.0'. Need value >= '2.0' for Directory 'XXXXXXXXXXX'\n+# WARNING: Offset 0x7B27: 'Extract Zip Spec' is '1.0'. Need value >= '2.0' for Directory 'XXXXXXXXXXX'\n #\n \n-7ACC CENTRAL HEADER #5     02014B50 (33639248)\n-7AD0 Created Zip Spec      14 (20) '2.0'\n-7AD1 Created OS            03 (3) 'Unix'\n-7AD2 Extract Zip Spec      0A (10) '1.0'\n-7AD3 Extract OS            00 (0) 'MS-DOS'\n-7AD4 General Purpose Flag  0800 (2048)\n-     [Bit 11]              1 'Language Encoding'\n-7AD6 Compression Method    0000 (0) 'Stored'\n-7AD8 Modification Time     50814080 (1350647936) 'Wed Apr  1 08:04:00 2020'\n-7ADC CRC                   00000000 (0)\n-7AE0 Compressed Size       00000000 (0)\n-7AE4 Uncompressed Size     00000000 (0)\n-7AE8 Filename Length       0011 (17)\n-7AEA Extra Length          0000 (0)\n-7AEC Comment Length        0000 (0)\n-7AEE Disk Start            0000 (0)\n-7AF0 Int File Attributes   0000 (0)\n+7B5A CENTRAL HEADER #5     02014B50 (33639248)\n+7B5E Created Zip Spec      14 (20) '2.0'\n+7B5F Created OS            03 (3) 'Unix'\n+7B60 Extract Zip Spec      0A (10) '1.0'\n+7B61 Extract OS            00 (0) 'MS-DOS'\n+7B62 General Purpose Flag  0800 (2048)\n+     [Bit 11]              1 'Language Encoding'\n+7B64 Compression Method    0000 (0) 'Stored'\n+7B66 Modification Time     50814080 (1350647936) 'Wed Apr  1 08:04:00 2020'\n+7B6A CRC                   00000000 (0)\n+7B6E Compressed Size       00000000 (0)\n+7B72 Uncompressed Size     00000000 (0)\n+7B76 Filename Length       0011 (17)\n+7B78 Extra Length          0000 (0)\n+7B7A Comment Length        0000 (0)\n+7B7C Disk Start            0000 (0)\n+7B7E Int File Attributes   0000 (0)\n      [Bit 0]               0 'Binary Data'\n-7AF2 Ext File Attributes   41ED0010 (1106051088)\n+7B80 Ext File Attributes   41ED0010 (1106051088)\n      [Bit 4]               Directory\n      [Bits 16-24]          01ED (493) 'Unix attrib: rwxr-xr-x'\n      [Bits 28-31]          04 (4) 'Directory'\n-7AF6 Local Header Offset   000000E6 (230)\n-7AFA Filename              'XXXXXXXXXXXXXXXXX'\n+7B84 Local Header Offset   000000E6 (230)\n+7B88 Filename              'XXXXXXXXXXXXXXXXX'\n #\n-# WARNING: Offset 0x7AFA: Filename 'XXXXXXXXXXXXXXXXX'\n+# WARNING: Offset 0x7B88: Filename 'XXXXXXXXXXXXXXXXX'\n #          Zero length filename\n #\n-# ERROR: Offset 0x7AFA: Directory 'XXXXXXXXXXXXXXXXX' must end in a '/'\n+# ERROR: Offset 0x7B88: Directory 'XXXXXXXXXXXXXXXXX' must end in a '/'\n #        'External Attributes' flag this as a directory\n #\n-# WARNING: Offset 0x7AD2: 'Extract Zip Spec' is '1.0'. Need value >= '2.0' for Directory 'XXXXXXXXXXXXXXXXX'\n+# WARNING: Offset 0x7B60: 'Extract Zip Spec' is '1.0'. Need value >= '2.0' for Directory 'XXXXXXXXXXXXXXXXX'\n #\n \n-7B0B CENTRAL HEADER #6     02014B50 (33639248)\n-7B0F Created Zip Spec      14 (20) '2.0'\n-7B10 Created OS            03 (3) 'Unix'\n-7B11 Extract Zip Spec      0A (10) '1.0'\n-7B12 Extract OS            00 (0) 'MS-DOS'\n-7B13 General Purpose Flag  0800 (2048)\n-     [Bit 11]              1 'Language Encoding'\n-7B15 Compression Method    0000 (0) 'Stored'\n-7B17 Modification Time     50814080 (1350647936) 'Wed Apr  1 08:04:00 2020'\n-7B1B CRC                   00000000 (0)\n-7B1F Compressed Size       00000000 (0)\n-7B23 Uncompressed Size     00000000 (0)\n-7B27 Filename Length       001A (26)\n-7B29 Extra Length          0000 (0)\n-7B2B Comment Length        0000 (0)\n-7B2D Disk Start            0000 (0)\n-7B2F Int File Attributes   0000 (0)\n+7B99 CENTRAL HEADER #6     02014B50 (33639248)\n+7B9D Created Zip Spec      14 (20) '2.0'\n+7B9E Created OS            03 (3) 'Unix'\n+7B9F Extract Zip Spec      0A (10) '1.0'\n+7BA0 Extract OS            00 (0) 'MS-DOS'\n+7BA1 General Purpose Flag  0800 (2048)\n+     [Bit 11]              1 'Language Encoding'\n+7BA3 Compression Method    0000 (0) 'Stored'\n+7BA5 Modification Time     50814080 (1350647936) 'Wed Apr  1 08:04:00 2020'\n+7BA9 CRC                   00000000 (0)\n+7BAD Compressed Size       00000000 (0)\n+7BB1 Uncompressed Size     00000000 (0)\n+7BB5 Filename Length       001A (26)\n+7BB7 Extra Length          0000 (0)\n+7BB9 Comment Length        0000 (0)\n+7BBB Disk Start            0000 (0)\n+7BBD Int File Attributes   0000 (0)\n      [Bit 0]               0 'Binary Data'\n-7B31 Ext File Attributes   41ED0010 (1106051088)\n+7BBF Ext File Attributes   41ED0010 (1106051088)\n      [Bit 4]               Directory\n      [Bits 16-24]          01ED (493) 'Unix attrib: rwxr-xr-x'\n      [Bits 28-31]          04 (4) 'Directory'\n-7B35 Local Header Offset   00000115 (277)\n-7B39 Filename              'XXXXXXXXXXXXXXXXXXXXXXXXXX'\n+7BC3 Local Header Offset   00000115 (277)\n+7BC7 Filename              'XXXXXXXXXXXXXXXXXXXXXXXXXX'\n #\n-# WARNING: Offset 0x7B39: Filename 'XXXXXXXXXXXXXXXXXXXXXXXXXX'\n+# WARNING: Offset 0x7BC7: Filename 'XXXXXXXXXXXXXXXXXXXXXXXXXX'\n #          Zero length filename\n #\n-# ERROR: Offset 0x7B39: Directory 'XXXXXXXXXXXXXXXXXXXXXXXXXX' must end in a '/'\n+# ERROR: Offset 0x7BC7: Directory 'XXXXXXXXXXXXXXXXXXXXXXXXXX' must end in a '/'\n #        'External Attributes' flag this as a directory\n #\n-# WARNING: Offset 0x7B11: 'Extract Zip Spec' is '1.0'. Need value >= '2.0' for Directory 'XXXXXXXXXXXXXXXXXXXXXXXXXX'\n+# WARNING: Offset 0x7B9F: 'Extract Zip Spec' is '1.0'. Need value >= '2.0' for Directory 'XXXXXXXXXXXXXXXXXXXXXXXXXX'\n #\n \n-7B53 CENTRAL HEADER #7     02014B50 (33639248)\n-7B57 Created Zip Spec      14 (20) '2.0'\n-7B58 Created OS            03 (3) 'Unix'\n-7B59 Extract Zip Spec      0A (10) '1.0'\n-7B5A Extract OS            00 (0) 'MS-DOS'\n-7B5B General Purpose Flag  0800 (2048)\n-     [Bit 11]              1 'Language Encoding'\n-7B5D Compression Method    0000 (0) 'Stored'\n-7B5F Modification Time     50814080 (1350647936) 'Wed Apr  1 08:04:00 2020'\n-7B63 CRC                   00000000 (0)\n-7B67 Compressed Size       00000000 (0)\n-7B6B Uncompressed Size     00000000 (0)\n-7B6F Filename Length       0024 (36)\n-7B71 Extra Length          0000 (0)\n-7B73 Comment Length        0000 (0)\n-7B75 Disk Start            0000 (0)\n-7B77 Int File Attributes   0000 (0)\n+7BE1 CENTRAL HEADER #7     02014B50 (33639248)\n+7BE5 Created Zip Spec      14 (20) '2.0'\n+7BE6 Created OS            03 (3) 'Unix'\n+7BE7 Extract Zip Spec      0A (10) '1.0'\n+7BE8 Extract OS            00 (0) 'MS-DOS'\n+7BE9 General Purpose Flag  0800 (2048)\n+     [Bit 11]              1 'Language Encoding'\n+7BEB Compression Method    0000 (0) 'Stored'\n+7BED Modification Time     50814080 (1350647936) 'Wed Apr  1 08:04:00 2020'\n+7BF1 CRC                   00000000 (0)\n+7BF5 Compressed Size       00000000 (0)\n+7BF9 Uncompressed Size     00000000 (0)\n+7BFD Filename Length       0024 (36)\n+7BFF Extra Length          0000 (0)\n+7C01 Comment Length        0000 (0)\n+7C03 Disk Start            0000 (0)\n+7C05 Int File Attributes   0000 (0)\n      [Bit 0]               0 'Binary Data'\n-7B79 Ext File Attributes   41ED0010 (1106051088)\n+7C07 Ext File Attributes   41ED0010 (1106051088)\n      [Bit 4]               Directory\n      [Bits 16-24]          01ED (493) 'Unix attrib: rwxr-xr-x'\n      [Bits 28-31]          04 (4) 'Directory'\n-7B7D Local Header Offset   0000014D (333)\n-7B81 Filename              'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX'\n+7C0B Local Header Offset   0000014D (333)\n+7C0F Filename              'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX'\n #\n-# WARNING: Offset 0x7B81: Filename 'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX'\n+# WARNING: Offset 0x7C0F: Filename 'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX'\n #          Zero length filename\n #\n-# ERROR: Offset 0x7B81: Directory 'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX' must end in a '/'\n+# ERROR: Offset 0x7C0F: Directory 'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX' must end in a '/'\n #        'External Attributes' flag this as a directory\n #\n-# WARNING: Offset 0x7B59: 'Extract Zip Spec' is '1.0'. Need value >= '2.0' for Directory 'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX'\n+# WARNING: Offset 0x7BE7: 'Extract Zip Spec' is '1.0'. Need value >= '2.0' for Directory 'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX'\n #\n \n-7BA5 CENTRAL HEADER #8     02014B50 (33639248)\n-7BA9 Created Zip Spec      14 (20) '2.0'\n-7BAA Created OS            03 (3) 'Unix'\n-7BAB Extract Zip Spec      0A (10) '1.0'\n-7BAC Extract OS            00 (0) 'MS-DOS'\n-7BAD General Purpose Flag  0800 (2048)\n-     [Bit 11]              1 'Language Encoding'\n-7BAF Compression Method    0000 (0) 'Stored'\n-7BB1 Modification Time     50814080 (1350647936) 'Wed Apr  1 08:04:00 2020'\n-7BB5 CRC                   00000000 (0)\n-7BB9 Compressed Size       00000000 (0)\n-7BBD Uncompressed Size     00000000 (0)\n-7BC1 Filename Length       002B (43)\n-7BC3 Extra Length          0000 (0)\n-7BC5 Comment Length        0000 (0)\n-7BC7 Disk Start            0000 (0)\n-7BC9 Int File Attributes   0000 (0)\n+7C33 CENTRAL HEADER #8     02014B50 (33639248)\n+7C37 Created Zip Spec      14 (20) '2.0'\n+7C38 Created OS            03 (3) 'Unix'\n+7C39 Extract Zip Spec      0A (10) '1.0'\n+7C3A Extract OS            00 (0) 'MS-DOS'\n+7C3B General Purpose Flag  0800 (2048)\n+     [Bit 11]              1 'Language Encoding'\n+7C3D Compression Method    0000 (0) 'Stored'\n+7C3F Modification Time     50814080 (1350647936) 'Wed Apr  1 08:04:00 2020'\n+7C43 CRC                   00000000 (0)\n+7C47 Compressed Size       00000000 (0)\n+7C4B Uncompressed Size     00000000 (0)\n+7C4F Filename Length       002B (43)\n+7C51 Extra Length          0000 (0)\n+7C53 Comment Length        0000 (0)\n+7C55 Disk Start            0000 (0)\n+7C57 Int File Attributes   0000 (0)\n      [Bit 0]               0 'Binary Data'\n-7BCB Ext File Attributes   41ED0010 (1106051088)\n+7C59 Ext File Attributes   41ED0010 (1106051088)\n      [Bit 4]               Directory\n      [Bits 16-24]          01ED (493) 'Unix attrib: rwxr-xr-x'\n      [Bits 28-31]          04 (4) 'Directory'\n-7BCF Local Header Offset   0000018F (399)\n-7BD3 Filename              'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX'\n+7C5D Local Header Offset   0000018F (399)\n+7C61 Filename              'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX'\n #\n-# WARNING: Offset 0x7BD3: Filename 'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX'\n+# WARNING: Offset 0x7C61: Filename 'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX'\n #          Zero length filename\n #\n-# ERROR: Offset 0x7BD3: Directory 'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX' must end in a '/'\n+# ERROR: Offset 0x7C61: Directory 'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX' must end in a '/'\n #        'External Attributes' flag this as a directory\n #\n-# WARNING: Offset 0x7BAB: 'Extract Zip Spec' is '1.0'. Need value >= '2.0' for Directory 'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX'\n+# WARNING: Offset 0x7C39: 'Extract Zip Spec' is '1.0'. Need value >= '2.0' for Directory 'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX'\n #\n \n-7BFE CENTRAL HEADER #9     02014B50 (33639248)\n-7C02 Created Zip Spec      14 (20) '2.0'\n-7C03 Created OS            03 (3) 'Unix'\n-7C04 Extract Zip Spec      0A (10) '1.0'\n-7C05 Extract OS            00 (0) 'MS-DOS'\n-7C06 General Purpose Flag  0800 (2048)\n-     [Bit 11]              1 'Language Encoding'\n-7C08 Compression Method    0000 (0) 'Stored'\n-7C0A Modification Time     50814080 (1350647936) 'Wed Apr  1 08:04:00 2020'\n-7C0E CRC                   00000000 (0)\n-7C12 Compressed Size       00000000 (0)\n-7C16 Uncompressed Size     00000000 (0)\n-7C1A Filename Length       0033 (51)\n-7C1C Extra Length          0000 (0)\n-7C1E Comment Length        0000 (0)\n-7C20 Disk Start            0000 (0)\n-7C22 Int File Attributes   0000 (0)\n+7C8C CENTRAL HEADER #9     02014B50 (33639248)\n+7C90 Created Zip Spec      14 (20) '2.0'\n+7C91 Created OS            03 (3) 'Unix'\n+7C92 Extract Zip Spec      0A (10) '1.0'\n+7C93 Extract OS            00 (0) 'MS-DOS'\n+7C94 General Purpose Flag  0800 (2048)\n+     [Bit 11]              1 'Language Encoding'\n+7C96 Compression Method    0000 (0) 'Stored'\n+7C98 Modification Time     50814080 (1350647936) 'Wed Apr  1 08:04:00 2020'\n+7C9C CRC                   00000000 (0)\n+7CA0 Compressed Size       00000000 (0)\n+7CA4 Uncompressed Size     00000000 (0)\n+7CA8 Filename Length       0033 (51)\n+7CAA Extra Length          0000 (0)\n+7CAC Comment Length        0000 (0)\n+7CAE Disk Start            0000 (0)\n+7CB0 Int File Attributes   0000 (0)\n      [Bit 0]               0 'Binary Data'\n-7C24 Ext File Attributes   41ED0010 (1106051088)\n+7CB2 Ext File Attributes   41ED0010 (1106051088)\n      [Bit 4]               Directory\n      [Bits 16-24]          01ED (493) 'Unix attrib: rwxr-xr-x'\n      [Bits 28-31]          04 (4) 'Directory'\n-7C28 Local Header Offset   000001D8 (472)\n-7C2C Filename              'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX'\n+7CB6 Local Header Offset   000001D8 (472)\n+7CBA Filename              'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX'\n #\n-# WARNING: Offset 0x7C2C: Filename 'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX'\n+# WARNING: Offset 0x7CBA: Filename 'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX'\n #          Zero length filename\n #\n-# ERROR: Offset 0x7C2C: Directory 'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX' must end in a '/'\n+# ERROR: Offset 0x7CBA: Directory 'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX' must end in a '/'\n #        'External Attributes' flag this as a directory\n #\n-# WARNING: Offset 0x7C04: 'Extract Zip Spec' is '1.0'. Need value >= '2.0' for Directory 'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX'\n+# WARNING: Offset 0x7C92: 'Extract Zip Spec' is '1.0'. Need value >= '2.0' for Directory 'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX'\n #\n \n-7C5F CENTRAL HEADER #10    02014B50 (33639248)\n-7C63 Created Zip Spec      14 (20) '2.0'\n-7C64 Created OS            03 (3) 'Unix'\n-7C65 Extract Zip Spec      0A (10) '1.0'\n-7C66 Extract OS            00 (0) 'MS-DOS'\n-7C67 General Purpose Flag  0800 (2048)\n-     [Bit 11]              1 'Language Encoding'\n-7C69 Compression Method    0000 (0) 'Stored'\n-7C6B Modification Time     50814080 (1350647936) 'Wed Apr  1 08:04:00 2020'\n-7C6F CRC                   00000000 (0)\n-7C73 Compressed Size       00000000 (0)\n-7C77 Uncompressed Size     00000000 (0)\n-7C7B Filename Length       000F (15)\n-7C7D Extra Length          0000 (0)\n-7C7F Comment Length        0000 (0)\n-7C81 Disk Start            0000 (0)\n-7C83 Int File Attributes   0000 (0)\n+7CED CENTRAL HEADER #10    02014B50 (33639248)\n+7CF1 Created Zip Spec      14 (20) '2.0'\n+7CF2 Created OS            03 (3) 'Unix'\n+7CF3 Extract Zip Spec      0A (10) '1.0'\n+7CF4 Extract OS            00 (0) 'MS-DOS'\n+7CF5 General Purpose Flag  0800 (2048)\n+     [Bit 11]              1 'Language Encoding'\n+7CF7 Compression Method    0000 (0) 'Stored'\n+7CF9 Modification Time     50814080 (1350647936) 'Wed Apr  1 08:04:00 2020'\n+7CFD CRC                   00000000 (0)\n+7D01 Compressed Size       00000000 (0)\n+7D05 Uncompressed Size     00000000 (0)\n+7D09 Filename Length       000F (15)\n+7D0B Extra Length          0000 (0)\n+7D0D Comment Length        0000 (0)\n+7D0F Disk Start            0000 (0)\n+7D11 Int File Attributes   0000 (0)\n      [Bit 0]               0 'Binary Data'\n-7C85 Ext File Attributes   41ED0010 (1106051088)\n+7D13 Ext File Attributes   41ED0010 (1106051088)\n      [Bit 4]               Directory\n      [Bits 16-24]          01ED (493) 'Unix attrib: rwxr-xr-x'\n      [Bits 28-31]          04 (4) 'Directory'\n-7C89 Local Header Offset   00000229 (553)\n-7C8D Filename              'XXXXXXXXXXXXXXX'\n+7D17 Local Header Offset   00000229 (553)\n+7D1B Filename              'XXXXXXXXXXXXXXX'\n #\n-# WARNING: Offset 0x7C8D: Filename 'XXXXXXXXXXXXXXX'\n+# WARNING: Offset 0x7D1B: Filename 'XXXXXXXXXXXXXXX'\n #          Zero length filename\n #\n-# ERROR: Offset 0x7C8D: Directory 'XXXXXXXXXXXXXXX' must end in a '/'\n+# ERROR: Offset 0x7D1B: Directory 'XXXXXXXXXXXXXXX' must end in a '/'\n #        'External Attributes' flag this as a directory\n #\n-# WARNING: Offset 0x7C65: 'Extract Zip Spec' is '1.0'. Need value >= '2.0' for Directory 'XXXXXXXXXXXXXXX'\n+# WARNING: Offset 0x7CF3: 'Extract Zip Spec' is '1.0'. Need value >= '2.0' for Directory 'XXXXXXXXXXXXXXX'\n #\n \n-7C9C CENTRAL HEADER #11    02014B50 (33639248)\n-7CA0 Created Zip Spec      14 (20) '2.0'\n-7CA1 Created OS            03 (3) 'Unix'\n-7CA2 Extract Zip Spec      0A (10) '1.0'\n-7CA3 Extract OS            00 (0) 'MS-DOS'\n-7CA4 General Purpose Flag  0800 (2048)\n-     [Bit 11]              1 'Language Encoding'\n-7CA6 Compression Method    0000 (0) 'Stored'\n-7CA8 Modification Time     50814080 (1350647936) 'Wed Apr  1 08:04:00 2020'\n-7CAC CRC                   00000000 (0)\n-7CB0 Compressed Size       00000000 (0)\n-7CB4 Uncompressed Size     00000000 (0)\n-7CB8 Filename Length       0018 (24)\n-7CBA Extra Length          0000 (0)\n-7CBC Comment Length        0000 (0)\n-7CBE Disk Start            0000 (0)\n-7CC0 Int File Attributes   0000 (0)\n+7D2A CENTRAL HEADER #11    02014B50 (33639248)\n+7D2E Created Zip Spec      14 (20) '2.0'\n+7D2F Created OS            03 (3) 'Unix'\n+7D30 Extract Zip Spec      0A (10) '1.0'\n+7D31 Extract OS            00 (0) 'MS-DOS'\n+7D32 General Purpose Flag  0800 (2048)\n+     [Bit 11]              1 'Language Encoding'\n+7D34 Compression Method    0000 (0) 'Stored'\n+7D36 Modification Time     50814080 (1350647936) 'Wed Apr  1 08:04:00 2020'\n+7D3A CRC                   00000000 (0)\n+7D3E Compressed Size       00000000 (0)\n+7D42 Uncompressed Size     00000000 (0)\n+7D46 Filename Length       0018 (24)\n+7D48 Extra Length          0000 (0)\n+7D4A Comment Length        0000 (0)\n+7D4C Disk Start            0000 (0)\n+7D4E Int File Attributes   0000 (0)\n      [Bit 0]               0 'Binary Data'\n-7CC2 Ext File Attributes   41ED0010 (1106051088)\n+7D50 Ext File Attributes   41ED0010 (1106051088)\n      [Bit 4]               Directory\n      [Bits 16-24]          01ED (493) 'Unix attrib: rwxr-xr-x'\n      [Bits 28-31]          04 (4) 'Directory'\n-7CC6 Local Header Offset   00000256 (598)\n-7CCA Filename              'XXXXXXXXXXXXXXXXXXXXXXXX'\n+7D54 Local Header Offset   00000256 (598)\n+7D58 Filename              'XXXXXXXXXXXXXXXXXXXXXXXX'\n #\n-# WARNING: Offset 0x7CCA: Filename 'XXXXXXXXXXXXXXXXXXXXXXXX'\n+# WARNING: Offset 0x7D58: Filename 'XXXXXXXXXXXXXXXXXXXXXXXX'\n #          Zero length filename\n #\n-# ERROR: Offset 0x7CCA: Directory 'XXXXXXXXXXXXXXXXXXXXXXXX' must end in a '/'\n+# ERROR: Offset 0x7D58: Directory 'XXXXXXXXXXXXXXXXXXXXXXXX' must end in a '/'\n #        'External Attributes' flag this as a directory\n #\n-# WARNING: Offset 0x7CA2: 'Extract Zip Spec' is '1.0'. Need value >= '2.0' for Directory 'XXXXXXXXXXXXXXXXXXXXXXXX'\n+# WARNING: Offset 0x7D30: 'Extract Zip Spec' is '1.0'. Need value >= '2.0' for Directory 'XXXXXXXXXXXXXXXXXXXXXXXX'\n #\n \n-7CE2 CENTRAL HEADER #12    02014B50 (33639248)\n-7CE6 Created Zip Spec      14 (20) '2.0'\n-7CE7 Created OS            03 (3) 'Unix'\n-7CE8 Extract Zip Spec      0A (10) '1.0'\n-7CE9 Extract OS            00 (0) 'MS-DOS'\n-7CEA General Purpose Flag  0800 (2048)\n-     [Bit 11]              1 'Language Encoding'\n-7CEC Compression Method    0000 (0) 'Stored'\n-7CEE Modification Time     50814080 (1350647936) 'Wed Apr  1 08:04:00 2020'\n-7CF2 CRC                   00000000 (0)\n-7CF6 Compressed Size       00000000 (0)\n-7CFA Uncompressed Size     00000000 (0)\n-7CFE Filename Length       000F (15)\n-7D00 Extra Length          0000 (0)\n-7D02 Comment Length        0000 (0)\n-7D04 Disk Start            0000 (0)\n-7D06 Int File Attributes   0000 (0)\n+7D70 CENTRAL HEADER #12    02014B50 (33639248)\n+7D74 Created Zip Spec      14 (20) '2.0'\n+7D75 Created OS            03 (3) 'Unix'\n+7D76 Extract Zip Spec      0A (10) '1.0'\n+7D77 Extract OS            00 (0) 'MS-DOS'\n+7D78 General Purpose Flag  0800 (2048)\n+     [Bit 11]              1 'Language Encoding'\n+7D7A Compression Method    0000 (0) 'Stored'\n+7D7C Modification Time     50814080 (1350647936) 'Wed Apr  1 08:04:00 2020'\n+7D80 CRC                   00000000 (0)\n+7D84 Compressed Size       00000000 (0)\n+7D88 Uncompressed Size     00000000 (0)\n+7D8C Filename Length       000F (15)\n+7D8E Extra Length          0000 (0)\n+7D90 Comment Length        0000 (0)\n+7D92 Disk Start            0000 (0)\n+7D94 Int File Attributes   0000 (0)\n      [Bit 0]               0 'Binary Data'\n-7D08 Ext File Attributes   41ED0010 (1106051088)\n+7D96 Ext File Attributes   41ED0010 (1106051088)\n      [Bit 4]               Directory\n      [Bits 16-24]          01ED (493) 'Unix attrib: rwxr-xr-x'\n      [Bits 28-31]          04 (4) 'Directory'\n-7D0C Local Header Offset   0000028C (652)\n-7D10 Filename              'XXXXXXXXXXXXXXX'\n+7D9A Local Header Offset   0000028C (652)\n+7D9E Filename              'XXXXXXXXXXXXXXX'\n #\n-# WARNING: Offset 0x7D10: Filename 'XXXXXXXXXXXXXXX'\n+# WARNING: Offset 0x7D9E: Filename 'XXXXXXXXXXXXXXX'\n #          Zero length filename\n #\n-# ERROR: Offset 0x7D10: Directory 'XXXXXXXXXXXXXXX' must end in a '/'\n+# ERROR: Offset 0x7D9E: Directory 'XXXXXXXXXXXXXXX' must end in a '/'\n #        'External Attributes' flag this as a directory\n #\n-# WARNING: Offset 0x7CE8: 'Extract Zip Spec' is '1.0'. Need value >= '2.0' for Directory 'XXXXXXXXXXXXXXX'\n+# WARNING: Offset 0x7D76: 'Extract Zip Spec' is '1.0'. Need value >= '2.0' for Directory 'XXXXXXXXXXXXXXX'\n #\n \n-7D1F CENTRAL HEADER #13    02014B50 (33639248)\n-7D23 Created Zip Spec      14 (20) '2.0'\n-7D24 Created OS            03 (3) 'Unix'\n-7D25 Extract Zip Spec      0A (10) '1.0'\n-7D26 Extract OS            00 (0) 'MS-DOS'\n-7D27 General Purpose Flag  0800 (2048)\n-     [Bit 11]              1 'Language Encoding'\n-7D29 Compression Method    0000 (0) 'Stored'\n-7D2B Modification Time     50814080 (1350647936) 'Wed Apr  1 08:04:00 2020'\n-7D2F CRC                   00000000 (0)\n-7D33 Compressed Size       00000000 (0)\n-7D37 Uncompressed Size     00000000 (0)\n-7D3B Filename Length       0020 (32)\n-7D3D Extra Length          0000 (0)\n-7D3F Comment Length        0000 (0)\n-7D41 Disk Start            0000 (0)\n-7D43 Int File Attributes   0000 (0)\n+7DAD CENTRAL HEADER #13    02014B50 (33639248)\n+7DB1 Created Zip Spec      14 (20) '2.0'\n+7DB2 Created OS            03 (3) 'Unix'\n+7DB3 Extract Zip Spec      0A (10) '1.0'\n+7DB4 Extract OS            00 (0) 'MS-DOS'\n+7DB5 General Purpose Flag  0800 (2048)\n+     [Bit 11]              1 'Language Encoding'\n+7DB7 Compression Method    0000 (0) 'Stored'\n+7DB9 Modification Time     50814080 (1350647936) 'Wed Apr  1 08:04:00 2020'\n+7DBD CRC                   00000000 (0)\n+7DC1 Compressed Size       00000000 (0)\n+7DC5 Uncompressed Size     00000000 (0)\n+7DC9 Filename Length       0020 (32)\n+7DCB Extra Length          0000 (0)\n+7DCD Comment Length        0000 (0)\n+7DCF Disk Start            0000 (0)\n+7DD1 Int File Attributes   0000 (0)\n      [Bit 0]               0 'Binary Data'\n-7D45 Ext File Attributes   41ED0010 (1106051088)\n+7DD3 Ext File Attributes   41ED0010 (1106051088)\n      [Bit 4]               Directory\n      [Bits 16-24]          01ED (493) 'Unix attrib: rwxr-xr-x'\n      [Bits 28-31]          04 (4) 'Directory'\n-7D49 Local Header Offset   000002B9 (697)\n-7D4D Filename              'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX'\n+7DD7 Local Header Offset   000002B9 (697)\n+7DDB Filename              'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX'\n #\n-# WARNING: Offset 0x7D4D: Filename 'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX'\n+# WARNING: Offset 0x7DDB: Filename 'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX'\n #          Zero length filename\n #\n-# ERROR: Offset 0x7D4D: Directory 'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX' must end in a '/'\n+# ERROR: Offset 0x7DDB: Directory 'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX' must end in a '/'\n #        'External Attributes' flag this as a directory\n #\n-# WARNING: Offset 0x7D25: 'Extract Zip Spec' is '1.0'. Need value >= '2.0' for Directory 'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX'\n+# WARNING: Offset 0x7DB3: 'Extract Zip Spec' is '1.0'. Need value >= '2.0' for Directory 'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX'\n #\n \n-7D6D CENTRAL HEADER #14    02014B50 (33639248)\n-7D71 Created Zip Spec      14 (20) '2.0'\n-7D72 Created OS            03 (3) 'Unix'\n-7D73 Extract Zip Spec      0A (10) '1.0'\n-7D74 Extract OS            00 (0) 'MS-DOS'\n-7D75 General Purpose Flag  0800 (2048)\n-     [Bit 11]              1 'Language Encoding'\n-7D77 Compression Method    0000 (0) 'Stored'\n-7D79 Modification Time     50814080 (1350647936) 'Wed Apr  1 08:04:00 2020'\n-7D7D CRC                   00000000 (0)\n-7D81 Compressed Size       00000000 (0)\n-7D85 Uncompressed Size     00000000 (0)\n-7D89 Filename Length       0036 (54)\n-7D8B Extra Length          0000 (0)\n-7D8D Comment Length        0000 (0)\n-7D8F Disk Start            0000 (0)\n-7D91 Int File Attributes   0000 (0)\n+7DFB CENTRAL HEADER #14    02014B50 (33639248)\n+7DFF Created Zip Spec      14 (20) '2.0'\n+7E00 Created OS            03 (3) 'Unix'\n+7E01 Extract Zip Spec      0A (10) '1.0'\n+7E02 Extract OS            00 (0) 'MS-DOS'\n+7E03 General Purpose Flag  0800 (2048)\n+     [Bit 11]              1 'Language Encoding'\n+7E05 Compression Method    0000 (0) 'Stored'\n+7E07 Modification Time     50814080 (1350647936) 'Wed Apr  1 08:04:00 2020'\n+7E0B CRC                   00000000 (0)\n+7E0F Compressed Size       00000000 (0)\n+7E13 Uncompressed Size     00000000 (0)\n+7E17 Filename Length       0036 (54)\n+7E19 Extra Length          0000 (0)\n+7E1B Comment Length        0000 (0)\n+7E1D Disk Start            0000 (0)\n+7E1F Int File Attributes   0000 (0)\n      [Bit 0]               0 'Binary Data'\n-7D93 Ext File Attributes   41ED0010 (1106051088)\n+7E21 Ext File Attributes   41ED0010 (1106051088)\n      [Bit 4]               Directory\n      [Bits 16-24]          01ED (493) 'Unix attrib: rwxr-xr-x'\n      [Bits 28-31]          04 (4) 'Directory'\n-7D97 Local Header Offset   000002F7 (759)\n-7D9B Filename              'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX'\n+7E25 Local Header Offset   000002F7 (759)\n+7E29 Filename              'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX'\n #\n-# WARNING: Offset 0x7D9B: Filename 'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX'\n+# WARNING: Offset 0x7E29: Filename 'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX'\n #          Zero length filename\n #\n-# ERROR: Offset 0x7D9B: Directory 'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX' must end in a '/'\n+# ERROR: Offset 0x7E29: Directory 'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX' must end in a '/'\n #        'External Attributes' flag this as a directory\n #\n-# WARNING: Offset 0x7D73: 'Extract Zip Spec' is '1.0'. Need value >= '2.0' for Directory 'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX'\n+# WARNING: Offset 0x7E01: 'Extract Zip Spec' is '1.0'. Need value >= '2.0' for Directory 'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX'\n #\n \n-7DD1 CENTRAL HEADER #15    02014B50 (33639248)\n-7DD5 Created Zip Spec      14 (20) '2.0'\n-7DD6 Created OS            03 (3) 'Unix'\n-7DD7 Extract Zip Spec      14 (20) '2.0'\n-7DD8 Extract OS            00 (0) 'MS-DOS'\n-7DD9 General Purpose Flag  0800 (2048)\n-     [Bits 1-2]            0 'Normal Compression'\n-     [Bit 11]              1 'Language Encoding'\n-7DDB Compression Method    0008 (8) 'Deflated'\n-7DDD Modification Time     50814080 (1350647936) 'Wed Apr  1 08:04:00 2020'\n-7DE1 CRC                   0F83987F (260282495)\n-7DE5 Compressed Size       000002FB (763)\n-7DE9 Uncompressed Size     00000ACF (2767)\n-7DED Filename Length       0015 (21)\n-7DEF Extra Length          0000 (0)\n-7DF1 Comment Length        0000 (0)\n-7DF3 Disk Start            0000 (0)\n-7DF5 Int File Attributes   0000 (0)\n+7E5F CENTRAL HEADER #15    02014B50 (33639248)\n+7E63 Created Zip Spec      14 (20) '2.0'\n+7E64 Created OS            03 (3) 'Unix'\n+7E65 Extract Zip Spec      14 (20) '2.0'\n+7E66 Extract OS            00 (0) 'MS-DOS'\n+7E67 General Purpose Flag  0800 (2048)\n+     [Bits 1-2]            0 'Normal Compression'\n+     [Bit 11]              1 'Language Encoding'\n+7E69 Compression Method    0008 (8) 'Deflated'\n+7E6B Modification Time     50814080 (1350647936) 'Wed Apr  1 08:04:00 2020'\n+7E6F CRC                   0F83987F (260282495)\n+7E73 Compressed Size       000002FB (763)\n+7E77 Uncompressed Size     00000ACF (2767)\n+7E7B Filename Length       0015 (21)\n+7E7D Extra Length          0000 (0)\n+7E7F Comment Length        0000 (0)\n+7E81 Disk Start            0000 (0)\n+7E83 Int File Attributes   0000 (0)\n      [Bit 0]               0 'Binary Data'\n-7DF7 Ext File Attributes   81A40000 (2175008768)\n+7E85 Ext File Attributes   81A40000 (2175008768)\n      [Bits 16-24]          01A4 (420) 'Unix attrib: rw-r--r--'\n      [Bits 28-31]          08 (8) 'Regular File'\n-7DFB Local Header Offset   0000034B (843)\n-7DFF Filename              'XXXXXXXXXXXXXXXXXXXXX'\n+7E89 Local Header Offset   0000034B (843)\n+7E8D Filename              'XXXXXXXXXXXXXXXXXXXXX'\n #\n-# WARNING: Offset 0x7DFF: Filename 'XXXXXXXXXXXXXXXXXXXXX'\n+# WARNING: Offset 0x7E8D: Filename 'XXXXXXXXXXXXXXXXXXXXX'\n #          Zero length filename\n #\n \n-7E14 CENTRAL HEADER #16    02014B50 (33639248)\n-7E18 Created Zip Spec      14 (20) '2.0'\n-7E19 Created OS            03 (3) 'Unix'\n-7E1A Extract Zip Spec      14 (20) '2.0'\n-7E1B Extract OS            00 (0) 'MS-DOS'\n-7E1C General Purpose Flag  0800 (2048)\n+7EA2 CENTRAL HEADER #16    02014B50 (33639248)\n+7EA6 Created Zip Spec      14 (20) '2.0'\n+7EA7 Created OS            03 (3) 'Unix'\n+7EA8 Extract Zip Spec      14 (20) '2.0'\n+7EA9 Extract OS            00 (0) 'MS-DOS'\n+7EAA General Purpose Flag  0800 (2048)\n      [Bits 1-2]            0 'Normal Compression'\n      [Bit 11]              1 'Language Encoding'\n-7E1E Compression Method    0008 (8) 'Deflated'\n-7E20 Modification Time     50814080 (1350647936) 'Wed Apr  1 08:04:00 2020'\n-7E24 CRC                   86E2B4B4 (2263004340)\n-7E28 Compressed Size       00000F6D (3949)\n-7E2C Uncompressed Size     00002C5E (11358)\n-7E30 Filename Length       0010 (16)\n-7E32 Extra Length          0000 (0)\n-7E34 Comment Length        0000 (0)\n-7E36 Disk Start            0000 (0)\n-7E38 Int File Attributes   0000 (0)\n+7EAC Compression Method    0008 (8) 'Deflated'\n+7EAE Modification Time     50814080 (1350647936) 'Wed Apr  1 08:04:00 2020'\n+7EB2 CRC                   86E2B4B4 (2263004340)\n+7EB6 Compressed Size       00000F6D (3949)\n+7EBA Uncompressed Size     00002C5E (11358)\n+7EBE Filename Length       0010 (16)\n+7EC0 Extra Length          0000 (0)\n+7EC2 Comment Length        0000 (0)\n+7EC4 Disk Start            0000 (0)\n+7EC6 Int File Attributes   0000 (0)\n      [Bit 0]               0 'Binary Data'\n-7E3A Ext File Attributes   81A40000 (2175008768)\n+7EC8 Ext File Attributes   81A40000 (2175008768)\n      [Bits 16-24]          01A4 (420) 'Unix attrib: rw-r--r--'\n      [Bits 28-31]          08 (8) 'Regular File'\n-7E3E Local Header Offset   00000679 (1657)\n-7E42 Filename              'XXXXXXXXXXXXXXXX'\n+7ECC Local Header Offset   00000679 (1657)\n+7ED0 Filename              'XXXXXXXXXXXXXXXX'\n #\n-# WARNING: Offset 0x7E42: Filename 'XXXXXXXXXXXXXXXX'\n+# WARNING: Offset 0x7ED0: Filename 'XXXXXXXXXXXXXXXX'\n #          Zero length filename\n #\n \n-7E52 CENTRAL HEADER #17    02014B50 (33639248)\n-7E56 Created Zip Spec      14 (20) '2.0'\n-7E57 Created OS            03 (3) 'Unix'\n-7E58 Extract Zip Spec      14 (20) '2.0'\n-7E59 Extract OS            00 (0) 'MS-DOS'\n-7E5A General Purpose Flag  0800 (2048)\n+7EE0 CENTRAL HEADER #17    02014B50 (33639248)\n+7EE4 Created Zip Spec      14 (20) '2.0'\n+7EE5 Created OS            03 (3) 'Unix'\n+7EE6 Extract Zip Spec      14 (20) '2.0'\n+7EE7 Extract OS            00 (0) 'MS-DOS'\n+7EE8 General Purpose Flag  0800 (2048)\n      [Bits 1-2]            0 'Normal Compression'\n      [Bit 11]              1 'Language Encoding'\n-7E5C Compression Method    0008 (8) 'Deflated'\n-7E5E Modification Time     50814080 (1350647936) 'Wed Apr  1 08:04:00 2020'\n-7E62 CRC                   5A29D305 (1512690437)\n-7E66 Compressed Size       00000083 (131)\n-7E6A Uncompressed Size     000000B2 (178)\n-7E6E Filename Length       000F (15)\n-7E70 Extra Length          0000 (0)\n-7E72 Comment Length        0000 (0)\n-7E74 Disk Start            0000 (0)\n-7E76 Int File Attributes   0000 (0)\n+7EEA Compression Method    0008 (8) 'Deflated'\n+7EEC Modification Time     50814080 (1350647936) 'Wed Apr  1 08:04:00 2020'\n+7EF0 CRC                   5A29D305 (1512690437)\n+7EF4 Compressed Size       00000083 (131)\n+7EF8 Uncompressed Size     000000B2 (178)\n+7EFC Filename Length       000F (15)\n+7EFE Extra Length          0000 (0)\n+7F00 Comment Length        0000 (0)\n+7F02 Disk Start            0000 (0)\n+7F04 Int File Attributes   0000 (0)\n      [Bit 0]               0 'Binary Data'\n-7E78 Ext File Attributes   81A40000 (2175008768)\n+7F06 Ext File Attributes   81A40000 (2175008768)\n      [Bits 16-24]          01A4 (420) 'Unix attrib: rw-r--r--'\n      [Bits 28-31]          08 (8) 'Regular File'\n-7E7C Local Header Offset   00001614 (5652)\n-7E80 Filename              'XXXXXXXXXXXXXXX'\n+7F0A Local Header Offset   00001614 (5652)\n+7F0E Filename              'XXXXXXXXXXXXXXX'\n #\n-# WARNING: Offset 0x7E80: Filename 'XXXXXXXXXXXXXXX'\n+# WARNING: Offset 0x7F0E: Filename 'XXXXXXXXXXXXXXX'\n #          Zero length filename\n #\n \n-7E8F CENTRAL HEADER #18    02014B50 (33639248)\n-7E93 Created Zip Spec      14 (20) '2.0'\n-7E94 Created OS            03 (3) 'Unix'\n-7E95 Extract Zip Spec      14 (20) '2.0'\n-7E96 Extract OS            00 (0) 'MS-DOS'\n-7E97 General Purpose Flag  0800 (2048)\n+7F1D CENTRAL HEADER #18    02014B50 (33639248)\n+7F21 Created Zip Spec      14 (20) '2.0'\n+7F22 Created OS            03 (3) 'Unix'\n+7F23 Extract Zip Spec      14 (20) '2.0'\n+7F24 Extract OS            00 (0) 'MS-DOS'\n+7F25 General Purpose Flag  0800 (2048)\n      [Bits 1-2]            0 'Normal Compression'\n      [Bit 11]              1 'Language Encoding'\n-7E99 Compression Method    0008 (8) 'Deflated'\n-7E9B Modification Time     50814080 (1350647936) 'Wed Apr  1 08:04:00 2020'\n-7E9F CRC                   73E7CE8A (1944571530)\n-7EA3 Compressed Size       00000686 (1670)\n-7EA7 Uncompressed Size     000027E6 (10214)\n-7EAB Filename Length       0048 (72)\n-7EAD Extra Length          0000 (0)\n-7EAF Comment Length        0000 (0)\n-7EB1 Disk Start            0000 (0)\n-7EB3 Int File Attributes   0000 (0)\n+7F27 Compression Method    0008 (8) 'Deflated'\n+7F29 Modification Time     50814080 (1350647936) 'Wed Apr  1 08:04:00 2020'\n+7F2D CRC                   73E7CE8A (1944571530)\n+7F31 Compressed Size       00000686 (1670)\n+7F35 Uncompressed Size     000027E6 (10214)\n+7F39 Filename Length       0048 (72)\n+7F3B Extra Length          0000 (0)\n+7F3D Comment Length        0000 (0)\n+7F3F Disk Start            0000 (0)\n+7F41 Int File Attributes   0000 (0)\n      [Bit 0]               0 'Binary Data'\n-7EB5 Ext File Attributes   81A40000 (2175008768)\n+7F43 Ext File Attributes   81A40000 (2175008768)\n      [Bits 16-24]          01A4 (420) 'Unix attrib: rw-r--r--'\n      [Bits 28-31]          08 (8) 'Regular File'\n-7EB9 Local Header Offset   000016C4 (5828)\n-7EBD Filename              'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX'\n+7F47 Local Header Offset   000016C4 (5828)\n+7F4B Filename              'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX'\n #\n-# WARNING: Offset 0x7EBD: Filename 'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX'\n+# WARNING: Offset 0x7F4B: Filename 'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX'\n #          Zero length filename\n #\n \n-7F05 CENTRAL HEADER #19    02014B50 (33639248)\n-7F09 Created Zip Spec      14 (20) '2.0'\n-7F0A Created OS            03 (3) 'Unix'\n-7F0B Extract Zip Spec      14 (20) '2.0'\n-7F0C Extract OS            00 (0) 'MS-DOS'\n-7F0D General Purpose Flag  0800 (2048)\n+7F93 CENTRAL HEADER #19    02014B50 (33639248)\n+7F97 Created Zip Spec      14 (20) '2.0'\n+7F98 Created OS            03 (3) 'Unix'\n+7F99 Extract Zip Spec      14 (20) '2.0'\n+7F9A Extract OS            00 (0) 'MS-DOS'\n+7F9B General Purpose Flag  0800 (2048)\n      [Bits 1-2]            0 'Normal Compression'\n      [Bit 11]              1 'Language Encoding'\n-7F0F Compression Method    0008 (8) 'Deflated'\n-7F11 Modification Time     50814080 (1350647936) 'Wed Apr  1 08:04:00 2020'\n-7F15 CRC                   CD460ADB (3443919579)\n-7F19 Compressed Size       0000096A (2410)\n-7F1D Uncompressed Size     00002241 (8769)\n-7F21 Filename Length       003C (60)\n-7F23 Extra Length          0000 (0)\n-7F25 Comment Length        0000 (0)\n-7F27 Disk Start            0000 (0)\n-7F29 Int File Attributes   0000 (0)\n+7F9D Compression Method    0008 (8) 'Deflated'\n+7F9F Modification Time     50814080 (1350647936) 'Wed Apr  1 08:04:00 2020'\n+7FA3 CRC                   EADF50E0 (3940503776)\n+7FA7 Compressed Size       0000097F (2431)\n+7FAB Uncompressed Size     00002355 (9045)\n+7FAF Filename Length       003C (60)\n+7FB1 Extra Length          0000 (0)\n+7FB3 Comment Length        0000 (0)\n+7FB5 Disk Start            0000 (0)\n+7FB7 Int File Attributes   0000 (0)\n      [Bit 0]               0 'Binary Data'\n-7F2B Ext File Attributes   81A40000 (2175008768)\n+7FB9 Ext File Attributes   81A40000 (2175008768)\n      [Bits 16-24]          01A4 (420) 'Unix attrib: rw-r--r--'\n      [Bits 28-31]          08 (8) 'Regular File'\n-7F2F Local Header Offset   00001DB0 (7600)\n-7F33 Filename              'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX'\n+7FBD Local Header Offset   00001DB0 (7600)\n+7FC1 Filename              'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX'\n #\n-# WARNING: Offset 0x7F33: Filename 'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX'\n+# WARNING: Offset 0x7FC1: Filename 'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX'\n #          Zero length filename\n #\n \n-7F6F CENTRAL HEADER #20    02014B50 (33639248)\n-7F73 Created Zip Spec      14 (20) '2.0'\n-7F74 Created OS            03 (3) 'Unix'\n-7F75 Extract Zip Spec      14 (20) '2.0'\n-7F76 Extract OS            00 (0) 'MS-DOS'\n-7F77 General Purpose Flag  0800 (2048)\n+7FFD CENTRAL HEADER #20    02014B50 (33639248)\n+8001 Created Zip Spec      14 (20) '2.0'\n+8002 Created OS            03 (3) 'Unix'\n+8003 Extract Zip Spec      14 (20) '2.0'\n+8004 Extract OS            00 (0) 'MS-DOS'\n+8005 General Purpose Flag  0800 (2048)\n      [Bits 1-2]            0 'Normal Compression'\n      [Bit 11]              1 'Language Encoding'\n-7F79 Compression Method    0008 (8) 'Deflated'\n-7F7B Modification Time     50814080 (1350647936) 'Wed Apr  1 08:04:00 2020'\n-7F7F CRC                   17148ACF (387222223)\n-7F83 Compressed Size       00000AB8 (2744)\n-7F87 Uncompressed Size     00002446 (9286)\n-7F8B Filename Length       003B (59)\n-7F8D Extra Length          0000 (0)\n-7F8F Comment Length        0000 (0)\n-7F91 Disk Start            0000 (0)\n-7F93 Int File Attributes   0000 (0)\n+8007 Compression Method    0008 (8) 'Deflated'\n+8009 Modification Time     50814080 (1350647936) 'Wed Apr  1 08:04:00 2020'\n+800D CRC                   1CB2BCAF (481475759)\n+8011 Compressed Size       00000AC6 (2758)\n+8015 Uncompressed Size     0000251F (9503)\n+8019 Filename Length       003B (59)\n+801B Extra Length          0000 (0)\n+801D Comment Length        0000 (0)\n+801F Disk Start            0000 (0)\n+8021 Int File Attributes   0000 (0)\n      [Bit 0]               0 'Binary Data'\n-7F95 Ext File Attributes   81A40000 (2175008768)\n+8023 Ext File Attributes   81A40000 (2175008768)\n      [Bits 16-24]          01A4 (420) 'Unix attrib: rw-r--r--'\n      [Bits 28-31]          08 (8) 'Regular File'\n-7F99 Local Header Offset   00002774 (10100)\n-7F9D Filename              'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX'\n+8027 Local Header Offset   00002789 (10121)\n+802B Filename              'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX'\n #\n-# WARNING: Offset 0x7F9D: Filename 'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX'\n+# WARNING: Offset 0x802B: Filename 'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX'\n #          Zero length filename\n #\n \n-7FD8 CENTRAL HEADER #21    02014B50 (33639248)\n-7FDC Created Zip Spec      14 (20) '2.0'\n-7FDD Created OS            03 (3) 'Unix'\n-7FDE Extract Zip Spec      14 (20) '2.0'\n-7FDF Extract OS            00 (0) 'MS-DOS'\n-7FE0 General Purpose Flag  0800 (2048)\n+8066 CENTRAL HEADER #21    02014B50 (33639248)\n+806A Created Zip Spec      14 (20) '2.0'\n+806B Created OS            03 (3) 'Unix'\n+806C Extract Zip Spec      14 (20) '2.0'\n+806D Extract OS            00 (0) 'MS-DOS'\n+806E General Purpose Flag  0800 (2048)\n      [Bits 1-2]            0 'Normal Compression'\n      [Bit 11]              1 'Language Encoding'\n-7FE2 Compression Method    0008 (8) 'Deflated'\n-7FE4 Modification Time     50814080 (1350647936) 'Wed Apr  1 08:04:00 2020'\n-7FE8 CRC                   15F2B7F5 (368228341)\n-7FEC Compressed Size       0000074A (1866)\n-7FF0 Uncompressed Size     00001869 (6249)\n-7FF4 Filename Length       0042 (66)\n-7FF6 Extra Length          0000 (0)\n-7FF8 Comment Length        0000 (0)\n-7FFA Disk Start            0000 (0)\n-7FFC Int File Attributes   0000 (0)\n+8070 Compression Method    0008 (8) 'Deflated'\n+8072 Modification Time     50814080 (1350647936) 'Wed Apr  1 08:04:00 2020'\n+8076 CRC                   7DE2A421 (2112005153)\n+807A Compressed Size       0000075A (1882)\n+807E Uncompressed Size     0000190A (6410)\n+8082 Filename Length       0042 (66)\n+8084 Extra Length          0000 (0)\n+8086 Comment Length        0000 (0)\n+8088 Disk Start            0000 (0)\n+808A Int File Attributes   0000 (0)\n      [Bit 0]               0 'Binary Data'\n-7FFE Ext File Attributes   81A40000 (2175008768)\n+808C Ext File Attributes   81A40000 (2175008768)\n      [Bits 16-24]          01A4 (420) 'Unix attrib: rw-r--r--'\n      [Bits 28-31]          08 (8) 'Regular File'\n-8002 Local Header Offset   00003285 (12933)\n-8006 Filename              'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX'\n+8090 Local Header Offset   000032A8 (12968)\n+8094 Filename              'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX'\n #\n-# WARNING: Offset 0x8006: Filename 'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX'\n+# WARNING: Offset 0x8094: Filename 'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX'\n #          Zero length filename\n #\n \n-8048 CENTRAL HEADER #22    02014B50 (33639248)\n-804C Created Zip Spec      14 (20) '2.0'\n-804D Created OS            03 (3) 'Unix'\n-804E Extract Zip Spec      14 (20) '2.0'\n-804F Extract OS            00 (0) 'MS-DOS'\n-8050 General Purpose Flag  0800 (2048)\n+80D6 CENTRAL HEADER #22    02014B50 (33639248)\n+80DA Created Zip Spec      14 (20) '2.0'\n+80DB Created OS            03 (3) 'Unix'\n+80DC Extract Zip Spec      14 (20) '2.0'\n+80DD Extract OS            00 (0) 'MS-DOS'\n+80DE General Purpose Flag  0800 (2048)\n      [Bits 1-2]            0 'Normal Compression'\n      [Bit 11]              1 'Language Encoding'\n-8052 Compression Method    0008 (8) 'Deflated'\n-8054 Modification Time     50814080 (1350647936) 'Wed Apr  1 08:04:00 2020'\n-8058 CRC                   BA9CD18D (3130839437)\n-805C Compressed Size       000004BF (1215)\n-8060 Uncompressed Size     00000DDB (3547)\n-8064 Filename Length       0041 (65)\n-8066 Extra Length          0000 (0)\n-8068 Comment Length        0000 (0)\n-806A Disk Start            0000 (0)\n-806C Int File Attributes   0000 (0)\n+80E0 Compression Method    0008 (8) 'Deflated'\n+80E2 Modification Time     50814080 (1350647936) 'Wed Apr  1 08:04:00 2020'\n+80E6 CRC                   3BA2E25A (1000530522)\n+80EA Compressed Size       000004C9 (1225)\n+80EE Uncompressed Size     00000E40 (3648)\n+80F2 Filename Length       0041 (65)\n+80F4 Extra Length          0000 (0)\n+80F6 Comment Length        0000 (0)\n+80F8 Disk Start            0000 (0)\n+80FA Int File Attributes   0000 (0)\n      [Bit 0]               0 'Binary Data'\n-806E Ext File Attributes   81A40000 (2175008768)\n+80FC Ext File Attributes   81A40000 (2175008768)\n      [Bits 16-24]          01A4 (420) 'Unix attrib: rw-r--r--'\n      [Bits 28-31]          08 (8) 'Regular File'\n-8072 Local Header Offset   00003A2F (14895)\n-8076 Filename              'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX'\n+8100 Local Header Offset   00003A62 (14946)\n+8104 Filename              'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX'\n #\n-# WARNING: Offset 0x8076: Filename 'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX'\n+# WARNING: Offset 0x8104: Filename 'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX'\n #          Zero length filename\n #\n \n-80B7 CENTRAL HEADER #23    02014B50 (33639248)\n-80BB Created Zip Spec      14 (20) '2.0'\n-80BC Created OS            03 (3) 'Unix'\n-80BD Extract Zip Spec      14 (20) '2.0'\n-80BE Extract OS            00 (0) 'MS-DOS'\n-80BF General Purpose Flag  0800 (2048)\n+8145 CENTRAL HEADER #23    02014B50 (33639248)\n+8149 Created Zip Spec      14 (20) '2.0'\n+814A Created OS            03 (3) 'Unix'\n+814B Extract Zip Spec      14 (20) '2.0'\n+814C Extract OS            00 (0) 'MS-DOS'\n+814D General Purpose Flag  0800 (2048)\n      [Bits 1-2]            0 'Normal Compression'\n      [Bit 11]              1 'Language Encoding'\n-80C1 Compression Method    0008 (8) 'Deflated'\n-80C3 Modification Time     50814080 (1350647936) 'Wed Apr  1 08:04:00 2020'\n-80C7 CRC                   16F071B0 (384856496)\n-80CB Compressed Size       000003CA (970)\n-80CF Uncompressed Size     00000A5E (2654)\n-80D3 Filename Length       0045 (69)\n-80D5 Extra Length          0000 (0)\n-80D7 Comment Length        0000 (0)\n-80D9 Disk Start            0000 (0)\n-80DB Int File Attributes   0000 (0)\n+814F Compression Method    0008 (8) 'Deflated'\n+8151 Modification Time     50814080 (1350647936) 'Wed Apr  1 08:04:00 2020'\n+8155 CRC                   1E5B2A86 (509291142)\n+8159 Compressed Size       000003D1 (977)\n+815D Uncompressed Size     00000A9A (2714)\n+8161 Filename Length       0045 (69)\n+8163 Extra Length          0000 (0)\n+8165 Comment Length        0000 (0)\n+8167 Disk Start            0000 (0)\n+8169 Int File Attributes   0000 (0)\n      [Bit 0]               0 'Binary Data'\n-80DD Ext File Attributes   81A40000 (2175008768)\n+816B Ext File Attributes   81A40000 (2175008768)\n      [Bits 16-24]          01A4 (420) 'Unix attrib: rw-r--r--'\n      [Bits 28-31]          08 (8) 'Regular File'\n-80E1 Local Header Offset   00003F4D (16205)\n-80E5 Filename              'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX'\n+816F Local Header Offset   00003F8A (16266)\n+8173 Filename              'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX'\n #\n-# WARNING: Offset 0x80E5: Filename 'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX'\n+# WARNING: Offset 0x8173: Filename 'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX'\n #          Zero length filename\n #\n \n-812A CENTRAL HEADER #24    02014B50 (33639248)\n-812E Created Zip Spec      14 (20) '2.0'\n-812F Created OS            03 (3) 'Unix'\n-8130 Extract Zip Spec      14 (20) '2.0'\n-8131 Extract OS            00 (0) 'MS-DOS'\n-8132 General Purpose Flag  0800 (2048)\n+81B8 CENTRAL HEADER #24    02014B50 (33639248)\n+81BC Created Zip Spec      14 (20) '2.0'\n+81BD Created OS            03 (3) 'Unix'\n+81BE Extract Zip Spec      14 (20) '2.0'\n+81BF Extract OS            00 (0) 'MS-DOS'\n+81C0 General Purpose Flag  0800 (2048)\n      [Bits 1-2]            0 'Normal Compression'\n      [Bit 11]              1 'Language Encoding'\n-8134 Compression Method    0008 (8) 'Deflated'\n-8136 Modification Time     50814080 (1350647936) 'Wed Apr  1 08:04:00 2020'\n-813A CRC                   99FF093E (2583628094)\n-813E Compressed Size       00000923 (2339)\n-8142 Uncompressed Size     00001F03 (7939)\n-8146 Filename Length       003B (59)\n-8148 Extra Length          0000 (0)\n-814A Comment Length        0000 (0)\n-814C Disk Start            0000 (0)\n-814E Int File Attributes   0000 (0)\n+81C2 Compression Method    0008 (8) 'Deflated'\n+81C4 Modification Time     50814080 (1350647936) 'Wed Apr  1 08:04:00 2020'\n+81C8 CRC                   1CDD10AA (484249770)\n+81CC Compressed Size       00000935 (2357)\n+81D0 Uncompressed Size     00001FCD (8141)\n+81D4 Filename Length       003B (59)\n+81D6 Extra Length          0000 (0)\n+81D8 Comment Length        0000 (0)\n+81DA Disk Start            0000 (0)\n+81DC Int File Attributes   0000 (0)\n      [Bit 0]               0 'Binary Data'\n-8150 Ext File Attributes   81A40000 (2175008768)\n+81DE Ext File Attributes   81A40000 (2175008768)\n      [Bits 16-24]          01A4 (420) 'Unix attrib: rw-r--r--'\n      [Bits 28-31]          08 (8) 'Regular File'\n-8154 Local Header Offset   0000437A (17274)\n-8158 Filename              'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX'\n+81E2 Local Header Offset   000043BE (17342)\n+81E6 Filename              'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX'\n #\n-# WARNING: Offset 0x8158: Filename 'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX'\n+# WARNING: Offset 0x81E6: Filename 'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX'\n #          Zero length filename\n #\n \n-8193 CENTRAL HEADER #25    02014B50 (33639248)\n-8197 Created Zip Spec      14 (20) '2.0'\n-8198 Created OS            03 (3) 'Unix'\n-8199 Extract Zip Spec      14 (20) '2.0'\n-819A Extract OS            00 (0) 'MS-DOS'\n-819B General Purpose Flag  0800 (2048)\n+8221 CENTRAL HEADER #25    02014B50 (33639248)\n+8225 Created Zip Spec      14 (20) '2.0'\n+8226 Created OS            03 (3) 'Unix'\n+8227 Extract Zip Spec      14 (20) '2.0'\n+8228 Extract OS            00 (0) 'MS-DOS'\n+8229 General Purpose Flag  0800 (2048)\n      [Bits 1-2]            0 'Normal Compression'\n      [Bit 11]              1 'Language Encoding'\n-819D Compression Method    0008 (8) 'Deflated'\n-819F Modification Time     50814080 (1350647936) 'Wed Apr  1 08:04:00 2020'\n-81A3 CRC                   7ED127C7 (2127636423)\n-81A7 Compressed Size       000005D7 (1495)\n-81AB Uncompressed Size     0000147B (5243)\n-81AF Filename Length       0042 (66)\n-81B1 Extra Length          0000 (0)\n-81B3 Comment Length        0000 (0)\n-81B5 Disk Start            0000 (0)\n-81B7 Int File Attributes   0000 (0)\n+822B Compression Method    0008 (8) 'Deflated'\n+822D Modification Time     50814080 (1350647936) 'Wed Apr  1 08:04:00 2020'\n+8231 CRC                   52A8EAC6 (1386801862)\n+8235 Compressed Size       000005E0 (1504)\n+8239 Uncompressed Size     00001505 (5381)\n+823D Filename Length       0042 (66)\n+823F Extra Length          0000 (0)\n+8241 Comment Length        0000 (0)\n+8243 Disk Start            0000 (0)\n+8245 Int File Attributes   0000 (0)\n      [Bit 0]               0 'Binary Data'\n-81B9 Ext File Attributes   81A40000 (2175008768)\n+8247 Ext File Attributes   81A40000 (2175008768)\n      [Bits 16-24]          01A4 (420) 'Unix attrib: rw-r--r--'\n      [Bits 28-31]          08 (8) 'Regular File'\n-81BD Local Header Offset   00004CF6 (19702)\n-81C1 Filename              'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX'\n+824B Local Header Offset   00004D4C (19788)\n+824F Filename              'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX'\n #\n-# WARNING: Offset 0x81C1: Filename 'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX'\n+# WARNING: Offset 0x824F: Filename 'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX'\n #          Zero length filename\n #\n \n-8203 CENTRAL HEADER #26    02014B50 (33639248)\n-8207 Created Zip Spec      14 (20) '2.0'\n-8208 Created OS            03 (3) 'Unix'\n-8209 Extract Zip Spec      14 (20) '2.0'\n-820A Extract OS            00 (0) 'MS-DOS'\n-820B General Purpose Flag  0800 (2048)\n+8291 CENTRAL HEADER #26    02014B50 (33639248)\n+8295 Created Zip Spec      14 (20) '2.0'\n+8296 Created OS            03 (3) 'Unix'\n+8297 Extract Zip Spec      14 (20) '2.0'\n+8298 Extract OS            00 (0) 'MS-DOS'\n+8299 General Purpose Flag  0800 (2048)\n      [Bits 1-2]            0 'Normal Compression'\n      [Bit 11]              1 'Language Encoding'\n-820D Compression Method    0008 (8) 'Deflated'\n-820F Modification Time     50814080 (1350647936) 'Wed Apr  1 08:04:00 2020'\n-8213 CRC                   4AAC1D37 (1252793655)\n-8217 Compressed Size       000002CA (714)\n-821B Uncompressed Size     0000064E (1614)\n-821F Filename Length       0040 (64)\n-8221 Extra Length          0000 (0)\n-8223 Comment Length        0000 (0)\n-8225 Disk Start            0000 (0)\n-8227 Int File Attributes   0000 (0)\n+829B Compression Method    0008 (8) 'Deflated'\n+829D Modification Time     50814080 (1350647936) 'Wed Apr  1 08:04:00 2020'\n+82A1 CRC                   1AC58108 (449151240)\n+82A5 Compressed Size       000002D4 (724)\n+82A9 Uncompressed Size     00000679 (1657)\n+82AD Filename Length       0040 (64)\n+82AF Extra Length          0000 (0)\n+82B1 Comment Length        0000 (0)\n+82B3 Disk Start            0000 (0)\n+82B5 Int File Attributes   0000 (0)\n      [Bit 0]               0 'Binary Data'\n-8229 Ext File Attributes   81A40000 (2175008768)\n+82B7 Ext File Attributes   81A40000 (2175008768)\n      [Bits 16-24]          01A4 (420) 'Unix attrib: rw-r--r--'\n      [Bits 28-31]          08 (8) 'Regular File'\n-822D Local Header Offset   0000532D (21293)\n-8231 Filename              'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX'\n+82BB Local Header Offset   0000538C (21388)\n+82BF Filename              'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX'\n #\n-# WARNING: Offset 0x8231: Filename 'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX'\n+# WARNING: Offset 0x82BF: Filename 'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX'\n #          Zero length filename\n #\n \n-8271 CENTRAL HEADER #27    02014B50 (33639248)\n-8275 Created Zip Spec      14 (20) '2.0'\n-8276 Created OS            03 (3) 'Unix'\n-8277 Extract Zip Spec      14 (20) '2.0'\n-8278 Extract OS            00 (0) 'MS-DOS'\n-8279 General Purpose Flag  0800 (2048)\n+82FF CENTRAL HEADER #27    02014B50 (33639248)\n+8303 Created Zip Spec      14 (20) '2.0'\n+8304 Created OS            03 (3) 'Unix'\n+8305 Extract Zip Spec      14 (20) '2.0'\n+8306 Extract OS            00 (0) 'MS-DOS'\n+8307 General Purpose Flag  0800 (2048)\n      [Bits 1-2]            0 'Normal Compression'\n      [Bit 11]              1 'Language Encoding'\n-827B Compression Method    0008 (8) 'Deflated'\n-827D Modification Time     50814080 (1350647936) 'Wed Apr  1 08:04:00 2020'\n-8281 CRC                   155577E8 (357922792)\n-8285 Compressed Size       00000614 (1556)\n-8289 Uncompressed Size     000015AE (5550)\n-828D Filename Length       003B (59)\n-828F Extra Length          0000 (0)\n-8291 Comment Length        0000 (0)\n-8293 Disk Start            0000 (0)\n-8295 Int File Attributes   0000 (0)\n+8309 Compression Method    0008 (8) 'Deflated'\n+830B Modification Time     50814080 (1350647936) 'Wed Apr  1 08:04:00 2020'\n+830F CRC                   377C624A (930898506)\n+8313 Compressed Size       00000621 (1569)\n+8317 Uncompressed Size     00001627 (5671)\n+831B Filename Length       003B (59)\n+831D Extra Length          0000 (0)\n+831F Comment Length        0000 (0)\n+8321 Disk Start            0000 (0)\n+8323 Int File Attributes   0000 (0)\n      [Bit 0]               0 'Binary Data'\n-8297 Ext File Attributes   81A40000 (2175008768)\n+8325 Ext File Attributes   81A40000 (2175008768)\n      [Bits 16-24]          01A4 (420) 'Unix attrib: rw-r--r--'\n      [Bits 28-31]          08 (8) 'Regular File'\n-829B Local Header Offset   00005655 (22101)\n-829F Filename              'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX'\n+8329 Local Header Offset   000056BE (22206)\n+832D Filename              'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX'\n #\n-# WARNING: Offset 0x829F: Filename 'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX'\n+# WARNING: Offset 0x832D: Filename 'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX'\n #          Zero length filename\n #\n \n-82DA CENTRAL HEADER #28    02014B50 (33639248)\n-82DE Created Zip Spec      14 (20) '2.0'\n-82DF Created OS            03 (3) 'Unix'\n-82E0 Extract Zip Spec      14 (20) '2.0'\n-82E1 Extract OS            00 (0) 'MS-DOS'\n-82E2 General Purpose Flag  0800 (2048)\n+8368 CENTRAL HEADER #28    02014B50 (33639248)\n+836C Created Zip Spec      14 (20) '2.0'\n+836D Created OS            03 (3) 'Unix'\n+836E Extract Zip Spec      14 (20) '2.0'\n+836F Extract OS            00 (0) 'MS-DOS'\n+8370 General Purpose Flag  0800 (2048)\n      [Bits 1-2]            0 'Normal Compression'\n      [Bit 11]              1 'Language Encoding'\n-82E4 Compression Method    0008 (8) 'Deflated'\n-82E6 Modification Time     50814080 (1350647936) 'Wed Apr  1 08:04:00 2020'\n-82EA CRC                   FC50D2E5 (4233155301)\n-82EE Compressed Size       000005BE (1470)\n-82F2 Uncompressed Size     000016CB (5835)\n-82F6 Filename Length       0045 (69)\n-82F8 Extra Length          0000 (0)\n-82FA Comment Length        0000 (0)\n-82FC Disk Start            0000 (0)\n-82FE Int File Attributes   0000 (0)\n+8372 Compression Method    0008 (8) 'Deflated'\n+8374 Modification Time     50814080 (1350647936) 'Wed Apr  1 08:04:00 2020'\n+8378 CRC                   37334079 (926105721)\n+837C Compressed Size       000005C9 (1481)\n+8380 Uncompressed Size     00001758 (5976)\n+8384 Filename Length       0045 (69)\n+8386 Extra Length          0000 (0)\n+8388 Comment Length        0000 (0)\n+838A Disk Start            0000 (0)\n+838C Int File Attributes   0000 (0)\n      [Bit 0]               0 'Binary Data'\n-8300 Ext File Attributes   81A40000 (2175008768)\n+838E Ext File Attributes   81A40000 (2175008768)\n      [Bits 16-24]          01A4 (420) 'Unix attrib: rw-r--r--'\n      [Bits 28-31]          08 (8) 'Regular File'\n-8304 Local Header Offset   00005CC2 (23746)\n-8308 Filename              'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX'\n+8392 Local Header Offset   00005D38 (23864)\n+8396 Filename              'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX'\n #\n-# WARNING: Offset 0x8308: Filename 'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX'\n+# WARNING: Offset 0x8396: Filename 'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX'\n #          Zero length filename\n #\n \n-834D CENTRAL HEADER #29    02014B50 (33639248)\n-8351 Created Zip Spec      14 (20) '2.0'\n-8352 Created OS            03 (3) 'Unix'\n-8353 Extract Zip Spec      14 (20) '2.0'\n-8354 Extract OS            00 (0) 'MS-DOS'\n-8355 General Purpose Flag  0800 (2048)\n+83DB CENTRAL HEADER #29    02014B50 (33639248)\n+83DF Created Zip Spec      14 (20) '2.0'\n+83E0 Created OS            03 (3) 'Unix'\n+83E1 Extract Zip Spec      14 (20) '2.0'\n+83E2 Extract OS            00 (0) 'MS-DOS'\n+83E3 General Purpose Flag  0800 (2048)\n      [Bits 1-2]            0 'Normal Compression'\n      [Bit 11]              1 'Language Encoding'\n-8357 Compression Method    0008 (8) 'Deflated'\n-8359 Modification Time     50814080 (1350647936) 'Wed Apr  1 08:04:00 2020'\n-835D CRC                   58FEAB57 (1493085015)\n-8361 Compressed Size       000003A4 (932)\n-8365 Uncompressed Size     000008C3 (2243)\n-8369 Filename Length       0047 (71)\n-836B Extra Length          0000 (0)\n-836D Comment Length        0000 (0)\n-836F Disk Start            0000 (0)\n-8371 Int File Attributes   0000 (0)\n+83E5 Compression Method    0008 (8) 'Deflated'\n+83E7 Modification Time     50814080 (1350647936) 'Wed Apr  1 08:04:00 2020'\n+83EB CRC                   58FEAB57 (1493085015)\n+83EF Compressed Size       000003A4 (932)\n+83F3 Uncompressed Size     000008C3 (2243)\n+83F7 Filename Length       0047 (71)\n+83F9 Extra Length          0000 (0)\n+83FB Comment Length        0000 (0)\n+83FD Disk Start            0000 (0)\n+83FF Int File Attributes   0000 (0)\n      [Bit 0]               0 'Binary Data'\n-8373 Ext File Attributes   81A40000 (2175008768)\n+8401 Ext File Attributes   81A40000 (2175008768)\n      [Bits 16-24]          01A4 (420) 'Unix attrib: rw-r--r--'\n      [Bits 28-31]          08 (8) 'Regular File'\n-8377 Local Header Offset   000062E3 (25315)\n-837B Filename              'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX'\n+8405 Local Header Offset   00006364 (25444)\n+8409 Filename              'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX'\n #\n-# WARNING: Offset 0x837B: Filename 'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX'\n+# WARNING: Offset 0x8409: Filename 'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX'\n #          Zero length filename\n #\n \n-83C2 CENTRAL HEADER #30    02014B50 (33639248)\n-83C6 Created Zip Spec      14 (20) '2.0'\n-83C7 Created OS            03 (3) 'Unix'\n-83C8 Extract Zip Spec      14 (20) '2.0'\n-83C9 Extract OS            00 (0) 'MS-DOS'\n-83CA General Purpose Flag  0800 (2048)\n+8450 CENTRAL HEADER #30    02014B50 (33639248)\n+8454 Created Zip Spec      14 (20) '2.0'\n+8455 Created OS            03 (3) 'Unix'\n+8456 Extract Zip Spec      14 (20) '2.0'\n+8457 Extract OS            00 (0) 'MS-DOS'\n+8458 General Purpose Flag  0800 (2048)\n      [Bits 1-2]            0 'Normal Compression'\n      [Bit 11]              1 'Language Encoding'\n-83CC Compression Method    0008 (8) 'Deflated'\n-83CE Modification Time     50814080 (1350647936) 'Wed Apr  1 08:04:00 2020'\n-83D2 CRC                   BC1F87C6 (3156182982)\n-83D6 Compressed Size       00000D44 (3396)\n-83DA Uncompressed Size     0000391E (14622)\n-83DE Filename Length       0048 (72)\n-83E0 Extra Length          0000 (0)\n-83E2 Comment Length        0000 (0)\n-83E4 Disk Start            0000 (0)\n-83E6 Int File Attributes   0000 (0)\n+845A Compression Method    0008 (8) 'Deflated'\n+845C Modification Time     50814080 (1350647936) 'Wed Apr  1 08:04:00 2020'\n+8460 CRC                   A355BCB4 (2740305076)\n+8464 Compressed Size       00000D58 (3416)\n+8468 Uncompressed Size     00003AB8 (15032)\n+846C Filename Length       0048 (72)\n+846E Extra Length          0000 (0)\n+8470 Comment Length        0000 (0)\n+8472 Disk Start            0000 (0)\n+8474 Int File Attributes   0000 (0)\n      [Bit 0]               0 'Binary Data'\n-83E8 Ext File Attributes   81A40000 (2175008768)\n+8476 Ext File Attributes   81A40000 (2175008768)\n      [Bits 16-24]          01A4 (420) 'Unix attrib: rw-r--r--'\n      [Bits 28-31]          08 (8) 'Regular File'\n-83EC Local Header Offset   000066EC (26348)\n-83F0 Filename              'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX'\n+847A Local Header Offset   0000676D (26477)\n+847E Filename              'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX'\n #\n-# WARNING: Offset 0x83F0: Filename 'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX'\n+# WARNING: Offset 0x847E: Filename 'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX'\n #          Zero length filename\n #\n \n-8438 CENTRAL HEADER #31    02014B50 (33639248)\n-843C Created Zip Spec      14 (20) '2.0'\n-843D Created OS            03 (3) 'Unix'\n-843E Extract Zip Spec      14 (20) '2.0'\n-843F Extract OS            00 (0) 'MS-DOS'\n-8440 General Purpose Flag  0800 (2048)\n+84C6 CENTRAL HEADER #31    02014B50 (33639248)\n+84CA Created Zip Spec      14 (20) '2.0'\n+84CB Created OS            03 (3) 'Unix'\n+84CC Extract Zip Spec      14 (20) '2.0'\n+84CD Extract OS            00 (0) 'MS-DOS'\n+84CE General Purpose Flag  0800 (2048)\n      [Bits 1-2]            0 'Normal Compression'\n      [Bit 11]              1 'Language Encoding'\n-8442 Compression Method    0008 (8) 'Deflated'\n-8444 Modification Time     50814080 (1350647936) 'Wed Apr  1 08:04:00 2020'\n-8448 CRC                   8F7CA09F (2407309471)\n-844C Compressed Size       0000003F (63)\n-8450 Uncompressed Size     00000085 (133)\n-8454 Filename Length       003D (61)\n-8456 Extra Length          0000 (0)\n-8458 Comment Length        0000 (0)\n-845A Disk Start            0000 (0)\n-845C Int File Attributes   0000 (0)\n+84D0 Compression Method    0008 (8) 'Deflated'\n+84D2 Modification Time     50814080 (1350647936) 'Wed Apr  1 08:04:00 2020'\n+84D6 CRC                   8F7CA09F (2407309471)\n+84DA Compressed Size       0000003F (63)\n+84DE Uncompressed Size     00000085 (133)\n+84E2 Filename Length       003D (61)\n+84E4 Extra Length          0000 (0)\n+84E6 Comment Length        0000 (0)\n+84E8 Disk Start            0000 (0)\n+84EA Int File Attributes   0000 (0)\n      [Bit 0]               0 'Binary Data'\n-845E Ext File Attributes   81A40000 (2175008768)\n+84EC Ext File Attributes   81A40000 (2175008768)\n      [Bits 16-24]          01A4 (420) 'Unix attrib: rw-r--r--'\n      [Bits 28-31]          08 (8) 'Regular File'\n-8462 Local Header Offset   00007496 (29846)\n-8466 Filename              'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX'\n+84F0 Local Header Offset   0000752B (29995)\n+84F4 Filename              'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX'\n #\n-# WARNING: Offset 0x8466: Filename 'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX'\n+# WARNING: Offset 0x84F4: Filename 'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX'\n #          Zero length filename\n #\n \n-84A3 CENTRAL HEADER #32    02014B50 (33639248)\n-84A7 Created Zip Spec      14 (20) '2.0'\n-84A8 Created OS            03 (3) 'Unix'\n-84A9 Extract Zip Spec      14 (20) '2.0'\n-84AA Extract OS            00 (0) 'MS-DOS'\n-84AB General Purpose Flag  0800 (2048)\n+8531 CENTRAL HEADER #32    02014B50 (33639248)\n+8535 Created Zip Spec      14 (20) '2.0'\n+8536 Created OS            03 (3) 'Unix'\n+8537 Extract Zip Spec      14 (20) '2.0'\n+8538 Extract OS            00 (0) 'MS-DOS'\n+8539 General Purpose Flag  0800 (2048)\n      [Bits 1-2]            0 'Normal Compression'\n      [Bit 11]              1 'Language Encoding'\n-84AD Compression Method    0008 (8) 'Deflated'\n-84AF Modification Time     50814080 (1350647936) 'Wed Apr  1 08:04:00 2020'\n-84B3 CRC                   2E65EAC2 (778431170)\n-84B7 Compressed Size       000003B1 (945)\n-84BB Uncompressed Size     0000095F (2399)\n-84BF Filename Length       003D (61)\n-84C1 Extra Length          0000 (0)\n-84C3 Comment Length        0000 (0)\n-84C5 Disk Start            0000 (0)\n-84C7 Int File Attributes   0000 (0)\n+853B Compression Method    0008 (8) 'Deflated'\n+853D Modification Time     50814080 (1350647936) 'Wed Apr  1 08:04:00 2020'\n+8541 CRC                   1D29AE65 (489270885)\n+8545 Compressed Size       000003AA (938)\n+8549 Uncompressed Size     00000924 (2340)\n+854D Filename Length       003D (61)\n+854F Extra Length          0000 (0)\n+8551 Comment Length        0000 (0)\n+8553 Disk Start            0000 (0)\n+8555 Int File Attributes   0000 (0)\n      [Bit 0]               0 'Binary Data'\n-84C9 Ext File Attributes   81A40000 (2175008768)\n+8557 Ext File Attributes   81A40000 (2175008768)\n      [Bits 16-24]          01A4 (420) 'Unix attrib: rw-r--r--'\n      [Bits 28-31]          08 (8) 'Regular File'\n-84CD Local Header Offset   00007530 (30000)\n-84D1 Filename              'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX'\n+855B Local Header Offset   000075C5 (30149)\n+855F Filename              'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX'\n #\n-# WARNING: Offset 0x84D1: Filename 'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX'\n+# WARNING: Offset 0x855F: Filename 'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX'\n #          Zero length filename\n #\n \n-850E CENTRAL HEADER #33    02014B50 (33639248)\n-8512 Created Zip Spec      14 (20) '2.0'\n-8513 Created OS            03 (3) 'Unix'\n-8514 Extract Zip Spec      14 (20) '2.0'\n-8515 Extract OS            00 (0) 'MS-DOS'\n-8516 General Purpose Flag  0800 (2048)\n+859C CENTRAL HEADER #33    02014B50 (33639248)\n+85A0 Created Zip Spec      14 (20) '2.0'\n+85A1 Created OS            03 (3) 'Unix'\n+85A2 Extract Zip Spec      14 (20) '2.0'\n+85A3 Extract OS            00 (0) 'MS-DOS'\n+85A4 General Purpose Flag  0800 (2048)\n      [Bits 1-2]            0 'Normal Compression'\n      [Bit 11]              1 'Language Encoding'\n-8518 Compression Method    0008 (8) 'Deflated'\n-851A Modification Time     50814080 (1350647936) 'Wed Apr  1 08:04:00 2020'\n-851E CRC                   E328D6D4 (3811104468)\n-8522 Compressed Size       0000004A (74)\n-8526 Uncompressed Size     0000004C (76)\n-852A Filename Length       0044 (68)\n-852C Extra Length          0000 (0)\n-852E Comment Length        0000 (0)\n-8530 Disk Start            0000 (0)\n-8532 Int File Attributes   0000 (0)\n+85A6 Compression Method    0008 (8) 'Deflated'\n+85A8 Modification Time     50814080 (1350647936) 'Wed Apr  1 08:04:00 2020'\n+85AC CRC                   E328D6D4 (3811104468)\n+85B0 Compressed Size       0000004A (74)\n+85B4 Uncompressed Size     0000004C (76)\n+85B8 Filename Length       0044 (68)\n+85BA Extra Length          0000 (0)\n+85BC Comment Length        0000 (0)\n+85BE Disk Start            0000 (0)\n+85C0 Int File Attributes   0000 (0)\n      [Bit 0]               0 'Binary Data'\n-8534 Ext File Attributes   81A40000 (2175008768)\n+85C2 Ext File Attributes   81A40000 (2175008768)\n      [Bits 16-24]          01A4 (420) 'Unix attrib: rw-r--r--'\n      [Bits 28-31]          08 (8) 'Regular File'\n-8538 Local Header Offset   0000793C (31036)\n-853C Filename              'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX'\n+85C6 Local Header Offset   000079CA (31178)\n+85CA Filename              'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX'\n #\n-# WARNING: Offset 0x853C: Filename 'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX'\n+# WARNING: Offset 0x85CA: Filename 'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX'\n #          Zero length filename\n #\n \n-8580 END CENTRAL HEADER    06054B50 (101010256)\n-8584 Number of this disk   0000 (0)\n-8586 Central Dir Disk no   0000 (0)\n-8588 Entries in this disk  0021 (33)\n-858A Total Entries         0021 (33)\n-858C Size of Central Dir   00000B98 (2968)\n-8590 Offset to Central Dir 000079E8 (31208)\n-8594 Comment Length        0000 (0)\n+860E END CENTRAL HEADER    06054B50 (101010256)\n+8612 Number of this disk   0000 (0)\n+8614 Central Dir Disk no   0000 (0)\n+8616 Entries in this disk  0021 (33)\n+8618 Total Entries         0021 (33)\n+861A Size of Central Dir   00000B98 (2968)\n+861E Offset to Central Dir 00007A76 (31350)\n+8622 Comment Length        0000 (0)\n #\n # Error Count: 13\n # Warning Count: 79\n #\n # Done\n"}, {"source1": "org/apache/dubbo/remoting/transport/netty4/NettyChannel.java", "source2": "org/apache/dubbo/remoting/transport/netty4/NettyChannel.java", "comments": ["Ordering differences only"], "unified_diff": "@@ -1,276 +1,276 @@\n-/*\n- * Licensed to the Apache Software Foundation (ASF) under one or more\n- * contributor license agreements.  See the NOTICE file distributed with\n- * this work for additional information regarding copyright ownership.\n- * The ASF licenses this file to You under the Apache License, Version 2.0\n- * (the \"License\"); you may not use this file except in compliance with\n- * the License.  You may obtain a copy of the License at\n- *\n- *     http://www.apache.org/licenses/LICENSE-2.0\n- *\n- * Unless required by applicable law or agreed to in writing, software\n- * distributed under the License is distributed on an \"AS IS\" BASIS,\n- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n- * See the License for the specific language governing permissions and\n- * limitations under the License.\n- */\n-package org.apache.dubbo.remoting.transport.netty4;\n-\n-import org.apache.dubbo.common.URL;\n-import org.apache.dubbo.common.logger.Logger;\n-import org.apache.dubbo.common.logger.LoggerFactory;\n-import org.apache.dubbo.remoting.ChannelHandler;\n-import org.apache.dubbo.remoting.RemotingException;\n-import org.apache.dubbo.remoting.transport.AbstractChannel;\n-import org.apache.dubbo.remoting.utils.PayloadDropper;\n-\n-import io.netty.channel.Channel;\n-import io.netty.channel.ChannelFuture;\n-\n-import java.net.InetSocketAddress;\n-import java.util.Map;\n-import java.util.concurrent.ConcurrentHashMap;\n-import java.util.concurrent.ConcurrentMap;\n-import java.util.concurrent.atomic.AtomicBoolean;\n-\n-import static org.apache.dubbo.common.constants.CommonConstants.DEFAULT_TIMEOUT;\n-import static org.apache.dubbo.common.constants.CommonConstants.TIMEOUT_KEY;\n-\n-/**\n- * NettyChannel maintains the cache of channel.\n- */\n-final class NettyChannel extends AbstractChannel {\n-\n-    private static final Logger logger = LoggerFactory.getLogger(NettyChannel.class);\n-    /**\n-     * the cache for netty channel and dubbo channel\n-     */\n-    private static final ConcurrentMap<Channel, NettyChannel> CHANNEL_MAP = new ConcurrentHashMap<Channel, NettyChannel>();\n-    /**\n-     * netty channel\n-     */\n-    private final Channel channel;\n-\n-    private final Map<String, Object> attributes = new ConcurrentHashMap<String, Object>();\n-\n-    private final AtomicBoolean active = new AtomicBoolean(false);\n-\n-    /**\n-     * The constructor of NettyChannel.\n-     * It is private so NettyChannel usually create by {@link NettyChannel#getOrAddChannel(Channel, URL, ChannelHandler)}\n-     *\n-     * @param channel netty channel\n-     * @param url\n-     * @param handler dubbo handler that contain netty handler\n-     */\n-    private NettyChannel(Channel channel, URL url, ChannelHandler handler) {\n-        super(url, handler);\n-        if (channel == null) {\n-            throw new IllegalArgumentException(\"netty channel == null;\");\n-        }\n-        this.channel = channel;\n-    }\n-\n-    /**\n-     * Get dubbo channel by netty channel through channel cache.\n-     * Put netty channel into it if dubbo channel don't exist in the cache.\n-     *\n-     * @param ch      netty channel\n-     * @param url\n-     * @param handler dubbo handler that contain netty's handler\n-     * @return\n-     */\n-    static NettyChannel getOrAddChannel(Channel ch, URL url, ChannelHandler handler) {\n-        if (ch == null) {\n-            return null;\n-        }\n-        NettyChannel ret = CHANNEL_MAP.get(ch);\n-        if (ret == null) {\n-            NettyChannel nettyChannel = new NettyChannel(ch, url, handler);\n-            if (ch.isActive()) {\n-                nettyChannel.markActive(true);\n-                ret = CHANNEL_MAP.putIfAbsent(ch, nettyChannel);\n-            }\n-            if (ret == null) {\n-                ret = nettyChannel;\n-            }\n-        }\n-        return ret;\n-    }\n-\n-    /**\n-     * Remove the inactive channel.\n-     *\n-     * @param ch netty channel\n-     */\n-    static void removeChannelIfDisconnected(Channel ch) {\n-        if (ch != null && !ch.isActive()) {\n-            NettyChannel nettyChannel = CHANNEL_MAP.remove(ch);\n-            if (nettyChannel != null) {\n-                nettyChannel.markActive(false);\n-            }\n-        }\n-    }\n-\n-    static void removeChannel(Channel ch) {\n-        if (ch != null) {\n-            NettyChannel nettyChannel = CHANNEL_MAP.remove(ch);\n-            if (nettyChannel != null) {\n-                nettyChannel.markActive(false);\n-            }\n-        }\n-    }\n-\n-    @Override\n-    public InetSocketAddress getLocalAddress() {\n-        return (InetSocketAddress) channel.localAddress();\n-    }\n-\n-    @Override\n-    public InetSocketAddress getRemoteAddress() {\n-        return (InetSocketAddress) channel.remoteAddress();\n-    }\n-\n-    @Override\n-    public boolean isConnected() {\n-        return !isClosed() && active.get();\n-    }\n-\n-    public boolean isActive() {\n-        return active.get();\n-    }\n-\n-    public void markActive(boolean isActive) {\n-        active.set(isActive);\n-    }\n-\n-    /**\n-     * Send message by netty and whether to wait the completion of the send.\n-     *\n-     * @param message message that need send.\n-     * @param sent    whether to ack async-sent\n-     * @throws RemotingException throw RemotingException if wait until timeout or any exception thrown by method body that surrounded by try-catch.\n-     */\n-    @Override\n-    public void send(Object message, boolean sent) throws RemotingException {\n-        // whether the channel is closed\n-        super.send(message, sent);\n-\n-        boolean success = true;\n-        int timeout = 0;\n-        try {\n-            ChannelFuture future = channel.writeAndFlush(message);\n-            if (sent) {\n-                // wait timeout ms\n-                timeout = getUrl().getPositiveParameter(TIMEOUT_KEY, DEFAULT_TIMEOUT);\n-                success = future.await(timeout);\n-            }\n-            Throwable cause = future.cause();\n-            if (cause != null) {\n-                throw cause;\n-            }\n-        } catch (Throwable e) {\n-            removeChannelIfDisconnected(channel);\n-            throw new RemotingException(this, \"Failed to send message \" + PayloadDropper.getRequestWithoutData(message) + \" to \" + getRemoteAddress() + \", cause: \" + e.getMessage(), e);\n-        }\n-        if (!success) {\n-            throw new RemotingException(this, \"Failed to send message \" + PayloadDropper.getRequestWithoutData(message) + \" to \" + getRemoteAddress()\n-                    + \"in timeout(\" + timeout + \"ms) limit\");\n-        }\n-    }\n-\n-    @Override\n-    public void close() {\n-        try {\n-            super.close();\n-        } catch (Exception e) {\n-            logger.warn(e.getMessage(), e);\n-        }\n-        try {\n-            removeChannelIfDisconnected(channel);\n-        } catch (Exception e) {\n-            logger.warn(e.getMessage(), e);\n-        }\n-        try {\n-            attributes.clear();\n-        } catch (Exception e) {\n-            logger.warn(e.getMessage(), e);\n-        }\n-        try {\n-            if (logger.isInfoEnabled()) {\n-                logger.info(\"Close netty channel \" + channel);\n-            }\n-            channel.close();\n-        } catch (Exception e) {\n-            logger.warn(e.getMessage(), e);\n-        }\n-    }\n-\n-    @Override\n-    public boolean hasAttribute(String key) {\n-        return attributes.containsKey(key);\n-    }\n-\n-    @Override\n-    public Object getAttribute(String key) {\n-        return attributes.get(key);\n-    }\n-\n-    @Override\n-    public void setAttribute(String key, Object value) {\n-        // The null value is unallowed in the ConcurrentHashMap.\n-        if (value == null) {\n-            attributes.remove(key);\n-        } else {\n-            attributes.put(key, value);\n-        }\n-    }\n-\n-    @Override\n-    public void removeAttribute(String key) {\n-        attributes.remove(key);\n-    }\n-\n-    @Override\n-    public int hashCode() {\n-        final int prime = 31;\n-        int result = 1;\n-        result = prime * result + ((channel == null) ? 0 : channel.hashCode());\n-        return result;\n-    }\n-\n-    @Override\n-    public boolean equals(Object obj) {\n-        if (this == obj) {\n-            return true;\n-        }\n-        if (obj == null) {\n-            return false;\n-        }\n-\n-        // FIXME: a hack to make org.apache.dubbo.remoting.exchange.support.DefaultFuture.closeChannel work\n-        if (obj instanceof NettyClient) {\n-            NettyClient client = (NettyClient) obj;\n-            return channel.equals(client.getNettyChannel());\n-        }\n-\n-        if (getClass() != obj.getClass()) {\n-            return false;\n-        }\n-        NettyChannel other = (NettyChannel) obj;\n-        if (channel == null) {\n-            if (other.channel != null) {\n-                return false;\n-            }\n-        } else if (!channel.equals(other.channel)) {\n-            return false;\n-        }\n-        return true;\n-    }\n-\n-    @Override\n-    public String toString() {\n-        return \"NettyChannel [channel=\" + channel + \"]\";\n-    }\n-\n-}\n+/*\r\n+ * Licensed to the Apache Software Foundation (ASF) under one or more\r\n+ * contributor license agreements.  See the NOTICE file distributed with\r\n+ * this work for additional information regarding copyright ownership.\r\n+ * The ASF licenses this file to You under the Apache License, Version 2.0\r\n+ * (the \"License\"); you may not use this file except in compliance with\r\n+ * the License.  You may obtain a copy of the License at\r\n+ *\r\n+ *     http://www.apache.org/licenses/LICENSE-2.0\r\n+ *\r\n+ * Unless required by applicable law or agreed to in writing, software\r\n+ * distributed under the License is distributed on an \"AS IS\" BASIS,\r\n+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r\n+ * See the License for the specific language governing permissions and\r\n+ * limitations under the License.\r\n+ */\r\n+package org.apache.dubbo.remoting.transport.netty4;\r\n+\r\n+import org.apache.dubbo.common.URL;\r\n+import org.apache.dubbo.common.logger.Logger;\r\n+import org.apache.dubbo.common.logger.LoggerFactory;\r\n+import org.apache.dubbo.remoting.ChannelHandler;\r\n+import org.apache.dubbo.remoting.RemotingException;\r\n+import org.apache.dubbo.remoting.transport.AbstractChannel;\r\n+import org.apache.dubbo.remoting.utils.PayloadDropper;\r\n+\r\n+import io.netty.channel.Channel;\r\n+import io.netty.channel.ChannelFuture;\r\n+\r\n+import java.net.InetSocketAddress;\r\n+import java.util.Map;\r\n+import java.util.concurrent.ConcurrentHashMap;\r\n+import java.util.concurrent.ConcurrentMap;\r\n+import java.util.concurrent.atomic.AtomicBoolean;\r\n+\r\n+import static org.apache.dubbo.common.constants.CommonConstants.DEFAULT_TIMEOUT;\r\n+import static org.apache.dubbo.common.constants.CommonConstants.TIMEOUT_KEY;\r\n+\r\n+/**\r\n+ * NettyChannel maintains the cache of channel.\r\n+ */\r\n+final class NettyChannel extends AbstractChannel {\r\n+\r\n+    private static final Logger logger = LoggerFactory.getLogger(NettyChannel.class);\r\n+    /**\r\n+     * the cache for netty channel and dubbo channel\r\n+     */\r\n+    private static final ConcurrentMap<Channel, NettyChannel> CHANNEL_MAP = new ConcurrentHashMap<Channel, NettyChannel>();\r\n+    /**\r\n+     * netty channel\r\n+     */\r\n+    private final Channel channel;\r\n+\r\n+    private final Map<String, Object> attributes = new ConcurrentHashMap<String, Object>();\r\n+\r\n+    private final AtomicBoolean active = new AtomicBoolean(false);\r\n+\r\n+    /**\r\n+     * The constructor of NettyChannel.\r\n+     * It is private so NettyChannel usually create by {@link NettyChannel#getOrAddChannel(Channel, URL, ChannelHandler)}\r\n+     *\r\n+     * @param channel netty channel\r\n+     * @param url\r\n+     * @param handler dubbo handler that contain netty handler\r\n+     */\r\n+    private NettyChannel(Channel channel, URL url, ChannelHandler handler) {\r\n+        super(url, handler);\r\n+        if (channel == null) {\r\n+            throw new IllegalArgumentException(\"netty channel == null;\");\r\n+        }\r\n+        this.channel = channel;\r\n+    }\r\n+\r\n+    /**\r\n+     * Get dubbo channel by netty channel through channel cache.\r\n+     * Put netty channel into it if dubbo channel don't exist in the cache.\r\n+     *\r\n+     * @param ch      netty channel\r\n+     * @param url\r\n+     * @param handler dubbo handler that contain netty's handler\r\n+     * @return\r\n+     */\r\n+    static NettyChannel getOrAddChannel(Channel ch, URL url, ChannelHandler handler) {\r\n+        if (ch == null) {\r\n+            return null;\r\n+        }\r\n+        NettyChannel ret = CHANNEL_MAP.get(ch);\r\n+        if (ret == null) {\r\n+            NettyChannel nettyChannel = new NettyChannel(ch, url, handler);\r\n+            if (ch.isActive()) {\r\n+                nettyChannel.markActive(true);\r\n+                ret = CHANNEL_MAP.putIfAbsent(ch, nettyChannel);\r\n+            }\r\n+            if (ret == null) {\r\n+                ret = nettyChannel;\r\n+            }\r\n+        }\r\n+        return ret;\r\n+    }\r\n+\r\n+    /**\r\n+     * Remove the inactive channel.\r\n+     *\r\n+     * @param ch netty channel\r\n+     */\r\n+    static void removeChannelIfDisconnected(Channel ch) {\r\n+        if (ch != null && !ch.isActive()) {\r\n+            NettyChannel nettyChannel = CHANNEL_MAP.remove(ch);\r\n+            if (nettyChannel != null) {\r\n+                nettyChannel.markActive(false);\r\n+            }\r\n+        }\r\n+    }\r\n+\r\n+    static void removeChannel(Channel ch) {\r\n+        if (ch != null) {\r\n+            NettyChannel nettyChannel = CHANNEL_MAP.remove(ch);\r\n+            if (nettyChannel != null) {\r\n+                nettyChannel.markActive(false);\r\n+            }\r\n+        }\r\n+    }\r\n+\r\n+    @Override\r\n+    public InetSocketAddress getLocalAddress() {\r\n+        return (InetSocketAddress) channel.localAddress();\r\n+    }\r\n+\r\n+    @Override\r\n+    public InetSocketAddress getRemoteAddress() {\r\n+        return (InetSocketAddress) channel.remoteAddress();\r\n+    }\r\n+\r\n+    @Override\r\n+    public boolean isConnected() {\r\n+        return !isClosed() && active.get();\r\n+    }\r\n+\r\n+    public boolean isActive() {\r\n+        return active.get();\r\n+    }\r\n+\r\n+    public void markActive(boolean isActive) {\r\n+        active.set(isActive);\r\n+    }\r\n+\r\n+    /**\r\n+     * Send message by netty and whether to wait the completion of the send.\r\n+     *\r\n+     * @param message message that need send.\r\n+     * @param sent    whether to ack async-sent\r\n+     * @throws RemotingException throw RemotingException if wait until timeout or any exception thrown by method body that surrounded by try-catch.\r\n+     */\r\n+    @Override\r\n+    public void send(Object message, boolean sent) throws RemotingException {\r\n+        // whether the channel is closed\r\n+        super.send(message, sent);\r\n+\r\n+        boolean success = true;\r\n+        int timeout = 0;\r\n+        try {\r\n+            ChannelFuture future = channel.writeAndFlush(message);\r\n+            if (sent) {\r\n+                // wait timeout ms\r\n+                timeout = getUrl().getPositiveParameter(TIMEOUT_KEY, DEFAULT_TIMEOUT);\r\n+                success = future.await(timeout);\r\n+            }\r\n+            Throwable cause = future.cause();\r\n+            if (cause != null) {\r\n+                throw cause;\r\n+            }\r\n+        } catch (Throwable e) {\r\n+            removeChannelIfDisconnected(channel);\r\n+            throw new RemotingException(this, \"Failed to send message \" + PayloadDropper.getRequestWithoutData(message) + \" to \" + getRemoteAddress() + \", cause: \" + e.getMessage(), e);\r\n+        }\r\n+        if (!success) {\r\n+            throw new RemotingException(this, \"Failed to send message \" + PayloadDropper.getRequestWithoutData(message) + \" to \" + getRemoteAddress()\r\n+                    + \"in timeout(\" + timeout + \"ms) limit\");\r\n+        }\r\n+    }\r\n+\r\n+    @Override\r\n+    public void close() {\r\n+        try {\r\n+            super.close();\r\n+        } catch (Exception e) {\r\n+            logger.warn(e.getMessage(), e);\r\n+        }\r\n+        try {\r\n+            removeChannelIfDisconnected(channel);\r\n+        } catch (Exception e) {\r\n+            logger.warn(e.getMessage(), e);\r\n+        }\r\n+        try {\r\n+            attributes.clear();\r\n+        } catch (Exception e) {\r\n+            logger.warn(e.getMessage(), e);\r\n+        }\r\n+        try {\r\n+            if (logger.isInfoEnabled()) {\r\n+                logger.info(\"Close netty channel \" + channel);\r\n+            }\r\n+            channel.close();\r\n+        } catch (Exception e) {\r\n+            logger.warn(e.getMessage(), e);\r\n+        }\r\n+    }\r\n+\r\n+    @Override\r\n+    public boolean hasAttribute(String key) {\r\n+        return attributes.containsKey(key);\r\n+    }\r\n+\r\n+    @Override\r\n+    public Object getAttribute(String key) {\r\n+        return attributes.get(key);\r\n+    }\r\n+\r\n+    @Override\r\n+    public void setAttribute(String key, Object value) {\r\n+        // The null value is unallowed in the ConcurrentHashMap.\r\n+        if (value == null) {\r\n+            attributes.remove(key);\r\n+        } else {\r\n+            attributes.put(key, value);\r\n+        }\r\n+    }\r\n+\r\n+    @Override\r\n+    public void removeAttribute(String key) {\r\n+        attributes.remove(key);\r\n+    }\r\n+\r\n+    @Override\r\n+    public int hashCode() {\r\n+        final int prime = 31;\r\n+        int result = 1;\r\n+        result = prime * result + ((channel == null) ? 0 : channel.hashCode());\r\n+        return result;\r\n+    }\r\n+\r\n+    @Override\r\n+    public boolean equals(Object obj) {\r\n+        if (this == obj) {\r\n+            return true;\r\n+        }\r\n+        if (obj == null) {\r\n+            return false;\r\n+        }\r\n+\r\n+        // FIXME: a hack to make org.apache.dubbo.remoting.exchange.support.DefaultFuture.closeChannel work\r\n+        if (obj instanceof NettyClient) {\r\n+            NettyClient client = (NettyClient) obj;\r\n+            return channel.equals(client.getNettyChannel());\r\n+        }\r\n+\r\n+        if (getClass() != obj.getClass()) {\r\n+            return false;\r\n+        }\r\n+        NettyChannel other = (NettyChannel) obj;\r\n+        if (channel == null) {\r\n+            if (other.channel != null) {\r\n+                return false;\r\n+            }\r\n+        } else if (!channel.equals(other.channel)) {\r\n+            return false;\r\n+        }\r\n+        return true;\r\n+    }\r\n+\r\n+    @Override\r\n+    public String toString() {\r\n+        return \"NettyChannel [channel=\" + channel + \"]\";\r\n+    }\r\n+\r\n+}\r\n"}, {"source1": "org/apache/dubbo/remoting/transport/netty4/NettyClient.java", "source2": "org/apache/dubbo/remoting/transport/netty4/NettyClient.java", "comments": ["Ordering differences only"], "unified_diff": "@@ -1,217 +1,217 @@\n-/*\n- * Licensed to the Apache Software Foundation (ASF) under one or more\n- * contributor license agreements.  See the NOTICE file distributed with\n- * this work for additional information regarding copyright ownership.\n- * The ASF licenses this file to You under the Apache License, Version 2.0\n- * (the \"License\"); you may not use this file except in compliance with\n- * the License.  You may obtain a copy of the License at\n- *\n- *     http://www.apache.org/licenses/LICENSE-2.0\n- *\n- * Unless required by applicable law or agreed to in writing, software\n- * distributed under the License is distributed on an \"AS IS\" BASIS,\n- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n- * See the License for the specific language governing permissions and\n- * limitations under the License.\n- */\n-package org.apache.dubbo.remoting.transport.netty4;\n-\n-import org.apache.dubbo.common.URL;\n-import org.apache.dubbo.common.Version;\n-import org.apache.dubbo.common.logger.Logger;\n-import org.apache.dubbo.common.logger.LoggerFactory;\n-import org.apache.dubbo.common.utils.ConfigUtils;\n-import org.apache.dubbo.common.utils.NetUtils;\n-import org.apache.dubbo.remoting.ChannelHandler;\n-import org.apache.dubbo.remoting.Constants;\n-import org.apache.dubbo.remoting.RemotingException;\n-import org.apache.dubbo.remoting.transport.AbstractClient;\n-import org.apache.dubbo.remoting.utils.UrlUtils;\n-\n-import io.netty.bootstrap.Bootstrap;\n-import io.netty.buffer.PooledByteBufAllocator;\n-import io.netty.channel.Channel;\n-import io.netty.channel.ChannelFuture;\n-import io.netty.channel.ChannelInitializer;\n-import io.netty.channel.ChannelOption;\n-import io.netty.channel.EventLoopGroup;\n-import io.netty.channel.socket.SocketChannel;\n-import io.netty.handler.proxy.Socks5ProxyHandler;\n-import io.netty.handler.timeout.IdleStateHandler;\n-\n-import java.net.InetSocketAddress;\n-\n-import static java.util.concurrent.TimeUnit.MILLISECONDS;\n-import static org.apache.dubbo.common.constants.CommonConstants.SSL_ENABLED_KEY;\n-import static org.apache.dubbo.remoting.transport.netty4.NettyEventLoopFactory.eventLoopGroup;\n-import static org.apache.dubbo.remoting.transport.netty4.NettyEventLoopFactory.socketChannelClass;\n-\n-/**\n- * NettyClient.\n- */\n-public class NettyClient extends AbstractClient {\n-\n-    private static final Logger logger = LoggerFactory.getLogger(NettyClient.class);\n-    /**\n-     * netty client bootstrap\n-     */\n-    private static final EventLoopGroup NIO_EVENT_LOOP_GROUP = eventLoopGroup(Constants.DEFAULT_IO_THREADS, \"NettyClientWorker\");\n-\n-    private static final String SOCKS_PROXY_HOST = \"socksProxyHost\";\n-\n-    private static final String SOCKS_PROXY_PORT = \"socksProxyPort\";\n-\n-    private static final String DEFAULT_SOCKS_PROXY_PORT = \"1080\";\n-\n-    private Bootstrap bootstrap;\n-\n-    /**\n-     * current channel. Each successful invocation of {@link NettyClient#doConnect()} will\n-     * replace this with new channel and close old channel.\n-     * <b>volatile, please copy reference to use.</b>\n-     */\n-    private volatile Channel channel;\n-\n-    /**\n-     * The constructor of NettyClient.\n-     * It wil init and start netty.\n-     */\n-    public NettyClient(final URL url, final ChannelHandler handler) throws RemotingException {\n-    \t// you can customize name and type of client thread pool by THREAD_NAME_KEY and THREADPOOL_KEY in CommonConstants.\n-    \t// the handler will be wrapped: MultiMessageHandler->HeartbeatHandler->handler\n-    \tsuper(url, wrapChannelHandler(url, handler));\n-    }\n-\n-    /**\n-     * Init bootstrap\n-     *\n-     * @throws Throwable\n-     */\n-    @Override\n-    protected void doOpen() throws Throwable {\n-        final NettyClientHandler nettyClientHandler = new NettyClientHandler(getUrl(), this);\n-        bootstrap = new Bootstrap();\n-        bootstrap.group(NIO_EVENT_LOOP_GROUP)\n-                .option(ChannelOption.SO_KEEPALIVE, true)\n-                .option(ChannelOption.TCP_NODELAY, true)\n-                .option(ChannelOption.ALLOCATOR, PooledByteBufAllocator.DEFAULT)\n-                //.option(ChannelOption.CONNECT_TIMEOUT_MILLIS, getTimeout())\n-                .channel(socketChannelClass());\n-\n-        bootstrap.option(ChannelOption.CONNECT_TIMEOUT_MILLIS, Math.max(3000, getConnectTimeout()));\n-        bootstrap.handler(new ChannelInitializer<SocketChannel>() {\n-\n-            @Override\n-            protected void initChannel(SocketChannel ch) throws Exception {\n-                int heartbeatInterval = UrlUtils.getHeartbeat(getUrl());\n-\n-                if (getUrl().getParameter(SSL_ENABLED_KEY, false)) {\n-                    ch.pipeline().addLast(\"negotiation\", SslHandlerInitializer.sslClientHandler(getUrl(), nettyClientHandler));\n-                }\n-\n-                NettyCodecAdapter adapter = new NettyCodecAdapter(getCodec(), getUrl(), NettyClient.this);\n-                ch.pipeline()//.addLast(\"logging\",new LoggingHandler(LogLevel.INFO))//for debug\n-                        .addLast(\"decoder\", adapter.getDecoder())\n-                        .addLast(\"encoder\", adapter.getEncoder())\n-                        .addLast(\"client-idle-handler\", new IdleStateHandler(heartbeatInterval, 0, 0, MILLISECONDS))\n-                        .addLast(\"handler\", nettyClientHandler);\n-\n-                String socksProxyHost = ConfigUtils.getProperty(SOCKS_PROXY_HOST);\n-                if(socksProxyHost != null) {\n-                    int socksProxyPort = Integer.parseInt(ConfigUtils.getProperty(SOCKS_PROXY_PORT, DEFAULT_SOCKS_PROXY_PORT));\n-                    Socks5ProxyHandler socks5ProxyHandler = new Socks5ProxyHandler(new InetSocketAddress(socksProxyHost, socksProxyPort));\n-                    ch.pipeline().addFirst(socks5ProxyHandler);\n-                }\n-            }\n-        });\n-    }\n-\n-    @Override\n-    protected void doConnect() throws Throwable {\n-        long start = System.currentTimeMillis();\n-        ChannelFuture future = bootstrap.connect(getConnectAddress());\n-        try {\n-            boolean ret = future.awaitUninterruptibly(getConnectTimeout(), MILLISECONDS);\n-\n-            if (ret && future.isSuccess()) {\n-                Channel newChannel = future.channel();\n-                try {\n-                    // Close old channel\n-                    // copy reference\n-                    Channel oldChannel = NettyClient.this.channel;\n-                    if (oldChannel != null) {\n-                        try {\n-                            if (logger.isInfoEnabled()) {\n-                                logger.info(\"Close old netty channel \" + oldChannel + \" on create new netty channel \" + newChannel);\n-                            }\n-                            oldChannel.close();\n-                        } finally {\n-                            NettyChannel.removeChannelIfDisconnected(oldChannel);\n-                        }\n-                    }\n-                } finally {\n-                    if (NettyClient.this.isClosed()) {\n-                        try {\n-                            if (logger.isInfoEnabled()) {\n-                                logger.info(\"Close new netty channel \" + newChannel + \", because the client closed.\");\n-                            }\n-                            newChannel.close();\n-                        } finally {\n-                            NettyClient.this.channel = null;\n-                            NettyChannel.removeChannelIfDisconnected(newChannel);\n-                        }\n-                    } else {\n-                        NettyClient.this.channel = newChannel;\n-                    }\n-                }\n-            } else if (future.cause() != null) {\n-                throw new RemotingException(this, \"client(url: \" + getUrl() + \") failed to connect to server \"\n-                        + getRemoteAddress() + \", error message is:\" + future.cause().getMessage(), future.cause());\n-            } else {\n-                throw new RemotingException(this, \"client(url: \" + getUrl() + \") failed to connect to server \"\n-                        + getRemoteAddress() + \" client-side timeout \"\n-                        + getConnectTimeout() + \"ms (elapsed: \" + (System.currentTimeMillis() - start) + \"ms) from netty client \"\n-                        + NetUtils.getLocalHost() + \" using dubbo version \" + Version.getVersion());\n-            }\n-        } finally {\n-            // just add new valid channel to NettyChannel's cache\n-            if (!isConnected()) {\n-                //future.cancel(true);\n-            }\n-        }\n-    }\n-\n-    @Override\n-    protected void doDisConnect() throws Throwable {\n-        try {\n-            NettyChannel.removeChannelIfDisconnected(channel);\n-        } catch (Throwable t) {\n-            logger.warn(t.getMessage());\n-        }\n-    }\n-\n-    @Override\n-    protected void doClose() throws Throwable {\n-        // can't shutdown nioEventLoopGroup because the method will be invoked when closing one channel but not a client,\n-        // but when and how to close the nioEventLoopGroup ?\n-        // nioEventLoopGroup.shutdownGracefully();\n-    }\n-\n-    @Override\n-    protected org.apache.dubbo.remoting.Channel getChannel() {\n-        Channel c = channel;\n-        if (c == null) {\n-            return null;\n-        }\n-        return NettyChannel.getOrAddChannel(c, getUrl(), this);\n-    }\n-\n-    Channel getNettyChannel() {\n-        return channel;\n-    }\n-\n-    @Override\n-    public boolean canHandleIdle() {\n-        return true;\n-    }\n-}\n+/*\r\n+ * Licensed to the Apache Software Foundation (ASF) under one or more\r\n+ * contributor license agreements.  See the NOTICE file distributed with\r\n+ * this work for additional information regarding copyright ownership.\r\n+ * The ASF licenses this file to You under the Apache License, Version 2.0\r\n+ * (the \"License\"); you may not use this file except in compliance with\r\n+ * the License.  You may obtain a copy of the License at\r\n+ *\r\n+ *     http://www.apache.org/licenses/LICENSE-2.0\r\n+ *\r\n+ * Unless required by applicable law or agreed to in writing, software\r\n+ * distributed under the License is distributed on an \"AS IS\" BASIS,\r\n+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r\n+ * See the License for the specific language governing permissions and\r\n+ * limitations under the License.\r\n+ */\r\n+package org.apache.dubbo.remoting.transport.netty4;\r\n+\r\n+import org.apache.dubbo.common.URL;\r\n+import org.apache.dubbo.common.Version;\r\n+import org.apache.dubbo.common.logger.Logger;\r\n+import org.apache.dubbo.common.logger.LoggerFactory;\r\n+import org.apache.dubbo.common.utils.ConfigUtils;\r\n+import org.apache.dubbo.common.utils.NetUtils;\r\n+import org.apache.dubbo.remoting.ChannelHandler;\r\n+import org.apache.dubbo.remoting.Constants;\r\n+import org.apache.dubbo.remoting.RemotingException;\r\n+import org.apache.dubbo.remoting.transport.AbstractClient;\r\n+import org.apache.dubbo.remoting.utils.UrlUtils;\r\n+\r\n+import io.netty.bootstrap.Bootstrap;\r\n+import io.netty.buffer.PooledByteBufAllocator;\r\n+import io.netty.channel.Channel;\r\n+import io.netty.channel.ChannelFuture;\r\n+import io.netty.channel.ChannelInitializer;\r\n+import io.netty.channel.ChannelOption;\r\n+import io.netty.channel.EventLoopGroup;\r\n+import io.netty.channel.socket.SocketChannel;\r\n+import io.netty.handler.proxy.Socks5ProxyHandler;\r\n+import io.netty.handler.timeout.IdleStateHandler;\r\n+\r\n+import java.net.InetSocketAddress;\r\n+\r\n+import static java.util.concurrent.TimeUnit.MILLISECONDS;\r\n+import static org.apache.dubbo.common.constants.CommonConstants.SSL_ENABLED_KEY;\r\n+import static org.apache.dubbo.remoting.transport.netty4.NettyEventLoopFactory.eventLoopGroup;\r\n+import static org.apache.dubbo.remoting.transport.netty4.NettyEventLoopFactory.socketChannelClass;\r\n+\r\n+/**\r\n+ * NettyClient.\r\n+ */\r\n+public class NettyClient extends AbstractClient {\r\n+\r\n+    private static final Logger logger = LoggerFactory.getLogger(NettyClient.class);\r\n+    /**\r\n+     * netty client bootstrap\r\n+     */\r\n+    private static final EventLoopGroup NIO_EVENT_LOOP_GROUP = eventLoopGroup(Constants.DEFAULT_IO_THREADS, \"NettyClientWorker\");\r\n+\r\n+    private static final String SOCKS_PROXY_HOST = \"socksProxyHost\";\r\n+\r\n+    private static final String SOCKS_PROXY_PORT = \"socksProxyPort\";\r\n+\r\n+    private static final String DEFAULT_SOCKS_PROXY_PORT = \"1080\";\r\n+\r\n+    private Bootstrap bootstrap;\r\n+\r\n+    /**\r\n+     * current channel. Each successful invocation of {@link NettyClient#doConnect()} will\r\n+     * replace this with new channel and close old channel.\r\n+     * <b>volatile, please copy reference to use.</b>\r\n+     */\r\n+    private volatile Channel channel;\r\n+\r\n+    /**\r\n+     * The constructor of NettyClient.\r\n+     * It wil init and start netty.\r\n+     */\r\n+    public NettyClient(final URL url, final ChannelHandler handler) throws RemotingException {\r\n+    \t// you can customize name and type of client thread pool by THREAD_NAME_KEY and THREADPOOL_KEY in CommonConstants.\r\n+    \t// the handler will be wrapped: MultiMessageHandler->HeartbeatHandler->handler\r\n+    \tsuper(url, wrapChannelHandler(url, handler));\r\n+    }\r\n+\r\n+    /**\r\n+     * Init bootstrap\r\n+     *\r\n+     * @throws Throwable\r\n+     */\r\n+    @Override\r\n+    protected void doOpen() throws Throwable {\r\n+        final NettyClientHandler nettyClientHandler = new NettyClientHandler(getUrl(), this);\r\n+        bootstrap = new Bootstrap();\r\n+        bootstrap.group(NIO_EVENT_LOOP_GROUP)\r\n+                .option(ChannelOption.SO_KEEPALIVE, true)\r\n+                .option(ChannelOption.TCP_NODELAY, true)\r\n+                .option(ChannelOption.ALLOCATOR, PooledByteBufAllocator.DEFAULT)\r\n+                //.option(ChannelOption.CONNECT_TIMEOUT_MILLIS, getTimeout())\r\n+                .channel(socketChannelClass());\r\n+\r\n+        bootstrap.option(ChannelOption.CONNECT_TIMEOUT_MILLIS, Math.max(3000, getConnectTimeout()));\r\n+        bootstrap.handler(new ChannelInitializer<SocketChannel>() {\r\n+\r\n+            @Override\r\n+            protected void initChannel(SocketChannel ch) throws Exception {\r\n+                int heartbeatInterval = UrlUtils.getHeartbeat(getUrl());\r\n+\r\n+                if (getUrl().getParameter(SSL_ENABLED_KEY, false)) {\r\n+                    ch.pipeline().addLast(\"negotiation\", SslHandlerInitializer.sslClientHandler(getUrl(), nettyClientHandler));\r\n+                }\r\n+\r\n+                NettyCodecAdapter adapter = new NettyCodecAdapter(getCodec(), getUrl(), NettyClient.this);\r\n+                ch.pipeline()//.addLast(\"logging\",new LoggingHandler(LogLevel.INFO))//for debug\r\n+                        .addLast(\"decoder\", adapter.getDecoder())\r\n+                        .addLast(\"encoder\", adapter.getEncoder())\r\n+                        .addLast(\"client-idle-handler\", new IdleStateHandler(heartbeatInterval, 0, 0, MILLISECONDS))\r\n+                        .addLast(\"handler\", nettyClientHandler);\r\n+\r\n+                String socksProxyHost = ConfigUtils.getProperty(SOCKS_PROXY_HOST);\r\n+                if(socksProxyHost != null) {\r\n+                    int socksProxyPort = Integer.parseInt(ConfigUtils.getProperty(SOCKS_PROXY_PORT, DEFAULT_SOCKS_PROXY_PORT));\r\n+                    Socks5ProxyHandler socks5ProxyHandler = new Socks5ProxyHandler(new InetSocketAddress(socksProxyHost, socksProxyPort));\r\n+                    ch.pipeline().addFirst(socks5ProxyHandler);\r\n+                }\r\n+            }\r\n+        });\r\n+    }\r\n+\r\n+    @Override\r\n+    protected void doConnect() throws Throwable {\r\n+        long start = System.currentTimeMillis();\r\n+        ChannelFuture future = bootstrap.connect(getConnectAddress());\r\n+        try {\r\n+            boolean ret = future.awaitUninterruptibly(getConnectTimeout(), MILLISECONDS);\r\n+\r\n+            if (ret && future.isSuccess()) {\r\n+                Channel newChannel = future.channel();\r\n+                try {\r\n+                    // Close old channel\r\n+                    // copy reference\r\n+                    Channel oldChannel = NettyClient.this.channel;\r\n+                    if (oldChannel != null) {\r\n+                        try {\r\n+                            if (logger.isInfoEnabled()) {\r\n+                                logger.info(\"Close old netty channel \" + oldChannel + \" on create new netty channel \" + newChannel);\r\n+                            }\r\n+                            oldChannel.close();\r\n+                        } finally {\r\n+                            NettyChannel.removeChannelIfDisconnected(oldChannel);\r\n+                        }\r\n+                    }\r\n+                } finally {\r\n+                    if (NettyClient.this.isClosed()) {\r\n+                        try {\r\n+                            if (logger.isInfoEnabled()) {\r\n+                                logger.info(\"Close new netty channel \" + newChannel + \", because the client closed.\");\r\n+                            }\r\n+                            newChannel.close();\r\n+                        } finally {\r\n+                            NettyClient.this.channel = null;\r\n+                            NettyChannel.removeChannelIfDisconnected(newChannel);\r\n+                        }\r\n+                    } else {\r\n+                        NettyClient.this.channel = newChannel;\r\n+                    }\r\n+                }\r\n+            } else if (future.cause() != null) {\r\n+                throw new RemotingException(this, \"client(url: \" + getUrl() + \") failed to connect to server \"\r\n+                        + getRemoteAddress() + \", error message is:\" + future.cause().getMessage(), future.cause());\r\n+            } else {\r\n+                throw new RemotingException(this, \"client(url: \" + getUrl() + \") failed to connect to server \"\r\n+                        + getRemoteAddress() + \" client-side timeout \"\r\n+                        + getConnectTimeout() + \"ms (elapsed: \" + (System.currentTimeMillis() - start) + \"ms) from netty client \"\r\n+                        + NetUtils.getLocalHost() + \" using dubbo version \" + Version.getVersion());\r\n+            }\r\n+        } finally {\r\n+            // just add new valid channel to NettyChannel's cache\r\n+            if (!isConnected()) {\r\n+                //future.cancel(true);\r\n+            }\r\n+        }\r\n+    }\r\n+\r\n+    @Override\r\n+    protected void doDisConnect() throws Throwable {\r\n+        try {\r\n+            NettyChannel.removeChannelIfDisconnected(channel);\r\n+        } catch (Throwable t) {\r\n+            logger.warn(t.getMessage());\r\n+        }\r\n+    }\r\n+\r\n+    @Override\r\n+    protected void doClose() throws Throwable {\r\n+        // can't shutdown nioEventLoopGroup because the method will be invoked when closing one channel but not a client,\r\n+        // but when and how to close the nioEventLoopGroup ?\r\n+        // nioEventLoopGroup.shutdownGracefully();\r\n+    }\r\n+\r\n+    @Override\r\n+    protected org.apache.dubbo.remoting.Channel getChannel() {\r\n+        Channel c = channel;\r\n+        if (c == null) {\r\n+            return null;\r\n+        }\r\n+        return NettyChannel.getOrAddChannel(c, getUrl(), this);\r\n+    }\r\n+\r\n+    Channel getNettyChannel() {\r\n+        return channel;\r\n+    }\r\n+\r\n+    @Override\r\n+    public boolean canHandleIdle() {\r\n+        return true;\r\n+    }\r\n+}\r\n"}, {"source1": "org/apache/dubbo/remoting/transport/netty4/NettyClientHandler.java", "source2": "org/apache/dubbo/remoting/transport/netty4/NettyClientHandler.java", "comments": ["Ordering differences only"], "unified_diff": "@@ -1,161 +1,161 @@\n-/*\n- * Licensed to the Apache Software Foundation (ASF) under one or more\n- * contributor license agreements.  See the NOTICE file distributed with\n- * this work for additional information regarding copyright ownership.\n- * The ASF licenses this file to You under the Apache License, Version 2.0\n- * (the \"License\"); you may not use this file except in compliance with\n- * the License.  You may obtain a copy of the License at\n- *\n- *     http://www.apache.org/licenses/LICENSE-2.0\n- *\n- * Unless required by applicable law or agreed to in writing, software\n- * distributed under the License is distributed on an \"AS IS\" BASIS,\n- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n- * See the License for the specific language governing permissions and\n- * limitations under the License.\n- */\n-package org.apache.dubbo.remoting.transport.netty4;\n-\n-import org.apache.dubbo.common.URL;\n-import org.apache.dubbo.common.Version;\n-import org.apache.dubbo.common.logger.Logger;\n-import org.apache.dubbo.common.logger.LoggerFactory;\n-import org.apache.dubbo.common.utils.StringUtils;\n-import org.apache.dubbo.remoting.ChannelHandler;\n-import org.apache.dubbo.remoting.exchange.Request;\n-import org.apache.dubbo.remoting.exchange.Response;\n-\n-import io.netty.channel.ChannelDuplexHandler;\n-import io.netty.channel.ChannelHandlerContext;\n-import io.netty.channel.ChannelPromise;\n-import io.netty.handler.timeout.IdleStateEvent;\n-\n-import static org.apache.dubbo.common.constants.CommonConstants.HEARTBEAT_EVENT;\n-\n-/**\n- * NettyClientHandler\n- */\n-@io.netty.channel.ChannelHandler.Sharable\n-public class NettyClientHandler extends ChannelDuplexHandler {\n-    private static final Logger logger = LoggerFactory.getLogger(NettyClientHandler.class);\n-\n-    private final URL url;\n-\n-    private final ChannelHandler handler;\n-\n-    public NettyClientHandler(URL url, ChannelHandler handler) {\n-        if (url == null) {\n-            throw new IllegalArgumentException(\"url == null\");\n-        }\n-        if (handler == null) {\n-            throw new IllegalArgumentException(\"handler == null\");\n-        }\n-        this.url = url;\n-        this.handler = handler;\n-    }\n-\n-    @Override\n-    public void channelActive(ChannelHandlerContext ctx) throws Exception {\n-        NettyChannel channel = NettyChannel.getOrAddChannel(ctx.channel(), url, handler);\n-        handler.connected(channel);\n-        if (logger.isInfoEnabled()) {\n-            logger.info(\"The connection of \" + channel.getLocalAddress() + \" -> \" + channel.getRemoteAddress() + \" is established.\");\n-        }\n-    }\n-\n-    @Override\n-    public void channelInactive(ChannelHandlerContext ctx) throws Exception {\n-        NettyChannel channel = NettyChannel.getOrAddChannel(ctx.channel(), url, handler);\n-        try {\n-            handler.disconnected(channel);\n-        } finally {\n-            NettyChannel.removeChannel(ctx.channel());\n-        }\n-\n-        if (logger.isInfoEnabled()) {\n-            logger.info(\"The connection of \" + channel.getLocalAddress() + \" -> \" + channel.getRemoteAddress() + \" is disconnected.\");\n-        }\n-    }\n-\n-    @Override\n-    public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {\n-        NettyChannel channel = NettyChannel.getOrAddChannel(ctx.channel(), url, handler);\n-        handler.received(channel, msg);\n-    }\n-\n-    @Override\n-    public void write(ChannelHandlerContext ctx, Object msg, ChannelPromise promise) throws Exception {\n-        super.write(ctx, msg, promise);\n-        final NettyChannel channel = NettyChannel.getOrAddChannel(ctx.channel(), url, handler);\n-        final boolean isRequest = msg instanceof Request;\n-\n-        // We add listeners to make sure our out bound event is correct.\n-        // If our out bound event has an error (in most cases the encoder fails),\n-        // we need to have the request return directly instead of blocking the invoke process.\n-        promise.addListener(future -> {\n-            if (future.isSuccess()) {\n-                // if our future is success, mark the future to sent.\n-                handler.sent(channel, msg);\n-                return;\n-            }\n-\n-            Throwable t = future.cause();\n-            if (t != null && isRequest) {\n-                Request request = (Request) msg;\n-                Response response = buildErrorResponse(request, t);\n-                handler.received(channel, response);\n-            }\n-        });\n-    }\n-\n-    @Override\n-    public void userEventTriggered(ChannelHandlerContext ctx, Object evt) throws Exception {\n-        // send heartbeat when read idle.\n-        if (evt instanceof IdleStateEvent) {\n-            try {\n-                NettyChannel channel = NettyChannel.getOrAddChannel(ctx.channel(), url, handler);\n-                if (logger.isDebugEnabled()) {\n-                    logger.debug(\"IdleStateEvent triggered, send heartbeat to channel \" + channel);\n-                }\n-                Request req = new Request();\n-                req.setVersion(Version.getProtocolVersion());\n-                req.setTwoWay(true);\n-                req.setEvent(HEARTBEAT_EVENT);\n-                channel.send(req);\n-            } finally {\n-                NettyChannel.removeChannelIfDisconnected(ctx.channel());\n-            }\n-        } else {\n-            super.userEventTriggered(ctx, evt);\n-        }\n-    }\n-\n-    @Override\n-    public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause)\n-            throws Exception {\n-        NettyChannel channel = NettyChannel.getOrAddChannel(ctx.channel(), url, handler);\n-        try {\n-            handler.caught(channel, cause);\n-        } finally {\n-            NettyChannel.removeChannelIfDisconnected(ctx.channel());\n-        }\n-    }\n-\n-    public void handshakeCompleted(SslHandlerInitializer.HandshakeCompletionEvent evt) {\n-        // TODO\n-    }\n-\n-    /**\n-     * build a bad request's response\n-     *\n-     * @param request the request\n-     * @param t       the throwable. In most cases, serialization fails.\n-     * @return the response\n-     */\n-    private static Response buildErrorResponse(Request request, Throwable t) {\n-        Response response = new Response(request.getId(), request.getVersion());\n-        response.setStatus(Response.BAD_REQUEST);\n-        response.setErrorMessage(StringUtils.toString(t));\n-        return response;\n-    }\n-}\n+/*\r\n+ * Licensed to the Apache Software Foundation (ASF) under one or more\r\n+ * contributor license agreements.  See the NOTICE file distributed with\r\n+ * this work for additional information regarding copyright ownership.\r\n+ * The ASF licenses this file to You under the Apache License, Version 2.0\r\n+ * (the \"License\"); you may not use this file except in compliance with\r\n+ * the License.  You may obtain a copy of the License at\r\n+ *\r\n+ *     http://www.apache.org/licenses/LICENSE-2.0\r\n+ *\r\n+ * Unless required by applicable law or agreed to in writing, software\r\n+ * distributed under the License is distributed on an \"AS IS\" BASIS,\r\n+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r\n+ * See the License for the specific language governing permissions and\r\n+ * limitations under the License.\r\n+ */\r\n+package org.apache.dubbo.remoting.transport.netty4;\r\n+\r\n+import org.apache.dubbo.common.URL;\r\n+import org.apache.dubbo.common.Version;\r\n+import org.apache.dubbo.common.logger.Logger;\r\n+import org.apache.dubbo.common.logger.LoggerFactory;\r\n+import org.apache.dubbo.common.utils.StringUtils;\r\n+import org.apache.dubbo.remoting.ChannelHandler;\r\n+import org.apache.dubbo.remoting.exchange.Request;\r\n+import org.apache.dubbo.remoting.exchange.Response;\r\n+\r\n+import io.netty.channel.ChannelDuplexHandler;\r\n+import io.netty.channel.ChannelHandlerContext;\r\n+import io.netty.channel.ChannelPromise;\r\n+import io.netty.handler.timeout.IdleStateEvent;\r\n+\r\n+import static org.apache.dubbo.common.constants.CommonConstants.HEARTBEAT_EVENT;\r\n+\r\n+/**\r\n+ * NettyClientHandler\r\n+ */\r\n+@io.netty.channel.ChannelHandler.Sharable\r\n+public class NettyClientHandler extends ChannelDuplexHandler {\r\n+    private static final Logger logger = LoggerFactory.getLogger(NettyClientHandler.class);\r\n+\r\n+    private final URL url;\r\n+\r\n+    private final ChannelHandler handler;\r\n+\r\n+    public NettyClientHandler(URL url, ChannelHandler handler) {\r\n+        if (url == null) {\r\n+            throw new IllegalArgumentException(\"url == null\");\r\n+        }\r\n+        if (handler == null) {\r\n+            throw new IllegalArgumentException(\"handler == null\");\r\n+        }\r\n+        this.url = url;\r\n+        this.handler = handler;\r\n+    }\r\n+\r\n+    @Override\r\n+    public void channelActive(ChannelHandlerContext ctx) throws Exception {\r\n+        NettyChannel channel = NettyChannel.getOrAddChannel(ctx.channel(), url, handler);\r\n+        handler.connected(channel);\r\n+        if (logger.isInfoEnabled()) {\r\n+            logger.info(\"The connection of \" + channel.getLocalAddress() + \" -> \" + channel.getRemoteAddress() + \" is established.\");\r\n+        }\r\n+    }\r\n+\r\n+    @Override\r\n+    public void channelInactive(ChannelHandlerContext ctx) throws Exception {\r\n+        NettyChannel channel = NettyChannel.getOrAddChannel(ctx.channel(), url, handler);\r\n+        try {\r\n+            handler.disconnected(channel);\r\n+        } finally {\r\n+            NettyChannel.removeChannel(ctx.channel());\r\n+        }\r\n+\r\n+        if (logger.isInfoEnabled()) {\r\n+            logger.info(\"The connection of \" + channel.getLocalAddress() + \" -> \" + channel.getRemoteAddress() + \" is disconnected.\");\r\n+        }\r\n+    }\r\n+\r\n+    @Override\r\n+    public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {\r\n+        NettyChannel channel = NettyChannel.getOrAddChannel(ctx.channel(), url, handler);\r\n+        handler.received(channel, msg);\r\n+    }\r\n+\r\n+    @Override\r\n+    public void write(ChannelHandlerContext ctx, Object msg, ChannelPromise promise) throws Exception {\r\n+        super.write(ctx, msg, promise);\r\n+        final NettyChannel channel = NettyChannel.getOrAddChannel(ctx.channel(), url, handler);\r\n+        final boolean isRequest = msg instanceof Request;\r\n+\r\n+        // We add listeners to make sure our out bound event is correct.\r\n+        // If our out bound event has an error (in most cases the encoder fails),\r\n+        // we need to have the request return directly instead of blocking the invoke process.\r\n+        promise.addListener(future -> {\r\n+            if (future.isSuccess()) {\r\n+                // if our future is success, mark the future to sent.\r\n+                handler.sent(channel, msg);\r\n+                return;\r\n+            }\r\n+\r\n+            Throwable t = future.cause();\r\n+            if (t != null && isRequest) {\r\n+                Request request = (Request) msg;\r\n+                Response response = buildErrorResponse(request, t);\r\n+                handler.received(channel, response);\r\n+            }\r\n+        });\r\n+    }\r\n+\r\n+    @Override\r\n+    public void userEventTriggered(ChannelHandlerContext ctx, Object evt) throws Exception {\r\n+        // send heartbeat when read idle.\r\n+        if (evt instanceof IdleStateEvent) {\r\n+            try {\r\n+                NettyChannel channel = NettyChannel.getOrAddChannel(ctx.channel(), url, handler);\r\n+                if (logger.isDebugEnabled()) {\r\n+                    logger.debug(\"IdleStateEvent triggered, send heartbeat to channel \" + channel);\r\n+                }\r\n+                Request req = new Request();\r\n+                req.setVersion(Version.getProtocolVersion());\r\n+                req.setTwoWay(true);\r\n+                req.setEvent(HEARTBEAT_EVENT);\r\n+                channel.send(req);\r\n+            } finally {\r\n+                NettyChannel.removeChannelIfDisconnected(ctx.channel());\r\n+            }\r\n+        } else {\r\n+            super.userEventTriggered(ctx, evt);\r\n+        }\r\n+    }\r\n+\r\n+    @Override\r\n+    public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause)\r\n+            throws Exception {\r\n+        NettyChannel channel = NettyChannel.getOrAddChannel(ctx.channel(), url, handler);\r\n+        try {\r\n+            handler.caught(channel, cause);\r\n+        } finally {\r\n+            NettyChannel.removeChannelIfDisconnected(ctx.channel());\r\n+        }\r\n+    }\r\n+\r\n+    public void handshakeCompleted(SslHandlerInitializer.HandshakeCompletionEvent evt) {\r\n+        // TODO\r\n+    }\r\n+\r\n+    /**\r\n+     * build a bad request's response\r\n+     *\r\n+     * @param request the request\r\n+     * @param t       the throwable. In most cases, serialization fails.\r\n+     * @return the response\r\n+     */\r\n+    private static Response buildErrorResponse(Request request, Throwable t) {\r\n+        Response response = new Response(request.getId(), request.getVersion());\r\n+        response.setStatus(Response.BAD_REQUEST);\r\n+        response.setErrorMessage(StringUtils.toString(t));\r\n+        return response;\r\n+    }\r\n+}\r\n"}, {"source1": "org/apache/dubbo/remoting/transport/netty4/NettyCodecAdapter.java", "source2": "org/apache/dubbo/remoting/transport/netty4/NettyCodecAdapter.java", "comments": ["Ordering differences only"], "unified_diff": "@@ -1,101 +1,101 @@\n-/*\n- * Licensed to the Apache Software Foundation (ASF) under one or more\n- * contributor license agreements.  See the NOTICE file distributed with\n- * this work for additional information regarding copyright ownership.\n- * The ASF licenses this file to You under the Apache License, Version 2.0\n- * (the \"License\"); you may not use this file except in compliance with\n- * the License.  You may obtain a copy of the License at\n- *\n- *     http://www.apache.org/licenses/LICENSE-2.0\n- *\n- * Unless required by applicable law or agreed to in writing, software\n- * distributed under the License is distributed on an \"AS IS\" BASIS,\n- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n- * See the License for the specific language governing permissions and\n- * limitations under the License.\n- */\n-package org.apache.dubbo.remoting.transport.netty4;\n-\n-import org.apache.dubbo.common.URL;\n-import org.apache.dubbo.remoting.Codec2;\n-import org.apache.dubbo.remoting.buffer.ChannelBuffer;\n-\n-import io.netty.buffer.ByteBuf;\n-import io.netty.channel.Channel;\n-import io.netty.channel.ChannelHandler;\n-import io.netty.channel.ChannelHandlerContext;\n-import io.netty.handler.codec.ByteToMessageDecoder;\n-import io.netty.handler.codec.MessageToByteEncoder;\n-\n-import java.io.IOException;\n-import java.util.List;\n-\n-/**\n- * NettyCodecAdapter.\n- */\n-final public class NettyCodecAdapter {\n-\n-    private final ChannelHandler encoder = new InternalEncoder();\n-\n-    private final ChannelHandler decoder = new InternalDecoder();\n-\n-    private final Codec2 codec;\n-\n-    private final URL url;\n-\n-    private final org.apache.dubbo.remoting.ChannelHandler handler;\n-\n-    public NettyCodecAdapter(Codec2 codec, URL url, org.apache.dubbo.remoting.ChannelHandler handler) {\n-        this.codec = codec;\n-        this.url = url;\n-        this.handler = handler;\n-    }\n-\n-    public ChannelHandler getEncoder() {\n-        return encoder;\n-    }\n-\n-    public ChannelHandler getDecoder() {\n-        return decoder;\n-    }\n-\n-    private class InternalEncoder extends MessageToByteEncoder {\n-\n-        @Override\n-        protected void encode(ChannelHandlerContext ctx, Object msg, ByteBuf out) throws Exception {\n-            org.apache.dubbo.remoting.buffer.ChannelBuffer buffer = new NettyBackedChannelBuffer(out);\n-            Channel ch = ctx.channel();\n-            NettyChannel channel = NettyChannel.getOrAddChannel(ch, url, handler);\n-            codec.encode(channel, buffer, msg);\n-        }\n-    }\n-\n-    private class InternalDecoder extends ByteToMessageDecoder {\n-\n-        @Override\n-        protected void decode(ChannelHandlerContext ctx, ByteBuf input, List<Object> out) throws Exception {\n-\n-            ChannelBuffer message = new NettyBackedChannelBuffer(input);\n-\n-            NettyChannel channel = NettyChannel.getOrAddChannel(ctx.channel(), url, handler);\n-\n-            // decode object.\n-            do {\n-                int saveReaderIndex = message.readerIndex();\n-                Object msg = codec.decode(channel, message);\n-                if (msg == Codec2.DecodeResult.NEED_MORE_INPUT) {\n-                    message.readerIndex(saveReaderIndex);\n-                    break;\n-                } else {\n-                    //is it possible to go here ?\n-                    if (saveReaderIndex == message.readerIndex()) {\n-                        throw new IOException(\"Decode without read data.\");\n-                    }\n-                    if (msg != null) {\n-                        out.add(msg);\n-                    }\n-                }\n-            } while (message.readable());\n-        }\n-    }\n-}\n+/*\r\n+ * Licensed to the Apache Software Foundation (ASF) under one or more\r\n+ * contributor license agreements.  See the NOTICE file distributed with\r\n+ * this work for additional information regarding copyright ownership.\r\n+ * The ASF licenses this file to You under the Apache License, Version 2.0\r\n+ * (the \"License\"); you may not use this file except in compliance with\r\n+ * the License.  You may obtain a copy of the License at\r\n+ *\r\n+ *     http://www.apache.org/licenses/LICENSE-2.0\r\n+ *\r\n+ * Unless required by applicable law or agreed to in writing, software\r\n+ * distributed under the License is distributed on an \"AS IS\" BASIS,\r\n+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r\n+ * See the License for the specific language governing permissions and\r\n+ * limitations under the License.\r\n+ */\r\n+package org.apache.dubbo.remoting.transport.netty4;\r\n+\r\n+import org.apache.dubbo.common.URL;\r\n+import org.apache.dubbo.remoting.Codec2;\r\n+import org.apache.dubbo.remoting.buffer.ChannelBuffer;\r\n+\r\n+import io.netty.buffer.ByteBuf;\r\n+import io.netty.channel.Channel;\r\n+import io.netty.channel.ChannelHandler;\r\n+import io.netty.channel.ChannelHandlerContext;\r\n+import io.netty.handler.codec.ByteToMessageDecoder;\r\n+import io.netty.handler.codec.MessageToByteEncoder;\r\n+\r\n+import java.io.IOException;\r\n+import java.util.List;\r\n+\r\n+/**\r\n+ * NettyCodecAdapter.\r\n+ */\r\n+final public class NettyCodecAdapter {\r\n+\r\n+    private final ChannelHandler encoder = new InternalEncoder();\r\n+\r\n+    private final ChannelHandler decoder = new InternalDecoder();\r\n+\r\n+    private final Codec2 codec;\r\n+\r\n+    private final URL url;\r\n+\r\n+    private final org.apache.dubbo.remoting.ChannelHandler handler;\r\n+\r\n+    public NettyCodecAdapter(Codec2 codec, URL url, org.apache.dubbo.remoting.ChannelHandler handler) {\r\n+        this.codec = codec;\r\n+        this.url = url;\r\n+        this.handler = handler;\r\n+    }\r\n+\r\n+    public ChannelHandler getEncoder() {\r\n+        return encoder;\r\n+    }\r\n+\r\n+    public ChannelHandler getDecoder() {\r\n+        return decoder;\r\n+    }\r\n+\r\n+    private class InternalEncoder extends MessageToByteEncoder {\r\n+\r\n+        @Override\r\n+        protected void encode(ChannelHandlerContext ctx, Object msg, ByteBuf out) throws Exception {\r\n+            org.apache.dubbo.remoting.buffer.ChannelBuffer buffer = new NettyBackedChannelBuffer(out);\r\n+            Channel ch = ctx.channel();\r\n+            NettyChannel channel = NettyChannel.getOrAddChannel(ch, url, handler);\r\n+            codec.encode(channel, buffer, msg);\r\n+        }\r\n+    }\r\n+\r\n+    private class InternalDecoder extends ByteToMessageDecoder {\r\n+\r\n+        @Override\r\n+        protected void decode(ChannelHandlerContext ctx, ByteBuf input, List<Object> out) throws Exception {\r\n+\r\n+            ChannelBuffer message = new NettyBackedChannelBuffer(input);\r\n+\r\n+            NettyChannel channel = NettyChannel.getOrAddChannel(ctx.channel(), url, handler);\r\n+\r\n+            // decode object.\r\n+            do {\r\n+                int saveReaderIndex = message.readerIndex();\r\n+                Object msg = codec.decode(channel, message);\r\n+                if (msg == Codec2.DecodeResult.NEED_MORE_INPUT) {\r\n+                    message.readerIndex(saveReaderIndex);\r\n+                    break;\r\n+                } else {\r\n+                    //is it possible to go here ?\r\n+                    if (saveReaderIndex == message.readerIndex()) {\r\n+                        throw new IOException(\"Decode without read data.\");\r\n+                    }\r\n+                    if (msg != null) {\r\n+                        out.add(msg);\r\n+                    }\r\n+                }\r\n+            } while (message.readable());\r\n+        }\r\n+    }\r\n+}\r\n"}, {"source1": "org/apache/dubbo/remoting/transport/netty4/NettyEventLoopFactory.java", "source2": "org/apache/dubbo/remoting/transport/netty4/NettyEventLoopFactory.java", "comments": ["Ordering differences only"], "unified_diff": "@@ -1,60 +1,60 @@\n-/*\n- * Licensed to the Apache Software Foundation (ASF) under one or more\n- * contributor license agreements.  See the NOTICE file distributed with\n- * this work for additional information regarding copyright ownership.\n- * The ASF licenses this file to You under the Apache License, Version 2.0\n- * (the \"License\"); you may not use this file except in compliance with\n- * the License.  You may obtain a copy of the License at\n- *\n- *     http://www.apache.org/licenses/LICENSE-2.0\n- *\n- * Unless required by applicable law or agreed to in writing, software\n- * distributed under the License is distributed on an \"AS IS\" BASIS,\n- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n- * See the License for the specific language governing permissions and\n- * limitations under the License.\n- */\n-package org.apache.dubbo.remoting.transport.netty4;\n-\n-import org.apache.dubbo.common.config.Configuration;\n-import org.apache.dubbo.rpc.model.ApplicationModel;\n-\n-import io.netty.channel.EventLoopGroup;\n-import io.netty.channel.epoll.Epoll;\n-import io.netty.channel.epoll.EpollEventLoopGroup;\n-import io.netty.channel.epoll.EpollServerSocketChannel;\n-import io.netty.channel.epoll.EpollSocketChannel;\n-import io.netty.channel.nio.NioEventLoopGroup;\n-import io.netty.channel.socket.ServerSocketChannel;\n-import io.netty.channel.socket.SocketChannel;\n-import io.netty.channel.socket.nio.NioServerSocketChannel;\n-import io.netty.channel.socket.nio.NioSocketChannel;\n-import io.netty.util.concurrent.DefaultThreadFactory;\n-\n-import java.util.concurrent.ThreadFactory;\n-\n-public class NettyEventLoopFactory {\n-    public static EventLoopGroup eventLoopGroup(int threads, String threadFactoryName) {\n-        ThreadFactory threadFactory = new DefaultThreadFactory(threadFactoryName, true);\n-        return shouldEpoll() ? new EpollEventLoopGroup(threads, threadFactory) :\n-                new NioEventLoopGroup(threads, threadFactory);\n-    }\n-\n-    public static Class<? extends SocketChannel> socketChannelClass() {\n-        return shouldEpoll() ? EpollSocketChannel.class : NioSocketChannel.class;\n-    }\n-\n-    public static Class<? extends ServerSocketChannel> serverSocketChannelClass() {\n-        return shouldEpoll() ? EpollServerSocketChannel.class : NioServerSocketChannel.class;\n-    }\n-\n-    private static boolean shouldEpoll() {\n-        Configuration configuration = ApplicationModel.getEnvironment().getConfiguration();\n-        if (configuration.getBoolean(\"netty.epoll.enable\", false)) {\n-            String osName = configuration.getString(\"os.name\");\n-            return osName.toLowerCase().contains(\"linux\") && Epoll.isAvailable();\n-        }\n-\n-        return false;\n-    }\n-}\n+/*\r\n+ * Licensed to the Apache Software Foundation (ASF) under one or more\r\n+ * contributor license agreements.  See the NOTICE file distributed with\r\n+ * this work for additional information regarding copyright ownership.\r\n+ * The ASF licenses this file to You under the Apache License, Version 2.0\r\n+ * (the \"License\"); you may not use this file except in compliance with\r\n+ * the License.  You may obtain a copy of the License at\r\n+ *\r\n+ *     http://www.apache.org/licenses/LICENSE-2.0\r\n+ *\r\n+ * Unless required by applicable law or agreed to in writing, software\r\n+ * distributed under the License is distributed on an \"AS IS\" BASIS,\r\n+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r\n+ * See the License for the specific language governing permissions and\r\n+ * limitations under the License.\r\n+ */\r\n+package org.apache.dubbo.remoting.transport.netty4;\r\n+\r\n+import org.apache.dubbo.common.config.Configuration;\r\n+import org.apache.dubbo.rpc.model.ApplicationModel;\r\n+\r\n+import io.netty.channel.EventLoopGroup;\r\n+import io.netty.channel.epoll.Epoll;\r\n+import io.netty.channel.epoll.EpollEventLoopGroup;\r\n+import io.netty.channel.epoll.EpollServerSocketChannel;\r\n+import io.netty.channel.epoll.EpollSocketChannel;\r\n+import io.netty.channel.nio.NioEventLoopGroup;\r\n+import io.netty.channel.socket.ServerSocketChannel;\r\n+import io.netty.channel.socket.SocketChannel;\r\n+import io.netty.channel.socket.nio.NioServerSocketChannel;\r\n+import io.netty.channel.socket.nio.NioSocketChannel;\r\n+import io.netty.util.concurrent.DefaultThreadFactory;\r\n+\r\n+import java.util.concurrent.ThreadFactory;\r\n+\r\n+public class NettyEventLoopFactory {\r\n+    public static EventLoopGroup eventLoopGroup(int threads, String threadFactoryName) {\r\n+        ThreadFactory threadFactory = new DefaultThreadFactory(threadFactoryName, true);\r\n+        return shouldEpoll() ? new EpollEventLoopGroup(threads, threadFactory) :\r\n+                new NioEventLoopGroup(threads, threadFactory);\r\n+    }\r\n+\r\n+    public static Class<? extends SocketChannel> socketChannelClass() {\r\n+        return shouldEpoll() ? EpollSocketChannel.class : NioSocketChannel.class;\r\n+    }\r\n+\r\n+    public static Class<? extends ServerSocketChannel> serverSocketChannelClass() {\r\n+        return shouldEpoll() ? EpollServerSocketChannel.class : NioServerSocketChannel.class;\r\n+    }\r\n+\r\n+    private static boolean shouldEpoll() {\r\n+        Configuration configuration = ApplicationModel.getEnvironment().getConfiguration();\r\n+        if (configuration.getBoolean(\"netty.epoll.enable\", false)) {\r\n+            String osName = configuration.getString(\"os.name\");\r\n+            return osName.toLowerCase().contains(\"linux\") && Epoll.isAvailable();\r\n+        }\r\n+\r\n+        return false;\r\n+    }\r\n+}\r\n"}, {"source1": "org/apache/dubbo/remoting/transport/netty4/NettyServer.java", "source2": "org/apache/dubbo/remoting/transport/netty4/NettyServer.java", "comments": ["Ordering differences only"], "unified_diff": "@@ -1,202 +1,202 @@\n-/*\n- * Licensed to the Apache Software Foundation (ASF) under one or more\n- * contributor license agreements.  See the NOTICE file distributed with\n- * this work for additional information regarding copyright ownership.\n- * The ASF licenses this file to You under the Apache License, Version 2.0\n- * (the \"License\"); you may not use this file except in compliance with\n- * the License.  You may obtain a copy of the License at\n- *\n- *     http://www.apache.org/licenses/LICENSE-2.0\n- *\n- * Unless required by applicable law or agreed to in writing, software\n- * distributed under the License is distributed on an \"AS IS\" BASIS,\n- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n- * See the License for the specific language governing permissions and\n- * limitations under the License.\n- */\n-package org.apache.dubbo.remoting.transport.netty4;\n-\n-import org.apache.dubbo.common.URL;\n-import org.apache.dubbo.common.logger.Logger;\n-import org.apache.dubbo.common.logger.LoggerFactory;\n-import org.apache.dubbo.common.utils.ExecutorUtil;\n-import org.apache.dubbo.common.utils.NetUtils;\n-import org.apache.dubbo.remoting.Channel;\n-import org.apache.dubbo.remoting.ChannelHandler;\n-import org.apache.dubbo.remoting.Constants;\n-import org.apache.dubbo.remoting.RemotingException;\n-import org.apache.dubbo.remoting.RemotingServer;\n-import org.apache.dubbo.remoting.transport.AbstractServer;\n-import org.apache.dubbo.remoting.transport.dispatcher.ChannelHandlers;\n-import org.apache.dubbo.remoting.utils.UrlUtils;\n-\n-import io.netty.bootstrap.ServerBootstrap;\n-import io.netty.buffer.PooledByteBufAllocator;\n-import io.netty.channel.ChannelFuture;\n-import io.netty.channel.ChannelInitializer;\n-import io.netty.channel.ChannelOption;\n-import io.netty.channel.EventLoopGroup;\n-import io.netty.channel.socket.SocketChannel;\n-import io.netty.handler.timeout.IdleStateHandler;\n-\n-import java.net.InetSocketAddress;\n-import java.util.ArrayList;\n-import java.util.Collection;\n-import java.util.Map;\n-\n-import static java.util.concurrent.TimeUnit.MILLISECONDS;\n-import static org.apache.dubbo.common.constants.CommonConstants.IO_THREADS_KEY;\n-import static org.apache.dubbo.common.constants.CommonConstants.KEEP_ALIVE_KEY;\n-import static org.apache.dubbo.common.constants.CommonConstants.SSL_ENABLED_KEY;\n-\n-\n-/**\n- * NettyServer.\n- */\n-public class NettyServer extends AbstractServer implements RemotingServer {\n-\n-    private static final Logger logger = LoggerFactory.getLogger(NettyServer.class);\n-    /**\n-     * the cache for alive worker channel.\n-     * <ip:port, dubbo channel>\n-     */\n-    private Map<String, Channel> channels;\n-    /**\n-     * netty server bootstrap.\n-     */\n-    private ServerBootstrap bootstrap;\n-    /**\n-     * the boss channel that receive connections and dispatch these to worker channel.\n-     */\n-\tprivate io.netty.channel.Channel channel;\n-\n-    private EventLoopGroup bossGroup;\n-    private EventLoopGroup workerGroup;\n-\n-    public NettyServer(URL url, ChannelHandler handler) throws RemotingException {\n-        // you can customize name and type of client thread pool by THREAD_NAME_KEY and THREADPOOL_KEY in CommonConstants.\n-        // the handler will be wrapped: MultiMessageHandler->HeartbeatHandler->handler\n-        super(ExecutorUtil.setThreadName(url, SERVER_THREAD_POOL_NAME), ChannelHandlers.wrap(handler, url));\n-    }\n-\n-    /**\n-     * Init and start netty server\n-     *\n-     * @throws Throwable\n-     */\n-    @Override\n-    protected void doOpen() throws Throwable {\n-        bootstrap = new ServerBootstrap();\n-\n-        bossGroup = NettyEventLoopFactory.eventLoopGroup(1, \"NettyServerBoss\");\n-        workerGroup = NettyEventLoopFactory.eventLoopGroup(\n-                getUrl().getPositiveParameter(IO_THREADS_KEY, Constants.DEFAULT_IO_THREADS),\n-                \"NettyServerWorker\");\n-\n-        final NettyServerHandler nettyServerHandler = new NettyServerHandler(getUrl(), this);\n-        channels = nettyServerHandler.getChannels();\n-\n-        boolean keepalive = getUrl().getParameter(KEEP_ALIVE_KEY, Boolean.FALSE);\n-\n-        bootstrap.group(bossGroup, workerGroup)\n-                .channel(NettyEventLoopFactory.serverSocketChannelClass())\n-                .option(ChannelOption.SO_REUSEADDR, Boolean.TRUE)\n-                .childOption(ChannelOption.TCP_NODELAY, Boolean.TRUE)\n-                .childOption(ChannelOption.SO_KEEPALIVE, keepalive)\n-                .childOption(ChannelOption.ALLOCATOR, PooledByteBufAllocator.DEFAULT)\n-                .childHandler(new ChannelInitializer<SocketChannel>() {\n-                    @Override\n-                    protected void initChannel(SocketChannel ch) throws Exception {\n-                        // FIXME: should we use getTimeout()?\n-                        int idleTimeout = UrlUtils.getIdleTimeout(getUrl());\n-                        NettyCodecAdapter adapter = new NettyCodecAdapter(getCodec(), getUrl(), NettyServer.this);\n-                        if (getUrl().getParameter(SSL_ENABLED_KEY, false)) {\n-                            ch.pipeline().addLast(\"negotiation\",\n-                                    SslHandlerInitializer.sslServerHandler(getUrl(), nettyServerHandler));\n-                        }\n-                        ch.pipeline()\n-                                .addLast(\"decoder\", adapter.getDecoder())\n-                                .addLast(\"encoder\", adapter.getEncoder())\n-                                .addLast(\"server-idle-handler\", new IdleStateHandler(0, 0, idleTimeout, MILLISECONDS))\n-                                .addLast(\"handler\", nettyServerHandler);\n-                    }\n-                });\n-        // bind\n-        ChannelFuture channelFuture = bootstrap.bind(getBindAddress());\n-        channelFuture.syncUninterruptibly();\n-        channel = channelFuture.channel();\n-\n-    }\n-\n-    @Override\n-    protected void doClose() throws Throwable {\n-        try {\n-            if (channel != null) {\n-                // unbind.\n-                channel.close();\n-            }\n-        } catch (Throwable e) {\n-            logger.warn(e.getMessage(), e);\n-        }\n-        try {\n-            Collection<org.apache.dubbo.remoting.Channel> channels = getChannels();\n-            if (channels != null && channels.size() > 0) {\n-                for (org.apache.dubbo.remoting.Channel channel : channels) {\n-                    try {\n-                        channel.close();\n-                    } catch (Throwable e) {\n-                        logger.warn(e.getMessage(), e);\n-                    }\n-                }\n-            }\n-        } catch (Throwable e) {\n-            logger.warn(e.getMessage(), e);\n-        }\n-        try {\n-            if (bootstrap != null) {\n-                bossGroup.shutdownGracefully().syncUninterruptibly();\n-                workerGroup.shutdownGracefully().syncUninterruptibly();\n-            }\n-        } catch (Throwable e) {\n-            logger.warn(e.getMessage(), e);\n-        }\n-        try {\n-            if (channels != null) {\n-                channels.clear();\n-            }\n-        } catch (Throwable e) {\n-            logger.warn(e.getMessage(), e);\n-        }\n-    }\n-\n-    @Override\n-    public Collection<Channel> getChannels() {\n-        Collection<Channel> chs = new ArrayList<>(this.channels.size());\n-        chs.addAll(this.channels.values());\n-        // check of connection status is unnecessary since we are using channels in NettyServerHandler\n-//        for (Channel channel : this.channels.values()) {\n-//            if (channel.isConnected()) {\n-//                chs.add(channel);\n-//            } else {\n-//                channels.remove(NetUtils.toAddressString(channel.getRemoteAddress()));\n-//            }\n-//        }\n-        return chs;\n-    }\n-\n-    @Override\n-    public Channel getChannel(InetSocketAddress remoteAddress) {\n-        return channels.get(NetUtils.toAddressString(remoteAddress));\n-    }\n-\n-    @Override\n-    public boolean canHandleIdle() {\n-        return true;\n-    }\n-\n-    @Override\n-    public boolean isBound() {\n-        return channel.isActive();\n-    }\n-\n-}\n+/*\r\n+ * Licensed to the Apache Software Foundation (ASF) under one or more\r\n+ * contributor license agreements.  See the NOTICE file distributed with\r\n+ * this work for additional information regarding copyright ownership.\r\n+ * The ASF licenses this file to You under the Apache License, Version 2.0\r\n+ * (the \"License\"); you may not use this file except in compliance with\r\n+ * the License.  You may obtain a copy of the License at\r\n+ *\r\n+ *     http://www.apache.org/licenses/LICENSE-2.0\r\n+ *\r\n+ * Unless required by applicable law or agreed to in writing, software\r\n+ * distributed under the License is distributed on an \"AS IS\" BASIS,\r\n+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r\n+ * See the License for the specific language governing permissions and\r\n+ * limitations under the License.\r\n+ */\r\n+package org.apache.dubbo.remoting.transport.netty4;\r\n+\r\n+import org.apache.dubbo.common.URL;\r\n+import org.apache.dubbo.common.logger.Logger;\r\n+import org.apache.dubbo.common.logger.LoggerFactory;\r\n+import org.apache.dubbo.common.utils.ExecutorUtil;\r\n+import org.apache.dubbo.common.utils.NetUtils;\r\n+import org.apache.dubbo.remoting.Channel;\r\n+import org.apache.dubbo.remoting.ChannelHandler;\r\n+import org.apache.dubbo.remoting.Constants;\r\n+import org.apache.dubbo.remoting.RemotingException;\r\n+import org.apache.dubbo.remoting.RemotingServer;\r\n+import org.apache.dubbo.remoting.transport.AbstractServer;\r\n+import org.apache.dubbo.remoting.transport.dispatcher.ChannelHandlers;\r\n+import org.apache.dubbo.remoting.utils.UrlUtils;\r\n+\r\n+import io.netty.bootstrap.ServerBootstrap;\r\n+import io.netty.buffer.PooledByteBufAllocator;\r\n+import io.netty.channel.ChannelFuture;\r\n+import io.netty.channel.ChannelInitializer;\r\n+import io.netty.channel.ChannelOption;\r\n+import io.netty.channel.EventLoopGroup;\r\n+import io.netty.channel.socket.SocketChannel;\r\n+import io.netty.handler.timeout.IdleStateHandler;\r\n+\r\n+import java.net.InetSocketAddress;\r\n+import java.util.ArrayList;\r\n+import java.util.Collection;\r\n+import java.util.Map;\r\n+\r\n+import static java.util.concurrent.TimeUnit.MILLISECONDS;\r\n+import static org.apache.dubbo.common.constants.CommonConstants.IO_THREADS_KEY;\r\n+import static org.apache.dubbo.common.constants.CommonConstants.KEEP_ALIVE_KEY;\r\n+import static org.apache.dubbo.common.constants.CommonConstants.SSL_ENABLED_KEY;\r\n+\r\n+\r\n+/**\r\n+ * NettyServer.\r\n+ */\r\n+public class NettyServer extends AbstractServer implements RemotingServer {\r\n+\r\n+    private static final Logger logger = LoggerFactory.getLogger(NettyServer.class);\r\n+    /**\r\n+     * the cache for alive worker channel.\r\n+     * <ip:port, dubbo channel>\r\n+     */\r\n+    private Map<String, Channel> channels;\r\n+    /**\r\n+     * netty server bootstrap.\r\n+     */\r\n+    private ServerBootstrap bootstrap;\r\n+    /**\r\n+     * the boss channel that receive connections and dispatch these to worker channel.\r\n+     */\r\n+\tprivate io.netty.channel.Channel channel;\r\n+\r\n+    private EventLoopGroup bossGroup;\r\n+    private EventLoopGroup workerGroup;\r\n+\r\n+    public NettyServer(URL url, ChannelHandler handler) throws RemotingException {\r\n+        // you can customize name and type of client thread pool by THREAD_NAME_KEY and THREADPOOL_KEY in CommonConstants.\r\n+        // the handler will be wrapped: MultiMessageHandler->HeartbeatHandler->handler\r\n+        super(ExecutorUtil.setThreadName(url, SERVER_THREAD_POOL_NAME), ChannelHandlers.wrap(handler, url));\r\n+    }\r\n+\r\n+    /**\r\n+     * Init and start netty server\r\n+     *\r\n+     * @throws Throwable\r\n+     */\r\n+    @Override\r\n+    protected void doOpen() throws Throwable {\r\n+        bootstrap = new ServerBootstrap();\r\n+\r\n+        bossGroup = NettyEventLoopFactory.eventLoopGroup(1, \"NettyServerBoss\");\r\n+        workerGroup = NettyEventLoopFactory.eventLoopGroup(\r\n+                getUrl().getPositiveParameter(IO_THREADS_KEY, Constants.DEFAULT_IO_THREADS),\r\n+                \"NettyServerWorker\");\r\n+\r\n+        final NettyServerHandler nettyServerHandler = new NettyServerHandler(getUrl(), this);\r\n+        channels = nettyServerHandler.getChannels();\r\n+\r\n+        boolean keepalive = getUrl().getParameter(KEEP_ALIVE_KEY, Boolean.FALSE);\r\n+\r\n+        bootstrap.group(bossGroup, workerGroup)\r\n+                .channel(NettyEventLoopFactory.serverSocketChannelClass())\r\n+                .option(ChannelOption.SO_REUSEADDR, Boolean.TRUE)\r\n+                .childOption(ChannelOption.TCP_NODELAY, Boolean.TRUE)\r\n+                .childOption(ChannelOption.SO_KEEPALIVE, keepalive)\r\n+                .childOption(ChannelOption.ALLOCATOR, PooledByteBufAllocator.DEFAULT)\r\n+                .childHandler(new ChannelInitializer<SocketChannel>() {\r\n+                    @Override\r\n+                    protected void initChannel(SocketChannel ch) throws Exception {\r\n+                        // FIXME: should we use getTimeout()?\r\n+                        int idleTimeout = UrlUtils.getIdleTimeout(getUrl());\r\n+                        NettyCodecAdapter adapter = new NettyCodecAdapter(getCodec(), getUrl(), NettyServer.this);\r\n+                        if (getUrl().getParameter(SSL_ENABLED_KEY, false)) {\r\n+                            ch.pipeline().addLast(\"negotiation\",\r\n+                                    SslHandlerInitializer.sslServerHandler(getUrl(), nettyServerHandler));\r\n+                        }\r\n+                        ch.pipeline()\r\n+                                .addLast(\"decoder\", adapter.getDecoder())\r\n+                                .addLast(\"encoder\", adapter.getEncoder())\r\n+                                .addLast(\"server-idle-handler\", new IdleStateHandler(0, 0, idleTimeout, MILLISECONDS))\r\n+                                .addLast(\"handler\", nettyServerHandler);\r\n+                    }\r\n+                });\r\n+        // bind\r\n+        ChannelFuture channelFuture = bootstrap.bind(getBindAddress());\r\n+        channelFuture.syncUninterruptibly();\r\n+        channel = channelFuture.channel();\r\n+\r\n+    }\r\n+\r\n+    @Override\r\n+    protected void doClose() throws Throwable {\r\n+        try {\r\n+            if (channel != null) {\r\n+                // unbind.\r\n+                channel.close();\r\n+            }\r\n+        } catch (Throwable e) {\r\n+            logger.warn(e.getMessage(), e);\r\n+        }\r\n+        try {\r\n+            Collection<org.apache.dubbo.remoting.Channel> channels = getChannels();\r\n+            if (channels != null && channels.size() > 0) {\r\n+                for (org.apache.dubbo.remoting.Channel channel : channels) {\r\n+                    try {\r\n+                        channel.close();\r\n+                    } catch (Throwable e) {\r\n+                        logger.warn(e.getMessage(), e);\r\n+                    }\r\n+                }\r\n+            }\r\n+        } catch (Throwable e) {\r\n+            logger.warn(e.getMessage(), e);\r\n+        }\r\n+        try {\r\n+            if (bootstrap != null) {\r\n+                bossGroup.shutdownGracefully().syncUninterruptibly();\r\n+                workerGroup.shutdownGracefully().syncUninterruptibly();\r\n+            }\r\n+        } catch (Throwable e) {\r\n+            logger.warn(e.getMessage(), e);\r\n+        }\r\n+        try {\r\n+            if (channels != null) {\r\n+                channels.clear();\r\n+            }\r\n+        } catch (Throwable e) {\r\n+            logger.warn(e.getMessage(), e);\r\n+        }\r\n+    }\r\n+\r\n+    @Override\r\n+    public Collection<Channel> getChannels() {\r\n+        Collection<Channel> chs = new ArrayList<>(this.channels.size());\r\n+        chs.addAll(this.channels.values());\r\n+        // check of connection status is unnecessary since we are using channels in NettyServerHandler\r\n+//        for (Channel channel : this.channels.values()) {\r\n+//            if (channel.isConnected()) {\r\n+//                chs.add(channel);\r\n+//            } else {\r\n+//                channels.remove(NetUtils.toAddressString(channel.getRemoteAddress()));\r\n+//            }\r\n+//        }\r\n+        return chs;\r\n+    }\r\n+\r\n+    @Override\r\n+    public Channel getChannel(InetSocketAddress remoteAddress) {\r\n+        return channels.get(NetUtils.toAddressString(remoteAddress));\r\n+    }\r\n+\r\n+    @Override\r\n+    public boolean canHandleIdle() {\r\n+        return true;\r\n+    }\r\n+\r\n+    @Override\r\n+    public boolean isBound() {\r\n+        return channel.isActive();\r\n+    }\r\n+\r\n+}\r\n"}, {"source1": "org/apache/dubbo/remoting/transport/netty4/NettyServerHandler.java", "source2": "org/apache/dubbo/remoting/transport/netty4/NettyServerHandler.java", "comments": ["Ordering differences only"], "unified_diff": "@@ -1,138 +1,138 @@\n-/*\n- * Licensed to the Apache Software Foundation (ASF) under one or more\n- * contributor license agreements.  See the NOTICE file distributed with\n- * this work for additional information regarding copyright ownership.\n- * The ASF licenses this file to You under the Apache License, Version 2.0\n- * (the \"License\"); you may not use this file except in compliance with\n- * the License.  You may obtain a copy of the License at\n- *\n- *     http://www.apache.org/licenses/LICENSE-2.0\n- *\n- * Unless required by applicable law or agreed to in writing, software\n- * distributed under the License is distributed on an \"AS IS\" BASIS,\n- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n- * See the License for the specific language governing permissions and\n- * limitations under the License.\n- */\n-package org.apache.dubbo.remoting.transport.netty4;\n-\n-import org.apache.dubbo.common.URL;\n-import org.apache.dubbo.common.logger.Logger;\n-import org.apache.dubbo.common.logger.LoggerFactory;\n-import org.apache.dubbo.common.utils.NetUtils;\n-import org.apache.dubbo.remoting.Channel;\n-import org.apache.dubbo.remoting.ChannelHandler;\n-import org.apache.dubbo.remoting.transport.netty4.SslHandlerInitializer.HandshakeCompletionEvent;\n-\n-import io.netty.channel.ChannelDuplexHandler;\n-import io.netty.channel.ChannelHandlerContext;\n-import io.netty.channel.ChannelPromise;\n-import io.netty.handler.timeout.IdleStateEvent;\n-\n-import java.net.InetSocketAddress;\n-import java.util.Map;\n-import java.util.concurrent.ConcurrentHashMap;\n-\n-/**\n- * NettyServerHandler.\n- */\n-@io.netty.channel.ChannelHandler.Sharable\n-public class NettyServerHandler extends ChannelDuplexHandler {\n-    private static final Logger logger = LoggerFactory.getLogger(NettyServerHandler.class);\n-    /**\n-     * the cache for alive worker channel.\n-     * <ip:port, dubbo channel>\n-     */\n-    private final Map<String, Channel> channels = new ConcurrentHashMap<String, Channel>();\n-\n-    private final URL url;\n-\n-    private final ChannelHandler handler;\n-\n-    public NettyServerHandler(URL url, ChannelHandler handler) {\n-        if (url == null) {\n-            throw new IllegalArgumentException(\"url == null\");\n-        }\n-        if (handler == null) {\n-            throw new IllegalArgumentException(\"handler == null\");\n-        }\n-        this.url = url;\n-        this.handler = handler;\n-    }\n-\n-    public Map<String, Channel> getChannels() {\n-        return channels;\n-    }\n-\n-    @Override\n-    public void channelActive(ChannelHandlerContext ctx) throws Exception {\n-        NettyChannel channel = NettyChannel.getOrAddChannel(ctx.channel(), url, handler);\n-        if (channel != null) {\n-            channels.put(NetUtils.toAddressString((InetSocketAddress) ctx.channel().remoteAddress()), channel);\n-        }\n-        handler.connected(channel);\n-\n-        if (logger.isInfoEnabled()) {\n-            logger.info(\"The connection of \" + channel.getRemoteAddress() + \" -> \" + channel.getLocalAddress() + \" is established.\");\n-        }\n-    }\n-\n-    @Override\n-    public void channelInactive(ChannelHandlerContext ctx) throws Exception {\n-        NettyChannel channel = NettyChannel.getOrAddChannel(ctx.channel(), url, handler);\n-        try {\n-            channels.remove(NetUtils.toAddressString((InetSocketAddress) ctx.channel().remoteAddress()));\n-            handler.disconnected(channel);\n-        } finally {\n-            NettyChannel.removeChannel(ctx.channel());\n-        }\n-\n-        if (logger.isInfoEnabled()) {\n-            logger.info(\"The connection of \" + channel.getRemoteAddress() + \" -> \" + channel.getLocalAddress() + \" is disconnected.\");\n-        }\n-    }\n-\n-    @Override\n-    public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {\n-        NettyChannel channel = NettyChannel.getOrAddChannel(ctx.channel(), url, handler);\n-        handler.received(channel, msg);\n-    }\n-\n-\n-    @Override\n-    public void write(ChannelHandlerContext ctx, Object msg, ChannelPromise promise) throws Exception {\n-        super.write(ctx, msg, promise);\n-        NettyChannel channel = NettyChannel.getOrAddChannel(ctx.channel(), url, handler);\n-        handler.sent(channel, msg);\n-    }\n-\n-    @Override\n-    public void userEventTriggered(ChannelHandlerContext ctx, Object evt) throws Exception {\n-        // server will close channel when server don't receive any heartbeat from client util timeout.\n-        if (evt instanceof IdleStateEvent) {\n-            NettyChannel channel = NettyChannel.getOrAddChannel(ctx.channel(), url, handler);\n-            try {\n-                logger.info(\"IdleStateEvent triggered, close channel \" + channel);\n-                channel.close();\n-            } finally {\n-                NettyChannel.removeChannelIfDisconnected(ctx.channel());\n-            }\n-        }\n-        super.userEventTriggered(ctx, evt);\n-    }\n-\n-    @Override\n-    public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause)\n-            throws Exception {\n-        NettyChannel channel = NettyChannel.getOrAddChannel(ctx.channel(), url, handler);\n-        try {\n-            handler.caught(channel, cause);\n-        } finally {\n-            NettyChannel.removeChannelIfDisconnected(ctx.channel());\n-        }\n-    }\n-\n-    public void handshakeCompleted(HandshakeCompletionEvent evt) {\n-        // TODO\n-    }\n-}\n+/*\r\n+ * Licensed to the Apache Software Foundation (ASF) under one or more\r\n+ * contributor license agreements.  See the NOTICE file distributed with\r\n+ * this work for additional information regarding copyright ownership.\r\n+ * The ASF licenses this file to You under the Apache License, Version 2.0\r\n+ * (the \"License\"); you may not use this file except in compliance with\r\n+ * the License.  You may obtain a copy of the License at\r\n+ *\r\n+ *     http://www.apache.org/licenses/LICENSE-2.0\r\n+ *\r\n+ * Unless required by applicable law or agreed to in writing, software\r\n+ * distributed under the License is distributed on an \"AS IS\" BASIS,\r\n+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r\n+ * See the License for the specific language governing permissions and\r\n+ * limitations under the License.\r\n+ */\r\n+package org.apache.dubbo.remoting.transport.netty4;\r\n+\r\n+import org.apache.dubbo.common.URL;\r\n+import org.apache.dubbo.common.logger.Logger;\r\n+import org.apache.dubbo.common.logger.LoggerFactory;\r\n+import org.apache.dubbo.common.utils.NetUtils;\r\n+import org.apache.dubbo.remoting.Channel;\r\n+import org.apache.dubbo.remoting.ChannelHandler;\r\n+import org.apache.dubbo.remoting.transport.netty4.SslHandlerInitializer.HandshakeCompletionEvent;\r\n+\r\n+import io.netty.channel.ChannelDuplexHandler;\r\n+import io.netty.channel.ChannelHandlerContext;\r\n+import io.netty.channel.ChannelPromise;\r\n+import io.netty.handler.timeout.IdleStateEvent;\r\n+\r\n+import java.net.InetSocketAddress;\r\n+import java.util.Map;\r\n+import java.util.concurrent.ConcurrentHashMap;\r\n+\r\n+/**\r\n+ * NettyServerHandler.\r\n+ */\r\n+@io.netty.channel.ChannelHandler.Sharable\r\n+public class NettyServerHandler extends ChannelDuplexHandler {\r\n+    private static final Logger logger = LoggerFactory.getLogger(NettyServerHandler.class);\r\n+    /**\r\n+     * the cache for alive worker channel.\r\n+     * <ip:port, dubbo channel>\r\n+     */\r\n+    private final Map<String, Channel> channels = new ConcurrentHashMap<String, Channel>();\r\n+\r\n+    private final URL url;\r\n+\r\n+    private final ChannelHandler handler;\r\n+\r\n+    public NettyServerHandler(URL url, ChannelHandler handler) {\r\n+        if (url == null) {\r\n+            throw new IllegalArgumentException(\"url == null\");\r\n+        }\r\n+        if (handler == null) {\r\n+            throw new IllegalArgumentException(\"handler == null\");\r\n+        }\r\n+        this.url = url;\r\n+        this.handler = handler;\r\n+    }\r\n+\r\n+    public Map<String, Channel> getChannels() {\r\n+        return channels;\r\n+    }\r\n+\r\n+    @Override\r\n+    public void channelActive(ChannelHandlerContext ctx) throws Exception {\r\n+        NettyChannel channel = NettyChannel.getOrAddChannel(ctx.channel(), url, handler);\r\n+        if (channel != null) {\r\n+            channels.put(NetUtils.toAddressString((InetSocketAddress) ctx.channel().remoteAddress()), channel);\r\n+        }\r\n+        handler.connected(channel);\r\n+\r\n+        if (logger.isInfoEnabled()) {\r\n+            logger.info(\"The connection of \" + channel.getRemoteAddress() + \" -> \" + channel.getLocalAddress() + \" is established.\");\r\n+        }\r\n+    }\r\n+\r\n+    @Override\r\n+    public void channelInactive(ChannelHandlerContext ctx) throws Exception {\r\n+        NettyChannel channel = NettyChannel.getOrAddChannel(ctx.channel(), url, handler);\r\n+        try {\r\n+            channels.remove(NetUtils.toAddressString((InetSocketAddress) ctx.channel().remoteAddress()));\r\n+            handler.disconnected(channel);\r\n+        } finally {\r\n+            NettyChannel.removeChannel(ctx.channel());\r\n+        }\r\n+\r\n+        if (logger.isInfoEnabled()) {\r\n+            logger.info(\"The connection of \" + channel.getRemoteAddress() + \" -> \" + channel.getLocalAddress() + \" is disconnected.\");\r\n+        }\r\n+    }\r\n+\r\n+    @Override\r\n+    public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {\r\n+        NettyChannel channel = NettyChannel.getOrAddChannel(ctx.channel(), url, handler);\r\n+        handler.received(channel, msg);\r\n+    }\r\n+\r\n+\r\n+    @Override\r\n+    public void write(ChannelHandlerContext ctx, Object msg, ChannelPromise promise) throws Exception {\r\n+        super.write(ctx, msg, promise);\r\n+        NettyChannel channel = NettyChannel.getOrAddChannel(ctx.channel(), url, handler);\r\n+        handler.sent(channel, msg);\r\n+    }\r\n+\r\n+    @Override\r\n+    public void userEventTriggered(ChannelHandlerContext ctx, Object evt) throws Exception {\r\n+        // server will close channel when server don't receive any heartbeat from client util timeout.\r\n+        if (evt instanceof IdleStateEvent) {\r\n+            NettyChannel channel = NettyChannel.getOrAddChannel(ctx.channel(), url, handler);\r\n+            try {\r\n+                logger.info(\"IdleStateEvent triggered, close channel \" + channel);\r\n+                channel.close();\r\n+            } finally {\r\n+                NettyChannel.removeChannelIfDisconnected(ctx.channel());\r\n+            }\r\n+        }\r\n+        super.userEventTriggered(ctx, evt);\r\n+    }\r\n+\r\n+    @Override\r\n+    public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause)\r\n+            throws Exception {\r\n+        NettyChannel channel = NettyChannel.getOrAddChannel(ctx.channel(), url, handler);\r\n+        try {\r\n+            handler.caught(channel, cause);\r\n+        } finally {\r\n+            NettyChannel.removeChannelIfDisconnected(ctx.channel());\r\n+        }\r\n+    }\r\n+\r\n+    public void handshakeCompleted(HandshakeCompletionEvent evt) {\r\n+        // TODO\r\n+    }\r\n+}\r\n"}, {"source1": "org/apache/dubbo/remoting/transport/netty4/NettyTransporter.java", "source2": "org/apache/dubbo/remoting/transport/netty4/NettyTransporter.java", "comments": ["Ordering differences only"], "unified_diff": "@@ -1,43 +1,43 @@\n-/*\n- * Licensed to the Apache Software Foundation (ASF) under one or more\n- * contributor license agreements.  See the NOTICE file distributed with\n- * this work for additional information regarding copyright ownership.\n- * The ASF licenses this file to You under the Apache License, Version 2.0\n- * (the \"License\"); you may not use this file except in compliance with\n- * the License.  You may obtain a copy of the License at\n- *\n- *     http://www.apache.org/licenses/LICENSE-2.0\n- *\n- * Unless required by applicable law or agreed to in writing, software\n- * distributed under the License is distributed on an \"AS IS\" BASIS,\n- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n- * See the License for the specific language governing permissions and\n- * limitations under the License.\n- */\n-package org.apache.dubbo.remoting.transport.netty4;\n-\n-import org.apache.dubbo.common.URL;\n-import org.apache.dubbo.remoting.ChannelHandler;\n-import org.apache.dubbo.remoting.Client;\n-import org.apache.dubbo.remoting.RemotingException;\n-import org.apache.dubbo.remoting.RemotingServer;\n-import org.apache.dubbo.remoting.Transporter;\n-\n-/**\n- * Default extension of {@link Transporter} using netty4.x.\n- */\n-public class NettyTransporter implements Transporter {\n-\n-    public static final String NAME = \"netty\";\n-\n-    @Override\n-    public RemotingServer bind(URL url, ChannelHandler handler) throws RemotingException {\n-        return new NettyServer(url, handler);\n-    }\n-\n-    @Override\n-    public Client connect(URL url, ChannelHandler handler) throws RemotingException {\n-        return new NettyClient(url, handler);\n-    }\n-\n-}\n+/*\r\n+ * Licensed to the Apache Software Foundation (ASF) under one or more\r\n+ * contributor license agreements.  See the NOTICE file distributed with\r\n+ * this work for additional information regarding copyright ownership.\r\n+ * The ASF licenses this file to You under the Apache License, Version 2.0\r\n+ * (the \"License\"); you may not use this file except in compliance with\r\n+ * the License.  You may obtain a copy of the License at\r\n+ *\r\n+ *     http://www.apache.org/licenses/LICENSE-2.0\r\n+ *\r\n+ * Unless required by applicable law or agreed to in writing, software\r\n+ * distributed under the License is distributed on an \"AS IS\" BASIS,\r\n+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r\n+ * See the License for the specific language governing permissions and\r\n+ * limitations under the License.\r\n+ */\r\n+package org.apache.dubbo.remoting.transport.netty4;\r\n+\r\n+import org.apache.dubbo.common.URL;\r\n+import org.apache.dubbo.remoting.ChannelHandler;\r\n+import org.apache.dubbo.remoting.Client;\r\n+import org.apache.dubbo.remoting.RemotingException;\r\n+import org.apache.dubbo.remoting.RemotingServer;\r\n+import org.apache.dubbo.remoting.Transporter;\r\n+\r\n+/**\r\n+ * Default extension of {@link Transporter} using netty4.x.\r\n+ */\r\n+public class NettyTransporter implements Transporter {\r\n+\r\n+    public static final String NAME = \"netty\";\r\n+\r\n+    @Override\r\n+    public RemotingServer bind(URL url, ChannelHandler handler) throws RemotingException {\r\n+        return new NettyServer(url, handler);\r\n+    }\r\n+\r\n+    @Override\r\n+    public Client connect(URL url, ChannelHandler handler) throws RemotingException {\r\n+        return new NettyClient(url, handler);\r\n+    }\r\n+\r\n+}\r\n"}, {"source1": "org/apache/dubbo/remoting/transport/netty4/SslContexts.java", "source2": "org/apache/dubbo/remoting/transport/netty4/SslContexts.java", "comments": ["Ordering differences only"], "unified_diff": "@@ -1,121 +1,121 @@\n-/*\n- * Licensed to the Apache Software Foundation (ASF) under one or more\n- * contributor license agreements.  See the NOTICE file distributed with\n- * this work for additional information regarding copyright ownership.\n- * The ASF licenses this file to You under the Apache License, Version 2.0\n- * (the \"License\"); you may not use this file except in compliance with\n- * the License.  You may obtain a copy of the License at\n- *\n- *     http://www.apache.org/licenses/LICENSE-2.0\n- *\n- * Unless required by applicable law or agreed to in writing, software\n- * distributed under the License is distributed on an \"AS IS\" BASIS,\n- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n- * See the License for the specific language governing permissions and\n- * limitations under the License.\n- */\n-package org.apache.dubbo.remoting.transport.netty4;\n-\n-import org.apache.dubbo.common.URL;\n-import org.apache.dubbo.common.logger.Logger;\n-import org.apache.dubbo.common.logger.LoggerFactory;\n-import org.apache.dubbo.config.SslConfig;\n-import org.apache.dubbo.config.context.ConfigManager;\n-import org.apache.dubbo.rpc.model.ApplicationModel;\n-\n-import io.netty.handler.ssl.ClientAuth;\n-import io.netty.handler.ssl.OpenSsl;\n-import io.netty.handler.ssl.SslContext;\n-import io.netty.handler.ssl.SslContextBuilder;\n-import io.netty.handler.ssl.SslProvider;\n-\n-import javax.net.ssl.SSLException;\n-import java.io.InputStream;\n-import java.security.Provider;\n-import java.security.Security;\n-\n-public class SslContexts {\n-\n-    private static final Logger logger = LoggerFactory.getLogger(SslContexts.class);\n-\n-    public static SslContext buildServerSslContext(URL url) {\n-        ConfigManager globalConfigManager = ApplicationModel.getConfigManager();\n-        SslConfig sslConfig = globalConfigManager.getSsl().orElseThrow(() -> new IllegalStateException(\"Ssl enabled, but no ssl cert information provided!\"));\n-\n-        SslContextBuilder sslClientContextBuilder = null;\n-        try {\n-            String password = sslConfig.getServerKeyPassword();\n-            if (password != null) {\n-                sslClientContextBuilder = SslContextBuilder.forServer(sslConfig.getServerKeyCertChainPathStream(),\n-                        sslConfig.getServerPrivateKeyPathStream(), password);\n-            } else {\n-                sslClientContextBuilder = SslContextBuilder.forServer(sslConfig.getServerKeyCertChainPathStream(),\n-                        sslConfig.getServerPrivateKeyPathStream());\n-            }\n-\n-            if (sslConfig.getServerTrustCertCollectionPathStream() != null) {\n-                sslClientContextBuilder.trustManager(sslConfig.getServerTrustCertCollectionPathStream());\n-                sslClientContextBuilder.clientAuth(ClientAuth.REQUIRE);\n-            }\n-        } catch (Exception e) {\n-            throw new IllegalArgumentException(\"Could not find certificate file or the certificate is invalid.\", e);\n-        }\n-        try {\n-            return sslClientContextBuilder.sslProvider(findSslProvider()).build();\n-        } catch (SSLException e) {\n-            throw new IllegalStateException(\"Build SslSession failed.\", e);\n-        }\n-    }\n-\n-    public static SslContext buildClientSslContext(URL url) {\n-        ConfigManager globalConfigManager = ApplicationModel.getConfigManager();\n-        SslConfig sslConfig = globalConfigManager.getSsl().orElseThrow(() -> new IllegalStateException(\"Ssl enabled, but no ssl cert information provided!\"));\n-\n-        SslContextBuilder builder = SslContextBuilder.forClient();\n-        try {\n-            if (sslConfig.getClientTrustCertCollectionPathStream() != null) {\n-                builder.trustManager(sslConfig.getClientTrustCertCollectionPathStream());\n-            }\n-\n-            InputStream clientCertChainFilePath = sslConfig.getClientKeyCertChainPathStream();\n-            InputStream clientPrivateKeyFilePath = sslConfig.getClientPrivateKeyPathStream();\n-            if (clientCertChainFilePath != null && clientPrivateKeyFilePath != null) {\n-                String password = sslConfig.getClientKeyPassword();\n-                if (password != null) {\n-                    builder.keyManager(clientCertChainFilePath, clientPrivateKeyFilePath, password);\n-                } else {\n-                    builder.keyManager(clientCertChainFilePath, clientPrivateKeyFilePath);\n-                }\n-            }\n-        } catch (Exception e) {\n-            throw new IllegalArgumentException(\"Could not find certificate file or find invalid certificate.\", e);\n-        }\n-        try {\n-            return builder.sslProvider(findSslProvider()).build();\n-        } catch (SSLException e) {\n-            throw new IllegalStateException(\"Build SslSession failed.\", e);\n-        }\n-    }\n-\n-    /**\n-     * Returns OpenSSL if available, otherwise returns the JDK provider.\n-     */\n-    private static SslProvider findSslProvider() {\n-        if (OpenSsl.isAvailable()) {\n-            logger.info(\"Using OPENSSL provider.\");\n-            return SslProvider.OPENSSL;\n-        } else if (checkJdkProvider()) {\n-            logger.info(\"Using JDK provider.\");\n-            return SslProvider.JDK;\n-        }\n-        throw new IllegalStateException(\n-                \"Could not find any valid TLS provider, please check your dependency or deployment environment, \" +\n-                        \"usually netty-tcnative, Conscrypt, or Jetty NPN/ALPN is needed.\");\n-    }\n-\n-    private static boolean checkJdkProvider() {\n-        Provider[] jdkProviders = Security.getProviders(\"SSLContext.TLS\");\n-        return (jdkProviders != null && jdkProviders.length > 0);\n-    }\n-\n-}\n+/*\r\n+ * Licensed to the Apache Software Foundation (ASF) under one or more\r\n+ * contributor license agreements.  See the NOTICE file distributed with\r\n+ * this work for additional information regarding copyright ownership.\r\n+ * The ASF licenses this file to You under the Apache License, Version 2.0\r\n+ * (the \"License\"); you may not use this file except in compliance with\r\n+ * the License.  You may obtain a copy of the License at\r\n+ *\r\n+ *     http://www.apache.org/licenses/LICENSE-2.0\r\n+ *\r\n+ * Unless required by applicable law or agreed to in writing, software\r\n+ * distributed under the License is distributed on an \"AS IS\" BASIS,\r\n+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r\n+ * See the License for the specific language governing permissions and\r\n+ * limitations under the License.\r\n+ */\r\n+package org.apache.dubbo.remoting.transport.netty4;\r\n+\r\n+import org.apache.dubbo.common.URL;\r\n+import org.apache.dubbo.common.logger.Logger;\r\n+import org.apache.dubbo.common.logger.LoggerFactory;\r\n+import org.apache.dubbo.config.SslConfig;\r\n+import org.apache.dubbo.config.context.ConfigManager;\r\n+import org.apache.dubbo.rpc.model.ApplicationModel;\r\n+\r\n+import io.netty.handler.ssl.ClientAuth;\r\n+import io.netty.handler.ssl.OpenSsl;\r\n+import io.netty.handler.ssl.SslContext;\r\n+import io.netty.handler.ssl.SslContextBuilder;\r\n+import io.netty.handler.ssl.SslProvider;\r\n+\r\n+import javax.net.ssl.SSLException;\r\n+import java.io.InputStream;\r\n+import java.security.Provider;\r\n+import java.security.Security;\r\n+\r\n+public class SslContexts {\r\n+\r\n+    private static final Logger logger = LoggerFactory.getLogger(SslContexts.class);\r\n+\r\n+    public static SslContext buildServerSslContext(URL url) {\r\n+        ConfigManager globalConfigManager = ApplicationModel.getConfigManager();\r\n+        SslConfig sslConfig = globalConfigManager.getSsl().orElseThrow(() -> new IllegalStateException(\"Ssl enabled, but no ssl cert information provided!\"));\r\n+\r\n+        SslContextBuilder sslClientContextBuilder = null;\r\n+        try {\r\n+            String password = sslConfig.getServerKeyPassword();\r\n+            if (password != null) {\r\n+                sslClientContextBuilder = SslContextBuilder.forServer(sslConfig.getServerKeyCertChainPathStream(),\r\n+                        sslConfig.getServerPrivateKeyPathStream(), password);\r\n+            } else {\r\n+                sslClientContextBuilder = SslContextBuilder.forServer(sslConfig.getServerKeyCertChainPathStream(),\r\n+                        sslConfig.getServerPrivateKeyPathStream());\r\n+            }\r\n+\r\n+            if (sslConfig.getServerTrustCertCollectionPathStream() != null) {\r\n+                sslClientContextBuilder.trustManager(sslConfig.getServerTrustCertCollectionPathStream());\r\n+                sslClientContextBuilder.clientAuth(ClientAuth.REQUIRE);\r\n+            }\r\n+        } catch (Exception e) {\r\n+            throw new IllegalArgumentException(\"Could not find certificate file or the certificate is invalid.\", e);\r\n+        }\r\n+        try {\r\n+            return sslClientContextBuilder.sslProvider(findSslProvider()).build();\r\n+        } catch (SSLException e) {\r\n+            throw new IllegalStateException(\"Build SslSession failed.\", e);\r\n+        }\r\n+    }\r\n+\r\n+    public static SslContext buildClientSslContext(URL url) {\r\n+        ConfigManager globalConfigManager = ApplicationModel.getConfigManager();\r\n+        SslConfig sslConfig = globalConfigManager.getSsl().orElseThrow(() -> new IllegalStateException(\"Ssl enabled, but no ssl cert information provided!\"));\r\n+\r\n+        SslContextBuilder builder = SslContextBuilder.forClient();\r\n+        try {\r\n+            if (sslConfig.getClientTrustCertCollectionPathStream() != null) {\r\n+                builder.trustManager(sslConfig.getClientTrustCertCollectionPathStream());\r\n+            }\r\n+\r\n+            InputStream clientCertChainFilePath = sslConfig.getClientKeyCertChainPathStream();\r\n+            InputStream clientPrivateKeyFilePath = sslConfig.getClientPrivateKeyPathStream();\r\n+            if (clientCertChainFilePath != null && clientPrivateKeyFilePath != null) {\r\n+                String password = sslConfig.getClientKeyPassword();\r\n+                if (password != null) {\r\n+                    builder.keyManager(clientCertChainFilePath, clientPrivateKeyFilePath, password);\r\n+                } else {\r\n+                    builder.keyManager(clientCertChainFilePath, clientPrivateKeyFilePath);\r\n+                }\r\n+            }\r\n+        } catch (Exception e) {\r\n+            throw new IllegalArgumentException(\"Could not find certificate file or find invalid certificate.\", e);\r\n+        }\r\n+        try {\r\n+            return builder.sslProvider(findSslProvider()).build();\r\n+        } catch (SSLException e) {\r\n+            throw new IllegalStateException(\"Build SslSession failed.\", e);\r\n+        }\r\n+    }\r\n+\r\n+    /**\r\n+     * Returns OpenSSL if available, otherwise returns the JDK provider.\r\n+     */\r\n+    private static SslProvider findSslProvider() {\r\n+        if (OpenSsl.isAvailable()) {\r\n+            logger.info(\"Using OPENSSL provider.\");\r\n+            return SslProvider.OPENSSL;\r\n+        } else if (checkJdkProvider()) {\r\n+            logger.info(\"Using JDK provider.\");\r\n+            return SslProvider.JDK;\r\n+        }\r\n+        throw new IllegalStateException(\r\n+                \"Could not find any valid TLS provider, please check your dependency or deployment environment, \" +\r\n+                        \"usually netty-tcnative, Conscrypt, or Jetty NPN/ALPN is needed.\");\r\n+    }\r\n+\r\n+    private static boolean checkJdkProvider() {\r\n+        Provider[] jdkProviders = Security.getProviders(\"SSLContext.TLS\");\r\n+        return (jdkProviders != null && jdkProviders.length > 0);\r\n+    }\r\n+\r\n+}\r\n"}, {"source1": "org/apache/dubbo/remoting/transport/netty4/SslHandlerInitializer.java", "source2": "org/apache/dubbo/remoting/transport/netty4/SslHandlerInitializer.java", "comments": ["Ordering differences only"], "unified_diff": "@@ -1,141 +1,141 @@\n-/*\n- * Licensed to the Apache Software Foundation (ASF) under one or more\n- * contributor license agreements.  See the NOTICE file distributed with\n- * this work for additional information regarding copyright ownership.\n- * The ASF licenses this file to You under the Apache License, Version 2.0\n- * (the \"License\"); you may not use this file except in compliance with\n- * the License.  You may obtain a copy of the License at\n- *\n- *     http://www.apache.org/licenses/LICENSE-2.0\n- *\n- * Unless required by applicable law or agreed to in writing, software\n- * distributed under the License is distributed on an \"AS IS\" BASIS,\n- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n- * See the License for the specific language governing permissions and\n- * limitations under the License.\n- */\n-package org.apache.dubbo.remoting.transport.netty4;\n-\n-import org.apache.dubbo.common.URL;\n-import org.apache.dubbo.common.logger.Logger;\n-import org.apache.dubbo.common.logger.LoggerFactory;\n-\n-import io.netty.channel.ChannelHandlerContext;\n-import io.netty.channel.ChannelInboundHandler;\n-import io.netty.channel.ChannelInboundHandlerAdapter;\n-import io.netty.handler.ssl.SslContext;\n-import io.netty.handler.ssl.SslHandler;\n-import io.netty.handler.ssl.SslHandshakeCompletionEvent;\n-\n-import javax.net.ssl.SSLEngine;\n-import javax.net.ssl.SSLSession;\n-\n-/**\n- * Handshake, SSl and Protocol\n- */\n-public class SslHandlerInitializer {\n-\n-    private static final Logger logger = LoggerFactory.getLogger(SslHandlerInitializer.class);\n-\n-    public static ChannelInboundHandler sslServerHandler(URL url, NettyServerHandler serverHandler) {\n-        // Decorate if necessary\n-        return new SslServerTlsHandler(url, serverHandler);\n-    }\n-\n-    public static ChannelInboundHandler sslClientHandler(URL url, NettyClientHandler clientHandler) {\n-        return new SslClientTlsHandler(url, clientHandler);\n-    }\n-\n-    public static class SslServerTlsHandler extends ChannelInboundHandlerAdapter {\n-\n-        private final SslContext sslContext;\n-        private final NettyServerHandler serverHandler;\n-\n-        SslServerTlsHandler(URL url, NettyServerHandler serverHandler) {\n-            this.sslContext = SslContexts.buildServerSslContext(url);\n-            this.serverHandler = serverHandler;\n-        }\n-\n-        @Override\n-        public void handlerAdded(ChannelHandlerContext ctx) throws Exception {\n-            super.handlerAdded(ctx);\n-\n-            SSLEngine sslEngine = sslContext.newEngine(ctx.alloc());\n-            ctx.pipeline().addFirst(new SslHandler(sslEngine, false));\n-        }\n-\n-        @Override\n-        public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {\n-            logger.error(\"TLS negotiation failed when trying to accept new connection.\", cause);\n-        }\n-\n-        @Override\n-        public void userEventTriggered(ChannelHandlerContext ctx, Object evt) throws Exception {\n-            if (evt instanceof SslHandshakeCompletionEvent) {\n-                SslHandshakeCompletionEvent handshakeEvent = (SslHandshakeCompletionEvent) evt;\n-                if (handshakeEvent.isSuccess()) {\n-                    SSLSession session = ctx.pipeline().get(SslHandler.class).engine().getSession();\n-                    logger.info(\"TLS negotiation succeed with session: \" + session);\n-                    serverHandler.handshakeCompleted(new HandshakeCompletionEvent(session, ctx));\n-                    // Remove after handshake success.\n-                    ctx.pipeline().remove(this);\n-                } else {\n-                    logger.error(\"TLS negotiation failed when trying to accept new connection.\", handshakeEvent.cause());\n-                    ctx.close();\n-                }\n-            }\n-            super.userEventTriggered(ctx, evt);\n-        }\n-    }\n-\n-    public static class SslClientTlsHandler extends ChannelInboundHandlerAdapter {\n-\n-        private final SslContext sslContext;\n-        private final NettyClientHandler clientHandler;\n-\n-        public SslClientTlsHandler(URL url, NettyClientHandler clientHandler) {\n-            this.sslContext = SslContexts.buildClientSslContext(url);\n-            this.clientHandler = clientHandler;\n-        }\n-\n-        @Override\n-        public void handlerAdded(ChannelHandlerContext ctx) {\n-            SSLEngine sslEngine = sslContext.newEngine(ctx.alloc());\n-            ctx.pipeline().addBefore(ctx.name(), null, new SslHandler(sslEngine, false));\n-        }\n-\n-        @Override\n-        public void userEventTriggered(ChannelHandlerContext ctx, Object evt) throws Exception {\n-            if (evt instanceof SslHandshakeCompletionEvent) {\n-                SslHandshakeCompletionEvent handshakeEvent = (SslHandshakeCompletionEvent) evt;\n-                if (handshakeEvent.isSuccess()) {\n-                    SSLSession session = ctx.pipeline().get(SslHandler.class).engine().getSession();\n-                    logger.info(\"TLS negotiation succeed with session: \" + session);\n-                    clientHandler.handshakeCompleted(new HandshakeCompletionEvent(session, ctx));\n-                    ctx.pipeline().remove(this);\n-                } else {\n-                    logger.error(\"TLS negotiation failed when trying to accept new connection.\", handshakeEvent.cause());\n-                    ctx.fireExceptionCaught(handshakeEvent.cause());\n-                }\n-            }\n-        }\n-    }\n-\n-    public static class HandshakeCompletionEvent {\n-        private final SSLSession sslSession;\n-        private final ChannelHandlerContext ctx;\n-\n-        public HandshakeCompletionEvent(SSLSession sslSession, ChannelHandlerContext ctx) {\n-            this.sslSession = sslSession;\n-            this.ctx = ctx;\n-        }\n-\n-        public SSLSession getSslSession() {\n-            return sslSession;\n-        }\n-\n-        public ChannelHandlerContext getCtx() {\n-            return ctx;\n-        }\n-    }\n-}\n+/*\r\n+ * Licensed to the Apache Software Foundation (ASF) under one or more\r\n+ * contributor license agreements.  See the NOTICE file distributed with\r\n+ * this work for additional information regarding copyright ownership.\r\n+ * The ASF licenses this file to You under the Apache License, Version 2.0\r\n+ * (the \"License\"); you may not use this file except in compliance with\r\n+ * the License.  You may obtain a copy of the License at\r\n+ *\r\n+ *     http://www.apache.org/licenses/LICENSE-2.0\r\n+ *\r\n+ * Unless required by applicable law or agreed to in writing, software\r\n+ * distributed under the License is distributed on an \"AS IS\" BASIS,\r\n+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r\n+ * See the License for the specific language governing permissions and\r\n+ * limitations under the License.\r\n+ */\r\n+package org.apache.dubbo.remoting.transport.netty4;\r\n+\r\n+import org.apache.dubbo.common.URL;\r\n+import org.apache.dubbo.common.logger.Logger;\r\n+import org.apache.dubbo.common.logger.LoggerFactory;\r\n+\r\n+import io.netty.channel.ChannelHandlerContext;\r\n+import io.netty.channel.ChannelInboundHandler;\r\n+import io.netty.channel.ChannelInboundHandlerAdapter;\r\n+import io.netty.handler.ssl.SslContext;\r\n+import io.netty.handler.ssl.SslHandler;\r\n+import io.netty.handler.ssl.SslHandshakeCompletionEvent;\r\n+\r\n+import javax.net.ssl.SSLEngine;\r\n+import javax.net.ssl.SSLSession;\r\n+\r\n+/**\r\n+ * Handshake, SSl and Protocol\r\n+ */\r\n+public class SslHandlerInitializer {\r\n+\r\n+    private static final Logger logger = LoggerFactory.getLogger(SslHandlerInitializer.class);\r\n+\r\n+    public static ChannelInboundHandler sslServerHandler(URL url, NettyServerHandler serverHandler) {\r\n+        // Decorate if necessary\r\n+        return new SslServerTlsHandler(url, serverHandler);\r\n+    }\r\n+\r\n+    public static ChannelInboundHandler sslClientHandler(URL url, NettyClientHandler clientHandler) {\r\n+        return new SslClientTlsHandler(url, clientHandler);\r\n+    }\r\n+\r\n+    public static class SslServerTlsHandler extends ChannelInboundHandlerAdapter {\r\n+\r\n+        private final SslContext sslContext;\r\n+        private final NettyServerHandler serverHandler;\r\n+\r\n+        SslServerTlsHandler(URL url, NettyServerHandler serverHandler) {\r\n+            this.sslContext = SslContexts.buildServerSslContext(url);\r\n+            this.serverHandler = serverHandler;\r\n+        }\r\n+\r\n+        @Override\r\n+        public void handlerAdded(ChannelHandlerContext ctx) throws Exception {\r\n+            super.handlerAdded(ctx);\r\n+\r\n+            SSLEngine sslEngine = sslContext.newEngine(ctx.alloc());\r\n+            ctx.pipeline().addFirst(new SslHandler(sslEngine, false));\r\n+        }\r\n+\r\n+        @Override\r\n+        public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {\r\n+            logger.error(\"TLS negotiation failed when trying to accept new connection.\", cause);\r\n+        }\r\n+\r\n+        @Override\r\n+        public void userEventTriggered(ChannelHandlerContext ctx, Object evt) throws Exception {\r\n+            if (evt instanceof SslHandshakeCompletionEvent) {\r\n+                SslHandshakeCompletionEvent handshakeEvent = (SslHandshakeCompletionEvent) evt;\r\n+                if (handshakeEvent.isSuccess()) {\r\n+                    SSLSession session = ctx.pipeline().get(SslHandler.class).engine().getSession();\r\n+                    logger.info(\"TLS negotiation succeed with session: \" + session);\r\n+                    serverHandler.handshakeCompleted(new HandshakeCompletionEvent(session, ctx));\r\n+                    // Remove after handshake success.\r\n+                    ctx.pipeline().remove(this);\r\n+                } else {\r\n+                    logger.error(\"TLS negotiation failed when trying to accept new connection.\", handshakeEvent.cause());\r\n+                    ctx.close();\r\n+                }\r\n+            }\r\n+            super.userEventTriggered(ctx, evt);\r\n+        }\r\n+    }\r\n+\r\n+    public static class SslClientTlsHandler extends ChannelInboundHandlerAdapter {\r\n+\r\n+        private final SslContext sslContext;\r\n+        private final NettyClientHandler clientHandler;\r\n+\r\n+        public SslClientTlsHandler(URL url, NettyClientHandler clientHandler) {\r\n+            this.sslContext = SslContexts.buildClientSslContext(url);\r\n+            this.clientHandler = clientHandler;\r\n+        }\r\n+\r\n+        @Override\r\n+        public void handlerAdded(ChannelHandlerContext ctx) {\r\n+            SSLEngine sslEngine = sslContext.newEngine(ctx.alloc());\r\n+            ctx.pipeline().addBefore(ctx.name(), null, new SslHandler(sslEngine, false));\r\n+        }\r\n+\r\n+        @Override\r\n+        public void userEventTriggered(ChannelHandlerContext ctx, Object evt) throws Exception {\r\n+            if (evt instanceof SslHandshakeCompletionEvent) {\r\n+                SslHandshakeCompletionEvent handshakeEvent = (SslHandshakeCompletionEvent) evt;\r\n+                if (handshakeEvent.isSuccess()) {\r\n+                    SSLSession session = ctx.pipeline().get(SslHandler.class).engine().getSession();\r\n+                    logger.info(\"TLS negotiation succeed with session: \" + session);\r\n+                    clientHandler.handshakeCompleted(new HandshakeCompletionEvent(session, ctx));\r\n+                    ctx.pipeline().remove(this);\r\n+                } else {\r\n+                    logger.error(\"TLS negotiation failed when trying to accept new connection.\", handshakeEvent.cause());\r\n+                    ctx.fireExceptionCaught(handshakeEvent.cause());\r\n+                }\r\n+            }\r\n+        }\r\n+    }\r\n+\r\n+    public static class HandshakeCompletionEvent {\r\n+        private final SSLSession sslSession;\r\n+        private final ChannelHandlerContext ctx;\r\n+\r\n+        public HandshakeCompletionEvent(SSLSession sslSession, ChannelHandlerContext ctx) {\r\n+            this.sslSession = sslSession;\r\n+            this.ctx = ctx;\r\n+        }\r\n+\r\n+        public SSLSession getSslSession() {\r\n+            return sslSession;\r\n+        }\r\n+\r\n+        public ChannelHandlerContext getCtx() {\r\n+            return ctx;\r\n+        }\r\n+    }\r\n+}\r\n"}, {"source1": "org/apache/dubbo/remoting/transport/netty4/logging/MessageFormatter.java", "source2": "org/apache/dubbo/remoting/transport/netty4/logging/MessageFormatter.java", "comments": ["Ordering differences only"], "unified_diff": "@@ -1,410 +1,410 @@\n-/*\n- * Licensed to the Apache Software Foundation (ASF) under one or more\n- * contributor license agreements.  See the NOTICE file distributed with\n- * this work for additional information regarding copyright ownership.\n- * The ASF licenses this file to You under the Apache License, Version 2.0\n- * (the \"License\"); you may not use this file except in compliance with\n- * the License.  You may obtain a copy of the License at\n- *\n- *     http://www.apache.org/licenses/LICENSE-2.0\n- *\n- * Unless required by applicable law or agreed to in writing, software\n- * distributed under the License is distributed on an \"AS IS\" BASIS,\n- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n- * See the License for the specific language governing permissions and\n- * limitations under the License.\n- */\n-package org.apache.dubbo.remoting.transport.netty4.logging;\n-\n-import org.apache.dubbo.common.logger.Logger;\n-import org.apache.dubbo.common.logger.LoggerFactory;\n-import org.apache.dubbo.common.utils.ArrayUtils;\n-\n-import java.text.MessageFormat;\n-import java.util.HashMap;\n-import java.util.Map;\n-\n-// contributors: lizongbo: proposed special treatment of array parameter values\n-// Joern Huxhorn: pointed out double[] omission, suggested deep array copy\n-\n-/**\n- * Formats messages according to very simple substitution rules. Substitutions\n- * can be made 1, 2 or more arguments.\n- * <p/>\n- * <p/>\n- * For example,\n- * <p/>\n- * <pre>\n- * MessageFormatter.format(&quot;Hi {}.&quot;, &quot;there&quot;)\n- * </pre>\n- * <p/>\n- * will return the string \"Hi there.\".\n- * <p/>\n- * The {} pair is called the <em>formatting anchor</em>. It serves to designate\n- * the location where arguments need to be substituted within the message\n- * pattern.\n- * <p/>\n- * In case your message contains the '{' or the '}' character, you do not have\n- * to do anything special unless the '}' character immediately follows '{'. For\n- * example,\n- * <p/>\n- * <pre>\n- * MessageFormatter.format(&quot;Set {1,2,3} is not equal to {}.&quot;, &quot;1,2&quot;);\n- * </pre>\n- * <p/>\n- * will return the string \"Set {1,2,3} is not equal to 1,2.\".\n- * <p/>\n- * <p/>\n- * If for whatever reason you need to place the string \"{}\" in the message\n- * without its <em>formatting anchor</em> meaning, then you need to escape the\n- * '{' character with '\\', that is the backslash character. Only the '{'\n- * character should be escaped. There is no need to escape the '}' character.\n- * For example,\n- * <p/>\n- * <pre>\n- * MessageFormatter.format(&quot;Set \\\\{} is not equal to {}.&quot;, &quot;1,2&quot;);\n- * </pre>\n- * <p/>\n- * will return the string \"Set {} is not equal to 1,2.\".\n- * <p/>\n- * <p/>\n- * The escaping behavior just described can be overridden by escaping the escape\n- * character '\\'. Calling\n- * <p/>\n- * <pre>\n- * MessageFormatter.format(&quot;File name is C:\\\\\\\\{}.&quot;, &quot;file.zip&quot;);\n- * </pre>\n- * <p/>\n- * will return the string \"File name is C:\\file.zip\".\n- * <p/>\n- * <p/>\n- * The formatting conventions are different than those of {@link MessageFormat}\n- * which ships with the Java platform. This is justified by the fact that\n- * SLF4J's implementation is 10 times faster than that of {@link MessageFormat}.\n- * This local performance difference is both measurable and significant in the\n- * larger context of the complete logging processing chain.\n- * <p/>\n- * <p/>\n- * See also {@link #format(String, Object)},\n- * {@link #format(String, Object, Object)} and\n- * {@link #arrayFormat(String, Object[])} methods for more details.\n- */\n-final class MessageFormatter {\n-    private static final Logger logger = LoggerFactory.getLogger(MessageFormatter.class);\n-    static final char DELIM_START = '{';\n-    static final char DELIM_STOP = '}';\n-    static final String DELIM_STR = \"{}\";\n-    private static final char ESCAPE_CHAR = '\\\\';\n-\n-    /**\n-     * Performs single argument substitution for the 'messagePattern' passed as\n-     * parameter.\n-     * <p/>\n-     * For example,\n-     * <p/>\n-     * <pre>\n-     * MessageFormatter.format(&quot;Hi {}.&quot;, &quot;there&quot;);\n-     * </pre>\n-     * <p/>\n-     * will return the string \"Hi there.\".\n-     * <p/>\n-     *\n-     * @param messagePattern The message pattern which will be parsed and formatted\n-     * @param arg            The argument to be substituted in place of the formatting anchor\n-     * @return The formatted message\n-     */\n-    static FormattingTuple format(String messagePattern, Object arg) {\n-        return arrayFormat(messagePattern, new Object[]{arg});\n-    }\n-\n-    /**\n-     * Performs a two argument substitution for the 'messagePattern' passed as\n-     * parameter.\n-     * <p/>\n-     * For example,\n-     * <p/>\n-     * <pre>\n-     * MessageFormatter.format(&quot;Hi {}. My name is {}.&quot;, &quot;Alice&quot;, &quot;Bob&quot;);\n-     * </pre>\n-     * <p/>\n-     * will return the string \"Hi Alice. My name is Bob.\".\n-     *\n-     * @param messagePattern The message pattern which will be parsed and formatted\n-     * @param argA           The argument to be substituted in place of the first formatting\n-     *                       anchor\n-     * @param argB           The argument to be substituted in place of the second formatting\n-     *                       anchor\n-     * @return The formatted message\n-     */\n-    static FormattingTuple format(final String messagePattern,\n-                                  Object argA, Object argB) {\n-        return arrayFormat(messagePattern, new Object[]{argA, argB});\n-    }\n-\n-    static Throwable getThrowableCandidate(Object[] argArray) {\n-        if (ArrayUtils.isEmpty(argArray)) {\n-            return null;\n-        }\n-\n-        final Object lastEntry = argArray[argArray.length - 1];\n-        if (lastEntry instanceof Throwable) {\n-            return (Throwable) lastEntry;\n-        }\n-        return null;\n-    }\n-\n-    /**\n-     * Same principle as the {@link #format(String, Object)} and\n-     * {@link #format(String, Object, Object)} methods except that any number of\n-     * arguments can be passed in an array.\n-     *\n-     * @param messagePattern The message pattern which will be parsed and formatted\n-     * @param argArray       An array of arguments to be substituted in place of formatting\n-     *                       anchors\n-     * @return The formatted message\n-     */\n-    static FormattingTuple arrayFormat(final String messagePattern,\n-                                       final Object[] argArray) {\n-\n-        Throwable throwableCandidate = getThrowableCandidate(argArray);\n-\n-        if (messagePattern == null) {\n-            return new FormattingTuple(null, argArray, throwableCandidate);\n-        }\n-\n-        if (argArray == null) {\n-            return new FormattingTuple(messagePattern);\n-        }\n-\n-        int i = 0;\n-        int j;\n-        StringBuffer sbuf = new StringBuffer(messagePattern.length() + 50);\n-\n-        int l;\n-        for (l = 0; l < argArray.length; l++) {\n-\n-            j = messagePattern.indexOf(DELIM_STR, i);\n-\n-            if (j == -1) {\n-                // no more variables\n-                if (i == 0) { // this is a simple string\n-                    return new FormattingTuple(messagePattern, argArray,\n-                            throwableCandidate);\n-                } else { // add the tail string which contains no variables and return\n-                    // the result.\n-                    sbuf.append(messagePattern.substring(i));\n-                    return new FormattingTuple(sbuf.toString(), argArray,\n-                            throwableCandidate);\n-                }\n-            } else {\n-                if (isEscapedDelimiter(messagePattern, j)) {\n-                    if (!isDoubleEscaped(messagePattern, j)) {\n-                        l--; // DELIM_START was escaped, thus should not be incremented\n-                        sbuf.append(messagePattern, i, j - 1);\n-                        sbuf.append(DELIM_START);\n-                        i = j + 1;\n-                    } else {\n-                        // The escape character preceding the delimiter start is\n-                        // itself escaped: \"abc x:\\\\{}\"\n-                        // we have to consume one backward slash\n-                        sbuf.append(messagePattern, i, j - 1);\n-                        deeplyAppendParameter(sbuf, argArray[l], new HashMap<Object[], Void>());\n-                        i = j + 2;\n-                    }\n-                } else {\n-                    // normal case\n-                    sbuf.append(messagePattern, i, j);\n-                    deeplyAppendParameter(sbuf, argArray[l], new HashMap<Object[], Void>());\n-                    i = j + 2;\n-                }\n-            }\n-        }\n-        // append the characters following the last {} pair.\n-        sbuf.append(messagePattern.substring(i));\n-        if (l < argArray.length - 1) {\n-            return new FormattingTuple(sbuf.toString(), argArray, throwableCandidate);\n-        } else {\n-            return new FormattingTuple(sbuf.toString(), argArray, null);\n-        }\n-    }\n-\n-    static boolean isEscapedDelimiter(String messagePattern,\n-                                      int delimiterStartIndex) {\n-\n-        if (delimiterStartIndex == 0) {\n-            return false;\n-        }\n-        return messagePattern.charAt(delimiterStartIndex - 1) == ESCAPE_CHAR;\n-    }\n-\n-    static boolean isDoubleEscaped(String messagePattern,\n-                                   int delimiterStartIndex) {\n-        return delimiterStartIndex >= 2 && messagePattern.charAt(delimiterStartIndex - 2) == ESCAPE_CHAR;\n-    }\n-\n-    // special treatment of array values was suggested by 'lizongbo'\n-    private static void deeplyAppendParameter(StringBuffer sbuf, Object o,\n-                                              Map<Object[], Void> seenMap) {\n-        if (o == null) {\n-            sbuf.append(\"null\");\n-            return;\n-        }\n-        if (!o.getClass().isArray()) {\n-            safeObjectAppend(sbuf, o);\n-        } else {\n-            // check for primitive array types because they\n-            // unfortunately cannot be cast to Object[]\n-            if (o instanceof boolean[]) {\n-                booleanArrayAppend(sbuf, (boolean[]) o);\n-            } else if (o instanceof byte[]) {\n-                byteArrayAppend(sbuf, (byte[]) o);\n-            } else if (o instanceof char[]) {\n-                charArrayAppend(sbuf, (char[]) o);\n-            } else if (o instanceof short[]) {\n-                shortArrayAppend(sbuf, (short[]) o);\n-            } else if (o instanceof int[]) {\n-                intArrayAppend(sbuf, (int[]) o);\n-            } else if (o instanceof long[]) {\n-                longArrayAppend(sbuf, (long[]) o);\n-            } else if (o instanceof float[]) {\n-                floatArrayAppend(sbuf, (float[]) o);\n-            } else if (o instanceof double[]) {\n-                doubleArrayAppend(sbuf, (double[]) o);\n-            } else {\n-                objectArrayAppend(sbuf, (Object[]) o, seenMap);\n-            }\n-        }\n-    }\n-\n-    private static void safeObjectAppend(StringBuffer sbuf, Object o) {\n-        try {\n-            String oAsString = o.toString();\n-            sbuf.append(oAsString);\n-        } catch (Throwable t) {\n-            System.err\n-                    .println(\"SLF4J: Failed toString() invocation on an object of type [\"\n-                            + o.getClass().getName() + ']');\n-            logger.error(t.getMessage(), t);\n-            sbuf.append(\"[FAILED toString()]\");\n-        }\n-    }\n-\n-    private static void objectArrayAppend(StringBuffer sbuf, Object[] a,\n-                                          Map<Object[], Void> seenMap) {\n-        sbuf.append('[');\n-        if (!seenMap.containsKey(a)) {\n-            seenMap.put(a, null);\n-            final int len = a.length;\n-            for (int i = 0; i < len; i++) {\n-                deeplyAppendParameter(sbuf, a[i], seenMap);\n-                if (i != len - 1) {\n-                    sbuf.append(\", \");\n-                }\n-            }\n-            // allow repeats in siblings\n-            seenMap.remove(a);\n-        } else {\n-            sbuf.append(\"...\");\n-        }\n-        sbuf.append(']');\n-    }\n-\n-    private static void booleanArrayAppend(StringBuffer sbuf, boolean[] a) {\n-        sbuf.append('[');\n-        final int len = a.length;\n-        for (int i = 0; i < len; i++) {\n-            sbuf.append(a[i]);\n-            if (i != len - 1) {\n-                sbuf.append(\", \");\n-            }\n-        }\n-        sbuf.append(']');\n-    }\n-\n-    private static void byteArrayAppend(StringBuffer sbuf, byte[] a) {\n-        sbuf.append('[');\n-        final int len = a.length;\n-        for (int i = 0; i < len; i++) {\n-            sbuf.append(a[i]);\n-            if (i != len - 1) {\n-                sbuf.append(\", \");\n-            }\n-        }\n-        sbuf.append(']');\n-    }\n-\n-    private static void charArrayAppend(StringBuffer sbuf, char[] a) {\n-        sbuf.append('[');\n-        final int len = a.length;\n-        for (int i = 0; i < len; i++) {\n-            sbuf.append(a[i]);\n-            if (i != len - 1) {\n-                sbuf.append(\", \");\n-            }\n-        }\n-        sbuf.append(']');\n-    }\n-\n-    private static void shortArrayAppend(StringBuffer sbuf, short[] a) {\n-        sbuf.append('[');\n-        final int len = a.length;\n-        for (int i = 0; i < len; i++) {\n-            sbuf.append(a[i]);\n-            if (i != len - 1) {\n-                sbuf.append(\", \");\n-            }\n-        }\n-        sbuf.append(']');\n-    }\n-\n-    private static void intArrayAppend(StringBuffer sbuf, int[] a) {\n-        sbuf.append('[');\n-        final int len = a.length;\n-        for (int i = 0; i < len; i++) {\n-            sbuf.append(a[i]);\n-            if (i != len - 1) {\n-                sbuf.append(\", \");\n-            }\n-        }\n-        sbuf.append(']');\n-    }\n-\n-    private static void longArrayAppend(StringBuffer sbuf, long[] a) {\n-        sbuf.append('[');\n-        final int len = a.length;\n-        for (int i = 0; i < len; i++) {\n-            sbuf.append(a[i]);\n-            if (i != len - 1) {\n-                sbuf.append(\", \");\n-            }\n-        }\n-        sbuf.append(']');\n-    }\n-\n-    private static void floatArrayAppend(StringBuffer sbuf, float[] a) {\n-        sbuf.append('[');\n-        final int len = a.length;\n-        for (int i = 0; i < len; i++) {\n-            sbuf.append(a[i]);\n-            if (i != len - 1) {\n-                sbuf.append(\", \");\n-            }\n-        }\n-        sbuf.append(']');\n-    }\n-\n-    private static void doubleArrayAppend(StringBuffer sbuf, double[] a) {\n-        sbuf.append('[');\n-        final int len = a.length;\n-        for (int i = 0; i < len; i++) {\n-            sbuf.append(a[i]);\n-            if (i != len - 1) {\n-                sbuf.append(\", \");\n-            }\n-        }\n-        sbuf.append(']');\n-    }\n-\n-    private MessageFormatter() {\n-    }\n-}\n+/*\r\n+ * Licensed to the Apache Software Foundation (ASF) under one or more\r\n+ * contributor license agreements.  See the NOTICE file distributed with\r\n+ * this work for additional information regarding copyright ownership.\r\n+ * The ASF licenses this file to You under the Apache License, Version 2.0\r\n+ * (the \"License\"); you may not use this file except in compliance with\r\n+ * the License.  You may obtain a copy of the License at\r\n+ *\r\n+ *     http://www.apache.org/licenses/LICENSE-2.0\r\n+ *\r\n+ * Unless required by applicable law or agreed to in writing, software\r\n+ * distributed under the License is distributed on an \"AS IS\" BASIS,\r\n+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r\n+ * See the License for the specific language governing permissions and\r\n+ * limitations under the License.\r\n+ */\r\n+package org.apache.dubbo.remoting.transport.netty4.logging;\r\n+\r\n+import org.apache.dubbo.common.logger.Logger;\r\n+import org.apache.dubbo.common.logger.LoggerFactory;\r\n+import org.apache.dubbo.common.utils.ArrayUtils;\r\n+\r\n+import java.text.MessageFormat;\r\n+import java.util.HashMap;\r\n+import java.util.Map;\r\n+\r\n+// contributors: lizongbo: proposed special treatment of array parameter values\r\n+// Joern Huxhorn: pointed out double[] omission, suggested deep array copy\r\n+\r\n+/**\r\n+ * Formats messages according to very simple substitution rules. Substitutions\r\n+ * can be made 1, 2 or more arguments.\r\n+ * <p/>\r\n+ * <p/>\r\n+ * For example,\r\n+ * <p/>\r\n+ * <pre>\r\n+ * MessageFormatter.format(&quot;Hi {}.&quot;, &quot;there&quot;)\r\n+ * </pre>\r\n+ * <p/>\r\n+ * will return the string \"Hi there.\".\r\n+ * <p/>\r\n+ * The {} pair is called the <em>formatting anchor</em>. It serves to designate\r\n+ * the location where arguments need to be substituted within the message\r\n+ * pattern.\r\n+ * <p/>\r\n+ * In case your message contains the '{' or the '}' character, you do not have\r\n+ * to do anything special unless the '}' character immediately follows '{'. For\r\n+ * example,\r\n+ * <p/>\r\n+ * <pre>\r\n+ * MessageFormatter.format(&quot;Set {1,2,3} is not equal to {}.&quot;, &quot;1,2&quot;);\r\n+ * </pre>\r\n+ * <p/>\r\n+ * will return the string \"Set {1,2,3} is not equal to 1,2.\".\r\n+ * <p/>\r\n+ * <p/>\r\n+ * If for whatever reason you need to place the string \"{}\" in the message\r\n+ * without its <em>formatting anchor</em> meaning, then you need to escape the\r\n+ * '{' character with '\\', that is the backslash character. Only the '{'\r\n+ * character should be escaped. There is no need to escape the '}' character.\r\n+ * For example,\r\n+ * <p/>\r\n+ * <pre>\r\n+ * MessageFormatter.format(&quot;Set \\\\{} is not equal to {}.&quot;, &quot;1,2&quot;);\r\n+ * </pre>\r\n+ * <p/>\r\n+ * will return the string \"Set {} is not equal to 1,2.\".\r\n+ * <p/>\r\n+ * <p/>\r\n+ * The escaping behavior just described can be overridden by escaping the escape\r\n+ * character '\\'. Calling\r\n+ * <p/>\r\n+ * <pre>\r\n+ * MessageFormatter.format(&quot;File name is C:\\\\\\\\{}.&quot;, &quot;file.zip&quot;);\r\n+ * </pre>\r\n+ * <p/>\r\n+ * will return the string \"File name is C:\\file.zip\".\r\n+ * <p/>\r\n+ * <p/>\r\n+ * The formatting conventions are different than those of {@link MessageFormat}\r\n+ * which ships with the Java platform. This is justified by the fact that\r\n+ * SLF4J's implementation is 10 times faster than that of {@link MessageFormat}.\r\n+ * This local performance difference is both measurable and significant in the\r\n+ * larger context of the complete logging processing chain.\r\n+ * <p/>\r\n+ * <p/>\r\n+ * See also {@link #format(String, Object)},\r\n+ * {@link #format(String, Object, Object)} and\r\n+ * {@link #arrayFormat(String, Object[])} methods for more details.\r\n+ */\r\n+final class MessageFormatter {\r\n+    private static final Logger logger = LoggerFactory.getLogger(MessageFormatter.class);\r\n+    static final char DELIM_START = '{';\r\n+    static final char DELIM_STOP = '}';\r\n+    static final String DELIM_STR = \"{}\";\r\n+    private static final char ESCAPE_CHAR = '\\\\';\r\n+\r\n+    /**\r\n+     * Performs single argument substitution for the 'messagePattern' passed as\r\n+     * parameter.\r\n+     * <p/>\r\n+     * For example,\r\n+     * <p/>\r\n+     * <pre>\r\n+     * MessageFormatter.format(&quot;Hi {}.&quot;, &quot;there&quot;);\r\n+     * </pre>\r\n+     * <p/>\r\n+     * will return the string \"Hi there.\".\r\n+     * <p/>\r\n+     *\r\n+     * @param messagePattern The message pattern which will be parsed and formatted\r\n+     * @param arg            The argument to be substituted in place of the formatting anchor\r\n+     * @return The formatted message\r\n+     */\r\n+    static FormattingTuple format(String messagePattern, Object arg) {\r\n+        return arrayFormat(messagePattern, new Object[]{arg});\r\n+    }\r\n+\r\n+    /**\r\n+     * Performs a two argument substitution for the 'messagePattern' passed as\r\n+     * parameter.\r\n+     * <p/>\r\n+     * For example,\r\n+     * <p/>\r\n+     * <pre>\r\n+     * MessageFormatter.format(&quot;Hi {}. My name is {}.&quot;, &quot;Alice&quot;, &quot;Bob&quot;);\r\n+     * </pre>\r\n+     * <p/>\r\n+     * will return the string \"Hi Alice. My name is Bob.\".\r\n+     *\r\n+     * @param messagePattern The message pattern which will be parsed and formatted\r\n+     * @param argA           The argument to be substituted in place of the first formatting\r\n+     *                       anchor\r\n+     * @param argB           The argument to be substituted in place of the second formatting\r\n+     *                       anchor\r\n+     * @return The formatted message\r\n+     */\r\n+    static FormattingTuple format(final String messagePattern,\r\n+                                  Object argA, Object argB) {\r\n+        return arrayFormat(messagePattern, new Object[]{argA, argB});\r\n+    }\r\n+\r\n+    static Throwable getThrowableCandidate(Object[] argArray) {\r\n+        if (ArrayUtils.isEmpty(argArray)) {\r\n+            return null;\r\n+        }\r\n+\r\n+        final Object lastEntry = argArray[argArray.length - 1];\r\n+        if (lastEntry instanceof Throwable) {\r\n+            return (Throwable) lastEntry;\r\n+        }\r\n+        return null;\r\n+    }\r\n+\r\n+    /**\r\n+     * Same principle as the {@link #format(String, Object)} and\r\n+     * {@link #format(String, Object, Object)} methods except that any number of\r\n+     * arguments can be passed in an array.\r\n+     *\r\n+     * @param messagePattern The message pattern which will be parsed and formatted\r\n+     * @param argArray       An array of arguments to be substituted in place of formatting\r\n+     *                       anchors\r\n+     * @return The formatted message\r\n+     */\r\n+    static FormattingTuple arrayFormat(final String messagePattern,\r\n+                                       final Object[] argArray) {\r\n+\r\n+        Throwable throwableCandidate = getThrowableCandidate(argArray);\r\n+\r\n+        if (messagePattern == null) {\r\n+            return new FormattingTuple(null, argArray, throwableCandidate);\r\n+        }\r\n+\r\n+        if (argArray == null) {\r\n+            return new FormattingTuple(messagePattern);\r\n+        }\r\n+\r\n+        int i = 0;\r\n+        int j;\r\n+        StringBuffer sbuf = new StringBuffer(messagePattern.length() + 50);\r\n+\r\n+        int l;\r\n+        for (l = 0; l < argArray.length; l++) {\r\n+\r\n+            j = messagePattern.indexOf(DELIM_STR, i);\r\n+\r\n+            if (j == -1) {\r\n+                // no more variables\r\n+                if (i == 0) { // this is a simple string\r\n+                    return new FormattingTuple(messagePattern, argArray,\r\n+                            throwableCandidate);\r\n+                } else { // add the tail string which contains no variables and return\r\n+                    // the result.\r\n+                    sbuf.append(messagePattern.substring(i));\r\n+                    return new FormattingTuple(sbuf.toString(), argArray,\r\n+                            throwableCandidate);\r\n+                }\r\n+            } else {\r\n+                if (isEscapedDelimiter(messagePattern, j)) {\r\n+                    if (!isDoubleEscaped(messagePattern, j)) {\r\n+                        l--; // DELIM_START was escaped, thus should not be incremented\r\n+                        sbuf.append(messagePattern, i, j - 1);\r\n+                        sbuf.append(DELIM_START);\r\n+                        i = j + 1;\r\n+                    } else {\r\n+                        // The escape character preceding the delimiter start is\r\n+                        // itself escaped: \"abc x:\\\\{}\"\r\n+                        // we have to consume one backward slash\r\n+                        sbuf.append(messagePattern, i, j - 1);\r\n+                        deeplyAppendParameter(sbuf, argArray[l], new HashMap<Object[], Void>());\r\n+                        i = j + 2;\r\n+                    }\r\n+                } else {\r\n+                    // normal case\r\n+                    sbuf.append(messagePattern, i, j);\r\n+                    deeplyAppendParameter(sbuf, argArray[l], new HashMap<Object[], Void>());\r\n+                    i = j + 2;\r\n+                }\r\n+            }\r\n+        }\r\n+        // append the characters following the last {} pair.\r\n+        sbuf.append(messagePattern.substring(i));\r\n+        if (l < argArray.length - 1) {\r\n+            return new FormattingTuple(sbuf.toString(), argArray, throwableCandidate);\r\n+        } else {\r\n+            return new FormattingTuple(sbuf.toString(), argArray, null);\r\n+        }\r\n+    }\r\n+\r\n+    static boolean isEscapedDelimiter(String messagePattern,\r\n+                                      int delimiterStartIndex) {\r\n+\r\n+        if (delimiterStartIndex == 0) {\r\n+            return false;\r\n+        }\r\n+        return messagePattern.charAt(delimiterStartIndex - 1) == ESCAPE_CHAR;\r\n+    }\r\n+\r\n+    static boolean isDoubleEscaped(String messagePattern,\r\n+                                   int delimiterStartIndex) {\r\n+        return delimiterStartIndex >= 2 && messagePattern.charAt(delimiterStartIndex - 2) == ESCAPE_CHAR;\r\n+    }\r\n+\r\n+    // special treatment of array values was suggested by 'lizongbo'\r\n+    private static void deeplyAppendParameter(StringBuffer sbuf, Object o,\r\n+                                              Map<Object[], Void> seenMap) {\r\n+        if (o == null) {\r\n+            sbuf.append(\"null\");\r\n+            return;\r\n+        }\r\n+        if (!o.getClass().isArray()) {\r\n+            safeObjectAppend(sbuf, o);\r\n+        } else {\r\n+            // check for primitive array types because they\r\n+            // unfortunately cannot be cast to Object[]\r\n+            if (o instanceof boolean[]) {\r\n+                booleanArrayAppend(sbuf, (boolean[]) o);\r\n+            } else if (o instanceof byte[]) {\r\n+                byteArrayAppend(sbuf, (byte[]) o);\r\n+            } else if (o instanceof char[]) {\r\n+                charArrayAppend(sbuf, (char[]) o);\r\n+            } else if (o instanceof short[]) {\r\n+                shortArrayAppend(sbuf, (short[]) o);\r\n+            } else if (o instanceof int[]) {\r\n+                intArrayAppend(sbuf, (int[]) o);\r\n+            } else if (o instanceof long[]) {\r\n+                longArrayAppend(sbuf, (long[]) o);\r\n+            } else if (o instanceof float[]) {\r\n+                floatArrayAppend(sbuf, (float[]) o);\r\n+            } else if (o instanceof double[]) {\r\n+                doubleArrayAppend(sbuf, (double[]) o);\r\n+            } else {\r\n+                objectArrayAppend(sbuf, (Object[]) o, seenMap);\r\n+            }\r\n+        }\r\n+    }\r\n+\r\n+    private static void safeObjectAppend(StringBuffer sbuf, Object o) {\r\n+        try {\r\n+            String oAsString = o.toString();\r\n+            sbuf.append(oAsString);\r\n+        } catch (Throwable t) {\r\n+            System.err\r\n+                    .println(\"SLF4J: Failed toString() invocation on an object of type [\"\r\n+                            + o.getClass().getName() + ']');\r\n+            logger.error(t.getMessage(), t);\r\n+            sbuf.append(\"[FAILED toString()]\");\r\n+        }\r\n+    }\r\n+\r\n+    private static void objectArrayAppend(StringBuffer sbuf, Object[] a,\r\n+                                          Map<Object[], Void> seenMap) {\r\n+        sbuf.append('[');\r\n+        if (!seenMap.containsKey(a)) {\r\n+            seenMap.put(a, null);\r\n+            final int len = a.length;\r\n+            for (int i = 0; i < len; i++) {\r\n+                deeplyAppendParameter(sbuf, a[i], seenMap);\r\n+                if (i != len - 1) {\r\n+                    sbuf.append(\", \");\r\n+                }\r\n+            }\r\n+            // allow repeats in siblings\r\n+            seenMap.remove(a);\r\n+        } else {\r\n+            sbuf.append(\"...\");\r\n+        }\r\n+        sbuf.append(']');\r\n+    }\r\n+\r\n+    private static void booleanArrayAppend(StringBuffer sbuf, boolean[] a) {\r\n+        sbuf.append('[');\r\n+        final int len = a.length;\r\n+        for (int i = 0; i < len; i++) {\r\n+            sbuf.append(a[i]);\r\n+            if (i != len - 1) {\r\n+                sbuf.append(\", \");\r\n+            }\r\n+        }\r\n+        sbuf.append(']');\r\n+    }\r\n+\r\n+    private static void byteArrayAppend(StringBuffer sbuf, byte[] a) {\r\n+        sbuf.append('[');\r\n+        final int len = a.length;\r\n+        for (int i = 0; i < len; i++) {\r\n+            sbuf.append(a[i]);\r\n+            if (i != len - 1) {\r\n+                sbuf.append(\", \");\r\n+            }\r\n+        }\r\n+        sbuf.append(']');\r\n+    }\r\n+\r\n+    private static void charArrayAppend(StringBuffer sbuf, char[] a) {\r\n+        sbuf.append('[');\r\n+        final int len = a.length;\r\n+        for (int i = 0; i < len; i++) {\r\n+            sbuf.append(a[i]);\r\n+            if (i != len - 1) {\r\n+                sbuf.append(\", \");\r\n+            }\r\n+        }\r\n+        sbuf.append(']');\r\n+    }\r\n+\r\n+    private static void shortArrayAppend(StringBuffer sbuf, short[] a) {\r\n+        sbuf.append('[');\r\n+        final int len = a.length;\r\n+        for (int i = 0; i < len; i++) {\r\n+            sbuf.append(a[i]);\r\n+            if (i != len - 1) {\r\n+                sbuf.append(\", \");\r\n+            }\r\n+        }\r\n+        sbuf.append(']');\r\n+    }\r\n+\r\n+    private static void intArrayAppend(StringBuffer sbuf, int[] a) {\r\n+        sbuf.append('[');\r\n+        final int len = a.length;\r\n+        for (int i = 0; i < len; i++) {\r\n+            sbuf.append(a[i]);\r\n+            if (i != len - 1) {\r\n+                sbuf.append(\", \");\r\n+            }\r\n+        }\r\n+        sbuf.append(']');\r\n+    }\r\n+\r\n+    private static void longArrayAppend(StringBuffer sbuf, long[] a) {\r\n+        sbuf.append('[');\r\n+        final int len = a.length;\r\n+        for (int i = 0; i < len; i++) {\r\n+            sbuf.append(a[i]);\r\n+            if (i != len - 1) {\r\n+                sbuf.append(\", \");\r\n+            }\r\n+        }\r\n+        sbuf.append(']');\r\n+    }\r\n+\r\n+    private static void floatArrayAppend(StringBuffer sbuf, float[] a) {\r\n+        sbuf.append('[');\r\n+        final int len = a.length;\r\n+        for (int i = 0; i < len; i++) {\r\n+            sbuf.append(a[i]);\r\n+            if (i != len - 1) {\r\n+                sbuf.append(\", \");\r\n+            }\r\n+        }\r\n+        sbuf.append(']');\r\n+    }\r\n+\r\n+    private static void doubleArrayAppend(StringBuffer sbuf, double[] a) {\r\n+        sbuf.append('[');\r\n+        final int len = a.length;\r\n+        for (int i = 0; i < len; i++) {\r\n+            sbuf.append(a[i]);\r\n+            if (i != len - 1) {\r\n+                sbuf.append(\", \");\r\n+            }\r\n+        }\r\n+        sbuf.append(']');\r\n+    }\r\n+\r\n+    private MessageFormatter() {\r\n+    }\r\n+}\r\n"}, {"source1": "META-INF/maven/org.apache.dubbo/dubbo-remoting-netty4/pom.xml", "source2": "META-INF/maven/org.apache.dubbo/dubbo-remoting-netty4/pom.xml", "comments": ["Format-specific differences are supported for XML files but no file-specific differences were detected; falling back to a binary diff. file(1) reports: XML 1.0 document, ASCII text, with CRLF line terminators"], "has_internal_linenos": true, "unified_diff": "@@ -1,150 +1,147 @@\n 00000000: 3c3f 786d 6c20 7665 7273 696f 6e3d 2231  <?xml version=\"1\n 00000010: 2e30 2220 656e 636f 6469 6e67 3d22 5554  .0\" encoding=\"UT\n-00000020: 462d 3822 3f3e 0d0a 3c21 2d2d 0d0a 2020  F-8\"?>..<!--..  \n-00000030: 4c69 6365 6e73 6564 2074 6f20 7468 6520  Licensed to the \n-00000040: 4170 6163 6865 2053 6f66 7477 6172 6520  Apache Software \n-00000050: 466f 756e 6461 7469 6f6e 2028 4153 4629  Foundation (ASF)\n-00000060: 2075 6e64 6572 206f 6e65 206f 7220 6d6f   under one or mo\n-00000070: 7265 0d0a 2020 636f 6e74 7269 6275 746f  re..  contributo\n-00000080: 7220 6c69 6365 6e73 6520 6167 7265 656d  r license agreem\n-00000090: 656e 7473 2e20 2053 6565 2074 6865 204e  ents.  See the N\n-000000a0: 4f54 4943 4520 6669 6c65 2064 6973 7472  OTICE file distr\n-000000b0: 6962 7574 6564 2077 6974 680d 0a20 2074  ibuted with..  t\n-000000c0: 6869 7320 776f 726b 2066 6f72 2061 6464  his work for add\n-000000d0: 6974 696f 6e61 6c20 696e 666f 726d 6174  itional informat\n-000000e0: 696f 6e20 7265 6761 7264 696e 6720 636f  ion regarding co\n-000000f0: 7079 7269 6768 7420 6f77 6e65 7273 6869  pyright ownershi\n-00000100: 702e 0d0a 2020 5468 6520 4153 4620 6c69  p...  The ASF li\n-00000110: 6365 6e73 6573 2074 6869 7320 6669 6c65  censes this file\n-00000120: 2074 6f20 596f 7520 756e 6465 7220 7468   to You under th\n-00000130: 6520 4170 6163 6865 204c 6963 656e 7365  e Apache License\n-00000140: 2c20 5665 7273 696f 6e20 322e 300d 0a20  , Version 2.0.. \n-00000150: 2028 7468 6520 224c 6963 656e 7365 2229   (the \"License\")\n-00000160: 3b20 796f 7520 6d61 7920 6e6f 7420 7573  ; you may not us\n-00000170: 6520 7468 6973 2066 696c 6520 6578 6365  e this file exce\n-00000180: 7074 2069 6e20 636f 6d70 6c69 616e 6365  pt in compliance\n-00000190: 2077 6974 680d 0a20 2074 6865 204c 6963   with..  the Lic\n-000001a0: 656e 7365 2e20 2059 6f75 206d 6179 206f  ense.  You may o\n-000001b0: 6274 6169 6e20 6120 636f 7079 206f 6620  btain a copy of \n-000001c0: 7468 6520 4c69 6365 6e73 6520 6174 0d0a  the License at..\n-000001d0: 0d0a 2020 2020 2020 6874 7470 3a2f 2f77  ..      http://w\n-000001e0: 7777 2e61 7061 6368 652e 6f72 672f 6c69  ww.apache.org/li\n-000001f0: 6365 6e73 6573 2f4c 4943 454e 5345 2d32  censes/LICENSE-2\n-00000200: 2e30 0d0a 0d0a 2020 556e 6c65 7373 2072  .0....  Unless r\n-00000210: 6571 7569 7265 6420 6279 2061 7070 6c69  equired by appli\n-00000220: 6361 626c 6520 6c61 7720 6f72 2061 6772  cable law or agr\n-00000230: 6565 6420 746f 2069 6e20 7772 6974 696e  eed to in writin\n-00000240: 672c 2073 6f66 7477 6172 650d 0a20 2064  g, software..  d\n-00000250: 6973 7472 6962 7574 6564 2075 6e64 6572  istributed under\n-00000260: 2074 6865 204c 6963 656e 7365 2069 7320   the License is \n-00000270: 6469 7374 7269 6275 7465 6420 6f6e 2061  distributed on a\n-00000280: 6e20 2241 5320 4953 2220 4241 5349 532c  n \"AS IS\" BASIS,\n-00000290: 0d0a 2020 5749 5448 4f55 5420 5741 5252  ..  WITHOUT WARR\n-000002a0: 414e 5449 4553 204f 5220 434f 4e44 4954  ANTIES OR CONDIT\n-000002b0: 494f 4e53 204f 4620 414e 5920 4b49 4e44  IONS OF ANY KIND\n-000002c0: 2c20 6569 7468 6572 2065 7870 7265 7373  , either express\n-000002d0: 206f 7220 696d 706c 6965 642e 0d0a 2020   or implied...  \n-000002e0: 5365 6520 7468 6520 4c69 6365 6e73 6520  See the License \n-000002f0: 666f 7220 7468 6520 7370 6563 6966 6963  for the specific\n-00000300: 206c 616e 6775 6167 6520 676f 7665 726e   language govern\n-00000310: 696e 6720 7065 726d 6973 7369 6f6e 7320  ing permissions \n-00000320: 616e 640d 0a20 206c 696d 6974 6174 696f  and..  limitatio\n-00000330: 6e73 2075 6e64 6572 2074 6865 204c 6963  ns under the Lic\n-00000340: 656e 7365 2e0d 0a20 202d 2d3e 0d0a 3c70  ense...  -->..<p\n-00000350: 726f 6a65 6374 2078 7369 3a73 6368 656d  roject xsi:schem\n-00000360: 614c 6f63 6174 696f 6e3d 2268 7474 703a  aLocation=\"http:\n-00000370: 2f2f 6d61 7665 6e2e 6170 6163 6865 2e6f  //maven.apache.o\n-00000380: 7267 2f50 4f4d 2f34 2e30 2e30 2068 7474  rg/POM/4.0.0 htt\n-00000390: 7073 3a2f 2f6d 6176 656e 2e61 7061 6368  ps://maven.apach\n-000003a0: 652e 6f72 672f 7873 642f 6d61 7665 6e2d  e.org/xsd/maven-\n-000003b0: 342e 302e 302e 7873 6422 2078 6d6c 6e73  4.0.0.xsd\" xmlns\n-000003c0: 3d22 6874 7470 3a2f 2f6d 6176 656e 2e61  =\"http://maven.a\n-000003d0: 7061 6368 652e 6f72 672f 504f 4d2f 342e  pache.org/POM/4.\n-000003e0: 302e 3022 0d0a 2020 2020 786d 6c6e 733a  0.0\"..    xmlns:\n-000003f0: 7873 693d 2268 7474 703a 2f2f 7777 772e  xsi=\"http://www.\n-00000400: 7733 2e6f 7267 2f32 3030 312f 584d 4c53  w3.org/2001/XMLS\n-00000410: 6368 656d 612d 696e 7374 616e 6365 223e  chema-instance\">\n-00000420: 0d0a 2020 3c6d 6f64 656c 5665 7273 696f  ..  <modelVersio\n-00000430: 6e3e 342e 302e 303c 2f6d 6f64 656c 5665  n>4.0.0</modelVe\n-00000440: 7273 696f 6e3e 0d0a 2020 3c70 6172 656e  rsion>..  <paren\n-00000450: 743e 0d0a 2020 2020 3c67 726f 7570 4964  t>..    <groupId\n-00000460: 3e6f 7267 2e61 7061 6368 652e 6475 6262  >org.apache.dubb\n-00000470: 6f3c 2f67 726f 7570 4964 3e0d 0a20 2020  o</groupId>..   \n-00000480: 203c 6172 7469 6661 6374 4964 3e64 7562   <artifactId>dub\n-00000490: 626f 2d72 656d 6f74 696e 673c 2f61 7274  bo-remoting</art\n-000004a0: 6966 6163 7449 643e 0d0a 2020 2020 3c76  ifactId>..    <v\n-000004b0: 6572 7369 6f6e 3e32 2e37 2e31 303c 2f76  ersion>2.7.10</v\n-000004c0: 6572 7369 6f6e 3e0d 0a20 203c 2f70 6172  ersion>..  </par\n-000004d0: 656e 743e 0d0a 2020 3c67 726f 7570 4964  ent>..  <groupId\n-000004e0: 3e6f 7267 2e61 7061 6368 652e 6475 6262  >org.apache.dubb\n-000004f0: 6f3c 2f67 726f 7570 4964 3e0d 0a20 203c  o</groupId>..  <\n-00000500: 6172 7469 6661 6374 4964 3e64 7562 626f  artifactId>dubbo\n-00000510: 2d72 656d 6f74 696e 672d 6e65 7474 7934  -remoting-netty4\n-00000520: 3c2f 6172 7469 6661 6374 4964 3e0d 0a20  </artifactId>.. \n-00000530: 203c 7665 7273 696f 6e3e 322e 372e 3130   <version>2.7.10\n-00000540: 3c2f 7665 7273 696f 6e3e 0d0a 2020 3c6e  </version>..  <n\n-00000550: 616d 653e 247b 7072 6f6a 6563 742e 6172  ame>${project.ar\n-00000560: 7469 6661 6374 4964 7d3c 2f6e 616d 653e  tifactId}</name>\n-00000570: 0d0a 2020 3c64 6573 6372 6970 7469 6f6e  ..  <description\n-00000580: 3e54 6865 206e 6574 7479 3420 7265 6d6f  >The netty4 remo\n-00000590: 7469 6e67 206d 6f64 756c 6520 6f66 2064  ting module of d\n-000005a0: 7562 626f 2070 726f 6a65 6374 3c2f 6465  ubbo project</de\n-000005b0: 7363 7269 7074 696f 6e3e 0d0a 2020 3c6c  scription>..  <l\n-000005c0: 6963 656e 7365 733e 0d0a 2020 2020 3c6c  icenses>..    <l\n-000005d0: 6963 656e 7365 3e0d 0a20 2020 2020 203c  icense>..      <\n-000005e0: 6e61 6d65 3e41 7061 6368 6520 4c69 6365  name>Apache Lice\n-000005f0: 6e73 652c 2056 6572 7369 6f6e 2032 2e30  nse, Version 2.0\n-00000600: 3c2f 6e61 6d65 3e0d 0a20 2020 2020 203c  </name>..      <\n-00000610: 7572 6c3e 6874 7470 3a2f 2f77 7777 2e61  url>http://www.a\n-00000620: 7061 6368 652e 6f72 672f 6c69 6365 6e73  pache.org/licens\n-00000630: 6573 2f4c 4943 454e 5345 2d32 2e30 3c2f  es/LICENSE-2.0</\n-00000640: 7572 6c3e 0d0a 2020 2020 2020 3c64 6973  url>..      <dis\n-00000650: 7472 6962 7574 696f 6e3e 7265 706f 3c2f  tribution>repo</\n-00000660: 6469 7374 7269 6275 7469 6f6e 3e0d 0a20  distribution>.. \n-00000670: 2020 203c 2f6c 6963 656e 7365 3e0d 0a20     </license>.. \n-00000680: 203c 2f6c 6963 656e 7365 733e 0d0a 2020   </licenses>..  \n-00000690: 3c70 726f 7065 7274 6965 733e 0d0a 2020  <properties>..  \n-000006a0: 2020 3c73 6b69 705f 6d61 7665 6e5f 6465    <skip_maven_de\n-000006b0: 706c 6f79 3e66 616c 7365 3c2f 736b 6970  ploy>false</skip\n-000006c0: 5f6d 6176 656e 5f64 6570 6c6f 793e 0d0a  _maven_deploy>..\n-000006d0: 2020 2020 3c70 726f 6a65 6374 2e62 7569      <project.bui\n-000006e0: 6c64 2e73 6f75 7263 6545 6e63 6f64 696e  ld.sourceEncodin\n-000006f0: 673e 5554 462d 383c 2f70 726f 6a65 6374  g>UTF-8</project\n-00000700: 2e62 7569 6c64 2e73 6f75 7263 6545 6e63  .build.sourceEnc\n-00000710: 6f64 696e 673e 0d0a 2020 3c2f 7072 6f70  oding>..  </prop\n-00000720: 6572 7469 6573 3e0d 0a20 203c 6465 7065  erties>..  <depe\n-00000730: 6e64 656e 6369 6573 3e0d 0a20 2020 203c  ndencies>..    <\n-00000740: 6465 7065 6e64 656e 6379 3e0d 0a20 2020  dependency>..   \n-00000750: 2020 203c 6772 6f75 7049 643e 6f72 672e     <groupId>org.\n-00000760: 6170 6163 6865 2e64 7562 626f 3c2f 6772  apache.dubbo</gr\n-00000770: 6f75 7049 643e 0d0a 2020 2020 2020 3c61  oupId>..      <a\n-00000780: 7274 6966 6163 7449 643e 6475 6262 6f2d  rtifactId>dubbo-\n-00000790: 7265 6d6f 7469 6e67 2d61 7069 3c2f 6172  remoting-api</ar\n-000007a0: 7469 6661 6374 4964 3e0d 0a20 2020 2020  tifactId>..     \n-000007b0: 203c 7665 7273 696f 6e3e 247b 7072 6f6a   <version>${proj\n-000007c0: 6563 742e 7061 7265 6e74 2e76 6572 7369  ect.parent.versi\n-000007d0: 6f6e 7d3c 2f76 6572 7369 6f6e 3e0d 0a20  on}</version>.. \n-000007e0: 2020 203c 2f64 6570 656e 6465 6e63 793e     </dependency>\n-000007f0: 0d0a 2020 2020 3c64 6570 656e 6465 6e63  ..    <dependenc\n-00000800: 793e 0d0a 2020 2020 2020 3c67 726f 7570  y>..      <group\n-00000810: 4964 3e69 6f2e 6e65 7474 793c 2f67 726f  Id>io.netty</gro\n-00000820: 7570 4964 3e0d 0a20 2020 2020 203c 6172  upId>..      <ar\n-00000830: 7469 6661 6374 4964 3e6e 6574 7479 2d61  tifactId>netty-a\n-00000840: 6c6c 3c2f 6172 7469 6661 6374 4964 3e0d  ll</artifactId>.\n-00000850: 0a20 2020 203c 2f64 6570 656e 6465 6e63  .    </dependenc\n-00000860: 793e 0d0a 2020 2020 3c64 6570 656e 6465  y>..    <depende\n-00000870: 6e63 793e 0d0a 2020 2020 2020 3c67 726f  ncy>..      <gro\n-00000880: 7570 4964 3e6f 7267 2e61 7061 6368 652e  upId>org.apache.\n-00000890: 6475 6262 6f3c 2f67 726f 7570 4964 3e0d  dubbo</groupId>.\n-000008a0: 0a20 2020 2020 203c 6172 7469 6661 6374  .      <artifact\n-000008b0: 4964 3e64 7562 626f 2d73 6572 6961 6c69  Id>dubbo-seriali\n-000008c0: 7a61 7469 6f6e 2d68 6573 7369 616e 323c  zation-hessian2<\n-000008d0: 2f61 7274 6966 6163 7449 643e 0d0a 2020  /artifactId>..  \n-000008e0: 2020 2020 3c76 6572 7369 6f6e 3e24 7b70      <version>${p\n-000008f0: 726f 6a65 6374 2e70 6172 656e 742e 7665  roject.parent.ve\n-00000900: 7273 696f 6e7d 3c2f 7665 7273 696f 6e3e  rsion}</version>\n-00000910: 0d0a 2020 2020 2020 3c73 636f 7065 3e74  ..      <scope>t\n-00000920: 6573 743c 2f73 636f 7065 3e0d 0a20 2020  est</scope>..   \n-00000930: 203c 2f64 6570 656e 6465 6e63 793e 0d0a   </dependency>..\n-00000940: 2020 3c2f 6465 7065 6e64 656e 6369 6573    </dependencies\n-00000950: 3e0d 0a3c 2f70 726f 6a65 6374 3e0d 0a    >..</project>..\n+00000020: 462d 3822 3f3e 0a3c 212d 2d0a 2020 4c69  F-8\"?>.<!--.  Li\n+00000030: 6365 6e73 6564 2074 6f20 7468 6520 4170  censed to the Ap\n+00000040: 6163 6865 2053 6f66 7477 6172 6520 466f  ache Software Fo\n+00000050: 756e 6461 7469 6f6e 2028 4153 4629 2075  undation (ASF) u\n+00000060: 6e64 6572 206f 6e65 206f 7220 6d6f 7265  nder one or more\n+00000070: 0a20 2063 6f6e 7472 6962 7574 6f72 206c  .  contributor l\n+00000080: 6963 656e 7365 2061 6772 6565 6d65 6e74  icense agreement\n+00000090: 732e 2020 5365 6520 7468 6520 4e4f 5449  s.  See the NOTI\n+000000a0: 4345 2066 696c 6520 6469 7374 7269 6275  CE file distribu\n+000000b0: 7465 6420 7769 7468 0a20 2074 6869 7320  ted with.  this \n+000000c0: 776f 726b 2066 6f72 2061 6464 6974 696f  work for additio\n+000000d0: 6e61 6c20 696e 666f 726d 6174 696f 6e20  nal information \n+000000e0: 7265 6761 7264 696e 6720 636f 7079 7269  regarding copyri\n+000000f0: 6768 7420 6f77 6e65 7273 6869 702e 0a20  ght ownership.. \n+00000100: 2054 6865 2041 5346 206c 6963 656e 7365   The ASF license\n+00000110: 7320 7468 6973 2066 696c 6520 746f 2059  s this file to Y\n+00000120: 6f75 2075 6e64 6572 2074 6865 2041 7061  ou under the Apa\n+00000130: 6368 6520 4c69 6365 6e73 652c 2056 6572  che License, Ver\n+00000140: 7369 6f6e 2032 2e30 0a20 2028 7468 6520  sion 2.0.  (the \n+00000150: 224c 6963 656e 7365 2229 3b20 796f 7520  \"License\"); you \n+00000160: 6d61 7920 6e6f 7420 7573 6520 7468 6973  may not use this\n+00000170: 2066 696c 6520 6578 6365 7074 2069 6e20   file except in \n+00000180: 636f 6d70 6c69 616e 6365 2077 6974 680a  compliance with.\n+00000190: 2020 7468 6520 4c69 6365 6e73 652e 2020    the License.  \n+000001a0: 596f 7520 6d61 7920 6f62 7461 696e 2061  You may obtain a\n+000001b0: 2063 6f70 7920 6f66 2074 6865 204c 6963   copy of the Lic\n+000001c0: 656e 7365 2061 740a 0a20 2020 2020 2068  ense at..      h\n+000001d0: 7474 703a 2f2f 7777 772e 6170 6163 6865  ttp://www.apache\n+000001e0: 2e6f 7267 2f6c 6963 656e 7365 732f 4c49  .org/licenses/LI\n+000001f0: 4345 4e53 452d 322e 300a 0a20 2055 6e6c  CENSE-2.0..  Unl\n+00000200: 6573 7320 7265 7175 6972 6564 2062 7920  ess required by \n+00000210: 6170 706c 6963 6162 6c65 206c 6177 206f  applicable law o\n+00000220: 7220 6167 7265 6564 2074 6f20 696e 2077  r agreed to in w\n+00000230: 7269 7469 6e67 2c20 736f 6674 7761 7265  riting, software\n+00000240: 0a20 2064 6973 7472 6962 7574 6564 2075  .  distributed u\n+00000250: 6e64 6572 2074 6865 204c 6963 656e 7365  nder the License\n+00000260: 2069 7320 6469 7374 7269 6275 7465 6420   is distributed \n+00000270: 6f6e 2061 6e20 2241 5320 4953 2220 4241  on an \"AS IS\" BA\n+00000280: 5349 532c 0a20 2057 4954 484f 5554 2057  SIS,.  WITHOUT W\n+00000290: 4152 5241 4e54 4945 5320 4f52 2043 4f4e  ARRANTIES OR CON\n+000002a0: 4449 5449 4f4e 5320 4f46 2041 4e59 204b  DITIONS OF ANY K\n+000002b0: 494e 442c 2065 6974 6865 7220 6578 7072  IND, either expr\n+000002c0: 6573 7320 6f72 2069 6d70 6c69 6564 2e0a  ess or implied..\n+000002d0: 2020 5365 6520 7468 6520 4c69 6365 6e73    See the Licens\n+000002e0: 6520 666f 7220 7468 6520 7370 6563 6966  e for the specif\n+000002f0: 6963 206c 616e 6775 6167 6520 676f 7665  ic language gove\n+00000300: 726e 696e 6720 7065 726d 6973 7369 6f6e  rning permission\n+00000310: 7320 616e 640a 2020 6c69 6d69 7461 7469  s and.  limitati\n+00000320: 6f6e 7320 756e 6465 7220 7468 6520 4c69  ons under the Li\n+00000330: 6365 6e73 652e 0a20 202d 2d3e 0a3c 7072  cense..  -->.<pr\n+00000340: 6f6a 6563 7420 7873 693a 7363 6865 6d61  oject xsi:schema\n+00000350: 4c6f 6361 7469 6f6e 3d22 6874 7470 3a2f  Location=\"http:/\n+00000360: 2f6d 6176 656e 2e61 7061 6368 652e 6f72  /maven.apache.or\n+00000370: 672f 504f 4d2f 342e 302e 3020 6874 7470  g/POM/4.0.0 http\n+00000380: 733a 2f2f 6d61 7665 6e2e 6170 6163 6865  s://maven.apache\n+00000390: 2e6f 7267 2f78 7364 2f6d 6176 656e 2d34  .org/xsd/maven-4\n+000003a0: 2e30 2e30 2e78 7364 2220 786d 6c6e 733d  .0.0.xsd\" xmlns=\n+000003b0: 2268 7474 703a 2f2f 6d61 7665 6e2e 6170  \"http://maven.ap\n+000003c0: 6163 6865 2e6f 7267 2f50 4f4d 2f34 2e30  ache.org/POM/4.0\n+000003d0: 2e30 220a 2020 2020 786d 6c6e 733a 7873  .0\".    xmlns:xs\n+000003e0: 693d 2268 7474 703a 2f2f 7777 772e 7733  i=\"http://www.w3\n+000003f0: 2e6f 7267 2f32 3030 312f 584d 4c53 6368  .org/2001/XMLSch\n+00000400: 656d 612d 696e 7374 616e 6365 223e 0a20  ema-instance\">. \n+00000410: 203c 6d6f 6465 6c56 6572 7369 6f6e 3e34   <modelVersion>4\n+00000420: 2e30 2e30 3c2f 6d6f 6465 6c56 6572 7369  .0.0</modelVersi\n+00000430: 6f6e 3e0a 2020 3c70 6172 656e 743e 0a20  on>.  <parent>. \n+00000440: 2020 203c 6772 6f75 7049 643e 6f72 672e     <groupId>org.\n+00000450: 6170 6163 6865 2e64 7562 626f 3c2f 6772  apache.dubbo</gr\n+00000460: 6f75 7049 643e 0a20 2020 203c 6172 7469  oupId>.    <arti\n+00000470: 6661 6374 4964 3e64 7562 626f 2d72 656d  factId>dubbo-rem\n+00000480: 6f74 696e 673c 2f61 7274 6966 6163 7449  oting</artifactI\n+00000490: 643e 0a20 2020 203c 7665 7273 696f 6e3e  d>.    <version>\n+000004a0: 322e 372e 3130 3c2f 7665 7273 696f 6e3e  2.7.10</version>\n+000004b0: 0a20 203c 2f70 6172 656e 743e 0a20 203c  .  </parent>.  <\n+000004c0: 6772 6f75 7049 643e 6f72 672e 6170 6163  groupId>org.apac\n+000004d0: 6865 2e64 7562 626f 3c2f 6772 6f75 7049  he.dubbo</groupI\n+000004e0: 643e 0a20 203c 6172 7469 6661 6374 4964  d>.  <artifactId\n+000004f0: 3e64 7562 626f 2d72 656d 6f74 696e 672d  >dubbo-remoting-\n+00000500: 6e65 7474 7934 3c2f 6172 7469 6661 6374  netty4</artifact\n+00000510: 4964 3e0a 2020 3c76 6572 7369 6f6e 3e32  Id>.  <version>2\n+00000520: 2e37 2e31 303c 2f76 6572 7369 6f6e 3e0a  .7.10</version>.\n+00000530: 2020 3c6e 616d 653e 247b 7072 6f6a 6563    <name>${projec\n+00000540: 742e 6172 7469 6661 6374 4964 7d3c 2f6e  t.artifactId}</n\n+00000550: 616d 653e 0a20 203c 6465 7363 7269 7074  ame>.  <descript\n+00000560: 696f 6e3e 5468 6520 6e65 7474 7934 2072  ion>The netty4 r\n+00000570: 656d 6f74 696e 6720 6d6f 6475 6c65 206f  emoting module o\n+00000580: 6620 6475 6262 6f20 7072 6f6a 6563 743c  f dubbo project<\n+00000590: 2f64 6573 6372 6970 7469 6f6e 3e0a 2020  /description>.  \n+000005a0: 3c6c 6963 656e 7365 733e 0a20 2020 203c  <licenses>.    <\n+000005b0: 6c69 6365 6e73 653e 0a20 2020 2020 203c  license>.      <\n+000005c0: 6e61 6d65 3e41 7061 6368 6520 4c69 6365  name>Apache Lice\n+000005d0: 6e73 652c 2056 6572 7369 6f6e 2032 2e30  nse, Version 2.0\n+000005e0: 3c2f 6e61 6d65 3e0a 2020 2020 2020 3c75  </name>.      <u\n+000005f0: 726c 3e68 7474 703a 2f2f 7777 772e 6170  rl>http://www.ap\n+00000600: 6163 6865 2e6f 7267 2f6c 6963 656e 7365  ache.org/license\n+00000610: 732f 4c49 4345 4e53 452d 322e 303c 2f75  s/LICENSE-2.0</u\n+00000620: 726c 3e0a 2020 2020 2020 3c64 6973 7472  rl>.      <distr\n+00000630: 6962 7574 696f 6e3e 7265 706f 3c2f 6469  ibution>repo</di\n+00000640: 7374 7269 6275 7469 6f6e 3e0a 2020 2020  stribution>.    \n+00000650: 3c2f 6c69 6365 6e73 653e 0a20 203c 2f6c  </license>.  </l\n+00000660: 6963 656e 7365 733e 0a20 203c 7072 6f70  icenses>.  <prop\n+00000670: 6572 7469 6573 3e0a 2020 2020 3c73 6b69  erties>.    <ski\n+00000680: 705f 6d61 7665 6e5f 6465 706c 6f79 3e66  p_maven_deploy>f\n+00000690: 616c 7365 3c2f 736b 6970 5f6d 6176 656e  alse</skip_maven\n+000006a0: 5f64 6570 6c6f 793e 0a20 2020 203c 7072  _deploy>.    <pr\n+000006b0: 6f6a 6563 742e 6275 696c 642e 736f 7572  oject.build.sour\n+000006c0: 6365 456e 636f 6469 6e67 3e55 5446 2d38  ceEncoding>UTF-8\n+000006d0: 3c2f 7072 6f6a 6563 742e 6275 696c 642e  </project.build.\n+000006e0: 736f 7572 6365 456e 636f 6469 6e67 3e0a  sourceEncoding>.\n+000006f0: 2020 3c2f 7072 6f70 6572 7469 6573 3e0a    </properties>.\n+00000700: 2020 3c64 6570 656e 6465 6e63 6965 733e    <dependencies>\n+00000710: 0a20 2020 203c 6465 7065 6e64 656e 6379  .    <dependency\n+00000720: 3e0a 2020 2020 2020 3c67 726f 7570 4964  >.      <groupId\n+00000730: 3e6f 7267 2e61 7061 6368 652e 6475 6262  >org.apache.dubb\n+00000740: 6f3c 2f67 726f 7570 4964 3e0a 2020 2020  o</groupId>.    \n+00000750: 2020 3c61 7274 6966 6163 7449 643e 6475    <artifactId>du\n+00000760: 6262 6f2d 7265 6d6f 7469 6e67 2d61 7069  bbo-remoting-api\n+00000770: 3c2f 6172 7469 6661 6374 4964 3e0a 2020  </artifactId>.  \n+00000780: 2020 2020 3c76 6572 7369 6f6e 3e24 7b70      <version>${p\n+00000790: 726f 6a65 6374 2e70 6172 656e 742e 7665  roject.parent.ve\n+000007a0: 7273 696f 6e7d 3c2f 7665 7273 696f 6e3e  rsion}</version>\n+000007b0: 0a20 2020 203c 2f64 6570 656e 6465 6e63  .    </dependenc\n+000007c0: 793e 0a20 2020 203c 6465 7065 6e64 656e  y>.    <dependen\n+000007d0: 6379 3e0a 2020 2020 2020 3c67 726f 7570  cy>.      <group\n+000007e0: 4964 3e69 6f2e 6e65 7474 793c 2f67 726f  Id>io.netty</gro\n+000007f0: 7570 4964 3e0a 2020 2020 2020 3c61 7274  upId>.      <art\n+00000800: 6966 6163 7449 643e 6e65 7474 792d 616c  ifactId>netty-al\n+00000810: 6c3c 2f61 7274 6966 6163 7449 643e 0a20  l</artifactId>. \n+00000820: 2020 203c 2f64 6570 656e 6465 6e63 793e     </dependency>\n+00000830: 0a20 2020 203c 6465 7065 6e64 656e 6379  .    <dependency\n+00000840: 3e0a 2020 2020 2020 3c67 726f 7570 4964  >.      <groupId\n+00000850: 3e6f 7267 2e61 7061 6368 652e 6475 6262  >org.apache.dubb\n+00000860: 6f3c 2f67 726f 7570 4964 3e0a 2020 2020  o</groupId>.    \n+00000870: 2020 3c61 7274 6966 6163 7449 643e 6475    <artifactId>du\n+00000880: 6262 6f2d 7365 7269 616c 697a 6174 696f  bbo-serializatio\n+00000890: 6e2d 6865 7373 6961 6e32 3c2f 6172 7469  n-hessian2</arti\n+000008a0: 6661 6374 4964 3e0a 2020 2020 2020 3c76  factId>.      <v\n+000008b0: 6572 7369 6f6e 3e24 7b70 726f 6a65 6374  ersion>${project\n+000008c0: 2e70 6172 656e 742e 7665 7273 696f 6e7d  .parent.version}\n+000008d0: 3c2f 7665 7273 696f 6e3e 0a20 2020 2020  </version>.     \n+000008e0: 203c 7363 6f70 653e 7465 7374 3c2f 7363   <scope>test</sc\n+000008f0: 6f70 653e 0a20 2020 203c 2f64 6570 656e  ope>.    </depen\n+00000900: 6465 6e63 793e 0a20 203c 2f64 6570 656e  dency>.  </depen\n+00000910: 6465 6e63 6965 733e 0a3c 2f70 726f 6a65  dencies>.</proje\n+00000920: 6374 3e0a                                ct>.\n"}]}
