LyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogQ29weXJpZ2h0IChjKSAyMDE2IEVjbGlwc2UgRm91bmRhdGlvbiBhbmQgb3RoZXJzLgogKiBBbGwgcmlnaHRzIHJlc2VydmVkLiBUaGlzIHByb2dyYW0gYW5kIHRoZSBhY2NvbXBhbnlpbmcgbWF0ZXJpYWxzCiAqIGFyZSBtYWRlIGF2YWlsYWJsZSB1bmRlciB0aGUgdGVybXMgb2YgdGhlIEVjbGlwc2UgUHVibGljIExpY2Vuc2UgdjEuMAogKiB3aGljaCBhY2NvbXBhbmllcyB0aGlzIGRpc3RyaWJ1dGlvbiwgYW5kIGlzIGF2YWlsYWJsZSBhdAogKiBodHRwOi8vd3d3LmVjbGlwc2Uub3JnL2xlZ2FsL2VwbC12MTAuaHRtbAogKgogKiBDb250cmlidXRvcnM6CiAqICAgICBNaWth62wgQmFyYmVybyAoRWNsaXBzZSBGb3VuZGF0aW9uKSAtIGluaXRpYWwgQVBJIGFuZCBpbXBsZW1lbnRhdGlvbgogKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8KcGFja2FnZSBvcmcuZWNsaXBzZS5jb3JlLmludGVybmFsLmpvYnM7CgppbXBvcnQgamF2YS51dGlsLio7CmltcG9ydCBqYXZhLnV0aWwuY29uY3VycmVudC5UaW1lVW5pdDsKaW1wb3J0IG9yZy5lY2xpcHNlLmNvcmUucnVudGltZS4qOwppbXBvcnQgb3JnLmVjbGlwc2Uub3NnaS51dGlsLk5MUzsKCi8qKgogKiBBIHByb2dyZXNzIG1vbml0b3Igd3JhcHBlciB0aGF0IGNvbXB1dGVzIHRoZSBudW1iZXIgb2YgY2FsbHMgdG8KICoge0BsaW5rICNpc0NhbmNlbGVkKCl9IGFuZCB0aGUgbWF4aW11bSB0aW1lIGludGVydmFsIHdpdGhvdXQgY2FsbHMgdG8KICoge0BsaW5rICNpc0NhbmNlbGVkKCl9LgogKiA8cD4KICogQ2xpZW50cyBhcmUgZXhwZWN0ZWQgdG8gY2FsbCB7QGxpbmsgI2Fib3V0VG9TdGFydCgpfSBhbmQKICoge0BsaW5rICNoYXNTdG9wcGVkKCl9IHNob3J0bHkgYmVmb3JlIGFuZCBhZnRlciB0aGUgam9iIGV4ZWN1dGlvbi4KICogPHA+CiAqIEFmdGVyIHtAbGluayAjaGFzU3RvcHBlZCgpfSBoYXMgYmVlbiBjYWxsZWQsIGNsaWVudCBjYW4gY2FsbAogKiB7QGxpbmsgI2NyZWF0ZUNhbmNlbGFiaWxpdHlTdGF0dXMoKX0gYW5kIHJldHJpZXZlIGFuIHtAbGluayBJU3RhdHVzfSBzdGF0aW5nCiAqIHdoZXRoZXIgdGhlIEpvYiBmb2xsb3dzIGJlc3QgcHJhY3RpY2VzIHJlZ2FyZGluZyBjYW5jZWxhYmlsaXR5LiBCZXN0CiAqIHByYWN0aWNlcyB0aHJlc2hvbGQgYW5kIHJlcG9ydCBkZXRhaWxzIGNhbiBiZSBjb25maWd1cmVkIHRocm91Z2ggYW4KICoge0BsaW5rIE9wdGlvbnN9IGdpdmVuIGF0IGluc3RhbnRpYXRpb24gdGltZS4KICovCnB1YmxpYyBmaW5hbCBjbGFzcyBKb2JDYW5jZWxhYmlsaXR5TW9uaXRvciBleHRlbmRzIFByb2dyZXNzTW9uaXRvcldyYXBwZXIgewoJLyoqCgkgKiBGb3IgY29udmVyc2lvbiBpbiB7QGxpbmsgI25hbm9zVG9TdHJpbmcobG9uZyl9CgkgKi8KCXByaXZhdGUgc3RhdGljIGZpbmFsIGxvbmcgXzFfU0VDT05EX0lOX05BTk9TID0gVGltZVVuaXQuU0VDT05EUy50b05hbm9zKDEpOwoKCS8qKgoJICogU3BlY2lmaWMgZXJyb3IgY29kZSB0byBoZWxwIHRoZSBBdXRvbWF0aWMgRXJyb3IgUmVwb3J0aW5nIEluaXRpYXRpdmUKCSAqIChBRVJJKSBpZGVudGlmeWluZyBjYW5jZWxhYmlsaXR5IGlzc3Vlcy4KCSAqLwoJcHJpdmF0ZSBzdGF0aWMgZmluYWwgaW50IENBTkNFTEFCSUxJVFlfRVJST1JfQ09ERSA9IDg7CgoJLyoqCgkgKiBXaWxsIGJlIGluY3JlbWVudGVkIGV2ZXJ5IHRpbWUge0BsaW5rICNpc0NhbmNlbGVkKCl9IGlzIGNhbGxlZC4KCSAqLwoJcHJpdmF0ZSBpbnQgaXNDYW5jZWxlZEhpdENvdW50ID0gMDsKCgkvKioKCSAqIFdpbGwgYmUgc2V0IHRvIHtAbGluayBTeXN0ZW0jbmFub1RpbWUoKX0gd2hlbiB7QGxpbmsgI2Fib3V0VG9TdGFydCgpfQoJICogd2lsbCBiZSBjYWxsZWQuCgkgKi8KCXByaXZhdGUgbG9uZyBzdGFydE5hbm8gPSAtMTsKCgkvKioKCSAqIFdpbGwgYmUgc2V0IHRvICJ7QGxpbmsgU3lzdGVtI25hbm9UaW1lKCl9IC0ge0BsaW5rICNzdGFydE5hbm99IiB3aGVuCgkgKiBoYXNTdG9wcGVkKCk7IHdpbGwgYmUgY2FsbGVkLgoJICovCglwcml2YXRlIGxvbmcgZWxhcHNlZE5hbm8gPSAtMTsKCgkvKioKCSAqIEtlZXAgdGhlIHtAbGluayBTeXN0ZW0jbmFub1RpbWUoKX0gdmFsdWUgb2YgcHJldmlvdXMgaGl0IHRvCgkgKiB7QGxpbmsgI2lzQ2FuY2VsZWQoKX0uIFdpbGwgYmUgaW5pdGlhbGl6ZWQgaW4ge0BsaW5rICNhYm91dFRvU3RhcnQoKX0uCgkgKi8KCXByaXZhdGUgbG9uZyBsYXN0SGl0ID0gLTE7CgoJLyoqCgkgKiBBdCBldmVyeSBjYWxsIHRvIHtAbGluayAjaXNDYW5jZWxlZCgpfSwgd2lsbCBiZSBzZXQgdG8KCSAqIHtAY29kZSBNYXRoLm1heChtYXhUaW1lQmV0d2VlblR3b0NhbmNlbGF0aW9uQ2hlY2ssIFN5c3RlbS5uYW5vVGltZSgpIC0gbGFzdEhpdCl9CgkgKiAuCgkgKi8KCXByaXZhdGUgbG9uZyBtYXhUaW1lQmV0d2VlblR3b0NhbmNlbGF0aW9uQ2hlY2sgPSAtMTsKCgkvKioKCSAqIExpc3Qgb2Ygc3RhY2sgdHJhY2VzIHRoYXQgd2lsbCBiZSBjb21wdXRlZCBkdXJpbmcgY2FsbHMgdG8gc29tZQoJICoge0BsaW5rIElQcm9ncmVzc01vbml0b3J9IG1ldGhvZHMKCSAqLwoJcHJpdmF0ZSBMaXN0PFN0YWNrVHJhY2VTYW1wbGU+IHN0YWNrVHJhY2VzOwoKCS8qKgoJICogVGVtcG9yYXJ5IGhvbGRlciBvZiB0aGUgbGFzdCBjYXB0dXJlZCBzdGFjayB0cmFjZSB0aGF0IG1heSBiZSBhZGRlZCB0bwoJICoge0BsaW5rICNzdGFja1RyYWNlc30gaWYge0BsaW5rIE9wdGlvbnMjbWF4U3RhY2tTYW1wbGVzKCl9IGlzIG5vdCByZWFjaGVkCgkgKiBvciBpZiBpdCBsb25nZXIgdGhhbiBvbmUgb2YgdGhlIGFscmVhZHkgcmVjb3JkZWQgc2FtcGxlLgoJICovCglwcml2YXRlIFN0YWNrVHJhY2VFbGVtZW50W10gbGFzdENhcHR1cmVkU3RhY2tUcmFjZTsKCgkvKioKCSAqIENvbmZpZ3VyYWJsZSB0aHJlc2hvbGQgYW5kIG9wdGlvbnMgZm9yIHRoZSByZXN1bHQgb2YKCSAqIHtAbGluayAjY3JlYXRlQ2FuY2VsYWJpbGl0eVN0YXR1cygpfS4KCSAqLwoJcHJpdmF0ZSBmaW5hbCBPcHRpb25zIG9wdGlvbnM7CgoJLyoqCgkgKiBUaGUgam9iIHRoYXQgcmVwb3J0IHByb2dyZXNzIHRvIHRoaXMgcHJvZ3Jlc3MgbW9uaXRvci4KCSAqLwoJcHJpdmF0ZSBmaW5hbCBJbnRlcm5hbEpvYiBqb2I7CgoJSm9iQ2FuY2VsYWJpbGl0eU1vbml0b3IoSW50ZXJuYWxKb2Igam9iLCBPcHRpb25zIG9wdGlvbnMpIHsKCQlzdXBlcihqb2IuZ2V0UHJvZ3Jlc3NNb25pdG9yKCkpOwoJCXRoaXMuam9iID0gam9iOwoJCXRoaXMub3B0aW9ucyA9IG9wdGlvbnM7CgkJdGhpcy5zdGFja1RyYWNlcyA9IG5ldyBBcnJheUxpc3Q8PihvcHRpb25zLm1heFN0YWNrU2FtcGxlcygpICsgMSk7Cgl9CgoJLyoqCgkgKiBNdXN0IGJlIGNhbGxlZCBiZWZvcmUgdGhlIHtAbGluayAjam9ifSBzdGFydHMuCgkgKgoJICogQHJldHVybiB0aGlzIHRvIHNpbXBsaWZ5IGNhbGxpbmcgY29kZS4KCSAqLwoJSVByb2dyZXNzTW9uaXRvciBhYm91dFRvU3RhcnQoKSB7CgkJbGFzdENhcHR1cmVkU3RhY2tUcmFjZSA9IGNhcHR1cmVTdGFja1RyYWNlKCk7CgkJc3RhcnROYW5vID0gU3lzdGVtLm5hbm9UaW1lKCk7CgkJbGFzdEhpdCA9IHN0YXJ0TmFubzsKCQlyZXR1cm4gdGhpczsKCX0KCgkvKioKCSAqIE11c3QgYmUgY2FsbGVkIGFmdGVyIHRoZSB7QGxpbmsgI2pvYn0gZW5kcy4KCSAqLwoJdm9pZCBoYXNTdG9wcGVkKCkgewoJCWVsYXBzZWROYW5vID0gU3lzdGVtLm5hbm9UaW1lKCkgLSBzdGFydE5hbm87Cgl9CgoJLyoqCgkgKiBDYXB0dXJlcyB0aGUgY3VycmVudCB0aHJlYWQgc3RhY2sgdHJhY2UgYW5kIHJlbW92ZXMgdGhlIHRvcCAzIGZyYW1lcyB0bwoJICogYXZvaWQgZGlzcGxheWluZyB0aGUgbW9uaXRvcmluZyByZWxhdGVkIGZyYW1lcyBpbiB0aGUgbG9nLgoJICovCglwcml2YXRlIFN0YWNrVHJhY2VFbGVtZW50W10gY2FwdHVyZVN0YWNrVHJhY2UoKSB7CgkJZmluYWwgU3RhY2tUcmFjZUVsZW1lbnRbXSByZXQ7CgkJU3RhY2tUcmFjZUVsZW1lbnRbXSBzdGFja1RyYWNlID0gVGhyZWFkLmN1cnJlbnRUaHJlYWQoKS5nZXRTdGFja1RyYWNlKCk7CgkJaWYgKHN0YWNrVHJhY2UubGVuZ3RoID4gMykgewoJCQlyZXQgPSBBcnJheXMuY29weU9mUmFuZ2Uoc3RhY2tUcmFjZSwgMywgc3RhY2tUcmFjZS5sZW5ndGgpOwoJCX0gZWxzZSB7CgkJCXJldCA9IHN0YWNrVHJhY2U7CgkJfQoJCXJldHVybiByZXQ7Cgl9CgoJcHJpdmF0ZSBzdGF0aWMgY2xhc3MgU3RhY2tUcmFjZVNhbXBsZSB7CgkJZmluYWwgbG9uZyBuYW5vQmV0d2VlblN0YWNrVHJhY2VzOwoJCWZpbmFsIFN0YWNrVHJhY2VFbGVtZW50W10gZmlyc3RTdGU7CgkJZmluYWwgU3RhY2tUcmFjZUVsZW1lbnRbXSBzZWNvbmRTdGU7CgoJCXB1YmxpYyBTdGFja1RyYWNlU2FtcGxlKGxvbmcgbmFub0JldHdlZW5TdGFja1RyYWNlLCBTdGFja1RyYWNlRWxlbWVudFtdIGZpcnN0U3RlLAoJCQkJU3RhY2tUcmFjZUVsZW1lbnRbXSBzZWNvbmRTdGUpIHsKCQkJbmFub0JldHdlZW5TdGFja1RyYWNlcyA9IG5hbm9CZXR3ZWVuU3RhY2tUcmFjZTsKCQkJdGhpcy5maXJzdFN0ZSA9IGZpcnN0U3RlOwoJCQl0aGlzLnNlY29uZFN0ZSA9IHNlY29uZFN0ZTsKCQl9Cgl9CgoJQE92ZXJyaWRlCglwdWJsaWMgYm9vbGVhbiBpc0NhbmNlbGVkKCkgewoJCWxvbmcgZWxhcHNlZFNpbmNlTGFzdEhpdCA9IFN5c3RlbS5uYW5vVGltZSgpIC0gbGFzdEhpdDsKCQlsYXN0SGl0ID0gU3lzdGVtLm5hbm9UaW1lKCk7CgkJbWF4VGltZUJldHdlZW5Ud29DYW5jZWxhdGlvbkNoZWNrID0gTWF0aC5tYXgobWF4VGltZUJldHdlZW5Ud29DYW5jZWxhdGlvbkNoZWNrLCBlbGFwc2VkU2luY2VMYXN0SGl0KTsKCQlsYXN0Q2FwdHVyZWRTdGFja1RyYWNlID0gc3RvcmVTdGFja1RyYWNlU2FtcGxlKGVsYXBzZWRTaW5jZUxhc3RIaXQsIGNhcHR1cmVTdGFja1RyYWNlKCkpOwoJCWlzQ2FuY2VsZWRIaXRDb3VudCsrOwoJCXJldHVybiBzdXBlci5pc0NhbmNlbGVkKCk7Cgl9CgoJcHJpdmF0ZSBTdGFja1RyYWNlRWxlbWVudFtdIHN0b3JlU3RhY2tUcmFjZVNhbXBsZShsb25nIGVsYXBzZWRTaW5jZUxhc3RIaXQsIFN0YWNrVHJhY2VFbGVtZW50W10gY3VycmVudFN0YWNrVHJhY2UpIHsKCQlpZiAoZWxhcHNlZFNpbmNlTGFzdEhpdCA+PSBvcHRpb25zLndhcm5pbmdUaHJlc2hvbGQoKSkgewoJCQlpZiAoc3RhY2tUcmFjZXMuc2l6ZSgpID49IG9wdGlvbnMubWF4U3RhY2tTYW1wbGVzKCkpIHsKCQkJCWludCBzaG9ydGVzdFN0YWNrVHJhY2VJZHggPSBmaW5kU2hvcnRlc3RTdGFja1RyYWNlU2FtcGxlKGVsYXBzZWRTaW5jZUxhc3RIaXQpOwoJCQkJaWYgKHNob3J0ZXN0U3RhY2tUcmFjZUlkeCA+PSAwKSB7CgkJCQkJc3RhY2tUcmFjZXMuc2V0KHNob3J0ZXN0U3RhY2tUcmFjZUlkeCwKCQkJCQkJCW5ldyBTdGFja1RyYWNlU2FtcGxlKGVsYXBzZWRTaW5jZUxhc3RIaXQsIGxhc3RDYXB0dXJlZFN0YWNrVHJhY2UsIGN1cnJlbnRTdGFja1RyYWNlKSk7CgkJCQl9CgkJCX0gZWxzZSB7CgkJCQlzdGFja1RyYWNlcy5hZGQobmV3IFN0YWNrVHJhY2VTYW1wbGUoZWxhcHNlZFNpbmNlTGFzdEhpdCwgbGFzdENhcHR1cmVkU3RhY2tUcmFjZSwgY3VycmVudFN0YWNrVHJhY2UpKTsKCQkJfQoJCX0KCQlyZXR1cm4gY3VycmVudFN0YWNrVHJhY2U7Cgl9CgoJLyoqCgkgKiBSZXR1cm5zIHRoZSBpbmRleCBvZiB0aGUge0BsaW5rIFN0YWNrVHJhY2VTYW1wbGV9IHdpdGggdGhlIHNob3J0ZXN0CgkgKiB7QGxpbmsgU3RhY2tUcmFjZVNhbXBsZSNuYW5vQmV0d2VlblN0YWNrVHJhY2VzfSB0aGF0IGlzIHNob3J0ZXIgdGhhbiB0aGUKCSAqIGdpdmVuIHtAY29kZSBzaG9ydGVyVGhhbn0gdmFsdWUuCgkgKgoJICogQHBhcmFtIHNob3J0ZXJUaGFuTmFub3MKCSAqICAgICAgICAgICAgdGhyZXNob2xkIGFib3ZlIHdoaWNoCgkgKiAgICAgICAgICAgIHtAbGluayBTdGFja1RyYWNlU2FtcGxlI25hbm9CZXR3ZWVuU3RhY2tUcmFjZXN9IHdpbGwgbm90IGJlCgkgKiAgICAgICAgICAgIGNvbnNpZGVyZWQgZHVyaW5nIHRoZSBzZWFyY2guCgkgKiBAcmV0dXJuIHRoZSBpbmRleCBvZiB0aGUge0BsaW5rIFN0YWNrVHJhY2VTYW1wbGV9IHdpdGggdGhlIHNob3J0ZXN0CgkgKiAgICAgICAgIG5hbm9CZXR3ZWVuU3RhY2tUcmFjZXMgdGhhdCBpcyBzaG9ydGVyIHRoYW4gdGhlIGdpdmVuCgkgKiAgICAgICAgIHtAY29kZSBzaG9ydGVyVGhhbn0gdmFsdWUsIG9yIC0xIGlmIHRoZXJlIGlzIG5vIHN1Y2ggdmFsdWUuCgkgKi8KCXByaXZhdGUgaW50IGZpbmRTaG9ydGVzdFN0YWNrVHJhY2VTYW1wbGUobG9uZyBzaG9ydGVyVGhhbk5hbm9zKSB7CgkJbG9uZyBtaW5WYWx1ZSA9IHNob3J0ZXJUaGFuTmFub3M7CgkJaW50IHNob3J0ZXN0ID0gLTE7CgkJZm9yIChpbnQgaSA9IDA7IGkgPCBzdGFja1RyYWNlcy5zaXplKCk7IGkrKykgewoJCQlmaW5hbCBTdGFja1RyYWNlU2FtcGxlIHN0YWNrVHJhY2VTYW1wbGUgPSBzdGFja1RyYWNlcy5nZXQoaSk7CgkJCWlmIChzdGFja1RyYWNlU2FtcGxlLm5hbm9CZXR3ZWVuU3RhY2tUcmFjZXMgPCBtaW5WYWx1ZSkgewoJCQkJc2hvcnRlc3QgPSBpOwoJCQkJbWluVmFsdWUgPSBzdGFja1RyYWNlU2FtcGxlLm5hbm9CZXR3ZWVuU3RhY2tUcmFjZXM7CgkJCX0KCQl9CgkJcmV0dXJuIHNob3J0ZXN0OwoJfQoKCUlTdGF0dXMgY3JlYXRlQ2FuY2VsYWJpbGl0eVN0YXR1cygpIHsKCQlJU3RhdHVzIHJldDsKCgkJaWYgKGlzQ2FuY2VsZWRIaXRDb3VudCA+IDApIHsKCQkJcmV0ID0gY3JlYXRlQ2FuY2VsYWJpbGl0eVN0YXR1cyhzZXZlcml0eUZvckVsYXBzZWRUaW1lKG1heFRpbWVCZXR3ZWVuVHdvQ2FuY2VsYXRpb25DaGVjayksCgkJCQkJTkxTLmJpbmQoCgkJCQkJCQlKb2JNZXNzYWdlcy5jYW5jZWxhYmlsaXR5X21vbml0b3Jfd2FpdGVkVG9vTG9uZywKCQkJCQkJCW5ldyBPYmplY3RbXSB7IGpvYi5nZXROYW1lKCksIG5hbm9zVG9TdHJpbmcobWF4VGltZUJldHdlZW5Ud29DYW5jZWxhdGlvbkNoZWNrKSwKCQkJCQkJCQkJaXNDYW5jZWxlZEhpdENvdW50LAoJCQkJCQkJCQluYW5vc1RvU3RyaW5nKGVsYXBzZWROYW5vKSB9KSk7CgkJfSBlbHNlIHsKCQkJcmV0ID0gY3JlYXRlQ2FuY2VsYWJpbGl0eVN0YXR1cyhzZXZlcml0eUZvckVsYXBzZWRUaW1lKGVsYXBzZWROYW5vKSwKCQkJCQlOTFMuYmluZChKb2JNZXNzYWdlcy5jYW5jZWxhYmlsaXR5X21vbml0b3Jfbm9DYW5jZWxhdGlvbkNoZWNrLAoJCQkJCQkJbmV3IE9iamVjdFtdIHsgam9iLmdldE5hbWUoKSwgaXNDYW5jZWxlZEhpdENvdW50LCBuYW5vc1RvU3RyaW5nKGVsYXBzZWROYW5vKSB9KSk7CgkJfQoKCQlyZXR1cm4gcmV0OwoJfQoKCXByaXZhdGUgaW50IHNldmVyaXR5Rm9yRWxhcHNlZFRpbWUobG9uZyBuYW5vVGltZSkgewoJCWZpbmFsIGludCBzZXZlcml0eTsKCQlpZiAoam9iLmlzVXNlcigpICYmIGlzQ2FuY2VsZWRIaXRDb3VudCA9PSAwICYmIG9wdGlvbnMuYWx3YXlzUmVwb3J0Tm9uQ2FuY2VsYWJsZVVzZXJKb2JBc0Vycm9yKCkpIHsKCQkJLy8gZXZlbiBhIHNob3J0IHVzZXIgam9iIHNob3VsZCBjaGVjayBmb3IgY2FuY2VsYXRpb24KCQkJc2V2ZXJpdHkgPSBJU3RhdHVzLkVSUk9SOwoJCX0gZWxzZSBpZiAobmFub1RpbWUgPj0gb3B0aW9ucy5lcnJvclRocmVzaG9sZCgpKSB7CgkJCXNldmVyaXR5ID0gSVN0YXR1cy5FUlJPUjsKCQl9IGVsc2UgaWYgKG5hbm9UaW1lID49IG9wdGlvbnMud2FybmluZ1RocmVzaG9sZCgpKSB7CgkJCXNldmVyaXR5ID0gSVN0YXR1cy5XQVJOSU5HOwoJCX0gZWxzZSB7CgkJCXNldmVyaXR5ID0gSVN0YXR1cy5PSzsKCQl9CgkJcmV0dXJuIHNldmVyaXR5OwoJfQoKCXByaXZhdGUgSVN0YXR1cyBjcmVhdGVDYW5jZWxhYmlsaXR5U3RhdHVzKGludCBzZXZlcml0eSwgU3RyaW5nIG1zZykgewoJCUlTdGF0dXMgcmV0OwoJCWlmIChzZXZlcml0eSA+IElTdGF0dXMuT0spIHsKCQkJZmluYWwgTXVsdGlTdGF0dXMgbXMgPSBuZXcgTXVsdGlTdGF0dXMoSm9iTWFuYWdlci5QSV9KT0JTLCBDQU5DRUxBQklMSVRZX0VSUk9SX0NPREUsIG1zZywgbnVsbCk7CgkJCS8vIFNvcnQgc3RhY2sgdHJhY2VzIHNhbXBsZXMgYnkgZWxhcHNlZCB0aW1lCgkJCUNvbGxlY3Rpb25zLnNvcnQoc3RhY2tUcmFjZXMsIG5ldyBDb21wYXJhdG9yPFN0YWNrVHJhY2VTYW1wbGU+KCkgewoJCQkJQE92ZXJyaWRlCgkJCQlwdWJsaWMgaW50IGNvbXBhcmUoU3RhY2tUcmFjZVNhbXBsZSBzMSwgU3RhY2tUcmFjZVNhbXBsZSBzMikgewoJCQkJCXJldHVybiAoaW50KSAoczEubmFub0JldHdlZW5TdGFja1RyYWNlcyAtIHMyLm5hbm9CZXR3ZWVuU3RhY2tUcmFjZXMpOwoJCQkJfQoJCQl9KTsKCQkJZm9yIChTdGFja1RyYWNlU2FtcGxlIHN0cyA6IHN0YWNrVHJhY2VzKSB7CgkJCQltcy5hZGQoY3JlYXRlU3RhdHVzRnJvbVN0YWNrVHJhY2VTYW1wbGUoc3RzKSk7CgkJCX0KCQkJcmV0ID0gbXM7CgkJfSBlbHNlIHsKCQkJcmV0ID0gU3RhdHVzLk9LX1NUQVRVUzsKCQl9CgkJcmV0dXJuIHJldDsKCX0KCglwcml2YXRlIElTdGF0dXMgY3JlYXRlU3RhdHVzRnJvbVN0YWNrVHJhY2VTYW1wbGUoU3RhY2tUcmFjZVNhbXBsZSBzdGFja1RyYWNlU2FtcGxlKSB7CgkJTXVsdGlTdGF0dXMgbXMgPSBuZXcgTXVsdGlTdGF0dXMoSm9iTWFuYWdlci5QSV9KT0JTLCBDQU5DRUxBQklMSVRZX0VSUk9SX0NPREUsCgkJCQlOTFMuYmluZChKb2JNZXNzYWdlcy5jYW5jZWxhYmlsaXR5X21vbml0b3Jfc2FtcGxlZFN0YWNrVHJhY2VzLAoJCQkJCQluYW5vc1RvU3RyaW5nKHN0YWNrVHJhY2VTYW1wbGUubmFub0JldHdlZW5TdGFja1RyYWNlcykpLAoJCQkJbnVsbCk7CgkJaW50IHNldmVyaXR5ID0gc2V2ZXJpdHlGb3JFbGFwc2VkVGltZShzdGFja1RyYWNlU2FtcGxlLm5hbm9CZXR3ZWVuU3RhY2tUcmFjZXMpOwoJCW1zLmFkZChjcmVhdGVTdGF0dXNGcm9tU3RhY2tUcmFjZShzZXZlcml0eSwgSm9iTWVzc2FnZXMuY2FuY2VsYWJpbGl0eV9tb25pdG9yX3NlY29uZFN0YWNrVHJhY2UsCgkJCQlzdGFja1RyYWNlU2FtcGxlLnNlY29uZFN0ZSkpOwoJCW1zLmFkZChjcmVhdGVTdGF0dXNGcm9tU3RhY2tUcmFjZShzZXZlcml0eSwgSm9iTWVzc2FnZXMuY2FuY2VsYWJpbGl0eV9tb25pdG9yX2luaXRpYWxTdGFja1RyYWNlLAoJCQkJc3RhY2tUcmFjZVNhbXBsZS5maXJzdFN0ZSkpOwoJCXJldHVybiBtczsKCX0KCglwcml2YXRlIHN0YXRpYyBJU3RhdHVzIGNyZWF0ZVN0YXR1c0Zyb21TdGFja1RyYWNlKGludCBzZXZlcml0eSwgU3RyaW5nIG1zZywgU3RhY2tUcmFjZUVsZW1lbnRbXSBzdGFja1RyYWNlKSB7CgkJcmV0dXJuIG5ldyBTdGF0dXMoc2V2ZXJpdHksIEpvYk1hbmFnZXIuUElfSk9CUywgbXNnLCBjcmVhdGVUaHJvd2FibGVGcm9tU3RhY2tUcmFjZShzdGFja1RyYWNlLCBtc2cpKTsKCX0KCglwcml2YXRlIHN0YXRpYyBUaHJvd2FibGUgY3JlYXRlVGhyb3dhYmxlRnJvbVN0YWNrVHJhY2UoU3RhY2tUcmFjZUVsZW1lbnRbXSBzdGFja1RyYWNlLCBTdHJpbmcgbXNnKSB7CgkJVGhyb3dhYmxlIHRocm93YWJsZSA9IG5ldyBUaHJvd2FibGUobXNnKTsKCQl0aHJvd2FibGUuc2V0U3RhY2tUcmFjZShzdGFja1RyYWNlKTsKCQlyZXR1cm4gdGhyb3dhYmxlOwoJfQoKCXByaXZhdGUgc3RhdGljIFN0cmluZyBuYW5vc1RvU3RyaW5nKGxvbmcgbmFub3MpIHsKCQlkb3VibGUgdmFsdWUgPSAoZG91YmxlKSBuYW5vcyAvIF8xX1NFQ09ORF9JTl9OQU5PUzsKCQlmaW5hbCBTdHJpbmcgZm9ybWF0ID0gbmFub3MgPj0gVGltZVVuaXQuU0VDT05EUy50b05hbm9zKDEwMCkgPyAiJS4wZiAlcyIgLy8kTk9OLU5MUy0xJAoJCQkJOiBuYW5vcyA+PSBUaW1lVW5pdC5NSUxMSVNFQ09ORFMudG9OYW5vcygxMCkgPyAiJS4yZyAlcyIgOiAiJS4xZyAlcyI7IC8vJE5PTi1OTFMtMSQgLy8kTk9OLU5MUy0yJAoJCXJldHVybiBTdHJpbmcuZm9ybWF0KGZvcm1hdCwgdmFsdWUsIEpvYk1lc3NhZ2VzLmNhbmNlbGFiaWxpdHlfbW9uaXRvcl9hYmJyZXZVbml0U2Vjb25kcyk7Cgl9CgoJcHVibGljIHN0YXRpYyBpbnRlcmZhY2UgT3B0aW9ucyB7CgkJYm9vbGVhbiBlbmFibGVkKCk7CgoJCWxvbmcgZXJyb3JUaHJlc2hvbGQoKTsKCgkJbG9uZyB3YXJuaW5nVGhyZXNob2xkKCk7CgoJCWludCBtYXhTdGFja1NhbXBsZXMoKTsKCgkJYm9vbGVhbiBhbHdheXNSZXBvcnROb25DYW5jZWxhYmxlVXNlckpvYkFzRXJyb3IoKTsKCX0KCgkvKioKCSAqIFN0YXRpYyBpbmFjdGl2ZSBzaW5nbGV0b24gdGhhdCB3aWxsIGJlIHVzZWQgd2hlbiBubyBzZXJ2aWNlIGhhcyBiZWVuCgkgKiByZWdpc3RlcmVkLgoJICovCglzdGF0aWMgZmluYWwgT3B0aW9ucyBERUZBVUxUX09QVElPTlMgPSBuZXcgQmFzaWNPcHRpb25zSW1wbCgpOwoJc3RhdGljIHsKCQkoKEJhc2ljT3B0aW9uc0ltcGwpIERFRkFVTFRfT1BUSU9OUykuc2V0RW5hYmxlZChmYWxzZSk7Cgl9CgoJcHVibGljIHN0YXRpYyBjbGFzcyBCYXNpY09wdGlvbnNJbXBsIGltcGxlbWVudHMgT3B0aW9ucyB7CgkJcHJpdmF0ZSBib29sZWFuIGVuYWJsZWQ7CgkJcHJpdmF0ZSBsb25nIGVycm9yVGhyZXNob2xkOwoJCXByaXZhdGUgbG9uZyB3YXJuaW5nVGhyZXNob2xkOwoJCXByaXZhdGUgaW50IG1heFN0YWNrU2FtcGxlczsKCQlwcml2YXRlIGJvb2xlYW4gYWx3YXlzUmVwb3J0Tm9uQ2FuY2VsYWJsZVVzZXJKb2JBc0Vycm9yOwoKCQlwdWJsaWMgdm9pZCBzZXRFbmFibGVkKGJvb2xlYW4gZW5hYmxlZCkgewoJCQl0aGlzLmVuYWJsZWQgPSBlbmFibGVkOwoJCX0KCgkJcHVibGljIHZvaWQgc2V0RXJyb3JUaHJlc2hvbGQobG9uZyBlcnJvclRocmVzaG9sZCkgewoJCQl0aGlzLmVycm9yVGhyZXNob2xkID0gZXJyb3JUaHJlc2hvbGQ7CgkJfQoKCQlwdWJsaWMgdm9pZCBzZXRXYXJuaW5nVGhyZXNob2xkKGxvbmcgd2FybmluZ1RocmVzaG9sZCkgewoJCQl0aGlzLndhcm5pbmdUaHJlc2hvbGQgPSB3YXJuaW5nVGhyZXNob2xkOwoJCX0KCgkJcHVibGljIHZvaWQgc2V0TWF4U3RhY2tTYW1wbGVzKGludCBtYXhTdGFja1NhbXBsZXMpIHsKCQkJdGhpcy5tYXhTdGFja1NhbXBsZXMgPSBtYXhTdGFja1NhbXBsZXM7CgkJfQoKCQlwdWJsaWMgdm9pZCBzZXRBbHdheXNSZXBvcnROb25DYW5jZWxhYmxlVXNlckpvYkFzRXJyb3IoYm9vbGVhbiBhbHdheXNSZXBvcnROb25DYW5jZWxhYmxlVXNlckpvYkFzRXJyb3IpIHsKCQkJdGhpcy5hbHdheXNSZXBvcnROb25DYW5jZWxhYmxlVXNlckpvYkFzRXJyb3IgPSBhbHdheXNSZXBvcnROb25DYW5jZWxhYmxlVXNlckpvYkFzRXJyb3I7CgkJfQoKCQlAT3ZlcnJpZGUKCQlwdWJsaWMgYm9vbGVhbiBlbmFibGVkKCkgewoJCQlyZXR1cm4gZW5hYmxlZDsKCQl9CgoJCUBPdmVycmlkZQoJCXB1YmxpYyBsb25nIGVycm9yVGhyZXNob2xkKCkgewoJCQlyZXR1cm4gZXJyb3JUaHJlc2hvbGQ7CgkJfQoKCQlAT3ZlcnJpZGUKCQlwdWJsaWMgbG9uZyB3YXJuaW5nVGhyZXNob2xkKCkgewoJCQlyZXR1cm4gd2FybmluZ1RocmVzaG9sZDsKCQl9CgoJCUBPdmVycmlkZQoJCXB1YmxpYyBpbnQgbWF4U3RhY2tTYW1wbGVzKCkgewoJCQlyZXR1cm4gbWF4U3RhY2tTYW1wbGVzOwoJCX0KCgkJQE92ZXJyaWRlCgkJcHVibGljIGJvb2xlYW4gYWx3YXlzUmVwb3J0Tm9uQ2FuY2VsYWJsZVVzZXJKb2JBc0Vycm9yKCkgewoJCQlyZXR1cm4gYWx3YXlzUmVwb3J0Tm9uQ2FuY2VsYWJsZVVzZXJKb2JBc0Vycm9yOwoJCX0KCX0KfQ==