cGFja2FnZSBvcmcuYXBhY2hlLnR1cmJpbmUuc2VydmljZXMueG1scnBjOwoKLyogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KICogVGhlIEFwYWNoZSBTb2Z0d2FyZSBMaWNlbnNlLCBWZXJzaW9uIDEuMQogKgogKiBDb3B5cmlnaHQgKGMpIDIwMDEtMjAwMyBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uICBBbGwgcmlnaHRzCiAqIHJlc2VydmVkLgogKgogKiBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQKICogbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zCiAqIGFyZSBtZXQ6CiAqCiAqIDEuIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0CiAqICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4KICoKICogMi4gUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZSBjb3B5cmlnaHQKICogICAgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyIGluCiAqICAgIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUKICogICAgZGlzdHJpYnV0aW9uLgogKgogKiAzLiBUaGUgZW5kLXVzZXIgZG9jdW1lbnRhdGlvbiBpbmNsdWRlZCB3aXRoIHRoZSByZWRpc3RyaWJ1dGlvbiwKICogICAgaWYgYW55LCBtdXN0IGluY2x1ZGUgdGhlIGZvbGxvd2luZyBhY2tub3dsZWRnbWVudDoKICogICAgICAgIlRoaXMgcHJvZHVjdCBpbmNsdWRlcyBzb2Z0d2FyZSBkZXZlbG9wZWQgYnkgdGhlCiAqICAgICAgICBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoaHR0cDovL3d3dy5hcGFjaGUub3JnLykuIgogKiAgICBBbHRlcm5hdGVseSwgdGhpcyBhY2tub3dsZWRnbWVudCBtYXkgYXBwZWFyIGluIHRoZSBzb2Z0d2FyZSBpdHNlbGYsCiAqICAgIGlmIGFuZCB3aGVyZXZlciBzdWNoIHRoaXJkLXBhcnR5IGFja25vd2xlZGdtZW50cyBub3JtYWxseSBhcHBlYXIuCiAqCiAqIDQuIFRoZSBuYW1lcyAiQXBhY2hlIiBhbmQgIkFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIiBhbmQKICogICAgIkFwYWNoZSBUdXJiaW5lIiBtdXN0IG5vdCBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cwogKiAgICBkZXJpdmVkIGZyb20gdGhpcyBzb2Z0d2FyZSB3aXRob3V0IHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi4gRm9yCiAqICAgIHdyaXR0ZW4gcGVybWlzc2lvbiwgcGxlYXNlIGNvbnRhY3QgYXBhY2hlQGFwYWNoZS5vcmcuCiAqCiAqIDUuIFByb2R1Y3RzIGRlcml2ZWQgZnJvbSB0aGlzIHNvZnR3YXJlIG1heSBub3QgYmUgY2FsbGVkICJBcGFjaGUiLAogKiAgICAiQXBhY2hlIFR1cmJpbmUiLCBub3IgbWF5ICJBcGFjaGUiIGFwcGVhciBpbiB0aGVpciBuYW1lLCB3aXRob3V0CiAqICAgIHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbiBvZiB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24uCiAqCiAqIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgYGBBUyBJUycnIEFORCBBTlkgRVhQUkVTU0VEIE9SIElNUExJRUQKICogV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFRIRSBJTVBMSUVEIFdBUlJBTlRJRVMKICogT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBUkUKICogRElTQ0xBSU1FRC4gIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBBUEFDSEUgU09GVFdBUkUgRk9VTkRBVElPTiBPUgogKiBJVFMgQ09OVFJJQlVUT1JTIEJFIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsCiAqIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QKICogTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRgogKiBVU0UsIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5ECiAqIE9OIEFOWSBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLAogKiBPUiBUT1JUIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQKICogT0YgVEhFIFVTRSBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GCiAqIFNVQ0ggREFNQUdFLgogKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQogKgogKiBUaGlzIHNvZnR3YXJlIGNvbnNpc3RzIG9mIHZvbHVudGFyeSBjb250cmlidXRpb25zIG1hZGUgYnkgbWFueQogKiBpbmRpdmlkdWFscyBvbiBiZWhhbGYgb2YgdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLiAgRm9yIG1vcmUKICogaW5mb3JtYXRpb24gb24gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLCBwbGVhc2Ugc2VlCiAqIDxodHRwOi8vd3d3LmFwYWNoZS5vcmcvPi4KICovCgppbXBvcnQgamF2YS5pby5JbnB1dFN0cmVhbTsKCmltcG9ydCBqYXZhLm5ldC5JbmV0QWRkcmVzczsKaW1wb3J0IGphdmEubmV0LlNvY2tldDsKaW1wb3J0IGphdmEubmV0LlVSTDsKaW1wb3J0IGphdmEubmV0LlVua25vd25Ib3N0RXhjZXB0aW9uOwoKaW1wb3J0IGphdmEudXRpbC5JdGVyYXRvcjsKaW1wb3J0IGphdmEudXRpbC5MaXN0OwppbXBvcnQgamF2YS51dGlsLlZlY3RvcjsKCmltcG9ydCBqYXZheC5zZXJ2bGV0LlNlcnZsZXRDb25maWc7CgppbXBvcnQgb3JnLmFwYWNoZS5jb21tb25zLmNvbmZpZ3VyYXRpb24uQ29uZmlndXJhdGlvbjsKCmltcG9ydCBvcmcuYXBhY2hlLmNvbW1vbnMubGFuZy5TdHJpbmdVdGlsczsKCmltcG9ydCBvcmcuYXBhY2hlLmNvbW1vbnMubG9nZ2luZy5Mb2c7CmltcG9ydCBvcmcuYXBhY2hlLmNvbW1vbnMubG9nZ2luZy5Mb2dGYWN0b3J5OwoKaW1wb3J0IG9yZy5hcGFjaGUudHVyYmluZS5zZXJ2aWNlcy5Jbml0aWFsaXphdGlvbkV4Y2VwdGlvbjsKaW1wb3J0IG9yZy5hcGFjaGUudHVyYmluZS5zZXJ2aWNlcy5UdXJiaW5lQmFzZVNlcnZpY2U7CmltcG9ydCBvcmcuYXBhY2hlLnR1cmJpbmUuc2VydmljZXMueG1scnBjLnV0aWwuRmlsZVRyYW5zZmVyOwppbXBvcnQgb3JnLmFwYWNoZS50dXJiaW5lLnV0aWwuVHVyYmluZUV4Y2VwdGlvbjsKCmltcG9ydCBvcmcuYXBhY2hlLnhlcmNlcy5wYXJzZXJzLlNBWFBhcnNlcjsKCmltcG9ydCBvcmcuYXBhY2hlLnhtbHJwYy5XZWJTZXJ2ZXI7CmltcG9ydCBvcmcuYXBhY2hlLnhtbHJwYy5YbWxScGM7CmltcG9ydCBvcmcuYXBhY2hlLnhtbHJwYy5YbWxScGNDbGllbnQ7CmltcG9ydCBvcmcuYXBhY2hlLnhtbHJwYy5YbWxScGNTZXJ2ZXI7CmltcG9ydCBvcmcuYXBhY2hlLnhtbHJwYy5zZWN1cmUuU2VjdXJlV2ViU2VydmVyOwoKLyoqCiAqIFRoaXMgaXMgYSBzZXJ2aWNlIHdoaWNoIHdpbGwgbWFrZSBhbiB4bWwtcnBjIGNhbGwgdG8gYSByZW1vdGUKICogc2VydmVyLgogKgogKiBIZXJlJ3MgYW4gZXhhbXBsZSBvZiBob3cgaXQgd291bGQgYmUgZG9uZToKICogPGJsb2NrcXVvdGU+PGNvZGU+PHByZT4KICogWG1sUnBjU2VydmljZSB4cyA9CiAqICAgKFhtbFJwY1NlcnZpY2UpVHVyYmluZVNlcnZpY2VzLmdldEluc3RhbmNlKCkKICogICAuZ2V0U2VydmljZShYbWxScGNTZXJ2aWNlLlhNTFJQQ19TRVJWSUNFX05BTUUpOwogKiBWZWN0b3IgdmVjID0gbmV3IFZlY3RvcigpOwogKiB2ZWMuYWRkRWxlbWVudChuZXcgSW50ZWdlcig1KSk7CiAqIFVSTCB1cmwgPSBuZXcgVVJMKCJodHRwOi8vYmV0dHkudXNlcmxhbmQuY29tL1JQQzIiKTsKICogU3RyaW5nIG5hbWUgPSAoU3RyaW5nKXhzLmV4ZWN1dGVScGModXJsLCAiZXhhbXBsZXMuZ2V0U3RhdGVOYW1lIiwgdmVjKTsKICogPC9wcmU+PC9jb2RlPjwvYmxvY2txdW90ZT4KICoKICogPHA+VE9ETzogSGFuZGxlIFhtbFJwYy5zZXREZWJ1Zyhib29sZWFuKTwvcD4KICoKICogQGF1dGhvciA8YSBocmVmPSJtYWlsdG86am9zaEBzdG9uZWNvdHRhZ2UuY29tIj5Kb3NoIEx1Y2FzPC9hPgogKiBAYXV0aG9yIDxhIGhyZWY9Im1haWx0bzptYWdudXNAaGFuZHRvbHZ1ci5pcyI+TWFnbvpzIN7zciBUb3JmYXNvbjwvYT4KICogQGF1dGhvciA8YSBocmVmPSJtYWlsdG86UmFmYWwuS3J6ZXdza2lAZS1wb2ludC5wbCI+UmFmYWwgS3J6ZXdza2k8L2E+CiAqIEBhdXRob3IgPGEgaHJlZj0ibWFpbHRvOmp2YW56eWxAcGVyaWFwdC5jb20iPkphc29uIHZhbiBaeWw8L2E+CiAqIEBhdXRob3IgPGEgaHJlZj0ibWFpbHRvOmRsckBmaW5lbWFsdGNvZGluZy5jb20iPkRhbmllbCBSYWxsPC9hPgogKiBAYXV0aG9yIDxhIGhyZWY9Im1haWx0bzptcG9lc2NobEBtYXJtb3QuYXQiPk1hcnRpbiBQb2VzY2hsPC9hPgogKiBAYXV0aG9yIDxhIGhyZWY9Im1haWx0bzpxdWludG9ubUBiZWxsc291dGgubmV0Ij5RdWludG9uIE1jQ29tYnM8L2E+CiAqIEB2ZXJzaW9uICRJZCQKICovCnB1YmxpYyBjbGFzcyBUdXJiaW5lWG1sUnBjU2VydmljZQogICAgICAgIGV4dGVuZHMgVHVyYmluZUJhc2VTZXJ2aWNlCiAgICAgICAgaW1wbGVtZW50cyBYbWxScGNTZXJ2aWNlCnsKICAgIC8qKiBMb2dnaW5nICovCiAgICBwcml2YXRlIHN0YXRpYyBMb2cgbG9nID0gTG9nRmFjdG9yeS5nZXRMb2coVHVyYmluZVhtbFJwY1NlcnZpY2UuY2xhc3MpOwoKICAgIC8qKgogICAgICogV2hldGhlciBhIHZlcnNpb24gb2YgQXBhY2hlJ3MgWE1MLVJQQyBsaWJyYXJ5IGdyZWF0ZXIgdGhhbiAxLjEKICAgICAqIGlzIGF2YWlsYWJsZS4KICAgICAqLwogICAgcHJvdGVjdGVkIGJvb2xlYW4gaXNNb2Rlcm5WZXJzaW9uID0gZmFsc2U7CgogICAgLyoqIFRoZSBzdGFuZGFsb25lIHhtbHJwYyBzZXJ2ZXIuICovCiAgICBwcm90ZWN0ZWQgV2ViU2VydmVyIHdlYnNlcnZlciA9IG51bGw7CgogICAgLyoqIFRoZSBlbmNhcHN1bGF0ZWQgeG1scnBjIHNlcnZlci4gKi8KICAgIHByb3RlY3RlZCBYbWxScGNTZXJ2ZXIgc2VydmVyID0gbnVsbDsKCiAgICAvKioKICAgICAqIFRoZSBhZGRyZXNzIHRvIGxpc3RlbiBvbi4gIFRoZSBkZWZhdWx0IG9mIDxjb2RlPm51bGw8L2NvZGU+CiAgICAgKiBpbmRpY2F0ZXMgYWxsIG5ldHdvcmsgaW50ZXJmYWNlcyBvbiBhIG11bHRpLWhvbWVkIGhvc3QuCiAgICAgKi8KICAgIHByaXZhdGUgSW5ldEFkZHJlc3MgYWRkcmVzcyA9IG51bGw7CgogICAgLyoqIFRoZSBwb3J0IHRvIGxpc3RlbiBvbi4gKi8KICAgIHByb3RlY3RlZCBpbnQgcG9ydCA9IDA7CgogICAgLyoqCiAgICAgKiBUaGlzIGZ1bmN0aW9uIGluaXRpYWxpemVzIHRoZSBYbWxScGNTZXJ2aWNlLlRoaXMgaXMKICAgICAqIGEgemVybyBwYXJhbWV0ZXIgdmFyaWFudCB3aGljaCBxdWVyaWVzIHRoZSBUdXJiaW5lIFNlcnZsZXQKICAgICAqIGZvciBpdHMgY29uZmlnLgogICAgICoKICAgICAqIEB0aHJvd3MgSW5pdGlhbGl6YXRpb25FeGNlcHRpb24gU29tZXRoaW5nIHdlbnQgd3JvbmcgaW4gdGhlIGluaXQKICAgICAqICAgICAgICAgc3RhZ2UKICAgICAqLwogICAgcHVibGljIHZvaWQgaW5pdCgpCiAgICAgICAgICAgIHRocm93cyBJbml0aWFsaXphdGlvbkV4Y2VwdGlvbgogICAgewogICAgICAgIENvbmZpZ3VyYXRpb24gY29uZiA9IGdldENvbmZpZ3VyYXRpb24oKTsKCiAgICAgICAgdHJ5CiAgICAgICAgewogICAgICAgICAgICBzZXJ2ZXIgPSBuZXcgWG1sUnBjU2VydmVyKCk7CgogICAgICAgICAgICAvLyBzZXR1cCBKU1NFIFN5c3RlbSBwcm9wZXJ0aWVzIGZyb20gc2VjdXJlLnNlcnZlci5vcHRpb25zCiAgICAgICAgICAgIENvbmZpZ3VyYXRpb24gc2VjdXJlU2VydmVyT3B0aW9ucyA9CiAgICAgICAgICAgICAgICAgICAgY29uZi5zdWJzZXQoInNlY3VyZS5zZXJ2ZXIub3B0aW9uIik7CgogICAgICAgICAgICBpZiAoc2VjdXJlU2VydmVyT3B0aW9ucyAhPSBudWxsKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBzZXRTeXN0ZW1Qcm9wZXJ0aWVzRnJvbUNvbmZpZ3VyYXRpb24oc2VjdXJlU2VydmVyT3B0aW9ucyk7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIC8vIEhvc3QgYW5kIHBvcnQgaW5mb3JtYXRpb24gZm9yIHRoZSBXZWJTZXJ2ZXIKICAgICAgICAgICAgU3RyaW5nIGFkZHIgPSBjb25mLmdldFN0cmluZygiYWRkcmVzcyIsICIwLjAuMC4wIik7CiAgICAgICAgICAgIHBvcnQgPSBjb25mLmdldEludCgicG9ydCIsIDApOwoKICAgICAgICAgICAgaWYgKHBvcnQgIT0gMCkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgaWYgKGFkZHIgIT0gbnVsbCAmJiBhZGRyLmxlbmd0aCgpID4gMCkKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICB0cnkKICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgIGFkZHJlc3MgPSBJbmV0QWRkcmVzcy5nZXRCeU5hbWUoYWRkcik7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIGNhdGNoIChVbmtub3duSG9zdEV4Y2VwdGlvbiB1c2VEZWZhdWx0KQogICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgYWRkcmVzcyA9IG51bGw7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgIGxvZy5kZWJ1ZygiUG9ydDogIiArIHBvcnQgKyAiLCBBZGRyZXNzOiAiICsgYWRkcmVzcyk7CgogICAgICAgICAgICAgICAgaWYgKGNvbmYuZ2V0Qm9vbGVhbigic2VjdXJlLnNlcnZlciIsIGZhbHNlKSkKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICB3ZWJzZXJ2ZXIgPSBuZXcgU2VjdXJlV2ViU2VydmVyKHBvcnQsIGFkZHJlc3MpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgZWxzZQogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIHdlYnNlcnZlciA9IG5ldyBXZWJTZXJ2ZXIocG9ydCwgYWRkcmVzcyk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIC8vIFNldCB0aGUgWE1MIGRyaXZlciB0byB0aGUgY29ycmVjdCBTQVggcGFyc2VyIGNsYXNzCiAgICAgICAgICAgIFN0cmluZyBzYXhQYXJzZXJDbGFzcyA9IAogICAgICAgICAgICAgICAgICAgIGNvbmYuZ2V0U3RyaW5nKCJwYXJzZXIiLCBTQVhQYXJzZXIuY2xhc3MuZ2V0TmFtZSgpKTsKCiAgICAgICAgICAgIFhtbFJwYy5zZXREcml2ZXIoc2F4UGFyc2VyQ2xhc3MpOwoKICAgICAgICAgICAgLy8gQ2hlY2sgaWYgdGhlcmUgYXJlIGFueSBoYW5kbGVycyB0byByZWdpc3RlciBhdCBzdGFydHVwCiAgICAgICAgICAgIGZvciAoSXRlcmF0b3Iga2V5cyA9IGNvbmYuZ2V0S2V5cygiaGFuZGxlciIpOyBrZXlzLmhhc05leHQoKTspCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIFN0cmluZyBoYW5kbGVyICAgICAgPSAoU3RyaW5nKSBrZXlzLm5leHQoKTsKICAgICAgICAgICAgICAgIFN0cmluZyBoYW5kbGVyTmFtZSAgPSBoYW5kbGVyLnN1YnN0cmluZyhoYW5kbGVyLmluZGV4T2YoJy4nKSsxKTsKICAgICAgICAgICAgICAgIFN0cmluZyBoYW5kbGVyQ2xhc3MgPSBjb25mLmdldFN0cmluZyhoYW5kbGVyKTsKCiAgICAgICAgICAgICAgICBsb2cuZGVidWcoIkZvdW5kIEhhbmRsZXIgIiArIGhhbmRsZXIgKyAiIGFzICIgKyBoYW5kbGVyTmFtZSArICIgLyAiICsgaGFuZGxlckNsYXNzKTsKCiAgICAgICAgICAgICAgICByZWdpc3RlckhhbmRsZXIoaGFuZGxlck5hbWUsIGhhbmRsZXJDbGFzcyk7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIC8vIFR1cm4gb24gcGFyYW5vaWEgZm9yIHRoZSB3ZWJzZXJ2ZXIgaWYgcmVxdWVzdGVkLgogICAgICAgICAgICBib29sZWFuIHN0YXRlT2ZQYXJhbm9pYSA9CiAgICAgICAgICAgICAgICAgICAgY29uZi5nZXRCb29sZWFuKCJwYXJhbm9pZCIsIGZhbHNlKTsKCiAgICAgICAgICAgIGlmIChzdGF0ZU9mUGFyYW5vaWEpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIHdlYnNlcnZlci5zZXRQYXJhbm9pZChzdGF0ZU9mUGFyYW5vaWEpOwogICAgICAgICAgICAgICAgbG9nLmluZm8oWG1sUnBjU2VydmljZS5TRVJWSUNFX05BTUUgKwogICAgICAgICAgICAgICAgICAgICAgICAiOiBPcGVyYXRpbmcgaW4gYSBzdGF0ZSBvZiBwYXJhbm9pYSIpOwoKICAgICAgICAgICAgICAgIC8vIE9ubHkgc2V0IHRoZSBhY2NlcHQvZGVueSBjbGllbnQgbGlzdHMgaWYgd2UKICAgICAgICAgICAgICAgIC8vIGFyZSBpbiBhIHN0YXRlIG9mIHBhcmFub2lhIGFzIHRoZXkgd2lsbCBqdXN0CiAgICAgICAgICAgICAgICAvLyBiZSBpZ25vcmVkIHNvIHRoZXJlJ3Mgbm8gcG9pbnQgaW4gc2V0dGluZyB0aGVtLgoKICAgICAgICAgICAgICAgIC8vIFNldCB0aGUgbGlzdCBvZiBjbGllbnRzIHRoYXQgY2FuIGNvbm5lY3QKICAgICAgICAgICAgICAgIC8vIHRvIHRoZSB4bWxycGMgc2VydmVyLiBUaGUgYWNjZXB0ZWQgY2xpZW50IGxpc3QKICAgICAgICAgICAgICAgIC8vIHdpbGwgb25seSBiZSBjb25zdWx0ZWQgaWYgd2UgYXJlIHBhcmFub2lkLgogICAgICAgICAgICAgICAgTGlzdCBhY2NlcHRlZENsaWVudHMgPQogICAgICAgICAgICAgICAgICAgICAgICBjb25mLmdldExpc3QoImFjY2VwdENsaWVudCIpOwoKICAgICAgICAgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgYWNjZXB0ZWRDbGllbnRzLnNpemUoKTsgaSsrKQogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIFN0cmluZyBhY2NlcHRDbGllbnQgPSAoU3RyaW5nKSBhY2NlcHRlZENsaWVudHMuZ2V0KGkpOwoKICAgICAgICAgICAgICAgICAgICBpZiAoU3RyaW5nVXRpbHMuaXNOb3RFbXB0eShhY2NlcHRDbGllbnQpKQogICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgd2Vic2VydmVyLmFjY2VwdENsaWVudChhY2NlcHRDbGllbnQpOwogICAgICAgICAgICAgICAgICAgICAgICBsb2cuaW5mbyhYbWxScGNTZXJ2aWNlLlNFUlZJQ0VfTkFNRSArCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIjogQWNjZXB0aW5nIGNsaWVudCAtPiAiICsgYWNjZXB0Q2xpZW50KTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgLy8gU2V0IHRoZSBsaXN0IG9mIGNsaWVudHMgdGhhdCBjYW4gY29ubmVjdAogICAgICAgICAgICAgICAgLy8gdG8gdGhlIHhtbHJwYyBzZXJ2ZXIuIFRoZSBkZW5pZWQgY2xpZW50IGxpc3QKICAgICAgICAgICAgICAgIC8vIHdpbGwgb25seSBiZSBjb25zdWx0ZWQgaWYgd2UgYXJlIHBhcmFub2lkLgogICAgICAgICAgICAgICAgTGlzdCBkZW5pZWRDbGllbnRzID0gY29uZi5nZXRMaXN0KCJkZW55Q2xpZW50Iik7CgogICAgICAgICAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBkZW5pZWRDbGllbnRzLnNpemUoKTsgaSsrKQogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIFN0cmluZyBkZW55Q2xpZW50ID0gKFN0cmluZykgZGVuaWVkQ2xpZW50cy5nZXQoaSk7CgogICAgICAgICAgICAgICAgICAgIGlmIChTdHJpbmdVdGlscy5pc05vdEVtcHR5KGRlbnlDbGllbnQpKQogICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgd2Vic2VydmVyLmRlbnlDbGllbnQoZGVueUNsaWVudCk7CiAgICAgICAgICAgICAgICAgICAgICAgIGxvZy5pbmZvKFhtbFJwY1NlcnZpY2UuU0VSVklDRV9OQU1FICsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiOiBEZW55aW5nIGNsaWVudCAtPiAiICsgZGVueUNsaWVudCk7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgICAgIC8vIElmIHdlIGhhdmUgYSBYTUwtUlBDIEpBUiB3aG9zZSB2ZXJzaW9uIGlzIGdyZWF0ZXIgdGhhbiB0aGUKICAgICAgICAgICAgLy8gMS4xIHNlcmllcywgdGhlIFdlYlNlcnZlciBtdXN0IGJlIGV4cGxpY2l0bHkgc3RhcnQoKSdkLgogICAgICAgICAgICB0cnkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgQ2xhc3MuZm9yTmFtZSgib3JnLmFwYWNoZS54bWxycGMuWG1sUnBjUmVxdWVzdCIpOwogICAgICAgICAgICAgICAgaXNNb2Rlcm5WZXJzaW9uID0gdHJ1ZTsKICAgICAgICAgICAgICAgIHdlYnNlcnZlci5zdGFydCgpOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGNhdGNoIChDbGFzc05vdEZvdW5kRXhjZXB0aW9uIGlnbm9yZWQpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIC8vIFhtbFJwY1JlcXVlc3QgZG9lcyBub3QgZXhpc3QgaW4gdmVyc2lvbnMgMS4xIGFuZCBsb3dlci4KICAgICAgICAgICAgICAgIC8vIEFzc3VtZSB0aGF0IG91ciBXZWJTZXJ2ZXIgd2FzIGFscmVhZHkgc3RhcnRlZC4KICAgICAgICAgICAgfQogICAgICAgICAgICBsb2cuZGVidWcoWG1sUnBjU2VydmljZS5TRVJWSUNFX05BTUUgKyAiOiBVc2luZyAiICsKICAgICAgICAgICAgICAgICAgICAiQXBhY2hlIFhNTC1SUEMgdmVyc2lvbiAiICsKICAgICAgICAgICAgICAgICAgICAoaXNNb2Rlcm5WZXJzaW9uID8KICAgICAgICAgICAgICAgICAgICAiZ3JlYXRlciB0aGFuIDEuMSIgOiAiMS4xIG9yIGxvd2VyIikpOwogICAgICAgIH0KICAgICAgICBjYXRjaCAoRXhjZXB0aW9uIGUpCiAgICAgICAgewogICAgICAgICAgICBTdHJpbmcgZXJyb3JNZXNzYWdlID0gIlhNTFJQQ1NlcnZpY2UgZmFpbGVkIHRvIGluaXRpYWxpemUiOwogICAgICAgICAgICBsb2cuZXJyb3IoZXJyb3JNZXNzYWdlLCBlKTsKICAgICAgICAgICAgdGhyb3cgbmV3IEluaXRpYWxpemF0aW9uRXhjZXB0aW9uKGVycm9yTWVzc2FnZSwgZSk7CiAgICAgICAgfQoKICAgICAgICBzZXRJbml0KHRydWUpOwogICAgfQoKICAgIC8qKgogICAgICogVGhpcyBmdW5jdGlvbiBpbml0aWFsaXplcyB0aGUgWG1sUnBjU2VydmljZS4KICAgICAqCiAgICAgKiBAZGVwcmVjYXRlZCBVc2UgaW5pdCgpIGluc3RlYWQuCiAgICAgKi8KICAgIHB1YmxpYyB2b2lkIGluaXQoU2VydmxldENvbmZpZyBjb25maWcpIHRocm93cyBJbml0aWFsaXphdGlvbkV4Y2VwdGlvbgogICAgewogICAgICAgIGluaXQoKTsKICAgIH0KCiAgICAvKioKICAgICAqIENyZWF0ZSBTeXN0ZW0gcHJvcGVydGllcyB1c2luZyB0aGUga2V5LXZhbHVlIHBhaXJzIGluIGEgZ2l2ZW4KICAgICAqIENvbmZpZ3VyYXRpb24uICBUaGlzIGlzIHVzZWQgdG8gc2V0IHN5c3RlbSBwcm9wZXJ0aWVzIGFuZCB0aGUKICAgICAqIFVSTCBodHRwcyBjb25uZWN0aW9uIGhhbmRsZXIgbmVlZGVkIGJ5IEpTU0UgdG8gZW5hYmxlIFNTTAogICAgICogYmV0d2VlbiBYTUwtUlBDIGNsaWVudCBhbmQgc2VydmVyLgogICAgICoKICAgICAqIEBwYXJhbSBjb25maWd1cmF0aW9uIHRoZSBDb25maWd1cmF0aW9uIGRlZmluaW5nIHRoZSBTeXN0ZW0KICAgICAqIHByb3BlcnRpZXMgdG8gYmUgc2V0CiAgICAgKi8KICAgIHByaXZhdGUgdm9pZCBzZXRTeXN0ZW1Qcm9wZXJ0aWVzRnJvbUNvbmZpZ3VyYXRpb24oQ29uZmlndXJhdGlvbiBjb25maWd1cmF0aW9uKQogICAgewogICAgICAgIGZvciAoSXRlcmF0b3IgaSA9IGNvbmZpZ3VyYXRpb24uZ2V0S2V5cygpOyBpLmhhc05leHQoKTspCiAgICAgICAgewogICAgICAgICAgICBTdHJpbmcga2V5ID0gKFN0cmluZykgaS5uZXh0KCk7CiAgICAgICAgICAgIFN0cmluZyB2YWx1ZSA9IGNvbmZpZ3VyYXRpb24uZ2V0U3RyaW5nKGtleSk7CgogICAgICAgICAgICBsb2cuZGVidWcoIkpTU0Ugb3B0aW9uOiAiICsga2V5ICsgIiA9PiAiICsgdmFsdWUpOwoKICAgICAgICAgICAgU3lzdGVtLnNldFByb3BlcnR5KGtleSwgdmFsdWUpOwogICAgICAgIH0KICAgIH0KCiAgICAvKioKICAgICAqIFJlZ2lzdGVyIGFuIE9iamVjdCBhcyBhIGRlZmF1bHQgaGFuZGxlciBmb3IgdGhlIHNlcnZpY2UuCiAgICAgKgogICAgICogQHBhcmFtIGhhbmRsZXIgVGhlIGhhbmRsZXIgdG8gdXNlLgogICAgICovCiAgICBwdWJsaWMgdm9pZCByZWdpc3RlckhhbmRsZXIoT2JqZWN0IGhhbmRsZXIpCiAgICB7CiAgICAgICAgcmVnaXN0ZXJIYW5kbGVyKCIkZGVmYXVsdCIsIGhhbmRsZXIpOwogICAgfQoKICAgIC8qKgogICAgICogUmVnaXN0ZXIgYW4gT2JqZWN0IGFzIGEgaGFuZGxlciBmb3IgdGhlIHNlcnZpY2UuCiAgICAgKgogICAgICogQHBhcmFtIGhhbmRsZXJOYW1lIFRoZSBuYW1lIHRoZSBoYW5kbGVyIGlzIHJlZ2lzdGVyZWQgdW5kZXIuCiAgICAgKiBAcGFyYW0gaGFuZGxlciBUaGUgaGFuZGxlciB0byB1c2UuCiAgICAgKi8KICAgIHB1YmxpYyB2b2lkIHJlZ2lzdGVySGFuZGxlcihTdHJpbmcgaGFuZGxlck5hbWUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgT2JqZWN0IGhhbmRsZXIpCiAgICB7CiAgICAgICAgaWYgKHdlYnNlcnZlciAhPSBudWxsKQogICAgICAgIHsKICAgICAgICAgICAgd2Vic2VydmVyLmFkZEhhbmRsZXIoaGFuZGxlck5hbWUsIGhhbmRsZXIpOwogICAgICAgIH0KCiAgICAgICAgc2VydmVyLmFkZEhhbmRsZXIoaGFuZGxlck5hbWUsIGhhbmRsZXIpOwogICAgICAgIAogICAgICAgIGxvZy5kZWJ1ZygiUmVnaXN0ZXJlZCBIYW5kbGVyICIgKyBoYW5kbGVyTmFtZSArICIgYXMgIiAKICAgICAgICAgICAgICAgICsgaGFuZGxlci5nZXRDbGFzcygpLmdldE5hbWUoKSAKICAgICAgICAgICAgICAgICsgIiwgU2VydmVyOiAiICsgc2VydmVyIAogICAgICAgICAgICAgICAgKyAiLCBXZWJzZXJ2ZXI6ICIgKyB3ZWJzZXJ2ZXIpOwogICAgfQoKICAgIC8qKgogICAgICogQSBoZWxwZXIgbWV0aG9kIHRoYXQgdHJpZXMgdG8gaW5pdGlhbGl6ZSBhIGhhbmRsZXIgYW5kIHJlZ2lzdGVyIGl0LgogICAgICogVGhlIHB1cnBvc2UgaXMgdG8gY2hlY2sgZm9yIGFsbCB0aGUgZXhjZXB0aW9ucyB0aGF0IG1heSBvY2N1ciBpbgogICAgICogZHluYW1pYyBjbGFzcyBsb2FkaW5nIGFuZCB0aHJvdyBhbiBJbml0aWFsaXphdGlvbkV4Y2VwdGlvbiBvbgogICAgICogZXJyb3IuCiAgICAgKgogICAgICogQHBhcmFtIGhhbmRsZXJOYW1lIFRoZSBuYW1lIHRoZSBoYW5kbGVyIGlzIHJlZ2lzdGVyZWQgdW5kZXIuCiAgICAgKiBAcGFyYW0gaGFuZGxlckNsYXNzIFRoZSBuYW1lIG9mIHRoZSBjbGFzcyB0byB1c2UgYXMgYSBoYW5kbGVyLgogICAgICogQGV4Y2VwdGlvbiBUdXJiaW5lRXhjZXB0aW9uIENvdWxkbid0IGluc3RhbnRpYXRlIGhhbmRsZXIuCiAgICAgKi8KICAgIHB1YmxpYyB2b2lkIHJlZ2lzdGVySGFuZGxlcihTdHJpbmcgaGFuZGxlck5hbWUsIFN0cmluZyBoYW5kbGVyQ2xhc3MpCiAgICAgICAgICAgIHRocm93cyBUdXJiaW5lRXhjZXB0aW9uCiAgICB7CiAgICAgICAgdHJ5CiAgICAgICAgewogICAgICAgICAgICBPYmplY3QgaGFuZGxlciA9IENsYXNzLmZvck5hbWUoaGFuZGxlckNsYXNzKS5uZXdJbnN0YW5jZSgpOwoKICAgICAgICAgICAgaWYgKHdlYnNlcnZlciAhPSBudWxsKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICB3ZWJzZXJ2ZXIuYWRkSGFuZGxlcihoYW5kbGVyTmFtZSwgaGFuZGxlcik7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIHNlcnZlci5hZGRIYW5kbGVyKGhhbmRsZXJOYW1lLCBoYW5kbGVyKTsKICAgICAgICB9CiAgICAgICAgICAgICAgICAvLyB0aG9zZSB0d28gZXJyb3JzIG11c3QgYmUgcGFzc2VkIHRvIHRoZSBWTQogICAgICAgIGNhdGNoIChUaHJlYWREZWF0aCB0KQogICAgICAgIHsKICAgICAgICAgICAgdGhyb3cgdDsKICAgICAgICB9CiAgICAgICAgY2F0Y2ggKE91dE9mTWVtb3J5RXJyb3IgdCkKICAgICAgICB7CiAgICAgICAgICAgIHRocm93IHQ7CiAgICAgICAgfQoKICAgICAgICBjYXRjaCAoVGhyb3dhYmxlIHQpCiAgICAgICAgewogICAgICAgICAgICB0aHJvdyBuZXcgVHVyYmluZUV4Y2VwdGlvbgogICAgICAgICAgICAgICAgICAgICgiRmFpbGVkIHRvIGluc3RhbnRpYXRlICIgKyBoYW5kbGVyQ2xhc3MsIHQpOwogICAgICAgIH0KICAgIH0KCiAgICAvKioKICAgICAqIFVucmVnaXN0ZXIgYSBoYW5kbGVyLgogICAgICoKICAgICAqIEBwYXJhbSBoYW5kbGVyTmFtZSBUaGUgbmFtZSBvZiB0aGUgaGFuZGxlciB0byB1bnJlZ2lzdGVyLgogICAgICovCiAgICBwdWJsaWMgdm9pZCB1bnJlZ2lzdGVySGFuZGxlcihTdHJpbmcgaGFuZGxlck5hbWUpCiAgICB7CiAgICAgICAgaWYgKHdlYnNlcnZlciAhPSBudWxsKQogICAgICAgIHsKICAgICAgICAgICAgd2Vic2VydmVyLnJlbW92ZUhhbmRsZXIoaGFuZGxlck5hbWUpOwogICAgICAgIH0KCiAgICAgICAgc2VydmVyLnJlbW92ZUhhbmRsZXIoaGFuZGxlck5hbWUpOwogICAgfQoKICAgIC8qKgogICAgICogSGFuZGxlIGFuIFhNTC1SUEMgcmVxdWVzdCB1c2luZyB0aGUgZW5jYXBzdWxhdGVkIHNlcnZlci4KICAgICAqCiAgICAgKiBZb3UgY2FuIHVzZSB0aGlzIG1ldGhvZCB0byBoYW5kbGUgYSByZXF1ZXN0IGZyb20gd2l0aGluCiAgICAgKiBhIFR1cmJpbmUgc2NyZWVuLgogICAgICoKICAgICAqIEBwYXJhbSBpcyB0aGUgc3RyZWFtIHRvIHJlYWQgcmVxdWVzdCBkYXRhIGZyb20uCiAgICAgKiBAcmV0dXJuIHRoZSByZXNwb25zZSBib2R5IHRoYXQgbmVlZHMgdG8gYmUgc2VudCB0byB0aGUgY2xpZW50LgogICAgICovCiAgICBwdWJsaWMgYnl0ZVtdIGhhbmRsZVJlcXVlc3QoSW5wdXRTdHJlYW0gaXMpCiAgICB7CiAgICAgICAgcmV0dXJuIHNlcnZlci5leGVjdXRlKGlzKTsKICAgIH0KCiAgICAvKioKICAgICAqIEhhbmRsZSBhbiBYTUwtUlBDIHJlcXVlc3QgdXNpbmcgdGhlIGVuY2Fwc3VsYXRlZCBzZXJ2ZXIgd2l0aCB1c2VyCiAgICAgKiBhdXRoZW50aWNhdGlvbi4KICAgICAqCiAgICAgKiBZb3UgY2FuIHVzZSB0aGlzIG1ldGhvZCB0byBoYW5kbGUgYSByZXF1ZXN0IGZyb20gd2l0aGluCiAgICAgKiBhIFR1cmJpbmUgc2NyZWVuLgogICAgICoKICAgICAqIDxwPiBOb3RlIHRoYXQgdGhlIGhhbmRsZXJzIG5lZWQgdG8gaW1wbGVtZW50IEF1dGhlbnRpY2F0ZWRYbWxScGNIYW5kbGVyCiAgICAgKiBpbnRlcmZhY2UgdG8gYWNjZXNzIHRoZSBhdXRoZW50aWNhdGlvbiBpbmZvbXJhdGlvbi4KICAgICAqCiAgICAgKiBAcGFyYW0gaXMgdGhlIHN0cmVhbSB0byByZWFkIHJlcXVlc3QgZGF0YSBmcm9tLgogICAgICogQHBhcmFtIHVzZXIgdGhlIHVzZXIgdGhhdCBpcyBtYWtpbmcgdGhlIHJlcXVlc3QuCiAgICAgKiBAcGFyYW0gcGFzc3dvcmQgdGhlIHBhc3N3b3JkIGdpdmVuIGJ5IHVzZXIuCiAgICAgKiBAcmV0dXJuIHRoZSByZXNwb25zZSBib2R5IHRoYXQgbmVlZHMgdG8gYmUgc2VudCB0byB0aGUgY2xpZW50LgogICAgICovCiAgICBwdWJsaWMgYnl0ZVtdIGhhbmRsZVJlcXVlc3QoSW5wdXRTdHJlYW0gaXMsIFN0cmluZyB1c2VyLCBTdHJpbmcgcGFzc3dvcmQpCiAgICB7CiAgICAgICAgcmV0dXJuIHNlcnZlci5leGVjdXRlKGlzLCB1c2VyLCBwYXNzd29yZCk7CiAgICB9CgogICAgLyoqCiAgICAgKiBDbGllbnQncyBpbnRlcmZhY2UgdG8gWE1MLVJQQy4KICAgICAqCiAgICAgKiBUaGUgcmV0dXJuIHR5cGUgaXMgT2JqZWN0IHdoaWNoIHlvdSdsbCBuZWVkIHRvIGNhc3QgdG8KICAgICAqIHdoYXRldmVyIHlvdSBhcmUgZXhwZWN0aW5nLgogICAgICoKICAgICAqIEBwYXJhbSB1cmwgQSBVUkwuCiAgICAgKiBAcGFyYW0gbWV0aG9kTmFtZSBBIFN0cmluZyB3aXRoIHRoZSBtZXRob2QgbmFtZS4KICAgICAqIEBwYXJhbSBwYXJhbXMgQSBWZWN0b3Igd2l0aCB0aGUgcGFyYW1ldGVycy4KICAgICAqIEByZXR1cm4gQW4gT2JqZWN0LgogICAgICogQGV4Y2VwdGlvbiBUdXJiaW5lRXhjZXB0aW9uCiAgICAgKi8KICAgIHB1YmxpYyBPYmplY3QgZXhlY3V0ZVJwYyhVUkwgdXJsLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgIFN0cmluZyBtZXRob2ROYW1lLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgIFZlY3RvciBwYXJhbXMpCiAgICAgICAgICAgIHRocm93cyBUdXJiaW5lRXhjZXB0aW9uCiAgICB7CiAgICAgICAgdHJ5CiAgICAgICAgewogICAgICAgICAgICBYbWxScGNDbGllbnQgY2xpZW50ID0gbmV3IFhtbFJwY0NsaWVudCh1cmwpOwogICAgICAgICAgICByZXR1cm4gY2xpZW50LmV4ZWN1dGUobWV0aG9kTmFtZSwgcGFyYW1zKTsKICAgICAgICB9CiAgICAgICAgY2F0Y2ggKEV4Y2VwdGlvbiBlKQogICAgICAgIHsKICAgICAgICAgICAgdGhyb3cgbmV3IFR1cmJpbmVFeGNlcHRpb24oIlhNTC1SUEMgY2FsbCBmYWlsZWQiLCBlKTsKICAgICAgICB9CiAgICB9CgogICAgLyoqCiAgICAgKiBDbGllbnQncyBBdXRoZW50aWNhdGVkIGludGVyZmFjZSB0byBYTUwtUlBDLgogICAgICoKICAgICAqIFRoZSByZXR1cm4gdHlwZSBpcyBPYmplY3Qgd2hpY2ggeW91J2xsIG5lZWQgdG8gY2FzdCB0bwogICAgICogd2hhdGV2ZXIgeW91IGFyZSBleHBlY3RpbmcuCiAgICAgKgogICAgICogQHBhcmFtIHVybCBBIFVSTC4KICAgICAqIEBwYXJhbSB1c2VybmFtZSBUaGUgdXNlcm5hbWUgdG8gdHJ5IGFuZCBhdXRoZW50aWNhdGUgd2l0aAogICAgICogQHBhcmFtIHBhc3N3b3JkIFRoZSBwYXNzd29yZCB0byB0cnkgYW5kIGF1dGhlbnRpY2F0ZSB3aXRoCiAgICAgKiBAcGFyYW0gbWV0aG9kTmFtZSBBIFN0cmluZyB3aXRoIHRoZSBtZXRob2QgbmFtZS4KICAgICAqIEBwYXJhbSBwYXJhbXMgQSBWZWN0b3Igd2l0aCB0aGUgcGFyYW1ldGVycy4KICAgICAqIEByZXR1cm4gQW4gT2JqZWN0LgogICAgICogQHRocm93cyBUdXJiaW5lRXhjZXB0aW9uCiAgICAgKi8KICAgIHB1YmxpYyBPYmplY3QgZXhlY3V0ZUF1dGhlbnRpY2F0ZWRScGMoVVJMIHVybCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgU3RyaW5nIHVzZXJuYW1lLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBTdHJpbmcgcGFzc3dvcmQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFN0cmluZyBtZXRob2ROYW1lLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBWZWN0b3IgcGFyYW1zKQogICAgICAgICAgICB0aHJvd3MgVHVyYmluZUV4Y2VwdGlvbgogICAgewogICAgICAgIHRyeQogICAgICAgIHsKICAgICAgICAgICAgWG1sUnBjQ2xpZW50IGNsaWVudCA9IG5ldyBYbWxScGNDbGllbnQodXJsKTsKICAgICAgICAgICAgY2xpZW50LnNldEJhc2ljQXV0aGVudGljYXRpb24odXNlcm5hbWUsIHBhc3N3b3JkKTsKICAgICAgICAgICAgcmV0dXJuIGNsaWVudC5leGVjdXRlKG1ldGhvZE5hbWUsIHBhcmFtcyk7CiAgICAgICAgfQogICAgICAgIGNhdGNoIChFeGNlcHRpb24gZSkKICAgICAgICB7CiAgICAgICAgICAgIHRocm93IG5ldyBUdXJiaW5lRXhjZXB0aW9uKCJYTUwtUlBDIGNhbGwgZmFpbGVkIiwgZSk7CiAgICAgICAgfQogICAgfQoKICAgIC8qKgogICAgICogTWV0aG9kIHRvIGFsbG93IGEgY2xpZW50IHRvIHNlbmQgYSBmaWxlIHRvIGEgc2VydmVyLgogICAgICoKICAgICAqIEBwYXJhbSBzZXJ2ZXJVUkwKICAgICAqIEBwYXJhbSBzb3VyY2VMb2NhdGlvblByb3BlcnR5CiAgICAgKiBAcGFyYW0gc291cmNlRmlsZU5hbWUKICAgICAqIEBwYXJhbSBkZXN0aW5hdGlvbkxvY2F0aW9uUHJvcGVydHkKICAgICAqIEBwYXJhbSBkZXN0aW5hdGlvbkZpbGVOYW1lCiAgICAgKiBAZGVwcmVjYXRlZCBUaGlzIGlzIG5vdCBzY29wZSBvZiB0aGUgU2VydmljZSBpdHNlbGYgYnV0IG9mIGFuCiAgICAgKiAgICAgICAgICAgICBhcHBsaWNhdGlvbiB3aGljaCB1c2VzIHRoZSBzZXJ2aWNlLgogICAgICovCiAgICBwdWJsaWMgdm9pZCBzZW5kKFN0cmluZyBzZXJ2ZXJVUkwsCiAgICAgICAgICAgICAgICAgICAgIFN0cmluZyBzb3VyY2VMb2NhdGlvblByb3BlcnR5LAogICAgICAgICAgICAgICAgICAgICBTdHJpbmcgc291cmNlRmlsZU5hbWUsCiAgICAgICAgICAgICAgICAgICAgIFN0cmluZyBkZXN0aW5hdGlvbkxvY2F0aW9uUHJvcGVydHksCiAgICAgICAgICAgICAgICAgICAgIFN0cmluZyBkZXN0aW5hdGlvbkZpbGVOYW1lKQogICAgICAgICAgICB0aHJvd3MgVHVyYmluZUV4Y2VwdGlvbgogICAgewogICAgICAgIEZpbGVUcmFuc2Zlci5zZW5kKHNlcnZlclVSTCwKICAgICAgICAgICAgICAgIHNvdXJjZUxvY2F0aW9uUHJvcGVydHksCiAgICAgICAgICAgICAgICBzb3VyY2VGaWxlTmFtZSwKICAgICAgICAgICAgICAgIGRlc3RpbmF0aW9uTG9jYXRpb25Qcm9wZXJ0eSwKICAgICAgICAgICAgICAgIGRlc3RpbmF0aW9uRmlsZU5hbWUpOwogICAgfQoKICAgIC8qKgogICAgICogTWV0aG9kIHRvIGFsbG93IGEgY2xpZW50IHRvIHNlbmQgYSBmaWxlIHRvIGEgc2VydmVyIHRoYXQKICAgICAqIHJlcXVpcmVzIGF1dGhlbnRpY2F0aW9uCiAgICAgKgogICAgICogQHBhcmFtIHNlcnZlclVSTAogICAgICogQHBhcmFtIHVzZXJuYW1lCiAgICAgKiBAcGFyYW0gcGFzc3dvcmQKICAgICAqIEBwYXJhbSBzb3VyY2VMb2NhdGlvblByb3BlcnR5CiAgICAgKiBAcGFyYW0gc291cmNlRmlsZU5hbWUKICAgICAqIEBwYXJhbSBkZXN0aW5hdGlvbkxvY2F0aW9uUHJvcGVydHkKICAgICAqIEBwYXJhbSBkZXN0aW5hdGlvbkZpbGVOYW1lCiAgICAgKiBAZGVwcmVjYXRlZCBUaGlzIGlzIG5vdCBzY29wZSBvZiB0aGUgU2VydmljZSBpdHNlbGYgYnV0IG9mIGFuCiAgICAgKiAgICAgICAgICAgICBhcHBsaWNhdGlvbiB3aGljaCB1c2VzIHRoZSBzZXJ2aWNlLgogICAgICovCiAgICBwdWJsaWMgdm9pZCBzZW5kKFN0cmluZyBzZXJ2ZXJVUkwsCiAgICAgICAgICAgICAgICAgICAgIFN0cmluZyB1c2VybmFtZSwKICAgICAgICAgICAgICAgICAgICAgU3RyaW5nIHBhc3N3b3JkLAogICAgICAgICAgICAgICAgICAgICBTdHJpbmcgc291cmNlTG9jYXRpb25Qcm9wZXJ0eSwKICAgICAgICAgICAgICAgICAgICAgU3RyaW5nIHNvdXJjZUZpbGVOYW1lLAogICAgICAgICAgICAgICAgICAgICBTdHJpbmcgZGVzdGluYXRpb25Mb2NhdGlvblByb3BlcnR5LAogICAgICAgICAgICAgICAgICAgICBTdHJpbmcgZGVzdGluYXRpb25GaWxlTmFtZSkKICAgICAgICAgICAgdGhyb3dzIFR1cmJpbmVFeGNlcHRpb24KICAgIHsKICAgICAgICBGaWxlVHJhbnNmZXIuc2VuZChzZXJ2ZXJVUkwsCiAgICAgICAgICAgICAgICB1c2VybmFtZSwKICAgICAgICAgICAgICAgIHBhc3N3b3JkLAogICAgICAgICAgICAgICAgc291cmNlTG9jYXRpb25Qcm9wZXJ0eSwKICAgICAgICAgICAgICAgIHNvdXJjZUZpbGVOYW1lLAogICAgICAgICAgICAgICAgZGVzdGluYXRpb25Mb2NhdGlvblByb3BlcnR5LAogICAgICAgICAgICAgICAgZGVzdGluYXRpb25GaWxlTmFtZSk7CiAgICB9CgogICAgLyoqCiAgICAgKiBNZXRob2QgdG8gYWxsb3cgYSBjbGllbnQgdG8gZ2V0IGEgZmlsZSBmcm9tIGEgc2VydmVyLgogICAgICoKICAgICAqIEBwYXJhbSBzZXJ2ZXJVUkwKICAgICAqIEBwYXJhbSBzb3VyY2VMb2NhdGlvblByb3BlcnR5CiAgICAgKiBAcGFyYW0gc291cmNlRmlsZU5hbWUKICAgICAqIEBwYXJhbSBkZXN0aW5hdGlvbkxvY2F0aW9uUHJvcGVydHkKICAgICAqIEBwYXJhbSBkZXN0aW5hdGlvbkZpbGVOYW1lCiAgICAgKiBAZGVwcmVjYXRlZCBUaGlzIGlzIG5vdCBzY29wZSBvZiB0aGUgU2VydmljZSBpdHNlbGYgYnV0IG9mIGFuCiAgICAgKiAgICAgICAgICAgICBhcHBsaWNhdGlvbiB3aGljaCB1c2VzIHRoZSBzZXJ2aWNlLgogICAgICovCiAgICBwdWJsaWMgdm9pZCBnZXQoU3RyaW5nIHNlcnZlclVSTCwKICAgICAgICAgICAgICAgICAgICBTdHJpbmcgc291cmNlTG9jYXRpb25Qcm9wZXJ0eSwKICAgICAgICAgICAgICAgICAgICBTdHJpbmcgc291cmNlRmlsZU5hbWUsCiAgICAgICAgICAgICAgICAgICAgU3RyaW5nIGRlc3RpbmF0aW9uTG9jYXRpb25Qcm9wZXJ0eSwKICAgICAgICAgICAgICAgICAgICBTdHJpbmcgZGVzdGluYXRpb25GaWxlTmFtZSkKICAgICAgICAgICAgdGhyb3dzIFR1cmJpbmVFeGNlcHRpb24KICAgIHsKICAgICAgICBGaWxlVHJhbnNmZXIuZ2V0KHNlcnZlclVSTCwKICAgICAgICAgICAgICAgIHNvdXJjZUxvY2F0aW9uUHJvcGVydHksCiAgICAgICAgICAgICAgICBzb3VyY2VGaWxlTmFtZSwKICAgICAgICAgICAgICAgIGRlc3RpbmF0aW9uTG9jYXRpb25Qcm9wZXJ0eSwKICAgICAgICAgICAgICAgIGRlc3RpbmF0aW9uRmlsZU5hbWUpOwogICAgfQoKICAgIC8qKgogICAgICogTWV0aG9kIHRvIGFsbG93IGEgY2xpZW50IHRvIGdldCBhIGZpbGUgZnJvbSBhIHNlcnZlciB0aGF0CiAgICAgKiByZXF1aXJlcyBhdXRoZW50aWNhdGlvbi4KICAgICAqCiAgICAgKiBAcGFyYW0gc2VydmVyVVJMCiAgICAgKiBAcGFyYW0gdXNlcm5hbWUKICAgICAqIEBwYXJhbSBwYXNzd29yZAogICAgICogQHBhcmFtIHNvdXJjZUxvY2F0aW9uUHJvcGVydHkKICAgICAqIEBwYXJhbSBzb3VyY2VGaWxlTmFtZQogICAgICogQHBhcmFtIGRlc3RpbmF0aW9uTG9jYXRpb25Qcm9wZXJ0eQogICAgICogQHBhcmFtIGRlc3RpbmF0aW9uRmlsZU5hbWUKICAgICAqIEBkZXByZWNhdGVkIFRoaXMgaXMgbm90IHNjb3BlIG9mIHRoZSBTZXJ2aWNlIGl0c2VsZiBidXQgb2YgYW4KICAgICAqICAgICAgICAgICAgIGFwcGxpY2F0aW9uIHdoaWNoIHVzZXMgdGhlIHNlcnZpY2UuCiAgICAgKi8KICAgIHB1YmxpYyB2b2lkIGdldChTdHJpbmcgc2VydmVyVVJMLAogICAgICAgICAgICAgICAgICAgIFN0cmluZyB1c2VybmFtZSwKICAgICAgICAgICAgICAgICAgICBTdHJpbmcgcGFzc3dvcmQsCiAgICAgICAgICAgICAgICAgICAgU3RyaW5nIHNvdXJjZUxvY2F0aW9uUHJvcGVydHksCiAgICAgICAgICAgICAgICAgICAgU3RyaW5nIHNvdXJjZUZpbGVOYW1lLAogICAgICAgICAgICAgICAgICAgIFN0cmluZyBkZXN0aW5hdGlvbkxvY2F0aW9uUHJvcGVydHksCiAgICAgICAgICAgICAgICAgICAgU3RyaW5nIGRlc3RpbmF0aW9uRmlsZU5hbWUpCiAgICAgICAgICAgIHRocm93cyBUdXJiaW5lRXhjZXB0aW9uCiAgICB7CiAgICAgICAgRmlsZVRyYW5zZmVyLmdldChzZXJ2ZXJVUkwsCiAgICAgICAgICAgICAgICB1c2VybmFtZSwKICAgICAgICAgICAgICAgIHBhc3N3b3JkLAogICAgICAgICAgICAgICAgc291cmNlTG9jYXRpb25Qcm9wZXJ0eSwKICAgICAgICAgICAgICAgIHNvdXJjZUZpbGVOYW1lLAogICAgICAgICAgICAgICAgZGVzdGluYXRpb25Mb2NhdGlvblByb3BlcnR5LAogICAgICAgICAgICAgICAgZGVzdGluYXRpb25GaWxlTmFtZSk7CiAgICB9CgogICAgLyoqCiAgICAgKiBNZXRob2QgdG8gYWxsb3cgYSBjbGllbnQgdG8gcmVtb3ZlIGEgZmlsZSBmcm9tCiAgICAgKiB0aGUgc2VydmVyCiAgICAgKgogICAgICogQHBhcmFtIHNlcnZlclVSTAogICAgICogQHBhcmFtIHNvdXJjZUxvY2F0aW9uUHJvcGVydHkKICAgICAqIEBwYXJhbSBzb3VyY2VGaWxlTmFtZQogICAgICogQGRlcHJlY2F0ZWQgVGhpcyBpcyBub3Qgc2NvcGUgb2YgdGhlIFNlcnZpY2UgaXRzZWxmIGJ1dCBvZiBhbgogICAgICogICAgICAgICAgICAgYXBwbGljYXRpb24gd2hpY2ggdXNlcyB0aGUgc2VydmljZS4KICAgICAqLwogICAgcHVibGljIHZvaWQgcmVtb3ZlKFN0cmluZyBzZXJ2ZXJVUkwsCiAgICAgICAgICAgICAgICAgICAgICAgU3RyaW5nIHNvdXJjZUxvY2F0aW9uUHJvcGVydHksCiAgICAgICAgICAgICAgICAgICAgICAgU3RyaW5nIHNvdXJjZUZpbGVOYW1lKQogICAgICAgICAgICB0aHJvd3MgVHVyYmluZUV4Y2VwdGlvbgogICAgewogICAgICAgIEZpbGVUcmFuc2Zlci5yZW1vdmUoc2VydmVyVVJMLAogICAgICAgICAgICAgICAgc291cmNlTG9jYXRpb25Qcm9wZXJ0eSwKICAgICAgICAgICAgICAgIHNvdXJjZUZpbGVOYW1lKTsKICAgIH0KCiAgICAvKioKICAgICAqIE1ldGhvZCB0byBhbGxvdyBhIGNsaWVudCB0byByZW1vdmUgYSBmaWxlIGZyb20KICAgICAqIGEgc2VydmVyIHRoYXQgcmVxdWlyZXMgYXV0aGVudGljYXRpb24uCiAgICAgKgogICAgICogQHBhcmFtIHNlcnZlclVSTAogICAgICogQHBhcmFtIHVzZXJuYW1lCiAgICAgKiBAcGFyYW0gcGFzc3dvcmQKICAgICAqIEBwYXJhbSBzb3VyY2VMb2NhdGlvblByb3BlcnR5CiAgICAgKiBAcGFyYW0gc291cmNlRmlsZU5hbWUKICAgICAqIEBkZXByZWNhdGVkIFRoaXMgaXMgbm90IHNjb3BlIG9mIHRoZSBTZXJ2aWNlIGl0c2VsZiBidXQgb2YgYW4KICAgICAqICAgICAgICAgICAgIGFwcGxpY2F0aW9uIHdoaWNoIHVzZXMgdGhlIHNlcnZpY2UuCiAgICAgKi8KICAgIHB1YmxpYyB2b2lkIHJlbW92ZShTdHJpbmcgc2VydmVyVVJMLAogICAgICAgICAgICAgICAgICAgICAgIFN0cmluZyB1c2VybmFtZSwKICAgICAgICAgICAgICAgICAgICAgICBTdHJpbmcgcGFzc3dvcmQsCiAgICAgICAgICAgICAgICAgICAgICAgU3RyaW5nIHNvdXJjZUxvY2F0aW9uUHJvcGVydHksCiAgICAgICAgICAgICAgICAgICAgICAgU3RyaW5nIHNvdXJjZUZpbGVOYW1lKQogICAgICAgICAgICB0aHJvd3MgVHVyYmluZUV4Y2VwdGlvbgogICAgewogICAgICAgIEZpbGVUcmFuc2Zlci5yZW1vdmUoc2VydmVyVVJMLAogICAgICAgICAgICAgICAgdXNlcm5hbWUsCiAgICAgICAgICAgICAgICBwYXNzd29yZCwKICAgICAgICAgICAgICAgIHNvdXJjZUxvY2F0aW9uUHJvcGVydHksCiAgICAgICAgICAgICAgICBzb3VyY2VGaWxlTmFtZSk7CiAgICB9CgogICAgLyoqCiAgICAgKiBTd2l0Y2ggY2xpZW50IGZpbHRlcmluZyBvbi9vZmYuCiAgICAgKgogICAgICogQHBhcmFtIHN0YXRlIFdoZXRoZXIgdG8gZmlsdGVyIGNsaWVudHMuCiAgICAgKgogICAgICogQHNlZSAjYWNjZXB0Q2xpZW50KGphdmEubGFuZy5TdHJpbmcpCiAgICAgKiBAc2VlICNkZW55Q2xpZW50KGphdmEubGFuZy5TdHJpbmcpCiAgICAgKi8KICAgIHB1YmxpYyB2b2lkIHNldFBhcmFub2lkKGJvb2xlYW4gc3RhdGUpCiAgICB7CiAgICAgICAgd2Vic2VydmVyLnNldFBhcmFub2lkKHN0YXRlKTsKICAgIH0KCiAgICAvKioKICAgICAqIEFkZCBhbiBJUCBhZGRyZXNzIHRvIHRoZSBsaXN0IG9mIGFjY2VwdGVkIGNsaWVudHMuIFRoZSBwYXJhbWV0ZXIgY2FuCiAgICAgKiBjb250YWluICcqJyBhcyB3aWxkY2FyZCBjaGFyYWN0ZXIsIGUuZy4gIjE5Mi4xNjguKi4qIi4gWW91IG11c3QKICAgICAqIGNhbGwgc2V0UGFyYW5vaWQodHJ1ZSkgaW4gb3JkZXIgZm9yIHRoaXMgdG8gaGF2ZQogICAgICogYW55IGVmZmVjdC4KICAgICAqCiAgICAgKiBAcGFyYW0gYWRkcmVzcyBUaGUgYWRkcmVzcyB0byBhZGQgdG8gdGhlIGxpc3QuCiAgICAgKgogICAgICogQHNlZSAjZGVueUNsaWVudChqYXZhLmxhbmcuU3RyaW5nKQogICAgICogQHNlZSAjc2V0UGFyYW5vaWQoYm9vbGVhbikKICAgICAqLwogICAgcHVibGljIHZvaWQgYWNjZXB0Q2xpZW50KFN0cmluZyBhZGRyZXNzKQogICAgewogICAgICAgIHdlYnNlcnZlci5hY2NlcHRDbGllbnQoYWRkcmVzcyk7CiAgICB9CgogICAgLyoqCiAgICAgKiBBZGQgYW4gSVAgYWRkcmVzcyB0byB0aGUgbGlzdCBvZiBkZW5pZWQgY2xpZW50cy4gVGhlIHBhcmFtZXRlciBjYW4KICAgICAqIGNvbnRhaW4gJyonIGFzIHdpbGRjYXJkIGNoYXJhY3RlciwgZS5nLiAiMTkyLjE2OC4qLioiLiBZb3UgbXVzdCBjYWxsCiAgICAgKiBzZXRQYXJhbm9pZCh0cnVlKSBpbiBvcmRlciBmb3IgdGhpcyB0byBoYXZlIGFueSBlZmZlY3QuCiAgICAgKgogICAgICogQHBhcmFtIGFkZHJlc3MgVGhlIGFkZHJlc3MgdG8gYWRkIHRvIHRoZSBsaXN0LgogICAgICoKICAgICAqIEBzZWUgI2FjY2VwdENsaWVudChqYXZhLmxhbmcuU3RyaW5nKQogICAgICogQHNlZSAjc2V0UGFyYW5vaWQoYm9vbGVhbikKICAgICAqLwogICAgcHVibGljIHZvaWQgZGVueUNsaWVudChTdHJpbmcgYWRkcmVzcykKICAgIHsKICAgICAgICB3ZWJzZXJ2ZXIuZGVueUNsaWVudChhZGRyZXNzKTsKICAgIH0KCiAgICAvKioKICAgICAqIFNodXRzIGRvd24gdGhpcyBzZXJ2aWNlLCBzdG9wcGluZyBydW5uaW5nIHRocmVhZHMuCiAgICAgKi8KICAgIHB1YmxpYyB2b2lkIHNodXRkb3duKCkKICAgIHsKICAgICAgICAvLyBTdG9wIHRoZSBYTUwgUlBDIHNlcnZlci4KICAgICAgICB3ZWJzZXJ2ZXIuc2h1dGRvd24oKTsKCiAgICAgICAgaWYgKCFpc01vZGVyblZlcnNpb24pCiAgICAgICAgewogICAgICAgICAgICAvLyBvcmcuYXBhY2hlLnhtbHJwYy5XZWJTZXJ2ZXIgdXNlZCB0byBibG9jayBpbiBhIGNhbGwgdG8KICAgICAgICAgICAgLy8gU2VydmVyU29ja2V0LmFjY2VwdCgpIHVudGlsIGEgc29ja2V0IGNvbm5lY3Rpb24gd2FzIG1hZGUuCiAgICAgICAgICAgIHRyeQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBTb2NrZXQgaW50ZXJydXB0ID0gbmV3IFNvY2tldChhZGRyZXNzLCBwb3J0KTsKICAgICAgICAgICAgICAgIGludGVycnVwdC5jbG9zZSgpOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGNhdGNoIChFeGNlcHRpb24gbm90U2h1dGRvd24pCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIC8vIEl0J3MgcmVtb3RlbHkgcG9zc2libGUgd2UncmUgbGVhdmluZyBhbiBvcGVuIGxpc3RlbmVyCiAgICAgICAgICAgICAgICAvLyBzb2NrZXQgYXJvdW5kLgogICAgICAgICAgICAgICAgbG9nLndhcm4oWG1sUnBjU2VydmljZS5TRVJWSUNFX05BTUUgKwogICAgICAgICAgICAgICAgICAgICAgICAiSXQncyBwb3NzaWJsZSB0aGUgeG1scnBjIHNlcnZlciB3YXMgbm90ICIgKwogICAgICAgICAgICAgICAgICAgICAgICAic2h1dGRvd246ICIgKyBub3RTaHV0ZG93bi5nZXRNZXNzYWdlKCkpOwogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICBzZXRJbml0KGZhbHNlKTsKICAgIH0KfQo=