LyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogQ29weXJpZ2h0IChjKSAyMDA1IElCTSBDb3Jwb3JhdGlvbiBhbmQgb3RoZXJzLgogKiBBbGwgcmlnaHRzIHJlc2VydmVkLiBUaGlzIHByb2dyYW0gYW5kIHRoZSBhY2NvbXBhbnlpbmcgbWF0ZXJpYWxzCiAqIGFyZSBtYWRlIGF2YWlsYWJsZSB1bmRlciB0aGUgdGVybXMgb2YgdGhlIEVjbGlwc2UgUHVibGljIExpY2Vuc2UgdjEuMAogKiB3aGljaCBhY2NvbXBhbmllcyB0aGlzIGRpc3RyaWJ1dGlvbiwgYW5kIGlzIGF2YWlsYWJsZSBhdAogKiBodHRwOi8vd3d3LmVjbGlwc2Uub3JnL2xlZ2FsL2VwbC12MTAuaHRtbAqgKiAKICogQ29udHJpYnV0b3JzOgogKiAgICAgSUJNIENvcnBvcmF0aW9uIC0gSW5pdGlhbCBBUEkgYW5kIGltcGxlbWVudGF0aW9uCiAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwpwYWNrYWdlIG9yZy5lY2xpcHNlLndzdC5zZXJ2ZXIuY29yZS5tb2RlbDsKCmltcG9ydCBqYXZhLnV0aWwuQXJyYXlMaXN0OwppbXBvcnQgamF2YS51dGlsLkl0ZXJhdG9yOwppbXBvcnQgamF2YS51dGlsLkxpc3Q7CmltcG9ydCBvcmcuZWNsaXBzZS5jb3JlLnJ1bnRpbWUuKjsKaW1wb3J0IG9yZy5lY2xpcHNlLmRlYnVnLmNvcmUuSUxhdW5jaENvbmZpZ3VyYXRpb25Xb3JraW5nQ29weTsKaW1wb3J0IG9yZy5lY2xpcHNlLm9zZ2kudXRpbC5OTFM7CmltcG9ydCBvcmcuZWNsaXBzZS53c3Quc2VydmVyLmNvcmUuSU1vZHVsZTsKaW1wb3J0IG9yZy5lY2xpcHNlLndzdC5zZXJ2ZXIuY29yZS5JU2VydmVyOwppbXBvcnQgb3JnLmVjbGlwc2Uud3N0LnNlcnZlci5jb3JlLmludGVybmFsLk1lc3NhZ2VzOwppbXBvcnQgb3JnLmVjbGlwc2Uud3N0LnNlcnZlci5jb3JlLmludGVybmFsLlByb2dyZXNzVXRpbDsKaW1wb3J0IG9yZy5lY2xpcHNlLndzdC5zZXJ2ZXIuY29yZS5pbnRlcm5hbC5TZXJ2ZXI7CmltcG9ydCBvcmcuZWNsaXBzZS53c3Quc2VydmVyLmNvcmUuaW50ZXJuYWwuU2VydmVyUGx1Z2luOwppbXBvcnQgb3JnLmVjbGlwc2Uud3N0LnNlcnZlci5jb3JlLmludGVybmFsLlRyYWNlOwovKioKICogQSBzZXJ2ZXIgZGVsZWdhdGUgcHJvdmlkZXMgdGhlIGltcGxlbWVudGF0aW9uIGZvciB2YXJpb3VzIAogKiBnZW5lcmljIGFuZCBzZXJ2ZXItdHlwZS1zcGVjaWZpYyBvcGVyYXRpb25zIGZvciBhIHNwZWNpZmljIHR5cGUgb2Ygc2VydmVyLgogKiBBIHNlcnZlciBkZWxlZ2F0ZSBpcyBzcGVjaWZpZWQgYnkgdGhlCiAqIDxjb2RlPmNsYXNzPC9jb2RlPiBhdHRyaWJ1dGUgb2YgYSA8Y29kZT5zZXJ2ZXJUeXBlczwvY29kZT4gZXh0ZW5zaW9uLgogKiA8cD4KICogV2hlbiB0aGUgc2VydmVyIGluc3RhbmNlIG5lZWRzIHRvIGJlIGdpdmVuIGEgZGVsZWdhdGUsIHRoZSBkZWxlZ2F0ZSBjbGFzcwogKiBzcGVjaWZpZWQgZm9yIHRoZSBzZXJ2ZXIgdHlwZSBpcyBpbnN0YW50aWF0ZWQgd2l0aCBhIDAtYXJndW1lbnQgY29uc3RydWN0b3IKICogYW5kIHByaW1lZCB3aXRoIDxjb2RlPmRlbGVnYXRlLmluaXRpYWxpemUoKChJU2VydmVyU3RhdGUpc2VydmVyKTwvY29kZT4sIAogKiB3aGljaCBpdCBpcyBleHBlY3RlZCB0byBoYW5nIG9uIHRvLiBMYXRlciwgd2hlbgogKiA8Y29kZT5kZWxlZ2F0ZS5kaXNwb3NlKCk8L2NvZGU+IGlzIGNhbGxlZCBhcyB0aGUgc2VydmVyIGluc3RhbmNlIGlzCiAqIGJlaW5nIGRpc2NhcmRlZCwgdGhlIGRlbGVnYXRlIGlzIGV4cGVjdGVkIHRvIGxldCBnbyBvZiB0aGUgc2VydmVyIGluc3RhbmNlLgogKiA8L3A+CiAqIDxwPgogKiBTZXJ2ZXIgZGVsZWdhdGVzIG1heSBrZWVwIHN0YXRlIGluIGluc3RhbmNlIGZpZWxkcywgYnV0IHRoYXQgc3RhdGUgaXMKICogdHJhbnNpZW50IGFuZCB3aWxsIG5vdCBiZSBwZXJzaXN0ZWQgYWNyb3NzIHdvcmtiZW5jaCBzZXNzaW9ucy4KICogPC9wPgogKiA8cD4KICogVGhpcyBhYnN0cmFjdCBjbGFzcyBpcyBpbnRlbmRlZCB0byBiZSBleHRlbmRlZCBvbmx5IGJ5IGNsaWVudHMKICogdG8gZXh0ZW5kIHRoZSA8Y29kZT5zZXJ2ZXJUeXBlczwvY29kZT4gZXh0ZW5zaW9uIHBvaW50LgogKiA8L3A+CiAqIAogKiBAc2VlIG9yZy5lY2xpcHNlLndzdC5zZXJ2ZXIuY29yZS5JU2VydmVyCiAqIEBzZWUgb3JnLmVjbGlwc2Uud3N0LnNlcnZlci5jb3JlLklTZXJ2ZXJXb3JraW5nQ29weQogKiBAc2luY2UgMS4wCiAqLwpwdWJsaWMgYWJzdHJhY3QgY2xhc3MgU2VydmVyQmVoYXZpb3VyRGVsZWdhdGUgewoJcHJpdmF0ZSBTZXJ2ZXIgc2VydmVyOwoKCS8qKgoJICogUHVibGlzaCBraW5kIGNvbnN0YW50ICh2YWx1ZSAwKSBmb3Igbm8gY2hhbmdlLgoJICogCgkgKiBAc2VlICNwdWJsaXNoTW9kdWxlKGludCwgaW50LCBJTW9kdWxlW10sIElQcm9ncmVzc01vbml0b3IpCgkgKi8KCXB1YmxpYyBzdGF0aWMgZmluYWwgaW50IE5PX0NIQU5HRSA9IDA7CgoJLyoqCgkgKiBQdWJsaXNoIGtpbmQgY29uc3RhbnQgKHZhbHVlIDEpIGZvciBhZGRlZCByZXNvdXJjZXMuCgkgKiAKCSAqIEBzZWUgI3B1Ymxpc2hNb2R1bGUoaW50LCBpbnQsIElNb2R1bGVbXSwgSVByb2dyZXNzTW9uaXRvcikKCSAqLwoJcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgQURERUQgPSAxOwoKCS8qKgoJICogUHVibGlzaCBraW5kIGNvbnN0YW50ICh2YWx1ZSAyKSBmb3IgY2hhbmdlZCByZXNvdXJjZXMuCgkgKiAKCSAqIEBzZWUgI3B1Ymxpc2hNb2R1bGUoaW50LCBpbnQsIElNb2R1bGVbXSwgSVByb2dyZXNzTW9uaXRvcikKCSAqLwoJcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgQ0hBTkdFRCA9IDI7CgoJLyoqCgkgKiBQdWJsaXNoIGtpbmQgY29uc3RhbnQgKHZhbHVlIDMpIGZvciByZW1vdmVkIHJlc291cmNlcy4KCSAqIAoJICogQHNlZSAjcHVibGlzaE1vZHVsZShpbnQsIGludCwgSU1vZHVsZVtdLCBJUHJvZ3Jlc3NNb25pdG9yKQoJICovCglwdWJsaWMgc3RhdGljIGZpbmFsIGludCBSRU1PVkVEID0gMzsKCgkvKioKCSAqIERlbGVnYXRlcyBtdXN0IGhhdmUgYSBwdWJsaWMgMC1hcmcgY29uc3RydWN0b3IuCgkgKi8KCXB1YmxpYyBTZXJ2ZXJCZWhhdmlvdXJEZWxlZ2F0ZSgpIHsKCQkvLyBkbyBub3RoaW5nCgl9CgoJLyoqCgkgKiBJbml0aWFsaXplcyB0aGlzIHNlcnZlciBkZWxlZ2F0ZSB3aXRoIGl0cyBsaWZlLWxvbmcgc2VydmVyIGluc3RhbmNlLgoJICogPHA+CgkgKiBUaGlzIG1ldGhvZCBpcyBjYWxsZWQgYnkgdGhlIHNlcnZlciBjb3JlIGZyYW1ld29yay4KCSAqIENsaWVudHMgc2hvdWxkIG5ldmVyIGNhbGwgdGhpcyBtZXRob2QuCgkgKiA8L3A+CgkgKiAKCSAqIEBwYXJhbSBuZXdTZXJ2ZXIgdGhlIHNlcnZlciBpbnN0YW5jZQoJICovCglmaW5hbCB2b2lkIGluaXRpYWxpemUoU2VydmVyIG5ld1NlcnZlcikgewoJCXNlcnZlciA9IG5ld1NlcnZlcjsKCQlpbml0aWFsaXplKCk7Cgl9CgoJLyoqCgkgKiBJbml0aWFsaXplcyB0aGlzIHNlcnZlciBkZWxlZ2F0ZS4gVGhpcyBtZXRob2QgZ2l2ZXMgZGVsZWdhdGVzIGEgY2hhbmNlCgkgKiB0byBkbyB0aGVpciBvd24gaW5pdGlhbGl6YXRpb24uCgkgKiA8cD4KCSAqIElmIHRoZSBzZXJ2ZXIgc3RhdGUgaXMgaW5pdGlhbGx5IHVua25vd24sIHRoaXMgbWV0aG9kIHNob3VsZCBhdHRlbXB0CgkgKiB0byBjb25uZWN0IHRvIHRoZSBzZXJ2ZXIgYW5kIHVwZGF0ZSB0aGUgc3RhdGUuIE9uIHNlcnZlcnMgd2hlcmUgdGhlCgkgKiBzdGF0ZSBtYXkgY2hhbmdlLCB0aGlzIGlzIGFsc28gYW4gZXhjZWxsZW50IHBsYWNlIHRvIGNyZWF0ZSBhIGJhY2tncm91bmQKCSAqIHRocmVhZCB0aGF0IHdpbGwgY29uc3RhbnRseSBwaW5nIHRoZSBzZXJ2ZXIgKG9yIGhhdmUgYSBsaXN0ZW5lcikgdG8KCSAqIHVwZGF0ZSB0aGUgc2VydmVyIHN0YXRlIGFzIGNoYW5nZXMgb2NjdXIuCgkgKiA8L3A+CgkgKiA8cD4KCSAqIFRoaXMgbWV0aG9kIGlzIGNhbGxlZCBieSB0aGUgc2VydmVyIGNvcmUgZnJhbWV3b3JrLgoJICogQ2xpZW50cyBzaG91bGQgbmV2ZXIgY2FsbCB0aGlzIG1ldGhvZC4KCSAqIDwvcD4KCSAqIFtpc3N1ZTogYWRkIHByb2dyZXNzIG1vbml0b3I/XQoJICovCglwcm90ZWN0ZWQgdm9pZCBpbml0aWFsaXplKCkgewoJCS8vIGRvIG5vdGhpbmcKCX0KCgkvKioKCSAqIFJldHVybnMgdGhlIHNlcnZlciB0aGF0IHRoaXMgc2VydmVyIGRlbGVnYXRlIGNvcnJlc3BvbmRzIHRvLgoJICogCgkgKiBAcmV0dXJuIHRoZSBzZXJ2ZXIKCSAqLwoJcHVibGljIGZpbmFsIElTZXJ2ZXIgZ2V0U2VydmVyKCkgewoJCXJldHVybiBzZXJ2ZXI7Cgl9CgoJLyoqCgkgKiBTZXRzIHRoZSBjdXJyZW50IHN0YXRlIG9mIHRoaXMgc2VydmVyLgoJICoKCSAqIEBwYXJhbSBzdGF0ZSB0aGUgY3VycmVudCBzdGF0ZSBvZiB0aGUgc2VydmVyLCBvbmUgb2YgdGhlIHN0YXRlCgkgKiAgICBjb25zdGFudHMgZGVmaW5lZCBieSB7QGxpbmsgSVNlcnZlcn0KCSAqIEBzZWUgSVNlcnZlciNnZXRTZXJ2ZXJTdGF0ZSgpCgkgKi8KCXByb3RlY3RlZCBmaW5hbCB2b2lkIHNldFNlcnZlclN0YXRlKGludCBzdGF0ZSkgewoJCXNlcnZlci5zZXRTZXJ2ZXJTdGF0ZShzdGF0ZSk7Cgl9CgoJLyoqCgkgKiBTZXRzIHRoZSBJTGF1bmNoTWFuYWdlciBtb2RlIHRoYXQgdGhlIHNlcnZlciBpcyBydW5uaW5nIGluLiBUaGUgc2VydmVyCgkgKiBpbXBsZW1lbnRhdGlvbiB3aWxsIGF1dG9tYXRpY2FsbHkgcmV0dXJuIDxjb2RlPm51bGw8L2NvZGU+IHRvIGNsaWVudHMKCSAqIHdoZW4gdGhlIHNlcnZlciBpcyBzdG9wcGVkLCBzbyB5b3Ugb25seSBuZWVkIHRvIHVwZGF0ZSB0aGUgbW9kZSB3aGVuCgkgKiBpdCBjaGFuZ2VzLgoJICogCgkgKiBAcGFyYW0gbW9kZSB0aGUgbW9kZSBpbiB3aGljaCBhIHNlcnZlciBpcyBydW5uaW5nLCBvbmUgb2YgdGhlIG1vZGUgY29uc3RhbnRzCgkgKiAgICBkZWZpbmVkIGJ5IHtAbGluayBvcmcuZWNsaXBzZS5kZWJ1Zy5jb3JlLklMYXVuY2hNYW5hZ2VyfQoJICovCglwcm90ZWN0ZWQgZmluYWwgdm9pZCBzZXRNb2RlKFN0cmluZyBtb2RlKSB7CgkJc2VydmVyLnNldE1vZGUobW9kZSk7Cgl9CgoJLyoqCgkgKiBTZXRzIHRoZSBzZXJ2ZXIgcmVzdGFydCBzdGF0ZS4KCSAqCgkgKiBAcGFyYW0gc3RhdGUgPGNvZGU+dHJ1ZTwvY29kZT4gaWYgdGhlIHNlcnZlciBuZWVkcyB0byBiZSByZXN0YXJ0ZWQsCgkgKiAgICBhbmQgPGNvZGU+ZmFsc2U8L2NvZGU+IG90aGVyd2lzZQoJICovCglwcm90ZWN0ZWQgZmluYWwgdm9pZCBzZXRTZXJ2ZXJSZXN0YXJ0U3RhdGUoYm9vbGVhbiBzdGF0ZSkgewoJCXNlcnZlci5zZXRTZXJ2ZXJSZXN0YXJ0U3RhdGUoc3RhdGUpOwoJfQoKCS8qKgoJICogU2V0cyB0aGUgc2VydmVyIHB1Ymxpc2ggc3RhdGUuCgkgKgoJICogQHBhcmFtIHN0YXRlIHRoZSBjdXJyZW50IHB1Ymxpc2ggc3RhdGUgb2YgdGhlIHNlcnZlciwgb25lIG9mIHRoZQoJICogICAgcHVibGlzaCBjb25zdGFudHMgZGVmaW5lZCBieSB7QGxpbmsgSVNlcnZlcn0KCSAqLwoJcHJvdGVjdGVkIGZpbmFsIHZvaWQgc2V0U2VydmVyUHVibGlzaFN0YXRlKGludCBzdGF0ZSkgewoJCXNlcnZlci5zZXRTZXJ2ZXJQdWJsaXNoU3RhdGUoc3RhdGUpOwoJfQoKCS8qKgoJICogSG9vayB0byBmaXJlIGFuIGV2ZW50IHdoZW4gYSBtb2R1bGUgc3RhdGUgY2hhbmdlcy4KCSAqIAoJICogQHBhcmFtIG1vZHVsZSB0aGUgbW9kdWxlCgkgKiBAcGFyYW0gc3RhdGUgdGhlIGN1cnJlbnQgc3RhdGUgb2YgdGhlIG1vZHVsZSwgb25lIG9mIHRoZSBzdGF0ZQoJICogICAgY29uc3RhbnRzIGRlZmluZWQgYnkge0BsaW5rIElTZXJ2ZXJ9CgkgKi8KCXByb3RlY3RlZCBmaW5hbCB2b2lkIHNldE1vZHVsZVN0YXRlKElNb2R1bGVbXSBtb2R1bGUsIGludCBzdGF0ZSkgewoJCXNlcnZlci5zZXRNb2R1bGVTdGF0ZShtb2R1bGUsIHN0YXRlKTsKCX0KCgkvKioKCSAqIFNldHMgdGhlIG1vZHVsZSBwdWJsaXNoIHN0YXRlLgoJICoKCSAqIEBwYXJhbSBtb2R1bGUgdGhlIG1vZHVsZQoJICogQHBhcmFtIHN0YXRlIHRoZSBjdXJyZW50IHB1Ymxpc2ggc3RhdGUgb2YgdGhlIG1vZHVsZSwgb25lIG9mIHRoZQoJICogICAgcHVibGlzaCBjb25zdGFudHMgZGVmaW5lZCBieSB7QGxpbmsgSVNlcnZlcn0KCSAqLwoJcHJvdGVjdGVkIGZpbmFsIHZvaWQgc2V0TW9kdWxlUHVibGlzaFN0YXRlKElNb2R1bGVbXSBtb2R1bGUsIGludCBzdGF0ZSkgewoJCXNlcnZlci5zZXRNb2R1bGVQdWJsaXNoU3RhdGUobW9kdWxlLCBzdGF0ZSk7Cgl9CgoJLyoqCgkgKiBTZXRzIHRoZSBtb2R1bGUgcmVzdGFydCBzdGF0ZS4KCSAqCgkgKiBAcGFyYW0gbW9kdWxlIHRoZSBtb2R1bGUKCSAqIEBwYXJhbSBzdGF0ZSA8Y29kZT50cnVlPC9jb2RlPiBpZiB0aGUgbW9kdWxlIG5lZWRzIHRvIGJlIHJlc3RhcnRlZCwKCSAqICAgIGFuZCA8Y29kZT5mYWxzZTwvY29kZT4gb3RoZXJ3aXNlCgkgKi8KCXByb3RlY3RlZCBmaW5hbCB2b2lkIHNldE1vZHVsZVJlc3RhcnRTdGF0ZShJTW9kdWxlW10gbW9kdWxlLCBib29sZWFuIHN0YXRlKSB7CgkJc2VydmVyLnNldE1vZHVsZVJlc3RhcnRTdGF0ZShtb2R1bGUsIHN0YXRlKTsKCX0KCgkvKioKCSAqIERpc3Bvc2VzIG9mIHRoaXMgc2VydmVyIGRlbGVnYXRlLgoJICogPHA+CgkgKiBUaGlzIG1ldGhvZCBpcyBjYWxsZWQgYnkgdGhlIHdlYiBzZXJ2ZXIgY29yZSBmcmFtZXdvcmsuCgkgKiBDbGllbnRzIHNob3VsZCBuZXZlciBjYWxsIHRoaXMgbWV0aG9kLgoJICogPC9wPgoJICogPHA+CgkgKiBJbXBsZW1lbnRhdGlvbnMgYXJlIGV4cGVjdGVkIHRvIGxldCBnbyBvZiB0aGUgZGVsZWdhdGUncyByZWZlcmVuY2UKCSAqIHRvIHRoZSBzZXJ2ZXIsIGRlcmVnaXN0ZXIgbGlzdGVuZXJzLCBldGMuCgkgKiA8L3A+CgkgKi8KCXB1YmxpYyB2b2lkIGRpc3Bvc2UoKSB7CgkJLy8gZG8gbm90aGluZwoJfQoKCS8qKgoJICogTWV0aG9kcyBjYWxsZWQgdG8gbm90aWZ5IHRoYXQgcHVibGlzaGluZyBpcyBhYm91dCB0byBiZWdpbi4KCSAqIFRoaXMgYWxsb3dzIHRoZSBzZXJ2ZXIgdG8gb3BlbiBhIGNvbm5lY3Rpb24gdG8gdGhlIHNlcnZlcgoJICogb3IgZ2V0IGFueSBnbG9iYWwgaW5mb3JtYXRpb24gcmVhZHkuCgkgKiA8cD4KCSAqIFRoaXMgbWV0aG9kIGlzIGNhbGxlZCBieSB0aGUgc2VydmVyIGNvcmUgZnJhbWV3b3JrLAoJICogaW4gcmVzcG9uc2UgdG8gYSBjYWxsIHRvIDxjb2RlPklTZXJ2ZXIucHVibGlzaCgpPC9jb2RlPi4KCSAqIENsaWVudHMgc2hvdWxkIG5ldmVyIGNhbGwgdGhpcyBtZXRob2QuCgkgKiA8L3A+CgkgKgoJICogQHBhcmFtIG1vbml0b3IgYSBwcm9ncmVzcyBtb25pdG9yLCBvciA8Y29kZT5udWxsPC9jb2RlPiBpZiBwcm9ncmVzcwoJICogICAgcmVwb3J0aW5nIGFuZCBjYW5jZWxsYXRpb24gYXJlIG5vdCBkZXNpcmVkCgkgKiBAdGhyb3dzIENvcmVFeGNlcHRpb24gaWYgdGhlcmUgaXMgYSBwcm9ibGVtIHN0YXJ0aW5nIHRoZSBwdWJsaXNoCgkgKi8KCXByb3RlY3RlZCB2b2lkIHB1Ymxpc2hTdGFydChJUHJvZ3Jlc3NNb25pdG9yIG1vbml0b3IpIHRocm93cyBDb3JlRXhjZXB0aW9uIHsKCQkvLyBkbyBub3RoaW5nCgl9CgoJLyoqCgkgKiBQdWJsaXNoIHRoZSBzZXJ2ZXIuCgkgKiA8cD4KCSAqIFRoaXMgbWV0aG9kIGlzIGNhbGxlZCBieSB0aGUgc2VydmVyIGNvcmUgZnJhbWV3b3JrLAoJICogaW4gcmVzcG9uc2UgdG8gYSBjYWxsIHRvIDxjb2RlPklTZXJ2ZXIucHVibGlzaCgpPC9jb2RlPi4KCSAqIENsaWVudHMgc2hvdWxkIG5ldmVyIGNhbGwgdGhpcyBtZXRob2QuCgkgKiA8L3A+CgkgKiAKCSAqIEBwYXJhbSBraW5kIG9uZSBvZiB0aGUgSVNlcnZlci5QVUJMSVNIX1hYIGNvbnN0YW50cy4gVmFsaWQgdmFsdWVzIGFyZQoJICogICAgPHVsPgoJICogICAgPGxpPjxjb2RlPlBVQkxTSUhfRlVMTDwvY29kZT4tIGluZGljYXRlcyBhIGZ1bGwgcHVibGlzaC48L2xpPgoJICogICAgPGxpPjxjb2RlPlBVQkxJU0hfSU5DUkVNRU5UQUw8L2NvZGU+LSBpbmRpY2F0ZXMgYSBpbmNyZW1lbnRhbCBwdWJsaXNoLgoJICogICAgPGxpPjxjb2RlPlBVQkxTSUhfQVVUTzwvY29kZT4tIGluZGljYXRlcyBhbiBhdXRvbWF0aWMgaW5jcmVtZW50YWwgcHVibGlzaC48L2xpPgoJICogICAgPGxpPjxjb2RlPlBVQkxJU0hfQ0xFQU48L2NvZGU+LSBpbmRpY2F0ZXMgYSBjbGVhbiByZXF1ZXN0LiBDbGVhbiB0aHJvd3MKCSAqICAgICAgb3V0IGFsbCBzdGF0ZSBhbmQgY2xlYW5zIHVwIHRoZSBtb2R1bGUgb24gdGhlIHNlcnZlciBiZWZvcmUgZG9pbmcgYQoJICogICAgICBmdWxsIHB1Ymxpc2guCgkgKiAgICA8L3VsPgoJICogQHBhcmFtIG1vbml0b3IgYSBwcm9ncmVzcyBtb25pdG9yLCBvciA8Y29kZT5udWxsPC9jb2RlPiBpZiBwcm9ncmVzcwoJICogICAgcmVwb3J0aW5nIGFuZCBjYW5jZWxsYXRpb24gYXJlIG5vdCBkZXNpcmVkCgkgKiBAdGhyb3dzIENvcmVFeGNlcHRpb24gaWYgdGhlcmUgaXMgYSBwcm9ibGVtIHB1Ymxpc2hpbmcgdGhlIHNlcnZlcgoJICovCglwcm90ZWN0ZWQgdm9pZCBwdWJsaXNoU2VydmVyKGludCBraW5kLCBJUHJvZ3Jlc3NNb25pdG9yIG1vbml0b3IpIHRocm93cyBDb3JlRXhjZXB0aW9uIHsKCQkvLyBkbyBub3RoaW5nCgl9CgoJLyoqCgkgKiBQdWJsaXNoIGEgc2luZ2xlIG1vZHVsZSB0byB0aGUgc2VydmVyLgoJICogPHA+CgkgKiBUaGlzIG1ldGhvZCBpcyBjYWxsZWQgYnkgdGhlIHNlcnZlciBjb3JlIGZyYW1ld29yaywKCSAqIGluIHJlc3BvbnNlIHRvIGEgY2FsbCB0byA8Y29kZT5JU2VydmVyLnB1Ymxpc2goKTwvY29kZT4uCgkgKiBDbGllbnRzIHNob3VsZCBuZXZlciBjYWxsIHRoaXMgbWV0aG9kIGRpcmVjdGx5LgoJICogPC9wPgoJICogPHA+CgkgKiBJZiB0aGUgZGVsdGFLaW5kIGlzIElTZXJ2ZXIuUkVNT1ZFRCwgdGhlIG1vZHVsZSBtYXkgaGF2ZSBiZWVuIGNvbXBsZXRlbHkKCSAqIGRlbGV0ZWQgYW5kIGRvZXMgbm90IGV4aXN0IGFueW1vcmUuIEluIHRoaXMgY2FzZSwgYSBkdW1teSBtb2R1bGUgKHdpdGggdGhlCgkgKiBjb3JyZWN0IGlkKSB3aWxsIGJlIHBhc3NlZCB0byB0aGlzIG1ldGhvZC4KCSAqIDwvcD4KCSAqIAoJICogQHBhcmFtIGtpbmQgb25lIG9mIHRoZSBJU2VydmVyLlBVQkxJU0hfWFggY29uc3RhbnRzLiBWYWxpZCB2YWx1ZXMgYXJlOgoJICogICAgPHVsPgoJICogICAgPGxpPjxjb2RlPlBVQkxTSUhfRlVMTDwvY29kZT4tIGluZGljYXRlcyBhIGZ1bGwgcHVibGlzaC48L2xpPgoJICogICAgPGxpPjxjb2RlPlBVQkxJU0hfSU5DUkVNRU5UQUw8L2NvZGU+LSBpbmRpY2F0ZXMgYSBpbmNyZW1lbnRhbCBwdWJsaXNoLgoJICogICAgPGxpPjxjb2RlPlBVQkxTSUhfQVVUTzwvY29kZT4tIGluZGljYXRlcyBhbiBhdXRvbWF0aWMgaW5jcmVtZW50YWwgcHVibGlzaC48L2xpPgoJICogICAgPGxpPjxjb2RlPlBVQkxJU0hfQ0xFQU48L2NvZGU+LSBpbmRpY2F0ZXMgYSBjbGVhbiByZXF1ZXN0LiBDbGVhbiB0aHJvd3MKCSAqICAgICAgb3V0IGFsbCBzdGF0ZSBhbmQgY2xlYW5zIHVwIHRoZSBtb2R1bGUgb24gdGhlIHNlcnZlciBiZWZvcmUgZG9pbmcgYQoJICogICAgICBmdWxsIHB1Ymxpc2guCgkgKiAgICA8L3VsPgoJICogQHBhcmFtIG1vZHVsZSB0aGUgbW9kdWxlIHRvIHB1Ymxpc2gKCSAqIEBwYXJhbSBkZWx0YUtpbmQgb25lIG9mIHRoZSBJU2VydmVyIHB1Ymxpc2ggY2hhbmdlIGNvbnN0YW50cy4gVmFsaWQgdmFsdWVzIGFyZToKCSAqICAgIDx1bD4KCSAqICAgIDxsaT48Y29kZT5BRERFRDwvY29kZT4tIGluZGljYXRlcyB0aGUgbW9kdWxlIGhhcyBqdXN0IGJlZW4gYWRkZWQgdG8gdGhlIHNlcnZlcgoJICogICAgICBhbmQgdGhpcyBpcyB0aGUgZmlyc3QgcHVibGlzaC4KCSAqICAgIDxsaT48Y29kZT5OT19DSEFOR0U8L2NvZGU+LSBpbmRpY2F0ZXMgdGhhdCBub3RoaW5nIGhhcyBjaGFuZ2VkIGluIHRoZSBtb2R1bGUKCSAqICAgICAgc2luY2UgdGhlIGxhc3QgcHVibGlzaC48L2xpPgoJICogICAgPGxpPjxjb2RlPkNIQU5HRUQ8L2NvZGU+LSBpbmRpY2F0ZXMgdGhhdCB0aGUgbW9kdWxlIGhhcyBiZWVuIGNoYW5nZWQgc2luY2UKCSAqICAgICAgdGhlIGxhc3QgcHVibGlzaC4gQ2FsbCA8Y29kZT5nZXRQdWJsaXNoZWRSZXNvdXJjZURlbHRhKCk8L2NvZGU+IGZvcgoJICogICAgICBkZXRhaWxzIG9mIHRoZSBjaGFuZ2UuCgkgKiAgICA8bGk+PGNvZGU+UkVNT1ZFRDwvY29kZT4tIGluZGljYXRlcyB0aGUgbW9kdWxlIGhhcyBiZWVuIHJlbW92ZWQgYW5kIHNob3VsZCBiZQoJICogICAgICByZW1vdmVkL2NsZWFuZWQgdXAgZnJvbSB0aGUgc2VydmVyLgoJICogICAgPC91bD4KCSAqIEBwYXJhbSBtb25pdG9yIGEgcHJvZ3Jlc3MgbW9uaXRvciwgb3IgPGNvZGU+bnVsbDwvY29kZT4gaWYgcHJvZ3Jlc3MKCSAqICAgIHJlcG9ydGluZyBhbmQgY2FuY2VsbGF0aW9uIGFyZSBub3QgZGVzaXJlZAoJICogQHRocm93cyBDb3JlRXhjZXB0aW9uIGlmIHRoZXJlIGlzIGEgcHJvYmxlbSBwdWJsaXNoaW5nIHRoZSBtb2R1bGUKCSAqLwoJcHJvdGVjdGVkIHZvaWQgcHVibGlzaE1vZHVsZShpbnQga2luZCwgaW50IGRlbHRhS2luZCwgSU1vZHVsZVtdIG1vZHVsZSwgSVByb2dyZXNzTW9uaXRvciBtb25pdG9yKSB0aHJvd3MgQ29yZUV4Y2VwdGlvbiB7CgkJLy8gZG8gbm90aGluZwoJfQoKCS8qKgoJICogTWV0aG9kcyBjYWxsZWQgdG8gbm90aWZ5IHRoYXQgcHVibGlzaGluZyBoYXMgZmluaXNoZWQuCgkgKiBUaGUgc2VydmVyIGNhbiBjbG9zZSBhbnkgb3BlbiBjb25uZWN0aW9ucyB0byB0aGUgc2VydmVyCgkgKiBhbmQgZG8gYW55IGNsZWFudXAgb3BlcmF0aW9ucy4KCSAqIDxwPgoJICogVGhpcyBtZXRob2QgaXMgY2FsbGVkIGJ5IHRoZSBzZXJ2ZXIgY29yZSBmcmFtZXdvcmssCgkgKiBpbiByZXNwb25zZSB0byBhIGNhbGwgdG8gPGNvZGU+SVNlcnZlci5wdWJsaXNoKCk8L2NvZGU+LgoJICogQ2xpZW50cyBzaG91bGQgbmV2ZXIgY2FsbCB0aGlzIG1ldGhvZC4KCSAqIDwvcD4KCSAqCgkgKiBAcGFyYW0gbW9uaXRvciBhIHByb2dyZXNzIG1vbml0b3IsIG9yIDxjb2RlPm51bGw8L2NvZGU+IGlmIHByb2dyZXNzCgkgKiAgICByZXBvcnRpbmcgYW5kIGNhbmNlbGxhdGlvbiBhcmUgbm90IGRlc2lyZWQKCSAqIEB0aHJvd3MgQ29yZUV4Y2VwdGlvbiBpZiB0aGVyZSBpcyBhIHByb2JsZW0gc3RvcHBpbmcgdGhlIHB1Ymxpc2gKCSAqLwoJcHJvdGVjdGVkIHZvaWQgcHVibGlzaEZpbmlzaChJUHJvZ3Jlc3NNb25pdG9yIG1vbml0b3IpIHRocm93cyBDb3JlRXhjZXB0aW9uIHsKCQkvLyBkbyBub3RoaW5nCgl9CgoJLyoqCgkgKiBDb25maWd1cmUgdGhlIGdpdmVuIGxhdW5jaCBjb25maWd1cmF0aW9uIHRvIHN0YXJ0IHRoaXMgc2VydmVyLiBUaGlzIG1ldGhvZCBpcyBjYWxsZWQgd2hlbmV2ZXIKCSAqIHRoZSBzZXJ2ZXIgaXMgc3RhcnRlZCB0byBlbnN1cmUgdGhhdCB0aGUgbGF1bmNoIGNvbmZpZ3VyYXRpb24gaXMgYWNjdXJhdGUgYW5kIHVwIHRvIGRhdGUuCgkgKiBUaGlzIG1ldGhvZCBzaG91bGQgbm90IGJsaW5kbHkgdXBkYXRlIHRoZSBsYXVuY2ggY29uZmlndXJhdGlvbiBpbiBjYXNlcyB3aGVyZSB0aGUgdXNlciBoYXMKCSAqIGFjY2VzcyB0byBjaGFuZ2UgdGhlIGxhdW5jaCBjb25maWd1cmF0aW9uIGJ5IGhhbmQuCgkgKiAKCSAqIEBwYXJhbSB3b3JraW5nQ29weSBhIGxhdW5jaCBjb25maWd1cmF0aW9uIHdvcmtpbmcgY29weQoJICogQHBhcmFtIG1vbml0b3IgYSBwcm9ncmVzcyBtb25pdG9yLCBvciA8Y29kZT5udWxsPC9jb2RlPiBpZiBwcm9ncmVzcwoJICogICAgcmVwb3J0aW5nIGFuZCBjYW5jZWxsYXRpb24gYXJlIG5vdCBkZXNpcmVkCgkgKiBAdGhyb3dzIENvcmVFeGNlcHRpb24gaWYgdGhlcmUgaXMgYW4gZXJyb3Igc2V0dGluZyB1cCB0aGUgY29uZmlndXJhdGlvbgoJICovCglwdWJsaWMgdm9pZCBzZXR1cExhdW5jaENvbmZpZ3VyYXRpb24oSUxhdW5jaENvbmZpZ3VyYXRpb25Xb3JraW5nQ29weSB3b3JraW5nQ29weSwgSVByb2dyZXNzTW9uaXRvciBtb25pdG9yKSB0aHJvd3MgQ29yZUV4Y2VwdGlvbiB7CgkJLy8gZG8gbm90aGluZwoJfQoKCS8qKgoJICogUmVzdGFydCB0aGlzIHNlcnZlci4gVGhlIHNlcnZlciBzaG91bGQgdXNlIHRoZSBzZXJ2ZXIKCSAqIGxpc3RlbmVyIHRvIG5vdGlmeSBwcm9ncmVzcy4gSXQgbXVzdCB1c2UgdGhlIHNhbWUgZGVidWcKCSAqIGZsYWdzIGFzIHdhcyBvcmlnaW5hbGx5IHBhc3NlZCBpbnRvIHRoZSBzdGFydCgpIG1ldGhvZC4KCSAqIAoJICogVGhpcyBtZXRob2QgaXMgdXNlZCBpZiB0aGVyZSBpcyBhIHF1aWNrL2JldHRlciB3YXkgdG8gcmVzdGFydAoJICogdGhlIHNlcnZlci4gSWYgaXQgdGhyb3dzIGEgQ29yZUV4Y2VwdGlvbiwgdGhlIG5vcm1hbCBzdG9wL3N0YXJ0CgkgKiBhY3Rpb25zIHdpbGwgYmUgdXNlZC4KCSAqIAoJICogQHBhcmFtIGxhdW5jaE1vZGUgdGhlIG1vZGUgdG8gcmVzdGFydCBpbiwgb25lIG9mIHRoZSBtb2RlIGNvbnN0YW50cwoJICogICAgZGVmaW5lZCBieSB7QGxpbmsgb3JnLmVjbGlwc2UuZGVidWcuY29yZS5JTGF1bmNoTWFuYWdlcn0KCSAqIEB0aHJvd3MgQ29yZUV4Y2VwdGlvbiBpZiB0aGVyZSB3YXMgYSBwcm9ibGVtIHJlc3RhcnRpbmcKCSAqLwoJcHVibGljIHZvaWQgcmVzdGFydChTdHJpbmcgbGF1bmNoTW9kZSkgdGhyb3dzIENvcmVFeGNlcHRpb24gewoJCSB0aHJvdyBuZXcgQ29yZUV4Y2VwdGlvbihuZXcgU3RhdHVzKElTdGF0dXMuRVJST1IsIFNlcnZlclBsdWdpbi5QTFVHSU5fSUQsIDAsICJDb3VsZCBub3QgcmVzdGFydCIsIG51bGwpKTsKCX0KCgkvKioKCSAqIFJldHVybnMgd2hldGhlciB0aGUgZ2l2ZW4gbW9kdWxlIGNhbiBiZSByZXN0YXJ0ZWQuCgkgKiA8cD4KCSAqIFtpc3N1ZTogSXQncyB1bmNsZWFyIHdoZXRoZXIgdGhpcyBvcGVyYXRpb25zIGlzIGd1YXJhbnRlZWQgdG8gYmUgZmFzdAoJICogb3Igd2hldGhlciBpdCBjb3VsZCBpbnZvbHZlIGNvbW11bmljYXRpb24gd2l0aCBhbnkgYWN0dWFsCgkgKiBzZXJ2ZXIuIElmIGl0IGlzIG5vdCBmYXN0LCB0aGUgbWV0aG9kIHNob3VsZCB0YWtlIGEgcHJvZ3Jlc3MKCSAqIG1vbml0b3IuXQoJICogPC9wPgoJICogCgkgKiBAcGFyYW0gbW9kdWxlIHRoZSBtb2R1bGUKCSAqIEByZXR1cm4gPGNvZGU+dHJ1ZTwvY29kZT4gaWYgdGhlIGdpdmVuIG1vZHVsZSBjYW4gYmUKCSAqIHJlc3RhcnRlZCwgYW5kIDxjb2RlPmZhbHNlPC9jb2RlPiBvdGhlcndpc2UgCgkgKi8KCXB1YmxpYyBib29sZWFuIGNhbkNvbnRyb2xNb2R1bGUoSU1vZHVsZVtdIG1vZHVsZSkgewoJCXJldHVybiBmYWxzZTsKCX0KCQoJLyoqCgkgKiBTdGFydHMgdGhlIGdpdmVuIG1vZHVsZSBvbiB0aGUgc2VydmVyLiBTZWUgdGhlIHNwZWNpZmljYXRpb24gb2YgCgkgKiB7QGxpbmsgSVNlcnZlciNzdGFydE1vZHVsZShJTW9kdWxlW10sIElTZXJ2ZXIuSU9wZXJhdGlvbkxpc3RlbmVyKX0KCSAqIGZvciBmdXJ0aGVyIGRldGFpbHMuIAoJICogPHA+CgkgKiBUaGUgaW1wbGVtZW50YXRpb24gc2hvdWxkIHVwZGF0ZSB0aGUgbW9kdWxlIHN5bmMgc3RhdGUgYW5kIGZpcmUKCSAqIGFuIGV2ZW50IGZvciB0aGUgbW9kdWxlLgoJICogPC9wPgoJICogPHA+CgkgKiBUaGlzIG1ldGhvZCB3aWxsIHRocm93IGFuIGV4Y2VwdGlvbiBpZiB0aGUgbW9kdWxlIGRvZXMgbm90IGV4aXN0IG9uCgkgKiB0aGUgc2VydmVyLgoJICogPC9wPgoJICogPHA+CgkgKiBbaXNzdWU6IFNpbmNlIHRoaXMgbWV0aG9kIGlzIGFzY3luY2hyb25vdXMsIGlzIHRoZXJlCgkgKiBhbnkgbmVlZCBmb3IgdGhlIHByb2dyZXNzIG1vbml0b3I/XQoJICogPC9wPgoJICogCgkgKiBAcGFyYW0gbW9kdWxlIHRoZSBtb2R1bGUgdG8gYmUgc3RhcnRlZAoJICogQHBhcmFtIG1vbml0b3IgYSBwcm9ncmVzcyBtb25pdG9yLCBvciA8Y29kZT5udWxsPC9jb2RlPiBpZiBwcm9ncmVzcwoJICogICAgcmVwb3J0aW5nIGFuZCBjYW5jZWxsYXRpb24gYXJlIG5vdCBkZXNpcmVkCgkgKiBAZXhjZXB0aW9uIENvcmVFeGNlcHRpb24gaWYgYW4gZXJyb3Igb2NjdXJzIHdoaWxlIHRyeWluZyB0byByZXN0YXJ0IHRoZSBtb2R1bGUKCSAqLwoJcHVibGljIHZvaWQgc3RhcnRNb2R1bGUoSU1vZHVsZVtdIG1vZHVsZSwgSVByb2dyZXNzTW9uaXRvciBtb25pdG9yKSB0aHJvd3MgQ29yZUV4Y2VwdGlvbiB7CgkJLy8gZG8gbm90aGluZwoJfQoKCS8qKgoJICogU3RvcHMgdGhlIGdpdmVuIG1vZHVsZSBvbiB0aGUgc2VydmVyLiBTZWUgdGhlIHNwZWNpZmljYXRpb24gb2YgCgkgKiB7QGxpbmsgSVNlcnZlciNzdG9wTW9kdWxlKElNb2R1bGVbXSwgSVNlcnZlci5JT3BlcmF0aW9uTGlzdGVuZXIpfQoJICogZm9yIGZ1cnRoZXIgZGV0YWlscy4gCgkgKiA8cD4KCSAqIFRoZSBpbXBsZW1lbnRhdGlvbiBzaG91bGQgdXBkYXRlIHRoZSBtb2R1bGUgc3luYyBzdGF0ZSBhbmQgZmlyZQoJICogYW4gZXZlbnQgZm9yIHRoZSBtb2R1bGUuCgkgKiA8L3A+CgkgKiA8cD4KCSAqIFRoaXMgbWV0aG9kIHdpbGwgdGhyb3cgYW4gZXhjZXB0aW9uIGlmIHRoZSBtb2R1bGUgZG9lcyBub3QgZXhpc3Qgb24KCSAqIHRoZSBzZXJ2ZXIuCgkgKiA8L3A+CgkgKiA8cD4KCSAqIFtpc3N1ZTogU2luY2UgdGhpcyBtZXRob2QgaXMgYXNjeW5jaHJvbm91cywgaXMgdGhlcmUKCSAqIGFueSBuZWVkIGZvciB0aGUgcHJvZ3Jlc3MgbW9uaXRvcj9dCgkgKiA8L3A+CgkgKiAKCSAqIEBwYXJhbSBtb2R1bGUgdGhlIG1vZHVsZSB0byBiZSBzdG9wcGVkCgkgKiBAcGFyYW0gbW9uaXRvciBhIHByb2dyZXNzIG1vbml0b3IsIG9yIDxjb2RlPm51bGw8L2NvZGU+IGlmIHByb2dyZXNzCgkgKiAgICByZXBvcnRpbmcgYW5kIGNhbmNlbGxhdGlvbiBhcmUgbm90IGRlc2lyZWQKCSAqIEBleGNlcHRpb24gQ29yZUV4Y2VwdGlvbiBpZiBhbiBlcnJvciBvY2N1cnMgd2hpbGUgdHJ5aW5nIHRvIHJlc3RhcnQgdGhlIG1vZHVsZQoJICovCglwdWJsaWMgdm9pZCBzdG9wTW9kdWxlKElNb2R1bGVbXSBtb2R1bGUsIElQcm9ncmVzc01vbml0b3IgbW9uaXRvcikgdGhyb3dzIENvcmVFeGNlcHRpb24gewoJCS8vIGRvIG5vdGhpbmcKCX0KCgkvKioKCSAqIFNodXRzIGRvd24gYW5kIHN0b3BzIHRoaXMgc2VydmVyLiBUaGUgc2VydmVyIHNob3VsZCByZXR1cm4gZnJvbSB0aGlzIG1ldGhvZAoJICogcXVpY2tseSBhbmQgdXNlIHRoZSBzZXJ2ZXIgbGlzdGVuZXIgdG8gbm90aWZ5IHNodXRkb3duIHByb2dyZXNzLgoJICogPHA+IAoJICogSWYgZm9yY2UgaXMgPGNvZGU+ZmFsc2U8L2NvZGU+LCBpdCB3aWxsIGF0dGVtcHQgdG8gc3RvcCB0aGUgc2VydmVyCgkgKiBub3JtYWxseS9ncmFjZWZ1bGx5LiBJZiBmb3JjZSBpcyA8Y29kZT50cnVlPC9jb2RlPiwgdGhlbiB0aGUgc2VydmVyCgkgKiBwcm9jZXNzIHdpbGwgYmUgdGVybWluYXRlZCBhbnkgd2F5IHRoYXQgaXQgY2FuLgoJICogPC9wPgoJICogPHA+CgkgKiBbaXNzdWU6IFRoZXJlIGlzIG5vIHdheSB0byBjb21tdW5pY2F0ZSBmYWlsdXJlIHRvIHRoZQoJICogY2xpZW50LiBHaXZlbiB0aGF0IHRoaXMgb3BlcmF0aW9uIGNhbiBnbyBhd3J5LCB0aGVyZSBwcm9iYWJseQoJICogc2hvdWxkIGJlIGEgbWVjaGFuaXNtIHRoYXQgYWxsb3dzIGZhaWxpbmcgYXN5bmNoIG9wZXJhdGlvbnMKCSAqIHRvIGJlIGRpYWdub3NlZC5dCgkgKiA8L3A+CgkgKiBAcGFyYW0gZm9yY2UgPGNvZGU+dHJ1ZTwvY29kZT4gdG8ga2lsbCB0aGUgc2VydmVyLCBvciA8Y29kZT5mYWxzZTwvY29kZT4KCSAqICAgIHRvIHN0b3Agbm9ybWFsbHkKCSAqLwoJcHVibGljIGFic3RyYWN0IHZvaWQgc3RvcChib29sZWFuIGZvcmNlKTsKCgkvKioKCSAqIFJldHVybnMgdGhlIG1vZHVsZSByZXNvdXJjZXMgdGhhdCBoYXZlIGJlZW4gcHVibGlzaGVkIHRvIHRoZSBzZXJ2ZXIuCgkgKiAKCSAqIDxwPgoJICogSWYgdGhlIG1vZHVsZSBoYXMganVzdCBiZWVuIGFkZGVkIHRvIHRoZSBzZXJ2ZXIsIGFuIGVtcHR5IGxpc3Qgd2lsbAoJICogYmUgcmV0dXJuZWQuIElmIHRoZSBtb2R1bGUgaGFzIG5ldmVyIGV4aXN0ZWQgb24gdGhlIHNlcnZlciwgYSBDb3JlRXhjZXB0aW9uCgkgKiB3aWxsIGJlIHRocm93bi4KCSAqIDwvcD4KCSAqIAoJICogQHBhcmFtIG1vZHVsZSB0aGUgbW9kdWxlCgkgKiBAcmV0dXJuIGFuIGFycmF5IGNvbnRhaW5pbmcgdGhlIHB1Ymxpc2hlZCBtb2R1bGUgcmVzb3VyY2UKCSAqLwoJcHJvdGVjdGVkIElNb2R1bGVSZXNvdXJjZVtdIGdldFB1Ymxpc2hlZFJlc291cmNlcyhJTW9kdWxlW10gbW9kdWxlKSB7CgkJcmV0dXJuIHNlcnZlci5nZXRQdWJsaXNoZWRSZXNvdXJjZXMobW9kdWxlKTsKCX0KCgkvKioKCSAqIFJldHVybnMgdGhlIGRlbHRhIG9mIHRoZSBjdXJyZW50IG1vZHVsZSByZXNvdXJjZXMgdGhhdCBoYXZlIGJlZW4KCSAqIHB1Ymxpc2hlZCBjb21wYXJlZCB0byB0aGUgY3VycmVudCBzdGF0ZSBvZiB0aGUgbW9kdWxlLgoJICoKCSAqIEBwYXJhbSBtb2R1bGUgdGhlIG1vZHVsZQoJICogQHJldHVybiBhbiBhcnJheSBjb250YWluaW5nIHRoZSBwdWJsaXNoIHJlc291cmNlIGRlbHRhCgkgKi8KCXByb3RlY3RlZCBJTW9kdWxlUmVzb3VyY2VEZWx0YVtdIGdldFB1Ymxpc2hlZFJlc291cmNlRGVsdGEoSU1vZHVsZVtdIG1vZHVsZSkgewoJCXJldHVybiBzZXJ2ZXIuZ2V0UHVibGlzaGVkUmVzb3VyY2VEZWx0YShtb2R1bGUpOwoJfQoKCS8qKgoJICogUmV0dXJucyBhIHRlbXBvcmFyeSBkaXJlY3RvcnkgdGhhdCB0aGUgcmVxdWVzdG9yIGNhbiB1c2UKCSAqIHRocm91Z2hvdXQgaXQncyBsaWZlY3ljbGUuIFRoaXMgaXMgcHJpbWFyeSB0byBiZSB1c2VkIGJ5CgkgKiBzZXJ2ZXJzIGZvciB3b3JraW5nIGRpcmVjdG9yaWVzLCBzZXJ2ZXIgc3BlY2lmaWMKCSAqIGZpbGVzLCBldGMuCgkgKiA8cD4KCSAqIFRoaXMgbWV0aG9kIGRpcmVjdG9yeSB3aWxsIHJldHVybiB0aGUgc2FtZSBkaXJlY3Rvcnkgb24KCSAqIGVhY2ggdXNlIG9mIHRoZSB3b3JrYmVuY2guIElmIHRoZSBkaXJlY3RvcnkgaXMgbm90IHJlcXVlc3RlZAoJICogb3ZlciBhIHBlcmlvZCBvZiB0aW1lLCB0aGUgZGlyZWN0b3J5IG1heSBiZSBkZWxldGVkIGFuZCBhCgkgKiBuZXcgb25lIHdpbGwgYmUgYXNzaWduZWQgb24gdGhlIG5leHQgcmVxdWVzdC4gRm9yIHRoaXMKCSAqIHJlYXNvbiwgYSBzZXJ2ZXIgbWF5IHdhbnQgdG8gcmVxdWVzdCB0aGUgdGVtcCBkaXJlY3Rvcnkgb24KCSAqIHN0YXJ0dXAgaWYgaXQgd2FudHMgdG8gc3RvcmUgZmlsZXMgdGhlcmUuIEluIGFueSBjYXNlLCB0aGUKCSAqIHNlcnZlciBzaG91bGQgaGF2ZSBhIGJhY2t1cCBwbGFuIHRvIHJlZmlsbCB0aGUgZGlyZWN0b3J5CgkgKiBpbiBjYXNlIGl0IGhhcyBiZWVuIGRlbGV0ZWQgc2luY2UgbGFzdCB1c2UuPC9wPgoJICoKCSAqIEByZXR1cm4gYSB0ZW1wb3JhcnkgZGlyZWN0b3J5CgkgKi8KCXByb3RlY3RlZCBJUGF0aCBnZXRUZW1wRGlyZWN0b3J5KCkgewoJCXJldHVybiBzZXJ2ZXIuZ2V0VGVtcERpcmVjdG9yeSgpOwoJfQoKCS8qKgoJICogU2V0IGEgZ2xvYmFsIHN0YXR1cyBvbiB0aGUgc2VydmVyLgoJICogIAoJICogQHBhcmFtIHN0YXR1cyB0aGUgc3RhdHVzCgkgKi8KCXByb3RlY3RlZCBmaW5hbCB2b2lkIHNldFNlcnZlclN0YXR1cyhJU3RhdHVzIHN0YXR1cykgewoJCXNlcnZlci5zZXRTZXJ2ZXJTdGF0dXMoc3RhdHVzKTsKCX0KCgkvKioKCSAqIFNldCBhIHN0YXR1cyBvbiBhIHNwZWNpZmljIG1vZHVsZS4KCSAqIAoJICogQHBhcmFtIG1vZHVsZSB0aGUgbW9kdWxlCgkgKiBAcGFyYW0gc3RhdHVzIHRoZSBzdGF0dXMKCSAqLwoJcHJvdGVjdGVkIGZpbmFsIHZvaWQgc2V0TW9kdWxlU3RhdHVzKElNb2R1bGVbXSBtb2R1bGUsIElTdGF0dXMgc3RhdHVzKSB7CgkJc2VydmVyLnNldE1vZHVsZVN0YXR1cyhtb2R1bGUsIHN0YXR1cyk7Cgl9CgkKCXB1YmxpYyBJU3RhdHVzIHB1Ymxpc2goaW50IGtpbmQsIElQcm9ncmVzc01vbml0b3IgbW9uaXRvcikgewoJCVRyYWNlLnRyYWNlKFRyYWNlLkZJTkVTVCwgIi0tPi0tIFB1Ymxpc2hpbmcgdG8gc2VydmVyOiAiICsgdG9TdHJpbmcoKSArICIgLS0+LS0iKTsKCgkJZmluYWwgTGlzdCBtb2R1bGVMaXN0ID0gZ2V0QWxsTW9kdWxlcygpOwoJCWZpbmFsIExpc3Qga2luZExpc3QgPSBuZXcgQXJyYXlMaXN0KCk7CgkJCgkJSXRlcmF0b3IgaXRlcmF0b3IgPSBtb2R1bGVMaXN0Lml0ZXJhdG9yKCk7CgkJd2hpbGUgKGl0ZXJhdG9yLmhhc05leHQoKSkgewoJCQlJTW9kdWxlW10gbW9kdWxlID0gKElNb2R1bGVbXSkgaXRlcmF0b3IubmV4dCgpOwoJCQlpZiAoaGFzQmVlblB1Ymxpc2hlZChtb2R1bGUpKSB7CgkJCQlpZiAoZ2V0UHVibGlzaGVkUmVzb3VyY2VEZWx0YShtb2R1bGUpLmxlbmd0aCA9PSAwKQoJCQkJCWtpbmRMaXN0LmFkZChuZXcgSW50ZWdlcihTZXJ2ZXJCZWhhdmlvdXJEZWxlZ2F0ZS5OT19DSEFOR0UpKTsKCQkJCWVsc2UKCQkJCQlraW5kTGlzdC5hZGQobmV3IEludGVnZXIoU2VydmVyQmVoYXZpb3VyRGVsZWdhdGUuQ0hBTkdFRCkpOwoJCQl9IGVsc2UKCQkJCWtpbmRMaXN0LmFkZChuZXcgSW50ZWdlcihTZXJ2ZXJCZWhhdmlvdXJEZWxlZ2F0ZS5BRERFRCkpOwoJCX0KCQkKCQlQdWJsaXNoT3BlcmF0aW9uW10gdGFza3MgPSBnZXRUYXNrcygpOwoJCQoJCWFkZFJlbW92ZWRNb2R1bGVzKG1vZHVsZUxpc3QsIGtpbmRMaXN0KTsKCQkKCQl3aGlsZSAobW9kdWxlTGlzdC5zaXplKCkgPiBraW5kTGlzdC5zaXplKCkpIHsKCQkJa2luZExpc3QuYWRkKG5ldyBJbnRlZ2VyKFNlcnZlckJlaGF2aW91ckRlbGVnYXRlLlJFTU9WRUQpKTsKCQl9CgoJCWludCBzaXplID0gMjAwMCArIDM1MDAgKiBtb2R1bGVMaXN0LnNpemUoKSArIDUwMCAqIHRhc2tzLmxlbmd0aDsKCQkKCQltb25pdG9yID0gUHJvZ3Jlc3NVdGlsLmdldE1vbml0b3JGb3IobW9uaXRvcik7CgkJbW9uaXRvci5iZWdpblRhc2soTkxTLmJpbmQoTWVzc2FnZXMucHVibGlzaGluZywgdG9TdHJpbmcoKSksIHNpemUpOwoKCQkvLyBUT0RPIC0gZ3JvdXAgdXAgc3RhdHVzIHVudGlsIHRoZSBlbmQgYW5kIHVzZSBiZXR0ZXIgbWVzc2FnZSBiYXNlZCBvbiBzdWNjZXNzIG9yIGZhaWx1cmUKCQlNdWx0aVN0YXR1cyBtdWx0aSA9IG5ldyBNdWx0aVN0YXR1cyhTZXJ2ZXJQbHVnaW4uUExVR0lOX0lELCAwLCBNZXNzYWdlcy5wdWJsaXNoaW5nU3RhdHVzLCBudWxsKTsKCgkJaWYgKG1vbml0b3IuaXNDYW5jZWxlZCgpKQoJCQlyZXR1cm4gbmV3IFN0YXR1cyhJU3RhdHVzLklORk8sIFNlcnZlclBsdWdpbi5QTFVHSU5fSUQsIDAsIE1lc3NhZ2VzLnB1Ymxpc2hpbmdDYW5jZWxsZWQsIG51bGwpOwoJCQoJCS8vIHN0YXJ0IHB1Ymxpc2hpbmcKCQlUcmFjZS50cmFjZShUcmFjZS5GSU5FU1QsICJDYWxsaW5nIHB1Ymxpc2hTdGFydCgpIik7CgkJdHJ5IHsKCQkJcHVibGlzaFN0YXJ0KFByb2dyZXNzVXRpbC5nZXRTdWJNb25pdG9yRm9yKG1vbml0b3IsIDEwMDApKTsKCQl9IGNhdGNoIChDb3JlRXhjZXB0aW9uIGNlKSB7CgkJCVRyYWNlLnRyYWNlKFRyYWNlLklORk8sICJDb3JlRXhjZXB0aW9uIHB1Ymxpc2hpbmcgdG8gIiArIHRvU3RyaW5nKCksIGNlKTsKCQkJcmV0dXJuIGNlLmdldFN0YXR1cygpOwoJCX0KCQkKCQkvLyBwZXJmb3JtIHRhc2tzCgkJSVN0YXR1cyB0YXNrU3RhdHVzID0gcGVyZm9ybVRhc2tzKHRhc2tzLCBtb25pdG9yKTsKCQlpZiAodGFza1N0YXR1cyAhPSBudWxsKQoJCQltdWx0aS5hZGQodGFza1N0YXR1cyk7CgkJCgkJLy8gcHVibGlzaCB0aGUgc2VydmVyCgkJdHJ5IHsKCQkJaWYgKCFtb25pdG9yLmlzQ2FuY2VsZWQoKSAmJiBnZXRTZXJ2ZXIoKS5nZXRTZXJ2ZXJUeXBlKCkuaGFzU2VydmVyQ29uZmlndXJhdGlvbigpKSB7CgkJCQlwdWJsaXNoU2VydmVyKGtpbmQsIFByb2dyZXNzVXRpbC5nZXRTdWJNb25pdG9yRm9yKG1vbml0b3IsIDEwMDApKTsKCQkJfQoJCX0gY2F0Y2ggKENvcmVFeGNlcHRpb24gY2UpIHsKCQkJVHJhY2UudHJhY2UoVHJhY2UuSU5GTywgIkNvcmVFeGNlcHRpb24gcHVibGlzaGluZyB0byAiICsgdG9TdHJpbmcoKSwgY2UpOwoJCQltdWx0aS5hZGQoY2UuZ2V0U3RhdHVzKCkpOwoJCX0gY2F0Y2ggKEV4Y2VwdGlvbiBlKSB7CgkJCVRyYWNlLnRyYWNlKFRyYWNlLlNFVkVSRSwgIkVycm9yIHB1Ymxpc2hpbmcgY29uZmlndXJhdGlvbiB0byAiICsgdG9TdHJpbmcoKSwgZSk7CgkJCW11bHRpLmFkZChuZXcgU3RhdHVzKElTdGF0dXMuRVJST1IsIFNlcnZlclBsdWdpbi5QTFVHSU5fSUQsIDAsIE1lc3NhZ2VzLmVycm9yUHVibGlzaGluZywgZSkpOwoJCX0KCQkKCQkvLyBwdWJsaXNoIG1vZHVsZXMKCQlpZiAoIW1vbml0b3IuaXNDYW5jZWxlZCgpKSB7CgkJCXRyeSB7CgkJCQlwdWJsaXNoTW9kdWxlcyhraW5kLCBtb2R1bGVMaXN0LCBraW5kTGlzdCwgbXVsdGksIG1vbml0b3IpOwoJCQl9IGNhdGNoIChFeGNlcHRpb24gZSkgewoJCQkJVHJhY2UudHJhY2UoVHJhY2UuV0FSTklORywgIkVycm9yIHdoaWxlIHB1Ymxpc2hpbmcgbW9kdWxlcyIsIGUpOwoJCQkJbXVsdGkuYWRkKG5ldyBTdGF0dXMoSVN0YXR1cy5FUlJPUiwgU2VydmVyUGx1Z2luLlBMVUdJTl9JRCwgMCwgTWVzc2FnZXMuZXJyb3JQdWJsaXNoaW5nLCBlKSk7CgkJCX0KCQl9CgkJCgkJLy8gZW5kIHRoZSBwdWJsaXNoaW5nCgkJVHJhY2UudHJhY2UoVHJhY2UuRklORVNULCAiQ2FsbGluZyBwdWJsaXNoRmluaXNoKCkiKTsKCQl0cnkgewoJCQlwdWJsaXNoRmluaXNoKFByb2dyZXNzVXRpbC5nZXRTdWJNb25pdG9yRm9yKG1vbml0b3IsIDUwMCkpOwoJCX0gY2F0Y2ggKENvcmVFeGNlcHRpb24gY2UpIHsKCQkJVHJhY2UudHJhY2UoVHJhY2UuSU5GTywgIkNvcmVFeGNlcHRpb24gcHVibGlzaGluZyB0byAiICsgdG9TdHJpbmcoKSwgY2UpOwoJCQltdWx0aS5hZGQoY2UuZ2V0U3RhdHVzKCkpOwoJCX0gY2F0Y2ggKEV4Y2VwdGlvbiBlKSB7CgkJCVRyYWNlLnRyYWNlKFRyYWNlLlNFVkVSRSwgIkVycm9yIHN0b3BwaW5nIHB1Ymxpc2ggdG8gIiArIHRvU3RyaW5nKCksIGUpOwoJCQltdWx0aS5hZGQobmV3IFN0YXR1cyhJU3RhdHVzLkVSUk9SLCBTZXJ2ZXJQbHVnaW4uUExVR0lOX0lELCAwLCBNZXNzYWdlcy5lcnJvclB1Ymxpc2hpbmcsIGUpKTsKCQl9CgkJCgkJaWYgKG1vbml0b3IuaXNDYW5jZWxlZCgpKSB7CgkJCUlTdGF0dXMgc3RhdHVzID0gbmV3IFN0YXR1cyhJU3RhdHVzLklORk8sIFNlcnZlclBsdWdpbi5QTFVHSU5fSUQsIDAsIE1lc3NhZ2VzLnB1Ymxpc2hpbmdDYW5jZWxsZWQsIG51bGwpOwoJCQltdWx0aS5hZGQoc3RhdHVzKTsKCQl9CgoJCU11bHRpU3RhdHVzIHBzID0gbmV3IE11bHRpU3RhdHVzKFNlcnZlclBsdWdpbi5QTFVHSU5fSUQsIDAsIE1lc3NhZ2VzLnB1Ymxpc2hpbmdTdG9wLCBudWxsKTsKCQlwcy5hZGQobXVsdGkpOwoKCQltb25pdG9yLmRvbmUoKTsKCgkJVHJhY2UudHJhY2UoVHJhY2UuRklORVNULCAiLS08LS0gRG9uZSBwdWJsaXNoaW5nIC0tPC0tIik7CgkJCgkJaWYgKG11bHRpLmdldENoaWxkcmVuKCkubGVuZ3RoID09IDEpCgkJCXJldHVybiBtdWx0aS5nZXRDaGlsZHJlbigpWzBdOwoJCQoJCXJldHVybiBtdWx0aTsKCX0KCgkvKioKCSAqIFB1Ymxpc2ggYSBzaW5nbGUgbW9kdWxlLgoJICovCglwcm90ZWN0ZWQgSVN0YXR1cyBwdWJsaXNoTW9kdWxlKGludCBraW5kLCBJTW9kdWxlW10gbW9kdWxlLCBpbnQgZGVsdGFLaW5kLCBJUHJvZ3Jlc3NNb25pdG9yIG1vbml0b3IpIHsKCQlUcmFjZS50cmFjZShUcmFjZS5GSU5FU1QsICJQdWJsaXNoaW5nIG1vZHVsZTogIiArIG1vZHVsZSk7CgkJCgkJaW50IHNpemUgPSBtb2R1bGUubGVuZ3RoOwoJCUlNb2R1bGUgbSA9IG1vZHVsZVtzaXplIC0gMV07CgkJbW9uaXRvci5iZWdpblRhc2soTkxTLmJpbmQoTWVzc2FnZXMucHVibGlzaGluZ01vZHVsZSwgbS5nZXROYW1lKCkpLCAxMDAwKTsKCQkKCQlJU3RhdHVzIHN0YXR1cyA9IG5ldyBTdGF0dXMoSVN0YXR1cy5PSywgU2VydmVyUGx1Z2luLlBMVUdJTl9JRCwgMCwgTkxTLmJpbmQoTWVzc2FnZXMucHVibGlzaGVkTW9kdWxlLCBtLmdldE5hbWUoKSksIG51bGwpOwoJCXRyeSB7CgkJCXB1Ymxpc2hNb2R1bGUoa2luZCwgZGVsdGFLaW5kLCBtb2R1bGUsIG1vbml0b3IpOwoJCX0gY2F0Y2ggKENvcmVFeGNlcHRpb24gY2UpIHsKCQkJc3RhdHVzID0gY2UuZ2V0U3RhdHVzKCk7CgkJfQoJCQoJCS8qVHJhY2UudHJhY2UoVHJhY2UuRklORVNULCAiRGVsdGE6Iik7CgkJSU1vZHVsZVJlc291cmNlRGVsdGFbXSBkZWx0YSA9IGdldFNlcnZlclB1Ymxpc2hJbmZvKCkuZ2V0RGVsdGEocGFyZW50cywgbW9kdWxlKTsKCQlpbnQgc2l6ZSA9IGRlbHRhLmxlbmd0aDsKCQlmb3IgKGludCBpID0gMDsgaSA8IHNpemU7IGkrKykgewoJCQkoKE1vZHVsZVJlc291cmNlRGVsdGEpZGVsdGFbaV0pLnRyYWNlKCI+ICAiKTsKCQl9Ki8KCQl1cGRhdGVQdWJsaXNoSW5mbyhkZWx0YUtpbmQsIG1vZHVsZSk7CgkJCgkJbW9uaXRvci5kb25lKCk7CgkJCgkJVHJhY2UudHJhY2UoVHJhY2UuRklORVNULCAiRG9uZSBwdWJsaXNoaW5nOiAiICsgbW9kdWxlKTsKCQlyZXR1cm4gc3RhdHVzOwoJfQoJCglwcm90ZWN0ZWQgYm9vbGVhbiBoYXNCZWVuUHVibGlzaGVkKElNb2R1bGVbXSBtb2R1bGUpIHsKCQlyZXR1cm4gc2VydmVyLmdldFNlcnZlclB1Ymxpc2hJbmZvKCkuaGFzTW9kdWxlUHVibGlzaEluZm8obW9kdWxlKTsKCX0KCQoJcHJvdGVjdGVkIHZvaWQgYWRkUmVtb3ZlZE1vZHVsZXMoTGlzdCBtb2R1bGVMaXN0LCBMaXN0IGtpbmRMaXN0KSB7CgkJc2VydmVyLmdldFNlcnZlclB1Ymxpc2hJbmZvKCkuYWRkUmVtb3ZlZE1vZHVsZXMobW9kdWxlTGlzdCwga2luZExpc3QpOwoJfQoJCglwcm90ZWN0ZWQgdm9pZCB1cGRhdGVQdWJsaXNoSW5mbyhpbnQgZGVsdGFLaW5kLCBJTW9kdWxlW10gbW9kdWxlKSB7CgkJaWYgKGRlbHRhS2luZCA9PSBTZXJ2ZXJCZWhhdmlvdXJEZWxlZ2F0ZS5SRU1PVkVEKQoJCQlzZXJ2ZXIuZ2V0U2VydmVyUHVibGlzaEluZm8oKS5yZW1vdmVNb2R1bGVQdWJsaXNoSW5mbyhtb2R1bGUpOwoJCWVsc2UKCQkJc2VydmVyLmdldFNlcnZlclB1Ymxpc2hJbmZvKCkuZmlsbChtb2R1bGUpOwoJfQoKCS8qKgoJICogUHVibGlzaGVzIHRoZSBnaXZlbiBtb2R1bGVzLiBSZXR1cm5zIHRydWUgaWYgdGhlIHB1Ymxpc2hpbmcKCSAqIHNob3VsZCBjb250aW51ZSwgb3IgZmFsc2UgaWYgcHVibGlzaGluZyBoYXMgZmFpbGVkIG9yIGlzIGNhbmNlbGxlZC4KCSAqIAoJICogVXNlcyA1MDAgdGlja3MgcGx1cyAzNTAwIHRpY2tzIHBlciBtb2R1bGUKCSAqLwoJcHJvdGVjdGVkIHZvaWQgcHVibGlzaE1vZHVsZXMoaW50IGtpbmQsIExpc3QgbW9kdWxlczIsIExpc3QgZGVsdGFLaW5kLCBNdWx0aVN0YXR1cyBtdWx0aSwgSVByb2dyZXNzTW9uaXRvciBtb25pdG9yKSB7CgkJaWYgKG1vZHVsZXMyID09IG51bGwpCgkJCXJldHVybjsKCgkJaW50IHNpemUgPSBtb2R1bGVzMi5zaXplKCk7CgkJaWYgKHNpemUgPT0gMCkKCQkJcmV0dXJuOwoJCQoJCWlmIChtb25pdG9yLmlzQ2FuY2VsZWQoKSkKCQkJcmV0dXJuOwoKCQkvLyBwdWJsaXNoIG1vZHVsZXMKCQlmb3IgKGludCBpID0gMDsgaSA8IHNpemU7IGkrKykgewoJCQlJU3RhdHVzIHN0YXR1cyA9IHB1Ymxpc2hNb2R1bGUoa2luZCwgKElNb2R1bGVbXSkgbW9kdWxlczIuZ2V0KGkpLCAoKEludGVnZXIpZGVsdGFLaW5kLmdldChpKSkuaW50VmFsdWUoKSwgUHJvZ3Jlc3NVdGlsLmdldFN1Yk1vbml0b3JGb3IobW9uaXRvciwgMzAwMCkpOwoJCQltdWx0aS5hZGQoc3RhdHVzKTsKCQl9Cgl9CgoJLyoqCgkgKiBSZXR1cm5zIHRoZSBwdWJsaXNoIHRhc2tzIHRoYXQgaGF2ZSBiZWVuIHRhcmdldHRlZCB0byB0aGlzIHNlcnZlci4KCSAqIFRoZXNlIHRhc2tzIHNob3VsZCBiZSBydW4gZHVyaW5nIHB1Ymxpc2hpbmcuCgkgKiAKCSAqIEByZXR1cm4gYSBwb3NzaWJseSBlbXB0eSBhcnJheSBvZiBJT3B0aW9uYWxUYXNrcwoJICovCglwcm90ZWN0ZWQgZmluYWwgUHVibGlzaE9wZXJhdGlvbltdIGdldFRhc2tzKCkgewoJCXJldHVybiBzZXJ2ZXIuZ2V0VGFza3MoKTsKCX0KCgkvKioKCSAqIFJldHVybnMgYWxsIHRoZSBtb2R1bGVzIHRoYXQgYXJlIG9uIHRoZSBzZXJ2ZXIsIGluY2x1ZGluZyByb290CgkgKiBtb2R1bGVzIGFuZCBhbGwgdGhlaXIgY2hpbGRyZW4uCgkgKiAKCSAqIEByZXR1cm4gYSBsaXN0IG9mIElNb2R1bGVbXXMKCSAqLwoJcHJvdGVjdGVkIGZpbmFsIExpc3QgZ2V0QWxsTW9kdWxlcygpIHsKCQlyZXR1cm4gc2VydmVyLmdldEFsbE1vZHVsZXMoKTsKCX0KCgkvKioKCSAqIFBlcmZvcm0gKGV4ZWN1dGUpIGFsbCB0aGUgZ2l2ZW4gdGFza3MuCgkgKiAKCSAqIEBwYXJhbSB0YXNrcyBhbiBhcnJheSBvZiB0YXNrcwoJICogQHBhcmFtIG1vbml0b3IgYSBwcm9ncmVzcyBtb25pdG9yLCBvciA8Y29kZT5udWxsPC9jb2RlPiBpZiBwcm9ncmVzcwoJICogICAgcmVwb3J0aW5nIGFuZCBjYW5jZWxsYXRpb24gYXJlIG5vdCBkZXNpcmVkCgkgKiBAcmV0dXJuIHRoZSBzdGF0dXMKCSAqLwoJcHJvdGVjdGVkIElTdGF0dXMgcGVyZm9ybVRhc2tzKFB1Ymxpc2hPcGVyYXRpb25bXSB0YXNrcywgSVByb2dyZXNzTW9uaXRvciBtb25pdG9yKSB7CgkJaW50IHNpemUgPSB0YXNrcy5sZW5ndGg7CgkJVHJhY2UudHJhY2UoVHJhY2UuRklORVNULCAiUGVyZm9ybWluZyB0YXNrczogIiArIHNpemUpOwoJCQoJCWlmIChzaXplID09IDApCgkJCXJldHVybiBudWxsOwoJCQoJCVN0YXR1cyBtdWx0aSA9IG5ldyBNdWx0aVN0YXR1cyhTZXJ2ZXJQbHVnaW4uUExVR0lOX0lELCAwLCBNZXNzYWdlcy50YXNrUGVyZm9ybWluZywgbnVsbCk7CgoJCWZvciAoaW50IGkgPSAwOyBpIDwgc2l6ZTsgaSsrKSB7CgkJCVB1Ymxpc2hPcGVyYXRpb24gdGFzayA9IHRhc2tzW2ldOwoJCQltb25pdG9yLnN1YlRhc2soTkxTLmJpbmQoTWVzc2FnZXMudGFza1BlcmZvcm1pbmcsIHRhc2sudG9TdHJpbmcoKSkpOwoJCQl0cnkgewoJCQkJdGFzay5leGVjdXRlKFByb2dyZXNzVXRpbC5nZXRTdWJNb25pdG9yRm9yKG1vbml0b3IsIDUwMCksIG51bGwpOwoJCQl9IGNhdGNoIChDb3JlRXhjZXB0aW9uIGNlKSB7CgkJCQlUcmFjZS50cmFjZShUcmFjZS5TRVZFUkUsICJUYXNrIGZhaWxlZCIsIGNlKTsKCQkJfQoJCQlpZiAobW9uaXRvci5pc0NhbmNlbGVkKCkpCgkJCQlyZXR1cm4gbXVsdGk7CgkJfQoJCQoJCXJldHVybiBtdWx0aTsKCX0KfQ==