LyoKKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgoqIENvcHlyaWdodCAoYykgMjAwMi0yMDA0LCBJbnRlcm5hdGlvbmFsIEJ1c2luZXNzIE1hY2hpbmVzCiogQ29ycG9yYXRpb24gYW5kIG90aGVycy4gIEFsbCBSaWdodHMgUmVzZXJ2ZWQuCioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKKiBBdXRob3I6IE1hcmsgRGF2aXMKKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgoqLwpwYWNrYWdlIGNvbS5pYm0uaWN1LmRldi50b29sLmNsZHI7CgppbXBvcnQgamF2YS5pby5CdWZmZXJlZFJlYWRlcjsKaW1wb3J0IGphdmEuaW8uRmlsZTsKaW1wb3J0IGphdmEuaW8uRmlsZUlucHV0U3RyZWFtOwppbXBvcnQgamF2YS5pby5JT0V4Y2VwdGlvbjsKaW1wb3J0IGphdmEuaW8uUHJpbnRXcml0ZXI7CmltcG9ydCBqYXZhLnV0aWwuQXJyYXlMaXN0OwppbXBvcnQgamF2YS51dGlsLkFycmF5czsKaW1wb3J0IGphdmEudXRpbC5Db2xsZWN0aW9uOwppbXBvcnQgamF2YS51dGlsLkNvbXBhcmF0b3I7CmltcG9ydCBqYXZhLnV0aWwuRW51bWVyYXRpb247CmltcG9ydCBqYXZhLnV0aWwuSGFzaE1hcDsKaW1wb3J0IGphdmEudXRpbC5IYXNoU2V0OwppbXBvcnQgamF2YS51dGlsLkl0ZXJhdG9yOwppbXBvcnQgamF2YS51dGlsLkxpc3Q7CmltcG9ydCBqYXZhLnV0aWwuTWFwOwppbXBvcnQgamF2YS51dGlsLlNldDsKaW1wb3J0IGphdmEudXRpbC5UcmVlTWFwOwppbXBvcnQgamF2YS51dGlsLlRyZWVTZXQ7CmltcG9ydCBqYXZhLnV0aWwucmVnZXguTWF0Y2hlcjsKaW1wb3J0IGphdmEudXRpbC5yZWdleC5QYXR0ZXJuOwoKaW1wb3J0IG9yZy54bWwuc2F4LkF0dHJpYnV0ZXM7CmltcG9ydCBvcmcueG1sLnNheC5JbnB1dFNvdXJjZTsKaW1wb3J0IG9yZy54bWwuc2F4LkxvY2F0b3I7CmltcG9ydCBvcmcueG1sLnNheC5TQVhFeGNlcHRpb247CmltcG9ydCBvcmcueG1sLnNheC5oZWxwZXJzLlhNTFJlYWRlckZhY3Rvcnk7CmltcG9ydCBvcmcueG1sLnNheC5Db250ZW50SGFuZGxlcjsKaW1wb3J0IG9yZy54bWwuc2F4LmV4dC5EZWNsSGFuZGxlcjsKaW1wb3J0IG9yZy54bWwuc2F4LmV4dC5MZXhpY2FsSGFuZGxlcjsKaW1wb3J0IG9yZy54bWwuc2F4LlhNTFJlYWRlcjsKCmltcG9ydCBjb20uaWJtLmljdS5kZXYudGVzdC51dGlsLkJhZ0Zvcm1hdHRlcjsKaW1wb3J0IGNvbS5pYm0uaWN1LmRldi50b29sLlVPcHRpb247CmltcG9ydCBjb20uaWJtLmljdS5pbXBsLklDVVJlc291cmNlQnVuZGxlOwppbXBvcnQgY29tLmlibS5pY3UuaW1wbC5VdGlsaXR5OwppbXBvcnQgY29tLmlibS5pY3UubGFuZy5VQ2hhcmFjdGVyOwppbXBvcnQgY29tLmlibS5pY3UudGV4dC5Db2xsYXRvcjsKaW1wb3J0IGNvbS5pYm0uaWN1LnRleHQuTm9ybWFsaXplcjsKaW1wb3J0IGNvbS5pYm0uaWN1LnRleHQuUnVsZUJhc2VkQ29sbGF0b3I7CmltcG9ydCBjb20uaWJtLmljdS50ZXh0LlVURjE2OwppbXBvcnQgY29tLmlibS5pY3UudGV4dC5Vbmljb2RlU2V0OwppbXBvcnQgY29tLmlibS5pY3UudXRpbC5VTG9jYWxlOwppbXBvcnQgY29tLmlibS5pY3UudXRpbC5VUmVzb3VyY2VCdW5kbGU7CgovL2ltcG9ydCBqYXZheC54bWwucGFyc2Vycy4qOwoKLyoqCiAqIFRoaXMgaXMgYSBzaW1wbGUgY2xhc3MgdGhhdCB3YWxrcyB0aHJvdWdoIHRoZSBDTERSIGhpZXJhcmNoeSBhbmQgZG9lcyAyIHRoaW5ncy4KICogRmlyc3QsIGl0IGRldGVybWluZXMgYWxsIHRoZSBwbGFjZXMgd2hlcmUgdGhlIENMRFIgaXMgbm90IG1pbmltYWw6IHdoZXJlIHRoZXJlCiAqIGFyZSByZWR1bmRhbmNpZXMgd2l0aCBpbmhlcml0YW5jZS4gSXQgZ2VuZXJhdGVzIG5ldyBmaWxlcyBpbiB0aGUgdGFyZ2V0IGRpcmVjdG9yeS4KICogU2Vjb25kLCBpdCBnYXRoZXJzIHRvZ2V0aGVyIGFsbCB0aGUgaXRlbXMgZnJvbSBhbGwgdGhlIGxvY2FsZXMgdGhhdCBzaGFyZSB0aGUKICogc2FtZSBlbGVtZW50IGNoYWluLCBhbmQgdGh1cyBwcmVzZW50cyBhICJzaWRld2F5cyIgdmlldyBvZiB0aGUgZGF0YSwgaW4gZmlsZXMgY2FsbGVkCiAqIGJ5X3R5cGUvWC5odG1sLCB3aGVyZSBYIGlzIGEgdHlwZS4gWCBtYXkgYmUgdGhlIGNvbmNhdGVuYXRpb24gb2YgbW9yZSB0aGFuIG1vcmUgdGhhbgogKiBvbmUgZWxlbWVudCwgd2hlcmUgdGhlIGZpbGUgd291bGQgb3RoZXJ3aXNlIGJlIHRvbyBsYXJnZS4KICogQGF1dGhvciBtZWRhdmlzCiAqLwovKiAKTm90ZXM6Cmh0dHA6Ly94bWwuYXBhY2hlLm9yZy94ZXJjZXMyLWovZmFxLWdyYW1tYXJzLmh0bWwjZmFxLTMKaHR0cDovL2RldmVsb3BlcnMuc3VuLmNvbS9kZXYvY29vbHN0dWZmL3htbC9yZWFkbWUuaHRtbApodHRwOi8vbGlzdHMueG1sLm9yZy9hcmNoaXZlcy94bWwtZGV2LzIwMDAwNy9tc2cwMDI4NC5odG1sCmh0dHA6Ly9qYXZhLnN1bi5jb20vajJzZS8xLjQuMi9kb2NzL2FwaS9vcmcveG1sL3NheC9EVERIYW5kbGVyLmh0bWwKICovCnB1YmxpYyBjbGFzcyBHZW5lcmF0ZVNpZGV3YXlzVmlldyB7CiAgICAvLyBkZWJ1ZyBmbGFncwogICAgc3RhdGljIGZpbmFsIGJvb2xlYW4gREVCVUcgPSBmYWxzZTsKICAgIHN0YXRpYyBmaW5hbCBib29sZWFuIERFQlVHMiA9IGZhbHNlOwogICAgc3RhdGljIGZpbmFsIGJvb2xlYW4gREVCVUdfU0hPV19BREQgPSBmYWxzZTsKICAgIHN0YXRpYyBmaW5hbCBib29sZWFuIERFQlVHX0VMRU1FTlQgPSBmYWxzZTsKICAgIHN0YXRpYyBmaW5hbCBib29sZWFuIERFQlVHX1NIT1dfQkFUID0gZmFsc2U7CiAgICAKICAgIHN0YXRpYyBmaW5hbCBib29sZWFuIEZJWF9aT05FX0FMSUFTRVMgPSB0cnVlOwoKICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGludCAKICAgICAgICBIRUxQMSA9IDAsCgkJSEVMUDIgPSAxLAogICAgICAgIFNPVVJDRURJUiA9IDIsCiAgICAgICAgREVTVERJUiA9IDMsCiAgICAgICAgTUFUQ0ggPSA0LAogICAgICAgIFNLSVAgPSA1LAogICAgICAgIFRaQURJUiA9IDYsCiAgICAgICAgTk9OVkFMSURBVElORyA9IDcsCiAgICAgICAgU0hPV19EVEQgPSA4OwogICAgICAgIAogICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgU3RyaW5nIE5FV0xJTkUgPSAiXG4iOwoKICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIFVPcHRpb25bXSBvcHRpb25zID0gewogICAgICAgICAgICBVT3B0aW9uLkhFTFBfSCgpLAogICAgICAgICAgICBVT3B0aW9uLkhFTFBfUVVFU1RJT05fTUFSSygpLAogICAgICAgICAgICBVT3B0aW9uLlNPVVJDRURJUigpLnNldERlZmF1bHQoIkM6XFxJQ1U0Q1xcbG9jYWxlXFxjb21tb25cXG1haW5cXCIpLAogICAgICAgICAgICBVT3B0aW9uLkRFU1RESVIoKS5zZXREZWZhdWx0KCJDOlxcREFUQVxcR0VOXFxjbGRyXFxtYWluXFwiKSwKICAgICAgICAgICAgVU9wdGlvbi5jcmVhdGUoIm1hdGNoIiwgJ20nLCBVT3B0aW9uLlJFUVVJUkVTX0FSRykuc2V0RGVmYXVsdCgiLioiKSwKICAgICAgICAgICAgVU9wdGlvbi5jcmVhdGUoInNraXAiLCAneicsIFVPcHRpb24uUkVRVUlSRVNfQVJHKS5zZXREZWZhdWx0KCJ6aF8oQ3xTfEhLfE0pLioiKSwKICAgICAgICAgICAgVU9wdGlvbi5jcmVhdGUoInR6YWRpciIsICd0JywgVU9wdGlvbi5SRVFVSVJFU19BUkcpLnNldERlZmF1bHQoIkM6XFxJQ1U0SlxcaWN1NGpcXHNyY1xcY29tXFxpYm1cXGljdVxcZGV2XFx0b29sXFxjbGRyXFwiKSwKICAgICAgICAgICAgVU9wdGlvbi5jcmVhdGUoIm5vbnZhbGlkYXRpbmciLCAnbicsIFVPcHRpb24uTk9fQVJHKSwKICAgICAgICAgICAgVU9wdGlvbi5jcmVhdGUoImR0ZCIsICd3JywgVU9wdGlvbi5OT19BUkcpLAogICAgfTsKICAgIHByaXZhdGUgc3RhdGljIFN0cmluZyB0aW1lWm9uZUFsaWFzRGlyID0gbnVsbDsKICAgIAogICAgcHVibGljIHN0YXRpYyB2b2lkIG1haW4oU3RyaW5nW10gYXJncykgdGhyb3dzIFNBWEV4Y2VwdGlvbiwgSU9FeGNlcHRpb24gewogICAgICAgIAogICAgICAgIFVPcHRpb24ucGFyc2VBcmdzKGFyZ3MsIG9wdGlvbnMpOwoKICAgICAgICBNYXRjaGVyIHNraXBwZXIgPSBQYXR0ZXJuLmNvbXBpbGUob3B0aW9uc1tTS0lQXS52YWx1ZSkubWF0Y2hlcigiIik7CiAgICAgICAgTWF0Y2hlciBtYXRjaGVyID0gUGF0dGVybi5jb21waWxlKG9wdGlvbnNbTUFUQ0hdLnZhbHVlKS5tYXRjaGVyKCIiKTsKICAgICAgICAvL21hdGNoZXIgPSBQYXR0ZXJuLmNvbXBpbGUoIihyb290fGIpLioiKS5tYXRjaGVyKCIiKTsKICAgICAgICBsb2cgPSBCYWdGb3JtYXR0ZXIub3BlblVURjhXcml0ZXIob3B0aW9uc1tERVNURElSXS52YWx1ZSwgImxvZy50eHQiKTsKICAgICAgICB0aW1lWm9uZUFsaWFzRGlyID0gb3B0aW9uc1tUWkFESVJdLnZhbHVlOwogICAgICAgIHRyeSB7CiAgICAgICAgICAgIEZpbGUgc291cmNlRGlyID0gbmV3IEZpbGUob3B0aW9uc1tTT1VSQ0VESVJdLnZhbHVlKTsKICAgICAgICAgICAgU3RyaW5nW10gY29udGVudHMgPSBzb3VyY2VEaXIubGlzdCgpOwogICAgICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IGNvbnRlbnRzLmxlbmd0aDsgKytpKSB7CiAgICAgICAgICAgICAgICBpZiAoIWNvbnRlbnRzW2ldLmVuZHNXaXRoKCIueG1sIikpIGNvbnRpbnVlOwogICAgICAgICAgICAgICAgaWYgKGNvbnRlbnRzW2ldLnN0YXJ0c1dpdGgoInN1cHBsZW1lbnRhbERhdGEiKSkgY29udGludWU7CiAgICAgICAgICAgICAgICBpZiAoIW1hdGNoZXIucmVzZXQoY29udGVudHNbaV0pLm1hdGNoZXMoKSkgY29udGludWU7IC8vIGRlYnVnIHNodXRvZmYKICAgICAgICAgICAgICAgIGlmIChza2lwcGVyLnJlc2V0KGNvbnRlbnRzW2ldKS5tYXRjaGVzKCkpIGNvbnRpbnVlOyAvLyBkZWJ1ZyBzaHV0b2ZmCiAgICAgICAgICAgICAgICAvL1N5c3RlbS5vdXQucHJpbnRsbigiUHJvY2Vzc2luZyAiICsgY29udGVudHNbaV0pOwogICAgICAgICAgICAgICAgbG9nLnByaW50bG4oKTsKICAgICAgICAgICAgICAgIGxvZy5wcmludGxuKCJQcm9jZXNzaW5nICIgKyBjb250ZW50c1tpXSk7CiAgICAgICAgICAgICAgICBTdHJpbmcgYmFzZU5hbWUgPSBjb250ZW50c1tpXS5zdWJzdHJpbmcoMCxjb250ZW50c1tpXS5sZW5ndGgoKS00KTsKICAgICAgICAgICAgICAgIEdlbmVyYXRlU2lkZXdheXNWaWV3IHRlbXAgPSBnZXRDTERSKGJhc2VOYW1lLCAhb3B0aW9uc1tOT05WQUxJREFUSU5HXS5kb2VzT2NjdXIpOwogICAgICAgICAgICAgICAgLy8gaWYgKGJhc2VOYW1lLmVxdWFscygiemhfVFciKSkgYmFzZU5hbWUgPSAiemhfSGFudF9UVyI7CiAgICAgICAgICAgICAgICAvLyBpZiAoYmFzZU5hbWUuZXF1YWxzKCJyb290IikpIHRlbXAuYWRkTWlzc2luZygpOwogICAgICAgICAgICAgICAgaWYgKG9wdGlvbnNbU0hPV19EVERdLmRvZXNPY2N1cikgdGVtcC53cml0ZURURENoZWNrKCk7CiAgICAgICAgICAgICAgICB0ZW1wLndyaXRlVG8ob3B0aW9uc1tERVNURElSXS52YWx1ZSwgYmFzZU5hbWUpOwogICAgICAgICAgICAgICAgZ2VuZXJhdGVCYXQob3B0aW9uc1tTT1VSQ0VESVJdLnZhbHVlLCBiYXNlTmFtZSArICIueG1sIiwgb3B0aW9uc1tERVNURElSXS52YWx1ZSwgYmFzZU5hbWUgKyAiLnhtbCIpOwogICAgICAgICAgICAgICAgc2lkZXdheXNWaWV3LnB1dERhdGEodGVtcC5kYXRhLCBiYXNlTmFtZSk7CiAgICAgICAgICAgICAgICBsb2cuZmx1c2goKTsgICAgICAgICAgCiAgICAgICAgICAgIH0KICAgICAgICAgICAgc2lkZXdheXNWaWV3LnNob3dDYWNoZURhdGEoKTsKICAgICAgICB9IGZpbmFsbHkgewogICAgICAgICAgICBsb2cuY2xvc2UoKTsKICAgICAgICAgICAgU3lzdGVtLm91dC5wcmludGxuKCJEb25lIik7CiAgICAgICB9CiAgICB9CiAgICAKICAgIC8qKgoJICogCgkgKi8KCXByaXZhdGUgdm9pZCB3cml0ZURURENoZWNrKCkgewoJCURFRkFVTFRfREVDTEhBTkRMRVIuY2hlY2tEYXRhKCk7Cgl9CgoJc3RhdGljIENvbGxhdG9yIERFRkFVTFRfQ09MTEFUSU9OID0gbnVsbDsKICAgIAogICAgc3RhdGljIGZpbmFsIFNldCBJR05PUkVBQkxFID0gIG5ldyBIYXNoU2V0KEFycmF5cy5hc0xpc3QobmV3IFN0cmluZ1tdIHsKICAgICAgICAgICAgImRyYWZ0IiwgCiAgICAgICAgICAgIC8vInJlZmVyZW5jZXMiLAogICAgICAgICAgICAvLyJzdGFuZGFyZCIKICAgIH0pKTsKCiAgICBzdGF0aWMgZmluYWwgU2V0IElHTk9SRUxJU1QgPSBuZXcgSGFzaFNldChBcnJheXMuYXNMaXN0KG5ldyBTdHJpbmdbXSB7CiAgICAgICAgICAgICJkcmFmdCIsICJzdGFuZGFyZCIsICJyZWZlcmVuY2VzIiwgInZhbGlkU3ViTG9jYWxlcyIKICAgIH0pKTsKCiAgICBzdGF0aWMgZmluYWwgU2V0IExFQUZOT0RFUyA9IG5ldyBIYXNoU2V0KEFycmF5cy5hc0xpc3QobmV3IFN0cmluZ1tdIHsKICAgICAgICAgICAgICAgICAgICJhbGlhcyIsICJkZWZhdWx0IiwgImZpcnN0RGF5IiwgIm1hcHBpbmciLCAibWVhc3VyZW1lbnRTeXN0ZW0iLCAKICAgICAgICAgICAgICAgICAgICJtaW5EYXlzIiwgIm9yaWVudGF0aW9uIiwgInNldHRpbmdzIiwgIndlZWtlbmRTdGFydCIsICJ3ZWVrZW5kRW5kIgogICB9KSk7CiAgICAKICAgIHN0YXRpYyBDb2xsYXRvciBnZXREZWZhdWx0Q29sbGF0aW9uKCkgewogICAgICAgIGlmIChERUZBVUxUX0NPTExBVElPTiAhPSBudWxsKSByZXR1cm4gREVGQVVMVF9DT0xMQVRJT047CiAgICAgICAgUnVsZUJhc2VkQ29sbGF0b3IgdGVtcCA9IChSdWxlQmFzZWRDb2xsYXRvcikgQ29sbGF0b3IuZ2V0SW5zdGFuY2UoVUxvY2FsZS5FTkdMSVNIKTsKICAgICAgICB0ZW1wLnNldFN0cmVuZ3RoKENvbGxhdG9yLklERU5USUNBTCk7CiAgICAgICAgdGVtcC5zZXROdW1lcmljQ29sbGF0aW9uKHRydWUpOwogICAgICAgIERFRkFVTFRfQ09MTEFUSU9OID0gdGVtcDsKICAgICAgICByZXR1cm4gdGVtcDsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGNsYXNzIFRpbWVab25lQWxpYXNlcyB7ICAgICAgICAKICAgIAlzdGF0aWMgTWFwIG1hcCA9IG51bGw7CiAgICAgICAgc3RhdGljIHZvaWQgaW5pdCgpIHsKICAgICAgICAgICAgbWFwID0gbmV3IEhhc2hNYXAoKTsKICAgICAgICAJdHJ5IHsKCQkJCUJ1ZmZlcmVkUmVhZGVyIGJyID0gQmFnRm9ybWF0dGVyLm9wZW5VVEY4UmVhZGVyKHRpbWVab25lQWxpYXNEaXIsICJ0aW1lem9uZV9hbGlhc2VzLnR4dCIpOwoJCQkJU3RyaW5nW10gcGllY2VzID0gbmV3IFN0cmluZ1syXTsKCQkJCXdoaWxlICh0cnVlKSB7CgkJCQkJU3RyaW5nIGxpbmUgPSBici5yZWFkTGluZSgpOwoJCQkJICAgIGlmIChsaW5lID09IG51bGwpIGJyZWFrOwoJCQkJICAgIFV0aWxpdHkuc3BsaXQobGluZSwnOycsIHBpZWNlcyk7CgkJCQkgICAgbWFwLnB1dChwaWVjZXNbMF0udHJpbSgpLCBwaWVjZXNbMV0udHJpbSgpKTsKCQkJCX0KCQkJCWJyLmNsb3NlKCk7CiAgICAgICAgICAgICAgICBtYXAucHV0KCIiLCJFTVBUWS1SRU1PVkUiKTsKCQkJfSBjYXRjaCAoSU9FeGNlcHRpb24gZSkgewogICAgICAgICAgICAgICAgdGhyb3cgbmV3IFJ1bnRpbWVFeGNlcHRpb24oZSk7CgkJCX0KICAgICAgICB9CiAgICAgICAgCiAgICAgICAgcHVibGljIHN0YXRpYyBTdHJpbmcgZ2V0KE9iamVjdCBpZCkgewogICAgICAgICAgICBpZiAobWFwID09IG51bGwpIGluaXQoKTsKICAgICAgICAJcmV0dXJuIChTdHJpbmcpIG1hcC5nZXQoaWQpOwogICAgICAgIH0KICAgIH0KCiAgICBzdGF0aWMgTWFwQ29tcGFyYXRvciBlbGVtZW50T3JkZXJpbmcgPSBuZXcgTWFwQ29tcGFyYXRvcigpOwogICAgc3RhdGljIE1hcENvbXBhcmF0b3IgYXR0cmlidXRlT3JkZXJpbmcgPSBuZXcgTWFwQ29tcGFyYXRvcigpOwogICAgewogICAgICAgIC8vIGhhY2sgdGhlIG9yZGVyaW5nIG9mIHRoZXNlIHR3bwogICAgICAgIGF0dHJpYnV0ZU9yZGVyaW5nLmFkZCgiYWx0Iik7CiAgICAgICAgYXR0cmlidXRlT3JkZXJpbmcuYWRkKCJkcmFmdCIpOwogICAgfQogICAgc3RhdGljIE1hcENvbXBhcmF0b3IgdmFsdWVPcmRlcmluZyA9IG5ldyBNYXBDb21wYXJhdG9yKCk7CiAgICAgICAgCiAgICBPcmRlcmVkTWFwIGRhdGEgPSBuZXcgT3JkZXJlZE1hcCgpOwogICAgTXlDb250ZW50SGFuZGxlciBERUZBVUxUX0hBTkRMRVIgPSBuZXcgTXlDb250ZW50SGFuZGxlcigpOwogICAgTXlEZWNsSGFuZGxlciBERUZBVUxUX0RFQ0xIQU5ETEVSID0gbmV3IE15RGVjbEhhbmRsZXIoKTsKICAgIFhNTFJlYWRlciB4bWxSZWFkZXI7CgogICAgLypTQVhQYXJzZXIgU0FYOwogICAgewogICAgICAgIHRyeSB7CiAgICAgICAgICAgIFNBWFBhcnNlckZhY3RvcnkgZmFjdG9yeSA9IFNBWFBhcnNlckZhY3RvcnkubmV3SW5zdGFuY2UoKTsKICAgICAgICAgICAgZmFjdG9yeS5zZXRWYWxpZGF0aW5nKHRydWUpOwoKICAgICAgICAgICAgU0FYID0gZmFjdG9yeS5uZXdTQVhQYXJzZXIoKTsKICAgICAgICB9IGNhdGNoIChFeGNlcHRpb24gZSkgewogICAgICAgICAgICB0aHJvdyBuZXcgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCJjYW4ndCBzdGFydCIpOwogICAgICAgIH0KICAgIH0KICAgICovCiAgICAKICAgIHN0YXRpYyBQcmludFdyaXRlciBsb2c7CiAgICAKICAgIC8qKgogICAgICogCiAgICAgKi8KICAgIC8qcHJpdmF0ZSB2b2lkIGFkZE1pc3NpbmcoKSB7CiAgICAgICAgU3RyaW5nW10gY3VycmVuY2llcyA9IGdldENvZGVzKG5ldyBVTG9jYWxlKCJlbiIsIiIsIiIpLCAiQ3VycmVuY2llcyIpOwogICAgICAgIC8vPGxkbWw+PG51bWJlcnM+PGN1cnJlbmNpZXM+PGN1cnJlbmN5IHR5cGU9IkFVRCI+PGRpc3BsYXlOYW1lPgogICAgICAgIGFkZEN1cnJlbmNpZXMoY3VycmVuY2llcywgImRpc3BsYXlOYW1lIik7CiAgICAgICAgYWRkQ3VycmVuY2llcyhjdXJyZW5jaWVzLCAic3ltYm9sIik7CiAgICB9CiAgICAqLwoKICAgIC8qCiAgICBwcml2YXRlIHZvaWQgYWRkQ3VycmVuY2llcyhTdHJpbmdbXSBjdXJyZW5jaWVzLCBTdHJpbmcgbGFzdEVsZW1lbnQpIHsKICAgICAgICBFbGVtZW50Q2hhaW4gdGVtcCA9IG5ldyBFbGVtZW50Q2hhaW4oKTsKICAgICAgICB0ZW1wLnB1c2goImxkbWwiLG51bGwpLnB1c2goIm51bWJlcnMiLG51bGwpLnB1c2goImN1cnJlbmNpZXMiLG51bGwpCiAgICAgICAgICAgIC5wdXNoKCJjdXJyZW5jeSIsbnVsbCkucHVzaChsYXN0RWxlbWVudCxudWxsLG51bGwpOwogICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgY3VycmVuY2llcy5sZW5ndGg7ICsraSkgewogICAgICAgICAgICB0ZW1wLnNldEF0dHJpYnV0ZSgiY3VycmVuY3kiLCJ0eXBlIixjdXJyZW5jaWVzW2ldKTsKICAgICAgICAgICAgU3RyaW5nIHZhbHVlID0gKFN0cmluZykgZGF0YS5nZXQodGVtcCk7CiAgICAgICAgICAgIGlmICh2YWx1ZSAhPSBudWxsKSBjb250aW51ZTsKICAgICAgICAgICAgcHV0RGF0YSh0ZW1wLCBjdXJyZW5jaWVzW2ldKTsKICAgICAgICB9CiAgICB9CiAgICAqLwogICAgCiAgICAvLyBVR0xZIGhhY2sKICAgIHByaXZhdGUgc3RhdGljIFN0cmluZ1tdIGdldENvZGVzKFVMb2NhbGUgbG9jYWxlLCBTdHJpbmcgdGFibGVOYW1lKSB7CiAgICAgICAgLy8gVE9ETyByZW1vdmUgVWdseSBIYWNrCiAgICAgICAgLy8gZ2V0IHN0dWZmCiAgICAgICAgSUNVUmVzb3VyY2VCdW5kbGUgYnVuZGxlID0gKElDVVJlc291cmNlQnVuZGxlKVVSZXNvdXJjZUJ1bmRsZS5nZXRCdW5kbGVJbnN0YW5jZShsb2NhbGUpOwogICAgICAgIElDVVJlc291cmNlQnVuZGxlIHRhYmxlID0gYnVuZGxlLmdldFdpdGhGYWxsYmFjayh0YWJsZU5hbWUpOwogICAgICAgIC8vIGNvcHkgaW50byBhcnJheQogICAgICAgIEFycmF5TGlzdCBzdHVmZiA9IG5ldyBBcnJheUxpc3QoKTsKICAgICAgICBmb3IgKEVudW1lcmF0aW9uIGtleXMgPSB0YWJsZS5nZXRLZXlzKCk7IGtleXMuaGFzTW9yZUVsZW1lbnRzKCk7KSB7CiAgICAgICAgICAgIHN0dWZmLmFkZChrZXlzLm5leHRFbGVtZW50KCkpOwogICAgICAgIH0KICAgICAgICBTdHJpbmdbXSByZXN1bHQgPSBuZXcgU3RyaW5nW3N0dWZmLnNpemUoKV07CiAgICAgICAgcmV0dXJuIChTdHJpbmdbXSkgc3R1ZmYudG9BcnJheShyZXN1bHQpOwogICAgICAgIC8vcmV0dXJuIG5ldyBTdHJpbmdbXSB7IkxhdG4iLCAiQ3lybCJ9OwogICAgfQoKCiAgICBzdGF0aWMgTWFwIGNhY2hlID0gbmV3IEhhc2hNYXAoKTsKICAgIAogICAgc3RhdGljIEdlbmVyYXRlU2lkZXdheXNWaWV3IGdldENMRFIoU3RyaW5nIHMsIGJvb2xlYW4gdmFsaWRhdGluZykgdGhyb3dzIFNBWEV4Y2VwdGlvbiwgSU9FeGNlcHRpb24gewogICAgICAgIEdlbmVyYXRlU2lkZXdheXNWaWV3IHRlbXAgPSAoR2VuZXJhdGVTaWRld2F5c1ZpZXcpY2FjaGUuZ2V0KHMpOwogICAgICAgIGlmICh0ZW1wID09IG51bGwpIHsKICAgICAgICAgICAgdGVtcCA9IG5ldyBHZW5lcmF0ZVNpZGV3YXlzVmlldyhzLCB2YWxpZGF0aW5nKTsKICAgICAgICAgICAgY2FjaGUucHV0KHMsdGVtcCk7CiAgICAgICAgfQogICAgICAgIHJldHVybiB0ZW1wOwogICAgfQogICAgCiAgICBTdHJpbmcgZmlsZW5hbWU7CiAgICBHZW5lcmF0ZVNpZGV3YXlzVmlldyBwYXJlbnQgPSBudWxsOwogICAgICAgIAogICAgcHJpdmF0ZSBHZW5lcmF0ZVNpZGV3YXlzVmlldyhTdHJpbmcgZmlsZW5hbWUsIGJvb2xlYW4gdmFsaWRhdGluZykgdGhyb3dzIFNBWEV4Y2VwdGlvbiwgSU9FeGNlcHRpb24gewogICAgICAgIHRoaXMuZmlsZW5hbWUgPSBmaWxlbmFtZTsKICAgICAgICB4bWxSZWFkZXIgPSBjcmVhdGVYTUxSZWFkZXIodmFsaWRhdGluZyk7CiAgICAgICAgLy8gbWFrZSBzdXJlIHRoZSBwYXJlbnRzIGFyZSBsb2FkZWQgaW50byBjYWNoZSBiZWZvcmUgd2UgYXJlCiAgICAgICAgU3RyaW5nIHBhcmVudE5hbWUgPSBnZXRQYXJlbnRGaWxlbmFtZShmaWxlbmFtZSk7CiAgICAgICAgaWYgKHBhcmVudE5hbWUgIT0gbnVsbCkgewogICAgICAgICAgICBwYXJlbnQgPSBnZXRDTERSKHBhcmVudE5hbWUsIHZhbGlkYXRpbmcpOwogICAgICAgIH0KICAgICAgICAvL1N5c3RlbS5vdXQucHJpbnRsbigiQ3JlYXRpbmcgIiArIGZpbGVuYW1lKTsKCiAgICAgICAgeG1sUmVhZGVyLnNldENvbnRlbnRIYW5kbGVyKERFRkFVTFRfSEFORExFUik7CiAgICAgICAgeG1sUmVhZGVyLnNldFByb3BlcnR5KCJodHRwOi8veG1sLm9yZy9zYXgvcHJvcGVydGllcy9sZXhpY2FsLWhhbmRsZXIiLERFRkFVTFRfSEFORExFUik7CiAgICAgICAgaWYgKG9wdGlvbnNbU0hPV19EVERdLmRvZXNPY2N1cikgeG1sUmVhZGVyLnNldFByb3BlcnR5KCJodHRwOi8veG1sLm9yZy9zYXgvcHJvcGVydGllcy9kZWNsYXJhdGlvbi1oYW5kbGVyIiwgREVGQVVMVF9ERUNMSEFORExFUik7CgogICAgICAgIHJlYWRGcm9tKG9wdGlvbnNbU09VUkNFRElSXS52YWx1ZSwgZmlsZW5hbWUpOwogICAgICAgIC8vIHdhbGsgdGhyb3VnaCB0aGUgbWFwIHJlbW92aW5nIGFueXRoaW5nIHRoYXQgaXMgaW5oZXJpdGVkIGZyb20gYSBwYXJlbnQuCiAgICAgICAgLy8gY2hhbmdlZCBzbyB0aGF0IHdlIHN0b3Agd2hlbiB0aGUgcGFyZW50IGhhcyBhbiBlbGVtZW50CiAgICAgICAgaWYgKHBhcmVudCAhPSBudWxsKSB7CiAgICAgICAgICAgIFBhcmVudCBwYXJlbnRPdXQgPSBuZXcgUGFyZW50KCk7CiAgICAgICAgICAgIE1hcCB0b1JlbW92ZSA9IG5ldyBUcmVlTWFwKCk7CiAgICAgICAgICAgIGZvciAoSXRlcmF0b3IgaXQgPSBkYXRhLml0ZXJhdG9yKCk7IGl0Lmhhc05leHQoKTspIHsKICAgICAgICAgICAgICAgIE9iamVjdCBrZXkgPSBpdC5uZXh0KCk7CiAgICAgICAgICAgICAgICBpZiAoKChFbGVtZW50Q2hhaW4pa2V5KS5jb250YWluc0VsZW1lbnQoImlkZW50aXR5IikpIGNvbnRpbnVlOwogICAgICAgICAgICAgICAgRW5kTm9kZSB2YWx1ZSA9IChFbmROb2RlKSBkYXRhLmdldChrZXkpOwogICAgICAgICAgICAgICAgT2JqZWN0IGluaGVyaXRlZFZhbHVlID0gZ2V0SW5oZXJpdGVkVmFsdWUoa2V5LCBwYXJlbnRPdXQpOwogICAgICAgICAgICAgICAgaWYgKHZhbHVlLmVxdWFscyhpbmhlcml0ZWRWYWx1ZSkpIHsKICAgICAgICAgICAgICAgICAgICAvLyBkZWJ1Z2dpbmc6IGRhdGEuZ2V0KGtleSk7CiAgICAgICAgICAgICAgICAgICAgLy9nZXRJbmhlcml0ZWRWYWx1ZShrZXkpOwogICAgICAgICAgICAgICAgICAgIC8vdmFsdWUuZXF1YWxzKGluaGVyaXRlZFZhbHVlKTsKICAgICAgICAgICAgICAgICAgICB0b1JlbW92ZS5wdXQoa2V5LCBwYXJlbnRPdXQucGFyZW50KTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgICAgICBmb3IgKEl0ZXJhdG9yIGl0ID0gdG9SZW1vdmUua2V5U2V0KCkuaXRlcmF0b3IoKTsgaXQuaGFzTmV4dCgpOykgewogICAgICAgICAgICAgICAgRWxlbWVudENoYWluIGtleSA9IChFbGVtZW50Q2hhaW4paXQubmV4dCgpOwogICAgICAgICAgICAgICAgRW5kTm9kZSB2YWx1ZSA9IChFbmROb2RlKSBkYXRhLmdldChrZXkpOwogICAgICAgICAgICAgICAgR2VuZXJhdGVTaWRld2F5c1ZpZXcgcGFyZW50ID0gKEdlbmVyYXRlU2lkZXdheXNWaWV3KSB0b1JlbW92ZS5nZXQoa2V5KTsKICAgICAgICAgICAgICAgIEVuZE5vZGUgcGFyZW50VmFsdWUgPSAoRW5kTm9kZSkgcGFyZW50LmRhdGEuZ2V0KGtleSk7CiAgICAgICAgICAgICAgICBsb2cucHJpbnRsbigiUmVtb3ZpbmcgIiArIGtleS50b1N0cmluZyh0cnVlLCAwLCBJbnRlZ2VyLk1BWF9WQUxVRSkgKyAiXHQiICsgdmFsdWUpOwogICAgICAgICAgICAgICAgRWxlbWVudENoYWluIHBhcmVudEtleSA9IChFbGVtZW50Q2hhaW4pIHBhcmVudC5kYXRhLmdldEtleUZvcihrZXkpOwogICAgICAgICAgICAgICAgbG9nLnByaW50bG4oIlx0SW4gIiArIHBhcmVudC5maWxlbmFtZSArICI6XHQiICsgcGFyZW50S2V5LnRvU3RyaW5nKHRydWUsIDAsIEludGVnZXIuTUFYX1ZBTFVFKSArICJcdCIrIHBhcmVudFZhbHVlKTsKICAgICAgICAgICAgICAgIGRhdGEucmVtb3ZlKGtleSk7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICB9CiAgICAKICAgIHN0YXRpYyBjbGFzcyBQYXJlbnQgewogICAgCUdlbmVyYXRlU2lkZXdheXNWaWV3IHBhcmVudDsKICAgIH0KICAgIHByaXZhdGUgT2JqZWN0IGdldEluaGVyaXRlZFZhbHVlKE9iamVjdCBrZXksIFBhcmVudCBwYXJlbnRPdXQpIHsKICAgICAgICBpZiAocGFyZW50ID09IG51bGwpIHsKICAgICAgICAgICAgcGFyZW50T3V0LnBhcmVudCA9IG51bGw7CiAgICAgICAgICAgIHJldHVybiBudWxsOwogICAgICAgIH0KICAgICAgICBFbmROb2RlIHZhbHVlID0gKEVuZE5vZGUpIHBhcmVudC5kYXRhLmdldChrZXkpOwogICAgICAgIGlmICh2YWx1ZSAhPSBudWxsKSB7CiAgICAgICAgICAgIHBhcmVudE91dC5wYXJlbnQgPSBwYXJlbnQ7CiAgICAgICAgICAgIHJldHVybiB2YWx1ZTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHBhcmVudC5nZXRJbmhlcml0ZWRWYWx1ZShrZXksIHBhcmVudE91dCk7CiAgICB9CiAgICAKICAgIC8qCiAgICBTZXQgYmFkVGltZXpvbmVJRHMgPSBudWxsOwogICAgIHByaXZhdGUgdm9pZCBkZXRlY3RBbGlhc2VzKFN0cmluZyBmaWxlbmFtZSkgewogICAgICAKICAgICAgICBTZXQgcHJvYmxlbXMgPSBuZXcgVHJlZVNldCgpOwogICAgICAgIGZvciAoSXRlcmF0b3IgaXQgPSBkYXRhLml0ZXJhdG9yKCk7IGl0Lmhhc05leHQoKTspIHsKICAgICAgICAgICAgRWxlbWVudENoYWluIGtleSA9IChFbGVtZW50Q2hhaW4pIGl0Lm5leHQoKTsKICAgICAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBrZXkuY29udGV4dHMuc2l6ZSgpOyArK2kpIHsKICAgICAgICAgICAgCUVsZW1lbnQgZSA9IChFbGVtZW50KSBrZXkuY29udGV4dHMuZ2V0KGkpOwogICAgICAgICAgICAgICAgaWYgKCFlLmVsZW1lbnROYW1lLmVxdWFscygiem9uZSIpKSBjb250aW51ZTsKICAgICAgICAgICAgICAgIGZvciAoSXRlcmF0b3IgcSA9IGUuYXR0cmlidXRlcy5jb250ZW50cy5pdGVyYXRvcigpOyBxLmhhc05leHQoKTsgKSB7CiAgICAgICAgICAgICAgICAgICAgU2ltcGxlQXR0cmlidXRlIGEgPSAoU2ltcGxlQXR0cmlidXRlKXEubmV4dCgpOwogICAgICAgICAgICAgICAgICAgIGlmICghYS5uYW1lLmVxdWFscygidHlwZSIpKSBjb250aW51ZTsKICAgICAgICAgICAgICAgICAgICBTdHJpbmcgb3RoZXIgPSBUaW1lWm9uZUFsaWFzZXMuZ2V0KGEudmFsdWUpOwogICAgICAgICAgICAgICAgICAgIGlmIChvdGhlciAhPSBudWxsKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIHByb2JsZW1zLmFkZChhLnZhbHVlKTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAKICAgICAgICBmb3IgKEl0ZXJhdG9yIGl0ID0gYmFkVGltZXpvbmVJRHMuaXRlcmF0b3IoKTsgaXQuaGFzTmV4dCgpOykgewogICAgICAgICAgICBTdHJpbmcgb2xkT25lID0gKFN0cmluZylpdC5uZXh0KCk7CiAgICAgICAgICAgIFN0cmluZyBuZXdPbmUgPSBUaW1lWm9uZUFsaWFzZXMuZ2V0KG9sZE9uZSk7CiAgICAgICAgCWxvZy5wcmludGxuKCJGaXggVGltZXpvbmUgQWxpYXM6ICIgKyBmaWxlbmFtZSArICJcdCIgKyBvbGRPbmUgKyAiID0+ICIgKyBuZXdPbmUpOwogICAgICAgIH0KICAgIH0gKi8KICAgIAogICAgLyoKICAgIHByaXZhdGUgdm9pZCByZW1vdmVBbGwoR2VuZXJhdGVTaWRld2F5c1ZpZXcgdGVtcCkgewogICAgICAgIGRhdGEucmVtb3ZlQWxsKHRlbXAuZGF0YSk7CiAgICB9CiAgICAqLwoKICAgIHByaXZhdGUgc3RhdGljIFN0cmluZyBnZXRQYXJlbnRGaWxlbmFtZShTdHJpbmcgZmlsZW5hbWUpIHsKICAgICAgICBpZiAoZmlsZW5hbWUuZXF1YWxzKCJ6aF9UVyIpKSByZXR1cm4gInpoX0hhbnQiOwogICAgICAgIGludCBwb3MgPSBmaWxlbmFtZS5sYXN0SW5kZXhPZignXycpOwogICAgICAgIGlmIChwb3MgPj0gMCkgewogICAgICAgICAgICByZXR1cm4gZmlsZW5hbWUuc3Vic3RyaW5nKDAscG9zKTsKICAgICAgICB9CiAgICAgICAgaWYgKGZpbGVuYW1lLmVxdWFscygicm9vdCIpKSByZXR1cm4gbnVsbDsKICAgICAgICByZXR1cm4gInJvb3QiOwogICAgfQoKICAgIHByaXZhdGUgdm9pZCB3cml0ZVRvKFN0cmluZyBkaXIsIFN0cmluZyBmaWxlbmFtZSkgdGhyb3dzIElPRXhjZXB0aW9uIHsKICAgICAgICBQcmludFdyaXRlciBvdXQgPSBCYWdGb3JtYXR0ZXIub3BlblVURjhXcml0ZXIoZGlyLCBmaWxlbmFtZSArICIueG1sIik7CiAgICAgICAgb3V0LnByaW50bG4odGhpcyk7CiAgICAgICAgb3V0LmNsb3NlKCk7CiAgICB9CgogICAgcHVibGljIHZvaWQgcmVhZEZyb20oU3RyaW5nIGRpciwgU3RyaW5nIGZpbGVuYW1lKSB0aHJvd3MgU0FYRXhjZXB0aW9uLCBJT0V4Y2VwdGlvbiB7CiAgICAgICAgRmlsZSBmID0gbmV3IEZpbGUoZGlyICsgZmlsZW5hbWUgKyAiLnhtbCIpOwogICAgICAgIFN5c3RlbS5vdXQucHJpbnRsbigiUGFyc2luZzogIiArIGYuZ2V0Q2Fub25pY2FsUGF0aCgpKTsKICAgICAgICBsb2cucHJpbnRsbigiUGFyc2luZzogIiArIGYuZ2V0Q2Fub25pY2FsUGF0aCgpKTsKICAgICAgICB4bWxSZWFkZXIucGFyc2UobmV3IElucHV0U291cmNlKG5ldyBGaWxlSW5wdXRTdHJlYW0oZikpKTsKICAgICAgICAvL1NBWC5wYXJzZShmLCBERUZBVUxUX0hBTkRMRVIpOwogICAgfQogICAgCiAgICBwcml2YXRlIFNldCBmaW5kRHVwbGljYXRlWm9uZUlEcygpIHsKICAgICAgICBTZXQgcmVzdWx0ID0gbmV3IEhhc2hTZXQoKTsKICAgICAgICAvLyBpZiBhIHNldCBjb250YWlucyBib3RoIEVTVCBhbmQgQW1lcmljYS9JbmRpYW5hcG9saXMsIHJlbW92ZSB0aGUgZm9ybWVyCiAgICAJZm9yIChJdGVyYXRvciBpdCA9IHpvbmVJRHMuaXRlcmF0b3IoKTsgaXQuaGFzTmV4dCgpOykgewogICAgICAgICAgICBPYmplY3QgcG9zc2libGVPbWlzc2lvbiA9IGl0Lm5leHQoKTsKICAgIAkJT2JqZWN0IG8gPSBUaW1lWm9uZUFsaWFzZXMuZ2V0KHBvc3NpYmxlT21pc3Npb24pOwogICAgICAgICAgICBpZiAobyA9PSBudWxsKSBjb250aW51ZTsKICAgICAgICAgICAgaWYgKHpvbmVJRHMuY29udGFpbnMobykpIHJlc3VsdC5hZGQocG9zc2libGVPbWlzc2lvbik7CiAgICAgICAgfQogICAgICAgIHJldHVybiByZXN1bHQ7CiAgICB9CiAgICAKICAgIHB1YmxpYyBTdHJpbmcgdG9TdHJpbmcoKSB7CiAgICAgICAgU3RyaW5nQnVmZmVyIGJ1ZmZlciA9IG5ldyBTdHJpbmdCdWZmZXIoKTsKCiAgICAgICAgYnVmZmVyLmFwcGVuZCgiPD94bWwgdmVyc2lvbj1cIjEuMFwiIGVuY29kaW5nPVwiVVRGLThcIiA/PiIrTkVXTElORQogICAgICAgICsgIjwhRE9DVFlQRSBsZG1sIFNZU1RFTSBcImh0dHA6Ly93d3cudW5pY29kZS5vcmcvY2xkci9kdGQvMS4yL2JldGEvbGRtbC5kdGRcIj4iK05FV0xJTkUpOwogICAgICAgIAogICAgICAgIFNldCBkdXBsaWNhdGVab25lSURzID0gZmluZER1cGxpY2F0ZVpvbmVJRHMoKTsKICAgICAgICAvL2JhZFRpbWV6b25lSURzID0gbmV3IFRyZWVTZXQoKTsKICAgICAgICAKICAgICAgICBFbGVtZW50Q2hhaW4gZW1wdHkgPSBuZXcgRWxlbWVudENoYWluKCk7CiAgICAgICAgRWxlbWVudENoYWluIG9sZCA9IGVtcHR5OwogICAgICAgIGZvciAoSXRlcmF0b3IgaXQgPSBkYXRhLml0ZXJhdG9yKCk7IGl0Lmhhc05leHQoKTspIHsKICAgICAgICAgICAgRWxlbWVudENoYWluIGtleSA9IChFbGVtZW50Q2hhaW4pIGl0Lm5leHQoKTsKICAgICAgICAgICAgaWYgKEZJWF9aT05FX0FMSUFTRVMpIHsKICAgICAgICAgICAgICAgIEVsZW1lbnQgem9uZUVsZW1lbnQgPSBrZXkuZ2V0RWxlbWVudCgiem9uZSIpOwogICAgICAgICAgICAgICAgaWYgKHpvbmVFbGVtZW50ICE9IG51bGwpIHsKICAgICAgICAgICAgICAgIAlTdHJpbmcgem9uZVR5cGVWYWx1ZSA9IHpvbmVFbGVtZW50LmdldFZhbHVlKCJ0eXBlIik7CiAgICAgICAgICAgICAgICAgICAgaWYgKHpvbmVUeXBlVmFsdWUgIT0gbnVsbCkgewogICAgICAgICAgICAgICAgCQlpZiAoZHVwbGljYXRlWm9uZUlEcy5jb250YWlucyh6b25lVHlwZVZhbHVlKSkgY29udGludWU7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgICAgIGlmICh0cnVlKSB7CiAgICAgICAgICAgICAgICAvLyB3ZWVrZW5kRW5kIGRyYWZ0PSJ0cnVlIiB0aW1lPSIwMDowMCIgTkVWRVIgb2sKICAgICAgICAgICAgICAgIEVsZW1lbnQgem9uZUVsZW1lbnQgPSBrZXkuZ2V0RWxlbWVudCgid2Vla2VuZEVuZCIpOwogICAgICAgICAgICAgICAgaWYgKHpvbmVFbGVtZW50ICE9IG51bGwpIHsKICAgICAgICAgICAgICAgICAgICBTdHJpbmcgem9uZVR5cGVWYWx1ZSA9IHpvbmVFbGVtZW50LmdldFZhbHVlKCJ0aW1lIik7CiAgICAgICAgICAgICAgICAgICAgaWYgKCIwMDowMCIuZXF1YWxzKHpvbmVUeXBlVmFsdWUpKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIGxvZy5wcmludGxuKCJCQUQgV0VFS0VOREVORCBUSU1FOiAiICsgem9uZVR5cGVWYWx1ZSk7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgICAgIEVuZE5vZGUgdmFsdWUgPSAoRW5kTm9kZSkgZGF0YS5nZXQoa2V5KTsKICAgICAgICAgICAga2V5LndyaXRlRGlmZmVyZW5jZShvbGQsIHZhbHVlLCBidWZmZXIpOwogICAgICAgICAgICBvbGQgPSBrZXk7ICAgICAgICAgICAKICAgICAgICB9CiAgICAgICAgZW1wdHkud3JpdGVEaWZmZXJlbmNlKG9sZCwgbnVsbCwgYnVmZmVyKTsKICAgICAgICB3cml0ZUVsZW1lbnRDb21tZW50KGJ1ZmZlcixmaW5hbENvbW1lbnQsMCk7CgogICAgICAgIHJldHVybiBidWZmZXIudG9TdHJpbmcoKTsKICAgIH0KICAgIAogICAgc3RhdGljIHZvaWQgZ2VuZXJhdGVCYXQoU3RyaW5nIHNvdXJjZURpciwgU3RyaW5nIHNvdXJjZUZpbGUsIFN0cmluZyB0YXJnZXREaXIsIFN0cmluZyB0YXJnZXRGaWxlKSB7CiAgICAgICAgYm9vbGVhbiBuZWVkQmF0ID0gdHJ1ZTsKICAgICAgICB0cnkgewoJCQlCdWZmZXJlZFJlYWRlciBiMSA9IEJhZ0Zvcm1hdHRlci5vcGVuVVRGOFJlYWRlcihzb3VyY2VEaXIsIHNvdXJjZUZpbGUpOwogICAgICAgICAgICBCdWZmZXJlZFJlYWRlciBiMiA9IEJhZ0Zvcm1hdHRlci5vcGVuVVRGOFJlYWRlcih0YXJnZXREaXIsIHRhcmdldEZpbGUpOwogICAgICAgICAgICB3aGlsZSAodHJ1ZSkgewogICAgICAgICAgICAJU3RyaW5nIGxpbmUxID0gYjEucmVhZExpbmUoKTsKICAgICAgICAgICAgICAgIFN0cmluZyBsaW5lMiA9IGIyLnJlYWRMaW5lKCk7CiAgICAgICAgICAgICAgICBpZiAobGluZTEgPT0gbnVsbCAmJiBsaW5lMiA9PSBudWxsKSB7CiAgICAgICAgICAgICAgICAgICAgbmVlZEJhdCA9IGZhbHNlOwogICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgaWYgKGxpbmUxID09IG51bGwgfHwgbGluZTIgPT0gbnVsbCkgewogICAgICAgICAgICAgICAgICAgIGlmIChERUJVR19TSE9XX0JBVCkgU3lzdGVtLm91dC5wcmludGxuKCIqRmlsZSBsaW5lIGNvdW50cyBkaWZmZXI6ICIpOwogICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgaWYgKCFlcXVhbHNJZ25vcmluZ1doaXRlc3BhY2UobGluZTEsIGxpbmUyKSkgewogICAgICAgICAgICAgICAgICAgIGlmIChERUJVR19TSE9XX0JBVCkgewogICAgICAgICAgICAgICAgICAgICAgICBTeXN0ZW0ub3V0LnByaW50bG4oIipGaWxlIGxpbmVzIGRpZmZlcjogIik7CiAgICAgICAgICAgICAgICAgICAgICAgIFN5c3RlbS5vdXQucHJpbnRsbigiXHQxXHQiICsgbGluZTEpOwogICAgICAgICAgICAgICAgICAgICAgICBTeXN0ZW0ub3V0LnByaW50bG4oIlx0Mlx0IiArIGxpbmUyKTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICAgICAgYjEuY2xvc2UoKTsKICAgICAgICAgICAgYjIuY2xvc2UoKTsKICAgICAgICAgICAgU3RyaW5nIGJhdERpciA9IHRhcmdldERpciArIEZpbGUuc2VwYXJhdG9yICsgImRpZmYiICsgRmlsZS5zZXBhcmF0b3I7CiAgICAgICAgICAgIFN0cmluZyBiYXROYW1lID0gdGFyZ2V0RmlsZSArICIuYmF0IjsKICAgICAgICAgICAgaWYgKG5lZWRCYXQpIHsKICAgICAgICAgICAgCVByaW50V3JpdGVyIGJhdCA9IEJhZ0Zvcm1hdHRlci5vcGVuVVRGOFdyaXRlcihiYXREaXIsIGJhdE5hbWUpOwogICAgICAgICAgICAgICAgYmF0LnByaW50bG4oIlwiQzpcXFByb2dyYW0gRmlsZXNcXENvbXBhcmUgSXQhXFx3aW5jbXAzLmV4ZVwiICIgKwogICAgICAgICAgICAgICAgICAgICAgICBuZXcgRmlsZShzb3VyY2VEaXIgKyBzb3VyY2VGaWxlKS5nZXRDYW5vbmljYWxQYXRoKCkgKyAiICIgKwogICAgICAgICAgICAgICAgICAgICAgICBuZXcgRmlsZSh0YXJnZXREaXIgKyB0YXJnZXRGaWxlKS5nZXRDYW5vbmljYWxQYXRoKCkpOwogICAgICAgICAgICAgICAgYmF0LmNsb3NlKCk7CiAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIAlGaWxlIGYgPSBuZXcgRmlsZShiYXREaXIgKyBiYXROYW1lKTsKICAgICAgICAgICAgICAgIGlmIChmLmV4aXN0cygpKSB7CiAgICAgICAgICAgICAgICAJaWYgKERFQlVHX1NIT1dfQkFUKSBTeXN0ZW0ub3V0LnByaW50bG4oIipEZWxldGluZyBvbGQgIiArIGYuZ2V0Q2Fub25pY2FsUGF0aCgpKTsKICAgICAgICAgICAgICAgIAlmLmRlbGV0ZSgpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CgkJfSBjYXRjaCAoSU9FeGNlcHRpb24gZSkgewoJCQkvLyBUT0RPIEF1dG8tZ2VuZXJhdGVkIGNhdGNoIGJsb2NrCgkJCWUucHJpbnRTdGFja1RyYWNlKCk7CgkJfQogICAgICAgIAogICAgIC8vIAogICAKICAgIH0KICAgIAogICAgc3RhdGljIGJvb2xlYW4gZXF1YWxzSWdub3JpbmdXaGl0ZXNwYWNlKFN0cmluZyBhLCBTdHJpbmcgYikgewogICAgICAgIGludCBpID0gMDsKICAgICAgICBpbnQgaiA9IDA7CiAgICAgICAgY2hhciBjLCBkOwogICAgCXdoaWxlICh0cnVlKSB7IC8vIGRvbid0IHdvcnJ5IGFib3V0IHN1cnJvZ2F0ZXMKICAgICAgICAgICAgZG8ge2MgPSBpIDwgYS5sZW5ndGgoKSA/IGEuY2hhckF0KGkrKykgOiAweEZGRkY7fSB3aGlsZSAoVUNoYXJhY3Rlci5pc1VXaGl0ZVNwYWNlKGMpKTsKICAgICAgICAgICAgZG8ge2QgPSBqIDwgYi5sZW5ndGgoKSA/IGIuY2hhckF0KGorKykgOiAweEZGRkY7fSB3aGlsZSAoVUNoYXJhY3Rlci5pc1VXaGl0ZVNwYWNlKGQpKTsKICAgICAgICAgICAgaWYgKGMgIT0gZCkgcmV0dXJuIGZhbHNlOwogICAgICAgICAgICBpZiAoYyA9PSAweEZGRkYpIHJldHVybiB0cnVlOwogICAgICAgIH0KICAgIH0KCiAgICBzdGF0aWMgY2xhc3MgU2ltcGxlQXR0cmlidXRlIGltcGxlbWVudHMgQ29tcGFyYWJsZSB7CiAgICAgICAgU3RyaW5nIG5hbWU7CiAgICAgICAgU3RyaW5nIHZhbHVlOwogICAgICAgIFNpbXBsZUF0dHJpYnV0ZShTdHJpbmcgbmFtZSwgU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgICAgIGF0dHJpYnV0ZU9yZGVyaW5nLmFkZChuYW1lKTsKICAgICAgICAgICAgdmFsdWVPcmRlcmluZy5hZGQodmFsdWUpOwogICAgICAgICAgICB0aGlzLm5hbWUgPSBuYW1lOwogICAgICAgICAgICB0aGlzLnZhbHVlID0gdmFsdWU7CiAgICAgICAgfQogICAgICAgIHB1YmxpYyBib29sZWFuIGVxdWFscyhPYmplY3Qgb3RoZXIpIHsKICAgICAgICAgICAgcmV0dXJuIGNvbXBhcmVUbyhvdGhlcikgPT0gMDsKICAgICAgICB9CiAgICAgICAgcHVibGljIGludCBoYXNoQ29kZSgpIHsKICAgICAgICAgICAgcmV0dXJuIG5hbWUuaGFzaENvZGUoKSBeIHZhbHVlLmhhc2hDb2RlKCk7CiAgICAgICAgfQogICAgICAgIHB1YmxpYyBTdHJpbmcgdG9TdHJpbmcoKSB7cmV0dXJuIHRvU3RyaW5nKHRydWUpO30KICAgICAgICBwdWJsaWMgU3RyaW5nIHRvU3RyaW5nKGJvb2xlYW4gcGF0aCkgewogICAgICAgICAgICBpZiAocGF0aCkgewogICAgICAgICAgICAJcmV0dXJuICJbQCIgKyBuYW1lICsgIj0nIiArIEJhZ0Zvcm1hdHRlci50b0hUTUwudHJhbnNsaXRlcmF0ZSh2YWx1ZSkgKyAiJ10iOwogICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgcmV0dXJuICIgIiArIG5hbWUgKyAiPVwiIiArIEJhZ0Zvcm1hdHRlci50b1hNTC50cmFuc2xpdGVyYXRlKHZhbHVlKSArICJcIiI7ICAgICAgICAgICAgICAgIAogICAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIHB1YmxpYyBpbnQgY29tcGFyZVRvKE9iamVjdCBvKSB7CiAgICAgICAgICAgIFNpbXBsZUF0dHJpYnV0ZSB0aGF0ID0gKFNpbXBsZUF0dHJpYnV0ZSkgbzsKICAgICAgICAgICAgaW50IHJlc3VsdDsKICAgICAgICAgICAgaWYgKChyZXN1bHQgPSBhdHRyaWJ1dGVPcmRlcmluZy5jb21wYXJlKG5hbWUsIHRoYXQubmFtZSkpICE9IDApIHJldHVybiByZXN1bHQ7CiAgICAgICAgICAgIHJldHVybiB2YWx1ZU9yZGVyaW5nLmNvbXBhcmUodmFsdWUsIHRoYXQudmFsdWUpOwogICAgICAgIH0KICAgIH0KICAgIAogICAgU2V0IHpvbmVJRHMgPSBuZXcgSGFzaFNldCgpOwogICAgCiAgICBjbGFzcyBTaW1wbGVBdHRyaWJ1dGVzIGltcGxlbWVudHMgQ29tcGFyYWJsZSB7CiAgICAgICAgU2V0IGNvbnRlbnRzID0gbmV3IFRyZWVTZXQoKTsKICAgICAgICAKICAgICAgICBTaW1wbGVBdHRyaWJ1dGVzKCkge30KICAgICAgICAKICAgICAgICBTaW1wbGVBdHRyaWJ1dGVzKFNpbXBsZUF0dHJpYnV0ZXMgb3RoZXIsIFN0cmluZyBlbGVtZW50TmFtZSkgewogICAgICAgICAgICBjb250ZW50cy5jbGVhcigpOwogICAgICAgICAgICBjb250ZW50cy5hZGRBbGwob3RoZXIuY29udGVudHMpOwogICAgICAgIH0KICAgICAgICAKICAgICAgICBTaW1wbGVBdHRyaWJ1dGVzKEF0dHJpYnV0ZXMgYXR0cmlidXRlcywgU3RyaW5nIGVsZW1lbnROYW1lKSB7CiAgICAgICAgICAgIGJvb2xlYW4gaW5ab25lID0gZWxlbWVudE5hbWUuZXF1YWxzKCJ6b25lIik7CiAgICAgICAgICAgIGlmIChhdHRyaWJ1dGVzICE9IG51bGwpIHsKICAgICAgICAgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgYXR0cmlidXRlcy5nZXRMZW5ndGgoKTsgKytpKSB7CiAgICAgICAgICAgICAgICAgICAgU3RyaW5nIG5hbWUgPSBhdHRyaWJ1dGVzLmdldFFOYW1lKGkpOwogICAgICAgICAgICAgICAgICAgIFN0cmluZyB2YWx1ZSA9IGF0dHJpYnV0ZXMuZ2V0VmFsdWUoaSk7CiAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgaWYgKEZJWF9aT05FX0FMSUFTRVMgJiYgaW5ab25lKSB7CiAgICAgICAgICAgICAgICAgICAgCWlmIChuYW1lLmVxdWFscygidHlwZSIpKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICB6b25lSURzLmFkZCh2YWx1ZSk7CiAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgLy8gaGFjayB0byByZW1vdmVkICNJTVBMSUVECiAgICAgICAgICAgICAgICAgICAgaWYgKGVsZW1lbnROYW1lLmVxdWFscygibGRtbCIpCiAgICAgICAgICAgICAgICAgICAgICAgICYmIG5hbWUuZXF1YWxzKCJ2ZXJzaW9uIikpIGNvbnRpbnVlOyAvLyBza2lwIHZlcnNpb24KICAgICAgICAgICAgICAgICAgICBpZiAobmFtZS5lcXVhbHMoInR5cGUiKSAKICAgICAgICAgICAgICAgICAgICAgICAgJiYgdmFsdWUuZXF1YWxzKCJzdGFuZGFyZCIpKSBjb250aW51ZTsKCiAgICAgICAgICAgICAgICAgICAgY29udGVudHMuYWRkKG5ldyBTaW1wbGVBdHRyaWJ1dGUobmFtZSwgdmFsdWUpKTsKICAgICAgICAgICAgICAgICAgICB0cmlwbGVEYXRhLnJlY29yZERhdGEoZWxlbWVudE5hbWUsIG5hbWUsIHZhbHVlKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgIH0KICAgICAgICAKICAgICAgICBwdWJsaWMgU3RyaW5nIHRvU3RyaW5nKCkge3JldHVybiB0b1N0cmluZyh0cnVlLCBmYWxzZSk7fQogICAgICAgIHB1YmxpYyBTdHJpbmcgdG9TdHJpbmcoYm9vbGVhbiBwYXRoLCBib29sZWFuIGlzWm9uZSkgewogICAgICAgICAgICBTdHJpbmdCdWZmZXIgYnVmZmVyID0gbmV3IFN0cmluZ0J1ZmZlcigpOwogICAgICAgICAgICBmb3IgKEl0ZXJhdG9yIGl0ID0gY29udGVudHMuaXRlcmF0b3IoKTsgaXQuaGFzTmV4dCgpOykgewogICAgICAgICAgICAgICAgU2ltcGxlQXR0cmlidXRlIGEgPSAoU2ltcGxlQXR0cmlidXRlKSBpdC5uZXh0KCk7CiAgICAgICAgICAgICAgICAvL1NpbXBsZUF0dHJpYnV0ZSBhID0gZ2V0U2tpcHBpbmcoaXQpOwogICAgICAgICAgICAgICAgLy9pZiAoYSA9PSBudWxsKSBjb250aW51ZTsKICAgICAgICAgICAgICAgIC8vU2ltcGxlQXR0cmlidXRlIGEgPSAoU2ltcGxlQXR0cmlidXRlKWl0Lm5leHQoKTsKICAgICAgICAgICAgICAgIC8vaWYgKHBhdGggJiYgSUdOT1JFQUJMRS5jb250YWlucyhhLm5hbWUpKSBjb250aW51ZTsKICAgICAgICAgICAgICAgIGlmIChpc1pvbmUgJiYgYS5uYW1lLmVxdWFscygidHlwZSIpKSB7CiAgICAgICAgICAgICAgICAgICAgU3RyaW5nIHJlcGxhY2VtZW50ID0gVGltZVpvbmVBbGlhc2VzLmdldChhLnZhbHVlKTsKICAgICAgICAgICAgICAgICAgICBpZiAocmVwbGFjZW1lbnQgIT0gbnVsbCkgYSA9IG5ldyBTaW1wbGVBdHRyaWJ1dGUoInR5cGUiLCByZXBsYWNlbWVudCk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBidWZmZXIuYXBwZW5kKGEudG9TdHJpbmcocGF0aCkpOwogICAgICAgICAgICB9CiAgICAgICAgICAgIHJldHVybiBidWZmZXIudG9TdHJpbmcoKTsKICAgICAgICB9CiAgICAgICAgcHVibGljIGludCBjb21wYXJlVG8oT2JqZWN0IG8pIHsKICAgICAgICAgICAgLy8gSUdOT1JFIGRyYWZ0LCBzb3VyY2UsIHJlZmVyZW5jZQogICAgICAgICAgICBTaW1wbGVBdHRyaWJ1dGVzIHRoYXQgPSAoU2ltcGxlQXR0cmlidXRlcykgbzsKICAgICAgICAgICAgLy8gcXVpY2sgY2hlY2sgZm9yIGNvbW1vbiBjYXNlCiAgICAgICAgICAgIGlmIChjb250ZW50cy5zaXplKCkgPT0gMCAmJiB0aGF0LmNvbnRlbnRzLnNpemUoKSA9PSAwKSByZXR1cm4gMDsKICAgICAgICAgICAgLy8gY29tcGFyZSBvbmUgYXQgYSB0aW1lLiBTdG9wIGlmIG9uZSBlbGVtZW50IGlzIGxlc3MgdGhhbiBhbm90aGVyLgogICAgICAgICAgICBJdGVyYXRvciBpdCA9IGNvbnRlbnRzLml0ZXJhdG9yKCk7CiAgICAgICAgICAgIEl0ZXJhdG9yIGl0MiA9IHRoYXQuY29udGVudHMuaXRlcmF0b3IoKTsKICAgICAgICAgICAgaW50IHJlc3VsdDsKICAgICAgICAgICAgd2hpbGUgKHRydWUpIHsKICAgICAgICAgICAgCVNpbXBsZUF0dHJpYnV0ZSBhID0gZ2V0U2tpcHBpbmcoaXQpOwogICAgICAgICAgICAgICAgU2ltcGxlQXR0cmlidXRlIGEyID0gZ2V0U2tpcHBpbmcoaXQyKTsKICAgICAgICAgICAgICAgIGlmIChhID09IG51bGwpIHsKICAgICAgICAgICAgICAgIAlpZiAoYTIgPT0gbnVsbCkgcmV0dXJuIDA7CiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIC0xOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgaWYgKGEyID09IG51bGwpIHsKICAgICAgICAgICAgICAgIAlyZXR1cm4gMTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGlmICgocmVzdWx0ID0gYS5jb21wYXJlVG8oYTIpKSAhPSAwKSByZXR1cm4gcmVzdWx0OwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIHByaXZhdGUgU2ltcGxlQXR0cmlidXRlIGdldFNraXBwaW5nKEl0ZXJhdG9yIGl0KSB7CiAgICAgICAgICAgIHdoaWxlIChpdC5oYXNOZXh0KCkpIHsKICAgICAgICAgICAgCVNpbXBsZUF0dHJpYnV0ZSBhID0gKFNpbXBsZUF0dHJpYnV0ZSlpdC5uZXh0KCk7CiAgICAgICAgICAgICAgICBpZiAoIUlHTk9SRUFCTEUuY29udGFpbnMoYS5uYW1lKSkgcmV0dXJuIGE7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgcmV0dXJuIG51bGw7CiAgICAgICAgfQoKICAgICAgICAvKioKICAgICAgICAgKiBAcGFyYW0gYXR0cmlidXRlCiAgICAgICAgICogQHBhcmFtIHZhbHVlCiAgICAgICAgICovCiAgICAgICAgcHVibGljIFNpbXBsZUF0dHJpYnV0ZXMgc2V0KFN0cmluZyBlbGVtZW50LCBTdHJpbmcgYXR0cmlidXRlLCBTdHJpbmcgdmFsdWUpIHsKICAgICAgICAgICAgZm9yIChJdGVyYXRvciBpdCA9IGNvbnRlbnRzLml0ZXJhdG9yKCk7IGl0Lmhhc05leHQoKTspIHsKICAgICAgICAgICAgICAgIFNpbXBsZUF0dHJpYnV0ZSBzYSA9IChTaW1wbGVBdHRyaWJ1dGUpIGl0Lm5leHQoKTsKICAgICAgICAgICAgICAgIGlmIChzYS5uYW1lLmVxdWFscyhhdHRyaWJ1dGUpKSB7CiAgICAgICAgICAgICAgICAgICAgY29udGVudHMucmVtb3ZlKHNhKTsKICAgICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgICAgICBjb250ZW50cy5hZGQobmV3IFNpbXBsZUF0dHJpYnV0ZShhdHRyaWJ1dGUsIHZhbHVlKSk7CiAgICAgICAgICAgIHRyaXBsZURhdGEucmVjb3JkRGF0YShlbGVtZW50LCBhdHRyaWJ1dGUsIHZhbHVlKTsKICAgICAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgICAgfQoKCQkvKioKCQkgKiBAcGFyYW0gYXR0cmlidXRlTmFtZQoJCSAqIEByZXR1cm4KCQkgKi8KCQlwdWJsaWMgU3RyaW5nIGdldFZhbHVlKFN0cmluZyBhdHRyaWJ1dGVOYW1lKSB7CiAgICAgICAgICAgIGZvciAoSXRlcmF0b3IgaXQgPSBjb250ZW50cy5pdGVyYXRvcigpOyBpdC5oYXNOZXh0KCk7KSB7CiAgICAgICAgICAgICAgICBTaW1wbGVBdHRyaWJ1dGUgc2EgPSAoU2ltcGxlQXR0cmlidXRlKSBpdC5uZXh0KCk7CiAgICAgICAgICAgICAgICBpZiAoc2EubmFtZS5lcXVhbHMoYXR0cmlidXRlTmFtZSkpIHsKICAgICAgICAgICAgICAgICAgICByZXR1cm4gc2EudmFsdWU7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICAgICAgcmV0dXJuIG51bGw7CgkJfQoKCQkvKioKCQkgKiBAcGFyYW0gYXR0cmlidXRlcwoJCSAqLwoJCXB1YmxpYyB2b2lkIGFkZChTaW1wbGVBdHRyaWJ1dGVzIGF0dHJpYnV0ZXMpIHsKCQkJY29udGVudHMuYWRkQWxsKGF0dHJpYnV0ZXMuY29udGVudHMpOwoJCX0KCgkJLyoqCgkJICogQHBhcmFtIGlnbm9yZWxpc3QKCQkgKi8KCQlwdWJsaWMgdm9pZCByZW1vdmVBdHRyaWJ1dGVzKFNldCBpZ25vcmVsaXN0KSB7CiAgICAgICAgICAgIGZvciAoSXRlcmF0b3IgaXQgPSBjb250ZW50cy5pdGVyYXRvcigpOyBpdC5oYXNOZXh0KCk7KSB7CiAgICAgICAgICAgICAgICBTaW1wbGVBdHRyaWJ1dGUgc2EgPSAoU2ltcGxlQXR0cmlidXRlKSBpdC5uZXh0KCk7CiAgICAgICAgICAgICAgICBpZiAoaWdub3JlbGlzdC5jb250YWlucyhzYS5uYW1lKSkgewogICAgICAgICAgICAgICAgICAgIGl0LnJlbW92ZSgpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CQoJCX0KICAgIH0KICAgIAogICAgc3RhdGljIGNsYXNzIFRyaXBsZURhdGEgewogICAgICAgIE1hcCBlbGVtZW50VG9BdHRyaWJ1dGVUb1ZhbHVlcyA9IG5ldyBUcmVlTWFwKGdldERlZmF1bHRDb2xsYXRpb24oKSk7CiAgICAgICAgTWFwIGJpZ2d1eXMgPSBudWxsOwogICAgICAgIHN0YXRpYyBmaW5hbCBTdHJpbmcgQU5ZU1RSSU5HID0gIlthbnldIjsKICAgICAgICAKICAgICAgICBwcml2YXRlIHZvaWQgcmVjb3JkRGF0YShTdHJpbmcgZWxlbWVudCwgU3RyaW5nIGF0dHJpYnV0ZSwgU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgICAgIGlmICghZWxlbWVudC5lcXVhbHMoQU5ZU1RSSU5HKSAmJiBJR05PUkVMSVNULmNvbnRhaW5zKGF0dHJpYnV0ZSkpIHJldHVybjsKICAgICAgICAgICAgaWYgKGJpZ2d1eXMgPT0gbnVsbCkgaW5pdCgpOwogICAgICAgICAgICAvLyByZWNvcmQgZm9yIHBvc3Rlcml0eQogICAgICAgICAgICBNYXAgZWxlbWVudFRvQXR0cmlidXRlID0gKE1hcCkgZWxlbWVudFRvQXR0cmlidXRlVG9WYWx1ZXMuZ2V0KGVsZW1lbnQpOwogICAgICAgICAgICBpZiAoZWxlbWVudFRvQXR0cmlidXRlID09IG51bGwpIHsKICAgICAgICAgICAgICAgIGVsZW1lbnRUb0F0dHJpYnV0ZSA9IG5ldyBUcmVlTWFwKGdldERlZmF1bHRDb2xsYXRpb24oKSk7CiAgICAgICAgICAgICAgICBlbGVtZW50VG9BdHRyaWJ1dGVUb1ZhbHVlcy5wdXQoZWxlbWVudCwgZWxlbWVudFRvQXR0cmlidXRlKTsKICAgICAgICAgICAgfQogICAgICAgICAgICBTZXQgdmFsdWVTZXQgPSAoU2V0KSBlbGVtZW50VG9BdHRyaWJ1dGUuZ2V0KGF0dHJpYnV0ZSk7CiAgICAgICAgICAgIGlmICh2YWx1ZVNldCA9PSBudWxsKSB7CiAgICAgICAgICAgICAgICB2YWx1ZVNldCA9IG5ldyBUcmVlU2V0KGdldERlZmF1bHRDb2xsYXRpb24oKSk7CiAgICAgICAgICAgICAgICBlbGVtZW50VG9BdHRyaWJ1dGUucHV0KGF0dHJpYnV0ZSwgdmFsdWVTZXQpOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGlmICh2YWx1ZSAhPSBudWxsKSB2YWx1ZVNldC5hZGQodmFsdWUpOwogICAgICAgIH0KICAgICAgICAKICAgICAgICAvKioKICAgICAgICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uCiAgICAgICAgICogCiAgICAgICAgICovCiAgICAgICAgcHJpdmF0ZSB2b2lkIHdyaXRlRGF0YSgpIHRocm93cyBJT0V4Y2VwdGlvbiB7CiAgICAgICAgICAgIFN0cmluZyBmaWxlTmFtZSA9ICJhdHRyaWJ1dGVMaXN0Lmh0bWwiOwogICAgICAgICAgICBQcmludFdyaXRlciBvdXQgPSBCYWdGb3JtYXR0ZXIub3BlblVURjhXcml0ZXIob3B0aW9uc1tERVNURElSXS52YWx1ZSwgImJ5X3R5cGUiICsgRmlsZS5zZXBhcmF0b3IgKyBmaWxlTmFtZSk7CiAgICAgICAgICAgIG91dC5wcmludGxuKCI8aHRtbD48aGVhZD4iKTsKICAgICAgICAgICAgb3V0LnByaW50bG4oIjxtZXRhIGh0dHAtZXF1aXY9J0NvbnRlbnQtVHlwZScgY29udGVudD0ndGV4dC9odG1sOyBjaGFyc2V0PXV0Zi04Jz4iKTsKICAgICAgICAgICAgb3V0LnByaW50bG4oIjx0aXRsZT5FbGVtZW50L0F0dHJpYnV0ZS9WYWx1ZTwvdGl0bGU+Iik7CiAgICAgICAgICAgIG91dC5wcmludGxuKCI8bGluayByZWw9J3N0eWxlc2hlZXQnIHR5cGU9J3RleHQvY3NzJyBocmVmPSdodHRwOi8vb3NzLnNvZnR3YXJlLmlibS5jb20vY3ZzL2ljdS9+Y2hlY2tvdXR+L2ljdWh0bWwvY29tbW9uLmNzcyc+Iik7CiAgICAgICAgICAgIG91dC5wcmludGxuKCI8bGluayByZWw9J3N0eWxlc2hlZXQnIHR5cGU9J3RleHQvY3NzJyBocmVmPSdieV90eXBlLmNzcyc+Iik7CiAgICAgICAgICAgIG91dC5wcmludGxuKCI8L2hlYWQ+PGJvZHk+Iik7CiAgICAgICAgICAgIG91dC5wcmludGxuKCI8dGFibGU+Iik7CiAgICAgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgZml4TGlzdC5sZW5ndGg7ICsraSkgewogICAgICAgICAgICAgICAgT2JqZWN0W10gcm93ID0gZml4TGlzdFtpXTsKICAgICAgICAgICAgICAgIFN0cmluZyBlbGVtZW50SXRlbSA9IChTdHJpbmcpcm93WzBdOwogICAgICAgICAgICAgICAgaWYgKGVsZW1lbnRJdGVtLmVxdWFscygiKiIpKSBjb250aW51ZTsKICAgICAgICAgICAgICAgIFN0cmluZyBhdHRyaWJ1dGVJdGVtID0gKFN0cmluZylyb3dbMV07CiAgICAgICAgICAgICAgICBpZiAoYXR0cmlidXRlSXRlbS5lcXVhbHMoIioiKSkgY29udGludWU7CiAgICAgICAgICAgICAgICByZWNvcmREYXRhKGVsZW1lbnRJdGVtLCBhdHRyaWJ1dGVJdGVtLCBudWxsKTsKICAgICAgICAgICAgfQogICAgICAgICAgICBmb3IgKEl0ZXJhdG9yIGl0ID0gZWxlbWVudFRvQXR0cmlidXRlVG9WYWx1ZXMua2V5U2V0KCkuaXRlcmF0b3IoKTsgaXQuaGFzTmV4dCgpOykgewogICAgICAgICAgICAgICAgU3RyaW5nIGVsZW1lbnQgPSAoU3RyaW5nKSBpdC5uZXh0KCk7CiAgICAgICAgICAgICAgICBib29sZWFuIG5ld0VsZW1lbnQgPSB0cnVlOwogICAgICAgICAgICAgICAgTWFwIGVsZW1lbnRUb0F0dHJpYnV0ZSA9IChNYXApIGVsZW1lbnRUb0F0dHJpYnV0ZVRvVmFsdWVzLmdldChlbGVtZW50KTsKICAgICAgICAgICAgICAgIFNldCBhdHRyaWJ1dGVLZXlzID0gZWxlbWVudFRvQXR0cmlidXRlLmtleVNldCgpOwogICAgICAgICAgICAgICAgZm9yIChJdGVyYXRvciBpdDIgPSBhdHRyaWJ1dGVLZXlzLml0ZXJhdG9yKCk7IGl0Mi5oYXNOZXh0KCk7KSB7CiAgICAgICAgICAgICAgICAgICAgU3RyaW5nIGF0dHJpYnV0ZSA9IChTdHJpbmcpIGl0Mi5uZXh0KCk7CiAgICAgICAgICAgICAgICAgICAgYm9vbGVhbiBuZXdBdHRyaWJ1dGUgPSB0cnVlOwogICAgICAgICAgICAgICAgICAgIENvbGxlY3Rpb24gdmFsdWVTZXQgPSBnZXRWYWx1ZXMoZWxlbWVudCwgZWxlbWVudFRvQXR0cmlidXRlLCBhdHRyaWJ1dGUpOwogICAgICAgICAgICAgICAgICAgIG91dC5wcmludGxuKCI8dHI+Iik7CiAgICAgICAgICAgICAgICAgICAgaWYgKG5ld0VsZW1lbnQpIHsKICAgICAgICAgICAgICAgICAgICAgICAgb3V0LnByaW50KCI8dGQgcm93U3Bhbj0nIiAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICArIGF0dHJpYnV0ZUtleXMuc2l6ZSgpCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKyAiJz4iICsgZWxlbWVudCArICI8L3RkPiIpOwogICAgICAgICAgICAgICAgICAgICAgICBvdXQucHJpbnRsbigiPCEtLSAiICsgdmFsdWVTZXQuc2l6ZSgpICsgIiwgIiAgKyBhdHRyaWJ1dGVLZXlzLnNpemUoKSArICItLT4iKTsKICAgICAgICAgICAgICAgICAgICAgICAgbmV3RWxlbWVudCA9IGZhbHNlOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICBpZiAobmV3QXR0cmlidXRlKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIG91dC5wcmludCgiPHRkPiIgKyBhdHRyaWJ1dGUgKyAiPC90ZD4iKTsKICAgICAgICAgICAgICAgICAgICAgICAgb3V0LnByaW50bG4oIjwhLS0gIiArIHZhbHVlU2V0LnNpemUoKSArICItLT4iKTsKICAgICAgICAgICAgICAgICAgICAgICAgbmV3QXR0cmlidXRlID0gZmFsc2U7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIG91dC5wcmludCgiPHRkPiIpOwogICAgICAgICAgICAgICAgICAgIGJvb2xlYW4gbmV3U2V0ID0gdHJ1ZTsKICAgICAgICAgICAgICAgICAgICBmb3IgKEl0ZXJhdG9yIGl0MyA9IHZhbHVlU2V0Lml0ZXJhdG9yKCk7IGl0My5oYXNOZXh0KCk7KSB7CiAgICAgICAgICAgICAgICAgICAgICAgIFN0cmluZyB2YWx1ZSA9IChTdHJpbmcpIGl0My5uZXh0KCk7CiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChuZXdTZXQpIG5ld1NldCA9IGZhbHNlOwogICAgICAgICAgICAgICAgICAgICAgICBlbHNlIG91dC5wcmludCgiLCAiKTsKICAgICAgICAgICAgICAgICAgICAgICAgb3V0LnByaW50KEJhZ0Zvcm1hdHRlci50b0hUTUwudHJhbnNsaXRlcmF0ZSgiXCIiICsgdmFsdWUgKyAiXCIiKSk7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIG91dC5wcmludGxuKCI8L3RkPjwvdHI+Iik7CiAgICAgICAgICAgICAgICAgICAgLyoKICAgICAgICAgICAgICAgICAgICBmb3IgKEl0ZXJhdG9yIGl0MyA9IHZhbHVlU2V0Lml0ZXJhdG9yKCk7IGl0My5oYXNOZXh0KCk7KSB7CiAgICAgICAgICAgICAgICAgICAgICAgIFN0cmluZyB2YWx1ZSA9IChTdHJpbmcpIGl0My5uZXh0KCk7CiAgICAgICAgICAgICAgICAgICAgICAgIG91dC5wcmludGxuKCI8dHI+Iik7CiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChuZXdFbGVtZW50KSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBvdXQucHJpbnQoIjx0ZCByb3dTcGFuPSciIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICArIGdldFZhbHVlQ291bnQoZWxlbWVudFRvQXR0cmlidXRlKQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICArICInPiIgKyBlbGVtZW50ICsgIjwvdGQ+Iik7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBvdXQucHJpbnRsbigiPCEtLSAiICsgdmFsdWVTZXQuc2l6ZSgpICsgIiwgIiAgKyBhdHRyaWJ1dGVLZXlzLnNpemUoKSArICItLT4iKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5ld0VsZW1lbnQgPSBmYWxzZTsKICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICAgICBpZiAobmV3QXR0cmlidXRlKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIAlvdXQucHJpbnQoIjx0ZCByb3dTcGFuPSciICsgdmFsdWVTZXQuc2l6ZSgpICsgIic+IiArIGF0dHJpYnV0ZSArICI8L3RkPiIpOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgb3V0LnByaW50bG4oIjwhLS0gIiArIHZhbHVlU2V0LnNpemUoKSArICItLT4iKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5ld0F0dHJpYnV0ZSA9IGZhbHNlOwogICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgICAgIG91dC5wcmludGxuKCI8dGQ+IiArIEJhZ0Zvcm1hdHRlci50b0hUTUwudHJhbnNsaXRlcmF0ZSgiXCIiICsgdmFsdWUgKyAiXCIiKSArICI8L3RkPjwvdHI+Iik7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICovCiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICAgICAgb3V0LnByaW50bG4oIjwvdGFibGU+Iik7CiAgICAgICAgICAgIHdyaXRlRm9vdGVyQW5kQ2xvc2Uob3V0KTsKICAgICAgICB9CiAgICAgICAgCiAgICAgICAgT2JqZWN0W11bXSBmaXhMaXN0ID0gewogICAgICAgICAgICAgICAgeyJhbGlhcyIsICJwYXRoIiwgIjx2YWxpZCBYUGF0aCB3aXRoaW4gbG9jYWxlIHRyZWU+In0sCiAgICAgICAgICAgICAgICB7ImFsaWFzIiwgInNvdXJjZSIsICI8dmFsaWQgbG9jYWxlIElEPiJ9LAogICAgICAgICAgICAgICAgeyJkYXkiLCAidHlwZSIsIG5ldyBTdHJpbmdbXSB7InN1biIsICJtb24iLCAidHVlIiwgIndlZCIsICJ0aHUiLCAiZnJpIiwgInNhdCJ9fSwKICAgICAgICAgICAgICAgIHsiZXJhIiwgInR5cGUiLCAiPG5vbi1uZWdhdGl2ZSBudW1iZXI+In0sCiAgICAgICAgICAgICAgICB7IioiLCAiZGF5IiwgbmV3IFN0cmluZ1tdIHsic3VuIiwgIm1vbiIsICJ0dWUiLCAid2VkIiwgInRodSIsICJmcmkiLCAic2F0In19LAogICAgICAgICAgICAgICAgeyJnZW5lcmF0aW9uIiwgImRhdGUiLCAiPHl5eXktTU0tZGQgZm9ybWF0PiJ9LAogICAgICAgICAgICAgICAgeyJ2ZXJzaW9uIiwgIm51bWJlciIsICI8bi5tIGZvcm1hdD4ifSwKICAgICAgICAgICAgICAgIHsiKiIsICJ0aW1lIiwgIjxISDptbSAoMDA6MDAuLjI0OjAwKT4ifSwKICAgICAgICAgICAgICAgIHsib3JpZW50YXRpb24iLCAiKiIsIG5ldyBTdHJpbmdbXSB7ImxlZnQtdG8tcmlnaHQiLCAicmlnaHQtdG8tbGVmdCIsICJ0b3AtdG8tYm90dG9tIiwgImJvdHRvbS10by10b3AifX0sCiAgICAgICAgICAgICAgICB7Im1pbkRheXMiLCAiY291bnQiLCBuZXcgU3RyaW5nW10geyIxIiwgIjIiLCAiMyIsICI0IiwgIjUiLCAiNiIsICI3In19LAogICAgICAgICAgICAgICAgeyJsYW5ndWFnZSIsICJ0eXBlIiwgIiUlJWxhbmd1YWdlIn0sCiAgICAgICAgICAgICAgICB7InNjcmlwdCIsICJ0eXBlIiwgIiUlJXNjcmlwdCJ9LAogICAgICAgICAgICAgICAgeyJ0ZXJyaXRvcnkiLCAidHlwZSIsICIlJSVyZWdpb24ifSwKICAgICAgICAgICAgICAgIHsidmFyaWFudCIsICJ0eXBlIiwgIiUlJXZhcmlhbnQifSwKICAgICAgICAgICAgICAgIHsiem9uZSIsICJ0eXBlIiwgIiUlJXR6aWQifSwKICAgICAgICAgICAgICAgIHsiY3VycmVuY3kiLCAidHlwZSIsICIlJSVjdXJyZW5jeSJ9LAogICAgICAgICAgICAgICAgeyJjYWxlbmRhciIsICJ0eXBlIiwgbmV3IFN0cmluZ1tdIHsKICAgICAgICAgICAgICAgICAgICAgICAgImJ1ZGRoaXN0IiwgImNoaW5lc2UiLCAiZ3JlZ29yaWFuIiwgImhlYnJldyIsICJpc2xhbWljIiwgImlzbGFtaWMtY2l2aWwiLCAiamFwYW5lc2UiCiAgICAgICAgICAgICAgICAgICAgICAgICwiYXJhYmljW2FsaWFzXSIsICJjaXZpbC1hcmFiaWNbYWxpYXNdIiwgInRoYWktYnVkZGhpc3RbYWxpYXNdIgogICAgICAgICAgICAgICAgfX0sCiAgICAgICAgICAgICAgICB7Im1lYXN1cmVtZW50U3lzdGVtIiwgInR5cGUiLCBuZXcgU3RyaW5nW10geyJtZXRyaWMiLCAiVVMiLCAiVUsifX0sIAogICAgICAgICAgICAgICAgeyJ0eXBlIiwgInR5cGUiLCAiPGFueSB0eXBlIHZhbHVlLS13aXRoIGFwcHJvcHJpYXRlIGtleT4ifSwKICAgICAgICAgICAgICAgIHsidHlwZSIsICJrZXkiLCAiPGFueSBlbGVtZW50IG5hbWUgaGF2aW5nICd0eXBlJyBhdHRyaWJ1dGU+In0sCiAgICAgICAgICAgICAgICB7ImtleSIsICJ0eXBlIiwgIjxhbnkgZWxlbWVudCBuYW1lIGhhdmluZyAndHlwZScgYXR0cmlidXRlPiJ9LAogICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICB7QU5ZU1RSSU5HLCAiZHJhZnQiLCBuZXcgU3RyaW5nW10geyJ0cnVlIiwgImZhbHNlKiJ9fSwKICAgICAgICAgICAgICAgIHtBTllTVFJJTkcsICJhbHQiLCBuZXcgU3RyaW5nW10geyJwcm9wb3NlZCIsICJ2YXJpYW50In19LAogICAgICAgICAgICAgICAge0FOWVNUUklORywgInJlZmVyZW5jZXMiLCAiPGxpc3Qgb2YgcmVmZXJlbmNlcz4ifSwKICAgICAgICAgICAgICAgIHtBTllTVFJJTkcsICJzdGFuZGFyZCIsICI8bGlzdCBvZiBzdGFuZGFyZHM+In0sCiAgICAgICAgICAgICAgICB7QU5ZU1RSSU5HLCAidmFsaWRTdWJMb2NhbGVzIiwgIjxsaXN0IG9mIHN1Yi1sb2NhbGVzPiJ9LAogICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICB7ImNvbGxhdGlvbiIsICJ0eXBlIiwgbmV3IFN0cmluZ1tdIHsicGhvbmVib29rIiwgInRyYWRpdGlvbmFsIiwgImRpcmVjdCIsICJwaW55aW4iLCAic3Ryb2tlIiwgInBvc2l4IiwgImJpZzVoYW4iLCAiZ2IyMzEyaGFuIn19LAogICAgICAgICAgICAgICAgeyJzZXR0aW5ncyIsICJzdHJlbmd0aCIsIG5ldyBTdHJpbmdbXSB7InByaW1hcnkiLCAic2Vjb25kYXJ5IiwgInRlcnRpYXJ5IiwgInF1YXRlcm5hcnkiLCAiaWRlbnRpY2FsIn19LAogICAgICAgICAgICAgICAgeyJzZXR0aW5ncyIsICJhbHRlcm5hdGUiLCBuZXcgU3RyaW5nW10geyJub24taWdub3JhYmxlIiwgInNoaWZ0ZWQifX0sCiAgICAgICAgICAgICAgICB7InNldHRpbmdzIiwgImJhY2t3YXJkcyIsIG5ldyBTdHJpbmdbXSB7Im9uIiwgIm9mZiJ9fSwKICAgICAgICAgICAgICAgIHsic2V0dGluZ3MiLCAibm9ybWFsaXphdGlvbiIsIG5ldyBTdHJpbmdbXSB7Im9uIiwgIm9mZiJ9fSwKICAgICAgICAgICAgICAgIHsic2V0dGluZ3MiLCAiY2FzZUxldmVsIiwgbmV3IFN0cmluZ1tdIHsib24iLCAib2ZmIn19LAogICAgICAgICAgICAgICAgeyJzZXR0aW5ncyIsICJjYXNlRmlyc3QiLCBuZXcgU3RyaW5nW10geyJ1cHBlciIsICJsb3dlciIsICJvZmYifX0sCiAgICAgICAgICAgICAgICB7InNldHRpbmdzIiwgImhpcmFnYW5hUXVhcnRlcm5hcnkiLCBuZXcgU3RyaW5nW10geyJvbiIsICJvZmYifX0sCiAgICAgICAgICAgICAgICB7InNldHRpbmdzIiwgIm51bWVyaWMiLCBuZXcgU3RyaW5nW10geyJvbiIsICJvZmYifX0sCiAgICAgICAgICAgICAgICB7InJlc2V0IiwgImJlZm9yZSIsIG5ldyBTdHJpbmdbXSB7InByaW1hcnkiLCAic2Vjb25kYXJ5IiwgInRlcnRpYXJ5In19LAogICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICB7ImRlZmF1bHQiLCAidHlwZSIsICI8YW55IHR5cGUgdmFsdWUgbGVnYWwgZm9yIG9uZSBvZiB0aGUgcGVlciBlbGVtZW50cz4ifSwKICAgICAgICAgICAgICAgIHsibWFwcGluZyIsICJyZWdpc3RyeSIsICI8YW55IGNoYXJzZXQgcmVnaXN0cnksIGlhbmEgcHJlZmVycmVkPiJ9LAogICAgICAgICAgICAgICAgeyJtYXBwaW5nIiwgInR5cGUiLCAiPGFueSB2YWxpZCBjaGFyc2V0IGZyb20gdGhlIGdpdmVuIHJlZ2lzdHJ5PiJ9LAogICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICB7ImFiYnJldmlhdGlvbkZhbGxiYWNrIiwgInR5cGUiLCBuZXcgU3RyaW5nW10geyJzdGFuZGFyZCIsICJHTVQifX0sCiAgICAgICAgICAgICAgICB7InByZWZlcmVuY2VPcmRlcmluZyIsICJ0eXBlIiwgIjxzcGFjZS1kZWxpbWl0ZWQgbGlzdCBvZiB0aW1lem9uZSBJRHM+In0sCiAgICAgICAgICAgICAgICB7ImV4ZW1wbGFyQ2hhcmFjdGVycyIsICJ0eXBlIiwgbmV3IFN0cmluZ1tdIHsic3RhbmRhcmQiLCAiYXV4aWxpYXJ5In19LAoKICAgICAgICAgICAgICAgIHsiZGVjaW1hbEZvcm1hdExlbmd0aCIsICJ0eXBlIiwgbmV3IFN0cmluZ1tdIHsiZnVsbCIsICJsb25nIiwgIm1lZGl1bSIsICJzaG9ydCJ9fSwKICAgICAgICAgICAgICAgIHsic2NpZW50aWZpY0Zvcm1hdExlbmd0aCIsICJ0eXBlIiwgbmV3IFN0cmluZ1tdIHsiZnVsbCIsICJsb25nIiwgIm1lZGl1bSIsICJzaG9ydCJ9fSwKICAgICAgICAgICAgICAgIHsiY3VycmVuY3lGb3JtYXRMZW5ndGgiLCAidHlwZSIsIG5ldyBTdHJpbmdbXSB7ImZ1bGwiLCAibG9uZyIsICJtZWRpdW0iLCAic2hvcnQifX0sCiAgICAgICAgICAgICAgICB7InBlcmNlbnRGb3JtYXRMZW5ndGgiLCAidHlwZSIsIG5ldyBTdHJpbmdbXSB7ImZ1bGwiLCAibG9uZyIsICJtZWRpdW0iLCAic2hvcnQifX0sCgogICAgICAgICAgICAgICAgeyJmaWVsZCIsICJ0eXBlIiwgbmV3IFN0cmluZ1tdIHsiZXJhIiwgInllYXIiLCAibW9udGgiLCAid2VlayIsICJkYXkiLCAid2Vla2RheSIsICJkYXlwZXJpb2QiLCAiaG91ciIsICJtaW51dGUiLCAic2Vjb25kIiwgInpvbmUifX0sCiAgICAgICAgICAgICAgICB7InJlbGF0aXZlIiwgInR5cGUiLCAiPGludGVnZXI+In0sCgogICAgICAgICAgICAgICAgeyJwYXR0ZXJuIiwgInR5cGUiLCAiPHZhbGlkIHBhdHRlcm4gZm9yIGZvcm1hdD4ifSwKCiAgICAgICAgICAgICAgICB7ImRhdGVGb3JtYXQiLCAidHlwZSIsIG5ldyBTdHJpbmdbXSB7InN0YW5kYXJkIiwgIjxzcGVjaWFsLWtleT4ifX0sCiAgICAgICAgICAgICAgICB7InRpbWVGb3JtYXQiLCAidHlwZSIsIG5ldyBTdHJpbmdbXSB7InN0YW5kYXJkIiwgIjxzcGVjaWFsLWtleT4ifX0sCiAgICAgICAgICAgICAgICB7ImRhdGVUaW1lRm9ybWF0IiwgInR5cGUiLCBuZXcgU3RyaW5nW10geyJzdGFuZGFyZCIsICI8c3BlY2lhbC1rZXk+In19LAogICAgICAgICAgICAgICAgeyJkZWNpbWFsRm9ybWF0IiwgInR5cGUiLCBuZXcgU3RyaW5nW10geyJzdGFuZGFyZCIsICI8c3BlY2lhbC1rZXk+In19LAogICAgICAgICAgICAgICAgeyJzY2llbnRpZmljRm9ybWF0IiwgInR5cGUiLCBuZXcgU3RyaW5nW10geyJzdGFuZGFyZCIsICI8c3BlY2lhbC1rZXk+In19LAogICAgICAgICAgICAgICAgeyJwZXJjZW50Rm9ybWF0IiwgInR5cGUiLCBuZXcgU3RyaW5nW10geyJzdGFuZGFyZCIsICI8c3BlY2lhbC1rZXk+In19LAogICAgICAgICAgICAgICAgeyJjdXJyZW5jeUZvcm1hdCIsICJ0eXBlIiwgbmV3IFN0cmluZ1tdIHsic3RhbmRhcmQiLCAiPHNwZWNpYWwta2V5PiJ9fSwKICAgICAgICB9OwogICAgICAgIAogICAgICAgIFN0cmluZ1tdIHBpZWNlcyA9IG5ldyBTdHJpbmdbNTBdOwogICAgICAgIAogICAgICAgIHByaXZhdGUgdm9pZCBpbml0KCkgewogICAgICAgICAgICB0cnkgewogICAgICAgICAgICAgICAgYmlnZ3V5cyA9IG5ldyBIYXNoTWFwKCk7CiAgICAgICAgICAgICAgICBCdWZmZXJlZFJlYWRlciBiciA9IEJhZ0Zvcm1hdHRlci5vcGVuVVRGOFJlYWRlcih0aW1lWm9uZUFsaWFzRGlyLCAiaWRMaXN0LnR4dCIpOwogICAgICAgICAgICAgICAgd2hpbGUgKHRydWUpIHsKICAgICAgICAgICAgICAgICAgICBTdHJpbmcgbGluZSA9IGJyLnJlYWRMaW5lKCk7CiAgICAgICAgICAgICAgICAgICAgaWYgKGxpbmUgPT0gbnVsbCkgYnJlYWs7CiAgICAgICAgICAgICAgICAgICAgbGluZSA9IGxpbmUudHJpbSgpOwogICAgICAgICAgICAgICAgICAgIGlmIChsaW5lLnN0YXJ0c1dpdGgoIiMiKSkgY29udGludWU7CiAgICAgICAgICAgICAgICAgICAgVXRpbGl0eS5zcGxpdChsaW5lLCc7JywgcGllY2VzKTsKICAgICAgICAgICAgICAgICAgICBTdHJpbmcgdGFnID0gcGllY2VzWzBdLnRyaW0oKTsKICAgICAgICAgICAgICAgICAgICBTdHJpbmcgaWQgPSBwaWVjZXNbMV0udHJpbSgpOwogICAgICAgICAgICAgICAgICAgIGFkZFRhZ1ZhbHVlKHRhZywgaWQpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgYnIuY2xvc2UoKTsKICAgICAgICAgICAgICAgIC8vIGhhY2sgc29tZSBleHRyYXMKICAgICAgICAgICAgICAgIGFkZFRhZ1ZhbHVlKCJsYW5ndWFnZSIsICJyb290Iik7CiAgICAgICAgICAgICAgICBhZGRUYWdWYWx1ZSgic2NyaXB0IiwgIlFhYWkiKTsKICAgICAgICAgICAgICAgIGFkZFRhZ1ZhbHVlKCJ2YXJpYW50IiwgIlBPU0lYIik7CiAgICAgICAgICAgICAgICBhZGRUYWdWYWx1ZSgidmFyaWFudCIsICJSRVZJU0VEIik7CiAgICAgICAgICAgICAgICBhZGRUYWdWYWx1ZSgidmFyaWFudCIsICJib2ttYWwiKTsKICAgICAgICAgICAgICAgIGFkZFRhZ1ZhbHVlKCJ2YXJpYW50IiwgIm55bm9yc2siKTsKICAgICAgICAgICAgICAgIGFkZFRhZ1ZhbHVlKCJ2YXJpYW50IiwgImFhbGFuZCIpOwogICAgICAgICAgICB9IGNhdGNoIChJT0V4Y2VwdGlvbiBlKSB7CiAgICAgICAgICAgICAgICB0aHJvdyBuZXcgUnVudGltZUV4Y2VwdGlvbihlKTsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgICAgICAKICAgICAgICAvKioKCQkgKiBAcGFyYW0gdGFnCgkJICogQHBhcmFtIGlkCgkJICovCgkJcHJpdmF0ZSB2b2lkIGFkZFRhZ1ZhbHVlKFN0cmluZyB0YWcsIFN0cmluZyBpZCkgewoJCQlDb2xsZWN0aW9uIGMgPSAoQ29sbGVjdGlvbikgYmlnZ3V5cy5nZXQodGFnKTsKCQkJaWYgKGMgPT0gbnVsbCkgewoJCQkJYyA9IG5ldyBUcmVlU2V0KCk7CgkJCSAgICBiaWdndXlzLnB1dCh0YWcsIGMpOwoJCQl9CgkJCVV0aWxpdHkuc3BsaXQoaWQsICcsJywgcGllY2VzKTsKCQkJZm9yIChpbnQgaSA9IDA7IGkgPCBwaWVjZXMubGVuZ3RoOyArK2kpIHsKCQkJICAgIGlmIChwaWVjZXNbaV0ubGVuZ3RoKCkgPT0gMCkgY29udGludWU7CgkJCQljLmFkZChwaWVjZXNbaV0udHJpbSgpKTsKCQkJfQoJCX0KCgkJLyoqCgkJICogQHBhcmFtIGVsZW1lbnRUb0F0dHJpYnV0ZQoJCSAqIEBwYXJhbSBhdHRyaWJ1dGUKCQkgKiBAcmV0dXJuCgkJICovCgkJcHJpdmF0ZSBDb2xsZWN0aW9uIGdldFZhbHVlcyhTdHJpbmcgZWxlbWVudCwgTWFwIGVsZW1lbnRUb0F0dHJpYnV0ZSwgU3RyaW5nIGF0dHJpYnV0ZSkgewogICAgICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IGZpeExpc3QubGVuZ3RoOyArK2kpIHsKICAgICAgICAgICAgICAgIE9iamVjdFtdIHJvdyA9IGZpeExpc3RbaV07CiAgICAgICAgICAgICAgICBTdHJpbmcgZWxlbWVudEl0ZW0gPSAoU3RyaW5nKXJvd1swXTsKICAgICAgICAgICAgICAgIFN0cmluZyBhdHRyaWJ1dGVJdGVtID0gKFN0cmluZylyb3dbMV07CiAgICAgICAgICAgIAlpZiAoKGF0dHJpYnV0ZS5lcXVhbHMoYXR0cmlidXRlSXRlbSkgfHwgIioiLmVxdWFscyhhdHRyaWJ1dGVJdGVtKSkKICAgICAgICAgICAgICAgICAgICAgICAgJiYgKGVsZW1lbnQuZXF1YWxzKGVsZW1lbnRJdGVtKSB8fCAiKiIuZXF1YWxzKGVsZW1lbnRJdGVtKSkpIHsKICAgICAgICAgICAgCQlpZiAocm93WzJdIGluc3RhbmNlb2YgU3RyaW5nKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIFN0cmluZyB2YWx1ZUl0ZW0gPSAoU3RyaW5nKXJvd1syXTsKICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHZhbHVlSXRlbS5zdGFydHNXaXRoKCIlJSUiKSkgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgLy9TeXN0ZW0ub3V0LnByaW50bG4oIlN1YnN0aXR1dGluZyBWYWx1ZXM6ICIgKyBlbGVtZW50ICsgIiwgIiArIGF0dHJpYnV0ZSk7CiAgICAgICAgICAgICAgICAgICAgICAgIAlDb2xsZWN0aW9uIHJlc3VsdCA9IChDb2xsZWN0aW9uKSBiaWdndXlzLmdldCh2YWx1ZUl0ZW0uc3Vic3RyaW5nKDMpKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIFNldCBzID0gbmV3IFRyZWVTZXQoKENvbGxlY3Rpb24pZWxlbWVudFRvQXR0cmlidXRlLmdldChhdHRyaWJ1dGUpKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHMucmVtb3ZlQWxsKHJlc3VsdCk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAocy5zaXplKCkgIT0gMCkgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgCVN5c3RlbS5vdXQucHJpbnQoIldhcm5pbmc6IE1pc3NpbmcgdmFsdWVzIGZvciAiICsgZWxlbWVudCArICIsICIgKyBhdHRyaWJ1dGUgKyAiOiAiKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmb3IgKEl0ZXJhdG9yIGl0ID0gcy5pdGVyYXRvcigpOyBpdC5oYXNOZXh0KCk7ICkgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAlTeXN0ZW0ub3V0LnByaW50KGl0Lm5leHQoKSArICIgIik7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFN5c3RlbS5vdXQucHJpbnRsbigpOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHJlc3VsdDsKICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAJCQlMaXN0IHJlc3VsdCA9IG5ldyBBcnJheUxpc3QoKTsKICAgICAgICAgICAgICAgICAgICAgICAgcmVzdWx0LmFkZCh2YWx1ZUl0ZW0pOwogICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gcmVzdWx0OwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICByZXR1cm4gQXJyYXlzLmFzTGlzdCgoT2JqZWN0W10pcm93WzJdKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQoJCQlyZXR1cm4gKENvbGxlY3Rpb24pIGVsZW1lbnRUb0F0dHJpYnV0ZS5nZXQoYXR0cmlidXRlKTsKCQl9CgkJaW50IGdldFZhbHVlQ291bnQoTWFwIGVsZW1lbnRUb0F0dHJpYnV0ZSkgewogICAgICAgICAgICBpbnQgcmVzdWx0ID0gMDsKICAgICAgICAgICAgZm9yIChJdGVyYXRvciBpdDIgPSBlbGVtZW50VG9BdHRyaWJ1dGUua2V5U2V0KCkuaXRlcmF0b3IoKTsgaXQyLmhhc05leHQoKTspIHsKICAgICAgICAgICAgICAgIFN0cmluZyBhdHRyaWJ1dGUgPSAoU3RyaW5nKSBpdDIubmV4dCgpOwogICAgICAgICAgICAgICAgU2V0IHZhbHVlU2V0ID0gKFNldCkgZWxlbWVudFRvQXR0cmlidXRlLmdldChhdHRyaWJ1dGUpOwogICAgICAgICAgICAgICAgcmVzdWx0ICs9IHZhbHVlU2V0LnNpemUoKTsKICAgICAgICAgICAgfQogICAgICAgICAgICByZXR1cm4gcmVzdWx0OwogICAgICAgIH0KICAgIH0KICAgIAogICAgc3RhdGljIFRyaXBsZURhdGEgdHJpcGxlRGF0YSA9IG5ldyBUcmlwbGVEYXRhKCk7CiAgICAKICAgIGNsYXNzIEVsZW1lbnQgaW1wbGVtZW50cyBDb21wYXJhYmxlIHsKICAgICAgICBTdHJpbmcgZWxlbWVudE5hbWU7CiAgICAgICAgU2ltcGxlQXR0cmlidXRlcyBhdHRyaWJ1dGVzOwogICAgICAgIFN0cmluZyBjb21tZW50OwoKICAgICAgICBFbGVtZW50KFN0cmluZyBlbGVtZW50TmFtZSwgQXR0cmlidXRlcyBhdHRyaWJ1dGVzLCBTdHJpbmcgY29tbWVudCkgewogICAgICAgICAgICAvL2VsZW1lbnRPcmRlcmluZy5hZGQoZWxlbWVudE5hbWUpOwogICAgICAgICAgICB0aGlzLmVsZW1lbnROYW1lID0gZWxlbWVudE5hbWU7CiAgICAgICAgICAgIHRoaXMuYXR0cmlidXRlcyA9IG5ldyBTaW1wbGVBdHRyaWJ1dGVzKGF0dHJpYnV0ZXMsIGVsZW1lbnROYW1lKTsKICAgICAgICAgICAgdGhpcy5jb21tZW50ID0gY29tbWVudDsKICAgICAgICB9CiAgICAgICAgLyoqCgkJICogQHBhcmFtIHN0cmluZwoJCSAqIEBwYXJhbSBmaXhlZAoJCSAqLwoJCXB1YmxpYyB2b2lkIHNldEF0dHJpYnV0ZShTdHJpbmcgYXR0cmlidXRlLCBTdHJpbmcgdmFsdWUpIHsKCQkJYXR0cmlidXRlcy5zZXQoZWxlbWVudE5hbWUsIGF0dHJpYnV0ZSwgdmFsdWUpOwkJCQoJCX0KCQkvKioKCQkgKiBAcGFyYW0gc3RyaW5nCgkJICogQHJldHVybgoJCSAqLwoJCXB1YmxpYyBTdHJpbmcgZ2V0VmFsdWUoU3RyaW5nIGF0dHJpYnV0ZU5hbWUpIHsKCQkJcmV0dXJuIGF0dHJpYnV0ZXMuZ2V0VmFsdWUoYXR0cmlidXRlTmFtZSk7CgkJfQogICAgICAgIAoJCUVsZW1lbnQoRWxlbWVudCBvdGhlcikgewogICAgICAgICAgICAvL2VsZW1lbnRPcmRlcmluZy5hZGQoZWxlbWVudE5hbWUpOwogICAgICAgICAgICB0aGlzLmVsZW1lbnROYW1lID0gb3RoZXIuZWxlbWVudE5hbWU7CiAgICAgICAgICAgIHRoaXMuYXR0cmlidXRlcyA9IG5ldyBTaW1wbGVBdHRyaWJ1dGVzKG90aGVyLmF0dHJpYnV0ZXMsIGVsZW1lbnROYW1lKTsKICAgICAgICAgICAgdGhpcy5jb21tZW50ID0gb3RoZXIuY29tbWVudDsKICAgICAgICB9CiAgICAgICAgCiAgICAgICAgcHVibGljIFN0cmluZyB0b1N0cmluZygpIHsKICAgICAgICAgICAgLy90aHJvdyBuZXcgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCJEb24ndCB1c2UyIik7CiAgICAgICAgICAgIHJldHVybiB0b1N0cmluZyhQQVRIKTsKICAgICAgICB9CiAgICAgICAgLyoKICAgICAgICBwdWJsaWMgU3RyaW5nIHRvU3RyaW5nKGJvb2xlYW4gcGF0aCkgewogICAgICAgICAgICByZXR1cm4gdG9TdHJpbmcoU1RBUlRfVkFMVUUsIHBhdGgpOwogICAgICAgIH0KICAgICAgICAqLwogICAgICAgIHN0YXRpYyBmaW5hbCBpbnQgUEFUSCA9IC0xLCBOT19WQUxVRSA9IDAsIFNUQVJUX1ZBTFVFID0gMSwgRU5EX1ZBTFVFID0gMjsKICAgICAgICBwdWJsaWMgU3RyaW5nIHRvU3RyaW5nKGludCB0eXBlKSB7CiAgICAgICAgICAgIFN0cmluZyBhID0gYXR0cmlidXRlcy50b1N0cmluZyh0eXBlPT1QQVRILCBlbGVtZW50TmFtZS5lcXVhbHMoInpvbmUiKSk7CiAgICAgICAgICAgIFN0cmluZyByZXN1bHQ7CiAgICAgICAgICAgIGlmICh0eXBlPT1QQVRIKSB7CiAgICAgICAgICAgICAgICAvL2lmICh0eXBlID09IE5PX1ZBTFVFKSByZXR1cm4gZWxlbWVudE5hbWUgKyBhICsgIi1OT1ZBTFVFIjsKICAgICAgICAgICAgICAgIC8vaWYgKHR5cGUgPT0gRU5EX1ZBTFVFKSByZXR1cm4gIkVORC0iICsgZWxlbWVudE5hbWUgKyAiPiI7CiAgICAgICAgICAgICAgICByZXN1bHQgPSBlbGVtZW50TmFtZSArIGE7CiAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICBpZiAodHlwZSA9PSBOT19WQUxVRSkgcmVzdWx0ID0gIjwiICsgZWxlbWVudE5hbWUgKyBhICsgIi8+IjsKICAgICAgICAgICAgICAgIGVsc2UgaWYgKHR5cGUgPT0gRU5EX1ZBTFVFKSByZXN1bHQgPSAiPC8iICsgZWxlbWVudE5hbWUgKyAiPiI7CiAgICAgICAgICAgICAgICBlbHNlIHJlc3VsdCA9ICI8IiArIGVsZW1lbnROYW1lICsgYSArICI+IjsKICAgICAgICAgICAgfQogICAgICAgICAgICByZXR1cm4gcmVzdWx0OwogICAgICAgIH0KICAgICAgICBwdWJsaWMgaW50IGNvbXBhcmVUbyhPYmplY3QgbykgewogICAgICAgICAgICBpZiAobyA9PSBudWxsKSByZXR1cm4gMTsKICAgICAgICAgICAgaW50IHJlc3VsdDsKICAgICAgICAgICAgRWxlbWVudCB0aGF0ID0gKEVsZW1lbnQpIG87CiAgICAgICAgICAgIGlmICgocmVzdWx0ID0gZWxlbWVudE9yZGVyaW5nLmNvbXBhcmUoZWxlbWVudE5hbWUsIHRoYXQuZWxlbWVudE5hbWUpKSAhPSAwKSByZXR1cm4gcmVzdWx0OwogICAgICAgICAgICByZXR1cm4gYXR0cmlidXRlcy5jb21wYXJlVG8odGhhdC5hdHRyaWJ1dGVzKTsKICAgICAgICB9CiAgICAgICAgcHVibGljIGJvb2xlYW4gZXF1YWxzKE9iamVjdCBvKSB7CiAgICAgICAgICAgIGlmICghKG8gaW5zdGFuY2VvZiBFbGVtZW50KSkgcmV0dXJuIGZhbHNlOwogICAgICAgIAlyZXR1cm4gY29tcGFyZVRvKG8pID09IDA7CiAgICAgICAgfQogICAgICAgIC8qCiAgICAgICAgcHVibGljIHZvaWQgYWRkQ29tbWVudChTdHJpbmcgaW5fY29tbWVudCkgewogICAgICAgICAgICBpZiAoY29tbWVudCA9PSBudWxsKSBjb21tZW50ID0gaW5fY29tbWVudDsKICAgICAgICAgICAgZWxzZSBjb21tZW50ICs9IE5FV0xJTkUgKyBpbl9jb21tZW50OwogICAgICAgICAgICByZXR1cm47CiAgICAgICAgfQogICAgICAgICovCgkJLyoqCgkJICogQHBhcmFtIGlnbm9yZWxpc3QKCQkgKiBAcmV0dXJuCgkJICovCgkJcHVibGljIHZvaWQgcmVtb3ZlQXR0cmlidXRlcyhTZXQgaWdub3JlbGlzdCkgewogICAgICAgICAgICBhdHRyaWJ1dGVzLnJlbW92ZUF0dHJpYnV0ZXMoaWdub3JlbGlzdCk7CgkJfQogICAgfQogICAgCiAgICBwcml2YXRlIHZvaWQgd3JpdGVFbGVtZW50Q29tbWVudChTdHJpbmdCdWZmZXIgb3V0LCBTdHJpbmcgY29tbWVudCwgaW50IGNvbW1vbikgewogICAgICAgIGlmIChjb21tZW50ICE9IG51bGwpIHsKICAgICAgICAgICAgaW5kZW50KGNvbW1vbiwgb3V0KTsKICAgICAgICAgICAgb3V0LmFwcGVuZCgiPCEtLSAiKTsKICAgICAgICAgICAgb3V0LmFwcGVuZChjb21tZW50KTsKICAgICAgICAgICAgaWYgKGNvbW1lbnQuaW5kZXhPZignXG4nKSA+PSAwKSB7CiAgICAgICAgICAgICAgICBvdXQuYXBwZW5kKCJcclxuIik7CiAgICAgICAgICAgICAgICBpbmRlbnQoY29tbW9uLCBvdXQpOwogICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAJb3V0LmFwcGVuZCgiICIpOwogICAgICAgICAgICB9CiAgICAgICAgICAgIG91dC5hcHBlbmQoIi0tPlxyXG4iKTsKICAgICAgICB9CiAgICB9CgogICAgY2xhc3MgRWxlbWVudENoYWluIGltcGxlbWVudHMgQ29tcGFyYWJsZSB7CiAgICAgICAgTGlzdCBjb250ZXh0czsKICAgICAgICAKICAgICAgICBFbGVtZW50Q2hhaW4oKSB7CiAgICAgICAgICAgIGNvbnRleHRzID0gbmV3IEFycmF5TGlzdCgpOwogICAgICAgIH0KICAgICAgICAKICAgICAgICAvKioKCQkgKiBAcGFyYW0gc3RyaW5nCgkJICogQHJldHVybgoJCSAqLwoJCXB1YmxpYyBFbGVtZW50IGdldEVsZW1lbnQoU3RyaW5nIHN0cmluZykgewogICAgICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IGNvbnRleHRzLnNpemUoKTsgKytpKSB7CiAgICAgICAgICAgICAgICBFbGVtZW50IHggPSAoRWxlbWVudCljb250ZXh0cy5nZXQoaSk7CiAgICAgICAgICAgICAgICBpZiAoc3RyaW5nLmVxdWFscyh4LmVsZW1lbnROYW1lKSkgcmV0dXJuIHg7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgcmV0dXJuIG51bGw7CgkJfQoKCQkvKioKICAgICAgICAgKiBAcGFyYW0gc3RyaW5nCiAgICAgICAgICogQHBhcmFtIHN0cmluZzIKICAgICAgICAgKiBAcGFyYW0gc3RyaW5nMwogICAgICAgICAqLwogICAgICAgIHB1YmxpYyB2b2lkIHNldEF0dHJpYnV0ZShTdHJpbmcgZWxlbWVudCwgU3RyaW5nIGF0dHJpYnV0ZSwgU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgY29udGV4dHMuc2l6ZSgpOyArK2kpIHsKICAgICAgICAgICAgICAgIEVsZW1lbnQgY29udGV4dCA9IChFbGVtZW50KWNvbnRleHRzLmdldChpKTsKICAgICAgICAgICAgICAgIGlmIChjb250ZXh0LmVsZW1lbnROYW1lLmVxdWFscyhlbGVtZW50KSkgewogICAgICAgICAgICAgICAgICAgIGNvbnRleHQgPSBuZXcgRWxlbWVudChjb250ZXh0KTsgLy8gY2xvbmUgZm9yIHNhZmV0eQogICAgICAgICAgICAgICAgICAgIGNvbnRleHQuYXR0cmlidXRlcy5zZXQoZWxlbWVudCwgYXR0cmlidXRlLCB2YWx1ZSk7CiAgICAgICAgICAgICAgICAgICAgY29udGV4dHMuc2V0KGksIGNvbnRleHQpOwogICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICBFbGVtZW50Q2hhaW4oRWxlbWVudENoYWluIG90aGVyKSB7CiAgICAgICAgICAgIGNvbnRleHRzID0gbmV3IEFycmF5TGlzdChvdGhlci5jb250ZXh0cyk7CiAgICAgICAgfQogICAgICAgIAogICAgICAgIHB1YmxpYyBFbGVtZW50Q2hhaW4gcHVzaChTdHJpbmcgZWxlbWVudE5hbWUsIEF0dHJpYnV0ZXMgYXR0cmlidXRlcywgU3RyaW5nIGNvbW1lbnQpIHsKICAgICAgICAgICAgZWxlbWVudE9yZGVyaW5nLmFkZChlbGVtZW50TmFtZSk7CiAgICAgICAgICAgIGNvbnRleHRzLmFkZChuZXcgRWxlbWVudChlbGVtZW50TmFtZSwgYXR0cmlidXRlcywgY29tbWVudCkpOwogICAgICAgICAgICByZXR1cm4gdGhpczsKICAgICAgICB9CiAgICAgICAgCiAgICAgICAgcHVibGljIHZvaWQgcG9wKFN0cmluZyBlbGVtZW50TmFtZSkgewogICAgICAgICAgICBpbnQgbGFzdCA9IGNvbnRleHRzLnNpemUoKS0xOwogICAgICAgICAgICBFbGVtZW50IGMgPSAoRWxlbWVudCkgY29udGV4dHMuZ2V0KGxhc3QpOwogICAgICAgICAgICBpZiAoIWMuZWxlbWVudE5hbWUuZXF1YWxzKGVsZW1lbnROYW1lKSkgdGhyb3cgbmV3IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigibWlzbWF0Y2giKTsKICAgICAgICAgICAgY29udGV4dHMucmVtb3ZlKGxhc3QpOwogICAgICAgIH0KICAgICAgICAKICAgICAgICBwdWJsaWMgU3RyaW5nIHRvU3RyaW5nKCkgewogICAgICAgICAgICAvL3Rocm93IG5ldyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oIkRvbid0IHVzZSIpOwogICAgICAgICAgICByZXR1cm4gdG9TdHJpbmcodHJ1ZSwgMCwgSW50ZWdlci5NQVhfVkFMVUUpOwogICAgICAgIH0KICAgICAgICAKICAgICAgICBwdWJsaWMgU3RyaW5nIHRvU3RyaW5nKGJvb2xlYW4gcGF0aCwgaW50IHN0YXJ0TGV2ZWwsIGludCBsaW1pdExldmVsKSB7CiAgICAgICAgICAgIFN0cmluZ0J1ZmZlciBidWZmZXIgPSBuZXcgU3RyaW5nQnVmZmVyKCk7CiAgICAgICAgICAgIGlmIChzdGFydExldmVsIDwgMCkgc3RhcnRMZXZlbCA9IDA7CiAgICAgICAgICAgIGlmIChsaW1pdExldmVsID4gY29udGV4dHMuc2l6ZSgpKSBsaW1pdExldmVsID0gY29udGV4dHMuc2l6ZSgpOwogICAgICAgICAgICBmb3IgKGludCBpID0gc3RhcnRMZXZlbDsgaSA8IGxpbWl0TGV2ZWw7ICsraSkgewogICAgICAgICAgICAgICAgLy9pZiAoaSAhPSAwKSBidWZmZXIuYXBwZW5kKCcgJyk7CiAgICAgICAgICAgICAgICBFbGVtZW50IGUgPSAoRWxlbWVudCkgY29udGV4dHMuZ2V0KGkpOwogICAgICAgICAgICAgICAgaWYgKHBhdGgpIGJ1ZmZlci5hcHBlbmQoIi8iICsgZS50b1N0cmluZyhFbGVtZW50LlBBVEgpKTsKICAgICAgICAgICAgICAgIGVsc2UgYnVmZmVyLmFwcGVuZChlLnRvU3RyaW5nKEVsZW1lbnQuU1RBUlRfVkFMVUUpKTsKICAgICAgICAgICAgfQogICAgICAgICAgICByZXR1cm4gYnVmZmVyLnRvU3RyaW5nKCk7CiAgICAgICAgfQogICAgICAgIAogICAgICAgIHB1YmxpYyBib29sZWFuIGVxdWFscyhPYmplY3Qgb3RoZXIpIHsKICAgICAgICAgICAgcmV0dXJuIGNvbXBhcmVUbyhvdGhlcikgPT0gMDsKICAgICAgICB9CiAgICAgICAgcHVibGljIGludCBoYXNoQ29kZSgpIHsKICAgICAgICAgICAgcmV0dXJuIGNvbnRleHRzLmhhc2hDb2RlKCk7CiAgICAgICAgfQoKICAgICAgICAvKiAobm9uLUphdmFkb2MpCiAgICAgICAgICogQHNlZSBqYXZhLmxhbmcuQ29tcGFyYWJsZSNjb21wYXJlVG8oamF2YS5sYW5nLk9iamVjdCkKICAgICAgICAgKi8KICAgICAgICBwdWJsaWMgaW50IGNvbXBhcmVUbyhPYmplY3QgbykgewogICAgICAgICAgICBpbnQgcmVzdWx0OwogICAgICAgICAgICBFbGVtZW50Q2hhaW4gdGhhdCA9IChFbGVtZW50Q2hhaW4pIG87CiAgICAgICAgICAgIGlmIChERUJVR19FTEVNRU5UICYmIGNvbnRhaW5zRWxlbWVudCgid2Vla2VuZEVuZCIpICYmIHRoYXQuY29udGFpbnNFbGVtZW50KCgid2Vla2VuZEVuZCIpKSkgewogICAgICAgICAgICAgICAgcmVzdWx0ID0gNjY2OwogICAgICAgICAgICB9CiAgICAgICAgICAgIGludCBtaW5MZW4gPSBNYXRoLm1pbihjb250ZXh0cy5zaXplKCksIHRoYXQuY29udGV4dHMuc2l6ZSgpKTsKICAgICAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBtaW5MZW47ICsraSkgewogICAgICAgICAgICAgICAgaWYgKChyZXN1bHQgPSAoKEVsZW1lbnQpY29udGV4dHMuZ2V0KGkpKS5jb21wYXJlVG8odGhhdC5jb250ZXh0cy5nZXQoaSkpKSAhPSAwKSByZXR1cm4gcmVzdWx0OwogICAgICAgICAgICB9CiAgICAgICAgICAgIHJldHVybiBjb21wYXJlSW50KGNvbnRleHRzLnNpemUoKSwgdGhhdC5jb250ZXh0cy5zaXplKCkpOwogICAgICAgIH0KICAgICAgICBwdWJsaWMgdm9pZCB3cml0ZURpZmZlcmVuY2UoRWxlbWVudENoYWluIGZvcm1lciwgRW5kTm9kZSB2YWx1ZSwgU3RyaW5nQnVmZmVyIG91dCkgewogICAgICAgICAgICAvLyBmaW5kIHRoZSBpZGVudGljYWwgc3R1ZmYgZmlyc3QhCiAgICAgICAgICAgIGludCBjc2l6ZSA9IGNvbnRleHRzLnNpemUoKTsKICAgICAgICAgICAgaW50IGZzaXplID0gZm9ybWVyLmNvbnRleHRzLnNpemUoKTsKICAgICAgICAgICAgaW50IG1pbkxlbiA9IE1hdGgubWluKGNzaXplLCBmc2l6ZSk7CiAgICAgICAgICAgIGludCByZXN1bHQ7CiAgICAgICAgICAgIAogICAgICAgICAgICAvLyBza2lwIHN0dWZmIHRoYXQgaXMgaW4gY29tbW9uCiAgICAgICAgICAgIGludCBjb21tb247CiAgICAgICAgICAgIGZvciAoY29tbW9uID0gMDsgY29tbW9uIDwgbWluTGVuOyArK2NvbW1vbikgewogICAgICAgICAgICAgICAgaWYgKChyZXN1bHQgPSAoKEVsZW1lbnQpY29udGV4dHMuZ2V0KGNvbW1vbikpLmNvbXBhcmVUbyhmb3JtZXIuY29udGV4dHMuZ2V0KGNvbW1vbikpKSAhPSAwKSBicmVhazsKICAgICAgICAgICAgfQogICAgICAgICAgICAvLyBmaW5pc2ggdXAgb2xkIGVsZW1lbnRzLCBieSB3cml0aW5nIG91dCB0ZXJtaW5hdGlvbiBlbGVtZW50cy4KICAgICAgICAgICAgLy8gV2UgZG9uJ3QgZG8gdGhlIHZlcnkgbGFzdCBvbmUsIGhvd2V2ZXIsIHNpbmNlIHRoYXQgd2FzIGRvbmUgd2l0aCB0aGUgdmFsdWUKICAgICAgICAgICAgZm9yIChpbnQgaiA9IGZzaXplIC0gMjsgaiA+PSBjb21tb247IC0taikgewogICAgICAgICAgICAgICAgaW5kZW50KGosIG91dCk7CiAgICAgICAgICAgICAgICBvdXQuYXBwZW5kKCgoRWxlbWVudClmb3JtZXIuY29udGV4dHMuZ2V0KGopKS50b1N0cmluZyhFbGVtZW50LkVORF9WQUxVRSkpOwogICAgICAgICAgICAgICAgb3V0LmFwcGVuZChORVdMSU5FKTsKICAgICAgICAgICAgfQogICAgICAgICAgICBpZiAoY3NpemUgPT0gMCkgcmV0dXJuOyAvLyB3ZSBtdXN0IGJlIGF0IHRoZSB2ZXJ5IGVuZCwgYmFpbC4KICAgICAgICAgICAgCiAgICAgICAgICAgIC8vIHdyaXRlIG5ldyBlbGVtZW50cyBpZiBuZWVkZWQuCiAgICAgICAgICAgIGZvciAoOyBjb21tb24gPCBjc2l6ZS0xOyArK2NvbW1vbikgewogICAgICAgICAgICAgICAgRWxlbWVudCBlZSA9ICgoRWxlbWVudCljb250ZXh0cy5nZXQoY29tbW9uKSk7CiAgICAgICAgICAgICAgICB3cml0ZUVsZW1lbnRDb21tZW50KG91dCwgZWUuY29tbWVudCwgY29tbW9uKTsKICAgICAgICAgICAgICAgIGluZGVudChjb21tb24sIG91dCk7CiAgICAgICAgICAgICAgICBvdXQuYXBwZW5kKGVlLnRvU3RyaW5nKEVsZW1lbnQuU1RBUlRfVkFMVUUpKTsKICAgICAgICAgICAgICAgIG91dC5hcHBlbmQoTkVXTElORSk7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgLy8gbm93IHdyaXRlIHRoZSB2ZXJ5IGN1cnJlbnQgZWxlbWVudAogICAgICAgICAgICBFbGVtZW50IGVlID0gKChFbGVtZW50KWNvbnRleHRzLmdldChjc2l6ZS0xKSk7CiAgICAgICAgICAgIHdyaXRlRWxlbWVudENvbW1lbnQob3V0LCBlZS5jb21tZW50LCBjb21tb24pOwogICAgICAgICAgICBpbmRlbnQoY29tbW9uLCBvdXQpOwogICAgICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCB8fCAiIi5lcXVhbHModmFsdWUuc3RyaW5nKSkgeyAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgb3V0LmFwcGVuZChlZS50b1N0cmluZyhFbGVtZW50Lk5PX1ZBTFVFKSk7CiAgICAgICAgICAgIH0gZWxzZSBpZiAodmFsdWUuc3RyaW5nID09IG51bGwpIHsKICAgICAgICAgICAgICAgIEVsZW1lbnQgdGVtcCA9IG5ldyBFbGVtZW50KGVlKTsgLy8gY2xvbmUgZm9yIHNhZmV0eQogICAgICAgICAgICAgICAgdGVtcC5hdHRyaWJ1dGVzLmFkZCh2YWx1ZS5hdHRyaWJ1dGVzKTsKICAgICAgICAgICAgICAgIG91dC5hcHBlbmQodGVtcC50b1N0cmluZyhFbGVtZW50Lk5PX1ZBTFVFKSk7CiAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICBvdXQuYXBwZW5kKGVlLnRvU3RyaW5nKEVsZW1lbnQuU1RBUlRfVkFMVUUpKTsKICAgICAgICAgICAgICAgIG91dC5hcHBlbmQodmFsdWUudG9TdHJpbmcoRWxlbWVudC5OT19WQUxVRSkpOwogICAgICAgICAgICAgICAgb3V0LmFwcGVuZChlZS50b1N0cmluZyhFbGVtZW50LkVORF9WQUxVRSkpOwogICAgICAgICAgICB9CiAgICAgICAgICAgIG91dC5hcHBlbmQoTkVXTElORSk7CiAgICAgICAgfQoKICAgICAgICBwdWJsaWMgYm9vbGVhbiBjb250YWluc0VsZW1lbnQoU3RyaW5nIHN0cmluZykgewogICAgICAgICAgICByZXR1cm4gZ2V0RWxlbWVudChzdHJpbmcpICE9IG51bGw7CiAgICAgICAgfQoKCQlwdWJsaWMgRWxlbWVudCBnZXRMYXN0KCkgewoJCQlyZXR1cm4gKEVsZW1lbnQpIGNvbnRleHRzLmdldChjb250ZXh0cy5zaXplKCktMSk7CgkJfQoKCQkvKioKCQkgKiBAcGFyYW0gaWdub3JlbGlzdAoJCSAqIEByZXR1cm4KCQkgKi8KCQlwdWJsaWMgRWxlbWVudENoYWluIGNyZWF0ZVJlbW92aW5nQXR0cmlidXRlcyhTZXQgaWdub3JlbGlzdCkgewoJCQlFbGVtZW50Q2hhaW4gcmVzdWx0ID0gbmV3IEVsZW1lbnRDaGFpbih0aGlzKTsKICAgICAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBjb250ZXh0cy5zaXplKCk7ICsraSkgewogICAgICAgICAgICAJRWxlbWVudCBlID0gKEVsZW1lbnQpY29udGV4dHMuZ2V0KGkpOwogICAgICAgICAgICAgICAgZS5yZW1vdmVBdHRyaWJ1dGVzKGlnbm9yZWxpc3QpOwogICAgICAgICAgICB9CiAgICAgICAgICAgIHJldHVybiByZXN1bHQ7CgkJfQoKCQkvKioKCQkgKiBAcGFyYW0gY29tbWVudAoJCSAqLwogICAgICAgIC8qCiAgICAgICAgcHVibGljIHZvaWQgYWRkQ29tbWVudChTdHJpbmcgY29tbWVudCkgewogICAgICAgIAlpbnQgY291bnQgPSBjb250ZXh0cy5zaXplKCk7CiAgICAgICAgCWlmIChjb3VudCA9PSAwKSB7CiAgICAgICAgCQlTeXN0ZW0ub3V0LnByaW50bG4oIlNraXBwaW5nIHN0YXJ0IGNvbW1lbnQgZm9yIG5vdyIpOwogICAgICAgIAkJLy9pZiAoc3RhcnRDb21tZW50ID09IG51bGwpIHN0YXJ0Q29tbWVudCA9IGNvbW1lbnQ7CiAgICAgICAgCQkvL2Vsc2Ugc3RhcnRDb21tZW50ICs9IE5FV0xJTkUgKyBjb21tZW50OwogICAgICAgIAkJcmV0dXJuOwogICAgICAgIAl9CiAgICAgICAgCUVsZW1lbnQgZWMgPSAoRWxlbWVudCkgY29udGV4dHMuZ2V0KGNvdW50LTEpOwogICAgICAgIAllYy5hZGRDb21tZW50KGNvbW1lbnQpOwogICAgICAgIH0KICAgICAgICAqLwogICAgfQogICAgCiAgICBzdGF0aWMgaW50IGNvbXBhcmVJbnQoaW50IGEsIGludCBiKSB7CiAgICAgICAgcmV0dXJuIGEgPCBiID8gLTEgOiBhID4gYiA/IDEgOiAwOwogICAgfQogICAgCiAgICBzdGF0aWMgdm9pZCBpbmRlbnQoaW50IGNvdW50LCBTdHJpbmdCdWZmZXIgb3V0KSB7CiAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBjb3VudDsgKytpKSB7CiAgICAgICAgICAgIG91dC5hcHBlbmQoIlx0Iik7CiAgICAgICAgfQogICAgfQogICAgCiAgICAvKgogICAgc3RhdGljIHsKICAgICAgICBPYmplY3RbXVtdIHRlbXAgPSB7CiAgICAgICAgICAgIHsia2V5cyIsIG5ldyBJbnRlZ2VyKDEzKX0sCiAgICAgICAgICAgIHsic2NyaXB0cyIsIG5ldyBJbnRlZ2VyKDcpfSwKICAgICAgICAgICAgeyJzY3JpcHQiLCBuZXcgSW50ZWdlcig4KX0sCiAgICAgICAgICAgIHsiZXJhIiwgbmV3IEludGVnZXIoMzgpfSwKICAgICAgICAgICAgeyJsZG1sIiwgbmV3IEludGVnZXIoMCl9LAogICAgICAgICAgICB7ImNhbGVuZGFyIiwgbmV3IEludGVnZXIoMjIpfSwKICAgICAgICAgICAgeyJudW1iZXJzIiwgbmV3IEludGVnZXIoNTcpfSwKICAgICAgICAgICAgeyJ0aW1lRm9ybWF0cyIsIG5ldyBJbnRlZ2VyKDQ0KX0sCiAgICAgICAgICAgIHsiaW5maW5pdHkiLCBuZXcgSW50ZWdlcig2OSl9LAogICAgICAgICAgICB7ImxvY2FsaXplZFBhdHRlcm5DaGFycyIsIG5ldyBJbnRlZ2VyKDIwKX0sCiAgICAgICAgICAgIHsiZGF0ZVRpbWVGb3JtYXRzIiwgbmV3IEludGVnZXIoNDcpfSwKICAgICAgICAgICAgeyJlcmFBYmJyIiwgbmV3IEludGVnZXIoMzcpfSwKICAgICAgICAgICAgeyJleGVtcGxhckNoYXJhY3RlcnMiLCBuZXcgSW50ZWdlcigxOCl9LAogICAgICAgICAgICB7Im1vbnRoIiwgbmV3IEludGVnZXIoMjYpfSwKICAgICAgICAgICAgeyJ2YXJpYW50cyIsIG5ldyBJbnRlZ2VyKDExKX0sCiAgICAgICAgICAgIHsiZ3JvdXAiLCBuZXcgSW50ZWdlcig2MCl9LAogICAgICAgICAgICB7ImRhdGVUaW1lRm9ybWF0IiwgbmV3IEludGVnZXIoNDkpfSwKICAgICAgICAgICAgeyJkYXkiLCBuZXcgSW50ZWdlcigzMCl9LAogICAgICAgICAgICB7InpvbmUiLCBuZXcgSW50ZWdlcig1MSl9LAogICAgICAgICAgICB7InR5cGVzIiwgbmV3IEludGVnZXIoMTUpfSwKICAgICAgICAgICAgeyJ0aW1lRm9ybWF0IiwgbmV3IEludGVnZXIoNDYpfSwKICAgICAgICAgICAgeyJkZWZhdWx0IiwgbmV3IEludGVnZXIoNDApfSwKICAgICAgICAgICAgeyJkYXRlcyIsIG5ldyBJbnRlZ2VyKDE5KX0sCiAgICAgICAgICAgIHsibGFuZ3VhZ2UiLCBuZXcgSW50ZWdlcig0KX0sCiAgICAgICAgICAgIHsibG9uZyIsIG5ldyBJbnRlZ2VyKDUyKX0sCiAgICAgICAgICAgIHsidmVyc2lvbiIsIG5ldyBJbnRlZ2VyKDIpfSwKICAgICAgICAgICAgeyJkYXlXaWR0aCIsIG5ldyBJbnRlZ2VyKDI5KX0sCiAgICAgICAgICAgIHsiY2hhcmFjdGVycyIsIG5ldyBJbnRlZ2VyKDE3KX0sCiAgICAgICAgICAgIHsidmFyaWFudCIsIG5ldyBJbnRlZ2VyKDEyKX0sCiAgICAgICAgICAgIHsic2hvcnQiLCBuZXcgSW50ZWdlcig1NSl9LAogICAgICAgICAgICB7ImdlbmVyYXRpb24iLCBuZXcgSW50ZWdlcigzKX0sCiAgICAgICAgICAgIHsiYW0iLCBuZXcgSW50ZWdlcigzNCl9LAogICAgICAgICAgICB7InBhdHRlcm4iLCBuZXcgSW50ZWdlcig0Myl9LAogICAgICAgICAgICB7Im1pbkRheXMiLCBuZXcgSW50ZWdlcigzMil9LAogICAgICAgICAgICB7ImRpc3BsYXlOYW1lIiwgbmV3IEludGVnZXIoNzMpfSwKICAgICAgICAgICAgeyJwZXJNaWxsZSIsIG5ldyBJbnRlZ2VyKDY4KX0sCiAgICAgICAgICAgIHsibW9udGhDb250ZXh0IiwgbmV3IEludGVnZXIoMjQpfSwKICAgICAgICAgICAgeyJkYXlzIiwgbmV3IEludGVnZXIoMjcpfSwKICAgICAgICAgICAgeyJtb250aHMiLCBuZXcgSW50ZWdlcigyMyl9LAogICAgICAgICAgICB7InRlcnJpdG9yaWVzIiwgbmV3IEludGVnZXIoOSl9LAogICAgICAgICAgICB7ImlkZW50aXR5IiwgbmV3IEludGVnZXIoMSl9LAogICAgICAgICAgICB7ImN1cnJlbmN5IiwgbmV3IEludGVnZXIoNzIpfSwKICAgICAgICAgICAgeyJleHBvbmVudGlhbCIsIG5ldyBJbnRlZ2VyKDY3KX0sCiAgICAgICAgICAgIHsidGVycml0b3J5IiwgbmV3IEludGVnZXIoMTApfSwKICAgICAgICAgICAgeyJmaXJzdERheSIsIG5ldyBJbnRlZ2VyKDMzKX0sCiAgICAgICAgICAgIHsibGFuZ3VhZ2VzIiwgbmV3IEludGVnZXIoNil9LAogICAgICAgICAgICB7Im5hbiIsIG5ldyBJbnRlZ2VyKDcwKX0sCiAgICAgICAgICAgIHsid2VlayIsIG5ldyBJbnRlZ2VyKDMxKX0sCiAgICAgICAgICAgIHsibmF0aXZlWmVyb0RpZ2l0IiwgbmV3IEludGVnZXIoNjMpfSwKICAgICAgICAgICAgeyJkZWNpbWFsIiwgbmV3IEludGVnZXIoNTkpfSwKICAgICAgICAgICAgeyJzeW1ib2xzIiwgbmV3IEludGVnZXIoNTgpfSwKICAgICAgICAgICAgeyJkYXlsaWdodCIsIG5ldyBJbnRlZ2VyKDU0KX0sCiAgICAgICAgICAgIHsiY2FsZW5kYXJzIiwgbmV3IEludGVnZXIoMjEpfSwKICAgICAgICAgICAgeyJlcmFzIiwgbmV3IEludGVnZXIoMzYpfSwKICAgICAgICAgICAgeyJsb2NhbGVEaXNwbGF5TmFtZXMiLCBuZXcgSW50ZWdlcig1KX0sCiAgICAgICAgICAgIHsiZGF0ZVRpbWVGb3JtYXRMZW5ndGgiLCBuZXcgSW50ZWdlcig0OCl9LAogICAgICAgICAgICB7ImRhdGVGb3JtYXRzIiwgbmV3IEludGVnZXIoMzkpfSwKICAgICAgICAgICAgeyJleGVtcGxhckNpdHkiLCBuZXcgSW50ZWdlcig1Nil9LAogICAgICAgICAgICB7ImN1cnJlbmNpZXMiLCBuZXcgSW50ZWdlcig3MSl9LAogICAgICAgICAgICB7Im1pbnVzU2lnbiIsIG5ldyBJbnRlZ2VyKDY2KX0sCiAgICAgICAgICAgIHsibGlzdCIsIG5ldyBJbnRlZ2VyKDYxKX0sCiAgICAgICAgICAgIHsiZGF0ZUZvcm1hdExlbmd0aCIsIG5ldyBJbnRlZ2VyKDQxKX0sCiAgICAgICAgICAgIHsidHlwZSIsIG5ldyBJbnRlZ2VyKDE2KX0sCiAgICAgICAgICAgIHsicGx1c1NpZ24iLCBuZXcgSW50ZWdlcig2NSl9LAogICAgICAgICAgICB7ImRheUNvbnRleHQiLCBuZXcgSW50ZWdlcigyOCl9LAogICAgICAgICAgICB7ImRhdGVGb3JtYXQiLCBuZXcgSW50ZWdlcig0Mil9LAogICAgICAgICAgICB7InN5bWJvbCIsIG5ldyBJbnRlZ2VyKDc0KX0sCiAgICAgICAgICAgIHsidGltZVpvbmVOYW1lcyIsIG5ldyBJbnRlZ2VyKDUwKX0sCiAgICAgICAgICAgIHsia2V5IiwgbmV3IEludGVnZXIoMTQpfSwKICAgICAgICAgICAgeyJwYXR0ZXJuRGlnaXQiLCBuZXcgSW50ZWdlcig2NCl9LAogICAgICAgICAgICB7InBlcmNlbnRTaWduIiwgbmV3IEludGVnZXIoNjIpfSwKICAgICAgICAgICAgeyJzdGFuZGFyZCIsIG5ldyBJbnRlZ2VyKDUzKX0sCiAgICAgICAgICAgIHsibW9udGhXaWR0aCIsIG5ldyBJbnRlZ2VyKDI1KX0sCiAgICAgICAgICAgIHsicG0iLCBuZXcgSW50ZWdlcigzNSl9LAogICAgICAgICAgICB7InRpbWVGb3JtYXRMZW5ndGgiLCBuZXcgSW50ZWdlcig0NSl9LAogICAgICAgIH07CiAgICAgICAgZWxlbWVudE9yZGVyaW5nID0gbmV3IE1hcENvbXBhcmF0b3IodGVtcCk7CiAgICB9CiAgICAqLwogICAgCiAgICBwdWJsaWMgc3RhdGljIGNsYXNzIE1hcENvbXBhcmF0b3IgewogICAgICAgIE1hcCBvcmRlcmluZyA9IG5ldyBUcmVlTWFwKCk7IC8vIG1hcHMgZnJvbSBuYW1lIHRvIHJhbmsKICAgICAgICBMaXN0IHJhbmtUb05hbWUgPSBuZXcgQXJyYXlMaXN0KCk7CiAgICAgICAgCiAgICAgICAgTWFwQ29tcGFyYXRvcigpe30KICAgICAgICBNYXBDb21wYXJhdG9yKENvbXBhcmFibGVbXSBkYXRhKSB7CiAgICAgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgZGF0YS5sZW5ndGg7ICsraSkgewogICAgICAgICAgICAgICAgYWRkKGRhdGFbaV0pOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIHB1YmxpYyB2b2lkIGFkZChDb21wYXJhYmxlIG5ld09iamVjdCkgewogICAgICAgICAgICBPYmplY3QgYWxyZWFkeSA9IG9yZGVyaW5nLmdldChuZXdPYmplY3QpOwogICAgICAgICAgICBpZiAoYWxyZWFkeSA9PSBudWxsKSB7CiAgICAgICAgICAgICAgICBvcmRlcmluZy5wdXQobmV3T2JqZWN0LCBuZXcgSW50ZWdlcihyYW5rVG9OYW1lLnNpemUoKSkpOwogICAgICAgICAgICAgICAgcmFua1RvTmFtZS5hZGQobmV3T2JqZWN0KTsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgICAgICBwdWJsaWMgaW50IGNvbXBhcmUoQ29tcGFyYWJsZSBhLCBDb21wYXJhYmxlIGIpIHsKICAgICAgICAgICAgQ29tcGFyYWJsZSBhYSA9IChDb21wYXJhYmxlKSBvcmRlcmluZy5nZXQoYSk7CiAgICAgICAgICAgIE9iamVjdCBiYiA9IG9yZGVyaW5nLmdldChiKTsKICAgICAgICAgICAgaWYgKGFhID09IG51bGwgfHwgYmIgPT0gbnVsbCkgcmV0dXJuIGEuY29tcGFyZVRvKGIpOwogICAgICAgICAgICByZXR1cm4gYWEuY29tcGFyZVRvKGJiKTsKICAgICAgICB9CiAgICAgICAgcHVibGljIFN0cmluZyB0b1N0cmluZygpIHsKICAgICAgICAgICAgU3RyaW5nQnVmZmVyIGJ1ZmZlciA9IG5ldyBTdHJpbmdCdWZmZXIoKTsKICAgICAgICAgICAgZm9yIChJdGVyYXRvciBpdCA9IHJhbmtUb05hbWUuaXRlcmF0b3IoKTsgaXQuaGFzTmV4dCgpOykgewogICAgICAgICAgICAgICAgT2JqZWN0IGtleSA9IGl0Lm5leHQoKTsKICAgICAgICAgICAgICAgIGJ1ZmZlci5hcHBlbmQoIlwiIikuYXBwZW5kKGtleSkuYXBwZW5kKCJcIiwiK05FV0xJTkUpOwogICAgICAgICAgICB9CiAgICAgICAgICAgIHJldHVybiBidWZmZXIudG9TdHJpbmcoKTsKICAgICAgICB9CiAgICB9CiAgICAKICAgIHB1YmxpYyBzdGF0aWMgY2xhc3MgT3JkZXJlZE1hcCB7CiAgICAgICAgcHJpdmF0ZSBNYXAgbWFwID0gbmV3IFRyZWVNYXAoKTsKICAgICAgICBwcml2YXRlIExpc3QgbGlzdCA9IG5ldyBBcnJheUxpc3QoKTsKICAgICAgICBwdWJsaWMgdm9pZCBwdXQoT2JqZWN0IGEsIE9iamVjdCBiKSB7CiAgICAgICAgICAgIG1hcC5wdXQoYSxiKTsKICAgICAgICAgICAgbGlzdC5hZGQoYSk7CiAgICAgICAgfQogICAgICAgIC8qKgoJCSAqIEBwYXJhbSBrZXkKCQkgKiBAcmV0dXJuCgkJICovCgkJcHVibGljIE9iamVjdCBnZXRLZXlGb3IoRWxlbWVudENoYWluIGtleSkgewogICAgICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IGxpc3Quc2l6ZSgpOyArK2kpIHsKICAgICAgICAgICAgCWlmIChsaXN0LmdldChpKS5lcXVhbHMoa2V5KSkgcmV0dXJuIGtleTsKICAgICAgICAgICAgfQoJCQlyZXR1cm4gbnVsbDsKCQl9CgkJLyoqCgkJICogQHBhcmFtIG9iamVjdAoJCSAqLwoJCXB1YmxpYyB2b2lkIHJlbW92ZShPYmplY3Qgb2JqZWN0KSB7CgkJCW1hcC5yZW1vdmUob2JqZWN0KTsKICAgICAgICAgICAgbGlzdC5yZW1vdmUob2JqZWN0KTsKCQl9CgkJLyoqCiAgICAgICAgICogQHBhcmFtIG1hcAogICAgICAgICAqLwogICAgICAgIC8qCiAgICAgICAgcHVibGljIHZvaWQgcmVtb3ZlQWxsKE9yZGVyZWRNYXAgb3RoZXIpIHsKICAgICAgICAgICAgZm9yIChJdGVyYXRvciBpdCA9IG90aGVyLml0ZXJhdG9yKCk7IGl0Lmhhc05leHQoKTspIHsKICAgICAgICAgICAgICAgIE9iamVjdCBrZXkgPSBpdC5uZXh0KCk7CiAgICAgICAgICAgICAgICBPYmplY3Qgb3RoZXJWYWx1ZSA9IG90aGVyLm1hcC5nZXQoa2V5KTsKICAgICAgICAgICAgICAgIE9iamVjdCB2YWx1ZSA9IG1hcC5nZXQoa2V5KTsKICAgICAgICAgICAgICAgIGlmICh2YWx1ZSA9PSBudWxsIHx8ICF2YWx1ZS5lcXVhbHMob3RoZXJWYWx1ZSkpIGNvbnRpbnVlOwogICAgICAgICAgICAgICAgaWYgKCgoRWxlbWVudENoYWluKWtleSkuY29udGFpbnNFbGVtZW50KCJpZGVudGl0eSIpKSBjb250aW51ZTsKICAgICAgICAgICAgICAgIHZhbHVlLmVxdWFscyhvdGhlclZhbHVlKTsKICAgICAgICAgICAgICAgIGxvZy5wcmludGxuKCJSZW1vdmluZyAiICsgKChFbGVtZW50Q2hhaW4pa2V5KS50b1N0cmluZyh0cnVlLCAwKSArICJcdCIgKyB2YWx1ZSk7CiAgICAgICAgICAgICAgICBtYXAucmVtb3ZlKGtleSk7CiAgICAgICAgICAgICAgICB3aGlsZShsaXN0LnJlbW92ZShrZXkpKSB7fQogICAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgICovCiAgICAgICAgcHVibGljIE9iamVjdCBnZXQoT2JqZWN0IGEpIHsKICAgICAgICAgICAgcmV0dXJuIG1hcC5nZXQoYSk7CiAgICAgICAgfQogICAgICAgIHB1YmxpYyBJdGVyYXRvciBpdGVyYXRvcigpIHsKICAgICAgICAgICAgcmV0dXJuIGxpc3QuaXRlcmF0b3IoKTsKICAgICAgICB9CiAgICAgICAgcHVibGljIGludCBzaXplKCkgewogICAgICAgIAlyZXR1cm4gbGlzdC5zaXplKCk7CiAgICAgICAgfQogICAgICAgIHB1YmxpYyBPYmplY3QgZ2V0KGludCBpbmRleCkgewogICAgICAgIAlyZXR1cm4gbGlzdC5nZXQoaW5kZXgpOwogICAgICAgIH0KICAgIH0KICAgIAogICAgRWxlbWVudENoYWluIHB1dERhdGEoRWxlbWVudENoYWluIHN0YWNrLCBTdHJpbmcgYXNzb2NpYXRlZERhdGEpIHsKICAgICAgICAKICAgICAgICAvL0lmIHRoZSBhc3NvY2lhdGVkIGRhdGEgaXMgIiIgYW5kIHdlIGhhdmUgYSBmaW5hbCBlbGVtZW50IGluIExFQUZOT0RFLAogICAgICAgIC8vdGhlbiBwdWxsIG9mZiB0aGUgbGFzdCBlbGVtZW50LCBhbmQgbWFrZSBpdCB0aGUgYXNzb2NpYXRlZCBkYXRhCiAgICAgICAgCiAgICAgICAgRWxlbWVudENoYWluIHJlc3VsdCA9IG5ldyBFbGVtZW50Q2hhaW4oc3RhY2spOwogICAgICAgIEVuZE5vZGUgdmFsdWUgPSBuZXcgRW5kTm9kZSgpOwogICAgICAgIHZhbHVlLnN0cmluZyA9IGFzc29jaWF0ZWREYXRhOwogICAgICAgIEVsZW1lbnQgbGFzdEVsZW1lbnQgPSByZXN1bHQuZ2V0TGFzdCgpOwogICAgICAgIGlmIChMRUFGTk9ERVMuY29udGFpbnMobGFzdEVsZW1lbnQuZWxlbWVudE5hbWUpKSB7CiAgICAgICAgICAgIGlmIChhc3NvY2lhdGVkRGF0YS5sZW5ndGgoKSAhPSAwKSB7CiAgICAgICAgICAgICAgICBTeXN0ZW0uZXJyLnByaW50bG4oIkxlYWYgTm9kZSBtdXN0IGJlIGVtcHR5OiAiICsgbGFzdEVsZW1lbnQgKyAiXHREYXRhOiAiICsgYXNzb2NpYXRlZERhdGEpOyAgICAgICAgICAgIAkKICAgICAgICAgICAgfQogICAgICAgICAgICB2YWx1ZS5hdHRyaWJ1dGVzID0gbGFzdEVsZW1lbnQuYXR0cmlidXRlczsKICAgICAgICAgICAgbGFzdEVsZW1lbnQuYXR0cmlidXRlcyA9IG5ldyBTaW1wbGVBdHRyaWJ1dGVzKCk7CiAgICAgICAgICAgIHZhbHVlLnN0cmluZyA9IG51bGw7CiAgICAgICAgfQogICAgICAgIGlmIChERUJVR19TSE9XX0FERCkgU3lzdGVtLm91dC5wcmludGxuKCJBZGRpbmc6ICIgKyByZXN1bHQgKyAiXHQiICsgdmFsdWUpOwogICAgICAgIEVuZE5vZGUgYWxyZWFkeVRoZXJlID0gKEVuZE5vZGUpIGRhdGEuZ2V0KHJlc3VsdCk7CiAgICAgICAgaWYgKGFscmVhZHlUaGVyZSAhPSBudWxsKSB7CiAgICAgICAgCVN5c3RlbS5lcnIucHJpbnRsbigiT3ZlcnJpZGluZzogIiArIHJlc3VsdCArICJcdE9sZCBWYWx1ZTogIiArIGFscmVhZHlUaGVyZSArICIsXHQgTmV3IFZhbHVlOiAiICsgdmFsdWUpOwogICAgICAgIH0KICAgICAgICBkYXRhLnB1dChyZXN1bHQsIHZhbHVlKTsgICAgICAKICAgICAgICByZXR1cm4gcmVzdWx0OwogICAgfQogICAgCiAgICAvL1N0cmluZyBzdGFydENvbW1lbnQ7CiAgICAKICAgIHN0YXRpYyBTaWRld2F5c1ZpZXcgc2lkZXdheXNWaWV3ID0gbmV3IFNpZGV3YXlzVmlldygpOwogICAgCiAgICBzdGF0aWMgY2xhc3MgRW5kTm9kZSB7CiAgICAJU3RyaW5nIHN0cmluZzsKICAgICAgICBTaW1wbGVBdHRyaWJ1dGVzIGF0dHJpYnV0ZXM7CgkJcHVibGljIHZvaWQgc2V0KE9iamVjdCBhc3NvY2lhdGVkRGF0YSkgewoJCQlpZiAoYXNzb2NpYXRlZERhdGEgaW5zdGFuY2VvZiBTdHJpbmcpIHsKCQkJCXN0cmluZyA9IChTdHJpbmcpIGFzc29jaWF0ZWREYXRhOwogICAgICAgICAgICAgICAgYXR0cmlidXRlcyA9IG51bGw7CiAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIAlhdHRyaWJ1dGVzID0gKFNpbXBsZUF0dHJpYnV0ZXMpIGFzc29jaWF0ZWREYXRhOwogICAgICAgICAgICAgICAgc3RyaW5nID0gbnVsbDsKICAgICAgICAgICAgfQkJCQoJCX0KICAgICAgICBwdWJsaWMgU3RyaW5nIHRvU3RyaW5nKCkgewogICAgICAgIAlyZXR1cm4gdG9TdHJpbmcoRWxlbWVudC5QQVRIKTsKICAgICAgICB9CiAgICAgICAgcHVibGljIFN0cmluZyB0b1N0cmluZyhpbnQgdHlwZSkgewogICAgICAgIAlpZiAoc3RyaW5nICE9IG51bGwpIHJldHVybiBCYWdGb3JtYXR0ZXIudG9IVE1MLnRyYW5zbGl0ZXJhdGUoc3RyaW5nKTsKICAgICAgICAgICAgcmV0dXJuIGF0dHJpYnV0ZXMudG9TdHJpbmcoKTsgLy8gVE8gRklYIHR5cGU9PUVsZW1lbnQuUEFUSAogICAgICAgIH0KICAgICAgICAvKgogICAgICAgIHB1YmxpYyBzdGF0aWMgU3RyaW5nIHNob3dWYWx1ZShPYmplY3QgdmFsdWUpIHsKICAgICAgICAgICAgaWYgKHZhbHVlIGluc3RhbmNlb2YgU3RyaW5nKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gQmFnRm9ybWF0dGVyLnRvSFRNTC50cmFuc2xpdGVyYXRlKChTdHJpbmcpdmFsdWUpOwogICAgICAgICAgICB9CiAgICAgICAgICAgIHJldHVybiAoKEVsZW1lbnQpdmFsdWUpLnRvU3RyaW5nKCk7CiAgICAgICAgfQogICAgICAgICovCiAgICAgICAgCgogICAgfQogICAgCiAgICBzdGF0aWMgY2xhc3MgRW5kTm9kZUNvbXBhcmF0b3IgaW1wbGVtZW50cyBDb21wYXJhdG9yIHsKCQlwdWJsaWMgaW50IGNvbXBhcmUoT2JqZWN0IG8xLCBPYmplY3QgbzIpIHsKICAgICAgICAgICAgRW5kTm9kZSB0aGVzZSA9IChFbmROb2RlKSBvMTsKICAgICAgICAgICAgICAgIEVuZE5vZGUgdGhhdCA9IChFbmROb2RlKSBvMjsKICAgICAgICAgICAgICAgIGlmICh0aGVzZS5zdHJpbmcgIT0gbnVsbCkgewogICAgICAgICAgICAgICAgICAgIGlmICh0aGF0LnN0cmluZyAhPSBudWxsKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBnZXREZWZhdWx0Q29sbGF0aW9uKCkuY29tcGFyZSh0aGVzZS5zdHJpbmcsIHRoYXQuc3RyaW5nKTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIC0xOwogICAgICAgICAgICAgICAgfSBlbHNlIGlmICh0aGF0LmF0dHJpYnV0ZXMgIT0gbnVsbCkgewogICAgICAgICAgICAgICAgICAgIHJldHVybiB0aGVzZS5hdHRyaWJ1dGVzLmNvbXBhcmVUbyh0aGF0LmF0dHJpYnV0ZXMpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgcmV0dXJuIDE7CiAgICAgICAgICAgIH0gICAgICAgCiAgICB9CiAgICAKICAgIHN0YXRpYyBjbGFzcyBTaWRld2F5c1ZpZXcgewogICAgICAgIEVuZE5vZGVDb21wYXJhdG9yIGVuYyA9IG5ldyBFbmROb2RlQ29tcGFyYXRvcigpOwogICAgICAgIE1hcCBjb250ZXh0Q2FjaGUgPSBuZXcgVHJlZU1hcCgpOwogICAgICAgIFNldCBmaWxlTmFtZXMgPSBuZXcgVHJlZVNldCgpOwogICAgICAgIFNldCBhbGxUeXBlcyA9IG5ldyBUcmVlU2V0KCk7CiAgICAgICAgCiAgICAgICAgdm9pZCBwdXREYXRhKE9yZGVyZWRNYXAgZGF0YSwgU3RyaW5nIGZpbGVuYW1lKSB7CiAgICAgICAgICAgIGZvciAoSXRlcmF0b3IgaXQgPSBkYXRhLml0ZXJhdG9yKCk7IGl0Lmhhc05leHQoKTspIHsKICAgICAgICAgICAgICAgIEVsZW1lbnRDaGFpbiBvcmlnaW5hbCA9IChFbGVtZW50Q2hhaW4pIGl0Lm5leHQoKTsKICAgICAgICAgICAgICAgIEVsZW1lbnRDaGFpbiBjb3B5ID0gb3JpZ2luYWwuY3JlYXRlUmVtb3ZpbmdBdHRyaWJ1dGVzKElHTk9SRUxJU1QpOwogICAgICAgICAgICAgICAgRW5kTm9kZSBlbmROb2RlID0gKEVuZE5vZGUpZGF0YS5nZXQoY29weSk7CiAgICAgICAgICAgICAgICBNYXAgZGF0YVRvRmlsZSA9IChNYXApY29udGV4dENhY2hlLmdldChjb3B5KTsKICAgICAgICAgICAgICAgIGlmIChkYXRhVG9GaWxlID09IG51bGwpIHsKICAgICAgICAgICAgICAgICAgICBkYXRhVG9GaWxlID0gbmV3IFRyZWVNYXAoZW5jKTsKICAgICAgICAgICAgICAgICAgICBjb250ZXh0Q2FjaGUucHV0KGNvcHksIGRhdGFUb0ZpbGUpOwogICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIC8vU3lzdGVtLm91dC5wcmludGxuKGNvcHkgKyAiXHRcdCIgKyBlbmROb2RlKTsKICAgICAgICAgICAgICAgIFNldCBmaWxlcyA9IChTZXQpIGRhdGFUb0ZpbGUuZ2V0KGVuZE5vZGUpOwogICAgICAgICAgICAgICAgaWYgKGZpbGVzID09IG51bGwpIHsKICAgICAgICAgICAgICAgICAgICBmaWxlcyA9IG5ldyBUcmVlU2V0KCk7CiAgICAgICAgICAgICAgICAgICAgZGF0YVRvRmlsZS5wdXQoZW5kTm9kZSwgZmlsZXMpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgZmlsZXMuYWRkKGZpbGVuYW1lKTsKICAgICAgICAgICAgfQogICAgICAgICAgICBpZiAoZmlsZW5hbWUuaW5kZXhPZignXycpIDwgMAogICAgICAgICAgICAgICAgfHwgZmlsZW5hbWUuZXF1YWxzKCJ6aF9IYW50IikpIGZpbGVOYW1lcy5hZGQoZmlsZW5hbWUpOyAvLyBhZGQgYWxsIGxhbmd1YWdlLW9ubHkgbG9jYWxlcwogICAgICAgIH0KIAogICAgICAgIGludCBnZXRDaGFpbkRlcHRoKEVsZW1lbnRDaGFpbiBlYykgewogICAgICAgICAgICBFbGVtZW50IGUgPSAoRWxlbWVudCllYy5jb250ZXh0cy5nZXQoMSk7CiAgICAgICAgICAgIFN0cmluZyByZXN1bHQgPSBlLmVsZW1lbnROYW1lOwogICAgICAgICAgICBpZiAocmVzdWx0LmVxdWFscygibnVtYmVycyIpIHx8IHJlc3VsdC5lcXVhbHMoImxvY2FsZURpc3BsYXlOYW1lcyIpIHx8IHJlc3VsdC5lcXVhbHMoImRhdGVzIikpIHsKICAgICAgICAgICAgICAgIHJldHVybiAzOwogICAgICAgICAgICB9CiAgICAgICAgICAgIHJldHVybiAyOwogICAgICAgIH0KCiAgICAgICAgU3RyaW5nIGdldENoYWluTmFtZShFbGVtZW50Q2hhaW4gZWMsIGludCBsaW1pdCkgewogICAgICAgIAlFbGVtZW50IGUgPSAoRWxlbWVudCllYy5jb250ZXh0cy5nZXQoMSk7CiAgICAgICAgICAgIFN0cmluZyByZXN1bHQgPSBlLmVsZW1lbnROYW1lOwogICAgICAgICAgICBmb3IgKGludCBpID0gMjsgaSA8IGxpbWl0OyArK2kpIHsKICAgICAgICAgICAgCWUgPSAoRWxlbWVudCllYy5jb250ZXh0cy5nZXQoaSk7CiAgICAgICAgICAgICAgICByZXN1bHQgKz0gIl8iICsgZS5lbGVtZW50TmFtZTsKICAgICAgICAgICAgfQogICAgICAgICAgICByZXR1cm4gcmVzdWx0OwogICAgICAgIH0KICAgICAgICAvKgogICAgICAgIFN0cmluZyBnZXRMYXN0RWxlbWVudHNUeXBlKEVsZW1lbnRDaGFpbiBlYykgewogICAgICAgICAgICAvL1RPRE8gbWFrZSBTaW1wbGVBdHRyaWJ1dGVzIGEgbWFwIGluc3RlYWQgb2YgYSBzZXQuCiAgICAgICAgICAgIEVsZW1lbnQgZSA9IChFbGVtZW50KWVjLmNvbnRleHRzLmdldChlYy5jb250ZXh0cy5zaXplKCktMSk7CiAgICAgICAgICAgIFNpbXBsZUF0dHJpYnV0ZXMgc2EgPSBlLmF0dHJpYnV0ZXM7CiAgICAgICAgICAgIGZvciAoSXRlcmF0b3IgaXQgPSBzYS5jb250ZW50cy5pdGVyYXRvcigpOyBpdC5oYXNOZXh0KCk7KSB7CiAgICAgICAgICAgIAlTaW1wbGVBdHRyaWJ1dGUgc2ExID0gKFNpbXBsZUF0dHJpYnV0ZSlpdC5uZXh0KCk7CiAgICAgICAgICAgICAgICBpZiAoc2ExLm5hbWUuZXF1YWxzKCJ0eXBlIikpIHJldHVybiBzYTEudmFsdWU7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgcmV0dXJuICIqTk9UX0ZPVU5EKiI7CiAgICAgICAgfQogICAgICAgICovCiAgICAgICAgdm9pZCBzaG93Q2FjaGVEYXRhKCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKICAgICAgICAgICAgd3JpdGVTdHlsZVNoZWV0KCk7CiAgICAgICAgICAgIFByaW50V3JpdGVyIG91dCA9IG51bGw7CiAgICAgICAgICAgIFN0cmluZyBsYXN0Q2hhaW5OYW1lID0gIiI7CiAgICAgICAgICAgIGludCBsaW5lQ291bnRlciA9IDE7CiAgICAgICAgICAgIGZvciAoSXRlcmF0b3IgaXQgPSBjb250ZXh0Q2FjaGUua2V5U2V0KCkuaXRlcmF0b3IoKTsgaXQuaGFzTmV4dCgpOykgewogICAgICAgICAgICAgICAgRWxlbWVudENoYWluIHN0YWNrID0gKEVsZW1lbnRDaGFpbikgaXQubmV4dCgpOwogICAgICAgICAgICAgICAgaW50IGxpbWl0ID0gZ2V0Q2hhaW5EZXB0aChzdGFjayk7CiAgICAgICAgICAgICAgICBTdHJpbmcgY2hhaW5OYW1lID0gZ2V0Q2hhaW5OYW1lKHN0YWNrLCBsaW1pdCk7CiAgICAgICAgICAgICAgICBpZiAoIWNoYWluTmFtZS5lcXVhbHMobGFzdENoYWluTmFtZSkpIHsKICAgICAgICAgICAgICAgICAgICBpZiAob3V0ICE9IG51bGwpIHsKICAgICAgICAgICAgICAgICAgICAgICAgb3V0LnByaW50bG4oIjwvdGFibGU+Iik7CiAgICAgICAgICAgICAgICAgICAgICAgIHdyaXRlRm9vdGVyQW5kQ2xvc2Uob3V0KTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgYWxsVHlwZXMuYWRkKGNoYWluTmFtZSk7IC8vIGFkZCB0byB0aGUgbGlzdAogICAgICAgICAgICAgICAgCW91dCA9IG9wZW5BbmREb0hlYWRlcihjaGFpbk5hbWUpOwogICAgICAgICAgICAgICAgICAgIGxhc3RDaGFpbk5hbWUgPSBjaGFpbk5hbWU7CiAgICAgICAgICAgICAgICAgICAgbGluZUNvdW50ZXIgPSAwOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgU3RyaW5nIGtleSA9IHN0YWNrLnRvU3RyaW5nKHRydWUsIGxpbWl0LCBJbnRlZ2VyLk1BWF9WQUxVRSk7CiAgICAgICAgICAgICAgICAvLyBzdHJpcCAgICAvbGRtbEB2ZXJzaW9uPSIxLjIiLzsKICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgbGluZUNvdW50ZXIrKzsKICAgICAgICAgICAgICAgIG91dC5wcmludGxuKCI8dHI+PHRkIGNvbHNwYW49JzInIGNsYXNzPSdoZWFkJz4iICsgCiAgICAgICAgICAgICAgICAgICAgICAgICI8YSBocmVmPScjIiArIGxpbmVDb3VudGVyICsgIicgbmFtZT0nIiArIGxpbmVDb3VudGVyICsgIic+IiAKICAgICAgICAgICAgICAgICAgICAgICAgKyBsaW5lQ291bnRlciArICI8L2E+Jm5ic3A7IiArIAogICAgICAgICAgICAgICAgICAgICAgICBCYWdGb3JtYXR0ZXIudG9IVE1MLnRyYW5zbGl0ZXJhdGUoa2V5KSArICI8L3RkPjwvdHI+Iik7CiAgICAgICAgICAgICAgICBNYXAgZGF0YVRvRmlsZSA9IChNYXApIGNvbnRleHRDYWNoZS5nZXQoc3RhY2spOwogICAgICAgICAgICAgICAgLy8gd2FsayB0aHJvdWdoIG9uY2UsIGFuZCBnYXRoZXIgYWxsIHRoZSBmaWxlbmFtZXMKICAgICAgICAgICAgICAgIFNldCByZW1haW5pbmdGaWxlcyA9IG5ldyBUcmVlU2V0KGZpbGVOYW1lcyk7CiAgICAgICAgICAgICAgICBmb3IgKEl0ZXJhdG9yIGl0MiA9IGRhdGFUb0ZpbGUua2V5U2V0KCkuaXRlcmF0b3IoKTsgaXQyLmhhc05leHQoKTspIHsKICAgICAgICAgICAgICAgICAgICBPYmplY3QgZGF0YSA9IGl0Mi5uZXh0KCk7CiAgICAgICAgICAgICAgICAgICAgcmVtYWluaW5nRmlsZXMucmVtb3ZlQWxsKChTZXQpIGRhdGFUb0ZpbGUuZ2V0KGRhdGEpKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIC8vIGhhY2sgZm9yIHpoX0hhbnQKICAgICAgICAgICAgICAgIGlmICghcmVtYWluaW5nRmlsZXMuY29udGFpbnMoInpoIikpIHJlbWFpbmluZ0ZpbGVzLnJlbW92ZSgiemhfSGFudCIpOwogICAgICAgICAgICAgICAgLy8gbm93IGRpc3BsYXkKICAgICAgICAgICAgICAgIGZvciAoSXRlcmF0b3IgaXQyID0gZGF0YVRvRmlsZS5rZXlTZXQoKS5pdGVyYXRvcigpOyBpdDIuaGFzTmV4dCgpOykgewogICAgICAgICAgICAgICAgICAgIEVuZE5vZGUgZGF0YSA9IChFbmROb2RlKSBpdDIubmV4dCgpOwogICAgICAgICAgICAgICAgICAgIFN0cmluZyBkYXRhU3R5bGUgPSAiIjsKICAgICAgICAgICAgICAgICAgICBTZXQgZmlsZXMgPSAoU2V0KSBkYXRhVG9GaWxlLmdldChkYXRhKTsKICAgICAgICAgICAgICAgICAgICBpZiAoZmlsZXMuY29udGFpbnMoInJvb3QiKSkgewogICAgICAgICAgICAgICAgICAgICAgICBmaWxlcy5hZGRBbGwocmVtYWluaW5nRmlsZXMpOwogICAgICAgICAgICAgICAgICAgICAgICBkYXRhU3R5bGUgPSAiIGNsYXNzPSdub2RhdGEnIjsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgb3V0LnByaW50KCI8dHI+PHRoIiArIGRhdGFTdHlsZSArIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgKGxpbmVDb3VudGVyID09IDEgPyAiIHdpZHRoPScyMCUnIiA6ICIiKQogICAgICAgICAgICAgICAgICAgICAgICAgICAgKyAiPlwiIiArIGRhdGEgKyAiXCI8L3RoPjx0ZD4iKTsKICAgICAgICAgICAgICAgICAgICBib29sZWFuIGZpcnN0ID0gdHJ1ZTsKICAgICAgICAgICAgICAgICAgICBmb3IgKEl0ZXJhdG9yIGl0MyA9IGZpbGVzLml0ZXJhdG9yKCk7IGl0My5oYXNOZXh0KCk7KSB7CiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChmaXJzdCkgZmlyc3QgPSBmYWxzZTsKICAgICAgICAgICAgICAgICAgICAgICAgZWxzZSBvdXQucHJpbnQoIiAiKTsKICAgICAgICAgICAgICAgICAgICAgICAgU3RyaW5nIGxvY2FsZUlEID0gKFN0cmluZylpdDMubmV4dCgpOwogICAgICAgICAgICAgICAgICAgICAgICBib29sZWFuIGVtcGhhc2l6ZSA9IGxvY2FsZUlELmVxdWFscygicm9vdCIpIHx8IGxvY2FsZUlELmluZGV4T2YoJ18nKSA+PSAwOwogICAgICAgICAgICAgICAgICAgICAgICBpZiAoZW1waGFzaXplKSBvdXQucHJpbnQoIjxiPiIpOwogICAgICAgICAgICAgICAgICAgICAgICBvdXQucHJpbnQoIlx1MDBCNyIgKyBsb2NhbGVJRCArICJcdTAwQjciKTsKICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGVtcGhhc2l6ZSkgb3V0LnByaW50KCI8L2I+Iik7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIG91dC5wcmludGxuKCI8L3RkPjwvdHI+Iik7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICAgICAgaWYob3V0PT1udWxsKSB7CiAgICAgICAgICAgICAgICBTeXN0ZW0uZXJyLnByaW50bG4oIk91dCA9IG51bGw/Iik7CiAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICBvdXQucHJpbnRsbigiPC90YWJsZT4iKTsKICAgICAgICAgICAgICAgIHdyaXRlRm9vdGVyQW5kQ2xvc2Uob3V0KTsKICAgICAgICAgICAgICAgIG91dC5jbG9zZSgpOwogICAgICAgICAgICB9CiAgICAgICAgICAgIHdyaXRlSW5kZXgoKTsKICAgICAgICAgICAgdHJpcGxlRGF0YS53cml0ZURhdGEoKTsKICAgICAgICB9CgoJCS8qKgoJCSAqIEBwYXJhbSB0eXBlCgkJICogQHJldHVybgoJCSAqIEB0aHJvd3MgSU9FeGNlcHRpb24KCQkgKi8KCQlwcml2YXRlIFByaW50V3JpdGVyIG9wZW5BbmREb0hlYWRlcihTdHJpbmcgdHlwZSkgdGhyb3dzIElPRXhjZXB0aW9uIHsKICAgICAgICAgICAgU3RyaW5nIGZpbGVOYW1lID0gdHlwZSArICIuaHRtbCI7CgkJCVByaW50V3JpdGVyIG91dCA9IEJhZ0Zvcm1hdHRlci5vcGVuVVRGOFdyaXRlcihvcHRpb25zW0RFU1RESVJdLnZhbHVlLCAiYnlfdHlwZSIgKyBGaWxlLnNlcGFyYXRvciArIGZpbGVOYW1lKTsKICAgICAgICAgICAgb3V0LnByaW50bG4oIjxodG1sPjxoZWFkPiIpOwogICAgICAgICAgICBvdXQucHJpbnRsbigiPG1ldGEgaHR0cC1lcXVpdj0nQ29udGVudC1UeXBlJyBjb250ZW50PSd0ZXh0L2h0bWw7IGNoYXJzZXQ9dXRmLTgnPiIpOwoJCQlvdXQucHJpbnRsbigiPHRpdGxlPkNvbXBhcmlzb24gQnkgVHlwZTogIiArIEJhZ0Zvcm1hdHRlci50b0hUTUwudHJhbnNsaXRlcmF0ZSh0eXBlKSArICI8L3RpdGxlPiIpOwogICAgICAgICAgICBvdXQucHJpbnRsbigiPGxpbmsgcmVsPSdzdHlsZXNoZWV0JyB0eXBlPSd0ZXh0L2NzcycgaHJlZj0naHR0cDovL29zcy5zb2Z0d2FyZS5pYm0uY29tL2N2cy9pY3UvfmNoZWNrb3V0fi9pY3VodG1sL2NvbW1vbi5jc3MnPiIpOwogICAgICAgICAgICBvdXQucHJpbnRsbigiPGxpbmsgcmVsPSdzdHlsZXNoZWV0JyB0eXBlPSd0ZXh0L2NzcycgaHJlZj0nYnlfdHlwZS5jc3MnPiIpOwoJCQlvdXQucHJpbnRsbigiPC9oZWFkPiIpOwogICAgICAgICAgICBvdXQucHJpbnRsbigiPGJvZHk+Iik7CiAgICAgICAgICAgIG91dC5wcmludGxuKCI8aDI+QnktVHlwZSBDaGFydCBmb3IgIiArICIvL2xkbWwvIiArIHR5cGUucmVwbGFjZSgnXycsICcvJykgKyAiLy4uLjwvaDE+Iik7CiAgICAgICAgICAgIG91dC5wcmludGxuKCI8cD4iICsKICAgICAgICAgICAgICAgICAgICAiPGEgaHJlZj1cImluZGV4Lmh0bWxcIj5CeS1UeXBlIENoYXJ0IEluZGV4PC9hPiAiICsKICAgICAgICAgICAgICAgICAgICAifCA8YSBocmVmPSdodHRwOi8vd3d3Lmp0Y3N2LmNvbS9jZ2liaW4vY2xkcndpa2kucGw/SW50ZXJpbVZldHRpbmdDaGFydHMnPkludGVyaW0gVmV0dGluZyBDaGFydHM8L2E+IiArCiAgICAgICAgICAgICAgICAgICAgInwgPGEgaHJlZj0naHR0cDovL29zcy5zb2Z0d2FyZS5pYm0uY29tL2N2cy9pY3UvfmNoZWNrb3V0fi9sb2NhbGUvZG9jcy90cjM1Lmh0bWwnPkxETUwgU3BlY2lmaWNhdGlvbjwvYT4iICsKICAgICAgICAgICAgICAgICAgICAifCA8YSBocmVmPSdodHRwOi8vd3d3LnVuaWNvZGUub3JnL2NsZHIvZmlsaW5nX2J1Z19yZXBvcnRzLmh0bWwnPkZpbGluZyBCdWcgUmVwb3J0czwvYT4iICsKICAgICAgICAgICAgICAgICAgICAifCA8YSBocmVmPSdodHRwOi8vb3NzLnNvZnR3YXJlLmlibS5jb20vY3ZzL2ljdS9+Y2hlY2tvdXR+L2xvY2FsZS9jb21wYXJpc29uX2NoYXJ0cy5odG1sJz5Dcm9zcyBQbGF0Zm9ybSBDaGFydHM8L2E+IiArICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgIjwvcD4iKTsKICAgICAgICAgICAgb3V0LnByaW50bG4oIjxwPlRoaXMgY2hhcnQgc2hvd3MgdmFsdWVzIGFjcm9zcyBsb2NhbGVzIGZvciBkaWZmZXJlbnQgZmllbGRzLiAiICsKICAgICAgICAgICAgICAgICAgICAiRWFjaCB2YWx1ZSBpcyBsaXN0ZWQgdW5kZXIgdGhlIGZpZWxkIGRlc2lnbmF0b3IgKGluIFhNTCBYUGF0aCBmb3JtYXQpLCAiICsKICAgICAgICAgICAgICAgICAgICAiZm9sbG93ZWQgYnkgYWxsIHRoZSBsb2NhbGVzIHRoYXQgdXNlIGl0LiAiICsKICAgICAgICAgICAgICAgICAgICAiTG9jYWxlcyBhcmUgb21pdHRlZCBpZiB0aGUgdmFsdWUgd291bGQgYmUgdGhlIHNhbWUgYXMgdGhlIHBhcmVudCdzLiAiICsKICAgICAgICAgICAgICAgICAgICAiVGhlIGxvY2FsZXMgYXJlIGxpc3RlZCBpbiB0aGUgZm9ybWF0OiC3YWG3IGZvciBzZWFyY2hpbmcuICIgKwogICAgICAgICAgICAgICAgICAgICJUaGUgdmFsdWUgYXBwZWFycyBpbiByZWQgaWYgaXQgaXMgdGhlIHNhbWUgYXMgdGhlIHJvb3QuIDwvcD4iKTsgICAgICAgICAgICAgCiAgICAgICAgICAgIG91dC5wcmludGxuKCI8dGFibGU+Iik7CgkJCXJldHVybiBvdXQ7CgkJfQogICAgICAgIHByaXZhdGUgdm9pZCB3cml0ZVN0eWxlU2hlZXQoKSB0aHJvd3MgSU9FeGNlcHRpb24gewogICAgICAgICAgICBQcmludFdyaXRlciBvdXQgPSBCYWdGb3JtYXR0ZXIub3BlblVURjhXcml0ZXIob3B0aW9uc1tERVNURElSXS52YWx1ZSwgImJ5X3R5cGUiICsgRmlsZS5zZXBhcmF0b3IgKyAiYnlfdHlwZS5jc3MiKTsKICAgICAgICAgICAgb3V0LnByaW50bG4oIi5oZWFkIHsgZm9udC13ZWlnaHQ6Ym9sZDsgYmFja2dyb3VuZC1jb2xvcjojREREREZGIH0iKTsKICAgICAgICAgICAgb3V0LnByaW50bG4oInRkLCB0aCB7IGJvcmRlcjogMXB4IHNvbGlkICMwMDAwRkY7IHRleHQtYWxpZ24gfSIpOwogICAgICAgICAgICBvdXQucHJpbnRsbigidGggeyB3aWR0aDoxMCUgfSIpOwogICAgICAgICAgICBvdXQucHJpbnRsbigiLm5vZGF0YSB7IGJhY2tncm91bmQtY29sb3I6I0ZGMDAwMCB9Iik7CiAgICAgICAgICAgIG91dC5wcmludGxuKCJ0YWJsZSB7bWFyZ2luLXRvcDogMWVtfSIpOwogICAgICAgICAgICBvdXQuY2xvc2UoKTsKICAgICAgICB9CiAgICAgICAgCiAgICAgICAgcHJpdmF0ZSB2b2lkIHdyaXRlSW5kZXgoKSB0aHJvd3MgSU9FeGNlcHRpb24gewogICAgICAgICAgICBTdHJpbmcgZmlsZU5hbWUgPSAiaW5kZXgiICsgIi5odG1sIjsKCQkJUHJpbnRXcml0ZXIgb3V0ID0gQmFnRm9ybWF0dGVyLm9wZW5VVEY4V3JpdGVyKG9wdGlvbnNbREVTVERJUl0udmFsdWUsICJieV90eXBlIiArIEZpbGUuc2VwYXJhdG9yICsgZmlsZU5hbWUpOwogICAgICAgICAgICBvdXQucHJpbnRsbigiPGh0bWw+PGhlYWQ+Iik7CiAgICAgICAgICAgIG91dC5wcmludGxuKCI8bWV0YSBodHRwLWVxdWl2PSdDb250ZW50LVR5cGUnIGNvbnRlbnQ9J3RleHQvaHRtbDsgY2hhcnNldD11dGYtOCc+Iik7CgkJCW91dC5wcmludGxuKCI8dGl0bGU+Q29tcGFyaXNvbiBCeSBUeXBlOiAiICsgImluZGV4IiArICI8L3RpdGxlPiIpOwogICAgICAgICAgICBvdXQucHJpbnRsbigiPGxpbmsgcmVsPSdzdHlsZXNoZWV0JyB0eXBlPSd0ZXh0L2NzcycgaHJlZj0naHR0cDovL29zcy5zb2Z0d2FyZS5pYm0uY29tL2N2cy9pY3UvfmNoZWNrb3V0fi9pY3VodG1sL2NvbW1vbi5jc3MnPiIpOwogICAgICAgICAgICBvdXQucHJpbnRsbigiPGxpbmsgcmVsPSdzdHlsZXNoZWV0JyB0eXBlPSd0ZXh0L2NzcycgaHJlZj0nYnlfdHlwZS5jc3MnPiIpOwoJCQlvdXQucHJpbnRsbigiPC9oZWFkPiIpOwogICAgICAgICAgICBvdXQucHJpbnRsbigiPGJvZHk+PGgxPkJ5IFR5cGUgQ2hhcnQgSW5kZXg8L2gxPiIpOwogICAgICAgICAgICBvdXQucHJpbnRsbigiPHA+VGhlIGZvbGxvd2luZyBhcmUgY2hhcnRzIGZvciB0aGUgaW5kaXZpZHVhbCBkYXRhdHlwZXMsICIgKwogICAgICAgICAgICAgICAgICAgICJ0aGF0IHNob3cgYSBjb21wYXJpc29uIGFjcm9zcyBsb2NhbGVzIGZvciBkaWZmZXJlbnQgZmllbGRzLiAiICsKICAgICAgICAgICAgICAgICAgICAiRm9yIGV4YW1wbGUsIGluIHRoZSBvcmllbnRhdGlvbiBjaGFydCwgb25lIGNhbiBzZWUgdGhhdCBhbGwgbG9jYWxlcyAiICsKICAgICAgICAgICAgICAgICAgICAiYXJlIGxlZnQtdG8tcmlnaHQgZXhjZXB0ILdhcrcgt2ZhtyC3aGW3ILdwc7cgKGFuZCB0aGVpciBjaGlsZHJlbikuPC9wPiIgKwogICAgICAgICAgICAgICAgICAgICI8cD5Ob3RlOiB0aGVzZSBjaGFydHMgZG8gbm90IHlldCBpbmNsdWRlIGNvbGxhdGlvbnM8L3A+Iik7ICAgICAgICAgICAgIAogICAgICAgICAgICBvdXQucHJpbnRsbigiPHVsPiIpOwogICAgICAgICAgICBmb3IoSXRlcmF0b3IgZSA9IGFsbFR5cGVzLml0ZXJhdG9yKCk7ZS5oYXNOZXh0KCk7KSB7CiAgICAgICAgICAgICAgICBTdHJpbmcgZiA9IChTdHJpbmcpZS5uZXh0KCk7CiAgICAgICAgICAgICAgICBvdXQucHJpbnRsbigiIDxsaT48YSBocmVmPVwiIiArIGYgKyAiLmh0bWwiICsgICJcIj4iICsgZiArICI8L2E+Iik7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgb3V0LnByaW50bG4oIjwvdWw+Iik7CiAgICAgICAgICAgIG91dC5wcmludGxuKCI8YSBocmVmPSdodHRwOi8vd3d3Lmp0Y3N2LmNvbS9jZ2liaW4vY2xkcndpa2kucGw/QnlUeXBlJz5BYm91dCB0aGlzIGNoYXJ0PC9hPiA8YnIvPiIpOwogICAgICAgICAgICB3cml0ZUZvb3RlckFuZENsb3NlKG91dCk7CiAgICAgICAgfQogICAgfQogICAgCiAgICBjbGFzcyBNeURlY2xIYW5kbGVyIGltcGxlbWVudHMgRGVjbEhhbmRsZXIgewogICAgICAgIE1hcCBlbGVtZW50X2NoaWxkQ29tcGFyYXRvciA9IG5ldyBUcmVlTWFwKCk7CiAgICAgICAgYm9vbGVhbiBzaG93UmVhc29uID0gZmFsc2U7CiAgICAgICAgU2V0IFNLSVBfTElTVCA9IG5ldyBIYXNoU2V0KEFycmF5cy5hc0xpc3QobmV3IFN0cmluZ1tdIHsKICAgICAgICAJCSJjb2xsYXRpb24iLCAiYmFzZSIsICJzZXR0aW5ncyIsICJzdXBwcmVzc19jb250cmFjdGlvbnMiLCAib3B0aW1pemUiLCAicnVsZXMiLCAicmVzZXQiLAogICAgICAgICAgICAgICAgImNvbnRleHQiLCAicCIsICJwYyIsICJzIiwgInNjIiwgInQiLCAidGMiLCAicSIsICJxYyIsICJpIiwgImljIiwgImV4dGVuZCIsICJ4IgogICAgICAgIH0pKTsKICAgICAgICBPYmplY3QgRE9ORSA9IG5ldyBPYmplY3QoKTsgLy8gbWFya2VyCiAgICAgICAgCiAgICAgICAgcHVibGljIHZvaWQgY2hlY2tEYXRhKCkgewogICAgICAgIAkvLyB2ZXJpZnkgdGhhdCB0aGUgb3JkZXJpbmcgaXMgdGhlIGNvbnNpc3RlbnQgZm9yIGFsbCBjaGlsZCBlbGVtZW50cwogICAgICAgICAgICAvLyBkbyB0aGlzIGJ5IGJ1aWxkaW5nIGFuIG9yZGVyaW5nIGZyb20gdGhlIGxpc3RzLgogICAgICAgICAgICAvLyBUaGUgZmlyc3QgaXRlbSBoYXMgbm8gZ3JlYXRlciBpdGVtIGluIGFueSBzZXQuIFNvIGZpbmQgYW4gaXRlbSB0aGF0IGlzIG9ubHkgZmlyc3QKICAgICAgICAgICAgc2hvd1JlYXNvbiA9IGZhbHNlOwogICAgICAgICAgICBMaXN0IG9yZGVyaW5nTGlzdCA9IG5ldyBBcnJheUxpc3QoKTsKICAgICAgICAgICAgd2hpbGUgKHRydWUpIHsKICAgICAgICAgICAgICAgIE9iamVjdCBmaXJzdCA9IGdldEZpcnN0KG9yZGVyaW5nTGlzdCk7CiAgICAgICAgICAgICAgICBpZiAoZmlyc3QgPT0gRE9ORSkgewogICAgICAgICAgICAgICAgICAgIGxvZy5wcmludGxuKCJTdWNjZXNzZnVsIE9yZGVyaW5nIik7CiAgICAgICAgICAgICAgICAgICAgaW50IGNvdW50ID0gMDsKICAgICAgICAgICAgICAgICAgICBmb3IgKEl0ZXJhdG9yIGl0ID0gb3JkZXJpbmdMaXN0Lml0ZXJhdG9yKCk7IGl0Lmhhc05leHQoKTspIGxvZy5wcmludGxuKCsrY291bnQgKyBpdC5uZXh0KCkudG9TdHJpbmcoKSk7IAogICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgaWYgKGZpcnN0ICE9IG51bGwpIHsgCiAgICAgICAgICAgICAgICAgICAgb3JkZXJpbmdMaXN0LmFkZChmaXJzdCk7CiAgICAgICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgICAgIHNob3dSZWFzb24gPSB0cnVlOwogICAgICAgICAgICAgICAgICAgIGdldEZpcnN0KG9yZGVyaW5nTGlzdCk7CiAgICAgICAgICAgICAgICAgICAgbG9nLnByaW50bG4oKTsKICAgICAgICAgICAgICAgICAgICBsb2cucHJpbnRsbigiRmFpbGVkIG9yZGVyaW5nLiBTbyBmYXI6Iik7CiAgICAgICAgICAgICAgICAgICAgZm9yIChJdGVyYXRvciBpdCA9IG9yZGVyaW5nTGlzdC5pdGVyYXRvcigpOyBpdC5oYXNOZXh0KCk7KSBsb2cucHJpbnQoIlx0IiArIGl0Lm5leHQoKSk7CiAgICAgICAgICAgICAgICAgICAgbG9nLnByaW50bG4oKTsKICAgICAgICAgICAgICAgICAgICBsb2cucHJpbnRsbigiSXRlbXM6Iik7CiAgICAgICAgICAgICAgICAgICAgZm9yIChJdGVyYXRvciBpdCA9ICBlbGVtZW50X2NoaWxkQ29tcGFyYXRvci5rZXlTZXQoKS5pdGVyYXRvcigpOyBpdC5oYXNOZXh0KCk7KSBzaG93Um93KGl0Lm5leHQoKSwgdHJ1ZSk7CiAgICAgICAgICAgICAgICAgICAgbG9nLnByaW50bG4oKTsKICAgICAgICAgICAgICAgIAlicmVhazsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgIH0KICAgICAgICAKICAgICAgICAvKioKCQkgKiBAcGFyYW0gcGFyZW50CiAgICAgICAgICogQHBhcmFtIHNraXBFbXB0eSBUT0RPCgkJICovCgkJcHJpdmF0ZSB2b2lkIHNob3dSb3coT2JqZWN0IHBhcmVudCwgYm9vbGVhbiBza2lwRW1wdHkpIHsKCQkJTGlzdCBpdGVtcyA9IChMaXN0KSBlbGVtZW50X2NoaWxkQ29tcGFyYXRvci5nZXQocGFyZW50KTsKICAgICAgICAgICAgaWYgKHNraXBFbXB0eSAmJiBpdGVtcy5zaXplKCkgPT0gMCkgcmV0dXJuOwogICAgICAgICAgICBsb2cucHJpbnQocGFyZW50KTsKCQkJZm9yIChJdGVyYXRvciBpdDIgPSBpdGVtcy5pdGVyYXRvcigpOyBpdDIuaGFzTmV4dCgpOykgbG9nLnByaW50KCJcdCIgKyBpdDIubmV4dCgpKTsKCQkJbG9nLnByaW50bG4oKTsKCQl9CgoJCS8qKgoJCSAqIEBwYXJhbSBvcmRlcmluZ0xpc3QKCQkgKi8KCQlwcml2YXRlIE9iamVjdCBnZXRGaXJzdChMaXN0IG9yZGVyaW5nTGlzdCkgewoJCQlTZXQga2V5cyA9IGVsZW1lbnRfY2hpbGRDb21wYXJhdG9yLmtleVNldCgpOwogICAgICAgICAgICBTZXQgZmFpbHVyZXMgPSBuZXcgSGFzaFNldCgpOwogICAgICAgICAgICBib29sZWFuIGFsbFplcm8gPSB0cnVlOwogICAgICAgICAgICBmb3IgKEl0ZXJhdG9yIGl0ID0ga2V5cy5pdGVyYXRvcigpOyBpdC5oYXNOZXh0KCk7KSB7CiAgICAgICAgICAgICAgICBMaXN0IGxpc3QgPSAoTGlzdCkgZWxlbWVudF9jaGlsZENvbXBhcmF0b3IuZ2V0KGl0Lm5leHQoKSk7CiAgICAgICAgICAgICAgICBpZiAobGlzdC5zaXplKCkgIT0gMCkgewogICAgICAgICAgICAgICAgICAgIGFsbFplcm8gPSBmYWxzZTsKICAgICAgICAgICAgICAgIAlPYmplY3QgcG9zc2libGVGaXJzdCA9IGxpc3QuZ2V0KDApOwogICAgICAgICAgICAgICAgICAgIGlmICghZmFpbHVyZXMuY29udGFpbnMocG9zc2libGVGaXJzdCkgJiYgaXNBbHdheXNGaXJzdChwb3NzaWJsZUZpcnN0KSkgewogICAgICAgICAgICAgICAgICAgICAgICAvLyB3ZSBzdXJ2aXZlZCB0aGUgZ3VhbnRsZXQuIGFkZCB0byBvcmRlcmluZyBsaXN0LCByZW1vdmUgZnJvbSB0aGUgbWFwcGluZ3MgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICByZW1vdmVFdmVyeXdoZXJlKHBvc3NpYmxlRmlyc3QpOwogICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gcG9zc2libGVGaXJzdDsKICAgICAgICAgICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgICAgIAlmYWlsdXJlcy5hZGQocG9zc2libGVGaXJzdCk7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgICAgIGlmIChhbGxaZXJvKSByZXR1cm4gRE9ORTsKICAgICAgICAgICAgcmV0dXJuIG51bGw7CgkJfQogICAgICAgIC8qKgoJCSAqIEBwYXJhbSBrZXlzCgkJICogQHBhcmFtIGl0CgkJICogQHBhcmFtIHBvc3NpYmxlRmlyc3QKCQkgKi8KCQlwcml2YXRlIHZvaWQgcmVtb3ZlRXZlcnl3aGVyZShPYmplY3QgcG9zc2libGVGaXJzdCkgewoJCQkvLyBhbmQgcmVtb3ZlIGZyb20gYWxsIHRoZSBsaXN0cwoJCQlmb3IgKEl0ZXJhdG9yIGl0MiA9IGVsZW1lbnRfY2hpbGRDb21wYXJhdG9yLmtleVNldCgpLml0ZXJhdG9yKCk7IGl0Mi5oYXNOZXh0KCk7KSB7CgkJCSAgICBMaXN0IGxpc3QyID0gKExpc3QpIGVsZW1lbnRfY2hpbGRDb21wYXJhdG9yLmdldChpdDIubmV4dCgpKTsKCQkJICAgIGxpc3QyLnJlbW92ZShwb3NzaWJsZUZpcnN0KTsKCQkJfQoJCX0KCgkJcHJpdmF0ZSBib29sZWFuIGlzQWx3YXlzRmlyc3QoT2JqZWN0IHBvc3NpYmxlRmlyc3QpIHsKICAgICAgICAgICAgaWYgKHNob3dSZWFzb24pIGxvZy5wcmludGxuKCJUcnlpbmc6ICIgKyBwb3NzaWJsZUZpcnN0KTsKICAgICAgICAgICAgZm9yIChJdGVyYXRvciBpdDIgPSBlbGVtZW50X2NoaWxkQ29tcGFyYXRvci5rZXlTZXQoKS5pdGVyYXRvcigpOyBpdDIuaGFzTmV4dCgpOykgewogICAgICAgICAgICAgICAgT2JqZWN0IGtleSA9IGl0Mi5uZXh0KCk7CiAgICAgICAgICAgICAgICBMaXN0IGxpc3QyID0gKExpc3QpIGVsZW1lbnRfY2hpbGRDb21wYXJhdG9yLmdldChrZXkpOwogICAgICAgICAgICAgICAgaW50IHBvcyA9IGxpc3QyLmluZGV4T2YocG9zc2libGVGaXJzdCk7CiAgICAgICAgICAgICAgICBpZiAocG9zID4gMCkgewogICAgICAgICAgICAgICAgICAgIGlmIChzaG93UmVhc29uKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIGxvZy5wcmludCgiRmFpbGVkIGF0Olx0Iik7CiAgICAgICAgICAgICAgICAgICAgICAgIHNob3dSb3coa2V5LCBmYWxzZSk7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgICAgICByZXR1cm4gdHJ1ZTsKICAgICAgICB9CgoJCS8vIHJlZmluZSBsYXRlcjsgcmlnaHQgbm93LCBkb2Vzbid0IGhhbmRsZSBtdWx0aXBsZSBlbGVtZW50cyB3ZWxsLgoJCXB1YmxpYyB2b2lkIGVsZW1lbnREZWNsKFN0cmluZyBuYW1lLCBTdHJpbmcgbW9kZWwpIHRocm93cyBTQVhFeGNlcHRpb24gewogICAgICAgICAgICBpZiAoU0tJUF9MSVNULmNvbnRhaW5zKG5hbWUpKSByZXR1cm47CgkJCS8vbG9nLnByaW50bG4oIkVsZW1lbnRcdCIgKyBuYW1lICsgIlx0IiArIG1vZGVsKTsKICAgICAgICAgICAgU3RyaW5nW10gbGlzdCA9IG1vZGVsLnNwbGl0KCJbXkEtWjAtOWEtel0iKTsKICAgICAgICAgICAgTGlzdCBtYyA9IG5ldyBBcnJheUxpc3QoKTsKICAgICAgICAgICAgaWYgKG5hbWUuZXF1YWxzKCJjdXJyZW5jeSIpKSB7CiAgICAgICAgICAgICAgICBtYy5hZGQoImFsaWFzIik7CiAgICAgICAgICAgICAgICBtYy5hZGQoInN5bWJvbCIpOwogICAgICAgICAgICAgICAgbWMuYWRkKCJwYXR0ZXJuIik7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBsaXN0Lmxlbmd0aDsgKytpKSB7CiAgICAgICAgICAgICAgICBpZiAobGlzdFtpXS5sZW5ndGgoKSA9PSAwKSBjb250aW51ZTsKICAgICAgICAgICAgCS8vbG9nLnByaW50KCJcdCIgKyBsaXN0W2ldKTsKICAgICAgICAgICAgICAgIGlmIChtYy5jb250YWlucyhsaXN0W2ldKSkgewogICAgICAgICAgICAgICAgICAgIGxvZy5wcmludGxuKCJEdXBsaWNhdGUgYXR0cmlidXRlICIgKyBuYW1lICsgIiwgIiArIGxpc3RbaV0pOwogICAgICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICAgICBtYy5hZGQobGlzdFtpXSk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICAgICAgZWxlbWVudF9jaGlsZENvbXBhcmF0b3IucHV0KG5hbWUsIG1jKTsKICAgICAgICAgICAgLy9sb2cucHJpbnRsbigpOwoJCX0KCQlwdWJsaWMgdm9pZCBhdHRyaWJ1dGVEZWNsKFN0cmluZyBlTmFtZSwgU3RyaW5nIGFOYW1lLCBTdHJpbmcgdHlwZSwgU3RyaW5nIG1vZGUsIFN0cmluZyB2YWx1ZSkgdGhyb3dzIFNBWEV4Y2VwdGlvbiB7CiAgICAgICAgICAgIC8vbG9nLnByaW50bG4oIkF0dHJpYnV0ZVx0IiArIGVOYW1lICsgIlx0IiArIGFOYW1lICsgIlx0IiArIHR5cGUgKyAiXHQiICsgbW9kZSArICJcdCIgKyB2YWx1ZSk7ICAgICAgICAgCgkJfQoJCXB1YmxpYyB2b2lkIGludGVybmFsRW50aXR5RGVjbChTdHJpbmcgbmFtZSwgU3RyaW5nIHZhbHVlKSB0aHJvd3MgU0FYRXhjZXB0aW9uIHsKICAgICAgICAgICAgLy9sb2cucHJpbnRsbigiSW50ZXJuYWwgRW50aXR5XHQiICsgbmFtZSArICJcdCIgKyB2YWx1ZSk7ICAgCgkJfQoJCXB1YmxpYyB2b2lkIGV4dGVybmFsRW50aXR5RGVjbChTdHJpbmcgbmFtZSwgU3RyaW5nIHB1YmxpY0lkLCBTdHJpbmcgc3lzdGVtSWQpIHRocm93cyBTQVhFeGNlcHRpb24gewogICAgICAgICAgICAvL2xvZy5wcmludGxuKCJJbnRlcm5hbCBFbnRpdHlcdCIgKyBuYW1lICsgIlx0IiArIHB1YmxpY0lkICsgIlx0IiArIHN5c3RlbUlkKTsgICAKCQl9CiAgIAogICAgfQogICAgCiAgICBjbGFzcyBNeUNvbnRlbnRIYW5kbGVyIGltcGxlbWVudHMgQ29udGVudEhhbmRsZXIsIExleGljYWxIYW5kbGVyIHsKICAgICAgICAKICAgICAgICBFbGVtZW50Q2hhaW4gY29udGV4dFN0YWNrID0gbmV3IEVsZW1lbnRDaGFpbigpOwogICAgICAgIFN0cmluZyBsYXN0Q2hhcnMgPSAiIjsKICAgICAgICBib29sZWFuIGp1c3RQb3BwZWQgPSBmYWxzZTsKICAgICAgICBpbnQgY29tbWVudFN0YWNrID0gMDsKICAgICAgICAKICAgICAgICBwdWJsaWMgdm9pZCBzdGFydEVsZW1lbnQoCiAgICAgICAgICAgIFN0cmluZyB1cmksCiAgICAgICAgICAgIFN0cmluZyBsb2NhbE5hbWUsCiAgICAgICAgICAgIFN0cmluZyBxTmFtZSwKICAgICAgICAgICAgQXR0cmlidXRlcyBhdHRyaWJ1dGVzKQogICAgICAgICAgICB0aHJvd3MgU0FYRXhjZXB0aW9uIHsKICAgICAgICAgICAgICAgIC8vZGF0YS5wdXQobmV3IENvbnRleHRTdGFjayhjb250ZXh0U3RhY2spLCBsYXN0Q2hhcnMpOwogICAgICAgICAgICAgICAgLy9sYXN0Q2hhcnMgPSAiIjsKICAgICAgICAgICAgICAgIHRyeSB7CiAgICAgICAgICAgICAgICAgICAgY29udGV4dFN0YWNrLnB1c2gocU5hbWUsIGF0dHJpYnV0ZXMsIGZpbmFsQ29tbWVudCk7CiAgICAgICAgICAgICAgICAgICAgZmluYWxDb21tZW50ID0gbnVsbDsKICAgICAgICAgICAgICAgICAgICBpZiAoREVCVUcpIFN5c3RlbS5vdXQucHJpbnRsbigic3RhcnRFbGVtZW50Olx0IiArIGNvbnRleHRTdGFjayk7CiAgICAgICAgICAgICAgICAgICAganVzdFBvcHBlZCA9IGZhbHNlOwogICAgICAgICAgICAgICAgfSBjYXRjaCAoUnVudGltZUV4Y2VwdGlvbiBlKSB7CiAgICAgICAgICAgICAgICAgICAgZS5wcmludFN0YWNrVHJhY2UoKTsKICAgICAgICAgICAgICAgICAgICB0aHJvdyBlOwogICAgICAgICAgICAgICAgfQogICAgICAgIH0KICAgICAgICBwdWJsaWMgdm9pZCBlbmRFbGVtZW50KFN0cmluZyB1cmksIFN0cmluZyBsb2NhbE5hbWUsIFN0cmluZyBxTmFtZSkKICAgICAgICAgICAgdGhyb3dzIFNBWEV4Y2VwdGlvbiB7CiAgICAgICAgICAgICAgICB0cnkgewogICAgICAgICAgICAgICAgICAgIGlmIChERUJVRykgU3lzdGVtLm91dC5wcmludGxuKCJlbmRFbGVtZW50Olx0IiArIGNvbnRleHRTdGFjayk7CiAgICAgICAgICAgICAgICAgICAgaWYgKGxhc3RDaGFycy5sZW5ndGgoKSAhPSAwIHx8IGp1c3RQb3BwZWQgPT0gZmFsc2UpIHsKICAgICAgICAgICAgICAgICAgICAgICAgcHV0RGF0YShjb250ZXh0U3RhY2ssIGxhc3RDaGFycyk7CiAgICAgICAgICAgICAgICAgICAgICAgIGxhc3RDaGFycyA9ICIiOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICBjb250ZXh0U3RhY2sucG9wKHFOYW1lKTsKICAgICAgICAgICAgICAgICAgICBqdXN0UG9wcGVkID0gdHJ1ZTsKICAgICAgICAgICAgICAgIH0gY2F0Y2ggKFJ1bnRpbWVFeGNlcHRpb24gZSkgewogICAgICAgICAgICAgICAgICAgIGUucHJpbnRTdGFja1RyYWNlKCk7CiAgICAgICAgICAgICAgICAgICAgdGhyb3cgZTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgIHB1YmxpYyB2b2lkIGNoYXJhY3RlcnMoY2hhcltdIGNoLCBpbnQgc3RhcnQsIGludCBsZW5ndGgpCiAgICAgICAgICAgIHRocm93cyBTQVhFeGNlcHRpb24gewogICAgICAgICAgICAgICAgdHJ5IHsKICAgICAgICAgICAgICAgICAgICBTdHJpbmcgdmFsdWUgPSBuZXcgU3RyaW5nKGNoLHN0YXJ0LGxlbmd0aCk7CiAgICAgICAgICAgICAgICAgICAgaWYgKERFQlVHKSBTeXN0ZW0ub3V0LnByaW50bG4oImNoYXJhY3RlcnM6XHQiICsgdmFsdWUpOwogICAgICAgICAgICAgICAgICAgIGxhc3RDaGFycyArPSB2YWx1ZTsKICAgICAgICAgICAgICAgICAgICBqdXN0UG9wcGVkID0gZmFsc2U7CiAgICAgICAgICAgICAgICB9IGNhdGNoIChSdW50aW1lRXhjZXB0aW9uIGUpIHsKICAgICAgICAgICAgICAgICAgICBlLnByaW50U3RhY2tUcmFjZSgpOwogICAgICAgICAgICAgICAgICAgIHRocm93IGU7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KCiAgICAgICAgLy8ganVzdCBmb3IgZGVidWdnaW5nCiAgICAgICAgCiAgICAgICAgcHVibGljIHZvaWQgbm90YXRpb25EZWNsIChTdHJpbmcgbmFtZSwgU3RyaW5nIHB1YmxpY0lkLCBTdHJpbmcgc3lzdGVtSWQpCiAgICAgICAgdGhyb3dzIFNBWEV4Y2VwdGlvbiB7CiAgICAgICAgICAgIGlmIChERUJVRzIpIFN5c3RlbS5vdXQucHJpbnRsbigibm90YXRpb25EZWNsOiAiICsgbmFtZQogICAgICAgICAgICArICIsICIgKyBwdWJsaWNJZAogICAgICAgICAgICArICIsICIgKyBzeXN0ZW1JZAogICAgICAgICAgICApOwogICAgICAgIH0KCiAgICAgICAgcHVibGljIHZvaWQgcHJvY2Vzc2luZ0luc3RydWN0aW9uIChTdHJpbmcgdGFyZ2V0LCBTdHJpbmcgZGF0YSkKICAgICAgICB0aHJvd3MgU0FYRXhjZXB0aW9uIHsKICAgICAgICAgICAgaWYgKERFQlVHMikgU3lzdGVtLm91dC5wcmludGxuKCJwcm9jZXNzaW5nSW5zdHJ1Y3Rpb246ICIgKyB0YXJnZXQgKyAiLCAiICsgZGF0YSk7CiAgICAgICAgfQogICAgICAgIAogICAgICAgIHB1YmxpYyB2b2lkIHNraXBwZWRFbnRpdHkgKFN0cmluZyBuYW1lKQogICAgICAgIHRocm93cyBTQVhFeGNlcHRpb24KICAgICAgICB7CiAgICAgICAgICAgIGlmIChERUJVRzIpIFN5c3RlbS5vdXQucHJpbnRsbigic2tpcHBlZEVudGl0eTogIiArIG5hbWUKICAgICAgICAgICAgKTsKICAgICAgICB9CgogICAgICAgIHB1YmxpYyB2b2lkIHVucGFyc2VkRW50aXR5RGVjbCAoU3RyaW5nIG5hbWUsIFN0cmluZyBwdWJsaWNJZCwKICAgICAgICAgICAgICAgICAgICAgICAgU3RyaW5nIHN5c3RlbUlkLCBTdHJpbmcgbm90YXRpb25OYW1lKSB7CiAgICAgICAgICAgIGlmIChERUJVRzIpIFN5c3RlbS5vdXQucHJpbnRsbigidW5wYXJzZWRFbnRpdHlEZWNsOiAiICsgbmFtZQogICAgICAgICAgICArICIsICIgKyBwdWJsaWNJZAogICAgICAgICAgICArICIsICIgKyBzeXN0ZW1JZAogICAgICAgICAgICArICIsICIgKyBub3RhdGlvbk5hbWUKICAgICAgICAgICAgKTsKICAgICAgICB9CgkJcHVibGljIHZvaWQgc2V0RG9jdW1lbnRMb2NhdG9yKExvY2F0b3IgbG9jYXRvcikgewogICAgICAgICAgICBpZiAoREVCVUcyKSBTeXN0ZW0ub3V0LnByaW50bG4oInNldERvY3VtZW50TG9jYXRvciBMb2NhdG9yICIgKyBsb2NhdG9yKTsKCQl9CgkJcHVibGljIHZvaWQgc3RhcnREb2N1bWVudCgpIHRocm93cyBTQVhFeGNlcHRpb24gewogICAgICAgICAgICBpZiAoREVCVUcyKSBTeXN0ZW0ub3V0LnByaW50bG4oInN0YXJ0RG9jdW1lbnQiKTsKICAgICAgICAgICAgY29tbWVudFN0YWNrID0gMDsgLy8gaW5pdGlhbGl6ZQoJCX0KCQlwdWJsaWMgdm9pZCBlbmREb2N1bWVudCgpIHRocm93cyBTQVhFeGNlcHRpb24gewogICAgICAgICAgICBpZiAoREVCVUcyKSBTeXN0ZW0ub3V0LnByaW50bG4oImVuZERvY3VtZW50Iik7CgkJfQoJCXB1YmxpYyB2b2lkIHN0YXJ0UHJlZml4TWFwcGluZyhTdHJpbmcgcHJlZml4LCBTdHJpbmcgdXJpKSB0aHJvd3MgU0FYRXhjZXB0aW9uIHsKICAgICAgICAgICAgaWYgKERFQlVHMikgU3lzdGVtLm91dC5wcmludGxuKCJzdGFydFByZWZpeE1hcHBpbmcgcHJlZml4OiAiICsgcHJlZml4ICsgCiAgICAgICAgICAgICAgICAgICAgIiwgdXJpOiAiICsgdXJpKTsKCQl9CgkJcHVibGljIHZvaWQgZW5kUHJlZml4TWFwcGluZyhTdHJpbmcgcHJlZml4KSB0aHJvd3MgU0FYRXhjZXB0aW9uIHsKICAgICAgICAgICAgaWYgKERFQlVHMikgU3lzdGVtLm91dC5wcmludGxuKCJlbmRQcmVmaXhNYXBwaW5nIHByZWZpeDogIiArIHByZWZpeCk7CgkJfQoJCXB1YmxpYyB2b2lkIGlnbm9yYWJsZVdoaXRlc3BhY2UoY2hhcltdIGNoLCBpbnQgc3RhcnQsIGludCBsZW5ndGgpIHRocm93cyBTQVhFeGNlcHRpb24gewogICAgICAgICAgICBpZiAoREVCVUcyKSBTeXN0ZW0ub3V0LnByaW50bG4oImlnbm9yYWJsZVdoaXRlc3BhY2UgbGVuZ3RoOiAiICsgbGVuZ3RoKTsKCQl9CgkJcHVibGljIHZvaWQgc3RhcnREVEQoU3RyaW5nIG5hbWUsIFN0cmluZyBwdWJsaWNJZCwgU3RyaW5nIHN5c3RlbUlkKSB0aHJvd3MgU0FYRXhjZXB0aW9uIHsKICAgICAgICAgICAgaWYgKERFQlVHMikgU3lzdGVtLm91dC5wcmludGxuKCJzdGFydERURCBuYW1lOiAiICsgbmFtZQogICAgICAgICAgICAgICAgICAgICsgIiwgcHVibGljSWQ6ICIgKyBwdWJsaWNJZAogICAgICAgICAgICAgICAgICAgICsgIiwgc3lzdGVtSWQ6ICIgKyBzeXN0ZW1JZCAgICAgICAgIAogICAgICAgICAgICApOwogICAgICAgICAgICBjb21tZW50U3RhY2srKzsKCQl9CgkJcHVibGljIHZvaWQgZW5kRFREKCkgdGhyb3dzIFNBWEV4Y2VwdGlvbiB7CiAgICAgICAgICAgIGlmIChERUJVRzIpIFN5c3RlbS5vdXQucHJpbnRsbigiZW5kRFREIik7CiAgICAgICAgICAgIGNvbW1lbnRTdGFjay0tOwoJCX0KCQlwdWJsaWMgdm9pZCBzdGFydEVudGl0eShTdHJpbmcgbmFtZSkgdGhyb3dzIFNBWEV4Y2VwdGlvbiB7CiAgICAgICAgICAgIGlmIChERUJVRzIpIFN5c3RlbS5vdXQucHJpbnRsbigic3RhcnRFbnRpdHkgbmFtZTogIiArIG5hbWUpOwoJCX0KCQlwdWJsaWMgdm9pZCBlbmRFbnRpdHkoU3RyaW5nIG5hbWUpIHRocm93cyBTQVhFeGNlcHRpb24gewogICAgICAgICAgICBpZiAoREVCVUcyKSBTeXN0ZW0ub3V0LnByaW50bG4oImVuZEVudGl0eSBuYW1lOiAiICsgbmFtZSk7CgkJfQoJCXB1YmxpYyB2b2lkIHN0YXJ0Q0RBVEEoKSB0aHJvd3MgU0FYRXhjZXB0aW9uIHsKICAgICAgICAgICAgaWYgKERFQlVHMikgU3lzdGVtLm91dC5wcmludGxuKCJzdGFydENEQVRBIik7CgkJfQoJCXB1YmxpYyB2b2lkIGVuZENEQVRBKCkgdGhyb3dzIFNBWEV4Y2VwdGlvbiB7CiAgICAgICAgICAgIGlmIChERUJVRzIpIFN5c3RlbS5vdXQucHJpbnRsbigiZW5kQ0RBVEEiKTsKCQl9CgkJcHVibGljIHZvaWQgY29tbWVudChjaGFyW10gY2gsIGludCBzdGFydCwgaW50IGxlbmd0aCkgdGhyb3dzIFNBWEV4Y2VwdGlvbiB7CiAgICAgICAgICAgIGlmIChjb21tZW50U3RhY2sgIT0gMCkgcmV0dXJuOwogICAgICAgICAgICBTdHJpbmcgY29tbWVudCA9IG5ldyBTdHJpbmcoY2gsIHN0YXJ0LGxlbmd0aCkudHJpbSgpOwogICAgICAgICAgICBpZiAoZmluYWxDb21tZW50ID09IG51bGwpIGZpbmFsQ29tbWVudCA9IGNvbW1lbnQ7CiAgICAgICAgICAgIGVsc2UgZmluYWxDb21tZW50ICs9IE5FV0xJTkUgKyBjb21tZW50OwogICAgICAgICAgICBpZiAoREVCVUcyKSBTeXN0ZW0ub3V0LnByaW50bG4oImNvbW1lbnQ6ICIgKyBjb21tZW50KTsKCQl9CiAgICB9OwogICAgCiAgICBTdHJpbmcgZmluYWxDb21tZW50ID0gbnVsbDsKICAgIAogICAgWE1MUmVhZGVyIGNyZWF0ZVhNTFJlYWRlcihib29sZWFuIHZhbGlkYXRpbmcpIHsKICAgICAgICBYTUxSZWFkZXIgcmVzdWx0ID0gbnVsbDsKCQl0cnkgeyAvLyBYZXJjZXMKCQkJcmVzdWx0ID0gIFhNTFJlYWRlckZhY3RvcnkKCQkJCQkuY3JlYXRlWE1MUmVhZGVyKCJvcmcuYXBhY2hlLnhlcmNlcy5wYXJzZXJzLlNBWFBhcnNlciIpOwogICAgICAgICAgICByZXN1bHQuc2V0RmVhdHVyZSgiaHR0cDovL3htbC5vcmcvc2F4L2ZlYXR1cmVzL3ZhbGlkYXRpb24iLCB2YWxpZGF0aW5nKTsKCQl9IGNhdGNoIChTQVhFeGNlcHRpb24gZTEpIHsKCQkJdHJ5IHsgLy8gQ3JpbXNvbgoJCQkJcmVzdWx0ID0gIFhNTFJlYWRlckZhY3RvcnkKCQkJCQkJLmNyZWF0ZVhNTFJlYWRlcigib3JnLmFwYWNoZS5jcmltc29uLnBhcnNlci5YTUxSZWFkZXJJbXBsIik7CiAgICAgICAgICAgICAgICByZXN1bHQuc2V0RmVhdHVyZSgiaHR0cDovL3htbC5vcmcvc2F4L2ZlYXR1cmVzL3ZhbGlkYXRpb24iLCB2YWxpZGF0aW5nKTsKCQkJfSBjYXRjaCAoU0FYRXhjZXB0aW9uIGUyKSB7CgkJCQl0cnkgeyAvLyDGbGZyZWQKCQkJCQlyZXN1bHQgPSAgWE1MUmVhZGVyRmFjdG9yeQoJCQkJCQkJLmNyZWF0ZVhNTFJlYWRlcigiZ251LnhtbC5hZWxmcmVkMi5YbWxSZWFkZXIiKTsKICAgICAgICAgICAgICAgICAgICByZXN1bHQuc2V0RmVhdHVyZSgiaHR0cDovL3htbC5vcmcvc2F4L2ZlYXR1cmVzL3ZhbGlkYXRpb24iLCB2YWxpZGF0aW5nKTsKCQkJCX0gY2F0Y2ggKFNBWEV4Y2VwdGlvbiBlMykgewoJCQkJCXRyeSB7IC8vIFBpY2NvbG8KCQkJCQkJcmVzdWx0ID0gIFhNTFJlYWRlckZhY3RvcnkKCQkJCQkJCQkuY3JlYXRlWE1MUmVhZGVyKCJjb20uYmx1ZWNhc3QueG1sLlBpY2NvbG8iKTsKICAgICAgICAgICAgICAgICAgICAgICAgcmVzdWx0LnNldEZlYXR1cmUoImh0dHA6Ly94bWwub3JnL3NheC9mZWF0dXJlcy92YWxpZGF0aW9uIiwgdmFsaWRhdGluZyk7CgkJCQkJfSBjYXRjaCAoU0FYRXhjZXB0aW9uIGU0KSB7CgkJCQkJCXRyeSB7IC8vIE9yYWNsZQoJCQkJCQkJcmVzdWx0ID0gIFhNTFJlYWRlckZhY3RvcnkKCQkJCQkJCQkJLmNyZWF0ZVhNTFJlYWRlcigib3JhY2xlLnhtbC5wYXJzZXIudjIuU0FYUGFyc2VyIik7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXN1bHQuc2V0RmVhdHVyZSgiaHR0cDovL3htbC5vcmcvc2F4L2ZlYXR1cmVzL3ZhbGlkYXRpb24iLCB2YWxpZGF0aW5nKTsKCQkJCQkJfSBjYXRjaCAoU0FYRXhjZXB0aW9uIGU1KSB7CgkJCQkJCQl0cnkgeyAvLyBkZWZhdWx0CgkJCQkJCQkJcmVzdWx0ID0gIFhNTFJlYWRlckZhY3RvcnkuY3JlYXRlWE1MUmVhZGVyKCk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVzdWx0LnNldEZlYXR1cmUoImh0dHA6Ly94bWwub3JnL3NheC9mZWF0dXJlcy92YWxpZGF0aW9uIiwgdmFsaWRhdGluZyk7CgkJCQkJCQl9IGNhdGNoIChTQVhFeGNlcHRpb24gZTYpIHsKCQkJCQkJCQl0aHJvdyBuZXcgTm9DbGFzc0RlZkZvdW5kRXJyb3IoCgkJCQkJCQkJCQkiTm8gU0FYIHBhcnNlciBpcyBhdmFpbGFibGUsIG9yIHVuYWJsZSB0byBzZXQgdmFsaWRhdGlvbiBjb3JyZWN0bHkiKTsKCQkJCQkJCQkvLyBvciB3aGF0ZXZlciBleGNlcHRpb24geW91ciBtZXRob2QgaXMgIAoJCQkJCQkJCS8vIGRlY2xhcmVkIHRvIHRocm93CgkJCQkJCQl9CgkJCQkJCX0KCQkJCQl9CgkJCQl9CgkJCX0KCQl9CiAgICAgICAgdHJ5IHsKCQkJcmVzdWx0LnNldEVudGl0eVJlc29sdmVyKG5ldyBDYWNoaW5nRW50aXR5UmVzb2x2ZXIoKSk7CgkJfSBjYXRjaCAoVGhyb3dhYmxlIGUpIHsKCQkJU3lzdGVtLm91dAoJCQkJCS5wcmludGxuKCJXQVJOSU5HOiBDYW4ndCBzZXQgY2FjaGluZyBlbnRpdHkgcmVzb2x2ZXIgIC0gIGVycm9yICIKCQkJCQkJCSsgZS50b1N0cmluZygpKTsKCQkJZS5wcmludFN0YWNrVHJhY2UoKTsKCQl9CiAgICAgICAgcmV0dXJuIHJlc3VsdDsKCX0KICAgIHByaXZhdGUgc3RhdGljIHZvaWQgd3JpdGVGb290ZXJBbmRDbG9zZShQcmludFdyaXRlciBvdXQpCiAgICB7CiAgICAgICAgb3V0LnByaW50bG4oIkdlbmVyYXRlZCAiICsgamF2YS51dGlsLkNhbGVuZGFyLmdldEluc3RhbmNlKCkuZ2V0VGltZSgpKTsKICAgICAgICBvdXQucHJpbnRsbigiPC9ib2R5PjwvaHRtbD4iKTsKICAgICAgICBvdXQuY2xvc2UoKTsKICAgIH0KfQog