LyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogQ29weXJpZ2h0IChjKSAyMDA0LCAyMDE4IElCTSBDb3Jwb3JhdGlvbiBhbmQgb3RoZXJzLgogKiBBbGwgcmlnaHRzIHJlc2VydmVkLiBUaGlzIHByb2dyYW0gYW5kIHRoZSBhY2NvbXBhbnlpbmcgbWF0ZXJpYWxzCiAqIGFyZSBtYWRlIGF2YWlsYWJsZSB1bmRlciB0aGUgdGVybXMgb2YgdGhlIEVjbGlwc2UgUHVibGljIExpY2Vuc2UgdjEuMAogKiB3aGljaCBhY2NvbXBhbmllcyB0aGlzIGRpc3RyaWJ1dGlvbiwgYW5kIGlzIGF2YWlsYWJsZSBhdAogKiBodHRwOi8vd3d3LmVjbGlwc2Uub3JnL2xlZ2FsL2VwbC12MTAuaHRtbAogKgogKiBDb250cmlidXRvcnM6CiAqICAgICBJQk0gQ29ycG9yYXRpb24gLSBpbml0aWFsIEFQSSBhbmQgaW1wbGVtZW50YXRpb24KICogICAgIE1pY2thZWwgSXN0cmlhIChSZWQgSGF0IEluYy4pIC0gWzI2MzMxNl0gcmVnZXhwIGZvciBmaWxlIGFzc29jaWF0aW9uCiAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwpwYWNrYWdlIG9yZy5lY2xpcHNlLmNvcmUudGVzdHMucmVzb3VyY2VzLmNvbnRlbnQ7CgppbXBvcnQgamF2YS5pby4qOwppbXBvcnQgamF2YS5uaW8uY2hhcnNldC5DaGFyc2V0OwppbXBvcnQgamF2YS5uaW8uY2hhcnNldC5TdGFuZGFyZENoYXJzZXRzOwppbXBvcnQgamF2YS51dGlsLkhhc2hTZXQ7CmltcG9ydCBqYXZhLnV0aWwuU2V0OwppbXBvcnQganVuaXQuZnJhbWV3b3JrLkFzc2VydGlvbkZhaWxlZEVycm9yOwppbXBvcnQganVuaXQuZnJhbWV3b3JrLlRlc3Q7CmltcG9ydCBvcmcuZWNsaXBzZS5jb3JlLmludGVybmFsLmNvbnRlbnQuKjsKaW1wb3J0IG9yZy5lY2xpcHNlLmNvcmUucnVudGltZS4qOwppbXBvcnQgb3JnLmVjbGlwc2UuY29yZS5ydW50aW1lLmNvbnRlbnQuKjsKaW1wb3J0IG9yZy5lY2xpcHNlLmNvcmUucnVudGltZS5jb250ZW50LklDb250ZW50VHlwZU1hbmFnZXIuQ29udGVudFR5cGVDaGFuZ2VFdmVudDsKaW1wb3J0IG9yZy5lY2xpcHNlLmNvcmUucnVudGltZS5jb250ZW50LlhNTENvbnRlbnREZXNjcmliZXI7CmltcG9ydCBvcmcuZWNsaXBzZS5jb3JlLnJ1bnRpbWUuam9icy5Kb2I7CmltcG9ydCBvcmcuZWNsaXBzZS5jb3JlLnJ1bnRpbWUucHJlZmVyZW5jZXMuKjsKaW1wb3J0IG9yZy5lY2xpcHNlLmNvcmUudGVzdHMuaGFybmVzcy5CdW5kbGVUZXN0aW5nSGVscGVyOwppbXBvcnQgb3JnLmVjbGlwc2UuY29yZS50ZXN0cy5oYXJuZXNzLlRlc3RSZWdpc3RyeUNoYW5nZUxpc3RlbmVyOwppbXBvcnQgb3JnLmVjbGlwc2UudGVzdC5PcmRlcmVkVGVzdFN1aXRlOwppbXBvcnQgb3JnLm9zZ2kuc2VydmljZS5wcmVmcy5CYWNraW5nU3RvcmVFeGNlcHRpb247CmltcG9ydCBvcmcub3NnaS5zZXJ2aWNlLnByZWZzLlByZWZlcmVuY2VzOwoKcHVibGljIGNsYXNzIElDb250ZW50VHlwZU1hbmFnZXJUZXN0IGV4dGVuZHMgQ29udGVudFR5cGVUZXN0IHsKCglwcml2YXRlIHN0YXRpYyBjbGFzcyBDb250ZW50VHlwZUNoYW5nZVRyYWNlciBpbXBsZW1lbnRzIElDb250ZW50VHlwZU1hbmFnZXIuSUNvbnRlbnRUeXBlQ2hhbmdlTGlzdGVuZXIgewoJCXByaXZhdGUgZmluYWwgU2V0PElDb250ZW50VHlwZT4gY2hhbmdlZCA9IG5ldyBIYXNoU2V0PD4oKTsKCgkJcHVibGljIENvbnRlbnRUeXBlQ2hhbmdlVHJhY2VyKCkgewoJCX0KCgkJQE92ZXJyaWRlCgkJcHVibGljIHZvaWQgY29udGVudFR5cGVDaGFuZ2VkKENvbnRlbnRUeXBlQ2hhbmdlRXZlbnQgZXZlbnQpIHsKCQkJY2hhbmdlZC5hZGQoZXZlbnQuZ2V0Q29udGVudFR5cGUoKSk7CgkJfQoKCQlwdWJsaWMgYm9vbGVhbiBpc09ubHlDaGFuZ2UoSUNvbnRlbnRUeXBlIG15VHlwZSkgewoJCQlyZXR1cm4gY2hhbmdlZC5zaXplKCkgPT0gMSAmJiBjaGFuZ2VkLmNvbnRhaW5zKG15VHlwZSk7CgkJfQoKCQlwdWJsaWMgdm9pZCByZXNldCgpIHsKCQkJY2hhbmdlZC5jbGVhcigpOwoJCX0KCX0KCgkvLyBYWFggdGhpcyBpcyBjb3BpZWQgZnJvbSBDaGFyc2V0RGVsdGFKb2IgaW4gdGhlIHJlc291cmNlcyBwbHVnLWluCglwcml2YXRlIHN0YXRpYyBmaW5hbCBTdHJpbmcgRkFNSUxZX0NIQVJTRVRfREVMVEEgPSAib3JnLmVjbGlwc2UuY29yZS5yZXNvdXJjZXMuY2hhcnNldEpvYkZhbWlseSI7CgoJcHJpdmF0ZSBmaW5hbCBzdGF0aWMgU3RyaW5nIE1JTklNQUxfWE1MID0gIjw/eG1sIHZlcnNpb249XCIxLjBcIj8+PG9yZy5lY2xpcHNlLmNvcmUucmVzb3VyY2VzLnRlc3RzLnJvb3QvPiI7Cglwcml2YXRlIGZpbmFsIHN0YXRpYyBTdHJpbmcgU0FNUExFX0JJTjFfT0ZGU0VUID0gIjEyMzQ1IjsKCXByaXZhdGUgZmluYWwgc3RhdGljIGJ5dGVbXSBTQU1QTEVfQklOMV9TSUdOQVRVUkUgPSB7MHgxMCwgKGJ5dGUpIDB4QUIsIChieXRlKSAweENELCAoYnl0ZSkgMHhGRn07Cglwcml2YXRlIGZpbmFsIHN0YXRpYyBTdHJpbmcgU0FNUExFX0JJTjJfT0ZGU0VUID0gIiI7Cglwcml2YXRlIGZpbmFsIHN0YXRpYyBieXRlW10gU0FNUExFX0JJTjJfU0lHTkFUVVJFID0gezB4MTAsIChieXRlKSAweEFCLCAoYnl0ZSkgMHhDRCwgKGJ5dGUpIDB4RUZ9OwoJcHJpdmF0ZSBmaW5hbCBzdGF0aWMgU3RyaW5nIFhNTF9EVERfRVhURVJOQUxfRU5USVRZID0gIjw/eG1sIHZlcnNpb249XCIxLjBcIj8+PCFET0NUWVBFIHByb2plY3QgIFNZU1RFTSBcIm9yZy5lY2xpcHNlLmNvcmUucmVzb3VyY2VzLnRlc3RzLnNvbWUuZHRkXCIgIFs8IUVOVElUWSBzb21lZW50aXR5IFNZU1RFTSBcInNvbWVlbnRpdHkueG1sXCI+XT48b3JnLmVjbGlwc2UuY29yZS5yZXNvdXJjZXMudGVzdHMucm9vdC8+IjsKCXByaXZhdGUgZmluYWwgc3RhdGljIFN0cmluZyBYTUxfRFREX1VTX0FTQ0lJID0gIjw/eG1sIHZlcnNpb249XCIxLjBcIiBlbmNvZGluZz1cIlVTLUFTQ0lJXCI/PjwhRE9DVFlQRSBzb21ldHlwZSBTWVNURU0gXCJvcmcuZWNsaXBzZS5jb3JlLnJlc291cmNlcy50ZXN0cy5zb21lLmR0ZFwiPjxvcmcuZWNsaXBzZS5jb3JlLnJlc291cmNlcy50ZXN0cy5yb290Lz4iOwoJcHJpdmF0ZSBmaW5hbCBzdGF0aWMgU3RyaW5nIFhNTF9JU09fODg1OV8xID0gIjw/eG1sIHZlcnNpb249XCIxLjBcIiBlbmNvZGluZz1cIklTTy04ODU5LTFcIj8+PG9yZy5lY2xpcHNlLmNvcmUucmVzb3VyY2VzLnRlc3RzLnJvb3QvPiI7Cglwcml2YXRlIGZpbmFsIHN0YXRpYyBTdHJpbmcgWE1MX0lTT184ODU5XzFfU0lOR0xFX1FVT1RFUyA9ICI8P3htbCB2ZXJzaW9uPScxLjAnIGVuY29kaW5nPSdJU08tODg1OS0xJz8+PG9yZy5lY2xpcHNlLmNvcmUucmVzb3VyY2VzLnRlc3RzLnJvb3QvPiI7Cglwcml2YXRlIGZpbmFsIHN0YXRpYyBTdHJpbmcgWE1MX1JPT1RfRUxFTUVOVF9FWFRFUk5BTF9FTlRJVFkgPSAiPD94bWwgdmVyc2lvbj1cIjEuMFwiPz48IURPQ1RZUEUgcHJvamVjdCAgIFs8IUVOVElUWSBzb21lZW50aXR5IFNZU1RFTSBcInNvbWVlbnRpdHkueG1sXCI+XT48b3JnLmVjbGlwc2UuY29yZS5yZXNvdXJjZXMudGVzdHMucm9vdC1lbGVtZW50Lz4iOwoJcHJpdmF0ZSBmaW5hbCBzdGF0aWMgU3RyaW5nIFhNTF9ST09UX0VMRU1FTlRfRVhURVJOQUxfRU5USVRZMiA9ICI8P3htbCB2ZXJzaW9uPVwiMS4wXCI/PjwhRE9DVFlQRSBvcmcuZWNsaXBzZS5jb3JlLnJlc291cmNlcy50ZXN0cy5yb290LWVsZW1lbnQgUFVCTElDIFwib3JnLmVjbGlwc2UuY29yZS5yZXNvdXJjZXMudGVzdHMucm9vdC1lbGVtZW50SWRcIiBcIm9yZy5lY2xpcHNlLmNvcmUucmVzb3VyY2VzLnRlc3RzLnJvb3QtZWxlbWVudC5kdGRcIiA+PG9yZy5lY2xpcHNlLmNvcmUucmVzb3VyY2VzLnRlc3RzLnJvb3QtZWxlbWVudC8+IjsKCXByaXZhdGUgZmluYWwgc3RhdGljIFN0cmluZyBYTUxfUk9PVF9FTEVNRU5UX0lTT184ODU5XzEgPSAiPD94bWwgdmVyc2lvbj1cIjEuMFwiIGVuY29kaW5nPVwiSVNPLTg4NTktMVwiPz48b3JnLmVjbGlwc2UuY29yZS5yZXNvdXJjZXMudGVzdHMucm9vdC1lbGVtZW50Lz4iOwoJcHJpdmF0ZSBmaW5hbCBzdGF0aWMgU3RyaW5nIFhNTF9ST09UX0VMRU1FTlRfTk9fREVDTCA9ICI8b3JnLmVjbGlwc2UuY29yZS5yZXNvdXJjZXMudGVzdHMucm9vdC1lbGVtZW50Lz4iOwoJcHJpdmF0ZSBmaW5hbCBzdGF0aWMgU3RyaW5nIFhNTF9VU19BU0NJSV9JTlZBTElEID0gIjw/eG1sIHZlcnNpb249JzEuMCcgZW5jb2Rpbmc9J3VzLWFzY2lpJz8+PCEtLSBOb24tQVNDSUkgY2hhcnM6IOHp7fP6IC0tPjxvcmcuZWNsaXBzZS5jb3JlLnJlc291cmNlcy50ZXN0cy5yb290Lz4iOwoJcHJpdmF0ZSBmaW5hbCBzdGF0aWMgU3RyaW5nIFhNTF9VVEZfMTYgPSAiPD94bWwgdmVyc2lvbj1cIjEuMFwiIGVuY29kaW5nPVwiVVRGLTE2XCI/PjxvcmcuZWNsaXBzZS5jb3JlLnJlc291cmNlcy50ZXN0cy5yb290Lz4iOwoJcHJpdmF0ZSBmaW5hbCBzdGF0aWMgU3RyaW5nIFhNTF9VVEZfMTZCRSA9ICI8P3htbCB2ZXJzaW9uPVwiMS4wXCIgZW5jb2Rpbmc9XCJVVEYtMTZCRVwiPz48b3JnLmVjbGlwc2UuY29yZS5yZXNvdXJjZXMudGVzdHMucm9vdC8+IjsKCXByaXZhdGUgZmluYWwgc3RhdGljIFN0cmluZyBYTUxfVVRGXzE2TEUgPSAiPD94bWwgdmVyc2lvbj1cIjEuMFwiIGVuY29kaW5nPVwiVVRGLTE2TEVcIj8+PG9yZy5lY2xpcHNlLmNvcmUucmVzb3VyY2VzLnRlc3RzLnJvb3QvPiI7Cglwcml2YXRlIGZpbmFsIHN0YXRpYyBTdHJpbmcgWE1MX1VURl84ID0gIjw/eG1sIHZlcnNpb249XCIxLjBcIiBlbmNvZGluZz1cIlVURi04XCI/PjxvcmcuZWNsaXBzZS5jb3JlLnJlc291cmNlcy50ZXN0cy5yb290Lz4iOwoKCS8vIHVzZWQgYWxzbyBieSBGaWxlUHJvcGVydHlUZXN0ZXJUZXN0CglwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBYTUxfUk9PVF9FTEVNRU5UX05TX01BVENIMSA9ICI8P3htbCB2ZXJzaW9uPVwiMS4wXCIgZW5jb2Rpbmc9XCJJU08tODg1OS0xXCI/PjxwcmVmaXg6cm9vdEVsZW1lbnQxIHhtbG5zOnByZWZpeD0ndXJuOmVjbGlwc2UuY29yZS5ydW50aW1lLm5zMScvPiI7CgoJcHJpdmF0ZSBzdGF0aWMgZmluYWwgU3RyaW5nIFhNTF9ST09UX0VMRU1FTlRfTlNfTUFUQ0gyID0gIjw/eG1sIHZlcnNpb249XCIxLjBcIiBlbmNvZGluZz1cIklTTy04ODU5LTFcIj8+PCFET0NUWVBFIHJvb3RFbGVtZW50MiBTWVNURU0gXCJvcmcuZWNsaXBzZS5jb3JlLnJlc291cmNlcy50ZXN0cy5ub3RoaW5nXCI+PHJvb3RFbGVtZW50MiB4bWxucz0ndXJuOmVjbGlwc2UuY29yZS5ydW50aW1lLm5zMicvPiI7Cglwcml2YXRlIHN0YXRpYyBmaW5hbCBTdHJpbmcgWE1MX1JPT1RfRUxFTUVOVF9OU19XUk9OR19FTEVNID0gIjw/eG1sIHZlcnNpb249XCIxLjBcIiBlbmNvZGluZz1cIklTTy04ODU5LTFcIj8+PHJvb3RFbGVtZW50MyB4bWxucz0ndXJuOmVjbGlwc2UuY29yZS5ydW50aW1lLm5zMicvPiI7Cglwcml2YXRlIHN0YXRpYyBmaW5hbCBTdHJpbmcgWE1MX1JPT1RfRUxFTUVOVF9OU19XUk9OR19OUyA9ICI8P3htbCB2ZXJzaW9uPVwiMS4wXCIgZW5jb2Rpbmc9XCJJU08tODg1OS0xXCI/PjxwcmVmaXg6cm9vdEVsZW1lbnQxIHhtbG5zPSdodHRwOi8vZXhhbXBsZS5jb20vJy8+IjsKCXByaXZhdGUgc3RhdGljIGZpbmFsIFN0cmluZyBYTUxfUk9PVF9FTEVNRU5UX05TX01JWFVQID0gIjw/eG1sIHZlcnNpb249XCIxLjBcIiBlbmNvZGluZz1cIklTTy04ODU5LTFcIj8+PHJvb3RFbGVtZW50MiB4bWxucz0ndXJuOmVjbGlwc2UuY29yZS5ydW50aW1lLm5zMScvPiI7Cglwcml2YXRlIHN0YXRpYyBmaW5hbCBTdHJpbmcgWE1MX1JPT1RfRUxFTUVOVF9OU19XSUxEQ0FSRCA9ICI8P3htbCB2ZXJzaW9uPVwiMS4wXCIgZW5jb2Rpbmc9XCJJU08tODg1OS0xXCI/Pjx3ZUNvdWxkUHV0QW55dGhpbmdIZXJlIHhtbG5zPSd1cm46ZWNsaXBzZS5jb3JlLnJ1bnRpbWUubnNXaWxkJy8+IjsKCXByaXZhdGUgZmluYWwgc3RhdGljIFN0cmluZyBYTUxfUk9PVF9FTEVNRU5UX05TX1dJTERDQVJEMiA9ICI8P3htbCB2ZXJzaW9uPVwiMS4wXCIgZW5jb2Rpbmc9XCJVUy1BU0NJSVwiPz48IURPQ1RZUEUgSm9rZXIgU1lTVEVNIFwib3JnLmVjbGlwc2UuY29yZS5yZXNvdXJjZXMudGVzdHMuc29tZS5kdGQzXCI+PEpva2VyLz4iOwoJcHJpdmF0ZSBmaW5hbCBzdGF0aWMgU3RyaW5nIFhNTF9ST09UX0VMRU1FTlRfRU1QVFlfTlMgPSAiPD94bWwgdmVyc2lvbj1cIjEuMFwiIGVuY29kaW5nPVwiVVMtQVNDSUlcIj8+PCFET0NUWVBFIEpva2VyIFNZU1RFTSBcIm9yZy5lY2xpcHNlLmNvcmUucmVzb3VyY2VzLnRlc3RzLnNvbWUuZHRkM1wiPjxyb290RWxlbWVudD4iOwoKCXB1YmxpYyBzdGF0aWMgVGVzdCBzdWl0ZSgpIHsKCQlyZXR1cm4gbmV3IE9yZGVyZWRUZXN0U3VpdGUoSUNvbnRlbnRUeXBlTWFuYWdlclRlc3QuY2xhc3MpOwoJfQoKCXB1YmxpYyBJQ29udGVudFR5cGVNYW5hZ2VyVGVzdChTdHJpbmcgbmFtZSkgewoJCXN1cGVyKG5hbWUpOwoJfQoKCS8qKgoJICogSGVscHMgdG8gZW5zdXJlIHdlIGRvbid0IGdldCBmb29sZWQgYnkgY2FzZSBzZW5zaXRpdml0eSBpbiBmaWxlIG5hbWVzL3NwZWNzLgoJICovCglwcml2YXRlIFN0cmluZyBjaGFuZ2VDYXNlKFN0cmluZyBvcmlnaW5hbCkgewoJCVN0cmluZ0J1aWxkZXIgcmVzdWx0ID0gbmV3IFN0cmluZ0J1aWxkZXIob3JpZ2luYWwpOwoJCWZvciAoaW50IGkgPSByZXN1bHQubGVuZ3RoKCkgLSAxOyBpID49IDA7IGktLSkgewoJCQljaGFyIG9yaWdpbmFsQ2hhciA9IG9yaWdpbmFsLmNoYXJBdChpKTsKCQkJcmVzdWx0LnNldENoYXJBdChpLCBpICUgMiA9PSAwID8gQ2hhcmFjdGVyLnRvTG93ZXJDYXNlKG9yaWdpbmFsQ2hhcikgOiBDaGFyYWN0ZXIudG9VcHBlckNhc2Uob3JpZ2luYWxDaGFyKSk7CgkJfQoJCXJldHVybiByZXN1bHQudG9TdHJpbmcoKTsKCX0KCglib29sZWFuIGNvbnRhaW5zKE9iamVjdFtdIGFycmF5LCBPYmplY3QgZWxlbWVudCkgewoJCWZvciAoT2JqZWN0IGVsZW1lbnQyIDogYXJyYXkpIHsKCQkJaWYgKGVsZW1lbnQyLmVxdWFscyhlbGVtZW50KSkgewoJCQkJcmV0dXJuIHRydWU7CgkJCX0KCQl9CgkJcmV0dXJuIGZhbHNlOwoJfQoKCXByaXZhdGUgSUNvbnRlbnREZXNjcmlwdGlvbiBnZXREZXNjcmlwdGlvbkZvcihJQ29udGVudFR5cGVNYXRjaGVyIGZpbmRlciwgU3RyaW5nIGNvbnRlbnRzLCBDaGFyc2V0IGVuY29kaW5nLCBTdHJpbmcgZmlsZU5hbWUsIFF1YWxpZmllZE5hbWVbXSBvcHRpb25zLCBib29sZWFuIHRleHQpIHRocm93cyBJT0V4Y2VwdGlvbiB7CgkJcmV0dXJuIHRleHQgPyBmaW5kZXIuZ2V0RGVzY3JpcHRpb25Gb3IoZ2V0UmVhZGVyKGNvbnRlbnRzKSwgZmlsZU5hbWUsIG9wdGlvbnMpIDogZmluZGVyLmdldERlc2NyaXB0aW9uRm9yKGdldElucHV0U3RyZWFtKGNvbnRlbnRzLCBlbmNvZGluZyksIGZpbGVOYW1lLCBvcHRpb25zKTsKCX0KCglwdWJsaWMgSW5wdXRTdHJlYW0gZ2V0SW5wdXRTdHJlYW0oYnl0ZVtdW10gY29udGVudHMpIHsKCQlpbnQgc2l6ZSA9IDA7CgkJLy8gY29tcHV0ZXMgZmluYWwgYXJyYXkgc2l6ZQoJCWZvciAoYnl0ZVtdIGNvbnRlbnQgOiBjb250ZW50cykgewoJCQlzaXplICs9IGNvbnRlbnQubGVuZ3RoOwoJCX0KCQlieXRlW10gZnVsbCA9IG5ldyBieXRlW3NpemVdOwoJCWludCBmdWxsSW5kZXggPSAwOwoJCS8vIGNvbmNhdGVuYXRlcyBhbGwgYnl0ZSBhcnJheXMKCQlmb3IgKGJ5dGVbXSBjb250ZW50IDogY29udGVudHMpIHsKCQkJZm9yIChieXRlIGVsZW1lbnQgOiBjb250ZW50KSB7CgkJCQlmdWxsW2Z1bGxJbmRleCsrXSA9IGVsZW1lbnQ7CgkJCX0KCQl9CgkJcmV0dXJuIG5ldyBCeXRlQXJyYXlJbnB1dFN0cmVhbShmdWxsKTsKCX0KCglwdWJsaWMgSW5wdXRTdHJlYW0gZ2V0SW5wdXRTdHJlYW0oU3RyaW5nIGNvbnRlbnRzKSB7CgkJcmV0dXJuIG5ldyBCeXRlQXJyYXlJbnB1dFN0cmVhbShjb250ZW50cy5nZXRCeXRlcygpKTsKCX0KCglwdWJsaWMgSW5wdXRTdHJlYW0gZ2V0SW5wdXRTdHJlYW0oU3RyaW5nIGNvbnRlbnRzLCBDaGFyc2V0IGVuY29kaW5nKSB7CgkJcmV0dXJuIG5ldyBCeXRlQXJyYXlJbnB1dFN0cmVhbShlbmNvZGluZyA9PSBudWxsID8gY29udGVudHMuZ2V0Qnl0ZXMoKSA6IGNvbnRlbnRzLmdldEJ5dGVzKGVuY29kaW5nKSk7Cgl9CgoJcHVibGljIFJlYWRlciBnZXRSZWFkZXIoU3RyaW5nIGNvbnRlbnRzKSB7CgkJcmV0dXJuIG5ldyBDaGFyQXJyYXlSZWFkZXIoY29udGVudHMudG9DaGFyQXJyYXkoKSk7Cgl9CgoJcHJpdmF0ZSBib29sZWFuIGlzVGV4dChJQ29udGVudFR5cGVNYW5hZ2VyIG1hbmFnZXIsIElDb250ZW50VHlwZSBjYW5kaWRhdGUpIHsKCQlJQ29udGVudFR5cGUgdGV4dCA9IG1hbmFnZXIuZ2V0Q29udGVudFR5cGUoSUNvbnRlbnRUeXBlTWFuYWdlci5DVF9URVhUKTsKCQlyZXR1cm4gY2FuZGlkYXRlLmlzS2luZE9mKHRleHQpOwoJfQoKCUBPdmVycmlkZQoJcHJvdGVjdGVkIHZvaWQgdGVhckRvd24oKSB0aHJvd3MgRXhjZXB0aW9uIHsKCQlzdXBlci50ZWFyRG93bigpOwoJCS8vIHNvbWUgdGVzdHMgaGVyZSB3aWxsIHRyaWdnZXIgYSBjaGFyc2V0IGRlbHRhIGpvYiAoYW55IGNhdXNpbmcgQ29udGVudFR5cGVDaGFuZ2VFdmVudHMgdG8gYmUgYnJvYWRjYXN0KQoJCS8vIGVuc3VyZSBub25lIGlzIGxlZnQgcnVubmluZyBhZnRlciB3ZSBmaW5pc2gKCQlKb2IuZ2V0Sm9iTWFuYWdlcigpLmpvaW4oRkFNSUxZX0NIQVJTRVRfREVMVEEsIGdldE1vbml0b3IoKSk7Cgl9CgoJLyoqCgkgKiBUaGlzIHRlc3Qgc2hvd3MgaG93IHdlIGRlYWwgd2l0aCBhbGlhc2VzLgoJICovCglwdWJsaWMgdm9pZCB0ZXN0QWxpYXMoKSB0aHJvd3MgSU9FeGNlcHRpb24gewoJCWZpbmFsIElDb250ZW50VHlwZU1hbmFnZXIgY29udGVudFR5cGVNYW5hZ2VyID0gUGxhdGZvcm0uZ2V0Q29udGVudFR5cGVNYW5hZ2VyKCk7CgkJSUNvbnRlbnRUeXBlIGFsaWFzID0gY29udGVudFR5cGVNYW5hZ2VyLmdldENvbnRlbnRUeXBlKFBJX1JFU09VUkNFU19URVNUUyArICIuYWxpYXMiKTsKCQlhc3NlcnROb3ROdWxsKCIwLjciLCBhbGlhcyk7CgkJSUNvbnRlbnRUeXBlIGRlcml2ZWQgPSBjb250ZW50VHlwZU1hbmFnZXIuZ2V0Q29udGVudFR5cGUoUElfUkVTT1VSQ0VTX1RFU1RTICsgIi5kZXJpdmVkLWZyb20tYWxpYXMiKTsKCQlhc3NlcnROb3ROdWxsKCIwLjgiLCBkZXJpdmVkKTsKCQlJQ29udGVudFR5cGUgdGFyZ2V0ID0gY29udGVudFR5cGVNYW5hZ2VyLmdldENvbnRlbnRUeXBlKCJvcmcuZWNsaXBzZS5idW5kbGUwMi5taXNzaW5nLXRhcmdldCIpOwoJCWFzc2VydE51bGwoIjAuOSIsIHRhcmdldCk7CgkJSUNvbnRlbnRUeXBlW10gc2VsZWN0ZWQ7CgkJc2VsZWN0ZWQgPSBjb250ZW50VHlwZU1hbmFnZXIuZmluZENvbnRlbnRUeXBlc0ZvcigiZm9vLm1pc3NpbmctdGFyZ2V0Iik7CgkJYXNzZXJ0RXF1YWxzKCIxLjEiLCAyLCBzZWxlY3RlZC5sZW5ndGgpOwoJCWFzc2VydEVxdWFscygiMS4yIiwgYWxpYXMsIHNlbGVjdGVkWzBdKTsKCQlhc3NlcnRFcXVhbHMoIjEuMyIsIGRlcml2ZWQsIHNlbGVjdGVkWzFdKTsKCQlzZWxlY3RlZCA9IGNvbnRlbnRUeXBlTWFuYWdlci5maW5kQ29udGVudFR5cGVzRm9yKGdldFJhbmRvbUNvbnRlbnRzKCksICJmb28ubWlzc2luZy10YXJnZXQiKTsKCQlhc3NlcnRFcXVhbHMoIjEuNCIsIDIsIHNlbGVjdGVkLmxlbmd0aCk7CgkJYXNzZXJ0RXF1YWxzKCIxLjUiLCBhbGlhcywgc2VsZWN0ZWRbMF0pOwoJCWFzc2VydEVxdWFscygiMS42IiwgZGVyaXZlZCwgc2VsZWN0ZWRbMV0pOwoKCQkvL3Rlc3QgbGF0ZSBhZGRpdGlvbiBvZiBjb250ZW50IHR5cGUKCQlUZXN0UmVnaXN0cnlDaGFuZ2VMaXN0ZW5lciBsaXN0ZW5lciA9IG5ldyBUZXN0UmVnaXN0cnlDaGFuZ2VMaXN0ZW5lcihQbGF0Zm9ybS5QSV9SVU5USU1FLCBDb250ZW50VHlwZUJ1aWxkZXIuUFRfQ09OVEVOVFRZUEVTLCBudWxsLCBudWxsKTsKCQlCdW5kbGVUZXN0aW5nSGVscGVyLnJ1bldpdGhCdW5kbGVzKCIyIiwgKCkgLT4gewoJCQlJQ29udGVudFR5cGUgYWxpYXMxID0gY29udGVudFR5cGVNYW5hZ2VyLmdldENvbnRlbnRUeXBlKFBJX1JFU09VUkNFU19URVNUUyArICIuYWxpYXMiKTsKCQkJYXNzZXJ0TnVsbCgiMi4xLjEiLCBhbGlhczEpOwoJCQlJQ29udGVudFR5cGUgZGVyaXZlZDEgPSBjb250ZW50VHlwZU1hbmFnZXIuZ2V0Q29udGVudFR5cGUoUElfUkVTT1VSQ0VTX1RFU1RTICsgIi5kZXJpdmVkLWZyb20tYWxpYXMiKTsKCQkJYXNzZXJ0Tm90TnVsbCgiMi4xLjIiLCBkZXJpdmVkMSk7CgkJCUlDb250ZW50VHlwZSB0YXJnZXQxID0gY29udGVudFR5cGVNYW5hZ2VyLmdldENvbnRlbnRUeXBlKCJvcmcuZWNsaXBzZS5idW5kbGUwMi5taXNzaW5nLXRhcmdldCIpOwoJCQlhc3NlcnROb3ROdWxsKCIyLjEuMyIsIHRhcmdldDEpOwoJCQkvLyBjaGVja3MgYXNzb2NpYXRpb25zCgkJCUlDb250ZW50VHlwZVtdIHNlbGVjdGVkMSA9IGNvbnRlbnRUeXBlTWFuYWdlci5maW5kQ29udGVudFR5cGVzRm9yKCJmb28ubWlzc2luZy10YXJnZXQiKTsKCQkJYXNzZXJ0RXF1YWxzKCIyLjIuMSIsIDIsIHNlbGVjdGVkMS5sZW5ndGgpOwoJCQlhc3NlcnRFcXVhbHMoIjIuMi4yIiwgdGFyZ2V0MSwgc2VsZWN0ZWQxWzBdKTsKCQkJYXNzZXJ0RXF1YWxzKCIyLjIuMyIsIGRlcml2ZWQxLCBzZWxlY3RlZDFbMV0pOwoJCQl0cnkgewoJCQkJc2VsZWN0ZWQxID0gY29udGVudFR5cGVNYW5hZ2VyLmZpbmRDb250ZW50VHlwZXNGb3IoZ2V0UmFuZG9tQ29udGVudHMoKSwgImZvby5taXNzaW5nLXRhcmdldCIpOwoJCQl9IGNhdGNoIChJT0V4Y2VwdGlvbiBlKSB7CgkJCQlmYWlsKCIyLjIuNCIsIGUpOwoJCQl9CgkJCWFzc2VydEVxdWFscygiMi4yLjUiLCAyLCBzZWxlY3RlZDEubGVuZ3RoKTsKCQkJYXNzZXJ0RXF1YWxzKCIyLjIuNiIsIHRhcmdldDEsIHNlbGVjdGVkMVswXSk7CgkJCWFzc2VydEVxdWFscygiMi4yLjciLCBkZXJpdmVkMSwgc2VsZWN0ZWQxWzFdKTsKCQl9LCBnZXRDb250ZXh0KCksIG5ldyBTdHJpbmdbXSB7Q29udGVudFR5cGVUZXN0LlRFU1RfRklMRVNfUk9PVCArICJjb250ZW50L2J1bmRsZTAyIn0sIGxpc3RlbmVyKTsKCX0KCglwdWJsaWMgdm9pZCB0ZXN0QXNzb2NpYXRpb25Jbmhlcml0YW5jZSgpIHRocm93cyBDb3JlRXhjZXB0aW9uIHsKCQlJQ29udGVudFR5cGVNYW5hZ2VyIG1hbmFnZXIgPSBQbGF0Zm9ybS5nZXRDb250ZW50VHlwZU1hbmFnZXIoKTsKCQlJQ29udGVudFR5cGVNYXRjaGVyIGZpbmRlciA9IG1hbmFnZXIuZ2V0TWF0Y2hlcihuZXcgTG9jYWxTZWxlY3Rpb25Qb2xpY3koKSwgbnVsbCk7CgkJSUNvbnRlbnRUeXBlIHRleHQgPSBtYW5hZ2VyLmdldENvbnRlbnRUeXBlKFBsYXRmb3JtLlBJX1JVTlRJTUUgKyAiLnRleHQiKTsKCQlJQ29udGVudFR5cGUgYXNzb2MxID0gbWFuYWdlci5nZXRDb250ZW50VHlwZShQSV9SRVNPVVJDRVNfVEVTVFMgKyAiLmFzc29jMSIpOwoJCUlDb250ZW50VHlwZSBhc3NvYzIgPSBtYW5hZ2VyLmdldENvbnRlbnRUeXBlKFBJX1JFU09VUkNFU19URVNUUyArICIuYXNzb2MyIik7CgoJCS8vIGFzc29jaWF0ZSBhIHVzZXItZGVmaW5lZCBmaWxlIHNwZWMKCQl0ZXh0LmFkZEZpbGVTcGVjKCJ0eHRfdXNlcmFkZGVkIiwgSUNvbnRlbnRUeXBlLkZJTEVfRVhURU5TSU9OX1NQRUMpOwoJCWFzc29jMS5hZGRGaWxlU3BlYygidHh0X2Fzc29jMXVzZXJhZGRlZCIsIElDb250ZW50VHlwZS5GSUxFX0VYVEVOU0lPTl9TUEVDKTsKCQlhc3NvYzIuYWRkRmlsZVNwZWMoInR4dF9hc3NvYzJ1c2VyYWRkZWQiLCBJQ29udGVudFR5cGUuRklMRV9FWFRFTlNJT05fU1BFQyk7CgoJCS8vIHRlc3QgYXNzb2NpYXRpb25zCgkJYXNzZXJ0VHJ1ZSgiMS4xIiwgYXNzb2MxLmlzQXNzb2NpYXRlZFdpdGgoY2hhbmdlQ2FzZSgidGV4dC50eHQiKSkpOwoJCWFzc2VydFRydWUoIjEuMiIsIGFzc29jMS5pc0Fzc29jaWF0ZWRXaXRoKGNoYW5nZUNhc2UoInRleHQudHh0X3VzZXJhZGRlZCIpKSk7CgkJYXNzZXJ0VHJ1ZSgiMS4zIiwgYXNzb2MxLmlzQXNzb2NpYXRlZFdpdGgoY2hhbmdlQ2FzZSgidGV4dC50eHRfcGx1Z2luYWRkZWQiKSkpOwoJCWFzc2VydFRydWUoIjEuNCIsIGFzc29jMS5pc0Fzc29jaWF0ZWRXaXRoKGNoYW5nZUNhc2UoInRleHQudHh0X2Fzc29jMXBsdWdpbmFkZGVkIikpKTsKCQlhc3NlcnRUcnVlKCIxLjUiLCBhc3NvYzEuaXNBc3NvY2lhdGVkV2l0aChjaGFuZ2VDYXNlKCJ0ZXh0LnR4dF9hc3NvYzF1c2VyYWRkZWQiKSkpOwoKCQlhc3NlcnRUcnVlKCIyLjEiLCAhYXNzb2MyLmlzQXNzb2NpYXRlZFdpdGgoY2hhbmdlQ2FzZSgidGV4dC50eHQiKSkpOwoJCWFzc2VydFRydWUoIjIuMiIsICFhc3NvYzIuaXNBc3NvY2lhdGVkV2l0aChjaGFuZ2VDYXNlKCJ0ZXh0LnR4dF91c2VyYWRkZWQiKSkpOwoJCWFzc2VydFRydWUoIjIuMyIsICFhc3NvYzIuaXNBc3NvY2lhdGVkV2l0aChjaGFuZ2VDYXNlKCJ0ZXh0LnR4dF9wbHVnaW5hZGRlZCIpKSk7CgkJYXNzZXJ0VHJ1ZSgiMi40IiwgYXNzb2MyLmlzQXNzb2NpYXRlZFdpdGgoY2hhbmdlQ2FzZSgidGV4dC50eHRfYXNzb2MycGx1Z2luYWRkZWQiKSkpOwoJCWFzc2VydFRydWUoIjIuNSIsIGFzc29jMi5pc0Fzc29jaWF0ZWRXaXRoKGNoYW5nZUNhc2UoInRleHQudHh0X2Fzc29jMmJ1aWx0aW4iKSkpOwoJCWFzc2VydFRydWUoIjIuNiIsIGFzc29jMi5pc0Fzc29jaWF0ZWRXaXRoKGNoYW5nZUNhc2UoInRleHQudHh0X2Fzc29jMnVzZXJhZGRlZCIpKSk7CgoJCUlDb250ZW50VHlwZVtdIHNlbGVjdGVkOwoJCS8vIHRleHQgYnVpbHQtaW4gYXNzb2NpYXRpb25zCgkJc2VsZWN0ZWQgPSBmaW5kZXIuZmluZENvbnRlbnRUeXBlc0ZvcihjaGFuZ2VDYXNlKCJ0ZXh0LnR4dCIpKTsKCQlhc3NlcnRFcXVhbHMoIjMuMCIsIDIsIHNlbGVjdGVkLmxlbmd0aCk7CgkJYXNzZXJ0RXF1YWxzKCIzLjEiLCBhc3NvYzEsIHNlbGVjdGVkWzFdKTsKCQlhc3NlcnRFcXVhbHMoIjMuMiIsIHRleHQsIHNlbGVjdGVkWzBdKTsKCgkJLy8gdGV4dCB1c2VyLWFkZGVkIGFzc29jaWF0aW9ucwoJCXNlbGVjdGVkID0gZmluZGVyLmZpbmRDb250ZW50VHlwZXNGb3IoY2hhbmdlQ2FzZSgidGV4dC50eHRfdXNlcmFkZGVkIikpOwoJCWFzc2VydEVxdWFscygiNC4wIiwgMiwgc2VsZWN0ZWQubGVuZ3RoKTsKCQlhc3NlcnRFcXVhbHMoIjQuMSIsIGFzc29jMSwgc2VsZWN0ZWRbMV0pOwoJCWFzc2VydEVxdWFscygiNC4yIiwgdGV4dCwgc2VsZWN0ZWRbMF0pOwoKCQkvLyB0ZXh0IHByb3ZpZGVyLWFkZGVkIGFzc29jaWF0aW9ucwoJCXNlbGVjdGVkID0gZmluZGVyLmZpbmRDb250ZW50VHlwZXNGb3IoY2hhbmdlQ2FzZSgidGV4dC50eHRfcGx1Z2luYWRkZWQiKSk7CgkJYXNzZXJ0RXF1YWxzKCI1LjAiLCAyLCBzZWxlY3RlZC5sZW5ndGgpOwoJCWFzc2VydEVxdWFscygiNS4xIiwgYXNzb2MxLCBzZWxlY3RlZFsxXSk7CgkJYXNzZXJ0RXF1YWxzKCI1LjIiLCB0ZXh0LCBzZWxlY3RlZFswXSk7CgoJCXNlbGVjdGVkID0gZmluZGVyLmZpbmRDb250ZW50VHlwZXNGb3IoY2hhbmdlQ2FzZSgidGV4dC50eHRfYXNzb2MxcGx1Z2luYWRkZWQiKSk7CgkJYXNzZXJ0RXF1YWxzKCI2LjAiLCAxLCBzZWxlY3RlZC5sZW5ndGgpOwoJCWFzc2VydEVxdWFscygiNi4xIiwgYXNzb2MxLCBzZWxlY3RlZFswXSk7CgoJCXNlbGVjdGVkID0gZmluZGVyLmZpbmRDb250ZW50VHlwZXNGb3IoY2hhbmdlQ2FzZSgidGV4dC50eHRfYXNzb2MxdXNlcmFkZGVkIikpOwoJCWFzc2VydEVxdWFscygiNy4wIiwgMSwgc2VsZWN0ZWQubGVuZ3RoKTsKCQlhc3NlcnRFcXVhbHMoIjcuMSIsIGFzc29jMSwgc2VsZWN0ZWRbMF0pOwoKCQlzZWxlY3RlZCA9IGZpbmRlci5maW5kQ29udGVudFR5cGVzRm9yKGNoYW5nZUNhc2UoInRleHQudHh0X2Fzc29jMnBsdWdpbmFkZGVkIikpOwoJCWFzc2VydEVxdWFscygiOC4wIiwgMSwgc2VsZWN0ZWQubGVuZ3RoKTsKCQlhc3NlcnRFcXVhbHMoIjguMSIsIGFzc29jMiwgc2VsZWN0ZWRbMF0pOwoKCQlzZWxlY3RlZCA9IGZpbmRlci5maW5kQ29udGVudFR5cGVzRm9yKGNoYW5nZUNhc2UoInRleHQudHh0X2Fzc29jMnVzZXJhZGRlZCIpKTsKCQlhc3NlcnRFcXVhbHMoIjkuMCIsIDEsIHNlbGVjdGVkLmxlbmd0aCk7CgkJYXNzZXJ0RXF1YWxzKCI5LjEiLCBhc3NvYzIsIHNlbGVjdGVkWzBdKTsKCgkJc2VsZWN0ZWQgPSBmaW5kZXIuZmluZENvbnRlbnRUeXBlc0ZvcihjaGFuZ2VDYXNlKCJ0ZXh0LnR4dF9hc3NvYzJidWlsdGluIikpOwoJCWFzc2VydEVxdWFscygiMTAuMCIsIDEsIHNlbGVjdGVkLmxlbmd0aCk7CgkJYXNzZXJ0RXF1YWxzKCIxMC4xIiwgYXNzb2MyLCBzZWxlY3RlZFswXSk7Cgl9CgoJcHVibGljIHZvaWQgdGVzdEFzc29jaWF0aW9ucygpIHRocm93cyBDb3JlRXhjZXB0aW9uIHsKCQlJQ29udGVudFR5cGUgdGV4dCA9IFBsYXRmb3JtLmdldENvbnRlbnRUeXBlTWFuYWdlcigpLmdldENvbnRlbnRUeXBlKFBsYXRmb3JtLlBJX1JVTlRJTUUgKyAiLnRleHQiKTsKCgkJLy8gYXNzb2NpYXRlIGEgdXNlci1kZWZpbmVkIGZpbGUgc3BlYwoJCXRleHQuYWRkRmlsZVNwZWMoInR4dF91c2VyYWRkZWQiLCBJQ29udGVudFR5cGUuRklMRV9FWFRFTlNJT05fU1BFQyk7CgoJCS8vIHRlc3QgYXNzb2NpYXRpb25zCgkJYXNzZXJ0VHJ1ZSgiMC4xIiwgdGV4dC5pc0Fzc29jaWF0ZWRXaXRoKGNoYW5nZUNhc2UoInRleHQudHh0IikpKTsKCQlhc3NlcnRUcnVlKCIwLjIiLCB0ZXh0LmlzQXNzb2NpYXRlZFdpdGgoY2hhbmdlQ2FzZSgidGV4dC50eHRfdXNlcmFkZGVkIikpKTsKCQlhc3NlcnRUcnVlKCIwLjMiLCB0ZXh0LmlzQXNzb2NpYXRlZFdpdGgoY2hhbmdlQ2FzZSgidGV4dC50eHRfcGx1Z2luYWRkZWQiKSkpOwoKCQkvLyBjaGVjayBwcm92aWRlciBkZWZpbmVkIHNldHRpbmdzCgkJU3RyaW5nW10gcHJvdmlkZXJEZWZpbmVkRXh0ZW5zaW9ucyA9IHRleHQuZ2V0RmlsZVNwZWNzKElDb250ZW50VHlwZS5GSUxFX0VYVEVOU0lPTl9TUEVDIHwgSUNvbnRlbnRUeXBlLklHTk9SRV9VU0VSX0RFRklORUQpOwoJCWFzc2VydFRydWUoIjEuMCIsIGNvbnRhaW5zKHByb3ZpZGVyRGVmaW5lZEV4dGVuc2lvbnMsICJ0eHQiKSk7CgkJYXNzZXJ0VHJ1ZSgiMS4xIiwgIWNvbnRhaW5zKHByb3ZpZGVyRGVmaW5lZEV4dGVuc2lvbnMsICJ0eHRfdXNlcmFkZGVkIikpOwoJCWFzc2VydFRydWUoIjEuMiIsIGNvbnRhaW5zKHByb3ZpZGVyRGVmaW5lZEV4dGVuc2lvbnMsICJ0eHRfcGx1Z2luYWRkZWQiKSk7CgoJCS8vIGNoZWNrIHVzZXIgZGVmaW5lZCBzZXR0aW5ncwoJCVN0cmluZ1tdIHRleHRVc2VyRGVmaW5lZEV4dGVuc2lvbnMgPSB0ZXh0LmdldEZpbGVTcGVjcyhJQ29udGVudFR5cGUuRklMRV9FWFRFTlNJT05fU1BFQyB8IElDb250ZW50VHlwZS5JR05PUkVfUFJFX0RFRklORUQpOwoJCWFzc2VydFRydWUoIjIuMCIsICFjb250YWlucyh0ZXh0VXNlckRlZmluZWRFeHRlbnNpb25zLCAidHh0IikpOwoJCWFzc2VydFRydWUoIjIuMSIsIGNvbnRhaW5zKHRleHRVc2VyRGVmaW5lZEV4dGVuc2lvbnMsICJ0eHRfdXNlcmFkZGVkIikpOwoJCWFzc2VydFRydWUoIjIuMiIsICFjb250YWlucyh0ZXh0VXNlckRlZmluZWRFeHRlbnNpb25zLCAidHh0X3BsdWdpbmFkZGVkIikpOwoKCQkvLyByZW1vdmluZyBwcmUtZGVmaW5lZCBmaWxlIHNwZWNzIHNob3VsZCBub3QgZG8gYW55dGhpbmcKCQl0ZXh0LnJlbW92ZUZpbGVTcGVjKCJ0eHQiLCBJQ29udGVudFR5cGUuRklMRV9FWFRFTlNJT05fU1BFQyk7CgkJYXNzZXJ0VHJ1ZSgiMy4wIiwgY29udGFpbnModGV4dC5nZXRGaWxlU3BlY3MoSUNvbnRlbnRUeXBlLkZJTEVfRVhURU5TSU9OX1NQRUMgfCBJQ29udGVudFR5cGUuSUdOT1JFX1VTRVJfREVGSU5FRCksICJ0eHQiKSk7CgkJYXNzZXJ0VHJ1ZSgiMy4xIiwgdGV4dC5pc0Fzc29jaWF0ZWRXaXRoKGNoYW5nZUNhc2UoInRleHQudHh0IikpKTsKCQlhc3NlcnRUcnVlKCIzLjIiLCB0ZXh0LmlzQXNzb2NpYXRlZFdpdGgoY2hhbmdlQ2FzZSgidGV4dC50eHRfdXNlcmFkZGVkIikpKTsKCQlhc3NlcnRUcnVlKCIzLjMiLCB0ZXh0LmlzQXNzb2NpYXRlZFdpdGgoY2hhbmdlQ2FzZSgidGV4dC50eHRfcGx1Z2luYWRkZWQiKSkpOwoKCQkvLyByZW1vdmluZyB1c2VyIGZpbGUgc3BlY3MgaXMgdGhlIG5vcm1hbCBjYXNlIGFuZCBoYXMgdG8gd29yayBhcyBleHBlY3RlZAoJCXRleHQucmVtb3ZlRmlsZVNwZWMoInR4dF91c2VyYWRkZWQiLCBJQ29udGVudFR5cGUuRklMRV9FWFRFTlNJT05fU1BFQyk7CgkJYXNzZXJ0VHJ1ZSgiNC4wIiwgIWNvbnRhaW5zKHRleHQuZ2V0RmlsZVNwZWNzKElDb250ZW50VHlwZS5GSUxFX0VYVEVOU0lPTl9TUEVDIHwgSUNvbnRlbnRUeXBlLklHTk9SRV9QUkVfREVGSU5FRCksICJpbmkiKSk7CgkJYXNzZXJ0VHJ1ZSgiNC4xIiwgdGV4dC5pc0Fzc29jaWF0ZWRXaXRoKGNoYW5nZUNhc2UoInRleHQudHh0IikpKTsKCQlhc3NlcnRUcnVlKCI0LjIiLCAhdGV4dC5pc0Fzc29jaWF0ZWRXaXRoKGNoYW5nZUNhc2UoInRleHQudHh0X3VzZXJhZGRlZCIpKSk7CgkJYXNzZXJ0VHJ1ZSgiNC4zIiwgdGV4dC5pc0Fzc29jaWF0ZWRXaXRoKGNoYW5nZUNhc2UoInRleHQudHh0X3BsdWdpbmFkZGVkIikpKTsKCX0KCglwdWJsaWMgdm9pZCB0ZXN0QmluYXJ5VHlwZXMoKSB0aHJvd3MgSU9FeGNlcHRpb24gewoJCUlDb250ZW50VHlwZU1hbmFnZXIgY29udGVudFR5cGVNYW5hZ2VyID0gUGxhdGZvcm0uZ2V0Q29udGVudFR5cGVNYW5hZ2VyKCk7CgkJSUNvbnRlbnRUeXBlIHNhbXBsZUJpbmFyeTEgPSBjb250ZW50VHlwZU1hbmFnZXIuZ2V0Q29udGVudFR5cGUoUElfUkVTT1VSQ0VTX1RFU1RTICsgIi5zYW1wbGUtYmluYXJ5MSIpOwoJCUlDb250ZW50VHlwZSBzYW1wbGVCaW5hcnkyID0gY29udGVudFR5cGVNYW5hZ2VyLmdldENvbnRlbnRUeXBlKFBJX1JFU09VUkNFU19URVNUUyArICIuc2FtcGxlLWJpbmFyeTIiKTsKCQlJbnB1dFN0cmVhbSBjb250ZW50czsKCgkJY29udGVudHMgPSBnZXRJbnB1dFN0cmVhbShuZXcgYnl0ZVtdW10ge1NBTVBMRV9CSU4xX09GRlNFVC5nZXRCeXRlcygpLCBTQU1QTEVfQklOMV9TSUdOQVRVUkUsICIgZXh0cmEgY29udGVudHMiLmdldEJ5dGVzKCl9KTsKCQlJQ29udGVudERlc2NyaXB0aW9uIGRlc2NyaXB0aW9uID0gY29udGVudFR5cGVNYW5hZ2VyLmdldERlc2NyaXB0aW9uRm9yKGNvbnRlbnRzLCBudWxsLCBJQ29udGVudERlc2NyaXB0aW9uLkFMTCk7CgkJYXNzZXJ0Tm90TnVsbCgiNi4wIiwgZGVzY3JpcHRpb24pOwoJCWFzc2VydEVxdWFscygiNi4xIiwgc2FtcGxlQmluYXJ5MSwgZGVzY3JpcHRpb24uZ2V0Q29udGVudFR5cGUoKSk7CgoJCWNvbnRlbnRzID0gZ2V0SW5wdXRTdHJlYW0obmV3IGJ5dGVbXVtdIHtTQU1QTEVfQklOMl9PRkZTRVQuZ2V0Qnl0ZXMoKSwgU0FNUExFX0JJTjJfU0lHTkFUVVJFLCAiIGV4dHJhIGNvbnRlbnRzIi5nZXRCeXRlcygpfSk7CgkJZGVzY3JpcHRpb24gPSBjb250ZW50VHlwZU1hbmFnZXIuZ2V0RGVzY3JpcHRpb25Gb3IoY29udGVudHMsIG51bGwsIElDb250ZW50RGVzY3JpcHRpb24uQUxMKTsKCQlhc3NlcnROb3ROdWxsKCI3LjAiLCBkZXNjcmlwdGlvbik7CgkJYXNzZXJ0RXF1YWxzKCI3LjEiLCBzYW1wbGVCaW5hcnkyLCBkZXNjcmlwdGlvbi5nZXRDb250ZW50VHlwZSgpKTsKCgkJLy8gbWFrZSBzdXJlIHdlIGlnbm9yZSB0aGF0IGNvbnRlbnQgdHlwZSB3aGVuIGNvbnRlbnRzIGFyZSB0ZXh0CgkJLy8gKHNlZSBidWcgMTAwMDMyKQoJCS8vIGZpcnN0IGNoZWNrIGlmIG91ciB0ZXN0IGVudmlyb25tZW50IGlzIHNhbmUKCQlJQ29udGVudFR5cGVbXSBzZWxlY3RlZCA9IGNvbnRlbnRUeXBlTWFuYWdlci5maW5kQ29udGVudFR5cGVzRm9yKCJ0ZXN0LnNhbXBsZWJpbjIiKTsKCQlhc3NlcnRFcXVhbHMoIjguMSIsIDEsIHNlbGVjdGVkLmxlbmd0aCk7CgkJYXNzZXJ0RXF1YWxzKCI4LjIiLCBzYW1wbGVCaW5hcnkyLmdldElkKCksIHNlbGVjdGVkWzBdLmdldElkKCkpOwoJCS8vICh3ZSB1c2VkIHRvIGJsb3cgdXAgaGVyZSkKCQlkZXNjcmlwdGlvbiA9IGNvbnRlbnRUeXBlTWFuYWdlci5nZXREZXNjcmlwdGlvbkZvcihnZXRSZWFkZXIoZ2V0UmFuZG9tU3RyaW5nKCkpLCAidGVzdC5zYW1wbGViaW4yIiwgSUNvbnRlbnREZXNjcmlwdGlvbi5BTEwpOwoJCWFzc2VydE51bGwoIjguMyIsIGRlc2NyaXB0aW9uKTsKCX0KCglwdWJsaWMgdm9pZCB0ZXN0Qnl0ZU9yZGVyTWFyaygpIHRocm93cyBJT0V4Y2VwdGlvbiB7CgkJSUNvbnRlbnRUeXBlIHRleHQgPSBQbGF0Zm9ybS5nZXRDb250ZW50VHlwZU1hbmFnZXIoKS5nZXRDb250ZW50VHlwZShJQ29udGVudFR5cGVNYW5hZ2VyLkNUX1RFWFQpOwoJCVF1YWxpZmllZE5hbWVbXSBvcHRpb25zID0gbmV3IFF1YWxpZmllZE5hbWVbXSB7SUNvbnRlbnREZXNjcmlwdGlvbi5CWVRFX09SREVSX01BUkt9OwoJCUlDb250ZW50RGVzY3JpcHRpb24gZGVzY3JpcHRpb247CgkJLy8gdGVzdHMgd2l0aCBVVEYtOCBCT00KCQlTdHJpbmcgVVRGOF9CT00gPSBuZXcgU3RyaW5nKElDb250ZW50RGVzY3JpcHRpb24uQk9NX1VURl84LCBTdGFuZGFyZENoYXJzZXRzLklTT184ODU5XzEpOwoJCWRlc2NyaXB0aW9uID0gdGV4dC5nZXREZXNjcmlwdGlvbkZvcihuZXcgQnl0ZUFycmF5SW5wdXRTdHJlYW0oKFVURjhfQk9NICsgTUlOSU1BTF9YTUwpLmdldEJ5dGVzKFN0YW5kYXJkQ2hhcnNldHMuSVNPXzg4NTlfMSkpLCBvcHRpb25zKTsKCQlhc3NlcnROb3ROdWxsKCIxLjAiLCBkZXNjcmlwdGlvbi5nZXRQcm9wZXJ0eShJQ29udGVudERlc2NyaXB0aW9uLkJZVEVfT1JERVJfTUFSSykpOwoJCWFzc2VydEVxdWFscygiMS4xIiwgSUNvbnRlbnREZXNjcmlwdGlvbi5CT01fVVRGXzgsIGRlc2NyaXB0aW9uLmdldFByb3BlcnR5KElDb250ZW50RGVzY3JpcHRpb24uQllURV9PUkRFUl9NQVJLKSk7CgkJLy8gdGVzdHMgd2l0aCBVVEYtMTYgTGl0dGxlIEVuZGlhbiBCT00KCQlTdHJpbmcgVVRGMTZfTEVfQk9NID0gbmV3IFN0cmluZyhJQ29udGVudERlc2NyaXB0aW9uLkJPTV9VVEZfMTZMRSwgU3RhbmRhcmRDaGFyc2V0cy5JU09fODg1OV8xKTsKCQlkZXNjcmlwdGlvbiA9IHRleHQuZ2V0RGVzY3JpcHRpb25Gb3IobmV3IEJ5dGVBcnJheUlucHV0U3RyZWFtKChVVEYxNl9MRV9CT00gKyBNSU5JTUFMX1hNTCkuZ2V0Qnl0ZXMoU3RhbmRhcmRDaGFyc2V0cy5JU09fODg1OV8xKSksIG9wdGlvbnMpOwoJCWFzc2VydE5vdE51bGwoIjIuMCIsIGRlc2NyaXB0aW9uLmdldFByb3BlcnR5KElDb250ZW50RGVzY3JpcHRpb24uQllURV9PUkRFUl9NQVJLKSk7CgkJYXNzZXJ0RXF1YWxzKCIyLjEiLCBJQ29udGVudERlc2NyaXB0aW9uLkJPTV9VVEZfMTZMRSwgZGVzY3JpcHRpb24uZ2V0UHJvcGVydHkoSUNvbnRlbnREZXNjcmlwdGlvbi5CWVRFX09SREVSX01BUkspKTsKCQkvLyB0ZXN0cyB3aXRoIFVURi0xNiBCaWcgRW5kaWFuIEJPTQoJCVN0cmluZyBVVEYxNl9CRV9CT00gPSBuZXcgU3RyaW5nKElDb250ZW50RGVzY3JpcHRpb24uQk9NX1VURl8xNkJFLCBTdGFuZGFyZENoYXJzZXRzLklTT184ODU5XzEpOwoJCWRlc2NyaXB0aW9uID0gdGV4dC5nZXREZXNjcmlwdGlvbkZvcihuZXcgQnl0ZUFycmF5SW5wdXRTdHJlYW0oKFVURjE2X0JFX0JPTSArIE1JTklNQUxfWE1MKS5nZXRCeXRlcyhTdGFuZGFyZENoYXJzZXRzLklTT184ODU5XzEpKSwgb3B0aW9ucyk7CgkJYXNzZXJ0Tm90TnVsbCgiMy4wIiwgZGVzY3JpcHRpb24uZ2V0UHJvcGVydHkoSUNvbnRlbnREZXNjcmlwdGlvbi5CWVRFX09SREVSX01BUkspKTsKCQlhc3NlcnRFcXVhbHMoIjMuMSIsIElDb250ZW50RGVzY3JpcHRpb24uQk9NX1VURl8xNkJFLCBkZXNjcmlwdGlvbi5nZXRQcm9wZXJ0eShJQ29udGVudERlc2NyaXB0aW9uLkJZVEVfT1JERVJfTUFSSykpOwoJCS8vIHRlc3Qgd2l0aCBubyBCT00KCQlkZXNjcmlwdGlvbiA9IHRleHQuZ2V0RGVzY3JpcHRpb25Gb3IobmV3IEJ5dGVBcnJheUlucHV0U3RyZWFtKE1JTklNQUxfWE1MLmdldEJ5dGVzKFN0YW5kYXJkQ2hhcnNldHMuSVNPXzg4NTlfMSkpLCBvcHRpb25zKTsKCQlhc3NlcnROdWxsKCI0LjAiLCBkZXNjcmlwdGlvbi5nZXRQcm9wZXJ0eShJQ29udGVudERlc2NyaXB0aW9uLkJZVEVfT1JERVJfTUFSSykpOwoKCQkvLyB0ZXN0cyBmb3IgcGFydGlhbCBCT00KCQkvLyBmaXJzdCBieXRlIG9mIFVURi0xNiBCaWcgRW5kaWFuICsgbWluaW1hbCB4bWwKCQlTdHJpbmcgVVRGMTZfQkVfQk9NXzFieXRlID0gbmV3IFN0cmluZyhuZXcgYnl0ZVtdIHsoYnl0ZSkgMHhGRX0sICJJU08tODg1OS0xIik7CgkJZGVzY3JpcHRpb24gPSB0ZXh0LmdldERlc2NyaXB0aW9uRm9yKG5ldyBCeXRlQXJyYXlJbnB1dFN0cmVhbSgoVVRGMTZfQkVfQk9NXzFieXRlICsgTUlOSU1BTF9YTUwpLmdldEJ5dGVzKFN0YW5kYXJkQ2hhcnNldHMuSVNPXzg4NTlfMSkpLCBvcHRpb25zKTsKCQlhc3NlcnROdWxsKCI1LjAiLCBkZXNjcmlwdGlvbi5nZXRQcm9wZXJ0eShJQ29udGVudERlc2NyaXB0aW9uLkJZVEVfT1JERVJfTUFSSykpOwoJCS8vIGZpcnN0IGJ5dGUgb2YgVVRGLTE2IEJpZyBFbmRpYW4gb25seSAoc2VlIGh0dHBzOi8vYnVncy5lY2xpcHNlLm9yZy9idWdzL3Nob3dfYnVnLmNnaT9pZD0xOTkyNTIpCgkJZGVzY3JpcHRpb24gPSB0ZXh0LmdldERlc2NyaXB0aW9uRm9yKG5ldyBCeXRlQXJyYXlJbnB1dFN0cmVhbSgoVVRGMTZfQkVfQk9NXzFieXRlKS5nZXRCeXRlcyhTdGFuZGFyZENoYXJzZXRzLklTT184ODU5XzEpKSwgb3B0aW9ucyk7CgkJYXNzZXJ0TnVsbCgiNS4xIiwgZGVzY3JpcHRpb24uZ2V0UHJvcGVydHkoSUNvbnRlbnREZXNjcmlwdGlvbi5CWVRFX09SREVSX01BUkspKTsKCgkJLy8gZmlyc3QgYnl0ZSBvZiBVVEYtMTYgTGl0dGxlIEVuZGlhbiArIG1pbmltYWwgeG1sCgkJU3RyaW5nIFVURjE2X0xFX0JPTV8xYnl0ZSA9IG5ldyBTdHJpbmcobmV3IGJ5dGVbXSB7KGJ5dGUpIDB4RkZ9LCBTdGFuZGFyZENoYXJzZXRzLklTT184ODU5XzEpOwoJCWRlc2NyaXB0aW9uID0gdGV4dC5nZXREZXNjcmlwdGlvbkZvcihuZXcgQnl0ZUFycmF5SW5wdXRTdHJlYW0oKFVURjE2X0xFX0JPTV8xYnl0ZSArIE1JTklNQUxfWE1MKS5nZXRCeXRlcyhTdGFuZGFyZENoYXJzZXRzLklTT184ODU5XzEpKSwgb3B0aW9ucyk7CgkJYXNzZXJ0TnVsbCgiNi4wIiwgZGVzY3JpcHRpb24uZ2V0UHJvcGVydHkoSUNvbnRlbnREZXNjcmlwdGlvbi5CWVRFX09SREVSX01BUkspKTsKCQkvLyBmaXJzdCBieXRlIG9mIFVURi0xNiBMaXR0bGUgRW5kaWFuIG9ubHkKCQlkZXNjcmlwdGlvbiA9IHRleHQuZ2V0RGVzY3JpcHRpb25Gb3IobmV3IEJ5dGVBcnJheUlucHV0U3RyZWFtKChVVEYxNl9MRV9CT01fMWJ5dGUpLmdldEJ5dGVzKFN0YW5kYXJkQ2hhcnNldHMuSVNPXzg4NTlfMSkpLCBvcHRpb25zKTsKCQlhc3NlcnROdWxsKCI2LjEiLCBkZXNjcmlwdGlvbi5nZXRQcm9wZXJ0eShJQ29udGVudERlc2NyaXB0aW9uLkJZVEVfT1JERVJfTUFSSykpOwoKCQkvLyBmaXJzdCBieXRlIG9mIFVURi04ICsgbWluaW1hbCB4bWwKCQlTdHJpbmcgVVRGOF9CT01fMWJ5dGUgPSBuZXcgU3RyaW5nKG5ldyBieXRlW10geyhieXRlKSAweEVGfSwgU3RhbmRhcmRDaGFyc2V0cy5JU09fODg1OV8xKTsKCQlkZXNjcmlwdGlvbiA9IHRleHQuZ2V0RGVzY3JpcHRpb25Gb3IobmV3IEJ5dGVBcnJheUlucHV0U3RyZWFtKChVVEY4X0JPTV8xYnl0ZSArIE1JTklNQUxfWE1MKS5nZXRCeXRlcyhTdGFuZGFyZENoYXJzZXRzLklTT184ODU5XzEpKSwgb3B0aW9ucyk7CgkJYXNzZXJ0TnVsbCgiNy4wIiwgZGVzY3JpcHRpb24uZ2V0UHJvcGVydHkoSUNvbnRlbnREZXNjcmlwdGlvbi5CWVRFX09SREVSX01BUkspKTsKCQkvLyBmaXJzdCBieXRlIG9mIFVURi04IG9ubHkKCQlkZXNjcmlwdGlvbiA9IHRleHQuZ2V0RGVzY3JpcHRpb25Gb3IobmV3IEJ5dGVBcnJheUlucHV0U3RyZWFtKChVVEY4X0JPTV8xYnl0ZSkuZ2V0Qnl0ZXMoU3RhbmRhcmRDaGFyc2V0cy5JU09fODg1OV8xKSksIG9wdGlvbnMpOwoJCWFzc2VydE51bGwoIjcuMSIsIGRlc2NyaXB0aW9uLmdldFByb3BlcnR5KElDb250ZW50RGVzY3JpcHRpb24uQllURV9PUkRFUl9NQVJLKSk7CgoJCS8vIHR3byBmaXJzdCBieXRlcyBvZiBVVEYtOCArIG1pbmltYWwgeG1sCgkJU3RyaW5nIFVURjhfQk9NXzJieXRlcyA9IG5ldyBTdHJpbmcobmV3IGJ5dGVbXSB7KGJ5dGUpIDB4RUYsIChieXRlKSAweEJCfSwgU3RhbmRhcmRDaGFyc2V0cy5JU09fODg1OV8xKTsKCQlkZXNjcmlwdGlvbiA9IHRleHQuZ2V0RGVzY3JpcHRpb25Gb3IobmV3IEJ5dGVBcnJheUlucHV0U3RyZWFtKChVVEY4X0JPTV8yYnl0ZXMgKyBNSU5JTUFMX1hNTCkuZ2V0Qnl0ZXMoU3RhbmRhcmRDaGFyc2V0cy5JU09fODg1OV8xKSksIG9wdGlvbnMpOwoJCWFzc2VydE51bGwoIjguMCIsIGRlc2NyaXB0aW9uLmdldFByb3BlcnR5KElDb250ZW50RGVzY3JpcHRpb24uQllURV9PUkRFUl9NQVJLKSk7CgkJLy8gdHdvIGZpcnN0IGJ5dGVzIG9mIFVURi04IG9ubHkKCQlkZXNjcmlwdGlvbiA9IHRleHQuZ2V0RGVzY3JpcHRpb25Gb3IobmV3IEJ5dGVBcnJheUlucHV0U3RyZWFtKChVVEY4X0JPTV8yYnl0ZXMpLmdldEJ5dGVzKFN0YW5kYXJkQ2hhcnNldHMuSVNPXzg4NTlfMSkpLCBvcHRpb25zKTsKCQlhc3NlcnROdWxsKCI4LjEiLCBkZXNjcmlwdGlvbi5nZXRQcm9wZXJ0eShJQ29udGVudERlc2NyaXB0aW9uLkJZVEVfT1JERVJfTUFSSykpOwoJfQoKCS8qKgoJICogU2VlIGJ1ZyA5MDIxOC4KCSAqLwoJcHVibGljIHZvaWQgdGVzdENvbnRlbnRBbmROYW1lTWF0Y2hpbmcoKSB0aHJvd3MgSU9FeGNlcHRpb24gLyogbm90IHJlYWxseSAqLyB7CgkJSUNvbnRlbnRUeXBlTWFuYWdlciBtYW5hZ2VyID0gUGxhdGZvcm0uZ2V0Q29udGVudFR5cGVNYW5hZ2VyKCk7CgoJCWJ5dGVbXVtdIGNvbnRlbnRzMCA9IHt7MHgwQSwgMHgwQiwgMHgwRSwgMHgxMH19OwoJCWJ5dGVbXVtdIGNvbnRlbnRzMSA9IHt7MHgwQSwgMHgwQiwgMHgwQywgMHgxMH19OwoJCWJ5dGVbXVtdIGNvbnRlbnRzMiA9IHt7MHgwQSwgMHgwQiwgMHgwRCwgMHgxMH19OwoJCWJ5dGVbXVtdIGludmFsaWRDb250ZW50cyA9IHt7MCwgMCwgMCwgMH19OwoKCQkvLyBiYXNlIG1hdGNoZXMgKi5teWJpbmFyeSBmaWxlcyBzdGFydGluZyB3aXRoIDB4MGEgMHgwYgoJCUlDb250ZW50VHlwZSBiYXNlID0gbWFuYWdlci5nZXRDb250ZW50VHlwZShQSV9SRVNPVVJDRVNfVEVTVFMgKyAiLmJpbmFyeV9iYXNlIik7CgkJLy8gZGVyaXZlZDEgbWF0Y2hlcyAqLm15YmluYXJ5IGFuZCBzcGVjaWZpY2FsbHkgZm9vLm15YmluYXJ5IGZpbGVzIHN0YXJ0aW5nIHdpdGggMHgwYSAweDBiIDB4YwoJCUlDb250ZW50VHlwZSBkZXJpdmVkMSA9IG1hbmFnZXIuZ2V0Q29udGVudFR5cGUoUElfUkVTT1VSQ0VTX1RFU1RTICsgIi5iaW5hcnlfZGVyaXZlZDEiKTsKCQkvLyBkZXJpdmVkMiBtYXRjaGVzICoubXliaW5hcnkgKGluaGVyaXRzIGZpbGVzcGVjIGZyb20gYmFzZSkgZmlsZXMgc3RhcnRpbmcgd2l0aCAweDBhIDB4MGIgMHhkCgkJSUNvbnRlbnRUeXBlIGRlcml2ZWQyID0gbWFuYWdlci5nZXRDb250ZW50VHlwZShQSV9SRVNPVVJDRVNfVEVTVFMgKyAiLmJpbmFyeV9kZXJpdmVkMiIpOwoKCQlJQ29udGVudFR5cGVbXSBzZWxlY3RlZDsKCgkJc2VsZWN0ZWQgPSBtYW5hZ2VyLmZpbmRDb250ZW50VHlwZXNGb3IoZ2V0SW5wdXRTdHJlYW0oY29udGVudHMwKSwgImFueXRoaW5nLm15YmluYXJ5Iik7CgkJYXNzZXJ0RXF1YWxzKCIxLjAiLCAzLCBzZWxlY3RlZC5sZW5ndGgpOwoJCS8vIGFsbCB3ZSBrbm93IGlzIHRoZSBmaXJzdCBvbmUgaXMgdGhlIGJhc2UgdHlwZSAob25seSBvbmUgd2l0aCBhIFZBTElEIG1hdGNoKQoJCWFzc2VydEVxdWFscygiMS4xIiwgYmFzZSwgc2VsZWN0ZWRbMF0pOwoKCQlzZWxlY3RlZCA9IG1hbmFnZXIuZmluZENvbnRlbnRUeXBlc0ZvcihnZXRJbnB1dFN0cmVhbShjb250ZW50czApLCAiZm9vLm15YmluYXJ5Iik7CgkJLy8gd2Uga25vdyBhbHNvIHRoYXQgdGhlIHNlY29uZCBvbmUgd2lsbCBiZSBkZXJpdmVkMSwgYmVjYXVzZSBpdCBoYXMgYSBmdWxsIG5hbWUgbWF0Y2hpbmcKCQlhc3NlcnRFcXVhbHMoIjIuMCIsIDMsIHNlbGVjdGVkLmxlbmd0aCk7CgkJYXNzZXJ0RXF1YWxzKCIyLjEiLCBiYXNlLCBzZWxlY3RlZFswXSk7CgkJYXNzZXJ0RXF1YWxzKCIyLjIiLCBkZXJpdmVkMSwgc2VsZWN0ZWRbMV0pOwoKCQlzZWxlY3RlZCA9IG1hbmFnZXIuZmluZENvbnRlbnRUeXBlc0ZvcihnZXRJbnB1dFN0cmVhbShjb250ZW50czEpLCAiZm9vLm15YmluYXJ5Iik7CgkJLy8gZGVyaXZlZDEgd2lsbCBiZSBmaXJzdCBiZWNhdXNlIGJvdGggYmFzZSBhbmQgZGVyaXZlZDEgaGF2ZSBhIHN0cm9uZyBjb250ZW50IG1hdGNoaW5nLCBzbyBtb3JlIHNwZWNpZmljIHdpbnMKCQlhc3NlcnRFcXVhbHMoIjMuMCIsIDMsIHNlbGVjdGVkLmxlbmd0aCk7CgkJYXNzZXJ0RXF1YWxzKCIzLjEiLCBkZXJpdmVkMSwgc2VsZWN0ZWRbMF0pOwoJCWFzc2VydEVxdWFscygiMy4yIiwgYmFzZSwgc2VsZWN0ZWRbMV0pOwoKCQlzZWxlY3RlZCA9IG1hbmFnZXIuZmluZENvbnRlbnRUeXBlc0ZvcihnZXRJbnB1dFN0cmVhbShjb250ZW50czIpLCAiZm9vLm15YmluYXJ5Iik7CgkJLy8gc2FtZSBhcyAzLiogLSBkZXJpdmVkMSBpcyBsYXN0IGJlY2F1c2UgY29udGVudCBtYXRjaGluZyBpcyB3ZWFrLCBhbHRob3VnIG5hbWUgbWF0Y2hpbmcgaXMgc3Ryb25nCgkJYXNzZXJ0RXF1YWxzKCI0LjAiLCAzLCBzZWxlY3RlZC5sZW5ndGgpOwoJCWFzc2VydEVxdWFscygiNC4xIiwgZGVyaXZlZDIsIHNlbGVjdGVkWzBdKTsKCQlhc3NlcnRFcXVhbHMoIjQuMiIsIGJhc2UsIHNlbGVjdGVkWzFdKTsKCgkJc2VsZWN0ZWQgPSBtYW5hZ2VyLmZpbmRDb250ZW50VHlwZXNGb3IoZ2V0SW5wdXRTdHJlYW0oaW52YWxpZENvbnRlbnRzKSwgImZvby5teWJpbmFyeSIpOwoJCS8vIGFsbCB0eXBlcyBoYXZlIHdlYWsgY29udGVudCBtYXRjaGluZyBvbmx5IC0gZGVyaXZlZDEgaGFzIHN0cm9uZyBuYW1lIG1hdGNoaW5nCgkJYXNzZXJ0RXF1YWxzKCI1LjAiLCAzLCBzZWxlY3RlZC5sZW5ndGgpOwoJCWFzc2VydEVxdWFscygiNS4xIiwgZGVyaXZlZDEsIHNlbGVjdGVkWzBdKTsKCQlhc3NlcnRFcXVhbHMoIjUuMiIsIGJhc2UsIHNlbGVjdGVkWzFdKTsKCgkJc2VsZWN0ZWQgPSBtYW5hZ2VyLmZpbmRDb250ZW50VHlwZXNGb3IoZ2V0SW5wdXRTdHJlYW0oaW52YWxpZENvbnRlbnRzKSwgImFueXRoaW5nLm15YmluYXJ5Iik7CgkJLy8gYWxsIHR5cGVzIGhhdmUgd2VhayBjb250ZW50L25hbWUgbWF0Y2hpbmcgb25seSAtIG1vc3QgZ2VuZXJhbCB3aW5zCgkJYXNzZXJ0RXF1YWxzKCI2LjAiLCAzLCBzZWxlY3RlZC5sZW5ndGgpOwoJCWFzc2VydEVxdWFscygiNi4xIiwgYmFzZSwgc2VsZWN0ZWRbMF0pOwoJfQoKCS8qCgkgKiBUZXN0cyBib3RoIHRleHQgYW5kIGJ5dGUgc3RyZWFtLWJhc2VkIGdldERlc2NyaXB0aW9uRm9yIG1ldGhvZHMuCgkgKi8KCXB1YmxpYyB2b2lkIHRlc3RDb250ZW50RGVzY3JpcHRpb24oKSB0aHJvd3MgSU9FeGNlcHRpb24sIENvcmVFeGNlcHRpb24gewoJCUlDb250ZW50VHlwZU1hbmFnZXIgY29udGVudFR5cGVNYW5hZ2VyID0gUGxhdGZvcm0uZ2V0Q29udGVudFR5cGVNYW5hZ2VyKCk7CgkJSUNvbnRlbnRUeXBlTWF0Y2hlciBmaW5kZXIgPSBjb250ZW50VHlwZU1hbmFnZXIuZ2V0TWF0Y2hlcihuZXcgTG9jYWxTZWxlY3Rpb25Qb2xpY3koKSwgbnVsbCk7CgoJCUlDb250ZW50VHlwZSB4bWxUeXBlID0gY29udGVudFR5cGVNYW5hZ2VyLmdldENvbnRlbnRUeXBlKFBsYXRmb3JtLlBJX1JVTlRJTUUgKyAiLnhtbCIpOwoJCUlDb250ZW50VHlwZSBteXRleHQgPSBjb250ZW50VHlwZU1hbmFnZXIuZ2V0Q29udGVudFR5cGUoUElfUkVTT1VSQ0VTX1RFU1RTICsgJy4nICsgIm15dGV4dCIpOwoJCUlDb250ZW50VHlwZSBteXRleHQxID0gY29udGVudFR5cGVNYW5hZ2VyLmdldENvbnRlbnRUeXBlKFBJX1JFU09VUkNFU19URVNUUyArICcuJyArICJteXRleHQxIik7CgkJSUNvbnRlbnRUeXBlIG15dGV4dDIgPSBjb250ZW50VHlwZU1hbmFnZXIuZ2V0Q29udGVudFR5cGUoUElfUkVTT1VSQ0VTX1RFU1RTICsgJy4nICsgIm15dGV4dDIiKTsKCgkJYm9vbGVhbiB0ZXh0ID0gZmFsc2U7CgoJCWZvciAoaW50IGkgPSAwOyBpIDwgMjsgaSsrLCB0ZXh0ID0gIXRleHQpIHsKCQkJU3RyaW5nIHN1Zml4ID0gdGV4dCA/ICItdGV4dCIgOiAiLWJpbmFyeSI7CgkJCUlDb250ZW50RGVzY3JpcHRpb24gZGVzY3JpcHRpb247CgoJCQlkZXNjcmlwdGlvbiA9IGdldERlc2NyaXB0aW9uRm9yKGZpbmRlciwgTUlOSU1BTF9YTUwsIFN0YW5kYXJkQ2hhcnNldHMuVVRGXzgsICJmb28ueG1sIiwgSUNvbnRlbnREZXNjcmlwdGlvbi5BTEwsIHRleHQpOwoJCQlhc3NlcnROb3ROdWxsKCIxLjAiICsgc3VmaXgsIGRlc2NyaXB0aW9uKTsKCQkJYXNzZXJ0RXF1YWxzKCIxLjEiICsgc3VmaXgsIHhtbFR5cGUsIGRlc2NyaXB0aW9uLmdldENvbnRlbnRUeXBlKCkpOwoJCQlhc3NlcnRTYW1lKCIxLjIiLCB4bWxUeXBlLmdldERlZmF1bHREZXNjcmlwdGlvbigpLCBkZXNjcmlwdGlvbik7CgoJCQlkZXNjcmlwdGlvbiA9IGdldERlc2NyaXB0aW9uRm9yKGZpbmRlciwgTUlOSU1BTF9YTUwsIFN0YW5kYXJkQ2hhcnNldHMuVVRGXzgsICJmb28ueG1sIiwgbmV3IFF1YWxpZmllZE5hbWVbXSB7SUNvbnRlbnREZXNjcmlwdGlvbi5DSEFSU0VUfSwgdGV4dCk7CgkJCWFzc2VydE5vdE51bGwoIjIuMCIgKyBzdWZpeCwgZGVzY3JpcHRpb24pOwoJCQlhc3NlcnRFcXVhbHMoIjIuMSIgKyBzdWZpeCwgeG1sVHlwZSwgZGVzY3JpcHRpb24uZ2V0Q29udGVudFR5cGUoKSk7CgkJCS8vIHRoZSBkZWZhdWx0IGNoYXJzZXQgc2hvdWxkIGhhdmUgYmVlbiBmaWxsZWQgYnkgdGhlIGNvbnRlbnQgdHlwZSBtYW5hZ2VyCgkJCWFzc2VydEVxdWFscygiMi4yIiArIHN1Zml4LCAiVVRGLTgiLCBkZXNjcmlwdGlvbi5nZXRQcm9wZXJ0eShJQ29udGVudERlc2NyaXB0aW9uLkNIQVJTRVQpKTsKCQkJYXNzZXJ0U2FtZSgiMi4zIiwgeG1sVHlwZS5nZXREZWZhdWx0RGVzY3JpcHRpb24oKSwgZGVzY3JpcHRpb24pOwoKCQkJZGVzY3JpcHRpb24gPSBnZXREZXNjcmlwdGlvbkZvcihmaW5kZXIsIFhNTF9JU09fODg1OV8xLCBTdGFuZGFyZENoYXJzZXRzLklTT184ODU5XzEsICJmb28ueG1sIiwgbmV3IFF1YWxpZmllZE5hbWVbXSB7SUNvbnRlbnREZXNjcmlwdGlvbi5DSEFSU0VUfSwgdGV4dCk7CgkJCWFzc2VydE5vdE51bGwoIjIuM2EiICsgc3VmaXgsIGRlc2NyaXB0aW9uKTsKCQkJYXNzZXJ0RXF1YWxzKCIyLjNiIiArIHN1Zml4LCB4bWxUeXBlLCBkZXNjcmlwdGlvbi5nZXRDb250ZW50VHlwZSgpKTsKCQkJYXNzZXJ0RXF1YWxzKCIyLjNjIiArIHN1Zml4LCAiSVNPLTg4NTktMSIsIGRlc2NyaXB0aW9uLmdldFByb3BlcnR5KElDb250ZW50RGVzY3JpcHRpb24uQ0hBUlNFVCkpOwoJCQlhc3NlcnROb3RTYW1lKCIyLjNkIiwgeG1sVHlwZS5nZXREZWZhdWx0RGVzY3JpcHRpb24oKSwgZGVzY3JpcHRpb24pOwoKCQkJLy8gZW5zdXJlIHdlIGhhbmRsZSBzaW5nbGUgcXVvdGVzIHByb3Blcmx5IChidWcgNjU0NDMpCgkJCWRlc2NyaXB0aW9uID0gZ2V0RGVzY3JpcHRpb25Gb3IoZmluZGVyLCBYTUxfSVNPXzg4NTlfMV9TSU5HTEVfUVVPVEVTLCBTdGFuZGFyZENoYXJzZXRzLklTT184ODU5XzEsICJmb28ueG1sIiwgbmV3IFF1YWxpZmllZE5hbWVbXSB7SUNvbnRlbnREZXNjcmlwdGlvbi5DSEFSU0VUfSwgdGV4dCk7CgkJCWFzc2VydE5vdE51bGwoIjIuM2UiICsgc3VmaXgsIGRlc2NyaXB0aW9uKTsKCQkJYXNzZXJ0RXF1YWxzKCIyLjNmIiArIHN1Zml4LCB4bWxUeXBlLCBkZXNjcmlwdGlvbi5nZXRDb250ZW50VHlwZSgpKTsKCQkJYXNzZXJ0RXF1YWxzKCIyLjNnIiArIHN1Zml4LCAiSVNPLTg4NTktMSIsIGRlc2NyaXB0aW9uLmdldFByb3BlcnR5KElDb250ZW50RGVzY3JpcHRpb24uQ0hBUlNFVCkpOwoJCQlhc3NlcnROb3RTYW1lKCIyLjNoIiwgeG1sVHlwZS5nZXREZWZhdWx0RGVzY3JpcHRpb24oKSwgZGVzY3JpcHRpb24pOwoKCQkJZGVzY3JpcHRpb24gPSBnZXREZXNjcmlwdGlvbkZvcihmaW5kZXIsIFhNTF9VVEZfMTYsIFN0YW5kYXJkQ2hhcnNldHMuVVRGXzE2LCAiZm9vLnhtbCIsIG5ldyBRdWFsaWZpZWROYW1lW10ge0lDb250ZW50RGVzY3JpcHRpb24uQ0hBUlNFVCwgSUNvbnRlbnREZXNjcmlwdGlvbi5CWVRFX09SREVSX01BUkt9LCB0ZXh0KTsKCQkJYXNzZXJ0Tm90TnVsbCgiMi40YSIgKyBzdWZpeCwgZGVzY3JpcHRpb24pOwoJCQlhc3NlcnRFcXVhbHMoIjIuNGIiICsgc3VmaXgsIHhtbFR5cGUsIGRlc2NyaXB0aW9uLmdldENvbnRlbnRUeXBlKCkpOwoJCQlhc3NlcnRFcXVhbHMoIjIuNGMiICsgc3VmaXgsICJVVEYtMTYiLCBkZXNjcmlwdGlvbi5nZXRQcm9wZXJ0eShJQ29udGVudERlc2NyaXB0aW9uLkNIQVJTRVQpKTsKCQkJYXNzZXJ0VHJ1ZSgiMi40ZCIgKyBzdWZpeCwgdGV4dCB8fCBJQ29udGVudERlc2NyaXB0aW9uLkJPTV9VVEZfMTZCRSA9PSBkZXNjcmlwdGlvbi5nZXRQcm9wZXJ0eShJQ29udGVudERlc2NyaXB0aW9uLkJZVEVfT1JERVJfTUFSSykpOwoJCQlhc3NlcnROb3RTYW1lKCIyLjRlIiwgeG1sVHlwZS5nZXREZWZhdWx0RGVzY3JpcHRpb24oKSwgZGVzY3JpcHRpb24pOwoKCQkJZGVzY3JpcHRpb24gPSBnZXREZXNjcmlwdGlvbkZvcihmaW5kZXIsIFhNTF9VVEZfMTZCRSwgU3RhbmRhcmRDaGFyc2V0cy5VVEZfOCwgImZvby54bWwiLCBuZXcgUXVhbGlmaWVkTmFtZVtdIHtJQ29udGVudERlc2NyaXB0aW9uLkNIQVJTRVR9LCB0ZXh0KTsKCQkJYXNzZXJ0Tm90TnVsbCgiMi41YSIgKyBzdWZpeCwgZGVzY3JpcHRpb24pOwoJCQlhc3NlcnRFcXVhbHMoIjIuNWIiICsgc3VmaXgsIHhtbFR5cGUsIGRlc2NyaXB0aW9uLmdldENvbnRlbnRUeXBlKCkpOwoJCQlhc3NlcnRFcXVhbHMoIjIuNWMiICsgc3VmaXgsICJVVEYtMTZCRSIsIGRlc2NyaXB0aW9uLmdldFByb3BlcnR5KElDb250ZW50RGVzY3JpcHRpb24uQ0hBUlNFVCkpOwoJCQlhc3NlcnROb3RTYW1lKCIyLjVkIiwgeG1sVHlwZS5nZXREZWZhdWx0RGVzY3JpcHRpb24oKSwgZGVzY3JpcHRpb24pOwoKCQkJZGVzY3JpcHRpb24gPSBnZXREZXNjcmlwdGlvbkZvcihmaW5kZXIsIFhNTF9VVEZfMTZMRSwgU3RhbmRhcmRDaGFyc2V0cy5VVEZfOCwgImZvby54bWwiLCBuZXcgUXVhbGlmaWVkTmFtZVtdIHtJQ29udGVudERlc2NyaXB0aW9uLkNIQVJTRVR9LCB0ZXh0KTsKCQkJYXNzZXJ0Tm90TnVsbCgiMi42YSIgKyBzdWZpeCwgZGVzY3JpcHRpb24pOwoJCQlhc3NlcnRFcXVhbHMoIjIuNmIiICsgc3VmaXgsIHhtbFR5cGUsIGRlc2NyaXB0aW9uLmdldENvbnRlbnRUeXBlKCkpOwoJCQkvLyB0aGUgZGVmYXVsdCBjaGFyc2V0IHNob3VsZCBoYXZlIGJlZW4gZmlsbGVkIGJ5IHRoZSBjb250ZW50IHR5cGUgbWFuYWdlcgoJCQlhc3NlcnRFcXVhbHMoIjIuNmMiICsgc3VmaXgsICJVVEYtMTZMRSIsIGRlc2NyaXB0aW9uLmdldFByb3BlcnR5KElDb250ZW50RGVzY3JpcHRpb24uQ0hBUlNFVCkpOwoJCQlhc3NlcnROb3RTYW1lKCIyLjZkIiwgeG1sVHlwZS5nZXREZWZhdWx0RGVzY3JpcHRpb24oKSwgZGVzY3JpcHRpb24pOwoKCQkJZGVzY3JpcHRpb24gPSBnZXREZXNjcmlwdGlvbkZvcihmaW5kZXIsIE1JTklNQUxfWE1MLCBTdGFuZGFyZENoYXJzZXRzLlVURl84LCAiZm9vLnhtbCIsIElDb250ZW50RGVzY3JpcHRpb24uQUxMLCB0ZXh0KTsKCQkJYXNzZXJ0Tm90TnVsbCgiNC4wIiArIHN1Zml4LCBkZXNjcmlwdGlvbik7CgkJCWFzc2VydEVxdWFscygiNC4xIiArIHN1Zml4LCB4bWxUeXBlLCBkZXNjcmlwdGlvbi5nZXRDb250ZW50VHlwZSgpKTsKCQkJYXNzZXJ0RXF1YWxzKCI0LjIiICsgc3VmaXgsICJVVEYtOCIsIGRlc2NyaXB0aW9uLmdldFByb3BlcnR5KElDb250ZW50RGVzY3JpcHRpb24uQ0hBUlNFVCkpOwoJCQlhc3NlcnROb3ROdWxsKCI1LjAiICsgc3VmaXgsIG15dGV4dCk7CgkJCWFzc2VydEVxdWFscygiNS4wYiIgKyBzdWZpeCwgIkJBUiIsIG15dGV4dC5nZXREZWZhdWx0Q2hhcnNldCgpKTsKCQkJYXNzZXJ0U2FtZSgiNS4wYyIsIHhtbFR5cGUuZ2V0RGVmYXVsdERlc2NyaXB0aW9uKCksIGRlc2NyaXB0aW9uKTsKCgkJCWRlc2NyaXB0aW9uID0gZ2V0RGVzY3JpcHRpb25Gb3IoZmluZGVyLCAic29tZSBjb250ZW50cyIsIG51bGwsICJhYmMudHp0IiwgSUNvbnRlbnREZXNjcmlwdGlvbi5BTEwsIHRleHQpOwoJCQlhc3NlcnROb3ROdWxsKCI1LjEiICsgc3VmaXgsIGRlc2NyaXB0aW9uKTsKCQkJYXNzZXJ0RXF1YWxzKCI1LjIiICsgc3VmaXgsIG15dGV4dCwgZGVzY3JpcHRpb24uZ2V0Q29udGVudFR5cGUoKSk7CgkJCWFzc2VydEVxdWFscygiNS4zIiArIHN1Zml4LCAiQkFSIiwgZGVzY3JpcHRpb24uZ2V0UHJvcGVydHkoSUNvbnRlbnREZXNjcmlwdGlvbi5DSEFSU0VUKSk7CgkJCWFzc2VydFNhbWUoIjUuNCIsIG15dGV4dC5nZXREZWZhdWx0RGVzY3JpcHRpb24oKSwgZGVzY3JpcHRpb24pOwoJCQkvLyBub3cgcGxheXMgd2l0aCBzZXR0aW5nIGEgbm9uLWRlZmF1bHQgZGVmYXVsdCBjaGFyc2V0CgkJCW15dGV4dC5zZXREZWZhdWx0Q2hhcnNldCgiRk9PIik7CgoJCQlkZXNjcmlwdGlvbiA9IGdldERlc2NyaXB0aW9uRm9yKGZpbmRlciwgInNvbWUgY29udGVudHMiLCBudWxsLCAiYWJjLnR6dCIsIElDb250ZW50RGVzY3JpcHRpb24uQUxMLCB0ZXh0KTsKCQkJYXNzZXJ0Tm90TnVsbCgiNS41IiArIHN1Zml4LCBkZXNjcmlwdGlvbik7CgkJCWFzc2VydEVxdWFscygiNS42IiArIHN1Zml4LCBteXRleHQsIGRlc2NyaXB0aW9uLmdldENvbnRlbnRUeXBlKCkpOwoJCQlhc3NlcnRFcXVhbHMoIjUuNyIgKyBzdWZpeCwgIkZPTyIsIGRlc2NyaXB0aW9uLmdldFByb3BlcnR5KElDb250ZW50RGVzY3JpcHRpb24uQ0hBUlNFVCkpOwoJCQlhc3NlcnRTYW1lKCI1LjgiLCBteXRleHQuZ2V0RGVmYXVsdERlc2NyaXB0aW9uKCksIGRlc2NyaXB0aW9uKTsKCQkJbXl0ZXh0LnNldERlZmF1bHRDaGFyc2V0KG51bGwpOwoKCQkJZGVzY3JpcHRpb24gPSBnZXREZXNjcmlwdGlvbkZvcihmaW5kZXIsICJzb21lIGNvbnRlbnRzIiwgbnVsbCwgImFiYy50enQiLCBJQ29udGVudERlc2NyaXB0aW9uLkFMTCwgdGV4dCk7CgkJCWFzc2VydE5vdE51bGwoIjUuMTAiICsgc3VmaXgsIGRlc2NyaXB0aW9uKTsKCQkJYXNzZXJ0RXF1YWxzKCI1LjExIiArIHN1Zml4LCBteXRleHQsIGRlc2NyaXB0aW9uLmdldENvbnRlbnRUeXBlKCkpOwoJCQlhc3NlcnRFcXVhbHMoIjUuMTIiICsgc3VmaXgsICJCQVIiLCBkZXNjcmlwdGlvbi5nZXRQcm9wZXJ0eShJQ29udGVudERlc2NyaXB0aW9uLkNIQVJTRVQpKTsKCQkJYXNzZXJ0U2FtZSgiNS4xMyIsIG15dGV4dC5nZXREZWZhdWx0RGVzY3JpcHRpb24oKSwgZGVzY3JpcHRpb24pOwoKCQkJLy8gc2VlIGh0dHBzOi8vYnVncy5lY2xpcHNlLm9yZy9idWdzL3Nob3dfYnVnLmNnaT9pZD0xNzYzNTQKCQkJZGVzY3JpcHRpb24gPSBnZXREZXNjcmlwdGlvbkZvcihmaW5kZXIsICI8P3htbCB2ZXJzaW9uPVwnMS4wXCcgZW5jb2Rpbmc9XCdVVEYtOFwnPz48c29hcGVudjpFbnZlbG9wZSB4bWxuczpzb2FwZW52PVwiaHR0cDovL3NjaGVtYXMueG1sc29hcC5vcmcvc29hcC9lbnZlbG9wZS9cIiB4bWxuczp0bnM9XCJodHRwOi8vd3d3LmV4YW1wbGUub3JnL1wiIHhtbG5zOm5zMD1cImh0dHA6Ly9hbm90aGVyLmV4YW1wbGUub3JnL1wiPjxzb2FwZW52OkhlYWRlciAvPjxzb2FwZW52OkJvZHk+PG5zMDp4IC8+PC9zb2FwZW52OkJvZHk+PC9zb2FwZW52OkVudmVsb3BlPiIsIFN0YW5kYXJkQ2hhcnNldHMuVVRGXzgsICJmb28ueG1sIiwgbmV3IFF1YWxpZmllZE5hbWVbXSB7SUNvbnRlbnREZXNjcmlwdGlvbi5DSEFSU0VUfSwgdGV4dCk7CgkJCWFzc2VydE5vdE51bGwoIjUuMTQiICsgc3VmaXgsIGRlc2NyaXB0aW9uKTsKCQkJYXNzZXJ0RXF1YWxzKCI1LjE1IiArIHN1Zml4LCB4bWxUeXBlLCBkZXNjcmlwdGlvbi5nZXRDb250ZW50VHlwZSgpKTsKCQkJYXNzZXJ0RXF1YWxzKCI1LjE2IiArIHN1Zml4LCAiVVRGLTgiLCBkZXNjcmlwdGlvbi5nZXRQcm9wZXJ0eShJQ29udGVudERlc2NyaXB0aW9uLkNIQVJTRVQpKTsKCQkJYXNzZXJ0RXF1YWxzKCI1LjE3IiwgeG1sVHlwZS5nZXREZWZhdWx0RGVzY3JpcHRpb24oKS5nZXRDaGFyc2V0KCksIGRlc2NyaXB0aW9uLmdldENoYXJzZXQoKSk7CgkJfQoJCWFzc2VydE5vdE51bGwoIjYuMCIsIG15dGV4dDEpOwoJCWFzc2VydEVxdWFscygiNi4xIiwgIkJBUiIsIG15dGV4dDEuZ2V0RGVmYXVsdENoYXJzZXQoKSk7CgkJYXNzZXJ0Tm90TnVsbCgiNi4yIiwgbXl0ZXh0Mik7CgkJYXNzZXJ0RXF1YWxzKCI2LjMiLCBudWxsLCBteXRleHQyLmdldERlZmF1bHRDaGFyc2V0KCkpOwoKCX0KCgkvKioKCSAqIEBzZWUgSUNvbnRlbnRUeXBlTWF0Y2hlciNmaW5kQ29udGVudFR5cGVGb3IKCSAqLwoJcHVibGljIHZvaWQgdGVzdENvbnRlbnREZXRlY3Rpb24oKSB0aHJvd3MgSU9FeGNlcHRpb24gewoJCUlDb250ZW50VHlwZU1hbmFnZXIgY29udGVudFR5cGVNYW5hZ2VyID0gUGxhdGZvcm0uZ2V0Q29udGVudFR5cGVNYW5hZ2VyKCk7CgkJSUNvbnRlbnRUeXBlTWF0Y2hlciBmaW5kZXI7CgoJCUlDb250ZW50VHlwZSBpbmFwcHJvcHJpYXRlID0gY29udGVudFR5cGVNYW5hZ2VyLmdldENvbnRlbnRUeXBlKFBJX1JFU09VUkNFU19URVNUUyArICIuc2FtcGxlLWJpbmFyeTEiKTsKCQlJQ29udGVudFR5cGUgYXBwcm9wcmlhdGUgPSBjb250ZW50VHlwZU1hbmFnZXIuZ2V0Q29udGVudFR5cGUoUGxhdGZvcm0uUElfUlVOVElNRSArICIueG1sIik7CgkJSUNvbnRlbnRUeXBlIGFwcHJvcHJpYXRlU3BlY2lmaWMxID0gY29udGVudFR5cGVNYW5hZ2VyLmdldENvbnRlbnRUeXBlKFBJX1JFU09VUkNFU19URVNUUyArICIueG1sLWJhc2VkLWRpZmZlcmVudC1leHRlbnNpb24iKTsKCQlJQ29udGVudFR5cGUgYXBwcm9wcmlhdGVTcGVjaWZpYzFMb3dQcmlvcml0eSA9IGNvbnRlbnRUeXBlTWFuYWdlci5nZXRDb250ZW50VHlwZShQSV9SRVNPVVJDRVNfVEVTVFMgKyAiLnhtbC1iYXNlZC1kaWZmZXJlbnQtZXh0ZW5zaW9uLWxvdy1wcmlvcml0eSIpOwoJCUlDb250ZW50VHlwZSBhcHByb3ByaWF0ZVNwZWNpZmljMiA9IGNvbnRlbnRUeXBlTWFuYWdlci5nZXRDb250ZW50VHlwZShQSV9SRVNPVVJDRVNfVEVTVFMgKyAiLnhtbC1iYXNlZC1zcGVjaWZpYy1uYW1lIik7CgoJCS8vIGlmIG9ubHkgaW5hcHByb3ByaWF0ZSBpcyBwcm92aWRlZCwgbm9uZSB3aWxsIGJlIHNlbGVjdGVkCgkJZmluZGVyID0gY29udGVudFR5cGVNYW5hZ2VyLmdldE1hdGNoZXIobmV3IFN1YnNldFNlbGVjdGlvblBvbGljeShuZXcgSUNvbnRlbnRUeXBlW10ge2luYXBwcm9wcmlhdGV9KSwgbnVsbCk7CgkJYXNzZXJ0TnVsbCgiMS4wIiwgZmluZGVyLmZpbmRDb250ZW50VHlwZUZvcihnZXRJbnB1dFN0cmVhbShNSU5JTUFMX1hNTCksIG51bGwpKTsKCgkJLy8gaWYgaW5hcHByb3ByaWF0ZSBhbmQgYXBwcm9wcmlhdGUgYXJlIHByb3ZpZGVkLCBhcHByb3ByaWF0ZSB3aWxsIGJlIHNlbGVjdGVkCgkJZmluZGVyID0gY29udGVudFR5cGVNYW5hZ2VyLmdldE1hdGNoZXIobmV3IFN1YnNldFNlbGVjdGlvblBvbGljeShuZXcgSUNvbnRlbnRUeXBlW10ge2luYXBwcm9wcmlhdGUsIGFwcHJvcHJpYXRlfSksIG51bGwpOwoJCWFzc2VydEVxdWFscygiMi4wIiwgYXBwcm9wcmlhdGUsIGZpbmRlci5maW5kQ29udGVudFR5cGVGb3IoZ2V0SW5wdXRTdHJlYW0oTUlOSU1BTF9YTUwpLCBudWxsKSk7CgoJCS8vIGlmIGluYXBwcm9wcmlhdGUsIGFwcHJvcHJpYXRlIGFuZCBhIG1vcmUgc3BlY2lmaWMgYXBwcm9wcmlhdGUgdHlwZSBhcmUgcHJvdmlkZWQsIHRoZSBzcGVjaWZpYyB0eXBlIHdpbGwgYmUgc2VsZWN0ZWQKCQlmaW5kZXIgPSBjb250ZW50VHlwZU1hbmFnZXIuZ2V0TWF0Y2hlcihuZXcgU3Vic2V0U2VsZWN0aW9uUG9saWN5KG5ldyBJQ29udGVudFR5cGVbXSB7aW5hcHByb3ByaWF0ZSwgYXBwcm9wcmlhdGUsIGFwcHJvcHJpYXRlU3BlY2lmaWMxfSksIG51bGwpOwoJCWFzc2VydEVxdWFscygiMy4wIiwgYXBwcm9wcmlhdGVTcGVjaWZpYzEsIGZpbmRlci5maW5kQ29udGVudFR5cGVGb3IoZ2V0SW5wdXRTdHJlYW0oTUlOSU1BTF9YTUwpLCBudWxsKSk7CgkJZmluZGVyID0gY29udGVudFR5cGVNYW5hZ2VyLmdldE1hdGNoZXIobmV3IFN1YnNldFNlbGVjdGlvblBvbGljeShuZXcgSUNvbnRlbnRUeXBlW10ge2luYXBwcm9wcmlhdGUsIGFwcHJvcHJpYXRlLCBhcHByb3ByaWF0ZVNwZWNpZmljMn0pLCBudWxsKTsKCQlhc3NlcnRFcXVhbHMoIjMuMSIsIGFwcHJvcHJpYXRlU3BlY2lmaWMyLCBmaW5kZXIuZmluZENvbnRlbnRUeXBlRm9yKGdldElucHV0U3RyZWFtKE1JTklNQUxfWE1MKSwgbnVsbCkpOwoKCQkvLyBpZiBhbGwgYXJlIHByb3ZpZGVkLCB0aGUgbW9yZSBzcGVjaWZpYyB0eXBlcyB3aWxsIGFwcGVhciBiZWZvcmUgdGhlIG1vcmUgZ2VuZXJpYyB0eXBlcwoJCWZpbmRlciA9IGNvbnRlbnRUeXBlTWFuYWdlci5nZXRNYXRjaGVyKG5ldyBTdWJzZXRTZWxlY3Rpb25Qb2xpY3kobmV3IElDb250ZW50VHlwZVtdIHtpbmFwcHJvcHJpYXRlLCBhcHByb3ByaWF0ZSwgYXBwcm9wcmlhdGVTcGVjaWZpYzEsIGFwcHJvcHJpYXRlU3BlY2lmaWMyfSksIG51bGwpOwoJCUlDb250ZW50VHlwZVtdIHNlbGVjdGVkID0gZmluZGVyLmZpbmRDb250ZW50VHlwZXNGb3IoZ2V0SW5wdXRTdHJlYW0oTUlOSU1BTF9YTUwpLCBudWxsKTsKCQlhc3NlcnRFcXVhbHMoIjQuMCIsIDMsIHNlbGVjdGVkLmxlbmd0aCk7CgkJYXNzZXJ0VHJ1ZSgiNC4xIiwgYXBwcm9wcmlhdGVTcGVjaWZpYzEuZXF1YWxzKHNlbGVjdGVkWzBdKSB8fCBhcHByb3ByaWF0ZVNwZWNpZmljMS5lcXVhbHMoc2VsZWN0ZWRbMV0pKTsKCQlhc3NlcnRUcnVlKCI0LjIiLCBhcHByb3ByaWF0ZVNwZWNpZmljMi5lcXVhbHMoc2VsZWN0ZWRbMF0pIHx8IGFwcHJvcHJpYXRlU3BlY2lmaWMyLmVxdWFscyhzZWxlY3RlZFsxXSkpOwoJCWFzc2VydFRydWUoIjQuMyIsIGFwcHJvcHJpYXRlLmVxdWFscyhzZWxlY3RlZFsyXSkpOwoKCQkvLyBpZiBhcHByb3ByaWF0ZSBhbmQgYSBtb3JlIHNwZWNpZmljIGFwcHJvcHJpYXRlIHR5cGUgKGJ1dCB3aXRoIGxvdyBwcmlvcml0eSkgYXJlIHByb3ZpZGVkLCB0aGUgc3BlY2lmaWMgdHlwZSB3aWxsIGJlIHNlbGVjdGVkCgkJZmluZGVyID0gY29udGVudFR5cGVNYW5hZ2VyLmdldE1hdGNoZXIobmV3IFN1YnNldFNlbGVjdGlvblBvbGljeShuZXcgSUNvbnRlbnRUeXBlW10ge2FwcHJvcHJpYXRlLCBhcHByb3ByaWF0ZVNwZWNpZmljMUxvd1ByaW9yaXR5fSksIG51bGwpOwoJCWFzc2VydEVxdWFscygiNS4wIiwgYXBwcm9wcmlhdGVTcGVjaWZpYzFMb3dQcmlvcml0eSwgZmluZGVyLmZpbmRDb250ZW50VHlwZUZvcihnZXRJbnB1dFN0cmVhbShNSU5JTUFMX1hNTCksIG51bGwpKTsKCgkJLy8gaWYgYXBwcm9wcmlhdGUgYW5kIHR3byBzcGVjaWZpYyBhcHByb3ByaWF0ZSB0eXBlcyAoYnV0IG9uZSB3aXRoIGxvd2VyIHByaW9yaXR5KSBhcmUgcHJvdmlkZWQsIHRoZSBzcGVjaWZpYyB0eXBlIHdpdGggaGlnaGVyIHByaW9yaXR5IHdpbGwgYmUgc2VsZWN0ZWQKCQlmaW5kZXIgPSBjb250ZW50VHlwZU1hbmFnZXIuZ2V0TWF0Y2hlcihuZXcgU3Vic2V0U2VsZWN0aW9uUG9saWN5KG5ldyBJQ29udGVudFR5cGVbXSB7YXBwcm9wcmlhdGUsIGFwcHJvcHJpYXRlU3BlY2lmaWMxLCBhcHByb3ByaWF0ZVNwZWNpZmljMUxvd1ByaW9yaXR5fSksIG51bGwpOwoJCWFzc2VydEVxdWFscygiNS4xIiwgYXBwcm9wcmlhdGVTcGVjaWZpYzEsIGZpbmRlci5maW5kQ29udGVudFR5cGVGb3IoZ2V0SW5wdXRTdHJlYW0oTUlOSU1BTF9YTUwpLCBudWxsKSk7Cgl9CgoJcHVibGljIHZvaWQgdGVzdERlZmF1bHRQcm9wZXJ0aWVzKCkgdGhyb3dzIElPRXhjZXB0aW9uIC8qIG5ldmVyIGFjdHVhbGx5IHRocm93biAqLyB7CgkJSUNvbnRlbnRUeXBlTWFuYWdlciBjb250ZW50VHlwZU1hbmFnZXIgPSBQbGF0Zm9ybS5nZXRDb250ZW50VHlwZU1hbmFnZXIoKTsKCgkJSUNvbnRlbnRUeXBlIG15dGV4dCA9IGNvbnRlbnRUeXBlTWFuYWdlci5nZXRDb250ZW50VHlwZShQSV9SRVNPVVJDRVNfVEVTVFMgKyAnLicgKyAibXl0ZXh0Iik7CgkJSUNvbnRlbnRUeXBlIG15dGV4dDEgPSBjb250ZW50VHlwZU1hbmFnZXIuZ2V0Q29udGVudFR5cGUoUElfUkVTT1VSQ0VTX1RFU1RTICsgJy4nICsgIm15dGV4dDEiKTsKCQlJQ29udGVudFR5cGUgbXl0ZXh0MiA9IGNvbnRlbnRUeXBlTWFuYWdlci5nZXRDb250ZW50VHlwZShQSV9SRVNPVVJDRVNfVEVTVFMgKyAnLicgKyAibXl0ZXh0MiIpOwoJCWFzc2VydE5vdE51bGwoIjAuMSIsIG15dGV4dCk7CgkJYXNzZXJ0Tm90TnVsbCgiMC4yIiwgbXl0ZXh0MSk7CgkJYXNzZXJ0Tm90TnVsbCgiMC4zIiwgbXl0ZXh0Mik7CgoJCVF1YWxpZmllZE5hbWUgY2hhcnNldCA9IElDb250ZW50RGVzY3JpcHRpb24uQ0hBUlNFVDsKCQlRdWFsaWZpZWROYW1lIGxvY2FsQ2hhcnNldCA9IG5ldyBRdWFsaWZpZWROYW1lKFBJX1JFU09VUkNFU19URVNUUywgImNoYXJzZXQiKTsKCQlRdWFsaWZpZWROYW1lIHByb3BlcnR5MSA9IG5ldyBRdWFsaWZpZWROYW1lKFBJX1JFU09VUkNFU19URVNUUywgInByb3BlcnR5MSIpOwoJCVF1YWxpZmllZE5hbWUgcHJvcGVydHkyID0gbmV3IFF1YWxpZmllZE5hbWUoUElfUkVTT1VSQ0VTX1RFU1RTLCAicHJvcGVydHkyIik7CgkJUXVhbGlmaWVkTmFtZSBwcm9wZXJ0eTMgPSBuZXcgUXVhbGlmaWVkTmFtZShQSV9SRVNPVVJDRVNfVEVTVFMsICJwcm9wZXJ0eTMiKTsKCQlRdWFsaWZpZWROYW1lIHByb3BlcnR5NCA9IG5ldyBRdWFsaWZpZWROYW1lKFBJX1JFU09VUkNFU19URVNUUywgInByb3BlcnR5NCIpOwoKCQlJQ29udGVudERlc2NyaXB0aW9uIGRlc2NyaXB0aW9uOwoJCUlDb250ZW50VHlwZU1hdGNoZXIgZmluZGVyID0gY29udGVudFR5cGVNYW5hZ2VyLmdldE1hdGNoZXIobmV3IExvY2FsU2VsZWN0aW9uUG9saWN5KCksIG51bGwpOwoKCQlkZXNjcmlwdGlvbiA9IGdldERlc2NyaXB0aW9uRm9yKGZpbmRlciwgInNvbWUgY29udGVudHMiLCBudWxsLCAiYWJjLnR6dCIsIElDb250ZW50RGVzY3JpcHRpb24uQUxMLCB0cnVlKTsKCQlhc3NlcnROb3ROdWxsKCIxLjAiLCBkZXNjcmlwdGlvbik7CgkJYXNzZXJ0RXF1YWxzKCIxLjEiLCBteXRleHQsIGRlc2NyaXB0aW9uLmdldENvbnRlbnRUeXBlKCkpOwoJCWFzc2VydEVxdWFscygiMS4yIiwgInZhbHVlMSIsIGRlc2NyaXB0aW9uLmdldFByb3BlcnR5KHByb3BlcnR5MSkpOwoJCWFzc2VydE51bGwoIjEuMyIsIGRlc2NyaXB0aW9uLmdldFByb3BlcnR5KHByb3BlcnR5MikpOwoJCWFzc2VydEVxdWFscygiMS40IiwgInZhbHVlMyIsIGRlc2NyaXB0aW9uLmdldFByb3BlcnR5KHByb3BlcnR5MykpOwoJCWFzc2VydEVxdWFscygiMS41IiwgIkJBUiIsIGRlc2NyaXB0aW9uLmdldFByb3BlcnR5KGNoYXJzZXQpKTsKCgkJZGVzY3JpcHRpb24gPSBnZXREZXNjcmlwdGlvbkZvcihmaW5kZXIsICJzb21lIGNvbnRlbnRzIiwgbnVsbCwgImFiYy50enQxIiwgSUNvbnRlbnREZXNjcmlwdGlvbi5BTEwsIHRydWUpOwoJCWFzc2VydE5vdE51bGwoIjIuMCIsIGRlc2NyaXB0aW9uKTsKCQlhc3NlcnRFcXVhbHMoIjIuMSIsIG15dGV4dDEsIGRlc2NyaXB0aW9uLmdldENvbnRlbnRUeXBlKCkpOwoJCWFzc2VydEVxdWFscygiMi4yIiwgInZhbHVlMSIsIGRlc2NyaXB0aW9uLmdldFByb3BlcnR5KHByb3BlcnR5MSkpOwoJCWFzc2VydEVxdWFscygiMi4zIiwgInZhbHVlMiIsIGRlc2NyaXB0aW9uLmdldFByb3BlcnR5KHByb3BlcnR5MikpOwoJCWFzc2VydE51bGwoIjIuNCIsIGRlc2NyaXB0aW9uLmdldFByb3BlcnR5KHByb3BlcnR5MykpOwoJCWFzc2VydEVxdWFscygiMi41IiwgInZhbHVlNCIsIGRlc2NyaXB0aW9uLmdldFByb3BlcnR5KHByb3BlcnR5NCkpOwoJCWFzc2VydEVxdWFscygiMi42IiwgIkJBUiIsIGRlc2NyaXB0aW9uLmdldFByb3BlcnR5KGNoYXJzZXQpKTsKCgkJZGVzY3JpcHRpb24gPSBnZXREZXNjcmlwdGlvbkZvcihmaW5kZXIsICJzb21lIGNvbnRlbnRzIiwgbnVsbCwgImFiYy50enQyIiwgSUNvbnRlbnREZXNjcmlwdGlvbi5BTEwsIHRydWUpOwoJCWFzc2VydE5vdE51bGwoIjMuMCIsIGRlc2NyaXB0aW9uKTsKCQlhc3NlcnRFcXVhbHMoIjMuMSIsIG15dGV4dDIsIGRlc2NyaXB0aW9uLmdldENvbnRlbnRUeXBlKCkpOwoJCWFzc2VydE51bGwoIjMuMiIsIGRlc2NyaXB0aW9uLmdldFByb3BlcnR5KHByb3BlcnR5MSkpOwoJCWFzc2VydE51bGwoIjMuMyIsIGRlc2NyaXB0aW9uLmdldFByb3BlcnR5KHByb3BlcnR5MikpOwoJCWFzc2VydE51bGwoIjMuNCIsIGRlc2NyaXB0aW9uLmdldFByb3BlcnR5KHByb3BlcnR5MykpOwoJCWFzc2VydE51bGwoIjMuNSIsIGRlc2NyaXB0aW9uLmdldFByb3BlcnR5KHByb3BlcnR5NCkpOwoJCWFzc2VydE51bGwoIjMuNiIsIGRlc2NyaXB0aW9uLmdldFByb3BlcnR5KGNoYXJzZXQpKTsKCQlhc3NlcnRFcXVhbHMoIjMuNyIsICJteXRleHQyIiwgZGVzY3JpcHRpb24uZ2V0UHJvcGVydHkobG9jYWxDaGFyc2V0KSk7Cgl9CgoJLyoqCgkgKiBUaGUgZm9vQmFyIGNvbnRlbnQgdHlwZSBpcyBhc3NvY2lhdGVkIHdpdGggdGhlICJmb28uYmFyIiBmaWxlIG5hbWUgYW5kCgkgKiB0aGUgImJhciIgZmlsZSBleHRlbnNpb24gKHdoYXQgaXMgYm9ndXMsIGFueXdheSkuIFRoaXMgdGVzdCBlbnN1cmVzIGl0CgkgKiBkb2VzIG5vdCBhcHBlYXIgdHdpY2UgaW4gdGhlIGxpc3Qgb2YgY29udGVudCB0eXBlcyBhc3NvY2lhdGVkIHdpdGggdGhlCgkgKiAiZm9vLmJhciIgZmlsZSBuYW1lLgoJICovCglwdWJsaWMgdm9pZCB0ZXN0RG91YmxlQXNzb2NpYXRpb24oKSB7CgkJSUNvbnRlbnRUeXBlTWFuYWdlciBjb250ZW50VHlwZU1hbmFnZXIgPSBQbGF0Zm9ybS5nZXRDb250ZW50VHlwZU1hbmFnZXIoKTsKCgkJSUNvbnRlbnRUeXBlIGZvb0JhclR5cGUgPSBjb250ZW50VHlwZU1hbmFnZXIuZ2V0Q29udGVudFR5cGUoUElfUkVTT1VSQ0VTX1RFU1RTICsgJy4nICsgImZvb0JhciIpOwoJCWFzc2VydE5vdE51bGwoIjEuMCIsIGZvb0JhclR5cGUpOwoJCUlDb250ZW50VHlwZSBzdWJGb29CYXJUeXBlID0gY29udGVudFR5cGVNYW5hZ2VyLmdldENvbnRlbnRUeXBlKFBJX1JFU09VUkNFU19URVNUUyArICcuJyArICJzdWJGb29CYXIiKTsKCQlhc3NlcnROb3ROdWxsKCIxLjEiLCBzdWJGb29CYXJUeXBlKTsKCQkvLyBlbnN1cmUgd2UgZG9uJ3QgZ2V0IGZvb0JhciB0d2ljZQoJCUlDb250ZW50VHlwZU1hdGNoZXIgZmluZGVyID0gY29udGVudFR5cGVNYW5hZ2VyLmdldE1hdGNoZXIobmV3IExvY2FsU2VsZWN0aW9uUG9saWN5KCksIG51bGwpOwoJCUlDb250ZW50VHlwZVtdIGZvb0JhckFzc29jaWF0ZWQgPSBmaW5kZXIuZmluZENvbnRlbnRUeXBlc0ZvcihjaGFuZ2VDYXNlKCJmb28uYmFyIikpOwoJCWFzc2VydEVxdWFscygiMi4xIiwgMiwgZm9vQmFyQXNzb2NpYXRlZC5sZW5ndGgpOwoJCWFzc2VydFRydWUoIjIuMiIsIGNvbnRhaW5zKGZvb0JhckFzc29jaWF0ZWQsIGZvb0JhclR5cGUpKTsKCQlhc3NlcnRUcnVlKCIyLjMiLCBjb250YWlucyhmb29CYXJBc3NvY2lhdGVkLCBzdWJGb29CYXJUeXBlKSk7Cgl9CgoJLyoqCgkgKiBPYnRhaW5zIGEgcmVmZXJlbmNlIHRvIGEga25vd24gY29udGVudCB0eXBlLCB0aGVuIGluc3RhbGxzIGEgYnVuZGxlIHRoYXQgY29udHJpYnV0ZXMgYSBjb250ZW50IHR5cGUsCgkgKiBhbmQgbWFrZXMgc3VyZSBhIG5ldyBvYnRhaW5lZCByZWZlcmVuY2UgdG8gdGhlIHNhbWUgY29udGVudCB0eXBlIGlzIG5vdCBpZGVudGljYWwgKHNob3dzCgkgKiB0aGF0IHRoZSBjb250ZW50IHR5cGUgY2F0YWxvZyBoYXMgYmVlbiBkaXNjYXJkZWQgYW5kIHJlYnVpbHQpLiBUaGVuIHVuaW5zdGFsbHMgdGhhdCBidW5kbGUKCSAqIGFuZCBjaGVja3MgYWdhaW4gdGhlIHNhbWUgdGhpbmcgKGJlY2F1c2UgdGhlIGNvbnRlbnQgdHlwZSBjYXRhbG9nIHNob3VsZCBiZSByZWJ1aWx0IHdoZW5ldmVyCgkgKiBjb250ZW50IHR5cGVzIGFyZSBkeW5hbWljYWx5IGFkZGVkL3JlbW92ZWQpLgoJICovCglwdWJsaWMgdm9pZCB0ZXN0RHluYW1pY0NoYW5nZXMoKSB7CgkJZmluYWwgSUNvbnRlbnRUeXBlW10gdGV4dCA9IG5ldyBJQ29udGVudFR5cGVbNF07CgkJZmluYWwgSUNvbnRlbnRUeXBlTWFuYWdlciBtYW5hZ2VyID0gUGxhdGZvcm0uZ2V0Q29udGVudFR5cGVNYW5hZ2VyKCk7CgkJdGV4dFswXSA9IG1hbmFnZXIuZ2V0Q29udGVudFR5cGUoSUNvbnRlbnRUeXBlTWFuYWdlci5DVF9URVhUKTsKCQlhc3NlcnROb3ROdWxsKCIxLjAiLCB0ZXh0WzBdKTsKCQl0ZXh0WzFdID0gbWFuYWdlci5nZXRDb250ZW50VHlwZShJQ29udGVudFR5cGVNYW5hZ2VyLkNUX1RFWFQpOwoJCWFzc2VydE5vdE51bGwoIjEuMSIsIHRleHRbMV0pOwoJCXRleHRbMF0gPSAoKENvbnRlbnRUeXBlSGFuZGxlcikgdGV4dFswXSkuZ2V0VGFyZ2V0KCk7CgkJdGV4dFsxXSA9ICgoQ29udGVudFR5cGVIYW5kbGVyKSB0ZXh0WzFdKS5nZXRUYXJnZXQoKTsKCQlhc3NlcnRFcXVhbHMoIjIuMCIsIHRleHRbMF0sIHRleHRbMV0pOwoJCWFzc2VydFRydWUoIjIuMSIsIHRleHRbMF0gPT0gdGV4dFsxXSk7CgkJLy8JbWFrZSBhcmJpdHJhcnkgZHluYW1pYyBjaGFuZ2VzIHRvIHRoZSBjb250ZW50VHlwZXMgZXh0ZW5zaW9uIHBvaW50CgkJVGVzdFJlZ2lzdHJ5Q2hhbmdlTGlzdGVuZXIgbGlzdGVuZXIgPSBuZXcgVGVzdFJlZ2lzdHJ5Q2hhbmdlTGlzdGVuZXIoUGxhdGZvcm0uUElfUlVOVElNRSwgQ29udGVudFR5cGVCdWlsZGVyLlBUX0NPTlRFTlRUWVBFUywgbnVsbCwgbnVsbCk7CgkJQnVuZGxlVGVzdGluZ0hlbHBlci5ydW5XaXRoQnVuZGxlcygiMyIsICgpIC0+IHsKCQkJSUNvbnRlbnRUeXBlIG1pc3NpbmcgPSBtYW5hZ2VyLmdldENvbnRlbnRUeXBlKCJvcmcuZWNsaXBzZS5idW5kbGUwMS5taXNzaW5nIik7CgkJCWFzc2VydE5vdE51bGwoIjMuMSIsIG1pc3NpbmcpOwoJCQkvLyBlbnN1cmUgdGhlIGNvbnRlbnQgdHlwZSBpbnN0YW5jZXMgYXJlIGRpZmZlcmVudAoJCQl0ZXh0WzJdID0gbWFuYWdlci5nZXRDb250ZW50VHlwZShJQ29udGVudFR5cGVNYW5hZ2VyLkNUX1RFWFQpOwoJCQlhc3NlcnROb3ROdWxsKCIzLjIiLCB0ZXh0WzJdKTsKCQkJdGV4dFsyXSA9ICgoQ29udGVudFR5cGVIYW5kbGVyKSB0ZXh0WzJdKS5nZXRUYXJnZXQoKTsKCQkJYXNzZXJ0RXF1YWxzKCIzLjMiLCB0ZXh0WzBdLCB0ZXh0WzJdKTsKCQkJYXNzZXJ0VHJ1ZSgiMy40IiwgdGV4dFswXSAhPSB0ZXh0WzJdKTsKCQl9LCBnZXRDb250ZXh0KCksIG5ldyBTdHJpbmdbXSB7Q29udGVudFR5cGVUZXN0LlRFU1RfRklMRVNfUk9PVCArICJjb250ZW50L2J1bmRsZTAxIn0sIGxpc3RlbmVyKTsKCQlhc3NlcnROdWxsKCI0LjAiLCBtYW5hZ2VyLmdldENvbnRlbnRUeXBlKCJvcmcuZWNsaXBzZS5idW5kbGUwMS5taXNzaW5nIikpOwoJCS8vIGVuc3VyZSB0aGUgY29udGVudCB0eXBlIGluc3RhbmNlcyBhcmUgYWxsIGRpZmZlcmVudAoJCXRleHRbM10gPSBtYW5hZ2VyLmdldENvbnRlbnRUeXBlKElDb250ZW50VHlwZU1hbmFnZXIuQ1RfVEVYVCk7CgkJYXNzZXJ0Tm90TnVsbCgiNS4wIiwgdGV4dFszXSk7CgkJdGV4dFszXSA9ICgoQ29udGVudFR5cGVIYW5kbGVyKSB0ZXh0WzNdKS5nZXRUYXJnZXQoKTsKCQlhc3NlcnRFcXVhbHMoIjUuMSIsIHRleHRbMF0sIHRleHRbM10pOwoJCWFzc2VydEVxdWFscygiNS4yIiwgdGV4dFsyXSwgdGV4dFszXSk7CgkJYXNzZXJ0VHJ1ZSgiNS4zIiwgdGV4dFswXSAhPSB0ZXh0WzNdKTsKCQlhc3NlcnRUcnVlKCI1LjQiLCB0ZXh0WzJdICE9IHRleHRbM10pOwoJfQoKCS8qKgoJICogU2ltaWxhciB0byB0ZXN0RHluYW1pY0NoYW5nZXMsIGJ1dCB1c2luZyB0aGUgb3JnLmVjbGlwc2UuY29yZS5jb250ZW50dHlwZS5jb250ZW50VHlwZXMgZXh0ZW5zaW9uIHBvaW50LgoJICovCglwdWJsaWMgdm9pZCB0ZXN0RHluYW1pY0NoYW5nZXNOZXdFeHRlbnNpb24oKSB7CgkJZmluYWwgSUNvbnRlbnRUeXBlW10gdGV4dCA9IG5ldyBJQ29udGVudFR5cGVbNF07CgkJZmluYWwgSUNvbnRlbnRUeXBlTWFuYWdlciBtYW5hZ2VyID0gUGxhdGZvcm0uZ2V0Q29udGVudFR5cGVNYW5hZ2VyKCk7CgkJdGV4dFswXSA9IG1hbmFnZXIuZ2V0Q29udGVudFR5cGUoSUNvbnRlbnRUeXBlTWFuYWdlci5DVF9URVhUKTsKCQlhc3NlcnROb3ROdWxsKCIxLjAiLCB0ZXh0WzBdKTsKCQl0ZXh0WzFdID0gbWFuYWdlci5nZXRDb250ZW50VHlwZShJQ29udGVudFR5cGVNYW5hZ2VyLkNUX1RFWFQpOwoJCWFzc2VydE5vdE51bGwoIjEuMSIsIHRleHRbMV0pOwoJCXRleHRbMF0gPSAoKENvbnRlbnRUeXBlSGFuZGxlcikgdGV4dFswXSkuZ2V0VGFyZ2V0KCk7CgkJdGV4dFsxXSA9ICgoQ29udGVudFR5cGVIYW5kbGVyKSB0ZXh0WzFdKS5nZXRUYXJnZXQoKTsKCQlhc3NlcnRFcXVhbHMoIjIuMCIsIHRleHRbMF0sIHRleHRbMV0pOwoJCWFzc2VydFRydWUoIjIuMSIsIHRleHRbMF0gPT0gdGV4dFsxXSk7CgkJLy8JbWFrZSBhcmJpdHJhcnkgZHluYW1pYyBjaGFuZ2VzIHRvIHRoZSBjb250ZW50VHlwZXMgZXh0ZW5zaW9uIHBvaW50CgkJVGVzdFJlZ2lzdHJ5Q2hhbmdlTGlzdGVuZXIgbGlzdGVuZXIgPSBuZXcgVGVzdFJlZ2lzdHJ5Q2hhbmdlTGlzdGVuZXIoSUNvbnRlbnRDb25zdGFudHMuQ09OVEVOVF9OQU1FLCBDb250ZW50VHlwZUJ1aWxkZXIuUFRfQ09OVEVOVFRZUEVTLCBudWxsLCBudWxsKTsKCQlCdW5kbGVUZXN0aW5nSGVscGVyLnJ1bldpdGhCdW5kbGVzKCIzIiwgKCkgLT4gewoJCQlJQ29udGVudFR5cGUgY29udGVudFR5cGUgPSBtYW5hZ2VyLmdldENvbnRlbnRUeXBlKCJvcmcuZWNsaXBzZS5idWc0ODUyMjcuYnVnNDg1MjI3X2NvbnRlbnRUeXBlIik7CgkJCWFzc2VydE5vdE51bGwoIjMuMSBDb250cmlidXRlZCBjb250ZW50IHR5cGUgbm90IGZvdW5kIiwgY29udGVudFR5cGUpOwoJCQkvLyBlbnN1cmUgdGhlIGNvbnRlbnQgdHlwZSBpbnN0YW5jZXMgYXJlIGRpZmZlcmVudAoJCQl0ZXh0WzJdID0gbWFuYWdlci5nZXRDb250ZW50VHlwZShJQ29udGVudFR5cGVNYW5hZ2VyLkNUX1RFWFQpOwoJCQlhc3NlcnROb3ROdWxsKCIzLjIgVGV4dCBjb250ZW50IHR5cGUgbm90IG1vZGlmaWVkIiwgdGV4dFsyXSk7CgkJCXRleHRbMl0gPSAoKENvbnRlbnRUeXBlSGFuZGxlcikgdGV4dFsyXSkuZ2V0VGFyZ2V0KCk7CgkJCWFzc2VydEVxdWFscygiMy4zIiwgdGV4dFswXSwgdGV4dFsyXSk7CgkJCWFzc2VydFRydWUoIjMuNCIsIHRleHRbMF0gIT0gdGV4dFsyXSk7CgkJCWFzc2VydEVxdWFscygiMy41IGRlZmF1bHQgZXh0ZW5zaW9uIG5vdCBhc3NvY2lhdGVkIiwgY29udGVudFR5cGUsIG1hbmFnZXIuZmluZENvbnRlbnRUeXBlRm9yKCJmaWxlLmJ1ZzQ4NTIyNyIpKTsKCQkJYXNzZXJ0RXF1YWxzKCIzLjYgYWRkaXRpb25hbCBleHRlbnNpb24gbm90IGFzc29jaWF0ZWQiLCBjb250ZW50VHlwZSwgbWFuYWdlci5maW5kQ29udGVudFR5cGVGb3IoImZpbGUuYnVnNDg1MjI3XzIiKSk7CgkJfSwgZ2V0Q29udGV4dCgpLCBuZXcgU3RyaW5nW10ge0NvbnRlbnRUeXBlVGVzdC5URVNUX0ZJTEVTX1JPT1QgKyAiY29udGVudC9idWc0ODUyMjcifSwgbGlzdGVuZXIpOwoJCWFzc2VydE51bGwoIjQuMCBDb250ZW50IHR5cGUgbm90IGNsZWFyZWQgYWZ0ZXIgYnVuZGxlIHVuaW5zdGFsbCIsIG1hbmFnZXIuZ2V0Q29udGVudFR5cGUoIm9yZy5lY2xpcHNlLmJ1ZzQ4NTIyNy5idWc0ODUyMjdfY29udGVudFR5cGUiKSk7CgkJLy8gZW5zdXJlIHRoZSBjb250ZW50IHR5cGUgaW5zdGFuY2VzIGFyZSBhbGwgZGlmZmVyZW50CgkJdGV4dFszXSA9IG1hbmFnZXIuZ2V0Q29udGVudFR5cGUoSUNvbnRlbnRUeXBlTWFuYWdlci5DVF9URVhUKTsKCQlhc3NlcnROb3ROdWxsKCI1LjAiLCB0ZXh0WzNdKTsKCQl0ZXh0WzNdID0gKChDb250ZW50VHlwZUhhbmRsZXIpIHRleHRbM10pLmdldFRhcmdldCgpOwoJCWFzc2VydEVxdWFscygiNS4xIiwgdGV4dFswXSwgdGV4dFszXSk7CgkJYXNzZXJ0RXF1YWxzKCI1LjIiLCB0ZXh0WzJdLCB0ZXh0WzNdKTsKCQlhc3NlcnRUcnVlKCI1LjMiLCB0ZXh0WzBdICE9IHRleHRbM10pOwoJCWFzc2VydFRydWUoIjUuNCIsIHRleHRbMl0gIT0gdGV4dFszXSk7Cgl9CgoJcHVibGljIHZvaWQgdGVzdEV2ZW50cygpIHsKCQlJQ29udGVudFR5cGVNYW5hZ2VyIGNvbnRlbnRUeXBlTWFuYWdlciA9IFBsYXRmb3JtLmdldENvbnRlbnRUeXBlTWFuYWdlcigpOwoJCUlDb250ZW50VHlwZSBteVR5cGUgPSBjb250ZW50VHlwZU1hbmFnZXIuZ2V0Q29udGVudFR5cGUoUElfUkVTT1VSQ0VTX1RFU1RTICsgIi5teUNvbnRlbnQiKTsKCQlhc3NlcnROb3ROdWxsKCIwLjkiLCBteVR5cGUpOwoKCQlDb250ZW50VHlwZUNoYW5nZVRyYWNlciB0cmFjZXI7CgoJCXRyYWNlciA9IG5ldyBDb250ZW50VHlwZUNoYW5nZVRyYWNlcigpOwoJCWNvbnRlbnRUeXBlTWFuYWdlci5hZGRDb250ZW50VHlwZUNoYW5nZUxpc3RlbmVyKHRyYWNlcik7CgoJCS8vIGFkZCBhIGZpbGUgc3BlYyBhbmQgY2hlY2sgZXZlbnQKCQl0cnkgewoJCQlteVR5cGUuYWRkRmlsZVNwZWMoImFub3RoZXIuZmlsZS5uYW1lIiwgSUNvbnRlbnRUeXBlLkZJTEVfTkFNRV9TUEVDKTsKCQl9IGNhdGNoIChDb3JlRXhjZXB0aW9uIGUpIHsKCQkJZmFpbCgiMS4wIiwgZSk7CgkJfQoJCWFzc2VydFRydWUoIjEuMSIsIHRyYWNlci5pc09ubHlDaGFuZ2UobXlUeXBlKSk7CgoJCS8vIHJlbW92ZSBhIG5vbi1leGlzdGluZyBmaWxlIHNwZWMgLSBzaG91bGQgbm90IGNhdXNlIGFuIGV2ZW50IHRvIGJlIGZpcmVkCgkJdHJhY2VyLnJlc2V0KCk7CgkJdHJ5IHsKCQkJbXlUeXBlLnJlbW92ZUZpbGVTcGVjKCJhbm90aGVyLmZpbGUubmFtZSIsIElDb250ZW50VHlwZS5GSUxFX0VYVEVOU0lPTl9TUEVDKTsKCQl9IGNhdGNoIChDb3JlRXhjZXB0aW9uIGUpIHsKCQkJZmFpbCgiMi4wIiwgZSk7CgkJfQoJCWFzc2VydFRydWUoIjIuMSIsICF0cmFjZXIuaXNPbmx5Q2hhbmdlKG15VHlwZSkpOwoKCQkvLyBhZGQgYSBmaWxlIHNwZWMgYWdhaW4gYW5kIGNoZWNrIG5vIGV2ZW50IGlzIGdlbmVyYXRlZAoJCXRyYWNlci5yZXNldCgpOwoJCXRyeSB7CgkJCW15VHlwZS5hZGRGaWxlU3BlYygiYW5vdGhlci5maWxlLm5hbWUiLCBJQ29udGVudFR5cGUuRklMRV9OQU1FX1NQRUMpOwoJCX0gY2F0Y2ggKENvcmVFeGNlcHRpb24gZSkgewoJCQlmYWlsKCIzLjAiLCBlKTsKCQl9CgkJYXNzZXJ0VHJ1ZSgiMy4xIiwgIXRyYWNlci5pc09ubHlDaGFuZ2UobXlUeXBlKSk7CgoJCS8vIHJlbW92ZSBhIGZpbGUgc3BlYyBhbmQgY2hlY2sgZXZlbnQKCQl0cmFjZXIucmVzZXQoKTsKCQl0cnkgewoJCQlteVR5cGUucmVtb3ZlRmlsZVNwZWMoImFub3RoZXIuZmlsZS5uYW1lIiwgSUNvbnRlbnRUeXBlLkZJTEVfTkFNRV9TUEVDKTsKCQl9IGNhdGNoIChDb3JlRXhjZXB0aW9uIGUpIHsKCQkJZmFpbCgiNC4wIiwgZSk7CgkJfQoJCWFzc2VydFRydWUoIjQuMSIsIHRyYWNlci5pc09ubHlDaGFuZ2UobXlUeXBlKSk7CgoJCS8vIGNoYW5nZSB0aGUgZGVmYXVsdCBjaGFyc2V0IGFuZCBjaGVjayBldmVudAoJCXRyYWNlci5yZXNldCgpOwoJCXRyeSB7CgkJCW15VHlwZS5zZXREZWZhdWx0Q2hhcnNldCgiRk9PIik7CgkJfSBjYXRjaCAoQ29yZUV4Y2VwdGlvbiBlKSB7CgkJCWZhaWwoIjUuMCIsIGUpOwoJCX0KCQlhc3NlcnRUcnVlKCI1LjEiLCB0cmFjZXIuaXNPbmx5Q2hhbmdlKG15VHlwZSkpOwoKCQkvLyBzZXQgdGhlIGRlZmF1bHQgY2hhcnNldCB0byB0aGUgc2FtZSAtIG5vIGV2ZW50IHNob3VsZCBiZSBnZW5lcmF0ZWQKCQl0cmFjZXIucmVzZXQoKTsKCQl0cnkgewoJCQlteVR5cGUuc2V0RGVmYXVsdENoYXJzZXQoIkZPTyIpOwoJCX0gY2F0Y2ggKENvcmVFeGNlcHRpb24gZSkgewoJCQlmYWlsKCI2LjAiLCBlKTsKCQl9CgkJYXNzZXJ0VHJ1ZSgiNi4xIiwgIXRyYWNlci5pc09ubHlDaGFuZ2UobXlUeXBlKSk7CgoJCXRyeSB7CgkJCW15VHlwZS5zZXREZWZhdWx0Q2hhcnNldCgiQUJDIik7CgkJfSBjYXRjaCAoQ29yZUV4Y2VwdGlvbiBlMSkgewoJCQlmYWlsKCI3LjAiLCBlMSk7CgkJfQoJfQoKCXB1YmxpYyB2b2lkIHRlc3RGaWxlU3BlY0NvbmZsaWN0cygpIHsKCQlJQ29udGVudFR5cGVNYW5hZ2VyIG1hbmFnZXIgPSBQbGF0Zm9ybS5nZXRDb250ZW50VHlwZU1hbmFnZXIoKTsKCQkvLyB3aGVuIG5vdCBzdWJtaXR0aW5nIGNvbnRlbnRzLCBmb3IgcmVsYXRlZCB0eXBlcywgbW9zdCBnZW5lcmFsIHR5cGUgcHJldmFpbHMKCQlJQ29udGVudFR5cGUgY29uZmxpY3QxYSA9IG1hbmFnZXIuZ2V0Q29udGVudFR5cGUoUElfUkVTT1VSQ0VTX1RFU1RTICsgIi5iYXNlX2NvbmZsaWN0MSIpOwoJCUlDb250ZW50VHlwZSBjb25mbGljdDFiID0gbWFuYWdlci5nZXRDb250ZW50VHlwZShQSV9SRVNPVVJDRVNfVEVTVFMgKyAiLnN1Yl9jb25mbGljdDEiKTsKCQlhc3NlcnROb3ROdWxsKCIxLjAiLCBjb25mbGljdDFhKTsKCQlhc3NlcnROb3ROdWxsKCIxLjEiLCBjb25mbGljdDFiKTsKCQlJQ29udGVudFR5cGUgcHJlZmVycmVkQ29uZmxpY3QxID0gbWFuYWdlci5maW5kQ29udGVudFR5cGVGb3IoInRlc3QuY29uZmxpY3QxIik7CgkJYXNzZXJ0Tm90TnVsbCgiMS4yIiwgcHJlZmVycmVkQ29uZmxpY3QxKTsKCQlhc3NlcnRFcXVhbHMoIjEuMyIsIGNvbmZsaWN0MWEsIHByZWZlcnJlZENvbmZsaWN0MSk7CgoJCUlDb250ZW50VHlwZSBjb25mbGljdDJiYXNlID0gbWFuYWdlci5nZXRDb250ZW50VHlwZShQSV9SRVNPVVJDRVNfVEVTVFMgKyAiLmJhc2VfY29uZmxpY3QyIik7CgkJSUNvbnRlbnRUeXBlIGNvbmZsaWN0MnN1YiA9IG1hbmFnZXIuZ2V0Q29udGVudFR5cGUoUElfUkVTT1VSQ0VTX1RFU1RTICsgIi5zdWJfY29uZmxpY3QyIik7CgkJYXNzZXJ0Tm90TnVsbCgiMi4wIiwgY29uZmxpY3QyYmFzZSk7CgkJYXNzZXJ0Tm90TnVsbCgiMi4xIiwgY29uZmxpY3Qyc3ViKTsKCQkvLyB3aGVuIHN1Ym1pdHRpbmcgY29udGVudHMsIGZvciByZWxhdGVkIHR5cGVzLCBkZXNjZW5kYW50IGNvbWVzIGZpcnN0CgkJSUNvbnRlbnRUeXBlW10gc2VsZWN0ZWRDb25mbGljdDI7CgkJdHJ5IHsKCQkJc2VsZWN0ZWRDb25mbGljdDIgPSBtYW5hZ2VyLmZpbmRDb250ZW50VHlwZXNGb3IoZ2V0UmFuZG9tQ29udGVudHMoKSwgInRlc3QuY29uZmxpY3QyIik7CgkJCWFzc2VydEVxdWFscygiMi4yIiwgMiwgc2VsZWN0ZWRDb25mbGljdDIubGVuZ3RoKTsKCQkJYXNzZXJ0RXF1YWxzKCIyLjMiLCBzZWxlY3RlZENvbmZsaWN0MlswXSwgY29uZmxpY3QyYmFzZSk7CgkJCWFzc2VydEVxdWFscygiMi40Iiwgc2VsZWN0ZWRDb25mbGljdDJbMV0sIGNvbmZsaWN0MnN1Yik7CgkJfSBjYXRjaCAoSU9FeGNlcHRpb24gZSkgewoJCQlmYWlsKCIyLjUiLCBlKTsKCQl9CgoJCUlDb250ZW50VHlwZSBjb25mbGljdDNiYXNlID0gbWFuYWdlci5nZXRDb250ZW50VHlwZShQSV9SRVNPVVJDRVNfVEVTVFMgKyAiLmJhc2VfY29uZmxpY3QzIik7CgkJSUNvbnRlbnRUeXBlIGNvbmZsaWN0M3N1YiA9IG1hbmFnZXIuZ2V0Q29udGVudFR5cGUoUElfUkVTT1VSQ0VTX1RFU1RTICsgIi5zdWJfY29uZmxpY3QzIik7CgkJSUNvbnRlbnRUeXBlIGNvbmZsaWN0M3VucmVsYXRlZCA9IG1hbmFnZXIuZ2V0Q29udGVudFR5cGUoUElfUkVTT1VSQ0VTX1RFU1RTICsgIi51bnJlbGF0ZWRfY29uZmxpY3QzIik7CgkJYXNzZXJ0Tm90TnVsbCgiMy4wLjEiLCBjb25mbGljdDNiYXNlKTsKCQlhc3NlcnROb3ROdWxsKCIzLjAuMiIsIGNvbmZsaWN0M3N1Yik7CgkJYXNzZXJ0Tm90TnVsbCgiMy4wLjMiLCBjb25mbGljdDN1bnJlbGF0ZWQpOwoKCQkvLyBUd28gdW5yZWxhdGVkIHR5cGVzIChzdWJfY29uZmxpY3QzIGFuZCB1bnJlbGF0ZWQgY29uZmxpY3QzKSBhcmUgaW4gY29uZmxpY3QuCgkJLy8gT3JkZXIgd2lsbCBiZSBiYXNlZCBvbiBkZXB0aCAobW9yZSBnZW5lcmFsIGZpcnN0IHNpbmNlIHRoZXkgZG9uJ3QgaGF2ZSBkZXNjcmliZXJzKQoKCQlJQ29udGVudFR5cGVbXSBzZWxlY3RlZENvbmZsaWN0MzsKCQl0cnkgewoJCQlzZWxlY3RlZENvbmZsaWN0MyA9IG1hbmFnZXIuZmluZENvbnRlbnRUeXBlc0ZvcihnZXRSYW5kb21Db250ZW50cygpLCAidGVzdC5jb25mbGljdDMiKTsKCQkJYXNzZXJ0RXF1YWxzKCI0LjAiLCAyLCBzZWxlY3RlZENvbmZsaWN0My5sZW5ndGgpOwoJCQlhc3NlcnRFcXVhbHMoIjQuMSIsIHNlbGVjdGVkQ29uZmxpY3QzWzBdLCBjb25mbGljdDN1bnJlbGF0ZWQpOwoJCQlhc3NlcnRFcXVhbHMoIjQuMiIsIHNlbGVjdGVkQ29uZmxpY3QzWzFdLCBjb25mbGljdDNzdWIpOwoJCX0gY2F0Y2ggKElPRXhjZXB0aW9uIGUpIHsKCQkJZmFpbCgiNC4zIiwgZSk7CgkJfQoJfQoKCXB1YmxpYyB2b2lkIHRlc3RGaW5kQ29udGVudFR5cGUoKSB0aHJvd3MgSU9FeGNlcHRpb24gewoJCUlDb250ZW50VHlwZU1hbmFnZXIgY29udGVudFR5cGVNYW5hZ2VyID0gUGxhdGZvcm0uZ2V0Q29udGVudFR5cGVNYW5hZ2VyKCk7CgkJSUNvbnRlbnRUeXBlTWF0Y2hlciBmaW5kZXIgPSBjb250ZW50VHlwZU1hbmFnZXIuZ2V0TWF0Y2hlcihuZXcgTG9jYWxTZWxlY3Rpb25Qb2xpY3koKSwgbnVsbCk7CgoJCUlDb250ZW50VHlwZSB0ZXh0Q29udGVudFR5cGUgPSBjb250ZW50VHlwZU1hbmFnZXIuZ2V0Q29udGVudFR5cGUoUGxhdGZvcm0uUElfUlVOVElNRSArICcuJyArICJ0ZXh0Iik7CgkJSUNvbnRlbnRUeXBlIHhtbENvbnRlbnRUeXBlID0gY29udGVudFR5cGVNYW5hZ2VyLmdldENvbnRlbnRUeXBlKFBsYXRmb3JtLlBJX1JVTlRJTUUgKyAiLnhtbCIpOwoKCQlJQ29udGVudFR5cGUgc2luZ2xlOwoKCQlzaW5nbGUgPSBmaW5kZXIuZmluZENvbnRlbnRUeXBlRm9yKGdldElucHV0U3RyZWFtKCJKdXN0IGEgdGVzdCIpLCBjaGFuZ2VDYXNlKCJmaWxlLnR4dCIpKTsKCQlhc3NlcnROb3ROdWxsKCIxLjAiLCBzaW5nbGUpOwoJCWFzc2VydEVxdWFscygiMS4xIiwgdGV4dENvbnRlbnRUeXBlLCBzaW5nbGUpOwoKCQlzaW5nbGUgPSBmaW5kZXIuZmluZENvbnRlbnRUeXBlRm9yKGdldElucHV0U3RyZWFtKFhNTF9VVEZfOCwgU3RhbmRhcmRDaGFyc2V0cy5VVEZfOCksIGNoYW5nZUNhc2UoImZvby54bWwiKSk7CgkJYXNzZXJ0Tm90TnVsbCgiMi4wIiwgc2luZ2xlKTsKCQlhc3NlcnRFcXVhbHMoIjIuMSIsIHhtbENvbnRlbnRUeXBlLCBzaW5nbGUpOwoKCQlJQ29udGVudFR5cGVbXSBtdWx0aXBsZSA9IGZpbmRlci5maW5kQ29udGVudFR5cGVzRm9yKGdldElucHV0U3RyZWFtKFhNTF9VVEZfOCwgU3RhbmRhcmRDaGFyc2V0cy5VVEZfOCksIG51bGwpOwoJCWFzc2VydFRydWUoIjMuMCIsIGNvbnRhaW5zKG11bHRpcGxlLCB4bWxDb250ZW50VHlwZSkpOwoJfQoKCXB1YmxpYyB2b2lkIHRlc3RGaW5kQ29udGVudFR5cFByZWRlZmluZWRSZWdleHAoKSB0aHJvd3MgSU9FeGNlcHRpb24sIENvcmVFeGNlcHRpb24gewoJCUlDb250ZW50VHlwZU1hbmFnZXIgY29udGVudFR5cGVNYW5hZ2VyID0gUGxhdGZvcm0uZ2V0Q29udGVudFR5cGVNYW5hZ2VyKCk7CgkJSUNvbnRlbnRUeXBlTWF0Y2hlciBmaW5kZXIgPSBjb250ZW50VHlwZU1hbmFnZXIuZ2V0TWF0Y2hlcihuZXcgTG9jYWxTZWxlY3Rpb25Qb2xpY3koKSwgbnVsbCk7CgoJCUlDb250ZW50VHlwZSB0YXJnZXRDb250ZW50VHlwZSA9IGNvbnRlbnRUeXBlTWFuYWdlci5nZXRDb250ZW50VHlwZSgib3JnLmVjbGlwc2UuY29yZS50ZXN0cy5yZXNvdXJjZXMucHJlZGVmaW5lZENvbnRlbnRUeXBlV2l0aFJlZ2V4cCIpOwoJCWFzc2VydE5vdE51bGwoIlRhcmdldCBjb250ZW50LXR5cGUgbm90IGZvdW5kIiwgdGFyZ2V0Q29udGVudFR5cGUpOwoKCQlJQ29udGVudFR5cGUgc2luZ2xlID0gZmluZGVyLmZpbmRDb250ZW50VHlwZUZvcihnZXRJbnB1dFN0cmVhbSgiSnVzdCBhIHRlc3QiKSwgInNvbWVwcmVkZWZpbmVkQ29udGVudFR5cGVXaXRoUmVnZXhwRmlsZSIpOwoJCWFzc2VydEVxdWFscyh0YXJnZXRDb250ZW50VHlwZSwgc2luZ2xlKTsKCQlzaW5nbGUgPSBmaW5kZXIuZmluZENvbnRlbnRUeXBlRm9yKGdldElucHV0U3RyZWFtKCJKdXN0IGEgdGVzdCIpLCAic29tZXByZWRlZmluZWRDb250ZW50VHlwZVdpdGhQYXR0ZXJuRmlsZSIpOwoJCWFzc2VydEVxdWFscyh0YXJnZXRDb250ZW50VHlwZSwgc2luZ2xlKTsKCQlzaW5nbGUgPSBmaW5kZXIuZmluZENvbnRlbnRUeXBlRm9yKGdldElucHV0U3RyZWFtKCJKdXN0IGEgdGVzdCIpLCAic29tZXByZWRlZmluZWRDb250ZW50VHlwZVdpdGhXaWxkY2FyZHNGaWxlIik7CgkJYXNzZXJ0RXF1YWxzKHRhcmdldENvbnRlbnRUeXBlLCBzaW5nbGUpOwoJfQoKCXB1YmxpYyB2b2lkIHRlc3RGaW5kQ29udGVudFR5cGVVc2VyUmVnZXhwKCkgdGhyb3dzIElPRXhjZXB0aW9uLCBDb3JlRXhjZXB0aW9uIHsKCQlJQ29udGVudFR5cGVNYW5hZ2VyIGNvbnRlbnRUeXBlTWFuYWdlciA9IFBsYXRmb3JtLmdldENvbnRlbnRUeXBlTWFuYWdlcigpOwoJCUlDb250ZW50VHlwZU1hdGNoZXIgZmluZGVyID0gY29udGVudFR5cGVNYW5hZ2VyLmdldE1hdGNoZXIobmV3IExvY2FsU2VsZWN0aW9uUG9saWN5KCksIG51bGwpOwoKCQlJQ29udGVudFR5cGUgdGV4dENvbnRlbnRUeXBlID0gY29udGVudFR5cGVNYW5hZ2VyLmdldENvbnRlbnRUeXBlKFBsYXRmb3JtLlBJX1JVTlRJTUUgKyAnLicgKyAidGV4dCIpOwoKCQlJQ29udGVudFR5cGUgc2luZ2xlID0gZmluZGVyLmZpbmRDb250ZW50VHlwZUZvcihnZXRJbnB1dFN0cmVhbSgiSnVzdCBhIHRlc3QiKSwgInNvbWVUZXh0LnVua25vd24iKTsKCQlhc3NlcnROdWxsKCJGaWxlIHBhdHRlcm4gdW5rbm93biBhdCB0aGF0IHBvaW50Iiwgc2luZ2xlKTsKCgkJdGV4dENvbnRlbnRUeXBlLmFkZEZpbGVTcGVjKCIqVGV4dCoiLCBJQ29udGVudFR5cGUuRklMRV9QQVRURVJOX1NQRUMpOwoJCXNpbmdsZSA9IGZpbmRlci5maW5kQ29udGVudFR5cGVGb3IoZ2V0SW5wdXRTdHJlYW0oIkp1c3QgYSB0ZXN0IiksICJzb21lVGV4dC51bmtub3duIik7CgkJYXNzZXJ0RXF1YWxzKCJUZXh0IGNvbnRlbnQgc2hvdWxkIG5vdyBtYXRjaCAqVGV4dCogZmlsZXMiLCB0ZXh0Q29udGVudFR5cGUsIHNpbmdsZSk7Cgl9CgoJcHVibGljIHZvaWQgdGVzdEltcG9ydEZpbGVBc3NvY2lhdGlvbigpIHRocm93cyBDb3JlRXhjZXB0aW9uIHsKCQlJQ29udGVudFR5cGVNYW5hZ2VyIGNvbnRlbnRUeXBlTWFuYWdlciA9IFBsYXRmb3JtLmdldENvbnRlbnRUeXBlTWFuYWdlcigpOwoJCWFzc2VydE51bGwoY29udGVudFR5cGVNYW5hZ2VyLmZpbmRDb250ZW50VHlwZUZvcigiKi5idWcxMjIyMTciKSk7CgkJSVByZWZlcmVuY2VzU2VydmljZSBzZXJ2aWNlID0gUGxhdGZvcm0uZ2V0UHJlZmVyZW5jZXNTZXJ2aWNlKCk7CgkJU3RyaW5nIHByZWZzID0gImZpbGVfZXhwb3J0X3ZlcnNpb249My4wXG4vaW5zdGFuY2Uvb3JnLmVjbGlwc2UuY29yZS5ydW50aW1lL2NvbnRlbnQtdHlwZXMvb3JnLmVjbGlwc2UuY29yZS5ydW50aW1lLnhtbC9maWxlLWV4dGVuc2lvbnM9YnVnMTIyMjE3IjsKCQlJRXhwb3J0ZWRQcmVmZXJlbmNlcyBleHBvcnRlZCA9IHNlcnZpY2UucmVhZFByZWZlcmVuY2VzKG5ldyBCeXRlQXJyYXlJbnB1dFN0cmVhbShwcmVmcy5nZXRCeXRlcygpKSk7CgkJYXNzZXJ0VHJ1ZShzZXJ2aWNlLmFwcGx5UHJlZmVyZW5jZXMoZXhwb3J0ZWQpLmlzT0soKSk7CgkJYXNzZXJ0Tm90TnVsbChjb250ZW50VHlwZU1hbmFnZXIuZmluZENvbnRlbnRUeXBlRm9yKCIqLmJ1ZzEyMjIxNyIpKTsKCX0KCglwdWJsaWMgdm9pZCB0ZXN0SW52YWxpZE1hcmt1cCgpIHsKCQlmaW5hbCBJQ29udGVudFR5cGVNYW5hZ2VyIGNvbnRlbnRUeXBlTWFuYWdlciA9IFBsYXRmb3JtLmdldENvbnRlbnRUeXBlTWFuYWdlcigpOwoJCUlDb250ZW50VHlwZU1hdGNoZXIgZmluZGVyID0gY29udGVudFR5cGVNYW5hZ2VyLmdldE1hdGNoZXIobmV3IExvY2FsU2VsZWN0aW9uUG9saWN5KCksIG51bGwpOwoJCWFzc2VydEVxdWFscygiMS4wIiwgMCwgZmluZGVyLmZpbmRDb250ZW50VHlwZXNGb3IoImludmFsaWQubWlzc2luZy5pZGVudGlmaWVyIikubGVuZ3RoKTsKCQlhc3NlcnRFcXVhbHMoIjIuMCIsIDAsIGZpbmRlci5maW5kQ29udGVudFR5cGVzRm9yKCJpbnZhbGlkLm1pc3NpbmcubmFtZSIpLmxlbmd0aCk7CgkJYXNzZXJ0TnVsbCgiMy4wIiwgY29udGVudFR5cGVNYW5hZ2VyLmdldENvbnRlbnRUeXBlKFBJX1JFU09VUkNFU19URVNUUyArICcuJyArICJpbnZhbGlkLW1pc3NpbmctbmFtZSIpKTsKCQlUZXN0UmVnaXN0cnlDaGFuZ2VMaXN0ZW5lciBsaXN0ZW5lciA9IG5ldyBUZXN0UmVnaXN0cnlDaGFuZ2VMaXN0ZW5lcihQbGF0Zm9ybS5QSV9SVU5USU1FLCBDb250ZW50VHlwZUJ1aWxkZXIuUFRfQ09OVEVOVFRZUEVTLCBudWxsLCBudWxsKTsKCQlCdW5kbGVUZXN0aW5nSGVscGVyLnJ1bldpdGhCdW5kbGVzKCIxIiwgKCkgLT4gewoJCQkvLyBlbnN1cmUgdGhlIGludmFsaWQgY29udGVudCB0eXBlcyBhcmUgbm90IGF2YWlsYWJsZQoJCQlhc3NlcnRFcXVhbHMoIjEuMiIsIDAsIGNvbnRlbnRUeXBlTWFuYWdlci5maW5kQ29udGVudFR5cGVzRm9yKCJpbnZhbGlkLm1pc3NpbmcuaWRlbnRpZmllciIpLmxlbmd0aCk7CgkJCWFzc2VydEVxdWFscygiMS4zIiwgMCwgY29udGVudFR5cGVNYW5hZ2VyLmZpbmRDb250ZW50VHlwZXNGb3IoImludmFsaWQubWlzc2luZy5uYW1lIikubGVuZ3RoKTsKCQkJYXNzZXJ0TnVsbCgiMS40IiwgY29udGVudFR5cGVNYW5hZ2VyLmdldENvbnRlbnRUeXBlKCJvcmcuZWNsaXBzZS5idW5kbGUwMy5pbnZhbGlkLW1pc3NpbmctbmFtZSIpKTsKCQkJLy8gdGhpcyBjb250ZW50IHR5cGUgaGFzIGdvb2QgbWFya3VwLCBidXQgaW52YWxpZCBkZXNjcmliZXIgY2xhc3MKCQkJSUNvbnRlbnRUeXBlIGludmFsaWREZXNjcmliZXIgPSBjb250ZW50VHlwZU1hbmFnZXIuZ2V0Q29udGVudFR5cGUoIm9yZy5lY2xpcHNlLmJ1bmRsZTAzLmludmFsaWQtZGVzY3JpYmVyIik7CgkJCWFzc2VydE5vdE51bGwoIjEuNSIsIGludmFsaWREZXNjcmliZXIpOwoJCQkvLyBuYW1lIGJhc2VkIG1hdGNoaW5nIHNob3VsZCB3b3JrIGZpbmUKCQkJYXNzZXJ0RXF1YWxzKCIxLjYiLCBpbnZhbGlkRGVzY3JpYmVyLCBjb250ZW50VHlwZU1hbmFnZXIuZmluZENvbnRlbnRUeXBlRm9yKCJpbnZhbGlkLmRlc2NyaWJlciIpKTsKCQkJdHJ5IHsKCQkJCS8vIHRoZSBkZXNjcmliZXIgY2xhc3MgaXMgaW52YWxpZCwgY29udGVudCBtYXRjaG9uZyBzaG91bGQgZmFpbAoJCQkJYXNzZXJ0TnVsbCgiMS43IiwgY29udGVudFR5cGVNYW5hZ2VyLmZpbmRDb250ZW50VHlwZUZvcihnZXRSYW5kb21Db250ZW50cygpLCAiaW52YWxpZC5kZXNjcmliZXIiKSk7CgkJCX0gY2F0Y2ggKElPRXhjZXB0aW9uIGUpIHsKCQkJCWZhaWwoIjEuOCIsIGUpOwoJCQl9CgkJfSwgZ2V0Q29udGV4dCgpLCBuZXcgU3RyaW5nW10ge0NvbnRlbnRUeXBlVGVzdC5URVNUX0ZJTEVTX1JPT1QgKyAiY29udGVudC9idW5kbGUwMyJ9LCBsaXN0ZW5lcik7Cgl9CgoJLyoqCgkgKiBCdWdzIDY3ODQxIGFuZCA2MjQ0MwoJICovCglwdWJsaWMgdm9pZCB0ZXN0SU9FeGNlcHRpb24oKSB7CgkJSUNvbnRlbnRUeXBlTWFuYWdlciBtYW5hZ2VyID0gUGxhdGZvcm0uZ2V0Q29udGVudFR5cGVNYW5hZ2VyKCk7CgkJSUNvbnRlbnRUeXBlIHhtbCA9IG1hbmFnZXIuZ2V0Q29udGVudFR5cGUoUGxhdGZvcm0uUElfUlVOVElNRSArICIueG1sIik7CgkJSUNvbnRlbnRUeXBlIHJvb3RFbGVtZW50ID0gbWFuYWdlci5nZXRDb250ZW50VHlwZShQSV9SRVNPVVJDRVNfVEVTVFMgKyAiLnJvb3QtZWxlbWVudCIpOwoJCUlDb250ZW50VHlwZVtdIHNlbGVjdGVkID0gbnVsbDsKCQl0cnkgewoJCQlzZWxlY3RlZCA9IG1hbmFnZXIuZmluZENvbnRlbnRUeXBlc0ZvcihnZXRJbnB1dFN0cmVhbShYTUxfVVNfQVNDSUlfSU5WQUxJRCwgU3RhbmRhcmRDaGFyc2V0cy5JU09fODg1OV8xKSwgInRlc3QueG1sIik7CgkJfSBjYXRjaCAoSU9FeGNlcHRpb24gaW9lKSB7CgkJCS8vIGEgU0FYRXhjZXB0aW9uIGlzIHVzdWFsbHkgY2F1Z2h0IChhbmQgc2lsZW50bHkgaWdub3JlZCkgaW4gWE1MUm9vdEVsZW1lbnREZXNjcmliZXIgaW4gdGhlc2UgY2FzZXMKCQkJZmFpbCgiMS4wIiwgaW9lKTsKCQl9CgkJYXNzZXJ0VHJ1ZSgiMS4xIiwgY29udGFpbnMoc2VsZWN0ZWQsIHhtbCkpOwoJCWFzc2VydFRydWUoIjEuMiIsIGNvbnRhaW5zKHNlbGVjdGVkLCByb290RWxlbWVudCkpOwoKCQkvLyBpbmR1Y2UgcmVndWxhciBJT0V4Y2VwdGlvbnMuLi4gdGhlc2Ugc2hvdWxkIGJlIHRocm93biB0byBjbGllbnRzCgkJY2xhc3MgRmFrZUlPRXhjZXB0aW9uIGV4dGVuZHMgSU9FeGNlcHRpb24gewoJCQkvKioKCQkJICogQWxsIHNlcmlhbGl6YWJsZSBvYmplY3RzIHNob3VsZCBoYXZlIGEgc3RhYmxlIHNlcmlhbFZlcnNpb25VSUQKCQkJICovCgkJCXByaXZhdGUgc3RhdGljIGZpbmFsIGxvbmcgc2VyaWFsVmVyc2lvblVJRCA9IDFMOwoKCQkJQE92ZXJyaWRlCgkJCXB1YmxpYyBTdHJpbmcgZ2V0TWVzc2FnZSgpIHsKCQkJCXJldHVybiAiVGhpcyBleGNlcHRpb24gd2FzIHRocm93biBmb3IgdGVzdGluZyBwdXJwb3NlcyI7CgkJCX0KCQl9CgkJdHJ5IHsKCQkJc2VsZWN0ZWQgPSBtYW5hZ2VyLmZpbmRDb250ZW50VHlwZXNGb3IobmV3IElucHV0U3RyZWFtKCkgewoKCQkJCUBPdmVycmlkZQoJCQkJcHVibGljIGludCBhdmFpbGFibGUoKSB7CgkJCQkJLy8gdHJpY2sgdGhlIGNsaWVudCBpbnRvIHJlYWRpbmcgdGhlIGZpbGUKCQkJCQlyZXR1cm4gSW50ZWdlci5NQVhfVkFMVUU7CgkJCQl9CgoJCQkJQE92ZXJyaWRlCgkJCQlwdWJsaWMgaW50IHJlYWQoKSB0aHJvd3MgSU9FeGNlcHRpb24gewoJCQkJCXRocm93IG5ldyBGYWtlSU9FeGNlcHRpb24oKTsKCQkJCX0KCgkJCQlAT3ZlcnJpZGUKCQkJCXB1YmxpYyBpbnQgcmVhZChieXRlW10gYiwgaW50IG9mZiwgaW50IGxlbikgdGhyb3dzIElPRXhjZXB0aW9uIHsKCQkJCQl0aHJvdyBuZXcgRmFrZUlPRXhjZXB0aW9uKCk7CgkJCQl9CgkJCX0sICJ0ZXN0LnhtbCIpOwoJCQkvLyBhbiBleGNlcHRpb24gd2lsbCBoYXBwZW4gd2hlbiByZWFkaW5nIHRoZSBzdHJlYW0uLi4gc2hvdWxkIGJlIHRocm93biB0byB0aGUgY2FsbGVyCgkJCWZhaWwoIjIuMCIpOwoJCX0gY2F0Y2ggKEZha2VJT0V4Y2VwdGlvbiBmaW9lKSB7CgkJCS8vIHN1Y2VzcwoJCX0gY2F0Y2ggKElPRXhjZXB0aW9uIGlvZSkgewoJCQkvLyB0aGlzIHNob3VsZCBuZXZlciBoYXBwZW4sIGJ1dCBqdXN0IGluIGNhc2UuLi4KCQkJZmFpbCgiMi4xIik7CgkJfQoJfQoKCXB1YmxpYyB2b2lkIHRlc3RJc0tpbmRPZigpIHsKCQlJQ29udGVudFR5cGVNYW5hZ2VyIGNvbnRlbnRUeXBlTWFuYWdlciA9IFBsYXRmb3JtLmdldENvbnRlbnRUeXBlTWFuYWdlcigpOwoJCUlDb250ZW50VHlwZSB0ZXh0Q29udGVudFR5cGUgPSBjb250ZW50VHlwZU1hbmFnZXIuZ2V0Q29udGVudFR5cGUoUGxhdGZvcm0uUElfUlVOVElNRSArICcuJyArICJ0ZXh0Iik7CgkJSUNvbnRlbnRUeXBlIHhtbENvbnRlbnRUeXBlID0gY29udGVudFR5cGVNYW5hZ2VyLmdldENvbnRlbnRUeXBlKFBsYXRmb3JtLlBJX1JVTlRJTUUgKyAiLnhtbCIpOwoJCUlDb250ZW50VHlwZSB4bWxCYXNlZERpZmZlcmVudEV4dGVuc2lvbkNvbnRlbnRUeXBlID0gY29udGVudFR5cGVNYW5hZ2VyLmdldENvbnRlbnRUeXBlKFBJX1JFU09VUkNFU19URVNUUyArICcuJyArICJ4bWwtYmFzZWQtZGlmZmVyZW50LWV4dGVuc2lvbiIpOwoJCUlDb250ZW50VHlwZSB4bWxCYXNlZFNwZWNpZmljTmFtZUNvbnRlbnRUeXBlID0gY29udGVudFR5cGVNYW5hZ2VyLmdldENvbnRlbnRUeXBlKFBJX1JFU09VUkNFU19URVNUUyArICcuJyArICJ4bWwtYmFzZWQtc3BlY2lmaWMtbmFtZSIpOwoJCUlDb250ZW50VHlwZSBiaW5hcnlDb250ZW50VHlwZSA9IGNvbnRlbnRUeXBlTWFuYWdlci5nZXRDb250ZW50VHlwZShQSV9SRVNPVVJDRVNfVEVTVFMgKyAnLicgKyAic2FtcGxlLWJpbmFyeTEiKTsKCQlhc3NlcnRUcnVlKCIxLjAiLCB0ZXh0Q29udGVudFR5cGUuaXNLaW5kT2YodGV4dENvbnRlbnRUeXBlKSk7CgkJYXNzZXJ0VHJ1ZSgiMi4wIiwgeG1sQ29udGVudFR5cGUuaXNLaW5kT2YodGV4dENvbnRlbnRUeXBlKSk7CgkJYXNzZXJ0VHJ1ZSgiMi4xIiwgIXRleHRDb250ZW50VHlwZS5pc0tpbmRPZih4bWxDb250ZW50VHlwZSkpOwoJCWFzc2VydFRydWUoIjIuMiIsIHhtbENvbnRlbnRUeXBlLmlzS2luZE9mKHhtbENvbnRlbnRUeXBlKSk7CgkJYXNzZXJ0VHJ1ZSgiMy4wIiwgeG1sQmFzZWREaWZmZXJlbnRFeHRlbnNpb25Db250ZW50VHlwZS5pc0tpbmRPZih0ZXh0Q29udGVudFR5cGUpKTsKCQlhc3NlcnRUcnVlKCIzLjEiLCB4bWxCYXNlZERpZmZlcmVudEV4dGVuc2lvbkNvbnRlbnRUeXBlLmlzS2luZE9mKHhtbENvbnRlbnRUeXBlKSk7CgkJYXNzZXJ0VHJ1ZSgiNC4wIiwgIXhtbEJhc2VkRGlmZmVyZW50RXh0ZW5zaW9uQ29udGVudFR5cGUuaXNLaW5kT2YoeG1sQmFzZWRTcGVjaWZpY05hbWVDb250ZW50VHlwZSkpOwoJCWFzc2VydFRydWUoIjUuMCIsICFiaW5hcnlDb250ZW50VHlwZS5pc0tpbmRPZih0ZXh0Q29udGVudFR5cGUpKTsKCX0KCglwdWJsaWMgdm9pZCB0ZXN0TGlzdFBhcnNpbmcoKSB7CgkJU3RyaW5nW10gbGlzdDsKCQlsaXN0ID0gVXRpbC5wYXJzZUl0ZW1zKG51bGwpOwoJCWFzc2VydEVxdWFscygiMC4wIiwgMCwgbGlzdC5sZW5ndGgpOwoJCWxpc3QgPSBVdGlsLnBhcnNlSXRlbXMoIiIpOwoJCWFzc2VydEVxdWFscygiMS4wIiwgMSwgbGlzdC5sZW5ndGgpOwoJCWFzc2VydEVxdWFscygiMS4xIiwgIiIsIGxpc3RbMF0pOwoJCWxpc3QgPSBVdGlsLnBhcnNlSXRlbXMoImZvbyIpOwoJCWFzc2VydEVxdWFscygiMi4wIiwgMSwgbGlzdC5sZW5ndGgpOwoJCWFzc2VydEVxdWFscygiMi4xIiwgImZvbyIsIGxpc3RbMF0pOwoJCWxpc3QgPSBVdGlsLnBhcnNlSXRlbXMoIiwiKTsKCQlhc3NlcnRFcXVhbHMoIjMuMCIsIDIsIGxpc3QubGVuZ3RoKTsKCQlhc3NlcnRFcXVhbHMoIjMuMSIsICIiLCBsaXN0WzBdKTsKCQlhc3NlcnRFcXVhbHMoIjMuMiIsICIiLCBsaXN0WzFdKTsKCQlsaXN0ID0gVXRpbC5wYXJzZUl0ZW1zKCIsZm9vLGJhciIpOwoJCWFzc2VydEVxdWFscygiNC4wIiwgMywgbGlzdC5sZW5ndGgpOwoJCWFzc2VydEVxdWFscygiNC4xIiwgIiIsIGxpc3RbMF0pOwoJCWFzc2VydEVxdWFscygiNC4yIiwgImZvbyIsIGxpc3RbMV0pOwoJCWFzc2VydEVxdWFscygiNC4zIiwgImJhciIsIGxpc3RbMl0pOwoJCWxpc3QgPSBVdGlsLnBhcnNlSXRlbXMoImZvbyxiYXIsIik7CgkJYXNzZXJ0RXF1YWxzKCI1LjAiLCAzLCBsaXN0Lmxlbmd0aCk7CgkJYXNzZXJ0RXF1YWxzKCI1LjEiLCAiZm9vIiwgbGlzdFswXSk7CgkJYXNzZXJ0RXF1YWxzKCI1LjIiLCAiYmFyIiwgbGlzdFsxXSk7CgkJYXNzZXJ0RXF1YWxzKCI1LjMiLCAiIiwgbGlzdFsyXSk7CgkJbGlzdCA9IFV0aWwucGFyc2VJdGVtcygiZm9vLCxiYXIiKTsKCQlhc3NlcnRFcXVhbHMoIjYuMCIsIDMsIGxpc3QubGVuZ3RoKTsKCQlhc3NlcnRFcXVhbHMoIjYuMSIsICJmb28iLCBsaXN0WzBdKTsKCQlhc3NlcnRFcXVhbHMoIjYuMiIsICIiLCBsaXN0WzFdKTsKCQlhc3NlcnRFcXVhbHMoIjYuMyIsICJiYXIiLCBsaXN0WzJdKTsKCQlsaXN0ID0gVXRpbC5wYXJzZUl0ZW1zKCJmb28sLCxiYXIiKTsKCQlhc3NlcnRFcXVhbHMoIjcuMCIsIDQsIGxpc3QubGVuZ3RoKTsKCQlhc3NlcnRFcXVhbHMoIjcuMSIsICJmb28iLCBsaXN0WzBdKTsKCQlhc3NlcnRFcXVhbHMoIjcuMiIsICIiLCBsaXN0WzFdKTsKCQlhc3NlcnRFcXVhbHMoIjcuMyIsICIiLCBsaXN0WzJdKTsKCQlhc3NlcnRFcXVhbHMoIjcuNCIsICJiYXIiLCBsaXN0WzNdKTsKCQlsaXN0ID0gVXRpbC5wYXJzZUl0ZW1zKCIsLGZvbyxiYXIiKTsKCQlhc3NlcnRFcXVhbHMoIjguMCIsIDQsIGxpc3QubGVuZ3RoKTsKCQlhc3NlcnRFcXVhbHMoIjguMSIsICIiLCBsaXN0WzBdKTsKCQlhc3NlcnRFcXVhbHMoIjguMiIsICIiLCBsaXN0WzFdKTsKCQlhc3NlcnRFcXVhbHMoIjguMyIsICJmb28iLCBsaXN0WzJdKTsKCQlhc3NlcnRFcXVhbHMoIjguNCIsICJiYXIiLCBsaXN0WzNdKTsKCQlsaXN0ID0gVXRpbC5wYXJzZUl0ZW1zKCJmb28sYmFyLCwiKTsKCQlhc3NlcnRFcXVhbHMoIjkuMCIsIDQsIGxpc3QubGVuZ3RoKTsKCQlhc3NlcnRFcXVhbHMoIjkuMSIsICJmb28iLCBsaXN0WzBdKTsKCQlhc3NlcnRFcXVhbHMoIjkuMiIsICJiYXIiLCBsaXN0WzFdKTsKCQlhc3NlcnRFcXVhbHMoIjkuMyIsICIiLCBsaXN0WzJdKTsKCQlhc3NlcnRFcXVhbHMoIjkuNCIsICIiLCBsaXN0WzNdKTsKCQlsaXN0ID0gVXRpbC5wYXJzZUl0ZW1zKCIsLCwiKTsKCQlhc3NlcnRFcXVhbHMoIjEwLjAiLCA0LCBsaXN0Lmxlbmd0aCk7CgkJYXNzZXJ0RXF1YWxzKCIxMC4xIiwgIiIsIGxpc3RbMF0pOwoJCWFzc2VydEVxdWFscygiMTAuMiIsICIiLCBsaXN0WzFdKTsKCQlhc3NlcnRFcXVhbHMoIjEwLjMiLCAiIiwgbGlzdFsyXSk7CgkJYXNzZXJ0RXF1YWxzKCIxMC40IiwgIiIsIGxpc3RbM10pOwoJfQoKCXB1YmxpYyB2b2lkIHRlc3RNeUNvbnRlbnREZXNjcmliZXIoKSB0aHJvd3MgSU9FeGNlcHRpb24gewoJCUlDb250ZW50VHlwZU1hbmFnZXIgbWFuYWdlciA9IFBsYXRmb3JtLmdldENvbnRlbnRUeXBlTWFuYWdlcigpOwoJCUlDb250ZW50VHlwZSBteUNvbnRlbnQgPSBtYW5hZ2VyLmdldENvbnRlbnRUeXBlKFBJX1JFU09VUkNFU19URVNUUyArICcuJyArICJteUNvbnRlbnQiKTsKCQlhc3NlcnROb3ROdWxsKCIwLjUiLCBteUNvbnRlbnQpOwoJCWFzc2VydEVxdWFscygiMC42IiwgbXlDb250ZW50LCBtYW5hZ2VyLmZpbmRDb250ZW50VHlwZUZvcigibXlDb250ZW50Lm1jMSIpKTsKCQlhc3NlcnRFcXVhbHMoIjAuNyIsIG15Q29udGVudCwgbWFuYWdlci5maW5kQ29udGVudFR5cGVGb3IoIm15Q29udGVudC5tYzIiKSk7CgkJYXNzZXJ0RXF1YWxzKCIwLjgiLCBteUNvbnRlbnQsIG1hbmFnZXIuZmluZENvbnRlbnRUeXBlRm9yKCJmb28ubXlDb250ZW50MSIpKTsKCQlhc3NlcnRFcXVhbHMoIjAuOSIsIG15Q29udGVudCwgbWFuYWdlci5maW5kQ29udGVudFR5cGVGb3IoImJhci5teUNvbnRlbnQyIikpOwoJCUlDb250ZW50RGVzY3JpcHRpb24gZGVzY3JpcHRpb24gPSBtYW5hZ2VyLmdldERlc2NyaXB0aW9uRm9yKGdldElucHV0U3RyZWFtKE15Q29udGVudERlc2NyaWJlci5TSUdOQVRVUkUsIFN0YW5kYXJkQ2hhcnNldHMuVVNfQVNDSUkpLCAibXlDb250ZW50Lm1jMSIsIElDb250ZW50RGVzY3JpcHRpb24uQUxMKTsKCQlhc3NlcnROb3ROdWxsKCIxLjAiLCBkZXNjcmlwdGlvbik7CgkJYXNzZXJ0RXF1YWxzKCIxLjEiLCBteUNvbnRlbnQsIGRlc2NyaXB0aW9uLmdldENvbnRlbnRUeXBlKCkpOwoJCWFzc2VydE5vdFNhbWUoIjEuMiIsIG15Q29udGVudC5nZXREZWZhdWx0RGVzY3JpcHRpb24oKSwgZGVzY3JpcHRpb24pOwoJCWZvciAoaW50IGkgPSAwOyBpIDwgTXlDb250ZW50RGVzY3JpYmVyLk1ZX09QVElPTlMubGVuZ3RoOyBpKyspIHsKCQkJYXNzZXJ0RXF1YWxzKCIyLiIgKyBpLCBNeUNvbnRlbnREZXNjcmliZXIuTVlfT1BUSU9OX1ZBTFVFU1tpXSwgZGVzY3JpcHRpb24uZ2V0UHJvcGVydHkoTXlDb250ZW50RGVzY3JpYmVyLk1ZX09QVElPTlNbaV0pKTsKCQl9Cgl9CgoJcHVibGljIHZvaWQgdGVzdE5vRXh0ZW5zaW9uQXNzb2NpYXRpb24oKSB7CgkJLy9UT0RPIHVzZSBhIElDb250ZW50VHlwZU1hdGNoZXIgaW5zdGVhZAoJCWZpbmFsIElDb250ZW50VHlwZU1hbmFnZXIgbWFuYWdlciA9IFBsYXRmb3JtLmdldENvbnRlbnRUeXBlTWFuYWdlcigpOwoKCQlJQ29udGVudFR5cGVbXSBzZWxlY3RlZCA9IG1hbmFnZXIuZmluZENvbnRlbnRUeXBlc0ZvcigiZmlsZV93aXRoX25vX2V4dGVuc2lvbiIpOwoJCWFzc2VydEVxdWFscygiMC4xIiwgMCwgc2VsZWN0ZWQubGVuZ3RoKTsKCgkJVGVzdFJlZ2lzdHJ5Q2hhbmdlTGlzdGVuZXIgbGlzdGVuZXIgPSBuZXcgVGVzdFJlZ2lzdHJ5Q2hhbmdlTGlzdGVuZXIoUGxhdGZvcm0uUElfUlVOVElNRSwgQ29udGVudFR5cGVCdWlsZGVyLlBUX0NPTlRFTlRUWVBFUywgbnVsbCwgbnVsbCk7CgkJQnVuZGxlVGVzdGluZ0hlbHBlci5ydW5XaXRoQnVuZGxlcygiMSIsICgpIC0+IHsKCQkJZmluYWwgU3RyaW5nIG5hbWVzcGFjZSA9ICJvcmcuZWNsaXBzZS5idW5kbGUwNCI7CgoJCQlJQ29udGVudFR5cGUgZW1wdHkxID0gbWFuYWdlci5nZXRDb250ZW50VHlwZShuYW1lc3BhY2UgKyAiLmVtcHR5X2V4dGVuc2lvbjEiKTsKCQkJSUNvbnRlbnRUeXBlIGVtcHR5MiA9IG1hbmFnZXIuZ2V0Q29udGVudFR5cGUobmFtZXNwYWNlICsgIi5lbXB0eV9leHRlbnNpb24yIik7CgkJCUlDb250ZW50VHlwZSBlbXB0eTMgPSBtYW5hZ2VyLmdldENvbnRlbnRUeXBlKG5hbWVzcGFjZSArICIuZW1wdHlfZXh0ZW5zaW9uMyIpOwoJCQlJQ29udGVudFR5cGUgZW1wdHk0ID0gbWFuYWdlci5nZXRDb250ZW50VHlwZShuYW1lc3BhY2UgKyAiLmVtcHR5X2V4dGVuc2lvbjQiKTsKCQkJSUNvbnRlbnRUeXBlIG5vbkVtcHR5ID0gbWFuYWdlci5nZXRDb250ZW50VHlwZShuYW1lc3BhY2UgKyAiLm5vbl9lbXB0eV9leHRlbnNpb24iKTsKCgkJCWFzc2VydE5vdE51bGwoIjEuMS4xIiwgZW1wdHkxKTsKCQkJYXNzZXJ0Tm90TnVsbCgiMS4xLjIiLCBlbXB0eTIpOwoJCQlhc3NlcnROb3ROdWxsKCIxLjEuMyIsIGVtcHR5Myk7CgkJCWFzc2VydE5vdE51bGwoIjEuMS40IiwgZW1wdHk0KTsKCQkJYXNzZXJ0Tm90TnVsbCgiMS4xLjUiLCBub25FbXB0eSk7CgoJCQlJQ29udGVudFR5cGVbXSBzZWxlY3RlZDEgPSBtYW5hZ2VyLmZpbmRDb250ZW50VHlwZXNGb3IoImZpbGVfd2l0aF9ub19leHRlbnNpb24iKTsKCQkJYXNzZXJ0RXF1YWxzKCIxLjIuMCIsIDQsIHNlbGVjdGVkMS5sZW5ndGgpOwoJCQlhc3NlcnRUcnVlKCIxLjIuMSIsIGNvbnRhaW5zKHNlbGVjdGVkMSwgZW1wdHkxKSk7CgkJCWFzc2VydFRydWUoIjEuMi4yIiwgY29udGFpbnMoc2VsZWN0ZWQxLCBlbXB0eTIpKTsKCQkJYXNzZXJ0VHJ1ZSgiMS4yLjMiLCBjb250YWlucyhzZWxlY3RlZDEsIGVtcHR5MykpOwoJCQlhc3NlcnRUcnVlKCIxLjIuNCIsIGNvbnRhaW5zKHNlbGVjdGVkMSwgZW1wdHk0KSk7CgoJCQlzZWxlY3RlZDEgPSBtYW5hZ2VyLmZpbmRDb250ZW50VHlwZXNGb3IoImZpbGVfd2l0aF9leHRlbnNpb24ubm9uLWVtcHR5Iik7CgkJCWFzc2VydEVxdWFscygiMS4yLjUiLCAxLCBzZWxlY3RlZDEubGVuZ3RoKTsKCQkJYXNzZXJ0VHJ1ZSgiMS4yLjYiLCBjb250YWlucyhzZWxlY3RlZDEsIG5vbkVtcHR5KSk7CgoJCQl0cnkgewoJCQkJbm9uRW1wdHkuYWRkRmlsZVNwZWMoIiIsIElDb250ZW50VHlwZS5GSUxFX0VYVEVOU0lPTl9TUEVDKTsKCQkJfSBjYXRjaCAoQ29yZUV4Y2VwdGlvbiBlMSkgewoJCQkJZmFpbCgiMS4zLjAiLCBlMSk7CgkJCX0KCQkJdHJ5IHsKCQkJCXNlbGVjdGVkMSA9IG1hbmFnZXIuZmluZENvbnRlbnRUeXBlc0ZvcigiZmlsZV93aXRoX25vX2V4dGVuc2lvbiIpOwoJCQkJYXNzZXJ0RXF1YWxzKCIxLjMuMSIsIDUsIHNlbGVjdGVkMS5sZW5ndGgpOwoJCQkJYXNzZXJ0VHJ1ZSgiMS4zLjIiLCBjb250YWlucyhzZWxlY3RlZDEsIG5vbkVtcHR5KSk7CgkJCX0gZmluYWxseSB7CgkJCQl0cnkgewoJCQkJCW5vbkVtcHR5LnJlbW92ZUZpbGVTcGVjKCIiLCBJQ29udGVudFR5cGUuRklMRV9FWFRFTlNJT05fU1BFQyk7CgkJCQl9IGNhdGNoIChDb3JlRXhjZXB0aW9uIGUyKSB7CgkJCQkJZmFpbCgiMS4zLjMiLCBlMik7CgkJCQl9CgkJCX0KCQkJc2VsZWN0ZWQxID0gbWFuYWdlci5maW5kQ29udGVudFR5cGVzRm9yKCJmaWxlX3dpdGhfbm9fZXh0ZW5zaW9uIik7CgkJCWFzc2VydEVxdWFscygiMS40LjAiLCA0LCBzZWxlY3RlZDEubGVuZ3RoKTsKCQkJYXNzZXJ0VHJ1ZSgiMS40LjEiLCAhY29udGFpbnMoc2VsZWN0ZWQxLCBub25FbXB0eSkpOwoJCX0sIGdldENvbnRleHQoKSwgbmV3IFN0cmluZ1tdIHtDb250ZW50VHlwZVRlc3QuVEVTVF9GSUxFU19ST09UICsgImNvbnRlbnQvYnVuZGxlMDQifSwgbGlzdGVuZXIpOwoJfQoKCXB1YmxpYyB2b2lkIHRlc3RPcmRlcldpdGhFbXB0eUZpbGVzKCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKCQlJQ29udGVudFR5cGVNYW5hZ2VyIG1hbmFnZXIgPSBQbGF0Zm9ybS5nZXRDb250ZW50VHlwZU1hbmFnZXIoKTsKCQlJQ29udGVudFR5cGVNYXRjaGVyIGZpbmRlciA9IG1hbmFnZXIuZ2V0TWF0Y2hlcihuZXcgTG9jYWxTZWxlY3Rpb25Qb2xpY3koKSwgbnVsbCk7CgoJCUlDb250ZW50VHlwZSB4bWwgPSBtYW5hZ2VyLmdldENvbnRlbnRUeXBlKFBsYXRmb3JtLlBJX1JVTlRJTUUgKyAiLnhtbCIpOwoJCW1hbmFnZXIuZ2V0Q29udGVudFR5cGUoUElfUkVTT1VSQ0VTX1RFU1RTICsgIi5yb290LWVsZW1lbnQiKTsKCQltYW5hZ2VyLmdldENvbnRlbnRUeXBlKFBJX1JFU09VUkNFU19URVNUUyArICIuZHRkIik7CgkJLy8gZm9yIGFuIGVtcHR5IGZpbGUsIHRoZSBtb3N0IGdlbmVyaWMgY29udGVudCB0eXBlIHNob3VsZCBiZSByZXR1cm5lZAoJCUlDb250ZW50VHlwZSBzZWxlY3RlZCA9IGZpbmRlci5maW5kQ29udGVudFR5cGVGb3IoZ2V0SW5wdXRTdHJlYW0oIiIpLCAiZm9vLnhtbCIpOwoJCWFzc2VydEVxdWFscygiMS4wIiwgeG1sLCBzZWxlY3RlZCk7CgkJLy8gaXQgc2hvdWxkIGJlIGVxdWl2YWxlbnQgdG8gb21pdHRpbmcgdGhlIGNvbnRlbnRzCgkJYXNzZXJ0RXF1YWxzKCIxLjEiLCB4bWwsIGZpbmRlci5maW5kQ29udGVudFR5cGVGb3IoImZvby54bWwiKSk7Cgl9CgoJLyoqCgkgKiBUaGlzIHRlc3Qgc2hvd3MgaG93IHdlIGRlYWwgd2l0aCBvcnBoYW4gZmlsZSBhc3NvY2lhdGlvbnMgKGFzc29jaWF0aW9ucwoJICogd2hvc2UgY29udGVudCB0eXBlcyBhcmUgbWlzc2luZykuCgkgKi8KCXB1YmxpYyB2b2lkIHRlc3RPcnBoYW5Db250ZW50VHlwZSgpIHsKCQlmaW5hbCBJQ29udGVudFR5cGVNYW5hZ2VyIGNvbnRlbnRUeXBlTWFuYWdlciA9IFBsYXRmb3JtLmdldENvbnRlbnRUeXBlTWFuYWdlcigpOwoJCUlDb250ZW50VHlwZSBvcnBoYW4gPSBjb250ZW50VHlwZU1hbmFnZXIuZ2V0Q29udGVudFR5cGUoUElfUkVTT1VSQ0VTX1RFU1RTICsgIi5vcnBoYW4iKTsKCQlhc3NlcnROdWxsKCIwLjgiLCBvcnBoYW4pOwoJCUlDb250ZW50VHlwZSBtaXNzaW5nID0gY29udGVudFR5cGVNYW5hZ2VyLmdldENvbnRlbnRUeXBlKCJvcmcuZWNsaXBzZS5idW5kbGUwMS5taXNzaW5nIik7CgkJYXNzZXJ0TnVsbCgiMC45IiwgbWlzc2luZyk7CgkJYXNzZXJ0RXF1YWxzKCIxLjEiLCAwLCBjb250ZW50VHlwZU1hbmFnZXIuZmluZENvbnRlbnRUeXBlc0ZvcigiZm9vLm9ycGhhbiIpLmxlbmd0aCk7CgkJYXNzZXJ0RXF1YWxzKCIxLjIiLCAwLCBjb250ZW50VHlwZU1hbmFnZXIuZmluZENvbnRlbnRUeXBlc0Zvcigib3JwaGFuLm9ycGhhbiIpLmxlbmd0aCk7CgkJYXNzZXJ0RXF1YWxzKCIxLjMiLCAwLCBjb250ZW50VHlwZU1hbmFnZXIuZmluZENvbnRlbnRUeXBlc0ZvcigiZm9vLm9ycGhhbjIiKS5sZW5ndGgpOwoKCQkvL3Rlc3QgbGF0ZSBhZGRpdGlvbiBvZiBjb250ZW50IHR5cGUgLSBvcnBoYW4yIHNob3VsZCBiZWNvbWUgdmlzaWJsZQoJCVRlc3RSZWdpc3RyeUNoYW5nZUxpc3RlbmVyIGxpc3RlbmVyID0gbmV3IFRlc3RSZWdpc3RyeUNoYW5nZUxpc3RlbmVyKFBsYXRmb3JtLlBJX1JVTlRJTUUsIENvbnRlbnRUeXBlQnVpbGRlci5QVF9DT05URU5UVFlQRVMsIG51bGwsIG51bGwpOwoKCQlCdW5kbGVUZXN0aW5nSGVscGVyLnJ1bldpdGhCdW5kbGVzKCIyIiwgKCkgLT4gewoJCQlJQ29udGVudFR5cGUgb3JwaGFuMSA9IGNvbnRlbnRUeXBlTWFuYWdlci5nZXRDb250ZW50VHlwZShQSV9SRVNPVVJDRVNfVEVTVFMgKyAiLm9ycGhhbiIpOwoJCQlhc3NlcnROb3ROdWxsKCIyLjEiLCBvcnBoYW4xKTsKCQkJSUNvbnRlbnRUeXBlIG1pc3NpbmcxID0gY29udGVudFR5cGVNYW5hZ2VyLmdldENvbnRlbnRUeXBlKCJvcmcuZWNsaXBzZS5idW5kbGUwMS5taXNzaW5nIik7CgkJCWFzc2VydE5vdE51bGwoIjIuMiIsIG1pc3NpbmcxKTsKCQkJLy8gY2hlY2tzIG9ycGhhbidzIGFzc29jaWF0aW9ucwoJCQlhc3NlcnRFcXVhbHMoIjIuMyIsIDEsIGNvbnRlbnRUeXBlTWFuYWdlci5maW5kQ29udGVudFR5cGVzRm9yKCJmb28ub3JwaGFuIikubGVuZ3RoKTsKCQkJYXNzZXJ0RXF1YWxzKCIyLjQiLCBvcnBoYW4xLCBjb250ZW50VHlwZU1hbmFnZXIuZmluZENvbnRlbnRUeXBlc0ZvcigiZm9vLm9ycGhhbiIpWzBdKTsKCQkJYXNzZXJ0RXF1YWxzKCIyLjUiLCAxLCBjb250ZW50VHlwZU1hbmFnZXIuZmluZENvbnRlbnRUeXBlc0Zvcigib3JwaGFuLm9ycGhhbiIpLmxlbmd0aCk7CgkJCWFzc2VydEVxdWFscygiMi42Iiwgb3JwaGFuMSwgY29udGVudFR5cGVNYW5hZ2VyLmZpbmRDb250ZW50VHlwZXNGb3IoImZvby5vcnBoYW4iKVswXSk7CgkJCS8vIGNoZWNrIHdoZXRoZXIgYW4gb3JwaGFuIGFzc29jaWF0aW9uIHdhcyBhZGRlZCB0byB0aGUgZHluYW1pY2FsbHkgYWRkZWQgYnVuZGxlCgkJCWFzc2VydEVxdWFscygiMi43IiwgMSwgY29udGVudFR5cGVNYW5hZ2VyLmZpbmRDb250ZW50VHlwZXNGb3IoImZvby5vcnBoYW4yIikubGVuZ3RoKTsKCQkJYXNzZXJ0RXF1YWxzKCIyLjgiLCBtaXNzaW5nMSwgY29udGVudFR5cGVNYW5hZ2VyLmZpbmRDb250ZW50VHlwZXNGb3IoImZvby5vcnBoYW4yIilbMF0pOwoJCX0sIGdldENvbnRleHQoKSwgbmV3IFN0cmluZ1tdIHtDb250ZW50VHlwZVRlc3QuVEVTVF9GSUxFU19ST09UICsgImNvbnRlbnQvYnVuZGxlMDEifSwgbGlzdGVuZXIpOwoJfQoKCS8qKgoJICogUmVncmVzc2lvbiB0ZXN0IGZvciBidWcgNjg4OTQKCSAqLwoJcHVibGljIHZvaWQgdGVzdFByZWZlcmVuY2VzKCkgdGhyb3dzIENvcmVFeGNlcHRpb24sIEJhY2tpbmdTdG9yZUV4Y2VwdGlvbiB7CgkJSUNvbnRlbnRUeXBlTWFuYWdlciBtYW5hZ2VyID0gUGxhdGZvcm0uZ2V0Q29udGVudFR5cGVNYW5hZ2VyKCk7CgkJSUNvbnRlbnRUeXBlIHRleHQgPSBtYW5hZ2VyLmdldENvbnRlbnRUeXBlKElDb250ZW50VHlwZU1hbmFnZXIuQ1RfVEVYVCk7CgkJUHJlZmVyZW5jZXMgdGV4dFByZWZzID0gSW5zdGFuY2VTY29wZS5JTlNUQU5DRS5nZXROb2RlKENvbnRlbnRUeXBlTWFuYWdlci5DT05URU5UX1RZUEVfUFJFRl9OT0RFKS5ub2RlKHRleHQuZ2V0SWQoKSk7CgkJYXNzZXJ0Tm90TnVsbCgiMC4xIiwgdGV4dCk7CgoJCS8vIGVuc3VyZSB0aGUgImRlZmF1bHQgY2hhcnNldCIgcHJlZmVyZW5jZSBpcyBiZWluZyBwcm9wZXJseSB1c2VkCgkJYXNzZXJ0TnVsbCgiMS4wIiwgdGV4dC5nZXREZWZhdWx0Q2hhcnNldCgpKTsKCQlhc3NlcnROdWxsKCIxLjEiLCB0ZXh0UHJlZnMuZ2V0KENvbnRlbnRUeXBlLlBSRUZfREVGQVVMVF9DSEFSU0VULCBudWxsKSk7CgkJdGV4dC5zZXREZWZhdWx0Q2hhcnNldCgiVVRGLTgiKTsKCQlhc3NlcnRFcXVhbHMoIjEuMiIsICJVVEYtOCIsIHRleHRQcmVmcy5nZXQoQ29udGVudFR5cGUuUFJFRl9ERUZBVUxUX0NIQVJTRVQsIG51bGwpKTsKCQl0ZXh0LnNldERlZmF1bHRDaGFyc2V0KG51bGwpOwoJCWFzc2VydE51bGwoIjEuMyIsIHRleHRQcmVmcy5nZXQoQ29udGVudFR5cGUuUFJFRl9ERUZBVUxUX0NIQVJTRVQsIG51bGwpKTsKCgkJLy8gZW5zdXJlIHRoZSBmaWxlIHNwZWMgcHJlZmVyZW5jZXMgYXJlIGJlaW5nIHByb3Blcmx5IHVzZWQKCQkvLyBzb21lIHNhbml0eSBjaGVja2luZwoJCWFzc2VydEZhbHNlKCIyLjAxIiwgdGV4dC5pc0Fzc29jaWF0ZWRXaXRoKCJ4eXouZm9vIikpOwoJCWFzc2VydEZhbHNlKCIyLjAxIiwgdGV4dC5pc0Fzc29jaWF0ZWRXaXRoKCJ4eXouYmFyIikpOwoJCWFzc2VydEZhbHNlKCIyLjAzIiwgdGV4dC5pc0Fzc29jaWF0ZWRXaXRoKCJmb28uZXh0IikpOwoJCWFzc2VydEZhbHNlKCIyLjA0IiwgdGV4dC5pc0Fzc29jaWF0ZWRXaXRoKCJiYXIuZXh0IikpOwoJCS8vTnVsbCBlbnRyaWVzIGZpcnN0IHRvIGF2b2lkIGludGVyZmVyZW5jZSBmcm9tIG90aGVyIHRlc3RzCgkJdGV4dFByZWZzLnJlbW92ZShDb250ZW50VHlwZS5QUkVGX0ZJTEVfTkFNRVMpOwoJCXRleHRQcmVmcy5yZW1vdmUoQ29udGVudFR5cGUuUFJFRl9GSUxFX0VYVEVOU0lPTlMpOwoJCS8vIHBsYXkgd2l0aCBmaWxlIG5hbWUgYXNzb2NpYXRpb25zIGZpcnN0Li4uCgkJYXNzZXJ0TnVsbCgiMi4wYSIsIHRleHRQcmVmcy5nZXQoQ29udGVudFR5cGUuUFJFRl9GSUxFX05BTUVTLCBudWxsKSk7CgkJYXNzZXJ0TnVsbCgiMi4wYiIsIHRleHRQcmVmcy5nZXQoQ29udGVudFR5cGUuUFJFRl9GSUxFX0VYVEVOU0lPTlMsIG51bGwpKTsKCQl0ZXh0LmFkZEZpbGVTcGVjKCJmb28uZXh0IiwgSUNvbnRlbnRUeXBlLkZJTEVfTkFNRV9TUEVDKTsKCQlhc3NlcnRUcnVlKCIyLjEiLCB0ZXh0LmlzQXNzb2NpYXRlZFdpdGgoImZvby5leHQiKSk7CgkJYXNzZXJ0RXF1YWxzKCIyLjIiLCAiZm9vLmV4dCIsIHRleHRQcmVmcy5nZXQoQ29udGVudFR5cGUuUFJFRl9GSUxFX05BTUVTLCBudWxsKSk7CgkJdGV4dC5hZGRGaWxlU3BlYygiYmFyLmV4dCIsIElDb250ZW50VHlwZS5GSUxFX05BTUVfU1BFQyk7CgkJYXNzZXJ0VHJ1ZSgiMi4zIiwgdGV4dC5pc0Fzc29jaWF0ZWRXaXRoKCJiYXIuZXh0IikpOwoJCWFzc2VydEVxdWFscygiMi40IiwgImZvby5leHQsYmFyLmV4dCIsIHRleHRQcmVmcy5nZXQoQ29udGVudFR5cGUuUFJFRl9GSUxFX05BTUVTLCBudWxsKSk7CgkJLy8gLi4uIGFuZCB0aGVuIHdpdGggZmlsZSBleHRlbnNpb25zCgkJdGV4dC5hZGRGaWxlU3BlYygiZm9vIiwgSUNvbnRlbnRUeXBlLkZJTEVfRVhURU5TSU9OX1NQRUMpOwoJCWFzc2VydFRydWUoIjIuNSIsIHRleHQuaXNBc3NvY2lhdGVkV2l0aCgieHl6LmZvbyIpKTsKCQlhc3NlcnRFcXVhbHMoIjIuNiIsICJmb28iLCB0ZXh0UHJlZnMuZ2V0KENvbnRlbnRUeXBlLlBSRUZfRklMRV9FWFRFTlNJT05TLCBudWxsKSk7CgkJdGV4dC5hZGRGaWxlU3BlYygiYmFyIiwgSUNvbnRlbnRUeXBlLkZJTEVfRVhURU5TSU9OX1NQRUMpOwoJCWFzc2VydFRydWUoIjIuNyIsIHRleHQuaXNBc3NvY2lhdGVkV2l0aCgieHl6LmJhciIpKTsKCQlhc3NlcnRFcXVhbHMoIjIuNCIsICJmb28sYmFyIiwgdGV4dFByZWZzLmdldChDb250ZW50VHlwZS5QUkVGX0ZJTEVfRVhURU5TSU9OUywgbnVsbCkpOwoJCS8vIHJlbW92ZSBhbGwgYXNzb2NpYXRpb25zIG1hZGUKCQl0ZXh0LnJlbW92ZUZpbGVTcGVjKCJmb28uZXh0IiwgSUNvbnRlbnRUeXBlLkZJTEVfTkFNRV9TUEVDKTsKCQl0ZXh0LnJlbW92ZUZpbGVTcGVjKCJiYXIuZXh0IiwgSUNvbnRlbnRUeXBlLkZJTEVfTkFNRV9TUEVDKTsKCQl0ZXh0LnJlbW92ZUZpbGVTcGVjKCJmb28iLCBJQ29udGVudFR5cGUuRklMRV9FWFRFTlNJT05fU1BFQyk7CgkJdGV4dC5yZW1vdmVGaWxlU3BlYygiYmFyIiwgSUNvbnRlbnRUeXBlLkZJTEVfRVhURU5TSU9OX1NQRUMpOwoJCS8vIGVuc3VyZSBhbGwgaXMgYXMgYmVmb3JlCgkJYXNzZXJ0RmFsc2UoIjMuMSIsIHRleHQuaXNBc3NvY2lhdGVkV2l0aCgieHl6LmZvbyIpKTsKCQlhc3NlcnRGYWxzZSgiMy4yIiwgdGV4dC5pc0Fzc29jaWF0ZWRXaXRoKCJ4eXouYmFyIikpOwoJCWFzc2VydEZhbHNlKCIzLjMiLCB0ZXh0LmlzQXNzb2NpYXRlZFdpdGgoImZvby5leHQiKSk7CgkJYXNzZXJ0RmFsc2UoIjMuNCIsIHRleHQuaXNBc3NvY2lhdGVkV2l0aCgiYmFyLmV4dCIpKTsKCgkJLy8gZW5zdXJlIHRoZSBzZXJpYWxpemF0aW9uIGZvcm1hdCBpcyBjb3JyZWN0CgkJdHJ5IHsKCQkJdGV4dC5hZGRGaWxlU3BlYygiZm9vLmJhciIsIElDb250ZW50VHlwZS5GSUxFX05BTUVfU1BFQyk7CgkJCXRleHRQcmVmcy5zeW5jKCk7CgkJCWFzc2VydEVxdWFscygiNC4wIiwgImZvby5iYXIiLCB0ZXh0UHJlZnMuZ2V0KENvbnRlbnRUeXBlLlBSRUZfRklMRV9OQU1FUywgbnVsbCkpOwoJCX0gZmluYWxseSB7CgkJCS8vIGNsZWFuLXVwCgkJCXRleHQucmVtb3ZlRmlsZVNwZWMoImZvby5iYXIiLCBJQ29udGVudFR5cGUuRklMRV9OQU1FX1NQRUMpOwoJCX0KCX0KCglwdWJsaWMgdm9pZCB0ZXN0UmVnaXN0cnkoKSB7CgkJSUNvbnRlbnRUeXBlTWFuYWdlciBjb250ZW50VHlwZU1hbmFnZXIgPSBQbGF0Zm9ybS5nZXRDb250ZW50VHlwZU1hbmFnZXIoKTsKCQlJQ29udGVudFR5cGVNYXRjaGVyIGZpbmRlciA9IGNvbnRlbnRUeXBlTWFuYWdlci5nZXRNYXRjaGVyKG5ldyBMb2NhbFNlbGVjdGlvblBvbGljeSgpLCBudWxsKTsKCgkJSUNvbnRlbnRUeXBlIHRleHRDb250ZW50VHlwZSA9IGNvbnRlbnRUeXBlTWFuYWdlci5nZXRDb250ZW50VHlwZShQbGF0Zm9ybS5QSV9SVU5USU1FICsgJy4nICsgInRleHQiKTsKCQlhc3NlcnROb3ROdWxsKCIxLjAiLCB0ZXh0Q29udGVudFR5cGUpOwoJCWFzc2VydFRydWUoIjEuMSIsIGlzVGV4dChjb250ZW50VHlwZU1hbmFnZXIsIHRleHRDb250ZW50VHlwZSkpOwoJCWFzc2VydE5vdE51bGwoIjEuMiIsICgoQ29udGVudFR5cGVIYW5kbGVyKSB0ZXh0Q29udGVudFR5cGUpLmdldFRhcmdldCgpLmdldERlc2NyaWJlcigpKTsKCgkJSUNvbnRlbnRUeXBlIHhtbENvbnRlbnRUeXBlID0gY29udGVudFR5cGVNYW5hZ2VyLmdldENvbnRlbnRUeXBlKFBsYXRmb3JtLlBJX1JVTlRJTUUgKyAiLnhtbCIpOwoJCWFzc2VydE5vdE51bGwoIjIuMCIsIHhtbENvbnRlbnRUeXBlKTsKCQlhc3NlcnRUcnVlKCIyLjEiLCBpc1RleHQoY29udGVudFR5cGVNYW5hZ2VyLCB4bWxDb250ZW50VHlwZSkpOwoJCWFzc2VydEVxdWFscygiMi4yIiwgdGV4dENvbnRlbnRUeXBlLCB4bWxDb250ZW50VHlwZS5nZXRCYXNlVHlwZSgpKTsKCQlJQ29udGVudERlc2NyaWJlciB4bWxEZXNjcmliZXIgPSAoKENvbnRlbnRUeXBlSGFuZGxlcikgeG1sQ29udGVudFR5cGUpLmdldFRhcmdldCgpLmdldERlc2NyaWJlcigpOwoJCWFzc2VydE5vdE51bGwoIjIuMyIsIHhtbERlc2NyaWJlcik7CgkJYXNzZXJ0VHJ1ZSgiMi40IiwgeG1sRGVzY3JpYmVyIGluc3RhbmNlb2YgWE1MQ29udGVudERlc2NyaWJlcik7CgoJCUlDb250ZW50VHlwZSB4bWxCYXNlZERpZmZlcmVudEV4dGVuc2lvbkNvbnRlbnRUeXBlID0gY29udGVudFR5cGVNYW5hZ2VyLmdldENvbnRlbnRUeXBlKFBJX1JFU09VUkNFU19URVNUUyArICcuJyArICJ4bWwtYmFzZWQtZGlmZmVyZW50LWV4dGVuc2lvbiIpOwoJCWFzc2VydE5vdE51bGwoIjMuMCIsIHhtbEJhc2VkRGlmZmVyZW50RXh0ZW5zaW9uQ29udGVudFR5cGUpOwoJCWFzc2VydFRydWUoIjMuMSIsIGlzVGV4dChjb250ZW50VHlwZU1hbmFnZXIsIHhtbEJhc2VkRGlmZmVyZW50RXh0ZW5zaW9uQ29udGVudFR5cGUpKTsKCQlhc3NlcnRFcXVhbHMoIjMuMiIsIHhtbENvbnRlbnRUeXBlLCB4bWxCYXNlZERpZmZlcmVudEV4dGVuc2lvbkNvbnRlbnRUeXBlLmdldEJhc2VUeXBlKCkpOwoKCQlJQ29udGVudFR5cGUgeG1sQmFzZWRTcGVjaWZpY05hbWVDb250ZW50VHlwZSA9IGNvbnRlbnRUeXBlTWFuYWdlci5nZXRDb250ZW50VHlwZShQSV9SRVNPVVJDRVNfVEVTVFMgKyAnLicgKyAieG1sLWJhc2VkLXNwZWNpZmljLW5hbWUiKTsKCQlhc3NlcnROb3ROdWxsKCI0LjAiLCB4bWxCYXNlZFNwZWNpZmljTmFtZUNvbnRlbnRUeXBlKTsKCQlhc3NlcnRUcnVlKCI0LjEiLCBpc1RleHQoY29udGVudFR5cGVNYW5hZ2VyLCB4bWxCYXNlZFNwZWNpZmljTmFtZUNvbnRlbnRUeXBlKSk7CgkJYXNzZXJ0RXF1YWxzKCI0LjIiLCB4bWxDb250ZW50VHlwZSwgeG1sQmFzZWRTcGVjaWZpY05hbWVDb250ZW50VHlwZS5nZXRCYXNlVHlwZSgpKTsKCgkJSUNvbnRlbnRUeXBlW10geG1sVHlwZXMgPSBmaW5kZXIuZmluZENvbnRlbnRUeXBlc0ZvcihjaGFuZ2VDYXNlKCJmb28ueG1sIikpOwoJCWFzc2VydFRydWUoIjUuMSIsIGNvbnRhaW5zKHhtbFR5cGVzLCB4bWxDb250ZW50VHlwZSkpOwoKCQlJQ29udGVudFR5cGUgYmluYXJ5Q29udGVudFR5cGUgPSBjb250ZW50VHlwZU1hbmFnZXIuZ2V0Q29udGVudFR5cGUoUElfUkVTT1VSQ0VTX1RFU1RTICsgJy4nICsgInNhbXBsZS1iaW5hcnkxIik7CgkJYXNzZXJ0Tm90TnVsbCgiNi4wIiwgYmluYXJ5Q29udGVudFR5cGUpOwoJCWFzc2VydFRydWUoIjYuMSIsICFpc1RleHQoY29udGVudFR5cGVNYW5hZ2VyLCBiaW5hcnlDb250ZW50VHlwZSkpOwoJCWFzc2VydE51bGwoIjYuMiIsIGJpbmFyeUNvbnRlbnRUeXBlLmdldEJhc2VUeXBlKCkpOwoKCQlJQ29udGVudFR5cGVbXSBiaW5hcnlUeXBlcyA9IGZpbmRlci5maW5kQ29udGVudFR5cGVzRm9yKGNoYW5nZUNhc2UoImZvby5zYW1wbGViaW4xIikpOwoJCWFzc2VydEVxdWFscygiNy4wIiwgMSwgYmluYXJ5VHlwZXMubGVuZ3RoKTsKCQlhc3NlcnRFcXVhbHMoIjcuMSIsIGJpbmFyeUNvbnRlbnRUeXBlLCBiaW5hcnlUeXBlc1swXSk7CgoJCUlDb250ZW50VHlwZSBteVRleHQgPSBjb250ZW50VHlwZU1hbmFnZXIuZ2V0Q29udGVudFR5cGUoUElfUkVTT1VSQ0VTX1RFU1RTICsgIi5teXRleHQiKTsKCQlhc3NlcnROb3ROdWxsKCI4LjAiLCBteVRleHQpOwoJCWFzc2VydEVxdWFscygiOC4xIiwgIkJBUiIsIG15VGV4dC5nZXREZWZhdWx0Q2hhcnNldCgpKTsKCgkJSUNvbnRlbnRUeXBlW10gZm9vQmFyVHlwZXMgPSBmaW5kZXIuZmluZENvbnRlbnRUeXBlc0ZvcihjaGFuZ2VDYXNlKCJmb28uYmFyIikpOwoJCWFzc2VydEVxdWFscygiOS4wIiwgMiwgZm9vQmFyVHlwZXMubGVuZ3RoKTsKCgkJSUNvbnRlbnRUeXBlIGZvb0JhciA9IGNvbnRlbnRUeXBlTWFuYWdlci5nZXRDb250ZW50VHlwZShQSV9SRVNPVVJDRVNfVEVTVFMgKyAiLmZvb0JhciIpOwoJCWFzc2VydE5vdE51bGwoIjkuMSIsIGZvb0Jhcik7CgkJSUNvbnRlbnRUeXBlIHN1YkZvb0JhciA9IGNvbnRlbnRUeXBlTWFuYWdlci5nZXRDb250ZW50VHlwZShQSV9SRVNPVVJDRVNfVEVTVFMgKyAiLnN1YkZvb0JhciIpOwoJCWFzc2VydE5vdE51bGwoIjkuMiIsIHN1YkZvb0Jhcik7CgkJYXNzZXJ0VHJ1ZSgiOS4zIiwgY29udGFpbnMoZm9vQmFyVHlwZXMsIGZvb0JhcikpOwoJCWFzc2VydFRydWUoIjkuNCIsIGNvbnRhaW5zKGZvb0JhclR5cGVzLCBzdWJGb29CYXIpKTsKCX0KCglwdWJsaWMgdm9pZCB0ZXN0Um9vdEVsZW1lbnRBbmREVEREZXNjcmliZXIoKSB0aHJvd3MgSU9FeGNlcHRpb24gewoJCUlDb250ZW50VHlwZU1hbmFnZXIgY29udGVudFR5cGVNYW5hZ2VyID0gUGxhdGZvcm0uZ2V0Q29udGVudFR5cGVNYW5hZ2VyKCk7CgkJSUNvbnRlbnRUeXBlIHJvb3RFbGVtZW50ID0gY29udGVudFR5cGVNYW5hZ2VyLmdldENvbnRlbnRUeXBlKFBJX1JFU09VUkNFU19URVNUUyArICIucm9vdC1lbGVtZW50Iik7CgkJSUNvbnRlbnRUeXBlIGR0ZEVsZW1lbnQgPSBjb250ZW50VHlwZU1hbmFnZXIuZ2V0Q29udGVudFR5cGUoUElfUkVTT1VSQ0VTX1RFU1RTICsgIi5kdGQiKTsKCQlJQ29udGVudFR5cGUgbnNSb290RWxlbWVudCA9IGNvbnRlbnRUeXBlTWFuYWdlci5nZXRDb250ZW50VHlwZShQSV9SRVNPVVJDRVNfVEVTVFMgKyAiLm5zLXJvb3QtZWxlbWVudCIpOwoJCUlDb250ZW50VHlwZSBuc1dpbGRjYXJkID0gY29udGVudFR5cGVNYW5hZ2VyLmdldENvbnRlbnRUeXBlKFBJX1JFU09VUkNFU19URVNUUyArICIubnMtd2lsZGNhcmQiKTsKCQlJQ29udGVudFR5cGUgZW1wdHlOc1Jvb3RFbGVtZW50ID0gY29udGVudFR5cGVNYW5hZ2VyLmdldENvbnRlbnRUeXBlKFBJX1JFU09VUkNFU19URVNUUyArICIuZW1wdHktbnMtcm9vdC1lbGVtZW50Iik7CgkJSUNvbnRlbnRUeXBlIHhtbFR5cGUgPSBjb250ZW50VHlwZU1hbmFnZXIuZ2V0Q29udGVudFR5cGUoUGxhdGZvcm0uUElfUlVOVElNRSArICIueG1sIik7CgoJCUlDb250ZW50VHlwZVtdIGNvbnRlbnRUeXBlcyA9IGNvbnRlbnRUeXBlTWFuYWdlci5maW5kQ29udGVudFR5cGVzRm9yKGdldElucHV0U3RyZWFtKFhNTF9ST09UX0VMRU1FTlRfSVNPXzg4NTlfMSwgU3RhbmRhcmRDaGFyc2V0cy5JU09fODg1OV8xKSwgImZha2UueG1sIik7CgkJYXNzZXJ0VHJ1ZSgiMS4wIiwgY29udGVudFR5cGVzLmxlbmd0aCA+IDApOwoJCWFzc2VydEVxdWFscygiMS4xIiwgcm9vdEVsZW1lbnQsIGNvbnRlbnRUeXBlc1swXSk7CgoJCS8vIGJ1Z3MgNjQwNTMgYW5kIDYzMjk4CgkJY29udGVudFR5cGVzID0gY29udGVudFR5cGVNYW5hZ2VyLmZpbmRDb250ZW50VHlwZXNGb3IoZ2V0SW5wdXRTdHJlYW0oWE1MX1JPT1RfRUxFTUVOVF9FWFRFUk5BTF9FTlRJVFksIFN0YW5kYXJkQ2hhcnNldHMuVVRGXzgpLCAiZmFrZS54bWwiKTsKCQlhc3NlcnRUcnVlKCIyLjAiLCBjb250ZW50VHlwZXMubGVuZ3RoID4gMCk7CgkJYXNzZXJ0RXF1YWxzKCIyLjEiLCByb290RWxlbWVudCwgY29udGVudFR5cGVzWzBdKTsKCgkJLy8gYnVnIDYzNjI1CgkJY29udGVudFR5cGVzID0gY29udGVudFR5cGVNYW5hZ2VyLmZpbmRDb250ZW50VHlwZXNGb3IoZ2V0SW5wdXRTdHJlYW0oWE1MX1JPT1RfRUxFTUVOVF9FWFRFUk5BTF9FTlRJVFkyLCBTdGFuZGFyZENoYXJzZXRzLlVURl84KSwgImZha2UueG1sIik7CgkJYXNzZXJ0VHJ1ZSgiMy4wIiwgY29udGVudFR5cGVzLmxlbmd0aCA+IDApOwoJCWFzc2VydEVxdWFscygiMy4xIiwgcm9vdEVsZW1lbnQsIGNvbnRlbnRUeXBlc1swXSk7CgoJCS8vIGJ1ZyAxMzU1NzUKCQljb250ZW50VHlwZXMgPSBjb250ZW50VHlwZU1hbmFnZXIuZmluZENvbnRlbnRUeXBlc0ZvcihnZXRJbnB1dFN0cmVhbShYTUxfUk9PVF9FTEVNRU5UX05TX01BVENIMSwgU3RhbmRhcmRDaGFyc2V0cy5VVEZfOCksICJmYWtlLnhtbCIpOwoJCWFzc2VydFRydWUoIjQuMCIsIGNvbnRlbnRUeXBlcy5sZW5ndGggPiAwKTsKCQlhc3NlcnRFcXVhbHMoIjQuMSIsIG5zUm9vdEVsZW1lbnQsIGNvbnRlbnRUeXBlc1swXSk7CgkJY29udGVudFR5cGVzID0gY29udGVudFR5cGVNYW5hZ2VyLmZpbmRDb250ZW50VHlwZXNGb3IoZ2V0SW5wdXRTdHJlYW0oWE1MX1JPT1RfRUxFTUVOVF9OU19NQVRDSDIsIFN0YW5kYXJkQ2hhcnNldHMuVVRGXzgpLCAiZmFrZS54bWwiKTsKCQlhc3NlcnRUcnVlKCI0LjIiLCBjb250ZW50VHlwZXMubGVuZ3RoID4gMCk7CgkJYXNzZXJ0RXF1YWxzKCI0LjMiLCBuc1Jvb3RFbGVtZW50LCBjb250ZW50VHlwZXNbMF0pOwoJCWNvbnRlbnRUeXBlcyA9IGNvbnRlbnRUeXBlTWFuYWdlci5maW5kQ29udGVudFR5cGVzRm9yKGdldElucHV0U3RyZWFtKFhNTF9ST09UX0VMRU1FTlRfTlNfV1JPTkdfRUxFTSwgU3RhbmRhcmRDaGFyc2V0cy5VVEZfOCksICJmYWtlLnhtbCIpOwoJCWFzc2VydFRydWUoIjQuNCIsIGNvbnRlbnRUeXBlcy5sZW5ndGggPiAwKTsKCQlhc3NlcnRFcXVhbHMoIjQuNSIsIHhtbFR5cGUsIGNvbnRlbnRUeXBlc1swXSk7CgkJY29udGVudFR5cGVzID0gY29udGVudFR5cGVNYW5hZ2VyLmZpbmRDb250ZW50VHlwZXNGb3IoZ2V0SW5wdXRTdHJlYW0oWE1MX1JPT1RfRUxFTUVOVF9OU19XUk9OR19OUywgU3RhbmRhcmRDaGFyc2V0cy5VVEZfOCksICJmYWtlLnhtbCIpOwoJCWFzc2VydFRydWUoIjQuNiIsIGNvbnRlbnRUeXBlcy5sZW5ndGggPiAwKTsKCQlhc3NlcnRFcXVhbHMoIjQuNyIsIHhtbFR5cGUsIGNvbnRlbnRUeXBlc1swXSk7CgkJY29udGVudFR5cGVzID0gY29udGVudFR5cGVNYW5hZ2VyLmZpbmRDb250ZW50VHlwZXNGb3IoZ2V0SW5wdXRTdHJlYW0oWE1MX1JPT1RfRUxFTUVOVF9OU19NSVhVUCwgU3RhbmRhcmRDaGFyc2V0cy5VVEZfOCksICJmYWtlLnhtbCIpOwoJCWFzc2VydFRydWUoIjQuOCIsIGNvbnRlbnRUeXBlcy5sZW5ndGggPiAwKTsKCQlhc3NlcnRFcXVhbHMoIjQuOSIsIHhtbFR5cGUsIGNvbnRlbnRUeXBlc1swXSk7CgkJY29udGVudFR5cGVzID0gY29udGVudFR5cGVNYW5hZ2VyLmZpbmRDb250ZW50VHlwZXNGb3IoZ2V0SW5wdXRTdHJlYW0oWE1MX1JPT1RfRUxFTUVOVF9OU19XSUxEQ0FSRCwgU3RhbmRhcmRDaGFyc2V0cy5VVEZfOCksICJmYWtlLnhtbCIpOwoJCWFzc2VydFRydWUoIjQuMTAiLCBjb250ZW50VHlwZXMubGVuZ3RoID4gMCk7CgkJYXNzZXJ0RXF1YWxzKCI0LjExIiwgbnNXaWxkY2FyZCwgY29udGVudFR5cGVzWzBdKTsKCQljb250ZW50VHlwZXMgPSBjb250ZW50VHlwZU1hbmFnZXIuZmluZENvbnRlbnRUeXBlc0ZvcihnZXRJbnB1dFN0cmVhbShYTUxfUk9PVF9FTEVNRU5UX05TX1dJTERDQVJEMiwgU3RhbmRhcmRDaGFyc2V0cy5VVEZfOCksICJmYWtlLnhtbCIpOwoJCWFzc2VydFRydWUoIjQuMTIiLCBjb250ZW50VHlwZXMubGVuZ3RoID4gMCk7CgkJYXNzZXJ0RXF1YWxzKCI0LjEzIiwgbnNXaWxkY2FyZCwgY29udGVudFR5cGVzWzBdKTsKCQljb250ZW50VHlwZXMgPSBjb250ZW50VHlwZU1hbmFnZXIuZmluZENvbnRlbnRUeXBlc0ZvcihnZXRJbnB1dFN0cmVhbShYTUxfUk9PVF9FTEVNRU5UX0VNUFRZX05TLCBTdGFuZGFyZENoYXJzZXRzLlVURl84KSwgImZha2UueG1sIik7CgkJYXNzZXJ0VHJ1ZSgiNC4xNCIsIGNvbnRlbnRUeXBlcy5sZW5ndGggPiAwKTsKCQlhc3NlcnRFcXVhbHMoIjQuMTUiLCBlbXB0eU5zUm9vdEVsZW1lbnQsIGNvbnRlbnRUeXBlc1swXSk7CgoJCWNvbnRlbnRUeXBlcyA9IGNvbnRlbnRUeXBlTWFuYWdlci5maW5kQ29udGVudFR5cGVzRm9yKGdldElucHV0U3RyZWFtKFhNTF9EVERfVVNfQVNDSUksIFN0YW5kYXJkQ2hhcnNldHMuVVNfQVNDSUkpLCAiZmFrZS54bWwiKTsKCQlhc3NlcnRUcnVlKCI1LjAiLCBjb250ZW50VHlwZXMubGVuZ3RoID4gMCk7CgkJYXNzZXJ0RXF1YWxzKCI1LjEiLCBkdGRFbGVtZW50LCBjb250ZW50VHlwZXNbMF0pOwoJCWNvbnRlbnRUeXBlcyA9IGNvbnRlbnRUeXBlTWFuYWdlci5maW5kQ29udGVudFR5cGVzRm9yKGdldElucHV0U3RyZWFtKFhNTF9EVERfRVhURVJOQUxfRU5USVRZLCBTdGFuZGFyZENoYXJzZXRzLlVURl84KSwgImZha2UueG1sIik7CgkJYXNzZXJ0VHJ1ZSgiNS40IiwgY29udGVudFR5cGVzLmxlbmd0aCA+IDApOwoJCWFzc2VydEVxdWFscygiNS41IiwgZHRkRWxlbWVudCwgY29udGVudFR5cGVzWzBdKTsKCgkJLy8gYnVnIDY3OTc1CgkJSUNvbnRlbnREZXNjcmlwdGlvbiBkZXNjcmlwdGlvbiA9IGNvbnRlbnRUeXBlTWFuYWdlci5nZXREZXNjcmlwdGlvbkZvcihnZXRJbnB1dFN0cmVhbShuZXcgYnl0ZVtdW10ge0lDb250ZW50RGVzY3JpcHRpb24uQk9NX1VURl8xNkJFLCBYTUxfUk9PVF9FTEVNRU5UX05PX0RFQ0wuZ2V0Qnl0ZXMoIlVURi0xNkJFIil9KSwgImZha2UueG1sIiwgSUNvbnRlbnREZXNjcmlwdGlvbi5BTEwpOwoJCWFzc2VydFRydWUoIjYuMCIsIGRlc2NyaXB0aW9uICE9IG51bGwpOwoJCWFzc2VydEVxdWFscygiNi4xIiwgcm9vdEVsZW1lbnQsIGRlc2NyaXB0aW9uLmdldENvbnRlbnRUeXBlKCkpOwoJCWFzc2VydEVxdWFscygiNi4yIiwgSUNvbnRlbnREZXNjcmlwdGlvbi5CT01fVVRGXzE2QkUsIGRlc2NyaXB0aW9uLmdldFByb3BlcnR5KElDb250ZW50RGVzY3JpcHRpb24uQllURV9PUkRFUl9NQVJLKSk7CgoJCWRlc2NyaXB0aW9uID0gY29udGVudFR5cGVNYW5hZ2VyLmdldERlc2NyaXB0aW9uRm9yKGdldElucHV0U3RyZWFtKG5ldyBieXRlW11bXSB7SUNvbnRlbnREZXNjcmlwdGlvbi5CT01fVVRGXzE2TEUsIFhNTF9ST09UX0VMRU1FTlRfTk9fREVDTC5nZXRCeXRlcygiVVRGLTE2TEUiKX0pLCAiZmFrZS54bWwiLCBJQ29udGVudERlc2NyaXB0aW9uLkFMTCk7CgkJYXNzZXJ0VHJ1ZSgiNy4wIiwgZGVzY3JpcHRpb24gIT0gbnVsbCk7CgkJYXNzZXJ0RXF1YWxzKCI3LjEiLCByb290RWxlbWVudCwgZGVzY3JpcHRpb24uZ2V0Q29udGVudFR5cGUoKSk7CgkJYXNzZXJ0RXF1YWxzKCI3LjIiLCBJQ29udGVudERlc2NyaXB0aW9uLkJPTV9VVEZfMTZMRSwgZGVzY3JpcHRpb24uZ2V0UHJvcGVydHkoSUNvbnRlbnREZXNjcmlwdGlvbi5CWVRFX09SREVSX01BUkspKTsKCgkJLy8gZHVlIHRvIGJ1ZyA2NzA0OCwgdGhlIHRlc3QgYmVsb3cgZmFpbHMgd2l0aCBDcmltc29uIHBhcnNlciAoZG9lcyBub3QgaGFuZGxlIFVURi04IEJPTXMpCgkJLy8JCWRlc2NyaXB0aW9uID0gY29udGVudFR5cGVNYW5hZ2VyLmdldERlc2NyaXB0aW9uRm9yKGdldElucHV0U3RyZWFtKG5ldyBieXRlW11bXSB7SUNvbnRlbnREZXNjcmlwdGlvbi5CT01fVVRGXzgsWE1MX1JPT1RfRUxFTUVOVF9OT19ERUNMLmdldEJ5dGVzKCJVVEYtOCIpfSksICJmYWtlLnhtbCIsIElDb250ZW50RGVzY3JpcHRpb24uQUxMKTsKCQkvLwkJYXNzZXJ0VHJ1ZSgiNy4wIiwgZGVzY3JpcHRpb24gIT0gbnVsbCk7CgkJLy8JCWFzc2VydEVxdWFscygiNy4xIiwgcm9vdEVsZW1lbnQsIGRlc2NyaXB0aW9uLmdldENvbnRlbnRUeXBlKCkpOwoJCS8vCQlhc3NlcnRFcXVhbHMoIjcuMiIsIElDb250ZW50RGVzY3JpcHRpb24uQk9NX1VURl84LCBkZXNjcmlwdGlvbi5nZXRQcm9wZXJ0eShJQ29udGVudERlc2NyaXB0aW9uLkJZVEVfT1JERVJfTUFSSykpOwoKCQkvLyBidWcgODQzNTQKCQljb250ZW50VHlwZXMgPSBjb250ZW50VHlwZU1hbmFnZXIuZmluZENvbnRlbnRUeXBlc0ZvcihnZXRJbnB1dFN0cmVhbShYTUxfUk9PVF9FTEVNRU5UX05PX0RFQ0wsIFN0YW5kYXJkQ2hhcnNldHMuVVRGXzgpLCAidGVzdC50eHQiKTsKCQlhc3NlcnRUcnVlKCI4LjAiLCBjb250ZW50VHlwZXMubGVuZ3RoID4gMCk7CgkJYXNzZXJ0RXF1YWxzKCI4LjEiLCBjb250ZW50VHlwZU1hbmFnZXIuZ2V0Q29udGVudFR5cGUoSUNvbnRlbnRUeXBlTWFuYWdlci5DVF9URVhUKSwgY29udGVudFR5cGVzWzBdKTsKCX0KCgkvKioKCSAqIEJ1ZyA2Njk3NgoJICovCglwdWJsaWMgdm9pZCB0ZXN0U2lnbmF0dXJlQmV5b25kQnVmZmVyTGltaXQoKSB0aHJvd3MgSU9FeGNlcHRpb24gewoJCWludCBidWZmZXJMaW1pdCA9IENvbnRlbnRUeXBlTWFuYWdlci5CTE9DS19TSVpFICogNDsKCQkvLyBjcmVhdGUgYSBsb25nIFhNTCBjb21tZW50IGFzIHByZWZpeAoJCVN0cmluZ0J1aWxkZXIgY29tbWVudCA9IG5ldyBTdHJpbmdCdWlsZGVyKCI8IS0tIik7CgkJZm9yIChpbnQgaSA9IDA7IGkgPCBidWZmZXJMaW1pdDsgaSsrKSB7CgkJCWNvbW1lbnQuYXBwZW5kKCcqJyk7CgkJfQoJCWNvbW1lbnQuYXBwZW5kKCItLT4iKTsKCQlJQ29udGVudFR5cGVNYW5hZ2VyIG1hbmFnZXIgPSBQbGF0Zm9ybS5nZXRDb250ZW50VHlwZU1hbmFnZXIoKTsKCQlJQ29udGVudFR5cGUgcm9vdEVsZW1lbnQgPSBtYW5hZ2VyLmdldENvbnRlbnRUeXBlKFBJX1JFU09VUkNFU19URVNUUyArICIucm9vdC1lbGVtZW50Iik7CgkJSUNvbnRlbnRUeXBlIHNlbGVjdGVkID0gbWFuYWdlci5maW5kQ29udGVudFR5cGVGb3IoZ2V0SW5wdXRTdHJlYW0oY29tbWVudCArIFhNTF9ST09UX0VMRU1FTlRfTk9fREVDTCwgU3RhbmRhcmRDaGFyc2V0cy5VU19BU0NJSSksICJmYWtlLnhtbCIpOwoJCWFzc2VydE5vdE51bGwoIjEuMCIsIHNlbGVjdGVkKTsKCQlhc3NlcnRFcXVhbHMoIjEuMSIsIHJvb3RFbGVtZW50LCBzZWxlY3RlZCk7Cgl9CgoJLyoqCgkgKiBTZWUgYWxzbzogYnVnIDcyNzk2LgoJICovCglwdWJsaWMgdm9pZCB0ZXN0VXNlckRlZmluZWRBc3NvY2lhdGlvbnMoKSB7CgkJSUNvbnRlbnRUeXBlTWFuYWdlciBtYW5hZ2VyID0gUGxhdGZvcm0uZ2V0Q29udGVudFR5cGVNYW5hZ2VyKCk7CgkJSUNvbnRlbnRUeXBlIHRleHQgPSBtYW5hZ2VyLmdldENvbnRlbnRUeXBlKChQbGF0Zm9ybS5QSV9SVU5USU1FICsgIi50ZXh0IikpOwoKCQlhc3NlcnROdWxsKCIwLjEiLCBtYW5hZ2VyLmZpbmRDb250ZW50VHlwZUZvcigidGVzdC5teXRleHQiKSk7CgkJLy8gYXNzb2NpYXRlIGEgdXNlci1kZWZpbmVkIGZpbGUgc3BlYwoJCXRyeSB7CgkJCXRleHQuYWRkRmlsZVNwZWMoIm15dGV4dCIsIElDb250ZW50VHlwZS5GSUxFX0VYVEVOU0lPTl9TUEVDKTsKCQl9IGNhdGNoIChDb3JlRXhjZXB0aW9uIGUpIHsKCQkJZmFpbCgiMS4wIiwgZSk7CgkJfQoJCWJvb2xlYW4gYXNzZXJ0aW9uRmFpbGVkID0gZmFsc2U7CgkJdHJ5IHsKCQkJSUNvbnRlbnRUeXBlIHJlc3VsdCA9IG1hbmFnZXIuZmluZENvbnRlbnRUeXBlRm9yKCJ0ZXN0Lm15dGV4dCIpOwoJCQlhc3NlcnROb3ROdWxsKCIxLjEiLCByZXN1bHQpOwoJCQlhc3NlcnRFcXVhbHMoIjEuMiIsIHRleHQsIHJlc3VsdCk7CgkJfSBjYXRjaCAoQXNzZXJ0aW9uRmFpbGVkRXJyb3IgYWZlKSB7CgkJCWFzc2VydGlvbkZhaWxlZCA9IHRydWU7CgkJCXRocm93IGFmZTsKCQl9IGZpbmFsbHkgewoJCQl0cnkgewoJCQkJdGV4dC5yZW1vdmVGaWxlU3BlYygibXl0ZXh0IiwgSUNvbnRlbnRUeXBlLkZJTEVfRVhURU5TSU9OX1NQRUMpOwoJCQl9IGNhdGNoIChDb3JlRXhjZXB0aW9uIGUpIHsKCQkJCWlmICghYXNzZXJ0aW9uRmFpbGVkKSB7CgkJCQkJZmFpbCgiIDIuMCIsIGUpOwoJCQkJfQoJCQl9CgkJfQoJCUlDb250ZW50VHlwZSByZXN1bHQgPSBtYW5hZ2VyLmZpbmRDb250ZW50VHlwZUZvcigidGVzdC5teXRleHQiKTsKCQlhc3NlcnROdWxsKCIzLjAiLCByZXN1bHQpOwoJfQoKCXB1YmxpYyB2b2lkIHRlc3REZXNjcmliZXJJbnZhbGlkYXRpb24oKSB0aHJvd3MgSU9FeGNlcHRpb24gewoJCUlDb250ZW50VHlwZU1hbmFnZXIgY29udGVudFR5cGVNYW5hZ2VyID0gUGxhdGZvcm0uZ2V0Q29udGVudFR5cGVNYW5hZ2VyKCk7CgkJSUNvbnRlbnRUeXBlIHR5cGVfYnVnMTgyMzM3X0EgPSBjb250ZW50VHlwZU1hbmFnZXIuZ2V0Q29udGVudFR5cGUoUElfUkVTT1VSQ0VTX1RFU1RTICsgIi5CdWcxODIzMzdfQSIpOwoJCUlDb250ZW50VHlwZSB0eXBlX2J1ZzE4MjMzN19CID0gY29udGVudFR5cGVNYW5hZ2VyLmdldENvbnRlbnRUeXBlKFBJX1JFU09VUkNFU19URVNUUyArICIuQnVnMTgyMzM3X0IiKTsKCgkJSUNvbnRlbnRUeXBlW10gY29udGVudFR5cGVzID0gY29udGVudFR5cGVNYW5hZ2VyLmZpbmRDb250ZW50VHlwZXNGb3IoZ2V0SW5wdXRTdHJlYW0oWE1MX1JPT1RfRUxFTUVOVF9OU19NQVRDSDIsIFN0YW5kYXJkQ2hhcnNldHMuVVRGXzgpLCAiQnVnMTgyMzM3LkJ1ZzE4MjMzNyIpOwoJCWFzc2VydFRydWUoIjEuMCIsIGNvbnRlbnRUeXBlcy5sZW5ndGggPT0gMik7CgkJYXNzZXJ0RXF1YWxzKCIxLjEiLCB0eXBlX2J1ZzE4MjMzN19BLCBjb250ZW50VHlwZXNbMF0pOwoJCWFzc2VydEVxdWFscygiMS4xIiwgdHlwZV9idWcxODIzMzdfQiwgY29udGVudFR5cGVzWzFdKTsKCgkJSW5wdXRTdHJlYW0gaXMgPSBuZXcgSW5wdXRTdHJlYW0oKSB7CgkJCUBPdmVycmlkZQoJCQlwdWJsaWMgaW50IHJlYWQoKSB7CgkJCQkvLyB0aHJvdyBhIG5vbiBjaGVja2VkIGV4Y2VwdGlvbiB0byBlbXVsYXRlIGEgcHJvYmxlbSB3aXRoIHRoZSBkZXNjcmliZXIgaXRzZWxmCgkJCQl0aHJvdyBuZXcgUnVudGltZUV4Y2VwdGlvbigpOwoJCQl9CgkJfTsKCQljb250ZW50VHlwZXMgPSBjb250ZW50VHlwZU1hbmFnZXIuZmluZENvbnRlbnRUeXBlc0ZvcihpcywgIkJ1ZzE4MjMzNy5CdWcxODIzMzciKTsKCQlhc3NlcnRUcnVlKCIxLjIiLCBjb250ZW50VHlwZXMubGVuZ3RoID09IDApOwoKCQkvLyBEZXNjcmliZXIgc2hvdWxkIGJlIGludmFsaWRhdGVkIGJ5IG5vdwoJCWNvbnRlbnRUeXBlcyA9IGNvbnRlbnRUeXBlTWFuYWdlci5maW5kQ29udGVudFR5cGVzRm9yKGdldElucHV0U3RyZWFtKFhNTF9ST09UX0VMRU1FTlRfTlNfTUFUQ0gyLCBTdGFuZGFyZENoYXJzZXRzLlVURl84KSwgIkJ1ZzE4MjMzNy5CdWcxODIzMzciKTsKCQlhc3NlcnRUcnVlKCIxLjMiLCBjb250ZW50VHlwZXMubGVuZ3RoID09IDApOwoJfQoKfQo=