LyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogWW91IG1heSBhbWVuZCBhbmQgZGlzdHJpYnV0ZSBhcyB5b3UgbGlrZSwgYnV0IGRvbid0IHJlbW92ZSB0aGlzIGhlYWRlciEKICoKICogRVBQbHVzIHByb3ZpZGVzIHNlcnZlci1zaWRlIGdlbmVyYXRpb24gb2YgRXhjZWwgMjAwNy8yMDEwIHNwcmVhZHNoZWV0cy4KICogU2VlIGh0dHA6Ly93d3cuY29kZXBsZXguY29tL0VQUGx1cyBmb3IgZGV0YWlscy4KICoKICogQ29weXJpZ2h0IChDKSAyMDExICBKYW4gS+RsbG1hbgogKgogKiBUaGlzIGxpYnJhcnkgaXMgZnJlZSBzb2Z0d2FyZTsgeW91IGNhbiByZWRpc3RyaWJ1dGUgaXQgYW5kL29yCiAqIG1vZGlmeSBpdCB1bmRlciB0aGUgdGVybXMgb2YgdGhlIEdOVSBMZXNzZXIgR2VuZXJhbCBQdWJsaWMKICogTGljZW5zZSBhcyBwdWJsaXNoZWQgYnkgdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbjsgZWl0aGVyCiAqIHZlcnNpb24gMi4xIG9mIHRoZSBMaWNlbnNlLCBvciAoYXQgeW91ciBvcHRpb24pIGFueSBsYXRlciB2ZXJzaW9uLgoKICogVGhpcyBsaWJyYXJ5IGlzIGRpc3RyaWJ1dGVkIGluIHRoZSBob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsCiAqIGJ1dCBXSVRIT1VUIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuIHRoZSBpbXBsaWVkIHdhcnJhbnR5IG9mCiAqIE1FUkNIQU5UQUJJTElUWSBvciBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRS4gIAogKiBTZWUgdGhlIEdOVSBMZXNzZXIgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSBmb3IgbW9yZSBkZXRhaWxzLgogKgogKiBUaGUgR05VIExlc3NlciBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIGNhbiBiZSB2aWV3ZWQgYXQgaHR0cDovL3d3dy5vcGVuc291cmNlLm9yZy9saWNlbnNlcy9sZ3BsLWxpY2Vuc2UucGhwCiAqIElmIHlvdSB1bmZhbWlsaWFyIHdpdGggdGhpcyBsaWNlbnNlIG9yIGhhdmUgcXVlc3Rpb25zIGFib3V0IGl0LCBoZXJlIGlzIGFuIGh0dHA6Ly93d3cuZ251Lm9yZy9saWNlbnNlcy9ncGwtZmFxLmh0bWwKICoKICogQWxsIGNvZGUgYW5kIGV4ZWN1dGFibGVzIGFyZSBwcm92aWRlZCAiYXMgaXMiIHdpdGggbm8gd2FycmFudHkgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4gCiAqIFRoZSBhdXRob3IgYWNjZXB0cyBubyBsaWFiaWxpdHkgZm9yIGFueSBkYW1hZ2Ugb3IgbG9zcyBvZiBidXNpbmVzcyB0aGF0IHRoaXMgcHJvZHVjdCBtYXkgY2F1c2UuCiAqCiAqIENvZGUgY2hhbmdlIG5vdGVzOgogKiAKICogQXV0aG9yCQkJCQkJCUNoYW5nZQkJCQkJCURhdGUKICogKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIEphbiBL5GxsbWFuCQkgICAgSW5pdGlhbCBSZWxlYXNlCQkgICAgICAgIDIwMTEtMTEtMDIKICogSmFuIEvkbGxtYW4gICAgICAgICAgVG90YWwgcmV3cml0ZSAgICAgICAgICAgICAgIDIwMTAtMDMtMDEKICogSmFuIEvkbGxtYW4JCSAgICBMaWNlbnNlIGNoYW5nZWQgR1BMLS0+TEdQTCAgMjAxMS0xMi0yNwogKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8KdXNpbmcgU3lzdGVtOwp1c2luZyBTeXN0ZW0uWG1sOwp1c2luZyBTeXN0ZW0uQ29sbGVjdGlvbnMuR2VuZXJpYzsKdXNpbmcgU3lzdGVtLklPOwp1c2luZyBTeXN0ZW0uQ29uZmlndXJhdGlvbjsKdXNpbmcgT2ZmaWNlT3BlblhtbC5EcmF3aW5nOwp1c2luZyBTeXN0ZW0uRGlhZ25vc3RpY3M7CnVzaW5nIE9mZmljZU9wZW5YbWwuRm9ybXVsYVBhcnNpbmcuRXhjZWwuRnVuY3Rpb25zLkxvZ2ljYWw7CnVzaW5nIE9mZmljZU9wZW5YbWwuU3R5bGU7CnVzaW5nIFN5c3RlbS5HbG9iYWxpemF0aW9uOwp1c2luZyBTeXN0ZW0uVGV4dDsKdXNpbmcgU3lzdGVtLlNlY3VyaXR5Owp1c2luZyBPZmZpY2VPcGVuWG1sLkRyYXdpbmcuQ2hhcnQ7CnVzaW5nIE9mZmljZU9wZW5YbWwuU3R5bGUuWG1sQWNjZXNzOwp1c2luZyBTeXN0ZW0uVGV4dC5SZWd1bGFyRXhwcmVzc2lvbnM7CnVzaW5nIE9mZmljZU9wZW5YbWwuRHJhd2luZy5WbWw7CnVzaW5nIE9mZmljZU9wZW5YbWwuVGFibGU7CnVzaW5nIE9mZmljZU9wZW5YbWwuRGF0YVZhbGlkYXRpb247CnVzaW5nIE9mZmljZU9wZW5YbWwuVGFibGUuUGl2b3RUYWJsZTsKdXNpbmcgU3lzdGVtLkNvbXBvbmVudE1vZGVsOwp1c2luZyBTeXN0ZW0uRHJhd2luZzsKdXNpbmcgT2ZmaWNlT3BlblhtbC5Db25kaXRpb25hbEZvcm1hdHRpbmc7CnVzaW5nIE9mZmljZU9wZW5YbWwuVXRpbHM7CnVzaW5nIElvbmljLlppcDsKdXNpbmcgT2ZmaWNlT3BlblhtbC5Gb3JtdWxhUGFyc2luZy5MZXhpY2FsQW5hbHlzaXM7CnVzaW5nIE9mZmljZU9wZW5YbWwuRm9ybXVsYVBhcnNpbmc7CnVzaW5nIE9mZmljZU9wZW5YbWwuUGFja2FnaW5nLklvbmljLlppcDsKbmFtZXNwYWNlIE9mZmljZU9wZW5YbWwKewogICAgLy8vIDxzdW1tYXJ5PgogICAgLy8vIFdvcmtzaGVldCBoaWRkZW4gZW51bWVyYXRpb24KICAgIC8vLyA8L3N1bW1hcnk+CiAgICBwdWJsaWMgZW51bSBlV29ya1NoZWV0SGlkZGVuCiAgICB7CiAgICAgICAgLy8vIDxzdW1tYXJ5PgogICAgICAgIC8vLyBUaGUgd29ya3NoZWV0IGlzIHZpc2libGUKICAgICAgICAvLy8gPC9zdW1tYXJ5PgogICAgICAgIFZpc2libGUsCiAgICAgICAgLy8vIDxzdW1tYXJ5PgogICAgICAgIC8vLyBUaGUgd29ya3NoZWV0IGlzIGhpZGRlbiBidXQgY2FuIGJlIHNob3duIGJ5IHRoZSB1c2VyIHZpYSB0aGUgdXNlciBpbnRlcmZhY2UKICAgICAgICAvLy8gPC9zdW1tYXJ5PgogICAgICAgIEhpZGRlbiwKICAgICAgICAvLy8gPHN1bW1hcnk+CiAgICAgICAgLy8vIFRoZSB3b3Jrc2hlZXQgaXMgaGlkZGVuIGFuZCBjYW5ub3QgYmUgc2hvd24gYnkgdGhlIHVzZXIgdmlhIHRoZSB1c2VyIGludGVyZmFjZQogICAgICAgIC8vLyA8L3N1bW1hcnk+CiAgICAgICAgVmVyeUhpZGRlbgogICAgfQogICAgW0ZsYWdzXQogICAgaW50ZXJuYWwgZW51bSBDZWxsRmxhZ3MKICAgIHsKICAgICAgICAvL01lcmdlZCA9IDB4MSwKICAgICAgICBSaWNoVGV4dCA9IDB4MiwKICAgICAgICBTaGFyZWRGb3JtdWxhID0gMHg0LAogICAgICAgIEFycmF5Rm9ybXVsYSA9IDB4OAogICAgfQogICAgLy8vIDxzdW1tYXJ5PgogICAgLy8vIFJlcHJlc2VudHMgYW4gRXhjZWwgQ2hhcnRzaGVldCBhbmQgcHJvdmlkZXMgYWNjZXNzIHRvIGl0cyBwcm9wZXJ0aWVzIGFuZCBtZXRob2RzCiAgICAvLy8gPC9zdW1tYXJ5PgogICAgcHVibGljIGNsYXNzIEV4Y2VsQ2hhcnRzaGVldCA6IEV4Y2VsV29ya3NoZWV0CiAgICB7CiAgICAgICAgLy9FeGNlbERyYXdpbmdzIGRyYXdzOwogICAgICAgIHB1YmxpYyBFeGNlbENoYXJ0c2hlZXQoWG1sTmFtZXNwYWNlTWFuYWdlciBucywgRXhjZWxQYWNrYWdlIHBjaywgc3RyaW5nIHJlbElELCBVcmkgdXJpV29ya3NoZWV0LCBzdHJpbmcgc2hlZXROYW1lLCBpbnQgc2hlZXRJRCwgaW50IHBvc2l0aW9uSUQsIGVXb3JrU2hlZXRIaWRkZW4gaGlkZGVuLCBlQ2hhcnRUeXBlIGNoYXJ0VHlwZSkgOgogICAgICAgICAgICBiYXNlKG5zLCBwY2ssIHJlbElELCB1cmlXb3Jrc2hlZXQsIHNoZWV0TmFtZSwgc2hlZXRJRCwgcG9zaXRpb25JRCwgaGlkZGVuKQogICAgICAgIHsKICAgICAgICAgICAgdGhpcy5EcmF3aW5ncy5BZGRDaGFydCgiQ2hhcnQgMSIsIGNoYXJ0VHlwZSk7CiAgICAgICAgfQogICAgICAgIHB1YmxpYyBFeGNlbENoYXJ0c2hlZXQoWG1sTmFtZXNwYWNlTWFuYWdlciBucywgRXhjZWxQYWNrYWdlIHBjaywgc3RyaW5nIHJlbElELCBVcmkgdXJpV29ya3NoZWV0LCBzdHJpbmcgc2hlZXROYW1lLCBpbnQgc2hlZXRJRCwgaW50IHBvc2l0aW9uSUQsIGVXb3JrU2hlZXRIaWRkZW4gaGlkZGVuKSA6CiAgICAgICAgICAgIGJhc2UobnMsIHBjaywgcmVsSUQsIHVyaVdvcmtzaGVldCwgc2hlZXROYW1lLCBzaGVldElELCBwb3NpdGlvbklELCBoaWRkZW4pCiAgICAgICAgewogICAgICAgIH0KICAgICAgICBwdWJsaWMgRXhjZWxDaGFydCBDaGFydCAKICAgICAgICB7CiAgICAgICAgICAgIGdldAogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICByZXR1cm4gKEV4Y2VsQ2hhcnQpRHJhd2luZ3NbMF07CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICB9CiAgICAvLy8gPHN1bW1hcnk+CgkvLy8gUmVwcmVzZW50cyBhbiBFeGNlbCB3b3Jrc2hlZXQgYW5kIHByb3ZpZGVzIGFjY2VzcyB0byBpdHMgcHJvcGVydGllcyBhbmQgbWV0aG9kcwoJLy8vIDwvc3VtbWFyeT4KICAgIHB1YmxpYyBjbGFzcyBFeGNlbFdvcmtzaGVldCA6IFhtbEhlbHBlciwgSUVxdWFsaXR5Q29tcGFyZXI8RXhjZWxXb3Jrc2hlZXQ+LCBJRGlzcG9zYWJsZQoJewogICAgICAgIGludGVybmFsIGNsYXNzIEZvcm11bGFzCiAgICAgICAgewogICAgICAgICAgICBwdWJsaWMgRm9ybXVsYXMoSVNvdXJjZUNvZGVUb2tlbml6ZXIgdG9rZW5pemVyKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBfdG9rZW5pemVyID0gdG9rZW5pemVyOwogICAgICAgICAgICB9CgogICAgICAgICAgICBwcml2YXRlIElTb3VyY2VDb2RlVG9rZW5pemVyIF90b2tlbml6ZXI7CiAgICAgICAgICAgIGludGVybmFsIGludCBJbmRleCB7IGdldDsgc2V0OyB9CiAgICAgICAgICAgIGludGVybmFsIHN0cmluZyBBZGRyZXNzIHsgZ2V0OyBzZXQ7IH0KICAgICAgICAgICAgaW50ZXJuYWwgYm9vbCBJc0FycmF5IHsgZ2V0OyBzZXQ7IH0KICAgICAgICAgICAgcHVibGljIHN0cmluZyBGb3JtdWxhIHsgZ2V0OyBzZXQ7IH0KICAgICAgICAgICAgcHVibGljIGludCBTdGFydFJvdyB7IGdldDsgc2V0OyB9CiAgICAgICAgICAgIHB1YmxpYyBpbnQgU3RhcnRDb2wgeyBnZXQ7IHNldDsgfQoKICAgICAgICAgICAgcHJpdmF0ZSBJRW51bWVyYWJsZTxUb2tlbj4gVG9rZW5zIHtnZXQ7IHNldDt9CgogICAgICAgICAgICBpbnRlcm5hbCBzdHJpbmcgR2V0Rm9ybXVsYShpbnQgcm93LCBpbnQgY29sdW1uLCBzdHJpbmcgd29ya3NoZWV0KQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBpZiAoU3RhcnRSb3cgPT0gcm93ICYmIFN0YXJ0Q29sID09IGNvbHVtbikKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICByZXR1cm4gRm9ybXVsYTsKICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICBpZiAoVG9rZW5zID09IG51bGwpCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgVG9rZW5zID0gX3Rva2VuaXplci5Ub2tlbml6ZShGb3JtdWxhLCB3b3Jrc2hlZXQpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICBzdHJpbmcgZiA9ICIiOwogICAgICAgICAgICAgICAgZm9yZWFjaCAodmFyIHRva2VuIGluIFRva2VucykKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICBpZiAodG9rZW4uVG9rZW5UeXBlID09IFRva2VuVHlwZS5FeGNlbEFkZHJlc3MpCiAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICB2YXIgYSA9IG5ldyBFeGNlbEZvcm11bGFBZGRyZXNzKHRva2VuLlZhbHVlKTsKICAgICAgICAgICAgICAgICAgICAgICAgZiArPSBhLkdldE9mZnNldChyb3cgLSBTdGFydFJvdywgY29sdW1uIC0gU3RhcnRDb2wpOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICBlbHNlCiAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICBmICs9IHRva2VuLlZhbHVlOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIHJldHVybiBmOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIC8vLyA8c3VtbWFyeT4KICAgICAgICAvLy8gQ29sbGVjdGlvbiBjb250YWluaW5nIG1lcmdlZCBjZWxsIGFkZHJlc3NlcwogICAgICAgIC8vLyA8L3N1bW1hcnk+CiAgICAgICAgcHVibGljIGNsYXNzIE1lcmdlQ2VsbHNDb2xsZWN0aW9uIDogSUVudW1lcmFibGU8c3RyaW5nPgogICAgICAgIHsKICAgICAgICAgICAgaW50ZXJuYWwgTWVyZ2VDZWxsc0NvbGxlY3Rpb24oKQogICAgICAgICAgICB7CgogICAgICAgICAgICB9CiAgICAgICAgICAgIGludGVybmFsIENlbGxTdG9yZTxpbnQ+IF9jZWxscyA9IG5ldyBDZWxsU3RvcmU8aW50PigpOwogICAgICAgICAgICBMaXN0PHN0cmluZz4gX2xpc3QgPSBuZXcgTGlzdDxzdHJpbmc+KCk7CiAgICAgICAgICAgIGludGVybmFsIExpc3Q8c3RyaW5nPiBMaXN0IHsgZ2V0IHtyZXR1cm4gX2xpc3Q7fSB9CiAgICAgICAgICAgIHB1YmxpYyBzdHJpbmcgdGhpc1tpbnQgcm93LCBpbnQgY29sdW1uXQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBnZXQKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICBpbnQgaXg9LTE7CiAgICAgICAgICAgICAgICAgICAgaWYgKF9jZWxscy5FeGlzdHMocm93LCBjb2x1bW4sIHJlZiBpeCkgJiYgaXggPj0gMCAmJiBpeCA8IExpc3QuQ291bnQpICAvL0ZpeGVzIGlzc3VlIDE1MDc1CiAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gTGlzdFtpeF07CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIGVsc2UKICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBudWxsOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgICAgICBwdWJsaWMgc3RyaW5nIHRoaXNbaW50IGluZGV4XQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBnZXQKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICByZXR1cm4gX2xpc3RbaW5kZXhdOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgICAgIGludGVybmFsIHZvaWQgQWRkKEV4Y2VsQWRkcmVzc0Jhc2UgYWRkcmVzcywgYm9vbCBkb1ZhbGlkYXRlKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBpbnQgaXg9MDsKCiAgICAgICAgICAgICAgICAvL1ZhbGlkYXRlCiAgICAgICAgICAgICAgICBpZiAoZG9WYWxpZGF0ZSAmJiBWYWxpZGF0ZShhZGRyZXNzKSA9PSBmYWxzZSkKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICB0aHJvdyhuZXcgQXJndW1lbnRFeGNlcHRpb24oIkNhbid0IG1lcmdlIGFuZCBhbHJlYWR5IG1lcmdlZCByYW5nZSIpKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGxvY2sodGhpcykKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICBpeCA9IF9saXN0LkNvdW50OwogICAgICAgICAgICAgICAgICAgIF9saXN0LkFkZChhZGRyZXNzLkFkZHJlc3MpOwogICAgICAgICAgICAgICAgICAgIFNldEluZGV4KGFkZHJlc3MsIGl4KTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQoKICAgICAgICAgICAgcHJpdmF0ZSBib29sIFZhbGlkYXRlKEV4Y2VsQWRkcmVzc0Jhc2UgYWRkcmVzcykKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgaW50IGl4PTA7CiAgICAgICAgICAgICAgICBpZihfY2VsbHMuRXhpc3RzKGFkZHJlc3MuX2Zyb21Sb3csIGFkZHJlc3MuX2Zyb21Db2wsIHJlZiBpeCkpCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgaWYgKGl4Pj0wICYmIGl4IDwgX2xpc3QuQ291bnQgJiYgX2xpc3RbaXhdIT1udWxsICYmIGFkZHJlc3MuQWRkcmVzcyA9PSBfbGlzdFtpeF0pCiAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gdHJ1ZTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgZWxzZQogICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgdmFyIGNzZSA9IG5ldyBDZWxsc1N0b3JlRW51bWVyYXRvcjxpbnQ+KF9jZWxscywgYWRkcmVzcy5fZnJvbVJvdywgYWRkcmVzcy5fZnJvbUNvbCwgYWRkcmVzcy5fdG9Sb3csIGFkZHJlc3MuX3RvQ29sKTsKICAgICAgICAgICAgICAgIC8vY2VsbHMKICAgICAgICAgICAgICAgIHdoaWxlKGNzZS5OZXh0KCkpCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgLy9FbnRpcmUgY29sdW1uCiAgICAgICAgICAgICAgICBjc2UgPSBuZXcgQ2VsbHNTdG9yZUVudW1lcmF0b3I8aW50PihfY2VsbHMsIDAsIGFkZHJlc3MuX2Zyb21Db2wsIDAsIGFkZHJlc3MuX3RvQ29sKTsKICAgICAgICAgICAgICAgIHdoaWxlIChjc2UuTmV4dCgpKQogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIC8vRW50aXJlIHJvdwogICAgICAgICAgICAgICAgY3NlID0gbmV3IENlbGxzU3RvcmVFbnVtZXJhdG9yPGludD4oX2NlbGxzLCBhZGRyZXNzLl9mcm9tUm93LCAwLCBhZGRyZXNzLl90b1JvdywgMCk7CiAgICAgICAgICAgICAgICB3aGlsZSAoY3NlLk5leHQoKSkKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICByZXR1cm4gdHJ1ZTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgaW50ZXJuYWwgdm9pZCBTZXRJbmRleChFeGNlbEFkZHJlc3NCYXNlIGFkZHJlc3MsIGludCBpeCkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgaWYgKGFkZHJlc3MuX2Zyb21Sb3cgPT0gMSAmJiBhZGRyZXNzLl90b1JvdyA9PSBFeGNlbFBhY2thZ2UuTWF4Um93cykgLy9FbnRpcmUgcm93CiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgZm9yIChpbnQgY29sID0gYWRkcmVzcy5fZnJvbUNvbDsgY29sIDw9IGFkZHJlc3MuX3RvQ29sOyBjb2wrKykKICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgIF9jZWxscy5TZXRWYWx1ZSgwLCBjb2wsIGl4KTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBlbHNlIGlmIChhZGRyZXNzLl9mcm9tQ29sID09IDEgJiYgYWRkcmVzcy5fdG9Db2wgPT0gRXhjZWxQYWNrYWdlLk1heENvbHVtbnMpIC8vRW50aXJlIHJvdwogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIGZvciAoaW50IHJvdyA9IGFkZHJlc3MuX2Zyb21Sb3c7IHJvdyA8PSBhZGRyZXNzLl90b1Jvdzsgcm93KyspCiAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICBfY2VsbHMuU2V0VmFsdWUocm93LCAwLCBpeCk7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgZWxzZQogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIGZvciAoaW50IGNvbCA9IGFkZHJlc3MuX2Zyb21Db2w7IGNvbCA8PSBhZGRyZXNzLl90b0NvbDsgY29sKyspCiAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICBmb3IgKGludCByb3cgPSBhZGRyZXNzLl9mcm9tUm93OyByb3cgPD0gYWRkcmVzcy5fdG9Sb3c7IHJvdysrKQogICAgICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBfY2VsbHMuU2V0VmFsdWUocm93LCBjb2wsIGl4KTsKICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgICAgICBwdWJsaWMgaW50IENvdW50CiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIGdldAogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIHJldHVybiBfbGlzdC5Db3VudDsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgICAgICBpbnRlcm5hbCB2b2lkIFJlbW92ZShzdHJpbmcgSXRlbSkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgX2xpc3QuUmVtb3ZlKEl0ZW0pOwogICAgICAgICAgICB9CiAgICAgICAgICAgICNyZWdpb24gSUVudW1lcmFibGU8c3RyaW5nPiBNZW1iZXJzCgogICAgICAgICAgICBwdWJsaWMgSUVudW1lcmF0b3I8c3RyaW5nPiBHZXRFbnVtZXJhdG9yKCkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgcmV0dXJuIF9saXN0LkdldEVudW1lcmF0b3IoKTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgI2VuZHJlZ2lvbgoKICAgICAgICAgICAgI3JlZ2lvbiBJRW51bWVyYWJsZSBNZW1iZXJzCgogICAgICAgICAgICBTeXN0ZW0uQ29sbGVjdGlvbnMuSUVudW1lcmF0b3IgU3lzdGVtLkNvbGxlY3Rpb25zLklFbnVtZXJhYmxlLkdldEVudW1lcmF0b3IoKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICByZXR1cm4gX2xpc3QuR2V0RW51bWVyYXRvcigpOwogICAgICAgICAgICB9CiAgICAgICAgICAgIAogICAgICAgICAgICAjZW5kcmVnaW9uCiAgICAgICAgICAgIGludGVybmFsIHZvaWQgQ2xlYXIoRXhjZWxBZGRyZXNzQmFzZSBEZXN0aW5hdGlvbikKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgdmFyIGNzZSA9IG5ldyBDZWxsc1N0b3JlRW51bWVyYXRvcjxpbnQ+KF9jZWxscywgRGVzdGluYXRpb24uX2Zyb21Sb3csIERlc3RpbmF0aW9uLl9mcm9tQ29sLCBEZXN0aW5hdGlvbi5fdG9Sb3csIERlc3RpbmF0aW9uLl90b0NvbCk7CiAgICAgICAgICAgICAgICB2YXIgdXNlZD1uZXcgSGFzaFNldDxpbnQ+KCk7CiAgICAgICAgICAgICAgICB3aGlsZShjc2UuTmV4dCgpKQogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIHZhciB2PWNzZS5WYWx1ZTsKICAgICAgICAgICAgICAgICAgICBpZiAoIXVzZWQuQ29udGFpbnModikgJiYgX2xpc3Rbdl0hPW51bGwpCiAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICB2YXIgYWRyPW5ldyBFeGNlbEFkZHJlc3NCYXNlKF9saXN0W3ZdKTsKICAgICAgICAgICAgICAgICAgICAgICAgaWYgKCEoRGVzdGluYXRpb24uQ29sbGlkZShhZHIpID09IEV4Y2VsQWRkcmVzc0Jhc2UuZUFkZHJlc3NDb2xsaXRpb24uSW5zaWRlIHx8IERlc3RpbmF0aW9uLkNvbGxpZGUoYWRyKT09RXhjZWxBZGRyZXNzQmFzZS5lQWRkcmVzc0NvbGxpdGlvbi5FcXVhbCkpCiAgICAgICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRocm93KG5ldyBJbnZhbGlkT3BlcmF0aW9uRXhjZXB0aW9uKHN0cmluZy5Gb3JtYXQoIkNhbid0IGRlbGV0ZSBtZXJnZWQgY2VsbHMuIEEgcmFuZ2UgaXMgcGFydGx5IG1lcmdlZCB3aXRoIHRoZSBkZWxldGVkIHJhbmdlLiB7MH0iLCBhZHIuX2FkZHJlc3MpKSk7CiAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgdXNlZC5BZGQodik7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgIF9jZWxscy5DbGVhcihEZXN0aW5hdGlvbi5fZnJvbVJvdywgRGVzdGluYXRpb24uX2Zyb21Db2wsIERlc3RpbmF0aW9uLl90b1JvdyAtIERlc3RpbmF0aW9uLl9mcm9tUm93ICsgMSwgRGVzdGluYXRpb24uX3RvQ29sIC0gRGVzdGluYXRpb24uX2Zyb21Db2wgKyAxKTsKICAgICAgICAgICAgICAgIGZvcmVhY2godmFyIGkgaW4gdXNlZCkKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICBfbGlzdFtpXSA9IG51bGw7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgaW50ZXJuYWwgQ2VsbFN0b3JlPG9iamVjdD4gX3ZhbHVlczsKICAgICAgICBpbnRlcm5hbCBDZWxsU3RvcmU8c3RyaW5nPiBfdHlwZXM7CiAgICAgICAgaW50ZXJuYWwgQ2VsbFN0b3JlPGludD4gX3N0eWxlczsKICAgICAgICBpbnRlcm5hbCBDZWxsU3RvcmU8b2JqZWN0PiBfZm9ybXVsYXM7CiAgICAgICAgaW50ZXJuYWwgRmxhZ0NlbGxTdG9yZSBfZmxhZ3M7CiAgICAgICAgaW50ZXJuYWwgQ2VsbFN0b3JlPExpc3Q8VG9rZW4+PiBfZm9ybXVsYVRva2VuczsKCiAgICAgICAgaW50ZXJuYWwgQ2VsbFN0b3JlPFVyaT4gX2h5cGVyTGlua3M7CiAgICAgICAgaW50ZXJuYWwgQ2VsbFN0b3JlPEV4Y2VsQ29tbWVudD4gX2NvbW1lbnRzU3RvcmU7CgogICAgICAgIGludGVybmFsIERpY3Rpb25hcnk8aW50LCBGb3JtdWxhcz4gX3NoYXJlZEZvcm11bGFzID0gbmV3IERpY3Rpb25hcnk8aW50LCBGb3JtdWxhcz4oKTsKICAgICAgICBpbnRlcm5hbCBpbnQgX21pbkNvbCA9IEV4Y2VsUGFja2FnZS5NYXhDb2x1bW5zOwogICAgICAgIGludGVybmFsIGludCBfbWF4Q29sID0gMDsKICAgICAgICAjcmVnaW9uIFdvcmtzaGVldCBQcml2YXRlIFByb3BlcnRpZXMKICAgICAgICBpbnRlcm5hbCBFeGNlbFBhY2thZ2UgX3BhY2thZ2U7CgkJcHJpdmF0ZSBVcmkgX3dvcmtzaGVldFVyaTsKCQlwcml2YXRlIHN0cmluZyBfbmFtZTsKCQlwcml2YXRlIGludCBfc2hlZXRJRDsKICAgICAgICBwcml2YXRlIGludCBfcG9zaXRpb25JRDsKCQlwcml2YXRlIHN0cmluZyBfcmVsYXRpb25zaGlwSUQ7CgkJcHJpdmF0ZSBYbWxEb2N1bWVudCBfd29ya3NoZWV0WG1sOwogICAgICAgIGludGVybmFsIEV4Y2VsV29ya3NoZWV0VmlldyBfc2hlZXRWaWV3OwoJCWludGVybmFsIEV4Y2VsSGVhZGVyRm9vdGVyIF9oZWFkZXJGb290ZXI7CiAgICAgICAgI2VuZHJlZ2lvbgogICAgICAgICNyZWdpb24gRXhjZWxXb3Jrc2hlZXQgQ29uc3RydWN0b3IKICAgICAgICAvLy8gPHN1bW1hcnk+CiAgICAgICAgLy8vIEEgd29ya3NoZWV0CiAgICAgICAgLy8vIDwvc3VtbWFyeT4KICAgICAgICAvLy8gPHBhcmFtIG5hbWU9Im5zIj5OYW1lc3BhY2VtYW5hZ2VyPC9wYXJhbT4KICAgICAgICAvLy8gPHBhcmFtIG5hbWU9ImV4Y2VsUGFja2FnZSI+UGFja2FnZTwvcGFyYW0+CiAgICAgICAgLy8vIDxwYXJhbSBuYW1lPSJyZWxJRCI+UmVsYXRpb25zaGlwIElEPC9wYXJhbT4KICAgICAgICAvLy8gPHBhcmFtIG5hbWU9InVyaVdvcmtzaGVldCI+VVJJPC9wYXJhbT4KICAgICAgICAvLy8gPHBhcmFtIG5hbWU9InNoZWV0TmFtZSI+TmFtZSBvZiB0aGUgc2hlZXQ8L3BhcmFtPgogICAgICAgIC8vLyA8cGFyYW0gbmFtZT0ic2hlZXRJRCI+U2hlZXQgaWQ8L3BhcmFtPgogICAgICAgIC8vLyA8cGFyYW0gbmFtZT0icG9zaXRpb25JRCI+UG9zaXRpb248L3BhcmFtPgogICAgICAgIC8vLyA8cGFyYW0gbmFtZT0iaGlkZSI+aGlkZTwvcGFyYW0+CiAgICAgICAgcHVibGljIEV4Y2VsV29ya3NoZWV0KFhtbE5hbWVzcGFjZU1hbmFnZXIgbnMsIEV4Y2VsUGFja2FnZSBleGNlbFBhY2thZ2UsIHN0cmluZyByZWxJRCwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFVyaSB1cmlXb3Jrc2hlZXQsIHN0cmluZyBzaGVldE5hbWUsIGludCBzaGVldElELCBpbnQgcG9zaXRpb25JRCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZVdvcmtTaGVldEhpZGRlbiBoaWRlKSA6CiAgICAgICAgICAgIGJhc2UobnMsIG51bGwpCiAgICAgICAgewogICAgICAgICAgICBTY2hlbWFOb2RlT3JkZXIgPSBuZXcgc3RyaW5nW10geyAic2hlZXRQciIsICJ0YWJDb2xvciIsICJvdXRsaW5lUHIiLCAicGFnZVNldFVwUHIiLCAiZGltZW5zaW9uIiwgInNoZWV0Vmlld3MiLCAic2hlZXRGb3JtYXRQciIsICJjb2xzIiwgInNoZWV0RGF0YSIsICJzaGVldFByb3RlY3Rpb24iLCAicHJvdGVjdGVkUmFuZ2VzIiwic2NlbmFyaW9zIiwgImF1dG9GaWx0ZXIiLCAic29ydFN0YXRlIiwgImRhdGFDb25zb2xpZGF0ZSIsICJjdXN0b21TaGVldFZpZXdzIiwgImN1c3RvbVNoZWV0Vmlld3MiLCAibWVyZ2VDZWxscyIsICJwaG9uZXRpY1ByIiwgImNvbmRpdGlvbmFsRm9ybWF0dGluZyIsICJkYXRhVmFsaWRhdGlvbnMiLCAiaHlwZXJsaW5rcyIsICJwcmludE9wdGlvbnMiLCAicGFnZU1hcmdpbnMiLCAicGFnZVNldHVwIiwgImhlYWRlckZvb3RlciIsICJsaW5lUHJpbnQiLCAicm93QnJlYWtzIiwgImNvbEJyZWFrcyIsICJjdXN0b21Qcm9wZXJ0aWVzIiwgImNlbGxXYXRjaGVzIiwgImlnbm9yZWRFcnJvcnMiLCAic21hcnRUYWdzIiwgImRyYXdpbmciLCAibGVnYWN5RHJhd2luZyIsICJsZWdhY3lEcmF3aW5nSEYiLCAicGljdHVyZSIsICJvbGVPYmplY3RzIiwgImFjdGl2ZVhDb250cm9scyIsICJ3ZWJQdWJsaXNoSXRlbXMiLCAidGFibGVQYXJ0cyIgLCAiZXh0THN0IiB9OwogICAgICAgICAgICBfcGFja2FnZSA9IGV4Y2VsUGFja2FnZTsgICAKICAgICAgICAgICAgX3JlbGF0aW9uc2hpcElEID0gcmVsSUQ7CiAgICAgICAgICAgIF93b3Jrc2hlZXRVcmkgPSB1cmlXb3Jrc2hlZXQ7CiAgICAgICAgICAgIF9uYW1lID0gc2hlZXROYW1lOwogICAgICAgICAgICBfc2hlZXRJRCA9IHNoZWV0SUQ7CiAgICAgICAgICAgIF9wb3NpdGlvbklEID0gcG9zaXRpb25JRDsKICAgICAgICAgICAgSGlkZGVuID0gaGlkZTsKICAgICAgICAgICAKICAgICAgICAgICAgLyoqKiogQ2VsbHN0b3JlICoqKiovCiAgICAgICAgICAgIF92YWx1ZXM9bmV3IENlbGxTdG9yZTxvYmplY3Q+KCk7CiAgICAgICAgICAgIF90eXBlcyA9IG5ldyBDZWxsU3RvcmU8c3RyaW5nPigpOwogICAgICAgICAgICBfc3R5bGVzID0gbmV3IENlbGxTdG9yZTxpbnQ+KCk7CiAgICAgICAgICAgIF9mb3JtdWxhcyA9IG5ldyBDZWxsU3RvcmU8b2JqZWN0PigpOwogICAgICAgICAgICBfZmxhZ3MgPSBuZXcgRmxhZ0NlbGxTdG9yZSgpOwogICAgICAgICAgICBfY29tbWVudHNTdG9yZSA9IG5ldyBDZWxsU3RvcmU8RXhjZWxDb21tZW50PigpOwogICAgICAgICAgICBfaHlwZXJMaW5rcyA9IG5ldyBDZWxsU3RvcmU8VXJpPigpOwogICAgICAgICAgICAKICAgICAgICAgICAgX25hbWVzID0gbmV3IEV4Y2VsTmFtZWRSYW5nZUNvbGxlY3Rpb24oV29ya2Jvb2ssdGhpcyk7CgogICAgICAgICAgICBDcmVhdGVYbWwoKTsKICAgICAgICAgICAgVG9wTm9kZSA9IF93b3Jrc2hlZXRYbWwuRG9jdW1lbnRFbGVtZW50OwogICAgICAgIH0KCiAgICAgICAgI2VuZHJlZ2lvbgogICAgICAgIC8vLyA8c3VtbWFyeT4KICAgICAgICAvLy8gVGhlIFVyaSB0byB0aGUgd29ya3NoZWV0IHdpdGhpbiB0aGUgcGFja2FnZQogICAgICAgIC8vLyA8L3N1bW1hcnk+CiAgICAgICAgaW50ZXJuYWwgVXJpIFdvcmtzaGVldFVyaSB7IGdldCB7IHJldHVybiAoX3dvcmtzaGVldFVyaSk7IH0gfQogICAgICAgIC8vLyA8c3VtbWFyeT4KICAgICAgICAvLy8gVGhlIFppcC5aaXBQYWNrYWdlUGFydCBmb3IgdGhlIHdvcmtzaGVldCB3aXRoaW4gdGhlIHBhY2thZ2UKICAgICAgICAvLy8gPC9zdW1tYXJ5PgogICAgICAgIGludGVybmFsIFBhY2thZ2luZy5aaXBQYWNrYWdlUGFydCBQYXJ0IHsgZ2V0IHsgcmV0dXJuIChfcGFja2FnZS5QYWNrYWdlLkdldFBhcnQoV29ya3NoZWV0VXJpKSk7IH0gfQogICAgICAgIC8vLyA8c3VtbWFyeT4KICAgICAgICAvLy8gVGhlIElEIGZvciB0aGUgd29ya3NoZWV0J3MgcmVsYXRpb25zaGlwIHdpdGggdGhlIHdvcmtib29rIGluIHRoZSBwYWNrYWdlCiAgICAgICAgLy8vIDwvc3VtbWFyeT4KICAgICAgICBpbnRlcm5hbCBzdHJpbmcgUmVsYXRpb25zaGlwSUQgeyBnZXQgeyByZXR1cm4gKF9yZWxhdGlvbnNoaXBJRCk7IH0gfQogICAgICAgIC8vLyA8c3VtbWFyeT4KICAgICAgICAvLy8gVGhlIHVuaXF1ZSBpZGVudGlmaWVyIGZvciB0aGUgd29ya3NoZWV0LgogICAgICAgIC8vLyA8L3N1bW1hcnk+CiAgICAgICAgaW50ZXJuYWwgaW50IFNoZWV0SUQgeyBnZXQgeyByZXR1cm4gKF9zaGVldElEKTsgfSB9CiAgICAgICAgLy8vIDxzdW1tYXJ5PgogICAgICAgIC8vLyBUaGUgcG9zaXRpb24gb2YgdGhlIHdvcmtzaGVldC4KICAgICAgICAvLy8gPC9zdW1tYXJ5PgogICAgICAgIGludGVybmFsIGludCBQb3NpdGlvbklEIHsgZ2V0IHsgcmV0dXJuIChfcG9zaXRpb25JRCk7IH0gc2V0IHsgX3Bvc2l0aW9uSUQgPSB2YWx1ZTsgfSB9CgkJI3JlZ2lvbiBXb3Jrc2hlZXQgUHVibGljIFByb3BlcnRpZXMKICAgIAkvLy8gPHN1bW1hcnk+CiAgICAgICAgLy8vIFRoZSBpbmRleCBpbiB0aGUgd29ya3NoZWV0cyBjb2xsZWN0aW9uCiAgICAgICAgLy8vIDwvc3VtbWFyeT4KICAgICAgICBwdWJsaWMgaW50IEluZGV4IHsgZ2V0IHsgcmV0dXJuIChfcG9zaXRpb25JRCk7IH0gfQogICAgICAgIC8vLyA8c3VtbWFyeT4KICAgICAgICAvLy8gQWRkcmVzcyBmb3IgYXV0b2ZpbHRlcgogICAgICAgIC8vLyA8c2VlYWxzbyBjcmVmPSJFeGNlbFJhbmdlQmFzZS5BdXRvRmlsdGVyIiAvPiAgICAgICAgCiAgICAgICAgLy8vIDwvc3VtbWFyeT4KICAgICAgICBwdWJsaWMgRXhjZWxBZGRyZXNzQmFzZSBBdXRvRmlsdGVyQWRkcmVzcwogICAgICAgIHsKICAgICAgICAgICAgZ2V0CiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIENoZWNrU2hlZXRUeXBlKCk7CiAgICAgICAgICAgICAgICBzdHJpbmcgYWRkcmVzcyA9IEdldFhtbE5vZGVTdHJpbmcoImQ6YXV0b0ZpbHRlci9AcmVmIik7CiAgICAgICAgICAgICAgICBpZiAoYWRkcmVzcyA9PSAiIikKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICByZXR1cm4gbnVsbDsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGVsc2UKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICByZXR1cm4gbmV3IEV4Y2VsQWRkcmVzc0Jhc2UoYWRkcmVzcyk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICAgICAgaW50ZXJuYWwgc2V0CiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIENoZWNrU2hlZXRUeXBlKCk7CiAgICAgICAgICAgICAgICBTZXRYbWxOb2RlU3RyaW5nKCJkOmF1dG9GaWx0ZXIvQHJlZiIsIHZhbHVlLkFkZHJlc3MpOwogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICBpbnRlcm5hbCB2b2lkIENoZWNrU2hlZXRUeXBlKCkKICAgICAgICB7CiAgICAgICAgICAgIGlmICh0aGlzIGlzIEV4Y2VsQ2hhcnRzaGVldCkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgdGhyb3cgKG5ldyBOb3RTdXBwb3J0ZWRFeGNlcHRpb24oIlRoaXMgcHJvcGVydHkgb3IgbWV0aG9kIGlzIG5vdCBzdXBwb3J0ZWQgZm9yIGEgQ2hhcnRzaGVldCIpKTsKICAgICAgICAgICAgfQogICAgICAgIH0KCgkJLy8vIDxzdW1tYXJ5PgoJCS8vLyBSZXR1cm5zIGEgRXhjZWxXb3Jrc2hlZXRWaWV3IG9iamVjdCB0aGF0IGFsbG93cyB5b3UgdG8gc2V0IHRoZSB2aWV3IHN0YXRlIHByb3BlcnRpZXMgb2YgdGhlIHdvcmtzaGVldAoJCS8vLyA8L3N1bW1hcnk+CgkJcHVibGljIEV4Y2VsV29ya3NoZWV0VmlldyBWaWV3CgkJewoJCQlnZXQKCQkJewoJCQkJaWYgKF9zaGVldFZpZXcgPT0gbnVsbCkKCQkJCXsKICAgICAgICAgICAgICAgICAgICBYbWxOb2RlIG5vZGUgPSBUb3BOb2RlLlNlbGVjdFNpbmdsZU5vZGUoImQ6c2hlZXRWaWV3cy9kOnNoZWV0VmlldyIsIE5hbWVTcGFjZU1hbmFnZXIpOwogICAgICAgICAgICAgICAgICAgIGlmIChub2RlID09IG51bGwpCiAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICBDcmVhdGVOb2RlKCJkOnNoZWV0Vmlld3MvZDpzaGVldFZpZXciKTsgLy90aGlzIG9uZSBzaG91bHMgYWx3YXlzIGV4aXN0LiBidXQgY2hlY2sgYW55d2F5CiAgICAgICAgICAgICAgICAgICAgICAgIG5vZGUgPSBUb3BOb2RlLlNlbGVjdFNpbmdsZU5vZGUoImQ6c2hlZXRWaWV3cy9kOnNoZWV0VmlldyIsIE5hbWVTcGFjZU1hbmFnZXIpOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICBfc2hlZXRWaWV3ID0gbmV3IEV4Y2VsV29ya3NoZWV0VmlldyhOYW1lU3BhY2VNYW5hZ2VyLCBub2RlLCB0aGlzKTsKCQkJCX0KCQkJCXJldHVybiAoX3NoZWV0Vmlldyk7CgkJCX0KCQl9CgoJCS8vLyA8c3VtbWFyeT4KCQkvLy8gVGhlIHdvcmtzaGVldCdzIGRpc3BsYXkgbmFtZSBhcyBpdCBhcHBlYXJzIG9uIHRoZSB0YWIKCQkvLy8gPC9zdW1tYXJ5PgoJCXB1YmxpYyBzdHJpbmcgTmFtZQoJCXsKCQkJZ2V0IHsgcmV0dXJuIChfbmFtZSk7IH0KCQkJc2V0CgkJCXsKICAgICAgICAgICAgICAgIGlmICh2YWx1ZSA9PSBfbmFtZSkgcmV0dXJuOwogICAgICAgICAgICAgICAgdmFsdWU9X3BhY2thZ2UuV29ya2Jvb2suV29ya3NoZWV0cy5WYWxpZGF0ZUZpeFNoZWV0TmFtZSh2YWx1ZSk7CiAgICAgICAgICAgICAgICBmb3JlYWNoKHZhciB3cyBpbiBXb3JrYm9vay5Xb3Jrc2hlZXRzKQogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIGlmKHdzLlBvc2l0aW9uSUQhPVBvc2l0aW9uSUQgJiYgd3MuTmFtZS5FcXVhbHModmFsdWUsU3RyaW5nQ29tcGFyaXNvbi5JbnZhcmlhbnRDdWx0dXJlSWdub3JlQ2FzZSkpCiAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICB0aHJvdyAobmV3IEFyZ3VtZW50RXhjZXB0aW9uKCJXb3Jrc2hlZXQgbmFtZSBtdXN0IGJlIHVuaXF1ZSIpKTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBfcGFja2FnZS5Xb3JrYm9vay5TZXRYbWxOb2RlU3RyaW5nKHN0cmluZy5Gb3JtYXQoImQ6c2hlZXRzL2Q6c2hlZXRbQHNoZWV0SWQ9ezB9XS9AbmFtZSIsIF9zaGVldElEKSwgdmFsdWUpOwogICAgICAgICAgICAgICAgQ2hhbmdlTmFtZXModmFsdWUpOwoKICAgICAgICAgICAgICAgIF9uYW1lID0gdmFsdWU7CiAgICAgICAgICAgIH0KCQl9CgogICAgICAgIHByaXZhdGUgdm9pZCBDaGFuZ2VOYW1lcyhzdHJpbmcgdmFsdWUpCiAgICAgICAgewogICAgICAgICAgICAvL1JlbmFtZXMgbmFtZSBpbiB0aGlzIFdvcmtzaGVldDsKICAgICAgICAgICAgZm9yZWFjaCAodmFyIG4gaW4gV29ya2Jvb2suTmFtZXMpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIGlmIChzdHJpbmcuSXNOdWxsT3JFbXB0eShuLk5hbWVGb3JtdWxhKSAmJiBuLk5hbWVWYWx1ZT09bnVsbCkKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICBuLkNoYW5nZVdvcmtzaGVldChfbmFtZSwgdmFsdWUpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgICAgIGZvcmVhY2ggKHZhciB3cyBpbiBXb3JrYm9vay5Xb3Jrc2hlZXRzKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBpZiAoISh3cyBpcyBFeGNlbENoYXJ0c2hlZXQpKQogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIGZvcmVhY2ggKHZhciBuIGluIHdzLk5hbWVzKQogICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHN0cmluZy5Jc051bGxPckVtcHR5KG4uTmFtZUZvcm11bGEpICYmIG4uTmFtZVZhbHVlID09IG51bGwpCiAgICAgICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIG4uQ2hhbmdlV29ya3NoZWV0KF9uYW1lLCB2YWx1ZSk7CiAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgaW50ZXJuYWwgRXhjZWxOYW1lZFJhbmdlQ29sbGVjdGlvbiBfbmFtZXM7CiAgICAgICAgLy8vIDxzdW1tYXJ5PgogICAgICAgIC8vLyBQcm92aWRlcyBhY2Nlc3MgdG8gbmFtZWQgcmFuZ2VzCiAgICAgICAgLy8vIDwvc3VtbWFyeT4KICAgICAgICBwdWJsaWMgRXhjZWxOYW1lZFJhbmdlQ29sbGVjdGlvbiBOYW1lcyAKICAgICAgICB7CiAgICAgICAgICAgIGdldAogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBDaGVja1NoZWV0VHlwZSgpOwogICAgICAgICAgICAgICAgcmV0dXJuIF9uYW1lczsKICAgICAgICAgICAgfQogICAgICAgIH0KCQkvLy8gPHN1bW1hcnk+CgkJLy8vIEluZGljYXRlcyBpZiB0aGUgd29ya3NoZWV0IGlzIGhpZGRlbiBpbiB0aGUgd29ya2Jvb2sKCQkvLy8gPC9zdW1tYXJ5PgoJCXB1YmxpYyBlV29ya1NoZWV0SGlkZGVuIEhpZGRlbgoJCXsKCQkJZ2V0IAogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBzdHJpbmcgc3RhdGU9X3BhY2thZ2UuV29ya2Jvb2suR2V0WG1sTm9kZVN0cmluZyhzdHJpbmcuRm9ybWF0KCJkOnNoZWV0cy9kOnNoZWV0W0BzaGVldElkPXswfV0vQHN0YXRlIiwgX3NoZWV0SUQpKTsKICAgICAgICAgICAgICAgIGlmIChzdGF0ZSA9PSAiaGlkZGVuIikKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICByZXR1cm4gZVdvcmtTaGVldEhpZGRlbi5IaWRkZW47CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBlbHNlIGlmIChzdGF0ZSA9PSAidmVyeUhpZGRlbiIpCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGVXb3JrU2hlZXRIaWRkZW4uVmVyeUhpZGRlbjsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIHJldHVybiBlV29ya1NoZWV0SGlkZGVuLlZpc2libGU7CiAgICAgICAgICAgIH0KCQkJc2V0CgkJCXsKICAgICAgICAgICAgICAgICAgICBpZiAodmFsdWUgPT0gZVdvcmtTaGVldEhpZGRlbi5WaXNpYmxlKQogICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgX3BhY2thZ2UuV29ya2Jvb2suRGVsZXRlTm9kZShzdHJpbmcuRm9ybWF0KCJkOnNoZWV0cy9kOnNoZWV0W0BzaGVldElkPXswfV0vQHN0YXRlIiwgX3NoZWV0SUQpKTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgZWxzZQogICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgc3RyaW5nIHY7CiAgICAgICAgICAgICAgICAgICAgICAgIHY9dmFsdWUuVG9TdHJpbmcoKTsgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgdj12LlN1YnN0cmluZygwLDEpLlRvTG93ZXIoQ3VsdHVyZUluZm8uSW52YXJpYW50Q3VsdHVyZSkrdi5TdWJzdHJpbmcoMSk7CiAgICAgICAgICAgICAgICAgICAgICAgIF9wYWNrYWdlLldvcmtib29rLlNldFhtbE5vZGVTdHJpbmcoc3RyaW5nLkZvcm1hdCgiZDpzaGVldHMvZDpzaGVldFtAc2hlZXRJZD17MH1dL0BzdGF0ZSIsIF9zaGVldElEKSx2ICk7CiAgICAgICAgICAgICAgICAgICAgfQoJCSAgICB9CgkJfQogICAgICAgIGRvdWJsZSBfZGVmYXVsdFJvd0hlaWdodCA9IGRvdWJsZS5OYU47CiAgICAgICAgLy8vIDxzdW1tYXJ5PgoJCS8vLyBHZXQvc2V0IHRoZSBkZWZhdWx0IGhlaWdodCBvZiBhbGwgcm93cyBpbiB0aGUgd29ya3NoZWV0CgkJLy8vIDwvc3VtbWFyeT4KICAgICAgICBwdWJsaWMgZG91YmxlIERlZmF1bHRSb3dIZWlnaHQKCQl7CgkJCWdldCAKCQkJewogICAgICAgICAgICAgICAgQ2hlY2tTaGVldFR5cGUoKTsKICAgICAgICAgICAgICAgIGlmIChkb3VibGUuSXNOYU4oX2RlZmF1bHRSb3dIZWlnaHQpKQogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIF9kZWZhdWx0Um93SGVpZ2h0ID0gR2V0WG1sTm9kZURvdWJsZSgiZDpzaGVldEZvcm1hdFByL0BkZWZhdWx0Um93SGVpZ2h0Iik7CiAgICAgICAgICAgICAgICAgICAgaWYoZG91YmxlLklzTmFOKF9kZWZhdWx0Um93SGVpZ2h0KSkKICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgIF9kZWZhdWx0Um93SGVpZ2h0ID0gMTU7IC8vIEV4Y2VsIGRlZmF1bHQgaGVpZ2h0CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfQoJCQkJcmV0dXJuIF9kZWZhdWx0Um93SGVpZ2h0OwoJCQl9CgkJCXNldAoJCQl7CiAgICAgICAgICAgICAgICBDaGVja1NoZWV0VHlwZSgpOwogICAgICAgICAgICAgICAgX2RlZmF1bHRSb3dIZWlnaHQgPSB2YWx1ZTsKICAgICAgICAgICAgICAgIFNldFhtbE5vZGVTdHJpbmcoImQ6c2hlZXRGb3JtYXRQci9AZGVmYXVsdFJvd0hlaWdodCIsIHZhbHVlLlRvU3RyaW5nKEN1bHR1cmVJbmZvLkludmFyaWFudEN1bHR1cmUpKTsKICAgICAgICAgICAgICAgIFNldFhtbE5vZGVCb29sKCJkOnNoZWV0Rm9ybWF0UHIvQGN1c3RvbUhlaWdodCIsIHZhbHVlICE9IDE1KTsKCiAgICAgICAgICAgICAgICBpZiAoZG91YmxlLklzTmFOKEdldFhtbE5vZGVEb3VibGUoImQ6c2hlZXRGb3JtYXRQci9AZGVmYXVsdENvbFdpZHRoIikpKQogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIERlZmF1bHRDb2xXaWR0aCA9IDkuMTQwNjI1OwogICAgICAgICAgICAgICAgfQoJCQl9CgkJfQogICAgICAgIC8vLyA8c3VtbWFyeT4KICAgICAgICAvLy8gR2V0L3NldCB0aGUgZGVmYXVsdCB3aWR0aCBvZiBhbGwgcm93cyBpbiB0aGUgd29ya3NoZWV0CiAgICAgICAgLy8vIDwvc3VtbWFyeT4KICAgICAgICBwdWJsaWMgZG91YmxlIERlZmF1bHRDb2xXaWR0aAogICAgICAgIHsKICAgICAgICAgICAgZ2V0CiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIENoZWNrU2hlZXRUeXBlKCk7CiAgICAgICAgICAgICAgICBkb3VibGUgcmV0ID0gR2V0WG1sTm9kZURvdWJsZSgiZDpzaGVldEZvcm1hdFByL0BkZWZhdWx0Q29sV2lkdGgiKTsKICAgICAgICAgICAgICAgIGlmIChkb3VibGUuSXNOYU4ocmV0KSkKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICByZXQgPSA5LjE0MDYyNTsgLy8gRXhjZWwncyBkZWZhdWx0IHdpZHRoCiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICByZXR1cm4gcmV0OwogICAgICAgICAgICB9CiAgICAgICAgICAgIHNldAogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBDaGVja1NoZWV0VHlwZSgpOwogICAgICAgICAgICAgICAgU2V0WG1sTm9kZVN0cmluZygiZDpzaGVldEZvcm1hdFByL0BkZWZhdWx0Q29sV2lkdGgiLCB2YWx1ZS5Ub1N0cmluZyhDdWx0dXJlSW5mby5JbnZhcmlhbnRDdWx0dXJlKSk7CgogICAgICAgICAgICAgICAgaWYgKGRvdWJsZS5Jc05hTihHZXRYbWxOb2RlRG91YmxlKCJkOnNoZWV0Rm9ybWF0UHIvQGRlZmF1bHRSb3dIZWlnaHQiKSkpCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgRGVmYXVsdFJvd0hlaWdodCA9IDE1OwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIC8qKiA8b3V0bGluZVByIGFwcGx5U3R5bGVzPSIxIiBzdW1tYXJ5QmVsb3c9IjAiIHN1bW1hcnlSaWdodD0iMCIgLz4gKiovCiAgICAgICAgY29uc3Qgc3RyaW5nIG91dExpbmVTdW1tYXJ5QmVsb3dQYXRoID0gImQ6c2hlZXRQci9kOm91dGxpbmVQci9Ac3VtbWFyeUJlbG93IjsKICAgICAgICAvLy8gPHN1bW1hcnk+CiAgICAgICAgLy8vIFN1bW1hcnkgcm93cyBiZWxvdyBkZXRhaWxzIAogICAgICAgIC8vLyA8L3N1bW1hcnk+CiAgICAgICAgcHVibGljIGJvb2wgT3V0TGluZVN1bW1hcnlCZWxvdwogICAgICAgIHsgCiAgICAgICAgICAgIGdldAogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBDaGVja1NoZWV0VHlwZSgpOwogICAgICAgICAgICAgICAgcmV0dXJuIEdldFhtbE5vZGVCb29sKG91dExpbmVTdW1tYXJ5QmVsb3dQYXRoKTsKICAgICAgICAgICAgfQogICAgICAgICAgICBzZXQKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgQ2hlY2tTaGVldFR5cGUoKTsKICAgICAgICAgICAgICAgIFNldFhtbE5vZGVTdHJpbmcob3V0TGluZVN1bW1hcnlCZWxvd1BhdGgsIHZhbHVlID8gIjEiIDogIjAiKTsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgICAgICBjb25zdCBzdHJpbmcgb3V0TGluZVN1bW1hcnlSaWdodFBhdGggPSAiZDpzaGVldFByL2Q6b3V0bGluZVByL0BzdW1tYXJ5UmlnaHQiOwogICAgICAgIC8vLyA8c3VtbWFyeT4KICAgICAgICAvLy8gU3VtbWFyeSByb3dzIHRvIHJpZ2h0IG9mIGRldGFpbHMKICAgICAgICAvLy8gPC9zdW1tYXJ5PgogICAgICAgIHB1YmxpYyBib29sIE91dExpbmVTdW1tYXJ5UmlnaHQKICAgICAgICB7CiAgICAgICAgICAgIGdldAogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBDaGVja1NoZWV0VHlwZSgpOwogICAgICAgICAgICAgICAgcmV0dXJuIEdldFhtbE5vZGVCb29sKG91dExpbmVTdW1tYXJ5UmlnaHRQYXRoKTsKICAgICAgICAgICAgfQogICAgICAgICAgICBzZXQKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgQ2hlY2tTaGVldFR5cGUoKTsKICAgICAgICAgICAgICAgIFNldFhtbE5vZGVTdHJpbmcob3V0TGluZVN1bW1hcnlSaWdodFBhdGgsIHZhbHVlID8gIjEiIDogIjAiKTsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgICAgICBjb25zdCBzdHJpbmcgb3V0TGluZUFwcGx5U3R5bGVQYXRoID0gImQ6c2hlZXRQci9kOm91dGxpbmVQci9AYXBwbHlTdHlsZXMiOwogICAgICAgIC8vLyA8c3VtbWFyeT4KICAgICAgICAvLy8gQXV0b21hdGljIHN0eWxlcwogICAgICAgIC8vLyA8L3N1bW1hcnk+CiAgICAgICAgcHVibGljIGJvb2wgT3V0TGluZUFwcGx5U3R5bGUKICAgICAgICB7CiAgICAgICAgICAgIGdldAogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBDaGVja1NoZWV0VHlwZSgpOwogICAgICAgICAgICAgICAgcmV0dXJuIEdldFhtbE5vZGVCb29sKG91dExpbmVBcHBseVN0eWxlUGF0aCk7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgc2V0CiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIENoZWNrU2hlZXRUeXBlKCk7CiAgICAgICAgICAgICAgICBTZXRYbWxOb2RlU3RyaW5nKG91dExpbmVBcHBseVN0eWxlUGF0aCwgdmFsdWUgPyAiMSIgOiAiMCIpOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIGNvbnN0IHN0cmluZyB0YWJDb2xvclBhdGggPSAiZDpzaGVldFByL2Q6dGFiQ29sb3IvQHJnYiI7CiAgICAgICAgLy8vIDxzdW1tYXJ5PgogICAgICAgIC8vLyBDb2xvciBvZiB0aGUgc2hlZXQgdGFiCiAgICAgICAgLy8vIDwvc3VtbWFyeT4KICAgICAgICBwdWJsaWMgQ29sb3IgVGFiQ29sb3IKICAgICAgICB7CiAgICAgICAgICAgIGdldAogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBzdHJpbmcgY29sID0gR2V0WG1sTm9kZVN0cmluZyh0YWJDb2xvclBhdGgpOwogICAgICAgICAgICAgICAgaWYgKGNvbCA9PSAiIikKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICByZXR1cm4gQ29sb3IuRW1wdHk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBlbHNlCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIENvbG9yLkZyb21BcmdiKGludC5QYXJzZShjb2wsIFN5c3RlbS5HbG9iYWxpemF0aW9uLk51bWJlclN0eWxlcy5BbGxvd0hleFNwZWNpZmllcikpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgICAgIHNldAogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBTZXRYbWxOb2RlU3RyaW5nKHRhYkNvbG9yUGF0aCwgdmFsdWUuVG9BcmdiKCkuVG9TdHJpbmcoIlgiKSk7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgY29uc3Qgc3RyaW5nIGNvZGVNb2R1bGVOYW1lUGF0aCA9ICJkOnNoZWV0UHIvQGNvZGVOYW1lIjsKICAgICAgICBpbnRlcm5hbCBzdHJpbmcgQ29kZU1vZHVsZU5hbWUKICAgICAgICB7CiAgICAgICAgICAgIGdldAogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICByZXR1cm4gR2V0WG1sTm9kZVN0cmluZyhjb2RlTW9kdWxlTmFtZVBhdGgpOwogICAgICAgICAgICB9CiAgICAgICAgICAgIHNldAogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBTZXRYbWxOb2RlU3RyaW5nKGNvZGVNb2R1bGVOYW1lUGF0aCwgdmFsdWUpOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIGludGVybmFsIHZvaWQgQ29kZU5hbWVDaGFuZ2Uoc3RyaW5nIHZhbHVlKQogICAgICAgIHsKICAgICAgICAgICAgQ29kZU1vZHVsZU5hbWUgPSB2YWx1ZTsKICAgICAgICB9CiAgICAgICAgcHVibGljIFZCQS5FeGNlbFZCQU1vZHVsZSBDb2RlTW9kdWxlCiAgICAgICAgewogICAgICAgICAgICBnZXQKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgaWYgKF9wYWNrYWdlLldvcmtib29rLlZiYVByb2plY3QgIT0gbnVsbCkKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICByZXR1cm4gX3BhY2thZ2UuV29ya2Jvb2suVmJhUHJvamVjdC5Nb2R1bGVzW0NvZGVNb2R1bGVOYW1lXTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGVsc2UKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICByZXR1cm4gbnVsbDsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgIH0KICAgICAgICAjcmVnaW9uIFdvcmtzaGVldFhtbAoJCS8vLyA8c3VtbWFyeT4KCQkvLy8gVGhlIFhNTCBkb2N1bWVudCBob2xkaW5nIHRoZSB3b3Jrc2hlZXQgZGF0YS4KICAgICAgICAvLy8gQWxsIGNvbHVtbiwgcm93LCBjZWxsLCBwYWdlYnJlYWssIG1lcmdlZCBjZWxsIGFuZCBoeXBlcmxpbmstZGF0YSBhcmUgbG9hZGVkIGludG8gbWVtb3J5IGFuZCByZW1vdmVkIGZyb20gdGhlIGRvY3VtZW50IHdoZW4gbG9hZGluZyB0aGUgZG9jdW1lbnQuICAgICAgICAKCQkvLy8gPC9zdW1tYXJ5PgoJCXB1YmxpYyBYbWxEb2N1bWVudCBXb3Jrc2hlZXRYbWwKCQl7CgkJCWdldAoJCQl7CgkJCQlyZXR1cm4gKF93b3Jrc2hlZXRYbWwpOwoJCQl9CgkJfQogICAgICAgIGludGVybmFsIEV4Y2VsVm1sRHJhd2luZ0NvbW1lbnRDb2xsZWN0aW9uIF92bWxEcmF3aW5ncyA9IG51bGw7CiAgICAgICAgLy8vIDxzdW1tYXJ5PgogICAgICAgIC8vLyBWbWwgZHJhd2luZ3MuIHVuZGVybGF5aW5nIG9iamVjdCBmb3IgY29tbWVudHMKICAgICAgICAvLy8gPC9zdW1tYXJ5PgogICAgICAgIGludGVybmFsIEV4Y2VsVm1sRHJhd2luZ0NvbW1lbnRDb2xsZWN0aW9uIFZtbERyYXdpbmdzQ29tbWVudHMKICAgICAgICB7CiAgICAgICAgICAgIGdldAogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBpZiAoX3ZtbERyYXdpbmdzID09IG51bGwpCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgQ3JlYXRlVm1sQ29sbGVjdGlvbigpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgcmV0dXJuIF92bWxEcmF3aW5nczsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgICAgICBpbnRlcm5hbCBFeGNlbENvbW1lbnRDb2xsZWN0aW9uIF9jb21tZW50cyA9IG51bGw7CiAgICAgICAgLy8vIDxzdW1tYXJ5PgogICAgICAgIC8vLyBDb2xsZWN0aW9uIG9mIGNvbW1lbnRzCiAgICAgICAgLy8vIDwvc3VtbWFyeT4KICAgICAgICBwdWJsaWMgRXhjZWxDb21tZW50Q29sbGVjdGlvbiBDb21tZW50cwogICAgICAgIHsKICAgICAgICAgICAgZ2V0CiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIENoZWNrU2hlZXRUeXBlKCk7CiAgICAgICAgICAgICAgICBpZiAoX2NvbW1lbnRzID09IG51bGwpCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgQ3JlYXRlVm1sQ29sbGVjdGlvbigpOwogICAgICAgICAgICAgICAgICAgIF9jb21tZW50cyA9IG5ldyBFeGNlbENvbW1lbnRDb2xsZWN0aW9uKF9wYWNrYWdlLCB0aGlzLCBOYW1lU3BhY2VNYW5hZ2VyKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIHJldHVybiBfY29tbWVudHM7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgcHJpdmF0ZSB2b2lkIENyZWF0ZVZtbENvbGxlY3Rpb24oKQogICAgICAgIHsKICAgICAgICAgICAgdmFyIHZtbE5vZGUgPSBfd29ya3NoZWV0WG1sLkRvY3VtZW50RWxlbWVudC5TZWxlY3RTaW5nbGVOb2RlKCJkOmxlZ2FjeURyYXdpbmcvQHI6aWQiLCBOYW1lU3BhY2VNYW5hZ2VyKTsKICAgICAgICAgICAgaWYgKHZtbE5vZGUgPT0gbnVsbCkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgX3ZtbERyYXdpbmdzID0gbmV3IEV4Y2VsVm1sRHJhd2luZ0NvbW1lbnRDb2xsZWN0aW9uKF9wYWNrYWdlLCB0aGlzLCBudWxsKTsKICAgICAgICAgICAgfQogICAgICAgICAgICBlbHNlCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIGlmIChQYXJ0LlJlbGF0aW9uc2hpcEV4aXN0cyh2bWxOb2RlLlZhbHVlKSkKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICB2YXIgcmVsID0gUGFydC5HZXRSZWxhdGlvbnNoaXAodm1sTm9kZS5WYWx1ZSk7CiAgICAgICAgICAgICAgICAgICAgdmFyIHZtbFVyaSA9IFVyaUhlbHBlci5SZXNvbHZlUGFydFVyaShyZWwuU291cmNlVXJpLCByZWwuVGFyZ2V0VXJpKTsKCiAgICAgICAgICAgICAgICAgICAgX3ZtbERyYXdpbmdzID0gbmV3IEV4Y2VsVm1sRHJhd2luZ0NvbW1lbnRDb2xsZWN0aW9uKF9wYWNrYWdlLCB0aGlzLCB2bWxVcmkpOwogICAgICAgICAgICAgICAgICAgIF92bWxEcmF3aW5ncy5SZWxJZCA9IHJlbC5JZDsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgcHJpdmF0ZSB2b2lkIENyZWF0ZVhtbCgpCiAgICAgICAgewogICAgICAgICAgICBfd29ya3NoZWV0WG1sID0gbmV3IFhtbERvY3VtZW50KCk7CiAgICAgICAgICAgIF93b3Jrc2hlZXRYbWwuUHJlc2VydmVXaGl0ZXNwYWNlID0gRXhjZWxQYWNrYWdlLnByZXNlcnZlV2hpdGVzcGFjZTsKICAgICAgICAgICAgUGFja2FnaW5nLlppcFBhY2thZ2VQYXJ0IHBhY2tQYXJ0ID0gX3BhY2thZ2UuUGFja2FnZS5HZXRQYXJ0KFdvcmtzaGVldFVyaSk7CiAgICAgICAgICAgIHN0cmluZyB4bWwgPSAiIjsKCiAgICAgICAgICAgIC8vIEZpcnN0IENvbHVtbnMsIHJvd3MsIGNlbGxzLCBtZXJnZWNlbGxzLCBoeXBlcmxpbmtzIGFuZCBwYWdlYnJlYWtlcyBhcmUgbG9hZGVkIGZyb20gYSB4bWxzdHJlYW0gdG8gb3B0aW1pemUgc3BlZWQuLi4KICAgICAgICAgICAgYm9vbCBkb0FkanVzdCA9IF9wYWNrYWdlLkRvQWRqdXN0RHJhd2luZ3M7CiAgICAgICAgICAgIF9wYWNrYWdlLkRvQWRqdXN0RHJhd2luZ3MgPSBmYWxzZTsKICAgICAgICAgICAgU3RyZWFtIHN0cmVhbSA9IHBhY2tQYXJ0LkdldFN0cmVhbSgpOwoKICAgICAgICAgICAgWG1sVGV4dFJlYWRlciB4ciA9IG5ldyBYbWxUZXh0UmVhZGVyKHN0cmVhbSk7CiAgICAgICAgICAgIHhyLlByb2hpYml0RHRkID0gdHJ1ZTsKICAgICAgICAgICAgeHIuV2hpdGVzcGFjZUhhbmRsaW5nID0gV2hpdGVzcGFjZUhhbmRsaW5nLk5vbmU7CiAgICAgICAgICAgIExvYWRDb2x1bW5zKHhyKTsgICAgLy9jb2x1bW5YbWwKICAgICAgICAgICAgbG9uZyBzdGFydCA9IHN0cmVhbS5Qb3NpdGlvbjsKICAgICAgICAgICAgTG9hZENlbGxzKHhyKTsKICAgICAgICAgICAgdmFyIG5leHRFbGVtZW50TGVuZ3RoID0gR2V0QXR0cmlidXRlTGVuZ3RoKHhyKTsKICAgICAgICAgICAgbG9uZyBlbmQgPSBzdHJlYW0uUG9zaXRpb24gLSBuZXh0RWxlbWVudExlbmd0aDsKICAgICAgICAgICAgTG9hZE1lcmdlQ2VsbHMoeHIpOwogICAgICAgICAgICBMb2FkSHlwZXJMaW5rcyh4cik7CiAgICAgICAgICAgIExvYWRSb3dQYWdlQnJlYWtlcyh4cik7CiAgICAgICAgICAgIExvYWRDb2xQYWdlQnJlYWtlcyh4cik7CiAgICAgICAgICAgIC8vLi4udGhlbiB0aGUgcmVzdCBvZiB0aGUgWG1sIGlzIGV4dHJhY3RlZCBhbmQgbG9hZGVkIGludG8gdGhlIFdvcmtzaGVldFhtbCBkb2N1bWVudC4KICAgICAgICAgICAgc3RyZWFtLlNlZWsoMCwgU2Vla09yaWdpbi5CZWdpbik7CiAgICAgICAgICAgIEVuY29kaW5nIGVuY29kaW5nOwogICAgICAgICAgICB4bWwgPSBHZXRXb3JrU2hlZXRYbWwoc3RyZWFtLCBzdGFydCwgZW5kLCBvdXQgZW5jb2RpbmcpOwoKICAgICAgICAgICAgLy9maXJzdCBjaGFyIGlzIGludmFsaWQgc29tZXRpbWVzPz8gCiAgICAgICAgICAgIGlmICh4bWxbMF0gIT0gJzwnKQogICAgICAgICAgICAgICAgTG9hZFhtbFNhZmUoX3dvcmtzaGVldFhtbCwgeG1sLlN1YnN0cmluZygxLCB4bWwuTGVuZ3RoIC0gMSksIGVuY29kaW5nKTsKICAgICAgICAgICAgZWxzZQogICAgICAgICAgICAgICAgTG9hZFhtbFNhZmUoX3dvcmtzaGVldFhtbCwgeG1sLCBlbmNvZGluZyk7CgogICAgICAgICAgICBfcGFja2FnZS5Eb0FkanVzdERyYXdpbmdzID0gZG9BZGp1c3Q7CiAgICAgICAgICAgIENsZWFyTm9kZXMoKTsKICAgICAgICB9CiAgICAgICAgLy8vIDxzdW1tYXJ5PgogICAgICAgIC8vLyBHZXQgdGhlIGxlbnRoIG9mIHRoZSBhdHRyaWJ1dGVzCiAgICAgICAgLy8vIENvbmRpdGlvbmFsIGZvcm1hdHRpbmcgYXR0cmlidXRlcyBjYW4gYmUgZXh0cmVtbHkgbG9uZyBzb20gZ2V0IGxlbmd0aCBvZiB0aGUgYXR0cmlidXRlcyB0byBmaW5ldHVuZSBwb3NpdGlvbi4KICAgICAgICAvLy8gPC9zdW1tYXJ5PgogICAgICAgIC8vLyA8cGFyYW0gbmFtZT0ieHIiPjwvcGFyYW0+CiAgICAgICAgLy8vIDxyZXR1cm5zPjwvcmV0dXJucz4KICAgICAgICBwcml2YXRlIGludCBHZXRBdHRyaWJ1dGVMZW5ndGgoWG1sVGV4dFJlYWRlciB4cikKICAgICAgICB7CiAgICAgICAgICAgIGlmICh4ci5Ob2RlVHlwZSAhPSBYbWxOb2RlVHlwZS5FbGVtZW50KSByZXR1cm4gMDsKICAgICAgICAgICAgdmFyIGxlbmd0aCA9IDA7CiAgICAgICAgICAgIAogICAgICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IHhyLkF0dHJpYnV0ZUNvdW50OyBpKyspCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIHZhciBhPXhyLkdldEF0dHJpYnV0ZShpKTsKICAgICAgICAgICAgICAgIGxlbmd0aCArPSBzdHJpbmcuSXNOdWxsT3JFbXB0eShhKSA/IDAgOiBhLkxlbmd0aDsKICAgICAgICAgICAgfQogICAgICAgICAgICByZXR1cm4gbGVuZ3RoOwogICAgICAgIH0KICAgICAgICBwcml2YXRlIHZvaWQgTG9hZFJvd1BhZ2VCcmVha2VzKFhtbFRleHRSZWFkZXIgeHIpCiAgICAgICAgewogICAgICAgICAgICBpZighUmVhZFVudGlsKHhyLCAicm93QnJlYWtzIiwiY29sQnJlYWtzIikpIHJldHVybjsKICAgICAgICAgICAgd2hpbGUgKHhyLlJlYWQoKSkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgaWYgKHhyLkxvY2FsTmFtZSA9PSAiYnJrIikKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICBpZiAoeHIuTm9kZVR5cGUgPT0gWG1sTm9kZVR5cGUuRWxlbWVudCkKICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgIGludCBpZDsKICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGludC5UcnlQYXJzZSh4ci5HZXRBdHRyaWJ1dGUoImlkIiksIG91dCBpZCkpCiAgICAgICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIFJvdyhpZCkuUGFnZUJyZWFrID0gdHJ1ZTsKICAgICAgICAgICAgICAgICAgICAgICAgfSAgIAogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGVsc2UKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgIH0KICAgICAgICBwcml2YXRlIHZvaWQgTG9hZENvbFBhZ2VCcmVha2VzKFhtbFRleHRSZWFkZXIgeHIpCiAgICAgICAgewogICAgICAgICAgICBpZiAoIVJlYWRVbnRpbCh4ciwgImNvbEJyZWFrcyIpKSByZXR1cm47CiAgICAgICAgICAgIHdoaWxlICh4ci5SZWFkKCkpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIGlmICh4ci5Mb2NhbE5hbWUgPT0gImJyayIpCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgaWYgKHhyLk5vZGVUeXBlID09IFhtbE5vZGVUeXBlLkVsZW1lbnQpCiAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICBpbnQgaWQ7CiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChpbnQuVHJ5UGFyc2UoeHIuR2V0QXR0cmlidXRlKCJpZCIpLCBvdXQgaWQpKQogICAgICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBDb2x1bW4oaWQpLlBhZ2VCcmVhayA9IHRydWU7CiAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBlbHNlCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIHByaXZhdGUgdm9pZCBDbGVhck5vZGVzKCkKICAgICAgICB7CiAgICAgICAgICAgIGlmIChfd29ya3NoZWV0WG1sLlNlbGVjdFNpbmdsZU5vZGUoIi8vZDpjb2xzIiwgTmFtZVNwYWNlTWFuYWdlcikhPW51bGwpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIF93b3Jrc2hlZXRYbWwuU2VsZWN0U2luZ2xlTm9kZSgiLy9kOmNvbHMiLCBOYW1lU3BhY2VNYW5hZ2VyKS5SZW1vdmVBbGwoKTsKICAgICAgICAgICAgfQogICAgICAgICAgICBpZiAoX3dvcmtzaGVldFhtbC5TZWxlY3RTaW5nbGVOb2RlKCIvL2Q6bWVyZ2VDZWxscyIsIE5hbWVTcGFjZU1hbmFnZXIpICE9IG51bGwpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIF93b3Jrc2hlZXRYbWwuU2VsZWN0U2luZ2xlTm9kZSgiLy9kOm1lcmdlQ2VsbHMiLCBOYW1lU3BhY2VNYW5hZ2VyKS5SZW1vdmVBbGwoKTsKICAgICAgICAgICAgfQogICAgICAgICAgICBpZiAoX3dvcmtzaGVldFhtbC5TZWxlY3RTaW5nbGVOb2RlKCIvL2Q6aHlwZXJsaW5rcyIsIE5hbWVTcGFjZU1hbmFnZXIpICE9IG51bGwpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIF93b3Jrc2hlZXRYbWwuU2VsZWN0U2luZ2xlTm9kZSgiLy9kOmh5cGVybGlua3MiLCBOYW1lU3BhY2VNYW5hZ2VyKS5SZW1vdmVBbGwoKTsKICAgICAgICAgICAgfQogICAgICAgICAgICBpZiAoX3dvcmtzaGVldFhtbC5TZWxlY3RTaW5nbGVOb2RlKCIvL2Q6cm93QnJlYWtzIiwgTmFtZVNwYWNlTWFuYWdlcikgIT0gbnVsbCkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgX3dvcmtzaGVldFhtbC5TZWxlY3RTaW5nbGVOb2RlKCIvL2Q6cm93QnJlYWtzIiwgTmFtZVNwYWNlTWFuYWdlcikuUmVtb3ZlQWxsKCk7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgaWYgKF93b3Jrc2hlZXRYbWwuU2VsZWN0U2luZ2xlTm9kZSgiLy9kOmNvbEJyZWFrcyIsIE5hbWVTcGFjZU1hbmFnZXIpICE9IG51bGwpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIF93b3Jrc2hlZXRYbWwuU2VsZWN0U2luZ2xlTm9kZSgiLy9kOmNvbEJyZWFrcyIsIE5hbWVTcGFjZU1hbmFnZXIpLlJlbW92ZUFsbCgpOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIGNvbnN0IGludCBCTE9DS1NJWkU9ODE5MjsKICAgICAgICBwcml2YXRlIHN0cmluZyBHZXRXb3JrU2hlZXRYbWwoU3RyZWFtIHN0cmVhbSwgbG9uZyBzdGFydCwgbG9uZyBlbmQsIG91dCBFbmNvZGluZyBlbmNvZGluZykKICAgICAgICB7CiAgICAgICAgICAgIFN0cmVhbVJlYWRlciBzciA9IG5ldyBTdHJlYW1SZWFkZXIoc3RyZWFtKTsKICAgICAgICAgICAgaW50IGxlbmd0aCA9IDA7CiAgICAgICAgICAgIGNoYXJbXSBibG9jazsKICAgICAgICAgICAgaW50IHBvczsKICAgICAgICAgICAgU3RyaW5nQnVpbGRlciBzYiA9IG5ldyBTdHJpbmdCdWlsZGVyKCk7ICAgICAgICAgICAgCiAgICAgICAgICAgIE1hdGNoIHN0YXJ0bU1hdGNoLCBlbmRNYXRjaDsKICAgICAgICAgICAgZG8KICAgICAgICAgICAgewogICAgICAgICAgICAgICAgaW50IHNpemUgPSBzdHJlYW0uTGVuZ3RoIDwgQkxPQ0tTSVpFID8gKGludClzdHJlYW0uTGVuZ3RoIDogQkxPQ0tTSVpFOwogICAgICAgICAgICAgICAgYmxvY2sgPSBuZXcgY2hhcltzaXplXTsKICAgICAgICAgICAgICAgIHBvcyA9IHNyLlJlYWRCbG9jayhibG9jaywgMCwgc2l6ZSk7ICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICBzYi5BcHBlbmQoYmxvY2ssMCxwb3MpOwogICAgICAgICAgICAgICAgbGVuZ3RoICs9IHNpemU7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgd2hpbGUgKGxlbmd0aCA8IHN0YXJ0ICsgMjAgJiYgbGVuZ3RoIDwgZW5kKTsKICAgICAgICAgICAgc3RhcnRtTWF0Y2ggPSBSZWdleC5NYXRjaChzYi5Ub1N0cmluZygpLCBzdHJpbmcuRm9ybWF0KCIoPFtePl0qezB9W14+XSo+KSIsICJzaGVldERhdGEiKSk7CiAgICAgICAgICAgIGlmICghc3RhcnRtTWF0Y2guU3VjY2VzcykgLy9Ob3QgZm91bmQKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgZW5jb2RpbmcgPSBzci5DdXJyZW50RW5jb2Rpbmc7CiAgICAgICAgICAgICAgICByZXR1cm4gc2IuVG9TdHJpbmcoKTsKICAgICAgICAgICAgfQogICAgICAgICAgICBlbHNlCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIHN0cmluZyBzID0gc2IuVG9TdHJpbmcoKTsKICAgICAgICAgICAgICAgIHN0cmluZyB4bWwgPSBzLlN1YnN0cmluZygwLCBzdGFydG1NYXRjaC5JbmRleCk7IAogICAgICAgICAgICAgICAgaWYoc3RhcnRtTWF0Y2guVmFsdWUuRW5kc1dpdGgoIi8+IikpCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgeG1sICs9IHMuU3Vic3RyaW5nKHN0YXJ0bU1hdGNoLkluZGV4LCBzLkxlbmd0aCAtIHN0YXJ0bU1hdGNoLkluZGV4KTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGVsc2UKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICBpZiAoc3IuUGVlaygpICE9IC0xKQogICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgLyoqKiogRml4ZXMgaXNzdWUgMTQ3ODguIEZpeCBieSBQaGlsaXAgR2FycmV0dCAqKioqLwogICAgICAgICAgICAgICAgICAgICAgICBsb25nIGVuZFNlZWtTdGFydCA9IGVuZDsKCiAgICAgICAgICAgICAgICAgICAgICAgIHdoaWxlIChlbmRTZWVrU3RhcnQgPj0gMCkKICAgICAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgZW5kU2Vla1N0YXJ0ID0gTWF0aC5NYXgoZW5kU2Vla1N0YXJ0IC0gQkxPQ0tTSVpFLCAwKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGludCBzaXplID0gKGludCkoZW5kIC0gZW5kU2Vla1N0YXJ0KTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN0cmVhbS5TZWVrKGVuZFNlZWtTdGFydCwgU2Vla09yaWdpbi5CZWdpbik7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBibG9jayA9IG5ldyBjaGFyW3NpemVdOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgc3IgPSBuZXcgU3RyZWFtUmVhZGVyKHN0cmVhbSk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBwb3MgPSBzci5SZWFkQmxvY2soYmxvY2ssIDAsIHNpemUpOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgc2IgPSBuZXcgU3RyaW5nQnVpbGRlcigpOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgc2IuQXBwZW5kKGJsb2NrLCAwLCBwb3MpOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgcyA9IHNiLlRvU3RyaW5nKCk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBlbmRNYXRjaCA9IFJlZ2V4Lk1hdGNoKHMsIHN0cmluZy5Gb3JtYXQoIig8L1tePl0qezB9W14+XSo+KSIsICJzaGVldERhdGEiKSk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoZW5kTWF0Y2guU3VjY2VzcykKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICBlbmRNYXRjaCA9IFJlZ2V4Lk1hdGNoKHMsIHN0cmluZy5Gb3JtYXQoIig8L1tePl0qezB9W14+XSo+KSIsICJzaGVldERhdGEiKSk7CiAgICAgICAgICAgICAgICAgICAgeG1sICs9ICI8c2hlZXREYXRhLz4iICsgcy5TdWJzdHJpbmcoZW5kTWF0Y2guSW5kZXggKyBlbmRNYXRjaC5MZW5ndGgsIHMuTGVuZ3RoIC0gKGVuZE1hdGNoLkluZGV4ICsgZW5kTWF0Y2guTGVuZ3RoKSk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBpZiAoc3IuUGVlaygpID4gLTEpCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgeG1sICs9IHNyLlJlYWRUb0VuZCgpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICBlbmNvZGluZyA9IHNyLkN1cnJlbnRFbmNvZGluZzsKICAgICAgICAgICAgICAgIHJldHVybiB4bWw7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgcHJpdmF0ZSB2b2lkIEdldEJsb2NrUG9zKHN0cmluZyB4bWwsIHN0cmluZyB0YWcsIHJlZiBpbnQgc3RhcnQsIHJlZiBpbnQgZW5kKQogICAgICAgIHsKICAgICAgICAgICAgTWF0Y2ggc3RhcnRtTWF0Y2gsIGVuZE1hdGNoOwogICAgICAgICAgICBzdGFydG1NYXRjaCA9IFJlZ2V4Lk1hdGNoKHhtbC5TdWJzdHJpbmcoc3RhcnQpLCBzdHJpbmcuRm9ybWF0KCIoPFtePl0qezB9W14+XSo+KSIsIHRhZykpOyAvLyI8W2EtekEtWjpdKiIgKyB0YWcgKyAiWz9dKj4iKTsKCiAgICAgICAgICAgIGlmICghc3RhcnRtTWF0Y2guU3VjY2VzcykgLy9Ob3QgZm91bmQKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgc3RhcnQgPSAtMTsKICAgICAgICAgICAgICAgIGVuZCA9IC0xOwogICAgICAgICAgICAgICAgcmV0dXJuOwogICAgICAgICAgICB9CiAgICAgICAgICAgIHZhciBzdGFydFBvcz1zdGFydG1NYXRjaC5JbmRleCtzdGFydDsKICAgICAgICAgICAgaWYoc3RhcnRtTWF0Y2guVmFsdWUuU3Vic3RyaW5nKHN0YXJ0bU1hdGNoLlZhbHVlLkxlbmd0aC0yLDEpPT0iLyIpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIGVuZCA9IHN0YXJ0UG9zICsgc3RhcnRtTWF0Y2guTGVuZ3RoOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGVsc2UKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgZW5kTWF0Y2ggPSBSZWdleC5NYXRjaCh4bWwuU3Vic3RyaW5nKHN0YXJ0KSwgc3RyaW5nLkZvcm1hdCgiKDwvW14+XSp7MH1bXj5dKj4pIiwgdGFnKSk7CiAgICAgICAgICAgICAgICBpZiAoZW5kTWF0Y2guU3VjY2VzcykKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICBlbmQgPSBlbmRNYXRjaC5JbmRleCArIGVuZE1hdGNoLkxlbmd0aCArIHN0YXJ0OwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgICAgIHN0YXJ0ID0gc3RhcnRQb3M7CiAgICAgICAgfQogICAgICAgIHByaXZhdGUgYm9vbCBSZWFkVW50aWwoWG1sVGV4dFJlYWRlciB4cixwYXJhbXMgc3RyaW5nW10gdGFnTmFtZSkKICAgICAgICB7CiAgICAgICAgICAgIGlmICh4ci5FT0YpIHJldHVybiBmYWxzZTsKICAgICAgICAgICAgd2hpbGUgKCFBcnJheS5FeGlzdHModGFnTmFtZSwgdGFnID0+IHhyLkxvY2FsTmFtZS5FbmRzV2l0aCh0YWcpKSkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgeHIuUmVhZCgpOwogICAgICAgICAgICAgICAgaWYgKHhyLkVPRikgcmV0dXJuIGZhbHNlOwogICAgICAgICAgICB9CiAgICAgICAgICAgIHJldHVybiAoeHIuTG9jYWxOYW1lLkVuZHNXaXRoKHRhZ05hbWVbMF0pKTsKICAgICAgICB9CiAgICAgICAgcHJpdmF0ZSB2b2lkIExvYWRDb2x1bW5zIChYbWxUZXh0UmVhZGVyIHhyKS8vKHN0cmluZyB4bWwpCiAgICAgICAgewogICAgICAgICAgICB2YXIgY29sTGlzdCA9IG5ldyBMaXN0PElSYW5nZUlEPigpOwogICAgICAgICAgICBpZiAoUmVhZFVudGlsKHhyLCAiY29scyIsICJzaGVldERhdGEiKSkKICAgICAgICAgICAgewogICAgICAgICAgICAvL2lmICh4bWwgIT0gIiIpCiAgICAgICAgICAgIC8vewogICAgICAgICAgICAgICAgLy92YXIgeHI9bmV3IFhtbFRleHRSZWFkZXIobmV3IFN0cmluZ1JlYWRlcih4bWwpKTsKICAgICAgICAgICAgICAgIHdoaWxlKHhyLlJlYWQoKSkKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICBpZiAoeHIuTm9kZVR5cGUgPT0gWG1sTm9kZVR5cGUuV2hpdGVzcGFjZSkgY29udGludWU7CiAgICAgICAgICAgICAgICAgICAgaWYgKHhyLkxvY2FsTmFtZSAhPSAiY29sIikgYnJlYWs7CiAgICAgICAgICAgICAgICAgICAgaWYgKHhyLk5vZGVUeXBlID09IFhtbE5vZGVUeXBlLkVsZW1lbnQpCiAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICBpbnQgbWluID0gaW50LlBhcnNlKHhyLkdldEF0dHJpYnV0ZSgibWluIikpOwoKICAgICAgICAgICAgICAgICAgICAgICAgRXhjZWxDb2x1bW4gY29sID0gbmV3IEV4Y2VsQ29sdW1uKHRoaXMsIG1pbik7CgogICAgICAgICAgICAgICAgICAgICAgICBjb2wuQ29sdW1uTWF4ID0gaW50LlBhcnNlKHhyLkdldEF0dHJpYnV0ZSgibWF4IikpOwogICAgICAgICAgICAgICAgICAgICAgICBjb2wuV2lkdGggPSB4ci5HZXRBdHRyaWJ1dGUoIndpZHRoIikgPT0gbnVsbCA/IDAgOiBkb3VibGUuUGFyc2UoeHIuR2V0QXR0cmlidXRlKCJ3aWR0aCIpLCBDdWx0dXJlSW5mby5JbnZhcmlhbnRDdWx0dXJlKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbC5CZXN0Rml0ID0geHIuR2V0QXR0cmlidXRlKCJiZXN0Rml0IikgIT0gbnVsbCAmJiB4ci5HZXRBdHRyaWJ1dGUoImJlc3RGaXQiKSA9PSAiMSIgPyB0cnVlIDogZmFsc2U7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb2wuQ29sbGFwc2VkID0geHIuR2V0QXR0cmlidXRlKCJjb2xsYXBzZWQiKSAhPSBudWxsICYmIHhyLkdldEF0dHJpYnV0ZSgiY29sbGFwc2VkIikgPT0gIjEiID8gdHJ1ZSA6IGZhbHNlOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgY29sLlBob25ldGljID0geHIuR2V0QXR0cmlidXRlKCJwaG9uZXRpYyIpICE9IG51bGwgJiYgeHIuR2V0QXR0cmlidXRlKCJwaG9uZXRpYyIpID09ICIxIiA/IHRydWUgOiBmYWxzZTsKICAgICAgICAgICAgICAgICAgICAgICAgY29sLk91dGxpbmVMZXZlbCA9IChzaG9ydCkoeHIuR2V0QXR0cmlidXRlKCJvdXRsaW5lTGV2ZWwiKSA9PSBudWxsID8gMCA6IGludC5QYXJzZSh4ci5HZXRBdHRyaWJ1dGUoIm91dGxpbmVMZXZlbCIpLCBDdWx0dXJlSW5mby5JbnZhcmlhbnRDdWx0dXJlKSk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb2wuSGlkZGVuID0geHIuR2V0QXR0cmlidXRlKCJoaWRkZW4iKSAhPSBudWxsICYmIHhyLkdldEF0dHJpYnV0ZSgiaGlkZGVuIikgPT0gIjEiID8gdHJ1ZSA6IGZhbHNlOwogICAgICAgICAgICAgICAgICAgICAgICBfdmFsdWVzLlNldFZhbHVlKDAsIG1pbiwgY29sKTsKICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgaW50IHN0eWxlOwogICAgICAgICAgICAgICAgICAgICAgICBpZiAoISh4ci5HZXRBdHRyaWJ1dGUoInN0eWxlIikgPT0gbnVsbCB8fCAhaW50LlRyeVBhcnNlKHhyLkdldEF0dHJpYnV0ZSgic3R5bGUiKSwgb3V0IHN0eWxlKSkpCiAgICAgICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIF9zdHlsZXMuU2V0VmFsdWUoMCwgbWluLCBzdHlsZSk7CiAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgLy8vIDxzdW1tYXJ5PgogICAgICAgIC8vLyBSZWFkIHVudGlsIHRoZSBub2RlIGlzIGZvdW5kLiBJZiBub3QgZm91bmQgdGhlIHhtbHJlYWRlciBpcyByZXNldGVkLgogICAgICAgIC8vLyA8L3N1bW1hcnk+CiAgICAgICAgLy8vIDxwYXJhbSBuYW1lPSJ4ciI+VGhlIHJlYWRlcjwvcGFyYW0+CiAgICAgICAgLy8vIDxwYXJhbSBuYW1lPSJub2RlVGV4dCI+VGV4dCB0byBzZWFyY2ggZm9yPC9wYXJhbT4KICAgICAgICAvLy8gPHBhcmFtIG5hbWU9ImFsdE5vZGUiPkFsdGVybmF0aXZlIHRleHQgdG8gc2VhcmNoIGZvcjwvcGFyYW0+CiAgICAgICAgLy8vIDxyZXR1cm5zPjwvcmV0dXJucz4KICAgICAgICBwcml2YXRlIHN0YXRpYyBib29sIFJlYWRYbWxSZWFkZXJVbnRpbChYbWxUZXh0UmVhZGVyIHhyLCBzdHJpbmcgbm9kZVRleHQsIHN0cmluZyBhbHROb2RlKQogICAgICAgIHsKICAgICAgICAgICAgZG8KICAgICAgICAgICAgewogICAgICAgICAgICAgICAgaWYgKHhyLkxvY2FsTmFtZSA9PSBub2RlVGV4dCB8fCB4ci5Mb2NhbE5hbWUgPT0gYWx0Tm9kZSkgcmV0dXJuIHRydWU7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgd2hpbGUoeHIuUmVhZCgpKTsKICAgICAgICAgICAgeHIuQ2xvc2UoKTsKICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgICAgIH0KICAgICAgICAvLy8gPHN1bW1hcnk+CiAgICAgICAgLy8vIExvYWQgSHlwZXJsaW5rcwogICAgICAgIC8vLyA8L3N1bW1hcnk+CiAgICAgICAgLy8vIDxwYXJhbSBuYW1lPSJ4ciI+VGhlIHJlYWRlcjwvcGFyYW0+CiAgICAgICAgcHJpdmF0ZSB2b2lkIExvYWRIeXBlckxpbmtzKFhtbFRleHRSZWFkZXIgeHIpCiAgICAgICAgewogICAgICAgICAgICBpZiAoIVJlYWRVbnRpbCh4ciwgImh5cGVybGlua3MiLCAicm93QnJlYWtzIiwgImNvbEJyZWFrcyIpKSByZXR1cm47CiAgICAgICAgICAgIHdoaWxlICh4ci5SZWFkKCkpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIGlmICh4ci5Mb2NhbE5hbWUgPT0gImh5cGVybGluayIpCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgaW50IGZyb21Sb3csIGZyb21Db2wsIHRvUm93LCB0b0NvbDsKICAgICAgICAgICAgICAgICAgICBFeGNlbENlbGxCYXNlLkdldFJvd0NvbEZyb21BZGRyZXNzKHhyLkdldEF0dHJpYnV0ZSgicmVmIiksIG91dCBmcm9tUm93LCBvdXQgZnJvbUNvbCwgb3V0IHRvUm93LCBvdXQgdG9Db2wpOwogICAgICAgICAgICAgICAgICAgIEV4Y2VsSHlwZXJMaW5rIGhsID0gbnVsbDsKICAgICAgICAgICAgICAgICAgICBpZiAoeHIuR2V0QXR0cmlidXRlKCJpZCIsIEV4Y2VsUGFja2FnZS5zY2hlbWFSZWxhdGlvbnNoaXBzKSAhPSBudWxsKQogICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgdmFyIHJJZCA9IHhyLkdldEF0dHJpYnV0ZSgiaWQiLCBFeGNlbFBhY2thZ2Uuc2NoZW1hUmVsYXRpb25zaGlwcyk7CiAgICAgICAgICAgICAgICAgICAgICAgIHZhciB1cmkgPSBQYXJ0LkdldFJlbGF0aW9uc2hpcChySWQpLlRhcmdldFVyaTsKICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHVyaS5Jc0Fic29sdXRlVXJpKQogICAgICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0cnkKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBobCA9IG5ldyBFeGNlbEh5cGVyTGluayh1cmkuQWJzb2x1dGVVcmkpOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICAgICAgICAgY2F0Y2gKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBobCA9IG5ldyBFeGNlbEh5cGVyTGluayh1cmkuT3JpZ2luYWxTdHJpbmcsIFVyaUtpbmQuQWJzb2x1dGUpOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgICAgIGVsc2UKICAgICAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgaGwgPSBuZXcgRXhjZWxIeXBlckxpbmsodXJpLk9yaWdpbmFsU3RyaW5nLCBVcmlLaW5kLlJlbGF0aXZlKTsKICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICAgICBobC5SSWQgPSBySWQ7CiAgICAgICAgICAgICAgICAgICAgICAgIFBhcnQuRGVsZXRlUmVsYXRpb25zaGlwKHJJZCk7IC8vRGVsZXRlIHRoZSByZWxhdGlvbnNoaXAsIGl0IGlzIHJlY3JlYXRlZCB3aGVuIHdlIHNhdmUgdGhlIHBhY2thZ2UuCiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIGVsc2UgaWYgKHhyLkdldEF0dHJpYnV0ZSgibG9jYXRpb24iKSAhPSBudWxsKQogICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgaGwgPSBuZXcgRXhjZWxIeXBlckxpbmsoeHIuR2V0QXR0cmlidXRlKCJsb2NhdGlvbiIpLCB4ci5HZXRBdHRyaWJ1dGUoImRpc3BsYXkiKSk7CiAgICAgICAgICAgICAgICAgICAgICAgIGhsLlJvd1NwYW5uID0gdG9Sb3cgLSBmcm9tUm93OwogICAgICAgICAgICAgICAgICAgICAgICBobC5Db2xTcGFubiA9IHRvQ29sIC0gZnJvbUNvbDsKICAgICAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgICAgIHN0cmluZyB0dCA9IHhyLkdldEF0dHJpYnV0ZSgidG9vbHRpcCIpOwogICAgICAgICAgICAgICAgICAgIGlmICghc3RyaW5nLklzTnVsbE9yRW1wdHkodHQpKQogICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgaGwuVG9vbFRpcCA9IHR0OwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICBfaHlwZXJMaW5rcy5TZXRWYWx1ZShmcm9tUm93LCBmcm9tQ29sLCBobCk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBlbHNlCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgLy8vIDxzdW1tYXJ5PgogICAgICAgIC8vLyBMb2FkIGNlbGxzCiAgICAgICAgLy8vIDwvc3VtbWFyeT4KICAgICAgICAvLy8gPHBhcmFtIG5hbWU9InhyIj5UaGUgcmVhZGVyPC9wYXJhbT4KICAgICAgICBwcml2YXRlIHZvaWQgTG9hZENlbGxzKFhtbFRleHRSZWFkZXIgeHIpCiAgICAgICAgewogICAgICAgICAgICAvL3ZhciBjZWxsTGlzdD1uZXcgTGlzdDxJUmFuZ2VJRD4oKTsKICAgICAgICAgICAgLy92YXIgcm93TGlzdCA9IG5ldyBMaXN0PElSYW5nZUlEPigpOwogICAgICAgICAgICAvL3ZhciBmb3JtdWxhTGlzdCA9IG5ldyBMaXN0PElSYW5nZUlEPigpOwogICAgICAgICAgICBSZWFkVW50aWwoeHIsICJzaGVldERhdGEiLCAibWVyZ2VDZWxscyIsICJoeXBlcmxpbmtzIiwgInJvd0JyZWFrcyIsICJjb2xCcmVha3MiKTsKICAgICAgICAgICAgRXhjZWxBZGRyZXNzQmFzZSBhZGRyZXNzPW51bGw7CiAgICAgICAgICAgIHN0cmluZyB0eXBlPSIiOwogICAgICAgICAgICBpbnQgc3R5bGU9MDsKICAgICAgICAgICAgaW50IHJvdyA9IDA7CiAgICAgICAgICAgIGludCBjb2wgPSAwOwogICAgICAgICAgICB4ci5SZWFkKCk7CiAgICAgICAgICAgIAogICAgICAgICAgICB3aGlsZSAoIXhyLkVPRikKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgd2hpbGUgKHhyLk5vZGVUeXBlID09IFhtbE5vZGVUeXBlLkVuZEVsZW1lbnQpCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgeHIuUmVhZCgpOwogICAgICAgICAgICAgICAgICAgIGNvbnRpbnVlOwogICAgICAgICAgICAgICAgfSAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgIGlmICh4ci5Mb2NhbE5hbWUgPT0gInJvdyIpCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgdmFyIHIgPSB4ci5HZXRBdHRyaWJ1dGUoInIiKTsKICAgICAgICAgICAgICAgICAgICBpZiAociA9PSBudWxsKQogICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgcm93Kys7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIGVsc2UKICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgIHJvdyA9IENvbnZlcnQuVG9JbnQzMihyKTsKICAgICAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgICAgIGlmIChEb0FkZFJvdyh4cikpCiAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICBfdmFsdWVzLlNldFZhbHVlKHJvdywgMCwgQWRkUm93KHhyLCByb3cpKTsKICAgICAgICAgICAgICAgICAgICAgICAgaWYoeHIuR2V0QXR0cmlidXRlKCJzIikgIT0gbnVsbCkKICAgICAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgX3N0eWxlcy5TZXRWYWx1ZShyb3csIDAsIGludC5QYXJzZSh4ci5HZXRBdHRyaWJ1dGUoInMiKSwgQ3VsdHVyZUluZm8uSW52YXJpYW50Q3VsdHVyZSkpOwogICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIHhyLlJlYWQoKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGVsc2UgaWYgKHhyLkxvY2FsTmFtZSA9PSAiYyIpCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgLy9pZiAoY2VsbCAhPSBudWxsKSBjZWxsTGlzdC5BZGQoY2VsbCk7CiAgICAgICAgICAgICAgICAgICAgLy9jZWxsID0gbmV3IEV4Y2VsQ2VsbCh0aGlzLCB4ci5HZXRBdHRyaWJ1dGUoInIiKSk7CiAgICAgICAgICAgICAgICAgICAgdmFyIHIgPSB4ci5HZXRBdHRyaWJ1dGUoInIiKTsKICAgICAgICAgICAgICAgICAgICBpZiAociA9PSBudWxsKQogICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgLy9IYW5kbGUgY2VsbHMgd2l0aCBubyByZWZlcmVuY2UKICAgICAgICAgICAgICAgICAgICAgICAgY29sKys7CiAgICAgICAgICAgICAgICAgICAgICAgIGFkZHJlc3MgPSBuZXcgRXhjZWxBZGRyZXNzQmFzZShyb3csIGNvbCwgcm93LCBjb2wpOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICBlbHNlCiAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICBhZGRyZXNzID0gbmV3IEV4Y2VsQWRkcmVzc0Jhc2Uocik7CiAgICAgICAgICAgICAgICAgICAgICAgIGNvbCA9IGFkZHJlc3MuX2Zyb21Db2w7CiAgICAgICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAvL0RhdGV0eXBlCiAgICAgICAgICAgICAgICAgICAgaWYgKHhyLkdldEF0dHJpYnV0ZSgidCIpICE9IG51bGwpCiAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICB0eXBlPXhyLkdldEF0dHJpYnV0ZSgidCIpOwogICAgICAgICAgICAgICAgICAgICAgICBfdHlwZXMuU2V0VmFsdWUoYWRkcmVzcy5fZnJvbVJvdywgYWRkcmVzcy5fZnJvbUNvbCwgdHlwZSk7IAogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICBlbHNlCiAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICB0eXBlPSIiOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAvL1N0eWxlCiAgICAgICAgICAgICAgICAgICAgaWYoeHIuR2V0QXR0cmlidXRlKCJzIikgIT0gbnVsbCkKICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgIHN0eWxlPWludC5QYXJzZSh4ci5HZXRBdHRyaWJ1dGUoInMiKSk7CiAgICAgICAgICAgICAgICAgICAgICAgIF9zdHlsZXMuU2V0VmFsdWUoYWRkcmVzcy5fZnJvbVJvdywgYWRkcmVzcy5fZnJvbUNvbCwgc3R5bGUpOwogICAgICAgICAgICAgICAgICAgICAgICBfdmFsdWVzLlNldFZhbHVlKGFkZHJlc3MuX2Zyb21Sb3csIGFkZHJlc3MuX2Zyb21Db2wsIG51bGwpOyAvL1RPRE86QmV0dGVyIFBlcmZvcm1hbmNlID8/CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIGVsc2UKICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgIHN0eWxlID0gMDsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgeHIuUmVhZCgpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgZWxzZSBpZiAoeHIuTG9jYWxOYW1lID09ICJ2IikKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICBTZXRWYWx1ZUZyb21YbWwoeHIsIHR5cGUsIHN0eWxlLCBhZGRyZXNzLl9mcm9tUm93LCBhZGRyZXNzLl9mcm9tQ29sKTsKICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICB4ci5SZWFkKCk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBlbHNlIGlmICh4ci5Mb2NhbE5hbWUgPT0gImYiKQogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIHN0cmluZyB0ID0geHIuR2V0QXR0cmlidXRlKCJ0Iik7CiAgICAgICAgICAgICAgICAgICAgaWYgKHQgPT0gbnVsbCkKICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgIF9mb3JtdWxhcy5TZXRWYWx1ZShhZGRyZXNzLl9mcm9tUm93LCBhZGRyZXNzLl9mcm9tQ29sLCB4ci5SZWFkRWxlbWVudENvbnRlbnRBc1N0cmluZygpKTsKICAgICAgICAgICAgICAgICAgICAgICAgX3ZhbHVlcy5TZXRWYWx1ZShhZGRyZXNzLl9mcm9tUm93LCBhZGRyZXNzLl9mcm9tQ29sLCBudWxsKTsKICAgICAgICAgICAgICAgICAgICAgICAgLy9mb3JtdWxhTGlzdC5BZGQoY2VsbCk7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIGVsc2UgaWYgKHQgPT0gInNoYXJlZCIpCiAgICAgICAgICAgICAgICAgICAgewoKICAgICAgICAgICAgICAgICAgICAgICAgc3RyaW5nIHNpID0geHIuR2V0QXR0cmlidXRlKCJzaSIpOwogICAgICAgICAgICAgICAgICAgICAgICBpZiAoc2kgIT0gbnVsbCkKICAgICAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgdmFyIHNmSW5kZXggPSBpbnQuUGFyc2Uoc2kpOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgX2Zvcm11bGFzLlNldFZhbHVlKGFkZHJlc3MuX2Zyb21Sb3csIGFkZHJlc3MuX2Zyb21Db2wsIHNmSW5kZXgpOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgX3ZhbHVlcy5TZXRWYWx1ZShhZGRyZXNzLl9mcm9tUm93LCBhZGRyZXNzLl9mcm9tQ29sLCBudWxsKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN0cmluZyBmQWRkcmVzcyA9IHhyLkdldEF0dHJpYnV0ZSgicmVmIik7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBzdHJpbmcgZm9ybXVsYSA9IENvbnZlcnRVdGlsLkV4Y2VsRGVjb2RlU3RyaW5nKHhyLlJlYWRFbGVtZW50Q29udGVudEFzU3RyaW5nKCkpOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGZvcm11bGEgIT0gIiIpCiAgICAgICAgICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgX3NoYXJlZEZvcm11bGFzLkFkZChzZkluZGV4LCBuZXcgRm9ybXVsYXMoU291cmNlQ29kZVRva2VuaXplci5EZWZhdWx0KSB7IEluZGV4ID0gc2ZJbmRleCwgRm9ybXVsYSA9IGZvcm11bGEsIEFkZHJlc3MgPSBmQWRkcmVzcywgU3RhcnRSb3cgPSBhZGRyZXNzLl9mcm9tUm93LCBTdGFydENvbCA9IGFkZHJlc3MuX2Zyb21Db2wgfSk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgZWxzZQogICAgICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICB4ci5SZWFkKCk7ICAvL1NvbWV0aGluZyBpcyB3cm9uZyBpbiB0aGUgc2hlZXQsIHJlYWQgbmV4dAogICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIGVsc2UgaWYgKHQgPT0gImFycmF5IikgLy9UT0RPOiBBcnJheSBmdW5jdGlvbnMgYXJlIG5vdCBzdXBwb3J0IHlldC4gUmVhZCB0aGUgZm9ybXVsYSBmb3IgdGhlIHN0YXJ0IGNlbGwgb25seS4KICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgIHN0cmluZyBhQWRkcmVzcyA9IHhyLkdldEF0dHJpYnV0ZSgicmVmIik7CiAgICAgICAgICAgICAgICAgICAgICAgIHN0cmluZyBmb3JtdWxhID0geHIuUmVhZEVsZW1lbnRDb250ZW50QXNTdHJpbmcoKTsKICAgICAgICAgICAgICAgICAgICAgICAgdmFyIGFmSW5kZXggPSBHZXRNYXhTaGFyZUZ1bmN0aW9uSW5kZXgodHJ1ZSk7CiAgICAgICAgICAgICAgICAgICAgICAgIF9mb3JtdWxhcy5TZXRWYWx1ZShhZGRyZXNzLl9mcm9tUm93LCBhZGRyZXNzLl9mcm9tQ29sLCBhZkluZGV4KTsKICAgICAgICAgICAgICAgICAgICAgICAgX3ZhbHVlcy5TZXRWYWx1ZShhZGRyZXNzLl9mcm9tUm93LCBhZGRyZXNzLl9mcm9tQ29sLCBudWxsKTsKICAgICAgICAgICAgICAgICAgICAgICAgX3NoYXJlZEZvcm11bGFzLkFkZChhZkluZGV4LCBuZXcgRm9ybXVsYXMoU291cmNlQ29kZVRva2VuaXplci5EZWZhdWx0KSB7IEluZGV4ID0gYWZJbmRleCwgRm9ybXVsYSA9IGZvcm11bGEsIEFkZHJlc3MgPSBhQWRkcmVzcywgU3RhcnRSb3cgPSBhZGRyZXNzLl9mcm9tUm93LCBTdGFydENvbCA9IGFkZHJlc3MuX2Zyb21Db2wsIElzQXJyYXkgPSB0cnVlIH0pOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICBlbHNlIC8vID8/PyBzb21lIG90aGVyIHR5cGUKICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgIHhyLlJlYWQoKTsgIC8vU29tZXRoaW5nIGlzIHdyb25nIGluIHRoZSBzaGVldCwgcmVhZCBuZXh0CiAgICAgICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGVsc2UgaWYgKHhyLkxvY2FsTmFtZSA9PSAiaXMiKSAgIC8vSW5saW5lIHN0cmluZwogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIHhyLlJlYWQoKTsKICAgICAgICAgICAgICAgICAgICBpZiAoeHIuTG9jYWxOYW1lID09ICJ0IikKICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgIF92YWx1ZXMuU2V0VmFsdWUoYWRkcmVzcy5fZnJvbVJvdywgYWRkcmVzcy5fZnJvbUNvbCwgQ29udmVydFV0aWwuRXhjZWxEZWNvZGVTdHJpbmcoeHIuUmVhZEVsZW1lbnRDb250ZW50QXNTdHJpbmcoKSkpOwogICAgICAgICAgICAgICAgICAgICAgICAvL2NlbGwuX3ZhbHVlID0geHIuUmVhZElubmVyWG1sKCk7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIGVsc2UKICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgIF92YWx1ZXMuU2V0VmFsdWUoYWRkcmVzcy5fZnJvbVJvdywgYWRkcmVzcy5fZnJvbUNvbCwgeHIuUmVhZE91dGVyWG1sKCkpOwogICAgICAgICAgICAgICAgICAgICAgICBfdHlwZXMuU2V0VmFsdWUoYWRkcmVzcy5fZnJvbVJvdywgYWRkcmVzcy5fZnJvbUNvbCwgInJ0Iik7CiAgICAgICAgICAgICAgICAgICAgICAgIF9mbGFncy5TZXRGbGFnVmFsdWUoYWRkcmVzcy5fZnJvbVJvdywgYWRkcmVzcy5fZnJvbUNvbCwgdHJ1ZSwgQ2VsbEZsYWdzLlJpY2hUZXh0KTsKICAgICAgICAgICAgICAgICAgICAgICAgLy9jZWxsLklzUmljaFRleHQgPSB0cnVlOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGVsc2UKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgICAgICAvL2lmIChjZWxsICE9IG51bGwpIGNlbGxMaXN0LkFkZChjZWxsKTsKCiAgICAgICAgICAgIC8vX2NlbGxzID0gbmV3IFJhbmdlQ29sbGVjdGlvbihjZWxsTGlzdCk7CiAgICAgICAgICAgIC8vX3Jvd3MgPSBuZXcgUmFuZ2VDb2xsZWN0aW9uKHJvd0xpc3QpOwogICAgICAgICAgICAvL19mb3JtdWxhQ2VsbHMgPSBuZXcgUmFuZ2VDb2xsZWN0aW9uKGZvcm11bGFMaXN0KTsKICAgICAgICB9CgogICAgICAgIHByaXZhdGUgYm9vbCBEb0FkZFJvdyhYbWxUZXh0UmVhZGVyIHhyKQogICAgICAgIHsKICAgICAgICAgICAgdmFyIGMgPSB4ci5HZXRBdHRyaWJ1dGUoInIiKT09bnVsbCA/IDA6MTsKICAgICAgICAgICAgaWYgKHhyLkdldEF0dHJpYnV0ZSgic3BhbnMiKSAhPSBudWxsKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBjKys7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgcmV0dXJuIHhyLkF0dHJpYnV0ZUNvdW50ID4gYzsKICAgICAgICB9CiAgICAgICAgLy8vIDxzdW1tYXJ5PgogICAgICAgIC8vLyBMb2FkIG1lcmdlZCBjZWxscwogICAgICAgIC8vLyA8L3N1bW1hcnk+CiAgICAgICAgLy8vIDxwYXJhbSBuYW1lPSJ4ciI+PC9wYXJhbT4KICAgICAgICBwcml2YXRlIHZvaWQgTG9hZE1lcmdlQ2VsbHMoWG1sVGV4dFJlYWRlciB4cikKICAgICAgICB7CiAgICAgICAgICAgIGlmKFJlYWRVbnRpbCh4ciwgIm1lcmdlQ2VsbHMiLCAiaHlwZXJsaW5rcyIsICJyb3dCcmVha3MiLCAiY29sQnJlYWtzIikgJiYgIXhyLkVPRikKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgd2hpbGUgKHhyLlJlYWQoKSkKICAgICAgICAgICAgICAgIHsgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgIGlmICh4ci5Mb2NhbE5hbWUgIT0gIm1lcmdlQ2VsbCIpIGJyZWFrOwogICAgICAgICAgICAgICAgICAgIGlmICh4ci5Ob2RlVHlwZSA9PSBYbWxOb2RlVHlwZS5FbGVtZW50KQogICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgc3RyaW5nIGFkZHJlc3MgPSB4ci5HZXRBdHRyaWJ1dGUoInJlZiIpOwogICAgICAgICAgICAgICAgICAgICAgICAvL2ludCBmcm9tUm93LCBmcm9tQ29sLCB0b1JvdywgdG9Db2w7CiAgICAgICAgICAgICAgICAgICAgICAgIC8vRXhjZWxDZWxsQmFzZS5HZXRSb3dDb2xGcm9tQWRkcmVzcyhhZGRyZXNzLCBvdXQgZnJvbVJvdywgb3V0IGZyb21Db2wsIG91dCB0b1Jvdywgb3V0IHRvQ29sKTsKICAgICAgICAgICAgICAgICAgICAgICAgLy9mb3IgKGludCByb3cgPSBmcm9tUm93OyByb3cgPD0gdG9Sb3c7IHJvdysrKQogICAgICAgICAgICAgICAgICAgICAgICAvL3sKICAgICAgICAgICAgICAgICAgICAgICAgLy8gICAgZm9yIChpbnQgY29sID0gZnJvbUNvbDsgY29sIDw9IHRvQ29sOyBjb2wrKykKICAgICAgICAgICAgICAgICAgICAgICAgLy8gICAgewogICAgICAgICAgICAgICAgICAgICAgICAvLyAgICAgICAgX2ZsYWdzLlNldEZsYWdWYWx1ZShyb3csIGNvbCwgdHJ1ZSxDZWxsRmxhZ3MuTWVyZ2VkKTsKICAgICAgICAgICAgICAgICAgICAgICAgLy8gICAgfQogICAgICAgICAgICAgICAgICAgICAgICAvL30KICAgICAgICAgICAgICAgICAgICAgICAgLy9fbWVyZ2VkQ2VsbHMuTGlzdC5BZGQoYWRkcmVzcyk7CiAgICAgICAgICAgICAgICAgICAgICAgIF9tZXJnZWRDZWxscy5BZGQobmV3IEV4Y2VsQWRkcmVzcyhhZGRyZXNzKSwgZmFsc2UpOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgIH0KICAgICAgICAvLy8gPHN1bW1hcnk+CiAgICAgICAgLy8vIFVwZGF0ZSBtZXJnZWQgY2VsbHMKICAgICAgICAvLy8gPC9zdW1tYXJ5PgogICAgICAgIC8vLyA8cGFyYW0gbmFtZT0ic3ciPlRoZSB3cml0ZXI8L3BhcmFtPgogICAgICAgIHByaXZhdGUgdm9pZCBVcGRhdGVNZXJnZWRDZWxscyhTdHJlYW1Xcml0ZXIgc3cpCiAgICAgICAgewogICAgICAgICAgICBzdy5Xcml0ZSgiPG1lcmdlQ2VsbHM+Iik7CiAgICAgICAgICAgIGZvcmVhY2ggKHN0cmluZyBhZGRyZXNzIGluIF9tZXJnZWRDZWxscykKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgc3cuV3JpdGUoIjxtZXJnZUNlbGwgcmVmPVwiezB9XCIgLz4iLCBhZGRyZXNzKTsKICAgICAgICAgICAgfQogICAgICAgICAgICBzdy5Xcml0ZSgiPC9tZXJnZUNlbGxzPiIpOwogICAgICAgIH0KICAgICAgICAvLy8gPHN1bW1hcnk+CiAgICAgICAgLy8vIFJlYWRzIGEgcm93IGZyb20gdGhlIFhNTCByZWFkZXIKICAgICAgICAvLy8gPC9zdW1tYXJ5PgogICAgICAgIC8vLyA8cGFyYW0gbmFtZT0ieHIiPlRoZSByZWFkZXI8L3BhcmFtPgogICAgICAgIC8vLyA8cGFyYW0gbmFtZT0icm93Ij5UaGUgcm93IG51bWJlcjwvcGFyYW0+CiAgICAgICAgLy8vIDxyZXR1cm5zPjwvcmV0dXJucz4KICAgICAgICBwcml2YXRlIFJvd0ludGVybmFsIEFkZFJvdyhYbWxUZXh0UmVhZGVyIHhyLCBpbnQgcm93KQogICAgICAgIHsKICAgICAgICAgICAgcmV0dXJuIG5ldyBSb3dJbnRlcm5hbCgpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIENvbGxhcHNlZD0oeHIuR2V0QXR0cmlidXRlKCJjb2xsYXBzZWQiKSAhPSBudWxsICYmIHhyLkdldEF0dHJpYnV0ZSgiY29sbGFwc2VkIik9PSAiMSIgPyB0cnVlIDogZmFsc2UpLAogICAgICAgICAgICAgICAgT3V0bGluZUxldmVsID0gKHhyLkdldEF0dHJpYnV0ZSgib3V0bGluZUxldmVsIikgPT0gbnVsbCA/IChzaG9ydCkwIDogc2hvcnQuUGFyc2UoeHIuR2V0QXR0cmlidXRlKCJvdXRsaW5lTGV2ZWwiKSwgQ3VsdHVyZUluZm8uSW52YXJpYW50Q3VsdHVyZSkpLAogICAgICAgICAgICAgICAgSGVpZ2h0ID0gKHhyLkdldEF0dHJpYnV0ZSgiaHQiKSA9PSBudWxsID8gLTEgOiBkb3VibGUuUGFyc2UoeHIuR2V0QXR0cmlidXRlKCJodCIpLCBDdWx0dXJlSW5mby5JbnZhcmlhbnRDdWx0dXJlKSksCiAgICAgICAgICAgICAgICBIaWRkZW4gPSAoeHIuR2V0QXR0cmlidXRlKCJoaWRkZW4iKSAhPSBudWxsICYmIHhyLkdldEF0dHJpYnV0ZSgiaGlkZGVuIikgPT0gIjEiID8gdHJ1ZSA6IGZhbHNlKSwKICAgICAgICAgICAgICAgIFBob25ldGljID0geHIuR2V0QXR0cmlidXRlKCJwaCIpICE9IG51bGwgJiYgeHIuR2V0QXR0cmlidXRlKCJwaCIpID09ICIxIiA/IHRydWUgOiBmYWxzZSwKICAgICAgICAgICAgICAgIEN1c3RvbUhlaWdodCA9IHhyLkdldEF0dHJpYnV0ZSgiY3VzdG9tSGVpZ2h0IikgPT0gbnVsbCA/IGZhbHNlIDogeHIuR2V0QXR0cmlidXRlKCJjdXN0b21IZWlnaHQiKT09IjEiCiAgICAgICAgICAgIH07CiAgICAgICAgfQoKICAgICAgICBwcml2YXRlIHZvaWQgU2V0VmFsdWVGcm9tWG1sKFhtbFRleHRSZWFkZXIgeHIsIHN0cmluZyB0eXBlLCBpbnQgc3R5bGVJRCwgaW50IHJvdywgaW50IGNvbCkKICAgICAgICB7CiAgICAgICAgICAgIC8vWG1sTm9kZSB2bm9kZSA9IGNvbE5vZGUuU2VsZWN0U2luZ2xlTm9kZSgiZDp2IiwgTmFtZVNwYWNlTWFuYWdlcik7CiAgICAgICAgICAgIC8vaWYgKHZub2RlID09IG51bGwpIHJldHVybiBudWxsOwogICAgICAgICAgICBpZiAodHlwZSA9PSAicyIpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIGludCBpeCA9IHhyLlJlYWRFbGVtZW50Q29udGVudEFzSW50KCk7CiAgICAgICAgICAgICAgICBfdmFsdWVzLlNldFZhbHVlKHJvdywgY29sLCBfcGFja2FnZS5Xb3JrYm9vay5fc2hhcmVkU3RyaW5nc0xpc3RbaXhdLlRleHQpOwogICAgICAgICAgICAgICAgaWYgKF9wYWNrYWdlLldvcmtib29rLl9zaGFyZWRTdHJpbmdzTGlzdFtpeF0uaXNSaWNoVGV4dCkKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICBfZmxhZ3MuU2V0RmxhZ1ZhbHVlKHJvdywgY29sLCB0cnVlLCBDZWxsRmxhZ3MuUmljaFRleHQpOwogICAgICAgICAgICAgICAgfSAgICAgICAgICAgICAgICAKICAgICAgICAgICAgfQogICAgICAgICAgICBlbHNlIGlmICh0eXBlID09ICJzdHIiKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBfdmFsdWVzLlNldFZhbHVlKHJvdywgY29sLCBDb252ZXJ0VXRpbC5FeGNlbERlY29kZVN0cmluZyh4ci5SZWFkRWxlbWVudENvbnRlbnRBc1N0cmluZygpKSk7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgZWxzZSBpZiAodHlwZSA9PSAiYiIpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIF92YWx1ZXMuU2V0VmFsdWUocm93LCBjb2wsICh4ci5SZWFkRWxlbWVudENvbnRlbnRBc1N0cmluZygpIT0iMCIpKTsKICAgICAgICAgICAgfQogICAgICAgICAgICBlbHNlIGlmICh0eXBlID09ICJlIikKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgX3ZhbHVlcy5TZXRWYWx1ZShyb3csIGNvbCwgR2V0RXJyb3JUeXBlKHhyLlJlYWRFbGVtZW50Q29udGVudEFzU3RyaW5nKCkpKTsKICAgICAgICAgICAgfQogICAgICAgICAgICBlbHNlCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIHN0cmluZyB2ID0geHIuUmVhZEVsZW1lbnRDb250ZW50QXNTdHJpbmcoKTsKICAgICAgICAgICAgICAgIHZhciBuZiA9IFdvcmtib29rLlN0eWxlcy5DZWxsWGZzW3N0eWxlSURdLk51bWJlckZvcm1hdElkOwogICAgICAgICAgICAgICAgaWYgKChuZiA+PSAxNCAmJiBuZiA8PSAyMikgfHwgKG5mID49IDQ1ICYmIG5mIDw9IDQ3KSkKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICBkb3VibGUgcmVzOwogICAgICAgICAgICAgICAgICAgIGlmIChkb3VibGUuVHJ5UGFyc2UodiwgTnVtYmVyU3R5bGVzLkFueSwgQ3VsdHVyZUluZm8uSW52YXJpYW50Q3VsdHVyZSwgb3V0IHJlcykpCiAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICBpZiAoV29ya2Jvb2suRGF0ZTE5MDQpCiAgICAgICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlcyArPSBFeGNlbFdvcmtib29rLmRhdGUxOTA0T2Zmc2V0OwogICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChyZXMgPj0gLTY1NzQzNS4wICYmIHJlcyA8IDI5NTg0NjUuOTk5OTk5OSkKICAgICAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgX3ZhbHVlcy5TZXRWYWx1ZShyb3csIGNvbCwgRGF0ZVRpbWUuRnJvbU9BRGF0ZShyZXMpKTsKICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICAgICBlbHNlCiAgICAgICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIF92YWx1ZXMuU2V0VmFsdWUocm93LCBjb2wsICIiKTsKICAgICAgICAgICAgICAgICAgICAgICAgfSAKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgZWxzZQogICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgX3ZhbHVlcy5TZXRWYWx1ZShyb3csIGNvbCwgIiIpOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGVsc2UKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICBkb3VibGUgZDsKICAgICAgICAgICAgICAgICAgICBpZiAoZG91YmxlLlRyeVBhcnNlKHYsIE51bWJlclN0eWxlcy5BbnksIEN1bHR1cmVJbmZvLkludmFyaWFudEN1bHR1cmUsIG91dCBkKSkKICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgIF92YWx1ZXMuU2V0VmFsdWUocm93LCBjb2wsIGQpOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICBlbHNlCiAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICBfdmFsdWVzLlNldFZhbHVlKHJvdywgY29sLCBkb3VibGUuTmFOKTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIHByaXZhdGUgb2JqZWN0IEdldEVycm9yVHlwZShzdHJpbmcgdikKICAgICAgICB7CiAgICAgICAgICAgIHJldHVybiBFeGNlbEVycm9yVmFsdWUuUGFyc2Uodi5Ub1VwcGVyKEN1bHR1cmVJbmZvLkludmFyaWFudEN1bHR1cmUpKTsKICAgICAgICAgICAgLy9zd2l0Y2godi5Ub1VwcGVyKCkpCiAgICAgICAgICAgIC8vewogICAgICAgICAgICAvLyAgICBjYXNlICIjRElWLzAhIjoKICAgICAgICAgICAgLy8gICAgICAgIHJldHVybiBuZXcgRXhjZWxFcnJvclZhbHVlLmNyZShlRXJyb3JUeXBlLkRpdjApOwogICAgICAgICAgICAvLyAgICBjYXNlICIjUkVGISI6CiAgICAgICAgICAgIC8vICAgICAgICByZXR1cm4gbmV3IEV4Y2VsRXJyb3JWYWx1ZShlRXJyb3JUeXBlLlJlZik7CiAgICAgICAgICAgIC8vICAgIGNhc2UgIiNOL0EiOgogICAgICAgICAgICAvLyAgICAgICAgcmV0dXJuIG5ldyBFeGNlbEVycm9yVmFsdWUoZUVycm9yVHlwZS5OQSk7CiAgICAgICAgICAgIC8vICAgIGNhc2UgIiNOQU1FPyI6CiAgICAgICAgICAgIC8vICAgICAgICByZXR1cm4gbmV3IEV4Y2VsRXJyb3JWYWx1ZShlRXJyb3JUeXBlLk5hbWUpOwogICAgICAgICAgICAvLyAgICBjYXNlICIjTlVMTCEiOgogICAgICAgICAgICAvLyAgICAgICAgcmV0dXJuIG5ldyBFeGNlbEVycm9yVmFsdWUoZUVycm9yVHlwZS5OdWxsKTsKICAgICAgICAgICAgLy8gICAgY2FzZSAiI05VTSEiOgogICAgICAgICAgICAvLyAgICAgICAgcmV0dXJuIG5ldyBFeGNlbEVycm9yVmFsdWUoZUVycm9yVHlwZS5OdW0pOwogICAgICAgICAgICAvLyAgICBkZWZhdWx0OgogICAgICAgICAgICAvLyAgICAgICAgcmV0dXJuIG5ldyBFeGNlbEVycm9yVmFsdWUoZUVycm9yVHlwZS5WYWx1ZSk7CiAgICAgICAgICAgIC8vfQogICAgICAgIH0KICAgICAgICAvL3ByaXZhdGUgc3RyaW5nIEdldFNoYXJlZFN0cmluZyhpbnQgc3RyaW5nSUQpCiAgICAgICAgLy97CiAgICAgICAgLy8gICAgc3RyaW5nIHJldFZhbHVlID0gbnVsbDsKICAgICAgICAvLyAgICBYbWxOb2RlTGlzdCBzdHJpbmdOb2RlcyA9IHhsUGFja2FnZS5Xb3JrYm9vay5TaGFyZWRTdHJpbmdzWG1sLlNlbGVjdE5vZGVzKHN0cmluZy5Gb3JtYXQoIi8vZDpzaSIsIHN0cmluZ0lEKSwgTmFtZVNwYWNlTWFuYWdlcik7CiAgICAgICAgLy8gICAgWG1sTm9kZSBzdHJpbmdOb2RlID0gc3RyaW5nTm9kZXNbc3RyaW5nSURdOwogICAgICAgIC8vICAgIGlmIChzdHJpbmdOb2RlICE9IG51bGwpCiAgICAgICAgLy8gICAgICAgIHJldFZhbHVlID0gc3RyaW5nTm9kZS5Jbm5lclRleHQ7CiAgICAgICAgLy8gICAgcmV0dXJuIChyZXRWYWx1ZSk7CiAgICAgICAgLy99CiAgICAgICAgI2VuZHJlZ2lvbgoJCSNyZWdpb24gSGVhZGVyRm9vdGVyCgkJLy8vIDxzdW1tYXJ5PgoJCS8vLyBBIHJlZmVyZW5jZSB0byB0aGUgaGVhZGVyIGFuZCBmb290ZXIgY2xhc3Mgd2hpY2ggYWxsb3dzIHlvdSB0byAKCQkvLy8gc2V0IHRoZSBoZWFkZXIgYW5kIGZvb3RlciBmb3IgYWxsIG9kZCwgZXZlbiBhbmQgZmlyc3QgcGFnZXMgb2YgdGhlIHdvcmtzaGVldAogICAgICAgIC8vLyA8L3N1bW1hcnk+CiAgICAgICAgLy8vIDxyZW1hcmtzPgogICAgICAgIC8vLyBUbyBmb3JtYXQgdGhlIHRleHQgeW91IGNhbiB1c2UgdGhlIGZvbGxvd2luZyBmb3JtYXQKICAgICAgICAvLy8gPGxpc3QgdHlwZT0idGFibGUiPgogICAgICAgIC8vLyA8bGlzdGhlYWRlcj48dGVybT5QcmVmaXg8L3Rlcm0+PGRlc2NyaXB0aW9uPkRlc2NyaXB0aW9uPC9kZXNjcmlwdGlvbj48L2xpc3RoZWFkZXI+CiAgICAgICAgLy8vIDxpdGVtPjx0ZXJtPiZhbXA7VTwvdGVybT48ZGVzY3JpcHRpb24+VW5kZXJsaW5lZDwvZGVzY3JpcHRpb24+PC9pdGVtPgogICAgICAgIC8vLyA8aXRlbT48dGVybT4mYW1wO0U8L3Rlcm0+PGRlc2NyaXB0aW9uPkRvdWJsZSBVbmRlcmxpbmU8L2Rlc2NyaXB0aW9uPjwvaXRlbT4KICAgICAgICAvLy8gPGl0ZW0+PHRlcm0+JmFtcDtLOnh4eHh4eDwvdGVybT48ZGVzY3JpcHRpb24+Q29sb3IuIGV4ICZhbXA7SzpGRjAwMDAgZm9yIHJlZDwvZGVzY3JpcHRpb24+PC9pdGVtPgogICAgICAgIC8vLyA8aXRlbT48dGVybT4mYW1wOyJGb250LFJlZ3VsYXIgQm9sZCBJdGFsaWMiPC90ZXJtPjxkZXNjcmlwdGlvbj5DaGFuZ2VzIHRoZSBmb250LiBSZWd1bGFyIG9yIEJvbGQgb3IgSXRhbGljIG9yIEJvbGQgSXRhbGljIGNhbiBiZSB1c2VkLiBleCAmYW1wOyJBcmlhbCxCb2xkIEl0YWxpYyI8L2Rlc2NyaXB0aW9uPjwvaXRlbT4KICAgICAgICAvLy8gPGl0ZW0+PHRlcm0+JmFtcDtubjwvdGVybT48ZGVzY3JpcHRpb24+Q2hhbmdlIGZvbnQgc2l6ZS4gbm4gaXMgYW4gaW50ZWdlci4gZXggJmFtcDsyNDwvZGVzY3JpcHRpb24+PC9pdGVtPgogICAgICAgIC8vLyA8aXRlbT48dGVybT4mYW1wO0c8L3Rlcm0+PGRlc2NyaXB0aW9uPlBsYWNlaG9sZGVyIGZvciBpbWFnZXMuIEltYWdlcyBjYW4gbm90IGJlIGFkZGVkIGJ5IHRoZSBsaWJyYXJ5LCBidXQgaXRzIHBvc3NpYmxlIHRvIHVzZSBpbiBhIHRlbXBsYXRlLjwvZGVzY3JpcHRpb24+PC9pdGVtPgogICAgICAgIC8vLyA8L2xpc3Q+CiAgICAgICAgLy8vIDwvcmVtYXJrcz4KICAgICAgICBwdWJsaWMgRXhjZWxIZWFkZXJGb290ZXIgSGVhZGVyRm9vdGVyCgkJewoJCQlnZXQKCQkJewoJCQkJaWYgKF9oZWFkZXJGb290ZXIgPT0gbnVsbCkKCQkJCXsKICAgICAgICAgICAgICAgICAgICBYbWxOb2RlIGhlYWRlckZvb3Rlck5vZGUgPSBUb3BOb2RlLlNlbGVjdFNpbmdsZU5vZGUoImQ6aGVhZGVyRm9vdGVyIiwgTmFtZVNwYWNlTWFuYWdlcik7CiAgICAgICAgICAgICAgICAgICAgaWYgKGhlYWRlckZvb3Rlck5vZGUgPT0gbnVsbCkKICAgICAgICAgICAgICAgICAgICAgICAgaGVhZGVyRm9vdGVyTm9kZT0gQ3JlYXRlTm9kZSgiZDpoZWFkZXJGb290ZXIiKTsKICAgICAgICAgICAgICAgICAgICBfaGVhZGVyRm9vdGVyID0gbmV3IEV4Y2VsSGVhZGVyRm9vdGVyKE5hbWVTcGFjZU1hbmFnZXIsIGhlYWRlckZvb3Rlck5vZGUsIHRoaXMpOwoJCQkJfSAgICAgICAgICAgICAgICAKCQkJCXJldHVybiAoX2hlYWRlckZvb3Rlcik7CgkJCX0KCQl9CgkJI2VuZHJlZ2lvbgoKICAgICAgICAjcmVnaW9uICJQcmludGVyU2V0dGluZ3MiCiAgICAgICAgLy8vIDxzdW1tYXJ5PgogICAgICAgIC8vLyBQcmludGVyIHNldHRpbmdzCiAgICAgICAgLy8vIDwvc3VtbWFyeT4KICAgICAgICBwdWJsaWMgRXhjZWxQcmludGVyU2V0dGluZ3MgUHJpbnRlclNldHRpbmdzCiAgICAgICAgewogICAgICAgICAgICBnZXQKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgdmFyIHBzID0gbmV3IEV4Y2VsUHJpbnRlclNldHRpbmdzKE5hbWVTcGFjZU1hbmFnZXIsIFRvcE5vZGUsIHRoaXMpOwogICAgICAgICAgICAgICAgcHMuU2NoZW1hTm9kZU9yZGVyID0gU2NoZW1hTm9kZU9yZGVyOwogICAgICAgICAgICAgICAgcmV0dXJuIHBzOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgICNlbmRyZWdpb24KCgkJI2VuZHJlZ2lvbiAvLyBFTkQgV29ya3NoZWV0IFB1YmxpYyBQcm9wZXJ0aWVzCgoJCSNyZWdpb24gV29ya3NoZWV0IFB1YmxpYyBNZXRob2RzCiAgICAgICAgCiAgICAgICAgLy8vLy8gPHN1bW1hcnk+CiAgICAgICAgLy8vLy8gUHJvdmlkZXMgYWNjZXNzIHRvIGFuIGluZGl2aWR1YWwgY2VsbCB3aXRoaW4gdGhlIHdvcmtzaGVldC4KICAgICAgICAvLy8vLyA8L3N1bW1hcnk+CiAgICAgICAgLy8vLy8gPHBhcmFtIG5hbWU9InJvdyI+VGhlIHJvdyBudW1iZXIgaW4gdGhlIHdvcmtzaGVldDwvcGFyYW0+CiAgICAgICAgLy8vLy8gPHBhcmFtIG5hbWU9ImNvbCI+VGhlIGNvbHVtbiBudW1iZXIgaW4gdGhlIHdvcmtzaGVldDwvcGFyYW0+CiAgICAgICAgLy8vLy8gPHJldHVybnM+PC9yZXR1cm5zPgkJCiAgICAgICAgLy9pbnRlcm5hbCBFeGNlbENlbGwgQ2VsbChpbnQgcm93LCBpbnQgY29sKQogICAgICAgIC8vewogICAgICAgIC8vICAgIHJldHVybiBuZXcgRXhjZWxDZWxsKF92YWx1ZXMsIHJvdywgY29sKTsKICAgICAgICAvL30KICAgICAgICAgLy8vIDxzdW1tYXJ5PgogICAgICAgICAvLy8gUHJvdmlkZXMgYWNjZXNzIHRvIGEgcmFuZ2Ugb2YgY2VsbHMKICAgICAgICAvLy8gPC9zdW1tYXJ5PiAgCiAgICAgICAgcHVibGljIEV4Y2VsUmFuZ2UgQ2VsbHMKICAgICAgICB7CiAgICAgICAgICAgIGdldAogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBDaGVja1NoZWV0VHlwZSgpOwogICAgICAgICAgICAgICAgcmV0dXJuIG5ldyBFeGNlbFJhbmdlKHRoaXMsIDEsIDEsIEV4Y2VsUGFja2FnZS5NYXhSb3dzLCBFeGNlbFBhY2thZ2UuTWF4Q29sdW1ucyk7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgLy8vIDxzdW1tYXJ5PgogICAgICAgIC8vLyBQcm92aWRlcyBhY2Nlc3MgdG8gdGhlIHNlbGVjdGVkIHJhbmdlIG9mIGNlbGxzCiAgICAgICAgLy8vIDwvc3VtbWFyeT4gIAogICAgICAgIHB1YmxpYyBFeGNlbFJhbmdlIFNlbGVjdGVkUmFuZ2UKICAgICAgICB7CiAgICAgICAgICAgIGdldAogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBDaGVja1NoZWV0VHlwZSgpOwogICAgICAgICAgICAgICAgcmV0dXJuIG5ldyBFeGNlbFJhbmdlKHRoaXMsIFZpZXcuU2VsZWN0ZWRSYW5nZSk7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgTWVyZ2VDZWxsc0NvbGxlY3Rpb24gX21lcmdlZENlbGxzID0gbmV3IE1lcmdlQ2VsbHNDb2xsZWN0aW9uKCk7CiAgICAgICAgLy8vIDxzdW1tYXJ5PgogICAgICAgIC8vLyBBZGRyZXNzZXMgdG8gbWVyZ2VkIHJhbmdlcwogICAgICAgIC8vLyA8L3N1bW1hcnk+CiAgICAgICAgcHVibGljIE1lcmdlQ2VsbHNDb2xsZWN0aW9uIE1lcmdlZENlbGxzCiAgICAgICAgewogICAgICAgICAgICBnZXQKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgQ2hlY2tTaGVldFR5cGUoKTsKICAgICAgICAgICAgICAgIHJldHVybiBfbWVyZ2VkQ2VsbHM7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgLy8vIDxzdW1tYXJ5PgoJCS8vLyBQcm92aWRlcyBhY2Nlc3MgdG8gYW4gaW5kaXZpZHVhbCByb3cgd2l0aGluIHRoZSB3b3Jrc2hlZXQgc28geW91IGNhbiBzZXQgaXRzIHByb3BlcnRpZXMuCgkJLy8vIDwvc3VtbWFyeT4KCQkvLy8gPHBhcmFtIG5hbWU9InJvdyI+VGhlIHJvdyBudW1iZXIgaW4gdGhlIHdvcmtzaGVldDwvcGFyYW0+CgkJLy8vIDxyZXR1cm5zPjwvcmV0dXJucz4KCQlwdWJsaWMgRXhjZWxSb3cgUm93KGludCByb3cpCgkJewogICAgICAgICAgICAvL0V4Y2VsUm93IHI7CiAgICAgICAgICAgIC8vdWxvbmcgaWQgPSBFeGNlbFJvdy5HZXRSb3dJRChfc2hlZXRJRCwgcm93KTsKICAgICAgICAgICAgLy9UT0RPOiBGaXhhLgogICAgICAgICAgICAvL3ZhciB2ID0gX3ZhbHVlcy5HZXRWYWx1ZShyb3csIDApOwogICAgICAgICAgICAvL2lmICh2IT1udWxsKQogICAgICAgICAgICAvL3sKICAgICAgICAgICAgLy8gICAgdmFyIHJpPShSb3dJbnRlcm5hbCl2OwogICAgICAgICAgICAvLyAgICByID0gbmV3IEV4Y2VsUm93KHRoaXMsIHJvdykKICAgICAgICAgICAgLy99CiAgICAgICAgICAgIC8vZWxzZQogICAgICAgICAgICAvL3sKICAgICAgICAgICAgICAgIC8vciA9IG5ldyBFeGNlbFJvdyh0aGlzLCByb3cpOwogICAgICAgICAgICAgICAgLy9fdmFsdWVzLlNldFZhbHVlKHJvdywgMCwgcik7CiAgICAgICAgICAgICAgICAvL19yb3dzLkFkZChyKTsKICAgICAgICAgICAgLy99CiAgICAgICAgICAgIENoZWNrU2hlZXRUeXBlKCk7CiAgICAgICAgICAgIGlmIChyb3cgPCAxIHx8IHJvdyA+IEV4Y2VsUGFja2FnZS5NYXhSb3dzKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICB0aHJvdyAobmV3IEFyZ3VtZW50RXhjZXB0aW9uKCJSb3cgbnVtYmVyIG91dCBvZiBib3VuZHMiKSk7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgcmV0dXJuIG5ldyBFeGNlbFJvdyh0aGlzLCByb3cpOwogICAgICAgICAgICAvL3JldHVybiByOwoJCX0KCQkvLy8gPHN1bW1hcnk+CgkJLy8vIFByb3ZpZGVzIGFjY2VzcyB0byBhbiBpbmRpdmlkdWFsIGNvbHVtbiB3aXRoaW4gdGhlIHdvcmtzaGVldCBzbyB5b3UgY2FuIHNldCBpdHMgcHJvcGVydGllcy4KCQkvLy8gPC9zdW1tYXJ5PgoJCS8vLyA8cGFyYW0gbmFtZT0iY29sIj5UaGUgY29sdW1uIG51bWJlciBpbiB0aGUgd29ya3NoZWV0PC9wYXJhbT4KCQkvLy8gPHJldHVybnM+PC9yZXR1cm5zPgoJCXB1YmxpYyBFeGNlbENvbHVtbiBDb2x1bW4oaW50IGNvbCkKCQl7ICAgICAgICAgICAgCiAgICAgICAgICAgIENoZWNrU2hlZXRUeXBlKCk7CiAgICAgICAgICAgIGlmIChjb2wgPCAxIHx8IGNvbCA+IEV4Y2VsUGFja2FnZS5NYXhDb2x1bW5zKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICB0aHJvdyAobmV3IEFyZ3VtZW50RXhjZXB0aW9uKCJDb2x1bW4gbnVtYmVyIG91dCBvZiBib3VuZHMiKSk7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgdmFyIGNvbHVtbiA9IF92YWx1ZXMuR2V0VmFsdWUoMCwgY29sKSBhcyBFeGNlbENvbHVtbjsKICAgICAgICAgICAgaWYgKGNvbHVtbiE9bnVsbCkKICAgICAgICAgICAgeyAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgaWYgKGNvbHVtbi5Db2x1bW5NaW4gIT0gY29sdW1uLkNvbHVtbk1heCkKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICBpbnQgbWF4Q29sID0gY29sdW1uLkNvbHVtbk1heDsKICAgICAgICAgICAgICAgICAgICBjb2x1bW4uQ29sdW1uTWF4ID0gY29sOwogICAgICAgICAgICAgICAgICAgIEV4Y2VsQ29sdW1uIGNvcHkgPSBDb3B5Q29sdW1uKGNvbHVtbiwgY29sICsgMSwgbWF4Q29sKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgICAgICBlbHNlCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIGludCByPTAsIGM9Y29sOwogICAgICAgICAgICAgICAgaWYgKF92YWx1ZXMuUHJldkNlbGwocmVmIHIsIHJlZiBjKSkKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICBjb2x1bW4gPSBfdmFsdWVzLkdldFZhbHVlKDAsIGMpIGFzIEV4Y2VsQ29sdW1uOwogICAgICAgICAgICAgICAgICAgIGludCBtYXhDb2wgPSBjb2x1bW4uQ29sdW1uTWF4OwogICAgICAgICAgICAgICAgICAgIGlmIChtYXhDb2wgPj0gY29sKQogICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgY29sdW1uLkNvbHVtbk1heCA9IGNvbC0xOwogICAgICAgICAgICAgICAgICAgICAgICBpZiAobWF4Q29sID4gY29sKQogICAgICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBFeGNlbENvbHVtbiBuZXdDID0gQ29weUNvbHVtbihjb2x1bW4sIGNvbCArIDEsIG1heENvbCk7CiAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIENvcHlDb2x1bW4oY29sdW1uLCBjb2wsIGNvbCk7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgLy9mb3JlYWNoIChFeGNlbENvbHVtbiBjaGVja0NvbHVtbiBpbiBfY29sdW1ucykKICAgICAgICAgICAgICAgIC8vewogICAgICAgICAgICAgICAgLy8gICAgaWYgKGNvbCA+IGNoZWNrQ29sdW1uLkNvbHVtbk1pbiAmJiBjb2wgPD0gY2hlY2tDb2x1bW4uQ29sdW1uTWF4KQogICAgICAgICAgICAgICAgLy8gICAgewogICAgICAgICAgICAgICAgLy8gICAgICAgIGludCBtYXhDb2wgPSBjaGVja0NvbHVtbi5Db2x1bW5NYXg7CiAgICAgICAgICAgICAgICAvLyAgICAgICAgY2hlY2tDb2x1bW4uQ29sdW1uTWF4ID0gY29sIC0gMTsKICAgICAgICAgICAgICAgIC8vICAgICAgICBpZiAobWF4Q29sID4gY29sKQogICAgICAgICAgICAgICAgLy8gICAgICAgIHsKICAgICAgICAgICAgICAgIC8vICAgICAgICAgICAgRXhjZWxDb2x1bW4gbmV3QyA9IENvcHlDb2x1bW4oY2hlY2tDb2x1bW4sIGNvbCArIDEsIG1heENvbCk7CiAgICAgICAgICAgICAgICAvLyAgICAgICAgfQogICAgICAgICAgICAgICAgLy8gICAgICAgIHJldHVybiBDb3B5Q29sdW1uKGNoZWNrQ29sdW1uLCBjb2wsY29sKTsgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgIC8vICAgIH0KICAgICAgICAgICAgICAgIC8vfQogICAgICAgICAgICAgICAgY29sdW1uID0gbmV3IEV4Y2VsQ29sdW1uKHRoaXMsIGNvbCk7CiAgICAgICAgICAgICAgICBfdmFsdWVzLlNldFZhbHVlKDAsIGNvbCwgY29sdW1uKTsKICAgICAgICAgICAgICAgIC8vX2NvbHVtbnMuQWRkKGNvbHVtbik7CiAgICAgICAgICAgICB9CiAgICAgICAgICAgIHJldHVybiBjb2x1bW47CgkJfQoKICAgICAgICAvLy8gPHN1bW1hcnk+CiAgICAgICAgLy8vIFJldHVybnMgdGhlIG5hbWUgb2YgdGhlIHdvcmtzaGVldAogICAgICAgIC8vLyA8L3N1bW1hcnk+CiAgICAgICAgLy8vIDxyZXR1cm5zPlRoZSBuYW1lIG9mIHRoZSB3b3Jrc2hlZXQ8L3JldHVybnM+CiAgICAgICAgcHVibGljIG92ZXJyaWRlIHN0cmluZyBUb1N0cmluZygpCiAgICAgICAgewogICAgICAgICAgICByZXR1cm4gTmFtZTsKICAgICAgICB9CiAgICAgICAgaW50ZXJuYWwgRXhjZWxDb2x1bW4gQ29weUNvbHVtbihFeGNlbENvbHVtbiBjLCBpbnQgY29sLCBpbnQgbWF4Q29sKQogICAgICAgIHsKICAgICAgICAgICAgRXhjZWxDb2x1bW4gbmV3QyA9IG5ldyBFeGNlbENvbHVtbih0aGlzLCBjb2wpOwogICAgICAgICAgICBuZXdDLkNvbHVtbk1heCA9IG1heENvbCA8IEV4Y2VsUGFja2FnZS5NYXhDb2x1bW5zID8gbWF4Q29sIDogRXhjZWxQYWNrYWdlLk1heENvbHVtbnM7CiAgICAgICAgICAgIGlmIChjLlN0eWxlTmFtZSAhPSAiIikKICAgICAgICAgICAgICAgIG5ld0MuU3R5bGVOYW1lID0gYy5TdHlsZU5hbWU7CiAgICAgICAgICAgIGVsc2UKICAgICAgICAgICAgICAgIG5ld0MuU3R5bGVJRCA9IGMuU3R5bGVJRDsKCiAgICAgICAgICAgIG5ld0MuT3V0bGluZUxldmVsID0gYy5PdXRsaW5lTGV2ZWw7CiAgICAgICAgICAgIG5ld0MuUGhvbmV0aWMgPSBjLlBob25ldGljOwogICAgICAgICAgICBuZXdDLkJlc3RGaXQgPSBjLkJlc3RGaXQ7CiAgICAgICAgICAgIC8vX2NvbHVtbnMuQWRkKG5ld0MpOwogICAgICAgICAgICBfdmFsdWVzLlNldFZhbHVlKDAsIGNvbCwgbmV3Qyk7CiAgICAgICAgICAgIG5ld0MuX3dpZHRoID0gYy5fd2lkdGg7CiAgICAgICAgICAgIG5ld0MuX2hpZGRlbiA9IGMuX2hpZGRlbjsKICAgICAgICAgICAgcmV0dXJuIG5ld0M7CiAgICAgICB9CiAgICAgICAgLy8vIDxzdW1tYXJ5PgogICAgICAgIC8vLyBNYWtlIHRoZSBjdXJyZW50IHdvcmtzaGVldCBhY3RpdmUuCiAgICAgICAgLy8vIDwvc3VtbWFyeT4KICAgICAgICBwdWJsaWMgdm9pZCBTZWxlY3QoKQogICAgICAgIHsKICAgICAgICAgICAgVmlldy5UYWJTZWxlY3RlZCA9IHRydWU7CiAgICAgICAgICAgIC8vU2VsZWN0KEFkZHJlc3MsIHRydWUpOwogICAgICAgIH0KICAgICAgICAvLy8gPHN1bW1hcnk+CiAgICAgICAgLy8vIFNlbGVjdHMgYSByYW5nZSBpbiB0aGUgd29ya3NoZWV0LiBUaGUgYWN0aXZlIGNlbGwgaXMgdGhlIHRvcG1vc3QgY2VsbC4KICAgICAgICAvLy8gTWFrZSB0aGUgY3VycmVudCB3b3Jrc2hlZXQgYWN0aXZlLgogICAgICAgIC8vLyA8L3N1bW1hcnk+CiAgICAgICAgLy8vIDxwYXJhbSBuYW1lPSJBZGRyZXNzIj5BbiBhZGRyZXNzIHJhbmdlPC9wYXJhbT4KICAgICAgICBwdWJsaWMgdm9pZCBTZWxlY3Qoc3RyaW5nIEFkZHJlc3MpCiAgICAgICAgewogICAgICAgICAgICBTZWxlY3QoQWRkcmVzcywgdHJ1ZSk7CiAgICAgICAgfQogICAgICAgIC8vLyA8c3VtbWFyeT4KICAgICAgICAvLy8gU2VsZWN0cyBhIHJhbmdlIGluIHRoZSB3b3Jrc2hlZXQuIFRoZSBhY3RpY2UgY2VsbCBpcyB0aGUgdG9wbW9zdCBjZWxsLgogICAgICAgIC8vLyA8L3N1bW1hcnk+CiAgICAgICAgLy8vIDxwYXJhbSBuYW1lPSJBZGRyZXNzIj5BIHJhbmdlIG9mIGNlbGxzPC9wYXJhbT4KICAgICAgICAvLy8gPHBhcmFtIG5hbWU9IlNlbGVjdFNoZWV0Ij5NYWtlIHRoZSBzaGVldCBhY3RpdmU8L3BhcmFtPgogICAgICAgIHB1YmxpYyB2b2lkIFNlbGVjdChzdHJpbmcgQWRkcmVzcywgYm9vbCBTZWxlY3RTaGVldCkKICAgICAgICB7CiAgICAgICAgICAgIENoZWNrU2hlZXRUeXBlKCk7CiAgICAgICAgICAgIGludCBmcm9tQ29sLCBmcm9tUm93LCB0b0NvbCwgdG9Sb3c7CiAgICAgICAgICAgIC8vR2V0IHJvd3MgYW5kIGNvbHVtbnMgYW5kIHZhbGlkYXRlIGFzIHdlbGwKICAgICAgICAgICAgRXhjZWxDZWxsQmFzZS5HZXRSb3dDb2xGcm9tQWRkcmVzcyhBZGRyZXNzLCBvdXQgZnJvbVJvdywgb3V0IGZyb21Db2wsIG91dCB0b1Jvdywgb3V0IHRvQ29sKTsKCiAgICAgICAgICAgIGlmIChTZWxlY3RTaGVldCkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgVmlldy5UYWJTZWxlY3RlZCA9IHRydWU7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgVmlldy5TZWxlY3RlZFJhbmdlID0gQWRkcmVzczsKICAgICAgICAgICAgVmlldy5BY3RpdmVDZWxsID0gRXhjZWxDZWxsQmFzZS5HZXRBZGRyZXNzKGZyb21Sb3csIGZyb21Db2wpOyAgICAgICAgICAgIAogICAgICAgIH0KICAgICAgICAvLy8gPHN1bW1hcnk+CiAgICAgICAgLy8vIFNlbGVjdHMgYSByYW5nZSBpbiB0aGUgd29ya3NoZWV0LiBUaGUgYWN0aXZlIGNlbGwgaXMgdGhlIHRvcG1vc3QgY2VsbCBvZiB0aGUgZmlyc3QgYWRkcmVzcy4KICAgICAgICAvLy8gTWFrZSB0aGUgY3VycmVudCB3b3Jrc2hlZXQgYWN0aXZlLgogICAgICAgIC8vLyA8L3N1bW1hcnk+CiAgICAgICAgLy8vIDxwYXJhbSBuYW1lPSJBZGRyZXNzIj5BbiBhZGRyZXNzIHJhbmdlPC9wYXJhbT4KICAgICAgICBwdWJsaWMgdm9pZCBTZWxlY3QoRXhjZWxBZGRyZXNzIEFkZHJlc3MpCiAgICAgICAgewogICAgICAgICAgICBDaGVja1NoZWV0VHlwZSgpOwogICAgICAgICAgICBTZWxlY3QoQWRkcmVzcywgdHJ1ZSk7CiAgICAgICAgfQogICAgICAgIC8vLyA8c3VtbWFyeT4KICAgICAgICAvLy8gU2VsZWN0cyBhIHJhbmdlIGluIHRoZSB3b3Jrc2hlZXQuIFRoZSBhY3RpdmUgY2VsbCBpcyB0aGUgdG9wbW9zdCBjZWxsIG9mIHRoZSBmaXJzdCBhZGRyZXNzLgogICAgICAgIC8vLyA8L3N1bW1hcnk+CiAgICAgICAgLy8vIDxwYXJhbSBuYW1lPSJBZGRyZXNzIj5BIHJhbmdlIG9mIGNlbGxzPC9wYXJhbT4KICAgICAgICAvLy8gPHBhcmFtIG5hbWU9IlNlbGVjdFNoZWV0Ij5NYWtlIHRoZSBzaGVldCBhY3RpdmU8L3BhcmFtPgogICAgICAgIHB1YmxpYyB2b2lkIFNlbGVjdChFeGNlbEFkZHJlc3MgQWRkcmVzcywgYm9vbCBTZWxlY3RTaGVldCkKICAgICAgICB7CgogICAgICAgICAgICBDaGVja1NoZWV0VHlwZSgpOwogICAgICAgICAgICBpZiAoU2VsZWN0U2hlZXQpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIFZpZXcuVGFiU2VsZWN0ZWQgPSB0cnVlOwogICAgICAgICAgICB9CiAgICAgICAgICAgIHN0cmluZyBzZWxBZGRyZXNzID0gRXhjZWxDZWxsQmFzZS5HZXRBZGRyZXNzKEFkZHJlc3MuU3RhcnQuUm93LCBBZGRyZXNzLlN0YXJ0LkNvbHVtbikgKyAiOiIgKyBFeGNlbENlbGxCYXNlLkdldEFkZHJlc3MoQWRkcmVzcy5FbmQuUm93LCBBZGRyZXNzLkVuZC5Db2x1bW4pOwogICAgICAgICAgICBpZiAoQWRkcmVzcy5BZGRyZXNzZXMgIT0gbnVsbCkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgZm9yZWFjaCAodmFyIGEgaW4gQWRkcmVzcy5BZGRyZXNzZXMpCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgc2VsQWRkcmVzcyArPSAiICIgKyBFeGNlbENlbGxCYXNlLkdldEFkZHJlc3MoYS5TdGFydC5Sb3csIGEuU3RhcnQuQ29sdW1uKSArICI6IiArIEV4Y2VsQ2VsbEJhc2UuR2V0QWRkcmVzcyhhLkVuZC5Sb3csIGEuRW5kLkNvbHVtbik7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICAgICAgVmlldy5TZWxlY3RlZFJhbmdlID0gc2VsQWRkcmVzczsKICAgICAgICAgICAgVmlldy5BY3RpdmVDZWxsID0gRXhjZWxDZWxsQmFzZS5HZXRBZGRyZXNzKEFkZHJlc3MuU3RhcnQuUm93LCBBZGRyZXNzLlN0YXJ0LkNvbHVtbik7CiAgICAgICAgfQoKCQkjcmVnaW9uIEluc2VydFJvdwogICAgICAgIC8vLyA8c3VtbWFyeT4KICAgICAgICAvLy8gSW5zZXJ0cyBhIG5ldyByb3cgaW50byB0aGUgc3ByZWFkc2hlZXQuICBFeGlzdGluZyByb3dzIGJlbG93IHRoZSBwb3NpdGlvbiBhcmUgCiAgICAgICAgLy8vIHNoaWZ0ZWQgZG93bi4gIEFsbCBmb3JtdWxhIGFyZSB1cGRhdGVkIHRvIHRha2UgYWNjb3VudCBvZiB0aGUgbmV3IHJvdy4KICAgICAgICAvLy8gPC9zdW1tYXJ5PgogICAgICAgIC8vLyA8cGFyYW0gbmFtZT0icm93RnJvbSI+VGhlIHBvc2l0aW9uIG9mIHRoZSBuZXcgcm93PC9wYXJhbT4KICAgICAgICAvLy8gPHBhcmFtIG5hbWU9InJvd3MiPk51bWJlciBvZiByb3dzIHRvIGluc2VydDwvcGFyYW0+CiAgICAgICAgcHVibGljIHZvaWQgSW5zZXJ0Um93KGludCByb3dGcm9tLCBpbnQgcm93cykKICAgICAgICB7CiAgICAgICAgICAgIEluc2VydFJvdyhyb3dGcm9tLCByb3dzLCAwKTsKICAgICAgICB9CiAgICAgICAgLy8vIDxzdW1tYXJ5PgoJCS8vLyBJbnNlcnRzIGEgbmV3IHJvdyBpbnRvIHRoZSBzcHJlYWRzaGVldC4gIEV4aXN0aW5nIHJvd3MgYmVsb3cgdGhlIHBvc2l0aW9uIGFyZSAKCQkvLy8gc2hpZnRlZCBkb3duLiAgQWxsIGZvcm11bGEgYXJlIHVwZGF0ZWQgdG8gdGFrZSBhY2NvdW50IG9mIHRoZSBuZXcgcm93LgoJCS8vLyA8L3N1bW1hcnk+CiAgICAgICAgLy8vIDxwYXJhbSBuYW1lPSJyb3dGcm9tIj5UaGUgcG9zaXRpb24gb2YgdGhlIG5ldyByb3c8L3BhcmFtPgogICAgICAgIC8vLyA8cGFyYW0gbmFtZT0icm93cyI+TnVtYmVyIG9mIHJvd3MgdG8gaW5zZXJ0LjwvcGFyYW0+CiAgICAgICAgLy8vIDxwYXJhbSBuYW1lPSJjb3B5U3R5bGVzRnJvbVJvdyI+Q29weSBTdHlsZXMgZnJvbSB0aGlzIHJvdy4gQXBwbGllZCB0byBhbGwgaW5zZXJ0ZWQgcm93czwvcGFyYW0+CgkJcHVibGljIHZvaWQgIEluc2VydFJvdyhpbnQgcm93RnJvbSwgaW50IHJvd3MsIGludCBjb3B5U3R5bGVzRnJvbVJvdykKCQl7CiAgICAgICAgICAgIENoZWNrU2hlZXRUeXBlKCk7CiAgICAgICAgICAgICAgICB2YXIgZCA9IERpbWVuc2lvbjsKCiAgICAgICAgICAgIGlmIChyb3dGcm9tIDwgMSkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgdGhyb3cgKG5ldyBBcmd1bWVudE91dE9mUmFuZ2VFeGNlcHRpb24oInJvd0Zyb20gY2FuJ3QgYmUgbGVzc2VyIHRoYXQgMSIpKTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgLy9DaGVjayB0aGF0IGNlbGxzIGFyZW4ndCBzaGlmdGVkIG91dHNpZGUgdGhlIGJvdW5kcmllcwogICAgICAgICAgICBpZiAoZCAhPSBudWxsICYmIGQuRW5kLlJvdyA+IHJvd0Zyb20gJiYgZC5FbmQuUm93ICsgcm93cyA+IEV4Y2VsUGFja2FnZS5NYXhSb3dzKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICB0aHJvdyAobmV3IEFyZ3VtZW50T3V0T2ZSYW5nZUV4Y2VwdGlvbigiQ2FuJ3QgaW5zZXJ0LiBSb3dzIHdpbGwgYmUgc2hpZnRlZCBvdXRzaWRlIHRoZSBib3VuZHJpZXMgb2YgdGhlIHdvcmtzaGVldC4iKSk7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIGxvY2sgKHRoaXMpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIF92YWx1ZXMuSW5zZXJ0KHJvd0Zyb20sIDAsIHJvd3MsIDApOwogICAgICAgICAgICAgICAgX2Zvcm11bGFzLkluc2VydChyb3dGcm9tLCAwLCByb3dzLCAwKTsKICAgICAgICAgICAgICAgIF9zdHlsZXMuSW5zZXJ0KHJvd0Zyb20sIDAsIHJvd3MsIDApOwogICAgICAgICAgICAgICAgX3R5cGVzLkluc2VydChyb3dGcm9tLCAwLCByb3dzLCAwKTsKICAgICAgICAgICAgICAgIF9jb21tZW50c1N0b3JlLkluc2VydChyb3dGcm9tLCAwLCByb3dzLCAwKTsKICAgICAgICAgICAgICAgIF9oeXBlckxpbmtzLkluc2VydChyb3dGcm9tLCAwLCByb3dzLCAwKTsKICAgICAgICAgICAgICAgIF9mbGFncy5JbnNlcnQocm93RnJvbSwgMCwgcm93cywgMCk7CgogICAgICAgICAgICAgICAgZm9yZWFjaCAodmFyIGYgaW4gX3NoYXJlZEZvcm11bGFzLlZhbHVlcykKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICBpZiAoZi5TdGFydFJvdyA+PSByb3dGcm9tKSBmLlN0YXJ0Um93ICs9IHJvd3M7CiAgICAgICAgICAgICAgICAgICAgdmFyIGEgPSBuZXcgRXhjZWxBZGRyZXNzQmFzZShmLkFkZHJlc3MpOwogICAgICAgICAgICAgICAgICAgIGlmIChhLl9mcm9tUm93ID49IHJvd0Zyb20pCiAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICBhLl9mcm9tUm93ICs9IHJvd3M7CiAgICAgICAgICAgICAgICAgICAgICAgIGEuX3RvUm93ICs9IHJvd3M7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIGVsc2UgaWYgKGEuX3RvUm93ID49IHJvd0Zyb20pCiAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICBhLl90b1JvdyArPSByb3dzOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICBmLkFkZHJlc3MgPSBFeGNlbEFkZHJlc3NCYXNlLkdldEFkZHJlc3MoYS5fZnJvbVJvdywgYS5fZnJvbUNvbCwgYS5fdG9Sb3csIGEuX3RvQ29sKTsKICAgICAgICAgICAgICAgICAgICBmLkZvcm11bGEgPSBFeGNlbENlbGxCYXNlLlVwZGF0ZUZvcm11bGFSZWZlcmVuY2VzKGYuRm9ybXVsYSwgcm93cywgMCwgcm93RnJvbSwgMCk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB2YXIgY3NlID0gbmV3IENlbGxzU3RvcmVFbnVtZXJhdG9yPG9iamVjdD4oX2Zvcm11bGFzKTsKICAgICAgICAgICAgICAgIHdoaWxlIChjc2UuTmV4dCgpKQogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIGlmIChjc2UuVmFsdWUgaXMgc3RyaW5nKQogICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgY3NlLlZhbHVlID0gRXhjZWxDZWxsQmFzZS5VcGRhdGVGb3JtdWxhUmVmZXJlbmNlcyhjc2UuVmFsdWUuVG9TdHJpbmcoKSwgcm93cywgMCwgcm93RnJvbSwgMCk7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgIEZpeE1lcmdlZENlbGxzUm93KHJvd0Zyb20sIHJvd3MsIGZhbHNlKTsKICAgICAgICAgICAgICAgIGlmIChjb3B5U3R5bGVzRnJvbVJvdyA+IDApCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgdmFyIGNzZVMgPSBuZXcgQ2VsbHNTdG9yZUVudW1lcmF0b3I8aW50Pihfc3R5bGVzLCBjb3B5U3R5bGVzRnJvbVJvdywgMCwgY29weVN0eWxlc0Zyb21Sb3csIEV4Y2VsUGFja2FnZS5NYXhDb2x1bW5zKTsgLy9GaXhlcyBpc3N1ZSAxNTA2OCAsIDE1MDkwCiAgICAgICAgICAgICAgICAgICAgd2hpbGUoY3NlUy5OZXh0KCkpCiAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICBmb3IgKHZhciByID0gMDsgciA8IHJvd3M7IHIrKykKICAgICAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgX3N0eWxlcy5TZXRWYWx1ZShyb3dGcm9tICsgciwgY3NlUy5Db2x1bW4sIGNzZVMuVmFsdWUpOwogICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgZm9yZWFjaCAodmFyIHRibCBpbiBUYWJsZXMpCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgdGJsLkFkZHJlc3MgPSB0YmwuQWRkcmVzcy5BZGRSb3cocm93RnJvbSwgcm93cyk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgLy8vIDxzdW1tYXJ5PgogICAgICAgIC8vLyBJbnNlcnRzIGEgbmV3IGNvbHVtbiBpbnRvIHRoZSBzcHJlYWRzaGVldC4gIEV4aXN0aW5nIGNvbHVtbnMgYmVsb3cgdGhlIHBvc2l0aW9uIGFyZSAKICAgICAgICAvLy8gc2hpZnRlZCBkb3duLiAgQWxsIGZvcm11bGEgYXJlIHVwZGF0ZWQgdG8gdGFrZSBhY2NvdW50IG9mIHRoZSBuZXcgY29sdW1uLgogICAgICAgIC8vLyA8L3N1bW1hcnk+CiAgICAgICAgLy8vIDxwYXJhbSBuYW1lPSJjb2x1bW5Gcm9tIj5UaGUgcG9zaXRpb24gb2YgdGhlIG5ldyBjb2x1bW48L3BhcmFtPgogICAgICAgIC8vLyA8cGFyYW0gbmFtZT0iY29sdW1ucyI+TnVtYmVyIG9mIGNvbHVtbnMgdG8gaW5zZXJ0PC9wYXJhbT4gICAgICAgIAogICAgICAgIHB1YmxpYyB2b2lkIEluc2VydENvbHVtbihpbnQgY29sdW1uRnJvbSwgaW50IGNvbHVtbnMpCiAgICAgICAgewogICAgICAgICAgICBJbnNlcnRDb2x1bW4oY29sdW1uRnJvbSwgY29sdW1ucywgMCk7CiAgICAgICAgfQogICAgICAgIC8vLzxzdW1tYXJ5PgogICAgICAgIC8vLyBJbnNlcnRzIGEgbmV3IGNvbHVtbiBpbnRvIHRoZSBzcHJlYWRzaGVldC4gIEV4aXN0aW5nIGNvbHVtbiB0byB0aGUgbGVmdCBhcmUgCiAgICAgICAgLy8vIHNoaWZ0ZWQuICBBbGwgZm9ybXVsYSBhcmUgdXBkYXRlZCB0byB0YWtlIGFjY291bnQgb2YgdGhlIG5ldyBjb2x1bW4uCiAgICAgICAgLy8vIDwvc3VtbWFyeT4KICAgICAgICAvLy8gPHBhcmFtIG5hbWU9ImNvbHVtbkZyb20iPlRoZSBwb3NpdGlvbiBvZiB0aGUgbmV3IGNvbHVtbjwvcGFyYW0+CiAgICAgICAgLy8vIDxwYXJhbSBuYW1lPSJjb2x1bW5zIj5OdW1iZXIgb2YgY29sdW1ucyB0byBpbnNlcnQuPC9wYXJhbT4KICAgICAgICAvLy8gPHBhcmFtIG5hbWU9ImNvcHlTdHlsZXNGcm9tQ29sdW1uIj5Db3B5IFN0eWxlcyBmcm9tIHRoaXMgY29sdW1uLiBBcHBsaWVkIHRvIGFsbCBpbnNlcnRlZCBjb2x1bW5zPC9wYXJhbT4KICAgICAgICBwdWJsaWMgdm9pZCBJbnNlcnRDb2x1bW4oaW50IGNvbHVtbkZyb20sIGludCBjb2x1bW5zLCBpbnQgY29weVN0eWxlc0Zyb21Db2x1bW4pCiAgICAgICAgewogICAgICAgICAgICBDaGVja1NoZWV0VHlwZSgpOwogICAgICAgICAgICB2YXIgZCA9IERpbWVuc2lvbjsKCiAgICAgICAgICAgIGlmIChjb2x1bW5Gcm9tIDwgMSkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgdGhyb3cgKG5ldyBBcmd1bWVudE91dE9mUmFuZ2VFeGNlcHRpb24oImNvbHVtbkZyb20gY2FuJ3QgYmUgbGVzc2VyIHRoYXQgMSIpKTsKICAgICAgICAgICAgfSAgICAgICAgICAgIAogICAgICAgICAgICAvL0NoZWNrIHRoYXQgY2VsbHMgYXJlbid0IHNoaWZ0ZWQgb3V0c2lkZSB0aGUgYm91bmRyaWVzCiAgICAgICAgICAgIGlmIChkICE9IG51bGwgJiYgZC5FbmQuQ29sdW1uID4gY29sdW1uRnJvbSAmJiBkLkVuZC5Db2x1bW4gKyBjb2x1bW5zID4gRXhjZWxQYWNrYWdlLk1heENvbHVtbnMpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIHRocm93IChuZXcgQXJndW1lbnRPdXRPZlJhbmdlRXhjZXB0aW9uKCJDYW4ndCBpbnNlcnQuIENvbHVtbnMgd2lsbCBiZSBzaGlmdGVkIG91dHNpZGUgdGhlIGJvdW5kcmllcyBvZiB0aGUgd29ya3NoZWV0LiIpKTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgbG9jayAodGhpcykKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgX3ZhbHVlcy5JbnNlcnQoMCwgY29sdW1uRnJvbSwgMCwgY29sdW1ucyk7CiAgICAgICAgICAgICAgICBfZm9ybXVsYXMuSW5zZXJ0KDAsIGNvbHVtbkZyb20sIDAsIGNvbHVtbnMpOwogICAgICAgICAgICAgICAgX3N0eWxlcy5JbnNlcnQoMCwgY29sdW1uRnJvbSwgMCwgY29sdW1ucyk7CiAgICAgICAgICAgICAgICBfdHlwZXMuSW5zZXJ0KDAsIGNvbHVtbkZyb20sIDAsIGNvbHVtbnMpOwogICAgICAgICAgICAgICAgX2NvbW1lbnRzU3RvcmUuSW5zZXJ0KDAsIGNvbHVtbkZyb20sIDAsIGNvbHVtbnMpOwogICAgICAgICAgICAgICAgX2h5cGVyTGlua3MuSW5zZXJ0KDAsIGNvbHVtbkZyb20sIDAsIGNvbHVtbnMpOwogICAgICAgICAgICAgICAgX2ZsYWdzLkluc2VydCgwLCBjb2x1bW5Gcm9tLCAwLCBjb2x1bW5zKTsKCiAgICAgICAgICAgICAgICBmb3JlYWNoICh2YXIgZiBpbiBfc2hhcmVkRm9ybXVsYXMuVmFsdWVzKQogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIGlmIChmLlN0YXJ0Q29sID49IGNvbHVtbkZyb20pIGYuU3RhcnRDb2wgKz0gY29sdW1uczsKICAgICAgICAgICAgICAgICAgICB2YXIgYSA9IG5ldyBFeGNlbEFkZHJlc3NCYXNlKGYuQWRkcmVzcyk7CiAgICAgICAgICAgICAgICAgICAgaWYgKGEuX2Zyb21Db2wgPj0gY29sdW1uRnJvbSkKICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgIGEuX2Zyb21Db2wgKz0gY29sdW1uczsKICAgICAgICAgICAgICAgICAgICAgICAgYS5fdG9Db2wgKz0gY29sdW1uczsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgZWxzZSBpZiAoYS5fdG9Db2wgPj0gY29sdW1uRnJvbSkKICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgIGEuX3RvQ29sICs9IGNvbHVtbnM7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIGYuQWRkcmVzcyA9IEV4Y2VsQWRkcmVzc0Jhc2UuR2V0QWRkcmVzcyhhLl9mcm9tUm93LCBhLl9mcm9tQ29sLCBhLl90b1JvdywgYS5fdG9Db2wpOwogICAgICAgICAgICAgICAgICAgIGYuRm9ybXVsYSA9IEV4Y2VsQ2VsbEJhc2UuVXBkYXRlRm9ybXVsYVJlZmVyZW5jZXMoZi5Gb3JtdWxhLCAwLCBjb2x1bW5zLCAwLCBjb2x1bW5Gcm9tKTsKICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICB2YXIgY3NlID0gbmV3IENlbGxzU3RvcmVFbnVtZXJhdG9yPG9iamVjdD4oX2Zvcm11bGFzKTsKICAgICAgICAgICAgICAgIHdoaWxlIChjc2UuTmV4dCgpKQogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIGlmIChjc2UuVmFsdWUgaXMgc3RyaW5nKQogICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgY3NlLlZhbHVlID0gRXhjZWxDZWxsQmFzZS5VcGRhdGVGb3JtdWxhUmVmZXJlbmNlcyhjc2UuVmFsdWUuVG9TdHJpbmcoKSwgMCwgY29sdW1ucywgMCwgY29sdW1uRnJvbSk7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgIEZpeE1lcmdlZENlbGxzQ29sdW1uKGNvbHVtbkZyb20sIGNvbHVtbnMsIGZhbHNlKTsKCiAgICAgICAgICAgICAgICB2YXIgY3NlYyA9IG5ldyBDZWxsc1N0b3JlRW51bWVyYXRvcjxvYmplY3Q+KF92YWx1ZXMsIDAsIDEsIDAsIEV4Y2VsUGFja2FnZS5NYXhDb2x1bW5zKTsKICAgICAgICAgICAgICAgIHZhciBsc3QgPSBuZXcgTGlzdDxFeGNlbENvbHVtbj4oKTsKICAgICAgICAgICAgICAgIGZvcmVhY2ggKHZhciBjb2wgaW4gY3NlYykKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICBpZiAoY29sIGlzIEV4Y2VsQ29sdW1uKQogICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgbHN0LkFkZCgoRXhjZWxDb2x1bW4pY29sKTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgZm9yIChpbnQgaSA9IGxzdC5Db3VudC0xOyBpID49IDA7IGktLSkKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICB2YXIgYyA9IGxzdFtpXTsKICAgICAgICAgICAgICAgICAgICBpZiAoYy5fY29sdW1uTWluID49IGNvbHVtbkZyb20pCiAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICBpZiAoYy5fY29sdW1uTWluICsgY29sdW1ucyA8PSBFeGNlbFBhY2thZ2UuTWF4Q29sdW1ucykKICAgICAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgYy5fY29sdW1uTWluICs9IGNvbHVtbnM7CiAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgZWxzZQogICAgICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjLl9jb2x1bW5NaW4gPSBFeGNlbFBhY2thZ2UuTWF4Q29sdW1uczsKICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGMuX2NvbHVtbk1heCArIGNvbHVtbnMgPD0gRXhjZWxQYWNrYWdlLk1heENvbHVtbnMpCiAgICAgICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGMuX2NvbHVtbk1heCArPSBjb2x1bW5zOwogICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgICAgIGVsc2UKICAgICAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgYy5fY29sdW1uTWF4ID0gRXhjZWxQYWNrYWdlLk1heENvbHVtbnM7CiAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgZWxzZSBpZiAoYy5fY29sdW1uTWF4ID49IGNvbHVtbkZyb20pCiAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICB2YXIgY2MgPSBjLl9jb2x1bW5NYXggLSBjb2x1bW5Gcm9tOwogICAgICAgICAgICAgICAgICAgICAgICBjLl9jb2x1bW5NYXggPSBjb2x1bW5Gcm9tIC0gMTsKICAgICAgICAgICAgICAgICAgICAgICAgQ29weUNvbHVtbihjLCBjb2x1bW5Gcm9tICsgY29sdW1ucywgY29sdW1uRnJvbSArIGNvbHVtbnMgKyBjYyk7CiAgICAgICAgICAgICAgICAgICAgfSAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICB9CgoKICAgICAgICAgICAgICAgIGlmIChjb3B5U3R5bGVzRnJvbUNvbHVtbiA+IDApCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgZm9yICh2YXIgYyA9IDA7IGMgPCBjb2x1bW5zOyBjKyspCiAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICB2YXIgY29sID0gdGhpcy5Db2x1bW4oY29sdW1uRnJvbSArIGMpOwogICAgICAgICAgICAgICAgICAgICAgICBjb2wuU3R5bGVJRCA9IHRoaXMuQ29sdW1uKGNvcHlTdHlsZXNGcm9tQ29sdW1uKS5TdHlsZUlEOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIC8vQWRqdXN0IHRhYmxlcwogICAgICAgICAgICAgICAgZm9yZWFjaCAodmFyIHRibCBpbiBUYWJsZXMpCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgaWYgKGNvbHVtbkZyb20gPiB0YmwuQWRkcmVzcy5TdGFydC5Db2x1bW4gJiYgY29sdW1uRnJvbSA8PSB0YmwuQWRkcmVzcy5FbmQuQ29sdW1uKQogICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgSW5zZXJ0VGFibGVDb2x1bW5zKGNvbHVtbkZyb20sIGNvbHVtbnMsIHRibCk7CiAgICAgICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgICAgICB0YmwuQWRkcmVzcz10YmwuQWRkcmVzcy5BZGRDb2x1bW4oY29sdW1uRnJvbSwgY29sdW1ucyk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIHByaXZhdGUgc3RhdGljIHZvaWQgSW5zZXJ0VGFibGVDb2x1bW5zKGludCBjb2x1bW5Gcm9tLCBpbnQgY29sdW1ucywgRXhjZWxUYWJsZSB0YmwpCiAgICAgICAgewogICAgICAgICAgICB2YXIgbm9kZSA9IHRibC5Db2x1bW5zWzBdLlRvcE5vZGUuUGFyZW50Tm9kZTsKICAgICAgICAgICAgdmFyIGl4ID0gY29sdW1uRnJvbSAtIHRibC5BZGRyZXNzLlN0YXJ0LkNvbHVtbiAtIDE7CiAgICAgICAgICAgIHZhciBpbnNQb3MgPSBub2RlLkNoaWxkTm9kZXNbaXhdOwogICAgICAgICAgICBpeCArPSAyOwogICAgICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IGNvbHVtbnM7IGkrKykKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgdmFyIG5hbWUgPQogICAgICAgICAgICAgICAgICAgIHRibC5Db2x1bW5zLkdldFVuaXF1ZU5hbWUoc3RyaW5nLkZvcm1hdCgiQ29sdW1uezB9IiwKICAgICAgICAgICAgICAgICAgICAgICAgKGl4KyspLlRvU3RyaW5nKEN1bHR1cmVJbmZvLkludmFyaWFudEN1bHR1cmUpKSk7CiAgICAgICAgICAgICAgICBYbWxFbGVtZW50IHRhYmxlQ29sdW1uID0KICAgICAgICAgICAgICAgICAgICAoWG1sRWxlbWVudCkgdGJsLlRhYmxlWG1sLkNyZWF0ZU5vZGUoWG1sTm9kZVR5cGUuRWxlbWVudCwgInRhYmxlQ29sdW1uIiwgRXhjZWxQYWNrYWdlLnNjaGVtYU1haW4pOwogICAgICAgICAgICAgICAgdGFibGVDb2x1bW4uU2V0QXR0cmlidXRlKCJpZCIsICh0YmwuQ29sdW1ucy5Db3VudCArIGkgKyAxKS5Ub1N0cmluZyhDdWx0dXJlSW5mby5JbnZhcmlhbnRDdWx0dXJlKSk7CiAgICAgICAgICAgICAgICB0YWJsZUNvbHVtbi5TZXRBdHRyaWJ1dGUoIm5hbWUiLCBuYW1lKTsKICAgICAgICAgICAgICAgIGluc1BvcyA9IG5vZGUuSW5zZXJ0QWZ0ZXIodGFibGVDb2x1bW4sIGluc1Bvcyk7CiAgICAgICAgICAgIH0gLy9DcmVhdGUgdGJsIENvbHVtbgogICAgICAgICAgICB0YmwuX2NvbHMgPSBuZXcgRXhjZWxUYWJsZUNvbHVtbkNvbGxlY3Rpb24odGJsKTsKICAgICAgICB9CgogICAgICAgIC8vLyA8c3VtbWFyeT4KICAgICAgICAvLy8gQWRkcyBhIHZhbHVlIHRvIHRoZSByb3cgb2YgbWVyZ2VkIGNlbGxzIHRvIGZpeCBmb3IgaW5zZXJ0cyBvciBkZWxldGVzCiAgICAgICAgLy8vIDwvc3VtbWFyeT4KICAgICAgICAvLy8gPHBhcmFtIG5hbWU9InJvdyI+PC9wYXJhbT4KICAgICAgICAvLy8gPHBhcmFtIG5hbWU9InJvd3MiPjwvcGFyYW0+IAogICAgICAgIC8vLyA8cGFyYW0gbmFtZT0iZGVsZXRlIj48L3BhcmFtPgogICAgICAgIHByaXZhdGUgdm9pZCBGaXhNZXJnZWRDZWxsc1JvdyhpbnQgcm93LCBpbnQgcm93cywgYm9vbCBkZWxldGUpCiAgICAgICAgewogICAgICAgICAgICBpZiAoZGVsZXRlKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBfbWVyZ2VkQ2VsbHMuX2NlbGxzLkRlbGV0ZShyb3csIDAsIHJvd3MsIDApOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGVsc2UKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgX21lcmdlZENlbGxzLl9jZWxscy5JbnNlcnQocm93LCAwLCByb3dzLCAwKTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgTGlzdDxpbnQ+IHJlbW92ZUluZGV4ID0gbmV3IExpc3Q8aW50PigpOwogICAgICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IF9tZXJnZWRDZWxscy5Db3VudDsgaSsrKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBpZiAoIXN0cmluZy5Jc051bGxPckVtcHR5KCBfbWVyZ2VkQ2VsbHNbaV0pKQogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIEV4Y2VsQWRkcmVzc0Jhc2UgYWRkciA9IG5ldyBFeGNlbEFkZHJlc3NCYXNlKF9tZXJnZWRDZWxsc1tpXSksIG5ld0FkZHI7CiAgICAgICAgICAgICAgICAgICAgaWYgKGRlbGV0ZSkKICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgIG5ld0FkZHIgPSBhZGRyLkRlbGV0ZVJvdyhyb3csIHJvd3MpOwogICAgICAgICAgICAgICAgICAgICAgICBpZiAobmV3QWRkciA9PSBudWxsKQogICAgICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICByZW1vdmVJbmRleC5BZGQoaSk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb250aW51ZTsKICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICBlbHNlCiAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICBuZXdBZGRyID0gYWRkci5BZGRSb3cocm93LCByb3dzKTsKICAgICAgICAgICAgICAgICAgICAgICAgaWYgKG5ld0FkZHIuQWRkcmVzcyAhPSBhZGRyLkFkZHJlc3MpCiAgICAgICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgLy8gICAgX21lcmdlZENlbGxzLl9jZWxscy5JbnNlcnQocm93LCAwLCByb3dzLCAwKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIF9tZXJnZWRDZWxscy5TZXRJbmRleChuZXdBZGRyLCBpKTsKICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICAgICAgaWYgKG5ld0FkZHIuQWRkcmVzcyAhPSBhZGRyLkFkZHJlc3MpCiAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICBfbWVyZ2VkQ2VsbHMuTGlzdFtpXSA9IG5ld0FkZHIuX2FkZHJlc3M7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgICAgIGZvciAoaW50IGkgPSByZW1vdmVJbmRleC5Db3VudCAtIDE7IGkgPj0gMDsgaS0tKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBfbWVyZ2VkQ2VsbHMuTGlzdC5SZW1vdmVBdChyZW1vdmVJbmRleFtpXSk7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgLy8vIDxzdW1tYXJ5PgogICAgICAgIC8vLyBBZGRzIGEgdmFsdWUgdG8gdGhlIHJvdyBvZiBtZXJnZWQgY2VsbHMgdG8gZml4IGZvciBpbnNlcnRzIG9yIGRlbGV0ZXMKICAgICAgICAvLy8gPC9zdW1tYXJ5PgogICAgICAgIC8vLyA8cGFyYW0gbmFtZT0iY29sdW1uIj48L3BhcmFtPgogICAgICAgIC8vLyA8cGFyYW0gbmFtZT0iY29sdW1ucyI+PC9wYXJhbT4KICAgICAgICAvLy8gPHBhcmFtIG5hbWU9ImRlbGV0ZSI+PC9wYXJhbT4KICAgICAgICBwcml2YXRlIHZvaWQgRml4TWVyZ2VkQ2VsbHNDb2x1bW4oaW50IGNvbHVtbiwgaW50IGNvbHVtbnMsIGJvb2wgZGVsZXRlKQogICAgICAgIHsKICAgICAgICAgICAgaWYgKGRlbGV0ZSkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgX21lcmdlZENlbGxzLl9jZWxscy5EZWxldGUoMCwgY29sdW1uLCAwLCBjb2x1bW5zKTsKICAgICAgICAgICAgfQogICAgICAgICAgICBlbHNlCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIF9tZXJnZWRDZWxscy5fY2VsbHMuSW5zZXJ0KDAsIGNvbHVtbiwgMCwgY29sdW1ucyk7ICAgICAgICAgICAgICAgIAogICAgICAgICAgICB9CiAgICAgICAgICAgIExpc3Q8aW50PiByZW1vdmVJbmRleCA9IG5ldyBMaXN0PGludD4oKTsKICAgICAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBfbWVyZ2VkQ2VsbHMuQ291bnQ7IGkrKykKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgaWYgKCFzdHJpbmcuSXNOdWxsT3JFbXB0eShfbWVyZ2VkQ2VsbHNbaV0pKQogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIEV4Y2VsQWRkcmVzc0Jhc2UgYWRkciA9IG5ldyBFeGNlbEFkZHJlc3NCYXNlKF9tZXJnZWRDZWxsc1tpXSksIG5ld0FkZHI7CiAgICAgICAgICAgICAgICAgICAgaWYgKGRlbGV0ZSkKICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgIG5ld0FkZHIgPSBhZGRyLkRlbGV0ZUNvbHVtbihjb2x1bW4sIGNvbHVtbnMpOwogICAgICAgICAgICAgICAgICAgICAgICBpZiAobmV3QWRkciA9PSBudWxsKQogICAgICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICByZW1vdmVJbmRleC5BZGQoaSk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb250aW51ZTsKICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICBlbHNlCiAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICBuZXdBZGRyID0gYWRkci5BZGRDb2x1bW4oY29sdW1uLCBjb2x1bW5zKTsKICAgICAgICAgICAgICAgICAgICAgICAgaWYgKG5ld0FkZHIuQWRkcmVzcyAhPSBhZGRyLkFkZHJlc3MpCiAgICAgICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIF9tZXJnZWRDZWxscy5TZXRJbmRleChuZXdBZGRyLCBpKTsKICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICAgICAgaWYgKG5ld0FkZHIuQWRkcmVzcyAhPSBhZGRyLkFkZHJlc3MpCiAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICBfbWVyZ2VkQ2VsbHMuTGlzdFtpXSA9IG5ld0FkZHIuX2FkZHJlc3M7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgICAgIGZvciAoaW50IGkgPSByZW1vdmVJbmRleC5Db3VudCAtIDE7IGkgPj0gMDsgaS0tKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBfbWVyZ2VkQ2VsbHMuTGlzdC5SZW1vdmVBdChyZW1vdmVJbmRleFtpXSk7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgcHJpdmF0ZSB2b2lkIEZpeFNoYXJlZEZvcm11bGFzUm93cyhpbnQgcG9zaXRpb24sIGludCByb3dzKQogICAgICAgIHsKICAgICAgICAgICAgTGlzdDxGb3JtdWxhcz4gYWRkZWQgPSBuZXcgTGlzdDxGb3JtdWxhcz4oKTsKICAgICAgICAgICAgTGlzdDxGb3JtdWxhcz4gZGVsZXRlZCA9IG5ldyBMaXN0PEZvcm11bGFzPigpOwoKICAgICAgICAgICAgZm9yZWFjaCAoaW50IGlkIGluIF9zaGFyZWRGb3JtdWxhcy5LZXlzKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICB2YXIgZiA9IF9zaGFyZWRGb3JtdWxhc1tpZF07CiAgICAgICAgICAgICAgICBpbnQgZnJvbUNvbCwgZnJvbVJvdywgdG9Db2wsIHRvUm93OwoKICAgICAgICAgICAgICAgIEV4Y2VsQ2VsbEJhc2UuR2V0Um93Q29sRnJvbUFkZHJlc3MoZi5BZGRyZXNzLCBvdXQgZnJvbVJvdywgb3V0IGZyb21Db2wsIG91dCB0b1Jvdywgb3V0IHRvQ29sKTsKICAgICAgICAgICAgICAgIGlmIChwb3NpdGlvbiA+PSBmcm9tUm93ICYmIHBvc2l0aW9uKyhNYXRoLkFicyhyb3dzKSkgPD0gdG9Sb3cpIC8vSW5zZXJ0L2RlbGV0ZSBpcyB3aGl0aGluIHRoZSBzaGFyZSBmb3JtdWxhIGFkZHJlc3MKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICBpZiAocm93cyA+IDApIC8vSW5zZXJ0CiAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICBmLkFkZHJlc3MgPSBFeGNlbENlbGxCYXNlLkdldEFkZHJlc3MoZnJvbVJvdywgZnJvbUNvbCkgKyAiOiIgKyBFeGNlbENlbGxCYXNlLkdldEFkZHJlc3MocG9zaXRpb24gLSAxLCB0b0NvbCk7CiAgICAgICAgICAgICAgICAgICAgICAgIGlmICh0b1JvdyAhPSBmcm9tUm93KQogICAgICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBGb3JtdWxhcyBuZXdGID0gbmV3IEZvcm11bGFzKFNvdXJjZUNvZGVUb2tlbml6ZXIuRGVmYXVsdCk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBuZXdGLlN0YXJ0Q29sID0gZi5TdGFydENvbDsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5ld0YuU3RhcnRSb3cgPSBwb3NpdGlvbiArIHJvd3M7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBuZXdGLkFkZHJlc3MgPSBFeGNlbENlbGxCYXNlLkdldEFkZHJlc3MocG9zaXRpb24gKyByb3dzLCBmcm9tQ29sKSArICI6IiArIEV4Y2VsQ2VsbEJhc2UuR2V0QWRkcmVzcyh0b1JvdyArIHJvd3MsIHRvQ29sKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5ld0YuRm9ybXVsYSA9IEV4Y2VsQ2VsbEJhc2UuVHJhbnNsYXRlRnJvbVIxQzEoRXhjZWxDZWxsQmFzZS5UcmFuc2xhdGVUb1IxQzEoZi5Gb3JtdWxhLCBmLlN0YXJ0Um93LCBmLlN0YXJ0Q29sKSwgcG9zaXRpb24sIGYuU3RhcnRDb2wpOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgYWRkZWQuQWRkKG5ld0YpOwogICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIGVsc2UKICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChmcm9tUm93IC0gcm93cyA8IHRvUm93KQogICAgICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBmLkFkZHJlc3MgPSBFeGNlbENlbGxCYXNlLkdldEFkZHJlc3MoZnJvbVJvdywgZnJvbUNvbCwgdG9Sb3crcm93cywgdG9Db2wpOwogICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgICAgIGVsc2UKICAgICAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgZi5BZGRyZXNzID0gRXhjZWxDZWxsQmFzZS5HZXRBZGRyZXNzKGZyb21Sb3csIGZyb21Db2wpICsgIjoiICsgRXhjZWxDZWxsQmFzZS5HZXRBZGRyZXNzKHRvUm93ICsgcm93cywgdG9Db2wpOwogICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgZWxzZSBpZiAocG9zaXRpb24gPD0gdG9Sb3cpCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgaWYgKHJvd3MgPiAwKSAvL0luc2VydCBiZWZvcmUgc2hpZnQgZG93bgogICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgZi5TdGFydFJvdyArPSByb3dzOwogICAgICAgICAgICAgICAgICAgICAgICAvL2YuRm9ybXVsYSA9IEV4Y2VsQ2VsbC5VcGRhdGVGb3JtdWxhUmVmZXJlbmNlcyhmLkZvcm11bGEsIHJvd3MsIDAsIHBvc2l0aW9uLCAwKTsgLy9SZWNhbGMgdGhlIGNlbGxzIHBvc2l0aW9ucwogICAgICAgICAgICAgICAgICAgICAgICBmLkFkZHJlc3MgPSBFeGNlbENlbGxCYXNlLkdldEFkZHJlc3MoZnJvbVJvdyArIHJvd3MsIGZyb21Db2wpICsgIjoiICsgRXhjZWxDZWxsQmFzZS5HZXRBZGRyZXNzKHRvUm93ICsgcm93cywgdG9Db2wpOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICBlbHNlCiAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICAvL0NlbGxzW2YuQWRkcmVzc10uU2V0U2hhcmVkRm9ybXVsYUlEKGludC5NaW5WYWx1ZSk7CiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChwb3NpdGlvbiA8PSBmcm9tUm93ICYmIHBvc2l0aW9uICsgTWF0aC5BYnMocm93cykgPiB0b1JvdykgIC8vRGVsZXRlIHRoZSBmb3JtdWxhIAogICAgICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBkZWxldGVkLkFkZChmKTsKICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICAgICBlbHNlCiAgICAgICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRvUm93ID0gdG9Sb3cgKyByb3dzIDwgcG9zaXRpb24gLSAxID8gcG9zaXRpb24gLSAxIDogdG9Sb3cgKyByb3dzOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHBvc2l0aW9uIDw9IGZyb21Sb3cpCiAgICAgICAgICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZnJvbVJvdyA9IGZyb21Sb3cgKyByb3dzIDwgcG9zaXRpb24gPyBwb3NpdGlvbiA6IGZyb21Sb3cgKyByb3dzOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGYuQWRkcmVzcyA9IEV4Y2VsQ2VsbEJhc2UuR2V0QWRkcmVzcyhmcm9tUm93LCBmcm9tQ29sLCB0b1JvdywgdG9Db2wpOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgQ2VsbHNbZi5BZGRyZXNzXS5TZXRTaGFyZWRGb3JtdWxhSUQoZi5JbmRleCk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAvL2YuU3RhcnRSb3cgPSBmcm9tUm93OwoKICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vZi5Gb3JtdWxhID0gRXhjZWxDZWxsLlVwZGF0ZUZvcm11bGFSZWZlcmVuY2VzKGYuRm9ybXVsYSwgcm93cywgMCwgcG9zaXRpb24sIDApOwogICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CgogICAgICAgICAgICBBZGRGb3JtdWxhcyhhZGRlZCwgcG9zaXRpb24sIHJvd3MpOwoKICAgICAgICAgICAgLy9SZW1vdmUgZm9ybXVsYXMKICAgICAgICAgICAgZm9yZWFjaCAoRm9ybXVsYXMgZiBpbiBkZWxldGVkKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBfc2hhcmVkRm9ybXVsYXMuUmVtb3ZlKGYuSW5kZXgpOwogICAgICAgICAgICB9CgogICAgICAgICAgICAvL0ZpeCBGb3JtdWxhcwogICAgICAgICAgICBhZGRlZCA9IG5ldyBMaXN0PEZvcm11bGFzPigpOwogICAgICAgICAgICBmb3JlYWNoIChpbnQgaWQgaW4gX3NoYXJlZEZvcm11bGFzLktleXMpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIHZhciBmID0gX3NoYXJlZEZvcm11bGFzW2lkXTsKICAgICAgICAgICAgICAgIFVwZGF0ZVNoYXJlZEZvcm11bGFSb3cocmVmIGYsIHBvc2l0aW9uLCByb3dzLCByZWYgYWRkZWQpOwogICAgICAgICAgICB9CiAgICAgICAgICAgIEFkZEZvcm11bGFzKGFkZGVkLCBwb3NpdGlvbiwgcm93cyk7CiAgICAgICAgfQoKICAgICAgICBwcml2YXRlIHZvaWQgQWRkRm9ybXVsYXMoTGlzdDxGb3JtdWxhcz4gYWRkZWQsIGludCBwb3NpdGlvbiwgaW50IHJvd3MpCiAgICAgICAgewogICAgICAgICAgICAvL0FkZCBuZXcgZm9ybXVsYXMKICAgICAgICAgICAgZm9yZWFjaCAoRm9ybXVsYXMgZiBpbiBhZGRlZCkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgZi5JbmRleCA9IEdldE1heFNoYXJlRnVuY3Rpb25JbmRleChmYWxzZSk7CiAgICAgICAgICAgICAgICBfc2hhcmVkRm9ybXVsYXMuQWRkKGYuSW5kZXgsIGYpOwogICAgICAgICAgICAgICAgQ2VsbHNbZi5BZGRyZXNzXS5TZXRTaGFyZWRGb3JtdWxhSUQoZi5JbmRleCk7CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIHByaXZhdGUgdm9pZCBVcGRhdGVTaGFyZWRGb3JtdWxhUm93KHJlZiBGb3JtdWxhcyBmb3JtdWxhLCBpbnQgc3RhcnRSb3csIGludCByb3dzLCByZWYgTGlzdDxGb3JtdWxhcz4gbmV3Rm9ybXVsYXMpCiAgICAgICAgewogICAgICAgICAgICBpbnQgZnJvbVJvdyxmcm9tQ29sLCB0b1JvdywgdG9Db2w7CiAgICAgICAgICAgIGludCBuZXdGb3JtdWxhc0NvdW50ID0gbmV3Rm9ybXVsYXMuQ291bnQ7CiAgICAgICAgICAgIEV4Y2VsQ2VsbEJhc2UuR2V0Um93Q29sRnJvbUFkZHJlc3MoZm9ybXVsYS5BZGRyZXNzLCBvdXQgZnJvbVJvdywgb3V0IGZyb21Db2wsIG91dCB0b1Jvdywgb3V0IHRvQ29sKTsKICAgICAgICAgICAgLy9pbnQgcmVmU3BsaXRzID0gUmVnZXguU3BsaXQoZm9ybXVsYS5Gb3JtdWxhLCAiI1JFRiEiKS5HZXRVcHBlckJvdW5kKDApOwogICAgICAgICAgICBzdHJpbmcgZm9ybXVhbFIxQzE7CiAgICAgICAgICAgIGlmIChyb3dzID4gMCB8fCBmcm9tUm93IDw9IHN0YXJ0Um93KQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBmb3JtdWFsUjFDMSA9IEV4Y2VsUmFuZ2VCYXNlLlRyYW5zbGF0ZVRvUjFDMShmb3JtdWxhLkZvcm11bGEsIGZvcm11bGEuU3RhcnRSb3csIGZvcm11bGEuU3RhcnRDb2wpOwogICAgICAgICAgICAgICAgZm9ybXVsYS5Gb3JtdWxhID0gRXhjZWxSYW5nZUJhc2UuVHJhbnNsYXRlRnJvbVIxQzEoZm9ybXVhbFIxQzEsIGZyb21Sb3csIGZvcm11bGEuU3RhcnRDb2wpOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGVsc2UKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgZm9ybXVhbFIxQzEgPSBFeGNlbFJhbmdlQmFzZS5UcmFuc2xhdGVUb1IxQzEoZm9ybXVsYS5Gb3JtdWxhLCBmb3JtdWxhLlN0YXJ0Um93LXJvd3MsIGZvcm11bGEuU3RhcnRDb2wpOwogICAgICAgICAgICAgICAgZm9ybXVsYS5Gb3JtdWxhID0gRXhjZWxSYW5nZUJhc2UuVHJhbnNsYXRlRnJvbVIxQzEoZm9ybXVhbFIxQzEsIGZvcm11bGEuU3RhcnRSb3csIGZvcm11bGEuU3RhcnRDb2wpOwogICAgICAgICAgICB9CiAgICAgICAgICAgIC8vYm9vbCBpc1JlZiA9IGZhbHNlOwogICAgICAgICAgICAvL0Zvcm11bGFzIHJlc3RGb3JtdWxhPWZvcm11bGE7CiAgICAgICAgICAgIHN0cmluZyBwcmV2Rm9ybXVhbFIxQzEgPSBmb3JtdWFsUjFDMTsKICAgICAgICAgICAgZm9yIChpbnQgcm93ID0gZnJvbVJvdzsgcm93IDw9IHRvUm93OyByb3crKykKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgZm9yIChpbnQgY29sID0gZnJvbUNvbDsgY29sIDw9IHRvQ29sOyBjb2wrKykKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICBzdHJpbmcgbmV3Rm9ybXVsYTsKICAgICAgICAgICAgICAgICAgICBzdHJpbmcgY3VycmVudEZvcm11bGFSMUMxOwogICAgICAgICAgICAgICAgICAgIGlmIChyb3dzID4gMCB8fCByb3cgPCBzdGFydFJvdykKICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgIG5ld0Zvcm11bGEgPSBFeGNlbENlbGxCYXNlLlVwZGF0ZUZvcm11bGFSZWZlcmVuY2VzKEV4Y2VsQ2VsbEJhc2UuVHJhbnNsYXRlRnJvbVIxQzEoZm9ybXVhbFIxQzEsIHJvdywgY29sKSwgcm93cywgMCwgc3RhcnRSb3csIDApOwogICAgICAgICAgICAgICAgICAgICAgICBjdXJyZW50Rm9ybXVsYVIxQzEgPSBFeGNlbFJhbmdlQmFzZS5UcmFuc2xhdGVUb1IxQzEobmV3Rm9ybXVsYSwgcm93LCBjb2wpOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICBlbHNlCiAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICBuZXdGb3JtdWxhID0gRXhjZWxDZWxsQmFzZS5VcGRhdGVGb3JtdWxhUmVmZXJlbmNlcyhFeGNlbENlbGxCYXNlLlRyYW5zbGF0ZUZyb21SMUMxKGZvcm11YWxSMUMxLCByb3ctcm93cywgY29sKSwgcm93cywgMCwgc3RhcnRSb3csIDApOwogICAgICAgICAgICAgICAgICAgICAgICBjdXJyZW50Rm9ybXVsYVIxQzEgPSBFeGNlbFJhbmdlQmFzZS5UcmFuc2xhdGVUb1IxQzEobmV3Rm9ybXVsYSwgcm93LCBjb2wpOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICBpZiAoY3VycmVudEZvcm11bGFSMUMxICE9IHByZXZGb3JtdWFsUjFDMSkgLy9uZXdGb3JtdWxhLkNvbnRhaW5zKCIjUkVGISIpKQogICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgLy9pZiAocmVmU3BsaXRzID09IDAgfHwgUmVnZXguU3BsaXQobmV3Rm9ybXVsYSwgIiNSRUYhIikuR2V0VXBwZXJCb3VuZCgwKSAhPSByZWZTcGxpdHMpCiAgICAgICAgICAgICAgICAgICAgICAgIC8vewogICAgICAgICAgICAgICAgICAgICAgICAvL2lzUmVmID0gdHJ1ZTsKICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHJvdyA9PSBmcm9tUm93ICYmIGNvbCA9PSBmcm9tQ29sKQogICAgICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBmb3JtdWxhLkZvcm11bGEgPSBuZXdGb3JtdWxhOwogICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgICAgIGVsc2UKICAgICAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKG5ld0Zvcm11bGFzLkNvdW50ID09IG5ld0Zvcm11bGFzQ291bnQpCiAgICAgICAgICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZm9ybXVsYS5BZGRyZXNzID0gRXhjZWxDZWxsQmFzZS5HZXRBZGRyZXNzKGZvcm11bGEuU3RhcnRSb3csIGZvcm11bGEuU3RhcnRDb2wsIHJvdyAtIDEsIGNvbCk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBlbHNlCiAgICAgICAgICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbmV3Rm9ybXVsYXNbbmV3Rm9ybXVsYXMuQ291bnQgLSAxXS5BZGRyZXNzID0gRXhjZWxDZWxsQmFzZS5HZXRBZGRyZXNzKG5ld0Zvcm11bGFzW25ld0Zvcm11bGFzLkNvdW50IC0gMV0uU3RhcnRSb3csIG5ld0Zvcm11bGFzW25ld0Zvcm11bGFzLkNvdW50IC0gMV0uU3RhcnRDb2wsIHJvdyAtIDEsIGNvbCk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgICAgICAgICB2YXIgcmVmRm9ybXVsYSA9IG5ldyBGb3JtdWxhcyhTb3VyY2VDb2RlVG9rZW5pemVyLkRlZmF1bHQpOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVmRm9ybXVsYS5Gb3JtdWxhID0gbmV3Rm9ybXVsYTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlZkZvcm11bGEuU3RhcnRSb3cgPSByb3c7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICByZWZGb3JtdWxhLlN0YXJ0Q29sID0gY29sOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgbmV3Rm9ybXVsYXMuQWRkKHJlZkZvcm11bGEpOwoKICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vcmVzdEZvcm11bGEgPSBudWxsOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgcHJldkZvcm11YWxSMUMxID0gY3VycmVudEZvcm11bGFSMUMxOwogICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIC8vICAgIH0KICAgICAgICAgICAgICAgICAgICAvLyAgICBlbHNlCiAgICAgICAgICAgICAgICAgICAgLy8gICAgewogICAgICAgICAgICAgICAgICAgIC8vICAgICAgICBpc1JlZiA9IGZhbHNlOwogICAgICAgICAgICAgICAgICAgIC8vICAgIH0KICAgICAgICAgICAgICAgICAgICAvL30KICAgICAgICAgICAgICAgICAgICAvL2Vsc2UKICAgICAgICAgICAgICAgICAgICAvL3sKICAgICAgICAgICAgICAgICAgICAvLyAgICBpc1JlZiA9IGZhbHNlOwogICAgICAgICAgICAgICAgICAgIC8vfQogICAgICAgICAgICAgICAgICAgIC8vaWYgKHJlc3RGb3JtdWxhPT1udWxsKQogICAgICAgICAgICAgICAgICAgIC8vewogICAgICAgICAgICAgICAgICAgICAgICAvL2lmIChuZXdGb3JtdWxhcy5Db3VudCA9PSBuZXdGb3JtdWxhc0NvdW50KQogICAgICAgICAgICAgICAgICAgICAgICAvL3sKICAgICAgICAgICAgICAgICAgICAgICAgLy8gICAgZm9ybXVsYS5BZGRyZXNzID0gRXhjZWxDZWxsQmFzZS5HZXRBZGRyZXNzKGZvcm11bGEuU3RhcnRSb3csIGZvcm11bGEuU3RhcnRDb2wsIHJvdyAtIDEsIGNvbCk7CiAgICAgICAgICAgICAgICAgICAgICAgIC8vfQogICAgICAgICAgICAgICAgICAgICAgICAvL2Vsc2UKICAgICAgICAgICAgICAgICAgICAgICAgLy97Ci8vICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5ld0Zvcm11bGFzW25ld0Zvcm11bGFzLkNvdW50IC0gMV0uQWRkcmVzcyA9IEV4Y2VsQ2VsbEJhc2UuR2V0QWRkcmVzcyhuZXdGb3JtdWxhc1tuZXdGb3JtdWxhcy5Db3VudCAtIDFdLlN0YXJ0Um93LCBuZXdGb3JtdWxhc1swXS5TdGFydENvbCwgcm93IC0gMSwgY29sKTsKICAgICAgICAgICAgICAgICAgICAgICAgLy99CgogICAgICAgICAgICAgICAgICAgICAgICAvL3Jlc3RGb3JtdWxhID0gbmV3IEZvcm11bGFzKCk7CiAgICAgICAgICAgICAgICAgICAgICAgIC8vcmVzdEZvcm11bGEuRm9ybXVsYSA9IG5ld0Zvcm11bGE7CiAgICAgICAgICAgICAgICAgICAgICAgIC8vcmVzdEZvcm11bGEuU3RhcnRSb3cgPSByb3c7CiAgICAgICAgICAgICAgICAgICAgICAgIC8vcmVzdEZvcm11bGEuU3RhcnRDb2wgPSBjb2w7CiAgICAgICAgICAgICAgICAgICAgICAgIC8vbmV3Rm9ybXVsYXMuQWRkKHJlc3RGb3JtdWxhKTsKICAgICAgICAgICAgICAgICAgICAvL30KICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgICAgICBpZiAocm93cyA8IDAgJiYgZm9ybXVsYS5TdGFydFJvdyA+IHN0YXJ0Um93KQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBpZiAoZm9ybXVsYS5TdGFydFJvdyArIHJvd3MgPCBzdGFydFJvdykKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICBmb3JtdWxhLlN0YXJ0Um93ID0gc3RhcnRSb3c7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBlbHNlCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgZm9ybXVsYS5TdGFydFJvdyArPSByb3dzOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgICAgIGlmIChuZXdGb3JtdWxhcy5Db3VudCA+IG5ld0Zvcm11bGFzQ291bnQpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIG5ld0Zvcm11bGFzW25ld0Zvcm11bGFzLkNvdW50IC0gMV0uQWRkcmVzcyA9IEV4Y2VsQ2VsbEJhc2UuR2V0QWRkcmVzcyhuZXdGb3JtdWxhc1tuZXdGb3JtdWxhcy5Db3VudCAtIDFdLlN0YXJ0Um93LCBuZXdGb3JtdWxhc1tuZXdGb3JtdWxhcy5Db3VudCAtIDFdLlN0YXJ0Q29sLCB0b1JvdywgdG9Db2wpOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgICNlbmRyZWdpb24KCiAgICAgICAgI3JlZ2lvbiBEZWxldGVSb3cKICAgICAgICAvLy8gPHN1bW1hcnk+CiAgICAgICAgLy8vIERlbGV0ZSB0aGUgc3BlY2lmaWVkIHJvdyBmcm9tIHRoZSB3b3Jrc2hlZXQuCiAgICAgICAgLy8vIDwvc3VtbWFyeT4KICAgICAgICAvLy8gPHBhcmFtIG5hbWU9InJvdyI+QSByb3cgdG8gYmUgZGVsZXRlZDwvcGFyYW0+CiAgICAgICAgcHVibGljIHZvaWQgRGVsZXRlUm93KGludCByb3cpCiAgICAgICAgewogICAgICAgICAgICBEZWxldGVSb3cocm93LCAxKTsKICAgICAgICB9CiAgICAgICAgLy8vIDxzdW1tYXJ5PgogICAgICAgIC8vLyBEZWxldGUgdGhlIHNwZWNpZmllZCByb3cgZnJvbSB0aGUgd29ya3NoZWV0LgogICAgICAgIC8vLyA8L3N1bW1hcnk+CiAgICAgICAgLy8vIDxwYXJhbSBuYW1lPSJyb3dGcm9tIj5UaGUgc3RhcnQgcm93PC9wYXJhbT4KICAgICAgICAvLy8gPHBhcmFtIG5hbWU9InJvd3MiPk51bWJlciBvZiByb3dzIHRvIGRlbGV0ZTwvcGFyYW0+CiAgICAgICAgcHVibGljIHZvaWQgRGVsZXRlUm93KGludCByb3dGcm9tLCBpbnQgcm93cykKICAgICAgICB7CiAgICAgICAgICAgIENoZWNrU2hlZXRUeXBlKCk7CiAgICAgICAgICAgIGlmIChyb3dGcm9tIDwgMSB8fCByb3dGcm9tICsgcm93cyA+IEV4Y2VsUGFja2FnZS5NYXhSb3dzKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICB0aHJvdyhuZXcgQXJndW1lbnRFeGNlcHRpb24oIlJvdyBvdXQgb2YgcmFuZ2UuIFNwYW5zIGZyb20gMSB0byAiICsgRXhjZWxQYWNrYWdlLk1heFJvd3MuVG9TdHJpbmcoQ3VsdHVyZUluZm8uSW52YXJpYW50Q3VsdHVyZSkpKTsKICAgICAgICAgICAgfQogICAgICAgICAgICBsb2NrICh0aGlzKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBfdmFsdWVzLkRlbGV0ZShyb3dGcm9tLCAwLCByb3dzLCBFeGNlbFBhY2thZ2UuTWF4Q29sdW1ucyk7CiAgICAgICAgICAgICAgICBfdHlwZXMuRGVsZXRlKHJvd0Zyb20sIDAsIHJvd3MsIEV4Y2VsUGFja2FnZS5NYXhDb2x1bW5zKTsKICAgICAgICAgICAgICAgIF9mb3JtdWxhcy5EZWxldGUocm93RnJvbSwgMCwgcm93cywgRXhjZWxQYWNrYWdlLk1heENvbHVtbnMpOwogICAgICAgICAgICAgICAgX3N0eWxlcy5EZWxldGUocm93RnJvbSwgMCwgcm93cywgRXhjZWxQYWNrYWdlLk1heENvbHVtbnMpOwogICAgICAgICAgICAgICAgX2ZsYWdzLkRlbGV0ZShyb3dGcm9tLCAwLCByb3dzLCBFeGNlbFBhY2thZ2UuTWF4Q29sdW1ucyk7CiAgICAgICAgICAgICAgICBfY29tbWVudHNTdG9yZS5EZWxldGUocm93RnJvbSwgMCwgcm93cywgRXhjZWxQYWNrYWdlLk1heENvbHVtbnMpOwogICAgICAgICAgICAgICAgX2h5cGVyTGlua3MuRGVsZXRlKHJvd0Zyb20sIDAsIHJvd3MsIEV4Y2VsUGFja2FnZS5NYXhDb2x1bW5zKTsKCiAgICAgICAgICAgICAgICBBZGp1c3RGb3JtdWxhc1Jvdyhyb3dGcm9tLCByb3dzKTsKICAgICAgICAgICAgICAgIEZpeE1lcmdlZENlbGxzUm93KHJvd0Zyb20sIHJvd3MsIHRydWUpOwoKICAgICAgICAgICAgICAgIGZvcmVhY2ggKHZhciB0YmwgaW4gVGFibGVzKQogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIHRibC5BZGRyZXNzID0gdGJsLkFkZHJlc3MuRGVsZXRlUm93KHJvd0Zyb20sIHJvd3MpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIC8vLyA8c3VtbWFyeT4KICAgICAgICAvLy8gRGVsZXRlIHRoZSBzcGVjaWZpZWQgY29sdW1uIGZyb20gdGhlIHdvcmtzaGVldC4KICAgICAgICAvLy8gPC9zdW1tYXJ5PgogICAgICAgIC8vLyA8cGFyYW0gbmFtZT0iY29sdW1uIj5UaGUgY29sdW1uIHRvIGJlIGRlbGV0ZWQ8L3BhcmFtPgogICAgICAgIHB1YmxpYyB2b2lkIERlbGV0ZUNvbHVtbihpbnQgY29sdW1uKQogICAgICAgIHsKICAgICAgICAgICAgRGVsZXRlQ29sdW1uKGNvbHVtbiwxKTsKICAgICAgICB9CiAgICAgICAgLy8vIDxzdW1tYXJ5PgogICAgICAgIC8vLyBEZWxldGUgdGhlIHNwZWNpZmllZCBjb2x1bW4gZnJvbSB0aGUgd29ya3NoZWV0LgogICAgICAgIC8vLyA8L3N1bW1hcnk+CiAgICAgICAgLy8vIDxwYXJhbSBuYW1lPSJjb2x1bW5Gcm9tIj5UaGUgc3RhcnQgY29sdW1uPC9wYXJhbT4KICAgICAgICAvLy8gPHBhcmFtIG5hbWU9ImNvbHVtbnMiPk51bWJlciBvZiBjb2x1bW5zIHRvIGRlbGV0ZTwvcGFyYW0+CiAgICAgICAgcHVibGljIHZvaWQgRGVsZXRlQ29sdW1uKGludCBjb2x1bW5Gcm9tLCBpbnQgY29sdW1ucykKICAgICAgICB7CiAgICAgICAgICAgIGlmIChjb2x1bW5Gcm9tIDwgMSB8fCBjb2x1bW5Gcm9tICsgY29sdW1ucyA+IEV4Y2VsUGFja2FnZS5NYXhDb2x1bW5zKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICB0aHJvdyAobmV3IEFyZ3VtZW50RXhjZXB0aW9uKCJDb2x1bW4gb3V0IG9mIHJhbmdlLiBTcGFucyBmcm9tIDEgdG8gIiArIEV4Y2VsUGFja2FnZS5NYXhDb2x1bW5zLlRvU3RyaW5nKEN1bHR1cmVJbmZvLkludmFyaWFudEN1bHR1cmUpKSk7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgbG9jayAodGhpcykKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgdmFyIGNvbCA9IF92YWx1ZXMuR2V0VmFsdWUoMCwgY29sdW1uRnJvbSkgYXMgRXhjZWxDb2x1bW47CiAgICAgICAgICAgICAgICBpZiAoY29sID09IG51bGwpCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgdmFyIHIgPSAwOyAKICAgICAgICAgICAgICAgICAgICB2YXIgYyA9IGNvbHVtbkZyb207CiAgICAgICAgICAgICAgICAgICAgaWYoX3ZhbHVlcy5QcmV2Q2VsbChyZWYgcixyZWYgYykpCiAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICBjb2wgPSBfdmFsdWVzLkdldFZhbHVlKDAsIGMpIGFzIEV4Y2VsQ29sdW1uOwogICAgICAgICAgICAgICAgICAgICAgICBpZihjb2wuX2NvbHVtbk1heCA+PSBjb2x1bW5Gcm9tKQogICAgICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb2wuQ29sdW1uTWF4PWNvbHVtbkZyb20tMTsKICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICBfdmFsdWVzLkRlbGV0ZSgwLCBjb2x1bW5Gcm9tLCBFeGNlbFBhY2thZ2UuTWF4Um93cywgY29sdW1ucyk7CiAgICAgICAgICAgICAgICBfdHlwZXMuRGVsZXRlKDAsIGNvbHVtbkZyb20sIEV4Y2VsUGFja2FnZS5NYXhSb3dzLCBjb2x1bW5zKTsKICAgICAgICAgICAgICAgIF9mb3JtdWxhcy5EZWxldGUoMCwgY29sdW1uRnJvbSwgRXhjZWxQYWNrYWdlLk1heFJvd3MsIGNvbHVtbnMpOwogICAgICAgICAgICAgICAgX3N0eWxlcy5EZWxldGUoMCwgY29sdW1uRnJvbSwgRXhjZWxQYWNrYWdlLk1heFJvd3MsIGNvbHVtbnMpOwogICAgICAgICAgICAgICAgX2ZsYWdzLkRlbGV0ZSgwLCBjb2x1bW5Gcm9tLCBFeGNlbFBhY2thZ2UuTWF4Um93cywgY29sdW1ucyk7CiAgICAgICAgICAgICAgICBfY29tbWVudHNTdG9yZS5EZWxldGUoMCwgY29sdW1uRnJvbSwgRXhjZWxQYWNrYWdlLk1heFJvd3MsIGNvbHVtbnMpOwogICAgICAgICAgICAgICAgX2h5cGVyTGlua3MuRGVsZXRlKDAsIGNvbHVtbkZyb20sIEV4Y2VsUGFja2FnZS5NYXhSb3dzLCBjb2x1bW5zKTsKCiAgICAgICAgICAgICAgICBBZGp1c3RGb3JtdWxhc0NvbHVtbihjb2x1bW5Gcm9tLCBjb2x1bW5zKTsKICAgICAgICAgICAgICAgIEZpeE1lcmdlZENlbGxzQ29sdW1uKGNvbHVtbkZyb20sIGNvbHVtbnMsIHRydWUpOwoKICAgICAgICAgICAgICAgIHZhciBjc2VjID0gbmV3IENlbGxzU3RvcmVFbnVtZXJhdG9yPG9iamVjdD4oX3ZhbHVlcywgMCwgY29sdW1uRnJvbSwgMCwgRXhjZWxQYWNrYWdlLk1heENvbHVtbnMpOwogICAgICAgICAgICAgICAgZm9yZWFjaCAodmFyIGNvbHVtbiBpbiBjc2VjKSAgICAKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICBpZiAoY29sdW1uIGlzIEV4Y2VsQ29sdW1uKQogICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgdmFyIGMgPSAoRXhjZWxDb2x1bW4pY29sdW1uOwogICAgICAgICAgICAgICAgICAgICAgICBpZiAoYy5fY29sdW1uTWluID49IGNvbHVtbkZyb20pCiAgICAgICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGMuX2NvbHVtbk1pbiAtPSBjb2x1bW5zOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgYy5fY29sdW1uTWF4IC09IGNvbHVtbnM7CiAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgZm9yZWFjaCAodmFyIHRibCBpbiBUYWJsZXMpCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgaWYgKGNvbHVtbkZyb20gPj0gdGJsLkFkZHJlc3MuU3RhcnQuQ29sdW1uICYmIGNvbHVtbkZyb20gPD0gdGJsLkFkZHJlc3MuRW5kLkNvbHVtbikKICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgIHZhciBub2RlID0gdGJsLkNvbHVtbnNbMF0uVG9wTm9kZS5QYXJlbnROb2RlOwogICAgICAgICAgICAgICAgICAgICAgICB2YXIgaXggPSBjb2x1bW5Gcm9tIC0gdGJsLkFkZHJlc3MuU3RhcnQuQ29sdW1uOwogICAgICAgICAgICAgICAgICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IGNvbHVtbnM7IGkrKykKICAgICAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKG5vZGUuQ2hpbGROb2Rlcy5Db3VudCA+IGl4KQogICAgICAgICAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5vZGUuUmVtb3ZlQ2hpbGQobm9kZS5DaGlsZE5vZGVzW2l4XSk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgICAgIH0gCiAgICAgICAgICAgICAgICAgICAgICAgIHRibC5fY29scyA9IG5ldyBFeGNlbFRhYmxlQ29sdW1uQ29sbGVjdGlvbih0YmwpOwogICAgICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICAgICAgdGJsLkFkZHJlc3MgPSB0YmwuQWRkcmVzcy5EZWxldGVDb2x1bW4oY29sdW1uRnJvbSwgY29sdW1ucyk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgaW50ZXJuYWwgdm9pZCBBZGp1c3RGb3JtdWxhc1JvdyhpbnQgcm93RnJvbSwgaW50IHJvd3MpCiAgICAgICAgewogICAgICAgICAgICB2YXIgZGVsU0YgPSBuZXcgTGlzdDxpbnQ+KCk7CiAgICAgICAgICAgIGZvcmVhY2ggKHZhciBzZiBpbiBfc2hhcmVkRm9ybXVsYXMuVmFsdWVzKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICB2YXIgYSA9IG5ldyBFeGNlbEFkZHJlc3Moc2YuQWRkcmVzcykuRGVsZXRlUm93KHJvd0Zyb20sIHJvd3MpOwogICAgICAgICAgICAgICAgaWYgKGE9PW51bGwpCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgZGVsU0YuQWRkKHNmLkluZGV4KTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGVsc2UKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICBzZi5BZGRyZXNzID0gYS5BZGRyZXNzOwogICAgICAgICAgICAgICAgICAgIGlmIChzZi5TdGFydFJvdyA+IHJvd0Zyb20pCiAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICB2YXIgciA9IE1hdGguTWluKHNmLlN0YXJ0Um93IC0gcm93RnJvbSwgcm93cyk7CiAgICAgICAgICAgICAgICAgICAgICAgIHNmLkZvcm11bGEgPSBFeGNlbENlbGxCYXNlLlVwZGF0ZUZvcm11bGFSZWZlcmVuY2VzKHNmLkZvcm11bGEsIC1yLCAwLCByb3dGcm9tLCAwKTsKICAgICAgICAgICAgICAgICAgICAgICAgc2YuU3RhcnRSb3cgLT0gcjsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICAgICAgZm9yZWFjaCAodmFyIGl4IGluIGRlbFNGKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBfc2hhcmVkRm9ybXVsYXMuUmVtb3ZlKGl4KTsKICAgICAgICAgICAgfQogICAgICAgICAgICBkZWxTRiA9IG51bGw7CiAgICAgICAgICAgIHZhciBjc2UgPSBuZXcgQ2VsbHNTdG9yZUVudW1lcmF0b3I8b2JqZWN0PihfZm9ybXVsYXMsIDEsIDEsIEV4Y2VsUGFja2FnZS5NYXhSb3dzLCBFeGNlbFBhY2thZ2UuTWF4Q29sdW1ucyk7CiAgICAgICAgICAgIHdoaWxlIChjc2UuTmV4dCgpKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBpZiAoY3NlLlZhbHVlIGlzIHN0cmluZykKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICBjc2UuVmFsdWUgPSBFeGNlbENlbGxCYXNlLlVwZGF0ZUZvcm11bGFSZWZlcmVuY2VzKGNzZS5WYWx1ZS5Ub1N0cmluZygpLCAtcm93cywgMCwgcm93RnJvbSwgMCk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgaW50ZXJuYWwgdm9pZCBBZGp1c3RGb3JtdWxhc0NvbHVtbihpbnQgY29sdW1uRnJvbSwgaW50IGNvbHVtbnMpCiAgICAgICAgewogICAgICAgICAgICB2YXIgZGVsU0YgPSBuZXcgTGlzdDxpbnQ+KCk7CiAgICAgICAgICAgIGZvcmVhY2ggKHZhciBzZiBpbiBfc2hhcmVkRm9ybXVsYXMuVmFsdWVzKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICB2YXIgYSA9IG5ldyBFeGNlbEFkZHJlc3Moc2YuQWRkcmVzcykuRGVsZXRlQ29sdW1uKGNvbHVtbkZyb20sIGNvbHVtbnMpOwogICAgICAgICAgICAgICAgaWYgKGEgPT0gbnVsbCkKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICBkZWxTRi5BZGQoc2YuSW5kZXgpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgZWxzZQogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIHNmLkFkZHJlc3MgPSBhLkFkZHJlc3M7CiAgICAgICAgICAgICAgICAgICAgLy9zZi5Gb3JtdWxhID0gRXhjZWxDZWxsQmFzZS5VcGRhdGVGb3JtdWxhUmVmZXJlbmNlcyhzZi5Gb3JtdWxhLCAwLCAtY29sdW1ucywgMCwgY29sdW1uRnJvbSk7CiAgICAgICAgICAgICAgICAgICAgaWYgKHNmLlN0YXJ0Q29sID4gY29sdW1uRnJvbSkKICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgIHZhciBjID0gTWF0aC5NaW4oc2YuU3RhcnRDb2wgLSBjb2x1bW5Gcm9tLCBjb2x1bW5zKTsKICAgICAgICAgICAgICAgICAgICAgICAgc2YuRm9ybXVsYSA9IEV4Y2VsQ2VsbEJhc2UuVXBkYXRlRm9ybXVsYVJlZmVyZW5jZXMoc2YuRm9ybXVsYSwgMCwgLWMsIDAsIDEpOwogICAgICAgICAgICAgICAgICAgICAgICBzZi5TdGFydENvbC09IGM7CiAgICAgICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgICAgICAvL3NmLkFkZHJlc3MgPSBhLkFkZHJlc3M7CiAgICAgICAgICAgICAgICAgICAgLy9zZi5Gb3JtdWxhID0gRXhjZWxDZWxsQmFzZS5VcGRhdGVGb3JtdWxhUmVmZXJlbmNlcyhzZi5Gb3JtdWxhLCAwLC1jb2x1bW5zLDAsIGNvbHVtbkZyb20pOwogICAgICAgICAgICAgICAgICAgIC8vaWYgKHNmLlN0YXJ0Q29sID49IGNvbHVtbkZyb20pCiAgICAgICAgICAgICAgICAgICAgLy97CiAgICAgICAgICAgICAgICAgICAgLy8gICAgc2YuU3RhcnRDb2wgLT0gc2YuU3RhcnRDb2w7CiAgICAgICAgICAgICAgICAgICAgLy99CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICAgICAgZm9yZWFjaCAodmFyIGl4IGluIGRlbFNGKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBfc2hhcmVkRm9ybXVsYXMuUmVtb3ZlKGl4KTsKICAgICAgICAgICAgfQogICAgICAgICAgICBkZWxTRiA9IG51bGw7CiAgICAgICAgICAgIHZhciBjc2UgPSBuZXcgQ2VsbHNTdG9yZUVudW1lcmF0b3I8b2JqZWN0PihfZm9ybXVsYXMsIDEsIDEsICBFeGNlbFBhY2thZ2UuTWF4Um93cywgRXhjZWxQYWNrYWdlLk1heENvbHVtbnMpOwogICAgICAgICAgICB3aGlsZSAoY3NlLk5leHQoKSkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgaWYgKGNzZS5WYWx1ZSBpcyBzdHJpbmcpCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgY3NlLlZhbHVlID0gRXhjZWxDZWxsQmFzZS5VcGRhdGVGb3JtdWxhUmVmZXJlbmNlcyhjc2UuVmFsdWUuVG9TdHJpbmcoKSwgMCwgLWNvbHVtbnMsIDAsIGNvbHVtbkZyb20pOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIC8vLyA8c3VtbWFyeT4KICAgICAgICAvLy8gRGVsZXRlcyB0aGUgc3BlY2lmaWVkIHJvdyBmcm9tIHRoZSB3b3Jrc2hlZXQuCiAgICAgICAgLy8vIDwvc3VtbWFyeT4KICAgICAgICAvLy8gPHBhcmFtIG5hbWU9InJvd0Zyb20iPlRoZSBudW1iZXIgb2YgdGhlIHN0YXJ0IHJvdyB0byBiZSBkZWxldGVkPC9wYXJhbT4KICAgICAgICAvLy8gPHBhcmFtIG5hbWU9InJvd3MiPk51bWJlciBvZiByb3dzIHRvIGRlbGV0ZTwvcGFyYW0+CiAgICAgICAgLy8vIDxwYXJhbSBuYW1lPSJzaGlmdE90aGVyUm93c1VwIj5Ob3QgdXNlZC4gUm93cyBhcmUgYWx3YXlzIHNoaWZ0ZWQ8L3BhcmFtPgogICAgICAgIHB1YmxpYyB2b2lkIERlbGV0ZVJvdyhpbnQgcm93RnJvbSwgaW50IHJvd3MsIGJvb2wgc2hpZnRPdGhlclJvd3NVcCkKCQl7CiAgICAgICAgICAgIERlbGV0ZVJvdyhyb3dGcm9tLCByb3dzKTsKICAgICAgICB9CgkJI2VuZHJlZ2lvbgogICAgICAgIC8vLyA8c3VtbWFyeT4KICAgICAgICAvLy8gR2V0IHRoZSBjZWxsIHZhbHVlIGZyb20gdGh3IHdvcmtzaGVldAogICAgICAgIC8vLyA8L3N1bW1hcnk+CiAgICAgICAgLy8vIDxwYXJhbSBuYW1lPSJSb3ciPlRoZSByb3cgbnVtYmVyPC9wYXJhbT4KICAgICAgICAvLy8gPHBhcmFtIG5hbWU9IkNvbHVtbiI+VGhlIHJvdyBudW1iZXI8L3BhcmFtPgogICAgICAgIC8vLyA8cmV0dXJucz5UaGUgdmFsdWU8L3JldHVybnM+CiAgICAgICAgcHVibGljIG9iamVjdCBHZXRWYWx1ZShpbnQgUm93LCBpbnQgQ29sdW1uKQogICAgICAgIHsKICAgICAgICAgICAgQ2hlY2tTaGVldFR5cGUoKTsKICAgICAgICAgICAgLy91bG9uZyBjZWxsSUQgPSBFeGNlbENlbGxCYXNlLkdldENlbGxJRChTaGVldElELCBSb3csIENvbHVtbik7CiAgICAgICAgICAgIHZhciB2ID0gX3ZhbHVlcy5HZXRWYWx1ZShSb3csIENvbHVtbik7CiAgICAgICAgICAgIGlmICh2IT1udWxsKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAvL3ZhciBjZWxsID0gKChFeGNlbENlbGwpX2NlbGxzW2NlbGxJRF0pOwogICAgICAgICAgICAgICAgaWYgKF9mbGFncy5HZXRGbGFnVmFsdWUoUm93LCBDb2x1bW4sIENlbGxGbGFncy5SaWNoVGV4dCkpCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIChvYmplY3QpQ2VsbHNbUm93LCBDb2x1bW5dLlJpY2hUZXh0LlRleHQ7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBlbHNlCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHY7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICAgICAgZWxzZQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICByZXR1cm4gbnVsbDsKICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgLy8vIDxzdW1tYXJ5PgogICAgICAgIC8vLyBHZXQgYSBzdHJvbmdseSB0eXBlZCBjZWxsIHZhbHVlIGZyb20gdGhlIHdvcmtzaGVldAogICAgICAgIC8vLyA8L3N1bW1hcnk+CiAgICAgICAgLy8vIDx0eXBlcGFyYW0gbmFtZT0iVCI+VGhlIHR5cGU8L3R5cGVwYXJhbT4KICAgICAgICAvLy8gPHBhcmFtIG5hbWU9IlJvdyI+VGhlIHJvdyBudW1iZXI8L3BhcmFtPgogICAgICAgIC8vLyA8cGFyYW0gbmFtZT0iQ29sdW1uIj5UaGUgcm93IG51bWJlcjwvcGFyYW0+CiAgICAgICAgLy8vIDxyZXR1cm5zPlRoZSB2YWx1ZS4gSWYgdGhlIHZhbHVlIGNhbid0IGJlIGNvbnZlcnRlZCB0byB0aGUgc3BlY2lmaWVkIHR5cGUsIHRoZSBkZWZhdWx0IHZhbHVlIHdpbGwgYmUgcmV0dXJuZWQ8L3JldHVybnM+CiAgICAgICAgcHVibGljIFQgR2V0VmFsdWU8VD4oaW50IFJvdywgaW50IENvbHVtbikKICAgICAgICB7CiAgICAgICAgICAgIENoZWNrU2hlZXRUeXBlKCk7CiAgICAgICAgICAgIC8vdWxvbmcgY2VsbElEPUV4Y2VsQ2VsbEJhc2UuR2V0Q2VsbElEKFNoZWV0SUQsIFJvdywgQ29sdW1uKTsKICAgICAgICAgICAgdmFyIHYgPSBfdmFsdWVzLkdldFZhbHVlKFJvdywgQ29sdW1uKTsgICAgICAgICAgIAogICAgICAgICAgICBpZiAodj09bnVsbCkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgcmV0dXJuIGRlZmF1bHQoVCk7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIC8vdmFyIGNlbGw9KChFeGNlbENlbGwpX2NlbGxzW2NlbGxJRF0pOwogICAgICAgICAgICBpZiAoX2ZsYWdzLkdldEZsYWdWYWx1ZShSb3csIENvbHVtbiwgQ2VsbEZsYWdzLlJpY2hUZXh0KSkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgcmV0dXJuIChUKShvYmplY3QpQ2VsbHNbUm93LCBDb2x1bW5dLlJpY2hUZXh0LlRleHQ7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgZWxzZQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICByZXR1cm4gR2V0VHlwZWRWYWx1ZTxUPih2KTsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgICAgICAvL1RoYW5rcyB0byBNaWNoYWVsIFRyYW4gZm9yIHBhcnRzIG9mIHRoaXMgbWV0aG9kCiAgICAgICAgaW50ZXJuYWwgVCBHZXRUeXBlZFZhbHVlPFQ+KG9iamVjdCB2KQogICAgICAgIHsKICAgICAgICAgICAgaWYgKHYgPT0gbnVsbCkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgcmV0dXJuIGRlZmF1bHQoVCk7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgVHlwZSBmcm9tVHlwZSA9IHYuR2V0VHlwZSgpOwogICAgICAgICAgICBUeXBlIHRvVHlwZSA9IHR5cGVvZihUKTsKICAgICAgICAgICAgaWYgKGZyb21UeXBlID09IHRvVHlwZSkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgcmV0dXJuIChUKXY7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgdmFyIGNudiA9IFR5cGVEZXNjcmlwdG9yLkdldENvbnZlcnRlcihmcm9tVHlwZSk7CiAgICAgICAgICAgIGlmICh0b1R5cGUgPT0gdHlwZW9mKERhdGVUaW1lKSkgICAgLy9IYW5kbGUgZGF0ZXMKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgaWYgKGZyb21UeXBlID09IHR5cGVvZihUaW1lU3BhbikpCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgcmV0dXJuICgoVCkob2JqZWN0KShuZXcgRGF0ZVRpbWUoKChUaW1lU3Bhbil2KS5UaWNrcykpKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGVsc2UgaWYgKGZyb21UeXBlID09IHR5cGVvZihzdHJpbmcpKQogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIERhdGVUaW1lIGR0OwogICAgICAgICAgICAgICAgICAgIGlmIChEYXRlVGltZS5UcnlQYXJzZSh2LlRvU3RyaW5nKCksIG91dCBkdCkpCiAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gKFQpKG9iamVjdCkoZHQpOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICBlbHNlCiAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gZGVmYXVsdChUKTsKICAgICAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgZWxzZQogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIGlmIChjbnYuQ2FuQ29udmVydFRvKHR5cGVvZihkb3VibGUpKSkKICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiAoVCkob2JqZWN0KShEYXRlVGltZS5Gcm9tT0FEYXRlKChkb3VibGUpY252LkNvbnZlcnRUbyh2LCB0eXBlb2YoZG91YmxlKSkpKTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgZWxzZQogICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGRlZmF1bHQoVCk7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgICAgIGVsc2UgaWYgKHRvVHlwZSA9PSB0eXBlb2YoVGltZVNwYW4pKSAgICAvL0hhbmRsZSB0aW1lc3BhbgogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBpZiAoZnJvbVR5cGUgPT0gdHlwZW9mKERhdGVUaW1lKSkKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICByZXR1cm4gKChUKShvYmplY3QpKG5ldyBUaW1lU3BhbigoKERhdGVUaW1lKXYpLlRpY2tzKSkpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgZWxzZSBpZiAoZnJvbVR5cGUgPT0gdHlwZW9mKHN0cmluZykpCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgVGltZVNwYW4gdHM7CiAgICAgICAgICAgICAgICAgICAgaWYgKFRpbWVTcGFuLlRyeVBhcnNlKHYuVG9TdHJpbmcoKSwgb3V0IHRzKSkKICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiAoVCkob2JqZWN0KSh0cyk7IAogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICBlbHNlCiAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gZGVmYXVsdChUKTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBlbHNlCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgaWYgKGNudi5DYW5Db252ZXJ0VG8odHlwZW9mKGRvdWJsZSkpKQogICAgICAgICAgICAgICAgICAgIHsKCiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiAoVCkob2JqZWN0KShuZXcgVGltZVNwYW4oRGF0ZVRpbWUuRnJvbU9BRGF0ZSgoZG91YmxlKWNudi5Db252ZXJ0VG8odiwgdHlwZW9mKGRvdWJsZSkpKS5UaWNrcykpOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICBlbHNlCiAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICB0cnkKICAgICAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gSXNzdWUgMTQ2ODIgLS0gIkdldFZhbHVlPGRlY2ltYWw+KCkgd29uJ3QgY29udmVydCBzdHJpbmdzIgogICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gQXMgc3VnZ2VzdGVkLCBhZnRlciBhbGwgc3BlY2lhbCBjYXNlcywgYWxsIC5ORVQgdG8gZG8gaXQncyAKICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIHByZWZlcnJlZCBjb252ZXJzaW9uIHJhdGhlciB0aGFuIHNpbXBseSByZXR1cm5pbmcgdGhlIGRlZmF1bHQKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiAoVClDb252ZXJ0LkNoYW5nZVR5cGUodiwgdHlwZW9mKFQpKTsKICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICAgICBjYXRjaCAoRXhjZXB0aW9uKQogICAgICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBUaGlzIHdhcyB0aGUgcHJldmlvdXMgYmVoYXZpb3VyIC0tIG5vIGNvbnZlcnNpb24gaXMgYXZhaWxhYmxlLgogICAgICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGRlZmF1bHQoVCk7CiAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICAgICAgZWxzZQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBpZiAoY252LkNhbkNvbnZlcnRUbyh0b1R5cGUpKQogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIHJldHVybiAoVCljbnYuQ29udmVydFRvKHYsIHR5cGVvZihUKSk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBlbHNlCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgaWYgKHRvVHlwZS5Jc0dlbmVyaWNUeXBlICYmIHRvVHlwZS5HZXRHZW5lcmljVHlwZURlZmluaXRpb24oKS5FcXVhbHModHlwZW9mKE51bGxhYmxlPD4pKSkKICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgIHRvVHlwZSA9IE51bGxhYmxlLkdldFVuZGVybHlpbmdUeXBlKHRvVHlwZSk7CiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChjbnYuQ2FuQ29udmVydFRvKHRvVHlwZSkpCiAgICAgICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiAoVCljbnYuQ29udmVydFRvKHYsIHR5cGVvZihUKSk7CiAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgICAgIGlmKGZyb21UeXBlPT10eXBlb2YoZG91YmxlKSAmJiB0b1R5cGU9PXR5cGVvZihkZWNpbWFsKSkKICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiAoVCkob2JqZWN0KUNvbnZlcnQuVG9EZWNpbWFsKHYpOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICBlbHNlIGlmIChmcm9tVHlwZSA9PSB0eXBlb2YoZGVjaW1hbCkgJiYgdG9UeXBlID09IHR5cGVvZihkb3VibGUpKQogICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIChUKShvYmplY3QpQ29udmVydC5Ub0RvdWJsZSh2KTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgZWxzZQogICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGRlZmF1bHQoVCk7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIC8vLyA8c3VtbWFyeT4KICAgICAgICAvLy8gU2V0IHRoZSB2YWx1ZSBvZiBhIGNlbGwKICAgICAgICAvLy8gPC9zdW1tYXJ5PgogICAgICAgIC8vLyA8cGFyYW0gbmFtZT0iUm93Ij5UaGUgcm93IG51bWJlcjwvcGFyYW0+CiAgICAgICAgLy8vIDxwYXJhbSBuYW1lPSJDb2x1bW4iPlRoZSBjb2x1bW4gbnVtYmVyPC9wYXJhbT4KICAgICAgICAvLy8gPHBhcmFtIG5hbWU9IlZhbHVlIj5UaGUgdmFsdWU8L3BhcmFtPgogICAgICAgIHB1YmxpYyB2b2lkIFNldFZhbHVlKGludCBSb3csIGludCBDb2x1bW4sIG9iamVjdCBWYWx1ZSkKICAgICAgICB7CiAgICAgICAgICAgIENoZWNrU2hlZXRUeXBlKCk7CiAgICAgICAgICAgIGlmIChSb3cgPCAxIHx8IENvbHVtbiA8IDEgfHwgUm93ID4gRXhjZWxQYWNrYWdlLk1heFJvd3MgJiYgQ29sdW1uID4gRXhjZWxQYWNrYWdlLk1heENvbHVtbnMpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIHRocm93IG5ldyBBcmd1bWVudE91dE9mUmFuZ2VFeGNlcHRpb24oIlJvdyBvciBDb2x1bW4gb3V0IG9mIHJhbmdlIik7CiAgICAgICAgICAgIH0gICAgICAgICAgICAKICAgICAgICAgICAgX3ZhbHVlcy5TZXRWYWx1ZShSb3csIENvbHVtbiwgVmFsdWUpOwogICAgICAgIH0KICAgICAgICAvLy8gPHN1bW1hcnk+CiAgICAgICAgLy8vIFNldCB0aGUgdmFsdWUgb2YgYSBjZWxsCiAgICAgICAgLy8vIDwvc3VtbWFyeT4KICAgICAgICAvLy8gPHBhcmFtIG5hbWU9IkFkZHJlc3MiPlRoZSBFeGNlbCBhZGRyZXNzPC9wYXJhbT4KICAgICAgICAvLy8gPHBhcmFtIG5hbWU9IlZhbHVlIj5UaGUgdmFsdWU8L3BhcmFtPgogICAgICAgIHB1YmxpYyB2b2lkIFNldFZhbHVlKHN0cmluZyBBZGRyZXNzLCBvYmplY3QgVmFsdWUpCiAgICAgICAgewogICAgICAgICAgICBDaGVja1NoZWV0VHlwZSgpOwogICAgICAgICAgICBpbnQgcm93LCBjb2w7CiAgICAgICAgICAgIEV4Y2VsQWRkcmVzc0Jhc2UuR2V0Um93Q29sKEFkZHJlc3MsIG91dCByb3csIG91dCBjb2wsIHRydWUpOwogICAgICAgICAgICBpZiAocm93IDwgMSB8fCBjb2wgPCAxIHx8IHJvdyA+IEV4Y2VsUGFja2FnZS5NYXhSb3dzICYmIGNvbCA+IEV4Y2VsUGFja2FnZS5NYXhDb2x1bW5zKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICB0aHJvdyBuZXcgQXJndW1lbnRPdXRPZlJhbmdlRXhjZXB0aW9uKCJBZGRyZXNzIGlzIGludmFsaWQgb3Igb3V0IG9mIHJhbmdlIik7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgX3ZhbHVlcy5TZXRWYWx1ZShyb3csIGNvbCwgVmFsdWUpOyAgICAgICAgICAgCiAgICAgICAgfQoKICAgICAgICAjcmVnaW9uIE1lcmdlQ2VsbElkCgogICAgICAgIC8vLyA8c3VtbWFyeT4KICAgICAgICAvLy8gR2V0IE1lcmdlQ2VsbCBJbmRleCBObwogICAgICAgIC8vLyA8L3N1bW1hcnk+CiAgICAgICAgLy8vIDxwYXJhbSBuYW1lPSJyb3ciPjwvcGFyYW0+CiAgICAgICAgLy8vIDxwYXJhbSBuYW1lPSJjb2x1bW4iPjwvcGFyYW0+CiAgICAgICAgLy8vIDxyZXR1cm5zPjwvcmV0dXJucz4KICAgICAgICBwdWJsaWMgaW50IEdldE1lcmdlQ2VsbElkKGludCByb3csIGludCBjb2x1bW4pCiAgICAgICAgewogICAgICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IF9tZXJnZWRDZWxscy5Db3VudDsgaSsrKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgIGlmKCFzdHJpbmcuSXNOdWxsT3JFbXB0eSggX21lcmdlZENlbGxzW2ldKSkKICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIEV4Y2VsUmFuZ2UgcmFuZ2UgPSBDZWxsc1tfbWVyZ2VkQ2VsbHNbaV1dOwoKICAgICAgICAgICAgICAgICAgICBpZiAocmFuZ2UuU3RhcnQuUm93IDw9IHJvdyAmJiByb3cgPD0gcmFuZ2UuRW5kLlJvdykKICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChyYW5nZS5TdGFydC5Db2x1bW4gPD0gY29sdW1uICYmIGNvbHVtbiA8PSByYW5nZS5FbmQuQ29sdW1uKQogICAgICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gaSArIDE7CiAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICAgICAgcmV0dXJuIDA7CiAgICAgICAgfQoKICAgICAgICAjZW5kcmVnaW9uCgkJI2VuZHJlZ2lvbiAvLyBFTkQgV29ya3NoZWV0IFB1YmxpYyBNZXRob2RzCgoJCSNyZWdpb24gV29ya3NoZWV0IFByaXZhdGUgTWV0aG9kcwoKCQkjcmVnaW9uIFdvcmtzaGVldCBTYXZlCiAgICAgICAgaW50ZXJuYWwgdm9pZCBTYXZlKCkKICAgICAgICB7CiAgICAgICAgICAgICAgICBEZWxldGVQcmludGVyU2V0dGluZ3MoKTsKCiAgICAgICAgICAgICAgICBpZiAoX3dvcmtzaGVldFhtbCAhPSBudWxsKQogICAgICAgICAgICAgICAgewoKICAgICAgICAgICAgICAgICAgICBpZiAoISh0aGlzIGlzIEV4Y2VsQ2hhcnRzaGVldCkpCiAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICAvLyBzYXZlIHRoZSBoZWFkZXIgJiBmb290ZXIgKGlmIGRlZmluZWQpCiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChfaGVhZGVyRm9vdGVyICE9IG51bGwpCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBIZWFkZXJGb290ZXIuU2F2ZSgpOwoKICAgICAgICAgICAgICAgICAgICAgICAgdmFyIGQgPSBEaW1lbnNpb247CiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChkID09IG51bGwpCiAgICAgICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuRGVsZXRlQWxsTm9kZSgiZDpkaW1lbnNpb24vQHJlZiIpOwogICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgICAgIGVsc2UKICAgICAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5TZXRYbWxOb2RlU3RyaW5nKCJkOmRpbWVuc2lvbi9AcmVmIiwgZC5BZGRyZXNzKTsKICAgICAgICAgICAgICAgICAgICAgICAgfQoKCiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChEcmF3aW5ncy5Db3VudCA9PSAwKQogICAgICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAvL1JlbW92ZSBub2RlIGlmIG5vIGRyYXdpbmdzIGV4aXN0cy4KICAgICAgICAgICAgICAgICAgICAgICAgICAgIERlbGV0ZU5vZGUoImQ6ZHJhd2luZyIpOwogICAgICAgICAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgICAgICAgICBTYXZlQ29tbWVudHMoKTsKICAgICAgICAgICAgICAgICAgICAgICAgSGVhZGVyRm9vdGVyLlNhdmVIZWFkZXJGb290ZXJJbWFnZXMoKTsKICAgICAgICAgICAgICAgICAgICAgICAgU2F2ZVRhYmxlcygpOwogICAgICAgICAgICAgICAgICAgICAgICBTYXZlUGl2b3RUYWJsZXMoKTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgaWYgKERyYXdpbmdzLlVyaURyYXdpbmchPW51bGwpCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgaWYgKERyYXdpbmdzLkNvdW50ID09IDApCiAgICAgICAgICAgICAgICAgICAgeyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgIFBhcnQuRGVsZXRlUmVsYXRpb25zaGlwKERyYXdpbmdzLl9kcmF3aW5nUmVsYXRpb24uSWQpOwogICAgICAgICAgICAgICAgICAgICAgICBfcGFja2FnZS5QYWNrYWdlLkRlbGV0ZVBhcnQoRHJhd2luZ3MuVXJpRHJhd2luZyk7ICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgZWxzZQogICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgUGFja2FnaW5nLlppcFBhY2thZ2VQYXJ0IHBhcnRQYWNrID0gRHJhd2luZ3MuUGFydDsKICAgICAgICAgICAgICAgICAgICAgICAgRHJhd2luZ3MuRHJhd2luZ1htbC5TYXZlKHBhcnRQYWNrLkdldFN0cmVhbShGaWxlTW9kZS5DcmVhdGUsIEZpbGVBY2Nlc3MuV3JpdGUpKTsKICAgICAgICAgICAgICAgICAgICAgICAgZm9yZWFjaCAoRXhjZWxEcmF3aW5nIGQgaW4gRHJhd2luZ3MpCiAgICAgICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChkIGlzIEV4Y2VsQ2hhcnQpCiAgICAgICAgICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRXhjZWxDaGFydCBjID0gKEV4Y2VsQ2hhcnQpZDsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjLkNoYXJ0WG1sLlNhdmUoYy5QYXJ0LkdldFN0cmVhbShGaWxlTW9kZS5DcmVhdGUsIEZpbGVBY2Nlc3MuV3JpdGUpKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgaW50ZXJuYWwgdm9pZCBTYXZlSGFuZGxlcihaaXBPdXRwdXRTdHJlYW0gc3RyZWFtLCBDb21wcmVzc2lvbkxldmVsIGNvbXByZXNzaW9uTGV2ZWwsIHN0cmluZyBmaWxlTmFtZSkKICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgLy9Jbml0IFppcAogICAgICAgICAgICAgICAgICAgIHN0cmVhbS5Db2RlY0J1ZmZlclNpemUgPSA4MDk2OwogICAgICAgICAgICAgICAgICAgIHN0cmVhbS5Db21wcmVzc2lvbkxldmVsID0gKE9mZmljZU9wZW5YbWwuUGFja2FnaW5nLklvbmljLlpsaWIuQ29tcHJlc3Npb25MZXZlbCljb21wcmVzc2lvbkxldmVsOwogICAgICAgICAgICAgICAgICAgIHN0cmVhbS5QdXROZXh0RW50cnkoZmlsZU5hbWUpOwoKICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICBTYXZlWG1sKHN0cmVhbSk7CiAgICAgICAgfQoKICAgICAgICAKCiAgICAgICAgLy8vLy8gPHN1bW1hcnk+CiAgICAgICAgLy8vLy8gU2F2ZXMgdGhlIHdvcmtzaGVldCB0byB0aGUgcGFja2FnZS4KICAgICAgICAvLy8vLyA8L3N1bW1hcnk+CiAgICAgICAgLy9pbnRlcm5hbCB2b2lkIFNhdmUoKSAgLy8gV29ya3NoZWV0IFNhdmUKICAgICAgICAvL3sKICAgICAgICAvLyAgICBEZWxldGVQcmludGVyU2V0dGluZ3MoKTsKCiAgICAgICAgLy8gICAgaWYgKF93b3Jrc2hlZXRYbWwgIT0gbnVsbCkKICAgICAgICAvLyAgICB7CiAgICAgICAgICAgICAgICAKICAgICAgICAvLyAgICAgICAgLy8gc2F2ZSB0aGUgaGVhZGVyICYgZm9vdGVyIChpZiBkZWZpbmVkKQogICAgICAgIC8vICAgICAgICBpZiAoX2hlYWRlckZvb3RlciAhPSBudWxsKQogICAgICAgIC8vICAgICAgICAgICAgSGVhZGVyRm9vdGVyLlNhdmUoKTsKCiAgICAgICAgLy8gICAgICAgIHZhciBkID0gRGltZW5zaW9uOwogICAgICAgIC8vICAgICAgICBpZiAoZCA9PSBudWxsKQogICAgICAgIC8vICAgICAgICB7CiAgICAgICAgLy8gICAgICAgICAgICB0aGlzLkRlbGV0ZUFsbE5vZGUoImQ6ZGltZW5zaW9uL0ByZWYiKTsKICAgICAgICAvLyAgICAgICAgfQogICAgICAgIC8vICAgICAgICBlbHNlCiAgICAgICAgLy8gICAgICAgIHsKICAgICAgICAvLyAgICAgICAgICAgIHRoaXMuU2V0WG1sTm9kZVN0cmluZygiZDpkaW1lbnNpb24vQHJlZiIsIGQuQWRkcmVzcyk7CiAgICAgICAgLy8gICAgICAgIH0KICAgICAgICAgICAgICAgIAoKICAgICAgICAvLyAgICAgICAgaWYgKF9kcmF3aW5ncyAhPSBudWxsICYmIF9kcmF3aW5ncy5Db3VudCA9PSAwKQogICAgICAgIC8vICAgICAgICB7CiAgICAgICAgLy8gICAgICAgICAgICAvL1JlbW92ZSBub2RlIGlmIG5vIGRyYXdpbmdzIGV4aXN0cy4KICAgICAgICAvLyAgICAgICAgICAgIERlbGV0ZU5vZGUoImQ6ZHJhd2luZyIpOwogICAgICAgIC8vICAgICAgICB9CgogICAgICAgIC8vICAgICAgICBTYXZlQ29tbWVudHMoKTsKICAgICAgICAvLyAgICAgICAgSGVhZGVyRm9vdGVyLlNhdmVIZWFkZXJGb290ZXJJbWFnZXMoKTsKICAgICAgICAvLyAgICAgICAgU2F2ZVRhYmxlcygpOwogICAgICAgIC8vICAgICAgICBTYXZlUGl2b3RUYWJsZXMoKTsKICAgICAgICAvLyAgICAgICAgU2F2ZVhtbCgpOwogICAgICAgIC8vICAgIH0KICAgICAgICAgICAgCiAgICAgICAgLy8gICAgaWYgKERyYXdpbmdzLlVyaURyYXdpbmchPW51bGwpCiAgICAgICAgLy8gICAgewogICAgICAgIC8vICAgICAgICBpZiAoRHJhd2luZ3MuQ291bnQgPT0gMCkKICAgICAgICAvLyAgICAgICAgeyAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgLy8gICAgICAgICAgICBQYXJ0LkRlbGV0ZVJlbGF0aW9uc2hpcChEcmF3aW5ncy5fZHJhd2luZ1JlbGF0aW9uLklkKTsKICAgICAgICAvLyAgICAgICAgICAgIF9wYWNrYWdlLlBhY2thZ2UuRGVsZXRlUGFydChEcmF3aW5ncy5VcmlEcmF3aW5nKTsgICAgICAgICAgICAgICAgICAgIAogICAgICAgIC8vICAgICAgICB9CiAgICAgICAgLy8gICAgICAgIGVsc2UKICAgICAgICAvLyAgICAgICAgewogICAgICAgIC8vICAgICAgICAgICAgUGFja2FnaW5nLlppcFBhY2thZ2VQYXJ0IHBhcnRQYWNrID0gRHJhd2luZ3MuUGFydDsKICAgICAgICAvLyAgICAgICAgICAgIERyYXdpbmdzLkRyYXdpbmdYbWwuU2F2ZShwYXJ0UGFjay5HZXRTdHJlYW0oRmlsZU1vZGUuQ3JlYXRlLCBGaWxlQWNjZXNzLldyaXRlKSk7CiAgICAgICAgLy8gICAgICAgICAgICBmb3JlYWNoIChFeGNlbERyYXdpbmcgZCBpbiBEcmF3aW5ncykKICAgICAgICAvLyAgICAgICAgICAgIHsKICAgICAgICAvLyAgICAgICAgICAgICAgICBpZiAoZCBpcyBFeGNlbENoYXJ0KQogICAgICAgIC8vICAgICAgICAgICAgICAgIHsKICAgICAgICAvLyAgICAgICAgICAgICAgICAgICAgRXhjZWxDaGFydCBjID0gKEV4Y2VsQ2hhcnQpZDsKICAgICAgICAvLyAgICAgICAgICAgICAgICAgICAgYy5DaGFydFhtbC5TYXZlKGMuUGFydC5HZXRTdHJlYW0oRmlsZU1vZGUuQ3JlYXRlLCBGaWxlQWNjZXNzLldyaXRlKSk7CiAgICAgICAgLy8gICAgICAgICAgICAgICAgfQogICAgICAgIC8vICAgICAgICAgICAgfQogICAgICAgIC8vICAgICAgICB9CiAgICAgICAgLy8gICAgfQogICAgICAgIC8vfQoKICAgICAgICAvLy8gPHN1bW1hcnk+CiAgICAgICAgLy8vIERlbGV0ZSB0aGUgcHJpbnRlcnNldHRpbmdzIHJlbGF0aW9uc2hpcCBhbmQgcGFydC4KICAgICAgICAvLy8gPC9zdW1tYXJ5PgogICAgICAgIHByaXZhdGUgdm9pZCBEZWxldGVQcmludGVyU2V0dGluZ3MoKQogICAgICAgIHsKICAgICAgICAgICAgLy9EZWxldGUgdGhlIHJlbGF0aW9uc2hpcCBmcm9tIHRoZSBwYWdlU2V0dXAgdGFnCiAgICAgICAgICAgIFhtbEF0dHJpYnV0ZSBhdHRyID0gKFhtbEF0dHJpYnV0ZSlXb3Jrc2hlZXRYbWwuU2VsZWN0U2luZ2xlTm9kZSgiLy9kOnBhZ2VTZXR1cC9AcjppZCIsIE5hbWVTcGFjZU1hbmFnZXIpOwogICAgICAgICAgICBpZiAoYXR0ciAhPSBudWxsKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBzdHJpbmcgcmVsSUQgPSBhdHRyLlZhbHVlOwogICAgICAgICAgICAgICAgLy9GaXJzdCBkZWxldGUgdGhlIGF0dHJpYnV0ZSBmcm9tIHRoZSBYTUwKICAgICAgICAgICAgICAgIGF0dHIuT3duZXJFbGVtZW50LkF0dHJpYnV0ZXMuUmVtb3ZlKGF0dHIpOwogICAgICAgICAgICAgICAgaWYoUGFydC5SZWxhdGlvbnNoaXBFeGlzdHMocmVsSUQpKQogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIHZhciByZWwgPSBQYXJ0LkdldFJlbGF0aW9uc2hpcChyZWxJRCk7CiAgICAgICAgICAgICAgICAgICAgVXJpIHByaW50ZXJTZXR0aW5nc1VyaSA9IFVyaUhlbHBlci5SZXNvbHZlUGFydFVyaShyZWwuU291cmNlVXJpLCByZWwuVGFyZ2V0VXJpKTsKICAgICAgICAgICAgICAgICAgICBQYXJ0LkRlbGV0ZVJlbGF0aW9uc2hpcChyZWwuSWQpOwoKICAgICAgICAgICAgICAgICAgICAvL0RlbGV0ZSB0aGUgcGFydCBmcm9tIHRoZSBwYWNrYWdlCiAgICAgICAgICAgICAgICAgICAgaWYoX3BhY2thZ2UuUGFja2FnZS5QYXJ0RXhpc3RzKHByaW50ZXJTZXR0aW5nc1VyaSkpCiAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICBfcGFja2FnZS5QYWNrYWdlLkRlbGV0ZVBhcnQocHJpbnRlclNldHRpbmdzVXJpKTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgcHJpdmF0ZSB2b2lkIFNhdmVDb21tZW50cygpCiAgICAgICAgewogICAgICAgICAgICBpZiAoX2NvbW1lbnRzICE9IG51bGwpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIGlmIChfY29tbWVudHMuQ291bnQgPT0gMCkKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICBpZiAoX2NvbW1lbnRzLlVyaSAhPSBudWxsKQogICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgUGFydC5EZWxldGVSZWxhdGlvbnNoaXAoX2NvbW1lbnRzLlJlbElkKTsKICAgICAgICAgICAgICAgICAgICAgICAgX3BhY2thZ2UuUGFja2FnZS5EZWxldGVQYXJ0KF9jb21tZW50cy5VcmkpOyAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICBSZW1vdmVMZWdhY3lEcmF3aW5nUmVsKFZtbERyYXdpbmdzQ29tbWVudHMuUmVsSWQpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgZWxzZQogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIGlmIChfY29tbWVudHMuVXJpID09IG51bGwpCiAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICBfY29tbWVudHMuVXJpPW5ldyBVcmkoc3RyaW5nLkZvcm1hdChAIi94bC9jb21tZW50c3swfS54bWwiLCBTaGVldElEKSwgVXJpS2luZC5SZWxhdGl2ZSk7ICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIGlmKF9jb21tZW50cy5QYXJ0PT1udWxsKQogICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgX2NvbW1lbnRzLlBhcnQgPSBfcGFja2FnZS5QYWNrYWdlLkNyZWF0ZVBhcnQoX2NvbW1lbnRzLlVyaSwgImFwcGxpY2F0aW9uL3ZuZC5vcGVueG1sZm9ybWF0cy1vZmZpY2Vkb2N1bWVudC5zcHJlYWRzaGVldG1sLmNvbW1lbnRzK3htbCIsIF9wYWNrYWdlLkNvbXByZXNzaW9uKTsKICAgICAgICAgICAgICAgICAgICAgICAgdmFyIHJlbCA9IFBhcnQuQ3JlYXRlUmVsYXRpb25zaGlwKFVyaUhlbHBlci5HZXRSZWxhdGl2ZVVyaShXb3Jrc2hlZXRVcmksIF9jb21tZW50cy5VcmkpLCBQYWNrYWdpbmcuVGFyZ2V0TW9kZS5JbnRlcm5hbCwgRXhjZWxQYWNrYWdlLnNjaGVtYVJlbGF0aW9uc2hpcHMrIi9jb21tZW50cyIpOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICBfY29tbWVudHMuQ29tbWVudFhtbC5TYXZlKF9jb21tZW50cy5QYXJ0LkdldFN0cmVhbShGaWxlTW9kZS5DcmVhdGUpKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQoKICAgICAgICAgICAgaWYgKF92bWxEcmF3aW5ncyAhPSBudWxsKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBpZiAoX3ZtbERyYXdpbmdzLkNvdW50ID09IDApCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgaWYgKF92bWxEcmF3aW5ncy5VcmkgIT0gbnVsbCkKICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgIFBhcnQuRGVsZXRlUmVsYXRpb25zaGlwKF92bWxEcmF3aW5ncy5SZWxJZCk7CiAgICAgICAgICAgICAgICAgICAgICAgIF9wYWNrYWdlLlBhY2thZ2UuRGVsZXRlUGFydChfdm1sRHJhd2luZ3MuVXJpKTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBlbHNlCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgaWYgKF92bWxEcmF3aW5ncy5VcmkgPT0gbnVsbCkKICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgIF92bWxEcmF3aW5ncy5VcmkgPSBYbWxIZWxwZXIuR2V0TmV3VXJpKF9wYWNrYWdlLlBhY2thZ2UsIEAiL3hsL2RyYXdpbmdzL3ZtbERyYXdpbmd7MH0udm1sIik7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIGlmIChfdm1sRHJhd2luZ3MuUGFydCA9PSBudWxsKQogICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgX3ZtbERyYXdpbmdzLlBhcnQgPSBfcGFja2FnZS5QYWNrYWdlLkNyZWF0ZVBhcnQoX3ZtbERyYXdpbmdzLlVyaSwgImFwcGxpY2F0aW9uL3ZuZC5vcGVueG1sZm9ybWF0cy1vZmZpY2Vkb2N1bWVudC52bWxEcmF3aW5nIiwgX3BhY2thZ2UuQ29tcHJlc3Npb24pOwogICAgICAgICAgICAgICAgICAgICAgICB2YXIgcmVsID0gUGFydC5DcmVhdGVSZWxhdGlvbnNoaXAoVXJpSGVscGVyLkdldFJlbGF0aXZlVXJpKFdvcmtzaGVldFVyaSwgX3ZtbERyYXdpbmdzLlVyaSksIFBhY2thZ2luZy5UYXJnZXRNb2RlLkludGVybmFsLCBFeGNlbFBhY2thZ2Uuc2NoZW1hUmVsYXRpb25zaGlwcyArICIvdm1sRHJhd2luZyIpOwogICAgICAgICAgICAgICAgICAgICAgICBTZXRYbWxOb2RlU3RyaW5nKCJkOmxlZ2FjeURyYXdpbmcvQHI6aWQiLCByZWwuSWQpOwogICAgICAgICAgICAgICAgICAgICAgICBfdm1sRHJhd2luZ3MuUmVsSWQgPSByZWwuSWQ7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIF92bWxEcmF3aW5ncy5WbWxEcmF3aW5nWG1sLlNhdmUoX3ZtbERyYXdpbmdzLlBhcnQuR2V0U3RyZWFtKCkpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIC8vLyA8c3VtbWFyeT4KICAgICAgICAvLy8gU2F2ZSBhbGwgdGFibGUgZGF0YQogICAgICAgIC8vLyA8L3N1bW1hcnk+CiAgICAgICAgcHJpdmF0ZSB2b2lkIFNhdmVUYWJsZXMoKQogICAgICAgIHsKICAgICAgICAgICAgZm9yZWFjaCAodmFyIHRibCBpbiBUYWJsZXMpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIGlmICh0YmwuU2hvd0hlYWRlciB8fCB0YmwuU2hvd1RvdGFsKQogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIGludCBjb2xOdW0gPSB0YmwuQWRkcmVzcy5fZnJvbUNvbDsKICAgICAgICAgICAgICAgICAgICB2YXIgY29sVmFsID0gbmV3IEhhc2hTZXQ8c3RyaW5nPigpOwogICAgICAgICAgICAgICAgICAgIGZvcmVhY2ggKHZhciBjb2wgaW4gdGJsLkNvbHVtbnMpCiAgICAgICAgICAgICAgICAgICAgeyAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICBzdHJpbmcgbj1jb2wuTmFtZS5Ub0xvd2VyKEN1bHR1cmVJbmZvLkludmFyaWFudEN1bHR1cmUpOwogICAgICAgICAgICAgICAgICAgICAgICBpZiAodGJsLlNob3dIZWFkZXIpCiAgICAgICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIG4gPSB0YmwuV29ya1NoZWV0LkdldFZhbHVlPHN0cmluZz4odGJsLkFkZHJlc3MuX2Zyb21Sb3csCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGJsLkFkZHJlc3MuX2Zyb21Db2wgKyBjb2wuUG9zaXRpb24pOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHN0cmluZy5Jc051bGxPckVtcHR5KG4pKQogICAgICAgICAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG4gPSBjb2wuTmFtZS5Ub0xvd2VyKEN1bHR1cmVJbmZvLkludmFyaWFudEN1bHR1cmUpOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICAgICAgICAgZWxzZQogICAgICAgICAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbC5OYW1lID0gbjsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICAgICBlbHNlCiAgICAgICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIG4gPSBjb2wuTmFtZS5Ub0xvd2VyKEN1bHR1cmVJbmZvLkludmFyaWFudEN1bHR1cmUpOwogICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgIGlmKGNvbFZhbC5Db250YWlucyhuKSkKICAgICAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhyb3cobmV3IEludmFsaWREYXRhRXhjZXB0aW9uKHN0cmluZy5Gb3JtYXQoIlRhYmxlIHswfSBDb2x1bW4gezF9IGRvZXMgbm90IGhhdmUgYSB1bmlxdWUgbmFtZS4iLCB0YmwuTmFtZSwgY29sLk5hbWUpKSk7CiAgICAgICAgICAgICAgICAgICAgICAgIH0gICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgY29sVmFsLkFkZChuKTsKICAgICAgICAgICAgICAgICAgICAgICAgY29sLk5hbWUgPSBDb252ZXJ0VXRpbC5FeGNlbEVuY29kZVN0cmluZyhjb2wuTmFtZSk7CiAgICAgICAgICAgICAgICAgICAgICAgIGlmICh0YmwuU2hvd0hlYWRlcikKICAgICAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgX3ZhbHVlcy5TZXRWYWx1ZSh0YmwuQWRkcmVzcy5fZnJvbVJvdywgY29sTnVtLCBjb2wuTmFtZSk7CiAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHRibC5TaG93VG90YWwpCiAgICAgICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIFNldFRhYmxlVG90YWxGdW5jdGlvbih0YmwsIGNvbCwgY29sTnVtKTsKICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICAgICBpZiAoIXN0cmluZy5Jc051bGxPckVtcHR5KGNvbC5DYWxjdWxhdGVkQ29sdW1uRm9ybXVsYSkpCiAgICAgICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGludCBmcm9tUm93ID0gdGJsLlNob3dIZWFkZXIgPyB0YmwuQWRkcmVzcy5fZnJvbVJvdyArIDEgOiB0YmwuQWRkcmVzcy5fZnJvbVJvdzsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGludCB0b1JvdyA9IHRibC5TaG93VG90YWwgPyB0YmwuQWRkcmVzcy5fdG9Sb3cgLSAxIDogdGJsLkFkZHJlc3MuX3RvUm93OwogICAgICAgICAgICAgICAgICAgICAgICAgICAgZm9yIChpbnQgcm93ID0gZnJvbVJvdzsgcm93IDw9IHRvUm93OyByb3crKykKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvL0NlbGwocm93LCBjb2xOdW0pLkZvcm11bGEgPSBjb2wuQ2FsY3VsYXRlZENvbHVtbkZvcm11bGE7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgU2V0Rm9ybXVsYShyb3csIGNvbE51bSwgY29sLkNhbGN1bGF0ZWRDb2x1bW5Gb3JtdWxhKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0gICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgY29sTnVtKys7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfSAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgIGlmICh0YmwuUGFydCA9PSBudWxsKQogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIHRibC5UYWJsZVVyaSA9IEdldE5ld1VyaShfcGFja2FnZS5QYWNrYWdlLCBAIi94bC90YWJsZXMvdGFibGV7MH0ueG1sIiwgdGJsLklkKTsKICAgICAgICAgICAgICAgICAgICB0YmwuUGFydCA9IF9wYWNrYWdlLlBhY2thZ2UuQ3JlYXRlUGFydCh0YmwuVGFibGVVcmksICJhcHBsaWNhdGlvbi92bmQub3BlbnhtbGZvcm1hdHMtb2ZmaWNlZG9jdW1lbnQuc3ByZWFkc2hlZXRtbC50YWJsZSt4bWwiLCBXb3JrYm9vay5fcGFja2FnZS5Db21wcmVzc2lvbik7CiAgICAgICAgICAgICAgICAgICAgdmFyIHN0cmVhbSA9IHRibC5QYXJ0LkdldFN0cmVhbShGaWxlTW9kZS5DcmVhdGUpOwogICAgICAgICAgICAgICAgICAgIHRibC5UYWJsZVhtbC5TYXZlKHN0cmVhbSk7CiAgICAgICAgICAgICAgICAgICAgdmFyIHJlbCA9IFBhcnQuQ3JlYXRlUmVsYXRpb25zaGlwKFVyaUhlbHBlci5HZXRSZWxhdGl2ZVVyaShXb3Jrc2hlZXRVcmksIHRibC5UYWJsZVVyaSksIFBhY2thZ2luZy5UYXJnZXRNb2RlLkludGVybmFsLCBFeGNlbFBhY2thZ2Uuc2NoZW1hUmVsYXRpb25zaGlwcyArICIvdGFibGUiKTsKICAgICAgICAgICAgICAgICAgICB0YmwuUmVsYXRpb25zaGlwSUQgPSByZWwuSWQ7CgogICAgICAgICAgICAgICAgICAgIENyZWF0ZU5vZGUoImQ6dGFibGVQYXJ0cyIpOwogICAgICAgICAgICAgICAgICAgIFhtbE5vZGUgdGJscyA9IFRvcE5vZGUuU2VsZWN0U2luZ2xlTm9kZSgiZDp0YWJsZVBhcnRzIixOYW1lU3BhY2VNYW5hZ2VyKTsKCiAgICAgICAgICAgICAgICAgICAgdmFyIHRibE5vZGUgPSB0YmxzLk93bmVyRG9jdW1lbnQuQ3JlYXRlRWxlbWVudCgidGFibGVQYXJ0IixFeGNlbFBhY2thZ2Uuc2NoZW1hTWFpbik7CiAgICAgICAgICAgICAgICAgICAgdGJscy5BcHBlbmRDaGlsZCh0YmxOb2RlKTsKICAgICAgICAgICAgICAgICAgICB0YmxOb2RlLlNldEF0dHJpYnV0ZSgiaWQiLEV4Y2VsUGFja2FnZS5zY2hlbWFSZWxhdGlvbnNoaXBzLCByZWwuSWQpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgZWxzZQogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIHZhciBzdHJlYW0gPSB0YmwuUGFydC5HZXRTdHJlYW0oRmlsZU1vZGUuQ3JlYXRlKTsKICAgICAgICAgICAgICAgICAgICB0YmwuVGFibGVYbWwuU2F2ZShzdHJlYW0pOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICBpbnRlcm5hbCB2b2lkIFNldFRhYmxlVG90YWxGdW5jdGlvbihFeGNlbFRhYmxlIHRibCwgRXhjZWxUYWJsZUNvbHVtbiBjb2wsIGludCBjb2xOdW09LTEpCiAgICAgICAgewogICAgICAgICAgICBpZiAodGJsLlNob3dUb3RhbCA9PSBmYWxzZSkgcmV0dXJuOwogICAgICAgICAgICBpZiAoY29sTnVtID09IC0xKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IHRibC5Db2x1bW5zLkNvdW50OyBpKyspCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgaWYgKHRibC5Db2x1bW5zW2ldLk5hbWUgPT0gY29sLk5hbWUpCiAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICBjb2xOdW0gPSB0YmwuQWRkcmVzcy5fZnJvbUNvbCArIGk7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgICAgIGlmIChjb2wuVG90YWxzUm93RnVuY3Rpb24gPT0gUm93RnVuY3Rpb25zLkN1c3RvbSkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgU2V0Rm9ybXVsYSh0YmwuQWRkcmVzcy5fdG9Sb3csIGNvbE51bSwgY29sLlRvdGFsc1Jvd0Zvcm11bGEpOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGVsc2UgaWYgKGNvbC5Ub3RhbHNSb3dGdW5jdGlvbiAhPSBSb3dGdW5jdGlvbnMuTm9uZSkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgc3dpdGNoIChjb2wuVG90YWxzUm93RnVuY3Rpb24pCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgY2FzZSBSb3dGdW5jdGlvbnMuQXZlcmFnZToKICAgICAgICAgICAgICAgICAgICAgICAgU2V0Rm9ybXVsYSh0YmwuQWRkcmVzcy5fdG9Sb3csIGNvbE51bSwgR2V0VG90YWxGdW5jdGlvbihjb2wsICIxMDEiKSk7CiAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgICAgIGNhc2UgUm93RnVuY3Rpb25zLkNvdW50OgogICAgICAgICAgICAgICAgICAgICAgICBTZXRGb3JtdWxhKHRibC5BZGRyZXNzLl90b1JvdywgY29sTnVtLCBHZXRUb3RhbEZ1bmN0aW9uKGNvbCwgIjEwMiIpKTsKICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICAgICAgY2FzZSBSb3dGdW5jdGlvbnMuQ291bnROdW1zOgogICAgICAgICAgICAgICAgICAgICAgICBTZXRGb3JtdWxhKHRibC5BZGRyZXNzLl90b1JvdywgY29sTnVtLCBHZXRUb3RhbEZ1bmN0aW9uKGNvbCwgIjEwMyIpKTsKICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICAgICAgY2FzZSBSb3dGdW5jdGlvbnMuTWF4OgogICAgICAgICAgICAgICAgICAgICAgICBTZXRGb3JtdWxhKHRibC5BZGRyZXNzLl90b1JvdywgY29sTnVtLCBHZXRUb3RhbEZ1bmN0aW9uKGNvbCwgIjEwNCIpKTsKICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICAgICAgY2FzZSBSb3dGdW5jdGlvbnMuTWluOgogICAgICAgICAgICAgICAgICAgICAgICBTZXRGb3JtdWxhKHRibC5BZGRyZXNzLl90b1JvdywgY29sTnVtLCBHZXRUb3RhbEZ1bmN0aW9uKGNvbCwgIjEwNSIpKTsKICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICAgICAgY2FzZSBSb3dGdW5jdGlvbnMuU3RkRGV2OgogICAgICAgICAgICAgICAgICAgICAgICBTZXRGb3JtdWxhKHRibC5BZGRyZXNzLl90b1JvdywgY29sTnVtLCBHZXRUb3RhbEZ1bmN0aW9uKGNvbCwgIjEwNyIpKTsKICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICAgICAgY2FzZSBSb3dGdW5jdGlvbnMuVmFyOgogICAgICAgICAgICAgICAgICAgICAgICBTZXRGb3JtdWxhKHRibC5BZGRyZXNzLl90b1JvdywgY29sTnVtLCBHZXRUb3RhbEZ1bmN0aW9uKGNvbCwgIjExMCIpKTsKICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICAgICAgY2FzZSBSb3dGdW5jdGlvbnMuU3VtOgogICAgICAgICAgICAgICAgICAgICAgICBTZXRGb3JtdWxhKHRibC5BZGRyZXNzLl90b1JvdywgY29sTnVtLCBHZXRUb3RhbEZ1bmN0aW9uKGNvbCwgIjEwOSIpKTsKICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICAgICAgZGVmYXVsdDoKICAgICAgICAgICAgICAgICAgICAgICAgdGhyb3cgKG5ldyBFeGNlcHRpb24oIlVua25vd24gUm93RnVuY3Rpb24gZW51bSIpKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgICAgICBlbHNlCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIF92YWx1ZXMuU2V0VmFsdWUodGJsLkFkZHJlc3MuX3RvUm93LCBjb2xOdW0sIGNvbC5Ub3RhbHNSb3dMYWJlbCk7CgogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICBpbnRlcm5hbCB2b2lkIFNldEZvcm11bGEoaW50IHJvdywgaW50IGNvbCwgb2JqZWN0IHZhbHVlKQogICAgICAgIHsKICAgICAgICAgICAgX2Zvcm11bGFzLlNldFZhbHVlKHJvdywgY29sLCB2YWx1ZSk7CiAgICAgICAgICAgIGlmICghX3ZhbHVlcy5FeGlzdHMocm93LCBjb2wpKSBfdmFsdWVzLlNldFZhbHVlKHJvdywgY29sLCBudWxsKTsKICAgICAgICB9CiAgICAgICAgaW50ZXJuYWwgdm9pZCBTZXRTdHlsZShpbnQgcm93LCBpbnQgY29sLCBpbnQgdmFsdWUpCiAgICAgICAgewogICAgICAgICAgICBfc3R5bGVzLlNldFZhbHVlKHJvdywgY29sLCB2YWx1ZSk7CiAgICAgICAgICAgIGlmKCFfdmFsdWVzLkV4aXN0cyhyb3csY29sKSkgX3ZhbHVlcy5TZXRWYWx1ZShyb3csIGNvbCwgbnVsbCk7CiAgICAgICAgfQogICAgICAgIAogICAgICAgIHByaXZhdGUgdm9pZCBTYXZlUGl2b3RUYWJsZXMoKQogICAgICAgIHsKICAgICAgICAgICAgZm9yZWFjaCAodmFyIHB0IGluIFBpdm90VGFibGVzKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBpZiAocHQuRGF0YUZpZWxkcy5Db3VudCA+IDEpCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgWG1sRWxlbWVudCBwYXJlbnROb2RlOwogICAgICAgICAgICAgICAgICAgIGlmKHB0LkRhdGFPblJvd3M9PXRydWUpCiAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICBwYXJlbnROb2RlID0gIHB0LlBpdm90VGFibGVYbWwuU2VsZWN0U2luZ2xlTm9kZSgiLy9kOnJvd0ZpZWxkcyIsIHB0Lk5hbWVTcGFjZU1hbmFnZXIpIGFzIFhtbEVsZW1lbnQ7CiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChwYXJlbnROb2RlID09IG51bGwpCiAgICAgICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHB0LkNyZWF0ZU5vZGUoImQ6cm93RmllbGRzIik7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBwYXJlbnROb2RlID0gcHQuUGl2b3RUYWJsZVhtbC5TZWxlY3RTaW5nbGVOb2RlKCIvL2Q6cm93RmllbGRzIiwgcHQuTmFtZVNwYWNlTWFuYWdlcikgYXMgWG1sRWxlbWVudDsKICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICBlbHNlCiAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICBwYXJlbnROb2RlID0gIHB0LlBpdm90VGFibGVYbWwuU2VsZWN0U2luZ2xlTm9kZSgiLy9kOmNvbEZpZWxkcyIsIHB0Lk5hbWVTcGFjZU1hbmFnZXIpIGFzIFhtbEVsZW1lbnQ7CiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChwYXJlbnROb2RlID09IG51bGwpCiAgICAgICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHB0LkNyZWF0ZU5vZGUoImQ6Y29sRmllbGRzIik7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBwYXJlbnROb2RlID0gcHQuUGl2b3RUYWJsZVhtbC5TZWxlY3RTaW5nbGVOb2RlKCIvL2Q6Y29sRmllbGRzIiwgcHQuTmFtZVNwYWNlTWFuYWdlcikgYXMgWG1sRWxlbWVudDsKICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICAgICAgaWYgKHBhcmVudE5vZGUuU2VsZWN0U2luZ2xlTm9kZSgiZDpmaWVsZFtAIHg9IFwiLTJcIl0iLCBwdC5OYW1lU3BhY2VNYW5hZ2VyKSA9PSBudWxsKQogICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgWG1sRWxlbWVudCBmaWVsZE5vZGUgPSBwdC5QaXZvdFRhYmxlWG1sLkNyZWF0ZUVsZW1lbnQoImZpZWxkIiwgRXhjZWxQYWNrYWdlLnNjaGVtYU1haW4pOwogICAgICAgICAgICAgICAgICAgICAgICBmaWVsZE5vZGUuU2V0QXR0cmlidXRlKCJ4IiwgIi0yIik7CiAgICAgICAgICAgICAgICAgICAgICAgIHBhcmVudE5vZGUuQXBwZW5kQ2hpbGQoZmllbGROb2RlKTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB2YXIgd3MgPSBXb3JrYm9vay5Xb3Jrc2hlZXRzW3B0LkNhY2hlRGVmaW5pdGlvbi5Tb3VyY2VSYW5nZS5Xb3JrU2hlZXRdOwogICAgICAgICAgICAgICAgdmFyIHQgPSB3cy5UYWJsZXMuR2V0RnJvbVJhbmdlKHB0LkNhY2hlRGVmaW5pdGlvbi5Tb3VyY2VSYW5nZSk7CiAgICAgICAgICAgICAgICB2YXIgZmllbGRzID0KICAgICAgICAgICAgICAgICAgICBwdC5DYWNoZURlZmluaXRpb24uQ2FjaGVEZWZpbml0aW9uWG1sLlNlbGVjdE5vZGVzKAogICAgICAgICAgICAgICAgICAgICAgICAiZDpwaXZvdENhY2hlRGVmaW5pdGlvbi9kOmNhY2hlRmllbGRzL2Q6Y2FjaGVGaWVsZCIsIE5hbWVTcGFjZU1hbmFnZXIpOwogICAgICAgICAgICAgICAgaW50IGl4ID0gMDsKICAgICAgICAgICAgICAgIGlmIChmaWVsZHMgIT0gbnVsbCkKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICB2YXIgZmxkcyA9IG5ldyBIYXNoU2V0PHN0cmluZz4oKTsKICAgICAgICAgICAgICAgICAgICBmb3JlYWNoIChYbWxFbGVtZW50IG5vZGUgaW4gZmllbGRzKQogICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGl4ID49IHB0LkNhY2hlRGVmaW5pdGlvbi5Tb3VyY2VSYW5nZS5Db2x1bW5zKSBicmVhazsKICAgICAgICAgICAgICAgICAgICAgICAgdmFyIGZsZE5hbWUgPSBub2RlLkdldEF0dHJpYnV0ZSgibmFtZSIpOyAgICAgICAgICAgICAgICAgICAgICAgIC8vRml4ZXMgaXNzdWUgMTUyOTUgZHVwIG5hbWUgZXJyb3IKICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHN0cmluZy5Jc051bGxPckVtcHR5KGZsZE5hbWUpKQogICAgICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBmbGROYW1lID0gKHQgPT0gbnVsbAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgID8gcHQuQ2FjaGVEZWZpbml0aW9uLlNvdXJjZVJhbmdlLk9mZnNldCgwLCBpeCsrLCAxLCAxKS5WYWx1ZS5Ub1N0cmluZygpCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgOiB0LkNvbHVtbnNbaXgrK10uTmFtZSk7CiAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGZsZHMuQ29udGFpbnMoZmxkTmFtZSkpCiAgICAgICAgICAgICAgICAgICAgICAgIHsgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBmbGROYW1lID0gR2V0TmV3TmFtZShmbGRzLCBmbGROYW1lKTsKICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICAgICBmbGRzLkFkZChmbGROYW1lKTsKICAgICAgICAgICAgICAgICAgICAgICAgbm9kZS5TZXRBdHRyaWJ1dGUoIm5hbWUiLCBmbGROYW1lKTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgZm9yZWFjaCAodmFyIGRmIGluIHB0LkRhdGFGaWVsZHMpCiAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICBpZiAoc3RyaW5nLklzTnVsbE9yRW1wdHkoZGYuTmFtZSkpCiAgICAgICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN0cmluZyBuYW1lOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGRmLkZ1bmN0aW9uID09IERhdGFGaWVsZEZ1bmN0aW9ucy5Ob25lKQogICAgICAgICAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5hbWUgPSBkZi5GaWVsZC5OYW1lOyAvL05hbWUgbXVzdCBiZSBzZXQgb3IgRXhjZWwgd2lsbCBjcmFzaCBvbiByZW5hbWUuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVsc2UKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBuYW1lID0gZGYuRnVuY3Rpb24uVG9TdHJpbmcoKSArICIgb2YgIiArIGRmLkZpZWxkLk5hbWU7IC8vTmFtZSBtdXN0IGJlIHNldCBvciBFeGNlbCB3aWxsIGNyYXNoIG9uIHJlbmFtZS4KICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vTWFrZSBzdXJlIG5hbWUgaXMgdW5pcXVlCiAgICAgICAgICAgICAgICAgICAgICAgICAgICB2YXIgbmV3TmFtZSA9IG5hbWU7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICB2YXIgaSA9IDI7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICB3aGlsZSAocHQuRGF0YUZpZWxkcy5FeGlzdHNEZk5hbWUobmV3TmFtZSwgZGYpKQogICAgICAgICAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5ld05hbWUgPSBuYW1lICsgKGkrKykuVG9TdHJpbmcoQ3VsdHVyZUluZm8uSW52YXJpYW50Q3VsdHVyZSk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBkZi5OYW1lID0gbmV3TmFtZTsKICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIHB0LlBpdm90VGFibGVYbWwuU2F2ZShwdC5QYXJ0LkdldFN0cmVhbShGaWxlTW9kZS5DcmVhdGUpKTsKICAgICAgICAgICAgICAgIHB0LkNhY2hlRGVmaW5pdGlvbi5DYWNoZURlZmluaXRpb25YbWwuU2F2ZShwdC5DYWNoZURlZmluaXRpb24uUGFydC5HZXRTdHJlYW0oRmlsZU1vZGUuQ3JlYXRlKSk7CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIHByaXZhdGUgc3RyaW5nIEdldE5ld05hbWUoSGFzaFNldDxzdHJpbmc+IGZsZHMsIHN0cmluZyBmbGROYW1lKQogICAgICAgIHsKICAgICAgICAgICAgaW50IGl4ID0gMjsKICAgICAgICAgICAgd2hpbGUgKGZsZHMuQ29udGFpbnMoZmxkTmFtZSArIGl4LlRvU3RyaW5nKEN1bHR1cmVJbmZvLkludmFyaWFudEN1bHR1cmUpKSkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgaXgrKzsKICAgICAgICAgICAgfQogICAgICAgICAgICByZXR1cm4gZmxkTmFtZSArIGl4LlRvU3RyaW5nKEN1bHR1cmVJbmZvLkludmFyaWFudEN1bHR1cmUpOwogICAgICAgIH0KCiAgICAgICAgcHJpdmF0ZSBzdGF0aWMgc3RyaW5nIEdldFRvdGFsRnVuY3Rpb24oRXhjZWxUYWJsZUNvbHVtbiBjb2wsc3RyaW5nIEZ1bmN0aW9uTnVtKQogICAgICAgIHsKICAgICAgICAgICAgcmV0dXJuIHN0cmluZy5Gb3JtYXQoIlNVQlRPVEFMKHswfSx7MX1bezJ9XSkiLCBGdW5jdGlvbk51bSwgY29sLl90YmwuTmFtZSwgY29sLk5hbWUpOwogICAgICAgIH0KICAgICAgICBwcml2YXRlIHZvaWQgU2F2ZVhtbChTdHJlYW0gc3RyZWFtKQogICAgICAgIHsKICAgICAgICAgICAgLy9DcmVhdGUgdGhlIG5vZGVzIGlmIHRoZXkgZG8gbm90IGV4aXN0LgogICAgICAgICAgICBTdHJlYW1Xcml0ZXIgc3cgPSBuZXcgU3RyZWFtV3JpdGVyKHN0cmVhbSwgU3lzdGVtLlRleHQuRW5jb2RpbmcuVVRGOCwgNjU1MzYpOwogICAgICAgICAgICBpZiAodGhpcyBpcyBFeGNlbENoYXJ0c2hlZXQpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIHN3LldyaXRlKF93b3Jrc2hlZXRYbWwuT3V0ZXJYbWwpOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGVsc2UKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgQ3JlYXRlTm9kZSgiZDpjb2xzIik7CiAgICAgICAgICAgICAgICBDcmVhdGVOb2RlKCJkOnNoZWV0RGF0YSIpOwogICAgICAgICAgICAgICAgQ3JlYXRlTm9kZSgiZDptZXJnZUNlbGxzIik7CiAgICAgICAgICAgICAgICBDcmVhdGVOb2RlKCJkOmh5cGVybGlua3MiKTsKICAgICAgICAgICAgICAgIENyZWF0ZU5vZGUoImQ6cm93QnJlYWtzIik7CiAgICAgICAgICAgICAgICBDcmVhdGVOb2RlKCJkOmNvbEJyZWFrcyIpOwoKICAgICAgICAgICAgICAgIC8vU3RyZWFtV3JpdGVyIHN3PW5ldyBTdHJlYW1Xcml0ZXIoUGFydC5HZXRTdHJlYW0oRmlsZU1vZGUuQ3JlYXRlLCBGaWxlQWNjZXNzLldyaXRlKSk7CiAgICAgICAgICAgICAgICB2YXIgeG1sID0gX3dvcmtzaGVldFhtbC5PdXRlclhtbDsKICAgICAgICAgICAgICAgIGludCBjb2xTdGFydCA9IDAsIGNvbEVuZCA9IDA7CiAgICAgICAgICAgICAgICBHZXRCbG9ja1Bvcyh4bWwsICJjb2xzIiwgcmVmIGNvbFN0YXJ0LCByZWYgY29sRW5kKTsKCiAgICAgICAgICAgICAgICBzdy5Xcml0ZSh4bWwuU3Vic3RyaW5nKDAsIGNvbFN0YXJ0KSk7CiAgICAgICAgICAgICAgICB2YXIgY29sQnJlYWtzID0gbmV3IExpc3Q8aW50PigpOwogICAgICAgICAgICAgICAgLy9pZiAoX2NvbHVtbnMuQ291bnQgPiAwKQogICAgICAgICAgICAgICAgLy97CiAgICAgICAgICAgICAgICBVcGRhdGVDb2x1bW5EYXRhKHN3KTsKICAgICAgICAgICAgICAgIC8vfQoKICAgICAgICAgICAgICAgIGludCBjZWxsU3RhcnQgPSBjb2xFbmQsIGNlbGxFbmQgPSBjb2xFbmQ7CiAgICAgICAgICAgICAgICBHZXRCbG9ja1Bvcyh4bWwsICJzaGVldERhdGEiLCByZWYgY2VsbFN0YXJ0LCByZWYgY2VsbEVuZCk7CgogICAgICAgICAgICAgICAgc3cuV3JpdGUoeG1sLlN1YnN0cmluZyhjb2xFbmQsIGNlbGxTdGFydCAtIGNvbEVuZCkpOwogICAgICAgICAgICAgICAgdmFyIHJvd0JyZWFrcyA9IG5ldyBMaXN0PGludD4oKTsKICAgICAgICAgICAgICAgIFVwZGF0ZVJvd0NlbGxEYXRhKHN3KTsKCiAgICAgICAgICAgICAgICBpbnQgbWVyZ2VTdGFydCA9IGNlbGxFbmQsIG1lcmdlRW5kID0gY2VsbEVuZDsKCiAgICAgICAgICAgICAgICBHZXRCbG9ja1Bvcyh4bWwsICJtZXJnZUNlbGxzIiwgcmVmIG1lcmdlU3RhcnQsIHJlZiBtZXJnZUVuZCk7CiAgICAgICAgICAgICAgICBzdy5Xcml0ZSh4bWwuU3Vic3RyaW5nKGNlbGxFbmQsIG1lcmdlU3RhcnQgLSBjZWxsRW5kKSk7CgogICAgICAgICAgICAgICAgQ2xlYW51cE1lcmdlZENlbGxzKF9tZXJnZWRDZWxscyk7CiAgICAgICAgICAgICAgICBpZiAoX21lcmdlZENlbGxzLkNvdW50ID4gMCkKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICBVcGRhdGVNZXJnZWRDZWxscyhzdyk7CiAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgaW50IGh5cGVyU3RhcnQgPSBtZXJnZUVuZCwgaHlwZXJFbmQgPSBtZXJnZUVuZDsKICAgICAgICAgICAgICAgIEdldEJsb2NrUG9zKHhtbCwgImh5cGVybGlua3MiLCByZWYgaHlwZXJTdGFydCwgcmVmIGh5cGVyRW5kKTsKICAgICAgICAgICAgICAgIHN3LldyaXRlKHhtbC5TdWJzdHJpbmcobWVyZ2VFbmQsIGh5cGVyU3RhcnQgLSBtZXJnZUVuZCkpOwogICAgICAgICAgICAgICAgLy9pZiAoX2h5cGVyTGlua0NlbGxzLkNvdW50ID4gMCkKICAgICAgICAgICAgICAgIC8vewogICAgICAgICAgICAgICAgVXBkYXRlSHlwZXJMaW5rcyhzdyk7CiAgICAgICAgICAgICAgICAvLyB9CgogICAgICAgICAgICAgICAgaW50IHJvd0JyZWFrU3RhcnQgPSBoeXBlckVuZCwgcm93QnJlYWtFbmQgPSBoeXBlckVuZDsKICAgICAgICAgICAgICAgIEdldEJsb2NrUG9zKHhtbCwgInJvd0JyZWFrcyIsIHJlZiByb3dCcmVha1N0YXJ0LCByZWYgcm93QnJlYWtFbmQpOwogICAgICAgICAgICAgICAgc3cuV3JpdGUoeG1sLlN1YnN0cmluZyhoeXBlckVuZCwgcm93QnJlYWtTdGFydCAtIGh5cGVyRW5kKSk7CiAgICAgICAgICAgICAgICAvL2lmIChyb3dCcmVha3MuQ291bnQgPiAwKQogICAgICAgICAgICAgICAgLy97CiAgICAgICAgICAgICAgICBVcGRhdGVSb3dCcmVha3Moc3cpOwogICAgICAgICAgICAgICAgLy99CgogICAgICAgICAgICAgICAgaW50IGNvbEJyZWFrU3RhcnQgPSByb3dCcmVha0VuZCwgY29sQnJlYWtFbmQgPSByb3dCcmVha0VuZDsKICAgICAgICAgICAgICAgIEdldEJsb2NrUG9zKHhtbCwgImNvbEJyZWFrcyIsIHJlZiBjb2xCcmVha1N0YXJ0LCByZWYgY29sQnJlYWtFbmQpOwogICAgICAgICAgICAgICAgc3cuV3JpdGUoeG1sLlN1YnN0cmluZyhyb3dCcmVha0VuZCwgY29sQnJlYWtTdGFydCAtIHJvd0JyZWFrRW5kKSk7CiAgICAgICAgICAgICAgICAvL2lmIChjb2xCcmVha3MuQ291bnQgPiAwKQogICAgICAgICAgICAgICAgLy97CiAgICAgICAgICAgICAgICBVcGRhdGVDb2xCcmVha3Moc3cpOwogICAgICAgICAgICAgICAgLy99CiAgICAgICAgICAgICAgICBzdy5Xcml0ZSh4bWwuU3Vic3RyaW5nKGNvbEJyZWFrRW5kLCB4bWwuTGVuZ3RoIC0gY29sQnJlYWtFbmQpKTsKICAgICAgICAgICAgfQogICAgICAgICAgICBzdy5GbHVzaCgpOwogICAgICAgICAgICAvL3N3LkNsb3NlKCk7CiAgICAgICAgfQoKICAgICAgICBwcml2YXRlIHZvaWQgQ2xlYW51cE1lcmdlZENlbGxzKE1lcmdlQ2VsbHNDb2xsZWN0aW9uIF9tZXJnZWRDZWxscykKICAgICAgICB7CiAgICAgICAgICAgIGludCBpPTA7CiAgICAgICAgICAgIHdoaWxlIChpIDwgX21lcmdlZENlbGxzLkxpc3QuQ291bnQpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIGlmIChfbWVyZ2VkQ2VsbHNbaV0gPT0gbnVsbCkKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICBfbWVyZ2VkQ2VsbHMuTGlzdC5SZW1vdmVBdChpKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGVsc2UKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICBpKys7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgcHJpdmF0ZSB2b2lkIFVwZGF0ZUNvbEJyZWFrcyhTdHJlYW1Xcml0ZXIgc3cpCiAgICAgICAgewogICAgICAgICAgICBTdHJpbmdCdWlsZGVyIGJyZWFrcyA9IG5ldyBTdHJpbmdCdWlsZGVyKCk7CiAgICAgICAgICAgIGludCBjb3VudCA9IDA7CiAgICAgICAgICAgIHZhciBjc2UgPSBuZXcgQ2VsbHNTdG9yZUVudW1lcmF0b3I8b2JqZWN0PihfdmFsdWVzLCAwLCAwLCAwLCBFeGNlbFBhY2thZ2UuTWF4Q29sdW1ucyk7CiAgICAgICAgICAgIC8vZm9yZWFjaCAoRXhjZWxDb2x1bW4gY29sIGluIF9jb2x1bW5zKQogICAgICAgICAgICB3aGlsZShjc2UuTmV4dCgpKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICB2YXIgY29sPWNzZS5WYWx1ZSBhcyBFeGNlbENvbHVtbjsKICAgICAgICAgICAgICAgIGlmIChjb2wgIT0gbnVsbCAmJiBjb2wuUGFnZUJyZWFrKQogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIGJyZWFrcy5BcHBlbmRGb3JtYXQoIjxicmsgaWQ9XCJ7MH1cIiBtYXg9XCIxNjM4M1wiIG1hbj1cIjFcIiAvPiIsIGNzZS5Db2x1bW4pOwogICAgICAgICAgICAgICAgICAgIGNvdW50Kys7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICAgICAgaWYgKGNvdW50ID4gMCkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgc3cuV3JpdGUoc3RyaW5nLkZvcm1hdCgiPGNvbEJyZWFrcyBjb3VudD1cInswfVwiIG1hbnVhbEJyZWFrQ291bnQ9XCJ7MH1cIj57MX08L2NvbEJyZWFrcz4iLCBjb3VudCwgYnJlYWtzLlRvU3RyaW5nKCkpKTsKICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgcHJpdmF0ZSB2b2lkIFVwZGF0ZVJvd0JyZWFrcyhTdHJlYW1Xcml0ZXIgc3cpCiAgICAgICAgewogICAgICAgICAgICBTdHJpbmdCdWlsZGVyIGJyZWFrcz1uZXcgU3RyaW5nQnVpbGRlcigpOwogICAgICAgICAgICBpbnQgY291bnQgPSAwOwogICAgICAgICAgICB2YXIgY3NlID0gbmV3IENlbGxzU3RvcmVFbnVtZXJhdG9yPG9iamVjdD4oX3ZhbHVlcywgMCwgMCwgRXhjZWxQYWNrYWdlLk1heFJvd3MsIDApOwogICAgICAgICAgICAvL2ZvcmVhY2goRXhjZWxSb3cgcm93IGluIF9yb3dzKSAgICAgICAgICAgIAogICAgICAgICAgICB3aGlsZShjc2UuTmV4dCgpKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICB2YXIgcm93PWNzZS5WYWx1ZSBhcyBSb3dJbnRlcm5hbDsKICAgICAgICAgICAgICAgIGlmIChyb3cgIT0gbnVsbCAmJiByb3cuUGFnZUJyZWFrKQogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIGJyZWFrcy5BcHBlbmRGb3JtYXQoIjxicmsgaWQ9XCJ7MH1cIiBtYXg9XCIxMDQ4NTc1XCIgbWFuPVwiMVwiIC8+IiwgY3NlLlJvdyk7CiAgICAgICAgICAgICAgICAgICAgY291bnQrKzsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgICAgICBpZiAoY291bnQ+MCkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgc3cuV3JpdGUoc3RyaW5nLkZvcm1hdCgiPHJvd0JyZWFrcyBjb3VudD1cInswfVwiIG1hbnVhbEJyZWFrQ291bnQ9XCJ7MH1cIj57MX08L3Jvd0JyZWFrcz4iLCBjb3VudCwgYnJlYWtzLlRvU3RyaW5nKCkpKTsgICAgICAgICAgICAgICAgCiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgLy8vIDxzdW1tYXJ5PgogICAgICAgIC8vLyBJbnNlcnRzIHRoZSBjb2xzIGNvbGxlY3Rpb24gaW50byB0aGUgWE1MIGRvY3VtZW50CiAgICAgICAgLy8vIDwvc3VtbWFyeT4KICAgICAgICBwcml2YXRlIHZvaWQgVXBkYXRlQ29sdW1uRGF0YShTdHJlYW1Xcml0ZXIgc3cpCiAgICAgICAgewogICAgICAgICAgICAvL0V4Y2VsQ29sdW1uIHByZXZDb2wgPSBudWxsOyAgIC8vY29tbWVudGVkIG91dCAxMS8xLTEyIEpLIAogICAgICAgICAgICAvL2ZvcmVhY2ggKEV4Y2VsQ29sdW1uIGNvbCBpbiBfY29sdW1ucykKICAgICAgICAgICAgLy97ICAgICAgICAgICAgICAgIAogICAgICAgICAgICAvLyAgICBpZiAocHJldkNvbCAhPSBudWxsKQogICAgICAgICAgICAvLyAgICB7CiAgICAgICAgICAgIC8vICAgICAgICBpZihwcmV2Q29sLkNvbHVtbk1heCAhPSBjb2wuQ29sdW1uTWluLTEpCiAgICAgICAgICAgIC8vICAgICAgICB7CiAgICAgICAgICAgIC8vICAgICAgICAgICAgcHJldkNvbC5fY29sdW1uTWF4PWNvbC5Db2x1bW5NaW4tMTsKICAgICAgICAgICAgLy8gICAgICAgIH0KICAgICAgICAgICAgLy8gICAgfQogICAgICAgICAgICAvLyAgICBwcmV2Q29sID0gY29sOwogICAgICAgICAgICAvL30KICAgICAgICAgICAgdmFyIGNzZSA9IG5ldyBDZWxsc1N0b3JlRW51bWVyYXRvcjxvYmplY3Q+KF92YWx1ZXMsIDAsIDEsIDAsIEV4Y2VsUGFja2FnZS5NYXhDb2x1bW5zKTsKICAgICAgICAgICAgLy9zdy5Xcml0ZSgiPGNvbHM+Iik7CiAgICAgICAgICAgIC8vZm9yZWFjaCAoRXhjZWxDb2x1bW4gY29sIGluIF9jb2x1bW5zKQogICAgICAgICAgICBib29sIGZpcnN0ID0gdHJ1ZTsKICAgICAgICAgICAgd2hpbGUoY3NlLk5leHQoKSkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgaWYgKGZpcnN0KQogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIHN3LldyaXRlKCI8Y29scz4iKTsKICAgICAgICAgICAgICAgICAgICBmaXJzdCA9IGZhbHNlOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgdmFyIGNvbCA9IGNzZS5WYWx1ZSBhcyBFeGNlbENvbHVtbjsKICAgICAgICAgICAgICAgIEV4Y2VsU3R5bGVDb2xsZWN0aW9uPEV4Y2VsWGZzPiBjZWxsWGZzID0gX3BhY2thZ2UuV29ya2Jvb2suU3R5bGVzLkNlbGxYZnM7CgogICAgICAgICAgICAgICAgc3cuV3JpdGUoIjxjb2wgbWluPVwiezB9XCIgbWF4PVwiezF9XCIiLCBjb2wuQ29sdW1uTWluLCBjb2wuQ29sdW1uTWF4KTsKICAgICAgICAgICAgICAgIGlmIChjb2wuSGlkZGVuID09IHRydWUpCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgLy9zYlhtbC5BcHBlbmQoIiB3aWR0aD1cIjBcIiBoaWRkZW49XCIxXCIgY3VzdG9tV2lkdGg9XCIxXCIiKTsKICAgICAgICAgICAgICAgICAgICBzdy5Xcml0ZSgiIGhpZGRlbj1cIjFcIiIpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgZWxzZSBpZiAoY29sLkJlc3RGaXQpCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgc3cuV3JpdGUoIiBiZXN0Rml0PVwiMVwiIik7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBzdy5Xcml0ZShzdHJpbmcuRm9ybWF0KEN1bHR1cmVJbmZvLkludmFyaWFudEN1bHR1cmUsICIgd2lkdGg9XCJ7MH1cIiBjdXN0b21XaWR0aD1cIjFcIiIsIGNvbC5XaWR0aCkpOwogICAgICAgICAgICAgICAgaWYgKGNvbC5PdXRsaW5lTGV2ZWwgPiAwKQogICAgICAgICAgICAgICAgeyAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgc3cuV3JpdGUoIiBvdXRsaW5lTGV2ZWw9XCJ7MH1cIiAiLCBjb2wuT3V0bGluZUxldmVsKTsKICAgICAgICAgICAgICAgICAgICBpZiAoY29sLkNvbGxhcHNlZCkKICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChjb2wuSGlkZGVuKQogICAgICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBzdy5Xcml0ZSgiIGNvbGxhcHNlZD1cIjFcIiIpOwogICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgICAgIGVsc2UKICAgICAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgc3cuV3JpdGUoIiBjb2xsYXBzZWQ9XCIxXCIgaGlkZGVuPVwiMVwiIik7IC8vQWx3YXlzIGhpZGRlbgogICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgaWYgKGNvbC5QaG9uZXRpYykKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICBzdy5Xcml0ZSgiIHBob25ldGljPVwiMVwiIik7CiAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgdmFyIHN0eWxlSUQgPSBjb2wuU3R5bGVJRCA+PSAwID8gY2VsbFhmc1tjb2wuU3R5bGVJRF0ubmV3SUQgOiBjb2wuU3R5bGVJRDsKICAgICAgICAgICAgICAgIGlmIChzdHlsZUlEID4gMCkKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICBzdy5Xcml0ZSgiIHN0eWxlPVwiezB9XCIiLCBzdHlsZUlEKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIHN3LldyaXRlKCIgLz4iKTsKCiAgICAgICAgICAgICAgICAvL2lmIChjb2wuUGFnZUJyZWFrKQogICAgICAgICAgICAgICAgLy97CiAgICAgICAgICAgICAgICAvLyAgICBjb2xCcmVha3MuQWRkKGNvbC5Db2x1bW5NaW4pOwogICAgICAgICAgICAgICAgLy99CiAgICAgICAgICAgIH0KICAgICAgICAgICAgaWYgKCFmaXJzdCkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgc3cuV3JpdGUoIjwvY29scz4iKTsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgICAgICAvLy8gPHN1bW1hcnk+CiAgICAgICAgLy8vIEluc2VydCByb3cgYW5kIGNlbGxzIGludG8gdGhlIFhNTCBkb2N1bWVudAogICAgICAgIC8vLyA8L3N1bW1hcnk+CiAgICAgICAgcHJpdmF0ZSB2b2lkIFVwZGF0ZVJvd0NlbGxEYXRhKFN0cmVhbVdyaXRlciBzdykKICAgICAgICB7CiAgICAgICAgICAgIEV4Y2VsU3R5bGVDb2xsZWN0aW9uPEV4Y2VsWGZzPiBjZWxsWGZzID0gX3BhY2thZ2UuV29ya2Jvb2suU3R5bGVzLkNlbGxYZnM7CiAgICAgICAgICAgIAogICAgICAgICAgICBpbnQgcm93ID0gLTE7CgogICAgICAgICAgICBTdHJpbmdCdWlsZGVyIHNiWG1sID0gbmV3IFN0cmluZ0J1aWxkZXIoKTsKICAgICAgICAgICAgdmFyIHNzID0gX3BhY2thZ2UuV29ya2Jvb2suX3NoYXJlZFN0cmluZ3M7CiAgICAgICAgICAgIHZhciBzdHlsZXMgPSBfcGFja2FnZS5Xb3JrYm9vay5TdHlsZXM7CiAgICAgICAgICAgIHZhciBjYWNoZSA9IG5ldyBTdHJpbmdCdWlsZGVyKCk7CiAgICAgICAgICAgIGNhY2hlLkFwcGVuZCgiPHNoZWV0RGF0YT4iKTsKICAgICAgICAgICAgCiAgICAgICAgICAgIC8vU2V0IGEgdmFsdWUgZm9yIGNlbGxzIHdpdGggc3R5bGUgYW5kIG5vIHZhbHVlIHNldC4KICAgICAgICAgICAgdmFyIGNzZVN0eWxlID0gbmV3IENlbGxzU3RvcmVFbnVtZXJhdG9yPGludD4oX3N0eWxlcywgMCwgMCwgRXhjZWxQYWNrYWdlLk1heFJvd3MsIEV4Y2VsUGFja2FnZS5NYXhDb2x1bW5zKTsKICAgICAgICAgICAgZm9yZWFjaCAodmFyIHMgaW4gY3NlU3R5bGUpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIGlmKCFfdmFsdWVzLkV4aXN0cyhjc2VTdHlsZS5Sb3csIGNzZVN0eWxlLkNvbHVtbikpCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgX3ZhbHVlcy5TZXRWYWx1ZShjc2VTdHlsZS5Sb3csIGNzZVN0eWxlLkNvbHVtbiwgbnVsbCk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIHZhciBjc2UgPSBuZXcgQ2VsbHNTdG9yZUVudW1lcmF0b3I8b2JqZWN0PihfdmFsdWVzLCAxLCAwLCBFeGNlbFBhY2thZ2UuTWF4Um93cywgRXhjZWxQYWNrYWdlLk1heENvbHVtbnMpOwogICAgICAgICAgICAvL2ZvcmVhY2ggKElSYW5nZUlEIHIgaW4gX2NlbGxzKQogICAgICAgICAgICB3aGlsZShjc2UuTmV4dCgpKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBpZiAoY3NlLkNvbHVtbj4wKQogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIGludCBzdHlsZUlEID0gY2VsbFhmc1tzdHlsZXMuR2V0U3R5bGVJZCh0aGlzLCBjc2UuUm93LCBjc2UuQ29sdW1uKV0ubmV3SUQ7CiAgICAgICAgICAgICAgICAgICAgLy9BZGQgdGhlIHJvdyBlbGVtZW50IGlmIGl0J3MgYSBuZXcgcm93CiAgICAgICAgICAgICAgICAgICAgaWYgKGNzZS5Sb3cgIT0gcm93KQogICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgV3JpdGVSb3coY2FjaGUsIGNlbGxYZnMsIHJvdywgY3NlLlJvdyk7CiAgICAgICAgICAgICAgICAgICAgICAgIHJvdyA9IGNzZS5Sb3c7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIG9iamVjdCB2ID0gY3NlLlZhbHVlOwogICAgICAgICAgICAgICAgICAgIG9iamVjdCBmb3JtdWxhID0gX2Zvcm11bGFzLkdldFZhbHVlKGNzZS5Sb3csIGNzZS5Db2x1bW4pOwogICAgICAgICAgICAgICAgICAgIGlmIChmb3JtdWxhIGlzIGludCkKICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgIGludCBzZklkID0gKGludClmb3JtdWxhOwogICAgICAgICAgICAgICAgICAgICAgICB2YXIgZiA9IF9zaGFyZWRGb3JtdWxhc1soaW50KXNmSWRdOwogICAgICAgICAgICAgICAgICAgICAgICBpZiAoZi5BZGRyZXNzLkluZGV4T2YoJzonKSA+IDApCiAgICAgICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChmLlN0YXJ0Q29sID09IGNzZS5Db2x1bW4gJiYgZi5TdGFydFJvdyA9PSBjc2UuUm93KQogICAgICAgICAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChmLklzQXJyYXkpCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjYWNoZS5BcHBlbmRGb3JtYXQoIjxjIHI9XCJ7MH1cIiBzPVwiezF9XCJ7NX0+PGYgcmVmPVwiezJ9XCIgdD1cImFycmF5XCI+ezN9PC9mPns0fTwvYz4iLCBjc2UuQ2VsbEFkZHJlc3MsIHN0eWxlSUQgPCAwID8gMCA6IHN0eWxlSUQsIGYuQWRkcmVzcywgU2VjdXJpdHlFbGVtZW50LkVzY2FwZShmLkZvcm11bGEpLCBHZXRGb3JtdWxhVmFsdWUodiksIEdldENlbGxUeXBlKHYsdHJ1ZSkpOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlbHNlCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjYWNoZS5BcHBlbmRGb3JtYXQoIjxjIHI9XCJ7MH1cIiBzPVwiezF9XCJ7Nn0+PGYgcmVmPVwiezJ9XCIgdD1cInNoYXJlZFwiICBzaT1cInszfVwiPns0fTwvZj57NX08L2M+IiwgY3NlLkNlbGxBZGRyZXNzLCBzdHlsZUlEIDwgMCA/IDAgOiBzdHlsZUlELCBmLkFkZHJlc3MsIHNmSWQsIFNlY3VyaXR5RWxlbWVudC5Fc2NhcGUoZi5Gb3JtdWxhKSwgR2V0Rm9ybXVsYVZhbHVlKHYpLCBHZXRDZWxsVHlwZSh2LHRydWUpKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICAgICAgICAgZWxzZSBpZiAoZi5Jc0FycmF5KQogICAgICAgICAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNhY2hlLkFwcGVuZEZvcm1hdCgiPGMgcj1cInswfVwiIHM9XCJ7MX1cIiAvPiIsIGNzZS5DZWxsQWRkcmVzcywgc3R5bGVJRCA8IDAgPyAwIDogc3R5bGVJRCk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBlbHNlCiAgICAgICAgICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY2FjaGUuQXBwZW5kRm9ybWF0KCI8YyByPVwiezB9XCIgcz1cInsxfVwiezR9PjxmIHQ9XCJzaGFyZWRcIiBzaT1cInsyfVwiIC8+ezN9PC9jPiIsIGNzZS5DZWxsQWRkcmVzcywgc3R5bGVJRCA8IDAgPyAwIDogc3R5bGVJRCwgc2ZJZCwgR2V0Rm9ybXVsYVZhbHVlKHYpLCBHZXRDZWxsVHlwZSh2LHRydWUpKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICAgICBlbHNlCiAgICAgICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIFdlIGNhbiBhbHNvIGhhdmUgYSBzaW5nbGUgY2VsbCBhcnJheSBmb3JtdWxhCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZihmLklzQXJyYXkpCiAgICAgICAgICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY2FjaGUuQXBwZW5kRm9ybWF0KCI8YyByPVwiezB9XCIgcz1cInsxfVwiezV9PjxmIHJlZj1cInsyfVwiIHQ9XCJhcnJheVwiPnszfTwvZj57NH08L2M+IiwgY3NlLkNlbGxBZGRyZXNzLCBzdHlsZUlEIDwgMCA/IDAgOiBzdHlsZUlELCBzdHJpbmcuRm9ybWF0KCJ7MH06ezF9IiwgZi5BZGRyZXNzLCBmLkFkZHJlc3MpLCBTZWN1cml0eUVsZW1lbnQuRXNjYXBlKGYuRm9ybXVsYSksIEdldEZvcm11bGFWYWx1ZSh2KSwgR2V0Q2VsbFR5cGUodix0cnVlKSk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBlbHNlCiAgICAgICAgICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY2FjaGUuQXBwZW5kRm9ybWF0KCI8YyByPVwiezB9XCIgcz1cInsxfVwiPiIsIGYuQWRkcmVzcywgc3R5bGVJRCA8IDAgPyAwIDogc3R5bGVJRCk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY2FjaGUuQXBwZW5kRm9ybWF0KCI8Zj57MH08L2Y+ezF9PC9jPiIsIFNlY3VyaXR5RWxlbWVudC5Fc2NhcGUoZi5Gb3JtdWxhKSwgR2V0Rm9ybXVsYVZhbHVlKHYpKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICBlbHNlIGlmIChmb3JtdWxhIT1udWxsICYmIGZvcm11bGEuVG9TdHJpbmcoKSE9IiIpCiAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICBjYWNoZS5BcHBlbmRGb3JtYXQoIjxjIHI9XCJ7MH1cIiBzPVwiezF9XCJ7Mn0+IiwgY3NlLkNlbGxBZGRyZXNzLCBzdHlsZUlEIDwgMCA/IDAgOiBzdHlsZUlELCBHZXRDZWxsVHlwZSh2LHRydWUpKTsKICAgICAgICAgICAgICAgICAgICAgICAgY2FjaGUuQXBwZW5kRm9ybWF0KCI8Zj57MH08L2Y+ezF9PC9jPiIsIFNlY3VyaXR5RWxlbWVudC5Fc2NhcGUoZm9ybXVsYS5Ub1N0cmluZygpKSwgR2V0Rm9ybXVsYVZhbHVlKHYpKTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgZWxzZQogICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHYgPT0gbnVsbCAmJiBzdHlsZUlEID4gMCkKICAgICAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgY2FjaGUuQXBwZW5kRm9ybWF0KCI8YyByPVwiezB9XCIgcz1cInsxfVwiIC8+IiwgY3NlLkNlbGxBZGRyZXNzLCBzdHlsZUlEIDwgMCA/IDAgOiBzdHlsZUlEKTsKICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICAgICBlbHNlIGlmKHYgIT0gbnVsbCkKICAgICAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKCh2LkdldFR5cGUoKS5Jc1ByaW1pdGl2ZSB8fCB2IGlzIGRvdWJsZSB8fCB2IGlzIGRlY2ltYWwgfHwgdiBpcyBEYXRlVGltZSB8fCB2IGlzIFRpbWVTcGFuKSkKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvL3N0cmluZyBzdiA9IEdldFZhbHVlRm9yWG1sKHYpOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNhY2hlLkFwcGVuZEZvcm1hdCgiPGMgcj1cInswfVwiIHM9XCJ7MX1cIiB7Mn0+IiwgY3NlLkNlbGxBZGRyZXNzLCBzdHlsZUlEIDwgMCA/IDAgOiBzdHlsZUlELCBHZXRDZWxsVHlwZSh2KSk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY2FjaGUuQXBwZW5kRm9ybWF0KCJ7MH08L2M+IiwgR2V0Rm9ybXVsYVZhbHVlKHYpKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVsc2UKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbnQgaXg7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKCFzcy5Db250YWluc0tleSh2LlRvU3RyaW5nKCkpKQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaXggPSBzcy5Db3VudDsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc3MuQWRkKHYuVG9TdHJpbmcoKSwgbmV3IEV4Y2VsV29ya2Jvb2suU2hhcmVkU3RyaW5nSXRlbSgpIHsgaXNSaWNoVGV4dCA9IF9mbGFncy5HZXRGbGFnVmFsdWUoY3NlLlJvdyxjc2UuQ29sdW1uLENlbGxGbGFncy5SaWNoVGV4dCksIHBvcyA9IGl4IH0pOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlbHNlCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpeCA9IHNzW3YuVG9TdHJpbmcoKV0ucG9zOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjYWNoZS5BcHBlbmRGb3JtYXQoIjxjIHI9XCJ7MH1cIiBzPVwiezF9XCIgdD1cInNcIj4iLCBjc2UuQ2VsbEFkZHJlc3MsIHN0eWxlSUQgPCAwID8gMCA6IHN0eWxlSUQpOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNhY2hlLkFwcGVuZEZvcm1hdCgiPHY+ezB9PC92PjwvYz4iLCBpeCk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgLy8vL1VwZGF0ZSBoeXBlcmxpbmtzLgogICAgICAgICAgICAgICAgICAgLy9pZiAoY2VsbC5IeXBlcmxpbmsgIT0gbnVsbCkKICAgICAgICAgICAgICAgICAgICAvL3sKICAgICAgICAgICAgICAgICAgICAvLyAgICBfaHlwZXJMaW5rQ2VsbHMuQWRkKGNlbGwuQ2VsbElEKTsKICAgICAgICAgICAgICAgICAgICAvL30KICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGVsc2UgIC8vRXhjZWxSb3cKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAvL2ludCBuZXdSb3c9KChFeGNlbFJvdyljc2UuVmFsdWUpLlJvdzsKICAgICAgICAgICAgICAgICAgICBXcml0ZVJvdyhjYWNoZSwgY2VsbFhmcywgcm93LCBjc2UuUm93KTsKICAgICAgICAgICAgICAgICAgICByb3cgPSBjc2UuUm93OwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgaWYgKGNhY2hlLkxlbmd0aCA+IDB4NjAwMDAwKQogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIHN3LldyaXRlKGNhY2hlLlRvU3RyaW5nKCkpOwogICAgICAgICAgICAgICAgICAgIGNhY2hlID0gbmV3IFN0cmluZ0J1aWxkZXIoKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQoKICAgICAgICAgICAgaWYgKHJvdyAhPSAtMSkgY2FjaGUuQXBwZW5kKCI8L3Jvdz4iKTsKICAgICAgICAgICAgY2FjaGUuQXBwZW5kKCI8L3NoZWV0RGF0YT4iKTsKICAgICAgICAgICAgc3cuV3JpdGUoY2FjaGUuVG9TdHJpbmcoKSk7CiAgICAgICAgICAgIHN3LkZsdXNoKCk7CiAgICAgICAgfQoKICAgICAgICBwcml2YXRlIG9iamVjdCBHZXRGb3JtdWxhVmFsdWUob2JqZWN0IHYpCiAgICAgICAgewogICAgICAgICAgICAvL2lmIChfcGFja2FnZS5Xb3JrYm9vay5faXNDYWxjdWxhdGVkKQogICAgICAgICAgICAvL3sgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICBpZiAodiAhPSBudWxsICYmIHYuVG9TdHJpbmcoKSE9IiIpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIHJldHVybiAiPHY+IiArIFNlY3VyaXR5RWxlbWVudC5Fc2NhcGUoR2V0VmFsdWVGb3JYbWwodikpICsgIjwvdj4iOyAvL0ZpeGVzIGlzc3VlIDE1MDcxCiAgICAgICAgICAgIH0gICAgICAgICAgICAKICAgICAgICAgICAgZWxzZQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICByZXR1cm4gIiI7CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIHByaXZhdGUgc3RyaW5nIEdldENlbGxUeXBlKG9iamVjdCB2LCBib29sIGFsbG93U3RyPWZhbHNlKQogICAgICAgIHsKICAgICAgICAgICAgaWYgKHYgaXMgYm9vbCkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgcmV0dXJuICIgdD1cImJcIiI7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgZWxzZSBpZiAoKHYgaXMgZG91YmxlICYmIGRvdWJsZS5Jc0luZmluaXR5KChkb3VibGUpdikpIHx8IHYgaXMgRXhjZWxFcnJvclZhbHVlKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICByZXR1cm4gIiB0PVwiZVwiIjsKICAgICAgICAgICAgfQogICAgICAgICAgICBlbHNlIGlmKGFsbG93U3RyICYmIHYhPW51bGwgJiYgISh2LkdldFR5cGUoKS5Jc1ByaW1pdGl2ZSB8fCB2IGlzIGRvdWJsZSB8fCB2IGlzIGRlY2ltYWwgfHwgdiBpcyBEYXRlVGltZSB8fCB2IGlzIFRpbWVTcGFuKSkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgcmV0dXJuICIgdD1cInN0clwiIjsKICAgICAgICAgICAgfQogICAgICAgICAgICBlbHNlCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIHJldHVybiAiIjsKICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgcHJpdmF0ZSBzdHJpbmcgR2V0VmFsdWVGb3JYbWwob2JqZWN0IHYpCiAgICAgICAgewogICAgICAgICAgICBzdHJpbmcgczsKICAgICAgICAgICAgdHJ5CiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIGlmICh2IGlzIERhdGVUaW1lKQogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIGRvdWJsZSBzZHYgPSAoKERhdGVUaW1lKXYpLlRvT0FEYXRlKCk7CgogICAgICAgICAgICAgICAgICAgIGlmIChXb3JrYm9vay5EYXRlMTkwNCkKICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgIHNkdiAtPSBFeGNlbFdvcmtib29rLmRhdGUxOTA0T2Zmc2V0OwogICAgICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICAgICAgcyA9IHNkdi5Ub1N0cmluZyhDdWx0dXJlSW5mby5JbnZhcmlhbnRDdWx0dXJlKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGVsc2UgaWYgKHYgaXMgVGltZVNwYW4pCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgcyA9IG5ldyBEYXRlVGltZSgoKFRpbWVTcGFuKXYpLlRpY2tzKS5Ub09BRGF0ZSgpLlRvU3RyaW5nKEN1bHR1cmVJbmZvLkludmFyaWFudEN1bHR1cmUpOyA7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBlbHNlIGlmKHYuR2V0VHlwZSgpLklzUHJpbWl0aXZlIHx8IHYgaXMgZG91YmxlIHx8IHYgaXMgZGVjaW1hbCkKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICBpZiAodiBpcyBkb3VibGUgJiYgZG91YmxlLklzTmFOKChkb3VibGUpdikpCiAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICBzID0gIiI7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIGVsc2UgaWYgKHYgaXMgZG91YmxlICYmIGRvdWJsZS5Jc0luZmluaXR5KChkb3VibGUpdikpCiAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICBzID0gIiNOVU0hIjsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgZWxzZQogICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgcyA9IENvbnZlcnQuVG9Eb3VibGUodiwgQ3VsdHVyZUluZm8uSW52YXJpYW50Q3VsdHVyZSkuVG9TdHJpbmcoIlIxNSIsIEN1bHR1cmVJbmZvLkludmFyaWFudEN1bHR1cmUpOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGVsc2UKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICBzID0gdi5Ub1N0cmluZygpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CgogICAgICAgICAgICBjYXRjaAogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBzID0gIjAiOwogICAgICAgICAgICB9CiAgICAgICAgICAgIHJldHVybiBzOwogICAgICAgIH0KICAgICAgICBwcml2YXRlIHZvaWQgV3JpdGVSb3coU3RyaW5nQnVpbGRlciBjYWNoZSwgRXhjZWxTdHlsZUNvbGxlY3Rpb248RXhjZWxYZnM+IGNlbGxYZnMsIGludCBwcmV2Um93LCBpbnQgcm93KQogICAgICAgIHsKICAgICAgICAgICAgaWYgKHByZXZSb3cgIT0gLTEpIGNhY2hlLkFwcGVuZCgiPC9yb3c+Iik7CiAgICAgICAgICAgIC8vdWxvbmcgcm93SUQgPSBFeGNlbFJvdy5HZXRSb3dJRChTaGVldElELCByb3cpOwogICAgICAgICAgICBjYWNoZS5BcHBlbmRGb3JtYXQoIjxyb3cgcj1cInswfVwiICIsIHJvdyk7CiAgICAgICAgICAgIFJvd0ludGVybmFsIGN1cnJSb3cgPSBfdmFsdWVzLkdldFZhbHVlKHJvdywgMCkgYXMgUm93SW50ZXJuYWw7CiAgICAgICAgICAgIGlmIChjdXJyUm93ICE9IG51bGwpCiAgICAgICAgICAgIHsKCiAgICAgICAgICAgICAgICBpZiAoY3VyclJvdy5IaWRkZW4gPT0gdHJ1ZSkKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICBjYWNoZS5BcHBlbmQoImh0PVwiMFwiIGhpZGRlbj1cIjFcIiAiKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGVsc2UgaWYgKGN1cnJSb3cuSGVpZ2h0ICE9IERlZmF1bHRSb3dIZWlnaHQgJiYgY3VyclJvdy5IZWlnaHQ+PTApCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgY2FjaGUuQXBwZW5kRm9ybWF0KHN0cmluZy5Gb3JtYXQoQ3VsdHVyZUluZm8uSW52YXJpYW50Q3VsdHVyZSwgImh0PVwiezB9XCIgIiwgY3VyclJvdy5IZWlnaHQpKTsKICAgICAgICAgICAgICAgICAgICBpZiAoY3VyclJvdy5DdXN0b21IZWlnaHQpCiAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICBjYWNoZS5BcHBlbmQoImN1c3RvbUhlaWdodD1cIjFcIiAiKTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgaWYgKGN1cnJSb3cuT3V0bGluZUxldmVsID4gMCkKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICBjYWNoZS5BcHBlbmRGb3JtYXQoIm91dGxpbmVMZXZlbCA9XCJ7MH1cIiAiLCBjdXJyUm93Lk91dGxpbmVMZXZlbCk7CiAgICAgICAgICAgICAgICAgICAgaWYgKGN1cnJSb3cuQ29sbGFwc2VkKQogICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGN1cnJSb3cuSGlkZGVuKQogICAgICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjYWNoZS5BcHBlbmQoIiBjb2xsYXBzZWQ9XCIxXCIgIik7CiAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgZWxzZQogICAgICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjYWNoZS5BcHBlbmQoIiBjb2xsYXBzZWQ9XCIxXCIgaGlkZGVuPVwiMVwiICIpOyAvL0Fsd2F5cyBoaWRkZW4KICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGlmIChjdXJyUm93LlBob25ldGljKQogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIGNhY2hlLkFwcGVuZCgicGg9XCIxXCIgIik7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICAgICAgdmFyIHMgPSBfc3R5bGVzLkdldFZhbHVlKHJvdywgMCk7CiAgICAgICAgICAgIGlmIChzID4gMCkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgY2FjaGUuQXBwZW5kRm9ybWF0KCJzPVwiezB9XCIgY3VzdG9tRm9ybWF0PVwiMVwiIiwgY2VsbFhmc1tzXS5uZXdJRCk7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgY2FjaGUuQXBwZW5kKCI+Iik7CiAgICAgICAgfQogICAgICAgIHByaXZhdGUgdm9pZCBXcml0ZVJvdyhTdHJlYW1Xcml0ZXIgc3csIEV4Y2VsU3R5bGVDb2xsZWN0aW9uPEV4Y2VsWGZzPiBjZWxsWGZzLCBpbnQgcHJldlJvdywgaW50IHJvdykKICAgICAgICB7CiAgICAgICAgICAgIGlmIChwcmV2Um93ICE9IC0xKSBzdy5Xcml0ZSgiPC9yb3c+Iik7CiAgICAgICAgICAgIC8vdWxvbmcgcm93SUQgPSBFeGNlbFJvdy5HZXRSb3dJRChTaGVldElELCByb3cpOwogICAgICAgICAgICBzdy5Xcml0ZSgiPHJvdyByPVwiezB9XCIgIiwgcm93KTsKICAgICAgICAgICAgUm93SW50ZXJuYWwgY3VyclJvdyA9IF92YWx1ZXMuR2V0VmFsdWUocm93LCAwKSBhcyBSb3dJbnRlcm5hbDsKICAgICAgICAgICAgaWYgKGN1cnJSb3chPW51bGwpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgaWYgKGN1cnJSb3cuSGlkZGVuID09IHRydWUpCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgc3cuV3JpdGUoImh0PVwiMFwiIGhpZGRlbj1cIjFcIiAiKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGVsc2UgaWYgKGN1cnJSb3cuSGVpZ2h0ICE9IERlZmF1bHRSb3dIZWlnaHQpCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgc3cuV3JpdGUoc3RyaW5nLkZvcm1hdChDdWx0dXJlSW5mby5JbnZhcmlhbnRDdWx0dXJlLCAiaHQ9XCJ7MH1cIiAiLCBjdXJyUm93LkhlaWdodCkpOwogICAgICAgICAgICAgICAgICAgIGlmIChjdXJyUm93LkN1c3RvbUhlaWdodCkKICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgIHN3LldyaXRlKCJjdXN0b21IZWlnaHQ9XCIxXCIgIik7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgIGlmIChjdXJyUm93Lk91dGxpbmVMZXZlbCA+IDApCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgc3cuV3JpdGUoIm91dGxpbmVMZXZlbCA9XCJ7MH1cIiAiLCBjdXJyUm93Lk91dGxpbmVMZXZlbCk7CiAgICAgICAgICAgICAgICAgICAgaWYgKGN1cnJSb3cuQ29sbGFwc2VkKQogICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGN1cnJSb3cuSGlkZGVuKQogICAgICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBzdy5Xcml0ZSgiIGNvbGxhcHNlZD1cIjFcIiAiKTsKICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICAgICBlbHNlCiAgICAgICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN3LldyaXRlKCIgY29sbGFwc2VkPVwiMVwiIGhpZGRlbj1cIjFcIiAiKTsgLy9BbHdheXMgaGlkZGVuCiAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBpZiAoY3VyclJvdy5QaG9uZXRpYykKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICBzdy5Xcml0ZSgicGg9XCIxXCIgIik7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICAgICAgdmFyIHMgPSBfc3R5bGVzLkdldFZhbHVlKHJvdywgMCk7CiAgICAgICAgICAgIGlmIChzID4gMCkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgc3cuV3JpdGUoInM9XCJ7MH1cIiBjdXN0b21Gb3JtYXQ9XCIxXCIiLCBjZWxsWGZzW3NdLm5ld0lEKTsKICAgICAgICAgICAgfQogICAgICAgICAgICBzdy5Xcml0ZSgiPiIpOwogICAgICAgIH0KCiAgICAgICAgLy8vIDxzdW1tYXJ5PgogICAgICAgIC8vLyBVcGRhdGUgeG1sIHdpdGggaHlwZXJsaW5rcyAKICAgICAgICAvLy8gPC9zdW1tYXJ5PgogICAgICAgIC8vLyA8cGFyYW0gbmFtZT0ic3ciPlRoZSBzdHJlYW08L3BhcmFtPgogICAgICAgIHByaXZhdGUgdm9pZCBVcGRhdGVIeXBlckxpbmtzKFN0cmVhbVdyaXRlciBzdykKICAgICAgICB7CiAgICAgICAgICAgICAgICBEaWN0aW9uYXJ5PHN0cmluZywgc3RyaW5nPiBoeXBzID0gbmV3IERpY3Rpb25hcnk8c3RyaW5nLCBzdHJpbmc+KCk7CiAgICAgICAgICAgICAgICB2YXIgY3NlID0gbmV3IENlbGxzU3RvcmVFbnVtZXJhdG9yPFVyaT4oX2h5cGVyTGlua3MpOwogICAgICAgICAgICAgICAgYm9vbCBmaXJzdCA9IHRydWU7CiAgICAgICAgICAgICAgICAvL2ZvcmVhY2ggKHVsb25nIGNlbGwgaW4gX2h5cGVyTGlua3MpCiAgICAgICAgICAgICAgICB3aGlsZShjc2UuTmV4dCgpKQogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIGlmIChmaXJzdCkKICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgIHN3LldyaXRlKCI8aHlwZXJsaW5rcz4iKTsKICAgICAgICAgICAgICAgICAgICAgICAgZmlyc3QgPSBmYWxzZTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgLy9pbnQgcm93LCBjb2w7CiAgICAgICAgICAgICAgICAgICAgdmFyIHVyaSA9IF9oeXBlckxpbmtzLkdldFZhbHVlKGNzZS5Sb3csIGNzZS5Db2x1bW4pOwogICAgICAgICAgICAgICAgICAgIC8vRXhjZWxDZWxsIGNlbGwgPSBfY2VsbHNbY2VsbElkXSBhcyBFeGNlbENlbGw7CiAgICAgICAgICAgICAgICAgICAgaWYgKHVyaSBpcyBFeGNlbEh5cGVyTGluayAmJiAhc3RyaW5nLklzTnVsbE9yRW1wdHkoKHVyaSBhcyBFeGNlbEh5cGVyTGluaykuUmVmZXJlbmNlQWRkcmVzcykpCiAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICBFeGNlbEh5cGVyTGluayBobCA9IHVyaSBhcyBFeGNlbEh5cGVyTGluazsKICAgICAgICAgICAgICAgICAgICAgICAgc3cuV3JpdGUoIjxoeXBlcmxpbmsgcmVmPVwiezB9XCIgbG9jYXRpb249XCJ7MX1cIiB7Mn17M30vPiIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQ2VsbHNbY3NlLlJvdywgY3NlLkNvbHVtbiwgY3NlLlJvdyArIGhsLlJvd1NwYW5uLCBjc2UuQ29sdW1uICsgaGwuQ29sU3Bhbm5dLkFkZHJlc3MsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEV4Y2VsQ2VsbEJhc2UuR2V0RnVsbEFkZHJlc3MoU2VjdXJpdHlFbGVtZW50LkVzY2FwZShOYW1lKSwgU2VjdXJpdHlFbGVtZW50LkVzY2FwZShobC5SZWZlcmVuY2VBZGRyZXNzKSksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN0cmluZy5Jc051bGxPckVtcHR5KGhsLkRpc3BsYXkpID8gIiIgOiAiZGlzcGxheT1cIiIgKyBTZWN1cml0eUVsZW1lbnQuRXNjYXBlKGhsLkRpc3BsYXkpICsgIlwiICIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN0cmluZy5Jc051bGxPckVtcHR5KGhsLlRvb2xUaXApID8gIiIgOiAidG9vbHRpcD1cIiIgKyBTZWN1cml0eUVsZW1lbnQuRXNjYXBlKGhsLlRvb2xUaXApICsgIlwiICIpOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICBlbHNlIGlmKCB1cmkhPW51bGwpCiAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICBzdHJpbmcgaWQ7CiAgICAgICAgICAgICAgICAgICAgICAgIFVyaSBoeXA7CiAgICAgICAgICAgICAgICAgICAgICAgIGlmICh1cmkgaXMgRXhjZWxIeXBlckxpbmspCiAgICAgICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGh5cCA9ICgoRXhjZWxIeXBlckxpbmspdXJpKS5PcmlnaW5hbFVyaTsKICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICAgICBlbHNlCiAgICAgICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGh5cCA9IHVyaTsKICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICAgICBpZiAoaHlwcy5Db250YWluc0tleShoeXAuT3JpZ2luYWxTdHJpbmcpKQogICAgICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZCA9IGh5cHNbaHlwLk9yaWdpbmFsU3RyaW5nXTsKICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICAgICBlbHNlCiAgICAgICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZhciByZWxhdGlvbnNoaXAgPSBQYXJ0LkNyZWF0ZVJlbGF0aW9uc2hpcChoeXAsIFBhY2thZ2luZy5UYXJnZXRNb2RlLkV4dGVybmFsLCBFeGNlbFBhY2thZ2Uuc2NoZW1hSHlwZXJsaW5rKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmICh1cmkgaXMgRXhjZWxIeXBlckxpbmspCiAgICAgICAgICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRXhjZWxIeXBlckxpbmsgaGwgPSB1cmkgYXMgRXhjZWxIeXBlckxpbms7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc3cuV3JpdGUoIjxoeXBlcmxpbmsgcmVmPVwiezB9XCIgezJ9ezN9cjppZD1cInsxfVwiIC8+IiwgRXhjZWxDZWxsQmFzZS5HZXRBZGRyZXNzKGNzZS5Sb3csIGNzZS5Db2x1bW4pLCByZWxhdGlvbnNoaXAuSWQsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc3RyaW5nLklzTnVsbE9yRW1wdHkoaGwuRGlzcGxheSkgPyAiIiA6ICJkaXNwbGF5PVwiIiArIFNlY3VyaXR5RWxlbWVudC5Fc2NhcGUoaGwuRGlzcGxheSkgKyAiXCIgIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc3RyaW5nLklzTnVsbE9yRW1wdHkoaGwuVG9vbFRpcCkgPyAiIiA6ICJ0b29sdGlwPVwiIiArIFNlY3VyaXR5RWxlbWVudC5Fc2NhcGUoaGwuVG9vbFRpcCkgKyAiXCIgIik7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBlbHNlCiAgICAgICAgICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc3cuV3JpdGUoIjxoeXBlcmxpbmsgcmVmPVwiezB9XCIgcjppZD1cInsxfVwiIC8+IiwgRXhjZWxDZWxsQmFzZS5HZXRBZGRyZXNzKGNzZS5Sb3csIGNzZS5Db2x1bW4pLCByZWxhdGlvbnNoaXAuSWQpOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICAgICAgICAgaWQgPSByZWxhdGlvbnNoaXAuSWQ7CiAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgLy9jZWxsLkh5cGVyTGlua1JJZCA9IGlkOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGlmICghZmlyc3QpCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgc3cuV3JpdGUoIjwvaHlwZXJsaW5rcz4iKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgLy8vIDxzdW1tYXJ5PgogICAgICAgIC8vLyBDcmVhdGUgdGhlIGh5cGVybGlua3Mgbm9kZSBpbiB0aGUgWE1MCiAgICAgICAgLy8vIDwvc3VtbWFyeT4KICAgICAgICAvLy8gPHJldHVybnM+PC9yZXR1cm5zPgogICAgICAgIHByaXZhdGUgWG1sTm9kZSBDcmVhdGVIeXBlckxpbmtDb2xsZWN0aW9uKCkKICAgICAgICB7CiAgICAgICAgICAgIFhtbEVsZW1lbnQgaGw9X3dvcmtzaGVldFhtbC5DcmVhdGVFbGVtZW50KCJoeXBlcmxpbmtzIixFeGNlbFBhY2thZ2Uuc2NoZW1hTWFpbik7CiAgICAgICAgICAgIFhtbE5vZGUgcHJldk5vZGUgPSBfd29ya3NoZWV0WG1sLlNlbGVjdFNpbmdsZU5vZGUoIi8vZDpjb25kaXRpb25hbEZvcm1hdHRpbmciLCBOYW1lU3BhY2VNYW5hZ2VyKTsKICAgICAgICAgICAgaWYgKHByZXZOb2RlID09IG51bGwpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIHByZXZOb2RlID0gX3dvcmtzaGVldFhtbC5TZWxlY3RTaW5nbGVOb2RlKCIvL2Q6bWVyZ2VDZWxscyIsIE5hbWVTcGFjZU1hbmFnZXIpOwogICAgICAgICAgICAgICAgaWYgKHByZXZOb2RlID09IG51bGwpCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgcHJldk5vZGUgPSBfd29ya3NoZWV0WG1sLlNlbGVjdFNpbmdsZU5vZGUoIi8vZDpzaGVldERhdGEiLCBOYW1lU3BhY2VNYW5hZ2VyKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgICAgICByZXR1cm4gX3dvcmtzaGVldFhtbC5Eb2N1bWVudEVsZW1lbnQuSW5zZXJ0QWZ0ZXIoaGwsIHByZXZOb2RlKTsKICAgICAgICB9CiAgICAgICAgLy8vIDxzdW1tYXJ5PgogICAgICAgIC8vLyBEaW1lbnNpb24gYWRkcmVzcyBmb3IgdGhlIHdvcmtzaGVldC4gCiAgICAgICAgLy8vIFRvcCBsZWZ0IGNlbGwgdG8gQm90dG9tIHJpZ2h0LgogICAgICAgIC8vLyBJZiB0aGUgd29ya3NoZWV0IGhhcyBubyBjZWxscywgbnVsbCBpcyByZXR1cm5lZAogICAgICAgIC8vLyA8L3N1bW1hcnk+CiAgICAgICAgcHVibGljIEV4Y2VsQWRkcmVzc0Jhc2UgRGltZW5zaW9uCiAgICAgICAgewogICAgICAgICAgICBnZXQKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgQ2hlY2tTaGVldFR5cGUoKTsKICAgICAgICAgICAgICAgIGludCBmcm9tUm93LCBmcm9tQ29sLCB0b1JvdywgdG9Db2w7CiAgICAgICAgICAgICAgICBpZiAoX3ZhbHVlcy5HZXREaW1lbnNpb24ob3V0IGZyb21Sb3csIG91dCBmcm9tQ29sLCBvdXQgdG9Sb3csIG91dCB0b0NvbCkpCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgdmFyIGFkZHIgPSBuZXcgRXhjZWxBZGRyZXNzQmFzZShmcm9tUm93LCBmcm9tQ29sLCB0b1JvdywgdG9Db2wpOwogICAgICAgICAgICAgICAgICAgIGFkZHIuX3dzID0gTmFtZTsKICAgICAgICAgICAgICAgICAgICByZXR1cm4gYWRkcjsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGVsc2UKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICByZXR1cm4gbnVsbDsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgIH0KICAgICAgICBFeGNlbFNoZWV0UHJvdGVjdGlvbiBfcHJvdGVjdGlvbj1udWxsOwogICAgICAgIC8vLyA8c3VtbWFyeT4KICAgICAgICAvLy8gQWNjZXNzIHRvIHNoZWV0IHByb3RlY3Rpb24gcHJvcGVydGllcwogICAgICAgIC8vLyA8L3N1bW1hcnk+CiAgICAgICAgcHVibGljIEV4Y2VsU2hlZXRQcm90ZWN0aW9uIFByb3RlY3Rpb24KICAgICAgICB7CiAgICAgICAgICAgIGdldAogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBpZiAoX3Byb3RlY3Rpb24gPT0gbnVsbCkKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICBfcHJvdGVjdGlvbiA9IG5ldyBFeGNlbFNoZWV0UHJvdGVjdGlvbihOYW1lU3BhY2VNYW5hZ2VyLCBUb3BOb2RlLCB0aGlzKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIHJldHVybiBfcHJvdGVjdGlvbjsKICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgcHJpdmF0ZSBFeGNlbFByb3RlY3RlZFJhbmdlQ29sbGVjdGlvbiBfcHJvdGVjdGVkUmFuZ2VzOwogICAgICAgIHB1YmxpYyBFeGNlbFByb3RlY3RlZFJhbmdlQ29sbGVjdGlvbiBQcm90ZWN0ZWRSYW5nZXMKICAgICAgICB7CiAgICAgICAgICAgIGdldAogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBpZiAoX3Byb3RlY3RlZFJhbmdlcyA9PSBudWxsKQogICAgICAgICAgICAgICAgICAgIF9wcm90ZWN0ZWRSYW5nZXMgPSBuZXcgRXhjZWxQcm90ZWN0ZWRSYW5nZUNvbGxlY3Rpb24oTmFtZVNwYWNlTWFuYWdlciwgVG9wTm9kZSwgdGhpcyk7CiAgICAgICAgICAgICAgICByZXR1cm4gX3Byb3RlY3RlZFJhbmdlczsKICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgI3JlZ2lvbiBEcmF3aW5nCiAgICAgICAgRXhjZWxEcmF3aW5ncyBfZHJhd2luZ3MgPSBudWxsOwogICAgICAgIC8vLyA8c3VtbWFyeT4KICAgICAgICAvLy8gQ29sbGVjdGlvbiBvZiBkcmF3aW5nLW9iamVjdHMgbGlrZSBzaGFwZXMsIGltYWdlcyBhbmQgY2hhcnRzCiAgICAgICAgLy8vIDwvc3VtbWFyeT4KICAgICAgICBwdWJsaWMgRXhjZWxEcmF3aW5ncyBEcmF3aW5ncwogICAgICAgIHsKICAgICAgICAgICAgZ2V0CiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIGlmIChfZHJhd2luZ3MgPT0gbnVsbCkKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICBfZHJhd2luZ3MgPSBuZXcgRXhjZWxEcmF3aW5ncyhfcGFja2FnZSwgdGhpcyk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICByZXR1cm4gX2RyYXdpbmdzOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgICNlbmRyZWdpb24KICAgICAgICBFeGNlbFRhYmxlQ29sbGVjdGlvbiBfdGFibGVzID0gbnVsbDsKICAgICAgICAvLy8gPHN1bW1hcnk+CiAgICAgICAgLy8vIFRhYmxlcyBkZWZpbmVkIGluIHRoZSB3b3Jrc2hlZXQuCiAgICAgICAgLy8vIDwvc3VtbWFyeT4KICAgICAgICBwdWJsaWMgRXhjZWxUYWJsZUNvbGxlY3Rpb24gVGFibGVzCiAgICAgICAgewogICAgICAgICAgICBnZXQKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgQ2hlY2tTaGVldFR5cGUoKTsKICAgICAgICAgICAgICAgIGlmIChXb3JrYm9vay5fbmV4dFRhYmxlSUQgPT0gaW50Lk1pblZhbHVlKSBXb3JrYm9vay5SZWFkQWxsVGFibGVzKCk7CiAgICAgICAgICAgICAgICBpZiAoX3RhYmxlcyA9PSBudWxsKQogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIF90YWJsZXMgPSBuZXcgRXhjZWxUYWJsZUNvbGxlY3Rpb24odGhpcyk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICByZXR1cm4gX3RhYmxlczsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgICAgICBFeGNlbFBpdm90VGFibGVDb2xsZWN0aW9uIF9waXZvdFRhYmxlcyA9IG51bGw7CiAgICAgICAgLy8vIDxzdW1tYXJ5PgogICAgICAgIC8vLyBQaXZvdHRhYmxlcyBkZWZpbmVkIGluIHRoZSB3b3Jrc2hlZXQuCiAgICAgICAgLy8vIDwvc3VtbWFyeT4KICAgICAgICBwdWJsaWMgRXhjZWxQaXZvdFRhYmxlQ29sbGVjdGlvbiBQaXZvdFRhYmxlcwogICAgICAgIHsKICAgICAgICAgICAgZ2V0CiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIENoZWNrU2hlZXRUeXBlKCk7CiAgICAgICAgICAgICAgICBpZiAoX3Bpdm90VGFibGVzID09IG51bGwpCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgaWYgKFdvcmtib29rLl9uZXh0UGl2b3RUYWJsZUlEID09IGludC5NaW5WYWx1ZSkgV29ya2Jvb2suUmVhZEFsbFRhYmxlcygpOwogICAgICAgICAgICAgICAgICAgIF9waXZvdFRhYmxlcyA9IG5ldyBFeGNlbFBpdm90VGFibGVDb2xsZWN0aW9uKHRoaXMpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgcmV0dXJuIF9waXZvdFRhYmxlczsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgICAgICBwcml2YXRlIEV4Y2VsQ29uZGl0aW9uYWxGb3JtYXR0aW5nQ29sbGVjdGlvbiBfY29uZGl0aW9uYWxGb3JtYXR0aW5nID0gbnVsbDsKICAgICAgICAvLy8gPHN1bW1hcnk+CiAgICAgICAgLy8vIENvbmRpdGlvbmFsRm9ybWF0dGluZyBkZWZpbmVkIGluIHRoZSB3b3Jrc2hlZXQuIFVzZSB0aGUgQWRkIG1ldGhvZHMgdG8gY3JlYXRlIENvbmRpdGlvbmFsRm9ybWF0dGluZyBhbmQgYWRkIHRoZW0gdG8gdGhlIHdvcmtzaGVldC4gVGhlbgogICAgICAgIC8vLyBzZXQgdGhlIHByb3BlcnRpZXMgb24gdGhlIGluc3RhbmNlIHJldHVybmVkLgogICAgICAgIC8vLyA8L3N1bW1hcnk+CiAgICAgICAgLy8vIDxzZWVhbHNvIGNyZWY9IkV4Y2VsQ29uZGl0aW9uYWxGb3JtYXR0aW5nQ29sbGVjdGlvbiIvPgogICAgICAgIHB1YmxpYyBFeGNlbENvbmRpdGlvbmFsRm9ybWF0dGluZ0NvbGxlY3Rpb24gQ29uZGl0aW9uYWxGb3JtYXR0aW5nCiAgICAgICAgewogICAgICAgICAgICBnZXQKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgQ2hlY2tTaGVldFR5cGUoKTsKICAgICAgICAgICAgICAgIGlmIChfY29uZGl0aW9uYWxGb3JtYXR0aW5nID09IG51bGwpCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgX2NvbmRpdGlvbmFsRm9ybWF0dGluZyA9IG5ldyBFeGNlbENvbmRpdGlvbmFsRm9ybWF0dGluZ0NvbGxlY3Rpb24odGhpcyk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICByZXR1cm4gX2NvbmRpdGlvbmFsRm9ybWF0dGluZzsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgICAgICBwcml2YXRlIEV4Y2VsRGF0YVZhbGlkYXRpb25Db2xsZWN0aW9uIF9kYXRhVmFsaWRhdGlvbiA9IG51bGw7CiAgICAgICAgLy8vIDxzdW1tYXJ5PgogICAgICAgIC8vLyBEYXRhVmFsaWRhdGlvbiBkZWZpbmVkIGluIHRoZSB3b3Jrc2hlZXQuIFVzZSB0aGUgQWRkIG1ldGhvZHMgdG8gY3JlYXRlIERhdGFWYWxpZGF0aW9ucyBhbmQgYWRkIHRoZW0gdG8gdGhlIHdvcmtzaGVldC4gVGhlbgogICAgICAgIC8vLyBzZXQgdGhlIHByb3BlcnRpZXMgb24gdGhlIGluc3RhbmNlIHJldHVybmVkLgogICAgICAgIC8vLyA8L3N1bW1hcnk+CiAgICAgICAgLy8vIDxzZWVhbHNvIGNyZWY9IkV4Y2VsRGF0YVZhbGlkYXRpb25Db2xsZWN0aW9uIi8+CiAgICAgICAgcHVibGljIEV4Y2VsRGF0YVZhbGlkYXRpb25Db2xsZWN0aW9uIERhdGFWYWxpZGF0aW9ucwogICAgICAgIHsKICAgICAgICAgICAgZ2V0CiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIENoZWNrU2hlZXRUeXBlKCk7CiAgICAgICAgICAgICAgICBpZiAoX2RhdGFWYWxpZGF0aW9uID09IG51bGwpCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgX2RhdGFWYWxpZGF0aW9uID0gbmV3IEV4Y2VsRGF0YVZhbGlkYXRpb25Db2xsZWN0aW9uKHRoaXMpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgcmV0dXJuIF9kYXRhVmFsaWRhdGlvbjsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgICAgICBFeGNlbEJhY2tncm91bmRJbWFnZSBfYmFja2dyb3VuZEltYWdlID0gbnVsbDsKICAgICAgICAvLy8gPHN1bW1hcnk+CiAgICAgICAgLy8vIEFuIGltYWdlIGRpc3BsYXllZCBhcyB0aGUgYmFja2dyb3VuZCBvZiB0aGUgd29ya3NoZWV0LgogICAgICAgIC8vLyA8L3N1bW1hcnk+CiAgICAgICAgcHVibGljIEV4Y2VsQmFja2dyb3VuZEltYWdlIEJhY2tncm91bmRJbWFnZQogICAgICAgIHsKICAgICAgICAgICAgZ2V0CiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIGlmIChfYmFja2dyb3VuZEltYWdlID09IG51bGwpCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgX2JhY2tncm91bmRJbWFnZSA9IG5ldyBFeGNlbEJhY2tncm91bmRJbWFnZShOYW1lU3BhY2VNYW5hZ2VyLCBUb3BOb2RlLCB0aGlzKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIHJldHVybiBfYmFja2dyb3VuZEltYWdlOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIC8vLyA8c3VtbWFyeT4KCQkvLy8gUmV0dXJucyB0aGUgc3R5bGUgSUQgZ2l2ZW4gYSBzdHlsZSBuYW1lLiAgCgkJLy8vIFRoZSBzdHlsZSBJRCB3aWxsIGJlIGNyZWF0ZWQgaWYgbm90IGZvdW5kLCBidXQgb25seSBpZiB0aGUgc3R5bGUgbmFtZSBleGlzdHMhCgkJLy8vIDwvc3VtbWFyeT4KCQkvLy8gPHBhcmFtIG5hbWU9IlN0eWxlTmFtZSI+PC9wYXJhbT4KCQkvLy8gPHJldHVybnM+PC9yZXR1cm5zPgoJCWludGVybmFsIGludCBHZXRTdHlsZUlEKHN0cmluZyBTdHlsZU5hbWUpCgkJewoJCQlFeGNlbE5hbWVkU3R5bGVYbWwgbmFtZWRTdHlsZT1udWxsOwogICAgICAgICAgICBXb3JrYm9vay5TdHlsZXMuTmFtZWRTdHlsZXMuRmluZEJ5SUQoU3R5bGVOYW1lLCByZWYgbmFtZWRTdHlsZSk7CiAgICAgICAgICAgIGlmIChuYW1lZFN0eWxlLlhmSWQgPT0gaW50Lk1pblZhbHVlKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBuYW1lZFN0eWxlLlhmSWQ9V29ya2Jvb2suU3R5bGVzLkNlbGxYZnMuRmluZEluZGV4QnlJRChuYW1lZFN0eWxlLlN0eWxlLklkKTsKICAgICAgICAgICAgfQogICAgICAgICAgICByZXR1cm4gbmFtZWRTdHlsZS5YZklkOwoJCX0KICAgICAgICAvLy8gPHN1bW1hcnk+CiAgICAgICAgLy8vIFRoZSB3b3JrYm9vayBvYmplY3QKICAgICAgICAvLy8gPC9zdW1tYXJ5PgogICAgICAgIHB1YmxpYyBFeGNlbFdvcmtib29rIFdvcmtib29rCiAgICAgICAgewogICAgICAgICAgICBnZXQKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgcmV0dXJuIF9wYWNrYWdlLldvcmtib29rOwogICAgICAgICAgICB9CiAgICAgICAgfQoJCSNlbmRyZWdpb24KICAgICAgICAjZW5kcmVnaW9uICAvLyBFTkQgV29ya3NoZWV0IFByaXZhdGUgTWV0aG9kcwoKICAgICAgICAvLy8gPHN1bW1hcnk+CiAgICAgICAgLy8vIEdldCB0aGUgbmV4dCBJRCBmcm9tIGEgc2hhcmVkIGZvcm11bGEgb3IgYW4gQXJyYXkgZm9ybXVsYQogICAgICAgIC8vLyBTaGFyZWRmb3J1bWxhcyB3aWxsIGhhdmUgYW4gaWQgZnJvbSAwLXguIEFycmF5IGZvcm11bGEgaWRzIHN0YXJ0IGZyb20gMHg0MDAwMDAxLS4gCiAgICAgICAgLy8vIDwvc3VtbWFyeT4KICAgICAgICAvLy8gPHBhcmFtIG5hbWU9ImlzQXJyYXkiPklmIHRoZSBmb3JtdWxhIGlzIGFuIGFycmF5IGZvcm11bGE8L3BhcmFtPgogICAgICAgIC8vLyA8cmV0dXJucz48L3JldHVybnM+CiAgICAgICAgaW50ZXJuYWwgaW50IEdldE1heFNoYXJlRnVuY3Rpb25JbmRleChib29sIGlzQXJyYXkpCiAgICAgICAgewogICAgICAgICAgICBpbnQgaT1fc2hhcmVkRm9ybXVsYXMuQ291bnQgKyAxOwogICAgICAgICAgICBpZiAoaXNBcnJheSkKICAgICAgICAgICAgICAgIGkgfD0gMHg0MDAwMDAwMDsKCiAgICAgICAgICAgIHdoaWxlKF9zaGFyZWRGb3JtdWxhcy5Db250YWluc0tleShpKSkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgaSsrOwogICAgICAgICAgICB9CiAgICAgICAgICAgIHJldHVybiBpOwogICAgICAgIH0KICAgICAgICBpbnRlcm5hbCB2b2lkIFNldEhGTGVnYWN5RHJhd2luZ1JlbChzdHJpbmcgcmVsSUQpCiAgICAgICAgewogICAgICAgICAgICBTZXRYbWxOb2RlU3RyaW5nKCJkOmxlZ2FjeURyYXdpbmdIRi9AcjppZCIsIHJlbElEKTsKICAgICAgICB9CiAgICAgICAgaW50ZXJuYWwgdm9pZCBSZW1vdmVMZWdhY3lEcmF3aW5nUmVsKHN0cmluZyByZWxJRCkKICAgICAgICB7CiAgICAgICAgICAgIHZhciBuID0gV29ya3NoZWV0WG1sLkRvY3VtZW50RWxlbWVudC5TZWxlY3RTaW5nbGVOb2RlKHN0cmluZy5Gb3JtYXQoImQ6bGVnYWN5RHJhd2luZ1tAcjppZD1cInswfVwiXSIsIHJlbElEKSwgTmFtZVNwYWNlTWFuYWdlcik7CiAgICAgICAgICAgIGlmIChuICE9IG51bGwpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIG4uUGFyZW50Tm9kZS5SZW1vdmVDaGlsZChuKTsKICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgaW50ZXJuYWwgdm9pZCBVcGRhdGVDZWxsc1dpdGhEYXRlMTkwNFNldHRpbmcoKQogICAgICAgIHsKICAgICAgICAgICAgdmFyIGNzZSA9IG5ldyBDZWxsc1N0b3JlRW51bWVyYXRvcjxvYmplY3Q+KF92YWx1ZXMpOwogICAgICAgICAgICB2YXIgb2Zmc2V0ID0gV29ya2Jvb2suRGF0ZTE5MDQgPyAtRXhjZWxXb3JrYm9vay5kYXRlMTkwNE9mZnNldCA6IEV4Y2VsV29ya2Jvb2suZGF0ZTE5MDRPZmZzZXQ7CiAgICAgICAgICAgIHdoaWxlKGNzZS5Nb3ZlTmV4dCgpKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBpZiAoY3NlLlZhbHVlIGlzIERhdGVUaW1lKQogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIHRyeQogICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgZG91YmxlIHNkdiA9ICgoRGF0ZVRpbWUpY3NlLlZhbHVlKS5Ub09BRGF0ZSgpOwogICAgICAgICAgICAgICAgICAgICAgICBzZHYgKz0gb2Zmc2V0OwoKICAgICAgICAgICAgICAgICAgICAgICAgY3NlLlZhbHVlID0gRGF0ZVRpbWUuRnJvbU9BRGF0ZShzZHYpOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICBjYXRjaAogICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgaW50ZXJuYWwgc3RyaW5nIEdldEZvcm11bGEoaW50IHJvdywgaW50IGNvbCkKICAgICAgICB7CiAgICAgICAgICAgIHZhciB2ID0gX2Zvcm11bGFzLkdldFZhbHVlKHJvdywgY29sKTsKICAgICAgICAgICAgaWYgKHYgaXMgaW50KQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICByZXR1cm4gX3NoYXJlZEZvcm11bGFzWyhpbnQpdl0uR2V0Rm9ybXVsYShyb3csY29sLCBOYW1lKTsKICAgICAgICAgICAgfQogICAgICAgICAgICBlbHNlIGlmICh2ICE9IG51bGwpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIHJldHVybiB2LlRvU3RyaW5nKCk7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgZWxzZQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICByZXR1cm4gIiI7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgaW50ZXJuYWwgc3RyaW5nIEdldEZvcm11bGFSMUMxKGludCByb3csIGludCBjb2wpCiAgICAgICAgewogICAgICAgICAgICB2YXIgdiA9IF9mb3JtdWxhcy5HZXRWYWx1ZShyb3csIGNvbCk7CiAgICAgICAgICAgIGlmICh2IGlzIGludCkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgdmFyIHNmID0gX3NoYXJlZEZvcm11bGFzWyhpbnQpdl07CiAgICAgICAgICAgICAgICByZXR1cm4gRXhjZWxDZWxsQmFzZS5UcmFuc2xhdGVUb1IxQzEoc2YuRm9ybXVsYSwgc2YuU3RhcnRSb3csIHNmLlN0YXJ0Q29sKTsKICAgICAgICAgICAgfQogICAgICAgICAgICBlbHNlIGlmICh2ICE9IG51bGwpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIHJldHVybiBFeGNlbENlbGxCYXNlLlRyYW5zbGF0ZVRvUjFDMSh2LlRvU3RyaW5nKCksIHJvdywgY29sKTsKICAgICAgICAgICAgfQogICAgICAgICAgICBlbHNlCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIHJldHVybiAiIjsKICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgcHJpdmF0ZSB2b2lkIERpc3Bvc2VJbnRlcm5hbChJRGlzcG9zYWJsZSBjYW5kaWRhdGVEaXNwb3NhYmxlKQogICAgICAgIHsKICAgICAgICAgICAgaWYgKGNhbmRpZGF0ZURpc3Bvc2FibGUgIT0gbnVsbCkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgY2FuZGlkYXRlRGlzcG9zYWJsZS5EaXNwb3NlKCk7CiAgICAgICAgICAgIH0KICAgICAgICB9CgoKICAgICAgICBwdWJsaWMgdm9pZCBEaXNwb3NlKCkKICAgICAgICB7CiAgICAgICAgICAgIERpc3Bvc2VJbnRlcm5hbChfdmFsdWVzKTsKICAgICAgICAgICAgRGlzcG9zZUludGVybmFsKF9mb3JtdWxhcyk7CiAgICAgICAgICAgIERpc3Bvc2VJbnRlcm5hbChfZmxhZ3MpOwogICAgICAgICAgICBEaXNwb3NlSW50ZXJuYWwoX2h5cGVyTGlua3MpOwogICAgICAgICAgICBEaXNwb3NlSW50ZXJuYWwoX3N0eWxlcyk7CiAgICAgICAgICAgIERpc3Bvc2VJbnRlcm5hbChfdHlwZXMpOwogICAgICAgICAgICBEaXNwb3NlSW50ZXJuYWwoX2NvbW1lbnRzU3RvcmUpOwogICAgICAgICAgICBEaXNwb3NlSW50ZXJuYWwoX2Zvcm11bGFUb2tlbnMpOwoKICAgICAgICAgICAgX3ZhbHVlcyA9IG51bGw7CiAgICAgICAgICAgIF9mb3JtdWxhcyA9IG51bGw7CiAgICAgICAgICAgIF9mbGFncyA9IG51bGw7CiAgICAgICAgICAgIF9oeXBlckxpbmtzID0gbnVsbDsKICAgICAgICAgICAgX3N0eWxlcyA9IG51bGw7CiAgICAgICAgICAgIF90eXBlcyA9IG51bGw7CiAgICAgICAgICAgIF9jb21tZW50c1N0b3JlID0gbnVsbDsKICAgICAgICAgICAgX2Zvcm11bGFUb2tlbnMgPSBudWxsOwoKICAgICAgICAgICAgX3BhY2thZ2UgPSBudWxsOwogICAgICAgICAgICBfcGl2b3RUYWJsZXMgPSBudWxsOwogICAgICAgICAgICBfcHJvdGVjdGlvbiA9IG51bGw7CiAgICAgICAgICAgIGlmKF9zaGFyZWRGb3JtdWxhcyAhPSBudWxsKSBfc2hhcmVkRm9ybXVsYXMuQ2xlYXIoKTsKICAgICAgICAgICAgX3NoYXJlZEZvcm11bGFzID0gbnVsbDsKICAgICAgICAgICAgX3NoZWV0VmlldyA9IG51bGw7CiAgICAgICAgICAgIF90YWJsZXMgPSBudWxsOwogICAgICAgICAgICBfdm1sRHJhd2luZ3MgPSBudWxsOwogICAgICAgICAgICBfY29uZGl0aW9uYWxGb3JtYXR0aW5nID0gbnVsbDsKICAgICAgICAgICAgX2RhdGFWYWxpZGF0aW9uID0gbnVsbDsKICAgICAgICAgICAgX2RyYXdpbmdzID0gbnVsbDsKICAgICAgICB9CgogICAgICAgIC8vLyA8c3VtbWFyeT4KICAgICAgICAvLy8gR2V0IHRoZSBFeGNlbENvbHVtbiBmb3IgY29sdW1uIChzcGFuIENvbHVtbk1pbiBhbmQgQ29sdW1uTWF4KQogICAgICAgIC8vLyA8L3N1bW1hcnk+CiAgICAgICAgLy8vIDxwYXJhbSBuYW1lPSJjb2x1bW4iPjwvcGFyYW0+CiAgICAgICAgLy8vIDxyZXR1cm5zPjwvcmV0dXJucz4KICAgICAgICBpbnRlcm5hbCBFeGNlbENvbHVtbiBHZXRDb2x1bW4oaW50IGNvbHVtbikKICAgICAgICB7CiAgICAgICAgICAgIHZhciBjID0gX3ZhbHVlcy5HZXRWYWx1ZSgwLCBjb2x1bW4pIGFzIEV4Y2VsQ29sdW1uOwogICAgICAgICAgICBpZiAoYyA9PSBudWxsKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBpbnQgcm93ID0gMCwgY29sID0gY29sdW1uOwogICAgICAgICAgICAgICAgaWYgKF92YWx1ZXMuUHJldkNlbGwocmVmIHJvdywgcmVmIGNvbCkpCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgYyA9IF92YWx1ZXMuR2V0VmFsdWUoMCwgY29sKSBhcyBFeGNlbENvbHVtbjsKICAgICAgICAgICAgICAgICAgICBpZiAoYyAhPSBudWxsICYmIGMuQ29sdW1uTWF4ID49IGNvbHVtbikKICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBjOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICByZXR1cm4gbnVsbDsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgICAgICByZXR1cm4gYzsKCiAgICAgICAgfQoKICAgICAgICBwdWJsaWMgYm9vbCBFcXVhbHMoRXhjZWxXb3Jrc2hlZXQgeCwgRXhjZWxXb3Jrc2hlZXQgeSkKICAgICAgICB7CiAgICAgICAgICAgIHJldHVybiB4Lk5hbWUgPT0geS5OYW1lICYmIHguU2hlZXRJRCA9PSB5LlNoZWV0SUQgJiYgeC5Xb3Jrc2hlZXRYbWwuT3V0ZXJYbWwgPT0geS5Xb3Jrc2hlZXRYbWwuT3V0ZXJYbWw7CiAgICAgICAgfQoKICAgICAgICBwdWJsaWMgaW50IEdldEhhc2hDb2RlKEV4Y2VsV29ya3NoZWV0IG9iaikKICAgICAgICB7CiAgICAgICAgICAgIHJldHVybiBvYmouV29ya3NoZWV0WG1sLk91dGVyWG1sLkdldEhhc2hDb2RlKCk7CiAgICAgICAgfQoJfSAgLy8gRU5EIGNsYXNzIFdvcmtzaGVldAp9Cg==