{"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: 156249 bytes, number of entries: 42\n+Zip file size: 159388 bytes, number of entries: 42\n -rw----     2.0 fat        0 bx stor 70-Jan-01 00:00 META-INF/\n -rw----     2.0 fat     3136 bX stor 70-Jan-01 00:00 META-INF/DEPENDENCIES\n -rw----     2.0 fat    11358 bX stor 70-Jan-01 00:00 META-INF/LICENSE\n -rw----     2.0 fat       25 bX stor 70-Jan-01 00:00 META-INF/MANIFEST.MF\n -rw----     2.0 fat      172 bX stor 70-Jan-01 00:00 META-INF/NOTICE\n -rw----     2.0 fat        0 bx stor 70-Jan-01 00:00 META-INF/dubbo/\n -rw----     2.0 fat        0 bx stor 70-Jan-01 00:00 META-INF/dubbo/internal/\n@@ -10,35 +10,35 @@\n -rw----     2.0 fat       57 bX stor 70-Jan-01 00:00 META-INF/dubbo/internal/org.apache.dubbo.remoting.Codec2\n -rw----     2.0 fat      124 bX stor 70-Jan-01 00:00 META-INF/dubbo/internal/org.apache.dubbo.rpc.Filter\n -rw----     2.0 fat       55 bX stor 70-Jan-01 00:00 META-INF/dubbo/internal/org.apache.dubbo.rpc.Protocol\n -rw----     2.0 fat        0 bx stor 70-Jan-01 00:00 META-INF/maven/\n -rw----     2.0 fat        0 bx stor 70-Jan-01 00:00 META-INF/maven/org.apache.dubbo/\n -rw----     2.0 fat        0 bx stor 70-Jan-01 00:00 META-INF/maven/org.apache.dubbo/dubbo-rpc-dubbo/\n -rw----     2.0 fat        0 bX stor 70-Jan-01 00:00 META-INF/maven/org.apache.dubbo/dubbo-rpc-dubbo/pom.properties\n--rw----     2.0 fat     4028 bX stor 70-Jan-01 00:00 META-INF/maven/org.apache.dubbo/dubbo-rpc-dubbo/pom.xml\n+-rw----     2.0 fat     3916 bX stor 70-Jan-01 00:00 META-INF/maven/org.apache.dubbo/dubbo-rpc-dubbo/pom.xml\n -rw----     2.0 fat        0 bx stor 70-Jan-01 00:00 org/\n -rw----     2.0 fat        0 bx stor 70-Jan-01 00:00 org/apache/\n -rw----     2.0 fat        0 bx stor 70-Jan-01 00:00 org/apache/dubbo/\n -rw----     2.0 fat        0 bx stor 70-Jan-01 00:00 org/apache/dubbo/rpc/\n -rw----     2.0 fat        0 bx stor 70-Jan-01 00:00 org/apache/dubbo/rpc/protocol/\n -rw----     2.0 fat        0 bx stor 70-Jan-01 00:00 org/apache/dubbo/rpc/protocol/dubbo/\n--rw----     2.0 fat    15943 bX stor 70-Jan-01 00:00 org/apache/dubbo/rpc/protocol/dubbo/CallbackServiceCodec.java\n--rw----     2.0 fat     6371 bX stor 70-Jan-01 00:00 org/apache/dubbo/rpc/protocol/dubbo/ChannelWrappedInvoker.java\n--rw----     2.0 fat     2232 bX stor 70-Jan-01 00:00 org/apache/dubbo/rpc/protocol/dubbo/Constants.java\n--rw----     2.0 fat     7990 bX stor 70-Jan-01 00:00 org/apache/dubbo/rpc/protocol/dubbo/DecodeableRpcInvocation.java\n--rw----     2.0 fat     7072 bX stor 70-Jan-01 00:00 org/apache/dubbo/rpc/protocol/dubbo/DecodeableRpcResult.java\n--rw----     2.0 fat    10983 bX stor 70-Jan-01 00:00 org/apache/dubbo/rpc/protocol/dubbo/DubboCodec.java\n--rw----     2.0 fat     2585 bX stor 70-Jan-01 00:00 org/apache/dubbo/rpc/protocol/dubbo/DubboCodecSupport.java\n--rw----     2.0 fat     3102 bX stor 70-Jan-01 00:00 org/apache/dubbo/rpc/protocol/dubbo/DubboCountCodec.java\n--rw----     2.0 fat     1457 bX stor 70-Jan-01 00:00 org/apache/dubbo/rpc/protocol/dubbo/DubboExporter.java\n--rw----     2.0 fat     8153 bX stor 70-Jan-01 00:00 org/apache/dubbo/rpc/protocol/dubbo/DubboInvoker.java\n--rw----     2.0 fat    27447 bX stor 70-Jan-01 00:00 org/apache/dubbo/rpc/protocol/dubbo/DubboProtocol.java\n--rw----     2.0 fat     1812 bX stor 70-Jan-01 00:00 org/apache/dubbo/rpc/protocol/dubbo/DubboProtocolServer.java\n--rw----     2.0 fat     8140 bX stor 70-Jan-01 00:00 org/apache/dubbo/rpc/protocol/dubbo/LazyConnectExchangeClient.java\n--rw----     2.0 fat     6087 bX stor 70-Jan-01 00:00 org/apache/dubbo/rpc/protocol/dubbo/ReferenceCountExchangeClient.java\n+-rw----     2.0 fat    16261 bX stor 70-Jan-01 00:00 org/apache/dubbo/rpc/protocol/dubbo/CallbackServiceCodec.java\n+-rw----     2.0 fat     6554 bX stor 70-Jan-01 00:00 org/apache/dubbo/rpc/protocol/dubbo/ChannelWrappedInvoker.java\n+-rw----     2.0 fat     2303 bX stor 70-Jan-01 00:00 org/apache/dubbo/rpc/protocol/dubbo/Constants.java\n+-rw----     2.0 fat     8185 bX stor 70-Jan-01 00:00 org/apache/dubbo/rpc/protocol/dubbo/DecodeableRpcInvocation.java\n+-rw----     2.0 fat     7256 bX stor 70-Jan-01 00:00 org/apache/dubbo/rpc/protocol/dubbo/DecodeableRpcResult.java\n+-rw----     2.0 fat    11231 bX stor 70-Jan-01 00:00 org/apache/dubbo/rpc/protocol/dubbo/DubboCodec.java\n+-rw----     2.0 fat     2638 bX stor 70-Jan-01 00:00 org/apache/dubbo/rpc/protocol/dubbo/DubboCodecSupport.java\n+-rw----     2.0 fat     3188 bX stor 70-Jan-01 00:00 org/apache/dubbo/rpc/protocol/dubbo/DubboCountCodec.java\n+-rw----     2.0 fat     1501 bX stor 70-Jan-01 00:00 org/apache/dubbo/rpc/protocol/dubbo/DubboExporter.java\n+-rw----     2.0 fat     8336 bX stor 70-Jan-01 00:00 org/apache/dubbo/rpc/protocol/dubbo/DubboInvoker.java\n+-rw----     2.0 fat    28133 bX stor 70-Jan-01 00:00 org/apache/dubbo/rpc/protocol/dubbo/DubboProtocol.java\n+-rw----     2.0 fat     1874 bX stor 70-Jan-01 00:00 org/apache/dubbo/rpc/protocol/dubbo/DubboProtocolServer.java\n+-rw----     2.0 fat     8409 bX stor 70-Jan-01 00:00 org/apache/dubbo/rpc/protocol/dubbo/LazyConnectExchangeClient.java\n+-rw----     2.0 fat     6298 bX stor 70-Jan-01 00:00 org/apache/dubbo/rpc/protocol/dubbo/ReferenceCountExchangeClient.java\n -rw----     2.0 fat        0 bx stor 70-Jan-01 00:00 org/apache/dubbo/rpc/protocol/dubbo/filter/\n--rw----     2.0 fat     8744 bX stor 70-Jan-01 00:00 org/apache/dubbo/rpc/protocol/dubbo/filter/FutureFilter.java\n--rw----     2.0 fat     5704 bX stor 70-Jan-01 00:00 org/apache/dubbo/rpc/protocol/dubbo/filter/TraceFilter.java\n+-rw----     2.0 fat     8947 bX stor 70-Jan-01 00:00 org/apache/dubbo/rpc/protocol/dubbo/filter/FutureFilter.java\n+-rw----     2.0 fat     5831 bX stor 70-Jan-01 00:00 org/apache/dubbo/rpc/protocol/dubbo/filter/TraceFilter.java\n -rw----     2.0 fat        0 bx stor 70-Jan-01 00:00 org/apache/dubbo/rpc/protocol/dubbo/status/\n--rw----     2.0 fat     2276 bX stor 70-Jan-01 00:00 org/apache/dubbo/rpc/protocol/dubbo/status/ServerStatusChecker.java\n--rw----     2.0 fat     2950 bX stor 70-Jan-01 00:00 org/apache/dubbo/rpc/protocol/dubbo/status/ThreadPoolStatusChecker.java\n-42 files, 148151 bytes uncompressed, 148151 bytes compressed:  0.0%\n+-rw----     2.0 fat     2337 bX stor 70-Jan-01 00:00 org/apache/dubbo/rpc/protocol/dubbo/status/ServerStatusChecker.java\n+-rw----     2.0 fat     3017 bX stor 70-Jan-01 00:00 org/apache/dubbo/rpc/protocol/dubbo/status/ThreadPoolStatusChecker.java\n+42 files, 151290 bytes uncompressed, 151290 bytes compressed:  0.0%\n"}, {"source1": "zipdetails --redact --scan --utc {}", "source2": "zipdetails --redact --scan --utc {}", "unified_diff": "@@ -397,1942 +397,1942 @@\n #\n 0400A Extra ID #1           5455 (21589) 'Extended Timestamp [UT]'\n 0400C   Length              0005 (5)\n 0400E   Flags               01 (1) 'Modification'\n 0400F   Modification Time   00000000 (0) 'Thu Jan  1 00:00:00 1970'\n 04013 PAYLOAD\n \n-04FCF DATA DESCRIPTOR       08074B50 (134695760)\n-04FD3 CRC                   45DB5347 (1172001607)\n-04FD7 Compressed Size       00000FBC (4028)\n-04FDB Uncompressed Size     00000FBC (4028)\n-\n-04FDF LOCAL HEADER #17      04034B50 (67324752)\n-04FE3 Extract Zip Spec      14 (20) '2.0'\n-04FE4 Extract OS            00 (0) 'MS-DOS'\n-04FE5 General Purpose Flag  0000 (0)\n-04FE7 Compression Method    0000 (0) 'Stored'\n-04FE9 Modification Time     EC210000 (3961585664) 'Wed Jan  1 00:00:00 2098'\n-04FED CRC                   00000000 (0)\n-04FF1 Compressed Size       00000000 (0)\n-04FF5 Uncompressed Size     00000000 (0)\n-04FF9 Filename Length       0004 (4)\n-04FFB Extra Length          0009 (9)\n-04FFD Filename              'XXXX'\n-#\n-# WARNING: Offset 0x4FFD: Filename 'XXXX'\n-#          Zero length filename\n-#\n-05001 Extra ID #1           5455 (21589) 'Extended Timestamp [UT]'\n-05003   Length              0005 (5)\n-05005   Flags               01 (1) 'Modification'\n-05006   Modification Time   00000000 (0) 'Thu Jan  1 00:00:00 1970'\n-\n-0500A LOCAL HEADER #18      04034B50 (67324752)\n-0500E Extract Zip Spec      14 (20) '2.0'\n-0500F Extract OS            00 (0) 'MS-DOS'\n-05010 General Purpose Flag  0000 (0)\n-05012 Compression Method    0000 (0) 'Stored'\n-05014 Modification Time     EC210000 (3961585664) 'Wed Jan  1 00:00:00 2098'\n-05018 CRC                   00000000 (0)\n-0501C Compressed Size       00000000 (0)\n-05020 Uncompressed Size     00000000 (0)\n-05024 Filename Length       000B (11)\n-05026 Extra Length          0009 (9)\n-05028 Filename              'XXXXXXXXXXX'\n-#\n-# WARNING: Offset 0x5028: Filename 'XXXXXXXXXXX'\n-#          Zero length filename\n-#\n-05033 Extra ID #1           5455 (21589) 'Extended Timestamp [UT]'\n-05035   Length              0005 (5)\n-05037   Flags               01 (1) 'Modification'\n-05038   Modification Time   00000000 (0) 'Thu Jan  1 00:00:00 1970'\n-\n-0503C LOCAL HEADER #19      04034B50 (67324752)\n-05040 Extract Zip Spec      14 (20) '2.0'\n-05041 Extract OS            00 (0) 'MS-DOS'\n-05042 General Purpose Flag  0000 (0)\n-05044 Compression Method    0000 (0) 'Stored'\n-05046 Modification Time     EC210000 (3961585664) 'Wed Jan  1 00:00:00 2098'\n-0504A CRC                   00000000 (0)\n-0504E Compressed Size       00000000 (0)\n-05052 Uncompressed Size     00000000 (0)\n-05056 Filename Length       0011 (17)\n-05058 Extra Length          0009 (9)\n-0505A Filename              'XXXXXXXXXXXXXXXXX'\n-#\n-# WARNING: Offset 0x505A: Filename 'XXXXXXXXXXXXXXXXX'\n-#          Zero length filename\n-#\n-0506B Extra ID #1           5455 (21589) 'Extended Timestamp [UT]'\n-0506D   Length              0005 (5)\n-0506F   Flags               01 (1) 'Modification'\n-05070   Modification Time   00000000 (0) 'Thu Jan  1 00:00:00 1970'\n-\n-05074 LOCAL HEADER #20      04034B50 (67324752)\n-05078 Extract Zip Spec      14 (20) '2.0'\n-05079 Extract OS            00 (0) 'MS-DOS'\n-0507A General Purpose Flag  0000 (0)\n-0507C Compression Method    0000 (0) 'Stored'\n-0507E Modification Time     EC210000 (3961585664) 'Wed Jan  1 00:00:00 2098'\n-05082 CRC                   00000000 (0)\n-05086 Compressed Size       00000000 (0)\n-0508A Uncompressed Size     00000000 (0)\n-0508E Filename Length       0015 (21)\n-05090 Extra Length          0009 (9)\n-05092 Filename              'XXXXXXXXXXXXXXXXXXXXX'\n-#\n-# WARNING: Offset 0x5092: Filename 'XXXXXXXXXXXXXXXXXXXXX'\n-#          Zero length filename\n-#\n-050A7 Extra ID #1           5455 (21589) 'Extended Timestamp [UT]'\n-050A9   Length              0005 (5)\n-050AB   Flags               01 (1) 'Modification'\n-050AC   Modification Time   00000000 (0) 'Thu Jan  1 00:00:00 1970'\n-\n-050B0 LOCAL HEADER #21      04034B50 (67324752)\n-050B4 Extract Zip Spec      14 (20) '2.0'\n-050B5 Extract OS            00 (0) 'MS-DOS'\n-050B6 General Purpose Flag  0000 (0)\n-050B8 Compression Method    0000 (0) 'Stored'\n-050BA Modification Time     EC210000 (3961585664) 'Wed Jan  1 00:00:00 2098'\n-050BE CRC                   00000000 (0)\n-050C2 Compressed Size       00000000 (0)\n-050C6 Uncompressed Size     00000000 (0)\n-050CA Filename Length       001E (30)\n-050CC Extra Length          0009 (9)\n-050CE Filename              'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXX'\n-#\n-# WARNING: Offset 0x50CE: Filename 'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXX'\n-#          Zero length filename\n-#\n-050EC Extra ID #1           5455 (21589) 'Extended Timestamp [UT]'\n-050EE   Length              0005 (5)\n-050F0   Flags               01 (1) 'Modification'\n-050F1   Modification Time   00000000 (0) 'Thu Jan  1 00:00:00 1970'\n-\n-050F5 LOCAL HEADER #22      04034B50 (67324752)\n-050F9 Extract Zip Spec      14 (20) '2.0'\n-050FA Extract OS            00 (0) 'MS-DOS'\n-050FB General Purpose Flag  0000 (0)\n-050FD Compression Method    0000 (0) 'Stored'\n-050FF Modification Time     EC210000 (3961585664) 'Wed Jan  1 00:00:00 2098'\n-05103 CRC                   00000000 (0)\n-05107 Compressed Size       00000000 (0)\n-0510B Uncompressed Size     00000000 (0)\n-0510F Filename Length       0024 (36)\n-05111 Extra Length          0009 (9)\n-05113 Filename              'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX'\n-#\n-# WARNING: Offset 0x5113: Filename 'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX'\n-#          Zero length filename\n-#\n-05137 Extra ID #1           5455 (21589) 'Extended Timestamp [UT]'\n-05139   Length              0005 (5)\n-0513B   Flags               01 (1) 'Modification'\n-0513C   Modification Time   00000000 (0) 'Thu Jan  1 00:00:00 1970'\n-\n-05140 LOCAL HEADER #23      04034B50 (67324752)\n-05144 Extract Zip Spec      14 (20) '2.0'\n-05145 Extract OS            00 (0) 'MS-DOS'\n-05146 General Purpose Flag  0008 (8)\n-      [Bit  3]              1 'Streamed'\n-05148 Compression Method    0000 (0) 'Stored'\n-0514A Modification Time     EC210000 (3961585664) 'Wed Jan  1 00:00:00 2098'\n-0514E CRC                   00000000 (0)\n-05152 Compressed Size       00000000 (0)\n-05156 Uncompressed Size     00000000 (0)\n-0515A Filename Length       003D (61)\n-0515C Extra Length          0009 (9)\n-0515E Filename              'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX'\n-#\n-# WARNING: Offset 0x515E: Filename 'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX'\n-#          Zero length filename\n-#\n-0519B Extra ID #1           5455 (21589) 'Extended Timestamp [UT]'\n-0519D   Length              0005 (5)\n-0519F   Flags               01 (1) 'Modification'\n-051A0   Modification Time   00000000 (0) 'Thu Jan  1 00:00:00 1970'\n-051A4 PAYLOAD\n-\n-08FEB DATA DESCRIPTOR       08074B50 (134695760)\n-08FEF CRC                   B7F8FDDA (3086548442)\n-08FF3 Compressed Size       00003E47 (15943)\n-08FF7 Uncompressed Size     00003E47 (15943)\n-\n-08FFB LOCAL HEADER #24      04034B50 (67324752)\n-08FFF Extract Zip Spec      14 (20) '2.0'\n-09000 Extract OS            00 (0) 'MS-DOS'\n-09001 General Purpose Flag  0008 (8)\n-      [Bit  3]              1 'Streamed'\n-09003 Compression Method    0000 (0) 'Stored'\n-09005 Modification Time     EC210000 (3961585664) 'Wed Jan  1 00:00:00 2098'\n-09009 CRC                   00000000 (0)\n-0900D Compressed Size       00000000 (0)\n-09011 Uncompressed Size     00000000 (0)\n-09015 Filename Length       003E (62)\n-09017 Extra Length          0009 (9)\n-09019 Filename              'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX'\n-#\n-# WARNING: Offset 0x9019: Filename 'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX'\n-#          Zero length filename\n-#\n-09057 Extra ID #1           5455 (21589) 'Extended Timestamp [UT]'\n-09059   Length              0005 (5)\n-0905B   Flags               01 (1) 'Modification'\n-0905C   Modification Time   00000000 (0) 'Thu Jan  1 00:00:00 1970'\n-09060 PAYLOAD\n-\n-0A943 DATA DESCRIPTOR       08074B50 (134695760)\n-0A947 CRC                   03D1B931 (64076081)\n-0A94B Compressed Size       000018E3 (6371)\n-0A94F Uncompressed Size     000018E3 (6371)\n-\n-0A953 LOCAL HEADER #25      04034B50 (67324752)\n-0A957 Extract Zip Spec      14 (20) '2.0'\n-0A958 Extract OS            00 (0) 'MS-DOS'\n-0A959 General Purpose Flag  0008 (8)\n-      [Bit  3]              1 'Streamed'\n-0A95B Compression Method    0000 (0) 'Stored'\n-0A95D Modification Time     EC210000 (3961585664) 'Wed Jan  1 00:00:00 2098'\n-0A961 CRC                   00000000 (0)\n-0A965 Compressed Size       00000000 (0)\n-0A969 Uncompressed Size     00000000 (0)\n-0A96D Filename Length       0032 (50)\n-0A96F Extra Length          0009 (9)\n-0A971 Filename              'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX'\n-#\n-# WARNING: Offset 0xA971: Filename 'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX'\n-#          Zero length filename\n-#\n-0A9A3 Extra ID #1           5455 (21589) 'Extended Timestamp [UT]'\n-0A9A5   Length              0005 (5)\n-0A9A7   Flags               01 (1) 'Modification'\n-0A9A8   Modification Time   00000000 (0) 'Thu Jan  1 00:00:00 1970'\n-0A9AC PAYLOAD\n-\n-0B264 DATA DESCRIPTOR       08074B50 (134695760)\n-0B268 CRC                   F93BB070 (4181438576)\n-0B26C Compressed Size       000008B8 (2232)\n-0B270 Uncompressed Size     000008B8 (2232)\n-\n-0B274 LOCAL HEADER #26      04034B50 (67324752)\n-0B278 Extract Zip Spec      14 (20) '2.0'\n-0B279 Extract OS            00 (0) 'MS-DOS'\n-0B27A General Purpose Flag  0008 (8)\n-      [Bit  3]              1 'Streamed'\n-0B27C Compression Method    0000 (0) 'Stored'\n-0B27E Modification Time     EC210000 (3961585664) 'Wed Jan  1 00:00:00 2098'\n-0B282 CRC                   00000000 (0)\n-0B286 Compressed Size       00000000 (0)\n-0B28A Uncompressed Size     00000000 (0)\n-0B28E Filename Length       0040 (64)\n-0B290 Extra Length          0009 (9)\n-0B292 Filename              'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX'\n-#\n-# WARNING: Offset 0xB292: Filename 'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX'\n-#          Zero length filename\n-#\n-0B2D2 Extra ID #1           5455 (21589) 'Extended Timestamp [UT]'\n-0B2D4   Length              0005 (5)\n-0B2D6   Flags               01 (1) 'Modification'\n-0B2D7   Modification Time   00000000 (0) 'Thu Jan  1 00:00:00 1970'\n-0B2DB PAYLOAD\n-\n-0D211 DATA DESCRIPTOR       08074B50 (134695760)\n-0D215 CRC                   C7D35A4B (3352517195)\n-0D219 Compressed Size       00001F36 (7990)\n-0D21D Uncompressed Size     00001F36 (7990)\n-\n-0D221 LOCAL HEADER #27      04034B50 (67324752)\n-0D225 Extract Zip Spec      14 (20) '2.0'\n-0D226 Extract OS            00 (0) 'MS-DOS'\n-0D227 General Purpose Flag  0008 (8)\n-      [Bit  3]              1 'Streamed'\n-0D229 Compression Method    0000 (0) 'Stored'\n-0D22B Modification Time     EC210000 (3961585664) 'Wed Jan  1 00:00:00 2098'\n-0D22F CRC                   00000000 (0)\n-0D233 Compressed Size       00000000 (0)\n-0D237 Uncompressed Size     00000000 (0)\n-0D23B Filename Length       003C (60)\n-0D23D Extra Length          0009 (9)\n-0D23F Filename              'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX'\n-#\n-# WARNING: Offset 0xD23F: Filename 'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX'\n-#          Zero length filename\n-#\n-0D27B Extra ID #1           5455 (21589) 'Extended Timestamp [UT]'\n-0D27D   Length              0005 (5)\n-0D27F   Flags               01 (1) 'Modification'\n-0D280   Modification Time   00000000 (0) 'Thu Jan  1 00:00:00 1970'\n-0D284 PAYLOAD\n-\n-0EE24 DATA DESCRIPTOR       08074B50 (134695760)\n-0EE28 CRC                   D012E5FC (3490899452)\n-0EE2C Compressed Size       00001BA0 (7072)\n-0EE30 Uncompressed Size     00001BA0 (7072)\n-\n-0EE34 LOCAL HEADER #28      04034B50 (67324752)\n-0EE38 Extract Zip Spec      14 (20) '2.0'\n-0EE39 Extract OS            00 (0) 'MS-DOS'\n-0EE3A General Purpose Flag  0008 (8)\n-      [Bit  3]              1 'Streamed'\n-0EE3C Compression Method    0000 (0) 'Stored'\n-0EE3E Modification Time     EC210000 (3961585664) 'Wed Jan  1 00:00:00 2098'\n-0EE42 CRC                   00000000 (0)\n-0EE46 Compressed Size       00000000 (0)\n-0EE4A Uncompressed Size     00000000 (0)\n-0EE4E Filename Length       0033 (51)\n-0EE50 Extra Length          0009 (9)\n-0EE52 Filename              'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX'\n-#\n-# WARNING: Offset 0xEE52: Filename 'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX'\n-#          Zero length filename\n-#\n-0EE85 Extra ID #1           5455 (21589) 'Extended Timestamp [UT]'\n-0EE87   Length              0005 (5)\n-0EE89   Flags               01 (1) 'Modification'\n-0EE8A   Modification Time   00000000 (0) 'Thu Jan  1 00:00:00 1970'\n-0EE8E PAYLOAD\n-\n-11975 DATA DESCRIPTOR       08074B50 (134695760)\n-11979 CRC                   A6D38CE4 (2798882020)\n-1197D Compressed Size       00002AE7 (10983)\n-11981 Uncompressed Size     00002AE7 (10983)\n-\n-11985 LOCAL HEADER #29      04034B50 (67324752)\n-11989 Extract Zip Spec      14 (20) '2.0'\n-1198A Extract OS            00 (0) 'MS-DOS'\n-1198B General Purpose Flag  0008 (8)\n-      [Bit  3]              1 'Streamed'\n-1198D Compression Method    0000 (0) 'Stored'\n-1198F Modification Time     EC210000 (3961585664) 'Wed Jan  1 00:00:00 2098'\n-11993 CRC                   00000000 (0)\n-11997 Compressed Size       00000000 (0)\n-1199B Uncompressed Size     00000000 (0)\n-1199F Filename Length       003A (58)\n-119A1 Extra Length          0009 (9)\n-119A3 Filename              'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX'\n-#\n-# WARNING: Offset 0x119A3: Filename 'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX'\n-#          Zero length filename\n-#\n-119DD Extra ID #1           5455 (21589) 'Extended Timestamp [UT]'\n-119DF   Length              0005 (5)\n-119E1   Flags               01 (1) 'Modification'\n-119E2   Modification Time   00000000 (0) 'Thu Jan  1 00:00:00 1970'\n-119E6 PAYLOAD\n-\n-123FF DATA DESCRIPTOR       08074B50 (134695760)\n-12403 CRC                   982FC700 (2553267968)\n-12407 Compressed Size       00000A19 (2585)\n-1240B Uncompressed Size     00000A19 (2585)\n-\n-1240F LOCAL HEADER #30      04034B50 (67324752)\n-12413 Extract Zip Spec      14 (20) '2.0'\n-12414 Extract OS            00 (0) 'MS-DOS'\n-12415 General Purpose Flag  0008 (8)\n-      [Bit  3]              1 'Streamed'\n-12417 Compression Method    0000 (0) 'Stored'\n-12419 Modification Time     EC210000 (3961585664) 'Wed Jan  1 00:00:00 2098'\n-1241D CRC                   00000000 (0)\n-12421 Compressed Size       00000000 (0)\n-12425 Uncompressed Size     00000000 (0)\n-12429 Filename Length       0038 (56)\n-1242B Extra Length          0009 (9)\n-1242D Filename              'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX'\n-#\n-# WARNING: Offset 0x1242D: Filename 'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX'\n-#          Zero length filename\n-#\n-12465 Extra ID #1           5455 (21589) 'Extended Timestamp [UT]'\n-12467   Length              0005 (5)\n-12469   Flags               01 (1) 'Modification'\n-1246A   Modification Time   00000000 (0) 'Thu Jan  1 00:00:00 1970'\n-1246E PAYLOAD\n-\n-1308C DATA DESCRIPTOR       08074B50 (134695760)\n-13090 CRC                   C6A73CC6 (3332848838)\n-13094 Compressed Size       00000C1E (3102)\n-13098 Uncompressed Size     00000C1E (3102)\n-\n-1309C LOCAL HEADER #31      04034B50 (67324752)\n-130A0 Extract Zip Spec      14 (20) '2.0'\n-130A1 Extract OS            00 (0) 'MS-DOS'\n-130A2 General Purpose Flag  0008 (8)\n-      [Bit  3]              1 'Streamed'\n-130A4 Compression Method    0000 (0) 'Stored'\n-130A6 Modification Time     EC210000 (3961585664) 'Wed Jan  1 00:00:00 2098'\n-130AA CRC                   00000000 (0)\n-130AE Compressed Size       00000000 (0)\n-130B2 Uncompressed Size     00000000 (0)\n-130B6 Filename Length       0036 (54)\n-130B8 Extra Length          0009 (9)\n-130BA Filename              'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX'\n-#\n-# WARNING: Offset 0x130BA: Filename 'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX'\n-#          Zero length filename\n-#\n-130F0 Extra ID #1           5455 (21589) 'Extended Timestamp [UT]'\n-130F2   Length              0005 (5)\n-130F4   Flags               01 (1) 'Modification'\n-130F5   Modification Time   00000000 (0) 'Thu Jan  1 00:00:00 1970'\n-130F9 PAYLOAD\n-\n-136AA DATA DESCRIPTOR       08074B50 (134695760)\n-136AE CRC                   94899E78 (2492046968)\n-136B2 Compressed Size       000005B1 (1457)\n-136B6 Uncompressed Size     000005B1 (1457)\n-\n-136BA LOCAL HEADER #32      04034B50 (67324752)\n-136BE Extract Zip Spec      14 (20) '2.0'\n-136BF Extract OS            00 (0) 'MS-DOS'\n-136C0 General Purpose Flag  0008 (8)\n-      [Bit  3]              1 'Streamed'\n-136C2 Compression Method    0000 (0) 'Stored'\n-136C4 Modification Time     EC210000 (3961585664) 'Wed Jan  1 00:00:00 2098'\n-136C8 CRC                   00000000 (0)\n-136CC Compressed Size       00000000 (0)\n-136D0 Uncompressed Size     00000000 (0)\n-136D4 Filename Length       0035 (53)\n-136D6 Extra Length          0009 (9)\n-136D8 Filename              'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX'\n-#\n-# WARNING: Offset 0x136D8: Filename 'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX'\n-#          Zero length filename\n-#\n-1370D Extra ID #1           5455 (21589) 'Extended Timestamp [UT]'\n-1370F   Length              0005 (5)\n-13711   Flags               01 (1) 'Modification'\n-13712   Modification Time   00000000 (0) 'Thu Jan  1 00:00:00 1970'\n-13716 PAYLOAD\n-\n-156EF DATA DESCRIPTOR       08074B50 (134695760)\n-156F3 CRC                   4247D839 (1112004665)\n-156F7 Compressed Size       00001FD9 (8153)\n-156FB Uncompressed Size     00001FD9 (8153)\n-\n-156FF LOCAL HEADER #33      04034B50 (67324752)\n-15703 Extract Zip Spec      14 (20) '2.0'\n-15704 Extract OS            00 (0) 'MS-DOS'\n-15705 General Purpose Flag  0008 (8)\n-      [Bit  3]              1 'Streamed'\n-15707 Compression Method    0000 (0) 'Stored'\n-15709 Modification Time     EC210000 (3961585664) 'Wed Jan  1 00:00:00 2098'\n-1570D CRC                   00000000 (0)\n-15711 Compressed Size       00000000 (0)\n-15715 Uncompressed Size     00000000 (0)\n-15719 Filename Length       0036 (54)\n-1571B Extra Length          0009 (9)\n-1571D Filename              'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX'\n-#\n-# WARNING: Offset 0x1571D: Filename 'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX'\n-#          Zero length filename\n-#\n-15753 Extra ID #1           5455 (21589) 'Extended Timestamp [UT]'\n-15755   Length              0005 (5)\n-15757   Flags               01 (1) 'Modification'\n-15758   Modification Time   00000000 (0) 'Thu Jan  1 00:00:00 1970'\n-1575C PAYLOAD\n-\n-1C293 DATA DESCRIPTOR       08074B50 (134695760)\n-1C297 CRC                   C2B511E4 (3266646500)\n-1C29B Compressed Size       00006B37 (27447)\n-1C29F Uncompressed Size     00006B37 (27447)\n-\n-1C2A3 LOCAL HEADER #34      04034B50 (67324752)\n-1C2A7 Extract Zip Spec      14 (20) '2.0'\n-1C2A8 Extract OS            00 (0) 'MS-DOS'\n-1C2A9 General Purpose Flag  0008 (8)\n-      [Bit  3]              1 'Streamed'\n-1C2AB Compression Method    0000 (0) 'Stored'\n-1C2AD Modification Time     EC210000 (3961585664) 'Wed Jan  1 00:00:00 2098'\n-1C2B1 CRC                   00000000 (0)\n-1C2B5 Compressed Size       00000000 (0)\n-1C2B9 Uncompressed Size     00000000 (0)\n-1C2BD Filename Length       003C (60)\n-1C2BF Extra Length          0009 (9)\n-1C2C1 Filename              'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX'\n-#\n-# WARNING: Offset 0x1C2C1: Filename 'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX'\n-#          Zero length filename\n-#\n-1C2FD Extra ID #1           5455 (21589) 'Extended Timestamp [UT]'\n-1C2FF   Length              0005 (5)\n-1C301   Flags               01 (1) 'Modification'\n-1C302   Modification Time   00000000 (0) 'Thu Jan  1 00:00:00 1970'\n-1C306 PAYLOAD\n-\n-1CA1A DATA DESCRIPTOR       08074B50 (134695760)\n-1CA1E CRC                   7317DB5C (1930943324)\n-1CA22 Compressed Size       00000714 (1812)\n-1CA26 Uncompressed Size     00000714 (1812)\n-\n-1CA2A LOCAL HEADER #35      04034B50 (67324752)\n-1CA2E Extract Zip Spec      14 (20) '2.0'\n-1CA2F Extract OS            00 (0) 'MS-DOS'\n-1CA30 General Purpose Flag  0008 (8)\n-      [Bit  3]              1 'Streamed'\n-1CA32 Compression Method    0000 (0) 'Stored'\n-1CA34 Modification Time     EC210000 (3961585664) 'Wed Jan  1 00:00:00 2098'\n-1CA38 CRC                   00000000 (0)\n-1CA3C Compressed Size       00000000 (0)\n-1CA40 Uncompressed Size     00000000 (0)\n-1CA44 Filename Length       0042 (66)\n-1CA46 Extra Length          0009 (9)\n-1CA48 Filename              'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX'\n-#\n-# WARNING: Offset 0x1CA48: Filename 'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX'\n-#          Zero length filename\n-#\n-1CA8A Extra ID #1           5455 (21589) 'Extended Timestamp [UT]'\n-1CA8C   Length              0005 (5)\n-1CA8E   Flags               01 (1) 'Modification'\n-1CA8F   Modification Time   00000000 (0) 'Thu Jan  1 00:00:00 1970'\n-1CA93 PAYLOAD\n-\n-1EA5F DATA DESCRIPTOR       08074B50 (134695760)\n-1EA63 CRC                   344C1E36 (877403702)\n-1EA67 Compressed Size       00001FCC (8140)\n-1EA6B Uncompressed Size     00001FCC (8140)\n-\n-1EA6F LOCAL HEADER #36      04034B50 (67324752)\n-1EA73 Extract Zip Spec      14 (20) '2.0'\n-1EA74 Extract OS            00 (0) 'MS-DOS'\n-1EA75 General Purpose Flag  0008 (8)\n-      [Bit  3]              1 'Streamed'\n-1EA77 Compression Method    0000 (0) 'Stored'\n-1EA79 Modification Time     EC210000 (3961585664) 'Wed Jan  1 00:00:00 2098'\n-1EA7D CRC                   00000000 (0)\n-1EA81 Compressed Size       00000000 (0)\n-1EA85 Uncompressed Size     00000000 (0)\n-1EA89 Filename Length       0045 (69)\n-1EA8B Extra Length          0009 (9)\n-1EA8D Filename              'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX'\n-#\n-# WARNING: Offset 0x1EA8D: Filename 'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX'\n-#          Zero length filename\n-#\n-1EAD2 Extra ID #1           5455 (21589) 'Extended Timestamp [UT]'\n-1EAD4   Length              0005 (5)\n-1EAD6   Flags               01 (1) 'Modification'\n-1EAD7   Modification Time   00000000 (0) 'Thu Jan  1 00:00:00 1970'\n-1EADB PAYLOAD\n-\n-202A2 DATA DESCRIPTOR       08074B50 (134695760)\n-202A6 CRC                   3B14B127 (991211815)\n-202AA Compressed Size       000017C7 (6087)\n-202AE Uncompressed Size     000017C7 (6087)\n-\n-202B2 LOCAL HEADER #37      04034B50 (67324752)\n-202B6 Extract Zip Spec      14 (20) '2.0'\n-202B7 Extract OS            00 (0) 'MS-DOS'\n-202B8 General Purpose Flag  0000 (0)\n-202BA Compression Method    0000 (0) 'Stored'\n-202BC Modification Time     EC210000 (3961585664) 'Wed Jan  1 00:00:00 2098'\n-202C0 CRC                   00000000 (0)\n-202C4 Compressed Size       00000000 (0)\n-202C8 Uncompressed Size     00000000 (0)\n-202CC Filename Length       002B (43)\n-202CE Extra Length          0009 (9)\n-202D0 Filename              'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX'\n-#\n-# WARNING: Offset 0x202D0: Filename 'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX'\n-#          Zero length filename\n-#\n-202FB Extra ID #1           5455 (21589) 'Extended Timestamp [UT]'\n-202FD   Length              0005 (5)\n-202FF   Flags               01 (1) 'Modification'\n-20300   Modification Time   00000000 (0) 'Thu Jan  1 00:00:00 1970'\n-\n-20304 LOCAL HEADER #38      04034B50 (67324752)\n-20308 Extract Zip Spec      14 (20) '2.0'\n-20309 Extract OS            00 (0) 'MS-DOS'\n-2030A General Purpose Flag  0008 (8)\n-      [Bit  3]              1 'Streamed'\n-2030C Compression Method    0000 (0) 'Stored'\n-2030E Modification Time     EC210000 (3961585664) 'Wed Jan  1 00:00:00 2098'\n-20312 CRC                   00000000 (0)\n-20316 Compressed Size       00000000 (0)\n-2031A Uncompressed Size     00000000 (0)\n-2031E Filename Length       003C (60)\n-20320 Extra Length          0009 (9)\n-20322 Filename              'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX'\n-#\n-# WARNING: Offset 0x20322: Filename 'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX'\n-#          Zero length filename\n-#\n-2035E Extra ID #1           5455 (21589) 'Extended Timestamp [UT]'\n-20360   Length              0005 (5)\n-20362   Flags               01 (1) 'Modification'\n-20363   Modification Time   00000000 (0) 'Thu Jan  1 00:00:00 1970'\n-20367 PAYLOAD\n-\n-2258F DATA DESCRIPTOR       08074B50 (134695760)\n-22593 CRC                   1915FFAE (420872110)\n-22597 Compressed Size       00002228 (8744)\n-2259B Uncompressed Size     00002228 (8744)\n-\n-2259F LOCAL HEADER #39      04034B50 (67324752)\n-225A3 Extract Zip Spec      14 (20) '2.0'\n-225A4 Extract OS            00 (0) 'MS-DOS'\n-225A5 General Purpose Flag  0008 (8)\n-      [Bit  3]              1 'Streamed'\n-225A7 Compression Method    0000 (0) 'Stored'\n-225A9 Modification Time     EC210000 (3961585664) 'Wed Jan  1 00:00:00 2098'\n-225AD CRC                   00000000 (0)\n-225B1 Compressed Size       00000000 (0)\n-225B5 Uncompressed Size     00000000 (0)\n-225B9 Filename Length       003B (59)\n-225BB Extra Length          0009 (9)\n-225BD Filename              'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX'\n-#\n-# WARNING: Offset 0x225BD: Filename 'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX'\n-#          Zero length filename\n-#\n-225F8 Extra ID #1           5455 (21589) 'Extended Timestamp [UT]'\n-225FA   Length              0005 (5)\n-225FC   Flags               01 (1) 'Modification'\n-225FD   Modification Time   00000000 (0) 'Thu Jan  1 00:00:00 1970'\n-22601 PAYLOAD\n-\n-23C49 DATA DESCRIPTOR       08074B50 (134695760)\n-23C4D CRC                   B4BC5053 (3032240211)\n-23C51 Compressed Size       00001648 (5704)\n-23C55 Uncompressed Size     00001648 (5704)\n-\n-23C59 LOCAL HEADER #40      04034B50 (67324752)\n-23C5D Extract Zip Spec      14 (20) '2.0'\n-23C5E Extract OS            00 (0) 'MS-DOS'\n-23C5F General Purpose Flag  0000 (0)\n-23C61 Compression Method    0000 (0) 'Stored'\n-23C63 Modification Time     EC210000 (3961585664) 'Wed Jan  1 00:00:00 2098'\n-23C67 CRC                   00000000 (0)\n-23C6B Compressed Size       00000000 (0)\n-23C6F Uncompressed Size     00000000 (0)\n-23C73 Filename Length       002B (43)\n-23C75 Extra Length          0009 (9)\n-23C77 Filename              'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX'\n-#\n-# WARNING: Offset 0x23C77: Filename 'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX'\n-#          Zero length filename\n-#\n-23CA2 Extra ID #1           5455 (21589) 'Extended Timestamp [UT]'\n-23CA4   Length              0005 (5)\n-23CA6   Flags               01 (1) 'Modification'\n-23CA7   Modification Time   00000000 (0) 'Thu Jan  1 00:00:00 1970'\n-\n-23CAB LOCAL HEADER #41      04034B50 (67324752)\n-23CAF Extract Zip Spec      14 (20) '2.0'\n-23CB0 Extract OS            00 (0) 'MS-DOS'\n-23CB1 General Purpose Flag  0008 (8)\n-      [Bit  3]              1 'Streamed'\n-23CB3 Compression Method    0000 (0) 'Stored'\n-23CB5 Modification Time     EC210000 (3961585664) 'Wed Jan  1 00:00:00 2098'\n-23CB9 CRC                   00000000 (0)\n-23CBD Compressed Size       00000000 (0)\n-23CC1 Uncompressed Size     00000000 (0)\n-23CC5 Filename Length       0043 (67)\n-23CC7 Extra Length          0009 (9)\n-23CC9 Filename              'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX'\n-#\n-# WARNING: Offset 0x23CC9: Filename 'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX'\n-#          Zero length filename\n-#\n-23D0C Extra ID #1           5455 (21589) 'Extended Timestamp [UT]'\n-23D0E   Length              0005 (5)\n-23D10   Flags               01 (1) 'Modification'\n-23D11   Modification Time   00000000 (0) 'Thu Jan  1 00:00:00 1970'\n-23D15 PAYLOAD\n-\n-245F9 DATA DESCRIPTOR       08074B50 (134695760)\n-245FD CRC                   C9453D78 (3376758136)\n-24601 Compressed Size       000008E4 (2276)\n-24605 Uncompressed Size     000008E4 (2276)\n-\n-24609 LOCAL HEADER #42      04034B50 (67324752)\n-2460D Extract Zip Spec      14 (20) '2.0'\n-2460E Extract OS            00 (0) 'MS-DOS'\n-2460F General Purpose Flag  0008 (8)\n-      [Bit  3]              1 'Streamed'\n-24611 Compression Method    0000 (0) 'Stored'\n-24613 Modification Time     EC210000 (3961585664) 'Wed Jan  1 00:00:00 2098'\n-24617 CRC                   00000000 (0)\n-2461B Compressed Size       00000000 (0)\n-2461F Uncompressed Size     00000000 (0)\n-24623 Filename Length       0047 (71)\n-24625 Extra Length          0009 (9)\n-24627 Filename              'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX'\n-#\n-# WARNING: Offset 0x24627: Filename 'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX'\n-#          Zero length filename\n-#\n-2466E Extra ID #1           5455 (21589) 'Extended Timestamp [UT]'\n-24670   Length              0005 (5)\n-24672   Flags               01 (1) 'Modification'\n-24673   Modification Time   00000000 (0) 'Thu Jan  1 00:00:00 1970'\n-24677 PAYLOAD\n-\n-251FD DATA DESCRIPTOR       08074B50 (134695760)\n-25201 CRC                   5A226E99 (1512205977)\n-25205 Compressed Size       00000B86 (2950)\n-25209 Uncompressed Size     00000B86 (2950)\n-\n-2520D CENTRAL HEADER #1     02014B50 (33639248)\n-25211 Created Zip Spec      14 (20) '2.0'\n-25212 Created OS            00 (0) 'MS-DOS'\n-25213 Extract Zip Spec      14 (20) '2.0'\n-25214 Extract OS            00 (0) 'MS-DOS'\n-25215 General Purpose Flag  0000 (0)\n-25217 Compression Method    0000 (0) 'Stored'\n-25219 Modification Time     EC210000 (3961585664) 'Wed Jan  1 00:00:00 2098'\n-2521D CRC                   00000000 (0)\n-25221 Compressed Size       00000000 (0)\n-25225 Uncompressed Size     00000000 (0)\n-25229 Filename Length       0009 (9)\n-2522B Extra Length          0009 (9)\n-2522D Comment Length        0000 (0)\n-2522F Disk Start            0000 (0)\n-25231 Int File Attributes   0000 (0)\n-      [Bit 0]               0 'Binary Data'\n-25233 Ext File Attributes   00000000 (0)\n-25237 Local Header Offset   00000000 (0)\n-2523B Filename              'XXXXXXXXX'\n-#\n-# WARNING: Offset 0x2523B: Filename 'XXXXXXXXX'\n-#          Zero length filename\n-#\n-25244 Extra ID #1           5455 (21589) 'Extended Timestamp [UT]'\n-25246   Length              0005 (5)\n-25248   Flags               01 (1) 'Modification'\n-25249   Modification Time   00000000 (0) 'Thu Jan  1 00:00:00 1970'\n-\n-2524D CENTRAL HEADER #2     02014B50 (33639248)\n-25251 Created Zip Spec      14 (20) '2.0'\n-25252 Created OS            00 (0) 'MS-DOS'\n-25253 Extract Zip Spec      14 (20) '2.0'\n-25254 Extract OS            00 (0) 'MS-DOS'\n-25255 General Purpose Flag  0008 (8)\n-      [Bit  3]              1 'Streamed'\n-25257 Compression Method    0000 (0) 'Stored'\n-25259 Modification Time     EC210000 (3961585664) 'Wed Jan  1 00:00:00 2098'\n-2525D CRC                   CFC19B47 (3485571911)\n-25261 Compressed Size       00000C40 (3136)\n-25265 Uncompressed Size     00000C40 (3136)\n-25269 Filename Length       0015 (21)\n-2526B Extra Length          0009 (9)\n-2526D Comment Length        0000 (0)\n-2526F Disk Start            0000 (0)\n-25271 Int File Attributes   0000 (0)\n-      [Bit 0]               0 'Binary Data'\n-25273 Ext File Attributes   00000000 (0)\n-25277 Local Header Offset   00000030 (48)\n-2527B Filename              'XXXXXXXXXXXXXXXXXXXXX'\n-#\n-# WARNING: Offset 0x2527B: Filename 'XXXXXXXXXXXXXXXXXXXXX'\n-#          Zero length filename\n-#\n-25290 Extra ID #1           5455 (21589) 'Extended Timestamp [UT]'\n-25292   Length              0005 (5)\n-25294   Flags               01 (1) 'Modification'\n-25295   Modification Time   00000000 (0) 'Thu Jan  1 00:00:00 1970'\n-\n-25299 CENTRAL HEADER #3     02014B50 (33639248)\n-2529D Created Zip Spec      14 (20) '2.0'\n-2529E Created OS            00 (0) 'MS-DOS'\n-2529F Extract Zip Spec      14 (20) '2.0'\n-252A0 Extract OS            00 (0) 'MS-DOS'\n-252A1 General Purpose Flag  0008 (8)\n-      [Bit  3]              1 'Streamed'\n-252A3 Compression Method    0000 (0) 'Stored'\n-252A5 Modification Time     EC210000 (3961585664) 'Wed Jan  1 00:00:00 2098'\n-252A9 CRC                   86E2B4B4 (2263004340)\n-252AD Compressed Size       00002C5E (11358)\n-252B1 Uncompressed Size     00002C5E (11358)\n-252B5 Filename Length       0010 (16)\n-252B7 Extra Length          0009 (9)\n-252B9 Comment Length        0000 (0)\n-252BB Disk Start            0000 (0)\n-252BD Int File Attributes   0000 (0)\n-      [Bit 0]               0 'Binary Data'\n-252BF Ext File Attributes   00000000 (0)\n-252C3 Local Header Offset   00000CBC (3260)\n-252C7 Filename              'XXXXXXXXXXXXXXXX'\n-#\n-# WARNING: Offset 0x252C7: Filename 'XXXXXXXXXXXXXXXX'\n-#          Zero length filename\n-#\n-252D7 Extra ID #1           5455 (21589) 'Extended Timestamp [UT]'\n-252D9   Length              0005 (5)\n-252DB   Flags               01 (1) 'Modification'\n-252DC   Modification Time   00000000 (0) 'Thu Jan  1 00:00:00 1970'\n-\n-252E0 CENTRAL HEADER #4     02014B50 (33639248)\n-252E4 Created Zip Spec      14 (20) '2.0'\n-252E5 Created OS            00 (0) 'MS-DOS'\n-252E6 Extract Zip Spec      14 (20) '2.0'\n-252E7 Extract OS            00 (0) 'MS-DOS'\n-252E8 General Purpose Flag  0008 (8)\n-      [Bit  3]              1 'Streamed'\n-252EA Compression Method    0000 (0) 'Stored'\n-252EC Modification Time     EC210000 (3961585664) 'Wed Jan  1 00:00:00 2098'\n-252F0 CRC                   EE027FB2 (3993141170)\n-252F4 Compressed Size       00000019 (25)\n-252F8 Uncompressed Size     00000019 (25)\n-252FC Filename Length       0014 (20)\n-252FE Extra Length          0009 (9)\n-25300 Comment Length        0000 (0)\n-25302 Disk Start            0000 (0)\n-25304 Int File Attributes   0000 (0)\n-      [Bit 0]               0 'Binary Data'\n-25306 Ext File Attributes   00000000 (0)\n-2530A Local Header Offset   00003961 (14689)\n-2530E Filename              'XXXXXXXXXXXXXXXXXXXX'\n-#\n-# WARNING: Offset 0x2530E: Filename 'XXXXXXXXXXXXXXXXXXXX'\n-#          Zero length filename\n-#\n-25322 Extra ID #1           5455 (21589) 'Extended Timestamp [UT]'\n-25324   Length              0005 (5)\n-25326   Flags               01 (1) 'Modification'\n-25327   Modification Time   00000000 (0) 'Thu Jan  1 00:00:00 1970'\n-\n-2532B CENTRAL HEADER #5     02014B50 (33639248)\n-2532F Created Zip Spec      14 (20) '2.0'\n-25330 Created OS            00 (0) 'MS-DOS'\n-25331 Extract Zip Spec      14 (20) '2.0'\n-25332 Extract OS            00 (0) 'MS-DOS'\n-25333 General Purpose Flag  0008 (8)\n-      [Bit  3]              1 'Streamed'\n-25335 Compression Method    0000 (0) 'Stored'\n-25337 Modification Time     EC210000 (3961585664) 'Wed Jan  1 00:00:00 2098'\n-2533B CRC                   9C935012 (2626899986)\n-2533F Compressed Size       000000AC (172)\n-25343 Uncompressed Size     000000AC (172)\n-25347 Filename Length       000F (15)\n-25349 Extra Length          0009 (9)\n-2534B Comment Length        0000 (0)\n-2534D Disk Start            0000 (0)\n-2534F Int File Attributes   0000 (0)\n-      [Bit 0]               0 'Binary Data'\n-25351 Ext File Attributes   00000000 (0)\n-25355 Local Header Offset   000039C5 (14789)\n-25359 Filename              'XXXXXXXXXXXXXXX'\n-#\n-# WARNING: Offset 0x25359: Filename 'XXXXXXXXXXXXXXX'\n-#          Zero length filename\n-#\n-25368 Extra ID #1           5455 (21589) 'Extended Timestamp [UT]'\n-2536A   Length              0005 (5)\n-2536C   Flags               01 (1) 'Modification'\n-2536D   Modification Time   00000000 (0) 'Thu Jan  1 00:00:00 1970'\n-\n-25371 CENTRAL HEADER #6     02014B50 (33639248)\n-25375 Created Zip Spec      14 (20) '2.0'\n-25376 Created OS            00 (0) 'MS-DOS'\n-25377 Extract Zip Spec      14 (20) '2.0'\n-25378 Extract OS            00 (0) 'MS-DOS'\n-25379 General Purpose Flag  0000 (0)\n-2537B Compression Method    0000 (0) 'Stored'\n-2537D Modification Time     EC210000 (3961585664) 'Wed Jan  1 00:00:00 2098'\n-25381 CRC                   00000000 (0)\n-25385 Compressed Size       00000000 (0)\n-25389 Uncompressed Size     00000000 (0)\n-2538D Filename Length       000F (15)\n-2538F Extra Length          0009 (9)\n-25391 Comment Length        0000 (0)\n-25393 Disk Start            0000 (0)\n-25395 Int File Attributes   0000 (0)\n-      [Bit 0]               0 'Binary Data'\n-25397 Ext File Attributes   00000000 (0)\n-2539B Local Header Offset   00003AB7 (15031)\n-2539F Filename              'XXXXXXXXXXXXXXX'\n-#\n-# WARNING: Offset 0x2539F: Filename 'XXXXXXXXXXXXXXX'\n-#          Zero length filename\n-#\n-253AE Extra ID #1           5455 (21589) 'Extended Timestamp [UT]'\n-253B0   Length              0005 (5)\n-253B2   Flags               01 (1) 'Modification'\n-253B3   Modification Time   00000000 (0) 'Thu Jan  1 00:00:00 1970'\n-\n-253B7 CENTRAL HEADER #7     02014B50 (33639248)\n-253BB Created Zip Spec      14 (20) '2.0'\n-253BC Created OS            00 (0) 'MS-DOS'\n-253BD Extract Zip Spec      14 (20) '2.0'\n-253BE Extract OS            00 (0) 'MS-DOS'\n-253BF General Purpose Flag  0000 (0)\n-253C1 Compression Method    0000 (0) 'Stored'\n-253C3 Modification Time     EC210000 (3961585664) 'Wed Jan  1 00:00:00 2098'\n-253C7 CRC                   00000000 (0)\n-253CB Compressed Size       00000000 (0)\n-253CF Uncompressed Size     00000000 (0)\n-253D3 Filename Length       0018 (24)\n-253D5 Extra Length          0009 (9)\n-253D7 Comment Length        0000 (0)\n-253D9 Disk Start            0000 (0)\n-253DB Int File Attributes   0000 (0)\n-      [Bit 0]               0 'Binary Data'\n-253DD Ext File Attributes   00000000 (0)\n-253E1 Local Header Offset   00003AED (15085)\n-253E5 Filename              'XXXXXXXXXXXXXXXXXXXXXXXX'\n-#\n-# WARNING: Offset 0x253E5: Filename 'XXXXXXXXXXXXXXXXXXXXXXXX'\n-#          Zero length filename\n-#\n-253FD Extra ID #1           5455 (21589) 'Extended Timestamp [UT]'\n-253FF   Length              0005 (5)\n-25401   Flags               01 (1) 'Modification'\n-25402   Modification Time   00000000 (0) 'Thu Jan  1 00:00:00 1970'\n-\n-25406 CENTRAL HEADER #8     02014B50 (33639248)\n-2540A Created Zip Spec      14 (20) '2.0'\n-2540B Created OS            00 (0) 'MS-DOS'\n-2540C Extract Zip Spec      14 (20) '2.0'\n-2540D Extract OS            00 (0) 'MS-DOS'\n-2540E General Purpose Flag  0008 (8)\n-      [Bit  3]              1 'Streamed'\n-25410 Compression Method    0000 (0) 'Stored'\n-25412 Modification Time     EC210000 (3961585664) 'Wed Jan  1 00:00:00 2098'\n-25416 CRC                   2D68A65E (761833054)\n-2541A Compressed Size       00000094 (148)\n-2541E Uncompressed Size     00000094 (148)\n-25422 Filename Length       0044 (68)\n-25424 Extra Length          0009 (9)\n-25426 Comment Length        0000 (0)\n-25428 Disk Start            0000 (0)\n-2542A Int File Attributes   0000 (0)\n-      [Bit 0]               0 'Binary Data'\n-2542C Ext File Attributes   00000000 (0)\n-25430 Local Header Offset   00003B2C (15148)\n-25434 Filename              'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX'\n-#\n-# WARNING: Offset 0x25434: Filename 'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX'\n-#          Zero length filename\n-#\n-25478 Extra ID #1           5455 (21589) 'Extended Timestamp [UT]'\n-2547A   Length              0005 (5)\n-2547C   Flags               01 (1) 'Modification'\n-2547D   Modification Time   00000000 (0) 'Thu Jan  1 00:00:00 1970'\n-\n-25481 CENTRAL HEADER #9     02014B50 (33639248)\n-25485 Created Zip Spec      14 (20) '2.0'\n-25486 Created OS            00 (0) 'MS-DOS'\n-25487 Extract Zip Spec      14 (20) '2.0'\n-25488 Extract OS            00 (0) 'MS-DOS'\n-25489 General Purpose Flag  0008 (8)\n-      [Bit  3]              1 'Streamed'\n-2548B Compression Method    0000 (0) 'Stored'\n-2548D Modification Time     EC210000 (3961585664) 'Wed Jan  1 00:00:00 2098'\n-25491 CRC                   A5009E2B (2768281131)\n-25495 Compressed Size       00000039 (57)\n-25499 Uncompressed Size     00000039 (57)\n-2549D Filename Length       0038 (56)\n-2549F Extra Length          0009 (9)\n-254A1 Comment Length        0000 (0)\n-254A3 Disk Start            0000 (0)\n-254A5 Int File Attributes   0000 (0)\n-      [Bit 0]               0 'Binary Data'\n-254A7 Ext File Attributes   00000000 (0)\n-254AB Local Header Offset   00003C3B (15419)\n-254AF Filename              'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX'\n-#\n-# WARNING: Offset 0x254AF: Filename 'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX'\n-#          Zero length filename\n-#\n-254E7 Extra ID #1           5455 (21589) 'Extended Timestamp [UT]'\n-254E9   Length              0005 (5)\n-254EB   Flags               01 (1) 'Modification'\n-254EC   Modification Time   00000000 (0) 'Thu Jan  1 00:00:00 1970'\n-\n-254F0 CENTRAL HEADER #10    02014B50 (33639248)\n-254F4 Created Zip Spec      14 (20) '2.0'\n-254F5 Created OS            00 (0) 'MS-DOS'\n-254F6 Extract Zip Spec      14 (20) '2.0'\n-254F7 Extract OS            00 (0) 'MS-DOS'\n-254F8 General Purpose Flag  0008 (8)\n-      [Bit  3]              1 'Streamed'\n-254FA Compression Method    0000 (0) 'Stored'\n-254FC Modification Time     EC210000 (3961585664) 'Wed Jan  1 00:00:00 2098'\n-25500 CRC                   A3C6F966 (2747726182)\n-25504 Compressed Size       0000007C (124)\n-25508 Uncompressed Size     0000007C (124)\n-2550C Filename Length       0033 (51)\n-2550E Extra Length          0009 (9)\n-25510 Comment Length        0000 (0)\n-25512 Disk Start            0000 (0)\n-25514 Int File Attributes   0000 (0)\n-      [Bit 0]               0 'Binary Data'\n-25516 Ext File Attributes   00000000 (0)\n-2551A Local Header Offset   00003CE3 (15587)\n-2551E Filename              'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX'\n-#\n-# WARNING: Offset 0x2551E: Filename 'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX'\n-#          Zero length filename\n-#\n-25551 Extra ID #1           5455 (21589) 'Extended Timestamp [UT]'\n-25553   Length              0005 (5)\n-25555   Flags               01 (1) 'Modification'\n-25556   Modification Time   00000000 (0) 'Thu Jan  1 00:00:00 1970'\n-\n-2555A CENTRAL HEADER #11    02014B50 (33639248)\n-2555E Created Zip Spec      14 (20) '2.0'\n-2555F Created OS            00 (0) 'MS-DOS'\n-25560 Extract Zip Spec      14 (20) '2.0'\n-25561 Extract OS            00 (0) 'MS-DOS'\n-25562 General Purpose Flag  0008 (8)\n-      [Bit  3]              1 'Streamed'\n-25564 Compression Method    0000 (0) 'Stored'\n-25566 Modification Time     EC210000 (3961585664) 'Wed Jan  1 00:00:00 2098'\n-2556A CRC                   83A37AD0 (2208529104)\n-2556E Compressed Size       00000037 (55)\n-25572 Uncompressed Size     00000037 (55)\n-25576 Filename Length       0035 (53)\n-25578 Extra Length          0009 (9)\n-2557A Comment Length        0000 (0)\n-2557C Disk Start            0000 (0)\n-2557E Int File Attributes   0000 (0)\n-      [Bit 0]               0 'Binary Data'\n-25580 Ext File Attributes   00000000 (0)\n-25584 Local Header Offset   00003DC9 (15817)\n-25588 Filename              'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX'\n-#\n-# WARNING: Offset 0x25588: Filename 'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX'\n-#          Zero length filename\n-#\n-255BD Extra ID #1           5455 (21589) 'Extended Timestamp [UT]'\n-255BF   Length              0005 (5)\n-255C1   Flags               01 (1) 'Modification'\n-255C2   Modification Time   00000000 (0) 'Thu Jan  1 00:00:00 1970'\n-\n-255C6 CENTRAL HEADER #12    02014B50 (33639248)\n-255CA Created Zip Spec      14 (20) '2.0'\n-255CB Created OS            00 (0) 'MS-DOS'\n-255CC Extract Zip Spec      14 (20) '2.0'\n-255CD Extract OS            00 (0) 'MS-DOS'\n-255CE General Purpose Flag  0000 (0)\n-255D0 Compression Method    0000 (0) 'Stored'\n-255D2 Modification Time     EC210000 (3961585664) 'Wed Jan  1 00:00:00 2098'\n-255D6 CRC                   00000000 (0)\n-255DA Compressed Size       00000000 (0)\n-255DE Uncompressed Size     00000000 (0)\n-255E2 Filename Length       000F (15)\n-255E4 Extra Length          0009 (9)\n-255E6 Comment Length        0000 (0)\n-255E8 Disk Start            0000 (0)\n-255EA Int File Attributes   0000 (0)\n-      [Bit 0]               0 'Binary Data'\n-255EC Ext File Attributes   00000000 (0)\n-255F0 Local Header Offset   00003E6C (15980)\n-255F4 Filename              'XXXXXXXXXXXXXXX'\n-#\n-# WARNING: Offset 0x255F4: Filename 'XXXXXXXXXXXXXXX'\n-#          Zero length filename\n-#\n-25603 Extra ID #1           5455 (21589) 'Extended Timestamp [UT]'\n-25605   Length              0005 (5)\n-25607   Flags               01 (1) 'Modification'\n-25608   Modification Time   00000000 (0) 'Thu Jan  1 00:00:00 1970'\n-\n-2560C CENTRAL HEADER #13    02014B50 (33639248)\n-25610 Created Zip Spec      14 (20) '2.0'\n-25611 Created OS            00 (0) 'MS-DOS'\n-25612 Extract Zip Spec      14 (20) '2.0'\n-25613 Extract OS            00 (0) 'MS-DOS'\n-25614 General Purpose Flag  0000 (0)\n-25616 Compression Method    0000 (0) 'Stored'\n-25618 Modification Time     EC210000 (3961585664) 'Wed Jan  1 00:00:00 2098'\n-2561C CRC                   00000000 (0)\n-25620 Compressed Size       00000000 (0)\n-25624 Uncompressed Size     00000000 (0)\n-25628 Filename Length       0020 (32)\n-2562A Extra Length          0009 (9)\n-2562C Comment Length        0000 (0)\n-2562E Disk Start            0000 (0)\n-25630 Int File Attributes   0000 (0)\n-      [Bit 0]               0 'Binary Data'\n-25632 Ext File Attributes   00000000 (0)\n-25636 Local Header Offset   00003EA2 (16034)\n-2563A Filename              'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX'\n-#\n-# WARNING: Offset 0x2563A: Filename 'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX'\n-#          Zero length filename\n-#\n-2565A Extra ID #1           5455 (21589) 'Extended Timestamp [UT]'\n-2565C   Length              0005 (5)\n-2565E   Flags               01 (1) 'Modification'\n-2565F   Modification Time   00000000 (0) 'Thu Jan  1 00:00:00 1970'\n-\n-25663 CENTRAL HEADER #14    02014B50 (33639248)\n-25667 Created Zip Spec      14 (20) '2.0'\n-25668 Created OS            00 (0) 'MS-DOS'\n-25669 Extract Zip Spec      14 (20) '2.0'\n-2566A Extract OS            00 (0) 'MS-DOS'\n-2566B General Purpose Flag  0000 (0)\n-2566D Compression Method    0000 (0) 'Stored'\n-2566F Modification Time     EC210000 (3961585664) 'Wed Jan  1 00:00:00 2098'\n-25673 CRC                   00000000 (0)\n-25677 Compressed Size       00000000 (0)\n-2567B Uncompressed Size     00000000 (0)\n-2567F Filename Length       0030 (48)\n-25681 Extra Length          0009 (9)\n-25683 Comment Length        0000 (0)\n-25685 Disk Start            0000 (0)\n-25687 Int File Attributes   0000 (0)\n-      [Bit 0]               0 'Binary Data'\n-25689 Ext File Attributes   00000000 (0)\n-2568D Local Header Offset   00003EE9 (16105)\n-25691 Filename              'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX'\n-#\n-# WARNING: Offset 0x25691: Filename 'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX'\n-#          Zero length filename\n-#\n-256C1 Extra ID #1           5455 (21589) 'Extended Timestamp [UT]'\n-256C3   Length              0005 (5)\n-256C5   Flags               01 (1) 'Modification'\n-256C6   Modification Time   00000000 (0) 'Thu Jan  1 00:00:00 1970'\n-\n-256CA CENTRAL HEADER #15    02014B50 (33639248)\n-256CE Created Zip Spec      14 (20) '2.0'\n-256CF Created OS            00 (0) 'MS-DOS'\n-256D0 Extract Zip Spec      14 (20) '2.0'\n-256D1 Extract OS            00 (0) 'MS-DOS'\n-256D2 General Purpose Flag  0008 (8)\n-      [Bit  3]              1 'Streamed'\n-256D4 Compression Method    0000 (0) 'Stored'\n-256D6 Modification Time     EC210000 (3961585664) 'Wed Jan  1 00:00:00 2098'\n-256DA CRC                   00000000 (0)\n-256DE Compressed Size       00000000 (0)\n-256E2 Uncompressed Size     00000000 (0)\n-256E6 Filename Length       003E (62)\n-256E8 Extra Length          0009 (9)\n-256EA Comment Length        0000 (0)\n-256EC Disk Start            0000 (0)\n-256EE Int File Attributes   0000 (0)\n-      [Bit 0]               0 'Binary Data'\n-256F0 Ext File Attributes   00000000 (0)\n-256F4 Local Header Offset   00003F40 (16192)\n-256F8 Filename              'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX'\n-#\n-# WARNING: Offset 0x256F8: Filename 'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX'\n-#          Zero length filename\n-#\n-25736 Extra ID #1           5455 (21589) 'Extended Timestamp [UT]'\n-25738   Length              0005 (5)\n-2573A   Flags               01 (1) 'Modification'\n-2573B   Modification Time   00000000 (0) 'Thu Jan  1 00:00:00 1970'\n-\n-2573F CENTRAL HEADER #16    02014B50 (33639248)\n-25743 Created Zip Spec      14 (20) '2.0'\n-25744 Created OS            00 (0) 'MS-DOS'\n-25745 Extract Zip Spec      14 (20) '2.0'\n-25746 Extract OS            00 (0) 'MS-DOS'\n-25747 General Purpose Flag  0008 (8)\n-      [Bit  3]              1 'Streamed'\n-25749 Compression Method    0000 (0) 'Stored'\n-2574B Modification Time     EC210000 (3961585664) 'Wed Jan  1 00:00:00 2098'\n-2574F CRC                   45DB5347 (1172001607)\n-25753 Compressed Size       00000FBC (4028)\n-25757 Uncompressed Size     00000FBC (4028)\n-2575B Filename Length       0037 (55)\n-2575D Extra Length          0009 (9)\n-2575F Comment Length        0000 (0)\n-25761 Disk Start            0000 (0)\n-25763 Int File Attributes   0000 (0)\n-      [Bit 0]               0 'Binary Data'\n-25765 Ext File Attributes   00000000 (0)\n-25769 Local Header Offset   00003FB5 (16309)\n-2576D Filename              'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX'\n-#\n-# WARNING: Offset 0x2576D: Filename 'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX'\n-#          Zero length filename\n-#\n-257A4 Extra ID #1           5455 (21589) 'Extended Timestamp [UT]'\n-257A6   Length              0005 (5)\n-257A8   Flags               01 (1) 'Modification'\n-257A9   Modification Time   00000000 (0) 'Thu Jan  1 00:00:00 1970'\n-\n-257AD CENTRAL HEADER #17    02014B50 (33639248)\n-257B1 Created Zip Spec      14 (20) '2.0'\n-257B2 Created OS            00 (0) 'MS-DOS'\n-257B3 Extract Zip Spec      14 (20) '2.0'\n-257B4 Extract OS            00 (0) 'MS-DOS'\n-257B5 General Purpose Flag  0000 (0)\n-257B7 Compression Method    0000 (0) 'Stored'\n-257B9 Modification Time     EC210000 (3961585664) 'Wed Jan  1 00:00:00 2098'\n-257BD CRC                   00000000 (0)\n-257C1 Compressed Size       00000000 (0)\n-257C5 Uncompressed Size     00000000 (0)\n-257C9 Filename Length       0004 (4)\n-257CB Extra Length          0009 (9)\n-257CD Comment Length        0000 (0)\n-257CF Disk Start            0000 (0)\n-257D1 Int File Attributes   0000 (0)\n-      [Bit 0]               0 'Binary Data'\n-257D3 Ext File Attributes   00000000 (0)\n-257D7 Local Header Offset   00004FDF (20447)\n-257DB Filename              'XXXX'\n-#\n-# WARNING: Offset 0x257DB: Filename 'XXXX'\n-#          Zero length filename\n-#\n-257DF Extra ID #1           5455 (21589) 'Extended Timestamp [UT]'\n-257E1   Length              0005 (5)\n-257E3   Flags               01 (1) 'Modification'\n-257E4   Modification Time   00000000 (0) 'Thu Jan  1 00:00:00 1970'\n-\n-257E8 CENTRAL HEADER #18    02014B50 (33639248)\n-257EC Created Zip Spec      14 (20) '2.0'\n-257ED Created OS            00 (0) 'MS-DOS'\n-257EE Extract Zip Spec      14 (20) '2.0'\n-257EF Extract OS            00 (0) 'MS-DOS'\n-257F0 General Purpose Flag  0000 (0)\n-257F2 Compression Method    0000 (0) 'Stored'\n-257F4 Modification Time     EC210000 (3961585664) 'Wed Jan  1 00:00:00 2098'\n-257F8 CRC                   00000000 (0)\n-257FC Compressed Size       00000000 (0)\n-25800 Uncompressed Size     00000000 (0)\n-25804 Filename Length       000B (11)\n-25806 Extra Length          0009 (9)\n-25808 Comment Length        0000 (0)\n-2580A Disk Start            0000 (0)\n-2580C Int File Attributes   0000 (0)\n-      [Bit 0]               0 'Binary Data'\n-2580E Ext File Attributes   00000000 (0)\n-25812 Local Header Offset   0000500A (20490)\n-25816 Filename              'XXXXXXXXXXX'\n-#\n-# WARNING: Offset 0x25816: Filename 'XXXXXXXXXXX'\n-#          Zero length filename\n-#\n-25821 Extra ID #1           5455 (21589) 'Extended Timestamp [UT]'\n-25823   Length              0005 (5)\n-25825   Flags               01 (1) 'Modification'\n-25826   Modification Time   00000000 (0) 'Thu Jan  1 00:00:00 1970'\n-\n-2582A CENTRAL HEADER #19    02014B50 (33639248)\n-2582E Created Zip Spec      14 (20) '2.0'\n-2582F Created OS            00 (0) 'MS-DOS'\n-25830 Extract Zip Spec      14 (20) '2.0'\n-25831 Extract OS            00 (0) 'MS-DOS'\n-25832 General Purpose Flag  0000 (0)\n-25834 Compression Method    0000 (0) 'Stored'\n-25836 Modification Time     EC210000 (3961585664) 'Wed Jan  1 00:00:00 2098'\n-2583A CRC                   00000000 (0)\n-2583E Compressed Size       00000000 (0)\n-25842 Uncompressed Size     00000000 (0)\n-25846 Filename Length       0011 (17)\n-25848 Extra Length          0009 (9)\n-2584A Comment Length        0000 (0)\n-2584C Disk Start            0000 (0)\n-2584E Int File Attributes   0000 (0)\n-      [Bit 0]               0 'Binary Data'\n-25850 Ext File Attributes   00000000 (0)\n-25854 Local Header Offset   0000503C (20540)\n-25858 Filename              'XXXXXXXXXXXXXXXXX'\n-#\n-# WARNING: Offset 0x25858: Filename 'XXXXXXXXXXXXXXXXX'\n-#          Zero length filename\n-#\n-25869 Extra ID #1           5455 (21589) 'Extended Timestamp [UT]'\n-2586B   Length              0005 (5)\n-2586D   Flags               01 (1) 'Modification'\n-2586E   Modification Time   00000000 (0) 'Thu Jan  1 00:00:00 1970'\n-\n-25872 CENTRAL HEADER #20    02014B50 (33639248)\n-25876 Created Zip Spec      14 (20) '2.0'\n-25877 Created OS            00 (0) 'MS-DOS'\n-25878 Extract Zip Spec      14 (20) '2.0'\n-25879 Extract OS            00 (0) 'MS-DOS'\n-2587A General Purpose Flag  0000 (0)\n-2587C Compression Method    0000 (0) 'Stored'\n-2587E Modification Time     EC210000 (3961585664) 'Wed Jan  1 00:00:00 2098'\n-25882 CRC                   00000000 (0)\n-25886 Compressed Size       00000000 (0)\n-2588A Uncompressed Size     00000000 (0)\n-2588E Filename Length       0015 (21)\n-25890 Extra Length          0009 (9)\n-25892 Comment Length        0000 (0)\n-25894 Disk Start            0000 (0)\n-25896 Int File Attributes   0000 (0)\n-      [Bit 0]               0 'Binary Data'\n-25898 Ext File Attributes   00000000 (0)\n-2589C Local Header Offset   00005074 (20596)\n-258A0 Filename              'XXXXXXXXXXXXXXXXXXXXX'\n-#\n-# WARNING: Offset 0x258A0: Filename 'XXXXXXXXXXXXXXXXXXXXX'\n-#          Zero length filename\n-#\n-258B5 Extra ID #1           5455 (21589) 'Extended Timestamp [UT]'\n-258B7   Length              0005 (5)\n-258B9   Flags               01 (1) 'Modification'\n-258BA   Modification Time   00000000 (0) 'Thu Jan  1 00:00:00 1970'\n-\n-258BE CENTRAL HEADER #21    02014B50 (33639248)\n-258C2 Created Zip Spec      14 (20) '2.0'\n-258C3 Created OS            00 (0) 'MS-DOS'\n-258C4 Extract Zip Spec      14 (20) '2.0'\n-258C5 Extract OS            00 (0) 'MS-DOS'\n-258C6 General Purpose Flag  0000 (0)\n-258C8 Compression Method    0000 (0) 'Stored'\n-258CA Modification Time     EC210000 (3961585664) 'Wed Jan  1 00:00:00 2098'\n-258CE CRC                   00000000 (0)\n-258D2 Compressed Size       00000000 (0)\n-258D6 Uncompressed Size     00000000 (0)\n-258DA Filename Length       001E (30)\n-258DC Extra Length          0009 (9)\n-258DE Comment Length        0000 (0)\n-258E0 Disk Start            0000 (0)\n-258E2 Int File Attributes   0000 (0)\n-      [Bit 0]               0 'Binary Data'\n-258E4 Ext File Attributes   00000000 (0)\n-258E8 Local Header Offset   000050B0 (20656)\n-258EC Filename              'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXX'\n-#\n-# WARNING: Offset 0x258EC: Filename 'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXX'\n-#          Zero length filename\n-#\n-2590A Extra ID #1           5455 (21589) 'Extended Timestamp [UT]'\n-2590C   Length              0005 (5)\n-2590E   Flags               01 (1) 'Modification'\n-2590F   Modification Time   00000000 (0) 'Thu Jan  1 00:00:00 1970'\n-\n-25913 CENTRAL HEADER #22    02014B50 (33639248)\n-25917 Created Zip Spec      14 (20) '2.0'\n-25918 Created OS            00 (0) 'MS-DOS'\n-25919 Extract Zip Spec      14 (20) '2.0'\n-2591A Extract OS            00 (0) 'MS-DOS'\n-2591B General Purpose Flag  0000 (0)\n-2591D Compression Method    0000 (0) 'Stored'\n-2591F Modification Time     EC210000 (3961585664) 'Wed Jan  1 00:00:00 2098'\n-25923 CRC                   00000000 (0)\n-25927 Compressed Size       00000000 (0)\n-2592B Uncompressed Size     00000000 (0)\n-2592F Filename Length       0024 (36)\n-25931 Extra Length          0009 (9)\n-25933 Comment Length        0000 (0)\n-25935 Disk Start            0000 (0)\n-25937 Int File Attributes   0000 (0)\n-      [Bit 0]               0 'Binary Data'\n-25939 Ext File Attributes   00000000 (0)\n-2593D Local Header Offset   000050F5 (20725)\n-25941 Filename              'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX'\n-#\n-# WARNING: Offset 0x25941: Filename 'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX'\n-#          Zero length filename\n-#\n-25965 Extra ID #1           5455 (21589) 'Extended Timestamp [UT]'\n-25967   Length              0005 (5)\n-25969   Flags               01 (1) 'Modification'\n-2596A   Modification Time   00000000 (0) 'Thu Jan  1 00:00:00 1970'\n-\n-2596E CENTRAL HEADER #23    02014B50 (33639248)\n-25972 Created Zip Spec      14 (20) '2.0'\n-25973 Created OS            00 (0) 'MS-DOS'\n-25974 Extract Zip Spec      14 (20) '2.0'\n-25975 Extract OS            00 (0) 'MS-DOS'\n-25976 General Purpose Flag  0008 (8)\n-      [Bit  3]              1 'Streamed'\n-25978 Compression Method    0000 (0) 'Stored'\n-2597A Modification Time     EC210000 (3961585664) 'Wed Jan  1 00:00:00 2098'\n-2597E CRC                   B7F8FDDA (3086548442)\n-25982 Compressed Size       00003E47 (15943)\n-25986 Uncompressed Size     00003E47 (15943)\n-2598A Filename Length       003D (61)\n-2598C Extra Length          0009 (9)\n-2598E Comment Length        0000 (0)\n-25990 Disk Start            0000 (0)\n-25992 Int File Attributes   0000 (0)\n-      [Bit 0]               0 'Binary Data'\n-25994 Ext File Attributes   00000000 (0)\n-25998 Local Header Offset   00005140 (20800)\n-2599C Filename              'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX'\n-#\n-# WARNING: Offset 0x2599C: Filename 'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX'\n-#          Zero length filename\n-#\n-259D9 Extra ID #1           5455 (21589) 'Extended Timestamp [UT]'\n-259DB   Length              0005 (5)\n-259DD   Flags               01 (1) 'Modification'\n-259DE   Modification Time   00000000 (0) 'Thu Jan  1 00:00:00 1970'\n-\n-259E2 CENTRAL HEADER #24    02014B50 (33639248)\n-259E6 Created Zip Spec      14 (20) '2.0'\n-259E7 Created OS            00 (0) 'MS-DOS'\n-259E8 Extract Zip Spec      14 (20) '2.0'\n-259E9 Extract OS            00 (0) 'MS-DOS'\n-259EA General Purpose Flag  0008 (8)\n-      [Bit  3]              1 'Streamed'\n-259EC Compression Method    0000 (0) 'Stored'\n-259EE Modification Time     EC210000 (3961585664) 'Wed Jan  1 00:00:00 2098'\n-259F2 CRC                   03D1B931 (64076081)\n-259F6 Compressed Size       000018E3 (6371)\n-259FA Uncompressed Size     000018E3 (6371)\n-259FE Filename Length       003E (62)\n-25A00 Extra Length          0009 (9)\n-25A02 Comment Length        0000 (0)\n-25A04 Disk Start            0000 (0)\n-25A06 Int File Attributes   0000 (0)\n-      [Bit 0]               0 'Binary Data'\n-25A08 Ext File Attributes   00000000 (0)\n-25A0C Local Header Offset   00008FFB (36859)\n-25A10 Filename              'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX'\n-#\n-# WARNING: Offset 0x25A10: Filename 'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX'\n-#          Zero length filename\n-#\n-25A4E Extra ID #1           5455 (21589) 'Extended Timestamp [UT]'\n-25A50   Length              0005 (5)\n-25A52   Flags               01 (1) 'Modification'\n-25A53   Modification Time   00000000 (0) 'Thu Jan  1 00:00:00 1970'\n-\n-25A57 CENTRAL HEADER #25    02014B50 (33639248)\n-25A5B Created Zip Spec      14 (20) '2.0'\n-25A5C Created OS            00 (0) 'MS-DOS'\n-25A5D Extract Zip Spec      14 (20) '2.0'\n-25A5E Extract OS            00 (0) 'MS-DOS'\n-25A5F General Purpose Flag  0008 (8)\n-      [Bit  3]              1 'Streamed'\n-25A61 Compression Method    0000 (0) 'Stored'\n-25A63 Modification Time     EC210000 (3961585664) 'Wed Jan  1 00:00:00 2098'\n-25A67 CRC                   F93BB070 (4181438576)\n-25A6B Compressed Size       000008B8 (2232)\n-25A6F Uncompressed Size     000008B8 (2232)\n-25A73 Filename Length       0032 (50)\n-25A75 Extra Length          0009 (9)\n-25A77 Comment Length        0000 (0)\n-25A79 Disk Start            0000 (0)\n-25A7B Int File Attributes   0000 (0)\n-      [Bit 0]               0 'Binary Data'\n-25A7D Ext File Attributes   00000000 (0)\n-25A81 Local Header Offset   0000A953 (43347)\n-25A85 Filename              'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX'\n-#\n-# WARNING: Offset 0x25A85: Filename 'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX'\n-#          Zero length filename\n-#\n-25AB7 Extra ID #1           5455 (21589) 'Extended Timestamp [UT]'\n-25AB9   Length              0005 (5)\n-25ABB   Flags               01 (1) 'Modification'\n-25ABC   Modification Time   00000000 (0) 'Thu Jan  1 00:00:00 1970'\n-\n-25AC0 CENTRAL HEADER #26    02014B50 (33639248)\n-25AC4 Created Zip Spec      14 (20) '2.0'\n-25AC5 Created OS            00 (0) 'MS-DOS'\n-25AC6 Extract Zip Spec      14 (20) '2.0'\n-25AC7 Extract OS            00 (0) 'MS-DOS'\n-25AC8 General Purpose Flag  0008 (8)\n-      [Bit  3]              1 'Streamed'\n-25ACA Compression Method    0000 (0) 'Stored'\n-25ACC Modification Time     EC210000 (3961585664) 'Wed Jan  1 00:00:00 2098'\n-25AD0 CRC                   C7D35A4B (3352517195)\n-25AD4 Compressed Size       00001F36 (7990)\n-25AD8 Uncompressed Size     00001F36 (7990)\n-25ADC Filename Length       0040 (64)\n-25ADE Extra Length          0009 (9)\n-25AE0 Comment Length        0000 (0)\n-25AE2 Disk Start            0000 (0)\n-25AE4 Int File Attributes   0000 (0)\n-      [Bit 0]               0 'Binary Data'\n-25AE6 Ext File Attributes   00000000 (0)\n-25AEA Local Header Offset   0000B274 (45684)\n-25AEE Filename              'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX'\n-#\n-# WARNING: Offset 0x25AEE: Filename 'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX'\n-#          Zero length filename\n-#\n-25B2E Extra ID #1           5455 (21589) 'Extended Timestamp [UT]'\n-25B30   Length              0005 (5)\n-25B32   Flags               01 (1) 'Modification'\n-25B33   Modification Time   00000000 (0) 'Thu Jan  1 00:00:00 1970'\n-\n-25B37 CENTRAL HEADER #27    02014B50 (33639248)\n-25B3B Created Zip Spec      14 (20) '2.0'\n-25B3C Created OS            00 (0) 'MS-DOS'\n-25B3D Extract Zip Spec      14 (20) '2.0'\n-25B3E Extract OS            00 (0) 'MS-DOS'\n-25B3F General Purpose Flag  0008 (8)\n-      [Bit  3]              1 'Streamed'\n-25B41 Compression Method    0000 (0) 'Stored'\n-25B43 Modification Time     EC210000 (3961585664) 'Wed Jan  1 00:00:00 2098'\n-25B47 CRC                   D012E5FC (3490899452)\n-25B4B Compressed Size       00001BA0 (7072)\n-25B4F Uncompressed Size     00001BA0 (7072)\n-25B53 Filename Length       003C (60)\n-25B55 Extra Length          0009 (9)\n-25B57 Comment Length        0000 (0)\n-25B59 Disk Start            0000 (0)\n-25B5B Int File Attributes   0000 (0)\n-      [Bit 0]               0 'Binary Data'\n-25B5D Ext File Attributes   00000000 (0)\n-25B61 Local Header Offset   0000D221 (53793)\n-25B65 Filename              'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX'\n-#\n-# WARNING: Offset 0x25B65: Filename 'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX'\n-#          Zero length filename\n-#\n-25BA1 Extra ID #1           5455 (21589) 'Extended Timestamp [UT]'\n-25BA3   Length              0005 (5)\n-25BA5   Flags               01 (1) 'Modification'\n-25BA6   Modification Time   00000000 (0) 'Thu Jan  1 00:00:00 1970'\n-\n-25BAA CENTRAL HEADER #28    02014B50 (33639248)\n-25BAE Created Zip Spec      14 (20) '2.0'\n-25BAF Created OS            00 (0) 'MS-DOS'\n-25BB0 Extract Zip Spec      14 (20) '2.0'\n-25BB1 Extract OS            00 (0) 'MS-DOS'\n-25BB2 General Purpose Flag  0008 (8)\n-      [Bit  3]              1 'Streamed'\n-25BB4 Compression Method    0000 (0) 'Stored'\n-25BB6 Modification Time     EC210000 (3961585664) 'Wed Jan  1 00:00:00 2098'\n-25BBA CRC                   A6D38CE4 (2798882020)\n-25BBE Compressed Size       00002AE7 (10983)\n-25BC2 Uncompressed Size     00002AE7 (10983)\n-25BC6 Filename Length       0033 (51)\n-25BC8 Extra Length          0009 (9)\n-25BCA Comment Length        0000 (0)\n-25BCC Disk Start            0000 (0)\n-25BCE Int File Attributes   0000 (0)\n-      [Bit 0]               0 'Binary Data'\n-25BD0 Ext File Attributes   00000000 (0)\n-25BD4 Local Header Offset   0000EE34 (60980)\n-25BD8 Filename              'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX'\n-#\n-# WARNING: Offset 0x25BD8: Filename 'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX'\n-#          Zero length filename\n-#\n-25C0B Extra ID #1           5455 (21589) 'Extended Timestamp [UT]'\n-25C0D   Length              0005 (5)\n-25C0F   Flags               01 (1) 'Modification'\n-25C10   Modification Time   00000000 (0) 'Thu Jan  1 00:00:00 1970'\n-\n-25C14 CENTRAL HEADER #29    02014B50 (33639248)\n-25C18 Created Zip Spec      14 (20) '2.0'\n-25C19 Created OS            00 (0) 'MS-DOS'\n-25C1A Extract Zip Spec      14 (20) '2.0'\n-25C1B Extract OS            00 (0) 'MS-DOS'\n-25C1C General Purpose Flag  0008 (8)\n-      [Bit  3]              1 'Streamed'\n-25C1E Compression Method    0000 (0) 'Stored'\n-25C20 Modification Time     EC210000 (3961585664) 'Wed Jan  1 00:00:00 2098'\n-25C24 CRC                   982FC700 (2553267968)\n-25C28 Compressed Size       00000A19 (2585)\n-25C2C Uncompressed Size     00000A19 (2585)\n-25C30 Filename Length       003A (58)\n-25C32 Extra Length          0009 (9)\n-25C34 Comment Length        0000 (0)\n-25C36 Disk Start            0000 (0)\n-25C38 Int File Attributes   0000 (0)\n-      [Bit 0]               0 'Binary Data'\n-25C3A Ext File Attributes   00000000 (0)\n-25C3E Local Header Offset   00011985 (72069)\n-25C42 Filename              'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX'\n-#\n-# WARNING: Offset 0x25C42: Filename 'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX'\n-#          Zero length filename\n-#\n-25C7C Extra ID #1           5455 (21589) 'Extended Timestamp [UT]'\n-25C7E   Length              0005 (5)\n-25C80   Flags               01 (1) 'Modification'\n-25C81   Modification Time   00000000 (0) 'Thu Jan  1 00:00:00 1970'\n-\n-25C85 CENTRAL HEADER #30    02014B50 (33639248)\n-25C89 Created Zip Spec      14 (20) '2.0'\n-25C8A Created OS            00 (0) 'MS-DOS'\n-25C8B Extract Zip Spec      14 (20) '2.0'\n-25C8C Extract OS            00 (0) 'MS-DOS'\n-25C8D General Purpose Flag  0008 (8)\n-      [Bit  3]              1 'Streamed'\n-25C8F Compression Method    0000 (0) 'Stored'\n-25C91 Modification Time     EC210000 (3961585664) 'Wed Jan  1 00:00:00 2098'\n-25C95 CRC                   C6A73CC6 (3332848838)\n-25C99 Compressed Size       00000C1E (3102)\n-25C9D Uncompressed Size     00000C1E (3102)\n-25CA1 Filename Length       0038 (56)\n-25CA3 Extra Length          0009 (9)\n-25CA5 Comment Length        0000 (0)\n-25CA7 Disk Start            0000 (0)\n-25CA9 Int File Attributes   0000 (0)\n-      [Bit 0]               0 'Binary Data'\n-25CAB Ext File Attributes   00000000 (0)\n-25CAF Local Header Offset   0001240F (74767)\n-25CB3 Filename              'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX'\n-#\n-# WARNING: Offset 0x25CB3: Filename 'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX'\n-#          Zero length filename\n-#\n-25CEB Extra ID #1           5455 (21589) 'Extended Timestamp [UT]'\n-25CED   Length              0005 (5)\n-25CEF   Flags               01 (1) 'Modification'\n-25CF0   Modification Time   00000000 (0) 'Thu Jan  1 00:00:00 1970'\n-\n-25CF4 CENTRAL HEADER #31    02014B50 (33639248)\n-25CF8 Created Zip Spec      14 (20) '2.0'\n-25CF9 Created OS            00 (0) 'MS-DOS'\n-25CFA Extract Zip Spec      14 (20) '2.0'\n-25CFB Extract OS            00 (0) 'MS-DOS'\n-25CFC General Purpose Flag  0008 (8)\n-      [Bit  3]              1 'Streamed'\n-25CFE Compression Method    0000 (0) 'Stored'\n-25D00 Modification Time     EC210000 (3961585664) 'Wed Jan  1 00:00:00 2098'\n-25D04 CRC                   94899E78 (2492046968)\n-25D08 Compressed Size       000005B1 (1457)\n-25D0C Uncompressed Size     000005B1 (1457)\n-25D10 Filename Length       0036 (54)\n-25D12 Extra Length          0009 (9)\n-25D14 Comment Length        0000 (0)\n-25D16 Disk Start            0000 (0)\n-25D18 Int File Attributes   0000 (0)\n-      [Bit 0]               0 'Binary Data'\n-25D1A Ext File Attributes   00000000 (0)\n-25D1E Local Header Offset   0001309C (77980)\n-25D22 Filename              'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX'\n-#\n-# WARNING: Offset 0x25D22: Filename 'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX'\n-#          Zero length filename\n-#\n-25D58 Extra ID #1           5455 (21589) 'Extended Timestamp [UT]'\n-25D5A   Length              0005 (5)\n-25D5C   Flags               01 (1) 'Modification'\n-25D5D   Modification Time   00000000 (0) 'Thu Jan  1 00:00:00 1970'\n-\n-25D61 CENTRAL HEADER #32    02014B50 (33639248)\n-25D65 Created Zip Spec      14 (20) '2.0'\n-25D66 Created OS            00 (0) 'MS-DOS'\n-25D67 Extract Zip Spec      14 (20) '2.0'\n-25D68 Extract OS            00 (0) 'MS-DOS'\n-25D69 General Purpose Flag  0008 (8)\n-      [Bit  3]              1 'Streamed'\n-25D6B Compression Method    0000 (0) 'Stored'\n-25D6D Modification Time     EC210000 (3961585664) 'Wed Jan  1 00:00:00 2098'\n-25D71 CRC                   4247D839 (1112004665)\n-25D75 Compressed Size       00001FD9 (8153)\n-25D79 Uncompressed Size     00001FD9 (8153)\n-25D7D Filename Length       0035 (53)\n-25D7F Extra Length          0009 (9)\n-25D81 Comment Length        0000 (0)\n-25D83 Disk Start            0000 (0)\n-25D85 Int File Attributes   0000 (0)\n-      [Bit 0]               0 'Binary Data'\n-25D87 Ext File Attributes   00000000 (0)\n-25D8B Local Header Offset   000136BA (79546)\n-25D8F Filename              'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX'\n-#\n-# WARNING: Offset 0x25D8F: Filename 'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX'\n-#          Zero length filename\n-#\n-25DC4 Extra ID #1           5455 (21589) 'Extended Timestamp [UT]'\n-25DC6   Length              0005 (5)\n-25DC8   Flags               01 (1) 'Modification'\n-25DC9   Modification Time   00000000 (0) 'Thu Jan  1 00:00:00 1970'\n-\n-25DCD CENTRAL HEADER #33    02014B50 (33639248)\n-25DD1 Created Zip Spec      14 (20) '2.0'\n-25DD2 Created OS            00 (0) 'MS-DOS'\n-25DD3 Extract Zip Spec      14 (20) '2.0'\n-25DD4 Extract OS            00 (0) 'MS-DOS'\n-25DD5 General Purpose Flag  0008 (8)\n-      [Bit  3]              1 'Streamed'\n-25DD7 Compression Method    0000 (0) 'Stored'\n-25DD9 Modification Time     EC210000 (3961585664) 'Wed Jan  1 00:00:00 2098'\n-25DDD CRC                   C2B511E4 (3266646500)\n-25DE1 Compressed Size       00006B37 (27447)\n-25DE5 Uncompressed Size     00006B37 (27447)\n-25DE9 Filename Length       0036 (54)\n-25DEB Extra Length          0009 (9)\n-25DED Comment Length        0000 (0)\n-25DEF Disk Start            0000 (0)\n-25DF1 Int File Attributes   0000 (0)\n-      [Bit 0]               0 'Binary Data'\n-25DF3 Ext File Attributes   00000000 (0)\n-25DF7 Local Header Offset   000156FF (87807)\n-25DFB Filename              'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX'\n-#\n-# WARNING: Offset 0x25DFB: Filename 'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX'\n-#          Zero length filename\n-#\n-25E31 Extra ID #1           5455 (21589) 'Extended Timestamp [UT]'\n-25E33   Length              0005 (5)\n-25E35   Flags               01 (1) 'Modification'\n-25E36   Modification Time   00000000 (0) 'Thu Jan  1 00:00:00 1970'\n-\n-25E3A CENTRAL HEADER #34    02014B50 (33639248)\n-25E3E Created Zip Spec      14 (20) '2.0'\n-25E3F Created OS            00 (0) 'MS-DOS'\n-25E40 Extract Zip Spec      14 (20) '2.0'\n-25E41 Extract OS            00 (0) 'MS-DOS'\n-25E42 General Purpose Flag  0008 (8)\n-      [Bit  3]              1 'Streamed'\n-25E44 Compression Method    0000 (0) 'Stored'\n-25E46 Modification Time     EC210000 (3961585664) 'Wed Jan  1 00:00:00 2098'\n-25E4A CRC                   7317DB5C (1930943324)\n-25E4E Compressed Size       00000714 (1812)\n-25E52 Uncompressed Size     00000714 (1812)\n-25E56 Filename Length       003C (60)\n-25E58 Extra Length          0009 (9)\n-25E5A Comment Length        0000 (0)\n-25E5C Disk Start            0000 (0)\n-25E5E Int File Attributes   0000 (0)\n-      [Bit 0]               0 'Binary Data'\n-25E60 Ext File Attributes   00000000 (0)\n-25E64 Local Header Offset   0001C2A3 (115363)\n-25E68 Filename              'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX'\n-#\n-# WARNING: Offset 0x25E68: Filename 'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX'\n-#          Zero length filename\n-#\n-25EA4 Extra ID #1           5455 (21589) 'Extended Timestamp [UT]'\n-25EA6   Length              0005 (5)\n-25EA8   Flags               01 (1) 'Modification'\n-25EA9   Modification Time   00000000 (0) 'Thu Jan  1 00:00:00 1970'\n-\n-25EAD CENTRAL HEADER #35    02014B50 (33639248)\n-25EB1 Created Zip Spec      14 (20) '2.0'\n-25EB2 Created OS            00 (0) 'MS-DOS'\n-25EB3 Extract Zip Spec      14 (20) '2.0'\n-25EB4 Extract OS            00 (0) 'MS-DOS'\n-25EB5 General Purpose Flag  0008 (8)\n-      [Bit  3]              1 'Streamed'\n-25EB7 Compression Method    0000 (0) 'Stored'\n-25EB9 Modification Time     EC210000 (3961585664) 'Wed Jan  1 00:00:00 2098'\n-25EBD CRC                   344C1E36 (877403702)\n-25EC1 Compressed Size       00001FCC (8140)\n-25EC5 Uncompressed Size     00001FCC (8140)\n-25EC9 Filename Length       0042 (66)\n-25ECB Extra Length          0009 (9)\n-25ECD Comment Length        0000 (0)\n-25ECF Disk Start            0000 (0)\n-25ED1 Int File Attributes   0000 (0)\n-      [Bit 0]               0 'Binary Data'\n-25ED3 Ext File Attributes   00000000 (0)\n-25ED7 Local Header Offset   0001CA2A (117290)\n-25EDB Filename              'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX'\n-#\n-# WARNING: Offset 0x25EDB: Filename 'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX'\n-#          Zero length filename\n-#\n-25F1D Extra ID #1           5455 (21589) 'Extended Timestamp [UT]'\n-25F1F   Length              0005 (5)\n-25F21   Flags               01 (1) 'Modification'\n-25F22   Modification Time   00000000 (0) 'Thu Jan  1 00:00:00 1970'\n-\n-25F26 CENTRAL HEADER #36    02014B50 (33639248)\n-25F2A Created Zip Spec      14 (20) '2.0'\n-25F2B Created OS            00 (0) 'MS-DOS'\n-25F2C Extract Zip Spec      14 (20) '2.0'\n-25F2D Extract OS            00 (0) 'MS-DOS'\n-25F2E General Purpose Flag  0008 (8)\n-      [Bit  3]              1 'Streamed'\n-25F30 Compression Method    0000 (0) 'Stored'\n-25F32 Modification Time     EC210000 (3961585664) 'Wed Jan  1 00:00:00 2098'\n-25F36 CRC                   3B14B127 (991211815)\n-25F3A Compressed Size       000017C7 (6087)\n-25F3E Uncompressed Size     000017C7 (6087)\n-25F42 Filename Length       0045 (69)\n-25F44 Extra Length          0009 (9)\n-25F46 Comment Length        0000 (0)\n-25F48 Disk Start            0000 (0)\n-25F4A Int File Attributes   0000 (0)\n-      [Bit 0]               0 'Binary Data'\n-25F4C Ext File Attributes   00000000 (0)\n-25F50 Local Header Offset   0001EA6F (125551)\n-25F54 Filename              'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX'\n-#\n-# WARNING: Offset 0x25F54: Filename 'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX'\n-#          Zero length filename\n-#\n-25F99 Extra ID #1           5455 (21589) 'Extended Timestamp [UT]'\n-25F9B   Length              0005 (5)\n-25F9D   Flags               01 (1) 'Modification'\n-25F9E   Modification Time   00000000 (0) 'Thu Jan  1 00:00:00 1970'\n-\n-25FA2 CENTRAL HEADER #37    02014B50 (33639248)\n-25FA6 Created Zip Spec      14 (20) '2.0'\n-25FA7 Created OS            00 (0) 'MS-DOS'\n-25FA8 Extract Zip Spec      14 (20) '2.0'\n-25FA9 Extract OS            00 (0) 'MS-DOS'\n-25FAA General Purpose Flag  0000 (0)\n-25FAC Compression Method    0000 (0) 'Stored'\n-25FAE Modification Time     EC210000 (3961585664) 'Wed Jan  1 00:00:00 2098'\n-25FB2 CRC                   00000000 (0)\n-25FB6 Compressed Size       00000000 (0)\n-25FBA Uncompressed Size     00000000 (0)\n-25FBE Filename Length       002B (43)\n-25FC0 Extra Length          0009 (9)\n-25FC2 Comment Length        0000 (0)\n-25FC4 Disk Start            0000 (0)\n-25FC6 Int File Attributes   0000 (0)\n-      [Bit 0]               0 'Binary Data'\n-25FC8 Ext File Attributes   00000000 (0)\n-25FCC Local Header Offset   000202B2 (131762)\n-25FD0 Filename              'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX'\n-#\n-# WARNING: Offset 0x25FD0: Filename 'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX'\n-#          Zero length filename\n-#\n-25FFB Extra ID #1           5455 (21589) 'Extended Timestamp [UT]'\n-25FFD   Length              0005 (5)\n-25FFF   Flags               01 (1) 'Modification'\n-26000   Modification Time   00000000 (0) 'Thu Jan  1 00:00:00 1970'\n-\n-26004 CENTRAL HEADER #38    02014B50 (33639248)\n-26008 Created Zip Spec      14 (20) '2.0'\n-26009 Created OS            00 (0) 'MS-DOS'\n-2600A Extract Zip Spec      14 (20) '2.0'\n-2600B Extract OS            00 (0) 'MS-DOS'\n-2600C General Purpose Flag  0008 (8)\n-      [Bit  3]              1 'Streamed'\n-2600E Compression Method    0000 (0) 'Stored'\n-26010 Modification Time     EC210000 (3961585664) 'Wed Jan  1 00:00:00 2098'\n-26014 CRC                   1915FFAE (420872110)\n-26018 Compressed Size       00002228 (8744)\n-2601C Uncompressed Size     00002228 (8744)\n-26020 Filename Length       003C (60)\n-26022 Extra Length          0009 (9)\n-26024 Comment Length        0000 (0)\n-26026 Disk Start            0000 (0)\n-26028 Int File Attributes   0000 (0)\n-      [Bit 0]               0 'Binary Data'\n-2602A Ext File Attributes   00000000 (0)\n-2602E Local Header Offset   00020304 (131844)\n-26032 Filename              'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX'\n-#\n-# WARNING: Offset 0x26032: Filename 'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX'\n-#          Zero length filename\n-#\n-2606E Extra ID #1           5455 (21589) 'Extended Timestamp [UT]'\n-26070   Length              0005 (5)\n-26072   Flags               01 (1) 'Modification'\n-26073   Modification Time   00000000 (0) 'Thu Jan  1 00:00:00 1970'\n-\n-26077 CENTRAL HEADER #39    02014B50 (33639248)\n-2607B Created Zip Spec      14 (20) '2.0'\n-2607C Created OS            00 (0) 'MS-DOS'\n-2607D Extract Zip Spec      14 (20) '2.0'\n-2607E Extract OS            00 (0) 'MS-DOS'\n-2607F General Purpose Flag  0008 (8)\n-      [Bit  3]              1 'Streamed'\n-26081 Compression Method    0000 (0) 'Stored'\n-26083 Modification Time     EC210000 (3961585664) 'Wed Jan  1 00:00:00 2098'\n-26087 CRC                   B4BC5053 (3032240211)\n-2608B Compressed Size       00001648 (5704)\n-2608F Uncompressed Size     00001648 (5704)\n-26093 Filename Length       003B (59)\n-26095 Extra Length          0009 (9)\n-26097 Comment Length        0000 (0)\n-26099 Disk Start            0000 (0)\n-2609B Int File Attributes   0000 (0)\n-      [Bit 0]               0 'Binary Data'\n-2609D Ext File Attributes   00000000 (0)\n-260A1 Local Header Offset   0002259F (140703)\n-260A5 Filename              'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX'\n-#\n-# WARNING: Offset 0x260A5: Filename 'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX'\n-#          Zero length filename\n-#\n-260E0 Extra ID #1           5455 (21589) 'Extended Timestamp [UT]'\n-260E2   Length              0005 (5)\n-260E4   Flags               01 (1) 'Modification'\n-260E5   Modification Time   00000000 (0) 'Thu Jan  1 00:00:00 1970'\n-\n-260E9 CENTRAL HEADER #40    02014B50 (33639248)\n-260ED Created Zip Spec      14 (20) '2.0'\n-260EE Created OS            00 (0) 'MS-DOS'\n-260EF Extract Zip Spec      14 (20) '2.0'\n-260F0 Extract OS            00 (0) 'MS-DOS'\n-260F1 General Purpose Flag  0000 (0)\n-260F3 Compression Method    0000 (0) 'Stored'\n-260F5 Modification Time     EC210000 (3961585664) 'Wed Jan  1 00:00:00 2098'\n-260F9 CRC                   00000000 (0)\n-260FD Compressed Size       00000000 (0)\n-26101 Uncompressed Size     00000000 (0)\n-26105 Filename Length       002B (43)\n-26107 Extra Length          0009 (9)\n-26109 Comment Length        0000 (0)\n-2610B Disk Start            0000 (0)\n-2610D Int File Attributes   0000 (0)\n-      [Bit 0]               0 'Binary Data'\n-2610F Ext File Attributes   00000000 (0)\n-26113 Local Header Offset   00023C59 (146521)\n-26117 Filename              'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX'\n-#\n-# WARNING: Offset 0x26117: Filename 'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX'\n-#          Zero length filename\n-#\n-26142 Extra ID #1           5455 (21589) 'Extended Timestamp [UT]'\n-26144   Length              0005 (5)\n-26146   Flags               01 (1) 'Modification'\n-26147   Modification Time   00000000 (0) 'Thu Jan  1 00:00:00 1970'\n-\n-2614B CENTRAL HEADER #41    02014B50 (33639248)\n-2614F Created Zip Spec      14 (20) '2.0'\n-26150 Created OS            00 (0) 'MS-DOS'\n-26151 Extract Zip Spec      14 (20) '2.0'\n-26152 Extract OS            00 (0) 'MS-DOS'\n-26153 General Purpose Flag  0008 (8)\n-      [Bit  3]              1 'Streamed'\n-26155 Compression Method    0000 (0) 'Stored'\n-26157 Modification Time     EC210000 (3961585664) 'Wed Jan  1 00:00:00 2098'\n-2615B CRC                   C9453D78 (3376758136)\n-2615F Compressed Size       000008E4 (2276)\n-26163 Uncompressed Size     000008E4 (2276)\n-26167 Filename Length       0043 (67)\n-26169 Extra Length          0009 (9)\n-2616B Comment Length        0000 (0)\n-2616D Disk Start            0000 (0)\n-2616F Int File Attributes   0000 (0)\n-      [Bit 0]               0 'Binary Data'\n-26171 Ext File Attributes   00000000 (0)\n-26175 Local Header Offset   00023CAB (146603)\n-26179 Filename              'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX'\n-#\n-# WARNING: Offset 0x26179: Filename 'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX'\n-#          Zero length filename\n-#\n-261BC Extra ID #1           5455 (21589) 'Extended Timestamp [UT]'\n-261BE   Length              0005 (5)\n-261C0   Flags               01 (1) 'Modification'\n-261C1   Modification Time   00000000 (0) 'Thu Jan  1 00:00:00 1970'\n-\n-261C5 CENTRAL HEADER #42    02014B50 (33639248)\n-261C9 Created Zip Spec      14 (20) '2.0'\n-261CA Created OS            00 (0) 'MS-DOS'\n-261CB Extract Zip Spec      14 (20) '2.0'\n-261CC Extract OS            00 (0) 'MS-DOS'\n-261CD General Purpose Flag  0008 (8)\n-      [Bit  3]              1 'Streamed'\n-261CF Compression Method    0000 (0) 'Stored'\n-261D1 Modification Time     EC210000 (3961585664) 'Wed Jan  1 00:00:00 2098'\n-261D5 CRC                   5A226E99 (1512205977)\n-261D9 Compressed Size       00000B86 (2950)\n-261DD Uncompressed Size     00000B86 (2950)\n-261E1 Filename Length       0047 (71)\n-261E3 Extra Length          0009 (9)\n-261E5 Comment Length        0000 (0)\n-261E7 Disk Start            0000 (0)\n-261E9 Int File Attributes   0000 (0)\n-      [Bit 0]               0 'Binary Data'\n-261EB Ext File Attributes   00000000 (0)\n-261EF Local Header Offset   00024609 (149001)\n-261F3 Filename              'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX'\n-#\n-# WARNING: Offset 0x261F3: Filename 'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX'\n-#          Zero length filename\n-#\n-2623A Extra ID #1           5455 (21589) 'Extended Timestamp [UT]'\n-2623C   Length              0005 (5)\n-2623E   Flags               01 (1) 'Modification'\n-2623F   Modification Time   00000000 (0) 'Thu Jan  1 00:00:00 1970'\n-\n-26243 END CENTRAL HEADER    06054B50 (101010256)\n-26247 Number of this disk   0000 (0)\n-26249 Central Dir Disk no   0000 (0)\n-2624B Entries in this disk  002A (42)\n-2624D Total Entries         002A (42)\n-2624F Size of Central Dir   00001036 (4150)\n-26253 Offset to Central Dir 0002520D (152077)\n-26257 Comment Length        0000 (0)\n+04F5F DATA DESCRIPTOR       08074B50 (134695760)\n+04F63 CRC                   C3B87E97 (3283648151)\n+04F67 Compressed Size       00000F4C (3916)\n+04F6B Uncompressed Size     00000F4C (3916)\n+\n+04F6F LOCAL HEADER #17      04034B50 (67324752)\n+04F73 Extract Zip Spec      14 (20) '2.0'\n+04F74 Extract OS            00 (0) 'MS-DOS'\n+04F75 General Purpose Flag  0000 (0)\n+04F77 Compression Method    0000 (0) 'Stored'\n+04F79 Modification Time     EC210000 (3961585664) 'Wed Jan  1 00:00:00 2098'\n+04F7D CRC                   00000000 (0)\n+04F81 Compressed Size       00000000 (0)\n+04F85 Uncompressed Size     00000000 (0)\n+04F89 Filename Length       0004 (4)\n+04F8B Extra Length          0009 (9)\n+04F8D Filename              'XXXX'\n+#\n+# WARNING: Offset 0x4F8D: Filename 'XXXX'\n+#          Zero length filename\n+#\n+04F91 Extra ID #1           5455 (21589) 'Extended Timestamp [UT]'\n+04F93   Length              0005 (5)\n+04F95   Flags               01 (1) 'Modification'\n+04F96   Modification Time   00000000 (0) 'Thu Jan  1 00:00:00 1970'\n+\n+04F9A LOCAL HEADER #18      04034B50 (67324752)\n+04F9E Extract Zip Spec      14 (20) '2.0'\n+04F9F Extract OS            00 (0) 'MS-DOS'\n+04FA0 General Purpose Flag  0000 (0)\n+04FA2 Compression Method    0000 (0) 'Stored'\n+04FA4 Modification Time     EC210000 (3961585664) 'Wed Jan  1 00:00:00 2098'\n+04FA8 CRC                   00000000 (0)\n+04FAC Compressed Size       00000000 (0)\n+04FB0 Uncompressed Size     00000000 (0)\n+04FB4 Filename Length       000B (11)\n+04FB6 Extra Length          0009 (9)\n+04FB8 Filename              'XXXXXXXXXXX'\n+#\n+# WARNING: Offset 0x4FB8: Filename 'XXXXXXXXXXX'\n+#          Zero length filename\n+#\n+04FC3 Extra ID #1           5455 (21589) 'Extended Timestamp [UT]'\n+04FC5   Length              0005 (5)\n+04FC7   Flags               01 (1) 'Modification'\n+04FC8   Modification Time   00000000 (0) 'Thu Jan  1 00:00:00 1970'\n+\n+04FCC LOCAL HEADER #19      04034B50 (67324752)\n+04FD0 Extract Zip Spec      14 (20) '2.0'\n+04FD1 Extract OS            00 (0) 'MS-DOS'\n+04FD2 General Purpose Flag  0000 (0)\n+04FD4 Compression Method    0000 (0) 'Stored'\n+04FD6 Modification Time     EC210000 (3961585664) 'Wed Jan  1 00:00:00 2098'\n+04FDA CRC                   00000000 (0)\n+04FDE Compressed Size       00000000 (0)\n+04FE2 Uncompressed Size     00000000 (0)\n+04FE6 Filename Length       0011 (17)\n+04FE8 Extra Length          0009 (9)\n+04FEA Filename              'XXXXXXXXXXXXXXXXX'\n+#\n+# WARNING: Offset 0x4FEA: Filename 'XXXXXXXXXXXXXXXXX'\n+#          Zero length filename\n+#\n+04FFB Extra ID #1           5455 (21589) 'Extended Timestamp [UT]'\n+04FFD   Length              0005 (5)\n+04FFF   Flags               01 (1) 'Modification'\n+05000   Modification Time   00000000 (0) 'Thu Jan  1 00:00:00 1970'\n+\n+05004 LOCAL HEADER #20      04034B50 (67324752)\n+05008 Extract Zip Spec      14 (20) '2.0'\n+05009 Extract OS            00 (0) 'MS-DOS'\n+0500A General Purpose Flag  0000 (0)\n+0500C Compression Method    0000 (0) 'Stored'\n+0500E Modification Time     EC210000 (3961585664) 'Wed Jan  1 00:00:00 2098'\n+05012 CRC                   00000000 (0)\n+05016 Compressed Size       00000000 (0)\n+0501A Uncompressed Size     00000000 (0)\n+0501E Filename Length       0015 (21)\n+05020 Extra Length          0009 (9)\n+05022 Filename              'XXXXXXXXXXXXXXXXXXXXX'\n+#\n+# WARNING: Offset 0x5022: Filename 'XXXXXXXXXXXXXXXXXXXXX'\n+#          Zero length filename\n+#\n+05037 Extra ID #1           5455 (21589) 'Extended Timestamp [UT]'\n+05039   Length              0005 (5)\n+0503B   Flags               01 (1) 'Modification'\n+0503C   Modification Time   00000000 (0) 'Thu Jan  1 00:00:00 1970'\n+\n+05040 LOCAL HEADER #21      04034B50 (67324752)\n+05044 Extract Zip Spec      14 (20) '2.0'\n+05045 Extract OS            00 (0) 'MS-DOS'\n+05046 General Purpose Flag  0000 (0)\n+05048 Compression Method    0000 (0) 'Stored'\n+0504A Modification Time     EC210000 (3961585664) 'Wed Jan  1 00:00:00 2098'\n+0504E CRC                   00000000 (0)\n+05052 Compressed Size       00000000 (0)\n+05056 Uncompressed Size     00000000 (0)\n+0505A Filename Length       001E (30)\n+0505C Extra Length          0009 (9)\n+0505E Filename              'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXX'\n+#\n+# WARNING: Offset 0x505E: Filename 'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXX'\n+#          Zero length filename\n+#\n+0507C Extra ID #1           5455 (21589) 'Extended Timestamp [UT]'\n+0507E   Length              0005 (5)\n+05080   Flags               01 (1) 'Modification'\n+05081   Modification Time   00000000 (0) 'Thu Jan  1 00:00:00 1970'\n+\n+05085 LOCAL HEADER #22      04034B50 (67324752)\n+05089 Extract Zip Spec      14 (20) '2.0'\n+0508A Extract OS            00 (0) 'MS-DOS'\n+0508B General Purpose Flag  0000 (0)\n+0508D Compression Method    0000 (0) 'Stored'\n+0508F Modification Time     EC210000 (3961585664) 'Wed Jan  1 00:00:00 2098'\n+05093 CRC                   00000000 (0)\n+05097 Compressed Size       00000000 (0)\n+0509B Uncompressed Size     00000000 (0)\n+0509F Filename Length       0024 (36)\n+050A1 Extra Length          0009 (9)\n+050A3 Filename              'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX'\n+#\n+# WARNING: Offset 0x50A3: Filename 'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX'\n+#          Zero length filename\n+#\n+050C7 Extra ID #1           5455 (21589) 'Extended Timestamp [UT]'\n+050C9   Length              0005 (5)\n+050CB   Flags               01 (1) 'Modification'\n+050CC   Modification Time   00000000 (0) 'Thu Jan  1 00:00:00 1970'\n+\n+050D0 LOCAL HEADER #23      04034B50 (67324752)\n+050D4 Extract Zip Spec      14 (20) '2.0'\n+050D5 Extract OS            00 (0) 'MS-DOS'\n+050D6 General Purpose Flag  0008 (8)\n+      [Bit  3]              1 'Streamed'\n+050D8 Compression Method    0000 (0) 'Stored'\n+050DA Modification Time     EC210000 (3961585664) 'Wed Jan  1 00:00:00 2098'\n+050DE CRC                   00000000 (0)\n+050E2 Compressed Size       00000000 (0)\n+050E6 Uncompressed Size     00000000 (0)\n+050EA Filename Length       003D (61)\n+050EC Extra Length          0009 (9)\n+050EE Filename              'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX'\n+#\n+# WARNING: Offset 0x50EE: Filename 'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX'\n+#          Zero length filename\n+#\n+0512B Extra ID #1           5455 (21589) 'Extended Timestamp [UT]'\n+0512D   Length              0005 (5)\n+0512F   Flags               01 (1) 'Modification'\n+05130   Modification Time   00000000 (0) 'Thu Jan  1 00:00:00 1970'\n+05134 PAYLOAD\n+\n+090B9 DATA DESCRIPTOR       08074B50 (134695760)\n+090BD CRC                   5F5E6ACD (1600023245)\n+090C1 Compressed Size       00003F85 (16261)\n+090C5 Uncompressed Size     00003F85 (16261)\n+\n+090C9 LOCAL HEADER #24      04034B50 (67324752)\n+090CD Extract Zip Spec      14 (20) '2.0'\n+090CE Extract OS            00 (0) 'MS-DOS'\n+090CF General Purpose Flag  0008 (8)\n+      [Bit  3]              1 'Streamed'\n+090D1 Compression Method    0000 (0) 'Stored'\n+090D3 Modification Time     EC210000 (3961585664) 'Wed Jan  1 00:00:00 2098'\n+090D7 CRC                   00000000 (0)\n+090DB Compressed Size       00000000 (0)\n+090DF Uncompressed Size     00000000 (0)\n+090E3 Filename Length       003E (62)\n+090E5 Extra Length          0009 (9)\n+090E7 Filename              'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX'\n+#\n+# WARNING: Offset 0x90E7: Filename 'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX'\n+#          Zero length filename\n+#\n+09125 Extra ID #1           5455 (21589) 'Extended Timestamp [UT]'\n+09127   Length              0005 (5)\n+09129   Flags               01 (1) 'Modification'\n+0912A   Modification Time   00000000 (0) 'Thu Jan  1 00:00:00 1970'\n+0912E PAYLOAD\n+\n+0AAC8 DATA DESCRIPTOR       08074B50 (134695760)\n+0AACC CRC                   980C94D0 (2550961360)\n+0AAD0 Compressed Size       0000199A (6554)\n+0AAD4 Uncompressed Size     0000199A (6554)\n+\n+0AAD8 LOCAL HEADER #25      04034B50 (67324752)\n+0AADC Extract Zip Spec      14 (20) '2.0'\n+0AADD Extract OS            00 (0) 'MS-DOS'\n+0AADE General Purpose Flag  0008 (8)\n+      [Bit  3]              1 'Streamed'\n+0AAE0 Compression Method    0000 (0) 'Stored'\n+0AAE2 Modification Time     EC210000 (3961585664) 'Wed Jan  1 00:00:00 2098'\n+0AAE6 CRC                   00000000 (0)\n+0AAEA Compressed Size       00000000 (0)\n+0AAEE Uncompressed Size     00000000 (0)\n+0AAF2 Filename Length       0032 (50)\n+0AAF4 Extra Length          0009 (9)\n+0AAF6 Filename              'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX'\n+#\n+# WARNING: Offset 0xAAF6: Filename 'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX'\n+#          Zero length filename\n+#\n+0AB28 Extra ID #1           5455 (21589) 'Extended Timestamp [UT]'\n+0AB2A   Length              0005 (5)\n+0AB2C   Flags               01 (1) 'Modification'\n+0AB2D   Modification Time   00000000 (0) 'Thu Jan  1 00:00:00 1970'\n+0AB31 PAYLOAD\n+\n+0B430 DATA DESCRIPTOR       08074B50 (134695760)\n+0B434 CRC                   4C7D08FC (1283262716)\n+0B438 Compressed Size       000008FF (2303)\n+0B43C Uncompressed Size     000008FF (2303)\n+\n+0B440 LOCAL HEADER #26      04034B50 (67324752)\n+0B444 Extract Zip Spec      14 (20) '2.0'\n+0B445 Extract OS            00 (0) 'MS-DOS'\n+0B446 General Purpose Flag  0008 (8)\n+      [Bit  3]              1 'Streamed'\n+0B448 Compression Method    0000 (0) 'Stored'\n+0B44A Modification Time     EC210000 (3961585664) 'Wed Jan  1 00:00:00 2098'\n+0B44E CRC                   00000000 (0)\n+0B452 Compressed Size       00000000 (0)\n+0B456 Uncompressed Size     00000000 (0)\n+0B45A Filename Length       0040 (64)\n+0B45C Extra Length          0009 (9)\n+0B45E Filename              'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX'\n+#\n+# WARNING: Offset 0xB45E: Filename 'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX'\n+#          Zero length filename\n+#\n+0B49E Extra ID #1           5455 (21589) 'Extended Timestamp [UT]'\n+0B4A0   Length              0005 (5)\n+0B4A2   Flags               01 (1) 'Modification'\n+0B4A3   Modification Time   00000000 (0) 'Thu Jan  1 00:00:00 1970'\n+0B4A7 PAYLOAD\n+\n+0D4A0 DATA DESCRIPTOR       08074B50 (134695760)\n+0D4A4 CRC                   EAE8515F (3941093727)\n+0D4A8 Compressed Size       00001FF9 (8185)\n+0D4AC Uncompressed Size     00001FF9 (8185)\n+\n+0D4B0 LOCAL HEADER #27      04034B50 (67324752)\n+0D4B4 Extract Zip Spec      14 (20) '2.0'\n+0D4B5 Extract OS            00 (0) 'MS-DOS'\n+0D4B6 General Purpose Flag  0008 (8)\n+      [Bit  3]              1 'Streamed'\n+0D4B8 Compression Method    0000 (0) 'Stored'\n+0D4BA Modification Time     EC210000 (3961585664) 'Wed Jan  1 00:00:00 2098'\n+0D4BE CRC                   00000000 (0)\n+0D4C2 Compressed Size       00000000 (0)\n+0D4C6 Uncompressed Size     00000000 (0)\n+0D4CA Filename Length       003C (60)\n+0D4CC Extra Length          0009 (9)\n+0D4CE Filename              'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX'\n+#\n+# WARNING: Offset 0xD4CE: Filename 'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX'\n+#          Zero length filename\n+#\n+0D50A Extra ID #1           5455 (21589) 'Extended Timestamp [UT]'\n+0D50C   Length              0005 (5)\n+0D50E   Flags               01 (1) 'Modification'\n+0D50F   Modification Time   00000000 (0) 'Thu Jan  1 00:00:00 1970'\n+0D513 PAYLOAD\n+\n+0F16B DATA DESCRIPTOR       08074B50 (134695760)\n+0F16F CRC                   E202F321 (3791844129)\n+0F173 Compressed Size       00001C58 (7256)\n+0F177 Uncompressed Size     00001C58 (7256)\n+\n+0F17B LOCAL HEADER #28      04034B50 (67324752)\n+0F17F Extract Zip Spec      14 (20) '2.0'\n+0F180 Extract OS            00 (0) 'MS-DOS'\n+0F181 General Purpose Flag  0008 (8)\n+      [Bit  3]              1 'Streamed'\n+0F183 Compression Method    0000 (0) 'Stored'\n+0F185 Modification Time     EC210000 (3961585664) 'Wed Jan  1 00:00:00 2098'\n+0F189 CRC                   00000000 (0)\n+0F18D Compressed Size       00000000 (0)\n+0F191 Uncompressed Size     00000000 (0)\n+0F195 Filename Length       0033 (51)\n+0F197 Extra Length          0009 (9)\n+0F199 Filename              'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX'\n+#\n+# WARNING: Offset 0xF199: Filename 'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX'\n+#          Zero length filename\n+#\n+0F1CC Extra ID #1           5455 (21589) 'Extended Timestamp [UT]'\n+0F1CE   Length              0005 (5)\n+0F1D0   Flags               01 (1) 'Modification'\n+0F1D1   Modification Time   00000000 (0) 'Thu Jan  1 00:00:00 1970'\n+0F1D5 PAYLOAD\n+\n+11DB4 DATA DESCRIPTOR       08074B50 (134695760)\n+11DB8 CRC                   DBBCD787 (3686586247)\n+11DBC Compressed Size       00002BDF (11231)\n+11DC0 Uncompressed Size     00002BDF (11231)\n+\n+11DC4 LOCAL HEADER #29      04034B50 (67324752)\n+11DC8 Extract Zip Spec      14 (20) '2.0'\n+11DC9 Extract OS            00 (0) 'MS-DOS'\n+11DCA General Purpose Flag  0008 (8)\n+      [Bit  3]              1 'Streamed'\n+11DCC Compression Method    0000 (0) 'Stored'\n+11DCE Modification Time     EC210000 (3961585664) 'Wed Jan  1 00:00:00 2098'\n+11DD2 CRC                   00000000 (0)\n+11DD6 Compressed Size       00000000 (0)\n+11DDA Uncompressed Size     00000000 (0)\n+11DDE Filename Length       003A (58)\n+11DE0 Extra Length          0009 (9)\n+11DE2 Filename              'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX'\n+#\n+# WARNING: Offset 0x11DE2: Filename 'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX'\n+#          Zero length filename\n+#\n+11E1C Extra ID #1           5455 (21589) 'Extended Timestamp [UT]'\n+11E1E   Length              0005 (5)\n+11E20   Flags               01 (1) 'Modification'\n+11E21   Modification Time   00000000 (0) 'Thu Jan  1 00:00:00 1970'\n+11E25 PAYLOAD\n+\n+12873 DATA DESCRIPTOR       08074B50 (134695760)\n+12877 CRC                   E1297FD5 (3777593301)\n+1287B Compressed Size       00000A4E (2638)\n+1287F Uncompressed Size     00000A4E (2638)\n+\n+12883 LOCAL HEADER #30      04034B50 (67324752)\n+12887 Extract Zip Spec      14 (20) '2.0'\n+12888 Extract OS            00 (0) 'MS-DOS'\n+12889 General Purpose Flag  0008 (8)\n+      [Bit  3]              1 'Streamed'\n+1288B Compression Method    0000 (0) 'Stored'\n+1288D Modification Time     EC210000 (3961585664) 'Wed Jan  1 00:00:00 2098'\n+12891 CRC                   00000000 (0)\n+12895 Compressed Size       00000000 (0)\n+12899 Uncompressed Size     00000000 (0)\n+1289D Filename Length       0038 (56)\n+1289F Extra Length          0009 (9)\n+128A1 Filename              'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX'\n+#\n+# WARNING: Offset 0x128A1: Filename 'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX'\n+#          Zero length filename\n+#\n+128D9 Extra ID #1           5455 (21589) 'Extended Timestamp [UT]'\n+128DB   Length              0005 (5)\n+128DD   Flags               01 (1) 'Modification'\n+128DE   Modification Time   00000000 (0) 'Thu Jan  1 00:00:00 1970'\n+128E2 PAYLOAD\n+\n+13556 DATA DESCRIPTOR       08074B50 (134695760)\n+1355A CRC                   CDBF443E (3451864126)\n+1355E Compressed Size       00000C74 (3188)\n+13562 Uncompressed Size     00000C74 (3188)\n+\n+13566 LOCAL HEADER #31      04034B50 (67324752)\n+1356A Extract Zip Spec      14 (20) '2.0'\n+1356B Extract OS            00 (0) 'MS-DOS'\n+1356C General Purpose Flag  0008 (8)\n+      [Bit  3]              1 'Streamed'\n+1356E Compression Method    0000 (0) 'Stored'\n+13570 Modification Time     EC210000 (3961585664) 'Wed Jan  1 00:00:00 2098'\n+13574 CRC                   00000000 (0)\n+13578 Compressed Size       00000000 (0)\n+1357C Uncompressed Size     00000000 (0)\n+13580 Filename Length       0036 (54)\n+13582 Extra Length          0009 (9)\n+13584 Filename              'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX'\n+#\n+# WARNING: Offset 0x13584: Filename 'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX'\n+#          Zero length filename\n+#\n+135BA Extra ID #1           5455 (21589) 'Extended Timestamp [UT]'\n+135BC   Length              0005 (5)\n+135BE   Flags               01 (1) 'Modification'\n+135BF   Modification Time   00000000 (0) 'Thu Jan  1 00:00:00 1970'\n+135C3 PAYLOAD\n+\n+13BA0 DATA DESCRIPTOR       08074B50 (134695760)\n+13BA4 CRC                   151E182C (354293804)\n+13BA8 Compressed Size       000005DD (1501)\n+13BAC Uncompressed Size     000005DD (1501)\n+\n+13BB0 LOCAL HEADER #32      04034B50 (67324752)\n+13BB4 Extract Zip Spec      14 (20) '2.0'\n+13BB5 Extract OS            00 (0) 'MS-DOS'\n+13BB6 General Purpose Flag  0008 (8)\n+      [Bit  3]              1 'Streamed'\n+13BB8 Compression Method    0000 (0) 'Stored'\n+13BBA Modification Time     EC210000 (3961585664) 'Wed Jan  1 00:00:00 2098'\n+13BBE CRC                   00000000 (0)\n+13BC2 Compressed Size       00000000 (0)\n+13BC6 Uncompressed Size     00000000 (0)\n+13BCA Filename Length       0035 (53)\n+13BCC Extra Length          0009 (9)\n+13BCE Filename              'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX'\n+#\n+# WARNING: Offset 0x13BCE: Filename 'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX'\n+#          Zero length filename\n+#\n+13C03 Extra ID #1           5455 (21589) 'Extended Timestamp [UT]'\n+13C05   Length              0005 (5)\n+13C07   Flags               01 (1) 'Modification'\n+13C08   Modification Time   00000000 (0) 'Thu Jan  1 00:00:00 1970'\n+13C0C PAYLOAD\n+\n+15C9C DATA DESCRIPTOR       08074B50 (134695760)\n+15CA0 CRC                   39CBA339 (969646905)\n+15CA4 Compressed Size       00002090 (8336)\n+15CA8 Uncompressed Size     00002090 (8336)\n+\n+15CAC LOCAL HEADER #33      04034B50 (67324752)\n+15CB0 Extract Zip Spec      14 (20) '2.0'\n+15CB1 Extract OS            00 (0) 'MS-DOS'\n+15CB2 General Purpose Flag  0008 (8)\n+      [Bit  3]              1 'Streamed'\n+15CB4 Compression Method    0000 (0) 'Stored'\n+15CB6 Modification Time     EC210000 (3961585664) 'Wed Jan  1 00:00:00 2098'\n+15CBA CRC                   00000000 (0)\n+15CBE Compressed Size       00000000 (0)\n+15CC2 Uncompressed Size     00000000 (0)\n+15CC6 Filename Length       0036 (54)\n+15CC8 Extra Length          0009 (9)\n+15CCA Filename              'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX'\n+#\n+# WARNING: Offset 0x15CCA: Filename 'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX'\n+#          Zero length filename\n+#\n+15D00 Extra ID #1           5455 (21589) 'Extended Timestamp [UT]'\n+15D02   Length              0005 (5)\n+15D04   Flags               01 (1) 'Modification'\n+15D05   Modification Time   00000000 (0) 'Thu Jan  1 00:00:00 1970'\n+15D09 PAYLOAD\n+\n+1CAEE DATA DESCRIPTOR       08074B50 (134695760)\n+1CAF2 CRC                   07C16F02 (130117378)\n+1CAF6 Compressed Size       00006DE5 (28133)\n+1CAFA Uncompressed Size     00006DE5 (28133)\n+\n+1CAFE LOCAL HEADER #34      04034B50 (67324752)\n+1CB02 Extract Zip Spec      14 (20) '2.0'\n+1CB03 Extract OS            00 (0) 'MS-DOS'\n+1CB04 General Purpose Flag  0008 (8)\n+      [Bit  3]              1 'Streamed'\n+1CB06 Compression Method    0000 (0) 'Stored'\n+1CB08 Modification Time     EC210000 (3961585664) 'Wed Jan  1 00:00:00 2098'\n+1CB0C CRC                   00000000 (0)\n+1CB10 Compressed Size       00000000 (0)\n+1CB14 Uncompressed Size     00000000 (0)\n+1CB18 Filename Length       003C (60)\n+1CB1A Extra Length          0009 (9)\n+1CB1C Filename              'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX'\n+#\n+# WARNING: Offset 0x1CB1C: Filename 'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX'\n+#          Zero length filename\n+#\n+1CB58 Extra ID #1           5455 (21589) 'Extended Timestamp [UT]'\n+1CB5A   Length              0005 (5)\n+1CB5C   Flags               01 (1) 'Modification'\n+1CB5D   Modification Time   00000000 (0) 'Thu Jan  1 00:00:00 1970'\n+1CB61 PAYLOAD\n+\n+1D2B3 DATA DESCRIPTOR       08074B50 (134695760)\n+1D2B7 CRC                   DA119291 (3658584721)\n+1D2BB Compressed Size       00000752 (1874)\n+1D2BF Uncompressed Size     00000752 (1874)\n+\n+1D2C3 LOCAL HEADER #35      04034B50 (67324752)\n+1D2C7 Extract Zip Spec      14 (20) '2.0'\n+1D2C8 Extract OS            00 (0) 'MS-DOS'\n+1D2C9 General Purpose Flag  0008 (8)\n+      [Bit  3]              1 'Streamed'\n+1D2CB Compression Method    0000 (0) 'Stored'\n+1D2CD Modification Time     EC210000 (3961585664) 'Wed Jan  1 00:00:00 2098'\n+1D2D1 CRC                   00000000 (0)\n+1D2D5 Compressed Size       00000000 (0)\n+1D2D9 Uncompressed Size     00000000 (0)\n+1D2DD Filename Length       0042 (66)\n+1D2DF Extra Length          0009 (9)\n+1D2E1 Filename              'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX'\n+#\n+# WARNING: Offset 0x1D2E1: Filename 'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX'\n+#          Zero length filename\n+#\n+1D323 Extra ID #1           5455 (21589) 'Extended Timestamp [UT]'\n+1D325   Length              0005 (5)\n+1D327   Flags               01 (1) 'Modification'\n+1D328   Modification Time   00000000 (0) 'Thu Jan  1 00:00:00 1970'\n+1D32C PAYLOAD\n+\n+1F405 DATA DESCRIPTOR       08074B50 (134695760)\n+1F409 CRC                   0574FE58 (91553368)\n+1F40D Compressed Size       000020D9 (8409)\n+1F411 Uncompressed Size     000020D9 (8409)\n+\n+1F415 LOCAL HEADER #36      04034B50 (67324752)\n+1F419 Extract Zip Spec      14 (20) '2.0'\n+1F41A Extract OS            00 (0) 'MS-DOS'\n+1F41B General Purpose Flag  0008 (8)\n+      [Bit  3]              1 'Streamed'\n+1F41D Compression Method    0000 (0) 'Stored'\n+1F41F Modification Time     EC210000 (3961585664) 'Wed Jan  1 00:00:00 2098'\n+1F423 CRC                   00000000 (0)\n+1F427 Compressed Size       00000000 (0)\n+1F42B Uncompressed Size     00000000 (0)\n+1F42F Filename Length       0045 (69)\n+1F431 Extra Length          0009 (9)\n+1F433 Filename              'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX'\n+#\n+# WARNING: Offset 0x1F433: Filename 'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX'\n+#          Zero length filename\n+#\n+1F478 Extra ID #1           5455 (21589) 'Extended Timestamp [UT]'\n+1F47A   Length              0005 (5)\n+1F47C   Flags               01 (1) 'Modification'\n+1F47D   Modification Time   00000000 (0) 'Thu Jan  1 00:00:00 1970'\n+1F481 PAYLOAD\n+\n+20D1B DATA DESCRIPTOR       08074B50 (134695760)\n+20D1F CRC                   B5644E62 (3043249762)\n+20D23 Compressed Size       0000189A (6298)\n+20D27 Uncompressed Size     0000189A (6298)\n+\n+20D2B LOCAL HEADER #37      04034B50 (67324752)\n+20D2F Extract Zip Spec      14 (20) '2.0'\n+20D30 Extract OS            00 (0) 'MS-DOS'\n+20D31 General Purpose Flag  0000 (0)\n+20D33 Compression Method    0000 (0) 'Stored'\n+20D35 Modification Time     EC210000 (3961585664) 'Wed Jan  1 00:00:00 2098'\n+20D39 CRC                   00000000 (0)\n+20D3D Compressed Size       00000000 (0)\n+20D41 Uncompressed Size     00000000 (0)\n+20D45 Filename Length       002B (43)\n+20D47 Extra Length          0009 (9)\n+20D49 Filename              'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX'\n+#\n+# WARNING: Offset 0x20D49: Filename 'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX'\n+#          Zero length filename\n+#\n+20D74 Extra ID #1           5455 (21589) 'Extended Timestamp [UT]'\n+20D76   Length              0005 (5)\n+20D78   Flags               01 (1) 'Modification'\n+20D79   Modification Time   00000000 (0) 'Thu Jan  1 00:00:00 1970'\n+\n+20D7D LOCAL HEADER #38      04034B50 (67324752)\n+20D81 Extract Zip Spec      14 (20) '2.0'\n+20D82 Extract OS            00 (0) 'MS-DOS'\n+20D83 General Purpose Flag  0008 (8)\n+      [Bit  3]              1 'Streamed'\n+20D85 Compression Method    0000 (0) 'Stored'\n+20D87 Modification Time     EC210000 (3961585664) 'Wed Jan  1 00:00:00 2098'\n+20D8B CRC                   00000000 (0)\n+20D8F Compressed Size       00000000 (0)\n+20D93 Uncompressed Size     00000000 (0)\n+20D97 Filename Length       003C (60)\n+20D99 Extra Length          0009 (9)\n+20D9B Filename              'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX'\n+#\n+# WARNING: Offset 0x20D9B: Filename 'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX'\n+#          Zero length filename\n+#\n+20DD7 Extra ID #1           5455 (21589) 'Extended Timestamp [UT]'\n+20DD9   Length              0005 (5)\n+20DDB   Flags               01 (1) 'Modification'\n+20DDC   Modification Time   00000000 (0) 'Thu Jan  1 00:00:00 1970'\n+20DE0 PAYLOAD\n+\n+230D3 DATA DESCRIPTOR       08074B50 (134695760)\n+230D7 CRC                   45086F19 (1158180633)\n+230DB Compressed Size       000022F3 (8947)\n+230DF Uncompressed Size     000022F3 (8947)\n+\n+230E3 LOCAL HEADER #39      04034B50 (67324752)\n+230E7 Extract Zip Spec      14 (20) '2.0'\n+230E8 Extract OS            00 (0) 'MS-DOS'\n+230E9 General Purpose Flag  0008 (8)\n+      [Bit  3]              1 'Streamed'\n+230EB Compression Method    0000 (0) 'Stored'\n+230ED Modification Time     EC210000 (3961585664) 'Wed Jan  1 00:00:00 2098'\n+230F1 CRC                   00000000 (0)\n+230F5 Compressed Size       00000000 (0)\n+230F9 Uncompressed Size     00000000 (0)\n+230FD Filename Length       003B (59)\n+230FF Extra Length          0009 (9)\n+23101 Filename              'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX'\n+#\n+# WARNING: Offset 0x23101: Filename 'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX'\n+#          Zero length filename\n+#\n+2313C Extra ID #1           5455 (21589) 'Extended Timestamp [UT]'\n+2313E   Length              0005 (5)\n+23140   Flags               01 (1) 'Modification'\n+23141   Modification Time   00000000 (0) 'Thu Jan  1 00:00:00 1970'\n+23145 PAYLOAD\n+\n+2480C DATA DESCRIPTOR       08074B50 (134695760)\n+24810 CRC                   57E4B8CF (1474607311)\n+24814 Compressed Size       000016C7 (5831)\n+24818 Uncompressed Size     000016C7 (5831)\n+\n+2481C LOCAL HEADER #40      04034B50 (67324752)\n+24820 Extract Zip Spec      14 (20) '2.0'\n+24821 Extract OS            00 (0) 'MS-DOS'\n+24822 General Purpose Flag  0000 (0)\n+24824 Compression Method    0000 (0) 'Stored'\n+24826 Modification Time     EC210000 (3961585664) 'Wed Jan  1 00:00:00 2098'\n+2482A CRC                   00000000 (0)\n+2482E Compressed Size       00000000 (0)\n+24832 Uncompressed Size     00000000 (0)\n+24836 Filename Length       002B (43)\n+24838 Extra Length          0009 (9)\n+2483A Filename              'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX'\n+#\n+# WARNING: Offset 0x2483A: Filename 'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX'\n+#          Zero length filename\n+#\n+24865 Extra ID #1           5455 (21589) 'Extended Timestamp [UT]'\n+24867   Length              0005 (5)\n+24869   Flags               01 (1) 'Modification'\n+2486A   Modification Time   00000000 (0) 'Thu Jan  1 00:00:00 1970'\n+\n+2486E LOCAL HEADER #41      04034B50 (67324752)\n+24872 Extract Zip Spec      14 (20) '2.0'\n+24873 Extract OS            00 (0) 'MS-DOS'\n+24874 General Purpose Flag  0008 (8)\n+      [Bit  3]              1 'Streamed'\n+24876 Compression Method    0000 (0) 'Stored'\n+24878 Modification Time     EC210000 (3961585664) 'Wed Jan  1 00:00:00 2098'\n+2487C CRC                   00000000 (0)\n+24880 Compressed Size       00000000 (0)\n+24884 Uncompressed Size     00000000 (0)\n+24888 Filename Length       0043 (67)\n+2488A Extra Length          0009 (9)\n+2488C Filename              'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX'\n+#\n+# WARNING: Offset 0x2488C: Filename 'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX'\n+#          Zero length filename\n+#\n+248CF Extra ID #1           5455 (21589) 'Extended Timestamp [UT]'\n+248D1   Length              0005 (5)\n+248D3   Flags               01 (1) 'Modification'\n+248D4   Modification Time   00000000 (0) 'Thu Jan  1 00:00:00 1970'\n+248D8 PAYLOAD\n+\n+251F9 DATA DESCRIPTOR       08074B50 (134695760)\n+251FD CRC                   A77D588D (2810009741)\n+25201 Compressed Size       00000921 (2337)\n+25205 Uncompressed Size     00000921 (2337)\n+\n+25209 LOCAL HEADER #42      04034B50 (67324752)\n+2520D Extract Zip Spec      14 (20) '2.0'\n+2520E Extract OS            00 (0) 'MS-DOS'\n+2520F General Purpose Flag  0008 (8)\n+      [Bit  3]              1 'Streamed'\n+25211 Compression Method    0000 (0) 'Stored'\n+25213 Modification Time     EC210000 (3961585664) 'Wed Jan  1 00:00:00 2098'\n+25217 CRC                   00000000 (0)\n+2521B Compressed Size       00000000 (0)\n+2521F Uncompressed Size     00000000 (0)\n+25223 Filename Length       0047 (71)\n+25225 Extra Length          0009 (9)\n+25227 Filename              'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX'\n+#\n+# WARNING: Offset 0x25227: Filename 'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX'\n+#          Zero length filename\n+#\n+2526E Extra ID #1           5455 (21589) 'Extended Timestamp [UT]'\n+25270   Length              0005 (5)\n+25272   Flags               01 (1) 'Modification'\n+25273   Modification Time   00000000 (0) 'Thu Jan  1 00:00:00 1970'\n+25277 PAYLOAD\n+\n+25E40 DATA DESCRIPTOR       08074B50 (134695760)\n+25E44 CRC                   DF443A2F (3745790511)\n+25E48 Compressed Size       00000BC9 (3017)\n+25E4C Uncompressed Size     00000BC9 (3017)\n+\n+25E50 CENTRAL HEADER #1     02014B50 (33639248)\n+25E54 Created Zip Spec      14 (20) '2.0'\n+25E55 Created OS            00 (0) 'MS-DOS'\n+25E56 Extract Zip Spec      14 (20) '2.0'\n+25E57 Extract OS            00 (0) 'MS-DOS'\n+25E58 General Purpose Flag  0000 (0)\n+25E5A Compression Method    0000 (0) 'Stored'\n+25E5C Modification Time     EC210000 (3961585664) 'Wed Jan  1 00:00:00 2098'\n+25E60 CRC                   00000000 (0)\n+25E64 Compressed Size       00000000 (0)\n+25E68 Uncompressed Size     00000000 (0)\n+25E6C Filename Length       0009 (9)\n+25E6E Extra Length          0009 (9)\n+25E70 Comment Length        0000 (0)\n+25E72 Disk Start            0000 (0)\n+25E74 Int File Attributes   0000 (0)\n+      [Bit 0]               0 'Binary Data'\n+25E76 Ext File Attributes   00000000 (0)\n+25E7A Local Header Offset   00000000 (0)\n+25E7E Filename              'XXXXXXXXX'\n+#\n+# WARNING: Offset 0x25E7E: Filename 'XXXXXXXXX'\n+#          Zero length filename\n+#\n+25E87 Extra ID #1           5455 (21589) 'Extended Timestamp [UT]'\n+25E89   Length              0005 (5)\n+25E8B   Flags               01 (1) 'Modification'\n+25E8C   Modification Time   00000000 (0) 'Thu Jan  1 00:00:00 1970'\n+\n+25E90 CENTRAL HEADER #2     02014B50 (33639248)\n+25E94 Created Zip Spec      14 (20) '2.0'\n+25E95 Created OS            00 (0) 'MS-DOS'\n+25E96 Extract Zip Spec      14 (20) '2.0'\n+25E97 Extract OS            00 (0) 'MS-DOS'\n+25E98 General Purpose Flag  0008 (8)\n+      [Bit  3]              1 'Streamed'\n+25E9A Compression Method    0000 (0) 'Stored'\n+25E9C Modification Time     EC210000 (3961585664) 'Wed Jan  1 00:00:00 2098'\n+25EA0 CRC                   CFC19B47 (3485571911)\n+25EA4 Compressed Size       00000C40 (3136)\n+25EA8 Uncompressed Size     00000C40 (3136)\n+25EAC Filename Length       0015 (21)\n+25EAE Extra Length          0009 (9)\n+25EB0 Comment Length        0000 (0)\n+25EB2 Disk Start            0000 (0)\n+25EB4 Int File Attributes   0000 (0)\n+      [Bit 0]               0 'Binary Data'\n+25EB6 Ext File Attributes   00000000 (0)\n+25EBA Local Header Offset   00000030 (48)\n+25EBE Filename              'XXXXXXXXXXXXXXXXXXXXX'\n+#\n+# WARNING: Offset 0x25EBE: Filename 'XXXXXXXXXXXXXXXXXXXXX'\n+#          Zero length filename\n+#\n+25ED3 Extra ID #1           5455 (21589) 'Extended Timestamp [UT]'\n+25ED5   Length              0005 (5)\n+25ED7   Flags               01 (1) 'Modification'\n+25ED8   Modification Time   00000000 (0) 'Thu Jan  1 00:00:00 1970'\n+\n+25EDC CENTRAL HEADER #3     02014B50 (33639248)\n+25EE0 Created Zip Spec      14 (20) '2.0'\n+25EE1 Created OS            00 (0) 'MS-DOS'\n+25EE2 Extract Zip Spec      14 (20) '2.0'\n+25EE3 Extract OS            00 (0) 'MS-DOS'\n+25EE4 General Purpose Flag  0008 (8)\n+      [Bit  3]              1 'Streamed'\n+25EE6 Compression Method    0000 (0) 'Stored'\n+25EE8 Modification Time     EC210000 (3961585664) 'Wed Jan  1 00:00:00 2098'\n+25EEC CRC                   86E2B4B4 (2263004340)\n+25EF0 Compressed Size       00002C5E (11358)\n+25EF4 Uncompressed Size     00002C5E (11358)\n+25EF8 Filename Length       0010 (16)\n+25EFA Extra Length          0009 (9)\n+25EFC Comment Length        0000 (0)\n+25EFE Disk Start            0000 (0)\n+25F00 Int File Attributes   0000 (0)\n+      [Bit 0]               0 'Binary Data'\n+25F02 Ext File Attributes   00000000 (0)\n+25F06 Local Header Offset   00000CBC (3260)\n+25F0A Filename              'XXXXXXXXXXXXXXXX'\n+#\n+# WARNING: Offset 0x25F0A: Filename 'XXXXXXXXXXXXXXXX'\n+#          Zero length filename\n+#\n+25F1A Extra ID #1           5455 (21589) 'Extended Timestamp [UT]'\n+25F1C   Length              0005 (5)\n+25F1E   Flags               01 (1) 'Modification'\n+25F1F   Modification Time   00000000 (0) 'Thu Jan  1 00:00:00 1970'\n+\n+25F23 CENTRAL HEADER #4     02014B50 (33639248)\n+25F27 Created Zip Spec      14 (20) '2.0'\n+25F28 Created OS            00 (0) 'MS-DOS'\n+25F29 Extract Zip Spec      14 (20) '2.0'\n+25F2A Extract OS            00 (0) 'MS-DOS'\n+25F2B General Purpose Flag  0008 (8)\n+      [Bit  3]              1 'Streamed'\n+25F2D Compression Method    0000 (0) 'Stored'\n+25F2F Modification Time     EC210000 (3961585664) 'Wed Jan  1 00:00:00 2098'\n+25F33 CRC                   EE027FB2 (3993141170)\n+25F37 Compressed Size       00000019 (25)\n+25F3B Uncompressed Size     00000019 (25)\n+25F3F Filename Length       0014 (20)\n+25F41 Extra Length          0009 (9)\n+25F43 Comment Length        0000 (0)\n+25F45 Disk Start            0000 (0)\n+25F47 Int File Attributes   0000 (0)\n+      [Bit 0]               0 'Binary Data'\n+25F49 Ext File Attributes   00000000 (0)\n+25F4D Local Header Offset   00003961 (14689)\n+25F51 Filename              'XXXXXXXXXXXXXXXXXXXX'\n+#\n+# WARNING: Offset 0x25F51: Filename 'XXXXXXXXXXXXXXXXXXXX'\n+#          Zero length filename\n+#\n+25F65 Extra ID #1           5455 (21589) 'Extended Timestamp [UT]'\n+25F67   Length              0005 (5)\n+25F69   Flags               01 (1) 'Modification'\n+25F6A   Modification Time   00000000 (0) 'Thu Jan  1 00:00:00 1970'\n+\n+25F6E CENTRAL HEADER #5     02014B50 (33639248)\n+25F72 Created Zip Spec      14 (20) '2.0'\n+25F73 Created OS            00 (0) 'MS-DOS'\n+25F74 Extract Zip Spec      14 (20) '2.0'\n+25F75 Extract OS            00 (0) 'MS-DOS'\n+25F76 General Purpose Flag  0008 (8)\n+      [Bit  3]              1 'Streamed'\n+25F78 Compression Method    0000 (0) 'Stored'\n+25F7A Modification Time     EC210000 (3961585664) 'Wed Jan  1 00:00:00 2098'\n+25F7E CRC                   9C935012 (2626899986)\n+25F82 Compressed Size       000000AC (172)\n+25F86 Uncompressed Size     000000AC (172)\n+25F8A Filename Length       000F (15)\n+25F8C Extra Length          0009 (9)\n+25F8E Comment Length        0000 (0)\n+25F90 Disk Start            0000 (0)\n+25F92 Int File Attributes   0000 (0)\n+      [Bit 0]               0 'Binary Data'\n+25F94 Ext File Attributes   00000000 (0)\n+25F98 Local Header Offset   000039C5 (14789)\n+25F9C Filename              'XXXXXXXXXXXXXXX'\n+#\n+# WARNING: Offset 0x25F9C: Filename 'XXXXXXXXXXXXXXX'\n+#          Zero length filename\n+#\n+25FAB Extra ID #1           5455 (21589) 'Extended Timestamp [UT]'\n+25FAD   Length              0005 (5)\n+25FAF   Flags               01 (1) 'Modification'\n+25FB0   Modification Time   00000000 (0) 'Thu Jan  1 00:00:00 1970'\n+\n+25FB4 CENTRAL HEADER #6     02014B50 (33639248)\n+25FB8 Created Zip Spec      14 (20) '2.0'\n+25FB9 Created OS            00 (0) 'MS-DOS'\n+25FBA Extract Zip Spec      14 (20) '2.0'\n+25FBB Extract OS            00 (0) 'MS-DOS'\n+25FBC General Purpose Flag  0000 (0)\n+25FBE Compression Method    0000 (0) 'Stored'\n+25FC0 Modification Time     EC210000 (3961585664) 'Wed Jan  1 00:00:00 2098'\n+25FC4 CRC                   00000000 (0)\n+25FC8 Compressed Size       00000000 (0)\n+25FCC Uncompressed Size     00000000 (0)\n+25FD0 Filename Length       000F (15)\n+25FD2 Extra Length          0009 (9)\n+25FD4 Comment Length        0000 (0)\n+25FD6 Disk Start            0000 (0)\n+25FD8 Int File Attributes   0000 (0)\n+      [Bit 0]               0 'Binary Data'\n+25FDA Ext File Attributes   00000000 (0)\n+25FDE Local Header Offset   00003AB7 (15031)\n+25FE2 Filename              'XXXXXXXXXXXXXXX'\n+#\n+# WARNING: Offset 0x25FE2: Filename 'XXXXXXXXXXXXXXX'\n+#          Zero length filename\n+#\n+25FF1 Extra ID #1           5455 (21589) 'Extended Timestamp [UT]'\n+25FF3   Length              0005 (5)\n+25FF5   Flags               01 (1) 'Modification'\n+25FF6   Modification Time   00000000 (0) 'Thu Jan  1 00:00:00 1970'\n+\n+25FFA CENTRAL HEADER #7     02014B50 (33639248)\n+25FFE Created Zip Spec      14 (20) '2.0'\n+25FFF Created OS            00 (0) 'MS-DOS'\n+26000 Extract Zip Spec      14 (20) '2.0'\n+26001 Extract OS            00 (0) 'MS-DOS'\n+26002 General Purpose Flag  0000 (0)\n+26004 Compression Method    0000 (0) 'Stored'\n+26006 Modification Time     EC210000 (3961585664) 'Wed Jan  1 00:00:00 2098'\n+2600A CRC                   00000000 (0)\n+2600E Compressed Size       00000000 (0)\n+26012 Uncompressed Size     00000000 (0)\n+26016 Filename Length       0018 (24)\n+26018 Extra Length          0009 (9)\n+2601A Comment Length        0000 (0)\n+2601C Disk Start            0000 (0)\n+2601E Int File Attributes   0000 (0)\n+      [Bit 0]               0 'Binary Data'\n+26020 Ext File Attributes   00000000 (0)\n+26024 Local Header Offset   00003AED (15085)\n+26028 Filename              'XXXXXXXXXXXXXXXXXXXXXXXX'\n+#\n+# WARNING: Offset 0x26028: Filename 'XXXXXXXXXXXXXXXXXXXXXXXX'\n+#          Zero length filename\n+#\n+26040 Extra ID #1           5455 (21589) 'Extended Timestamp [UT]'\n+26042   Length              0005 (5)\n+26044   Flags               01 (1) 'Modification'\n+26045   Modification Time   00000000 (0) 'Thu Jan  1 00:00:00 1970'\n+\n+26049 CENTRAL HEADER #8     02014B50 (33639248)\n+2604D Created Zip Spec      14 (20) '2.0'\n+2604E Created OS            00 (0) 'MS-DOS'\n+2604F Extract Zip Spec      14 (20) '2.0'\n+26050 Extract OS            00 (0) 'MS-DOS'\n+26051 General Purpose Flag  0008 (8)\n+      [Bit  3]              1 'Streamed'\n+26053 Compression Method    0000 (0) 'Stored'\n+26055 Modification Time     EC210000 (3961585664) 'Wed Jan  1 00:00:00 2098'\n+26059 CRC                   2D68A65E (761833054)\n+2605D Compressed Size       00000094 (148)\n+26061 Uncompressed Size     00000094 (148)\n+26065 Filename Length       0044 (68)\n+26067 Extra Length          0009 (9)\n+26069 Comment Length        0000 (0)\n+2606B Disk Start            0000 (0)\n+2606D Int File Attributes   0000 (0)\n+      [Bit 0]               0 'Binary Data'\n+2606F Ext File Attributes   00000000 (0)\n+26073 Local Header Offset   00003B2C (15148)\n+26077 Filename              'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX'\n+#\n+# WARNING: Offset 0x26077: Filename 'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX'\n+#          Zero length filename\n+#\n+260BB Extra ID #1           5455 (21589) 'Extended Timestamp [UT]'\n+260BD   Length              0005 (5)\n+260BF   Flags               01 (1) 'Modification'\n+260C0   Modification Time   00000000 (0) 'Thu Jan  1 00:00:00 1970'\n+\n+260C4 CENTRAL HEADER #9     02014B50 (33639248)\n+260C8 Created Zip Spec      14 (20) '2.0'\n+260C9 Created OS            00 (0) 'MS-DOS'\n+260CA Extract Zip Spec      14 (20) '2.0'\n+260CB Extract OS            00 (0) 'MS-DOS'\n+260CC General Purpose Flag  0008 (8)\n+      [Bit  3]              1 'Streamed'\n+260CE Compression Method    0000 (0) 'Stored'\n+260D0 Modification Time     EC210000 (3961585664) 'Wed Jan  1 00:00:00 2098'\n+260D4 CRC                   A5009E2B (2768281131)\n+260D8 Compressed Size       00000039 (57)\n+260DC Uncompressed Size     00000039 (57)\n+260E0 Filename Length       0038 (56)\n+260E2 Extra Length          0009 (9)\n+260E4 Comment Length        0000 (0)\n+260E6 Disk Start            0000 (0)\n+260E8 Int File Attributes   0000 (0)\n+      [Bit 0]               0 'Binary Data'\n+260EA Ext File Attributes   00000000 (0)\n+260EE Local Header Offset   00003C3B (15419)\n+260F2 Filename              'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX'\n+#\n+# WARNING: Offset 0x260F2: Filename 'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX'\n+#          Zero length filename\n+#\n+2612A Extra ID #1           5455 (21589) 'Extended Timestamp [UT]'\n+2612C   Length              0005 (5)\n+2612E   Flags               01 (1) 'Modification'\n+2612F   Modification Time   00000000 (0) 'Thu Jan  1 00:00:00 1970'\n+\n+26133 CENTRAL HEADER #10    02014B50 (33639248)\n+26137 Created Zip Spec      14 (20) '2.0'\n+26138 Created OS            00 (0) 'MS-DOS'\n+26139 Extract Zip Spec      14 (20) '2.0'\n+2613A Extract OS            00 (0) 'MS-DOS'\n+2613B General Purpose Flag  0008 (8)\n+      [Bit  3]              1 'Streamed'\n+2613D Compression Method    0000 (0) 'Stored'\n+2613F Modification Time     EC210000 (3961585664) 'Wed Jan  1 00:00:00 2098'\n+26143 CRC                   A3C6F966 (2747726182)\n+26147 Compressed Size       0000007C (124)\n+2614B Uncompressed Size     0000007C (124)\n+2614F Filename Length       0033 (51)\n+26151 Extra Length          0009 (9)\n+26153 Comment Length        0000 (0)\n+26155 Disk Start            0000 (0)\n+26157 Int File Attributes   0000 (0)\n+      [Bit 0]               0 'Binary Data'\n+26159 Ext File Attributes   00000000 (0)\n+2615D Local Header Offset   00003CE3 (15587)\n+26161 Filename              'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX'\n+#\n+# WARNING: Offset 0x26161: Filename 'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX'\n+#          Zero length filename\n+#\n+26194 Extra ID #1           5455 (21589) 'Extended Timestamp [UT]'\n+26196   Length              0005 (5)\n+26198   Flags               01 (1) 'Modification'\n+26199   Modification Time   00000000 (0) 'Thu Jan  1 00:00:00 1970'\n+\n+2619D CENTRAL HEADER #11    02014B50 (33639248)\n+261A1 Created Zip Spec      14 (20) '2.0'\n+261A2 Created OS            00 (0) 'MS-DOS'\n+261A3 Extract Zip Spec      14 (20) '2.0'\n+261A4 Extract OS            00 (0) 'MS-DOS'\n+261A5 General Purpose Flag  0008 (8)\n+      [Bit  3]              1 'Streamed'\n+261A7 Compression Method    0000 (0) 'Stored'\n+261A9 Modification Time     EC210000 (3961585664) 'Wed Jan  1 00:00:00 2098'\n+261AD CRC                   83A37AD0 (2208529104)\n+261B1 Compressed Size       00000037 (55)\n+261B5 Uncompressed Size     00000037 (55)\n+261B9 Filename Length       0035 (53)\n+261BB Extra Length          0009 (9)\n+261BD Comment Length        0000 (0)\n+261BF Disk Start            0000 (0)\n+261C1 Int File Attributes   0000 (0)\n+      [Bit 0]               0 'Binary Data'\n+261C3 Ext File Attributes   00000000 (0)\n+261C7 Local Header Offset   00003DC9 (15817)\n+261CB Filename              'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX'\n+#\n+# WARNING: Offset 0x261CB: Filename 'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX'\n+#          Zero length filename\n+#\n+26200 Extra ID #1           5455 (21589) 'Extended Timestamp [UT]'\n+26202   Length              0005 (5)\n+26204   Flags               01 (1) 'Modification'\n+26205   Modification Time   00000000 (0) 'Thu Jan  1 00:00:00 1970'\n+\n+26209 CENTRAL HEADER #12    02014B50 (33639248)\n+2620D Created Zip Spec      14 (20) '2.0'\n+2620E Created OS            00 (0) 'MS-DOS'\n+2620F Extract Zip Spec      14 (20) '2.0'\n+26210 Extract OS            00 (0) 'MS-DOS'\n+26211 General Purpose Flag  0000 (0)\n+26213 Compression Method    0000 (0) 'Stored'\n+26215 Modification Time     EC210000 (3961585664) 'Wed Jan  1 00:00:00 2098'\n+26219 CRC                   00000000 (0)\n+2621D Compressed Size       00000000 (0)\n+26221 Uncompressed Size     00000000 (0)\n+26225 Filename Length       000F (15)\n+26227 Extra Length          0009 (9)\n+26229 Comment Length        0000 (0)\n+2622B Disk Start            0000 (0)\n+2622D Int File Attributes   0000 (0)\n+      [Bit 0]               0 'Binary Data'\n+2622F Ext File Attributes   00000000 (0)\n+26233 Local Header Offset   00003E6C (15980)\n+26237 Filename              'XXXXXXXXXXXXXXX'\n+#\n+# WARNING: Offset 0x26237: Filename 'XXXXXXXXXXXXXXX'\n+#          Zero length filename\n+#\n+26246 Extra ID #1           5455 (21589) 'Extended Timestamp [UT]'\n+26248   Length              0005 (5)\n+2624A   Flags               01 (1) 'Modification'\n+2624B   Modification Time   00000000 (0) 'Thu Jan  1 00:00:00 1970'\n+\n+2624F CENTRAL HEADER #13    02014B50 (33639248)\n+26253 Created Zip Spec      14 (20) '2.0'\n+26254 Created OS            00 (0) 'MS-DOS'\n+26255 Extract Zip Spec      14 (20) '2.0'\n+26256 Extract OS            00 (0) 'MS-DOS'\n+26257 General Purpose Flag  0000 (0)\n+26259 Compression Method    0000 (0) 'Stored'\n+2625B Modification Time     EC210000 (3961585664) 'Wed Jan  1 00:00:00 2098'\n+2625F CRC                   00000000 (0)\n+26263 Compressed Size       00000000 (0)\n+26267 Uncompressed Size     00000000 (0)\n+2626B Filename Length       0020 (32)\n+2626D Extra Length          0009 (9)\n+2626F Comment Length        0000 (0)\n+26271 Disk Start            0000 (0)\n+26273 Int File Attributes   0000 (0)\n+      [Bit 0]               0 'Binary Data'\n+26275 Ext File Attributes   00000000 (0)\n+26279 Local Header Offset   00003EA2 (16034)\n+2627D Filename              'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX'\n+#\n+# WARNING: Offset 0x2627D: Filename 'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX'\n+#          Zero length filename\n+#\n+2629D Extra ID #1           5455 (21589) 'Extended Timestamp [UT]'\n+2629F   Length              0005 (5)\n+262A1   Flags               01 (1) 'Modification'\n+262A2   Modification Time   00000000 (0) 'Thu Jan  1 00:00:00 1970'\n+\n+262A6 CENTRAL HEADER #14    02014B50 (33639248)\n+262AA Created Zip Spec      14 (20) '2.0'\n+262AB Created OS            00 (0) 'MS-DOS'\n+262AC Extract Zip Spec      14 (20) '2.0'\n+262AD Extract OS            00 (0) 'MS-DOS'\n+262AE General Purpose Flag  0000 (0)\n+262B0 Compression Method    0000 (0) 'Stored'\n+262B2 Modification Time     EC210000 (3961585664) 'Wed Jan  1 00:00:00 2098'\n+262B6 CRC                   00000000 (0)\n+262BA Compressed Size       00000000 (0)\n+262BE Uncompressed Size     00000000 (0)\n+262C2 Filename Length       0030 (48)\n+262C4 Extra Length          0009 (9)\n+262C6 Comment Length        0000 (0)\n+262C8 Disk Start            0000 (0)\n+262CA Int File Attributes   0000 (0)\n+      [Bit 0]               0 'Binary Data'\n+262CC Ext File Attributes   00000000 (0)\n+262D0 Local Header Offset   00003EE9 (16105)\n+262D4 Filename              'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX'\n+#\n+# WARNING: Offset 0x262D4: Filename 'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX'\n+#          Zero length filename\n+#\n+26304 Extra ID #1           5455 (21589) 'Extended Timestamp [UT]'\n+26306   Length              0005 (5)\n+26308   Flags               01 (1) 'Modification'\n+26309   Modification Time   00000000 (0) 'Thu Jan  1 00:00:00 1970'\n+\n+2630D CENTRAL HEADER #15    02014B50 (33639248)\n+26311 Created Zip Spec      14 (20) '2.0'\n+26312 Created OS            00 (0) 'MS-DOS'\n+26313 Extract Zip Spec      14 (20) '2.0'\n+26314 Extract OS            00 (0) 'MS-DOS'\n+26315 General Purpose Flag  0008 (8)\n+      [Bit  3]              1 'Streamed'\n+26317 Compression Method    0000 (0) 'Stored'\n+26319 Modification Time     EC210000 (3961585664) 'Wed Jan  1 00:00:00 2098'\n+2631D CRC                   00000000 (0)\n+26321 Compressed Size       00000000 (0)\n+26325 Uncompressed Size     00000000 (0)\n+26329 Filename Length       003E (62)\n+2632B Extra Length          0009 (9)\n+2632D Comment Length        0000 (0)\n+2632F Disk Start            0000 (0)\n+26331 Int File Attributes   0000 (0)\n+      [Bit 0]               0 'Binary Data'\n+26333 Ext File Attributes   00000000 (0)\n+26337 Local Header Offset   00003F40 (16192)\n+2633B Filename              'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX'\n+#\n+# WARNING: Offset 0x2633B: Filename 'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX'\n+#          Zero length filename\n+#\n+26379 Extra ID #1           5455 (21589) 'Extended Timestamp [UT]'\n+2637B   Length              0005 (5)\n+2637D   Flags               01 (1) 'Modification'\n+2637E   Modification Time   00000000 (0) 'Thu Jan  1 00:00:00 1970'\n+\n+26382 CENTRAL HEADER #16    02014B50 (33639248)\n+26386 Created Zip Spec      14 (20) '2.0'\n+26387 Created OS            00 (0) 'MS-DOS'\n+26388 Extract Zip Spec      14 (20) '2.0'\n+26389 Extract OS            00 (0) 'MS-DOS'\n+2638A General Purpose Flag  0008 (8)\n+      [Bit  3]              1 'Streamed'\n+2638C Compression Method    0000 (0) 'Stored'\n+2638E Modification Time     EC210000 (3961585664) 'Wed Jan  1 00:00:00 2098'\n+26392 CRC                   C3B87E97 (3283648151)\n+26396 Compressed Size       00000F4C (3916)\n+2639A Uncompressed Size     00000F4C (3916)\n+2639E Filename Length       0037 (55)\n+263A0 Extra Length          0009 (9)\n+263A2 Comment Length        0000 (0)\n+263A4 Disk Start            0000 (0)\n+263A6 Int File Attributes   0000 (0)\n+      [Bit 0]               0 'Binary Data'\n+263A8 Ext File Attributes   00000000 (0)\n+263AC Local Header Offset   00003FB5 (16309)\n+263B0 Filename              'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX'\n+#\n+# WARNING: Offset 0x263B0: Filename 'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX'\n+#          Zero length filename\n+#\n+263E7 Extra ID #1           5455 (21589) 'Extended Timestamp [UT]'\n+263E9   Length              0005 (5)\n+263EB   Flags               01 (1) 'Modification'\n+263EC   Modification Time   00000000 (0) 'Thu Jan  1 00:00:00 1970'\n+\n+263F0 CENTRAL HEADER #17    02014B50 (33639248)\n+263F4 Created Zip Spec      14 (20) '2.0'\n+263F5 Created OS            00 (0) 'MS-DOS'\n+263F6 Extract Zip Spec      14 (20) '2.0'\n+263F7 Extract OS            00 (0) 'MS-DOS'\n+263F8 General Purpose Flag  0000 (0)\n+263FA Compression Method    0000 (0) 'Stored'\n+263FC Modification Time     EC210000 (3961585664) 'Wed Jan  1 00:00:00 2098'\n+26400 CRC                   00000000 (0)\n+26404 Compressed Size       00000000 (0)\n+26408 Uncompressed Size     00000000 (0)\n+2640C Filename Length       0004 (4)\n+2640E Extra Length          0009 (9)\n+26410 Comment Length        0000 (0)\n+26412 Disk Start            0000 (0)\n+26414 Int File Attributes   0000 (0)\n+      [Bit 0]               0 'Binary Data'\n+26416 Ext File Attributes   00000000 (0)\n+2641A Local Header Offset   00004F6F (20335)\n+2641E Filename              'XXXX'\n+#\n+# WARNING: Offset 0x2641E: Filename 'XXXX'\n+#          Zero length filename\n+#\n+26422 Extra ID #1           5455 (21589) 'Extended Timestamp [UT]'\n+26424   Length              0005 (5)\n+26426   Flags               01 (1) 'Modification'\n+26427   Modification Time   00000000 (0) 'Thu Jan  1 00:00:00 1970'\n+\n+2642B CENTRAL HEADER #18    02014B50 (33639248)\n+2642F Created Zip Spec      14 (20) '2.0'\n+26430 Created OS            00 (0) 'MS-DOS'\n+26431 Extract Zip Spec      14 (20) '2.0'\n+26432 Extract OS            00 (0) 'MS-DOS'\n+26433 General Purpose Flag  0000 (0)\n+26435 Compression Method    0000 (0) 'Stored'\n+26437 Modification Time     EC210000 (3961585664) 'Wed Jan  1 00:00:00 2098'\n+2643B CRC                   00000000 (0)\n+2643F Compressed Size       00000000 (0)\n+26443 Uncompressed Size     00000000 (0)\n+26447 Filename Length       000B (11)\n+26449 Extra Length          0009 (9)\n+2644B Comment Length        0000 (0)\n+2644D Disk Start            0000 (0)\n+2644F Int File Attributes   0000 (0)\n+      [Bit 0]               0 'Binary Data'\n+26451 Ext File Attributes   00000000 (0)\n+26455 Local Header Offset   00004F9A (20378)\n+26459 Filename              'XXXXXXXXXXX'\n+#\n+# WARNING: Offset 0x26459: Filename 'XXXXXXXXXXX'\n+#          Zero length filename\n+#\n+26464 Extra ID #1           5455 (21589) 'Extended Timestamp [UT]'\n+26466   Length              0005 (5)\n+26468   Flags               01 (1) 'Modification'\n+26469   Modification Time   00000000 (0) 'Thu Jan  1 00:00:00 1970'\n+\n+2646D CENTRAL HEADER #19    02014B50 (33639248)\n+26471 Created Zip Spec      14 (20) '2.0'\n+26472 Created OS            00 (0) 'MS-DOS'\n+26473 Extract Zip Spec      14 (20) '2.0'\n+26474 Extract OS            00 (0) 'MS-DOS'\n+26475 General Purpose Flag  0000 (0)\n+26477 Compression Method    0000 (0) 'Stored'\n+26479 Modification Time     EC210000 (3961585664) 'Wed Jan  1 00:00:00 2098'\n+2647D CRC                   00000000 (0)\n+26481 Compressed Size       00000000 (0)\n+26485 Uncompressed Size     00000000 (0)\n+26489 Filename Length       0011 (17)\n+2648B Extra Length          0009 (9)\n+2648D Comment Length        0000 (0)\n+2648F Disk Start            0000 (0)\n+26491 Int File Attributes   0000 (0)\n+      [Bit 0]               0 'Binary Data'\n+26493 Ext File Attributes   00000000 (0)\n+26497 Local Header Offset   00004FCC (20428)\n+2649B Filename              'XXXXXXXXXXXXXXXXX'\n+#\n+# WARNING: Offset 0x2649B: Filename 'XXXXXXXXXXXXXXXXX'\n+#          Zero length filename\n+#\n+264AC Extra ID #1           5455 (21589) 'Extended Timestamp [UT]'\n+264AE   Length              0005 (5)\n+264B0   Flags               01 (1) 'Modification'\n+264B1   Modification Time   00000000 (0) 'Thu Jan  1 00:00:00 1970'\n+\n+264B5 CENTRAL HEADER #20    02014B50 (33639248)\n+264B9 Created Zip Spec      14 (20) '2.0'\n+264BA Created OS            00 (0) 'MS-DOS'\n+264BB Extract Zip Spec      14 (20) '2.0'\n+264BC Extract OS            00 (0) 'MS-DOS'\n+264BD General Purpose Flag  0000 (0)\n+264BF Compression Method    0000 (0) 'Stored'\n+264C1 Modification Time     EC210000 (3961585664) 'Wed Jan  1 00:00:00 2098'\n+264C5 CRC                   00000000 (0)\n+264C9 Compressed Size       00000000 (0)\n+264CD Uncompressed Size     00000000 (0)\n+264D1 Filename Length       0015 (21)\n+264D3 Extra Length          0009 (9)\n+264D5 Comment Length        0000 (0)\n+264D7 Disk Start            0000 (0)\n+264D9 Int File Attributes   0000 (0)\n+      [Bit 0]               0 'Binary Data'\n+264DB Ext File Attributes   00000000 (0)\n+264DF Local Header Offset   00005004 (20484)\n+264E3 Filename              'XXXXXXXXXXXXXXXXXXXXX'\n+#\n+# WARNING: Offset 0x264E3: Filename 'XXXXXXXXXXXXXXXXXXXXX'\n+#          Zero length filename\n+#\n+264F8 Extra ID #1           5455 (21589) 'Extended Timestamp [UT]'\n+264FA   Length              0005 (5)\n+264FC   Flags               01 (1) 'Modification'\n+264FD   Modification Time   00000000 (0) 'Thu Jan  1 00:00:00 1970'\n+\n+26501 CENTRAL HEADER #21    02014B50 (33639248)\n+26505 Created Zip Spec      14 (20) '2.0'\n+26506 Created OS            00 (0) 'MS-DOS'\n+26507 Extract Zip Spec      14 (20) '2.0'\n+26508 Extract OS            00 (0) 'MS-DOS'\n+26509 General Purpose Flag  0000 (0)\n+2650B Compression Method    0000 (0) 'Stored'\n+2650D Modification Time     EC210000 (3961585664) 'Wed Jan  1 00:00:00 2098'\n+26511 CRC                   00000000 (0)\n+26515 Compressed Size       00000000 (0)\n+26519 Uncompressed Size     00000000 (0)\n+2651D Filename Length       001E (30)\n+2651F Extra Length          0009 (9)\n+26521 Comment Length        0000 (0)\n+26523 Disk Start            0000 (0)\n+26525 Int File Attributes   0000 (0)\n+      [Bit 0]               0 'Binary Data'\n+26527 Ext File Attributes   00000000 (0)\n+2652B Local Header Offset   00005040 (20544)\n+2652F Filename              'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXX'\n+#\n+# WARNING: Offset 0x2652F: Filename 'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXX'\n+#          Zero length filename\n+#\n+2654D Extra ID #1           5455 (21589) 'Extended Timestamp [UT]'\n+2654F   Length              0005 (5)\n+26551   Flags               01 (1) 'Modification'\n+26552   Modification Time   00000000 (0) 'Thu Jan  1 00:00:00 1970'\n+\n+26556 CENTRAL HEADER #22    02014B50 (33639248)\n+2655A Created Zip Spec      14 (20) '2.0'\n+2655B Created OS            00 (0) 'MS-DOS'\n+2655C Extract Zip Spec      14 (20) '2.0'\n+2655D Extract OS            00 (0) 'MS-DOS'\n+2655E General Purpose Flag  0000 (0)\n+26560 Compression Method    0000 (0) 'Stored'\n+26562 Modification Time     EC210000 (3961585664) 'Wed Jan  1 00:00:00 2098'\n+26566 CRC                   00000000 (0)\n+2656A Compressed Size       00000000 (0)\n+2656E Uncompressed Size     00000000 (0)\n+26572 Filename Length       0024 (36)\n+26574 Extra Length          0009 (9)\n+26576 Comment Length        0000 (0)\n+26578 Disk Start            0000 (0)\n+2657A Int File Attributes   0000 (0)\n+      [Bit 0]               0 'Binary Data'\n+2657C Ext File Attributes   00000000 (0)\n+26580 Local Header Offset   00005085 (20613)\n+26584 Filename              'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX'\n+#\n+# WARNING: Offset 0x26584: Filename 'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX'\n+#          Zero length filename\n+#\n+265A8 Extra ID #1           5455 (21589) 'Extended Timestamp [UT]'\n+265AA   Length              0005 (5)\n+265AC   Flags               01 (1) 'Modification'\n+265AD   Modification Time   00000000 (0) 'Thu Jan  1 00:00:00 1970'\n+\n+265B1 CENTRAL HEADER #23    02014B50 (33639248)\n+265B5 Created Zip Spec      14 (20) '2.0'\n+265B6 Created OS            00 (0) 'MS-DOS'\n+265B7 Extract Zip Spec      14 (20) '2.0'\n+265B8 Extract OS            00 (0) 'MS-DOS'\n+265B9 General Purpose Flag  0008 (8)\n+      [Bit  3]              1 'Streamed'\n+265BB Compression Method    0000 (0) 'Stored'\n+265BD Modification Time     EC210000 (3961585664) 'Wed Jan  1 00:00:00 2098'\n+265C1 CRC                   5F5E6ACD (1600023245)\n+265C5 Compressed Size       00003F85 (16261)\n+265C9 Uncompressed Size     00003F85 (16261)\n+265CD Filename Length       003D (61)\n+265CF Extra Length          0009 (9)\n+265D1 Comment Length        0000 (0)\n+265D3 Disk Start            0000 (0)\n+265D5 Int File Attributes   0000 (0)\n+      [Bit 0]               0 'Binary Data'\n+265D7 Ext File Attributes   00000000 (0)\n+265DB Local Header Offset   000050D0 (20688)\n+265DF Filename              'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX'\n+#\n+# WARNING: Offset 0x265DF: Filename 'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX'\n+#          Zero length filename\n+#\n+2661C Extra ID #1           5455 (21589) 'Extended Timestamp [UT]'\n+2661E   Length              0005 (5)\n+26620   Flags               01 (1) 'Modification'\n+26621   Modification Time   00000000 (0) 'Thu Jan  1 00:00:00 1970'\n+\n+26625 CENTRAL HEADER #24    02014B50 (33639248)\n+26629 Created Zip Spec      14 (20) '2.0'\n+2662A Created OS            00 (0) 'MS-DOS'\n+2662B Extract Zip Spec      14 (20) '2.0'\n+2662C Extract OS            00 (0) 'MS-DOS'\n+2662D General Purpose Flag  0008 (8)\n+      [Bit  3]              1 'Streamed'\n+2662F Compression Method    0000 (0) 'Stored'\n+26631 Modification Time     EC210000 (3961585664) 'Wed Jan  1 00:00:00 2098'\n+26635 CRC                   980C94D0 (2550961360)\n+26639 Compressed Size       0000199A (6554)\n+2663D Uncompressed Size     0000199A (6554)\n+26641 Filename Length       003E (62)\n+26643 Extra Length          0009 (9)\n+26645 Comment Length        0000 (0)\n+26647 Disk Start            0000 (0)\n+26649 Int File Attributes   0000 (0)\n+      [Bit 0]               0 'Binary Data'\n+2664B Ext File Attributes   00000000 (0)\n+2664F Local Header Offset   000090C9 (37065)\n+26653 Filename              'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX'\n+#\n+# WARNING: Offset 0x26653: Filename 'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX'\n+#          Zero length filename\n+#\n+26691 Extra ID #1           5455 (21589) 'Extended Timestamp [UT]'\n+26693   Length              0005 (5)\n+26695   Flags               01 (1) 'Modification'\n+26696   Modification Time   00000000 (0) 'Thu Jan  1 00:00:00 1970'\n+\n+2669A CENTRAL HEADER #25    02014B50 (33639248)\n+2669E Created Zip Spec      14 (20) '2.0'\n+2669F Created OS            00 (0) 'MS-DOS'\n+266A0 Extract Zip Spec      14 (20) '2.0'\n+266A1 Extract OS            00 (0) 'MS-DOS'\n+266A2 General Purpose Flag  0008 (8)\n+      [Bit  3]              1 'Streamed'\n+266A4 Compression Method    0000 (0) 'Stored'\n+266A6 Modification Time     EC210000 (3961585664) 'Wed Jan  1 00:00:00 2098'\n+266AA CRC                   4C7D08FC (1283262716)\n+266AE Compressed Size       000008FF (2303)\n+266B2 Uncompressed Size     000008FF (2303)\n+266B6 Filename Length       0032 (50)\n+266B8 Extra Length          0009 (9)\n+266BA Comment Length        0000 (0)\n+266BC Disk Start            0000 (0)\n+266BE Int File Attributes   0000 (0)\n+      [Bit 0]               0 'Binary Data'\n+266C0 Ext File Attributes   00000000 (0)\n+266C4 Local Header Offset   0000AAD8 (43736)\n+266C8 Filename              'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX'\n+#\n+# WARNING: Offset 0x266C8: Filename 'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX'\n+#          Zero length filename\n+#\n+266FA Extra ID #1           5455 (21589) 'Extended Timestamp [UT]'\n+266FC   Length              0005 (5)\n+266FE   Flags               01 (1) 'Modification'\n+266FF   Modification Time   00000000 (0) 'Thu Jan  1 00:00:00 1970'\n+\n+26703 CENTRAL HEADER #26    02014B50 (33639248)\n+26707 Created Zip Spec      14 (20) '2.0'\n+26708 Created OS            00 (0) 'MS-DOS'\n+26709 Extract Zip Spec      14 (20) '2.0'\n+2670A Extract OS            00 (0) 'MS-DOS'\n+2670B General Purpose Flag  0008 (8)\n+      [Bit  3]              1 'Streamed'\n+2670D Compression Method    0000 (0) 'Stored'\n+2670F Modification Time     EC210000 (3961585664) 'Wed Jan  1 00:00:00 2098'\n+26713 CRC                   EAE8515F (3941093727)\n+26717 Compressed Size       00001FF9 (8185)\n+2671B Uncompressed Size     00001FF9 (8185)\n+2671F Filename Length       0040 (64)\n+26721 Extra Length          0009 (9)\n+26723 Comment Length        0000 (0)\n+26725 Disk Start            0000 (0)\n+26727 Int File Attributes   0000 (0)\n+      [Bit 0]               0 'Binary Data'\n+26729 Ext File Attributes   00000000 (0)\n+2672D Local Header Offset   0000B440 (46144)\n+26731 Filename              'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX'\n+#\n+# WARNING: Offset 0x26731: Filename 'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX'\n+#          Zero length filename\n+#\n+26771 Extra ID #1           5455 (21589) 'Extended Timestamp [UT]'\n+26773   Length              0005 (5)\n+26775   Flags               01 (1) 'Modification'\n+26776   Modification Time   00000000 (0) 'Thu Jan  1 00:00:00 1970'\n+\n+2677A CENTRAL HEADER #27    02014B50 (33639248)\n+2677E Created Zip Spec      14 (20) '2.0'\n+2677F Created OS            00 (0) 'MS-DOS'\n+26780 Extract Zip Spec      14 (20) '2.0'\n+26781 Extract OS            00 (0) 'MS-DOS'\n+26782 General Purpose Flag  0008 (8)\n+      [Bit  3]              1 'Streamed'\n+26784 Compression Method    0000 (0) 'Stored'\n+26786 Modification Time     EC210000 (3961585664) 'Wed Jan  1 00:00:00 2098'\n+2678A CRC                   E202F321 (3791844129)\n+2678E Compressed Size       00001C58 (7256)\n+26792 Uncompressed Size     00001C58 (7256)\n+26796 Filename Length       003C (60)\n+26798 Extra Length          0009 (9)\n+2679A Comment Length        0000 (0)\n+2679C Disk Start            0000 (0)\n+2679E Int File Attributes   0000 (0)\n+      [Bit 0]               0 'Binary Data'\n+267A0 Ext File Attributes   00000000 (0)\n+267A4 Local Header Offset   0000D4B0 (54448)\n+267A8 Filename              'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX'\n+#\n+# WARNING: Offset 0x267A8: Filename 'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX'\n+#          Zero length filename\n+#\n+267E4 Extra ID #1           5455 (21589) 'Extended Timestamp [UT]'\n+267E6   Length              0005 (5)\n+267E8   Flags               01 (1) 'Modification'\n+267E9   Modification Time   00000000 (0) 'Thu Jan  1 00:00:00 1970'\n+\n+267ED CENTRAL HEADER #28    02014B50 (33639248)\n+267F1 Created Zip Spec      14 (20) '2.0'\n+267F2 Created OS            00 (0) 'MS-DOS'\n+267F3 Extract Zip Spec      14 (20) '2.0'\n+267F4 Extract OS            00 (0) 'MS-DOS'\n+267F5 General Purpose Flag  0008 (8)\n+      [Bit  3]              1 'Streamed'\n+267F7 Compression Method    0000 (0) 'Stored'\n+267F9 Modification Time     EC210000 (3961585664) 'Wed Jan  1 00:00:00 2098'\n+267FD CRC                   DBBCD787 (3686586247)\n+26801 Compressed Size       00002BDF (11231)\n+26805 Uncompressed Size     00002BDF (11231)\n+26809 Filename Length       0033 (51)\n+2680B Extra Length          0009 (9)\n+2680D Comment Length        0000 (0)\n+2680F Disk Start            0000 (0)\n+26811 Int File Attributes   0000 (0)\n+      [Bit 0]               0 'Binary Data'\n+26813 Ext File Attributes   00000000 (0)\n+26817 Local Header Offset   0000F17B (61819)\n+2681B Filename              'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX'\n+#\n+# WARNING: Offset 0x2681B: Filename 'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX'\n+#          Zero length filename\n+#\n+2684E Extra ID #1           5455 (21589) 'Extended Timestamp [UT]'\n+26850   Length              0005 (5)\n+26852   Flags               01 (1) 'Modification'\n+26853   Modification Time   00000000 (0) 'Thu Jan  1 00:00:00 1970'\n+\n+26857 CENTRAL HEADER #29    02014B50 (33639248)\n+2685B Created Zip Spec      14 (20) '2.0'\n+2685C Created OS            00 (0) 'MS-DOS'\n+2685D Extract Zip Spec      14 (20) '2.0'\n+2685E Extract OS            00 (0) 'MS-DOS'\n+2685F General Purpose Flag  0008 (8)\n+      [Bit  3]              1 'Streamed'\n+26861 Compression Method    0000 (0) 'Stored'\n+26863 Modification Time     EC210000 (3961585664) 'Wed Jan  1 00:00:00 2098'\n+26867 CRC                   E1297FD5 (3777593301)\n+2686B Compressed Size       00000A4E (2638)\n+2686F Uncompressed Size     00000A4E (2638)\n+26873 Filename Length       003A (58)\n+26875 Extra Length          0009 (9)\n+26877 Comment Length        0000 (0)\n+26879 Disk Start            0000 (0)\n+2687B Int File Attributes   0000 (0)\n+      [Bit 0]               0 'Binary Data'\n+2687D Ext File Attributes   00000000 (0)\n+26881 Local Header Offset   00011DC4 (73156)\n+26885 Filename              'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX'\n+#\n+# WARNING: Offset 0x26885: Filename 'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX'\n+#          Zero length filename\n+#\n+268BF Extra ID #1           5455 (21589) 'Extended Timestamp [UT]'\n+268C1   Length              0005 (5)\n+268C3   Flags               01 (1) 'Modification'\n+268C4   Modification Time   00000000 (0) 'Thu Jan  1 00:00:00 1970'\n+\n+268C8 CENTRAL HEADER #30    02014B50 (33639248)\n+268CC Created Zip Spec      14 (20) '2.0'\n+268CD Created OS            00 (0) 'MS-DOS'\n+268CE Extract Zip Spec      14 (20) '2.0'\n+268CF Extract OS            00 (0) 'MS-DOS'\n+268D0 General Purpose Flag  0008 (8)\n+      [Bit  3]              1 'Streamed'\n+268D2 Compression Method    0000 (0) 'Stored'\n+268D4 Modification Time     EC210000 (3961585664) 'Wed Jan  1 00:00:00 2098'\n+268D8 CRC                   CDBF443E (3451864126)\n+268DC Compressed Size       00000C74 (3188)\n+268E0 Uncompressed Size     00000C74 (3188)\n+268E4 Filename Length       0038 (56)\n+268E6 Extra Length          0009 (9)\n+268E8 Comment Length        0000 (0)\n+268EA Disk Start            0000 (0)\n+268EC Int File Attributes   0000 (0)\n+      [Bit 0]               0 'Binary Data'\n+268EE Ext File Attributes   00000000 (0)\n+268F2 Local Header Offset   00012883 (75907)\n+268F6 Filename              'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX'\n+#\n+# WARNING: Offset 0x268F6: Filename 'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX'\n+#          Zero length filename\n+#\n+2692E Extra ID #1           5455 (21589) 'Extended Timestamp [UT]'\n+26930   Length              0005 (5)\n+26932   Flags               01 (1) 'Modification'\n+26933   Modification Time   00000000 (0) 'Thu Jan  1 00:00:00 1970'\n+\n+26937 CENTRAL HEADER #31    02014B50 (33639248)\n+2693B Created Zip Spec      14 (20) '2.0'\n+2693C Created OS            00 (0) 'MS-DOS'\n+2693D Extract Zip Spec      14 (20) '2.0'\n+2693E Extract OS            00 (0) 'MS-DOS'\n+2693F General Purpose Flag  0008 (8)\n+      [Bit  3]              1 'Streamed'\n+26941 Compression Method    0000 (0) 'Stored'\n+26943 Modification Time     EC210000 (3961585664) 'Wed Jan  1 00:00:00 2098'\n+26947 CRC                   151E182C (354293804)\n+2694B Compressed Size       000005DD (1501)\n+2694F Uncompressed Size     000005DD (1501)\n+26953 Filename Length       0036 (54)\n+26955 Extra Length          0009 (9)\n+26957 Comment Length        0000 (0)\n+26959 Disk Start            0000 (0)\n+2695B Int File Attributes   0000 (0)\n+      [Bit 0]               0 'Binary Data'\n+2695D Ext File Attributes   00000000 (0)\n+26961 Local Header Offset   00013566 (79206)\n+26965 Filename              'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX'\n+#\n+# WARNING: Offset 0x26965: Filename 'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX'\n+#          Zero length filename\n+#\n+2699B Extra ID #1           5455 (21589) 'Extended Timestamp [UT]'\n+2699D   Length              0005 (5)\n+2699F   Flags               01 (1) 'Modification'\n+269A0   Modification Time   00000000 (0) 'Thu Jan  1 00:00:00 1970'\n+\n+269A4 CENTRAL HEADER #32    02014B50 (33639248)\n+269A8 Created Zip Spec      14 (20) '2.0'\n+269A9 Created OS            00 (0) 'MS-DOS'\n+269AA Extract Zip Spec      14 (20) '2.0'\n+269AB Extract OS            00 (0) 'MS-DOS'\n+269AC General Purpose Flag  0008 (8)\n+      [Bit  3]              1 'Streamed'\n+269AE Compression Method    0000 (0) 'Stored'\n+269B0 Modification Time     EC210000 (3961585664) 'Wed Jan  1 00:00:00 2098'\n+269B4 CRC                   39CBA339 (969646905)\n+269B8 Compressed Size       00002090 (8336)\n+269BC Uncompressed Size     00002090 (8336)\n+269C0 Filename Length       0035 (53)\n+269C2 Extra Length          0009 (9)\n+269C4 Comment Length        0000 (0)\n+269C6 Disk Start            0000 (0)\n+269C8 Int File Attributes   0000 (0)\n+      [Bit 0]               0 'Binary Data'\n+269CA Ext File Attributes   00000000 (0)\n+269CE Local Header Offset   00013BB0 (80816)\n+269D2 Filename              'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX'\n+#\n+# WARNING: Offset 0x269D2: Filename 'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX'\n+#          Zero length filename\n+#\n+26A07 Extra ID #1           5455 (21589) 'Extended Timestamp [UT]'\n+26A09   Length              0005 (5)\n+26A0B   Flags               01 (1) 'Modification'\n+26A0C   Modification Time   00000000 (0) 'Thu Jan  1 00:00:00 1970'\n+\n+26A10 CENTRAL HEADER #33    02014B50 (33639248)\n+26A14 Created Zip Spec      14 (20) '2.0'\n+26A15 Created OS            00 (0) 'MS-DOS'\n+26A16 Extract Zip Spec      14 (20) '2.0'\n+26A17 Extract OS            00 (0) 'MS-DOS'\n+26A18 General Purpose Flag  0008 (8)\n+      [Bit  3]              1 'Streamed'\n+26A1A Compression Method    0000 (0) 'Stored'\n+26A1C Modification Time     EC210000 (3961585664) 'Wed Jan  1 00:00:00 2098'\n+26A20 CRC                   07C16F02 (130117378)\n+26A24 Compressed Size       00006DE5 (28133)\n+26A28 Uncompressed Size     00006DE5 (28133)\n+26A2C Filename Length       0036 (54)\n+26A2E Extra Length          0009 (9)\n+26A30 Comment Length        0000 (0)\n+26A32 Disk Start            0000 (0)\n+26A34 Int File Attributes   0000 (0)\n+      [Bit 0]               0 'Binary Data'\n+26A36 Ext File Attributes   00000000 (0)\n+26A3A Local Header Offset   00015CAC (89260)\n+26A3E Filename              'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX'\n+#\n+# WARNING: Offset 0x26A3E: Filename 'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX'\n+#          Zero length filename\n+#\n+26A74 Extra ID #1           5455 (21589) 'Extended Timestamp [UT]'\n+26A76   Length              0005 (5)\n+26A78   Flags               01 (1) 'Modification'\n+26A79   Modification Time   00000000 (0) 'Thu Jan  1 00:00:00 1970'\n+\n+26A7D CENTRAL HEADER #34    02014B50 (33639248)\n+26A81 Created Zip Spec      14 (20) '2.0'\n+26A82 Created OS            00 (0) 'MS-DOS'\n+26A83 Extract Zip Spec      14 (20) '2.0'\n+26A84 Extract OS            00 (0) 'MS-DOS'\n+26A85 General Purpose Flag  0008 (8)\n+      [Bit  3]              1 'Streamed'\n+26A87 Compression Method    0000 (0) 'Stored'\n+26A89 Modification Time     EC210000 (3961585664) 'Wed Jan  1 00:00:00 2098'\n+26A8D CRC                   DA119291 (3658584721)\n+26A91 Compressed Size       00000752 (1874)\n+26A95 Uncompressed Size     00000752 (1874)\n+26A99 Filename Length       003C (60)\n+26A9B Extra Length          0009 (9)\n+26A9D Comment Length        0000 (0)\n+26A9F Disk Start            0000 (0)\n+26AA1 Int File Attributes   0000 (0)\n+      [Bit 0]               0 'Binary Data'\n+26AA3 Ext File Attributes   00000000 (0)\n+26AA7 Local Header Offset   0001CAFE (117502)\n+26AAB Filename              'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX'\n+#\n+# WARNING: Offset 0x26AAB: Filename 'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX'\n+#          Zero length filename\n+#\n+26AE7 Extra ID #1           5455 (21589) 'Extended Timestamp [UT]'\n+26AE9   Length              0005 (5)\n+26AEB   Flags               01 (1) 'Modification'\n+26AEC   Modification Time   00000000 (0) 'Thu Jan  1 00:00:00 1970'\n+\n+26AF0 CENTRAL HEADER #35    02014B50 (33639248)\n+26AF4 Created Zip Spec      14 (20) '2.0'\n+26AF5 Created OS            00 (0) 'MS-DOS'\n+26AF6 Extract Zip Spec      14 (20) '2.0'\n+26AF7 Extract OS            00 (0) 'MS-DOS'\n+26AF8 General Purpose Flag  0008 (8)\n+      [Bit  3]              1 'Streamed'\n+26AFA Compression Method    0000 (0) 'Stored'\n+26AFC Modification Time     EC210000 (3961585664) 'Wed Jan  1 00:00:00 2098'\n+26B00 CRC                   0574FE58 (91553368)\n+26B04 Compressed Size       000020D9 (8409)\n+26B08 Uncompressed Size     000020D9 (8409)\n+26B0C Filename Length       0042 (66)\n+26B0E Extra Length          0009 (9)\n+26B10 Comment Length        0000 (0)\n+26B12 Disk Start            0000 (0)\n+26B14 Int File Attributes   0000 (0)\n+      [Bit 0]               0 'Binary Data'\n+26B16 Ext File Attributes   00000000 (0)\n+26B1A Local Header Offset   0001D2C3 (119491)\n+26B1E Filename              'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX'\n+#\n+# WARNING: Offset 0x26B1E: Filename 'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX'\n+#          Zero length filename\n+#\n+26B60 Extra ID #1           5455 (21589) 'Extended Timestamp [UT]'\n+26B62   Length              0005 (5)\n+26B64   Flags               01 (1) 'Modification'\n+26B65   Modification Time   00000000 (0) 'Thu Jan  1 00:00:00 1970'\n+\n+26B69 CENTRAL HEADER #36    02014B50 (33639248)\n+26B6D Created Zip Spec      14 (20) '2.0'\n+26B6E Created OS            00 (0) 'MS-DOS'\n+26B6F Extract Zip Spec      14 (20) '2.0'\n+26B70 Extract OS            00 (0) 'MS-DOS'\n+26B71 General Purpose Flag  0008 (8)\n+      [Bit  3]              1 'Streamed'\n+26B73 Compression Method    0000 (0) 'Stored'\n+26B75 Modification Time     EC210000 (3961585664) 'Wed Jan  1 00:00:00 2098'\n+26B79 CRC                   B5644E62 (3043249762)\n+26B7D Compressed Size       0000189A (6298)\n+26B81 Uncompressed Size     0000189A (6298)\n+26B85 Filename Length       0045 (69)\n+26B87 Extra Length          0009 (9)\n+26B89 Comment Length        0000 (0)\n+26B8B Disk Start            0000 (0)\n+26B8D Int File Attributes   0000 (0)\n+      [Bit 0]               0 'Binary Data'\n+26B8F Ext File Attributes   00000000 (0)\n+26B93 Local Header Offset   0001F415 (128021)\n+26B97 Filename              'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX'\n+#\n+# WARNING: Offset 0x26B97: Filename 'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX'\n+#          Zero length filename\n+#\n+26BDC Extra ID #1           5455 (21589) 'Extended Timestamp [UT]'\n+26BDE   Length              0005 (5)\n+26BE0   Flags               01 (1) 'Modification'\n+26BE1   Modification Time   00000000 (0) 'Thu Jan  1 00:00:00 1970'\n+\n+26BE5 CENTRAL HEADER #37    02014B50 (33639248)\n+26BE9 Created Zip Spec      14 (20) '2.0'\n+26BEA Created OS            00 (0) 'MS-DOS'\n+26BEB Extract Zip Spec      14 (20) '2.0'\n+26BEC Extract OS            00 (0) 'MS-DOS'\n+26BED General Purpose Flag  0000 (0)\n+26BEF Compression Method    0000 (0) 'Stored'\n+26BF1 Modification Time     EC210000 (3961585664) 'Wed Jan  1 00:00:00 2098'\n+26BF5 CRC                   00000000 (0)\n+26BF9 Compressed Size       00000000 (0)\n+26BFD Uncompressed Size     00000000 (0)\n+26C01 Filename Length       002B (43)\n+26C03 Extra Length          0009 (9)\n+26C05 Comment Length        0000 (0)\n+26C07 Disk Start            0000 (0)\n+26C09 Int File Attributes   0000 (0)\n+      [Bit 0]               0 'Binary Data'\n+26C0B Ext File Attributes   00000000 (0)\n+26C0F Local Header Offset   00020D2B (134443)\n+26C13 Filename              'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX'\n+#\n+# WARNING: Offset 0x26C13: Filename 'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX'\n+#          Zero length filename\n+#\n+26C3E Extra ID #1           5455 (21589) 'Extended Timestamp [UT]'\n+26C40   Length              0005 (5)\n+26C42   Flags               01 (1) 'Modification'\n+26C43   Modification Time   00000000 (0) 'Thu Jan  1 00:00:00 1970'\n+\n+26C47 CENTRAL HEADER #38    02014B50 (33639248)\n+26C4B Created Zip Spec      14 (20) '2.0'\n+26C4C Created OS            00 (0) 'MS-DOS'\n+26C4D Extract Zip Spec      14 (20) '2.0'\n+26C4E Extract OS            00 (0) 'MS-DOS'\n+26C4F General Purpose Flag  0008 (8)\n+      [Bit  3]              1 'Streamed'\n+26C51 Compression Method    0000 (0) 'Stored'\n+26C53 Modification Time     EC210000 (3961585664) 'Wed Jan  1 00:00:00 2098'\n+26C57 CRC                   45086F19 (1158180633)\n+26C5B Compressed Size       000022F3 (8947)\n+26C5F Uncompressed Size     000022F3 (8947)\n+26C63 Filename Length       003C (60)\n+26C65 Extra Length          0009 (9)\n+26C67 Comment Length        0000 (0)\n+26C69 Disk Start            0000 (0)\n+26C6B Int File Attributes   0000 (0)\n+      [Bit 0]               0 'Binary Data'\n+26C6D Ext File Attributes   00000000 (0)\n+26C71 Local Header Offset   00020D7D (134525)\n+26C75 Filename              'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX'\n+#\n+# WARNING: Offset 0x26C75: Filename 'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX'\n+#          Zero length filename\n+#\n+26CB1 Extra ID #1           5455 (21589) 'Extended Timestamp [UT]'\n+26CB3   Length              0005 (5)\n+26CB5   Flags               01 (1) 'Modification'\n+26CB6   Modification Time   00000000 (0) 'Thu Jan  1 00:00:00 1970'\n+\n+26CBA CENTRAL HEADER #39    02014B50 (33639248)\n+26CBE Created Zip Spec      14 (20) '2.0'\n+26CBF Created OS            00 (0) 'MS-DOS'\n+26CC0 Extract Zip Spec      14 (20) '2.0'\n+26CC1 Extract OS            00 (0) 'MS-DOS'\n+26CC2 General Purpose Flag  0008 (8)\n+      [Bit  3]              1 'Streamed'\n+26CC4 Compression Method    0000 (0) 'Stored'\n+26CC6 Modification Time     EC210000 (3961585664) 'Wed Jan  1 00:00:00 2098'\n+26CCA CRC                   57E4B8CF (1474607311)\n+26CCE Compressed Size       000016C7 (5831)\n+26CD2 Uncompressed Size     000016C7 (5831)\n+26CD6 Filename Length       003B (59)\n+26CD8 Extra Length          0009 (9)\n+26CDA Comment Length        0000 (0)\n+26CDC Disk Start            0000 (0)\n+26CDE Int File Attributes   0000 (0)\n+      [Bit 0]               0 'Binary Data'\n+26CE0 Ext File Attributes   00000000 (0)\n+26CE4 Local Header Offset   000230E3 (143587)\n+26CE8 Filename              'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX'\n+#\n+# WARNING: Offset 0x26CE8: Filename 'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX'\n+#          Zero length filename\n+#\n+26D23 Extra ID #1           5455 (21589) 'Extended Timestamp [UT]'\n+26D25   Length              0005 (5)\n+26D27   Flags               01 (1) 'Modification'\n+26D28   Modification Time   00000000 (0) 'Thu Jan  1 00:00:00 1970'\n+\n+26D2C CENTRAL HEADER #40    02014B50 (33639248)\n+26D30 Created Zip Spec      14 (20) '2.0'\n+26D31 Created OS            00 (0) 'MS-DOS'\n+26D32 Extract Zip Spec      14 (20) '2.0'\n+26D33 Extract OS            00 (0) 'MS-DOS'\n+26D34 General Purpose Flag  0000 (0)\n+26D36 Compression Method    0000 (0) 'Stored'\n+26D38 Modification Time     EC210000 (3961585664) 'Wed Jan  1 00:00:00 2098'\n+26D3C CRC                   00000000 (0)\n+26D40 Compressed Size       00000000 (0)\n+26D44 Uncompressed Size     00000000 (0)\n+26D48 Filename Length       002B (43)\n+26D4A Extra Length          0009 (9)\n+26D4C Comment Length        0000 (0)\n+26D4E Disk Start            0000 (0)\n+26D50 Int File Attributes   0000 (0)\n+      [Bit 0]               0 'Binary Data'\n+26D52 Ext File Attributes   00000000 (0)\n+26D56 Local Header Offset   0002481C (149532)\n+26D5A Filename              'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX'\n+#\n+# WARNING: Offset 0x26D5A: Filename 'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX'\n+#          Zero length filename\n+#\n+26D85 Extra ID #1           5455 (21589) 'Extended Timestamp [UT]'\n+26D87   Length              0005 (5)\n+26D89   Flags               01 (1) 'Modification'\n+26D8A   Modification Time   00000000 (0) 'Thu Jan  1 00:00:00 1970'\n+\n+26D8E CENTRAL HEADER #41    02014B50 (33639248)\n+26D92 Created Zip Spec      14 (20) '2.0'\n+26D93 Created OS            00 (0) 'MS-DOS'\n+26D94 Extract Zip Spec      14 (20) '2.0'\n+26D95 Extract OS            00 (0) 'MS-DOS'\n+26D96 General Purpose Flag  0008 (8)\n+      [Bit  3]              1 'Streamed'\n+26D98 Compression Method    0000 (0) 'Stored'\n+26D9A Modification Time     EC210000 (3961585664) 'Wed Jan  1 00:00:00 2098'\n+26D9E CRC                   A77D588D (2810009741)\n+26DA2 Compressed Size       00000921 (2337)\n+26DA6 Uncompressed Size     00000921 (2337)\n+26DAA Filename Length       0043 (67)\n+26DAC Extra Length          0009 (9)\n+26DAE Comment Length        0000 (0)\n+26DB0 Disk Start            0000 (0)\n+26DB2 Int File Attributes   0000 (0)\n+      [Bit 0]               0 'Binary Data'\n+26DB4 Ext File Attributes   00000000 (0)\n+26DB8 Local Header Offset   0002486E (149614)\n+26DBC Filename              'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX'\n+#\n+# WARNING: Offset 0x26DBC: Filename 'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX'\n+#          Zero length filename\n+#\n+26DFF Extra ID #1           5455 (21589) 'Extended Timestamp [UT]'\n+26E01   Length              0005 (5)\n+26E03   Flags               01 (1) 'Modification'\n+26E04   Modification Time   00000000 (0) 'Thu Jan  1 00:00:00 1970'\n+\n+26E08 CENTRAL HEADER #42    02014B50 (33639248)\n+26E0C Created Zip Spec      14 (20) '2.0'\n+26E0D Created OS            00 (0) 'MS-DOS'\n+26E0E Extract Zip Spec      14 (20) '2.0'\n+26E0F Extract OS            00 (0) 'MS-DOS'\n+26E10 General Purpose Flag  0008 (8)\n+      [Bit  3]              1 'Streamed'\n+26E12 Compression Method    0000 (0) 'Stored'\n+26E14 Modification Time     EC210000 (3961585664) 'Wed Jan  1 00:00:00 2098'\n+26E18 CRC                   DF443A2F (3745790511)\n+26E1C Compressed Size       00000BC9 (3017)\n+26E20 Uncompressed Size     00000BC9 (3017)\n+26E24 Filename Length       0047 (71)\n+26E26 Extra Length          0009 (9)\n+26E28 Comment Length        0000 (0)\n+26E2A Disk Start            0000 (0)\n+26E2C Int File Attributes   0000 (0)\n+      [Bit 0]               0 'Binary Data'\n+26E2E Ext File Attributes   00000000 (0)\n+26E32 Local Header Offset   00025209 (152073)\n+26E36 Filename              'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX'\n+#\n+# WARNING: Offset 0x26E36: Filename 'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX'\n+#          Zero length filename\n+#\n+26E7D Extra ID #1           5455 (21589) 'Extended Timestamp [UT]'\n+26E7F   Length              0005 (5)\n+26E81   Flags               01 (1) 'Modification'\n+26E82   Modification Time   00000000 (0) 'Thu Jan  1 00:00:00 1970'\n+\n+26E86 END CENTRAL HEADER    06054B50 (101010256)\n+26E8A Number of this disk   0000 (0)\n+26E8C Central Dir Disk no   0000 (0)\n+26E8E Entries in this disk  002A (42)\n+26E90 Total Entries         002A (42)\n+26E92 Size of Central Dir   00001036 (4150)\n+26E96 Offset to Central Dir 00025E50 (155216)\n+26E9A Comment Length        0000 (0)\n #\n # Warning Count: 84\n #\n # Done\n"}, {"source1": "META-INF/maven/org.apache.dubbo/dubbo-rpc-dubbo/pom.xml", "source2": "META-INF/maven/org.apache.dubbo/dubbo-rpc-dubbo/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,252 +1,245 @@\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 7063 3c2f 6172 7469 6661 6374  bo-rpc</artifact\n-000004a0: 4964 3e0d 0a20 2020 203c 7665 7273 696f  Id>..    <versio\n-000004b0: 6e3e 322e 372e 3130 3c2f 7665 7273 696f  n>2.7.10</versio\n-000004c0: 6e3e 0d0a 2020 3c2f 7061 7265 6e74 3e0d  n>..  </parent>.\n-000004d0: 0a20 203c 6772 6f75 7049 643e 6f72 672e  .  <groupId>org.\n-000004e0: 6170 6163 6865 2e64 7562 626f 3c2f 6772  apache.dubbo</gr\n-000004f0: 6f75 7049 643e 0d0a 2020 3c61 7274 6966  oupId>..  <artif\n-00000500: 6163 7449 643e 6475 6262 6f2d 7270 632d  actId>dubbo-rpc-\n-00000510: 6475 6262 6f3c 2f61 7274 6966 6163 7449  dubbo</artifactI\n-00000520: 643e 0d0a 2020 3c76 6572 7369 6f6e 3e32  d>..  <version>2\n-00000530: 2e37 2e31 303c 2f76 6572 7369 6f6e 3e0d  .7.10</version>.\n-00000540: 0a20 203c 6e61 6d65 3e24 7b70 726f 6a65  .  <name>${proje\n-00000550: 6374 2e61 7274 6966 6163 7449 647d 3c2f  ct.artifactId}</\n-00000560: 6e61 6d65 3e0d 0a20 203c 6465 7363 7269  name>..  <descri\n-00000570: 7074 696f 6e3e 5468 6520 6465 6661 756c  ption>The defaul\n-00000580: 7420 7270 6320 6d6f 6475 6c65 206f 6620  t rpc module of \n-00000590: 6475 6262 6f20 7072 6f6a 6563 743c 2f64  dubbo project</d\n-000005a0: 6573 6372 6970 7469 6f6e 3e0d 0a20 203c  escription>..  <\n-000005b0: 6c69 6365 6e73 6573 3e0d 0a20 2020 203c  licenses>..    <\n-000005c0: 6c69 6365 6e73 653e 0d0a 2020 2020 2020  license>..      \n-000005d0: 3c6e 616d 653e 4170 6163 6865 204c 6963  <name>Apache Lic\n-000005e0: 656e 7365 2c20 5665 7273 696f 6e20 322e  ense, Version 2.\n-000005f0: 303c 2f6e 616d 653e 0d0a 2020 2020 2020  0</name>..      \n-00000600: 3c75 726c 3e68 7474 703a 2f2f 7777 772e  <url>http://www.\n-00000610: 6170 6163 6865 2e6f 7267 2f6c 6963 656e  apache.org/licen\n-00000620: 7365 732f 4c49 4345 4e53 452d 322e 303c  ses/LICENSE-2.0<\n-00000630: 2f75 726c 3e0d 0a20 2020 2020 203c 6469  /url>..      <di\n-00000640: 7374 7269 6275 7469 6f6e 3e72 6570 6f3c  stribution>repo<\n-00000650: 2f64 6973 7472 6962 7574 696f 6e3e 0d0a  /distribution>..\n-00000660: 2020 2020 3c2f 6c69 6365 6e73 653e 0d0a      </license>..\n-00000670: 2020 3c2f 6c69 6365 6e73 6573 3e0d 0a20    </licenses>.. \n-00000680: 203c 7072 6f70 6572 7469 6573 3e0d 0a20   <properties>.. \n-00000690: 2020 203c 736b 6970 5f6d 6176 656e 5f64     <skip_maven_d\n-000006a0: 6570 6c6f 793e 6661 6c73 653c 2f73 6b69  eploy>false</ski\n-000006b0: 705f 6d61 7665 6e5f 6465 706c 6f79 3e0d  p_maven_deploy>.\n-000006c0: 0a20 203c 2f70 726f 7065 7274 6965 733e  .  </properties>\n-000006d0: 0d0a 2020 3c64 6570 656e 6465 6e63 6965  ..  <dependencie\n-000006e0: 733e 0d0a 2020 2020 3c64 6570 656e 6465  s>..    <depende\n-000006f0: 6e63 793e 0d0a 2020 2020 2020 3c67 726f  ncy>..      <gro\n-00000700: 7570 4964 3e6f 7267 2e61 7061 6368 652e  upId>org.apache.\n-00000710: 6475 6262 6f3c 2f67 726f 7570 4964 3e0d  dubbo</groupId>.\n-00000720: 0a20 2020 2020 203c 6172 7469 6661 6374  .      <artifact\n-00000730: 4964 3e64 7562 626f 2d72 7063 2d61 7069  Id>dubbo-rpc-api\n-00000740: 3c2f 6172 7469 6661 6374 4964 3e0d 0a20  </artifactId>.. \n-00000750: 2020 2020 203c 7665 7273 696f 6e3e 247b       <version>${\n-00000760: 7072 6f6a 6563 742e 7061 7265 6e74 2e76  project.parent.v\n-00000770: 6572 7369 6f6e 7d3c 2f76 6572 7369 6f6e  ersion}</version\n-00000780: 3e0d 0a20 2020 203c 2f64 6570 656e 6465  >..    </depende\n-00000790: 6e63 793e 0d0a 2020 2020 3c64 6570 656e  ncy>..    <depen\n-000007a0: 6465 6e63 793e 0d0a 2020 2020 2020 3c67  dency>..      <g\n-000007b0: 726f 7570 4964 3e6f 7267 2e61 7061 6368  roupId>org.apach\n-000007c0: 652e 6475 6262 6f3c 2f67 726f 7570 4964  e.dubbo</groupId\n-000007d0: 3e0d 0a20 2020 2020 203c 6172 7469 6661  >..      <artifa\n-000007e0: 6374 4964 3e64 7562 626f 2d72 656d 6f74  ctId>dubbo-remot\n-000007f0: 696e 672d 6170 693c 2f61 7274 6966 6163  ing-api</artifac\n-00000800: 7449 643e 0d0a 2020 2020 2020 3c76 6572  tId>..      <ver\n-00000810: 7369 6f6e 3e24 7b70 726f 6a65 6374 2e70  sion>${project.p\n-00000820: 6172 656e 742e 7665 7273 696f 6e7d 3c2f  arent.version}</\n-00000830: 7665 7273 696f 6e3e 0d0a 2020 2020 3c2f  version>..    </\n-00000840: 6465 7065 6e64 656e 6379 3e0d 0a20 2020  dependency>..   \n-00000850: 203c 6465 7065 6e64 656e 6379 3e0d 0a20   <dependency>.. \n-00000860: 2020 2020 203c 6772 6f75 7049 643e 6f72       <groupId>or\n-00000870: 672e 6170 6163 6865 2e64 7562 626f 3c2f  g.apache.dubbo</\n-00000880: 6772 6f75 7049 643e 0d0a 2020 2020 2020  groupId>..      \n-00000890: 3c61 7274 6966 6163 7449 643e 6475 6262  <artifactId>dubb\n-000008a0: 6f2d 636c 7573 7465 723c 2f61 7274 6966  o-cluster</artif\n-000008b0: 6163 7449 643e 0d0a 2020 2020 2020 3c76  actId>..      <v\n-000008c0: 6572 7369 6f6e 3e24 7b70 726f 6a65 6374  ersion>${project\n-000008d0: 2e70 6172 656e 742e 7665 7273 696f 6e7d  .parent.version}\n-000008e0: 3c2f 7665 7273 696f 6e3e 0d0a 2020 2020  </version>..    \n-000008f0: 3c2f 6465 7065 6e64 656e 6379 3e0d 0a20  </dependency>.. \n-00000900: 2020 203c 6465 7065 6e64 656e 6379 3e0d     <dependency>.\n-00000910: 0a20 2020 2020 203c 6772 6f75 7049 643e  .      <groupId>\n-00000920: 6f72 672e 6170 6163 6865 2e64 7562 626f  org.apache.dubbo\n-00000930: 3c2f 6772 6f75 7049 643e 0d0a 2020 2020  </groupId>..    \n-00000940: 2020 3c61 7274 6966 6163 7449 643e 6475    <artifactId>du\n-00000950: 6262 6f2d 7265 6d6f 7469 6e67 2d6e 6574  bbo-remoting-net\n-00000960: 7479 343c 2f61 7274 6966 6163 7449 643e  ty4</artifactId>\n-00000970: 0d0a 2020 2020 2020 3c76 6572 7369 6f6e  ..      <version\n-00000980: 3e24 7b70 726f 6a65 6374 2e70 6172 656e  >${project.paren\n-00000990: 742e 7665 7273 696f 6e7d 3c2f 7665 7273  t.version}</vers\n-000009a0: 696f 6e3e 0d0a 2020 2020 2020 3c73 636f  ion>..      <sco\n-000009b0: 7065 3e74 6573 743c 2f73 636f 7065 3e0d  pe>test</scope>.\n-000009c0: 0a20 2020 203c 2f64 6570 656e 6465 6e63  .    </dependenc\n-000009d0: 793e 0d0a 2020 2020 3c64 6570 656e 6465  y>..    <depende\n-000009e0: 6e63 793e 0d0a 2020 2020 2020 3c67 726f  ncy>..      <gro\n-000009f0: 7570 4964 3e6f 7267 2e61 7061 6368 652e  upId>org.apache.\n-00000a00: 6475 6262 6f3c 2f67 726f 7570 4964 3e0d  dubbo</groupId>.\n-00000a10: 0a20 2020 2020 203c 6172 7469 6661 6374  .      <artifact\n-00000a20: 4964 3e64 7562 626f 2d72 656d 6f74 696e  Id>dubbo-remotin\n-00000a30: 672d 6d69 6e61 3c2f 6172 7469 6661 6374  g-mina</artifact\n-00000a40: 4964 3e0d 0a20 2020 2020 203c 7665 7273  Id>..      <vers\n-00000a50: 696f 6e3e 247b 7072 6f6a 6563 742e 7061  ion>${project.pa\n-00000a60: 7265 6e74 2e76 6572 7369 6f6e 7d3c 2f76  rent.version}</v\n-00000a70: 6572 7369 6f6e 3e0d 0a20 2020 2020 203c  ersion>..      <\n-00000a80: 7363 6f70 653e 7465 7374 3c2f 7363 6f70  scope>test</scop\n-00000a90: 653e 0d0a 2020 2020 3c2f 6465 7065 6e64  e>..    </depend\n-00000aa0: 656e 6379 3e0d 0a20 2020 203c 6465 7065  ency>..    <depe\n-00000ab0: 6e64 656e 6379 3e0d 0a20 2020 2020 203c  ndency>..      <\n-00000ac0: 6772 6f75 7049 643e 696f 2e6e 6574 7479  groupId>io.netty\n-00000ad0: 3c2f 6772 6f75 7049 643e 0d0a 2020 2020  </groupId>..    \n-00000ae0: 2020 3c61 7274 6966 6163 7449 643e 6e65    <artifactId>ne\n-00000af0: 7474 792d 616c 6c3c 2f61 7274 6966 6163  tty-all</artifac\n-00000b00: 7449 643e 0d0a 2020 2020 2020 3c73 636f  tId>..      <sco\n-00000b10: 7065 3e74 6573 743c 2f73 636f 7065 3e0d  pe>test</scope>.\n-00000b20: 0a20 2020 203c 2f64 6570 656e 6465 6e63  .    </dependenc\n-00000b30: 793e 0d0a 2020 2020 3c64 6570 656e 6465  y>..    <depende\n-00000b40: 6e63 793e 0d0a 2020 2020 2020 3c67 726f  ncy>..      <gro\n-00000b50: 7570 4964 3e6f 7267 2e61 7061 6368 652e  upId>org.apache.\n-00000b60: 6475 6262 6f3c 2f67 726f 7570 4964 3e0d  dubbo</groupId>.\n-00000b70: 0a20 2020 2020 203c 6172 7469 6661 6374  .      <artifact\n-00000b80: 4964 3e64 7562 626f 2d73 6572 6961 6c69  Id>dubbo-seriali\n-00000b90: 7a61 7469 6f6e 2d68 6573 7369 616e 323c  zation-hessian2<\n-00000ba0: 2f61 7274 6966 6163 7449 643e 0d0a 2020  /artifactId>..  \n-00000bb0: 2020 2020 3c76 6572 7369 6f6e 3e24 7b70      <version>${p\n-00000bc0: 726f 6a65 6374 2e70 6172 656e 742e 7665  roject.parent.ve\n-00000bd0: 7273 696f 6e7d 3c2f 7665 7273 696f 6e3e  rsion}</version>\n-00000be0: 0d0a 2020 2020 2020 3c73 636f 7065 3e74  ..      <scope>t\n-00000bf0: 6573 743c 2f73 636f 7065 3e0d 0a20 2020  est</scope>..   \n-00000c00: 203c 2f64 6570 656e 6465 6e63 793e 0d0a   </dependency>..\n-00000c10: 2020 2020 3c64 6570 656e 6465 6e63 793e      <dependency>\n-00000c20: 0d0a 2020 2020 2020 3c67 726f 7570 4964  ..      <groupId\n-00000c30: 3e6f 7267 2e61 7061 6368 652e 6475 6262  >org.apache.dubb\n-00000c40: 6f3c 2f67 726f 7570 4964 3e0d 0a20 2020  o</groupId>..   \n-00000c50: 2020 203c 6172 7469 6661 6374 4964 3e64     <artifactId>d\n-00000c60: 7562 626f 2d73 6572 6961 6c69 7a61 7469  ubbo-serializati\n-00000c70: 6f6e 2d6a 646b 3c2f 6172 7469 6661 6374  on-jdk</artifact\n-00000c80: 4964 3e0d 0a20 2020 2020 203c 7665 7273  Id>..      <vers\n-00000c90: 696f 6e3e 247b 7072 6f6a 6563 742e 7061  ion>${project.pa\n-00000ca0: 7265 6e74 2e76 6572 7369 6f6e 7d3c 2f76  rent.version}</v\n-00000cb0: 6572 7369 6f6e 3e0d 0a20 2020 2020 203c  ersion>..      <\n-00000cc0: 7363 6f70 653e 7465 7374 3c2f 7363 6f70  scope>test</scop\n-00000cd0: 653e 0d0a 2020 2020 3c2f 6465 7065 6e64  e>..    </depend\n-00000ce0: 656e 6379 3e0d 0a20 2020 203c 6465 7065  ency>..    <depe\n-00000cf0: 6e64 656e 6379 3e0d 0a20 2020 2020 203c  ndency>..      <\n-00000d00: 6772 6f75 7049 643e 6a61 7661 782e 7661  groupId>javax.va\n-00000d10: 6c69 6461 7469 6f6e 3c2f 6772 6f75 7049  lidation</groupI\n-00000d20: 643e 0d0a 2020 2020 2020 3c61 7274 6966  d>..      <artif\n-00000d30: 6163 7449 643e 7661 6c69 6461 7469 6f6e  actId>validation\n-00000d40: 2d61 7069 3c2f 6172 7469 6661 6374 4964  -api</artifactId\n-00000d50: 3e0d 0a20 2020 2020 203c 7363 6f70 653e  >..      <scope>\n-00000d60: 7465 7374 3c2f 7363 6f70 653e 0d0a 2020  test</scope>..  \n-00000d70: 2020 3c2f 6465 7065 6e64 656e 6379 3e0d    </dependency>.\n-00000d80: 0a20 2020 203c 6465 7065 6e64 656e 6379  .    <dependency\n-00000d90: 3e0d 0a20 2020 2020 203c 6772 6f75 7049  >..      <groupI\n-00000da0: 643e 6f72 672e 6869 6265 726e 6174 653c  d>org.hibernate<\n-00000db0: 2f67 726f 7570 4964 3e0d 0a20 2020 2020  /groupId>..     \n-00000dc0: 203c 6172 7469 6661 6374 4964 3e68 6962   <artifactId>hib\n-00000dd0: 6572 6e61 7465 2d76 616c 6964 6174 6f72  ernate-validator\n-00000de0: 3c2f 6172 7469 6661 6374 4964 3e0d 0a20  </artifactId>.. \n-00000df0: 2020 2020 203c 7363 6f70 653e 7465 7374       <scope>test\n-00000e00: 3c2f 7363 6f70 653e 0d0a 2020 2020 3c2f  </scope>..    </\n-00000e10: 6465 7065 6e64 656e 6379 3e0d 0a20 2020  dependency>..   \n-00000e20: 203c 6465 7065 6e64 656e 6379 3e0d 0a20   <dependency>.. \n-00000e30: 2020 2020 203c 6772 6f75 7049 643e 6f72       <groupId>or\n-00000e40: 672e 676c 6173 7366 6973 683c 2f67 726f  g.glassfish</gro\n-00000e50: 7570 4964 3e0d 0a20 2020 2020 203c 6172  upId>..      <ar\n-00000e60: 7469 6661 6374 4964 3e6a 6176 6178 2e65  tifactId>javax.e\n-00000e70: 6c3c 2f61 7274 6966 6163 7449 643e 0d0a  l</artifactId>..\n-00000e80: 2020 2020 2020 3c73 636f 7065 3e74 6573        <scope>tes\n-00000e90: 743c 2f73 636f 7065 3e0d 0a20 2020 203c  t</scope>..    <\n-00000ea0: 2f64 6570 656e 6465 6e63 793e 0d0a 2020  /dependency>..  \n-00000eb0: 3c2f 6465 7065 6e64 656e 6369 6573 3e0d  </dependencies>.\n-00000ec0: 0a20 203c 6275 696c 643e 0d0a 2020 2020  .  <build>..    \n-00000ed0: 3c70 6c75 6769 6e73 3e0d 0a20 2020 2020  <plugins>..     \n-00000ee0: 203c 706c 7567 696e 3e0d 0a20 2020 2020   <plugin>..     \n-00000ef0: 2020 203c 6172 7469 6661 6374 4964 3e6d     <artifactId>m\n-00000f00: 6176 656e 2d73 7572 6566 6972 652d 706c  aven-surefire-pl\n-00000f10: 7567 696e 3c2f 6172 7469 6661 6374 4964  ugin</artifactId\n-00000f20: 3e0d 0a20 2020 2020 2020 203c 636f 6e66  >..        <conf\n-00000f30: 6967 7572 6174 696f 6e3e 0d0a 2020 2020  iguration>..    \n-00000f40: 2020 2020 2020 3c72 756e 4f72 6465 723e        <runOrder>\n-00000f50: 616c 7068 6162 6574 6963 616c 3c2f 7275  alphabetical</ru\n-00000f60: 6e4f 7264 6572 3e0d 0a20 2020 2020 2020  nOrder>..       \n-00000f70: 203c 2f63 6f6e 6669 6775 7261 7469 6f6e   </configuration\n-00000f80: 3e0d 0a20 2020 2020 203c 2f70 6c75 6769  >..      </plugi\n-00000f90: 6e3e 0d0a 2020 2020 3c2f 706c 7567 696e  n>..    </plugin\n-00000fa0: 733e 0d0a 2020 3c2f 6275 696c 643e 0d0a  s>..  </build>..\n-00000fb0: 3c2f 7072 6f6a 6563 743e 0d0a            </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 7063  factId>dubbo-rpc\n+00000480: 3c2f 6172 7469 6661 6374 4964 3e0a 2020  </artifactId>.  \n+00000490: 2020 3c76 6572 7369 6f6e 3e32 2e37 2e31    <version>2.7.1\n+000004a0: 303c 2f76 6572 7369 6f6e 3e0a 2020 3c2f  0</version>.  </\n+000004b0: 7061 7265 6e74 3e0a 2020 3c67 726f 7570  parent>.  <group\n+000004c0: 4964 3e6f 7267 2e61 7061 6368 652e 6475  Id>org.apache.du\n+000004d0: 6262 6f3c 2f67 726f 7570 4964 3e0a 2020  bbo</groupId>.  \n+000004e0: 3c61 7274 6966 6163 7449 643e 6475 6262  <artifactId>dubb\n+000004f0: 6f2d 7270 632d 6475 6262 6f3c 2f61 7274  o-rpc-dubbo</art\n+00000500: 6966 6163 7449 643e 0a20 203c 7665 7273  ifactId>.  <vers\n+00000510: 696f 6e3e 322e 372e 3130 3c2f 7665 7273  ion>2.7.10</vers\n+00000520: 696f 6e3e 0a20 203c 6e61 6d65 3e24 7b70  ion>.  <name>${p\n+00000530: 726f 6a65 6374 2e61 7274 6966 6163 7449  roject.artifactI\n+00000540: 647d 3c2f 6e61 6d65 3e0a 2020 3c64 6573  d}</name>.  <des\n+00000550: 6372 6970 7469 6f6e 3e54 6865 2064 6566  cription>The def\n+00000560: 6175 6c74 2072 7063 206d 6f64 756c 6520  ault rpc module \n+00000570: 6f66 2064 7562 626f 2070 726f 6a65 6374  of dubbo project\n+00000580: 3c2f 6465 7363 7269 7074 696f 6e3e 0a20  </description>. \n+00000590: 203c 6c69 6365 6e73 6573 3e0a 2020 2020   <licenses>.    \n+000005a0: 3c6c 6963 656e 7365 3e0a 2020 2020 2020  <license>.      \n+000005b0: 3c6e 616d 653e 4170 6163 6865 204c 6963  <name>Apache Lic\n+000005c0: 656e 7365 2c20 5665 7273 696f 6e20 322e  ense, Version 2.\n+000005d0: 303c 2f6e 616d 653e 0a20 2020 2020 203c  0</name>.      <\n+000005e0: 7572 6c3e 6874 7470 3a2f 2f77 7777 2e61  url>http://www.a\n+000005f0: 7061 6368 652e 6f72 672f 6c69 6365 6e73  pache.org/licens\n+00000600: 6573 2f4c 4943 454e 5345 2d32 2e30 3c2f  es/LICENSE-2.0</\n+00000610: 7572 6c3e 0a20 2020 2020 203c 6469 7374  url>.      <dist\n+00000620: 7269 6275 7469 6f6e 3e72 6570 6f3c 2f64  ribution>repo</d\n+00000630: 6973 7472 6962 7574 696f 6e3e 0a20 2020  istribution>.   \n+00000640: 203c 2f6c 6963 656e 7365 3e0a 2020 3c2f   </license>.  </\n+00000650: 6c69 6365 6e73 6573 3e0a 2020 3c70 726f  licenses>.  <pro\n+00000660: 7065 7274 6965 733e 0a20 2020 203c 736b  perties>.    <sk\n+00000670: 6970 5f6d 6176 656e 5f64 6570 6c6f 793e  ip_maven_deploy>\n+00000680: 6661 6c73 653c 2f73 6b69 705f 6d61 7665  false</skip_mave\n+00000690: 6e5f 6465 706c 6f79 3e0a 2020 3c2f 7072  n_deploy>.  </pr\n+000006a0: 6f70 6572 7469 6573 3e0a 2020 3c64 6570  operties>.  <dep\n+000006b0: 656e 6465 6e63 6965 733e 0a20 2020 203c  endencies>.    <\n+000006c0: 6465 7065 6e64 656e 6379 3e0a 2020 2020  dependency>.    \n+000006d0: 2020 3c67 726f 7570 4964 3e6f 7267 2e61    <groupId>org.a\n+000006e0: 7061 6368 652e 6475 6262 6f3c 2f67 726f  pache.dubbo</gro\n+000006f0: 7570 4964 3e0a 2020 2020 2020 3c61 7274  upId>.      <art\n+00000700: 6966 6163 7449 643e 6475 6262 6f2d 7270  ifactId>dubbo-rp\n+00000710: 632d 6170 693c 2f61 7274 6966 6163 7449  c-api</artifactI\n+00000720: 643e 0a20 2020 2020 203c 7665 7273 696f  d>.      <versio\n+00000730: 6e3e 247b 7072 6f6a 6563 742e 7061 7265  n>${project.pare\n+00000740: 6e74 2e76 6572 7369 6f6e 7d3c 2f76 6572  nt.version}</ver\n+00000750: 7369 6f6e 3e0a 2020 2020 3c2f 6465 7065  sion>.    </depe\n+00000760: 6e64 656e 6379 3e0a 2020 2020 3c64 6570  ndency>.    <dep\n+00000770: 656e 6465 6e63 793e 0a20 2020 2020 203c  endency>.      <\n+00000780: 6772 6f75 7049 643e 6f72 672e 6170 6163  groupId>org.apac\n+00000790: 6865 2e64 7562 626f 3c2f 6772 6f75 7049  he.dubbo</groupI\n+000007a0: 643e 0a20 2020 2020 203c 6172 7469 6661  d>.      <artifa\n+000007b0: 6374 4964 3e64 7562 626f 2d72 656d 6f74  ctId>dubbo-remot\n+000007c0: 696e 672d 6170 693c 2f61 7274 6966 6163  ing-api</artifac\n+000007d0: 7449 643e 0a20 2020 2020 203c 7665 7273  tId>.      <vers\n+000007e0: 696f 6e3e 247b 7072 6f6a 6563 742e 7061  ion>${project.pa\n+000007f0: 7265 6e74 2e76 6572 7369 6f6e 7d3c 2f76  rent.version}</v\n+00000800: 6572 7369 6f6e 3e0a 2020 2020 3c2f 6465  ersion>.    </de\n+00000810: 7065 6e64 656e 6379 3e0a 2020 2020 3c64  pendency>.    <d\n+00000820: 6570 656e 6465 6e63 793e 0a20 2020 2020  ependency>.     \n+00000830: 203c 6772 6f75 7049 643e 6f72 672e 6170   <groupId>org.ap\n+00000840: 6163 6865 2e64 7562 626f 3c2f 6772 6f75  ache.dubbo</grou\n+00000850: 7049 643e 0a20 2020 2020 203c 6172 7469  pId>.      <arti\n+00000860: 6661 6374 4964 3e64 7562 626f 2d63 6c75  factId>dubbo-clu\n+00000870: 7374 6572 3c2f 6172 7469 6661 6374 4964  ster</artifactId\n+00000880: 3e0a 2020 2020 2020 3c76 6572 7369 6f6e  >.      <version\n+00000890: 3e24 7b70 726f 6a65 6374 2e70 6172 656e  >${project.paren\n+000008a0: 742e 7665 7273 696f 6e7d 3c2f 7665 7273  t.version}</vers\n+000008b0: 696f 6e3e 0a20 2020 203c 2f64 6570 656e  ion>.    </depen\n+000008c0: 6465 6e63 793e 0a20 2020 203c 6465 7065  dency>.    <depe\n+000008d0: 6e64 656e 6379 3e0a 2020 2020 2020 3c67  ndency>.      <g\n+000008e0: 726f 7570 4964 3e6f 7267 2e61 7061 6368  roupId>org.apach\n+000008f0: 652e 6475 6262 6f3c 2f67 726f 7570 4964  e.dubbo</groupId\n+00000900: 3e0a 2020 2020 2020 3c61 7274 6966 6163  >.      <artifac\n+00000910: 7449 643e 6475 6262 6f2d 7265 6d6f 7469  tId>dubbo-remoti\n+00000920: 6e67 2d6e 6574 7479 343c 2f61 7274 6966  ng-netty4</artif\n+00000930: 6163 7449 643e 0a20 2020 2020 203c 7665  actId>.      <ve\n+00000940: 7273 696f 6e3e 247b 7072 6f6a 6563 742e  rsion>${project.\n+00000950: 7061 7265 6e74 2e76 6572 7369 6f6e 7d3c  parent.version}<\n+00000960: 2f76 6572 7369 6f6e 3e0a 2020 2020 2020  /version>.      \n+00000970: 3c73 636f 7065 3e74 6573 743c 2f73 636f  <scope>test</sco\n+00000980: 7065 3e0a 2020 2020 3c2f 6465 7065 6e64  pe>.    </depend\n+00000990: 656e 6379 3e0a 2020 2020 3c64 6570 656e  ency>.    <depen\n+000009a0: 6465 6e63 793e 0a20 2020 2020 203c 6772  dency>.      <gr\n+000009b0: 6f75 7049 643e 6f72 672e 6170 6163 6865  oupId>org.apache\n+000009c0: 2e64 7562 626f 3c2f 6772 6f75 7049 643e  .dubbo</groupId>\n+000009d0: 0a20 2020 2020 203c 6172 7469 6661 6374  .      <artifact\n+000009e0: 4964 3e64 7562 626f 2d72 656d 6f74 696e  Id>dubbo-remotin\n+000009f0: 672d 6d69 6e61 3c2f 6172 7469 6661 6374  g-mina</artifact\n+00000a00: 4964 3e0a 2020 2020 2020 3c76 6572 7369  Id>.      <versi\n+00000a10: 6f6e 3e24 7b70 726f 6a65 6374 2e70 6172  on>${project.par\n+00000a20: 656e 742e 7665 7273 696f 6e7d 3c2f 7665  ent.version}</ve\n+00000a30: 7273 696f 6e3e 0a20 2020 2020 203c 7363  rsion>.      <sc\n+00000a40: 6f70 653e 7465 7374 3c2f 7363 6f70 653e  ope>test</scope>\n+00000a50: 0a20 2020 203c 2f64 6570 656e 6465 6e63  .    </dependenc\n+00000a60: 793e 0a20 2020 203c 6465 7065 6e64 656e  y>.    <dependen\n+00000a70: 6379 3e0a 2020 2020 2020 3c67 726f 7570  cy>.      <group\n+00000a80: 4964 3e69 6f2e 6e65 7474 793c 2f67 726f  Id>io.netty</gro\n+00000a90: 7570 4964 3e0a 2020 2020 2020 3c61 7274  upId>.      <art\n+00000aa0: 6966 6163 7449 643e 6e65 7474 792d 616c  ifactId>netty-al\n+00000ab0: 6c3c 2f61 7274 6966 6163 7449 643e 0a20  l</artifactId>. \n+00000ac0: 2020 2020 203c 7363 6f70 653e 7465 7374       <scope>test\n+00000ad0: 3c2f 7363 6f70 653e 0a20 2020 203c 2f64  </scope>.    </d\n+00000ae0: 6570 656e 6465 6e63 793e 0a20 2020 203c  ependency>.    <\n+00000af0: 6465 7065 6e64 656e 6379 3e0a 2020 2020  dependency>.    \n+00000b00: 2020 3c67 726f 7570 4964 3e6f 7267 2e61    <groupId>org.a\n+00000b10: 7061 6368 652e 6475 6262 6f3c 2f67 726f  pache.dubbo</gro\n+00000b20: 7570 4964 3e0a 2020 2020 2020 3c61 7274  upId>.      <art\n+00000b30: 6966 6163 7449 643e 6475 6262 6f2d 7365  ifactId>dubbo-se\n+00000b40: 7269 616c 697a 6174 696f 6e2d 6865 7373  rialization-hess\n+00000b50: 6961 6e32 3c2f 6172 7469 6661 6374 4964  ian2</artifactId\n+00000b60: 3e0a 2020 2020 2020 3c76 6572 7369 6f6e  >.      <version\n+00000b70: 3e24 7b70 726f 6a65 6374 2e70 6172 656e  >${project.paren\n+00000b80: 742e 7665 7273 696f 6e7d 3c2f 7665 7273  t.version}</vers\n+00000b90: 696f 6e3e 0a20 2020 2020 203c 7363 6f70  ion>.      <scop\n+00000ba0: 653e 7465 7374 3c2f 7363 6f70 653e 0a20  e>test</scope>. \n+00000bb0: 2020 203c 2f64 6570 656e 6465 6e63 793e     </dependency>\n+00000bc0: 0a20 2020 203c 6465 7065 6e64 656e 6379  .    <dependency\n+00000bd0: 3e0a 2020 2020 2020 3c67 726f 7570 4964  >.      <groupId\n+00000be0: 3e6f 7267 2e61 7061 6368 652e 6475 6262  >org.apache.dubb\n+00000bf0: 6f3c 2f67 726f 7570 4964 3e0a 2020 2020  o</groupId>.    \n+00000c00: 2020 3c61 7274 6966 6163 7449 643e 6475    <artifactId>du\n+00000c10: 6262 6f2d 7365 7269 616c 697a 6174 696f  bbo-serializatio\n+00000c20: 6e2d 6a64 6b3c 2f61 7274 6966 6163 7449  n-jdk</artifactI\n+00000c30: 643e 0a20 2020 2020 203c 7665 7273 696f  d>.      <versio\n+00000c40: 6e3e 247b 7072 6f6a 6563 742e 7061 7265  n>${project.pare\n+00000c50: 6e74 2e76 6572 7369 6f6e 7d3c 2f76 6572  nt.version}</ver\n+00000c60: 7369 6f6e 3e0a 2020 2020 2020 3c73 636f  sion>.      <sco\n+00000c70: 7065 3e74 6573 743c 2f73 636f 7065 3e0a  pe>test</scope>.\n+00000c80: 2020 2020 3c2f 6465 7065 6e64 656e 6379      </dependency\n+00000c90: 3e0a 2020 2020 3c64 6570 656e 6465 6e63  >.    <dependenc\n+00000ca0: 793e 0a20 2020 2020 203c 6772 6f75 7049  y>.      <groupI\n+00000cb0: 643e 6a61 7661 782e 7661 6c69 6461 7469  d>javax.validati\n+00000cc0: 6f6e 3c2f 6772 6f75 7049 643e 0a20 2020  on</groupId>.   \n+00000cd0: 2020 203c 6172 7469 6661 6374 4964 3e76     <artifactId>v\n+00000ce0: 616c 6964 6174 696f 6e2d 6170 693c 2f61  alidation-api</a\n+00000cf0: 7274 6966 6163 7449 643e 0a20 2020 2020  rtifactId>.     \n+00000d00: 203c 7363 6f70 653e 7465 7374 3c2f 7363   <scope>test</sc\n+00000d10: 6f70 653e 0a20 2020 203c 2f64 6570 656e  ope>.    </depen\n+00000d20: 6465 6e63 793e 0a20 2020 203c 6465 7065  dency>.    <depe\n+00000d30: 6e64 656e 6379 3e0a 2020 2020 2020 3c67  ndency>.      <g\n+00000d40: 726f 7570 4964 3e6f 7267 2e68 6962 6572  roupId>org.hiber\n+00000d50: 6e61 7465 3c2f 6772 6f75 7049 643e 0a20  nate</groupId>. \n+00000d60: 2020 2020 203c 6172 7469 6661 6374 4964       <artifactId\n+00000d70: 3e68 6962 6572 6e61 7465 2d76 616c 6964  >hibernate-valid\n+00000d80: 6174 6f72 3c2f 6172 7469 6661 6374 4964  ator</artifactId\n+00000d90: 3e0a 2020 2020 2020 3c73 636f 7065 3e74  >.      <scope>t\n+00000da0: 6573 743c 2f73 636f 7065 3e0a 2020 2020  est</scope>.    \n+00000db0: 3c2f 6465 7065 6e64 656e 6379 3e0a 2020  </dependency>.  \n+00000dc0: 2020 3c64 6570 656e 6465 6e63 793e 0a20    <dependency>. \n+00000dd0: 2020 2020 203c 6772 6f75 7049 643e 6f72       <groupId>or\n+00000de0: 672e 676c 6173 7366 6973 683c 2f67 726f  g.glassfish</gro\n+00000df0: 7570 4964 3e0a 2020 2020 2020 3c61 7274  upId>.      <art\n+00000e00: 6966 6163 7449 643e 6a61 7661 782e 656c  ifactId>javax.el\n+00000e10: 3c2f 6172 7469 6661 6374 4964 3e0a 2020  </artifactId>.  \n+00000e20: 2020 2020 3c73 636f 7065 3e74 6573 743c      <scope>test<\n+00000e30: 2f73 636f 7065 3e0a 2020 2020 3c2f 6465  /scope>.    </de\n+00000e40: 7065 6e64 656e 6379 3e0a 2020 3c2f 6465  pendency>.  </de\n+00000e50: 7065 6e64 656e 6369 6573 3e0a 2020 3c62  pendencies>.  <b\n+00000e60: 7569 6c64 3e0a 2020 2020 3c70 6c75 6769  uild>.    <plugi\n+00000e70: 6e73 3e0a 2020 2020 2020 3c70 6c75 6769  ns>.      <plugi\n+00000e80: 6e3e 0a20 2020 2020 2020 203c 6172 7469  n>.        <arti\n+00000e90: 6661 6374 4964 3e6d 6176 656e 2d73 7572  factId>maven-sur\n+00000ea0: 6566 6972 652d 706c 7567 696e 3c2f 6172  efire-plugin</ar\n+00000eb0: 7469 6661 6374 4964 3e0a 2020 2020 2020  tifactId>.      \n+00000ec0: 2020 3c63 6f6e 6669 6775 7261 7469 6f6e    <configuration\n+00000ed0: 3e0a 2020 2020 2020 2020 2020 3c72 756e  >.          <run\n+00000ee0: 4f72 6465 723e 616c 7068 6162 6574 6963  Order>alphabetic\n+00000ef0: 616c 3c2f 7275 6e4f 7264 6572 3e0a 2020  al</runOrder>.  \n+00000f00: 2020 2020 2020 3c2f 636f 6e66 6967 7572        </configur\n+00000f10: 6174 696f 6e3e 0a20 2020 2020 203c 2f70  ation>.      </p\n+00000f20: 6c75 6769 6e3e 0a20 2020 203c 2f70 6c75  lugin>.    </plu\n+00000f30: 6769 6e73 3e0a 2020 3c2f 6275 696c 643e  gins>.  </build>\n+00000f40: 0a3c 2f70 726f 6a65 6374 3e0a            .</project>.\n"}, {"source1": "org/apache/dubbo/rpc/protocol/dubbo/CallbackServiceCodec.java", "source2": "org/apache/dubbo/rpc/protocol/dubbo/CallbackServiceCodec.java", "comments": ["Line-ending differences only"], "unified_diff": "@@ -1,318 +1,318 @@\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.rpc.protocol.dubbo;\n-\n-import org.apache.dubbo.common.URL;\n-import org.apache.dubbo.common.bytecode.Wrapper;\n-import org.apache.dubbo.common.extension.ExtensionLoader;\n-import org.apache.dubbo.common.logger.Logger;\n-import org.apache.dubbo.common.logger.LoggerFactory;\n-import org.apache.dubbo.common.utils.ConcurrentHashSet;\n-import org.apache.dubbo.common.utils.StringUtils;\n-import org.apache.dubbo.remoting.Channel;\n-import org.apache.dubbo.remoting.Constants;\n-import org.apache.dubbo.remoting.RemotingException;\n-import org.apache.dubbo.rpc.Exporter;\n-import org.apache.dubbo.rpc.Invocation;\n-import org.apache.dubbo.rpc.Invoker;\n-import org.apache.dubbo.rpc.ProxyFactory;\n-import org.apache.dubbo.rpc.RpcInvocation;\n-import org.apache.dubbo.rpc.model.ApplicationModel;\n-import org.apache.dubbo.rpc.protocol.AsyncToSyncInvoker;\n-\n-import java.io.IOException;\n-import java.util.HashMap;\n-import java.util.Map;\n-import java.util.Set;\n-\n-import static org.apache.dubbo.common.constants.CommonConstants.CALLBACK_INSTANCES_LIMIT_KEY;\n-import static org.apache.dubbo.common.constants.CommonConstants.DEFAULT_CALLBACK_INSTANCES;\n-import static org.apache.dubbo.common.constants.CommonConstants.GROUP_KEY;\n-import static org.apache.dubbo.common.constants.CommonConstants.INTERFACE_KEY;\n-import static org.apache.dubbo.common.constants.CommonConstants.METHODS_KEY;\n-import static org.apache.dubbo.common.constants.CommonConstants.VERSION_KEY;\n-import static org.apache.dubbo.rpc.Constants.IS_SERVER_KEY;\n-import static org.apache.dubbo.rpc.protocol.dubbo.Constants.CALLBACK_SERVICE_KEY;\n-import static org.apache.dubbo.rpc.protocol.dubbo.Constants.CALLBACK_SERVICE_PROXY_KEY;\n-import static org.apache.dubbo.rpc.protocol.dubbo.Constants.CHANNEL_CALLBACK_KEY;\n-import static org.apache.dubbo.rpc.protocol.dubbo.Constants.IS_CALLBACK_SERVICE;\n-\n-/**\n- * callback service helper\n- */\n-class CallbackServiceCodec {\n-    private static final Logger logger = LoggerFactory.getLogger(CallbackServiceCodec.class);\n-\n-    private static final ProxyFactory PROXY_FACTORY = ExtensionLoader.getExtensionLoader(ProxyFactory.class).getAdaptiveExtension();\n-    private static final DubboProtocol PROTOCOL = DubboProtocol.getDubboProtocol();\n-    private static final byte CALLBACK_NONE = 0x0;\n-    private static final byte CALLBACK_CREATE = 0x1;\n-    private static final byte CALLBACK_DESTROY = 0x2;\n-    private static final String INV_ATT_CALLBACK_KEY = \"sys_callback_arg-\";\n-\n-    private static byte isCallBack(URL url, String protocolServiceKey, String methodName, int argIndex) {\n-        // parameter callback rule: method-name.parameter-index(starting from 0).callback\n-        byte isCallback = CALLBACK_NONE;\n-        if (url != null && url.hasServiceMethodParameter(protocolServiceKey, methodName)) {\n-            String callback = url.getServiceParameter(protocolServiceKey, methodName + \".\" + argIndex + \".callback\");\n-            if (callback != null) {\n-                if (\"true\".equalsIgnoreCase(callback)) {\n-                    isCallback = CALLBACK_CREATE;\n-                } else if (\"false\".equalsIgnoreCase(callback)) {\n-                    isCallback = CALLBACK_DESTROY;\n-                }\n-            }\n-        }\n-        return isCallback;\n-    }\n-\n-    /**\n-     * export or unexport callback service on client side\n-     *\n-     * @param channel\n-     * @param url\n-     * @param clazz\n-     * @param inst\n-     * @param export\n-     * @throws IOException\n-     */\n-    @SuppressWarnings({\"unchecked\", \"rawtypes\"})\n-    private static String exportOrUnexportCallbackService(Channel channel, URL url, Class clazz, Object inst, Boolean export) throws IOException {\n-        int instid = System.identityHashCode(inst);\n-\n-        Map<String, String> params = new HashMap<>(3);\n-        // no need to new client again\n-        params.put(IS_SERVER_KEY, Boolean.FALSE.toString());\n-        // mark it's a callback, for troubleshooting\n-        params.put(IS_CALLBACK_SERVICE, Boolean.TRUE.toString());\n-        String group = (url == null ? null : url.getParameter(GROUP_KEY));\n-        if (group != null && group.length() > 0) {\n-            params.put(GROUP_KEY, group);\n-        }\n-        // add method, for verifying against method, automatic fallback (see dubbo protocol)\n-        params.put(METHODS_KEY, StringUtils.join(Wrapper.getWrapper(clazz).getDeclaredMethodNames(), \",\"));\n-\n-        Map<String, String> tmpMap = new HashMap<>();\n-        if (url != null) {\n-            Map<String, String> parameters = url.getParameters();\n-            if (parameters != null && !parameters.isEmpty()) {\n-                tmpMap.putAll(parameters);\n-            }\n-        }\n-        tmpMap.putAll(params);\n-        \n-        tmpMap.remove(VERSION_KEY);// doesn't need to distinguish version for callback\n-        tmpMap.remove(Constants.BIND_PORT_KEY); //callback doesn't needs bind.port\n-        tmpMap.put(INTERFACE_KEY, clazz.getName());\n-        URL exportUrl = new URL(DubboProtocol.NAME, channel.getLocalAddress().getAddress().getHostAddress(), channel.getLocalAddress().getPort(), clazz.getName() + \".\" + instid, tmpMap);\n-\n-        // no need to generate multiple exporters for different channel in the same JVM, cache key cannot collide.\n-        String cacheKey = getClientSideCallbackServiceCacheKey(instid);\n-        String countKey = getClientSideCountKey(clazz.getName());\n-        if (export) {\n-            // one channel can have multiple callback instances, no need to re-export for different instance.\n-            if (!channel.hasAttribute(cacheKey)) {\n-                if (!isInstancesOverLimit(channel, url, clazz.getName(), instid, false)) {\n-                    ApplicationModel.getServiceRepository().registerService(clazz);\n-                    Invoker<?> invoker = PROXY_FACTORY.getInvoker(inst, clazz, exportUrl);\n-                    // should destroy resource?\n-                    Exporter<?> exporter = PROTOCOL.export(invoker);\n-                    // this is used for tracing if instid has published service or not.\n-                    channel.setAttribute(cacheKey, exporter);\n-                    logger.info(\"Export a callback service :\" + exportUrl + \", on \" + channel + \", url is: \" + url);\n-                    increaseInstanceCount(channel, countKey);\n-                }\n-            }\n-        } else {\n-            if (channel.hasAttribute(cacheKey)) {\n-                Exporter<?> exporter = (Exporter<?>) channel.getAttribute(cacheKey);\n-                exporter.unexport();\n-                channel.removeAttribute(cacheKey);\n-                decreaseInstanceCount(channel, countKey);\n-            }\n-        }\n-        return String.valueOf(instid);\n-    }\n-\n-    /**\n-     * refer or destroy callback service on server side\n-     *\n-     * @param url\n-     */\n-    @SuppressWarnings(\"unchecked\")\n-    private static Object referOrDestroyCallbackService(Channel channel, URL url, Class<?> clazz, Invocation inv, int instid, boolean isRefer) {\n-        Object proxy;\n-        String invokerCacheKey = getServerSideCallbackInvokerCacheKey(channel, clazz.getName(), instid);\n-        String proxyCacheKey = getServerSideCallbackServiceCacheKey(channel, clazz.getName(), instid);\n-        proxy = channel.getAttribute(proxyCacheKey);\n-        String countkey = getServerSideCountKey(channel, clazz.getName());\n-        if (isRefer) {\n-            if (proxy == null) {\n-                URL referurl = URL.valueOf(\"callback://\" + url.getAddress() + \"/\" + clazz.getName() + \"?\" + INTERFACE_KEY + \"=\" + clazz.getName());\n-                referurl = referurl.addParametersIfAbsent(url.getParameters()).removeParameter(METHODS_KEY);\n-                if (!isInstancesOverLimit(channel, referurl, clazz.getName(), instid, true)) {\n-                    ApplicationModel.getServiceRepository().registerService(clazz);\n-                    @SuppressWarnings(\"rawtypes\")\n-                    Invoker<?> invoker = new ChannelWrappedInvoker(clazz, channel, referurl, String.valueOf(instid));\n-                    proxy = PROXY_FACTORY.getProxy(new AsyncToSyncInvoker<>(invoker));\n-                    channel.setAttribute(proxyCacheKey, proxy);\n-                    channel.setAttribute(invokerCacheKey, invoker);\n-                    increaseInstanceCount(channel, countkey);\n-\n-                    //convert error fail fast .\n-                    //ignore concurrent problem.\n-                    Set<Invoker<?>> callbackInvokers = (Set<Invoker<?>>) channel.getAttribute(CHANNEL_CALLBACK_KEY);\n-                    if (callbackInvokers == null) {\n-                        callbackInvokers = new ConcurrentHashSet<>(1);\n-                        channel.setAttribute(CHANNEL_CALLBACK_KEY, callbackInvokers);\n-                    }\n-                    callbackInvokers.add(invoker);\n-                    logger.info(\"method \" + inv.getMethodName() + \" include a callback service :\" + invoker.getUrl() + \", a proxy :\" + invoker + \" has been created.\");\n-                }\n-            }\n-        } else {\n-            if (proxy != null) {\n-                Invoker<?> invoker = (Invoker<?>) channel.getAttribute(invokerCacheKey);\n-                try {\n-                    Set<Invoker<?>> callbackInvokers = (Set<Invoker<?>>) channel.getAttribute(CHANNEL_CALLBACK_KEY);\n-                    if (callbackInvokers != null) {\n-                        callbackInvokers.remove(invoker);\n-                    }\n-                    invoker.destroy();\n-                } catch (Exception e) {\n-                    logger.error(e.getMessage(), e);\n-                }\n-                // cancel refer, directly remove from the map\n-                channel.removeAttribute(proxyCacheKey);\n-                channel.removeAttribute(invokerCacheKey);\n-                decreaseInstanceCount(channel, countkey);\n-            }\n-        }\n-        return proxy;\n-    }\n-\n-    private static String getClientSideCallbackServiceCacheKey(int instid) {\n-        return CALLBACK_SERVICE_KEY + \".\" + instid;\n-    }\n-\n-    private static String getServerSideCallbackServiceCacheKey(Channel channel, String interfaceClass, int instid) {\n-        return CALLBACK_SERVICE_PROXY_KEY + \".\" + System.identityHashCode(channel) + \".\" + interfaceClass + \".\" + instid;\n-    }\n-\n-    private static String getServerSideCallbackInvokerCacheKey(Channel channel, String interfaceClass, int instid) {\n-        return getServerSideCallbackServiceCacheKey(channel, interfaceClass, instid) + \".\" + \"invoker\";\n-    }\n-\n-    private static String getClientSideCountKey(String interfaceClass) {\n-        return CALLBACK_SERVICE_KEY + \".\" + interfaceClass + \".COUNT\";\n-    }\n-\n-    private static String getServerSideCountKey(Channel channel, String interfaceClass) {\n-        return CALLBACK_SERVICE_PROXY_KEY + \".\" + System.identityHashCode(channel) + \".\" + interfaceClass + \".COUNT\";\n-    }\n-\n-    private static boolean isInstancesOverLimit(Channel channel, URL url, String interfaceClass, int instid, boolean isServer) {\n-        Integer count = (Integer) channel.getAttribute(isServer ? getServerSideCountKey(channel, interfaceClass) : getClientSideCountKey(interfaceClass));\n-        int limit = url.getParameter(CALLBACK_INSTANCES_LIMIT_KEY, DEFAULT_CALLBACK_INSTANCES);\n-        if (count != null && count >= limit) {\n-            //client side error\n-            throw new IllegalStateException(\"interface \" + interfaceClass + \" `s callback instances num exceed providers limit :\" + limit\n-                    + \" ,current num: \" + (count + 1) + \". The new callback service will not work !!! you can cancle the callback service which exported before. channel :\" + channel);\n-        } else {\n-            return false;\n-        }\n-    }\n-\n-    private static void increaseInstanceCount(Channel channel, String countkey) {\n-        try {\n-            //ignore concurrent problem?\n-            Integer count = (Integer) channel.getAttribute(countkey);\n-            if (count == null) {\n-                count = 1;\n-            } else {\n-                count++;\n-            }\n-            channel.setAttribute(countkey, count);\n-        } catch (Exception e) {\n-            logger.error(e.getMessage(), e);\n-        }\n-    }\n-\n-    private static void decreaseInstanceCount(Channel channel, String countkey) {\n-        try {\n-            Integer count = (Integer) channel.getAttribute(countkey);\n-            if (count == null || count <= 0) {\n-                return;\n-            } else {\n-                count--;\n-            }\n-            channel.setAttribute(countkey, count);\n-        } catch (Exception e) {\n-            logger.error(e.getMessage(), e);\n-        }\n-    }\n-\n-    public static Object encodeInvocationArgument(Channel channel, RpcInvocation inv, int paraIndex) throws IOException {\n-        // get URL directly\n-        URL url = inv.getInvoker() == null ? null : inv.getInvoker().getUrl();\n-        byte callbackStatus = isCallBack(url, inv.getProtocolServiceKey(), inv.getMethodName(), paraIndex);\n-        Object[] args = inv.getArguments();\n-        Class<?>[] pts = inv.getParameterTypes();\n-        switch (callbackStatus) {\n-            case CallbackServiceCodec.CALLBACK_CREATE:\n-                inv.setAttachment(INV_ATT_CALLBACK_KEY + paraIndex, exportOrUnexportCallbackService(channel, url, pts[paraIndex], args[paraIndex], true));\n-                return null;\n-            case CallbackServiceCodec.CALLBACK_DESTROY:\n-                inv.setAttachment(INV_ATT_CALLBACK_KEY + paraIndex, exportOrUnexportCallbackService(channel, url, pts[paraIndex], args[paraIndex], false));\n-                return null;\n-            default:\n-                return args[paraIndex];\n-        }\n-    }\n-\n-    public static Object decodeInvocationArgument(Channel channel, RpcInvocation inv, Class<?>[] pts, int paraIndex, Object inObject) throws IOException {\n-        // if it's a callback, create proxy on client side, callback interface on client side can be invoked through channel\n-        // need get URL from channel and env when decode\n-        URL url = null;\n-        try {\n-            url = DubboProtocol.getDubboProtocol().getInvoker(channel, inv).getUrl();\n-        } catch (RemotingException e) {\n-            if (logger.isInfoEnabled()) {\n-                logger.info(e.getMessage(), e);\n-            }\n-            return inObject;\n-        }\n-        byte callbackstatus = isCallBack(url, inv.getProtocolServiceKey(), inv.getMethodName(), paraIndex);\n-        switch (callbackstatus) {\n-            case CallbackServiceCodec.CALLBACK_CREATE:\n-                try {\n-                    return referOrDestroyCallbackService(channel, url, pts[paraIndex], inv, Integer.parseInt(inv.getAttachment(INV_ATT_CALLBACK_KEY + paraIndex)), true);\n-                } catch (Exception e) {\n-                    logger.error(e.getMessage(), e);\n-                    throw new IOException(StringUtils.toString(e));\n-                }\n-            case CallbackServiceCodec.CALLBACK_DESTROY:\n-                try {\n-                    return referOrDestroyCallbackService(channel, url, pts[paraIndex], inv, Integer.parseInt(inv.getAttachment(INV_ATT_CALLBACK_KEY + paraIndex)), false);\n-                } catch (Exception e) {\n-                    throw new IOException(StringUtils.toString(e));\n-                }\n-            default:\n-                return inObject;\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.rpc.protocol.dubbo;\r\n+\r\n+import org.apache.dubbo.common.URL;\r\n+import org.apache.dubbo.common.bytecode.Wrapper;\r\n+import org.apache.dubbo.common.extension.ExtensionLoader;\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.ConcurrentHashSet;\r\n+import org.apache.dubbo.common.utils.StringUtils;\r\n+import org.apache.dubbo.remoting.Channel;\r\n+import org.apache.dubbo.remoting.Constants;\r\n+import org.apache.dubbo.remoting.RemotingException;\r\n+import org.apache.dubbo.rpc.Exporter;\r\n+import org.apache.dubbo.rpc.Invocation;\r\n+import org.apache.dubbo.rpc.Invoker;\r\n+import org.apache.dubbo.rpc.ProxyFactory;\r\n+import org.apache.dubbo.rpc.RpcInvocation;\r\n+import org.apache.dubbo.rpc.model.ApplicationModel;\r\n+import org.apache.dubbo.rpc.protocol.AsyncToSyncInvoker;\r\n+\r\n+import java.io.IOException;\r\n+import java.util.HashMap;\r\n+import java.util.Map;\r\n+import java.util.Set;\r\n+\r\n+import static org.apache.dubbo.common.constants.CommonConstants.CALLBACK_INSTANCES_LIMIT_KEY;\r\n+import static org.apache.dubbo.common.constants.CommonConstants.DEFAULT_CALLBACK_INSTANCES;\r\n+import static org.apache.dubbo.common.constants.CommonConstants.GROUP_KEY;\r\n+import static org.apache.dubbo.common.constants.CommonConstants.INTERFACE_KEY;\r\n+import static org.apache.dubbo.common.constants.CommonConstants.METHODS_KEY;\r\n+import static org.apache.dubbo.common.constants.CommonConstants.VERSION_KEY;\r\n+import static org.apache.dubbo.rpc.Constants.IS_SERVER_KEY;\r\n+import static org.apache.dubbo.rpc.protocol.dubbo.Constants.CALLBACK_SERVICE_KEY;\r\n+import static org.apache.dubbo.rpc.protocol.dubbo.Constants.CALLBACK_SERVICE_PROXY_KEY;\r\n+import static org.apache.dubbo.rpc.protocol.dubbo.Constants.CHANNEL_CALLBACK_KEY;\r\n+import static org.apache.dubbo.rpc.protocol.dubbo.Constants.IS_CALLBACK_SERVICE;\r\n+\r\n+/**\r\n+ * callback service helper\r\n+ */\r\n+class CallbackServiceCodec {\r\n+    private static final Logger logger = LoggerFactory.getLogger(CallbackServiceCodec.class);\r\n+\r\n+    private static final ProxyFactory PROXY_FACTORY = ExtensionLoader.getExtensionLoader(ProxyFactory.class).getAdaptiveExtension();\r\n+    private static final DubboProtocol PROTOCOL = DubboProtocol.getDubboProtocol();\r\n+    private static final byte CALLBACK_NONE = 0x0;\r\n+    private static final byte CALLBACK_CREATE = 0x1;\r\n+    private static final byte CALLBACK_DESTROY = 0x2;\r\n+    private static final String INV_ATT_CALLBACK_KEY = \"sys_callback_arg-\";\r\n+\r\n+    private static byte isCallBack(URL url, String protocolServiceKey, String methodName, int argIndex) {\r\n+        // parameter callback rule: method-name.parameter-index(starting from 0).callback\r\n+        byte isCallback = CALLBACK_NONE;\r\n+        if (url != null && url.hasServiceMethodParameter(protocolServiceKey, methodName)) {\r\n+            String callback = url.getServiceParameter(protocolServiceKey, methodName + \".\" + argIndex + \".callback\");\r\n+            if (callback != null) {\r\n+                if (\"true\".equalsIgnoreCase(callback)) {\r\n+                    isCallback = CALLBACK_CREATE;\r\n+                } else if (\"false\".equalsIgnoreCase(callback)) {\r\n+                    isCallback = CALLBACK_DESTROY;\r\n+                }\r\n+            }\r\n+        }\r\n+        return isCallback;\r\n+    }\r\n+\r\n+    /**\r\n+     * export or unexport callback service on client side\r\n+     *\r\n+     * @param channel\r\n+     * @param url\r\n+     * @param clazz\r\n+     * @param inst\r\n+     * @param export\r\n+     * @throws IOException\r\n+     */\r\n+    @SuppressWarnings({\"unchecked\", \"rawtypes\"})\r\n+    private static String exportOrUnexportCallbackService(Channel channel, URL url, Class clazz, Object inst, Boolean export) throws IOException {\r\n+        int instid = System.identityHashCode(inst);\r\n+\r\n+        Map<String, String> params = new HashMap<>(3);\r\n+        // no need to new client again\r\n+        params.put(IS_SERVER_KEY, Boolean.FALSE.toString());\r\n+        // mark it's a callback, for troubleshooting\r\n+        params.put(IS_CALLBACK_SERVICE, Boolean.TRUE.toString());\r\n+        String group = (url == null ? null : url.getParameter(GROUP_KEY));\r\n+        if (group != null && group.length() > 0) {\r\n+            params.put(GROUP_KEY, group);\r\n+        }\r\n+        // add method, for verifying against method, automatic fallback (see dubbo protocol)\r\n+        params.put(METHODS_KEY, StringUtils.join(Wrapper.getWrapper(clazz).getDeclaredMethodNames(), \",\"));\r\n+\r\n+        Map<String, String> tmpMap = new HashMap<>();\r\n+        if (url != null) {\r\n+            Map<String, String> parameters = url.getParameters();\r\n+            if (parameters != null && !parameters.isEmpty()) {\r\n+                tmpMap.putAll(parameters);\r\n+            }\r\n+        }\r\n+        tmpMap.putAll(params);\r\n+        \r\n+        tmpMap.remove(VERSION_KEY);// doesn't need to distinguish version for callback\r\n+        tmpMap.remove(Constants.BIND_PORT_KEY); //callback doesn't needs bind.port\r\n+        tmpMap.put(INTERFACE_KEY, clazz.getName());\r\n+        URL exportUrl = new URL(DubboProtocol.NAME, channel.getLocalAddress().getAddress().getHostAddress(), channel.getLocalAddress().getPort(), clazz.getName() + \".\" + instid, tmpMap);\r\n+\r\n+        // no need to generate multiple exporters for different channel in the same JVM, cache key cannot collide.\r\n+        String cacheKey = getClientSideCallbackServiceCacheKey(instid);\r\n+        String countKey = getClientSideCountKey(clazz.getName());\r\n+        if (export) {\r\n+            // one channel can have multiple callback instances, no need to re-export for different instance.\r\n+            if (!channel.hasAttribute(cacheKey)) {\r\n+                if (!isInstancesOverLimit(channel, url, clazz.getName(), instid, false)) {\r\n+                    ApplicationModel.getServiceRepository().registerService(clazz);\r\n+                    Invoker<?> invoker = PROXY_FACTORY.getInvoker(inst, clazz, exportUrl);\r\n+                    // should destroy resource?\r\n+                    Exporter<?> exporter = PROTOCOL.export(invoker);\r\n+                    // this is used for tracing if instid has published service or not.\r\n+                    channel.setAttribute(cacheKey, exporter);\r\n+                    logger.info(\"Export a callback service :\" + exportUrl + \", on \" + channel + \", url is: \" + url);\r\n+                    increaseInstanceCount(channel, countKey);\r\n+                }\r\n+            }\r\n+        } else {\r\n+            if (channel.hasAttribute(cacheKey)) {\r\n+                Exporter<?> exporter = (Exporter<?>) channel.getAttribute(cacheKey);\r\n+                exporter.unexport();\r\n+                channel.removeAttribute(cacheKey);\r\n+                decreaseInstanceCount(channel, countKey);\r\n+            }\r\n+        }\r\n+        return String.valueOf(instid);\r\n+    }\r\n+\r\n+    /**\r\n+     * refer or destroy callback service on server side\r\n+     *\r\n+     * @param url\r\n+     */\r\n+    @SuppressWarnings(\"unchecked\")\r\n+    private static Object referOrDestroyCallbackService(Channel channel, URL url, Class<?> clazz, Invocation inv, int instid, boolean isRefer) {\r\n+        Object proxy;\r\n+        String invokerCacheKey = getServerSideCallbackInvokerCacheKey(channel, clazz.getName(), instid);\r\n+        String proxyCacheKey = getServerSideCallbackServiceCacheKey(channel, clazz.getName(), instid);\r\n+        proxy = channel.getAttribute(proxyCacheKey);\r\n+        String countkey = getServerSideCountKey(channel, clazz.getName());\r\n+        if (isRefer) {\r\n+            if (proxy == null) {\r\n+                URL referurl = URL.valueOf(\"callback://\" + url.getAddress() + \"/\" + clazz.getName() + \"?\" + INTERFACE_KEY + \"=\" + clazz.getName());\r\n+                referurl = referurl.addParametersIfAbsent(url.getParameters()).removeParameter(METHODS_KEY);\r\n+                if (!isInstancesOverLimit(channel, referurl, clazz.getName(), instid, true)) {\r\n+                    ApplicationModel.getServiceRepository().registerService(clazz);\r\n+                    @SuppressWarnings(\"rawtypes\")\r\n+                    Invoker<?> invoker = new ChannelWrappedInvoker(clazz, channel, referurl, String.valueOf(instid));\r\n+                    proxy = PROXY_FACTORY.getProxy(new AsyncToSyncInvoker<>(invoker));\r\n+                    channel.setAttribute(proxyCacheKey, proxy);\r\n+                    channel.setAttribute(invokerCacheKey, invoker);\r\n+                    increaseInstanceCount(channel, countkey);\r\n+\r\n+                    //convert error fail fast .\r\n+                    //ignore concurrent problem.\r\n+                    Set<Invoker<?>> callbackInvokers = (Set<Invoker<?>>) channel.getAttribute(CHANNEL_CALLBACK_KEY);\r\n+                    if (callbackInvokers == null) {\r\n+                        callbackInvokers = new ConcurrentHashSet<>(1);\r\n+                        channel.setAttribute(CHANNEL_CALLBACK_KEY, callbackInvokers);\r\n+                    }\r\n+                    callbackInvokers.add(invoker);\r\n+                    logger.info(\"method \" + inv.getMethodName() + \" include a callback service :\" + invoker.getUrl() + \", a proxy :\" + invoker + \" has been created.\");\r\n+                }\r\n+            }\r\n+        } else {\r\n+            if (proxy != null) {\r\n+                Invoker<?> invoker = (Invoker<?>) channel.getAttribute(invokerCacheKey);\r\n+                try {\r\n+                    Set<Invoker<?>> callbackInvokers = (Set<Invoker<?>>) channel.getAttribute(CHANNEL_CALLBACK_KEY);\r\n+                    if (callbackInvokers != null) {\r\n+                        callbackInvokers.remove(invoker);\r\n+                    }\r\n+                    invoker.destroy();\r\n+                } catch (Exception e) {\r\n+                    logger.error(e.getMessage(), e);\r\n+                }\r\n+                // cancel refer, directly remove from the map\r\n+                channel.removeAttribute(proxyCacheKey);\r\n+                channel.removeAttribute(invokerCacheKey);\r\n+                decreaseInstanceCount(channel, countkey);\r\n+            }\r\n+        }\r\n+        return proxy;\r\n+    }\r\n+\r\n+    private static String getClientSideCallbackServiceCacheKey(int instid) {\r\n+        return CALLBACK_SERVICE_KEY + \".\" + instid;\r\n+    }\r\n+\r\n+    private static String getServerSideCallbackServiceCacheKey(Channel channel, String interfaceClass, int instid) {\r\n+        return CALLBACK_SERVICE_PROXY_KEY + \".\" + System.identityHashCode(channel) + \".\" + interfaceClass + \".\" + instid;\r\n+    }\r\n+\r\n+    private static String getServerSideCallbackInvokerCacheKey(Channel channel, String interfaceClass, int instid) {\r\n+        return getServerSideCallbackServiceCacheKey(channel, interfaceClass, instid) + \".\" + \"invoker\";\r\n+    }\r\n+\r\n+    private static String getClientSideCountKey(String interfaceClass) {\r\n+        return CALLBACK_SERVICE_KEY + \".\" + interfaceClass + \".COUNT\";\r\n+    }\r\n+\r\n+    private static String getServerSideCountKey(Channel channel, String interfaceClass) {\r\n+        return CALLBACK_SERVICE_PROXY_KEY + \".\" + System.identityHashCode(channel) + \".\" + interfaceClass + \".COUNT\";\r\n+    }\r\n+\r\n+    private static boolean isInstancesOverLimit(Channel channel, URL url, String interfaceClass, int instid, boolean isServer) {\r\n+        Integer count = (Integer) channel.getAttribute(isServer ? getServerSideCountKey(channel, interfaceClass) : getClientSideCountKey(interfaceClass));\r\n+        int limit = url.getParameter(CALLBACK_INSTANCES_LIMIT_KEY, DEFAULT_CALLBACK_INSTANCES);\r\n+        if (count != null && count >= limit) {\r\n+            //client side error\r\n+            throw new IllegalStateException(\"interface \" + interfaceClass + \" `s callback instances num exceed providers limit :\" + limit\r\n+                    + \" ,current num: \" + (count + 1) + \". The new callback service will not work !!! you can cancle the callback service which exported before. channel :\" + channel);\r\n+        } else {\r\n+            return false;\r\n+        }\r\n+    }\r\n+\r\n+    private static void increaseInstanceCount(Channel channel, String countkey) {\r\n+        try {\r\n+            //ignore concurrent problem?\r\n+            Integer count = (Integer) channel.getAttribute(countkey);\r\n+            if (count == null) {\r\n+                count = 1;\r\n+            } else {\r\n+                count++;\r\n+            }\r\n+            channel.setAttribute(countkey, count);\r\n+        } catch (Exception e) {\r\n+            logger.error(e.getMessage(), e);\r\n+        }\r\n+    }\r\n+\r\n+    private static void decreaseInstanceCount(Channel channel, String countkey) {\r\n+        try {\r\n+            Integer count = (Integer) channel.getAttribute(countkey);\r\n+            if (count == null || count <= 0) {\r\n+                return;\r\n+            } else {\r\n+                count--;\r\n+            }\r\n+            channel.setAttribute(countkey, count);\r\n+        } catch (Exception e) {\r\n+            logger.error(e.getMessage(), e);\r\n+        }\r\n+    }\r\n+\r\n+    public static Object encodeInvocationArgument(Channel channel, RpcInvocation inv, int paraIndex) throws IOException {\r\n+        // get URL directly\r\n+        URL url = inv.getInvoker() == null ? null : inv.getInvoker().getUrl();\r\n+        byte callbackStatus = isCallBack(url, inv.getProtocolServiceKey(), inv.getMethodName(), paraIndex);\r\n+        Object[] args = inv.getArguments();\r\n+        Class<?>[] pts = inv.getParameterTypes();\r\n+        switch (callbackStatus) {\r\n+            case CallbackServiceCodec.CALLBACK_CREATE:\r\n+                inv.setAttachment(INV_ATT_CALLBACK_KEY + paraIndex, exportOrUnexportCallbackService(channel, url, pts[paraIndex], args[paraIndex], true));\r\n+                return null;\r\n+            case CallbackServiceCodec.CALLBACK_DESTROY:\r\n+                inv.setAttachment(INV_ATT_CALLBACK_KEY + paraIndex, exportOrUnexportCallbackService(channel, url, pts[paraIndex], args[paraIndex], false));\r\n+                return null;\r\n+            default:\r\n+                return args[paraIndex];\r\n+        }\r\n+    }\r\n+\r\n+    public static Object decodeInvocationArgument(Channel channel, RpcInvocation inv, Class<?>[] pts, int paraIndex, Object inObject) throws IOException {\r\n+        // if it's a callback, create proxy on client side, callback interface on client side can be invoked through channel\r\n+        // need get URL from channel and env when decode\r\n+        URL url = null;\r\n+        try {\r\n+            url = DubboProtocol.getDubboProtocol().getInvoker(channel, inv).getUrl();\r\n+        } catch (RemotingException e) {\r\n+            if (logger.isInfoEnabled()) {\r\n+                logger.info(e.getMessage(), e);\r\n+            }\r\n+            return inObject;\r\n+        }\r\n+        byte callbackstatus = isCallBack(url, inv.getProtocolServiceKey(), inv.getMethodName(), paraIndex);\r\n+        switch (callbackstatus) {\r\n+            case CallbackServiceCodec.CALLBACK_CREATE:\r\n+                try {\r\n+                    return referOrDestroyCallbackService(channel, url, pts[paraIndex], inv, Integer.parseInt(inv.getAttachment(INV_ATT_CALLBACK_KEY + paraIndex)), true);\r\n+                } catch (Exception e) {\r\n+                    logger.error(e.getMessage(), e);\r\n+                    throw new IOException(StringUtils.toString(e));\r\n+                }\r\n+            case CallbackServiceCodec.CALLBACK_DESTROY:\r\n+                try {\r\n+                    return referOrDestroyCallbackService(channel, url, pts[paraIndex], inv, Integer.parseInt(inv.getAttachment(INV_ATT_CALLBACK_KEY + paraIndex)), false);\r\n+                } catch (Exception e) {\r\n+                    throw new IOException(StringUtils.toString(e));\r\n+                }\r\n+            default:\r\n+                return inObject;\r\n+        }\r\n+    }\r\n+}\r\n"}, {"source1": "org/apache/dubbo/rpc/protocol/dubbo/ChannelWrappedInvoker.java", "source2": "org/apache/dubbo/rpc/protocol/dubbo/ChannelWrappedInvoker.java", "comments": ["Line-ending differences only"], "unified_diff": "@@ -1,183 +1,183 @@\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.rpc.protocol.dubbo;\n-\n-import org.apache.dubbo.common.URL;\n-import org.apache.dubbo.remoting.Channel;\n-import org.apache.dubbo.remoting.ChannelHandler;\n-import org.apache.dubbo.remoting.RemotingException;\n-import org.apache.dubbo.remoting.TimeoutException;\n-import org.apache.dubbo.remoting.exchange.ExchangeClient;\n-import org.apache.dubbo.remoting.exchange.support.header.HeaderExchangeClient;\n-import org.apache.dubbo.remoting.transport.ClientDelegate;\n-import org.apache.dubbo.rpc.AppResponse;\n-import org.apache.dubbo.rpc.AsyncRpcResult;\n-import org.apache.dubbo.rpc.Invocation;\n-import org.apache.dubbo.rpc.Result;\n-import org.apache.dubbo.rpc.RpcException;\n-import org.apache.dubbo.rpc.RpcInvocation;\n-import org.apache.dubbo.rpc.protocol.AbstractInvoker;\n-import org.apache.dubbo.rpc.support.RpcUtils;\n-\n-import java.net.InetSocketAddress;\n-import java.util.concurrent.CompletableFuture;\n-\n-import static org.apache.dubbo.common.constants.CommonConstants.GROUP_KEY;\n-import static org.apache.dubbo.common.constants.CommonConstants.PATH_KEY;\n-import static org.apache.dubbo.remoting.Constants.SENT_KEY;\n-import static org.apache.dubbo.rpc.Constants.TOKEN_KEY;\n-import static org.apache.dubbo.rpc.protocol.dubbo.Constants.CALLBACK_SERVICE_KEY;\n-\n-/**\n- * Server push uses this Invoker to continuously push data to client.\n- * Wrap the existing invoker on the channel.\n- */\n-class ChannelWrappedInvoker<T> extends AbstractInvoker<T> {\n-\n-    private final Channel channel;\n-    private final String serviceKey;\n-    private final ExchangeClient currentClient;\n-\n-    ChannelWrappedInvoker(Class<T> serviceType, Channel channel, URL url, String serviceKey) {\n-        super(serviceType, url, new String[]{GROUP_KEY, TOKEN_KEY});\n-        this.channel = channel;\n-        this.serviceKey = serviceKey;\n-        this.currentClient = new HeaderExchangeClient(new ChannelWrapper(this.channel), false);\n-    }\n-\n-    @Override\n-    protected Result doInvoke(Invocation invocation) throws Throwable {\n-        RpcInvocation inv = (RpcInvocation) invocation;\n-        // use interface's name as service path to export if it's not found on client side\n-        inv.setAttachment(PATH_KEY, getInterface().getName());\n-        inv.setAttachment(CALLBACK_SERVICE_KEY, serviceKey);\n-\n-        try {\n-            if (RpcUtils.isOneway(getUrl(), inv)) { // may have concurrency issue\n-                currentClient.send(inv, getUrl().getMethodParameter(invocation.getMethodName(), SENT_KEY, false));\n-                return AsyncRpcResult.newDefaultAsyncResult(invocation);\n-            } else {\n-                CompletableFuture<AppResponse> appResponseFuture = currentClient.request(inv).thenApply(obj -> (AppResponse) obj);\n-                return new AsyncRpcResult(appResponseFuture, inv);\n-            }\n-        } catch (RpcException e) {\n-            throw e;\n-        } catch (TimeoutException e) {\n-            throw new RpcException(RpcException.TIMEOUT_EXCEPTION, e.getMessage(), e);\n-        } catch (RemotingException e) {\n-            throw new RpcException(RpcException.NETWORK_EXCEPTION, e.getMessage(), e);\n-        } catch (Throwable e) { // here is non-biz exception, wrap it.\n-            throw new RpcException(e.getMessage(), e);\n-        }\n-    }\n-\n-    @Override\n-    public void destroy() {\n-//        super.destroy();\n-//        try {\n-//            channel.close();\n-//        } catch (Throwable t) {\n-//            logger.warn(t.getMessage(), t);\n-//        }\n-    }\n-\n-    public static class ChannelWrapper extends ClientDelegate {\n-\n-        private final Channel channel;\n-        private final URL url;\n-\n-        ChannelWrapper(Channel channel) {\n-            this.channel = channel;\n-            this.url = channel.getUrl().addParameter(\"codec\", DubboCodec.NAME);\n-        }\n-\n-        @Override\n-        public URL getUrl() {\n-            return url;\n-        }\n-\n-        @Override\n-        public ChannelHandler getChannelHandler() {\n-            return channel.getChannelHandler();\n-        }\n-\n-        @Override\n-        public InetSocketAddress getLocalAddress() {\n-            return channel.getLocalAddress();\n-        }\n-\n-        @Override\n-        public void close() {\n-            channel.close();\n-        }\n-\n-        @Override\n-        public boolean isClosed() {\n-            return channel == null || channel.isClosed();\n-        }\n-\n-        @Override\n-        public void reset(URL url) {\n-            throw new RpcException(\"ChannelInvoker can not reset.\");\n-        }\n-\n-        @Override\n-        public InetSocketAddress getRemoteAddress() {\n-            return channel.getLocalAddress();\n-        }\n-\n-        @Override\n-        public boolean isConnected() {\n-            return channel != null && channel.isConnected();\n-        }\n-\n-        @Override\n-        public boolean hasAttribute(String key) {\n-            return channel.hasAttribute(key);\n-        }\n-\n-        @Override\n-        public Object getAttribute(String key) {\n-            return channel.getAttribute(key);\n-        }\n-\n-        @Override\n-        public void setAttribute(String key, Object value) {\n-            channel.setAttribute(key, value);\n-        }\n-\n-        @Override\n-        public void removeAttribute(String key) {\n-            channel.removeAttribute(key);\n-        }\n-\n-        @Override\n-        public void reconnect() throws RemotingException {\n-\n-        }\n-\n-        @Override\n-        public void send(Object message) throws RemotingException {\n-            channel.send(message);\n-        }\n-\n-        @Override\n-        public void send(Object message, boolean sent) throws RemotingException {\n-            channel.send(message, sent);\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.rpc.protocol.dubbo;\r\n+\r\n+import org.apache.dubbo.common.URL;\r\n+import org.apache.dubbo.remoting.Channel;\r\n+import org.apache.dubbo.remoting.ChannelHandler;\r\n+import org.apache.dubbo.remoting.RemotingException;\r\n+import org.apache.dubbo.remoting.TimeoutException;\r\n+import org.apache.dubbo.remoting.exchange.ExchangeClient;\r\n+import org.apache.dubbo.remoting.exchange.support.header.HeaderExchangeClient;\r\n+import org.apache.dubbo.remoting.transport.ClientDelegate;\r\n+import org.apache.dubbo.rpc.AppResponse;\r\n+import org.apache.dubbo.rpc.AsyncRpcResult;\r\n+import org.apache.dubbo.rpc.Invocation;\r\n+import org.apache.dubbo.rpc.Result;\r\n+import org.apache.dubbo.rpc.RpcException;\r\n+import org.apache.dubbo.rpc.RpcInvocation;\r\n+import org.apache.dubbo.rpc.protocol.AbstractInvoker;\r\n+import org.apache.dubbo.rpc.support.RpcUtils;\r\n+\r\n+import java.net.InetSocketAddress;\r\n+import java.util.concurrent.CompletableFuture;\r\n+\r\n+import static org.apache.dubbo.common.constants.CommonConstants.GROUP_KEY;\r\n+import static org.apache.dubbo.common.constants.CommonConstants.PATH_KEY;\r\n+import static org.apache.dubbo.remoting.Constants.SENT_KEY;\r\n+import static org.apache.dubbo.rpc.Constants.TOKEN_KEY;\r\n+import static org.apache.dubbo.rpc.protocol.dubbo.Constants.CALLBACK_SERVICE_KEY;\r\n+\r\n+/**\r\n+ * Server push uses this Invoker to continuously push data to client.\r\n+ * Wrap the existing invoker on the channel.\r\n+ */\r\n+class ChannelWrappedInvoker<T> extends AbstractInvoker<T> {\r\n+\r\n+    private final Channel channel;\r\n+    private final String serviceKey;\r\n+    private final ExchangeClient currentClient;\r\n+\r\n+    ChannelWrappedInvoker(Class<T> serviceType, Channel channel, URL url, String serviceKey) {\r\n+        super(serviceType, url, new String[]{GROUP_KEY, TOKEN_KEY});\r\n+        this.channel = channel;\r\n+        this.serviceKey = serviceKey;\r\n+        this.currentClient = new HeaderExchangeClient(new ChannelWrapper(this.channel), false);\r\n+    }\r\n+\r\n+    @Override\r\n+    protected Result doInvoke(Invocation invocation) throws Throwable {\r\n+        RpcInvocation inv = (RpcInvocation) invocation;\r\n+        // use interface's name as service path to export if it's not found on client side\r\n+        inv.setAttachment(PATH_KEY, getInterface().getName());\r\n+        inv.setAttachment(CALLBACK_SERVICE_KEY, serviceKey);\r\n+\r\n+        try {\r\n+            if (RpcUtils.isOneway(getUrl(), inv)) { // may have concurrency issue\r\n+                currentClient.send(inv, getUrl().getMethodParameter(invocation.getMethodName(), SENT_KEY, false));\r\n+                return AsyncRpcResult.newDefaultAsyncResult(invocation);\r\n+            } else {\r\n+                CompletableFuture<AppResponse> appResponseFuture = currentClient.request(inv).thenApply(obj -> (AppResponse) obj);\r\n+                return new AsyncRpcResult(appResponseFuture, inv);\r\n+            }\r\n+        } catch (RpcException e) {\r\n+            throw e;\r\n+        } catch (TimeoutException e) {\r\n+            throw new RpcException(RpcException.TIMEOUT_EXCEPTION, e.getMessage(), e);\r\n+        } catch (RemotingException e) {\r\n+            throw new RpcException(RpcException.NETWORK_EXCEPTION, e.getMessage(), e);\r\n+        } catch (Throwable e) { // here is non-biz exception, wrap it.\r\n+            throw new RpcException(e.getMessage(), e);\r\n+        }\r\n+    }\r\n+\r\n+    @Override\r\n+    public void destroy() {\r\n+//        super.destroy();\r\n+//        try {\r\n+//            channel.close();\r\n+//        } catch (Throwable t) {\r\n+//            logger.warn(t.getMessage(), t);\r\n+//        }\r\n+    }\r\n+\r\n+    public static class ChannelWrapper extends ClientDelegate {\r\n+\r\n+        private final Channel channel;\r\n+        private final URL url;\r\n+\r\n+        ChannelWrapper(Channel channel) {\r\n+            this.channel = channel;\r\n+            this.url = channel.getUrl().addParameter(\"codec\", DubboCodec.NAME);\r\n+        }\r\n+\r\n+        @Override\r\n+        public URL getUrl() {\r\n+            return url;\r\n+        }\r\n+\r\n+        @Override\r\n+        public ChannelHandler getChannelHandler() {\r\n+            return channel.getChannelHandler();\r\n+        }\r\n+\r\n+        @Override\r\n+        public InetSocketAddress getLocalAddress() {\r\n+            return channel.getLocalAddress();\r\n+        }\r\n+\r\n+        @Override\r\n+        public void close() {\r\n+            channel.close();\r\n+        }\r\n+\r\n+        @Override\r\n+        public boolean isClosed() {\r\n+            return channel == null || channel.isClosed();\r\n+        }\r\n+\r\n+        @Override\r\n+        public void reset(URL url) {\r\n+            throw new RpcException(\"ChannelInvoker can not reset.\");\r\n+        }\r\n+\r\n+        @Override\r\n+        public InetSocketAddress getRemoteAddress() {\r\n+            return channel.getLocalAddress();\r\n+        }\r\n+\r\n+        @Override\r\n+        public boolean isConnected() {\r\n+            return channel != null && channel.isConnected();\r\n+        }\r\n+\r\n+        @Override\r\n+        public boolean hasAttribute(String key) {\r\n+            return channel.hasAttribute(key);\r\n+        }\r\n+\r\n+        @Override\r\n+        public Object getAttribute(String key) {\r\n+            return channel.getAttribute(key);\r\n+        }\r\n+\r\n+        @Override\r\n+        public void setAttribute(String key, Object value) {\r\n+            channel.setAttribute(key, value);\r\n+        }\r\n+\r\n+        @Override\r\n+        public void removeAttribute(String key) {\r\n+            channel.removeAttribute(key);\r\n+        }\r\n+\r\n+        @Override\r\n+        public void reconnect() throws RemotingException {\r\n+\r\n+        }\r\n+\r\n+        @Override\r\n+        public void send(Object message) throws RemotingException {\r\n+            channel.send(message);\r\n+        }\r\n+\r\n+        @Override\r\n+        public void send(Object message, boolean sent) throws RemotingException {\r\n+            channel.send(message, sent);\r\n+        }\r\n+    }\r\n+}\r\n"}, {"source1": "org/apache/dubbo/rpc/protocol/dubbo/Constants.java", "source2": "org/apache/dubbo/rpc/protocol/dubbo/Constants.java", "comments": ["Line-ending differences only"], "unified_diff": "@@ -1,71 +1,71 @@\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-\n-package org.apache.dubbo.rpc.protocol.dubbo;\n-\n-/**\n- *\n- */\n-public interface Constants {\n-\n-    String SHARE_CONNECTIONS_KEY = \"shareconnections\";\n-\n-    /**\n-     * By default, a consumer JVM instance and a provider JVM instance share a long TCP connection (except when connections are set),\n-     * which can set the number of long TCP connections shared to avoid the bottleneck of sharing a single long TCP connection.\n-     */\n-    String DEFAULT_SHARE_CONNECTIONS = \"1\";\n-\n-    String DECODE_IN_IO_THREAD_KEY = \"decode.in.io\";\n-\n-    boolean DEFAULT_DECODE_IN_IO_THREAD = false;\n-\n-    /**\n-     * callback inst id\n-     */\n-    String CALLBACK_SERVICE_KEY = \"callback.service.instid\";\n-\n-    String CALLBACK_SERVICE_PROXY_KEY = \"callback.service.proxy\";\n-\n-    String IS_CALLBACK_SERVICE = \"is_callback_service\";\n-\n-    /**\n-     * Invokers in channel's callback\n-     */\n-    String CHANNEL_CALLBACK_KEY = \"channel.callback.invokers.key\";\n-\n-    /**\n-     * The initial state for lazy connection\n-     */\n-    String LAZY_CONNECT_INITIAL_STATE_KEY = \"connect.lazy.initial.state\";\n-\n-    /**\n-     * The default value of lazy connection's initial state: true\n-     *\n-     * @see #LAZY_CONNECT_INITIAL_STATE_KEY\n-     */\n-    boolean DEFAULT_LAZY_CONNECT_INITIAL_STATE = true;\n-\n-    String OPTIMIZER_KEY = \"optimizer\";\n-\n-    String ON_CONNECT_KEY = \"onconnect\";\n-\n-    String ON_DISCONNECT_KEY = \"ondisconnect\";\n-\n-    String ASYNC_METHOD_INFO = \"async-method-info\";\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+\r\n+package org.apache.dubbo.rpc.protocol.dubbo;\r\n+\r\n+/**\r\n+ *\r\n+ */\r\n+public interface Constants {\r\n+\r\n+    String SHARE_CONNECTIONS_KEY = \"shareconnections\";\r\n+\r\n+    /**\r\n+     * By default, a consumer JVM instance and a provider JVM instance share a long TCP connection (except when connections are set),\r\n+     * which can set the number of long TCP connections shared to avoid the bottleneck of sharing a single long TCP connection.\r\n+     */\r\n+    String DEFAULT_SHARE_CONNECTIONS = \"1\";\r\n+\r\n+    String DECODE_IN_IO_THREAD_KEY = \"decode.in.io\";\r\n+\r\n+    boolean DEFAULT_DECODE_IN_IO_THREAD = false;\r\n+\r\n+    /**\r\n+     * callback inst id\r\n+     */\r\n+    String CALLBACK_SERVICE_KEY = \"callback.service.instid\";\r\n+\r\n+    String CALLBACK_SERVICE_PROXY_KEY = \"callback.service.proxy\";\r\n+\r\n+    String IS_CALLBACK_SERVICE = \"is_callback_service\";\r\n+\r\n+    /**\r\n+     * Invokers in channel's callback\r\n+     */\r\n+    String CHANNEL_CALLBACK_KEY = \"channel.callback.invokers.key\";\r\n+\r\n+    /**\r\n+     * The initial state for lazy connection\r\n+     */\r\n+    String LAZY_CONNECT_INITIAL_STATE_KEY = \"connect.lazy.initial.state\";\r\n+\r\n+    /**\r\n+     * The default value of lazy connection's initial state: true\r\n+     *\r\n+     * @see #LAZY_CONNECT_INITIAL_STATE_KEY\r\n+     */\r\n+    boolean DEFAULT_LAZY_CONNECT_INITIAL_STATE = true;\r\n+\r\n+    String OPTIMIZER_KEY = \"optimizer\";\r\n+\r\n+    String ON_CONNECT_KEY = \"onconnect\";\r\n+\r\n+    String ON_DISCONNECT_KEY = \"ondisconnect\";\r\n+\r\n+    String ASYNC_METHOD_INFO = \"async-method-info\";\r\n+\r\n+}\r\n"}, {"source1": "org/apache/dubbo/rpc/protocol/dubbo/DecodeableRpcInvocation.java", "source2": "org/apache/dubbo/rpc/protocol/dubbo/DecodeableRpcInvocation.java", "comments": ["Line-ending differences only"], "unified_diff": "@@ -1,195 +1,195 @@\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.rpc.protocol.dubbo;\n-\n-\n-import org.apache.dubbo.common.config.ConfigurationUtils;\n-import org.apache.dubbo.common.logger.Logger;\n-import org.apache.dubbo.common.logger.LoggerFactory;\n-import org.apache.dubbo.common.serialize.Cleanable;\n-import org.apache.dubbo.common.serialize.ObjectInput;\n-import org.apache.dubbo.common.utils.Assert;\n-import org.apache.dubbo.common.utils.ReflectUtils;\n-import org.apache.dubbo.common.utils.StringUtils;\n-import org.apache.dubbo.remoting.Channel;\n-import org.apache.dubbo.remoting.Codec;\n-import org.apache.dubbo.remoting.Decodeable;\n-import org.apache.dubbo.remoting.exchange.Request;\n-import org.apache.dubbo.remoting.transport.CodecSupport;\n-import org.apache.dubbo.rpc.RpcInvocation;\n-import org.apache.dubbo.rpc.model.ApplicationModel;\n-import org.apache.dubbo.rpc.model.MethodDescriptor;\n-import org.apache.dubbo.rpc.model.ServiceDescriptor;\n-import org.apache.dubbo.rpc.model.ServiceRepository;\n-import org.apache.dubbo.rpc.support.RpcUtils;\n-\n-import java.io.IOException;\n-import java.io.InputStream;\n-import java.io.OutputStream;\n-import java.util.HashMap;\n-import java.util.Map;\n-\n-import static org.apache.dubbo.common.URL.buildKey;\n-import static org.apache.dubbo.common.constants.CommonConstants.DUBBO_VERSION_KEY;\n-import static org.apache.dubbo.common.constants.CommonConstants.GROUP_KEY;\n-import static org.apache.dubbo.common.constants.CommonConstants.PATH_KEY;\n-import static org.apache.dubbo.common.constants.CommonConstants.VERSION_KEY;\n-import static org.apache.dubbo.rpc.Constants.SERIALIZATION_ID_KEY;\n-import static org.apache.dubbo.rpc.Constants.SERIALIZATION_SECURITY_CHECK_KEY;\n-import static org.apache.dubbo.rpc.protocol.dubbo.CallbackServiceCodec.decodeInvocationArgument;\n-\n-public class DecodeableRpcInvocation extends RpcInvocation implements Codec, Decodeable {\n-\n-    private static final Logger log = LoggerFactory.getLogger(DecodeableRpcInvocation.class);\n-\n-    private Channel channel;\n-\n-    private byte serializationType;\n-\n-    private InputStream inputStream;\n-\n-    private Request request;\n-\n-    private volatile boolean hasDecoded;\n-\n-    public DecodeableRpcInvocation(Channel channel, Request request, InputStream is, byte id) {\n-        Assert.notNull(channel, \"channel == null\");\n-        Assert.notNull(request, \"request == null\");\n-        Assert.notNull(is, \"inputStream == null\");\n-        this.channel = channel;\n-        this.request = request;\n-        this.inputStream = is;\n-        this.serializationType = id;\n-    }\n-\n-    @Override\n-    public void decode() throws Exception {\n-        if (!hasDecoded && channel != null && inputStream != null) {\n-            try {\n-                decode(channel, inputStream);\n-            } catch (Throwable e) {\n-                if (log.isWarnEnabled()) {\n-                    log.warn(\"Decode rpc invocation failed: \" + e.getMessage(), e);\n-                }\n-                request.setBroken(true);\n-                request.setData(e);\n-            } finally {\n-                hasDecoded = true;\n-            }\n-        }\n-    }\n-\n-    @Override\n-    public void encode(Channel channel, OutputStream output, Object message) throws IOException {\n-        throw new UnsupportedOperationException();\n-    }\n-\n-    private void checkSerializationTypeFromRemote() {\n-\n-    }\n-\n-    @Override\n-    public Object decode(Channel channel, InputStream input) throws IOException {\n-        ObjectInput in = CodecSupport.getSerialization(channel.getUrl(), serializationType)\n-                .deserialize(channel.getUrl(), input);\n-        this.put(SERIALIZATION_ID_KEY, serializationType);\n-\n-        String dubboVersion = in.readUTF();\n-        request.setVersion(dubboVersion);\n-        setAttachment(DUBBO_VERSION_KEY, dubboVersion);\n-\n-        String path = in.readUTF();\n-        setAttachment(PATH_KEY, path);\n-        String version = in.readUTF();\n-        setAttachment(VERSION_KEY, version);\n-\n-        setMethodName(in.readUTF());\n-\n-        String desc = in.readUTF();\n-        setParameterTypesDesc(desc);\n-\n-        try {\n-            if (ConfigurationUtils.getSystemConfiguration().getBoolean(SERIALIZATION_SECURITY_CHECK_KEY, false)) {\n-                CodecSupport.checkSerialization(path, version, serializationType);\n-            }\n-            Object[] args = DubboCodec.EMPTY_OBJECT_ARRAY;\n-            Class<?>[] pts = DubboCodec.EMPTY_CLASS_ARRAY;\n-            if (desc.length() > 0) {\n-//                if (RpcUtils.isGenericCall(path, getMethodName()) || RpcUtils.isEcho(path, getMethodName())) {\n-//                    pts = ReflectUtils.desc2classArray(desc);\n-//                } else {\n-                ServiceRepository repository = ApplicationModel.getServiceRepository();\n-                ServiceDescriptor serviceDescriptor = repository.lookupService(path);\n-                if (serviceDescriptor != null) {\n-                    MethodDescriptor methodDescriptor = serviceDescriptor.getMethod(getMethodName(), desc);\n-                    if (methodDescriptor != null) {\n-                        pts = methodDescriptor.getParameterClasses();\n-                        this.setReturnTypes(methodDescriptor.getReturnTypes());\n-                    }\n-                }\n-                if (pts == DubboCodec.EMPTY_CLASS_ARRAY) {\n-                    if (!RpcUtils.isGenericCall(desc, getMethodName()) && !RpcUtils.isEcho(desc, getMethodName())) {\n-                        throw new IllegalArgumentException(\"Service not found:\" + path + \", \" + getMethodName());\n-                    }\n-                    pts = ReflectUtils.desc2classArray(desc);\n-                }\n-//                }\n-\n-                args = new Object[pts.length];\n-                for (int i = 0; i < args.length; i++) {\n-                    try {\n-                        args[i] = in.readObject(pts[i]);\n-                    } catch (Exception e) {\n-                        if (log.isWarnEnabled()) {\n-                            log.warn(\"Decode argument failed: \" + e.getMessage(), e);\n-                        }\n-                    }\n-                }\n-            }\n-            setParameterTypes(pts);\n-\n-            Map<String, Object> map = in.readAttachments();\n-            if (map != null && map.size() > 0) {\n-                Map<String, Object> attachment = getObjectAttachments();\n-                if (attachment == null) {\n-                    attachment = new HashMap<>();\n-                }\n-                attachment.putAll(map);\n-                setObjectAttachments(attachment);\n-            }\n-\n-            //decode argument ,may be callback\n-            for (int i = 0; i < args.length; i++) {\n-                args[i] = decodeInvocationArgument(channel, this, pts, i, args[i]);\n-            }\n-\n-            setArguments(args);\n-            String targetServiceName = buildKey((String) getAttachment(PATH_KEY),\n-                    getAttachment(GROUP_KEY),\n-                    getAttachment(VERSION_KEY));\n-            setTargetServiceUniqueName(targetServiceName);\n-        } catch (ClassNotFoundException e) {\n-            throw new IOException(StringUtils.toString(\"Read invocation data failed.\", e));\n-        } finally {\n-            if (in instanceof Cleanable) {\n-                ((Cleanable) in).cleanup();\n-            }\n-        }\n-        return this;\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.rpc.protocol.dubbo;\r\n+\r\n+\r\n+import org.apache.dubbo.common.config.ConfigurationUtils;\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.serialize.Cleanable;\r\n+import org.apache.dubbo.common.serialize.ObjectInput;\r\n+import org.apache.dubbo.common.utils.Assert;\r\n+import org.apache.dubbo.common.utils.ReflectUtils;\r\n+import org.apache.dubbo.common.utils.StringUtils;\r\n+import org.apache.dubbo.remoting.Channel;\r\n+import org.apache.dubbo.remoting.Codec;\r\n+import org.apache.dubbo.remoting.Decodeable;\r\n+import org.apache.dubbo.remoting.exchange.Request;\r\n+import org.apache.dubbo.remoting.transport.CodecSupport;\r\n+import org.apache.dubbo.rpc.RpcInvocation;\r\n+import org.apache.dubbo.rpc.model.ApplicationModel;\r\n+import org.apache.dubbo.rpc.model.MethodDescriptor;\r\n+import org.apache.dubbo.rpc.model.ServiceDescriptor;\r\n+import org.apache.dubbo.rpc.model.ServiceRepository;\r\n+import org.apache.dubbo.rpc.support.RpcUtils;\r\n+\r\n+import java.io.IOException;\r\n+import java.io.InputStream;\r\n+import java.io.OutputStream;\r\n+import java.util.HashMap;\r\n+import java.util.Map;\r\n+\r\n+import static org.apache.dubbo.common.URL.buildKey;\r\n+import static org.apache.dubbo.common.constants.CommonConstants.DUBBO_VERSION_KEY;\r\n+import static org.apache.dubbo.common.constants.CommonConstants.GROUP_KEY;\r\n+import static org.apache.dubbo.common.constants.CommonConstants.PATH_KEY;\r\n+import static org.apache.dubbo.common.constants.CommonConstants.VERSION_KEY;\r\n+import static org.apache.dubbo.rpc.Constants.SERIALIZATION_ID_KEY;\r\n+import static org.apache.dubbo.rpc.Constants.SERIALIZATION_SECURITY_CHECK_KEY;\r\n+import static org.apache.dubbo.rpc.protocol.dubbo.CallbackServiceCodec.decodeInvocationArgument;\r\n+\r\n+public class DecodeableRpcInvocation extends RpcInvocation implements Codec, Decodeable {\r\n+\r\n+    private static final Logger log = LoggerFactory.getLogger(DecodeableRpcInvocation.class);\r\n+\r\n+    private Channel channel;\r\n+\r\n+    private byte serializationType;\r\n+\r\n+    private InputStream inputStream;\r\n+\r\n+    private Request request;\r\n+\r\n+    private volatile boolean hasDecoded;\r\n+\r\n+    public DecodeableRpcInvocation(Channel channel, Request request, InputStream is, byte id) {\r\n+        Assert.notNull(channel, \"channel == null\");\r\n+        Assert.notNull(request, \"request == null\");\r\n+        Assert.notNull(is, \"inputStream == null\");\r\n+        this.channel = channel;\r\n+        this.request = request;\r\n+        this.inputStream = is;\r\n+        this.serializationType = id;\r\n+    }\r\n+\r\n+    @Override\r\n+    public void decode() throws Exception {\r\n+        if (!hasDecoded && channel != null && inputStream != null) {\r\n+            try {\r\n+                decode(channel, inputStream);\r\n+            } catch (Throwable e) {\r\n+                if (log.isWarnEnabled()) {\r\n+                    log.warn(\"Decode rpc invocation failed: \" + e.getMessage(), e);\r\n+                }\r\n+                request.setBroken(true);\r\n+                request.setData(e);\r\n+            } finally {\r\n+                hasDecoded = true;\r\n+            }\r\n+        }\r\n+    }\r\n+\r\n+    @Override\r\n+    public void encode(Channel channel, OutputStream output, Object message) throws IOException {\r\n+        throw new UnsupportedOperationException();\r\n+    }\r\n+\r\n+    private void checkSerializationTypeFromRemote() {\r\n+\r\n+    }\r\n+\r\n+    @Override\r\n+    public Object decode(Channel channel, InputStream input) throws IOException {\r\n+        ObjectInput in = CodecSupport.getSerialization(channel.getUrl(), serializationType)\r\n+                .deserialize(channel.getUrl(), input);\r\n+        this.put(SERIALIZATION_ID_KEY, serializationType);\r\n+\r\n+        String dubboVersion = in.readUTF();\r\n+        request.setVersion(dubboVersion);\r\n+        setAttachment(DUBBO_VERSION_KEY, dubboVersion);\r\n+\r\n+        String path = in.readUTF();\r\n+        setAttachment(PATH_KEY, path);\r\n+        String version = in.readUTF();\r\n+        setAttachment(VERSION_KEY, version);\r\n+\r\n+        setMethodName(in.readUTF());\r\n+\r\n+        String desc = in.readUTF();\r\n+        setParameterTypesDesc(desc);\r\n+\r\n+        try {\r\n+            if (ConfigurationUtils.getSystemConfiguration().getBoolean(SERIALIZATION_SECURITY_CHECK_KEY, false)) {\r\n+                CodecSupport.checkSerialization(path, version, serializationType);\r\n+            }\r\n+            Object[] args = DubboCodec.EMPTY_OBJECT_ARRAY;\r\n+            Class<?>[] pts = DubboCodec.EMPTY_CLASS_ARRAY;\r\n+            if (desc.length() > 0) {\r\n+//                if (RpcUtils.isGenericCall(path, getMethodName()) || RpcUtils.isEcho(path, getMethodName())) {\r\n+//                    pts = ReflectUtils.desc2classArray(desc);\r\n+//                } else {\r\n+                ServiceRepository repository = ApplicationModel.getServiceRepository();\r\n+                ServiceDescriptor serviceDescriptor = repository.lookupService(path);\r\n+                if (serviceDescriptor != null) {\r\n+                    MethodDescriptor methodDescriptor = serviceDescriptor.getMethod(getMethodName(), desc);\r\n+                    if (methodDescriptor != null) {\r\n+                        pts = methodDescriptor.getParameterClasses();\r\n+                        this.setReturnTypes(methodDescriptor.getReturnTypes());\r\n+                    }\r\n+                }\r\n+                if (pts == DubboCodec.EMPTY_CLASS_ARRAY) {\r\n+                    if (!RpcUtils.isGenericCall(desc, getMethodName()) && !RpcUtils.isEcho(desc, getMethodName())) {\r\n+                        throw new IllegalArgumentException(\"Service not found:\" + path + \", \" + getMethodName());\r\n+                    }\r\n+                    pts = ReflectUtils.desc2classArray(desc);\r\n+                }\r\n+//                }\r\n+\r\n+                args = new Object[pts.length];\r\n+                for (int i = 0; i < args.length; i++) {\r\n+                    try {\r\n+                        args[i] = in.readObject(pts[i]);\r\n+                    } catch (Exception e) {\r\n+                        if (log.isWarnEnabled()) {\r\n+                            log.warn(\"Decode argument failed: \" + e.getMessage(), e);\r\n+                        }\r\n+                    }\r\n+                }\r\n+            }\r\n+            setParameterTypes(pts);\r\n+\r\n+            Map<String, Object> map = in.readAttachments();\r\n+            if (map != null && map.size() > 0) {\r\n+                Map<String, Object> attachment = getObjectAttachments();\r\n+                if (attachment == null) {\r\n+                    attachment = new HashMap<>();\r\n+                }\r\n+                attachment.putAll(map);\r\n+                setObjectAttachments(attachment);\r\n+            }\r\n+\r\n+            //decode argument ,may be callback\r\n+            for (int i = 0; i < args.length; i++) {\r\n+                args[i] = decodeInvocationArgument(channel, this, pts, i, args[i]);\r\n+            }\r\n+\r\n+            setArguments(args);\r\n+            String targetServiceName = buildKey((String) getAttachment(PATH_KEY),\r\n+                    getAttachment(GROUP_KEY),\r\n+                    getAttachment(VERSION_KEY));\r\n+            setTargetServiceUniqueName(targetServiceName);\r\n+        } catch (ClassNotFoundException e) {\r\n+            throw new IOException(StringUtils.toString(\"Read invocation data failed.\", e));\r\n+        } finally {\r\n+            if (in instanceof Cleanable) {\r\n+                ((Cleanable) in).cleanup();\r\n+            }\r\n+        }\r\n+        return this;\r\n+    }\r\n+\r\n+}\r\n"}, {"source1": "org/apache/dubbo/rpc/protocol/dubbo/DecodeableRpcResult.java", "source2": "org/apache/dubbo/rpc/protocol/dubbo/DecodeableRpcResult.java", "comments": ["Line-ending differences only"], "unified_diff": "@@ -1,184 +1,184 @@\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.rpc.protocol.dubbo;\n-\n-import org.apache.dubbo.common.config.ConfigurationUtils;\n-import org.apache.dubbo.common.logger.Logger;\n-import org.apache.dubbo.common.logger.LoggerFactory;\n-import org.apache.dubbo.common.serialize.Cleanable;\n-import org.apache.dubbo.common.serialize.ObjectInput;\n-import org.apache.dubbo.common.utils.ArrayUtils;\n-import org.apache.dubbo.common.utils.Assert;\n-import org.apache.dubbo.common.utils.StringUtils;\n-import org.apache.dubbo.remoting.Channel;\n-import org.apache.dubbo.remoting.Codec;\n-import org.apache.dubbo.remoting.Decodeable;\n-import org.apache.dubbo.remoting.exchange.Response;\n-import org.apache.dubbo.remoting.transport.CodecSupport;\n-import org.apache.dubbo.rpc.AppResponse;\n-import org.apache.dubbo.rpc.Invocation;\n-import org.apache.dubbo.rpc.RpcInvocation;\n-import org.apache.dubbo.rpc.support.RpcUtils;\n-\n-import java.io.IOException;\n-import java.io.InputStream;\n-import java.io.OutputStream;\n-import java.lang.reflect.Type;\n-\n-import static org.apache.dubbo.rpc.Constants.SERIALIZATION_ID_KEY;\n-import static org.apache.dubbo.rpc.Constants.SERIALIZATION_SECURITY_CHECK_KEY;\n-\n-public class DecodeableRpcResult extends AppResponse implements Codec, Decodeable {\n-\n-    private static final Logger log = LoggerFactory.getLogger(DecodeableRpcResult.class);\n-\n-    private Channel channel;\n-\n-    private byte serializationType;\n-\n-    private InputStream inputStream;\n-\n-    private Response response;\n-\n-    private Invocation invocation;\n-\n-    private volatile boolean hasDecoded;\n-\n-    public DecodeableRpcResult(Channel channel, Response response, InputStream is, Invocation invocation, byte id) {\n-        Assert.notNull(channel, \"channel == null\");\n-        Assert.notNull(response, \"response == null\");\n-        Assert.notNull(is, \"inputStream == null\");\n-        this.channel = channel;\n-        this.response = response;\n-        this.inputStream = is;\n-        this.invocation = invocation;\n-        this.serializationType = id;\n-    }\n-\n-    @Override\n-    public void encode(Channel channel, OutputStream output, Object message) throws IOException {\n-        throw new UnsupportedOperationException();\n-    }\n-\n-    @Override\n-    public Object decode(Channel channel, InputStream input) throws IOException {\n-        if (log.isDebugEnabled()) {\n-            Thread thread = Thread.currentThread();\n-            log.debug(\"Decoding in thread -- [\" + thread.getName() + \"#\" + thread.getId() + \"]\");\n-        }\n-\n-        ObjectInput in = CodecSupport.getSerialization(channel.getUrl(), serializationType)\n-                .deserialize(channel.getUrl(), input);\n-\n-        byte flag = in.readByte();\n-        switch (flag) {\n-            case DubboCodec.RESPONSE_NULL_VALUE:\n-                break;\n-            case DubboCodec.RESPONSE_VALUE:\n-                handleValue(in);\n-                break;\n-            case DubboCodec.RESPONSE_WITH_EXCEPTION:\n-                handleException(in);\n-                break;\n-            case DubboCodec.RESPONSE_NULL_VALUE_WITH_ATTACHMENTS:\n-                handleAttachment(in);\n-                break;\n-            case DubboCodec.RESPONSE_VALUE_WITH_ATTACHMENTS:\n-                handleValue(in);\n-                handleAttachment(in);\n-                break;\n-            case DubboCodec.RESPONSE_WITH_EXCEPTION_WITH_ATTACHMENTS:\n-                handleException(in);\n-                handleAttachment(in);\n-                break;\n-            default:\n-                throw new IOException(\"Unknown result flag, expect '0' '1' '2' '3' '4' '5', but received: \" + flag);\n-        }\n-        if (in instanceof Cleanable) {\n-            ((Cleanable) in).cleanup();\n-        }\n-        return this;\n-    }\n-\n-    @Override\n-    public void decode() throws Exception {\n-        if (!hasDecoded && channel != null && inputStream != null) {\n-            try {\n-                if (ConfigurationUtils.getSystemConfiguration().getBoolean(SERIALIZATION_SECURITY_CHECK_KEY, false)) {\n-                    Object serializationType_obj = invocation.get(SERIALIZATION_ID_KEY);\n-                    if (serializationType_obj != null) {\n-                        if ((byte) serializationType_obj != serializationType) {\n-                            throw new IOException(\"Unexpected serialization id:\" + serializationType + \" received from network, please check if the peer send the right id.\");\n-                        }\n-                    }\n-                }\n-                decode(channel, inputStream);\n-            } catch (Throwable e) {\n-                if (log.isWarnEnabled()) {\n-                    log.warn(\"Decode rpc result failed: \" + e.getMessage(), e);\n-                }\n-                response.setStatus(Response.CLIENT_ERROR);\n-                response.setErrorMessage(StringUtils.toString(e));\n-            } finally {\n-                hasDecoded = true;\n-            }\n-        }\n-    }\n-\n-    private void handleValue(ObjectInput in) throws IOException {\n-        try {\n-            Type[] returnTypes;\n-            if (invocation instanceof RpcInvocation) {\n-                returnTypes = ((RpcInvocation) invocation).getReturnTypes();\n-            } else {\n-                returnTypes = RpcUtils.getReturnTypes(invocation);\n-            }\n-            Object value = null;\n-            if (ArrayUtils.isEmpty(returnTypes)) {\n-                // This almost never happens?\n-                value = in.readObject();\n-            } else if (returnTypes.length == 1) {\n-                value = in.readObject((Class<?>) returnTypes[0]);\n-            } else {\n-                value = in.readObject((Class<?>) returnTypes[0], returnTypes[1]);\n-            }\n-            setValue(value);\n-        } catch (ClassNotFoundException e) {\n-            rethrow(e);\n-        }\n-    }\n-\n-    private void handleException(ObjectInput in) throws IOException {\n-        try {\n-            setException(in.readThrowable());\n-        } catch (ClassNotFoundException e) {\n-            rethrow(e);\n-        }\n-    }\n-\n-    private void handleAttachment(ObjectInput in) throws IOException {\n-        try {\n-            addObjectAttachments(in.readAttachments());\n-        } catch (ClassNotFoundException e) {\n-            rethrow(e);\n-        }\n-    }\n-\n-    private void rethrow(Exception e) throws IOException {\n-        throw new IOException(StringUtils.toString(\"Read response data failed.\", e));\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.rpc.protocol.dubbo;\r\n+\r\n+import org.apache.dubbo.common.config.ConfigurationUtils;\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.serialize.Cleanable;\r\n+import org.apache.dubbo.common.serialize.ObjectInput;\r\n+import org.apache.dubbo.common.utils.ArrayUtils;\r\n+import org.apache.dubbo.common.utils.Assert;\r\n+import org.apache.dubbo.common.utils.StringUtils;\r\n+import org.apache.dubbo.remoting.Channel;\r\n+import org.apache.dubbo.remoting.Codec;\r\n+import org.apache.dubbo.remoting.Decodeable;\r\n+import org.apache.dubbo.remoting.exchange.Response;\r\n+import org.apache.dubbo.remoting.transport.CodecSupport;\r\n+import org.apache.dubbo.rpc.AppResponse;\r\n+import org.apache.dubbo.rpc.Invocation;\r\n+import org.apache.dubbo.rpc.RpcInvocation;\r\n+import org.apache.dubbo.rpc.support.RpcUtils;\r\n+\r\n+import java.io.IOException;\r\n+import java.io.InputStream;\r\n+import java.io.OutputStream;\r\n+import java.lang.reflect.Type;\r\n+\r\n+import static org.apache.dubbo.rpc.Constants.SERIALIZATION_ID_KEY;\r\n+import static org.apache.dubbo.rpc.Constants.SERIALIZATION_SECURITY_CHECK_KEY;\r\n+\r\n+public class DecodeableRpcResult extends AppResponse implements Codec, Decodeable {\r\n+\r\n+    private static final Logger log = LoggerFactory.getLogger(DecodeableRpcResult.class);\r\n+\r\n+    private Channel channel;\r\n+\r\n+    private byte serializationType;\r\n+\r\n+    private InputStream inputStream;\r\n+\r\n+    private Response response;\r\n+\r\n+    private Invocation invocation;\r\n+\r\n+    private volatile boolean hasDecoded;\r\n+\r\n+    public DecodeableRpcResult(Channel channel, Response response, InputStream is, Invocation invocation, byte id) {\r\n+        Assert.notNull(channel, \"channel == null\");\r\n+        Assert.notNull(response, \"response == null\");\r\n+        Assert.notNull(is, \"inputStream == null\");\r\n+        this.channel = channel;\r\n+        this.response = response;\r\n+        this.inputStream = is;\r\n+        this.invocation = invocation;\r\n+        this.serializationType = id;\r\n+    }\r\n+\r\n+    @Override\r\n+    public void encode(Channel channel, OutputStream output, Object message) throws IOException {\r\n+        throw new UnsupportedOperationException();\r\n+    }\r\n+\r\n+    @Override\r\n+    public Object decode(Channel channel, InputStream input) throws IOException {\r\n+        if (log.isDebugEnabled()) {\r\n+            Thread thread = Thread.currentThread();\r\n+            log.debug(\"Decoding in thread -- [\" + thread.getName() + \"#\" + thread.getId() + \"]\");\r\n+        }\r\n+\r\n+        ObjectInput in = CodecSupport.getSerialization(channel.getUrl(), serializationType)\r\n+                .deserialize(channel.getUrl(), input);\r\n+\r\n+        byte flag = in.readByte();\r\n+        switch (flag) {\r\n+            case DubboCodec.RESPONSE_NULL_VALUE:\r\n+                break;\r\n+            case DubboCodec.RESPONSE_VALUE:\r\n+                handleValue(in);\r\n+                break;\r\n+            case DubboCodec.RESPONSE_WITH_EXCEPTION:\r\n+                handleException(in);\r\n+                break;\r\n+            case DubboCodec.RESPONSE_NULL_VALUE_WITH_ATTACHMENTS:\r\n+                handleAttachment(in);\r\n+                break;\r\n+            case DubboCodec.RESPONSE_VALUE_WITH_ATTACHMENTS:\r\n+                handleValue(in);\r\n+                handleAttachment(in);\r\n+                break;\r\n+            case DubboCodec.RESPONSE_WITH_EXCEPTION_WITH_ATTACHMENTS:\r\n+                handleException(in);\r\n+                handleAttachment(in);\r\n+                break;\r\n+            default:\r\n+                throw new IOException(\"Unknown result flag, expect '0' '1' '2' '3' '4' '5', but received: \" + flag);\r\n+        }\r\n+        if (in instanceof Cleanable) {\r\n+            ((Cleanable) in).cleanup();\r\n+        }\r\n+        return this;\r\n+    }\r\n+\r\n+    @Override\r\n+    public void decode() throws Exception {\r\n+        if (!hasDecoded && channel != null && inputStream != null) {\r\n+            try {\r\n+                if (ConfigurationUtils.getSystemConfiguration().getBoolean(SERIALIZATION_SECURITY_CHECK_KEY, false)) {\r\n+                    Object serializationType_obj = invocation.get(SERIALIZATION_ID_KEY);\r\n+                    if (serializationType_obj != null) {\r\n+                        if ((byte) serializationType_obj != serializationType) {\r\n+                            throw new IOException(\"Unexpected serialization id:\" + serializationType + \" received from network, please check if the peer send the right id.\");\r\n+                        }\r\n+                    }\r\n+                }\r\n+                decode(channel, inputStream);\r\n+            } catch (Throwable e) {\r\n+                if (log.isWarnEnabled()) {\r\n+                    log.warn(\"Decode rpc result failed: \" + e.getMessage(), e);\r\n+                }\r\n+                response.setStatus(Response.CLIENT_ERROR);\r\n+                response.setErrorMessage(StringUtils.toString(e));\r\n+            } finally {\r\n+                hasDecoded = true;\r\n+            }\r\n+        }\r\n+    }\r\n+\r\n+    private void handleValue(ObjectInput in) throws IOException {\r\n+        try {\r\n+            Type[] returnTypes;\r\n+            if (invocation instanceof RpcInvocation) {\r\n+                returnTypes = ((RpcInvocation) invocation).getReturnTypes();\r\n+            } else {\r\n+                returnTypes = RpcUtils.getReturnTypes(invocation);\r\n+            }\r\n+            Object value = null;\r\n+            if (ArrayUtils.isEmpty(returnTypes)) {\r\n+                // This almost never happens?\r\n+                value = in.readObject();\r\n+            } else if (returnTypes.length == 1) {\r\n+                value = in.readObject((Class<?>) returnTypes[0]);\r\n+            } else {\r\n+                value = in.readObject((Class<?>) returnTypes[0], returnTypes[1]);\r\n+            }\r\n+            setValue(value);\r\n+        } catch (ClassNotFoundException e) {\r\n+            rethrow(e);\r\n+        }\r\n+    }\r\n+\r\n+    private void handleException(ObjectInput in) throws IOException {\r\n+        try {\r\n+            setException(in.readThrowable());\r\n+        } catch (ClassNotFoundException e) {\r\n+            rethrow(e);\r\n+        }\r\n+    }\r\n+\r\n+    private void handleAttachment(ObjectInput in) throws IOException {\r\n+        try {\r\n+            addObjectAttachments(in.readAttachments());\r\n+        } catch (ClassNotFoundException e) {\r\n+            rethrow(e);\r\n+        }\r\n+    }\r\n+\r\n+    private void rethrow(Exception e) throws IOException {\r\n+        throw new IOException(StringUtils.toString(\"Read response data failed.\", e));\r\n+    }\r\n+}\r\n"}, {"source1": "org/apache/dubbo/rpc/protocol/dubbo/DubboCodec.java", "source2": "org/apache/dubbo/rpc/protocol/dubbo/DubboCodec.java", "comments": ["Line-ending differences only"], "unified_diff": "@@ -1,248 +1,248 @@\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.rpc.protocol.dubbo;\n-\n-import org.apache.dubbo.common.Version;\n-import org.apache.dubbo.common.io.Bytes;\n-import org.apache.dubbo.common.io.UnsafeByteArrayInputStream;\n-import org.apache.dubbo.common.logger.Logger;\n-import org.apache.dubbo.common.logger.LoggerFactory;\n-import org.apache.dubbo.common.serialize.ObjectInput;\n-import org.apache.dubbo.common.serialize.ObjectOutput;\n-import org.apache.dubbo.common.serialize.Serialization;\n-import org.apache.dubbo.common.utils.StringUtils;\n-import org.apache.dubbo.remoting.Channel;\n-import org.apache.dubbo.remoting.exchange.Request;\n-import org.apache.dubbo.remoting.exchange.Response;\n-import org.apache.dubbo.remoting.exchange.codec.ExchangeCodec;\n-import org.apache.dubbo.remoting.transport.CodecSupport;\n-import org.apache.dubbo.rpc.AppResponse;\n-import org.apache.dubbo.rpc.Invocation;\n-import org.apache.dubbo.rpc.Result;\n-import org.apache.dubbo.rpc.RpcInvocation;\n-\n-import java.io.ByteArrayInputStream;\n-import java.io.IOException;\n-import java.io.InputStream;\n-\n-import static org.apache.dubbo.common.constants.CommonConstants.DUBBO_VERSION_KEY;\n-import static org.apache.dubbo.common.constants.CommonConstants.INTERFACE_KEY;\n-import static org.apache.dubbo.common.constants.CommonConstants.PATH_KEY;\n-import static org.apache.dubbo.common.constants.CommonConstants.VERSION_KEY;\n-import static org.apache.dubbo.rpc.protocol.dubbo.CallbackServiceCodec.encodeInvocationArgument;\n-import static org.apache.dubbo.rpc.protocol.dubbo.Constants.DECODE_IN_IO_THREAD_KEY;\n-import static org.apache.dubbo.rpc.protocol.dubbo.Constants.DEFAULT_DECODE_IN_IO_THREAD;\n-\n-/**\n- * Dubbo codec.\n- */\n-public class DubboCodec extends ExchangeCodec {\n-\n-    public static final String NAME = \"dubbo\";\n-    public static final String DUBBO_VERSION = Version.getProtocolVersion();\n-    public static final byte RESPONSE_WITH_EXCEPTION = 0;\n-    public static final byte RESPONSE_VALUE = 1;\n-    public static final byte RESPONSE_NULL_VALUE = 2;\n-    public static final byte RESPONSE_WITH_EXCEPTION_WITH_ATTACHMENTS = 3;\n-    public static final byte RESPONSE_VALUE_WITH_ATTACHMENTS = 4;\n-    public static final byte RESPONSE_NULL_VALUE_WITH_ATTACHMENTS = 5;\n-    public static final Object[] EMPTY_OBJECT_ARRAY = new Object[0];\n-    public static final Class<?>[] EMPTY_CLASS_ARRAY = new Class<?>[0];\n-    private static final Logger log = LoggerFactory.getLogger(DubboCodec.class);\n-\n-    @Override\n-    protected Object decodeBody(Channel channel, InputStream is, byte[] header) throws IOException {\n-        byte flag = header[2], proto = (byte) (flag & SERIALIZATION_MASK);\n-        // get request id.\n-        long id = Bytes.bytes2long(header, 4);\n-        if ((flag & FLAG_REQUEST) == 0) {\n-            // decode response.\n-            Response res = new Response(id);\n-            if ((flag & FLAG_EVENT) != 0) {\n-                res.setEvent(true);\n-            }\n-            // get status.\n-            byte status = header[3];\n-            res.setStatus(status);\n-            try {\n-                if (status == Response.OK) {\n-                    Object data;\n-                    if (res.isEvent()) {\n-                        byte[] eventPayload = CodecSupport.getPayload(is);\n-                        if (CodecSupport.isHeartBeat(eventPayload, proto)) {\n-                            // heart beat response data is always null;\n-                            data = null;\n-                        } else {\n-                            ObjectInput in = CodecSupport.deserialize(channel.getUrl(), new ByteArrayInputStream(eventPayload), proto);\n-                            data = decodeEventData(channel, in, eventPayload);\n-                        }\n-                    } else {\n-                        DecodeableRpcResult result;\n-                        if (channel.getUrl().getParameter(DECODE_IN_IO_THREAD_KEY, DEFAULT_DECODE_IN_IO_THREAD)) {\n-                            result = new DecodeableRpcResult(channel, res, is,\n-                                    (Invocation) getRequestData(id), proto);\n-                            result.decode();\n-                        } else {\n-                            result = new DecodeableRpcResult(channel, res,\n-                                    new UnsafeByteArrayInputStream(readMessageData(is)),\n-                                    (Invocation) getRequestData(id), proto);\n-                        }\n-                        data = result;\n-                    }\n-                    res.setResult(data);\n-                } else {\n-                    ObjectInput in = CodecSupport.deserialize(channel.getUrl(), is, proto);\n-                    res.setErrorMessage(in.readUTF());\n-                }\n-            } catch (Throwable t) {\n-                if (log.isWarnEnabled()) {\n-                    log.warn(\"Decode response failed: \" + t.getMessage(), t);\n-                }\n-                res.setStatus(Response.CLIENT_ERROR);\n-                res.setErrorMessage(StringUtils.toString(t));\n-            }\n-            return res;\n-        } else {\n-            // decode request.\n-            Request req = new Request(id);\n-            req.setVersion(Version.getProtocolVersion());\n-            req.setTwoWay((flag & FLAG_TWOWAY) != 0);\n-            if ((flag & FLAG_EVENT) != 0) {\n-                req.setEvent(true);\n-            }\n-            try {\n-                Object data;\n-                if (req.isEvent()) {\n-                    byte[] eventPayload = CodecSupport.getPayload(is);\n-                    if (CodecSupport.isHeartBeat(eventPayload, proto)) {\n-                        // heart beat response data is always null;\n-                        data = null;\n-                    } else {\n-                        ObjectInput in = CodecSupport.deserialize(channel.getUrl(), new ByteArrayInputStream(eventPayload), proto);\n-                        data = decodeEventData(channel, in, eventPayload);\n-                    }\n-                } else {\n-                    DecodeableRpcInvocation inv;\n-                    if (channel.getUrl().getParameter(DECODE_IN_IO_THREAD_KEY, DEFAULT_DECODE_IN_IO_THREAD)) {\n-                        inv = new DecodeableRpcInvocation(channel, req, is, proto);\n-                        inv.decode();\n-                    } else {\n-                        inv = new DecodeableRpcInvocation(channel, req,\n-                                new UnsafeByteArrayInputStream(readMessageData(is)), proto);\n-                    }\n-                    data = inv;\n-                }\n-                req.setData(data);\n-            } catch (Throwable t) {\n-                if (log.isWarnEnabled()) {\n-                    log.warn(\"Decode request failed: \" + t.getMessage(), t);\n-                }\n-                // bad request\n-                req.setBroken(true);\n-                req.setData(t);\n-            }\n-\n-            return req;\n-        }\n-    }\n-\n-    private byte[] readMessageData(InputStream is) throws IOException {\n-        if (is.available() > 0) {\n-            byte[] result = new byte[is.available()];\n-            is.read(result);\n-            return result;\n-        }\n-        return new byte[]{};\n-    }\n-\n-    @Override\n-    protected void encodeRequestData(Channel channel, ObjectOutput out, Object data) throws IOException {\n-        encodeRequestData(channel, out, data, DUBBO_VERSION);\n-    }\n-\n-    @Override\n-    protected void encodeResponseData(Channel channel, ObjectOutput out, Object data) throws IOException {\n-        encodeResponseData(channel, out, data, DUBBO_VERSION);\n-    }\n-\n-    @Override\n-    protected void encodeRequestData(Channel channel, ObjectOutput out, Object data, String version) throws IOException {\n-        RpcInvocation inv = (RpcInvocation) data;\n-\n-        out.writeUTF(version);\n-        // https://github.com/apache/dubbo/issues/6138\n-        String serviceName = inv.getAttachment(INTERFACE_KEY);\n-        if (serviceName == null) {\n-            serviceName = inv.getAttachment(PATH_KEY);\n-        }\n-        out.writeUTF(serviceName);\n-        out.writeUTF(inv.getAttachment(VERSION_KEY));\n-\n-        out.writeUTF(inv.getMethodName());\n-        out.writeUTF(inv.getParameterTypesDesc());\n-        Object[] args = inv.getArguments();\n-        if (args != null) {\n-            for (int i = 0; i < args.length; i++) {\n-                out.writeObject(encodeInvocationArgument(channel, inv, i));\n-            }\n-        }\n-        out.writeAttachments(inv.getObjectAttachments());\n-    }\n-\n-    @Override\n-    protected void encodeResponseData(Channel channel, ObjectOutput out, Object data, String version) throws IOException {\n-        Result result = (Result) data;\n-        // currently, the version value in Response records the version of Request\n-        boolean attach = Version.isSupportResponseAttachment(version);\n-        Throwable th = result.getException();\n-        if (th == null) {\n-            Object ret = result.getValue();\n-            if (ret == null) {\n-                out.writeByte(attach ? RESPONSE_NULL_VALUE_WITH_ATTACHMENTS : RESPONSE_NULL_VALUE);\n-            } else {\n-                out.writeByte(attach ? RESPONSE_VALUE_WITH_ATTACHMENTS : RESPONSE_VALUE);\n-                out.writeObject(ret);\n-            }\n-        } else {\n-            out.writeByte(attach ? RESPONSE_WITH_EXCEPTION_WITH_ATTACHMENTS : RESPONSE_WITH_EXCEPTION);\n-            out.writeThrowable(th);\n-        }\n-\n-        if (attach) {\n-            // returns current version of Response to consumer side.\n-            result.getObjectAttachments().put(DUBBO_VERSION_KEY, Version.getProtocolVersion());\n-            out.writeAttachments(result.getObjectAttachments());\n-        }\n-    }\n-\n-    @Override\n-    protected Serialization getSerialization(Channel channel, Request req) {\n-        if (!(req.getData() instanceof Invocation)) {\n-            return super.getSerialization(channel, req);\n-        }\n-        return DubboCodecSupport.getRequestSerialization(channel.getUrl(), (Invocation) req.getData());\n-    }\n-\n-    @Override\n-    protected Serialization getSerialization(Channel channel, Response res) {\n-        if (!(res.getResult() instanceof AppResponse)) {\n-            return super.getSerialization(channel, res);\n-        }\n-        return DubboCodecSupport.getResponseSerialization(channel.getUrl(), (AppResponse) res.getResult());\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.rpc.protocol.dubbo;\r\n+\r\n+import org.apache.dubbo.common.Version;\r\n+import org.apache.dubbo.common.io.Bytes;\r\n+import org.apache.dubbo.common.io.UnsafeByteArrayInputStream;\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.serialize.ObjectInput;\r\n+import org.apache.dubbo.common.serialize.ObjectOutput;\r\n+import org.apache.dubbo.common.serialize.Serialization;\r\n+import org.apache.dubbo.common.utils.StringUtils;\r\n+import org.apache.dubbo.remoting.Channel;\r\n+import org.apache.dubbo.remoting.exchange.Request;\r\n+import org.apache.dubbo.remoting.exchange.Response;\r\n+import org.apache.dubbo.remoting.exchange.codec.ExchangeCodec;\r\n+import org.apache.dubbo.remoting.transport.CodecSupport;\r\n+import org.apache.dubbo.rpc.AppResponse;\r\n+import org.apache.dubbo.rpc.Invocation;\r\n+import org.apache.dubbo.rpc.Result;\r\n+import org.apache.dubbo.rpc.RpcInvocation;\r\n+\r\n+import java.io.ByteArrayInputStream;\r\n+import java.io.IOException;\r\n+import java.io.InputStream;\r\n+\r\n+import static org.apache.dubbo.common.constants.CommonConstants.DUBBO_VERSION_KEY;\r\n+import static org.apache.dubbo.common.constants.CommonConstants.INTERFACE_KEY;\r\n+import static org.apache.dubbo.common.constants.CommonConstants.PATH_KEY;\r\n+import static org.apache.dubbo.common.constants.CommonConstants.VERSION_KEY;\r\n+import static org.apache.dubbo.rpc.protocol.dubbo.CallbackServiceCodec.encodeInvocationArgument;\r\n+import static org.apache.dubbo.rpc.protocol.dubbo.Constants.DECODE_IN_IO_THREAD_KEY;\r\n+import static org.apache.dubbo.rpc.protocol.dubbo.Constants.DEFAULT_DECODE_IN_IO_THREAD;\r\n+\r\n+/**\r\n+ * Dubbo codec.\r\n+ */\r\n+public class DubboCodec extends ExchangeCodec {\r\n+\r\n+    public static final String NAME = \"dubbo\";\r\n+    public static final String DUBBO_VERSION = Version.getProtocolVersion();\r\n+    public static final byte RESPONSE_WITH_EXCEPTION = 0;\r\n+    public static final byte RESPONSE_VALUE = 1;\r\n+    public static final byte RESPONSE_NULL_VALUE = 2;\r\n+    public static final byte RESPONSE_WITH_EXCEPTION_WITH_ATTACHMENTS = 3;\r\n+    public static final byte RESPONSE_VALUE_WITH_ATTACHMENTS = 4;\r\n+    public static final byte RESPONSE_NULL_VALUE_WITH_ATTACHMENTS = 5;\r\n+    public static final Object[] EMPTY_OBJECT_ARRAY = new Object[0];\r\n+    public static final Class<?>[] EMPTY_CLASS_ARRAY = new Class<?>[0];\r\n+    private static final Logger log = LoggerFactory.getLogger(DubboCodec.class);\r\n+\r\n+    @Override\r\n+    protected Object decodeBody(Channel channel, InputStream is, byte[] header) throws IOException {\r\n+        byte flag = header[2], proto = (byte) (flag & SERIALIZATION_MASK);\r\n+        // get request id.\r\n+        long id = Bytes.bytes2long(header, 4);\r\n+        if ((flag & FLAG_REQUEST) == 0) {\r\n+            // decode response.\r\n+            Response res = new Response(id);\r\n+            if ((flag & FLAG_EVENT) != 0) {\r\n+                res.setEvent(true);\r\n+            }\r\n+            // get status.\r\n+            byte status = header[3];\r\n+            res.setStatus(status);\r\n+            try {\r\n+                if (status == Response.OK) {\r\n+                    Object data;\r\n+                    if (res.isEvent()) {\r\n+                        byte[] eventPayload = CodecSupport.getPayload(is);\r\n+                        if (CodecSupport.isHeartBeat(eventPayload, proto)) {\r\n+                            // heart beat response data is always null;\r\n+                            data = null;\r\n+                        } else {\r\n+                            ObjectInput in = CodecSupport.deserialize(channel.getUrl(), new ByteArrayInputStream(eventPayload), proto);\r\n+                            data = decodeEventData(channel, in, eventPayload);\r\n+                        }\r\n+                    } else {\r\n+                        DecodeableRpcResult result;\r\n+                        if (channel.getUrl().getParameter(DECODE_IN_IO_THREAD_KEY, DEFAULT_DECODE_IN_IO_THREAD)) {\r\n+                            result = new DecodeableRpcResult(channel, res, is,\r\n+                                    (Invocation) getRequestData(id), proto);\r\n+                            result.decode();\r\n+                        } else {\r\n+                            result = new DecodeableRpcResult(channel, res,\r\n+                                    new UnsafeByteArrayInputStream(readMessageData(is)),\r\n+                                    (Invocation) getRequestData(id), proto);\r\n+                        }\r\n+                        data = result;\r\n+                    }\r\n+                    res.setResult(data);\r\n+                } else {\r\n+                    ObjectInput in = CodecSupport.deserialize(channel.getUrl(), is, proto);\r\n+                    res.setErrorMessage(in.readUTF());\r\n+                }\r\n+            } catch (Throwable t) {\r\n+                if (log.isWarnEnabled()) {\r\n+                    log.warn(\"Decode response failed: \" + t.getMessage(), t);\r\n+                }\r\n+                res.setStatus(Response.CLIENT_ERROR);\r\n+                res.setErrorMessage(StringUtils.toString(t));\r\n+            }\r\n+            return res;\r\n+        } else {\r\n+            // decode request.\r\n+            Request req = new Request(id);\r\n+            req.setVersion(Version.getProtocolVersion());\r\n+            req.setTwoWay((flag & FLAG_TWOWAY) != 0);\r\n+            if ((flag & FLAG_EVENT) != 0) {\r\n+                req.setEvent(true);\r\n+            }\r\n+            try {\r\n+                Object data;\r\n+                if (req.isEvent()) {\r\n+                    byte[] eventPayload = CodecSupport.getPayload(is);\r\n+                    if (CodecSupport.isHeartBeat(eventPayload, proto)) {\r\n+                        // heart beat response data is always null;\r\n+                        data = null;\r\n+                    } else {\r\n+                        ObjectInput in = CodecSupport.deserialize(channel.getUrl(), new ByteArrayInputStream(eventPayload), proto);\r\n+                        data = decodeEventData(channel, in, eventPayload);\r\n+                    }\r\n+                } else {\r\n+                    DecodeableRpcInvocation inv;\r\n+                    if (channel.getUrl().getParameter(DECODE_IN_IO_THREAD_KEY, DEFAULT_DECODE_IN_IO_THREAD)) {\r\n+                        inv = new DecodeableRpcInvocation(channel, req, is, proto);\r\n+                        inv.decode();\r\n+                    } else {\r\n+                        inv = new DecodeableRpcInvocation(channel, req,\r\n+                                new UnsafeByteArrayInputStream(readMessageData(is)), proto);\r\n+                    }\r\n+                    data = inv;\r\n+                }\r\n+                req.setData(data);\r\n+            } catch (Throwable t) {\r\n+                if (log.isWarnEnabled()) {\r\n+                    log.warn(\"Decode request failed: \" + t.getMessage(), t);\r\n+                }\r\n+                // bad request\r\n+                req.setBroken(true);\r\n+                req.setData(t);\r\n+            }\r\n+\r\n+            return req;\r\n+        }\r\n+    }\r\n+\r\n+    private byte[] readMessageData(InputStream is) throws IOException {\r\n+        if (is.available() > 0) {\r\n+            byte[] result = new byte[is.available()];\r\n+            is.read(result);\r\n+            return result;\r\n+        }\r\n+        return new byte[]{};\r\n+    }\r\n+\r\n+    @Override\r\n+    protected void encodeRequestData(Channel channel, ObjectOutput out, Object data) throws IOException {\r\n+        encodeRequestData(channel, out, data, DUBBO_VERSION);\r\n+    }\r\n+\r\n+    @Override\r\n+    protected void encodeResponseData(Channel channel, ObjectOutput out, Object data) throws IOException {\r\n+        encodeResponseData(channel, out, data, DUBBO_VERSION);\r\n+    }\r\n+\r\n+    @Override\r\n+    protected void encodeRequestData(Channel channel, ObjectOutput out, Object data, String version) throws IOException {\r\n+        RpcInvocation inv = (RpcInvocation) data;\r\n+\r\n+        out.writeUTF(version);\r\n+        // https://github.com/apache/dubbo/issues/6138\r\n+        String serviceName = inv.getAttachment(INTERFACE_KEY);\r\n+        if (serviceName == null) {\r\n+            serviceName = inv.getAttachment(PATH_KEY);\r\n+        }\r\n+        out.writeUTF(serviceName);\r\n+        out.writeUTF(inv.getAttachment(VERSION_KEY));\r\n+\r\n+        out.writeUTF(inv.getMethodName());\r\n+        out.writeUTF(inv.getParameterTypesDesc());\r\n+        Object[] args = inv.getArguments();\r\n+        if (args != null) {\r\n+            for (int i = 0; i < args.length; i++) {\r\n+                out.writeObject(encodeInvocationArgument(channel, inv, i));\r\n+            }\r\n+        }\r\n+        out.writeAttachments(inv.getObjectAttachments());\r\n+    }\r\n+\r\n+    @Override\r\n+    protected void encodeResponseData(Channel channel, ObjectOutput out, Object data, String version) throws IOException {\r\n+        Result result = (Result) data;\r\n+        // currently, the version value in Response records the version of Request\r\n+        boolean attach = Version.isSupportResponseAttachment(version);\r\n+        Throwable th = result.getException();\r\n+        if (th == null) {\r\n+            Object ret = result.getValue();\r\n+            if (ret == null) {\r\n+                out.writeByte(attach ? RESPONSE_NULL_VALUE_WITH_ATTACHMENTS : RESPONSE_NULL_VALUE);\r\n+            } else {\r\n+                out.writeByte(attach ? RESPONSE_VALUE_WITH_ATTACHMENTS : RESPONSE_VALUE);\r\n+                out.writeObject(ret);\r\n+            }\r\n+        } else {\r\n+            out.writeByte(attach ? RESPONSE_WITH_EXCEPTION_WITH_ATTACHMENTS : RESPONSE_WITH_EXCEPTION);\r\n+            out.writeThrowable(th);\r\n+        }\r\n+\r\n+        if (attach) {\r\n+            // returns current version of Response to consumer side.\r\n+            result.getObjectAttachments().put(DUBBO_VERSION_KEY, Version.getProtocolVersion());\r\n+            out.writeAttachments(result.getObjectAttachments());\r\n+        }\r\n+    }\r\n+\r\n+    @Override\r\n+    protected Serialization getSerialization(Channel channel, Request req) {\r\n+        if (!(req.getData() instanceof Invocation)) {\r\n+            return super.getSerialization(channel, req);\r\n+        }\r\n+        return DubboCodecSupport.getRequestSerialization(channel.getUrl(), (Invocation) req.getData());\r\n+    }\r\n+\r\n+    @Override\r\n+    protected Serialization getSerialization(Channel channel, Response res) {\r\n+        if (!(res.getResult() instanceof AppResponse)) {\r\n+            return super.getSerialization(channel, res);\r\n+        }\r\n+        return DubboCodecSupport.getResponseSerialization(channel.getUrl(), (AppResponse) res.getResult());\r\n+    }\r\n+\r\n+}\r\n"}, {"source1": "org/apache/dubbo/rpc/protocol/dubbo/DubboCodecSupport.java", "source2": "org/apache/dubbo/rpc/protocol/dubbo/DubboCodecSupport.java", "comments": ["Line-ending differences only"], "unified_diff": "@@ -1,53 +1,53 @@\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.rpc.protocol.dubbo;\n-\n-import org.apache.dubbo.common.URL;\n-import org.apache.dubbo.common.extension.ExtensionLoader;\n-import org.apache.dubbo.common.serialize.Serialization;\n-import org.apache.dubbo.remoting.Constants;\n-import org.apache.dubbo.remoting.transport.CodecSupport;\n-import org.apache.dubbo.rpc.AppResponse;\n-import org.apache.dubbo.rpc.Invocation;\n-\n-import static org.apache.dubbo.rpc.Constants.INVOCATION_KEY;\n-import static org.apache.dubbo.rpc.Constants.SERIALIZATION_ID_KEY;\n-\n-public class DubboCodecSupport {\n-\n-    public static Serialization getRequestSerialization(URL url, Invocation invocation) {\n-        Object serializationType_obj = invocation.get(SERIALIZATION_ID_KEY);\n-        if (serializationType_obj != null) {\n-            return CodecSupport.getSerializationById((byte) serializationType_obj);\n-        }\n-        return ExtensionLoader.getExtensionLoader(Serialization.class).getExtension(\n-                url.getParameter(org.apache.dubbo.remoting.Constants.SERIALIZATION_KEY, Constants.DEFAULT_REMOTING_SERIALIZATION));\n-    }\n-\n-    public static Serialization getResponseSerialization(URL url, AppResponse appResponse) {\n-        Object invocation_obj = appResponse.getAttribute(INVOCATION_KEY);\n-        if (invocation_obj != null) {\n-            Invocation invocation = (Invocation) invocation_obj;\n-            Object serializationType_obj = invocation.get(SERIALIZATION_ID_KEY);\n-            if (serializationType_obj != null) {\n-                return CodecSupport.getSerializationById((byte) serializationType_obj);\n-            }\n-        }\n-        return ExtensionLoader.getExtensionLoader(Serialization.class).getExtension(\n-                url.getParameter(Constants.SERIALIZATION_KEY, Constants.DEFAULT_REMOTING_SERIALIZATION));\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.rpc.protocol.dubbo;\r\n+\r\n+import org.apache.dubbo.common.URL;\r\n+import org.apache.dubbo.common.extension.ExtensionLoader;\r\n+import org.apache.dubbo.common.serialize.Serialization;\r\n+import org.apache.dubbo.remoting.Constants;\r\n+import org.apache.dubbo.remoting.transport.CodecSupport;\r\n+import org.apache.dubbo.rpc.AppResponse;\r\n+import org.apache.dubbo.rpc.Invocation;\r\n+\r\n+import static org.apache.dubbo.rpc.Constants.INVOCATION_KEY;\r\n+import static org.apache.dubbo.rpc.Constants.SERIALIZATION_ID_KEY;\r\n+\r\n+public class DubboCodecSupport {\r\n+\r\n+    public static Serialization getRequestSerialization(URL url, Invocation invocation) {\r\n+        Object serializationType_obj = invocation.get(SERIALIZATION_ID_KEY);\r\n+        if (serializationType_obj != null) {\r\n+            return CodecSupport.getSerializationById((byte) serializationType_obj);\r\n+        }\r\n+        return ExtensionLoader.getExtensionLoader(Serialization.class).getExtension(\r\n+                url.getParameter(org.apache.dubbo.remoting.Constants.SERIALIZATION_KEY, Constants.DEFAULT_REMOTING_SERIALIZATION));\r\n+    }\r\n+\r\n+    public static Serialization getResponseSerialization(URL url, AppResponse appResponse) {\r\n+        Object invocation_obj = appResponse.getAttribute(INVOCATION_KEY);\r\n+        if (invocation_obj != null) {\r\n+            Invocation invocation = (Invocation) invocation_obj;\r\n+            Object serializationType_obj = invocation.get(SERIALIZATION_ID_KEY);\r\n+            if (serializationType_obj != null) {\r\n+                return CodecSupport.getSerializationById((byte) serializationType_obj);\r\n+            }\r\n+        }\r\n+        return ExtensionLoader.getExtensionLoader(Serialization.class).getExtension(\r\n+                url.getParameter(Constants.SERIALIZATION_KEY, Constants.DEFAULT_REMOTING_SERIALIZATION));\r\n+    }\r\n+}\r\n"}, {"source1": "org/apache/dubbo/rpc/protocol/dubbo/DubboCountCodec.java", "source2": "org/apache/dubbo/rpc/protocol/dubbo/DubboCountCodec.java", "comments": ["Line-ending differences only"], "unified_diff": "@@ -1,86 +1,86 @@\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-\n-package org.apache.dubbo.rpc.protocol.dubbo;\n-\n-import org.apache.dubbo.remoting.Channel;\n-import org.apache.dubbo.remoting.Codec2;\n-import org.apache.dubbo.remoting.buffer.ChannelBuffer;\n-import org.apache.dubbo.remoting.exchange.Request;\n-import org.apache.dubbo.remoting.exchange.Response;\n-import org.apache.dubbo.remoting.exchange.support.MultiMessage;\n-import org.apache.dubbo.rpc.AppResponse;\n-import org.apache.dubbo.rpc.RpcInvocation;\n-\n-import java.io.IOException;\n-\n-import static org.apache.dubbo.rpc.Constants.INPUT_KEY;\n-import static org.apache.dubbo.rpc.Constants.OUTPUT_KEY;\n-\n-public final class DubboCountCodec implements Codec2 {\n-\n-    private DubboCodec codec = new DubboCodec();\n-\n-    @Override\n-    public void encode(Channel channel, ChannelBuffer buffer, Object msg) throws IOException {\n-        codec.encode(channel, buffer, msg);\n-    }\n-\n-    @Override\n-    public Object decode(Channel channel, ChannelBuffer buffer) throws IOException {\n-        int save = buffer.readerIndex();\n-        MultiMessage result = MultiMessage.create();\n-        do {\n-            Object obj = codec.decode(channel, buffer);\n-            if (Codec2.DecodeResult.NEED_MORE_INPUT == obj) {\n-                buffer.readerIndex(save);\n-                break;\n-            } else {\n-                result.addMessage(obj);\n-                logMessageLength(obj, buffer.readerIndex() - save);\n-                save = buffer.readerIndex();\n-            }\n-        } while (true);\n-        if (result.isEmpty()) {\n-            return Codec2.DecodeResult.NEED_MORE_INPUT;\n-        }\n-        if (result.size() == 1) {\n-            return result.get(0);\n-        }\n-        return result;\n-    }\n-\n-    private void logMessageLength(Object result, int bytes) {\n-        if (bytes <= 0) {\n-            return;\n-        }\n-        if (result instanceof Request) {\n-            try {\n-                ((RpcInvocation) ((Request) result).getData()).setAttachment(INPUT_KEY, String.valueOf(bytes));\n-            } catch (Throwable e) {\n-                /* ignore */\n-            }\n-        } else if (result instanceof Response) {\n-            try {\n-                ((AppResponse) ((Response) result).getResult()).setAttachment(OUTPUT_KEY, String.valueOf(bytes));\n-            } catch (Throwable e) {\n-                /* ignore */\n-            }\n-        }\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+\r\n+package org.apache.dubbo.rpc.protocol.dubbo;\r\n+\r\n+import org.apache.dubbo.remoting.Channel;\r\n+import org.apache.dubbo.remoting.Codec2;\r\n+import org.apache.dubbo.remoting.buffer.ChannelBuffer;\r\n+import org.apache.dubbo.remoting.exchange.Request;\r\n+import org.apache.dubbo.remoting.exchange.Response;\r\n+import org.apache.dubbo.remoting.exchange.support.MultiMessage;\r\n+import org.apache.dubbo.rpc.AppResponse;\r\n+import org.apache.dubbo.rpc.RpcInvocation;\r\n+\r\n+import java.io.IOException;\r\n+\r\n+import static org.apache.dubbo.rpc.Constants.INPUT_KEY;\r\n+import static org.apache.dubbo.rpc.Constants.OUTPUT_KEY;\r\n+\r\n+public final class DubboCountCodec implements Codec2 {\r\n+\r\n+    private DubboCodec codec = new DubboCodec();\r\n+\r\n+    @Override\r\n+    public void encode(Channel channel, ChannelBuffer buffer, Object msg) throws IOException {\r\n+        codec.encode(channel, buffer, msg);\r\n+    }\r\n+\r\n+    @Override\r\n+    public Object decode(Channel channel, ChannelBuffer buffer) throws IOException {\r\n+        int save = buffer.readerIndex();\r\n+        MultiMessage result = MultiMessage.create();\r\n+        do {\r\n+            Object obj = codec.decode(channel, buffer);\r\n+            if (Codec2.DecodeResult.NEED_MORE_INPUT == obj) {\r\n+                buffer.readerIndex(save);\r\n+                break;\r\n+            } else {\r\n+                result.addMessage(obj);\r\n+                logMessageLength(obj, buffer.readerIndex() - save);\r\n+                save = buffer.readerIndex();\r\n+            }\r\n+        } while (true);\r\n+        if (result.isEmpty()) {\r\n+            return Codec2.DecodeResult.NEED_MORE_INPUT;\r\n+        }\r\n+        if (result.size() == 1) {\r\n+            return result.get(0);\r\n+        }\r\n+        return result;\r\n+    }\r\n+\r\n+    private void logMessageLength(Object result, int bytes) {\r\n+        if (bytes <= 0) {\r\n+            return;\r\n+        }\r\n+        if (result instanceof Request) {\r\n+            try {\r\n+                ((RpcInvocation) ((Request) result).getData()).setAttachment(INPUT_KEY, String.valueOf(bytes));\r\n+            } catch (Throwable e) {\r\n+                /* ignore */\r\n+            }\r\n+        } else if (result instanceof Response) {\r\n+            try {\r\n+                ((AppResponse) ((Response) result).getResult()).setAttachment(OUTPUT_KEY, String.valueOf(bytes));\r\n+            } catch (Throwable e) {\r\n+                /* ignore */\r\n+            }\r\n+        }\r\n+    }\r\n+\r\n+}\r\n"}, {"source1": "org/apache/dubbo/rpc/protocol/dubbo/DubboExporter.java", "source2": "org/apache/dubbo/rpc/protocol/dubbo/DubboExporter.java", "comments": ["Line-ending differences only"], "unified_diff": "@@ -1,45 +1,45 @@\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.rpc.protocol.dubbo;\n-\n-import org.apache.dubbo.rpc.Exporter;\n-import org.apache.dubbo.rpc.Invoker;\n-import org.apache.dubbo.rpc.protocol.AbstractExporter;\n-\n-import java.util.Map;\n-\n-/**\n- * DubboExporter\n- */\n-public class DubboExporter<T> extends AbstractExporter<T> {\n-\n-    private final String key;\n-\n-    private final Map<String, Exporter<?>> exporterMap;\n-\n-    public DubboExporter(Invoker<T> invoker, String key, Map<String, Exporter<?>> exporterMap) {\n-        super(invoker);\n-        this.key = key;\n-        this.exporterMap = exporterMap;\n-    }\n-\n-    @Override\n-    public void afterUnExport() {\n-        exporterMap.remove(key);\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.rpc.protocol.dubbo;\r\n+\r\n+import org.apache.dubbo.rpc.Exporter;\r\n+import org.apache.dubbo.rpc.Invoker;\r\n+import org.apache.dubbo.rpc.protocol.AbstractExporter;\r\n+\r\n+import java.util.Map;\r\n+\r\n+/**\r\n+ * DubboExporter\r\n+ */\r\n+public class DubboExporter<T> extends AbstractExporter<T> {\r\n+\r\n+    private final String key;\r\n+\r\n+    private final Map<String, Exporter<?>> exporterMap;\r\n+\r\n+    public DubboExporter(Invoker<T> invoker, String key, Map<String, Exporter<?>> exporterMap) {\r\n+        super(invoker);\r\n+        this.key = key;\r\n+        this.exporterMap = exporterMap;\r\n+    }\r\n+\r\n+    @Override\r\n+    public void afterUnExport() {\r\n+        exporterMap.remove(key);\r\n+    }\r\n+\r\n }\n"}, {"source1": "org/apache/dubbo/rpc/protocol/dubbo/DubboInvoker.java", "source2": "org/apache/dubbo/rpc/protocol/dubbo/DubboInvoker.java", "comments": ["Line-ending differences only"], "unified_diff": "@@ -1,183 +1,183 @@\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.rpc.protocol.dubbo;\n-\n-import org.apache.dubbo.common.URL;\n-import org.apache.dubbo.common.config.ConfigurationUtils;\n-import org.apache.dubbo.common.utils.AtomicPositiveInteger;\n-import org.apache.dubbo.remoting.Constants;\n-import org.apache.dubbo.remoting.RemotingException;\n-import org.apache.dubbo.remoting.TimeoutException;\n-import org.apache.dubbo.remoting.exchange.ExchangeClient;\n-import org.apache.dubbo.rpc.AppResponse;\n-import org.apache.dubbo.rpc.AsyncRpcResult;\n-import org.apache.dubbo.rpc.FutureContext;\n-import org.apache.dubbo.rpc.Invocation;\n-import org.apache.dubbo.rpc.Invoker;\n-import org.apache.dubbo.rpc.Result;\n-import org.apache.dubbo.rpc.RpcContext;\n-import org.apache.dubbo.rpc.RpcException;\n-import org.apache.dubbo.rpc.RpcInvocation;\n-import org.apache.dubbo.rpc.TimeoutCountDown;\n-import org.apache.dubbo.rpc.protocol.AbstractInvoker;\n-import org.apache.dubbo.rpc.support.RpcUtils;\n-\n-import java.util.Set;\n-import java.util.concurrent.CompletableFuture;\n-import java.util.concurrent.ExecutorService;\n-import java.util.concurrent.TimeUnit;\n-import java.util.concurrent.locks.ReentrantLock;\n-\n-import static org.apache.dubbo.common.constants.CommonConstants.DEFAULT_TIMEOUT;\n-import static org.apache.dubbo.common.constants.CommonConstants.DEFAULT_VERSION;\n-import static org.apache.dubbo.common.constants.CommonConstants.ENABLE_TIMEOUT_COUNTDOWN_KEY;\n-import static org.apache.dubbo.common.constants.CommonConstants.GROUP_KEY;\n-import static org.apache.dubbo.common.constants.CommonConstants.INTERFACE_KEY;\n-import static org.apache.dubbo.common.constants.CommonConstants.PATH_KEY;\n-import static org.apache.dubbo.common.constants.CommonConstants.TIMEOUT_ATTACHMENT_KEY;\n-import static org.apache.dubbo.common.constants.CommonConstants.TIMEOUT_KEY;\n-import static org.apache.dubbo.common.constants.CommonConstants.TIME_COUNTDOWN_KEY;\n-import static org.apache.dubbo.common.constants.CommonConstants.VERSION_KEY;\n-import static org.apache.dubbo.rpc.Constants.TOKEN_KEY;\n-\n-/**\n- * DubboInvoker\n- */\n-public class DubboInvoker<T> extends AbstractInvoker<T> {\n-\n-    private final ExchangeClient[] clients;\n-\n-    private final AtomicPositiveInteger index = new AtomicPositiveInteger();\n-\n-    private final String version;\n-\n-    private final ReentrantLock destroyLock = new ReentrantLock();\n-\n-    private final Set<Invoker<?>> invokers;\n-\n-    public DubboInvoker(Class<T> serviceType, URL url, ExchangeClient[] clients) {\n-        this(serviceType, url, clients, null);\n-    }\n-\n-    public DubboInvoker(Class<T> serviceType, URL url, ExchangeClient[] clients, Set<Invoker<?>> invokers) {\n-        super(serviceType, url, new String[]{INTERFACE_KEY, GROUP_KEY, TOKEN_KEY});\n-        this.clients = clients;\n-        // get version.\n-        this.version = url.getParameter(VERSION_KEY, DEFAULT_VERSION);\n-        this.invokers = invokers;\n-    }\n-\n-    @Override\n-    protected Result doInvoke(final Invocation invocation) throws Throwable {\n-        RpcInvocation inv = (RpcInvocation) invocation;\n-        final String methodName = RpcUtils.getMethodName(invocation);\n-        inv.setAttachment(PATH_KEY, getUrl().getPath());\n-        inv.setAttachment(VERSION_KEY, version);\n-\n-        ExchangeClient currentClient;\n-        if (clients.length == 1) {\n-            currentClient = clients[0];\n-        } else {\n-            currentClient = clients[index.getAndIncrement() % clients.length];\n-        }\n-        try {\n-            boolean isOneway = RpcUtils.isOneway(getUrl(), invocation);\n-            int timeout = calculateTimeout(invocation, methodName);\n-            invocation.put(TIMEOUT_KEY, timeout);\n-            if (isOneway) {\n-                boolean isSent = getUrl().getMethodParameter(methodName, Constants.SENT_KEY, false);\n-                currentClient.send(inv, isSent);\n-                return AsyncRpcResult.newDefaultAsyncResult(invocation);\n-            } else {\n-                ExecutorService executor = getCallbackExecutor(getUrl(), inv);\n-                CompletableFuture<AppResponse> appResponseFuture =\n-                        currentClient.request(inv, timeout, executor).thenApply(obj -> (AppResponse) obj);\n-                // save for 2.6.x compatibility, for example, TraceFilter in Zipkin uses com.alibaba.xxx.FutureAdapter\n-                FutureContext.getContext().setCompatibleFuture(appResponseFuture);\n-                AsyncRpcResult result = new AsyncRpcResult(appResponseFuture, inv);\n-                result.setExecutor(executor);\n-                return result;\n-            }\n-        } catch (TimeoutException e) {\n-            throw new RpcException(RpcException.TIMEOUT_EXCEPTION, \"Invoke remote method timeout. method: \" + invocation.getMethodName() + \", provider: \" + getUrl() + \", cause: \" + e.getMessage(), e);\n-        } catch (RemotingException e) {\n-            throw new RpcException(RpcException.NETWORK_EXCEPTION, \"Failed to invoke remote method: \" + invocation.getMethodName() + \", provider: \" + getUrl() + \", cause: \" + e.getMessage(), e);\n-        }\n-    }\n-\n-    @Override\n-    public boolean isAvailable() {\n-        if (!super.isAvailable()) {\n-            return false;\n-        }\n-        for (ExchangeClient client : clients) {\n-            if (client.isConnected() && !client.hasAttribute(Constants.CHANNEL_ATTRIBUTE_READONLY_KEY)) {\n-                //cannot write == not Available ?\n-                return true;\n-            }\n-        }\n-        return false;\n-    }\n-\n-    @Override\n-    public void destroy() {\n-        // in order to avoid closing a client multiple times, a counter is used in case of connection per jvm, every\n-        // time when client.close() is called, counter counts down once, and when counter reaches zero, client will be\n-        // closed.\n-        if (super.isDestroyed()) {\n-            return;\n-        } else {\n-            // double check to avoid dup close\n-            destroyLock.lock();\n-            try {\n-                if (super.isDestroyed()) {\n-                    return;\n-                }\n-                super.destroy();\n-                if (invokers != null) {\n-                    invokers.remove(this);\n-                }\n-                for (ExchangeClient client : clients) {\n-                    try {\n-                        client.close(ConfigurationUtils.getServerShutdownTimeout());\n-                    } catch (Throwable t) {\n-                        logger.warn(t.getMessage(), t);\n-                    }\n-                }\n-\n-            } finally {\n-                destroyLock.unlock();\n-            }\n-        }\n-    }\n-\n-    private int calculateTimeout(Invocation invocation, String methodName) {\n-        Object countdown = RpcContext.getContext().get(TIME_COUNTDOWN_KEY);\n-        int timeout = DEFAULT_TIMEOUT;\n-        if (countdown == null) {\n-            timeout = (int) RpcUtils.getTimeout(getUrl(), methodName, RpcContext.getContext(), DEFAULT_TIMEOUT);\n-            if (getUrl().getParameter(ENABLE_TIMEOUT_COUNTDOWN_KEY, false)) {\n-                invocation.setObjectAttachment(TIMEOUT_ATTACHMENT_KEY, timeout); // pass timeout to remote server\n-            }\n-        } else {\n-            TimeoutCountDown timeoutCountDown = (TimeoutCountDown) countdown;\n-            timeout = (int) timeoutCountDown.timeRemaining(TimeUnit.MILLISECONDS);\n-            invocation.setObjectAttachment(TIMEOUT_ATTACHMENT_KEY, timeout);// pass timeout to remote server\n-        }\n-        return timeout;\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.rpc.protocol.dubbo;\r\n+\r\n+import org.apache.dubbo.common.URL;\r\n+import org.apache.dubbo.common.config.ConfigurationUtils;\r\n+import org.apache.dubbo.common.utils.AtomicPositiveInteger;\r\n+import org.apache.dubbo.remoting.Constants;\r\n+import org.apache.dubbo.remoting.RemotingException;\r\n+import org.apache.dubbo.remoting.TimeoutException;\r\n+import org.apache.dubbo.remoting.exchange.ExchangeClient;\r\n+import org.apache.dubbo.rpc.AppResponse;\r\n+import org.apache.dubbo.rpc.AsyncRpcResult;\r\n+import org.apache.dubbo.rpc.FutureContext;\r\n+import org.apache.dubbo.rpc.Invocation;\r\n+import org.apache.dubbo.rpc.Invoker;\r\n+import org.apache.dubbo.rpc.Result;\r\n+import org.apache.dubbo.rpc.RpcContext;\r\n+import org.apache.dubbo.rpc.RpcException;\r\n+import org.apache.dubbo.rpc.RpcInvocation;\r\n+import org.apache.dubbo.rpc.TimeoutCountDown;\r\n+import org.apache.dubbo.rpc.protocol.AbstractInvoker;\r\n+import org.apache.dubbo.rpc.support.RpcUtils;\r\n+\r\n+import java.util.Set;\r\n+import java.util.concurrent.CompletableFuture;\r\n+import java.util.concurrent.ExecutorService;\r\n+import java.util.concurrent.TimeUnit;\r\n+import java.util.concurrent.locks.ReentrantLock;\r\n+\r\n+import static org.apache.dubbo.common.constants.CommonConstants.DEFAULT_TIMEOUT;\r\n+import static org.apache.dubbo.common.constants.CommonConstants.DEFAULT_VERSION;\r\n+import static org.apache.dubbo.common.constants.CommonConstants.ENABLE_TIMEOUT_COUNTDOWN_KEY;\r\n+import static org.apache.dubbo.common.constants.CommonConstants.GROUP_KEY;\r\n+import static org.apache.dubbo.common.constants.CommonConstants.INTERFACE_KEY;\r\n+import static org.apache.dubbo.common.constants.CommonConstants.PATH_KEY;\r\n+import static org.apache.dubbo.common.constants.CommonConstants.TIMEOUT_ATTACHMENT_KEY;\r\n+import static org.apache.dubbo.common.constants.CommonConstants.TIMEOUT_KEY;\r\n+import static org.apache.dubbo.common.constants.CommonConstants.TIME_COUNTDOWN_KEY;\r\n+import static org.apache.dubbo.common.constants.CommonConstants.VERSION_KEY;\r\n+import static org.apache.dubbo.rpc.Constants.TOKEN_KEY;\r\n+\r\n+/**\r\n+ * DubboInvoker\r\n+ */\r\n+public class DubboInvoker<T> extends AbstractInvoker<T> {\r\n+\r\n+    private final ExchangeClient[] clients;\r\n+\r\n+    private final AtomicPositiveInteger index = new AtomicPositiveInteger();\r\n+\r\n+    private final String version;\r\n+\r\n+    private final ReentrantLock destroyLock = new ReentrantLock();\r\n+\r\n+    private final Set<Invoker<?>> invokers;\r\n+\r\n+    public DubboInvoker(Class<T> serviceType, URL url, ExchangeClient[] clients) {\r\n+        this(serviceType, url, clients, null);\r\n+    }\r\n+\r\n+    public DubboInvoker(Class<T> serviceType, URL url, ExchangeClient[] clients, Set<Invoker<?>> invokers) {\r\n+        super(serviceType, url, new String[]{INTERFACE_KEY, GROUP_KEY, TOKEN_KEY});\r\n+        this.clients = clients;\r\n+        // get version.\r\n+        this.version = url.getParameter(VERSION_KEY, DEFAULT_VERSION);\r\n+        this.invokers = invokers;\r\n+    }\r\n+\r\n+    @Override\r\n+    protected Result doInvoke(final Invocation invocation) throws Throwable {\r\n+        RpcInvocation inv = (RpcInvocation) invocation;\r\n+        final String methodName = RpcUtils.getMethodName(invocation);\r\n+        inv.setAttachment(PATH_KEY, getUrl().getPath());\r\n+        inv.setAttachment(VERSION_KEY, version);\r\n+\r\n+        ExchangeClient currentClient;\r\n+        if (clients.length == 1) {\r\n+            currentClient = clients[0];\r\n+        } else {\r\n+            currentClient = clients[index.getAndIncrement() % clients.length];\r\n+        }\r\n+        try {\r\n+            boolean isOneway = RpcUtils.isOneway(getUrl(), invocation);\r\n+            int timeout = calculateTimeout(invocation, methodName);\r\n+            invocation.put(TIMEOUT_KEY, timeout);\r\n+            if (isOneway) {\r\n+                boolean isSent = getUrl().getMethodParameter(methodName, Constants.SENT_KEY, false);\r\n+                currentClient.send(inv, isSent);\r\n+                return AsyncRpcResult.newDefaultAsyncResult(invocation);\r\n+            } else {\r\n+                ExecutorService executor = getCallbackExecutor(getUrl(), inv);\r\n+                CompletableFuture<AppResponse> appResponseFuture =\r\n+                        currentClient.request(inv, timeout, executor).thenApply(obj -> (AppResponse) obj);\r\n+                // save for 2.6.x compatibility, for example, TraceFilter in Zipkin uses com.alibaba.xxx.FutureAdapter\r\n+                FutureContext.getContext().setCompatibleFuture(appResponseFuture);\r\n+                AsyncRpcResult result = new AsyncRpcResult(appResponseFuture, inv);\r\n+                result.setExecutor(executor);\r\n+                return result;\r\n+            }\r\n+        } catch (TimeoutException e) {\r\n+            throw new RpcException(RpcException.TIMEOUT_EXCEPTION, \"Invoke remote method timeout. method: \" + invocation.getMethodName() + \", provider: \" + getUrl() + \", cause: \" + e.getMessage(), e);\r\n+        } catch (RemotingException e) {\r\n+            throw new RpcException(RpcException.NETWORK_EXCEPTION, \"Failed to invoke remote method: \" + invocation.getMethodName() + \", provider: \" + getUrl() + \", cause: \" + e.getMessage(), e);\r\n+        }\r\n+    }\r\n+\r\n+    @Override\r\n+    public boolean isAvailable() {\r\n+        if (!super.isAvailable()) {\r\n+            return false;\r\n+        }\r\n+        for (ExchangeClient client : clients) {\r\n+            if (client.isConnected() && !client.hasAttribute(Constants.CHANNEL_ATTRIBUTE_READONLY_KEY)) {\r\n+                //cannot write == not Available ?\r\n+                return true;\r\n+            }\r\n+        }\r\n+        return false;\r\n+    }\r\n+\r\n+    @Override\r\n+    public void destroy() {\r\n+        // in order to avoid closing a client multiple times, a counter is used in case of connection per jvm, every\r\n+        // time when client.close() is called, counter counts down once, and when counter reaches zero, client will be\r\n+        // closed.\r\n+        if (super.isDestroyed()) {\r\n+            return;\r\n+        } else {\r\n+            // double check to avoid dup close\r\n+            destroyLock.lock();\r\n+            try {\r\n+                if (super.isDestroyed()) {\r\n+                    return;\r\n+                }\r\n+                super.destroy();\r\n+                if (invokers != null) {\r\n+                    invokers.remove(this);\r\n+                }\r\n+                for (ExchangeClient client : clients) {\r\n+                    try {\r\n+                        client.close(ConfigurationUtils.getServerShutdownTimeout());\r\n+                    } catch (Throwable t) {\r\n+                        logger.warn(t.getMessage(), t);\r\n+                    }\r\n+                }\r\n+\r\n+            } finally {\r\n+                destroyLock.unlock();\r\n+            }\r\n+        }\r\n+    }\r\n+\r\n+    private int calculateTimeout(Invocation invocation, String methodName) {\r\n+        Object countdown = RpcContext.getContext().get(TIME_COUNTDOWN_KEY);\r\n+        int timeout = DEFAULT_TIMEOUT;\r\n+        if (countdown == null) {\r\n+            timeout = (int) RpcUtils.getTimeout(getUrl(), methodName, RpcContext.getContext(), DEFAULT_TIMEOUT);\r\n+            if (getUrl().getParameter(ENABLE_TIMEOUT_COUNTDOWN_KEY, false)) {\r\n+                invocation.setObjectAttachment(TIMEOUT_ATTACHMENT_KEY, timeout); // pass timeout to remote server\r\n+            }\r\n+        } else {\r\n+            TimeoutCountDown timeoutCountDown = (TimeoutCountDown) countdown;\r\n+            timeout = (int) timeoutCountDown.timeRemaining(TimeUnit.MILLISECONDS);\r\n+            invocation.setObjectAttachment(TIMEOUT_ATTACHMENT_KEY, timeout);// pass timeout to remote server\r\n+        }\r\n+        return timeout;\r\n+    }\r\n+}\r\n"}, {"source1": "org/apache/dubbo/rpc/protocol/dubbo/DubboProtocol.java", "source2": "org/apache/dubbo/rpc/protocol/dubbo/DubboProtocol.java", "comments": ["Line-ending differences only"], "unified_diff": "@@ -1,686 +1,686 @@\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.rpc.protocol.dubbo;\n-\n-import org.apache.dubbo.common.URL;\n-import org.apache.dubbo.common.URLBuilder;\n-import org.apache.dubbo.common.config.ConfigurationUtils;\n-import org.apache.dubbo.common.extension.ExtensionLoader;\n-import org.apache.dubbo.common.serialize.support.SerializableClassRegistry;\n-import org.apache.dubbo.common.serialize.support.SerializationOptimizer;\n-import org.apache.dubbo.common.utils.CollectionUtils;\n-import org.apache.dubbo.common.utils.ConcurrentHashSet;\n-import org.apache.dubbo.common.utils.ConfigUtils;\n-import org.apache.dubbo.common.utils.NetUtils;\n-import org.apache.dubbo.common.utils.StringUtils;\n-import org.apache.dubbo.remoting.Channel;\n-import org.apache.dubbo.remoting.RemotingException;\n-import org.apache.dubbo.remoting.RemotingServer;\n-import org.apache.dubbo.remoting.Transporter;\n-import org.apache.dubbo.remoting.exchange.ExchangeChannel;\n-import org.apache.dubbo.remoting.exchange.ExchangeClient;\n-import org.apache.dubbo.remoting.exchange.ExchangeHandler;\n-import org.apache.dubbo.remoting.exchange.ExchangeServer;\n-import org.apache.dubbo.remoting.exchange.Exchangers;\n-import org.apache.dubbo.remoting.exchange.support.ExchangeHandlerAdapter;\n-import org.apache.dubbo.rpc.Exporter;\n-import org.apache.dubbo.rpc.Invocation;\n-import org.apache.dubbo.rpc.Invoker;\n-import org.apache.dubbo.rpc.Protocol;\n-import org.apache.dubbo.rpc.ProtocolServer;\n-import org.apache.dubbo.rpc.Result;\n-import org.apache.dubbo.rpc.RpcContext;\n-import org.apache.dubbo.rpc.RpcException;\n-import org.apache.dubbo.rpc.RpcInvocation;\n-import org.apache.dubbo.rpc.protocol.AbstractProtocol;\n-\n-import java.net.InetSocketAddress;\n-import java.util.ArrayList;\n-import java.util.Collection;\n-import java.util.Collections;\n-import java.util.List;\n-import java.util.Map;\n-import java.util.Set;\n-import java.util.concurrent.CompletableFuture;\n-import java.util.concurrent.ConcurrentHashMap;\n-import java.util.concurrent.ConcurrentMap;\n-import java.util.function.Function;\n-\n-import static org.apache.dubbo.common.constants.CommonConstants.GROUP_KEY;\n-import static org.apache.dubbo.common.constants.CommonConstants.INTERFACE_KEY;\n-import static org.apache.dubbo.common.constants.CommonConstants.LAZY_CONNECT_KEY;\n-import static org.apache.dubbo.common.constants.CommonConstants.PATH_KEY;\n-import static org.apache.dubbo.common.constants.CommonConstants.STUB_EVENT_KEY;\n-import static org.apache.dubbo.common.constants.CommonConstants.VERSION_KEY;\n-import static org.apache.dubbo.remoting.Constants.CHANNEL_READONLYEVENT_SENT_KEY;\n-import static org.apache.dubbo.remoting.Constants.CLIENT_KEY;\n-import static org.apache.dubbo.remoting.Constants.CODEC_KEY;\n-import static org.apache.dubbo.remoting.Constants.CONNECTIONS_KEY;\n-import static org.apache.dubbo.remoting.Constants.DEFAULT_HEARTBEAT;\n-import static org.apache.dubbo.remoting.Constants.DEFAULT_REMOTING_CLIENT;\n-import static org.apache.dubbo.remoting.Constants.HEARTBEAT_KEY;\n-import static org.apache.dubbo.remoting.Constants.SERVER_KEY;\n-import static org.apache.dubbo.rpc.Constants.DEFAULT_REMOTING_SERVER;\n-import static org.apache.dubbo.rpc.Constants.DEFAULT_STUB_EVENT;\n-import static org.apache.dubbo.rpc.Constants.IS_SERVER_KEY;\n-import static org.apache.dubbo.rpc.Constants.STUB_EVENT_METHODS_KEY;\n-import static org.apache.dubbo.rpc.protocol.dubbo.Constants.CALLBACK_SERVICE_KEY;\n-import static org.apache.dubbo.rpc.protocol.dubbo.Constants.DEFAULT_SHARE_CONNECTIONS;\n-import static org.apache.dubbo.rpc.protocol.dubbo.Constants.IS_CALLBACK_SERVICE;\n-import static org.apache.dubbo.rpc.protocol.dubbo.Constants.ON_CONNECT_KEY;\n-import static org.apache.dubbo.rpc.protocol.dubbo.Constants.ON_DISCONNECT_KEY;\n-import static org.apache.dubbo.rpc.protocol.dubbo.Constants.OPTIMIZER_KEY;\n-import static org.apache.dubbo.rpc.protocol.dubbo.Constants.SHARE_CONNECTIONS_KEY;\n-\n-\n-/**\n- * dubbo protocol support.\n- */\n-public class DubboProtocol extends AbstractProtocol {\n-\n-    public static final String NAME = \"dubbo\";\n-\n-    public static final int DEFAULT_PORT = 20880;\n-    private static final String IS_CALLBACK_SERVICE_INVOKE = \"_isCallBackServiceInvoke\";\n-    private static DubboProtocol INSTANCE;\n-\n-    /**\n-     * <host:port,Exchanger>\n-     */\n-    private final Map<String, List<ReferenceCountExchangeClient>> referenceClientMap = new ConcurrentHashMap<>();\n-    private final ConcurrentMap<String, Object> locks = new ConcurrentHashMap<>();\n-    private final Set<String> optimizers = new ConcurrentHashSet<>();\n-\n-    private ExchangeHandler requestHandler = new ExchangeHandlerAdapter() {\n-\n-        @Override\n-        public CompletableFuture<Object> reply(ExchangeChannel channel, Object message) throws RemotingException {\n-\n-            if (!(message instanceof Invocation)) {\n-                throw new RemotingException(channel, \"Unsupported request: \"\n-                        + (message == null ? null : (message.getClass().getName() + \": \" + message))\n-                        + \", channel: consumer: \" + channel.getRemoteAddress() + \" --> provider: \" + channel.getLocalAddress());\n-            }\n-\n-            Invocation inv = (Invocation) message;\n-            Invoker<?> invoker = getInvoker(channel, inv);\n-            // need to consider backward-compatibility if it's a callback\n-            if (Boolean.TRUE.toString().equals(inv.getObjectAttachments().get(IS_CALLBACK_SERVICE_INVOKE))) {\n-                String methodsStr = invoker.getUrl().getParameters().get(\"methods\");\n-                boolean hasMethod = false;\n-                if (methodsStr == null || !methodsStr.contains(\",\")) {\n-                    hasMethod = inv.getMethodName().equals(methodsStr);\n-                } else {\n-                    String[] methods = methodsStr.split(\",\");\n-                    for (String method : methods) {\n-                        if (inv.getMethodName().equals(method)) {\n-                            hasMethod = true;\n-                            break;\n-                        }\n-                    }\n-                }\n-                if (!hasMethod) {\n-                    logger.warn(new IllegalStateException(\"The methodName \" + inv.getMethodName()\n-                            + \" not found in callback service interface ,invoke will be ignored.\"\n-                            + \" please update the api interface. url is:\"\n-                            + invoker.getUrl()) + \" ,invocation is :\" + inv);\n-                    return null;\n-                }\n-            }\n-            RpcContext.getContext().setRemoteAddress(channel.getRemoteAddress());\n-            Result result = invoker.invoke(inv);\n-            return result.thenApply(Function.identity());\n-        }\n-\n-        @Override\n-        public void received(Channel channel, Object message) throws RemotingException {\n-            if (message instanceof Invocation) {\n-                reply((ExchangeChannel) channel, message);\n-\n-            } else {\n-                super.received(channel, message);\n-            }\n-        }\n-\n-        @Override\n-        public void connected(Channel channel) throws RemotingException {\n-            invoke(channel, ON_CONNECT_KEY);\n-        }\n-\n-        @Override\n-        public void disconnected(Channel channel) throws RemotingException {\n-            if (logger.isDebugEnabled()) {\n-                logger.debug(\"disconnected from \" + channel.getRemoteAddress() + \",url:\" + channel.getUrl());\n-            }\n-            invoke(channel, ON_DISCONNECT_KEY);\n-        }\n-\n-        private void invoke(Channel channel, String methodKey) {\n-            Invocation invocation = createInvocation(channel, channel.getUrl(), methodKey);\n-            if (invocation != null) {\n-                try {\n-                    received(channel, invocation);\n-                } catch (Throwable t) {\n-                    logger.warn(\"Failed to invoke event method \" + invocation.getMethodName() + \"(), cause: \" + t.getMessage(), t);\n-                }\n-            }\n-        }\n-\n-        /**\n-         * FIXME channel.getUrl() always binds to a fixed service, and this service is random.\n-         * we can choose to use a common service to carry onConnect event if there's no easy way to get the specific\n-         * service this connection is binding to.\n-         * @param channel\n-         * @param url\n-         * @param methodKey\n-         * @return\n-         */\n-        private Invocation createInvocation(Channel channel, URL url, String methodKey) {\n-            String method = url.getParameter(methodKey);\n-            if (method == null || method.length() == 0) {\n-                return null;\n-            }\n-\n-            RpcInvocation invocation = new RpcInvocation(method, url.getParameter(INTERFACE_KEY), \"\", new Class<?>[0], new Object[0]);\n-            invocation.setAttachment(PATH_KEY, url.getPath());\n-            invocation.setAttachment(GROUP_KEY, url.getParameter(GROUP_KEY));\n-            invocation.setAttachment(INTERFACE_KEY, url.getParameter(INTERFACE_KEY));\n-            invocation.setAttachment(VERSION_KEY, url.getParameter(VERSION_KEY));\n-            if (url.getParameter(STUB_EVENT_KEY, false)) {\n-                invocation.setAttachment(STUB_EVENT_KEY, Boolean.TRUE.toString());\n-            }\n-\n-            return invocation;\n-        }\n-    };\n-\n-    public DubboProtocol() {\n-        INSTANCE = this;\n-    }\n-\n-    public static DubboProtocol getDubboProtocol() {\n-        if (INSTANCE == null) {\n-            // load\n-            ExtensionLoader.getExtensionLoader(Protocol.class).getExtension(DubboProtocol.NAME);\n-        }\n-\n-        return INSTANCE;\n-    }\n-\n-    @Override\n-    public Collection<Exporter<?>> getExporters() {\n-        return Collections.unmodifiableCollection(exporterMap.values());\n-    }\n-\n-    private boolean isClientSide(Channel channel) {\n-        InetSocketAddress address = channel.getRemoteAddress();\n-        URL url = channel.getUrl();\n-        return url.getPort() == address.getPort() &&\n-                NetUtils.filterLocalHost(channel.getUrl().getIp())\n-                        .equals(NetUtils.filterLocalHost(address.getAddress().getHostAddress()));\n-    }\n-\n-    Invoker<?> getInvoker(Channel channel, Invocation inv) throws RemotingException {\n-        boolean isCallBackServiceInvoke = false;\n-        boolean isStubServiceInvoke = false;\n-        int port = channel.getLocalAddress().getPort();\n-        String path = (String) inv.getObjectAttachments().get(PATH_KEY);\n-\n-        // if it's callback service on client side\n-        isStubServiceInvoke = Boolean.TRUE.toString().equals(inv.getObjectAttachments().get(STUB_EVENT_KEY));\n-        if (isStubServiceInvoke) {\n-            port = channel.getRemoteAddress().getPort();\n-        }\n-\n-        //callback\n-        isCallBackServiceInvoke = isClientSide(channel) && !isStubServiceInvoke;\n-        if (isCallBackServiceInvoke) {\n-            path += \".\" + inv.getObjectAttachments().get(CALLBACK_SERVICE_KEY);\n-            inv.getObjectAttachments().put(IS_CALLBACK_SERVICE_INVOKE, Boolean.TRUE.toString());\n-        }\n-\n-        String serviceKey = serviceKey(\n-                port,\n-                path,\n-                (String) inv.getObjectAttachments().get(VERSION_KEY),\n-                (String) inv.getObjectAttachments().get(GROUP_KEY)\n-        );\n-        DubboExporter<?> exporter = (DubboExporter<?>) exporterMap.get(serviceKey);\n-\n-        if (exporter == null) {\n-            throw new RemotingException(channel, \"Not found exported service: \" + serviceKey + \" in \" + exporterMap.keySet() + \", may be version or group mismatch \" +\n-                    \", channel: consumer: \" + channel.getRemoteAddress() + \" --> provider: \" + channel.getLocalAddress() + \", message:\" + getInvocationWithoutData(inv));\n-        }\n-\n-        return exporter.getInvoker();\n-    }\n-\n-    public Collection<Invoker<?>> getInvokers() {\n-        return Collections.unmodifiableCollection(invokers);\n-    }\n-\n-    @Override\n-    public int getDefaultPort() {\n-        return DEFAULT_PORT;\n-    }\n-\n-    @Override\n-    public <T> Exporter<T> export(Invoker<T> invoker) throws RpcException {\n-        URL url = invoker.getUrl();\n-\n-        // export service.\n-        String key = serviceKey(url);\n-        DubboExporter<T> exporter = new DubboExporter<T>(invoker, key, exporterMap);\n-        exporterMap.put(key, exporter);\n-\n-        //export an stub service for dispatching event\n-        Boolean isStubSupportEvent = url.getParameter(STUB_EVENT_KEY, DEFAULT_STUB_EVENT);\n-        Boolean isCallbackservice = url.getParameter(IS_CALLBACK_SERVICE, false);\n-        if (isStubSupportEvent && !isCallbackservice) {\n-            String stubServiceMethods = url.getParameter(STUB_EVENT_METHODS_KEY);\n-            if (stubServiceMethods == null || stubServiceMethods.length() == 0) {\n-                if (logger.isWarnEnabled()) {\n-                    logger.warn(new IllegalStateException(\"consumer [\" + url.getParameter(INTERFACE_KEY) +\n-                            \"], has set stubproxy support event ,but no stub methods founded.\"));\n-                }\n-\n-            }\n-        }\n-\n-        openServer(url);\n-        optimizeSerialization(url);\n-\n-        return exporter;\n-    }\n-\n-    private void openServer(URL url) {\n-        // find server.\n-        String key = url.getAddress();\n-        //client can export a service which's only for server to invoke\n-        boolean isServer = url.getParameter(IS_SERVER_KEY, true);\n-        if (isServer) {\n-            ProtocolServer server = serverMap.get(key);\n-            if (server == null) {\n-                synchronized (this) {\n-                    server = serverMap.get(key);\n-                    if (server == null) {\n-                        serverMap.put(key, createServer(url));\n-                    }\n-                }\n-            } else {\n-                // server supports reset, use together with override\n-                server.reset(url);\n-            }\n-        }\n-    }\n-\n-    private ProtocolServer createServer(URL url) {\n-        url = URLBuilder.from(url)\n-                // send readonly event when server closes, it's enabled by default\n-                .addParameterIfAbsent(CHANNEL_READONLYEVENT_SENT_KEY, Boolean.TRUE.toString())\n-                // enable heartbeat by default\n-                .addParameterIfAbsent(HEARTBEAT_KEY, String.valueOf(DEFAULT_HEARTBEAT))\n-                .addParameter(CODEC_KEY, DubboCodec.NAME)\n-                .build();\n-        String str = url.getParameter(SERVER_KEY, DEFAULT_REMOTING_SERVER);\n-\n-        if (str != null && str.length() > 0 && !ExtensionLoader.getExtensionLoader(Transporter.class).hasExtension(str)) {\n-            throw new RpcException(\"Unsupported server type: \" + str + \", url: \" + url);\n-        }\n-\n-        ExchangeServer server;\n-        try {\n-            server = Exchangers.bind(url, requestHandler);\n-        } catch (RemotingException e) {\n-            throw new RpcException(\"Fail to start server(url: \" + url + \") \" + e.getMessage(), e);\n-        }\n-\n-        str = url.getParameter(CLIENT_KEY);\n-        if (str != null && str.length() > 0) {\n-            Set<String> supportedTypes = ExtensionLoader.getExtensionLoader(Transporter.class).getSupportedExtensions();\n-            if (!supportedTypes.contains(str)) {\n-                throw new RpcException(\"Unsupported client type: \" + str);\n-            }\n-        }\n-\n-        return new DubboProtocolServer(server);\n-    }\n-\n-    private void optimizeSerialization(URL url) throws RpcException {\n-        String className = url.getParameter(OPTIMIZER_KEY, \"\");\n-        if (StringUtils.isEmpty(className) || optimizers.contains(className)) {\n-            return;\n-        }\n-\n-        logger.info(\"Optimizing the serialization process for Kryo, FST, etc...\");\n-\n-        try {\n-            Class clazz = Thread.currentThread().getContextClassLoader().loadClass(className);\n-            if (!SerializationOptimizer.class.isAssignableFrom(clazz)) {\n-                throw new RpcException(\"The serialization optimizer \" + className + \" isn't an instance of \" + SerializationOptimizer.class.getName());\n-            }\n-\n-            SerializationOptimizer optimizer = (SerializationOptimizer) clazz.newInstance();\n-\n-            if (optimizer.getSerializableClasses() == null) {\n-                return;\n-            }\n-\n-            for (Class c : optimizer.getSerializableClasses()) {\n-                SerializableClassRegistry.registerClass(c);\n-            }\n-\n-            optimizers.add(className);\n-\n-        } catch (ClassNotFoundException e) {\n-            throw new RpcException(\"Cannot find the serialization optimizer class: \" + className, e);\n-\n-        } catch (InstantiationException | IllegalAccessException e) {\n-            throw new RpcException(\"Cannot instantiate the serialization optimizer class: \" + className, e);\n-\n-        }\n-    }\n-\n-    @Override\n-    public <T> Invoker<T> protocolBindingRefer(Class<T> serviceType, URL url) throws RpcException {\n-        optimizeSerialization(url);\n-\n-        // create rpc invoker.\n-        DubboInvoker<T> invoker = new DubboInvoker<T>(serviceType, url, getClients(url), invokers);\n-        invokers.add(invoker);\n-\n-        return invoker;\n-    }\n-\n-    private ExchangeClient[] getClients(URL url) {\n-        // whether to share connection\n-\n-        boolean useShareConnect = false;\n-\n-        int connections = url.getParameter(CONNECTIONS_KEY, 0);\n-        List<ReferenceCountExchangeClient> shareClients = null;\n-        // if not configured, connection is shared, otherwise, one connection for one service\n-        if (connections == 0) {\n-            useShareConnect = true;\n-\n-            /*\n-             * The xml configuration should have a higher priority than properties.\n-             */\n-            String shareConnectionsStr = url.getParameter(SHARE_CONNECTIONS_KEY, (String) null);\n-            connections = Integer.parseInt(StringUtils.isBlank(shareConnectionsStr) ? ConfigUtils.getProperty(SHARE_CONNECTIONS_KEY,\n-                    DEFAULT_SHARE_CONNECTIONS) : shareConnectionsStr);\n-            shareClients = getSharedClient(url, connections);\n-        }\n-\n-        ExchangeClient[] clients = new ExchangeClient[connections];\n-        for (int i = 0; i < clients.length; i++) {\n-            if (useShareConnect) {\n-                clients[i] = shareClients.get(i);\n-\n-            } else {\n-                clients[i] = initClient(url);\n-            }\n-        }\n-\n-        return clients;\n-    }\n-\n-    /**\n-     * Get shared connection\n-     *\n-     * @param url\n-     * @param connectNum connectNum must be greater than or equal to 1\n-     */\n-    private List<ReferenceCountExchangeClient> getSharedClient(URL url, int connectNum) {\n-        String key = url.getAddress();\n-        List<ReferenceCountExchangeClient> clients = referenceClientMap.get(key);\n-\n-        if (checkClientCanUse(clients)) {\n-            batchClientRefIncr(clients);\n-            return clients;\n-        }\n-\n-        locks.putIfAbsent(key, new Object());\n-        synchronized (locks.get(key)) {\n-            clients = referenceClientMap.get(key);\n-            // double check\n-            if (checkClientCanUse(clients)) {\n-                batchClientRefIncr(clients);\n-                return clients;\n-            }\n-\n-            // connectNum must be greater than or equal to 1\n-            connectNum = Math.max(connectNum, 1);\n-\n-            // If the clients is empty, then the first initialization is\n-            if (CollectionUtils.isEmpty(clients)) {\n-                clients = buildReferenceCountExchangeClientList(url, connectNum);\n-                referenceClientMap.put(key, clients);\n-\n-            } else {\n-                for (int i = 0; i < clients.size(); i++) {\n-                    ReferenceCountExchangeClient referenceCountExchangeClient = clients.get(i);\n-                    // If there is a client in the list that is no longer available, create a new one to replace him.\n-                    if (referenceCountExchangeClient == null || referenceCountExchangeClient.isClosed()) {\n-                        clients.set(i, buildReferenceCountExchangeClient(url));\n-                        continue;\n-                    }\n-\n-                    referenceCountExchangeClient.incrementAndGetCount();\n-                }\n-            }\n-\n-            /*\n-             * I understand that the purpose of the remove operation here is to avoid the expired url key\n-             * always occupying this memory space.\n-             * But \"locks.remove(key);\" can lead to \"synchronized (locks.get(key)) {\" NPE, considering that the key of locks is \"IP + port\",\n-             * it will not lead to the expansion of \"locks\" in theory, so I will annotate it here.\n-             */\n-//            locks.remove(key);\n-\n-            return clients;\n-        }\n-    }\n-\n-    /**\n-     * Check if the client list is all available\n-     *\n-     * @param referenceCountExchangeClients\n-     * @return true-available\uff0cfalse-unavailable\n-     */\n-    private boolean checkClientCanUse(List<ReferenceCountExchangeClient> referenceCountExchangeClients) {\n-        if (CollectionUtils.isEmpty(referenceCountExchangeClients)) {\n-            return false;\n-        }\n-\n-        for (ReferenceCountExchangeClient referenceCountExchangeClient : referenceCountExchangeClients) {\n-            // As long as one client is not available, you need to replace the unavailable client with the available one.\n-            if (referenceCountExchangeClient == null || referenceCountExchangeClient.getCount() <= 0 || referenceCountExchangeClient.isClosed()) {\n-                return false;\n-            }\n-        }\n-\n-        return true;\n-    }\n-\n-    /**\n-     * Increase the reference Count if we create new invoker shares same connection, the connection will be closed without any reference.\n-     *\n-     * @param referenceCountExchangeClients\n-     */\n-    private void batchClientRefIncr(List<ReferenceCountExchangeClient> referenceCountExchangeClients) {\n-        if (CollectionUtils.isEmpty(referenceCountExchangeClients)) {\n-            return;\n-        }\n-\n-        for (ReferenceCountExchangeClient referenceCountExchangeClient : referenceCountExchangeClients) {\n-            if (referenceCountExchangeClient != null) {\n-                referenceCountExchangeClient.incrementAndGetCount();\n-            }\n-        }\n-    }\n-\n-    /**\n-     * Bulk build client\n-     *\n-     * @param url\n-     * @param connectNum\n-     * @return\n-     */\n-    private List<ReferenceCountExchangeClient> buildReferenceCountExchangeClientList(URL url, int connectNum) {\n-        List<ReferenceCountExchangeClient> clients = new ArrayList<>();\n-\n-        for (int i = 0; i < connectNum; i++) {\n-            clients.add(buildReferenceCountExchangeClient(url));\n-        }\n-\n-        return clients;\n-    }\n-\n-    /**\n-     * Build a single client\n-     *\n-     * @param url\n-     * @return\n-     */\n-    private ReferenceCountExchangeClient buildReferenceCountExchangeClient(URL url) {\n-        ExchangeClient exchangeClient = initClient(url);\n-\n-        return new ReferenceCountExchangeClient(exchangeClient);\n-    }\n-\n-    /**\n-     * Create new connection\n-     *\n-     * @param url\n-     */\n-    private ExchangeClient initClient(URL url) {\n-\n-        // client type setting.\n-        String str = url.getParameter(CLIENT_KEY, url.getParameter(SERVER_KEY, DEFAULT_REMOTING_CLIENT));\n-\n-        url = url.addParameter(CODEC_KEY, DubboCodec.NAME);\n-        // enable heartbeat by default\n-        url = url.addParameterIfAbsent(HEARTBEAT_KEY, String.valueOf(DEFAULT_HEARTBEAT));\n-\n-        // BIO is not allowed since it has severe performance issue.\n-        if (str != null && str.length() > 0 && !ExtensionLoader.getExtensionLoader(Transporter.class).hasExtension(str)) {\n-            throw new RpcException(\"Unsupported client type: \" + str + \",\" +\n-                    \" supported client type is \" + StringUtils.join(ExtensionLoader.getExtensionLoader(Transporter.class).getSupportedExtensions(), \" \"));\n-        }\n-\n-        ExchangeClient client;\n-        try {\n-            // connection should be lazy\n-            if (url.getParameter(LAZY_CONNECT_KEY, false)) {\n-                client = new LazyConnectExchangeClient(url, requestHandler);\n-\n-            } else {\n-                client = Exchangers.connect(url, requestHandler);\n-            }\n-\n-        } catch (RemotingException e) {\n-            throw new RpcException(\"Fail to create remoting client for service(\" + url + \"): \" + e.getMessage(), e);\n-        }\n-\n-        return client;\n-    }\n-\n-    @Override\n-    public void destroy() {\n-        for (String key : new ArrayList<>(serverMap.keySet())) {\n-            ProtocolServer protocolServer = serverMap.remove(key);\n-\n-            if (protocolServer == null) {\n-                continue;\n-            }\n-\n-            RemotingServer server = protocolServer.getRemotingServer();\n-\n-            try {\n-                if (logger.isInfoEnabled()) {\n-                    logger.info(\"Close dubbo server: \" + server.getLocalAddress());\n-                }\n-\n-                server.close(ConfigurationUtils.getServerShutdownTimeout());\n-\n-            } catch (Throwable t) {\n-                logger.warn(t.getMessage(), t);\n-            }\n-        }\n-\n-        for (String key : new ArrayList<>(referenceClientMap.keySet())) {\n-            List<ReferenceCountExchangeClient> clients = referenceClientMap.remove(key);\n-\n-            if (CollectionUtils.isEmpty(clients)) {\n-                continue;\n-            }\n-\n-            for (ReferenceCountExchangeClient client : clients) {\n-                closeReferenceCountExchangeClient(client);\n-            }\n-        }\n-\n-        super.destroy();\n-    }\n-\n-    /**\n-     * close ReferenceCountExchangeClient\n-     *\n-     * @param client\n-     */\n-    private void closeReferenceCountExchangeClient(ReferenceCountExchangeClient client) {\n-        if (client == null) {\n-            return;\n-        }\n-\n-        try {\n-            if (logger.isInfoEnabled()) {\n-                logger.info(\"Close dubbo connect: \" + client.getLocalAddress() + \"-->\" + client.getRemoteAddress());\n-            }\n-\n-            client.close(ConfigurationUtils.getServerShutdownTimeout());\n-\n-            // TODO\n-            /*\n-             * At this time, ReferenceCountExchangeClient#client has been replaced with LazyConnectExchangeClient.\n-             * Do you need to call client.close again to ensure that LazyConnectExchangeClient is also closed?\n-             */\n-\n-        } catch (Throwable t) {\n-            logger.warn(t.getMessage(), t);\n-        }\n-    }\n-\n-    /**\n-     * only log body in debugger mode for size & security consideration.\n-     *\n-     * @param invocation\n-     * @return\n-     */\n-    private Invocation getInvocationWithoutData(Invocation invocation) {\n-        if (logger.isDebugEnabled()) {\n-            return invocation;\n-        }\n-        if (invocation instanceof RpcInvocation) {\n-            RpcInvocation rpcInvocation = (RpcInvocation) invocation;\n-            rpcInvocation.setArguments(null);\n-            return rpcInvocation;\n-        }\n-        return invocation;\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.rpc.protocol.dubbo;\r\n+\r\n+import org.apache.dubbo.common.URL;\r\n+import org.apache.dubbo.common.URLBuilder;\r\n+import org.apache.dubbo.common.config.ConfigurationUtils;\r\n+import org.apache.dubbo.common.extension.ExtensionLoader;\r\n+import org.apache.dubbo.common.serialize.support.SerializableClassRegistry;\r\n+import org.apache.dubbo.common.serialize.support.SerializationOptimizer;\r\n+import org.apache.dubbo.common.utils.CollectionUtils;\r\n+import org.apache.dubbo.common.utils.ConcurrentHashSet;\r\n+import org.apache.dubbo.common.utils.ConfigUtils;\r\n+import org.apache.dubbo.common.utils.NetUtils;\r\n+import org.apache.dubbo.common.utils.StringUtils;\r\n+import org.apache.dubbo.remoting.Channel;\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+import org.apache.dubbo.remoting.exchange.ExchangeChannel;\r\n+import org.apache.dubbo.remoting.exchange.ExchangeClient;\r\n+import org.apache.dubbo.remoting.exchange.ExchangeHandler;\r\n+import org.apache.dubbo.remoting.exchange.ExchangeServer;\r\n+import org.apache.dubbo.remoting.exchange.Exchangers;\r\n+import org.apache.dubbo.remoting.exchange.support.ExchangeHandlerAdapter;\r\n+import org.apache.dubbo.rpc.Exporter;\r\n+import org.apache.dubbo.rpc.Invocation;\r\n+import org.apache.dubbo.rpc.Invoker;\r\n+import org.apache.dubbo.rpc.Protocol;\r\n+import org.apache.dubbo.rpc.ProtocolServer;\r\n+import org.apache.dubbo.rpc.Result;\r\n+import org.apache.dubbo.rpc.RpcContext;\r\n+import org.apache.dubbo.rpc.RpcException;\r\n+import org.apache.dubbo.rpc.RpcInvocation;\r\n+import org.apache.dubbo.rpc.protocol.AbstractProtocol;\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.Collections;\r\n+import java.util.List;\r\n+import java.util.Map;\r\n+import java.util.Set;\r\n+import java.util.concurrent.CompletableFuture;\r\n+import java.util.concurrent.ConcurrentHashMap;\r\n+import java.util.concurrent.ConcurrentMap;\r\n+import java.util.function.Function;\r\n+\r\n+import static org.apache.dubbo.common.constants.CommonConstants.GROUP_KEY;\r\n+import static org.apache.dubbo.common.constants.CommonConstants.INTERFACE_KEY;\r\n+import static org.apache.dubbo.common.constants.CommonConstants.LAZY_CONNECT_KEY;\r\n+import static org.apache.dubbo.common.constants.CommonConstants.PATH_KEY;\r\n+import static org.apache.dubbo.common.constants.CommonConstants.STUB_EVENT_KEY;\r\n+import static org.apache.dubbo.common.constants.CommonConstants.VERSION_KEY;\r\n+import static org.apache.dubbo.remoting.Constants.CHANNEL_READONLYEVENT_SENT_KEY;\r\n+import static org.apache.dubbo.remoting.Constants.CLIENT_KEY;\r\n+import static org.apache.dubbo.remoting.Constants.CODEC_KEY;\r\n+import static org.apache.dubbo.remoting.Constants.CONNECTIONS_KEY;\r\n+import static org.apache.dubbo.remoting.Constants.DEFAULT_HEARTBEAT;\r\n+import static org.apache.dubbo.remoting.Constants.DEFAULT_REMOTING_CLIENT;\r\n+import static org.apache.dubbo.remoting.Constants.HEARTBEAT_KEY;\r\n+import static org.apache.dubbo.remoting.Constants.SERVER_KEY;\r\n+import static org.apache.dubbo.rpc.Constants.DEFAULT_REMOTING_SERVER;\r\n+import static org.apache.dubbo.rpc.Constants.DEFAULT_STUB_EVENT;\r\n+import static org.apache.dubbo.rpc.Constants.IS_SERVER_KEY;\r\n+import static org.apache.dubbo.rpc.Constants.STUB_EVENT_METHODS_KEY;\r\n+import static org.apache.dubbo.rpc.protocol.dubbo.Constants.CALLBACK_SERVICE_KEY;\r\n+import static org.apache.dubbo.rpc.protocol.dubbo.Constants.DEFAULT_SHARE_CONNECTIONS;\r\n+import static org.apache.dubbo.rpc.protocol.dubbo.Constants.IS_CALLBACK_SERVICE;\r\n+import static org.apache.dubbo.rpc.protocol.dubbo.Constants.ON_CONNECT_KEY;\r\n+import static org.apache.dubbo.rpc.protocol.dubbo.Constants.ON_DISCONNECT_KEY;\r\n+import static org.apache.dubbo.rpc.protocol.dubbo.Constants.OPTIMIZER_KEY;\r\n+import static org.apache.dubbo.rpc.protocol.dubbo.Constants.SHARE_CONNECTIONS_KEY;\r\n+\r\n+\r\n+/**\r\n+ * dubbo protocol support.\r\n+ */\r\n+public class DubboProtocol extends AbstractProtocol {\r\n+\r\n+    public static final String NAME = \"dubbo\";\r\n+\r\n+    public static final int DEFAULT_PORT = 20880;\r\n+    private static final String IS_CALLBACK_SERVICE_INVOKE = \"_isCallBackServiceInvoke\";\r\n+    private static DubboProtocol INSTANCE;\r\n+\r\n+    /**\r\n+     * <host:port,Exchanger>\r\n+     */\r\n+    private final Map<String, List<ReferenceCountExchangeClient>> referenceClientMap = new ConcurrentHashMap<>();\r\n+    private final ConcurrentMap<String, Object> locks = new ConcurrentHashMap<>();\r\n+    private final Set<String> optimizers = new ConcurrentHashSet<>();\r\n+\r\n+    private ExchangeHandler requestHandler = new ExchangeHandlerAdapter() {\r\n+\r\n+        @Override\r\n+        public CompletableFuture<Object> reply(ExchangeChannel channel, Object message) throws RemotingException {\r\n+\r\n+            if (!(message instanceof Invocation)) {\r\n+                throw new RemotingException(channel, \"Unsupported request: \"\r\n+                        + (message == null ? null : (message.getClass().getName() + \": \" + message))\r\n+                        + \", channel: consumer: \" + channel.getRemoteAddress() + \" --> provider: \" + channel.getLocalAddress());\r\n+            }\r\n+\r\n+            Invocation inv = (Invocation) message;\r\n+            Invoker<?> invoker = getInvoker(channel, inv);\r\n+            // need to consider backward-compatibility if it's a callback\r\n+            if (Boolean.TRUE.toString().equals(inv.getObjectAttachments().get(IS_CALLBACK_SERVICE_INVOKE))) {\r\n+                String methodsStr = invoker.getUrl().getParameters().get(\"methods\");\r\n+                boolean hasMethod = false;\r\n+                if (methodsStr == null || !methodsStr.contains(\",\")) {\r\n+                    hasMethod = inv.getMethodName().equals(methodsStr);\r\n+                } else {\r\n+                    String[] methods = methodsStr.split(\",\");\r\n+                    for (String method : methods) {\r\n+                        if (inv.getMethodName().equals(method)) {\r\n+                            hasMethod = true;\r\n+                            break;\r\n+                        }\r\n+                    }\r\n+                }\r\n+                if (!hasMethod) {\r\n+                    logger.warn(new IllegalStateException(\"The methodName \" + inv.getMethodName()\r\n+                            + \" not found in callback service interface ,invoke will be ignored.\"\r\n+                            + \" please update the api interface. url is:\"\r\n+                            + invoker.getUrl()) + \" ,invocation is :\" + inv);\r\n+                    return null;\r\n+                }\r\n+            }\r\n+            RpcContext.getContext().setRemoteAddress(channel.getRemoteAddress());\r\n+            Result result = invoker.invoke(inv);\r\n+            return result.thenApply(Function.identity());\r\n+        }\r\n+\r\n+        @Override\r\n+        public void received(Channel channel, Object message) throws RemotingException {\r\n+            if (message instanceof Invocation) {\r\n+                reply((ExchangeChannel) channel, message);\r\n+\r\n+            } else {\r\n+                super.received(channel, message);\r\n+            }\r\n+        }\r\n+\r\n+        @Override\r\n+        public void connected(Channel channel) throws RemotingException {\r\n+            invoke(channel, ON_CONNECT_KEY);\r\n+        }\r\n+\r\n+        @Override\r\n+        public void disconnected(Channel channel) throws RemotingException {\r\n+            if (logger.isDebugEnabled()) {\r\n+                logger.debug(\"disconnected from \" + channel.getRemoteAddress() + \",url:\" + channel.getUrl());\r\n+            }\r\n+            invoke(channel, ON_DISCONNECT_KEY);\r\n+        }\r\n+\r\n+        private void invoke(Channel channel, String methodKey) {\r\n+            Invocation invocation = createInvocation(channel, channel.getUrl(), methodKey);\r\n+            if (invocation != null) {\r\n+                try {\r\n+                    received(channel, invocation);\r\n+                } catch (Throwable t) {\r\n+                    logger.warn(\"Failed to invoke event method \" + invocation.getMethodName() + \"(), cause: \" + t.getMessage(), t);\r\n+                }\r\n+            }\r\n+        }\r\n+\r\n+        /**\r\n+         * FIXME channel.getUrl() always binds to a fixed service, and this service is random.\r\n+         * we can choose to use a common service to carry onConnect event if there's no easy way to get the specific\r\n+         * service this connection is binding to.\r\n+         * @param channel\r\n+         * @param url\r\n+         * @param methodKey\r\n+         * @return\r\n+         */\r\n+        private Invocation createInvocation(Channel channel, URL url, String methodKey) {\r\n+            String method = url.getParameter(methodKey);\r\n+            if (method == null || method.length() == 0) {\r\n+                return null;\r\n+            }\r\n+\r\n+            RpcInvocation invocation = new RpcInvocation(method, url.getParameter(INTERFACE_KEY), \"\", new Class<?>[0], new Object[0]);\r\n+            invocation.setAttachment(PATH_KEY, url.getPath());\r\n+            invocation.setAttachment(GROUP_KEY, url.getParameter(GROUP_KEY));\r\n+            invocation.setAttachment(INTERFACE_KEY, url.getParameter(INTERFACE_KEY));\r\n+            invocation.setAttachment(VERSION_KEY, url.getParameter(VERSION_KEY));\r\n+            if (url.getParameter(STUB_EVENT_KEY, false)) {\r\n+                invocation.setAttachment(STUB_EVENT_KEY, Boolean.TRUE.toString());\r\n+            }\r\n+\r\n+            return invocation;\r\n+        }\r\n+    };\r\n+\r\n+    public DubboProtocol() {\r\n+        INSTANCE = this;\r\n+    }\r\n+\r\n+    public static DubboProtocol getDubboProtocol() {\r\n+        if (INSTANCE == null) {\r\n+            // load\r\n+            ExtensionLoader.getExtensionLoader(Protocol.class).getExtension(DubboProtocol.NAME);\r\n+        }\r\n+\r\n+        return INSTANCE;\r\n+    }\r\n+\r\n+    @Override\r\n+    public Collection<Exporter<?>> getExporters() {\r\n+        return Collections.unmodifiableCollection(exporterMap.values());\r\n+    }\r\n+\r\n+    private boolean isClientSide(Channel channel) {\r\n+        InetSocketAddress address = channel.getRemoteAddress();\r\n+        URL url = channel.getUrl();\r\n+        return url.getPort() == address.getPort() &&\r\n+                NetUtils.filterLocalHost(channel.getUrl().getIp())\r\n+                        .equals(NetUtils.filterLocalHost(address.getAddress().getHostAddress()));\r\n+    }\r\n+\r\n+    Invoker<?> getInvoker(Channel channel, Invocation inv) throws RemotingException {\r\n+        boolean isCallBackServiceInvoke = false;\r\n+        boolean isStubServiceInvoke = false;\r\n+        int port = channel.getLocalAddress().getPort();\r\n+        String path = (String) inv.getObjectAttachments().get(PATH_KEY);\r\n+\r\n+        // if it's callback service on client side\r\n+        isStubServiceInvoke = Boolean.TRUE.toString().equals(inv.getObjectAttachments().get(STUB_EVENT_KEY));\r\n+        if (isStubServiceInvoke) {\r\n+            port = channel.getRemoteAddress().getPort();\r\n+        }\r\n+\r\n+        //callback\r\n+        isCallBackServiceInvoke = isClientSide(channel) && !isStubServiceInvoke;\r\n+        if (isCallBackServiceInvoke) {\r\n+            path += \".\" + inv.getObjectAttachments().get(CALLBACK_SERVICE_KEY);\r\n+            inv.getObjectAttachments().put(IS_CALLBACK_SERVICE_INVOKE, Boolean.TRUE.toString());\r\n+        }\r\n+\r\n+        String serviceKey = serviceKey(\r\n+                port,\r\n+                path,\r\n+                (String) inv.getObjectAttachments().get(VERSION_KEY),\r\n+                (String) inv.getObjectAttachments().get(GROUP_KEY)\r\n+        );\r\n+        DubboExporter<?> exporter = (DubboExporter<?>) exporterMap.get(serviceKey);\r\n+\r\n+        if (exporter == null) {\r\n+            throw new RemotingException(channel, \"Not found exported service: \" + serviceKey + \" in \" + exporterMap.keySet() + \", may be version or group mismatch \" +\r\n+                    \", channel: consumer: \" + channel.getRemoteAddress() + \" --> provider: \" + channel.getLocalAddress() + \", message:\" + getInvocationWithoutData(inv));\r\n+        }\r\n+\r\n+        return exporter.getInvoker();\r\n+    }\r\n+\r\n+    public Collection<Invoker<?>> getInvokers() {\r\n+        return Collections.unmodifiableCollection(invokers);\r\n+    }\r\n+\r\n+    @Override\r\n+    public int getDefaultPort() {\r\n+        return DEFAULT_PORT;\r\n+    }\r\n+\r\n+    @Override\r\n+    public <T> Exporter<T> export(Invoker<T> invoker) throws RpcException {\r\n+        URL url = invoker.getUrl();\r\n+\r\n+        // export service.\r\n+        String key = serviceKey(url);\r\n+        DubboExporter<T> exporter = new DubboExporter<T>(invoker, key, exporterMap);\r\n+        exporterMap.put(key, exporter);\r\n+\r\n+        //export an stub service for dispatching event\r\n+        Boolean isStubSupportEvent = url.getParameter(STUB_EVENT_KEY, DEFAULT_STUB_EVENT);\r\n+        Boolean isCallbackservice = url.getParameter(IS_CALLBACK_SERVICE, false);\r\n+        if (isStubSupportEvent && !isCallbackservice) {\r\n+            String stubServiceMethods = url.getParameter(STUB_EVENT_METHODS_KEY);\r\n+            if (stubServiceMethods == null || stubServiceMethods.length() == 0) {\r\n+                if (logger.isWarnEnabled()) {\r\n+                    logger.warn(new IllegalStateException(\"consumer [\" + url.getParameter(INTERFACE_KEY) +\r\n+                            \"], has set stubproxy support event ,but no stub methods founded.\"));\r\n+                }\r\n+\r\n+            }\r\n+        }\r\n+\r\n+        openServer(url);\r\n+        optimizeSerialization(url);\r\n+\r\n+        return exporter;\r\n+    }\r\n+\r\n+    private void openServer(URL url) {\r\n+        // find server.\r\n+        String key = url.getAddress();\r\n+        //client can export a service which's only for server to invoke\r\n+        boolean isServer = url.getParameter(IS_SERVER_KEY, true);\r\n+        if (isServer) {\r\n+            ProtocolServer server = serverMap.get(key);\r\n+            if (server == null) {\r\n+                synchronized (this) {\r\n+                    server = serverMap.get(key);\r\n+                    if (server == null) {\r\n+                        serverMap.put(key, createServer(url));\r\n+                    }\r\n+                }\r\n+            } else {\r\n+                // server supports reset, use together with override\r\n+                server.reset(url);\r\n+            }\r\n+        }\r\n+    }\r\n+\r\n+    private ProtocolServer createServer(URL url) {\r\n+        url = URLBuilder.from(url)\r\n+                // send readonly event when server closes, it's enabled by default\r\n+                .addParameterIfAbsent(CHANNEL_READONLYEVENT_SENT_KEY, Boolean.TRUE.toString())\r\n+                // enable heartbeat by default\r\n+                .addParameterIfAbsent(HEARTBEAT_KEY, String.valueOf(DEFAULT_HEARTBEAT))\r\n+                .addParameter(CODEC_KEY, DubboCodec.NAME)\r\n+                .build();\r\n+        String str = url.getParameter(SERVER_KEY, DEFAULT_REMOTING_SERVER);\r\n+\r\n+        if (str != null && str.length() > 0 && !ExtensionLoader.getExtensionLoader(Transporter.class).hasExtension(str)) {\r\n+            throw new RpcException(\"Unsupported server type: \" + str + \", url: \" + url);\r\n+        }\r\n+\r\n+        ExchangeServer server;\r\n+        try {\r\n+            server = Exchangers.bind(url, requestHandler);\r\n+        } catch (RemotingException e) {\r\n+            throw new RpcException(\"Fail to start server(url: \" + url + \") \" + e.getMessage(), e);\r\n+        }\r\n+\r\n+        str = url.getParameter(CLIENT_KEY);\r\n+        if (str != null && str.length() > 0) {\r\n+            Set<String> supportedTypes = ExtensionLoader.getExtensionLoader(Transporter.class).getSupportedExtensions();\r\n+            if (!supportedTypes.contains(str)) {\r\n+                throw new RpcException(\"Unsupported client type: \" + str);\r\n+            }\r\n+        }\r\n+\r\n+        return new DubboProtocolServer(server);\r\n+    }\r\n+\r\n+    private void optimizeSerialization(URL url) throws RpcException {\r\n+        String className = url.getParameter(OPTIMIZER_KEY, \"\");\r\n+        if (StringUtils.isEmpty(className) || optimizers.contains(className)) {\r\n+            return;\r\n+        }\r\n+\r\n+        logger.info(\"Optimizing the serialization process for Kryo, FST, etc...\");\r\n+\r\n+        try {\r\n+            Class clazz = Thread.currentThread().getContextClassLoader().loadClass(className);\r\n+            if (!SerializationOptimizer.class.isAssignableFrom(clazz)) {\r\n+                throw new RpcException(\"The serialization optimizer \" + className + \" isn't an instance of \" + SerializationOptimizer.class.getName());\r\n+            }\r\n+\r\n+            SerializationOptimizer optimizer = (SerializationOptimizer) clazz.newInstance();\r\n+\r\n+            if (optimizer.getSerializableClasses() == null) {\r\n+                return;\r\n+            }\r\n+\r\n+            for (Class c : optimizer.getSerializableClasses()) {\r\n+                SerializableClassRegistry.registerClass(c);\r\n+            }\r\n+\r\n+            optimizers.add(className);\r\n+\r\n+        } catch (ClassNotFoundException e) {\r\n+            throw new RpcException(\"Cannot find the serialization optimizer class: \" + className, e);\r\n+\r\n+        } catch (InstantiationException | IllegalAccessException e) {\r\n+            throw new RpcException(\"Cannot instantiate the serialization optimizer class: \" + className, e);\r\n+\r\n+        }\r\n+    }\r\n+\r\n+    @Override\r\n+    public <T> Invoker<T> protocolBindingRefer(Class<T> serviceType, URL url) throws RpcException {\r\n+        optimizeSerialization(url);\r\n+\r\n+        // create rpc invoker.\r\n+        DubboInvoker<T> invoker = new DubboInvoker<T>(serviceType, url, getClients(url), invokers);\r\n+        invokers.add(invoker);\r\n+\r\n+        return invoker;\r\n+    }\r\n+\r\n+    private ExchangeClient[] getClients(URL url) {\r\n+        // whether to share connection\r\n+\r\n+        boolean useShareConnect = false;\r\n+\r\n+        int connections = url.getParameter(CONNECTIONS_KEY, 0);\r\n+        List<ReferenceCountExchangeClient> shareClients = null;\r\n+        // if not configured, connection is shared, otherwise, one connection for one service\r\n+        if (connections == 0) {\r\n+            useShareConnect = true;\r\n+\r\n+            /*\r\n+             * The xml configuration should have a higher priority than properties.\r\n+             */\r\n+            String shareConnectionsStr = url.getParameter(SHARE_CONNECTIONS_KEY, (String) null);\r\n+            connections = Integer.parseInt(StringUtils.isBlank(shareConnectionsStr) ? ConfigUtils.getProperty(SHARE_CONNECTIONS_KEY,\r\n+                    DEFAULT_SHARE_CONNECTIONS) : shareConnectionsStr);\r\n+            shareClients = getSharedClient(url, connections);\r\n+        }\r\n+\r\n+        ExchangeClient[] clients = new ExchangeClient[connections];\r\n+        for (int i = 0; i < clients.length; i++) {\r\n+            if (useShareConnect) {\r\n+                clients[i] = shareClients.get(i);\r\n+\r\n+            } else {\r\n+                clients[i] = initClient(url);\r\n+            }\r\n+        }\r\n+\r\n+        return clients;\r\n+    }\r\n+\r\n+    /**\r\n+     * Get shared connection\r\n+     *\r\n+     * @param url\r\n+     * @param connectNum connectNum must be greater than or equal to 1\r\n+     */\r\n+    private List<ReferenceCountExchangeClient> getSharedClient(URL url, int connectNum) {\r\n+        String key = url.getAddress();\r\n+        List<ReferenceCountExchangeClient> clients = referenceClientMap.get(key);\r\n+\r\n+        if (checkClientCanUse(clients)) {\r\n+            batchClientRefIncr(clients);\r\n+            return clients;\r\n+        }\r\n+\r\n+        locks.putIfAbsent(key, new Object());\r\n+        synchronized (locks.get(key)) {\r\n+            clients = referenceClientMap.get(key);\r\n+            // double check\r\n+            if (checkClientCanUse(clients)) {\r\n+                batchClientRefIncr(clients);\r\n+                return clients;\r\n+            }\r\n+\r\n+            // connectNum must be greater than or equal to 1\r\n+            connectNum = Math.max(connectNum, 1);\r\n+\r\n+            // If the clients is empty, then the first initialization is\r\n+            if (CollectionUtils.isEmpty(clients)) {\r\n+                clients = buildReferenceCountExchangeClientList(url, connectNum);\r\n+                referenceClientMap.put(key, clients);\r\n+\r\n+            } else {\r\n+                for (int i = 0; i < clients.size(); i++) {\r\n+                    ReferenceCountExchangeClient referenceCountExchangeClient = clients.get(i);\r\n+                    // If there is a client in the list that is no longer available, create a new one to replace him.\r\n+                    if (referenceCountExchangeClient == null || referenceCountExchangeClient.isClosed()) {\r\n+                        clients.set(i, buildReferenceCountExchangeClient(url));\r\n+                        continue;\r\n+                    }\r\n+\r\n+                    referenceCountExchangeClient.incrementAndGetCount();\r\n+                }\r\n+            }\r\n+\r\n+            /*\r\n+             * I understand that the purpose of the remove operation here is to avoid the expired url key\r\n+             * always occupying this memory space.\r\n+             * But \"locks.remove(key);\" can lead to \"synchronized (locks.get(key)) {\" NPE, considering that the key of locks is \"IP + port\",\r\n+             * it will not lead to the expansion of \"locks\" in theory, so I will annotate it here.\r\n+             */\r\n+//            locks.remove(key);\r\n+\r\n+            return clients;\r\n+        }\r\n+    }\r\n+\r\n+    /**\r\n+     * Check if the client list is all available\r\n+     *\r\n+     * @param referenceCountExchangeClients\r\n+     * @return true-available\uff0cfalse-unavailable\r\n+     */\r\n+    private boolean checkClientCanUse(List<ReferenceCountExchangeClient> referenceCountExchangeClients) {\r\n+        if (CollectionUtils.isEmpty(referenceCountExchangeClients)) {\r\n+            return false;\r\n+        }\r\n+\r\n+        for (ReferenceCountExchangeClient referenceCountExchangeClient : referenceCountExchangeClients) {\r\n+            // As long as one client is not available, you need to replace the unavailable client with the available one.\r\n+            if (referenceCountExchangeClient == null || referenceCountExchangeClient.getCount() <= 0 || referenceCountExchangeClient.isClosed()) {\r\n+                return false;\r\n+            }\r\n+        }\r\n+\r\n+        return true;\r\n+    }\r\n+\r\n+    /**\r\n+     * Increase the reference Count if we create new invoker shares same connection, the connection will be closed without any reference.\r\n+     *\r\n+     * @param referenceCountExchangeClients\r\n+     */\r\n+    private void batchClientRefIncr(List<ReferenceCountExchangeClient> referenceCountExchangeClients) {\r\n+        if (CollectionUtils.isEmpty(referenceCountExchangeClients)) {\r\n+            return;\r\n+        }\r\n+\r\n+        for (ReferenceCountExchangeClient referenceCountExchangeClient : referenceCountExchangeClients) {\r\n+            if (referenceCountExchangeClient != null) {\r\n+                referenceCountExchangeClient.incrementAndGetCount();\r\n+            }\r\n+        }\r\n+    }\r\n+\r\n+    /**\r\n+     * Bulk build client\r\n+     *\r\n+     * @param url\r\n+     * @param connectNum\r\n+     * @return\r\n+     */\r\n+    private List<ReferenceCountExchangeClient> buildReferenceCountExchangeClientList(URL url, int connectNum) {\r\n+        List<ReferenceCountExchangeClient> clients = new ArrayList<>();\r\n+\r\n+        for (int i = 0; i < connectNum; i++) {\r\n+            clients.add(buildReferenceCountExchangeClient(url));\r\n+        }\r\n+\r\n+        return clients;\r\n+    }\r\n+\r\n+    /**\r\n+     * Build a single client\r\n+     *\r\n+     * @param url\r\n+     * @return\r\n+     */\r\n+    private ReferenceCountExchangeClient buildReferenceCountExchangeClient(URL url) {\r\n+        ExchangeClient exchangeClient = initClient(url);\r\n+\r\n+        return new ReferenceCountExchangeClient(exchangeClient);\r\n+    }\r\n+\r\n+    /**\r\n+     * Create new connection\r\n+     *\r\n+     * @param url\r\n+     */\r\n+    private ExchangeClient initClient(URL url) {\r\n+\r\n+        // client type setting.\r\n+        String str = url.getParameter(CLIENT_KEY, url.getParameter(SERVER_KEY, DEFAULT_REMOTING_CLIENT));\r\n+\r\n+        url = url.addParameter(CODEC_KEY, DubboCodec.NAME);\r\n+        // enable heartbeat by default\r\n+        url = url.addParameterIfAbsent(HEARTBEAT_KEY, String.valueOf(DEFAULT_HEARTBEAT));\r\n+\r\n+        // BIO is not allowed since it has severe performance issue.\r\n+        if (str != null && str.length() > 0 && !ExtensionLoader.getExtensionLoader(Transporter.class).hasExtension(str)) {\r\n+            throw new RpcException(\"Unsupported client type: \" + str + \",\" +\r\n+                    \" supported client type is \" + StringUtils.join(ExtensionLoader.getExtensionLoader(Transporter.class).getSupportedExtensions(), \" \"));\r\n+        }\r\n+\r\n+        ExchangeClient client;\r\n+        try {\r\n+            // connection should be lazy\r\n+            if (url.getParameter(LAZY_CONNECT_KEY, false)) {\r\n+                client = new LazyConnectExchangeClient(url, requestHandler);\r\n+\r\n+            } else {\r\n+                client = Exchangers.connect(url, requestHandler);\r\n+            }\r\n+\r\n+        } catch (RemotingException e) {\r\n+            throw new RpcException(\"Fail to create remoting client for service(\" + url + \"): \" + e.getMessage(), e);\r\n+        }\r\n+\r\n+        return client;\r\n+    }\r\n+\r\n+    @Override\r\n+    public void destroy() {\r\n+        for (String key : new ArrayList<>(serverMap.keySet())) {\r\n+            ProtocolServer protocolServer = serverMap.remove(key);\r\n+\r\n+            if (protocolServer == null) {\r\n+                continue;\r\n+            }\r\n+\r\n+            RemotingServer server = protocolServer.getRemotingServer();\r\n+\r\n+            try {\r\n+                if (logger.isInfoEnabled()) {\r\n+                    logger.info(\"Close dubbo server: \" + server.getLocalAddress());\r\n+                }\r\n+\r\n+                server.close(ConfigurationUtils.getServerShutdownTimeout());\r\n+\r\n+            } catch (Throwable t) {\r\n+                logger.warn(t.getMessage(), t);\r\n+            }\r\n+        }\r\n+\r\n+        for (String key : new ArrayList<>(referenceClientMap.keySet())) {\r\n+            List<ReferenceCountExchangeClient> clients = referenceClientMap.remove(key);\r\n+\r\n+            if (CollectionUtils.isEmpty(clients)) {\r\n+                continue;\r\n+            }\r\n+\r\n+            for (ReferenceCountExchangeClient client : clients) {\r\n+                closeReferenceCountExchangeClient(client);\r\n+            }\r\n+        }\r\n+\r\n+        super.destroy();\r\n+    }\r\n+\r\n+    /**\r\n+     * close ReferenceCountExchangeClient\r\n+     *\r\n+     * @param client\r\n+     */\r\n+    private void closeReferenceCountExchangeClient(ReferenceCountExchangeClient client) {\r\n+        if (client == null) {\r\n+            return;\r\n+        }\r\n+\r\n+        try {\r\n+            if (logger.isInfoEnabled()) {\r\n+                logger.info(\"Close dubbo connect: \" + client.getLocalAddress() + \"-->\" + client.getRemoteAddress());\r\n+            }\r\n+\r\n+            client.close(ConfigurationUtils.getServerShutdownTimeout());\r\n+\r\n+            // TODO\r\n+            /*\r\n+             * At this time, ReferenceCountExchangeClient#client has been replaced with LazyConnectExchangeClient.\r\n+             * Do you need to call client.close again to ensure that LazyConnectExchangeClient is also closed?\r\n+             */\r\n+\r\n+        } catch (Throwable t) {\r\n+            logger.warn(t.getMessage(), t);\r\n+        }\r\n+    }\r\n+\r\n+    /**\r\n+     * only log body in debugger mode for size & security consideration.\r\n+     *\r\n+     * @param invocation\r\n+     * @return\r\n+     */\r\n+    private Invocation getInvocationWithoutData(Invocation invocation) {\r\n+        if (logger.isDebugEnabled()) {\r\n+            return invocation;\r\n+        }\r\n+        if (invocation instanceof RpcInvocation) {\r\n+            RpcInvocation rpcInvocation = (RpcInvocation) invocation;\r\n+            rpcInvocation.setArguments(null);\r\n+            return rpcInvocation;\r\n+        }\r\n+        return invocation;\r\n+    }\r\n+}\r\n"}, {"source1": "org/apache/dubbo/rpc/protocol/dubbo/DubboProtocolServer.java", "source2": "org/apache/dubbo/rpc/protocol/dubbo/DubboProtocolServer.java", "comments": ["Line-ending differences only"], "unified_diff": "@@ -1,62 +1,62 @@\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.rpc.protocol.dubbo;\n-\n-import org.apache.dubbo.common.URL;\n-import org.apache.dubbo.common.utils.StringUtils;\n-import org.apache.dubbo.remoting.RemotingServer;\n-import org.apache.dubbo.rpc.ProtocolServer;\n-\n-public class DubboProtocolServer implements ProtocolServer {\n-\n-    private RemotingServer server;\n-    private String address;\n-\n-    public DubboProtocolServer(RemotingServer server) {\n-        this.server = server;\n-    }\n-\n-    @Override\n-    public RemotingServer getRemotingServer() {\n-        return server;\n-    }\n-\n-    @Override\n-    public String getAddress() {\n-        return StringUtils.isNotEmpty(address) ? address : server.getUrl().getAddress();\n-    }\n-\n-    @Override\n-    public void setAddress(String address) {\n-        this.address = address;\n-    }\n-\n-    @Override\n-    public URL getUrl() {\n-        return server.getUrl();\n-    }\n-\n-    @Override\n-    public void reset(URL url) {\n-        server.reset(url);\n-    }\n-\n-    @Override\n-    public void close() {\n-        server.close();\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.rpc.protocol.dubbo;\r\n+\r\n+import org.apache.dubbo.common.URL;\r\n+import org.apache.dubbo.common.utils.StringUtils;\r\n+import org.apache.dubbo.remoting.RemotingServer;\r\n+import org.apache.dubbo.rpc.ProtocolServer;\r\n+\r\n+public class DubboProtocolServer implements ProtocolServer {\r\n+\r\n+    private RemotingServer server;\r\n+    private String address;\r\n+\r\n+    public DubboProtocolServer(RemotingServer server) {\r\n+        this.server = server;\r\n+    }\r\n+\r\n+    @Override\r\n+    public RemotingServer getRemotingServer() {\r\n+        return server;\r\n+    }\r\n+\r\n+    @Override\r\n+    public String getAddress() {\r\n+        return StringUtils.isNotEmpty(address) ? address : server.getUrl().getAddress();\r\n+    }\r\n+\r\n+    @Override\r\n+    public void setAddress(String address) {\r\n+        this.address = address;\r\n+    }\r\n+\r\n+    @Override\r\n+    public URL getUrl() {\r\n+        return server.getUrl();\r\n+    }\r\n+\r\n+    @Override\r\n+    public void reset(URL url) {\r\n+        server.reset(url);\r\n+    }\r\n+\r\n+    @Override\r\n+    public void close() {\r\n+        server.close();\r\n+    }\r\n+}\r\n"}, {"source1": "org/apache/dubbo/rpc/protocol/dubbo/LazyConnectExchangeClient.java", "source2": "org/apache/dubbo/rpc/protocol/dubbo/LazyConnectExchangeClient.java", "comments": ["Line-ending differences only"], "unified_diff": "@@ -1,269 +1,269 @@\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.rpc.protocol.dubbo;\n-\n-import org.apache.dubbo.common.Parameters;\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.ChannelHandler;\n-import org.apache.dubbo.remoting.RemotingException;\n-import org.apache.dubbo.remoting.exchange.ExchangeClient;\n-import org.apache.dubbo.remoting.exchange.ExchangeHandler;\n-import org.apache.dubbo.remoting.exchange.Exchangers;\n-\n-import java.net.InetSocketAddress;\n-import java.util.concurrent.CompletableFuture;\n-import java.util.concurrent.ExecutorService;\n-import java.util.concurrent.atomic.AtomicLong;\n-import java.util.concurrent.locks.Lock;\n-import java.util.concurrent.locks.ReentrantLock;\n-\n-import static org.apache.dubbo.remoting.Constants.SEND_RECONNECT_KEY;\n-import static org.apache.dubbo.rpc.protocol.dubbo.Constants.DEFAULT_LAZY_CONNECT_INITIAL_STATE;\n-import static org.apache.dubbo.rpc.protocol.dubbo.Constants.LAZY_CONNECT_INITIAL_STATE_KEY;\n-\n-/**\n- * dubbo protocol support class.\n- */\n-@SuppressWarnings(\"deprecation\")\n-final class LazyConnectExchangeClient implements ExchangeClient {\n-\n-    /**\n-     * when this warning rises from invocation, program probably have bug.\n-     */\n-    protected static final String REQUEST_WITH_WARNING_KEY = \"lazyclient_request_with_warning\";\n-    private final static Logger logger = LoggerFactory.getLogger(LazyConnectExchangeClient.class);\n-    protected final boolean requestWithWarning;\n-    private final URL url;\n-    private final ExchangeHandler requestHandler;\n-    private final Lock connectLock = new ReentrantLock();\n-    private final int warning_period = 5000;\n-    /**\n-     * lazy connect, initial state for connection\n-     */\n-    private final boolean initialState;\n-    private volatile ExchangeClient client;\n-    private AtomicLong warningcount = new AtomicLong(0);\n-\n-    public LazyConnectExchangeClient(URL url, ExchangeHandler requestHandler) {\n-        // lazy connect, need set send.reconnect = true, to avoid channel bad status.\n-        this.url = url.addParameter(SEND_RECONNECT_KEY, Boolean.TRUE.toString());\n-        this.requestHandler = requestHandler;\n-        this.initialState = url.getParameter(LAZY_CONNECT_INITIAL_STATE_KEY, DEFAULT_LAZY_CONNECT_INITIAL_STATE);\n-        this.requestWithWarning = url.getParameter(REQUEST_WITH_WARNING_KEY, false);\n-    }\n-\n-    private void initClient() throws RemotingException {\n-        if (client != null) {\n-            return;\n-        }\n-        if (logger.isInfoEnabled()) {\n-            logger.info(\"Lazy connect to \" + url);\n-        }\n-        connectLock.lock();\n-        try {\n-            if (client != null) {\n-                return;\n-            }\n-            this.client = Exchangers.connect(url, requestHandler);\n-        } finally {\n-            connectLock.unlock();\n-        }\n-    }\n-\n-    @Override\n-    public CompletableFuture<Object> request(Object request) throws RemotingException {\n-        warning();\n-        initClient();\n-        return client.request(request);\n-    }\n-\n-    @Override\n-    public URL getUrl() {\n-        return url;\n-    }\n-\n-    @Override\n-    public InetSocketAddress getRemoteAddress() {\n-        if (client == null) {\n-            return InetSocketAddress.createUnresolved(url.getHost(), url.getPort());\n-        } else {\n-            return client.getRemoteAddress();\n-        }\n-    }\n-\n-    @Override\n-    public CompletableFuture<Object> request(Object request, int timeout) throws RemotingException {\n-        warning();\n-        initClient();\n-        return client.request(request, timeout);\n-    }\n-\n-    @Override\n-    public CompletableFuture<Object> request(Object request, ExecutorService executor) throws RemotingException {\n-        warning();\n-        initClient();\n-        return client.request(request, executor);\n-    }\n-\n-    @Override\n-    public CompletableFuture<Object> request(Object request, int timeout, ExecutorService executor) throws RemotingException {\n-        warning();\n-        initClient();\n-        return client.request(request, timeout, executor);\n-    }\n-\n-    /**\n-     * If {@link #REQUEST_WITH_WARNING_KEY} is configured, then warn once every 5000 invocations.\n-     */\n-    private void warning() {\n-        if (requestWithWarning) {\n-            if (warningcount.get() % warning_period == 0) {\n-                logger.warn(url.getAddress() + \" \" + url.getServiceKey() + \" safe guard client , should not be called ,must have a bug.\");\n-            }\n-            warningcount.incrementAndGet();\n-        }\n-    }\n-\n-    @Override\n-    public ChannelHandler getChannelHandler() {\n-        checkClient();\n-        return client.getChannelHandler();\n-    }\n-\n-    @Override\n-    public boolean isConnected() {\n-        if (client == null) {\n-            return initialState;\n-        } else {\n-            return client.isConnected();\n-        }\n-    }\n-\n-    @Override\n-    public InetSocketAddress getLocalAddress() {\n-        if (client == null) {\n-            return InetSocketAddress.createUnresolved(NetUtils.getLocalHost(), 0);\n-        } else {\n-            return client.getLocalAddress();\n-        }\n-    }\n-\n-    @Override\n-    public ExchangeHandler getExchangeHandler() {\n-        return requestHandler;\n-    }\n-\n-    @Override\n-    public void send(Object message) throws RemotingException {\n-        initClient();\n-        client.send(message);\n-    }\n-\n-    @Override\n-    public void send(Object message, boolean sent) throws RemotingException {\n-        initClient();\n-        client.send(message, sent);\n-    }\n-\n-    @Override\n-    public boolean isClosed() {\n-        if (client != null) {\n-            return client.isClosed();\n-        } else {\n-            return false;\n-        }\n-    }\n-\n-    @Override\n-    public void close() {\n-        if (client != null) {\n-            client.close();\n-        }\n-    }\n-\n-    @Override\n-    public void close(int timeout) {\n-        if (client != null) {\n-            client.close(timeout);\n-        }\n-    }\n-\n-    @Override\n-    public void startClose() {\n-        if (client != null) {\n-            client.startClose();\n-        }\n-    }\n-\n-    @Override\n-    public void reset(URL url) {\n-        checkClient();\n-        client.reset(url);\n-    }\n-\n-    @Override\n-    @Deprecated\n-    public void reset(Parameters parameters) {\n-        reset(getUrl().addParameters(parameters.getParameters()));\n-    }\n-\n-    @Override\n-    public void reconnect() throws RemotingException {\n-        checkClient();\n-        client.reconnect();\n-    }\n-\n-    @Override\n-    public Object getAttribute(String key) {\n-        if (client == null) {\n-            return null;\n-        } else {\n-            return client.getAttribute(key);\n-        }\n-    }\n-\n-    @Override\n-    public void setAttribute(String key, Object value) {\n-        checkClient();\n-        client.setAttribute(key, value);\n-    }\n-\n-    @Override\n-    public void removeAttribute(String key) {\n-        checkClient();\n-        client.removeAttribute(key);\n-    }\n-\n-    @Override\n-    public boolean hasAttribute(String key) {\n-        if (client == null) {\n-            return false;\n-        } else {\n-            return client.hasAttribute(key);\n-        }\n-    }\n-\n-    private void checkClient() {\n-        if (client == null) {\n-            throw new IllegalStateException(\n-                    \"LazyConnectExchangeClient state error. the client has not be init .url:\" + url);\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.rpc.protocol.dubbo;\r\n+\r\n+import org.apache.dubbo.common.Parameters;\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.ChannelHandler;\r\n+import org.apache.dubbo.remoting.RemotingException;\r\n+import org.apache.dubbo.remoting.exchange.ExchangeClient;\r\n+import org.apache.dubbo.remoting.exchange.ExchangeHandler;\r\n+import org.apache.dubbo.remoting.exchange.Exchangers;\r\n+\r\n+import java.net.InetSocketAddress;\r\n+import java.util.concurrent.CompletableFuture;\r\n+import java.util.concurrent.ExecutorService;\r\n+import java.util.concurrent.atomic.AtomicLong;\r\n+import java.util.concurrent.locks.Lock;\r\n+import java.util.concurrent.locks.ReentrantLock;\r\n+\r\n+import static org.apache.dubbo.remoting.Constants.SEND_RECONNECT_KEY;\r\n+import static org.apache.dubbo.rpc.protocol.dubbo.Constants.DEFAULT_LAZY_CONNECT_INITIAL_STATE;\r\n+import static org.apache.dubbo.rpc.protocol.dubbo.Constants.LAZY_CONNECT_INITIAL_STATE_KEY;\r\n+\r\n+/**\r\n+ * dubbo protocol support class.\r\n+ */\r\n+@SuppressWarnings(\"deprecation\")\r\n+final class LazyConnectExchangeClient implements ExchangeClient {\r\n+\r\n+    /**\r\n+     * when this warning rises from invocation, program probably have bug.\r\n+     */\r\n+    protected static final String REQUEST_WITH_WARNING_KEY = \"lazyclient_request_with_warning\";\r\n+    private final static Logger logger = LoggerFactory.getLogger(LazyConnectExchangeClient.class);\r\n+    protected final boolean requestWithWarning;\r\n+    private final URL url;\r\n+    private final ExchangeHandler requestHandler;\r\n+    private final Lock connectLock = new ReentrantLock();\r\n+    private final int warning_period = 5000;\r\n+    /**\r\n+     * lazy connect, initial state for connection\r\n+     */\r\n+    private final boolean initialState;\r\n+    private volatile ExchangeClient client;\r\n+    private AtomicLong warningcount = new AtomicLong(0);\r\n+\r\n+    public LazyConnectExchangeClient(URL url, ExchangeHandler requestHandler) {\r\n+        // lazy connect, need set send.reconnect = true, to avoid channel bad status.\r\n+        this.url = url.addParameter(SEND_RECONNECT_KEY, Boolean.TRUE.toString());\r\n+        this.requestHandler = requestHandler;\r\n+        this.initialState = url.getParameter(LAZY_CONNECT_INITIAL_STATE_KEY, DEFAULT_LAZY_CONNECT_INITIAL_STATE);\r\n+        this.requestWithWarning = url.getParameter(REQUEST_WITH_WARNING_KEY, false);\r\n+    }\r\n+\r\n+    private void initClient() throws RemotingException {\r\n+        if (client != null) {\r\n+            return;\r\n+        }\r\n+        if (logger.isInfoEnabled()) {\r\n+            logger.info(\"Lazy connect to \" + url);\r\n+        }\r\n+        connectLock.lock();\r\n+        try {\r\n+            if (client != null) {\r\n+                return;\r\n+            }\r\n+            this.client = Exchangers.connect(url, requestHandler);\r\n+        } finally {\r\n+            connectLock.unlock();\r\n+        }\r\n+    }\r\n+\r\n+    @Override\r\n+    public CompletableFuture<Object> request(Object request) throws RemotingException {\r\n+        warning();\r\n+        initClient();\r\n+        return client.request(request);\r\n+    }\r\n+\r\n+    @Override\r\n+    public URL getUrl() {\r\n+        return url;\r\n+    }\r\n+\r\n+    @Override\r\n+    public InetSocketAddress getRemoteAddress() {\r\n+        if (client == null) {\r\n+            return InetSocketAddress.createUnresolved(url.getHost(), url.getPort());\r\n+        } else {\r\n+            return client.getRemoteAddress();\r\n+        }\r\n+    }\r\n+\r\n+    @Override\r\n+    public CompletableFuture<Object> request(Object request, int timeout) throws RemotingException {\r\n+        warning();\r\n+        initClient();\r\n+        return client.request(request, timeout);\r\n+    }\r\n+\r\n+    @Override\r\n+    public CompletableFuture<Object> request(Object request, ExecutorService executor) throws RemotingException {\r\n+        warning();\r\n+        initClient();\r\n+        return client.request(request, executor);\r\n+    }\r\n+\r\n+    @Override\r\n+    public CompletableFuture<Object> request(Object request, int timeout, ExecutorService executor) throws RemotingException {\r\n+        warning();\r\n+        initClient();\r\n+        return client.request(request, timeout, executor);\r\n+    }\r\n+\r\n+    /**\r\n+     * If {@link #REQUEST_WITH_WARNING_KEY} is configured, then warn once every 5000 invocations.\r\n+     */\r\n+    private void warning() {\r\n+        if (requestWithWarning) {\r\n+            if (warningcount.get() % warning_period == 0) {\r\n+                logger.warn(url.getAddress() + \" \" + url.getServiceKey() + \" safe guard client , should not be called ,must have a bug.\");\r\n+            }\r\n+            warningcount.incrementAndGet();\r\n+        }\r\n+    }\r\n+\r\n+    @Override\r\n+    public ChannelHandler getChannelHandler() {\r\n+        checkClient();\r\n+        return client.getChannelHandler();\r\n+    }\r\n+\r\n+    @Override\r\n+    public boolean isConnected() {\r\n+        if (client == null) {\r\n+            return initialState;\r\n+        } else {\r\n+            return client.isConnected();\r\n+        }\r\n+    }\r\n+\r\n+    @Override\r\n+    public InetSocketAddress getLocalAddress() {\r\n+        if (client == null) {\r\n+            return InetSocketAddress.createUnresolved(NetUtils.getLocalHost(), 0);\r\n+        } else {\r\n+            return client.getLocalAddress();\r\n+        }\r\n+    }\r\n+\r\n+    @Override\r\n+    public ExchangeHandler getExchangeHandler() {\r\n+        return requestHandler;\r\n+    }\r\n+\r\n+    @Override\r\n+    public void send(Object message) throws RemotingException {\r\n+        initClient();\r\n+        client.send(message);\r\n+    }\r\n+\r\n+    @Override\r\n+    public void send(Object message, boolean sent) throws RemotingException {\r\n+        initClient();\r\n+        client.send(message, sent);\r\n+    }\r\n+\r\n+    @Override\r\n+    public boolean isClosed() {\r\n+        if (client != null) {\r\n+            return client.isClosed();\r\n+        } else {\r\n+            return false;\r\n+        }\r\n+    }\r\n+\r\n+    @Override\r\n+    public void close() {\r\n+        if (client != null) {\r\n+            client.close();\r\n+        }\r\n+    }\r\n+\r\n+    @Override\r\n+    public void close(int timeout) {\r\n+        if (client != null) {\r\n+            client.close(timeout);\r\n+        }\r\n+    }\r\n+\r\n+    @Override\r\n+    public void startClose() {\r\n+        if (client != null) {\r\n+            client.startClose();\r\n+        }\r\n+    }\r\n+\r\n+    @Override\r\n+    public void reset(URL url) {\r\n+        checkClient();\r\n+        client.reset(url);\r\n+    }\r\n+\r\n+    @Override\r\n+    @Deprecated\r\n+    public void reset(Parameters parameters) {\r\n+        reset(getUrl().addParameters(parameters.getParameters()));\r\n+    }\r\n+\r\n+    @Override\r\n+    public void reconnect() throws RemotingException {\r\n+        checkClient();\r\n+        client.reconnect();\r\n+    }\r\n+\r\n+    @Override\r\n+    public Object getAttribute(String key) {\r\n+        if (client == null) {\r\n+            return null;\r\n+        } else {\r\n+            return client.getAttribute(key);\r\n+        }\r\n+    }\r\n+\r\n+    @Override\r\n+    public void setAttribute(String key, Object value) {\r\n+        checkClient();\r\n+        client.setAttribute(key, value);\r\n+    }\r\n+\r\n+    @Override\r\n+    public void removeAttribute(String key) {\r\n+        checkClient();\r\n+        client.removeAttribute(key);\r\n+    }\r\n+\r\n+    @Override\r\n+    public boolean hasAttribute(String key) {\r\n+        if (client == null) {\r\n+            return false;\r\n+        } else {\r\n+            return client.hasAttribute(key);\r\n+        }\r\n+    }\r\n+\r\n+    private void checkClient() {\r\n+        if (client == null) {\r\n+            throw new IllegalStateException(\r\n+                    \"LazyConnectExchangeClient state error. the client has not be init .url:\" + url);\r\n+        }\r\n+    }\r\n+}\r\n"}, {"source1": "org/apache/dubbo/rpc/protocol/dubbo/ReferenceCountExchangeClient.java", "source2": "org/apache/dubbo/rpc/protocol/dubbo/ReferenceCountExchangeClient.java", "comments": ["Line-ending differences only"], "unified_diff": "@@ -1,211 +1,211 @@\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.rpc.protocol.dubbo;\n-\n-\n-import org.apache.dubbo.common.Parameters;\n-import org.apache.dubbo.common.URL;\n-import org.apache.dubbo.remoting.ChannelHandler;\n-import org.apache.dubbo.remoting.RemotingException;\n-import org.apache.dubbo.remoting.exchange.ExchangeClient;\n-import org.apache.dubbo.remoting.exchange.ExchangeHandler;\n-\n-import java.net.InetSocketAddress;\n-import java.util.concurrent.CompletableFuture;\n-import java.util.concurrent.ExecutorService;\n-import java.util.concurrent.atomic.AtomicInteger;\n-\n-import static org.apache.dubbo.remoting.Constants.SEND_RECONNECT_KEY;\n-import static org.apache.dubbo.rpc.protocol.dubbo.Constants.LAZY_CONNECT_INITIAL_STATE_KEY;\n-\n-/**\n- * dubbo protocol support class.\n- */\n-@SuppressWarnings(\"deprecation\")\n-final class ReferenceCountExchangeClient implements ExchangeClient {\n-\n-    private final URL url;\n-    private final AtomicInteger referenceCount = new AtomicInteger(0);\n-\n-    private ExchangeClient client;\n-\n-    public ReferenceCountExchangeClient(ExchangeClient client) {\n-        this.client = client;\n-        referenceCount.incrementAndGet();\n-        this.url = client.getUrl();\n-    }\n-\n-    @Override\n-    public void reset(URL url) {\n-        client.reset(url);\n-    }\n-\n-    @Override\n-    public CompletableFuture<Object> request(Object request) throws RemotingException {\n-        return client.request(request);\n-    }\n-\n-    @Override\n-    public URL getUrl() {\n-        return client.getUrl();\n-    }\n-\n-    @Override\n-    public InetSocketAddress getRemoteAddress() {\n-        return client.getRemoteAddress();\n-    }\n-\n-    @Override\n-    public ChannelHandler getChannelHandler() {\n-        return client.getChannelHandler();\n-    }\n-\n-    @Override\n-    public CompletableFuture<Object> request(Object request, int timeout) throws RemotingException {\n-        return client.request(request, timeout);\n-    }\n-\n-    @Override\n-    public CompletableFuture<Object> request(Object request, ExecutorService executor) throws RemotingException {\n-        return client.request(request, executor);\n-    }\n-\n-    @Override\n-    public CompletableFuture<Object> request(Object request, int timeout, ExecutorService executor) throws RemotingException {\n-        return client.request(request, timeout, executor);\n-    }\n-\n-    @Override\n-    public boolean isConnected() {\n-        return client.isConnected();\n-    }\n-\n-    @Override\n-    public void reconnect() throws RemotingException {\n-        client.reconnect();\n-    }\n-\n-    @Override\n-    public InetSocketAddress getLocalAddress() {\n-        return client.getLocalAddress();\n-    }\n-\n-    @Override\n-    public boolean hasAttribute(String key) {\n-        return client.hasAttribute(key);\n-    }\n-\n-    @Override\n-    public void reset(Parameters parameters) {\n-        client.reset(parameters);\n-    }\n-\n-    @Override\n-    public void send(Object message) throws RemotingException {\n-        client.send(message);\n-    }\n-\n-    @Override\n-    public ExchangeHandler getExchangeHandler() {\n-        return client.getExchangeHandler();\n-    }\n-\n-    @Override\n-    public Object getAttribute(String key) {\n-        return client.getAttribute(key);\n-    }\n-\n-    @Override\n-    public void send(Object message, boolean sent) throws RemotingException {\n-        client.send(message, sent);\n-    }\n-\n-    @Override\n-    public void setAttribute(String key, Object value) {\n-        client.setAttribute(key, value);\n-    }\n-\n-    @Override\n-    public void removeAttribute(String key) {\n-        client.removeAttribute(key);\n-    }\n-\n-    /**\n-     * close() is not idempotent any longer\n-     */\n-    @Override\n-    public void close() {\n-        close(0);\n-    }\n-\n-    @Override\n-    public void close(int timeout) {\n-        if (referenceCount.decrementAndGet() <= 0) {\n-            if (timeout == 0) {\n-                client.close();\n-\n-            } else {\n-                client.close(timeout);\n-            }\n-\n-            replaceWithLazyClient();\n-        }\n-    }\n-\n-    @Override\n-    public void startClose() {\n-        client.startClose();\n-    }\n-\n-    /**\n-     * when closing the client, the client needs to be set to LazyConnectExchangeClient, and if a new call is made,\n-     * the client will \"resurrect\".\n-     *\n-     * @return\n-     */\n-    private void replaceWithLazyClient() {\n-        // this is a defensive operation to avoid client is closed by accident, the initial state of the client is false\n-        URL lazyUrl = url.addParameter(LAZY_CONNECT_INITIAL_STATE_KEY, Boolean.TRUE)\n-                //.addParameter(RECONNECT_KEY, Boolean.FALSE)\n-                .addParameter(SEND_RECONNECT_KEY, Boolean.TRUE.toString())\n-                .addParameter(LazyConnectExchangeClient.REQUEST_WITH_WARNING_KEY, true);\n-\n-        /**\n-         * the order of judgment in the if statement cannot be changed.\n-         */\n-        if (!(client instanceof LazyConnectExchangeClient) || client.isClosed()) {\n-            client = new LazyConnectExchangeClient(lazyUrl, client.getExchangeHandler());\n-        }\n-    }\n-\n-    @Override\n-    public boolean isClosed() {\n-        return client.isClosed();\n-    }\n-\n-    /**\n-     * The reference count of current ExchangeClient, connection will be closed if all invokers destroyed.\n-     */\n-    public void incrementAndGetCount() {\n-        referenceCount.incrementAndGet();\n-    }\n-\n-    public int getCount() {\n-        return referenceCount.get();\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.rpc.protocol.dubbo;\r\n+\r\n+\r\n+import org.apache.dubbo.common.Parameters;\r\n+import org.apache.dubbo.common.URL;\r\n+import org.apache.dubbo.remoting.ChannelHandler;\r\n+import org.apache.dubbo.remoting.RemotingException;\r\n+import org.apache.dubbo.remoting.exchange.ExchangeClient;\r\n+import org.apache.dubbo.remoting.exchange.ExchangeHandler;\r\n+\r\n+import java.net.InetSocketAddress;\r\n+import java.util.concurrent.CompletableFuture;\r\n+import java.util.concurrent.ExecutorService;\r\n+import java.util.concurrent.atomic.AtomicInteger;\r\n+\r\n+import static org.apache.dubbo.remoting.Constants.SEND_RECONNECT_KEY;\r\n+import static org.apache.dubbo.rpc.protocol.dubbo.Constants.LAZY_CONNECT_INITIAL_STATE_KEY;\r\n+\r\n+/**\r\n+ * dubbo protocol support class.\r\n+ */\r\n+@SuppressWarnings(\"deprecation\")\r\n+final class ReferenceCountExchangeClient implements ExchangeClient {\r\n+\r\n+    private final URL url;\r\n+    private final AtomicInteger referenceCount = new AtomicInteger(0);\r\n+\r\n+    private ExchangeClient client;\r\n+\r\n+    public ReferenceCountExchangeClient(ExchangeClient client) {\r\n+        this.client = client;\r\n+        referenceCount.incrementAndGet();\r\n+        this.url = client.getUrl();\r\n+    }\r\n+\r\n+    @Override\r\n+    public void reset(URL url) {\r\n+        client.reset(url);\r\n+    }\r\n+\r\n+    @Override\r\n+    public CompletableFuture<Object> request(Object request) throws RemotingException {\r\n+        return client.request(request);\r\n+    }\r\n+\r\n+    @Override\r\n+    public URL getUrl() {\r\n+        return client.getUrl();\r\n+    }\r\n+\r\n+    @Override\r\n+    public InetSocketAddress getRemoteAddress() {\r\n+        return client.getRemoteAddress();\r\n+    }\r\n+\r\n+    @Override\r\n+    public ChannelHandler getChannelHandler() {\r\n+        return client.getChannelHandler();\r\n+    }\r\n+\r\n+    @Override\r\n+    public CompletableFuture<Object> request(Object request, int timeout) throws RemotingException {\r\n+        return client.request(request, timeout);\r\n+    }\r\n+\r\n+    @Override\r\n+    public CompletableFuture<Object> request(Object request, ExecutorService executor) throws RemotingException {\r\n+        return client.request(request, executor);\r\n+    }\r\n+\r\n+    @Override\r\n+    public CompletableFuture<Object> request(Object request, int timeout, ExecutorService executor) throws RemotingException {\r\n+        return client.request(request, timeout, executor);\r\n+    }\r\n+\r\n+    @Override\r\n+    public boolean isConnected() {\r\n+        return client.isConnected();\r\n+    }\r\n+\r\n+    @Override\r\n+    public void reconnect() throws RemotingException {\r\n+        client.reconnect();\r\n+    }\r\n+\r\n+    @Override\r\n+    public InetSocketAddress getLocalAddress() {\r\n+        return client.getLocalAddress();\r\n+    }\r\n+\r\n+    @Override\r\n+    public boolean hasAttribute(String key) {\r\n+        return client.hasAttribute(key);\r\n+    }\r\n+\r\n+    @Override\r\n+    public void reset(Parameters parameters) {\r\n+        client.reset(parameters);\r\n+    }\r\n+\r\n+    @Override\r\n+    public void send(Object message) throws RemotingException {\r\n+        client.send(message);\r\n+    }\r\n+\r\n+    @Override\r\n+    public ExchangeHandler getExchangeHandler() {\r\n+        return client.getExchangeHandler();\r\n+    }\r\n+\r\n+    @Override\r\n+    public Object getAttribute(String key) {\r\n+        return client.getAttribute(key);\r\n+    }\r\n+\r\n+    @Override\r\n+    public void send(Object message, boolean sent) throws RemotingException {\r\n+        client.send(message, sent);\r\n+    }\r\n+\r\n+    @Override\r\n+    public void setAttribute(String key, Object value) {\r\n+        client.setAttribute(key, value);\r\n+    }\r\n+\r\n+    @Override\r\n+    public void removeAttribute(String key) {\r\n+        client.removeAttribute(key);\r\n+    }\r\n+\r\n+    /**\r\n+     * close() is not idempotent any longer\r\n+     */\r\n+    @Override\r\n+    public void close() {\r\n+        close(0);\r\n+    }\r\n+\r\n+    @Override\r\n+    public void close(int timeout) {\r\n+        if (referenceCount.decrementAndGet() <= 0) {\r\n+            if (timeout == 0) {\r\n+                client.close();\r\n+\r\n+            } else {\r\n+                client.close(timeout);\r\n+            }\r\n+\r\n+            replaceWithLazyClient();\r\n+        }\r\n+    }\r\n+\r\n+    @Override\r\n+    public void startClose() {\r\n+        client.startClose();\r\n+    }\r\n+\r\n+    /**\r\n+     * when closing the client, the client needs to be set to LazyConnectExchangeClient, and if a new call is made,\r\n+     * the client will \"resurrect\".\r\n+     *\r\n+     * @return\r\n+     */\r\n+    private void replaceWithLazyClient() {\r\n+        // this is a defensive operation to avoid client is closed by accident, the initial state of the client is false\r\n+        URL lazyUrl = url.addParameter(LAZY_CONNECT_INITIAL_STATE_KEY, Boolean.TRUE)\r\n+                //.addParameter(RECONNECT_KEY, Boolean.FALSE)\r\n+                .addParameter(SEND_RECONNECT_KEY, Boolean.TRUE.toString())\r\n+                .addParameter(LazyConnectExchangeClient.REQUEST_WITH_WARNING_KEY, true);\r\n+\r\n+        /**\r\n+         * the order of judgment in the if statement cannot be changed.\r\n+         */\r\n+        if (!(client instanceof LazyConnectExchangeClient) || client.isClosed()) {\r\n+            client = new LazyConnectExchangeClient(lazyUrl, client.getExchangeHandler());\r\n+        }\r\n+    }\r\n+\r\n+    @Override\r\n+    public boolean isClosed() {\r\n+        return client.isClosed();\r\n+    }\r\n+\r\n+    /**\r\n+     * The reference count of current ExchangeClient, connection will be closed if all invokers destroyed.\r\n+     */\r\n+    public void incrementAndGetCount() {\r\n+        referenceCount.incrementAndGet();\r\n+    }\r\n+\r\n+    public int getCount() {\r\n+        return referenceCount.get();\r\n+    }\r\n+}\r\n+\r\n"}, {"source1": "org/apache/dubbo/rpc/protocol/dubbo/filter/FutureFilter.java", "source2": "org/apache/dubbo/rpc/protocol/dubbo/filter/FutureFilter.java", "comments": ["Line-ending differences only"], "unified_diff": "@@ -1,203 +1,203 @@\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.rpc.protocol.dubbo.filter;\n-\n-import org.apache.dubbo.common.constants.CommonConstants;\n-import org.apache.dubbo.common.extension.Activate;\n-import org.apache.dubbo.common.logger.Logger;\n-import org.apache.dubbo.common.logger.LoggerFactory;\n-import org.apache.dubbo.common.utils.ReflectUtils;\n-import org.apache.dubbo.rpc.Filter;\n-import org.apache.dubbo.rpc.Invocation;\n-import org.apache.dubbo.rpc.Invoker;\n-import org.apache.dubbo.rpc.Result;\n-import org.apache.dubbo.rpc.RpcException;\n-import org.apache.dubbo.rpc.model.ApplicationModel;\n-import org.apache.dubbo.rpc.model.AsyncMethodInfo;\n-import org.apache.dubbo.rpc.model.ConsumerModel;\n-\n-import java.lang.reflect.InvocationTargetException;\n-import java.lang.reflect.Method;\n-\n-import static org.apache.dubbo.common.constants.CommonConstants.$INVOKE;\n-import static org.apache.dubbo.rpc.protocol.dubbo.Constants.ASYNC_METHOD_INFO;\n-\n-/**\n- * EventFilter\n- */\n-@Activate(group = CommonConstants.CONSUMER)\n-public class FutureFilter implements Filter, Filter.Listener {\n-\n-    protected static final Logger logger = LoggerFactory.getLogger(FutureFilter.class);\n-\n-    @Override\n-    public Result invoke(final Invoker<?> invoker, final Invocation invocation) throws RpcException {\n-        fireInvokeCallback(invoker, invocation);\n-        // need to configure if there's return value before the invocation in order to help invoker to judge if it's\n-        // necessary to return future.\n-        return invoker.invoke(invocation);\n-    }\n-\n-    @Override\n-    public void onResponse(Result result, Invoker<?> invoker, Invocation invocation) {\n-        if (result.hasException()) {\n-            fireThrowCallback(invoker, invocation, result.getException());\n-        } else {\n-            fireReturnCallback(invoker, invocation, result.getValue());\n-        }\n-    }\n-\n-    @Override\n-    public void onError(Throwable t, Invoker<?> invoker, Invocation invocation) {\n-        fireThrowCallback(invoker, invocation, t);\n-    }\n-\n-    private void fireInvokeCallback(final Invoker<?> invoker, final Invocation invocation) {\n-        final AsyncMethodInfo asyncMethodInfo = getAsyncMethodInfo(invoker, invocation);\n-        if (asyncMethodInfo == null) {\n-            return;\n-        }\n-        final Method onInvokeMethod = asyncMethodInfo.getOninvokeMethod();\n-        final Object onInvokeInst = asyncMethodInfo.getOninvokeInstance();\n-\n-        if (onInvokeMethod == null && onInvokeInst == null) {\n-            return;\n-        }\n-        if (onInvokeMethod == null || onInvokeInst == null) {\n-            throw new IllegalStateException(\"service:\" + invoker.getUrl().getServiceKey() + \" has a oninvoke callback config , but no such \" + (onInvokeMethod == null ? \"method\" : \"instance\") + \" found. url:\" + invoker.getUrl());\n-        }\n-\n-        ReflectUtils.makeAccessible(onInvokeMethod);\n-        Object[] params = invocation.getArguments();\n-        try {\n-            onInvokeMethod.invoke(onInvokeInst, params);\n-        } catch (InvocationTargetException e) {\n-            fireThrowCallback(invoker, invocation, e.getTargetException());\n-        } catch (Throwable e) {\n-            fireThrowCallback(invoker, invocation, e);\n-        }\n-    }\n-\n-    private void fireReturnCallback(final Invoker<?> invoker, final Invocation invocation, final Object result) {\n-        final AsyncMethodInfo asyncMethodInfo = getAsyncMethodInfo(invoker, invocation);\n-        if (asyncMethodInfo == null) {\n-            return;\n-        }\n-\n-        final Method onReturnMethod = asyncMethodInfo.getOnreturnMethod();\n-        final Object onReturnInst = asyncMethodInfo.getOnreturnInstance();\n-\n-        //not set onreturn callback\n-        if (onReturnMethod == null && onReturnInst == null) {\n-            return;\n-        }\n-\n-        if (onReturnMethod == null || onReturnInst == null) {\n-            throw new IllegalStateException(\"service:\" + invoker.getUrl().getServiceKey() + \" has a onreturn callback config , but no such \" + (onReturnMethod == null ? \"method\" : \"instance\") + \" found. url:\" + invoker.getUrl());\n-        }\n-        ReflectUtils.makeAccessible(onReturnMethod);\n-\n-        Object[] args = invocation.getArguments();\n-        Object[] params;\n-        Class<?>[] rParaTypes = onReturnMethod.getParameterTypes();\n-        if (rParaTypes.length > 1) {\n-            if (rParaTypes.length == 2 && rParaTypes[1].isAssignableFrom(Object[].class)) {\n-                params = new Object[2];\n-                params[0] = result;\n-                params[1] = args;\n-            } else {\n-                params = new Object[args.length + 1];\n-                params[0] = result;\n-                System.arraycopy(args, 0, params, 1, args.length);\n-            }\n-        } else {\n-            params = new Object[]{result};\n-        }\n-        try {\n-            onReturnMethod.invoke(onReturnInst, params);\n-        } catch (InvocationTargetException e) {\n-            fireThrowCallback(invoker, invocation, e.getTargetException());\n-        } catch (Throwable e) {\n-            fireThrowCallback(invoker, invocation, e);\n-        }\n-    }\n-\n-    private void fireThrowCallback(final Invoker<?> invoker, final Invocation invocation, final Throwable exception) {\n-        final AsyncMethodInfo asyncMethodInfo = getAsyncMethodInfo(invoker, invocation);\n-        if (asyncMethodInfo == null) {\n-            return;\n-        }\n-\n-        final Method onthrowMethod = asyncMethodInfo.getOnthrowMethod();\n-        final Object onthrowInst = asyncMethodInfo.getOnthrowInstance();\n-\n-        //onthrow callback not configured\n-        if (onthrowMethod == null && onthrowInst == null) {\n-            return;\n-        }\n-        if (onthrowMethod == null || onthrowInst == null) {\n-            throw new IllegalStateException(\"service:\" + invoker.getUrl().getServiceKey() + \" has a onthrow callback config , but no such \" + (onthrowMethod == null ? \"method\" : \"instance\") + \" found. url:\" + invoker.getUrl());\n-        }\n-        ReflectUtils.makeAccessible(onthrowMethod);\n-        Class<?>[] rParaTypes = onthrowMethod.getParameterTypes();\n-        if (rParaTypes[0].isAssignableFrom(exception.getClass())) {\n-            try {\n-                Object[] args = invocation.getArguments();\n-                Object[] params;\n-\n-                if (rParaTypes.length > 1) {\n-                    if (rParaTypes.length == 2 && rParaTypes[1].isAssignableFrom(Object[].class)) {\n-                        params = new Object[2];\n-                        params[0] = exception;\n-                        params[1] = args;\n-                    } else {\n-                        params = new Object[args.length + 1];\n-                        params[0] = exception;\n-                        System.arraycopy(args, 0, params, 1, args.length);\n-                    }\n-                } else {\n-                    params = new Object[]{exception};\n-                }\n-                onthrowMethod.invoke(onthrowInst, params);\n-            } catch (Throwable e) {\n-                logger.error(invocation.getMethodName() + \".call back method invoke error . callback method :\" + onthrowMethod + \", url:\" + invoker.getUrl(), e);\n-            }\n-        } else {\n-            logger.error(invocation.getMethodName() + \".call back method invoke error . callback method :\" + onthrowMethod + \", url:\" + invoker.getUrl(), exception);\n-        }\n-    }\n-\n-    private AsyncMethodInfo getAsyncMethodInfo(Invoker<?> invoker, Invocation invocation) {\n-        AsyncMethodInfo asyncMethodInfo = (AsyncMethodInfo) invocation.get(ASYNC_METHOD_INFO);\n-        if (asyncMethodInfo != null) {\n-            return asyncMethodInfo;\n-        }\n-\n-        ConsumerModel consumerModel = ApplicationModel.getConsumerModel(invoker.getUrl().getServiceKey());\n-        if (consumerModel == null) {\n-            return null;\n-        }\n-\n-        String methodName = invocation.getMethodName();\n-        if (methodName.equals($INVOKE)) {\n-            methodName = (String) invocation.getArguments()[0];\n-        }\n-\n-        return consumerModel.getAsyncInfo(methodName);\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.rpc.protocol.dubbo.filter;\r\n+\r\n+import org.apache.dubbo.common.constants.CommonConstants;\r\n+import org.apache.dubbo.common.extension.Activate;\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.ReflectUtils;\r\n+import org.apache.dubbo.rpc.Filter;\r\n+import org.apache.dubbo.rpc.Invocation;\r\n+import org.apache.dubbo.rpc.Invoker;\r\n+import org.apache.dubbo.rpc.Result;\r\n+import org.apache.dubbo.rpc.RpcException;\r\n+import org.apache.dubbo.rpc.model.ApplicationModel;\r\n+import org.apache.dubbo.rpc.model.AsyncMethodInfo;\r\n+import org.apache.dubbo.rpc.model.ConsumerModel;\r\n+\r\n+import java.lang.reflect.InvocationTargetException;\r\n+import java.lang.reflect.Method;\r\n+\r\n+import static org.apache.dubbo.common.constants.CommonConstants.$INVOKE;\r\n+import static org.apache.dubbo.rpc.protocol.dubbo.Constants.ASYNC_METHOD_INFO;\r\n+\r\n+/**\r\n+ * EventFilter\r\n+ */\r\n+@Activate(group = CommonConstants.CONSUMER)\r\n+public class FutureFilter implements Filter, Filter.Listener {\r\n+\r\n+    protected static final Logger logger = LoggerFactory.getLogger(FutureFilter.class);\r\n+\r\n+    @Override\r\n+    public Result invoke(final Invoker<?> invoker, final Invocation invocation) throws RpcException {\r\n+        fireInvokeCallback(invoker, invocation);\r\n+        // need to configure if there's return value before the invocation in order to help invoker to judge if it's\r\n+        // necessary to return future.\r\n+        return invoker.invoke(invocation);\r\n+    }\r\n+\r\n+    @Override\r\n+    public void onResponse(Result result, Invoker<?> invoker, Invocation invocation) {\r\n+        if (result.hasException()) {\r\n+            fireThrowCallback(invoker, invocation, result.getException());\r\n+        } else {\r\n+            fireReturnCallback(invoker, invocation, result.getValue());\r\n+        }\r\n+    }\r\n+\r\n+    @Override\r\n+    public void onError(Throwable t, Invoker<?> invoker, Invocation invocation) {\r\n+        fireThrowCallback(invoker, invocation, t);\r\n+    }\r\n+\r\n+    private void fireInvokeCallback(final Invoker<?> invoker, final Invocation invocation) {\r\n+        final AsyncMethodInfo asyncMethodInfo = getAsyncMethodInfo(invoker, invocation);\r\n+        if (asyncMethodInfo == null) {\r\n+            return;\r\n+        }\r\n+        final Method onInvokeMethod = asyncMethodInfo.getOninvokeMethod();\r\n+        final Object onInvokeInst = asyncMethodInfo.getOninvokeInstance();\r\n+\r\n+        if (onInvokeMethod == null && onInvokeInst == null) {\r\n+            return;\r\n+        }\r\n+        if (onInvokeMethod == null || onInvokeInst == null) {\r\n+            throw new IllegalStateException(\"service:\" + invoker.getUrl().getServiceKey() + \" has a oninvoke callback config , but no such \" + (onInvokeMethod == null ? \"method\" : \"instance\") + \" found. url:\" + invoker.getUrl());\r\n+        }\r\n+\r\n+        ReflectUtils.makeAccessible(onInvokeMethod);\r\n+        Object[] params = invocation.getArguments();\r\n+        try {\r\n+            onInvokeMethod.invoke(onInvokeInst, params);\r\n+        } catch (InvocationTargetException e) {\r\n+            fireThrowCallback(invoker, invocation, e.getTargetException());\r\n+        } catch (Throwable e) {\r\n+            fireThrowCallback(invoker, invocation, e);\r\n+        }\r\n+    }\r\n+\r\n+    private void fireReturnCallback(final Invoker<?> invoker, final Invocation invocation, final Object result) {\r\n+        final AsyncMethodInfo asyncMethodInfo = getAsyncMethodInfo(invoker, invocation);\r\n+        if (asyncMethodInfo == null) {\r\n+            return;\r\n+        }\r\n+\r\n+        final Method onReturnMethod = asyncMethodInfo.getOnreturnMethod();\r\n+        final Object onReturnInst = asyncMethodInfo.getOnreturnInstance();\r\n+\r\n+        //not set onreturn callback\r\n+        if (onReturnMethod == null && onReturnInst == null) {\r\n+            return;\r\n+        }\r\n+\r\n+        if (onReturnMethod == null || onReturnInst == null) {\r\n+            throw new IllegalStateException(\"service:\" + invoker.getUrl().getServiceKey() + \" has a onreturn callback config , but no such \" + (onReturnMethod == null ? \"method\" : \"instance\") + \" found. url:\" + invoker.getUrl());\r\n+        }\r\n+        ReflectUtils.makeAccessible(onReturnMethod);\r\n+\r\n+        Object[] args = invocation.getArguments();\r\n+        Object[] params;\r\n+        Class<?>[] rParaTypes = onReturnMethod.getParameterTypes();\r\n+        if (rParaTypes.length > 1) {\r\n+            if (rParaTypes.length == 2 && rParaTypes[1].isAssignableFrom(Object[].class)) {\r\n+                params = new Object[2];\r\n+                params[0] = result;\r\n+                params[1] = args;\r\n+            } else {\r\n+                params = new Object[args.length + 1];\r\n+                params[0] = result;\r\n+                System.arraycopy(args, 0, params, 1, args.length);\r\n+            }\r\n+        } else {\r\n+            params = new Object[]{result};\r\n+        }\r\n+        try {\r\n+            onReturnMethod.invoke(onReturnInst, params);\r\n+        } catch (InvocationTargetException e) {\r\n+            fireThrowCallback(invoker, invocation, e.getTargetException());\r\n+        } catch (Throwable e) {\r\n+            fireThrowCallback(invoker, invocation, e);\r\n+        }\r\n+    }\r\n+\r\n+    private void fireThrowCallback(final Invoker<?> invoker, final Invocation invocation, final Throwable exception) {\r\n+        final AsyncMethodInfo asyncMethodInfo = getAsyncMethodInfo(invoker, invocation);\r\n+        if (asyncMethodInfo == null) {\r\n+            return;\r\n+        }\r\n+\r\n+        final Method onthrowMethod = asyncMethodInfo.getOnthrowMethod();\r\n+        final Object onthrowInst = asyncMethodInfo.getOnthrowInstance();\r\n+\r\n+        //onthrow callback not configured\r\n+        if (onthrowMethod == null && onthrowInst == null) {\r\n+            return;\r\n+        }\r\n+        if (onthrowMethod == null || onthrowInst == null) {\r\n+            throw new IllegalStateException(\"service:\" + invoker.getUrl().getServiceKey() + \" has a onthrow callback config , but no such \" + (onthrowMethod == null ? \"method\" : \"instance\") + \" found. url:\" + invoker.getUrl());\r\n+        }\r\n+        ReflectUtils.makeAccessible(onthrowMethod);\r\n+        Class<?>[] rParaTypes = onthrowMethod.getParameterTypes();\r\n+        if (rParaTypes[0].isAssignableFrom(exception.getClass())) {\r\n+            try {\r\n+                Object[] args = invocation.getArguments();\r\n+                Object[] params;\r\n+\r\n+                if (rParaTypes.length > 1) {\r\n+                    if (rParaTypes.length == 2 && rParaTypes[1].isAssignableFrom(Object[].class)) {\r\n+                        params = new Object[2];\r\n+                        params[0] = exception;\r\n+                        params[1] = args;\r\n+                    } else {\r\n+                        params = new Object[args.length + 1];\r\n+                        params[0] = exception;\r\n+                        System.arraycopy(args, 0, params, 1, args.length);\r\n+                    }\r\n+                } else {\r\n+                    params = new Object[]{exception};\r\n+                }\r\n+                onthrowMethod.invoke(onthrowInst, params);\r\n+            } catch (Throwable e) {\r\n+                logger.error(invocation.getMethodName() + \".call back method invoke error . callback method :\" + onthrowMethod + \", url:\" + invoker.getUrl(), e);\r\n+            }\r\n+        } else {\r\n+            logger.error(invocation.getMethodName() + \".call back method invoke error . callback method :\" + onthrowMethod + \", url:\" + invoker.getUrl(), exception);\r\n+        }\r\n+    }\r\n+\r\n+    private AsyncMethodInfo getAsyncMethodInfo(Invoker<?> invoker, Invocation invocation) {\r\n+        AsyncMethodInfo asyncMethodInfo = (AsyncMethodInfo) invocation.get(ASYNC_METHOD_INFO);\r\n+        if (asyncMethodInfo != null) {\r\n+            return asyncMethodInfo;\r\n+        }\r\n+\r\n+        ConsumerModel consumerModel = ApplicationModel.getConsumerModel(invoker.getUrl().getServiceKey());\r\n+        if (consumerModel == null) {\r\n+            return null;\r\n+        }\r\n+\r\n+        String methodName = invocation.getMethodName();\r\n+        if (methodName.equals($INVOKE)) {\r\n+            methodName = (String) invocation.getArguments()[0];\r\n+        }\r\n+\r\n+        return consumerModel.getAsyncInfo(methodName);\r\n+    }\r\n+\r\n+}\r\n"}, {"source1": "org/apache/dubbo/rpc/protocol/dubbo/filter/TraceFilter.java", "source2": "org/apache/dubbo/rpc/protocol/dubbo/filter/TraceFilter.java", "comments": ["Line-ending differences only"], "unified_diff": "@@ -1,127 +1,127 @@\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.rpc.protocol.dubbo.filter;\n-\n-import org.apache.dubbo.common.constants.CommonConstants;\n-import org.apache.dubbo.common.extension.Activate;\n-import org.apache.dubbo.common.logger.Logger;\n-import org.apache.dubbo.common.logger.LoggerFactory;\n-import org.apache.dubbo.common.utils.CollectionUtils;\n-import org.apache.dubbo.common.utils.ConcurrentHashSet;\n-import org.apache.dubbo.remoting.Channel;\n-import org.apache.dubbo.remoting.Constants;\n-import org.apache.dubbo.rpc.Filter;\n-import org.apache.dubbo.rpc.Invocation;\n-import org.apache.dubbo.rpc.Invoker;\n-import org.apache.dubbo.rpc.Result;\n-import org.apache.dubbo.rpc.RpcContext;\n-import org.apache.dubbo.rpc.RpcException;\n-\n-import com.alibaba.fastjson.JSON;\n-\n-import java.util.ArrayList;\n-import java.util.Set;\n-import java.util.concurrent.ConcurrentHashMap;\n-import java.util.concurrent.ConcurrentMap;\n-import java.util.concurrent.atomic.AtomicInteger;\n-\n-/**\n- * TraceFilter\n- */\n-@Activate(group = CommonConstants.PROVIDER)\n-public class TraceFilter implements Filter {\n-\n-    private static final Logger logger = LoggerFactory.getLogger(TraceFilter.class);\n-\n-    private static final String TRACE_MAX = \"trace.max\";\n-\n-    private static final String TRACE_COUNT = \"trace.count\";\n-\n-    private static final ConcurrentMap<String, Set<Channel>> TRACERS = new ConcurrentHashMap<>();\n-\n-    public static void addTracer(Class<?> type, String method, Channel channel, int max) {\n-        channel.setAttribute(TRACE_MAX, max);\n-        channel.setAttribute(TRACE_COUNT, new AtomicInteger());\n-        String key = method != null && method.length() > 0 ? type.getName() + \".\" + method : type.getName();\n-        Set<Channel> channels = TRACERS.computeIfAbsent(key, k -> new ConcurrentHashSet<>());\n-        channels.add(channel);\n-    }\n-\n-    public static void removeTracer(Class<?> type, String method, Channel channel) {\n-        channel.removeAttribute(TRACE_MAX);\n-        channel.removeAttribute(TRACE_COUNT);\n-        String key = method != null && method.length() > 0 ? type.getName() + \".\" + method : type.getName();\n-        Set<Channel> channels = TRACERS.get(key);\n-        if (channels != null) {\n-            channels.remove(channel);\n-        }\n-    }\n-\n-    @Override\n-    public Result invoke(Invoker<?> invoker, Invocation invocation) throws RpcException {\n-        long start = System.currentTimeMillis();\n-        Result result = invoker.invoke(invocation);\n-        long end = System.currentTimeMillis();\n-        if (TRACERS.size() > 0) {\n-            String key = invoker.getInterface().getName() + \".\" + invocation.getMethodName();\n-            Set<Channel> channels = TRACERS.get(key);\n-            if (channels == null || channels.isEmpty()) {\n-                key = invoker.getInterface().getName();\n-                channels = TRACERS.get(key);\n-            }\n-            if (CollectionUtils.isNotEmpty(channels)) {\n-                for (Channel channel : new ArrayList<>(channels)) {\n-                    if (channel.isConnected()) {\n-                        try {\n-                            int max = 1;\n-                            Integer m = (Integer) channel.getAttribute(TRACE_MAX);\n-                            if (m != null) {\n-                                max = m;\n-                            }\n-                            int count = 0;\n-                            AtomicInteger c = (AtomicInteger) channel.getAttribute(TRACE_COUNT);\n-                            if (c == null) {\n-                                c = new AtomicInteger();\n-                                channel.setAttribute(TRACE_COUNT, c);\n-                            }\n-                            count = c.getAndIncrement();\n-                            if (count < max) {\n-                                String prompt = channel.getUrl().getParameter(Constants.PROMPT_KEY, Constants.DEFAULT_PROMPT);\n-                                channel.send(\"\\r\\n\" + RpcContext.getContext().getRemoteAddress() + \" -> \"\n-                                        + invoker.getInterface().getName()\n-                                        + \".\" + invocation.getMethodName()\n-                                        + \"(\" + JSON.toJSONString(invocation.getArguments()) + \")\" + \" -> \" + JSON.toJSONString(result.getValue())\n-                                        + \"\\r\\nelapsed: \" + (end - start) + \" ms.\"\n-                                        + \"\\r\\n\\r\\n\" + prompt);\n-                            }\n-                            if (count >= max - 1) {\n-                                channels.remove(channel);\n-                            }\n-                        } catch (Throwable e) {\n-                            channels.remove(channel);\n-                            logger.warn(e.getMessage(), e);\n-                        }\n-                    } else {\n-                        channels.remove(channel);\n-                    }\n-                }\n-            }\n-        }\n-        return result;\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.rpc.protocol.dubbo.filter;\r\n+\r\n+import org.apache.dubbo.common.constants.CommonConstants;\r\n+import org.apache.dubbo.common.extension.Activate;\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.CollectionUtils;\r\n+import org.apache.dubbo.common.utils.ConcurrentHashSet;\r\n+import org.apache.dubbo.remoting.Channel;\r\n+import org.apache.dubbo.remoting.Constants;\r\n+import org.apache.dubbo.rpc.Filter;\r\n+import org.apache.dubbo.rpc.Invocation;\r\n+import org.apache.dubbo.rpc.Invoker;\r\n+import org.apache.dubbo.rpc.Result;\r\n+import org.apache.dubbo.rpc.RpcContext;\r\n+import org.apache.dubbo.rpc.RpcException;\r\n+\r\n+import com.alibaba.fastjson.JSON;\r\n+\r\n+import java.util.ArrayList;\r\n+import java.util.Set;\r\n+import java.util.concurrent.ConcurrentHashMap;\r\n+import java.util.concurrent.ConcurrentMap;\r\n+import java.util.concurrent.atomic.AtomicInteger;\r\n+\r\n+/**\r\n+ * TraceFilter\r\n+ */\r\n+@Activate(group = CommonConstants.PROVIDER)\r\n+public class TraceFilter implements Filter {\r\n+\r\n+    private static final Logger logger = LoggerFactory.getLogger(TraceFilter.class);\r\n+\r\n+    private static final String TRACE_MAX = \"trace.max\";\r\n+\r\n+    private static final String TRACE_COUNT = \"trace.count\";\r\n+\r\n+    private static final ConcurrentMap<String, Set<Channel>> TRACERS = new ConcurrentHashMap<>();\r\n+\r\n+    public static void addTracer(Class<?> type, String method, Channel channel, int max) {\r\n+        channel.setAttribute(TRACE_MAX, max);\r\n+        channel.setAttribute(TRACE_COUNT, new AtomicInteger());\r\n+        String key = method != null && method.length() > 0 ? type.getName() + \".\" + method : type.getName();\r\n+        Set<Channel> channels = TRACERS.computeIfAbsent(key, k -> new ConcurrentHashSet<>());\r\n+        channels.add(channel);\r\n+    }\r\n+\r\n+    public static void removeTracer(Class<?> type, String method, Channel channel) {\r\n+        channel.removeAttribute(TRACE_MAX);\r\n+        channel.removeAttribute(TRACE_COUNT);\r\n+        String key = method != null && method.length() > 0 ? type.getName() + \".\" + method : type.getName();\r\n+        Set<Channel> channels = TRACERS.get(key);\r\n+        if (channels != null) {\r\n+            channels.remove(channel);\r\n+        }\r\n+    }\r\n+\r\n+    @Override\r\n+    public Result invoke(Invoker<?> invoker, Invocation invocation) throws RpcException {\r\n+        long start = System.currentTimeMillis();\r\n+        Result result = invoker.invoke(invocation);\r\n+        long end = System.currentTimeMillis();\r\n+        if (TRACERS.size() > 0) {\r\n+            String key = invoker.getInterface().getName() + \".\" + invocation.getMethodName();\r\n+            Set<Channel> channels = TRACERS.get(key);\r\n+            if (channels == null || channels.isEmpty()) {\r\n+                key = invoker.getInterface().getName();\r\n+                channels = TRACERS.get(key);\r\n+            }\r\n+            if (CollectionUtils.isNotEmpty(channels)) {\r\n+                for (Channel channel : new ArrayList<>(channels)) {\r\n+                    if (channel.isConnected()) {\r\n+                        try {\r\n+                            int max = 1;\r\n+                            Integer m = (Integer) channel.getAttribute(TRACE_MAX);\r\n+                            if (m != null) {\r\n+                                max = m;\r\n+                            }\r\n+                            int count = 0;\r\n+                            AtomicInteger c = (AtomicInteger) channel.getAttribute(TRACE_COUNT);\r\n+                            if (c == null) {\r\n+                                c = new AtomicInteger();\r\n+                                channel.setAttribute(TRACE_COUNT, c);\r\n+                            }\r\n+                            count = c.getAndIncrement();\r\n+                            if (count < max) {\r\n+                                String prompt = channel.getUrl().getParameter(Constants.PROMPT_KEY, Constants.DEFAULT_PROMPT);\r\n+                                channel.send(\"\\r\\n\" + RpcContext.getContext().getRemoteAddress() + \" -> \"\r\n+                                        + invoker.getInterface().getName()\r\n+                                        + \".\" + invocation.getMethodName()\r\n+                                        + \"(\" + JSON.toJSONString(invocation.getArguments()) + \")\" + \" -> \" + JSON.toJSONString(result.getValue())\r\n+                                        + \"\\r\\nelapsed: \" + (end - start) + \" ms.\"\r\n+                                        + \"\\r\\n\\r\\n\" + prompt);\r\n+                            }\r\n+                            if (count >= max - 1) {\r\n+                                channels.remove(channel);\r\n+                            }\r\n+                        } catch (Throwable e) {\r\n+                            channels.remove(channel);\r\n+                            logger.warn(e.getMessage(), e);\r\n+                        }\r\n+                    } else {\r\n+                        channels.remove(channel);\r\n+                    }\r\n+                }\r\n+            }\r\n+        }\r\n+        return result;\r\n+    }\r\n+\r\n+}\r\n"}, {"source1": "org/apache/dubbo/rpc/protocol/dubbo/status/ServerStatusChecker.java", "source2": "org/apache/dubbo/rpc/protocol/dubbo/status/ServerStatusChecker.java", "comments": ["Line-ending differences only"], "unified_diff": "@@ -1,61 +1,61 @@\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.rpc.protocol.dubbo.status;\n-\n-import org.apache.dubbo.common.extension.Activate;\n-import org.apache.dubbo.common.status.Status;\n-import org.apache.dubbo.common.status.StatusChecker;\n-import org.apache.dubbo.remoting.RemotingServer;\n-import org.apache.dubbo.rpc.ProtocolServer;\n-import org.apache.dubbo.rpc.protocol.dubbo.DubboProtocol;\n-\n-import java.util.List;\n-\n-/**\n- * ServerStatusChecker\n- */\n-@Activate\n-public class ServerStatusChecker implements StatusChecker {\n-\n-    @Override\n-    public Status check() {\n-        List<ProtocolServer> servers = DubboProtocol.getDubboProtocol().getServers();\n-        if (servers == null || servers.isEmpty()) {\n-            return new Status(Status.Level.UNKNOWN);\n-        }\n-        Status.Level level = Status.Level.OK;\n-        StringBuilder buf = new StringBuilder();\n-        for (ProtocolServer protocolServer : servers) {\n-            RemotingServer server = protocolServer.getRemotingServer();\n-            if (!server.isBound()) {\n-                level = Status.Level.ERROR;\n-                buf.setLength(0);\n-                buf.append(server.getLocalAddress());\n-                break;\n-            }\n-            if (buf.length() > 0) {\n-                buf.append(\",\");\n-            }\n-            buf.append(server.getLocalAddress());\n-            buf.append(\"(clients:\");\n-            buf.append(server.getChannels().size());\n-            buf.append(\")\");\n-        }\n-        return new Status(level, buf.toString());\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.rpc.protocol.dubbo.status;\r\n+\r\n+import org.apache.dubbo.common.extension.Activate;\r\n+import org.apache.dubbo.common.status.Status;\r\n+import org.apache.dubbo.common.status.StatusChecker;\r\n+import org.apache.dubbo.remoting.RemotingServer;\r\n+import org.apache.dubbo.rpc.ProtocolServer;\r\n+import org.apache.dubbo.rpc.protocol.dubbo.DubboProtocol;\r\n+\r\n+import java.util.List;\r\n+\r\n+/**\r\n+ * ServerStatusChecker\r\n+ */\r\n+@Activate\r\n+public class ServerStatusChecker implements StatusChecker {\r\n+\r\n+    @Override\r\n+    public Status check() {\r\n+        List<ProtocolServer> servers = DubboProtocol.getDubboProtocol().getServers();\r\n+        if (servers == null || servers.isEmpty()) {\r\n+            return new Status(Status.Level.UNKNOWN);\r\n+        }\r\n+        Status.Level level = Status.Level.OK;\r\n+        StringBuilder buf = new StringBuilder();\r\n+        for (ProtocolServer protocolServer : servers) {\r\n+            RemotingServer server = protocolServer.getRemotingServer();\r\n+            if (!server.isBound()) {\r\n+                level = Status.Level.ERROR;\r\n+                buf.setLength(0);\r\n+                buf.append(server.getLocalAddress());\r\n+                break;\r\n+            }\r\n+            if (buf.length() > 0) {\r\n+                buf.append(\",\");\r\n+            }\r\n+            buf.append(server.getLocalAddress());\r\n+            buf.append(\"(clients:\");\r\n+            buf.append(server.getChannels().size());\r\n+            buf.append(\")\");\r\n+        }\r\n+        return new Status(level, buf.toString());\r\n+    }\r\n+\r\n+}\r\n"}, {"source1": "org/apache/dubbo/rpc/protocol/dubbo/status/ThreadPoolStatusChecker.java", "source2": "org/apache/dubbo/rpc/protocol/dubbo/status/ThreadPoolStatusChecker.java", "comments": ["Line-ending differences only"], "unified_diff": "@@ -1,67 +1,67 @@\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.rpc.protocol.dubbo.status;\n-\n-import org.apache.dubbo.common.constants.CommonConstants;\n-import org.apache.dubbo.common.extension.Activate;\n-import org.apache.dubbo.common.extension.ExtensionLoader;\n-import org.apache.dubbo.common.status.Status;\n-import org.apache.dubbo.common.status.StatusChecker;\n-import org.apache.dubbo.common.store.DataStore;\n-\n-import java.util.Map;\n-import java.util.concurrent.ExecutorService;\n-import java.util.concurrent.ThreadPoolExecutor;\n-\n-/**\n- * ThreadPoolStatusChecker\n- */\n-@Activate\n-public class ThreadPoolStatusChecker implements StatusChecker {\n-\n-    @Override\n-    public Status check() {\n-        DataStore dataStore = ExtensionLoader.getExtensionLoader(DataStore.class).getDefaultExtension();\n-        Map<String, Object> executors = dataStore.get(CommonConstants.EXECUTOR_SERVICE_COMPONENT_KEY);\n-\n-        StringBuilder msg = new StringBuilder();\n-        Status.Level level = Status.Level.OK;\n-        for (Map.Entry<String, Object> entry : executors.entrySet()) {\n-            String port = entry.getKey();\n-            ExecutorService executor = (ExecutorService) entry.getValue();\n-\n-            if (executor instanceof ThreadPoolExecutor) {\n-                ThreadPoolExecutor tp = (ThreadPoolExecutor) executor;\n-                boolean ok = tp.getActiveCount() < tp.getMaximumPoolSize() - 1;\n-                Status.Level lvl = Status.Level.OK;\n-                if (!ok) {\n-                    level = Status.Level.WARN;\n-                    lvl = Status.Level.WARN;\n-                }\n-\n-                if (msg.length() > 0) {\n-                    msg.append(\";\");\n-                }\n-                msg.append(\"Pool status:\").append(lvl).append(\", max:\").append(tp.getMaximumPoolSize()).append(\", core:\")\n-                        .append(tp.getCorePoolSize()).append(\", largest:\").append(tp.getLargestPoolSize()).append(\", active:\")\n-                        .append(tp.getActiveCount()).append(\", task:\").append(tp.getTaskCount()).append(\", service port: \").append(port);\n-            }\n-        }\n-        return msg.length() == 0 ? new Status(Status.Level.UNKNOWN) : new Status(level, msg.toString());\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.rpc.protocol.dubbo.status;\r\n+\r\n+import org.apache.dubbo.common.constants.CommonConstants;\r\n+import org.apache.dubbo.common.extension.Activate;\r\n+import org.apache.dubbo.common.extension.ExtensionLoader;\r\n+import org.apache.dubbo.common.status.Status;\r\n+import org.apache.dubbo.common.status.StatusChecker;\r\n+import org.apache.dubbo.common.store.DataStore;\r\n+\r\n+import java.util.Map;\r\n+import java.util.concurrent.ExecutorService;\r\n+import java.util.concurrent.ThreadPoolExecutor;\r\n+\r\n+/**\r\n+ * ThreadPoolStatusChecker\r\n+ */\r\n+@Activate\r\n+public class ThreadPoolStatusChecker implements StatusChecker {\r\n+\r\n+    @Override\r\n+    public Status check() {\r\n+        DataStore dataStore = ExtensionLoader.getExtensionLoader(DataStore.class).getDefaultExtension();\r\n+        Map<String, Object> executors = dataStore.get(CommonConstants.EXECUTOR_SERVICE_COMPONENT_KEY);\r\n+\r\n+        StringBuilder msg = new StringBuilder();\r\n+        Status.Level level = Status.Level.OK;\r\n+        for (Map.Entry<String, Object> entry : executors.entrySet()) {\r\n+            String port = entry.getKey();\r\n+            ExecutorService executor = (ExecutorService) entry.getValue();\r\n+\r\n+            if (executor instanceof ThreadPoolExecutor) {\r\n+                ThreadPoolExecutor tp = (ThreadPoolExecutor) executor;\r\n+                boolean ok = tp.getActiveCount() < tp.getMaximumPoolSize() - 1;\r\n+                Status.Level lvl = Status.Level.OK;\r\n+                if (!ok) {\r\n+                    level = Status.Level.WARN;\r\n+                    lvl = Status.Level.WARN;\r\n+                }\r\n+\r\n+                if (msg.length() > 0) {\r\n+                    msg.append(\";\");\r\n+                }\r\n+                msg.append(\"Pool status:\").append(lvl).append(\", max:\").append(tp.getMaximumPoolSize()).append(\", core:\")\r\n+                        .append(tp.getCorePoolSize()).append(\", largest:\").append(tp.getLargestPoolSize()).append(\", active:\")\r\n+                        .append(tp.getActiveCount()).append(\", task:\").append(tp.getTaskCount()).append(\", service port: \").append(port);\r\n+            }\r\n+        }\r\n+        return msg.length() == 0 ? new Status(Status.Level.UNKNOWN) : new Status(level, msg.toString());\r\n+    }\r\n+\r\n+}\r\n"}]}
