fn4gPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0Kfn4gTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZQp+fiBvciBtb3JlIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUKfn4gZGlzdHJpYnV0ZWQgd2l0aCB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24Kfn4gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZQp+fiB0byB5b3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlCn5+ICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2UKfn4gd2l0aCB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAp+fiAKfn4gICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKfn4gCn5+IFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywKfn4gc29mdHdhcmUgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4Kfn4gIkFTIElTIiBCQVNJUywgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZCn5+IEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuICBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZQp+fiBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kIGxpbWl0YXRpb25zCn5+IHVuZGVyIHRoZSBMaWNlbnNlLgp+fiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQp+fiAKfn4gVGhpcyBzb2Z0d2FyZSBjb25zaXN0cyBvZiB2b2x1bnRhcnkgY29udHJpYnV0aW9ucyBtYWRlIGJ5IG1hbnkKfn4gaW5kaXZpZHVhbHMgb24gYmVoYWxmIG9mIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbi4gIEZvciBtb3JlCn5+IGluZm9ybWF0aW9uIG9uIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiwgcGxlYXNlIHNlZQp+fiA8aHR0cDovL3d3dy5hcGFjaGUub3JnLz4uCgogICAgLS0tLS0tLS0tLQogICAgSHR0cENvbXBvbmVudHMgUHJvamVjdCBDaGFydGVyCiAgICAtLS0tLS0tLS0tCiAgICAtLS0tLS0tLS0tCiAgICAtLS0tLS0tLS0tCgp+fiBUaGUgQ2hhcnRlciB3YXMgYXBwcm92ZWQgYnkgYSBQTUMgdm90ZSBlbmRpbmcgb24gMjAwOC0wMi0wOS4Kfn4gQ2hhbmdlcyB0byB0aGUgQ2hhcnRlciByZXF1aXJlIFBNQyBhcHByb3ZhbC4Kfn4gRE8gTk9UIEVESVQgdGhlICJDaGFydGVyIiBzZWN0aW9uLCBub3QgZXZlbiB0byBmaXggdHlwb3MuCgp7Q2hhcnRlcn0KCiAgVGhlIEFwYWNoZSBIdHRwQ29tcG9uZW50cyBwcm9qZWN0IGlzIHJlc3BvbnNpYmxlIGZvciBjcmVhdGluZyBhbmQKICBtYWludGFpbmluZyBhIHRvb2xzZXQgb2YgbG93IGxldmVsIEphdmEgY29tcG9uZW50cyBmb2N1c2VkIG9uIEhUVFAKICBhbmQgYXNzb2NpYXRlZCBwcm90b2NvbHMuCgogIFdlIGRldmVsb3AgYW5kIG1haW50YWluIGEgY29tcG9uZW50IGNhbGxlZCA8PEh0dHBDb3JlPj4sIHdoaWNoIGFkZHJlc3NlcwogIHRoZSBiYXNpYyBuZWVkcyBmb3IgY29tbXVuaWNhdGluZyB2aWEgSFRUUCBvbiB0aGUgY2xpZW50IGFuZCBzZXJ2ZXIgc2lkZS4KICBIdHRwQ29yZSBkZWZpbmVzIGEgZnJhbWV3b3JrIGZvciBleHRlbmRpbmcgdGhlIHByb3ZpZGVkIGZ1bmN0aW9uYWxpdHkKICBiZXlvbmQgdGhlIGJhc2ljIG5lZWRzLgoKICBXZSBkZXZlbG9wIGFuZCBtYWludGFpbiBhIGNvbXBvbmVudCBjYWxsZWQgPDxIdHRwQ2xpZW50Pj4sIHdoaWNoIGJ1aWxkcwogIG9uIEh0dHBDb3JlIGFuZCBhZGRzIGZ1bmN0aW9uYWxpdHkgdHlwaWNhbGx5IHJlcXVpcmVkIGZvciBjbGllbnQtc2lkZQogIEhUVFAgY29tbXVuaWNhdGlvbi4gSW4gcGFydGljdWxhciwgSHR0cENsaWVudCBhZGRzIHN1cHBvcnQgZm9yIGNvb2tpZXMsCiAgYXV0aGVudGljYXRpb24sIGFuZCBjbGllbnQtc2lkZSBjb25uZWN0aW9uIG1hbmFnZW1lbnQuCgogIDw8SHR0cENvcmU+PiBhbmQgPDxIdHRwQ2xpZW50Pj4gYXJlIGF0IHRoZSBjZW50ZXIgb2YgdGhlCiAgQXBhY2hlIEh0dHBDb21wb25lbnRzIHByb2plY3QuIEFsbCBvdGhlciBhY3Rpdml0aWVzIG9yYml0IGFyb3VuZCB0aGlzIGR1by4KCiAgV2UgbWFpbnRhaW4gdGhlIGNvZGViYXNlIG9mIHRoZSBKYWthcnRhIENvbW1vbnMgSHR0cENsaWVudCwgYWxzbyBrbm93biBhcwogIENvbW1vbnMgSHR0cENsaWVudCAzLjEsIHVudGlsIHN1Y2ggdGltZSB0aGF0IHRoZSBuZXcgSHR0cENsaWVudCBiYXNlZCBvbgogIEh0dHBDb3JlIGlzIGNvbnNpZGVyZWQgcmVhZHkgZm9yIHVzZSBpbiBwcm9kdWN0aW9uIHN5c3RlbXMuCgogIFdlIGFyZSBsb29raW5nIGZvciBuZXcgY29tcG9uZW50cyB0aGF0IGJ1aWxkIHVwb24gYW5kIGV4dGVuZCB0aGUKICBmdW5jdGlvbmFsaXR5IG9mIHRoZSBleGlzdGluZyBvbmVzLgogIFdlIGFyZSBhbHNvIGxvb2tpbmcgZm9yIG5ldyBjb21wb25lbnRzIHRoYXQgY29tcGxlbWVudCB0aGUKICBmdW5jdGlvbmFsaXR5IG9mIHRoZSBleGlzdGluZyBvbmVzIGFuZCBtYWtlIHRoZW0gbW9yZSB1c2VmdWwKICBvciBlYXNpZXIgdG8gdXNlLgoKICBXZSBhcmUgb3BlbiB0byBnaXZlIGEgaG9tZSB0byBhcHBsaWNhdGlvbnMgdGhhdCBkZXJpdmUgYSBzaWduaWZpY2FudCBwYXJ0CiAgb2YgdGhlaXIgZnVuY3Rpb25hbGl0eSBmcm9tIG91ciBjb21wb25lbnRzLCBpZiBhcHByb2FjaGVkIGJ5IHN1Y2ggcHJvamVjdHMuCgp+fgp+fiBlbmQgb2YgdGhlICJDaGFydGVyIiBzZWN0aW9uIHRoYXQgbXVzdCBub3QgYmUgZWRpdGVkIHdpdGhvdXQgUE1DIGFwcHJvdmFsCn5+CgoKe0hpc3Rvcnl9CgogIFRoZSBoaXN0b3J5IG9mIHRoZSBIdHRwQ29tcG9uZW50cyBzdGFydHMgd2l0aCB0aGUgbm93IHJldGlyZWQKICB7e3todHRwOi8vamFrYXJ0YS5hcGFjaGUub3JnL3NsaWRlL31KYWthcnRhIFNsaWRlfX0gcHJvamVjdC4KICBTbGlkZSB3YXMgYSBXZWJEQVYgc2VydmVyIGluY2x1ZGluZyBhIGNsaWVudCBjb21wb25lbnQsIGFuZCB0aGUKICBXZWJEQVYgcHJvdG9jb2wgYnVpbGRzIG9uIEhUVFAuIFRoZXJlIHdhcyBpbnRlcmVzdCBpbiB1c2luZyB0aGUKICBjbGllbnQtc2lkZSBIVFRQIGltcGxlbWVudGF0aW9uIGluZGVwZW5kZW50bHkgb2YgU2xpZGUuCiAgVGhlIGNvZGUgd2FzIHNwdW4gb2ZmIGZyb20gU2xpZGUgaW4gMjAwMSB0byBiZWNvbWUgdGhlIEh0dHBDbGllbnQKICBzdWJwcm9qZWN0IG9mIHRoZSBKYWthcnRhIENvbW1vbnMuCgogIFNpbmNlIGl0IGdlbmVyYXRlZCBhIGRpc3Byb3BvcnRpb25hbCBhbW91bnQgb2YgdHJhZmZpYyBvbiB0aGUKICBDb21tb25zIG1haWxpbmcgbGlzdHMsIEh0dHBDbGllbnQgYWN0aXZpdHkgd2FzIG1vdmVkIHRvIHNlcGFyYXRlCiAgbWFpbGluZyBsaXN0cy4gVGhpcyBzdGFydGVkIHRoZSBkaXNzb2NpYXRpb24gb2YgSHR0cENsaWVudCBmcm9tCiAgQ29tbW9ucywgd2hpY2ggY29udGludWVkIHdoZW4gSHR0cENsaWVudCB3YXMgcHJvbW90ZWQgdG8gdGhlCiAgSmFrYXJ0YSBzdWJwcm9qZWN0IGxldmVsIGluIDIwMDQuCiAgVGhlIGxhdHRlciBldmVudCBpcyByZWNvcmRlZCBhcyB0aGUgb2xkZXN0IHt7ey4vbmV3cy5odG1sfU5ld3N9fSBpdGVtCiAgb2YgdGhlIEh0dHBDb21wb25lbnRzIHByb2plY3QuCgogIFRoZSBzaG9ydGNvbWluZ3MgaW4gdGhlIGRlc2lnbiBvZiBIdHRwQ2xpZW50LCBhcyBleHBsYWluZWQgaW4gdGhlCiAge3t7Li9jb21tb25zLWh0dHBjbGllbnQtbGVzc29ucy5odG1sfUxlc3NvbnMgTGVhcm5lZH19LAogIGNyZWF0ZWQgaW50ZXJlc3QgaW4gcmVkZXNpZ25pbmcgdGhlIEFQSSBmcm9tIHNjcmF0Y2guIFRvIHRoYXQgZW5kLCB0aGUKICBKYWthcnRhIEh0dHBDb21wb25lbnRzIHByb2plY3QgcmVwbGFjZWQgdGhlIEh0dHBDbGllbnQgcHJvamVjdCBpbiAyMDA1LgogIFRoZSBuZXcgcHJvamVjdCB3YXMgY2hhcmdlZCB3aXRoIHRoZSB0YXNrcyBvZiBkZXZlbG9waW5nIGEgc3VjY2Vzc29yCiAgdG8gSHR0cENsaWVudCAzLngsIGFuZCBvZiBtYWludGFpbmluZyB0aGUgZXhpc3RpbmcgY29kZWJhc2UgdW50aWwgdGhlCiAgbmV3IG9uZSBpcyByZWFkeSB0byB0YWtlIG92ZXIuCgogIFRoZSB7e3todHRwOi8vY29tbW9ucy5hcGFjaGUub3JnL31Db21tb25zfX0sIGNyYWRsZSBvZiBIdHRwQ2xpZW50LAogIGxlZnQgSmFrYXJ0YSBpbiAyMDA3IHRvIGJlY29tZSBhbiBpbmRlcGVuZGVudCBUb3AgTGV2ZWwgUHJvamVjdC4KICBMYXRlciBpbiB0aGUgc2FtZSB5ZWFyLCB0aGUgSHR0cENvbXBvbmVudHMgcHJvamVjdCBhbHNvIGxlZnQgSmFrYXJ0YQogIHRvIGJlY29tZSBhbiBpbmRlcGVuZGVudCBUb3AgTGV2ZWwgUHJvamVjdCwgdGFraW5nIHRoZSByZXNwb25zaWJpbGl0eQogIGZvciBtYWludGFpbmluZyBIdHRwQ2xpZW50IDMueCB3aXRoIGl0LgogIE91ciBUTFAgcmVzb2x1dGlvbiBpcyBwcmVzZW50ZWQgYmVsb3cuCgoKe1Jlc29sdXRpb259CgogIFRoZSBBcGFjaGUgSHR0cENvbXBvbmVudHMgcHJvamVjdCB3YXMgZXN0YWJsaXNoZWQKICBhcyBhbiBBcGFjaGUgdG9wIGxldmVsIHByb2plY3QgaW4gTm92ZW1iZXIgMjAwNywKICB3aGVuIHRoZSBBcGFjaGUgQm9hcmQgYXBwcm92ZWQgdGhlIGZvbGxvd2luZyByZXNvbHV0aW9uOgoKfn4gVGhlIGZvbGxvd2luZyBpcyBhIHZlcmJhdGltIGNvcHkgb2YgdGhlIFRMUCByZXNvbHV0aW9uLgp+fiBETyBOT1QgRURJVCwgbm90IGV2ZW4gdG8gZml4IHR5cG9zCi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQpFc3RhYmxpc2ggdGhlIEFwYWNoZSBIdHRwQ29tcG9uZW50cyBwcm9qZWN0CgpXSEVSRUFTLCB0aGUgQm9hcmQgb2YgRGlyZWN0b3JzIGRlZW1zIGl0IHRvIGJlIGluIHRoZSBiZXN0IGludGVyZXN0cyBvZiB0aGUgRm91bmRhdGlvbiBhbmQKY29uc2lzdGVudCB3aXRoIHRoZSBGb3VuZGF0aW9uJ3MgcHVycG9zZSB0byBlc3RhYmxpc2ggYSBQcm9qZWN0IE1hbmFnZW1lbnQgQ29tbWl0dGVlIGNoYXJnZWQgd2l0aAp0aGUgY3JlYXRpb24gYW5kIG1haW50ZW5hbmNlIG9mIG9wZW4tc291cmNlIHNvZnR3YXJlIHJlbGF0ZWQgdG8gYSB0b29sc2V0IG9mIGxvdyBsZXZlbCBKYXZhCmNvbXBvbmVudHMgZm9jdXNlZCBvbiBIVFRQIGFuZCBhc3NvY2lhdGVkIHByb3RvY29scywgYW5kIG9mIGFwcGxpY2F0aW9ucyBiYXNlZCBvbiB0aGVzZSBjb21wb25lbnRzLApmb3IgZGlzdHJpYnV0aW9uIGF0IG5vIGNoYXJnZSB0byB0aGUgcHVibGljLgoKTk9XLCBUSEVSRUZPUkUsIEJFIElUIFJFU09MVkVELCB0aGF0IGEgUHJvamVjdCBNYW5hZ2VtZW50IENvbW1pdHRlZSAoUE1DKSwgdG8gYmUga25vd24gYXMgIkFwYWNoZQpIdHRwQ29tcG9uZW50cyBQcm9qZWN0IiwgYmUgYW5kIGhlcmVieSBpcyBlc3RhYmxpc2hlZCBwdXJzdWFudCB0byBCeWxhd3Mgb2YgdGhlIEZvdW5kYXRpb247IGFuZCBiZQppdCBmdXJ0aGVyCgpSRVNPTFZFRCwgdGhhdCB0aGUgQXBhY2hlIEh0dHBDb21wb25lbnRzIFByb2plY3QgYmUgYW5kIGhlcmVieSBpcyByZXNwb25zaWJsZSBmb3IgdGhlIGNyZWF0aW9uIGFuZAptYWludGVuYW5jZSBvZiBhIHRvb2xzZXQgb2YgbG93IGxldmVsIEphdmEgY29tcG9uZW50cyBmb2N1c2VkIG9uIEhUVFAgYW5kIGFzc29jaWF0ZWQgcHJvdG9jb2xzLCBhbmQKb2YgYXBwbGljYXRpb25zIGJhc2VkIG9uIHRoZXNlIGNvbXBvbmVudHM7IGFuZCBiZSBpdCBmdXJ0aGVyCgpSRVNPTFZFRCwgdGhhdCB0aGUgb2ZmaWNlIG9mICJWaWNlIFByZXNpZGVudCwgQXBhY2hlIEh0dHBDb21wb25lbnRzIiBiZSBhbmQgaGVyZWJ5IGlzIGNyZWF0ZWQsIHRoZQpwZXJzb24gaG9sZGluZyBzdWNoIG9mZmljZSB0byBzZXJ2ZSBhdCB0aGUgZGlyZWN0aW9uIG9mIHRoZSBCb2FyZCBvZiBEaXJlY3RvcnMgYXMgdGhlIGNoYWlyIG9mIHRoZQpBcGFjaGUgSHR0cENvbXBvbmVudHMgUHJvamVjdCwgYW5kIHRvIGhhdmUgcHJpbWFyeSByZXNwb25zaWJpbGl0eSBmb3IgbWFuYWdlbWVudCBvZiB0aGUgcHJvamVjdHMKd2l0aGluIHRoZSBzY29wZSBvZiByZXNwb25zaWJpbGl0eSBvZiB0aGUgQXBhY2hlIEh0dHBDb21wb25lbnRzIFByb2plY3Q7IGFuZCBiZSBpdCBmdXJ0aGVyCgpSRVNPTFZFRCwgdGhhdCB0aGUgcGVyc29ucyBsaXN0ZWQgaW1tZWRpYXRlbHkgYmVsb3cgYmUgYW5kIGhlcmVieSBhcmUgYXBwb2ludGVkIHRvIHNlcnZlIGFzIHRoZQppbml0aWFsIG1lbWJlcnMgb2YgdGhlIEFwYWNoZSBIdHRwQ29tcG9uZW50cyBQcm9qZWN0OgoKICAgICogT2xlZyBLYWxuaWNoZXZza2kgPG9sZWdrIEFUIGFwYWNoZSBET1Qgb3JnPgogICAgKiBTZWJhc3RpYW4gQmF6bGV5IDxzZWJiIEFUIGFwYWNoZSBET1Qgb3JnPgogICAgKiBFcmlrIEFiZWxlIDxlcmlrYWJlbGUgQVQgYXBhY2hlIERPVCBvcmc+CiAgICAqIE9ydHdpbiBHbPxjayA8b2dsdWVjayBBVCBhcGFjaGUgRE9UIG9yZz4KICAgICogUm9sYW5kIFdlYmVyIDxyb2xhbmR3IEFUIGFwYWNoZSBET1Qgb3JnPgogICAgKiBBbnQgRWxkZXIgPGFudGVsZGVyIEFUIGFwYWNoZSBET1Qgb3JnPgogICAgKiBQYXVsIEZyZW1hbnRsZSA8cHpmIEFUIGFwYWNoZSBET1Qgb3JnPgogICAgKiBBc2Fua2hhIFBlcmVyYSA8YXNhbmtoYSBBVCBhcGFjaGUgRE9UIG9yZz4KCk5PVywgVEhFUkVGT1JFLCBCRSBJVCBGVVJUSEVSIFJFU09MVkVELCB0aGF0IEVyaWsgQWJlbGUgYmUgYXBwb2ludGVkIHRvIHRoZSBvZmZpY2Ugb2YgVmljZQpQcmVzaWRlbnQsIEFwYWNoZSBIdHRwQ29tcG9uZW50cywgdG8gc2VydmUgaW4gYWNjb3JkYW5jZSB3aXRoIGFuZCBzdWJqZWN0IHRvIHRoZSBkaXJlY3Rpb24gb2YgdGhlCkJvYXJkIG9mIERpcmVjdG9ycyBhbmQgdGhlIEJ5bGF3cyBvZiB0aGUgRm91bmRhdGlvbiB1bnRpbCBkZWF0aCwgcmVzaWduYXRpb24sIHJldGlyZW1lbnQsIHJlbW92YWwgb3IKZGlzcXVhbGlmaWNhdGlvbiwgb3IgdW50aWwgYSBzdWNjZXNzb3IgaXMgYXBwb2ludGVkOyBhbmQgYmUgaXQgZnVydGhlcgoKUkVTT0xWRUQsIHRoYXQgdGhlIEFwYWNoZSBIdHRwQ29tcG9uZW50cyBQcm9qZWN0IGJlIGFuZCBoZXJlYnkgaXMgdGFza2VkIHdpdGggdGhlIG1pZ3JhdGlvbiBhbmQKcmF0aW9uYWxpemF0aW9uIG9mIHRoZSBBcGFjaGUgSmFrYXJ0YSBIdHRwQ29tcG9uZW50cyBzdWJwcm9qZWN0OyBhbmQgYmUgaXQgZnVydGhlcgoKUkVTT0xWRUQsIHRoYXQgdGhlIEFwYWNoZSBIdHRwQ29tcG9uZW50cyBQcm9qZWN0IGJlIGFuZCBoZXJlYnkgaXMgdGFza2VkIHdpdGggdGhlIG1pZ3JhdGlvbiBhbmQKbWFpbnRlbmFuY2Ugb2YgdGhlIGNvZGViYXNlIGZvcm1lcmx5IGtub3duIGFzIEFwYWNoZSBKYWthcnRhIENvbW1vbnMgSHR0cENsaWVudCB1bnRpbCBpdCBpcwpvYnNvbGV0ZWQgYnkgdGhlIGNvbXBvbmVudHMgb2YgdGhlIEFwYWNoZSBIdHRwQ29tcG9uZW50cyBQcm9qZWN0OyBhbmQgYmUgaXQgZnVydGhlcgoKUkVTT0xWRUQsIHRoYXQgYWxsIHJlc3BvbnNpYmlsaXRpZXMgcGVydGFpbmluZyB0byB0aGUgQXBhY2hlIEpha2FydGEgSHR0cENvbXBvbmVudHMgc3VicHJvamVjdCBhbmQKdGhlIGZvcm1lciBBcGFjaGUgSmFrYXJ0YSBDb21tb25zIEh0dHBDbGllbnQgY29kZWJhc2UgZW5jdW1iZXJlZCB1cG9uIHRoZSBBcGFjaGUgSmFrYXJ0YSBQcm9qZWN0IGFyZQpoZXJlYWZ0ZXIgZGlzY2hhcmdlZC4KLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCgoK