cGFja2FnZSBjb20uaWJtLmljdS5kZXYudGVzdC5ub3JtYWxpemVyOwoKaW1wb3J0IGphdmEudXRpbC5IYXNodGFibGU7CmltcG9ydCBqYXZhLnV0aWwuQml0U2V0OwoKLyoqCiAqIEFjY2Vzc2VzIHRoZSBOb3JtYWxpemF0aW9uIERhdGEgdXNlZCBmb3IgRm9ybXMgQyBhbmQgRC48YnI+CiAqIENvcHlyaWdodCCpIDE5OTgtMjAwMiBVbmljb2RlLCBJbmMuIEFsbCBSaWdodHMgUmVzZXJ2ZWQuPGJyPgogKiBUaGUgVW5pY29kZSBDb25zb3J0aXVtIG1ha2VzIG5vIGV4cHJlc3NlZCBvciBpbXBsaWVkIHdhcnJhbnR5IG9mIGFueQogKiBraW5kLCBhbmQgYXNzdW1lcyBubyBsaWFiaWxpdHkgZm9yIGVycm9ycyBvciBvbWlzc2lvbnMuCiAqIE5vIGxpYWJpbGl0eSBpcyBhc3N1bWVkIGZvciBpbmNpZGVudGFsIGFuZCBjb25zZXF1ZW50aWFsIGRhbWFnZXMKICogaW4gY29ubmVjdGlvbiB3aXRoIG9yIGFyaXNpbmcgb3V0IG9mIHRoZSB1c2Ugb2YgdGhlIGluZm9ybWF0aW9uIGhlcmUuCiAqIEBhdXRob3IgTWFyayBEYXZpcwogKiBVcGRhdGVzIGZvciBzdXBwbGVtZW50YXJ5IGNvZGUgcG9pbnRzOiAKICogVmxhZGltaXIgV2VpbnN0ZWluICYgTWFya3VzIFNjaGVyZXIKICovCnB1YmxpYyBjbGFzcyBOb3JtYWxpemVyRGF0YSB7CiAgICBzdGF0aWMgZmluYWwgU3RyaW5nIGNvcHlyaWdodCA9ICJDb3B5cmlnaHQgqSAxOTk4LTE5OTkgVW5pY29kZSwgSW5jLiI7CiAgICAKICAgIC8qKgogICAgKiBDb25zdGFudCBmb3IgdXNlIGluIGdldFBhaXJ3aXNlQ29tcG9zaXRpb24KICAgICovCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBOT1RfQ09NUE9TSVRFID0gJ1x1RkZGRic7CgogICAgLyoqCiAgICAqIEdldHMgdGhlIGNvbWJpbmluZyBjbGFzcyBvZiBhIGNoYXJhY3RlciBmcm9tIHRoZQogICAgKiBVbmljb2RlIENoYXJhY3RlciBEYXRhYmFzZS4KICAgICogQHBhcmFtICAgY2ggICAgICB0aGUgc291cmNlIGNoYXJhY3RlcgogICAgKiBAcmV0dXJuICAgICAgICAgIHZhbHVlIGZyb20gMCB0byAyNTUKICAgICovCiAgICBwdWJsaWMgaW50IGdldENhbm9uaWNhbENsYXNzKGludCBjaCkgewogICAgICAgIHJldHVybiBjYW5vbmljYWxDbGFzcy5nZXQoY2gpOwogICAgfQoKICAgIC8qKgogICAgKiBSZXR1cm5zIHRoZSBjb21wb3NpdGUgb2YgdGhlIHR3byBjaGFyYWN0ZXJzLiBJZiB0aGUgdHdvCiAgICAqIGNoYXJhY3RlcnMgZG9uJ3QgY29tYmluZSwgcmV0dXJucyBOT1RfQ09NUE9TSVRFLgogICAgKiBAcGFyYW0gICBmaXJzdCAgIGZpcnN0IGNoYXJhY3RlciAoZS5nLiAnYycpCiAgICAqIEBwYXJhbSAgIGZpcnN0ICAgc2Vjb25kIGNoYXJhY3RlciAoZS5nLiAnuCcgY2VkaWxsYSkKICAgICogQHJldHVybiAgICAgICAgICBjb21wb3NpdGUgKGUuZy4gJ+cnKQogICAgKi8KICAgIHB1YmxpYyBpbnQgZ2V0UGFpcndpc2VDb21wb3NpdGlvbihpbnQgZmlyc3QsIGludCBzZWNvbmQpIHsKICAgICAgICByZXR1cm4gY29tcG9zZS5nZXQoKChsb25nKWZpcnN0IDw8IDMyKSB8IHNlY29uZCk7CiAgICB9CgoKICAgIC8qKgogICAgKiBHZXRzIHJlY3Vyc2l2ZSBkZWNvbXBvc2l0aW9uIG9mIGEgY2hhcmFjdGVyIGZyb20gdGhlIAogICAgKiBVbmljb2RlIENoYXJhY3RlciBEYXRhYmFzZS4KICAgICogQHBhcmFtICAgY2Fub25pY2FsICAgIElmIHRydWUKICAgICogICAgICAgICAgICAgICAgICBiaXQgaXMgb24gaW4gdGhpcyBieXRlLCB0aGVuIHNlbGVjdHMgdGhlIHJlY3Vyc2l2ZSAKICAgICogICAgICAgICAgICAgICAgICBjYW5vbmljYWwgZGVjb21wb3NpdGlvbiwgb3RoZXJ3aXNlIHNlbGVjdHMKICAgICogICAgICAgICAgICAgICAgICB0aGUgcmVjdXJzaXZlIGNvbXBhdGliaWxpdHkgYW5kIGNhbm9uaWNhbCBkZWNvbXBvc2l0aW9uLgogICAgKiBAcGFyYW0gICBjaCAgICAgIHRoZSBzb3VyY2UgY2hhcmFjdGVyCiAgICAqIEBwYXJhbSAgIGJ1ZmZlciAgYnVmZmVyIHRvIGJlIGZpbGxlZCB3aXRoIHRoZSBkZWNvbXBvc2l0aW9uCiAgICAqLwogICAgcHVibGljIHZvaWQgZ2V0UmVjdXJzaXZlRGVjb21wb3NpdGlvbihib29sZWFuIGNhbm9uaWNhbCwgaW50IGNoLCBTdHJpbmdCdWZmZXIgYnVmZmVyKSB7CiAgICAgICAgU3RyaW5nIGRlY29tcCA9IGRlY29tcG9zZS5nZXQoY2gpOyAKICAgICAgICBpZiAoZGVjb21wICE9IG51bGwgJiYgIShjYW5vbmljYWwgJiYgaXNDb21wYXRpYmlsaXR5LmdldChjaCkpKSB7CiAgICAgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgZGVjb21wLmxlbmd0aCgpOyBpKz1VVEYxNlV0aWwuY29kZVBvaW50TGVuZ3RoKGNoKSkgewogICAgICAgICAgICAgICAgY2ggPSBVVEYxNlV0aWwubmV4dENvZGVQb2ludChkZWNvbXAsIGkpOwogICAgICAgICAgICAgICAgZ2V0UmVjdXJzaXZlRGVjb21wb3NpdGlvbihjYW5vbmljYWwsIGNoLCBidWZmZXIpOwogICAgICAgICAgICB9CiAgICAgICAgfSBlbHNlIHsgICAgICAgICAgICAgICAgICAgIC8vIGlmIG5vIGRlY29tcCwgYXBwZW5kCiAgICAgICAgICAgIFVURjE2VXRpbC5hcHBlbmRDb2RlUG9pbnQoYnVmZmVyLCBjaCk7CiAgICAgICAgfQogICAgfQogICAgCiAgICAvLyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CiAgICAvLyAgICAgICAgICAgICAgICAgICBQUklWQVRFUwogICAgLy8gPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQogICAgCiAgICAvKioKICAgICAqIE9ubHkgYWNjZXNzZWQgYnkgTm9ybWFsaXplckJ1aWxkZXIuCiAgICAgKi8KICAgIE5vcm1hbGl6ZXJEYXRhKEludEhhc2h0YWJsZSBjYW5vbmljYWxDbGFzcywgSW50U3RyaW5nSGFzaHRhYmxlIGRlY29tcG9zZSwgCiAgICAgIExvbmdIYXNodGFibGUgY29tcG9zZSwgQml0U2V0IGlzQ29tcGF0aWJpbGl0eSwgQml0U2V0IGlzRXhjbHVkZWQpIHsKICAgICAgICB0aGlzLmNhbm9uaWNhbENsYXNzID0gY2Fub25pY2FsQ2xhc3M7CiAgICAgICAgdGhpcy5kZWNvbXBvc2UgPSBkZWNvbXBvc2U7CiAgICAgICAgdGhpcy5jb21wb3NlID0gY29tcG9zZTsKICAgICAgICB0aGlzLmlzQ29tcGF0aWJpbGl0eSA9IGlzQ29tcGF0aWJpbGl0eTsKICAgICAgICB0aGlzLmlzRXhjbHVkZWQgPSBpc0V4Y2x1ZGVkOwogICAgfQogICAgCiAgICAvKioKICAgICogSnVzdCBhY2Nlc3NpYmxlIGZvciB0ZXN0aW5nLgogICAgKi8KICAgIGJvb2xlYW4gZ2V0RXhjbHVkZWQgKGNoYXIgY2gpIHsKICAgICAgICByZXR1cm4gaXNFeGNsdWRlZC5nZXQoY2gpOwogICAgfQogICAKICAgIC8qKgogICAgKiBKdXN0IGFjY2Vzc2libGUgZm9yIHRlc3RpbmcuCiAgICAqLwogICAgU3RyaW5nIGdldFJhd0RlY29tcG9zaXRpb25NYXBwaW5nIChjaGFyIGNoKSB7CiAgICAgICAgcmV0dXJuIGRlY29tcG9zZS5nZXQoY2gpOwogICAgfQogICAKICAgIC8qKgogICAgKiBGb3Igbm93LCBqdXN0IHVzZSBJbnRIYXNodGFibGUKICAgICogVHdvLXN0YWdlIHRhYmxlcyB3b3VsZCBiZSB1c2VkIGluIGFuIG9wdGltaXplZCBpbXBsZW1lbnRhdGlvbi4KICAgICovCiAgICBwcml2YXRlIEludEhhc2h0YWJsZSBjYW5vbmljYWxDbGFzczsKCiAgICAvKioKICAgICogVGhlIG1haW4gZGF0YSB0YWJsZSBtYXBzIGNoYXJzIHRvIGEgMzItYml0IGludC4KICAgICogSXQgaG9sZHMgZWl0aGVyIGEgcGFpcjogdG9wID0gZmlyc3QsIGJvdHRvbSA9IHNlY29uZAogICAgKiBvciBzaW5nbGV0b246IHRvcCA9IDAsIGJvdHRvbSA9IHNpbmdsZS4KICAgICogSWYgdGhlcmUgaXMgbm8gZGVjb21wb3NpdGlvbiwgdGhlIHZhbHVlIGlzIDAuCiAgICAqIFR3by1zdGFnZSB0YWJsZXMgd291bGQgYmUgdXNlZCBpbiBhbiBvcHRpbWl6ZWQgaW1wbGVtZW50YXRpb24uCiAgICAqIEFuIG9wdGltaXphdGlvbiBjb3VsZCBhbHNvIG1hcCBjaGFycyB0byBhIHNtYWxsIGluZGV4LCB0aGVuIHVzZSB0aGF0CiAgICAqIGluZGV4IGluIGEgc21hbGwgYXJyYXkgb2YgaW50cy4KICAgICovCiAgICBwcml2YXRlIEludFN0cmluZ0hhc2h0YWJsZSBkZWNvbXBvc2U7CiAgICAKICAgIC8qKgogICAgKiBNYXBzIGZyb20gcGFpcnMgb2YgY2hhcmFjdGVycyB0byBzaW5nbGUuCiAgICAqIElmIHRoZXJlIGlzIG5vIGRlY29tcG9zaXRpb24sIHRoZSB2YWx1ZSBpcyBOT1RfQ09NUE9TSVRFLgogICAgKi8KICAgIHByaXZhdGUgTG9uZ0hhc2h0YWJsZSBjb21wb3NlOwogICAgCiAgICAvKioKICAgICogVGVsbHMgd2hldGhlciBkZWNvbXBvc2l0aW9uIGlzIGNhbm9uaWNhbCBvciBub3QuCiAgICAqLwogICAgcHJpdmF0ZSBCaXRTZXQgaXNDb21wYXRpYmlsaXR5ID0gbmV3IEJpdFNldCgpOwogICAgCiAgICAvKioKICAgICogVGVsbHMgd2hldGhlciBjaGFyYWN0ZXIgaXMgc2NyaXB0LWV4Y2x1ZGVkIG9yIG5vdC4KICAgICogVXNlZCBvbmx5IHdoaWxlIGJ1aWxkaW5nLCBhbmQgZm9yIHRlc3RpbmcuCiAgICAqLwogICAgCiAgICBwcml2YXRlIEJpdFNldCBpc0V4Y2x1ZGVkID0gbmV3IEJpdFNldCgpOwp9