LyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogQ29weXJpZ2h0IChjKSAyMDA1IElCTSBDb3Jwb3JhdGlvbiBhbmQgb3RoZXJzLgogKiBBbGwgcmlnaHRzIHJlc2VydmVkLiBUaGlzIHByb2dyYW0gYW5kIHRoZSBhY2NvbXBhbnlpbmcgbWF0ZXJpYWxzCiAqIGFyZSBtYWRlIGF2YWlsYWJsZSB1bmRlciB0aGUgdGVybXMgb2YgdGhlIEVjbGlwc2UgUHVibGljIExpY2Vuc2UgdjEuMAogKiB3aGljaCBhY2NvbXBhbmllcyB0aGlzIGRpc3RyaWJ1dGlvbiwgYW5kIGlzIGF2YWlsYWJsZSBhdAogKiBodHRwOi8vd3d3LmVjbGlwc2Uub3JnL2xlZ2FsL2VwbC12MTAuaHRtbAqgKiAKICogQ29udHJpYnV0b3JzOgogKiAgICAgSUJNIENvcnBvcmF0aW9uIC0gSW5pdGlhbCBBUEkgYW5kIGltcGxlbWVudGF0aW9uCiAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwpwYWNrYWdlIG9yZy5lY2xpcHNlLndzdC5zZXJ2ZXIuY29yZS5tb2RlbDsKCmltcG9ydCBqYXZhLnV0aWwuTGlzdDsKaW1wb3J0IGphdmEudXRpbC5NYXA7CgppbXBvcnQgb3JnLmVjbGlwc2UuY29yZS5ydW50aW1lLkNvcmVFeGNlcHRpb247CmltcG9ydCBvcmcuZWNsaXBzZS5jb3JlLnJ1bnRpbWUuSVByb2dyZXNzTW9uaXRvcjsKaW1wb3J0IG9yZy5lY2xpcHNlLmNvcmUucnVudGltZS5JU3RhdHVzOwppbXBvcnQgb3JnLmVjbGlwc2Uud3N0LnNlcnZlci5jb3JlLio7CmltcG9ydCBvcmcuZWNsaXBzZS53c3Quc2VydmVyLmNvcmUuaW50ZXJuYWwuU2VydmVyOwppbXBvcnQgb3JnLmVjbGlwc2Uud3N0LnNlcnZlci5jb3JlLmludGVybmFsLlNlcnZlcldvcmtpbmdDb3B5OwovKioKICogQSBzZXJ2ZXIgZGVsZWdhdGUgcHJvdmlkZXMgdGhlIGltcGxlbWVudGF0aW9uIGZvciB2YXJpb3VzIAogKiBnZW5lcmljIGFuZCBzZXJ2ZXItdHlwZS1zcGVjaWZpYyBvcGVyYXRpb25zIGZvciBhIHNwZWNpZmljIHR5cGUgb2Ygc2VydmVyLgogKiBBIHNlcnZlciBkZWxlZ2F0ZSBpcyBzcGVjaWZpZWQgYnkgdGhlCiAqIDxjb2RlPmNsYXNzPC9jb2RlPiBhdHRyaWJ1dGUgb2YgYSA8Y29kZT5zZXJ2ZXJUeXBlczwvY29kZT4gZXh0ZW5zaW9uLgogKiA8cD4KICogV2hlbiB0aGUgc2VydmVyIGluc3RhbmNlIG5lZWRzIHRvIGJlIGdpdmVuIGEgZGVsZWdhdGUsIHRoZSBkZWxlZ2F0ZSBjbGFzcwogKiBzcGVjaWZpZWQgZm9yIHRoZSBzZXJ2ZXIgdHlwZSBpcyBpbnN0YW50aWF0ZWQgd2l0aCBhIDAtYXJndW1lbnQgY29uc3RydWN0b3IKICogYW5kIHByaW1lZCB3aXRoIDxjb2RlPmRlbGVnYXRlLmluaXRpYWxpemUoKChJU2VydmVyU3RhdGUpc2VydmVyKTwvY29kZT4sIAogKiB3aGljaCBpdCBpcyBleHBlY3RlZCB0byBoYW5nIG9uIHRvLiBMYXRlciwgd2hlbgogKiA8Y29kZT5kZWxlZ2F0ZS5kaXNwb3NlKCk8L2NvZGU+IGlzIGNhbGxlZCBhcyB0aGUgc2VydmVyIGluc3RhbmNlIGlzCiAqIGJlaW5nIGRpc2NhcmRlZCwgdGhlIGRlbGVnYXRlIGlzIGV4cGVjdGVkIHRvIGxldCBnbyBvZiB0aGUgc2VydmVyIGluc3RhbmNlLgogKiA8L3A+CiAqIDxwPgogKiBTZXJ2ZXJEZWxlZ2F0ZSBzdXBwb3J0cyBhbiBvcGVuLWVuZGVkIHNldCBvZiBhdHRyaWJ1dGUtdmFsdWUgcGFpcnMuIEFsbAogKiBzdGF0ZSBzdG9yZWQgaW4gdGhpcyBtYW5uZXIgd2lsbCBiZSBzYXZlZCB3aGVuIHRoZSBzZXJ2ZXIgd29ya2luZyBjb3B5IGlzCiAqIHNhdmVkLCBhbmQgcGVyc2lzdGVkIGFjcm9zcyB3b3JrYmVuY2ggc2Vzc2lvbnMuCiAqIFNlcnZlciBkZWxlZ2F0ZXMgbWF5IGtlZXAgc3RhdGUgaW4gaW5zdGFuY2UgZmllbGRzLCBidXQgdGhhdCBzdGF0ZSBpcwogKiB0cmFuc2llbnQgYW5kIHdpbGwgbm90IGJlIHBlcnNpc3RlZCBhY3Jvc3Mgd29ya2JlbmNoIHNlc3Npb25zLiBUbyBzYXZlCiAqIHN0YXRlIGFjcm9zcyB3b3JrYmVuY2ggc2Vzc2lvbnMsIGl0IG11c3QgYmUgcGVyc2lzdGVkIHVzaW5nIHRoZQogKiBhdHRyaWJ1dGVzLgogKiA8L3A+CiAqIDxwPgogKiBUaGlzIGFic3RyYWN0IGNsYXNzIGlzIGludGVuZGVkIHRvIGJlIGV4dGVuZGVkIG9ubHkgYnkgY2xpZW50cwogKiB0byBleHRlbmQgdGhlIDxjb2RlPnNlcnZlclR5cGVzPC9jb2RlPiBleHRlbnNpb24gcG9pbnQuCiAqIDwvcD4KICogCiAqIEBzZWUgSVNlcnZlcgogKiBAc2VlIElTZXJ2ZXJXb3JraW5nQ29weQogKiBAcGxhbm5lZGZvciAxLjAKICovCnB1YmxpYyBhYnN0cmFjdCBjbGFzcyBTZXJ2ZXJEZWxlZ2F0ZSB7Cglwcml2YXRlIFNlcnZlciBzZXJ2ZXI7Cglwcml2YXRlIFNlcnZlcldvcmtpbmdDb3B5IHNlcnZlcldDOwoKCS8qKgoJICogRGVsZWdhdGVzIG11c3QgaGF2ZSBhIHB1YmxpYyAwLWFyZyBjb25zdHJ1Y3Rvci4KCSAqLwoJcHVibGljIFNlcnZlckRlbGVnYXRlKCkgewoJCS8vIGRvIG5vdGhpbmcKCX0KCgkvKioKCSAqIEluaXRpYWxpemVzIHRoaXMgc2VydmVyIGRlbGVnYXRlIHdpdGggaXRzIGxpZmUtbG9uZyBzZXJ2ZXIgaW5zdGFuY2UuCgkgKiA8cD4KCSAqIFRoaXMgbWV0aG9kIGlzIGNhbGxlZCBieSB0aGUgc2VydmVyIGNvcmUgZnJhbWV3b3JrLgoJICogQ2xpZW50cyBzaG91bGQgbmV2ZXIgY2FsbCB0aGlzIG1ldGhvZC4KCSAqIDwvcD4KCSAqIAoJICogQHBhcmFtIG5ld1NlcnZlciB0aGUgc2VydmVyIGluc3RhbmNlCgkgKiBAcGFyYW0gbW9uaXRvciBhIHByb2dyZXNzIG1vbml0b3IsIG9yIDxjb2RlPm51bGw8L2NvZGU+IGlmIHByb2dyZXNzCgkgKiAgICByZXBvcnRpbmcgYW5kIGNhbmNlbGxhdGlvbiBhcmUgbm90IGRlc2lyZWQKCSAqLwoJZmluYWwgdm9pZCBpbml0aWFsaXplKFNlcnZlciBuZXdTZXJ2ZXIsIElQcm9ncmVzc01vbml0b3IgbW9uaXRvcikgewoJCXNlcnZlciA9IG5ld1NlcnZlcjsKCQlpZiAobmV3U2VydmVyIGluc3RhbmNlb2YgU2VydmVyV29ya2luZ0NvcHkpCgkJCXNlcnZlcldDID0gKFNlcnZlcldvcmtpbmdDb3B5KSBuZXdTZXJ2ZXI7CgkJaW5pdGlhbGl6ZSgpOwoJfQoKCS8qKgoJICogSW5pdGlhbGl6ZXMgdGhpcyBzZXJ2ZXIgZGVsZWdhdGUuIFRoaXMgbWV0aG9kIGdpdmVzIGRlbGVnYXRlcyBhIGNoYW5jZQoJICogdG8gZG8gdGhlaXIgb3duIGluaXRpYWxpemF0aW9uLgoJICogPHA+CgkgKiBUaGlzIG1ldGhvZCBpcyBjYWxsZWQgYnkgdGhlIHNlcnZlciBjb3JlIGZyYW1ld29yay4KCSAqIENsaWVudHMgc2hvdWxkIG5ldmVyIGNhbGwgdGhpcyBtZXRob2QuCgkgKiA8L3A+CgkgKi8KCXByb3RlY3RlZCB2b2lkIGluaXRpYWxpemUoKSB7CgkJLy8gZG8gbm90aGluZwoJfQoKCS8qKgoJICogUmV0dXJucyB0aGUgc2VydmVyIHRoYXQgdGhpcyBzZXJ2ZXIgZGVsZWdhdGUgY29ycmVzcG9uZHMgdG8uCgkgKiAKCSAqIEByZXR1cm4gdGhlIHNlcnZlcgoJICovCglwdWJsaWMgZmluYWwgSVNlcnZlciBnZXRTZXJ2ZXIoKSB7CgkJcmV0dXJuIHNlcnZlcjsKCX0KCgkvKioKCSAqIFJldHVybnMgdGhlIHNlcnZlciB3b3JraW5nIGNvcHkgdGhhdCB0aGlzIHNlcnZlciBkZWxlZ2F0ZSBjb3JyZXNwb25kcyB0by4KCSAqIAoJICogQHJldHVybiB0aGUgc2VydmVyCgkgKi8KCXB1YmxpYyBmaW5hbCBJU2VydmVyV29ya2luZ0NvcHkgZ2V0U2VydmVyV29ya2luZ0NvcHkoKSB7CgkJcmV0dXJuIHNlcnZlcldDOwoJfQoKCS8qKgoJICogUmV0dXJucyB0aGUgdmFsdWUgb2YgdGhlIHNwZWNpZmllZCBpbnQtdmFsdWVkIGF0dHJpYnV0ZS4KCSAqIAoJICogQHBhcmFtIGlkIHRoZSBhdHRyaWJ1dGUgaWQKCSAqIEBwYXJhbSBkZWZhdWx0VmFsdWUgdGhlIGRlZmF1bHQgdmFsdWUgb2YgdGhlIHNwZWNpZmllZCBhdHRyaWJ1dGUKCSAqIEByZXR1cm4gdGhlIGF0dHJpYnV0ZSB2YWx1ZQoJICogQHNlZSAjc2V0QXR0cmlidXRlKFN0cmluZywgaW50KQoJICovCglwcm90ZWN0ZWQgZmluYWwgaW50IGdldEF0dHJpYnV0ZShTdHJpbmcgaWQsIGludCBkZWZhdWx0VmFsdWUpIHsKCQlyZXR1cm4gc2VydmVyLmdldEF0dHJpYnV0ZShpZCwgZGVmYXVsdFZhbHVlKTsKCX0KCgkvKioKCSAqIFJldHVybnMgdGhlIHZhbHVlIG9mIHRoZSBzcGVjaWZpZWQgYm9vbGVhbi12YWx1ZWQgYXR0cmlidXRlLgoJICogCgkgKiBAcGFyYW0gaWQgdGhlIGF0dHJpYnV0ZSBpZAoJICogQHBhcmFtIGRlZmF1bHRWYWx1ZSB0aGUgZGVmYXVsdCB2YWx1ZSBvZiB0aGUgc3BlY2lmaWVkIGF0dHJpYnV0ZQoJICogQHJldHVybiB0aGUgYXR0cmlidXRlIHZhbHVlCgkgKiBAc2VlICNzZXRBdHRyaWJ1dGUoU3RyaW5nLCBib29sZWFuKQoJICovCglwcm90ZWN0ZWQgZmluYWwgYm9vbGVhbiBnZXRBdHRyaWJ1dGUoU3RyaW5nIGlkLCBib29sZWFuIGRlZmF1bHRWYWx1ZSkgewoJCXJldHVybiBzZXJ2ZXIuZ2V0QXR0cmlidXRlKGlkLCBkZWZhdWx0VmFsdWUpOwoJfQoKCS8qKgoJICogUmV0dXJucyB0aGUgdmFsdWUgb2YgdGhlIHNwZWNpZmllZCBTdHJpbmctdmFsdWVkIGF0dHJpYnV0ZS4KCSAqIAoJICogQHBhcmFtIGlkIHRoZSBhdHRyaWJ1dGUgaWQKCSAqIEBwYXJhbSBkZWZhdWx0VmFsdWUgdGhlIGRlZmF1bHQgdmFsdWUgb2YgdGhlIHNwZWNpZmllZCBhdHRyaWJ1dGUKCSAqIEByZXR1cm4gdGhlIGF0dHJpYnV0ZSB2YWx1ZQoJICogQHNlZSAjc2V0QXR0cmlidXRlKFN0cmluZywgU3RyaW5nKQoJICovCglwcm90ZWN0ZWQgZmluYWwgU3RyaW5nIGdldEF0dHJpYnV0ZShTdHJpbmcgaWQsIFN0cmluZyBkZWZhdWx0VmFsdWUpIHsKCQlyZXR1cm4gc2VydmVyLmdldEF0dHJpYnV0ZShpZCwgZGVmYXVsdFZhbHVlKTsKCX0KCgkvKioKCSAqIFJldHVybnMgdGhlIHZhbHVlIG9mIHRoZSBzcGVjaWZpZWQgTGlzdC12YWx1ZWQgYXR0cmlidXRlLgoJICogCgkgKiBAcGFyYW0gaWQgdGhlIGF0dHJpYnV0ZSBpZAoJICogQHBhcmFtIGRlZmF1bHRWYWx1ZSB0aGUgZGVmYXVsdCB2YWx1ZSBvZiB0aGUgc3BlY2lmaWVkIGF0dHJpYnV0ZQoJICogQHJldHVybiB0aGUgYXR0cmlidXRlIHZhbHVlCgkgKiBAc2VlICNzZXRBdHRyaWJ1dGUoU3RyaW5nLCBMaXN0KQoJICovCglwcm90ZWN0ZWQgZmluYWwgTGlzdCBnZXRBdHRyaWJ1dGUoU3RyaW5nIGlkLCBMaXN0IGRlZmF1bHRWYWx1ZSkgewoJCXJldHVybiBzZXJ2ZXIuZ2V0QXR0cmlidXRlKGlkLCBkZWZhdWx0VmFsdWUpOwoJfQoKCS8qKgoJICogUmV0dXJucyB0aGUgdmFsdWUgb2YgdGhlIHNwZWNpZmllZCBNYXAtdmFsdWVkIGF0dHJpYnV0ZS4KCSAqIAoJICogQHBhcmFtIGlkIHRoZSBhdHRyaWJ1dGUgaWQKCSAqIEBwYXJhbSBkZWZhdWx0VmFsdWUgdGhlIGRlZmF1bHQgdmFsdWUgb2YgdGhlIHNwZWNpZmllZCBhdHRyaWJ1dGUKCSAqIEByZXR1cm4gdGhlIGF0dHJpYnV0ZSB2YWx1ZQoJICogQHNlZSAjc2V0QXR0cmlidXRlKFN0cmluZywgTWFwKQoJICovCglwcm90ZWN0ZWQgZmluYWwgTWFwIGdldEF0dHJpYnV0ZShTdHJpbmcgaWQsIE1hcCBkZWZhdWx0VmFsdWUpIHsKCQlyZXR1cm4gc2VydmVyLmdldEF0dHJpYnV0ZShpZCwgZGVmYXVsdFZhbHVlKTsKCX0KCgkvKioKCSAqIERpc3Bvc2VzIG9mIHRoaXMgc2VydmVyIGRlbGVnYXRlLgoJICogPHA+CgkgKiBUaGlzIG1ldGhvZCBpcyBjYWxsZWQgYnkgdGhlIHdlYiBzZXJ2ZXIgY29yZSBmcmFtZXdvcmsuCgkgKiBDbGllbnRzIHNob3VsZCBuZXZlciBjYWxsIHRoaXMgbWV0aG9kLgoJICogPC9wPgoJICogPHA+CgkgKiBJbXBsZW1lbnRhdGlvbnMgYXJlIGV4cGVjdGVkIHRvIGxldCBnbyBvZiB0aGUgZGVsZWdhdGUncyByZWZlcmVuY2UKCSAqIHRvIHRoZSBzZXJ2ZXIsIGRlcmVnaXN0ZXIgbGlzdGVuZXJzLCBldGMuCgkgKiA8L3A+CgkgKi8KCXB1YmxpYyB2b2lkIGRpc3Bvc2UoKSB7CgkJLy8gZG8gbm90aGluZwoJfQoKCS8qKgoJICogUmV0dXJucyB3aGV0aGVyIHRoZSBzcGVjaWZpZWQgbW9kdWxlIG1vZGlmaWNhdGlvbnMgY291bGQgYmUgbWFkZSB0byB0aGlzCgkgKiBzZXJ2ZXIgYXQgdGhpcyB0aW1lLiBTZWUgdGhlIHNwZWNpZmljYXRpb24gb2YKCSAqIHtAbGluayBJU2VydmVyQXR0cmlidXRlcyNjYW5Nb2RpZnlNb2R1bGVzKElNb2R1bGVbXSwgSU1vZHVsZVtdLCBJUHJvZ3Jlc3NNb25pdG9yKX0KCSAqIGZvciBmdXJ0aGVyIGRldGFpbHMuIAoJICogPHA+CgkgKiBUaGlzIG1ldGhvZCBpcyBjYWxsZWQgYnkgdGhlIHdlYiBzZXJ2ZXIgY29yZSBmcmFtZXdvcmssCgkgKiBpbiByZXNwb25zZSB0byBhIGNhbGwgdG8gPGNvZGU+SVNlcnZlci5jYW5Nb2RpZnlNb2R1bGVzPC9jb2RlPi4KCSAqIENsaWVudHMgc2hvdWxkIG5ldmVyIGNhbGwgdGhpcyBtZXRob2QuCgkgKiA8L3A+CgkgKiA8cD4KCSAqIFtpc3N1ZTogU2VlIElTZXJ2ZXJBdHRyaWJ1dGVzLmNhbk1vZGlmeU1vZHVsZXMoSU1vZHVsZVtdLCBJTW9kdWxlW10sIElQcm9ncmVzc01vbml0b3IpLl0KCSAqIDwvcD4KCSAqIFtpc3N1ZTogZG9jIHRoYXQgaXQgc2hvdWxkIGJlIHF1aWNrXQoJICoKCSAqIEBwYXJhbSBhZGQgYSBwb3NzaWJseS1lbXB0eSBsaXN0IG9mIG1vZHVsZXMgdG8gYWRkCgkgKiBAcGFyYW0gcmVtb3ZlIGEgcG9zc2libHktZW1wdHkgbGlzdCBvZiBtb2R1bGVzIHRvIHJlbW92ZQoJICogQHJldHVybiBhIHN0YXR1cyBvYmplY3Qgd2l0aCBjb2RlIDxjb2RlPklTdGF0dXMuT0s8L2NvZGU+IGlmIHRoZSBtb2R1bGVzCgkgKiAgIGNhbiBiZSBtb2RpZmllZCwgb3RoZXJ3aXNlIGEgc3RhdHVzIG9iamVjdCBpbmRpY2F0aW5nIHdoeSB0aGV5IGNhbid0CgkgKi8KCXB1YmxpYyBhYnN0cmFjdCBJU3RhdHVzIGNhbk1vZGlmeU1vZHVsZXMoSU1vZHVsZVtdIGFkZCwgSU1vZHVsZVtdIHJlbW92ZSk7CgoJLyoqCgkgKiBSZXR1cm5zIHRoZSBjaGlsZCBtb2R1bGUocykgb2YgdGhpcyBtb2R1bGUuIElmIHRoaXMKCSAqIG1vZHVsZSBjb250YWlucyBvdGhlciBtb2R1bGVzLCBpdCBzaG91bGQgbGlzdCB0aG9zZQoJICogbW9kdWxlcy4gSWYgbm90LCBpdCBzaG91bGQgcmV0dXJuIGFuIGVtcHR5IGxpc3QuCgkgKgoJICogPHA+VGhpcyBtZXRob2Qgc2hvdWxkIG9ubHkgcmV0dXJuIHRoZSBkaXJlY3QgY2hpbGRyZW4uCgkgKiBUbyBvYnRhaW4gdGhlIGZ1bGwgbW9kdWxlIHRyZWUsIHRoaXMgbWV0aG9kIG1heSBiZQoJICogcmVjdXJzaXZlbHkgY2FsbGVkIG9uIHRoZSBjaGlsZHJlbi48L3A+CgkgKgoJICogQHBhcmFtIG1vZHVsZSBhIG1vZHVsZQoJICogQHJldHVybiB0aGUgY2hpbGQgbW9kdWxlcwoJICogQHNlZSBJU2VydmVyQXR0cmlidXRlcyNnZXRDaGlsZE1vZHVsZXMoSU1vZHVsZVtdLCBJUHJvZ3Jlc3NNb25pdG9yKQoJICovCglwdWJsaWMgYWJzdHJhY3QgSU1vZHVsZVtdIGdldENoaWxkTW9kdWxlcyhJTW9kdWxlW10gbW9kdWxlKTsKCgkvKioKCSAqIFJldHVybnMgdGhlIHBhcmVudCBtb2R1bGUocykgb2YgdGhpcyBtb2R1bGUuIFdoZW4gZGV0ZXJtaW5pbmcgaWYgYSBnaXZlbgoJICogcHJvamVjdCBjYW4gcnVuIG9uIGEgc2VydmVyLCB0aGlzIG1ldGhvZCB3aWxsIGJlIHVzZWQgdG8gZmluZCB0aGUgYWN0dWFsCgkgKiBtb2R1bGUocykgdGhhdCBtYXkgYmUgcnVuIG9uIHRoZSBzZXJ2ZXIuIEZvciBpbnN0YW5jZSwgYSBXZWIgbW9kdWxlIG1heQoJICogcmV0dXJuIGEgbGlzdCBvZiBFQVIgbW9kdWxlcyB0aGF0IGl0IGlzIGNvbnRhaW5lZCBpbiBpZiB0aGUgc2VydmVyIG9ubHkKCSAqIHN1cHBvcnRzIGNvbmZpZ3VyaW5nIEVBUiBtb2R1bGVzLgoJICoKCSAqIDxwPklmIHRoZSBtb2R1bGUgdHlwZSBpcyBub3Qgc3VwcG9ydGVkLCB0aGlzIG1ldGhvZCB3aWxsIHJldHVybiBudWxsLgoJICogSWYgdGhlIHR5cGUgaXMgbm9ybWFsbHkgc3VwcG9ydGVkIGJ1dCB0aGVyZSBpcyBhIGNvbmZpZ3VyYXRpb24KCSAqIHByb2JsZW0gb3IgbWlzc2luZyBwYXJlbnQsIGV0Yy4sIHRoaXMgbWV0aG9kIHdpbGwgZmlyZSBhIENvcmVFeGNlcHRpb24KCSAqIHRoYXQgbWF5IHRoZW4gYmUgcHJlc2VudGVkIHRvIHRoZSB1c2VyLjwvcD4KCSAqCgkgKiA8cD5JZiBpdCBkb2VzIHJldHVybiB2YWxpZCBwYXJlbnQocyksIHRoaXMgbWV0aG9kIHdpbGwgYWx3YXlzIHJldHVybgoJICogdGhlIHRvcG1vc3QgcGFyZW50IG1vZHVsZShzKSwgZXZlbiBpZiB0aGVyZSBhcmUgYSBmZXcgbGV2ZWxzCgkgKiAoYSBoZWlyYXJjaHkpIG9mIG1vZHVsZXMuPC9wPgoJICogCgkgKiBbaXNzdWU6IHNob3VsZCB0aGUgcGFyYW1ldGVyIGJlIElNb2R1bGVbXT9dCgkgKgoJICogQHBhcmFtIG1vZHVsZSBhIG1vZHVsZQoJICogQHJldHVybiBhbiBhcnJheSBvZiBwb3NzaWJsZSByb290IG1vZHVsZXMKCSAqIEB0aHJvd3MgQ29yZUV4Y2VwdGlvbiBpZiBhbnl0aGluZyB3ZW50IHdyb25nCgkgKgoJICogQHNlZSBvcmcuZWNsaXBzZS53c3Quc2VydmVyLmNvcmUuSVNlcnZlckF0dHJpYnV0ZXMjZ2V0Um9vdE1vZHVsZXMoSU1vZHVsZSwgSVByb2dyZXNzTW9uaXRvcikKCSAqLwoJcHVibGljIGFic3RyYWN0IElNb2R1bGVbXSBnZXRSb290TW9kdWxlcyhJTW9kdWxlIG1vZHVsZSkgdGhyb3dzIENvcmVFeGNlcHRpb247CgoJLyoqCgkgKiBSZXR1cm5zIGFuIGFycmF5IG9mIElTZXJ2ZXJQb3J0cyB0aGF0IHRoaXMgc2VydmVyIGhhcy4KCSAqCgkgKiBAcmV0dXJuIHRoZSBzZXJ2ZXIncyBwb3J0cwoJICovCglwdWJsaWMgU2VydmVyUG9ydFtdIGdldFNlcnZlclBvcnRzKCkgewoJCXJldHVybiBudWxsOwoJfQoKCS8qKgoJICogSW5pdGlhbGl6ZXMgdGhpcyBzZXJ2ZXIgd2l0aCBkZWZhdWx0IHZhbHVlcy4gVGhpcyBtZXRob2QgaXMgY2FsbGVkIHdoZW4KCSAqIGEgbmV3IHNlcnZlciBpcyBjcmVhdGVkIHNvIHRoYXQgdGhlIHNlcnZlciBjYW4gYmUgaW5pdGlhbGl6ZWQgd2l0aAoJICogbWVhbmluZ2Z1bCB2YWx1ZXMuCgkgKiAKCSAqIEBwYXJhbSBtb25pdG9yIGEgcHJvZ3Jlc3MgbW9uaXRvciwgb3IgPGNvZGU+bnVsbDwvY29kZT4gaWYgcHJvZ3Jlc3MKCSAqICAgIHJlcG9ydGluZyBhbmQgY2FuY2VsbGF0aW9uIGFyZSBub3QgZGVzaXJlZAoJICovCglwdWJsaWMgdm9pZCBzZXREZWZhdWx0cyhJUHJvZ3Jlc3NNb25pdG9yIG1vbml0b3IpIHsKCQkvLyBkbyBub3RoaW5nCgl9CgkKCS8qKgoJICogU2V0cyB0aGUgdmFsdWUgb2YgdGhlIHNwZWNpZmllZCBpbnRlZ2VyLXZhbHVlZCBhdHRyaWJ1dGUgb2YgdGhpcwoJICogZWxlbWVudC4KCSAqIAoJICogQHBhcmFtIGlkIHRoZSBhdHRyaWJ1dGUgaWQKCSAqIEBwYXJhbSB2YWx1ZSB0aGUgdmFsdWUgb2YgdGhlIHNwZWNpZmllZCBhdHRyaWJ1dGUKCSAqIEBzZWUgI2dldEF0dHJpYnV0ZShTdHJpbmcsIGludCkKCSAqLwoJcHJvdGVjdGVkIGZpbmFsIHZvaWQgc2V0QXR0cmlidXRlKFN0cmluZyBpZCwgaW50IHZhbHVlKSB7CgkJc2VydmVyV0Muc2V0QXR0cmlidXRlKGlkLCB2YWx1ZSk7Cgl9CgoJLyoqCgkgKiBTZXRzIHRoZSB2YWx1ZSBvZiB0aGUgc3BlY2lmaWVkIGJvb2xlYW4tdmFsdWVkIGF0dHJpYnV0ZSBvZiB0aGlzCgkgKiBlbGVtZW50LgoJICogCgkgKiBAcGFyYW0gaWQgdGhlIGF0dHJpYnV0ZSBpZAoJICogQHBhcmFtIHZhbHVlIHRoZSB2YWx1ZSBvZiB0aGUgc3BlY2lmaWVkIGF0dHJpYnV0ZQoJICogQHNlZSAjZ2V0QXR0cmlidXRlKFN0cmluZywgYm9vbGVhbikKCSAqLwoJcHJvdGVjdGVkIGZpbmFsIHZvaWQgc2V0QXR0cmlidXRlKFN0cmluZyBpZCwgYm9vbGVhbiB2YWx1ZSkgewoJCXNlcnZlcldDLnNldEF0dHJpYnV0ZShpZCwgdmFsdWUpOwoJfQoKCS8qKgoJICogU2V0cyB0aGUgdmFsdWUgb2YgdGhlIHNwZWNpZmllZCBzdHJpbmctdmFsdWVkIGF0dHJpYnV0ZSBvZiB0aGlzCgkgKiBlbGVtZW50LgoJICogCgkgKiBAcGFyYW0gaWQgdGhlIGF0dHJpYnV0ZSBpZAoJICogQHBhcmFtIHZhbHVlIHRoZSB2YWx1ZSBvZiB0aGUgc3BlY2lmaWVkIGF0dHJpYnV0ZQoJICogQHNlZSAjZ2V0QXR0cmlidXRlKFN0cmluZywgU3RyaW5nKQoJICovCglwcm90ZWN0ZWQgZmluYWwgdm9pZCBzZXRBdHRyaWJ1dGUoU3RyaW5nIGlkLCBTdHJpbmcgdmFsdWUpIHsKCQlzZXJ2ZXJXQy5zZXRBdHRyaWJ1dGUoaWQsIHZhbHVlKTsKCX0KCgkvKioKCSAqIFNldHMgdGhlIHZhbHVlIG9mIHRoZSBzcGVjaWZpZWQgbGlzdC12YWx1ZWQgYXR0cmlidXRlIG9mIHRoaXMKCSAqIGVsZW1lbnQuIFRoZSBsaXN0IG1heSBvbmx5IGNvbnRhaW4gU3RyaW5nIHZhbHVlcy4KCSAqIAoJICogQHBhcmFtIGlkIHRoZSBhdHRyaWJ1dGUgaWQKCSAqIEBwYXJhbSB2YWx1ZSB0aGUgdmFsdWUgb2YgdGhlIHNwZWNpZmllZCBhdHRyaWJ1dGUKCSAqIEBzZWUgI2dldEF0dHJpYnV0ZShTdHJpbmcsIExpc3QpCgkgKi8KCXByb3RlY3RlZCBmaW5hbCB2b2lkIHNldEF0dHJpYnV0ZShTdHJpbmcgaWQsIExpc3QgdmFsdWUpIHsKCQlzZXJ2ZXJXQy5zZXRBdHRyaWJ1dGUoaWQsIHZhbHVlKTsKCX0KCgkvKioKCSAqIFNldHMgdGhlIHZhbHVlIG9mIHRoZSBzcGVjaWZpZWQgbWFwLXZhbHVlZCBhdHRyaWJ1dGUgb2YgdGhpcwoJICogZWxlbWVudC4gVGhlIG1hcCBtYXkgb25seSBjb250YWluIFN0cmluZyB2YWx1ZXMuCgkgKiAKCSAqIEBwYXJhbSBpZCB0aGUgYXR0cmlidXRlIGlkCgkgKiBAcGFyYW0gdmFsdWUgdGhlIHZhbHVlIG9mIHRoZSBzcGVjaWZpZWQgYXR0cmlidXRlCgkgKiBAc2VlICNnZXRBdHRyaWJ1dGUoU3RyaW5nLCBNYXApCgkgKi8KCXByb3RlY3RlZCBmaW5hbCB2b2lkIHNldEF0dHJpYnV0ZShTdHJpbmcgaWQsIE1hcCB2YWx1ZSkgewoJCXNlcnZlcldDLnNldEF0dHJpYnV0ZShpZCwgdmFsdWUpOwoJfQoKCS8qKgoJICogTW9kaWZpZXMgdGhlIGxpc3Qgb2YgbW9kdWxlcyBhc3NvY2lhdGVkIHdpdGggdGhlIHNlcnZlci4KCSAqIFNlZSB0aGUgc3BlY2lmaWNhdGlvbiBvZgoJICoge0BsaW5rIElTZXJ2ZXJXb3JraW5nQ29weSNtb2RpZnlNb2R1bGVzKElNb2R1bGVbXSwgSU1vZHVsZVtdLCBJUHJvZ3Jlc3NNb25pdG9yKX0KCSAqIGZvciBmdXJ0aGVyIGRldGFpbHMuCgkgKiA8cD4KCSAqIFRoaXMgbWV0aG9kIGlzIGNhbGxlZCBieSB0aGUgd2ViIHNlcnZlciBjb3JlIGZyYW1ld29yaywKCSAqIGluIHJlc3BvbnNlIHRvIGEgY2FsbCB0byA8Y29kZT5JU2VydmVyV29ya2luZ0NvcHkubW9kaWZ5TW9kdWxlczwvY29kZT4uCgkgKiBDbGllbnRzIHNob3VsZCBuZXZlciBjYWxsIHRoaXMgbWV0aG9kLgoJICogPC9wPgoJICogPHA+CgkgKiBUaGlzIG1ldGhvZCBpcyBjYWxsZWQgdG8gdXBkYXRlIHRoZSBzZXJ2ZXIgY29uZmlndXJhdGlvbiAoaWYgYW55KQoJICogb3IgdXBkYXRlIHRoZSBkZWxlZ2F0ZXMgaW50ZXJuYWwgc3RhdGUuIE5vdGUgdGhhdCB0aGUgYWN0dWFsIGxpc3QKCSAqIG9mIG1vZHVsZXMgaXMgc3RvcmVkIG9uIHRoZSBzZXJ2ZXIgYW5kIGNhbiBiZSBhY2Nlc3NlZCBhdCBhbnkgdGltZQoJICogdXNpbmcgc2VydmVyLmdldE1vZHVsZXMoKS4gZ2V0TW9kdWxlcygpIHdpbGwgbm90IGJlIHVwZGF0ZWQgdW50aWwKCSAqIGFmdGVyIHRoaXMgbWV0aG9kIHN1Y2Nlc3NmdWxseSByZXR1cm5zLgoJICogPC9wPgoJICogPHA+CgkgKiBUaGlzIG1ldGhvZCB3aWxsIG5vdCBjb21tdW5pY2F0ZSB3aXRoIHRoZSBzZXJ2ZXIuIEFmdGVyIHNhdmluZywKCSAqIHB1Ymxpc2goKSBjYW4gYmUgdXNlZCB0byBzeW5jIHVwIHdpdGggdGhlIHNlcnZlci4KCSAqIDwvcD4KCSAqCgkgKiBAcGFyYW0gYWRkIGEgcG9zc2libHktZW1wdHkgbGlzdCBvZiBtb2R1bGVzIHRvIGFkZAoJICogQHBhcmFtIHJlbW92ZSBhIHBvc3NpYmx5LWVtcHR5IGxpc3Qgb2YgbW9kdWxlcyB0byByZW1vdmUKCSAqIEBwYXJhbSBtb25pdG9yIGEgcHJvZ3Jlc3MgbW9uaXRvciwgb3IgPGNvZGU+bnVsbDwvY29kZT4gaWYgcHJvZ3Jlc3MKCSAqICAgIHJlcG9ydGluZyBhbmQgY2FuY2VsbGF0aW9uIGFyZSBub3QgZGVzaXJlZAoJICogQHRocm93cyBDb3JlRXhjZXB0aW9uIFttaXNzaW5nXQoJICovCglwdWJsaWMgYWJzdHJhY3Qgdm9pZCBtb2RpZnlNb2R1bGVzKElNb2R1bGVbXSBhZGQsIElNb2R1bGVbXSByZW1vdmUsIElQcm9ncmVzc01vbml0b3IgbW9uaXRvcikgdGhyb3dzIENvcmVFeGNlcHRpb247CgoJLyoqCgkgKiBUaGlzIG1ldGhvZCBpcyBjYWxsZWQgdG8gaW1wb3J0IHRoZSBzZXJ2ZXIgY29uZmlndXJhdGlvbiBmcm9tIHRoZSBnaXZlbgoJICogcnVudGltZS4KCSAqIAoJICogQHBhcmFtIHJ1bnRpbWUgYSBzZXJ2ZXIgcnVudGltZQoJICogQHBhcmFtIG1vbml0b3IgYSBwcm9ncmVzcyBtb25pdG9yLCBvciA8Y29kZT5udWxsPC9jb2RlPiBpZiBwcm9ncmVzcwoJICogICAgcmVwb3J0aW5nIGFuZCBjYW5jZWxsYXRpb24gYXJlIG5vdCBkZXNpcmVkCgkgKi8KCXB1YmxpYyB2b2lkIGltcG9ydENvbmZpZ3VyYXRpb24oSVJ1bnRpbWUgcnVudGltZSwgSVByb2dyZXNzTW9uaXRvciBtb25pdG9yKSB7CgkJLy8gZG8gbm90aGluZwoJfQoKCS8qKgoJICogVGhpcyBtZXRob2QgaXMgY2FsbGVkIHdoZW5ldmVyIHRoZSBzZXJ2ZXIgY29uZmlndXJhdGlvbiBzaG91bGQgYmUgc2F2ZWQuCgkgKiAKCSAqIEBwYXJhbSBtb25pdG9yIGEgcHJvZ3Jlc3MgbW9uaXRvciwgb3IgPGNvZGU+bnVsbDwvY29kZT4gaWYgcHJvZ3Jlc3MKCSAqICAgIHJlcG9ydGluZyBhbmQgY2FuY2VsbGF0aW9uIGFyZSBub3QgZGVzaXJlZAoJICogQHRocm93cyBDb3JlRXhjZXB0aW9uIGlmIHRoZXJlIHdhcyBhIHByb2JsZW0gc2F2aW5nCgkgKi8KCXB1YmxpYyB2b2lkIHNhdmVDb25maWd1cmF0aW9uKElQcm9ncmVzc01vbml0b3IgbW9uaXRvcikgdGhyb3dzIENvcmVFeGNlcHRpb24gewoJCS8vIGRvIG5vdGhpbmcKCX0KCgkvKioKCSAqIFRoaXMgbWV0aG9kIGlzIGNhbGxlZCB3aGVuZXZlciB0aGUgc2VydmVyIGNvbmZpZ3VyYXRpb24gZm9sZGVyIGhhcyBjaGFuZ2VkLgoJICogSXQgZ2l2ZXMgdGhlIHNlcnZlciBhIGNoYW5jZSB0byB0aHJvdyBvdXQgYW55IG9sZCBkYXRhIGFuZCBiZSByZWFkeSB0bwoJICogcmVsb2FkIHRoZSBzZXJ2ZXIgY29uZmlndXJhdGlvbiB3aGVuIGl0IGlzIG5lZWRlZCBuZXh0LgoJICovCglwdWJsaWMgdm9pZCBjb25maWd1cmF0aW9uQ2hhbmdlZCgpIHsKCQkvLyBkbyBub3RoaW5nCgl9Cn0=