LyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogQ29weXJpZ2h0IChjKSAyMDA1IElCTSBDb3Jwb3JhdGlvbiBhbmQgb3RoZXJzLgogKiBBbGwgcmlnaHRzIHJlc2VydmVkLiBUaGlzIHByb2dyYW0gYW5kIHRoZSBhY2NvbXBhbnlpbmcgbWF0ZXJpYWxzCiAqIGFyZSBtYWRlIGF2YWlsYWJsZSB1bmRlciB0aGUgdGVybXMgb2YgdGhlIEVjbGlwc2UgUHVibGljIExpY2Vuc2UgdjEuMAogKiB3aGljaCBhY2NvbXBhbmllcyB0aGlzIGRpc3RyaWJ1dGlvbiwgYW5kIGlzIGF2YWlsYWJsZSBhdAogKiBodHRwOi8vd3d3LmVjbGlwc2Uub3JnL2xlZ2FsL2VwbC12MTAuaHRtbAqgKiAKICogQ29udHJpYnV0b3JzOgogKiAgICAgSUJNIENvcnBvcmF0aW9uIC0gSW5pdGlhbCBBUEkgYW5kIGltcGxlbWVudGF0aW9uCiAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwpwYWNrYWdlIG9yZy5lY2xpcHNlLndzdC5zZXJ2ZXIuY29yZS5tb2RlbDsKCmltcG9ydCBqYXZhLnV0aWwuQXJyYXlMaXN0OwppbXBvcnQgamF2YS51dGlsLkl0ZXJhdG9yOwppbXBvcnQgamF2YS51dGlsLkxpc3Q7CmltcG9ydCBvcmcuZWNsaXBzZS5jb3JlLnJ1bnRpbWUuKjsKaW1wb3J0IG9yZy5lY2xpcHNlLmRlYnVnLmNvcmUuSUxhdW5jaENvbmZpZ3VyYXRpb25Xb3JraW5nQ29weTsKaW1wb3J0IG9yZy5lY2xpcHNlLm9zZ2kudXRpbC5OTFM7CmltcG9ydCBvcmcuZWNsaXBzZS53c3Quc2VydmVyLmNvcmUuSU1vZHVsZTsKaW1wb3J0IG9yZy5lY2xpcHNlLndzdC5zZXJ2ZXIuY29yZS5JU2VydmVyOwppbXBvcnQgb3JnLmVjbGlwc2Uud3N0LnNlcnZlci5jb3JlLmludGVybmFsLk1lc3NhZ2VzOwppbXBvcnQgb3JnLmVjbGlwc2Uud3N0LnNlcnZlci5jb3JlLmludGVybmFsLlByb2dyZXNzVXRpbDsKaW1wb3J0IG9yZy5lY2xpcHNlLndzdC5zZXJ2ZXIuY29yZS5pbnRlcm5hbC5TZXJ2ZXI7CmltcG9ydCBvcmcuZWNsaXBzZS53c3Quc2VydmVyLmNvcmUuaW50ZXJuYWwuU2VydmVyUGx1Z2luOwppbXBvcnQgb3JnLmVjbGlwc2Uud3N0LnNlcnZlci5jb3JlLmludGVybmFsLlRyYWNlOwovKioKICogQSBzZXJ2ZXIgZGVsZWdhdGUgcHJvdmlkZXMgdGhlIGltcGxlbWVudGF0aW9uIGZvciB2YXJpb3VzIAogKiBnZW5lcmljIGFuZCBzZXJ2ZXItdHlwZS1zcGVjaWZpYyBvcGVyYXRpb25zIGZvciBhIHNwZWNpZmljIHR5cGUgb2Ygc2VydmVyLgogKiBBIHNlcnZlciBkZWxlZ2F0ZSBpcyBzcGVjaWZpZWQgYnkgdGhlCiAqIDxjb2RlPmNsYXNzPC9jb2RlPiBhdHRyaWJ1dGUgb2YgYSA8Y29kZT5zZXJ2ZXJUeXBlczwvY29kZT4gZXh0ZW5zaW9uLgogKiA8cD4KICogV2hlbiB0aGUgc2VydmVyIGluc3RhbmNlIG5lZWRzIHRvIGJlIGdpdmVuIGEgZGVsZWdhdGUsIHRoZSBkZWxlZ2F0ZSBjbGFzcwogKiBzcGVjaWZpZWQgZm9yIHRoZSBzZXJ2ZXIgdHlwZSBpcyBpbnN0YW50aWF0ZWQgd2l0aCBhIDAtYXJndW1lbnQgY29uc3RydWN0b3IKICogYW5kIHByaW1lZCB3aXRoIDxjb2RlPmRlbGVnYXRlLmluaXRpYWxpemUoKChJU2VydmVyU3RhdGUpc2VydmVyKTwvY29kZT4sIAogKiB3aGljaCBpdCBpcyBleHBlY3RlZCB0byBoYW5nIG9uIHRvLiBMYXRlciwgd2hlbgogKiA8Y29kZT5kZWxlZ2F0ZS5kaXNwb3NlKCk8L2NvZGU+IGlzIGNhbGxlZCBhcyB0aGUgc2VydmVyIGluc3RhbmNlIGlzCiAqIGJlaW5nIGRpc2NhcmRlZCwgdGhlIGRlbGVnYXRlIGlzIGV4cGVjdGVkIHRvIGxldCBnbyBvZiB0aGUgc2VydmVyIGluc3RhbmNlLgogKiA8L3A+CiAqIDxwPgogKiBTZXJ2ZXIgZGVsZWdhdGVzIG1heSBrZWVwIHN0YXRlIGluIGluc3RhbmNlIGZpZWxkcywgYnV0IHRoYXQgc3RhdGUgaXMKICogdHJhbnNpZW50IGFuZCB3aWxsIG5vdCBiZSBwZXJzaXN0ZWQgYWNyb3NzIHdvcmtiZW5jaCBzZXNzaW9ucy4KICogPC9wPgogKiA8cD4KICogVGhpcyBhYnN0cmFjdCBjbGFzcyBpcyBpbnRlbmRlZCB0byBiZSBleHRlbmRlZCBvbmx5IGJ5IGNsaWVudHMKICogdG8gZXh0ZW5kIHRoZSA8Y29kZT5zZXJ2ZXJUeXBlczwvY29kZT4gZXh0ZW5zaW9uIHBvaW50LgogKiA8L3A+CiAqIAogKiBAc2VlIG9yZy5lY2xpcHNlLndzdC5zZXJ2ZXIuY29yZS5JU2VydmVyCiAqIEBzZWUgb3JnLmVjbGlwc2Uud3N0LnNlcnZlci5jb3JlLklTZXJ2ZXJXb3JraW5nQ29weQogKiBAc2luY2UgMS4wCiAqLwpwdWJsaWMgYWJzdHJhY3QgY2xhc3MgU2VydmVyQmVoYXZpb3VyRGVsZWdhdGUgewoJcHJpdmF0ZSBTZXJ2ZXIgc2VydmVyOwoKCS8qKgoJICogUHVibGlzaCBraW5kIGNvbnN0YW50ICh2YWx1ZSAwKSBmb3Igbm8gY2hhbmdlLgoJICogCgkgKiBAc2VlICNwdWJsaXNoTW9kdWxlKGludCwgaW50LCBJTW9kdWxlW10sIElQcm9ncmVzc01vbml0b3IpCgkgKi8KCXB1YmxpYyBzdGF0aWMgZmluYWwgaW50IE5PX0NIQU5HRSA9IDA7CgoJLyoqCgkgKiBQdWJsaXNoIGtpbmQgY29uc3RhbnQgKHZhbHVlIDEpIGZvciBhZGRlZCByZXNvdXJjZXMuCgkgKiAKCSAqIEBzZWUgI3B1Ymxpc2hNb2R1bGUoaW50LCBpbnQsIElNb2R1bGVbXSwgSVByb2dyZXNzTW9uaXRvcikKCSAqLwoJcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgQURERUQgPSAxOwoKCS8qKgoJICogUHVibGlzaCBraW5kIGNvbnN0YW50ICh2YWx1ZSAyKSBmb3IgY2hhbmdlZCByZXNvdXJjZXMuCgkgKiAKCSAqIEBzZWUgI3B1Ymxpc2hNb2R1bGUoaW50LCBpbnQsIElNb2R1bGVbXSwgSVByb2dyZXNzTW9uaXRvcikKCSAqLwoJcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgQ0hBTkdFRCA9IDI7CgoJLyoqCgkgKiBQdWJsaXNoIGtpbmQgY29uc3RhbnQgKHZhbHVlIDMpIGZvciByZW1vdmVkIHJlc291cmNlcy4KCSAqIAoJICogQHNlZSAjcHVibGlzaE1vZHVsZShpbnQsIGludCwgSU1vZHVsZVtdLCBJUHJvZ3Jlc3NNb25pdG9yKQoJICovCglwdWJsaWMgc3RhdGljIGZpbmFsIGludCBSRU1PVkVEID0gMzsKCgkvKioKCSAqIERlbGVnYXRlcyBtdXN0IGhhdmUgYSBwdWJsaWMgMC1hcmcgY29uc3RydWN0b3IuCgkgKi8KCXB1YmxpYyBTZXJ2ZXJCZWhhdmlvdXJEZWxlZ2F0ZSgpIHsKCQkvLyBkbyBub3RoaW5nCgl9CgoJLyoqCgkgKiBJbml0aWFsaXplcyB0aGlzIHNlcnZlciBkZWxlZ2F0ZSB3aXRoIGl0cyBsaWZlLWxvbmcgc2VydmVyIGluc3RhbmNlLgoJICogPHA+CgkgKiBUaGlzIG1ldGhvZCBpcyBjYWxsZWQgYnkgdGhlIHNlcnZlciBjb3JlIGZyYW1ld29yay4KCSAqIENsaWVudHMgc2hvdWxkIG5ldmVyIGNhbGwgdGhpcyBtZXRob2QuCgkgKiA8L3A+CgkgKiAKCSAqIEBwYXJhbSBuZXdTZXJ2ZXIgdGhlIHNlcnZlciBpbnN0YW5jZQoJICogQHBhcmFtIG1vbml0b3IgYSBwcm9ncmVzcyBtb25pdG9yLCBvciA8Y29kZT5udWxsPC9jb2RlPiBpZiBwcm9ncmVzcwoJICogICAgcmVwb3J0aW5nIGFuZCBjYW5jZWxsYXRpb24gYXJlIG5vdCBkZXNpcmVkCgkgKi8KCWZpbmFsIHZvaWQgaW5pdGlhbGl6ZShTZXJ2ZXIgbmV3U2VydmVyLCBJUHJvZ3Jlc3NNb25pdG9yIG1vbml0b3IpIHsKCQlzZXJ2ZXIgPSBuZXdTZXJ2ZXI7CgkJaW5pdGlhbGl6ZShtb25pdG9yKTsKCX0KCgkvKioKCSAqIEluaXRpYWxpemVzIHRoaXMgc2VydmVyIGRlbGVnYXRlLiBUaGlzIG1ldGhvZCBnaXZlcyBkZWxlZ2F0ZXMgYSBjaGFuY2UKCSAqIHRvIGRvIHRoZWlyIG93biBpbml0aWFsaXphdGlvbi4KCSAqIDxwPgoJICogSWYgdGhlIHNlcnZlciBzdGF0ZSBpcyBpbml0aWFsbHkgdW5rbm93biwgdGhpcyBtZXRob2Qgc2hvdWxkIGF0dGVtcHQKCSAqIHRvIGNvbm5lY3QgdG8gdGhlIHNlcnZlciBhbmQgdXBkYXRlIHRoZSBzdGF0ZS4gT24gc2VydmVycyB3aGVyZSB0aGUKCSAqIHN0YXRlIG1heSBjaGFuZ2UsIHRoaXMgaXMgYWxzbyBhbiBleGNlbGxlbnQgcGxhY2UgdG8gY3JlYXRlIGEgYmFja2dyb3VuZAoJICogdGhyZWFkIHRoYXQgd2lsbCBjb25zdGFudGx5IHBpbmcgdGhlIHNlcnZlciAob3IgaGF2ZSBhIGxpc3RlbmVyKSB0bwoJICogdXBkYXRlIHRoZSBzZXJ2ZXIgc3RhdGUgYXMgY2hhbmdlcyBvY2N1ci4KCSAqIDwvcD4KCSAqIDxwPgoJICogVGhpcyBtZXRob2QgaXMgY2FsbGVkIGJ5IHRoZSBzZXJ2ZXIgY29yZSBmcmFtZXdvcmsuCgkgKiBDbGllbnRzIHNob3VsZCBuZXZlciBjYWxsIHRoaXMgbWV0aG9kLgoJICogPC9wPgoJICogCgkgKiBAcGFyYW0gbW9uaXRvciBhIHByb2dyZXNzIG1vbml0b3IsIG9yIDxjb2RlPm51bGw8L2NvZGU+IGlmIHByb2dyZXNzCgkgKiAgICByZXBvcnRpbmcgYW5kIGNhbmNlbGxhdGlvbiBhcmUgbm90IGRlc2lyZWQKCSAqLwoJcHJvdGVjdGVkIHZvaWQgaW5pdGlhbGl6ZShJUHJvZ3Jlc3NNb25pdG9yIG1vbml0b3IpIHsKCQkvLyBkbyBub3RoaW5nCgl9CgoJLyoqCgkgKiBSZXR1cm5zIHRoZSBzZXJ2ZXIgdGhhdCB0aGlzIHNlcnZlciBkZWxlZ2F0ZSBjb3JyZXNwb25kcyB0by4KCSAqIAoJICogQHJldHVybiB0aGUgc2VydmVyCgkgKi8KCXB1YmxpYyBmaW5hbCBJU2VydmVyIGdldFNlcnZlcigpIHsKCQlyZXR1cm4gc2VydmVyOwoJfQoKCS8qKgoJICogU2V0cyB0aGUgY3VycmVudCBzdGF0ZSBvZiB0aGlzIHNlcnZlci4KCSAqCgkgKiBAcGFyYW0gc3RhdGUgdGhlIGN1cnJlbnQgc3RhdGUgb2YgdGhlIHNlcnZlciwgb25lIG9mIHRoZSBzdGF0ZQoJICogICAgY29uc3RhbnRzIGRlZmluZWQgYnkge0BsaW5rIElTZXJ2ZXJ9CgkgKiBAc2VlIElTZXJ2ZXIjZ2V0U2VydmVyU3RhdGUoKQoJICovCglwcm90ZWN0ZWQgZmluYWwgdm9pZCBzZXRTZXJ2ZXJTdGF0ZShpbnQgc3RhdGUpIHsKCQlzZXJ2ZXIuc2V0U2VydmVyU3RhdGUoc3RhdGUpOwoJfQoKCS8qKgoJICogU2V0cyB0aGUgSUxhdW5jaE1hbmFnZXIgbW9kZSB0aGF0IHRoZSBzZXJ2ZXIgaXMgcnVubmluZyBpbi4gVGhlIHNlcnZlcgoJICogaW1wbGVtZW50YXRpb24gd2lsbCBhdXRvbWF0aWNhbGx5IHJldHVybiA8Y29kZT5udWxsPC9jb2RlPiB0byBjbGllbnRzCgkgKiB3aGVuIHRoZSBzZXJ2ZXIgaXMgc3RvcHBlZCwgc28geW91IG9ubHkgbmVlZCB0byB1cGRhdGUgdGhlIG1vZGUgd2hlbgoJICogaXQgY2hhbmdlcy4KCSAqIAoJICogQHBhcmFtIG1vZGUgdGhlIG1vZGUgaW4gd2hpY2ggYSBzZXJ2ZXIgaXMgcnVubmluZywgb25lIG9mIHRoZSBtb2RlIGNvbnN0YW50cwoJICogICAgZGVmaW5lZCBieSB7QGxpbmsgb3JnLmVjbGlwc2UuZGVidWcuY29yZS5JTGF1bmNoTWFuYWdlcn0KCSAqLwoJcHJvdGVjdGVkIGZpbmFsIHZvaWQgc2V0TW9kZShTdHJpbmcgbW9kZSkgewoJCXNlcnZlci5zZXRNb2RlKG1vZGUpOwoJfQoKCS8qKgoJICogU2V0cyB0aGUgc2VydmVyIHJlc3RhcnQgc3RhdGUuCgkgKgoJICogQHBhcmFtIHN0YXRlIDxjb2RlPnRydWU8L2NvZGU+IGlmIHRoZSBzZXJ2ZXIgbmVlZHMgdG8gYmUgcmVzdGFydGVkLAoJICogICAgYW5kIDxjb2RlPmZhbHNlPC9jb2RlPiBvdGhlcndpc2UKCSAqLwoJcHJvdGVjdGVkIGZpbmFsIHZvaWQgc2V0U2VydmVyUmVzdGFydFN0YXRlKGJvb2xlYW4gc3RhdGUpIHsKCQlzZXJ2ZXIuc2V0U2VydmVyUmVzdGFydFN0YXRlKHN0YXRlKTsKCX0KCgkvKioKCSAqIFNldHMgdGhlIHNlcnZlciBwdWJsaXNoIHN0YXRlLgoJICoKCSAqIEBwYXJhbSBzdGF0ZSB0aGUgY3VycmVudCBwdWJsaXNoIHN0YXRlIG9mIHRoZSBzZXJ2ZXIsIG9uZSBvZiB0aGUKCSAqICAgIHB1Ymxpc2ggY29uc3RhbnRzIGRlZmluZWQgYnkge0BsaW5rIElTZXJ2ZXJ9CgkgKi8KCXByb3RlY3RlZCBmaW5hbCB2b2lkIHNldFNlcnZlclB1Ymxpc2hTdGF0ZShpbnQgc3RhdGUpIHsKCQlzZXJ2ZXIuc2V0U2VydmVyUHVibGlzaFN0YXRlKHN0YXRlKTsKCX0KCgkvKioKCSAqIEhvb2sgdG8gZmlyZSBhbiBldmVudCB3aGVuIGEgbW9kdWxlIHN0YXRlIGNoYW5nZXMuCgkgKiAKCSAqIEBwYXJhbSBtb2R1bGUgdGhlIG1vZHVsZQoJICogQHBhcmFtIHN0YXRlIHRoZSBjdXJyZW50IHN0YXRlIG9mIHRoZSBtb2R1bGUsIG9uZSBvZiB0aGUgc3RhdGUKCSAqICAgIGNvbnN0YW50cyBkZWZpbmVkIGJ5IHtAbGluayBJU2VydmVyfQoJICovCglwcm90ZWN0ZWQgZmluYWwgdm9pZCBzZXRNb2R1bGVTdGF0ZShJTW9kdWxlW10gbW9kdWxlLCBpbnQgc3RhdGUpIHsKCQlzZXJ2ZXIuc2V0TW9kdWxlU3RhdGUobW9kdWxlLCBzdGF0ZSk7Cgl9CgoJLyoqCgkgKiBTZXRzIHRoZSBtb2R1bGUgcHVibGlzaCBzdGF0ZS4KCSAqCgkgKiBAcGFyYW0gbW9kdWxlIHRoZSBtb2R1bGUKCSAqIEBwYXJhbSBzdGF0ZSB0aGUgY3VycmVudCBwdWJsaXNoIHN0YXRlIG9mIHRoZSBtb2R1bGUsIG9uZSBvZiB0aGUKCSAqICAgIHB1Ymxpc2ggY29uc3RhbnRzIGRlZmluZWQgYnkge0BsaW5rIElTZXJ2ZXJ9CgkgKi8KCXByb3RlY3RlZCBmaW5hbCB2b2lkIHNldE1vZHVsZVB1Ymxpc2hTdGF0ZShJTW9kdWxlW10gbW9kdWxlLCBpbnQgc3RhdGUpIHsKCQlzZXJ2ZXIuc2V0TW9kdWxlUHVibGlzaFN0YXRlKG1vZHVsZSwgc3RhdGUpOwoJfQoKCS8qKgoJICogU2V0cyB0aGUgbW9kdWxlIHJlc3RhcnQgc3RhdGUuCgkgKgoJICogQHBhcmFtIG1vZHVsZSB0aGUgbW9kdWxlCgkgKiBAcGFyYW0gc3RhdGUgPGNvZGU+dHJ1ZTwvY29kZT4gaWYgdGhlIG1vZHVsZSBuZWVkcyB0byBiZSByZXN0YXJ0ZWQsCgkgKiAgICBhbmQgPGNvZGU+ZmFsc2U8L2NvZGU+IG90aGVyd2lzZQoJICovCglwcm90ZWN0ZWQgZmluYWwgdm9pZCBzZXRNb2R1bGVSZXN0YXJ0U3RhdGUoSU1vZHVsZVtdIG1vZHVsZSwgYm9vbGVhbiBzdGF0ZSkgewoJCXNlcnZlci5zZXRNb2R1bGVSZXN0YXJ0U3RhdGUobW9kdWxlLCBzdGF0ZSk7Cgl9CgoJLyoqCgkgKiBEaXNwb3NlcyBvZiB0aGlzIHNlcnZlciBkZWxlZ2F0ZS4KCSAqIDxwPgoJICogVGhpcyBtZXRob2QgaXMgY2FsbGVkIGJ5IHRoZSB3ZWIgc2VydmVyIGNvcmUgZnJhbWV3b3JrLgoJICogQ2xpZW50cyBzaG91bGQgbmV2ZXIgY2FsbCB0aGlzIG1ldGhvZC4KCSAqIDwvcD4KCSAqIDxwPgoJICogSW1wbGVtZW50YXRpb25zIGFyZSBleHBlY3RlZCB0byBsZXQgZ28gb2YgdGhlIGRlbGVnYXRlJ3MgcmVmZXJlbmNlCgkgKiB0byB0aGUgc2VydmVyLCBkZXJlZ2lzdGVyIGxpc3RlbmVycywgZXRjLgoJICogPC9wPgoJICovCglwdWJsaWMgdm9pZCBkaXNwb3NlKCkgewoJCS8vIGRvIG5vdGhpbmcKCX0KCgkvKioKCSAqIE1ldGhvZHMgY2FsbGVkIHRvIG5vdGlmeSB0aGF0IHB1Ymxpc2hpbmcgaXMgYWJvdXQgdG8gYmVnaW4uCgkgKiBUaGlzIGFsbG93cyB0aGUgc2VydmVyIHRvIG9wZW4gYSBjb25uZWN0aW9uIHRvIHRoZSBzZXJ2ZXIKCSAqIG9yIGdldCBhbnkgZ2xvYmFsIGluZm9ybWF0aW9uIHJlYWR5LgoJICogPHA+CgkgKiBUaGlzIG1ldGhvZCBpcyBjYWxsZWQgYnkgdGhlIHNlcnZlciBjb3JlIGZyYW1ld29yaywKCSAqIGluIHJlc3BvbnNlIHRvIGEgY2FsbCB0byA8Y29kZT5JU2VydmVyLnB1Ymxpc2goKTwvY29kZT4uCgkgKiBDbGllbnRzIHNob3VsZCBuZXZlciBjYWxsIHRoaXMgbWV0aG9kLgoJICogPC9wPgoJICoKCSAqIEBwYXJhbSBtb25pdG9yIGEgcHJvZ3Jlc3MgbW9uaXRvciwgb3IgPGNvZGU+bnVsbDwvY29kZT4gaWYgcHJvZ3Jlc3MKCSAqICAgIHJlcG9ydGluZyBhbmQgY2FuY2VsbGF0aW9uIGFyZSBub3QgZGVzaXJlZAoJICogQHRocm93cyBDb3JlRXhjZXB0aW9uIGlmIHRoZXJlIGlzIGEgcHJvYmxlbSBzdGFydGluZyB0aGUgcHVibGlzaAoJICovCglwcm90ZWN0ZWQgdm9pZCBwdWJsaXNoU3RhcnQoSVByb2dyZXNzTW9uaXRvciBtb25pdG9yKSB0aHJvd3MgQ29yZUV4Y2VwdGlvbiB7CgkJLy8gZG8gbm90aGluZwoJfQoKCS8qKgoJICogUHVibGlzaCB0aGUgc2VydmVyLgoJICogPHA+CgkgKiBUaGlzIG1ldGhvZCBpcyBjYWxsZWQgYnkgdGhlIHNlcnZlciBjb3JlIGZyYW1ld29yaywKCSAqIGluIHJlc3BvbnNlIHRvIGEgY2FsbCB0byA8Y29kZT5JU2VydmVyLnB1Ymxpc2goKTwvY29kZT4uCgkgKiBDbGllbnRzIHNob3VsZCBuZXZlciBjYWxsIHRoaXMgbWV0aG9kLgoJICogPC9wPgoJICogCgkgKiBAcGFyYW0ga2luZCBvbmUgb2YgdGhlIElTZXJ2ZXIuUFVCTElTSF9YWCBjb25zdGFudHMuIFZhbGlkIHZhbHVlcyBhcmUKCSAqICAgIDx1bD4KCSAqICAgIDxsaT48Y29kZT5QVUJMU0lIX0ZVTEw8L2NvZGU+LSBpbmRpY2F0ZXMgYSBmdWxsIHB1Ymxpc2guPC9saT4KCSAqICAgIDxsaT48Y29kZT5QVUJMSVNIX0lOQ1JFTUVOVEFMPC9jb2RlPi0gaW5kaWNhdGVzIGEgaW5jcmVtZW50YWwgcHVibGlzaC4KCSAqICAgIDxsaT48Y29kZT5QVUJMU0lIX0FVVE88L2NvZGU+LSBpbmRpY2F0ZXMgYW4gYXV0b21hdGljIGluY3JlbWVudGFsIHB1Ymxpc2guPC9saT4KCSAqICAgIDxsaT48Y29kZT5QVUJMSVNIX0NMRUFOPC9jb2RlPi0gaW5kaWNhdGVzIGEgY2xlYW4gcmVxdWVzdC4gQ2xlYW4gdGhyb3dzCgkgKiAgICAgIG91dCBhbGwgc3RhdGUgYW5kIGNsZWFucyB1cCB0aGUgbW9kdWxlIG9uIHRoZSBzZXJ2ZXIgYmVmb3JlIGRvaW5nIGEKCSAqICAgICAgZnVsbCBwdWJsaXNoLgoJICogICAgPC91bD4KCSAqIEBwYXJhbSBtb25pdG9yIGEgcHJvZ3Jlc3MgbW9uaXRvciwgb3IgPGNvZGU+bnVsbDwvY29kZT4gaWYgcHJvZ3Jlc3MKCSAqICAgIHJlcG9ydGluZyBhbmQgY2FuY2VsbGF0aW9uIGFyZSBub3QgZGVzaXJlZAoJICogQHRocm93cyBDb3JlRXhjZXB0aW9uIGlmIHRoZXJlIGlzIGEgcHJvYmxlbSBwdWJsaXNoaW5nIHRoZSBzZXJ2ZXIKCSAqLwoJcHJvdGVjdGVkIHZvaWQgcHVibGlzaFNlcnZlcihpbnQga2luZCwgSVByb2dyZXNzTW9uaXRvciBtb25pdG9yKSB0aHJvd3MgQ29yZUV4Y2VwdGlvbiB7CgkJLy8gZG8gbm90aGluZwoJfQoKCS8qKgoJICogUHVibGlzaCBhIHNpbmdsZSBtb2R1bGUgdG8gdGhlIHNlcnZlci4KCSAqIDxwPgoJICogVGhpcyBtZXRob2QgaXMgY2FsbGVkIGJ5IHRoZSBzZXJ2ZXIgY29yZSBmcmFtZXdvcmssCgkgKiBpbiByZXNwb25zZSB0byBhIGNhbGwgdG8gPGNvZGU+SVNlcnZlci5wdWJsaXNoKCk8L2NvZGU+LgoJICogQ2xpZW50cyBzaG91bGQgbmV2ZXIgY2FsbCB0aGlzIG1ldGhvZCBkaXJlY3RseS4KCSAqIDwvcD4KCSAqIDxwPgoJICogSWYgdGhlIGRlbHRhS2luZCBpcyBJU2VydmVyLlJFTU9WRUQsIHRoZSBtb2R1bGUgbWF5IGhhdmUgYmVlbiBjb21wbGV0ZWx5CgkgKiBkZWxldGVkIGFuZCBkb2VzIG5vdCBleGlzdCBhbnltb3JlLiBJbiB0aGlzIGNhc2UsIGEgZHVtbXkgbW9kdWxlICh3aXRoIHRoZQoJICogY29ycmVjdCBpZCkgd2lsbCBiZSBwYXNzZWQgdG8gdGhpcyBtZXRob2QuCgkgKiA8L3A+CgkgKiAKCSAqIEBwYXJhbSBraW5kIG9uZSBvZiB0aGUgSVNlcnZlci5QVUJMSVNIX1hYIGNvbnN0YW50cy4gVmFsaWQgdmFsdWVzIGFyZToKCSAqICAgIDx1bD4KCSAqICAgIDxsaT48Y29kZT5QVUJMU0lIX0ZVTEw8L2NvZGU+LSBpbmRpY2F0ZXMgYSBmdWxsIHB1Ymxpc2guPC9saT4KCSAqICAgIDxsaT48Y29kZT5QVUJMSVNIX0lOQ1JFTUVOVEFMPC9jb2RlPi0gaW5kaWNhdGVzIGEgaW5jcmVtZW50YWwgcHVibGlzaC4KCSAqICAgIDxsaT48Y29kZT5QVUJMU0lIX0FVVE88L2NvZGU+LSBpbmRpY2F0ZXMgYW4gYXV0b21hdGljIGluY3JlbWVudGFsIHB1Ymxpc2guPC9saT4KCSAqICAgIDxsaT48Y29kZT5QVUJMSVNIX0NMRUFOPC9jb2RlPi0gaW5kaWNhdGVzIGEgY2xlYW4gcmVxdWVzdC4gQ2xlYW4gdGhyb3dzCgkgKiAgICAgIG91dCBhbGwgc3RhdGUgYW5kIGNsZWFucyB1cCB0aGUgbW9kdWxlIG9uIHRoZSBzZXJ2ZXIgYmVmb3JlIGRvaW5nIGEKCSAqICAgICAgZnVsbCBwdWJsaXNoLgoJICogICAgPC91bD4KCSAqIEBwYXJhbSBtb2R1bGUgdGhlIG1vZHVsZSB0byBwdWJsaXNoCgkgKiBAcGFyYW0gZGVsdGFLaW5kIG9uZSBvZiB0aGUgSVNlcnZlciBwdWJsaXNoIGNoYW5nZSBjb25zdGFudHMuIFZhbGlkIHZhbHVlcyBhcmU6CgkgKiAgICA8dWw+CgkgKiAgICA8bGk+PGNvZGU+QURERUQ8L2NvZGU+LSBpbmRpY2F0ZXMgdGhlIG1vZHVsZSBoYXMganVzdCBiZWVuIGFkZGVkIHRvIHRoZSBzZXJ2ZXIKCSAqICAgICAgYW5kIHRoaXMgaXMgdGhlIGZpcnN0IHB1Ymxpc2guCgkgKiAgICA8bGk+PGNvZGU+Tk9fQ0hBTkdFPC9jb2RlPi0gaW5kaWNhdGVzIHRoYXQgbm90aGluZyBoYXMgY2hhbmdlZCBpbiB0aGUgbW9kdWxlCgkgKiAgICAgIHNpbmNlIHRoZSBsYXN0IHB1Ymxpc2guPC9saT4KCSAqICAgIDxsaT48Y29kZT5DSEFOR0VEPC9jb2RlPi0gaW5kaWNhdGVzIHRoYXQgdGhlIG1vZHVsZSBoYXMgYmVlbiBjaGFuZ2VkIHNpbmNlCgkgKiAgICAgIHRoZSBsYXN0IHB1Ymxpc2guIENhbGwgPGNvZGU+Z2V0UHVibGlzaGVkUmVzb3VyY2VEZWx0YSgpPC9jb2RlPiBmb3IKCSAqICAgICAgZGV0YWlscyBvZiB0aGUgY2hhbmdlLgoJICogICAgPGxpPjxjb2RlPlJFTU9WRUQ8L2NvZGU+LSBpbmRpY2F0ZXMgdGhlIG1vZHVsZSBoYXMgYmVlbiByZW1vdmVkIGFuZCBzaG91bGQgYmUKCSAqICAgICAgcmVtb3ZlZC9jbGVhbmVkIHVwIGZyb20gdGhlIHNlcnZlci4KCSAqICAgIDwvdWw+CgkgKiBAcGFyYW0gbW9uaXRvciBhIHByb2dyZXNzIG1vbml0b3IsIG9yIDxjb2RlPm51bGw8L2NvZGU+IGlmIHByb2dyZXNzCgkgKiAgICByZXBvcnRpbmcgYW5kIGNhbmNlbGxhdGlvbiBhcmUgbm90IGRlc2lyZWQKCSAqIEB0aHJvd3MgQ29yZUV4Y2VwdGlvbiBpZiB0aGVyZSBpcyBhIHByb2JsZW0gcHVibGlzaGluZyB0aGUgbW9kdWxlCgkgKi8KCXByb3RlY3RlZCB2b2lkIHB1Ymxpc2hNb2R1bGUoaW50IGtpbmQsIGludCBkZWx0YUtpbmQsIElNb2R1bGVbXSBtb2R1bGUsIElQcm9ncmVzc01vbml0b3IgbW9uaXRvcikgdGhyb3dzIENvcmVFeGNlcHRpb24gewoJCS8vIGRvIG5vdGhpbmcKCX0KCgkvKioKCSAqIE1ldGhvZHMgY2FsbGVkIHRvIG5vdGlmeSB0aGF0IHB1Ymxpc2hpbmcgaGFzIGZpbmlzaGVkLgoJICogVGhlIHNlcnZlciBjYW4gY2xvc2UgYW55IG9wZW4gY29ubmVjdGlvbnMgdG8gdGhlIHNlcnZlcgoJICogYW5kIGRvIGFueSBjbGVhbnVwIG9wZXJhdGlvbnMuCgkgKiA8cD4KCSAqIFRoaXMgbWV0aG9kIGlzIGNhbGxlZCBieSB0aGUgc2VydmVyIGNvcmUgZnJhbWV3b3JrLAoJICogaW4gcmVzcG9uc2UgdG8gYSBjYWxsIHRvIDxjb2RlPklTZXJ2ZXIucHVibGlzaCgpPC9jb2RlPi4KCSAqIENsaWVudHMgc2hvdWxkIG5ldmVyIGNhbGwgdGhpcyBtZXRob2QuCgkgKiA8L3A+CgkgKgoJICogQHBhcmFtIG1vbml0b3IgYSBwcm9ncmVzcyBtb25pdG9yLCBvciA8Y29kZT5udWxsPC9jb2RlPiBpZiBwcm9ncmVzcwoJICogICAgcmVwb3J0aW5nIGFuZCBjYW5jZWxsYXRpb24gYXJlIG5vdCBkZXNpcmVkCgkgKiBAdGhyb3dzIENvcmVFeGNlcHRpb24gaWYgdGhlcmUgaXMgYSBwcm9ibGVtIHN0b3BwaW5nIHRoZSBwdWJsaXNoCgkgKi8KCXByb3RlY3RlZCB2b2lkIHB1Ymxpc2hGaW5pc2goSVByb2dyZXNzTW9uaXRvciBtb25pdG9yKSB0aHJvd3MgQ29yZUV4Y2VwdGlvbiB7CgkJLy8gZG8gbm90aGluZwoJfQoKCS8qKgoJICogQ29uZmlndXJlIHRoZSBnaXZlbiBsYXVuY2ggY29uZmlndXJhdGlvbiB0byBzdGFydCB0aGlzIHNlcnZlci4gVGhpcyBtZXRob2QgaXMgY2FsbGVkIHdoZW5ldmVyCgkgKiB0aGUgc2VydmVyIGlzIHN0YXJ0ZWQgdG8gZW5zdXJlIHRoYXQgdGhlIGxhdW5jaCBjb25maWd1cmF0aW9uIGlzIGFjY3VyYXRlIGFuZCB1cCB0byBkYXRlLgoJICogVGhpcyBtZXRob2Qgc2hvdWxkIG5vdCBibGluZGx5IHVwZGF0ZSB0aGUgbGF1bmNoIGNvbmZpZ3VyYXRpb24gaW4gY2FzZXMgd2hlcmUgdGhlIHVzZXIgaGFzCgkgKiBhY2Nlc3MgdG8gY2hhbmdlIHRoZSBsYXVuY2ggY29uZmlndXJhdGlvbiBieSBoYW5kLgoJICogCgkgKiBAcGFyYW0gd29ya2luZ0NvcHkgYSBsYXVuY2ggY29uZmlndXJhdGlvbiB3b3JraW5nIGNvcHkKCSAqIEBwYXJhbSBtb25pdG9yIGEgcHJvZ3Jlc3MgbW9uaXRvciwgb3IgPGNvZGU+bnVsbDwvY29kZT4gaWYgcHJvZ3Jlc3MKCSAqICAgIHJlcG9ydGluZyBhbmQgY2FuY2VsbGF0aW9uIGFyZSBub3QgZGVzaXJlZAoJICogQHRocm93cyBDb3JlRXhjZXB0aW9uIGlmIHRoZXJlIGlzIGFuIGVycm9yIHNldHRpbmcgdXAgdGhlIGNvbmZpZ3VyYXRpb24KCSAqLwoJcHVibGljIHZvaWQgc2V0dXBMYXVuY2hDb25maWd1cmF0aW9uKElMYXVuY2hDb25maWd1cmF0aW9uV29ya2luZ0NvcHkgd29ya2luZ0NvcHksIElQcm9ncmVzc01vbml0b3IgbW9uaXRvcikgdGhyb3dzIENvcmVFeGNlcHRpb24gewoJCS8vIGRvIG5vdGhpbmcKCX0KCgkvKioKCSAqIFJlc3RhcnQgdGhpcyBzZXJ2ZXIuIFRoZSBzZXJ2ZXIgc2hvdWxkIHVzZSB0aGUgc2VydmVyCgkgKiBsaXN0ZW5lciB0byBub3RpZnkgcHJvZ3Jlc3MuIEl0IG11c3QgdXNlIHRoZSBzYW1lIGRlYnVnCgkgKiBmbGFncyBhcyB3YXMgb3JpZ2luYWxseSBwYXNzZWQgaW50byB0aGUgc3RhcnQoKSBtZXRob2QuCgkgKiAKCSAqIFRoaXMgbWV0aG9kIGlzIHVzZWQgaWYgdGhlcmUgaXMgYSBxdWljay9iZXR0ZXIgd2F5IHRvIHJlc3RhcnQKCSAqIHRoZSBzZXJ2ZXIuIElmIGl0IHRocm93cyBhIENvcmVFeGNlcHRpb24sIHRoZSBub3JtYWwgc3RvcC9zdGFydAoJICogYWN0aW9ucyB3aWxsIGJlIHVzZWQuCgkgKiAKCSAqIEBwYXJhbSBsYXVuY2hNb2RlIHRoZSBtb2RlIHRvIHJlc3RhcnQgaW4sIG9uZSBvZiB0aGUgbW9kZSBjb25zdGFudHMKCSAqICAgIGRlZmluZWQgYnkge0BsaW5rIG9yZy5lY2xpcHNlLmRlYnVnLmNvcmUuSUxhdW5jaE1hbmFnZXJ9CgkgKiBAdGhyb3dzIENvcmVFeGNlcHRpb24gaWYgdGhlcmUgd2FzIGEgcHJvYmxlbSByZXN0YXJ0aW5nCgkgKi8KCXB1YmxpYyB2b2lkIHJlc3RhcnQoU3RyaW5nIGxhdW5jaE1vZGUpIHRocm93cyBDb3JlRXhjZXB0aW9uIHsKCQkgdGhyb3cgbmV3IENvcmVFeGNlcHRpb24obmV3IFN0YXR1cyhJU3RhdHVzLkVSUk9SLCBTZXJ2ZXJQbHVnaW4uUExVR0lOX0lELCAwLCAiQ291bGQgbm90IHJlc3RhcnQiLCBudWxsKSk7Cgl9CgoJLyoqCgkgKiBSZXR1cm5zIHdoZXRoZXIgdGhlIGdpdmVuIG1vZHVsZSBjYW4gYmUgcmVzdGFydGVkLgoJICogPHA+CgkgKiBbaXNzdWU6IEl0J3MgdW5jbGVhciB3aGV0aGVyIHRoaXMgb3BlcmF0aW9ucyBpcyBndWFyYW50ZWVkIHRvIGJlIGZhc3QKCSAqIG9yIHdoZXRoZXIgaXQgY291bGQgaW52b2x2ZSBjb21tdW5pY2F0aW9uIHdpdGggYW55IGFjdHVhbAoJICogc2VydmVyLiBJZiBpdCBpcyBub3QgZmFzdCwgdGhlIG1ldGhvZCBzaG91bGQgdGFrZSBhIHByb2dyZXNzCgkgKiBtb25pdG9yLl0KCSAqIDwvcD4KCSAqIAoJICogQHBhcmFtIG1vZHVsZSB0aGUgbW9kdWxlCgkgKiBAcmV0dXJuIDxjb2RlPnRydWU8L2NvZGU+IGlmIHRoZSBnaXZlbiBtb2R1bGUgY2FuIGJlCgkgKiByZXN0YXJ0ZWQsIGFuZCA8Y29kZT5mYWxzZTwvY29kZT4gb3RoZXJ3aXNlIAoJICovCglwdWJsaWMgYm9vbGVhbiBjYW5Db250cm9sTW9kdWxlKElNb2R1bGVbXSBtb2R1bGUpIHsKCQlyZXR1cm4gZmFsc2U7Cgl9CgkKCS8qKgoJICogU3RhcnRzIHRoZSBnaXZlbiBtb2R1bGUgb24gdGhlIHNlcnZlci4gU2VlIHRoZSBzcGVjaWZpY2F0aW9uIG9mIAoJICoge0BsaW5rIElTZXJ2ZXIjc3RhcnRNb2R1bGUoSU1vZHVsZVtdLCBJU2VydmVyLklPcGVyYXRpb25MaXN0ZW5lcil9CgkgKiBmb3IgZnVydGhlciBkZXRhaWxzLiAKCSAqIDxwPgoJICogVGhlIGltcGxlbWVudGF0aW9uIHNob3VsZCB1cGRhdGUgdGhlIG1vZHVsZSBzeW5jIHN0YXRlIGFuZCBmaXJlCgkgKiBhbiBldmVudCBmb3IgdGhlIG1vZHVsZS4KCSAqIDwvcD4KCSAqIDxwPgoJICogVGhpcyBtZXRob2Qgd2lsbCB0aHJvdyBhbiBleGNlcHRpb24gaWYgdGhlIG1vZHVsZSBkb2VzIG5vdCBleGlzdCBvbgoJICogdGhlIHNlcnZlci4KCSAqIDwvcD4KCSAqIDxwPgoJICogW2lzc3VlOiBTaW5jZSB0aGlzIG1ldGhvZCBpcyBhc2N5bmNocm9ub3VzLCBpcyB0aGVyZQoJICogYW55IG5lZWQgZm9yIHRoZSBwcm9ncmVzcyBtb25pdG9yP10KCSAqIDwvcD4KCSAqIAoJICogQHBhcmFtIG1vZHVsZSB0aGUgbW9kdWxlIHRvIGJlIHN0YXJ0ZWQKCSAqIEBwYXJhbSBtb25pdG9yIGEgcHJvZ3Jlc3MgbW9uaXRvciwgb3IgPGNvZGU+bnVsbDwvY29kZT4gaWYgcHJvZ3Jlc3MKCSAqICAgIHJlcG9ydGluZyBhbmQgY2FuY2VsbGF0aW9uIGFyZSBub3QgZGVzaXJlZAoJICogQGV4Y2VwdGlvbiBDb3JlRXhjZXB0aW9uIGlmIGFuIGVycm9yIG9jY3VycyB3aGlsZSB0cnlpbmcgdG8gcmVzdGFydCB0aGUgbW9kdWxlCgkgKi8KCXB1YmxpYyB2b2lkIHN0YXJ0TW9kdWxlKElNb2R1bGVbXSBtb2R1bGUsIElQcm9ncmVzc01vbml0b3IgbW9uaXRvcikgdGhyb3dzIENvcmVFeGNlcHRpb24gewoJCS8vIGRvIG5vdGhpbmcKCX0KCgkvKioKCSAqIFN0b3BzIHRoZSBnaXZlbiBtb2R1bGUgb24gdGhlIHNlcnZlci4gU2VlIHRoZSBzcGVjaWZpY2F0aW9uIG9mIAoJICoge0BsaW5rIElTZXJ2ZXIjc3RvcE1vZHVsZShJTW9kdWxlW10sIElTZXJ2ZXIuSU9wZXJhdGlvbkxpc3RlbmVyKX0KCSAqIGZvciBmdXJ0aGVyIGRldGFpbHMuIAoJICogPHA+CgkgKiBUaGUgaW1wbGVtZW50YXRpb24gc2hvdWxkIHVwZGF0ZSB0aGUgbW9kdWxlIHN5bmMgc3RhdGUgYW5kIGZpcmUKCSAqIGFuIGV2ZW50IGZvciB0aGUgbW9kdWxlLgoJICogPC9wPgoJICogPHA+CgkgKiBUaGlzIG1ldGhvZCB3aWxsIHRocm93IGFuIGV4Y2VwdGlvbiBpZiB0aGUgbW9kdWxlIGRvZXMgbm90IGV4aXN0IG9uCgkgKiB0aGUgc2VydmVyLgoJICogPC9wPgoJICogPHA+CgkgKiBbaXNzdWU6IFNpbmNlIHRoaXMgbWV0aG9kIGlzIGFzY3luY2hyb25vdXMsIGlzIHRoZXJlCgkgKiBhbnkgbmVlZCBmb3IgdGhlIHByb2dyZXNzIG1vbml0b3I/XQoJICogPC9wPgoJICogCgkgKiBAcGFyYW0gbW9kdWxlIHRoZSBtb2R1bGUgdG8gYmUgc3RvcHBlZAoJICogQHBhcmFtIG1vbml0b3IgYSBwcm9ncmVzcyBtb25pdG9yLCBvciA8Y29kZT5udWxsPC9jb2RlPiBpZiBwcm9ncmVzcwoJICogICAgcmVwb3J0aW5nIGFuZCBjYW5jZWxsYXRpb24gYXJlIG5vdCBkZXNpcmVkCgkgKiBAZXhjZXB0aW9uIENvcmVFeGNlcHRpb24gaWYgYW4gZXJyb3Igb2NjdXJzIHdoaWxlIHRyeWluZyB0byByZXN0YXJ0IHRoZSBtb2R1bGUKCSAqLwoJcHVibGljIHZvaWQgc3RvcE1vZHVsZShJTW9kdWxlW10gbW9kdWxlLCBJUHJvZ3Jlc3NNb25pdG9yIG1vbml0b3IpIHRocm93cyBDb3JlRXhjZXB0aW9uIHsKCQkvLyBkbyBub3RoaW5nCgl9CgoJLyoqCgkgKiBTaHV0cyBkb3duIGFuZCBzdG9wcyB0aGlzIHNlcnZlci4gVGhlIHNlcnZlciBzaG91bGQgcmV0dXJuIGZyb20gdGhpcyBtZXRob2QKCSAqIHF1aWNrbHkgYW5kIHVzZSB0aGUgc2VydmVyIGxpc3RlbmVyIHRvIG5vdGlmeSBzaHV0ZG93biBwcm9ncmVzcy4KCSAqIDxwPiAKCSAqIElmIGZvcmNlIGlzIDxjb2RlPmZhbHNlPC9jb2RlPiwgaXQgd2lsbCBhdHRlbXB0IHRvIHN0b3AgdGhlIHNlcnZlcgoJICogbm9ybWFsbHkvZ3JhY2VmdWxseS4gSWYgZm9yY2UgaXMgPGNvZGU+dHJ1ZTwvY29kZT4sIHRoZW4gdGhlIHNlcnZlcgoJICogcHJvY2VzcyB3aWxsIGJlIHRlcm1pbmF0ZWQgYW55IHdheSB0aGF0IGl0IGNhbi4KCSAqIDwvcD4KCSAqIDxwPgoJICogW2lzc3VlOiBUaGVyZSBpcyBubyB3YXkgdG8gY29tbXVuaWNhdGUgZmFpbHVyZSB0byB0aGUKCSAqIGNsaWVudC4gR2l2ZW4gdGhhdCB0aGlzIG9wZXJhdGlvbiBjYW4gZ28gYXdyeSwgdGhlcmUgcHJvYmFibHkKCSAqIHNob3VsZCBiZSBhIG1lY2hhbmlzbSB0aGF0IGFsbG93cyBmYWlsaW5nIGFzeW5jaCBvcGVyYXRpb25zCgkgKiB0byBiZSBkaWFnbm9zZWQuXQoJICogPC9wPgoJICogQHBhcmFtIGZvcmNlIDxjb2RlPnRydWU8L2NvZGU+IHRvIGtpbGwgdGhlIHNlcnZlciwgb3IgPGNvZGU+ZmFsc2U8L2NvZGU+CgkgKiAgICB0byBzdG9wIG5vcm1hbGx5CgkgKi8KCXB1YmxpYyBhYnN0cmFjdCB2b2lkIHN0b3AoYm9vbGVhbiBmb3JjZSk7CgoJLyoqCgkgKiBSZXR1cm5zIHRoZSBtb2R1bGUgcmVzb3VyY2VzIHRoYXQgaGF2ZSBiZWVuIHB1Ymxpc2hlZCB0byB0aGUgc2VydmVyLgoJICogCgkgKiA8cD4KCSAqIElmIHRoZSBtb2R1bGUgaGFzIGp1c3QgYmVlbiBhZGRlZCB0byB0aGUgc2VydmVyLCBhbiBlbXB0eSBsaXN0IHdpbGwKCSAqIGJlIHJldHVybmVkLiBJZiB0aGUgbW9kdWxlIGhhcyBuZXZlciBleGlzdGVkIG9uIHRoZSBzZXJ2ZXIsIGEgQ29yZUV4Y2VwdGlvbgoJICogd2lsbCBiZSB0aHJvd24uCgkgKiA8L3A+CgkgKiAKCSAqIEBwYXJhbSBtb2R1bGUgdGhlIG1vZHVsZQoJICogQHJldHVybiBhbiBhcnJheSBjb250YWluaW5nIHRoZSBwdWJsaXNoZWQgbW9kdWxlIHJlc291cmNlCgkgKi8KCXByb3RlY3RlZCBJTW9kdWxlUmVzb3VyY2VbXSBnZXRQdWJsaXNoZWRSZXNvdXJjZXMoSU1vZHVsZVtdIG1vZHVsZSkgewoJCXJldHVybiBzZXJ2ZXIuZ2V0UHVibGlzaGVkUmVzb3VyY2VzKG1vZHVsZSk7Cgl9CgoJLyoqCgkgKiBSZXR1cm5zIHRoZSBkZWx0YSBvZiB0aGUgY3VycmVudCBtb2R1bGUgcmVzb3VyY2VzIHRoYXQgaGF2ZSBiZWVuCgkgKiBwdWJsaXNoZWQgY29tcGFyZWQgdG8gdGhlIGN1cnJlbnQgc3RhdGUgb2YgdGhlIG1vZHVsZS4KCSAqCgkgKiBAcGFyYW0gbW9kdWxlIHRoZSBtb2R1bGUKCSAqIEByZXR1cm4gYW4gYXJyYXkgY29udGFpbmluZyB0aGUgcHVibGlzaCByZXNvdXJjZSBkZWx0YQoJICovCglwcm90ZWN0ZWQgSU1vZHVsZVJlc291cmNlRGVsdGFbXSBnZXRQdWJsaXNoZWRSZXNvdXJjZURlbHRhKElNb2R1bGVbXSBtb2R1bGUpIHsKCQlyZXR1cm4gc2VydmVyLmdldFB1Ymxpc2hlZFJlc291cmNlRGVsdGEobW9kdWxlKTsKCX0KCgkvKioKCSAqIFJldHVybnMgYSB0ZW1wb3JhcnkgZGlyZWN0b3J5IHRoYXQgdGhlIHJlcXVlc3RvciBjYW4gdXNlCgkgKiB0aHJvdWdob3V0IGl0J3MgbGlmZWN5Y2xlLiBUaGlzIGlzIHByaW1hcnkgdG8gYmUgdXNlZCBieQoJICogc2VydmVycyBmb3Igd29ya2luZyBkaXJlY3Rvcmllcywgc2VydmVyIHNwZWNpZmljCgkgKiBmaWxlcywgZXRjLgoJICogPHA+CgkgKiBUaGlzIG1ldGhvZCBkaXJlY3Rvcnkgd2lsbCByZXR1cm4gdGhlIHNhbWUgZGlyZWN0b3J5IG9uCgkgKiBlYWNoIHVzZSBvZiB0aGUgd29ya2JlbmNoLiBJZiB0aGUgZGlyZWN0b3J5IGlzIG5vdCByZXF1ZXN0ZWQKCSAqIG92ZXIgYSBwZXJpb2Qgb2YgdGltZSwgdGhlIGRpcmVjdG9yeSBtYXkgYmUgZGVsZXRlZCBhbmQgYQoJICogbmV3IG9uZSB3aWxsIGJlIGFzc2lnbmVkIG9uIHRoZSBuZXh0IHJlcXVlc3QuIEZvciB0aGlzCgkgKiByZWFzb24sIGEgc2VydmVyIG1heSB3YW50IHRvIHJlcXVlc3QgdGhlIHRlbXAgZGlyZWN0b3J5IG9uCgkgKiBzdGFydHVwIGlmIGl0IHdhbnRzIHRvIHN0b3JlIGZpbGVzIHRoZXJlLiBJbiBhbnkgY2FzZSwgdGhlCgkgKiBzZXJ2ZXIgc2hvdWxkIGhhdmUgYSBiYWNrdXAgcGxhbiB0byByZWZpbGwgdGhlIGRpcmVjdG9yeQoJICogaW4gY2FzZSBpdCBoYXMgYmVlbiBkZWxldGVkIHNpbmNlIGxhc3QgdXNlLjwvcD4KCSAqCgkgKiBAcmV0dXJuIGEgdGVtcG9yYXJ5IGRpcmVjdG9yeQoJICovCglwcm90ZWN0ZWQgSVBhdGggZ2V0VGVtcERpcmVjdG9yeSgpIHsKCQlyZXR1cm4gc2VydmVyLmdldFRlbXBEaXJlY3RvcnkoKTsKCX0KCgkvKioKCSAqIFNldCBhIGdsb2JhbCBzdGF0dXMgb24gdGhlIHNlcnZlci4KCSAqICAKCSAqIEBwYXJhbSBzdGF0dXMgdGhlIHN0YXR1cwoJICovCglwcm90ZWN0ZWQgZmluYWwgdm9pZCBzZXRTZXJ2ZXJTdGF0dXMoSVN0YXR1cyBzdGF0dXMpIHsKCQlzZXJ2ZXIuc2V0U2VydmVyU3RhdHVzKHN0YXR1cyk7Cgl9CgoJLyoqCgkgKiBTZXQgYSBzdGF0dXMgb24gYSBzcGVjaWZpYyBtb2R1bGUuCgkgKiAKCSAqIEBwYXJhbSBtb2R1bGUgdGhlIG1vZHVsZQoJICogQHBhcmFtIHN0YXR1cyB0aGUgc3RhdHVzCgkgKi8KCXByb3RlY3RlZCBmaW5hbCB2b2lkIHNldE1vZHVsZVN0YXR1cyhJTW9kdWxlW10gbW9kdWxlLCBJU3RhdHVzIHN0YXR1cykgewoJCXNlcnZlci5zZXRNb2R1bGVTdGF0dXMobW9kdWxlLCBzdGF0dXMpOwoJfQoKCS8qKgoJICogUHVibGlzaCB0byB0aGUgc2VydmVyLgoJICogCgkgKiBAcGFyYW0ga2luZCB0aGUgcHVibGlzaCBraW5kCgkgKiBAcGFyYW0gbW9uaXRvciBhIHByb2dyZXNzIG1vbml0b3IsIG9yIDxjb2RlPm51bGw8L2NvZGU+IGlmIHByb2dyZXNzCgkgKiAgICByZXBvcnRpbmcgYW5kIGNhbmNlbGxhdGlvbiBhcmUgbm90IGRlc2lyZWQKCSAqIEByZXR1cm4gdGhlIHB1Ymxpc2ggc3RhdHVzCgkgKi8KCXB1YmxpYyBJU3RhdHVzIHB1Ymxpc2goaW50IGtpbmQsIElQcm9ncmVzc01vbml0b3IgbW9uaXRvcikgewoJCVRyYWNlLnRyYWNlKFRyYWNlLkZJTkVTVCwgIi0tPi0tIFB1Ymxpc2hpbmcgdG8gc2VydmVyOiAiICsgdG9TdHJpbmcoKSArICIgLS0+LS0iKTsKCQkKCQlpZiAoZ2V0U2VydmVyKCkuZ2V0U2VydmVyVHlwZSgpLmhhc1J1bnRpbWUoKSAmJiBnZXRTZXJ2ZXIoKS5nZXRSdW50aW1lKCkgPT0gbnVsbCkKCQkJcmV0dXJuIG5ldyBTdGF0dXMoSVN0YXR1cy5FUlJPUiwgU2VydmVyUGx1Z2luLlBMVUdJTl9JRCwgMCwgTWVzc2FnZXMuZXJyb3JQdWJsaXNoTm9SdW50aW1lLCBudWxsKTsKCQkKCQlmaW5hbCBMaXN0IG1vZHVsZUxpc3QgPSBnZXRBbGxNb2R1bGVzKCk7CgkJZmluYWwgTGlzdCBkZWx0YUtpbmRMaXN0ID0gbmV3IEFycmF5TGlzdCgpOwoJCQoJCUl0ZXJhdG9yIGl0ZXJhdG9yID0gbW9kdWxlTGlzdC5pdGVyYXRvcigpOwoJCXdoaWxlIChpdGVyYXRvci5oYXNOZXh0KCkpIHsKCQkJSU1vZHVsZVtdIG1vZHVsZSA9IChJTW9kdWxlW10pIGl0ZXJhdG9yLm5leHQoKTsKCQkJaWYgKGhhc0JlZW5QdWJsaXNoZWQobW9kdWxlKSkgewoJCQkJaWYgKGdldFB1Ymxpc2hlZFJlc291cmNlRGVsdGEobW9kdWxlKS5sZW5ndGggPT0gMCkKCQkJCQlkZWx0YUtpbmRMaXN0LmFkZChuZXcgSW50ZWdlcihTZXJ2ZXJCZWhhdmlvdXJEZWxlZ2F0ZS5OT19DSEFOR0UpKTsKCQkJCWVsc2UKCQkJCQlkZWx0YUtpbmRMaXN0LmFkZChuZXcgSW50ZWdlcihTZXJ2ZXJCZWhhdmlvdXJEZWxlZ2F0ZS5DSEFOR0VEKSk7CgkJCX0gZWxzZQoJCQkJZGVsdGFLaW5kTGlzdC5hZGQobmV3IEludGVnZXIoU2VydmVyQmVoYXZpb3VyRGVsZWdhdGUuQURERUQpKTsKCQl9CgkJCgkJYWRkUmVtb3ZlZE1vZHVsZXMobW9kdWxlTGlzdCwgZGVsdGFLaW5kTGlzdCk7CgkJCgkJd2hpbGUgKG1vZHVsZUxpc3Quc2l6ZSgpID4gZGVsdGFLaW5kTGlzdC5zaXplKCkpIHsKCQkJZGVsdGFLaW5kTGlzdC5hZGQobmV3IEludGVnZXIoU2VydmVyQmVoYXZpb3VyRGVsZWdhdGUuUkVNT1ZFRCkpOwoJCX0KCQkKCQlQdWJsaXNoT3BlcmF0aW9uW10gdGFza3MgPSBnZXRUYXNrcyhraW5kLCBtb2R1bGVMaXN0LCBkZWx0YUtpbmRMaXN0KTsKCQlpbnQgc2l6ZSA9IDIwMDAgKyAzNTAwICogbW9kdWxlTGlzdC5zaXplKCkgKyA1MDAgKiB0YXNrcy5sZW5ndGg7CgkJCgkJbW9uaXRvciA9IFByb2dyZXNzVXRpbC5nZXRNb25pdG9yRm9yKG1vbml0b3IpOwoJCW1vbml0b3IuYmVnaW5UYXNrKE5MUy5iaW5kKE1lc3NhZ2VzLnB1Ymxpc2hpbmcsIGdldFNlcnZlcigpLmdldE5hbWUoKSksIHNpemUpOwoKCQlNdWx0aVN0YXR1cyB0ZW1wTXVsdGkgPSBuZXcgTXVsdGlTdGF0dXMoU2VydmVyUGx1Z2luLlBMVUdJTl9JRCwgMCwgIiIsIG51bGwpOwoKCQlpZiAobW9uaXRvci5pc0NhbmNlbGVkKCkpCgkJCXJldHVybiBTdGF0dXMuQ0FOQ0VMX1NUQVRVUzsKCQkKCQkvLyBzdGFydCBwdWJsaXNoaW5nCgkJVHJhY2UudHJhY2UoVHJhY2UuRklORVNULCAiQ2FsbGluZyBwdWJsaXNoU3RhcnQoKSIpOwoJCXRyeSB7CgkJCXB1Ymxpc2hTdGFydChQcm9ncmVzc1V0aWwuZ2V0U3ViTW9uaXRvckZvcihtb25pdG9yLCAxMDAwKSk7CgkJfSBjYXRjaCAoQ29yZUV4Y2VwdGlvbiBjZSkgewoJCQlUcmFjZS50cmFjZShUcmFjZS5JTkZPLCAiQ29yZUV4Y2VwdGlvbiBwdWJsaXNoaW5nIHRvICIgKyB0b1N0cmluZygpLCBjZSk7CgkJCXJldHVybiBjZS5nZXRTdGF0dXMoKTsKCQl9CgkJCgkJLy8gcGVyZm9ybSB0YXNrcwoJCU11bHRpU3RhdHVzIHRhc2tTdGF0dXMgPSBwZXJmb3JtVGFza3ModGFza3MsIG1vbml0b3IpOwoJCWlmICh0YXNrU3RhdHVzICE9IG51bGwpCgkJCXRlbXBNdWx0aS5hZGRBbGwodGFza1N0YXR1cyk7CgkJCgkJLy8gcHVibGlzaCB0aGUgc2VydmVyCgkJdHJ5IHsKCQkJaWYgKCFtb25pdG9yLmlzQ2FuY2VsZWQoKSkgewoJCQkJcHVibGlzaFNlcnZlcihraW5kLCBQcm9ncmVzc1V0aWwuZ2V0U3ViTW9uaXRvckZvcihtb25pdG9yLCAxMDAwKSk7CgkJCX0KCQl9IGNhdGNoIChDb3JlRXhjZXB0aW9uIGNlKSB7CgkJCVRyYWNlLnRyYWNlKFRyYWNlLklORk8sICJDb3JlRXhjZXB0aW9uIHB1Ymxpc2hpbmcgdG8gIiArIHRvU3RyaW5nKCksIGNlKTsKCQkJdGVtcE11bHRpLmFkZChjZS5nZXRTdGF0dXMoKSk7CgkJfSBjYXRjaCAoRXhjZXB0aW9uIGUpIHsKCQkJVHJhY2UudHJhY2UoVHJhY2UuU0VWRVJFLCAiRXJyb3IgcHVibGlzaGluZyBjb25maWd1cmF0aW9uIHRvICIgKyB0b1N0cmluZygpLCBlKTsKCQkJdGVtcE11bHRpLmFkZChuZXcgU3RhdHVzKElTdGF0dXMuRVJST1IsIFNlcnZlclBsdWdpbi5QTFVHSU5fSUQsIDAsIE1lc3NhZ2VzLmVycm9yUHVibGlzaGluZywgZSkpOwoJCX0KCQkKCQkvLyBwdWJsaXNoIG1vZHVsZXMKCQlpZiAoIW1vbml0b3IuaXNDYW5jZWxlZCgpKSB7CgkJCXRyeSB7CgkJCQlwdWJsaXNoTW9kdWxlcyhraW5kLCBtb2R1bGVMaXN0LCBkZWx0YUtpbmRMaXN0LCB0ZW1wTXVsdGksIG1vbml0b3IpOwoJCQl9IGNhdGNoIChFeGNlcHRpb24gZSkgewoJCQkJVHJhY2UudHJhY2UoVHJhY2UuV0FSTklORywgIkVycm9yIHdoaWxlIHB1Ymxpc2hpbmcgbW9kdWxlcyIsIGUpOwoJCQkJdGVtcE11bHRpLmFkZChuZXcgU3RhdHVzKElTdGF0dXMuRVJST1IsIFNlcnZlclBsdWdpbi5QTFVHSU5fSUQsIDAsIE1lc3NhZ2VzLmVycm9yUHVibGlzaGluZywgZSkpOwoJCQl9CgkJfQoJCQoJCS8vIGVuZCB0aGUgcHVibGlzaGluZwoJCVRyYWNlLnRyYWNlKFRyYWNlLkZJTkVTVCwgIkNhbGxpbmcgcHVibGlzaEZpbmlzaCgpIik7CgkJdHJ5IHsKCQkJcHVibGlzaEZpbmlzaChQcm9ncmVzc1V0aWwuZ2V0U3ViTW9uaXRvckZvcihtb25pdG9yLCA1MDApKTsKCQl9IGNhdGNoIChDb3JlRXhjZXB0aW9uIGNlKSB7CgkJCVRyYWNlLnRyYWNlKFRyYWNlLklORk8sICJDb3JlRXhjZXB0aW9uIHB1Ymxpc2hpbmcgdG8gIiArIHRvU3RyaW5nKCksIGNlKTsKCQkJdGVtcE11bHRpLmFkZChjZS5nZXRTdGF0dXMoKSk7CgkJfSBjYXRjaCAoRXhjZXB0aW9uIGUpIHsKCQkJVHJhY2UudHJhY2UoVHJhY2UuU0VWRVJFLCAiRXJyb3Igc3RvcHBpbmcgcHVibGlzaCB0byAiICsgdG9TdHJpbmcoKSwgZSk7CgkJCXRlbXBNdWx0aS5hZGQobmV3IFN0YXR1cyhJU3RhdHVzLkVSUk9SLCBTZXJ2ZXJQbHVnaW4uUExVR0lOX0lELCAwLCBNZXNzYWdlcy5lcnJvclB1Ymxpc2hpbmcsIGUpKTsKCQl9CgkJCgkJaWYgKG1vbml0b3IuaXNDYW5jZWxlZCgpKQoJCQlyZXR1cm4gU3RhdHVzLkNBTkNFTF9TVEFUVVM7CgkJCgkJbW9uaXRvci5kb25lKCk7CgkJCgkJVHJhY2UudHJhY2UoVHJhY2UuRklORVNULCAiLS08LS0gRG9uZSBwdWJsaXNoaW5nIC0tPC0tIik7CgkJCgkJaWYgKHRlbXBNdWx0aS5nZXRDaGlsZHJlbigpLmxlbmd0aCA9PSAxKQoJCQlyZXR1cm4gdGVtcE11bHRpLmdldENoaWxkcmVuKClbMF07CgkJCgkJTXVsdGlTdGF0dXMgbXVsdGkgPSBudWxsOwoJCWlmICh0ZW1wTXVsdGkuZ2V0U2V2ZXJpdHkoKSA9PSBJU3RhdHVzLk9LKQoJCQltdWx0aSA9IG5ldyBNdWx0aVN0YXR1cyhTZXJ2ZXJQbHVnaW4uUExVR0lOX0lELCAwLCBNZXNzYWdlcy5wdWJsaXNoaW5nU3RhdHVzT2ssIG51bGwpOwoJCWVsc2UgaWYgKHRlbXBNdWx0aS5nZXRTZXZlcml0eSgpID09IElTdGF0dXMuSU5GTykKCQkJbXVsdGkgPSBuZXcgTXVsdGlTdGF0dXMoU2VydmVyUGx1Z2luLlBMVUdJTl9JRCwgMCwgTWVzc2FnZXMucHVibGlzaGluZ1N0YXR1c0luZm8sIG51bGwpOwoJCWVsc2UgaWYgKHRlbXBNdWx0aS5nZXRTZXZlcml0eSgpID09IElTdGF0dXMuV0FSTklORykKCQkJbXVsdGkgPSBuZXcgTXVsdGlTdGF0dXMoU2VydmVyUGx1Z2luLlBMVUdJTl9JRCwgMCwgTWVzc2FnZXMucHVibGlzaGluZ1N0YXR1c1dhcm5pbmcsIG51bGwpOwoJCWVsc2UgaWYgKHRlbXBNdWx0aS5nZXRTZXZlcml0eSgpID09IElTdGF0dXMuRVJST1IpCgkJCW11bHRpID0gbmV3IE11bHRpU3RhdHVzKFNlcnZlclBsdWdpbi5QTFVHSU5fSUQsIDAsIE1lc3NhZ2VzLnB1Ymxpc2hpbmdTdGF0dXNFcnJvciwgbnVsbCk7CgkJbXVsdGkuYWRkQWxsKHRlbXBNdWx0aSk7CgkJCgkJcmV0dXJuIG11bHRpOwoJfQoKCS8qKgoJICogUHVibGlzaCBhIHNpbmdsZSBtb2R1bGUuCgkgKiAKCSAqIEBwYXJhbSBraW5kIGEgcHVibGlzaCBraW5kCgkgKiBAcGFyYW0gbW9kdWxlIGEgbW9kdWxlCgkgKiBAcGFyYW0gZGVsdGFLaW5kIHRoZSBkZWx0YSBraW5kCgkgKiBAcGFyYW0gbW9uaXRvciBhIHByb2dyZXNzIG1vbml0b3IsIG9yIDxjb2RlPm51bGw8L2NvZGU+IGlmIHByb2dyZXNzCgkgKiAgICByZXBvcnRpbmcgYW5kIGNhbmNlbGxhdGlvbiBhcmUgbm90IGRlc2lyZWQKCSAqIEByZXR1cm4gdGhlIHN0YXR1cwoJICovCglwcm90ZWN0ZWQgSVN0YXR1cyBwdWJsaXNoTW9kdWxlKGludCBraW5kLCBJTW9kdWxlW10gbW9kdWxlLCBpbnQgZGVsdGFLaW5kLCBJUHJvZ3Jlc3NNb25pdG9yIG1vbml0b3IpIHsKCQlUcmFjZS50cmFjZShUcmFjZS5GSU5FU1QsICJQdWJsaXNoaW5nIG1vZHVsZTogIiArIG1vZHVsZSk7CgkJCgkJaW50IHNpemUgPSBtb2R1bGUubGVuZ3RoOwoJCUlNb2R1bGUgbSA9IG1vZHVsZVtzaXplIC0gMV07CgkJbW9uaXRvci5iZWdpblRhc2soTkxTLmJpbmQoTWVzc2FnZXMucHVibGlzaGluZ01vZHVsZSwgbS5nZXROYW1lKCkpLCAxMDAwKTsKCQkKCQlJU3RhdHVzIHN0YXR1cyA9IFN0YXR1cy5PS19TVEFUVVM7CgkJdHJ5IHsKCQkJcHVibGlzaE1vZHVsZShraW5kLCBkZWx0YUtpbmQsIG1vZHVsZSwgbW9uaXRvcik7CgkJfSBjYXRjaCAoQ29yZUV4Y2VwdGlvbiBjZSkgewoJCQlzdGF0dXMgPSBjZS5nZXRTdGF0dXMoKTsKCQl9IGNhdGNoIChFeGNlcHRpb24gZSkgewoJCQlzdGF0dXMgPSBuZXcgU3RhdHVzKElTdGF0dXMuRVJST1IsIFNlcnZlclBsdWdpbi5QTFVHSU5fSUQsIDAsIE1lc3NhZ2VzLmVycm9yUHVibGlzaGluZywgZSk7CgkJfQoJCQoJCS8qVHJhY2UudHJhY2UoVHJhY2UuRklORVNULCAiRGVsdGE6Iik7CgkJSU1vZHVsZVJlc291cmNlRGVsdGFbXSBkZWx0YSA9IGdldFNlcnZlclB1Ymxpc2hJbmZvKCkuZ2V0RGVsdGEocGFyZW50cywgbW9kdWxlKTsKCQlpbnQgc2l6ZSA9IGRlbHRhLmxlbmd0aDsKCQlmb3IgKGludCBpID0gMDsgaSA8IHNpemU7IGkrKykgewoJCQkoKE1vZHVsZVJlc291cmNlRGVsdGEpZGVsdGFbaV0pLnRyYWNlKCI+ICAiKTsKCQl9Ki8KCQkKCQltb25pdG9yLmRvbmUoKTsKCQkKCQlUcmFjZS50cmFjZShUcmFjZS5GSU5FU1QsICJEb25lIHB1Ymxpc2hpbmc6ICIgKyBtb2R1bGUpOwoJCXJldHVybiBzdGF0dXM7Cgl9CgoJLyoqCgkgKiBSZXR1cm5zIDxjb2RlPnRydWU8L2NvZGU+IGlmIHRoZSBnaXZlbiBtb2R1bGUgaGFzIGJlZW4gcHVibGlzaGVkLCBhbmQKCSAqICAgIDxjb2RlPmZhbHNlPC9jb2RlPiBvdGhlcndpc2UuCgkgKiAKCSAqIEBwYXJhbSBtb2R1bGUgYSBtb2R1bGUKCSAqIEByZXR1cm4gPGNvZGU+dHJ1ZTwvY29kZT4gaWYgdGhlIGdpdmVuIG1vZHVsZSBoYXMgYmVlbiBwdWJsaXNoZWQsIGFuZAoJICogICAgPGNvZGU+ZmFsc2U8L2NvZGU+IG90aGVyd2lzZQoJICovCglwcm90ZWN0ZWQgYm9vbGVhbiBoYXNCZWVuUHVibGlzaGVkKElNb2R1bGVbXSBtb2R1bGUpIHsKCQlyZXR1cm4gc2VydmVyLmdldFNlcnZlclB1Ymxpc2hJbmZvKCkuaGFzTW9kdWxlUHVibGlzaEluZm8obW9kdWxlKTsKCX0KCgkvKioKCSAqIEFkZHMgcmVtb3ZlZCBtb2R1bGVzLgoJICogCgkgKiBAcGFyYW0gbW9kdWxlTGlzdCBhIGxpc3Qgb2YgbW9kdWxlcwoJICogQHBhcmFtIGtpbmRMaXN0IGEgbGlzdCBvZiBwdWJsaXNoIGtpbmRzCgkgKi8KCXByb3RlY3RlZCB2b2lkIGFkZFJlbW92ZWRNb2R1bGVzKExpc3QgbW9kdWxlTGlzdCwgTGlzdCBraW5kTGlzdCkgewoJCXNlcnZlci5nZXRTZXJ2ZXJQdWJsaXNoSW5mbygpLmFkZFJlbW92ZWRNb2R1bGVzKG1vZHVsZUxpc3QsIGtpbmRMaXN0KTsKCX0KCgkvKioKCSAqIFVwZGF0ZSB0aGUgc3RvcmVkIHB1Ymxpc2ggaW5mbyBmb3IgdGhlIGdpdmVuIG1vZHVsZS4KCSAqIAoJICogQGRlcHJlY2F0ZWQgc2hvdWxkIG5ldmVyIG5lZWQgdG8gYmUgY2FsbGVkIGRpcmVjdGx5LiBXaWxsIGJlIHJlbW92ZWQKCSAqICAgIGluIGEgZnV0dXJlIHZlcnNpb24gb2YgV1RQCgkgKiBAcGFyYW0gZGVsdGFLaW5kIGEgcHVibGlzaCBkZWx0YSBraW5kCgkgKiBAcGFyYW0gbW9kdWxlIGEgbW9kdWxlCgkgKi8KCXByb3RlY3RlZCB2b2lkIHVwZGF0ZVB1Ymxpc2hJbmZvKGludCBkZWx0YUtpbmQsIElNb2R1bGVbXSBtb2R1bGUpIHsKCQkvLyBUT0RPIHJlbW92ZQoJfQoKCS8qKgoJICogUHVibGlzaGVzIHRoZSBnaXZlbiBtb2R1bGVzLiBSZXR1cm5zIHRydWUgaWYgdGhlIHB1Ymxpc2hpbmcKCSAqIHNob3VsZCBjb250aW51ZSwgb3IgZmFsc2UgaWYgcHVibGlzaGluZyBoYXMgZmFpbGVkIG9yIGlzIGNhbmNlbGxlZC4KCSAqIAoJICogVXNlcyA1MDAgdGlja3MgcGx1cyAzNTAwIHRpY2tzIHBlciBtb2R1bGUKCSAqIAoJICogQHBhcmFtIGtpbmQgdGhlIHB1Ymxpc2gga2luZAoJICogQHBhcmFtIG1vZHVsZXMgYSBsaXN0IG9mIG1vZHVsZXMKCSAqIEBwYXJhbSBkZWx0YUtpbmQgYSBsaXN0IG9mIGRlbHRhIGtpbmRzCgkgKiBAcGFyYW0gbXVsdGkgYSBtdWx0aXN0YXR1cyB0byBhZGQgdGhlIHN0YXR1cyB0bwoJICogQHBhcmFtIG1vbml0b3IgYSBwcm9ncmVzcyBtb25pdG9yLCBvciA8Y29kZT5udWxsPC9jb2RlPiBpZiBwcm9ncmVzcwoJICogICAgcmVwb3J0aW5nIGFuZCBjYW5jZWxsYXRpb24gYXJlIG5vdCBkZXNpcmVkCgkgKi8KCXByb3RlY3RlZCB2b2lkIHB1Ymxpc2hNb2R1bGVzKGludCBraW5kLCBMaXN0IG1vZHVsZXMsIExpc3QgZGVsdGFLaW5kLCBNdWx0aVN0YXR1cyBtdWx0aSwgSVByb2dyZXNzTW9uaXRvciBtb25pdG9yKSB7CgkJaWYgKG1vZHVsZXMgPT0gbnVsbCkKCQkJcmV0dXJuOwoJCQoJCWludCBzaXplID0gbW9kdWxlcy5zaXplKCk7CgkJaWYgKHNpemUgPT0gMCkKCQkJcmV0dXJuOwoJCQoJCWlmIChtb25pdG9yLmlzQ2FuY2VsZWQoKSkKCQkJcmV0dXJuOwoJCQoJCS8vIHB1Ymxpc2ggbW9kdWxlcwoJCWZvciAoaW50IGkgPSAwOyBpIDwgc2l6ZTsgaSsrKSB7CgkJCUlTdGF0dXMgc3RhdHVzID0gcHVibGlzaE1vZHVsZShraW5kLCAoSU1vZHVsZVtdKSBtb2R1bGVzLmdldChpKSwgKChJbnRlZ2VyKWRlbHRhS2luZC5nZXQoaSkpLmludFZhbHVlKCksIFByb2dyZXNzVXRpbC5nZXRTdWJNb25pdG9yRm9yKG1vbml0b3IsIDMwMDApKTsKCQkJbXVsdGkuYWRkKHN0YXR1cyk7CgkJfQoJfQoKCS8qKgoJICogUmV0dXJucyB0aGUgcHVibGlzaCB0YXNrcyB0aGF0IGhhdmUgYmVlbiB0YXJnZXR0ZWQgdG8gdGhpcyBzZXJ2ZXIuCgkgKiBUaGVzZSB0YXNrcyBzaG91bGQgYmUgcnVuIGR1cmluZyBwdWJsaXNoaW5nLgoJICogCgkgKiBAcGFyYW0ga2luZCBvbmUgb2YgdGhlIElTZXJ2ZXIuUFVCTElTSF9YWCBjb25zdGFudHMKCSAqIEBwYXJhbSBtb2R1bGVMaXN0IGEgbGlzdCBvZiBtb2R1bGVzCgkgKiBAcGFyYW0ga2luZExpc3QgbGlzdCBvZiBvbmUgb2YgdGhlIElTZXJ2ZXIgcHVibGlzaCBjaGFuZ2UgY29uc3RhbnRzCgkgKiBAcmV0dXJuIGEgcG9zc2libHkgZW1wdHkgYXJyYXkgb2YgSU9wdGlvbmFsVGFza3MKCSAqLwoJcHJvdGVjdGVkIGZpbmFsIFB1Ymxpc2hPcGVyYXRpb25bXSBnZXRUYXNrcyhpbnQga2luZCwgTGlzdCBtb2R1bGVMaXN0LCBMaXN0IGtpbmRMaXN0KSB7CgkJcmV0dXJuIHNlcnZlci5nZXRUYXNrcyhraW5kLCBtb2R1bGVMaXN0LCBraW5kTGlzdCk7Cgl9CgoJLyoqCgkgKiBSZXR1cm5zIGFsbCB0aGUgbW9kdWxlcyB0aGF0IGFyZSBvbiB0aGUgc2VydmVyLCBpbmNsdWRpbmcgcm9vdAoJICogbW9kdWxlcyBhbmQgYWxsIHRoZWlyIGNoaWxkcmVuLgoJICogCgkgKiBAcmV0dXJuIGEgbGlzdCBvZiBJTW9kdWxlW11zCgkgKi8KCXByb3RlY3RlZCBmaW5hbCBMaXN0IGdldEFsbE1vZHVsZXMoKSB7CgkJcmV0dXJuIHNlcnZlci5nZXRBbGxNb2R1bGVzKCk7Cgl9CgoJLyoqCgkgKiBQZXJmb3JtIChleGVjdXRlKSBhbGwgdGhlIGdpdmVuIHRhc2tzLgoJICogCgkgKiBAcGFyYW0gdGFza3MgYW4gYXJyYXkgb2YgdGFza3MKCSAqIEBwYXJhbSBtb25pdG9yIGEgcHJvZ3Jlc3MgbW9uaXRvciwgb3IgPGNvZGU+bnVsbDwvY29kZT4gaWYgcHJvZ3Jlc3MKCSAqICAgIHJlcG9ydGluZyBhbmQgY2FuY2VsbGF0aW9uIGFyZSBub3QgZGVzaXJlZAoJICogQHJldHVybiB0aGUgc3RhdHVzCgkgKi8KCXByb3RlY3RlZCBNdWx0aVN0YXR1cyBwZXJmb3JtVGFza3MoUHVibGlzaE9wZXJhdGlvbltdIHRhc2tzLCBJUHJvZ3Jlc3NNb25pdG9yIG1vbml0b3IpIHsKCQlpbnQgc2l6ZSA9IHRhc2tzLmxlbmd0aDsKCQlUcmFjZS50cmFjZShUcmFjZS5GSU5FU1QsICJQZXJmb3JtaW5nIHRhc2tzOiAiICsgc2l6ZSk7CgkJCgkJaWYgKHNpemUgPT0gMCkKCQkJcmV0dXJuIG51bGw7CgkJCgkJTXVsdGlTdGF0dXMgbXVsdGkgPSBuZXcgTXVsdGlTdGF0dXMoU2VydmVyUGx1Z2luLlBMVUdJTl9JRCwgMCwgTWVzc2FnZXMudGFza1BlcmZvcm1pbmcsIG51bGwpOwoJCQoJCWZvciAoaW50IGkgPSAwOyBpIDwgc2l6ZTsgaSsrKSB7CgkJCVB1Ymxpc2hPcGVyYXRpb24gdGFzayA9IHRhc2tzW2ldOwoJCQltb25pdG9yLnN1YlRhc2soTkxTLmJpbmQoTWVzc2FnZXMudGFza1BlcmZvcm1pbmcsIHRhc2sudG9TdHJpbmcoKSkpOwoJCQl0cnkgewoJCQkJdGFzay5leGVjdXRlKFByb2dyZXNzVXRpbC5nZXRTdWJNb25pdG9yRm9yKG1vbml0b3IsIDUwMCksIG51bGwpOwoJCQl9IGNhdGNoIChDb3JlRXhjZXB0aW9uIGNlKSB7CgkJCQlUcmFjZS50cmFjZShUcmFjZS5TRVZFUkUsICJUYXNrIGZhaWxlZCIsIGNlKTsKCQkJCW11bHRpLmFkZChjZS5nZXRTdGF0dXMoKSk7CgkJCX0KCQkJCgkJCS8vIHJldHVybiBlYXJseSBpZiB0aGUgbW9uaXRvciBoYXMgYmVlbiBjYW5jZWxsZWQKCQkJaWYgKG1vbml0b3IuaXNDYW5jZWxlZCgpKQoJCQkJcmV0dXJuIG11bHRpOwoJCX0KCQkKCQlyZXR1cm4gbXVsdGk7Cgl9CgoJLyoqCgkgKiBDYWxsZWQgd2hlbiByZXNvdXJjZXMgY2hhbmdlIHdpdGhpbiB0aGUgd29ya3NwYWNlLgoJICogVGhpcyBnaXZlcyB0aGUgc2VydmVyIGFuIG9wcG9ydHVuaXR5IHRvIHVwZGF0ZSB0aGUgc2VydmVyIG9yIG1vZHVsZQoJICogcmVzdGFydCBzdGF0ZS4KCSAqLwoJcHVibGljIHZvaWQgaGFuZGxlUmVzb3VyY2VDaGFuZ2UoKSB7CgkJLy8gZG8gbm90aGluZwoJfQp9