LyoqCiAqIEltcGxlbWVudHMgVW5pY29kZSBOb3JtYWxpemF0aW9uIEZvcm1zIEMsIEQsIEtDLCBLRC48YnI+CiAqIFNlZSBVVFIjMTUgZm9yIGRldGFpbHMuPGJyPgogKiBDb3B5cmlnaHQgqSAxOTk4LTIwMDIgVW5pY29kZSwgSW5jLiBBbGwgUmlnaHRzIFJlc2VydmVkLjxicj4KICogVGhlIFVuaWNvZGUgQ29uc29ydGl1bSBtYWtlcyBubyBleHByZXNzZWQgb3IgaW1wbGllZCB3YXJyYW50eSBvZiBhbnkKICoga2luZCwgYW5kIGFzc3VtZXMgbm8gbGlhYmlsaXR5IGZvciBlcnJvcnMgb3Igb21pc3Npb25zLgogKiBObyBsaWFiaWxpdHkgaXMgYXNzdW1lZCBmb3IgaW5jaWRlbnRhbCBhbmQgY29uc2VxdWVudGlhbCBkYW1hZ2VzCiAqIGluIGNvbm5lY3Rpb24gd2l0aCBvciBhcmlzaW5nIG91dCBvZiB0aGUgdXNlIG9mIHRoZSBpbmZvcm1hdGlvbiBoZXJlLgogKiBAYXV0aG9yIE1hcmsgRGF2aXMKICogVXBkYXRlcyBmb3Igc3VwcGxlbWVudGFyeSBjb2RlIHBvaW50czogCiAqIFZsYWRpbWlyIFdlaW5zdGVpbiAmIE1hcmt1cyBTY2hlcmVyCiAqLwoKcGFja2FnZSBjb20uaWJtLmljdS5kZXYudGVzdC5ub3JtYWxpemVyOwoKcHVibGljIGNsYXNzIFVuaWNvZGVOb3JtYWxpemVyIHsKICAgIHN0YXRpYyBmaW5hbCBTdHJpbmcgY29weXJpZ2h0ID0gIkNvcHlyaWdodCCpIDE5OTgtMTk5OSBVbmljb2RlLCBJbmMuIjsKICAgIAogICAgLyoqCiAgICAgKiBDcmVhdGUgYSBub3JtYWxpemVyIGZvciBhIGdpdmVuIGZvcm0uCiAgICAgKi8KICAgIHB1YmxpYyBVbmljb2RlTm9ybWFsaXplcihieXRlIGZvcm0sIGJvb2xlYW4gZnVsbERhdGEpIHsKICAgICAgICB0aGlzLmZvcm0gPSBmb3JtOwogICAgICAgIGlmIChkYXRhID09IG51bGwpIGRhdGEgPSBOb3JtYWxpemVyQnVpbGRlci5idWlsZChmdWxsRGF0YSk7IC8vIGxvYWQgMXN0IHRpbWUKICAgIH0KICAgIAogICAgLyoqCiAgICAqIE1hc2tzIGZvciB0aGUgZm9ybSBzZWxlY3RvcgogICAgKi8KICAgIHN0YXRpYyBmaW5hbCBieXRlIAogICAgICAgIENPTVBBVElCSUxJVFlfTUFTSyA9IDEsCiAgICAgICAgQ09NUE9TSVRJT05fTUFTSyA9IDI7CiAgICAgICAgCiAgICAvKioKICAgICogTm9ybWFsaXphdGlvbiBGb3JtIFNlbGVjdG9yCiAgICAqLwogICAgcHVibGljIHN0YXRpYyBmaW5hbCBieXRlIAogICAgICAgIEQgPSAwICwgCiAgICAgICAgQyA9IENPTVBPU0lUSU9OX01BU0ssCiAgICAgICAgS0QgPSBDT01QQVRJQklMSVRZX01BU0ssCiAgICAgICAgS0MgPSAoYnl0ZSkoQ09NUEFUSUJJTElUWV9NQVNLICsgQ09NUE9TSVRJT05fTUFTSyk7CiAgICAKICAgIC8qKgogICAgKiBOb3JtYWxpemVzIHRleHQgYWNjb3JkaW5nIHRvIHRoZSBjaG9zZW4gZm9ybSwgCiAgICAqIHJlcGxhY2luZyBjb250ZW50cyBvZiB0aGUgdGFyZ2V0IGJ1ZmZlci4KICAgICogQHBhcmFtICAgc291cmNlICAgICAgdGhlIG9yaWdpbmFsIHRleHQsIHVubm9ybWFsaXplZAogICAgKiBAcGFyYW0gICB0YXJnZXQgICAgICB0aGUgcmVzdWx0aW5nIG5vcm1hbGl6ZWQgdGV4dAogICAgKi8KICAgIHB1YmxpYyBTdHJpbmdCdWZmZXIgbm9ybWFsaXplKFN0cmluZyBzb3VyY2UsIFN0cmluZ0J1ZmZlciB0YXJnZXQpIHsKICAgICAgICAKICAgICAgICAvLyBGaXJzdCBkZWNvbXBvc2UgdGhlIHNvdXJjZSBpbnRvIHRhcmdldCwKICAgICAgICAvLyB0aGVuIGNvbXBvc2UgaWYgdGhlIGZvcm0gcmVxdWlyZXMuCiAgICAgICAgCiAgICAgICAgaWYgKHNvdXJjZS5sZW5ndGgoKSAhPSAwKSB7CiAgICAgICAgICAgIGludGVybmFsRGVjb21wb3NlKHNvdXJjZSwgdGFyZ2V0KTsKICAgICAgICAgICAgaWYgKChmb3JtICYgQ09NUE9TSVRJT05fTUFTSykgIT0gMCkgewogICAgICAgICAgICAgICAgaW50ZXJuYWxDb21wb3NlKHRhcmdldCk7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgcmV0dXJuIHRhcmdldDsKICAgIH0KCiAgICAvKioKICAgICogTm9ybWFsaXplcyB0ZXh0IGFjY29yZGluZyB0byB0aGUgY2hvc2VuIGZvcm0KICAgICogQHBhcmFtICAgc291cmNlICAgICAgdGhlIG9yaWdpbmFsIHRleHQsIHVubm9ybWFsaXplZAogICAgKiBAcmV0dXJuICB0YXJnZXQgICAgICB0aGUgcmVzdWx0aW5nIG5vcm1hbGl6ZWQgdGV4dAogICAgKi8KICAgIHB1YmxpYyBTdHJpbmcgbm9ybWFsaXplKFN0cmluZyBzb3VyY2UpIHsKICAgICAgICByZXR1cm4gbm9ybWFsaXplKHNvdXJjZSwgbmV3IFN0cmluZ0J1ZmZlcigpKS50b1N0cmluZygpOwogICAgfQogICAgICAgIAogICAgLy8gPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KICAgIC8vICAgICAgICAgICAgICAgICAgUFJJVkFURVMKICAgIC8vID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CiAgICAKICAgIC8qKgogICAgICogVGhlIGN1cnJlbnQgZm9ybS4KICAgICAqLwogICAgcHJpdmF0ZSBieXRlIGZvcm07CgogICAgLyoqCiAgICAqIERlY29tcG9zZXMgdGV4dCwgZWl0aGVyIGNhbm9uaWNhbCBvciBjb21wYXRpYmlsaXR5LAogICAgKiByZXBsYWNpbmcgY29udGVudHMgb2YgdGhlIHRhcmdldCBidWZmZXIuCiAgICAqIEBwYXJhbSAgIGZvcm0gICAgICAgIHRoZSBub3JtYWxpemF0aW9uIGZvcm0uIElmIENPTVBBVElCSUxJVFlfTUFTSwogICAgKiAgICAgICAgICAgICAgICAgICAgICBiaXQgaXMgb24gaW4gdGhpcyBieXRlLCB0aGVuIHNlbGVjdHMgdGhlIHJlY3Vyc2l2ZSAKICAgICogICAgICAgICAgICAgICAgICAgICAgY29tcGF0aWJpbGl0eSBkZWNvbXBvc2l0aW9uLCBvdGhlcndpc2Ugc2VsZWN0cwogICAgKiAgICAgICAgICAgICAgICAgICAgICB0aGUgcmVjdXJzaXZlIGNhbm9uaWNhbCBkZWNvbXBvc2l0aW9uLgogICAgKiBAcGFyYW0gICBzb3VyY2UgICAgICB0aGUgb3JpZ2luYWwgdGV4dCwgdW5ub3JtYWxpemVkCiAgICAqIEBwYXJhbSAgIHRhcmdldCAgICAgIHRoZSByZXN1bHRpbmcgbm9ybWFsaXplZCB0ZXh0CiAgICAqLwogICAgcHJpdmF0ZSB2b2lkIGludGVybmFsRGVjb21wb3NlKFN0cmluZyBzb3VyY2UsIFN0cmluZ0J1ZmZlciB0YXJnZXQpIHsKICAgICAgICBTdHJpbmdCdWZmZXIgYnVmZmVyID0gbmV3IFN0cmluZ0J1ZmZlcigpOwogICAgICAgIGJvb2xlYW4gY2Fub25pY2FsID0gKGZvcm0gJiBDT01QQVRJQklMSVRZX01BU0spID09IDA7CiAgICAgICAgaW50IGNoOwogICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgc291cmNlLmxlbmd0aCgpOykgewogICAgICAgICAgICBidWZmZXIuc2V0TGVuZ3RoKDApOwogICAgICAgICAgICBjaCA9IFVURjE2VXRpbC5uZXh0Q29kZVBvaW50KHNvdXJjZSwgaSk7CiAgICAgICAgICAgIGkrPVVURjE2VXRpbC5jb2RlUG9pbnRMZW5ndGgoY2gpOwogICAgICAgICAgICBkYXRhLmdldFJlY3Vyc2l2ZURlY29tcG9zaXRpb24oY2Fub25pY2FsLCBjaCwgYnVmZmVyKTsKICAgICAgICAgICAgCiAgICAgICAgICAgIC8vIGFkZCBhbGwgb2YgdGhlIGNoYXJhY3RlcnMgaW4gdGhlIGRlY29tcG9zaXRpb24uCiAgICAgICAgICAgIC8vIChtYXkgYmUganVzdCB0aGUgb3JpZ2luYWwgY2hhcmFjdGVyLCBpZiB0aGVyZSB3YXMKICAgICAgICAgICAgLy8gbm8gZGVjb21wb3NpdGlvbiBtYXBwaW5nKQogICAgICAgICAgICAKICAgICAgICAgICAgZm9yIChpbnQgaiA9IDA7IGogPCBidWZmZXIubGVuZ3RoKCk7KSB7CiAgICAgICAgICAgICAgICBjaCA9IFVURjE2VXRpbC5uZXh0Q29kZVBvaW50KGJ1ZmZlciwgaik7CiAgICAgICAgICAgICAgICBqKz1VVEYxNlV0aWwuY29kZVBvaW50TGVuZ3RoKGNoKTsKICAgICAgICAgICAgICAgIGludCBjaENsYXNzID0gZGF0YS5nZXRDYW5vbmljYWxDbGFzcyhjaCk7CiAgICAgICAgICAgICAgICBpbnQgayA9IHRhcmdldC5sZW5ndGgoKTsgLy8gaW5zZXJ0aW9uIHBvaW50CiAgICAgICAgICAgICAgICBpZiAoY2hDbGFzcyAhPSAwKSB7CiAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgLy8gYnViYmxlLXNvcnQgY29tYmluaW5nIG1hcmtzIGFzIG5lY2Vzc2FyeQogICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgIGludCBjaDI7CiAgICAgICAgICAgICAgICAgICAgZm9yICg7IGsgPiAwOyBrIC09IFVURjE2VXRpbC5jb2RlUG9pbnRMZW5ndGgoY2gyKSkgewogICAgICAgICAgICAgICAgICAgICAgICBjaDIgPSBVVEYxNlV0aWwucHJldkNvZGVQb2ludCh0YXJnZXQsIGspOwogICAgICAgICAgICAgICAgICAgICAgICBpZiAoZGF0YS5nZXRDYW5vbmljYWxDbGFzcyhjaDIpIDw9IGNoQ2xhc3MpIGJyZWFrOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIFVURjE2VXRpbC5pbnNlcnRDb2RlUG9pbnQodGFyZ2V0LCBrLCBjaCk7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICB9CgogICAgLyoqCiAgICAqIENvbXBvc2VzIHRleHQgaW4gcGxhY2UuIFRhcmdldCBtdXN0IGFscmVhZHkKICAgICogaGF2ZSBiZWVuIGRlY29tcG9zZWQuCiAgICAqIEBwYXJhbSAgIHRhcmdldCAgICAgIGlucHV0OiBkZWNvbXBvc2VkIHRleHQuCiAgICAqICAgICAgICAgICAgICAgICAgICAgIG91dHB1dDogdGhlIHJlc3VsdGluZyBub3JtYWxpemVkIHRleHQuCiAgICAqLwogICAgcHJpdmF0ZSB2b2lkIGludGVybmFsQ29tcG9zZShTdHJpbmdCdWZmZXIgdGFyZ2V0KSB7CiAgICAgICAgCiAgICAgICAgaW50IHN0YXJ0ZXJQb3MgPSAwOwogICAgICAgIGludCBzdGFydGVyQ2ggPSBVVEYxNlV0aWwubmV4dENvZGVQb2ludCh0YXJnZXQsMCk7CiAgICAgICAgaW50IGNvbXBQb3MgPSBVVEYxNlV0aWwuY29kZVBvaW50TGVuZ3RoKHN0YXJ0ZXJDaCk7CiAgICAgICAgaW50IGxhc3RDbGFzcyA9IGRhdGEuZ2V0Q2Fub25pY2FsQ2xhc3Moc3RhcnRlckNoKTsKICAgICAgICBpZiAobGFzdENsYXNzICE9IDApIGxhc3RDbGFzcyA9IDI1NjsgLy8gZml4IGZvciBpcnJlZ3VsYXIgY29tYmluaW5nIHNlcXVlbmNlCiAgICAgICAgCiAgICAgICAgLy8gTG9vcCBvbiB0aGUgZGVjb21wb3NlZCBjaGFyYWN0ZXJzLCBjb21iaW5pbmcgd2hlcmUgcG9zc2libGUKICAgICAgICAKICAgICAgICBmb3IgKGludCBkZWNvbXBQb3MgPSBVVEYxNlV0aWwuY29kZVBvaW50TGVuZ3RoKHN0YXJ0ZXJDaCk7IGRlY29tcFBvcyA8IHRhcmdldC5sZW5ndGgoKTsgKSB7CiAgICAgICAgICAgIGludCBjaCA9IFVURjE2VXRpbC5uZXh0Q29kZVBvaW50KHRhcmdldCwgZGVjb21wUG9zKTsKICAgICAgICAgICAgZGVjb21wUG9zICs9IFVURjE2VXRpbC5jb2RlUG9pbnRMZW5ndGgoY2gpOwogICAgICAgICAgICBpbnQgY2hDbGFzcyA9IGRhdGEuZ2V0Q2Fub25pY2FsQ2xhc3MoY2gpOwogICAgICAgICAgICBpbnQgY29tcG9zaXRlID0gZGF0YS5nZXRQYWlyd2lzZUNvbXBvc2l0aW9uKHN0YXJ0ZXJDaCwgY2gpOwogICAgICAgICAgICBpZiAoY29tcG9zaXRlICE9IGRhdGEuTk9UX0NPTVBPU0lURQogICAgICAgICAgICAmJiAobGFzdENsYXNzIDwgY2hDbGFzcyB8fCBsYXN0Q2xhc3MgPT0gMCkpIHsKICAgICAgICAgICAgICAgIFVURjE2VXRpbC5zZXRDb2RlUG9pbnRBdCh0YXJnZXQsIHN0YXJ0ZXJQb3MsIGNvbXBvc2l0ZSk7CiAgICAgICAgICAgICAgICBzdGFydGVyQ2ggPSBjb21wb3NpdGU7CiAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICBpZiAoY2hDbGFzcyA9PSAwKSB7CiAgICAgICAgICAgICAgICAgICAgc3RhcnRlclBvcyA9IGNvbXBQb3M7CiAgICAgICAgICAgICAgICAgICAgc3RhcnRlckNoICA9IGNoOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgbGFzdENsYXNzID0gY2hDbGFzczsKICAgICAgICAgICAgICAgIGRlY29tcFBvcyArPSBVVEYxNlV0aWwuc2V0Q29kZVBvaW50QXQodGFyZ2V0LCBjb21wUG9zLCBjaCk7CiAgICAgICAgICAgICAgICBjb21wUG9zICs9IFVURjE2VXRpbC5jb2RlUG9pbnRMZW5ndGgoY2gpOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIHRhcmdldC5zZXRMZW5ndGgoY29tcFBvcyk7CiAgICB9CgogICAgLyoqCiAgICAqIENvbnRhaW5zIG5vcm1hbGl6YXRpb24gZGF0YSBmcm9tIHRoZSBVbmljb2RlIENoYXJhY3RlciBEYXRhYmFzZS4KICAgICogdXNlIGZhbHNlIGZvciB0aGUgbWluaW1hbCBzZXQsIHRydWUgZm9yIHRoZSByZWFsIHNldC4gIAogICAgKi8KICAgIHByaXZhdGUgc3RhdGljIE5vcm1hbGl6ZXJEYXRhIGRhdGEgPSBudWxsOwogICAgCiAgICAvKioKICAgICogSnVzdCBhY2Nlc3NpYmxlIGZvciB0ZXN0aW5nLgogICAgKi8KICAgIGJvb2xlYW4gZ2V0RXhjbHVkZWQgKGNoYXIgY2gpIHsKICAgICAgICByZXR1cm4gZGF0YS5nZXRFeGNsdWRlZChjaCk7CiAgICB9CiAgIAogICAgLyoqCiAgICAqIEp1c3QgYWNjZXNzaWJsZSBmb3IgdGVzdGluZy4KICAgICovCiAgICBTdHJpbmcgZ2V0UmF3RGVjb21wb3NpdGlvbk1hcHBpbmcgKGNoYXIgY2gpIHsKICAgICAgICByZXR1cm4gZGF0YS5nZXRSYXdEZWNvbXBvc2l0aW9uTWFwcGluZyhjaCk7CiAgICB9Cn0=