LyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogQ29weXJpZ2h0IChjKSAyMDAzLCAyMDA0IElCTSBDb3Jwb3JhdGlvbiBhbmQgb3RoZXJzLgogKiBBbGwgcmlnaHRzIHJlc2VydmVkLiBUaGlzIHByb2dyYW0gYW5kIHRoZSBhY2NvbXBhbnlpbmcgbWF0ZXJpYWxzCiAqIGFyZSBtYWRlIGF2YWlsYWJsZSB1bmRlciB0aGUgdGVybXMgb2YgdGhlIENvbW1vbiBQdWJsaWMgTGljZW5zZSB2MS4wCiAqIHdoaWNoIGFjY29tcGFuaWVzIHRoaXMgZGlzdHJpYnV0aW9uLCBhbmQgaXMgYXZhaWxhYmxlIGF0CiAqIGh0dHA6Ly93d3cuZWNsaXBzZS5vcmcvbGVnYWwvY3BsLXYxMC5odG1sCqAqCiAqIENvbnRyaWJ1dG9yczoKICogICAgSUJNIC0gSW5pdGlhbCBBUEkgYW5kIGltcGxlbWVudGF0aW9uCiAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwpwYWNrYWdlIG9yZy5lY2xpcHNlLndzdC5zZXJ2ZXIudWk7CgppbXBvcnQgamF2YS51dGlsLkFycmF5TGlzdDsKaW1wb3J0IGphdmEudXRpbC5MaXN0OwoKaW1wb3J0IG9yZy5lY2xpcHNlLmNvcmUucnVudGltZS5Db3JlRXhjZXB0aW9uOwppbXBvcnQgb3JnLmVjbGlwc2UuZGVidWcuY29yZS5JTGF1bmNoQ29uZmlndXJhdGlvbjsKaW1wb3J0IG9yZy5lY2xpcHNlLmRlYnVnLmNvcmUuSUxhdW5jaENvbmZpZ3VyYXRpb25Xb3JraW5nQ29weTsKaW1wb3J0IG9yZy5lY2xpcHNlLmRlYnVnLnVpLkFic3RyYWN0TGF1bmNoQ29uZmlndXJhdGlvblRhYjsKaW1wb3J0IG9yZy5lY2xpcHNlLmpmYWNlLmRpYWxvZ3MuRGlhbG9nOwppbXBvcnQgb3JnLmVjbGlwc2Uuc3d0LlNXVDsKaW1wb3J0IG9yZy5lY2xpcHNlLnN3dC5ldmVudHMuU2VsZWN0aW9uRXZlbnQ7CmltcG9ydCBvcmcuZWNsaXBzZS5zd3QuZXZlbnRzLlNlbGVjdGlvbkxpc3RlbmVyOwppbXBvcnQgb3JnLmVjbGlwc2Uuc3d0LmdyYXBoaWNzLkltYWdlOwppbXBvcnQgb3JnLmVjbGlwc2Uuc3d0LmxheW91dC5HcmlkRGF0YTsKaW1wb3J0IG9yZy5lY2xpcHNlLnN3dC5sYXlvdXQuR3JpZExheW91dDsKaW1wb3J0IG9yZy5lY2xpcHNlLnN3dC53aWRnZXRzLkNvbWJvOwppbXBvcnQgb3JnLmVjbGlwc2Uuc3d0LndpZGdldHMuQ29tcG9zaXRlOwppbXBvcnQgb3JnLmVjbGlwc2Uuc3d0LndpZGdldHMuTGFiZWw7CmltcG9ydCBvcmcuZWNsaXBzZS51aS5oZWxwLldvcmtiZW5jaEhlbHA7CgppbXBvcnQgb3JnLmVjbGlwc2Uud3N0LnNlcnZlci5jb3JlLklSdW50aW1lOwppbXBvcnQgb3JnLmVjbGlwc2Uud3N0LnNlcnZlci5jb3JlLklTZXJ2ZXI7CmltcG9ydCBvcmcuZWNsaXBzZS53c3Quc2VydmVyLmNvcmUuU2VydmVyQ29yZTsKaW1wb3J0IG9yZy5lY2xpcHNlLndzdC5zZXJ2ZXIudWkuaW50ZXJuYWwuQ29udGV4dElkczsKaW1wb3J0IG9yZy5lY2xpcHNlLndzdC5zZXJ2ZXIudWkuaW50ZXJuYWwuSW1hZ2VSZXNvdXJjZTsKaW1wb3J0IG9yZy5lY2xpcHNlLndzdC5zZXJ2ZXIudWkuaW50ZXJuYWwuU2VydmVyVUlQbHVnaW47CgpwdWJsaWMgY2xhc3MgU2VydmVyTGF1bmNoQ29uZmlndXJhdGlvblRhYiBleHRlbmRzIEFic3RyYWN0TGF1bmNoQ29uZmlndXJhdGlvblRhYiB7Cglwcm90ZWN0ZWQgU3RyaW5nW10gc2VydmVyVHlwZUlkczsKCglwcm90ZWN0ZWQgQ29tYm8gc2VydmVyQ29tYm87CgkKCXByb3RlY3RlZCBMYWJlbCBydW50aW1lTGFiZWw7Cglwcm90ZWN0ZWQgTGFiZWwgcnVudGltZUxvY2F0aW9uOwoJCglwcm90ZWN0ZWQgSVNlcnZlciBzZXJ2ZXI7CgkKCS8vIGxpc3Qgb2Ygc2VydmVycyB0aGF0IGFyZSBpbiBjb21ibwoJcHJvdGVjdGVkIExpc3Qgc2VydmVyczsKCgkvLyBmbGFnIHRvIGJlIHVzZWQgdG8gZGVjaWRlIHdoZXRoZXIgdG8gZW5hYmxlIGNvbWJvIGluIGxhdW5jaCBjb25maWcgZGlhbG9nCgkvLyBhZnRlciB0aGUgdXNlciByZXF1ZXN0cyBhIGxhdW5jaCwgdGhleSBjYW5ub3QgY2hhbmdlIGl0Cglwcml2YXRlIHN0YXRpYyBmaW5hbCBTdHJpbmcgUkVBRF9PTkxZID0gInJlYWQtb25seSI7CgoJcHVibGljIFNlcnZlckxhdW5jaENvbmZpZ3VyYXRpb25UYWIoKSB7CgkJdGhpcyhuZXcgU3RyaW5nW10geyIqIn0pOwoJfQoKCXB1YmxpYyBTZXJ2ZXJMYXVuY2hDb25maWd1cmF0aW9uVGFiKFN0cmluZ1tdIHNlcnZlclR5cGVJZHMpIHsKCQl0aGlzLnNlcnZlclR5cGVJZHMgPSBzZXJ2ZXJUeXBlSWRzOwoJfQoKCS8qKgoJICogQHNlZSBJTGF1bmNoQ29uZmlndXJhdGlvblRhYiNjcmVhdGVDb250cm9sKENvbXBvc2l0ZSkKCSAqLwoJcHVibGljIHZvaWQgY3JlYXRlQ29udHJvbChDb21wb3NpdGUgcGFyZW50KSB7CgkJQ29tcG9zaXRlIGNvbXBvc2l0ZSA9IG5ldyBDb21wb3NpdGUocGFyZW50LCBTV1QuTk9ORSk7CgkJR3JpZExheW91dCBsYXlvdXQgPSBuZXcgR3JpZExheW91dCgpOwoJCWxheW91dC5tYXJnaW5XaWR0aCA9IDEwOwoJCWxheW91dC5tYXJnaW5IZWlnaHQgPSAxMDsKCQlsYXlvdXQubnVtQ29sdW1ucyA9IDE7CgkJY29tcG9zaXRlLnNldExheW91dChsYXlvdXQpOwoKCQlHcmlkRGF0YSBkYXRhID0gbmV3IEdyaWREYXRhKEdyaWREYXRhLkZJTExfSE9SSVpPTlRBTCk7CgkJY29tcG9zaXRlLnNldExheW91dERhdGEoZGF0YSk7CgoJCUxhYmVsIGxhYmVsID0gbmV3IExhYmVsKGNvbXBvc2l0ZSwgU1dULldSQVApOwoJCWxhYmVsLnNldFRleHQoU2VydmVyVUlQbHVnaW4uZ2V0UmVzb3VyY2UoIiVzZXJ2ZXJMYXVuY2hTZXJ2ZXIiKSk7CgkJbGFiZWwuc2V0TGF5b3V0RGF0YShuZXcgR3JpZERhdGEoR3JpZERhdGEuRklMTF9IT1JJWk9OVEFMKSk7CgkJc2VydmVyQ29tYm8gPSBuZXcgQ29tYm8oY29tcG9zaXRlLCBTV1QuU0lOR0xFIHwgU1dULkJPUkRFUiB8IFNXVC5SRUFEX09OTFkpOwoJCXNlcnZlckNvbWJvLnNldExheW91dERhdGEobmV3IEdyaWREYXRhKEdyaWREYXRhLkZJTExfSE9SSVpPTlRBTCkpOwoJCXNlcnZlckNvbWJvLmFkZFNlbGVjdGlvbkxpc3RlbmVyKG5ldyBTZWxlY3Rpb25MaXN0ZW5lcigpIHsKCQkJcHVibGljIHZvaWQgd2lkZ2V0RGVmYXVsdFNlbGVjdGVkKFNlbGVjdGlvbkV2ZW50IGUpIHsKCQkJCXdpZGdldFNlbGVjdGVkKGUpOwoJCQl9CgkJCXB1YmxpYyB2b2lkIHdpZGdldFNlbGVjdGVkKFNlbGVjdGlvbkV2ZW50IGUpIHsKCQkJCWhhbmRsZVNlcnZlclNlbGVjdGlvbigpOwoJCQl9CgkJfSk7CgkJV29ya2JlbmNoSGVscC5zZXRIZWxwKHNlcnZlckNvbWJvLCBDb250ZXh0SWRzLkxBVU5DSF9DT05GSUdVUkFUSU9OX1NFUlZFUl9DT01CTyk7CgoJCXJ1bnRpbWVMYWJlbCA9IG5ldyBMYWJlbChjb21wb3NpdGUsIFNXVC5OT05FKTsKCQlydW50aW1lTGFiZWwuc2V0TGF5b3V0RGF0YShuZXcgR3JpZERhdGEoR3JpZERhdGEuRklMTF9IT1JJWk9OVEFMKSk7CgkJcnVudGltZUxvY2F0aW9uID0gbmV3IExhYmVsKGNvbXBvc2l0ZSwgU1dULk5PTkUpOwoJCXJ1bnRpbWVMb2NhdGlvbi5zZXRMYXlvdXREYXRhKG5ldyBHcmlkRGF0YShHcmlkRGF0YS5GSUxMX0hPUklaT05UQUwpKTsKCQkKCQkvLyBpbml0aWFsaXplCgkJSVNlcnZlcltdIHNlcnZlcnMyID0gU2VydmVyQ29yZS5nZXRTZXJ2ZXJzKCk7CgkJc2VydmVycyA9IG5ldyBBcnJheUxpc3QoKTsKCQlpZiAoc2VydmVyczIgIT0gbnVsbCkgewoJCQlpbnQgc2l6ZSA9IHNlcnZlcnMyLmxlbmd0aDsKCQkJZm9yIChpbnQgaSA9IDA7IGkgPCBzaXplOyBpKyspIHsKCQkJCUlTZXJ2ZXIgc2VydmVyMiA9IHNlcnZlcnMyW2ldOwoJCQkJaWYgKGlzU3VwcG9ydGVkU2VydmVyKHNlcnZlcjIuZ2V0U2VydmVyVHlwZSgpLmdldElkKCkpKSB7CgkJCQkJc2VydmVyQ29tYm8uYWRkKHNlcnZlcjIuZ2V0TmFtZSgpKTsKCQkJCQlzZXJ2ZXJzLmFkZChzZXJ2ZXIyKTsKCQkJCX0KCQkJfQoJCX0KCgkJLy8gc2VsZWN0IGZpcnN0IGl0ZW0gaW4gbGlzdAoJCWlmIChzZXJ2ZXJDb21iby5nZXRJdGVtQ291bnQoKSA+IDApCgkJCXNlcnZlckNvbWJvLnNlbGVjdCgwKTsKCgkJaGFuZGxlU2VydmVyU2VsZWN0aW9uKCk7CgoJCXNlcnZlckNvbWJvLmZvcmNlRm9jdXMoKTsKCgkJRGlhbG9nLmFwcGx5RGlhbG9nRm9udChjb21wb3NpdGUpOwoJCXNldENvbnRyb2woY29tcG9zaXRlKTsKCX0KCQoJcHJvdGVjdGVkIGJvb2xlYW4gaXNTdXBwb3J0ZWRTZXJ2ZXIoU3RyaW5nIHNlcnZlclR5cGVJZCkgewoJCWlmIChzZXJ2ZXJUeXBlSWRzID09IG51bGwpCgkJCXJldHVybiB0cnVlOwoJCWludCBzaXplID0gc2VydmVyVHlwZUlkcy5sZW5ndGg7CgkJZm9yIChpbnQgaSA9IDA7IGkgPCBzaXplOyBpKyspIHsKCQkJaWYgKG1hdGNoZXMoc2VydmVyVHlwZUlkLCBzZXJ2ZXJUeXBlSWRzW2ldKSkKCQkJCXJldHVybiB0cnVlOwoJCX0KCQlyZXR1cm4gZmFsc2U7Cgl9CgkKCXByb3RlY3RlZCBzdGF0aWMgYm9vbGVhbiBtYXRjaGVzKFN0cmluZyBhLCBTdHJpbmcgYikgewoJCWlmIChhID09IG51bGwgfHwgYiA9PSBudWxsIHx8ICIqIi5lcXVhbHMoYSkgfHwgIioiLmVxdWFscyhiKSB8fCBhLnN0YXJ0c1dpdGgoYikgfHwgYi5zdGFydHNXaXRoKGEpKQoJCQlyZXR1cm4gdHJ1ZTsKCQlyZXR1cm4gZmFsc2U7Cgl9CgkKCXByb3RlY3RlZCB2b2lkIGhhbmRsZVNlcnZlclNlbGVjdGlvbigpIHsKCQlpZiAoc2VydmVycy5pc0VtcHR5KCkpCgkJCXNlcnZlciA9IG51bGw7CgkJZWxzZQoJCQlzZXJ2ZXIgPSAoSVNlcnZlcikgc2VydmVycy5nZXQoc2VydmVyQ29tYm8uZ2V0U2VsZWN0aW9uSW5kZXgoKSk7CgkJSVJ1bnRpbWUgcnVudGltZSA9IG51bGw7CgkJaWYgKHNlcnZlciAhPSBudWxsKSB7CgkJCXJ1bnRpbWUgPSBzZXJ2ZXIuZ2V0UnVudGltZSgpOwoJCQlydW50aW1lTG9jYXRpb24uc2V0VGV4dChTZXJ2ZXJVSVBsdWdpbi5nZXRSZXNvdXJjZSgiJXNlcnZlckxhdW5jaEhvc3QiKSArICIgIiArIHNlcnZlci5nZXRIb3N0KCkpOwoJCX0gZWxzZQoJCQlydW50aW1lTG9jYXRpb24uc2V0VGV4dChTZXJ2ZXJVSVBsdWdpbi5nZXRSZXNvdXJjZSgiJXNlcnZlckxhdW5jaEhvc3QiKSk7CgkJCQoJCWlmIChydW50aW1lICE9IG51bGwpCgkJCXJ1bnRpbWVMYWJlbC5zZXRUZXh0KFNlcnZlclVJUGx1Z2luLmdldFJlc291cmNlKCIlc2VydmVyTGF1bmNoUnVudGltZSIpICsgIiAiICsgcnVudGltZS5nZXROYW1lKCkpOwoJCWVsc2UKCQkJcnVudGltZUxhYmVsLnNldFRleHQoU2VydmVyVUlQbHVnaW4uZ2V0UmVzb3VyY2UoIiVzZXJ2ZXJMYXVuY2hSdW50aW1lIikpOwoKCQlpZiAoc2VydmVyID09IG51bGwpCgkJCXNldEVycm9yTWVzc2FnZShTZXJ2ZXJVSVBsdWdpbi5nZXRSZXNvdXJjZSgiJWVycm9yTm9TZXJ2ZXJTZWxlY3RlZCIpKTsKCQllbHNlIGlmIChzZXJ2ZXIuZ2V0U2VydmVyU3RhdGUoKSAhPSBJU2VydmVyLlNUQVRFX1NUT1BQRUQpCgkJCXNldEVycm9yTWVzc2FnZShTZXJ2ZXJVSVBsdWdpbi5nZXRSZXNvdXJjZSgiJWVycm9yU2VydmVyQWxyZWFkeVJ1bm5pbmciKSk7CgkJZWxzZQoJCQlzZXRFcnJvck1lc3NhZ2UobnVsbCk7CgkJLyppZiAoc2VydmVyICE9IG51bGwpIHsKCQkgc2VydmVyLnNldExhdW5jaERlZmF1bHRzKGNvbmZpZ3VyYXRpb24pOwoJCSB9Ki8KCQl1cGRhdGVMYXVuY2hDb25maWd1cmF0aW9uRGlhbG9nKCk7Cgl9CgoJcHJvdGVjdGVkIHZvaWQgc2V0RXJyb3JNZXNzYWdlKFN0cmluZyBzKSB7CgkJc3VwZXIuc2V0RXJyb3JNZXNzYWdlKHMpOwoJfQoJCglwcm90ZWN0ZWQgdm9pZCB1cGRhdGVMYXVuY2hDb25maWd1cmF0aW9uRGlhbG9nKCkgewoJCXN1cGVyLnVwZGF0ZUxhdW5jaENvbmZpZ3VyYXRpb25EaWFsb2coKTsKCX0KCgkvKioKCSAqIEBzZWUgSUxhdW5jaENvbmZpZ3VyYXRpb25UYWIjc2V0RGVmYXVsdHMoSUxhdW5jaENvbmZpZ3VyYXRpb25Xb3JraW5nQ29weSkKCSAqLwoJcHVibGljIHZvaWQgc2V0RGVmYXVsdHMoSUxhdW5jaENvbmZpZ3VyYXRpb25Xb3JraW5nQ29weSBjb25maWd1cmF0aW9uKSB7CgkJc2V0RXJyb3JNZXNzYWdlKG51bGwpOwoJCWlmIChzZXJ2ZXJDb21ibyAhPSBudWxsKSB7CQoJCQlzZXJ2ZXJDb21iby5zZXRFbmFibGVkKHRydWUpOwoJCQlpZiAoc2VydmVyQ29tYm8uZ2V0SXRlbUNvdW50KCkgPiAwKQoJCQkJc2VydmVyQ29tYm8uc2VsZWN0KDApOwoJCX0KCQkKCQlpZiAoc2VydmVycyAhPSBudWxsKSB7CgkJCXNlcnZlciA9IChJU2VydmVyKSBzZXJ2ZXJzLmdldChzZXJ2ZXJDb21iby5nZXRTZWxlY3Rpb25JbmRleCgpKTsKCQkJaWYgKHNlcnZlciAhPSBudWxsKSB7CgkJCQlzZXJ2ZXIuc2V0TGF1bmNoRGVmYXVsdHMoY29uZmlndXJhdGlvbiwgbnVsbCk7CgkJCX0KCQl9Cgl9CgoJLyoqCgkgKiBAc2VlIElMYXVuY2hDb25maWd1cmF0aW9uVGFiI2luaXRpYWxpemVGcm9tKElMYXVuY2hDb25maWd1cmF0aW9uKQoJICovCglwdWJsaWMgdm9pZCBpbml0aWFsaXplRnJvbShJTGF1bmNoQ29uZmlndXJhdGlvbiBjb25maWd1cmF0aW9uKSB7CgkJc2VydmVyQ29tYm8uc2V0RW5hYmxlZCh0cnVlKTsKCQkvL3JlbW92ZSBlcnJvciBtZXNzYWdlIHRoYXQgb3RoZXIgaW5zdGFuY2VzIG1heSBoYXZlIHNldAoJCXNldEVycm9yTWVzc2FnZShudWxsKTsKCgkJdHJ5IHsKCQkJU3RyaW5nIHNlcnZlcklkID0gY29uZmlndXJhdGlvbi5nZXRBdHRyaWJ1dGUoSVNlcnZlci5BVFRSX1NFUlZFUl9JRCwgIiIpOwoJCQlpZiAoc2VydmVySWQgIT0gbnVsbCAmJiAhc2VydmVySWQuZXF1YWxzKCIiKSkgewoJCQkJc2VydmVyID0gU2VydmVyQ29yZS5maW5kU2VydmVyKHNlcnZlcklkKTsKCgkJCQlpZiAoc2VydmVyID09IG51bGwpIHsgLy9zZXJ2ZXIgbm8gbG9uZ2VyIGV4aXN0cwkJCQkKCQkJCQlzZXRFcnJvck1lc3NhZ2UoU2VydmVyVUlQbHVnaW4uZ2V0UmVzb3VyY2UoIiVlcnJvckludmFsaWRTZXJ2ZXIiKSk7CgkJCQkJLy9zZXJ2ZXJDb21iby5jbGVhclNlbGVjdGlvbigpOyAgLy9hcHBlYXJzIHRvIGJlIGJyb2tlbi4uLmRvZXNuJ3Qgd29yayB3aXRoIHJlYWQgb25seT8JCQkJCQkJCQkJCQkKCQkJCQlzZXJ2ZXJDb21iby5zZXRFbmFibGVkKGZhbHNlKTsKCQkJCQlyZXR1cm47CgkJCQl9CgoJCQkJc2VydmVyQ29tYm8uc2V0VGV4dChzZXJ2ZXIuZ2V0TmFtZSgpKTsKCQkJCWlmIChzZXJ2ZXIuZ2V0U2VydmVyU3RhdGUoKSAhPSBJU2VydmVyLlNUQVRFX1NUT1BQRUQpCgkJCQkJc2V0RXJyb3JNZXNzYWdlKFNlcnZlclVJUGx1Z2luLmdldFJlc291cmNlKCIlZXJyb3JTZXJ2ZXJBbHJlYWR5UnVubmluZyIpKTsKCQkJfSBlbHNlIHsKCQkJCWlmIChzZXJ2ZXJDb21iby5nZXRJdGVtQ291bnQoKSA+IDApCgkJCQkJc2VydmVyQ29tYm8uc2VsZWN0KDApOwoJCQl9CgkJCS8vZmxhZyBzaG91bGQgb25seSBiZSBzZXQgaWYgbGF1bmNoIGhhcyBiZWVuIGF0dGVtcHRlZCBvbiB0aGUgY29uZmlnCgkJCWlmIChjb25maWd1cmF0aW9uLmdldEF0dHJpYnV0ZShSRUFEX09OTFksIGZhbHNlKSkKCQkJCXNlcnZlckNvbWJvLnNldEVuYWJsZWQoZmFsc2UpOwoJCX0gY2F0Y2ggKENvcmVFeGNlcHRpb24gZSkgewoJCQkvLyBpZ25vcmUKCQl9Cgl9CgoJLyoqCgkgKiBAc2VlIElMYXVuY2hDb25maWd1cmF0aW9uVGFiI3BlcmZvcm1BcHBseShJTGF1bmNoQ29uZmlndXJhdGlvbldvcmtpbmdDb3B5KQoJICovCglwdWJsaWMgdm9pZCBwZXJmb3JtQXBwbHkoSUxhdW5jaENvbmZpZ3VyYXRpb25Xb3JraW5nQ29weSBjb25maWd1cmF0aW9uKSB7CgkJaWYgKHNlcnZlciAhPSBudWxsKQoJCQljb25maWd1cmF0aW9uLnNldEF0dHJpYnV0ZShJU2VydmVyLkFUVFJfU0VSVkVSX0lELCBzZXJ2ZXIuZ2V0SWQoKSk7CgkJZWxzZQoJCQljb25maWd1cmF0aW9uLnNldEF0dHJpYnV0ZShJU2VydmVyLkFUVFJfU0VSVkVSX0lELCAoU3RyaW5nKW51bGwpOwoJfQoKCS8qKgoJICogQHNlZSBJTGF1bmNoQ29uZmlndXJhdGlvblRhYiNpc1ZhbGlkKCkgCgkgKi8KCXB1YmxpYyBib29sZWFuIGlzVmFsaWQoKSB7CgkJaWYgKHNlcnZlckNvbWJvLmdldFNlbGVjdGlvbkluZGV4KCkgIT0gLTEpCgkJCXJldHVybiB0cnVlOwoJCXJldHVybiBmYWxzZTsKCX0KCgkvKioKCSAqIEBzZWUgSUxhdW5jaENvbmZpZ3VyYXRpb25UYWIjaXNWYWxpZChJTGF1bmNoQ29uZmlndXJhdGlvbikgCgkgKi8KCXB1YmxpYyBib29sZWFuIGlzVmFsaWQoSUxhdW5jaENvbmZpZ3VyYXRpb24gbGF1bmNoQ29uZmlnKSB7CgkJdHJ5IHsKCQkJU3RyaW5nIGlkID0gbGF1bmNoQ29uZmlnLmdldEF0dHJpYnV0ZShJU2VydmVyLkFUVFJfU0VSVkVSX0lELCAiIik7CgkJCWlmIChpZCAhPSBudWxsICYmICFpZC5lcXVhbHMoIiIpKSB7CgkJCQlJU2VydmVyIHNlcnZlcjIgPSBTZXJ2ZXJDb3JlLmZpbmRTZXJ2ZXIoaWQpOwoJCQkJaWYgKHNlcnZlcjIgPT0gbnVsbCkKCQkJCQlyZXR1cm4gZmFsc2U7CgkJCQlpZiAoc2VydmVyMi5nZXRTZXJ2ZXJTdGF0ZSgpID09IElTZXJ2ZXIuU1RBVEVfU1RPUFBFRCkKCQkJCQlyZXR1cm4gdHJ1ZTsKCQkJfQoJCX0gY2F0Y2ggKENvcmVFeGNlcHRpb24gZSkgewoJCQkvLyBpZ25vcmUKCQl9CgkJcmV0dXJuIGZhbHNlOwoJfQoKCXB1YmxpYyBJbWFnZSBnZXRJbWFnZSgpIHsKCQlyZXR1cm4gSW1hZ2VSZXNvdXJjZS5nZXRJbWFnZShJbWFnZVJlc291cmNlLklNR19TRVJWRVIpOwoJfQoKCS8qKgoJICogQHNlZSBJTGF1bmNoQ29uZmlndXJhdGlvblRhYiNnZXROYW1lKCkKCSAqLwoJcHVibGljIFN0cmluZyBnZXROYW1lKCkgewoJCXJldHVybiBTZXJ2ZXJVSVBsdWdpbi5nZXRSZXNvdXJjZSgiJXNlcnZlckxhdW5jaENvbmZpZ3VyYXRpb25UYWIiKTsKCX0KfQ==