LyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogQ29weXJpZ2h0IChjKSAyMDAzLCAyMDA1IElCTSBDb3Jwb3JhdGlvbiBhbmQgb3RoZXJzLgogKiBBbGwgcmlnaHRzIHJlc2VydmVkLiBUaGlzIHByb2dyYW0gYW5kIHRoZSBhY2NvbXBhbnlpbmcgbWF0ZXJpYWxzCiAqIGFyZSBtYWRlIGF2YWlsYWJsZSB1bmRlciB0aGUgdGVybXMgb2YgdGhlIEVjbGlwc2UgUHVibGljIExpY2Vuc2UgdjEuMAogKiB3aGljaCBhY2NvbXBhbmllcyB0aGlzIGRpc3RyaWJ1dGlvbiwgYW5kIGlzIGF2YWlsYWJsZSBhdAogKiBodHRwOi8vd3d3LmVjbGlwc2Uub3JnL2xlZ2FsL2VwbC12MTAuaHRtbAqgKiAKICogQ29udHJpYnV0b3JzOgogKiAgICAgSUJNIENvcnBvcmF0aW9uIC0gSW5pdGlhbCBBUEkgYW5kIGltcGxlbWVudGF0aW9uCiAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwpwYWNrYWdlIG9yZy5lY2xpcHNlLndzdC5zZXJ2ZXIudWkuaW50ZXJuYWw7CgppbXBvcnQgamF2YS50ZXh0Lk1lc3NhZ2VGb3JtYXQ7CmltcG9ydCBqYXZhLnV0aWwuQXJyYXlMaXN0OwppbXBvcnQgamF2YS51dGlsLkhhc2hNYXA7CmltcG9ydCBqYXZhLnV0aWwuSXRlcmF0b3I7CmltcG9ydCBqYXZhLnV0aWwuTGlzdDsKaW1wb3J0IGphdmEudXRpbC5NYXA7CgppbXBvcnQgb3JnLmVjbGlwc2UuY29yZS5yZXNvdXJjZXMuSUZpbGU7CmltcG9ydCBvcmcuZWNsaXBzZS5jb3JlLnJ1bnRpbWUuKjsKaW1wb3J0IG9yZy5lY2xpcHNlLmpmYWNlLmFjdGlvbi5BY3Rpb247CmltcG9ydCBvcmcuZWNsaXBzZS5qZmFjZS5kaWFsb2dzLklEaWFsb2dDb25zdGFudHM7CmltcG9ydCBvcmcuZWNsaXBzZS5qZmFjZS5kaWFsb2dzLk1lc3NhZ2VEaWFsb2c7CmltcG9ydCBvcmcuZWNsaXBzZS5qZmFjZS52aWV3ZXJzLlN0cnVjdHVyZWRTZWxlY3Rpb247CgppbXBvcnQgb3JnLmVjbGlwc2Uud3N0LnNlcnZlci5jb3JlLio7CmltcG9ydCBvcmcuZWNsaXBzZS53c3Quc2VydmVyLmNvcmUuaW50ZXJuYWwuSVB1Ymxpc2hMaXN0ZW5lcjsKaW1wb3J0IG9yZy5lY2xpcHNlLndzdC5zZXJ2ZXIuY29yZS5pbnRlcm5hbC5QdWJsaXNoQWRhcHRlcjsKaW1wb3J0IG9yZy5lY2xpcHNlLndzdC5zZXJ2ZXIuY29yZS5pbnRlcm5hbC5TZXJ2ZXI7CmltcG9ydCBvcmcuZWNsaXBzZS53c3Quc2VydmVyLmNvcmUuaW50ZXJuYWwuU2VydmVyVHlwZTsKaW1wb3J0IG9yZy5lY2xpcHNlLndzdC5zZXJ2ZXIuY29yZS51dGlsLlNlcnZlckV2ZW50OwppbXBvcnQgb3JnLmVjbGlwc2Uud3N0LnNlcnZlci51aS5TZXJ2ZXJVSVV0aWw7CmltcG9ydCBvcmcuZWNsaXBzZS53c3Quc2VydmVyLnVpLmludGVybmFsLmFjdGlvbnMuUnVuT25TZXJ2ZXJBY3Rpb25EZWxlZ2F0ZTsKaW1wb3J0IG9yZy5lY2xpcHNlLndzdC5zZXJ2ZXIudWkuaW50ZXJuYWwuZWRpdG9yLklTZXJ2ZXJFZGl0b3JJbnB1dDsKaW1wb3J0IG9yZy5lY2xpcHNlLndzdC5zZXJ2ZXIudWkuaW50ZXJuYWwuZWRpdG9yLlNlcnZlckVkaXRvcklucHV0OwppbXBvcnQgb3JnLmVjbGlwc2Uud3N0LnNlcnZlci51aS5pbnRlcm5hbC50YXNrLkZpbmlzaFdpemFyZEZyYWdtZW50OwppbXBvcnQgb3JnLmVjbGlwc2Uud3N0LnNlcnZlci51aS5pbnRlcm5hbC50YXNrLklucHV0V2l6YXJkRnJhZ21lbnQ7CmltcG9ydCBvcmcuZWNsaXBzZS53c3Quc2VydmVyLnVpLmludGVybmFsLnRhc2suU2F2ZVJ1bnRpbWVUYXNrOwppbXBvcnQgb3JnLmVjbGlwc2Uud3N0LnNlcnZlci51aS5pbnRlcm5hbC53aXphcmQuQ2xvc2FibGVXaXphcmREaWFsb2c7CmltcG9ydCBvcmcuZWNsaXBzZS53c3Quc2VydmVyLnVpLmludGVybmFsLndpemFyZC5mcmFnbWVudC5OZXdSdW50aW1lV2l6YXJkRnJhZ21lbnQ7CmltcG9ydCBvcmcuZWNsaXBzZS53c3Quc2VydmVyLnVpLndpemFyZC5UYXNrV2l6YXJkOwppbXBvcnQgb3JnLmVjbGlwc2Uud3N0LnNlcnZlci51aS53aXphcmQuV2l6YXJkRnJhZ21lbnQ7CgppbXBvcnQgb3JnLmVjbGlwc2Uuc3d0LndpZGdldHMuRGlzcGxheTsKaW1wb3J0IG9yZy5lY2xpcHNlLnN3dC53aWRnZXRzLlNoZWxsOwppbXBvcnQgb3JnLmVjbGlwc2UudWkuSVZpZXdQYXJ0OwppbXBvcnQgb3JnLmVjbGlwc2UudWkuSVdvcmtiZW5jaDsKaW1wb3J0IG9yZy5lY2xpcHNlLnVpLklXb3JrYmVuY2hQYWdlOwppbXBvcnQgb3JnLmVjbGlwc2UudWkuSVdvcmtiZW5jaFdpbmRvdzsKaW1wb3J0IG9yZy5lY2xpcHNlLnVpLnBsdWdpbi5BYnN0cmFjdFVJUGx1Z2luOwppbXBvcnQgb3JnLm9zZ2kuZnJhbWV3b3JrLkJ1bmRsZUNvbnRleHQ7Ci8qKgogKiBUaGUgc2VydmVyIFVJIHBsdWdpbiBjbGFzcy4KICovCnB1YmxpYyBjbGFzcyBTZXJ2ZXJVSVBsdWdpbiBleHRlbmRzIEFic3RyYWN0VUlQbHVnaW4gewoJcHJvdGVjdGVkIHN0YXRpYyBmaW5hbCBTdHJpbmcgVklFV19JRCA9ICJvcmcuZWNsaXBzZS53c3Quc2VydmVyLnVpLlNlcnZlcnNWaWV3IjsKCQoJLy8gc2VydmVyIFVJIHBsdWdpbiBpZAoJcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgUExVR0lOX0lEID0gIm9yZy5lY2xpcHNlLndzdC5zZXJ2ZXIudWkiOwoKCS8vcHVibGljIHN0YXRpYyBmaW5hbCBieXRlIFNUQVJUID0gMDsKCXB1YmxpYyBzdGF0aWMgZmluYWwgYnl0ZSBTVE9QID0gMTsKCS8vcHVibGljIHN0YXRpYyBmaW5hbCBieXRlIFJFU1RBUlQgPSAyOwoJCgkvLyBzaW5nbGV0b24gaW5zdGFuY2Ugb2YgdGhpcyBjbGFzcwoJcHJpdmF0ZSBzdGF0aWMgU2VydmVyVUlQbHVnaW4gc2luZ2xldG9uOwoKCXByb3RlY3RlZCBNYXAgaW1hZ2VEZXNjcmlwdG9ycyA9IG5ldyBIYXNoTWFwKCk7CgkKCS8vIGNhY2hlZCBjb3B5IG9mIGFsbCBydW50aW1lIHdpemFyZHMKCXByaXZhdGUgc3RhdGljIE1hcCB3aXphcmRGcmFnbWVudHM7CgkKCXN0YXRpYyBjbGFzcyBXaXphcmRGcmFnbWVudERhdGEgewoJCVN0cmluZyBpZDsKCQlJQ29uZmlndXJhdGlvbkVsZW1lbnQgY2U7CgkJV2l6YXJkRnJhZ21lbnQgZnJhZ21lbnQ7CgkJCgkJcHVibGljIFdpemFyZEZyYWdtZW50RGF0YShTdHJpbmcgaWQsIElDb25maWd1cmF0aW9uRWxlbWVudCBjZSkgewoJCQl0aGlzLmlkID0gaWQ7CgkJCXRoaXMuY2UgPSBjZTsKCQl9Cgl9CgoJcHJvdGVjdGVkIHN0YXRpYyBMaXN0IHRlcm1pbmF0aW9uV2F0Y2hlcyA9IG5ldyBBcnJheUxpc3QoKTsKCglwcm90ZWN0ZWQgSVNlcnZlckxpZmVjeWNsZUxpc3RlbmVyIHNlcnZlckxpZmVjeWNsZUxpc3RlbmVyID0gbmV3IElTZXJ2ZXJMaWZlY3ljbGVMaXN0ZW5lcigpIHsKCQlwdWJsaWMgdm9pZCBzZXJ2ZXJBZGRlZChJU2VydmVyIHNlcnZlcikgewoJCQlzZXJ2ZXIuYWRkU2VydmVyTGlzdGVuZXIoc2VydmVyTGlzdGVuZXIpOwoJCQkoKFNlcnZlcikgc2VydmVyKS5hZGRQdWJsaXNoTGlzdGVuZXIocHVibGlzaExpc3RlbmVyKTsKCQl9CgoJCXB1YmxpYyB2b2lkIHNlcnZlckNoYW5nZWQoSVNlcnZlciBzZXJ2ZXIpIHsKCQkJLy8gaWdub3JlCgkJfQoKCQlwdWJsaWMgdm9pZCBzZXJ2ZXJSZW1vdmVkKElTZXJ2ZXIgc2VydmVyKSB7CgkJCXNlcnZlci5yZW1vdmVTZXJ2ZXJMaXN0ZW5lcihzZXJ2ZXJMaXN0ZW5lcik7CgkJCSgoU2VydmVyKSBzZXJ2ZXIpLnJlbW92ZVB1Ymxpc2hMaXN0ZW5lcihwdWJsaXNoTGlzdGVuZXIpOwoJCX0KCX07CgoJcHJvdGVjdGVkIHN0YXRpYyBJU2VydmVyTGlzdGVuZXIgc2VydmVyTGlzdGVuZXIgPSBuZXcgSVNlcnZlckxpc3RlbmVyKCkgewoJCXB1YmxpYyB2b2lkIHNlcnZlckNoYW5nZWQoU2VydmVyRXZlbnQgZXZlbnQpIHsKCQkJaW50IGV2ZW50S2luZCA9IGV2ZW50LmdldEtpbmQoKTsKCQkJaWYgKGV2ZW50S2luZCA9PSAoU2VydmVyRXZlbnQuU0VSVkVSX0NIQU5HRSB8IFNlcnZlckV2ZW50LlNUQVRFX0NIQU5HRSkpIHsKCQkJCXNob3dTZXJ2ZXJzVmlldygpOwoJCQl9CgkJfQoJfTsKCQoJcHJvdGVjdGVkIHN0YXRpYyBJUHVibGlzaExpc3RlbmVyIHB1Ymxpc2hMaXN0ZW5lciA9IG5ldyBQdWJsaXNoQWRhcHRlcigpIHsKCQlwdWJsaWMgdm9pZCBwdWJsaXNoU3RhcnRlZChJU2VydmVyIHNlcnZlcikgewoJCQlzaG93U2VydmVyc1ZpZXcoKTsKCQl9CgoJCXB1YmxpYyB2b2lkIHB1Ymxpc2hGaW5pc2hlZChJU2VydmVyIHNlcnZlciwgSVN0YXR1cyBzdGF0dXMpIHsKCQkJc2hvd1NlcnZlcnNWaWV3KCk7CgkJfQoJfTsKCgkvKioKCSAqIENyZWF0ZSB0aGUgU2VydmVyVUlQbHVnaW4uCgkgKi8KCXB1YmxpYyBTZXJ2ZXJVSVBsdWdpbigpIHsKCQlzdXBlcigpOwoJCXNpbmdsZXRvbiA9IHRoaXM7Cgl9CgoJLyoqCgkgKiBSZXR1cm5zIHRoZSBzaW5nbGV0b24gaW5zdGFuY2Ugb2YgdGhpcyBwbHVnaW4uCgkgKgoJICogQHJldHVybiBvcmcuZWNsaXBzZS53c3Quc2VydmVyLnVpLmludGVybmFsLnBsdWdpbi5TZXJ2ZXJVSVBsdWdpbgoJICovCglwdWJsaWMgc3RhdGljIFNlcnZlclVJUGx1Z2luIGdldEluc3RhbmNlKCkgewoJCXJldHVybiBzaW5nbGV0b247Cgl9CgoJLyoqCgkgKiBSZXR1cm5zIHRoZSB0cmFuc2xhdGVkIFN0cmluZyBmb3VuZCB3aXRoIHRoZSBnaXZlbiBrZXkuCgkgKgoJICogQHBhcmFtIGtleSBqYXZhLmxhbmcuU3RyaW5nCgkgKiBAcmV0dXJuIGphdmEubGFuZy5TdHJpbmcKCSAqLwoJcHVibGljIHN0YXRpYyBTdHJpbmcgZ2V0UmVzb3VyY2UoU3RyaW5nIGtleSkgewoJCXRyeSB7CgkJCXJldHVybiBQbGF0Zm9ybS5nZXRSZXNvdXJjZVN0cmluZyhnZXRJbnN0YW5jZSgpLmdldEJ1bmRsZSgpLCBrZXkpOwoJCX0gY2F0Y2ggKEV4Y2VwdGlvbiBlKSB7CgkJCXJldHVybiBrZXk7CgkJfQoJfQoKCS8qKgoJICogUmV0dXJucyB0aGUgdHJhbnNsYXRlZCBTdHJpbmcgZm91bmQgd2l0aCB0aGUgZ2l2ZW4ga2V5LAoJICogYW5kIGZvcm1hdHRlZCB3aXRoIHRoZSBnaXZlbiBhcmd1bWVudHMgdXNpbmcgamF2YS50ZXh0Lk1lc3NhZ2VGb3JtYXQuCgkgKgoJICogQHBhcmFtIGtleSBqYXZhLmxhbmcuU3RyaW5nCgkgKiBAcGFyYW0gYXJnIGphdmEubGFuZy5TdHJpbmcKCSAqIEByZXR1cm4gamF2YS5sYW5nLlN0cmluZwoJICovCglwdWJsaWMgc3RhdGljIFN0cmluZyBnZXRSZXNvdXJjZShTdHJpbmcga2V5LCBTdHJpbmcgYXJnKSB7CgkJcmV0dXJuIGdldFJlc291cmNlKGtleSwgbmV3IFN0cmluZ1tdIHthcmd9KTsKCX0KCgkvKioKCSAqIFJldHVybnMgdGhlIHRyYW5zbGF0ZWQgU3RyaW5nIGZvdW5kIHdpdGggdGhlIGdpdmVuIGtleSwKCSAqIGFuZCBmb3JtYXR0ZWQgd2l0aCB0aGUgZ2l2ZW4gYXJndW1lbnRzIHVzaW5nIGphdmEudGV4dC5NZXNzYWdlRm9ybWF0LgoJICoKCSAqIEBwYXJhbSBrZXkgamF2YS5sYW5nLlN0cmluZwoJICogQHBhcmFtIGFyZ3VtZW50cyBqYXZhLmxhbmcuT2JqZWN0W10KCSAqIEByZXR1cm4gamF2YS5sYW5nLlN0cmluZwoJICovCglwdWJsaWMgc3RhdGljIFN0cmluZyBnZXRSZXNvdXJjZShTdHJpbmcga2V5LCBPYmplY3RbXSBhcmd1bWVudHMpIHsKCQl0cnkgewoJCQlTdHJpbmcgdGV4dCA9IGdldFJlc291cmNlKGtleSk7CgkJCXJldHVybiBNZXNzYWdlRm9ybWF0LmZvcm1hdCh0ZXh0LCBhcmd1bWVudHMpOwoJCX0gY2F0Y2ggKEV4Y2VwdGlvbiBlKSB7CgkJCXJldHVybiBrZXk7CgkJfQoJfQoKCS8qKgoJICogQ29udmVuaWVuY2UgbWV0aG9kIGZvciBsb2dnaW5nLgoJICoKCSAqIEBwYXJhbSBzdGF0dXMgb3JnLmVjbGlwc2UuY29yZS5ydW50aW1lLklTdGF0dXMKCSAqLwoJcHVibGljIHN0YXRpYyB2b2lkIGxvZyhJU3RhdHVzIHN0YXR1cykgewoJCWdldEluc3RhbmNlKCkuZ2V0TG9nKCkubG9nKHN0YXR1cyk7Cgl9CgkKCS8qKgoJICogUmV0dXJuIHRoZSBVSSBwcmVmZXJlbmNlcy4KCSAqIAoJICogQHJldHVybiBTZXJ2ZXJVSVByZWZlcmVuY2VzCgkgKi8KCXB1YmxpYyBzdGF0aWMgU2VydmVyVUlQcmVmZXJlbmNlcyBnZXRQcmVmZXJlbmNlcygpIHsKCQlyZXR1cm4gbmV3IFNlcnZlclVJUHJlZmVyZW5jZXMoKTsKCX0KCgkvKioKCSAqIFN0YXJ0IHVwIHRoaXMgcGx1Zy1pbi4KCSAqCgkgKiBAdGhyb3dzIEV4Y2VwdGlvbgoJICovCglwdWJsaWMgdm9pZCBzdGFydChCdW5kbGVDb250ZXh0IGNvbnRleHQpIHRocm93cyBFeGNlcHRpb24gewoJCVRyYWNlLnRyYWNlKFRyYWNlLkNPTkZJRywgIi0tLS0tPi0tLS0tIFNlcnZlciBVSSBwbHVnaW4gc3RhcnQgLS0tLS0+LS0tLS0iKTsKCQlzdXBlci5zdGFydChjb250ZXh0KTsKCQoJCVNlcnZlclVJUHJlZmVyZW5jZXMgcHJlZnMgPSBnZXRQcmVmZXJlbmNlcygpOwoJCXByZWZzLnNldERlZmF1bHRzKCk7CgkJCgkJU2VydmVyQ29yZS5hZGRTZXJ2ZXJMaWZlY3ljbGVMaXN0ZW5lcihzZXJ2ZXJMaWZlY3ljbGVMaXN0ZW5lcik7CgkJCgkJSVNlcnZlcltdIHNlcnZlcnMgPSBTZXJ2ZXJDb3JlLmdldFNlcnZlcnMoKTsKCQlpZiAoc2VydmVycyAhPSBudWxsKSB7CgkJCWludCBzaXplID0gc2VydmVycy5sZW5ndGg7CgkJCWZvciAoaW50IGkgPSAwOyBpIDwgc2l6ZTsgaSsrKSB7CgkJCQlzZXJ2ZXJzW2ldLmFkZFNlcnZlckxpc3RlbmVyKHNlcnZlckxpc3RlbmVyKTsKCQkJCSgoU2VydmVyKSBzZXJ2ZXJzW2ldKS5hZGRQdWJsaXNoTGlzdGVuZXIocHVibGlzaExpc3RlbmVyKTsKCQkJfQoJCX0KCX0KCgkvKioKCSAqIFNodXRzIGRvd24gdGhpcyBwbHVnLWluIGFuZCBzYXZlcyBhbGwgcGx1Zy1pbiBzdGF0ZS4KCSAqCgkgKiBAZXhjZXB0aW9uIEV4Y2VwdGlvbgoJICovCglwdWJsaWMgdm9pZCBzdG9wKEJ1bmRsZUNvbnRleHQgY29udGV4dCkgdGhyb3dzIEV4Y2VwdGlvbiB7CgkJVHJhY2UudHJhY2UoVHJhY2UuQ09ORklHLCAiLS0tLS08LS0tLS0gU2VydmVyIFVJIHBsdWdpbiBzdG9wIC0tLS0tPC0tLS0tIik7CgkJc3VwZXIuc3RvcChjb250ZXh0KTsKCQkKCQlJbWFnZVJlc291cmNlLmRpc3Bvc2UoKTsKCQkKCQlJU2VydmVyW10gc2VydmVycyA9IFNlcnZlckNvcmUuZ2V0U2VydmVycygpOwoJCWlmIChzZXJ2ZXJzICE9IG51bGwpIHsKCQkJaW50IHNpemUgPSBzZXJ2ZXJzLmxlbmd0aDsKCQkJZm9yIChpbnQgaSA9IDA7IGkgPCBzaXplOyBpKyspIHsKCQkJCXNlcnZlcnNbaV0ucmVtb3ZlU2VydmVyTGlzdGVuZXIoc2VydmVyTGlzdGVuZXIpOwoJCQkJKChTZXJ2ZXIpIHNlcnZlcnNbaV0pLnJlbW92ZVB1Ymxpc2hMaXN0ZW5lcihwdWJsaXNoTGlzdGVuZXIpOwoJCQl9CgkJfQoJCQoJCVNlcnZlckNvcmUucmVtb3ZlU2VydmVyTGlmZWN5Y2xlTGlzdGVuZXIoc2VydmVyTGlmZWN5Y2xlTGlzdGVuZXIpOwoJfQoKCS8qKgoJICogQWRkcyBhIHdhdGNoIHRvIHRoaXMgc2VydmVyLiBJZiBpdCBoYXNuJ3Qgc3RvcHBlZCBpbiBhCgkgKiByZWFzb25hYmxlIGFtb3VudCBvZiB0aW1lLCB0aGUgdXNlciB3aWxsIGJlIHByb21wdGVkIHRvCgkgKiB0ZXJtaW5hdGUgdGhlIHNlcnZlci4KCSAqCgkgKiBAcGFyYW0gc2VydmVyIG9yZy5lY2xpcHNlLndzdC5zZXJ2ZXIuY29yZS5JU2VydmVyCgkgKi8KCXB1YmxpYyBzdGF0aWMgdm9pZCBhZGRUZXJtaW5hdGlvbldhdGNoKGZpbmFsIFNoZWxsIHNoZWxsLCBmaW5hbCBJU2VydmVyIHNlcnZlciwgZmluYWwgaW50IG1vZGUpIHsKCQlpZiAodGVybWluYXRpb25XYXRjaGVzLmNvbnRhaW5zKHNlcnZlcikpCgkJCXJldHVybjsKCQoJCXRlcm1pbmF0aW9uV2F0Y2hlcy5hZGQoc2VydmVyKTsKCQoJCWNsYXNzIFRlcm1pbmF0ZVRocmVhZCBleHRlbmRzIFRocmVhZCB7CgkJCXB1YmxpYyBib29sZWFuIGFsaXZlID0gdHJ1ZTsKCQkJcHVibGljIElTZXJ2ZXJMaXN0ZW5lciBsaXN0ZW5lcjsKCQoJCQlwdWJsaWMgdm9pZCBydW4oKSB7CgkJCQl3aGlsZSAoYWxpdmUpIHsKCQkJCQlTZXJ2ZXJUeXBlIHNlcnZlclR5cGUgPSAoU2VydmVyVHlwZSkgc2VydmVyLmdldFNlcnZlclR5cGUoKTsKCQkJCQlpbnQgZGVsYXkgPSBzZXJ2ZXJUeXBlLmdldFN0YXJ0VGltZW91dCgpOwoJCQkJCWlmIChtb2RlID09IDEpCgkJCQkJCWRlbGF5ID0gc2VydmVyVHlwZS5nZXRTdG9wVGltZW91dCgpOwoJCQkJCWVsc2UgaWYgKG1vZGUgPT0gMikKCQkJCQkJZGVsYXkgKz0gc2VydmVyVHlwZS5nZXRTdG9wVGltZW91dCgpOwoJCQkJCQoJCQkJCWlmIChkZWxheSA8IDApCgkJCQkJCXJldHVybjsKCQkJCQkKCQkJCQl0cnkgewoJCQkJCQlUaHJlYWQuc2xlZXAoZGVsYXkpOwoJCQkJCX0gY2F0Y2ggKEludGVycnVwdGVkRXhjZXB0aW9uIGUpIHsKCQkJCQkJLy8gaWdub3JlCgkJCQkJfQoJCQkJCQoJCQkJCWlmIChzZXJ2ZXIuZ2V0U2VydmVyU3RhdGUoKSA9PSBJU2VydmVyLlNUQVRFX1NUT1BQRUQpCgkJCQkJCWFsaXZlID0gZmFsc2U7CgkKCQkJCQlpZiAoYWxpdmUpIHsKCQkJCQkJRGlzcGxheS5nZXREZWZhdWx0KCkuc3luY0V4ZWMobmV3IFJ1bm5hYmxlKCkgewoJCQkJCQkJcHVibGljIHZvaWQgcnVuKCkgewoJCQkJCQkJCVRlcm1pbmF0aW9uRGlhbG9nIGRpYWxvZyA9IG5ldyBUZXJtaW5hdGlvbkRpYWxvZyhzaGVsbCwgc2VydmVyLmdldE5hbWUoKSk7CgkJCQkJCQkJZGlhbG9nLm9wZW4oKTsKCQkJCQkJCQlpZiAoZGlhbG9nLmdldFJldHVybkNvZGUoKSA9PSBJRGlhbG9nQ29uc3RhbnRzLk9LX0lEKSB7CgkJCQkJCQkJCS8vIG9ubHkgdHJ5IGNhbGxpbmcgdGVybWluYXRlIG9uY2UuIEFsc28sIG1ha2Ugc3VyZSB0aGF0IGl0IGRpZG4ndCBzdG9wIHdoaWxlCgkJCQkJCQkJCS8vIHRoZSBkaWFsb2cgd2FzIG9wZW4KCQkJCQkJCQkJaWYgKHNlcnZlci5nZXRTZXJ2ZXJTdGF0ZSgpICE9IElTZXJ2ZXIuU1RBVEVfU1RPUFBFRCkKCQkJCQkJCQkJCXNlcnZlci5zdG9wKHRydWUpOwoJCQkJCQkJCQlhbGl2ZSA9IGZhbHNlOwoJCQkJCQkJCX0KCQkJCQkJCX0KCQkJCQkJfSk7CgkJCQkJfQoJCQkJCWlmICghYWxpdmUpIHsKCQkJCQkJaWYgKGxpc3RlbmVyICE9IG51bGwpCgkJCQkJCQlzZXJ2ZXIucmVtb3ZlU2VydmVyTGlzdGVuZXIobGlzdGVuZXIpOwoJCQkJCQl0ZXJtaW5hdGlvbldhdGNoZXMucmVtb3ZlKHNlcnZlcik7CgkJCQkJfQoJCQkJfQoJCQl9CgkJfQoJCgkJZmluYWwgVGVybWluYXRlVGhyZWFkIHQgPSBuZXcgVGVybWluYXRlVGhyZWFkKCk7CgkJdC5zZXREYWVtb24odHJ1ZSk7CgkJdC5zZXRQcmlvcml0eShUaHJlYWQuTk9STV9QUklPUklUWSAtIDIpOwoJCgkJLy8gYWRkIGxpc3RlbmVyIHRvIHN0b3AgdGhlIHRocmVhZCBpZi93aGVuIHRoZSBzZXJ2ZXIgc3RvcHMKCQlJU2VydmVyTGlzdGVuZXIgbGlzdGVuZXIgPSBuZXcgSVNlcnZlckxpc3RlbmVyKCkgewoJCQlwdWJsaWMgdm9pZCBzZXJ2ZXJDaGFuZ2VkKFNlcnZlckV2ZW50IGV2ZW50KSB7CgkJCQlpbnQgZXZlbnRLaW5kID0gZXZlbnQuZ2V0S2luZCgpOwoJCQkJSVNlcnZlciBzZXJ2ZXIyID0gZXZlbnQuZ2V0U2VydmVyKCk7CgkJCQlpZiAoZXZlbnRLaW5kID09IChTZXJ2ZXJFdmVudC5TRVJWRVJfQ0hBTkdFIHwgU2VydmVyRXZlbnQuU1RBVEVfQ0hBTkdFKSkgewoJCQkJCWlmIChzZXJ2ZXIyLmdldFNlcnZlclN0YXRlKCkgPT0gSVNlcnZlci5TVEFURV9TVE9QUEVEICYmIHQgIT0gbnVsbCkKCQkJCQkJdC5hbGl2ZSA9IGZhbHNlOwoJCQkJfQoJCQl9CgkJfTsKCQl0Lmxpc3RlbmVyID0gbGlzdGVuZXI7CgkJc2VydmVyLmFkZFNlcnZlckxpc3RlbmVyKGxpc3RlbmVyKTsKCQoJCXQuc3RhcnQoKTsKCX0KCQoJLy9wcm90ZWN0ZWQgc3RhdGljIGZpbmFsIFN0cmluZyBNT0RVTEVfQVJUSUZBQ1RfQ0xBU1MgPSAib3JnLmVjbGlwc2Uud3N0LnNlcnZlci5jb3JlLklNb2R1bGVBcnRpZmFjdCI7CgkKCS8qKgoJICogUmV0dXJucyB0aGUgbW9kdWxlIGFydGlmYWN0IGZvciB0aGUgZ2l2ZW4gb2JqZWN0LCBvciBudWxsIGlmIGEgbW9kdWxlIGFydGlmYWN0CgkgKiBjYW4ndCBiZSBmb3VuZC4KCSAqCgkgKiBAcmV0dXJuIHRoZSBtb2R1bGUgYXJ0aWZhY3QKCSAqLwoJLypwdWJsaWMgc3RhdGljIGJvb2xlYW4gaGFzTW9kdWxlQXJ0aWZhY3QoT2JqZWN0IGFkYXB0YWJsZSkgewoJCWlmIChhZGFwdGFibGUgaW5zdGFuY2VvZiBJTW9kdWxlQXJ0aWZhY3QpCgkJCXJldHVybiB0cnVlOwoJCQoJCXJldHVybiBQbGF0Zm9ybS5nZXRBZGFwdGVyTWFuYWdlcigpLmhhc0FkYXB0ZXIoYWRhcHRhYmxlLCBNT0RVTEVfQVJUSUZBQ1RfQ0xBU1MpOwoJfSovCgkKCS8qKgoJICogUmV0dXJucyB0aGUgbW9kdWxlIGFydGlmYWN0IGZvciB0aGUgZ2l2ZW4gb2JqZWN0LCBvciBudWxsIGlmIGEgbW9kdWxlIGFydGlmYWN0CgkgKiBjYW4ndCBiZSBmb3VuZC4KCSAqCgkgKiBAcmV0dXJuIHRoZSBtb2R1bGUgYXJ0aWZhY3QKCSAqLwoJLypwdWJsaWMgc3RhdGljIElNb2R1bGVBcnRpZmFjdCBnZXRNb2R1bGVBcnRpZmFjdChPYmplY3QgYWRhcHRhYmxlKSB7CgkJaWYgKGFkYXB0YWJsZSBpbnN0YW5jZW9mIElNb2R1bGVBcnRpZmFjdCkKCQkJcmV0dXJuIChJTW9kdWxlQXJ0aWZhY3QpIGFkYXB0YWJsZTsKCQkKCQlpZiAoUGxhdGZvcm0uZ2V0QWRhcHRlck1hbmFnZXIoKS5oYXNBZGFwdGVyKGFkYXB0YWJsZSwgTU9EVUxFX0FSVElGQUNUX0NMQVNTKSkgewoJCQlyZXR1cm4gKElNb2R1bGVBcnRpZmFjdCkgUGxhdGZvcm0uZ2V0QWRhcHRlck1hbmFnZXIoKS5nZXRBZGFwdGVyKGFkYXB0YWJsZSwgTU9EVUxFX0FSVElGQUNUX0NMQVNTKTsKCQl9CgkJCgkJcmV0dXJuIG51bGw7Cgl9Ki8KCgkvKioKCSAqIFJldHVybnMgdGhlIG1vZHVsZSBhcnRpZmFjdCBmb3IgdGhlIGdpdmVuIG9iamVjdCwgb3IgbnVsbCBpZiBhIG1vZHVsZSBhcnRpZmFjdAoJICogY2FuJ3QgYmUgZm91bmQuCgkgKgoJICogQHJldHVybiB0aGUgbW9kdWxlIGFydGlmYWN0CgkgKi8KCS8qcHVibGljIHN0YXRpYyBJTW9kdWxlQXJ0aWZhY3QgbG9hZE1vZHVsZUFydGlmYWN0KE9iamVjdCBvYmopIHsKCQlpZiAob2JqIGluc3RhbmNlb2YgSU1vZHVsZUFydGlmYWN0KQoJCQlyZXR1cm4gKElNb2R1bGVBcnRpZmFjdCkgb2JqOwoJCQoJCWlmIChQbGF0Zm9ybS5nZXRBZGFwdGVyTWFuYWdlcigpLmhhc0FkYXB0ZXIob2JqLCBNT0RVTEVfQVJUSUZBQ1RfQ0xBU1MpKSB7CgkJCXJldHVybiAoSU1vZHVsZUFydGlmYWN0KSBQbGF0Zm9ybS5nZXRBZGFwdGVyTWFuYWdlcigpLmxvYWRBZGFwdGVyKG9iaiwgTU9EVUxFX0FSVElGQUNUX0NMQVNTKTsKCQl9CgkJCgkJcmV0dXJuIG51bGw7Cgl9Ki8KCQoJLyoqCgkgKiBSZXR1cm5zIHRoZSBzZXJ2ZXIgdGhhdCBjYW1lIGZyb20gdGhlIGdpdmVuIGZpbGUsIG9yIDxjb2RlPm51bGw8L2NvZGU+CgkgKiBpZiBub25lLiBUaGlzIGNvbnZlbmllbmNlIG1ldGhvZCBzZWFyY2hlcyB0aGUgbGlzdCBvZiBrbm93bgoJICogc2VydmVycyAoe0BsaW5rIFNlcnZlckNvcmUjZ2V0U2VydmVycygpfSkgZm9yIHRoZSBvbmUgd2l0aCBhIG1hdGNoaW5nCgkgKiBsb2NhdGlvbiAoe0BsaW5rIElTZXJ2ZXIjZ2V0RmlsZSgpfSkuIFRoZSBmaWxlIG1heSBub3QgYmUgbnVsbC4KCSAqCgkgKiBAcGFyYW0gZmlsZSBhIHNlcnZlciBmaWxlCgkgKiBAcmV0dXJuIHRoZSBzZXJ2ZXIgaW5zdGFuY2UsIG9yIDxjb2RlPm51bGw8L2NvZGU+IGlmIAoJICogdGhlcmUgaXMgbm8gc2VydmVyIGFzc29jaWF0ZWQgd2l0aCB0aGUgZ2l2ZW4gZmlsZQoJICovCglwdWJsaWMgc3RhdGljIElTZXJ2ZXIgZmluZFNlcnZlcihJRmlsZSBmaWxlKSB7CgkJaWYgKGZpbGUgPT0gbnVsbCkKCQkJdGhyb3cgbmV3IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOwoJCQoJCUlTZXJ2ZXJbXSBzZXJ2ZXJzID0gU2VydmVyQ29yZS5nZXRTZXJ2ZXJzKCk7CgkJaWYgKHNlcnZlcnMgIT0gbnVsbCkgewoJCQlpbnQgc2l6ZSA9IHNlcnZlcnMubGVuZ3RoOwoJCQlmb3IgKGludCBpID0gMDsgaSA8IHNpemU7IGkrKykgewoJCQkJaWYgKGZpbGUuZXF1YWxzKCgoU2VydmVyKXNlcnZlcnNbaV0pLmdldEZpbGUoKSkpCgkJCQkJcmV0dXJuIHNlcnZlcnNbaV07CgkJCX0KCQl9CgkJcmV0dXJuIG51bGw7Cgl9CgkKCS8qKgoJICogUmV0dXJucyBhbiBhcnJheSBvZiBhbGwga25vd24gcnVudGltZSBpbnN0YW5jZXMgb2YKCSAqIHRoZSBnaXZlbiBydW50aW1lIHR5cGUuIFRoaXMgY29udmVuaWVuY2UgbWV0aG9kIGZpbHRlcnMgdGhlIGxpc3Qgb2Yga25vd24KCSAqIHJ1bnRpbWUgKHtAbGluayBTZXJ2ZXJDb3JlI2dldFJ1bnRpbWVzKCl9KSBmb3Igb25lcyB3aXRoIGEgbWF0Y2hpbmcKCSAqIHJ1bnRpbWUgdHlwZSAoe0BsaW5rIElSdW50aW1lI2dldFJ1bnRpbWVUeXBlKCl9KS4gVGhlIGFycmF5IHdpbGwgbm90CgkgKiBjb250YWluIGFueSB3b3JraW5nIGNvcGllcy4KCSAqIDxwPgoJICogQSBuZXcgYXJyYXkgaXMgcmV0dXJuZWQgb24gZWFjaCBjYWxsLCBzbyBjbGllbnRzIG1heSBzdG9yZSBvciBtb2RpZnkgdGhlIHJlc3VsdC4KCSAqIDwvcD4KCSAqIAoJICogQHBhcmFtIHJ1bnRpbWVUeXBlIHRoZSBydW50aW1lIHR5cGUKCSAqIEByZXR1cm4gYSBwb3NzaWJseS1lbXB0eSBsaXN0IG9mIHJ1bnRpbWUgaW5zdGFuY2VzIHtAbGluayBJUnVudGltZX0KCSAqIG9mIHRoZSBnaXZlbiBydW50aW1lIHR5cGUKCSAqLwoJcHVibGljIHN0YXRpYyBJUnVudGltZVtdIGdldFJ1bnRpbWVzKElSdW50aW1lVHlwZSBydW50aW1lVHlwZSkgewoJCUxpc3QgbGlzdCA9IG5ldyBBcnJheUxpc3QoKTsKCQlJUnVudGltZVtdIHJ1bnRpbWVzID0gU2VydmVyQ29yZS5nZXRSdW50aW1lcygpOwoJCWlmIChydW50aW1lcyAhPSBudWxsKSB7CgkJCWludCBzaXplID0gcnVudGltZXMubGVuZ3RoOwoJCQlmb3IgKGludCBpID0gMDsgaSA8IHNpemU7IGkrKykgewoJCQkJaWYgKHJ1bnRpbWVzW2ldLmdldFJ1bnRpbWVUeXBlKCkgIT0gbnVsbCAmJiBydW50aW1lc1tpXS5nZXRSdW50aW1lVHlwZSgpLmVxdWFscyhydW50aW1lVHlwZSkpCgkJCQkJbGlzdC5hZGQocnVudGltZXNbaV0pOwoJCQl9CgkJfQoJCQoJCUlSdW50aW1lW10gciA9IG5ldyBJUnVudGltZVtsaXN0LnNpemUoKV07CgkJbGlzdC50b0FycmF5KHIpOwoJCXJldHVybiByOwoJfQoJCgkvKioKCSAqIE9wZW4gdGhlIGdpdmVuIHNlcnZlciB3aXRoIHRoZSBzZXJ2ZXIgZWRpdG9yLgoJICoKCSAqIEBwYXJhbSBzZXJ2ZXIKCSAqLwoJcHVibGljIHN0YXRpYyB2b2lkIGVkaXRTZXJ2ZXIoSVNlcnZlciBzZXJ2ZXIpIHsKCQlpZiAoc2VydmVyID09IG51bGwpCgkJCXJldHVybjsKCgkJZWRpdFNlcnZlcihzZXJ2ZXIuZ2V0SWQoKSk7Cgl9CgoJLyoqCgkgKiBPcGVuIHRoZSBnaXZlbiBzZXJ2ZXIgaWQgd2l0aCB0aGUgc2VydmVyIGVkaXRvci4KCSAqCgkgKiBAcGFyYW0gc2VydmVySWQKCSAqLwoJcHJvdGVjdGVkIHN0YXRpYyB2b2lkIGVkaXRTZXJ2ZXIoU3RyaW5nIHNlcnZlcklkKSB7CgkJaWYgKHNlcnZlcklkID09IG51bGwpCgkJCXJldHVybjsKCgkJSVdvcmtiZW5jaFdpbmRvdyB3b3JrYmVuY2hXaW5kb3cgPSBTZXJ2ZXJVSVBsdWdpbi5nZXRJbnN0YW5jZSgpLmdldFdvcmtiZW5jaCgpLmdldEFjdGl2ZVdvcmtiZW5jaFdpbmRvdygpOwoJCUlXb3JrYmVuY2hQYWdlIHBhZ2UgPSB3b3JrYmVuY2hXaW5kb3cuZ2V0QWN0aXZlUGFnZSgpOwoKCQl0cnkgewoJCQlJU2VydmVyRWRpdG9ySW5wdXQgaW5wdXQgPSBuZXcgU2VydmVyRWRpdG9ySW5wdXQoc2VydmVySWQpOwoJCQlwYWdlLm9wZW5FZGl0b3IoaW5wdXQsIElTZXJ2ZXJFZGl0b3JJbnB1dC5FRElUT1JfSUQpOwoJCX0gY2F0Y2ggKEV4Y2VwdGlvbiBlKSB7CgkJCVRyYWNlLnRyYWNlKFRyYWNlLlNFVkVSRSwgIkVycm9yIG9wZW5pbmcgc2VydmVyIGVkaXRvciIsIGUpOwoJCX0KCX0KCQoJLyoqCgkgKiBVc2UgdGhlIHByZWZlcmVuY2UgdG8gcHJvbXB0IHRoZSB1c2VyIHRvIHNhdmUgZGlydHkgZWRpdG9ycywgaWYgYXBwbGljYWJsZS4KCSAqIAoJICogQHJldHVybiBib29sZWFuICAtIFJldHVybnMgZmFsc2UgaWYgdGhlIHVzZXIgY2FuY2VsbGVkIHRoZSBvcGVyYXRpb24KCSAqLwoJcHVibGljIHN0YXRpYyBib29sZWFuIHNhdmVFZGl0b3JzKCkgewoJCWJ5dGUgYiA9IFNlcnZlclVJUGx1Z2luLmdldFByZWZlcmVuY2VzKCkuZ2V0U2F2ZUVkaXRvcnMoKTsKCQlpZiAoYiA9PSBTZXJ2ZXJVSVByZWZlcmVuY2VzLlNBVkVfRURJVE9SU19ORVZFUikKCQkJcmV0dXJuIHRydWU7CgkJcmV0dXJuIFNlcnZlclVJUGx1Z2luLmdldEluc3RhbmNlKCkuZ2V0V29ya2JlbmNoKCkuc2F2ZUFsbEVkaXRvcnMoYiA9PSBTZXJ2ZXJVSVByZWZlcmVuY2VzLlNBVkVfRURJVE9SU19QUk9NUFQpOwkJCQoJfQoJCgkvKioKCSAqIFByb21wdHMgdGhlIHVzZXIgaWYgdGhlIHNlcnZlciBpcyBkaXJ0eS4gUmV0dXJucyB0cnVlIGlmIHRoZSBzZXJ2ZXIgd2FzCgkgKiBub3QgZGlydHkgb3IgaWYgdGhlIHVzZXIgZGVjaWRlZCB0byBjb250aW51ZSBhbnl3YXkuIFJldHVybnMgZmFsc2UgaWYKCSAqIHRoZSBzZXJ2ZXIgaXMgZGlydHkgYW5kIHRoZSB1c2VyIGNob3NlIHRvIGNhbmNlbCB0aGUgb3BlcmF0aW9uLgoJICoKCSAqIEByZXR1cm4gYm9vbGVhbgoJICovCglwdWJsaWMgc3RhdGljIGJvb2xlYW4gcHJvbXB0SWZEaXJ0eShTaGVsbCBzaGVsbCwgSVNlcnZlciBzZXJ2ZXIpIHsKCQlpZiAoc2VydmVyID09IG51bGwpCgkJCXJldHVybiBmYWxzZTsKCQkKCQlpZiAoIShzZXJ2ZXIgaW5zdGFuY2VvZiBJU2VydmVyV29ya2luZ0NvcHkpKQoJCQlyZXR1cm4gdHJ1ZTsKCgkJU3RyaW5nIHRpdGxlID0gU2VydmVyVUlQbHVnaW4uZ2V0UmVzb3VyY2UoIiVyZXNvdXJjZURpcnR5RGlhbG9nVGl0bGUiKTsKCQkKCQlJU2VydmVyV29ya2luZ0NvcHkgd2MgPSAoSVNlcnZlcldvcmtpbmdDb3B5KSBzZXJ2ZXI7CgkJaWYgKHdjLmlzRGlydHkoKSkgewoJCQlTdHJpbmcgbWVzc2FnZSA9IFNlcnZlclVJUGx1Z2luLmdldFJlc291cmNlKCIlcmVzb3VyY2VEaXJ0eURpYWxvZ01lc3NhZ2UiLCBzZXJ2ZXIuZ2V0TmFtZSgpKTsKCQkJU3RyaW5nW10gbGFiZWxzID0gbmV3IFN0cmluZ1tdIHtTZXJ2ZXJVSVBsdWdpbi5nZXRSZXNvdXJjZSgiJXJlc291cmNlRGlydHlEaWFsb2dDb250aW51ZSIpLCBJRGlhbG9nQ29uc3RhbnRzLkNBTkNFTF9MQUJFTH07CgkJCU1lc3NhZ2VEaWFsb2cgZGlhbG9nID0gbmV3IE1lc3NhZ2VEaWFsb2coc2hlbGwsIHRpdGxlLCBudWxsLCBtZXNzYWdlLCBNZXNzYWdlRGlhbG9nLklORk9STUFUSU9OLCBsYWJlbHMsIDApOwoJCgkJCWlmIChkaWFsb2cub3BlbigpICE9IDApCgkJCQlyZXR1cm4gZmFsc2U7CgkJfQoJCgkJcmV0dXJuIHRydWU7Cgl9CgkKCXByb3RlY3RlZCBzdGF0aWMgdm9pZCBzaG93U2VydmVyc1ZpZXcoKSB7CgkJaWYgKCFnZXRQcmVmZXJlbmNlcygpLmdldFNob3dPbkFjdGl2aXR5KCkpCgkJCXJldHVybjsKCQkKCQlEaXNwbGF5LmdldERlZmF1bHQoKS5hc3luY0V4ZWMobmV3IFJ1bm5hYmxlKCkgewoJCQlwdWJsaWMgdm9pZCBydW4oKSB7CgkJCQl0cnkgewoJCQkJCUlXb3JrYmVuY2ggd29ya2JlbmNoID0gU2VydmVyVUlQbHVnaW4uZ2V0SW5zdGFuY2UoKS5nZXRXb3JrYmVuY2goKTsKCQkJCQlJV29ya2JlbmNoV2luZG93IHdvcmtiZW5jaFdpbmRvdyA9IHdvcmtiZW5jaC5nZXRBY3RpdmVXb3JrYmVuY2hXaW5kb3coKTsKCQoJCQkJCUlXb3JrYmVuY2hQYWdlIHBhZ2UgPSB3b3JrYmVuY2hXaW5kb3cuZ2V0QWN0aXZlUGFnZSgpOwoJCgkJCQkJSVZpZXdQYXJ0IHZpZXcyID0gcGFnZS5maW5kVmlldyhWSUVXX0lEKTsKCQkJCQkKCQkJCQlpZiAodmlldzIgIT0gbnVsbCkKCQkJCQkJcGFnZS5icmluZ1RvVG9wKHZpZXcyKTsKCQkJCQllbHNlCgkJCQkJCXBhZ2Uuc2hvd1ZpZXcoVklFV19JRCk7CgkJCQl9IGNhdGNoIChFeGNlcHRpb24gZSkgewoJCQkJCVRyYWNlLnRyYWNlKFRyYWNlLlNFVkVSRSwgIkVycm9yIG9wZW5pbmcgVENQL0lQIHZpZXciLCBlKTsKCQkJCX0KCQkJfQoJCX0pOwoJfQoJCgkvKioKCSAqIFJldHVybnMgdHJ1ZSBpZiB0aGUgZ2l2ZW4gc2VydmVyIGlzIGFscmVhZHkgc3RhcnRlZCBpbiB0aGUgZ2l2ZW4KCSAqIG1vZGUsIG9yIGNvdWxkIGJlIChyZSlzdGFydGVkIGluIHRoZSBzdGFydCBtb2RlLgoJICogCgkgKiBAcGFyYW0gc2VydmVyCgkgKiBAcGFyYW0gbGF1bmNoTW9kZQoJICogQHJldHVybiBib29sZWFuCgkgKi8KCXB1YmxpYyBzdGF0aWMgYm9vbGVhbiBpc0NvbXBhdGlibGVXaXRoTGF1bmNoTW9kZShJU2VydmVyIHNlcnZlciwgU3RyaW5nIGxhdW5jaE1vZGUpIHsKCQlpZiAoc2VydmVyID09IG51bGwgfHwgbGF1bmNoTW9kZSA9PSBudWxsKQoJCQlyZXR1cm4gZmFsc2U7CgoJCWludCBzdGF0ZSA9IHNlcnZlci5nZXRTZXJ2ZXJTdGF0ZSgpOwoJCWlmIChzdGF0ZSA9PSBJU2VydmVyLlNUQVRFX1NUQVJURUQgJiYgbGF1bmNoTW9kZS5lcXVhbHMoc2VydmVyLmdldE1vZGUoKSkpCgkJCXJldHVybiB0cnVlOwoKCQlpZiAoc2VydmVyLmdldFNlcnZlclR5cGUoKS5zdXBwb3J0c0xhdW5jaE1vZGUobGF1bmNoTW9kZSkpCgkJCXJldHVybiB0cnVlOwoJCXJldHVybiBmYWxzZTsKCX0KCQoJLyoqCgkgKiBPcGVuIHRoZSBuZXcgcnVudGltZSB3aXphcmQuCgkgKiAKCSAqIEBwYXJhbSBzaGVsbAoJICogQHBhcmFtIHR5cGUKCSAqIEBwYXJhbSB2ZXJzaW9uCgkgKiBAcGFyYW0gcnVudGltZVR5cGVJZAoJICogQHJldHVybiB0cnVlIGlmIGEgbmV3IHJ1bnRpbWUgd2FzIGNyZWF0ZWQKCSAqLwoJcHVibGljIHN0YXRpYyBib29sZWFuIHNob3dOZXdSdW50aW1lV2l6YXJkKFNoZWxsIHNoZWxsLCBmaW5hbCBTdHJpbmcgdHlwZSwgZmluYWwgU3RyaW5nIHZlcnNpb24sIGZpbmFsIFN0cmluZyBydW50aW1lVHlwZUlkKSB7CgkJV2l6YXJkRnJhZ21lbnQgZnJhZ21lbnQgPSBuZXcgV2l6YXJkRnJhZ21lbnQoKSB7CgkJCXByb3RlY3RlZCB2b2lkIGNyZWF0ZUNoaWxkRnJhZ21lbnRzKExpc3QgbGlzdCkgewoJCQkJbGlzdC5hZGQobmV3IE5ld1J1bnRpbWVXaXphcmRGcmFnbWVudCh0eXBlLCB2ZXJzaW9uLCBydW50aW1lVHlwZUlkKSk7CgkJCQlsaXN0LmFkZChuZXcgRmluaXNoV2l6YXJkRnJhZ21lbnQobmV3IFNhdmVSdW50aW1lVGFzaygpKSk7CgkJCX0KCQl9OwoJCVRhc2tXaXphcmQgd2l6YXJkID0gbmV3IFRhc2tXaXphcmQoU2VydmVyVUlQbHVnaW4uZ2V0UmVzb3VyY2UoIiV3aXpOZXdSdW50aW1lV2l6YXJkVGl0bGUiKSwgZnJhZ21lbnQpOwoJCXdpemFyZC5zZXRGb3JjZVByZXZpb3VzQW5kTmV4dEJ1dHRvbnModHJ1ZSk7CgkJQ2xvc2FibGVXaXphcmREaWFsb2cgZGlhbG9nID0gbmV3IENsb3NhYmxlV2l6YXJkRGlhbG9nKHNoZWxsLCB3aXphcmQpOwoJCXJldHVybiAoZGlhbG9nLm9wZW4oKSA9PSBJRGlhbG9nQ29uc3RhbnRzLk9LX0lEKTsKCX0KCQoJLyoqCgkgKiBPcGVuIHRoZSBuZXcgcnVudGltZSB3aXphcmQuCgkgKiAKCSAqIEBwYXJhbSBzaGVsbAoJICogQHBhcmFtIHJ1bnRpbWVUeXBlSWQKCSAqIEByZXR1cm4gdHJ1ZSBpZiBhIG5ldyBydW50aW1lIHdhcyBjcmVhdGVkCgkgKi8KCXB1YmxpYyBzdGF0aWMgYm9vbGVhbiBzaG93TmV3UnVudGltZVdpemFyZChTaGVsbCBzaGVsbCwgZmluYWwgU3RyaW5nIHJ1bnRpbWVUeXBlSWQpIHsKCQlJUnVudGltZVR5cGUgcnVudGltZVR5cGUgPSBudWxsOwoJCWlmIChydW50aW1lVHlwZUlkICE9IG51bGwpCgkJCXJ1bnRpbWVUeXBlID0gU2VydmVyQ29yZS5maW5kUnVudGltZVR5cGUocnVudGltZVR5cGVJZCk7CgkJaWYgKHJ1bnRpbWVUeXBlICE9IG51bGwpIHsKCQkJdHJ5IHsKCQkJCWZpbmFsIElSdW50aW1lV29ya2luZ0NvcHkgcnVudGltZSA9IHJ1bnRpbWVUeXBlLmNyZWF0ZVJ1bnRpbWUobnVsbCwgbnVsbCk7CgkJCQlXaXphcmRGcmFnbWVudCBmcmFnbWVudCA9IG5ldyBXaXphcmRGcmFnbWVudCgpIHsKCQkJCQlwcm90ZWN0ZWQgdm9pZCBjcmVhdGVDaGlsZEZyYWdtZW50cyhMaXN0IGxpc3QpIHsKCQkJCQkJbGlzdC5hZGQobmV3IElucHV0V2l6YXJkRnJhZ21lbnQoVGFza01vZGVsLlRBU0tfUlVOVElNRSwgcnVudGltZSkpOwoJCQkJCQlsaXN0LmFkZChnZXRXaXphcmRGcmFnbWVudChydW50aW1lVHlwZUlkKSk7CgkJCQkJCWxpc3QuYWRkKG5ldyBGaW5pc2hXaXphcmRGcmFnbWVudChuZXcgU2F2ZVJ1bnRpbWVUYXNrKCkpKTsKCQkJCQl9CgkJCQl9OwoJCQkJVGFza1dpemFyZCB3aXphcmQgPSBuZXcgVGFza1dpemFyZChTZXJ2ZXJVSVBsdWdpbi5nZXRSZXNvdXJjZSgiJXdpek5ld1J1bnRpbWVXaXphcmRUaXRsZSIpLCBmcmFnbWVudCk7CgkJCQl3aXphcmQuc2V0Rm9yY2VQcmV2aW91c0FuZE5leHRCdXR0b25zKHRydWUpOwoJCQkJQ2xvc2FibGVXaXphcmREaWFsb2cgZGlhbG9nID0gbmV3IENsb3NhYmxlV2l6YXJkRGlhbG9nKHNoZWxsLCB3aXphcmQpOwoJCQkJcmV0dXJuIChkaWFsb2cub3BlbigpID09IElEaWFsb2dDb25zdGFudHMuT0tfSUQpOwoJCQl9IGNhdGNoIChFeGNlcHRpb24gZSkgewoJCQkJcmV0dXJuIGZhbHNlOwoJCQl9CgkJfQoJCXJldHVybiBzaG93TmV3UnVudGltZVdpemFyZChzaGVsbCwgbnVsbCwgbnVsbCwgcnVudGltZVR5cGVJZCk7Cgl9CgkKCS8qKgoJICogT3BlbiB0aGUgbmV3IHJ1bnRpbWUgd2l6YXJkLgoJICogQHBhcmFtIHNoZWxsCgkgKiBAcmV0dXJuIHRydWUgaWYgYSBuZXcgcnVudGltZSB3YXMgY3JlYXRlZAoJICovCglwdWJsaWMgc3RhdGljIGJvb2xlYW4gc2hvd05ld1J1bnRpbWVXaXphcmQoU2hlbGwgc2hlbGwpIHsKCQlyZXR1cm4gU2VydmVyVUlVdGlsLnNob3dOZXdSdW50aW1lV2l6YXJkKHNoZWxsLCBudWxsLCBudWxsKTsKCX0KCQoJLyoqCgkgKiBSZXR1cm5zIHRoZSB3aXphcmQgZnJhZ21lbnQgd2l0aCB0aGUgZ2l2ZW4gaWQuCgkgKgoJICogQHBhcmFtIHR5cGVJZCB0aGUgc2VydmVyIG9yIHJ1bnRpbWUgdHlwZSBpZAoJICogQHJldHVybiBhIHdpemFyZCBmcmFnbWVudCwgb3IgPGNvZGU+bnVsbDwvY29kZT4gaWYgbm9uZSBjb3VsZCBiZSBmb3VuZAoJICovCglwdWJsaWMgc3RhdGljIFdpemFyZEZyYWdtZW50IGdldFdpemFyZEZyYWdtZW50KFN0cmluZyB0eXBlSWQpIHsKCQlpZiAodHlwZUlkID09IG51bGwpCgkJCXJldHVybiBudWxsOwoKCQlpZiAod2l6YXJkRnJhZ21lbnRzID09IG51bGwpCgkJCWxvYWRXaXphcmRGcmFnbWVudHMoKTsKCQkKCQlJdGVyYXRvciBpdGVyYXRvciA9IHdpemFyZEZyYWdtZW50cy5rZXlTZXQoKS5pdGVyYXRvcigpOwoJCXdoaWxlIChpdGVyYXRvci5oYXNOZXh0KCkpIHsKCQkJU3RyaW5nIGtleSA9IChTdHJpbmcpIGl0ZXJhdG9yLm5leHQoKTsKCQkJaWYgKHR5cGVJZC5lcXVhbHMoa2V5KSkgewoJCQkJV2l6YXJkRnJhZ21lbnREYXRhIGRhdGEgPSAoV2l6YXJkRnJhZ21lbnREYXRhKSB3aXphcmRGcmFnbWVudHMuZ2V0KGtleSk7CgkJCQlyZXR1cm4gZ2V0V2l6YXJkRnJhZ21lbnQoZGF0YSk7CgkJCX0KCQl9CgkJcmV0dXJuIG51bGw7Cgl9CgoJLyoqCgkgKiBMb2FkIHRoZSB3aXphcmQgZnJhZ21lbnRzLgoJICovCglwcml2YXRlIHN0YXRpYyBzeW5jaHJvbml6ZWQgdm9pZCBsb2FkV2l6YXJkRnJhZ21lbnRzKCkgewoJCWlmICh3aXphcmRGcmFnbWVudHMgIT0gbnVsbCkKCQkJcmV0dXJuOwoJCVRyYWNlLnRyYWNlKFRyYWNlLkNPTkZJRywgIi0+LSBMb2FkaW5nIC53aXphcmRGcmFnbWVudHMgZXh0ZW5zaW9uIHBvaW50IC0+LSIpOwoJCUlFeHRlbnNpb25SZWdpc3RyeSByZWdpc3RyeSA9IFBsYXRmb3JtLmdldEV4dGVuc2lvblJlZ2lzdHJ5KCk7CgkJSUNvbmZpZ3VyYXRpb25FbGVtZW50W10gY2YgPSByZWdpc3RyeS5nZXRDb25maWd1cmF0aW9uRWxlbWVudHNGb3IoU2VydmVyVUlQbHVnaW4uUExVR0lOX0lELCAid2l6YXJkRnJhZ21lbnRzIik7CgoJCWludCBzaXplID0gY2YubGVuZ3RoOwoJCXdpemFyZEZyYWdtZW50cyA9IG5ldyBIYXNoTWFwKHNpemUpOwoJCWZvciAoaW50IGkgPSAwOyBpIDwgc2l6ZTsgaSsrKSB7CgkJCXRyeSB7CgkJCQlTdHJpbmcgaWQgPSBjZltpXS5nZXRBdHRyaWJ1dGUoInR5cGVJZHMiKTsKCQkJCXdpemFyZEZyYWdtZW50cy5wdXQoaWQsIG5ldyBXaXphcmRGcmFnbWVudERhdGEoaWQsIGNmW2ldKSk7CgkJCQlUcmFjZS50cmFjZShUcmFjZS5DT05GSUcsICIgIExvYWRlZCB3aXphcmRGcmFnbWVudDogIiArIGlkKTsKCQkJfSBjYXRjaCAoVGhyb3dhYmxlIHQpIHsKCQkJCVRyYWNlLnRyYWNlKFRyYWNlLlNFVkVSRSwgIiAgQ291bGQgbm90IGxvYWQgd2l6YXJkRnJhZ21lbnQ6ICIgKyBjZltpXS5nZXRBdHRyaWJ1dGUoImlkIiksIHQpOwoJCQl9CgkJfQoJCQoJCVRyYWNlLnRyYWNlKFRyYWNlLkNPTkZJRywgIi08LSBEb25lIGxvYWRpbmcgLndpemFyZEZyYWdtZW50cyBleHRlbnNpb24gcG9pbnQgLTwtIik7Cgl9CgoJcHJvdGVjdGVkIHN0YXRpYyBXaXphcmRGcmFnbWVudCBnZXRXaXphcmRGcmFnbWVudChXaXphcmRGcmFnbWVudERhdGEgZnJhZ21lbnQpIHsKCQlpZiAoZnJhZ21lbnQgPT0gbnVsbCkKCQkJcmV0dXJuIG51bGw7CgkKCQlpZiAoZnJhZ21lbnQuZnJhZ21lbnQgPT0gbnVsbCkgewoJCQl0cnkgewoJCQkJZnJhZ21lbnQuZnJhZ21lbnQgPSAoV2l6YXJkRnJhZ21lbnQpIGZyYWdtZW50LmNlLmNyZWF0ZUV4ZWN1dGFibGVFeHRlbnNpb24oImNsYXNzIik7CgkJCX0gY2F0Y2ggKFRocm93YWJsZSB0KSB7CgkJCQlUcmFjZS50cmFjZShUcmFjZS5TRVZFUkUsICJDb3VsZCBub3QgY3JlYXRlIHdpemFyZEZyYWdtZW50OiAiICsgZnJhZ21lbnQuY2UuZ2V0QXR0cmlidXRlKCJpZCIpLCB0KTsKCQkJfQoJCX0KCQlyZXR1cm4gZnJhZ21lbnQuZnJhZ21lbnQ7Cgl9CgkKCXB1YmxpYyBzdGF0aWMgdm9pZCBydW5PblNlcnZlcihPYmplY3Qgb2JqZWN0LCBTdHJpbmcgbGF1bmNoTW9kZSkgewoJCVJ1bk9uU2VydmVyQWN0aW9uRGVsZWdhdGUgZGVsZWdhdGUgPSBuZXcgUnVuT25TZXJ2ZXJBY3Rpb25EZWxlZ2F0ZSgpOwoJCUFjdGlvbiBhY3Rpb24gPSBuZXcgQWN0aW9uKCkgewoJCQkvLyBkdW1teSBhY3Rpb24KCQl9OwoJCWlmIChvYmplY3QgIT0gbnVsbCkgewoJCQlTdHJ1Y3R1cmVkU2VsZWN0aW9uIHNlbCA9IG5ldyBTdHJ1Y3R1cmVkU2VsZWN0aW9uKG9iamVjdCk7CgkJCWRlbGVnYXRlLnNlbGVjdGlvbkNoYW5nZWQoYWN0aW9uLCBzZWwpOwoJCX0gZWxzZQoJCQlkZWxlZ2F0ZS5zZWxlY3Rpb25DaGFuZ2VkKGFjdGlvbiwgbnVsbCk7CgoJCWRlbGVnYXRlLnJ1bihhY3Rpb24pOwoJfQp9