LyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogQ29weXJpZ2h0IChjKSAyMDAzLCAyMDA0IElCTSBDb3Jwb3JhdGlvbiBhbmQgb3RoZXJzLgogKiBBbGwgcmlnaHRzIHJlc2VydmVkLiBUaGlzIHByb2dyYW0gYW5kIHRoZSBhY2NvbXBhbnlpbmcgbWF0ZXJpYWxzCiAqIGFyZSBtYWRlIGF2YWlsYWJsZSB1bmRlciB0aGUgdGVybXMgb2YgdGhlIENvbW1vbiBQdWJsaWMgTGljZW5zZSB2MS4wCiAqIHdoaWNoIGFjY29tcGFuaWVzIHRoaXMgZGlzdHJpYnV0aW9uLCBhbmQgaXMgYXZhaWxhYmxlIGF0CiAqIGh0dHA6Ly93d3cuZWNsaXBzZS5vcmcvbGVnYWwvY3BsLXYxMC5odG1sCqAqCiAqIENvbnRyaWJ1dG9yczoKICogICAgSUJNIC0gSW5pdGlhbCBBUEkgYW5kIGltcGxlbWVudGF0aW9uCiAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwpwYWNrYWdlIG9yZy5lY2xpcHNlLndzdC5zZXJ2ZXIudWkuaW50ZXJuYWw7CgppbXBvcnQgamF2YS51dGlsLkFycmF5TGlzdDsKaW1wb3J0IGphdmEudXRpbC5JdGVyYXRvcjsKaW1wb3J0IGphdmEudXRpbC5MaXN0OwoKaW1wb3J0IG9yZy5lY2xpcHNlLmRlYnVnLmNvcmUuSUxhdW5jaE1hbmFnZXI7CmltcG9ydCBvcmcuZWNsaXBzZS5qZmFjZS5hY3Rpb24uQWN0aW9uOwppbXBvcnQgb3JnLmVjbGlwc2UuamZhY2UuYWN0aW9uLklBY3Rpb247CmltcG9ydCBvcmcuZWNsaXBzZS5qZmFjZS5hY3Rpb24uSU1lbnVNYW5hZ2VyOwppbXBvcnQgb3JnLmVjbGlwc2UuamZhY2UuYWN0aW9uLk1lbnVNYW5hZ2VyOwppbXBvcnQgb3JnLmVjbGlwc2UuamZhY2Uudmlld2Vycy4qOwppbXBvcnQgb3JnLmVjbGlwc2Uud3N0LnNlcnZlci5jb3JlLklTZXJ2ZXI7CmltcG9ydCBvcmcuZWNsaXBzZS53c3Quc2VydmVyLnVpLmFjdGlvbnMuTmV3U2VydmVyQWN0aW9uOwppbXBvcnQgb3JnLmVjbGlwc2Uud3N0LnNlcnZlci51aS5pbnRlcm5hbC52aWV3LnNlcnZlcnMuKjsKaW1wb3J0IG9yZy5lY2xpcHNlLndzdC5zZXJ2ZXIudWkuaW50ZXJuYWwudmlldy50cmVlLlNlcnZlckVsZW1lbnRBZGFwdGVyOwppbXBvcnQgb3JnLmVjbGlwc2Uud3N0LnNlcnZlci51aS5pbnRlcm5hbC52aWV3LnRyZWUuU2VydmVyVHJlZUFjdGlvbjsKaW1wb3J0IG9yZy5lY2xpcHNlLnN3dC53aWRnZXRzLlNoZWxsOwovKioKICogCiAqLwpwdWJsaWMgY2xhc3MgU2VydmVyVHJlZSB7CgkvKioKCSAqIENvbnN0YW50cyBmb3IgYWN0aW9ucwoJICovCglwdWJsaWMgc3RhdGljIGZpbmFsIGJ5dGUgQUNUSU9OX09QRU4gPSAwOwoJcHVibGljIHN0YXRpYyBmaW5hbCBieXRlIEFDVElPTl9ERUxFVEUgPSAxOwoJcHVibGljIHN0YXRpYyBmaW5hbCBieXRlIEFDVElPTl9CT09LTUFSSyA9IDI7CgoJcHJpdmF0ZSBTZXJ2ZXJUcmVlKCkgewoJCS8vIGRvIG5vdGhpbmcKCX0KCQoJcHVibGljIHN0YXRpYyB2b2lkIGZpbGxDb250ZXh0TWVudShTaGVsbCBzaGVsbCwgSVNlbGVjdGlvbiBzZWxlY3Rpb24sIElNZW51TWFuYWdlciBtZW51KSB7CgkJTWVudU1hbmFnZXIgbmV3TWVudSA9IG5ldyBNZW51TWFuYWdlcihTZXJ2ZXJVSVBsdWdpbi5nZXRSZXNvdXJjZSgiJWFjdGlvbk5ldyIpKTsKCQlmaWxsTmV3Q29udGV4dE1lbnUoc2hlbGwsIHNlbGVjdGlvbiwgbmV3TWVudSk7CgkJbWVudS5hZGQobmV3TWVudSk7CgkJZmlsbE90aGVyQ29udGV4dE1lbnUoc2hlbGwsIHNlbGVjdGlvbiwgbWVudSk7Cgl9CgkKCXB1YmxpYyBzdGF0aWMgdm9pZCBmaWxsTmV3Q29udGV4dE1lbnUoU2hlbGwgc2hlbGwsIElTZWxlY3Rpb24gc2VsZWN0aW9uLCBJTWVudU1hbmFnZXIgbWVudSkgewoJCUlBY3Rpb24gbmV3U2VydmVyQWN0aW9uID0gbmV3IE5ld1NlcnZlckFjdGlvbigpOwoJCW5ld1NlcnZlckFjdGlvbi5zZXRUZXh0KFNlcnZlclVJUGx1Z2luLmdldFJlc291cmNlKCIlYWN0aW9uTmV3U2VydmVyIikpOwoJCW1lbnUuYWRkKG5ld1NlcnZlckFjdGlvbik7Cgl9CgoJcHVibGljIHN0YXRpYyB2b2lkIGZpbGxPdGhlckNvbnRleHRNZW51KFNoZWxsIHNoZWxsLCBJU2VsZWN0aW9uIHNlbGVjdGlvbiwgSU1lbnVNYW5hZ2VyIG1lbnUpIHsKCQlpZiAoc2VsZWN0aW9uID09IG51bGwpCgkJCXJldHVybjsKCgkJaWYgKHNlbGVjdGlvbi5pc0VtcHR5KCkgfHwgIShzZWxlY3Rpb24gaW5zdGFuY2VvZiBJU3RydWN0dXJlZFNlbGVjdGlvbikpCgkJCXJldHVybjsKCgkJLy9JU3RydWN0dXJlZFNlbGVjdGlvbiBzZWwgPSAoSVN0cnVjdHVyZWRTZWxlY3Rpb24pIHNlbGVjdGlvbjsKCQkKCQkvL2Jvb2xlYW4gc2luZ2xlU2VsZWN0ID0gKHNlbC5zaXplKCkgPT0gMSk7CgkJLy9PYmplY3QgZmlyc3QgPSBzZWwuZ2V0Rmlyc3RFbGVtZW50KCk7CgoJCS8vIG9wZW4gbWVudQoJCS8qaWYgKHNpbmdsZVNlbGVjdCAmJiBmaXJzdCBpbnN0YW5jZW9mIFNlcnZlckxpZmVjeWNsZUFkYXB0ZXIpIHsKCQkJU2VydmVyTGlmZWN5Y2xlQWRhcHRlciBhZGFwdGVyID0gKFNlcnZlckxpZmVjeWNsZUFkYXB0ZXIpIGZpcnN0OwoJCQlJU2VydmVyUmVzb3VyY2UgcmVzb3VyY2UgPSBhZGFwdGVyLmdldFNlcnZlclJlc291cmNlKCk7CgkJCW1lbnUuYWRkKG5ldyBPcGVuQWN0aW9uKHJlc291cmNlKSk7CgkJCW1lbnUuYWRkKG5ldyBTZXBhcmF0b3IoKSk7CgkJfQoJCQoJCS8vIGRlbGV0ZSBtZW51CgkJTGlzdCBsaXN0ID0gbmV3IEFycmF5TGlzdCgpOwoJCWJvb2xlYW4gY2FuRGVsZXRlID0gdHJ1ZTsKCQlJdGVyYXRvciBpdGVyYXRvcjIgPSBzZWwuaXRlcmF0b3IoKTsKCQl3aGlsZSAoaXRlcmF0b3IyLmhhc05leHQoKSkgewoJCQlPYmplY3Qgb2JqID0gaXRlcmF0b3IyLm5leHQoKTsKCQkJCgkJCWlmIChvYmogaW5zdGFuY2VvZiBTZXJ2ZXJMaWZlY3ljbGVBZGFwdGVyKQoJCQkJbGlzdC5hZGQoKChTZXJ2ZXJMaWZlY3ljbGVBZGFwdGVyKSBvYmopLmdldFNlcnZlclJlc291cmNlKCkpOwoJCQllbHNlCgkJCQljYW5EZWxldGUgPSBmYWxzZTsKCQl9CgkJaWYgKGNhbkRlbGV0ZSkgewoJCQlJU2VydmVyUmVzb3VyY2VbXSByZXMgPSBuZXcgSVNlcnZlclJlc291cmNlW2xpc3Quc2l6ZSgpXTsKCQkJbGlzdC50b0FycmF5KHJlcyk7CgkJCW1lbnUuYWRkKG5ldyBEZWxldGVBY3Rpb24oc2hlbGwsIHJlcykpOwoJCX0KCgkJaWYgKHNpbmdsZVNlbGVjdCAmJiBmaXJzdCBpbnN0YW5jZW9mIElTZXJ2ZXJFbGVtZW50VGFnKQoJCQltZW51LmFkZChuZXcgU2VwYXJhdG9yKCkpOwoKCQlpZiAoc2luZ2xlU2VsZWN0ICYmIGZpcnN0IGluc3RhbmNlb2YgU2VydmVyTGlmZWN5Y2xlQWRhcHRlcikgewoJCQlTZXJ2ZXJMaWZlY3ljbGVBZGFwdGVyIGFkYXB0ZXIgPSAoU2VydmVyTGlmZWN5Y2xlQWRhcHRlcikgZmlyc3Q7CgkJCUlTZXJ2ZXJSZXNvdXJjZSByZXNvdXJjZSA9IGFkYXB0ZXIuZ2V0U2VydmVyUmVzb3VyY2UoKTsKCgkJCUlTZXJ2ZXIgc2VydmVyID0gbnVsbDsKCQkJaWYgKHJlc291cmNlIGluc3RhbmNlb2YgSVNlcnZlcikKCQkJCXNlcnZlciA9IChJU2VydmVyKSByZXNvdXJjZTsKCgkJCS8vIHN3aXRjaCBjb25maWd1cmF0aW9uIG1lbnUKCQkJaWYgKHNlcnZlciAhPSBudWxsKSB7CgkJCQlhZGRTZXJ2ZXJBY3Rpb25zKHNoZWxsLCBtZW51LCBzZXJ2ZXIpOwoKCQkJCU1lbnVNYW5hZ2VyIG1lbnVNYW5hZ2VyID0gbmV3IE1lbnVNYW5hZ2VyKFNlcnZlclVJUGx1Z2luLmdldFJlc291cmNlKCIlYWN0aW9uU3dpdGNoQ29uZmlndXJhdGlvbiIpKTsKCQkJCW1lbnVNYW5hZ2VyLmFkZChuZXcgU3dpdGNoQ29uZmlndXJhdGlvbkFjdGlvbihzaGVsbCwgU2VydmVyVUlQbHVnaW4uZ2V0UmVzb3VyY2UoIiV2aWV3Tm9Db25maWd1cmF0aW9uIiksIHNlcnZlciwgbnVsbCkpOwoKCQkJCUxpc3QgY29uZmlncyA9IFNlcnZlclV0aWwuZ2V0U3VwcG9ydGVkU2VydmVyQ29uZmlndXJhdGlvbnMoc2VydmVyKTsKCQkJCUl0ZXJhdG9yIGl0ZXJhdG9yID0gY29uZmlncy5pdGVyYXRvcigpOwoJCQkJd2hpbGUgKGl0ZXJhdG9yLmhhc05leHQoKSkgewoJCQkJCUlTZXJ2ZXJDb25maWd1cmF0aW9uIGNvbmZpZyA9IChJU2VydmVyQ29uZmlndXJhdGlvbikgaXRlcmF0b3IubmV4dCgpOwoJCQkJCW1lbnVNYW5hZ2VyLmFkZChuZXcgU3dpdGNoQ29uZmlndXJhdGlvbkFjdGlvbihzaGVsbCwgU2VydmVyVXRpbC5nZXROYW1lKGNvbmZpZyksIHNlcnZlciwgY29uZmlnKSk7CgkJCQl9CgoJCQkJbWVudS5hZGQobWVudU1hbmFnZXIpOwoJCQl9CgkJCQoJCQlpZiAoc2VydmVyICE9IG51bGwgJiYgc2VydmVyIGluc3RhbmNlb2YgSU1vZHVsZVJlc3RhcnRhYmxlKSB7CgkJCQltZW51LmFkZChuZXcgU2VwYXJhdG9yKCkpOwoKCQkJCU1lbnVNYW5hZ2VyIHJlc3RhcnRQcm9qZWN0TWVudSA9IG5ldyBNZW51TWFuYWdlcihTZXJ2ZXJVSVBsdWdpbi5nZXRSZXNvdXJjZSgiJWFjdGlvblJlc3RhcnRQcm9qZWN0IikpOwoKCQkJCUlNb2R1bGVSZXN0YXJ0YWJsZSByZXN0YXJ0YWJsZSA9IChJTW9kdWxlUmVzdGFydGFibGUpIHNlcnZlcjsKCgkJCQlJU2VydmVyQ29uZmlndXJhdGlvbiBjb25maWd1cmF0aW9uID0gU2VydmVyVXRpbC5nZXRTZXJ2ZXJDb25maWd1cmF0aW9uKHNlcnZlcik7CgkJCQlpZiAoY29uZmlndXJhdGlvbiAhPSBudWxsKSB7CgkJCQkJSXRlcmF0b3IgaXRlcmF0b3IgPSBTZXJ2ZXJVdGlsLmdldEFsbENvbnRhaW5lZE1vZHVsZXMoY29uZmlndXJhdGlvbikuaXRlcmF0b3IoKTsKCQkJCQl3aGlsZSAoaXRlcmF0b3IuaGFzTmV4dCgpKSB7CgkJCQkJCUlNb2R1bGUgbW9kdWxlID0gKElNb2R1bGUpIGl0ZXJhdG9yLm5leHQoKTsKCQkJCQkJQWN0aW9uIGFjdGlvbiA9IG5ldyBSZXN0YXJ0TW9kdWxlQWN0aW9uKHJlc3RhcnRhYmxlLCBtb2R1bGUpOwoJCQkJCQlyZXN0YXJ0UHJvamVjdE1lbnUuYWRkKGFjdGlvbik7CgkJCQkJfQoJCQkJfQoJCQkJaWYgKHJlc3RhcnRQcm9qZWN0TWVudS5pc0VtcHR5KCkpCgkJCQkJbWVudS5hZGQobmV3IERpc2FibGVkTWVudU1hbmFnZXIoU2VydmVyVUlQbHVnaW4uZ2V0UmVzb3VyY2UoIiVhY3Rpb25SZXN0YXJ0UHJvamVjdCIpKSk7CgkJCQllbHNlCgkJCQkJbWVudS5hZGQocmVzdGFydFByb2plY3RNZW51KTsKCQkJfQoJCX0KCQlpZiAoc2luZ2xlU2VsZWN0ICYmIGZpcnN0IGluc3RhbmNlb2YgTW9kdWxlUmVzb3VyY2VBZGFwdGVyKSB7CgkJCU1vZHVsZVJlc291cmNlQWRhcHRlciBhZGFwdGVyID0gKE1vZHVsZVJlc291cmNlQWRhcHRlcikgZmlyc3Q7CgkJCUlTZXJ2ZXJDb25maWd1cmF0aW9uIGNvbmZpZ3VyYXRpb24gPSBhZGFwdGVyLmdldFNlcnZlckNvbmZpZ3VyYXRpb24oKTsKCQkJSU1vZHVsZSBtb2R1bGUgPSBhZGFwdGVyLmdldE1vZHVsZSgpOwoJCQkKCQkJSU1vZHVsZVtdIG1vZHVsZXMgPSBjb25maWd1cmF0aW9uLmdldE1vZHVsZXMoKTsKCQkJYm9vbGVhbiBmb3VuZCA9IGZhbHNlOwoJCQlpZiAobW9kdWxlcyAhPSBudWxsICYmIG1vZHVsZSAhPSBudWxsKSB7CgkJCQlpbnQgc2l6ZSA9IG1vZHVsZXMubGVuZ3RoOwoJCQkJZm9yIChpbnQgaSA9IDA7IGkgPCBzaXplOyBpKyspIHsKCQkJCQlpZiAobW9kdWxlLmVxdWFscyhtb2R1bGVzW2ldKSAmJiBjb25maWd1cmF0aW9uLmNhblJlbW92ZU1vZHVsZShtb2R1bGUpKQoJCQkJCQlmb3VuZCA9IHRydWU7CgkJCQl9CgkJCX0KCQoJCQlpZiAoZm91bmQpCgkJCQltZW51LmFkZChuZXcgTW9kaWZ5Q29uZmlndXJhdGlvbk1vZHVsZXNBY3Rpb24oc2hlbGwsIGNvbmZpZ3VyYXRpb24sIG1vZHVsZSwgZmFsc2UpKTsKCQl9CgkJCgkJaWYgKHNpbmdsZVNlbGVjdCAmJiBmaXJzdCBpbnN0YW5jZW9mIFNlcnZlckxpZmVjeWNsZUFkYXB0ZXIpIHsKCQkJU2VydmVyTGlmZWN5Y2xlQWRhcHRlciBhZGFwdGVyID0gKFNlcnZlckxpZmVjeWNsZUFkYXB0ZXIpIGZpcnN0OwoJCQlJU2VydmVyUmVzb3VyY2UgcmVzb3VyY2UgPSBhZGFwdGVyLmdldFNlcnZlclJlc291cmNlKCk7CgoJCQlJU2VydmVyIHNlcnZlciA9IG51bGw7CgkJCUlTZXJ2ZXJDb25maWd1cmF0aW9uIGNvbmZpZ3VyYXRpb24gPSBudWxsOwoJCQlpZiAocmVzb3VyY2UgaW5zdGFuY2VvZiBJU2VydmVyQ29uZmlndXJhdGlvbikKCQkJCWNvbmZpZ3VyYXRpb24gPSAoSVNlcnZlckNvbmZpZ3VyYXRpb24pIHJlc291cmNlOwoJCQllbHNlIGlmIChyZXNvdXJjZSBpbnN0YW5jZW9mIElTZXJ2ZXIpIHsKCQkJCXNlcnZlciA9IChJU2VydmVyKSByZXNvdXJjZTsKCQkJCWNvbmZpZ3VyYXRpb24gPSBTZXJ2ZXJVdGlsLmdldFNlcnZlckNvbmZpZ3VyYXRpb24oc2VydmVyKTsKCQkJfQoJCQkKCQkJU2VydmVyQWN0aW9uLmFkZFNlcnZlck1lbnVJdGVtcyhzaGVsbCwgbWVudSwgc2VydmVyLCBjb25maWd1cmF0aW9uKTsKCQl9Ki8KCX0KCglwcm90ZWN0ZWQgc3RhdGljIHZvaWQgYWRkU2VydmVyQWN0aW9ucyhTaGVsbCBzaGVsbCwgSU1lbnVNYW5hZ2VyIG1lbnUsIElTZXJ2ZXIgc2VydmVyKSB7CgkJZmluYWwgSVNlbGVjdGlvbiBzZWxlY3Rpb24gPSBuZXcgU3RydWN0dXJlZFNlbGVjdGlvbihzZXJ2ZXIpOwoJCUlTZWxlY3Rpb25Qcm92aWRlciBwcm92aWRlciA9IG5ldyBJU2VsZWN0aW9uUHJvdmlkZXIoKSB7CgkJCXB1YmxpYyB2b2lkIGFkZFNlbGVjdGlvbkNoYW5nZWRMaXN0ZW5lcihJU2VsZWN0aW9uQ2hhbmdlZExpc3RlbmVyIGxpc3RlbmVyKSB7CgkJCQkvLyBkbyBub3RoaW5nCgkJCX0KCQkJcHVibGljIElTZWxlY3Rpb24gZ2V0U2VsZWN0aW9uKCkgewoJCQkJcmV0dXJuIHNlbGVjdGlvbjsKCQkJfQoJCQlwdWJsaWMgdm9pZCByZW1vdmVTZWxlY3Rpb25DaGFuZ2VkTGlzdGVuZXIoSVNlbGVjdGlvbkNoYW5nZWRMaXN0ZW5lciBsaXN0ZW5lcikgewoJCQkJLy8gZG8gbm90aGluZwoJCQl9CgkJCXB1YmxpYyB2b2lkIHNldFNlbGVjdGlvbihJU2VsZWN0aW9uIHNlbCkgewoJCQkJLy8gZG8gbm90aGluZwoJCQl9CgkJfTsKCQoJCS8vIGNyZWF0ZSB0aGUgZGVidWcgYWN0aW9uCgkJQWN0aW9uIGRlYnVnQWN0aW9uID0gbmV3IFN0YXJ0QWN0aW9uKHNoZWxsLCBwcm92aWRlciwgImRlYnVnIiwgSUxhdW5jaE1hbmFnZXIuREVCVUdfTU9ERSk7CgkJZGVidWdBY3Rpb24uc2V0VG9vbFRpcFRleHQoU2VydmVyVUlQbHVnaW4uZ2V0UmVzb3VyY2UoIiVhY3Rpb25EZWJ1Z1Rvb2xUaXAiKSk7CgkJZGVidWdBY3Rpb24uc2V0VGV4dChTZXJ2ZXJVSVBsdWdpbi5nZXRSZXNvdXJjZSgiJWFjdGlvbkRlYnVnIikpOwoJCWRlYnVnQWN0aW9uLnNldEltYWdlRGVzY3JpcHRvcihJbWFnZVJlc291cmNlLmdldEltYWdlRGVzY3JpcHRvcihJbWFnZVJlc291cmNlLklNR19FTENMX1NUQVJUX0RFQlVHKSk7CgkJZGVidWdBY3Rpb24uc2V0SG92ZXJJbWFnZURlc2NyaXB0b3IoSW1hZ2VSZXNvdXJjZS5nZXRJbWFnZURlc2NyaXB0b3IoSW1hZ2VSZXNvdXJjZS5JTUdfQ0xDTF9TVEFSVF9ERUJVRykpOwoJCWRlYnVnQWN0aW9uLnNldERpc2FibGVkSW1hZ2VEZXNjcmlwdG9yKEltYWdlUmVzb3VyY2UuZ2V0SW1hZ2VEZXNjcmlwdG9yKEltYWdlUmVzb3VyY2UuSU1HX0RMQ0xfU1RBUlRfREVCVUcpKTsKCQltZW51LmFkZChkZWJ1Z0FjdGlvbik7CgkKCQkvLyBjcmVhdGUgdGhlIHN0YXJ0IGFjdGlvbgoJCUFjdGlvbiBydW5BY3Rpb24gPSBuZXcgU3RhcnRBY3Rpb24oc2hlbGwsIHByb3ZpZGVyLCAic3RhcnQiLCBJTGF1bmNoTWFuYWdlci5SVU5fTU9ERSk7CgkJcnVuQWN0aW9uLnNldFRvb2xUaXBUZXh0KFNlcnZlclVJUGx1Z2luLmdldFJlc291cmNlKCIlYWN0aW9uU3RhcnRUb29sVGlwIikpOwoJCXJ1bkFjdGlvbi5zZXRUZXh0KFNlcnZlclVJUGx1Z2luLmdldFJlc291cmNlKCIlYWN0aW9uU3RhcnQiKSk7CgkJcnVuQWN0aW9uLnNldEltYWdlRGVzY3JpcHRvcihJbWFnZVJlc291cmNlLmdldEltYWdlRGVzY3JpcHRvcihJbWFnZVJlc291cmNlLklNR19FTENMX1NUQVJUKSk7CgkJcnVuQWN0aW9uLnNldEhvdmVySW1hZ2VEZXNjcmlwdG9yKEltYWdlUmVzb3VyY2UuZ2V0SW1hZ2VEZXNjcmlwdG9yKEltYWdlUmVzb3VyY2UuSU1HX0NMQ0xfU1RBUlQpKTsKCQlydW5BY3Rpb24uc2V0RGlzYWJsZWRJbWFnZURlc2NyaXB0b3IoSW1hZ2VSZXNvdXJjZS5nZXRJbWFnZURlc2NyaXB0b3IoSW1hZ2VSZXNvdXJjZS5JTUdfRExDTF9TVEFSVCkpOwoJCW1lbnUuYWRkKHJ1bkFjdGlvbik7CgkJCgkJLy8gY3JlYXRlIHRoZSBwcm9maWxlIGFjdGlvbgoJCUFjdGlvbiBwcm9maWxlQWN0aW9uID0gbmV3IFN0YXJ0QWN0aW9uKHNoZWxsLCBwcm92aWRlciwgInByb2ZpbGUiLCBJTGF1bmNoTWFuYWdlci5QUk9GSUxFX01PREUpOwoJCXByb2ZpbGVBY3Rpb24uc2V0VG9vbFRpcFRleHQoU2VydmVyVUlQbHVnaW4uZ2V0UmVzb3VyY2UoIiVhY3Rpb25Qcm9maWxlVG9vbFRpcCIpKTsKCQlwcm9maWxlQWN0aW9uLnNldFRleHQoU2VydmVyVUlQbHVnaW4uZ2V0UmVzb3VyY2UoIiVhY3Rpb25Qcm9maWxlIikpOwoJCXByb2ZpbGVBY3Rpb24uc2V0SW1hZ2VEZXNjcmlwdG9yKEltYWdlUmVzb3VyY2UuZ2V0SW1hZ2VEZXNjcmlwdG9yKEltYWdlUmVzb3VyY2UuSU1HX0VMQ0xfU1RBUlRfUFJPRklMRSkpOwoJCXByb2ZpbGVBY3Rpb24uc2V0SG92ZXJJbWFnZURlc2NyaXB0b3IoSW1hZ2VSZXNvdXJjZS5nZXRJbWFnZURlc2NyaXB0b3IoSW1hZ2VSZXNvdXJjZS5JTUdfQ0xDTF9TVEFSVF9QUk9GSUxFKSk7CgkJcHJvZmlsZUFjdGlvbi5zZXREaXNhYmxlZEltYWdlRGVzY3JpcHRvcihJbWFnZVJlc291cmNlLmdldEltYWdlRGVzY3JpcHRvcihJbWFnZVJlc291cmNlLklNR19ETENMX1NUQVJUX1BST0ZJTEUpKTsKCQltZW51LmFkZChwcm9maWxlQWN0aW9uKTsKCQoJCS8vIGNyZWF0ZSB0aGUgcmVzdGFydCBhY3Rpb24KCQlNZW51TWFuYWdlciBtZW51TWFuYWdlciA9IG5ldyBNZW51TWFuYWdlcihTZXJ2ZXJVSVBsdWdpbi5nZXRSZXNvdXJjZSgiJWFjdGlvblJlc3RhcnQiKSk7CgkJCgkJQWN0aW9uIHJlc3RhcnRBY3Rpb24gPSBuZXcgUmVzdGFydEFjdGlvbihzaGVsbCwgcHJvdmlkZXIsICJyZXN0YXJ0IiwgSUxhdW5jaE1hbmFnZXIuUlVOX01PREUpOwoJCXJlc3RhcnRBY3Rpb24uc2V0VG9vbFRpcFRleHQoU2VydmVyVUlQbHVnaW4uZ2V0UmVzb3VyY2UoIiVhY3Rpb25SZXN0YXJ0VG9vbFRpcCIpKTsKCQlyZXN0YXJ0QWN0aW9uLnNldFRleHQoU2VydmVyVUlQbHVnaW4uZ2V0UmVzb3VyY2UoIiVhY3Rpb25SZXN0YXJ0IikpOwoJCXJlc3RhcnRBY3Rpb24uc2V0SW1hZ2VEZXNjcmlwdG9yKEltYWdlUmVzb3VyY2UuZ2V0SW1hZ2VEZXNjcmlwdG9yKEltYWdlUmVzb3VyY2UuSU1HX0VMQ0xfUkVTVEFSVCkpOwoJCXJlc3RhcnRBY3Rpb24uc2V0SG92ZXJJbWFnZURlc2NyaXB0b3IoSW1hZ2VSZXNvdXJjZS5nZXRJbWFnZURlc2NyaXB0b3IoSW1hZ2VSZXNvdXJjZS5JTUdfQ0xDTF9SRVNUQVJUKSk7CgkJcmVzdGFydEFjdGlvbi5zZXREaXNhYmxlZEltYWdlRGVzY3JpcHRvcihJbWFnZVJlc291cmNlLmdldEltYWdlRGVzY3JpcHRvcihJbWFnZVJlc291cmNlLklNR19ETENMX1JFU1RBUlQpKTsKCQltZW51TWFuYWdlci5hZGQocmVzdGFydEFjdGlvbik7CgkJLy9tZW51LmFkZChyZXN0YXJ0QWN0aW9uKTsKCQltZW51LmFkZChtZW51TWFuYWdlcik7CgoJCS8vIGNyZWF0ZSB0aGUgc3RvcCBhY3Rpb24KCQkvKkFjdGlvbiBzdG9wQWN0aW9uID0gbmV3IFN0b3BBY3Rpb24oc2hlbGwsIHByb3ZpZGVyLCAic3RvcCIsIElTZXJ2ZXJGYWN0b3J5LlNFUlZFUl9TVEFURV9TRVRfTUFOQUdFRCk7CgkJc3RvcEFjdGlvbi5zZXRUb29sVGlwVGV4dChTZXJ2ZXJVSVBsdWdpbi5nZXRSZXNvdXJjZSgiJWFjdGlvblN0b3BUb29sVGlwIikpOwoJCXN0b3BBY3Rpb24uc2V0VGV4dChTZXJ2ZXJVSVBsdWdpbi5nZXRSZXNvdXJjZSgiJWFjdGlvblN0b3AiKSk7CgkJc3RvcEFjdGlvbi5zZXRJbWFnZURlc2NyaXB0b3IoSW1hZ2VSZXNvdXJjZS5nZXRJbWFnZURlc2NyaXB0b3IoSW1hZ2VSZXNvdXJjZS5JTUdfRUxDTF9TVE9QKSk7CgkJc3RvcEFjdGlvbi5zZXRIb3ZlckltYWdlRGVzY3JpcHRvcihJbWFnZVJlc291cmNlLmdldEltYWdlRGVzY3JpcHRvcihJbWFnZVJlc291cmNlLklNR19DTENMX1NUT1ApKTsKCQlzdG9wQWN0aW9uLnNldERpc2FibGVkSW1hZ2VEZXNjcmlwdG9yKEltYWdlUmVzb3VyY2UuZ2V0SW1hZ2VEZXNjcmlwdG9yKEltYWdlUmVzb3VyY2UuSU1HX0RMQ0xfU1RPUCkpOwoJCW1lbnUuYWRkKHN0b3BBY3Rpb24pOwoKCQkvLyBjcmVhdGUgdGhlIGRpc2Nvbm5lY3QgYWN0aW9uCgkJQWN0aW9uIGRpc2Nvbm5lY3RBY3Rpb24gPSBuZXcgU3RvcEFjdGlvbihzaGVsbCwgcHJvdmlkZXIsICJkaXNjb25uZWN0IiwgSVNlcnZlckZhY3RvcnkuU0VSVkVSX1NUQVRFX1NFVF9BVFRBQ0hFRCk7CgkJZGlzY29ubmVjdEFjdGlvbi5zZXRUb29sVGlwVGV4dChTZXJ2ZXJVSVBsdWdpbi5nZXRSZXNvdXJjZSgiJWFjdGlvblN0b3BUb29sVGlwMiIpKTsKCQlkaXNjb25uZWN0QWN0aW9uLnNldFRleHQoU2VydmVyVUlQbHVnaW4uZ2V0UmVzb3VyY2UoIiVhY3Rpb25TdG9wMiIpKTsKCQlkaXNjb25uZWN0QWN0aW9uLnNldEltYWdlRGVzY3JpcHRvcihJbWFnZVJlc291cmNlLmdldEltYWdlRGVzY3JpcHRvcihJbWFnZVJlc291cmNlLklNR19FTENMX0RJU0NPTk5FQ1QpKTsKCQlkaXNjb25uZWN0QWN0aW9uLnNldEhvdmVySW1hZ2VEZXNjcmlwdG9yKEltYWdlUmVzb3VyY2UuZ2V0SW1hZ2VEZXNjcmlwdG9yKEltYWdlUmVzb3VyY2UuSU1HX0NMQ0xfRElTQ09OTkVDVCkpOwoJCWRpc2Nvbm5lY3RBY3Rpb24uc2V0RGlzYWJsZWRJbWFnZURlc2NyaXB0b3IoSW1hZ2VSZXNvdXJjZS5nZXRJbWFnZURlc2NyaXB0b3IoSW1hZ2VSZXNvdXJjZS5JTUdfRExDTF9ESVNDT05ORUNUKSk7CgkJbWVudS5hZGQoZGlzY29ubmVjdEFjdGlvbik7Ki8KCgkJLy8gY3JlYXRlIHRoZSBwdWJsaXNoIGFjdGlvbgoJCUFjdGlvbiBwdWJsaXNoQWN0aW9uID0gbmV3IFB1Ymxpc2hBY3Rpb24oc2hlbGwsIHByb3ZpZGVyLCAicHVibGlzaCIpOwoJCXB1Ymxpc2hBY3Rpb24uc2V0VG9vbFRpcFRleHQoU2VydmVyVUlQbHVnaW4uZ2V0UmVzb3VyY2UoIiVhY3Rpb25QdWJsaXNoVG9vbFRpcCIpKTsKCQlwdWJsaXNoQWN0aW9uLnNldFRleHQoU2VydmVyVUlQbHVnaW4uZ2V0UmVzb3VyY2UoIiVhY3Rpb25QdWJsaXNoIikpOwoJCXB1Ymxpc2hBY3Rpb24uc2V0SW1hZ2VEZXNjcmlwdG9yKEltYWdlUmVzb3VyY2UuZ2V0SW1hZ2VEZXNjcmlwdG9yKEltYWdlUmVzb3VyY2UuSU1HX0VMQ0xfUFVCTElTSCkpOwoJCXB1Ymxpc2hBY3Rpb24uc2V0SG92ZXJJbWFnZURlc2NyaXB0b3IoSW1hZ2VSZXNvdXJjZS5nZXRJbWFnZURlc2NyaXB0b3IoSW1hZ2VSZXNvdXJjZS5JTUdfQ0xDTF9QVUJMSVNIKSk7CgkJcHVibGlzaEFjdGlvbi5zZXREaXNhYmxlZEltYWdlRGVzY3JpcHRvcihJbWFnZVJlc291cmNlLmdldEltYWdlRGVzY3JpcHRvcihJbWFnZVJlc291cmNlLklNR19ETENMX1BVQkxJU0gpKTsKCQltZW51LmFkZChwdWJsaXNoQWN0aW9uKTsKCX0KCglwdWJsaWMgc3RhdGljIGJvb2xlYW4gaXNBY3Rpb25FbmFibGVkKElTZWxlY3Rpb24gc2VsZWN0aW9uLCBieXRlIGFjdGlvbikgewoJCWlmIChzZWxlY3Rpb24gPT0gbnVsbCB8fCBhY3Rpb24gPCAwKQoJCQlyZXR1cm4gZmFsc2U7CgoJCWlmIChzZWxlY3Rpb24uaXNFbXB0eSgpIHx8ICEoc2VsZWN0aW9uIGluc3RhbmNlb2YgSVN0cnVjdHVyZWRTZWxlY3Rpb24pKQoJCQlyZXR1cm4gZmFsc2U7CgoJCUlTdHJ1Y3R1cmVkU2VsZWN0aW9uIHNlbCA9IChJU3RydWN0dXJlZFNlbGVjdGlvbikgc2VsZWN0aW9uOwoJCQoJCWlmIChhY3Rpb24gPT0gQUNUSU9OX09QRU4pIHsKCQkJaWYgKHNlbC5zaXplKCkgIT0gMSkKCQkJCXJldHVybiBmYWxzZTsKCgkJCU9iamVjdCBvYmogPSBzZWwuZ2V0Rmlyc3RFbGVtZW50KCk7CgoJCQlyZXR1cm4gKG9iaiBpbnN0YW5jZW9mIFNlcnZlckVsZW1lbnRBZGFwdGVyKTsKCQl9IGVsc2UgaWYgKGFjdGlvbiA9PSBBQ1RJT05fREVMRVRFKSB7CgkJCWlmIChzZWwuc2l6ZSgpID09IDApCgkJCQlyZXR1cm4gZmFsc2U7CgkJCQoJCQlJdGVyYXRvciBpdGVyYXRvciA9IHNlbC5pdGVyYXRvcigpOwoJCQl3aGlsZSAoaXRlcmF0b3IuaGFzTmV4dCgpKSB7CgkJCQlPYmplY3Qgb2JqID0gaXRlcmF0b3IubmV4dCgpOwoJCQkJCgkJCQlpZiAoIShvYmogaW5zdGFuY2VvZiBTZXJ2ZXJFbGVtZW50QWRhcHRlcikgJiYgIShvYmogaW5zdGFuY2VvZiBJU2VydmVyKSkKCQkJCQlyZXR1cm4gZmFsc2U7CgkJCX0KCQkJcmV0dXJuIHRydWU7CgkJfQoKCQlyZXR1cm4gZmFsc2U7Cgl9CgoJcHVibGljIHN0YXRpYyBib29sZWFuIHBlcmZvcm1BY3Rpb24oU2hlbGwgc2hlbGwsIElTZWxlY3Rpb24gc2VsZWN0aW9uLCBieXRlIGFjdGlvbikgewoJCS8vaWYgKCFpc0FjdGlvbkVuYWJsZWQoc2VsZWN0aW9uLCBhY3Rpb24pKQoJCS8vCXJldHVybiBmYWxzZTsKCgkJaWYgKHNlbGVjdGlvbiA9PSBudWxsIHx8IGFjdGlvbiA8IDApCgkJCXJldHVybiBmYWxzZTsKCgkJaWYgKHNlbGVjdGlvbi5pc0VtcHR5KCkgfHwgIShzZWxlY3Rpb24gaW5zdGFuY2VvZiBJU3RydWN0dXJlZFNlbGVjdGlvbikpCgkJCXJldHVybiBmYWxzZTsKCgkJSVN0cnVjdHVyZWRTZWxlY3Rpb24gc2VsID0gKElTdHJ1Y3R1cmVkU2VsZWN0aW9uKSBzZWxlY3Rpb247CgoJCWlmIChhY3Rpb24gPT0gQUNUSU9OX09QRU4pIHsKCQkJaWYgKHNlbC5zaXplKCkgIT0gMSkKCQkJCXJldHVybiBmYWxzZTsKCgkJCU9iamVjdCBvYmogPSBzZWwuZ2V0Rmlyc3RFbGVtZW50KCk7CgkJCWlmIChvYmogaW5zdGFuY2VvZiBJU2VydmVyKSB7CgkJCQlBY3Rpb24gb3BlbiA9IG5ldyBPcGVuQWN0aW9uKChJU2VydmVyKSBvYmopOwoJCQkJb3Blbi5ydW4oKTsKCQkJCXJldHVybiB0cnVlOwoJCQl9IGVsc2UgaWYgKG9iaiBpbnN0YW5jZW9mIFNlcnZlckVsZW1lbnRBZGFwdGVyKSB7CgkJCQlTZXJ2ZXJFbGVtZW50QWRhcHRlciBhZGFwdGVyID0gKFNlcnZlckVsZW1lbnRBZGFwdGVyKSBvYmo7CgkJCQlPYmplY3QgZWxlbWVudCA9IGFkYXB0ZXIuZ2V0T2JqZWN0KCk7CgkJCQlpZiAoZWxlbWVudCBpbnN0YW5jZW9mIElTZXJ2ZXIpIHsKCQkJCQlBY3Rpb24gb3BlbiA9IG5ldyBPcGVuQWN0aW9uKChJU2VydmVyKSBlbGVtZW50KTsKCQkJCQlvcGVuLnJ1bigpOwoJCQkJCXJldHVybiB0cnVlOwoJCQkJfQoJCQkJcmV0dXJuIGZhbHNlOwoJCQl9CgkJCXJldHVybiBmYWxzZTsKCQl9IGVsc2UgaWYgKGFjdGlvbiA9PSBBQ1RJT05fREVMRVRFKSB7CgkJCWlmIChzZWwuc2l6ZSgpID09IDApCgkJCQlyZXR1cm4gZmFsc2U7CgkJCQoJCQlMaXN0IGxpc3QgPSBuZXcgQXJyYXlMaXN0KCk7CgkJCUl0ZXJhdG9yIGl0ZXJhdG9yID0gc2VsLml0ZXJhdG9yKCk7CgkJCXdoaWxlIChpdGVyYXRvci5oYXNOZXh0KCkpIHsKCQkJCU9iamVjdCBvYmogPSBpdGVyYXRvci5uZXh0KCk7CgkJCQkKCQkJCWlmIChvYmogaW5zdGFuY2VvZiBTZXJ2ZXJFbGVtZW50QWRhcHRlcikKCQkJCQlsaXN0LmFkZCgoKFNlcnZlckVsZW1lbnRBZGFwdGVyKSBvYmopLmdldE9iamVjdCgpKTsKCQkJCWVsc2UgaWYgKG9iaiBpbnN0YW5jZW9mIElTZXJ2ZXIpCgkJCQkJbGlzdC5hZGQob2JqKTsKCQkJfQoJCQkKCQkJSVNlcnZlcltdIHNlcnZlcnMgPSBuZXcgSVNlcnZlcltsaXN0LnNpemUoKV07CgkJCWxpc3QudG9BcnJheShzZXJ2ZXJzKTsKCQkJCgkJCUFjdGlvbiBkZWxldGUgPSBuZXcgRGVsZXRlQWN0aW9uKHNoZWxsLCBzZXJ2ZXJzKTsKCQkJZGVsZXRlLnJ1bigpOwoJCQlyZXR1cm4gdHJ1ZTsKCQl9CgoJCXJldHVybiBmYWxzZTsKCX0KCQoJLyoqCgkgKiBSZXR1cm5zIGFuIGFjdGlvbiBvZiB0aGUgc3BlY2lmaWVkIHR5cGUsIHdoaWNoIGNhbiBiZSB1c2VkIGZvciBnbG9iYWwKCSAqLwoJcHVibGljIHN0YXRpYyBJQWN0aW9uIGdldEFjdGlvbihTaGVsbCBzaGVsbCwgSVNlbGVjdGlvblByb3ZpZGVyIHByb3ZpZGVyLCBieXRlIGFjdGlvbikgewoJCWlmIChhY3Rpb24gPT0gQUNUSU9OX0RFTEVURSkgewoJCQlyZXR1cm4gbmV3IFNlcnZlclRyZWVBY3Rpb24oc2hlbGwsIHByb3ZpZGVyLCBTZXJ2ZXJVSVBsdWdpbi5nZXRSZXNvdXJjZSgiJWFjdGlvbkRlbGV0ZSIpLCBTZXJ2ZXJUcmVlLkFDVElPTl9ERUxFVEUpOwoJCX0KCQlyZXR1cm4gbnVsbDsKCX0KfQ==