PGh0bWw+CiAgPGhlYWQ+CiAgICA8bWV0YSBodHRwLWVxdWl2PSJDb250ZW50LUxhbmd1YWdlIiBjb250ZW50PSJlbi11cyI+CiAgICA8dGl0bGU+UHJvZ3JhbW1pbmcgU2VsZWN0b3JzIGluIEFudDwvdGl0bGU+CjxsaW5rIHJlbD0ic3R5bGVzaGVldCIgdHlwZT0idGV4dC9jc3MiIGhyZWY9Ii4uL3N0eWxlc2hlZXRzL2FudG1hbnVhbC5jc3MiPgogIDwvaGVhZD4KCiAgPGJvZHk+CiAgICA8aDI+UHJvZ3JhbW1pbmcgeW91ciBvd24gU2VsZWN0b3JzPC9oMj4KCiAgICA8aDM+U2VsZWN0b3IgUHJvZ3JhbW1pbmcgQVBJPC9oMz4KCiAgICA8cD5XYW50IHRvIGRlZmluZSB5b3VyIG93biBzZWxlY3RvcnM/IEl0J3MgZWFzeSE8L3A+CgogICAgPHA+Rmlyc3QsIHBpY2sgdGhlIHR5cGUgb2Ygc2VsZWN0b3IgdGhhdCB5b3Ugd2FudCB0byBkZWZpbmUuIFRoZXJlCiAgICBhcmUgdGhyZWUgdHlwZXMsIGFuZCBhIHJlY2lwZSBmb3IgZWFjaCBvbmUgZm9sbG93cy4gQ2hhbmNlcyBhcmUKICAgIHlvdSdsbCB3YW50IHRvIHdvcmsgd2l0aCB0aGUgZmlyc3Qgb25lLCBDdXN0b20gU2VsZWN0b3JzLjwvcD4KCiAgICA8b2w+CiAgICAgIDxsaT5DdXN0b20gU2VsZWN0b3JzCgogICAgICAgIDxwPlRoaXMgaXMgdGhlIGNhdGVnb3J5IHRoYXQgQW50IHByb3ZpZGVzIHNwZWNpZmljYWxseSBmb3IgeW91IHRvCiAgICAgICAgZGVmaW5lIHlvdXIgb3duIFNlbGVjdG9ycy4gQW55d2hlcmUgeW91IHdhbnQgdG8gdXNlIHlvdXIgc2VsZWN0b3IKICAgICAgICB5b3UgdXNlIHRoZSA8Y29kZT4mbHQ7Y3VzdG9tJmd0OzwvY29kZT4gZWxlbWVudCBhbmQgc3BlY2lmeQogICAgICAgIHRoZSBjbGFzcyBuYW1lIG9mIHlvdXIgc2VsZWN0b3Igd2l0aGluIGl0LiBTZWUgdGhlCiAgICAgICAgPGEgaHJlZj0ic2VsZWN0b3JzLmh0bWwjY3VzdG9tc2VsZWN0Ij5DdXN0b20gU2VsZWN0b3JzPC9hPgogICAgICAgIHNlY3Rpb24gb2YgdGhlIFNlbGVjdG9yIHBhZ2UgZm9yIGRldGFpbHMuIFRoZQogICAgICAgIDxjb2RlPiZsdDtjdXN0b20mZ3Q7PC9jb2RlPiBlbGVtZW50IGNhbiBiZSB1c2VkIGFueXdoZXJlCiAgICAgICAgdGhlIGNvcmUgc2VsZWN0b3JzIGNhbiBiZSB1c2VkLiBJdCBjYW4gYmUgY29udGFpbmVkIHdpdGhpbgogICAgICAgIDxhIGhyZWY9InNlbGVjdG9ycy5odG1sI3NlbGVjdGNvbnRhaW5lcnMiPlNlbGVjdG9yIENvbnRhaW5lcnM8L2E+LAogICAgICAgIGZvciBleGFtcGxlLjwvcD4KCiAgICAgICAgPHA+VG8gY3JlYXRlIGEgbmV3IEN1c3RvbSBTZWxlY3RvciwgeW91IGhhdmUgdG8gY3JlYXRlIGEgY2xhc3MgdGhhdAogICAgICAgIGltcGxlbWVudHMKICAgICAgICA8Y29kZT5vcmcuYXBhY2hlLnRvb2xzLmFudC50eXBlcy5zZWxlY3RvcnMuRXh0ZW5kRmlsZVNlbGVjdG9yPC9jb2RlPi4KICAgICAgICBUaGUgZWFzaWVzdCB3YXkgdG8gZG8gdGhhdCBpcyB0aHJvdWdoIHRoZSBjb252ZW5pZW5jZSBiYXNlIGNsYXNzCiAgICAgICAgPGNvZGU+b3JnLmFwYWNoZS50b29scy5hbnQudHlwZXMuc2VsZWN0b3JzLkJhc2VFeHRlbmRTZWxlY3RvcjwvY29kZT4sCiAgICAgICAgd2hpY2ggcHJvdmlkZXMgYWxsIG9mIHRoZSBtZXRob2RzIGZvciBzdXBwb3J0aW5nCiAgICAgICAgPGNvZGU+Jmx0O3BhcmFtJmd0OzwvY29kZT4gdGFncy4gRmlyc3QsIG92ZXJyaWRlIHRoZQogICAgICAgIDxjb2RlPmlzU2VsZWN0ZWQoKTwvY29kZT4gbWV0aG9kLCBhbmQgb3B0aW9uYWxseSB0aGUKICAgICAgICA8Y29kZT52ZXJpZnlTZXR0aW5ncygpPC9jb2RlPiBtZXRob2QuIElmIHlvdXIgY3VzdG9tCiAgICAgICAgc2VsZWN0b3IgcmVxdWlyZXMgcGFyYW1ldGVycyB0byBiZSBzZXQsIHlvdSBjYW4gYWxzbyBvdmVycmlkZQogICAgICAgIHRoZSA8Y29kZT5zZXRQYXJhbWV0ZXJzKCk8L2NvZGU+IG1ldGhvZCBhbmQgaW50ZXJwcmV0IHRoZQogICAgICAgIHBhcmFtZXRlcnMgdGhhdCBhcmUgcGFzc2VkIGluIGFueSB3YXkgeW91IGxpa2UuIFNldmVyYWwgb2YgdGhlCiAgICAgICAgY29yZSBzZWxlY3RvcnMgZGVtb25zdHJhdGUgaG93IHRvIGRvIHRoYXQgYmVjYXVzZSB0aGV5IGNhbgogICAgICAgIGFsc28gYmUgdXNlZCBhcyBjdXN0b20gc2VsZWN0b3JzLjwvcD4KCiAgICAgIDxsaT5Db3JlIFNlbGVjdG9ycwoKICAgICAgICA8cD5UaGVzZSBhcmUgdGhlIHNlbGVjdG9ycyB1c2VkIGJ5IEFudCBpdHNlbGYuIFRvIGltcGxlbWVudCBvbmUgb2YKICAgICAgICB0aGVzZSwgeW91IHdpbGwgaGF2ZSB0byBhbHRlciBzb21lIG9mIHRoZSBjbGFzc2VzIGNvbnRhaW5lZCB3aXRoaW4KICAgICAgICBBbnQuPC9wPgoKICAgICAgICA8dWw+CiAgICAgICAgICA8bGk+PHA+Rmlyc3QsIGNyZWF0ZSBhIGNsYXNzIHRoYXQgaW1wbGVtZW50cwogICAgICAgICAgICA8Y29kZT5vcmcuYXBhY2hlLnRvb2xzLmFudC50eXBlcy5zZWxlY3RvcnMuRmlsZVNlbGVjdG9yPC9jb2RlPi4KICAgICAgICAgICAgWW91IGNhbiBlaXRoZXIgY2hvb3NlIHRvIGltcGxlbWVudCBhbGwgbWV0aG9kcyB5b3Vyc2VsZiBmcm9tCiAgICAgICAgICAgIHNjcmF0Y2gsIG9yIHlvdSBjYW4gZXh0ZW5kCiAgICAgICAgICAgIDxjb2RlPm9yZy5hcGFjaGUudG9vbHMuYW50LnR5cGVzLnNlbGVjdG9ycy5CYXNlU2VsZWN0b3I8L2NvZGU+CiAgICAgICAgICAgIGluc3RlYWQsIGEgY29udmVuaWVuY2UgY2xhc3MgdGhhdCBwcm92aWRlcyByZWFzb25hYmxlIGRlZmF1bHQKICAgICAgICAgICAgYmVoYXZpb3VyIGZvciBtYW55IG1ldGhvZHMuPC9wPgoKICAgICAgICAgICAgPHA+VGhlcmUgaXMgb25seSBvbmUgbWV0aG9kIHJlcXVpcmVkLgogICAgICAgICAgICA8Y29kZT5wdWJsaWMgYm9vbGVhbiBpc1NlbGVjdGVkKEZpbGUgYmFzZWRpciwgU3RyaW5nIGZpbGVuYW1lLAogICAgICAgICAgICAgIEZpbGUgZmlsZSk8L2NvZGU+CiAgICAgICAgICAgICAgaXMgdGhlIHJlYWwgcHVycG9zZSBvZiB0aGUgd2hvbGUgZXhlcmNpc2UuIEl0IHJldHVybnMgdHJ1ZQogICAgICAgICAgICAgIG9yIGZhbHNlIGRlcGVuZGluZyBvbiB3aGV0aGVyIHRoZSBnaXZlbiBmaWxlIHNob3VsZCBiZQogICAgICAgICAgICAgIHNlbGVjdGVkIGZyb20gdGhlIGxpc3Qgb3Igbm90LjwvcD4KCiAgICAgICAgICAgIDxwPklmIHlvdSBhcmUgdXNpbmcKICAgICAgICAgICAgPGNvZGU+b3JnLmFwYWNoZS50b29scy5hbnQudHlwZXMuc2VsZWN0b3JzLkJhc2VTZWxlY3RvcjwvY29kZT4KICAgICAgICAgICAgdGhlcmUgYXJlIGFsc28gc29tZSBwcmVkZWZpbmVkIGJlaGF2aW91cnMgeW91IGNhbiB0YWtlIGFkdmFudGFnZQogICAgICAgICAgICBvZi4gQW55IHRpbWUgeW91IGVuY291bnRlciBhIHByb2JsZW0gd2hlbiBzZXR0aW5nIGF0dHJpYnV0ZXMgb3IKICAgICAgICAgICAgYWRkaW5nIHRhZ3MsIHlvdSBjYW4gY2FsbCBzZXRFcnJvcihTdHJpbmcgZXJybXNnKSBhbmQgdGhlIGNsYXNzCiAgICAgICAgICAgIHdpbGwga25vdyB0aGF0IHRoZXJlIGlzIGEgcHJvYmxlbS4gVGhlbiwgYXQgdGhlIHRvcCBvZiB5b3VyCiAgICAgICAgICAgIDxjb2RlPmlzU2VsZWN0ZWQoKTwvY29kZT4gbWV0aG9kIGNhbGwgPGNvZGU+dmFsaWRhdGUoKTwvY29kZT4gYW5kCiAgICAgICAgICAgIGEgQnVpbGRFeGNlcHRpb24gd2lsbCBiZSB0aHJvd24gd2l0aCB0aGUgY29udGVudHMgb2YgeW91ciBlcnJvcgogICAgICAgICAgICBtZXNzYWdlLiBUaGUgPGNvZGU+dmFsaWRhdGUoKTwvY29kZT4gbWV0aG9kIGFsc28gZ2l2ZXMgeW91IGEKICAgICAgICAgICAgbGFzdCBjaGFuY2UgdG8gY2hlY2sgeW91ciBzZXR0aW5ncyBmb3IgY29uc2lzdGVuY3kgYmVjYXVzZSBpdAogICAgICAgICAgICBjYWxscyA8Y29kZT52ZXJpZnlTZXR0aW5ncygpPC9jb2RlPi4gT3ZlcnJpZGUgdGhpcyBtZXRob2QgYW5kCiAgICAgICAgICAgIGNhbGwgPGNvZGU+c2V0RXJyb3IoKTwvY29kZT4gd2l0aGluIGl0IGlmIHlvdSBkZXRlY3QgYW55CiAgICAgICAgICAgIHByb2JsZW1zIGluIGhvdyB5b3VyIHNlbGVjdG9yIGlzIHNldCB1cC48L3A+CgogICAgICAgICAgICA8cD5Zb3UgbWF5IGFsc28gd2FudCB0byBvdmVycmlkZSA8Y29kZT50b1N0cmluZygpPC9jb2RlPi48L3A+CgogICAgICAgICAgPGxpPjxwPlB1dCBhbiA8Y29kZT5hZGQ8L2NvZGU+IG1ldGhvZCBmb3IgeW91ciBzZWxlY3RvciBpbgogICAgICAgICAgICA8Y29kZT5vcmcuYXBhY2hlLnRvb2xzLmFudC50eXBlcy5zZWxlY3RvcnMuU2VsZWN0b3JDb250YWluZXI8L2NvZGU+LgogICAgICAgICAgICBUaGlzIGlzIGFuIGludGVyZmFjZSwgc28geW91IHdpbGwgYWxzbyBoYXZlIHRvIGFkZCBhbiBpbXBsZW1lbnRhdGlvbgogICAgICAgICAgICBmb3IgdGhlIG1ldGhvZCBpbiB0aGUgY2xhc3NlcyB3aGljaCBpbXBsZW1lbnQgaXQsIG5hbWVseQogICAgICAgICAgICA8Y29kZT5vcmcuYXBhY2hlLnRvb2xzLmFudC50eXBlcy5BYnN0cmFjdEZpbGVTZXQ8L2NvZGU+LAogICAgICAgICAgICA8Y29kZT5vcmcuYXBhY2hlLnRvb2xzLmFudC50YXNrZGVmcy5NYXRjaGluZ1Rhc2s8L2NvZGU+IGFuZAogICAgICAgICAgICA8Y29kZT5vcmcuYXBhY2hlLnRvb2xzLmFudC50eXBlcy5zZWxlY3RvcnMuQmFzZVNlbGVjdG9yQ29udGFpbmVyPC9jb2RlPi4KICAgICAgICAgICAgT25jZSBpdCBpcyBpbiB0aGVyZSwgaXQgd2lsbCBiZSBhdmFpbGFibGUgZXZlcnl3aGVyZSB0aGF0IGNvcmUKICAgICAgICAgICAgc2VsZWN0b3JzIGFyZSBhcHByb3ByaWF0ZS48L3A+CiAgICAgICAgPC91bD4KCiAgICAgIDxsaT5TZWxlY3RvciBDb250YWluZXJzCiAgICAgICAgPHA+R290IGFuIGlkZWEgZm9yIGEgbmV3IFNlbGVjdG9yIENvbnRhaW5lcj8gQ3JlYXRpbmcgYSBuZXcgb25lIGlzCiAgICAgICAgbm8gcHJvYmxlbTo8L3A+CiAgICAgICAgPHVsPgogICAgICAgICAgPGxpPjxwPkNyZWF0ZSBhIG5ldyBjbGFzcyB0aGF0IGltcGxlbWVudHMKICAgICAgICAgICAgPGNvZGU+b3JnLmFwYWNoZS50b29scy5hbnQudHlwZXMuc2VsZWN0b3JzLlNlbGVjdG9yQ29udGFpbmVyPC9jb2RlPi4KICAgICAgICAgICAgVGhpcyB3aWxsIGVuc3VyZSB0aGF0IHlvdXIgbmV3CiAgICAgICAgICAgIENvbnRhaW5lciBjYW4gYWNjZXNzIGFueSBuZXcgc2VsZWN0b3JzIHRoYXQgY29tZSBhbG9uZy4gQWdhaW4sIHRoZXJlCiAgICAgICAgICAgIGlzIGEgY29udmVuaWVuY2UgY2xhc3MgYXZhaWxhYmxlIGZvciB5b3UgY2FsbGVkCiAgICAgICAgICAgIDxjb2RlPm9yZy5hcGFjaGUudG9vbHMuYW50LnR5cGVzLnNlbGVjdG9ycy5CYXNlU2VsZWN0b3JDb250YWluZXI8L2NvZGU+LgogICAgICAgICAgICA8L3A+CiAgICAgICAgICA8bGk+PHA+SW1wbGVtZW50IHRoZQogICAgICAgICAgICA8Y29kZT5wdWJsaWMgYm9vbGVhbiBpc1NlbGVjdGVkKFN0cmluZyBmaWxlbmFtZSwgRmlsZSBmaWxlKTwvY29kZT4KICAgICAgICAgICAgbWV0aG9kIHRvIGRvIHRoZSByaWdodCB0aGluZy4gQ2hhbmNlcyBhcmUgeW91J2xsIHdhbnQgdG8gaXRlcmF0ZQogICAgICAgICAgICBvdmVyIHRoZSBzZWxlY3RvcnMgdW5kZXIgeW91LCBzbyB1c2UKICAgICAgICAgICAgPGNvZGU+c2VsZWN0b3JFbGVtZW50cygpPC9jb2RlPiB0byBnZXQgYW4gaXRlcmF0b3IgdGhhdCB3aWxsIGRvCiAgICAgICAgICAgIHRoYXQuPC9wPgogICAgICAgICAgPGxpPjxwPkFnYWluLCBwdXQgYW4gPGNvZGU+YWRkPC9jb2RlPiBtZXRob2QgZm9yIHlvdXIgY29udGFpbmVyIGluCiAgICAgICAgICAgIDxjb2RlPm9yZy5hcGFjaGUudG9vbHMuYW50LnR5cGVzLnNlbGVjdG9ycy5TZWxlY3RvckNvbnRhaW5lcjwvY29kZT4KICAgICAgICAgICAgYW5kIGl0cyBpbXBsZW1lbnRhdGlvbnMKICAgICAgICAgICAgPGNvZGU+b3JnLmFwYWNoZS50b29scy5hbnQudHlwZXMuQWJzdHJhY3RGaWxlU2V0PC9jb2RlPiBhbmQKICAgICAgICAgICAgPGNvZGU+b3JnLmFwYWNoZS50b29scy5hbnQudHlwZXMuc2VsZWN0b3JzLkJhc2VTZWxlY3RvckNvbnRhaW5lcjwvY29kZT4uCiAgICAgICAgICAgIDwvcD4KICAgICAgICA8L3VsPgogICAgPC9vbD4KCiAgICA8aDM+VGVzdGluZyBTZWxlY3RvcnM8L2gzPgoKICAgIDxwPkZvciBhIHJvYnVzdCBjb21wb25lbnQgKGFuZCBzZWxlY3RvcnMgYXJlIChQcm9qZWN0KUNvbXBvbmVudLRzKSB0ZXN0cyBhcmUKICAgIG5lY2Vzc2FyeS4gRm9yIHRlc3RpbmcgVGFza3Mgd2UgdXNlIEpVbml0IFRlc3RDYXNlcyAtIG1vcmUgc3BlY2lmaWMKICAgIDx0dD5vcmcuYXBhY2hlLnRvb2xzLmFudC5CdWlsZEZpbGVUZXN0IGV4dGVuZHMganVuaXQuZnJhbWV3b3JrLlRlc3RDYXNlPC90dD4uCiAgICBTb21lIG9mIGl0cyBmZWF0dXJlcyBsaWtlIGNvbmZpZ3VyZSB0aGUgKHRlc3QpIHByb2plY3QgYnkgcmVhZGluZyBpdHMgYnVpbGRmaWxlIGFuZAogICAgZXhlY3V0ZSB0YXJnZXRzIHdlIG5lZWQgZm9yIHNlbGVjdG9yIHRlc3RzIGFsc28uIFRoZXJlZm9yZSB3ZSB1c2UgdGhhdCBCdWlsZEZpbGVUZXN0LgogICAgQnV0IHRlc3Rpbmcgc2VsZWN0b3JzIHJlcXVpcmVzIHNvbWUgbW9yZSB3b3JrOiBoYXZpbmcgYSBzZXQgb2YgZmlsZXMsIGluc3RhbnRpYXRlCiAgICBhbmQgY29uZmlndXJlIHRoZSBzZWxlY3RvciwgY2hlY2sgdGhlIHNlbGVjdGlvbiB3b3JrIGFuZCBtb3JlLiBCZWNhdXNlIHdlIHVzdWFsbHkKICAgIGV4dGVuZCA8dHQ+QmFzZUV4dGVuZFNlbGVjdG9yPC90dD4gaXRzIGZlYXR1cmVzIGhhdmUgdG8gYmUgdGVzdGVkIGFsc28gKGUuZy4gc2V0RXJyb3IoKSkuCiAgICA8L3A+CgogICAgPHA+VGhhdLRzIHdoeSB3ZSBoYXZlIGEgYmFzZSBjbGFzcyBmb3IgZG9pbmcgb3VyIHNlbGVjdG9yIHRlc3RzOgogICAgPHR0Pm9yZy5hcGFjaGUudG9vbHMuYW50LnR5cGVzLnNlbGVjdG9ycy5CYXNlU2VsZWN0b3JUZXN0PC90dD4uPC9wPgoKICAgIDxwPlRoaXMgY2xhc3MgZXh0ZW5kcyBUZXN0Q2FzZSBhbmQgdGhlcmVmb3JlIGNhbiBpbmNsdWRlZCBpbiB0aGUgc2V0IG9mIEFudLRzCiAgICB1bml0IHRlc3RzLiBJdCBob2xkcyBhbiBpbnN0YW5jZSBvZiBwcmVjb25maWd1cmVkIEJ1aWxkRmlsZVRlc3QuIENvbmZpZ3VyYXRpb24KICAgIGlzIGRvbmUgYnkgcGFyc2luZyB0aGUgc3JjL2V0Yy90ZXN0Y2FzZXMvdHlwZXMvc2VsZWN0b3JzLnhtbC4gQmFzZVNlbGVjdG9yVGVzdAogICAgdGhlbiBnaXZlcyB1cyBoZWxwZXIgbWV0aG9kcyBmb3IgaGFuZGxpbmcgbXVsdGlwbGUgc2VsZWN0aW9ucy4gPC9wPgoKICAgIDxwPkJlY2F1c2UgdGhlIHRlcm0gInRlc3RjYXNlIiBvciAidGVzdGVudmlyb25tZW50IiBhcmUgc28gb2Z0ZW4gdXNlZCwgdGhpcwogICAgc3BlY2lhbCB0ZXN0ZW52aXJvbm1lbnQgZ290IGEgbmV3IG5hbWU6IDxpPmJlZDwvaT4uIExpa2UgeW91IGluaXRpYWxpemUgdGhlCiAgICB0ZXN0IGVudmlyb25tZW50IGJ5IGNhbGxpbmcgc2V0VXAoKSBhbmQgY2xlYW5pbmcgYnkgY2FsbGluZyB0ZWFyRG93bigpICg8aT5vciBsaWtlCiAgICB0byBtYWtlIHlvdXIgYmVkIGJlZm9yZSBnbyBzbGVlcGluZzwvaT4pIHlvdSBoYXZlIHRvIGRvIHRoYXQgd29yayB3aXRoIHlvdXIKICAgIDxpPmJlZDwvaT4gYnkgY2FsbGluZyA8dHQ+bWFrZUJlZCgpPC90dD4gcmVzcGVjaXRpdmUgPHR0PmNsZWFudXBCZWQoKTwvdHQ+LjwvcD4KCiAgICA8cD5BIHVzdWFsIHRlc3Qgc2NlbmFyaW8gaXM8b2w+CiAgICAgICA8bGk+bWFrZSB0aGUgYmVkPC9saT4KICAgICAgIDxsaT5pbnN0YW50aWF0ZSB0aGUgc2VsZWN0b3I8L2xpPgogICAgICAgPGxpPmNvbmZpZ3VyZSB0aGUgc2VsZWN0b3I8L2xpPgogICAgICAgPGxpPmxldCB0aGUgc2VsZWN0b3IgZG8gc29tZSB3b3JrPC9saT4KICAgICAgIDxsaT52ZXJpZnkgdGhlIHdvcms8L2xpPgogICAgICAgPGxpPmNsZWFuIHRoZSBiZWQ8L2xpPgogICAgICAgPC9vbD4KICAgIDwvcD4KCiAgICA8cD5Gb3IgY29tbW9uIHdheSBvZiBpbnN0YW50aWF0aW9uIHlvdSBoYXZlIHRvIG92ZXJyaWRlIHRoZSA8dHQ+Z2V0SW5zdGFuY2UoKTwvdHQ+CiAgICBzaW1wbHkgYnkgcmV0dXJuaW5nIGEgbmV3IG9iamVjdCBvZiB5b3VyIHNlbGVjdG9yLiBGb3IgZWFzaWVyICJzZWxlY3Rpb24gYW5kIHZlcmlmaWNhdGlvbiB3b3JrIgogICAgQmFzZVNlbGVjdG9yVGVzdCBwcm92aWRlcyB0aGUgbWV0aG9kIDx0dD5wZXJmb3JtVGVzdHMoKTwvdHQ+IHdoaWNoCiAgICBpdGVyYXRlcyBvdmVyIGFsbCBmaWxlcyAoYW5kIGRpcmVjdG9yaWVzKSBpbiB0aGUgU3RyaW5nIGFycmF5IDx0dD5maWxlbmFtZXM8L3R0PgogICAgYW5kIGNoZWNrcyB3aGV0aGVyIHRoZSBnaXZlbiBzZWxlY3RvciByZXR1cm5zIHRoZSBleHBlY3RlZCByZXN1bHQuIElmIGFuIGVycm9yCiAgICBvY2N1cmVkIChlc3BlY2lhbGx5IHRoZSBzZWxlY3RvciBkb2VzIG5vdCByZXR1cm4gdGhlIGV4cGVjdGVkIHJlc3VsdCkgdGhlIHRlc3QKICAgIGZhaWxzIGFuZCB0aGUgZmFpbGluZyBmaWxlbmFtZXMgYXJlIGxvZ2dlZC48L3A+CgogICAgPHA+QW4gZXhhbXBsZSB0ZXN0IHdvdWxkIGJlOjxwcmU+CnBhY2thZ2Ugb3JnLmFwYWNoZS50b29scy5hbnQudHlwZXMuc2VsZWN0b3JzOwoKcHVibGljIGNsYXNzIE15U2VsZWN0b3JUZXN0IGV4dGVuZHMgQmFzZVNlbGVjdG9yVGVzdCB7CgogICAgcHVibGljIE15U2VsZWN0b3JUZXN0KFN0cmluZyBuYW1lKSB7CiAgICAgICAgc3VwZXIobmFtZSk7CiAgICB9CgogICAgcHVibGljIEJhc2VTZWxlY3RvciBnZXRJbnN0YW5jZSgpIHsKICAgICAgICByZXR1cm4gbmV3IE15U2VsZWN0b3IoKTsKICAgIH0KCiAgICBwdWJsaWMgdm9pZCB0ZXN0Q2FzZTEoKSB7CiAgICAgICAgdHJ5IHsKICAgICAgICAgICAgLy8gaW5pdGlhbGl6ZSB0ZXN0IGVudmlyb25tZW50ICdiZWQnCiAgICAgICAgICAgIG1ha2VCZWQoKTsKCiAgICAgICAgICAgIC8vIENvbmZpZ3VyZSB0aGUgc2VsZWN0b3IKICAgICAgICAgICAgTXlTZWxlY3RvciBzID0gKE15U2VsZWN0b3IpZ2V0U2VsZWN0b3IoKTsKICAgICAgICAgICAgcy5hZGRQYXJhbSgia2V5MSIsICJ2YWx1ZTEiKTsKICAgICAgICAgICAgcy5hZGRQYXJhbSgia2V5MiIsICJ2YWx1ZTIiKTsKICAgICAgICAgICAgcy5zZXRYWCh0cnVlKTsKICAgICAgICAgICAgcy5zZXRZWSgiYSB2YWx1ZSIpOwoKICAgICAgICAgICAgLy8gZG8gdGhlIHRlc3RzCiAgICAgICAgICAgIHBlcmZvcm1UZXN0cyhzLCAiRlRUVFRUVFRUVFRUIik7ICAvLyBGaXJzdCBpcyBub3Qgc2VsZWN0ZWQgLSByZXN0IGlzCgogICAgICAgIH0gZmluYWxseSB7CiAgICAgICAgICAgIC8vIGNsZWFudXAgdGhlIGVudmlyb25tZW50CiAgICAgICAgICAgIGNsZWFudXBCZWQoKTsKICAgICAgICB9CiAgICB9Cn0KICAgIDwvcHJlPgogICAgQXMgYW4gZXhhbXBsZSBvZiBhbiBlcnJvciBKVW5pdCBjb3VsZCBsb2c8cHJlPgogICAgW2p1bml0XSAgICAgRkFJTEVECiAgICBbanVuaXRdIEVycm9yIGZvciBmaWxlczogPGZvbnQgY29sb3I9Ymx1ZT4uO2NvcHkuZmlsdGVyc2V0LmZpbHRlcmVkO3Rhci9nei9hc2YtbG9nby5naWYudGFyLmd6PC9mb250PgogICAgW2p1bml0XSBleHBlY3RlZDombHQ7PGZvbnQgY29sb3I9Ymx1ZT5GVFRURlRUVEYuLi48L2ZvbnQ+PiBidXQgd2FzOiZsdDtUVFRUVFRUVFQuLi4+CiAgICBbanVuaXRdIGp1bml0LmZyYW1ld29yay5Db21wYXJpc29uRmFpbHVyZTogRXJyb3IgZm9yIGZpbGVzOiAuO2NvcHkuZmlsdGVyc2V0LmZpbHRlcmVkO3Rhci9nei9hc2YtbG9nby5naWYudGFyLmd6CiAgICBbanVuaXRdIGV4cGVjdGVkOiZsdDtGVFRURlRUVEYuLi4+IGJ1dCB3YXM6Jmx0O1RUVFRUVFRUVC4uLj4KICAgIFtqdW5pdF0gICAgIGF0IGp1bml0LmZyYW1ld29yay5Bc3NlcnQuYXNzZXJ0RXF1YWxzKEFzc2VydC5qYXZhOjgxKQogICAgW2p1bml0XSAgICAgYXQgb3JnLmFwYWNoZS50b29scy5hbnQudHlwZXMuc2VsZWN0b3JzLkJhc2VTZWxlY3RvclRlc3QucGVyZm9ybVRlc3QoQmFzZVNlbGVjdG9yVGVzdC5qYXZhOjE5NCkKICAgIDwvcHJlPjwvcD4KCiAgICA8cD5EZXNjcmliZWQgYWJvdmUgdGhlIHRlc3QgY2xhc3Mgc2hvdWxkIHByb3ZpZGUgYSA8dHQ+Z2V0SW5zdGFuY2UoKTwvdHQ+CiAgICBtZXRob2QuIEJ1dCB0aGF0IGlzbrR0IHVzZWQgaGVyZS4gVGhlIHVzZWQgPHR0PmdldFNlbGVjdG9yKCk8L3R0PiBtZXRob2QgaXMKICAgIGltcGxlbWVudGVkIGluIHRoZSBiYXNlIGNsYXNzIGFuZCBnaXZlcyBhbiBpbnN0YW5jZSBvZiBhbiBBbnQgUHJvamVjdCB0bwogICAgdGhlIHNlbGVjdG9yLiBUaGlzIGlzIHVzdWFsbHkgZG9uZSBpbnNpZGUgbm9ybWFsIGJ1aWxkIGZpbGUgcnVucywgYnV0IG5vdAogICAgaW5zaWRlIHRoaXMgc3BlY2lhbCBlbnZpcm9ubWVudCwgc28gdGhpcyBtZXRob2QgZ2l2ZXMgdGhlIHNlbGVjdG9yIHRoZQogICAgYWJpbGl0eSB0byB1c2UgaXRzIG93biBQcm9qZWN0IG9iamVjdCAoPHR0PmdldFByb2plY3QoKTwvdHQ+KSwgZm9yIGV4YW1wbGUKICAgIGZvciBsb2dnaW5nLjwvcD4KCgogICAgPGgzPkxvZ2dpbmc8L2gzPgoKICAgIDxwPkR1cmluZyBkZXZlbG9wbWVudCBhbmQgbWF5YmUgbGF0ZXIgeW91IHNvbWV0aW1lcyBuZWVkIHRoZSBvdXRwdXQgb2YgaW5mb3JtYXRpb24uCiAgICBUaGVyZWZvcmUgTG9nZ2luZyBpcyBuZWVkZWQuIEJlY2F1c2UgdGhlIHNlbGVjdG9yIGV4dGVuZHMgQmFzZUV4dGVuZFNlbGVjdG9yIG9yIGRpcmVjdGx5CiAgICBCYXNlU2VsZWN0b3IgaXQgaXMgYW4gQW50IDx0dD5EYXRhVHlwZTwvdHQ+IGFuZCB0aGVyZWZvcmUgYSA8dHQ+UHJvamVjdENvbXBvbmVudDwvdHQ+LiA8YnI+CiAgICBUaGF0IG1lYW5zIHRoYXQgeW91IGhhdmUgYWNjZXNzIHRvIHRoZSBwcm9qZWN0IG9iamVjdCBhbmQgaXRzIGxvZ2dpbmcgY2FwYWJpbGl0eS4KICAgIDx0dD5Qcm9qZWN0Q29tcG9uZW50PC90dD4gaXRzZWxmIHByb3ZpZGVzIDxpPmxvZzwvaT4gbWV0aG9kcyB3aGljaCB3aWxsIGRvIHRoZQogICAgYWNjZXNzIHRvIHRoZSBwcm9qZWN0IGluc3RhbmNlLiBMb2dnaW5nIGlzIHRoZXJlZm9yZSBkb25lIHNpbXBseSB3aXRoOgogICAgPHByZT4KICAgICAgICBsb2coICJtZXNzYWdlIiApOwogICAgPC9wcmU+CiAgICBvcgogICAgPHByZT4KICAgICAgICBsb2coICJtZXNzYWdlIiAsIGxvZ2xldmVsICk7CiAgICA8L3ByZT4KICAgIHdoZXJlIHRoZSA8dHQ+bG9nbGV2ZWw8L3R0PiBpcyBvbmUgb2YgdGhlIHZhbHVlcyA8dWw+CiAgICA8bGk+IG9yZy5hcGFjaGUudG9vbHMuYW50LlByb2plY3QuTVNHX0VSUiA8L2xpPgogICAgPGxpPiBvcmcuYXBhY2hlLnRvb2xzLmFudC5Qcm9qZWN0Lk1TR19XQVJOIDwvbGk+CiAgICA8bGk+IG9yZy5hcGFjaGUudG9vbHMuYW50LlByb2plY3QuTVNHX0lORk8gICg9IGRlZmF1bHQpIDwvbGk+CiAgICA8bGk+IG9yZy5hcGFjaGUudG9vbHMuYW50LlByb2plY3QuTVNHX1ZFUkJPU0UgPC9saT4KICAgIDxsaT4gb3JnLmFwYWNoZS50b29scy5hbnQuUHJvamVjdC5NU0dfREVCVUcgPC9saT4KICAgIDwvdWw+CiAgICA8L3A+CgogICAgPGhyPgogICAgPHAgYWxpZ249ImNlbnRlciI+Q29weXJpZ2h0ICZjb3B5OyAyMDAyLTIwMDMgQXBhY2hlIFNvZnR3YXJlCiAgICBGb3VuZGF0aW9uLiBBbGwgcmlnaHRzIFJlc2VydmVkLjwvcD4KICA8L2JvZHk+Cgo8L2h0bWw+Cg==