LyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogQ29weXJpZ2h0IChjKSAyMDA0LCAyMDE3IElCTSBDb3Jwb3JhdGlvbiBhbmQgb3RoZXJzLgogKiBBbGwgcmlnaHRzIHJlc2VydmVkLiBUaGlzIHByb2dyYW0gYW5kIHRoZSBhY2NvbXBhbnlpbmcgbWF0ZXJpYWxzCiAqIGFyZSBtYWRlIGF2YWlsYWJsZSB1bmRlciB0aGUgdGVybXMgb2YgdGhlIEVjbGlwc2UgUHVibGljIExpY2Vuc2UgdjEuMAogKiB3aGljaCBhY2NvbXBhbmllcyB0aGlzIGRpc3RyaWJ1dGlvbiwgYW5kIGlzIGF2YWlsYWJsZSBhdAogKiBodHRwOi8vd3d3LmVjbGlwc2Uub3JnL2xlZ2FsL2VwbC12MTAuaHRtbAogKgogKiBDb250cmlidXRvcnM6CiAqICAgICBJQk0gQ29ycG9yYXRpb24gLSBpbml0aWFsIEFQSSBhbmQgaW1wbGVtZW50YXRpb24KICogICAgIE1pY2thZWwgSXN0cmlhIChSZWQgSGF0IEluYy4pIC0gWzI2MzMxNl0gcmVnZXhwIGZvciBmaWxlIGFzc29jaWF0aW9uCiAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwpwYWNrYWdlIG9yZy5lY2xpcHNlLmNvcmUudGVzdHMucmVzb3VyY2VzLmNvbnRlbnQ7CgppbXBvcnQgamF2YS5pby4qOwppbXBvcnQgamF2YS5uaW8uY2hhcnNldC5TdGFuZGFyZENoYXJzZXRzOwppbXBvcnQgamF2YS51dGlsLkhhc2hTZXQ7CmltcG9ydCBqYXZhLnV0aWwuU2V0OwppbXBvcnQganVuaXQuZnJhbWV3b3JrLkFzc2VydGlvbkZhaWxlZEVycm9yOwppbXBvcnQganVuaXQuZnJhbWV3b3JrLlRlc3Q7CmltcG9ydCBvcmcuZWNsaXBzZS5jb3JlLmludGVybmFsLmNvbnRlbnQuKjsKaW1wb3J0IG9yZy5lY2xpcHNlLmNvcmUucnVudGltZS4qOwppbXBvcnQgb3JnLmVjbGlwc2UuY29yZS5ydW50aW1lLmNvbnRlbnQuKjsKaW1wb3J0IG9yZy5lY2xpcHNlLmNvcmUucnVudGltZS5jb250ZW50LklDb250ZW50VHlwZU1hbmFnZXIuQ29udGVudFR5cGVDaGFuZ2VFdmVudDsKaW1wb3J0IG9yZy5lY2xpcHNlLmNvcmUucnVudGltZS5jb250ZW50LlhNTENvbnRlbnREZXNjcmliZXI7CmltcG9ydCBvcmcuZWNsaXBzZS5jb3JlLnJ1bnRpbWUuam9icy5Kb2I7CmltcG9ydCBvcmcuZWNsaXBzZS5jb3JlLnJ1bnRpbWUucHJlZmVyZW5jZXMuKjsKaW1wb3J0IG9yZy5lY2xpcHNlLmNvcmUudGVzdHMuaGFybmVzcy5CdW5kbGVUZXN0aW5nSGVscGVyOwppbXBvcnQgb3JnLmVjbGlwc2UuY29yZS50ZXN0cy5oYXJuZXNzLlRlc3RSZWdpc3RyeUNoYW5nZUxpc3RlbmVyOwppbXBvcnQgb3JnLmVjbGlwc2UudGVzdC5PcmRlcmVkVGVzdFN1aXRlOwppbXBvcnQgb3JnLm9zZ2kuc2VydmljZS5wcmVmcy5CYWNraW5nU3RvcmVFeGNlcHRpb247CmltcG9ydCBvcmcub3NnaS5zZXJ2aWNlLnByZWZzLlByZWZlcmVuY2VzOwoKcHVibGljIGNsYXNzIElDb250ZW50VHlwZU1hbmFnZXJUZXN0IGV4dGVuZHMgQ29udGVudFR5cGVUZXN0IHsKCglwcml2YXRlIHN0YXRpYyBjbGFzcyBDb250ZW50VHlwZUNoYW5nZVRyYWNlciBpbXBsZW1lbnRzIElDb250ZW50VHlwZU1hbmFnZXIuSUNvbnRlbnRUeXBlQ2hhbmdlTGlzdGVuZXIgewoJCXByaXZhdGUgZmluYWwgU2V0PElDb250ZW50VHlwZT4gY2hhbmdlZCA9IG5ldyBIYXNoU2V0PD4oKTsKCgkJcHVibGljIENvbnRlbnRUeXBlQ2hhbmdlVHJhY2VyKCkgewoJCX0KCgkJQE92ZXJyaWRlCgkJcHVibGljIHZvaWQgY29udGVudFR5cGVDaGFuZ2VkKENvbnRlbnRUeXBlQ2hhbmdlRXZlbnQgZXZlbnQpIHsKCQkJY2hhbmdlZC5hZGQoZXZlbnQuZ2V0Q29udGVudFR5cGUoKSk7CgkJfQoKCQlwdWJsaWMgYm9vbGVhbiBpc09ubHlDaGFuZ2UoSUNvbnRlbnRUeXBlIG15VHlwZSkgewoJCQlyZXR1cm4gY2hhbmdlZC5zaXplKCkgPT0gMSAmJiBjaGFuZ2VkLmNvbnRhaW5zKG15VHlwZSk7CgkJfQoKCQlwdWJsaWMgdm9pZCByZXNldCgpIHsKCQkJY2hhbmdlZC5jbGVhcigpOwoJCX0KCX0KCgkvLyBYWFggdGhpcyBpcyBjb3BpZWQgZnJvbSBDaGFyc2V0RGVsdGFKb2IgaW4gdGhlIHJlc291cmNlcyBwbHVnLWluCglwcml2YXRlIHN0YXRpYyBmaW5hbCBTdHJpbmcgRkFNSUxZX0NIQVJTRVRfREVMVEEgPSAib3JnLmVjbGlwc2UuY29yZS5yZXNvdXJjZXMuY2hhcnNldEpvYkZhbWlseSI7CgoJcHJpdmF0ZSBmaW5hbCBzdGF0aWMgU3RyaW5nIE1JTklNQUxfWE1MID0gIjw/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+PCFET0NUWVBFIEpva2VyIFNZU1RFTSBcIm9yZy5lY2xpcHNlLmNvcmUucmVzb3VyY2VzLnRlc3RzLnNvbWUuZHRkM1wiPjxyb290RWxlbWVudD4iOwoKCXB1YmxpYyBzdGF0aWMgVGVzdCBzdWl0ZSgpIHsKCQlyZXR1cm4gbmV3IE9yZGVyZWRUZXN0U3VpdGUoSUNvbnRlbnRUeXBlTWFuYWdlclRlc3QuY2xhc3MpOwoJfQoKCXB1YmxpYyBJQ29udGVudFR5cGVNYW5hZ2VyVGVzdChTdHJpbmcgbmFtZSkgewoJCXN1cGVyKG5hbWUpOwoJfQoKCS8qKgoJICogSGVscHMgdG8gZW5zdXJlIHdlIGRvbid0IGdldCBmb29sZWQgYnkgY2FzZSBzZW5zaXRpdml0eSBpbiBmaWxlIG5hbWVzL3NwZWNzLgoJICovCglwcml2YXRlIFN0cmluZyBjaGFuZ2VDYXNlKFN0cmluZyBvcmlnaW5hbCkgewoJCVN0cmluZ0J1aWxkZXIgcmVzdWx0ID0gbmV3IFN0cmluZ0J1aWxkZXIob3JpZ2luYWwpOwoJCWZvciAoaW50IGkgPSByZXN1bHQubGVuZ3RoKCkgLSAxOyBpID49IDA7IGktLSkgewoJCQljaGFyIG9yaWdpbmFsQ2hhciA9IG9yaWdpbmFsLmNoYXJBdChpKTsKCQkJcmVzdWx0LnNldENoYXJBdChpLCBpICUgMiA9PSAwID8gQ2hhcmFjdGVyLnRvTG93ZXJDYXNlKG9yaWdpbmFsQ2hhcikgOiBDaGFyYWN0ZXIudG9VcHBlckNhc2Uob3JpZ2luYWxDaGFyKSk7CgkJfQoJCXJldHVybiByZXN1bHQudG9TdHJpbmcoKTsKCX0KCglib29sZWFuIGNvbnRhaW5zKE9iamVjdFtdIGFycmF5LCBPYmplY3QgZWxlbWVudCkgewoJCWZvciAoT2JqZWN0IGVsZW1lbnQyIDogYXJyYXkpIHsKCQkJaWYgKGVsZW1lbnQyLmVxdWFscyhlbGVtZW50KSkgewoJCQkJcmV0dXJuIHRydWU7CgkJCX0KCQl9CgkJcmV0dXJuIGZhbHNlOwoJfQoKCXByaXZhdGUgSUNvbnRlbnREZXNjcmlwdGlvbiBnZXREZXNjcmlwdGlvbkZvcihJQ29udGVudFR5cGVNYXRjaGVyIGZpbmRlciwgU3RyaW5nIGNvbnRlbnRzLCBTdHJpbmcgZW5jb2RpbmcsIFN0cmluZyBmaWxlTmFtZSwgUXVhbGlmaWVkTmFtZVtdIG9wdGlvbnMsIGJvb2xlYW4gdGV4dCkgdGhyb3dzIFVuc3VwcG9ydGVkRW5jb2RpbmdFeGNlcHRpb24sIElPRXhjZXB0aW9uIHsKCQlyZXR1cm4gdGV4dCA/IGZpbmRlci5nZXREZXNjcmlwdGlvbkZvcihnZXRSZWFkZXIoY29udGVudHMpLCBmaWxlTmFtZSwgb3B0aW9ucykgOiBmaW5kZXIuZ2V0RGVzY3JpcHRpb25Gb3IoZ2V0SW5wdXRTdHJlYW0oY29udGVudHMsIGVuY29kaW5nKSwgZmlsZU5hbWUsIG9wdGlvbnMpOwoJfQoKCXB1YmxpYyBJbnB1dFN0cmVhbSBnZXRJbnB1dFN0cmVhbShieXRlW11bXSBjb250ZW50cykgewoJCWludCBzaXplID0gMDsKCQkvLyBjb21wdXRlcyBmaW5hbCBhcnJheSBzaXplCgkJZm9yIChieXRlW10gY29udGVudCA6IGNvbnRlbnRzKSB7CgkJCXNpemUgKz0gY29udGVudC5sZW5ndGg7CgkJfQoJCWJ5dGVbXSBmdWxsID0gbmV3IGJ5dGVbc2l6ZV07CgkJaW50IGZ1bGxJbmRleCA9IDA7CgkJLy8gY29uY2F0ZW5hdGVzIGFsbCBieXRlIGFycmF5cwoJCWZvciAoYnl0ZVtdIGNvbnRlbnQgOiBjb250ZW50cykgewoJCQlmb3IgKGJ5dGUgZWxlbWVudCA6IGNvbnRlbnQpIHsKCQkJCWZ1bGxbZnVsbEluZGV4KytdID0gZWxlbWVudDsKCQkJfQoJCX0KCQlyZXR1cm4gbmV3IEJ5dGVBcnJheUlucHV0U3RyZWFtKGZ1bGwpOwoJfQoKCXB1YmxpYyBJbnB1dFN0cmVhbSBnZXRJbnB1dFN0cmVhbShTdHJpbmcgY29udGVudHMpIHsKCQlyZXR1cm4gbmV3IEJ5dGVBcnJheUlucHV0U3RyZWFtKGNvbnRlbnRzLmdldEJ5dGVzKCkpOwoJfQoKCXB1YmxpYyBJbnB1dFN0cmVhbSBnZXRJbnB1dFN0cmVhbShTdHJpbmcgY29udGVudHMsIFN0cmluZyBlbmNvZGluZykgdGhyb3dzIFVuc3VwcG9ydGVkRW5jb2RpbmdFeGNlcHRpb24gewoJCXJldHVybiBuZXcgQnl0ZUFycmF5SW5wdXRTdHJlYW0oZW5jb2RpbmcgPT0gbnVsbCA/IGNvbnRlbnRzLmdldEJ5dGVzKCkgOiBjb250ZW50cy5nZXRCeXRlcyhlbmNvZGluZykpOwoJfQoKCXB1YmxpYyBSZWFkZXIgZ2V0UmVhZGVyKFN0cmluZyBjb250ZW50cykgewoJCXJldHVybiBuZXcgQ2hhckFycmF5UmVhZGVyKGNvbnRlbnRzLnRvQ2hhckFycmF5KCkpOwoJfQoKCXByaXZhdGUgYm9vbGVhbiBpc1RleHQoSUNvbnRlbnRUeXBlTWFuYWdlciBtYW5hZ2VyLCBJQ29udGVudFR5cGUgY2FuZGlkYXRlKSB7CgkJSUNvbnRlbnRUeXBlIHRleHQgPSBtYW5hZ2VyLmdldENvbnRlbnRUeXBlKElDb250ZW50VHlwZU1hbmFnZXIuQ1RfVEVYVCk7CgkJcmV0dXJuIGNhbmRpZGF0ZS5pc0tpbmRPZih0ZXh0KTsKCX0KCglAT3ZlcnJpZGUKCXByb3RlY3RlZCB2b2lkIHRlYXJEb3duKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CgkJc3VwZXIudGVhckRvd24oKTsKCQkvLyBzb21lIHRlc3RzIGhlcmUgd2lsbCB0cmlnZ2VyIGEgY2hhcnNldCBkZWx0YSBqb2IgKGFueSBjYXVzaW5nIENvbnRlbnRUeXBlQ2hhbmdlRXZlbnRzIHRvIGJlIGJyb2FkY2FzdCkKCQkvLyBlbnN1cmUgbm9uZSBpcyBsZWZ0IHJ1bm5pbmcgYWZ0ZXIgd2UgZmluaXNoCgkJSm9iLmdldEpvYk1hbmFnZXIoKS5qb2luKEZBTUlMWV9DSEFSU0VUX0RFTFRBLCBnZXRNb25pdG9yKCkpOwoJfQoKCS8qKgoJICogVGhpcyB0ZXN0IHNob3dzIGhvdyB3ZSBkZWFsIHdpdGggYWxpYXNlcy4KCSAqLwoJcHVibGljIHZvaWQgdGVzdEFsaWFzKCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKCQlmaW5hbCBJQ29udGVudFR5cGVNYW5hZ2VyIGNvbnRlbnRUeXBlTWFuYWdlciA9IFBsYXRmb3JtLmdldENvbnRlbnRUeXBlTWFuYWdlcigpOwoJCUlDb250ZW50VHlwZSBhbGlhcyA9IGNvbnRlbnRUeXBlTWFuYWdlci5nZXRDb250ZW50VHlwZShQSV9SRVNPVVJDRVNfVEVTVFMgKyAiLmFsaWFzIik7CgkJYXNzZXJ0Tm90TnVsbCgiMC43IiwgYWxpYXMpOwoJCUlDb250ZW50VHlwZSBkZXJpdmVkID0gY29udGVudFR5cGVNYW5hZ2VyLmdldENvbnRlbnRUeXBlKFBJX1JFU09VUkNFU19URVNUUyArICIuZGVyaXZlZC1mcm9tLWFsaWFzIik7CgkJYXNzZXJ0Tm90TnVsbCgiMC44IiwgZGVyaXZlZCk7CgkJSUNvbnRlbnRUeXBlIHRhcmdldCA9IGNvbnRlbnRUeXBlTWFuYWdlci5nZXRDb250ZW50VHlwZSgib3JnLmVjbGlwc2UuYnVuZGxlMDIubWlzc2luZy10YXJnZXQiKTsKCQlhc3NlcnROdWxsKCIwLjkiLCB0YXJnZXQpOwoJCUlDb250ZW50VHlwZVtdIHNlbGVjdGVkOwoJCXNlbGVjdGVkID0gY29udGVudFR5cGVNYW5hZ2VyLmZpbmRDb250ZW50VHlwZXNGb3IoImZvby5taXNzaW5nLXRhcmdldCIpOwoJCWFzc2VydEVxdWFscygiMS4xIiwgMiwgc2VsZWN0ZWQubGVuZ3RoKTsKCQlhc3NlcnRFcXVhbHMoIjEuMiIsIGFsaWFzLCBzZWxlY3RlZFswXSk7CgkJYXNzZXJ0RXF1YWxzKCIxLjMiLCBkZXJpdmVkLCBzZWxlY3RlZFsxXSk7CgkJc2VsZWN0ZWQgPSBjb250ZW50VHlwZU1hbmFnZXIuZmluZENvbnRlbnRUeXBlc0ZvcihnZXRSYW5kb21Db250ZW50cygpLCAiZm9vLm1pc3NpbmctdGFyZ2V0Iik7CgkJYXNzZXJ0RXF1YWxzKCIxLjQiLCAyLCBzZWxlY3RlZC5sZW5ndGgpOwoJCWFzc2VydEVxdWFscygiMS41IiwgYWxpYXMsIHNlbGVjdGVkWzBdKTsKCQlhc3NlcnRFcXVhbHMoIjEuNiIsIGRlcml2ZWQsIHNlbGVjdGVkWzFdKTsKCgkJLy90ZXN0IGxhdGUgYWRkaXRpb24gb2YgY29udGVudCB0eXBlCgkJVGVzdFJlZ2lzdHJ5Q2hhbmdlTGlzdGVuZXIgbGlzdGVuZXIgPSBuZXcgVGVzdFJlZ2lzdHJ5Q2hhbmdlTGlzdGVuZXIoUGxhdGZvcm0uUElfUlVOVElNRSwgQ29udGVudFR5cGVCdWlsZGVyLlBUX0NPTlRFTlRUWVBFUywgbnVsbCwgbnVsbCk7CgkJQnVuZGxlVGVzdGluZ0hlbHBlci5ydW5XaXRoQnVuZGxlcygiMiIsICgpIC0+IHsKCQkJSUNvbnRlbnRUeXBlIGFsaWFzMSA9IGNvbnRlbnRUeXBlTWFuYWdlci5nZXRDb250ZW50VHlwZShQSV9SRVNPVVJDRVNfVEVTVFMgKyAiLmFsaWFzIik7CgkJCWFzc2VydE51bGwoIjIuMS4xIiwgYWxpYXMxKTsKCQkJSUNvbnRlbnRUeXBlIGRlcml2ZWQxID0gY29udGVudFR5cGVNYW5hZ2VyLmdldENvbnRlbnRUeXBlKFBJX1JFU09VUkNFU19URVNUUyArICIuZGVyaXZlZC1mcm9tLWFsaWFzIik7CgkJCWFzc2VydE5vdE51bGwoIjIuMS4yIiwgZGVyaXZlZDEpOwoJCQlJQ29udGVudFR5cGUgdGFyZ2V0MSA9IGNvbnRlbnRUeXBlTWFuYWdlci5nZXRDb250ZW50VHlwZSgib3JnLmVjbGlwc2UuYnVuZGxlMDIubWlzc2luZy10YXJnZXQiKTsKCQkJYXNzZXJ0Tm90TnVsbCgiMi4xLjMiLCB0YXJnZXQxKTsKCQkJLy8gY2hlY2tzIGFzc29jaWF0aW9ucwoJCQlJQ29udGVudFR5cGVbXSBzZWxlY3RlZDEgPSBjb250ZW50VHlwZU1hbmFnZXIuZmluZENvbnRlbnRUeXBlc0ZvcigiZm9vLm1pc3NpbmctdGFyZ2V0Iik7CgkJCWFzc2VydEVxdWFscygiMi4yLjEiLCAyLCBzZWxlY3RlZDEubGVuZ3RoKTsKCQkJYXNzZXJ0RXF1YWxzKCIyLjIuMiIsIHRhcmdldDEsIHNlbGVjdGVkMVswXSk7CgkJCWFzc2VydEVxdWFscygiMi4yLjMiLCBkZXJpdmVkMSwgc2VsZWN0ZWQxWzFdKTsKCQkJdHJ5IHsKCQkJCXNlbGVjdGVkMSA9IGNvbnRlbnRUeXBlTWFuYWdlci5maW5kQ29udGVudFR5cGVzRm9yKGdldFJhbmRvbUNvbnRlbnRzKCksICJmb28ubWlzc2luZy10YXJnZXQiKTsKCQkJfSBjYXRjaCAoSU9FeGNlcHRpb24gZSkgewoJCQkJZmFpbCgiMi4yLjQiLCBlKTsKCQkJfQoJCQlhc3NlcnRFcXVhbHMoIjIuMi41IiwgMiwgc2VsZWN0ZWQxLmxlbmd0aCk7CgkJCWFzc2VydEVxdWFscygiMi4yLjYiLCB0YXJnZXQxLCBzZWxlY3RlZDFbMF0pOwoJCQlhc3NlcnRFcXVhbHMoIjIuMi43IiwgZGVyaXZlZDEsIHNlbGVjdGVkMVsxXSk7CgkJfSwgZ2V0Q29udGV4dCgpLCBuZXcgU3RyaW5nW10ge0NvbnRlbnRUeXBlVGVzdC5URVNUX0ZJTEVTX1JPT1QgKyAiY29udGVudC9idW5kbGUwMiJ9LCBsaXN0ZW5lcik7Cgl9CgoJcHVibGljIHZvaWQgdGVzdEFzc29jaWF0aW9uSW5oZXJpdGFuY2UoKSB0aHJvd3MgQ29yZUV4Y2VwdGlvbiB7CgkJSUNvbnRlbnRUeXBlTWFuYWdlciBtYW5hZ2VyID0gUGxhdGZvcm0uZ2V0Q29udGVudFR5cGVNYW5hZ2VyKCk7CgkJSUNvbnRlbnRUeXBlTWF0Y2hlciBmaW5kZXIgPSBtYW5hZ2VyLmdldE1hdGNoZXIobmV3IExvY2FsU2VsZWN0aW9uUG9saWN5KCksIG51bGwpOwoJCUlDb250ZW50VHlwZSB0ZXh0ID0gbWFuYWdlci5nZXRDb250ZW50VHlwZShQbGF0Zm9ybS5QSV9SVU5USU1FICsgIi50ZXh0Iik7CgkJSUNvbnRlbnRUeXBlIGFzc29jMSA9IG1hbmFnZXIuZ2V0Q29udGVudFR5cGUoUElfUkVTT1VSQ0VTX1RFU1RTICsgIi5hc3NvYzEiKTsKCQlJQ29udGVudFR5cGUgYXNzb2MyID0gbWFuYWdlci5nZXRDb250ZW50VHlwZShQSV9SRVNPVVJDRVNfVEVTVFMgKyAiLmFzc29jMiIpOwoKCQkvLyBhc3NvY2lhdGUgYSB1c2VyLWRlZmluZWQgZmlsZSBzcGVjCgkJdGV4dC5hZGRGaWxlU3BlYygidHh0X3VzZXJhZGRlZCIsIElDb250ZW50VHlwZS5GSUxFX0VYVEVOU0lPTl9TUEVDKTsKCQlhc3NvYzEuYWRkRmlsZVNwZWMoInR4dF9hc3NvYzF1c2VyYWRkZWQiLCBJQ29udGVudFR5cGUuRklMRV9FWFRFTlNJT05fU1BFQyk7CgkJYXNzb2MyLmFkZEZpbGVTcGVjKCJ0eHRfYXNzb2MydXNlcmFkZGVkIiwgSUNvbnRlbnRUeXBlLkZJTEVfRVhURU5TSU9OX1NQRUMpOwoKCQkvLyB0ZXN0IGFzc29jaWF0aW9ucwoJCWFzc2VydFRydWUoIjEuMSIsIGFzc29jMS5pc0Fzc29jaWF0ZWRXaXRoKGNoYW5nZUNhc2UoInRleHQudHh0IikpKTsKCQlhc3NlcnRUcnVlKCIxLjIiLCBhc3NvYzEuaXNBc3NvY2lhdGVkV2l0aChjaGFuZ2VDYXNlKCJ0ZXh0LnR4dF91c2VyYWRkZWQiKSkpOwoJCWFzc2VydFRydWUoIjEuMyIsIGFzc29jMS5pc0Fzc29jaWF0ZWRXaXRoKGNoYW5nZUNhc2UoInRleHQudHh0X3BsdWdpbmFkZGVkIikpKTsKCQlhc3NlcnRUcnVlKCIxLjQiLCBhc3NvYzEuaXNBc3NvY2lhdGVkV2l0aChjaGFuZ2VDYXNlKCJ0ZXh0LnR4dF9hc3NvYzFwbHVnaW5hZGRlZCIpKSk7CgkJYXNzZXJ0VHJ1ZSgiMS41IiwgYXNzb2MxLmlzQXNzb2NpYXRlZFdpdGgoY2hhbmdlQ2FzZSgidGV4dC50eHRfYXNzb2MxdXNlcmFkZGVkIikpKTsKCgkJYXNzZXJ0VHJ1ZSgiMi4xIiwgIWFzc29jMi5pc0Fzc29jaWF0ZWRXaXRoKGNoYW5nZUNhc2UoInRleHQudHh0IikpKTsKCQlhc3NlcnRUcnVlKCIyLjIiLCAhYXNzb2MyLmlzQXNzb2NpYXRlZFdpdGgoY2hhbmdlQ2FzZSgidGV4dC50eHRfdXNlcmFkZGVkIikpKTsKCQlhc3NlcnRUcnVlKCIyLjMiLCAhYXNzb2MyLmlzQXNzb2NpYXRlZFdpdGgoY2hhbmdlQ2FzZSgidGV4dC50eHRfcGx1Z2luYWRkZWQiKSkpOwoJCWFzc2VydFRydWUoIjIuNCIsIGFzc29jMi5pc0Fzc29jaWF0ZWRXaXRoKGNoYW5nZUNhc2UoInRleHQudHh0X2Fzc29jMnBsdWdpbmFkZGVkIikpKTsKCQlhc3NlcnRUcnVlKCIyLjUiLCBhc3NvYzIuaXNBc3NvY2lhdGVkV2l0aChjaGFuZ2VDYXNlKCJ0ZXh0LnR4dF9hc3NvYzJidWlsdGluIikpKTsKCQlhc3NlcnRUcnVlKCIyLjYiLCBhc3NvYzIuaXNBc3NvY2lhdGVkV2l0aChjaGFuZ2VDYXNlKCJ0ZXh0LnR4dF9hc3NvYzJ1c2VyYWRkZWQiKSkpOwoKCQlJQ29udGVudFR5cGVbXSBzZWxlY3RlZDsKCQkvLyB0ZXh0IGJ1aWx0LWluIGFzc29jaWF0aW9ucwoJCXNlbGVjdGVkID0gZmluZGVyLmZpbmRDb250ZW50VHlwZXNGb3IoY2hhbmdlQ2FzZSgidGV4dC50eHQiKSk7CgkJYXNzZXJ0RXF1YWxzKCIzLjAiLCAyLCBzZWxlY3RlZC5sZW5ndGgpOwoJCWFzc2VydEVxdWFscygiMy4xIiwgYXNzb2MxLCBzZWxlY3RlZFsxXSk7CgkJYXNzZXJ0RXF1YWxzKCIzLjIiLCB0ZXh0LCBzZWxlY3RlZFswXSk7CgoJCS8vIHRleHQgdXNlci1hZGRlZCBhc3NvY2lhdGlvbnMKCQlzZWxlY3RlZCA9IGZpbmRlci5maW5kQ29udGVudFR5cGVzRm9yKGNoYW5nZUNhc2UoInRleHQudHh0X3VzZXJhZGRlZCIpKTsKCQlhc3NlcnRFcXVhbHMoIjQuMCIsIDIsIHNlbGVjdGVkLmxlbmd0aCk7CgkJYXNzZXJ0RXF1YWxzKCI0LjEiLCBhc3NvYzEsIHNlbGVjdGVkWzFdKTsKCQlhc3NlcnRFcXVhbHMoIjQuMiIsIHRleHQsIHNlbGVjdGVkWzBdKTsKCgkJLy8gdGV4dCBwcm92aWRlci1hZGRlZCBhc3NvY2lhdGlvbnMKCQlzZWxlY3RlZCA9IGZpbmRlci5maW5kQ29udGVudFR5cGVzRm9yKGNoYW5nZUNhc2UoInRleHQudHh0X3BsdWdpbmFkZGVkIikpOwoJCWFzc2VydEVxdWFscygiNS4wIiwgMiwgc2VsZWN0ZWQubGVuZ3RoKTsKCQlhc3NlcnRFcXVhbHMoIjUuMSIsIGFzc29jMSwgc2VsZWN0ZWRbMV0pOwoJCWFzc2VydEVxdWFscygiNS4yIiwgdGV4dCwgc2VsZWN0ZWRbMF0pOwoKCQlzZWxlY3RlZCA9IGZpbmRlci5maW5kQ29udGVudFR5cGVzRm9yKGNoYW5nZUNhc2UoInRleHQudHh0X2Fzc29jMXBsdWdpbmFkZGVkIikpOwoJCWFzc2VydEVxdWFscygiNi4wIiwgMSwgc2VsZWN0ZWQubGVuZ3RoKTsKCQlhc3NlcnRFcXVhbHMoIjYuMSIsIGFzc29jMSwgc2VsZWN0ZWRbMF0pOwoKCQlzZWxlY3RlZCA9IGZpbmRlci5maW5kQ29udGVudFR5cGVzRm9yKGNoYW5nZUNhc2UoInRleHQudHh0X2Fzc29jMXVzZXJhZGRlZCIpKTsKCQlhc3NlcnRFcXVhbHMoIjcuMCIsIDEsIHNlbGVjdGVkLmxlbmd0aCk7CgkJYXNzZXJ0RXF1YWxzKCI3LjEiLCBhc3NvYzEsIHNlbGVjdGVkWzBdKTsKCgkJc2VsZWN0ZWQgPSBmaW5kZXIuZmluZENvbnRlbnRUeXBlc0ZvcihjaGFuZ2VDYXNlKCJ0ZXh0LnR4dF9hc3NvYzJwbHVnaW5hZGRlZCIpKTsKCQlhc3NlcnRFcXVhbHMoIjguMCIsIDEsIHNlbGVjdGVkLmxlbmd0aCk7CgkJYXNzZXJ0RXF1YWxzKCI4LjEiLCBhc3NvYzIsIHNlbGVjdGVkWzBdKTsKCgkJc2VsZWN0ZWQgPSBmaW5kZXIuZmluZENvbnRlbnRUeXBlc0ZvcihjaGFuZ2VDYXNlKCJ0ZXh0LnR4dF9hc3NvYzJ1c2VyYWRkZWQiKSk7CgkJYXNzZXJ0RXF1YWxzKCI5LjAiLCAxLCBzZWxlY3RlZC5sZW5ndGgpOwoJCWFzc2VydEVxdWFscygiOS4xIiwgYXNzb2MyLCBzZWxlY3RlZFswXSk7CgoJCXNlbGVjdGVkID0gZmluZGVyLmZpbmRDb250ZW50VHlwZXNGb3IoY2hhbmdlQ2FzZSgidGV4dC50eHRfYXNzb2MyYnVpbHRpbiIpKTsKCQlhc3NlcnRFcXVhbHMoIjEwLjAiLCAxLCBzZWxlY3RlZC5sZW5ndGgpOwoJCWFzc2VydEVxdWFscygiMTAuMSIsIGFzc29jMiwgc2VsZWN0ZWRbMF0pOwoJfQoKCXB1YmxpYyB2b2lkIHRlc3RBc3NvY2lhdGlvbnMoKSB0aHJvd3MgQ29yZUV4Y2VwdGlvbiB7CgkJSUNvbnRlbnRUeXBlIHRleHQgPSBQbGF0Zm9ybS5nZXRDb250ZW50VHlwZU1hbmFnZXIoKS5nZXRDb250ZW50VHlwZShQbGF0Zm9ybS5QSV9SVU5USU1FICsgIi50ZXh0Iik7CgoJCS8vIGFzc29jaWF0ZSBhIHVzZXItZGVmaW5lZCBmaWxlIHNwZWMKCQl0ZXh0LmFkZEZpbGVTcGVjKCJ0eHRfdXNlcmFkZGVkIiwgSUNvbnRlbnRUeXBlLkZJTEVfRVhURU5TSU9OX1NQRUMpOwoKCQkvLyB0ZXN0IGFzc29jaWF0aW9ucwoJCWFzc2VydFRydWUoIjAuMSIsIHRleHQuaXNBc3NvY2lhdGVkV2l0aChjaGFuZ2VDYXNlKCJ0ZXh0LnR4dCIpKSk7CgkJYXNzZXJ0VHJ1ZSgiMC4yIiwgdGV4dC5pc0Fzc29jaWF0ZWRXaXRoKGNoYW5nZUNhc2UoInRleHQudHh0X3VzZXJhZGRlZCIpKSk7CgkJYXNzZXJ0VHJ1ZSgiMC4zIiwgdGV4dC5pc0Fzc29jaWF0ZWRXaXRoKGNoYW5nZUNhc2UoInRleHQudHh0X3BsdWdpbmFkZGVkIikpKTsKCgkJLy8gY2hlY2sgcHJvdmlkZXIgZGVmaW5lZCBzZXR0aW5ncwoJCVN0cmluZ1tdIHByb3ZpZGVyRGVmaW5lZEV4dGVuc2lvbnMgPSB0ZXh0LmdldEZpbGVTcGVjcyhJQ29udGVudFR5cGUuRklMRV9FWFRFTlNJT05fU1BFQyB8IElDb250ZW50VHlwZS5JR05PUkVfVVNFUl9ERUZJTkVEKTsKCQlhc3NlcnRUcnVlKCIxLjAiLCBjb250YWlucyhwcm92aWRlckRlZmluZWRFeHRlbnNpb25zLCAidHh0IikpOwoJCWFzc2VydFRydWUoIjEuMSIsICFjb250YWlucyhwcm92aWRlckRlZmluZWRFeHRlbnNpb25zLCAidHh0X3VzZXJhZGRlZCIpKTsKCQlhc3NlcnRUcnVlKCIxLjIiLCBjb250YWlucyhwcm92aWRlckRlZmluZWRFeHRlbnNpb25zLCAidHh0X3BsdWdpbmFkZGVkIikpOwoKCQkvLyBjaGVjayB1c2VyIGRlZmluZWQgc2V0dGluZ3MKCQlTdHJpbmdbXSB0ZXh0VXNlckRlZmluZWRFeHRlbnNpb25zID0gdGV4dC5nZXRGaWxlU3BlY3MoSUNvbnRlbnRUeXBlLkZJTEVfRVhURU5TSU9OX1NQRUMgfCBJQ29udGVudFR5cGUuSUdOT1JFX1BSRV9ERUZJTkVEKTsKCQlhc3NlcnRUcnVlKCIyLjAiLCAhY29udGFpbnModGV4dFVzZXJEZWZpbmVkRXh0ZW5zaW9ucywgInR4dCIpKTsKCQlhc3NlcnRUcnVlKCIyLjEiLCBjb250YWlucyh0ZXh0VXNlckRlZmluZWRFeHRlbnNpb25zLCAidHh0X3VzZXJhZGRlZCIpKTsKCQlhc3NlcnRUcnVlKCIyLjIiLCAhY29udGFpbnModGV4dFVzZXJEZWZpbmVkRXh0ZW5zaW9ucywgInR4dF9wbHVnaW5hZGRlZCIpKTsKCgkJLy8gcmVtb3ZpbmcgcHJlLWRlZmluZWQgZmlsZSBzcGVjcyBzaG91bGQgbm90IGRvIGFueXRoaW5nCgkJdGV4dC5yZW1vdmVGaWxlU3BlYygidHh0IiwgSUNvbnRlbnRUeXBlLkZJTEVfRVhURU5TSU9OX1NQRUMpOwoJCWFzc2VydFRydWUoIjMuMCIsIGNvbnRhaW5zKHRleHQuZ2V0RmlsZVNwZWNzKElDb250ZW50VHlwZS5GSUxFX0VYVEVOU0lPTl9TUEVDIHwgSUNvbnRlbnRUeXBlLklHTk9SRV9VU0VSX0RFRklORUQpLCAidHh0IikpOwoJCWFzc2VydFRydWUoIjMuMSIsIHRleHQuaXNBc3NvY2lhdGVkV2l0aChjaGFuZ2VDYXNlKCJ0ZXh0LnR4dCIpKSk7CgkJYXNzZXJ0VHJ1ZSgiMy4yIiwgdGV4dC5pc0Fzc29jaWF0ZWRXaXRoKGNoYW5nZUNhc2UoInRleHQudHh0X3VzZXJhZGRlZCIpKSk7CgkJYXNzZXJ0VHJ1ZSgiMy4zIiwgdGV4dC5pc0Fzc29jaWF0ZWRXaXRoKGNoYW5nZUNhc2UoInRleHQudHh0X3BsdWdpbmFkZGVkIikpKTsKCgkJLy8gcmVtb3ZpbmcgdXNlciBmaWxlIHNwZWNzIGlzIHRoZSBub3JtYWwgY2FzZSBhbmQgaGFzIHRvIHdvcmsgYXMgZXhwZWN0ZWQKCQl0ZXh0LnJlbW92ZUZpbGVTcGVjKCJ0eHRfdXNlcmFkZGVkIiwgSUNvbnRlbnRUeXBlLkZJTEVfRVhURU5TSU9OX1NQRUMpOwoJCWFzc2VydFRydWUoIjQuMCIsICFjb250YWlucyh0ZXh0LmdldEZpbGVTcGVjcyhJQ29udGVudFR5cGUuRklMRV9FWFRFTlNJT05fU1BFQyB8IElDb250ZW50VHlwZS5JR05PUkVfUFJFX0RFRklORUQpLCAiaW5pIikpOwoJCWFzc2VydFRydWUoIjQuMSIsIHRleHQuaXNBc3NvY2lhdGVkV2l0aChjaGFuZ2VDYXNlKCJ0ZXh0LnR4dCIpKSk7CgkJYXNzZXJ0VHJ1ZSgiNC4yIiwgIXRleHQuaXNBc3NvY2lhdGVkV2l0aChjaGFuZ2VDYXNlKCJ0ZXh0LnR4dF91c2VyYWRkZWQiKSkpOwoJCWFzc2VydFRydWUoIjQuMyIsIHRleHQuaXNBc3NvY2lhdGVkV2l0aChjaGFuZ2VDYXNlKCJ0ZXh0LnR4dF9wbHVnaW5hZGRlZCIpKSk7Cgl9CgoJcHVibGljIHZvaWQgdGVzdEJpbmFyeVR5cGVzKCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKCQlJQ29udGVudFR5cGVNYW5hZ2VyIGNvbnRlbnRUeXBlTWFuYWdlciA9IFBsYXRmb3JtLmdldENvbnRlbnRUeXBlTWFuYWdlcigpOwoJCUlDb250ZW50VHlwZSBzYW1wbGVCaW5hcnkxID0gY29udGVudFR5cGVNYW5hZ2VyLmdldENvbnRlbnRUeXBlKFBJX1JFU09VUkNFU19URVNUUyArICIuc2FtcGxlLWJpbmFyeTEiKTsKCQlJQ29udGVudFR5cGUgc2FtcGxlQmluYXJ5MiA9IGNvbnRlbnRUeXBlTWFuYWdlci5nZXRDb250ZW50VHlwZShQSV9SRVNPVVJDRVNfVEVTVFMgKyAiLnNhbXBsZS1iaW5hcnkyIik7CgkJSW5wdXRTdHJlYW0gY29udGVudHM7CgoJCWNvbnRlbnRzID0gZ2V0SW5wdXRTdHJlYW0obmV3IGJ5dGVbXVtdIHtTQU1QTEVfQklOMV9PRkZTRVQuZ2V0Qnl0ZXMoKSwgU0FNUExFX0JJTjFfU0lHTkFUVVJFLCAiIGV4dHJhIGNvbnRlbnRzIi5nZXRCeXRlcygpfSk7CgkJSUNvbnRlbnREZXNjcmlwdGlvbiBkZXNjcmlwdGlvbiA9IGNvbnRlbnRUeXBlTWFuYWdlci5nZXREZXNjcmlwdGlvbkZvcihjb250ZW50cywgbnVsbCwgSUNvbnRlbnREZXNjcmlwdGlvbi5BTEwpOwoJCWFzc2VydE5vdE51bGwoIjYuMCIsIGRlc2NyaXB0aW9uKTsKCQlhc3NlcnRFcXVhbHMoIjYuMSIsIHNhbXBsZUJpbmFyeTEsIGRlc2NyaXB0aW9uLmdldENvbnRlbnRUeXBlKCkpOwoKCQljb250ZW50cyA9IGdldElucHV0U3RyZWFtKG5ldyBieXRlW11bXSB7U0FNUExFX0JJTjJfT0ZGU0VULmdldEJ5dGVzKCksIFNBTVBMRV9CSU4yX1NJR05BVFVSRSwgIiBleHRyYSBjb250ZW50cyIuZ2V0Qnl0ZXMoKX0pOwoJCWRlc2NyaXB0aW9uID0gY29udGVudFR5cGVNYW5hZ2VyLmdldERlc2NyaXB0aW9uRm9yKGNvbnRlbnRzLCBudWxsLCBJQ29udGVudERlc2NyaXB0aW9uLkFMTCk7CgkJYXNzZXJ0Tm90TnVsbCgiNy4wIiwgZGVzY3JpcHRpb24pOwoJCWFzc2VydEVxdWFscygiNy4xIiwgc2FtcGxlQmluYXJ5MiwgZGVzY3JpcHRpb24uZ2V0Q29udGVudFR5cGUoKSk7CgoJCS8vIG1ha2Ugc3VyZSB3ZSBpZ25vcmUgdGhhdCBjb250ZW50IHR5cGUgd2hlbiBjb250ZW50cyBhcmUgdGV4dAoJCS8vIChzZWUgYnVnIDEwMDAzMikKCQkvLyBmaXJzdCBjaGVjayBpZiBvdXIgdGVzdCBlbnZpcm9ubWVudCBpcyBzYW5lCgkJSUNvbnRlbnRUeXBlW10gc2VsZWN0ZWQgPSBjb250ZW50VHlwZU1hbmFnZXIuZmluZENvbnRlbnRUeXBlc0ZvcigidGVzdC5zYW1wbGViaW4yIik7CgkJYXNzZXJ0RXF1YWxzKCI4LjEiLCAxLCBzZWxlY3RlZC5sZW5ndGgpOwoJCWFzc2VydEVxdWFscygiOC4yIiwgc2FtcGxlQmluYXJ5Mi5nZXRJZCgpLCBzZWxlY3RlZFswXS5nZXRJZCgpKTsKCQkvLyAod2UgdXNlZCB0byBibG93IHVwIGhlcmUpCgkJZGVzY3JpcHRpb24gPSBjb250ZW50VHlwZU1hbmFnZXIuZ2V0RGVzY3JpcHRpb25Gb3IoZ2V0UmVhZGVyKGdldFJhbmRvbVN0cmluZygpKSwgInRlc3Quc2FtcGxlYmluMiIsIElDb250ZW50RGVzY3JpcHRpb24uQUxMKTsKCQlhc3NlcnROdWxsKCI4LjMiLCBkZXNjcmlwdGlvbik7Cgl9CgoJcHVibGljIHZvaWQgdGVzdEJ5dGVPcmRlck1hcmsoKSB0aHJvd3MgSU9FeGNlcHRpb24gewoJCUlDb250ZW50VHlwZSB0ZXh0ID0gUGxhdGZvcm0uZ2V0Q29udGVudFR5cGVNYW5hZ2VyKCkuZ2V0Q29udGVudFR5cGUoSUNvbnRlbnRUeXBlTWFuYWdlci5DVF9URVhUKTsKCQlRdWFsaWZpZWROYW1lW10gb3B0aW9ucyA9IG5ldyBRdWFsaWZpZWROYW1lW10ge0lDb250ZW50RGVzY3JpcHRpb24uQllURV9PUkRFUl9NQVJLfTsKCQlJQ29udGVudERlc2NyaXB0aW9uIGRlc2NyaXB0aW9uOwoJCS8vIHRlc3RzIHdpdGggVVRGLTggQk9NCgkJU3RyaW5nIFVURjhfQk9NID0gbmV3IFN0cmluZyhJQ29udGVudERlc2NyaXB0aW9uLkJPTV9VVEZfOCwgU3RhbmRhcmRDaGFyc2V0cy5JU09fODg1OV8xKTsKCQlkZXNjcmlwdGlvbiA9IHRleHQuZ2V0RGVzY3JpcHRpb25Gb3IobmV3IEJ5dGVBcnJheUlucHV0U3RyZWFtKChVVEY4X0JPTSArIE1JTklNQUxfWE1MKS5nZXRCeXRlcyhTdGFuZGFyZENoYXJzZXRzLklTT184ODU5XzEpKSwgb3B0aW9ucyk7CgkJYXNzZXJ0Tm90TnVsbCgiMS4wIiwgZGVzY3JpcHRpb24uZ2V0UHJvcGVydHkoSUNvbnRlbnREZXNjcmlwdGlvbi5CWVRFX09SREVSX01BUkspKTsKCQlhc3NlcnRFcXVhbHMoIjEuMSIsIElDb250ZW50RGVzY3JpcHRpb24uQk9NX1VURl84LCBkZXNjcmlwdGlvbi5nZXRQcm9wZXJ0eShJQ29udGVudERlc2NyaXB0aW9uLkJZVEVfT1JERVJfTUFSSykpOwoJCS8vIHRlc3RzIHdpdGggVVRGLTE2IExpdHRsZSBFbmRpYW4gQk9NCgkJU3RyaW5nIFVURjE2X0xFX0JPTSA9IG5ldyBTdHJpbmcoSUNvbnRlbnREZXNjcmlwdGlvbi5CT01fVVRGXzE2TEUsIFN0YW5kYXJkQ2hhcnNldHMuSVNPXzg4NTlfMSk7CgkJZGVzY3JpcHRpb24gPSB0ZXh0LmdldERlc2NyaXB0aW9uRm9yKG5ldyBCeXRlQXJyYXlJbnB1dFN0cmVhbSgoVVRGMTZfTEVfQk9NICsgTUlOSU1BTF9YTUwpLmdldEJ5dGVzKFN0YW5kYXJkQ2hhcnNldHMuSVNPXzg4NTlfMSkpLCBvcHRpb25zKTsKCQlhc3NlcnROb3ROdWxsKCIyLjAiLCBkZXNjcmlwdGlvbi5nZXRQcm9wZXJ0eShJQ29udGVudERlc2NyaXB0aW9uLkJZVEVfT1JERVJfTUFSSykpOwoJCWFzc2VydEVxdWFscygiMi4xIiwgSUNvbnRlbnREZXNjcmlwdGlvbi5CT01fVVRGXzE2TEUsIGRlc2NyaXB0aW9uLmdldFByb3BlcnR5KElDb250ZW50RGVzY3JpcHRpb24uQllURV9PUkRFUl9NQVJLKSk7CgkJLy8gdGVzdHMgd2l0aCBVVEYtMTYgQmlnIEVuZGlhbiBCT00KCQlTdHJpbmcgVVRGMTZfQkVfQk9NID0gbmV3IFN0cmluZyhJQ29udGVudERlc2NyaXB0aW9uLkJPTV9VVEZfMTZCRSwgU3RhbmRhcmRDaGFyc2V0cy5JU09fODg1OV8xKTsKCQlkZXNjcmlwdGlvbiA9IHRleHQuZ2V0RGVzY3JpcHRpb25Gb3IobmV3IEJ5dGVBcnJheUlucHV0U3RyZWFtKChVVEYxNl9CRV9CT00gKyBNSU5JTUFMX1hNTCkuZ2V0Qnl0ZXMoU3RhbmRhcmRDaGFyc2V0cy5JU09fODg1OV8xKSksIG9wdGlvbnMpOwoJCWFzc2VydE5vdE51bGwoIjMuMCIsIGRlc2NyaXB0aW9uLmdldFByb3BlcnR5KElDb250ZW50RGVzY3JpcHRpb24uQllURV9PUkRFUl9NQVJLKSk7CgkJYXNzZXJ0RXF1YWxzKCIzLjEiLCBJQ29udGVudERlc2NyaXB0aW9uLkJPTV9VVEZfMTZCRSwgZGVzY3JpcHRpb24uZ2V0UHJvcGVydHkoSUNvbnRlbnREZXNjcmlwdGlvbi5CWVRFX09SREVSX01BUkspKTsKCQkvLyB0ZXN0IHdpdGggbm8gQk9NCgkJZGVzY3JpcHRpb24gPSB0ZXh0LmdldERlc2NyaXB0aW9uRm9yKG5ldyBCeXRlQXJyYXlJbnB1dFN0cmVhbShNSU5JTUFMX1hNTC5nZXRCeXRlcyhTdGFuZGFyZENoYXJzZXRzLklTT184ODU5XzEpKSwgb3B0aW9ucyk7CgkJYXNzZXJ0TnVsbCgiNC4wIiwgZGVzY3JpcHRpb24uZ2V0UHJvcGVydHkoSUNvbnRlbnREZXNjcmlwdGlvbi5CWVRFX09SREVSX01BUkspKTsKCgkJLy8gdGVzdHMgZm9yIHBhcnRpYWwgQk9NCgkJLy8gZmlyc3QgYnl0ZSBvZiBVVEYtMTYgQmlnIEVuZGlhbiArIG1pbmltYWwgeG1sCgkJU3RyaW5nIFVURjE2X0JFX0JPTV8xYnl0ZSA9IG5ldyBTdHJpbmcobmV3IGJ5dGVbXSB7KGJ5dGUpIDB4RkV9LCAiSVNPLTg4NTktMSIpOwoJCWRlc2NyaXB0aW9uID0gdGV4dC5nZXREZXNjcmlwdGlvbkZvcihuZXcgQnl0ZUFycmF5SW5wdXRTdHJlYW0oKFVURjE2X0JFX0JPTV8xYnl0ZSArIE1JTklNQUxfWE1MKS5nZXRCeXRlcyhTdGFuZGFyZENoYXJzZXRzLklTT184ODU5XzEpKSwgb3B0aW9ucyk7CgkJYXNzZXJ0TnVsbCgiNS4wIiwgZGVzY3JpcHRpb24uZ2V0UHJvcGVydHkoSUNvbnRlbnREZXNjcmlwdGlvbi5CWVRFX09SREVSX01BUkspKTsKCQkvLyBmaXJzdCBieXRlIG9mIFVURi0xNiBCaWcgRW5kaWFuIG9ubHkgKHNlZSBodHRwczovL2J1Z3MuZWNsaXBzZS5vcmcvYnVncy9zaG93X2J1Zy5jZ2k/aWQ9MTk5MjUyKQoJCWRlc2NyaXB0aW9uID0gdGV4dC5nZXREZXNjcmlwdGlvbkZvcihuZXcgQnl0ZUFycmF5SW5wdXRTdHJlYW0oKFVURjE2X0JFX0JPTV8xYnl0ZSkuZ2V0Qnl0ZXMoU3RhbmRhcmRDaGFyc2V0cy5JU09fODg1OV8xKSksIG9wdGlvbnMpOwoJCWFzc2VydE51bGwoIjUuMSIsIGRlc2NyaXB0aW9uLmdldFByb3BlcnR5KElDb250ZW50RGVzY3JpcHRpb24uQllURV9PUkRFUl9NQVJLKSk7CgoJCS8vIGZpcnN0IGJ5dGUgb2YgVVRGLTE2IExpdHRsZSBFbmRpYW4gKyBtaW5pbWFsIHhtbAoJCVN0cmluZyBVVEYxNl9MRV9CT01fMWJ5dGUgPSBuZXcgU3RyaW5nKG5ldyBieXRlW10geyhieXRlKSAweEZGfSwgU3RhbmRhcmRDaGFyc2V0cy5JU09fODg1OV8xKTsKCQlkZXNjcmlwdGlvbiA9IHRleHQuZ2V0RGVzY3JpcHRpb25Gb3IobmV3IEJ5dGVBcnJheUlucHV0U3RyZWFtKChVVEYxNl9MRV9CT01fMWJ5dGUgKyBNSU5JTUFMX1hNTCkuZ2V0Qnl0ZXMoU3RhbmRhcmRDaGFyc2V0cy5JU09fODg1OV8xKSksIG9wdGlvbnMpOwoJCWFzc2VydE51bGwoIjYuMCIsIGRlc2NyaXB0aW9uLmdldFByb3BlcnR5KElDb250ZW50RGVzY3JpcHRpb24uQllURV9PUkRFUl9NQVJLKSk7CgkJLy8gZmlyc3QgYnl0ZSBvZiBVVEYtMTYgTGl0dGxlIEVuZGlhbiBvbmx5CgkJZGVzY3JpcHRpb24gPSB0ZXh0LmdldERlc2NyaXB0aW9uRm9yKG5ldyBCeXRlQXJyYXlJbnB1dFN0cmVhbSgoVVRGMTZfTEVfQk9NXzFieXRlKS5nZXRCeXRlcyhTdGFuZGFyZENoYXJzZXRzLklTT184ODU5XzEpKSwgb3B0aW9ucyk7CgkJYXNzZXJ0TnVsbCgiNi4xIiwgZGVzY3JpcHRpb24uZ2V0UHJvcGVydHkoSUNvbnRlbnREZXNjcmlwdGlvbi5CWVRFX09SREVSX01BUkspKTsKCgkJLy8gZmlyc3QgYnl0ZSBvZiBVVEYtOCArIG1pbmltYWwgeG1sCgkJU3RyaW5nIFVURjhfQk9NXzFieXRlID0gbmV3IFN0cmluZyhuZXcgYnl0ZVtdIHsoYnl0ZSkgMHhFRn0sIFN0YW5kYXJkQ2hhcnNldHMuSVNPXzg4NTlfMSk7CgkJZGVzY3JpcHRpb24gPSB0ZXh0LmdldERlc2NyaXB0aW9uRm9yKG5ldyBCeXRlQXJyYXlJbnB1dFN0cmVhbSgoVVRGOF9CT01fMWJ5dGUgKyBNSU5JTUFMX1hNTCkuZ2V0Qnl0ZXMoU3RhbmRhcmRDaGFyc2V0cy5JU09fODg1OV8xKSksIG9wdGlvbnMpOwoJCWFzc2VydE51bGwoIjcuMCIsIGRlc2NyaXB0aW9uLmdldFByb3BlcnR5KElDb250ZW50RGVzY3JpcHRpb24uQllURV9PUkRFUl9NQVJLKSk7CgkJLy8gZmlyc3QgYnl0ZSBvZiBVVEYtOCBvbmx5CgkJZGVzY3JpcHRpb24gPSB0ZXh0LmdldERlc2NyaXB0aW9uRm9yKG5ldyBCeXRlQXJyYXlJbnB1dFN0cmVhbSgoVVRGOF9CT01fMWJ5dGUpLmdldEJ5dGVzKFN0YW5kYXJkQ2hhcnNldHMuSVNPXzg4NTlfMSkpLCBvcHRpb25zKTsKCQlhc3NlcnROdWxsKCI3LjEiLCBkZXNjcmlwdGlvbi5nZXRQcm9wZXJ0eShJQ29udGVudERlc2NyaXB0aW9uLkJZVEVfT1JERVJfTUFSSykpOwoKCQkvLyB0d28gZmlyc3QgYnl0ZXMgb2YgVVRGLTggKyBtaW5pbWFsIHhtbAoJCVN0cmluZyBVVEY4X0JPTV8yYnl0ZXMgPSBuZXcgU3RyaW5nKG5ldyBieXRlW10geyhieXRlKSAweEVGLCAoYnl0ZSkgMHhCQn0sIFN0YW5kYXJkQ2hhcnNldHMuSVNPXzg4NTlfMSk7CgkJZGVzY3JpcHRpb24gPSB0ZXh0LmdldERlc2NyaXB0aW9uRm9yKG5ldyBCeXRlQXJyYXlJbnB1dFN0cmVhbSgoVVRGOF9CT01fMmJ5dGVzICsgTUlOSU1BTF9YTUwpLmdldEJ5dGVzKFN0YW5kYXJkQ2hhcnNldHMuSVNPXzg4NTlfMSkpLCBvcHRpb25zKTsKCQlhc3NlcnROdWxsKCI4LjAiLCBkZXNjcmlwdGlvbi5nZXRQcm9wZXJ0eShJQ29udGVudERlc2NyaXB0aW9uLkJZVEVfT1JERVJfTUFSSykpOwoJCS8vIHR3byBmaXJzdCBieXRlcyBvZiBVVEYtOCBvbmx5CgkJZGVzY3JpcHRpb24gPSB0ZXh0LmdldERlc2NyaXB0aW9uRm9yKG5ldyBCeXRlQXJyYXlJbnB1dFN0cmVhbSgoVVRGOF9CT01fMmJ5dGVzKS5nZXRCeXRlcyhTdGFuZGFyZENoYXJzZXRzLklTT184ODU5XzEpKSwgb3B0aW9ucyk7CgkJYXNzZXJ0TnVsbCgiOC4xIiwgZGVzY3JpcHRpb24uZ2V0UHJvcGVydHkoSUNvbnRlbnREZXNjcmlwdGlvbi5CWVRFX09SREVSX01BUkspKTsKCX0KCgkvKioKCSAqIFNlZSBidWcgOTAyMTguCgkgKi8KCXB1YmxpYyB2b2lkIHRlc3RDb250ZW50QW5kTmFtZU1hdGNoaW5nKCkgdGhyb3dzIElPRXhjZXB0aW9uIC8qIG5vdCByZWFsbHkgKi8gewoJCUlDb250ZW50VHlwZU1hbmFnZXIgbWFuYWdlciA9IFBsYXRmb3JtLmdldENvbnRlbnRUeXBlTWFuYWdlcigpOwoKCQlieXRlW11bXSBjb250ZW50czAgPSB7ezB4MEEsIDB4MEIsIDB4MEUsIDB4MTB9fTsKCQlieXRlW11bXSBjb250ZW50czEgPSB7ezB4MEEsIDB4MEIsIDB4MEMsIDB4MTB9fTsKCQlieXRlW11bXSBjb250ZW50czIgPSB7ezB4MEEsIDB4MEIsIDB4MEQsIDB4MTB9fTsKCQlieXRlW11bXSBpbnZhbGlkQ29udGVudHMgPSB7ezAsIDAsIDAsIDB9fTsKCgkJLy8gYmFzZSBtYXRjaGVzICoubXliaW5hcnkgZmlsZXMgc3RhcnRpbmcgd2l0aCAweDBhIDB4MGIKCQlJQ29udGVudFR5cGUgYmFzZSA9IG1hbmFnZXIuZ2V0Q29udGVudFR5cGUoUElfUkVTT1VSQ0VTX1RFU1RTICsgIi5iaW5hcnlfYmFzZSIpOwoJCS8vIGRlcml2ZWQxIG1hdGNoZXMgKi5teWJpbmFyeSBhbmQgc3BlY2lmaWNhbGx5IGZvby5teWJpbmFyeSBmaWxlcyBzdGFydGluZyB3aXRoIDB4MGEgMHgwYiAweGMKCQlJQ29udGVudFR5cGUgZGVyaXZlZDEgPSBtYW5hZ2VyLmdldENvbnRlbnRUeXBlKFBJX1JFU09VUkNFU19URVNUUyArICIuYmluYXJ5X2Rlcml2ZWQxIik7CgkJLy8gZGVyaXZlZDIgbWF0Y2hlcyAqLm15YmluYXJ5IChpbmhlcml0cyBmaWxlc3BlYyBmcm9tIGJhc2UpIGZpbGVzIHN0YXJ0aW5nIHdpdGggMHgwYSAweDBiIDB4ZAoJCUlDb250ZW50VHlwZSBkZXJpdmVkMiA9IG1hbmFnZXIuZ2V0Q29udGVudFR5cGUoUElfUkVTT1VSQ0VTX1RFU1RTICsgIi5iaW5hcnlfZGVyaXZlZDIiKTsKCgkJSUNvbnRlbnRUeXBlW10gc2VsZWN0ZWQ7CgoJCXNlbGVjdGVkID0gbWFuYWdlci5maW5kQ29udGVudFR5cGVzRm9yKGdldElucHV0U3RyZWFtKGNvbnRlbnRzMCksICJhbnl0aGluZy5teWJpbmFyeSIpOwoJCWFzc2VydEVxdWFscygiMS4wIiwgMywgc2VsZWN0ZWQubGVuZ3RoKTsKCQkvLyBhbGwgd2Uga25vdyBpcyB0aGUgZmlyc3Qgb25lIGlzIHRoZSBiYXNlIHR5cGUgKG9ubHkgb25lIHdpdGggYSBWQUxJRCBtYXRjaCkKCQlhc3NlcnRFcXVhbHMoIjEuMSIsIGJhc2UsIHNlbGVjdGVkWzBdKTsKCgkJc2VsZWN0ZWQgPSBtYW5hZ2VyLmZpbmRDb250ZW50VHlwZXNGb3IoZ2V0SW5wdXRTdHJlYW0oY29udGVudHMwKSwgImZvby5teWJpbmFyeSIpOwoJCS8vIHdlIGtub3cgYWxzbyB0aGF0IHRoZSBzZWNvbmQgb25lIHdpbGwgYmUgZGVyaXZlZDEsIGJlY2F1c2UgaXQgaGFzIGEgZnVsbCBuYW1lIG1hdGNoaW5nCgkJYXNzZXJ0RXF1YWxzKCIyLjAiLCAzLCBzZWxlY3RlZC5sZW5ndGgpOwoJCWFzc2VydEVxdWFscygiMi4xIiwgYmFzZSwgc2VsZWN0ZWRbMF0pOwoJCWFzc2VydEVxdWFscygiMi4yIiwgZGVyaXZlZDEsIHNlbGVjdGVkWzFdKTsKCgkJc2VsZWN0ZWQgPSBtYW5hZ2VyLmZpbmRDb250ZW50VHlwZXNGb3IoZ2V0SW5wdXRTdHJlYW0oY29udGVudHMxKSwgImZvby5teWJpbmFyeSIpOwoJCS8vIGRlcml2ZWQxIHdpbGwgYmUgZmlyc3QgYmVjYXVzZSBib3RoIGJhc2UgYW5kIGRlcml2ZWQxIGhhdmUgYSBzdHJvbmcgY29udGVudCBtYXRjaGluZywgc28gbW9yZSBzcGVjaWZpYyB3aW5zCgkJYXNzZXJ0RXF1YWxzKCIzLjAiLCAzLCBzZWxlY3RlZC5sZW5ndGgpOwoJCWFzc2VydEVxdWFscygiMy4xIiwgZGVyaXZlZDEsIHNlbGVjdGVkWzBdKTsKCQlhc3NlcnRFcXVhbHMoIjMuMiIsIGJhc2UsIHNlbGVjdGVkWzFdKTsKCgkJc2VsZWN0ZWQgPSBtYW5hZ2VyLmZpbmRDb250ZW50VHlwZXNGb3IoZ2V0SW5wdXRTdHJlYW0oY29udGVudHMyKSwgImZvby5teWJpbmFyeSIpOwoJCS8vIHNhbWUgYXMgMy4qIC0gZGVyaXZlZDEgaXMgbGFzdCBiZWNhdXNlIGNvbnRlbnQgbWF0Y2hpbmcgaXMgd2VhaywgYWx0aG91ZyBuYW1lIG1hdGNoaW5nIGlzIHN0cm9uZwoJCWFzc2VydEVxdWFscygiNC4wIiwgMywgc2VsZWN0ZWQubGVuZ3RoKTsKCQlhc3NlcnRFcXVhbHMoIjQuMSIsIGRlcml2ZWQyLCBzZWxlY3RlZFswXSk7CgkJYXNzZXJ0RXF1YWxzKCI0LjIiLCBiYXNlLCBzZWxlY3RlZFsxXSk7CgoJCXNlbGVjdGVkID0gbWFuYWdlci5maW5kQ29udGVudFR5cGVzRm9yKGdldElucHV0U3RyZWFtKGludmFsaWRDb250ZW50cyksICJmb28ubXliaW5hcnkiKTsKCQkvLyBhbGwgdHlwZXMgaGF2ZSB3ZWFrIGNvbnRlbnQgbWF0Y2hpbmcgb25seSAtIGRlcml2ZWQxIGhhcyBzdHJvbmcgbmFtZSBtYXRjaGluZwoJCWFzc2VydEVxdWFscygiNS4wIiwgMywgc2VsZWN0ZWQubGVuZ3RoKTsKCQlhc3NlcnRFcXVhbHMoIjUuMSIsIGRlcml2ZWQxLCBzZWxlY3RlZFswXSk7CgkJYXNzZXJ0RXF1YWxzKCI1LjIiLCBiYXNlLCBzZWxlY3RlZFsxXSk7CgoJCXNlbGVjdGVkID0gbWFuYWdlci5maW5kQ29udGVudFR5cGVzRm9yKGdldElucHV0U3RyZWFtKGludmFsaWRDb250ZW50cyksICJhbnl0aGluZy5teWJpbmFyeSIpOwoJCS8vIGFsbCB0eXBlcyBoYXZlIHdlYWsgY29udGVudC9uYW1lIG1hdGNoaW5nIG9ubHkgLSBtb3N0IGdlbmVyYWwgd2lucwoJCWFzc2VydEVxdWFscygiNi4wIiwgMywgc2VsZWN0ZWQubGVuZ3RoKTsKCQlhc3NlcnRFcXVhbHMoIjYuMSIsIGJhc2UsIHNlbGVjdGVkWzBdKTsKCX0KCgkvKgoJICogVGVzdHMgYm90aCB0ZXh0IGFuZCBieXRlIHN0cmVhbS1iYXNlZCBnZXREZXNjcmlwdGlvbkZvciBtZXRob2RzLgoJICovCglwdWJsaWMgdm9pZCB0ZXN0Q29udGVudERlc2NyaXB0aW9uKCkgdGhyb3dzIElPRXhjZXB0aW9uLCBDb3JlRXhjZXB0aW9uIHsKCQlJQ29udGVudFR5cGVNYW5hZ2VyIGNvbnRlbnRUeXBlTWFuYWdlciA9IFBsYXRmb3JtLmdldENvbnRlbnRUeXBlTWFuYWdlcigpOwoJCUlDb250ZW50VHlwZU1hdGNoZXIgZmluZGVyID0gY29udGVudFR5cGVNYW5hZ2VyLmdldE1hdGNoZXIobmV3IExvY2FsU2VsZWN0aW9uUG9saWN5KCksIG51bGwpOwoKCQlJQ29udGVudFR5cGUgeG1sVHlwZSA9IGNvbnRlbnRUeXBlTWFuYWdlci5nZXRDb250ZW50VHlwZShQbGF0Zm9ybS5QSV9SVU5USU1FICsgIi54bWwiKTsKCQlJQ29udGVudFR5cGUgbXl0ZXh0ID0gY29udGVudFR5cGVNYW5hZ2VyLmdldENvbnRlbnRUeXBlKFBJX1JFU09VUkNFU19URVNUUyArICcuJyArICJteXRleHQiKTsKCQlJQ29udGVudFR5cGUgbXl0ZXh0MSA9IGNvbnRlbnRUeXBlTWFuYWdlci5nZXRDb250ZW50VHlwZShQSV9SRVNPVVJDRVNfVEVTVFMgKyAnLicgKyAibXl0ZXh0MSIpOwoJCUlDb250ZW50VHlwZSBteXRleHQyID0gY29udGVudFR5cGVNYW5hZ2VyLmdldENvbnRlbnRUeXBlKFBJX1JFU09VUkNFU19URVNUUyArICcuJyArICJteXRleHQyIik7CgoJCWJvb2xlYW4gdGV4dCA9IGZhbHNlOwoKCQlmb3IgKGludCBpID0gMDsgaSA8IDI7IGkrKywgdGV4dCA9ICF0ZXh0KSB7CgkJCVN0cmluZyBzdWZpeCA9IHRleHQgPyAiLXRleHQiIDogIi1iaW5hcnkiOwoJCQlJQ29udGVudERlc2NyaXB0aW9uIGRlc2NyaXB0aW9uOwoKCQkJZGVzY3JpcHRpb24gPSBnZXREZXNjcmlwdGlvbkZvcihmaW5kZXIsIE1JTklNQUxfWE1MLCAiVVRGLTgiLCAiZm9vLnhtbCIsIElDb250ZW50RGVzY3JpcHRpb24uQUxMLCB0ZXh0KTsKCQkJYXNzZXJ0Tm90TnVsbCgiMS4wIiArIHN1Zml4LCBkZXNjcmlwdGlvbik7CgkJCWFzc2VydEVxdWFscygiMS4xIiArIHN1Zml4LCB4bWxUeXBlLCBkZXNjcmlwdGlvbi5nZXRDb250ZW50VHlwZSgpKTsKCQkJYXNzZXJ0U2FtZSgiMS4yIiwgeG1sVHlwZS5nZXREZWZhdWx0RGVzY3JpcHRpb24oKSwgZGVzY3JpcHRpb24pOwoKCQkJZGVzY3JpcHRpb24gPSBnZXREZXNjcmlwdGlvbkZvcihmaW5kZXIsIE1JTklNQUxfWE1MLCAiVVRGLTgiLCAiZm9vLnhtbCIsIG5ldyBRdWFsaWZpZWROYW1lW10ge0lDb250ZW50RGVzY3JpcHRpb24uQ0hBUlNFVH0sIHRleHQpOwoJCQlhc3NlcnROb3ROdWxsKCIyLjAiICsgc3VmaXgsIGRlc2NyaXB0aW9uKTsKCQkJYXNzZXJ0RXF1YWxzKCIyLjEiICsgc3VmaXgsIHhtbFR5cGUsIGRlc2NyaXB0aW9uLmdldENvbnRlbnRUeXBlKCkpOwoJCQkvLyB0aGUgZGVmYXVsdCBjaGFyc2V0IHNob3VsZCBoYXZlIGJlZW4gZmlsbGVkIGJ5IHRoZSBjb250ZW50IHR5cGUgbWFuYWdlcgoJCQlhc3NlcnRFcXVhbHMoIjIuMiIgKyBzdWZpeCwgIlVURi04IiwgZGVzY3JpcHRpb24uZ2V0UHJvcGVydHkoSUNvbnRlbnREZXNjcmlwdGlvbi5DSEFSU0VUKSk7CgkJCWFzc2VydFNhbWUoIjIuMyIsIHhtbFR5cGUuZ2V0RGVmYXVsdERlc2NyaXB0aW9uKCksIGRlc2NyaXB0aW9uKTsKCgkJCWRlc2NyaXB0aW9uID0gZ2V0RGVzY3JpcHRpb25Gb3IoZmluZGVyLCBYTUxfSVNPXzg4NTlfMSwgIklTTy04ODU5LTEiLCAiZm9vLnhtbCIsIG5ldyBRdWFsaWZpZWROYW1lW10ge0lDb250ZW50RGVzY3JpcHRpb24uQ0hBUlNFVH0sIHRleHQpOwoJCQlhc3NlcnROb3ROdWxsKCIyLjNhIiArIHN1Zml4LCBkZXNjcmlwdGlvbik7CgkJCWFzc2VydEVxdWFscygiMi4zYiIgKyBzdWZpeCwgeG1sVHlwZSwgZGVzY3JpcHRpb24uZ2V0Q29udGVudFR5cGUoKSk7CgkJCWFzc2VydEVxdWFscygiMi4zYyIgKyBzdWZpeCwgIklTTy04ODU5LTEiLCBkZXNjcmlwdGlvbi5nZXRQcm9wZXJ0eShJQ29udGVudERlc2NyaXB0aW9uLkNIQVJTRVQpKTsKCQkJYXNzZXJ0Tm90U2FtZSgiMi4zZCIsIHhtbFR5cGUuZ2V0RGVmYXVsdERlc2NyaXB0aW9uKCksIGRlc2NyaXB0aW9uKTsKCgkJCS8vIGVuc3VyZSB3ZSBoYW5kbGUgc2luZ2xlIHF1b3RlcyBwcm9wZXJseSAoYnVnIDY1NDQzKQoJCQlkZXNjcmlwdGlvbiA9IGdldERlc2NyaXB0aW9uRm9yKGZpbmRlciwgWE1MX0lTT184ODU5XzFfU0lOR0xFX1FVT1RFUywgIklTTy04ODU5LTEiLCAiZm9vLnhtbCIsIG5ldyBRdWFsaWZpZWROYW1lW10ge0lDb250ZW50RGVzY3JpcHRpb24uQ0hBUlNFVH0sIHRleHQpOwoJCQlhc3NlcnROb3ROdWxsKCIyLjNlIiArIHN1Zml4LCBkZXNjcmlwdGlvbik7CgkJCWFzc2VydEVxdWFscygiMi4zZiIgKyBzdWZpeCwgeG1sVHlwZSwgZGVzY3JpcHRpb24uZ2V0Q29udGVudFR5cGUoKSk7CgkJCWFzc2VydEVxdWFscygiMi4zZyIgKyBzdWZpeCwgIklTTy04ODU5LTEiLCBkZXNjcmlwdGlvbi5nZXRQcm9wZXJ0eShJQ29udGVudERlc2NyaXB0aW9uLkNIQVJTRVQpKTsKCQkJYXNzZXJ0Tm90U2FtZSgiMi4zaCIsIHhtbFR5cGUuZ2V0RGVmYXVsdERlc2NyaXB0aW9uKCksIGRlc2NyaXB0aW9uKTsKCgkJCWRlc2NyaXB0aW9uID0gZ2V0RGVzY3JpcHRpb25Gb3IoZmluZGVyLCBYTUxfVVRGXzE2LCAiVVRGLTE2IiwgImZvby54bWwiLCBuZXcgUXVhbGlmaWVkTmFtZVtdIHtJQ29udGVudERlc2NyaXB0aW9uLkNIQVJTRVQsIElDb250ZW50RGVzY3JpcHRpb24uQllURV9PUkRFUl9NQVJLfSwgdGV4dCk7CgkJCWFzc2VydE5vdE51bGwoIjIuNGEiICsgc3VmaXgsIGRlc2NyaXB0aW9uKTsKCQkJYXNzZXJ0RXF1YWxzKCIyLjRiIiArIHN1Zml4LCB4bWxUeXBlLCBkZXNjcmlwdGlvbi5nZXRDb250ZW50VHlwZSgpKTsKCQkJYXNzZXJ0RXF1YWxzKCIyLjRjIiArIHN1Zml4LCAiVVRGLTE2IiwgZGVzY3JpcHRpb24uZ2V0UHJvcGVydHkoSUNvbnRlbnREZXNjcmlwdGlvbi5DSEFSU0VUKSk7CgkJCWFzc2VydFRydWUoIjIuNGQiICsgc3VmaXgsIHRleHQgfHwgSUNvbnRlbnREZXNjcmlwdGlvbi5CT01fVVRGXzE2QkUgPT0gZGVzY3JpcHRpb24uZ2V0UHJvcGVydHkoSUNvbnRlbnREZXNjcmlwdGlvbi5CWVRFX09SREVSX01BUkspKTsKCQkJYXNzZXJ0Tm90U2FtZSgiMi40ZSIsIHhtbFR5cGUuZ2V0RGVmYXVsdERlc2NyaXB0aW9uKCksIGRlc2NyaXB0aW9uKTsKCgkJCWRlc2NyaXB0aW9uID0gZ2V0RGVzY3JpcHRpb25Gb3IoZmluZGVyLCBYTUxfVVRGXzE2QkUsICJVVEYtOCIsICJmb28ueG1sIiwgbmV3IFF1YWxpZmllZE5hbWVbXSB7SUNvbnRlbnREZXNjcmlwdGlvbi5DSEFSU0VUfSwgdGV4dCk7CgkJCWFzc2VydE5vdE51bGwoIjIuNWEiICsgc3VmaXgsIGRlc2NyaXB0aW9uKTsKCQkJYXNzZXJ0RXF1YWxzKCIyLjViIiArIHN1Zml4LCB4bWxUeXBlLCBkZXNjcmlwdGlvbi5nZXRDb250ZW50VHlwZSgpKTsKCQkJYXNzZXJ0RXF1YWxzKCIyLjVjIiArIHN1Zml4LCAiVVRGLTE2QkUiLCBkZXNjcmlwdGlvbi5nZXRQcm9wZXJ0eShJQ29udGVudERlc2NyaXB0aW9uLkNIQVJTRVQpKTsKCQkJYXNzZXJ0Tm90U2FtZSgiMi41ZCIsIHhtbFR5cGUuZ2V0RGVmYXVsdERlc2NyaXB0aW9uKCksIGRlc2NyaXB0aW9uKTsKCgkJCWRlc2NyaXB0aW9uID0gZ2V0RGVzY3JpcHRpb25Gb3IoZmluZGVyLCBYTUxfVVRGXzE2TEUsICJVVEYtOCIsICJmb28ueG1sIiwgbmV3IFF1YWxpZmllZE5hbWVbXSB7SUNvbnRlbnREZXNjcmlwdGlvbi5DSEFSU0VUfSwgdGV4dCk7CgkJCWFzc2VydE5vdE51bGwoIjIuNmEiICsgc3VmaXgsIGRlc2NyaXB0aW9uKTsKCQkJYXNzZXJ0RXF1YWxzKCIyLjZiIiArIHN1Zml4LCB4bWxUeXBlLCBkZXNjcmlwdGlvbi5nZXRDb250ZW50VHlwZSgpKTsKCQkJLy8gdGhlIGRlZmF1bHQgY2hhcnNldCBzaG91bGQgaGF2ZSBiZWVuIGZpbGxlZCBieSB0aGUgY29udGVudCB0eXBlIG1hbmFnZXIKCQkJYXNzZXJ0RXF1YWxzKCIyLjZjIiArIHN1Zml4LCAiVVRGLTE2TEUiLCBkZXNjcmlwdGlvbi5nZXRQcm9wZXJ0eShJQ29udGVudERlc2NyaXB0aW9uLkNIQVJTRVQpKTsKCQkJYXNzZXJ0Tm90U2FtZSgiMi42ZCIsIHhtbFR5cGUuZ2V0RGVmYXVsdERlc2NyaXB0aW9uKCksIGRlc2NyaXB0aW9uKTsKCgkJCWRlc2NyaXB0aW9uID0gZ2V0RGVzY3JpcHRpb25Gb3IoZmluZGVyLCBNSU5JTUFMX1hNTCwgIlVURi04IiwgImZvby54bWwiLCBJQ29udGVudERlc2NyaXB0aW9uLkFMTCwgdGV4dCk7CgkJCWFzc2VydE5vdE51bGwoIjQuMCIgKyBzdWZpeCwgZGVzY3JpcHRpb24pOwoJCQlhc3NlcnRFcXVhbHMoIjQuMSIgKyBzdWZpeCwgeG1sVHlwZSwgZGVzY3JpcHRpb24uZ2V0Q29udGVudFR5cGUoKSk7CgkJCWFzc2VydEVxdWFscygiNC4yIiArIHN1Zml4LCAiVVRGLTgiLCBkZXNjcmlwdGlvbi5nZXRQcm9wZXJ0eShJQ29udGVudERlc2NyaXB0aW9uLkNIQVJTRVQpKTsKCQkJYXNzZXJ0Tm90TnVsbCgiNS4wIiArIHN1Zml4LCBteXRleHQpOwoJCQlhc3NlcnRFcXVhbHMoIjUuMGIiICsgc3VmaXgsICJCQVIiLCBteXRleHQuZ2V0RGVmYXVsdENoYXJzZXQoKSk7CgkJCWFzc2VydFNhbWUoIjUuMGMiLCB4bWxUeXBlLmdldERlZmF1bHREZXNjcmlwdGlvbigpLCBkZXNjcmlwdGlvbik7CgoJCQlkZXNjcmlwdGlvbiA9IGdldERlc2NyaXB0aW9uRm9yKGZpbmRlciwgInNvbWUgY29udGVudHMiLCBudWxsLCAiYWJjLnR6dCIsIElDb250ZW50RGVzY3JpcHRpb24uQUxMLCB0ZXh0KTsKCQkJYXNzZXJ0Tm90TnVsbCgiNS4xIiArIHN1Zml4LCBkZXNjcmlwdGlvbik7CgkJCWFzc2VydEVxdWFscygiNS4yIiArIHN1Zml4LCBteXRleHQsIGRlc2NyaXB0aW9uLmdldENvbnRlbnRUeXBlKCkpOwoJCQlhc3NlcnRFcXVhbHMoIjUuMyIgKyBzdWZpeCwgIkJBUiIsIGRlc2NyaXB0aW9uLmdldFByb3BlcnR5KElDb250ZW50RGVzY3JpcHRpb24uQ0hBUlNFVCkpOwoJCQlhc3NlcnRTYW1lKCI1LjQiLCBteXRleHQuZ2V0RGVmYXVsdERlc2NyaXB0aW9uKCksIGRlc2NyaXB0aW9uKTsKCQkJLy8gbm93IHBsYXlzIHdpdGggc2V0dGluZyBhIG5vbi1kZWZhdWx0IGRlZmF1bHQgY2hhcnNldAoJCQlteXRleHQuc2V0RGVmYXVsdENoYXJzZXQoIkZPTyIpOwoKCQkJZGVzY3JpcHRpb24gPSBnZXREZXNjcmlwdGlvbkZvcihmaW5kZXIsICJzb21lIGNvbnRlbnRzIiwgbnVsbCwgImFiYy50enQiLCBJQ29udGVudERlc2NyaXB0aW9uLkFMTCwgdGV4dCk7CgkJCWFzc2VydE5vdE51bGwoIjUuNSIgKyBzdWZpeCwgZGVzY3JpcHRpb24pOwoJCQlhc3NlcnRFcXVhbHMoIjUuNiIgKyBzdWZpeCwgbXl0ZXh0LCBkZXNjcmlwdGlvbi5nZXRDb250ZW50VHlwZSgpKTsKCQkJYXNzZXJ0RXF1YWxzKCI1LjciICsgc3VmaXgsICJGT08iLCBkZXNjcmlwdGlvbi5nZXRQcm9wZXJ0eShJQ29udGVudERlc2NyaXB0aW9uLkNIQVJTRVQpKTsKCQkJYXNzZXJ0U2FtZSgiNS44IiwgbXl0ZXh0LmdldERlZmF1bHREZXNjcmlwdGlvbigpLCBkZXNjcmlwdGlvbik7CgkJCW15dGV4dC5zZXREZWZhdWx0Q2hhcnNldChudWxsKTsKCgkJCWRlc2NyaXB0aW9uID0gZ2V0RGVzY3JpcHRpb25Gb3IoZmluZGVyLCAic29tZSBjb250ZW50cyIsIG51bGwsICJhYmMudHp0IiwgSUNvbnRlbnREZXNjcmlwdGlvbi5BTEwsIHRleHQpOwoJCQlhc3NlcnROb3ROdWxsKCI1LjEwIiArIHN1Zml4LCBkZXNjcmlwdGlvbik7CgkJCWFzc2VydEVxdWFscygiNS4xMSIgKyBzdWZpeCwgbXl0ZXh0LCBkZXNjcmlwdGlvbi5nZXRDb250ZW50VHlwZSgpKTsKCQkJYXNzZXJ0RXF1YWxzKCI1LjEyIiArIHN1Zml4LCAiQkFSIiwgZGVzY3JpcHRpb24uZ2V0UHJvcGVydHkoSUNvbnRlbnREZXNjcmlwdGlvbi5DSEFSU0VUKSk7CgkJCWFzc2VydFNhbWUoIjUuMTMiLCBteXRleHQuZ2V0RGVmYXVsdERlc2NyaXB0aW9uKCksIGRlc2NyaXB0aW9uKTsKCgkJCS8vIHNlZSBodHRwczovL2J1Z3MuZWNsaXBzZS5vcmcvYnVncy9zaG93X2J1Zy5jZ2k/aWQ9MTc2MzU0CgkJCWRlc2NyaXB0aW9uID0gZ2V0RGVzY3JpcHRpb25Gb3IoZmluZGVyLCAiPD94bWwgdmVyc2lvbj1cJzEuMFwnIGVuY29kaW5nPVwnVVRGLThcJz8+PHNvYXBlbnY6RW52ZWxvcGUgeG1sbnM6c29hcGVudj1cImh0dHA6Ly9zY2hlbWFzLnhtbHNvYXAub3JnL3NvYXAvZW52ZWxvcGUvXCIgeG1sbnM6dG5zPVwiaHR0cDovL3d3dy5leGFtcGxlLm9yZy9cIiB4bWxuczpuczA9XCJodHRwOi8vYW5vdGhlci5leGFtcGxlLm9yZy9cIj48c29hcGVudjpIZWFkZXIgLz48c29hcGVudjpCb2R5PjxuczA6eCAvPjwvc29hcGVudjpCb2R5Pjwvc29hcGVudjpFbnZlbG9wZT4iLCAiVVRGLTgiLCAiZm9vLnhtbCIsIG5ldyBRdWFsaWZpZWROYW1lW10ge0lDb250ZW50RGVzY3JpcHRpb24uQ0hBUlNFVH0sIHRleHQpOwoJCQlhc3NlcnROb3ROdWxsKCI1LjE0IiArIHN1Zml4LCBkZXNjcmlwdGlvbik7CgkJCWFzc2VydEVxdWFscygiNS4xNSIgKyBzdWZpeCwgeG1sVHlwZSwgZGVzY3JpcHRpb24uZ2V0Q29udGVudFR5cGUoKSk7CgkJCWFzc2VydEVxdWFscygiNS4xNiIgKyBzdWZpeCwgIlVURi04IiwgZGVzY3JpcHRpb24uZ2V0UHJvcGVydHkoSUNvbnRlbnREZXNjcmlwdGlvbi5DSEFSU0VUKSk7CgkJCWFzc2VydEVxdWFscygiNS4xNyIsIHhtbFR5cGUuZ2V0RGVmYXVsdERlc2NyaXB0aW9uKCkuZ2V0Q2hhcnNldCgpLCBkZXNjcmlwdGlvbi5nZXRDaGFyc2V0KCkpOwoJCX0KCQlhc3NlcnROb3ROdWxsKCI2LjAiLCBteXRleHQxKTsKCQlhc3NlcnRFcXVhbHMoIjYuMSIsICJCQVIiLCBteXRleHQxLmdldERlZmF1bHRDaGFyc2V0KCkpOwoJCWFzc2VydE5vdE51bGwoIjYuMiIsIG15dGV4dDIpOwoJCWFzc2VydEVxdWFscygiNi4zIiwgbnVsbCwgbXl0ZXh0Mi5nZXREZWZhdWx0Q2hhcnNldCgpKTsKCgl9CgoJLyoqCgkgKiBAc2VlIElDb250ZW50VHlwZU1hdGNoZXIjZmluZENvbnRlbnRUeXBlRm9yCgkgKi8KCXB1YmxpYyB2b2lkIHRlc3RDb250ZW50RGV0ZWN0aW9uKCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKCQlJQ29udGVudFR5cGVNYW5hZ2VyIGNvbnRlbnRUeXBlTWFuYWdlciA9IFBsYXRmb3JtLmdldENvbnRlbnRUeXBlTWFuYWdlcigpOwoJCUlDb250ZW50VHlwZU1hdGNoZXIgZmluZGVyOwoKCQlJQ29udGVudFR5cGUgaW5hcHByb3ByaWF0ZSA9IGNvbnRlbnRUeXBlTWFuYWdlci5nZXRDb250ZW50VHlwZShQSV9SRVNPVVJDRVNfVEVTVFMgKyAiLnNhbXBsZS1iaW5hcnkxIik7CgkJSUNvbnRlbnRUeXBlIGFwcHJvcHJpYXRlID0gY29udGVudFR5cGVNYW5hZ2VyLmdldENvbnRlbnRUeXBlKFBsYXRmb3JtLlBJX1JVTlRJTUUgKyAiLnhtbCIpOwoJCUlDb250ZW50VHlwZSBhcHByb3ByaWF0ZVNwZWNpZmljMSA9IGNvbnRlbnRUeXBlTWFuYWdlci5nZXRDb250ZW50VHlwZShQSV9SRVNPVVJDRVNfVEVTVFMgKyAiLnhtbC1iYXNlZC1kaWZmZXJlbnQtZXh0ZW5zaW9uIik7CgkJSUNvbnRlbnRUeXBlIGFwcHJvcHJpYXRlU3BlY2lmaWMxTG93UHJpb3JpdHkgPSBjb250ZW50VHlwZU1hbmFnZXIuZ2V0Q29udGVudFR5cGUoUElfUkVTT1VSQ0VTX1RFU1RTICsgIi54bWwtYmFzZWQtZGlmZmVyZW50LWV4dGVuc2lvbi1sb3ctcHJpb3JpdHkiKTsKCQlJQ29udGVudFR5cGUgYXBwcm9wcmlhdGVTcGVjaWZpYzIgPSBjb250ZW50VHlwZU1hbmFnZXIuZ2V0Q29udGVudFR5cGUoUElfUkVTT1VSQ0VTX1RFU1RTICsgIi54bWwtYmFzZWQtc3BlY2lmaWMtbmFtZSIpOwoKCQkvLyBpZiBvbmx5IGluYXBwcm9wcmlhdGUgaXMgcHJvdmlkZWQsIG5vbmUgd2lsbCBiZSBzZWxlY3RlZAoJCWZpbmRlciA9IGNvbnRlbnRUeXBlTWFuYWdlci5nZXRNYXRjaGVyKG5ldyBTdWJzZXRTZWxlY3Rpb25Qb2xpY3kobmV3IElDb250ZW50VHlwZVtdIHtpbmFwcHJvcHJpYXRlfSksIG51bGwpOwoJCWFzc2VydE51bGwoIjEuMCIsIGZpbmRlci5maW5kQ29udGVudFR5cGVGb3IoZ2V0SW5wdXRTdHJlYW0oTUlOSU1BTF9YTUwpLCBudWxsKSk7CgoJCS8vIGlmIGluYXBwcm9wcmlhdGUgYW5kIGFwcHJvcHJpYXRlIGFyZSBwcm92aWRlZCwgYXBwcm9wcmlhdGUgd2lsbCBiZSBzZWxlY3RlZAoJCWZpbmRlciA9IGNvbnRlbnRUeXBlTWFuYWdlci5nZXRNYXRjaGVyKG5ldyBTdWJzZXRTZWxlY3Rpb25Qb2xpY3kobmV3IElDb250ZW50VHlwZVtdIHtpbmFwcHJvcHJpYXRlLCBhcHByb3ByaWF0ZX0pLCBudWxsKTsKCQlhc3NlcnRFcXVhbHMoIjIuMCIsIGFwcHJvcHJpYXRlLCBmaW5kZXIuZmluZENvbnRlbnRUeXBlRm9yKGdldElucHV0U3RyZWFtKE1JTklNQUxfWE1MKSwgbnVsbCkpOwoKCQkvLyBpZiBpbmFwcHJvcHJpYXRlLCBhcHByb3ByaWF0ZSBhbmQgYSBtb3JlIHNwZWNpZmljIGFwcHJvcHJpYXRlIHR5cGUgYXJlIHByb3ZpZGVkLCB0aGUgc3BlY2lmaWMgdHlwZSB3aWxsIGJlIHNlbGVjdGVkCgkJZmluZGVyID0gY29udGVudFR5cGVNYW5hZ2VyLmdldE1hdGNoZXIobmV3IFN1YnNldFNlbGVjdGlvblBvbGljeShuZXcgSUNvbnRlbnRUeXBlW10ge2luYXBwcm9wcmlhdGUsIGFwcHJvcHJpYXRlLCBhcHByb3ByaWF0ZVNwZWNpZmljMX0pLCBudWxsKTsKCQlhc3NlcnRFcXVhbHMoIjMuMCIsIGFwcHJvcHJpYXRlU3BlY2lmaWMxLCBmaW5kZXIuZmluZENvbnRlbnRUeXBlRm9yKGdldElucHV0U3RyZWFtKE1JTklNQUxfWE1MKSwgbnVsbCkpOwoJCWZpbmRlciA9IGNvbnRlbnRUeXBlTWFuYWdlci5nZXRNYXRjaGVyKG5ldyBTdWJzZXRTZWxlY3Rpb25Qb2xpY3kobmV3IElDb250ZW50VHlwZVtdIHtpbmFwcHJvcHJpYXRlLCBhcHByb3ByaWF0ZSwgYXBwcm9wcmlhdGVTcGVjaWZpYzJ9KSwgbnVsbCk7CgkJYXNzZXJ0RXF1YWxzKCIzLjEiLCBhcHByb3ByaWF0ZVNwZWNpZmljMiwgZmluZGVyLmZpbmRDb250ZW50VHlwZUZvcihnZXRJbnB1dFN0cmVhbShNSU5JTUFMX1hNTCksIG51bGwpKTsKCgkJLy8gaWYgYWxsIGFyZSBwcm92aWRlZCwgdGhlIG1vcmUgc3BlY2lmaWMgdHlwZXMgd2lsbCBhcHBlYXIgYmVmb3JlIHRoZSBtb3JlIGdlbmVyaWMgdHlwZXMKCQlmaW5kZXIgPSBjb250ZW50VHlwZU1hbmFnZXIuZ2V0TWF0Y2hlcihuZXcgU3Vic2V0U2VsZWN0aW9uUG9saWN5KG5ldyBJQ29udGVudFR5cGVbXSB7aW5hcHByb3ByaWF0ZSwgYXBwcm9wcmlhdGUsIGFwcHJvcHJpYXRlU3BlY2lmaWMxLCBhcHByb3ByaWF0ZVNwZWNpZmljMn0pLCBudWxsKTsKCQlJQ29udGVudFR5cGVbXSBzZWxlY3RlZCA9IGZpbmRlci5maW5kQ29udGVudFR5cGVzRm9yKGdldElucHV0U3RyZWFtKE1JTklNQUxfWE1MKSwgbnVsbCk7CgkJYXNzZXJ0RXF1YWxzKCI0LjAiLCAzLCBzZWxlY3RlZC5sZW5ndGgpOwoJCWFzc2VydFRydWUoIjQuMSIsIGFwcHJvcHJpYXRlU3BlY2lmaWMxLmVxdWFscyhzZWxlY3RlZFswXSkgfHwgYXBwcm9wcmlhdGVTcGVjaWZpYzEuZXF1YWxzKHNlbGVjdGVkWzFdKSk7CgkJYXNzZXJ0VHJ1ZSgiNC4yIiwgYXBwcm9wcmlhdGVTcGVjaWZpYzIuZXF1YWxzKHNlbGVjdGVkWzBdKSB8fCBhcHByb3ByaWF0ZVNwZWNpZmljMi5lcXVhbHMoc2VsZWN0ZWRbMV0pKTsKCQlhc3NlcnRUcnVlKCI0LjMiLCBhcHByb3ByaWF0ZS5lcXVhbHMoc2VsZWN0ZWRbMl0pKTsKCgkJLy8gaWYgYXBwcm9wcmlhdGUgYW5kIGEgbW9yZSBzcGVjaWZpYyBhcHByb3ByaWF0ZSB0eXBlIChidXQgd2l0aCBsb3cgcHJpb3JpdHkpIGFyZSBwcm92aWRlZCwgdGhlIHNwZWNpZmljIHR5cGUgd2lsbCBiZSBzZWxlY3RlZAoJCWZpbmRlciA9IGNvbnRlbnRUeXBlTWFuYWdlci5nZXRNYXRjaGVyKG5ldyBTdWJzZXRTZWxlY3Rpb25Qb2xpY3kobmV3IElDb250ZW50VHlwZVtdIHthcHByb3ByaWF0ZSwgYXBwcm9wcmlhdGVTcGVjaWZpYzFMb3dQcmlvcml0eX0pLCBudWxsKTsKCQlhc3NlcnRFcXVhbHMoIjUuMCIsIGFwcHJvcHJpYXRlU3BlY2lmaWMxTG93UHJpb3JpdHksIGZpbmRlci5maW5kQ29udGVudFR5cGVGb3IoZ2V0SW5wdXRTdHJlYW0oTUlOSU1BTF9YTUwpLCBudWxsKSk7CgoJCS8vIGlmIGFwcHJvcHJpYXRlIGFuZCB0d28gc3BlY2lmaWMgYXBwcm9wcmlhdGUgdHlwZXMgKGJ1dCBvbmUgd2l0aCBsb3dlciBwcmlvcml0eSkgYXJlIHByb3ZpZGVkLCB0aGUgc3BlY2lmaWMgdHlwZSB3aXRoIGhpZ2hlciBwcmlvcml0eSB3aWxsIGJlIHNlbGVjdGVkCgkJZmluZGVyID0gY29udGVudFR5cGVNYW5hZ2VyLmdldE1hdGNoZXIobmV3IFN1YnNldFNlbGVjdGlvblBvbGljeShuZXcgSUNvbnRlbnRUeXBlW10ge2FwcHJvcHJpYXRlLCBhcHByb3ByaWF0ZVNwZWNpZmljMSwgYXBwcm9wcmlhdGVTcGVjaWZpYzFMb3dQcmlvcml0eX0pLCBudWxsKTsKCQlhc3NlcnRFcXVhbHMoIjUuMSIsIGFwcHJvcHJpYXRlU3BlY2lmaWMxLCBmaW5kZXIuZmluZENvbnRlbnRUeXBlRm9yKGdldElucHV0U3RyZWFtKE1JTklNQUxfWE1MKSwgbnVsbCkpOwoJfQoKCXB1YmxpYyB2b2lkIHRlc3REZWZhdWx0UHJvcGVydGllcygpIHRocm93cyBJT0V4Y2VwdGlvbiAvKiBuZXZlciBhY3R1YWxseSB0aHJvd24gKi8gewoJCUlDb250ZW50VHlwZU1hbmFnZXIgY29udGVudFR5cGVNYW5hZ2VyID0gUGxhdGZvcm0uZ2V0Q29udGVudFR5cGVNYW5hZ2VyKCk7CgoJCUlDb250ZW50VHlwZSBteXRleHQgPSBjb250ZW50VHlwZU1hbmFnZXIuZ2V0Q29udGVudFR5cGUoUElfUkVTT1VSQ0VTX1RFU1RTICsgJy4nICsgIm15dGV4dCIpOwoJCUlDb250ZW50VHlwZSBteXRleHQxID0gY29udGVudFR5cGVNYW5hZ2VyLmdldENvbnRlbnRUeXBlKFBJX1JFU09VUkNFU19URVNUUyArICcuJyArICJteXRleHQxIik7CgkJSUNvbnRlbnRUeXBlIG15dGV4dDIgPSBjb250ZW50VHlwZU1hbmFnZXIuZ2V0Q29udGVudFR5cGUoUElfUkVTT1VSQ0VTX1RFU1RTICsgJy4nICsgIm15dGV4dDIiKTsKCQlhc3NlcnROb3ROdWxsKCIwLjEiLCBteXRleHQpOwoJCWFzc2VydE5vdE51bGwoIjAuMiIsIG15dGV4dDEpOwoJCWFzc2VydE5vdE51bGwoIjAuMyIsIG15dGV4dDIpOwoKCQlRdWFsaWZpZWROYW1lIGNoYXJzZXQgPSBJQ29udGVudERlc2NyaXB0aW9uLkNIQVJTRVQ7CgkJUXVhbGlmaWVkTmFtZSBsb2NhbENoYXJzZXQgPSBuZXcgUXVhbGlmaWVkTmFtZShQSV9SRVNPVVJDRVNfVEVTVFMsICJjaGFyc2V0Iik7CgkJUXVhbGlmaWVkTmFtZSBwcm9wZXJ0eTEgPSBuZXcgUXVhbGlmaWVkTmFtZShQSV9SRVNPVVJDRVNfVEVTVFMsICJwcm9wZXJ0eTEiKTsKCQlRdWFsaWZpZWROYW1lIHByb3BlcnR5MiA9IG5ldyBRdWFsaWZpZWROYW1lKFBJX1JFU09VUkNFU19URVNUUywgInByb3BlcnR5MiIpOwoJCVF1YWxpZmllZE5hbWUgcHJvcGVydHkzID0gbmV3IFF1YWxpZmllZE5hbWUoUElfUkVTT1VSQ0VTX1RFU1RTLCAicHJvcGVydHkzIik7CgkJUXVhbGlmaWVkTmFtZSBwcm9wZXJ0eTQgPSBuZXcgUXVhbGlmaWVkTmFtZShQSV9SRVNPVVJDRVNfVEVTVFMsICJwcm9wZXJ0eTQiKTsKCgkJSUNvbnRlbnREZXNjcmlwdGlvbiBkZXNjcmlwdGlvbjsKCQlJQ29udGVudFR5cGVNYXRjaGVyIGZpbmRlciA9IGNvbnRlbnRUeXBlTWFuYWdlci5nZXRNYXRjaGVyKG5ldyBMb2NhbFNlbGVjdGlvblBvbGljeSgpLCBudWxsKTsKCgkJZGVzY3JpcHRpb24gPSBnZXREZXNjcmlwdGlvbkZvcihmaW5kZXIsICJzb21lIGNvbnRlbnRzIiwgbnVsbCwgImFiYy50enQiLCBJQ29udGVudERlc2NyaXB0aW9uLkFMTCwgdHJ1ZSk7CgkJYXNzZXJ0Tm90TnVsbCgiMS4wIiwgZGVzY3JpcHRpb24pOwoJCWFzc2VydEVxdWFscygiMS4xIiwgbXl0ZXh0LCBkZXNjcmlwdGlvbi5nZXRDb250ZW50VHlwZSgpKTsKCQlhc3NlcnRFcXVhbHMoIjEuMiIsICJ2YWx1ZTEiLCBkZXNjcmlwdGlvbi5nZXRQcm9wZXJ0eShwcm9wZXJ0eTEpKTsKCQlhc3NlcnROdWxsKCIxLjMiLCBkZXNjcmlwdGlvbi5nZXRQcm9wZXJ0eShwcm9wZXJ0eTIpKTsKCQlhc3NlcnRFcXVhbHMoIjEuNCIsICJ2YWx1ZTMiLCBkZXNjcmlwdGlvbi5nZXRQcm9wZXJ0eShwcm9wZXJ0eTMpKTsKCQlhc3NlcnRFcXVhbHMoIjEuNSIsICJCQVIiLCBkZXNjcmlwdGlvbi5nZXRQcm9wZXJ0eShjaGFyc2V0KSk7CgoJCWRlc2NyaXB0aW9uID0gZ2V0RGVzY3JpcHRpb25Gb3IoZmluZGVyLCAic29tZSBjb250ZW50cyIsIG51bGwsICJhYmMudHp0MSIsIElDb250ZW50RGVzY3JpcHRpb24uQUxMLCB0cnVlKTsKCQlhc3NlcnROb3ROdWxsKCIyLjAiLCBkZXNjcmlwdGlvbik7CgkJYXNzZXJ0RXF1YWxzKCIyLjEiLCBteXRleHQxLCBkZXNjcmlwdGlvbi5nZXRDb250ZW50VHlwZSgpKTsKCQlhc3NlcnRFcXVhbHMoIjIuMiIsICJ2YWx1ZTEiLCBkZXNjcmlwdGlvbi5nZXRQcm9wZXJ0eShwcm9wZXJ0eTEpKTsKCQlhc3NlcnRFcXVhbHMoIjIuMyIsICJ2YWx1ZTIiLCBkZXNjcmlwdGlvbi5nZXRQcm9wZXJ0eShwcm9wZXJ0eTIpKTsKCQlhc3NlcnROdWxsKCIyLjQiLCBkZXNjcmlwdGlvbi5nZXRQcm9wZXJ0eShwcm9wZXJ0eTMpKTsKCQlhc3NlcnRFcXVhbHMoIjIuNSIsICJ2YWx1ZTQiLCBkZXNjcmlwdGlvbi5nZXRQcm9wZXJ0eShwcm9wZXJ0eTQpKTsKCQlhc3NlcnRFcXVhbHMoIjIuNiIsICJCQVIiLCBkZXNjcmlwdGlvbi5nZXRQcm9wZXJ0eShjaGFyc2V0KSk7CgoJCWRlc2NyaXB0aW9uID0gZ2V0RGVzY3JpcHRpb25Gb3IoZmluZGVyLCAic29tZSBjb250ZW50cyIsIG51bGwsICJhYmMudHp0MiIsIElDb250ZW50RGVzY3JpcHRpb24uQUxMLCB0cnVlKTsKCQlhc3NlcnROb3ROdWxsKCIzLjAiLCBkZXNjcmlwdGlvbik7CgkJYXNzZXJ0RXF1YWxzKCIzLjEiLCBteXRleHQyLCBkZXNjcmlwdGlvbi5nZXRDb250ZW50VHlwZSgpKTsKCQlhc3NlcnROdWxsKCIzLjIiLCBkZXNjcmlwdGlvbi5nZXRQcm9wZXJ0eShwcm9wZXJ0eTEpKTsKCQlhc3NlcnROdWxsKCIzLjMiLCBkZXNjcmlwdGlvbi5nZXRQcm9wZXJ0eShwcm9wZXJ0eTIpKTsKCQlhc3NlcnROdWxsKCIzLjQiLCBkZXNjcmlwdGlvbi5nZXRQcm9wZXJ0eShwcm9wZXJ0eTMpKTsKCQlhc3NlcnROdWxsKCIzLjUiLCBkZXNjcmlwdGlvbi5nZXRQcm9wZXJ0eShwcm9wZXJ0eTQpKTsKCQlhc3NlcnROdWxsKCIzLjYiLCBkZXNjcmlwdGlvbi5nZXRQcm9wZXJ0eShjaGFyc2V0KSk7CgkJYXNzZXJ0RXF1YWxzKCIzLjciLCAibXl0ZXh0MiIsIGRlc2NyaXB0aW9uLmdldFByb3BlcnR5KGxvY2FsQ2hhcnNldCkpOwoJfQoKCS8qKgoJICogVGhlIGZvb0JhciBjb250ZW50IHR5cGUgaXMgYXNzb2NpYXRlZCB3aXRoIHRoZSAiZm9vLmJhciIgZmlsZSBuYW1lIGFuZAoJICogdGhlICJiYXIiIGZpbGUgZXh0ZW5zaW9uICh3aGF0IGlzIGJvZ3VzLCBhbnl3YXkpLiBUaGlzIHRlc3QgZW5zdXJlcyBpdAoJICogZG9lcyBub3QgYXBwZWFyIHR3aWNlIGluIHRoZSBsaXN0IG9mIGNvbnRlbnQgdHlwZXMgYXNzb2NpYXRlZCB3aXRoIHRoZQoJICogImZvby5iYXIiIGZpbGUgbmFtZS4KCSAqLwoJcHVibGljIHZvaWQgdGVzdERvdWJsZUFzc29jaWF0aW9uKCkgewoJCUlDb250ZW50VHlwZU1hbmFnZXIgY29udGVudFR5cGVNYW5hZ2VyID0gUGxhdGZvcm0uZ2V0Q29udGVudFR5cGVNYW5hZ2VyKCk7CgoJCUlDb250ZW50VHlwZSBmb29CYXJUeXBlID0gY29udGVudFR5cGVNYW5hZ2VyLmdldENvbnRlbnRUeXBlKFBJX1JFU09VUkNFU19URVNUUyArICcuJyArICJmb29CYXIiKTsKCQlhc3NlcnROb3ROdWxsKCIxLjAiLCBmb29CYXJUeXBlKTsKCQlJQ29udGVudFR5cGUgc3ViRm9vQmFyVHlwZSA9IGNvbnRlbnRUeXBlTWFuYWdlci5nZXRDb250ZW50VHlwZShQSV9SRVNPVVJDRVNfVEVTVFMgKyAnLicgKyAic3ViRm9vQmFyIik7CgkJYXNzZXJ0Tm90TnVsbCgiMS4xIiwgc3ViRm9vQmFyVHlwZSk7CgkJLy8gZW5zdXJlIHdlIGRvbid0IGdldCBmb29CYXIgdHdpY2UKCQlJQ29udGVudFR5cGVNYXRjaGVyIGZpbmRlciA9IGNvbnRlbnRUeXBlTWFuYWdlci5nZXRNYXRjaGVyKG5ldyBMb2NhbFNlbGVjdGlvblBvbGljeSgpLCBudWxsKTsKCQlJQ29udGVudFR5cGVbXSBmb29CYXJBc3NvY2lhdGVkID0gZmluZGVyLmZpbmRDb250ZW50VHlwZXNGb3IoY2hhbmdlQ2FzZSgiZm9vLmJhciIpKTsKCQlhc3NlcnRFcXVhbHMoIjIuMSIsIDIsIGZvb0JhckFzc29jaWF0ZWQubGVuZ3RoKTsKCQlhc3NlcnRUcnVlKCIyLjIiLCBjb250YWlucyhmb29CYXJBc3NvY2lhdGVkLCBmb29CYXJUeXBlKSk7CgkJYXNzZXJ0VHJ1ZSgiMi4zIiwgY29udGFpbnMoZm9vQmFyQXNzb2NpYXRlZCwgc3ViRm9vQmFyVHlwZSkpOwoJfQoKCS8qKgoJICogT2J0YWlucyBhIHJlZmVyZW5jZSB0byBhIGtub3duIGNvbnRlbnQgdHlwZSwgdGhlbiBpbnN0YWxscyBhIGJ1bmRsZSB0aGF0IGNvbnRyaWJ1dGVzIGEgY29udGVudCB0eXBlLAoJICogYW5kIG1ha2VzIHN1cmUgYSBuZXcgb2J0YWluZWQgcmVmZXJlbmNlIHRvIHRoZSBzYW1lIGNvbnRlbnQgdHlwZSBpcyBub3QgaWRlbnRpY2FsIChzaG93cwoJICogdGhhdCB0aGUgY29udGVudCB0eXBlIGNhdGFsb2cgaGFzIGJlZW4gZGlzY2FyZGVkIGFuZCByZWJ1aWx0KS4gVGhlbiB1bmluc3RhbGxzIHRoYXQgYnVuZGxlCgkgKiBhbmQgY2hlY2tzIGFnYWluIHRoZSBzYW1lIHRoaW5nIChiZWNhdXNlIHRoZSBjb250ZW50IHR5cGUgY2F0YWxvZyBzaG91bGQgYmUgcmVidWlsdCB3aGVuZXZlcgoJICogY29udGVudCB0eXBlcyBhcmUgZHluYW1pY2FseSBhZGRlZC9yZW1vdmVkKS4KCSAqLwoJcHVibGljIHZvaWQgdGVzdER5bmFtaWNDaGFuZ2VzKCkgewoJCWZpbmFsIElDb250ZW50VHlwZVtdIHRleHQgPSBuZXcgSUNvbnRlbnRUeXBlWzRdOwoJCWZpbmFsIElDb250ZW50VHlwZU1hbmFnZXIgbWFuYWdlciA9IFBsYXRmb3JtLmdldENvbnRlbnRUeXBlTWFuYWdlcigpOwoJCXRleHRbMF0gPSBtYW5hZ2VyLmdldENvbnRlbnRUeXBlKElDb250ZW50VHlwZU1hbmFnZXIuQ1RfVEVYVCk7CgkJYXNzZXJ0Tm90TnVsbCgiMS4wIiwgdGV4dFswXSk7CgkJdGV4dFsxXSA9IG1hbmFnZXIuZ2V0Q29udGVudFR5cGUoSUNvbnRlbnRUeXBlTWFuYWdlci5DVF9URVhUKTsKCQlhc3NlcnROb3ROdWxsKCIxLjEiLCB0ZXh0WzFdKTsKCQl0ZXh0WzBdID0gKChDb250ZW50VHlwZUhhbmRsZXIpIHRleHRbMF0pLmdldFRhcmdldCgpOwoJCXRleHRbMV0gPSAoKENvbnRlbnRUeXBlSGFuZGxlcikgdGV4dFsxXSkuZ2V0VGFyZ2V0KCk7CgkJYXNzZXJ0RXF1YWxzKCIyLjAiLCB0ZXh0WzBdLCB0ZXh0WzFdKTsKCQlhc3NlcnRUcnVlKCIyLjEiLCB0ZXh0WzBdID09IHRleHRbMV0pOwoJCS8vCW1ha2UgYXJiaXRyYXJ5IGR5bmFtaWMgY2hhbmdlcyB0byB0aGUgY29udGVudFR5cGVzIGV4dGVuc2lvbiBwb2ludAoJCVRlc3RSZWdpc3RyeUNoYW5nZUxpc3RlbmVyIGxpc3RlbmVyID0gbmV3IFRlc3RSZWdpc3RyeUNoYW5nZUxpc3RlbmVyKFBsYXRmb3JtLlBJX1JVTlRJTUUsIENvbnRlbnRUeXBlQnVpbGRlci5QVF9DT05URU5UVFlQRVMsIG51bGwsIG51bGwpOwoJCUJ1bmRsZVRlc3RpbmdIZWxwZXIucnVuV2l0aEJ1bmRsZXMoIjMiLCAoKSAtPiB7CgkJCUlDb250ZW50VHlwZSBtaXNzaW5nID0gbWFuYWdlci5nZXRDb250ZW50VHlwZSgib3JnLmVjbGlwc2UuYnVuZGxlMDEubWlzc2luZyIpOwoJCQlhc3NlcnROb3ROdWxsKCIzLjEiLCBtaXNzaW5nKTsKCQkJLy8gZW5zdXJlIHRoZSBjb250ZW50IHR5cGUgaW5zdGFuY2VzIGFyZSBkaWZmZXJlbnQKCQkJdGV4dFsyXSA9IG1hbmFnZXIuZ2V0Q29udGVudFR5cGUoSUNvbnRlbnRUeXBlTWFuYWdlci5DVF9URVhUKTsKCQkJYXNzZXJ0Tm90TnVsbCgiMy4yIiwgdGV4dFsyXSk7CgkJCXRleHRbMl0gPSAoKENvbnRlbnRUeXBlSGFuZGxlcikgdGV4dFsyXSkuZ2V0VGFyZ2V0KCk7CgkJCWFzc2VydEVxdWFscygiMy4zIiwgdGV4dFswXSwgdGV4dFsyXSk7CgkJCWFzc2VydFRydWUoIjMuNCIsIHRleHRbMF0gIT0gdGV4dFsyXSk7CgkJfSwgZ2V0Q29udGV4dCgpLCBuZXcgU3RyaW5nW10ge0NvbnRlbnRUeXBlVGVzdC5URVNUX0ZJTEVTX1JPT1QgKyAiY29udGVudC9idW5kbGUwMSJ9LCBsaXN0ZW5lcik7CgkJYXNzZXJ0TnVsbCgiNC4wIiwgbWFuYWdlci5nZXRDb250ZW50VHlwZSgib3JnLmVjbGlwc2UuYnVuZGxlMDEubWlzc2luZyIpKTsKCQkvLyBlbnN1cmUgdGhlIGNvbnRlbnQgdHlwZSBpbnN0YW5jZXMgYXJlIGFsbCBkaWZmZXJlbnQKCQl0ZXh0WzNdID0gbWFuYWdlci5nZXRDb250ZW50VHlwZShJQ29udGVudFR5cGVNYW5hZ2VyLkNUX1RFWFQpOwoJCWFzc2VydE5vdE51bGwoIjUuMCIsIHRleHRbM10pOwoJCXRleHRbM10gPSAoKENvbnRlbnRUeXBlSGFuZGxlcikgdGV4dFszXSkuZ2V0VGFyZ2V0KCk7CgkJYXNzZXJ0RXF1YWxzKCI1LjEiLCB0ZXh0WzBdLCB0ZXh0WzNdKTsKCQlhc3NlcnRFcXVhbHMoIjUuMiIsIHRleHRbMl0sIHRleHRbM10pOwoJCWFzc2VydFRydWUoIjUuMyIsIHRleHRbMF0gIT0gdGV4dFszXSk7CgkJYXNzZXJ0VHJ1ZSgiNS40IiwgdGV4dFsyXSAhPSB0ZXh0WzNdKTsKCX0KCgkvKioKCSAqIFNpbWlsYXIgdG8gdGVzdER5bmFtaWNDaGFuZ2VzLCBidXQgdXNpbmcgdGhlIG9yZy5lY2xpcHNlLmNvcmUuY29udGVudHR5cGUuY29udGVudFR5cGVzIGV4dGVuc2lvbiBwb2ludC4KCSAqLwoJcHVibGljIHZvaWQgdGVzdER5bmFtaWNDaGFuZ2VzTmV3RXh0ZW5zaW9uKCkgewoJCWZpbmFsIElDb250ZW50VHlwZVtdIHRleHQgPSBuZXcgSUNvbnRlbnRUeXBlWzRdOwoJCWZpbmFsIElDb250ZW50VHlwZU1hbmFnZXIgbWFuYWdlciA9IFBsYXRmb3JtLmdldENvbnRlbnRUeXBlTWFuYWdlcigpOwoJCXRleHRbMF0gPSBtYW5hZ2VyLmdldENvbnRlbnRUeXBlKElDb250ZW50VHlwZU1hbmFnZXIuQ1RfVEVYVCk7CgkJYXNzZXJ0Tm90TnVsbCgiMS4wIiwgdGV4dFswXSk7CgkJdGV4dFsxXSA9IG1hbmFnZXIuZ2V0Q29udGVudFR5cGUoSUNvbnRlbnRUeXBlTWFuYWdlci5DVF9URVhUKTsKCQlhc3NlcnROb3ROdWxsKCIxLjEiLCB0ZXh0WzFdKTsKCQl0ZXh0WzBdID0gKChDb250ZW50VHlwZUhhbmRsZXIpIHRleHRbMF0pLmdldFRhcmdldCgpOwoJCXRleHRbMV0gPSAoKENvbnRlbnRUeXBlSGFuZGxlcikgdGV4dFsxXSkuZ2V0VGFyZ2V0KCk7CgkJYXNzZXJ0RXF1YWxzKCIyLjAiLCB0ZXh0WzBdLCB0ZXh0WzFdKTsKCQlhc3NlcnRUcnVlKCIyLjEiLCB0ZXh0WzBdID09IHRleHRbMV0pOwoJCS8vCW1ha2UgYXJiaXRyYXJ5IGR5bmFtaWMgY2hhbmdlcyB0byB0aGUgY29udGVudFR5cGVzIGV4dGVuc2lvbiBwb2ludAoJCVRlc3RSZWdpc3RyeUNoYW5nZUxpc3RlbmVyIGxpc3RlbmVyID0gbmV3IFRlc3RSZWdpc3RyeUNoYW5nZUxpc3RlbmVyKElDb250ZW50Q29uc3RhbnRzLkNPTlRFTlRfTkFNRSwgQ29udGVudFR5cGVCdWlsZGVyLlBUX0NPTlRFTlRUWVBFUywgbnVsbCwgbnVsbCk7CgkJQnVuZGxlVGVzdGluZ0hlbHBlci5ydW5XaXRoQnVuZGxlcygiMyIsICgpIC0+IHsKCQkJSUNvbnRlbnRUeXBlIGNvbnRlbnRUeXBlID0gbWFuYWdlci5nZXRDb250ZW50VHlwZSgib3JnLmVjbGlwc2UuYnVnNDg1MjI3LmJ1ZzQ4NTIyN19jb250ZW50VHlwZSIpOwoJCQlhc3NlcnROb3ROdWxsKCIzLjEgQ29udHJpYnV0ZWQgY29udGVudCB0eXBlIG5vdCBmb3VuZCIsIGNvbnRlbnRUeXBlKTsKCQkJLy8gZW5zdXJlIHRoZSBjb250ZW50IHR5cGUgaW5zdGFuY2VzIGFyZSBkaWZmZXJlbnQKCQkJdGV4dFsyXSA9IG1hbmFnZXIuZ2V0Q29udGVudFR5cGUoSUNvbnRlbnRUeXBlTWFuYWdlci5DVF9URVhUKTsKCQkJYXNzZXJ0Tm90TnVsbCgiMy4yIFRleHQgY29udGVudCB0eXBlIG5vdCBtb2RpZmllZCIsIHRleHRbMl0pOwoJCQl0ZXh0WzJdID0gKChDb250ZW50VHlwZUhhbmRsZXIpIHRleHRbMl0pLmdldFRhcmdldCgpOwoJCQlhc3NlcnRFcXVhbHMoIjMuMyIsIHRleHRbMF0sIHRleHRbMl0pOwoJCQlhc3NlcnRUcnVlKCIzLjQiLCB0ZXh0WzBdICE9IHRleHRbMl0pOwoJCQlhc3NlcnRFcXVhbHMoIjMuNSBkZWZhdWx0IGV4dGVuc2lvbiBub3QgYXNzb2NpYXRlZCIsIGNvbnRlbnRUeXBlLCBtYW5hZ2VyLmZpbmRDb250ZW50VHlwZUZvcigiZmlsZS5idWc0ODUyMjciKSk7CgkJCWFzc2VydEVxdWFscygiMy42IGFkZGl0aW9uYWwgZXh0ZW5zaW9uIG5vdCBhc3NvY2lhdGVkIiwgY29udGVudFR5cGUsIG1hbmFnZXIuZmluZENvbnRlbnRUeXBlRm9yKCJmaWxlLmJ1ZzQ4NTIyN18yIikpOwoJCX0sIGdldENvbnRleHQoKSwgbmV3IFN0cmluZ1tdIHtDb250ZW50VHlwZVRlc3QuVEVTVF9GSUxFU19ST09UICsgImNvbnRlbnQvYnVnNDg1MjI3In0sIGxpc3RlbmVyKTsKCQlhc3NlcnROdWxsKCI0LjAgQ29udGVudCB0eXBlIG5vdCBjbGVhcmVkIGFmdGVyIGJ1bmRsZSB1bmluc3RhbGwiLCBtYW5hZ2VyLmdldENvbnRlbnRUeXBlKCJvcmcuZWNsaXBzZS5idWc0ODUyMjcuYnVnNDg1MjI3X2NvbnRlbnRUeXBlIikpOwoJCS8vIGVuc3VyZSB0aGUgY29udGVudCB0eXBlIGluc3RhbmNlcyBhcmUgYWxsIGRpZmZlcmVudAoJCXRleHRbM10gPSBtYW5hZ2VyLmdldENvbnRlbnRUeXBlKElDb250ZW50VHlwZU1hbmFnZXIuQ1RfVEVYVCk7CgkJYXNzZXJ0Tm90TnVsbCgiNS4wIiwgdGV4dFszXSk7CgkJdGV4dFszXSA9ICgoQ29udGVudFR5cGVIYW5kbGVyKSB0ZXh0WzNdKS5nZXRUYXJnZXQoKTsKCQlhc3NlcnRFcXVhbHMoIjUuMSIsIHRleHRbMF0sIHRleHRbM10pOwoJCWFzc2VydEVxdWFscygiNS4yIiwgdGV4dFsyXSwgdGV4dFszXSk7CgkJYXNzZXJ0VHJ1ZSgiNS4zIiwgdGV4dFswXSAhPSB0ZXh0WzNdKTsKCQlhc3NlcnRUcnVlKCI1LjQiLCB0ZXh0WzJdICE9IHRleHRbM10pOwoJfQoKCXB1YmxpYyB2b2lkIHRlc3RFdmVudHMoKSB7CgkJSUNvbnRlbnRUeXBlTWFuYWdlciBjb250ZW50VHlwZU1hbmFnZXIgPSBQbGF0Zm9ybS5nZXRDb250ZW50VHlwZU1hbmFnZXIoKTsKCQlJQ29udGVudFR5cGUgbXlUeXBlID0gY29udGVudFR5cGVNYW5hZ2VyLmdldENvbnRlbnRUeXBlKFBJX1JFU09VUkNFU19URVNUUyArICIubXlDb250ZW50Iik7CgkJYXNzZXJ0Tm90TnVsbCgiMC45IiwgbXlUeXBlKTsKCgkJQ29udGVudFR5cGVDaGFuZ2VUcmFjZXIgdHJhY2VyOwoKCQl0cmFjZXIgPSBuZXcgQ29udGVudFR5cGVDaGFuZ2VUcmFjZXIoKTsKCQljb250ZW50VHlwZU1hbmFnZXIuYWRkQ29udGVudFR5cGVDaGFuZ2VMaXN0ZW5lcih0cmFjZXIpOwoKCQkvLyBhZGQgYSBmaWxlIHNwZWMgYW5kIGNoZWNrIGV2ZW50CgkJdHJ5IHsKCQkJbXlUeXBlLmFkZEZpbGVTcGVjKCJhbm90aGVyLmZpbGUubmFtZSIsIElDb250ZW50VHlwZS5GSUxFX05BTUVfU1BFQyk7CgkJfSBjYXRjaCAoQ29yZUV4Y2VwdGlvbiBlKSB7CgkJCWZhaWwoIjEuMCIsIGUpOwoJCX0KCQlhc3NlcnRUcnVlKCIxLjEiLCB0cmFjZXIuaXNPbmx5Q2hhbmdlKG15VHlwZSkpOwoKCQkvLyByZW1vdmUgYSBub24tZXhpc3RpbmcgZmlsZSBzcGVjIC0gc2hvdWxkIG5vdCBjYXVzZSBhbiBldmVudCB0byBiZSBmaXJlZAoJCXRyYWNlci5yZXNldCgpOwoJCXRyeSB7CgkJCW15VHlwZS5yZW1vdmVGaWxlU3BlYygiYW5vdGhlci5maWxlLm5hbWUiLCBJQ29udGVudFR5cGUuRklMRV9FWFRFTlNJT05fU1BFQyk7CgkJfSBjYXRjaCAoQ29yZUV4Y2VwdGlvbiBlKSB7CgkJCWZhaWwoIjIuMCIsIGUpOwoJCX0KCQlhc3NlcnRUcnVlKCIyLjEiLCAhdHJhY2VyLmlzT25seUNoYW5nZShteVR5cGUpKTsKCgkJLy8gYWRkIGEgZmlsZSBzcGVjIGFnYWluIGFuZCBjaGVjayBubyBldmVudCBpcyBnZW5lcmF0ZWQKCQl0cmFjZXIucmVzZXQoKTsKCQl0cnkgewoJCQlteVR5cGUuYWRkRmlsZVNwZWMoImFub3RoZXIuZmlsZS5uYW1lIiwgSUNvbnRlbnRUeXBlLkZJTEVfTkFNRV9TUEVDKTsKCQl9IGNhdGNoIChDb3JlRXhjZXB0aW9uIGUpIHsKCQkJZmFpbCgiMy4wIiwgZSk7CgkJfQoJCWFzc2VydFRydWUoIjMuMSIsICF0cmFjZXIuaXNPbmx5Q2hhbmdlKG15VHlwZSkpOwoKCQkvLyByZW1vdmUgYSBmaWxlIHNwZWMgYW5kIGNoZWNrIGV2ZW50CgkJdHJhY2VyLnJlc2V0KCk7CgkJdHJ5IHsKCQkJbXlUeXBlLnJlbW92ZUZpbGVTcGVjKCJhbm90aGVyLmZpbGUubmFtZSIsIElDb250ZW50VHlwZS5GSUxFX05BTUVfU1BFQyk7CgkJfSBjYXRjaCAoQ29yZUV4Y2VwdGlvbiBlKSB7CgkJCWZhaWwoIjQuMCIsIGUpOwoJCX0KCQlhc3NlcnRUcnVlKCI0LjEiLCB0cmFjZXIuaXNPbmx5Q2hhbmdlKG15VHlwZSkpOwoKCQkvLyBjaGFuZ2UgdGhlIGRlZmF1bHQgY2hhcnNldCBhbmQgY2hlY2sgZXZlbnQKCQl0cmFjZXIucmVzZXQoKTsKCQl0cnkgewoJCQlteVR5cGUuc2V0RGVmYXVsdENoYXJzZXQoIkZPTyIpOwoJCX0gY2F0Y2ggKENvcmVFeGNlcHRpb24gZSkgewoJCQlmYWlsKCI1LjAiLCBlKTsKCQl9CgkJYXNzZXJ0VHJ1ZSgiNS4xIiwgdHJhY2VyLmlzT25seUNoYW5nZShteVR5cGUpKTsKCgkJLy8gc2V0IHRoZSBkZWZhdWx0IGNoYXJzZXQgdG8gdGhlIHNhbWUgLSBubyBldmVudCBzaG91bGQgYmUgZ2VuZXJhdGVkCgkJdHJhY2VyLnJlc2V0KCk7CgkJdHJ5IHsKCQkJbXlUeXBlLnNldERlZmF1bHRDaGFyc2V0KCJGT08iKTsKCQl9IGNhdGNoIChDb3JlRXhjZXB0aW9uIGUpIHsKCQkJZmFpbCgiNi4wIiwgZSk7CgkJfQoJCWFzc2VydFRydWUoIjYuMSIsICF0cmFjZXIuaXNPbmx5Q2hhbmdlKG15VHlwZSkpOwoKCQl0cnkgewoJCQlteVR5cGUuc2V0RGVmYXVsdENoYXJzZXQoIkFCQyIpOwoJCX0gY2F0Y2ggKENvcmVFeGNlcHRpb24gZTEpIHsKCQkJZmFpbCgiNy4wIiwgZTEpOwoJCX0KCX0KCglwdWJsaWMgdm9pZCB0ZXN0RmlsZVNwZWNDb25mbGljdHMoKSB7CgkJSUNvbnRlbnRUeXBlTWFuYWdlciBtYW5hZ2VyID0gUGxhdGZvcm0uZ2V0Q29udGVudFR5cGVNYW5hZ2VyKCk7CgkJLy8gd2hlbiBub3Qgc3VibWl0dGluZyBjb250ZW50cywgZm9yIHJlbGF0ZWQgdHlwZXMsIG1vc3QgZ2VuZXJhbCB0eXBlIHByZXZhaWxzCgkJSUNvbnRlbnRUeXBlIGNvbmZsaWN0MWEgPSBtYW5hZ2VyLmdldENvbnRlbnRUeXBlKFBJX1JFU09VUkNFU19URVNUUyArICIuYmFzZV9jb25mbGljdDEiKTsKCQlJQ29udGVudFR5cGUgY29uZmxpY3QxYiA9IG1hbmFnZXIuZ2V0Q29udGVudFR5cGUoUElfUkVTT1VSQ0VTX1RFU1RTICsgIi5zdWJfY29uZmxpY3QxIik7CgkJYXNzZXJ0Tm90TnVsbCgiMS4wIiwgY29uZmxpY3QxYSk7CgkJYXNzZXJ0Tm90TnVsbCgiMS4xIiwgY29uZmxpY3QxYik7CgkJSUNvbnRlbnRUeXBlIHByZWZlcnJlZENvbmZsaWN0MSA9IG1hbmFnZXIuZmluZENvbnRlbnRUeXBlRm9yKCJ0ZXN0LmNvbmZsaWN0MSIpOwoJCWFzc2VydE5vdE51bGwoIjEuMiIsIHByZWZlcnJlZENvbmZsaWN0MSk7CgkJYXNzZXJ0RXF1YWxzKCIxLjMiLCBjb25mbGljdDFhLCBwcmVmZXJyZWRDb25mbGljdDEpOwoKCQlJQ29udGVudFR5cGUgY29uZmxpY3QyYmFzZSA9IG1hbmFnZXIuZ2V0Q29udGVudFR5cGUoUElfUkVTT1VSQ0VTX1RFU1RTICsgIi5iYXNlX2NvbmZsaWN0MiIpOwoJCUlDb250ZW50VHlwZSBjb25mbGljdDJzdWIgPSBtYW5hZ2VyLmdldENvbnRlbnRUeXBlKFBJX1JFU09VUkNFU19URVNUUyArICIuc3ViX2NvbmZsaWN0MiIpOwoJCWFzc2VydE5vdE51bGwoIjIuMCIsIGNvbmZsaWN0MmJhc2UpOwoJCWFzc2VydE5vdE51bGwoIjIuMSIsIGNvbmZsaWN0MnN1Yik7CgkJLy8gd2hlbiBzdWJtaXR0aW5nIGNvbnRlbnRzLCBmb3IgcmVsYXRlZCB0eXBlcywgZGVzY2VuZGFudCBjb21lcyBmaXJzdAoJCUlDb250ZW50VHlwZVtdIHNlbGVjdGVkQ29uZmxpY3QyOwoJCXRyeSB7CgkJCXNlbGVjdGVkQ29uZmxpY3QyID0gbWFuYWdlci5maW5kQ29udGVudFR5cGVzRm9yKGdldFJhbmRvbUNvbnRlbnRzKCksICJ0ZXN0LmNvbmZsaWN0MiIpOwoJCQlhc3NlcnRFcXVhbHMoIjIuMiIsIDIsIHNlbGVjdGVkQ29uZmxpY3QyLmxlbmd0aCk7CgkJCWFzc2VydEVxdWFscygiMi4zIiwgc2VsZWN0ZWRDb25mbGljdDJbMF0sIGNvbmZsaWN0MmJhc2UpOwoJCQlhc3NlcnRFcXVhbHMoIjIuNCIsIHNlbGVjdGVkQ29uZmxpY3QyWzFdLCBjb25mbGljdDJzdWIpOwoJCX0gY2F0Y2ggKElPRXhjZXB0aW9uIGUpIHsKCQkJZmFpbCgiMi41IiwgZSk7CgkJfQoKCQlJQ29udGVudFR5cGUgY29uZmxpY3QzYmFzZSA9IG1hbmFnZXIuZ2V0Q29udGVudFR5cGUoUElfUkVTT1VSQ0VTX1RFU1RTICsgIi5iYXNlX2NvbmZsaWN0MyIpOwoJCUlDb250ZW50VHlwZSBjb25mbGljdDNzdWIgPSBtYW5hZ2VyLmdldENvbnRlbnRUeXBlKFBJX1JFU09VUkNFU19URVNUUyArICIuc3ViX2NvbmZsaWN0MyIpOwoJCUlDb250ZW50VHlwZSBjb25mbGljdDN1bnJlbGF0ZWQgPSBtYW5hZ2VyLmdldENvbnRlbnRUeXBlKFBJX1JFU09VUkNFU19URVNUUyArICIudW5yZWxhdGVkX2NvbmZsaWN0MyIpOwoJCWFzc2VydE5vdE51bGwoIjMuMC4xIiwgY29uZmxpY3QzYmFzZSk7CgkJYXNzZXJ0Tm90TnVsbCgiMy4wLjIiLCBjb25mbGljdDNzdWIpOwoJCWFzc2VydE5vdE51bGwoIjMuMC4zIiwgY29uZmxpY3QzdW5yZWxhdGVkKTsKCgkJLy8gVHdvIHVucmVsYXRlZCB0eXBlcyAoc3ViX2NvbmZsaWN0MyBhbmQgdW5yZWxhdGVkIGNvbmZsaWN0MykgYXJlIGluIGNvbmZsaWN0LgoJCS8vIE9yZGVyIHdpbGwgYmUgYmFzZWQgb24gZGVwdGggKG1vcmUgZ2VuZXJhbCBmaXJzdCBzaW5jZSB0aGV5IGRvbid0IGhhdmUgZGVzY3JpYmVycykKCgkJSUNvbnRlbnRUeXBlW10gc2VsZWN0ZWRDb25mbGljdDM7CgkJdHJ5IHsKCQkJc2VsZWN0ZWRDb25mbGljdDMgPSBtYW5hZ2VyLmZpbmRDb250ZW50VHlwZXNGb3IoZ2V0UmFuZG9tQ29udGVudHMoKSwgInRlc3QuY29uZmxpY3QzIik7CgkJCWFzc2VydEVxdWFscygiNC4wIiwgMiwgc2VsZWN0ZWRDb25mbGljdDMubGVuZ3RoKTsKCQkJYXNzZXJ0RXF1YWxzKCI0LjEiLCBzZWxlY3RlZENvbmZsaWN0M1swXSwgY29uZmxpY3QzdW5yZWxhdGVkKTsKCQkJYXNzZXJ0RXF1YWxzKCI0LjIiLCBzZWxlY3RlZENvbmZsaWN0M1sxXSwgY29uZmxpY3Qzc3ViKTsKCQl9IGNhdGNoIChJT0V4Y2VwdGlvbiBlKSB7CgkJCWZhaWwoIjQuMyIsIGUpOwoJCX0KCX0KCglwdWJsaWMgdm9pZCB0ZXN0RmluZENvbnRlbnRUeXBlKCkgdGhyb3dzIFVuc3VwcG9ydGVkRW5jb2RpbmdFeGNlcHRpb24sIElPRXhjZXB0aW9uIHsKCQlJQ29udGVudFR5cGVNYW5hZ2VyIGNvbnRlbnRUeXBlTWFuYWdlciA9IFBsYXRmb3JtLmdldENvbnRlbnRUeXBlTWFuYWdlcigpOwoJCUlDb250ZW50VHlwZU1hdGNoZXIgZmluZGVyID0gY29udGVudFR5cGVNYW5hZ2VyLmdldE1hdGNoZXIobmV3IExvY2FsU2VsZWN0aW9uUG9saWN5KCksIG51bGwpOwoKCQlJQ29udGVudFR5cGUgdGV4dENvbnRlbnRUeXBlID0gY29udGVudFR5cGVNYW5hZ2VyLmdldENvbnRlbnRUeXBlKFBsYXRmb3JtLlBJX1JVTlRJTUUgKyAnLicgKyAidGV4dCIpOwoJCUlDb250ZW50VHlwZSB4bWxDb250ZW50VHlwZSA9IGNvbnRlbnRUeXBlTWFuYWdlci5nZXRDb250ZW50VHlwZShQbGF0Zm9ybS5QSV9SVU5USU1FICsgIi54bWwiKTsKCgkJSUNvbnRlbnRUeXBlIHNpbmdsZTsKCgkJc2luZ2xlID0gZmluZGVyLmZpbmRDb250ZW50VHlwZUZvcihnZXRJbnB1dFN0cmVhbSgiSnVzdCBhIHRlc3QiKSwgY2hhbmdlQ2FzZSgiZmlsZS50eHQiKSk7CgkJYXNzZXJ0Tm90TnVsbCgiMS4wIiwgc2luZ2xlKTsKCQlhc3NlcnRFcXVhbHMoIjEuMSIsIHRleHRDb250ZW50VHlwZSwgc2luZ2xlKTsKCgkJc2luZ2xlID0gZmluZGVyLmZpbmRDb250ZW50VHlwZUZvcihnZXRJbnB1dFN0cmVhbShYTUxfVVRGXzgsICJVVEYtOCIpLCBjaGFuZ2VDYXNlKCJmb28ueG1sIikpOwoJCWFzc2VydE5vdE51bGwoIjIuMCIsIHNpbmdsZSk7CgkJYXNzZXJ0RXF1YWxzKCIyLjEiLCB4bWxDb250ZW50VHlwZSwgc2luZ2xlKTsKCgkJSUNvbnRlbnRUeXBlW10gbXVsdGlwbGUgPSBmaW5kZXIuZmluZENvbnRlbnRUeXBlc0ZvcihnZXRJbnB1dFN0cmVhbShYTUxfVVRGXzgsICJVVEYtOCIpLCBudWxsKTsKCQlhc3NlcnRUcnVlKCIzLjAiLCBjb250YWlucyhtdWx0aXBsZSwgeG1sQ29udGVudFR5cGUpKTsKCX0KCglwdWJsaWMgdm9pZCB0ZXN0RmluZENvbnRlbnRUeXBQcmVkZWZpbmVkUmVnZXhwKCkgdGhyb3dzIFVuc3VwcG9ydGVkRW5jb2RpbmdFeGNlcHRpb24sIElPRXhjZXB0aW9uLCBDb3JlRXhjZXB0aW9uIHsKCQlJQ29udGVudFR5cGVNYW5hZ2VyIGNvbnRlbnRUeXBlTWFuYWdlciA9IFBsYXRmb3JtLmdldENvbnRlbnRUeXBlTWFuYWdlcigpOwoJCUlDb250ZW50VHlwZU1hdGNoZXIgZmluZGVyID0gY29udGVudFR5cGVNYW5hZ2VyLmdldE1hdGNoZXIobmV3IExvY2FsU2VsZWN0aW9uUG9saWN5KCksIG51bGwpOwoKCQlJQ29udGVudFR5cGUgdGFyZ2V0Q29udGVudFR5cGUgPSBjb250ZW50VHlwZU1hbmFnZXIuZ2V0Q29udGVudFR5cGUoIm9yZy5lY2xpcHNlLmNvcmUudGVzdHMucmVzb3VyY2VzLnByZWRlZmluZWRDb250ZW50VHlwZVdpdGhSZWdleHAiKTsKCQlhc3NlcnROb3ROdWxsKCJUYXJnZXQgY29udGVudC10eXBlIG5vdCBmb3VuZCIsIHRhcmdldENvbnRlbnRUeXBlKTsKCgkJSUNvbnRlbnRUeXBlIHNpbmdsZSA9IGZpbmRlci5maW5kQ29udGVudFR5cGVGb3IoZ2V0SW5wdXRTdHJlYW0oIkp1c3QgYSB0ZXN0IiksICJzb21lcHJlZGVmaW5lZENvbnRlbnRUeXBlV2l0aFJlZ2V4cEZpbGUiKTsKCQlhc3NlcnRFcXVhbHModGFyZ2V0Q29udGVudFR5cGUsIHNpbmdsZSk7CgkJc2luZ2xlID0gZmluZGVyLmZpbmRDb250ZW50VHlwZUZvcihnZXRJbnB1dFN0cmVhbSgiSnVzdCBhIHRlc3QiKSwgInNvbWVwcmVkZWZpbmVkQ29udGVudFR5cGVXaXRoUGF0dGVybkZpbGUiKTsKCQlhc3NlcnRFcXVhbHModGFyZ2V0Q29udGVudFR5cGUsIHNpbmdsZSk7CgkJc2luZ2xlID0gZmluZGVyLmZpbmRDb250ZW50VHlwZUZvcihnZXRJbnB1dFN0cmVhbSgiSnVzdCBhIHRlc3QiKSwgInNvbWVwcmVkZWZpbmVkQ29udGVudFR5cGVXaXRoV2lsZGNhcmRzRmlsZSIpOwoJCWFzc2VydEVxdWFscyh0YXJnZXRDb250ZW50VHlwZSwgc2luZ2xlKTsKCX0KCglwdWJsaWMgdm9pZCB0ZXN0RmluZENvbnRlbnRUeXBlVXNlclJlZ2V4cCgpIHRocm93cyBVbnN1cHBvcnRlZEVuY29kaW5nRXhjZXB0aW9uLCBJT0V4Y2VwdGlvbiwgQ29yZUV4Y2VwdGlvbiB7CgkJSUNvbnRlbnRUeXBlTWFuYWdlciBjb250ZW50VHlwZU1hbmFnZXIgPSBQbGF0Zm9ybS5nZXRDb250ZW50VHlwZU1hbmFnZXIoKTsKCQlJQ29udGVudFR5cGVNYXRjaGVyIGZpbmRlciA9IGNvbnRlbnRUeXBlTWFuYWdlci5nZXRNYXRjaGVyKG5ldyBMb2NhbFNlbGVjdGlvblBvbGljeSgpLCBudWxsKTsKCgkJSUNvbnRlbnRUeXBlIHRleHRDb250ZW50VHlwZSA9IGNvbnRlbnRUeXBlTWFuYWdlci5nZXRDb250ZW50VHlwZShQbGF0Zm9ybS5QSV9SVU5USU1FICsgJy4nICsgInRleHQiKTsKCgkJSUNvbnRlbnRUeXBlIHNpbmdsZSA9IGZpbmRlci5maW5kQ29udGVudFR5cGVGb3IoZ2V0SW5wdXRTdHJlYW0oIkp1c3QgYSB0ZXN0IiksICJzb21lVGV4dC51bmtub3duIik7CgkJYXNzZXJ0TnVsbCgiRmlsZSBwYXR0ZXJuIHVua25vd24gYXQgdGhhdCBwb2ludCIsIHNpbmdsZSk7CgoJCXRleHRDb250ZW50VHlwZS5hZGRGaWxlU3BlYygiKlRleHQqIiwgSUNvbnRlbnRUeXBlLkZJTEVfUEFUVEVSTl9TUEVDKTsKCQlzaW5nbGUgPSBmaW5kZXIuZmluZENvbnRlbnRUeXBlRm9yKGdldElucHV0U3RyZWFtKCJKdXN0IGEgdGVzdCIpLCAic29tZVRleHQudW5rbm93biIpOwoJCWFzc2VydEVxdWFscygiVGV4dCBjb250ZW50IHNob3VsZCBub3cgbWF0Y2ggKlRleHQqIGZpbGVzIiwgdGV4dENvbnRlbnRUeXBlLCBzaW5nbGUpOwoJfQoKCXB1YmxpYyB2b2lkIHRlc3RJbXBvcnRGaWxlQXNzb2NpYXRpb24oKSB0aHJvd3MgQ29yZUV4Y2VwdGlvbiB7CgkJSUNvbnRlbnRUeXBlTWFuYWdlciBjb250ZW50VHlwZU1hbmFnZXIgPSBQbGF0Zm9ybS5nZXRDb250ZW50VHlwZU1hbmFnZXIoKTsKCQlhc3NlcnROdWxsKGNvbnRlbnRUeXBlTWFuYWdlci5maW5kQ29udGVudFR5cGVGb3IoIiouYnVnMTIyMjE3IikpOwoJCUlQcmVmZXJlbmNlc1NlcnZpY2Ugc2VydmljZSA9IFBsYXRmb3JtLmdldFByZWZlcmVuY2VzU2VydmljZSgpOwoJCVN0cmluZyBwcmVmcyA9ICJmaWxlX2V4cG9ydF92ZXJzaW9uPTMuMFxuL2luc3RhbmNlL29yZy5lY2xpcHNlLmNvcmUucnVudGltZS9jb250ZW50LXR5cGVzL29yZy5lY2xpcHNlLmNvcmUucnVudGltZS54bWwvZmlsZS1leHRlbnNpb25zPWJ1ZzEyMjIxNyI7CgkJSUV4cG9ydGVkUHJlZmVyZW5jZXMgZXhwb3J0ZWQgPSBzZXJ2aWNlLnJlYWRQcmVmZXJlbmNlcyhuZXcgQnl0ZUFycmF5SW5wdXRTdHJlYW0ocHJlZnMuZ2V0Qnl0ZXMoKSkpOwoJCWFzc2VydFRydWUoc2VydmljZS5hcHBseVByZWZlcmVuY2VzKGV4cG9ydGVkKS5pc09LKCkpOwoJCWFzc2VydE5vdE51bGwoY29udGVudFR5cGVNYW5hZ2VyLmZpbmRDb250ZW50VHlwZUZvcigiKi5idWcxMjIyMTciKSk7Cgl9CgoJcHVibGljIHZvaWQgdGVzdEludmFsaWRNYXJrdXAoKSB7CgkJZmluYWwgSUNvbnRlbnRUeXBlTWFuYWdlciBjb250ZW50VHlwZU1hbmFnZXIgPSBQbGF0Zm9ybS5nZXRDb250ZW50VHlwZU1hbmFnZXIoKTsKCQlJQ29udGVudFR5cGVNYXRjaGVyIGZpbmRlciA9IGNvbnRlbnRUeXBlTWFuYWdlci5nZXRNYXRjaGVyKG5ldyBMb2NhbFNlbGVjdGlvblBvbGljeSgpLCBudWxsKTsKCQlhc3NlcnRFcXVhbHMoIjEuMCIsIDAsIGZpbmRlci5maW5kQ29udGVudFR5cGVzRm9yKCJpbnZhbGlkLm1pc3NpbmcuaWRlbnRpZmllciIpLmxlbmd0aCk7CgkJYXNzZXJ0RXF1YWxzKCIyLjAiLCAwLCBmaW5kZXIuZmluZENvbnRlbnRUeXBlc0ZvcigiaW52YWxpZC5taXNzaW5nLm5hbWUiKS5sZW5ndGgpOwoJCWFzc2VydE51bGwoIjMuMCIsIGNvbnRlbnRUeXBlTWFuYWdlci5nZXRDb250ZW50VHlwZShQSV9SRVNPVVJDRVNfVEVTVFMgKyAnLicgKyAiaW52YWxpZC1taXNzaW5nLW5hbWUiKSk7CgkJVGVzdFJlZ2lzdHJ5Q2hhbmdlTGlzdGVuZXIgbGlzdGVuZXIgPSBuZXcgVGVzdFJlZ2lzdHJ5Q2hhbmdlTGlzdGVuZXIoUGxhdGZvcm0uUElfUlVOVElNRSwgQ29udGVudFR5cGVCdWlsZGVyLlBUX0NPTlRFTlRUWVBFUywgbnVsbCwgbnVsbCk7CgkJQnVuZGxlVGVzdGluZ0hlbHBlci5ydW5XaXRoQnVuZGxlcygiMSIsICgpIC0+IHsKCQkJLy8gZW5zdXJlIHRoZSBpbnZhbGlkIGNvbnRlbnQgdHlwZXMgYXJlIG5vdCBhdmFpbGFibGUKCQkJYXNzZXJ0RXF1YWxzKCIxLjIiLCAwLCBjb250ZW50VHlwZU1hbmFnZXIuZmluZENvbnRlbnRUeXBlc0ZvcigiaW52YWxpZC5taXNzaW5nLmlkZW50aWZpZXIiKS5sZW5ndGgpOwoJCQlhc3NlcnRFcXVhbHMoIjEuMyIsIDAsIGNvbnRlbnRUeXBlTWFuYWdlci5maW5kQ29udGVudFR5cGVzRm9yKCJpbnZhbGlkLm1pc3NpbmcubmFtZSIpLmxlbmd0aCk7CgkJCWFzc2VydE51bGwoIjEuNCIsIGNvbnRlbnRUeXBlTWFuYWdlci5nZXRDb250ZW50VHlwZSgib3JnLmVjbGlwc2UuYnVuZGxlMDMuaW52YWxpZC1taXNzaW5nLW5hbWUiKSk7CgkJCS8vIHRoaXMgY29udGVudCB0eXBlIGhhcyBnb29kIG1hcmt1cCwgYnV0IGludmFsaWQgZGVzY3JpYmVyIGNsYXNzCgkJCUlDb250ZW50VHlwZSBpbnZhbGlkRGVzY3JpYmVyID0gY29udGVudFR5cGVNYW5hZ2VyLmdldENvbnRlbnRUeXBlKCJvcmcuZWNsaXBzZS5idW5kbGUwMy5pbnZhbGlkLWRlc2NyaWJlciIpOwoJCQlhc3NlcnROb3ROdWxsKCIxLjUiLCBpbnZhbGlkRGVzY3JpYmVyKTsKCQkJLy8gbmFtZSBiYXNlZCBtYXRjaGluZyBzaG91bGQgd29yayBmaW5lCgkJCWFzc2VydEVxdWFscygiMS42IiwgaW52YWxpZERlc2NyaWJlciwgY29udGVudFR5cGVNYW5hZ2VyLmZpbmRDb250ZW50VHlwZUZvcigiaW52YWxpZC5kZXNjcmliZXIiKSk7CgkJCXRyeSB7CgkJCQkvLyB0aGUgZGVzY3JpYmVyIGNsYXNzIGlzIGludmFsaWQsIGNvbnRlbnQgbWF0Y2hvbmcgc2hvdWxkIGZhaWwKCQkJCWFzc2VydE51bGwoIjEuNyIsIGNvbnRlbnRUeXBlTWFuYWdlci5maW5kQ29udGVudFR5cGVGb3IoZ2V0UmFuZG9tQ29udGVudHMoKSwgImludmFsaWQuZGVzY3JpYmVyIikpOwoJCQl9IGNhdGNoIChJT0V4Y2VwdGlvbiBlKSB7CgkJCQlmYWlsKCIxLjgiLCBlKTsKCQkJfQoJCX0sIGdldENvbnRleHQoKSwgbmV3IFN0cmluZ1tdIHtDb250ZW50VHlwZVRlc3QuVEVTVF9GSUxFU19ST09UICsgImNvbnRlbnQvYnVuZGxlMDMifSwgbGlzdGVuZXIpOwoJfQoKCS8qKgoJICogQnVncyA2Nzg0MSBhbmQgNjI0NDMKCSAqLwoJcHVibGljIHZvaWQgdGVzdElPRXhjZXB0aW9uKCkgewoJCUlDb250ZW50VHlwZU1hbmFnZXIgbWFuYWdlciA9IFBsYXRmb3JtLmdldENvbnRlbnRUeXBlTWFuYWdlcigpOwoJCUlDb250ZW50VHlwZSB4bWwgPSBtYW5hZ2VyLmdldENvbnRlbnRUeXBlKFBsYXRmb3JtLlBJX1JVTlRJTUUgKyAiLnhtbCIpOwoJCUlDb250ZW50VHlwZSByb290RWxlbWVudCA9IG1hbmFnZXIuZ2V0Q29udGVudFR5cGUoUElfUkVTT1VSQ0VTX1RFU1RTICsgIi5yb290LWVsZW1lbnQiKTsKCQlJQ29udGVudFR5cGVbXSBzZWxlY3RlZCA9IG51bGw7CgkJdHJ5IHsKCQkJc2VsZWN0ZWQgPSBtYW5hZ2VyLmZpbmRDb250ZW50VHlwZXNGb3IoZ2V0SW5wdXRTdHJlYW0oWE1MX1VTX0FTQ0lJX0lOVkFMSUQsICJJU08tODg1OS0xIiksICJ0ZXN0LnhtbCIpOwoJCX0gY2F0Y2ggKElPRXhjZXB0aW9uIGlvZSkgewoJCQkvLyBhIFNBWEV4Y2VwdGlvbiBpcyB1c3VhbGx5IGNhdWdodCAoYW5kIHNpbGVudGx5IGlnbm9yZWQpIGluIFhNTFJvb3RFbGVtZW50RGVzY3JpYmVyIGluIHRoZXNlIGNhc2VzCgkJCWZhaWwoIjEuMCIsIGlvZSk7CgkJfQoJCWFzc2VydFRydWUoIjEuMSIsIGNvbnRhaW5zKHNlbGVjdGVkLCB4bWwpKTsKCQlhc3NlcnRUcnVlKCIxLjIiLCBjb250YWlucyhzZWxlY3RlZCwgcm9vdEVsZW1lbnQpKTsKCgkJLy8gaW5kdWNlIHJlZ3VsYXIgSU9FeGNlcHRpb25zLi4uIHRoZXNlIHNob3VsZCBiZSB0aHJvd24gdG8gY2xpZW50cwoJCWNsYXNzIEZha2VJT0V4Y2VwdGlvbiBleHRlbmRzIElPRXhjZXB0aW9uIHsKCQkJLyoqCgkJCSAqIEFsbCBzZXJpYWxpemFibGUgb2JqZWN0cyBzaG91bGQgaGF2ZSBhIHN0YWJsZSBzZXJpYWxWZXJzaW9uVUlECgkJCSAqLwoJCQlwcml2YXRlIHN0YXRpYyBmaW5hbCBsb25nIHNlcmlhbFZlcnNpb25VSUQgPSAxTDsKCgkJCUBPdmVycmlkZQoJCQlwdWJsaWMgU3RyaW5nIGdldE1lc3NhZ2UoKSB7CgkJCQlyZXR1cm4gIlRoaXMgZXhjZXB0aW9uIHdhcyB0aHJvd24gZm9yIHRlc3RpbmcgcHVycG9zZXMiOwoJCQl9CgkJfQoJCXRyeSB7CgkJCXNlbGVjdGVkID0gbWFuYWdlci5maW5kQ29udGVudFR5cGVzRm9yKG5ldyBJbnB1dFN0cmVhbSgpIHsKCgkJCQlAT3ZlcnJpZGUKCQkJCXB1YmxpYyBpbnQgYXZhaWxhYmxlKCkgewoJCQkJCS8vIHRyaWNrIHRoZSBjbGllbnQgaW50byByZWFkaW5nIHRoZSBmaWxlCgkJCQkJcmV0dXJuIEludGVnZXIuTUFYX1ZBTFVFOwoJCQkJfQoKCQkJCUBPdmVycmlkZQoJCQkJcHVibGljIGludCByZWFkKCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKCQkJCQl0aHJvdyBuZXcgRmFrZUlPRXhjZXB0aW9uKCk7CgkJCQl9CgoJCQkJQE92ZXJyaWRlCgkJCQlwdWJsaWMgaW50IHJlYWQoYnl0ZVtdIGIsIGludCBvZmYsIGludCBsZW4pIHRocm93cyBJT0V4Y2VwdGlvbiB7CgkJCQkJdGhyb3cgbmV3IEZha2VJT0V4Y2VwdGlvbigpOwoJCQkJfQoJCQl9LCAidGVzdC54bWwiKTsKCQkJLy8gYW4gZXhjZXB0aW9uIHdpbGwgaGFwcGVuIHdoZW4gcmVhZGluZyB0aGUgc3RyZWFtLi4uIHNob3VsZCBiZSB0aHJvd24gdG8gdGhlIGNhbGxlcgoJCQlmYWlsKCIyLjAiKTsKCQl9IGNhdGNoIChGYWtlSU9FeGNlcHRpb24gZmlvZSkgewoJCQkvLyBzdWNlc3MKCQl9IGNhdGNoIChJT0V4Y2VwdGlvbiBpb2UpIHsKCQkJLy8gdGhpcyBzaG91bGQgbmV2ZXIgaGFwcGVuLCBidXQganVzdCBpbiBjYXNlLi4uCgkJCWZhaWwoIjIuMSIpOwoJCX0KCX0KCglwdWJsaWMgdm9pZCB0ZXN0SXNLaW5kT2YoKSB7CgkJSUNvbnRlbnRUeXBlTWFuYWdlciBjb250ZW50VHlwZU1hbmFnZXIgPSBQbGF0Zm9ybS5nZXRDb250ZW50VHlwZU1hbmFnZXIoKTsKCQlJQ29udGVudFR5cGUgdGV4dENvbnRlbnRUeXBlID0gY29udGVudFR5cGVNYW5hZ2VyLmdldENvbnRlbnRUeXBlKFBsYXRmb3JtLlBJX1JVTlRJTUUgKyAnLicgKyAidGV4dCIpOwoJCUlDb250ZW50VHlwZSB4bWxDb250ZW50VHlwZSA9IGNvbnRlbnRUeXBlTWFuYWdlci5nZXRDb250ZW50VHlwZShQbGF0Zm9ybS5QSV9SVU5USU1FICsgIi54bWwiKTsKCQlJQ29udGVudFR5cGUgeG1sQmFzZWREaWZmZXJlbnRFeHRlbnNpb25Db250ZW50VHlwZSA9IGNvbnRlbnRUeXBlTWFuYWdlci5nZXRDb250ZW50VHlwZShQSV9SRVNPVVJDRVNfVEVTVFMgKyAnLicgKyAieG1sLWJhc2VkLWRpZmZlcmVudC1leHRlbnNpb24iKTsKCQlJQ29udGVudFR5cGUgeG1sQmFzZWRTcGVjaWZpY05hbWVDb250ZW50VHlwZSA9IGNvbnRlbnRUeXBlTWFuYWdlci5nZXRDb250ZW50VHlwZShQSV9SRVNPVVJDRVNfVEVTVFMgKyAnLicgKyAieG1sLWJhc2VkLXNwZWNpZmljLW5hbWUiKTsKCQlJQ29udGVudFR5cGUgYmluYXJ5Q29udGVudFR5cGUgPSBjb250ZW50VHlwZU1hbmFnZXIuZ2V0Q29udGVudFR5cGUoUElfUkVTT1VSQ0VTX1RFU1RTICsgJy4nICsgInNhbXBsZS1iaW5hcnkxIik7CgkJYXNzZXJ0VHJ1ZSgiMS4wIiwgdGV4dENvbnRlbnRUeXBlLmlzS2luZE9mKHRleHRDb250ZW50VHlwZSkpOwoJCWFzc2VydFRydWUoIjIuMCIsIHhtbENvbnRlbnRUeXBlLmlzS2luZE9mKHRleHRDb250ZW50VHlwZSkpOwoJCWFzc2VydFRydWUoIjIuMSIsICF0ZXh0Q29udGVudFR5cGUuaXNLaW5kT2YoeG1sQ29udGVudFR5cGUpKTsKCQlhc3NlcnRUcnVlKCIyLjIiLCB4bWxDb250ZW50VHlwZS5pc0tpbmRPZih4bWxDb250ZW50VHlwZSkpOwoJCWFzc2VydFRydWUoIjMuMCIsIHhtbEJhc2VkRGlmZmVyZW50RXh0ZW5zaW9uQ29udGVudFR5cGUuaXNLaW5kT2YodGV4dENvbnRlbnRUeXBlKSk7CgkJYXNzZXJ0VHJ1ZSgiMy4xIiwgeG1sQmFzZWREaWZmZXJlbnRFeHRlbnNpb25Db250ZW50VHlwZS5pc0tpbmRPZih4bWxDb250ZW50VHlwZSkpOwoJCWFzc2VydFRydWUoIjQuMCIsICF4bWxCYXNlZERpZmZlcmVudEV4dGVuc2lvbkNvbnRlbnRUeXBlLmlzS2luZE9mKHhtbEJhc2VkU3BlY2lmaWNOYW1lQ29udGVudFR5cGUpKTsKCQlhc3NlcnRUcnVlKCI1LjAiLCAhYmluYXJ5Q29udGVudFR5cGUuaXNLaW5kT2YodGV4dENvbnRlbnRUeXBlKSk7Cgl9CgoJcHVibGljIHZvaWQgdGVzdExpc3RQYXJzaW5nKCkgewoJCVN0cmluZ1tdIGxpc3Q7CgkJbGlzdCA9IFV0aWwucGFyc2VJdGVtcyhudWxsKTsKCQlhc3NlcnRFcXVhbHMoIjAuMCIsIDAsIGxpc3QubGVuZ3RoKTsKCQlsaXN0ID0gVXRpbC5wYXJzZUl0ZW1zKCIiKTsKCQlhc3NlcnRFcXVhbHMoIjEuMCIsIDEsIGxpc3QubGVuZ3RoKTsKCQlhc3NlcnRFcXVhbHMoIjEuMSIsICIiLCBsaXN0WzBdKTsKCQlsaXN0ID0gVXRpbC5wYXJzZUl0ZW1zKCJmb28iKTsKCQlhc3NlcnRFcXVhbHMoIjIuMCIsIDEsIGxpc3QubGVuZ3RoKTsKCQlhc3NlcnRFcXVhbHMoIjIuMSIsICJmb28iLCBsaXN0WzBdKTsKCQlsaXN0ID0gVXRpbC5wYXJzZUl0ZW1zKCIsIik7CgkJYXNzZXJ0RXF1YWxzKCIzLjAiLCAyLCBsaXN0Lmxlbmd0aCk7CgkJYXNzZXJ0RXF1YWxzKCIzLjEiLCAiIiwgbGlzdFswXSk7CgkJYXNzZXJ0RXF1YWxzKCIzLjIiLCAiIiwgbGlzdFsxXSk7CgkJbGlzdCA9IFV0aWwucGFyc2VJdGVtcygiLGZvbyxiYXIiKTsKCQlhc3NlcnRFcXVhbHMoIjQuMCIsIDMsIGxpc3QubGVuZ3RoKTsKCQlhc3NlcnRFcXVhbHMoIjQuMSIsICIiLCBsaXN0WzBdKTsKCQlhc3NlcnRFcXVhbHMoIjQuMiIsICJmb28iLCBsaXN0WzFdKTsKCQlhc3NlcnRFcXVhbHMoIjQuMyIsICJiYXIiLCBsaXN0WzJdKTsKCQlsaXN0ID0gVXRpbC5wYXJzZUl0ZW1zKCJmb28sYmFyLCIpOwoJCWFzc2VydEVxdWFscygiNS4wIiwgMywgbGlzdC5sZW5ndGgpOwoJCWFzc2VydEVxdWFscygiNS4xIiwgImZvbyIsIGxpc3RbMF0pOwoJCWFzc2VydEVxdWFscygiNS4yIiwgImJhciIsIGxpc3RbMV0pOwoJCWFzc2VydEVxdWFscygiNS4zIiwgIiIsIGxpc3RbMl0pOwoJCWxpc3QgPSBVdGlsLnBhcnNlSXRlbXMoImZvbywsYmFyIik7CgkJYXNzZXJ0RXF1YWxzKCI2LjAiLCAzLCBsaXN0Lmxlbmd0aCk7CgkJYXNzZXJ0RXF1YWxzKCI2LjEiLCAiZm9vIiwgbGlzdFswXSk7CgkJYXNzZXJ0RXF1YWxzKCI2LjIiLCAiIiwgbGlzdFsxXSk7CgkJYXNzZXJ0RXF1YWxzKCI2LjMiLCAiYmFyIiwgbGlzdFsyXSk7CgkJbGlzdCA9IFV0aWwucGFyc2VJdGVtcygiZm9vLCwsYmFyIik7CgkJYXNzZXJ0RXF1YWxzKCI3LjAiLCA0LCBsaXN0Lmxlbmd0aCk7CgkJYXNzZXJ0RXF1YWxzKCI3LjEiLCAiZm9vIiwgbGlzdFswXSk7CgkJYXNzZXJ0RXF1YWxzKCI3LjIiLCAiIiwgbGlzdFsxXSk7CgkJYXNzZXJ0RXF1YWxzKCI3LjMiLCAiIiwgbGlzdFsyXSk7CgkJYXNzZXJ0RXF1YWxzKCI3LjQiLCAiYmFyIiwgbGlzdFszXSk7CgkJbGlzdCA9IFV0aWwucGFyc2VJdGVtcygiLCxmb28sYmFyIik7CgkJYXNzZXJ0RXF1YWxzKCI4LjAiLCA0LCBsaXN0Lmxlbmd0aCk7CgkJYXNzZXJ0RXF1YWxzKCI4LjEiLCAiIiwgbGlzdFswXSk7CgkJYXNzZXJ0RXF1YWxzKCI4LjIiLCAiIiwgbGlzdFsxXSk7CgkJYXNzZXJ0RXF1YWxzKCI4LjMiLCAiZm9vIiwgbGlzdFsyXSk7CgkJYXNzZXJ0RXF1YWxzKCI4LjQiLCAiYmFyIiwgbGlzdFszXSk7CgkJbGlzdCA9IFV0aWwucGFyc2VJdGVtcygiZm9vLGJhciwsIik7CgkJYXNzZXJ0RXF1YWxzKCI5LjAiLCA0LCBsaXN0Lmxlbmd0aCk7CgkJYXNzZXJ0RXF1YWxzKCI5LjEiLCAiZm9vIiwgbGlzdFswXSk7CgkJYXNzZXJ0RXF1YWxzKCI5LjIiLCAiYmFyIiwgbGlzdFsxXSk7CgkJYXNzZXJ0RXF1YWxzKCI5LjMiLCAiIiwgbGlzdFsyXSk7CgkJYXNzZXJ0RXF1YWxzKCI5LjQiLCAiIiwgbGlzdFszXSk7CgkJbGlzdCA9IFV0aWwucGFyc2VJdGVtcygiLCwsIik7CgkJYXNzZXJ0RXF1YWxzKCIxMC4wIiwgNCwgbGlzdC5sZW5ndGgpOwoJCWFzc2VydEVxdWFscygiMTAuMSIsICIiLCBsaXN0WzBdKTsKCQlhc3NlcnRFcXVhbHMoIjEwLjIiLCAiIiwgbGlzdFsxXSk7CgkJYXNzZXJ0RXF1YWxzKCIxMC4zIiwgIiIsIGxpc3RbMl0pOwoJCWFzc2VydEVxdWFscygiMTAuNCIsICIiLCBsaXN0WzNdKTsKCX0KCglwdWJsaWMgdm9pZCB0ZXN0TXlDb250ZW50RGVzY3JpYmVyKCkgdGhyb3dzIFVuc3VwcG9ydGVkRW5jb2RpbmdFeGNlcHRpb24sIElPRXhjZXB0aW9uIHsKCQlJQ29udGVudFR5cGVNYW5hZ2VyIG1hbmFnZXIgPSBQbGF0Zm9ybS5nZXRDb250ZW50VHlwZU1hbmFnZXIoKTsKCQlJQ29udGVudFR5cGUgbXlDb250ZW50ID0gbWFuYWdlci5nZXRDb250ZW50VHlwZShQSV9SRVNPVVJDRVNfVEVTVFMgKyAnLicgKyAibXlDb250ZW50Iik7CgkJYXNzZXJ0Tm90TnVsbCgiMC41IiwgbXlDb250ZW50KTsKCQlhc3NlcnRFcXVhbHMoIjAuNiIsIG15Q29udGVudCwgbWFuYWdlci5maW5kQ29udGVudFR5cGVGb3IoIm15Q29udGVudC5tYzEiKSk7CgkJYXNzZXJ0RXF1YWxzKCIwLjciLCBteUNvbnRlbnQsIG1hbmFnZXIuZmluZENvbnRlbnRUeXBlRm9yKCJteUNvbnRlbnQubWMyIikpOwoJCWFzc2VydEVxdWFscygiMC44IiwgbXlDb250ZW50LCBtYW5hZ2VyLmZpbmRDb250ZW50VHlwZUZvcigiZm9vLm15Q29udGVudDEiKSk7CgkJYXNzZXJ0RXF1YWxzKCIwLjkiLCBteUNvbnRlbnQsIG1hbmFnZXIuZmluZENvbnRlbnRUeXBlRm9yKCJiYXIubXlDb250ZW50MiIpKTsKCQlJQ29udGVudERlc2NyaXB0aW9uIGRlc2NyaXB0aW9uID0gbWFuYWdlci5nZXREZXNjcmlwdGlvbkZvcihnZXRJbnB1dFN0cmVhbShNeUNvbnRlbnREZXNjcmliZXIuU0lHTkFUVVJFLCAiVVMtQVNDSUkiKSwgIm15Q29udGVudC5tYzEiLCBJQ29udGVudERlc2NyaXB0aW9uLkFMTCk7CgkJYXNzZXJ0Tm90TnVsbCgiMS4wIiwgZGVzY3JpcHRpb24pOwoJCWFzc2VydEVxdWFscygiMS4xIiwgbXlDb250ZW50LCBkZXNjcmlwdGlvbi5nZXRDb250ZW50VHlwZSgpKTsKCQlhc3NlcnROb3RTYW1lKCIxLjIiLCBteUNvbnRlbnQuZ2V0RGVmYXVsdERlc2NyaXB0aW9uKCksIGRlc2NyaXB0aW9uKTsKCQlmb3IgKGludCBpID0gMDsgaSA8IE15Q29udGVudERlc2NyaWJlci5NWV9PUFRJT05TLmxlbmd0aDsgaSsrKSB7CgkJCWFzc2VydEVxdWFscygiMi4iICsgaSwgTXlDb250ZW50RGVzY3JpYmVyLk1ZX09QVElPTl9WQUxVRVNbaV0sIGRlc2NyaXB0aW9uLmdldFByb3BlcnR5KE15Q29udGVudERlc2NyaWJlci5NWV9PUFRJT05TW2ldKSk7CgkJfQoJfQoKCXB1YmxpYyB2b2lkIHRlc3ROb0V4dGVuc2lvbkFzc29jaWF0aW9uKCkgewoJCS8vVE9ETyB1c2UgYSBJQ29udGVudFR5cGVNYXRjaGVyIGluc3RlYWQKCQlmaW5hbCBJQ29udGVudFR5cGVNYW5hZ2VyIG1hbmFnZXIgPSBQbGF0Zm9ybS5nZXRDb250ZW50VHlwZU1hbmFnZXIoKTsKCgkJSUNvbnRlbnRUeXBlW10gc2VsZWN0ZWQgPSBtYW5hZ2VyLmZpbmRDb250ZW50VHlwZXNGb3IoImZpbGVfd2l0aF9ub19leHRlbnNpb24iKTsKCQlhc3NlcnRFcXVhbHMoIjAuMSIsIDAsIHNlbGVjdGVkLmxlbmd0aCk7CgoJCVRlc3RSZWdpc3RyeUNoYW5nZUxpc3RlbmVyIGxpc3RlbmVyID0gbmV3IFRlc3RSZWdpc3RyeUNoYW5nZUxpc3RlbmVyKFBsYXRmb3JtLlBJX1JVTlRJTUUsIENvbnRlbnRUeXBlQnVpbGRlci5QVF9DT05URU5UVFlQRVMsIG51bGwsIG51bGwpOwoJCUJ1bmRsZVRlc3RpbmdIZWxwZXIucnVuV2l0aEJ1bmRsZXMoIjEiLCAoKSAtPiB7CgkJCWZpbmFsIFN0cmluZyBuYW1lc3BhY2UgPSAib3JnLmVjbGlwc2UuYnVuZGxlMDQiOwoKCQkJSUNvbnRlbnRUeXBlIGVtcHR5MSA9IG1hbmFnZXIuZ2V0Q29udGVudFR5cGUobmFtZXNwYWNlICsgIi5lbXB0eV9leHRlbnNpb24xIik7CgkJCUlDb250ZW50VHlwZSBlbXB0eTIgPSBtYW5hZ2VyLmdldENvbnRlbnRUeXBlKG5hbWVzcGFjZSArICIuZW1wdHlfZXh0ZW5zaW9uMiIpOwoJCQlJQ29udGVudFR5cGUgZW1wdHkzID0gbWFuYWdlci5nZXRDb250ZW50VHlwZShuYW1lc3BhY2UgKyAiLmVtcHR5X2V4dGVuc2lvbjMiKTsKCQkJSUNvbnRlbnRUeXBlIGVtcHR5NCA9IG1hbmFnZXIuZ2V0Q29udGVudFR5cGUobmFtZXNwYWNlICsgIi5lbXB0eV9leHRlbnNpb240Iik7CgkJCUlDb250ZW50VHlwZSBub25FbXB0eSA9IG1hbmFnZXIuZ2V0Q29udGVudFR5cGUobmFtZXNwYWNlICsgIi5ub25fZW1wdHlfZXh0ZW5zaW9uIik7CgoJCQlhc3NlcnROb3ROdWxsKCIxLjEuMSIsIGVtcHR5MSk7CgkJCWFzc2VydE5vdE51bGwoIjEuMS4yIiwgZW1wdHkyKTsKCQkJYXNzZXJ0Tm90TnVsbCgiMS4xLjMiLCBlbXB0eTMpOwoJCQlhc3NlcnROb3ROdWxsKCIxLjEuNCIsIGVtcHR5NCk7CgkJCWFzc2VydE5vdE51bGwoIjEuMS41Iiwgbm9uRW1wdHkpOwoKCQkJSUNvbnRlbnRUeXBlW10gc2VsZWN0ZWQxID0gbWFuYWdlci5maW5kQ29udGVudFR5cGVzRm9yKCJmaWxlX3dpdGhfbm9fZXh0ZW5zaW9uIik7CgkJCWFzc2VydEVxdWFscygiMS4yLjAiLCA0LCBzZWxlY3RlZDEubGVuZ3RoKTsKCQkJYXNzZXJ0VHJ1ZSgiMS4yLjEiLCBjb250YWlucyhzZWxlY3RlZDEsIGVtcHR5MSkpOwoJCQlhc3NlcnRUcnVlKCIxLjIuMiIsIGNvbnRhaW5zKHNlbGVjdGVkMSwgZW1wdHkyKSk7CgkJCWFzc2VydFRydWUoIjEuMi4zIiwgY29udGFpbnMoc2VsZWN0ZWQxLCBlbXB0eTMpKTsKCQkJYXNzZXJ0VHJ1ZSgiMS4yLjQiLCBjb250YWlucyhzZWxlY3RlZDEsIGVtcHR5NCkpOwoKCQkJc2VsZWN0ZWQxID0gbWFuYWdlci5maW5kQ29udGVudFR5cGVzRm9yKCJmaWxlX3dpdGhfZXh0ZW5zaW9uLm5vbi1lbXB0eSIpOwoJCQlhc3NlcnRFcXVhbHMoIjEuMi41IiwgMSwgc2VsZWN0ZWQxLmxlbmd0aCk7CgkJCWFzc2VydFRydWUoIjEuMi42IiwgY29udGFpbnMoc2VsZWN0ZWQxLCBub25FbXB0eSkpOwoKCQkJdHJ5IHsKCQkJCW5vbkVtcHR5LmFkZEZpbGVTcGVjKCIiLCBJQ29udGVudFR5cGUuRklMRV9FWFRFTlNJT05fU1BFQyk7CgkJCX0gY2F0Y2ggKENvcmVFeGNlcHRpb24gZTEpIHsKCQkJCWZhaWwoIjEuMy4wIiwgZTEpOwoJCQl9CgkJCXRyeSB7CgkJCQlzZWxlY3RlZDEgPSBtYW5hZ2VyLmZpbmRDb250ZW50VHlwZXNGb3IoImZpbGVfd2l0aF9ub19leHRlbnNpb24iKTsKCQkJCWFzc2VydEVxdWFscygiMS4zLjEiLCA1LCBzZWxlY3RlZDEubGVuZ3RoKTsKCQkJCWFzc2VydFRydWUoIjEuMy4yIiwgY29udGFpbnMoc2VsZWN0ZWQxLCBub25FbXB0eSkpOwoJCQl9IGZpbmFsbHkgewoJCQkJdHJ5IHsKCQkJCQlub25FbXB0eS5yZW1vdmVGaWxlU3BlYygiIiwgSUNvbnRlbnRUeXBlLkZJTEVfRVhURU5TSU9OX1NQRUMpOwoJCQkJfSBjYXRjaCAoQ29yZUV4Y2VwdGlvbiBlMikgewoJCQkJCWZhaWwoIjEuMy4zIiwgZTIpOwoJCQkJfQoJCQl9CgkJCXNlbGVjdGVkMSA9IG1hbmFnZXIuZmluZENvbnRlbnRUeXBlc0ZvcigiZmlsZV93aXRoX25vX2V4dGVuc2lvbiIpOwoJCQlhc3NlcnRFcXVhbHMoIjEuNC4wIiwgNCwgc2VsZWN0ZWQxLmxlbmd0aCk7CgkJCWFzc2VydFRydWUoIjEuNC4xIiwgIWNvbnRhaW5zKHNlbGVjdGVkMSwgbm9uRW1wdHkpKTsKCQl9LCBnZXRDb250ZXh0KCksIG5ldyBTdHJpbmdbXSB7Q29udGVudFR5cGVUZXN0LlRFU1RfRklMRVNfUk9PVCArICJjb250ZW50L2J1bmRsZTA0In0sIGxpc3RlbmVyKTsKCX0KCglwdWJsaWMgdm9pZCB0ZXN0T3JkZXJXaXRoRW1wdHlGaWxlcygpIHRocm93cyBJT0V4Y2VwdGlvbiB7CgkJSUNvbnRlbnRUeXBlTWFuYWdlciBtYW5hZ2VyID0gUGxhdGZvcm0uZ2V0Q29udGVudFR5cGVNYW5hZ2VyKCk7CgkJSUNvbnRlbnRUeXBlTWF0Y2hlciBmaW5kZXIgPSBtYW5hZ2VyLmdldE1hdGNoZXIobmV3IExvY2FsU2VsZWN0aW9uUG9saWN5KCksIG51bGwpOwoKCQlJQ29udGVudFR5cGUgeG1sID0gbWFuYWdlci5nZXRDb250ZW50VHlwZShQbGF0Zm9ybS5QSV9SVU5USU1FICsgIi54bWwiKTsKCQltYW5hZ2VyLmdldENvbnRlbnRUeXBlKFBJX1JFU09VUkNFU19URVNUUyArICIucm9vdC1lbGVtZW50Iik7CgkJbWFuYWdlci5nZXRDb250ZW50VHlwZShQSV9SRVNPVVJDRVNfVEVTVFMgKyAiLmR0ZCIpOwoJCS8vIGZvciBhbiBlbXB0eSBmaWxlLCB0aGUgbW9zdCBnZW5lcmljIGNvbnRlbnQgdHlwZSBzaG91bGQgYmUgcmV0dXJuZWQKCQlJQ29udGVudFR5cGUgc2VsZWN0ZWQgPSBmaW5kZXIuZmluZENvbnRlbnRUeXBlRm9yKGdldElucHV0U3RyZWFtKCIiKSwgImZvby54bWwiKTsKCQlhc3NlcnRFcXVhbHMoIjEuMCIsIHhtbCwgc2VsZWN0ZWQpOwoJCS8vIGl0IHNob3VsZCBiZSBlcXVpdmFsZW50IHRvIG9taXR0aW5nIHRoZSBjb250ZW50cwoJCWFzc2VydEVxdWFscygiMS4xIiwgeG1sLCBmaW5kZXIuZmluZENvbnRlbnRUeXBlRm9yKCJmb28ueG1sIikpOwoJfQoKCS8qKgoJICogVGhpcyB0ZXN0IHNob3dzIGhvdyB3ZSBkZWFsIHdpdGggb3JwaGFuIGZpbGUgYXNzb2NpYXRpb25zIChhc3NvY2lhdGlvbnMKCSAqIHdob3NlIGNvbnRlbnQgdHlwZXMgYXJlIG1pc3NpbmcpLgoJICovCglwdWJsaWMgdm9pZCB0ZXN0T3JwaGFuQ29udGVudFR5cGUoKSB7CgkJZmluYWwgSUNvbnRlbnRUeXBlTWFuYWdlciBjb250ZW50VHlwZU1hbmFnZXIgPSBQbGF0Zm9ybS5nZXRDb250ZW50VHlwZU1hbmFnZXIoKTsKCQlJQ29udGVudFR5cGUgb3JwaGFuID0gY29udGVudFR5cGVNYW5hZ2VyLmdldENvbnRlbnRUeXBlKFBJX1JFU09VUkNFU19URVNUUyArICIub3JwaGFuIik7CgkJYXNzZXJ0TnVsbCgiMC44Iiwgb3JwaGFuKTsKCQlJQ29udGVudFR5cGUgbWlzc2luZyA9IGNvbnRlbnRUeXBlTWFuYWdlci5nZXRDb250ZW50VHlwZSgib3JnLmVjbGlwc2UuYnVuZGxlMDEubWlzc2luZyIpOwoJCWFzc2VydE51bGwoIjAuOSIsIG1pc3NpbmcpOwoJCWFzc2VydEVxdWFscygiMS4xIiwgMCwgY29udGVudFR5cGVNYW5hZ2VyLmZpbmRDb250ZW50VHlwZXNGb3IoImZvby5vcnBoYW4iKS5sZW5ndGgpOwoJCWFzc2VydEVxdWFscygiMS4yIiwgMCwgY29udGVudFR5cGVNYW5hZ2VyLmZpbmRDb250ZW50VHlwZXNGb3IoIm9ycGhhbi5vcnBoYW4iKS5sZW5ndGgpOwoJCWFzc2VydEVxdWFscygiMS4zIiwgMCwgY29udGVudFR5cGVNYW5hZ2VyLmZpbmRDb250ZW50VHlwZXNGb3IoImZvby5vcnBoYW4yIikubGVuZ3RoKTsKCgkJLy90ZXN0IGxhdGUgYWRkaXRpb24gb2YgY29udGVudCB0eXBlIC0gb3JwaGFuMiBzaG91bGQgYmVjb21lIHZpc2libGUKCQlUZXN0UmVnaXN0cnlDaGFuZ2VMaXN0ZW5lciBsaXN0ZW5lciA9IG5ldyBUZXN0UmVnaXN0cnlDaGFuZ2VMaXN0ZW5lcihQbGF0Zm9ybS5QSV9SVU5USU1FLCBDb250ZW50VHlwZUJ1aWxkZXIuUFRfQ09OVEVOVFRZUEVTLCBudWxsLCBudWxsKTsKCgkJQnVuZGxlVGVzdGluZ0hlbHBlci5ydW5XaXRoQnVuZGxlcygiMiIsICgpIC0+IHsKCQkJSUNvbnRlbnRUeXBlIG9ycGhhbjEgPSBjb250ZW50VHlwZU1hbmFnZXIuZ2V0Q29udGVudFR5cGUoUElfUkVTT1VSQ0VTX1RFU1RTICsgIi5vcnBoYW4iKTsKCQkJYXNzZXJ0Tm90TnVsbCgiMi4xIiwgb3JwaGFuMSk7CgkJCUlDb250ZW50VHlwZSBtaXNzaW5nMSA9IGNvbnRlbnRUeXBlTWFuYWdlci5nZXRDb250ZW50VHlwZSgib3JnLmVjbGlwc2UuYnVuZGxlMDEubWlzc2luZyIpOwoJCQlhc3NlcnROb3ROdWxsKCIyLjIiLCBtaXNzaW5nMSk7CgkJCS8vIGNoZWNrcyBvcnBoYW4ncyBhc3NvY2lhdGlvbnMKCQkJYXNzZXJ0RXF1YWxzKCIyLjMiLCAxLCBjb250ZW50VHlwZU1hbmFnZXIuZmluZENvbnRlbnRUeXBlc0ZvcigiZm9vLm9ycGhhbiIpLmxlbmd0aCk7CgkJCWFzc2VydEVxdWFscygiMi40Iiwgb3JwaGFuMSwgY29udGVudFR5cGVNYW5hZ2VyLmZpbmRDb250ZW50VHlwZXNGb3IoImZvby5vcnBoYW4iKVswXSk7CgkJCWFzc2VydEVxdWFscygiMi41IiwgMSwgY29udGVudFR5cGVNYW5hZ2VyLmZpbmRDb250ZW50VHlwZXNGb3IoIm9ycGhhbi5vcnBoYW4iKS5sZW5ndGgpOwoJCQlhc3NlcnRFcXVhbHMoIjIuNiIsIG9ycGhhbjEsIGNvbnRlbnRUeXBlTWFuYWdlci5maW5kQ29udGVudFR5cGVzRm9yKCJmb28ub3JwaGFuIilbMF0pOwoJCQkvLyBjaGVjayB3aGV0aGVyIGFuIG9ycGhhbiBhc3NvY2lhdGlvbiB3YXMgYWRkZWQgdG8gdGhlIGR5bmFtaWNhbGx5IGFkZGVkIGJ1bmRsZQoJCQlhc3NlcnRFcXVhbHMoIjIuNyIsIDEsIGNvbnRlbnRUeXBlTWFuYWdlci5maW5kQ29udGVudFR5cGVzRm9yKCJmb28ub3JwaGFuMiIpLmxlbmd0aCk7CgkJCWFzc2VydEVxdWFscygiMi44IiwgbWlzc2luZzEsIGNvbnRlbnRUeXBlTWFuYWdlci5maW5kQ29udGVudFR5cGVzRm9yKCJmb28ub3JwaGFuMiIpWzBdKTsKCQl9LCBnZXRDb250ZXh0KCksIG5ldyBTdHJpbmdbXSB7Q29udGVudFR5cGVUZXN0LlRFU1RfRklMRVNfUk9PVCArICJjb250ZW50L2J1bmRsZTAxIn0sIGxpc3RlbmVyKTsKCX0KCgkvKioKCSAqIFJlZ3Jlc3Npb24gdGVzdCBmb3IgYnVnIDY4ODk0CgkgKi8KCXB1YmxpYyB2b2lkIHRlc3RQcmVmZXJlbmNlcygpIHRocm93cyBDb3JlRXhjZXB0aW9uLCBCYWNraW5nU3RvcmVFeGNlcHRpb24gewoJCUlDb250ZW50VHlwZU1hbmFnZXIgbWFuYWdlciA9IFBsYXRmb3JtLmdldENvbnRlbnRUeXBlTWFuYWdlcigpOwoJCUlDb250ZW50VHlwZSB0ZXh0ID0gbWFuYWdlci5nZXRDb250ZW50VHlwZShJQ29udGVudFR5cGVNYW5hZ2VyLkNUX1RFWFQpOwoJCVByZWZlcmVuY2VzIHRleHRQcmVmcyA9IEluc3RhbmNlU2NvcGUuSU5TVEFOQ0UuZ2V0Tm9kZShDb250ZW50VHlwZU1hbmFnZXIuQ09OVEVOVF9UWVBFX1BSRUZfTk9ERSkubm9kZSh0ZXh0LmdldElkKCkpOwoJCWFzc2VydE5vdE51bGwoIjAuMSIsIHRleHQpOwoKCQkvLyBlbnN1cmUgdGhlICJkZWZhdWx0IGNoYXJzZXQiIHByZWZlcmVuY2UgaXMgYmVpbmcgcHJvcGVybHkgdXNlZAoJCWFzc2VydE51bGwoIjEuMCIsIHRleHQuZ2V0RGVmYXVsdENoYXJzZXQoKSk7CgkJYXNzZXJ0TnVsbCgiMS4xIiwgdGV4dFByZWZzLmdldChDb250ZW50VHlwZS5QUkVGX0RFRkFVTFRfQ0hBUlNFVCwgbnVsbCkpOwoJCXRleHQuc2V0RGVmYXVsdENoYXJzZXQoIlVURi04Iik7CgkJYXNzZXJ0RXF1YWxzKCIxLjIiLCAiVVRGLTgiLCB0ZXh0UHJlZnMuZ2V0KENvbnRlbnRUeXBlLlBSRUZfREVGQVVMVF9DSEFSU0VULCBudWxsKSk7CgkJdGV4dC5zZXREZWZhdWx0Q2hhcnNldChudWxsKTsKCQlhc3NlcnROdWxsKCIxLjMiLCB0ZXh0UHJlZnMuZ2V0KENvbnRlbnRUeXBlLlBSRUZfREVGQVVMVF9DSEFSU0VULCBudWxsKSk7CgoJCS8vIGVuc3VyZSB0aGUgZmlsZSBzcGVjIHByZWZlcmVuY2VzIGFyZSBiZWluZyBwcm9wZXJseSB1c2VkCgkJLy8gc29tZSBzYW5pdHkgY2hlY2tpbmcKCQlhc3NlcnRGYWxzZSgiMi4wMSIsIHRleHQuaXNBc3NvY2lhdGVkV2l0aCgieHl6LmZvbyIpKTsKCQlhc3NlcnRGYWxzZSgiMi4wMSIsIHRleHQuaXNBc3NvY2lhdGVkV2l0aCgieHl6LmJhciIpKTsKCQlhc3NlcnRGYWxzZSgiMi4wMyIsIHRleHQuaXNBc3NvY2lhdGVkV2l0aCgiZm9vLmV4dCIpKTsKCQlhc3NlcnRGYWxzZSgiMi4wNCIsIHRleHQuaXNBc3NvY2lhdGVkV2l0aCgiYmFyLmV4dCIpKTsKCQkvL051bGwgZW50cmllcyBmaXJzdCB0byBhdm9pZCBpbnRlcmZlcmVuY2UgZnJvbSBvdGhlciB0ZXN0cwoJCXRleHRQcmVmcy5yZW1vdmUoQ29udGVudFR5cGUuUFJFRl9GSUxFX05BTUVTKTsKCQl0ZXh0UHJlZnMucmVtb3ZlKENvbnRlbnRUeXBlLlBSRUZfRklMRV9FWFRFTlNJT05TKTsKCQkvLyBwbGF5IHdpdGggZmlsZSBuYW1lIGFzc29jaWF0aW9ucyBmaXJzdC4uLgoJCWFzc2VydE51bGwoIjIuMGEiLCB0ZXh0UHJlZnMuZ2V0KENvbnRlbnRUeXBlLlBSRUZfRklMRV9OQU1FUywgbnVsbCkpOwoJCWFzc2VydE51bGwoIjIuMGIiLCB0ZXh0UHJlZnMuZ2V0KENvbnRlbnRUeXBlLlBSRUZfRklMRV9FWFRFTlNJT05TLCBudWxsKSk7CgkJdGV4dC5hZGRGaWxlU3BlYygiZm9vLmV4dCIsIElDb250ZW50VHlwZS5GSUxFX05BTUVfU1BFQyk7CgkJYXNzZXJ0VHJ1ZSgiMi4xIiwgdGV4dC5pc0Fzc29jaWF0ZWRXaXRoKCJmb28uZXh0IikpOwoJCWFzc2VydEVxdWFscygiMi4yIiwgImZvby5leHQiLCB0ZXh0UHJlZnMuZ2V0KENvbnRlbnRUeXBlLlBSRUZfRklMRV9OQU1FUywgbnVsbCkpOwoJCXRleHQuYWRkRmlsZVNwZWMoImJhci5leHQiLCBJQ29udGVudFR5cGUuRklMRV9OQU1FX1NQRUMpOwoJCWFzc2VydFRydWUoIjIuMyIsIHRleHQuaXNBc3NvY2lhdGVkV2l0aCgiYmFyLmV4dCIpKTsKCQlhc3NlcnRFcXVhbHMoIjIuNCIsICJmb28uZXh0LGJhci5leHQiLCB0ZXh0UHJlZnMuZ2V0KENvbnRlbnRUeXBlLlBSRUZfRklMRV9OQU1FUywgbnVsbCkpOwoJCS8vIC4uLiBhbmQgdGhlbiB3aXRoIGZpbGUgZXh0ZW5zaW9ucwoJCXRleHQuYWRkRmlsZVNwZWMoImZvbyIsIElDb250ZW50VHlwZS5GSUxFX0VYVEVOU0lPTl9TUEVDKTsKCQlhc3NlcnRUcnVlKCIyLjUiLCB0ZXh0LmlzQXNzb2NpYXRlZFdpdGgoInh5ei5mb28iKSk7CgkJYXNzZXJ0RXF1YWxzKCIyLjYiLCAiZm9vIiwgdGV4dFByZWZzLmdldChDb250ZW50VHlwZS5QUkVGX0ZJTEVfRVhURU5TSU9OUywgbnVsbCkpOwoJCXRleHQuYWRkRmlsZVNwZWMoImJhciIsIElDb250ZW50VHlwZS5GSUxFX0VYVEVOU0lPTl9TUEVDKTsKCQlhc3NlcnRUcnVlKCIyLjciLCB0ZXh0LmlzQXNzb2NpYXRlZFdpdGgoInh5ei5iYXIiKSk7CgkJYXNzZXJ0RXF1YWxzKCIyLjQiLCAiZm9vLGJhciIsIHRleHRQcmVmcy5nZXQoQ29udGVudFR5cGUuUFJFRl9GSUxFX0VYVEVOU0lPTlMsIG51bGwpKTsKCQkvLyByZW1vdmUgYWxsIGFzc29jaWF0aW9ucyBtYWRlCgkJdGV4dC5yZW1vdmVGaWxlU3BlYygiZm9vLmV4dCIsIElDb250ZW50VHlwZS5GSUxFX05BTUVfU1BFQyk7CgkJdGV4dC5yZW1vdmVGaWxlU3BlYygiYmFyLmV4dCIsIElDb250ZW50VHlwZS5GSUxFX05BTUVfU1BFQyk7CgkJdGV4dC5yZW1vdmVGaWxlU3BlYygiZm9vIiwgSUNvbnRlbnRUeXBlLkZJTEVfRVhURU5TSU9OX1NQRUMpOwoJCXRleHQucmVtb3ZlRmlsZVNwZWMoImJhciIsIElDb250ZW50VHlwZS5GSUxFX0VYVEVOU0lPTl9TUEVDKTsKCQkvLyBlbnN1cmUgYWxsIGlzIGFzIGJlZm9yZQoJCWFzc2VydEZhbHNlKCIzLjEiLCB0ZXh0LmlzQXNzb2NpYXRlZFdpdGgoInh5ei5mb28iKSk7CgkJYXNzZXJ0RmFsc2UoIjMuMiIsIHRleHQuaXNBc3NvY2lhdGVkV2l0aCgieHl6LmJhciIpKTsKCQlhc3NlcnRGYWxzZSgiMy4zIiwgdGV4dC5pc0Fzc29jaWF0ZWRXaXRoKCJmb28uZXh0IikpOwoJCWFzc2VydEZhbHNlKCIzLjQiLCB0ZXh0LmlzQXNzb2NpYXRlZFdpdGgoImJhci5leHQiKSk7CgoJCS8vIGVuc3VyZSB0aGUgc2VyaWFsaXphdGlvbiBmb3JtYXQgaXMgY29ycmVjdAoJCXRyeSB7CgkJCXRleHQuYWRkRmlsZVNwZWMoImZvby5iYXIiLCBJQ29udGVudFR5cGUuRklMRV9OQU1FX1NQRUMpOwoJCQl0ZXh0UHJlZnMuc3luYygpOwoJCQlhc3NlcnRFcXVhbHMoIjQuMCIsICJmb28uYmFyIiwgdGV4dFByZWZzLmdldChDb250ZW50VHlwZS5QUkVGX0ZJTEVfTkFNRVMsIG51bGwpKTsKCQl9IGZpbmFsbHkgewoJCQkvLyBjbGVhbi11cAoJCQl0ZXh0LnJlbW92ZUZpbGVTcGVjKCJmb28uYmFyIiwgSUNvbnRlbnRUeXBlLkZJTEVfTkFNRV9TUEVDKTsKCQl9Cgl9CgoJcHVibGljIHZvaWQgdGVzdFJlZ2lzdHJ5KCkgewoJCUlDb250ZW50VHlwZU1hbmFnZXIgY29udGVudFR5cGVNYW5hZ2VyID0gUGxhdGZvcm0uZ2V0Q29udGVudFR5cGVNYW5hZ2VyKCk7CgkJSUNvbnRlbnRUeXBlTWF0Y2hlciBmaW5kZXIgPSBjb250ZW50VHlwZU1hbmFnZXIuZ2V0TWF0Y2hlcihuZXcgTG9jYWxTZWxlY3Rpb25Qb2xpY3koKSwgbnVsbCk7CgoJCUlDb250ZW50VHlwZSB0ZXh0Q29udGVudFR5cGUgPSBjb250ZW50VHlwZU1hbmFnZXIuZ2V0Q29udGVudFR5cGUoUGxhdGZvcm0uUElfUlVOVElNRSArICcuJyArICJ0ZXh0Iik7CgkJYXNzZXJ0Tm90TnVsbCgiMS4wIiwgdGV4dENvbnRlbnRUeXBlKTsKCQlhc3NlcnRUcnVlKCIxLjEiLCBpc1RleHQoY29udGVudFR5cGVNYW5hZ2VyLCB0ZXh0Q29udGVudFR5cGUpKTsKCQlhc3NlcnROb3ROdWxsKCIxLjIiLCAoKENvbnRlbnRUeXBlSGFuZGxlcikgdGV4dENvbnRlbnRUeXBlKS5nZXRUYXJnZXQoKS5nZXREZXNjcmliZXIoKSk7CgoJCUlDb250ZW50VHlwZSB4bWxDb250ZW50VHlwZSA9IGNvbnRlbnRUeXBlTWFuYWdlci5nZXRDb250ZW50VHlwZShQbGF0Zm9ybS5QSV9SVU5USU1FICsgIi54bWwiKTsKCQlhc3NlcnROb3ROdWxsKCIyLjAiLCB4bWxDb250ZW50VHlwZSk7CgkJYXNzZXJ0VHJ1ZSgiMi4xIiwgaXNUZXh0KGNvbnRlbnRUeXBlTWFuYWdlciwgeG1sQ29udGVudFR5cGUpKTsKCQlhc3NlcnRFcXVhbHMoIjIuMiIsIHRleHRDb250ZW50VHlwZSwgeG1sQ29udGVudFR5cGUuZ2V0QmFzZVR5cGUoKSk7CgkJSUNvbnRlbnREZXNjcmliZXIgeG1sRGVzY3JpYmVyID0gKChDb250ZW50VHlwZUhhbmRsZXIpIHhtbENvbnRlbnRUeXBlKS5nZXRUYXJnZXQoKS5nZXREZXNjcmliZXIoKTsKCQlhc3NlcnROb3ROdWxsKCIyLjMiLCB4bWxEZXNjcmliZXIpOwoJCWFzc2VydFRydWUoIjIuNCIsIHhtbERlc2NyaWJlciBpbnN0YW5jZW9mIFhNTENvbnRlbnREZXNjcmliZXIpOwoKCQlJQ29udGVudFR5cGUgeG1sQmFzZWREaWZmZXJlbnRFeHRlbnNpb25Db250ZW50VHlwZSA9IGNvbnRlbnRUeXBlTWFuYWdlci5nZXRDb250ZW50VHlwZShQSV9SRVNPVVJDRVNfVEVTVFMgKyAnLicgKyAieG1sLWJhc2VkLWRpZmZlcmVudC1leHRlbnNpb24iKTsKCQlhc3NlcnROb3ROdWxsKCIzLjAiLCB4bWxCYXNlZERpZmZlcmVudEV4dGVuc2lvbkNvbnRlbnRUeXBlKTsKCQlhc3NlcnRUcnVlKCIzLjEiLCBpc1RleHQoY29udGVudFR5cGVNYW5hZ2VyLCB4bWxCYXNlZERpZmZlcmVudEV4dGVuc2lvbkNvbnRlbnRUeXBlKSk7CgkJYXNzZXJ0RXF1YWxzKCIzLjIiLCB4bWxDb250ZW50VHlwZSwgeG1sQmFzZWREaWZmZXJlbnRFeHRlbnNpb25Db250ZW50VHlwZS5nZXRCYXNlVHlwZSgpKTsKCgkJSUNvbnRlbnRUeXBlIHhtbEJhc2VkU3BlY2lmaWNOYW1lQ29udGVudFR5cGUgPSBjb250ZW50VHlwZU1hbmFnZXIuZ2V0Q29udGVudFR5cGUoUElfUkVTT1VSQ0VTX1RFU1RTICsgJy4nICsgInhtbC1iYXNlZC1zcGVjaWZpYy1uYW1lIik7CgkJYXNzZXJ0Tm90TnVsbCgiNC4wIiwgeG1sQmFzZWRTcGVjaWZpY05hbWVDb250ZW50VHlwZSk7CgkJYXNzZXJ0VHJ1ZSgiNC4xIiwgaXNUZXh0KGNvbnRlbnRUeXBlTWFuYWdlciwgeG1sQmFzZWRTcGVjaWZpY05hbWVDb250ZW50VHlwZSkpOwoJCWFzc2VydEVxdWFscygiNC4yIiwgeG1sQ29udGVudFR5cGUsIHhtbEJhc2VkU3BlY2lmaWNOYW1lQ29udGVudFR5cGUuZ2V0QmFzZVR5cGUoKSk7CgoJCUlDb250ZW50VHlwZVtdIHhtbFR5cGVzID0gZmluZGVyLmZpbmRDb250ZW50VHlwZXNGb3IoY2hhbmdlQ2FzZSgiZm9vLnhtbCIpKTsKCQlhc3NlcnRUcnVlKCI1LjEiLCBjb250YWlucyh4bWxUeXBlcywgeG1sQ29udGVudFR5cGUpKTsKCgkJSUNvbnRlbnRUeXBlIGJpbmFyeUNvbnRlbnRUeXBlID0gY29udGVudFR5cGVNYW5hZ2VyLmdldENvbnRlbnRUeXBlKFBJX1JFU09VUkNFU19URVNUUyArICcuJyArICJzYW1wbGUtYmluYXJ5MSIpOwoJCWFzc2VydE5vdE51bGwoIjYuMCIsIGJpbmFyeUNvbnRlbnRUeXBlKTsKCQlhc3NlcnRUcnVlKCI2LjEiLCAhaXNUZXh0KGNvbnRlbnRUeXBlTWFuYWdlciwgYmluYXJ5Q29udGVudFR5cGUpKTsKCQlhc3NlcnROdWxsKCI2LjIiLCBiaW5hcnlDb250ZW50VHlwZS5nZXRCYXNlVHlwZSgpKTsKCgkJSUNvbnRlbnRUeXBlW10gYmluYXJ5VHlwZXMgPSBmaW5kZXIuZmluZENvbnRlbnRUeXBlc0ZvcihjaGFuZ2VDYXNlKCJmb28uc2FtcGxlYmluMSIpKTsKCQlhc3NlcnRFcXVhbHMoIjcuMCIsIDEsIGJpbmFyeVR5cGVzLmxlbmd0aCk7CgkJYXNzZXJ0RXF1YWxzKCI3LjEiLCBiaW5hcnlDb250ZW50VHlwZSwgYmluYXJ5VHlwZXNbMF0pOwoKCQlJQ29udGVudFR5cGUgbXlUZXh0ID0gY29udGVudFR5cGVNYW5hZ2VyLmdldENvbnRlbnRUeXBlKFBJX1JFU09VUkNFU19URVNUUyArICIubXl0ZXh0Iik7CgkJYXNzZXJ0Tm90TnVsbCgiOC4wIiwgbXlUZXh0KTsKCQlhc3NlcnRFcXVhbHMoIjguMSIsICJCQVIiLCBteVRleHQuZ2V0RGVmYXVsdENoYXJzZXQoKSk7CgoJCUlDb250ZW50VHlwZVtdIGZvb0JhclR5cGVzID0gZmluZGVyLmZpbmRDb250ZW50VHlwZXNGb3IoY2hhbmdlQ2FzZSgiZm9vLmJhciIpKTsKCQlhc3NlcnRFcXVhbHMoIjkuMCIsIDIsIGZvb0JhclR5cGVzLmxlbmd0aCk7CgoJCUlDb250ZW50VHlwZSBmb29CYXIgPSBjb250ZW50VHlwZU1hbmFnZXIuZ2V0Q29udGVudFR5cGUoUElfUkVTT1VSQ0VTX1RFU1RTICsgIi5mb29CYXIiKTsKCQlhc3NlcnROb3ROdWxsKCI5LjEiLCBmb29CYXIpOwoJCUlDb250ZW50VHlwZSBzdWJGb29CYXIgPSBjb250ZW50VHlwZU1hbmFnZXIuZ2V0Q29udGVudFR5cGUoUElfUkVTT1VSQ0VTX1RFU1RTICsgIi5zdWJGb29CYXIiKTsKCQlhc3NlcnROb3ROdWxsKCI5LjIiLCBzdWJGb29CYXIpOwoJCWFzc2VydFRydWUoIjkuMyIsIGNvbnRhaW5zKGZvb0JhclR5cGVzLCBmb29CYXIpKTsKCQlhc3NlcnRUcnVlKCI5LjQiLCBjb250YWlucyhmb29CYXJUeXBlcywgc3ViRm9vQmFyKSk7Cgl9CgoJcHVibGljIHZvaWQgdGVzdFJvb3RFbGVtZW50QW5kRFRERGVzY3JpYmVyKCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKCQlJQ29udGVudFR5cGVNYW5hZ2VyIGNvbnRlbnRUeXBlTWFuYWdlciA9IFBsYXRmb3JtLmdldENvbnRlbnRUeXBlTWFuYWdlcigpOwoJCUlDb250ZW50VHlwZSByb290RWxlbWVudCA9IGNvbnRlbnRUeXBlTWFuYWdlci5nZXRDb250ZW50VHlwZShQSV9SRVNPVVJDRVNfVEVTVFMgKyAiLnJvb3QtZWxlbWVudCIpOwoJCUlDb250ZW50VHlwZSBkdGRFbGVtZW50ID0gY29udGVudFR5cGVNYW5hZ2VyLmdldENvbnRlbnRUeXBlKFBJX1JFU09VUkNFU19URVNUUyArICIuZHRkIik7CgkJSUNvbnRlbnRUeXBlIG5zUm9vdEVsZW1lbnQgPSBjb250ZW50VHlwZU1hbmFnZXIuZ2V0Q29udGVudFR5cGUoUElfUkVTT1VSQ0VTX1RFU1RTICsgIi5ucy1yb290LWVsZW1lbnQiKTsKCQlJQ29udGVudFR5cGUgbnNXaWxkY2FyZCA9IGNvbnRlbnRUeXBlTWFuYWdlci5nZXRDb250ZW50VHlwZShQSV9SRVNPVVJDRVNfVEVTVFMgKyAiLm5zLXdpbGRjYXJkIik7CgkJSUNvbnRlbnRUeXBlIGVtcHR5TnNSb290RWxlbWVudCA9IGNvbnRlbnRUeXBlTWFuYWdlci5nZXRDb250ZW50VHlwZShQSV9SRVNPVVJDRVNfVEVTVFMgKyAiLmVtcHR5LW5zLXJvb3QtZWxlbWVudCIpOwoJCUlDb250ZW50VHlwZSB4bWxUeXBlID0gY29udGVudFR5cGVNYW5hZ2VyLmdldENvbnRlbnRUeXBlKFBsYXRmb3JtLlBJX1JVTlRJTUUgKyAiLnhtbCIpOwoKCQlJQ29udGVudFR5cGVbXSBjb250ZW50VHlwZXMgPSBjb250ZW50VHlwZU1hbmFnZXIuZmluZENvbnRlbnRUeXBlc0ZvcihnZXRJbnB1dFN0cmVhbShYTUxfUk9PVF9FTEVNRU5UX0lTT184ODU5XzEsICJJU08tODg1OS0xIiksICJmYWtlLnhtbCIpOwoJCWFzc2VydFRydWUoIjEuMCIsIGNvbnRlbnRUeXBlcy5sZW5ndGggPiAwKTsKCQlhc3NlcnRFcXVhbHMoIjEuMSIsIHJvb3RFbGVtZW50LCBjb250ZW50VHlwZXNbMF0pOwoKCQkvLyBidWdzIDY0MDUzIGFuZCA2MzI5OAoJCWNvbnRlbnRUeXBlcyA9IGNvbnRlbnRUeXBlTWFuYWdlci5maW5kQ29udGVudFR5cGVzRm9yKGdldElucHV0U3RyZWFtKFhNTF9ST09UX0VMRU1FTlRfRVhURVJOQUxfRU5USVRZLCAiVVRGLTgiKSwgImZha2UueG1sIik7CgkJYXNzZXJ0VHJ1ZSgiMi4wIiwgY29udGVudFR5cGVzLmxlbmd0aCA+IDApOwoJCWFzc2VydEVxdWFscygiMi4xIiwgcm9vdEVsZW1lbnQsIGNvbnRlbnRUeXBlc1swXSk7CgoJCS8vIGJ1ZyA2MzYyNQoJCWNvbnRlbnRUeXBlcyA9IGNvbnRlbnRUeXBlTWFuYWdlci5maW5kQ29udGVudFR5cGVzRm9yKGdldElucHV0U3RyZWFtKFhNTF9ST09UX0VMRU1FTlRfRVhURVJOQUxfRU5USVRZMiwgIlVURi04IiksICJmYWtlLnhtbCIpOwoJCWFzc2VydFRydWUoIjMuMCIsIGNvbnRlbnRUeXBlcy5sZW5ndGggPiAwKTsKCQlhc3NlcnRFcXVhbHMoIjMuMSIsIHJvb3RFbGVtZW50LCBjb250ZW50VHlwZXNbMF0pOwoKCQkvLyBidWcgMTM1NTc1CgkJY29udGVudFR5cGVzID0gY29udGVudFR5cGVNYW5hZ2VyLmZpbmRDb250ZW50VHlwZXNGb3IoZ2V0SW5wdXRTdHJlYW0oWE1MX1JPT1RfRUxFTUVOVF9OU19NQVRDSDEsICJVVEYtOCIpLCAiZmFrZS54bWwiKTsKCQlhc3NlcnRUcnVlKCI0LjAiLCBjb250ZW50VHlwZXMubGVuZ3RoID4gMCk7CgkJYXNzZXJ0RXF1YWxzKCI0LjEiLCBuc1Jvb3RFbGVtZW50LCBjb250ZW50VHlwZXNbMF0pOwoJCWNvbnRlbnRUeXBlcyA9IGNvbnRlbnRUeXBlTWFuYWdlci5maW5kQ29udGVudFR5cGVzRm9yKGdldElucHV0U3RyZWFtKFhNTF9ST09UX0VMRU1FTlRfTlNfTUFUQ0gyLCAiVVRGLTgiKSwgImZha2UueG1sIik7CgkJYXNzZXJ0VHJ1ZSgiNC4yIiwgY29udGVudFR5cGVzLmxlbmd0aCA+IDApOwoJCWFzc2VydEVxdWFscygiNC4zIiwgbnNSb290RWxlbWVudCwgY29udGVudFR5cGVzWzBdKTsKCQljb250ZW50VHlwZXMgPSBjb250ZW50VHlwZU1hbmFnZXIuZmluZENvbnRlbnRUeXBlc0ZvcihnZXRJbnB1dFN0cmVhbShYTUxfUk9PVF9FTEVNRU5UX05TX1dST05HX0VMRU0sICJVVEYtOCIpLCAiZmFrZS54bWwiKTsKCQlhc3NlcnRUcnVlKCI0LjQiLCBjb250ZW50VHlwZXMubGVuZ3RoID4gMCk7CgkJYXNzZXJ0RXF1YWxzKCI0LjUiLCB4bWxUeXBlLCBjb250ZW50VHlwZXNbMF0pOwoJCWNvbnRlbnRUeXBlcyA9IGNvbnRlbnRUeXBlTWFuYWdlci5maW5kQ29udGVudFR5cGVzRm9yKGdldElucHV0U3RyZWFtKFhNTF9ST09UX0VMRU1FTlRfTlNfV1JPTkdfTlMsICJVVEYtOCIpLCAiZmFrZS54bWwiKTsKCQlhc3NlcnRUcnVlKCI0LjYiLCBjb250ZW50VHlwZXMubGVuZ3RoID4gMCk7CgkJYXNzZXJ0RXF1YWxzKCI0LjciLCB4bWxUeXBlLCBjb250ZW50VHlwZXNbMF0pOwoJCWNvbnRlbnRUeXBlcyA9IGNvbnRlbnRUeXBlTWFuYWdlci5maW5kQ29udGVudFR5cGVzRm9yKGdldElucHV0U3RyZWFtKFhNTF9ST09UX0VMRU1FTlRfTlNfTUlYVVAsICJVVEYtOCIpLCAiZmFrZS54bWwiKTsKCQlhc3NlcnRUcnVlKCI0LjgiLCBjb250ZW50VHlwZXMubGVuZ3RoID4gMCk7CgkJYXNzZXJ0RXF1YWxzKCI0LjkiLCB4bWxUeXBlLCBjb250ZW50VHlwZXNbMF0pOwoJCWNvbnRlbnRUeXBlcyA9IGNvbnRlbnRUeXBlTWFuYWdlci5maW5kQ29udGVudFR5cGVzRm9yKGdldElucHV0U3RyZWFtKFhNTF9ST09UX0VMRU1FTlRfTlNfV0lMRENBUkQsICJVVEYtOCIpLCAiZmFrZS54bWwiKTsKCQlhc3NlcnRUcnVlKCI0LjEwIiwgY29udGVudFR5cGVzLmxlbmd0aCA+IDApOwoJCWFzc2VydEVxdWFscygiNC4xMSIsIG5zV2lsZGNhcmQsIGNvbnRlbnRUeXBlc1swXSk7CgkJY29udGVudFR5cGVzID0gY29udGVudFR5cGVNYW5hZ2VyLmZpbmRDb250ZW50VHlwZXNGb3IoZ2V0SW5wdXRTdHJlYW0oWE1MX1JPT1RfRUxFTUVOVF9OU19XSUxEQ0FSRDIsICJVVEYtOCIpLCAiZmFrZS54bWwiKTsKCQlhc3NlcnRUcnVlKCI0LjEyIiwgY29udGVudFR5cGVzLmxlbmd0aCA+IDApOwoJCWFzc2VydEVxdWFscygiNC4xMyIsIG5zV2lsZGNhcmQsIGNvbnRlbnRUeXBlc1swXSk7CgkJY29udGVudFR5cGVzID0gY29udGVudFR5cGVNYW5hZ2VyLmZpbmRDb250ZW50VHlwZXNGb3IoZ2V0SW5wdXRTdHJlYW0oWE1MX1JPT1RfRUxFTUVOVF9FTVBUWV9OUywgIlVURi04IiksICJmYWtlLnhtbCIpOwoJCWFzc2VydFRydWUoIjQuMTQiLCBjb250ZW50VHlwZXMubGVuZ3RoID4gMCk7CgkJYXNzZXJ0RXF1YWxzKCI0LjE1IiwgZW1wdHlOc1Jvb3RFbGVtZW50LCBjb250ZW50VHlwZXNbMF0pOwoKCQljb250ZW50VHlwZXMgPSBjb250ZW50VHlwZU1hbmFnZXIuZmluZENvbnRlbnRUeXBlc0ZvcihnZXRJbnB1dFN0cmVhbShYTUxfRFREX1VTX0FTQ0lJLCAiVVMtQVNDSUkiKSwgImZha2UueG1sIik7CgkJYXNzZXJ0VHJ1ZSgiNS4wIiwgY29udGVudFR5cGVzLmxlbmd0aCA+IDApOwoJCWFzc2VydEVxdWFscygiNS4xIiwgZHRkRWxlbWVudCwgY29udGVudFR5cGVzWzBdKTsKCQljb250ZW50VHlwZXMgPSBjb250ZW50VHlwZU1hbmFnZXIuZmluZENvbnRlbnRUeXBlc0ZvcihnZXRJbnB1dFN0cmVhbShYTUxfRFREX0VYVEVSTkFMX0VOVElUWSwgIlVURi04IiksICJmYWtlLnhtbCIpOwoJCWFzc2VydFRydWUoIjUuNCIsIGNvbnRlbnRUeXBlcy5sZW5ndGggPiAwKTsKCQlhc3NlcnRFcXVhbHMoIjUuNSIsIGR0ZEVsZW1lbnQsIGNvbnRlbnRUeXBlc1swXSk7CgoJCS8vIGJ1ZyA2Nzk3NQoJCUlDb250ZW50RGVzY3JpcHRpb24gZGVzY3JpcHRpb24gPSBjb250ZW50VHlwZU1hbmFnZXIuZ2V0RGVzY3JpcHRpb25Gb3IoZ2V0SW5wdXRTdHJlYW0obmV3IGJ5dGVbXVtdIHtJQ29udGVudERlc2NyaXB0aW9uLkJPTV9VVEZfMTZCRSwgWE1MX1JPT1RfRUxFTUVOVF9OT19ERUNMLmdldEJ5dGVzKCJVVEYtMTZCRSIpfSksICJmYWtlLnhtbCIsIElDb250ZW50RGVzY3JpcHRpb24uQUxMKTsKCQlhc3NlcnRUcnVlKCI2LjAiLCBkZXNjcmlwdGlvbiAhPSBudWxsKTsKCQlhc3NlcnRFcXVhbHMoIjYuMSIsIHJvb3RFbGVtZW50LCBkZXNjcmlwdGlvbi5nZXRDb250ZW50VHlwZSgpKTsKCQlhc3NlcnRFcXVhbHMoIjYuMiIsIElDb250ZW50RGVzY3JpcHRpb24uQk9NX1VURl8xNkJFLCBkZXNjcmlwdGlvbi5nZXRQcm9wZXJ0eShJQ29udGVudERlc2NyaXB0aW9uLkJZVEVfT1JERVJfTUFSSykpOwoKCQlkZXNjcmlwdGlvbiA9IGNvbnRlbnRUeXBlTWFuYWdlci5nZXREZXNjcmlwdGlvbkZvcihnZXRJbnB1dFN0cmVhbShuZXcgYnl0ZVtdW10ge0lDb250ZW50RGVzY3JpcHRpb24uQk9NX1VURl8xNkxFLCBYTUxfUk9PVF9FTEVNRU5UX05PX0RFQ0wuZ2V0Qnl0ZXMoIlVURi0xNkxFIil9KSwgImZha2UueG1sIiwgSUNvbnRlbnREZXNjcmlwdGlvbi5BTEwpOwoJCWFzc2VydFRydWUoIjcuMCIsIGRlc2NyaXB0aW9uICE9IG51bGwpOwoJCWFzc2VydEVxdWFscygiNy4xIiwgcm9vdEVsZW1lbnQsIGRlc2NyaXB0aW9uLmdldENvbnRlbnRUeXBlKCkpOwoJCWFzc2VydEVxdWFscygiNy4yIiwgSUNvbnRlbnREZXNjcmlwdGlvbi5CT01fVVRGXzE2TEUsIGRlc2NyaXB0aW9uLmdldFByb3BlcnR5KElDb250ZW50RGVzY3JpcHRpb24uQllURV9PUkRFUl9NQVJLKSk7CgoJCS8vIGR1ZSB0byBidWcgNjcwNDgsIHRoZSB0ZXN0IGJlbG93IGZhaWxzIHdpdGggQ3JpbXNvbiBwYXJzZXIgKGRvZXMgbm90IGhhbmRsZSBVVEYtOCBCT01zKQoJCS8vCQlkZXNjcmlwdGlvbiA9IGNvbnRlbnRUeXBlTWFuYWdlci5nZXREZXNjcmlwdGlvbkZvcihnZXRJbnB1dFN0cmVhbShuZXcgYnl0ZVtdW10ge0lDb250ZW50RGVzY3JpcHRpb24uQk9NX1VURl84LFhNTF9ST09UX0VMRU1FTlRfTk9fREVDTC5nZXRCeXRlcygiVVRGLTgiKX0pLCAiZmFrZS54bWwiLCBJQ29udGVudERlc2NyaXB0aW9uLkFMTCk7CgkJLy8JCWFzc2VydFRydWUoIjcuMCIsIGRlc2NyaXB0aW9uICE9IG51bGwpOwoJCS8vCQlhc3NlcnRFcXVhbHMoIjcuMSIsIHJvb3RFbGVtZW50LCBkZXNjcmlwdGlvbi5nZXRDb250ZW50VHlwZSgpKTsKCQkvLwkJYXNzZXJ0RXF1YWxzKCI3LjIiLCBJQ29udGVudERlc2NyaXB0aW9uLkJPTV9VVEZfOCwgZGVzY3JpcHRpb24uZ2V0UHJvcGVydHkoSUNvbnRlbnREZXNjcmlwdGlvbi5CWVRFX09SREVSX01BUkspKTsKCgkJLy8gYnVnIDg0MzU0CgkJY29udGVudFR5cGVzID0gY29udGVudFR5cGVNYW5hZ2VyLmZpbmRDb250ZW50VHlwZXNGb3IoZ2V0SW5wdXRTdHJlYW0oWE1MX1JPT1RfRUxFTUVOVF9OT19ERUNMLCAiVVRGLTgiKSwgInRlc3QudHh0Iik7CgkJYXNzZXJ0VHJ1ZSgiOC4wIiwgY29udGVudFR5cGVzLmxlbmd0aCA+IDApOwoJCWFzc2VydEVxdWFscygiOC4xIiwgY29udGVudFR5cGVNYW5hZ2VyLmdldENvbnRlbnRUeXBlKElDb250ZW50VHlwZU1hbmFnZXIuQ1RfVEVYVCksIGNvbnRlbnRUeXBlc1swXSk7Cgl9CgoJLyoqCgkgKiBCdWcgNjY5NzYKCSAqLwoJcHVibGljIHZvaWQgdGVzdFNpZ25hdHVyZUJleW9uZEJ1ZmZlckxpbWl0KCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKCQlpbnQgYnVmZmVyTGltaXQgPSBDb250ZW50VHlwZU1hbmFnZXIuQkxPQ0tfU0laRSAqIDQ7CgkJLy8gY3JlYXRlIGEgbG9uZyBYTUwgY29tbWVudCBhcyBwcmVmaXgKCQlTdHJpbmdCdWlsZGVyIGNvbW1lbnQgPSBuZXcgU3RyaW5nQnVpbGRlcigiPCEtLSIpOwoJCWZvciAoaW50IGkgPSAwOyBpIDwgYnVmZmVyTGltaXQ7IGkrKykgewoJCQljb21tZW50LmFwcGVuZCgnKicpOwoJCX0KCQljb21tZW50LmFwcGVuZCgiLS0+Iik7CgkJSUNvbnRlbnRUeXBlTWFuYWdlciBtYW5hZ2VyID0gUGxhdGZvcm0uZ2V0Q29udGVudFR5cGVNYW5hZ2VyKCk7CgkJSUNvbnRlbnRUeXBlIHJvb3RFbGVtZW50ID0gbWFuYWdlci5nZXRDb250ZW50VHlwZShQSV9SRVNPVVJDRVNfVEVTVFMgKyAiLnJvb3QtZWxlbWVudCIpOwoJCUlDb250ZW50VHlwZSBzZWxlY3RlZCA9IG1hbmFnZXIuZmluZENvbnRlbnRUeXBlRm9yKGdldElucHV0U3RyZWFtKGNvbW1lbnQgKyBYTUxfUk9PVF9FTEVNRU5UX05PX0RFQ0wsICJVUy1BU0NJSSIpLCAiZmFrZS54bWwiKTsKCQlhc3NlcnROb3ROdWxsKCIxLjAiLCBzZWxlY3RlZCk7CgkJYXNzZXJ0RXF1YWxzKCIxLjEiLCByb290RWxlbWVudCwgc2VsZWN0ZWQpOwoJfQoKCS8qKgoJICogU2VlIGFsc286IGJ1ZyA3Mjc5Ni4KCSAqLwoJcHVibGljIHZvaWQgdGVzdFVzZXJEZWZpbmVkQXNzb2NpYXRpb25zKCkgewoJCUlDb250ZW50VHlwZU1hbmFnZXIgbWFuYWdlciA9IFBsYXRmb3JtLmdldENvbnRlbnRUeXBlTWFuYWdlcigpOwoJCUlDb250ZW50VHlwZSB0ZXh0ID0gbWFuYWdlci5nZXRDb250ZW50VHlwZSgoUGxhdGZvcm0uUElfUlVOVElNRSArICIudGV4dCIpKTsKCgkJYXNzZXJ0TnVsbCgiMC4xIiwgbWFuYWdlci5maW5kQ29udGVudFR5cGVGb3IoInRlc3QubXl0ZXh0IikpOwoJCS8vIGFzc29jaWF0ZSBhIHVzZXItZGVmaW5lZCBmaWxlIHNwZWMKCQl0cnkgewoJCQl0ZXh0LmFkZEZpbGVTcGVjKCJteXRleHQiLCBJQ29udGVudFR5cGUuRklMRV9FWFRFTlNJT05fU1BFQyk7CgkJfSBjYXRjaCAoQ29yZUV4Y2VwdGlvbiBlKSB7CgkJCWZhaWwoIjEuMCIsIGUpOwoJCX0KCQlib29sZWFuIGFzc2VydGlvbkZhaWxlZCA9IGZhbHNlOwoJCXRyeSB7CgkJCUlDb250ZW50VHlwZSByZXN1bHQgPSBtYW5hZ2VyLmZpbmRDb250ZW50VHlwZUZvcigidGVzdC5teXRleHQiKTsKCQkJYXNzZXJ0Tm90TnVsbCgiMS4xIiwgcmVzdWx0KTsKCQkJYXNzZXJ0RXF1YWxzKCIxLjIiLCB0ZXh0LCByZXN1bHQpOwoJCX0gY2F0Y2ggKEFzc2VydGlvbkZhaWxlZEVycm9yIGFmZSkgewoJCQlhc3NlcnRpb25GYWlsZWQgPSB0cnVlOwoJCQl0aHJvdyBhZmU7CgkJfSBmaW5hbGx5IHsKCQkJdHJ5IHsKCQkJCXRleHQucmVtb3ZlRmlsZVNwZWMoIm15dGV4dCIsIElDb250ZW50VHlwZS5GSUxFX0VYVEVOU0lPTl9TUEVDKTsKCQkJfSBjYXRjaCAoQ29yZUV4Y2VwdGlvbiBlKSB7CgkJCQlpZiAoIWFzc2VydGlvbkZhaWxlZCkgewoJCQkJCWZhaWwoIiAyLjAiLCBlKTsKCQkJCX0KCQkJfQoJCX0KCQlJQ29udGVudFR5cGUgcmVzdWx0ID0gbWFuYWdlci5maW5kQ29udGVudFR5cGVGb3IoInRlc3QubXl0ZXh0Iik7CgkJYXNzZXJ0TnVsbCgiMy4wIiwgcmVzdWx0KTsKCX0KCglwdWJsaWMgdm9pZCB0ZXN0RGVzY3JpYmVySW52YWxpZGF0aW9uKCkgdGhyb3dzIFVuc3VwcG9ydGVkRW5jb2RpbmdFeGNlcHRpb24sIElPRXhjZXB0aW9uIHsKCQlJQ29udGVudFR5cGVNYW5hZ2VyIGNvbnRlbnRUeXBlTWFuYWdlciA9IFBsYXRmb3JtLmdldENvbnRlbnRUeXBlTWFuYWdlcigpOwoJCUlDb250ZW50VHlwZSB0eXBlX2J1ZzE4MjMzN19BID0gY29udGVudFR5cGVNYW5hZ2VyLmdldENvbnRlbnRUeXBlKFBJX1JFU09VUkNFU19URVNUUyArICIuQnVnMTgyMzM3X0EiKTsKCQlJQ29udGVudFR5cGUgdHlwZV9idWcxODIzMzdfQiA9IGNvbnRlbnRUeXBlTWFuYWdlci5nZXRDb250ZW50VHlwZShQSV9SRVNPVVJDRVNfVEVTVFMgKyAiLkJ1ZzE4MjMzN19CIik7CgoJCUlDb250ZW50VHlwZVtdIGNvbnRlbnRUeXBlcyA9IGNvbnRlbnRUeXBlTWFuYWdlci5maW5kQ29udGVudFR5cGVzRm9yKGdldElucHV0U3RyZWFtKFhNTF9ST09UX0VMRU1FTlRfTlNfTUFUQ0gyLCAiVVRGLTgiKSwgIkJ1ZzE4MjMzNy5CdWcxODIzMzciKTsKCQlhc3NlcnRUcnVlKCIxLjAiLCBjb250ZW50VHlwZXMubGVuZ3RoID09IDIpOwoJCWFzc2VydEVxdWFscygiMS4xIiwgdHlwZV9idWcxODIzMzdfQSwgY29udGVudFR5cGVzWzBdKTsKCQlhc3NlcnRFcXVhbHMoIjEuMSIsIHR5cGVfYnVnMTgyMzM3X0IsIGNvbnRlbnRUeXBlc1sxXSk7CgoJCUlucHV0U3RyZWFtIGlzID0gbmV3IElucHV0U3RyZWFtKCkgewoJCQlAT3ZlcnJpZGUKCQkJcHVibGljIGludCByZWFkKCkgewoJCQkJLy8gdGhyb3cgYSBub24gY2hlY2tlZCBleGNlcHRpb24gdG8gZW11bGF0ZSBhIHByb2JsZW0gd2l0aCB0aGUgZGVzY3JpYmVyIGl0c2VsZgoJCQkJdGhyb3cgbmV3IFJ1bnRpbWVFeGNlcHRpb24oKTsKCQkJfQoJCX07CgkJY29udGVudFR5cGVzID0gY29udGVudFR5cGVNYW5hZ2VyLmZpbmRDb250ZW50VHlwZXNGb3IoaXMsICJCdWcxODIzMzcuQnVnMTgyMzM3Iik7CgkJYXNzZXJ0VHJ1ZSgiMS4yIiwgY29udGVudFR5cGVzLmxlbmd0aCA9PSAwKTsKCgkJLy8gRGVzY3JpYmVyIHNob3VsZCBiZSBpbnZhbGlkYXRlZCBieSBub3cKCQljb250ZW50VHlwZXMgPSBjb250ZW50VHlwZU1hbmFnZXIuZmluZENvbnRlbnRUeXBlc0ZvcihnZXRJbnB1dFN0cmVhbShYTUxfUk9PVF9FTEVNRU5UX05TX01BVENIMiwgIlVURi04IiksICJCdWcxODIzMzcuQnVnMTgyMzM3Iik7CgkJYXNzZXJ0VHJ1ZSgiMS4zIiwgY29udGVudFR5cGVzLmxlbmd0aCA9PSAwKTsKCX0KCn0K