UEsDBAoAAAAAAOp4xzCNYR7iDgcAAA4HAAAcAAQAanVuaXQvYXd0dWkvUHJvZ3Jlc3NCYXIuamF2Yf7KAABwYWNrYWdlIGp1bml0LmF3dHVpOw0KDQppbXBvcnQgamF2YS5hd3QuKjsNCg0KcHVibGljIGNsYXNzIFByb2dyZXNzQmFyIGV4dGVuZHMgQ2FudmFzIHsNCglwdWJsaWMgYm9vbGVhbiBmRXJyb3I9IGZhbHNlOw0KCXB1YmxpYyBpbnQgZlRvdGFsPSAwOw0KCXB1YmxpYyBpbnQgZlByb2dyZXNzPSAwOw0KCXB1YmxpYyBpbnQgZlByb2dyZXNzWD0gMDsNCg0KCXB1YmxpYyBQcm9ncmVzc0JhcigpIHsNCgkJc3VwZXIoKTsNCgkJc2V0U2l6ZSgyMCwgMzApOw0KCX0NCgkNCglwcml2YXRlIENvbG9yIGdldFN0YXR1c0NvbG9yKCkgew0KCQlpZiAoZkVycm9yKQ0KCQkJcmV0dXJuIENvbG9yLnJlZDsNCgkJcmV0dXJuIENvbG9yLmdyZWVuOw0KCX0NCgkNCglwdWJsaWMgdm9pZCBwYWludChHcmFwaGljcyBnKSB7DQoJCXBhaW50QmFja2dyb3VuZChnKTsNCgkJcGFpbnRTdGF0dXMoZyk7DQoJfQ0KCQ0KCXB1YmxpYyB2b2lkIHBhaW50QmFja2dyb3VuZChHcmFwaGljcyBnKSB7DQoJCWcuc2V0Q29sb3IoU3lzdGVtQ29sb3IuY29udHJvbCk7DQoJCVJlY3RhbmdsZSByPSBnZXRCb3VuZHMoKTsNCgkJZy5maWxsUmVjdCgwLCAwLCByLndpZHRoLCByLmhlaWdodCk7DQoJCWcuc2V0Q29sb3IoQ29sb3IuZGFya0dyYXkpOw0KCQlnLmRyYXdMaW5lKDAsIDAsIHIud2lkdGgtMSwgMCk7DQoJCWcuZHJhd0xpbmUoMCwgMCwgMCwgci5oZWlnaHQtMSk7DQoJCWcuc2V0Q29sb3IoQ29sb3Iud2hpdGUpOw0KCQlnLmRyYXdMaW5lKHIud2lkdGgtMSwgMCwgci53aWR0aC0xLCByLmhlaWdodC0xKTsNCgkJZy5kcmF3TGluZSgwLCByLmhlaWdodC0xLCByLndpZHRoLTEsIHIuaGVpZ2h0LTEpOw0KCX0NCgkNCglwdWJsaWMgdm9pZCBwYWludFN0YXR1cyhHcmFwaGljcyBnKSB7DQoJCWcuc2V0Q29sb3IoZ2V0U3RhdHVzQ29sb3IoKSk7DQoJCVJlY3RhbmdsZSByPSBuZXcgUmVjdGFuZ2xlKDAsIDAsIGZQcm9ncmVzc1gsIGdldEJvdW5kcygpLmhlaWdodCk7DQoJCWcuZmlsbFJlY3QoMSwgMSwgci53aWR0aC0xLCByLmhlaWdodC0yKTsNCgl9DQoJDQoJcHJpdmF0ZSB2b2lkIHBhaW50U3RlcChpbnQgc3RhcnRYLCBpbnQgZW5kWCkgew0KCQlyZXBhaW50KHN0YXJ0WCwgMSwgZW5kWC1zdGFydFgsIGdldEJvdW5kcygpLmhlaWdodC0yKTsNCgl9DQoJDQoJcHVibGljIHZvaWQgcmVzZXQoKSB7DQoJCWZQcm9ncmVzc1g9IDE7DQoJCWZQcm9ncmVzcz0gMDsNCgkJZkVycm9yPSBmYWxzZTsNCgkJcGFpbnQoZ2V0R3JhcGhpY3MoKSk7DQoJfQ0KCQ0KCXB1YmxpYyBpbnQgc2NhbGUoaW50IHZhbHVlKSB7DQoJCWlmIChmVG90YWwgPiAwKQ0KCQkJcmV0dXJuIE1hdGgubWF4KDEsIHZhbHVlKihnZXRCb3VuZHMoKS53aWR0aC0xKS9mVG90YWwpOw0KCQlyZXR1cm4gdmFsdWU7IA0KCX0NCgkNCglwdWJsaWMgdm9pZCBzZXRCb3VuZHMoaW50IHgsIGludCB5LCBpbnQgdywgaW50IGgpIHsNCgkJc3VwZXIuc2V0Qm91bmRzKHgsIHksIHcsIGgpOw0KCQlmUHJvZ3Jlc3NYPSBzY2FsZShmUHJvZ3Jlc3MpOw0KCX0NCgkNCglwdWJsaWMgdm9pZCBzdGFydChpbnQgdG90YWwpIHsNCgkJZlRvdGFsPSB0b3RhbDsNCgkJcmVzZXQoKTsNCgl9DQoJDQoJcHVibGljIHZvaWQgc3RlcChib29sZWFuIHN1Y2Nlc3NmdWwpIHsNCgkJZlByb2dyZXNzKys7DQoJCWludCB4PSBmUHJvZ3Jlc3NYOw0KDQoJCWZQcm9ncmVzc1g9IHNjYWxlKGZQcm9ncmVzcyk7DQoNCgkJaWYgKCFmRXJyb3IgJiYgIXN1Y2Nlc3NmdWwpIHsNCgkJCWZFcnJvcj0gdHJ1ZTsNCgkJCXg9IDE7DQoJCX0NCgkJcGFpbnRTdGVwKHgsIGZQcm9ncmVzc1gpOw0KCX0NCn1QSwMECgAAAAAA6njHMENnQPVDCAAAQwgAABwAAABqdW5pdC9hd3R1aS9BYm91dERpYWxvZy5qYXZhcGFja2FnZSBqdW5pdC5hd3R1aTsNCg0KaW1wb3J0IGphdmEuYXd0Lio7DQppbXBvcnQgamF2YS5hd3QuZXZlbnQuKjsNCg0KaW1wb3J0IGp1bml0LnJ1bm5lci5WZXJzaW9uOw0KDQpjbGFzcyBBYm91dERpYWxvZyBleHRlbmRzIERpYWxvZyB7DQoJcHVibGljIEFib3V0RGlhbG9nKEZyYW1lIHBhcmVudCkgew0KCQlzdXBlcihwYXJlbnQpOw0KCQkNCgkJc2V0UmVzaXphYmxlKGZhbHNlKTsNCgkJc2V0TGF5b3V0KG5ldyBHcmlkQmFnTGF5b3V0KCkpOw0KCQlzZXRTaXplKDMzMCwgMTM4KTsNCgkJc2V0VGl0bGUoIkFib3V0Iik7DQoJCQ0KCQlCdXR0b24gYnV0dG9uPSBuZXcgQnV0dG9uKCJDbG9zZSIpOw0KCQlidXR0b24uYWRkQWN0aW9uTGlzdGVuZXIoDQoJCQluZXcgQWN0aW9uTGlzdGVuZXIoKSB7DQoJCQkJcHVibGljIHZvaWQgYWN0aW9uUGVyZm9ybWVkKEFjdGlvbkV2ZW50IGUpIHsNCgkJCQkJZGlzcG9zZSgpOw0KCQkJCX0NCgkJCX0NCgkJKTsNCgkJDQoJCUxhYmVsIGxhYmVsMT0gbmV3IExhYmVsKCJKVW5pdCIpOw0KCQlsYWJlbDEuc2V0Rm9udChuZXcgRm9udCgiZGlhbG9nIiwgRm9udC5QTEFJTiwgMzYpKTsNCgkJDQoJCUxhYmVsIGxhYmVsMj0gbmV3IExhYmVsKCJKVW5pdCAiK1ZlcnNpb24uaWQoKSsgIiBieSBLZW50IEJlY2sgYW5kIEVyaWNoIEdhbW1hIik7DQoJCWxhYmVsMi5zZXRGb250KG5ldyBGb250KCJkaWFsb2ciLCBGb250LlBMQUlOLCAxNCkpOw0KCQkNCgkJTG9nbyBsb2dvPSBuZXcgTG9nbygpOw0KDQoJCUdyaWRCYWdDb25zdHJhaW50cyBjb25zdHJhaW50c0xhYmVsMT0gbmV3IEdyaWRCYWdDb25zdHJhaW50cygpOw0KCQljb25zdHJhaW50c0xhYmVsMS5ncmlkeCA9IDM7IGNvbnN0cmFpbnRzTGFiZWwxLmdyaWR5ID0gMDsNCgkJY29uc3RyYWludHNMYWJlbDEuZ3JpZHdpZHRoID0gMTsgY29uc3RyYWludHNMYWJlbDEuZ3JpZGhlaWdodCA9IDE7DQoJCWNvbnN0cmFpbnRzTGFiZWwxLmFuY2hvciA9IEdyaWRCYWdDb25zdHJhaW50cy5DRU5URVI7DQoJCWFkZChsYWJlbDEsIGNvbnN0cmFpbnRzTGFiZWwxKTsNCg0KCQlHcmlkQmFnQ29uc3RyYWludHMgY29uc3RyYWludHNMYWJlbDI9IG5ldyBHcmlkQmFnQ29uc3RyYWludHMoKTsNCgkJY29uc3RyYWludHNMYWJlbDIuZ3JpZHggPSAyOyBjb25zdHJhaW50c0xhYmVsMi5ncmlkeSA9IDE7DQoJCWNvbnN0cmFpbnRzTGFiZWwyLmdyaWR3aWR0aCA9IDI7IGNvbnN0cmFpbnRzTGFiZWwyLmdyaWRoZWlnaHQgPSAxOw0KCQljb25zdHJhaW50c0xhYmVsMi5hbmNob3IgPSBHcmlkQmFnQ29uc3RyYWludHMuQ0VOVEVSOw0KCQlhZGQobGFiZWwyLCBjb25zdHJhaW50c0xhYmVsMik7DQoNCgkJR3JpZEJhZ0NvbnN0cmFpbnRzIGNvbnN0cmFpbnRzQnV0dG9uMT0gbmV3IEdyaWRCYWdDb25zdHJhaW50cygpOw0KCQljb25zdHJhaW50c0J1dHRvbjEuZ3JpZHggPSAyOyBjb25zdHJhaW50c0J1dHRvbjEuZ3JpZHkgPSAyOw0KCQljb25zdHJhaW50c0J1dHRvbjEuZ3JpZHdpZHRoID0gMjsgY29uc3RyYWludHNCdXR0b24xLmdyaWRoZWlnaHQgPSAxOw0KCQljb25zdHJhaW50c0J1dHRvbjEuYW5jaG9yID0gR3JpZEJhZ0NvbnN0cmFpbnRzLkNFTlRFUjsNCgkJY29uc3RyYWludHNCdXR0b24xLmluc2V0cz0gbmV3IEluc2V0cyg4LCAwLCA4LCAwKTsNCgkJYWRkKGJ1dHRvbiwgY29uc3RyYWludHNCdXR0b24xKTsNCg0KCQlHcmlkQmFnQ29uc3RyYWludHMgY29uc3RyYWludHNMb2dvMT0gbmV3IEdyaWRCYWdDb25zdHJhaW50cygpOw0KCQljb25zdHJhaW50c0xvZ28xLmdyaWR4ID0gMjsgY29uc3RyYWludHNMb2dvMS5ncmlkeSA9IDA7DQoJCWNvbnN0cmFpbnRzTG9nbzEuZ3JpZHdpZHRoID0gMTsgY29uc3RyYWludHNMb2dvMS5ncmlkaGVpZ2h0ID0gMTsNCgkJY29uc3RyYWludHNMb2dvMS5hbmNob3IgPSBHcmlkQmFnQ29uc3RyYWludHMuQ0VOVEVSOw0KCQlhZGQobG9nbywgY29uc3RyYWludHNMb2dvMSk7DQoNCgkJYWRkV2luZG93TGlzdGVuZXIoDQoJCQluZXcgV2luZG93QWRhcHRlcigpIHsNCgkJCQlwdWJsaWMgdm9pZCB3aW5kb3dDbG9zaW5nKFdpbmRvd0V2ZW50IGUpIHsNCgkJCQkJZGlzcG9zZSgpOw0KCQkJCX0NCgkJCX0NCgkJKTsNCgl9DQp9UEsDBAoAAAAAAOp4xzDoroSHrQQAAK0EAAAVAAAAanVuaXQvYXd0dWkvTG9nby5qYXZhcGFja2FnZSBqdW5pdC5hd3R1aTsNCg0KaW1wb3J0IGphdmEuYXd0Lio7DQppbXBvcnQgamF2YS5hd3QuaW1hZ2UuKjsNCmltcG9ydCBqYXZhLm5ldC5VUkw7DQoNCmltcG9ydCBqdW5pdC5ydW5uZXIuQmFzZVRlc3RSdW5uZXI7DQoNCnB1YmxpYyBjbGFzcyBMb2dvIGV4dGVuZHMgQ2FudmFzIHsNCglwcml2YXRlIEltYWdlIGZJbWFnZTsNCglwcml2YXRlIGludCBmV2lkdGg7DQoJcHJpdmF0ZSBpbnQgZkhlaWdodDsNCgkNCglwdWJsaWMgTG9nbygpIHsNCgkJZkltYWdlPSBsb2FkSW1hZ2UoImxvZ28uZ2lmIik7DQoJCU1lZGlhVHJhY2tlciB0cmFja2VyPSBuZXcgTWVkaWFUcmFja2VyKHRoaXMpOw0KCSAgCXRyYWNrZXIuYWRkSW1hZ2UoZkltYWdlLCAwKTsNCgkJdHJ5IHsNCgkJCXRyYWNrZXIud2FpdEZvckFsbCgpOw0KCQl9IGNhdGNoIChFeGNlcHRpb24gZSkgew0KCQl9DQoNCgkJaWYgKGZJbWFnZSAhPSBudWxsKSB7DQoJCQlmV2lkdGg9IGZJbWFnZS5nZXRXaWR0aCh0aGlzKTsNCgkJCWZIZWlnaHQ9IGZJbWFnZS5nZXRIZWlnaHQodGhpcyk7DQoJCX0gZWxzZSB7DQoJCQlmV2lkdGg9IDIwOw0KCQkJZkhlaWdodD0gMjA7DQoJCX0NCgkJc2V0U2l6ZShmV2lkdGgsIGZIZWlnaHQpOw0KCX0NCgkNCglwdWJsaWMgSW1hZ2UgbG9hZEltYWdlKFN0cmluZyBuYW1lKSB7DQoJCVRvb2xraXQgdG9vbGtpdD0gVG9vbGtpdC5nZXREZWZhdWx0VG9vbGtpdCgpOw0KCQl0cnkgew0KCQkJVVJMIHVybD0gQmFzZVRlc3RSdW5uZXIuY2xhc3MuZ2V0UmVzb3VyY2UobmFtZSk7DQoJCQlyZXR1cm4gdG9vbGtpdC5jcmVhdGVJbWFnZSgoSW1hZ2VQcm9kdWNlcikgdXJsLmdldENvbnRlbnQoKSk7DQoJCX0gY2F0Y2ggKEV4Y2VwdGlvbiBleCkgew0KCQl9DQoJCXJldHVybiBudWxsOw0KCX0NCgkNCglwdWJsaWMgdm9pZCBwYWludChHcmFwaGljcyBnKSB7DQoJCXBhaW50QmFja2dyb3VuZChnKTsNCgkJaWYgKGZJbWFnZSAhPSBudWxsKQ0KCQkJZy5kcmF3SW1hZ2UoZkltYWdlLCAwLCAwLCBmV2lkdGgsIGZIZWlnaHQsIHRoaXMpOw0KCX0NCgkNCglwdWJsaWMgdm9pZCBwYWludEJhY2tncm91bmQoIGphdmEuYXd0LkdyYXBoaWNzIGcpIHsNCgkJZy5zZXRDb2xvcihTeXN0ZW1Db2xvci5jb250cm9sKTsNCgkJZy5maWxsUmVjdCgwLCAwLCBnZXRCb3VuZHMoKS53aWR0aCwgZ2V0Qm91bmRzKCkuaGVpZ2h0KTsNCgl9DQp9UEsDBAoAAAAAAOp4xzDt0/jNbToAAG06AAAbAAAAanVuaXQvYXd0dWkvVGVzdFJ1bm5lci5qYXZhcGFja2FnZSBqdW5pdC5hd3R1aTsNCg0KaW1wb3J0IGphdmEuYXd0Lio7DQppbXBvcnQgamF2YS5hd3QuZXZlbnQuKjsNCmltcG9ydCBqYXZhLmF3dC5pbWFnZS5JbWFnZVByb2R1Y2VyOw0KaW1wb3J0IGphdmEudXRpbC5WZWN0b3I7DQoNCmltcG9ydCBqdW5pdC5mcmFtZXdvcmsuKjsNCmltcG9ydCBqdW5pdC5ydW5uZXIuKjsNCg0KLyoqDQogKiBBbiBBV1QgYmFzZWQgdXNlciBpbnRlcmZhY2UgdG8gcnVuIHRlc3RzLg0KICogRW50ZXIgdGhlIG5hbWUgb2YgYSBjbGFzcyB3aGljaCBlaXRoZXIgcHJvdmlkZXMgYSBzdGF0aWMNCiAqIHN1aXRlIG1ldGhvZCBvciBpcyBhIHN1YmNsYXNzIG9mIFRlc3RDYXNlLg0KICogPHByZT4NCiAqIFN5bm9wc2lzOiBqYXZhIGp1bml0LmF3dHVpLlRlc3RSdW5uZXIgWy1ub2xvYWRpbmddIFtUZXN0Q2FzZV0NCiAqIDwvcHJlPg0KICogVGVzdFJ1bm5lciB0YWtlcyBhcyBhbiBvcHRpb25hbCBhcmd1bWVudCB0aGUgbmFtZSBvZiB0aGUgdGVzdGNhc2UgY2xhc3MgdG8gYmUgcnVuLg0KICovDQogcHVibGljIGNsYXNzIFRlc3RSdW5uZXIgZXh0ZW5kcyBCYXNlVGVzdFJ1bm5lciB7DQoJcHJvdGVjdGVkIEZyYW1lIGZGcmFtZTsNCglwcm90ZWN0ZWQgVmVjdG9yIGZFeGNlcHRpb25zOw0KCXByb3RlY3RlZCBWZWN0b3IgZkZhaWxlZFRlc3RzOw0KCXByb3RlY3RlZCBUaHJlYWQgZlJ1bm5lcjsNCglwcm90ZWN0ZWQgVGVzdFJlc3VsdCBmVGVzdFJlc3VsdDsNCg0KCXByb3RlY3RlZCBUZXh0QXJlYSBmVHJhY2VBcmVhOw0KCXByb3RlY3RlZCBUZXh0RmllbGQgZlN1aXRlRmllbGQ7DQoJcHJvdGVjdGVkIEJ1dHRvbiBmUnVuOw0KCXByb3RlY3RlZCBQcm9ncmVzc0JhciBmUHJvZ3Jlc3NJbmRpY2F0b3I7DQoJcHJvdGVjdGVkIExpc3QgZkZhaWx1cmVMaXN0Ow0KCXByb3RlY3RlZCBMb2dvIGZMb2dvOw0KCXByb3RlY3RlZCBMYWJlbCBmTnVtYmVyT2ZFcnJvcnM7DQoJcHJvdGVjdGVkIExhYmVsIGZOdW1iZXJPZkZhaWx1cmVzOw0KCXByb3RlY3RlZCBMYWJlbCBmTnVtYmVyT2ZSdW5zOw0KCXByb3RlY3RlZCBCdXR0b24gZlF1aXRCdXR0b247DQoJcHJvdGVjdGVkIEJ1dHRvbiBmUmVydW5CdXR0b247DQoJcHJvdGVjdGVkIFRleHRGaWVsZCBmU3RhdHVzTGluZTsNCglwcm90ZWN0ZWQgQ2hlY2tib3ggZlVzZUxvYWRpbmdSdW5uZXI7DQoNCglwcm90ZWN0ZWQgc3RhdGljIGZpbmFsIEZvbnQgUExBSU5fRk9OVD0gbmV3IEZvbnQoImRpYWxvZyIsIEZvbnQuUExBSU4sIDEyKTsNCglwcml2YXRlIHN0YXRpYyBmaW5hbCBpbnQgR0FQPSA0Ow0KDQoJcHVibGljIFRlc3RSdW5uZXIoKSB7DQoJfQ0KDQoJcHJpdmF0ZSB2b2lkIGFib3V0KCkgew0KCQlBYm91dERpYWxvZyBhYm91dD0gbmV3IEFib3V0RGlhbG9nKGZGcmFtZSk7DQoJCWFib3V0LnNldE1vZGFsKHRydWUpOw0KCQlhYm91dC5zZXRMb2NhdGlvbigzMDAsIDMwMCk7DQoJCWFib3V0LnNldFZpc2libGUodHJ1ZSk7DQoJfQ0KDQoJcHVibGljIHZvaWQgdGVzdFN0YXJ0ZWQoU3RyaW5nIHRlc3ROYW1lKSB7DQoJCXNob3dJbmZvKCJSdW5uaW5nOiAiK3Rlc3ROYW1lKTsNCgl9DQoNCglwdWJsaWMgdm9pZCB0ZXN0RW5kZWQoU3RyaW5nIHRlc3ROYW1lKSB7DQoJCXNldExhYmVsVmFsdWUoZk51bWJlck9mUnVucywgZlRlc3RSZXN1bHQucnVuQ291bnQoKSk7DQoJCXN5bmNocm9uaXplZCh0aGlzKSB7DQoJCQlmUHJvZ3Jlc3NJbmRpY2F0b3Iuc3RlcChmVGVzdFJlc3VsdC53YXNTdWNjZXNzZnVsKCkpOw0KCQl9DQoJfQ0KDQoJcHVibGljIHZvaWQgdGVzdEZhaWxlZChpbnQgc3RhdHVzLCBUZXN0IHRlc3QsIFRocm93YWJsZSB0KSB7DQoJCXN3aXRjaCAoc3RhdHVzKSB7DQoJCQljYXNlIFRlc3RSdW5MaXN0ZW5lci5TVEFUVVNfRVJST1I6DQoJCQkJZk51bWJlck9mRXJyb3JzLnNldFRleHQoSW50ZWdlci50b1N0cmluZyhmVGVzdFJlc3VsdC5lcnJvckNvdW50KCkpKTsNCgkJCQlhcHBlbmRGYWlsdXJlKCJFcnJvciIsIHRlc3QsIHQpOw0KCQkJCWJyZWFrOw0KCQkJY2FzZSBUZXN0UnVuTGlzdGVuZXIuU1RBVFVTX0ZBSUxVUkU6DQoJCQkJZk51bWJlck9mRmFpbHVyZXMuc2V0VGV4dChJbnRlZ2VyLnRvU3RyaW5nKGZUZXN0UmVzdWx0LmZhaWx1cmVDb3VudCgpKSk7DQoJCQkJYXBwZW5kRmFpbHVyZSgiRmFpbHVyZSIsIHRlc3QsIHQpOw0KCQkJCWJyZWFrOw0KCQl9DQoJfQ0KDQoJcHJvdGVjdGVkIHZvaWQgYWRkR3JpZChQYW5lbCBwLCBDb21wb25lbnQgY28sIGludCB4LCBpbnQgeSwgaW50IHcsIGludCBmaWxsLCBkb3VibGUgd3gsIGludCBhbmNob3IpIHsNCgkJR3JpZEJhZ0NvbnN0cmFpbnRzIGM9IG5ldyBHcmlkQmFnQ29uc3RyYWludHMoKTsNCgkJYy5ncmlkeD0geDsgYy5ncmlkeT0geTsNCgkJYy5ncmlkd2lkdGg9IHc7DQoJCWMuYW5jaG9yPSBhbmNob3I7DQoJCWMud2VpZ2h0eD0gd3g7DQoJCWMuZmlsbD0gZmlsbDsNCgkJaWYgKGZpbGwgPT0gR3JpZEJhZ0NvbnN0cmFpbnRzLkJPVEggfHwgZmlsbCA9PSBHcmlkQmFnQ29uc3RyYWludHMuVkVSVElDQUwpDQoJCQljLndlaWdodHk9IDEuMDsNCgkJYy5pbnNldHM9IG5ldyBJbnNldHMoeSA9PSAwID8gR0FQIDogMCwgeCA9PSAwID8gR0FQIDogMCwgR0FQLCBHQVApOw0KCQlwLmFkZChjbywgYyk7DQoJfQ0KDQoJcHJpdmF0ZSB2b2lkIGFwcGVuZEZhaWx1cmUoU3RyaW5nIGtpbmQsIFRlc3QgdGVzdCwgVGhyb3dhYmxlIHQpIHsNCgkJa2luZCs9ICI6ICIgKyB0ZXN0Ow0KCQlTdHJpbmcgbXNnPSB0LmdldE1lc3NhZ2UoKTsNCgkJaWYgKG1zZyAhPSBudWxsKSB7DQoJCQlraW5kKz0gIjoiICsgdHJ1bmNhdGUobXNnKTsNCgkJfQ0KCQlmRmFpbHVyZUxpc3QuYWRkKGtpbmQpOw0KCQlmRXhjZXB0aW9ucy5hZGRFbGVtZW50KHQpOw0KCQlmRmFpbGVkVGVzdHMuYWRkRWxlbWVudCh0ZXN0KTsNCgkJaWYgKGZGYWlsdXJlTGlzdC5nZXRJdGVtQ291bnQoKSA9PSAxKSB7DQoJCQlmRmFpbHVyZUxpc3Quc2VsZWN0KDApOw0KCQkJZmFpbHVyZVNlbGVjdGVkKCk7DQoJCX0NCgl9DQoJLyoqDQoJICogQ3JlYXRlcyB0aGUgSlVuaXQgbWVudS4gQ2xpZW50cyBvdmVycmlkZSB0aGlzDQoJICogbWV0aG9kIHRvIGFkZCBhZGRpdGlvbmFsIG1lbnUgaXRlbXMuDQoJICovDQoJcHJvdGVjdGVkIE1lbnUgY3JlYXRlSlVuaXRNZW51KCkgew0KCQlNZW51IG1lbnU9IG5ldyBNZW51KCJKVW5pdCIpOw0KCQlNZW51SXRlbSBtaT0gbmV3IE1lbnVJdGVtKCJBYm91dC4uLiIpOw0KCQltaS5hZGRBY3Rpb25MaXN0ZW5lcigNCgkJICAgIG5ldyBBY3Rpb25MaXN0ZW5lcigpIHsNCgkJICAgICAgICBwdWJsaWMgdm9pZCBhY3Rpb25QZXJmb3JtZWQoQWN0aW9uRXZlbnQgZXZlbnQpIHsNCgkJICAgICAgICAgICAgYWJvdXQoKTsNCgkJICAgICAgICB9DQoJCSAgICB9DQoJCSk7DQoJCW1lbnUuYWRkKG1pKTsNCg0KCQltZW51LmFkZFNlcGFyYXRvcigpOw0KCQltaT0gbmV3IE1lbnVJdGVtKCJFeGl0Iik7DQoJCW1pLmFkZEFjdGlvbkxpc3RlbmVyKA0KCQkgICAgbmV3IEFjdGlvbkxpc3RlbmVyKCkgew0KCQkgICAgICAgIHB1YmxpYyB2b2lkIGFjdGlvblBlcmZvcm1lZChBY3Rpb25FdmVudCBldmVudCkgew0KCQkgICAgICAgICAgICBTeXN0ZW0uZXhpdCgwKTsNCgkJICAgICAgICB9DQoJCSAgICB9DQoJCSk7DQoJCW1lbnUuYWRkKG1pKTsNCgkJcmV0dXJuIG1lbnU7DQoJfQ0KDQoJcHJvdGVjdGVkIHZvaWQgY3JlYXRlTWVudXMoTWVudUJhciBtYikgew0KCQltYi5hZGQoY3JlYXRlSlVuaXRNZW51KCkpOw0KCX0NCglwcm90ZWN0ZWQgVGVzdFJlc3VsdCBjcmVhdGVUZXN0UmVzdWx0KCkgew0KCQlyZXR1cm4gbmV3IFRlc3RSZXN1bHQoKTsNCgl9DQoNCglwcm90ZWN0ZWQgRnJhbWUgY3JlYXRlVUkoU3RyaW5nIHN1aXRlTmFtZSkgew0KCQlGcmFtZSBmcmFtZT0gbmV3IEZyYW1lKCJKVW5pdCIpOw0KCQlJbWFnZSBpY29uPSBsb2FkRnJhbWVJY29uKCk7DQoJCWlmIChpY29uICE9IG51bGwpDQoJCQlmcmFtZS5zZXRJY29uSW1hZ2UoaWNvbik7DQoNCgkJZnJhbWUuc2V0TGF5b3V0KG5ldyBCb3JkZXJMYXlvdXQoMCwgMCkpOw0KCQlmcmFtZS5zZXRCYWNrZ3JvdW5kKFN5c3RlbUNvbG9yLmNvbnRyb2wpOw0KCQlmaW5hbCBGcmFtZSBmaW5hbEZyYW1lPSBmcmFtZTsNCg0KCQlmcmFtZS5hZGRXaW5kb3dMaXN0ZW5lcigNCgkJCW5ldyBXaW5kb3dBZGFwdGVyKCkgew0KCQkJCXB1YmxpYyB2b2lkIHdpbmRvd0Nsb3NpbmcoV2luZG93RXZlbnQgZSkgew0KCQkJCQlmaW5hbEZyYW1lLmRpc3Bvc2UoKTsNCgkJCQkJU3lzdGVtLmV4aXQoMCk7DQoJCQkJfQ0KCQkJfQ0KCQkpOw0KDQoJCU1lbnVCYXIgbWIgPSBuZXcgTWVudUJhcigpOw0KCQljcmVhdGVNZW51cyhtYik7DQoJCWZyYW1lLnNldE1lbnVCYXIobWIpOw0KDQoJCS8vLS0tLSBmaXJzdCBzZWN0aW9uDQoJCUxhYmVsIHN1aXRlTGFiZWw9IG5ldyBMYWJlbCgiVGVzdCBjbGFzcyBuYW1lOiIpOw0KDQoJCWZTdWl0ZUZpZWxkPSBuZXcgVGV4dEZpZWxkKHN1aXRlTmFtZSAhPSBudWxsID8gc3VpdGVOYW1lIDogIiIpOw0KCQlmU3VpdGVGaWVsZC5zZWxlY3RBbGwoKTsNCgkJZlN1aXRlRmllbGQucmVxdWVzdEZvY3VzKCk7DQoJCWZTdWl0ZUZpZWxkLnNldEZvbnQoUExBSU5fRk9OVCk7DQoJCWZTdWl0ZUZpZWxkLnNldENvbHVtbnMoNDApOw0KCQlmU3VpdGVGaWVsZC5hZGRBY3Rpb25MaXN0ZW5lcigNCgkJCW5ldyBBY3Rpb25MaXN0ZW5lcigpIHsNCgkJCQlwdWJsaWMgdm9pZCBhY3Rpb25QZXJmb3JtZWQoQWN0aW9uRXZlbnQgZSkgew0KCQkJCQlydW5TdWl0ZSgpOw0KCQkJCX0NCgkJCX0NCgkJKTsNCgkJZlN1aXRlRmllbGQuYWRkVGV4dExpc3RlbmVyKA0KCQkJbmV3IFRleHRMaXN0ZW5lcigpIHsNCgkJCQlwdWJsaWMgdm9pZCB0ZXh0VmFsdWVDaGFuZ2VkKFRleHRFdmVudCBlKSB7DQoJCQkJCWZSdW4uc2V0RW5hYmxlZChmU3VpdGVGaWVsZC5nZXRUZXh0KCkubGVuZ3RoKCkgPiAwKTsNCgkJCQkJZlN0YXR1c0xpbmUuc2V0VGV4dCgiIik7DQoJCQkJfQ0KCQkJfQ0KCQkpOw0KCQlmUnVuPSBuZXcgQnV0dG9uKCJSdW4iKTsNCgkJZlJ1bi5zZXRFbmFibGVkKGZhbHNlKTsNCgkJZlJ1bi5hZGRBY3Rpb25MaXN0ZW5lcigNCgkJCW5ldyBBY3Rpb25MaXN0ZW5lcigpIHsNCgkJCQlwdWJsaWMgdm9pZCBhY3Rpb25QZXJmb3JtZWQoQWN0aW9uRXZlbnQgZSkgew0KCQkJCQlydW5TdWl0ZSgpOw0KCQkJCX0NCgkJCX0NCgkJKTsNCgkJYm9vbGVhbiB1c2VMb2FkZXI9IHVzZVJlbG9hZGluZ1Rlc3RTdWl0ZUxvYWRlcigpOw0KCQlmVXNlTG9hZGluZ1J1bm5lcj0gbmV3IENoZWNrYm94KCJSZWxvYWQgY2xhc3NlcyBldmVyeSBydW4iLCB1c2VMb2FkZXIpOw0KCQlpZiAoaW5WQUphdmEoKSkNCgkJCWZVc2VMb2FkaW5nUnVubmVyLnNldFZpc2libGUoZmFsc2UpOw0KDQoJCS8vLS0tLSBzZWNvbmQgc2VjdGlvbg0KCQlmUHJvZ3Jlc3NJbmRpY2F0b3I9IG5ldyBQcm9ncmVzc0JhcigpOw0KDQoJCS8vLS0tLSB0aGlyZCBzZWN0aW9uDQoJCWZOdW1iZXJPZkVycm9ycz0gbmV3IExhYmVsKCIwMDAwIiwgTGFiZWwuUklHSFQpOw0KCQlmTnVtYmVyT2ZFcnJvcnMuc2V0VGV4dCgiMCIpOw0KCQlmTnVtYmVyT2ZFcnJvcnMuc2V0Rm9udChQTEFJTl9GT05UKTsNCg0KCQlmTnVtYmVyT2ZGYWlsdXJlcz0gbmV3IExhYmVsKCIwMDAwIiwgTGFiZWwuUklHSFQpOw0KCQlmTnVtYmVyT2ZGYWlsdXJlcy5zZXRUZXh0KCIwIik7DQoJCWZOdW1iZXJPZkZhaWx1cmVzLnNldEZvbnQoUExBSU5fRk9OVCk7DQoNCgkJZk51bWJlck9mUnVucz0gbmV3IExhYmVsKCIwMDAwIiwgTGFiZWwuUklHSFQpOw0KCQlmTnVtYmVyT2ZSdW5zLnNldFRleHQoIjAiKTsNCgkJZk51bWJlck9mUnVucy5zZXRGb250KFBMQUlOX0ZPTlQpOw0KDQoJCVBhbmVsIG51bWJlcnNQYW5lbD0gY3JlYXRlQ291bnRlclBhbmVsKCk7DQoNCgkJLy8tLS0tIGZvdXJ0aCBzZWN0aW9uDQoJCUxhYmVsIGZhaWx1cmVMYWJlbD0gbmV3IExhYmVsKCJFcnJvcnMgYW5kIEZhaWx1cmVzOiIpOw0KDQoJCWZGYWlsdXJlTGlzdD0gbmV3IExpc3QoNSk7DQoJCWZGYWlsdXJlTGlzdC5hZGRJdGVtTGlzdGVuZXIoDQoJCQluZXcgSXRlbUxpc3RlbmVyKCkgew0KCQkJCXB1YmxpYyB2b2lkIGl0ZW1TdGF0ZUNoYW5nZWQoSXRlbUV2ZW50IGUpIHsNCgkJCQkJZmFpbHVyZVNlbGVjdGVkKCk7DQoJCQkJfQ0KCQkJfQ0KCQkpOw0KCQlmUmVydW5CdXR0b249IG5ldyBCdXR0b24oIlJ1biIpOw0KCQlmUmVydW5CdXR0b24uc2V0RW5hYmxlZChmYWxzZSk7DQoJCWZSZXJ1bkJ1dHRvbi5hZGRBY3Rpb25MaXN0ZW5lcigNCgkJCW5ldyBBY3Rpb25MaXN0ZW5lcigpIHsNCgkJCQlwdWJsaWMgdm9pZCBhY3Rpb25QZXJmb3JtZWQoQWN0aW9uRXZlbnQgZSkgew0KCQkJCQlyZXJ1bigpOw0KCQkJCX0NCgkJCX0NCgkJKTsNCg0KCQlQYW5lbCBmYWlsZWRQYW5lbD0gbmV3IFBhbmVsKG5ldyBHcmlkTGF5b3V0KDAsIDEsIDAsIDIpKTsNCgkJZmFpbGVkUGFuZWwuYWRkKGZSZXJ1bkJ1dHRvbik7DQoNCgkJZlRyYWNlQXJlYT0gbmV3IFRleHRBcmVhKCk7DQoJCWZUcmFjZUFyZWEuc2V0Um93cyg1KTsNCgkJZlRyYWNlQXJlYS5zZXRDb2x1bW5zKDYwKTsNCg0KCQkvLy0tLS0gZmlmdGggc2VjdGlvbg0KCQlmU3RhdHVzTGluZT0gbmV3IFRleHRGaWVsZCgpOw0KCQlmU3RhdHVzTGluZS5zZXRGb250KFBMQUlOX0ZPTlQpOw0KCQlmU3RhdHVzTGluZS5zZXRFZGl0YWJsZShmYWxzZSk7DQoJCWZTdGF0dXNMaW5lLnNldEZvcmVncm91bmQoQ29sb3IucmVkKTsNCg0KCQlmUXVpdEJ1dHRvbj0gbmV3IEJ1dHRvbigiRXhpdCIpOw0KCQlmUXVpdEJ1dHRvbi5hZGRBY3Rpb25MaXN0ZW5lcigNCgkJCW5ldyBBY3Rpb25MaXN0ZW5lcigpIHsNCgkJCQlwdWJsaWMgdm9pZCBhY3Rpb25QZXJmb3JtZWQoQWN0aW9uRXZlbnQgZSkgew0KCQkJCQlTeXN0ZW0uZXhpdCgwKTsNCgkJCQl9DQoJCQl9DQoJCSk7DQoNCgkJLy8gLS0tLS0tLS0tDQoJCWZMb2dvPSBuZXcgTG9nbygpOw0KDQoJCS8vLS0tLSBvdmVyYWxsIGxheW91dA0KCQlQYW5lbCBwYW5lbD0gbmV3IFBhbmVsKG5ldyBHcmlkQmFnTGF5b3V0KCkpOw0KDQoJCWFkZEdyaWQocGFuZWwsIHN1aXRlTGFiZWwsCQkgMCwgMCwgMiwgR3JpZEJhZ0NvbnN0cmFpbnRzLkhPUklaT05UQUwsIAkxLjAsIEdyaWRCYWdDb25zdHJhaW50cy5XRVNUKTsNCg0KCQlhZGRHcmlkKHBhbmVsLCBmU3VpdGVGaWVsZCwgCSAwLCAxLCAyLCBHcmlkQmFnQ29uc3RyYWludHMuSE9SSVpPTlRBTCwgCTEuMCwgR3JpZEJhZ0NvbnN0cmFpbnRzLldFU1QpOw0KCQlhZGRHcmlkKHBhbmVsLCBmUnVuLCAJCQkgMiwgMSwgMSwgR3JpZEJhZ0NvbnN0cmFpbnRzLkhPUklaT05UQUwsIAkwLjAsIEdyaWRCYWdDb25zdHJhaW50cy5DRU5URVIpOw0KCQlhZGRHcmlkKHBhbmVsLCBmVXNlTG9hZGluZ1J1bm5lciwgMCwgMiwgMiwgR3JpZEJhZ0NvbnN0cmFpbnRzLk5PTkUsIAkxLjAsIEdyaWRCYWdDb25zdHJhaW50cy5XRVNUKTsNCgkJYWRkR3JpZChwYW5lbCwgZlByb2dyZXNzSW5kaWNhdG9yLCAwLCAzLCAyLCBHcmlkQmFnQ29uc3RyYWludHMuSE9SSVpPTlRBTCwgCTEuMCwgR3JpZEJhZ0NvbnN0cmFpbnRzLldFU1QpOw0KCQlhZGRHcmlkKHBhbmVsLCBmTG9nbywgCQkJIDIsIDMsIDEsIEdyaWRCYWdDb25zdHJhaW50cy5OT05FLCAJCQkwLjAsIEdyaWRCYWdDb25zdHJhaW50cy5OT1JUSCk7DQoNCgkJYWRkR3JpZChwYW5lbCwgbnVtYmVyc1BhbmVsLAkgMCwgNCwgMiwgR3JpZEJhZ0NvbnN0cmFpbnRzLk5PTkUsIAkJCTAuMCwgR3JpZEJhZ0NvbnN0cmFpbnRzLldFU1QpOw0KDQoJCWFkZEdyaWQocGFuZWwsIGZhaWx1cmVMYWJlbCwgCSAwLCA1LCAyLCBHcmlkQmFnQ29uc3RyYWludHMuSE9SSVpPTlRBTCwgCTEuMCwgR3JpZEJhZ0NvbnN0cmFpbnRzLldFU1QpOw0KCQlhZGRHcmlkKHBhbmVsLCBmRmFpbHVyZUxpc3QsIAkgMCwgNiwgMiwgR3JpZEJhZ0NvbnN0cmFpbnRzLkJPVEgsIAkJCTEuMCwgR3JpZEJhZ0NvbnN0cmFpbnRzLldFU1QpOw0KCQlhZGRHcmlkKHBhbmVsLCBmYWlsZWRQYW5lbCwgCSAyLCA2LCAxLCBHcmlkQmFnQ29uc3RyYWludHMuSE9SSVpPTlRBTCwgCTAuMCwgR3JpZEJhZ0NvbnN0cmFpbnRzLkNFTlRFUik7DQoJCWFkZEdyaWQocGFuZWwsIGZUcmFjZUFyZWEsIAkgICAgIDAsIDcsIDIsIEdyaWRCYWdDb25zdHJhaW50cy5CT1RILCAJCQkxLjAsIEdyaWRCYWdDb25zdHJhaW50cy5XRVNUKTsNCg0KCQlhZGRHcmlkKHBhbmVsLCBmU3RhdHVzTGluZSwgCSAwLCA4LCAyLCBHcmlkQmFnQ29uc3RyYWludHMuSE9SSVpPTlRBTCwgCTEuMCwgR3JpZEJhZ0NvbnN0cmFpbnRzLkNFTlRFUik7DQoJCWFkZEdyaWQocGFuZWwsIGZRdWl0QnV0dG9uLCAJIDIsIDgsIDEsIEdyaWRCYWdDb25zdHJhaW50cy5IT1JJWk9OVEFMLCAJMC4wLCBHcmlkQmFnQ29uc3RyYWludHMuQ0VOVEVSKTsNCg0KCQlmcmFtZS5hZGQocGFuZWwsIEJvcmRlckxheW91dC5DRU5URVIpOw0KCQlmcmFtZS5wYWNrKCk7DQoJCXJldHVybiBmcmFtZTsNCgl9DQoNCglwcm90ZWN0ZWQgUGFuZWwgY3JlYXRlQ291bnRlclBhbmVsKCkgew0KCQlQYW5lbCBudW1iZXJzUGFuZWw9IG5ldyBQYW5lbChuZXcgR3JpZEJhZ0xheW91dCgpKTsNCgkJYWRkVG9Db3VudGVyUGFuZWwoDQoJCQludW1iZXJzUGFuZWwsDQoJCQluZXcgTGFiZWwoIlJ1bnM6IiksDQoJCQkwLCAwLCAxLCAxLCAwLjAsIDAuMCwNCiAgICAgICAgICAJR3JpZEJhZ0NvbnN0cmFpbnRzLkNFTlRFUiwgR3JpZEJhZ0NvbnN0cmFpbnRzLk5PTkUsDQogICAgICAgICAgCW5ldyBJbnNldHMoMCwgMCwgMCwgMCkgDQoJCSk7CQ0KCQlhZGRUb0NvdW50ZXJQYW5lbCgNCgkJCW51bWJlcnNQYW5lbCwNCgkJCWZOdW1iZXJPZlJ1bnMsIA0KICAgICAgICAgIAkxLCAwLCAxLCAxLCAwLjMzLCAwLjAsDQogICAgICAgICAgCUdyaWRCYWdDb25zdHJhaW50cy5DRU5URVIsIEdyaWRCYWdDb25zdHJhaW50cy5IT1JJWk9OVEFMLA0KICAgICAgICAgIAluZXcgSW5zZXRzKDAsIDgsIDAsIDQwKQ0KCQkpOw0KCQlhZGRUb0NvdW50ZXJQYW5lbCgNCgkJCW51bWJlcnNQYW5lbCwNCgkJCW5ldyBMYWJlbCgiRXJyb3JzOiIpLA0KICAgICAgICAgIAkyLCAwLCAxLCAxLCAwLjAsIDAuMCwNCiAgICAgICAgICAJR3JpZEJhZ0NvbnN0cmFpbnRzLkNFTlRFUiwgR3JpZEJhZ0NvbnN0cmFpbnRzLk5PTkUsDQogICAgICAgICAgCW5ldyBJbnNldHMoMCwgOCwgMCwgMCkNCgkJKTsNCgkJYWRkVG9Db3VudGVyUGFuZWwoDQoJCQludW1iZXJzUGFuZWwsDQoJCQlmTnVtYmVyT2ZFcnJvcnMsDQogICAgICAgICAgCTMsIDAsIDEsIDEsIDAuMzMsIDAuMCwNCiAgICAgICAgICAJR3JpZEJhZ0NvbnN0cmFpbnRzLkNFTlRFUiwgR3JpZEJhZ0NvbnN0cmFpbnRzLkhPUklaT05UQUwsDQogICAgICAgICAgCW5ldyBJbnNldHMoMCwgOCwgMCwgNDApDQoJCSk7DQoJCWFkZFRvQ291bnRlclBhbmVsKA0KCQkJbnVtYmVyc1BhbmVsLA0KCQkJbmV3IExhYmVsKCJGYWlsdXJlczoiKSwNCiAgICAgICAgICAJNCwgMCwgMSwgMSwgMC4wLCAwLjAsDQogICAgICAgICAgCUdyaWRCYWdDb25zdHJhaW50cy5DRU5URVIsIEdyaWRCYWdDb25zdHJhaW50cy5OT05FLA0KICAgICAgICAgIAluZXcgSW5zZXRzKDAsIDgsIDAsIDApDQoJCSk7CQ0KCQlhZGRUb0NvdW50ZXJQYW5lbCgNCgkJCW51bWJlcnNQYW5lbCwNCgkJCWZOdW1iZXJPZkZhaWx1cmVzLA0KICAgICAgICAgIAk1LCAwLCAxLCAxLCAwLjMzLCAwLjAsDQogICAgICAgICAgCUdyaWRCYWdDb25zdHJhaW50cy5DRU5URVIsIEdyaWRCYWdDb25zdHJhaW50cy5IT1JJWk9OVEFMLA0KICAgICAgICAgIAluZXcgSW5zZXRzKDAsIDgsIDAsIDApIA0KCQkpOw0KCQlyZXR1cm4gbnVtYmVyc1BhbmVsOw0KCX0NCg0KCXByaXZhdGUgdm9pZCBhZGRUb0NvdW50ZXJQYW5lbChQYW5lbCBjb3VudGVyLCBDb21wb25lbnQgY29tcCwNCgkgICAgCWludCBncmlkeCwgaW50IGdyaWR5LCBpbnQgZ3JpZHdpZHRoLCBpbnQgZ3JpZGhlaWdodCwNCgkJCWRvdWJsZSB3ZWlnaHR4LCBkb3VibGUgd2VpZ2h0eSwNCgkJCWludCBhbmNob3IsIGludCBmaWxsLA0KCQkJSW5zZXRzIGluc2V0cykgew0KCQkNCgkJR3JpZEJhZ0NvbnN0cmFpbnRzIGNvbnN0cmFpbnRzPSBuZXcgR3JpZEJhZ0NvbnN0cmFpbnRzKCk7DQoJCWNvbnN0cmFpbnRzLmdyaWR4PSBncmlkeDsNCgkJY29uc3RyYWludHMuZ3JpZHk9IGdyaWR5Ow0KCQljb25zdHJhaW50cy5ncmlkd2lkdGg9IGdyaWR3aWR0aDsNCgkJY29uc3RyYWludHMuZ3JpZGhlaWdodD0gZ3JpZGhlaWdodDsNCgkJY29uc3RyYWludHMud2VpZ2h0eD0gd2VpZ2h0eDsNCgkJY29uc3RyYWludHMud2VpZ2h0eT0gd2VpZ2h0eTsNCgkJY29uc3RyYWludHMuYW5jaG9yPSBhbmNob3I7DQoJCWNvbnN0cmFpbnRzLmZpbGw9IGZpbGw7DQoJCWNvbnN0cmFpbnRzLmluc2V0cz0gaW5zZXRzOw0KCQljb3VudGVyLmFkZChjb21wLCBjb25zdHJhaW50cyk7DQoJfQ0KDQoNCglwdWJsaWMgdm9pZCBmYWlsdXJlU2VsZWN0ZWQoKSB7DQoJCWZSZXJ1bkJ1dHRvbi5zZXRFbmFibGVkKGlzRXJyb3JTZWxlY3RlZCgpKTsNCgkJc2hvd0Vycm9yVHJhY2UoKTsNCgl9DQoNCglwcml2YXRlIGJvb2xlYW4gaXNFcnJvclNlbGVjdGVkKCkgew0KCQlyZXR1cm4gZkZhaWx1cmVMaXN0LmdldFNlbGVjdGVkSW5kZXgoKSAhPSAtMTsNCgl9DQoNCglwcml2YXRlIEltYWdlIGxvYWRGcmFtZUljb24oKSB7DQoJCVRvb2xraXQgdG9vbGtpdD0gVG9vbGtpdC5nZXREZWZhdWx0VG9vbGtpdCgpOw0KCQl0cnkgew0KCQkJamF2YS5uZXQuVVJMIHVybD0gQmFzZVRlc3RSdW5uZXIuY2xhc3MuZ2V0UmVzb3VyY2UoInNtYWxsbG9nby5naWYiKTsNCgkJCXJldHVybiB0b29sa2l0LmNyZWF0ZUltYWdlKChJbWFnZVByb2R1Y2VyKSB1cmwuZ2V0Q29udGVudCgpKTsNCgkJfSBjYXRjaCAoRXhjZXB0aW9uIGV4KSB7DQoJCX0NCgkJcmV0dXJuIG51bGw7DQoJfQ0KDQoJcHVibGljIFRocmVhZCBnZXRSdW5uZXIoKSB7DQoJCXJldHVybiBmUnVubmVyOw0KCX0NCg0KCXB1YmxpYyBzdGF0aWMgdm9pZCBtYWluKFN0cmluZ1tdIGFyZ3MpIHsNCgkJbmV3IFRlc3RSdW5uZXIoKS5zdGFydChhcmdzKTsNCgl9DQoNCglwdWJsaWMgc3RhdGljIHZvaWQgcnVuKENsYXNzIHRlc3QpIHsNCgkJU3RyaW5nIGFyZ3NbXT0geyB0ZXN0LmdldE5hbWUoKSB9Ow0KCQltYWluKGFyZ3MpOw0KCX0NCg0KCXB1YmxpYyB2b2lkIHJlcnVuKCkgew0KCQlpbnQgaW5kZXg9IGZGYWlsdXJlTGlzdC5nZXRTZWxlY3RlZEluZGV4KCk7DQoJCWlmIChpbmRleCA9PSAtMSkNCgkJCXJldHVybjsNCg0KCQlUZXN0IHRlc3Q9IChUZXN0KWZGYWlsZWRUZXN0cy5lbGVtZW50QXQoaW5kZXgpOw0KCQlyZXJ1blRlc3QodGVzdCk7DQoJfQ0KDQoJcHJpdmF0ZSB2b2lkIHJlcnVuVGVzdChUZXN0IHRlc3QpIHsNCgkJaWYgKCEodGVzdCBpbnN0YW5jZW9mIFRlc3RDYXNlKSkgew0KCQkJc2hvd0luZm8oIkNvdWxkIG5vdCByZWxvYWQgIisgdGVzdC50b1N0cmluZygpKTsNCgkJCXJldHVybjsNCgkJfQ0KCQlUZXN0IHJlbG9hZGVkVGVzdD0gbnVsbDsNCgkJVGVzdENhc2UgcmVydW5UZXN0PSAoVGVzdENhc2UpdGVzdDsNCgkJdHJ5IHsNCgkJCUNsYXNzIHJlbG9hZGVkVGVzdENsYXNzPSBnZXRMb2FkZXIoKS5yZWxvYWQodGVzdC5nZXRDbGFzcygpKTsgDQoJCQlyZWxvYWRlZFRlc3Q9IFRlc3RTdWl0ZS5jcmVhdGVUZXN0KHJlbG9hZGVkVGVzdENsYXNzLCByZXJ1blRlc3QuZ2V0TmFtZSgpKTsNCgkJfSBjYXRjaChFeGNlcHRpb24gZSkgew0KCQkJc2hvd0luZm8oIkNvdWxkIG5vdCByZWxvYWQgIisgdGVzdC50b1N0cmluZygpKTsNCgkJCXJldHVybjsNCgkJfQ0KCQlUZXN0UmVzdWx0IHJlc3VsdD0gbmV3IFRlc3RSZXN1bHQoKTsNCgkJcmVsb2FkZWRUZXN0LnJ1bihyZXN1bHQpOw0KDQoJCVN0cmluZyBtZXNzYWdlPSByZWxvYWRlZFRlc3QudG9TdHJpbmcoKTsNCgkJaWYocmVzdWx0Lndhc1N1Y2Nlc3NmdWwoKSkNCgkJCXNob3dJbmZvKG1lc3NhZ2UrIiB3YXMgc3VjY2Vzc2Z1bCIpOw0KCQllbHNlIGlmIChyZXN1bHQuZXJyb3JDb3VudCgpID09IDEpDQoJCQlzaG93U3RhdHVzKG1lc3NhZ2UrIiBoYWQgYW4gZXJyb3IiKTsNCgkJZWxzZQ0KCQkJc2hvd1N0YXR1cyhtZXNzYWdlKyIgaGFkIGEgZmFpbHVyZSIpOw0KCX0NCg0KCXByb3RlY3RlZCB2b2lkIHJlc2V0KCkgew0KCQlzZXRMYWJlbFZhbHVlKGZOdW1iZXJPZkVycm9ycywgMCk7DQoJCXNldExhYmVsVmFsdWUoZk51bWJlck9mRmFpbHVyZXMsIDApOw0KCQlzZXRMYWJlbFZhbHVlKGZOdW1iZXJPZlJ1bnMsIDApOw0KCQlmUHJvZ3Jlc3NJbmRpY2F0b3IucmVzZXQoKTsNCgkJZlJlcnVuQnV0dG9uLnNldEVuYWJsZWQoZmFsc2UpOw0KCQlmRmFpbHVyZUxpc3QucmVtb3ZlQWxsKCk7DQoJCWZFeGNlcHRpb25zPSBuZXcgVmVjdG9yKDEwKTsNCgkJZkZhaWxlZFRlc3RzPSBuZXcgVmVjdG9yKDEwKTsNCgkJZlRyYWNlQXJlYS5zZXRUZXh0KCIiKTsNCg0KCX0NCg0KCXByb3RlY3RlZCB2b2lkIHJ1bkZhaWxlZChTdHJpbmcgbWVzc2FnZSkgew0KCQlzaG93U3RhdHVzKG1lc3NhZ2UpOw0KCQlmUnVuLnNldExhYmVsKCJSdW4iKTsNCgkJZlJ1bm5lcj0gbnVsbDsNCgl9DQoNCglzeW5jaHJvbml6ZWQgcHVibGljIHZvaWQgcnVuU3VpdGUoKSB7DQoJCWlmIChmUnVubmVyICE9IG51bGwgJiYgZlRlc3RSZXN1bHQgIT0gbnVsbCkgew0KCQkJZlRlc3RSZXN1bHQuc3RvcCgpOw0KCQl9IGVsc2Ugew0KCQkJc2V0TG9hZGluZyhzaG91bGRSZWxvYWQoKSk7DQoJCQlmUnVuLnNldExhYmVsKCJTdG9wIik7DQoJCQlzaG93SW5mbygiSW5pdGlhbGl6aW5nLi4uIik7DQoJCQlyZXNldCgpOw0KDQoJCQlzaG93SW5mbygiTG9hZCBUZXN0IENhc2UuLi4iKTsNCg0KCQkJZmluYWwgVGVzdCB0ZXN0U3VpdGU9IGdldFRlc3QoZlN1aXRlRmllbGQuZ2V0VGV4dCgpKTsNCgkJCWlmICh0ZXN0U3VpdGUgIT0gbnVsbCkgew0KCQkJCWZSdW5uZXI9IG5ldyBUaHJlYWQoKSB7DQoJCQkJCXB1YmxpYyB2b2lkIHJ1bigpIHsNCgkJCQkJCWZUZXN0UmVzdWx0PSBjcmVhdGVUZXN0UmVzdWx0KCk7DQoJCQkJCQlmVGVzdFJlc3VsdC5hZGRMaXN0ZW5lcihUZXN0UnVubmVyLnRoaXMpOw0KCQkJCQkJZlByb2dyZXNzSW5kaWNhdG9yLnN0YXJ0KHRlc3RTdWl0ZS5jb3VudFRlc3RDYXNlcygpKTsNCgkJCQkJCXNob3dJbmZvKCJSdW5uaW5nLi4uIik7DQoNCgkJCQkJCWxvbmcgc3RhcnRUaW1lPSBTeXN0ZW0uY3VycmVudFRpbWVNaWxsaXMoKTsNCgkJCQkJCXRlc3RTdWl0ZS5ydW4oZlRlc3RSZXN1bHQpOw0KDQoJCQkJCQlpZiAoZlRlc3RSZXN1bHQuc2hvdWxkU3RvcCgpKSB7DQoJCQkJCQkJc2hvd1N0YXR1cygiU3RvcHBlZCIpOw0KCQkJCQkJfSBlbHNlIHsNCgkJCQkJCQlsb25nIGVuZFRpbWU9IFN5c3RlbS5jdXJyZW50VGltZU1pbGxpcygpOw0KCQkJCQkJCWxvbmcgcnVuVGltZT0gZW5kVGltZS1zdGFydFRpbWU7DQoJCQkJCQkJc2hvd0luZm8oIkZpbmlzaGVkOiAiICsgZWxhcHNlZFRpbWVBc1N0cmluZyhydW5UaW1lKSArICIgc2Vjb25kcyIpOw0KCQkJCQkJfQ0KCQkJCQkJZlRlc3RSZXN1bHQ9IG51bGw7DQoJCQkJCQlmUnVuLnNldExhYmVsKCJSdW4iKTsNCgkJCQkJCWZSdW5uZXI9IG51bGw7DQoJCQkJCQlTeXN0ZW0uZ2MoKTsNCgkJCQkJfQ0KCQkJCX07DQoJCQkJZlJ1bm5lci5zdGFydCgpOw0KCQkJfQ0KCQl9DQoJfQ0KDQoJcHJpdmF0ZSBib29sZWFuIHNob3VsZFJlbG9hZCgpIHsNCgkJcmV0dXJuICFpblZBSmF2YSgpICYmIGZVc2VMb2FkaW5nUnVubmVyLmdldFN0YXRlKCk7DQoJfQ0KDQoJcHJpdmF0ZSB2b2lkIHNldExhYmVsVmFsdWUoTGFiZWwgbGFiZWwsIGludCB2YWx1ZSkgew0KCQlsYWJlbC5zZXRUZXh0KEludGVnZXIudG9TdHJpbmcodmFsdWUpKTsNCgkJbGFiZWwuaW52YWxpZGF0ZSgpOw0KCQlsYWJlbC5nZXRQYXJlbnQoKS52YWxpZGF0ZSgpOw0KDQoJfQ0KDQoJcHVibGljIHZvaWQgc2V0U3VpdGVOYW1lKFN0cmluZyBzdWl0ZSkgew0KCQlmU3VpdGVGaWVsZC5zZXRUZXh0KHN1aXRlKTsNCgl9DQoNCglwcml2YXRlIHZvaWQgc2hvd0Vycm9yVHJhY2UoKSB7DQoJCWludCBpbmRleD0gZkZhaWx1cmVMaXN0LmdldFNlbGVjdGVkSW5kZXgoKTsNCgkJaWYgKGluZGV4ID09IC0xKQ0KCQkJcmV0dXJuOw0KDQoJCVRocm93YWJsZSB0PSAoVGhyb3dhYmxlKSBmRXhjZXB0aW9ucy5lbGVtZW50QXQoaW5kZXgpOw0KCQlmVHJhY2VBcmVhLnNldFRleHQoZ2V0RmlsdGVyZWRUcmFjZSh0KSk7DQoJfQ0KDQoNCglwcml2YXRlIHZvaWQgc2hvd0luZm8oU3RyaW5nIG1lc3NhZ2UpIHsNCgkJZlN0YXR1c0xpbmUuc2V0Rm9udChQTEFJTl9GT05UKTsNCgkJZlN0YXR1c0xpbmUuc2V0Rm9yZWdyb3VuZChDb2xvci5ibGFjayk7DQoJCWZTdGF0dXNMaW5lLnNldFRleHQobWVzc2FnZSk7DQoJfQ0KDQoJcHJvdGVjdGVkIHZvaWQgY2xlYXJTdGF0dXMoKSB7DQoJCXNob3dTdGF0dXMoIiIpOw0KCX0NCg0KCXByaXZhdGUgdm9pZCBzaG93U3RhdHVzKFN0cmluZyBzdGF0dXMpIHsNCgkJZlN0YXR1c0xpbmUuc2V0Rm9udChQTEFJTl9GT05UKTsNCgkJZlN0YXR1c0xpbmUuc2V0Rm9yZWdyb3VuZChDb2xvci5yZWQpOw0KCQlmU3RhdHVzTGluZS5zZXRUZXh0KHN0YXR1cyk7DQoJfQ0KCS8qKg0KCSAqIFN0YXJ0cyB0aGUgVGVzdFJ1bm5lcg0KCSAqLw0KCXB1YmxpYyB2b2lkIHN0YXJ0KFN0cmluZ1tdIGFyZ3MpIHsNCgkJU3RyaW5nIHN1aXRlTmFtZT0gcHJvY2Vzc0FyZ3VtZW50cyhhcmdzKTsNCgkJZkZyYW1lPSBjcmVhdGVVSShzdWl0ZU5hbWUpOw0KCQlmRnJhbWUuc2V0TG9jYXRpb24oMjAwLCAyMDApOw0KCQlmRnJhbWUuc2V0VmlzaWJsZSh0cnVlKTsNCg0KCQlpZiAoc3VpdGVOYW1lICE9IG51bGwpIHsNCgkJCXNldFN1aXRlTmFtZShzdWl0ZU5hbWUpOw0KCQkJcnVuU3VpdGUoKTsNCgkJfQ0KCX0NCn1QSwMECgAAAAAA6njHMLE2ffdyAwAAcgMAAB8AAABqdW5pdC9leHRlbnNpb25zL1Rlc3RTZXR1cC5qYXZhcGFja2FnZSBqdW5pdC5leHRlbnNpb25zOw0KDQppbXBvcnQganVuaXQuZnJhbWV3b3JrLio7DQoNCi8qKg0KICogQSBEZWNvcmF0b3IgdG8gc2V0IHVwIGFuZCB0ZWFyIGRvd24gYWRkaXRpb25hbCBmaXh0dXJlIHN0YXRlLg0KICogU3ViY2xhc3MgVGVzdFNldHVwIGFuZCBpbnNlcnQgaXQgaW50byB5b3VyIHRlc3RzIHdoZW4geW91IHdhbnQNCiAqIHRvIHNldCB1cCBhZGRpdGlvbmFsIHN0YXRlIG9uY2UgYmVmb3JlIHRoZSB0ZXN0cyBhcmUgcnVuLg0KICovDQpwdWJsaWMgY2xhc3MgVGVzdFNldHVwIGV4dGVuZHMgVGVzdERlY29yYXRvciB7DQoNCglwdWJsaWMgVGVzdFNldHVwKFRlc3QgdGVzdCkgew0KCQlzdXBlcih0ZXN0KTsNCgl9DQoJcHVibGljIHZvaWQgcnVuKGZpbmFsIFRlc3RSZXN1bHQgcmVzdWx0KSB7DQoJCVByb3RlY3RhYmxlIHA9IG5ldyBQcm90ZWN0YWJsZSgpIHsNCgkJCXB1YmxpYyB2b2lkIHByb3RlY3QoKSB0aHJvd3MgRXhjZXB0aW9uIHsNCgkJCQlzZXRVcCgpOw0KCQkJCWJhc2ljUnVuKHJlc3VsdCk7DQoJCQkJdGVhckRvd24oKTsNCgkJCX0NCgkJfTsNCgkJcmVzdWx0LnJ1blByb3RlY3RlZCh0aGlzLCBwKTsNCgl9DQoJLyoqDQoJICogU2V0cyB1cCB0aGUgZml4dHVyZS4gT3ZlcnJpZGUgdG8gc2V0IHVwIGFkZGl0aW9uYWwgZml4dHVyZQ0KCSAqIHN0YXRlLg0KCSAqLw0KCXByb3RlY3RlZCB2b2lkIHNldFVwKCkgdGhyb3dzIEV4Y2VwdGlvbiB7DQoJfQ0KCS8qKg0KCSAqIFRlYXJzIGRvd24gdGhlIGZpeHR1cmUuIE92ZXJyaWRlIHRvIHRlYXIgZG93biB0aGUgYWRkaXRpb25hbA0KCSAqIGZpeHR1cmUgc3RhdGUuDQoJICovDQoJcHJvdGVjdGVkIHZvaWQgdGVhckRvd24oKSB0aHJvd3MgRXhjZXB0aW9uIHsNCgl9DQp9UEsDBAoAAAAAAOp4xzBTc+QMtwIAALcCAAAiAAAAanVuaXQvZXh0ZW5zaW9ucy9SZXBlYXRlZFRlc3QuamF2YXBhY2thZ2UganVuaXQuZXh0ZW5zaW9uczsNCg0KaW1wb3J0IGp1bml0LmZyYW1ld29yay4qOw0KDQovKioNCiAqIEEgRGVjb3JhdG9yIHRoYXQgcnVucyBhIHRlc3QgcmVwZWF0ZWRseS4NCiAqDQogKi8NCnB1YmxpYyBjbGFzcyBSZXBlYXRlZFRlc3QgZXh0ZW5kcyAgVGVzdERlY29yYXRvciB7DQoJcHJpdmF0ZSBpbnQgZlRpbWVzUmVwZWF0Ow0KDQoJcHVibGljIFJlcGVhdGVkVGVzdChUZXN0IHRlc3QsIGludCByZXBlYXQpIHsNCgkJc3VwZXIodGVzdCk7DQoJCWlmIChyZXBlYXQgPCAwKQ0KCQkJdGhyb3cgbmV3IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigiUmVwZXRpdGlvbiBjb3VudCBtdXN0IGJlID4gMCIpOw0KCQlmVGltZXNSZXBlYXQ9IHJlcGVhdDsNCgl9DQoJcHVibGljIGludCBjb3VudFRlc3RDYXNlcygpIHsNCgkJcmV0dXJuIHN1cGVyLmNvdW50VGVzdENhc2VzKCkqZlRpbWVzUmVwZWF0Ow0KCX0NCglwdWJsaWMgdm9pZCBydW4oVGVzdFJlc3VsdCByZXN1bHQpIHsNCgkJZm9yIChpbnQgaT0gMDsgaSA8IGZUaW1lc1JlcGVhdDsgaSsrKSB7DQoJCQlpZiAocmVzdWx0LnNob3VsZFN0b3AoKSkNCgkJCQlicmVhazsNCgkJCXN1cGVyLnJ1bihyZXN1bHQpOw0KCQl9DQoJfQ0KCXB1YmxpYyBTdHJpbmcgdG9TdHJpbmcoKSB7DQoJCXJldHVybiBzdXBlci50b1N0cmluZygpKyIocmVwZWF0ZWQpIjsNCgl9DQp9UEsDBAoAAAAAAOp4xzBreLp3YgUAAGIFAAAlAAAAanVuaXQvZXh0ZW5zaW9ucy9BY3RpdmVUZXN0U3VpdGUuamF2YXBhY2thZ2UganVuaXQuZXh0ZW5zaW9uczsNCg0KaW1wb3J0IGp1bml0LmZyYW1ld29yay4qOw0KDQovKioNCiAqIEEgVGVzdFN1aXRlIGZvciBhY3RpdmUgVGVzdHMuIEl0IHJ1bnMgZWFjaA0KICogdGVzdCBpbiBhIHNlcGFyYXRlIHRocmVhZCBhbmQgd2FpdHMgdW50aWwgYWxsDQogKiB0aHJlYWRzIGhhdmUgdGVybWluYXRlZC4NCiAqIC0tIEFhcmh1cyBSYWRpc3NvbiBTY2FuZGluYXZpYW4gQ2VudGVyIDExdGggZmxvb3INCiAqLyANCnB1YmxpYyBjbGFzcyBBY3RpdmVUZXN0U3VpdGUgZXh0ZW5kcyBUZXN0U3VpdGUgew0KCXByaXZhdGUgdm9sYXRpbGUgaW50IGZBY3RpdmVUZXN0RGVhdGhDb3VudDsNCg0KCXB1YmxpYyBBY3RpdmVUZXN0U3VpdGUoKSB7DQoJfQ0KCQkNCglwdWJsaWMgQWN0aXZlVGVzdFN1aXRlKENsYXNzIHRoZUNsYXNzKSB7DQoJCXN1cGVyKHRoZUNsYXNzKTsNCgl9DQoJDQoJcHVibGljIEFjdGl2ZVRlc3RTdWl0ZShTdHJpbmcgbmFtZSkgew0KCQlzdXBlciAobmFtZSk7DQoJfQ0KCQ0KCXB1YmxpYyBBY3RpdmVUZXN0U3VpdGUoQ2xhc3MgdGhlQ2xhc3MsIFN0cmluZyBuYW1lKSB7DQoJCXN1cGVyKHRoZUNsYXNzLCBuYW1lKTsNCgl9DQoJDQoJcHVibGljIHZvaWQgcnVuKFRlc3RSZXN1bHQgcmVzdWx0KSB7DQoJCWZBY3RpdmVUZXN0RGVhdGhDb3VudD0gMDsNCgkJc3VwZXIucnVuKHJlc3VsdCk7DQoJCXdhaXRVbnRpbEZpbmlzaGVkKCk7DQoJfQ0KCQ0KCXB1YmxpYyB2b2lkIHJ1blRlc3QoZmluYWwgVGVzdCB0ZXN0LCBmaW5hbCBUZXN0UmVzdWx0IHJlc3VsdCkgew0KCQlUaHJlYWQgdD0gbmV3IFRocmVhZCgpIHsNCgkJCXB1YmxpYyB2b2lkIHJ1bigpIHsNCgkJCQl0cnkgew0KCQkJCQkvLyBpbmxpbmVkIGR1ZSB0byBsaW1pdGF0aW9uIGluIFZBL0phdmEgDQoJCQkJCS8vQWN0aXZlVGVzdFN1aXRlLnN1cGVyLnJ1blRlc3QodGVzdCwgcmVzdWx0KTsNCgkJCQkJdGVzdC5ydW4ocmVzdWx0KTsNCgkJCQl9IGZpbmFsbHkgew0KCQkJCQlBY3RpdmVUZXN0U3VpdGUudGhpcy5ydW5GaW5pc2hlZCh0ZXN0KTsNCgkJCQl9DQoJCQl9DQoJCX07DQoJCXQuc3RhcnQoKTsNCgl9DQoNCglzeW5jaHJvbml6ZWQgdm9pZCB3YWl0VW50aWxGaW5pc2hlZCgpIHsNCgkJd2hpbGUgKGZBY3RpdmVUZXN0RGVhdGhDb3VudCA8IHRlc3RDb3VudCgpKSB7DQoJCQl0cnkgew0KCQkJCXdhaXQoKTsNCgkJCX0gY2F0Y2ggKEludGVycnVwdGVkRXhjZXB0aW9uIGUpIHsNCgkJCQlyZXR1cm47IC8vIGlnbm9yZQ0KCQkJfQ0KCQl9DQoJfQ0KCQ0KCXN5bmNocm9uaXplZCBwdWJsaWMgdm9pZCBydW5GaW5pc2hlZChUZXN0IHRlc3QpIHsNCgkJZkFjdGl2ZVRlc3REZWF0aENvdW50Kys7DQoJCW5vdGlmeUFsbCgpOw0KCX0NCn1QSwMECgAAAAAA6njHMHpcHUkHAwAABwMAACMAAABqdW5pdC9leHRlbnNpb25zL1Rlc3REZWNvcmF0b3IuamF2YXBhY2thZ2UganVuaXQuZXh0ZW5zaW9uczsNCg0KaW1wb3J0IGp1bml0LmZyYW1ld29yay4qOw0KDQovKioNCiAqIEEgRGVjb3JhdG9yIGZvciBUZXN0cy4gVXNlIFRlc3REZWNvcmF0b3IgYXMgdGhlIGJhc2UgY2xhc3MNCiAqIGZvciBkZWZpbmluZyBuZXcgdGVzdCBkZWNvcmF0b3JzLiBUZXN0IGRlY29yYXRvciBzdWJjbGFzc2VzDQogKiBjYW4gYmUgaW50cm9kdWNlZCB0byBhZGQgYmVoYXZpb3VyIGJlZm9yZSBvciBhZnRlciBhIHRlc3QNCiAqIGlzIHJ1bi4NCiAqDQogKi8NCnB1YmxpYyBjbGFzcyBUZXN0RGVjb3JhdG9yIGV4dGVuZHMgQXNzZXJ0IGltcGxlbWVudHMgVGVzdCB7DQoJcHJvdGVjdGVkIFRlc3QgZlRlc3Q7DQoNCglwdWJsaWMgVGVzdERlY29yYXRvcihUZXN0IHRlc3QpIHsNCgkJZlRlc3Q9IHRlc3Q7DQoJfQ0KCS8qKg0KCSAqIFRoZSBiYXNpYyBydW4gYmVoYXZpb3VyLg0KCSAqLw0KCXB1YmxpYyB2b2lkIGJhc2ljUnVuKFRlc3RSZXN1bHQgcmVzdWx0KSB7DQoJCWZUZXN0LnJ1bihyZXN1bHQpOw0KCX0NCglwdWJsaWMgaW50IGNvdW50VGVzdENhc2VzKCkgew0KCQlyZXR1cm4gZlRlc3QuY291bnRUZXN0Q2FzZXMoKTsNCgl9DQoJcHVibGljIHZvaWQgcnVuKFRlc3RSZXN1bHQgcmVzdWx0KSB7DQoJCWJhc2ljUnVuKHJlc3VsdCk7DQoJfQ0KDQoJcHVibGljIFN0cmluZyB0b1N0cmluZygpIHsNCgkJcmV0dXJuIGZUZXN0LnRvU3RyaW5nKCk7DQoJfQ0KDQoJcHVibGljIFRlc3QgZ2V0VGVzdCgpIHsNCgkJcmV0dXJuIGZUZXN0Ow0KCX0NCn1QSwMECgAAAAAA6njHML9dpZ0oBAAAKAQAACcAAABqdW5pdC9leHRlbnNpb25zL0V4Y2VwdGlvblRlc3RDYXNlLmphdmFwYWNrYWdlIGp1bml0LmV4dGVuc2lvbnM7DQoNCmltcG9ydCBqdW5pdC5mcmFtZXdvcmsuKjsNCg0KLyoqDQogKiBBIFRlc3RDYXNlIHRoYXQgZXhwZWN0cyBhbiBFeGNlcHRpb24gb2YgY2xhc3MgZkV4cGVjdGVkIHRvIGJlIHRocm93bi4NCiAqIFRoZSBvdGhlciB3YXkgdG8gY2hlY2sgdGhhdCBhbiBleHBlY3RlZCBleGNlcHRpb24gaXMgdGhyb3duIGlzOg0KICogPHByZT4NCiAqIHRyeSB7DQogKiAgIHNob3VsZFRocm93KCk7DQogKiB9DQogKiBjYXRjaCAoU3BlY2lhbEV4Y2VwdGlvbiBlKSB7DQogKiAgIHJldHVybjsNCiAqIH0NCiAqIGZhaWwoIkV4cGVjdGVkIFNwZWNpYWxFeGNlcHRpb24iKTsNCiAqIDwvcHJlPg0KICoNCiAqIFRvIHVzZSBFeGNlcHRpb25UZXN0Q2FzZSwgY3JlYXRlIGEgVGVzdENhc2UgbGlrZToNCiAqIDxwcmU+DQogKiBuZXcgRXhjZXB0aW9uVGVzdENhc2UoInRlc3RTaG91bGRUaHJvdyIsIFNwZWNpYWxFeGNlcHRpb24uY2xhc3MpOw0KICogPC9wcmU+DQogKi8NCnB1YmxpYyBjbGFzcyBFeGNlcHRpb25UZXN0Q2FzZSBleHRlbmRzIFRlc3RDYXNlIHsNCglDbGFzcyBmRXhwZWN0ZWQ7DQoNCglwdWJsaWMgRXhjZXB0aW9uVGVzdENhc2UoU3RyaW5nIG5hbWUsIENsYXNzIGV4Y2VwdGlvbikgew0KCQlzdXBlcihuYW1lKTsNCgkJZkV4cGVjdGVkPSBleGNlcHRpb247DQoJfQ0KCS8qKg0KCSAqIEV4ZWN1dGUgdGhlIHRlc3QgbWV0aG9kIGV4cGVjdGluZyB0aGF0IGFuIEV4Y2VwdGlvbiBvZg0KCSAqIGNsYXNzIGZFeHBlY3RlZCBvciBvbmUgb2YgaXRzIHN1YmNsYXNzZXMgd2lsbCBiZSB0aHJvd24NCgkgKi8NCglwcm90ZWN0ZWQgdm9pZCBydW5UZXN0KCkgdGhyb3dzIFRocm93YWJsZSB7DQoJCXRyeSB7DQoJCQlzdXBlci5ydW5UZXN0KCk7DQoJCX0NCgkJY2F0Y2ggKEV4Y2VwdGlvbiBlKSB7DQoJCQlpZiAoZkV4cGVjdGVkLmlzQXNzaWduYWJsZUZyb20oZS5nZXRDbGFzcygpKSkNCgkJCQlyZXR1cm47DQoJCQllbHNlDQoJCQkJdGhyb3cgZTsNCgkJfQ0KCQlmYWlsKCJFeHBlY3RlZCBleGNlcHRpb24gIiArIGZFeHBlY3RlZCk7DQoJfQ0KfVBLAwQKAAAAAADqeMcwwzvNe/EAAADxAAAAKQAAAGp1bml0L2ZyYW1ld29yay9Bc3NlcnRpb25GYWlsZWRFcnJvci5qYXZhcGFja2FnZSBqdW5pdC5mcmFtZXdvcms7DQoNCi8qKg0KICogVGhyb3duIHdoZW4gYW4gYXNzZXJ0aW9uIGZhaWxlZC4NCiAqLw0KcHVibGljIGNsYXNzIEFzc2VydGlvbkZhaWxlZEVycm9yIGV4dGVuZHMgRXJyb3Igew0KDQoJcHVibGljIEFzc2VydGlvbkZhaWxlZEVycm9yICgpIHsNCgl9DQoJcHVibGljIEFzc2VydGlvbkZhaWxlZEVycm9yIChTdHJpbmcgbWVzc2FnZSkgew0KCQlzdXBlciAobWVzc2FnZSk7DQoJfQ0KfVBLAwQKAAAAAADqeMcwWIrZAaQFAACkBQAAIAAAAGp1bml0L2ZyYW1ld29yay9UZXN0RmFpbHVyZS5qYXZhcGFja2FnZSBqdW5pdC5mcmFtZXdvcms7DQoNCmltcG9ydCBqYXZhLmlvLlByaW50V3JpdGVyOw0KaW1wb3J0IGphdmEuaW8uU3RyaW5nV3JpdGVyOw0KDQoNCi8qKg0KICogQSA8Y29kZT5UZXN0RmFpbHVyZTwvY29kZT4gY29sbGVjdHMgYSBmYWlsZWQgdGVzdCB0b2dldGhlciB3aXRoDQogKiB0aGUgY2F1Z2h0IGV4Y2VwdGlvbi4NCiAqIEBzZWUgVGVzdFJlc3VsdA0KICovDQpwdWJsaWMgY2xhc3MgVGVzdEZhaWx1cmUgZXh0ZW5kcyBPYmplY3Qgew0KCXByb3RlY3RlZCBUZXN0IGZGYWlsZWRUZXN0Ow0KCXByb3RlY3RlZCBUaHJvd2FibGUgZlRocm93bkV4Y2VwdGlvbjsNCgkNCg0KCS8qKg0KCSAqIENvbnN0cnVjdHMgYSBUZXN0RmFpbHVyZSB3aXRoIHRoZSBnaXZlbiB0ZXN0IGFuZCBleGNlcHRpb24uDQoJICovDQoJcHVibGljIFRlc3RGYWlsdXJlKFRlc3QgZmFpbGVkVGVzdCwgVGhyb3dhYmxlIHRocm93bkV4Y2VwdGlvbikgew0KCQlmRmFpbGVkVGVzdD0gZmFpbGVkVGVzdDsNCgkJZlRocm93bkV4Y2VwdGlvbj0gdGhyb3duRXhjZXB0aW9uOw0KCX0NCgkvKioNCgkgKiBHZXRzIHRoZSBmYWlsZWQgdGVzdC4NCgkgKi8NCglwdWJsaWMgVGVzdCBmYWlsZWRUZXN0KCkgew0KCSAgICByZXR1cm4gZkZhaWxlZFRlc3Q7DQoJfQ0KCS8qKg0KCSAqIEdldHMgdGhlIHRocm93biBleGNlcHRpb24uDQoJICovDQoJcHVibGljIFRocm93YWJsZSB0aHJvd25FeGNlcHRpb24oKSB7DQoJICAgIHJldHVybiBmVGhyb3duRXhjZXB0aW9uOw0KCX0NCgkvKioNCgkgKiBSZXR1cm5zIGEgc2hvcnQgZGVzY3JpcHRpb24gb2YgdGhlIGZhaWx1cmUuDQoJICovDQoJcHVibGljIFN0cmluZyB0b1N0cmluZygpIHsNCgkgICAgU3RyaW5nQnVmZmVyIGJ1ZmZlcj0gbmV3IFN0cmluZ0J1ZmZlcigpOw0KCSAgICBidWZmZXIuYXBwZW5kKGZGYWlsZWRUZXN0KyI6ICIrZlRocm93bkV4Y2VwdGlvbi5nZXRNZXNzYWdlKCkpOw0KCSAgICByZXR1cm4gYnVmZmVyLnRvU3RyaW5nKCk7DQoJfQ0KCXB1YmxpYyBTdHJpbmcgdHJhY2UoKSB7DQoJCVN0cmluZ1dyaXRlciBzdHJpbmdXcml0ZXI9IG5ldyBTdHJpbmdXcml0ZXIoKTsNCgkJUHJpbnRXcml0ZXIgd3JpdGVyPSBuZXcgUHJpbnRXcml0ZXIoc3RyaW5nV3JpdGVyKTsNCgkJdGhyb3duRXhjZXB0aW9uKCkucHJpbnRTdGFja1RyYWNlKHdyaXRlcik7DQoJCVN0cmluZ0J1ZmZlciBidWZmZXI9IHN0cmluZ1dyaXRlci5nZXRCdWZmZXIoKTsNCgkJcmV0dXJuIGJ1ZmZlci50b1N0cmluZygpOw0KCX0NCglwdWJsaWMgU3RyaW5nIGV4Y2VwdGlvbk1lc3NhZ2UoKSB7DQoJCXJldHVybiB0aHJvd25FeGNlcHRpb24oKS5nZXRNZXNzYWdlKCk7DQoJfQ0KCXB1YmxpYyBib29sZWFuIGlzRmFpbHVyZSgpIHsNCgkJcmV0dXJuIHRocm93bkV4Y2VwdGlvbigpIGluc3RhbmNlb2YgQXNzZXJ0aW9uRmFpbGVkRXJyb3I7DQoJfQ0KfVBLAwQKAAAAAADqeMcwNjfDyoYBAACGAQAAGQAAAGp1bml0L2ZyYW1ld29yay9UZXN0LmphdmFwYWNrYWdlIGp1bml0LmZyYW1ld29yazsNCg0KLyoqDQogKiBBIDxlbT5UZXN0PC9lbT4gY2FuIGJlIHJ1biBhbmQgY29sbGVjdCBpdHMgcmVzdWx0cy4NCiAqDQogKiBAc2VlIFRlc3RSZXN1bHQNCiAqLw0KcHVibGljIGludGVyZmFjZSBUZXN0IHsNCgkvKioNCgkgKiBDb3VudHMgdGhlIG51bWJlciBvZiB0ZXN0IGNhc2VzIHRoYXQgd2lsbCBiZSBydW4gYnkgdGhpcyB0ZXN0Lg0KCSAqLw0KCXB1YmxpYyBhYnN0cmFjdCBpbnQgY291bnRUZXN0Q2FzZXMoKTsNCgkvKioNCgkgKiBSdW5zIGEgdGVzdCBhbmQgY29sbGVjdHMgaXRzIHJlc3VsdCBpbiBhIFRlc3RSZXN1bHQgaW5zdGFuY2UuDQoJICovDQoJcHVibGljIGFic3RyYWN0IHZvaWQgcnVuKFRlc3RSZXN1bHQgcmVzdWx0KTsNCn1QSwMECgAAAAAA6njHMMU6q/wOAQAADgEAACAAAABqdW5pdC9mcmFtZXdvcmsvUHJvdGVjdGFibGUuamF2YXBhY2thZ2UganVuaXQuZnJhbWV3b3JrOw0KDQovKioNCiAqIEEgPGVtPlByb3RlY3RhYmxlPC9lbT4gY2FuIGJlIHJ1biBhbmQgY2FuIHRocm93IGEgVGhyb3dhYmxlLg0KICoNCiAqIEBzZWUgVGVzdFJlc3VsdA0KICovDQpwdWJsaWMgaW50ZXJmYWNlIFByb3RlY3RhYmxlIHsNCg0KCS8qKg0KCSAqIFJ1biB0aGUgdGhlIGZvbGxvd2luZyBtZXRob2QgcHJvdGVjdGVkLg0KCSAqLw0KCXB1YmxpYyBhYnN0cmFjdCB2b2lkIHByb3RlY3QoKSB0aHJvd3MgVGhyb3dhYmxlOw0KfVBLAwQKAAAAAADqeMcwYMFI/WoQAABqEAAAHwAAAGp1bml0L2ZyYW1ld29yay9UZXN0UmVzdWx0LmphdmFwYWNrYWdlIGp1bml0LmZyYW1ld29yazsNCg0KaW1wb3J0IGphdmEudXRpbC5WZWN0b3I7DQppbXBvcnQgamF2YS51dGlsLkVudW1lcmF0aW9uOw0KDQovKioNCiAqIEEgPGNvZGU+VGVzdFJlc3VsdDwvY29kZT4gY29sbGVjdHMgdGhlIHJlc3VsdHMgb2YgZXhlY3V0aW5nDQogKiBhIHRlc3QgY2FzZS4gSXQgaXMgYW4gaW5zdGFuY2Ugb2YgdGhlIENvbGxlY3RpbmcgUGFyYW1ldGVyIHBhdHRlcm4uDQogKiBUaGUgdGVzdCBmcmFtZXdvcmsgZGlzdGluZ3Vpc2hlcyBiZXR3ZWVuIDxpPmZhaWx1cmVzPC9pPiBhbmQgPGk+ZXJyb3JzPC9pPi4NCiAqIEEgZmFpbHVyZSBpcyBhbnRpY2lwYXRlZCBhbmQgY2hlY2tlZCBmb3Igd2l0aCBhc3NlcnRpb25zLiBFcnJvcnMgYXJlDQogKiB1bmFudGljaXBhdGVkIHByb2JsZW1zIGxpa2UgYW4gPGNvZGU+QXJyYXlJbmRleE91dE9mQm91bmRzRXhjZXB0aW9uPC9jb2RlPi4NCiAqDQogKiBAc2VlIFRlc3QNCiAqLw0KcHVibGljIGNsYXNzIFRlc3RSZXN1bHQgZXh0ZW5kcyBPYmplY3Qgew0KCXByb3RlY3RlZCBWZWN0b3IgZkZhaWx1cmVzOw0KCXByb3RlY3RlZCBWZWN0b3IgZkVycm9yczsNCglwcm90ZWN0ZWQgVmVjdG9yIGZMaXN0ZW5lcnM7DQoJcHJvdGVjdGVkIGludCBmUnVuVGVzdHM7DQoJcHJpdmF0ZSBib29sZWFuIGZTdG9wOw0KCQ0KCXB1YmxpYyBUZXN0UmVzdWx0KCkgew0KCQlmRmFpbHVyZXM9IG5ldyBWZWN0b3IoKTsNCgkJZkVycm9ycz0gbmV3IFZlY3RvcigpOw0KCQlmTGlzdGVuZXJzPSBuZXcgVmVjdG9yKCk7DQoJCWZSdW5UZXN0cz0gMDsNCgkJZlN0b3A9IGZhbHNlOw0KCX0NCgkvKioNCgkgKiBBZGRzIGFuIGVycm9yIHRvIHRoZSBsaXN0IG9mIGVycm9ycy4gVGhlIHBhc3NlZCBpbiBleGNlcHRpb24NCgkgKiBjYXVzZWQgdGhlIGVycm9yLg0KCSAqLw0KCXB1YmxpYyBzeW5jaHJvbml6ZWQgdm9pZCBhZGRFcnJvcihUZXN0IHRlc3QsIFRocm93YWJsZSB0KSB7DQoJCWZFcnJvcnMuYWRkRWxlbWVudChuZXcgVGVzdEZhaWx1cmUodGVzdCwgdCkpOw0KCQlmb3IgKEVudW1lcmF0aW9uIGU9IGNsb25lTGlzdGVuZXJzKCkuZWxlbWVudHMoKTsgZS5oYXNNb3JlRWxlbWVudHMoKTsgKSB7DQoJCQkoKFRlc3RMaXN0ZW5lcillLm5leHRFbGVtZW50KCkpLmFkZEVycm9yKHRlc3QsIHQpOw0KCQl9DQoJfQ0KCS8qKg0KCSAqIEFkZHMgYSBmYWlsdXJlIHRvIHRoZSBsaXN0IG9mIGZhaWx1cmVzLiBUaGUgcGFzc2VkIGluIGV4Y2VwdGlvbg0KCSAqIGNhdXNlZCB0aGUgZmFpbHVyZS4NCgkgKi8NCglwdWJsaWMgc3luY2hyb25pemVkIHZvaWQgYWRkRmFpbHVyZShUZXN0IHRlc3QsIEFzc2VydGlvbkZhaWxlZEVycm9yIHQpIHsNCgkJZkZhaWx1cmVzLmFkZEVsZW1lbnQobmV3IFRlc3RGYWlsdXJlKHRlc3QsIHQpKTsNCgkJZm9yIChFbnVtZXJhdGlvbiBlPSBjbG9uZUxpc3RlbmVycygpLmVsZW1lbnRzKCk7IGUuaGFzTW9yZUVsZW1lbnRzKCk7ICkgew0KCQkJKChUZXN0TGlzdGVuZXIpZS5uZXh0RWxlbWVudCgpKS5hZGRGYWlsdXJlKHRlc3QsIHQpOw0KCQl9DQoJfQ0KCS8qKg0KCSAqIFJlZ2lzdGVycyBhIFRlc3RMaXN0ZW5lcg0KCSAqLw0KCXB1YmxpYyBzeW5jaHJvbml6ZWQgdm9pZCBhZGRMaXN0ZW5lcihUZXN0TGlzdGVuZXIgbGlzdGVuZXIpIHsNCgkJZkxpc3RlbmVycy5hZGRFbGVtZW50KGxpc3RlbmVyKTsNCgl9DQoJLyoqDQoJICogVW5yZWdpc3RlcnMgYSBUZXN0TGlzdGVuZXINCgkgKi8NCglwdWJsaWMgc3luY2hyb25pemVkIHZvaWQgcmVtb3ZlTGlzdGVuZXIoVGVzdExpc3RlbmVyIGxpc3RlbmVyKSB7DQoJCWZMaXN0ZW5lcnMucmVtb3ZlRWxlbWVudChsaXN0ZW5lcik7DQoJfQ0KCS8qKg0KCSAqIFJldHVybnMgYSBjb3B5IG9mIHRoZSBsaXN0ZW5lcnMuDQoJICovDQoJcHJpdmF0ZSBzeW5jaHJvbml6ZWQgVmVjdG9yIGNsb25lTGlzdGVuZXJzKCkgew0KCQlyZXR1cm4gKFZlY3RvcilmTGlzdGVuZXJzLmNsb25lKCk7DQoJfQ0KCS8qKg0KCSAqIEluZm9ybXMgdGhlIHJlc3VsdCB0aGF0IGEgdGVzdCB3YXMgY29tcGxldGVkLg0KCSAqLw0KCXB1YmxpYyB2b2lkIGVuZFRlc3QoVGVzdCB0ZXN0KSB7DQoJCWZvciAoRW51bWVyYXRpb24gZT0gY2xvbmVMaXN0ZW5lcnMoKS5lbGVtZW50cygpOyBlLmhhc01vcmVFbGVtZW50cygpOyApIHsNCgkJCSgoVGVzdExpc3RlbmVyKWUubmV4dEVsZW1lbnQoKSkuZW5kVGVzdCh0ZXN0KTsNCgkJfQ0KCX0NCgkvKioNCgkgKiBHZXRzIHRoZSBudW1iZXIgb2YgZGV0ZWN0ZWQgZXJyb3JzLg0KCSAqLw0KCXB1YmxpYyBzeW5jaHJvbml6ZWQgaW50IGVycm9yQ291bnQoKSB7DQoJCXJldHVybiBmRXJyb3JzLnNpemUoKTsNCgl9DQoJLyoqDQoJICogUmV0dXJucyBhbiBFbnVtZXJhdGlvbiBmb3IgdGhlIGVycm9ycw0KCSAqLw0KCXB1YmxpYyBzeW5jaHJvbml6ZWQgRW51bWVyYXRpb24gZXJyb3JzKCkgew0KCQlyZXR1cm4gZkVycm9ycy5lbGVtZW50cygpOw0KCX0NCgkvKioNCgkgKiBHZXRzIHRoZSBudW1iZXIgb2YgZGV0ZWN0ZWQgZmFpbHVyZXMuDQoJICovDQoJcHVibGljIHN5bmNocm9uaXplZCBpbnQgZmFpbHVyZUNvdW50KCkgew0KCQlyZXR1cm4gZkZhaWx1cmVzLnNpemUoKTsNCgl9DQoJLyoqDQoJICogUmV0dXJucyBhbiBFbnVtZXJhdGlvbiBmb3IgdGhlIGZhaWx1cmVzDQoJICovDQoJcHVibGljIHN5bmNocm9uaXplZCBFbnVtZXJhdGlvbiBmYWlsdXJlcygpIHsNCgkJcmV0dXJuIGZGYWlsdXJlcy5lbGVtZW50cygpOw0KCX0NCgkvKioNCgkgKiBSdW5zIGEgVGVzdENhc2UuDQoJICovDQoJcHJvdGVjdGVkIHZvaWQgcnVuKGZpbmFsIFRlc3RDYXNlIHRlc3QpIHsNCgkJc3RhcnRUZXN0KHRlc3QpOw0KCQlQcm90ZWN0YWJsZSBwPSBuZXcgUHJvdGVjdGFibGUoKSB7DQoJCQlwdWJsaWMgdm9pZCBwcm90ZWN0KCkgdGhyb3dzIFRocm93YWJsZSB7DQoJCQkJdGVzdC5ydW5CYXJlKCk7DQoJCQl9DQoJCX07DQoJCXJ1blByb3RlY3RlZCh0ZXN0LCBwKTsNCg0KCQllbmRUZXN0KHRlc3QpOw0KCX0NCgkvKioNCgkgKiBHZXRzIHRoZSBudW1iZXIgb2YgcnVuIHRlc3RzLg0KCSAqLw0KCXB1YmxpYyBzeW5jaHJvbml6ZWQgaW50IHJ1bkNvdW50KCkgew0KCQlyZXR1cm4gZlJ1blRlc3RzOw0KCX0NCgkvKioNCgkgKiBSdW5zIGEgVGVzdENhc2UuDQoJICovDQoJcHVibGljIHZvaWQgcnVuUHJvdGVjdGVkKGZpbmFsIFRlc3QgdGVzdCwgUHJvdGVjdGFibGUgcCkgew0KCQl0cnkgew0KCQkJcC5wcm90ZWN0KCk7DQoJCX0gDQoJCWNhdGNoIChBc3NlcnRpb25GYWlsZWRFcnJvciBlKSB7DQoJCQlhZGRGYWlsdXJlKHRlc3QsIGUpOw0KCQl9DQoJCWNhdGNoIChUaHJlYWREZWF0aCBlKSB7IC8vIGRvbid0IGNhdGNoIFRocmVhZERlYXRoIGJ5IGFjY2lkZW50DQoJCQl0aHJvdyBlOw0KCQl9DQoJCWNhdGNoIChUaHJvd2FibGUgZSkgew0KCQkJYWRkRXJyb3IodGVzdCwgZSk7DQoJCX0NCgl9DQoJLyoqDQoJICogQ2hlY2tzIHdoZXRoZXIgdGhlIHRlc3QgcnVuIHNob3VsZCBzdG9wDQoJICovDQoJcHVibGljIHN5bmNocm9uaXplZCBib29sZWFuIHNob3VsZFN0b3AoKSB7DQoJCXJldHVybiBmU3RvcDsNCgl9DQoJLyoqDQoJICogSW5mb3JtcyB0aGUgcmVzdWx0IHRoYXQgYSB0ZXN0IHdpbGwgYmUgc3RhcnRlZC4NCgkgKi8NCglwdWJsaWMgdm9pZCBzdGFydFRlc3QoVGVzdCB0ZXN0KSB7DQoJCWZpbmFsIGludCBjb3VudD0gdGVzdC5jb3VudFRlc3RDYXNlcygpOw0KCQlzeW5jaHJvbml6ZWQodGhpcykgew0KCQkJZlJ1blRlc3RzKz0gY291bnQ7DQoJCX0NCgkJZm9yIChFbnVtZXJhdGlvbiBlPSBjbG9uZUxpc3RlbmVycygpLmVsZW1lbnRzKCk7IGUuaGFzTW9yZUVsZW1lbnRzKCk7ICkgew0KCQkJKChUZXN0TGlzdGVuZXIpZS5uZXh0RWxlbWVudCgpKS5zdGFydFRlc3QodGVzdCk7DQoJCX0NCgl9DQoJLyoqDQoJICogTWFya3MgdGhhdCB0aGUgdGVzdCBydW4gc2hvdWxkIHN0b3AuDQoJICovDQoJcHVibGljIHN5bmNocm9uaXplZCB2b2lkIHN0b3AoKSB7DQoJCWZTdG9wPSB0cnVlOw0KCX0NCgkvKioNCgkgKiBSZXR1cm5zIHdoZXRoZXIgdGhlIGVudGlyZSB0ZXN0IHdhcyBzdWNjZXNzZnVsIG9yIG5vdC4NCgkgKi8NCglwdWJsaWMgc3luY2hyb25pemVkIGJvb2xlYW4gd2FzU3VjY2Vzc2Z1bCgpIHsNCgkJcmV0dXJuIGZhaWx1cmVDb3VudCgpID09IDAgJiYgZXJyb3JDb3VudCgpID09IDA7DQoJfQ0KfVBLAwQKAAAAAADqeMcwNrBsokImAABCJgAAGwAAAGp1bml0L2ZyYW1ld29yay9Bc3NlcnQuamF2YXBhY2thZ2UganVuaXQuZnJhbWV3b3JrOw0KDQovKioNCiAqIEEgc2V0IG9mIGFzc2VydCBtZXRob2RzLiAgTWVzc2FnZXMgYXJlIG9ubHkgZGlzcGxheWVkIHdoZW4gYW4gYXNzZXJ0IGZhaWxzLg0KICovDQoNCnB1YmxpYyBjbGFzcyBBc3NlcnQgew0KCS8qKg0KCSAqIFByb3RlY3QgY29uc3RydWN0b3Igc2luY2UgaXQgaXMgYSBzdGF0aWMgb25seSBjbGFzcw0KCSAqLw0KCXByb3RlY3RlZCBBc3NlcnQoKSB7DQoJfQ0KDQoJLyoqDQoJICogQXNzZXJ0cyB0aGF0IGEgY29uZGl0aW9uIGlzIHRydWUuIElmIGl0IGlzbid0IGl0IHRocm93cw0KCSAqIGFuIEFzc2VydGlvbkZhaWxlZEVycm9yIHdpdGggdGhlIGdpdmVuIG1lc3NhZ2UuDQoJICovDQoJc3RhdGljIHB1YmxpYyB2b2lkIGFzc2VydFRydWUoU3RyaW5nIG1lc3NhZ2UsIGJvb2xlYW4gY29uZGl0aW9uKSB7DQoJCWlmICghY29uZGl0aW9uKQ0KCQkJZmFpbChtZXNzYWdlKTsNCgl9DQoJLyoqDQoJICogQXNzZXJ0cyB0aGF0IGEgY29uZGl0aW9uIGlzIHRydWUuIElmIGl0IGlzbid0IGl0IHRocm93cw0KCSAqIGFuIEFzc2VydGlvbkZhaWxlZEVycm9yLg0KCSAqLw0KCXN0YXRpYyBwdWJsaWMgdm9pZCBhc3NlcnRUcnVlKGJvb2xlYW4gY29uZGl0aW9uKSB7DQoJCWFzc2VydFRydWUobnVsbCwgY29uZGl0aW9uKTsNCgl9DQoJLyoqDQoJICogQXNzZXJ0cyB0aGF0IGEgY29uZGl0aW9uIGlzIGZhbHNlLiBJZiBpdCBpc24ndCBpdCB0aHJvd3MNCgkgKiBhbiBBc3NlcnRpb25GYWlsZWRFcnJvciB3aXRoIHRoZSBnaXZlbiBtZXNzYWdlLg0KCSAqLw0KCXN0YXRpYyBwdWJsaWMgdm9pZCBhc3NlcnRGYWxzZShTdHJpbmcgbWVzc2FnZSwgYm9vbGVhbiBjb25kaXRpb24pIHsNCgkJYXNzZXJ0VHJ1ZShtZXNzYWdlLCAhY29uZGl0aW9uKTsNCgl9DQoJLyoqDQoJICogQXNzZXJ0cyB0aGF0IGEgY29uZGl0aW9uIGlzIGZhbHNlLiBJZiBpdCBpc24ndCBpdCB0aHJvd3MNCgkgKiBhbiBBc3NlcnRpb25GYWlsZWRFcnJvci4NCgkgKi8NCglzdGF0aWMgcHVibGljIHZvaWQgYXNzZXJ0RmFsc2UoYm9vbGVhbiBjb25kaXRpb24pIHsNCgkJYXNzZXJ0RmFsc2UobnVsbCwgY29uZGl0aW9uKTsNCgl9DQoJLyoqDQoJICogRmFpbHMgYSB0ZXN0IHdpdGggdGhlIGdpdmVuIG1lc3NhZ2UuDQoJICovDQoJc3RhdGljIHB1YmxpYyB2b2lkIGZhaWwoU3RyaW5nIG1lc3NhZ2UpIHsNCgkJdGhyb3cgbmV3IEFzc2VydGlvbkZhaWxlZEVycm9yKG1lc3NhZ2UpOw0KCX0NCgkvKioNCgkgKiBGYWlscyBhIHRlc3Qgd2l0aCBubyBtZXNzYWdlLg0KCSAqLw0KCXN0YXRpYyBwdWJsaWMgdm9pZCBmYWlsKCkgew0KCQlmYWlsKG51bGwpOw0KCX0NCgkvKioNCgkgKiBBc3NlcnRzIHRoYXQgdHdvIG9iamVjdHMgYXJlIGVxdWFsLiBJZiB0aGV5IGFyZSBub3QNCgkgKiBhbiBBc3NlcnRpb25GYWlsZWRFcnJvciBpcyB0aHJvd24gd2l0aCB0aGUgZ2l2ZW4gbWVzc2FnZS4NCgkgKi8NCglzdGF0aWMgcHVibGljIHZvaWQgYXNzZXJ0RXF1YWxzKFN0cmluZyBtZXNzYWdlLCBPYmplY3QgZXhwZWN0ZWQsIE9iamVjdCBhY3R1YWwpIHsNCgkJaWYgKGV4cGVjdGVkID09IG51bGwgJiYgYWN0dWFsID09IG51bGwpDQoJCQlyZXR1cm47DQoJCWlmIChleHBlY3RlZCAhPSBudWxsICYmIGV4cGVjdGVkLmVxdWFscyhhY3R1YWwpKQ0KCQkJcmV0dXJuOw0KCQlmYWlsTm90RXF1YWxzKG1lc3NhZ2UsIGV4cGVjdGVkLCBhY3R1YWwpOw0KCX0NCgkvKioNCgkgKiBBc3NlcnRzIHRoYXQgdHdvIG9iamVjdHMgYXJlIGVxdWFsLiBJZiB0aGV5IGFyZSBub3QNCgkgKiBhbiBBc3NlcnRpb25GYWlsZWRFcnJvciBpcyB0aHJvd24uDQoJICovDQoJc3RhdGljIHB1YmxpYyB2b2lkIGFzc2VydEVxdWFscyhPYmplY3QgZXhwZWN0ZWQsIE9iamVjdCBhY3R1YWwpIHsNCgkgICAgYXNzZXJ0RXF1YWxzKG51bGwsIGV4cGVjdGVkLCBhY3R1YWwpOw0KCX0NCgkvKioNCgkgKiBBc3NlcnRzIHRoYXQgdHdvIFN0cmluZ3MgYXJlIGVxdWFsLiANCgkgKi8NCglzdGF0aWMgcHVibGljIHZvaWQgYXNzZXJ0RXF1YWxzKFN0cmluZyBtZXNzYWdlLCBTdHJpbmcgZXhwZWN0ZWQsIFN0cmluZyBhY3R1YWwpIHsNCgkJaWYgKGV4cGVjdGVkID09IG51bGwgJiYgYWN0dWFsID09IG51bGwpDQoJCQlyZXR1cm47DQoJCWlmIChleHBlY3RlZCAhPSBudWxsICYmIGV4cGVjdGVkLmVxdWFscyhhY3R1YWwpKQ0KCQkJcmV0dXJuOw0KCQl0aHJvdyBuZXcgQ29tcGFyaXNvbkZhaWx1cmUobWVzc2FnZSwgZXhwZWN0ZWQsIGFjdHVhbCk7DQoJfQ0KCS8qKg0KCSAqIEFzc2VydHMgdGhhdCB0d28gU3RyaW5ncyBhcmUgZXF1YWwuIA0KCSAqLw0KCXN0YXRpYyBwdWJsaWMgdm9pZCBhc3NlcnRFcXVhbHMoU3RyaW5nIGV4cGVjdGVkLCBTdHJpbmcgYWN0dWFsKSB7DQoJICAgIGFzc2VydEVxdWFscyhudWxsLCBleHBlY3RlZCwgYWN0dWFsKTsNCgl9DQoJLyoqDQoJICogQXNzZXJ0cyB0aGF0IHR3byBkb3VibGVzIGFyZSBlcXVhbCBjb25jZXJuaW5nIGEgZGVsdGEuICBJZiB0aGV5IGFyZSBub3QNCgkgKiBhbiBBc3NlcnRpb25GYWlsZWRFcnJvciBpcyB0aHJvd24gd2l0aCB0aGUgZ2l2ZW4gbWVzc2FnZS4gIElmIHRoZSBleHBlY3RlZA0KCSAqIHZhbHVlIGlzIGluZmluaXR5IHRoZW4gdGhlIGRlbHRhIHZhbHVlIGlzIGlnbm9yZWQuDQoJICovDQoJc3RhdGljIHB1YmxpYyB2b2lkIGFzc2VydEVxdWFscyhTdHJpbmcgbWVzc2FnZSwgZG91YmxlIGV4cGVjdGVkLCBkb3VibGUgYWN0dWFsLCBkb3VibGUgZGVsdGEpIHsNCgkJLy8gaGFuZGxlIGluZmluaXR5IHNwZWNpYWxseSBzaW5jZSBzdWJ0cmFjdGluZyB0byBpbmZpbml0ZSB2YWx1ZXMgZ2l2ZXMgTmFOIGFuZCB0aGUNCgkJLy8gdGhlIGZvbGxvd2luZyB0ZXN0IGZhaWxzDQoJCWlmIChEb3VibGUuaXNJbmZpbml0ZShleHBlY3RlZCkpIHsNCgkJCWlmICghKGV4cGVjdGVkID09IGFjdHVhbCkpDQoJCQkJZmFpbE5vdEVxdWFscyhtZXNzYWdlLCBuZXcgRG91YmxlKGV4cGVjdGVkKSwgbmV3IERvdWJsZShhY3R1YWwpKTsNCgkJfSBlbHNlIGlmICghKE1hdGguYWJzKGV4cGVjdGVkLWFjdHVhbCkgPD0gZGVsdGEpKSAvLyBCZWNhdXNlIGNvbXBhcmlzb24gd2l0aCBOYU4gYWx3YXlzIHJldHVybnMgZmFsc2UNCgkJCWZhaWxOb3RFcXVhbHMobWVzc2FnZSwgbmV3IERvdWJsZShleHBlY3RlZCksIG5ldyBEb3VibGUoYWN0dWFsKSk7DQoJfQ0KCS8qKg0KCSAqIEFzc2VydHMgdGhhdCB0d28gZG91YmxlcyBhcmUgZXF1YWwgY29uY2VybmluZyBhIGRlbHRhLiBJZiB0aGUgZXhwZWN0ZWQNCgkgKiB2YWx1ZSBpcyBpbmZpbml0eSB0aGVuIHRoZSBkZWx0YSB2YWx1ZSBpcyBpZ25vcmVkLg0KCSAqLw0KCXN0YXRpYyBwdWJsaWMgdm9pZCBhc3NlcnRFcXVhbHMoZG91YmxlIGV4cGVjdGVkLCBkb3VibGUgYWN0dWFsLCBkb3VibGUgZGVsdGEpIHsNCgkgICAgYXNzZXJ0RXF1YWxzKG51bGwsIGV4cGVjdGVkLCBhY3R1YWwsIGRlbHRhKTsNCgl9DQoJLyoqDQoJICogQXNzZXJ0cyB0aGF0IHR3byBmbG9hdHMgYXJlIGVxdWFsIGNvbmNlcm5pbmcgYSBkZWx0YS4gSWYgdGhleSBhcmUgbm90DQoJICogYW4gQXNzZXJ0aW9uRmFpbGVkRXJyb3IgaXMgdGhyb3duIHdpdGggdGhlIGdpdmVuIG1lc3NhZ2UuICBJZiB0aGUgZXhwZWN0ZWQNCgkgKiB2YWx1ZSBpcyBpbmZpbml0eSB0aGVuIHRoZSBkZWx0YSB2YWx1ZSBpcyBpZ25vcmVkLg0KCSAqLw0KCXN0YXRpYyBwdWJsaWMgdm9pZCBhc3NlcnRFcXVhbHMoU3RyaW5nIG1lc3NhZ2UsIGZsb2F0IGV4cGVjdGVkLCBmbG9hdCBhY3R1YWwsIGZsb2F0IGRlbHRhKSB7DQogCQkvLyBoYW5kbGUgaW5maW5pdHkgc3BlY2lhbGx5IHNpbmNlIHN1YnRyYWN0aW5nIHRvIGluZmluaXRlIHZhbHVlcyBnaXZlcyBOYU4gYW5kIHRoZQ0KCQkvLyB0aGUgZm9sbG93aW5nIHRlc3QgZmFpbHMNCgkJaWYgKEZsb2F0LmlzSW5maW5pdGUoZXhwZWN0ZWQpKSB7DQoJCQlpZiAoIShleHBlY3RlZCA9PSBhY3R1YWwpKQ0KCQkJCWZhaWxOb3RFcXVhbHMobWVzc2FnZSwgbmV3IEZsb2F0KGV4cGVjdGVkKSwgbmV3IEZsb2F0KGFjdHVhbCkpOw0KCQl9IGVsc2UgaWYgKCEoTWF0aC5hYnMoZXhwZWN0ZWQtYWN0dWFsKSA8PSBkZWx0YSkpDQogICAgICAJCWZhaWxOb3RFcXVhbHMobWVzc2FnZSwgbmV3IEZsb2F0KGV4cGVjdGVkKSwgbmV3IEZsb2F0KGFjdHVhbCkpOw0KCX0NCgkvKioNCgkgKiBBc3NlcnRzIHRoYXQgdHdvIGZsb2F0cyBhcmUgZXF1YWwgY29uY2VybmluZyBhIGRlbHRhLiBJZiB0aGUgZXhwZWN0ZWQNCgkgKiB2YWx1ZSBpcyBpbmZpbml0eSB0aGVuIHRoZSBkZWx0YSB2YWx1ZSBpcyBpZ25vcmVkLg0KCSAqLw0KCXN0YXRpYyBwdWJsaWMgdm9pZCBhc3NlcnRFcXVhbHMoZmxvYXQgZXhwZWN0ZWQsIGZsb2F0IGFjdHVhbCwgZmxvYXQgZGVsdGEpIHsNCgkJYXNzZXJ0RXF1YWxzKG51bGwsIGV4cGVjdGVkLCBhY3R1YWwsIGRlbHRhKTsNCgl9DQoJLyoqDQoJICogQXNzZXJ0cyB0aGF0IHR3byBsb25ncyBhcmUgZXF1YWwuIElmIHRoZXkgYXJlIG5vdA0KCSAqIGFuIEFzc2VydGlvbkZhaWxlZEVycm9yIGlzIHRocm93biB3aXRoIHRoZSBnaXZlbiBtZXNzYWdlLg0KCSAqLw0KCXN0YXRpYyBwdWJsaWMgdm9pZCBhc3NlcnRFcXVhbHMoU3RyaW5nIG1lc3NhZ2UsIGxvbmcgZXhwZWN0ZWQsIGxvbmcgYWN0dWFsKSB7DQoJICAgIGFzc2VydEVxdWFscyhtZXNzYWdlLCBuZXcgTG9uZyhleHBlY3RlZCksIG5ldyBMb25nKGFjdHVhbCkpOw0KCX0NCgkvKioNCgkgKiBBc3NlcnRzIHRoYXQgdHdvIGxvbmdzIGFyZSBlcXVhbC4NCgkgKi8NCglzdGF0aWMgcHVibGljIHZvaWQgYXNzZXJ0RXF1YWxzKGxvbmcgZXhwZWN0ZWQsIGxvbmcgYWN0dWFsKSB7DQoJICAgIGFzc2VydEVxdWFscyhudWxsLCBleHBlY3RlZCwgYWN0dWFsKTsNCgl9DQoJLyoqDQoJICogQXNzZXJ0cyB0aGF0IHR3byBib29sZWFucyBhcmUgZXF1YWwuIElmIHRoZXkgYXJlIG5vdA0KCSAqIGFuIEFzc2VydGlvbkZhaWxlZEVycm9yIGlzIHRocm93biB3aXRoIHRoZSBnaXZlbiBtZXNzYWdlLg0KCSAqLw0KCXN0YXRpYyBwdWJsaWMgdm9pZCBhc3NlcnRFcXVhbHMoU3RyaW5nIG1lc3NhZ2UsIGJvb2xlYW4gZXhwZWN0ZWQsIGJvb2xlYW4gYWN0dWFsKSB7DQogICAgCQlhc3NlcnRFcXVhbHMobWVzc2FnZSwgbmV3IEJvb2xlYW4oZXhwZWN0ZWQpLCBuZXcgQm9vbGVhbihhY3R1YWwpKTsNCiAgCX0NCgkvKioNCgkgKiBBc3NlcnRzIHRoYXQgdHdvIGJvb2xlYW5zIGFyZSBlcXVhbC4NCiAJICovDQoJc3RhdGljIHB1YmxpYyB2b2lkIGFzc2VydEVxdWFscyhib29sZWFuIGV4cGVjdGVkLCBib29sZWFuIGFjdHVhbCkgew0KCQlhc3NlcnRFcXVhbHMobnVsbCwgZXhwZWN0ZWQsIGFjdHVhbCk7DQoJfQ0KCS8qKg0KCSAqIEFzc2VydHMgdGhhdCB0d28gYnl0ZXMgYXJlIGVxdWFsLiBJZiB0aGV5IGFyZSBub3QNCgkgKiBhbiBBc3NlcnRpb25GYWlsZWRFcnJvciBpcyB0aHJvd24gd2l0aCB0aGUgZ2l2ZW4gbWVzc2FnZS4NCgkgKi8NCiAgCXN0YXRpYyBwdWJsaWMgdm9pZCBhc3NlcnRFcXVhbHMoU3RyaW5nIG1lc3NhZ2UsIGJ5dGUgZXhwZWN0ZWQsIGJ5dGUgYWN0dWFsKSB7DQoJCWFzc2VydEVxdWFscyhtZXNzYWdlLCBuZXcgQnl0ZShleHBlY3RlZCksIG5ldyBCeXRlKGFjdHVhbCkpOw0KCX0NCgkvKioNCiAgIAkgKiBBc3NlcnRzIHRoYXQgdHdvIGJ5dGVzIGFyZSBlcXVhbC4NCgkgKi8NCglzdGF0aWMgcHVibGljIHZvaWQgYXNzZXJ0RXF1YWxzKGJ5dGUgZXhwZWN0ZWQsIGJ5dGUgYWN0dWFsKSB7DQoJCWFzc2VydEVxdWFscyhudWxsLCBleHBlY3RlZCwgYWN0dWFsKTsNCgl9DQoJLyoqDQoJICogQXNzZXJ0cyB0aGF0IHR3byBjaGFycyBhcmUgZXF1YWwuIElmIHRoZXkgYXJlIG5vdA0KCSAqIGFuIEFzc2VydGlvbkZhaWxlZEVycm9yIGlzIHRocm93biB3aXRoIHRoZSBnaXZlbiBtZXNzYWdlLg0KCSAqLw0KICAJc3RhdGljIHB1YmxpYyB2b2lkIGFzc2VydEVxdWFscyhTdHJpbmcgbWVzc2FnZSwgY2hhciBleHBlY3RlZCwgY2hhciBhY3R1YWwpIHsNCiAgICAJCWFzc2VydEVxdWFscyhtZXNzYWdlLCBuZXcgQ2hhcmFjdGVyKGV4cGVjdGVkKSwgbmV3IENoYXJhY3RlcihhY3R1YWwpKTsNCiAgCX0NCgkvKioNCgkgKiBBc3NlcnRzIHRoYXQgdHdvIGNoYXJzIGFyZSBlcXVhbC4NCgkgKi8NCiAgCXN0YXRpYyBwdWJsaWMgdm9pZCBhc3NlcnRFcXVhbHMoY2hhciBleHBlY3RlZCwgY2hhciBhY3R1YWwpIHsNCgkJYXNzZXJ0RXF1YWxzKG51bGwsIGV4cGVjdGVkLCBhY3R1YWwpOw0KCX0NCgkvKioNCgkgKiBBc3NlcnRzIHRoYXQgdHdvIHNob3J0cyBhcmUgZXF1YWwuIElmIHRoZXkgYXJlIG5vdA0KCSAqIGFuIEFzc2VydGlvbkZhaWxlZEVycm9yIGlzIHRocm93biB3aXRoIHRoZSBnaXZlbiBtZXNzYWdlLg0KCSAqLw0KCXN0YXRpYyBwdWJsaWMgdm9pZCBhc3NlcnRFcXVhbHMoU3RyaW5nIG1lc3NhZ2UsIHNob3J0IGV4cGVjdGVkLCBzaG9ydCBhY3R1YWwpIHsNCiAgICAJCWFzc2VydEVxdWFscyhtZXNzYWdlLCBuZXcgU2hvcnQoZXhwZWN0ZWQpLCBuZXcgU2hvcnQoYWN0dWFsKSk7DQoJfQ0KICAJLyoqDQoJICogQXNzZXJ0cyB0aGF0IHR3byBzaG9ydHMgYXJlIGVxdWFsLg0KCSAqLw0KCXN0YXRpYyBwdWJsaWMgdm9pZCBhc3NlcnRFcXVhbHMoc2hvcnQgZXhwZWN0ZWQsIHNob3J0IGFjdHVhbCkgew0KCQlhc3NlcnRFcXVhbHMobnVsbCwgZXhwZWN0ZWQsIGFjdHVhbCk7DQoJfQ0KCS8qKg0KCSAqIEFzc2VydHMgdGhhdCB0d28gaW50cyBhcmUgZXF1YWwuIElmIHRoZXkgYXJlIG5vdA0KCSAqIGFuIEFzc2VydGlvbkZhaWxlZEVycm9yIGlzIHRocm93biB3aXRoIHRoZSBnaXZlbiBtZXNzYWdlLg0KCSAqLw0KICAJc3RhdGljIHB1YmxpYyB2b2lkIGFzc2VydEVxdWFscyhTdHJpbmcgbWVzc2FnZSwgaW50IGV4cGVjdGVkLCBpbnQgYWN0dWFsKSB7DQoJCWFzc2VydEVxdWFscyhtZXNzYWdlLCBuZXcgSW50ZWdlcihleHBlY3RlZCksIG5ldyBJbnRlZ2VyKGFjdHVhbCkpOw0KICAJfQ0KICAJLyoqDQogICAJICogQXNzZXJ0cyB0aGF0IHR3byBpbnRzIGFyZSBlcXVhbC4NCgkgKi8NCiAgCXN0YXRpYyBwdWJsaWMgdm9pZCBhc3NlcnRFcXVhbHMoaW50IGV4cGVjdGVkLCBpbnQgYWN0dWFsKSB7DQogIAkJYXNzZXJ0RXF1YWxzKG51bGwsIGV4cGVjdGVkLCBhY3R1YWwpOw0KCX0NCgkvKioNCgkgKiBBc3NlcnRzIHRoYXQgYW4gb2JqZWN0IGlzbid0IG51bGwuDQoJICovDQoJc3RhdGljIHB1YmxpYyB2b2lkIGFzc2VydE5vdE51bGwoT2JqZWN0IG9iamVjdCkgew0KCQlhc3NlcnROb3ROdWxsKG51bGwsIG9iamVjdCk7DQoJfQ0KCS8qKg0KCSAqIEFzc2VydHMgdGhhdCBhbiBvYmplY3QgaXNuJ3QgbnVsbC4gSWYgaXQgaXMNCgkgKiBhbiBBc3NlcnRpb25GYWlsZWRFcnJvciBpcyB0aHJvd24gd2l0aCB0aGUgZ2l2ZW4gbWVzc2FnZS4NCgkgKi8NCglzdGF0aWMgcHVibGljIHZvaWQgYXNzZXJ0Tm90TnVsbChTdHJpbmcgbWVzc2FnZSwgT2JqZWN0IG9iamVjdCkgew0KCQlhc3NlcnRUcnVlKG1lc3NhZ2UsIG9iamVjdCAhPSBudWxsKTsNCgl9DQoJLyoqDQoJICogQXNzZXJ0cyB0aGF0IGFuIG9iamVjdCBpcyBudWxsLg0KCSAqLw0KCXN0YXRpYyBwdWJsaWMgdm9pZCBhc3NlcnROdWxsKE9iamVjdCBvYmplY3QpIHsNCgkJYXNzZXJ0TnVsbChudWxsLCBvYmplY3QpOw0KCX0NCgkvKioNCgkgKiBBc3NlcnRzIHRoYXQgYW4gb2JqZWN0IGlzIG51bGwuICBJZiBpdCBpcyBub3QNCgkgKiBhbiBBc3NlcnRpb25GYWlsZWRFcnJvciBpcyB0aHJvd24gd2l0aCB0aGUgZ2l2ZW4gbWVzc2FnZS4NCgkgKi8NCglzdGF0aWMgcHVibGljIHZvaWQgYXNzZXJ0TnVsbChTdHJpbmcgbWVzc2FnZSwgT2JqZWN0IG9iamVjdCkgew0KCQlhc3NlcnRUcnVlKG1lc3NhZ2UsIG9iamVjdCA9PSBudWxsKTsNCgl9DQoJLyoqDQoJICogQXNzZXJ0cyB0aGF0IHR3byBvYmplY3RzIHJlZmVyIHRvIHRoZSBzYW1lIG9iamVjdC4gSWYgdGhleSBhcmUgbm90DQoJICogYW4gQXNzZXJ0aW9uRmFpbGVkRXJyb3IgaXMgdGhyb3duIHdpdGggdGhlIGdpdmVuIG1lc3NhZ2UuDQoJICovDQoJc3RhdGljIHB1YmxpYyB2b2lkIGFzc2VydFNhbWUoU3RyaW5nIG1lc3NhZ2UsIE9iamVjdCBleHBlY3RlZCwgT2JqZWN0IGFjdHVhbCkgew0KCQlpZiAoZXhwZWN0ZWQgPT0gYWN0dWFsKQ0KCQkJcmV0dXJuOw0KCQlmYWlsTm90U2FtZShtZXNzYWdlLCBleHBlY3RlZCwgYWN0dWFsKTsNCgl9DQoJLyoqDQoJICogQXNzZXJ0cyB0aGF0IHR3byBvYmplY3RzIHJlZmVyIHRvIHRoZSBzYW1lIG9iamVjdC4gSWYgdGhleSBhcmUgbm90DQoJICogdGhlIHNhbWUgYW4gQXNzZXJ0aW9uRmFpbGVkRXJyb3IgaXMgdGhyb3duLg0KCSAqLw0KCXN0YXRpYyBwdWJsaWMgdm9pZCBhc3NlcnRTYW1lKE9iamVjdCBleHBlY3RlZCwgT2JqZWN0IGFjdHVhbCkgew0KCSAgICBhc3NlcnRTYW1lKG51bGwsIGV4cGVjdGVkLCBhY3R1YWwpOw0KCX0NCiAJLyoqDQogCSAqIEFzc2VydHMgdGhhdCB0d28gb2JqZWN0cyByZWZlciB0byB0aGUgc2FtZSBvYmplY3QuIElmIHRoZXkgYXJlIG5vdA0KIAkgKiBhbiBBc3NlcnRpb25GYWlsZWRFcnJvciBpcyB0aHJvd24gd2l0aCB0aGUgZ2l2ZW4gbWVzc2FnZS4NCiAJICovDQoJc3RhdGljIHB1YmxpYyB2b2lkIGFzc2VydE5vdFNhbWUoU3RyaW5nIG1lc3NhZ2UsIE9iamVjdCBleHBlY3RlZCwgT2JqZWN0IGFjdHVhbCkgew0KCQlpZiAoZXhwZWN0ZWQgPT0gYWN0dWFsKQ0KCQkJZmFpbFNhbWUobWVzc2FnZSk7DQoJfQ0KCS8qKg0KCSAqIEFzc2VydHMgdGhhdCB0d28gb2JqZWN0cyByZWZlciB0byB0aGUgc2FtZSBvYmplY3QuIElmIHRoZXkgYXJlIG5vdA0KCSAqIHRoZSBzYW1lIGFuIEFzc2VydGlvbkZhaWxlZEVycm9yIGlzIHRocm93bi4NCgkgKi8NCglzdGF0aWMgcHVibGljIHZvaWQgYXNzZXJ0Tm90U2FtZShPYmplY3QgZXhwZWN0ZWQsIE9iamVjdCBhY3R1YWwpIHsNCgkJYXNzZXJ0Tm90U2FtZShudWxsLCBleHBlY3RlZCwgYWN0dWFsKTsNCgl9DQoNCglzdGF0aWMgcHJpdmF0ZSB2b2lkIGZhaWxTYW1lKFN0cmluZyBtZXNzYWdlKSB7DQoJCVN0cmluZyBmb3JtYXR0ZWQ9ICIiOw0KIAkJaWYgKG1lc3NhZ2UgIT0gbnVsbCkNCiAJCQlmb3JtYXR0ZWQ9IG1lc3NhZ2UrIiAiOw0KIAkJZmFpbChmb3JtYXR0ZWQrImV4cGVjdGVkIG5vdCBzYW1lIik7DQoJfQ0KDQoJc3RhdGljIHByaXZhdGUgdm9pZCBmYWlsTm90U2FtZShTdHJpbmcgbWVzc2FnZSwgT2JqZWN0IGV4cGVjdGVkLCBPYmplY3QgYWN0dWFsKSB7DQoJCVN0cmluZyBmb3JtYXR0ZWQ9ICIiOw0KCQlpZiAobWVzc2FnZSAhPSBudWxsKQ0KCQkJZm9ybWF0dGVkPSBtZXNzYWdlKyIgIjsNCgkJZmFpbChmb3JtYXR0ZWQrImV4cGVjdGVkIHNhbWU6PCIrZXhwZWN0ZWQrIj4gd2FzIG5vdDo8IithY3R1YWwrIj4iKTsNCgl9DQoNCglzdGF0aWMgcHJpdmF0ZSB2b2lkIGZhaWxOb3RFcXVhbHMoU3RyaW5nIG1lc3NhZ2UsIE9iamVjdCBleHBlY3RlZCwgT2JqZWN0IGFjdHVhbCkgew0KCQlmYWlsKGZvcm1hdChtZXNzYWdlLCBleHBlY3RlZCwgYWN0dWFsKSk7DQoJfQ0KDQoJc3RhdGljIFN0cmluZyBmb3JtYXQoU3RyaW5nIG1lc3NhZ2UsIE9iamVjdCBleHBlY3RlZCwgT2JqZWN0IGFjdHVhbCkgew0KCQlTdHJpbmcgZm9ybWF0dGVkPSAiIjsNCgkJaWYgKG1lc3NhZ2UgIT0gbnVsbCkNCgkJCWZvcm1hdHRlZD0gbWVzc2FnZSsiICI7DQoJCXJldHVybiBmb3JtYXR0ZWQrImV4cGVjdGVkOjwiK2V4cGVjdGVkKyI+IGJ1dCB3YXM6PCIrYWN0dWFsKyI+IjsNCgl9DQp9UEsDBAoAAAAAAOp4xzB8PXh6xRsAAMUbAAAeAAAAanVuaXQvZnJhbWV3b3JrL1Rlc3RTdWl0ZS5qYXZhcGFja2FnZSBqdW5pdC5mcmFtZXdvcms7DQoNCmltcG9ydCBqYXZhLnV0aWwuVmVjdG9yOw0KaW1wb3J0IGphdmEudXRpbC5FbnVtZXJhdGlvbjsNCmltcG9ydCBqYXZhLmlvLlByaW50V3JpdGVyOw1pbXBvcnQgamF2YS5pby5TdHJpbmdXcml0ZXI7DWltcG9ydCBqYXZhLmxhbmcucmVmbGVjdC4qOw0KaW1wb3J0IGphdmEubGFuZy5yZWZsZWN0LkNvbnN0cnVjdG9yOw0KDQovKioNCiAqIEEgPGNvZGU+VGVzdFN1aXRlPC9jb2RlPiBpcyBhIDxjb2RlPkNvbXBvc2l0ZTwvY29kZT4gb2YgVGVzdHMuDQogKiBJdCBydW5zIGEgY29sbGVjdGlvbiBvZiB0ZXN0IGNhc2VzLiBIZXJlIGlzIGFuIGV4YW1wbGUgdXNpbmcNCiAqIHRoZSBkeW5hbWljIHRlc3QgZGVmaW5pdGlvbi4NCiAqIDxwcmU+DQogKiBUZXN0U3VpdGUgc3VpdGU9IG5ldyBUZXN0U3VpdGUoKTsNCiAqIHN1aXRlLmFkZFRlc3QobmV3IE1hdGhUZXN0KCJ0ZXN0QWRkIikpOw0KICogc3VpdGUuYWRkVGVzdChuZXcgTWF0aFRlc3QoInRlc3REaXZpZGVCeVplcm8iKSk7DQogKiA8L3ByZT4NCiAqIEFsdGVybmF0aXZlbHksIGEgVGVzdFN1aXRlIGNhbiBleHRyYWN0IHRoZSB0ZXN0cyB0byBiZSBydW4gYXV0b21hdGljYWxseS4NCiAqIFRvIGRvIHNvIHlvdSBwYXNzIHRoZSBjbGFzcyBvZiB5b3VyIFRlc3RDYXNlIGNsYXNzIHRvIHRoZQ0KICogVGVzdFN1aXRlIGNvbnN0cnVjdG9yLg0KICogPHByZT4NCiAqIFRlc3RTdWl0ZSBzdWl0ZT0gbmV3IFRlc3RTdWl0ZShNYXRoVGVzdC5jbGFzcyk7DQogKiA8L3ByZT4NCiAqIFRoaXMgY29uc3RydWN0b3IgY3JlYXRlcyBhIHN1aXRlIHdpdGggYWxsIHRoZSBtZXRob2RzDQogKiBzdGFydGluZyB3aXRoICJ0ZXN0IiB0aGF0IHRha2Ugbm8gYXJndW1lbnRzLg0KICoNCiAqIEBzZWUgVGVzdA0KICovDQpwdWJsaWMgY2xhc3MgVGVzdFN1aXRlIGltcGxlbWVudHMgVGVzdCB7DQoNCglwcml2YXRlIFZlY3RvciBmVGVzdHM9IG5ldyBWZWN0b3IoMTApOw0KCXByaXZhdGUgU3RyaW5nIGZOYW1lOw0KDQogICAgLyoqDQoJICogQ29uc3RydWN0cyBhbiBlbXB0eSBUZXN0U3VpdGUuDQoJICovDQoJcHVibGljIFRlc3RTdWl0ZSgpIHsNCgl9DQoJDQoJLyoqDQoJICogQ29uc3RydWN0cyBhIFRlc3RTdWl0ZSBmcm9tIHRoZSBnaXZlbiBjbGFzcyB3aXRoIHRoZSBnaXZlbiBuYW1lLg0KCSAqIEBzZWUgVGVzdFN1aXRlI1Rlc3RTdWl0ZShDbGFzcykNCgkgKi8NCglwdWJsaWMgVGVzdFN1aXRlKENsYXNzIHRoZUNsYXNzLCBTdHJpbmcgbmFtZSkgew0KCQl0aGlzKHRoZUNsYXNzKTsNCgkJc2V0TmFtZShuYW1lKTsNCgl9DQoJDQoJLyoqDQoJICogQ29uc3RydWN0cyBhIFRlc3RTdWl0ZSBmcm9tIHRoZSBnaXZlbiBjbGFzcy4gQWRkcyBhbGwgdGhlIG1ldGhvZHMNCgkgKiBzdGFydGluZyB3aXRoICJ0ZXN0IiBhcyB0ZXN0IGNhc2VzIHRvIHRoZSBzdWl0ZS4NCgkgKiBQYXJ0cyBvZiB0aGlzIG1ldGhvZCB3YXMgd3JpdHRlbiBhdCAyMzM3IG1ldGVycyBpbiB0aGUgSPxmZmlo/HR0ZSwNCgkgKiBLYW50b24gVXJpDQoJICovDQoJIHB1YmxpYyBUZXN0U3VpdGUoZmluYWwgQ2xhc3MgdGhlQ2xhc3MpIHsNCgkJZk5hbWU9IHRoZUNsYXNzLmdldE5hbWUoKTsNCgkJdHJ5IHsNCgkJCWdldFRlc3RDb25zdHJ1Y3Rvcih0aGVDbGFzcyk7IC8vIEF2b2lkIGdlbmVyYXRpbmcgbXVsdGlwbGUgZXJyb3IgbWVzc2FnZXMNCgkJfSBjYXRjaCAoTm9TdWNoTWV0aG9kRXhjZXB0aW9uIGUpIHsNCgkJCWFkZFRlc3Qod2FybmluZygiQ2xhc3MgIit0aGVDbGFzcy5nZXROYW1lKCkrIiBoYXMgbm8gcHVibGljIGNvbnN0cnVjdG9yIFRlc3RDYXNlKFN0cmluZyBuYW1lKSBvciBUZXN0Q2FzZSgpIikpOw0KCQkJcmV0dXJuOw0KCQl9DQoNCgkJaWYgKCFNb2RpZmllci5pc1B1YmxpYyh0aGVDbGFzcy5nZXRNb2RpZmllcnMoKSkpIHsNCgkJCWFkZFRlc3Qod2FybmluZygiQ2xhc3MgIit0aGVDbGFzcy5nZXROYW1lKCkrIiBpcyBub3QgcHVibGljIikpOw0KCQkJcmV0dXJuOw0KCQl9DQoNCgkJQ2xhc3Mgc3VwZXJDbGFzcz0gdGhlQ2xhc3M7DQoJCVZlY3RvciBuYW1lcz0gbmV3IFZlY3RvcigpOw0KCQl3aGlsZSAoVGVzdC5jbGFzcy5pc0Fzc2lnbmFibGVGcm9tKHN1cGVyQ2xhc3MpKSB7DQoJCQlNZXRob2RbXSBtZXRob2RzPSBzdXBlckNsYXNzLmdldERlY2xhcmVkTWV0aG9kcygpOw0KCQkJZm9yIChpbnQgaT0gMDsgaSA8IG1ldGhvZHMubGVuZ3RoOyBpKyspIHsNCgkJCQlhZGRUZXN0TWV0aG9kKG1ldGhvZHNbaV0sIG5hbWVzLCB0aGVDbGFzcyk7DQoJCQl9DQoJCQlzdXBlckNsYXNzPSBzdXBlckNsYXNzLmdldFN1cGVyY2xhc3MoKTsNCgkJfQ0KCQlpZiAoZlRlc3RzLnNpemUoKSA9PSAwKQ0KCQkJYWRkVGVzdCh3YXJuaW5nKCJObyB0ZXN0cyBmb3VuZCBpbiAiK3RoZUNsYXNzLmdldE5hbWUoKSkpOw0KCX0NCgkNCiAgIAkvKioNCgkgKiBDb25zdHJ1Y3RzIGFuIGVtcHR5IFRlc3RTdWl0ZS4NCgkgKi8NCglwdWJsaWMgVGVzdFN1aXRlKFN0cmluZyBuYW1lKSB7DQoJCXNldE5hbWUobmFtZSk7DQoJfQ0KCQ0KCS8qKg0KCSAqIEFkZHMgYSB0ZXN0IHRvIHRoZSBzdWl0ZS4NCgkgKi8NCglwdWJsaWMgdm9pZCBhZGRUZXN0KFRlc3QgdGVzdCkgew0KCQlmVGVzdHMuYWRkRWxlbWVudCh0ZXN0KTsNCgl9DQoNCgkvKioNCgkgKiBBZGRzIHRoZSB0ZXN0cyBmcm9tIHRoZSBnaXZlbiBjbGFzcyB0byB0aGUgc3VpdGUNCgkgKi8NCglwdWJsaWMgdm9pZCBhZGRUZXN0U3VpdGUoQ2xhc3MgdGVzdENsYXNzKSB7DQoJCWFkZFRlc3QobmV3IFRlc3RTdWl0ZSh0ZXN0Q2xhc3MpKTsNCgl9DQoNCglwcml2YXRlIHZvaWQgYWRkVGVzdE1ldGhvZChNZXRob2QgbSwgVmVjdG9yIG5hbWVzLCBDbGFzcyB0aGVDbGFzcykgew0KCQlTdHJpbmcgbmFtZT0gbS5nZXROYW1lKCk7DQoJCWlmIChuYW1lcy5jb250YWlucyhuYW1lKSkNCgkJCXJldHVybjsNCgkJaWYgKCEgaXNQdWJsaWNUZXN0TWV0aG9kKG0pKSB7DQoJCQlpZiAoaXNUZXN0TWV0aG9kKG0pKQ0KCQkJCWFkZFRlc3Qod2FybmluZygiVGVzdCBtZXRob2QgaXNuJ3QgcHVibGljOiAiK20uZ2V0TmFtZSgpKSk7DQoJCQlyZXR1cm47DQoJCX0NCgkJbmFtZXMuYWRkRWxlbWVudChuYW1lKTsNCgkJYWRkVGVzdChjcmVhdGVUZXN0KHRoZUNsYXNzLCBuYW1lKSk7DQoJfQ0KDQoJLyoqDQoJICogLi4uYXMgdGhlIG1vb24gc2V0cyBvdmVyIHRoZSBlYXJseSBtb3JuaW5nIE1lcmxpbiwgT3JlZ29uDQoJICogbW91bnRhaW5zLCBvdXIgaW50cmVwaWQgYWR2ZW50dXJlcnMgdHlwZS4uLg0KCSAqLw0KCXN0YXRpYyBwdWJsaWMgVGVzdCBjcmVhdGVUZXN0KENsYXNzIHRoZUNsYXNzLCBTdHJpbmcgbmFtZSkgew0KCQlDb25zdHJ1Y3RvciBjb25zdHJ1Y3RvcjsNCgkJdHJ5IHsNCgkJCWNvbnN0cnVjdG9yPSBnZXRUZXN0Q29uc3RydWN0b3IodGhlQ2xhc3MpOw0KCQl9IGNhdGNoIChOb1N1Y2hNZXRob2RFeGNlcHRpb24gZSkgew0KCQkJcmV0dXJuIHdhcm5pbmcoIkNsYXNzICIrdGhlQ2xhc3MuZ2V0TmFtZSgpKyIgaGFzIG5vIHB1YmxpYyBjb25zdHJ1Y3RvciBUZXN0Q2FzZShTdHJpbmcgbmFtZSkgb3IgVGVzdENhc2UoKSIpOw0KCQl9DQoJCU9iamVjdCB0ZXN0Ow0KCQl0cnkgew0KCQkJaWYgKGNvbnN0cnVjdG9yLmdldFBhcmFtZXRlclR5cGVzKCkubGVuZ3RoID09IDApIHsNCgkJCQl0ZXN0PSBjb25zdHJ1Y3Rvci5uZXdJbnN0YW5jZShuZXcgT2JqZWN0WzBdKTsNCgkJCQlpZiAodGVzdCBpbnN0YW5jZW9mIFRlc3RDYXNlKQ0KCQkJCQkoKFRlc3RDYXNlKSB0ZXN0KS5zZXROYW1lKG5hbWUpOw0KCQkJfSBlbHNlIHsNCgkJCQl0ZXN0PSBjb25zdHJ1Y3Rvci5uZXdJbnN0YW5jZShuZXcgT2JqZWN0W117bmFtZX0pOw0KCQkJfQ0KCQl9IGNhdGNoIChJbnN0YW50aWF0aW9uRXhjZXB0aW9uIGUpIHsNCgkJCXJldHVybih3YXJuaW5nKCJDYW5ub3QgaW5zdGFudGlhdGUgdGVzdCBjYXNlOiAiK25hbWUrIiAoIitleGNlcHRpb25Ub1N0cmluZyhlKSsiKSIpKTsNCgkJfSBjYXRjaCAoSW52b2NhdGlvblRhcmdldEV4Y2VwdGlvbiBlKSB7DQoJCQlyZXR1cm4od2FybmluZygiRXhjZXB0aW9uIGluIGNvbnN0cnVjdG9yOiAiK25hbWUrIiAoIitleGNlcHRpb25Ub1N0cmluZyhlLmdldFRhcmdldEV4Y2VwdGlvbigpKSsiKSIpKTsNCgkJfSBjYXRjaCAoSWxsZWdhbEFjY2Vzc0V4Y2VwdGlvbiBlKSB7DQoJCQlyZXR1cm4od2FybmluZygiQ2Fubm90IGFjY2VzcyB0ZXN0IGNhc2U6ICIrbmFtZSsiICgiK2V4Y2VwdGlvblRvU3RyaW5nKGUpKyIpIikpOw0KCQl9DQoJCXJldHVybiAoVGVzdCkgdGVzdDsNCgl9DQoNCgkvKioNCgkgKiBDb252ZXJ0cyB0aGUgc3RhY2sgdHJhY2UgaW50byBhIHN0cmluZw0KCSAqLw0KCXByaXZhdGUgc3RhdGljIFN0cmluZyBleGNlcHRpb25Ub1N0cmluZyhUaHJvd2FibGUgdCkgew0KCQlTdHJpbmdXcml0ZXIgc3RyaW5nV3JpdGVyPSBuZXcgU3RyaW5nV3JpdGVyKCk7DQoJCVByaW50V3JpdGVyIHdyaXRlcj0gbmV3IFByaW50V3JpdGVyKHN0cmluZ1dyaXRlcik7DQoJCXQucHJpbnRTdGFja1RyYWNlKHdyaXRlcik7DQoJCXJldHVybiBzdHJpbmdXcml0ZXIudG9TdHJpbmcoKTsNCg0KCX0NCgkNCgkvKioNCgkgKiBDb3VudHMgdGhlIG51bWJlciBvZiB0ZXN0IGNhc2VzIHRoYXQgd2lsbCBiZSBydW4gYnkgdGhpcyB0ZXN0Lg0KCSAqLw0KCXB1YmxpYyBpbnQgY291bnRUZXN0Q2FzZXMoKSB7DQoJCWludCBjb3VudD0gMDsNCgkJZm9yIChFbnVtZXJhdGlvbiBlPSB0ZXN0cygpOyBlLmhhc01vcmVFbGVtZW50cygpOyApIHsNCgkJCVRlc3QgdGVzdD0gKFRlc3QpZS5uZXh0RWxlbWVudCgpOw0KCQkJY291bnQ9IGNvdW50ICsgdGVzdC5jb3VudFRlc3RDYXNlcygpOw0KCQl9DQoJCXJldHVybiBjb3VudDsNCgl9DQoJDQoJLyoqDQoJICogR2V0cyBhIGNvbnN0cnVjdG9yIHdoaWNoIHRha2VzIGEgc2luZ2xlIFN0cmluZyBhcw0KCSAqIGl0cyBhcmd1bWVudCBvciBhIG5vIGFyZyBjb25zdHJ1Y3Rvci4NCgkgKi8NCglwdWJsaWMgc3RhdGljIENvbnN0cnVjdG9yIGdldFRlc3RDb25zdHJ1Y3RvcihDbGFzcyB0aGVDbGFzcykgdGhyb3dzIE5vU3VjaE1ldGhvZEV4Y2VwdGlvbiB7DQoJCUNsYXNzW10gYXJncz0geyBTdHJpbmcuY2xhc3MgfTsNCgkJdHJ5IHsNCgkJCXJldHVybiB0aGVDbGFzcy5nZXRDb25zdHJ1Y3RvcihhcmdzKTsJDQoJCX0gY2F0Y2ggKE5vU3VjaE1ldGhvZEV4Y2VwdGlvbiBlKSB7DQoJCQkvLyBmYWxsIHRocm91Z2gNCgkJfQ0KCQlyZXR1cm4gdGhlQ2xhc3MuZ2V0Q29uc3RydWN0b3IobmV3IENsYXNzWzBdKTsNCgl9DQoNCglwcml2YXRlIGJvb2xlYW4gaXNQdWJsaWNUZXN0TWV0aG9kKE1ldGhvZCBtKSB7DQoJCXJldHVybiBpc1Rlc3RNZXRob2QobSkgJiYgTW9kaWZpZXIuaXNQdWJsaWMobS5nZXRNb2RpZmllcnMoKSk7DQoJIH0NCgkgDQoJcHJpdmF0ZSBib29sZWFuIGlzVGVzdE1ldGhvZChNZXRob2QgbSkgew0KCQlTdHJpbmcgbmFtZT0gbS5nZXROYW1lKCk7DQoJCUNsYXNzW10gcGFyYW1ldGVycz0gbS5nZXRQYXJhbWV0ZXJUeXBlcygpOw0KCQlDbGFzcyByZXR1cm5UeXBlPSBtLmdldFJldHVyblR5cGUoKTsNCgkJcmV0dXJuIHBhcmFtZXRlcnMubGVuZ3RoID09IDAgJiYgbmFtZS5zdGFydHNXaXRoKCJ0ZXN0IikgJiYgcmV0dXJuVHlwZS5lcXVhbHMoVm9pZC5UWVBFKTsNCgkgfQ0KCSANCgkvKioNCgkgKiBSdW5zIHRoZSB0ZXN0cyBhbmQgY29sbGVjdHMgdGhlaXIgcmVzdWx0IGluIGEgVGVzdFJlc3VsdC4NCgkgKi8NCglwdWJsaWMgdm9pZCBydW4oVGVzdFJlc3VsdCByZXN1bHQpIHsNCgkJZm9yIChFbnVtZXJhdGlvbiBlPSB0ZXN0cygpOyBlLmhhc01vcmVFbGVtZW50cygpOyApIHsNCgkgIAkJaWYgKHJlc3VsdC5zaG91bGRTdG9wKCkgKQ0KCSAgCQkJYnJlYWs7DQoJCQlUZXN0IHRlc3Q9IChUZXN0KWUubmV4dEVsZW1lbnQoKTsNCgkJCXJ1blRlc3QodGVzdCwgcmVzdWx0KTsNCgkJfQ0KCX0NCg0KCXB1YmxpYyB2b2lkIHJ1blRlc3QoVGVzdCB0ZXN0LCBUZXN0UmVzdWx0IHJlc3VsdCkgew0KCQl0ZXN0LnJ1bihyZXN1bHQpOw0KCX0NCg0KCS8qKg0KCSAqIFJldHVybnMgdGhlIHRlc3QgYXQgdGhlIGdpdmVuIGluZGV4DQoJICovDQoJcHVibGljIFRlc3QgdGVzdEF0KGludCBpbmRleCkgew0KCQlyZXR1cm4gKFRlc3QpZlRlc3RzLmVsZW1lbnRBdChpbmRleCk7DQoJfQ0KCQ0KCS8qKg0KCSAqIFJldHVybnMgdGhlIG51bWJlciBvZiB0ZXN0cyBpbiB0aGlzIHN1aXRlDQoJICovDQoJcHVibGljIGludCB0ZXN0Q291bnQoKSB7DQoJCXJldHVybiBmVGVzdHMuc2l6ZSgpOw0KCX0NCgkNCgkvKioNCgkgKiBSZXR1cm5zIHRoZSB0ZXN0cyBhcyBhbiBlbnVtZXJhdGlvbg0KCSAqLw0KCXB1YmxpYyBFbnVtZXJhdGlvbiB0ZXN0cygpIHsNCgkJcmV0dXJuIGZUZXN0cy5lbGVtZW50cygpOw0KCX0NCgkNCgkvKioNCgkgKi8NCglwdWJsaWMgU3RyaW5nIHRvU3RyaW5nKCkgew0KCQlpZiAoZ2V0TmFtZSgpICE9IG51bGwpDQoJCQlyZXR1cm4gZ2V0TmFtZSgpOw0KCQlyZXR1cm4gc3VwZXIudG9TdHJpbmcoKTsNCgkgfQ0KCSANCgkvKioNCgkgKiBTZXRzIHRoZSBuYW1lIG9mIHRoZSBzdWl0ZS4NCgkgKiBAcGFyYW0gbmFtZSBUaGUgbmFtZSB0byBzZXQNCgkgKi8NCglwdWJsaWMgdm9pZCBzZXROYW1lKFN0cmluZyBuYW1lKSB7DQoJCWZOYW1lPSBuYW1lOw0KCX0NCg0KCS8qKg0KCSAqIFJldHVybnMgdGhlIG5hbWUgb2YgdGhlIHN1aXRlLiBOb3QgYWxsDQoJICogdGVzdCBzdWl0ZXMgaGF2ZSBhIG5hbWUgYW5kIHRoaXMgbWV0aG9kDQoJICogY2FuIHJldHVybiBudWxsLg0KCSAqLw0KCXB1YmxpYyBTdHJpbmcgZ2V0TmFtZSgpIHsNCgkJcmV0dXJuIGZOYW1lOw0KCX0NCg0KCS8qKg0KCSAqIFJldHVybnMgYSB0ZXN0IHdoaWNoIHdpbGwgZmFpbCBhbmQgbG9nIGEgd2FybmluZyBtZXNzYWdlLg0KCSAqLw0KCXByaXZhdGUgc3RhdGljIFRlc3Qgd2FybmluZyhmaW5hbCBTdHJpbmcgbWVzc2FnZSkgew0KCQlyZXR1cm4gbmV3IFRlc3RDYXNlKCJ3YXJuaW5nIikgew0KCQkJcHJvdGVjdGVkIHZvaWQgcnVuVGVzdCgpIHsNCgkJCQlmYWlsKG1lc3NhZ2UpOw0KCQkJfQ0KCQl9Ow0KCX0NCn1QSwMECgAAAAAA6njHMITWuZUGBwAABgcAACYAAABqdW5pdC9mcmFtZXdvcmsvQ29tcGFyaXNvbkZhaWx1cmUuamF2YXBhY2thZ2UganVuaXQuZnJhbWV3b3JrOw0KDQovKioNCiAqIFRocm93biB3aGVuIGFuIGFzc2VydCBlcXVhbHMgZm9yIFN0cmluZ3MgZmFpbGVkLg0KICogDQogKiBJbnNwaXJlZCBieSBhIHBhdGNoIGZyb20gQWxleCBDaGFmZmVlIG1haWx0bzphbGV4QHB1cnBsZXRlY2guY29tDQogKi8NCnB1YmxpYyBjbGFzcyBDb21wYXJpc29uRmFpbHVyZSBleHRlbmRzIEFzc2VydGlvbkZhaWxlZEVycm9yIHsNCglwcml2YXRlIFN0cmluZyBmRXhwZWN0ZWQ7DQoJcHJpdmF0ZSBTdHJpbmcgZkFjdHVhbDsNCg0KCS8qKg0KCSAqIENvbnN0cnVjdHMgYSBjb21wYXJpc29uIGZhaWx1cmUuDQoJICogQHBhcmFtIG1lc3NhZ2UgdGhlIGlkZW50aWZ5aW5nIG1lc3NhZ2Ugb3IgbnVsbA0KCSAqIEBwYXJhbSBleHBlY3RlZCB0aGUgZXhwZWN0ZWQgc3RyaW5nIHZhbHVlDQoJICogQHBhcmFtIGFjdHVhbCB0aGUgYWN0dWFsIHN0cmluZyB2YWx1ZQ0KCSAqLw0KCXB1YmxpYyBDb21wYXJpc29uRmFpbHVyZSAoU3RyaW5nIG1lc3NhZ2UsIFN0cmluZyBleHBlY3RlZCwgU3RyaW5nIGFjdHVhbCkgew0KCQlzdXBlciAobWVzc2FnZSk7DQoJCWZFeHBlY3RlZD0gZXhwZWN0ZWQ7DQoJCWZBY3R1YWw9IGFjdHVhbDsNCgl9DQoJDQoJLyoqDQoJICogUmV0dXJucyAiLi4uIiBpbiBwbGFjZSBvZiBjb21tb24gcHJlZml4IGFuZCAiLi4uIiBpbg0KCSAqIHBsYWNlIG9mIGNvbW1vbiBzdWZmaXggYmV0d2VlbiBleHBlY3RlZCBhbmQgYWN0dWFsLg0KCSAqIA0KCSAqIEBzZWUgamF2YS5sYW5nLlRocm93YWJsZSNnZXRNZXNzYWdlKCkNCgkgKi8NCglwdWJsaWMgU3RyaW5nIGdldE1lc3NhZ2UoKSB7DQoJCWlmIChmRXhwZWN0ZWQgPT0gbnVsbCB8fCBmQWN0dWFsID09IG51bGwpDQoJCQlyZXR1cm4gQXNzZXJ0LmZvcm1hdChzdXBlci5nZXRNZXNzYWdlKCksIGZFeHBlY3RlZCwgZkFjdHVhbCk7DQoJCQkNCgkJaW50IGVuZD0gTWF0aC5taW4oZkV4cGVjdGVkLmxlbmd0aCgpLCBmQWN0dWFsLmxlbmd0aCgpKTsNCgkJDQoJCWludCBpPSAwOw0KCQlmb3IoOyBpIDwgZW5kOyBpKyspIHsNCgkJCWlmIChmRXhwZWN0ZWQuY2hhckF0KGkpICE9IGZBY3R1YWwuY2hhckF0KGkpKQ0KCQkJCWJyZWFrOw0KCQl9DQoJCWludCBqPSBmRXhwZWN0ZWQubGVuZ3RoKCktMTsNCgkJaW50IGs9IGZBY3R1YWwubGVuZ3RoKCktMTsNCgkJZm9yICg7IGsgPj0gaSAmJiBqID49IGk7IGstLSxqLS0pIHsNCgkJCWlmIChmRXhwZWN0ZWQuY2hhckF0KGopICE9IGZBY3R1YWwuY2hhckF0KGspKQ0KCQkJCWJyZWFrOw0KCQl9DQoJCVN0cmluZyBhY3R1YWwsIGV4cGVjdGVkOw0KCQkNCgkJLy8gZXF1YWwgc3RyaW5ncw0KCQlpZiAoaiA8IGkgJiYgayA8IGkpIHsNCgkJCWV4cGVjdGVkPSBmRXhwZWN0ZWQ7DQoJCQlhY3R1YWw9IGZBY3R1YWw7DQoJCX0gZWxzZSB7DQoJCQlleHBlY3RlZD0gZkV4cGVjdGVkLnN1YnN0cmluZyhpLCBqKzEpOw0KCQkJYWN0dWFsPSBmQWN0dWFsLnN1YnN0cmluZyhpLCBrKzEpOw0KCQkJaWYgKGkgPD0gZW5kICYmIGkgPiAwKSB7DQoJCQkJZXhwZWN0ZWQ9ICIuLi4iK2V4cGVjdGVkOw0KCQkJCWFjdHVhbD0gIi4uLiIrYWN0dWFsOw0KCQkJfQ0KCQkJDQoJCQlpZiAoaiA8IGZFeHBlY3RlZC5sZW5ndGgoKS0xKQ0KCQkJCWV4cGVjdGVkPSBleHBlY3RlZCsiLi4uIjsNCgkJCWlmIChrIDwgZkFjdHVhbC5sZW5ndGgoKS0xKQ0KCQkJCWFjdHVhbD0gYWN0dWFsKyIuLi4iOw0KCQl9CQ0KCQlyZXR1cm4gQXNzZXJ0LmZvcm1hdChzdXBlci5nZXRNZXNzYWdlKCksIGV4cGVjdGVkLCBhY3R1YWwpOw0KCX0NCn1QSwMECgAAAAAA6njHMOW8TGauAQAArgEAACEAAABqdW5pdC9mcmFtZXdvcmsvVGVzdExpc3RlbmVyLmphdmFwYWNrYWdlIGp1bml0LmZyYW1ld29yazsNCg0KLyoqDQogKiBBIExpc3RlbmVyIGZvciB0ZXN0IHByb2dyZXNzDQogKi8NCnB1YmxpYyBpbnRlcmZhY2UgVGVzdExpc3RlbmVyIHsNCgkvKioNCiAJICogQW4gZXJyb3Igb2NjdXJyZWQuDQogCSAqLw0KCXB1YmxpYyB2b2lkIGFkZEVycm9yKFRlc3QgdGVzdCwgVGhyb3dhYmxlIHQpOw0KCS8qKg0KIAkgKiBBIGZhaWx1cmUgb2NjdXJyZWQuDQogCSAqLw0KIAlwdWJsaWMgdm9pZCBhZGRGYWlsdXJlKFRlc3QgdGVzdCwgQXNzZXJ0aW9uRmFpbGVkRXJyb3IgdCk7ICANCgkvKioNCgkgKiBBIHRlc3QgZW5kZWQuDQoJICovDQogCXB1YmxpYyB2b2lkIGVuZFRlc3QoVGVzdCB0ZXN0KTsgDQoJLyoqDQoJICogQSB0ZXN0IHN0YXJ0ZWQuDQoJICovDQoJcHVibGljIHZvaWQgc3RhcnRUZXN0KFRlc3QgdGVzdCk7DQp9UEsDBAoAAAAAAOp4xzDMuZ9FExUAABMVAAAdAAAAanVuaXQvZnJhbWV3b3JrL1Rlc3RDYXNlLmphdmFwYWNrYWdlIGp1bml0LmZyYW1ld29yazsNCg0KaW1wb3J0IGphdmEubGFuZy5yZWZsZWN0Lio7DQoNCi8qKg0KICogQSB0ZXN0IGNhc2UgZGVmaW5lcyB0aGUgZml4dHVyZSB0byBydW4gbXVsdGlwbGUgdGVzdHMuIFRvIGRlZmluZSBhIHRlc3QgY2FzZTxicj4NCiAqIDEpIGltcGxlbWVudCBhIHN1YmNsYXNzIG9mIFRlc3RDYXNlPGJyPg0KICogMikgZGVmaW5lIGluc3RhbmNlIHZhcmlhYmxlcyB0aGF0IHN0b3JlIHRoZSBzdGF0ZSBvZiB0aGUgZml4dHVyZTxicj4NCiAqIDMpIGluaXRpYWxpemUgdGhlIGZpeHR1cmUgc3RhdGUgYnkgb3ZlcnJpZGluZyA8Y29kZT5zZXRVcDwvY29kZT48YnI+DQogKiA0KSBjbGVhbi11cCBhZnRlciBhIHRlc3QgYnkgb3ZlcnJpZGluZyA8Y29kZT50ZWFyRG93bjwvY29kZT4uPGJyPg0KICogRWFjaCB0ZXN0IHJ1bnMgaW4gaXRzIG93biBmaXh0dXJlIHNvIHRoZXJlDQogKiBjYW4gYmUgbm8gc2lkZSBlZmZlY3RzIGFtb25nIHRlc3QgcnVucy4NCiAqIEhlcmUgaXMgYW4gZXhhbXBsZToNCiAqIDxwcmU+DQogKiBwdWJsaWMgY2xhc3MgTWF0aFRlc3QgZXh0ZW5kcyBUZXN0Q2FzZSB7DQogKiAgICAgcHJvdGVjdGVkIGRvdWJsZSBmVmFsdWUxOw0KICogICAgIHByb3RlY3RlZCBkb3VibGUgZlZhbHVlMjsNCiAqDQogKiAgICBwcm90ZWN0ZWQgdm9pZCBzZXRVcCgpIHsNCiAqICAgICAgICAgZlZhbHVlMT0gMi4wOw0KICogICAgICAgICBmVmFsdWUyPSAzLjA7DQogKiAgICAgfQ0KICogfQ0KICogPC9wcmU+DQogKg0KICogRm9yIGVhY2ggdGVzdCBpbXBsZW1lbnQgYSBtZXRob2Qgd2hpY2ggaW50ZXJhY3RzDQogKiB3aXRoIHRoZSBmaXh0dXJlLiBWZXJpZnkgdGhlIGV4cGVjdGVkIHJlc3VsdHMgd2l0aCBhc3NlcnRpb25zIHNwZWNpZmllZA0KICogYnkgY2FsbGluZyA8Y29kZT5hc3NlcnRUcnVlPC9jb2RlPiB3aXRoIGEgYm9vbGVhbi4NCiAqIDxwcmU+DQogKiAgICBwdWJsaWMgdm9pZCB0ZXN0QWRkKCkgew0KICogICAgICAgIGRvdWJsZSByZXN1bHQ9IGZWYWx1ZTEgKyBmVmFsdWUyOw0KICogICAgICAgIGFzc2VydFRydWUocmVzdWx0ID09IDUuMCk7DQogKiAgICB9DQogKiA8L3ByZT4NCiAqIE9uY2UgdGhlIG1ldGhvZHMgYXJlIGRlZmluZWQgeW91IGNhbiBydW4gdGhlbS4gVGhlIGZyYW1ld29yayBzdXBwb3J0cw0KICogYm90aCBhIHN0YXRpYyB0eXBlIHNhZmUgYW5kIG1vcmUgZHluYW1pYyB3YXkgdG8gcnVuIGEgdGVzdC4NCiAqIEluIHRoZSBzdGF0aWMgd2F5IHlvdSBvdmVycmlkZSB0aGUgcnVuVGVzdCBtZXRob2QgYW5kIGRlZmluZSB0aGUgbWV0aG9kIHRvDQogKiBiZSBpbnZva2VkLiBBIGNvbnZlbmllbnQgd2F5IHRvIGRvIHNvIGlzIHdpdGggYW4gYW5vbnltb3VzIGlubmVyIGNsYXNzLg0KICogPHByZT4NCiAqIFRlc3RDYXNlIHRlc3Q9IG5ldyBNYXRoVGVzdCgiYWRkIikgew0KICogICAgICAgIHB1YmxpYyB2b2lkIHJ1blRlc3QoKSB7DQogKiAgICAgICAgICAgIHRlc3RBZGQoKTsNCiAqICAgICAgICB9DQogKiB9Ow0KICogdGVzdC5ydW4oKTsNCiAqIDwvcHJlPg0KICogVGhlIGR5bmFtaWMgd2F5IHVzZXMgcmVmbGVjdGlvbiB0byBpbXBsZW1lbnQgPGNvZGU+cnVuVGVzdDwvY29kZT4uIEl0IGR5bmFtaWNhbGx5IGZpbmRzDQogKiBhbmQgaW52b2tlcyBhIG1ldGhvZC4NCiAqIEluIHRoaXMgY2FzZSB0aGUgbmFtZSBvZiB0aGUgdGVzdCBjYXNlIGhhcyB0byBjb3JyZXNwb25kIHRvIHRoZSB0ZXN0IG1ldGhvZA0KICogdG8gYmUgcnVuLg0KICogPHByZT4NCiAqIFRlc3RDYXNlPSBuZXcgTWF0aFRlc3QoInRlc3RBZGQiKTsNCiAqIHRlc3QucnVuKCk7DQogKiA8L3ByZT4NCiAqIFRoZSB0ZXN0cyB0byBiZSBydW4gY2FuIGJlIGNvbGxlY3RlZCBpbnRvIGEgVGVzdFN1aXRlLiBKVW5pdCBwcm92aWRlcw0KICogZGlmZmVyZW50IDxpPnRlc3QgcnVubmVyczwvaT4gd2hpY2ggY2FuIHJ1biBhIHRlc3Qgc3VpdGUgYW5kIGNvbGxlY3QgdGhlIHJlc3VsdHMuDQogKiBBIHRlc3QgcnVubmVyIGVpdGhlciBleHBlY3RzIGEgc3RhdGljIG1ldGhvZCA8Y29kZT5zdWl0ZTwvY29kZT4gYXMgdGhlIGVudHJ5DQogKiBwb2ludCB0byBnZXQgYSB0ZXN0IHRvIHJ1biBvciBpdCB3aWxsIGV4dHJhY3QgdGhlIHN1aXRlIGF1dG9tYXRpY2FsbHkuDQogKiA8cHJlPg0KICogcHVibGljIHN0YXRpYyBUZXN0IHN1aXRlKCkgew0KICogICAgICBzdWl0ZS5hZGRUZXN0KG5ldyBNYXRoVGVzdCgidGVzdEFkZCIpKTsNCiAqICAgICAgc3VpdGUuYWRkVGVzdChuZXcgTWF0aFRlc3QoInRlc3REaXZpZGVCeVplcm8iKSk7DQogKiAgICAgIHJldHVybiBzdWl0ZTsNCiAqICB9DQogKiA8L3ByZT4NCiAqIEBzZWUgVGVzdFJlc3VsdA0KICogQHNlZSBUZXN0U3VpdGUNCiAqLw0KDQpwdWJsaWMgYWJzdHJhY3QgY2xhc3MgVGVzdENhc2UgZXh0ZW5kcyBBc3NlcnQgaW1wbGVtZW50cyBUZXN0IHsNCgkvKioNCgkgKiB0aGUgbmFtZSBvZiB0aGUgdGVzdCBjYXNlDQoJICovDQoJcHJpdmF0ZSBTdHJpbmcgZk5hbWU7DQoNCgkvKioNCgkgKiBOby1hcmcgY29uc3RydWN0b3IgdG8gZW5hYmxlIHNlcmlhbGl6YXRpb24uIFRoaXMgbWV0aG9kDQoJICogaXMgbm90IGludGVuZGVkIHRvIGJlIHVzZWQgYnkgbWVyZSBtb3J0YWxzIHdpdGhvdXQgY2FsbGluZyBzZXROYW1lKCkuDQoJICovDQoJcHVibGljIFRlc3RDYXNlKCkgew0KCQlmTmFtZT0gbnVsbDsNCgl9DQoJLyoqDQoJICogQ29uc3RydWN0cyBhIHRlc3QgY2FzZSB3aXRoIHRoZSBnaXZlbiBuYW1lLg0KCSAqLw0KCXB1YmxpYyBUZXN0Q2FzZShTdHJpbmcgbmFtZSkgew0KCQlmTmFtZT0gbmFtZTsNCgl9DQoJLyoqDQoJICogQ291bnRzIHRoZSBudW1iZXIgb2YgdGVzdCBjYXNlcyBleGVjdXRlZCBieSBydW4oVGVzdFJlc3VsdCByZXN1bHQpLg0KCSAqLw0KCXB1YmxpYyBpbnQgY291bnRUZXN0Q2FzZXMoKSB7DQoJCXJldHVybiAxOw0KCX0NCgkvKioNCgkgKiBDcmVhdGVzIGEgZGVmYXVsdCBUZXN0UmVzdWx0IG9iamVjdA0KCSAqDQoJICogQHNlZSBUZXN0UmVzdWx0DQoJICovDQoJcHJvdGVjdGVkIFRlc3RSZXN1bHQgY3JlYXRlUmVzdWx0KCkgew0KCSAgICByZXR1cm4gbmV3IFRlc3RSZXN1bHQoKTsNCgl9DQoJLyoqDQoJICogQSBjb252ZW5pZW5jZSBtZXRob2QgdG8gcnVuIHRoaXMgdGVzdCwgY29sbGVjdGluZyB0aGUgcmVzdWx0cyB3aXRoIGENCgkgKiBkZWZhdWx0IFRlc3RSZXN1bHQgb2JqZWN0Lg0KCSAqDQoJICogQHNlZSBUZXN0UmVzdWx0DQoJICovDQoJcHVibGljIFRlc3RSZXN1bHQgcnVuKCkgew0KCQlUZXN0UmVzdWx0IHJlc3VsdD0gY3JlYXRlUmVzdWx0KCk7DQoJCXJ1bihyZXN1bHQpOw0KCQlyZXR1cm4gcmVzdWx0Ow0KCX0NCgkvKioNCgkgKiBSdW5zIHRoZSB0ZXN0IGNhc2UgYW5kIGNvbGxlY3RzIHRoZSByZXN1bHRzIGluIFRlc3RSZXN1bHQuDQoJICovDQoJcHVibGljIHZvaWQgcnVuKFRlc3RSZXN1bHQgcmVzdWx0KSB7DQoJCXJlc3VsdC5ydW4odGhpcyk7DQoJfQ0KCS8qKg0KCSAqIFJ1bnMgdGhlIGJhcmUgdGVzdCBzZXF1ZW5jZS4NCgkgKiBAZXhjZXB0aW9uIFRocm93YWJsZSBpZiBhbnkgZXhjZXB0aW9uIGlzIHRocm93bg0KCSAqLw0KCXB1YmxpYyB2b2lkIHJ1bkJhcmUoKSB0aHJvd3MgVGhyb3dhYmxlIHsNCgkJc2V0VXAoKTsNCgkJdHJ5IHsNCgkJCXJ1blRlc3QoKTsNCgkJfQ0KCQlmaW5hbGx5IHsNCgkJCXRlYXJEb3duKCk7DQoJCX0NCgl9DQoJLyoqDQoJICogT3ZlcnJpZGUgdG8gcnVuIHRoZSB0ZXN0IGFuZCBhc3NlcnQgaXRzIHN0YXRlLg0KCSAqIEBleGNlcHRpb24gVGhyb3dhYmxlIGlmIGFueSBleGNlcHRpb24gaXMgdGhyb3duDQoJICovDQoJcHJvdGVjdGVkIHZvaWQgcnVuVGVzdCgpIHRocm93cyBUaHJvd2FibGUgew0KCQlhc3NlcnROb3ROdWxsKGZOYW1lKTsNCgkJTWV0aG9kIHJ1bk1ldGhvZD0gbnVsbDsNCgkJdHJ5IHsNCgkJCS8vIHVzZSBnZXRNZXRob2QgdG8gZ2V0IGFsbCBwdWJsaWMgaW5oZXJpdGVkDQoJCQkvLyBtZXRob2RzLiBnZXREZWNsYXJlZE1ldGhvZHMgcmV0dXJucyBhbGwNCgkJCS8vIG1ldGhvZHMgb2YgdGhpcyBjbGFzcyBidXQgZXhjbHVkZXMgdGhlDQoJCQkvLyBpbmhlcml0ZWQgb25lcy4NCgkJCXJ1bk1ldGhvZD0gZ2V0Q2xhc3MoKS5nZXRNZXRob2QoZk5hbWUsIG51bGwpOw0KCQl9IGNhdGNoIChOb1N1Y2hNZXRob2RFeGNlcHRpb24gZSkgew0KCQkJZmFpbCgiTWV0aG9kIFwiIitmTmFtZSsiXCIgbm90IGZvdW5kIik7DQoJCX0NCgkJaWYgKCFNb2RpZmllci5pc1B1YmxpYyhydW5NZXRob2QuZ2V0TW9kaWZpZXJzKCkpKSB7DQoJCQlmYWlsKCJNZXRob2QgXCIiK2ZOYW1lKyJcIiBzaG91bGQgYmUgcHVibGljIik7DQoJCX0NCg0KCQl0cnkgew0KCQkJcnVuTWV0aG9kLmludm9rZSh0aGlzLCBuZXcgQ2xhc3NbMF0pOw0KCQl9DQoJCWNhdGNoIChJbnZvY2F0aW9uVGFyZ2V0RXhjZXB0aW9uIGUpIHsNCgkJCWUuZmlsbEluU3RhY2tUcmFjZSgpOw0KCQkJdGhyb3cgZS5nZXRUYXJnZXRFeGNlcHRpb24oKTsNCgkJfQ0KCQljYXRjaCAoSWxsZWdhbEFjY2Vzc0V4Y2VwdGlvbiBlKSB7DQoJCQllLmZpbGxJblN0YWNrVHJhY2UoKTsNCgkJCXRocm93IGU7DQoJCX0NCgl9DQoJLyoqDQoJICogU2V0cyB1cCB0aGUgZml4dHVyZSwgZm9yIGV4YW1wbGUsIG9wZW4gYSBuZXR3b3JrIGNvbm5lY3Rpb24uDQoJICogVGhpcyBtZXRob2QgaXMgY2FsbGVkIGJlZm9yZSBhIHRlc3QgaXMgZXhlY3V0ZWQuDQoJICovDQoJcHJvdGVjdGVkIHZvaWQgc2V0VXAoKSB0aHJvd3MgRXhjZXB0aW9uIHsNCgl9DQoJLyoqDQoJICogVGVhcnMgZG93biB0aGUgZml4dHVyZSwgZm9yIGV4YW1wbGUsIGNsb3NlIGEgbmV0d29yayBjb25uZWN0aW9uLg0KCSAqIFRoaXMgbWV0aG9kIGlzIGNhbGxlZCBhZnRlciBhIHRlc3QgaXMgZXhlY3V0ZWQuDQoJICovDQoJcHJvdGVjdGVkIHZvaWQgdGVhckRvd24oKSB0aHJvd3MgRXhjZXB0aW9uIHsNCgl9DQoJLyoqDQoJICogUmV0dXJucyBhIHN0cmluZyByZXByZXNlbnRhdGlvbiBvZiB0aGUgdGVzdCBjYXNlDQoJICovDQoJcHVibGljIFN0cmluZyB0b1N0cmluZygpIHsNCgkgICAgcmV0dXJuIGdldE5hbWUoKSArICIoIiArIGdldENsYXNzKCkuZ2V0TmFtZSgpICsgIikiOw0KCX0NCgkvKioNCgkgKiBHZXRzIHRoZSBuYW1lIG9mIGEgVGVzdENhc2UNCgkgKiBAcmV0dXJuIHJldHVybnMgYSBTdHJpbmcNCgkgKi8NCglwdWJsaWMgU3RyaW5nIGdldE5hbWUoKSB7DQoJCXJldHVybiBmTmFtZTsNCgl9DQoJLyoqDQoJICogU2V0cyB0aGUgbmFtZSBvZiBhIFRlc3RDYXNlDQoJICogQHBhcmFtIG5hbWUgVGhlIG5hbWUgdG8gc2V0DQoJICovDQoJcHVibGljIHZvaWQgc2V0TmFtZShTdHJpbmcgbmFtZSkgew0KCQlmTmFtZT0gbmFtZTsNCgl9DQp9UEsDBAoAAAAAAOp4xzDUajqxCAIAAAgCAAAqAAAAanVuaXQvcnVubmVyL1JlbG9hZGluZ1Rlc3RTdWl0ZUxvYWRlci5qYXZhcGFja2FnZSBqdW5pdC5ydW5uZXI7DQoNCi8qKg0KICogQSBUZXN0U3VpdGUgbG9hZGVyIHRoYXQgY2FuIHJlbG9hZCBjbGFzc2VzLg0KICovDQpwdWJsaWMgY2xhc3MgUmVsb2FkaW5nVGVzdFN1aXRlTG9hZGVyIGltcGxlbWVudHMgVGVzdFN1aXRlTG9hZGVyIHsNCgkNCglwdWJsaWMgQ2xhc3MgbG9hZChTdHJpbmcgc3VpdGVDbGFzc05hbWUpIHRocm93cyBDbGFzc05vdEZvdW5kRXhjZXB0aW9uIHsNCgkJcmV0dXJuIGNyZWF0ZUxvYWRlcigpLmxvYWRDbGFzcyhzdWl0ZUNsYXNzTmFtZSwgdHJ1ZSk7DQoJfQ0KCQ0KCXB1YmxpYyBDbGFzcyByZWxvYWQoQ2xhc3MgYUNsYXNzKSB0aHJvd3MgQ2xhc3NOb3RGb3VuZEV4Y2VwdGlvbiB7DQoJCXJldHVybiBjcmVhdGVMb2FkZXIoKS5sb2FkQ2xhc3MoYUNsYXNzLmdldE5hbWUoKSwgdHJ1ZSk7DQoJfQ0KCQ0KCXByb3RlY3RlZCBUZXN0Q2FzZUNsYXNzTG9hZGVyIGNyZWF0ZUxvYWRlcigpIHsNCgkJcmV0dXJuIG5ldyBUZXN0Q2FzZUNsYXNzTG9hZGVyKCk7DQoJfQ0KfVBLAwQKAAAAAADqeMcwD9obOw0CAAANAgAAKQAAAGp1bml0L3J1bm5lci9TdGFuZGFyZFRlc3RTdWl0ZUxvYWRlci5qYXZhcGFja2FnZSBqdW5pdC5ydW5uZXI7DQoNCi8qKg0KICogVGhlIHN0YW5kYXJkIHRlc3Qgc3VpdGUgbG9hZGVyLiBJdCBjYW4gb25seSBsb2FkIHRoZSBzYW1lIGNsYXNzIG9uY2UuDQogKi8NCnB1YmxpYyBjbGFzcyBTdGFuZGFyZFRlc3RTdWl0ZUxvYWRlciBpbXBsZW1lbnRzIFRlc3RTdWl0ZUxvYWRlciB7DQoJLyoqDQoJICogVXNlcyB0aGUgc3lzdGVtIGNsYXNzIGxvYWRlciB0byBsb2FkIHRoZSB0ZXN0IGNsYXNzDQoJICovDQoJcHVibGljIENsYXNzIGxvYWQoU3RyaW5nIHN1aXRlQ2xhc3NOYW1lKSB0aHJvd3MgQ2xhc3NOb3RGb3VuZEV4Y2VwdGlvbiB7DQoJCXJldHVybiBDbGFzcy5mb3JOYW1lKHN1aXRlQ2xhc3NOYW1lKTsNCgl9DQoJLyoqDQoJICogVXNlcyB0aGUgc3lzdGVtIGNsYXNzIGxvYWRlciB0byBsb2FkIHRoZSB0ZXN0IGNsYXNzDQoJICovDQoJcHVibGljIENsYXNzIHJlbG9hZChDbGFzcyBhQ2xhc3MpIHRocm93cyBDbGFzc05vdEZvdW5kRXhjZXB0aW9uIHsNCgkJcmV0dXJuIGFDbGFzczsNCgl9DQp9UEsDBAoAAAAAAOp4xzAdFyMgswEAALMBAAAjAAAAanVuaXQvcnVubmVyL0ZhaWx1cmVEZXRhaWxWaWV3LmphdmFwYWNrYWdlIGp1bml0LnJ1bm5lcjsNCg0KaW1wb3J0IGphdmEuYXd0LkNvbXBvbmVudDsgDQoNCmltcG9ydCBqdW5pdC5mcmFtZXdvcmsuKjsNCg0KLyoqDQogKiBBIHZpZXcgdG8gc2hvdyBhIGRldGFpbHMgYWJvdXQgYSBmYWlsdXJlDQogKi8NCnB1YmxpYyBpbnRlcmZhY2UgRmFpbHVyZURldGFpbFZpZXcgew0KCS8qKg0KCSAqIFJldHVybnMgdGhlIGNvbXBvbmVudCB1c2VkIHRvIHByZXNlbnQgdGhlIFRyYWNlVmlldw0KCSAqLw0KCXB1YmxpYyBDb21wb25lbnQgZ2V0Q29tcG9uZW50KCk7DQoJLyoqDQoJICogU2hvd3MgZGV0YWlscyBvZiBhIFRlc3RGYWlsdXJlDQoJICovDQoJcHVibGljIHZvaWQgc2hvd0ZhaWx1cmUoVGVzdEZhaWx1cmUgZmFpbHVyZSk7DQoJLyoqDQoJICogQ2xlYXJzIHRoZSB2aWV3DQoJICovDQoJcHVibGljIHZvaWQgY2xlYXIoKTsNCn1QSwMECgAAAAAA6njHMF91JDwPIQAADyEAACAAAABqdW5pdC9ydW5uZXIvQmFzZVRlc3RSdW5uZXIuamF2YXBhY2thZ2UganVuaXQucnVubmVyOw0KDQppbXBvcnQganVuaXQuZnJhbWV3b3JrLio7DQppbXBvcnQgamF2YS5sYW5nLnJlZmxlY3QuKjsNCmltcG9ydCBqYXZhLnRleHQuTnVtYmVyRm9ybWF0Ow0KaW1wb3J0IGphdmEuaW8uKjsNCmltcG9ydCBqYXZhLnV0aWwuKjsNCg0KLyoqDQogKiBCYXNlIGNsYXNzIGZvciBhbGwgdGVzdCBydW5uZXJzLg0KICogVGhpcyBjbGFzcyB3YXMgYm9ybiBsaXZlIG9uIHN0YWdlIGluIFNhcmRpbmlhIGR1cmluZyBYUDIwMDAuDQogKi8NCnB1YmxpYyBhYnN0cmFjdCBjbGFzcyBCYXNlVGVzdFJ1bm5lciBpbXBsZW1lbnRzIFRlc3RMaXN0ZW5lciB7DQoJcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgU1VJVEVfTUVUSE9ETkFNRT0gInN1aXRlIjsNCg0KCXByaXZhdGUgc3RhdGljIFByb3BlcnRpZXMgZlByZWZlcmVuY2VzOw0KCXN0YXRpYyBpbnQgZmdNYXhNZXNzYWdlTGVuZ3RoPSA1MDA7DQoJc3RhdGljIGJvb2xlYW4gZmdGaWx0ZXJTdGFjaz0gdHJ1ZTsNCglib29sZWFuIGZMb2FkaW5nPSB0cnVlOw0KDQogICAgLyoNCiAgICAqIEltcGxlbWVudGF0aW9uIG9mIFRlc3RMaXN0ZW5lcg0KICAgICovDQoJcHVibGljIHN5bmNocm9uaXplZCB2b2lkIHN0YXJ0VGVzdChUZXN0IHRlc3QpIHsNCgkJdGVzdFN0YXJ0ZWQodGVzdC50b1N0cmluZygpKTsNCgl9DQoNCglwcm90ZWN0ZWQgc3RhdGljIHZvaWQgc2V0UHJlZmVyZW5jZXMoUHJvcGVydGllcyBwcmVmZXJlbmNlcykgew0KCQlmUHJlZmVyZW5jZXM9IHByZWZlcmVuY2VzOw0KCX0NCg0KCXByb3RlY3RlZCBzdGF0aWMgUHJvcGVydGllcyBnZXRQcmVmZXJlbmNlcygpIHsNCgkJaWYgKGZQcmVmZXJlbmNlcyA9PSBudWxsKSB7DQoJCQlmUHJlZmVyZW5jZXM9IG5ldyBQcm9wZXJ0aWVzKCk7DQoJIAkJZlByZWZlcmVuY2VzLnB1dCgibG9hZGluZyIsICJ0cnVlIik7DQogCQkJZlByZWZlcmVuY2VzLnB1dCgiZmlsdGVyc3RhY2siLCAidHJ1ZSIpOw0KICAJCQlyZWFkUHJlZmVyZW5jZXMoKTsNCgkJfQ0KCQlyZXR1cm4gZlByZWZlcmVuY2VzOw0KCX0NCg0KCXB1YmxpYyBzdGF0aWMgdm9pZCBzYXZlUHJlZmVyZW5jZXMoKSB0aHJvd3MgSU9FeGNlcHRpb24gew0KCQlGaWxlT3V0cHV0U3RyZWFtIGZvcz0gbmV3IEZpbGVPdXRwdXRTdHJlYW0oZ2V0UHJlZmVyZW5jZXNGaWxlKCkpOw0KCQl0cnkgew0KCQkJZ2V0UHJlZmVyZW5jZXMoKS5zdG9yZShmb3MsICIiKTsNCgkJfSBmaW5hbGx5IHsNCgkJCWZvcy5jbG9zZSgpOw0KCQl9DQoJfQ0KDQoJcHVibGljIHZvaWQgc2V0UHJlZmVyZW5jZShTdHJpbmcga2V5LCBTdHJpbmcgdmFsdWUpIHsNCgkJZ2V0UHJlZmVyZW5jZXMoKS5zZXRQcm9wZXJ0eShrZXksIHZhbHVlKTsNCgl9DQoNCglwdWJsaWMgc3luY2hyb25pemVkIHZvaWQgZW5kVGVzdChUZXN0IHRlc3QpIHsNCgkJdGVzdEVuZGVkKHRlc3QudG9TdHJpbmcoKSk7DQoJfQ0KDQoJcHVibGljIHN5bmNocm9uaXplZCB2b2lkIGFkZEVycm9yKGZpbmFsIFRlc3QgdGVzdCwgZmluYWwgVGhyb3dhYmxlIHQpIHsNCgkJdGVzdEZhaWxlZChUZXN0UnVuTGlzdGVuZXIuU1RBVFVTX0VSUk9SLCB0ZXN0LCB0KTsNCgl9DQoNCglwdWJsaWMgc3luY2hyb25pemVkIHZvaWQgYWRkRmFpbHVyZShmaW5hbCBUZXN0IHRlc3QsIGZpbmFsIEFzc2VydGlvbkZhaWxlZEVycm9yIHQpIHsNCgkJdGVzdEZhaWxlZChUZXN0UnVuTGlzdGVuZXIuU1RBVFVTX0ZBSUxVUkUsIHRlc3QsIHQpOw0KCX0NCg0KCS8vIFRlc3RSdW5MaXN0ZW5lciBpbXBsZW1lbnRhdGlvbg0KDQoJcHVibGljIGFic3RyYWN0IHZvaWQgdGVzdFN0YXJ0ZWQoU3RyaW5nIHRlc3ROYW1lKTsNCg0KCXB1YmxpYyBhYnN0cmFjdCB2b2lkIHRlc3RFbmRlZChTdHJpbmcgdGVzdE5hbWUpOw0KDQoJcHVibGljIGFic3RyYWN0IHZvaWQgdGVzdEZhaWxlZChpbnQgc3RhdHVzLCBUZXN0IHRlc3QsIFRocm93YWJsZSB0KTsNCg0KCS8qKg0KCSAqIFJldHVybnMgdGhlIFRlc3QgY29ycmVzcG9uZGluZyB0byB0aGUgZ2l2ZW4gc3VpdGUuIFRoaXMgaXMNCgkgKiBhIHRlbXBsYXRlIG1ldGhvZCwgc3ViY2xhc3NlcyBvdmVycmlkZSBydW5GYWlsZWQoKSwgY2xlYXJTdGF0dXMoKS4NCgkgKi8NCglwdWJsaWMgVGVzdCBnZXRUZXN0KFN0cmluZyBzdWl0ZUNsYXNzTmFtZSkgew0KCQlpZiAoc3VpdGVDbGFzc05hbWUubGVuZ3RoKCkgPD0gMCkgew0KCQkJY2xlYXJTdGF0dXMoKTsNCgkJCXJldHVybiBudWxsOw0KCQl9DQoJCUNsYXNzIHRlc3RDbGFzcz0gbnVsbDsNCgkJdHJ5IHsNCgkJCXRlc3RDbGFzcz0gbG9hZFN1aXRlQ2xhc3Moc3VpdGVDbGFzc05hbWUpOw0KCQl9IGNhdGNoIChDbGFzc05vdEZvdW5kRXhjZXB0aW9uIGUpIHsNCgkJCVN0cmluZyBjbGF6ej0gZS5nZXRNZXNzYWdlKCk7DQoJCQlpZiAoY2xhenogPT0gbnVsbCkNCgkJCQljbGF6ej0gc3VpdGVDbGFzc05hbWU7DQoJCQlydW5GYWlsZWQoIkNsYXNzIG5vdCBmb3VuZCBcIiIrY2xhenorIlwiIik7DQoJCQlyZXR1cm4gbnVsbDsNCgkJfSBjYXRjaChFeGNlcHRpb24gZSkgew0KCQkJcnVuRmFpbGVkKCJFcnJvcjogIitlLnRvU3RyaW5nKCkpOw0KCQkJcmV0dXJuIG51bGw7DQoJCX0NCgkJTWV0aG9kIHN1aXRlTWV0aG9kPSBudWxsOw0KCQl0cnkgew0KCQkJc3VpdGVNZXRob2Q9IHRlc3RDbGFzcy5nZXRNZXRob2QoU1VJVEVfTUVUSE9ETkFNRSwgbmV3IENsYXNzWzBdKTsNCgkgCX0gY2F0Y2goRXhjZXB0aW9uIGUpIHsNCgkgCQkvLyB0cnkgdG8gZXh0cmFjdCBhIHRlc3Qgc3VpdGUgYXV0b21hdGljYWxseQ0KCQkJY2xlYXJTdGF0dXMoKTsNCgkJCXJldHVybiBuZXcgVGVzdFN1aXRlKHRlc3RDbGFzcyk7DQoJCX0NCgkJaWYgKCEgTW9kaWZpZXIuaXNTdGF0aWMoc3VpdGVNZXRob2QuZ2V0TW9kaWZpZXJzKCkpKSB7DQoJCQlydW5GYWlsZWQoIlN1aXRlKCkgbWV0aG9kIG11c3QgYmUgc3RhdGljIik7DQoJCQlyZXR1cm4gbnVsbDsNCgkJfQ0KCQlUZXN0IHRlc3Q9IG51bGw7DQoJCXRyeSB7DQoJCQl0ZXN0PSAoVGVzdClzdWl0ZU1ldGhvZC5pbnZva2UobnVsbCwgbmV3IENsYXNzWzBdKTsgLy8gc3RhdGljIG1ldGhvZA0KCQkJaWYgKHRlc3QgPT0gbnVsbCkNCgkJCQlyZXR1cm4gdGVzdDsNCgkJfQ0KCQljYXRjaCAoSW52b2NhdGlvblRhcmdldEV4Y2VwdGlvbiBlKSB7DQoJCQlydW5GYWlsZWQoIkZhaWxlZCB0byBpbnZva2Ugc3VpdGUoKToiICsgZS5nZXRUYXJnZXRFeGNlcHRpb24oKS50b1N0cmluZygpKTsNCgkJCXJldHVybiBudWxsOw0KCQl9DQoJCWNhdGNoIChJbGxlZ2FsQWNjZXNzRXhjZXB0aW9uIGUpIHsNCgkJCXJ1bkZhaWxlZCgiRmFpbGVkIHRvIGludm9rZSBzdWl0ZSgpOiIgKyBlLnRvU3RyaW5nKCkpOw0KCQkJcmV0dXJuIG51bGw7DQoJCX0NCg0KCQljbGVhclN0YXR1cygpOw0KCQlyZXR1cm4gdGVzdDsNCgl9DQoNCgkvKioNCgkgKiBSZXR1cm5zIHRoZSBmb3JtYXR0ZWQgc3RyaW5nIG9mIHRoZSBlbGFwc2VkIHRpbWUuDQoJICovDQoJcHVibGljIFN0cmluZyBlbGFwc2VkVGltZUFzU3RyaW5nKGxvbmcgcnVuVGltZSkgew0KCQlyZXR1cm4gTnVtYmVyRm9ybWF0LmdldEluc3RhbmNlKCkuZm9ybWF0KChkb3VibGUpcnVuVGltZS8xMDAwKTsNCgl9DQoNCgkvKioNCgkgKiBQcm9jZXNzZXMgdGhlIGNvbW1hbmQgbGluZSBhcmd1bWVudHMgYW5kDQoJICogcmV0dXJucyB0aGUgbmFtZSBvZiB0aGUgc3VpdGUgY2xhc3MgdG8gcnVuIG9yIG51bGwNCgkgKi8NCglwcm90ZWN0ZWQgU3RyaW5nIHByb2Nlc3NBcmd1bWVudHMoU3RyaW5nW10gYXJncykgew0KCQlTdHJpbmcgc3VpdGVOYW1lPSBudWxsOw0KCQlmb3IgKGludCBpPSAwOyBpIDwgYXJncy5sZW5ndGg7IGkrKykgew0KCQkJaWYgKGFyZ3NbaV0uZXF1YWxzKCItbm9sb2FkaW5nIikpIHsNCgkJCQlzZXRMb2FkaW5nKGZhbHNlKTsNCgkJCX0gZWxzZSBpZiAoYXJnc1tpXS5lcXVhbHMoIi1ub2ZpbHRlcnN0YWNrIikpIHsNCgkJCQlmZ0ZpbHRlclN0YWNrPSBmYWxzZTsNCgkJCX0gZWxzZSBpZiAoYXJnc1tpXS5lcXVhbHMoIi1jIikpIHsNCgkJCQlpZiAoYXJncy5sZW5ndGggPiBpKzEpDQoJCQkJCXN1aXRlTmFtZT0gZXh0cmFjdENsYXNzTmFtZShhcmdzW2krMV0pOw0KCQkJCWVsc2UNCgkJCQkJU3lzdGVtLm91dC5wcmludGxuKCJNaXNzaW5nIFRlc3QgY2xhc3MgbmFtZSIpOw0KCQkJCWkrKzsNCgkJCX0gZWxzZSB7DQoJCQkJc3VpdGVOYW1lPSBhcmdzW2ldOw0KCQkJfQ0KCQl9DQoJCXJldHVybiBzdWl0ZU5hbWU7DQoJfQ0KDQoJLyoqDQoJICogU2V0cyB0aGUgbG9hZGluZyBiZWhhdmlvdXIgb2YgdGhlIHRlc3QgcnVubmVyDQoJICovDQoJcHVibGljIHZvaWQgc2V0TG9hZGluZyhib29sZWFuIGVuYWJsZSkgew0KCQlmTG9hZGluZz0gZW5hYmxlOw0KCX0NCgkvKioNCgkgKiBFeHRyYWN0IHRoZSBjbGFzcyBuYW1lIGZyb20gYSBTdHJpbmcgaW4gVkEvSmF2YSBzdHlsZQ0KCSAqLw0KCXB1YmxpYyBTdHJpbmcgZXh0cmFjdENsYXNzTmFtZShTdHJpbmcgY2xhc3NOYW1lKSB7DQoJCWlmKGNsYXNzTmFtZS5zdGFydHNXaXRoKCJEZWZhdWx0IHBhY2thZ2UgZm9yIikpDQoJCQlyZXR1cm4gY2xhc3NOYW1lLnN1YnN0cmluZyhjbGFzc05hbWUubGFzdEluZGV4T2YoIi4iKSsxKTsNCgkJcmV0dXJuIGNsYXNzTmFtZTsNCgl9DQoNCgkvKioNCgkgKiBUcnVuY2F0ZXMgYSBTdHJpbmcgdG8gdGhlIG1heGltdW0gbGVuZ3RoLg0KCSAqLw0KCXB1YmxpYyBzdGF0aWMgU3RyaW5nIHRydW5jYXRlKFN0cmluZyBzKSB7DQoJCWlmIChmZ01heE1lc3NhZ2VMZW5ndGggIT0gLTEgJiYgcy5sZW5ndGgoKSA+IGZnTWF4TWVzc2FnZUxlbmd0aCkNCgkJCXM9IHMuc3Vic3RyaW5nKDAsIGZnTWF4TWVzc2FnZUxlbmd0aCkrIi4uLiI7DQoJCXJldHVybiBzOw0KCX0NCg0KCS8qKg0KCSAqIE92ZXJyaWRlIHRvIGRlZmluZSBob3cgdG8gaGFuZGxlIGEgZmFpbGVkIGxvYWRpbmcgb2YNCgkgKiBhIHRlc3Qgc3VpdGUuDQoJICovDQoJcHJvdGVjdGVkIGFic3RyYWN0IHZvaWQgcnVuRmFpbGVkKFN0cmluZyBtZXNzYWdlKTsNCg0KCS8qKg0KCSAqIFJldHVybnMgdGhlIGxvYWRlZCBDbGFzcyBmb3IgYSBzdWl0ZSBuYW1lLg0KCSAqLw0KCXByb3RlY3RlZCBDbGFzcyBsb2FkU3VpdGVDbGFzcyhTdHJpbmcgc3VpdGVDbGFzc05hbWUpIHRocm93cyBDbGFzc05vdEZvdW5kRXhjZXB0aW9uIHsNCgkJcmV0dXJuIGdldExvYWRlcigpLmxvYWQoc3VpdGVDbGFzc05hbWUpOw0KCX0NCg0KCS8qKg0KCSAqIENsZWFycyB0aGUgc3RhdHVzIG1lc3NhZ2UuDQoJICovDQoJcHJvdGVjdGVkIHZvaWQgY2xlYXJTdGF0dXMoKSB7IC8vIEJlbG9uZ3MgaW4gdGhlIEdVSSBUZXN0UnVubmVyIGNsYXNzDQoJfQ0KDQoJLyoqDQoJICogUmV0dXJucyB0aGUgbG9hZGVyIHRvIGJlIHVzZWQuDQoJICovDQoJcHVibGljIFRlc3RTdWl0ZUxvYWRlciBnZXRMb2FkZXIoKSB7DQoJCWlmICh1c2VSZWxvYWRpbmdUZXN0U3VpdGVMb2FkZXIoKSkNCgkJCXJldHVybiBuZXcgUmVsb2FkaW5nVGVzdFN1aXRlTG9hZGVyKCk7DQoJCXJldHVybiBuZXcgU3RhbmRhcmRUZXN0U3VpdGVMb2FkZXIoKTsNCgl9DQoNCglwcm90ZWN0ZWQgYm9vbGVhbiB1c2VSZWxvYWRpbmdUZXN0U3VpdGVMb2FkZXIoKSB7DQoJCXJldHVybiBnZXRQcmVmZXJlbmNlKCJsb2FkaW5nIikuZXF1YWxzKCJ0cnVlIikgJiYgIWluVkFKYXZhKCkgJiYgZkxvYWRpbmc7DQoJfQ0KDQoJcHJpdmF0ZSBzdGF0aWMgRmlsZSBnZXRQcmVmZXJlbmNlc0ZpbGUoKSB7DQoJIAlTdHJpbmcgaG9tZT0gU3lzdGVtLmdldFByb3BlcnR5KCJ1c2VyLmhvbWUiKTsNCiAJCXJldHVybiBuZXcgRmlsZShob21lLCAianVuaXQucHJvcGVydGllcyIpOw0KIAl9DQoNCiAJcHJpdmF0ZSBzdGF0aWMgdm9pZCByZWFkUHJlZmVyZW5jZXMoKSB7DQogCQlJbnB1dFN0cmVhbSBpcz0gbnVsbDsNCiAJCXRyeSB7DQogCQkJaXM9IG5ldyBGaWxlSW5wdXRTdHJlYW0oZ2V0UHJlZmVyZW5jZXNGaWxlKCkpOw0KIAkJCXNldFByZWZlcmVuY2VzKG5ldyBQcm9wZXJ0aWVzKGdldFByZWZlcmVuY2VzKCkpKTsNCgkJCWdldFByZWZlcmVuY2VzKCkubG9hZChpcyk7DQoJCX0gY2F0Y2ggKElPRXhjZXB0aW9uIGUpIHsNCgkJCXRyeSB7DQoJCQkJaWYgKGlzICE9IG51bGwpDQoJCQkJCWlzLmNsb3NlKCk7DQoJCQl9IGNhdGNoIChJT0V4Y2VwdGlvbiBlMSkgew0KCQkJfQ0KCQl9DQogCX0NCg0KIAlwdWJsaWMgc3RhdGljIFN0cmluZyBnZXRQcmVmZXJlbmNlKFN0cmluZyBrZXkpIHsNCiAJCXJldHVybiBnZXRQcmVmZXJlbmNlcygpLmdldFByb3BlcnR5KGtleSk7DQogCX0NCg0KIAlwdWJsaWMgc3RhdGljIGludCBnZXRQcmVmZXJlbmNlKFN0cmluZyBrZXksIGludCBkZmx0KSB7DQogCQlTdHJpbmcgdmFsdWU9IGdldFByZWZlcmVuY2Uoa2V5KTsNCiAJCWludCBpbnRWYWx1ZT0gZGZsdDsNCiAJCWlmICh2YWx1ZSA9PSBudWxsKQ0KIAkJCXJldHVybiBpbnRWYWx1ZTsNCiAJCXRyeSB7DQogCQkJaW50VmFsdWU9IEludGVnZXIucGFyc2VJbnQodmFsdWUpOw0KIAkgCX0gY2F0Y2ggKE51bWJlckZvcm1hdEV4Y2VwdGlvbiBuZSkgew0KIAkJfQ0KIAkJcmV0dXJuIGludFZhbHVlOw0KIAl9DQoNCiAJcHVibGljIHN0YXRpYyBib29sZWFuIGluVkFKYXZhKCkgew0KCQl0cnkgew0KCQkJQ2xhc3MuZm9yTmFtZSgiY29tLmlibS51dm0udG9vbHMuRGVidWdTdXBwb3J0Iik7DQoJCX0NCgkJY2F0Y2ggKEV4Y2VwdGlvbiBlKSB7DQoJCQlyZXR1cm4gZmFsc2U7DQoJCX0NCgkJcmV0dXJuIHRydWU7DQoJfQ0KDQoJLyoqDQoJICogUmV0dXJucyBhIGZpbHRlcmVkIHN0YWNrIHRyYWNlDQoJICovDQoJcHVibGljIHN0YXRpYyBTdHJpbmcgZ2V0RmlsdGVyZWRUcmFjZShUaHJvd2FibGUgdCkgew0KCQlTdHJpbmdXcml0ZXIgc3RyaW5nV3JpdGVyPSBuZXcgU3RyaW5nV3JpdGVyKCk7DQoJCVByaW50V3JpdGVyIHdyaXRlcj0gbmV3IFByaW50V3JpdGVyKHN0cmluZ1dyaXRlcik7DQoJCXQucHJpbnRTdGFja1RyYWNlKHdyaXRlcik7DQoJCVN0cmluZ0J1ZmZlciBidWZmZXI9IHN0cmluZ1dyaXRlci5nZXRCdWZmZXIoKTsNCgkJU3RyaW5nIHRyYWNlPSBidWZmZXIudG9TdHJpbmcoKTsNCgkJcmV0dXJuIEJhc2VUZXN0UnVubmVyLmdldEZpbHRlcmVkVHJhY2UodHJhY2UpOw0KCX0NCg0KCS8qKg0KCSAqIEZpbHRlcnMgc3RhY2sgZnJhbWVzIGZyb20gaW50ZXJuYWwgSlVuaXQgY2xhc3Nlcw0KCSAqLw0KCXB1YmxpYyBzdGF0aWMgU3RyaW5nIGdldEZpbHRlcmVkVHJhY2UoU3RyaW5nIHN0YWNrKSB7DQoJCWlmIChzaG93U3RhY2tSYXcoKSkNCgkJCXJldHVybiBzdGFjazsNCg0KCQlTdHJpbmdXcml0ZXIgc3c9IG5ldyBTdHJpbmdXcml0ZXIoKTsNCgkJUHJpbnRXcml0ZXIgcHc9IG5ldyBQcmludFdyaXRlcihzdyk7DQoJCVN0cmluZ1JlYWRlciBzcj0gbmV3IFN0cmluZ1JlYWRlcihzdGFjayk7DQoJCUJ1ZmZlcmVkUmVhZGVyIGJyPSBuZXcgQnVmZmVyZWRSZWFkZXIoc3IpOw0KDQoJCVN0cmluZyBsaW5lOw0KCQl0cnkgew0KCQkJd2hpbGUgKChsaW5lPSBici5yZWFkTGluZSgpKSAhPSBudWxsKSB7DQoJCQkJaWYgKCFmaWx0ZXJMaW5lKGxpbmUpKQ0KCQkJCQlwdy5wcmludGxuKGxpbmUpOw0KCQkJfQ0KCQl9IGNhdGNoIChFeGNlcHRpb24gSU9FeGNlcHRpb24pIHsNCgkJCXJldHVybiBzdGFjazsgLy8gcmV0dXJuIHRoZSBzdGFjayB1bmZpbHRlcmVkDQoJCX0NCgkJcmV0dXJuIHN3LnRvU3RyaW5nKCk7DQoJfQ0KDQoJcHJvdGVjdGVkIHN0YXRpYyBib29sZWFuIHNob3dTdGFja1JhdygpIHsNCgkJcmV0dXJuICFnZXRQcmVmZXJlbmNlKCJmaWx0ZXJzdGFjayIpLmVxdWFscygidHJ1ZSIpIHx8IGZnRmlsdGVyU3RhY2sgPT0gZmFsc2U7DQoJfQ0KDQoJc3RhdGljIGJvb2xlYW4gZmlsdGVyTGluZShTdHJpbmcgbGluZSkgew0KCQlTdHJpbmdbXSBwYXR0ZXJucz0gbmV3IFN0cmluZ1tdIHsNCgkJCSJqdW5pdC5mcmFtZXdvcmsuVGVzdENhc2UiLA0KCQkJImp1bml0LmZyYW1ld29yay5UZXN0UmVzdWx0IiwNCgkJCSJqdW5pdC5mcmFtZXdvcmsuVGVzdFN1aXRlIiwNCgkJCSJqdW5pdC5mcmFtZXdvcmsuQXNzZXJ0LiIsIC8vIGRvbid0IGZpbHRlciBBc3NlcnRpb25GYWlsdXJlDQoJCQkianVuaXQuc3dpbmd1aS5UZXN0UnVubmVyIiwNCgkJCSJqdW5pdC5hd3R1aS5UZXN0UnVubmVyIiwNCgkJCSJqdW5pdC50ZXh0dWkuVGVzdFJ1bm5lciIsDQoJCQkiamF2YS5sYW5nLnJlZmxlY3QuTWV0aG9kLmludm9rZSgiDQoJCX07DQoJCWZvciAoaW50IGk9IDA7IGkgPCBwYXR0ZXJucy5sZW5ndGg7IGkrKykgew0KCQkJaWYgKGxpbmUuaW5kZXhPZihwYXR0ZXJuc1tpXSkgPiAwKQ0KCQkJCXJldHVybiB0cnVlOw0KCQl9DQoJCXJldHVybiBmYWxzZTsNCgl9DQoNCiAJc3RhdGljIHsNCiAJCWZnTWF4TWVzc2FnZUxlbmd0aD0gZ2V0UHJlZmVyZW5jZSgibWF4bWVzc2FnZSIsIGZnTWF4TWVzc2FnZUxlbmd0aCk7DQogCX0NCg0KfVBLAwQKAAAAAADqeMcwpMUMfHsJAAB7CQAAKAAAAGp1bml0L3J1bm5lci9DbGFzc1BhdGhUZXN0Q29sbGVjdG9yLmphdmFwYWNrYWdlIGp1bml0LnJ1bm5lcjsNCg0KaW1wb3J0IGphdmEudXRpbC4qOw0KaW1wb3J0IGphdmEuaW8uKjsNCg0KLyoqDQogKiBBbiBpbXBsZW1lbnRhdGlvbiBvZiBhIFRlc3RDb2xsZWN0b3IgdGhhdCBjb25zdWx0cyB0aGUNCiAqIGNsYXNzIHBhdGguIEl0IGNvbnNpZGVycyBhbGwgY2xhc3NlcyBvbiB0aGUgY2xhc3MgcGF0aA0KICogZXhjbHVkaW5nIGNsYXNzZXMgaW4gSkFScy4gSXQgbGVhdmVzIGl0IHVwIHRvIHN1YmNsYXNzZXMNCiAqIHRvIGRlY2lkZSB3aGV0aGVyIGEgY2xhc3MgaXMgYSBydW5uYWJsZSBUZXN0Lg0KICoNCiAqIEBzZWUgVGVzdENvbGxlY3Rvcg0KICovDQpwdWJsaWMgYWJzdHJhY3QgY2xhc3MgQ2xhc3NQYXRoVGVzdENvbGxlY3RvciBpbXBsZW1lbnRzIFRlc3RDb2xsZWN0b3Igew0KCQ0KCXN0YXRpYyBmaW5hbCBpbnQgU1VGRklYX0xFTkdUSD0gIi5jbGFzcyIubGVuZ3RoKCk7DQoJDQoJcHVibGljIENsYXNzUGF0aFRlc3RDb2xsZWN0b3IoKSB7DQoJfQ0KCQ0KCXB1YmxpYyBFbnVtZXJhdGlvbiBjb2xsZWN0VGVzdHMoKSB7DQoJCVN0cmluZyBjbGFzc1BhdGg9IFN5c3RlbS5nZXRQcm9wZXJ0eSgiamF2YS5jbGFzcy5wYXRoIik7DQoJCUhhc2h0YWJsZSByZXN1bHQgPSBjb2xsZWN0RmlsZXNJblBhdGgoY2xhc3NQYXRoKTsNCgkJcmV0dXJuIHJlc3VsdC5lbGVtZW50cygpOw0KCX0NCg0KCXB1YmxpYyBIYXNodGFibGUgY29sbGVjdEZpbGVzSW5QYXRoKFN0cmluZyBjbGFzc1BhdGgpIHsNCgkJSGFzaHRhYmxlIHJlc3VsdD0gY29sbGVjdEZpbGVzSW5Sb290cyhzcGxpdENsYXNzUGF0aChjbGFzc1BhdGgpKTsNCgkJcmV0dXJuIHJlc3VsdDsNCgl9DQoJDQoJSGFzaHRhYmxlIGNvbGxlY3RGaWxlc0luUm9vdHMoVmVjdG9yIHJvb3RzKSB7DQoJCUhhc2h0YWJsZSByZXN1bHQ9IG5ldyBIYXNodGFibGUoMTAwKTsNCgkJRW51bWVyYXRpb24gZT0gcm9vdHMuZWxlbWVudHMoKTsNCgkJd2hpbGUgKGUuaGFzTW9yZUVsZW1lbnRzKCkpIA0KCQkJZ2F0aGVyRmlsZXMobmV3IEZpbGUoKFN0cmluZyllLm5leHRFbGVtZW50KCkpLCAiIiwgcmVzdWx0KTsNCgkJcmV0dXJuIHJlc3VsdDsNCgl9DQoNCgl2b2lkIGdhdGhlckZpbGVzKEZpbGUgY2xhc3NSb290LCBTdHJpbmcgY2xhc3NGaWxlTmFtZSwgSGFzaHRhYmxlIHJlc3VsdCkgew0KCQlGaWxlIHRoaXNSb290PSBuZXcgRmlsZShjbGFzc1Jvb3QsIGNsYXNzRmlsZU5hbWUpOw0KCQlpZiAodGhpc1Jvb3QuaXNGaWxlKCkpIHsNCgkJCWlmIChpc1Rlc3RDbGFzcyhjbGFzc0ZpbGVOYW1lKSkgew0KCQkJCVN0cmluZyBjbGFzc05hbWU9IGNsYXNzTmFtZUZyb21GaWxlKGNsYXNzRmlsZU5hbWUpOw0KCQkJCXJlc3VsdC5wdXQoY2xhc3NOYW1lLCBjbGFzc05hbWUpOw0KCQkJfQ0KCQkJcmV0dXJuOw0KCQl9CQkNCgkJU3RyaW5nW10gY29udGVudHM9IHRoaXNSb290Lmxpc3QoKTsNCgkJaWYgKGNvbnRlbnRzICE9IG51bGwpIHsgDQoJCQlmb3IgKGludCBpPSAwOyBpIDwgY29udGVudHMubGVuZ3RoOyBpKyspIA0KCQkJCWdhdGhlckZpbGVzKGNsYXNzUm9vdCwgY2xhc3NGaWxlTmFtZStGaWxlLnNlcGFyYXRvckNoYXIrY29udGVudHNbaV0sIHJlc3VsdCk7CQkNCgkJfQ0KCX0NCgkNCglWZWN0b3Igc3BsaXRDbGFzc1BhdGgoU3RyaW5nIGNsYXNzUGF0aCkgew0KCQlWZWN0b3IgcmVzdWx0PSBuZXcgVmVjdG9yKCk7DQoJCVN0cmluZyBzZXBhcmF0b3I9IFN5c3RlbS5nZXRQcm9wZXJ0eSgicGF0aC5zZXBhcmF0b3IiKTsNCgkJU3RyaW5nVG9rZW5pemVyIHRva2VuaXplcj0gbmV3IFN0cmluZ1Rva2VuaXplcihjbGFzc1BhdGgsIHNlcGFyYXRvcik7DQoJCXdoaWxlICh0b2tlbml6ZXIuaGFzTW9yZVRva2VucygpKSANCgkJCXJlc3VsdC5hZGRFbGVtZW50KHRva2VuaXplci5uZXh0VG9rZW4oKSk7DQoJCXJldHVybiByZXN1bHQ7DQoJfQ0KCQ0KCXByb3RlY3RlZCBib29sZWFuIGlzVGVzdENsYXNzKFN0cmluZyBjbGFzc0ZpbGVOYW1lKSB7DQoJCXJldHVybiANCgkJCWNsYXNzRmlsZU5hbWUuZW5kc1dpdGgoIi5jbGFzcyIpICYmIA0KCQkJY2xhc3NGaWxlTmFtZS5pbmRleE9mKCckJykgPCAwICYmDQoJCQljbGFzc0ZpbGVOYW1lLmluZGV4T2YoIlRlc3QiKSA+IDA7DQoJfQ0KCQ0KCXByb3RlY3RlZCBTdHJpbmcgY2xhc3NOYW1lRnJvbUZpbGUoU3RyaW5nIGNsYXNzRmlsZU5hbWUpIHsNCgkJLy8gY29udmVydCAvYS9iLmNsYXNzIHRvIGEuYg0KCQlTdHJpbmcgcz0gY2xhc3NGaWxlTmFtZS5zdWJzdHJpbmcoMCwgY2xhc3NGaWxlTmFtZS5sZW5ndGgoKS1TVUZGSVhfTEVOR1RIKTsNCgkJU3RyaW5nIHMyPSBzLnJlcGxhY2UoRmlsZS5zZXBhcmF0b3JDaGFyLCAnLicpOw0KCQlpZiAoczIuc3RhcnRzV2l0aCgiLiIpKQ0KCQkJcmV0dXJuIHMyLnN1YnN0cmluZygxKTsNCgkJcmV0dXJuIHMyOw0KCX0JDQp9DQpQSwMECgAAAAAA6njHMDd+oeolAQAAJQEAACEAAABqdW5pdC9ydW5uZXIvVGVzdFN1aXRlTG9hZGVyLmphdmFwYWNrYWdlIGp1bml0LnJ1bm5lcjsNCg0KLyoqDQogKiBBbiBpbnRlcmZhY2UgdG8gZGVmaW5lIGhvdyBhIHRlc3Qgc3VpdGUgc2hvdWxkIGJlIGxvYWRlZC4NCiAqLw0KcHVibGljIGludGVyZmFjZSBUZXN0U3VpdGVMb2FkZXIgew0KCWFic3RyYWN0IHB1YmxpYyBDbGFzcyBsb2FkKFN0cmluZyBzdWl0ZUNsYXNzTmFtZSkgdGhyb3dzIENsYXNzTm90Rm91bmRFeGNlcHRpb247DQoJYWJzdHJhY3QgcHVibGljIENsYXNzIHJlbG9hZChDbGFzcyBhQ2xhc3MpIHRocm93cyBDbGFzc05vdEZvdW5kRXhjZXB0aW9uOw0KfVBLAwQKAAAAAADqeMcwAlXo0vMBAADzAQAAJQAAAGp1bml0L3J1bm5lci9TaW1wbGVUZXN0Q29sbGVjdG9yLmphdmFwYWNrYWdlIGp1bml0LnJ1bm5lcjsNCg0KLyoqDQogKiBBbiBpbXBsZW1lbnRhdGlvbiBvZiBhIFRlc3RDb2xsZWN0b3IgdGhhdCBjb25zaWRlcnMNCiAqIGEgY2xhc3MgdG8gYmUgYSB0ZXN0IGNsYXNzIHdoZW4gaXQgY29udGFpbnMgdGhlDQogKiBwYXR0ZXJuICJUZXN0IiBpbiBpdHMgbmFtZQ0KICogQHNlZSBUZXN0Q29sbGVjdG9yDQogKi8NCnB1YmxpYyBjbGFzcyBTaW1wbGVUZXN0Q29sbGVjdG9yIGV4dGVuZHMgQ2xhc3NQYXRoVGVzdENvbGxlY3RvciB7DQoJDQoJcHVibGljIFNpbXBsZVRlc3RDb2xsZWN0b3IoKSB7DQoJfQ0KCQ0KCXByb3RlY3RlZCBib29sZWFuIGlzVGVzdENsYXNzKFN0cmluZyBjbGFzc0ZpbGVOYW1lKSB7DQoJCXJldHVybiANCgkJCWNsYXNzRmlsZU5hbWUuZW5kc1dpdGgoIi5jbGFzcyIpICYmIA0KCQkJY2xhc3NGaWxlTmFtZS5pbmRleE9mKCckJykgPCAwICYmDQoJCQljbGFzc0ZpbGVOYW1lLmluZGV4T2YoIlRlc3QiKSA+IDA7DQoJfQ0KfQ0KUEsDBAoAAAAAAOp4xzCzfoC74AIAAOACAAAhAAAAanVuaXQvcnVubmVyL1Rlc3RSdW5MaXN0ZW5lci5qYXZhcGFja2FnZSBqdW5pdC5ydW5uZXI7DQovKioNCiAqIEEgbGlzdGVuZXIgaW50ZXJmYWNlIGZvciBvYnNlcnZpbmcgdGhlDQogKiBleGVjdXRpb24gb2YgYSB0ZXN0IHJ1bi4gVW5saWtlIFRlc3RMaXN0ZW5lciwNCiAqIHRoaXMgaW50ZXJmYWNlIHVzaW5nIG9ubHkgcHJpbWl0aXZlIG9iamVjdHMsDQogKiBtYWtpbmcgaXQgc3VpdGFibGUgZm9yIHJlbW90ZSB0ZXN0IGV4ZWN1dGlvbi4NCiAqLw0KIHB1YmxpYyBpbnRlcmZhY2UgVGVzdFJ1bkxpc3RlbmVyIHsNCiAgICAgLyogdGVzdCBzdGF0dXMgY29uc3RhbnRzKi8NCiAgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgU1RBVFVTX0VSUk9SPSAxOw0KICAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBTVEFUVVNfRkFJTFVSRT0gMjsNCg0KICAgICBwdWJsaWMgdm9pZCB0ZXN0UnVuU3RhcnRlZChTdHJpbmcgdGVzdFN1aXRlTmFtZSwgaW50IHRlc3RDb3VudCk7DQogICAgIHB1YmxpYyB2b2lkIHRlc3RSdW5FbmRlZChsb25nIGVsYXBzZWRUaW1lKTsNCiAgICAgcHVibGljIHZvaWQgdGVzdFJ1blN0b3BwZWQobG9uZyBlbGFwc2VkVGltZSk7DQogICAgIHB1YmxpYyB2b2lkIHRlc3RTdGFydGVkKFN0cmluZyB0ZXN0TmFtZSk7DQogICAgIHB1YmxpYyB2b2lkIHRlc3RFbmRlZChTdHJpbmcgdGVzdE5hbWUpOw0KICAgICBwdWJsaWMgdm9pZCB0ZXN0RmFpbGVkKGludCBzdGF0dXMsIFN0cmluZyB0ZXN0TmFtZSwgU3RyaW5nIHRyYWNlKTsNCn0NClBLAwQKAAAAAADqeMcwyAWgKtsAAADbAAAAGQAAAGp1bml0L3J1bm5lci9WZXJzaW9uLmphdmFwYWNrYWdlIGp1bml0LnJ1bm5lcjsNCg0KLyoqDQogKiBUaGlzIGNsYXNzIGRlZmluZXMgdGhlIGN1cnJlbnQgdmVyc2lvbiBvZiBKVW5pdA0KICovDQpwdWJsaWMgY2xhc3MgVmVyc2lvbiB7DQoJcHJpdmF0ZSBWZXJzaW9uKCkgew0KCQkvLyBkb24ndCBpbnN0YW50aWF0ZQ0KCX0NCg0KCXB1YmxpYyBzdGF0aWMgU3RyaW5nIGlkKCkgew0KCQlyZXR1cm4gIjMuOC4xIjsNCgl9DQp9DQpQSwMECgAAAAAASXvHMEn5x2P0AAAA9AAAAB8AAABqdW5pdC9ydW5uZXIvVGVzdENvbGxlY3Rvci5qYXZhcGFja2FnZSBqdW5pdC5ydW5uZXI7DQoNCmltcG9ydCBqYXZhLnV0aWwuKjsNCg0KDQovKioNCiAqIENvbGxlY3RzIFRlc3QgY2xhc3MgbmFtZXMuIA0KICovDQpwdWJsaWMgaW50ZXJmYWNlIFRlc3RDb2xsZWN0b3Igew0KCS8qKg0KCSAqIFJldHVybnMgYW4gZW51bWVyYXRpb24gb2YgU3RyaW5ncyB3aXRoIHF1YWxpZmllZCBjbGFzcyBuYW1lcw0KCSAqLw0KCXB1YmxpYyBFbnVtZXJhdGlvbiBjb2xsZWN0VGVzdHMoKTsNCn0NClBLAwQKAAAAAAAre8cwe5gkEQgEAAAIBAAAGAAAAGp1bml0L3J1bm5lci9Tb3J0ZXIuamF2YXBhY2thZ2UganVuaXQucnVubmVyOw0KDQppbXBvcnQgamF2YS51dGlsLio7DQoNCi8qKg0KICogQSBjdXN0b20gcXVpY2sgc29ydCB3aXRoIHN1cHBvcnQgdG8gY3VzdG9taXplIHRoZSBzd2FwIGJlaGF2aW91ci4NCiAqIE5PVElDRTogV2UgY2FuJ3QgdXNlIHRoZSB0aGUgc29ydGluZyBzdXBwb3J0IGZyb20gdGhlIEpESyAxLjIgY29sbGVjdGlvbg0KICogY2xhc3NlcyBiZWNhdXNlIG9mIHRoZSBKREsgMS4xLjcgY29tcGF0aWJpbGl0eS4NCiAqLw0KcHVibGljIGNsYXNzIFNvcnRlciB7DQoJcHVibGljIHN0YXRpYyBpbnRlcmZhY2UgU3dhcHBlciB7DQoJCXB1YmxpYyB2b2lkIHN3YXAoVmVjdG9yIHZhbHVlcywgaW50IGxlZnQsIGludCByaWdodCk7DQoJfQ0KCQkNCglwdWJsaWMgc3RhdGljIHZvaWQgc29ydFN0cmluZ3MoVmVjdG9yIHZhbHVlcyAsIGludCBsZWZ0LCBpbnQgcmlnaHQsIFN3YXBwZXIgc3dhcHBlcikgeyANCgkJaW50IG9sZWZ0PSBsZWZ0Ow0KCQlpbnQgb3JpZ2h0PSByaWdodDsNCgkJU3RyaW5nIG1pZD0gKFN0cmluZyl2YWx1ZXMuZWxlbWVudEF0KChsZWZ0ICsgcmlnaHQpIC8gMik7IA0KCQlkbyB7IA0KCQkJd2hpbGUgKCgoU3RyaW5nKSh2YWx1ZXMuZWxlbWVudEF0KGxlZnQpKSkuY29tcGFyZVRvKG1pZCkgPCAwKSAgDQoJCQkJbGVmdCsrOyANCgkJCXdoaWxlIChtaWQuY29tcGFyZVRvKChTdHJpbmcpKHZhbHVlcy5lbGVtZW50QXQocmlnaHQpKSkgPCAwKSAgDQoJCQkJcmlnaHQtLTsgDQoJCQlpZiAobGVmdCA8PSByaWdodCkgew0KCQkJCXN3YXBwZXIuc3dhcCh2YWx1ZXMsIGxlZnQsIHJpZ2h0KTsgDQoJCQkJbGVmdCsrOyANCgkJCQlyaWdodC0tOyANCgkJCX0gDQoJCX0gd2hpbGUgKGxlZnQgPD0gcmlnaHQpOw0KCQkNCgkJaWYgKG9sZWZ0IDwgcmlnaHQpIA0KCQkJc29ydFN0cmluZ3ModmFsdWVzLCBvbGVmdCwgcmlnaHQsIHN3YXBwZXIpOyANCgkJaWYgKGxlZnQgPCBvcmlnaHQpIA0KCQkJIHNvcnRTdHJpbmdzKHZhbHVlcywgbGVmdCwgb3JpZ2h0LCBzd2FwcGVyKTsgDQoJfQ0KfVBLAwQKAAAAAAAle8cwY9736L4GAAC+BgAAJgAAAGp1bml0L3J1bm5lci9Mb2FkaW5nVGVzdENvbGxlY3Rvci5qYXZhcGFja2FnZSBqdW5pdC5ydW5uZXI7DQoNCmltcG9ydCBqYXZhLmxhbmcucmVmbGVjdC4qOw0KaW1wb3J0IGp1bml0LmZyYW1ld29yay4qOw0KDQovKioNCiAqIEFuIGltcGxlbWVudGF0aW9uIG9mIGEgVGVzdENvbGxlY3RvciB0aGF0IGxvYWRzDQogKiBhbGwgY2xhc3NlcyBvbiB0aGUgY2xhc3MgcGF0aCBhbmQgdGVzdHMgd2hldGhlcg0KICogaXQgaXMgYXNzaWduYWJsZSBmcm9tIFRlc3Qgb3IgcHJvdmlkZXMgYSBzdGF0aWMgc3VpdGUgbWV0aG9kLg0KICogQHNlZSBUZXN0Q29sbGVjdG9yDQogKi8NCnB1YmxpYyBjbGFzcyBMb2FkaW5nVGVzdENvbGxlY3RvciBleHRlbmRzIENsYXNzUGF0aFRlc3RDb2xsZWN0b3Igew0KCQ0KCVRlc3RDYXNlQ2xhc3NMb2FkZXIgZkxvYWRlcjsNCgkNCglwdWJsaWMgTG9hZGluZ1Rlc3RDb2xsZWN0b3IoKSB7DQoJCWZMb2FkZXI9IG5ldyBUZXN0Q2FzZUNsYXNzTG9hZGVyKCk7DQoJfQ0KCQ0KCXByb3RlY3RlZCBib29sZWFuIGlzVGVzdENsYXNzKFN0cmluZyBjbGFzc0ZpbGVOYW1lKSB7CQ0KCQl0cnkgew0KCQkJaWYgKGNsYXNzRmlsZU5hbWUuZW5kc1dpdGgoIi5jbGFzcyIpKSB7DQoJCQkJQ2xhc3MgdGVzdENsYXNzPSBjbGFzc0Zyb21GaWxlKGNsYXNzRmlsZU5hbWUpOw0KCQkJCXJldHVybiAodGVzdENsYXNzICE9IG51bGwpICYmIGlzVGVzdENsYXNzKHRlc3RDbGFzcyk7DQoJCQl9DQoJCX0gDQoJCWNhdGNoIChDbGFzc05vdEZvdW5kRXhjZXB0aW9uIGV4cGVjdGVkKSB7DQoJCX0NCgkJY2F0Y2ggKE5vQ2xhc3NEZWZGb3VuZEVycm9yIG5vdEZhdGFsKSB7DQoJCX0gDQoJCXJldHVybiBmYWxzZTsNCgl9DQoJDQoJQ2xhc3MgY2xhc3NGcm9tRmlsZShTdHJpbmcgY2xhc3NGaWxlTmFtZSkgdGhyb3dzIENsYXNzTm90Rm91bmRFeGNlcHRpb24gew0KCQlTdHJpbmcgY2xhc3NOYW1lPSBjbGFzc05hbWVGcm9tRmlsZShjbGFzc0ZpbGVOYW1lKTsNCgkJaWYgKCFmTG9hZGVyLmlzRXhjbHVkZWQoY2xhc3NOYW1lKSkNCgkJCXJldHVybiBmTG9hZGVyLmxvYWRDbGFzcyhjbGFzc05hbWUsIGZhbHNlKTsNCgkJcmV0dXJuIG51bGw7DQoJfQ0KCQ0KCWJvb2xlYW4gaXNUZXN0Q2xhc3MoQ2xhc3MgdGVzdENsYXNzKSB7DQoJCWlmIChoYXNTdWl0ZU1ldGhvZCh0ZXN0Q2xhc3MpKQ0KCQkJcmV0dXJuIHRydWU7DQoJCWlmIChUZXN0LmNsYXNzLmlzQXNzaWduYWJsZUZyb20odGVzdENsYXNzKSAmJg0KCQkJTW9kaWZpZXIuaXNQdWJsaWModGVzdENsYXNzLmdldE1vZGlmaWVycygpKSAmJg0KCQkJaGFzUHVibGljQ29uc3RydWN0b3IodGVzdENsYXNzKSkgDQoJCQlyZXR1cm4gdHJ1ZTsNCgkJcmV0dXJuIGZhbHNlOw0KCX0NCgkNCglib29sZWFuIGhhc1N1aXRlTWV0aG9kKENsYXNzIHRlc3RDbGFzcykgew0KCQl0cnkgew0KCQkJdGVzdENsYXNzLmdldE1ldGhvZChCYXNlVGVzdFJ1bm5lci5TVUlURV9NRVRIT0ROQU1FLCBuZXcgQ2xhc3NbMF0pOw0KCSAJfSBjYXRjaChFeGNlcHRpb24gZSkgew0KCSAJCXJldHVybiBmYWxzZTsNCgkJfQ0KCQlyZXR1cm4gdHJ1ZTsNCgl9DQoJDQoJYm9vbGVhbiBoYXNQdWJsaWNDb25zdHJ1Y3RvcihDbGFzcyB0ZXN0Q2xhc3MpIHsNCgkJdHJ5IHsNCgkJCVRlc3RTdWl0ZS5nZXRUZXN0Q29uc3RydWN0b3IodGVzdENsYXNzKTsNCgkJfSBjYXRjaChOb1N1Y2hNZXRob2RFeGNlcHRpb24gZSkgew0KCQkJcmV0dXJuIGZhbHNlOw0KCQl9DQoJCXJldHVybiB0cnVlOw0KCX0NCn0NClBLAwQKAAAAAADqeMcwChlcvWgWAABoFgAAJQAAAGp1bml0L3J1bm5lci9UZXN0Q2FzZUNsYXNzTG9hZGVyLmphdmFwYWNrYWdlIGp1bml0LnJ1bm5lcjsNCg0KaW1wb3J0IGphdmEudXRpbC4qOw0KaW1wb3J0IGphdmEuaW8uKjsNCmltcG9ydCBqYXZhLm5ldC5VUkw7DQppbXBvcnQgamF2YS51dGlsLnppcC4qOw0KDQovKioNCiAqIEEgY3VzdG9tIGNsYXNzIGxvYWRlciB3aGljaCBlbmFibGVzIHRoZSByZWxvYWRpbmcNCiAqIG9mIGNsYXNzZXMgZm9yIGVhY2ggdGVzdCBydW4uIFRoZSBjbGFzcyBsb2FkZXINCiAqIGNhbiBiZSBjb25maWd1cmVkIHdpdGggYSBsaXN0IG9mIHBhY2thZ2UgcGF0aHMgdGhhdA0KICogc2hvdWxkIGJlIGV4Y2x1ZGVkIGZyb20gbG9hZGluZy4gVGhlIGxvYWRpbmcNCiAqIG9mIHRoZXNlIHBhY2thZ2VzIGlzIGRlbGVnYXRlZCB0byB0aGUgc3lzdGVtIGNsYXNzDQogKiBsb2FkZXIuIFRoZXkgd2lsbCBiZSBzaGFyZWQgYWNyb3NzIHRlc3QgcnVucy4NCiAqIDxwPg0KICogVGhlIGxpc3Qgb2YgZXhjbHVkZWQgcGFja2FnZSBwYXRocyBpcyBzcGVjaWZpZWQgaW4NCiAqIGEgcHJvcGVydGllcyBmaWxlICJleGNsdWRlZC5wcm9wZXJ0aWVzIiB0aGF0IGlzIGxvY2F0ZWQgaW4gDQogKiB0aGUgc2FtZSBwbGFjZSBhcyB0aGUgVGVzdENhc2VDbGFzc0xvYWRlciBjbGFzcy4NCiAqIDxwPg0KICogPGI+S25vd24gbGltaXRhdGlvbjo8L2I+IHRoZSBUZXN0Q2FzZUNsYXNzTG9hZGVyIGNhbm5vdCBsb2FkIGNsYXNzZXMNCiAqIGZyb20gamFyIGZpbGVzLg0KICovDQoNCg0KcHVibGljIGNsYXNzIFRlc3RDYXNlQ2xhc3NMb2FkZXIgZXh0ZW5kcyBDbGFzc0xvYWRlciB7DQoJLyoqIHNjYW5uZWQgY2xhc3MgcGF0aCAqLw0KCXByaXZhdGUgVmVjdG9yIGZQYXRoSXRlbXM7DQoJLyoqIGRlZmF1bHQgZXhjbHVkZWQgcGF0aHMgKi8NCglwcml2YXRlIFN0cmluZ1tdIGRlZmF1bHRFeGNsdXNpb25zPSB7DQoJCSJqdW5pdC5mcmFtZXdvcmsuIiwgDQoJCSJqdW5pdC5leHRlbnNpb25zLiIsIA0KCQkianVuaXQucnVubmVyLiINCgl9Ow0KCS8qKiBuYW1lIG9mIGV4Y2x1ZGVkIHByb3BlcnRpZXMgZmlsZSAqLw0KCXN0YXRpYyBmaW5hbCBTdHJpbmcgRVhDTFVERURfRklMRT0gImV4Y2x1ZGVkLnByb3BlcnRpZXMiOw0KCS8qKiBleGNsdWRlZCBwYXRocyAqLw0KCXByaXZhdGUgVmVjdG9yIGZFeGNsdWRlZDsNCgkgDQoJLyoqDQoJICogQ29uc3RydWN0cyBhIFRlc3RDYXNlTG9hZGVyLiBJdCBzY2FucyB0aGUgY2xhc3MgcGF0aA0KCSAqIGFuZCB0aGUgZXhjbHVkZWQgcGFja2FnZSBwYXRocw0KCSAqLw0KCXB1YmxpYyBUZXN0Q2FzZUNsYXNzTG9hZGVyKCkgew0KCQl0aGlzKFN5c3RlbS5nZXRQcm9wZXJ0eSgiamF2YS5jbGFzcy5wYXRoIikpOw0KCX0NCgkNCgkvKioNCgkgKiBDb25zdHJ1Y3RzIGEgVGVzdENhc2VMb2FkZXIuIEl0IHNjYW5zIHRoZSBjbGFzcyBwYXRoDQoJICogYW5kIHRoZSBleGNsdWRlZCBwYWNrYWdlIHBhdGhzDQoJICovDQoJcHVibGljIFRlc3RDYXNlQ2xhc3NMb2FkZXIoU3RyaW5nIGNsYXNzUGF0aCkgew0KCQlzY2FuUGF0aChjbGFzc1BhdGgpOw0KCQlyZWFkRXhjbHVkZWRQYWNrYWdlcygpOw0KCX0NCg0KCXByaXZhdGUgdm9pZCBzY2FuUGF0aChTdHJpbmcgY2xhc3NQYXRoKSB7DQoJCVN0cmluZyBzZXBhcmF0b3I9IFN5c3RlbS5nZXRQcm9wZXJ0eSgicGF0aC5zZXBhcmF0b3IiKTsNCgkJZlBhdGhJdGVtcz0gbmV3IFZlY3RvcigxMCk7DQoJCVN0cmluZ1Rva2VuaXplciBzdD0gbmV3IFN0cmluZ1Rva2VuaXplcihjbGFzc1BhdGgsIHNlcGFyYXRvcik7DQoJCXdoaWxlIChzdC5oYXNNb3JlVG9rZW5zKCkpIHsNCgkJCWZQYXRoSXRlbXMuYWRkRWxlbWVudChzdC5uZXh0VG9rZW4oKSk7DQoJCX0NCgl9DQoJDQoJcHVibGljIFVSTCBnZXRSZXNvdXJjZShTdHJpbmcgbmFtZSkgew0KCQlyZXR1cm4gQ2xhc3NMb2FkZXIuZ2V0U3lzdGVtUmVzb3VyY2UobmFtZSk7DQoJfQ0KCQ0KCXB1YmxpYyBJbnB1dFN0cmVhbSBnZXRSZXNvdXJjZUFzU3RyZWFtKFN0cmluZyBuYW1lKSB7DQoJCXJldHVybiBDbGFzc0xvYWRlci5nZXRTeXN0ZW1SZXNvdXJjZUFzU3RyZWFtKG5hbWUpOw0KCX0gDQoJDQoJcHVibGljIGJvb2xlYW4gaXNFeGNsdWRlZChTdHJpbmcgbmFtZSkgew0KCQlmb3IgKGludCBpPSAwOyBpIDwgZkV4Y2x1ZGVkLnNpemUoKTsgaSsrKSB7DQoJCQlpZiAobmFtZS5zdGFydHNXaXRoKChTdHJpbmcpIGZFeGNsdWRlZC5lbGVtZW50QXQoaSkpKSB7DQoJCQkJcmV0dXJuIHRydWU7DQoJCQl9DQoJCX0NCgkJcmV0dXJuIGZhbHNlOwkNCgl9DQoJDQoJcHVibGljIHN5bmNocm9uaXplZCBDbGFzcyBsb2FkQ2xhc3MoU3RyaW5nIG5hbWUsIGJvb2xlYW4gcmVzb2x2ZSkNCgkJdGhyb3dzIENsYXNzTm90Rm91bmRFeGNlcHRpb24gew0KCQkJDQoJCUNsYXNzIGM9IGZpbmRMb2FkZWRDbGFzcyhuYW1lKTsNCgkJaWYgKGMgIT0gbnVsbCkNCgkJCXJldHVybiBjOw0KCQkvLw0KCQkvLyBEZWxlZ2F0ZSB0aGUgbG9hZGluZyBvZiBleGNsdWRlZCBjbGFzc2VzIHRvIHRoZQ0KCQkvLyBzdGFuZGFyZCBjbGFzcyBsb2FkZXIuDQoJCS8vDQoJCWlmIChpc0V4Y2x1ZGVkKG5hbWUpKSB7DQoJCQl0cnkgew0KCQkJCWM9IGZpbmRTeXN0ZW1DbGFzcyhuYW1lKTsNCgkJCQlyZXR1cm4gYzsNCgkJCX0gY2F0Y2ggKENsYXNzTm90Rm91bmRFeGNlcHRpb24gZSkgew0KCQkJCS8vIGtlZXAgc2VhcmNoaW5nDQoJCQl9DQoJCX0NCgkJaWYgKGMgPT0gbnVsbCkgew0KCQkJYnl0ZVtdIGRhdGE9IGxvb2t1cENsYXNzRGF0YShuYW1lKTsNCgkJCWlmIChkYXRhID09IG51bGwpDQoJCQkJdGhyb3cgbmV3IENsYXNzTm90Rm91bmRFeGNlcHRpb24oKTsNCgkJCWM9IGRlZmluZUNsYXNzKG5hbWUsIGRhdGEsIDAsIGRhdGEubGVuZ3RoKTsNCgkJfQ0KCQlpZiAocmVzb2x2ZSkgDQoJCQlyZXNvbHZlQ2xhc3MoYyk7DQoJCXJldHVybiBjOw0KCX0NCgkNCglwcml2YXRlIGJ5dGVbXSBsb29rdXBDbGFzc0RhdGEoU3RyaW5nIGNsYXNzTmFtZSkgdGhyb3dzIENsYXNzTm90Rm91bmRFeGNlcHRpb24gew0KCQlieXRlW10gZGF0YT0gbnVsbDsNCgkJZm9yIChpbnQgaT0gMDsgaSA8IGZQYXRoSXRlbXMuc2l6ZSgpOyBpKyspIHsNCgkJCVN0cmluZyBwYXRoPSAoU3RyaW5nKSBmUGF0aEl0ZW1zLmVsZW1lbnRBdChpKTsNCgkJCVN0cmluZyBmaWxlTmFtZT0gY2xhc3NOYW1lLnJlcGxhY2UoJy4nLCAnLycpKyIuY2xhc3MiOw0KCQkJaWYgKGlzSmFyKHBhdGgpKSB7DQoJCQkJZGF0YT0gbG9hZEphckRhdGEocGF0aCwgZmlsZU5hbWUpOw0KCQkJfSBlbHNlIHsNCgkJCQlkYXRhPSBsb2FkRmlsZURhdGEocGF0aCwgZmlsZU5hbWUpOw0KCQkJfQ0KCQkJaWYgKGRhdGEgIT0gbnVsbCkNCgkJCQlyZXR1cm4gZGF0YTsNCgkJfQ0KCQl0aHJvdyBuZXcgQ2xhc3NOb3RGb3VuZEV4Y2VwdGlvbihjbGFzc05hbWUpOw0KCX0NCgkJDQoJYm9vbGVhbiBpc0phcihTdHJpbmcgcGF0aEVudHJ5KSB7DQoJCXJldHVybiBwYXRoRW50cnkuZW5kc1dpdGgoIi5qYXIiKSB8fCBwYXRoRW50cnkuZW5kc1dpdGgoIi56aXAiKTsNCgl9DQoNCglwcml2YXRlIGJ5dGVbXSBsb2FkRmlsZURhdGEoU3RyaW5nIHBhdGgsIFN0cmluZyBmaWxlTmFtZSkgew0KCQlGaWxlIGZpbGU9IG5ldyBGaWxlKHBhdGgsIGZpbGVOYW1lKTsNCgkJaWYgKGZpbGUuZXhpc3RzKCkpIHsgDQoJCQlyZXR1cm4gZ2V0Q2xhc3NEYXRhKGZpbGUpOw0KCQl9DQoJCXJldHVybiBudWxsOw0KCX0NCgkNCglwcml2YXRlIGJ5dGVbXSBnZXRDbGFzc0RhdGEoRmlsZSBmKSB7DQoJCXRyeSB7DQoJCQlGaWxlSW5wdXRTdHJlYW0gc3RyZWFtPSBuZXcgRmlsZUlucHV0U3RyZWFtKGYpOw0KCQkJQnl0ZUFycmF5T3V0cHV0U3RyZWFtIG91dD0gbmV3IEJ5dGVBcnJheU91dHB1dFN0cmVhbSgxMDAwKTsNCgkJCWJ5dGVbXSBiPSBuZXcgYnl0ZVsxMDAwXTsNCgkJCWludCBuOw0KCQkJd2hpbGUgKChuPSBzdHJlYW0ucmVhZChiKSkgIT0gLTEpIA0KCQkJCW91dC53cml0ZShiLCAwLCBuKTsNCgkJCXN0cmVhbS5jbG9zZSgpOw0KCQkJb3V0LmNsb3NlKCk7DQoJCQlyZXR1cm4gb3V0LnRvQnl0ZUFycmF5KCk7DQoNCgkJfSBjYXRjaCAoSU9FeGNlcHRpb24gZSkgew0KCQl9DQoJCXJldHVybiBudWxsOw0KCX0NCg0KCXByaXZhdGUgYnl0ZVtdIGxvYWRKYXJEYXRhKFN0cmluZyBwYXRoLCBTdHJpbmcgZmlsZU5hbWUpIHsNCgkJWmlwRmlsZSB6aXBGaWxlPSBudWxsOw0KCQlJbnB1dFN0cmVhbSBzdHJlYW09IG51bGw7DQoJCUZpbGUgYXJjaGl2ZT0gbmV3IEZpbGUocGF0aCk7DQoJCWlmICghYXJjaGl2ZS5leGlzdHMoKSkNCgkJCXJldHVybiBudWxsOw0KCQl0cnkgew0KCQkJemlwRmlsZT0gbmV3IFppcEZpbGUoYXJjaGl2ZSk7DQoJCX0gY2F0Y2goSU9FeGNlcHRpb24gaW8pIHsNCgkJCXJldHVybiBudWxsOw0KCQl9DQoJCVppcEVudHJ5IGVudHJ5PSB6aXBGaWxlLmdldEVudHJ5KGZpbGVOYW1lKTsNCgkJaWYgKGVudHJ5ID09IG51bGwpDQoJCQlyZXR1cm4gbnVsbDsNCgkJaW50IHNpemU9IChpbnQpIGVudHJ5LmdldFNpemUoKTsNCgkJdHJ5IHsNCgkJCXN0cmVhbT0gemlwRmlsZS5nZXRJbnB1dFN0cmVhbShlbnRyeSk7DQoJCQlieXRlW10gZGF0YT0gbmV3IGJ5dGVbc2l6ZV07DQoJCQlpbnQgcG9zPSAwOw0KCQkJd2hpbGUgKHBvcyA8IHNpemUpIHsNCgkJCQlpbnQgbj0gc3RyZWFtLnJlYWQoZGF0YSwgcG9zLCBkYXRhLmxlbmd0aCAtIHBvcyk7DQoJCQkJcG9zICs9IG47DQoJCQl9DQoJCQl6aXBGaWxlLmNsb3NlKCk7DQoJCQlyZXR1cm4gZGF0YTsNCgkJfSBjYXRjaCAoSU9FeGNlcHRpb24gZSkgew0KCQl9IGZpbmFsbHkgew0KCQkJdHJ5IHsNCgkJCQlpZiAoc3RyZWFtICE9IG51bGwpDQoJCQkJCXN0cmVhbS5jbG9zZSgpOw0KCQkJfSBjYXRjaCAoSU9FeGNlcHRpb24gZSkgew0KCQkJfQ0KCQl9DQoJCXJldHVybiBudWxsOw0KCX0NCgkNCglwcml2YXRlIHZvaWQgcmVhZEV4Y2x1ZGVkUGFja2FnZXMoKSB7CQkNCgkJZkV4Y2x1ZGVkPSBuZXcgVmVjdG9yKDEwKTsNCgkJZm9yIChpbnQgaT0gMDsgaSA8IGRlZmF1bHRFeGNsdXNpb25zLmxlbmd0aDsgaSsrKQ0KCQkJZkV4Y2x1ZGVkLmFkZEVsZW1lbnQoZGVmYXVsdEV4Y2x1c2lvbnNbaV0pOw0KCQkJDQoJCUlucHV0U3RyZWFtIGlzPSBnZXRDbGFzcygpLmdldFJlc291cmNlQXNTdHJlYW0oRVhDTFVERURfRklMRSk7DQoJCWlmIChpcyA9PSBudWxsKSANCgkJCXJldHVybjsNCgkJUHJvcGVydGllcyBwPSBuZXcgUHJvcGVydGllcygpOw0KCQl0cnkgew0KCQkJcC5sb2FkKGlzKTsNCgkJfQ0KCQljYXRjaCAoSU9FeGNlcHRpb24gZSkgew0KCQkJcmV0dXJuOw0KCQl9IGZpbmFsbHkgew0KCQkJdHJ5IHsNCgkJCQlpcy5jbG9zZSgpOw0KCQkJfSBjYXRjaCAoSU9FeGNlcHRpb24gZSkgew0KCQkJfQ0KCQl9DQoJCWZvciAoRW51bWVyYXRpb24gZT0gcC5wcm9wZXJ0eU5hbWVzKCk7IGUuaGFzTW9yZUVsZW1lbnRzKCk7ICkgew0KCQkJU3RyaW5nIGtleT0gKFN0cmluZyllLm5leHRFbGVtZW50KCk7DQoJCQlpZiAoa2V5LnN0YXJ0c1dpdGgoImV4Y2x1ZGVkLiIpKSB7DQoJCQkJU3RyaW5nIHBhdGg9IHAuZ2V0UHJvcGVydHkoa2V5KTsNCgkJCQlwYXRoPSBwYXRoLnRyaW0oKTsNCgkJCQlpZiAocGF0aC5lbmRzV2l0aCgiKiIpKQ0KCQkJCQlwYXRoPSBwYXRoLnN1YnN0cmluZygwLCBwYXRoLmxlbmd0aCgpLTEpOw0KCQkJCWlmIChwYXRoLmxlbmd0aCgpID4gMCkgDQoJCQkJCWZFeGNsdWRlZC5hZGRFbGVtZW50KHBhdGgpOwkJCQkNCgkJCX0NCgkJfQ0KCX0NCn1QSwMECgAAAAAA6njHML9D+/YJAQAACQEAACAAAABqdW5pdC9ydW5uZXIvZXhjbHVkZWQucHJvcGVydGllcyMNCiMgVGhlIGxpc3Qgb2YgZXhjbHVkZWQgcGFja2FnZSBwYXRocyBmb3IgdGhlIFRlc3RDYXNlQ2xhc3NMb2FkZXINCiMNCmV4Y2x1ZGVkLjA9c3VuLioNCmV4Y2x1ZGVkLjE9Y29tLnN1bi4qDQpleGNsdWRlZC4yPW9yZy5vbWcu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dGNhc2UgY2xhc3MgdG8gYmUgcnVuLg0KICovDQpwdWJsaWMgY2xhc3MgVGVzdFJ1bm5lciBleHRlbmRzIEJhc2VUZXN0UnVubmVyIGltcGxlbWVudHMgVGVzdFJ1bkNvbnRleHQgew0KCXByaXZhdGUgc3RhdGljIGZpbmFsIGludCBHQVA9IDQ7DQoJcHJpdmF0ZSBzdGF0aWMgZmluYWwgaW50IEhJU1RPUllfTEVOR1RIPSA1Ow0KDQoJcHJvdGVjdGVkIEpGcmFtZSBmRnJhbWU7DQoJcHJpdmF0ZSBUaHJlYWQgZlJ1bm5lcjsNCglwcml2YXRlIFRlc3RSZXN1bHQgZlRlc3RSZXN1bHQ7DQoNCglwcml2YXRlIEpDb21ib0JveCBmU3VpdGVDb21ibzsNCglwcml2YXRlIFByb2dyZXNzQmFyIGZQcm9ncmVzc0luZGljYXRvcjsNCglwcml2YXRlIERlZmF1bHRMaXN0TW9kZWwgZkZhaWx1cmVzOw0KCXByaXZhdGUgSkxhYmVsIGZMb2dvOw0KCXByaXZhdGUgQ291bnRlclBhbmVsIGZDb3VudGVyUGFuZWw7DQoJcHJpdmF0ZSBKQnV0dG9uIGZSdW47DQoJcHJpdmF0ZSBKQnV0dG9uIGZRdWl0QnV0dG9uOw0KCXByaXZhdGUgSkJ1dHRvbiBmUmVydW5CdXR0b247DQoJcHJpdmF0ZSBTdGF0dXNMaW5lIGZTdGF0dXNMaW5lOw0KCXByaXZhdGUgRmFpbHVyZURldGFpbFZpZXcgZkZhaWx1cmVWaWV3Ow0KCXByaXZhdGUgSlRhYmJlZFBhbmUgZlRlc3RWaWV3VGFiOw0KCXByaXZhdGUgSkNoZWNrQm94IGZVc2VMb2FkaW5nUnVubmVyOw0KCXByaXZhdGUgVmVjdG9yIGZUZXN0UnVuVmlld3M9IG5ldyBWZWN0b3IoKTsgLy8gdmlldyBhc3NvY2lhdGVkIHdpdGggdGFiIGluIHRhYmJlZCBwYW5lDQoNCglwcml2YXRlIHN0YXRpYyBmaW5hbCBTdHJpbmcgVEVTVENPTExFQ1RPUl9LRVk9ICJUZXN0Q29sbGVjdG9yQ2xhc3MiOw0KCXByaXZhdGUgc3RhdGljIGZpbmFsIFN0cmluZyBGQUlMVVJFREVUQUlMVklFV19LRVk9ICJGYWlsdXJlVmlld0NsYXNzIjsNCg0KCXB1YmxpYyBUZXN0UnVubmVyKCkgew0KCX0NCg0KCXB1YmxpYyBzdGF0aWMgdm9pZCBtYWluKFN0cmluZ1tdIGFyZ3MpIHsNCgkJbmV3IFRlc3RSdW5uZXIoKS5zdGFydChhcmdzKTsNCgl9DQoNCglwdWJsaWMgc3RhdGljIHZvaWQgcnVuKENsYXNzIHRlc3QpIHsNCgkJU3RyaW5nIGFyZ3NbXT0geyB0ZXN0LmdldE5hbWUoKSB9Ow0KCQltYWluKGFyZ3MpOw0KCX0NCg0KCXB1YmxpYyB2b2lkIHRlc3RGYWlsZWQoZmluYWwgaW50IHN0YXR1cywgZmluYWwgVGVzdCB0ZXN0LCBmaW5hbCBUaHJvd2FibGUgdCkgew0KCQlTd2luZ1V0aWxpdGllcy5pbnZva2VMYXRlcigNCgkJCW5ldyBSdW5uYWJsZSgpIHsNCgkJCQlwdWJsaWMgdm9pZCBydW4oKSB7DQoJCQkJCXN3aXRjaCAoc3RhdHVzKSB7DQoJCQkJCQljYXNlIFRlc3RSdW5MaXN0ZW5lci5TVEFUVVNfRVJST1I6DQoJCQkJCQkJZkNvdW50ZXJQYW5lbC5zZXRFcnJvclZhbHVlKGZUZXN0UmVzdWx0LmVycm9yQ291bnQoKSk7DQoJCQkJCQkJYXBwZW5kRmFpbHVyZSh0ZXN0LCB0KTsNCgkJCQkJCQlicmVhazsNCgkJCQkJCWNhc2UgVGVzdFJ1bkxpc3RlbmVyLlNUQVRVU19GQUlMVVJFOg0KCQkJCQkJCWZDb3VudGVyUGFuZWwuc2V0RmFpbHVyZVZhbHVlKGZUZXN0UmVzdWx0LmZhaWx1cmVDb3VudCgpKTsNCgkJCQkJCQlhcHBlbmRGYWlsdXJlKHRlc3QsIHQpOw0KCQkJCQkJCWJyZWFrOw0KCQkJCQl9DQoJCQkJfQ0KCQkJfQ0KCQkpOw0KCX0NCg0KCXB1YmxpYyB2b2lkIHRlc3RTdGFydGVkKFN0cmluZyB0ZXN0TmFtZSkgew0KCQlwb3N0SW5mbygiUnVubmluZzogIit0ZXN0TmFtZSk7DQoJfQ0KDQoJcHVibGljIHZvaWQgdGVzdEVuZGVkKFN0cmluZyBzdHJpbmdOYW1lKSB7DQoJCXN5bmNoVUkoKTsNCgkJU3dpbmdVdGlsaXRpZXMuaW52b2tlTGF0ZXIoDQoJCQluZXcgUnVubmFibGUoKSB7DQoJCQkJcHVibGljIHZvaWQgcnVuKCkgew0KCQkJCQlpZiAoZlRlc3RSZXN1bHQgIT0gbnVsbCkgew0KCQkJCQkJZkNvdW50ZXJQYW5lbC5zZXRSdW5WYWx1ZShmVGVzdFJlc3VsdC5ydW5Db3VudCgpKTsNCgkJCQkJCWZQcm9ncmVzc0luZGljYXRvci5zdGVwKGZUZXN0UmVzdWx0LnJ1bkNvdW50KCksIGZUZXN0UmVzdWx0Lndhc1N1Y2Nlc3NmdWwoKSk7DQoJCQkJCX0NCgkJCQl9DQoJCQl9DQoJCSk7DQoJfQ0KDQoJcHVibGljIHZvaWQgc2V0U3VpdGUoU3RyaW5nIHN1aXRlTmFtZSkgew0KCQlmU3VpdGVDb21iby5nZXRFZGl0b3IoKS5zZXRJdGVtKHN1aXRlTmFtZSk7DQoJfQ0KDQoJcHJpdmF0ZSB2b2lkIGFkZFRvSGlzdG9yeShmaW5hbCBTdHJpbmcgc3VpdGUpIHsNCgkJZm9yIChpbnQgaT0gMDsgaSA8IGZTdWl0ZUNvbWJvLmdldEl0ZW1Db3VudCgpOyBpKyspIHsNCgkJCWlmIChzdWl0ZS5lcXVhbHMoZlN1aXRlQ29tYm8uZ2V0SXRlbUF0KGkpKSkgew0KCQkJCWZTdWl0ZUNvbWJvLnJlbW92ZUl0ZW1BdChpKTsNCgkJCQlmU3VpdGVDb21iby5pbnNlcnRJdGVtQXQoc3VpdGUsIDApOw0KCQkJCWZTdWl0ZUNvbWJvLnNldFNlbGVjdGVkSW5kZXgoMCk7DQoJCQkJcmV0dXJuOw0KCQkJfQ0KCQl9DQoJCWZTdWl0ZUNvbWJvLmluc2VydEl0ZW1BdChzdWl0ZSwgMCk7DQoJCWZTdWl0ZUNvbWJvLnNldFNlbGVjdGVkSW5kZXgoMCk7DQoJCXBydW5lSGlzdG9yeSgpOw0KCX0NCg0KCXByaXZhdGUgdm9pZCBwcnVuZUhpc3RvcnkoKSB7DQoJCWludCBoaXN0b3J5TGVuZ3RoPSBnZXRQcmVmZXJlbmNlKCJtYXhoaXN0b3J5IiwgSElTVE9SWV9MRU5HVEgpOw0KCQlpZiAoaGlzdG9yeUxlbmd0aCA8IDEpDQoJCQloaXN0b3J5TGVuZ3RoPSAxOw0KCQlmb3IgKGludCBpPSBmU3VpdGVDb21iby5nZXRJdGVtQ291bnQoKS0xOyBpID4gaGlzdG9yeUxlbmd0aC0xOyBpLS0pDQoJCQlmU3VpdGVDb21iby5yZW1vdmVJdGVtQXQoaSk7DQoJfQ0KDQoJcHJpdmF0ZSB2b2lkIGFwcGVuZEZhaWx1cmUoVGVzdCB0ZXN0LCBUaHJvd2FibGUgdCkgew0KCQlmRmFpbHVyZXMuYWRkRWxlbWVudChuZXcgVGVzdEZhaWx1cmUodGVzdCwgdCkpOw0KCQlpZiAoZkZhaWx1cmVzLnNpemUoKSA9PSAxKQ0KCQkJcmV2ZWFsRmFpbHVyZSh0ZXN0KTsNCgl9DQoNCglwcml2YXRlIHZvaWQgcmV2ZWFsRmFpbHVyZShUZXN0IHRlc3QpIHsNCgkJZm9yIChFbnVtZXJhdGlvbiBlPSBmVGVzdFJ1blZpZXdzLmVsZW1lbnRzKCk7IGUuaGFzTW9yZUVsZW1lbnRzKCk7ICkgew0KCQkJVGVzdFJ1blZpZXcgdj0gKFRlc3RSdW5WaWV3KSBlLm5leHRFbGVtZW50KCk7DQoJCQl2LnJldmVhbEZhaWx1cmUodGVzdCk7DQoJCX0NCgl9DQoNCglwcm90ZWN0ZWQgdm9pZCBhYm91dFRvU3RhcnQoZmluYWwgVGVzdCB0ZXN0U3VpdGUpIHsNCgkJZm9yIChFbnVtZXJhdGlvbiBlPSBmVGVzdFJ1blZpZXdzLmVsZW1lbnRzKCk7IGUuaGFzTW9yZUVsZW1lbnRzKCk7ICkgew0KCQkJVGVzdFJ1blZpZXcgdj0gKFRlc3RSdW5WaWV3KSBlLm5leHRFbGVtZW50KCk7DQoJCQl2LmFib3V0VG9TdGFydCh0ZXN0U3VpdGUsIGZUZXN0UmVzdWx0KTsNCgkJfQ0KCX0NCg0KCXByb3RlY3RlZCB2b2lkIHJ1bkZpbmlzaGVkKGZpbmFsIFRlc3QgdGVzdFN1aXRlKSB7DQoJCVN3aW5nVXRpbGl0aWVzLmludm9rZUxhdGVyKA0KCQkJbmV3IFJ1bm5hYmxlKCkgew0KCQkJCXB1YmxpYyB2b2lkIHJ1bigpIHsNCgkJCQkJZm9yIChFbnVtZXJhdGlvbiBlPSBmVGVzdFJ1blZpZXdzLmVsZW1lbnRzKCk7IGUuaGFzTW9yZUVsZW1lbnRzKCk7ICkgew0KCQkJCQkJVGVzdFJ1blZpZXcgdj0gKFRlc3RSdW5WaWV3KSBlLm5leHRFbGVtZW50KCk7DQoJCQkJCQl2LnJ1bkZpbmlzaGVkKHRlc3RTdWl0ZSwgZlRlc3RSZXN1bHQpOw0KCQkJCQl9DQoJCQkJfQ0KCQkJfQ0KCQkpOw0KCX0NCg0KCXByb3RlY3RlZCBDb3VudGVyUGFuZWwgY3JlYXRlQ291bnRlclBhbmVsKCkgew0KCQlyZXR1cm4gbmV3IENvdW50ZXJQYW5lbCgpOw0KCX0NCg0KCXByb3RlY3RlZCBKUGFuZWwgY3JlYXRlRmFpbGVkUGFuZWwoKSB7DQoJCUpQYW5lbCBmYWlsZWRQYW5lbD0gbmV3IEpQYW5lbChuZXcgR3JpZExheW91dCgwLCAxLCAwLCAyKSk7DQoJCWZSZXJ1bkJ1dHRvbj0gbmV3IEpCdXR0b24oIlJ1biIpOw0KCQlmUmVydW5CdXR0b24uc2V0RW5hYmxlZChmYWxzZSk7DQoJCWZSZXJ1bkJ1dHRvbi5hZGRBY3Rpb25MaXN0ZW5lcigNCgkJCW5ldyBBY3Rpb25MaXN0ZW5lcigpIHsNCgkJCQlwdWJsaWMgdm9pZCBhY3Rpb25QZXJmb3JtZWQoQWN0aW9uRXZlbnQgZSkgew0KCQkJCQlyZXJ1bigpOw0KCQkJCX0NCgkJCX0NCgkJKTsNCgkJZmFpbGVkUGFuZWwuYWRkKGZSZXJ1bkJ1dHRvbik7DQoJCXJldHVybiBmYWlsZWRQYW5lbDsNCgl9DQoNCglwcm90ZWN0ZWQgRmFpbHVyZURldGFpbFZpZXcgY3JlYXRlRmFpbHVyZURldGFpbFZpZXcoKSB7DQoJCVN0cmluZyBjbGFzc05hbWU9IEJhc2VUZXN0UnVubmVyLmdldFByZWZlcmVuY2UoRkFJTFVSRURFVEFJTFZJRVdfS0VZKTsNCgkJaWYgKGNsYXNzTmFtZSAhPSBudWxsKSB7DQoJCQlDbGFzcyB2aWV3Q2xhc3M9IG51bGw7DQoJCQl0cnkgew0KCQkJCXZpZXdDbGFzcz0gQ2xhc3MuZm9yTmFtZShjbGFzc05hbWUpOw0KCQkJCXJldHVybiAoRmFpbHVyZURldGFpbFZpZXcpdmlld0NsYXNzLm5ld0luc3RhbmNlKCk7DQoJCQl9IGNhdGNoKEV4Y2VwdGlvbiBlKSB7DQoJCQkJSk9wdGlvblBhbmUuc2hvd01lc3NhZ2VEaWFsb2coZkZyYW1lLCAiQ291bGQgbm90IGNyZWF0ZSBGYWlsdXJlIERldGFpbFZpZXcgLSB1c2luZyBkZWZhdWx0IHZpZXciKTsNCgkJCX0NCgkJfQ0KCQlyZXR1cm4gbmV3IERlZmF1bHRGYWlsdXJlRGV0YWlsVmlldygpOw0KCX0NCg0KCS8qKg0KCSAqIENyZWF0ZXMgdGhlIEpVbml0IG1lbnUuIENsaWVudHMgb3ZlcnJpZGUgdGhpcw0KCSAqIG1ldGhvZCB0byBhZGQgYWRkaXRpb25hbCBtZW51IGl0ZW1zLg0KCSAqLw0KCXByb3RlY3RlZCBKTWVudSBjcmVhdGVKVW5pdE1lbnUoKSB7DQoJCUpNZW51IG1lbnU9IG5ldyBKTWVudSgiSlVuaXQiKTsNCgkJbWVudS5zZXRNbmVtb25pYygnSicpOw0KCQlKTWVudUl0ZW0gbWkxPSBuZXcgSk1lbnVJdGVtKCJBYm91dC4uLiIpOw0KCQltaTEuYWRkQWN0aW9uTGlzdGVuZXIoDQoJCSAgICBuZXcgQWN0aW9uTGlzdGVuZXIoKSB7DQoJCSAgICAgICAgcHVibGljIHZvaWQgYWN0aW9uUGVyZm9ybWVkKEFjdGlvbkV2ZW50IGV2ZW50KSB7DQoJCSAgICAgICAgICAgIGFib3V0KCk7DQoJCSAgICAgICAgfQ0KCQkgICAgfQ0KCQkpOw0KCQltaTEuc2V0TW5lbW9uaWMoJ0EnKTsNCgkJbWVudS5hZGQobWkxKTsNCg0KCQltZW51LmFkZFNlcGFyYXRvcigpOw0KCQlKTWVudUl0ZW0gbWkyPSBuZXcgSk1lbnVJdGVtKCIgRXhpdCAiKTsNCgkJbWkyLmFkZEFjdGlvbkxpc3RlbmVyKA0KCQkgICAgbmV3IEFjdGlvbkxpc3RlbmVyKCkgew0KCQkgICAgICAgIHB1YmxpYyB2b2lkIGFjdGlvblBlcmZvcm1lZChBY3Rpb25FdmVudCBldmVudCkgew0KCQkgICAgICAgICAgICB0ZXJtaW5hdGUoKTsNCgkJICAgICAgICB9DQoJCSAgICB9DQoJCSk7DQoJCW1pMi5zZXRNbmVtb25pYygneCcpOw0KCQltZW51LmFkZChtaTIpOw0KDQoJCXJldHVybiBtZW51Ow0KCX0NCg0KCXByb3RlY3RlZCBKRnJhbWUgY3JlYXRlRnJhbWUoKSB7DQoJCUpGcmFtZSBmcmFtZT0gbmV3IEpGcmFtZSgiSlVuaXQiKTsNCgkJSW1hZ2UgaWNvbj0gbG9hZEZyYW1lSWNvbigpOw0KCQlpZiAoaWNvbiAhPSBudWxsKQ0KCQkJZnJhbWUuc2V0SWNvbkltYWdlKGljb24pOw0KCQlmcmFtZS5nZXRDb250ZW50UGFuZSgpLnNldExheW91dChuZXcgQm9yZGVyTGF5b3V0KDAsIDApKTsNCg0KCQlmcmFtZS5hZGRXaW5kb3dMaXN0ZW5lcigNCgkJCW5ldyBXaW5kb3dBZGFwdGVyKCkgew0KCQkJCXB1YmxpYyB2b2lkIHdpbmRvd0Nsb3NpbmcoV2luZG93RXZlbnQgZSkgew0KCQkJCQl0ZXJtaW5hdGUoKTsNCgkJCQl9DQoJCQl9DQoJCSk7DQoJCXJldHVybiBmcmFtZTsNCgl9DQoNCglwcm90ZWN0ZWQgSkxhYmVsIGNyZWF0ZUxvZ28oKSB7DQoJCUpMYWJlbCBsYWJlbDsNCgkJSWNvbiBpY29uPSBnZXRJY29uUmVzb3VyY2UoQmFzZVRlc3RSdW5uZXIuY2xhc3MsICJsb2dvLmdpZiIpOw0KCQlpZiAoaWNvbiAhPSBudWxsKQ0KCQkJbGFiZWw9IG5ldyBKTGFiZWwoaWNvbik7DQoJCWVsc2UNCgkJCWxhYmVsPSBuZXcgSkxhYmVsKCJKViIpOw0KCQlsYWJlbC5zZXRUb29sVGlwVGV4dCgiSlVuaXQgVmVyc2lvbiAiK1ZlcnNpb24uaWQoKSk7DQoJCXJldHVybiBsYWJlbDsNCgl9DQoNCglwcm90ZWN0ZWQgdm9pZCBjcmVhdGVNZW51cyhKTWVudUJhciBtYikgew0KCQltYi5hZGQoY3JlYXRlSlVuaXRNZW51KCkpOw0KCX0NCg0KCXByb3RlY3RlZCBKQ2hlY2tCb3ggY3JlYXRlVXNlTG9hZGVyQ2hlY2tCb3goKSB7DQoJCWJvb2xlYW4gdXNlTG9hZGVyPSB1c2VSZWxvYWRpbmdUZXN0U3VpdGVMb2FkZXIoKTsNCgkJSkNoZWNrQm94IGJveD0gbmV3IEpDaGVja0JveCgiUmVsb2FkIGNsYXNzZXMgZXZlcnkgcnVuIiwgdXNlTG9hZGVyKTsNCgkJYm94LnNldFRvb2xUaXBUZXh0KCJVc2UgYSBjdXN0b20gY2xhc3MgbG9hZGVyIHRvIHJlbG9hZCB0aGUgY2xhc3NlcyBmb3IgZXZlcnkgcnVuIik7DQoJCWlmIChpblZBSmF2YSgpKQ0KCQkJYm94LnNldFZpc2libGUoZmFsc2UpOw0KCQlyZXR1cm4gYm94Ow0KCX0NCg0KCXByb3RlY3RlZCBKQnV0dG9uIGNyZWF0ZVF1aXRCdXR0b24oKSB7DQoJCSAvLyBzcGFjZXMgcmVxdWlyZWQgdG8gYXZvaWQgbGF5b3V0IGZsaWNrZXINCgkJIC8vIEV4aXQgaXMgc2hvcnRlciB0aGFuIFN0b3AgdGhhdCBzaG93cyBpbiB0aGUgc2FtZSBjb2x1bW4NCgkJSkJ1dHRvbiBxdWl0PSBuZXcgSkJ1dHRvbigiIEV4aXQgIik7DQoJCXF1aXQuYWRkQWN0aW9uTGlzdGVuZXIoDQoJCQluZXcgQWN0aW9uTGlzdGVuZXIoKSB7DQoJCQkJcHVibGljIHZvaWQgYWN0aW9uUGVyZm9ybWVkKEFjdGlvbkV2ZW50IGUpIHsNCgkJCQkJdGVybWluYXRlKCk7DQoJCQkJfQ0KCQkJfQ0KCQkpOw0KCQlyZXR1cm4gcXVpdDsNCgl9DQoNCglwcm90ZWN0ZWQgSkJ1dHRvbiBjcmVhdGVSdW5CdXR0b24oKSB7DQoJCUpCdXR0b24gcnVuPSBuZXcgSkJ1dHRvbigiUnVuIik7DQoJCXJ1bi5zZXRFbmFibGVkKHRydWUpOw0KCQlydW4uYWRkQWN0aW9uTGlzdGVuZXIoDQoJCQluZXcgQWN0aW9uTGlzdGVuZXIoKSB7DQoJCQkJcHVibGljIHZvaWQgYWN0aW9uUGVyZm9ybWVkKEFjdGlvbkV2ZW50IGUpIHsNCgkJCQkJcnVuU3VpdGUoKTsNCgkJCQl9DQoJCQl9DQoJCSk7DQoJCXJldHVybiBydW47DQoJfQ0KDQoJcHJvdGVjdGVkIENvbXBvbmVudCBjcmVhdGVCcm93c2VCdXR0b24oKSB7DQoJCUpCdXR0b24gYnJvd3NlPSBuZXcgSkJ1dHRvbigiLi4uIik7DQoJCWJyb3dzZS5zZXRUb29sVGlwVGV4dCgiU2VsZWN0IGEgVGVzdCBjbGFzcyIpOw0KCQlicm93c2UuYWRkQWN0aW9uTGlzdGVuZXIoDQoJCQluZXcgQWN0aW9uTGlzdGVuZXIoKSB7DQoJCQkJcHVibGljIHZvaWQgYWN0aW9uUGVyZm9ybWVkKEFjdGlvbkV2ZW50IGUpIHsNCgkJCQkJYnJvd3NlVGVzdENsYXNzZXMoKTsNCgkJCQl9DQoJCQl9DQoJCSk7DQoJCXJldHVybiBicm93c2U7DQoJfQ0KDQoJcHJvdGVjdGVkIFN0YXR1c0xpbmUgY3JlYXRlU3RhdHVzTGluZSgpIHsNCgkJcmV0dXJuIG5ldyBTdGF0dXNMaW5lKDM4MCk7DQoJfQ0KDQoJcHJvdGVjdGVkIEpDb21ib0JveCBjcmVhdGVTdWl0ZUNvbWJvKCkgew0KCQlKQ29tYm9Cb3ggY29tYm89IG5ldyBKQ29tYm9Cb3goKTsNCgkJY29tYm8uc2V0RWRpdGFibGUodHJ1ZSk7DQoJCWNvbWJvLnNldExpZ2h0V2VpZ2h0UG9wdXBFbmFibGVkKGZhbHNlKTsNCg0KCQljb21iby5nZXRFZGl0b3IoKS5nZXRFZGl0b3JDb21wb25lbnQoKS5hZGRLZXlMaXN0ZW5lcigNCgkJCW5ldyBLZXlBZGFwdGVyKCkgew0KCQkJCXB1YmxpYyB2b2lkIGtleVR5cGVkKEtleUV2ZW50IGUpIHsNCgkJCQkJdGV4dENoYW5nZWQoKTsNCgkJCQkJaWYgKGUuZ2V0S2V5Q2hhcigpID09IEtleUV2ZW50LlZLX0VOVEVSKQ0KCQkJCQkJcnVuU3VpdGUoKTsNCgkJCQl9DQoJCQl9DQoJCSk7DQoJCXRyeSB7DQoJCQlsb2FkSGlzdG9yeShjb21ibyk7DQoJCX0gY2F0Y2ggKElPRXhjZXB0aW9uIGUpIHsNCgkJCS8vIGZhaWxzIHRoZSBmaXJzdCB0aW1lDQoJCX0NCgkJY29tYm8uYWRkSXRlbUxpc3RlbmVyKA0KCQkJbmV3IEl0ZW1MaXN0ZW5lcigpIHsNCgkJCQlwdWJsaWMgdm9pZCBpdGVtU3RhdGVDaGFuZ2VkKEl0ZW1FdmVudCBldmVudCkgew0KCQkJCQlpZiAoZXZlbnQuZ2V0U3RhdGVDaGFuZ2UoKSA9PSBJdGVtRXZlbnQuU0VMRUNURUQpIHsNCgkJCQkJCXRleHRDaGFuZ2VkKCk7DQoJCQkJCX0NCgkJCQl9DQoJCQl9DQoJCSk7DQoJCXJldHVybiBjb21ibzsNCgl9DQoNCglwcm90ZWN0ZWQgSlRhYmJlZFBhbmUgY3JlYXRlVGVzdFJ1blZpZXdzKCkgew0KCQlKVGFiYmVkUGFuZSBwYW5lPSBuZXcgSlRhYmJlZFBhbmUoSlRhYmJlZFBhbmUuQk9UVE9NKTsNCg0KCQlGYWlsdXJlUnVuVmlldyBsdj0gbmV3IEZhaWx1cmVSdW5WaWV3KHRoaXMpOw0KCQlmVGVzdFJ1blZpZXdzLmFkZEVsZW1lbnQobHYpOw0KCQlsdi5hZGRUYWIocGFuZSk7DQoNCgkJVGVzdEhpZXJhcmNoeVJ1blZpZXcgdHY9IG5ldyBUZXN0SGllcmFyY2h5UnVuVmlldyh0aGlzKTsNCgkJZlRlc3RSdW5WaWV3cy5hZGRFbGVtZW50KHR2KTsNCgkJdHYuYWRkVGFiKHBhbmUpOw0KDQoJCXBhbmUuYWRkQ2hhbmdlTGlzdGVuZXIoDQoJCQluZXcgQ2hhbmdlTGlzdGVuZXIoKSB7DQoJCQkJcHVibGljIHZvaWQgc3RhdGVDaGFuZ2VkKENoYW5nZUV2ZW50IGUpIHsNCgkJCQkJdGVzdFZpZXdDaGFuZ2VkKCk7DQoJCQkJfQ0KCQkJfQ0KCQkpOw0KCQlyZXR1cm4gcGFuZTsNCgl9DQoNCglwdWJsaWMgdm9pZCB0ZXN0Vmlld0NoYW5nZWQoKSB7DQoJCVRlc3RSdW5WaWV3IHZpZXc9IChUZXN0UnVuVmlldylmVGVzdFJ1blZpZXdzLmVsZW1lbnRBdChmVGVzdFZpZXdUYWIuZ2V0U2VsZWN0ZWRJbmRleCgpKTsNCgkJdmlldy5hY3RpdmF0ZSgpOw0KCX0NCg0KCXByb3RlY3RlZCBUZXN0UmVzdWx0IGNyZWF0ZVRlc3RSZXN1bHQoKSB7DQoJCXJldHVybiBuZXcgVGVzdFJlc3VsdCgpOw0KCX0NCg0KCXByb3RlY3RlZCBKRnJhbWUgY3JlYXRlVUkoU3RyaW5nIHN1aXRlTmFtZSkgew0KCQlKRnJhbWUgZnJhbWU9IGNyZWF0ZUZyYW1lKCk7DQoJCUpNZW51QmFyIG1iPSBuZXcgSk1lbnVCYXIoKTsNCgkJY3JlYXRlTWVudXMobWIpOw0KCQlmcmFtZS5zZXRKTWVudUJhcihtYik7DQoNCgkJSkxhYmVsIHN1aXRlTGFiZWw9IG5ldyBKTGFiZWwoIlRlc3QgY2xhc3MgbmFtZToiKTsNCgkJZlN1aXRlQ29tYm89IGNyZWF0ZVN1aXRlQ29tYm8oKTsNCgkJZlJ1bj0gY3JlYXRlUnVuQnV0dG9uKCk7DQoJCWZyYW1lLmdldFJvb3RQYW5lKCkuc2V0RGVmYXVsdEJ1dHRvbihmUnVuKTsNCgkJQ29tcG9uZW50IGJyb3dzZUJ1dHRvbj0gY3JlYXRlQnJvd3NlQnV0dG9uKCk7DQoNCgkJZlVzZUxvYWRpbmdSdW5uZXI9IGNyZWF0ZVVzZUxvYWRlckNoZWNrQm94KCk7DQoJCWZQcm9ncmVzc0luZGljYXRvcj0gbmV3IFByb2dyZXNzQmFyKCk7DQoJCWZDb3VudGVyUGFuZWw9IGNyZWF0ZUNvdW50ZXJQYW5lbCgpOw0KDQoJCWZGYWlsdXJlcz0gbmV3IERlZmF1bHRMaXN0TW9kZWwoKTsNCg0KCQlmVGVzdFZpZXdUYWI9IGNyZWF0ZVRlc3RSdW5WaWV3cygpOw0KCQlKUGFuZWwgZmFpbGVkUGFuZWw9IGNyZWF0ZUZhaWxlZFBhbmVsKCk7DQoNCgkJZkZhaWx1cmVWaWV3PSBjcmVhdGVGYWlsdXJlRGV0YWlsVmlldygpOw0KCQlKU2Nyb2xsUGFuZSB0cmFjZVBhbmU9IG5ldyBKU2Nyb2xsUGFuZShmRmFpbHVyZVZpZXcuZ2V0Q29tcG9uZW50KCksIEpTY3JvbGxQYW5lLlZFUlRJQ0FMX1NDUk9MTEJBUl9BTFdBWVMsIEpTY3JvbGxQYW5lLkhPUklaT05UQUxfU0NST0xMQkFSX0FMV0FZUyk7DQoNCgkJZlN0YXR1c0xpbmU9IGNyZWF0ZVN0YXR1c0xpbmUoKTsNCgkJZlF1aXRCdXR0b249IGNyZWF0ZVF1aXRCdXR0b24oKTsNCgkJZkxvZ289IGNyZWF0ZUxvZ28oKTsNCg0KCQlKUGFuZWwgcGFuZWw9IG5ldyBKUGFuZWwobmV3IEdyaWRCYWdMYXlvdXQoKSk7DQoNCgkJYWRkR3JpZChwYW5lbCwgc3VpdGVMYWJlbCwJMCwgMCwgMiwgR3JpZEJhZ0NvbnN0cmFpbnRzLkhPUklaT05UQUwsIAkxLjAsIEdyaWRCYWdDb25zdHJhaW50cy5XRVNUKTsNCgkJYWRkR3JpZChwYW5lbCwgZlN1aXRlQ29tYm8sIAkwLCAxLCAxLCBHcmlkQmFnQ29uc3RyYWludHMuSE9SSVpPTlRBTCwgCTEuMCwgR3JpZEJhZ0NvbnN0cmFpbnRzLldFU1QpOw0KCQlhZGRHcmlkKHBhbmVsLCBicm93c2VCdXR0b24sIAkxLCAxLCAxLCBHcmlkQmFnQ29uc3RyYWludHMuTk9ORSwgCQkJMC4wLCBHcmlkQmFnQ29uc3RyYWludHMuV0VTVCk7DQoJCWFkZEdyaWQocGFuZWwsIGZSdW4sIAkJMiwgMSwgMSwgR3JpZEJhZ0NvbnN0cmFpbnRzLkhPUklaT05UQUwsIAkwLjAsIEdyaWRCYWdDb25zdHJhaW50cy5DRU5URVIpOw0KDQoJCWFkZEdyaWQocGFuZWwsIGZVc2VMb2FkaW5nUnVubmVyLCAgCTAsIDIsIDMsIEdyaWRCYWdDb25zdHJhaW50cy5OT05FLCAxLjAsIEdyaWRCYWdDb25zdHJhaW50cy5XRVNUKTsNCgkJLy9hZGRHcmlkKHBhbmVsLCBuZXcgSlNlcGFyYXRvcigpLCAJMCwgMywgMywgR3JpZEJhZ0NvbnN0cmFpbnRzLkhPUklaT05UQUwsIDEuMCwgR3JpZEJhZ0NvbnN0cmFpbnRzLldFU1QpOw0KDQoNCgkJYWRkR3JpZChwYW5lbCwgZlByb2dyZXNzSW5kaWNhdG9yLCAJMCwgMywgMiwgR3JpZEJhZ0NvbnN0cmFpbnRzLkhPUklaT05UQUwsIAkxLjAsIEdyaWRCYWdDb25zdHJhaW50cy5XRVNUKTsNCgkJYWRkR3JpZChwYW5lbCwgZkxvZ28sIAkJCTIsIDMsIDEsIEdyaWRCYWdDb25zdHJhaW50cy5OT05FLCAJCQkwLjAsIEdyaWRCYWdDb25zdHJhaW50cy5OT1JUSCk7DQoNCgkJYWRkR3JpZChwYW5lbCwgZkNvdW50ZXJQYW5lbCwJIDAsIDQsIDIsIEdyaWRCYWdDb25zdHJhaW50cy5OT05FLCAJCQkwLjAsIEdyaWRCYWdDb25zdHJhaW50cy5XRVNUKTsNCgkJYWRkR3JpZChwYW5lbCwgbmV3IEpTZXBhcmF0b3IoKSwgCTAsIDUsIDIsIEdyaWRCYWdDb25zdHJhaW50cy5IT1JJWk9OVEFMLCAxLjAsIEdyaWRCYWdDb25zdHJhaW50cy5XRVNUKTsNCgkJYWRkR3JpZChwYW5lbCwgbmV3IEpMYWJlbCgiUmVzdWx0czoiKSwJMCwgNiwgMiwgR3JpZEJhZ0NvbnN0cmFpbnRzLkhPUklaT05UQUwsIAkxLjAsIEdyaWRCYWdDb25zdHJhaW50cy5XRVNUKTsNCg0KCQlKU3BsaXRQYW5lIHNwbGl0dGVyPSBuZXcgSlNwbGl0UGFuZShKU3BsaXRQYW5lLlZFUlRJQ0FMX1NQTElULCBmVGVzdFZpZXdUYWIsIHRyYWNlUGFuZSk7DQoJCWFkZEdyaWQocGFuZWwsIHNwbGl0dGVyLCAJIDAsIDcsIDIsIEdyaWRCYWdDb25zdHJhaW50cy5CT1RILCAJCQkxLjAsIEdyaWRCYWdDb25zdHJhaW50cy5XRVNUKTsNCg0KCQlhZGRHcmlkKHBhbmVsLCBmYWlsZWRQYW5lbCwgCSAyLCA3LCAxLCBHcmlkQmFnQ29uc3RyYWludHMuSE9SSVpPTlRBTCwgCTAuMCwgR3JpZEJhZ0NvbnN0cmFpbnRzLk5PUlRILypDRU5URVIqLyk7DQoNCgkJYWRkR3JpZChwYW5lbCwgZlN0YXR1c0xpbmUsIAkgMCwgOSwgMiwgR3JpZEJhZ0NvbnN0cmFpbnRzLkhPUklaT05UQUwsIAkxLjAsIEdyaWRCYWdDb25zdHJhaW50cy5DRU5URVIpOw0KCQlhZGRHcmlkKHBhbmVsLCBmUXVpdEJ1dHRvbiwgCSAyLCA5LCAxLCBHcmlkQmFnQ29uc3RyYWludHMuSE9SSVpPTlRBTCwgCTAuMCwgR3JpZEJhZ0NvbnN0cmFpbnRzLkNFTlRFUik7DQoNCgkJZnJhbWUuc2V0Q29udGVudFBhbmUocGFuZWwpOw0KCQlmcmFtZS5wYWNrKCk7DQoJCWZyYW1lLnNldExvY2F0aW9uKDIwMCwgMjAwKTsNCgkJcmV0dXJuIGZyYW1lOw0KCX0NCg0KCXByaXZhdGUgdm9pZCBhZGRHcmlkKEpQYW5lbCBwLCBDb21wb25lbnQgY28sIGludCB4LCBpbnQgeSwgaW50IHcsIGludCBmaWxsLCBkb3VibGUgd3gsIGludCBhbmNob3IpIHsNCgkJR3JpZEJhZ0NvbnN0cmFpbnRzIGM9IG5ldyBHcmlkQmFnQ29uc3RyYWludHMoKTsNCgkJYy5ncmlkeD0geDsgYy5ncmlkeT0geTsNCgkJYy5ncmlkd2lkdGg9IHc7DQoJCWMuYW5jaG9yPSBhbmNob3I7DQoJCWMud2VpZ2h0eD0gd3g7DQoJCWMuZmlsbD0gZmlsbDsNCgkJaWYgKGZpbGwgPT0gR3JpZEJhZ0NvbnN0cmFpbnRzLkJPVEggfHwgZmlsbCA9PSBHcmlkQmFnQ29uc3RyYWludHMuVkVSVElDQUwpDQoJCQljLndlaWdodHk9IDEuMDsNCgkJYy5pbnNldHM9IG5ldyBJbnNldHMoeSA9PSAwID8gMTAgOiAwLCB4ID09IDAgPyAxMCA6IEdBUCwgR0FQLCBHQVApOyANCgkJcC5hZGQoY28sIGMpOw0KCX0NCg0KCXByb3RlY3RlZCBTdHJpbmcgZ2V0U3VpdGVUZXh0KCkgew0KCQlpZiAoZlN1aXRlQ29tYm8gPT0gbnVsbCkNCgkJCXJldHVybiAiIjsNCgkJcmV0dXJuIChTdHJpbmcpZlN1aXRlQ29tYm8uZ2V0RWRpdG9yKCkuZ2V0SXRlbSgpOw0KCX0NCg0KCXB1YmxpYyBMaXN0TW9kZWwgZ2V0RmFpbHVyZXMoKSB7DQoJCXJldHVybiBmRmFpbHVyZXM7DQoJfQ0KDQoJcHVibGljIHZvaWQgaW5zZXJ0VXBkYXRlKERvY3VtZW50RXZlbnQgZXZlbnQpIHsNCgkJdGV4dENoYW5nZWQoKTsNCgl9DQoNCglwdWJsaWMgdm9pZCBicm93c2VUZXN0Q2xhc3NlcygpIHsNCgkJVGVzdENvbGxlY3RvciBjb2xsZWN0b3I9IGNyZWF0ZVRlc3RDb2xsZWN0b3IoKTsNCgkJVGVzdFNlbGVjdG9yIHNlbGVjdG9yPSBuZXcgVGVzdFNlbGVjdG9yKGZGcmFtZSwgY29sbGVjdG9yKTsNCgkJaWYgKHNlbGVjdG9yLmlzRW1wdHkoKSkgew0KCQkJSk9wdGlvblBhbmUuc2hvd01lc3NhZ2VEaWFsb2coZkZyYW1lLCAiTm8gVGVzdCBDYXNlcyBmb3VuZC5cbkNoZWNrIHRoYXQgdGhlIGNvbmZpZ3VyZWQgXCdUZXN0Q29sbGVjdG9yXCcgaXMgc3VwcG9ydGVkIG9uIHRoaXMgcGxhdGZvcm0uIik7DQoJCQlyZXR1cm47DQoJCX0NCgkJc2VsZWN0b3Iuc2hvdygpOw0KCQlTdHJpbmcgY2xhc3NOYW1lPSBzZWxlY3Rvci5nZXRTZWxlY3RlZEl0ZW0oKTsNCgkJaWYgKGNsYXNzTmFtZSAhPSBudWxsKQ0KCQkJc2V0U3VpdGUoY2xhc3NOYW1lKTsNCgl9DQoNCglUZXN0Q29sbGVjdG9yIGNyZWF0ZVRlc3RDb2xsZWN0b3IoKSB7DQoJCVN0cmluZyBjbGFzc05hbWU9IEJhc2VUZXN0UnVubmVyLmdldFByZWZlcmVuY2UoVEVTVENPTExFQ1RPUl9LRVkpOw0KCQlpZiAoY2xhc3NOYW1lICE9IG51bGwpIHsNCgkJCUNsYXNzIGNvbGxlY3RvckNsYXNzPSBudWxsOw0KCQkJdHJ5IHsNCgkJCQljb2xsZWN0b3JDbGFzcz0gQ2xhc3MuZm9yTmFtZShjbGFzc05hbWUpOw0KCQkJCXJldHVybiAoVGVzdENvbGxlY3Rvciljb2xsZWN0b3JDbGFzcy5uZXdJbnN0YW5jZSgpOw0KCQkJfSBjYXRjaChFeGNlcHRpb24gZSkgew0KCQkJCUpPcHRpb25QYW5lLnNob3dNZXNzYWdlRGlhbG9nKGZGcmFtZSwgIkNvdWxkIG5vdCBjcmVhdGUgVGVzdENvbGxlY3RvciAtIHVzaW5nIGRlZmF1bHQgY29sbGVjdG9yIik7DQoJCQl9DQoJCX0NCgkJcmV0dXJuIG5ldyBTaW1wbGVUZXN0Q29sbGVjdG9yKCk7DQoJfQ0KDQoJcHJpdmF0ZSBJbWFnZSBsb2FkRnJhbWVJY29uKCkgew0KCQlJbWFnZUljb24gaWNvbj0gKEltYWdlSWNvbilnZXRJY29uUmVzb3VyY2UoQmFzZVRlc3RSdW5uZXIuY2xhc3MsICJzbWFsbGxvZ28uZ2lmIik7DQoJCWlmIChpY29uICE9IG51bGwpDQoJCQlyZXR1cm4gaWNvbi5nZXRJbWFnZSgpOw0KCQlyZXR1cm4gbnVsbDsNCgl9DQoNCglwcml2YXRlIHZvaWQgbG9hZEhpc3RvcnkoSkNvbWJvQm94IGNvbWJvKSB0aHJvd3MgSU9FeGNlcHRpb24gew0KCQlCdWZmZXJlZFJlYWRlciBicj0gbmV3IEJ1ZmZlcmVkUmVhZGVyKG5ldyBGaWxlUmVhZGVyKGdldFNldHRpbmdzRmlsZSgpKSk7DQoJCWludCBpdGVtQ291bnQ9IDA7DQoJCXRyeSB7DQoJCQlTdHJpbmcgbGluZTsNCgkJCXdoaWxlICgobGluZT0gYnIucmVhZExpbmUoKSkgIT0gbnVsbCkgew0KCQkJCWNvbWJvLmFkZEl0ZW0obGluZSk7DQoJCQkJaXRlbUNvdW50Kys7DQoJCQl9DQoJCQlpZiAoaXRlbUNvdW50ID4gMCkNCgkJCQljb21iby5zZXRTZWxlY3RlZEluZGV4KDApOw0KDQoJCX0gZmluYWxseSB7DQoJCQlici5jbG9zZSgpOw0KCQl9DQoJfQ0KDQoJcHJpdmF0ZSBGaWxlIGdldFNldHRpbmdzRmlsZSgpIHsNCgkgCVN0cmluZyBob21lPSBTeXN0ZW0uZ2V0UHJvcGVydHkoInVzZXIuaG9tZSIpOw0KIAkJcmV0dXJuIG5ldyBGaWxlKGhvbWUsIi5qdW5pdHNlc3Npb24iKTsNCiAJfQ0KDQoJcHJpdmF0ZSB2b2lkIHBvc3RJbmZvKGZpbmFsIFN0cmluZyBtZXNzYWdlKSB7DQoJCVN3aW5nVXRpbGl0aWVzLmludm9rZUxhdGVyKA0KCQkJbmV3IFJ1bm5hYmxlKCkgew0KCQkJCXB1YmxpYyB2b2lkIHJ1bigpIHsNCgkJCQkJc2hvd0luZm8obWVzc2FnZSk7DQoJCQkJfQ0KCQkJfQ0KCQkpOw0KCX0NCg0KCXByaXZhdGUgdm9pZCBwb3N0U3RhdHVzKGZpbmFsIFN0cmluZyBzdGF0dXMpIHsNCgkJU3dpbmdVdGlsaXRpZXMuaW52b2tlTGF0ZXIoDQoJCQluZXcgUnVubmFibGUoKSB7DQoJCQkJcHVibGljIHZvaWQgcnVuKCkgew0KCQkJCQlzaG93U3RhdHVzKHN0YXR1cyk7DQoJCQkJfQ0KCQkJfQ0KCQkpOw0KCX0NCg0KCXB1YmxpYyB2b2lkIHJlbW92ZVVwZGF0ZShEb2N1bWVudEV2ZW50IGV2ZW50KSB7DQoJCXRleHRDaGFuZ2VkKCk7DQoJfQ0KDQoJcHJpdmF0ZSB2b2lkIHJlcnVuKCkgew0KCQlUZXN0UnVuVmlldyB2aWV3PSAoVGVzdFJ1blZpZXcpZlRlc3RSdW5WaWV3cy5lbGVtZW50QXQoZlRlc3RWaWV3VGFiLmdldFNlbGVjdGVkSW5kZXgoKSk7DQoJCVRlc3QgcmVydW5UZXN0PSB2aWV3LmdldFNlbGVjdGVkVGVzdCgpOw0KCQlpZiAocmVydW5UZXN0ICE9IG51bGwpDQoJCQlyZXJ1blRlc3QocmVydW5UZXN0KTsNCgl9DQoNCglwcml2YXRlIHZvaWQgcmVydW5UZXN0KFRlc3QgdGVzdCkgew0KCQlpZiAoISh0ZXN0IGluc3RhbmNlb2YgVGVzdENhc2UpKSB7DQoJCQlzaG93SW5mbygiQ291bGQgbm90IHJlbG9hZCAiKyB0ZXN0LnRvU3RyaW5nKCkpOw0KCQkJcmV0dXJuOw0KCQl9DQoJCVRlc3QgcmVsb2FkZWRUZXN0PSBudWxsOw0KCQlUZXN0Q2FzZSByZXJ1blRlc3Q9IChUZXN0Q2FzZSl0ZXN0Ow0KDQoJCXRyeSB7DQoJCQlDbGFzcyByZWxvYWRlZFRlc3RDbGFzcz0gZ2V0TG9hZGVyKCkucmVsb2FkKHRlc3QuZ2V0Q2xhc3MoKSk7IA0KCQkJcmVsb2FkZWRUZXN0PSBUZXN0U3VpdGUuY3JlYXRlVGVzdChyZWxvYWRlZFRlc3RDbGFzcywgcmVydW5UZXN0LmdldE5hbWUoKSk7DQoJCX0gY2F0Y2goRXhjZXB0aW9uIGUpIHsNCgkJCXNob3dJbmZvKCJDb3VsZCBub3QgcmVsb2FkICIrIHRlc3QudG9TdHJpbmcoKSk7DQoJCQlyZXR1cm47DQoJCX0NCgkJVGVzdFJlc3VsdCByZXN1bHQ9IG5ldyBUZXN0UmVzdWx0KCk7DQoJCXJlbG9hZGVkVGVzdC5ydW4ocmVzdWx0KTsNCg0KCQlTdHJpbmcgbWVzc2FnZT0gcmVsb2FkZWRUZXN0LnRvU3RyaW5nKCk7DQoJCWlmKHJlc3VsdC53YXNTdWNjZXNzZnVsKCkpDQoJCQlzaG93SW5mbyhtZXNzYWdlKyIgd2FzIHN1Y2Nlc3NmdWwiKTsNCgkJZWxzZSBpZiAocmVzdWx0LmVycm9yQ291bnQoKSA9PSAxKQ0KCQkJc2hvd1N0YXR1cyhtZXNzYWdlKyIgaGFkIGFuIGVycm9yIik7DQoJCWVsc2UNCgkJCXNob3dTdGF0dXMobWVzc2FnZSsiIGhhZCBhIGZhaWx1cmUiKTsNCgl9DQoNCglwcm90ZWN0ZWQgdm9pZCByZXNldCgpIHsNCgkJZkNvdW50ZXJQYW5lbC5yZXNldCgpOw0KCQlmUHJvZ3Jlc3NJbmRpY2F0b3IucmVzZXQoKTsNCgkJZlJlcnVuQnV0dG9uLnNldEVuYWJsZWQoZmFsc2UpOw0KCQlmRmFpbHVyZVZpZXcuY2xlYXIoKTsNCgkJZkZhaWx1cmVzLmNsZWFyKCk7DQoJfQ0KDQoJcHJvdGVjdGVkIHZvaWQgcnVuRmFpbGVkKFN0cmluZyBtZXNzYWdlKSB7DQoJCXNob3dTdGF0dXMobWVzc2FnZSk7DQoJCWZSdW4uc2V0VGV4dCgiUnVuIik7DQoJCWZSdW5uZXI9IG51bGw7DQoJfQ0KDQoJc3luY2hyb25pemVkIHB1YmxpYyB2b2lkIHJ1blN1aXRlKCkgew0KCQlpZiAoZlJ1bm5lciAhPSBudWxsKSB7DQoJCQlmVGVzdFJlc3VsdC5zdG9wKCk7DQoJCX0gZWxzZSB7DQoJCQlzZXRMb2FkaW5nKHNob3VsZFJlbG9hZCgpKTsNCgkJCXJlc2V0KCk7DQoJCQlzaG93SW5mbygiTG9hZCBUZXN0IENhc2UuLi4iKTsNCgkJCWZpbmFsIFN0cmluZyBzdWl0ZU5hbWU9IGdldFN1aXRlVGV4dCgpOw0KCQkJZmluYWwgVGVzdCB0ZXN0U3VpdGU9IGdldFRlc3Qoc3VpdGVOYW1lKTsNCgkJCWlmICh0ZXN0U3VpdGUgIT0gbnVsbCkgew0KCQkJCWFkZFRvSGlzdG9yeShzdWl0ZU5hbWUpOw0KCQkJCWRvUnVuVGVzdCh0ZXN0U3VpdGUpOw0KCQkJfQ0KCQl9DQoJfQ0KDQoJcHJpdmF0ZSBib29sZWFuIHNob3VsZFJlbG9hZCgpIHsNCgkJcmV0dXJuICFpblZBSmF2YSgpICYmIGZVc2VMb2FkaW5nUnVubmVyLmlzU2VsZWN0ZWQoKTsNCgl9DQoNCg0KCXN5bmNocm9uaXplZCBwcm90ZWN0ZWQgdm9pZCBydW5UZXN0KGZpbmFsIFRlc3QgdGVzdFN1aXRlKSB7DQoJCWlmIChmUnVubmVyICE9IG51bGwpIHsNCgkJCWZUZXN0UmVzdWx0LnN0b3AoKTsNCgkJfSBlbHNlIHsNCgkJCXJlc2V0KCk7DQoJCQlpZiAodGVzdFN1aXRlICE9IG51bGwpIHsNCgkJCQlkb1J1blRlc3QodGVzdFN1aXRlKTsNCgkJCX0NCgkJfQ0KCX0NCg0KCXByaXZhdGUgdm9pZCBkb1J1blRlc3QoZmluYWwgVGVzdCB0ZXN0U3VpdGUpIHsNCgkJc2V0QnV0dG9uTGFiZWwoZlJ1biwgIlN0b3AiKTsNCgkJZlJ1bm5lcj0gbmV3IFRocmVhZCgiVGVzdFJ1bm5lci1UaHJlYWQiKSB7DQoJCQlwdWJsaWMgdm9pZCBydW4oKSB7DQoJCQkJVGVzdFJ1bm5lci50aGlzLnN0YXJ0KHRlc3RTdWl0ZSk7DQoJCQkJcG9zdEluZm8oIlJ1bm5pbmcuLi4iKTsNCg0KCQkJCWxvbmcgc3RhcnRUaW1lPSBTeXN0ZW0uY3VycmVudFRpbWVNaWxsaXMoKTsNCgkJCQl0ZXN0U3VpdGUucnVuKGZUZXN0UmVzdWx0KTsNCg0KCQkJCWlmIChmVGVzdFJlc3VsdC5zaG91bGRTdG9wKCkpIHsNCgkJCQkJcG9zdFN0YXR1cygiU3RvcHBlZCIpOw0KCQkJCX0gZWxzZSB7DQoJCQkJCWxvbmcgZW5kVGltZT0gU3lzdGVtLmN1cnJlbnRUaW1lTWlsbGlzKCk7DQoJCQkJCWxvbmcgcnVuVGltZT0gZW5kVGltZS1zdGFydFRpbWU7DQoJCQkJCXBvc3RJbmZvKCJGaW5pc2hlZDogIiArIGVsYXBzZWRUaW1lQXNTdHJpbmcocnVuVGltZSkgKyAiIHNlY29uZHMiKTsNCgkJCQl9DQoJCQkJcnVuRmluaXNoZWQodGVzdFN1aXRlKTsNCgkJCQlzZXRCdXR0b25MYWJlbChmUnVuLCAiUnVuIik7DQoJCQkJZlJ1bm5lcj0gbnVsbDsNCgkJCQlTeXN0ZW0uZ2MoKTsNCgkJCX0NCgkJfTsNCgkJLy8gbWFrZSBzdXJlIHRoYXQgdGhlIHRlc3QgcmVzdWx0IGlzIGNyZWF0ZWQgYmVmb3JlIHdlIHN0YXJ0IHRoZQ0KCQkvLyB0ZXN0IHJ1bm5lciB0aHJlYWQgc28gdGhhdCBsaXN0ZW5lcnMgY2FuIHJlZ2lzdGVyIGZvciBpdC4NCgkJZlRlc3RSZXN1bHQ9IGNyZWF0ZVRlc3RSZXN1bHQoKTsNCgkJZlRlc3RSZXN1bHQuYWRkTGlzdGVuZXIoVGVzdFJ1bm5lci50aGlzKTsNCgkJYWJvdXRUb1N0YXJ0KHRlc3RTdWl0ZSk7DQoNCgkJZlJ1bm5lci5zdGFydCgpOw0KCX0NCg0KCXByaXZhdGUgdm9pZCBzYXZlSGlzdG9yeSgpIHRocm93cyBJT0V4Y2VwdGlvbiB7DQoJCUJ1ZmZlcmVkV3JpdGVyIGJ3PSBuZXcgQnVmZmVyZWRXcml0ZXIobmV3IEZpbGVXcml0ZXIoZ2V0U2V0dGluZ3NGaWxlKCkpKTsNCgkJdHJ5IHsNCgkJCWZvciAoaW50IGk9IDA7IGkgPCBmU3VpdGVDb21iby5nZXRJdGVtQ291bnQoKTsgaSsrKSB7DQoJCQkJU3RyaW5nIHRlc3RzdWl0ZT0gZlN1aXRlQ29tYm8uZ2V0SXRlbUF0KGkpLnRvU3RyaW5nKCk7DQoJCQkJYncud3JpdGUodGVzdHN1aXRlLCAwLCB0ZXN0c3VpdGUubGVuZ3RoKCkpOw0KCQkJCWJ3Lm5ld0xpbmUoKTsNCgkJCX0NCgkJfSBmaW5hbGx5IHsNCgkJCWJ3LmNsb3NlKCk7DQoJCX0NCgl9DQoNCglwcml2YXRlIHZvaWQgc2V0QnV0dG9uTGFiZWwoZmluYWwgSkJ1dHRvbiBidXR0b24sIGZpbmFsIFN0cmluZyBsYWJlbCkgew0KCQlTd2luZ1V0aWxpdGllcy5pbnZva2VMYXRlcigNCgkJCW5ldyBSdW5uYWJsZSgpIHsNCgkJCQlwdWJsaWMgdm9pZCBydW4oKSB7DQoJCQkJCWJ1dHRvbi5zZXRUZXh0KGxhYmVsKTsNCgkJCQl9DQoJCQl9DQoJCSk7DQoJfQ0KDQoJcHVibGljIHZvaWQgaGFuZGxlVGVzdFNlbGVjdGVkKFRlc3QgdGVzdCkgew0KCQlmUmVydW5CdXR0b24uc2V0RW5hYmxlZCh0ZXN0ICE9IG51bGwgJiYgKHRlc3QgaW5zdGFuY2VvZiBUZXN0Q2FzZSkpOw0KCQlzaG93RmFpbHVyZURldGFpbCh0ZXN0KTsNCgl9DQoNCglwcml2YXRlIHZvaWQgc2hvd0ZhaWx1cmVEZXRhaWwoVGVzdCB0ZXN0KSB7DQoJCWlmICh0ZXN0ICE9IG51bGwpIHsNCgkJCUxpc3RNb2RlbCBmYWlsdXJlcz0gZ2V0RmFpbHVyZXMoKTsNCgkJCWZvciAoaW50IGk9IDA7IGkgPCBmYWlsdXJlcy5nZXRTaXplKCk7IGkrKykgew0KCQkJCVRlc3RGYWlsdXJlIGZhaWx1cmU9IChUZXN0RmFpbHVyZSlmYWlsdXJlcy5nZXRFbGVtZW50QXQoaSk7DQoJCQkJaWYgKGZhaWx1cmUuZmFpbGVkVGVzdCgpID09IHRlc3QpIHsNCgkJCQkJZkZhaWx1cmVWaWV3LnNob3dGYWlsdXJlKGZhaWx1cmUpOw0KCQkJCQlyZXR1cm47DQoJCQkJfQ0KCQkJfQ0KCQl9DQoJCWZGYWlsdXJlVmlldy5jbGVhcigpOw0KCX0NCg0KCXByaXZhdGUgdm9pZCBzaG93SW5mbyhTdHJpbmcgbWVzc2FnZSkgew0KCQlmU3RhdHVzTGluZS5zaG93SW5mbyhtZXNzYWdlKTsNCgl9DQoNCglwcml2YXRlIHZvaWQgc2hvd1N0YXR1cyhTdHJpbmcgc3RhdHVzKSB7DQoJCWZTdGF0dXNMaW5lLnNob3dFcnJvcihzdGF0dXMpOw0KCX0NCg0KCS8qKg0KCSAqIFN0YXJ0cyB0aGUgVGVzdFJ1bm5lcg0KCSAqLw0KCXB1YmxpYyB2b2lkIHN0YXJ0KFN0cmluZ1tdIGFyZ3MpIHsNCgkJU3RyaW5nIHN1aXRlTmFtZT0gcHJvY2Vzc0FyZ3VtZW50cyhhcmdzKTsNCgkJZkZyYW1lPSBjcmVhdGVVSShzdWl0ZU5hbWUpOw0KCQlmRnJhbWUucGFjaygpOw0KCQlmRnJhbWUuc2V0VmlzaWJsZSh0cnVlKTsNCg0KCQlpZiAoc3VpdGVOYW1lICE9IG51bGwpIHsNCgkJCXNldFN1aXRlKHN1aXRlTmFtZSk7DQoJCQlydW5TdWl0ZSgpOw0KCQl9DQoJfQ0KDQoJcHJpdmF0ZSB2b2lkIHN0YXJ0KGZpbmFsIFRlc3QgdGVzdCkgew0KCQlTd2luZ1V0aWxpdGllcy5pbnZva2VMYXRlcigNCgkJCW5ldyBSdW5uYWJsZSgpIHsNCgkJCQlwdWJsaWMgdm9pZCBydW4oKSB7DQoJCQkJCWludCB0b3RhbD0gdGVzdC5jb3VudFRlc3RDYXNlcygpOw0KCQkJCQlmUHJvZ3Jlc3NJbmRpY2F0b3Iuc3RhcnQodG90YWwpOw0KCQkJCQlmQ291bnRlclBhbmVsLnNldFRvdGFsKHRvdGFsKTsNCgkJCQl9DQoJCQl9DQoJCSk7DQoJfQ0KDQoJLyoqDQoJICogV2FpdCB1bnRpbCBhbGwgdGhlIGV2ZW50cyBhcmUgcHJvY2Vzc2VkIGluIHRoZSBldmVudCB0aHJlYWQNCgkgKi8NCglwcml2YXRlIHZvaWQgc3luY2hVSSgpIHsNCgkJdHJ5IHsNCgkJCVN3aW5nVXRpbGl0aWVzLmludm9rZUFuZFdhaXQoDQoJCQkJbmV3IFJ1bm5hYmxlKCkgew0KCQkJCQlwdWJsaWMgdm9pZCBydW4oKSB7fQ0KCQkJCX0NCgkJCSk7DQoJCX0NCgkJY2F0Y2ggKEV4Y2VwdGlvbiBlKSB7DQoJCX0NCgl9DQoNCgkvKioNCgkgKiBUZXJtaW5hdGVzIHRoZSBUZXN0UnVubmVyDQoJICovDQoJcHVibGljIHZvaWQgdGVybWluYXRlKCkgew0KCQlmRnJhbWUuZGlzcG9zZSgpOw0KCQl0cnkgew0KCQkJc2F2ZUhpc3RvcnkoKTsNCgkJfSBjYXRjaCAoSU9FeGNlcHRpb24gZSkgew0KCQkJU3lzdGVtLm91dC5wcmludGxuKCJDb3VsZG4ndCBzYXZlIHRlc3QgcnVuIGhpc3RvcnkiKTsNCgkJfQ0KCQlTeXN0ZW0uZXhpdCgwKTsNCgl9DQoNCglwdWJsaWMgdm9pZCB0ZXh0Q2hhbmdlZCgpIHsNCgkJZlJ1bi5zZXRFbmFibGVkKGdldFN1aXRlVGV4dCgpLmxlbmd0aCgpID4gMCk7DQoJCWNsZWFyU3RhdHVzKCk7DQoJfQ0KDQoJcHJvdGVjdGVkIHZvaWQgY2xlYXJTdGF0dXMoKSB7DQoJCWZTdGF0dXNMaW5lLmNsZWFyKCk7DQoJfQ0KDQoJcHVibGljIHN0YXRpYyBJY29uIGdldEljb25SZXNvdXJjZShDbGFzcyBjbGF6eiwgU3RyaW5nIG5hbWUpIHsNCgkJVVJMIHVybD0gY2xhenouZ2V0UmVzb3VyY2UobmFtZSk7DQoJCWlmICh1cmwgPT0gbnVsbCkgew0KCQkJU3lzdGVtLmVyci5wcmludGxuKCJXYXJuaW5nOiBjb3VsZCBub3QgbG9hZCBcIiIrbmFtZSsiXCIgaWNvbiIpOw0KCQkJcmV0dXJuIG51bGw7DQoJCX0NCgkJcmV0dXJuIG5ldyBJbWFnZUljb24odXJsKTsNCgl9DQoNCglwcml2YXRlIHZvaWQgYWJvdXQoKSB7DQoJCUFib3V0RGlhbG9nIGFib3V0PSBuZXcgQWJvdXREaWFsb2coZkZyYW1lKTsNCgkJYWJvdXQuc2hvdygpOw0KCX0NCn1QSwMECgAAAAAA6njHMNmlBGupBwAAqQcAACcAAABqdW5pdC9zd2luZ3VpL1Rlc3RIaWVyYXJjaHlSdW5WaWV3LmphdmFwYWNrYWdlIGp1bml0LnN3aW5ndWk7DQoNCmltcG9ydCBqYXZhLnV0aWwuVmVjdG9yOw0KDQppbXBvcnQgamF2YXguc3dpbmcuKjsNCmltcG9ydCBqYXZheC5zd2luZy5ldmVudC4qOw0KaW1wb3J0IGphdmF4LnN3aW5nLnRyZWUuVHJlZVBhdGg7DQppbXBvcnQganVuaXQuZnJhbWV3b3JrLio7DQoNCi8qKg0KICogQSBoaWVyYXJjaGljYWwgdmlldyBvZiBhIHRlc3QgcnVuLg0KICogVGhlIGNvbnRlbnRzIG9mIGEgdGVzdCBzdWl0ZSBpcyBzaG93bg0KICogYXMgYSB0cmVlLg0KICovDQpwdWJsaWMgY2xhc3MgVGVzdEhpZXJhcmNoeVJ1blZpZXcgaW1wbGVtZW50cyBUZXN0UnVuVmlldyB7DQoJVGVzdFN1aXRlUGFuZWwgZlRyZWVCcm93c2VyOw0KCVRlc3RSdW5Db250ZXh0IGZUZXN0Q29udGV4dDsNCgkNCglwdWJsaWMgVGVzdEhpZXJhcmNoeVJ1blZpZXcoVGVzdFJ1bkNvbnRleHQgY29udGV4dCkgew0KCQlmVGVzdENvbnRleHQ9IGNvbnRleHQ7DQoJCWZUcmVlQnJvd3Nlcj0gbmV3IFRlc3RTdWl0ZVBhbmVsKCk7DQoJCWZUcmVlQnJvd3Nlci5nZXRUcmVlKCkuYWRkVHJlZVNlbGVjdGlvbkxpc3RlbmVyKA0KCQkJbmV3IFRyZWVTZWxlY3Rpb25MaXN0ZW5lcigpIHsNCgkJCQlwdWJsaWMgdm9pZCB2YWx1ZUNoYW5nZWQoVHJlZVNlbGVjdGlvbkV2ZW50IGUpIHsNCgkJCQkJdGVzdFNlbGVjdGVkKCk7DQoJCQkJfQ0KCQkJfQ0KCQkpOw0KCX0NCgkNCglwdWJsaWMgdm9pZCBhZGRUYWIoSlRhYmJlZFBhbmUgcGFuZSkgeyANCgkJSWNvbiB0cmVlSWNvbj0gVGVzdFJ1bm5lci5nZXRJY29uUmVzb3VyY2UoZ2V0Q2xhc3MoKSwgImljb25zL2hpZXJhcmNoeS5naWYiKTsNCgkJcGFuZS5hZGRUYWIoIlRlc3QgSGllcmFyY2h5IiwgdHJlZUljb24sIGZUcmVlQnJvd3NlciwgIlRoZSB0ZXN0IGhpZXJhcmNoeSIpOw0KCX0NCgkNCglwdWJsaWMgVGVzdCBnZXRTZWxlY3RlZFRlc3QoKSB7DQoJCXJldHVybiBmVHJlZUJyb3dzZXIuZ2V0U2VsZWN0ZWRUZXN0KCk7DQoJfQ0KCQ0KCXB1YmxpYyB2b2lkIGFjdGl2YXRlKCkgew0KCQl0ZXN0U2VsZWN0ZWQoKTsNCgl9DQoJDQoJcHVibGljIHZvaWQgcmV2ZWFsRmFpbHVyZShUZXN0IGZhaWx1cmUpIHsNCgkJSlRyZWUgdHJlZT0gZlRyZWVCcm93c2VyLmdldFRyZWUoKTsNCgkJVGVzdFRyZWVNb2RlbCBtb2RlbD0gKFRlc3RUcmVlTW9kZWwpdHJlZS5nZXRNb2RlbCgpOw0KCQlWZWN0b3IgdnBhdGg9IG5ldyBWZWN0b3IoKTsNCgkJaW50IGluZGV4PSBtb2RlbC5maW5kVGVzdChmYWlsdXJlLCAoVGVzdCltb2RlbC5nZXRSb290KCksIHZwYXRoKTsNCgkJaWYgKGluZGV4ID49IDApIHsNCgkJCU9iamVjdFtdIHBhdGg9IG5ldyBPYmplY3RbdnBhdGguc2l6ZSgpKzFdOw0KCQkJdnBhdGguY29weUludG8ocGF0aCk7DQoJCQlPYmplY3QgbGFzdD0gcGF0aFt2cGF0aC5zaXplKCktMV07DQoJCQlwYXRoW3ZwYXRoLnNpemUoKV09IG1vZGVsLmdldENoaWxkKGxhc3QsIGluZGV4KTsNCgkJCVRyZWVQYXRoIHNlbGVjdGlvblBhdGg9IG5ldyBUcmVlUGF0aChwYXRoKTsNCgkJCXRyZWUuc2V0U2VsZWN0aW9uUGF0aChzZWxlY3Rpb25QYXRoKTsNCgkJCXRyZWUubWFrZVZpc2libGUoc2VsZWN0aW9uUGF0aCk7DQoJCX0NCgl9DQoJDQoJcHVibGljIHZvaWQgYWJvdXRUb1N0YXJ0KFRlc3Qgc3VpdGUsIFRlc3RSZXN1bHQgcmVzdWx0KSB7DQoJCWZUcmVlQnJvd3Nlci5zaG93VGVzdFRyZWUoc3VpdGUpOw0KCQlyZXN1bHQuYWRkTGlzdGVuZXIoZlRyZWVCcm93c2VyKTsNCgl9DQoNCglwdWJsaWMgdm9pZCBydW5GaW5pc2hlZChUZXN0IHN1aXRlLCBUZXN0UmVzdWx0IHJlc3VsdCkgew0KCQlyZXN1bHQucmVtb3ZlTGlzdGVuZXIoZlRyZWVCcm93c2VyKTsNCgl9DQoNCglwcm90ZWN0ZWQgdm9pZCB0ZXN0U2VsZWN0ZWQoKSB7DQoJCWZUZXN0Q29udGV4dC5oYW5kbGVUZXN0U2VsZWN0ZWQoZ2V0U2VsZWN0ZWRUZXN0KCkpOw0KCX0NCn0NClBLAwQKAAAAAADqeMcwgW3L7BkRAAAZEQAAIAAAAGp1bml0L3N3aW5ndWkvVGVzdFRyZWVNb2RlbC5qYXZhcGFja2FnZSBqdW5pdC5zd2luZ3VpOw0KDQppbXBvcnQgamF2YS51dGlsLio7DQoNCmltcG9ydCBqYXZheC5zd2luZy5ldmVudC4qOw0KaW1wb3J0IGphdmF4LnN3aW5nLnRyZWUuKjsNCmltcG9ydCBqdW5pdC5leHRlbnNpb25zLlRlc3REZWNvcmF0b3I7DQppbXBvcnQganVuaXQuZnJhbWV3b3JrLio7DQoNCi8qKg0KICogQSB0cmVlIG1vZGVsIGZvciBhIFRlc3QuDQogKi8NCmNsYXNzIFRlc3RUcmVlTW9kZWwgaW1wbGVtZW50cyBUcmVlTW9kZWwgew0KCXByaXZhdGUgVGVzdCBmUm9vdDsNCglwcml2YXRlIFZlY3RvciBmTW9kZWxMaXN0ZW5lcnM9IG5ldyBWZWN0b3IoKTsNCglwcml2YXRlIEhhc2h0YWJsZSBmRmFpbHVyZXM9IG5ldyBIYXNodGFibGUoKTsNCglwcml2YXRlIEhhc2h0YWJsZSBmRXJyb3JzPSBuZXcgSGFzaHRhYmxlKCk7DQoJcHJpdmF0ZSBIYXNodGFibGUgZlJ1blRlc3RzPSBuZXcgSGFzaHRhYmxlKCk7DQoJDQoJLyoqDQoJICogQ29uc3RydWN0cyBhIHRyZWUgbW9kZWwgd2l0aCB0aGUgZ2l2ZW4gdGVzdCBhcyBpdHMgcm9vdC4NCgkgKi8NCglwdWJsaWMgVGVzdFRyZWVNb2RlbChUZXN0IHJvb3QpIHsNCgkJc3VwZXIoKTsNCgkJZlJvb3Q9IHJvb3Q7DQoJfQ0KCQ0KCS8qKg0KCSAqIGFkZHMgYSBUcmVlTW9kZWxMaXN0ZW5lcg0KCSAqLw0KCXB1YmxpYyB2b2lkIGFkZFRyZWVNb2RlbExpc3RlbmVyKFRyZWVNb2RlbExpc3RlbmVyIGwpIHsNCgkJaWYgKCFmTW9kZWxMaXN0ZW5lcnMuY29udGFpbnMobCkpDQoJCQlmTW9kZWxMaXN0ZW5lcnMuYWRkRWxlbWVudChsKTsNCgl9DQoJLyoqDQoJICogUmVtb3ZlcyBhIFRlc3RNb2RlbExpc3RlbmVyDQoJICovDQoJcHVibGljIHZvaWQgcmVtb3ZlVHJlZU1vZGVsTGlzdGVuZXIoVHJlZU1vZGVsTGlzdGVuZXIgbCkgew0KCQlmTW9kZWxMaXN0ZW5lcnMucmVtb3ZlRWxlbWVudChsKTsNCgl9DQoJLyoqDQoJICogRmluZHMgdGhlIHBhdGggdG8gYSB0ZXN0LiBSZXR1cm5zIHRoZSBpbmRleCBvZiB0aGUgdGVzdCBpbiBpdHMNCgkgKiBwYXJlbnQgdGVzdCBzdWl0ZS4NCgkgKi8NCglwdWJsaWMgaW50IGZpbmRUZXN0KFRlc3QgdGFyZ2V0LCBUZXN0IG5vZGUsIFZlY3RvciBwYXRoKSB7DQoJCWlmICh0YXJnZXQuZXF1YWxzKG5vZGUpKSANCgkJCXJldHVybiAwOw0KCQkJDQoJCVRlc3RTdWl0ZSBzdWl0ZT0gaXNUZXN0U3VpdGUobm9kZSk7DQoJCWZvciAoaW50IGk9IDA7IGkgPCBnZXRDaGlsZENvdW50KG5vZGUpOyBpKyspIHsNCgkJCVRlc3QgdD0gc3VpdGUudGVzdEF0KGkpOyANCgkJCWludCBpbmRleD0gZmluZFRlc3QodGFyZ2V0LCB0LCBwYXRoKTsNCgkJCWlmIChpbmRleCA+PSAwKSB7DQoJCQkJcGF0aC5pbnNlcnRFbGVtZW50QXQobm9kZSwgMCk7DQoJCQkJaWYgKHBhdGguc2l6ZSgpID09IDEpDQoJCQkJCXJldHVybiBpOw0KCQkJCXJldHVybiBpbmRleDsNCgkJCX0NCgkJfQ0KCQlyZXR1cm4gLTE7DQoJfQ0KCS8qKg0KCSAqIEZpcmVzIGEgbm9kZSBjaGFuZ2VkIGV2ZW50DQoJICovDQoJcHVibGljIHZvaWQgZmlyZU5vZGVDaGFuZ2VkKFRyZWVQYXRoIHBhdGgsIGludCBpbmRleCkgew0KCQlpbnRbXSBpbmRpY2VzPSB7aW5kZXh9Ow0KCQlPYmplY3RbXSBjaGFuZ2VkQ2hpbGRyZW49IHtnZXRDaGlsZChwYXRoLmdldExhc3RQYXRoQ29tcG9uZW50KCksIGluZGV4KX07DQoJCVRyZWVNb2RlbEV2ZW50IGV2ZW50PSBuZXcgVHJlZU1vZGVsRXZlbnQodGhpcywgcGF0aCwgaW5kaWNlcywgY2hhbmdlZENoaWxkcmVuKTsNCgkJDQoJCUVudW1lcmF0aW9uIGU9IGZNb2RlbExpc3RlbmVycy5lbGVtZW50cygpOw0KCQl3aGlsZSAoZS5oYXNNb3JlRWxlbWVudHMoKSkgeyANCgkJCVRyZWVNb2RlbExpc3RlbmVyIGw9IChUcmVlTW9kZWxMaXN0ZW5lcikgZS5uZXh0RWxlbWVudCgpOw0KCQkJbC50cmVlTm9kZXNDaGFuZ2VkKGV2ZW50KTsNCgkJfQkNCgl9DQoJLyoqDQoJICogR2V0cyB0aGUgdGVzdCBhdCB0aGUgZ2l2ZW4gaW5kZXgNCgkgKi8NCglwdWJsaWMgT2JqZWN0IGdldENoaWxkKE9iamVjdCBwYXJlbnQsIGludCBpbmRleCkgew0KCQlUZXN0U3VpdGUgc3VpdGU9IGlzVGVzdFN1aXRlKHBhcmVudCk7DQoJCWlmIChzdWl0ZSAhPSBudWxsKSANCgkJCXJldHVybiBzdWl0ZS50ZXN0QXQoaW5kZXgpOw0KCQlyZXR1cm4gbnVsbDsgDQoJfQ0KCS8qKg0KCSAqIEdldHMgdGhlIG51bWJlciBvZiB0ZXN0cy4NCgkgKi8NCglwdWJsaWMgaW50IGdldENoaWxkQ291bnQoT2JqZWN0IHBhcmVudCkgew0KCQlUZXN0U3VpdGUgc3VpdGU9IGlzVGVzdFN1aXRlKHBhcmVudCk7DQoJCWlmIChzdWl0ZSAhPSBudWxsKSANCgkJCXJldHVybiBzdWl0ZS50ZXN0Q291bnQoKTsNCgkJcmV0dXJuIDA7DQoJfQ0KCS8qKg0KCSAqIEdldHMgdGhlIGluZGV4IG9mIGEgdGVzdCBpbiBhIHRlc3Qgc3VpdGUNCgkgKi8NCglwdWJsaWMgaW50IGdldEluZGV4T2ZDaGlsZChPYmplY3QgcGFyZW50LCBPYmplY3QgY2hpbGQpIHsNCgkJVGVzdFN1aXRlIHN1aXRlPSBpc1Rlc3RTdWl0ZShwYXJlbnQpOw0KCQlpZiAoc3VpdGUgIT0gbnVsbCkgew0KCQkJaW50IGk9IDA7DQoJCQlmb3IgKEVudW1lcmF0aW9uIGU9IHN1aXRlLnRlc3RzKCk7IGUuaGFzTW9yZUVsZW1lbnRzKCk7IGkrKykgew0KCQkJCWlmIChjaGlsZC5lcXVhbHMoKFRlc3QpZS5uZXh0RWxlbWVudCgpKSkNCgkJCQkJcmV0dXJuIGk7DQoJCQl9DQoJCX0NCgkJcmV0dXJuIC0xOyANCgl9DQoJLyoqDQoJICogUmV0dXJucyB0aGUgcm9vdCBvZiB0aGUgdHJlZQ0KCSAqLw0KCXB1YmxpYyBPYmplY3QgZ2V0Um9vdCgpIHsNCgkJcmV0dXJuIGZSb290Ow0KCX0NCgkvKioNCgkgKiBUZXN0cyBpZiB0aGUgdGVzdCBpcyBhIGxlYWYuDQoJICovDQoJcHVibGljIGJvb2xlYW4gaXNMZWFmKE9iamVjdCBub2RlKSB7DQoJCXJldHVybiBpc1Rlc3RTdWl0ZShub2RlKSA9PSBudWxsOw0KCX0NCgkvKioNCgkgKiBUZXN0cyBpZiB0aGUgbm9kZSBpcyBhIFRlc3RTdWl0ZS4NCgkgKi8NCglUZXN0U3VpdGUgaXNUZXN0U3VpdGUoT2JqZWN0IG5vZGUpIHsNCgkJaWYgKG5vZGUgaW5zdGFuY2VvZiBUZXN0U3VpdGUpIA0KCQkJcmV0dXJuIChUZXN0U3VpdGUpbm9kZTsNCgkJaWYgKG5vZGUgaW5zdGFuY2VvZiBUZXN0RGVjb3JhdG9yKSB7IA0KCQkJVGVzdCBiYXNlVGVzdD0gKChUZXN0RGVjb3JhdG9yKW5vZGUpLmdldFRlc3QoKTsgDQoJCQlyZXR1cm4gaXNUZXN0U3VpdGUoYmFzZVRlc3QpOyANCgkJfSANCgkJcmV0dXJuIG51bGw7DQoJfQ0KCQ0KCS8qKg0KCSAqIENhbGxlZCB3aGVuIHRoZSB2YWx1ZSBvZiB0aGUgbW9kZWwgb2JqZWN0IHdhcyBjaGFuZ2VkIGluIHRoZSB2aWV3DQoJICovDQoJcHVibGljIHZvaWQgdmFsdWVGb3JQYXRoQ2hhbmdlZChUcmVlUGF0aCBwYXRoLCBPYmplY3QgbmV3VmFsdWUpIHsNCgkJLy8gd2UgZG9uJ3Qgc3VwcG9ydCBkaXJlY3QgZWRpdGluZyBvZiB0aGUgbW9kZWwNCgkJU3lzdGVtLm91dC5wcmludGxuKCJUcmVlTW9kZWwudmFsdWVGb3JQYXRoQ2hhbmdlZDogbm90IGltcGxlbWVudGVkIik7DQoJfQ0KCS8qKg0KCSAqIFJlbWVtYmVycyBhIHRlc3QgZmFpbHVyZQ0KCSAqLw0KCXZvaWQgYWRkRmFpbHVyZShUZXN0IHQpIHsNCgkJZkZhaWx1cmVzLnB1dCh0LCB0KTsNCgl9DQoJLyoqDQoJICogUmVtZW1iZXJzIGEgdGVzdCBlcnJvcg0KCSAqLw0KCXZvaWQgYWRkRXJyb3IoVGVzdCB0KSB7DQoJCWZFcnJvcnMucHV0KHQsIHQpOw0KCX0NCgkvKioNCgkgKiBSZW1lbWJlcnMgdGhhdCBhIHRlc3Qgd2FzIHJ1bg0KCSAqLw0KCXZvaWQgYWRkUnVuVGVzdChUZXN0IHQpIHsNCgkJZlJ1blRlc3RzLnB1dCh0LCB0KTsNCgl9DQoJLyoqDQoJICogUmV0dXJucyB3aGV0aGVyIGEgdGVzdCB3YXMgcnVuDQoJICovDQoJYm9vbGVhbiB3YXNSdW4oVGVzdCB0KSB7DQoJCXJldHVybiBmUnVuVGVzdHMuZ2V0KHQpICE9IG51bGw7DQoJfQ0KCS8qKg0KCSAqIFRlc3RzIHdoZXRoZXIgYSB0ZXN0IHdhcyBhbiBlcnJvcg0KCSAqLw0KCWJvb2xlYW4gaXNFcnJvcihUZXN0IHQpIHsNCgkJcmV0dXJuIChmRXJyb3JzICE9IG51bGwpICYmIGZFcnJvcnMuZ2V0KHQpICE9IG51bGw7DQoJfQ0KCS8qKg0KCSAqIFRlc3RzIHdoZXRoZXIgYSB0ZXN0IHdhcyBhIGZhaWx1cmUNCgkgKi8NCglib29sZWFuIGlzRmFpbHVyZShUZXN0IHQpIHsNCgkJcmV0dXJuIChmRmFpbHVyZXMgIT0gbnVsbCkgJiYgZkZhaWx1cmVzLmdldCh0KSAhPSBudWxsOw0KCX0NCgkvKioNCgkgKiBSZXNldHMgdGhlIHRlc3QgcmVzdWx0cw0KCSAqLw0KCXZvaWQgcmVzZXRSZXN1bHRzKCkgew0KCQlmRmFpbHVyZXM9IG5ldyBIYXNodGFibGUoKTsNCgkJZlJ1blRlc3RzPSBuZXcgSGFzaHRhYmxlKCk7DQoJCWZFcnJvcnM9IG5ldyBIYXNodGFibGUoKTsNCgl9DQp9UEsDBAoAAAAAAOp4xzAnuTF9cg0AAHINAAAfAAAAanVuaXQvc3dpbmd1aS9Db3VudGVyUGFuZWwuamF2YXBhY2thZ2UganVuaXQuc3dpbmd1aTsNCg0KaW1wb3J0IGphdmEuYXd0Lio7DQoNCmltcG9ydCBqYXZheC5zd2luZy4qOw0KDQovKioNCiAqIEEgcGFuZWwgd2l0aCB0ZXN0IHJ1biBjb3VudGVycw0KICovDQpwdWJsaWMgY2xhc3MgQ291bnRlclBhbmVsIGV4dGVuZHMgSlBhbmVsIHsNCglwcml2YXRlIEpUZXh0RmllbGQgZk51bWJlck9mRXJyb3JzOw0KCXByaXZhdGUgSlRleHRGaWVsZCBmTnVtYmVyT2ZGYWlsdXJlczsNCglwcml2YXRlIEpUZXh0RmllbGQgZk51bWJlck9mUnVuczsNCglwcml2YXRlIEljb24gZkZhaWx1cmVJY29uPSBUZXN0UnVubmVyLmdldEljb25SZXNvdXJjZShnZXRDbGFzcygpLCAiaWNvbnMvZmFpbHVyZS5naWYiKTsNCglwcml2YXRlIEljb24gZkVycm9ySWNvbj0gVGVzdFJ1bm5lci5nZXRJY29uUmVzb3VyY2UoZ2V0Q2xhc3MoKSwgImljb25zL2Vycm9yLmdpZiIpOw0KDQoJcHJpdmF0ZSBpbnQgZlRvdGFsOw0KDQoJcHVibGljIENvdW50ZXJQYW5lbCgpIHsNCgkJc3VwZXIobmV3IEdyaWRCYWdMYXlvdXQoKSk7DQoJCWZOdW1iZXJPZkVycm9ycz0gY3JlYXRlT3V0cHV0RmllbGQoNSk7DQoJCWZOdW1iZXJPZkZhaWx1cmVzPSBjcmVhdGVPdXRwdXRGaWVsZCg1KTsNCgkJZk51bWJlck9mUnVucz0gY3JlYXRlT3V0cHV0RmllbGQoOSk7DQoNCiAgICAgIGFkZFRvR3JpZChuZXcgSkxhYmVsKCJSdW5zOiIsIEpMYWJlbC5DRU5URVIpLA0KICAgICAgICAgIDAsIDAsIDEsIDEsIDAuMCwgMC4wLA0KICAgICAgICAgIEdyaWRCYWdDb25zdHJhaW50cy5DRU5URVIsIEdyaWRCYWdDb25zdHJhaW50cy5OT05FLA0KICAgICAgICAgIG5ldyBJbnNldHMoMCwgMCwgMCwgMCkpOw0KICAgICBhZGRUb0dyaWQoZk51bWJlck9mUnVucywNCiAgICAgICAgICAxLCAwLCAxLCAxLCAwLjMzLCAwLjAsDQogICAgICAgICAgR3JpZEJhZ0NvbnN0cmFpbnRzLkNFTlRFUiwgR3JpZEJhZ0NvbnN0cmFpbnRzLkhPUklaT05UQUwsDQogICAgICAgICAgbmV3IEluc2V0cygwLCA4LCAwLCAwKSk7DQoNCiAgICAgYWRkVG9HcmlkKG5ldyBKTGFiZWwoIkVycm9yczoiLCBmRXJyb3JJY29uLCBTd2luZ0NvbnN0YW50cy5MRUZUKSwNCiAgICAgICAgICAyLCAwLCAxLCAxLCAwLjAsIDAuMCwNCiAgICAgICAgICBHcmlkQmFnQ29uc3RyYWludHMuQ0VOVEVSLCBHcmlkQmFnQ29uc3RyYWludHMuTk9ORSwNCiAgICAgICAgICBuZXcgSW5zZXRzKDAsIDgsIDAsIDApKTsNCiAgICAgIGFkZFRvR3JpZChmTnVtYmVyT2ZFcnJvcnMsDQogICAgICAgICAgMywgMCwgMSwgMSwgMC4zMywgMC4wLA0KICAgICAgICAgIEdyaWRCYWdDb25zdHJhaW50cy5DRU5URVIsIEdyaWRCYWdDb25zdHJhaW50cy5IT1JJWk9OVEFMLA0KICAgICAgICAgIG5ldyBJbnNldHMoMCwgOCwgMCwgMCkpOw0KDQogICAgICBhZGRUb0dyaWQobmV3IEpMYWJlbCgiRmFpbHVyZXM6IiwgZkZhaWx1cmVJY29uLCBTd2luZ0NvbnN0YW50cy5MRUZUKSwNCiAgICAgICAgICA0LCAwLCAxLCAxLCAwLjAsIDAuMCwNCiAgICAgICAgICBHcmlkQmFnQ29uc3RyYWludHMuQ0VOVEVSLCBHcmlkQmFnQ29uc3RyYWludHMuTk9ORSwNCiAgICAgICAgICBuZXcgSW5zZXRzKDAsIDgsIDAsIDApKTsNCiAgICAgIGFkZFRvR3JpZChmTnVtYmVyT2ZGYWlsdXJlcywNCiAgICAgICAgICA1LCAwLCAxLCAxLCAwLjMzLCAwLjAsDQogICAgICAgICAgR3JpZEJhZ0NvbnN0cmFpbnRzLkNFTlRFUiwgR3JpZEJhZ0NvbnN0cmFpbnRzLkhPUklaT05UQUwsDQogICAgICAgICAgbmV3IEluc2V0cygwLCA4LCAwLCAwKSk7DQoJfQ0KDQoJcHJpdmF0ZSBKVGV4dEZpZWxkIGNyZWF0ZU91dHB1dEZpZWxkKGludCB3aWR0aCkgew0KCQlKVGV4dEZpZWxkIGZpZWxkPSBuZXcgSlRleHRGaWVsZCgiMCIsIHdpZHRoKTsNCgkJLy8gZm9yY2UgYSBmaXhlZCBsYXlvdXQgdG8gYXZvaWQgYWNjaWRlbnRhbCBoaWRpbmcgb24gcmVsYXlvdXQNCgkJZmllbGQuc2V0TWluaW11bVNpemUoZmllbGQuZ2V0UHJlZmVycmVkU2l6ZSgpKTsNCgkJZmllbGQuc2V0TWF4aW11bVNpemUoZmllbGQuZ2V0UHJlZmVycmVkU2l6ZSgpKTsNCgkJZmllbGQuc2V0SG9yaXpvbnRhbEFsaWdubWVudChKVGV4dEZpZWxkLkxFRlQpOw0KCQlmaWVsZC5zZXRGb250KFN0YXR1c0xpbmUuQk9MRF9GT05UKTsNCgkJZmllbGQuc2V0RWRpdGFibGUoZmFsc2UpOw0KCQlmaWVsZC5zZXRCb3JkZXIoQm9yZGVyRmFjdG9yeS5jcmVhdGVFbXB0eUJvcmRlcigpKTsNCgkJcmV0dXJuIGZpZWxkOw0KCX0NCg0KCXB1YmxpYyB2b2lkIGFkZFRvR3JpZChDb21wb25lbnQgY29tcCwNCgkgICAgCWludCBncmlkeCwgaW50IGdyaWR5LCBpbnQgZ3JpZHdpZHRoLCBpbnQgZ3JpZGhlaWdodCwNCgkJCWRvdWJsZSB3ZWlnaHR4LCBkb3VibGUgd2VpZ2h0eSwNCgkJCWludCBhbmNob3IsIGludCBmaWxsLA0KCQkJSW5zZXRzIGluc2V0cykgew0KDQoJCUdyaWRCYWdDb25zdHJhaW50cyBjb25zdHJhaW50cz0gbmV3IEdyaWRCYWdDb25zdHJhaW50cygpOw0KCQljb25zdHJhaW50cy5ncmlkeD0gZ3JpZHg7DQoJCWNvbnN0cmFpbnRzLmdyaWR5PSBncmlkeTsNCgkJY29uc3RyYWludHMuZ3JpZHdpZHRoPSBncmlkd2lkdGg7DQoJCWNvbnN0cmFpbnRzLmdyaWRoZWlnaHQ9IGdyaWRoZWlnaHQ7DQoJCWNvbnN0cmFpbnRzLndlaWdodHg9IHdlaWdodHg7DQoJCWNvbnN0cmFpbnRzLndlaWdodHk9IHdlaWdodHk7DQoJCWNvbnN0cmFpbnRzLmFuY2hvcj0gYW5jaG9yOw0KCQljb25zdHJhaW50cy5maWxsPSBmaWxsOw0KCQljb25zdHJhaW50cy5pbnNldHM9IGluc2V0czsNCgkJYWRkKGNvbXAsIGNvbnN0cmFpbnRzKTsNCgl9DQoNCglwdWJsaWMgdm9pZCByZXNldCgpIHsNCgkJc2V0TGFiZWxWYWx1ZShmTnVtYmVyT2ZFcnJvcnMsIDApOw0KCQlzZXRMYWJlbFZhbHVlKGZOdW1iZXJPZkZhaWx1cmVzLCAwKTsNCgkJc2V0TGFiZWxWYWx1ZShmTnVtYmVyT2ZSdW5zLCAwKTsNCgkJZlRvdGFsPSAwOw0KCX0NCg0KCXB1YmxpYyB2b2lkIHNldFRvdGFsKGludCB2YWx1ZSkgew0KCQlmVG90YWw9IHZhbHVlOw0KCX0NCg0KCXB1YmxpYyB2b2lkIHNldFJ1blZhbHVlKGludCB2YWx1ZSkgew0KCQlmTnVtYmVyT2ZSdW5zLnNldFRleHQoSW50ZWdlci50b1N0cmluZyh2YWx1ZSkgKyAiLyIgKyBmVG90YWwpOw0KCX0NCg0KCXB1YmxpYyB2b2lkIHNldEVycm9yVmFsdWUoaW50IHZhbHVlKSB7DQoJCXNldExhYmVsVmFsdWUoZk51bWJlck9mRXJyb3JzLCB2YWx1ZSk7DQoJfQ0KDQoJcHVibGljIHZvaWQgc2V0RmFpbHVyZVZhbHVlKGludCB2YWx1ZSkgew0KCQlzZXRMYWJlbFZhbHVlKGZOdW1iZXJPZkZhaWx1cmVzLCB2YWx1ZSk7DQoJfQ0KDQoJcHJpdmF0ZSB2b2lkIHNldExhYmVsVmFsdWUoSlRleHRGaWVsZCBsYWJlbCwgaW50IHZhbHVlKSB7DQoJCWxhYmVsLnNldFRleHQoSW50ZWdlci50b1N0cmluZyh2YWx1ZSkpOw0KCX0NCn1QSwMECgAAAAAA6njHMGX1s76qAwAAqgMAAB4AAABqdW5pdC9zd2luZ3VpL1Rlc3RSdW5WaWV3LmphdmFwYWNrYWdlIGp1bml0LnN3aW5ndWk7DQoNCmltcG9ydCBqYXZheC5zd2luZy5KVGFiYmVkUGFuZTsNCmltcG9ydCBqdW5pdC5mcmFtZXdvcmsuKjsNCg0KLyoqDQogKiBBIFRlc3RSdW5WaWV3IGlzIHNob3duIGFzIGEgcGFnZSBpbiBhIHRhYmJlZCBmb2xkZXIuDQogKiBJdCBjb250cmlidXRlcyB0aGUgcGFnZSBjb250ZW50cyBhbmQgY2FuIHJldHVybg0KICogdGhlIGN1cnJlbnRseSBzZWxlY3RlZCB0ZXN0cy4gQSBUZXN0UnVuVmlldyBpcyANCiAqIG5vdGlmaWVkIGFib3V0IHRoZSBzdGFydCBhbmQgZmluaXNoIG9mIGEgcnVuLg0KICovDQppbnRlcmZhY2UgVGVzdFJ1blZpZXcgew0KCS8qKg0KCSAqIFJldHVybnMgdGhlIGN1cnJlbnRseSBzZWxlY3RlZCBUZXN0IGluIHRoZSBWaWV3DQoJICovDQoJcHVibGljIFRlc3QgZ2V0U2VsZWN0ZWRUZXN0KCk7DQoJLyoqDQoJICogQWN0aXZhdGVzIHRoZSBUZXN0UnVuVmlldw0KCSAqLw0KCXB1YmxpYyB2b2lkIGFjdGl2YXRlKCk7DQoJLyoqDQoJICogUmV2ZWFscyB0aGUgZ2l2ZW4gZmFpbHVyZQ0KCSAqLw0KCXB1YmxpYyB2b2lkIHJldmVhbEZhaWx1cmUoVGVzdCBmYWlsdXJlKTsNCgkvKioNCgkgKiBBZGRzIHRoZSBUZXN0UnVuVmlldyB0byB0aGUgdGVzdCBydW4gdmlld3MgdGFiDQoJICovDQoJcHVibGljIHZvaWQgYWRkVGFiKEpUYWJiZWRQYW5lIHBhbmUpOw0KCS8qKg0KCSAqIEluZm9ybXMgdGhhdCB0aGUgc3VpdGUgaXMgYWJvdXQgdG8gc3RhcnQgDQoJICovDQoJcHVibGljIHZvaWQgYWJvdXRUb1N0YXJ0KFRlc3Qgc3VpdGUsIFRlc3RSZXN1bHQgcmVzdWx0KTsNCgkvKioNCgkgKiBJbmZvcm1zIHRoYXQgdGhlIHJ1biBvZiB0aGUgdGVzdCBzdWl0ZSBoYXMgZmluaXNoZWQgDQoJICovDQoJcHVibGljIHZvaWQgcnVuRmluaXNoZWQoVGVzdCBzdWl0ZSwgVGVzdFJlc3VsdCByZXN1bHQpOw0KfVBLAwQKAAAAAADqeMcwHx2Euz0KAAA9CgAAHgAAAGp1bml0L3N3aW5ndWkvQWJvdXREaWFsb2cuamF2YXBhY2thZ2UganVuaXQuc3dpbmd1aTsNCg0KaW1wb3J0IGphdmEuYXd0Lio7DQppbXBvcnQgamF2YS5hd3QuZXZlbnQuKjsNCg0KaW1wb3J0IGphdmF4LnN3aW5nLio7DQppbXBvcnQganVuaXQucnVubmVyLio7DQoNCi8qKg0KICogVGhlIEFib3V0RGlhbG9nLg0KICovDQpjbGFzcyBBYm91dERpYWxvZyBleHRlbmRzIEpEaWFsb2cgew0KCXB1YmxpYyBBYm91dERpYWxvZyhKRnJhbWUgcGFyZW50KSB7DQoJCXN1cGVyKHBhcmVudCwgdHJ1ZSk7DQoJCSANCgkJc2V0UmVzaXphYmxlKGZhbHNlKTsNCgkJZ2V0Q29udGVudFBhbmUoKS5zZXRMYXlvdXQobmV3IEdyaWRCYWdMYXlvdXQoKSk7DQoJCXNldFNpemUoMzMwLCAxMzgpOw0KCQlzZXRUaXRsZSgiQWJvdXQiKTsNCgkJLy8gc2V0TG9jYXRpb25SZWxhdGl2ZVRvIGlzIG9ubHkgYXZhaWxhYmxlIGluIEpESyAxLjQNCgkJdHJ5IHsNCgkJCXNldExvY2F0aW9uUmVsYXRpdmVUbyhwYXJlbnQpOw0KCQl9IGNhdGNoIChOb1N1Y2hNZXRob2RFcnJvciBlKSB7DQoJCQlUZXN0U2VsZWN0b3IuY2VudGVyV2luZG93KHRoaXMpOw0KCQl9DQoNCgkJSkJ1dHRvbiBjbG9zZT0gbmV3IEpCdXR0b24oIkNsb3NlIik7DQoJCWNsb3NlLmFkZEFjdGlvbkxpc3RlbmVyKA0KCQkJbmV3IEFjdGlvbkxpc3RlbmVyKCkgew0KCQkJCXB1YmxpYyB2b2lkIGFjdGlvblBlcmZvcm1lZChBY3Rpb25FdmVudCBlKSB7DQoJCQkJCWRpc3Bvc2UoKTsNCgkJCQl9DQoJCQl9DQoJCSk7DQoJCWdldFJvb3RQYW5lKCkuc2V0RGVmYXVsdEJ1dHRvbihjbG9zZSk7DQoJCUpMYWJlbCBsYWJlbDE9IG5ldyBKTGFiZWwoIkpVbml0Iik7DQoJCWxhYmVsMS5zZXRGb250KG5ldyBGb250KCJkaWFsb2ciLCBGb250LlBMQUlOLCAzNikpOw0KCQkNCgkJSkxhYmVsIGxhYmVsMj0gbmV3IEpMYWJlbCgiSlVuaXQgIitWZXJzaW9uLmlkKCkrIiBieSBLZW50IEJlY2sgYW5kIEVyaWNoIEdhbW1hIik7DQoJCWxhYmVsMi5zZXRGb250KG5ldyBGb250KCJkaWFsb2ciLCBGb250LlBMQUlOLCAxNCkpOw0KCQkNCgkJSkxhYmVsIGxvZ289IGNyZWF0ZUxvZ28oKTsNCg0KCQlHcmlkQmFnQ29uc3RyYWludHMgY29uc3RyYWludHNMYWJlbDE9IG5ldyBHcmlkQmFnQ29uc3RyYWludHMoKTsNCgkJY29uc3RyYWludHNMYWJlbDEuZ3JpZHggPSAzOyBjb25zdHJhaW50c0xhYmVsMS5ncmlkeSA9IDA7DQoJCWNvbnN0cmFpbnRzTGFiZWwxLmdyaWR3aWR0aCA9IDE7IGNvbnN0cmFpbnRzTGFiZWwxLmdyaWRoZWlnaHQgPSAxOw0KCQljb25zdHJhaW50c0xhYmVsMS5hbmNob3IgPSBHcmlkQmFnQ29uc3RyYWludHMuQ0VOVEVSOw0KCQlnZXRDb250ZW50UGFuZSgpLmFkZChsYWJlbDEsIGNvbnN0cmFpbnRzTGFiZWwxKTsNCg0KCQlHcmlkQmFnQ29uc3RyYWludHMgY29uc3RyYWludHNMYWJlbDI9IG5ldyBHcmlkQmFnQ29uc3RyYWludHMoKTsNCgkJY29uc3RyYWludHNMYWJlbDIuZ3JpZHggPSAyOyBjb25zdHJhaW50c0xhYmVsMi5ncmlkeSA9IDE7DQoJCWNvbnN0cmFpbnRzTGFiZWwyLmdyaWR3aWR0aCA9IDI7IGNvbnN0cmFpbnRzTGFiZWwyLmdyaWRoZWlnaHQgPSAxOw0KCQljb25zdHJhaW50c0xhYmVsMi5hbmNob3IgPSBHcmlkQmFnQ29uc3RyYWludHMuQ0VOVEVSOw0KCQlnZXRDb250ZW50UGFuZSgpLmFkZChsYWJlbDIsIGNvbnN0cmFpbnRzTGFiZWwyKTsNCg0KCQlHcmlkQmFnQ29uc3RyYWludHMgY29uc3RyYWludHNCdXR0b24xPSBuZXcgR3JpZEJhZ0NvbnN0cmFpbnRzKCk7DQoJCWNvbnN0cmFpbnRzQnV0dG9uMS5ncmlkeCA9IDI7IGNvbnN0cmFpbnRzQnV0dG9uMS5ncmlkeSA9IDI7DQoJCWNvbnN0cmFpbnRzQnV0dG9uMS5ncmlkd2lkdGggPSAyOyBjb25zdHJhaW50c0J1dHRvbjEuZ3JpZGhlaWdodCA9IDE7DQoJCWNvbnN0cmFpbnRzQnV0dG9uMS5hbmNob3IgPSBHcmlkQmFnQ29uc3RyYWludHMuQ0VOVEVSOw0KCQljb25zdHJhaW50c0J1dHRvbjEuaW5zZXRzPSBuZXcgSW5zZXRzKDgsIDAsIDgsIDApOw0KCQlnZXRDb250ZW50UGFuZSgpLmFkZChjbG9zZSwgY29uc3RyYWludHNCdXR0b24xKTsNCg0KCQlHcmlkQmFnQ29uc3RyYWludHMgY29uc3RyYWludHNMb2dvMT0gbmV3IEdyaWRCYWdDb25zdHJhaW50cygpOw0KCQljb25zdHJhaW50c0xvZ28xLmdyaWR4ID0gMjsgY29uc3RyYWludHNMb2dvMS5ncmlkeSA9IDA7DQoJCWNvbnN0cmFpbnRzTG9nbzEuZ3JpZHdpZHRoID0gMTsgY29uc3RyYWludHNMb2dvMS5ncmlkaGVpZ2h0ID0gMTsNCgkJY29uc3RyYWludHNMb2dvMS5hbmNob3IgPSBHcmlkQmFnQ29uc3RyYWludHMuQ0VOVEVSOw0KCQlnZXRDb250ZW50UGFuZSgpLmFkZChsb2dvLCBjb25zdHJhaW50c0xvZ28xKTsNCg0KCQlhZGRXaW5kb3dMaXN0ZW5lcigNCgkJCW5ldyBXaW5kb3dBZGFwdGVyKCkgew0KCQkJCXB1YmxpYyB2b2lkIHdpbmRvd0Nsb3NpbmcoV2luZG93RXZlbnQgZSkgew0KCQkJCQlkaXNwb3NlKCk7DQoJCQkJfQ0KCQkJfQ0KCQkpOw0KCX0NCglwcm90ZWN0ZWQgSkxhYmVsIGNyZWF0ZUxvZ28oKSB7DQoJCUljb24gaWNvbj0gVGVzdFJ1bm5lci5nZXRJY29uUmVzb3VyY2UoQmFzZVRlc3RSdW5uZXIuY2xhc3MsICJsb2dvLmdpZiIpOw0KCQlyZXR1cm4gbmV3IEpMYWJlbChpY29uKTsNCgl9DQp9UEsDBAoAAAAAAOp4xzD1SlnDzh0AAM4dAAAfAAAAanVuaXQvc3dpbmd1aS9UZXN0U2VsZWN0b3IuamF2YXBhY2thZ2UganVuaXQuc3dpbmd1aTsNCg0KaW1wb3J0IGphdmEuYXd0Lio7DQppbXBvcnQgamF2YS5hd3QuZXZlbnQuKjsNCmltcG9ydCBqYXZhLnV0aWwuKjsNCg0KaW1wb3J0IGphdmF4LnN3aW5nLio7DQppbXBvcnQgamF2YXguc3dpbmcuZXZlbnQuKjsNCmltcG9ydCBqdW5pdC5ydW5uZXIuKjsNCg0KLyoqDQogKiBBIHRlc3QgY2xhc3Mgc2VsZWN0b3IuIEEgc2ltcGxlIGRpYWxvZyB0byBwaWNrIHRoZSBuYW1lIG9mIGEgdGVzdCBzdWl0ZS4NCiAqLw0KY2xhc3MgVGVzdFNlbGVjdG9yIGV4dGVuZHMgSkRpYWxvZyB7DQoJcHJpdmF0ZSBKQnV0dG9uIGZDYW5jZWw7DQoJcHJpdmF0ZSBKQnV0dG9uIGZPazsNCglwcml2YXRlIEpMaXN0IGZMaXN0Ow0KCXByaXZhdGUgSlNjcm9sbFBhbmUgZlNjcm9sbGVkTGlzdDsNCglwcml2YXRlIEpMYWJlbCBmRGVzY3JpcHRpb247DQoJcHJpdmF0ZSBTdHJpbmcgZlNlbGVjdGVkSXRlbTsNCgkNCgkvKioNCgkgKiBSZW5kZXJzIFRlc3RGYWlsdXJlcyBpbiBhIEpMaXN0DQoJICovDQoJc3RhdGljIGNsYXNzIFRlc3RDZWxsUmVuZGVyZXIgZXh0ZW5kcyBEZWZhdWx0TGlzdENlbGxSZW5kZXJlciB7DQoJCUljb24gZkxlYWZJY29uOw0KCQlJY29uIGZTdWl0ZUljb247DQoJCQ0KCQlwdWJsaWMgVGVzdENlbGxSZW5kZXJlcigpIHsNCgkJCWZMZWFmSWNvbj0gVUlNYW5hZ2VyLmdldEljb24oIlRyZWUubGVhZkljb24iKTsNCgkJCWZTdWl0ZUljb249IFVJTWFuYWdlci5nZXRJY29uKCJUcmVlLmNsb3NlZEljb24iKTsNCgkJfQ0KCQkNCgkJcHVibGljIENvbXBvbmVudCBnZXRMaXN0Q2VsbFJlbmRlcmVyQ29tcG9uZW50KA0KCQkJCUpMaXN0IGxpc3QsIE9iamVjdCB2YWx1ZSwgaW50IG1vZGVsSW5kZXgsIA0KCQkJCWJvb2xlYW4gaXNTZWxlY3RlZCwgYm9vbGVhbiBjZWxsSGFzRm9jdXMpIHsNCgkJCUNvbXBvbmVudCBjPSBzdXBlci5nZXRMaXN0Q2VsbFJlbmRlcmVyQ29tcG9uZW50KGxpc3QsIHZhbHVlLCBtb2RlbEluZGV4LCBpc1NlbGVjdGVkLCBjZWxsSGFzRm9jdXMpOw0KCQkJU3RyaW5nIGRpc3BsYXlTdHJpbmc9IGRpc3BsYXlTdHJpbmcoKFN0cmluZyl2YWx1ZSk7DQoJCQkNCgkJCWlmIChkaXNwbGF5U3RyaW5nLnN0YXJ0c1dpdGgoIkFsbFRlc3RzIikpDQoJCQkJc2V0SWNvbihmU3VpdGVJY29uKTsNCgkJCWVsc2UNCgkJCQlzZXRJY29uKGZMZWFmSWNvbik7DQoJCQkJDQoJCQlzZXRUZXh0KGRpc3BsYXlTdHJpbmcpOw0KCQkgICAgCXJldHVybiBjOw0KCQl9DQoJCQ0KCQlwdWJsaWMgc3RhdGljIFN0cmluZyBkaXNwbGF5U3RyaW5nKFN0cmluZyBjbGFzc05hbWUpIHsNCgkJCWludCB0eXBlSW5kZXg9IGNsYXNzTmFtZS5sYXN0SW5kZXhPZignLicpOw0KICAgIAkJCWlmICh0eXBlSW5kZXggPCAwKSANCiAgICAJCQkJcmV0dXJuIGNsYXNzTmFtZTsNCiAgICAJCQlyZXR1cm4gY2xhc3NOYW1lLnN1YnN0cmluZyh0eXBlSW5kZXgrMSkgKyAiIC0gIiArIGNsYXNzTmFtZS5zdWJzdHJpbmcoMCwgdHlwZUluZGV4KTsNCgkJfQ0KCQkNCgkJcHVibGljIHN0YXRpYyBib29sZWFuIG1hdGNoZXNLZXkoU3RyaW5nIHMsIGNoYXIgY2gpIHsNCiAgICAJCQlyZXR1cm4gY2ggPT0gQ2hhcmFjdGVyLnRvVXBwZXJDYXNlKHMuY2hhckF0KHR5cGVJbmRleChzKSkpOw0KCQl9DQoJCQ0KCQlwcml2YXRlIHN0YXRpYyBpbnQgdHlwZUluZGV4KFN0cmluZyBzKSB7DQoJCQlpbnQgdHlwZUluZGV4PSBzLmxhc3RJbmRleE9mKCcuJyk7DQoJCQlpbnQgaT0gMDsNCiAgICAJCQlpZiAodHlwZUluZGV4ID4gMCkgDQogICAgCQkJCWk9IHR5cGVJbmRleCsxOw0KICAgIAkJCXJldHVybiBpOw0KCQl9DQoJfQ0KCQ0KCXByb3RlY3RlZCBjbGFzcyBEb3VibGVDbGlja0xpc3RlbmVyIGV4dGVuZHMgTW91c2VBZGFwdGVyIHsNCgkJcHVibGljIHZvaWQgbW91c2VDbGlja2VkKE1vdXNlRXZlbnQgZSkgew0KCSAgICAJCWlmIChlLmdldENsaWNrQ291bnQoKSA9PSAyKSB7DQoJICAgIAkJCW9rU2VsZWN0ZWQoKTsNCgkgICAgCQl9DQoJICAgICAgfQ0KCX0NCgkNCglwcm90ZWN0ZWQgY2xhc3MgS2V5U2VsZWN0TGlzdGVuZXIgZXh0ZW5kcyBLZXlBZGFwdGVyIHsNCgkJcHVibGljIHZvaWQga2V5VHlwZWQoS2V5RXZlbnQgZSkgew0KCQkJa2V5U2VsZWN0VGVzdENsYXNzKGUuZ2V0S2V5Q2hhcigpKTsNCgkJfQ0KCX0NCg0KCXB1YmxpYyBUZXN0U2VsZWN0b3IoRnJhbWUgcGFyZW50LCBUZXN0Q29sbGVjdG9yIHRlc3RDb2xsZWN0b3IpIHsNCgkJc3VwZXIocGFyZW50LCB0cnVlKTsNCgkJc2V0U2l6ZSgzNTAsIDMwMCk7DQoJCXNldFJlc2l6YWJsZShmYWxzZSk7DQoJCS8vIHNldExvY2F0aW9uUmVsYXRpdmVUbyBvbmx5IGV4aXN0cyBpbiAxLjQNCgkJdHJ5IHsNCgkJCXNldExvY2F0aW9uUmVsYXRpdmVUbyhwYXJlbnQpOw0KCQl9IGNhdGNoIChOb1N1Y2hNZXRob2RFcnJvciBlKSB7DQoJCQljZW50ZXJXaW5kb3codGhpcyk7DQoJCX0NCgkJc2V0VGl0bGUoIlRlc3QgU2VsZWN0b3IiKTsNCgkJDQoJCVZlY3RvciBsaXN0PSBudWxsOw0KCQl0cnkgew0KCQkJcGFyZW50LnNldEN1cnNvcihDdXJzb3IuZ2V0UHJlZGVmaW5lZEN1cnNvcihDdXJzb3IuV0FJVF9DVVJTT1IpKTsNCgkJCWxpc3Q9IGNyZWF0ZVRlc3RMaXN0KHRlc3RDb2xsZWN0b3IpOw0KCQl9IGZpbmFsbHkgew0KCQkJcGFyZW50LnNldEN1cnNvcihDdXJzb3IuZ2V0RGVmYXVsdEN1cnNvcigpKTsNCgkJfQ0KCQlmTGlzdD0gbmV3IEpMaXN0KGxpc3QpOw0KCQlmTGlzdC5zZXRTZWxlY3Rpb25Nb2RlKExpc3RTZWxlY3Rpb25Nb2RlbC5TSU5HTEVfU0VMRUNUSU9OKTsNCgkJZkxpc3Quc2V0Q2VsbFJlbmRlcmVyKG5ldyBUZXN0Q2VsbFJlbmRlcmVyKCkpOw0KCQlmU2Nyb2xsZWRMaXN0PSBuZXcgSlNjcm9sbFBhbmUoZkxpc3QpOw0KDQoJCWZDYW5jZWw9IG5ldyBKQnV0dG9uKCJDYW5jZWwiKTsNCgkJZkRlc2NyaXB0aW9uPSBuZXcgSkxhYmVsKCJTZWxlY3QgdGhlIFRlc3QgY2xhc3M6Iik7DQoJCWZPaz0gbmV3IEpCdXR0b24oIk9LIik7DQoJCWZPay5zZXRFbmFibGVkKGZhbHNlKTsNCgkJZ2V0Um9vdFBhbmUoKS5zZXREZWZhdWx0QnV0dG9uKGZPayk7DQoJCQ0KCQlkZWZpbmVMYXlvdXQoKTsNCgkJYWRkTGlzdGVuZXJzKCk7DQoJfQ0KDQoJcHVibGljIHN0YXRpYyB2b2lkIGNlbnRlcldpbmRvdyhDb21wb25lbnQgYykgew0KCQlEaW1lbnNpb24gcGFuZVNpemU9IGMuZ2V0U2l6ZSgpOw0KCQlEaW1lbnNpb24gc2NyZWVuU2l6ZT0gYy5nZXRUb29sa2l0KCkuZ2V0U2NyZWVuU2l6ZSgpOw0KCQljLnNldExvY2F0aW9uKChzY3JlZW5TaXplLndpZHRoLXBhbmVTaXplLndpZHRoKS8yLCAoc2NyZWVuU2l6ZS5oZWlnaHQtcGFuZVNpemUuaGVpZ2h0KS8yKTsNCgl9DQoJDQoJcHJpdmF0ZSB2b2lkIGFkZExpc3RlbmVycygpIHsNCgkJZkNhbmNlbC5hZGRBY3Rpb25MaXN0ZW5lcigNCgkJCW5ldyBBY3Rpb25MaXN0ZW5lcigpIHsNCgkJCQlwdWJsaWMgdm9pZCBhY3Rpb25QZXJmb3JtZWQoQWN0aW9uRXZlbnQgZSkgew0KCQkJCQlkaXNwb3NlKCk7DQoJCQkJfQ0KCQkJfQ0KCQkpOw0KCQkNCgkJZk9rLmFkZEFjdGlvbkxpc3RlbmVyKA0KCQkJbmV3IEFjdGlvbkxpc3RlbmVyKCkgew0KCQkJCXB1YmxpYyB2b2lkIGFjdGlvblBlcmZvcm1lZChBY3Rpb25FdmVudCBlKSB7DQoJCQkJCW9rU2VsZWN0ZWQoKTsNCgkJCQl9DQoJCQl9DQoJCSk7DQoNCgkJZkxpc3QuYWRkTW91c2VMaXN0ZW5lcihuZXcgRG91YmxlQ2xpY2tMaXN0ZW5lcigpKTsNCgkJZkxpc3QuYWRkS2V5TGlzdGVuZXIobmV3IEtleVNlbGVjdExpc3RlbmVyKCkpOw0KCQlmTGlzdC5hZGRMaXN0U2VsZWN0aW9uTGlzdGVuZXIoDQoJCQluZXcgTGlzdFNlbGVjdGlvbkxpc3RlbmVyKCkgew0KCQkJCXB1YmxpYyB2b2lkIHZhbHVlQ2hhbmdlZChMaXN0U2VsZWN0aW9uRXZlbnQgZSkgew0KCQkJCQljaGVja0VuYWJsZU9LKGUpOw0KCQkJCX0NCgkJCX0NCgkJKTsNCg0KCQlhZGRXaW5kb3dMaXN0ZW5lcigNCgkJCW5ldyBXaW5kb3dBZGFwdGVyKCkgew0KCQkJCXB1YmxpYyB2b2lkIHdpbmRvd0Nsb3NpbmcoV2luZG93RXZlbnQgZSkgew0KCQkJCQlkaXNwb3NlKCk7DQoJCQkJfQ0KCQkJfQ0KCQkpOw0KCX0NCgkNCglwcml2YXRlIHZvaWQgZGVmaW5lTGF5b3V0KCkgew0KCQlnZXRDb250ZW50UGFuZSgpLnNldExheW91dChuZXcgR3JpZEJhZ0xheW91dCgpKTsNCgkJR3JpZEJhZ0NvbnN0cmFpbnRzIGxhYmVsQ29uc3RyYWludHMgPSBuZXcgR3JpZEJhZ0NvbnN0cmFpbnRzKCk7DQoJCWxhYmVsQ29uc3RyYWludHMuZ3JpZHg9IDA7IGxhYmVsQ29uc3RyYWludHMuZ3JpZHk9IDA7DQoJCWxhYmVsQ29uc3RyYWludHMuZ3JpZHdpZHRoPSAxOyBsYWJlbENvbnN0cmFpbnRzLmdyaWRoZWlnaHQ9IDE7DQoJCWxhYmVsQ29uc3RyYWludHMuZmlsbD0gR3JpZEJhZ0NvbnN0cmFpbnRzLkJPVEg7DQoJCWxhYmVsQ29uc3RyYWludHMuYW5jaG9yPSBHcmlkQmFnQ29uc3RyYWludHMuV0VTVDsNCgkJbGFiZWxDb25zdHJhaW50cy53ZWlnaHR4PSAxLjA7DQoJCWxhYmVsQ29uc3RyYWludHMud2VpZ2h0eT0gMC4wOw0KCQlsYWJlbENvbnN0cmFpbnRzLmluc2V0cz0gbmV3IEluc2V0cyg4LCA4LCAwLCA4KTsNCgkJZ2V0Q29udGVudFBhbmUoKS5hZGQoZkRlc2NyaXB0aW9uLCBsYWJlbENvbnN0cmFpbnRzKTsNCg0KCQlHcmlkQmFnQ29uc3RyYWludHMgbGlzdENvbnN0cmFpbnRzID0gbmV3IEdyaWRCYWdDb25zdHJhaW50cygpOw0KCQlsaXN0Q29uc3RyYWludHMuZ3JpZHg9IDA7IGxpc3RDb25zdHJhaW50cy5ncmlkeT0gMTsNCgkJbGlzdENvbnN0cmFpbnRzLmdyaWR3aWR0aD0gNDsgbGlzdENvbnN0cmFpbnRzLmdyaWRoZWlnaHQ9IDE7DQoJCWxpc3RDb25zdHJhaW50cy5maWxsPSBHcmlkQmFnQ29uc3RyYWludHMuQk9USDsNCgkJbGlzdENvbnN0cmFpbnRzLmFuY2hvcj0gR3JpZEJhZ0NvbnN0cmFpbnRzLkNFTlRFUjsNCgkJbGlzdENvbnN0cmFpbnRzLndlaWdodHg9IDEuMDsNCgkJbGlzdENvbnN0cmFpbnRzLndlaWdodHk9IDEuMDsNCgkJbGlzdENvbnN0cmFpbnRzLmluc2V0cz0gbmV3IEluc2V0cyg4LCA4LCA4LCA4KTsNCgkJZ2V0Q29udGVudFBhbmUoKS5hZGQoZlNjcm9sbGVkTGlzdCwgbGlzdENvbnN0cmFpbnRzKTsNCgkJDQoJCUdyaWRCYWdDb25zdHJhaW50cyBva0NvbnN0cmFpbnRzPSBuZXcgR3JpZEJhZ0NvbnN0cmFpbnRzKCk7DQoJCW9rQ29uc3RyYWludHMuZ3JpZHg9IDI7IG9rQ29uc3RyYWludHMuZ3JpZHk9IDI7DQoJCW9rQ29uc3RyYWludHMuZ3JpZHdpZHRoPSAxOyBva0NvbnN0cmFpbnRzLmdyaWRoZWlnaHQ9IDE7DQoJCW9rQ29uc3RyYWludHMuYW5jaG9yPSBqYXZhLmF3dC5HcmlkQmFnQ29uc3RyYWludHMuRUFTVDsNCgkJb2tDb25zdHJhaW50cy5pbnNldHM9IG5ldyBJbnNldHMoMCwgOCwgOCwgOCk7DQoJCWdldENvbnRlbnRQYW5lKCkuYWRkKGZPaywgb2tDb25zdHJhaW50cyk7DQoNCg0KCQlHcmlkQmFnQ29uc3RyYWludHMgY2FuY2VsQ29uc3RyYWludHMgPSBuZXcgR3JpZEJhZ0NvbnN0cmFpbnRzKCk7DQoJCWNhbmNlbENvbnN0cmFpbnRzLmdyaWR4PSAzOyBjYW5jZWxDb25zdHJhaW50cy5ncmlkeT0gMjsNCgkJY2FuY2VsQ29uc3RyYWludHMuZ3JpZHdpZHRoPSAxOyBjYW5jZWxDb25zdHJhaW50cy5ncmlkaGVpZ2h0PSAxOw0KCQljYW5jZWxDb25zdHJhaW50cy5hbmNob3I9IGphdmEuYXd0LkdyaWRCYWdDb25zdHJhaW50cy5FQVNUOw0KCQljYW5jZWxDb25zdHJhaW50cy5pbnNldHM9IG5ldyBJbnNldHMoMCwgOCwgOCwgOCk7DQoJCWdldENvbnRlbnRQYW5lKCkuYWRkKGZDYW5jZWwsIGNhbmNlbENvbnN0cmFpbnRzKTsNCgl9DQoJDQoJcHVibGljIHZvaWQgY2hlY2tFbmFibGVPSyhMaXN0U2VsZWN0aW9uRXZlbnQgZSkgew0KCQlmT2suc2V0RW5hYmxlZChmTGlzdC5nZXRTZWxlY3RlZEluZGV4KCkgIT0gLTEpOw0KCX0NCgkNCglwdWJsaWMgdm9pZCBva1NlbGVjdGVkKCkgew0KCQlmU2VsZWN0ZWRJdGVtPSAoU3RyaW5nKWZMaXN0LmdldFNlbGVjdGVkVmFsdWUoKTsNCgkJZGlzcG9zZSgpOw0KCX0NCgkNCglwdWJsaWMgYm9vbGVhbiBpc0VtcHR5KCkgew0KCQlyZXR1cm4gZkxpc3QuZ2V0TW9kZWwoKS5nZXRTaXplKCkgPT0gMDsNCgl9DQoJDQoJcHVibGljIHZvaWQga2V5U2VsZWN0VGVzdENsYXNzKGNoYXIgY2gpIHsNCgkJTGlzdE1vZGVsIG1vZGVsPSBmTGlzdC5nZXRNb2RlbCgpOw0KCQlpZiAoIUNoYXJhY3Rlci5pc0phdmFJZGVudGlmaWVyU3RhcnQoY2gpKQ0KCQkJcmV0dXJuOw0KCQlmb3IgKGludCBpPSAwOyBpIDwgbW9kZWwuZ2V0U2l6ZSgpOyBpKyspIHsNCgkJCVN0cmluZyBzPSAoU3RyaW5nKW1vZGVsLmdldEVsZW1lbnRBdChpKTsNCgkJCWlmIChUZXN0Q2VsbFJlbmRlcmVyLm1hdGNoZXNLZXkocywgQ2hhcmFjdGVyLnRvVXBwZXJDYXNlKGNoKSkpIHsNCgkJCQlmTGlzdC5zZXRTZWxlY3RlZEluZGV4KGkpOw0KCQkJCWZMaXN0LmVuc3VyZUluZGV4SXNWaXNpYmxlKGkpOw0KCQkJCXJldHVybjsNCgkJCX0NCgkJfQ0KCQlUb29sa2l0LmdldERlZmF1bHRUb29sa2l0KCkuYmVlcCgpOw0KCX0NCgkNCglwdWJsaWMgU3RyaW5nIGdldFNlbGVjdGVkSXRlbSgpIHsNCgkJcmV0dXJuIGZTZWxlY3RlZEl0ZW07DQoJfQ0KDQoJcHJpdmF0ZSBWZWN0b3IgY3JlYXRlVGVzdExpc3QoVGVzdENvbGxlY3RvciBjb2xsZWN0b3IpIHsNCiAgICAJCUVudW1lcmF0aW9uIGVhY2g9IGNvbGxlY3Rvci5jb2xsZWN0VGVzdHMoKTsNCiAgICAJCVZlY3RvciB2PSBuZXcgVmVjdG9yKDIwMCk7DQogICAgCQlWZWN0b3IgZGlzcGxheVZlY3Rvcj0gbmV3IFZlY3Rvcih2LnNpemUoKSk7DQogICAgCQl3aGlsZShlYWNoLmhhc01vcmVFbGVtZW50cygpKSB7DQogICAgCQkJU3RyaW5nIHM9IChTdHJpbmcpZWFjaC5uZXh0RWxlbWVudCgpOw0KICAgIAkJCXYuYWRkRWxlbWVudChzKTsNCiAgICAJCQlkaXNwbGF5VmVjdG9yLmFkZEVsZW1lbnQoVGVzdENlbGxSZW5kZXJlci5kaXNwbGF5U3RyaW5nKHMpKTsNCiAgICAJCX0NCiAgICAJCWlmICh2LnNpemUoKSA+IDApDQogICAgCQkJU29ydGVyLnNvcnRTdHJpbmdzKGRpc3BsYXlWZWN0b3IsIDAsIGRpc3BsYXlWZWN0b3Iuc2l6ZSgpLTEsIG5ldyBQYXJhbGxlbFN3YXBwZXIodikpOw0KICAgIAkJcmV0dXJuIHY7DQoJfQ0KCQ0KCXByaXZhdGUgY2xhc3MgUGFyYWxsZWxTd2FwcGVyIGltcGxlbWVudHMgU29ydGVyLlN3YXBwZXIgew0KCQlWZWN0b3IgZk90aGVyOw0KCQkNCgkJUGFyYWxsZWxTd2FwcGVyKFZlY3RvciBvdGhlcikgew0KCQkJZk90aGVyPSBvdGhlcjsNCgkJfQ0KCQlwdWJsaWMgdm9pZCBzd2FwKFZlY3RvciB2YWx1ZXMsIGludCBsZWZ0LCBpbnQgcmlnaHQpIHsNCgkJCU9iamVjdCB0bXA9IHZhbHVlcy5lbGVtZW50QXQobGVmdCk7IA0KCQkJdmFsdWVzLnNldEVsZW1lbnRBdCh2YWx1ZXMuZWxlbWVudEF0KHJpZ2h0KSwgbGVmdCk7IA0KCQkJdmFsdWVzLnNldEVsZW1lbnRBdCh0bXAsIHJpZ2h0KTsNCgkJCU9iamVjdCB0bXAyPSBmT3RoZXIuZWxlbWVudEF0KGxlZnQpOw0KCQkJZk90aGVyLnNldEVsZW1lbnRBdChmT3RoZXIuZWxlbWVudEF0KHJpZ2h0KSwgbGVmdCk7DQoJCQlmT3RoZXIuc2V0RWxlbWVudEF0KHRtcDIsIHJpZ2h0KTsNCgkJfQkJCQ0KCX0NCn1QSwMECgAAAAAA6njHMCbHPJTLAQAAywEAACEAAABqdW5pdC9zd2luZ3VpL1Rlc3RSdW5Db250ZXh0LmphdmFwYWNrYWdlIGp1bml0LnN3aW5ndWk7DQoNCmltcG9ydCBqYXZheC5zd2luZy5MaXN0TW9kZWw7DQoNCmltcG9ydCBqdW5pdC5mcmFtZXdvcmsuVGVzdDsNCg0KLyoqDQogKiBUaGUgaW50ZXJmYWNlIGZvciBhY2Nlc3NpbmcgdGhlIFRlc3QgcnVuIGNvbnRleHQuIFRlc3QgcnVuIHZpZXdzDQogKiBzaG91bGQgdXNlIHRoaXMgaW50ZXJmYWNlIHJhdGhlciB0aGFuIGFjY2Vzc2luZyB0aGUgVGVzdFJ1bm5lcg0KICogZGlyZWN0bHkuDQogKi8NCnB1YmxpYyBpbnRlcmZhY2UgVGVzdFJ1bkNvbnRleHQgew0KCS8qKg0KCSAqIEhhbmRsZXMgdGhlIHNlbGVjdGlvbiBvZiBhIFRlc3QuDQoJICovDQoJcHVibGljIHZvaWQgaGFuZGxlVGVzdFNlbGVjdGVkKFRlc3QgdGVzdCk7DQoJLyoqDQoJICogUmV0dXJucyB0aGUgZmFpbHVyZSBtb2RlbA0KCSAqLw0KCXB1YmxpYyBMaXN0TW9kZWwgZ2V0RmFpbHVyZXMoKTsNCn1QSwMECgAAAAAA6njHMMKe+eXfCwAA3wsAACEAAABqdW5pdC9zd2luZ3VpL0ZhaWx1cmVSdW5WaWV3LmphdmFwYWNrYWdlIGp1bml0LnN3aW5ndWk7DQoNCmltcG9ydCBqYXZhLmF3dC4qOw0KDQppbXBvcnQgamF2YXguc3dpbmcuKjsNCmltcG9ydCBqYXZheC5zd2luZy5ldmVudC4qOw0KaW1wb3J0IGp1bml0LmZyYW1ld29yay4qOw0KaW1wb3J0IGp1bml0LnJ1bm5lci5CYXNlVGVzdFJ1bm5lcjsNCg0KDQovKioNCiAqIEEgdmlldyBwcmVzZW50aW5nIHRoZSB0ZXN0IGZhaWx1cmVzIGFzIGEgbGlzdC4NCiAqLw0KcHVibGljIGNsYXNzIEZhaWx1cmVSdW5WaWV3IGltcGxlbWVudHMgVGVzdFJ1blZpZXcgew0KCUpMaXN0IGZGYWlsdXJlTGlzdDsNCglUZXN0UnVuQ29udGV4dCBmUnVuQ29udGV4dDsNCgkNCgkvKioNCgkgKiBSZW5kZXJzIFRlc3RGYWlsdXJlcyBpbiBhIEpMaXN0DQoJICovDQoJc3RhdGljIGNsYXNzIEZhaWx1cmVMaXN0Q2VsbFJlbmRlcmVyIGV4dGVuZHMgRGVmYXVsdExpc3RDZWxsUmVuZGVyZXIgew0KCQlwcml2YXRlIEljb24gZkZhaWx1cmVJY29uOw0KCQlwcml2YXRlIEljb24gZkVycm9ySWNvbjsNCgkJDQoJCUZhaWx1cmVMaXN0Q2VsbFJlbmRlcmVyKCkgew0KCSAgICAJCXN1cGVyKCk7DQoJICAgIAkJbG9hZEljb25zKCk7DQoJCX0NCgkNCgkJdm9pZCBsb2FkSWNvbnMoKSB7DQoJCQlmRmFpbHVyZUljb249IFRlc3RSdW5uZXIuZ2V0SWNvblJlc291cmNlKGdldENsYXNzKCksICJpY29ucy9mYWlsdXJlLmdpZiIpOw0KCQkJZkVycm9ySWNvbj0gVGVzdFJ1bm5lci5nZXRJY29uUmVzb3VyY2UoZ2V0Q2xhc3MoKSwgImljb25zL2Vycm9yLmdpZiIpOwkJDQoJCX0NCgkJCQkJCQ0KCQlwdWJsaWMgQ29tcG9uZW50IGdldExpc3RDZWxsUmVuZGVyZXJDb21wb25lbnQoDQoJCQlKTGlzdCBsaXN0LCBPYmplY3QgdmFsdWUsIGludCBtb2RlbEluZGV4LCANCgkJCWJvb2xlYW4gaXNTZWxlY3RlZCwgYm9vbGVhbiBjZWxsSGFzRm9jdXMpIHsNCgkNCgkJICAgIENvbXBvbmVudCBjPSBzdXBlci5nZXRMaXN0Q2VsbFJlbmRlcmVyQ29tcG9uZW50KGxpc3QsIHZhbHVlLCBtb2RlbEluZGV4LCBpc1NlbGVjdGVkLCBjZWxsSGFzRm9jdXMpOw0KCQkJVGVzdEZhaWx1cmUgZmFpbHVyZT0gKFRlc3RGYWlsdXJlKXZhbHVlOw0KCQkJU3RyaW5nIHRleHQ9IGZhaWx1cmUuZmFpbGVkVGVzdCgpLnRvU3RyaW5nKCk7DQoJCQlTdHJpbmcgbXNnPSBmYWlsdXJlLmV4Y2VwdGlvbk1lc3NhZ2UoKTsNCgkJCWlmIChtc2cgIT0gbnVsbCkgDQoJCQkJdGV4dCs9ICI6IiArIEJhc2VUZXN0UnVubmVyLnRydW5jYXRlKG1zZyk7IA0KCSANCgkJCWlmIChmYWlsdXJlLmlzRmFpbHVyZSgpKSB7IA0KCQkJCWlmIChmRmFpbHVyZUljb24gIT0gbnVsbCkNCgkJICAgIAkJc2V0SWNvbihmRmFpbHVyZUljb24pOw0KCQkJfSBlbHNlIHsNCgkJICAgIAlpZiAoZkVycm9ySWNvbiAhPSBudWxsKQ0KCQkgICAgCQlzZXRJY29uKGZFcnJvckljb24pOw0KCQkgICAgfQ0KCQkJc2V0VGV4dCh0ZXh0KTsNCgkJCXNldFRvb2xUaXBUZXh0KHRleHQpOw0KCQkJcmV0dXJuIGM7DQoJCX0NCgl9DQoJDQoJcHVibGljIEZhaWx1cmVSdW5WaWV3KFRlc3RSdW5Db250ZXh0IGNvbnRleHQpIHsNCgkJZlJ1bkNvbnRleHQ9IGNvbnRleHQ7DQoJCWZGYWlsdXJlTGlzdD0gbmV3IEpMaXN0KGZSdW5Db250ZXh0LmdldEZhaWx1cmVzKCkpOw0KCQlmRmFpbHVyZUxpc3Quc2V0Rm9udChuZXcgRm9udCgiRGlhbG9nIiwgRm9udC5QTEFJTiwgMTIpKTsNCiANCgkJZkZhaWx1cmVMaXN0LnNldFNlbGVjdGlvbk1vZGUoTGlzdFNlbGVjdGlvbk1vZGVsLlNJTkdMRV9TRUxFQ1RJT04pOw0KCQlmRmFpbHVyZUxpc3Quc2V0Q2VsbFJlbmRlcmVyKG5ldyBGYWlsdXJlTGlzdENlbGxSZW5kZXJlcigpKTsNCgkJZkZhaWx1cmVMaXN0LnNldFZpc2libGVSb3dDb3VudCg1KTsNCg0KCQlmRmFpbHVyZUxpc3QuYWRkTGlzdFNlbGVjdGlvbkxpc3RlbmVyKA0KCQkJbmV3IExpc3RTZWxlY3Rpb25MaXN0ZW5lcigpIHsNCgkJCQlwdWJsaWMgdm9pZCB2YWx1ZUNoYW5nZWQoTGlzdFNlbGVjdGlvbkV2ZW50IGUpIHsNCgkJCQkJdGVzdFNlbGVjdGVkKCk7DQoJCQkJfQ0KCQkJfQ0KCQkpOw0KCX0NCgkNCglwdWJsaWMgVGVzdCBnZXRTZWxlY3RlZFRlc3QoKSB7DQoJCWludCBpbmRleD0gZkZhaWx1cmVMaXN0LmdldFNlbGVjdGVkSW5kZXgoKTsNCgkJaWYgKGluZGV4ID09IC0xKQ0KCQkJcmV0dXJuIG51bGw7DQoJCQkNCgkJTGlzdE1vZGVsIG1vZGVsPSBmRmFpbHVyZUxpc3QuZ2V0TW9kZWwoKTsNCgkJVGVzdEZhaWx1cmUgZmFpbHVyZT0gKFRlc3RGYWlsdXJlKW1vZGVsLmdldEVsZW1lbnRBdChpbmRleCk7DQoJCXJldHVybiBmYWlsdXJlLmZhaWxlZFRlc3QoKTsNCgl9DQoJDQoJcHVibGljIHZvaWQgYWN0aXZhdGUoKSB7DQoJCXRlc3RTZWxlY3RlZCgpOw0KCX0NCgkNCglwdWJsaWMgdm9pZCBhZGRUYWIoSlRhYmJlZFBhbmUgcGFuZSkgew0KCQlKU2Nyb2xsUGFuZSBzY3JvbGxQYW5lPSBuZXcgSlNjcm9sbFBhbmUoZkZhaWx1cmVMaXN0LCBKU2Nyb2xsUGFuZS5WRVJUSUNBTF9TQ1JPTExCQVJfQUxXQVlTLCBKU2Nyb2xsUGFuZS5IT1JJWk9OVEFMX1NDUk9MTEJBUl9BTFdBWVMpOw0KCQlJY29uIGVycm9ySWNvbj0gVGVzdFJ1bm5lci5nZXRJY29uUmVzb3VyY2UoZ2V0Q2xhc3MoKSwgImljb25zL2Vycm9yLmdpZiIpOw0KCQlwYW5lLmFkZFRhYigiRmFpbHVyZXMiLCBlcnJvckljb24sIHNjcm9sbFBhbmUsICJUaGUgbGlzdCBvZiBmYWlsZWQgdGVzdHMiKTsNCgl9DQoJCQ0KCXB1YmxpYyB2b2lkIHJldmVhbEZhaWx1cmUoVGVzdCBmYWlsdXJlKSB7DQoJCWZGYWlsdXJlTGlzdC5zZXRTZWxlY3RlZEluZGV4KDApOw0KCX0NCgkNCglwdWJsaWMgdm9pZCBhYm91dFRvU3RhcnQoVGVzdCBzdWl0ZSwgVGVzdFJlc3VsdCByZXN1bHQpIHsNCgl9DQoNCglwdWJsaWMgdm9pZCBydW5GaW5pc2hlZChUZXN0IHN1aXRlLCBUZXN0UmVzdWx0IHJlc3VsdCkgew0KCX0NCg0KCXByb3RlY3RlZCB2b2lkIHRlc3RTZWxlY3RlZCgpIHsNCgkJZlJ1bkNvbnRleHQuaGFuZGxlVGVzdFNlbGVjdGVkKGdldFNlbGVjdGVkVGVzdCgpKTsNCgl9DQp9DQpQSwMECgAAAAAA6njHMFS7gE8AEQAAABEAACEAAABqdW5pdC9zd2luZ3VpL1Rlc3RTdWl0ZVBhbmVsLmphdmFwYWNrYWdlIGp1bml0LnN3aW5ndWk7DQoNCmltcG9ydCBqYXZhLmF3dC4qOw0KaW1wb3J0IGphdmEudXRpbC5WZWN0b3I7DQoNCmltcG9ydCBqYXZheC5zd2luZy4qOw0KaW1wb3J0IGphdmF4LnN3aW5nLnRyZWUuKjsNCmltcG9ydCBqdW5pdC5mcmFtZXdvcmsuKjsNCg0KLyoqDQogKiBBIFBhbmVsIHNob3dpbmcgYSB0ZXN0IHN1aXRlIGFzIGEgdHJlZS4gDQogKi8NCmNsYXNzIFRlc3RTdWl0ZVBhbmVsIGV4dGVuZHMgSlBhbmVsIGltcGxlbWVudHMgVGVzdExpc3RlbmVyIHsNCglwcml2YXRlIEpUcmVlIGZUcmVlOw0KCXByaXZhdGUgSlNjcm9sbFBhbmUgZlNjcm9sbFRyZWU7DQoJcHJpdmF0ZSBUZXN0VHJlZU1vZGVsIGZNb2RlbDsNCg0KCXN0YXRpYyBjbGFzcyBUZXN0VHJlZUNlbGxSZW5kZXJlciBleHRlbmRzIERlZmF1bHRUcmVlQ2VsbFJlbmRlcmVyIHsNCgkJcHJpdmF0ZSBJY29uIGZFcnJvckljb247DQoJCXByaXZhdGUgSWNvbiBmT2tJY29uOw0KCQlwcml2YXRlIEljb24gZkZhaWx1cmVJY29uOw0KCQkNCgkJVGVzdFRyZWVDZWxsUmVuZGVyZXIoKSB7DQoJICAgIAkJc3VwZXIoKTsNCgkgICAgCQlsb2FkSWNvbnMoKTsNCgkJfQ0KCQkNCgkJdm9pZCBsb2FkSWNvbnMoKSB7DQoJCQlmRXJyb3JJY29uPSBUZXN0UnVubmVyLmdldEljb25SZXNvdXJjZShnZXRDbGFzcygpLCAiaWNvbnMvZXJyb3IuZ2lmIik7DQoJICAgIAkJZk9rSWNvbj0gVGVzdFJ1bm5lci5nZXRJY29uUmVzb3VyY2UoZ2V0Q2xhc3MoKSwgImljb25zL29rLmdpZiIpOw0KCSAgICAJCWZGYWlsdXJlSWNvbj0gVGVzdFJ1bm5lci5nZXRJY29uUmVzb3VyY2UoZ2V0Q2xhc3MoKSwgImljb25zL2ZhaWx1cmUuZ2lmIik7DQoJCX0NCgkJDQoJCVN0cmluZyBzdHJpcFBhcmVudGhlc2lzKE9iamVjdCBvKSB7DQoJCQlTdHJpbmcgdGV4dD0gby50b1N0cmluZyAoKTsNCiAgICAJCQlpbnQgcG9zPSB0ZXh0LmluZGV4T2YoJygnKTsNCiAgICAJCQlpZiAocG9zIDwgMSkNCiAgICAJCQkJcmV0dXJuIHRleHQ7DQogICAgCQkJcmV0dXJuIHRleHQuc3Vic3RyaW5nICgwLCBwb3MpOw0KICAJCX0NCg0KCQlwdWJsaWMgQ29tcG9uZW50IGdldFRyZWVDZWxsUmVuZGVyZXJDb21wb25lbnQoSlRyZWUgdHJlZSwgT2JqZWN0IHZhbHVlLA0KCQkJCWJvb2xlYW4gc2VsLCBib29sZWFuIGV4cGFuZGVkLCBib29sZWFuIGxlYWYsIGludCByb3csIGJvb2xlYW4gaGFzRm9jdXMpIHsNCgkJCQ0KCQkJQ29tcG9uZW50IGM9IHN1cGVyLmdldFRyZWVDZWxsUmVuZGVyZXJDb21wb25lbnQodHJlZSwgdmFsdWUsIHNlbCwgZXhwYW5kZWQsIGxlYWYsIHJvdywgaGFzRm9jdXMpOw0KCSAgCQlUcmVlTW9kZWwgbW9kZWw9IHRyZWUuZ2V0TW9kZWwoKTsNCgkgIAkJaWYgKG1vZGVsIGluc3RhbmNlb2YgVGVzdFRyZWVNb2RlbCkgewkNCgkJCQlUZXN0VHJlZU1vZGVsIHRlc3RNb2RlbD0gKFRlc3RUcmVlTW9kZWwpbW9kZWw7DQoJCQkJVGVzdCB0PSAoVGVzdCl2YWx1ZTsNCgkJCQlTdHJpbmcgcz0gIiI7DQoJICAgIAkJaWYgKHRlc3RNb2RlbC5pc0ZhaWx1cmUodCkpIHsNCgkgICAgCQkJaWYgKGZGYWlsdXJlSWNvbiAhPSBudWxsKQ0KCSAgICAJCQkJc2V0SWNvbihmRmFpbHVyZUljb24pOw0KCSAgICAJCQlzPSAiIC0gRmFpbGVkIjsNCgkgICAgCQl9DQoJICAgIAkJZWxzZSBpZiAodGVzdE1vZGVsLmlzRXJyb3IodCkpIHsNCgkgICAgCQkJaWYgKGZFcnJvckljb24gIT0gbnVsbCkNCgkgICAgCQkJCXNldEljb24oZkVycm9ySWNvbik7DQoJICAgIAkJCXM9ICIgLSBFcnJvciI7DQoJICAgIAkJfQ0KCSAgICAJCWVsc2UgaWYgKHRlc3RNb2RlbC53YXNSdW4odCkpIHsNCgkgICAgCQkJaWYgKGZPa0ljb24gIT0gbnVsbCkNCgkgICAgCQkJCXNldEljb24oZk9rSWNvbik7DQoJICAgIAkJCXM9ICIgLSBQYXNzZWQiOw0KCSAgICAJCX0NCgkgICAgCQlpZiAoYyBpbnN0YW5jZW9mIEpDb21wb25lbnQpDQoJICAgIAkJCSgoSkNvbXBvbmVudCljKS5zZXRUb29sVGlwVGV4dChnZXRUZXh0KCkrcyk7DQoJICAJCX0NCgkgIAkJc2V0VGV4dChzdHJpcFBhcmVudGhlc2lzKHZhbHVlKSk7DQoJCQlyZXR1cm4gYzsNCgkJfQ0KCX0NCgkNCglwdWJsaWMgVGVzdFN1aXRlUGFuZWwoKSB7DQoJCXN1cGVyKG5ldyBCb3JkZXJMYXlvdXQoKSk7DQoJCXNldFByZWZlcnJlZFNpemUobmV3IERpbWVuc2lvbigzMDAsIDEwMCkpOw0KCQlmVHJlZT0gbmV3IEpUcmVlKCk7DQoJCWZUcmVlLnNldE1vZGVsKG51bGwpOw0KCQlmVHJlZS5zZXRSb3dIZWlnaHQoMjApOw0KCQlUb29sVGlwTWFuYWdlci5zaGFyZWRJbnN0YW5jZSgpLnJlZ2lzdGVyQ29tcG9uZW50KGZUcmVlKTsJDQoJCWZUcmVlLnB1dENsaWVudFByb3BlcnR5KCJKVHJlZS5saW5lU3R5bGUiLCAiQW5nbGVkIik7DQoJCWZTY3JvbGxUcmVlPSBuZXcgSlNjcm9sbFBhbmUoZlRyZWUpOw0KCQlhZGQoZlNjcm9sbFRyZWUsIEJvcmRlckxheW91dC5DRU5URVIpOw0KCX0NCgkJDQoJcHVibGljIHZvaWQgYWRkRXJyb3IoZmluYWwgVGVzdCB0ZXN0LCBmaW5hbCBUaHJvd2FibGUgdCkgew0KIAkJZk1vZGVsLmFkZEVycm9yKHRlc3QpOw0KCQlmaXJlVGVzdENoYW5nZWQodGVzdCwgdHJ1ZSk7DQoJfQ0KCQ0KCXB1YmxpYyB2b2lkIGFkZEZhaWx1cmUoZmluYWwgVGVzdCB0ZXN0LCBmaW5hbCBBc3NlcnRpb25GYWlsZWRFcnJvciB0KSB7DQogCQlmTW9kZWwuYWRkRmFpbHVyZSh0ZXN0KTsNCgkJZmlyZVRlc3RDaGFuZ2VkKHRlc3QsIHRydWUpOw0KCX0NCgkNCgkvKioNCiAJICogQSB0ZXN0IGVuZGVkLg0KIAkgKi8NCiAJcHVibGljIHZvaWQgZW5kVGVzdChUZXN0IHRlc3QpIHsNCgkJZk1vZGVsLmFkZFJ1blRlc3QodGVzdCk7DQoJIAlmaXJlVGVzdENoYW5nZWQodGVzdCwgZmFsc2UpOw0KIAl9DQoNCgkvKioNCiAJICogQSB0ZXN0IHN0YXJ0ZWQuDQogCSAqLw0KIAlwdWJsaWMgdm9pZCBzdGFydFRlc3QoVGVzdCB0ZXN0KSB7DQogCX0gCSAgDQogCQkJDQoJLyoqDQoJICogUmV0dXJucyB0aGUgc2VsZWN0ZWQgdGVzdCBvciBudWxsIGlmIG11bHRpcGxlIG9yIG5vbmUgaXMgc2VsZWN0ZWQNCgkgKi8NCglwdWJsaWMgVGVzdCBnZXRTZWxlY3RlZFRlc3QoKSB7DQoJCVRyZWVQYXRoW10gcGF0aHM9IGZUcmVlLmdldFNlbGVjdGlvblBhdGhzKCk7DQoJCWlmIChwYXRocyAhPSBudWxsICYmIHBhdGhzLmxlbmd0aCA9PSAxKQ0KCQkJcmV0dXJuIChUZXN0KXBhdGhzWzBdLmdldExhc3RQYXRoQ29tcG9uZW50KCk7DQoJCXJldHVybiBudWxsOw0KCX0NCg0KCS8qKg0KCSAqIFJldHVybnMgdGhlIFRyZWUNCgkgKi8NCglwdWJsaWMgSlRyZWUgZ2V0VHJlZSgpIHsNCgkJcmV0dXJuIGZUcmVlOw0KCX0NCg0KCS8qKg0KCSAqIFNob3dzIHRoZSB0ZXN0IGhpZXJhcmNoeSBzdGFydGluZyBhdCB0aGUgZ2l2ZW4gdGVzdA0KCSAqLw0KCXB1YmxpYyB2b2lkIHNob3dUZXN0VHJlZShUZXN0IHJvb3QpIHsNCgkJZk1vZGVsPSBuZXcgVGVzdFRyZWVNb2RlbChyb290KTsNCgkJZlRyZWUuc2V0TW9kZWwoZk1vZGVsKTsNCgkJZlRyZWUuc2V0Q2VsbFJlbmRlcmVyKG5ldyBUZXN0VHJlZUNlbGxSZW5kZXJlcigpKTsNCgl9DQoJDQoJcHJpdmF0ZSB2b2lkIGZpcmVUZXN0Q2hhbmdlZChmaW5hbCBUZXN0IHRlc3QsIGZpbmFsIGJvb2xlYW4gZXhwYW5kKSB7DQoJCVN3aW5nVXRpbGl0aWVzLmludm9rZUxhdGVyKA0KCQkJbmV3IFJ1bm5hYmxlKCkgew0KCQkJCXB1YmxpYyB2b2lkIHJ1bigpIHsNCgkJCQkJVmVjdG9yIHZwYXRoPSBuZXcgVmVjdG9yKCk7DQoJCQkJCWludCBpbmRleD0gZk1vZGVsLmZpbmRUZXN0KHRlc3QsIChUZXN0KWZNb2RlbC5nZXRSb290KCksIHZwYXRoKTsNCgkJCQkJaWYgKGluZGV4ID49IDApIHsNCgkJCQkJCU9iamVjdFtdIHBhdGg9IG5ldyBPYmplY3RbdnBhdGguc2l6ZSgpXTsNCgkJCQkJCXZwYXRoLmNvcHlJbnRvKHBhdGgpOw0KCQkJCQkJVHJlZVBhdGggdHJlZVBhdGg9IG5ldyBUcmVlUGF0aChwYXRoKTsNCgkJCQkJCWZNb2RlbC5maXJlTm9kZUNoYW5nZWQodHJlZVBhdGgsIGluZGV4KTsNCgkJCQkJCWlmIChleHBhbmQpIHsNCgkJCQkJCQlPYmplY3RbXSBmdWxsUGF0aD0gbmV3IE9iamVjdFt2cGF0aC5zaXplKCkrMV07DQoJCQkJCQkJdnBhdGguY29weUludG8oZnVsbFBhdGgpOw0KCQkJCQkJCWZ1bGxQYXRoW3ZwYXRoLnNpemUoKV09IGZNb2RlbC5nZXRDaGlsZCh0cmVlUGF0aC5nZXRMYXN0UGF0aENvbXBvbmVudCgpLCBpbmRleCk7Ow0KCQkJCQkJCVRyZWVQYXRoIGZ1bGxUcmVlUGF0aD0gbmV3IFRyZWVQYXRoKGZ1bGxQYXRoKTsNCgkJCQkJCQlmVHJlZS5zY3JvbGxQYXRoVG9WaXNpYmxlKGZ1bGxUcmVlUGF0aCk7DQoJCQkJCQl9DQoJCQkJCX0NCgkJCQl9DQoJCQl9DQoJCSk7DQoJfQ0KfVBLAwQKAAAAAADqeMcwTcHYx7gDAAC4AwAAHQAAAGp1bml0L3N3aW5ndWkvU3RhdHVzTGluZS5qYXZhcGFja2FnZSBqdW5pdC5zd2luZ3VpOw0KDQppbXBvcnQgamF2YS5hd3QuKjsNCg0KaW1wb3J0IGphdmF4LnN3aW5nLio7DQppbXBvcnQgamF2YXguc3dpbmcuYm9yZGVyLkJldmVsQm9yZGVyOw0KDQovKioNCiAqIEEgc3RhdHVzIGxpbmUgY29tcG9uZW50Lg0KICovDQpwdWJsaWMgY2xhc3MgU3RhdHVzTGluZSBleHRlbmRzIEpUZXh0RmllbGQgew0KCXB1YmxpYyBzdGF0aWMgZmluYWwgRm9udCBQTEFJTl9GT05UPSBuZXcgRm9udCgiZGlhbG9nIiwgRm9udC5QTEFJTiwgMTIpOw0KCXB1YmxpYyBzdGF0aWMgZmluYWwgRm9udCBCT0xEX0ZPTlQ9IG5ldyBGb250KCJkaWFsb2ciLCBGb250LkJPTEQsIDEyKTsNCg0KCXB1YmxpYyBTdGF0dXNMaW5lKGludCBwcmVmZXJyZWRXaWR0aCkgew0KCQlzdXBlcigpOw0KCQlzZXRGb250KEJPTERfRk9OVCk7DQoJCXNldEVkaXRhYmxlKGZhbHNlKTsNCgkJc2V0Qm9yZGVyKEJvcmRlckZhY3RvcnkuY3JlYXRlQmV2ZWxCb3JkZXIoQmV2ZWxCb3JkZXIuTE9XRVJFRCkpOw0KCQlEaW1lbnNpb24gZD0gZ2V0UHJlZmVycmVkU2l6ZSgpOw0KCQlkLndpZHRoPSBwcmVmZXJyZWRXaWR0aDsNCgkJc2V0UHJlZmVycmVkU2l6ZShkKTsNCgl9DQoJDQoJcHVibGljIHZvaWQgc2hvd0luZm8oU3RyaW5nIG1lc3NhZ2UpIHsNCgkJc2V0Rm9udChQTEFJTl9GT05UKTsNCgkJc2V0Rm9yZWdyb3VuZChDb2xvci5ibGFjayk7DQoJCXNldFRleHQobWVzc2FnZSk7DQoJfQ0KCQ0KCXB1YmxpYyB2b2lkIHNob3dFcnJvcihTdHJpbmcgc3RhdHVzKSB7DQoJCXNldEZvbnQoQk9MRF9GT05UKTsNCgkJc2V0Rm9yZWdyb3VuZChDb2xvci5yZWQpOw0KCQlzZXRUZXh0KHN0YXR1cyk7DQoJCXNldFRvb2xUaXBUZXh0KHN0YXR1cyk7DQoJfQ0KCQ0KCXB1YmxpYyB2b2lkIGNsZWFyKCkgew0KCQlzZXRUZXh0KCIiKTsNCgkJc2V0VG9vbFRpcFRleHQobnVsbCk7DQoJfQ0KfVBLAwQKAAAAAADqeMcwYzZfdygJAAAoCQAAKwAAAGp1bml0L3N3aW5ndWkvRGVmYXVsdEZhaWx1cmVEZXRhaWxWaWV3LmphdmFwYWNrYWdlIGp1bml0LnN3aW5ndWk7DQoNCmltcG9ydCBqYXZhLmF3dC4qOw0KaW1wb3J0IGphdmEudXRpbC4qOw0KDQppbXBvcnQgamF2YXguc3dpbmcuKjsNCmltcG9ydCBqdW5pdC5mcmFtZXdvcmsuVGVzdEZhaWx1cmU7DQppbXBvcnQganVuaXQucnVubmVyLio7DQoNCi8qKg0KICogQSB2aWV3IHRoYXQgc2hvd3MgYSBzdGFjayB0cmFjZSBvZiBhIGZhaWx1cmUNCiAqLw0KcHVibGljIGNsYXNzIERlZmF1bHRGYWlsdXJlRGV0YWlsVmlldyBpbXBsZW1lbnRzIEZhaWx1cmVEZXRhaWxWaWV3IHsNCglKTGlzdCBmTGlzdDsgIA0KCQ0KCS8qKg0KCSAqIEEgTGlzdE1vZGVsIHJlcHJlc2VudGluZyB0aGUgc2Nhbm5lZCBmYWlsdXJlIHN0YWNrIHRyYWNlLg0KCSAqLw0KCXN0YXRpYyBjbGFzcyBTdGFja1RyYWNlTGlzdE1vZGVsIGV4dGVuZHMgQWJzdHJhY3RMaXN0TW9kZWwgew0KCQlwcml2YXRlIFZlY3RvciBmTGluZXM9IG5ldyBWZWN0b3IoMjApOw0KCQkNCgkJcHVibGljIE9iamVjdCBnZXRFbGVtZW50QXQoaW50IGluZGV4KSB7DQoJCQlyZXR1cm4gZkxpbmVzLmVsZW1lbnRBdChpbmRleCk7DQoJCX0NCg0KCQlwdWJsaWMgaW50IGdldFNpemUoKSB7DQoJCQlyZXR1cm4gZkxpbmVzLnNpemUoKTsNCgkJfQ0KCQkNCgkJcHVibGljIHZvaWQgc2V0VHJhY2UoU3RyaW5nIHRyYWNlKSB7DQoJCQlzY2FuKHRyYWNlKTsNCgkJCWZpcmVDb250ZW50c0NoYW5nZWQodGhpcywgMCwgZkxpbmVzLnNpemUoKSk7DQoJCX0NCgkJDQoJCXB1YmxpYyB2b2lkIGNsZWFyKCkgew0KCQkJZkxpbmVzLnJlbW92ZUFsbEVsZW1lbnRzKCk7DQoJCQlmaXJlQ29udGVudHNDaGFuZ2VkKHRoaXMsIDAsIGZMaW5lcy5zaXplKCkpOw0KCQl9DQoJCQ0KCQlwcml2YXRlIHZvaWQgc2NhbihTdHJpbmcgdHJhY2UpIHsNCgkJCWZMaW5lcy5yZW1vdmVBbGxFbGVtZW50cygpOw0KICAgICAJCVN0cmluZ1Rva2VuaXplciBzdD0gbmV3IFN0cmluZ1Rva2VuaXplcih0cmFjZSwgIlxuXHIiLCBmYWxzZSk7DQoJICAgIAl3aGlsZSAoc3QuaGFzTW9yZVRva2VucygpKSANCiAJCQkJZkxpbmVzLmFkZChzdC5uZXh0VG9rZW4oKSk7DQoJCX0NCgl9DQoJDQoJLyoqDQoJICogUmVuZGVyZXIgZm9yIHN0YWNrIGVudHJpZXMNCgkgKi8NCglzdGF0aWMgY2xhc3MgU3RhY2tFbnRyeVJlbmRlcmVyIGV4dGVuZHMgRGVmYXVsdExpc3RDZWxsUmVuZGVyZXIgew0KCQkJCQkJDQoJCXB1YmxpYyBDb21wb25lbnQgZ2V0TGlzdENlbGxSZW5kZXJlckNvbXBvbmVudCgNCgkJCQlKTGlzdCBsaXN0LCBPYmplY3QgdmFsdWUsIGludCBtb2RlbEluZGV4LCANCgkJCQlib29sZWFuIGlzU2VsZWN0ZWQsIGJvb2xlYW4gY2VsbEhhc0ZvY3VzKSB7DQoJCQlTdHJpbmcgdGV4dD0gKChTdHJpbmcpdmFsdWUpLnJlcGxhY2UoJ1x0JywgJyAnKTsNCgkJICAgIENvbXBvbmVudCBjPSBzdXBlci5nZXRMaXN0Q2VsbFJlbmRlcmVyQ29tcG9uZW50KGxpc3QsIHRleHQsIG1vZGVsSW5kZXgsIGlzU2VsZWN0ZWQsIGNlbGxIYXNGb2N1cyk7DQoJCQlzZXRUZXh0KHRleHQpOw0KCQkJc2V0VG9vbFRpcFRleHQodGV4dCk7DQoJCQlyZXR1cm4gYzsNCgkJfQ0KCX0NCgkNCgkvKioNCgkgKiBSZXR1cm5zIHRoZSBjb21wb25lbnQgdXNlZCB0byBwcmVzZW50IHRoZSB0cmFjZQ0KCSAqLw0KCXB1YmxpYyBDb21wb25lbnQgZ2V0Q29tcG9uZW50KCkgew0KCQlpZiAoZkxpc3QgPT0gbnVsbCkgew0KCQkJZkxpc3Q9IG5ldyBKTGlzdChuZXcgU3RhY2tUcmFjZUxpc3RNb2RlbCgpKTsNCgkJCWZMaXN0LnNldEZvbnQobmV3IEZvbnQoIkRpYWxvZyIsIEZvbnQuUExBSU4sIDEyKSk7DQoJCQlmTGlzdC5zZXRTZWxlY3Rpb25Nb2RlKExpc3RTZWxlY3Rpb25Nb2RlbC5TSU5HTEVfU0VMRUNUSU9OKTsNCgkJCWZMaXN0LnNldFZpc2libGVSb3dDb3VudCg1KTsNCgkJCWZMaXN0LnNldENlbGxSZW5kZXJlcihuZXcgU3RhY2tFbnRyeVJlbmRlcmVyKCkpOw0KCQl9DQoJCXJldHVybiBmTGlzdDsNCgl9DQoJDQoJLyoqDQoJICogU2hvd3MgYSBUZXN0RmFpbHVyZQ0KCSAqLw0KCXB1YmxpYyB2b2lkIHNob3dGYWlsdXJlKFRlc3RGYWlsdXJlIGZhaWx1cmUpIHsNCgkJZ2V0TW9kZWwoKS5zZXRUcmFjZShCYXNlVGVzdFJ1bm5lci5nZXRGaWx0ZXJlZFRyYWNlKGZhaWx1cmUudHJhY2UoKSkpOw0KCX0NCgkvKioNCgkgKiBDbGVhcnMgdGhlIG91dHB1dC4NCgkgKi8NCglwdWJsaWMgdm9pZCBjbGVhcigpIHsNCgkJZ2V0TW9kZWwoKS5jbGVhcigpOw0KCX0NCgkNCglwcml2YXRlIFN0YWNrVHJhY2VMaXN0TW9kZWwgZ2V0TW9kZWwoKSB7DQoJCXJldHVybiAJKFN0YWNrVHJhY2VMaXN0TW9kZWwpZkxpc3QuZ2V0TW9kZWwoKTsNCgl9DQp9UEsDBAoAAAAAAOp4xzARU1aZ6QIAAOkCAAAeAAAAanVuaXQvc3dpbmd1aS9Qcm9ncmVzc0Jhci5qYXZhcGFja2FnZSBqdW5pdC5zd2luZ3VpOw0KDQppbXBvcnQgamF2YS5hd3QuQ29sb3I7DQoNCmltcG9ydCBqYXZheC5zd2luZy5KUHJvZ3Jlc3NCYXI7DQoNCi8qKg0KICogQSBwcm9ncmVzcyBiYXIgc2hvd2luZyB0aGUgZ3JlZW4vcmVkIHN0YXR1cw0KICovDQpjbGFzcyBQcm9ncmVzc0JhciBleHRlbmRzIEpQcm9ncmVzc0JhciB7DQoJYm9vbGVhbiBmRXJyb3I9IGZhbHNlOw0KCQ0KCXB1YmxpYyBQcm9ncmVzc0JhcigpIHsNCgkJc3VwZXIoKTsgDQoJCXNldEZvcmVncm91bmQoZ2V0U3RhdHVzQ29sb3IoKSk7DQoJfQ0KCQ0KCXByaXZhdGUgQ29sb3IgZ2V0U3RhdHVzQ29sb3IoKSB7DQoJCWlmIChmRXJyb3IpDQoJCQlyZXR1cm4gQ29sb3IucmVkOw0KCQlyZXR1cm4gQ29sb3IuZ3JlZW47DQoJfQ0KCQkNCglwdWJsaWMgdm9pZCByZXNldCgpIHsNCgkJZkVycm9yPSBmYWxzZTsNCgkJc2V0Rm9yZWdyb3VuZChnZXRTdGF0dXNDb2xvcigpKTsNCgkJc2V0VmFsdWUoMCk7DQoJfQ0KCQ0KCXB1YmxpYyB2b2lkIHN0YXJ0KGludCB0b3RhbCkgew0KCQlzZXRNYXhpbXVtKHRvdGFsKTsNCgkJcmVzZXQoKTsNCgl9DQoJDQoJcHVibGljIHZvaWQgc3RlcChpbnQgdmFsdWUsIGJvb2xlYW4gc3VjY2Vzc2Z1bCkgew0KCQlzZXRWYWx1ZSh2YWx1ZSk7DQoJCWlmICghZkVycm9yICYmICFzdWNjZXNzZnVsKSB7DQoJCQlmRXJyb3I9IHRydWU7DQoJCQlzZXRGb3JlZ3JvdW5kKGdldFN0YXR1c0NvbG9yKCkpOw0KCQl9DQoJfQ0KfVBLAwQKAAAAAADqeMcwg8Bz/WQDAABkAwAAHQAAAGp1bml0L3N3aW5ndWkvaWNvbnMvZXJyb3IuZ2lmR0lGODlhCwAQAOcAAAAAAIAAAACAAICAAAAAgIAAgACAgMDAwMDcwKbK8BERESIiIjMzM0RERFVVVWZmZnd3d4iIiJmZmaqqqru7u8zMzN3d3e7u7l9/P39/P59/P79/P99/P/9/Pz+fP1+fP3+fP5+fP7+fP9+fP/+fPz+/P1+/P3+/P5+/P7+/P9+/P/+/Pz/fP1/fP3/fP5/fP7/fP9/fP//fPz//P1//P3//P5//P7//P9//P///Pz8/X18/X38/X58/X78/X98/X/8/Xz9fX19fX39fX59fX79fX99fX/9fXz9/X19/X39/X59/X79/X99/X/9/Xz+fX1+fX3+fX5+fX7+fX9+fX/+fXz+/X1+/X3+/X5+/X7+/X9+/X/+/Xz/fX1/fX3/fX5/fX7/fX9/fX//fXz//X1//X3//X5//X7//X9//X///Xz8/f18/f38/f58/f78/f98/f/8/fz9ff19ff39ff59ff79ff99ff/9ffz9/f19/f39/f59/f79/f99/f/9/fz+ff1+ff3+ff5+ff7+ff9+ff/+ffz+/f1+/f3+/f5+/f7+/f9+/f/+/fz/ff1/ff3/ff5/ff7/ff9/ff//ffz//f1//f3//f5//f7//f9//f///fz8/n18/n38/n58/n78/n98/n/8/nz9fn19fn39fn59fn79fn99fn/9fnz9/n19/n39/n59/n79/n99/n/9/nz+fn1+fn3+fn5+fn7+fn9+fn/+fnz+/n1+/n3+/n5+/n7+/n9+/n/+/nz/fn1/fn3/fn5/fn7/fn9/fn//fnz//n1//n3//n5//n7//n9//n///nz8/v18/v38/v58/v78/v98/v/8/vz9fv19fv39fv59fv79fv99fv/9fvz9/v19/v39/v59/v79/v99/v/9/vz+fv1+fv3+fv5+fv7+fv9+fv/+fvz+/v1+/v3+/v5+/v7+/v9+/v/+/vz/fv1/fv3/fv5/fv7/fv9/fv//78KCgpICAgP8AAAD/AP//AAAA//8A/wD//////yH5BAEAAAAALAAAAAALABAABwhBAAH8G0iwoMB8AfINTBjgn8B/CAdGdPgQ4UQAGCs2pJhxoUKODxl+xOixpMN/DCUmPFmwZcaXMGPKnEmzps2MAQEAO1BLAwQKAAAAAADqeMcwMPR2B14DAABeAwAAHwAAAGp1bml0L3N3aW5ndWkvaWNvbnMvZmFpbHVyZS5naWZHSUY4OWELABAA5wAAAAAAgAAAAIAAgIAAAACAgACAAICAwMDAwNzApsrwERERIiIiMzMzREREVVVVZmZmd3d3iIiImZmZqqqqu7u7zMzM3d3d7u7uX38/f38/n38/v38/338//38/P58/X58/f58/n58/v58/358//58/P78/X78/f78/n78/v78/378//78/P98/X98/f98/n98/v98/398//98/P/8/X/8/f/8/n/8/v/8/3/8///8/Pz9fXz9ffz9fnz9fvz9f3z9f/z9fP19fX19ff19fn19fv19f319f/19fP39fX39ff39fn39fv39f339f/39fP59fX59ff59fn59fv59f359f/59fP79fX79ff79fn79fv79f379f/79fP99fX99ff99fn99fv99f399f/99fP/9fX/9ff/9fn/9fv/9f3/9f//9fPz9/Xz9/fz9/nz9/vz9/3z9//z9/P19/X19/f19/n19/v19/319//19/P39/X39/f39/n39/v39/339//39/P59/X59/f59/n59/v59/359//59/P79/X79/f79/n79/v79/379//79/P99/X99/f99/n99/v99/399//99/P/9/X/9/f/9/n/9/v/9/3/9///9/Pz+fXz+ffz+fnz+fvz+f3z+f/z+fP1+fX1+ff1+fn1+fv1+f31+f/1+fP3+fX3+ff3+fn3+fv3+f33+f/3+fP5+fX5+ff5+fn5+fv5+f35+f/5+fP7+fX7+ff7+fn7+fv7+f37+f/7+fP9+fX9+ff9+fn9+fv9+f39+f/9+fP/+fX/+ff/+fn/+fv/+f3/+f//+fPz+/Xz+/fz+/nz+/vz+/3z+//z+/P1+/X1+/f1+/n1+/v1+/31+//1+/P3+/X3+/f3+/n3+/v3+/33+//3+/P5+/X5+/f5+/n5+/v5+/35+//5+/P7+/X7+/f7+/n7+/v7+/37+//7+/P9+/X9+/f9+/n9+/v9+/39+///vwoKCkgICA/wAAAP8A//8AAAD//wD/AP//////IfkEAQAAAAAsAAAAAAsAEAAHCDsAAfwbSLCgQHwIByLE90/gv4QPGTZ0uFAigIsULWLMOHCjwoUdOUbsGFEiSIcFDW5cybKly5cwY64MCAA7UEsDBAoAAAAAAOp4xzAq08bYewMAAHsDAAAhAAAAanVuaXQvc3dpbmd1aS9pY29ucy9oaWVyYXJjaHkuZ2lmR0lGODlhEAAOAPcAAAAAAIAAAACAAICAAAAAgIAAgACAgMDAwMDcwKbK8P///wAAhACEhISEAISEhKWlpcbexv/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////78KCgpICAgP8AAAD/AP//AAAA//8A/wD//////yH5BAEAAP4ALAAAAAAQAA4AAAhYAP0JHOgPAoMGCxwQXDhwwQIAChkShOCgYkSJBAFgZAjgwYKN/hgwSBhy5MWBBhE6SEmSoUOI/l6eFEjRYs2KGDWCHNjx40aRJIHOLHgwIcuhMR8qlLkwIAA7UEsDBAoAAAAAAOp4xzBEt5WfVQAAAFUAAAAaAAAAanVuaXQvc3dpbmd1aS9pY29ucy9vay5naWZHSUY4OWELABAAkQMAmvaaAP8AyNHa8PDwIfkEAQAAAwAsAAAAAAsAEABAAiacjzEBwCAEmiyaZqe+YDXeGQ+2SdvJoJB4PJbrtg1minONRPg5FQA7UEsDBAoAAAAAAOp4xzBbc+mVAxIAAAMSAAAcAAAAanVuaXQvdGV4dHVpL1Rlc3RSdW5uZXIuamF2YXBhY2thZ2UganVuaXQudGV4dHVpOw0KDQoNCmltcG9ydCBqYXZhLmlvLlByaW50U3RyZWFtOw0KDQppbXBvcnQganVuaXQuZnJhbWV3b3JrLio7DQppbXBvcnQganVuaXQucnVubmVyLio7DQoNCi8qKg0KICogQSBjb21tYW5kIGxpbmUgYmFzZWQgdG9vbCB0byBydW4gdGVzdHMuDQogKiA8cHJlPg0KICogamF2YSBqdW5pdC50ZXh0dWkuVGVzdFJ1bm5lciBbLXdhaXRdIFRlc3RDYXNlQ2xhc3MNCiAqIDwvcHJlPg0KICogVGVzdFJ1bm5lciBleHBlY3RzIHRoZSBuYW1lIG9mIGEgVGVzdENhc2UgY2xhc3MgYXMgYXJndW1lbnQuDQogKiBJZiB0aGlzIGNsYXNzIGRlZmluZXMgYSBzdGF0aWMgPGNvZGU+c3VpdGU8L2NvZGU+IG1ldGhvZCBpdCANCiAqIHdpbGwgYmUgaW52b2tlZCBhbmQgdGhlIHJldHVybmVkIHRlc3QgaXMgcnVuLiBPdGhlcndpc2UgYWxsIA0KICogdGhlIG1ldGhvZHMgc3RhcnRpbmcgd2l0aCAidGVzdCIgaGF2aW5nIG5vIGFyZ3VtZW50cyBhcmUgcnVuLg0KICogPHA+DQogKiBXaGVuIHRoZSB3YWl0IGNvbW1hbmQgbGluZSBhcmd1bWVudCBpcyBnaXZlbiBUZXN0UnVubmVyDQogKiB3YWl0cyB1bnRpbCB0aGUgdXNlcnMgdHlwZXMgUkVUVVJOLg0KICogPHA+DQogKiBUZXN0UnVubmVyIHByaW50cyBhIHRyYWNlIGFzIHRoZSB0ZXN0cyBhcmUgZXhlY3V0ZWQgZm9sbG93ZWQgYnkgYQ0KICogc3VtbWFyeSBhdCB0aGUgZW5kLiANCiAqLw0KcHVibGljIGNsYXNzIFRlc3RSdW5uZXIgZXh0ZW5kcyBCYXNlVGVzdFJ1bm5lciB7DQoJcHJpdmF0ZSBSZXN1bHRQcmludGVyIGZQcmludGVyOw0KCQ0KCXB1YmxpYyBzdGF0aWMgZmluYWwgaW50IFNVQ0NFU1NfRVhJVD0gMDsNCglwdWJsaWMgc3RhdGljIGZpbmFsIGludCBGQUlMVVJFX0VYSVQ9IDE7DQoJcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgRVhDRVBUSU9OX0VYSVQ9IDI7DQoNCgkvKioNCgkgKiBDb25zdHJ1Y3RzIGEgVGVzdFJ1bm5lci4NCgkgKi8NCglwdWJsaWMgVGVzdFJ1bm5lcigpIHsNCgkJdGhpcyhTeXN0ZW0ub3V0KTsNCgl9DQoNCgkvKioNCgkgKiBDb25zdHJ1Y3RzIGEgVGVzdFJ1bm5lciB1c2luZyB0aGUgZ2l2ZW4gc3RyZWFtIGZvciBhbGwgdGhlIG91dHB1dA0KCSAqLw0KCXB1YmxpYyBUZXN0UnVubmVyKFByaW50U3RyZWFtIHdyaXRlcikgew0KCQl0aGlzKG5ldyBSZXN1bHRQcmludGVyKHdyaXRlcikpOw0KCX0NCgkNCgkvKioNCgkgKiBDb25zdHJ1Y3RzIGEgVGVzdFJ1bm5lciB1c2luZyB0aGUgZ2l2ZW4gUmVzdWx0UHJpbnRlciBhbGwgdGhlIG91dHB1dA0KCSAqLw0KCXB1YmxpYyBUZXN0UnVubmVyKFJlc3VsdFByaW50ZXIgcHJpbnRlcikgew0KCQlmUHJpbnRlcj0gcHJpbnRlcjsNCgl9DQoJDQoJLyoqDQoJICogUnVucyBhIHN1aXRlIGV4dHJhY3RlZCBmcm9tIGEgVGVzdENhc2Ugc3ViY2xhc3MuDQoJICovDQoJc3RhdGljIHB1YmxpYyB2b2lkIHJ1bihDbGFzcyB0ZXN0Q2xhc3MpIHsNCgkJcnVuKG5ldyBUZXN0U3VpdGUodGVzdENsYXNzKSk7DQoJfQ0KDQoJLyoqDQoJICogUnVucyBhIHNpbmdsZSB0ZXN0IGFuZCBjb2xsZWN0cyBpdHMgcmVzdWx0cy4NCgkgKiBUaGlzIG1ldGhvZCBjYW4gYmUgdXNlZCB0byBzdGFydCBhIHRlc3QgcnVuDQoJICogZnJvbSB5b3VyIHByb2dyYW0uDQoJICogPHByZT4NCgkgKiBwdWJsaWMgc3RhdGljIHZvaWQgbWFpbiAoU3RyaW5nW10gYXJncykgew0KCSAqICAgICB0ZXN0LnRleHR1aS5UZXN0UnVubmVyLnJ1bihzdWl0ZSgpKTsNCgkgKiB9DQoJICogPC9wcmU+DQoJICovDQoJc3RhdGljIHB1YmxpYyBUZXN0UmVzdWx0IHJ1bihUZXN0IHRlc3QpIHsNCgkJVGVzdFJ1bm5lciBydW5uZXI9IG5ldyBUZXN0UnVubmVyKCk7DQoJCXJldHVybiBydW5uZXIuZG9SdW4odGVzdCk7DQoJfQ0KDQoJLyoqDQoJICogUnVucyBhIHNpbmdsZSB0ZXN0IGFuZCB3YWl0cyB1bnRpbCB0aGUgdXNlcg0KCSAqIHR5cGVzIFJFVFVSTi4NCgkgKi8NCglzdGF0aWMgcHVibGljIHZvaWQgcnVuQW5kV2FpdChUZXN0IHN1aXRlKSB7DQoJCVRlc3RSdW5uZXIgYVRlc3RSdW5uZXI9IG5ldyBUZXN0UnVubmVyKCk7DQoJCWFUZXN0UnVubmVyLmRvUnVuKHN1aXRlLCB0cnVlKTsNCgl9DQoNCgkvKioNCgkgKiBBbHdheXMgdXNlIHRoZSBTdGFuZGFyZFRlc3RTdWl0ZUxvYWRlci4gT3ZlcnJpZGRlbiBmcm9tDQoJICogQmFzZVRlc3RSdW5uZXIuDQoJICovDQoJcHVibGljIFRlc3RTdWl0ZUxvYWRlciBnZXRMb2FkZXIoKSB7DQoJCXJldHVybiBuZXcgU3RhbmRhcmRUZXN0U3VpdGVMb2FkZXIoKTsNCgl9DQoNCglwdWJsaWMgdm9pZCB0ZXN0RmFpbGVkKGludCBzdGF0dXMsIFRlc3QgdGVzdCwgVGhyb3dhYmxlIHQpIHsNCgl9DQoJDQoJcHVibGljIHZvaWQgdGVzdFN0YXJ0ZWQoU3RyaW5nIHRlc3ROYW1lKSB7DQoJfQ0KCQ0KCXB1YmxpYyB2b2lkIHRlc3RFbmRlZChTdHJpbmcgdGVzdE5hbWUpIHsNCgl9DQoNCgkvKioNCgkgKiBDcmVhdGVzIHRoZSBUZXN0UmVzdWx0IHRvIGJlIHVzZWQgZm9yIHRoZSB0ZXN0IHJ1bi4NCgkgKi8NCglwcm90ZWN0ZWQgVGVzdFJlc3VsdCBjcmVhdGVUZXN0UmVzdWx0KCkgew0KCQlyZXR1cm4gbmV3IFRlc3RSZXN1bHQoKTsNCgl9DQoJDQoJcHVibGljIFRlc3RSZXN1bHQgZG9SdW4oVGVzdCB0ZXN0KSB7DQoJCXJldHVybiBkb1J1bih0ZXN0LCBmYWxzZSk7DQoJfQ0KCQ0KCXB1YmxpYyBUZXN0UmVzdWx0IGRvUnVuKFRlc3Qgc3VpdGUsIGJvb2xlYW4gd2FpdCkgew0KCQlUZXN0UmVzdWx0IHJlc3VsdD0gY3JlYXRlVGVzdFJlc3VsdCgpOw0KCQlyZXN1bHQuYWRkTGlzdGVuZXIoZlByaW50ZXIpOw0KCQlsb25nIHN0YXJ0VGltZT0gU3lzdGVtLmN1cnJlbnRUaW1lTWlsbGlzKCk7DQoJCXN1aXRlLnJ1bihyZXN1bHQpOw0KCQlsb25nIGVuZFRpbWU9IFN5c3RlbS5jdXJyZW50VGltZU1pbGxpcygpOw0KCQlsb25nIHJ1blRpbWU9IGVuZFRpbWUtc3RhcnRUaW1lOw0KCQlmUHJpbnRlci5wcmludChyZXN1bHQsIHJ1blRpbWUpOw0KDQoJCXBhdXNlKHdhaXQpOw0KCQlyZXR1cm4gcmVzdWx0Ow0KCX0NCg0KCXByb3RlY3RlZCB2b2lkIHBhdXNlKGJvb2xlYW4gd2FpdCkgew0KCQlpZiAoIXdhaXQpIHJldHVybjsNCgkJZlByaW50ZXIucHJpbnRXYWl0UHJvbXB0KCk7DQoJCXRyeSB7DQoJCQlTeXN0ZW0uaW4ucmVhZCgpOw0KCQl9DQoJCWNhdGNoKEV4Y2VwdGlvbiBlKSB7DQoJCX0NCgl9DQoJDQoJcHVibGljIHN0YXRpYyB2b2lkIG1haW4oU3RyaW5nIGFyZ3NbXSkgew0KCQlUZXN0UnVubmVyIGFUZXN0UnVubmVyPSBuZXcgVGVzdFJ1bm5lcigpOw0KCQl0cnkgew0KCQkJVGVzdFJlc3VsdCByPSBhVGVzdFJ1bm5lci5zdGFydChhcmdzKTsNCgkJCWlmICghci53YXNTdWNjZXNzZnVsKCkpIA0KCQkJCVN5c3RlbS5leGl0KEZBSUxVUkVfRVhJVCk7DQoJCQlTeXN0ZW0uZXhpdChTVUNDRVNTX0VYSVQpOw0KCQl9IGNhdGNoKEV4Y2VwdGlvbiBlKSB7DQoJCQlTeXN0ZW0uZXJyLnByaW50bG4oZS5nZXRNZXNzYWdlKCkpOw0KCQkJU3lzdGVtLmV4aXQoRVhDRVBUSU9OX0VYSVQpOw0KCQl9DQoJfQ0KDQoJLyoqDQoJICogU3RhcnRzIGEgdGVzdCBydW4uIEFuYWx5emVzIHRoZSBjb21tYW5kIGxpbmUgYXJndW1lbnRzDQoJICogYW5kIHJ1bnMgdGhlIGdpdmVuIHRlc3Qgc3VpdGUuDQoJICovDQoJcHJvdGVjdGVkIFRlc3RSZXN1bHQgc3RhcnQoU3RyaW5nIGFyZ3NbXSkgdGhyb3dzIEV4Y2VwdGlvbiB7DQoJCVN0cmluZyB0ZXN0Q2FzZT0gIiI7DQoJCWJvb2xlYW4gd2FpdD0gZmFsc2U7DQoJCQ0KCQlmb3IgKGludCBpPSAwOyBpIDwgYXJncy5sZW5ndGg7IGkrKykgew0KCQkJaWYgKGFyZ3NbaV0uZXF1YWxzKCItd2FpdCIpKQ0KCQkJCXdhaXQ9IHRydWU7DQoJCQllbHNlIGlmIChhcmdzW2ldLmVxdWFscygiLWMiKSkgDQoJCQkJdGVzdENhc2U9IGV4dHJhY3RDbGFzc05hbWUoYXJnc1srK2ldKTsNCgkJCWVsc2UgaWYgKGFyZ3NbaV0uZXF1YWxzKCItdiIpKQ0KCQkJCVN5c3RlbS5lcnIucHJpbnRsbigiSlVuaXQgIitWZXJzaW9uLmlkKCkrIiBieSBLZW50IEJlY2sgYW5kIEVyaWNoIEdhbW1hIik7DQoJCQllbHNlDQoJCQkJdGVzdENhc2U9IGFyZ3NbaV07DQoJCX0NCgkJDQoJCWlmICh0ZXN0Q2FzZS5lcXVhbHMoIiIpKSANCgkJCXRocm93IG5ldyBFeGNlcHRpb24oIlVzYWdlOiBUZXN0UnVubmVyIFstd2FpdF0gdGVzdENhc2VOYW1lLCB3aGVyZSBuYW1lIGlzIHRoZSBuYW1lIG9mIHRoZSBUZXN0Q2FzZSBjbGFzcyIpOw0KDQoJCXRyeSB7DQoJCQlUZXN0IHN1aXRlPSBnZXRUZXN0KHRlc3RDYXNlKTsNCgkJCXJldHVybiBkb1J1bihzdWl0ZSwgd2FpdCk7DQoJCX0NCgkJY2F0Y2goRXhjZXB0aW9uIGUpIHsNCgkJCXRocm93IG5ldyBFeGNlcHRpb24oIkNvdWxkIG5vdCBjcmVhdGUgYW5kIHJ1biB0ZXN0IHN1aXRlOiAiK2UpOw0KCQl9DQoJfQ0KCQkNCglwcm90ZWN0ZWQgdm9pZCBydW5GYWlsZWQoU3RyaW5nIG1lc3NhZ2UpIHsNCgkJU3lzdGVtLmVyci5wcmludGxuKG1lc3NhZ2UpOw0KCQlTeXN0ZW0uZXhpdChGQUlMVVJFX0VYSVQpOw0KCX0NCgkNCglwdWJsaWMgdm9pZCBzZXRQcmludGVyKFJlc3VsdFByaW50ZXIgcHJpbnRlcikgew0KCQlmUHJpbnRlcj0gcHJpbnRlcjsNCgl9DQoJCQ0KCQ0KfVBLAwQKAAAAAADqeMcwh1BZI40OAACNDgAAHwAAAGp1bml0L3RleHR1aS9SZXN1bHRQcmludGVyLmphdmENCnBhY2thZ2UganVuaXQudGV4dHVpOw0KDQppbXBvcnQgamF2YS5pby5QcmludFN0cmVhbTsNCmltcG9ydCBqYXZhLnRleHQuTnVtYmVyRm9ybWF0Ow0KaW1wb3J0IGphdmEudXRpbC5FbnVtZXJhdGlvbjsNCg0KaW1wb3J0IGp1bml0LmZyYW1ld29yay5Bc3NlcnRpb25GYWlsZWRFcnJvcjsNCmltcG9ydCBqdW5pdC5mcmFtZXdvcmsuVGVzdDsNCmltcG9ydCBqdW5pdC5mcmFtZXdvcmsuVGVzdEZhaWx1cmU7DQppbXBvcnQganVuaXQuZnJhbWV3b3JrLlRlc3RMaXN0ZW5lcjsNCmltcG9ydCBqdW5pdC5mcmFtZXdvcmsuVGVzdFJlc3VsdDsNCmltcG9ydCBqdW5pdC5ydW5uZXIuQmFzZVRlc3RSdW5uZXI7DQoNCnB1YmxpYyBjbGFzcyBSZXN1bHRQcmludGVyIGltcGxlbWVudHMgVGVzdExpc3RlbmVyIHsNCglQcmludFN0cmVhbSBmV3JpdGVyOw0KCWludCBmQ29sdW1uPSAwOw0KCQ0KCXB1YmxpYyBSZXN1bHRQcmludGVyKFByaW50U3RyZWFtIHdyaXRlcikgew0KCQlmV3JpdGVyPSB3cml0ZXI7DQoJfQ0KCQ0KCS8qIEFQSSBmb3IgdXNlIGJ5IHRleHR1aS5UZXN0UnVubmVyDQoJICovDQoNCglzeW5jaHJvbml6ZWQgdm9pZCBwcmludChUZXN0UmVzdWx0IHJlc3VsdCwgbG9uZyBydW5UaW1lKSB7DQoJCXByaW50SGVhZGVyKHJ1blRpbWUpOw0KCSAgICBwcmludEVycm9ycyhyZXN1bHQpOw0KCSAgICBwcmludEZhaWx1cmVzKHJlc3VsdCk7DQoJICAgIHByaW50Rm9vdGVyKHJlc3VsdCk7DQoJfQ0KDQoJdm9pZCBwcmludFdhaXRQcm9tcHQoKSB7DQoJCWdldFdyaXRlcigpLnByaW50bG4oKTsNCgkJZ2V0V3JpdGVyKCkucHJpbnRsbigiPFJFVFVSTj4gdG8gY29udGludWUiKTsNCgl9DQoJDQoJLyogSW50ZXJuYWwgbWV0aG9kcyANCgkgKi8NCg0KCXByb3RlY3RlZCB2b2lkIHByaW50SGVhZGVyKGxvbmcgcnVuVGltZSkgew0KCQlnZXRXcml0ZXIoKS5wcmludGxuKCk7DQoJCWdldFdyaXRlcigpLnByaW50bG4oIlRpbWU6ICIrZWxhcHNlZFRpbWVBc1N0cmluZyhydW5UaW1lKSk7DQoJfQ0KCQ0KCXByb3RlY3RlZCB2b2lkIHByaW50RXJyb3JzKFRlc3RSZXN1bHQgcmVzdWx0KSB7DQoJCXByaW50RGVmZWN0cyhyZXN1bHQuZXJyb3JzKCksIHJlc3VsdC5lcnJvckNvdW50KCksICJlcnJvciIpOw0KCX0NCgkNCglwcm90ZWN0ZWQgdm9pZCBwcmludEZhaWx1cmVzKFRlc3RSZXN1bHQgcmVzdWx0KSB7DQoJCXByaW50RGVmZWN0cyhyZXN1bHQuZmFpbHVyZXMoKSwgcmVzdWx0LmZhaWx1cmVDb3VudCgpLCAiZmFpbHVyZSIpOw0KCX0NCgkNCglwcm90ZWN0ZWQgdm9pZCBwcmludERlZmVjdHMoRW51bWVyYXRpb24gYm9vQm9vcywgaW50IGNvdW50LCBTdHJpbmcgdHlwZSkgew0KCQlpZiAoY291bnQgPT0gMCkgcmV0dXJuOw0KCQlpZiAoY291bnQgPT0gMSkNCgkJCWdldFdyaXRlcigpLnByaW50bG4oIlRoZXJlIHdhcyAiICsgY291bnQgKyAiICIgKyB0eXBlICsgIjoiKTsNCgkJZWxzZQ0KCQkJZ2V0V3JpdGVyKCkucHJpbnRsbigiVGhlcmUgd2VyZSAiICsgY291bnQgKyAiICIgKyB0eXBlICsgInM6Iik7DQoJCWZvciAoaW50IGk9IDE7IGJvb0Jvb3MuaGFzTW9yZUVsZW1lbnRzKCk7IGkrKykgew0KCQkJcHJpbnREZWZlY3QoKFRlc3RGYWlsdXJlKSBib29Cb29zLm5leHRFbGVtZW50KCksIGkpOw0KCQl9DQoJfQ0KCQ0KCXB1YmxpYyB2b2lkIHByaW50RGVmZWN0KFRlc3RGYWlsdXJlIGJvb0JvbywgaW50IGNvdW50KSB7IC8vIG9ubHkgcHVibGljIGZvciB0ZXN0aW5nIHB1cnBvc2VzDQoJCXByaW50RGVmZWN0SGVhZGVyKGJvb0JvbywgY291bnQpOw0KCQlwcmludERlZmVjdFRyYWNlKGJvb0Jvbyk7DQoJfQ0KDQoJcHJvdGVjdGVkIHZvaWQgcHJpbnREZWZlY3RIZWFkZXIoVGVzdEZhaWx1cmUgYm9vQm9vLCBpbnQgY291bnQpIHsNCgkJLy8gSSBmZWVsIGxpa2UgbWFraW5nIHRoaXMgYSBwcmludGxuLCB0aGVuIGFkZGluZyBhIGxpbmUgZ2l2aW5nIHRoZSB0aHJvd2FibGUgYSBjaGFuY2UgdG8gcHJpbnQgc29tZXRoaW5nDQoJCS8vIGJlZm9yZSB3ZSBnZXQgdG8gdGhlIHN0YWNrIHRyYWNlLg0KCQlnZXRXcml0ZXIoKS5wcmludChjb3VudCArICIpICIgKyBib29Cb28uZmFpbGVkVGVzdCgpKTsNCgl9DQoNCglwcm90ZWN0ZWQgdm9pZCBwcmludERlZmVjdFRyYWNlKFRlc3RGYWlsdXJlIGJvb0Jvbykgew0KCQlnZXRXcml0ZXIoKS5wcmludChCYXNlVGVzdFJ1bm5lci5nZXRGaWx0ZXJlZFRyYWNlKGJvb0Jvby50cmFjZSgpKSk7DQoJfQ0KDQoJcHJvdGVjdGVkIHZvaWQgcHJpbnRGb290ZXIoVGVzdFJlc3VsdCByZXN1bHQpIHsNCgkJaWYgKHJlc3VsdC53YXNTdWNjZXNzZnVsKCkpIHsNCgkJCWdldFdyaXRlcigpLnByaW50bG4oKTsNCgkJCWdldFdyaXRlcigpLnByaW50KCJPSyIpOw0KCQkJZ2V0V3JpdGVyKCkucHJpbnRsbiAoIiAoIiArIHJlc3VsdC5ydW5Db3VudCgpICsgIiB0ZXN0IiArIChyZXN1bHQucnVuQ291bnQoKSA9PSAxID8gIiI6ICJzIikgKyAiKSIpOw0KDQoJCX0gZWxzZSB7DQoJCQlnZXRXcml0ZXIoKS5wcmludGxuKCk7DQoJCQlnZXRXcml0ZXIoKS5wcmludGxuKCJGQUlMVVJFUyEhISIpOw0KCQkJZ2V0V3JpdGVyKCkucHJpbnRsbigiVGVzdHMgcnVuOiAiK3Jlc3VsdC5ydW5Db3VudCgpKyANCgkJCQkgICAgICAgICAiLCAgRmFpbHVyZXM6ICIrcmVzdWx0LmZhaWx1cmVDb3VudCgpKw0KCQkJCSAgICAgICAgICIsICBFcnJvcnM6ICIrcmVzdWx0LmVycm9yQ291bnQoKSk7DQoJCX0NCgkgICAgZ2V0V3JpdGVyKCkucHJpbnRsbigpOw0KCX0NCg0KDQoJLyoqDQoJICogUmV0dXJucyB0aGUgZm9ybWF0dGVkIHN0cmluZyBvZiB0aGUgZWxhcHNlZCB0aW1lLg0KCSAqIER1cGxpY2F0ZWQgZnJvbSBCYXNlVGVzdFJ1bm5lci4gRml4IGl0Lg0KCSAqLw0KCXByb3RlY3RlZCBTdHJpbmcgZWxhcHNlZFRpbWVBc1N0cmluZyhsb25nIHJ1blRpbWUpIHsNCgkJcmV0dXJuIE51bWJlckZvcm1hdC5nZXRJbnN0YW5jZSgpLmZvcm1hdCgoZG91YmxlKXJ1blRpbWUvMTAwMCk7DQoJfQ0KDQoJcHVibGljIFByaW50U3RyZWFtIGdldFdyaXRlcigpIHsNCgkJcmV0dXJuIGZXcml0ZXI7DQoJfQ0KCS8qKg0KCSAqIEBzZWUganVuaXQuZnJhbWV3b3JrLlRlc3RMaXN0ZW5lciNhZGRFcnJvcihUZXN0LCBUaHJvd2FibGUpDQoJICovDQoJcHVibGljIHZvaWQgYWRkRXJyb3IoVGVzdCB0ZXN0LCBUaHJvd2FibGUgdCkgew0KCQlnZXRXcml0ZXIoKS5wcmludCgiRSIpOw0KCX0NCg0KCS8qKg0KCSAqIEBzZWUganVuaXQuZnJhbWV3b3JrLlRlc3RMaXN0ZW5lciNhZGRGYWlsdXJlKFRlc3QsIEFzc2VydGlvbkZhaWxlZEVycm9yKQ0KCSAqLw0KCXB1YmxpYyB2b2lkIGFkZEZhaWx1cmUoVGVzdCB0ZXN0LCBBc3NlcnRpb25GYWlsZWRFcnJvciB0KSB7DQoJCWdldFdyaXRlcigpLnByaW50KCJGIik7DQoJfQ0KDQoJLyoqDQoJICogQHNlZSBqdW5pdC5mcmFtZXdvcmsuVGVzdExpc3RlbmVyI2VuZFRlc3QoVGVzdCkNCgkgKi8NCglwdWJsaWMgdm9pZCBlbmRUZXN0KFRlc3QgdGVzdCkgew0KCX0NCg0KCS8qKg0KCSAqIEBzZWUganVuaXQuZnJhbWV3b3JrLlRlc3RMaXN0ZW5lciNzdGFydFRlc3QoVGVzdCkNCgkgKi8NCglwdWJsaWMgdm9pZCBzdGFydFRlc3QoVGVzdCB0ZXN0KSB7DQoJCWdldFdyaXRlcigpLnByaW50KCIuIik7DQoJCWlmIChmQ29sdW1uKysgPj0gNDApIHsNCgkJCWdldFdyaXRlcigpLnByaW50bG4oKTsNCgkJCWZDb2x1bW49IDA7DQoJCX0NCgl9DQoNCn0NClBLAwQKAAAAAAD1eMcwONhICrIEAACyBAAAHQAAAGp1bml0L3NhbXBsZXMvU2ltcGxlVGVzdC5qYXZhcGFja2FnZSBqdW5pdC5zYW1wbGVzOw0KDQppbXBvcnQganVuaXQuZnJhbWV3b3JrLio7DQoNCi8qKg0KICogU29tZSBzaW1wbGUgdGVzdHMuDQogKg0KICovDQpwdWJsaWMgY2xhc3MgU2ltcGxlVGVzdCBleHRlbmRzIFRlc3RDYXNlIHsNCglwcm90ZWN0ZWQgaW50IGZWYWx1ZTE7DQoJcHJvdGVjdGVkIGludCBmVmFsdWUyOw0KDQoJcHJvdGVjdGVkIHZvaWQgc2V0VXAoKSB7DQoJCWZWYWx1ZTE9IDI7DQoJCWZWYWx1ZTI9IDM7DQoJfQ0KCXB1YmxpYyBzdGF0aWMgVGVzdCBzdWl0ZSgpIHsNCg0KCQkvKg0KCQkgKiB0aGUgdHlwZSBzYWZlIHdheQ0KCQkgKg0KCQlUZXN0U3VpdGUgc3VpdGU9IG5ldyBUZXN0U3VpdGUoKTsNCgkJc3VpdGUuYWRkVGVzdCgNCgkJCW5ldyBTaW1wbGVUZXN0KCJhZGQiKSB7DQoJCQkJIHByb3RlY3RlZCB2b2lkIHJ1blRlc3QoKSB7IHRlc3RBZGQoKTsgfQ0KCQkJfQ0KCQkpOw0KDQoJCXN1aXRlLmFkZFRlc3QoDQoJCQluZXcgU2ltcGxlVGVzdCgidGVzdERpdmlkZUJ5WmVybyIpIHsNCgkJCQkgcHJvdGVjdGVkIHZvaWQgcnVuVGVzdCgpIHsgdGVzdERpdmlkZUJ5WmVybygpOyB9DQoJCQl9DQoJCSk7DQoJCXJldHVybiBzdWl0ZTsNCgkJKi8NCg0KCQkvKg0KCQkgKiB0aGUgZHluYW1pYyB3YXkNCgkJICovDQoJCXJldHVybiBuZXcgVGVzdFN1aXRlKFNpbXBsZVRlc3QuY2xhc3MpOw0KCX0NCglwdWJsaWMgdm9pZCB0ZXN0QWRkKCkgew0KCQlkb3VibGUgcmVzdWx0PSBmVmFsdWUxICsgZlZhbHVlMjsNCgkJLy8gZm9yY2VkIGZhaWx1cmUgcmVzdWx0ID09IDUNCgkJYXNzZXJ0VHJ1ZShyZXN1bHQgPT0gNik7DQoJfQ0KCXB1YmxpYyB2b2lkIHRlc3REaXZpZGVCeVplcm8oKSB7DQoJCWludCB6ZXJvPSAwOw0KCQlpbnQgcmVzdWx0PSA4L3plcm87DQoJfQ0KCXB1YmxpYyB2b2lkIHRlc3RFcXVhbHMoKSB7DQoJCWFzc2VydEVxdWFscygxMiwgMTIpOw0KCQlhc3NlcnRFcXVhbHMoMTJMLCAxMkwpOw0KCQlhc3NlcnRFcXVhbHMobmV3IExvbmcoMTIpLCBuZXcgTG9uZygxMikpOw0KDQoJCWFzc2VydEVxdWFscygiU2l6ZSIsIDEyLCAxMyk7DQoJCWFzc2VydEVxdWFscygiQ2FwYWNpdHkiLCAxMi4wLCAxMS45OSwgMC4wKTsNCgl9DQoJcHVibGljIHN0YXRpYyB2b2lkIG1haW4gKFN0cmluZ1tdIGFyZ3MpIHsNCgkJanVuaXQudGV4dHVpLlRlc3RSdW5uZXIucnVuKHN1aXRlKCkpOw0KCX0NCn1QSwMECgAAAAAAvXnHMMAcXyHDAQAAwwEAABsAAABqdW5pdC9zYW1wbGVzL0FsbFRlc3RzLmphdmFwYWNrYWdlIGp1bml0LnNhbXBsZXM7DQoNCmltcG9ydCBqdW5pdC5mcmFtZXdvcmsuKjsNCg0KLyoqDQogKiBUZXN0U3VpdGUgdGhhdCBydW5zIGFsbCB0aGUgc2FtcGxlIHRlc3RzDQogKg0KICovDQpwdWJsaWMgY2xhc3MgQWxsVGVzdHMgew0KDQoJcHVibGljIHN0YXRpYyB2b2lkIG1haW4gKFN0cmluZ1tdIGFyZ3MpIHsNCgkJanVuaXQudGV4dHVpLlRlc3RSdW5uZXIucnVuIChzdWl0ZSgpKTsNCgl9DQoJcHVibGljIHN0YXRpYyBUZXN0IHN1aXRlICggKSB7DQoJCVRlc3RTdWl0ZSBzdWl0ZT0gbmV3IFRlc3RTdWl0ZSgiQWxsIEpVbml0IFRlc3RzIik7DQoJCXN1aXRlLmFkZFRlc3QoVmVjdG9yVGVzdC5zdWl0ZSgpKTsNCgkJc3VpdGUuYWRkVGVzdChuZXcgVGVzdFN1aXRlKGp1bml0LnNhbXBsZXMubW9uZXkuTW9uZXlUZXN0LmNsYXNzKSk7DQoJICAgIHJldHVybiBzdWl0ZTsNCgl9DQp9UEsDBAoAAAAAAPV4xzBgJTtPggYAAIIGAAAdAAAAanVuaXQvc2FtcGxlcy9WZWN0b3JUZXN0LmphdmFwYWNrYWdlIGp1bml0LnNhbXBsZXM7DQoNCmltcG9ydCBqdW5pdC5mcmFtZXdvcmsuKjsNCmltcG9ydCBqYXZhLnV0aWwuVmVjdG9yOw0KDQovKioNCiAqIEEgc2FtcGxlIHRlc3QgY2FzZSwgdGVzdGluZyA8Y29kZT5qYXZhLnV0aWwuVmVjdG9yPC9jb2RlPi4NCiAqDQogKi8NCnB1YmxpYyBjbGFzcyBWZWN0b3JUZXN0IGV4dGVuZHMgVGVzdENhc2Ugew0KCXByb3RlY3RlZCBWZWN0b3IgZkVtcHR5Ow0KCXByb3RlY3RlZCBWZWN0b3IgZkZ1bGw7DQoNCglwdWJsaWMgc3RhdGljIHZvaWQgbWFpbiAoU3RyaW5nW10gYXJncykgew0KCQlqdW5pdC50ZXh0dWkuVGVzdFJ1bm5lci5ydW4gKHN1aXRlKCkpOw0KCX0NCglwcm90ZWN0ZWQgdm9pZCBzZXRVcCgpIHsNCgkJZkVtcHR5PSBuZXcgVmVjdG9yKCk7DQoJCWZGdWxsPSBuZXcgVmVjdG9yKCk7DQoJCWZGdWxsLmFkZEVsZW1lbnQobmV3IEludGVnZXIoMSkpOw0KCQlmRnVsbC5hZGRFbGVtZW50KG5ldyBJbnRlZ2VyKDIpKTsNCgkJZkZ1bGwuYWRkRWxlbWVudChuZXcgSW50ZWdlcigzKSk7DQoJfQ0KCXB1YmxpYyBzdGF0aWMgVGVzdCBzdWl0ZSgpIHsNCgkJcmV0dXJuIG5ldyBUZXN0U3VpdGUoVmVjdG9yVGVzdC5jbGFzcyk7DQoJfQ0KCXB1YmxpYyB2b2lkIHRlc3RDYXBhY2l0eSgpIHsNCgkJaW50IHNpemU9IGZGdWxsLnNpemUoKTsgDQoJCWZvciAoaW50IGk9IDA7IGkgPCAxMDA7IGkrKykNCgkJCWZGdWxsLmFkZEVsZW1lbnQobmV3IEludGVnZXIoaSkpOw0KCQlhc3NlcnRUcnVlKGZGdWxsLnNpemUoKSA9PSAxMDArc2l6ZSk7DQoJfQ0KCXB1YmxpYyB2b2lkIHRlc3RDbG9uZSgpIHsNCgkJVmVjdG9yIGNsb25lPSAoVmVjdG9yKWZGdWxsLmNsb25lKCk7IA0KCQlhc3NlcnRUcnVlKGNsb25lLnNpemUoKSA9PSBmRnVsbC5zaXplKCkpOw0KCQlhc3NlcnRUcnVlKGNsb25lLmNvbnRhaW5zKG5ldyBJbnRlZ2VyKDEpKSk7DQoJfQ0KCXB1YmxpYyB2b2lkIHRlc3RDb250YWlucygpIHsNCgkJYXNzZXJ0VHJ1ZShmRnVsbC5jb250YWlucyhuZXcgSW50ZWdlcigxKSkpOyAgDQoJCWFzc2VydFRydWUoIWZFbXB0eS5jb250YWlucyhuZXcgSW50ZWdlcigxKSkpOw0KCX0NCglwdWJsaWMgdm9pZCB0ZXN0RWxlbWVudEF0KCkgew0KCQlJbnRlZ2VyIGk9IChJbnRlZ2VyKWZGdWxsLmVsZW1lbnRBdCgwKTsNCgkJYXNzZXJ0VHJ1ZShpLmludFZhbHVlKCkgPT0gMSk7DQoNCgkJdHJ5IHsgDQoJCQlmRnVsbC5lbGVtZW50QXQoZkZ1bGwuc2l6ZSgpKTsNCgkJfSBjYXRjaCAoQXJyYXlJbmRleE91dE9mQm91bmRzRXhjZXB0aW9uIGUpIHsNCgkJCXJldHVybjsNCgkJfQ0KCQlmYWlsKCJTaG91bGQgcmFpc2UgYW4gQXJyYXlJbmRleE91dE9mQm91bmRzRXhjZXB0aW9uIik7DQoJfQ0KCXB1YmxpYyB2b2lkIHRlc3RSZW1vdmVBbGwoKSB7DQoJCWZGdWxsLnJlbW92ZUFsbEVsZW1lbnRzKCk7DQoJCWZFbXB0eS5yZW1vdmVBbGxFbGVtZW50cygpOw0KCQlhc3NlcnRUcnVlKGZGdWxsLmlzRW1wdHkoKSk7DQoJCWFzc2VydFRydWUoZkVtcHR5LmlzRW1wdHkoKSk7IA0KCX0NCglwdWJsaWMgdm9pZCB0ZXN0UmVtb3ZlRWxlbWVudCgpIHsNCgkJZkZ1bGwucmVtb3ZlRWxlbWVudChuZXcgSW50ZWdlcigzKSk7DQoJCWFzc2VydFRydWUoIWZGdWxsLmNvbnRhaW5zKG5ldyBJbnRlZ2VyKDMpKSApOyANCgl9DQp9UEsDBAoAAAAAAPV4xzDDSzAQhA4AAIQOAAAhAAAAanVuaXQvc2FtcGxlcy9tb25leS9Nb25leUJhZy5qYXZhcGFja2FnZSBqdW5pdC5zYW1wbGVzLm1vbmV5Ow0KDQppbXBvcnQgamF2YS51dGlsLio7DQoNCi8qKg0KICogQSBNb25leUJhZyBkZWZlcnMgZXhjaGFuZ2UgcmF0ZSBjb252ZXJzaW9ucy4gRm9yIGV4YW1wbGUgYWRkaW5nIA0KICogMTIgU3dpc3MgRnJhbmNzIHRvIDE0IFVTIERvbGxhcnMgaXMgcmVwcmVzZW50ZWQgYXMgYSBiYWcgDQogKiBjb250YWluaW5nIHRoZSB0d28gTW9uaWVzIDEyIENIRiBhbmQgMTQgVVNELiBBZGRpbmcgYW5vdGhlcg0KICogMTAgU3dpc3MgZnJhbmNzIGdpdmVzIGEgYmFnIHdpdGggMjIgQ0hGIGFuZCAxNCBVU0QuIER1ZSB0byANCiAqIHRoZSBkZWZlcnJlZCBleGNoYW5nZSByYXRlIGNvbnZlcnNpb24gd2UgY2FuIGxhdGVyIHZhbHVlIGEgDQogKiBNb25leUJhZyB3aXRoIGRpZmZlcmVudCBleGNoYW5nZSByYXRlcy4NCiAqDQogKiBBIE1vbmV5QmFnIGlzIHJlcHJlc2VudGVkIGFzIGEgbGlzdCBvZiBNb25pZXMgYW5kIHByb3ZpZGVzIA0KICogZGlmZmVyZW50IGNvbnN0cnVjdG9ycyB0byBjcmVhdGUgYSBNb25leUJhZy4gDQogKi8gDQpjbGFzcyBNb25leUJhZyBpbXBsZW1lbnRzIElNb25leSB7DQoJcHJpdmF0ZSBWZWN0b3IgZk1vbmllcz0gbmV3IFZlY3Rvcig1KTsNCg0KCXN0YXRpYyBJTW9uZXkgY3JlYXRlKElNb25leSBtMSwgSU1vbmV5IG0yKSB7DQoJCU1vbmV5QmFnIHJlc3VsdD0gbmV3IE1vbmV5QmFnKCk7DQoJCW0xLmFwcGVuZFRvKHJlc3VsdCk7DQoJCW0yLmFwcGVuZFRvKHJlc3VsdCk7DQoJCXJldHVybiByZXN1bHQuc2ltcGxpZnkoKTsNCgl9DQoJcHVibGljIElNb25leSBhZGQoSU1vbmV5IG0pIHsNCgkJcmV0dXJuIG0uYWRkTW9uZXlCYWcodGhpcyk7DQoJfQ0KCXB1YmxpYyBJTW9uZXkgYWRkTW9uZXkoTW9uZXkgbSkgeyANCgkJcmV0dXJuIE1vbmV5QmFnLmNyZWF0ZShtLCB0aGlzKTsNCgl9DQoJcHVibGljIElNb25leSBhZGRNb25leUJhZyhNb25leUJhZyBzKSB7DQoJCXJldHVybiBNb25leUJhZy5jcmVhdGUocywgdGhpcyk7DQoJfQ0KCXZvaWQgYXBwZW5kQmFnKE1vbmV5QmFnIGFCYWcpIHsNCgkJZm9yIChFbnVtZXJhdGlvbiBlPSBhQmFnLmZNb25pZXMuZWxlbWVudHMoKTsgZS5oYXNNb3JlRWxlbWVudHMoKTsgKQ0KCQkJYXBwZW5kTW9uZXkoKE1vbmV5KWUubmV4dEVsZW1lbnQoKSk7DQoJfQ0KCXZvaWQgYXBwZW5kTW9uZXkoTW9uZXkgYU1vbmV5KSB7DQoJCWlmIChhTW9uZXkuaXNaZXJvKCkpIHJldHVybjsNCgkJSU1vbmV5IG9sZD0gZmluZE1vbmV5KGFNb25leS5jdXJyZW5jeSgpKTsNCgkJaWYgKG9sZCA9PSBudWxsKSB7DQoJCQlmTW9uaWVzLmFkZEVsZW1lbnQoYU1vbmV5KTsNCgkJCXJldHVybjsNCgkJfQ0KCQlmTW9uaWVzLnJlbW92ZUVsZW1lbnQob2xkKTsNCgkJSU1vbmV5IHN1bT0gb2xkLmFkZChhTW9uZXkpOw0KCQlpZiAoc3VtLmlzWmVybygpKSANCgkJCXJldHVybjsNCgkJZk1vbmllcy5hZGRFbGVtZW50KHN1bSk7DQoJfQ0KCXB1YmxpYyBib29sZWFuIGVxdWFscyhPYmplY3QgYW5PYmplY3QpIHsNCgkJaWYgKGlzWmVybygpKQ0KCQkJaWYgKGFuT2JqZWN0IGluc3RhbmNlb2YgSU1vbmV5KQ0KCQkJCXJldHVybiAoKElNb25leSlhbk9iamVjdCkuaXNaZXJvKCk7DQoNCgkJaWYgKGFuT2JqZWN0IGluc3RhbmNlb2YgTW9uZXlCYWcpIHsNCgkJCU1vbmV5QmFnIGFNb25leUJhZz0gKE1vbmV5QmFnKWFuT2JqZWN0Ow0KCQkJaWYgKGFNb25leUJhZy5mTW9uaWVzLnNpemUoKSAhPSBmTW9uaWVzLnNpemUoKSkNCgkJCQlyZXR1cm4gZmFsc2U7DQoNCgkJICAgIGZvciAoRW51bWVyYXRpb24gZT0gZk1vbmllcy5lbGVtZW50cygpOyBlLmhhc01vcmVFbGVtZW50cygpOyApIHsNCgkJICAgICAgICBNb25leSBtPSAoTW9uZXkpIGUubmV4dEVsZW1lbnQoKTsNCgkJCQlpZiAoIWFNb25leUJhZy5jb250YWlucyhtKSkNCgkJCQkJcmV0dXJuIGZhbHNlOw0KCQkJfQ0KCQkJcmV0dXJuIHRydWU7DQoJCX0NCgkJcmV0dXJuIGZhbHNlOw0KCX0NCglwcml2YXRlIE1vbmV5IGZpbmRNb25leShTdHJpbmcgY3VycmVuY3kpIHsNCgkJZm9yIChFbnVtZXJhdGlvbiBlPSBmTW9uaWVzLmVsZW1lbnRzKCk7IGUuaGFzTW9yZUVsZW1lbnRzKCk7ICkgew0KCQkJTW9uZXkgbT0gKE1vbmV5KSBlLm5leHRFbGVtZW50KCk7DQoJCQlpZiAobS5jdXJyZW5jeSgpLmVxdWFscyhjdXJyZW5jeSkpDQoJCQkJcmV0dXJuIG07DQoJCX0NCgkJcmV0dXJuIG51bGw7DQoJfQ0KCXByaXZhdGUgYm9vbGVhbiBjb250YWlucyhNb25leSBtKSB7DQoJCU1vbmV5IGZvdW5kPSBmaW5kTW9uZXkobS5jdXJyZW5jeSgpKTsNCgkJaWYgKGZvdW5kID09IG51bGwpIHJldHVybiBmYWxzZTsNCgkJcmV0dXJuIGZvdW5kLmFtb3VudCgpID09IG0uYW1vdW50KCk7DQoJfQ0KCXB1YmxpYyBpbnQgaGFzaENvZGUoKSB7DQoJCWludCBoYXNoPSAwOw0KCSAgICBmb3IgKEVudW1lcmF0aW9uIGU9IGZNb25pZXMuZWxlbWVudHMoKTsgZS5oYXNNb3JlRWxlbWVudHMoKTsgKSB7DQoJICAgICAgICBPYmplY3QgbT0gZS5uZXh0RWxlbWVudCgpOw0KCQkJaGFzaF49IG0uaGFzaENvZGUoKTsNCgkJfQ0KCSAgICByZXR1cm4gaGFzaDsNCgl9DQoJcHVibGljIGJvb2xlYW4gaXNaZXJvKCkgew0KCQlyZXR1cm4gZk1vbmllcy5zaXplKCkgPT0gMDsNCgl9DQoJcHVibGljIElNb25leSBtdWx0aXBseShpbnQgZmFjdG9yKSB7DQoJCU1vbmV5QmFnIHJlc3VsdD0gbmV3IE1vbmV5QmFnKCk7DQoJCWlmIChmYWN0b3IgIT0gMCkgew0KCQkJZm9yIChFbnVtZXJhdGlvbiBlPSBmTW9uaWVzLmVsZW1lbnRzKCk7IGUuaGFzTW9yZUVsZW1lbnRzKCk7ICkgew0KCQkJCU1vbmV5IG09IChNb25leSkgZS5uZXh0RWxlbWVudCgpOw0KCQkJCXJlc3VsdC5hcHBlbmRNb25leSgoTW9uZXkpbS5tdWx0aXBseShmYWN0b3IpKTsNCgkJCX0NCgkJfQ0KCQlyZXR1cm4gcmVzdWx0Ow0KCX0NCglwdWJsaWMgSU1vbmV5IG5lZ2F0ZSgpIHsNCgkJTW9uZXlCYWcgcmVzdWx0PSBuZXcgTW9uZXlCYWcoKTsNCgkgICAgZm9yIChFbnVtZXJhdGlvbiBlPSBmTW9uaWVzLmVsZW1lbnRzKCk7IGUuaGFzTW9yZUVsZW1lbnRzKCk7ICkgew0KCSAgICAgICAgTW9uZXkgbT0gKE1vbmV5KSBlLm5leHRFbGVtZW50KCk7DQoJICAgICAgICByZXN1bHQuYXBwZW5kTW9uZXkoKE1vbmV5KW0ubmVnYXRlKCkpOw0KCQl9DQoJCXJldHVybiByZXN1bHQ7DQoJfQ0KCXByaXZhdGUgSU1vbmV5IHNpbXBsaWZ5KCkgew0KCQlpZiAoZk1vbmllcy5zaXplKCkgPT0gMSkNCgkJCXJldHVybiAoSU1vbmV5KWZNb25pZXMuZWxlbWVudHMoKS5uZXh0RWxlbWVudCgpOw0KCQlyZXR1cm4gdGhpczsNCgl9DQoJcHVibGljIElNb25leSBzdWJ0cmFjdChJTW9uZXkgbSkgew0KCQlyZXR1cm4gYWRkKG0ubmVnYXRlKCkpOw0KCX0NCglwdWJsaWMgU3RyaW5nIHRvU3RyaW5nKCkgew0KCQlTdHJpbmdCdWZmZXIgYnVmZmVyID0gbmV3IFN0cmluZ0J1ZmZlcigpOw0KCQlidWZmZXIuYXBwZW5kKCJ7Iik7DQoJCWZvciAoRW51bWVyYXRpb24gZT0gZk1vbmllcy5lbGVtZW50cygpOyBlLmhhc01vcmVFbGVtZW50cygpOyApDQoJCSAgICBidWZmZXIuYXBwZW5kKGUubmV4dEVsZW1lbnQoKSk7DQoJCWJ1ZmZlci5hcHBlbmQoIn0iKTsNCgkJcmV0dXJuIGJ1ZmZlci50b1N0cmluZygpOw0KCX0NCglwdWJsaWMgdm9pZCBhcHBlbmRUbyhNb25leUJhZyBtKSB7DQoJCW0uYXBwZW5kQmFnKHRoaXMpOw0KCX0NCn1QSwMECgAAAAAA9XjHMAfnAEOaEwAAmhMAACIAAABqdW5pdC9zYW1wbGVzL21vbmV5L01vbmV5VGVzdC5qYXZhcGFja2FnZSBqdW5pdC5zYW1wbGVzLm1vbmV5Ow0KDQppbXBvcnQganVuaXQuZnJhbWV3b3JrLio7DQoNCnB1YmxpYyBjbGFzcyBNb25leVRlc3QgZXh0ZW5kcyBUZXN0Q2FzZSB7DQoJcHJpdmF0ZSBNb25leSBmMTJDSEY7DQoJcHJpdmF0ZSBNb25leSBmMTRDSEY7DQoJcHJpdmF0ZSBNb25leSBmN1VTRDsNCglwcml2YXRlIE1vbmV5IGYyMVVTRDsNCg0KCXByaXZhdGUgSU1vbmV5IGZNQjE7DQoJcHJpdmF0ZSBJTW9uZXkgZk1CMjsNCg0KCXB1YmxpYyBzdGF0aWMgdm9pZCBtYWluKFN0cmluZyBhcmdzW10pIHsNCgkJanVuaXQudGV4dHVpLlRlc3RSdW5uZXIucnVuKE1vbmV5VGVzdC5jbGFzcyk7DQoJfQ0KCXByb3RlY3RlZCB2b2lkIHNldFVwKCkgew0KCQlmMTJDSEY9IG5ldyBNb25leSgxMiwgIkNIRiIpOw0KCQlmMTRDSEY9IG5ldyBNb25leSgxNCwgIkNIRiIpOw0KCQlmN1VTRD0gbmV3IE1vbmV5KCA3LCAiVVNEIik7DQoJCWYyMVVTRD0gbmV3IE1vbmV5KDIxLCAiVVNEIik7DQoNCgkJZk1CMT0gTW9uZXlCYWcuY3JlYXRlKGYxMkNIRiwgZjdVU0QpOw0KCQlmTUIyPSBNb25leUJhZy5jcmVhdGUoZjE0Q0hGLCBmMjFVU0QpOw0KCX0NCglwdWJsaWMgdm9pZCB0ZXN0QmFnTXVsdGlwbHkoKSB7DQoJCS8vIHtbMTIgQ0hGXVs3IFVTRF19ICoyID09IHtbMjQgQ0hGXVsxNCBVU0RdfQ0KCQlJTW9uZXkgZXhwZWN0ZWQ9IE1vbmV5QmFnLmNyZWF0ZShuZXcgTW9uZXkoMjQsICJDSEYiKSwgbmV3IE1vbmV5KDE0LCAiVVNEIikpOw0KCQlhc3NlcnRFcXVhbHMoZXhwZWN0ZWQsIGZNQjEubXVsdGlwbHkoMikpOyANCgkJYXNzZXJ0RXF1YWxzKGZNQjEsIGZNQjEubXVsdGlwbHkoMSkpOw0KCQlhc3NlcnRUcnVlKGZNQjEubXVsdGlwbHkoMCkuaXNaZXJvKCkpOw0KCX0NCglwdWJsaWMgdm9pZCB0ZXN0QmFnTmVnYXRlKCkgew0KCQkvLyB7WzEyIENIRl1bNyBVU0RdfSBuZWdhdGUgPT0ge1stMTIgQ0hGXVstNyBVU0RdfQ0KCQlJTW9uZXkgZXhwZWN0ZWQ9IE1vbmV5QmFnLmNyZWF0ZShuZXcgTW9uZXkoLTEyLCAiQ0hGIiksIG5ldyBNb25leSgtNywgIlVTRCIpKTsNCgkJYXNzZXJ0RXF1YWxzKGV4cGVjdGVkLCBmTUIxLm5lZ2F0ZSgpKTsNCgl9DQoJcHVibGljIHZvaWQgdGVzdEJhZ1NpbXBsZUFkZCgpIHsNCgkJLy8ge1sxMiBDSEZdWzcgVVNEXX0gKyBbMTQgQ0hGXSA9PSB7WzI2IENIRl1bNyBVU0RdfQ0KCQlJTW9uZXkgZXhwZWN0ZWQ9IE1vbmV5QmFnLmNyZWF0ZShuZXcgTW9uZXkoMjYsICJDSEYiKSwgbmV3IE1vbmV5KDcsICJVU0QiKSk7DQoJCWFzc2VydEVxdWFscyhleHBlY3RlZCwgZk1CMS5hZGQoZjE0Q0hGKSk7DQoJfQ0KCXB1YmxpYyB2b2lkIHRlc3RCYWdTdWJ0cmFjdCgpIHsNCgkJLy8ge1sxMiBDSEZdWzcgVVNEXX0gLSB7WzE0IENIRl1bMjEgVVNEXSA9PSB7Wy0yIENIRl1bLTE0IFVTRF19DQoJCUlNb25leSBleHBlY3RlZD0gTW9uZXlCYWcuY3JlYXRlKG5ldyBNb25leSgtMiwgIkNIRiIpLCBuZXcgTW9uZXkoLTE0LCAiVVNEIikpOw0KCQlhc3NlcnRFcXVhbHMoZXhwZWN0ZWQsIGZNQjEuc3VidHJhY3QoZk1CMikpOw0KCX0NCglwdWJsaWMgdm9pZCB0ZXN0QmFnU3VtQWRkKCkgew0KCQkvLyB7WzEyIENIRl1bNyBVU0RdfSArIHtbMTQgQ0hGXVsyMSBVU0RdfSA9PSB7WzI2IENIRl1bMjggVVNEXX0NCgkJSU1vbmV5IGV4cGVjdGVkPSBNb25leUJhZy5jcmVhdGUobmV3IE1vbmV5KDI2LCAiQ0hGIiksIG5ldyBNb25leSgyOCwgIlVTRCIpKTsNCgkJYXNzZXJ0RXF1YWxzKGV4cGVjdGVkLCBmTUIxLmFkZChmTUIyKSk7DQoJfQ0KCXB1YmxpYyB2b2lkIHRlc3RJc1plcm8oKSB7DQoJCWFzc2VydFRydWUoZk1CMS5zdWJ0cmFjdChmTUIxKS5pc1plcm8oKSk7IA0KCQlhc3NlcnRUcnVlKE1vbmV5QmFnLmNyZWF0ZShuZXcgTW9uZXkgKDAsICJDSEYiKSwgbmV3IE1vbmV5ICgwLCAiVVNEIikpLmlzWmVybygpKTsNCgl9DQoJcHVibGljIHZvaWQgdGVzdE1peGVkU2ltcGxlQWRkKCkgew0KCQkvLyBbMTIgQ0hGXSArIFs3IFVTRF0gPT0ge1sxMiBDSEZdWzcgVVNEXX0NCgkJSU1vbmV5IGV4cGVjdGVkPSBNb25leUJhZy5jcmVhdGUoZjEyQ0hGLCBmN1VTRCk7DQoJCWFzc2VydEVxdWFscyhleHBlY3RlZCwgZjEyQ0hGLmFkZChmN1VTRCkpOw0KCX0NCglwdWJsaWMgdm9pZCB0ZXN0QmFnTm90RXF1YWxzKCkgew0KCQlJTW9uZXkgYmFnPSBNb25leUJhZy5jcmVhdGUoZjEyQ0hGLCBmN1VTRCk7DQoJCWFzc2VydEZhbHNlKGJhZy5lcXVhbHMobmV3IE1vbmV5KDEyLCAiREVNIikuYWRkKGY3VVNEKSkpOw0KCX0NCglwdWJsaWMgdm9pZCB0ZXN0TW9uZXlCYWdFcXVhbHMoKSB7DQoJCWFzc2VydFRydWUoIWZNQjEuZXF1YWxzKG51bGwpKTsgDQoNCgkJYXNzZXJ0RXF1YWxzKGZNQjEsIGZNQjEpOw0KCQlJTW9uZXkgZXF1YWw9IE1vbmV5QmFnLmNyZWF0ZShuZXcgTW9uZXkoMTIsICJDSEYiKSwgbmV3IE1vbmV5KDcsICJVU0QiKSk7DQoJCWFzc2VydFRydWUoZk1CMS5lcXVhbHMoZXF1YWwpKTsNCgkJYXNzZXJ0VHJ1ZSghZk1CMS5lcXVhbHMoZjEyQ0hGKSk7DQoJCWFzc2VydFRydWUoIWYxMkNIRi5lcXVhbHMoZk1CMSkpOw0KCQlhc3NlcnRUcnVlKCFmTUIxLmVxdWFscyhmTUIyKSk7DQoJfQ0KCXB1YmxpYyB2b2lkIHRlc3RNb25leUJhZ0hhc2goKSB7DQoJCUlNb25leSBlcXVhbD0gTW9uZXlCYWcuY3JlYXRlKG5ldyBNb25leSgxMiwgIkNIRiIpLCBuZXcgTW9uZXkoNywgIlVTRCIpKTsNCgkJYXNzZXJ0RXF1YWxzKGZNQjEuaGFzaENvZGUoKSwgZXF1YWwuaGFzaENvZGUoKSk7DQoJfQ0KCXB1YmxpYyB2b2lkIHRlc3RNb25leUVxdWFscygpIHsNCgkJYXNzZXJ0VHJ1ZSghZjEyQ0hGLmVxdWFscyhudWxsKSk7IA0KCQlNb25leSBlcXVhbE1vbmV5PSBuZXcgTW9uZXkoMTIsICJDSEYiKTsNCgkJYXNzZXJ0RXF1YWxzKGYxMkNIRiwgZjEyQ0hGKTsNCgkJYXNzZXJ0RXF1YWxzKGYxMkNIRiwgZXF1YWxNb25leSk7DQoJCWFzc2VydEVxdWFscyhmMTJDSEYuaGFzaENvZGUoKSwgZXF1YWxNb25leS5oYXNoQ29kZSgpKTsNCgkJYXNzZXJ0VHJ1ZSghZjEyQ0hGLmVxdWFscyhmMTRDSEYpKTsNCgl9DQoJcHVibGljIHZvaWQgdGVzdE1vbmV5SGFzaCgpIHsNCgkJYXNzZXJ0VHJ1ZSghZjEyQ0hGLmVxdWFscyhudWxsKSk7IA0KCQlNb25leSBlcXVhbD0gbmV3IE1vbmV5KDEyLCAiQ0hGIik7DQoJCWFzc2VydEVxdWFscyhmMTJDSEYuaGFzaENvZGUoKSwgZXF1YWwuaGFzaENvZGUoKSk7DQoJfQ0KCXB1YmxpYyB2b2lkIHRlc3RTaW1wbGlmeSgpIHsNCgkJSU1vbmV5IG1vbmV5PSBNb25leUJhZy5jcmVhdGUobmV3IE1vbmV5KDI2LCAiQ0hGIiksIG5ldyBNb25leSgyOCwgIkNIRiIpKTsNCgkJYXNzZXJ0RXF1YWxzKG5ldyBNb25leSg1NCwgIkNIRiIpLCBtb25leSk7DQoJfQ0KCXB1YmxpYyB2b2lkIHRlc3ROb3JtYWxpemUyKCkgew0KCQkvLyB7WzEyIENIRl1bNyBVU0RdfSAtIFsxMiBDSEZdID09IFs3IFVTRF0NCgkJTW9uZXkgZXhwZWN0ZWQ9IG5ldyBNb25leSg3LCAiVVNEIik7DQoJCWFzc2VydEVxdWFscyhleHBlY3RlZCwgZk1CMS5zdWJ0cmFjdChmMTJDSEYpKTsNCgl9DQoJcHVibGljIHZvaWQgdGVzdE5vcm1hbGl6ZTMoKSB7DQoJCS8vIHtbMTIgQ0hGXVs3IFVTRF19IC0ge1sxMiBDSEZdWzMgVVNEXX0gPT0gWzQgVVNEXQ0KCQlJTW9uZXkgbXMxPSBNb25leUJhZy5jcmVhdGUobmV3IE1vbmV5KDEyLCAiQ0hGIiksIG5ldyBNb25leSgzLCAiVVNEIikpOw0KCQlNb25leSBleHBlY3RlZD0gbmV3IE1vbmV5KDQsICJVU0QiKTsNCgkJYXNzZXJ0RXF1YWxzKGV4cGVjdGVkLCBmTUIxLnN1YnRyYWN0KG1zMSkpOw0KCX0NCglwdWJsaWMgdm9pZCB0ZXN0Tm9ybWFsaXplNCgpIHsNCgkJLy8gWzEyIENIRl0gLSB7WzEyIENIRl1bMyBVU0RdfSA9PSBbLTMgVVNEXQ0KCQlJTW9uZXkgbXMxPSBNb25leUJhZy5jcmVhdGUobmV3IE1vbmV5KDEyLCAiQ0hGIiksIG5ldyBNb25leSgzLCAiVVNEIikpOw0KCQlNb25leSBleHBlY3RlZD0gbmV3IE1vbmV5KC0zLCAiVVNEIik7DQoJCWFzc2VydEVxdWFscyhleHBlY3RlZCwgZjEyQ0hGLnN1YnRyYWN0KG1zMSkpOw0KCX0NCglwdWJsaWMgdm9pZCB0ZXN0UHJpbnQoKSB7DQoJCWFzc2VydEVxdWFscygiWzEyIENIRl0iLCBmMTJDSEYudG9TdHJpbmcoKSk7DQoJfQ0KCXB1YmxpYyB2b2lkIHRlc3RTaW1wbGVBZGQoKSB7DQoJCS8vIFsxMiBDSEZdICsgWzE0IENIRl0gPT0gWzI2IENIRl0NCgkJTW9uZXkgZXhwZWN0ZWQ9IG5ldyBNb25leSgyNiwgIkNIRiIpOw0KCQlhc3NlcnRFcXVhbHMoZXhwZWN0ZWQsIGYxMkNIRi5hZGQoZjE0Q0hGKSk7DQoJfQ0KCXB1YmxpYyB2b2lkIHRlc3RTaW1wbGVCYWdBZGQoKSB7DQoJCS8vIFsxNCBDSEZdICsge1sxMiBDSEZdWzcgVVNEXX0gPT0ge1syNiBDSEZdWzcgVVNEXX0NCgkJSU1vbmV5IGV4cGVjdGVkPSBNb25leUJhZy5jcmVhdGUobmV3IE1vbmV5KDI2LCAiQ0hGIiksIG5ldyBNb25leSg3LCAiVVNEIikpOw0KCQlhc3NlcnRFcXVhbHMoZXhwZWN0ZWQsIGYxNENIRi5hZGQoZk1CMSkpOw0KCX0NCglwdWJsaWMgdm9pZCB0ZXN0U2ltcGxlTXVsdGlwbHkoKSB7DQoJCS8vIFsxNCBDSEZdICoyID09IFsyOCBDSEZdDQoJCU1vbmV5IGV4cGVjdGVkPSBuZXcgTW9uZXkoMjgsICJDSEYiKTsNCgkJYXNzZXJ0RXF1YWxzKGV4cGVjdGVkLCBmMTRDSEYubXVsdGlwbHkoMikpOw0KCX0NCglwdWJsaWMgdm9pZCB0ZXN0U2ltcGxlTmVnYXRlKCkgew0KCQkvLyBbMTQgQ0hGXSBuZWdhdGUgPT0gWy0xNCBDSEZdDQoJCU1vbmV5IGV4cGVjdGVkPSBuZXcgTW9uZXkoLTE0LCAiQ0hGIik7DQoJCWFzc2VydEVxdWFscyhleHBlY3RlZCwgZjE0Q0hGLm5lZ2F0ZSgpKTsNCgl9DQoJcHVibGljIHZvaWQgdGVzdFNpbXBsZVN1YnRyYWN0KCkgew0KCQkvLyBbMTQgQ0hGXSAtIFsxMiBDSEZdID09IFsyIENIRl0NCgkJTW9uZXkgZXhwZWN0ZWQ9IG5ldyBNb25leSgyLCAiQ0hGIik7DQoJCWFzc2VydEVxdWFscyhleHBlY3RlZCwgZjE0Q0hGLnN1YnRyYWN0KGYxMkNIRikpOw0KCX0NCn1QSwMECgAAAAAA9XjHMMBspM/YAwAA2AMAAB8AAABqdW5pdC9zYW1wbGVzL21vbmV5L0lNb25leS5qYXZhcGFja2FnZSBqdW5pdC5zYW1wbGVzLm1vbmV5Ow0KDQovKioNCiAqIFRoZSBjb21tb24gaW50ZXJmYWNlIGZvciBzaW1wbGUgTW9uaWVzIGFuZCBNb25leUJhZ3MNCiAqDQogKi8NCnB1YmxpYyBpbnRlcmZhY2UgSU1vbmV5IHsNCgkvKioNCgkgKiBBZGRzIGEgbW9uZXkgdG8gdGhpcyBtb25leS4NCgkgKi8NCglwdWJsaWMgYWJzdHJhY3QgSU1vbmV5IGFkZChJTW9uZXkgbSk7DQoJLyoqDQoJICogQWRkcyBhIHNpbXBsZSBNb25leSB0byB0aGlzIG1vbmV5LiBUaGlzIGlzIGEgaGVscGVyIG1ldGhvZCBmb3INCgkgKiBpbXBsZW1lbnRpbmcgZG91YmxlIGRpc3BhdGNoDQoJICovDQoJcHVibGljIGFic3RyYWN0IElNb25leSBhZGRNb25leShNb25leSBtKTsNCgkvKioNCgkgKiBBZGRzIGEgTW9uZXlCYWcgdG8gdGhpcyBtb25leS4gVGhpcyBpcyBhIGhlbHBlciBtZXRob2QgZm9yDQoJICogaW1wbGVtZW50aW5nIGRvdWJsZSBkaXNwYXRjaA0KCSAqLw0KCXB1YmxpYyBhYnN0cmFjdCBJTW9uZXkgYWRkTW9uZXlCYWcoTW9uZXlCYWcgcyk7DQoJLyoqDQoJICogVGVzdHMgd2hldGhlciB0aGlzIG1vbmV5IGlzIHplcm8NCgkgKi8NCglwdWJsaWMgYWJzdHJhY3QgYm9vbGVhbiBpc1plcm8oKTsNCgkvKioNCgkgKiBNdWx0aXBsaWVzIGEgbW9uZXkgYnkgdGhlIGdpdmVuIGZhY3Rvci4NCgkgKi8NCglwdWJsaWMgYWJzdHJhY3QgSU1vbmV5IG11bHRpcGx5KGludCBmYWN0b3IpOw0KCS8qKg0KCSAqIE5lZ2F0ZXMgdGhpcyBtb25leS4NCgkgKi8NCglwdWJsaWMgYWJzdHJhY3QgSU1vbmV5IG5lZ2F0ZSgpOw0KCS8qKg0KCSAqIFN1YnRyYWN0cyBhIG1vbmV5IGZyb20gdGhpcyBtb25leS4NCgkgKi8NCglwdWJsaWMgYWJzdHJhY3QgSU1vbmV5IHN1YnRyYWN0KElNb25leSBtKTsNCgkvKioNCgkgKiBBcHBlbmQgdGhpcyB0byBhIE1vbmV5QmFnIG0uDQoJICovDQoJcHVibGljIGFic3RyYWN0IHZvaWQgYXBwZW5kVG8oTW9uZXlCYWcgbSk7DQp9UEsDBAoAAAAAAPV4xzA3jDBp4wYAAOMGAAAeAAAAanVuaXQvc2FtcGxlcy9tb25leS9Nb25leS5qYXZhcGFja2FnZSBqdW5pdC5zYW1wbGVzLm1vbmV5Ow0KDQovKioNCiAqIEEgc2ltcGxlIE1vbmV5Lg0KICoNCiAqLw0KcHVibGljIGNsYXNzIE1vbmV5IGltcGxlbWVudHMgSU1vbmV5IHsNCg0KCXByaXZhdGUgaW50IGZBbW91bnQ7DQoJcHJpdmF0ZSBTdHJpbmcgZkN1cnJlbmN5Ow0KDQoJLyoqDQoJICogQ29uc3RydWN0cyBhIG1vbmV5IGZyb20gdGhlIGdpdmVuIGFtb3VudCBhbmQgY3VycmVuY3kuDQoJICovDQoJcHVibGljIE1vbmV5KGludCBhbW91bnQsIFN0cmluZyBjdXJyZW5jeSkgew0KCQlmQW1vdW50PSBhbW91bnQ7DQoJCWZDdXJyZW5jeT0gY3VycmVuY3k7DQoJfQ0KCS8qKg0KCSAqIEFkZHMgYSBtb25leSB0byB0aGlzIG1vbmV5LiBGb3J3YXJkcyB0aGUgcmVxdWVzdCB0byB0aGUgYWRkTW9uZXkgaGVscGVyLg0KCSAqLw0KCXB1YmxpYyBJTW9uZXkgYWRkKElNb25leSBtKSB7DQoJCXJldHVybiBtLmFkZE1vbmV5KHRoaXMpOw0KCX0NCglwdWJsaWMgSU1vbmV5IGFkZE1vbmV5KE1vbmV5IG0pIHsNCgkJaWYgKG0uY3VycmVuY3koKS5lcXVhbHMoY3VycmVuY3koKSkgKQ0KCQkJcmV0dXJuIG5ldyBNb25leShhbW91bnQoKSttLmFtb3VudCgpLCBjdXJyZW5jeSgpKTsNCgkJcmV0dXJuIE1vbmV5QmFnLmNyZWF0ZSh0aGlzLCBtKTsNCgl9DQoJcHVibGljIElNb25leSBhZGRNb25leUJhZyhNb25leUJhZyBzKSB7DQoJCXJldHVybiBzLmFkZE1vbmV5KHRoaXMpOw0KCX0NCglwdWJsaWMgaW50IGFtb3VudCgpIHsNCgkJcmV0dXJuIGZBbW91bnQ7DQoJfQ0KCXB1YmxpYyBTdHJpbmcgY3VycmVuY3koKSB7DQoJCXJldHVybiBmQ3VycmVuY3k7DQoJfQ0KCXB1YmxpYyBib29sZWFuIGVxdWFscyhPYmplY3QgYW5PYmplY3QpIHsNCgkJaWYgKGlzWmVybygpKSANCgkJCWlmIChhbk9iamVjdCBpbnN0YW5jZW9mIElNb25leSkNCgkJCQlyZXR1cm4gKChJTW9uZXkpYW5PYmplY3QpLmlzWmVybygpOw0KCQlpZiAoYW5PYmplY3QgaW5zdGFuY2VvZiBNb25leSkgew0KCQkJTW9uZXkgYU1vbmV5PSAoTW9uZXkpYW5PYmplY3Q7DQoJCQlyZXR1cm4gYU1vbmV5LmN1cnJlbmN5KCkuZXF1YWxzKGN1cnJlbmN5KCkpDQoJCQkJCQkJICYmIGFtb3VudCgpID09IGFNb25leS5hbW91bnQoKTsNCgkJfQ0KCQlyZXR1cm4gZmFsc2U7DQoJfQ0KCXB1YmxpYyBpbnQgaGFzaENvZGUoKSB7DQoJCXJldHVybiBmQ3VycmVuY3kuaGFzaENvZGUoKStmQW1vdW50Ow0KCX0NCglwdWJsaWMgYm9vbGVhbiBpc1plcm8oKSB7DQoJCXJldHVybiBhbW91bnQoKSA9PSAwOw0KCX0NCglwdWJsaWMgSU1vbmV5IG11bHRpcGx5KGludCBmYWN0b3IpIHsNCgkJcmV0dXJuIG5ldyBNb25leShhbW91bnQoKSpmYWN0b3IsIGN1cnJlbmN5KCkpOw0KCX0NCglwdWJsaWMgSU1vbmV5IG5lZ2F0ZSgpIHsNCgkJcmV0dXJuIG5ldyBNb25leSgtYW1vdW50KCksIGN1cnJlbmN5KCkpOw0KCX0NCglwdWJsaWMgSU1vbmV5IHN1YnRyYWN0KElNb25leSBtKSB7DQoJCXJldHVybiBhZGQobS5uZWdhdGUoKSk7DQoJfQ0KCXB1YmxpYyBTdHJpbmcgdG9TdHJpbmcoKSB7DQoJCVN0cmluZ0J1ZmZlciBidWZmZXIgPSBuZXcgU3RyaW5nQnVmZmVyKCk7DQoJCWJ1ZmZlci5hcHBlbmQoIlsiK2Ftb3VudCgpKyIgIitjdXJyZW5jeSgpKyJdIik7DQoJCXJldHVybiBidWZmZXIudG9TdHJpbmcoKTsNCgl9DQoJcHVibGljIC8qdGhpcyBtYWtlcyBubyBzZW5zZSovIHZvaWQgYXBwZW5kVG8oTW9uZXlCYWcgbSkgew0KCQltLmFwcGVuZE1vbmV5KHRoaXMpOw0KCX0NCn1QSwMECgAAAAAA0HjHMKHUI1jiAAAA4gAAAAoAAAAuY2xhc3NwYXRoPD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiPz4NCjxjbGFzc3BhdGg+DQoJPGNsYXNzcGF0aGVudHJ5IGtpbmQ9InNyYyIgcGF0aD0iIi8+DQoJPGNsYXNzcGF0aGVudHJ5IGtpbmQ9ImNvbiIgcGF0aD0ib3JnLmVjbGlwc2UuamR0LmxhdW5jaGluZy5KUkVfQ09OVEFJTkVSIi8+DQoJPGNsYXNzcGF0aGVudHJ5IGtpbmQ9Im91dHB1dCIgcGF0aD0iIi8+DQo8L2NsYXNzcGF0aD4NClBLAwQKAAAAAADQeMcw2XXMZoQBAACEAQAACAAAAC5wcm9qZWN0PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiPz4NCjxwcm9qZWN0RGVzY3JpcHRpb24+DQoJPG5hbWU+SlVuaXQtU291cmNlPC9uYW1lPg0KCTxjb21tZW50PjwvY29tbWVudD4NCgk8cHJvamVjdHM+DQoJPC9wcm9qZWN0cz4NCgk8YnVpbGRTcGVjPg0KCQk8YnVpbGRD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