LyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogQ29weXJpZ2h0IChjKSAyMDAzLCAyMDA0IElCTSBDb3Jwb3JhdGlvbiBhbmQgb3RoZXJzLgogKiBBbGwgcmlnaHRzIHJlc2VydmVkLiBUaGlzIHByb2dyYW0gYW5kIHRoZSBhY2NvbXBhbnlpbmcgbWF0ZXJpYWxzCiAqIGFyZSBtYWRlIGF2YWlsYWJsZSB1bmRlciB0aGUgdGVybXMgb2YgdGhlIENvbW1vbiBQdWJsaWMgTGljZW5zZSB2MS4wCiAqIHdoaWNoIGFjY29tcGFuaWVzIHRoaXMgZGlzdHJpYnV0aW9uLCBhbmQgaXMgYXZhaWxhYmxlIGF0CiAqIGh0dHA6Ly93d3cuZWNsaXBzZS5vcmcvbGVnYWwvY3BsLXYxMC5odG1sCqAqCiAqIENvbnRyaWJ1dG9yczoKICogICAgSUJNIC0gSW5pdGlhbCBBUEkgYW5kIGltcGxlbWVudGF0aW9uCiAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwpwYWNrYWdlIG9yZy5lY2xpcHNlLndzdC5zZXJ2ZXIudWkuaW50ZXJuYWwuYWN0aW9uczsKCmltcG9ydCBqYXZhLmJlYW5zLlByb3BlcnR5Q2hhbmdlRXZlbnQ7CmltcG9ydCBqYXZhLmJlYW5zLlByb3BlcnR5Q2hhbmdlTGlzdGVuZXI7CmltcG9ydCBqYXZhLnV0aWwuQXJyYXlMaXN0OwppbXBvcnQgamF2YS51dGlsLkhhc2hNYXA7CmltcG9ydCBqYXZhLnV0aWwuSXRlcmF0b3I7CmltcG9ydCBqYXZhLnV0aWwuTGlzdDsKaW1wb3J0IGphdmEudXRpbC5NYXA7CgppbXBvcnQgb3JnLmVjbGlwc2UuY29yZS5yZXNvdXJjZXMuSVByb2plY3Q7CmltcG9ydCBvcmcuZWNsaXBzZS5jb3JlLnJ1bnRpbWUuKjsKaW1wb3J0IG9yZy5lY2xpcHNlLmRlYnVnLmNvcmUuSUxhdW5jaE1hbmFnZXI7CmltcG9ydCBvcmcuZWNsaXBzZS5qZmFjZS5hY3Rpb24uSUFjdGlvbjsKaW1wb3J0IG9yZy5lY2xpcHNlLmpmYWNlLmRpYWxvZ3MuRXJyb3JEaWFsb2c7CmltcG9ydCBvcmcuZWNsaXBzZS5qZmFjZS5kaWFsb2dzLklEaWFsb2dDb25zdGFudHM7CmltcG9ydCBvcmcuZWNsaXBzZS5qZmFjZS5kaWFsb2dzLk1lc3NhZ2VEaWFsb2c7CmltcG9ydCBvcmcuZWNsaXBzZS5qZmFjZS52aWV3ZXJzLklTZWxlY3Rpb247CmltcG9ydCBvcmcuZWNsaXBzZS5qZmFjZS52aWV3ZXJzLklTdHJ1Y3R1cmVkU2VsZWN0aW9uOwppbXBvcnQgb3JnLmVjbGlwc2UuamZhY2Uud2luZG93LldpbmRvdzsKaW1wb3J0IG9yZy5lY2xpcHNlLmpmYWNlLndpemFyZC5XaXphcmREaWFsb2c7CmltcG9ydCBvcmcuZWNsaXBzZS53c3Quc2VydmVyLmNvcmUuKjsKaW1wb3J0IG9yZy5lY2xpcHNlLndzdC5zZXJ2ZXIuY29yZS5pbnRlcm5hbC5UcmFjZTsKaW1wb3J0IG9yZy5lY2xpcHNlLndzdC5zZXJ2ZXIudWkuU2VydmVyVUlVdGlsOwppbXBvcnQgb3JnLmVjbGlwc2Uud3N0LnNlcnZlci51aS5pbnRlcm5hbC4qOwppbXBvcnQgb3JnLmVjbGlwc2Uud3N0LnNlcnZlci51aS5pbnRlcm5hbC53aXphcmQuKjsKaW1wb3J0IG9yZy5lY2xpcHNlLnN3dC53aWRnZXRzLlNoZWxsOwppbXBvcnQgb3JnLmVjbGlwc2UudWkuSVdvcmtiZW5jaFdpbmRvdzsKaW1wb3J0IG9yZy5lY2xpcHNlLnVpLklXb3JrYmVuY2hXaW5kb3dBY3Rpb25EZWxlZ2F0ZTsKLyoqCiAqIFN1cHBvcnQgZm9yIHN0YXJ0aW5nL3N0b3BwaW5nIHNlcnZlciBhbmQgY2xpZW50cyBmb3IgcmVzb3VyY2VzIHJ1bm5pbmcgb24gYSBzZXJ2ZXIuCiAqLwpwdWJsaWMgY2xhc3MgUnVuT25TZXJ2ZXJBY3Rpb25EZWxlZ2F0ZSBpbXBsZW1lbnRzIElXb3JrYmVuY2hXaW5kb3dBY3Rpb25EZWxlZ2F0ZSB7Cglwcm90ZWN0ZWQgc3RhdGljIGZpbmFsIFN0cmluZ1tdIGxhdW5jaE1vZGVzID0gewoJCUlMYXVuY2hNYW5hZ2VyLlJVTl9NT0RFLCBJTGF1bmNoTWFuYWdlci5ERUJVR19NT0RFLCBJTGF1bmNoTWFuYWdlci5QUk9GSUxFX01PREUgfTsKCglwcm90ZWN0ZWQgT2JqZWN0IHNlbGVjdGlvbjsKCglwcm90ZWN0ZWQgSVdvcmtiZW5jaFdpbmRvdyB3aW5kb3c7CgkKCXByb3RlY3RlZCBzdGF0aWMgYm9vbGVhbiBpbml0aWFsaXplZCA9IGZhbHNlOwoJCglwcm90ZWN0ZWQgc3RhdGljIE9iamVjdCBnbG9iYWxTZWxlY3Rpb247CgoJcHJvdGVjdGVkIHN0YXRpYyBNYXAgZ2xvYmFsTGF1bmNoTW9kZTsKCglwcml2YXRlIHN0YXRpYyB0cmFuc2llbnQgTGlzdCBwcm9wZXJ0eUxpc3RlbmVyczsKCgkvKioKCSAqIFJ1bk9uU2VydmVyQWN0aW9uRGVsZWdhdGUgY29uc3RydWN0b3IgY29tbWVudC4KCSAqLwoJcHVibGljIFJ1bk9uU2VydmVyQWN0aW9uRGVsZWdhdGUoKSB7CgkJc3VwZXIoKTsKCX0KCgkvKioKCSAqIERpc3Bvc2VzIHRoaXMgYWN0aW9uIGRlbGVnYXRlLiAgVGhlIGltcGxlbWVudG9yIHNob3VsZCB1bmhvb2sgYW55IHJlZmVyZW5jZXMKCSAqIHRvIGl0c2VsZiBzbyB0aGF0IGdhcmJhZ2UgY29sbGVjdGlvbiBjYW4gb2NjdXIuCgkgKi8KCXB1YmxpYyB2b2lkIGRpc3Bvc2UoKSB7CgkJd2luZG93ID0gbnVsbDsKCX0KCgkvKioKCSAqIEluaXRpYWxpemVzIHRoaXMgYWN0aW9uIGRlbGVnYXRlIHdpdGggdGhlIHdvcmtiZW5jaCB3aW5kb3cgaXQgd2lsbCB3b3JrIGluLgoJICoKCSAqIEBwYXJhbSB3aW5kb3cgdGhlIHdpbmRvdyB0aGF0IHByb3ZpZGVzIHRoZSBjb250ZXh0IGZvciB0aGlzIGRlbGVnYXRlCgkgKi8KCXB1YmxpYyB2b2lkIGluaXQoSVdvcmtiZW5jaFdpbmRvdyBuZXdXaW5kb3cpIHsKCQl3aW5kb3cgPSBuZXdXaW5kb3c7Cgl9CgkKCS8qKgoJICogQWRkIGEgcHJvcGVydHkgY2hhbmdlIGxpc3RlbmVyIHRvIHRoaXMgc2VydmVyLgoJICoKCSAqIEBwYXJhbSBsaXN0ZW5lciBqYXZhLmJlYW5zLlByb3BlcnR5Q2hhbmdlTGlzdGVuZXIKCSAqLwoJcHVibGljIHN0YXRpYyB2b2lkIGFkZFByb3BlcnR5Q2hhbmdlTGlzdGVuZXIoUHJvcGVydHlDaGFuZ2VMaXN0ZW5lciBsaXN0ZW5lcikgewoJCWlmIChwcm9wZXJ0eUxpc3RlbmVycyA9PSBudWxsKQoJCQlwcm9wZXJ0eUxpc3RlbmVycyA9IG5ldyBBcnJheUxpc3QoKTsKCQlwcm9wZXJ0eUxpc3RlbmVycy5hZGQobGlzdGVuZXIpOwoJfQoJCgkvKioKCSAqIFJlbW92ZSBhIHByb3BlcnR5IGNoYW5nZSBsaXN0ZW5lciBmcm9tIHRoaXMgc2VydmVyLgoJICoKCSAqIEBwYXJhbSBsaXN0ZW5lciBqYXZhLmJlYW5zLlByb3BlcnR5Q2hhbmdlTGlzdGVuZXIKCSAqLwoJcHVibGljIHN0YXRpYyB2b2lkIHJlbW92ZVByb3BlcnR5Q2hhbmdlTGlzdGVuZXIoUHJvcGVydHlDaGFuZ2VMaXN0ZW5lciBsaXN0ZW5lcikgewoJCWlmIChwcm9wZXJ0eUxpc3RlbmVycyAhPSBudWxsKQoJCQlwcm9wZXJ0eUxpc3RlbmVycy5yZW1vdmUobGlzdGVuZXIpOwoJfQoJCgkvKioKCSAqIEZpcmUgYSBwcm9wZXJ0eSBjaGFuZ2UgZXZlbnQuCgkgKi8KCXByb3RlY3RlZCB2b2lkIGZpcmVQcm9wZXJ0eUNoYW5nZUV2ZW50KFN0cmluZyBwcm9wZXJ0eU5hbWUsIE9iamVjdCBvbGRWYWx1ZSwgT2JqZWN0IG5ld1ZhbHVlKSB7CgkJaWYgKHByb3BlcnR5TGlzdGVuZXJzID09IG51bGwpCgkJCXJldHVybjsKCQoJCVByb3BlcnR5Q2hhbmdlRXZlbnQgZXZlbnQgPSBuZXcgUHJvcGVydHlDaGFuZ2VFdmVudCh0aGlzLCBwcm9wZXJ0eU5hbWUsIG9sZFZhbHVlLCBuZXdWYWx1ZSk7CgkJdHJ5IHsKCQkJSXRlcmF0b3IgaXRlcmF0b3IgPSBwcm9wZXJ0eUxpc3RlbmVycy5pdGVyYXRvcigpOwoJCQl3aGlsZSAoaXRlcmF0b3IuaGFzTmV4dCgpKSB7CgkJCQl0cnkgewoJCQkJCVByb3BlcnR5Q2hhbmdlTGlzdGVuZXIgbGlzdGVuZXIgPSAoUHJvcGVydHlDaGFuZ2VMaXN0ZW5lcikgaXRlcmF0b3IubmV4dCgpOwoJCQkJCWxpc3RlbmVyLnByb3BlcnR5Q2hhbmdlKGV2ZW50KTsKCQkJCX0gY2F0Y2ggKEV4Y2VwdGlvbiBlKSB7CgkJCQkJVHJhY2UudHJhY2UoIkVycm9yIGZpcmluZyBwcm9wZXJ0eSBjaGFuZ2UgZXZlbnQiLCBlKTsKCQkJCX0KCQkJfQoJCX0gY2F0Y2ggKEV4Y2VwdGlvbiBlKSB7CgkJCVRyYWNlLnRyYWNlKCJFcnJvciBpbiBwcm9wZXJ0eSBldmVudCIsIGUpOwoJCX0KCX0KCgkvKioKCSAqIFJ1biB0aGUgcmVzb3VyY2Ugb24gYSBzZXJ2ZXIuCgkgKgoJICogQHBhcmFtIG1vbml0b3Igb3JnLmVjbGlwc2UuY29yZS5ydW50aW1lLklQcm9ncmVzc01vbml0b3IKCSAqLwoJcHJvdGVjdGVkIHZvaWQgcnVuKElQcm9ncmVzc01vbml0b3IgbW9uaXRvcikgewoJCVN0cmluZyBsYXVuY2hNb2RlID0gZ2V0TGF1bmNoTW9kZSgpOwoJCWZpcmVQcm9wZXJ0eUNoYW5nZUV2ZW50KCJsYXVuY2hNb2RlIiwgbnVsbCwgbGF1bmNoTW9kZSk7CgoJCUlNb2R1bGVBcnRpZmFjdFtdIG1vZHVsZU9iamVjdHMgPSBTZXJ2ZXJVdGlsLmdldE1vZHVsZU9iamVjdHMoc2VsZWN0aW9uKTsKCQkKCQlTaGVsbCBzaGVsbDsKCQlpZiAod2luZG93ICE9IG51bGwpCgkJCXNoZWxsID0gd2luZG93LmdldFNoZWxsKCk7CgkJZWxzZQoJCQlzaGVsbCA9IFNlcnZlclVJUGx1Z2luLmdldEluc3RhbmNlKCkuZ2V0V29ya2JlbmNoKCkuZ2V0QWN0aXZlV29ya2JlbmNoV2luZG93KCkuZ2V0U2hlbGwoKTsKCgkJaWYgKG1vZHVsZU9iamVjdHMgPT0gbnVsbCB8fCBtb2R1bGVPYmplY3RzLmxlbmd0aCA9PSAwKSB7CgkJCUVjbGlwc2VVdGlsLm9wZW5FcnJvcihTZXJ2ZXJVSVBsdWdpbi5nZXRSZXNvdXJjZSgiJWVycm9yTm9Nb2R1bGVzIikpOwoJCQlUcmFjZS50cmFjZShUcmFjZS5GSU5FU1QsICJObyBtb2R1bGVzIik7CgkJCXJldHVybjsKCQl9CgkJSU1vZHVsZSBtb2R1bGUgPSBtb2R1bGVPYmplY3RzWzBdLmdldE1vZHVsZSgpOwoJCWlmIChtb2R1bGVPYmplY3RzLmxlbmd0aCA+IDEpIHsKCQkJLy8gY2hlY2sgaWYgdGhlIG1vZHVsZXMgYXJlIGFsbCBpbiB0aGUgc2FtZSBtb2R1bGUKCQkJaW50IHNpemUgPSBtb2R1bGVPYmplY3RzLmxlbmd0aDsKCQkJZm9yIChpbnQgaSA9IDA7IGkgPCBzaXplOyBpKyspIHsKCQkJCUlNb2R1bGUgbW9kdWxlMiA9IG1vZHVsZU9iamVjdHNbaV0uZ2V0TW9kdWxlKCk7CgkJCQlpZiAoIW1vZHVsZS5lcXVhbHMobW9kdWxlMikpIHsKCQkJCQlFY2xpcHNlVXRpbC5vcGVuRXJyb3IoIlRvbyBtYW55IG1vZHVsZSBvYmplY3RzIik7CgkJCQkJVHJhY2UudHJhY2UoVHJhY2UuU0VWRVJFLCAiVG9vIG1hbnkgbW9kdWxlIG9iamVjdHMhIFVuc3VwcG9ydGVkISIpOwoJCQkJCXJldHVybjsKCQkJCX0KCQkJfQoJCX0KCgkJLy8gY2hlY2sgZm9yIHNlcnZlcnMgd2l0aCB0aGUgZ2l2ZW4gc3RhcnQgbW9kZQoJCUlTZXJ2ZXJbXSBzZXJ2ZXJzID0gU2VydmVyQ29yZS5nZXRTZXJ2ZXJzKCk7CgkJYm9vbGVhbiBmb3VuZCA9IGZhbHNlOwoJCWlmIChzZXJ2ZXJzICE9IG51bGwpIHsKCQkJaW50IHNpemUgPSBzZXJ2ZXJzLmxlbmd0aDsKCQkJZm9yIChpbnQgaSA9IDA7IGkgPCBzaXplICYmICFmb3VuZDsgaSsrKSB7CgkJCQlpZiAoU2VydmVyVXRpbC5pc0NvbXBhdGlibGVXaXRoTGF1bmNoTW9kZShzZXJ2ZXJzW2ldLCBsYXVuY2hNb2RlKSkgewoJCQkJCXRyeSB7CgkJCQkJCUlNb2R1bGVbXSBwYXJlbnRzID0gc2VydmVyc1tpXS5nZXRQYXJlbnRNb2R1bGVzKG1vZHVsZSwgbW9uaXRvcik7CgkJCQkJCWlmIChwYXJlbnRzICE9IG51bGwgJiYgcGFyZW50cy5sZW5ndGggPiAwKQoJCQkJCQkJZm91bmQgPSB0cnVlOwoJCQkJCX0gY2F0Y2ggKEV4Y2VwdGlvbiBlKSB7CgkJCQkJCS8vIGlnbm9yZQoJCQkJCX0KCQkJCX0KCQkJfQoJCX0KCgkJaWYgKCFmb3VuZCkgewoJCQkvLyBubyBleGlzdGluZyBzZXJ2ZXIgc3VwcG9ydHMgdGhlIHByb2plY3QgYW5kIHN0YXJ0IG1vZGUhCgkJCS8vIGNoZWNrIGlmIHRoZXJlIG1pZ2h0IGJlIGFub3RoZXIgb25lIHRoYXQgY2FuIGJlIGNyZWF0ZWQKCQkJSVNlcnZlclR5cGVbXSBzZXJ2ZXJUeXBlcyA9IFNlcnZlckNvcmUuZ2V0U2VydmVyVHlwZXMoKTsKCQkJYm9vbGVhbiBmb3VuZDIgPSBmYWxzZTsKCQkJaWYgKHNlcnZlclR5cGVzICE9IG51bGwpIHsKCQkJCWludCBzaXplID0gc2VydmVyVHlwZXMubGVuZ3RoOwoJCQkJZm9yIChpbnQgaSA9IDA7IGkgPCBzaXplICYmICFmb3VuZDI7IGkrKykgewoJCQkJCUlTZXJ2ZXJUeXBlIHR5cGUgPSBzZXJ2ZXJUeXBlc1tpXTsKCQkJCQlJTW9kdWxlVHlwZVtdIG1vZHVsZVR5cGVzID0gdHlwZS5nZXRSdW50aW1lVHlwZSgpLmdldE1vZHVsZVR5cGVzKCk7CgkJCQkJaWYgKHR5cGUuc3VwcG9ydHNMYXVuY2hNb2RlKGxhdW5jaE1vZGUpICYmIFNlcnZlclV0aWwuaXNTdXBwb3J0ZWRNb2R1bGUobW9kdWxlVHlwZXMsIG1vZHVsZS5nZXRNb2R1bGVUeXBlKCkpKSB7CgkJCQkJCWZvdW5kMiA9IHRydWU7CgkJCQkJfQoJCQkJfQoJCQl9CgkJCWlmICghZm91bmQyKSB7CgkJCQlFY2xpcHNlVXRpbC5vcGVuRXJyb3IoU2VydmVyVUlQbHVnaW4uZ2V0UmVzb3VyY2UoIiVlcnJvck5vU2VydmVyIikpOwoJCQkJVHJhY2UudHJhY2UoVHJhY2UuRklORVNULCAiTm8gc2VydmVyIGZvciBzdGFydCBtb2RlIik7CgkJCQlyZXR1cm47CgkJCX0KCQl9CgkJCgkJaWYgKCFTZXJ2ZXJVSVV0aWwuc2F2ZUVkaXRvcnMoKSkKCQkJcmV0dXJuOwoKCQlJU2VydmVyIHNlcnZlciA9IG51bGw7CgkJSVByb2plY3QgcHJvamVjdCA9IG1vZHVsZS5nZXRQcm9qZWN0KCk7CgkJaWYgKHByb2plY3QgIT0gbnVsbCkKCQkJc2VydmVyID0gU2VydmVyQ29yZS5nZXRQcm9qZWN0UHJvcGVydGllcyhwcm9qZWN0KS5nZXREZWZhdWx0U2VydmVyKCk7CgkJCgkJCgkJLy8gaWdub3JlIHByZWZlcmVuY2UgaWYgdGhlIHNlcnZlciBkb2Vzbid0IHN1cHBvcnQgdGhpcyBtb2RlLgoJCWlmIChzZXJ2ZXIgIT0gbnVsbCAmJiAhU2VydmVyVXRpbC5pc0NvbXBhdGlibGVXaXRoTGF1bmNoTW9kZShzZXJ2ZXIsIGxhdW5jaE1vZGUpKQoJCQlzZXJ2ZXIgPSBudWxsOwoKCQlib29sZWFuIHRhc2tzUnVuID0gZmFsc2U7CQoJCWlmIChzZXJ2ZXIgPT0gbnVsbCkgewoJCQkvLyB0cnkgdGhlIGZ1bGwgd2l6YXJkCgkJCVNlbGVjdFNlcnZlcldpemFyZCB3aXphcmQgPSBuZXcgU2VsZWN0U2VydmVyV2l6YXJkKG1vZHVsZSwgbGF1bmNoTW9kZSk7CgkJCUNsb3NhYmxlV2l6YXJkRGlhbG9nIGRpYWxvZyA9IG5ldyBDbG9zYWJsZVdpemFyZERpYWxvZyhzaGVsbCwgd2l6YXJkKTsKCQkJaWYgKGRpYWxvZy5vcGVuKCkgPT0gV2luZG93LkNBTkNFTCkgewoJCQkJcmV0dXJuOwoJCQl9CgoJCQlzZXJ2ZXIgPSB3aXphcmQuZ2V0U2VydmVyKCk7CgkJCWJvb2xlYW4gcHJlZmVycmVkID0gd2l6YXJkLmlzUHJlZmVycmVkU2VydmVyKCk7CgkJCXRhc2tzUnVuID0gdHJ1ZTsKCgkJCS8vIHNldCBwcmVmZXJyZWQgc2VydmVyIGlmIHJlcXVlc3RlZAoJCQlpZiAoc2VydmVyICE9IG51bGwgJiYgcHJlZmVycmVkICYmIHByb2plY3QgIT0gbnVsbCkgewoJCQkJdHJ5IHsKCQkJCQlTZXJ2ZXJDb3JlLmdldFByb2plY3RQcm9wZXJ0aWVzKHByb2plY3QpLnNldERlZmF1bHRTZXJ2ZXIoc2VydmVyLCBuZXcgTnVsbFByb2dyZXNzTW9uaXRvcigpKTsKCQkJCX0gY2F0Y2ggKENvcmVFeGNlcHRpb24gY2UpIHsKCQkJCQlTdHJpbmcgbWVzc2FnZSA9IFNlcnZlclVJUGx1Z2luLmdldFJlc291cmNlKCIlZXJyb3JDb3VsZE5vdFNhdmVQcmVmZXJlbmNlIik7CgkJCQkJRXJyb3JEaWFsb2cub3BlbkVycm9yKHNoZWxsLCBTZXJ2ZXJVSVBsdWdpbi5nZXRSZXNvdXJjZSgiJWVycm9yRGlhbG9nVGl0bGUiKSwgbWVzc2FnZSwgY2UuZ2V0U3RhdHVzKCkpOwoJCQkJfQoJCQl9CgkJfQoJCVRyYWNlLnRyYWNlKFRyYWNlLkZJTkVTVCwgIlNlcnZlcjogIiArIHNlcnZlcik7CgkJCgkJaWYgKHNlcnZlciA9PSBudWxsKSB7CgkJCUVjbGlwc2VVdGlsLm9wZW5FcnJvcihTZXJ2ZXJVSVBsdWdpbi5nZXRSZXNvdXJjZSgiJWVycm9yTm9TZXJ2ZXIiKSk7CgkJCVRyYWNlLnRyYWNlKFRyYWNlLlNFVkVSRSwgIk5vIHNlcnZlciBmb3VuZCIpOwoJCQlyZXR1cm47CgkJfQoKCQlpZiAoIVNlcnZlclVJVXRpbC5wcm9tcHRJZkRpcnR5KHNoZWxsLCBzZXJ2ZXIpKQoJCQlyZXR1cm47CgkJCgkJaWYgKCF0YXNrc1J1bikgewoJCQlTZWxlY3RUYXNrc1dpemFyZCB3aXphcmQgPSBuZXcgU2VsZWN0VGFza3NXaXphcmQoc2VydmVyKTsKCQkJd2l6YXJkLmFkZFBhZ2VzKCk7CgkJCWlmICh3aXphcmQuaGFzVGFza3MoKSAmJiB3aXphcmQuaGFzT3B0aW9uYWxUYXNrcygpKSB7CgkJCQlXaXphcmREaWFsb2cgZGlhbG9nID0gbmV3IFdpemFyZERpYWxvZyhzaGVsbCwgd2l6YXJkKTsKCQkJCWlmIChkaWFsb2cub3BlbigpID09IFdpbmRvdy5DQU5DRUwpCgkJCQkJcmV0dXJuOwoJCQl9IGVsc2UKCQkJCXdpemFyZC5wZXJmb3JtRmluaXNoKCk7CgkJfQoJCQoJCS8vIGdldCB0aGUgbGF1bmNoYWJsZSBhZGFwdGVyIGFuZCBtb2R1bGUgb2JqZWN0CgkJSUxhdW5jaGFibGVBZGFwdGVyIGxhdW5jaGFibGVBZGFwdGVyID0gbnVsbDsKCQlJTW9kdWxlQXJ0aWZhY3QgbW9kdWxlT2JqZWN0ID0gbnVsbDsKCQlJTGF1bmNoYWJsZSBsYXVuY2hhYmxlID0gbnVsbDsKCQkvL0lNb2R1bGVBcnRpZmFjdFtdIG1vID0gbW9kdWxlT2JqZWN0cy5pdGVyYXRvcigpOwoJCWlmIChtb2R1bGVPYmplY3RzICE9IG51bGwpIHsKCQkJaW50IHNpemUgPSBtb2R1bGVPYmplY3RzLmxlbmd0aDsKCQkJZm9yIChpbnQgaSA9IDA7IGkgPCBzaXplOyBpKyspIHsKCQkJCUlNb2R1bGVBcnRpZmFjdCBtb2R1bGVPYmplY3QyID0gbW9kdWxlT2JqZWN0c1tpXTsKCQkJCQoJCQkJSUxhdW5jaGFibGVBZGFwdGVyW10gYWRhcHRlcnMgPSBTZXJ2ZXJDb3JlLmdldExhdW5jaGFibGVBZGFwdGVycygpOwoJCQkJaWYgKGFkYXB0ZXJzICE9IG51bGwpIHsKCQkJCQlpbnQgc2l6ZTIgPSBhZGFwdGVycy5sZW5ndGg7CgkJCQkJZm9yIChpbnQgaiA9IDA7IGogPCBzaXplMiAmJiBtb2R1bGVPYmplY3QgPT0gbnVsbDsgaisrKSB7CgkJCQkJCUlMYXVuY2hhYmxlQWRhcHRlciBhZGFwdGVyID0gYWRhcHRlcnNbal07CgkJCQkJCXRyeSB7CgkJCQkJCQlJTGF1bmNoYWJsZSBsYXVuY2hhYmxlMiA9IGFkYXB0ZXIuZ2V0TGF1bmNoYWJsZShzZXJ2ZXIsIG1vZHVsZU9iamVjdDIpOwoJCQkJCQkJVHJhY2UudHJhY2UoVHJhY2UuRklORVNULCAiYWRhcHRlcj0gIiArIGFkYXB0ZXIgKyAiLCBsYXVuY2hhYmxlPSAiICsgbGF1bmNoYWJsZTIpOwoJCQkJCQkJaWYgKGxhdW5jaGFibGUyICE9IG51bGwpIHsKCQkJCQkJCQlsYXVuY2hhYmxlQWRhcHRlciA9IGFkYXB0ZXI7CgkJCQkJCQkJbW9kdWxlT2JqZWN0ID0gbW9kdWxlT2JqZWN0MjsKCQkJCQkJCQlsYXVuY2hhYmxlID0gbGF1bmNoYWJsZTI7CgkJCQkJCQl9CgkJCQkJCX0gY2F0Y2ggKEV4Y2VwdGlvbiBlKSB7CgkJCQkJCQlUcmFjZS50cmFjZShUcmFjZS5TRVZFUkUsICJFcnJvciBpbiBsYXVuY2hhYmxlIGFkYXB0ZXIiLCBlKTsKCQkJCQkJfQoJCQkJCX0KCQkJCX0KCQkJfQoJCX0KCQkKCQlJQ2xpZW50W10gY2xpZW50cyA9IG5ldyBJQ2xpZW50WzBdOwoJCWlmIChsYXVuY2hhYmxlICE9IG51bGwpCgkJCWNsaWVudHMgPSBnZXRDbGllbnRzKHNlcnZlciwgbGF1bmNoYWJsZSwgbGF1bmNoTW9kZSk7CgoJCVRyYWNlLnRyYWNlKFRyYWNlLkZJTkVTVCwgIkxhdW5jaGFibGUgY2xpZW50czogIiArIGNsaWVudHMpOwoKCQlJQ2xpZW50IGNsaWVudCA9IG51bGw7CgkJaWYgKGNsaWVudHMgPT0gbnVsbCB8fCBjbGllbnRzLmxlbmd0aCA9PSAwKSB7CgkJCUVjbGlwc2VVdGlsLm9wZW5FcnJvcihTZXJ2ZXJVSVBsdWdpbi5nZXRSZXNvdXJjZSgiJWVycm9yTm9DbGllbnQiKSk7CgkJCVRyYWNlLnRyYWNlKFRyYWNlLlNFVkVSRSwgIk5vIGxhdW5jaGFibGUgY2xpZW50cyEiKTsKCQkJcmV0dXJuOwoJCX0gZWxzZSBpZiAoY2xpZW50cy5sZW5ndGggPT0gMSkgewoJCQljbGllbnQgPSBjbGllbnRzWzBdOwoJCX0gZWxzZSB7CgkJCVNlbGVjdENsaWVudFdpemFyZCB3aXphcmQgPSBuZXcgU2VsZWN0Q2xpZW50V2l6YXJkKGNsaWVudHMpOwoJCQlDbG9zYWJsZVdpemFyZERpYWxvZyBkaWFsb2cgPSBuZXcgQ2xvc2FibGVXaXphcmREaWFsb2coc2hlbGwsIHdpemFyZCk7CgkJCWRpYWxvZy5vcGVuKCk7CgkJCWNsaWVudCA9IHdpemFyZC5nZXRTZWxlY3RlZENsaWVudCgpOwoJCQlpZiAoY2xpZW50ID09IG51bGwpCgkJCQlyZXR1cm47CgkJfQoKCQlUcmFjZS50cmFjZShUcmFjZS5GSU5FU1QsICJSZWFkeSB0byBsYXVuY2giKTsKCgkJZmluYWwgSVNlcnZlclByZWZlcmVuY2VzIHByZWZlcmVuY2VzID0gU2VydmVyQ29yZS5nZXRTZXJ2ZXJQcmVmZXJlbmNlcygpOwoKCQkvLyBzdGFydCBzZXJ2ZXIgaWYgaXQncyBub3QgYWxyZWFkeSBzdGFydGVkCgkJLy8gYW5kIGN1ZSB0aGUgY2xpZW50IHRvIHN0YXJ0CgkJaW50IHN0YXRlID0gc2VydmVyLmdldFNlcnZlclN0YXRlKCk7CgkJaWYgKHN0YXRlID09IElTZXJ2ZXIuU1RBVEVfU1RBUlRJTkcpIHsKCQkJU2VydmVyU3RhcnR1cExpc3RlbmVyIGxpc3RlbmVyID0gbmV3IFNlcnZlclN0YXJ0dXBMaXN0ZW5lcihzaGVsbCwgc2VydmVyLCBjbGllbnQsIGxhdW5jaGFibGVBZGFwdGVyLCBtb2R1bGVPYmplY3QsIGxhdW5jaE1vZGUsIG1vZHVsZSk7CgkJCWxpc3RlbmVyLnNldEVuYWJsZWQodHJ1ZSk7CgkJfSBlbHNlIGlmIChzdGF0ZSA9PSBJU2VydmVyLlNUQVRFX1NUQVJURUQpIHsKCQkJYm9vbGVhbiByZXN0YXJ0ID0gZmFsc2U7CgkJCVN0cmluZyBtb2RlID0gc2VydmVyLmdldE1vZGUoKTsKCQkJaWYgKCFJTGF1bmNoTWFuYWdlci5ERUJVR19NT0RFLmVxdWFscyhtb2RlKSAmJiBJTGF1bmNoTWFuYWdlci5ERUJVR19NT0RFLmVxdWFscyhsYXVuY2hNb2RlKSkgewoJCQkJaW50IHJlc3VsdCA9IG9wZW5XYXJuaW5nRGlhbG9nKHNoZWxsLCBTZXJ2ZXJVSVBsdWdpbi5nZXRSZXNvdXJjZSgiJWRpYWxvZ01vZGVXYXJuaW5nRGVidWciKSk7CgkJCQlpZiAocmVzdWx0ID09IDEpCgkJCQkJbGF1bmNoTW9kZSA9IG1vZGU7CgkJCQllbHNlIGlmIChyZXN1bHQgPT0gMCkKCQkJCQlyZXN0YXJ0ID0gdHJ1ZTsKCQkJCWVsc2UKCQkJCQlyZXR1cm47CgkJCX0gZWxzZSBpZiAoIUlMYXVuY2hNYW5hZ2VyLlBST0ZJTEVfTU9ERS5lcXVhbHMobW9kZSkgJiYgSUxhdW5jaE1hbmFnZXIuUFJPRklMRV9NT0RFLmVxdWFscyhsYXVuY2hNb2RlKSkgewoJCQkJaW50IHJlc3VsdCA9IG9wZW5XYXJuaW5nRGlhbG9nKHNoZWxsLCBTZXJ2ZXJVSVBsdWdpbi5nZXRSZXNvdXJjZSgiJWRpYWxvZ01vZGVXYXJuaW5nUHJvZmlsZSIpKTsKCQkJCWlmIChyZXN1bHQgPT0gMSkKCQkJCQlsYXVuY2hNb2RlID0gbW9kZTsKCQkJCWVsc2UgaWYgKHJlc3VsdCA9PSAwKQoJCQkJCXJlc3RhcnQgPSB0cnVlOwoJCQkJZWxzZQoJCQkJCXJldHVybjsKCQkJfQoJCQlpZiAocmVzdGFydCkgewoJCQkJc2VydmVyLnJlc3RhcnQobGF1bmNoTW9kZSk7CgkJCQkKCQkJCWlmIChwcmVmZXJlbmNlcy5pc0F1dG9QdWJsaXNoaW5nKCkgJiYgIWF1dG9QdWJsaXNoKHNoZWxsLCBzZXJ2ZXIpKQoJCQkJCXJldHVybjsKCQkJCVNlcnZlclN0YXJ0dXBMaXN0ZW5lci5sYXVuY2hDbGllbnRVdGlsKHNlcnZlciwgbW9kdWxlLCBsYXVuY2hhYmxlQWRhcHRlciwgbW9kdWxlT2JqZWN0LCBsYXVuY2hNb2RlLCBjbGllbnQpOwoJCQl9IGVsc2UgewoJCQkJaWYgKHByZWZlcmVuY2VzLmlzQXV0b1B1Ymxpc2hpbmcoKSAmJiAhYXV0b1B1Ymxpc2goc2hlbGwsIHNlcnZlcikpCgkJCQkJcmV0dXJuOwoJCgkJCQkvLyBvcGVuIGNsaWVudAoJCQkJU2VydmVyU3RhcnR1cExpc3RlbmVyLmxhdW5jaENsaWVudFV0aWwoc2VydmVyLCBtb2R1bGUsIGxhdW5jaGFibGVBZGFwdGVyLCBtb2R1bGVPYmplY3QsIGxhdW5jaE1vZGUsIGNsaWVudCk7CgkJCX0KCQl9IGVsc2UgaWYgKHN0YXRlICE9IElTZXJ2ZXIuU1RBVEVfU1RPUFBJTkcpIHsKCQkJU2VydmVyU3RhcnR1cExpc3RlbmVyIGxpc3RlbmVyID0gbmV3IFNlcnZlclN0YXJ0dXBMaXN0ZW5lcihzaGVsbCwgc2VydmVyLCBjbGllbnQsIGxhdW5jaGFibGVBZGFwdGVyLCBtb2R1bGVPYmplY3QsIGxhdW5jaE1vZGUsIG1vZHVsZSk7CgkJCWlmIChwcmVmZXJlbmNlcy5pc0F1dG9QdWJsaXNoaW5nKCkgJiYgIWF1dG9QdWJsaXNoKHNoZWxsLCBzZXJ2ZXIpKQoJCQkJcmV0dXJuOwoKCQkJdHJ5IHsKCQkJCUVjbGlwc2VVdGlsLnN0YXJ0U2VydmVyKHNoZWxsLCBzZXJ2ZXIsIGxhdW5jaE1vZGUsIGxpc3RlbmVyKTsKCQkJfSBjYXRjaCAoQ29yZUV4Y2VwdGlvbiBlKSB7CgkJCQkvLyBpZ25vcmUKCQkJfQoJCX0KCX0KCQoJLyoqCgkgKiBSZXR1cm5zIHRoZSBsYXVuY2hhYmxlIGNsaWVudHMgZm9yIHRoZSBnaXZlbiBzZXJ2ZXIgYW5kIGxhdW5jaGFibGUKCSAqIG9iamVjdC4KCSAqCgkgKiBAcGFyYW0gc2VydmVyIG9yZy5lY2xpcHNlLndzdC5zZXJ2ZXIuY29yZS5JU2VydmVyCgkgKiBAcGFyYW0gbW9kdWxlT2JqZWN0IG9yZy5lY2xpcHNlLndzdC5zZXJ2ZXIuY29yZS5JTW9kdWxlQXJ0aWZhY3QKCSAqIEBwYXJhbSBsYXVuY2hNb2RlIFN0cmluZwoJICogQHJldHVybiBqYXZhLnV0aWwuTGlzdAoJICovCglwdWJsaWMgc3RhdGljIElDbGllbnRbXSBnZXRDbGllbnRzKElTZXJ2ZXIgc2VydmVyLCBJTGF1bmNoYWJsZSBsYXVuY2hhYmxlLCBTdHJpbmcgbGF1bmNoTW9kZSkgewoJCUFycmF5TGlzdCBsaXN0ID0gbmV3IEFycmF5TGlzdCgpOwoJCUlDbGllbnRbXSBjbGllbnRzID0gU2VydmVyQ29yZS5nZXRDbGllbnRzKCk7CgkJaWYgKGNsaWVudHMgIT0gbnVsbCkgewoJCQlpbnQgc2l6ZSA9IGNsaWVudHMubGVuZ3RoOwoJCQlmb3IgKGludCBpID0gMDsgaSA8IHNpemU7IGkrKykgewoJCQkJVHJhY2UudHJhY2UoVHJhY2UuRklORVNULCAiY2xpZW50PSAiICsgY2xpZW50c1tpXSk7CgkJCQlpZiAoY2xpZW50c1tpXS5zdXBwb3J0cyhzZXJ2ZXIsIGxhdW5jaGFibGUsIGxhdW5jaE1vZGUpKQoJCQkJCWxpc3QuYWRkKGNsaWVudHNbaV0pOwoJCQl9CgkJfQoJCQoJCUlDbGllbnRbXSBjbGllbnRzMiA9IG5ldyBJQ2xpZW50W2xpc3Quc2l6ZSgpXTsKCQlsaXN0LnRvQXJyYXkoY2xpZW50czIpOwoJCXJldHVybiBjbGllbnRzMjsKCX0KCgkvKioKCSAqIEF1dG9tYXRpY2FsbHkgcHVibGlzaCB0byB0aGUgZ2l2ZW4gc2VydmVyLgoJICoKCSAqIEBwYXJhbSBzZXJ2ZXIKCSAqIEByZXR1cm4gYm9vbGVhbiAtIGZhbHNlIGlmIHRoZSBjdXJyZW50IG9wZXJhdGlvbiBzaG91bGQgYmUgc3RvcHBlZAoJICovCglwcm90ZWN0ZWQgYm9vbGVhbiBhdXRvUHVibGlzaChTaGVsbCBzaGVsbCwgSVNlcnZlciBzZXJ2ZXIpIHsKCQkvLyBwdWJsaXNoIGZpcnN0CgkJaWYgKHNlcnZlci5zaG91bGRQdWJsaXNoKCkpIHsKCQkJSVN0YXR1cyBwdWJsaXNoU3RhdHVzID0gU2VydmVyVUlVdGlsLnB1Ymxpc2hXaXRoRGlhbG9nKHNoZWxsLCBzZXJ2ZXIsIGZhbHNlKTsKCQoJCQlpZiAocHVibGlzaFN0YXR1cyA9PSBudWxsIHx8IHB1Ymxpc2hTdGF0dXMuZ2V0U2V2ZXJpdHkoKSA9PSBJU3RhdHVzLkVSUk9SKQoJCQkJcmV0dXJuIGZhbHNlOwoJCX0KCQlyZXR1cm4gdHJ1ZTsKCX0KCgkvKioKCSAqIE9wZW4gYSBtZXNzYWdlIGRpYWxvZy4KCSAqIAoJICogQHBhcmFtIHNoZWxsCgkgKiBAcGFyYW0gbWVzc2FnZQoJICogQHJldHVybgoJICovCglwcm90ZWN0ZWQgaW50IG9wZW5XYXJuaW5nRGlhbG9nKFNoZWxsIHNoZWxsLCBTdHJpbmcgbWVzc2FnZSkgewoJCU1lc3NhZ2VEaWFsb2cgZGlhbG9nID0gbmV3IE1lc3NhZ2VEaWFsb2coc2hlbGwsIFNlcnZlclVJUGx1Z2luLmdldFJlc291cmNlKCIlZXJyb3JEaWFsb2dUaXRsZSIpLCBudWxsLAoJCQltZXNzYWdlLAlNZXNzYWdlRGlhbG9nLldBUk5JTkcsIG5ldyBTdHJpbmdbXSB7U2VydmVyVUlQbHVnaW4uZ2V0UmVzb3VyY2UoIiVkaWFsb2dNb2RlV2FybmluZ1Jlc3RhcnQiKSwKCQkJU2VydmVyVUlQbHVnaW4uZ2V0UmVzb3VyY2UoIiVkaWFsb2dNb2RlV2FybmluZ0NvbnRpbnVlIiksIElEaWFsb2dDb25zdGFudHMuQ0FOQ0VMX0xBQkVMfSwgMCk7CgkJcmV0dXJuIGRpYWxvZy5vcGVuKCk7Cgl9CgoJLyoqCgkgKiBUaGUgZGVsZWdhdGluZyBhY3Rpb24gaGFzIGJlZW4gcGVyZm9ybWVkLiBJbXBsZW1lbnQKCSAqIHRoaXMgbWV0aG9kIHRvIGRvIHRoZSBhY3R1YWwgd29yay4KCSAqCgkgKiBAcGFyYW0gYWN0aW9uIGFjdGlvbiBwcm94eSB0aGF0IGhhbmRsZXMgdGhlIHByZXNlbnRhdGlvbgoJICogcG9ydGlvbiBvZiB0aGUgcGx1Z2luIGFjdGlvbgoJICovCglwdWJsaWMgdm9pZCBydW4oSUFjdGlvbiBhY3Rpb24pIHsKCQlUcmFjZS50cmFjZShUcmFjZS5GSU5FU1QsICJSdW5uaW5nIG9uIFNlcnZlci4uLiIpOwoJCWlmICghaW5pdGlhbGl6ZWQpIHsKCQkJaW5pdGlhbGl6ZWQgPSB0cnVlOwoJCQkKCQkJLypJTW9kdWxlRmFjdG9yeVtdIGZhY3RvcmllcyA9IFNlcnZlckNvcmUuZ2V0TW9kdWxlRmFjdG9yaWVzKCk7CgkJCWlmIChmYWN0b3JpZXMgIT0gbnVsbCkgewoJCQkJaW50IHNpemUgPSBmYWN0b3JpZXMubGVuZ3RoOwoJCQkJZm9yIChpbnQgaSA9IDA7IGkgPCBzaXplOyBpKyspCgkJCQkJZmFjdG9yaWVzW2ldLmdldE1vZHVsZXMoKTsKCQkJfSovCgkJCQoJCQl0cnkgewoJCQkJSU1vZHVsZSBtb2R1bGUgPSBTZXJ2ZXJVdGlsLmdldE1vZHVsZShnbG9iYWxTZWxlY3Rpb24sIHRydWUpOwoJCQkJZmluZEdsb2JhbExhdW5jaE1vZGVzKG1vZHVsZSk7CgkJCQlhY3Rpb24uc2V0RW5hYmxlZChpc0VuYWJsZWQoKSk7CgkJCX0gY2F0Y2ggKEV4Y2VwdGlvbiBlKSB7CgkJCQkvLyBpZ25vcmUKCQkJfQoJCQlpZiAoIWlzRW5hYmxlZCgpKSB7CgkJCQlFY2xpcHNlVXRpbC5vcGVuRXJyb3IoU2VydmVyVUlQbHVnaW4uZ2V0UmVzb3VyY2UoIiVlcnJvck5vU2VydmVyIikpOwoJCQkJVHJhY2UudHJhY2UoVHJhY2UuRklORVNULCAiVW5pbml0aWFsaXplZCIpOwoJCQkJcmV0dXJuOwoJCQl9CgkJfQoKCQl0cnkgewoJCQlydW4obmV3IE51bGxQcm9ncmVzc01vbml0b3IoKSk7CgkJfSBjYXRjaCAoRXhjZXB0aW9uIGUpIHsKCQkJVHJhY2UudHJhY2UoVHJhY2UuU0VWRVJFLCAiUnVuIG9uIFNlcnZlciBFcnJvciIsIGUpOwoJCX0KCX0KCQoJcHJvdGVjdGVkIGJvb2xlYW4gaXNFbmFibGVkKCkgewoJCXRyeSB7CgkJCUJvb2xlYW4gYiA9IChCb29sZWFuKSBnbG9iYWxMYXVuY2hNb2RlLmdldChnZXRMYXVuY2hNb2RlKCkpOwoJCQlyZXR1cm4gYi5ib29sZWFuVmFsdWUoKTsKCQl9IGNhdGNoIChFeGNlcHRpb24gZSkgewoJCQkvLyBpZ25vcmUKCQl9CgkJcmV0dXJuIGZhbHNlOwoJfQoKCS8qKgoJICogUmV0dXJucyB0aGUgc3RhcnQgbW9kZSB0aGF0IHRoZSBzZXJ2ZXIgc2hvdWxkIHVzZS4KCSAqLwoJcHJvdGVjdGVkIFN0cmluZyBnZXRMYXVuY2hNb2RlKCkgewoJCXJldHVybiBJTGF1bmNoTWFuYWdlci5SVU5fTU9ERTsKCX0KCgkvKioKCSAqIERldGVybWluZSB3aGljaCBjbGllbnRzIGNhbiBhY3Qgb24gdGhlIGN1cnJlbnQgc2VsZWN0aW9uLgoJICoKCSAqIEBwYXJhbSBhY3Rpb24gYWN0aW9uIHByb3h5IHRoYXQgaGFuZGxlcyBwcmVzZW50YXRpb24KCSAqIHBvcnRpb24gb2YgdGhlIHBsdWdpbiBhY3Rpb24KCSAqIEBwYXJhbSBzZWxlY3Rpb24gY3VycmVudCBzZWxlY3Rpb24gaW4gdGhlIGRlc2t0b3AKCSAqLwoJcHVibGljIHZvaWQgc2VsZWN0aW9uQ2hhbmdlZChJQWN0aW9uIGFjdGlvbiwgSVNlbGVjdGlvbiBzZWwpIHsKCQlUcmFjZS50cmFjZShUcmFjZS5GSU5FU1QsICI+IHNlbGVjdGlvbkNoYW5nZWQiKTsKCQlzZWxlY3Rpb24gPSBudWxsOwoJCWxvbmcgdGltZSA9IFN5c3RlbS5jdXJyZW50VGltZU1pbGxpcygpOwoJCWlmIChzZWwgPT0gbnVsbCB8fCBzZWwuaXNFbXB0eSgpIHx8ICEoc2VsIGluc3RhbmNlb2YgSVN0cnVjdHVyZWRTZWxlY3Rpb24pKSB7CgkJCWFjdGlvbi5zZXRFbmFibGVkKGZhbHNlKTsKCQkJZ2xvYmFsU2VsZWN0aW9uID0gbnVsbDsKCQkJcmV0dXJuOwoJCX0KCgkJSVN0cnVjdHVyZWRTZWxlY3Rpb24gc2VsZWN0ID0gKElTdHJ1Y3R1cmVkU2VsZWN0aW9uKSBzZWw7CgkJSXRlcmF0b3IgaXRlcmF0b3IgPSBzZWxlY3QuaXRlcmF0b3IoKTsKCQlzZWxlY3Rpb24gPSBpdGVyYXRvci5uZXh0KCk7CgkJaWYgKGl0ZXJhdG9yLmhhc05leHQoKSkgeyAvLyBtb3JlIHRoYW4gb25lIHNlbGVjdGlvbiAoc2hvdWxkIG5ldmVyIGhhcHBlbikKCQkJYWN0aW9uLnNldEVuYWJsZWQoZmFsc2UpOwoJCQlzZWxlY3Rpb24gPSBudWxsOwoJCQlnbG9iYWxTZWxlY3Rpb24gPSBudWxsOwoJCQlyZXR1cm47CgkJfQoKCQlpZiAoc2VsZWN0aW9uICE9IGdsb2JhbFNlbGVjdGlvbiB8fCAhaW5pdGlhbGl6ZWQpIHsKCQkJVHJhY2UudHJhY2UoVHJhY2UuRklORVNULCAiU2VsZWN0aW9uOiAiICsgc2VsZWN0aW9uKTsKCQkJaWYgKHNlbGVjdGlvbiAhPSBudWxsKQkKCQkJCVRyYWNlLnRyYWNlKFRyYWNlLkZJTkVTVCwgIlNlbGVjdGlvbiB0eXBlOiAiICsgc2VsZWN0aW9uLmdldENsYXNzKCkuZ2V0TmFtZSgpKTsKCQkJZ2xvYmFsU2VsZWN0aW9uID0gc2VsZWN0aW9uOwoJCQlnbG9iYWxMYXVuY2hNb2RlID0gbmV3IEhhc2hNYXAoKTsKCQkJdHJ5IHsKCQkJCVRyYWNlLnRyYWNlKFRyYWNlLkZJTkVTVCwgImNhbGxpbmcgZ2V0TW9kdWxlKCkgIiArIGluaXRpYWxpemVkKTsKCQkJCUlNb2R1bGUgbW9kdWxlID0gU2VydmVyVXRpbC5nZXRNb2R1bGUoZ2xvYmFsU2VsZWN0aW9uLCBpbml0aWFsaXplZCk7CgkJCQlUcmFjZS50cmFjZShUcmFjZS5GSU5FU1QsICJtb2R1bGU6ICIgKyBtb2R1bGUpOwoJCQkJZmluZEdsb2JhbExhdW5jaE1vZGVzKG1vZHVsZSk7CgkJCX0gY2F0Y2ggKEV4Y2VwdGlvbiBlKSB7CgkJCQlUcmFjZS50cmFjZShUcmFjZS5GSU5FU1QsICJub3QgaW5pdGlhbGl6ZWQiKTsKCQkJCWdsb2JhbExhdW5jaE1vZGUucHV0KElMYXVuY2hNYW5hZ2VyLlJVTl9NT0RFLCBuZXcgQm9vbGVhbih0cnVlKSk7CgkJCQlnbG9iYWxMYXVuY2hNb2RlLnB1dChJTGF1bmNoTWFuYWdlci5ERUJVR19NT0RFLCBuZXcgQm9vbGVhbih0cnVlKSk7CgkJCQlnbG9iYWxMYXVuY2hNb2RlLnB1dChJTGF1bmNoTWFuYWdlci5QUk9GSUxFX01PREUsIG5ldyBCb29sZWFuKHRydWUpKTsKCQkJfQoJCX0KCgkJYWN0aW9uLnNldEVuYWJsZWQoaXNFbmFibGVkKCkpOwoJCVRyYWNlLnRyYWNlKFRyYWNlLkZJTkVTVCwgIjwgc2VsZWN0aW9uQ2hhbmdlZCAiICsgKFN5c3RlbS5jdXJyZW50VGltZU1pbGxpcygpIC0gdGltZSkpOwoJfQoJCgkvKioKCSAqIERldGVybWluZXMgd2hldGhlciB0aGVyZSBpcyBhIHNlcnZlciBmYWN0b3J5IGF2YWlsYWJsZSBmb3IgdGhlIGdpdmVuIG1vZHVsZQoJICogYW5kIHRoZSB2YXJpb3VzIHN0YXJ0IG1vZGVzLgoJICovCglwcm90ZWN0ZWQgYm9vbGVhbiBmaW5kR2xvYmFsTGF1bmNoTW9kZXMoSU1vZHVsZSBtb2R1bGUpIHsKCQlJU2VydmVyVHlwZVtdIHNlcnZlclR5cGVzID0gU2VydmVyQ29yZS5nZXRTZXJ2ZXJUeXBlcygpOwoJCWlmIChzZXJ2ZXJUeXBlcyAhPSBudWxsKSB7CgkJCWludCBzaXplID0gc2VydmVyVHlwZXMubGVuZ3RoOwoJCQlmb3IgKGludCBpID0gMDsgaSA8IHNpemU7IGkrKykgewoJCQkJSVNlcnZlclR5cGUgdHlwZSA9IHNlcnZlclR5cGVzW2ldOwoJCQkJaWYgKGlzVmFsaWRTZXJ2ZXJUeXBlKHR5cGUsIG1vZHVsZSkpIHsKCQkJCQlmb3IgKGJ5dGUgYiA9IDA7IGIgPCBsYXVuY2hNb2Rlcy5sZW5ndGg7IGIrKykgewoJCQkJCQlpZiAodHlwZS5zdXBwb3J0c0xhdW5jaE1vZGUobGF1bmNoTW9kZXNbYl0pKSB7CgkJCQkJCQlnbG9iYWxMYXVuY2hNb2RlLnB1dChsYXVuY2hNb2Rlc1tiXSwgbmV3IEJvb2xlYW4odHJ1ZSkpOwoJCQkJCQl9CgkJCQkJfQoJCQkJfQoJCQl9CgkJfQoJCXJldHVybiBmYWxzZTsKCX0KCgkvKioKCSAqIFJldHVybnMgdHJ1ZSBpZiB0aGUgZ2l2ZW4gc2VydmVyIHR5cGUgY2FuIGxhdW5jaCB0aGUgbW9kdWxlLiAKCSAqLwoJcHJvdGVjdGVkIGJvb2xlYW4gaXNWYWxpZFNlcnZlclR5cGUoSVNlcnZlclR5cGUgdHlwZSwgSU1vZHVsZSBtb2R1bGUpIHsKCQl0cnkgewoJCQlJUnVudGltZVR5cGUgcnVudGltZVR5cGUgPSB0eXBlLmdldFJ1bnRpbWVUeXBlKCk7CgkJCVNlcnZlclV0aWwuaXNTdXBwb3J0ZWRNb2R1bGUocnVudGltZVR5cGUuZ2V0TW9kdWxlVHlwZXMoKSwgbW9kdWxlLmdldE1vZHVsZVR5cGUoKSk7CgkJfSBjYXRjaCAoRXhjZXB0aW9uIGUpIHsKCQkJcmV0dXJuIGZhbHNlOwoJCX0KCQlyZXR1cm4gdHJ1ZTsKCX0KCglwcm90ZWN0ZWQgYm9vbGVhbiBzdXBwb3J0c0xhdW5jaE1vZGUoSVNlcnZlciBzZXJ2ZXIsIFN0cmluZyBsYXVuY2hNb2RlKSB7CgkJcmV0dXJuIHNlcnZlci5nZXRTZXJ2ZXJUeXBlKCkuc3VwcG9ydHNMYXVuY2hNb2RlKGxhdW5jaE1vZGUpOwoJfQp9