LyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogQ29weXJpZ2h0IChjKSAyMDA0IEV0ZXJhdGlvbiBCaWxpc2ltIEEuUy4KICogQWxsIHJpZ2h0cyByZXNlcnZlZC4goCBUaGlzIHByb2dyYW0gYW5kIHRoZSBhY2NvbXBhbnlpbmcgbWF0ZXJpYWxzCiAqIGFyZSBtYWRlIGF2YWlsYWJsZSB1bmRlciB0aGUgdGVybXMgb2YgdGhlIENvbW1vbiBQdWJsaWMgTGljZW5zZSB2MS4wCiAqIHdoaWNoIGFjY29tcGFuaWVzIHRoaXMgZGlzdHJpYnV0aW9uLCBhbmQgaXMgYXZhaWxhYmxlIGF0CiAqIGh0dHA6Ly93d3cuZWNsaXBzZS5vcmcvbGVnYWwvY3BsLXYxMC5odG1sCiAqIAogKiBDb250cmlidXRvcnM6CiAqICAgICBHb3JrZW0gRXJjYW4gLSBpbml0aWFsIEFQSSBhbmQgaW1wbGVtZW50YXRpb24KICogICAgIE5hY2kgTS4gRGFpCiAqIAogKiBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIGBgQVMgSVMnJyBBTkQgQU5ZIEVYUFJFU1NFRCBPUiBJTVBMSUVECiAqIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBUSEUgSU1QTElFRCBXQVJSQU5USUVTCiAqIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFCiAqIERJU0NMQUlNRUQuICBJTiBOTyBFVkVOVCBTSEFMTCBFVEVSQVRJT04gQS5TLiBPUgogKiBJVFMgQ09OVFJJQlVUT1JTIEJFIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsCiAqIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QKICogTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRgogKiBVU0UsIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5ECiAqIE9OIEFOWSBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLAogKiBPUiBUT1JUIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQKICogT0YgVEhFIFVTRSBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GCiAqIFNVQ0ggREFNQUdFLgogKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQogKgogKiBUaGlzIHNvZnR3YXJlIGNvbnNpc3RzIG9mIHZvbHVudGFyeSBjb250cmlidXRpb25zIG1hZGUgYnkgbWFueQogKiBpbmRpdmlkdWFscyBvbiBiZWhhbGYgb2YgdGhlIEV0ZXJhdGlvbiBCaWxpc2ltIEEuUy4gIEZvciBtb3JlCiAqIGluZm9ybWF0aW9uIG9uIGV0ZXJhdGlvbiwgcGxlYXNlIHNlZQogKiA8aHR0cDovL3d3dy5ldGVyYXRpb24uY29tLz4uCiAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCnBhY2thZ2Ugb3JnLmVjbGlwc2UuanN0LnNlcnZlci5nZW5lcmljLmNvcmUuaW50ZXJuYWw7CgppbXBvcnQgamF2YS5uZXQuVVJMOwppbXBvcnQgamF2YS51dGlsLkFycmF5TGlzdDsKaW1wb3J0IGphdmEudXRpbC5IYXNoTWFwOwppbXBvcnQgamF2YS51dGlsLkl0ZXJhdG9yOwppbXBvcnQgamF2YS51dGlsLkxpc3Q7CmltcG9ydCBqYXZhLnV0aWwuTWFwOwppbXBvcnQgb3JnLmVjbGlwc2UuY29yZS5yZXNvdXJjZXMuSVByb2plY3Q7CmltcG9ydCBvcmcuZWNsaXBzZS5jb3JlLnJlc291cmNlcy5SZXNvdXJjZXNQbHVnaW47CmltcG9ydCBvcmcuZWNsaXBzZS5jb3JlLnJ1bnRpbWUuQ29yZUV4Y2VwdGlvbjsKaW1wb3J0IG9yZy5lY2xpcHNlLmNvcmUucnVudGltZS5JUHJvZ3Jlc3NNb25pdG9yOwppbXBvcnQgb3JnLmVjbGlwc2UuY29yZS5ydW50aW1lLklTdGF0dXM7CmltcG9ydCBvcmcuZWNsaXBzZS5jb3JlLnJ1bnRpbWUuU3RhdHVzOwppbXBvcnQgb3JnLmVjbGlwc2UuanN0LnNlcnZlci5nZW5lcmljLnNlcnZlcnR5cGUuZGVmaW5pdGlvbi5Nb2R1bGU7CmltcG9ydCBvcmcuZWNsaXBzZS5qc3Quc2VydmVyLmdlbmVyaWMuc2VydmVydHlwZS5kZWZpbml0aW9uLlBvcnQ7CmltcG9ydCBvcmcuZWNsaXBzZS5qc3Quc2VydmVyLmdlbmVyaWMuc2VydmVydHlwZS5kZWZpbml0aW9uLlNlcnZlclJ1bnRpbWU7CmltcG9ydCBvcmcuZWNsaXBzZS5qc3Quc2VydmVyLmNvcmUuSUVKQk1vZHVsZTsKaW1wb3J0IG9yZy5lY2xpcHNlLmpzdC5zZXJ2ZXIuY29yZS5JRW50ZXJwcmlzZUFwcGxpY2F0aW9uOwppbXBvcnQgb3JnLmVjbGlwc2UuanN0LnNlcnZlci5jb3JlLklXZWJNb2R1bGU7CmltcG9ydCBvcmcuZWNsaXBzZS53c3Quc2VydmVyLmNvcmUuSU1vZHVsZTsKaW1wb3J0IG9yZy5lY2xpcHNlLndzdC5zZXJ2ZXIuY29yZS5TZXJ2ZXJVdGlsOwppbXBvcnQgb3JnLmVjbGlwc2Uud3N0LnNlcnZlci5jb3JlLmludGVybmFsLlNlcnZlck1vbml0b3JNYW5hZ2VyOwppbXBvcnQgb3JnLmVjbGlwc2Uud3N0LnNlcnZlci5jb3JlLm1vZGVsLklVUkxQcm92aWRlcjsKaW1wb3J0IG9yZy5lY2xpcHNlLndzdC5zZXJ2ZXIuY29yZS5tb2RlbC5SdW50aW1lRGVsZWdhdGU7CmltcG9ydCBvcmcuZWNsaXBzZS53c3Quc2VydmVyLmNvcmUubW9kZWwuU2VydmVyRGVsZWdhdGU7CmltcG9ydCBvcmcuZWNsaXBzZS53c3Quc2VydmVyLmNvcmUuU2VydmVyUG9ydDsKCi8qKgogKiBHZW5lcmljIFhNTCBiYXNlZCBzZXJ2ZXIgaW1wbGVtZW50YXRpb24uCiAqIAogKiBAYXV0aG9yIEdvcmtlbSBFcmNhbgogKi8KcHVibGljIGNsYXNzIEdlbmVyaWNTZXJ2ZXIgZXh0ZW5kcyBTZXJ2ZXJEZWxlZ2F0ZSBpbXBsZW1lbnRzIElVUkxQcm92aWRlciB7CgogICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgU3RyaW5nIEFUVFJfR0VORVJJQ19TRVJWRVJfTU9EVUxFUyA9ICJHZW5lcmljX1NlcnZlcl9Nb2R1bGVzX0xpc3QiOwogICAgcHJpdmF0ZSBTZXJ2ZXJSdW50aW1lIGZTZXJ2ZXJEZWZpbml0aW9uOwoKCS8qCgkgKiAobm9uLUphdmFkb2MpCgkgKiAKCSAqIEBzZWUgb3JnLmVjbGlwc2Uud3N0LnNlcnZlci5jb3JlLm1vZGVsLklTZXJ2ZXJEZWxlZ2F0ZSNwdWJsaXNoU3RhcnQob3JnLmVjbGlwc2UuY29yZS5ydW50aW1lLklQcm9ncmVzc01vbml0b3IpCgkgKi8KCXB1YmxpYyBJU3RhdHVzIHB1Ymxpc2hTdGFydChJUHJvZ3Jlc3NNb25pdG9yIG1vbml0b3IpIHsKCSAgICBpZihnZXRNb2R1bGVzKCkubGVuZ3RoPDEpCgkgICAgICAgIHJldHVybiBuZXcgU3RhdHVzKElTdGF0dXMuQ0FOQ0VMLENvcmVQbHVnaW4uUExVR0lOX0lELDAsR2VuZXJpY1NlcnZlckNvcmVNZXNzYWdlcy5nZXRTdHJpbmcoImNhbmNlbE5vUHVibGlzaCIpLG51bGwpOwoJCXJldHVybiBuZXcgU3RhdHVzKElTdGF0dXMuT0ssIENvcmVQbHVnaW4uUExVR0lOX0lELCAwLCAiUHVibGlzaGluZ1N0YXJ0ZWQiLCBudWxsKTsKCX0KCgoJcHVibGljIElTdGF0dXMgY2FuTW9kaWZ5TW9kdWxlcyhJTW9kdWxlW10gYWRkLCBJTW9kdWxlW10gcmVtb3ZlKSB7CgkJSXRlcmF0b3IgaXRlcmF0b3IgPSBnZXRTZXJ2ZXJEZWZpbml0aW9uKCkuZ2V0TW9kdWxlKCkuaXRlcmF0b3IoKTsKICAgICAgIAogICAgICAgIHdoaWxlKGl0ZXJhdG9yLmhhc05leHQoKSkgICB7CgkgICAgICAgIE1vZHVsZSBtb2R1bGUgPSAoTW9kdWxlKWl0ZXJhdG9yLm5leHQoKTsKCSAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBhZGQubGVuZ3RoOyBpKyspIHsKICAgICAgICAgICAgICAgIGlmKGFkZFtpXS5nZXRNb2R1bGVUeXBlKCkuZ2V0SWQoKS5lcXVhbHMobW9kdWxlLmdldFR5cGUoKSkpCiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIG5ldyBTdGF0dXMoSVN0YXR1cy5PSywgQ29yZVBsdWdpbi5QTFVHSU5fSUQsIDAsICJDYW5Nb2RpZnlNb2R1bGVzIiwgbnVsbCk7CiAgICAgICAgICAgIH0KCSAgICB9CgkJcmV0dXJuIG5ldyBTdGF0dXMoSVN0YXR1cy5FUlJPUiwgQ29yZVBsdWdpbi5QTFVHSU5fSUQsIDAsIEdlbmVyaWNTZXJ2ZXJDb3JlTWVzc2FnZXMuZ2V0U3RyaW5nKCJtb2R1bGVOb3RDb21wYXRpYmxlIiksIG51bGwpOwoJfQoJCglwcml2YXRlIFN0cmluZyBjcmVhdGVNb2R1bGVJZChJTW9kdWxlIG1vZHVsZSkKCXsKCSAgICByZXR1cm4gbW9kdWxlLmdldFByb2plY3QoKS5nZXROYW1lKCkrIjoiK21vZHVsZS5nZXRJZCgpOwoJfQogICAgLyogKG5vbi1KYXZhZG9jKQogICAgICogQHNlZSBvcmcuZWNsaXBzZS53c3Quc2VydmVyLmNvcmUubW9kZWwuU2VydmVyRGVsZWdhdGUjbW9kaWZ5TW9kdWxlcyhvcmcuZWNsaXBzZS53c3Quc2VydmVyLmNvcmUuSU1vZHVsZVtdLCBvcmcuZWNsaXBzZS53c3Quc2VydmVyLmNvcmUuSU1vZHVsZVtdLCBvcmcuZWNsaXBzZS5jb3JlLnJ1bnRpbWUuSVByb2dyZXNzTW9uaXRvcikKICAgICAqLwogICAgcHVibGljIHZvaWQgbW9kaWZ5TW9kdWxlcyhJTW9kdWxlW10gYWRkLCBJTW9kdWxlW10gcmVtb3ZlLCBJUHJvZ3Jlc3NNb25pdG9yIG1vbml0b3IpIHRocm93cyBDb3JlRXhjZXB0aW9uIHsKICAgICAgCiAgICAgICAgTGlzdCBtb2R1bGVzID0gdGhpcy5nZXRBdHRyaWJ1dGUoQVRUUl9HRU5FUklDX1NFUlZFUl9NT0RVTEVTLChMaXN0KW51bGwpOwogICAgICAgIAogICAgICAgIGlmKGFkZCE9bnVsbCYmIGFkZC5sZW5ndGg+MCkKICAgICAgICB7CiAgICAgICAgICAgIGlmKG1vZHVsZXM9PW51bGwpIHsKICAgICAgICAgICAgICAgbW9kdWxlcz1uZXcgQXJyYXlMaXN0KGFkZC5sZW5ndGgpOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgYWRkLmxlbmd0aDsgaSsrKSB7CiAgICAgICAgICAgICAgIFN0cmluZyBtb2RsSWQgPSBjcmVhdGVNb2R1bGVJZChhZGRbaV0pOwogICAgICAgICAgICAgICBpZihtb2R1bGVzLmNvbnRhaW5zKG1vZGxJZCk9PWZhbHNlKQogICAgICAgICAgICAgICAgICAgIG1vZHVsZXMuYWRkKG1vZGxJZCk7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgaWYocmVtb3ZlIT1udWxsICYmIHJlbW92ZS5sZW5ndGg+MCAmJiBtb2R1bGVzIT1udWxsKQogICAgICAgIHsKICAgICAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCByZW1vdmUubGVuZ3RoOyBpKyspIHsKICAgICAgICAgICAgICAgIG1vZHVsZXMucmVtb3ZlKGNyZWF0ZU1vZHVsZUlkKHJlbW92ZVtpXSkpOwogICAgICAgICAgICAgfQogICAgICAgIH0KICAgICAgICBpZihtb2R1bGVzIT1udWxsKSAgICAKICAgICAgICAgICAgc2V0QXR0cmlidXRlKEFUVFJfR0VORVJJQ19TRVJWRVJfTU9EVUxFUyxtb2R1bGVzKTsKICAgICAgICAKICAgIH0KCiAgICAKICAgIAoJLyoKCSAqIChub24tSmF2YWRvYykKCSAqIAoJICogQHNlZSBvcmcuZWNsaXBzZS53c3Quc2VydmVyLmNvcmUubW9kZWwuSVNlcnZlckRlbGVnYXRlI2dldE1vZHVsZXMoKQoJICovCglwdWJsaWMgb3JnLmVjbGlwc2Uud3N0LnNlcnZlci5jb3JlLklNb2R1bGVbXSBnZXRNb2R1bGVzKCkgewoJCUxpc3QgbW9kdWxlcyA9IGdldEF0dHJpYnV0ZShBVFRSX0dFTkVSSUNfU0VSVkVSX01PRFVMRVMsKExpc3QpbnVsbCk7CgkJTGlzdCBpbW9kdWxlcyA9IG5ldyBBcnJheUxpc3QoKTsKCQlJdGVyYXRvciBpdGVyYXRvciA9IG1vZHVsZXMuaXRlcmF0b3IoKTsKCQl3aGlsZShpdGVyYXRvci5oYXNOZXh0KCkpCgkJewoJCSAgICBTdHJpbmcgbW9kdWxlSWQgPSAoU3RyaW5nKWl0ZXJhdG9yLm5leHQoKTsKCQkgICAgaW50IHNlcCA9IG1vZHVsZUlkLmluZGV4T2YoIjoiKTsKCQkgICAgSVByb2plY3QgcHJvamVjdCA9UmVzb3VyY2VzUGx1Z2luLmdldFdvcmtzcGFjZSgpLmdldFJvb3QoKS5nZXRQcm9qZWN0KG1vZHVsZUlkLnN1YnN0cmluZygwLHNlcCkpOwoJCSAgICBJTW9kdWxlW10gbXMgPSBTZXJ2ZXJVdGlsLmdldE1vZHVsZXMocHJvamVjdCk7CgkJICAgIGZvciAoaW50IGkgPSAwOyBpIDwgbXMubGVuZ3RoOyBpKyspIHsKICAgICAgICAgICAgICAgIGlmKG1zW2ldLmdldElkKCkuZXF1YWxzKG1vZHVsZUlkLnN1YnN0cmluZyhzZXArMSkpKQogICAgICAgICAgICAgICAgCWltb2R1bGVzLmFkZChtc1tpXSk7CiAgICAgICAgICAgIH0KCQoJCX0KCQlpZihtb2R1bGVzIT0gbnVsbCkKCQkgICAgcmV0dXJuIChJTW9kdWxlW10paW1vZHVsZXMudG9BcnJheShuZXcgSU1vZHVsZVtpbW9kdWxlcy5zaXplKCldKTsKCQlyZXR1cm4gbmV3IElNb2R1bGVbMF07Cgl9CgoKCgkvKgoJICogKG5vbi1KYXZhZG9jKQoJICogCgkgKiBAc2VlIG9yZy5lY2xpcHNlLndzdC5zZXJ2ZXIuY29yZS5tb2RlbC5JU2VydmVyRGVsZWdhdGUjZ2V0Q2hpbGRNb2R1bGVzKG9yZy5lY2xpcHNlLndzdC5zZXJ2ZXIuY29yZS5tb2RlbC5JTW9kdWxlW10pCgkgKi8KCXB1YmxpYyBJTW9kdWxlW10gZ2V0Q2hpbGRNb2R1bGVzKElNb2R1bGVbXSBtb2R1bGUpIHsKCQkvLyBUT0RPIEF1dG8tZ2VuZXJhdGVkIG1ldGhvZCBzdHViCgkJcmV0dXJuIG5ldyBJTW9kdWxlWzBdOwoJfQoKCS8qKgoJICogQHJldHVybgoJICovCglwcml2YXRlIE1hcCBnZXRTZXJ2ZXJJbnN0YW5jZVByb3BlcnRpZXMoKSB7CgkJTWFwIHJ1bnRpbWVQcm9wZXJ0aWVzID1nZXRSdW50aW1lRGVsZWdhdGUoKS5nZXRBdHRyaWJ1dGUoCgkJCQlHZW5lcmljU2VydmVyUnVudGltZS5TRVJWRVJfSU5TVEFOQ0VfUFJPUEVSVElFUywgbmV3IEhhc2hNYXAoKSk7CgkJTWFwIHNlcnZlclByb3BlcnRpZXMgPSBnZXRBdHRyaWJ1dGUoR2VuZXJpY1NlcnZlclJ1bnRpbWUuU0VSVkVSX0lOU1RBTkNFX1BST1BFUlRJRVMsbmV3IEhhc2hNYXAoMSkpOwoJCU1hcCBpbnN0YW5jZVByb3BlcnRpZXMgPSBuZXcgSGFzaE1hcChydW50aW1lUHJvcGVydGllcy5zaXplKCkrc2VydmVyUHJvcGVydGllcy5zaXplKCkpOwoJCWluc3RhbmNlUHJvcGVydGllcy5wdXRBbGwocnVudGltZVByb3BlcnRpZXMpOwoJCWluc3RhbmNlUHJvcGVydGllcy5wdXRBbGwoc2VydmVyUHJvcGVydGllcyk7CgkJcmV0dXJuIGluc3RhbmNlUHJvcGVydGllczsKCX0KCQogCQoJLyoKCSAqIChub24tSmF2YWRvYykKCSAqIAoJICogQHNlZSBvcmcuZWNsaXBzZS53c3Quc2VydmVyLmNvcmUubW9kZWwuSU1vbml0b3JhYmxlU2VydmVyI2dldFNlcnZlclBvcnRzKCkKCSAqLwoJcHVibGljIG9yZy5lY2xpcHNlLndzdC5zZXJ2ZXIuY29yZS5TZXJ2ZXJQb3J0W10gZ2V0U2VydmVyUG9ydHMoKSB7CgkJTGlzdCBwb3J0cyA9IG5ldyBBcnJheUxpc3QoKTsKCQlJdGVyYXRvciBwSXRlciA9IHRoaXMuZ2V0U2VydmVyRGVmaW5pdGlvbigpLmdldFBvcnQoKS5pdGVyYXRvcigpOwoJCXdoaWxlIChwSXRlci5oYXNOZXh0KCkpIHsKCQkJUG9ydCBlbGVtZW50ID0gKFBvcnQpIHBJdGVyLm5leHQoKTsKCQkJaW50IHBvcnQgPSBJbnRlZ2VyLnBhcnNlSW50KGdldFNlcnZlckRlZmluaXRpb24oKS5nZXRSZXNvbHZlcigpLnJlc29sdmVQcm9wZXJ0aWVzKGVsZW1lbnQuZ2V0Tm8oKSkpOwoJCQlwb3J0cy5hZGQobmV3IFNlcnZlclBvcnQoInNlcnZlciIsIGVsZW1lbnQuZ2V0TmFtZSgpLCBwb3J0LCBlbGVtZW50LmdldFByb3RvY29sKCkpKTsJCQoJCX0KCQoJCXJldHVybiAob3JnLmVjbGlwc2Uud3N0LnNlcnZlci5jb3JlLlNlcnZlclBvcnRbXSlwb3J0cy50b0FycmF5KG5ldyBvcmcuZWNsaXBzZS53c3Quc2VydmVyLmNvcmUuU2VydmVyUG9ydFtwb3J0cy5zaXplKCldKTsKCX0KCgoJLyogKG5vbi1KYXZhZG9jKQoJICogQHNlZSBvcmcuZWNsaXBzZS53dHAuc2VydmVyLmNvcmUubW9kZWwuSVVSTFByb3ZpZGVyI2dldE1vZHVsZVJvb3RVUkwob3JnLmVjbGlwc2Uud3RwLnNlcnZlci5jb3JlLm1vZGVsLklNb2R1bGUpCgkgKi8KCXB1YmxpYyBVUkwgZ2V0TW9kdWxlUm9vdFVSTChJTW9kdWxlIG1vZHVsZSkgewoKCQl0cnkgewkJCQogICAgICAgICAgICBpZiAobW9kdWxlID09IG51bGwgfHwgbW9kdWxlLmdldEFkYXB0ZXIoSVdlYk1vZHVsZS5jbGFzcyk9PW51bGwgKQoJCQkJcmV0dXJuIG51bGw7CgoJCQlTdHJpbmcgdXJsID0gImh0dHA6Ly9sb2NhbGhvc3QiOwoJCQlpbnQgcG9ydCA9IDA7CgkJCQoJCQlwb3J0ID0gZ2V0SHR0cFBvcnQoKTsKCQkJcG9ydCA9U2VydmVyTW9uaXRvck1hbmFnZXIuZ2V0SW5zdGFuY2UoKS5nZXRNb25pdG9yZWRQb3J0KGdldFNlcnZlcigpLCBwb3J0LCAid2ViIik7CgkJCWlmIChwb3J0ICE9IDgwKQoJCQkJdXJsICs9ICI6IiArIHBvcnQ7CgoJCQl1cmwgKz0gIi8iK21vZHVsZS5nZXROYW1lKCk7CgoJCQlpZiAoIXVybC5lbmRzV2l0aCgiLyIpKQoJCQkJdXJsICs9ICIvIjsKCgkJCXJldHVybiBuZXcgVVJMKHVybCk7CgkJfSBjYXRjaCAoRXhjZXB0aW9uIGUpIHsKCQkJVHJhY2UudHJhY2UoIkNvdWxkIG5vdCBnZXQgcm9vdCBVUkwiLCBlKTsKCQkJcmV0dXJuIG51bGw7CgkJfQoKCX0KCgkvKioKCSAqIEByZXR1cm4KCSAqLwoJcHJpdmF0ZSBpbnQgZ2V0SHR0cFBvcnQoKSB7CgkJaW50IHBvcnQ9LTE7CgkJSXRlcmF0b3IgcEl0ZXIgPSB0aGlzLmdldFNlcnZlckRlZmluaXRpb24oKS5nZXRQb3J0KCkuaXRlcmF0b3IoKTsKCQl3aGlsZSAocEl0ZXIuaGFzTmV4dCgpKSB7CgkJCVBvcnQgYVBvcnQgPSAoUG9ydCkgcEl0ZXIubmV4dCgpOwoJCQlpZihwb3J0PT0gLTEpCgkJCQlwb3J0ID0gSW50ZWdlci5wYXJzZUludChnZXRTZXJ2ZXJEZWZpbml0aW9uKCkuZ2V0UmVzb2x2ZXIoKS5yZXNvbHZlUHJvcGVydGllcyhhUG9ydC5nZXRObygpKSk7CgkJCWVsc2UgaWYoICJodHRwIi5lcXVhbHMoYVBvcnQuZ2V0UHJvdG9jb2woKSApICkKCQkJCXBvcnQgPSBJbnRlZ2VyLnBhcnNlSW50KGFQb3J0LmdldE5vKCkpOwkKCQl9CgkJaWYoIHBvcnQgPT0gLTEpCgkJCXBvcnQgPSA4MDgwOwoJCXJldHVybiBwb3J0OwoJfQoKICAgIHB1YmxpYyBTZXJ2ZXJSdW50aW1lIGdldFNlcnZlckRlZmluaXRpb24oKSB7CiAgICAJaWYgKGZTZXJ2ZXJEZWZpbml0aW9uID09IG51bGwpCiAgICAJCWZTZXJ2ZXJEZWZpbml0aW9uID0gQ29yZVBsdWdpbi5nZXREZWZhdWx0KCkKICAgIAkJCQkuZ2V0U2VydmVyVHlwZURlZmluaXRpb25NYW5hZ2VyKCkKICAgIAkJCQkuZ2V0U2VydmVyUnVudGltZURlZmluaXRpb24oZ2V0UnVudGltZURlbGVnYXRlKCkuZ2V0QXR0cmlidXRlKAogICAgCQkJCQkJCQlHZW5lcmljU2VydmVyUnVudGltZS5TRVJWRVJfREVGSU5JVElPTl9JRCwKICAgIAkJCQkJCQkJIiIpLCBnZXRTZXJ2ZXJJbnN0YW5jZVByb3BlcnRpZXMoKSk7CiAgICAJcmV0dXJuIGZTZXJ2ZXJEZWZpbml0aW9uOwogICAgfQoKICAgIHByaXZhdGUgUnVudGltZURlbGVnYXRlIGdldFJ1bnRpbWVEZWxlZ2F0ZSgpCiAgICB7CiAgICAgICByZXR1cm4gKFJ1bnRpbWVEZWxlZ2F0ZSlnZXRTZXJ2ZXIoKS5nZXRSdW50aW1lKCkuZ2V0QWRhcHRlcihSdW50aW1lRGVsZWdhdGUuY2xhc3MpOwogICAgfQoKCiAgICAvKgogICAgICogKG5vbi1KYXZhZG9jKQogICAgICogCiAgICAgKiBAc2VlIG9yZy5lY2xpcHNlLndzdC5zZXJ2ZXIuY29yZS5tb2RlbC5TZXJ2ZXJEZWxlZ2F0ZSNnZXRSb290TW9kdWxlcyhvcmcuZWNsaXBzZS53c3Quc2VydmVyLmNvcmUuSU1vZHVsZSkKICAgICAqLwogICAgcHVibGljIElNb2R1bGVbXSBnZXRSb290TW9kdWxlcyhJTW9kdWxlIG1vZHVsZSkgdGhyb3dzIENvcmVFeGNlcHRpb24gewoKICAgICAgICBTdHJpbmcgdHlwZSA9IG1vZHVsZS5nZXRNb2R1bGVUeXBlKCkuZ2V0SWQoKTsKCiAgICAgICAgaWYgKHR5cGUuZXF1YWxzKCJqMmVlLmVqYiIpKSB7CiAgICAgICAgICAgIElFSkJNb2R1bGUgZWpiTW9kdWxlID0gKElFSkJNb2R1bGUpIG1vZHVsZS5nZXRBZGFwdGVyKElFSkJNb2R1bGUuY2xhc3MpOwogICAgICAgICAgICBpZiAoZWpiTW9kdWxlICE9IG51bGwpIHsKICAgICAgICAgICAgICAgIElTdGF0dXMgc3RhdHVzID0gY2FuTW9kaWZ5TW9kdWxlcyhuZXcgSU1vZHVsZVtdIHsgbW9kdWxlIH0sCiAgICAgICAgICAgICAgICAgICAgICAgIG51bGwpOwogICAgICAgICAgICAgICAgaWYgKHN0YXR1cyA9PSBudWxsIHx8ICFzdGF0dXMuaXNPSygpKQogICAgICAgICAgICAgICAgICAgIHRocm93IG5ldyBDb3JlRXhjZXB0aW9uKHN0YXR1cyk7CiAgICAgICAgICAgICAgICByZXR1cm4gbmV3IElNb2R1bGVbXSB7IG1vZHVsZSB9OwogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICBpZiAodHlwZS5lcXVhbHMoImoyZWUuZWFyIikpIHsKCiAgICAgICAgICAgIElFbnRlcnByaXNlQXBwbGljYXRpb24gZW50ZXJwcmlzZUFwcGxpY2F0aW9uID0gKElFbnRlcnByaXNlQXBwbGljYXRpb24pIG1vZHVsZS5nZXRBZGFwdGVyKElFbnRlcnByaXNlQXBwbGljYXRpb24uY2xhc3MpOwogICAgICAgICAgICBpZiAoZW50ZXJwcmlzZUFwcGxpY2F0aW9uICE9IG51bGwpIHsKICAgICAgICAgICAgICAgIElTdGF0dXMgc3RhdHVzID0gY2FuTW9kaWZ5TW9kdWxlcyhuZXcgSU1vZHVsZVtdIHsgbW9kdWxlIH0sCiAgICAgICAgICAgICAgICAgICAgICAgIG51bGwpOwogICAgICAgICAgICAgICAgaWYgKHN0YXR1cyA9PSBudWxsIHx8ICFzdGF0dXMuaXNPSygpKQogICAgICAgICAgICAgICAgICAgIHRocm93IG5ldyBDb3JlRXhjZXB0aW9uKHN0YXR1cyk7CiAgICAgICAgICAgICAgICByZXR1cm4gbmV3IElNb2R1bGVbXSB7IG1vZHVsZSB9OwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIAogICAgICAgIGlmICh0eXBlLmVxdWFscygiajJlZS53ZWIiKSkgewoKICAgICAgICAgICAgSVdlYk1vZHVsZSB3ZWJNb2R1bGUgPSAoSVdlYk1vZHVsZSkgbW9kdWxlLmdldEFkYXB0ZXIoSVdlYk1vZHVsZS5jbGFzcyk7CiAgICAgICAgICAgIGlmICh3ZWJNb2R1bGUgIT0gbnVsbCkgewogICAgICAgICAgICAgICAgSVN0YXR1cyBzdGF0dXMgPSBjYW5Nb2RpZnlNb2R1bGVzKG5ldyBJTW9kdWxlW10geyBtb2R1bGUgfSwKICAgICAgICAgICAgICAgICAgICAgICAgbnVsbCk7CiAgICAgICAgICAgICAgICBpZiAoc3RhdHVzID09IG51bGwgfHwgIXN0YXR1cy5pc09LKCkpCiAgICAgICAgICAgICAgICAgICAgdGhyb3cgbmV3IENvcmVFeGNlcHRpb24oc3RhdHVzKTsKICAgICAgICAgICAgICAgIHJldHVybiBuZXcgSU1vZHVsZVtdIHsgbW9kdWxlIH07CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIHJldHVybiBudWxsOwogICAgfQoKfQ==