LyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogQ29weXJpZ2h0IChjKSAyMDA0LCAyMDE3IElCTSBDb3Jwb3JhdGlvbiBhbmQgb3RoZXJzLgogKiBBbGwgcmlnaHRzIHJlc2VydmVkLiBUaGlzIHByb2dyYW0gYW5kIHRoZSBhY2NvbXBhbnlpbmcgbWF0ZXJpYWxzCiAqIGFyZSBtYWRlIGF2YWlsYWJsZSB1bmRlciB0aGUgdGVybXMgb2YgdGhlIEVjbGlwc2UgUHVibGljIExpY2Vuc2UgdjEuMAogKiB3aGljaCBhY2NvbXBhbmllcyB0aGlzIGRpc3RyaWJ1dGlvbiwgYW5kIGlzIGF2YWlsYWJsZSBhdAogKiBodHRwOi8vd3d3LmVjbGlwc2Uub3JnL2xlZ2FsL2VwbC12MTAuaHRtbAogKgogKiBDb250cmlidXRvcnM6CiAqICAgICBJQk0gQ29ycG9yYXRpb24gLSBpbml0aWFsIEFQSSBhbmQgaW1wbGVtZW50YXRpb24KICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCnBhY2thZ2Ugb3JnLmVjbGlwc2UuY29yZS50ZXN0cy5yZXNvdXJjZXMuY29udGVudDsKCmltcG9ydCBqYXZhLmlvLio7CmltcG9ydCBqYXZhLnV0aWwuSGFzaFNldDsKaW1wb3J0IGphdmEudXRpbC5TZXQ7CmltcG9ydCBqdW5pdC5mcmFtZXdvcmsuQXNzZXJ0aW9uRmFpbGVkRXJyb3I7CmltcG9ydCBqdW5pdC5mcmFtZXdvcmsuVGVzdDsKaW1wb3J0IG9yZy5lY2xpcHNlLmNvcmUuaW50ZXJuYWwuY29udGVudC4qOwppbXBvcnQgb3JnLmVjbGlwc2UuY29yZS5ydW50aW1lLio7CmltcG9ydCBvcmcuZWNsaXBzZS5jb3JlLnJ1bnRpbWUuY29udGVudC4qOwppbXBvcnQgb3JnLmVjbGlwc2UuY29yZS5ydW50aW1lLmNvbnRlbnQuSUNvbnRlbnRUeXBlTWFuYWdlci5Db250ZW50VHlwZUNoYW5nZUV2ZW50OwppbXBvcnQgb3JnLmVjbGlwc2UuY29yZS5ydW50aW1lLmNvbnRlbnQuWE1MQ29udGVudERlc2NyaWJlcjsKaW1wb3J0IG9yZy5lY2xpcHNlLmNvcmUucnVudGltZS5qb2JzLkpvYjsKaW1wb3J0IG9yZy5lY2xpcHNlLmNvcmUucnVudGltZS5wcmVmZXJlbmNlcy4qOwppbXBvcnQgb3JnLmVjbGlwc2UuY29yZS50ZXN0cy5oYXJuZXNzLkJ1bmRsZVRlc3RpbmdIZWxwZXI7CmltcG9ydCBvcmcuZWNsaXBzZS5jb3JlLnRlc3RzLmhhcm5lc3MuVGVzdFJlZ2lzdHJ5Q2hhbmdlTGlzdGVuZXI7CmltcG9ydCBvcmcuZWNsaXBzZS50ZXN0Lk9yZGVyZWRUZXN0U3VpdGU7CmltcG9ydCBvcmcub3NnaS5zZXJ2aWNlLnByZWZzLkJhY2tpbmdTdG9yZUV4Y2VwdGlvbjsKaW1wb3J0IG9yZy5vc2dpLnNlcnZpY2UucHJlZnMuUHJlZmVyZW5jZXM7CgpwdWJsaWMgY2xhc3MgSUNvbnRlbnRUeXBlTWFuYWdlclRlc3QgZXh0ZW5kcyBDb250ZW50VHlwZVRlc3QgewoKCXByaXZhdGUgc3RhdGljIGNsYXNzIENvbnRlbnRUeXBlQ2hhbmdlVHJhY2VyIGltcGxlbWVudHMgSUNvbnRlbnRUeXBlTWFuYWdlci5JQ29udGVudFR5cGVDaGFuZ2VMaXN0ZW5lciB7CgkJcHJpdmF0ZSBmaW5hbCBTZXQ8SUNvbnRlbnRUeXBlPiBjaGFuZ2VkID0gbmV3IEhhc2hTZXQ8PigpOwoKCQlwdWJsaWMgQ29udGVudFR5cGVDaGFuZ2VUcmFjZXIoKSB7CgkJfQoKCQlAT3ZlcnJpZGUKCQlwdWJsaWMgdm9pZCBjb250ZW50VHlwZUNoYW5nZWQoQ29udGVudFR5cGVDaGFuZ2VFdmVudCBldmVudCkgewoJCQljaGFuZ2VkLmFkZChldmVudC5nZXRDb250ZW50VHlwZSgpKTsKCQl9CgoJCXB1YmxpYyBib29sZWFuIGlzT25seUNoYW5nZShJQ29udGVudFR5cGUgbXlUeXBlKSB7CgkJCXJldHVybiBjaGFuZ2VkLnNpemUoKSA9PSAxICYmIGNoYW5nZWQuY29udGFpbnMobXlUeXBlKTsKCQl9CgoJCXB1YmxpYyB2b2lkIHJlc2V0KCkgewoJCQljaGFuZ2VkLmNsZWFyKCk7CgkJfQoJfQoKCS8vIFhYWCB0aGlzIGlzIGNvcGllZCBmcm9tIENoYXJzZXREZWx0YUpvYiBpbiB0aGUgcmVzb3VyY2VzIHBsdWctaW4KCXByaXZhdGUgc3RhdGljIGZpbmFsIFN0cmluZyBGQU1JTFlfQ0hBUlNFVF9ERUxUQSA9ICJvcmcuZWNsaXBzZS5jb3JlLnJlc291cmNlcy5jaGFyc2V0Sm9iRmFtaWx5IjsKCglwcml2YXRlIGZpbmFsIHN0YXRpYyBTdHJpbmcgTUlOSU1BTF9YTUwgPSAiPD94bWwgdmVyc2lvbj1cIjEuMFwiPz48b3JnLmVjbGlwc2UuY29yZS5yZXNvdXJjZXMudGVzdHMucm9vdC8+IjsKCXByaXZhdGUgZmluYWwgc3RhdGljIFN0cmluZyBTQU1QTEVfQklOMV9PRkZTRVQgPSAiMTIzNDUiOwoJcHJpdmF0ZSBmaW5hbCBzdGF0aWMgYnl0ZVtdIFNBTVBMRV9CSU4xX1NJR05BVFVSRSA9IHsweDEwLCAoYnl0ZSkgMHhBQiwgKGJ5dGUpIDB4Q0QsIChieXRlKSAweEZGfTsKCXByaXZhdGUgZmluYWwgc3RhdGljIFN0cmluZyBTQU1QTEVfQklOMl9PRkZTRVQgPSAiIjsKCXByaXZhdGUgZmluYWwgc3RhdGljIGJ5dGVbXSBTQU1QTEVfQklOMl9TSUdOQVRVUkUgPSB7MHgxMCwgKGJ5dGUpIDB4QUIsIChieXRlKSAweENELCAoYnl0ZSkgMHhFRn07Cglwcml2YXRlIGZpbmFsIHN0YXRpYyBTdHJpbmcgWE1MX0RURF9FWFRFUk5BTF9FTlRJVFkgPSAiPD94bWwgdmVyc2lvbj1cIjEuMFwiPz48IURPQ1RZUEUgcHJvamVjdCAgU1lTVEVNIFwib3JnLmVjbGlwc2UuY29yZS5yZXNvdXJjZXMudGVzdHMuc29tZS5kdGRcIiAgWzwhRU5USVRZIHNvbWVlbnRpdHkgU1lTVEVNIFwic29tZWVudGl0eS54bWxcIj5dPjxvcmcuZWNsaXBzZS5jb3JlLnJlc291cmNlcy50ZXN0cy5yb290Lz4iOwoJcHJpdmF0ZSBmaW5hbCBzdGF0aWMgU3RyaW5nIFhNTF9EVERfVVNfQVNDSUkgPSAiPD94bWwgdmVyc2lvbj1cIjEuMFwiIGVuY29kaW5nPVwiVVMtQVNDSUlcIj8+PCFET0NUWVBFIHNvbWV0eXBlIFNZU1RFTSBcIm9yZy5lY2xpcHNlLmNvcmUucmVzb3VyY2VzLnRlc3RzLnNvbWUuZHRkXCI+PG9yZy5lY2xpcHNlLmNvcmUucmVzb3VyY2VzLnRlc3RzLnJvb3QvPiI7Cglwcml2YXRlIGZpbmFsIHN0YXRpYyBTdHJpbmcgWE1MX0lTT184ODU5XzEgPSAiPD94bWwgdmVyc2lvbj1cIjEuMFwiIGVuY29kaW5nPVwiSVNPLTg4NTktMVwiPz48b3JnLmVjbGlwc2UuY29yZS5yZXNvdXJjZXMudGVzdHMucm9vdC8+IjsKCXByaXZhdGUgZmluYWwgc3RhdGljIFN0cmluZyBYTUxfSVNPXzg4NTlfMV9TSU5HTEVfUVVPVEVTID0gIjw/eG1sIHZlcnNpb249JzEuMCcgZW5jb2Rpbmc9J0lTTy04ODU5LTEnPz48b3JnLmVjbGlwc2UuY29yZS5yZXNvdXJjZXMudGVzdHMucm9vdC8+IjsKCXByaXZhdGUgZmluYWwgc3RhdGljIFN0cmluZyBYTUxfUk9PVF9FTEVNRU5UX0VYVEVSTkFMX0VOVElUWSA9ICI8P3htbCB2ZXJzaW9uPVwiMS4wXCI/PjwhRE9DVFlQRSBwcm9qZWN0ICAgWzwhRU5USVRZIHNvbWVlbnRpdHkgU1lTVEVNIFwic29tZWVudGl0eS54bWxcIj5dPjxvcmcuZWNsaXBzZS5jb3JlLnJlc291cmNlcy50ZXN0cy5yb290LWVsZW1lbnQvPiI7Cglwcml2YXRlIGZpbmFsIHN0YXRpYyBTdHJpbmcgWE1MX1JPT1RfRUxFTUVOVF9FWFRFUk5BTF9FTlRJVFkyID0gIjw/eG1sIHZlcnNpb249XCIxLjBcIj8+PCFET0NUWVBFIG9yZy5lY2xpcHNlLmNvcmUucmVzb3VyY2VzLnRlc3RzLnJvb3QtZWxlbWVudCBQVUJMSUMgXCJvcmcuZWNsaXBzZS5jb3JlLnJlc291cmNlcy50ZXN0cy5yb290LWVsZW1lbnRJZFwiIFwib3JnLmVjbGlwc2UuY29yZS5yZXNvdXJjZXMudGVzdHMucm9vdC1lbGVtZW50LmR0ZFwiID48b3JnLmVjbGlwc2UuY29yZS5yZXNvdXJjZXMudGVzdHMucm9vdC1lbGVtZW50Lz4iOwoJcHJpdmF0ZSBmaW5hbCBzdGF0aWMgU3RyaW5nIFhNTF9ST09UX0VMRU1FTlRfSVNPXzg4NTlfMSA9ICI8P3htbCB2ZXJzaW9uPVwiMS4wXCIgZW5jb2Rpbmc9XCJJU08tODg1OS0xXCI/PjxvcmcuZWNsaXBzZS5jb3JlLnJlc291cmNlcy50ZXN0cy5yb290LWVsZW1lbnQvPiI7Cglwcml2YXRlIGZpbmFsIHN0YXRpYyBTdHJpbmcgWE1MX1JPT1RfRUxFTUVOVF9OT19ERUNMID0gIjxvcmcuZWNsaXBzZS5jb3JlLnJlc291cmNlcy50ZXN0cy5yb290LWVsZW1lbnQvPiI7Cglwcml2YXRlIGZpbmFsIHN0YXRpYyBTdHJpbmcgWE1MX1VTX0FTQ0lJX0lOVkFMSUQgPSAiPD94bWwgdmVyc2lvbj0nMS4wJyBlbmNvZGluZz0ndXMtYXNjaWknPz48IS0tIE5vbi1BU0NJSSBjaGFyczog4ent8/ogLS0+PG9yZy5lY2xpcHNlLmNvcmUucmVzb3VyY2VzLnRlc3RzLnJvb3QvPiI7Cglwcml2YXRlIGZpbmFsIHN0YXRpYyBTdHJpbmcgWE1MX1VURl8xNiA9ICI8P3htbCB2ZXJzaW9uPVwiMS4wXCIgZW5jb2Rpbmc9XCJVVEYtMTZcIj8+PG9yZy5lY2xpcHNlLmNvcmUucmVzb3VyY2VzLnRlc3RzLnJvb3QvPiI7Cglwcml2YXRlIGZpbmFsIHN0YXRpYyBTdHJpbmcgWE1MX1VURl8xNkJFID0gIjw/eG1sIHZlcnNpb249XCIxLjBcIiBlbmNvZGluZz1cIlVURi0xNkJFXCI/PjxvcmcuZWNsaXBzZS5jb3JlLnJlc291cmNlcy50ZXN0cy5yb290Lz4iOwoJcHJpdmF0ZSBmaW5hbCBzdGF0aWMgU3RyaW5nIFhNTF9VVEZfMTZMRSA9ICI8P3htbCB2ZXJzaW9uPVwiMS4wXCIgZW5jb2Rpbmc9XCJVVEYtMTZMRVwiPz48b3JnLmVjbGlwc2UuY29yZS5yZXNvdXJjZXMudGVzdHMucm9vdC8+IjsKCXByaXZhdGUgZmluYWwgc3RhdGljIFN0cmluZyBYTUxfVVRGXzggPSAiPD94bWwgdmVyc2lvbj1cIjEuMFwiIGVuY29kaW5nPVwiVVRGLThcIj8+PG9yZy5lY2xpcHNlLmNvcmUucmVzb3VyY2VzLnRlc3RzLnJvb3QvPiI7CgoJLy8gdXNlZCBhbHNvIGJ5IEZpbGVQcm9wZXJ0eVRlc3RlclRlc3QKCXB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIFhNTF9ST09UX0VMRU1FTlRfTlNfTUFUQ0gxID0gIjw/eG1sIHZlcnNpb249XCIxLjBcIiBlbmNvZGluZz1cIklTTy04ODU5LTFcIj8+PHByZWZpeDpyb290RWxlbWVudDEgeG1sbnM6cHJlZml4PSd1cm46ZWNsaXBzZS5jb3JlLnJ1bnRpbWUubnMxJy8+IjsKCglwcml2YXRlIHN0YXRpYyBmaW5hbCBTdHJpbmcgWE1MX1JPT1RfRUxFTUVOVF9OU19NQVRDSDIgPSAiPD94bWwgdmVyc2lvbj1cIjEuMFwiIGVuY29kaW5nPVwiSVNPLTg4NTktMVwiPz48IURPQ1RZUEUgcm9vdEVsZW1lbnQyIFNZU1RFTSBcIm9yZy5lY2xpcHNlLmNvcmUucmVzb3VyY2VzLnRlc3RzLm5vdGhpbmdcIj48cm9vdEVsZW1lbnQyIHhtbG5zPSd1cm46ZWNsaXBzZS5jb3JlLnJ1bnRpbWUubnMyJy8+IjsKCXByaXZhdGUgc3RhdGljIGZpbmFsIFN0cmluZyBYTUxfUk9PVF9FTEVNRU5UX05TX1dST05HX0VMRU0gPSAiPD94bWwgdmVyc2lvbj1cIjEuMFwiIGVuY29kaW5nPVwiSVNPLTg4NTktMVwiPz48cm9vdEVsZW1lbnQzIHhtbG5zPSd1cm46ZWNsaXBzZS5jb3JlLnJ1bnRpbWUubnMyJy8+IjsKCXByaXZhdGUgc3RhdGljIGZpbmFsIFN0cmluZyBYTUxfUk9PVF9FTEVNRU5UX05TX1dST05HX05TID0gIjw/eG1sIHZlcnNpb249XCIxLjBcIiBlbmNvZGluZz1cIklTTy04ODU5LTFcIj8+PHByZWZpeDpyb290RWxlbWVudDEgeG1sbnM9J2h0dHA6Ly9leGFtcGxlLmNvbS8nLz4iOwoJcHJpdmF0ZSBzdGF0aWMgZmluYWwgU3RyaW5nIFhNTF9ST09UX0VMRU1FTlRfTlNfTUlYVVAgPSAiPD94bWwgdmVyc2lvbj1cIjEuMFwiIGVuY29kaW5nPVwiSVNPLTg4NTktMVwiPz48cm9vdEVsZW1lbnQyIHhtbG5zPSd1cm46ZWNsaXBzZS5jb3JlLnJ1bnRpbWUubnMxJy8+IjsKCXByaXZhdGUgc3RhdGljIGZpbmFsIFN0cmluZyBYTUxfUk9PVF9FTEVNRU5UX05TX1dJTERDQVJEID0gIjw/eG1sIHZlcnNpb249XCIxLjBcIiBlbmNvZGluZz1cIklTTy04ODU5LTFcIj8+PHdlQ291bGRQdXRBbnl0aGluZ0hlcmUgeG1sbnM9J3VybjplY2xpcHNlLmNvcmUucnVudGltZS5uc1dpbGQnLz4iOwoJcHJpdmF0ZSBmaW5hbCBzdGF0aWMgU3RyaW5nIFhNTF9ST09UX0VMRU1FTlRfTlNfV0lMRENBUkQyID0gIjw/eG1sIHZlcnNpb249XCIxLjBcIiBlbmNvZGluZz1cIlVTLUFTQ0lJXCI/PjwhRE9DVFlQRSBKb2tlciBTWVNURU0gXCJvcmcuZWNsaXBzZS5jb3JlLnJlc291cmNlcy50ZXN0cy5zb21lLmR0ZDNcIj48Sm9rZXIvPiI7Cglwcml2YXRlIGZpbmFsIHN0YXRpYyBTdHJpbmcgWE1MX1JPT1RfRUxFTUVOVF9FTVBUWV9OUyA9ICI8P3htbCB2ZXJzaW9uPVwiMS4wXCIgZW5jb2Rpbmc9XCJVUy1BU0NJSVwiPz48IURPQ1RZUEUgSm9rZXIgU1lTVEVNIFwib3JnLmVjbGlwc2UuY29yZS5yZXNvdXJjZXMudGVzdHMuc29tZS5kdGQzXCI+PHJvb3RFbGVtZW50PiI7CgoJcHVibGljIHN0YXRpYyBUZXN0IHN1aXRlKCkgewoJCXJldHVybiBuZXcgT3JkZXJlZFRlc3RTdWl0ZShJQ29udGVudFR5cGVNYW5hZ2VyVGVzdC5jbGFzcyk7Cgl9CgoJcHVibGljIElDb250ZW50VHlwZU1hbmFnZXJUZXN0KFN0cmluZyBuYW1lKSB7CgkJc3VwZXIobmFtZSk7Cgl9CgoJLyoqCgkgKiBIZWxwcyB0byBlbnN1cmUgd2UgZG9uJ3QgZ2V0IGZvb2xlZCBieSBjYXNlIHNlbnNpdGl2aXR5IGluIGZpbGUgbmFtZXMvc3BlY3MuCgkgKi8KCXByaXZhdGUgU3RyaW5nIGNoYW5nZUNhc2UoU3RyaW5nIG9yaWdpbmFsKSB7CgkJU3RyaW5nQnVmZmVyIHJlc3VsdCA9IG5ldyBTdHJpbmdCdWZmZXIob3JpZ2luYWwpOwoJCWZvciAoaW50IGkgPSByZXN1bHQubGVuZ3RoKCkgLSAxOyBpID49IDA7IGktLSkgewoJCQljaGFyIG9yaWdpbmFsQ2hhciA9IG9yaWdpbmFsLmNoYXJBdChpKTsKCQkJcmVzdWx0LnNldENoYXJBdChpLCBpICUgMiA9PSAwID8gQ2hhcmFjdGVyLnRvTG93ZXJDYXNlKG9yaWdpbmFsQ2hhcikgOiBDaGFyYWN0ZXIudG9VcHBlckNhc2Uob3JpZ2luYWxDaGFyKSk7CgkJfQoJCXJldHVybiByZXN1bHQudG9TdHJpbmcoKTsKCX0KCglib29sZWFuIGNvbnRhaW5zKE9iamVjdFtdIGFycmF5LCBPYmplY3QgZWxlbWVudCkgewoJCWZvciAoT2JqZWN0IGVsZW1lbnQyIDogYXJyYXkpIHsKCQkJaWYgKGVsZW1lbnQyLmVxdWFscyhlbGVtZW50KSkgewoJCQkJcmV0dXJuIHRydWU7CgkJCX0KCQl9CgkJcmV0dXJuIGZhbHNlOwoJfQoKCXByaXZhdGUgSUNvbnRlbnREZXNjcmlwdGlvbiBnZXREZXNjcmlwdGlvbkZvcihJQ29udGVudFR5cGVNYXRjaGVyIGZpbmRlciwgU3RyaW5nIGNvbnRlbnRzLCBTdHJpbmcgZW5jb2RpbmcsIFN0cmluZyBmaWxlTmFtZSwgUXVhbGlmaWVkTmFtZVtdIG9wdGlvbnMsIGJvb2xlYW4gdGV4dCkgdGhyb3dzIFVuc3VwcG9ydGVkRW5jb2RpbmdFeGNlcHRpb24sIElPRXhjZXB0aW9uIHsKCQlyZXR1cm4gdGV4dCA/IGZpbmRlci5nZXREZXNjcmlwdGlvbkZvcihnZXRSZWFkZXIoY29udGVudHMpLCBmaWxlTmFtZSwgb3B0aW9ucykgOiBmaW5kZXIuZ2V0RGVzY3JpcHRpb25Gb3IoZ2V0SW5wdXRTdHJlYW0oY29udGVudHMsIGVuY29kaW5nKSwgZmlsZU5hbWUsIG9wdGlvbnMpOwoJfQoKCXB1YmxpYyBJbnB1dFN0cmVhbSBnZXRJbnB1dFN0cmVhbShieXRlW11bXSBjb250ZW50cykgewoJCWludCBzaXplID0gMDsKCQkvLyBjb21wdXRlcyBmaW5hbCBhcnJheSBzaXplCgkJZm9yIChieXRlW10gY29udGVudCA6IGNvbnRlbnRzKSB7CgkJCXNpemUgKz0gY29udGVudC5sZW5ndGg7CgkJfQoJCWJ5dGVbXSBmdWxsID0gbmV3IGJ5dGVbc2l6ZV07CgkJaW50IGZ1bGxJbmRleCA9IDA7CgkJLy8gY29uY2F0ZW5hdGVzIGFsbCBieXRlIGFycmF5cwoJCWZvciAoYnl0ZVtdIGNvbnRlbnQgOiBjb250ZW50cykgewoJCQlmb3IgKGludCBqID0gMDsgaiA8IGNvbnRlbnQubGVuZ3RoOyBqKyspIHsKCQkJCWZ1bGxbZnVsbEluZGV4KytdID0gY29udGVudFtqXTsKCQkJfQoJCX0KCQlyZXR1cm4gbmV3IEJ5dGVBcnJheUlucHV0U3RyZWFtKGZ1bGwpOwoJfQoKCXB1YmxpYyBJbnB1dFN0cmVhbSBnZXRJbnB1dFN0cmVhbShTdHJpbmcgY29udGVudHMpIHsKCQlyZXR1cm4gbmV3IEJ5dGVBcnJheUlucHV0U3RyZWFtKGNvbnRlbnRzLmdldEJ5dGVzKCkpOwoJfQoKCXB1YmxpYyBJbnB1dFN0cmVhbSBnZXRJbnB1dFN0cmVhbShTdHJpbmcgY29udGVudHMsIFN0cmluZyBlbmNvZGluZykgdGhyb3dzIFVuc3VwcG9ydGVkRW5jb2RpbmdFeGNlcHRpb24gewoJCXJldHVybiBuZXcgQnl0ZUFycmF5SW5wdXRTdHJlYW0oZW5jb2RpbmcgPT0gbnVsbCA/IGNvbnRlbnRzLmdldEJ5dGVzKCkgOiBjb250ZW50cy5nZXRCeXRlcyhlbmNvZGluZykpOwoJfQoKCXB1YmxpYyBSZWFkZXIgZ2V0UmVhZGVyKFN0cmluZyBjb250ZW50cykgewoJCXJldHVybiBuZXcgQ2hhckFycmF5UmVhZGVyKGNvbnRlbnRzLnRvQ2hhckFycmF5KCkpOwoJfQoKCXByaXZhdGUgYm9vbGVhbiBpc1RleHQoSUNvbnRlbnRUeXBlTWFuYWdlciBtYW5hZ2VyLCBJQ29udGVudFR5cGUgY2FuZGlkYXRlKSB7CgkJSUNvbnRlbnRUeXBlIHRleHQgPSBtYW5hZ2VyLmdldENvbnRlbnRUeXBlKElDb250ZW50VHlwZU1hbmFnZXIuQ1RfVEVYVCk7CgkJcmV0dXJuIGNhbmRpZGF0ZS5pc0tpbmRPZih0ZXh0KTsKCX0KCglAT3ZlcnJpZGUKCXByb3RlY3RlZCB2b2lkIHRlYXJEb3duKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CgkJc3VwZXIudGVhckRvd24oKTsKCQkvLyBzb21lIHRlc3RzIGhlcmUgd2lsbCB0cmlnZ2VyIGEgY2hhcnNldCBkZWx0YSBqb2IgKGFueSBjYXVzaW5nIENvbnRlbnRUeXBlQ2hhbmdlRXZlbnRzIHRvIGJlIGJyb2FkY2FzdCkKCQkvLyBlbnN1cmUgbm9uZSBpcyBsZWZ0IHJ1bm5pbmcgYWZ0ZXIgd2UgZmluaXNoCgkJSm9iLmdldEpvYk1hbmFnZXIoKS5qb2luKEZBTUlMWV9DSEFSU0VUX0RFTFRBLCBnZXRNb25pdG9yKCkpOwoJfQoKCS8qKgoJICogVGhpcyB0ZXN0IHNob3dzIGhvdyB3ZSBkZWFsIHdpdGggYWxpYXNlcy4KCSAqLwoJcHVibGljIHZvaWQgdGVzdEFsaWFzKCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKCQlmaW5hbCBJQ29udGVudFR5cGVNYW5hZ2VyIGNvbnRlbnRUeXBlTWFuYWdlciA9IFBsYXRmb3JtLmdldENvbnRlbnRUeXBlTWFuYWdlcigpOwoJCUlDb250ZW50VHlwZSBhbGlhcyA9IGNvbnRlbnRUeXBlTWFuYWdlci5nZXRDb250ZW50VHlwZShQSV9SRVNPVVJDRVNfVEVTVFMgKyAiLmFsaWFzIik7CgkJYXNzZXJ0Tm90TnVsbCgiMC43IiwgYWxpYXMpOwoJCUlDb250ZW50VHlwZSBkZXJpdmVkID0gY29udGVudFR5cGVNYW5hZ2VyLmdldENvbnRlbnRUeXBlKFBJX1JFU09VUkNFU19URVNUUyArICIuZGVyaXZlZC1mcm9tLWFsaWFzIik7CgkJYXNzZXJ0Tm90TnVsbCgiMC44IiwgZGVyaXZlZCk7CgkJSUNvbnRlbnRUeXBlIHRhcmdldCA9IGNvbnRlbnRUeXBlTWFuYWdlci5nZXRDb250ZW50VHlwZSgib3JnLmVjbGlwc2UuYnVuZGxlMDIubWlzc2luZy10YXJnZXQiKTsKCQlhc3NlcnROdWxsKCIwLjkiLCB0YXJnZXQpOwoJCUlDb250ZW50VHlwZVtdIHNlbGVjdGVkOwoJCXNlbGVjdGVkID0gY29udGVudFR5cGVNYW5hZ2VyLmZpbmRDb250ZW50VHlwZXNGb3IoImZvby5taXNzaW5nLXRhcmdldCIpOwoJCWFzc2VydEVxdWFscygiMS4xIiwgMiwgc2VsZWN0ZWQubGVuZ3RoKTsKCQlhc3NlcnRFcXVhbHMoIjEuMiIsIGFsaWFzLCBzZWxlY3RlZFswXSk7CgkJYXNzZXJ0RXF1YWxzKCIxLjMiLCBkZXJpdmVkLCBzZWxlY3RlZFsxXSk7CgkJc2VsZWN0ZWQgPSBjb250ZW50VHlwZU1hbmFnZXIuZmluZENvbnRlbnRUeXBlc0ZvcihnZXRSYW5kb21Db250ZW50cygpLCAiZm9vLm1pc3NpbmctdGFyZ2V0Iik7CgkJYXNzZXJ0RXF1YWxzKCIxLjQiLCAyLCBzZWxlY3RlZC5sZW5ndGgpOwoJCWFzc2VydEVxdWFscygiMS41IiwgYWxpYXMsIHNlbGVjdGVkWzBdKTsKCQlhc3NlcnRFcXVhbHMoIjEuNiIsIGRlcml2ZWQsIHNlbGVjdGVkWzFdKTsKCgkJLy90ZXN0IGxhdGUgYWRkaXRpb24gb2YgY29udGVudCB0eXBlCgkJVGVzdFJlZ2lzdHJ5Q2hhbmdlTGlzdGVuZXIgbGlzdGVuZXIgPSBuZXcgVGVzdFJlZ2lzdHJ5Q2hhbmdlTGlzdGVuZXIoUGxhdGZvcm0uUElfUlVOVElNRSwgQ29udGVudFR5cGVCdWlsZGVyLlBUX0NPTlRFTlRUWVBFUywgbnVsbCwgbnVsbCk7CgkJQnVuZGxlVGVzdGluZ0hlbHBlci5ydW5XaXRoQnVuZGxlcygiMiIsICgpIC0+IHsKCQkJSUNvbnRlbnRUeXBlIGFsaWFzMSA9IGNvbnRlbnRUeXBlTWFuYWdlci5nZXRDb250ZW50VHlwZShQSV9SRVNPVVJDRVNfVEVTVFMgKyAiLmFsaWFzIik7CgkJCWFzc2VydE51bGwoIjIuMS4xIiwgYWxpYXMxKTsKCQkJSUNvbnRlbnRUeXBlIGRlcml2ZWQxID0gY29udGVudFR5cGVNYW5hZ2VyLmdldENvbnRlbnRUeXBlKFBJX1JFU09VUkNFU19URVNUUyArICIuZGVyaXZlZC1mcm9tLWFsaWFzIik7CgkJCWFzc2VydE5vdE51bGwoIjIuMS4yIiwgZGVyaXZlZDEpOwoJCQlJQ29udGVudFR5cGUgdGFyZ2V0MSA9IGNvbnRlbnRUeXBlTWFuYWdlci5nZXRDb250ZW50VHlwZSgib3JnLmVjbGlwc2UuYnVuZGxlMDIubWlzc2luZy10YXJnZXQiKTsKCQkJYXNzZXJ0Tm90TnVsbCgiMi4xLjMiLCB0YXJnZXQxKTsKCQkJLy8gY2hlY2tzIGFzc29jaWF0aW9ucwoJCQlJQ29udGVudFR5cGVbXSBzZWxlY3RlZDEgPSBjb250ZW50VHlwZU1hbmFnZXIuZmluZENvbnRlbnRUeXBlc0ZvcigiZm9vLm1pc3NpbmctdGFyZ2V0Iik7CgkJCWFzc2VydEVxdWFscygiMi4yLjEiLCAyLCBzZWxlY3RlZDEubGVuZ3RoKTsKCQkJYXNzZXJ0RXF1YWxzKCIyLjIuMiIsIHRhcmdldDEsIHNlbGVjdGVkMVswXSk7CgkJCWFzc2VydEVxdWFscygiMi4yLjMiLCBkZXJpdmVkMSwgc2VsZWN0ZWQxWzFdKTsKCQkJdHJ5IHsKCQkJCXNlbGVjdGVkMSA9IGNvbnRlbnRUeXBlTWFuYWdlci5maW5kQ29udGVudFR5cGVzRm9yKGdldFJhbmRvbUNvbnRlbnRzKCksICJmb28ubWlzc2luZy10YXJnZXQiKTsKCQkJfSBjYXRjaCAoSU9FeGNlcHRpb24gZSkgewoJCQkJZmFpbCgiMi4yLjQiLCBlKTsKCQkJfQoJCQlhc3NlcnRFcXVhbHMoIjIuMi41IiwgMiwgc2VsZWN0ZWQxLmxlbmd0aCk7CgkJCWFzc2VydEVxdWFscygiMi4yLjYiLCB0YXJnZXQxLCBzZWxlY3RlZDFbMF0pOwoJCQlhc3NlcnRFcXVhbHMoIjIuMi43IiwgZGVyaXZlZDEsIHNlbGVjdGVkMVsxXSk7CgkJfSwgZ2V0Q29udGV4dCgpLCBuZXcgU3RyaW5nW10ge0NvbnRlbnRUeXBlVGVzdC5URVNUX0ZJTEVTX1JPT1QgKyAiY29udGVudC9idW5kbGUwMiJ9LCBsaXN0ZW5lcik7Cgl9CgoJcHVibGljIHZvaWQgdGVzdEFzc29jaWF0aW9uSW5oZXJpdGFuY2UoKSB0aHJvd3MgQ29yZUV4Y2VwdGlvbiB7CgkJSUNvbnRlbnRUeXBlTWFuYWdlciBtYW5hZ2VyID0gUGxhdGZvcm0uZ2V0Q29udGVudFR5cGVNYW5hZ2VyKCk7CgkJSUNvbnRlbnRUeXBlTWF0Y2hlciBmaW5kZXIgPSBtYW5hZ2VyLmdldE1hdGNoZXIobmV3IExvY2FsU2VsZWN0aW9uUG9saWN5KCksIG51bGwpOwoJCUlDb250ZW50VHlwZSB0ZXh0ID0gbWFuYWdlci5nZXRDb250ZW50VHlwZShQbGF0Zm9ybS5QSV9SVU5USU1FICsgIi50ZXh0Iik7CgkJSUNvbnRlbnRUeXBlIGFzc29jMSA9IG1hbmFnZXIuZ2V0Q29udGVudFR5cGUoUElfUkVTT1VSQ0VTX1RFU1RTICsgIi5hc3NvYzEiKTsKCQlJQ29udGVudFR5cGUgYXNzb2MyID0gbWFuYWdlci5nZXRDb250ZW50VHlwZShQSV9SRVNPVVJDRVNfVEVTVFMgKyAiLmFzc29jMiIpOwoKCQkvLyBhc3NvY2lhdGUgYSB1c2VyLWRlZmluZWQgZmlsZSBzcGVjCgkJdGV4dC5hZGRGaWxlU3BlYygidHh0X3VzZXJhZGRlZCIsIElDb250ZW50VHlwZS5GSUxFX0VYVEVOU0lPTl9TUEVDKTsKCQlhc3NvYzEuYWRkRmlsZVNwZWMoInR4dF9hc3NvYzF1c2VyYWRkZWQiLCBJQ29udGVudFR5cGUuRklMRV9FWFRFTlNJT05fU1BFQyk7CgkJYXNzb2MyLmFkZEZpbGVTcGVjKCJ0eHRfYXNzb2MydXNlcmFkZGVkIiwgSUNvbnRlbnRUeXBlLkZJTEVfRVhURU5TSU9OX1NQRUMpOwoKCQkvLyB0ZXN0IGFzc29jaWF0aW9ucwoJCWFzc2VydFRydWUoIjEuMSIsIGFzc29jMS5pc0Fzc29jaWF0ZWRXaXRoKGNoYW5nZUNhc2UoInRleHQudHh0IikpKTsKCQlhc3NlcnRUcnVlKCIxLjIiLCBhc3NvYzEuaXNBc3NvY2lhdGVkV2l0aChjaGFuZ2VDYXNlKCJ0ZXh0LnR4dF91c2VyYWRkZWQiKSkpOwoJCWFzc2VydFRydWUoIjEuMyIsIGFzc29jMS5pc0Fzc29jaWF0ZWRXaXRoKGNoYW5nZUNhc2UoInRleHQudHh0X3BsdWdpbmFkZGVkIikpKTsKCQlhc3NlcnRUcnVlKCIxLjQiLCBhc3NvYzEuaXNBc3NvY2lhdGVkV2l0aChjaGFuZ2VDYXNlKCJ0ZXh0LnR4dF9hc3NvYzFwbHVnaW5hZGRlZCIpKSk7CgkJYXNzZXJ0VHJ1ZSgiMS41IiwgYXNzb2MxLmlzQXNzb2NpYXRlZFdpdGgoY2hhbmdlQ2FzZSgidGV4dC50eHRfYXNzb2MxdXNlcmFkZGVkIikpKTsKCgkJYXNzZXJ0VHJ1ZSgiMi4xIiwgIWFzc29jMi5pc0Fzc29jaWF0ZWRXaXRoKGNoYW5nZUNhc2UoInRleHQudHh0IikpKTsKCQlhc3NlcnRUcnVlKCIyLjIiLCAhYXNzb2MyLmlzQXNzb2NpYXRlZFdpdGgoY2hhbmdlQ2FzZSgidGV4dC50eHRfdXNlcmFkZGVkIikpKTsKCQlhc3NlcnRUcnVlKCIyLjMiLCAhYXNzb2MyLmlzQXNzb2NpYXRlZFdpdGgoY2hhbmdlQ2FzZSgidGV4dC50eHRfcGx1Z2luYWRkZWQiKSkpOwoJCWFzc2VydFRydWUoIjIuNCIsIGFzc29jMi5pc0Fzc29jaWF0ZWRXaXRoKGNoYW5nZUNhc2UoInRleHQudHh0X2Fzc29jMnBsdWdpbmFkZGVkIikpKTsKCQlhc3NlcnRUcnVlKCIyLjUiLCBhc3NvYzIuaXNBc3NvY2lhdGVkV2l0aChjaGFuZ2VDYXNlKCJ0ZXh0LnR4dF9hc3NvYzJidWlsdGluIikpKTsKCQlhc3NlcnRUcnVlKCIyLjYiLCBhc3NvYzIuaXNBc3NvY2lhdGVkV2l0aChjaGFuZ2VDYXNlKCJ0ZXh0LnR4dF9hc3NvYzJ1c2VyYWRkZWQiKSkpOwoKCQlJQ29udGVudFR5cGVbXSBzZWxlY3RlZDsKCQkvLyB0ZXh0IGJ1aWx0LWluIGFzc29jaWF0aW9ucwoJCXNlbGVjdGVkID0gZmluZGVyLmZpbmRDb250ZW50VHlwZXNGb3IoY2hhbmdlQ2FzZSgidGV4dC50eHQiKSk7CgkJYXNzZXJ0RXF1YWxzKCIzLjAiLCAyLCBzZWxlY3RlZC5sZW5ndGgpOwoJCWFzc2VydEVxdWFscygiMy4xIiwgYXNzb2MxLCBzZWxlY3RlZFsxXSk7CgkJYXNzZXJ0RXF1YWxzKCIzLjIiLCB0ZXh0LCBzZWxlY3RlZFswXSk7CgoJCS8vIHRleHQgdXNlci1hZGRlZCBhc3NvY2lhdGlvbnMKCQlzZWxlY3RlZCA9IGZpbmRlci5maW5kQ29udGVudFR5cGVzRm9yKGNoYW5nZUNhc2UoInRleHQudHh0X3VzZXJhZGRlZCIpKTsKCQlhc3NlcnRFcXVhbHMoIjQuMCIsIDIsIHNlbGVjdGVkLmxlbmd0aCk7CgkJYXNzZXJ0RXF1YWxzKCI0LjEiLCBhc3NvYzEsIHNlbGVjdGVkWzFdKTsKCQlhc3NlcnRFcXVhbHMoIjQuMiIsIHRleHQsIHNlbGVjdGVkWzBdKTsKCgkJLy8gdGV4dCBwcm92aWRlci1hZGRlZCBhc3NvY2lhdGlvbnMKCQlzZWxlY3RlZCA9IGZpbmRlci5maW5kQ29udGVudFR5cGVzRm9yKGNoYW5nZUNhc2UoInRleHQudHh0X3BsdWdpbmFkZGVkIikpOwoJCWFzc2VydEVxdWFscygiNS4wIiwgMiwgc2VsZWN0ZWQubGVuZ3RoKTsKCQlhc3NlcnRFcXVhbHMoIjUuMSIsIGFzc29jMSwgc2VsZWN0ZWRbMV0pOwoJCWFzc2VydEVxdWFscygiNS4yIiwgdGV4dCwgc2VsZWN0ZWRbMF0pOwoKCQlzZWxlY3RlZCA9IGZpbmRlci5maW5kQ29udGVudFR5cGVzRm9yKGNoYW5nZUNhc2UoInRleHQudHh0X2Fzc29jMXBsdWdpbmFkZGVkIikpOwoJCWFzc2VydEVxdWFscygiNi4wIiwgMSwgc2VsZWN0ZWQubGVuZ3RoKTsKCQlhc3NlcnRFcXVhbHMoIjYuMSIsIGFzc29jMSwgc2VsZWN0ZWRbMF0pOwoKCQlzZWxlY3RlZCA9IGZpbmRlci5maW5kQ29udGVudFR5cGVzRm9yKGNoYW5nZUNhc2UoInRleHQudHh0X2Fzc29jMXVzZXJhZGRlZCIpKTsKCQlhc3NlcnRFcXVhbHMoIjcuMCIsIDEsIHNlbGVjdGVkLmxlbmd0aCk7CgkJYXNzZXJ0RXF1YWxzKCI3LjEiLCBhc3NvYzEsIHNlbGVjdGVkWzBdKTsKCgkJc2VsZWN0ZWQgPSBmaW5kZXIuZmluZENvbnRlbnRUeXBlc0ZvcihjaGFuZ2VDYXNlKCJ0ZXh0LnR4dF9hc3NvYzJwbHVnaW5hZGRlZCIpKTsKCQlhc3NlcnRFcXVhbHMoIjguMCIsIDEsIHNlbGVjdGVkLmxlbmd0aCk7CgkJYXNzZXJ0RXF1YWxzKCI4LjEiLCBhc3NvYzIsIHNlbGVjdGVkWzBdKTsKCgkJc2VsZWN0ZWQgPSBmaW5kZXIuZmluZENvbnRlbnRUeXBlc0ZvcihjaGFuZ2VDYXNlKCJ0ZXh0LnR4dF9hc3NvYzJ1c2VyYWRkZWQiKSk7CgkJYXNzZXJ0RXF1YWxzKCI5LjAiLCAxLCBzZWxlY3RlZC5sZW5ndGgpOwoJCWFzc2VydEVxdWFscygiOS4xIiwgYXNzb2MyLCBzZWxlY3RlZFswXSk7CgoJCXNlbGVjdGVkID0gZmluZGVyLmZpbmRDb250ZW50VHlwZXNGb3IoY2hhbmdlQ2FzZSgidGV4dC50eHRfYXNzb2MyYnVpbHRpbiIpKTsKCQlhc3NlcnRFcXVhbHMoIjEwLjAiLCAxLCBzZWxlY3RlZC5sZW5ndGgpOwoJCWFzc2VydEVxdWFscygiMTAuMSIsIGFzc29jMiwgc2VsZWN0ZWRbMF0pOwoJfQoKCXB1YmxpYyB2b2lkIHRlc3RBc3NvY2lhdGlvbnMoKSB0aHJvd3MgQ29yZUV4Y2VwdGlvbiB7CgkJSUNvbnRlbnRUeXBlIHRleHQgPSBQbGF0Zm9ybS5nZXRDb250ZW50VHlwZU1hbmFnZXIoKS5nZXRDb250ZW50VHlwZShQbGF0Zm9ybS5QSV9SVU5USU1FICsgIi50ZXh0Iik7CgoJCS8vIGFzc29jaWF0ZSBhIHVzZXItZGVmaW5lZCBmaWxlIHNwZWMKCQl0ZXh0LmFkZEZpbGVTcGVjKCJ0eHRfdXNlcmFkZGVkIiwgSUNvbnRlbnRUeXBlLkZJTEVfRVhURU5TSU9OX1NQRUMpOwoKCQkvLyB0ZXN0IGFzc29jaWF0aW9ucwoJCWFzc2VydFRydWUoIjAuMSIsIHRleHQuaXNBc3NvY2lhdGVkV2l0aChjaGFuZ2VDYXNlKCJ0ZXh0LnR4dCIpKSk7CgkJYXNzZXJ0VHJ1ZSgiMC4yIiwgdGV4dC5pc0Fzc29jaWF0ZWRXaXRoKGNoYW5nZUNhc2UoInRleHQudHh0X3VzZXJhZGRlZCIpKSk7CgkJYXNzZXJ0VHJ1ZSgiMC4zIiwgdGV4dC5pc0Fzc29jaWF0ZWRXaXRoKGNoYW5nZUNhc2UoInRleHQudHh0X3BsdWdpbmFkZGVkIikpKTsKCgkJLy8gY2hlY2sgcHJvdmlkZXIgZGVmaW5lZCBzZXR0aW5ncwoJCVN0cmluZ1tdIHByb3ZpZGVyRGVmaW5lZEV4dGVuc2lvbnMgPSB0ZXh0LmdldEZpbGVTcGVjcyhJQ29udGVudFR5cGUuRklMRV9FWFRFTlNJT05fU1BFQyB8IElDb250ZW50VHlwZS5JR05PUkVfVVNFUl9ERUZJTkVEKTsKCQlhc3NlcnRUcnVlKCIxLjAiLCBjb250YWlucyhwcm92aWRlckRlZmluZWRFeHRlbnNpb25zLCAidHh0IikpOwoJCWFzc2VydFRydWUoIjEuMSIsICFjb250YWlucyhwcm92aWRlckRlZmluZWRFeHRlbnNpb25zLCAidHh0X3VzZXJhZGRlZCIpKTsKCQlhc3NlcnRUcnVlKCIxLjIiLCBjb250YWlucyhwcm92aWRlckRlZmluZWRFeHRlbnNpb25zLCAidHh0X3BsdWdpbmFkZGVkIikpOwoKCQkvLyBjaGVjayB1c2VyIGRlZmluZWQgc2V0dGluZ3MKCQlTdHJpbmdbXSB0ZXh0VXNlckRlZmluZWRFeHRlbnNpb25zID0gdGV4dC5nZXRGaWxlU3BlY3MoSUNvbnRlbnRUeXBlLkZJTEVfRVhURU5TSU9OX1NQRUMgfCBJQ29udGVudFR5cGUuSUdOT1JFX1BSRV9ERUZJTkVEKTsKCQlhc3NlcnRUcnVlKCIyLjAiLCAhY29udGFpbnModGV4dFVzZXJEZWZpbmVkRXh0ZW5zaW9ucywgInR4dCIpKTsKCQlhc3NlcnRUcnVlKCIyLjEiLCBjb250YWlucyh0ZXh0VXNlckRlZmluZWRFeHRlbnNpb25zLCAidHh0X3VzZXJhZGRlZCIpKTsKCQlhc3NlcnRUcnVlKCIyLjIiLCAhY29udGFpbnModGV4dFVzZXJEZWZpbmVkRXh0ZW5zaW9ucywgInR4dF9wbHVnaW5hZGRlZCIpKTsKCgkJLy8gcmVtb3ZpbmcgcHJlLWRlZmluZWQgZmlsZSBzcGVjcyBzaG91bGQgbm90IGRvIGFueXRoaW5nCgkJdGV4dC5yZW1vdmVGaWxlU3BlYygidHh0IiwgSUNvbnRlbnRUeXBlLkZJTEVfRVhURU5TSU9OX1NQRUMpOwoJCWFzc2VydFRydWUoIjMuMCIsIGNvbnRhaW5zKHRleHQuZ2V0RmlsZVNwZWNzKElDb250ZW50VHlwZS5GSUxFX0VYVEVOU0lPTl9TUEVDIHwgSUNvbnRlbnRUeXBlLklHTk9SRV9VU0VSX0RFRklORUQpLCAidHh0IikpOwoJCWFzc2VydFRydWUoIjMuMSIsIHRleHQuaXNBc3NvY2lhdGVkV2l0aChjaGFuZ2VDYXNlKCJ0ZXh0LnR4dCIpKSk7CgkJYXNzZXJ0VHJ1ZSgiMy4yIiwgdGV4dC5pc0Fzc29jaWF0ZWRXaXRoKGNoYW5nZUNhc2UoInRleHQudHh0X3VzZXJhZGRlZCIpKSk7CgkJYXNzZXJ0VHJ1ZSgiMy4zIiwgdGV4dC5pc0Fzc29jaWF0ZWRXaXRoKGNoYW5nZUNhc2UoInRleHQudHh0X3BsdWdpbmFkZGVkIikpKTsKCgkJLy8gcmVtb3ZpbmcgdXNlciBmaWxlIHNwZWNzIGlzIHRoZSBub3JtYWwgY2FzZSBhbmQgaGFzIHRvIHdvcmsgYXMgZXhwZWN0ZWQKCQl0ZXh0LnJlbW92ZUZpbGVTcGVjKCJ0eHRfdXNlcmFkZGVkIiwgSUNvbnRlbnRUeXBlLkZJTEVfRVhURU5TSU9OX1NQRUMpOwoJCWFzc2VydFRydWUoIjQuMCIsICFjb250YWlucyh0ZXh0LmdldEZpbGVTcGVjcyhJQ29udGVudFR5cGUuRklMRV9FWFRFTlNJT05fU1BFQyB8IElDb250ZW50VHlwZS5JR05PUkVfUFJFX0RFRklORUQpLCAiaW5pIikpOwoJCWFzc2VydFRydWUoIjQuMSIsIHRleHQuaXNBc3NvY2lhdGVkV2l0aChjaGFuZ2VDYXNlKCJ0ZXh0LnR4dCIpKSk7CgkJYXNzZXJ0VHJ1ZSgiNC4yIiwgIXRleHQuaXNBc3NvY2lhdGVkV2l0aChjaGFuZ2VDYXNlKCJ0ZXh0LnR4dF91c2VyYWRkZWQiKSkpOwoJCWFzc2VydFRydWUoIjQuMyIsIHRleHQuaXNBc3NvY2lhdGVkV2l0aChjaGFuZ2VDYXNlKCJ0ZXh0LnR4dF9wbHVnaW5hZGRlZCIpKSk7Cgl9CgoJcHVibGljIHZvaWQgdGVzdEJpbmFyeVR5cGVzKCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKCQlJQ29udGVudFR5cGVNYW5hZ2VyIGNvbnRlbnRUeXBlTWFuYWdlciA9IFBsYXRmb3JtLmdldENvbnRlbnRUeXBlTWFuYWdlcigpOwoJCUlDb250ZW50VHlwZSBzYW1wbGVCaW5hcnkxID0gY29udGVudFR5cGVNYW5hZ2VyLmdldENvbnRlbnRUeXBlKFBJX1JFU09VUkNFU19URVNUUyArICIuc2FtcGxlLWJpbmFyeTEiKTsKCQlJQ29udGVudFR5cGUgc2FtcGxlQmluYXJ5MiA9IGNvbnRlbnRUeXBlTWFuYWdlci5nZXRDb250ZW50VHlwZShQSV9SRVNPVVJDRVNfVEVTVFMgKyAiLnNhbXBsZS1iaW5hcnkyIik7CgkJSW5wdXRTdHJlYW0gY29udGVudHM7CgoJCWNvbnRlbnRzID0gZ2V0SW5wdXRTdHJlYW0obmV3IGJ5dGVbXVtdIHtTQU1QTEVfQklOMV9PRkZTRVQuZ2V0Qnl0ZXMoKSwgU0FNUExFX0JJTjFfU0lHTkFUVVJFLCAiIGV4dHJhIGNvbnRlbnRzIi5nZXRCeXRlcygpfSk7CgkJSUNvbnRlbnREZXNjcmlwdGlvbiBkZXNjcmlwdGlvbiA9IGNvbnRlbnRUeXBlTWFuYWdlci5nZXREZXNjcmlwdGlvbkZvcihjb250ZW50cywgbnVsbCwgSUNvbnRlbnREZXNjcmlwdGlvbi5BTEwpOwoJCWFzc2VydE5vdE51bGwoIjYuMCIsIGRlc2NyaXB0aW9uKTsKCQlhc3NlcnRFcXVhbHMoIjYuMSIsIHNhbXBsZUJpbmFyeTEsIGRlc2NyaXB0aW9uLmdldENvbnRlbnRUeXBlKCkpOwoKCQljb250ZW50cyA9IGdldElucHV0U3RyZWFtKG5ldyBieXRlW11bXSB7U0FNUExFX0JJTjJfT0ZGU0VULmdldEJ5dGVzKCksIFNBTVBMRV9CSU4yX1NJR05BVFVSRSwgIiBleHRyYSBjb250ZW50cyIuZ2V0Qnl0ZXMoKX0pOwoJCWRlc2NyaXB0aW9uID0gY29udGVudFR5cGVNYW5hZ2VyLmdldERlc2NyaXB0aW9uRm9yKGNvbnRlbnRzLCBudWxsLCBJQ29udGVudERlc2NyaXB0aW9uLkFMTCk7CgkJYXNzZXJ0Tm90TnVsbCgiNy4wIiwgZGVzY3JpcHRpb24pOwoJCWFzc2VydEVxdWFscygiNy4xIiwgc2FtcGxlQmluYXJ5MiwgZGVzY3JpcHRpb24uZ2V0Q29udGVudFR5cGUoKSk7CgoJCS8vIG1ha2Ugc3VyZSB3ZSBpZ25vcmUgdGhhdCBjb250ZW50IHR5cGUgd2hlbiBjb250ZW50cyBhcmUgdGV4dAoJCS8vIChzZWUgYnVnIDEwMDAzMikKCQkvLyBmaXJzdCBjaGVjayBpZiBvdXIgdGVzdCBlbnZpcm9ubWVudCBpcyBzYW5lCgkJSUNvbnRlbnRUeXBlW10gc2VsZWN0ZWQgPSBjb250ZW50VHlwZU1hbmFnZXIuZmluZENvbnRlbnRUeXBlc0ZvcigidGVzdC5zYW1wbGViaW4yIik7CgkJYXNzZXJ0RXF1YWxzKCI4LjEiLCAxLCBzZWxlY3RlZC5sZW5ndGgpOwoJCWFzc2VydEVxdWFscygiOC4yIiwgc2FtcGxlQmluYXJ5Mi5nZXRJZCgpLCBzZWxlY3RlZFswXS5nZXRJZCgpKTsKCQkvLyAod2UgdXNlZCB0byBibG93IHVwIGhlcmUpCgkJZGVzY3JpcHRpb24gPSBjb250ZW50VHlwZU1hbmFnZXIuZ2V0RGVzY3JpcHRpb25Gb3IoZ2V0UmVhZGVyKGdldFJhbmRvbVN0cmluZygpKSwgInRlc3Quc2FtcGxlYmluMiIsIElDb250ZW50RGVzY3JpcHRpb24uQUxMKTsKCQlhc3NlcnROdWxsKCI4LjMiLCBkZXNjcmlwdGlvbik7Cgl9CgoJcHVibGljIHZvaWQgdGVzdEJ5dGVPcmRlck1hcmsoKSB0aHJvd3MgVW5zdXBwb3J0ZWRFbmNvZGluZ0V4Y2VwdGlvbiwgSU9FeGNlcHRpb24gewoJCUlDb250ZW50VHlwZSB0ZXh0ID0gUGxhdGZvcm0uZ2V0Q29udGVudFR5cGVNYW5hZ2VyKCkuZ2V0Q29udGVudFR5cGUoSUNvbnRlbnRUeXBlTWFuYWdlci5DVF9URVhUKTsKCQlRdWFsaWZpZWROYW1lW10gb3B0aW9ucyA9IG5ldyBRdWFsaWZpZWROYW1lW10ge0lDb250ZW50RGVzY3JpcHRpb24uQllURV9PUkRFUl9NQVJLfTsKCQlJQ29udGVudERlc2NyaXB0aW9uIGRlc2NyaXB0aW9uOwoJCS8vIHRlc3RzIHdpdGggVVRGLTggQk9NCgkJU3RyaW5nIFVURjhfQk9NID0gbmV3IFN0cmluZyhJQ29udGVudERlc2NyaXB0aW9uLkJPTV9VVEZfOCwgIklTTy04ODU5LTEiKTsKCQlkZXNjcmlwdGlvbiA9IHRleHQuZ2V0RGVzY3JpcHRpb25Gb3IobmV3IEJ5dGVBcnJheUlucHV0U3RyZWFtKChVVEY4X0JPTSArIE1JTklNQUxfWE1MKS5nZXRCeXRlcygiSVNPLTg4NTktMSIpKSwgb3B0aW9ucyk7CgkJYXNzZXJ0Tm90TnVsbCgiMS4wIiwgZGVzY3JpcHRpb24uZ2V0UHJvcGVydHkoSUNvbnRlbnREZXNjcmlwdGlvbi5CWVRFX09SREVSX01BUkspKTsKCQlhc3NlcnRFcXVhbHMoIjEuMSIsIElDb250ZW50RGVzY3JpcHRpb24uQk9NX1VURl84LCBkZXNjcmlwdGlvbi5nZXRQcm9wZXJ0eShJQ29udGVudERlc2NyaXB0aW9uLkJZVEVfT1JERVJfTUFSSykpOwoJCS8vIHRlc3RzIHdpdGggVVRGLTE2IExpdHRsZSBFbmRpYW4gQk9NCgkJU3RyaW5nIFVURjE2X0xFX0JPTSA9IG5ldyBTdHJpbmcoSUNvbnRlbnREZXNjcmlwdGlvbi5CT01fVVRGXzE2TEUsICJJU08tODg1OS0xIik7CgkJZGVzY3JpcHRpb24gPSB0ZXh0LmdldERlc2NyaXB0aW9uRm9yKG5ldyBCeXRlQXJyYXlJbnB1dFN0cmVhbSgoVVRGMTZfTEVfQk9NICsgTUlOSU1BTF9YTUwpLmdldEJ5dGVzKCJJU08tODg1OS0xIikpLCBvcHRpb25zKTsKCQlhc3NlcnROb3ROdWxsKCIyLjAiLCBkZXNjcmlwdGlvbi5nZXRQcm9wZXJ0eShJQ29udGVudERlc2NyaXB0aW9uLkJZVEVfT1JERVJfTUFSSykpOwoJCWFzc2VydEVxdWFscygiMi4xIiwgSUNvbnRlbnREZXNjcmlwdGlvbi5CT01fVVRGXzE2TEUsIGRlc2NyaXB0aW9uLmdldFByb3BlcnR5KElDb250ZW50RGVzY3JpcHRpb24uQllURV9PUkRFUl9NQVJLKSk7CgkJLy8gdGVzdHMgd2l0aCBVVEYtMTYgQmlnIEVuZGlhbiBCT00KCQlTdHJpbmcgVVRGMTZfQkVfQk9NID0gbmV3IFN0cmluZyhJQ29udGVudERlc2NyaXB0aW9uLkJPTV9VVEZfMTZCRSwgIklTTy04ODU5LTEiKTsKCQlkZXNjcmlwdGlvbiA9IHRleHQuZ2V0RGVzY3JpcHRpb25Gb3IobmV3IEJ5dGVBcnJheUlucHV0U3RyZWFtKChVVEYxNl9CRV9CT00gKyBNSU5JTUFMX1hNTCkuZ2V0Qnl0ZXMoIklTTy04ODU5LTEiKSksIG9wdGlvbnMpOwoJCWFzc2VydE5vdE51bGwoIjMuMCIsIGRlc2NyaXB0aW9uLmdldFByb3BlcnR5KElDb250ZW50RGVzY3JpcHRpb24uQllURV9PUkRFUl9NQVJLKSk7CgkJYXNzZXJ0RXF1YWxzKCIzLjEiLCBJQ29udGVudERlc2NyaXB0aW9uLkJPTV9VVEZfMTZCRSwgZGVzY3JpcHRpb24uZ2V0UHJvcGVydHkoSUNvbnRlbnREZXNjcmlwdGlvbi5CWVRFX09SREVSX01BUkspKTsKCQkvLyB0ZXN0IHdpdGggbm8gQk9NCgkJZGVzY3JpcHRpb24gPSB0ZXh0LmdldERlc2NyaXB0aW9uRm9yKG5ldyBCeXRlQXJyYXlJbnB1dFN0cmVhbShNSU5JTUFMX1hNTC5nZXRCeXRlcygiSVNPLTg4NTktMSIpKSwgb3B0aW9ucyk7CgkJYXNzZXJ0TnVsbCgiNC4wIiwgZGVzY3JpcHRpb24uZ2V0UHJvcGVydHkoSUNvbnRlbnREZXNjcmlwdGlvbi5CWVRFX09SREVSX01BUkspKTsKCgkJLy8gdGVzdHMgZm9yIHBhcnRpYWwgQk9NCgkJLy8gZmlyc3QgYnl0ZSBvZiBVVEYtMTYgQmlnIEVuZGlhbiArIG1pbmltYWwgeG1sCgkJU3RyaW5nIFVURjE2X0JFX0JPTV8xYnl0ZSA9IG5ldyBTdHJpbmcobmV3IGJ5dGVbXSB7KGJ5dGUpIDB4RkV9LCAiSVNPLTg4NTktMSIpOwoJCWRlc2NyaXB0aW9uID0gdGV4dC5nZXREZXNjcmlwdGlvbkZvcihuZXcgQnl0ZUFycmF5SW5wdXRTdHJlYW0oKFVURjE2X0JFX0JPTV8xYnl0ZSArIE1JTklNQUxfWE1MKS5nZXRCeXRlcygiSVNPLTg4NTktMSIpKSwgb3B0aW9ucyk7CgkJYXNzZXJ0TnVsbCgiNS4wIiwgZGVzY3JpcHRpb24uZ2V0UHJvcGVydHkoSUNvbnRlbnREZXNjcmlwdGlvbi5CWVRFX09SREVSX01BUkspKTsKCQkvLyBmaXJzdCBieXRlIG9mIFVURi0xNiBCaWcgRW5kaWFuIG9ubHkgKHNlZSBodHRwczovL2J1Z3MuZWNsaXBzZS5vcmcvYnVncy9zaG93X2J1Zy5jZ2k/aWQ9MTk5MjUyKQoJCWRlc2NyaXB0aW9uID0gdGV4dC5nZXREZXNjcmlwdGlvbkZvcihuZXcgQnl0ZUFycmF5SW5wdXRTdHJlYW0oKFVURjE2X0JFX0JPTV8xYnl0ZSkuZ2V0Qnl0ZXMoIklTTy04ODU5LTEiKSksIG9wdGlvbnMpOwoJCWFzc2VydE51bGwoIjUuMSIsIGRlc2NyaXB0aW9uLmdldFByb3BlcnR5KElDb250ZW50RGVzY3JpcHRpb24uQllURV9PUkRFUl9NQVJLKSk7CgoJCS8vIGZpcnN0IGJ5dGUgb2YgVVRGLTE2IExpdHRsZSBFbmRpYW4gKyBtaW5pbWFsIHhtbAoJCVN0cmluZyBVVEYxNl9MRV9CT01fMWJ5dGUgPSBuZXcgU3RyaW5nKG5ldyBieXRlW10geyhieXRlKSAweEZGfSwgIklTTy04ODU5LTEiKTsKCQlkZXNjcmlwdGlvbiA9IHRleHQuZ2V0RGVzY3JpcHRpb25Gb3IobmV3IEJ5dGVBcnJheUlucHV0U3RyZWFtKChVVEYxNl9MRV9CT01fMWJ5dGUgKyBNSU5JTUFMX1hNTCkuZ2V0Qnl0ZXMoIklTTy04ODU5LTEiKSksIG9wdGlvbnMpOwoJCWFzc2VydE51bGwoIjYuMCIsIGRlc2NyaXB0aW9uLmdldFByb3BlcnR5KElDb250ZW50RGVzY3JpcHRpb24uQllURV9PUkRFUl9NQVJLKSk7CgkJLy8gZmlyc3QgYnl0ZSBvZiBVVEYtMTYgTGl0dGxlIEVuZGlhbiBvbmx5CgkJZGVzY3JpcHRpb24gPSB0ZXh0LmdldERlc2NyaXB0aW9uRm9yKG5ldyBCeXRlQXJyYXlJbnB1dFN0cmVhbSgoVVRGMTZfTEVfQk9NXzFieXRlKS5nZXRCeXRlcygiSVNPLTg4NTktMSIpKSwgb3B0aW9ucyk7CgkJYXNzZXJ0TnVsbCgiNi4xIiwgZGVzY3JpcHRpb24uZ2V0UHJvcGVydHkoSUNvbnRlbnREZXNjcmlwdGlvbi5CWVRFX09SREVSX01BUkspKTsKCgkJLy8gZmlyc3QgYnl0ZSBvZiBVVEYtOCArIG1pbmltYWwgeG1sCgkJU3RyaW5nIFVURjhfQk9NXzFieXRlID0gbmV3IFN0cmluZyhuZXcgYnl0ZVtdIHsoYnl0ZSkgMHhFRn0sICJJU08tODg1OS0xIik7CgkJZGVzY3JpcHRpb24gPSB0ZXh0LmdldERlc2NyaXB0aW9uRm9yKG5ldyBCeXRlQXJyYXlJbnB1dFN0cmVhbSgoVVRGOF9CT01fMWJ5dGUgKyBNSU5JTUFMX1hNTCkuZ2V0Qnl0ZXMoIklTTy04ODU5LTEiKSksIG9wdGlvbnMpOwoJCWFzc2VydE51bGwoIjcuMCIsIGRlc2NyaXB0aW9uLmdldFByb3BlcnR5KElDb250ZW50RGVzY3JpcHRpb24uQllURV9PUkRFUl9NQVJLKSk7CgkJLy8gZmlyc3QgYnl0ZSBvZiBVVEYtOCBvbmx5CgkJZGVzY3JpcHRpb24gPSB0ZXh0LmdldERlc2NyaXB0aW9uRm9yKG5ldyBCeXRlQXJyYXlJbnB1dFN0cmVhbSgoVVRGOF9CT01fMWJ5dGUpLmdldEJ5dGVzKCJJU08tODg1OS0xIikpLCBvcHRpb25zKTsKCQlhc3NlcnROdWxsKCI3LjEiLCBkZXNjcmlwdGlvbi5nZXRQcm9wZXJ0eShJQ29udGVudERlc2NyaXB0aW9uLkJZVEVfT1JERVJfTUFSSykpOwoKCQkvLyB0d28gZmlyc3QgYnl0ZXMgb2YgVVRGLTggKyBtaW5pbWFsIHhtbAoJCVN0cmluZyBVVEY4X0JPTV8yYnl0ZXMgPSBuZXcgU3RyaW5nKG5ldyBieXRlW10geyhieXRlKSAweEVGLCAoYnl0ZSkgMHhCQn0sICJJU08tODg1OS0xIik7CgkJZGVzY3JpcHRpb24gPSB0ZXh0LmdldERlc2NyaXB0aW9uRm9yKG5ldyBCeXRlQXJyYXlJbnB1dFN0cmVhbSgoVVRGOF9CT01fMmJ5dGVzICsgTUlOSU1BTF9YTUwpLmdldEJ5dGVzKCJJU08tODg1OS0xIikpLCBvcHRpb25zKTsKCQlhc3NlcnROdWxsKCI4LjAiLCBkZXNjcmlwdGlvbi5nZXRQcm9wZXJ0eShJQ29udGVudERlc2NyaXB0aW9uLkJZVEVfT1JERVJfTUFSSykpOwoJCS8vIHR3byBmaXJzdCBieXRlcyBvZiBVVEYtOCBvbmx5CgkJZGVzY3JpcHRpb24gPSB0ZXh0LmdldERlc2NyaXB0aW9uRm9yKG5ldyBCeXRlQXJyYXlJbnB1dFN0cmVhbSgoVVRGOF9CT01fMmJ5dGVzKS5nZXRCeXRlcygiSVNPLTg4NTktMSIpKSwgb3B0aW9ucyk7CgkJYXNzZXJ0TnVsbCgiOC4xIiwgZGVzY3JpcHRpb24uZ2V0UHJvcGVydHkoSUNvbnRlbnREZXNjcmlwdGlvbi5CWVRFX09SREVSX01BUkspKTsKCX0KCgkvKioKCSAqIFNlZSBidWcgOTAyMTguCgkgKi8KCXB1YmxpYyB2b2lkIHRlc3RDb250ZW50QW5kTmFtZU1hdGNoaW5nKCkgdGhyb3dzIElPRXhjZXB0aW9uIC8qIG5vdCByZWFsbHkgKi8gewoJCUlDb250ZW50VHlwZU1hbmFnZXIgbWFuYWdlciA9IFBsYXRmb3JtLmdldENvbnRlbnRUeXBlTWFuYWdlcigpOwoKCQlieXRlW11bXSBjb250ZW50czAgPSB7ezB4MEEsIDB4MEIsIDB4MEUsIDB4MTB9fTsKCQlieXRlW11bXSBjb250ZW50czEgPSB7ezB4MEEsIDB4MEIsIDB4MEMsIDB4MTB9fTsKCQlieXRlW11bXSBjb250ZW50czIgPSB7ezB4MEEsIDB4MEIsIDB4MEQsIDB4MTB9fTsKCQlieXRlW11bXSBpbnZhbGlkQ29udGVudHMgPSB7ezAsIDAsIDAsIDB9fTsKCgkJLy8gYmFzZSBtYXRjaGVzICoubXliaW5hcnkgZmlsZXMgc3RhcnRpbmcgd2l0aCAweDBhIDB4MGIKCQlJQ29udGVudFR5cGUgYmFzZSA9IG1hbmFnZXIuZ2V0Q29udGVudFR5cGUoUElfUkVTT1VSQ0VTX1RFU1RTICsgIi5iaW5hcnlfYmFzZSIpOwoJCS8vIGRlcml2ZWQxIG1hdGNoZXMgKi5teWJpbmFyeSBhbmQgc3BlY2lmaWNhbGx5IGZvby5teWJpbmFyeSBmaWxlcyBzdGFydGluZyB3aXRoIDB4MGEgMHgwYiAweGMKCQlJQ29udGVudFR5cGUgZGVyaXZlZDEgPSBtYW5hZ2VyLmdldENvbnRlbnRUeXBlKFBJX1JFU09VUkNFU19URVNUUyArICIuYmluYXJ5X2Rlcml2ZWQxIik7CgkJLy8gZGVyaXZlZDIgbWF0Y2hlcyAqLm15YmluYXJ5IChpbmhlcml0cyBmaWxlc3BlYyBmcm9tIGJhc2UpIGZpbGVzIHN0YXJ0aW5nIHdpdGggMHgwYSAweDBiIDB4ZAoJCUlDb250ZW50VHlwZSBkZXJpdmVkMiA9IG1hbmFnZXIuZ2V0Q29udGVudFR5cGUoUElfUkVTT1VSQ0VTX1RFU1RTICsgIi5iaW5hcnlfZGVyaXZlZDIiKTsKCgkJSUNvbnRlbnRUeXBlW10gc2VsZWN0ZWQ7CgoJCXNlbGVjdGVkID0gbWFuYWdlci5maW5kQ29udGVudFR5cGVzRm9yKGdldElucHV0U3RyZWFtKGNvbnRlbnRzMCksICJhbnl0aGluZy5teWJpbmFyeSIpOwoJCWFzc2VydEVxdWFscygiMS4wIiwgMywgc2VsZWN0ZWQubGVuZ3RoKTsKCQkvLyBhbGwgd2Uga25vdyBpcyB0aGUgZmlyc3Qgb25lIGlzIHRoZSBiYXNlIHR5cGUgKG9ubHkgb25lIHdpdGggYSBWQUxJRCBtYXRjaCkKCQlhc3NlcnRFcXVhbHMoIjEuMSIsIGJhc2UsIHNlbGVjdGVkWzBdKTsKCgkJc2VsZWN0ZWQgPSBtYW5hZ2VyLmZpbmRDb250ZW50VHlwZXNGb3IoZ2V0SW5wdXRTdHJlYW0oY29udGVudHMwKSwgImZvby5teWJpbmFyeSIpOwoJCS8vIHdlIGtub3cgYWxzbyB0aGF0IHRoZSBzZWNvbmQgb25lIHdpbGwgYmUgZGVyaXZlZDEsIGJlY2F1c2UgaXQgaGFzIGEgZnVsbCBuYW1lIG1hdGNoaW5nCgkJYXNzZXJ0RXF1YWxzKCIyLjAiLCAzLCBzZWxlY3RlZC5sZW5ndGgpOwoJCWFzc2VydEVxdWFscygiMi4xIiwgYmFzZSwgc2VsZWN0ZWRbMF0pOwoJCWFzc2VydEVxdWFscygiMi4yIiwgZGVyaXZlZDEsIHNlbGVjdGVkWzFdKTsKCgkJc2VsZWN0ZWQgPSBtYW5hZ2VyLmZpbmRDb250ZW50VHlwZXNGb3IoZ2V0SW5wdXRTdHJlYW0oY29udGVudHMxKSwgImZvby5teWJpbmFyeSIpOwoJCS8vIGRlcml2ZWQxIHdpbGwgYmUgZmlyc3QgYmVjYXVzZSBib3RoIGJhc2UgYW5kIGRlcml2ZWQxIGhhdmUgYSBzdHJvbmcgY29udGVudCBtYXRjaGluZywgc28gbW9yZSBzcGVjaWZpYyB3aW5zCgkJYXNzZXJ0RXF1YWxzKCIzLjAiLCAzLCBzZWxlY3RlZC5sZW5ndGgpOwoJCWFzc2VydEVxdWFscygiMy4xIiwgZGVyaXZlZDEsIHNlbGVjdGVkWzBdKTsKCQlhc3NlcnRFcXVhbHMoIjMuMiIsIGJhc2UsIHNlbGVjdGVkWzFdKTsKCgkJc2VsZWN0ZWQgPSBtYW5hZ2VyLmZpbmRDb250ZW50VHlwZXNGb3IoZ2V0SW5wdXRTdHJlYW0oY29udGVudHMyKSwgImZvby5teWJpbmFyeSIpOwoJCS8vIHNhbWUgYXMgMy4qIC0gZGVyaXZlZDEgaXMgbGFzdCBiZWNhdXNlIGNvbnRlbnQgbWF0Y2hpbmcgaXMgd2VhaywgYWx0aG91ZyBuYW1lIG1hdGNoaW5nIGlzIHN0cm9uZwoJCWFzc2VydEVxdWFscygiNC4wIiwgMywgc2VsZWN0ZWQubGVuZ3RoKTsKCQlhc3NlcnRFcXVhbHMoIjQuMSIsIGRlcml2ZWQyLCBzZWxlY3RlZFswXSk7CgkJYXNzZXJ0RXF1YWxzKCI0LjIiLCBiYXNlLCBzZWxlY3RlZFsxXSk7CgoJCXNlbGVjdGVkID0gbWFuYWdlci5maW5kQ29udGVudFR5cGVzRm9yKGdldElucHV0U3RyZWFtKGludmFsaWRDb250ZW50cyksICJmb28ubXliaW5hcnkiKTsKCQkvLyBhbGwgdHlwZXMgaGF2ZSB3ZWFrIGNvbnRlbnQgbWF0Y2hpbmcgb25seSAtIGRlcml2ZWQxIGhhcyBzdHJvbmcgbmFtZSBtYXRjaGluZwoJCWFzc2VydEVxdWFscygiNS4wIiwgMywgc2VsZWN0ZWQubGVuZ3RoKTsKCQlhc3NlcnRFcXVhbHMoIjUuMSIsIGRlcml2ZWQxLCBzZWxlY3RlZFswXSk7CgkJYXNzZXJ0RXF1YWxzKCI1LjIiLCBiYXNlLCBzZWxlY3RlZFsxXSk7CgoJCXNlbGVjdGVkID0gbWFuYWdlci5maW5kQ29udGVudFR5cGVzRm9yKGdldElucHV0U3RyZWFtKGludmFsaWRDb250ZW50cyksICJhbnl0aGluZy5teWJpbmFyeSIpOwoJCS8vIGFsbCB0eXBlcyBoYXZlIHdlYWsgY29udGVudC9uYW1lIG1hdGNoaW5nIG9ubHkgLSBtb3N0IGdlbmVyYWwgd2lucwoJCWFzc2VydEVxdWFscygiNi4wIiwgMywgc2VsZWN0ZWQubGVuZ3RoKTsKCQlhc3NlcnRFcXVhbHMoIjYuMSIsIGJhc2UsIHNlbGVjdGVkWzBdKTsKCX0KCgkvKgoJICogVGVzdHMgYm90aCB0ZXh0IGFuZCBieXRlIHN0cmVhbS1iYXNlZCBnZXREZXNjcmlwdGlvbkZvciBtZXRob2RzLgoJICovCglwdWJsaWMgdm9pZCB0ZXN0Q29udGVudERlc2NyaXB0aW9uKCkgdGhyb3dzIElPRXhjZXB0aW9uLCBDb3JlRXhjZXB0aW9uIHsKCQlJQ29udGVudFR5cGVNYW5hZ2VyIGNvbnRlbnRUeXBlTWFuYWdlciA9IFBsYXRmb3JtLmdldENvbnRlbnRUeXBlTWFuYWdlcigpOwoJCUlDb250ZW50VHlwZU1hdGNoZXIgZmluZGVyID0gY29udGVudFR5cGVNYW5hZ2VyLmdldE1hdGNoZXIobmV3IExvY2FsU2VsZWN0aW9uUG9saWN5KCksIG51bGwpOwoKCQlJQ29udGVudFR5cGUgeG1sVHlwZSA9IGNvbnRlbnRUeXBlTWFuYWdlci5nZXRDb250ZW50VHlwZShQbGF0Zm9ybS5QSV9SVU5USU1FICsgIi54bWwiKTsKCQlJQ29udGVudFR5cGUgbXl0ZXh0ID0gY29udGVudFR5cGVNYW5hZ2VyLmdldENvbnRlbnRUeXBlKFBJX1JFU09VUkNFU19URVNUUyArICcuJyArICJteXRleHQiKTsKCQlJQ29udGVudFR5cGUgbXl0ZXh0MSA9IGNvbnRlbnRUeXBlTWFuYWdlci5nZXRDb250ZW50VHlwZShQSV9SRVNPVVJDRVNfVEVTVFMgKyAnLicgKyAibXl0ZXh0MSIpOwoJCUlDb250ZW50VHlwZSBteXRleHQyID0gY29udGVudFR5cGVNYW5hZ2VyLmdldENvbnRlbnRUeXBlKFBJX1JFU09VUkNFU19URVNUUyArICcuJyArICJteXRleHQyIik7CgoJCWJvb2xlYW4gdGV4dCA9IGZhbHNlOwoKCQlmb3IgKGludCBpID0gMDsgaSA8IDI7IGkrKywgdGV4dCA9ICF0ZXh0KSB7CgkJCVN0cmluZyBzdWZpeCA9IHRleHQgPyAiLXRleHQiIDogIi1iaW5hcnkiOwoJCQlJQ29udGVudERlc2NyaXB0aW9uIGRlc2NyaXB0aW9uOwoKCQkJZGVzY3JpcHRpb24gPSBnZXREZXNjcmlwdGlvbkZvcihmaW5kZXIsIE1JTklNQUxfWE1MLCAiVVRGLTgiLCAiZm9vLnhtbCIsIElDb250ZW50RGVzY3JpcHRpb24uQUxMLCB0ZXh0KTsKCQkJYXNzZXJ0Tm90TnVsbCgiMS4wIiArIHN1Zml4LCBkZXNjcmlwdGlvbik7CgkJCWFzc2VydEVxdWFscygiMS4xIiArIHN1Zml4LCB4bWxUeXBlLCBkZXNjcmlwdGlvbi5nZXRDb250ZW50VHlwZSgpKTsKCQkJYXNzZXJ0U2FtZSgiMS4yIiwgeG1sVHlwZS5nZXREZWZhdWx0RGVzY3JpcHRpb24oKSwgZGVzY3JpcHRpb24pOwoKCQkJZGVzY3JpcHRpb24gPSBnZXREZXNjcmlwdGlvbkZvcihmaW5kZXIsIE1JTklNQUxfWE1MLCAiVVRGLTgiLCAiZm9vLnhtbCIsIG5ldyBRdWFsaWZpZWROYW1lW10ge0lDb250ZW50RGVzY3JpcHRpb24uQ0hBUlNFVH0sIHRleHQpOwoJCQlhc3NlcnROb3ROdWxsKCIyLjAiICsgc3VmaXgsIGRlc2NyaXB0aW9uKTsKCQkJYXNzZXJ0RXF1YWxzKCIyLjEiICsgc3VmaXgsIHhtbFR5cGUsIGRlc2NyaXB0aW9uLmdldENvbnRlbnRUeXBlKCkpOwoJCQkvLyB0aGUgZGVmYXVsdCBjaGFyc2V0IHNob3VsZCBoYXZlIGJlZW4gZmlsbGVkIGJ5IHRoZSBjb250ZW50IHR5cGUgbWFuYWdlcgoJCQlhc3NlcnRFcXVhbHMoIjIuMiIgKyBzdWZpeCwgIlVURi04IiwgZGVzY3JpcHRpb24uZ2V0UHJvcGVydHkoSUNvbnRlbnREZXNjcmlwdGlvbi5DSEFSU0VUKSk7CgkJCWFzc2VydFNhbWUoIjIuMyIsIHhtbFR5cGUuZ2V0RGVmYXVsdERlc2NyaXB0aW9uKCksIGRlc2NyaXB0aW9uKTsKCgkJCWRlc2NyaXB0aW9uID0gZ2V0RGVzY3JpcHRpb25Gb3IoZmluZGVyLCBYTUxfSVNPXzg4NTlfMSwgIklTTy04ODU5LTEiLCAiZm9vLnhtbCIsIG5ldyBRdWFsaWZpZWROYW1lW10ge0lDb250ZW50RGVzY3JpcHRpb24uQ0hBUlNFVH0sIHRleHQpOwoJCQlhc3NlcnROb3ROdWxsKCIyLjNhIiArIHN1Zml4LCBkZXNjcmlwdGlvbik7CgkJCWFzc2VydEVxdWFscygiMi4zYiIgKyBzdWZpeCwgeG1sVHlwZSwgZGVzY3JpcHRpb24uZ2V0Q29udGVudFR5cGUoKSk7CgkJCWFzc2VydEVxdWFscygiMi4zYyIgKyBzdWZpeCwgIklTTy04ODU5LTEiLCBkZXNjcmlwdGlvbi5nZXRQcm9wZXJ0eShJQ29udGVudERlc2NyaXB0aW9uLkNIQVJTRVQpKTsKCQkJYXNzZXJ0Tm90U2FtZSgiMi4zZCIsIHhtbFR5cGUuZ2V0RGVmYXVsdERlc2NyaXB0aW9uKCksIGRlc2NyaXB0aW9uKTsKCgkJCS8vIGVuc3VyZSB3ZSBoYW5kbGUgc2luZ2xlIHF1b3RlcyBwcm9wZXJseSAoYnVnIDY1NDQzKQoJCQlkZXNjcmlwdGlvbiA9IGdldERlc2NyaXB0aW9uRm9yKGZpbmRlciwgWE1MX0lTT184ODU5XzFfU0lOR0xFX1FVT1RFUywgIklTTy04ODU5LTEiLCAiZm9vLnhtbCIsIG5ldyBRdWFsaWZpZWROYW1lW10ge0lDb250ZW50RGVzY3JpcHRpb24uQ0hBUlNFVH0sIHRleHQpOwoJCQlhc3NlcnROb3ROdWxsKCIyLjNlIiArIHN1Zml4LCBkZXNjcmlwdGlvbik7CgkJCWFzc2VydEVxdWFscygiMi4zZiIgKyBzdWZpeCwgeG1sVHlwZSwgZGVzY3JpcHRpb24uZ2V0Q29udGVudFR5cGUoKSk7CgkJCWFzc2VydEVxdWFscygiMi4zZyIgKyBzdWZpeCwgIklTTy04ODU5LTEiLCBkZXNjcmlwdGlvbi5nZXRQcm9wZXJ0eShJQ29udGVudERlc2NyaXB0aW9uLkNIQVJTRVQpKTsKCQkJYXNzZXJ0Tm90U2FtZSgiMi4zaCIsIHhtbFR5cGUuZ2V0RGVmYXVsdERlc2NyaXB0aW9uKCksIGRlc2NyaXB0aW9uKTsKCgkJCWRlc2NyaXB0aW9uID0gZ2V0RGVzY3JpcHRpb25Gb3IoZmluZGVyLCBYTUxfVVRGXzE2LCAiVVRGLTE2IiwgImZvby54bWwiLCBuZXcgUXVhbGlmaWVkTmFtZVtdIHtJQ29udGVudERlc2NyaXB0aW9uLkNIQVJTRVQsIElDb250ZW50RGVzY3JpcHRpb24uQllURV9PUkRFUl9NQVJLfSwgdGV4dCk7CgkJCWFzc2VydE5vdE51bGwoIjIuNGEiICsgc3VmaXgsIGRlc2NyaXB0aW9uKTsKCQkJYXNzZXJ0RXF1YWxzKCIyLjRiIiArIHN1Zml4LCB4bWxUeXBlLCBkZXNjcmlwdGlvbi5nZXRDb250ZW50VHlwZSgpKTsKCQkJYXNzZXJ0RXF1YWxzKCIyLjRjIiArIHN1Zml4LCAiVVRGLTE2IiwgZGVzY3JpcHRpb24uZ2V0UHJvcGVydHkoSUNvbnRlbnREZXNjcmlwdGlvbi5DSEFSU0VUKSk7CgkJCWFzc2VydFRydWUoIjIuNGQiICsgc3VmaXgsIHRleHQgfHwgSUNvbnRlbnREZXNjcmlwdGlvbi5CT01fVVRGXzE2QkUgPT0gZGVzY3JpcHRpb24uZ2V0UHJvcGVydHkoSUNvbnRlbnREZXNjcmlwdGlvbi5CWVRFX09SREVSX01BUkspKTsKCQkJYXNzZXJ0Tm90U2FtZSgiMi40ZSIsIHhtbFR5cGUuZ2V0RGVmYXVsdERlc2NyaXB0aW9uKCksIGRlc2NyaXB0aW9uKTsKCgkJCWRlc2NyaXB0aW9uID0gZ2V0RGVzY3JpcHRpb25Gb3IoZmluZGVyLCBYTUxfVVRGXzE2QkUsICJVVEYtOCIsICJmb28ueG1sIiwgbmV3IFF1YWxpZmllZE5hbWVbXSB7SUNvbnRlbnREZXNjcmlwdGlvbi5DSEFSU0VUfSwgdGV4dCk7CgkJCWFzc2VydE5vdE51bGwoIjIuNWEiICsgc3VmaXgsIGRlc2NyaXB0aW9uKTsKCQkJYXNzZXJ0RXF1YWxzKCIyLjViIiArIHN1Zml4LCB4bWxUeXBlLCBkZXNjcmlwdGlvbi5nZXRDb250ZW50VHlwZSgpKTsKCQkJYXNzZXJ0RXF1YWxzKCIyLjVjIiArIHN1Zml4LCAiVVRGLTE2QkUiLCBkZXNjcmlwdGlvbi5nZXRQcm9wZXJ0eShJQ29udGVudERlc2NyaXB0aW9uLkNIQVJTRVQpKTsKCQkJYXNzZXJ0Tm90U2FtZSgiMi41ZCIsIHhtbFR5cGUuZ2V0RGVmYXVsdERlc2NyaXB0aW9uKCksIGRlc2NyaXB0aW9uKTsKCgkJCWRlc2NyaXB0aW9uID0gZ2V0RGVzY3JpcHRpb25Gb3IoZmluZGVyLCBYTUxfVVRGXzE2TEUsICJVVEYtOCIsICJmb28ueG1sIiwgbmV3IFF1YWxpZmllZE5hbWVbXSB7SUNvbnRlbnREZXNjcmlwdGlvbi5DSEFSU0VUfSwgdGV4dCk7CgkJCWFzc2VydE5vdE51bGwoIjIuNmEiICsgc3VmaXgsIGRlc2NyaXB0aW9uKTsKCQkJYXNzZXJ0RXF1YWxzKCIyLjZiIiArIHN1Zml4LCB4bWxUeXBlLCBkZXNjcmlwdGlvbi5nZXRDb250ZW50VHlwZSgpKTsKCQkJLy8gdGhlIGRlZmF1bHQgY2hhcnNldCBzaG91bGQgaGF2ZSBiZWVuIGZpbGxlZCBieSB0aGUgY29udGVudCB0eXBlIG1hbmFnZXIKCQkJYXNzZXJ0RXF1YWxzKCIyLjZjIiArIHN1Zml4LCAiVVRGLTE2TEUiLCBkZXNjcmlwdGlvbi5nZXRQcm9wZXJ0eShJQ29udGVudERlc2NyaXB0aW9uLkNIQVJTRVQpKTsKCQkJYXNzZXJ0Tm90U2FtZSgiMi42ZCIsIHhtbFR5cGUuZ2V0RGVmYXVsdERlc2NyaXB0aW9uKCksIGRlc2NyaXB0aW9uKTsKCgkJCWRlc2NyaXB0aW9uID0gZ2V0RGVzY3JpcHRpb25Gb3IoZmluZGVyLCBNSU5JTUFMX1hNTCwgIlVURi04IiwgImZvby54bWwiLCBJQ29udGVudERlc2NyaXB0aW9uLkFMTCwgdGV4dCk7CgkJCWFzc2VydE5vdE51bGwoIjQuMCIgKyBzdWZpeCwgZGVzY3JpcHRpb24pOwoJCQlhc3NlcnRFcXVhbHMoIjQuMSIgKyBzdWZpeCwgeG1sVHlwZSwgZGVzY3JpcHRpb24uZ2V0Q29udGVudFR5cGUoKSk7CgkJCWFzc2VydEVxdWFscygiNC4yIiArIHN1Zml4LCAiVVRGLTgiLCBkZXNjcmlwdGlvbi5nZXRQcm9wZXJ0eShJQ29udGVudERlc2NyaXB0aW9uLkNIQVJTRVQpKTsKCQkJYXNzZXJ0Tm90TnVsbCgiNS4wIiArIHN1Zml4LCBteXRleHQpOwoJCQlhc3NlcnRFcXVhbHMoIjUuMGIiICsgc3VmaXgsICJCQVIiLCBteXRleHQuZ2V0RGVmYXVsdENoYXJzZXQoKSk7CgkJCWFzc2VydFNhbWUoIjUuMGMiLCB4bWxUeXBlLmdldERlZmF1bHREZXNjcmlwdGlvbigpLCBkZXNjcmlwdGlvbik7CgoJCQlkZXNjcmlwdGlvbiA9IGdldERlc2NyaXB0aW9uRm9yKGZpbmRlciwgInNvbWUgY29udGVudHMiLCBudWxsLCAiYWJjLnR6dCIsIElDb250ZW50RGVzY3JpcHRpb24uQUxMLCB0ZXh0KTsKCQkJYXNzZXJ0Tm90TnVsbCgiNS4xIiArIHN1Zml4LCBkZXNjcmlwdGlvbik7CgkJCWFzc2VydEVxdWFscygiNS4yIiArIHN1Zml4LCBteXRleHQsIGRlc2NyaXB0aW9uLmdldENvbnRlbnRUeXBlKCkpOwoJCQlhc3NlcnRFcXVhbHMoIjUuMyIgKyBzdWZpeCwgIkJBUiIsIGRlc2NyaXB0aW9uLmdldFByb3BlcnR5KElDb250ZW50RGVzY3JpcHRpb24uQ0hBUlNFVCkpOwoJCQlhc3NlcnRTYW1lKCI1LjQiLCBteXRleHQuZ2V0RGVmYXVsdERlc2NyaXB0aW9uKCksIGRlc2NyaXB0aW9uKTsKCQkJLy8gbm93IHBsYXlzIHdpdGggc2V0dGluZyBhIG5vbi1kZWZhdWx0IGRlZmF1bHQgY2hhcnNldAoJCQlteXRleHQuc2V0RGVmYXVsdENoYXJzZXQoIkZPTyIpOwoKCQkJZGVzY3JpcHRpb24gPSBnZXREZXNjcmlwdGlvbkZvcihmaW5kZXIsICJzb21lIGNvbnRlbnRzIiwgbnVsbCwgImFiYy50enQiLCBJQ29udGVudERlc2NyaXB0aW9uLkFMTCwgdGV4dCk7CgkJCWFzc2VydE5vdE51bGwoIjUuNSIgKyBzdWZpeCwgZGVzY3JpcHRpb24pOwoJCQlhc3NlcnRFcXVhbHMoIjUuNiIgKyBzdWZpeCwgbXl0ZXh0LCBkZXNjcmlwdGlvbi5nZXRDb250ZW50VHlwZSgpKTsKCQkJYXNzZXJ0RXF1YWxzKCI1LjciICsgc3VmaXgsICJGT08iLCBkZXNjcmlwdGlvbi5nZXRQcm9wZXJ0eShJQ29udGVudERlc2NyaXB0aW9uLkNIQVJTRVQpKTsKCQkJYXNzZXJ0U2FtZSgiNS44IiwgbXl0ZXh0LmdldERlZmF1bHREZXNjcmlwdGlvbigpLCBkZXNjcmlwdGlvbik7CgkJCW15dGV4dC5zZXREZWZhdWx0Q2hhcnNldChudWxsKTsKCgkJCWRlc2NyaXB0aW9uID0gZ2V0RGVzY3JpcHRpb25Gb3IoZmluZGVyLCAic29tZSBjb250ZW50cyIsIG51bGwsICJhYmMudHp0IiwgSUNvbnRlbnREZXNjcmlwdGlvbi5BTEwsIHRleHQpOwoJCQlhc3NlcnROb3ROdWxsKCI1LjEwIiArIHN1Zml4LCBkZXNjcmlwdGlvbik7CgkJCWFzc2VydEVxdWFscygiNS4xMSIgKyBzdWZpeCwgbXl0ZXh0LCBkZXNjcmlwdGlvbi5nZXRDb250ZW50VHlwZSgpKTsKCQkJYXNzZXJ0RXF1YWxzKCI1LjEyIiArIHN1Zml4LCAiQkFSIiwgZGVzY3JpcHRpb24uZ2V0UHJvcGVydHkoSUNvbnRlbnREZXNjcmlwdGlvbi5DSEFSU0VUKSk7CgkJCWFzc2VydFNhbWUoIjUuMTMiLCBteXRleHQuZ2V0RGVmYXVsdERlc2NyaXB0aW9uKCksIGRlc2NyaXB0aW9uKTsKCgkJCS8vIHNlZSBodHRwczovL2J1Z3MuZWNsaXBzZS5vcmcvYnVncy9zaG93X2J1Zy5jZ2k/aWQ9MTc2MzU0CgkJCWRlc2NyaXB0aW9uID0gZ2V0RGVzY3JpcHRpb25Gb3IoZmluZGVyLCAiPD94bWwgdmVyc2lvbj1cJzEuMFwnIGVuY29kaW5nPVwnVVRGLThcJz8+PHNvYXBlbnY6RW52ZWxvcGUgeG1sbnM6c29hcGVudj1cImh0dHA6Ly9zY2hlbWFzLnhtbHNvYXAub3JnL3NvYXAvZW52ZWxvcGUvXCIgeG1sbnM6dG5zPVwiaHR0cDovL3d3dy5leGFtcGxlLm9yZy9cIiB4bWxuczpuczA9XCJodHRwOi8vYW5vdGhlci5leGFtcGxlLm9yZy9cIj48c29hcGVudjpIZWFkZXIgLz48c29hcGVudjpCb2R5PjxuczA6eCAvPjwvc29hcGVudjpCb2R5Pjwvc29hcGVudjpFbnZlbG9wZT4iLCAiVVRGLTgiLCAiZm9vLnhtbCIsIG5ldyBRdWFsaWZpZWROYW1lW10ge0lDb250ZW50RGVzY3JpcHRpb24uQ0hBUlNFVH0sIHRleHQpOwoJCQlhc3NlcnROb3ROdWxsKCI1LjE0IiArIHN1Zml4LCBkZXNjcmlwdGlvbik7CgkJCWFzc2VydEVxdWFscygiNS4xNSIgKyBzdWZpeCwgeG1sVHlwZSwgZGVzY3JpcHRpb24uZ2V0Q29udGVudFR5cGUoKSk7CgkJCWFzc2VydEVxdWFscygiNS4xNiIgKyBzdWZpeCwgIlVURi04IiwgZGVzY3JpcHRpb24uZ2V0UHJvcGVydHkoSUNvbnRlbnREZXNjcmlwdGlvbi5DSEFSU0VUKSk7CgkJCWFzc2VydEVxdWFscygiNS4xNyIsIHhtbFR5cGUuZ2V0RGVmYXVsdERlc2NyaXB0aW9uKCkuZ2V0Q2hhcnNldCgpLCBkZXNjcmlwdGlvbi5nZXRDaGFyc2V0KCkpOwoJCX0KCQlhc3NlcnROb3ROdWxsKCI2LjAiLCBteXRleHQxKTsKCQlhc3NlcnRFcXVhbHMoIjYuMSIsICJCQVIiLCBteXRleHQxLmdldERlZmF1bHRDaGFyc2V0KCkpOwoJCWFzc2VydE5vdE51bGwoIjYuMiIsIG15dGV4dDIpOwoJCWFzc2VydEVxdWFscygiNi4zIiwgbnVsbCwgbXl0ZXh0Mi5nZXREZWZhdWx0Q2hhcnNldCgpKTsKCgl9CgoJLyoqCgkgKiBAc2VlIElDb250ZW50VHlwZU1hdGNoZXIjZmluZENvbnRlbnRUeXBlRm9yCgkgKi8KCXB1YmxpYyB2b2lkIHRlc3RDb250ZW50RGV0ZWN0aW9uKCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKCQlJQ29udGVudFR5cGVNYW5hZ2VyIGNvbnRlbnRUeXBlTWFuYWdlciA9IFBsYXRmb3JtLmdldENvbnRlbnRUeXBlTWFuYWdlcigpOwoJCUlDb250ZW50VHlwZU1hdGNoZXIgZmluZGVyOwoKCQlJQ29udGVudFR5cGUgaW5hcHByb3ByaWF0ZSA9IGNvbnRlbnRUeXBlTWFuYWdlci5nZXRDb250ZW50VHlwZShQSV9SRVNPVVJDRVNfVEVTVFMgKyAiLnNhbXBsZS1iaW5hcnkxIik7CgkJSUNvbnRlbnRUeXBlIGFwcHJvcHJpYXRlID0gY29udGVudFR5cGVNYW5hZ2VyLmdldENvbnRlbnRUeXBlKFBsYXRmb3JtLlBJX1JVTlRJTUUgKyAiLnhtbCIpOwoJCUlDb250ZW50VHlwZSBhcHByb3ByaWF0ZVNwZWNpZmljMSA9IGNvbnRlbnRUeXBlTWFuYWdlci5nZXRDb250ZW50VHlwZShQSV9SRVNPVVJDRVNfVEVTVFMgKyAiLnhtbC1iYXNlZC1kaWZmZXJlbnQtZXh0ZW5zaW9uIik7CgkJSUNvbnRlbnRUeXBlIGFwcHJvcHJpYXRlU3BlY2lmaWMxTG93UHJpb3JpdHkgPSBjb250ZW50VHlwZU1hbmFnZXIuZ2V0Q29udGVudFR5cGUoUElfUkVTT1VSQ0VTX1RFU1RTICsgIi54bWwtYmFzZWQtZGlmZmVyZW50LWV4dGVuc2lvbi1sb3ctcHJpb3JpdHkiKTsKCQlJQ29udGVudFR5cGUgYXBwcm9wcmlhdGVTcGVjaWZpYzIgPSBjb250ZW50VHlwZU1hbmFnZXIuZ2V0Q29udGVudFR5cGUoUElfUkVTT1VSQ0VTX1RFU1RTICsgIi54bWwtYmFzZWQtc3BlY2lmaWMtbmFtZSIpOwoKCQkvLyBpZiBvbmx5IGluYXBwcm9wcmlhdGUgaXMgcHJvdmlkZWQsIG5vbmUgd2lsbCBiZSBzZWxlY3RlZAoJCWZpbmRlciA9IGNvbnRlbnRUeXBlTWFuYWdlci5nZXRNYXRjaGVyKG5ldyBTdWJzZXRTZWxlY3Rpb25Qb2xpY3kobmV3IElDb250ZW50VHlwZVtdIHtpbmFwcHJvcHJpYXRlfSksIG51bGwpOwoJCWFzc2VydE51bGwoIjEuMCIsIGZpbmRlci5maW5kQ29udGVudFR5cGVGb3IoZ2V0SW5wdXRTdHJlYW0oTUlOSU1BTF9YTUwpLCBudWxsKSk7CgoJCS8vIGlmIGluYXBwcm9wcmlhdGUgYW5kIGFwcHJvcHJpYXRlIGFyZSBwcm92aWRlZCwgYXBwcm9wcmlhdGUgd2lsbCBiZSBzZWxlY3RlZAoJCWZpbmRlciA9IGNvbnRlbnRUeXBlTWFuYWdlci5nZXRNYXRjaGVyKG5ldyBTdWJzZXRTZWxlY3Rpb25Qb2xpY3kobmV3IElDb250ZW50VHlwZVtdIHtpbmFwcHJvcHJpYXRlLCBhcHByb3ByaWF0ZX0pLCBudWxsKTsKCQlhc3NlcnRFcXVhbHMoIjIuMCIsIGFwcHJvcHJpYXRlLCBmaW5kZXIuZmluZENvbnRlbnRUeXBlRm9yKGdldElucHV0U3RyZWFtKE1JTklNQUxfWE1MKSwgbnVsbCkpOwoKCQkvLyBpZiBpbmFwcHJvcHJpYXRlLCBhcHByb3ByaWF0ZSBhbmQgYSBtb3JlIHNwZWNpZmljIGFwcHJvcHJpYXRlIHR5cGUgYXJlIHByb3ZpZGVkLCB0aGUgc3BlY2lmaWMgdHlwZSB3aWxsIGJlIHNlbGVjdGVkCgkJZmluZGVyID0gY29udGVudFR5cGVNYW5hZ2VyLmdldE1hdGNoZXIobmV3IFN1YnNldFNlbGVjdGlvblBvbGljeShuZXcgSUNvbnRlbnRUeXBlW10ge2luYXBwcm9wcmlhdGUsIGFwcHJvcHJpYXRlLCBhcHByb3ByaWF0ZVNwZWNpZmljMX0pLCBudWxsKTsKCQlhc3NlcnRFcXVhbHMoIjMuMCIsIGFwcHJvcHJpYXRlU3BlY2lmaWMxLCBmaW5kZXIuZmluZENvbnRlbnRUeXBlRm9yKGdldElucHV0U3RyZWFtKE1JTklNQUxfWE1MKSwgbnVsbCkpOwoJCWZpbmRlciA9IGNvbnRlbnRUeXBlTWFuYWdlci5nZXRNYXRjaGVyKG5ldyBTdWJzZXRTZWxlY3Rpb25Qb2xpY3kobmV3IElDb250ZW50VHlwZVtdIHtpbmFwcHJvcHJpYXRlLCBhcHByb3ByaWF0ZSwgYXBwcm9wcmlhdGVTcGVjaWZpYzJ9KSwgbnVsbCk7CgkJYXNzZXJ0RXF1YWxzKCIzLjEiLCBhcHByb3ByaWF0ZVNwZWNpZmljMiwgZmluZGVyLmZpbmRDb250ZW50VHlwZUZvcihnZXRJbnB1dFN0cmVhbShNSU5JTUFMX1hNTCksIG51bGwpKTsKCgkJLy8gaWYgYWxsIGFyZSBwcm92aWRlZCwgdGhlIG1vcmUgc3BlY2lmaWMgdHlwZXMgd2lsbCBhcHBlYXIgYmVmb3JlIHRoZSBtb3JlIGdlbmVyaWMgdHlwZXMKCQlmaW5kZXIgPSBjb250ZW50VHlwZU1hbmFnZXIuZ2V0TWF0Y2hlcihuZXcgU3Vic2V0U2VsZWN0aW9uUG9saWN5KG5ldyBJQ29udGVudFR5cGVbXSB7aW5hcHByb3ByaWF0ZSwgYXBwcm9wcmlhdGUsIGFwcHJvcHJpYXRlU3BlY2lmaWMxLCBhcHByb3ByaWF0ZVNwZWNpZmljMn0pLCBudWxsKTsKCQlJQ29udGVudFR5cGVbXSBzZWxlY3RlZCA9IGZpbmRlci5maW5kQ29udGVudFR5cGVzRm9yKGdldElucHV0U3RyZWFtKE1JTklNQUxfWE1MKSwgbnVsbCk7CgkJYXNzZXJ0RXF1YWxzKCI0LjAiLCAzLCBzZWxlY3RlZC5sZW5ndGgpOwoJCWFzc2VydFRydWUoIjQuMSIsIGFwcHJvcHJpYXRlU3BlY2lmaWMxLmVxdWFscyhzZWxlY3RlZFswXSkgfHwgYXBwcm9wcmlhdGVTcGVjaWZpYzEuZXF1YWxzKHNlbGVjdGVkWzFdKSk7CgkJYXNzZXJ0VHJ1ZSgiNC4yIiwgYXBwcm9wcmlhdGVTcGVjaWZpYzIuZXF1YWxzKHNlbGVjdGVkWzBdKSB8fCBhcHByb3ByaWF0ZVNwZWNpZmljMi5lcXVhbHMoc2VsZWN0ZWRbMV0pKTsKCQlhc3NlcnRUcnVlKCI0LjMiLCBhcHByb3ByaWF0ZS5lcXVhbHMoc2VsZWN0ZWRbMl0pKTsKCgkJLy8gaWYgYXBwcm9wcmlhdGUgYW5kIGEgbW9yZSBzcGVjaWZpYyBhcHByb3ByaWF0ZSB0eXBlIChidXQgd2l0aCBsb3cgcHJpb3JpdHkpIGFyZSBwcm92aWRlZCwgdGhlIHNwZWNpZmljIHR5cGUgd2lsbCBiZSBzZWxlY3RlZAoJCWZpbmRlciA9IGNvbnRlbnRUeXBlTWFuYWdlci5nZXRNYXRjaGVyKG5ldyBTdWJzZXRTZWxlY3Rpb25Qb2xpY3kobmV3IElDb250ZW50VHlwZVtdIHthcHByb3ByaWF0ZSwgYXBwcm9wcmlhdGVTcGVjaWZpYzFMb3dQcmlvcml0eX0pLCBudWxsKTsKCQlhc3NlcnRFcXVhbHMoIjUuMCIsIGFwcHJvcHJpYXRlU3BlY2lmaWMxTG93UHJpb3JpdHksIGZpbmRlci5maW5kQ29udGVudFR5cGVGb3IoZ2V0SW5wdXRTdHJlYW0oTUlOSU1BTF9YTUwpLCBudWxsKSk7CgoJCS8vIGlmIGFwcHJvcHJpYXRlIGFuZCB0d28gc3BlY2lmaWMgYXBwcm9wcmlhdGUgdHlwZXMgKGJ1dCBvbmUgd2l0aCBsb3dlciBwcmlvcml0eSkgYXJlIHByb3ZpZGVkLCB0aGUgc3BlY2lmaWMgdHlwZSB3aXRoIGhpZ2hlciBwcmlvcml0eSB3aWxsIGJlIHNlbGVjdGVkCgkJZmluZGVyID0gY29udGVudFR5cGVNYW5hZ2VyLmdldE1hdGNoZXIobmV3IFN1YnNldFNlbGVjdGlvblBvbGljeShuZXcgSUNvbnRlbnRUeXBlW10ge2FwcHJvcHJpYXRlLCBhcHByb3ByaWF0ZVNwZWNpZmljMSwgYXBwcm9wcmlhdGVTcGVjaWZpYzFMb3dQcmlvcml0eX0pLCBudWxsKTsKCQlhc3NlcnRFcXVhbHMoIjUuMSIsIGFwcHJvcHJpYXRlU3BlY2lmaWMxLCBmaW5kZXIuZmluZENvbnRlbnRUeXBlRm9yKGdldElucHV0U3RyZWFtKE1JTklNQUxfWE1MKSwgbnVsbCkpOwoJfQoKCXB1YmxpYyB2b2lkIHRlc3REZWZhdWx0UHJvcGVydGllcygpIHRocm93cyBJT0V4Y2VwdGlvbiAvKiBuZXZlciBhY3R1YWxseSB0aHJvd24gKi8gewoJCUlDb250ZW50VHlwZU1hbmFnZXIgY29udGVudFR5cGVNYW5hZ2VyID0gUGxhdGZvcm0uZ2V0Q29udGVudFR5cGVNYW5hZ2VyKCk7CgoJCUlDb250ZW50VHlwZSBteXRleHQgPSBjb250ZW50VHlwZU1hbmFnZXIuZ2V0Q29udGVudFR5cGUoUElfUkVTT1VSQ0VTX1RFU1RTICsgJy4nICsgIm15dGV4dCIpOwoJCUlDb250ZW50VHlwZSBteXRleHQxID0gY29udGVudFR5cGVNYW5hZ2VyLmdldENvbnRlbnRUeXBlKFBJX1JFU09VUkNFU19URVNUUyArICcuJyArICJteXRleHQxIik7CgkJSUNvbnRlbnRUeXBlIG15dGV4dDIgPSBjb250ZW50VHlwZU1hbmFnZXIuZ2V0Q29udGVudFR5cGUoUElfUkVTT1VSQ0VTX1RFU1RTICsgJy4nICsgIm15dGV4dDIiKTsKCQlhc3NlcnROb3ROdWxsKCIwLjEiLCBteXRleHQpOwoJCWFzc2VydE5vdE51bGwoIjAuMiIsIG15dGV4dDEpOwoJCWFzc2VydE5vdE51bGwoIjAuMyIsIG15dGV4dDIpOwoKCQlRdWFsaWZpZWROYW1lIGNoYXJzZXQgPSBJQ29udGVudERlc2NyaXB0aW9uLkNIQVJTRVQ7CgkJUXVhbGlmaWVkTmFtZSBsb2NhbENoYXJzZXQgPSBuZXcgUXVhbGlmaWVkTmFtZShQSV9SRVNPVVJDRVNfVEVTVFMsICJjaGFyc2V0Iik7CgkJUXVhbGlmaWVkTmFtZSBwcm9wZXJ0eTEgPSBuZXcgUXVhbGlmaWVkTmFtZShQSV9SRVNPVVJDRVNfVEVTVFMsICJwcm9wZXJ0eTEiKTsKCQlRdWFsaWZpZWROYW1lIHByb3BlcnR5MiA9IG5ldyBRdWFsaWZpZWROYW1lKFBJX1JFU09VUkNFU19URVNUUywgInByb3BlcnR5MiIpOwoJCVF1YWxpZmllZE5hbWUgcHJvcGVydHkzID0gbmV3IFF1YWxpZmllZE5hbWUoUElfUkVTT1VSQ0VTX1RFU1RTLCAicHJvcGVydHkzIik7CgkJUXVhbGlmaWVkTmFtZSBwcm9wZXJ0eTQgPSBuZXcgUXVhbGlmaWVkTmFtZShQSV9SRVNPVVJDRVNfVEVTVFMsICJwcm9wZXJ0eTQiKTsKCgkJSUNvbnRlbnREZXNjcmlwdGlvbiBkZXNjcmlwdGlvbjsKCQlJQ29udGVudFR5cGVNYXRjaGVyIGZpbmRlciA9IGNvbnRlbnRUeXBlTWFuYWdlci5nZXRNYXRjaGVyKG5ldyBMb2NhbFNlbGVjdGlvblBvbGljeSgpLCBudWxsKTsKCgkJZGVzY3JpcHRpb24gPSBnZXREZXNjcmlwdGlvbkZvcihmaW5kZXIsICJzb21lIGNvbnRlbnRzIiwgbnVsbCwgImFiYy50enQiLCBJQ29udGVudERlc2NyaXB0aW9uLkFMTCwgdHJ1ZSk7CgkJYXNzZXJ0Tm90TnVsbCgiMS4wIiwgZGVzY3JpcHRpb24pOwoJCWFzc2VydEVxdWFscygiMS4xIiwgbXl0ZXh0LCBkZXNjcmlwdGlvbi5nZXRDb250ZW50VHlwZSgpKTsKCQlhc3NlcnRFcXVhbHMoIjEuMiIsICJ2YWx1ZTEiLCBkZXNjcmlwdGlvbi5nZXRQcm9wZXJ0eShwcm9wZXJ0eTEpKTsKCQlhc3NlcnROdWxsKCIxLjMiLCBkZXNjcmlwdGlvbi5nZXRQcm9wZXJ0eShwcm9wZXJ0eTIpKTsKCQlhc3NlcnRFcXVhbHMoIjEuNCIsICJ2YWx1ZTMiLCBkZXNjcmlwdGlvbi5nZXRQcm9wZXJ0eShwcm9wZXJ0eTMpKTsKCQlhc3NlcnRFcXVhbHMoIjEuNSIsICJCQVIiLCBkZXNjcmlwdGlvbi5nZXRQcm9wZXJ0eShjaGFyc2V0KSk7CgoJCWRlc2NyaXB0aW9uID0gZ2V0RGVzY3JpcHRpb25Gb3IoZmluZGVyLCAic29tZSBjb250ZW50cyIsIG51bGwsICJhYmMudHp0MSIsIElDb250ZW50RGVzY3JpcHRpb24uQUxMLCB0cnVlKTsKCQlhc3NlcnROb3ROdWxsKCIyLjAiLCBkZXNjcmlwdGlvbik7CgkJYXNzZXJ0RXF1YWxzKCIyLjEiLCBteXRleHQxLCBkZXNjcmlwdGlvbi5nZXRDb250ZW50VHlwZSgpKTsKCQlhc3NlcnRFcXVhbHMoIjIuMiIsICJ2YWx1ZTEiLCBkZXNjcmlwdGlvbi5nZXRQcm9wZXJ0eShwcm9wZXJ0eTEpKTsKCQlhc3NlcnRFcXVhbHMoIjIuMyIsICJ2YWx1ZTIiLCBkZXNjcmlwdGlvbi5nZXRQcm9wZXJ0eShwcm9wZXJ0eTIpKTsKCQlhc3NlcnROdWxsKCIyLjQiLCBkZXNjcmlwdGlvbi5nZXRQcm9wZXJ0eShwcm9wZXJ0eTMpKTsKCQlhc3NlcnRFcXVhbHMoIjIuNSIsICJ2YWx1ZTQiLCBkZXNjcmlwdGlvbi5nZXRQcm9wZXJ0eShwcm9wZXJ0eTQpKTsKCQlhc3NlcnRFcXVhbHMoIjIuNiIsICJCQVIiLCBkZXNjcmlwdGlvbi5nZXRQcm9wZXJ0eShjaGFyc2V0KSk7CgoJCWRlc2NyaXB0aW9uID0gZ2V0RGVzY3JpcHRpb25Gb3IoZmluZGVyLCAic29tZSBjb250ZW50cyIsIG51bGwsICJhYmMudHp0MiIsIElDb250ZW50RGVzY3JpcHRpb24uQUxMLCB0cnVlKTsKCQlhc3NlcnROb3ROdWxsKCIzLjAiLCBkZXNjcmlwdGlvbik7CgkJYXNzZXJ0RXF1YWxzKCIzLjEiLCBteXRleHQyLCBkZXNjcmlwdGlvbi5nZXRDb250ZW50VHlwZSgpKTsKCQlhc3NlcnROdWxsKCIzLjIiLCBkZXNjcmlwdGlvbi5nZXRQcm9wZXJ0eShwcm9wZXJ0eTEpKTsKCQlhc3NlcnROdWxsKCIzLjMiLCBkZXNjcmlwdGlvbi5nZXRQcm9wZXJ0eShwcm9wZXJ0eTIpKTsKCQlhc3NlcnROdWxsKCIzLjQiLCBkZXNjcmlwdGlvbi5nZXRQcm9wZXJ0eShwcm9wZXJ0eTMpKTsKCQlhc3NlcnROdWxsKCIzLjUiLCBkZXNjcmlwdGlvbi5nZXRQcm9wZXJ0eShwcm9wZXJ0eTQpKTsKCQlhc3NlcnROdWxsKCIzLjYiLCBkZXNjcmlwdGlvbi5nZXRQcm9wZXJ0eShjaGFyc2V0KSk7CgkJYXNzZXJ0RXF1YWxzKCIzLjciLCAibXl0ZXh0MiIsIGRlc2NyaXB0aW9uLmdldFByb3BlcnR5KGxvY2FsQ2hhcnNldCkpOwoJfQoKCS8qKgoJICogVGhlIGZvb0JhciBjb250ZW50IHR5cGUgaXMgYXNzb2NpYXRlZCB3aXRoIHRoZSAiZm9vLmJhciIgZmlsZSBuYW1lIGFuZAoJICogdGhlICJiYXIiIGZpbGUgZXh0ZW5zaW9uICh3aGF0IGlzIGJvZ3VzLCBhbnl3YXkpLiBUaGlzIHRlc3QgZW5zdXJlcyBpdAoJICogZG9lcyBub3QgYXBwZWFyIHR3aWNlIGluIHRoZSBsaXN0IG9mIGNvbnRlbnQgdHlwZXMgYXNzb2NpYXRlZCB3aXRoIHRoZQoJICogImZvby5iYXIiIGZpbGUgbmFtZS4KCSAqLwoJcHVibGljIHZvaWQgdGVzdERvdWJsZUFzc29jaWF0aW9uKCkgewoJCUlDb250ZW50VHlwZU1hbmFnZXIgY29udGVudFR5cGVNYW5hZ2VyID0gUGxhdGZvcm0uZ2V0Q29udGVudFR5cGVNYW5hZ2VyKCk7CgoJCUlDb250ZW50VHlwZSBmb29CYXJUeXBlID0gY29udGVudFR5cGVNYW5hZ2VyLmdldENvbnRlbnRUeXBlKFBJX1JFU09VUkNFU19URVNUUyArICcuJyArICJmb29CYXIiKTsKCQlhc3NlcnROb3ROdWxsKCIxLjAiLCBmb29CYXJUeXBlKTsKCQlJQ29udGVudFR5cGUgc3ViRm9vQmFyVHlwZSA9IGNvbnRlbnRUeXBlTWFuYWdlci5nZXRDb250ZW50VHlwZShQSV9SRVNPVVJDRVNfVEVTVFMgKyAnLicgKyAic3ViRm9vQmFyIik7CgkJYXNzZXJ0Tm90TnVsbCgiMS4xIiwgc3ViRm9vQmFyVHlwZSk7CgkJLy8gZW5zdXJlIHdlIGRvbid0IGdldCBmb29CYXIgdHdpY2UKCQlJQ29udGVudFR5cGVNYXRjaGVyIGZpbmRlciA9IGNvbnRlbnRUeXBlTWFuYWdlci5nZXRNYXRjaGVyKG5ldyBMb2NhbFNlbGVjdGlvblBvbGljeSgpLCBudWxsKTsKCQlJQ29udGVudFR5cGVbXSBmb29CYXJBc3NvY2lhdGVkID0gZmluZGVyLmZpbmRDb250ZW50VHlwZXNGb3IoY2hhbmdlQ2FzZSgiZm9vLmJhciIpKTsKCQlhc3NlcnRFcXVhbHMoIjIuMSIsIDIsIGZvb0JhckFzc29jaWF0ZWQubGVuZ3RoKTsKCQlhc3NlcnRUcnVlKCIyLjIiLCBjb250YWlucyhmb29CYXJBc3NvY2lhdGVkLCBmb29CYXJUeXBlKSk7CgkJYXNzZXJ0VHJ1ZSgiMi4zIiwgY29udGFpbnMoZm9vQmFyQXNzb2NpYXRlZCwgc3ViRm9vQmFyVHlwZSkpOwoJfQoKCS8qKgoJICogT2J0YWlucyBhIHJlZmVyZW5jZSB0byBhIGtub3duIGNvbnRlbnQgdHlwZSwgdGhlbiBpbnN0YWxscyBhIGJ1bmRsZSB0aGF0IGNvbnRyaWJ1dGVzIGEgY29udGVudCB0eXBlLAoJICogYW5kIG1ha2VzIHN1cmUgYSBuZXcgb2J0YWluZWQgcmVmZXJlbmNlIHRvIHRoZSBzYW1lIGNvbnRlbnQgdHlwZSBpcyBub3QgaWRlbnRpY2FsIChzaG93cwoJICogdGhhdCB0aGUgY29udGVudCB0eXBlIGNhdGFsb2cgaGFzIGJlZW4gZGlzY2FyZGVkIGFuZCByZWJ1aWx0KS4gVGhlbiB1bmluc3RhbGxzIHRoYXQgYnVuZGxlCgkgKiBhbmQgY2hlY2tzIGFnYWluIHRoZSBzYW1lIHRoaW5nIChiZWNhdXNlIHRoZSBjb250ZW50IHR5cGUgY2F0YWxvZyBzaG91bGQgYmUgcmVidWlsdCB3aGVuZXZlcgoJICogY29udGVudCB0eXBlcyBhcmUgZHluYW1pY2FseSBhZGRlZC9yZW1vdmVkKS4KCSAqLwoJcHVibGljIHZvaWQgdGVzdER5bmFtaWNDaGFuZ2VzKCkgewoJCWZpbmFsIElDb250ZW50VHlwZVtdIHRleHQgPSBuZXcgSUNvbnRlbnRUeXBlWzRdOwoJCWZpbmFsIElDb250ZW50VHlwZU1hbmFnZXIgbWFuYWdlciA9IFBsYXRmb3JtLmdldENvbnRlbnRUeXBlTWFuYWdlcigpOwoJCXRleHRbMF0gPSBtYW5hZ2VyLmdldENvbnRlbnRUeXBlKElDb250ZW50VHlwZU1hbmFnZXIuQ1RfVEVYVCk7CgkJYXNzZXJ0Tm90TnVsbCgiMS4wIiwgdGV4dFswXSk7CgkJdGV4dFsxXSA9IG1hbmFnZXIuZ2V0Q29udGVudFR5cGUoSUNvbnRlbnRUeXBlTWFuYWdlci5DVF9URVhUKTsKCQlhc3NlcnROb3ROdWxsKCIxLjEiLCB0ZXh0WzFdKTsKCQl0ZXh0WzBdID0gKChDb250ZW50VHlwZUhhbmRsZXIpIHRleHRbMF0pLmdldFRhcmdldCgpOwoJCXRleHRbMV0gPSAoKENvbnRlbnRUeXBlSGFuZGxlcikgdGV4dFsxXSkuZ2V0VGFyZ2V0KCk7CgkJYXNzZXJ0RXF1YWxzKCIyLjAiLCB0ZXh0WzBdLCB0ZXh0WzFdKTsKCQlhc3NlcnRUcnVlKCIyLjEiLCB0ZXh0WzBdID09IHRleHRbMV0pOwoJCS8vCW1ha2UgYXJiaXRyYXJ5IGR5bmFtaWMgY2hhbmdlcyB0byB0aGUgY29udGVudFR5cGVzIGV4dGVuc2lvbiBwb2ludAoJCVRlc3RSZWdpc3RyeUNoYW5nZUxpc3RlbmVyIGxpc3RlbmVyID0gbmV3IFRlc3RSZWdpc3RyeUNoYW5nZUxpc3RlbmVyKFBsYXRmb3JtLlBJX1JVTlRJTUUsIENvbnRlbnRUeXBlQnVpbGRlci5QVF9DT05URU5UVFlQRVMsIG51bGwsIG51bGwpOwoJCUJ1bmRsZVRlc3RpbmdIZWxwZXIucnVuV2l0aEJ1bmRsZXMoIjMiLCAoKSAtPiB7CgkJCUlDb250ZW50VHlwZSBtaXNzaW5nID0gbWFuYWdlci5nZXRDb250ZW50VHlwZSgib3JnLmVjbGlwc2UuYnVuZGxlMDEubWlzc2luZyIpOwoJCQlhc3NlcnROb3ROdWxsKCIzLjEiLCBtaXNzaW5nKTsKCQkJLy8gZW5zdXJlIHRoZSBjb250ZW50IHR5cGUgaW5zdGFuY2VzIGFyZSBkaWZmZXJlbnQKCQkJdGV4dFsyXSA9IG1hbmFnZXIuZ2V0Q29udGVudFR5cGUoSUNvbnRlbnRUeXBlTWFuYWdlci5DVF9URVhUKTsKCQkJYXNzZXJ0Tm90TnVsbCgiMy4yIiwgdGV4dFsyXSk7CgkJCXRleHRbMl0gPSAoKENvbnRlbnRUeXBlSGFuZGxlcikgdGV4dFsyXSkuZ2V0VGFyZ2V0KCk7CgkJCWFzc2VydEVxdWFscygiMy4zIiwgdGV4dFswXSwgdGV4dFsyXSk7CgkJCWFzc2VydFRydWUoIjMuNCIsIHRleHRbMF0gIT0gdGV4dFsyXSk7CgkJfSwgZ2V0Q29udGV4dCgpLCBuZXcgU3RyaW5nW10ge0NvbnRlbnRUeXBlVGVzdC5URVNUX0ZJTEVTX1JPT1QgKyAiY29udGVudC9idW5kbGUwMSJ9LCBsaXN0ZW5lcik7CgkJYXNzZXJ0TnVsbCgiNC4wIiwgbWFuYWdlci5nZXRDb250ZW50VHlwZSgib3JnLmVjbGlwc2UuYnVuZGxlMDEubWlzc2luZyIpKTsKCQkvLyBlbnN1cmUgdGhlIGNvbnRlbnQgdHlwZSBpbnN0YW5jZXMgYXJlIGFsbCBkaWZmZXJlbnQKCQl0ZXh0WzNdID0gbWFuYWdlci5nZXRDb250ZW50VHlwZShJQ29udGVudFR5cGVNYW5hZ2VyLkNUX1RFWFQpOwoJCWFzc2VydE5vdE51bGwoIjUuMCIsIHRleHRbM10pOwoJCXRleHRbM10gPSAoKENvbnRlbnRUeXBlSGFuZGxlcikgdGV4dFszXSkuZ2V0VGFyZ2V0KCk7CgkJYXNzZXJ0RXF1YWxzKCI1LjEiLCB0ZXh0WzBdLCB0ZXh0WzNdKTsKCQlhc3NlcnRFcXVhbHMoIjUuMiIsIHRleHRbMl0sIHRleHRbM10pOwoJCWFzc2VydFRydWUoIjUuMyIsIHRleHRbMF0gIT0gdGV4dFszXSk7CgkJYXNzZXJ0VHJ1ZSgiNS40IiwgdGV4dFsyXSAhPSB0ZXh0WzNdKTsKCX0KCgkvKioKCSAqIFNpbWlsYXIgdG8gdGVzdER5bmFtaWNDaGFuZ2VzLCBidXQgdXNpbmcgdGhlIG9yZy5lY2xpcHNlLmNvcmUuY29udGVudHR5cGUuY29udGVudFR5cGVzIGV4dGVuc2lvbiBwb2ludC4KCSAqLwoJcHVibGljIHZvaWQgdGVzdER5bmFtaWNDaGFuZ2VzTmV3RXh0ZW5zaW9uKCkgewoJCWZpbmFsIElDb250ZW50VHlwZVtdIHRleHQgPSBuZXcgSUNvbnRlbnRUeXBlWzRdOwoJCWZpbmFsIElDb250ZW50VHlwZU1hbmFnZXIgbWFuYWdlciA9IFBsYXRmb3JtLmdldENvbnRlbnRUeXBlTWFuYWdlcigpOwoJCXRleHRbMF0gPSBtYW5hZ2VyLmdldENvbnRlbnRUeXBlKElDb250ZW50VHlwZU1hbmFnZXIuQ1RfVEVYVCk7CgkJYXNzZXJ0Tm90TnVsbCgiMS4wIiwgdGV4dFswXSk7CgkJdGV4dFsxXSA9IG1hbmFnZXIuZ2V0Q29udGVudFR5cGUoSUNvbnRlbnRUeXBlTWFuYWdlci5DVF9URVhUKTsKCQlhc3NlcnROb3ROdWxsKCIxLjEiLCB0ZXh0WzFdKTsKCQl0ZXh0WzBdID0gKChDb250ZW50VHlwZUhhbmRsZXIpIHRleHRbMF0pLmdldFRhcmdldCgpOwoJCXRleHRbMV0gPSAoKENvbnRlbnRUeXBlSGFuZGxlcikgdGV4dFsxXSkuZ2V0VGFyZ2V0KCk7CgkJYXNzZXJ0RXF1YWxzKCIyLjAiLCB0ZXh0WzBdLCB0ZXh0WzFdKTsKCQlhc3NlcnRUcnVlKCIyLjEiLCB0ZXh0WzBdID09IHRleHRbMV0pOwoJCS8vCW1ha2UgYXJiaXRyYXJ5IGR5bmFtaWMgY2hhbmdlcyB0byB0aGUgY29udGVudFR5cGVzIGV4dGVuc2lvbiBwb2ludAoJCVRlc3RSZWdpc3RyeUNoYW5nZUxpc3RlbmVyIGxpc3RlbmVyID0gbmV3IFRlc3RSZWdpc3RyeUNoYW5nZUxpc3RlbmVyKElDb250ZW50Q29uc3RhbnRzLkNPTlRFTlRfTkFNRSwgQ29udGVudFR5cGVCdWlsZGVyLlBUX0NPTlRFTlRUWVBFUywgbnVsbCwgbnVsbCk7CgkJQnVuZGxlVGVzdGluZ0hlbHBlci5ydW5XaXRoQnVuZGxlcygiMyIsICgpIC0+IHsKCQkJSUNvbnRlbnRUeXBlIGNvbnRlbnRUeXBlID0gbWFuYWdlci5nZXRDb250ZW50VHlwZSgib3JnLmVjbGlwc2UuYnVnNDg1MjI3LmJ1ZzQ4NTIyN19jb250ZW50VHlwZSIpOwoJCQlhc3NlcnROb3ROdWxsKCIzLjEgQ29udHJpYnV0ZWQgY29udGVudCB0eXBlIG5vdCBmb3VuZCIsIGNvbnRlbnRUeXBlKTsKCQkJLy8gZW5zdXJlIHRoZSBjb250ZW50IHR5cGUgaW5zdGFuY2VzIGFyZSBkaWZmZXJlbnQKCQkJdGV4dFsyXSA9IG1hbmFnZXIuZ2V0Q29udGVudFR5cGUoSUNvbnRlbnRUeXBlTWFuYWdlci5DVF9URVhUKTsKCQkJYXNzZXJ0Tm90TnVsbCgiMy4yIFRleHQgY29udGVudCB0eXBlIG5vdCBtb2RpZmllZCIsIHRleHRbMl0pOwoJCQl0ZXh0WzJdID0gKChDb250ZW50VHlwZUhhbmRsZXIpIHRleHRbMl0pLmdldFRhcmdldCgpOwoJCQlhc3NlcnRFcXVhbHMoIjMuMyIsIHRleHRbMF0sIHRleHRbMl0pOwoJCQlhc3NlcnRUcnVlKCIzLjQiLCB0ZXh0WzBdICE9IHRleHRbMl0pOwoJCQlhc3NlcnRFcXVhbHMoIjMuNSBkZWZhdWx0IGV4dGVuc2lvbiBub3QgYXNzb2NpYXRlZCIsIGNvbnRlbnRUeXBlLCBtYW5hZ2VyLmZpbmRDb250ZW50VHlwZUZvcigiZmlsZS5idWc0ODUyMjciKSk7CgkJCWFzc2VydEVxdWFscygiMy42IGFkZGl0aW9uYWwgZXh0ZW5zaW9uIG5vdCBhc3NvY2lhdGVkIiwgY29udGVudFR5cGUsIG1hbmFnZXIuZmluZENvbnRlbnRUeXBlRm9yKCJmaWxlLmJ1ZzQ4NTIyN18yIikpOwoJCX0sIGdldENvbnRleHQoKSwgbmV3IFN0cmluZ1tdIHtDb250ZW50VHlwZVRlc3QuVEVTVF9GSUxFU19ST09UICsgImNvbnRlbnQvYnVnNDg1MjI3In0sIGxpc3RlbmVyKTsKCQlhc3NlcnROdWxsKCI0LjAgQ29udGVudCB0eXBlIG5vdCBjbGVhcmVkIGFmdGVyIGJ1bmRsZSB1bmluc3RhbGwiLCBtYW5hZ2VyLmdldENvbnRlbnRUeXBlKCJvcmcuZWNsaXBzZS5idWc0ODUyMjcuYnVnNDg1MjI3X2NvbnRlbnRUeXBlIikpOwoJCS8vIGVuc3VyZSB0aGUgY29udGVudCB0eXBlIGluc3RhbmNlcyBhcmUgYWxsIGRpZmZlcmVudAoJCXRleHRbM10gPSBtYW5hZ2VyLmdldENvbnRlbnRUeXBlKElDb250ZW50VHlwZU1hbmFnZXIuQ1RfVEVYVCk7CgkJYXNzZXJ0Tm90TnVsbCgiNS4wIiwgdGV4dFszXSk7CgkJdGV4dFszXSA9ICgoQ29udGVudFR5cGVIYW5kbGVyKSB0ZXh0WzNdKS5nZXRUYXJnZXQoKTsKCQlhc3NlcnRFcXVhbHMoIjUuMSIsIHRleHRbMF0sIHRleHRbM10pOwoJCWFzc2VydEVxdWFscygiNS4yIiwgdGV4dFsyXSwgdGV4dFszXSk7CgkJYXNzZXJ0VHJ1ZSgiNS4zIiwgdGV4dFswXSAhPSB0ZXh0WzNdKTsKCQlhc3NlcnRUcnVlKCI1LjQiLCB0ZXh0WzJdICE9IHRleHRbM10pOwoJfQoKCXB1YmxpYyB2b2lkIHRlc3RFdmVudHMoKSB7CgkJSUNvbnRlbnRUeXBlTWFuYWdlciBjb250ZW50VHlwZU1hbmFnZXIgPSBQbGF0Zm9ybS5nZXRDb250ZW50VHlwZU1hbmFnZXIoKTsKCQlJQ29udGVudFR5cGUgbXlUeXBlID0gY29udGVudFR5cGVNYW5hZ2VyLmdldENvbnRlbnRUeXBlKFBJX1JFU09VUkNFU19URVNUUyArICIubXlDb250ZW50Iik7CgkJYXNzZXJ0Tm90TnVsbCgiMC45IiwgbXlUeXBlKTsKCgkJQ29udGVudFR5cGVDaGFuZ2VUcmFjZXIgdHJhY2VyOwoKCQl0cmFjZXIgPSBuZXcgQ29udGVudFR5cGVDaGFuZ2VUcmFjZXIoKTsKCQljb250ZW50VHlwZU1hbmFnZXIuYWRkQ29udGVudFR5cGVDaGFuZ2VMaXN0ZW5lcih0cmFjZXIpOwoKCQkvLyBhZGQgYSBmaWxlIHNwZWMgYW5kIGNoZWNrIGV2ZW50CgkJdHJ5IHsKCQkJbXlUeXBlLmFkZEZpbGVTcGVjKCJhbm90aGVyLmZpbGUubmFtZSIsIElDb250ZW50VHlwZS5GSUxFX05BTUVfU1BFQyk7CgkJfSBjYXRjaCAoQ29yZUV4Y2VwdGlvbiBlKSB7CgkJCWZhaWwoIjEuMCIsIGUpOwoJCX0KCQlhc3NlcnRUcnVlKCIxLjEiLCB0cmFjZXIuaXNPbmx5Q2hhbmdlKG15VHlwZSkpOwoKCQkvLyByZW1vdmUgYSBub24tZXhpc3RpbmcgZmlsZSBzcGVjIC0gc2hvdWxkIG5vdCBjYXVzZSBhbiBldmVudCB0byBiZSBmaXJlZAoJCXRyYWNlci5yZXNldCgpOwoJCXRyeSB7CgkJCW15VHlwZS5yZW1vdmVGaWxlU3BlYygiYW5vdGhlci5maWxlLm5hbWUiLCBJQ29udGVudFR5cGUuRklMRV9FWFRFTlNJT05fU1BFQyk7CgkJfSBjYXRjaCAoQ29yZUV4Y2VwdGlvbiBlKSB7CgkJCWZhaWwoIjIuMCIsIGUpOwoJCX0KCQlhc3NlcnRUcnVlKCIyLjEiLCAhdHJhY2VyLmlzT25seUNoYW5nZShteVR5cGUpKTsKCgkJLy8gYWRkIGEgZmlsZSBzcGVjIGFnYWluIGFuZCBjaGVjayBubyBldmVudCBpcyBnZW5lcmF0ZWQKCQl0cmFjZXIucmVzZXQoKTsKCQl0cnkgewoJCQlteVR5cGUuYWRkRmlsZVNwZWMoImFub3RoZXIuZmlsZS5uYW1lIiwgSUNvbnRlbnRUeXBlLkZJTEVfTkFNRV9TUEVDKTsKCQl9IGNhdGNoIChDb3JlRXhjZXB0aW9uIGUpIHsKCQkJZmFpbCgiMy4wIiwgZSk7CgkJfQoJCWFzc2VydFRydWUoIjMuMSIsICF0cmFjZXIuaXNPbmx5Q2hhbmdlKG15VHlwZSkpOwoKCQkvLyByZW1vdmUgYSBmaWxlIHNwZWMgYW5kIGNoZWNrIGV2ZW50CgkJdHJhY2VyLnJlc2V0KCk7CgkJdHJ5IHsKCQkJbXlUeXBlLnJlbW92ZUZpbGVTcGVjKCJhbm90aGVyLmZpbGUubmFtZSIsIElDb250ZW50VHlwZS5GSUxFX05BTUVfU1BFQyk7CgkJfSBjYXRjaCAoQ29yZUV4Y2VwdGlvbiBlKSB7CgkJCWZhaWwoIjQuMCIsIGUpOwoJCX0KCQlhc3NlcnRUcnVlKCI0LjEiLCB0cmFjZXIuaXNPbmx5Q2hhbmdlKG15VHlwZSkpOwoKCQkvLyBjaGFuZ2UgdGhlIGRlZmF1bHQgY2hhcnNldCBhbmQgY2hlY2sgZXZlbnQKCQl0cmFjZXIucmVzZXQoKTsKCQl0cnkgewoJCQlteVR5cGUuc2V0RGVmYXVsdENoYXJzZXQoIkZPTyIpOwoJCX0gY2F0Y2ggKENvcmVFeGNlcHRpb24gZSkgewoJCQlmYWlsKCI1LjAiLCBlKTsKCQl9CgkJYXNzZXJ0VHJ1ZSgiNS4xIiwgdHJhY2VyLmlzT25seUNoYW5nZShteVR5cGUpKTsKCgkJLy8gc2V0IHRoZSBkZWZhdWx0IGNoYXJzZXQgdG8gdGhlIHNhbWUgLSBubyBldmVudCBzaG91bGQgYmUgZ2VuZXJhdGVkCgkJdHJhY2VyLnJlc2V0KCk7CgkJdHJ5IHsKCQkJbXlUeXBlLnNldERlZmF1bHRDaGFyc2V0KCJGT08iKTsKCQl9IGNhdGNoIChDb3JlRXhjZXB0aW9uIGUpIHsKCQkJZmFpbCgiNi4wIiwgZSk7CgkJfQoJCWFzc2VydFRydWUoIjYuMSIsICF0cmFjZXIuaXNPbmx5Q2hhbmdlKG15VHlwZSkpOwoKCQl0cnkgewoJCQlteVR5cGUuc2V0RGVmYXVsdENoYXJzZXQoIkFCQyIpOwoJCX0gY2F0Y2ggKENvcmVFeGNlcHRpb24gZTEpIHsKCQkJZmFpbCgiNy4wIiwgZTEpOwoJCX0KCX0KCglwdWJsaWMgdm9pZCB0ZXN0RmlsZVNwZWNDb25mbGljdHMoKSB7CgkJSUNvbnRlbnRUeXBlTWFuYWdlciBtYW5hZ2VyID0gUGxhdGZvcm0uZ2V0Q29udGVudFR5cGVNYW5hZ2VyKCk7CgkJLy8gd2hlbiBub3Qgc3VibWl0dGluZyBjb250ZW50cywgZm9yIHJlbGF0ZWQgdHlwZXMsIG1vc3QgZ2VuZXJhbCB0eXBlIHByZXZhaWxzCgkJSUNvbnRlbnRUeXBlIGNvbmZsaWN0MWEgPSBtYW5hZ2VyLmdldENvbnRlbnRUeXBlKFBJX1JFU09VUkNFU19URVNUUyArICIuYmFzZV9jb25mbGljdDEiKTsKCQlJQ29udGVudFR5cGUgY29uZmxpY3QxYiA9IG1hbmFnZXIuZ2V0Q29udGVudFR5cGUoUElfUkVTT1VSQ0VTX1RFU1RTICsgIi5zdWJfY29uZmxpY3QxIik7CgkJYXNzZXJ0Tm90TnVsbCgiMS4wIiwgY29uZmxpY3QxYSk7CgkJYXNzZXJ0Tm90TnVsbCgiMS4xIiwgY29uZmxpY3QxYik7CgkJSUNvbnRlbnRUeXBlIHByZWZlcnJlZENvbmZsaWN0MSA9IG1hbmFnZXIuZmluZENvbnRlbnRUeXBlRm9yKCJ0ZXN0LmNvbmZsaWN0MSIpOwoJCWFzc2VydE5vdE51bGwoIjEuMiIsIHByZWZlcnJlZENvbmZsaWN0MSk7CgkJYXNzZXJ0RXF1YWxzKCIxLjMiLCBjb25mbGljdDFhLCBwcmVmZXJyZWRDb25mbGljdDEpOwoKCQlJQ29udGVudFR5cGUgY29uZmxpY3QyYmFzZSA9IG1hbmFnZXIuZ2V0Q29udGVudFR5cGUoUElfUkVTT1VSQ0VTX1RFU1RTICsgIi5iYXNlX2NvbmZsaWN0MiIpOwoJCUlDb250ZW50VHlwZSBjb25mbGljdDJzdWIgPSBtYW5hZ2VyLmdldENvbnRlbnRUeXBlKFBJX1JFU09VUkNFU19URVNUUyArICIuc3ViX2NvbmZsaWN0MiIpOwoJCWFzc2VydE5vdE51bGwoIjIuMCIsIGNvbmZsaWN0MmJhc2UpOwoJCWFzc2VydE5vdE51bGwoIjIuMSIsIGNvbmZsaWN0MnN1Yik7CgkJLy8gd2hlbiBzdWJtaXR0aW5nIGNvbnRlbnRzLCBmb3IgcmVsYXRlZCB0eXBlcywgZGVzY2VuZGFudCBjb21lcyBmaXJzdAoJCUlDb250ZW50VHlwZVtdIHNlbGVjdGVkQ29uZmxpY3QyOwoJCXRyeSB7CgkJCXNlbGVjdGVkQ29uZmxpY3QyID0gbWFuYWdlci5maW5kQ29udGVudFR5cGVzRm9yKGdldFJhbmRvbUNvbnRlbnRzKCksICJ0ZXN0LmNvbmZsaWN0MiIpOwoJCQlhc3NlcnRFcXVhbHMoIjIuMiIsIDIsIHNlbGVjdGVkQ29uZmxpY3QyLmxlbmd0aCk7CgkJCWFzc2VydEVxdWFscygiMi4zIiwgc2VsZWN0ZWRDb25mbGljdDJbMF0sIGNvbmZsaWN0MmJhc2UpOwoJCQlhc3NlcnRFcXVhbHMoIjIuNCIsIHNlbGVjdGVkQ29uZmxpY3QyWzFdLCBjb25mbGljdDJzdWIpOwoJCX0gY2F0Y2ggKElPRXhjZXB0aW9uIGUpIHsKCQkJZmFpbCgiMi41IiwgZSk7CgkJfQoKCQlJQ29udGVudFR5cGUgY29uZmxpY3QzYmFzZSA9IG1hbmFnZXIuZ2V0Q29udGVudFR5cGUoUElfUkVTT1VSQ0VTX1RFU1RTICsgIi5iYXNlX2NvbmZsaWN0MyIpOwoJCUlDb250ZW50VHlwZSBjb25mbGljdDNzdWIgPSBtYW5hZ2VyLmdldENvbnRlbnRUeXBlKFBJX1JFU09VUkNFU19URVNUUyArICIuc3ViX2NvbmZsaWN0MyIpOwoJCUlDb250ZW50VHlwZSBjb25mbGljdDN1bnJlbGF0ZWQgPSBtYW5hZ2VyLmdldENvbnRlbnRUeXBlKFBJX1JFU09VUkNFU19URVNUUyArICIudW5yZWxhdGVkX2NvbmZsaWN0MyIpOwoJCWFzc2VydE5vdE51bGwoIjMuMC4xIiwgY29uZmxpY3QzYmFzZSk7CgkJYXNzZXJ0Tm90TnVsbCgiMy4wLjIiLCBjb25mbGljdDNzdWIpOwoJCWFzc2VydE5vdE51bGwoIjMuMC4zIiwgY29uZmxpY3QzdW5yZWxhdGVkKTsKCgkJLy8gVHdvIHVucmVsYXRlZCB0eXBlcyAoc3ViX2NvbmZsaWN0MyBhbmQgdW5yZWxhdGVkIGNvbmZsaWN0MykgYXJlIGluIGNvbmZsaWN0LgoJCS8vIE9yZGVyIHdpbGwgYmUgYmFzZWQgb24gZGVwdGggKG1vcmUgZ2VuZXJhbCBmaXJzdCBzaW5jZSB0aGV5IGRvbid0IGhhdmUgZGVzY3JpYmVycykKCgkJSUNvbnRlbnRUeXBlW10gc2VsZWN0ZWRDb25mbGljdDM7CgkJdHJ5IHsKCQkJc2VsZWN0ZWRDb25mbGljdDMgPSBtYW5hZ2VyLmZpbmRDb250ZW50VHlwZXNGb3IoZ2V0UmFuZG9tQ29udGVudHMoKSwgInRlc3QuY29uZmxpY3QzIik7CgkJCWFzc2VydEVxdWFscygiNC4wIiwgMiwgc2VsZWN0ZWRDb25mbGljdDMubGVuZ3RoKTsKCQkJYXNzZXJ0RXF1YWxzKCI0LjEiLCBzZWxlY3RlZENvbmZsaWN0M1swXSwgY29uZmxpY3QzdW5yZWxhdGVkKTsKCQkJYXNzZXJ0RXF1YWxzKCI0LjIiLCBzZWxlY3RlZENvbmZsaWN0M1sxXSwgY29uZmxpY3Qzc3ViKTsKCQl9IGNhdGNoIChJT0V4Y2VwdGlvbiBlKSB7CgkJCWZhaWwoIjQuMyIsIGUpOwoJCX0KCX0KCglwdWJsaWMgdm9pZCB0ZXN0RmluZENvbnRlbnRUeXBlKCkgdGhyb3dzIFVuc3VwcG9ydGVkRW5jb2RpbmdFeGNlcHRpb24sIElPRXhjZXB0aW9uIHsKCQlJQ29udGVudFR5cGVNYW5hZ2VyIGNvbnRlbnRUeXBlTWFuYWdlciA9IFBsYXRmb3JtLmdldENvbnRlbnRUeXBlTWFuYWdlcigpOwoJCUlDb250ZW50VHlwZU1hdGNoZXIgZmluZGVyID0gY29udGVudFR5cGVNYW5hZ2VyLmdldE1hdGNoZXIobmV3IExvY2FsU2VsZWN0aW9uUG9saWN5KCksIG51bGwpOwoKCQlJQ29udGVudFR5cGUgdGV4dENvbnRlbnRUeXBlID0gY29udGVudFR5cGVNYW5hZ2VyLmdldENvbnRlbnRUeXBlKFBsYXRmb3JtLlBJX1JVTlRJTUUgKyAnLicgKyAidGV4dCIpOwoJCUlDb250ZW50VHlwZSB4bWxDb250ZW50VHlwZSA9IGNvbnRlbnRUeXBlTWFuYWdlci5nZXRDb250ZW50VHlwZShQbGF0Zm9ybS5QSV9SVU5USU1FICsgIi54bWwiKTsKCgkJSUNvbnRlbnRUeXBlIHNpbmdsZTsKCgkJc2luZ2xlID0gZmluZGVyLmZpbmRDb250ZW50VHlwZUZvcihnZXRJbnB1dFN0cmVhbSgiSnVzdCBhIHRlc3QiKSwgY2hhbmdlQ2FzZSgiZmlsZS50eHQiKSk7CgkJYXNzZXJ0Tm90TnVsbCgiMS4wIiwgc2luZ2xlKTsKCQlhc3NlcnRFcXVhbHMoIjEuMSIsIHRleHRDb250ZW50VHlwZSwgc2luZ2xlKTsKCgkJc2luZ2xlID0gZmluZGVyLmZpbmRDb250ZW50VHlwZUZvcihnZXRJbnB1dFN0cmVhbShYTUxfVVRGXzgsICJVVEYtOCIpLCBjaGFuZ2VDYXNlKCJmb28ueG1sIikpOwoJCWFzc2VydE5vdE51bGwoIjIuMCIsIHNpbmdsZSk7CgkJYXNzZXJ0RXF1YWxzKCIyLjEiLCB4bWxDb250ZW50VHlwZSwgc2luZ2xlKTsKCgkJSUNvbnRlbnRUeXBlW10gbXVsdGlwbGUgPSBmaW5kZXIuZmluZENvbnRlbnRUeXBlc0ZvcihnZXRJbnB1dFN0cmVhbShYTUxfVVRGXzgsICJVVEYtOCIpLCBudWxsKTsKCQlhc3NlcnRUcnVlKCIzLjAiLCBjb250YWlucyhtdWx0aXBsZSwgeG1sQ29udGVudFR5cGUpKTsKCX0KCglwdWJsaWMgdm9pZCB0ZXN0SW1wb3J0RmlsZUFzc29jaWF0aW9uKCkgdGhyb3dzIENvcmVFeGNlcHRpb24gewoJCUlDb250ZW50VHlwZU1hbmFnZXIgY29udGVudFR5cGVNYW5hZ2VyID0gUGxhdGZvcm0uZ2V0Q29udGVudFR5cGVNYW5hZ2VyKCk7CgkJYXNzZXJ0TnVsbChjb250ZW50VHlwZU1hbmFnZXIuZmluZENvbnRlbnRUeXBlRm9yKCIqLmJ1ZzEyMjIxNyIpKTsKCQlJUHJlZmVyZW5jZXNTZXJ2aWNlIHNlcnZpY2UgPSBQbGF0Zm9ybS5nZXRQcmVmZXJlbmNlc1NlcnZpY2UoKTsKCQlTdHJpbmcgcHJlZnMgPSAiZmlsZV9leHBvcnRfdmVyc2lvbj0zLjBcbi9pbnN0YW5jZS9vcmcuZWNsaXBzZS5jb3JlLnJ1bnRpbWUvY29udGVudC10eXBlcy9vcmcuZWNsaXBzZS5jb3JlLnJ1bnRpbWUueG1sL2ZpbGUtZXh0ZW5zaW9ucz1idWcxMjIyMTciOwoJCUlFeHBvcnRlZFByZWZlcmVuY2VzIGV4cG9ydGVkID0gc2VydmljZS5yZWFkUHJlZmVyZW5jZXMobmV3IEJ5dGVBcnJheUlucHV0U3RyZWFtKHByZWZzLmdldEJ5dGVzKCkpKTsKCQlhc3NlcnRUcnVlKHNlcnZpY2UuYXBwbHlQcmVmZXJlbmNlcyhleHBvcnRlZCkuaXNPSygpKTsKCQlhc3NlcnROb3ROdWxsKGNvbnRlbnRUeXBlTWFuYWdlci5maW5kQ29udGVudFR5cGVGb3IoIiouYnVnMTIyMjE3IikpOwoJfQoKCXB1YmxpYyB2b2lkIHRlc3RJbnZhbGlkTWFya3VwKCkgewoJCWZpbmFsIElDb250ZW50VHlwZU1hbmFnZXIgY29udGVudFR5cGVNYW5hZ2VyID0gUGxhdGZvcm0uZ2V0Q29udGVudFR5cGVNYW5hZ2VyKCk7CgkJSUNvbnRlbnRUeXBlTWF0Y2hlciBmaW5kZXIgPSBjb250ZW50VHlwZU1hbmFnZXIuZ2V0TWF0Y2hlcihuZXcgTG9jYWxTZWxlY3Rpb25Qb2xpY3koKSwgbnVsbCk7CgkJYXNzZXJ0RXF1YWxzKCIxLjAiLCAwLCBmaW5kZXIuZmluZENvbnRlbnRUeXBlc0ZvcigiaW52YWxpZC5taXNzaW5nLmlkZW50aWZpZXIiKS5sZW5ndGgpOwoJCWFzc2VydEVxdWFscygiMi4wIiwgMCwgZmluZGVyLmZpbmRDb250ZW50VHlwZXNGb3IoImludmFsaWQubWlzc2luZy5uYW1lIikubGVuZ3RoKTsKCQlhc3NlcnROdWxsKCIzLjAiLCBjb250ZW50VHlwZU1hbmFnZXIuZ2V0Q29udGVudFR5cGUoUElfUkVTT1VSQ0VTX1RFU1RTICsgJy4nICsgImludmFsaWQtbWlzc2luZy1uYW1lIikpOwoJCVRlc3RSZWdpc3RyeUNoYW5nZUxpc3RlbmVyIGxpc3RlbmVyID0gbmV3IFRlc3RSZWdpc3RyeUNoYW5nZUxpc3RlbmVyKFBsYXRmb3JtLlBJX1JVTlRJTUUsIENvbnRlbnRUeXBlQnVpbGRlci5QVF9DT05URU5UVFlQRVMsIG51bGwsIG51bGwpOwoJCUJ1bmRsZVRlc3RpbmdIZWxwZXIucnVuV2l0aEJ1bmRsZXMoIjEiLCAoKSAtPiB7CgkJCS8vIGVuc3VyZSB0aGUgaW52YWxpZCBjb250ZW50IHR5cGVzIGFyZSBub3QgYXZhaWxhYmxlCgkJCWFzc2VydEVxdWFscygiMS4yIiwgMCwgY29udGVudFR5cGVNYW5hZ2VyLmZpbmRDb250ZW50VHlwZXNGb3IoImludmFsaWQubWlzc2luZy5pZGVudGlmaWVyIikubGVuZ3RoKTsKCQkJYXNzZXJ0RXF1YWxzKCIxLjMiLCAwLCBjb250ZW50VHlwZU1hbmFnZXIuZmluZENvbnRlbnRUeXBlc0ZvcigiaW52YWxpZC5taXNzaW5nLm5hbWUiKS5sZW5ndGgpOwoJCQlhc3NlcnROdWxsKCIxLjQiLCBjb250ZW50VHlwZU1hbmFnZXIuZ2V0Q29udGVudFR5cGUoIm9yZy5lY2xpcHNlLmJ1bmRsZTAzLmludmFsaWQtbWlzc2luZy1uYW1lIikpOwoJCQkvLyB0aGlzIGNvbnRlbnQgdHlwZSBoYXMgZ29vZCBtYXJrdXAsIGJ1dCBpbnZhbGlkIGRlc2NyaWJlciBjbGFzcwoJCQlJQ29udGVudFR5cGUgaW52YWxpZERlc2NyaWJlciA9IGNvbnRlbnRUeXBlTWFuYWdlci5nZXRDb250ZW50VHlwZSgib3JnLmVjbGlwc2UuYnVuZGxlMDMuaW52YWxpZC1kZXNjcmliZXIiKTsKCQkJYXNzZXJ0Tm90TnVsbCgiMS41IiwgaW52YWxpZERlc2NyaWJlcik7CgkJCS8vIG5hbWUgYmFzZWQgbWF0Y2hpbmcgc2hvdWxkIHdvcmsgZmluZQoJCQlhc3NlcnRFcXVhbHMoIjEuNiIsIGludmFsaWREZXNjcmliZXIsIGNvbnRlbnRUeXBlTWFuYWdlci5maW5kQ29udGVudFR5cGVGb3IoImludmFsaWQuZGVzY3JpYmVyIikpOwoJCQl0cnkgewoJCQkJLy8gdGhlIGRlc2NyaWJlciBjbGFzcyBpcyBpbnZhbGlkLCBjb250ZW50IG1hdGNob25nIHNob3VsZCBmYWlsCgkJCQlhc3NlcnROdWxsKCIxLjciLCBjb250ZW50VHlwZU1hbmFnZXIuZmluZENvbnRlbnRUeXBlRm9yKGdldFJhbmRvbUNvbnRlbnRzKCksICJpbnZhbGlkLmRlc2NyaWJlciIpKTsKCQkJfSBjYXRjaCAoSU9FeGNlcHRpb24gZSkgewoJCQkJZmFpbCgiMS44IiwgZSk7CgkJCX0KCQl9LCBnZXRDb250ZXh0KCksIG5ldyBTdHJpbmdbXSB7Q29udGVudFR5cGVUZXN0LlRFU1RfRklMRVNfUk9PVCArICJjb250ZW50L2J1bmRsZTAzIn0sIGxpc3RlbmVyKTsKCX0KCgkvKioKCSAqIEJ1Z3MgNjc4NDEgYW5kIDYyNDQzCgkgKi8KCXB1YmxpYyB2b2lkIHRlc3RJT0V4Y2VwdGlvbigpIHsKCQlJQ29udGVudFR5cGVNYW5hZ2VyIG1hbmFnZXIgPSBQbGF0Zm9ybS5nZXRDb250ZW50VHlwZU1hbmFnZXIoKTsKCQlJQ29udGVudFR5cGUgeG1sID0gbWFuYWdlci5nZXRDb250ZW50VHlwZShQbGF0Zm9ybS5QSV9SVU5USU1FICsgIi54bWwiKTsKCQlJQ29udGVudFR5cGUgcm9vdEVsZW1lbnQgPSBtYW5hZ2VyLmdldENvbnRlbnRUeXBlKFBJX1JFU09VUkNFU19URVNUUyArICIucm9vdC1lbGVtZW50Iik7CgkJSUNvbnRlbnRUeXBlW10gc2VsZWN0ZWQgPSBudWxsOwoJCXRyeSB7CgkJCXNlbGVjdGVkID0gbWFuYWdlci5maW5kQ29udGVudFR5cGVzRm9yKGdldElucHV0U3RyZWFtKFhNTF9VU19BU0NJSV9JTlZBTElELCAiSVNPLTg4NTktMSIpLCAidGVzdC54bWwiKTsKCQl9IGNhdGNoIChJT0V4Y2VwdGlvbiBpb2UpIHsKCQkJLy8gYSBTQVhFeGNlcHRpb24gaXMgdXN1YWxseSBjYXVnaHQgKGFuZCBzaWxlbnRseSBpZ25vcmVkKSBpbiBYTUxSb290RWxlbWVudERlc2NyaWJlciBpbiB0aGVzZSBjYXNlcwoJCQlmYWlsKCIxLjAiLCBpb2UpOwoJCX0KCQlhc3NlcnRUcnVlKCIxLjEiLCBjb250YWlucyhzZWxlY3RlZCwgeG1sKSk7CgkJYXNzZXJ0VHJ1ZSgiMS4yIiwgY29udGFpbnMoc2VsZWN0ZWQsIHJvb3RFbGVtZW50KSk7CgoJCS8vIGluZHVjZSByZWd1bGFyIElPRXhjZXB0aW9ucy4uLiB0aGVzZSBzaG91bGQgYmUgdGhyb3duIHRvIGNsaWVudHMKCQljbGFzcyBGYWtlSU9FeGNlcHRpb24gZXh0ZW5kcyBJT0V4Y2VwdGlvbiB7CgkJCS8qKgoJCQkgKiBBbGwgc2VyaWFsaXphYmxlIG9iamVjdHMgc2hvdWxkIGhhdmUgYSBzdGFibGUgc2VyaWFsVmVyc2lvblVJRAoJCQkgKi8KCQkJcHJpdmF0ZSBzdGF0aWMgZmluYWwgbG9uZyBzZXJpYWxWZXJzaW9uVUlEID0gMUw7CgoJCQlAT3ZlcnJpZGUKCQkJcHVibGljIFN0cmluZyBnZXRNZXNzYWdlKCkgewoJCQkJcmV0dXJuICJUaGlzIGV4Y2VwdGlvbiB3YXMgdGhyb3duIGZvciB0ZXN0aW5nIHB1cnBvc2VzIjsKCQkJfQoJCX0KCQl0cnkgewoJCQlzZWxlY3RlZCA9IG1hbmFnZXIuZmluZENvbnRlbnRUeXBlc0ZvcihuZXcgSW5wdXRTdHJlYW0oKSB7CgoJCQkJQE92ZXJyaWRlCgkJCQlwdWJsaWMgaW50IGF2YWlsYWJsZSgpIHsKCQkJCQkvLyB0cmljayB0aGUgY2xpZW50IGludG8gcmVhZGluZyB0aGUgZmlsZQoJCQkJCXJldHVybiBJbnRlZ2VyLk1BWF9WQUxVRTsKCQkJCX0KCgkJCQlAT3ZlcnJpZGUKCQkJCXB1YmxpYyBpbnQgcmVhZCgpIHRocm93cyBJT0V4Y2VwdGlvbiB7CgkJCQkJdGhyb3cgbmV3IEZha2VJT0V4Y2VwdGlvbigpOwoJCQkJfQoKCQkJCUBPdmVycmlkZQoJCQkJcHVibGljIGludCByZWFkKGJ5dGVbXSBiLCBpbnQgb2ZmLCBpbnQgbGVuKSB0aHJvd3MgSU9FeGNlcHRpb24gewoJCQkJCXRocm93IG5ldyBGYWtlSU9FeGNlcHRpb24oKTsKCQkJCX0KCQkJfSwgInRlc3QueG1sIik7CgkJCS8vIGFuIGV4Y2VwdGlvbiB3aWxsIGhhcHBlbiB3aGVuIHJlYWRpbmcgdGhlIHN0cmVhbS4uLiBzaG91bGQgYmUgdGhyb3duIHRvIHRoZSBjYWxsZXIKCQkJZmFpbCgiMi4wIik7CgkJfSBjYXRjaCAoRmFrZUlPRXhjZXB0aW9uIGZpb2UpIHsKCQkJLy8gc3VjZXNzCgkJfSBjYXRjaCAoSU9FeGNlcHRpb24gaW9lKSB7CgkJCS8vIHRoaXMgc2hvdWxkIG5ldmVyIGhhcHBlbiwgYnV0IGp1c3QgaW4gY2FzZS4uLgoJCQlmYWlsKCIyLjEiKTsKCQl9Cgl9CgoJcHVibGljIHZvaWQgdGVzdElzS2luZE9mKCkgewoJCUlDb250ZW50VHlwZU1hbmFnZXIgY29udGVudFR5cGVNYW5hZ2VyID0gUGxhdGZvcm0uZ2V0Q29udGVudFR5cGVNYW5hZ2VyKCk7CgkJSUNvbnRlbnRUeXBlIHRleHRDb250ZW50VHlwZSA9IGNvbnRlbnRUeXBlTWFuYWdlci5nZXRDb250ZW50VHlwZShQbGF0Zm9ybS5QSV9SVU5USU1FICsgJy4nICsgInRleHQiKTsKCQlJQ29udGVudFR5cGUgeG1sQ29udGVudFR5cGUgPSBjb250ZW50VHlwZU1hbmFnZXIuZ2V0Q29udGVudFR5cGUoUGxhdGZvcm0uUElfUlVOVElNRSArICIueG1sIik7CgkJSUNvbnRlbnRUeXBlIHhtbEJhc2VkRGlmZmVyZW50RXh0ZW5zaW9uQ29udGVudFR5cGUgPSBjb250ZW50VHlwZU1hbmFnZXIuZ2V0Q29udGVudFR5cGUoUElfUkVTT1VSQ0VTX1RFU1RTICsgJy4nICsgInhtbC1iYXNlZC1kaWZmZXJlbnQtZXh0ZW5zaW9uIik7CgkJSUNvbnRlbnRUeXBlIHhtbEJhc2VkU3BlY2lmaWNOYW1lQ29udGVudFR5cGUgPSBjb250ZW50VHlwZU1hbmFnZXIuZ2V0Q29udGVudFR5cGUoUElfUkVTT1VSQ0VTX1RFU1RTICsgJy4nICsgInhtbC1iYXNlZC1zcGVjaWZpYy1uYW1lIik7CgkJSUNvbnRlbnRUeXBlIGJpbmFyeUNvbnRlbnRUeXBlID0gY29udGVudFR5cGVNYW5hZ2VyLmdldENvbnRlbnRUeXBlKFBJX1JFU09VUkNFU19URVNUUyArICcuJyArICJzYW1wbGUtYmluYXJ5MSIpOwoJCWFzc2VydFRydWUoIjEuMCIsIHRleHRDb250ZW50VHlwZS5pc0tpbmRPZih0ZXh0Q29udGVudFR5cGUpKTsKCQlhc3NlcnRUcnVlKCIyLjAiLCB4bWxDb250ZW50VHlwZS5pc0tpbmRPZih0ZXh0Q29udGVudFR5cGUpKTsKCQlhc3NlcnRUcnVlKCIyLjEiLCAhdGV4dENvbnRlbnRUeXBlLmlzS2luZE9mKHhtbENvbnRlbnRUeXBlKSk7CgkJYXNzZXJ0VHJ1ZSgiMi4yIiwgeG1sQ29udGVudFR5cGUuaXNLaW5kT2YoeG1sQ29udGVudFR5cGUpKTsKCQlhc3NlcnRUcnVlKCIzLjAiLCB4bWxCYXNlZERpZmZlcmVudEV4dGVuc2lvbkNvbnRlbnRUeXBlLmlzS2luZE9mKHRleHRDb250ZW50VHlwZSkpOwoJCWFzc2VydFRydWUoIjMuMSIsIHhtbEJhc2VkRGlmZmVyZW50RXh0ZW5zaW9uQ29udGVudFR5cGUuaXNLaW5kT2YoeG1sQ29udGVudFR5cGUpKTsKCQlhc3NlcnRUcnVlKCI0LjAiLCAheG1sQmFzZWREaWZmZXJlbnRFeHRlbnNpb25Db250ZW50VHlwZS5pc0tpbmRPZih4bWxCYXNlZFNwZWNpZmljTmFtZUNvbnRlbnRUeXBlKSk7CgkJYXNzZXJ0VHJ1ZSgiNS4wIiwgIWJpbmFyeUNvbnRlbnRUeXBlLmlzS2luZE9mKHRleHRDb250ZW50VHlwZSkpOwoJfQoKCXB1YmxpYyB2b2lkIHRlc3RMaXN0UGFyc2luZygpIHsKCQlTdHJpbmdbXSBsaXN0OwoJCWxpc3QgPSBVdGlsLnBhcnNlSXRlbXMobnVsbCk7CgkJYXNzZXJ0RXF1YWxzKCIwLjAiLCAwLCBsaXN0Lmxlbmd0aCk7CgkJbGlzdCA9IFV0aWwucGFyc2VJdGVtcygiIik7CgkJYXNzZXJ0RXF1YWxzKCIxLjAiLCAxLCBsaXN0Lmxlbmd0aCk7CgkJYXNzZXJ0RXF1YWxzKCIxLjEiLCAiIiwgbGlzdFswXSk7CgkJbGlzdCA9IFV0aWwucGFyc2VJdGVtcygiZm9vIik7CgkJYXNzZXJ0RXF1YWxzKCIyLjAiLCAxLCBsaXN0Lmxlbmd0aCk7CgkJYXNzZXJ0RXF1YWxzKCIyLjEiLCAiZm9vIiwgbGlzdFswXSk7CgkJbGlzdCA9IFV0aWwucGFyc2VJdGVtcygiLCIpOwoJCWFzc2VydEVxdWFscygiMy4wIiwgMiwgbGlzdC5sZW5ndGgpOwoJCWFzc2VydEVxdWFscygiMy4xIiwgIiIsIGxpc3RbMF0pOwoJCWFzc2VydEVxdWFscygiMy4yIiwgIiIsIGxpc3RbMV0pOwoJCWxpc3QgPSBVdGlsLnBhcnNlSXRlbXMoIixmb28sYmFyIik7CgkJYXNzZXJ0RXF1YWxzKCI0LjAiLCAzLCBsaXN0Lmxlbmd0aCk7CgkJYXNzZXJ0RXF1YWxzKCI0LjEiLCAiIiwgbGlzdFswXSk7CgkJYXNzZXJ0RXF1YWxzKCI0LjIiLCAiZm9vIiwgbGlzdFsxXSk7CgkJYXNzZXJ0RXF1YWxzKCI0LjMiLCAiYmFyIiwgbGlzdFsyXSk7CgkJbGlzdCA9IFV0aWwucGFyc2VJdGVtcygiZm9vLGJhciwiKTsKCQlhc3NlcnRFcXVhbHMoIjUuMCIsIDMsIGxpc3QubGVuZ3RoKTsKCQlhc3NlcnRFcXVhbHMoIjUuMSIsICJmb28iLCBsaXN0WzBdKTsKCQlhc3NlcnRFcXVhbHMoIjUuMiIsICJiYXIiLCBsaXN0WzFdKTsKCQlhc3NlcnRFcXVhbHMoIjUuMyIsICIiLCBsaXN0WzJdKTsKCQlsaXN0ID0gVXRpbC5wYXJzZUl0ZW1zKCJmb28sLGJhciIpOwoJCWFzc2VydEVxdWFscygiNi4wIiwgMywgbGlzdC5sZW5ndGgpOwoJCWFzc2VydEVxdWFscygiNi4xIiwgImZvbyIsIGxpc3RbMF0pOwoJCWFzc2VydEVxdWFscygiNi4yIiwgIiIsIGxpc3RbMV0pOwoJCWFzc2VydEVxdWFscygiNi4zIiwgImJhciIsIGxpc3RbMl0pOwoJCWxpc3QgPSBVdGlsLnBhcnNlSXRlbXMoImZvbywsLGJhciIpOwoJCWFzc2VydEVxdWFscygiNy4wIiwgNCwgbGlzdC5sZW5ndGgpOwoJCWFzc2VydEVxdWFscygiNy4xIiwgImZvbyIsIGxpc3RbMF0pOwoJCWFzc2VydEVxdWFscygiNy4yIiwgIiIsIGxpc3RbMV0pOwoJCWFzc2VydEVxdWFscygiNy4zIiwgIiIsIGxpc3RbMl0pOwoJCWFzc2VydEVxdWFscygiNy40IiwgImJhciIsIGxpc3RbM10pOwoJCWxpc3QgPSBVdGlsLnBhcnNlSXRlbXMoIiwsZm9vLGJhciIpOwoJCWFzc2VydEVxdWFscygiOC4wIiwgNCwgbGlzdC5sZW5ndGgpOwoJCWFzc2VydEVxdWFscygiOC4xIiwgIiIsIGxpc3RbMF0pOwoJCWFzc2VydEVxdWFscygiOC4yIiwgIiIsIGxpc3RbMV0pOwoJCWFzc2VydEVxdWFscygiOC4zIiwgImZvbyIsIGxpc3RbMl0pOwoJCWFzc2VydEVxdWFscygiOC40IiwgImJhciIsIGxpc3RbM10pOwoJCWxpc3QgPSBVdGlsLnBhcnNlSXRlbXMoImZvbyxiYXIsLCIpOwoJCWFzc2VydEVxdWFscygiOS4wIiwgNCwgbGlzdC5sZW5ndGgpOwoJCWFzc2VydEVxdWFscygiOS4xIiwgImZvbyIsIGxpc3RbMF0pOwoJCWFzc2VydEVxdWFscygiOS4yIiwgImJhciIsIGxpc3RbMV0pOwoJCWFzc2VydEVxdWFscygiOS4zIiwgIiIsIGxpc3RbMl0pOwoJCWFzc2VydEVxdWFscygiOS40IiwgIiIsIGxpc3RbM10pOwoJCWxpc3QgPSBVdGlsLnBhcnNlSXRlbXMoIiwsLCIpOwoJCWFzc2VydEVxdWFscygiMTAuMCIsIDQsIGxpc3QubGVuZ3RoKTsKCQlhc3NlcnRFcXVhbHMoIjEwLjEiLCAiIiwgbGlzdFswXSk7CgkJYXNzZXJ0RXF1YWxzKCIxMC4yIiwgIiIsIGxpc3RbMV0pOwoJCWFzc2VydEVxdWFscygiMTAuMyIsICIiLCBsaXN0WzJdKTsKCQlhc3NlcnRFcXVhbHMoIjEwLjQiLCAiIiwgbGlzdFszXSk7Cgl9CgoJcHVibGljIHZvaWQgdGVzdE15Q29udGVudERlc2NyaWJlcigpIHRocm93cyBVbnN1cHBvcnRlZEVuY29kaW5nRXhjZXB0aW9uLCBJT0V4Y2VwdGlvbiB7CgkJSUNvbnRlbnRUeXBlTWFuYWdlciBtYW5hZ2VyID0gUGxhdGZvcm0uZ2V0Q29udGVudFR5cGVNYW5hZ2VyKCk7CgkJSUNvbnRlbnRUeXBlIG15Q29udGVudCA9IG1hbmFnZXIuZ2V0Q29udGVudFR5cGUoUElfUkVTT1VSQ0VTX1RFU1RTICsgJy4nICsgIm15Q29udGVudCIpOwoJCWFzc2VydE5vdE51bGwoIjAuNSIsIG15Q29udGVudCk7CgkJYXNzZXJ0RXF1YWxzKCIwLjYiLCBteUNvbnRlbnQsIG1hbmFnZXIuZmluZENvbnRlbnRUeXBlRm9yKCJteUNvbnRlbnQubWMxIikpOwoJCWFzc2VydEVxdWFscygiMC43IiwgbXlDb250ZW50LCBtYW5hZ2VyLmZpbmRDb250ZW50VHlwZUZvcigibXlDb250ZW50Lm1jMiIpKTsKCQlhc3NlcnRFcXVhbHMoIjAuOCIsIG15Q29udGVudCwgbWFuYWdlci5maW5kQ29udGVudFR5cGVGb3IoImZvby5teUNvbnRlbnQxIikpOwoJCWFzc2VydEVxdWFscygiMC45IiwgbXlDb250ZW50LCBtYW5hZ2VyLmZpbmRDb250ZW50VHlwZUZvcigiYmFyLm15Q29udGVudDIiKSk7CgkJSUNvbnRlbnREZXNjcmlwdGlvbiBkZXNjcmlwdGlvbiA9IG1hbmFnZXIuZ2V0RGVzY3JpcHRpb25Gb3IoZ2V0SW5wdXRTdHJlYW0oTXlDb250ZW50RGVzY3JpYmVyLlNJR05BVFVSRSwgIlVTLUFTQ0lJIiksICJteUNvbnRlbnQubWMxIiwgSUNvbnRlbnREZXNjcmlwdGlvbi5BTEwpOwoJCWFzc2VydE5vdE51bGwoIjEuMCIsIGRlc2NyaXB0aW9uKTsKCQlhc3NlcnRFcXVhbHMoIjEuMSIsIG15Q29udGVudCwgZGVzY3JpcHRpb24uZ2V0Q29udGVudFR5cGUoKSk7CgkJYXNzZXJ0Tm90U2FtZSgiMS4yIiwgbXlDb250ZW50LmdldERlZmF1bHREZXNjcmlwdGlvbigpLCBkZXNjcmlwdGlvbik7CgkJZm9yIChpbnQgaSA9IDA7IGkgPCBNeUNvbnRlbnREZXNjcmliZXIuTVlfT1BUSU9OUy5sZW5ndGg7IGkrKykgewoJCQlhc3NlcnRFcXVhbHMoIjIuIiArIGksIE15Q29udGVudERlc2NyaWJlci5NWV9PUFRJT05fVkFMVUVTW2ldLCBkZXNjcmlwdGlvbi5nZXRQcm9wZXJ0eShNeUNvbnRlbnREZXNjcmliZXIuTVlfT1BUSU9OU1tpXSkpOwoJCX0KCX0KCglwdWJsaWMgdm9pZCB0ZXN0Tm9FeHRlbnNpb25Bc3NvY2lhdGlvbigpIHsKCQkvL1RPRE8gdXNlIGEgSUNvbnRlbnRUeXBlTWF0Y2hlciBpbnN0ZWFkCgkJZmluYWwgSUNvbnRlbnRUeXBlTWFuYWdlciBtYW5hZ2VyID0gUGxhdGZvcm0uZ2V0Q29udGVudFR5cGVNYW5hZ2VyKCk7CgoJCUlDb250ZW50VHlwZVtdIHNlbGVjdGVkID0gbWFuYWdlci5maW5kQ29udGVudFR5cGVzRm9yKCJmaWxlX3dpdGhfbm9fZXh0ZW5zaW9uIik7CgkJYXNzZXJ0RXF1YWxzKCIwLjEiLCAwLCBzZWxlY3RlZC5sZW5ndGgpOwoKCQlUZXN0UmVnaXN0cnlDaGFuZ2VMaXN0ZW5lciBsaXN0ZW5lciA9IG5ldyBUZXN0UmVnaXN0cnlDaGFuZ2VMaXN0ZW5lcihQbGF0Zm9ybS5QSV9SVU5USU1FLCBDb250ZW50VHlwZUJ1aWxkZXIuUFRfQ09OVEVOVFRZUEVTLCBudWxsLCBudWxsKTsKCQlCdW5kbGVUZXN0aW5nSGVscGVyLnJ1bldpdGhCdW5kbGVzKCIxIiwgKCkgLT4gewoJCQlmaW5hbCBTdHJpbmcgbmFtZXNwYWNlID0gIm9yZy5lY2xpcHNlLmJ1bmRsZTA0IjsKCgkJCUlDb250ZW50VHlwZSBlbXB0eTEgPSBtYW5hZ2VyLmdldENvbnRlbnRUeXBlKG5hbWVzcGFjZSArICIuZW1wdHlfZXh0ZW5zaW9uMSIpOwoJCQlJQ29udGVudFR5cGUgZW1wdHkyID0gbWFuYWdlci5nZXRDb250ZW50VHlwZShuYW1lc3BhY2UgKyAiLmVtcHR5X2V4dGVuc2lvbjIiKTsKCQkJSUNvbnRlbnRUeXBlIGVtcHR5MyA9IG1hbmFnZXIuZ2V0Q29udGVudFR5cGUobmFtZXNwYWNlICsgIi5lbXB0eV9leHRlbnNpb24zIik7CgkJCUlDb250ZW50VHlwZSBlbXB0eTQgPSBtYW5hZ2VyLmdldENvbnRlbnRUeXBlKG5hbWVzcGFjZSArICIuZW1wdHlfZXh0ZW5zaW9uNCIpOwoJCQlJQ29udGVudFR5cGUgbm9uRW1wdHkgPSBtYW5hZ2VyLmdldENvbnRlbnRUeXBlKG5hbWVzcGFjZSArICIubm9uX2VtcHR5X2V4dGVuc2lvbiIpOwoKCQkJYXNzZXJ0Tm90TnVsbCgiMS4xLjEiLCBlbXB0eTEpOwoJCQlhc3NlcnROb3ROdWxsKCIxLjEuMiIsIGVtcHR5Mik7CgkJCWFzc2VydE5vdE51bGwoIjEuMS4zIiwgZW1wdHkzKTsKCQkJYXNzZXJ0Tm90TnVsbCgiMS4xLjQiLCBlbXB0eTQpOwoJCQlhc3NlcnROb3ROdWxsKCIxLjEuNSIsIG5vbkVtcHR5KTsKCgkJCUlDb250ZW50VHlwZVtdIHNlbGVjdGVkMSA9IG1hbmFnZXIuZmluZENvbnRlbnRUeXBlc0ZvcigiZmlsZV93aXRoX25vX2V4dGVuc2lvbiIpOwoJCQlhc3NlcnRFcXVhbHMoIjEuMi4wIiwgNCwgc2VsZWN0ZWQxLmxlbmd0aCk7CgkJCWFzc2VydFRydWUoIjEuMi4xIiwgY29udGFpbnMoc2VsZWN0ZWQxLCBlbXB0eTEpKTsKCQkJYXNzZXJ0VHJ1ZSgiMS4yLjIiLCBjb250YWlucyhzZWxlY3RlZDEsIGVtcHR5MikpOwoJCQlhc3NlcnRUcnVlKCIxLjIuMyIsIGNvbnRhaW5zKHNlbGVjdGVkMSwgZW1wdHkzKSk7CgkJCWFzc2VydFRydWUoIjEuMi40IiwgY29udGFpbnMoc2VsZWN0ZWQxLCBlbXB0eTQpKTsKCgkJCXNlbGVjdGVkMSA9IG1hbmFnZXIuZmluZENvbnRlbnRUeXBlc0ZvcigiZmlsZV93aXRoX2V4dGVuc2lvbi5ub24tZW1wdHkiKTsKCQkJYXNzZXJ0RXF1YWxzKCIxLjIuNSIsIDEsIHNlbGVjdGVkMS5sZW5ndGgpOwoJCQlhc3NlcnRUcnVlKCIxLjIuNiIsIGNvbnRhaW5zKHNlbGVjdGVkMSwgbm9uRW1wdHkpKTsKCgkJCXRyeSB7CgkJCQlub25FbXB0eS5hZGRGaWxlU3BlYygiIiwgSUNvbnRlbnRUeXBlLkZJTEVfRVhURU5TSU9OX1NQRUMpOwoJCQl9IGNhdGNoIChDb3JlRXhjZXB0aW9uIGUxKSB7CgkJCQlmYWlsKCIxLjMuMCIsIGUxKTsKCQkJfQoJCQl0cnkgewoJCQkJc2VsZWN0ZWQxID0gbWFuYWdlci5maW5kQ29udGVudFR5cGVzRm9yKCJmaWxlX3dpdGhfbm9fZXh0ZW5zaW9uIik7CgkJCQlhc3NlcnRFcXVhbHMoIjEuMy4xIiwgNSwgc2VsZWN0ZWQxLmxlbmd0aCk7CgkJCQlhc3NlcnRUcnVlKCIxLjMuMiIsIGNvbnRhaW5zKHNlbGVjdGVkMSwgbm9uRW1wdHkpKTsKCQkJfSBmaW5hbGx5IHsKCQkJCXRyeSB7CgkJCQkJbm9uRW1wdHkucmVtb3ZlRmlsZVNwZWMoIiIsIElDb250ZW50VHlwZS5GSUxFX0VYVEVOU0lPTl9TUEVDKTsKCQkJCX0gY2F0Y2ggKENvcmVFeGNlcHRpb24gZTIpIHsKCQkJCQlmYWlsKCIxLjMuMyIsIGUyKTsKCQkJCX0KCQkJfQoJCQlzZWxlY3RlZDEgPSBtYW5hZ2VyLmZpbmRDb250ZW50VHlwZXNGb3IoImZpbGVfd2l0aF9ub19leHRlbnNpb24iKTsKCQkJYXNzZXJ0RXF1YWxzKCIxLjQuMCIsIDQsIHNlbGVjdGVkMS5sZW5ndGgpOwoJCQlhc3NlcnRUcnVlKCIxLjQuMSIsICFjb250YWlucyhzZWxlY3RlZDEsIG5vbkVtcHR5KSk7CgkJfSwgZ2V0Q29udGV4dCgpLCBuZXcgU3RyaW5nW10ge0NvbnRlbnRUeXBlVGVzdC5URVNUX0ZJTEVTX1JPT1QgKyAiY29udGVudC9idW5kbGUwNCJ9LCBsaXN0ZW5lcik7Cgl9CgoJcHVibGljIHZvaWQgdGVzdE9yZGVyV2l0aEVtcHR5RmlsZXMoKSB0aHJvd3MgSU9FeGNlcHRpb24gewoJCUlDb250ZW50VHlwZU1hbmFnZXIgbWFuYWdlciA9IFBsYXRmb3JtLmdldENvbnRlbnRUeXBlTWFuYWdlcigpOwoJCUlDb250ZW50VHlwZU1hdGNoZXIgZmluZGVyID0gbWFuYWdlci5nZXRNYXRjaGVyKG5ldyBMb2NhbFNlbGVjdGlvblBvbGljeSgpLCBudWxsKTsKCgkJSUNvbnRlbnRUeXBlIHhtbCA9IG1hbmFnZXIuZ2V0Q29udGVudFR5cGUoUGxhdGZvcm0uUElfUlVOVElNRSArICIueG1sIik7CgkJbWFuYWdlci5nZXRDb250ZW50VHlwZShQSV9SRVNPVVJDRVNfVEVTVFMgKyAiLnJvb3QtZWxlbWVudCIpOwoJCW1hbmFnZXIuZ2V0Q29udGVudFR5cGUoUElfUkVTT1VSQ0VTX1RFU1RTICsgIi5kdGQiKTsKCQkvLyBmb3IgYW4gZW1wdHkgZmlsZSwgdGhlIG1vc3QgZ2VuZXJpYyBjb250ZW50IHR5cGUgc2hvdWxkIGJlIHJldHVybmVkCgkJSUNvbnRlbnRUeXBlIHNlbGVjdGVkID0gZmluZGVyLmZpbmRDb250ZW50VHlwZUZvcihnZXRJbnB1dFN0cmVhbSgiIiksICJmb28ueG1sIik7CgkJYXNzZXJ0RXF1YWxzKCIxLjAiLCB4bWwsIHNlbGVjdGVkKTsKCQkvLyBpdCBzaG91bGQgYmUgZXF1aXZhbGVudCB0byBvbWl0dGluZyB0aGUgY29udGVudHMKCQlhc3NlcnRFcXVhbHMoIjEuMSIsIHhtbCwgZmluZGVyLmZpbmRDb250ZW50VHlwZUZvcigiZm9vLnhtbCIpKTsKCX0KCgkvKioKCSAqIFRoaXMgdGVzdCBzaG93cyBob3cgd2UgZGVhbCB3aXRoIG9ycGhhbiBmaWxlIGFzc29jaWF0aW9ucyAoYXNzb2NpYXRpb25zCgkgKiB3aG9zZSBjb250ZW50IHR5cGVzIGFyZSBtaXNzaW5nKS4KCSAqLwoJcHVibGljIHZvaWQgdGVzdE9ycGhhbkNvbnRlbnRUeXBlKCkgewoJCWZpbmFsIElDb250ZW50VHlwZU1hbmFnZXIgY29udGVudFR5cGVNYW5hZ2VyID0gUGxhdGZvcm0uZ2V0Q29udGVudFR5cGVNYW5hZ2VyKCk7CgkJSUNvbnRlbnRUeXBlIG9ycGhhbiA9IGNvbnRlbnRUeXBlTWFuYWdlci5nZXRDb250ZW50VHlwZShQSV9SRVNPVVJDRVNfVEVTVFMgKyAiLm9ycGhhbiIpOwoJCWFzc2VydE51bGwoIjAuOCIsIG9ycGhhbik7CgkJSUNvbnRlbnRUeXBlIG1pc3NpbmcgPSBjb250ZW50VHlwZU1hbmFnZXIuZ2V0Q29udGVudFR5cGUoIm9yZy5lY2xpcHNlLmJ1bmRsZTAxLm1pc3NpbmciKTsKCQlhc3NlcnROdWxsKCIwLjkiLCBtaXNzaW5nKTsKCQlhc3NlcnRFcXVhbHMoIjEuMSIsIDAsIGNvbnRlbnRUeXBlTWFuYWdlci5maW5kQ29udGVudFR5cGVzRm9yKCJmb28ub3JwaGFuIikubGVuZ3RoKTsKCQlhc3NlcnRFcXVhbHMoIjEuMiIsIDAsIGNvbnRlbnRUeXBlTWFuYWdlci5maW5kQ29udGVudFR5cGVzRm9yKCJvcnBoYW4ub3JwaGFuIikubGVuZ3RoKTsKCQlhc3NlcnRFcXVhbHMoIjEuMyIsIDAsIGNvbnRlbnRUeXBlTWFuYWdlci5maW5kQ29udGVudFR5cGVzRm9yKCJmb28ub3JwaGFuMiIpLmxlbmd0aCk7CgoJCS8vdGVzdCBsYXRlIGFkZGl0aW9uIG9mIGNvbnRlbnQgdHlwZSAtIG9ycGhhbjIgc2hvdWxkIGJlY29tZSB2aXNpYmxlCgkJVGVzdFJlZ2lzdHJ5Q2hhbmdlTGlzdGVuZXIgbGlzdGVuZXIgPSBuZXcgVGVzdFJlZ2lzdHJ5Q2hhbmdlTGlzdGVuZXIoUGxhdGZvcm0uUElfUlVOVElNRSwgQ29udGVudFR5cGVCdWlsZGVyLlBUX0NPTlRFTlRUWVBFUywgbnVsbCwgbnVsbCk7CgoJCUJ1bmRsZVRlc3RpbmdIZWxwZXIucnVuV2l0aEJ1bmRsZXMoIjIiLCAoKSAtPiB7CgkJCUlDb250ZW50VHlwZSBvcnBoYW4xID0gY29udGVudFR5cGVNYW5hZ2VyLmdldENvbnRlbnRUeXBlKFBJX1JFU09VUkNFU19URVNUUyArICIub3JwaGFuIik7CgkJCWFzc2VydE5vdE51bGwoIjIuMSIsIG9ycGhhbjEpOwoJCQlJQ29udGVudFR5cGUgbWlzc2luZzEgPSBjb250ZW50VHlwZU1hbmFnZXIuZ2V0Q29udGVudFR5cGUoIm9yZy5lY2xpcHNlLmJ1bmRsZTAxLm1pc3NpbmciKTsKCQkJYXNzZXJ0Tm90TnVsbCgiMi4yIiwgbWlzc2luZzEpOwoJCQkvLyBjaGVja3Mgb3JwaGFuJ3MgYXNzb2NpYXRpb25zCgkJCWFzc2VydEVxdWFscygiMi4zIiwgMSwgY29udGVudFR5cGVNYW5hZ2VyLmZpbmRDb250ZW50VHlwZXNGb3IoImZvby5vcnBoYW4iKS5sZW5ndGgpOwoJCQlhc3NlcnRFcXVhbHMoIjIuNCIsIG9ycGhhbjEsIGNvbnRlbnRUeXBlTWFuYWdlci5maW5kQ29udGVudFR5cGVzRm9yKCJmb28ub3JwaGFuIilbMF0pOwoJCQlhc3NlcnRFcXVhbHMoIjIuNSIsIDEsIGNvbnRlbnRUeXBlTWFuYWdlci5maW5kQ29udGVudFR5cGVzRm9yKCJvcnBoYW4ub3JwaGFuIikubGVuZ3RoKTsKCQkJYXNzZXJ0RXF1YWxzKCIyLjYiLCBvcnBoYW4xLCBjb250ZW50VHlwZU1hbmFnZXIuZmluZENvbnRlbnRUeXBlc0ZvcigiZm9vLm9ycGhhbiIpWzBdKTsKCQkJLy8gY2hlY2sgd2hldGhlciBhbiBvcnBoYW4gYXNzb2NpYXRpb24gd2FzIGFkZGVkIHRvIHRoZSBkeW5hbWljYWxseSBhZGRlZCBidW5kbGUKCQkJYXNzZXJ0RXF1YWxzKCIyLjciLCAxLCBjb250ZW50VHlwZU1hbmFnZXIuZmluZENvbnRlbnRUeXBlc0ZvcigiZm9vLm9ycGhhbjIiKS5sZW5ndGgpOwoJCQlhc3NlcnRFcXVhbHMoIjIuOCIsIG1pc3NpbmcxLCBjb250ZW50VHlwZU1hbmFnZXIuZmluZENvbnRlbnRUeXBlc0ZvcigiZm9vLm9ycGhhbjIiKVswXSk7CgkJfSwgZ2V0Q29udGV4dCgpLCBuZXcgU3RyaW5nW10ge0NvbnRlbnRUeXBlVGVzdC5URVNUX0ZJTEVTX1JPT1QgKyAiY29udGVudC9idW5kbGUwMSJ9LCBsaXN0ZW5lcik7Cgl9CgoJLyoqCgkgKiBSZWdyZXNzaW9uIHRlc3QgZm9yIGJ1ZyA2ODg5NAoJICovCglwdWJsaWMgdm9pZCB0ZXN0UHJlZmVyZW5jZXMoKSB0aHJvd3MgQ29yZUV4Y2VwdGlvbiwgQmFja2luZ1N0b3JlRXhjZXB0aW9uIHsKCQlJQ29udGVudFR5cGVNYW5hZ2VyIG1hbmFnZXIgPSBQbGF0Zm9ybS5nZXRDb250ZW50VHlwZU1hbmFnZXIoKTsKCQlJQ29udGVudFR5cGUgdGV4dCA9IG1hbmFnZXIuZ2V0Q29udGVudFR5cGUoSUNvbnRlbnRUeXBlTWFuYWdlci5DVF9URVhUKTsKCQlQcmVmZXJlbmNlcyB0ZXh0UHJlZnMgPSBJbnN0YW5jZVNjb3BlLklOU1RBTkNFLmdldE5vZGUoQ29udGVudFR5cGVNYW5hZ2VyLkNPTlRFTlRfVFlQRV9QUkVGX05PREUpLm5vZGUodGV4dC5nZXRJZCgpKTsKCQlhc3NlcnROb3ROdWxsKCIwLjEiLCB0ZXh0KTsKCgkJLy8gZW5zdXJlIHRoZSAiZGVmYXVsdCBjaGFyc2V0IiBwcmVmZXJlbmNlIGlzIGJlaW5nIHByb3Blcmx5IHVzZWQKCQlhc3NlcnROdWxsKCIxLjAiLCB0ZXh0LmdldERlZmF1bHRDaGFyc2V0KCkpOwoJCWFzc2VydE51bGwoIjEuMSIsIHRleHRQcmVmcy5nZXQoQ29udGVudFR5cGUuUFJFRl9ERUZBVUxUX0NIQVJTRVQsIG51bGwpKTsKCQl0ZXh0LnNldERlZmF1bHRDaGFyc2V0KCJVVEYtOCIpOwoJCWFzc2VydEVxdWFscygiMS4yIiwgIlVURi04IiwgdGV4dFByZWZzLmdldChDb250ZW50VHlwZS5QUkVGX0RFRkFVTFRfQ0hBUlNFVCwgbnVsbCkpOwoJCXRleHQuc2V0RGVmYXVsdENoYXJzZXQobnVsbCk7CgkJYXNzZXJ0TnVsbCgiMS4zIiwgdGV4dFByZWZzLmdldChDb250ZW50VHlwZS5QUkVGX0RFRkFVTFRfQ0hBUlNFVCwgbnVsbCkpOwoKCQkvLyBlbnN1cmUgdGhlIGZpbGUgc3BlYyBwcmVmZXJlbmNlcyBhcmUgYmVpbmcgcHJvcGVybHkgdXNlZAoJCS8vIHNvbWUgc2FuaXR5IGNoZWNraW5nCgkJYXNzZXJ0RmFsc2UoIjIuMDEiLCB0ZXh0LmlzQXNzb2NpYXRlZFdpdGgoInh5ei5mb28iKSk7CgkJYXNzZXJ0RmFsc2UoIjIuMDEiLCB0ZXh0LmlzQXNzb2NpYXRlZFdpdGgoInh5ei5iYXIiKSk7CgkJYXNzZXJ0RmFsc2UoIjIuMDMiLCB0ZXh0LmlzQXNzb2NpYXRlZFdpdGgoImZvby5leHQiKSk7CgkJYXNzZXJ0RmFsc2UoIjIuMDQiLCB0ZXh0LmlzQXNzb2NpYXRlZFdpdGgoImJhci5leHQiKSk7CgkJLy9OdWxsIGVudHJpZXMgZmlyc3QgdG8gYXZvaWQgaW50ZXJmZXJlbmNlIGZyb20gb3RoZXIgdGVzdHMKCQl0ZXh0UHJlZnMucmVtb3ZlKENvbnRlbnRUeXBlLlBSRUZfRklMRV9OQU1FUyk7CgkJdGV4dFByZWZzLnJlbW92ZShDb250ZW50VHlwZS5QUkVGX0ZJTEVfRVhURU5TSU9OUyk7CgkJLy8gcGxheSB3aXRoIGZpbGUgbmFtZSBhc3NvY2lhdGlvbnMgZmlyc3QuLi4KCQlhc3NlcnROdWxsKCIyLjBhIiwgdGV4dFByZWZzLmdldChDb250ZW50VHlwZS5QUkVGX0ZJTEVfTkFNRVMsIG51bGwpKTsKCQlhc3NlcnROdWxsKCIyLjBiIiwgdGV4dFByZWZzLmdldChDb250ZW50VHlwZS5QUkVGX0ZJTEVfRVhURU5TSU9OUywgbnVsbCkpOwoJCXRleHQuYWRkRmlsZVNwZWMoImZvby5leHQiLCBJQ29udGVudFR5cGUuRklMRV9OQU1FX1NQRUMpOwoJCWFzc2VydFRydWUoIjIuMSIsIHRleHQuaXNBc3NvY2lhdGVkV2l0aCgiZm9vLmV4dCIpKTsKCQlhc3NlcnRFcXVhbHMoIjIuMiIsICJmb28uZXh0IiwgdGV4dFByZWZzLmdldChDb250ZW50VHlwZS5QUkVGX0ZJTEVfTkFNRVMsIG51bGwpKTsKCQl0ZXh0LmFkZEZpbGVTcGVjKCJiYXIuZXh0IiwgSUNvbnRlbnRUeXBlLkZJTEVfTkFNRV9TUEVDKTsKCQlhc3NlcnRUcnVlKCIyLjMiLCB0ZXh0LmlzQXNzb2NpYXRlZFdpdGgoImJhci5leHQiKSk7CgkJYXNzZXJ0RXF1YWxzKCIyLjQiLCAiZm9vLmV4dCxiYXIuZXh0IiwgdGV4dFByZWZzLmdldChDb250ZW50VHlwZS5QUkVGX0ZJTEVfTkFNRVMsIG51bGwpKTsKCQkvLyAuLi4gYW5kIHRoZW4gd2l0aCBmaWxlIGV4dGVuc2lvbnMKCQl0ZXh0LmFkZEZpbGVTcGVjKCJmb28iLCBJQ29udGVudFR5cGUuRklMRV9FWFRFTlNJT05fU1BFQyk7CgkJYXNzZXJ0VHJ1ZSgiMi41IiwgdGV4dC5pc0Fzc29jaWF0ZWRXaXRoKCJ4eXouZm9vIikpOwoJCWFzc2VydEVxdWFscygiMi42IiwgImZvbyIsIHRleHRQcmVmcy5nZXQoQ29udGVudFR5cGUuUFJFRl9GSUxFX0VYVEVOU0lPTlMsIG51bGwpKTsKCQl0ZXh0LmFkZEZpbGVTcGVjKCJiYXIiLCBJQ29udGVudFR5cGUuRklMRV9FWFRFTlNJT05fU1BFQyk7CgkJYXNzZXJ0VHJ1ZSgiMi43IiwgdGV4dC5pc0Fzc29jaWF0ZWRXaXRoKCJ4eXouYmFyIikpOwoJCWFzc2VydEVxdWFscygiMi40IiwgImZvbyxiYXIiLCB0ZXh0UHJlZnMuZ2V0KENvbnRlbnRUeXBlLlBSRUZfRklMRV9FWFRFTlNJT05TLCBudWxsKSk7CgkJLy8gcmVtb3ZlIGFsbCBhc3NvY2lhdGlvbnMgbWFkZQoJCXRleHQucmVtb3ZlRmlsZVNwZWMoImZvby5leHQiLCBJQ29udGVudFR5cGUuRklMRV9OQU1FX1NQRUMpOwoJCXRleHQucmVtb3ZlRmlsZVNwZWMoImJhci5leHQiLCBJQ29udGVudFR5cGUuRklMRV9OQU1FX1NQRUMpOwoJCXRleHQucmVtb3ZlRmlsZVNwZWMoImZvbyIsIElDb250ZW50VHlwZS5GSUxFX0VYVEVOU0lPTl9TUEVDKTsKCQl0ZXh0LnJlbW92ZUZpbGVTcGVjKCJiYXIiLCBJQ29udGVudFR5cGUuRklMRV9FWFRFTlNJT05fU1BFQyk7CgkJLy8gZW5zdXJlIGFsbCBpcyBhcyBiZWZvcmUKCQlhc3NlcnRGYWxzZSgiMy4xIiwgdGV4dC5pc0Fzc29jaWF0ZWRXaXRoKCJ4eXouZm9vIikpOwoJCWFzc2VydEZhbHNlKCIzLjIiLCB0ZXh0LmlzQXNzb2NpYXRlZFdpdGgoInh5ei5iYXIiKSk7CgkJYXNzZXJ0RmFsc2UoIjMuMyIsIHRleHQuaXNBc3NvY2lhdGVkV2l0aCgiZm9vLmV4dCIpKTsKCQlhc3NlcnRGYWxzZSgiMy40IiwgdGV4dC5pc0Fzc29jaWF0ZWRXaXRoKCJiYXIuZXh0IikpOwoKCQkvLyBlbnN1cmUgdGhlIHNlcmlhbGl6YXRpb24gZm9ybWF0IGlzIGNvcnJlY3QKCQl0cnkgewoJCQl0ZXh0LmFkZEZpbGVTcGVjKCJmb28uYmFyIiwgSUNvbnRlbnRUeXBlLkZJTEVfTkFNRV9TUEVDKTsKCQkJdGV4dFByZWZzLnN5bmMoKTsKCQkJYXNzZXJ0RXF1YWxzKCI0LjAiLCAiZm9vLmJhciIsIHRleHRQcmVmcy5nZXQoQ29udGVudFR5cGUuUFJFRl9GSUxFX05BTUVTLCBudWxsKSk7CgkJfSBmaW5hbGx5IHsKCQkJLy8gY2xlYW4tdXAKCQkJdGV4dC5yZW1vdmVGaWxlU3BlYygiZm9vLmJhciIsIElDb250ZW50VHlwZS5GSUxFX05BTUVfU1BFQyk7CgkJfQoJfQoKCXB1YmxpYyB2b2lkIHRlc3RSZWdpc3RyeSgpIHsKCQlJQ29udGVudFR5cGVNYW5hZ2VyIGNvbnRlbnRUeXBlTWFuYWdlciA9IFBsYXRmb3JtLmdldENvbnRlbnRUeXBlTWFuYWdlcigpOwoJCUlDb250ZW50VHlwZU1hdGNoZXIgZmluZGVyID0gY29udGVudFR5cGVNYW5hZ2VyLmdldE1hdGNoZXIobmV3IExvY2FsU2VsZWN0aW9uUG9saWN5KCksIG51bGwpOwoKCQlJQ29udGVudFR5cGUgdGV4dENvbnRlbnRUeXBlID0gY29udGVudFR5cGVNYW5hZ2VyLmdldENvbnRlbnRUeXBlKFBsYXRmb3JtLlBJX1JVTlRJTUUgKyAnLicgKyAidGV4dCIpOwoJCWFzc2VydE5vdE51bGwoIjEuMCIsIHRleHRDb250ZW50VHlwZSk7CgkJYXNzZXJ0VHJ1ZSgiMS4xIiwgaXNUZXh0KGNvbnRlbnRUeXBlTWFuYWdlciwgdGV4dENvbnRlbnRUeXBlKSk7CgkJYXNzZXJ0Tm90TnVsbCgiMS4yIiwgKChDb250ZW50VHlwZUhhbmRsZXIpIHRleHRDb250ZW50VHlwZSkuZ2V0VGFyZ2V0KCkuZ2V0RGVzY3JpYmVyKCkpOwoKCQlJQ29udGVudFR5cGUgeG1sQ29udGVudFR5cGUgPSBjb250ZW50VHlwZU1hbmFnZXIuZ2V0Q29udGVudFR5cGUoUGxhdGZvcm0uUElfUlVOVElNRSArICIueG1sIik7CgkJYXNzZXJ0Tm90TnVsbCgiMi4wIiwgeG1sQ29udGVudFR5cGUpOwoJCWFzc2VydFRydWUoIjIuMSIsIGlzVGV4dChjb250ZW50VHlwZU1hbmFnZXIsIHhtbENvbnRlbnRUeXBlKSk7CgkJYXNzZXJ0RXF1YWxzKCIyLjIiLCB0ZXh0Q29udGVudFR5cGUsIHhtbENvbnRlbnRUeXBlLmdldEJhc2VUeXBlKCkpOwoJCUlDb250ZW50RGVzY3JpYmVyIHhtbERlc2NyaWJlciA9ICgoQ29udGVudFR5cGVIYW5kbGVyKSB4bWxDb250ZW50VHlwZSkuZ2V0VGFyZ2V0KCkuZ2V0RGVzY3JpYmVyKCk7CgkJYXNzZXJ0Tm90TnVsbCgiMi4zIiwgeG1sRGVzY3JpYmVyKTsKCQlhc3NlcnRUcnVlKCIyLjQiLCB4bWxEZXNjcmliZXIgaW5zdGFuY2VvZiBYTUxDb250ZW50RGVzY3JpYmVyKTsKCgkJSUNvbnRlbnRUeXBlIHhtbEJhc2VkRGlmZmVyZW50RXh0ZW5zaW9uQ29udGVudFR5cGUgPSBjb250ZW50VHlwZU1hbmFnZXIuZ2V0Q29udGVudFR5cGUoUElfUkVTT1VSQ0VTX1RFU1RTICsgJy4nICsgInhtbC1iYXNlZC1kaWZmZXJlbnQtZXh0ZW5zaW9uIik7CgkJYXNzZXJ0Tm90TnVsbCgiMy4wIiwgeG1sQmFzZWREaWZmZXJlbnRFeHRlbnNpb25Db250ZW50VHlwZSk7CgkJYXNzZXJ0VHJ1ZSgiMy4xIiwgaXNUZXh0KGNvbnRlbnRUeXBlTWFuYWdlciwgeG1sQmFzZWREaWZmZXJlbnRFeHRlbnNpb25Db250ZW50VHlwZSkpOwoJCWFzc2VydEVxdWFscygiMy4yIiwgeG1sQ29udGVudFR5cGUsIHhtbEJhc2VkRGlmZmVyZW50RXh0ZW5zaW9uQ29udGVudFR5cGUuZ2V0QmFzZVR5cGUoKSk7CgoJCUlDb250ZW50VHlwZSB4bWxCYXNlZFNwZWNpZmljTmFtZUNvbnRlbnRUeXBlID0gY29udGVudFR5cGVNYW5hZ2VyLmdldENvbnRlbnRUeXBlKFBJX1JFU09VUkNFU19URVNUUyArICcuJyArICJ4bWwtYmFzZWQtc3BlY2lmaWMtbmFtZSIpOwoJCWFzc2VydE5vdE51bGwoIjQuMCIsIHhtbEJhc2VkU3BlY2lmaWNOYW1lQ29udGVudFR5cGUpOwoJCWFzc2VydFRydWUoIjQuMSIsIGlzVGV4dChjb250ZW50VHlwZU1hbmFnZXIsIHhtbEJhc2VkU3BlY2lmaWNOYW1lQ29udGVudFR5cGUpKTsKCQlhc3NlcnRFcXVhbHMoIjQuMiIsIHhtbENvbnRlbnRUeXBlLCB4bWxCYXNlZFNwZWNpZmljTmFtZUNvbnRlbnRUeXBlLmdldEJhc2VUeXBlKCkpOwoKCQlJQ29udGVudFR5cGVbXSB4bWxUeXBlcyA9IGZpbmRlci5maW5kQ29udGVudFR5cGVzRm9yKGNoYW5nZUNhc2UoImZvby54bWwiKSk7CgkJYXNzZXJ0VHJ1ZSgiNS4xIiwgY29udGFpbnMoeG1sVHlwZXMsIHhtbENvbnRlbnRUeXBlKSk7CgoJCUlDb250ZW50VHlwZSBiaW5hcnlDb250ZW50VHlwZSA9IGNvbnRlbnRUeXBlTWFuYWdlci5nZXRDb250ZW50VHlwZShQSV9SRVNPVVJDRVNfVEVTVFMgKyAnLicgKyAic2FtcGxlLWJpbmFyeTEiKTsKCQlhc3NlcnROb3ROdWxsKCI2LjAiLCBiaW5hcnlDb250ZW50VHlwZSk7CgkJYXNzZXJ0VHJ1ZSgiNi4xIiwgIWlzVGV4dChjb250ZW50VHlwZU1hbmFnZXIsIGJpbmFyeUNvbnRlbnRUeXBlKSk7CgkJYXNzZXJ0TnVsbCgiNi4yIiwgYmluYXJ5Q29udGVudFR5cGUuZ2V0QmFzZVR5cGUoKSk7CgoJCUlDb250ZW50VHlwZVtdIGJpbmFyeVR5cGVzID0gZmluZGVyLmZpbmRDb250ZW50VHlwZXNGb3IoY2hhbmdlQ2FzZSgiZm9vLnNhbXBsZWJpbjEiKSk7CgkJYXNzZXJ0RXF1YWxzKCI3LjAiLCAxLCBiaW5hcnlUeXBlcy5sZW5ndGgpOwoJCWFzc2VydEVxdWFscygiNy4xIiwgYmluYXJ5Q29udGVudFR5cGUsIGJpbmFyeVR5cGVzWzBdKTsKCgkJSUNvbnRlbnRUeXBlIG15VGV4dCA9IGNvbnRlbnRUeXBlTWFuYWdlci5nZXRDb250ZW50VHlwZShQSV9SRVNPVVJDRVNfVEVTVFMgKyAiLm15dGV4dCIpOwoJCWFzc2VydE5vdE51bGwoIjguMCIsIG15VGV4dCk7CgkJYXNzZXJ0RXF1YWxzKCI4LjEiLCAiQkFSIiwgbXlUZXh0LmdldERlZmF1bHRDaGFyc2V0KCkpOwoKCQlJQ29udGVudFR5cGVbXSBmb29CYXJUeXBlcyA9IGZpbmRlci5maW5kQ29udGVudFR5cGVzRm9yKGNoYW5nZUNhc2UoImZvby5iYXIiKSk7CgkJYXNzZXJ0RXF1YWxzKCI5LjAiLCAyLCBmb29CYXJUeXBlcy5sZW5ndGgpOwoKCQlJQ29udGVudFR5cGUgZm9vQmFyID0gY29udGVudFR5cGVNYW5hZ2VyLmdldENvbnRlbnRUeXBlKFBJX1JFU09VUkNFU19URVNUUyArICIuZm9vQmFyIik7CgkJYXNzZXJ0Tm90TnVsbCgiOS4xIiwgZm9vQmFyKTsKCQlJQ29udGVudFR5cGUgc3ViRm9vQmFyID0gY29udGVudFR5cGVNYW5hZ2VyLmdldENvbnRlbnRUeXBlKFBJX1JFU09VUkNFU19URVNUUyArICIuc3ViRm9vQmFyIik7CgkJYXNzZXJ0Tm90TnVsbCgiOS4yIiwgc3ViRm9vQmFyKTsKCQlhc3NlcnRUcnVlKCI5LjMiLCBjb250YWlucyhmb29CYXJUeXBlcywgZm9vQmFyKSk7CgkJYXNzZXJ0VHJ1ZSgiOS40IiwgY29udGFpbnMoZm9vQmFyVHlwZXMsIHN1YkZvb0JhcikpOwoJfQoKCXB1YmxpYyB2b2lkIHRlc3RSb290RWxlbWVudEFuZERURERlc2NyaWJlcigpIHRocm93cyBJT0V4Y2VwdGlvbiB7CgkJSUNvbnRlbnRUeXBlTWFuYWdlciBjb250ZW50VHlwZU1hbmFnZXIgPSBQbGF0Zm9ybS5nZXRDb250ZW50VHlwZU1hbmFnZXIoKTsKCQlJQ29udGVudFR5cGUgcm9vdEVsZW1lbnQgPSBjb250ZW50VHlwZU1hbmFnZXIuZ2V0Q29udGVudFR5cGUoUElfUkVTT1VSQ0VTX1RFU1RTICsgIi5yb290LWVsZW1lbnQiKTsKCQlJQ29udGVudFR5cGUgZHRkRWxlbWVudCA9IGNvbnRlbnRUeXBlTWFuYWdlci5nZXRDb250ZW50VHlwZShQSV9SRVNPVVJDRVNfVEVTVFMgKyAiLmR0ZCIpOwoJCUlDb250ZW50VHlwZSBuc1Jvb3RFbGVtZW50ID0gY29udGVudFR5cGVNYW5hZ2VyLmdldENvbnRlbnRUeXBlKFBJX1JFU09VUkNFU19URVNUUyArICIubnMtcm9vdC1lbGVtZW50Iik7CgkJSUNvbnRlbnRUeXBlIG5zV2lsZGNhcmQgPSBjb250ZW50VHlwZU1hbmFnZXIuZ2V0Q29udGVudFR5cGUoUElfUkVTT1VSQ0VTX1RFU1RTICsgIi5ucy13aWxkY2FyZCIpOwoJCUlDb250ZW50VHlwZSBlbXB0eU5zUm9vdEVsZW1lbnQgPSBjb250ZW50VHlwZU1hbmFnZXIuZ2V0Q29udGVudFR5cGUoUElfUkVTT1VSQ0VTX1RFU1RTICsgIi5lbXB0eS1ucy1yb290LWVsZW1lbnQiKTsKCQlJQ29udGVudFR5cGUgeG1sVHlwZSA9IGNvbnRlbnRUeXBlTWFuYWdlci5nZXRDb250ZW50VHlwZShQbGF0Zm9ybS5QSV9SVU5USU1FICsgIi54bWwiKTsKCgkJSUNvbnRlbnRUeXBlW10gY29udGVudFR5cGVzID0gY29udGVudFR5cGVNYW5hZ2VyLmZpbmRDb250ZW50VHlwZXNGb3IoZ2V0SW5wdXRTdHJlYW0oWE1MX1JPT1RfRUxFTUVOVF9JU09fODg1OV8xLCAiSVNPLTg4NTktMSIpLCAiZmFrZS54bWwiKTsKCQlhc3NlcnRUcnVlKCIxLjAiLCBjb250ZW50VHlwZXMubGVuZ3RoID4gMCk7CgkJYXNzZXJ0RXF1YWxzKCIxLjEiLCByb290RWxlbWVudCwgY29udGVudFR5cGVzWzBdKTsKCgkJLy8gYnVncyA2NDA1MyBhbmQgNjMyOTgKCQljb250ZW50VHlwZXMgPSBjb250ZW50VHlwZU1hbmFnZXIuZmluZENvbnRlbnRUeXBlc0ZvcihnZXRJbnB1dFN0cmVhbShYTUxfUk9PVF9FTEVNRU5UX0VYVEVSTkFMX0VOVElUWSwgIlVURi04IiksICJmYWtlLnhtbCIpOwoJCWFzc2VydFRydWUoIjIuMCIsIGNvbnRlbnRUeXBlcy5sZW5ndGggPiAwKTsKCQlhc3NlcnRFcXVhbHMoIjIuMSIsIHJvb3RFbGVtZW50LCBjb250ZW50VHlwZXNbMF0pOwoKCQkvLyBidWcgNjM2MjUKCQljb250ZW50VHlwZXMgPSBjb250ZW50VHlwZU1hbmFnZXIuZmluZENvbnRlbnRUeXBlc0ZvcihnZXRJbnB1dFN0cmVhbShYTUxfUk9PVF9FTEVNRU5UX0VYVEVSTkFMX0VOVElUWTIsICJVVEYtOCIpLCAiZmFrZS54bWwiKTsKCQlhc3NlcnRUcnVlKCIzLjAiLCBjb250ZW50VHlwZXMubGVuZ3RoID4gMCk7CgkJYXNzZXJ0RXF1YWxzKCIzLjEiLCByb290RWxlbWVudCwgY29udGVudFR5cGVzWzBdKTsKCgkJLy8gYnVnIDEzNTU3NQoJCWNvbnRlbnRUeXBlcyA9IGNvbnRlbnRUeXBlTWFuYWdlci5maW5kQ29udGVudFR5cGVzRm9yKGdldElucHV0U3RyZWFtKFhNTF9ST09UX0VMRU1FTlRfTlNfTUFUQ0gxLCAiVVRGLTgiKSwgImZha2UueG1sIik7CgkJYXNzZXJ0VHJ1ZSgiNC4wIiwgY29udGVudFR5cGVzLmxlbmd0aCA+IDApOwoJCWFzc2VydEVxdWFscygiNC4xIiwgbnNSb290RWxlbWVudCwgY29udGVudFR5cGVzWzBdKTsKCQljb250ZW50VHlwZXMgPSBjb250ZW50VHlwZU1hbmFnZXIuZmluZENvbnRlbnRUeXBlc0ZvcihnZXRJbnB1dFN0cmVhbShYTUxfUk9PVF9FTEVNRU5UX05TX01BVENIMiwgIlVURi04IiksICJmYWtlLnhtbCIpOwoJCWFzc2VydFRydWUoIjQuMiIsIGNvbnRlbnRUeXBlcy5sZW5ndGggPiAwKTsKCQlhc3NlcnRFcXVhbHMoIjQuMyIsIG5zUm9vdEVsZW1lbnQsIGNvbnRlbnRUeXBlc1swXSk7CgkJY29udGVudFR5cGVzID0gY29udGVudFR5cGVNYW5hZ2VyLmZpbmRDb250ZW50VHlwZXNGb3IoZ2V0SW5wdXRTdHJlYW0oWE1MX1JPT1RfRUxFTUVOVF9OU19XUk9OR19FTEVNLCAiVVRGLTgiKSwgImZha2UueG1sIik7CgkJYXNzZXJ0VHJ1ZSgiNC40IiwgY29udGVudFR5cGVzLmxlbmd0aCA+IDApOwoJCWFzc2VydEVxdWFscygiNC41IiwgeG1sVHlwZSwgY29udGVudFR5cGVzWzBdKTsKCQljb250ZW50VHlwZXMgPSBjb250ZW50VHlwZU1hbmFnZXIuZmluZENvbnRlbnRUeXBlc0ZvcihnZXRJbnB1dFN0cmVhbShYTUxfUk9PVF9FTEVNRU5UX05TX1dST05HX05TLCAiVVRGLTgiKSwgImZha2UueG1sIik7CgkJYXNzZXJ0VHJ1ZSgiNC42IiwgY29udGVudFR5cGVzLmxlbmd0aCA+IDApOwoJCWFzc2VydEVxdWFscygiNC43IiwgeG1sVHlwZSwgY29udGVudFR5cGVzWzBdKTsKCQljb250ZW50VHlwZXMgPSBjb250ZW50VHlwZU1hbmFnZXIuZmluZENvbnRlbnRUeXBlc0ZvcihnZXRJbnB1dFN0cmVhbShYTUxfUk9PVF9FTEVNRU5UX05TX01JWFVQLCAiVVRGLTgiKSwgImZha2UueG1sIik7CgkJYXNzZXJ0VHJ1ZSgiNC44IiwgY29udGVudFR5cGVzLmxlbmd0aCA+IDApOwoJCWFzc2VydEVxdWFscygiNC45IiwgeG1sVHlwZSwgY29udGVudFR5cGVzWzBdKTsKCQljb250ZW50VHlwZXMgPSBjb250ZW50VHlwZU1hbmFnZXIuZmluZENvbnRlbnRUeXBlc0ZvcihnZXRJbnB1dFN0cmVhbShYTUxfUk9PVF9FTEVNRU5UX05TX1dJTERDQVJELCAiVVRGLTgiKSwgImZha2UueG1sIik7CgkJYXNzZXJ0VHJ1ZSgiNC4xMCIsIGNvbnRlbnRUeXBlcy5sZW5ndGggPiAwKTsKCQlhc3NlcnRFcXVhbHMoIjQuMTEiLCBuc1dpbGRjYXJkLCBjb250ZW50VHlwZXNbMF0pOwoJCWNvbnRlbnRUeXBlcyA9IGNvbnRlbnRUeXBlTWFuYWdlci5maW5kQ29udGVudFR5cGVzRm9yKGdldElucHV0U3RyZWFtKFhNTF9ST09UX0VMRU1FTlRfTlNfV0lMRENBUkQyLCAiVVRGLTgiKSwgImZha2UueG1sIik7CgkJYXNzZXJ0VHJ1ZSgiNC4xMiIsIGNvbnRlbnRUeXBlcy5sZW5ndGggPiAwKTsKCQlhc3NlcnRFcXVhbHMoIjQuMTMiLCBuc1dpbGRjYXJkLCBjb250ZW50VHlwZXNbMF0pOwoJCWNvbnRlbnRUeXBlcyA9IGNvbnRlbnRUeXBlTWFuYWdlci5maW5kQ29udGVudFR5cGVzRm9yKGdldElucHV0U3RyZWFtKFhNTF9ST09UX0VMRU1FTlRfRU1QVFlfTlMsICJVVEYtOCIpLCAiZmFrZS54bWwiKTsKCQlhc3NlcnRUcnVlKCI0LjE0IiwgY29udGVudFR5cGVzLmxlbmd0aCA+IDApOwoJCWFzc2VydEVxdWFscygiNC4xNSIsIGVtcHR5TnNSb290RWxlbWVudCwgY29udGVudFR5cGVzWzBdKTsKCgkJY29udGVudFR5cGVzID0gY29udGVudFR5cGVNYW5hZ2VyLmZpbmRDb250ZW50VHlwZXNGb3IoZ2V0SW5wdXRTdHJlYW0oWE1MX0RURF9VU19BU0NJSSwgIlVTLUFTQ0lJIiksICJmYWtlLnhtbCIpOwoJCWFzc2VydFRydWUoIjUuMCIsIGNvbnRlbnRUeXBlcy5sZW5ndGggPiAwKTsKCQlhc3NlcnRFcXVhbHMoIjUuMSIsIGR0ZEVsZW1lbnQsIGNvbnRlbnRUeXBlc1swXSk7CgkJY29udGVudFR5cGVzID0gY29udGVudFR5cGVNYW5hZ2VyLmZpbmRDb250ZW50VHlwZXNGb3IoZ2V0SW5wdXRTdHJlYW0oWE1MX0RURF9FWFRFUk5BTF9FTlRJVFksICJVVEYtOCIpLCAiZmFrZS54bWwiKTsKCQlhc3NlcnRUcnVlKCI1LjQiLCBjb250ZW50VHlwZXMubGVuZ3RoID4gMCk7CgkJYXNzZXJ0RXF1YWxzKCI1LjUiLCBkdGRFbGVtZW50LCBjb250ZW50VHlwZXNbMF0pOwoKCQkvLyBidWcgNjc5NzUKCQlJQ29udGVudERlc2NyaXB0aW9uIGRlc2NyaXB0aW9uID0gY29udGVudFR5cGVNYW5hZ2VyLmdldERlc2NyaXB0aW9uRm9yKGdldElucHV0U3RyZWFtKG5ldyBieXRlW11bXSB7SUNvbnRlbnREZXNjcmlwdGlvbi5CT01fVVRGXzE2QkUsIFhNTF9ST09UX0VMRU1FTlRfTk9fREVDTC5nZXRCeXRlcygiVVRGLTE2QkUiKX0pLCAiZmFrZS54bWwiLCBJQ29udGVudERlc2NyaXB0aW9uLkFMTCk7CgkJYXNzZXJ0VHJ1ZSgiNi4wIiwgZGVzY3JpcHRpb24gIT0gbnVsbCk7CgkJYXNzZXJ0RXF1YWxzKCI2LjEiLCByb290RWxlbWVudCwgZGVzY3JpcHRpb24uZ2V0Q29udGVudFR5cGUoKSk7CgkJYXNzZXJ0RXF1YWxzKCI2LjIiLCBJQ29udGVudERlc2NyaXB0aW9uLkJPTV9VVEZfMTZCRSwgZGVzY3JpcHRpb24uZ2V0UHJvcGVydHkoSUNvbnRlbnREZXNjcmlwdGlvbi5CWVRFX09SREVSX01BUkspKTsKCgkJZGVzY3JpcHRpb24gPSBjb250ZW50VHlwZU1hbmFnZXIuZ2V0RGVzY3JpcHRpb25Gb3IoZ2V0SW5wdXRTdHJlYW0obmV3IGJ5dGVbXVtdIHtJQ29udGVudERlc2NyaXB0aW9uLkJPTV9VVEZfMTZMRSwgWE1MX1JPT1RfRUxFTUVOVF9OT19ERUNMLmdldEJ5dGVzKCJVVEYtMTZMRSIpfSksICJmYWtlLnhtbCIsIElDb250ZW50RGVzY3JpcHRpb24uQUxMKTsKCQlhc3NlcnRUcnVlKCI3LjAiLCBkZXNjcmlwdGlvbiAhPSBudWxsKTsKCQlhc3NlcnRFcXVhbHMoIjcuMSIsIHJvb3RFbGVtZW50LCBkZXNjcmlwdGlvbi5nZXRDb250ZW50VHlwZSgpKTsKCQlhc3NlcnRFcXVhbHMoIjcuMiIsIElDb250ZW50RGVzY3JpcHRpb24uQk9NX1VURl8xNkxFLCBkZXNjcmlwdGlvbi5nZXRQcm9wZXJ0eShJQ29udGVudERlc2NyaXB0aW9uLkJZVEVfT1JERVJfTUFSSykpOwoKCQkvLyBkdWUgdG8gYnVnIDY3MDQ4LCB0aGUgdGVzdCBiZWxvdyBmYWlscyB3aXRoIENyaW1zb24gcGFyc2VyIChkb2VzIG5vdCBoYW5kbGUgVVRGLTggQk9NcykKCQkvLwkJZGVzY3JpcHRpb24gPSBjb250ZW50VHlwZU1hbmFnZXIuZ2V0RGVzY3JpcHRpb25Gb3IoZ2V0SW5wdXRTdHJlYW0obmV3IGJ5dGVbXVtdIHtJQ29udGVudERlc2NyaXB0aW9uLkJPTV9VVEZfOCxYTUxfUk9PVF9FTEVNRU5UX05PX0RFQ0wuZ2V0Qnl0ZXMoIlVURi04Iil9KSwgImZha2UueG1sIiwgSUNvbnRlbnREZXNjcmlwdGlvbi5BTEwpOwoJCS8vCQlhc3NlcnRUcnVlKCI3LjAiLCBkZXNjcmlwdGlvbiAhPSBudWxsKTsKCQkvLwkJYXNzZXJ0RXF1YWxzKCI3LjEiLCByb290RWxlbWVudCwgZGVzY3JpcHRpb24uZ2V0Q29udGVudFR5cGUoKSk7CgkJLy8JCWFzc2VydEVxdWFscygiNy4yIiwgSUNvbnRlbnREZXNjcmlwdGlvbi5CT01fVVRGXzgsIGRlc2NyaXB0aW9uLmdldFByb3BlcnR5KElDb250ZW50RGVzY3JpcHRpb24uQllURV9PUkRFUl9NQVJLKSk7CgoJCS8vIGJ1ZyA4NDM1NAoJCWNvbnRlbnRUeXBlcyA9IGNvbnRlbnRUeXBlTWFuYWdlci5maW5kQ29udGVudFR5cGVzRm9yKGdldElucHV0U3RyZWFtKFhNTF9ST09UX0VMRU1FTlRfTk9fREVDTCwgIlVURi04IiksICJ0ZXN0LnR4dCIpOwoJCWFzc2VydFRydWUoIjguMCIsIGNvbnRlbnRUeXBlcy5sZW5ndGggPiAwKTsKCQlhc3NlcnRFcXVhbHMoIjguMSIsIGNvbnRlbnRUeXBlTWFuYWdlci5nZXRDb250ZW50VHlwZShJQ29udGVudFR5cGVNYW5hZ2VyLkNUX1RFWFQpLCBjb250ZW50VHlwZXNbMF0pOwoJfQoKCS8qKgoJICogQnVnIDY2OTc2CgkgKi8KCXB1YmxpYyB2b2lkIHRlc3RTaWduYXR1cmVCZXlvbmRCdWZmZXJMaW1pdCgpIHRocm93cyBJT0V4Y2VwdGlvbiB7CgkJaW50IGJ1ZmZlckxpbWl0ID0gQ29udGVudFR5cGVNYW5hZ2VyLkJMT0NLX1NJWkUgKiA0OwoJCS8vIGNyZWF0ZSBhIGxvbmcgWE1MIGNvbW1lbnQgYXMgcHJlZml4CgkJU3RyaW5nQnVmZmVyIGNvbW1lbnQgPSBuZXcgU3RyaW5nQnVmZmVyKCI8IS0tIik7CgkJZm9yIChpbnQgaSA9IDA7IGkgPCBidWZmZXJMaW1pdDsgaSsrKSB7CgkJCWNvbW1lbnQuYXBwZW5kKCcqJyk7CgkJfQoJCWNvbW1lbnQuYXBwZW5kKCItLT4iKTsKCQlJQ29udGVudFR5cGVNYW5hZ2VyIG1hbmFnZXIgPSBQbGF0Zm9ybS5nZXRDb250ZW50VHlwZU1hbmFnZXIoKTsKCQlJQ29udGVudFR5cGUgcm9vdEVsZW1lbnQgPSBtYW5hZ2VyLmdldENvbnRlbnRUeXBlKFBJX1JFU09VUkNFU19URVNUUyArICIucm9vdC1lbGVtZW50Iik7CgkJSUNvbnRlbnRUeXBlIHNlbGVjdGVkID0gbWFuYWdlci5maW5kQ29udGVudFR5cGVGb3IoZ2V0SW5wdXRTdHJlYW0oY29tbWVudCArIFhNTF9ST09UX0VMRU1FTlRfTk9fREVDTCwgIlVTLUFTQ0lJIiksICJmYWtlLnhtbCIpOwoJCWFzc2VydE5vdE51bGwoIjEuMCIsIHNlbGVjdGVkKTsKCQlhc3NlcnRFcXVhbHMoIjEuMSIsIHJvb3RFbGVtZW50LCBzZWxlY3RlZCk7Cgl9CgoJLyoqCgkgKiBTZWUgYWxzbzogYnVnIDcyNzk2LgoJICovCglwdWJsaWMgdm9pZCB0ZXN0VXNlckRlZmluZWRBc3NvY2lhdGlvbnMoKSB7CgkJSUNvbnRlbnRUeXBlTWFuYWdlciBtYW5hZ2VyID0gUGxhdGZvcm0uZ2V0Q29udGVudFR5cGVNYW5hZ2VyKCk7CgkJSUNvbnRlbnRUeXBlIHRleHQgPSBtYW5hZ2VyLmdldENvbnRlbnRUeXBlKChQbGF0Zm9ybS5QSV9SVU5USU1FICsgIi50ZXh0IikpOwoKCQlhc3NlcnROdWxsKCIwLjEiLCBtYW5hZ2VyLmZpbmRDb250ZW50VHlwZUZvcigidGVzdC5teXRleHQiKSk7CgkJLy8gYXNzb2NpYXRlIGEgdXNlci1kZWZpbmVkIGZpbGUgc3BlYwoJCXRyeSB7CgkJCXRleHQuYWRkRmlsZVNwZWMoIm15dGV4dCIsIElDb250ZW50VHlwZS5GSUxFX0VYVEVOU0lPTl9TUEVDKTsKCQl9IGNhdGNoIChDb3JlRXhjZXB0aW9uIGUpIHsKCQkJZmFpbCgiMS4wIiwgZSk7CgkJfQoJCWJvb2xlYW4gYXNzZXJ0aW9uRmFpbGVkID0gZmFsc2U7CgkJdHJ5IHsKCQkJSUNvbnRlbnRUeXBlIHJlc3VsdCA9IG1hbmFnZXIuZmluZENvbnRlbnRUeXBlRm9yKCJ0ZXN0Lm15dGV4dCIpOwoJCQlhc3NlcnROb3ROdWxsKCIxLjEiLCByZXN1bHQpOwoJCQlhc3NlcnRFcXVhbHMoIjEuMiIsIHRleHQsIHJlc3VsdCk7CgkJfSBjYXRjaCAoQXNzZXJ0aW9uRmFpbGVkRXJyb3IgYWZlKSB7CgkJCWFzc2VydGlvbkZhaWxlZCA9IHRydWU7CgkJCXRocm93IGFmZTsKCQl9IGZpbmFsbHkgewoJCQl0cnkgewoJCQkJdGV4dC5yZW1vdmVGaWxlU3BlYygibXl0ZXh0IiwgSUNvbnRlbnRUeXBlLkZJTEVfRVhURU5TSU9OX1NQRUMpOwoJCQl9IGNhdGNoIChDb3JlRXhjZXB0aW9uIGUpIHsKCQkJCWlmICghYXNzZXJ0aW9uRmFpbGVkKSB7CgkJCQkJZmFpbCgiIDIuMCIsIGUpOwoJCQkJfQoJCQl9CgkJfQoJCUlDb250ZW50VHlwZSByZXN1bHQgPSBtYW5hZ2VyLmZpbmRDb250ZW50VHlwZUZvcigidGVzdC5teXRleHQiKTsKCQlhc3NlcnROdWxsKCIzLjAiLCByZXN1bHQpOwoJfQoKCXB1YmxpYyB2b2lkIHRlc3REZXNjcmliZXJJbnZhbGlkYXRpb24oKSB0aHJvd3MgVW5zdXBwb3J0ZWRFbmNvZGluZ0V4Y2VwdGlvbiwgSU9FeGNlcHRpb24gewoJCUlDb250ZW50VHlwZU1hbmFnZXIgY29udGVudFR5cGVNYW5hZ2VyID0gUGxhdGZvcm0uZ2V0Q29udGVudFR5cGVNYW5hZ2VyKCk7CgkJSUNvbnRlbnRUeXBlIHR5cGVfYnVnMTgyMzM3X0EgPSBjb250ZW50VHlwZU1hbmFnZXIuZ2V0Q29udGVudFR5cGUoUElfUkVTT1VSQ0VTX1RFU1RTICsgIi5CdWcxODIzMzdfQSIpOwoJCUlDb250ZW50VHlwZSB0eXBlX2J1ZzE4MjMzN19CID0gY29udGVudFR5cGVNYW5hZ2VyLmdldENvbnRlbnRUeXBlKFBJX1JFU09VUkNFU19URVNUUyArICIuQnVnMTgyMzM3X0IiKTsKCgkJSUNvbnRlbnRUeXBlW10gY29udGVudFR5cGVzID0gY29udGVudFR5cGVNYW5hZ2VyLmZpbmRDb250ZW50VHlwZXNGb3IoZ2V0SW5wdXRTdHJlYW0oWE1MX1JPT1RfRUxFTUVOVF9OU19NQVRDSDIsICJVVEYtOCIpLCAiQnVnMTgyMzM3LkJ1ZzE4MjMzNyIpOwoJCWFzc2VydFRydWUoIjEuMCIsIGNvbnRlbnRUeXBlcy5sZW5ndGggPT0gMik7CgkJYXNzZXJ0RXF1YWxzKCIxLjEiLCB0eXBlX2J1ZzE4MjMzN19BLCBjb250ZW50VHlwZXNbMF0pOwoJCWFzc2VydEVxdWFscygiMS4xIiwgdHlwZV9idWcxODIzMzdfQiwgY29udGVudFR5cGVzWzFdKTsKCgkJSW5wdXRTdHJlYW0gaXMgPSBuZXcgSW5wdXRTdHJlYW0oKSB7CgkJCUBPdmVycmlkZQoJCQlwdWJsaWMgaW50IHJlYWQoKSB7CgkJCQkvLyB0aHJvdyBhIG5vbiBjaGVja2VkIGV4Y2VwdGlvbiB0byBlbXVsYXRlIGEgcHJvYmxlbSB3aXRoIHRoZSBkZXNjcmliZXIgaXRzZWxmCgkJCQl0aHJvdyBuZXcgUnVudGltZUV4Y2VwdGlvbigpOwoJCQl9CgkJfTsKCQljb250ZW50VHlwZXMgPSBjb250ZW50VHlwZU1hbmFnZXIuZmluZENvbnRlbnRUeXBlc0ZvcihpcywgIkJ1ZzE4MjMzNy5CdWcxODIzMzciKTsKCQlhc3NlcnRUcnVlKCIxLjIiLCBjb250ZW50VHlwZXMubGVuZ3RoID09IDApOwoKCQkvLyBEZXNjcmliZXIgc2hvdWxkIGJlIGludmFsaWRhdGVkIGJ5IG5vdwoJCWNvbnRlbnRUeXBlcyA9IGNvbnRlbnRUeXBlTWFuYWdlci5maW5kQ29udGVudFR5cGVzRm9yKGdldElucHV0U3RyZWFtKFhNTF9ST09UX0VMRU1FTlRfTlNfTUFUQ0gyLCAiVVRGLTgiKSwgIkJ1ZzE4MjMzNy5CdWcxODIzMzciKTsKCQlhc3NlcnRUcnVlKCIxLjMiLCBjb250ZW50VHlwZXMubGVuZ3RoID09IDApOwoJfQoKfQo=