LyoqCiAqIEltcGxlbWVudHMgVW5pY29kZSBOb3JtYWxpemF0aW9uIEZvcm1zIEMsIEQsIEtDLCBLRC48YnI+CiAqIFNlZSBVVFIjMTUgZm9yIGRldGFpbHMuPGJyPgogKiBDb3B5cmlnaHQgqSAxOTk4LTIwMDIgVW5pY29kZSwgSW5jLiBBbGwgUmlnaHRzIFJlc2VydmVkLjxicj4KICogVGhlIFVuaWNvZGUgQ29uc29ydGl1bSBtYWtlcyBubyBleHByZXNzZWQgb3IgaW1wbGllZCB3YXJyYW50eSBvZiBhbnkKICoga2luZCwgYW5kIGFzc3VtZXMgbm8gbGlhYmlsaXR5IGZvciBlcnJvcnMgb3Igb21pc3Npb25zLgogKiBObyBsaWFiaWxpdHkgaXMgYXNzdW1lZCBmb3IgaW5jaWRlbnRhbCBhbmQgY29uc2VxdWVudGlhbCBkYW1hZ2VzCiAqIGluIGNvbm5lY3Rpb24gd2l0aCBvciBhcmlzaW5nIG91dCBvZiB0aGUgdXNlIG9mIHRoZSBpbmZvcm1hdGlvbiBoZXJlLgogKiBAYXV0aG9yIE1hcmsgRGF2aXMKICogVXBkYXRlcyBmb3Igc3VwcGxlbWVudGFyeSBjb2RlIHBvaW50czoKICogVmxhZGltaXIgV2VpbnN0ZWluICYgTWFya3VzIFNjaGVyZXIKICovCgpwYWNrYWdlIGNvbS5pYm0uaWN1LmRldi50ZXN0Lm5vcm1hbGl6ZXI7CgppbXBvcnQgY29tLmlibS5pY3UuZGV2LnRlc3QuVVRGMTZVdGlsOwoKcHVibGljIGNsYXNzIFVuaWNvZGVOb3JtYWxpemVyIHsKICAgIHN0YXRpYyBmaW5hbCBTdHJpbmcgY29weXJpZ2h0ID0gIkNvcHlyaWdodCCpIDE5OTgtMTk5OSBVbmljb2RlLCBJbmMuIjsKCiAgICAvKioKICAgICAqIENyZWF0ZSBhIG5vcm1hbGl6ZXIgZm9yIGEgZ2l2ZW4gZm9ybS4KICAgICAqLwogICAgcHVibGljIFVuaWNvZGVOb3JtYWxpemVyKGJ5dGUgZm9ybSwgYm9vbGVhbiBmdWxsRGF0YSkgewogICAgICAgIHRoaXMuZm9ybSA9IGZvcm07CiAgICAgICAgaWYgKGRhdGEgPT0gbnVsbCkgZGF0YSA9IE5vcm1hbGl6ZXJCdWlsZGVyLmJ1aWxkKGZ1bGxEYXRhKTsgLy8gbG9hZCAxc3QgdGltZQogICAgfQoKICAgIC8qKgogICAgKiBNYXNrcyBmb3IgdGhlIGZvcm0gc2VsZWN0b3IKICAgICovCiAgICBzdGF0aWMgZmluYWwgYnl0ZQogICAgICAgIENPTVBBVElCSUxJVFlfTUFTSyA9IDEsCiAgICAgICAgQ09NUE9TSVRJT05fTUFTSyA9IDI7CgogICAgLyoqCiAgICAqIE5vcm1hbGl6YXRpb24gRm9ybSBTZWxlY3RvcgogICAgKi8KICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgYnl0ZQogICAgICAgIEQgPSAwICwKICAgICAgICBDID0gQ09NUE9TSVRJT05fTUFTSywKICAgICAgICBLRCA9IENPTVBBVElCSUxJVFlfTUFTSywKICAgICAgICBLQyA9IChieXRlKShDT01QQVRJQklMSVRZX01BU0sgKyBDT01QT1NJVElPTl9NQVNLKTsKCiAgICAvKioKICAgICogTm9ybWFsaXplcyB0ZXh0IGFjY29yZGluZyB0byB0aGUgY2hvc2VuIGZvcm0sCiAgICAqIHJlcGxhY2luZyBjb250ZW50cyBvZiB0aGUgdGFyZ2V0IGJ1ZmZlci4KICAgICogQHBhcmFtICAgc291cmNlICAgICAgdGhlIG9yaWdpbmFsIHRleHQsIHVubm9ybWFsaXplZAogICAgKiBAcGFyYW0gICB0YXJnZXQgICAgICB0aGUgcmVzdWx0aW5nIG5vcm1hbGl6ZWQgdGV4dAogICAgKi8KICAgIHB1YmxpYyBTdHJpbmdCdWZmZXIgbm9ybWFsaXplKFN0cmluZyBzb3VyY2UsIFN0cmluZ0J1ZmZlciB0YXJnZXQpIHsKCiAgICAgICAgLy8gRmlyc3QgZGVjb21wb3NlIHRoZSBzb3VyY2UgaW50byB0YXJnZXQsCiAgICAgICAgLy8gdGhlbiBjb21wb3NlIGlmIHRoZSBmb3JtIHJlcXVpcmVzLgoKICAgICAgICBpZiAoc291cmNlLmxlbmd0aCgpICE9IDApIHsKICAgICAgICAgICAgaW50ZXJuYWxEZWNvbXBvc2Uoc291cmNlLCB0YXJnZXQpOwogICAgICAgICAgICBpZiAoKGZvcm0gJiBDT01QT1NJVElPTl9NQVNLKSAhPSAwKSB7CiAgICAgICAgICAgICAgICBpbnRlcm5hbENvbXBvc2UodGFyZ2V0KTsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgICAgICByZXR1cm4gdGFyZ2V0OwogICAgfQoKICAgIC8qKgogICAgKiBOb3JtYWxpemVzIHRleHQgYWNjb3JkaW5nIHRvIHRoZSBjaG9zZW4gZm9ybQogICAgKiBAcGFyYW0gICBzb3VyY2UgICAgICB0aGUgb3JpZ2luYWwgdGV4dCwgdW5ub3JtYWxpemVkCiAgICAqIEByZXR1cm4gIHRhcmdldCAgICAgIHRoZSByZXN1bHRpbmcgbm9ybWFsaXplZCB0ZXh0CiAgICAqLwogICAgcHVibGljIFN0cmluZyBub3JtYWxpemUoU3RyaW5nIHNvdXJjZSkgewogICAgICAgIHJldHVybiBub3JtYWxpemUoc291cmNlLCBuZXcgU3RyaW5nQnVmZmVyKCkpLnRvU3RyaW5nKCk7CiAgICB9CgogICAgLy8gPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KICAgIC8vICAgICAgICAgICAgICAgICAgUFJJVkFURVMKICAgIC8vID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CgogICAgLyoqCiAgICAgKiBUaGUgY3VycmVudCBmb3JtLgogICAgICovCiAgICBwcml2YXRlIGJ5dGUgZm9ybTsKCiAgICAvKioKICAgICogRGVjb21wb3NlcyB0ZXh0LCBlaXRoZXIgY2Fub25pY2FsIG9yIGNvbXBhdGliaWxpdHksCiAgICAqIHJlcGxhY2luZyBjb250ZW50cyBvZiB0aGUgdGFyZ2V0IGJ1ZmZlci4KICAgICogQHBhcmFtICAgZm9ybSAgICAgICAgdGhlIG5vcm1hbGl6YXRpb24gZm9ybS4gSWYgQ09NUEFUSUJJTElUWV9NQVNLCiAgICAqICAgICAgICAgICAgICAgICAgICAgIGJpdCBpcyBvbiBpbiB0aGlzIGJ5dGUsIHRoZW4gc2VsZWN0cyB0aGUgcmVjdXJzaXZlCiAgICAqICAgICAgICAgICAgICAgICAgICAgIGNvbXBhdGliaWxpdHkgZGVjb21wb3NpdGlvbiwgb3RoZXJ3aXNlIHNlbGVjdHMKICAgICogICAgICAgICAgICAgICAgICAgICAgdGhlIHJlY3Vyc2l2ZSBjYW5vbmljYWwgZGVjb21wb3NpdGlvbi4KICAgICogQHBhcmFtICAgc291cmNlICAgICAgdGhlIG9yaWdpbmFsIHRleHQsIHVubm9ybWFsaXplZAogICAgKiBAcGFyYW0gICB0YXJnZXQgICAgICB0aGUgcmVzdWx0aW5nIG5vcm1hbGl6ZWQgdGV4dAogICAgKi8KICAgIHByaXZhdGUgdm9pZCBpbnRlcm5hbERlY29tcG9zZShTdHJpbmcgc291cmNlLCBTdHJpbmdCdWZmZXIgdGFyZ2V0KSB7CiAgICAgICAgU3RyaW5nQnVmZmVyIGJ1ZmZlciA9IG5ldyBTdHJpbmdCdWZmZXIoKTsKICAgICAgICBib29sZWFuIGNhbm9uaWNhbCA9IChmb3JtICYgQ09NUEFUSUJJTElUWV9NQVNLKSA9PSAwOwogICAgICAgIGludCBjaDsKICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IHNvdXJjZS5sZW5ndGgoKTspIHsKICAgICAgICAgICAgYnVmZmVyLnNldExlbmd0aCgwKTsKICAgICAgICAgICAgY2ggPSBVVEYxNlV0aWwubmV4dENvZGVQb2ludChzb3VyY2UsIGkpOwogICAgICAgICAgICBpKz1VVEYxNlV0aWwuY29kZVBvaW50TGVuZ3RoKGNoKTsKICAgICAgICAgICAgZGF0YS5nZXRSZWN1cnNpdmVEZWNvbXBvc2l0aW9uKGNhbm9uaWNhbCwgY2gsIGJ1ZmZlcik7CgogICAgICAgICAgICAvLyBhZGQgYWxsIG9mIHRoZSBjaGFyYWN0ZXJzIGluIHRoZSBkZWNvbXBvc2l0aW9uLgogICAgICAgICAgICAvLyAobWF5IGJlIGp1c3QgdGhlIG9yaWdpbmFsIGNoYXJhY3RlciwgaWYgdGhlcmUgd2FzCiAgICAgICAgICAgIC8vIG5vIGRlY29tcG9zaXRpb24gbWFwcGluZykKCiAgICAgICAgICAgIGZvciAoaW50IGogPSAwOyBqIDwgYnVmZmVyLmxlbmd0aCgpOykgewogICAgICAgICAgICAgICAgY2ggPSBVVEYxNlV0aWwubmV4dENvZGVQb2ludChidWZmZXIsIGopOwogICAgICAgICAgICAgICAgais9VVRGMTZVdGlsLmNvZGVQb2ludExlbmd0aChjaCk7CiAgICAgICAgICAgICAgICBpbnQgY2hDbGFzcyA9IGRhdGEuZ2V0Q2Fub25pY2FsQ2xhc3MoY2gpOwogICAgICAgICAgICAgICAgaW50IGsgPSB0YXJnZXQubGVuZ3RoKCk7IC8vIGluc2VydGlvbiBwb2ludAogICAgICAgICAgICAgICAgaWYgKGNoQ2xhc3MgIT0gMCkgewoKICAgICAgICAgICAgICAgICAgICAvLyBidWJibGUtc29ydCBjb21iaW5pbmcgbWFya3MgYXMgbmVjZXNzYXJ5CgogICAgICAgICAgICAgICAgICAgIGludCBjaDI7CiAgICAgICAgICAgICAgICAgICAgZm9yICg7IGsgPiAwOyBrIC09IFVURjE2VXRpbC5jb2RlUG9pbnRMZW5ndGgoY2gyKSkgewogICAgICAgICAgICAgICAgICAgICAgICBjaDIgPSBVVEYxNlV0aWwucHJldkNvZGVQb2ludCh0YXJnZXQsIGspOwogICAgICAgICAgICAgICAgICAgICAgICBpZiAoZGF0YS5nZXRDYW5vbmljYWxDbGFzcyhjaDIpIDw9IGNoQ2xhc3MpIGJyZWFrOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIFVURjE2VXRpbC5pbnNlcnRDb2RlUG9pbnQodGFyZ2V0LCBrLCBjaCk7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICB9CgogICAgLyoqCiAgICAqIENvbXBvc2VzIHRleHQgaW4gcGxhY2UuIFRhcmdldCBtdXN0IGFscmVhZHkKICAgICogaGF2ZSBiZWVuIGRlY29tcG9zZWQuCiAgICAqIEBwYXJhbSAgIHRhcmdldCAgICAgIGlucHV0OiBkZWNvbXBvc2VkIHRleHQuCiAgICAqICAgICAgICAgICAgICAgICAgICAgIG91dHB1dDogdGhlIHJlc3VsdGluZyBub3JtYWxpemVkIHRleHQuCiAgICAqLwogICAgcHJpdmF0ZSB2b2lkIGludGVybmFsQ29tcG9zZShTdHJpbmdCdWZmZXIgdGFyZ2V0KSB7CgogICAgICAgIGludCBzdGFydGVyUG9zID0gMDsKICAgICAgICBpbnQgc3RhcnRlckNoID0gVVRGMTZVdGlsLm5leHRDb2RlUG9pbnQodGFyZ2V0LDApOwogICAgICAgIGludCBjb21wUG9zID0gVVRGMTZVdGlsLmNvZGVQb2ludExlbmd0aChzdGFydGVyQ2gpOwogICAgICAgIGludCBsYXN0Q2xhc3MgPSBkYXRhLmdldENhbm9uaWNhbENsYXNzKHN0YXJ0ZXJDaCk7CiAgICAgICAgaWYgKGxhc3RDbGFzcyAhPSAwKSBsYXN0Q2xhc3MgPSAyNTY7IC8vIGZpeCBmb3IgaXJyZWd1bGFyIGNvbWJpbmluZyBzZXF1ZW5jZQoKICAgICAgICAvLyBMb29wIG9uIHRoZSBkZWNvbXBvc2VkIGNoYXJhY3RlcnMsIGNvbWJpbmluZyB3aGVyZSBwb3NzaWJsZQoKICAgICAgICBmb3IgKGludCBkZWNvbXBQb3MgPSBVVEYxNlV0aWwuY29kZVBvaW50TGVuZ3RoKHN0YXJ0ZXJDaCk7IGRlY29tcFBvcyA8IHRhcmdldC5sZW5ndGgoKTsgKSB7CiAgICAgICAgICAgIGludCBjaCA9IFVURjE2VXRpbC5uZXh0Q29kZVBvaW50KHRhcmdldCwgZGVjb21wUG9zKTsKICAgICAgICAgICAgZGVjb21wUG9zICs9IFVURjE2VXRpbC5jb2RlUG9pbnRMZW5ndGgoY2gpOwogICAgICAgICAgICBpbnQgY2hDbGFzcyA9IGRhdGEuZ2V0Q2Fub25pY2FsQ2xhc3MoY2gpOwogICAgICAgICAgICBpbnQgY29tcG9zaXRlID0gZGF0YS5nZXRQYWlyd2lzZUNvbXBvc2l0aW9uKHN0YXJ0ZXJDaCwgY2gpOwogICAgICAgICAgICBpZiAoY29tcG9zaXRlICE9IE5vcm1hbGl6ZXJEYXRhLk5PVF9DT01QT1NJVEUKICAgICAgICAgICAgJiYgKGxhc3RDbGFzcyA8IGNoQ2xhc3MgfHwgbGFzdENsYXNzID09IDApKSB7CiAgICAgICAgICAgICAgICBVVEYxNlV0aWwuc2V0Q29kZVBvaW50QXQodGFyZ2V0LCBzdGFydGVyUG9zLCBjb21wb3NpdGUpOwogICAgICAgICAgICAgICAgc3RhcnRlckNoID0gY29tcG9zaXRlOwogICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgaWYgKGNoQ2xhc3MgPT0gMCkgewogICAgICAgICAgICAgICAgICAgIHN0YXJ0ZXJQb3MgPSBjb21wUG9zOwogICAgICAgICAgICAgICAgICAgIHN0YXJ0ZXJDaCAgPSBjaDsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGxhc3RDbGFzcyA9IGNoQ2xhc3M7CiAgICAgICAgICAgICAgICBkZWNvbXBQb3MgKz0gVVRGMTZVdGlsLnNldENvZGVQb2ludEF0KHRhcmdldCwgY29tcFBvcywgY2gpOwogICAgICAgICAgICAgICAgY29tcFBvcyArPSBVVEYxNlV0aWwuY29kZVBvaW50TGVuZ3RoKGNoKTsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgICAgICB0YXJnZXQuc2V0TGVuZ3RoKGNvbXBQb3MpOwogICAgfQoKICAgIC8qKgogICAgKiBDb250YWlucyBub3JtYWxpemF0aW9uIGRhdGEgZnJvbSB0aGUgVW5pY29kZSBDaGFyYWN0ZXIgRGF0YWJhc2UuCiAgICAqIHVzZSBmYWxzZSBmb3IgdGhlIG1pbmltYWwgc2V0LCB0cnVlIGZvciB0aGUgcmVhbCBzZXQuCiAgICAqLwogICAgcHJpdmF0ZSBzdGF0aWMgTm9ybWFsaXplckRhdGEgZGF0YSA9IG51bGw7CgogICAgLyoqCiAgICAqIEp1c3QgYWNjZXNzaWJsZSBmb3IgdGVzdGluZy4KICAgICovCiAgICBib29sZWFuIGdldEV4Y2x1ZGVkIChjaGFyIGNoKSB7CiAgICAgICAgcmV0dXJuIGRhdGEuZ2V0RXhjbHVkZWQoY2gpOwogICAgfQoKICAgIC8qKgogICAgKiBKdXN0IGFjY2Vzc2libGUgZm9yIHRlc3RpbmcuCiAgICAqLwogICAgU3RyaW5nIGdldFJhd0RlY29tcG9zaXRpb25NYXBwaW5nIChjaGFyIGNoKSB7CiAgICAgICAgcmV0dXJuIGRhdGEuZ2V0UmF3RGVjb21wb3NpdGlvbk1hcHBpbmcoY2gpOwogICAgfQp9