cGFja2FnZSBjb20uaWJtLmljdS5kZXYudGVzdC5ub3JtYWxpemVyOwoKaW1wb3J0IGphdmEudXRpbC5CaXRTZXQ7CgppbXBvcnQgY29tLmlibS5pY3UuZGV2LnRlc3QuVVRGMTZVdGlsOwoKLyoqCiAqIEFjY2Vzc2VzIHRoZSBOb3JtYWxpemF0aW9uIERhdGEgdXNlZCBmb3IgRm9ybXMgQyBhbmQgRC48YnI+CiAqIENvcHlyaWdodCCpIDE5OTgtMjAwMiBVbmljb2RlLCBJbmMuIEFsbCBSaWdodHMgUmVzZXJ2ZWQuPGJyPgogKiBUaGUgVW5pY29kZSBDb25zb3J0aXVtIG1ha2VzIG5vIGV4cHJlc3NlZCBvciBpbXBsaWVkIHdhcnJhbnR5IG9mIGFueQogKiBraW5kLCBhbmQgYXNzdW1lcyBubyBsaWFiaWxpdHkgZm9yIGVycm9ycyBvciBvbWlzc2lvbnMuCiAqIE5vIGxpYWJpbGl0eSBpcyBhc3N1bWVkIGZvciBpbmNpZGVudGFsIGFuZCBjb25zZXF1ZW50aWFsIGRhbWFnZXMKICogaW4gY29ubmVjdGlvbiB3aXRoIG9yIGFyaXNpbmcgb3V0IG9mIHRoZSB1c2Ugb2YgdGhlIGluZm9ybWF0aW9uIGhlcmUuCiAqIEBhdXRob3IgTWFyayBEYXZpcwogKiBVcGRhdGVzIGZvciBzdXBwbGVtZW50YXJ5IGNvZGUgcG9pbnRzOgogKiBWbGFkaW1pciBXZWluc3RlaW4gJiBNYXJrdXMgU2NoZXJlcgogKi8KcHVibGljIGNsYXNzIE5vcm1hbGl6ZXJEYXRhIHsKICAgIHN0YXRpYyBmaW5hbCBTdHJpbmcgY29weXJpZ2h0ID0gIkNvcHlyaWdodCCpIDE5OTgtMTk5OSBVbmljb2RlLCBJbmMuIjsKCiAgICAvKioKICAgICogQ29uc3RhbnQgZm9yIHVzZSBpbiBnZXRQYWlyd2lzZUNvbXBvc2l0aW9uCiAgICAqLwogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgTk9UX0NPTVBPU0lURSA9ICdcdUZGRkYnOwoKICAgIC8qKgogICAgKiBHZXRzIHRoZSBjb21iaW5pbmcgY2xhc3Mgb2YgYSBjaGFyYWN0ZXIgZnJvbSB0aGUKICAgICogVW5pY29kZSBDaGFyYWN0ZXIgRGF0YWJhc2UuCiAgICAqIEBwYXJhbSAgIGNoICAgICAgdGhlIHNvdXJjZSBjaGFyYWN0ZXIKICAgICogQHJldHVybiAgICAgICAgICB2YWx1ZSBmcm9tIDAgdG8gMjU1CiAgICAqLwogICAgcHVibGljIGludCBnZXRDYW5vbmljYWxDbGFzcyhpbnQgY2gpIHsKICAgICAgICByZXR1cm4gY2Fub25pY2FsQ2xhc3MuZ2V0KGNoKTsKICAgIH0KCiAgICAvKioKICAgICogUmV0dXJucyB0aGUgY29tcG9zaXRlIG9mIHRoZSB0d28gY2hhcmFjdGVycy4gSWYgdGhlIHR3bwogICAgKiBjaGFyYWN0ZXJzIGRvbid0IGNvbWJpbmUsIHJldHVybnMgTk9UX0NPTVBPU0lURS4KICAgICogQHBhcmFtICAgZmlyc3QgICBmaXJzdCBjaGFyYWN0ZXIgKGUuZy4gJ2MnKQogICAgKiBAcGFyYW0gICBmaXJzdCAgIHNlY29uZCBjaGFyYWN0ZXIgKGUuZy4gJ7gnIGNlZGlsbGEpCiAgICAqIEByZXR1cm4gICAgICAgICAgY29tcG9zaXRlIChlLmcuICfnJykKICAgICovCiAgICBwdWJsaWMgaW50IGdldFBhaXJ3aXNlQ29tcG9zaXRpb24oaW50IGZpcnN0LCBpbnQgc2Vjb25kKSB7CiAgICAgICAgcmV0dXJuIGNvbXBvc2UuZ2V0KCgobG9uZylmaXJzdCA8PCAzMikgfCBzZWNvbmQpOwogICAgfQoKCiAgICAvKioKICAgICogR2V0cyByZWN1cnNpdmUgZGVjb21wb3NpdGlvbiBvZiBhIGNoYXJhY3RlciBmcm9tIHRoZQogICAgKiBVbmljb2RlIENoYXJhY3RlciBEYXRhYmFzZS4KICAgICogQHBhcmFtICAgY2Fub25pY2FsICAgIElmIHRydWUKICAgICogICAgICAgICAgICAgICAgICBiaXQgaXMgb24gaW4gdGhpcyBieXRlLCB0aGVuIHNlbGVjdHMgdGhlIHJlY3Vyc2l2ZQogICAgKiAgICAgICAgICAgICAgICAgIGNhbm9uaWNhbCBkZWNvbXBvc2l0aW9uLCBvdGhlcndpc2Ugc2VsZWN0cwogICAgKiAgICAgICAgICAgICAgICAgIHRoZSByZWN1cnNpdmUgY29tcGF0aWJpbGl0eSBhbmQgY2Fub25pY2FsIGRlY29tcG9zaXRpb24uCiAgICAqIEBwYXJhbSAgIGNoICAgICAgdGhlIHNvdXJjZSBjaGFyYWN0ZXIKICAgICogQHBhcmFtICAgYnVmZmVyICBidWZmZXIgdG8gYmUgZmlsbGVkIHdpdGggdGhlIGRlY29tcG9zaXRpb24KICAgICovCiAgICBwdWJsaWMgdm9pZCBnZXRSZWN1cnNpdmVEZWNvbXBvc2l0aW9uKGJvb2xlYW4gY2Fub25pY2FsLCBpbnQgY2gsIFN0cmluZ0J1ZmZlciBidWZmZXIpIHsKICAgICAgICBTdHJpbmcgZGVjb21wID0gZGVjb21wb3NlLmdldChjaCk7CiAgICAgICAgaWYgKGRlY29tcCAhPSBudWxsICYmICEoY2Fub25pY2FsICYmIGlzQ29tcGF0aWJpbGl0eS5nZXQoY2gpKSkgewogICAgICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IGRlY29tcC5sZW5ndGgoKTsgaSs9VVRGMTZVdGlsLmNvZGVQb2ludExlbmd0aChjaCkpIHsKICAgICAgICAgICAgICAgIGNoID0gVVRGMTZVdGlsLm5leHRDb2RlUG9pbnQoZGVjb21wLCBpKTsKICAgICAgICAgICAgICAgIGdldFJlY3Vyc2l2ZURlY29tcG9zaXRpb24oY2Fub25pY2FsLCBjaCwgYnVmZmVyKTsKICAgICAgICAgICAgfQogICAgICAgIH0gZWxzZSB7ICAgICAgICAgICAgICAgICAgICAvLyBpZiBubyBkZWNvbXAsIGFwcGVuZAogICAgICAgICAgICBVVEYxNlV0aWwuYXBwZW5kQ29kZVBvaW50KGJ1ZmZlciwgY2gpOwogICAgICAgIH0KICAgIH0KCiAgICAvLyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CiAgICAvLyAgICAgICAgICAgICAgICAgICBQUklWQVRFUwogICAgLy8gPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQoKICAgIC8qKgogICAgICogT25seSBhY2Nlc3NlZCBieSBOb3JtYWxpemVyQnVpbGRlci4KICAgICAqLwogICAgTm9ybWFsaXplckRhdGEoSW50SGFzaHRhYmxlIGNhbm9uaWNhbENsYXNzLCBJbnRTdHJpbmdIYXNodGFibGUgZGVjb21wb3NlLAogICAgICBMb25nSGFzaHRhYmxlIGNvbXBvc2UsIEJpdFNldCBpc0NvbXBhdGliaWxpdHksIEJpdFNldCBpc0V4Y2x1ZGVkKSB7CiAgICAgICAgdGhpcy5jYW5vbmljYWxDbGFzcyA9IGNhbm9uaWNhbENsYXNzOwogICAgICAgIHRoaXMuZGVjb21wb3NlID0gZGVjb21wb3NlOwogICAgICAgIHRoaXMuY29tcG9zZSA9IGNvbXBvc2U7CiAgICAgICAgdGhpcy5pc0NvbXBhdGliaWxpdHkgPSBpc0NvbXBhdGliaWxpdHk7CiAgICAgICAgdGhpcy5pc0V4Y2x1ZGVkID0gaXNFeGNsdWRlZDsKICAgIH0KCiAgICAvKioKICAgICogSnVzdCBhY2Nlc3NpYmxlIGZvciB0ZXN0aW5nLgogICAgKi8KICAgIGJvb2xlYW4gZ2V0RXhjbHVkZWQgKGNoYXIgY2gpIHsKICAgICAgICByZXR1cm4gaXNFeGNsdWRlZC5nZXQoY2gpOwogICAgfQoKICAgIC8qKgogICAgKiBKdXN0IGFjY2Vzc2libGUgZm9yIHRlc3RpbmcuCiAgICAqLwogICAgU3RyaW5nIGdldFJhd0RlY29tcG9zaXRpb25NYXBwaW5nIChjaGFyIGNoKSB7CiAgICAgICAgcmV0dXJuIGRlY29tcG9zZS5nZXQoY2gpOwogICAgfQoKICAgIC8qKgogICAgKiBGb3Igbm93LCBqdXN0IHVzZSBJbnRIYXNodGFibGUKICAgICogVHdvLXN0YWdlIHRhYmxlcyB3b3VsZCBiZSB1c2VkIGluIGFuIG9wdGltaXplZCBpbXBsZW1lbnRhdGlvbi4KICAgICovCiAgICBwcml2YXRlIEludEhhc2h0YWJsZSBjYW5vbmljYWxDbGFzczsKCiAgICAvKioKICAgICogVGhlIG1haW4gZGF0YSB0YWJsZSBtYXBzIGNoYXJzIHRvIGEgMzItYml0IGludC4KICAgICogSXQgaG9sZHMgZWl0aGVyIGEgcGFpcjogdG9wID0gZmlyc3QsIGJvdHRvbSA9IHNlY29uZAogICAgKiBvciBzaW5nbGV0b246IHRvcCA9IDAsIGJvdHRvbSA9IHNpbmdsZS4KICAgICogSWYgdGhlcmUgaXMgbm8gZGVjb21wb3NpdGlvbiwgdGhlIHZhbHVlIGlzIDAuCiAgICAqIFR3by1zdGFnZSB0YWJsZXMgd291bGQgYmUgdXNlZCBpbiBhbiBvcHRpbWl6ZWQgaW1wbGVtZW50YXRpb24uCiAgICAqIEFuIG9wdGltaXphdGlvbiBjb3VsZCBhbHNvIG1hcCBjaGFycyB0byBhIHNtYWxsIGluZGV4LCB0aGVuIHVzZSB0aGF0CiAgICAqIGluZGV4IGluIGEgc21hbGwgYXJyYXkgb2YgaW50cy4KICAgICovCiAgICBwcml2YXRlIEludFN0cmluZ0hhc2h0YWJsZSBkZWNvbXBvc2U7CgogICAgLyoqCiAgICAqIE1hcHMgZnJvbSBwYWlycyBvZiBjaGFyYWN0ZXJzIHRvIHNpbmdsZS4KICAgICogSWYgdGhlcmUgaXMgbm8gZGVjb21wb3NpdGlvbiwgdGhlIHZhbHVlIGlzIE5PVF9DT01QT1NJVEUuCiAgICAqLwogICAgcHJpdmF0ZSBMb25nSGFzaHRhYmxlIGNvbXBvc2U7CgogICAgLyoqCiAgICAqIFRlbGxzIHdoZXRoZXIgZGVjb21wb3NpdGlvbiBpcyBjYW5vbmljYWwgb3Igbm90LgogICAgKi8KICAgIHByaXZhdGUgQml0U2V0IGlzQ29tcGF0aWJpbGl0eSA9IG5ldyBCaXRTZXQoKTsKCiAgICAvKioKICAgICogVGVsbHMgd2hldGhlciBjaGFyYWN0ZXIgaXMgc2NyaXB0LWV4Y2x1ZGVkIG9yIG5vdC4KICAgICogVXNlZCBvbmx5IHdoaWxlIGJ1aWxkaW5nLCBhbmQgZm9yIHRlc3RpbmcuCiAgICAqLwoKICAgIHByaXZhdGUgQml0U2V0IGlzRXhjbHVkZWQgPSBuZXcgQml0U2V0KCk7Cn0=