LyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogWW91IG1heSBhbWVuZCBhbmQgZGlzdHJpYnV0ZSBhcyB5b3UgbGlrZSwgYnV0IGRvbid0IHJlbW92ZSB0aGlzIGhlYWRlciEKICoKICogRVBQbHVzIHByb3ZpZGVzIHNlcnZlci1zaWRlIGdlbmVyYXRpb24gb2YgRXhjZWwgMjAwNy8yMDEwIHNwcmVhZHNoZWV0cy4KICogU2VlIGh0dHA6Ly93d3cuY29kZXBsZXguY29tL0VQUGx1cyBmb3IgZGV0YWlscy4KICoKICogQ29weXJpZ2h0IChDKSAyMDExICBKYW4gS+RsbG1hbgogKgogKiBUaGlzIGxpYnJhcnkgaXMgZnJlZSBzb2Z0d2FyZTsgeW91IGNhbiByZWRpc3RyaWJ1dGUgaXQgYW5kL29yCiAqIG1vZGlmeSBpdCB1bmRlciB0aGUgdGVybXMgb2YgdGhlIEdOVSBMZXNzZXIgR2VuZXJhbCBQdWJsaWMKICogTGljZW5zZSBhcyBwdWJsaXNoZWQgYnkgdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbjsgZWl0aGVyCiAqIHZlcnNpb24gMi4xIG9mIHRoZSBMaWNlbnNlLCBvciAoYXQgeW91ciBvcHRpb24pIGFueSBsYXRlciB2ZXJzaW9uLgoKICogVGhpcyBsaWJyYXJ5IGlzIGRpc3RyaWJ1dGVkIGluIHRoZSBob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsCiAqIGJ1dCBXSVRIT1VUIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuIHRoZSBpbXBsaWVkIHdhcnJhbnR5IG9mCiAqIE1FUkNIQU5UQUJJTElUWSBvciBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRS4gIAogKiBTZWUgdGhlIEdOVSBMZXNzZXIgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSBmb3IgbW9yZSBkZXRhaWxzLgogKgogKiBUaGUgR05VIExlc3NlciBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIGNhbiBiZSB2aWV3ZWQgYXQgaHR0cDovL3d3dy5vcGVuc291cmNlLm9yZy9saWNlbnNlcy9sZ3BsLWxpY2Vuc2UucGhwCiAqIElmIHlvdSB1bmZhbWlsaWFyIHdpdGggdGhpcyBsaWNlbnNlIG9yIGhhdmUgcXVlc3Rpb25zIGFib3V0IGl0LCBoZXJlIGlzIGFuIGh0dHA6Ly93d3cuZ251Lm9yZy9saWNlbnNlcy9ncGwtZmFxLmh0bWwKICoKICogQWxsIGNvZGUgYW5kIGV4ZWN1dGFibGVzIGFyZSBwcm92aWRlZCAiYXMgaXMiIHdpdGggbm8gd2FycmFudHkgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4gCiAqIFRoZSBhdXRob3IgYWNjZXB0cyBubyBsaWFiaWxpdHkgZm9yIGFueSBkYW1hZ2Ugb3IgbG9zcyBvZiBidXNpbmVzcyB0aGF0IHRoaXMgcHJvZHVjdCBtYXkgY2F1c2UuCiAqCiAqIENvZGUgY2hhbmdlIG5vdGVzOgogKiAKICogQXV0aG9yCQkJCQkJCUNoYW5nZQkJCQkJCURhdGUKICogKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIEphbiBL5GxsbWFuCQkgICAgSW5pdGlhbCBSZWxlYXNlCQkgICAgICAgIDIwMTEtMTEtMDIKICogSmFuIEvkbGxtYW4gICAgICAgICAgVG90YWwgcmV3cml0ZSAgICAgICAgICAgICAgIDIwMTAtMDMtMDEKICogSmFuIEvkbGxtYW4JCSAgICBMaWNlbnNlIGNoYW5nZWQgR1BMLS0+TEdQTCAgMjAxMS0xMi0yNwogKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8KdXNpbmcgU3lzdGVtOwp1c2luZyBTeXN0ZW0uWG1sOwp1c2luZyBTeXN0ZW0uQ29sbGVjdGlvbnMuR2VuZXJpYzsKdXNpbmcgU3lzdGVtLklPOwp1c2luZyBTeXN0ZW0uQ29uZmlndXJhdGlvbjsKdXNpbmcgT2ZmaWNlT3BlblhtbC5EcmF3aW5nOwp1c2luZyBTeXN0ZW0uRGlhZ25vc3RpY3M7CnVzaW5nIE9mZmljZU9wZW5YbWwuRm9ybXVsYVBhcnNpbmcuRXhjZWwuRnVuY3Rpb25zLkxvZ2ljYWw7CnVzaW5nIE9mZmljZU9wZW5YbWwuU3R5bGU7CnVzaW5nIFN5c3RlbS5HbG9iYWxpemF0aW9uOwp1c2luZyBTeXN0ZW0uVGV4dDsKdXNpbmcgU3lzdGVtLlNlY3VyaXR5Owp1c2luZyBPZmZpY2VPcGVuWG1sLkRyYXdpbmcuQ2hhcnQ7CnVzaW5nIE9mZmljZU9wZW5YbWwuU3R5bGUuWG1sQWNjZXNzOwp1c2luZyBTeXN0ZW0uVGV4dC5SZWd1bGFyRXhwcmVzc2lvbnM7CnVzaW5nIE9mZmljZU9wZW5YbWwuRHJhd2luZy5WbWw7CnVzaW5nIE9mZmljZU9wZW5YbWwuVGFibGU7CnVzaW5nIE9mZmljZU9wZW5YbWwuRGF0YVZhbGlkYXRpb247CnVzaW5nIE9mZmljZU9wZW5YbWwuVGFibGUuUGl2b3RUYWJsZTsKdXNpbmcgU3lzdGVtLkNvbXBvbmVudE1vZGVsOwp1c2luZyBTeXN0ZW0uRHJhd2luZzsKdXNpbmcgT2ZmaWNlT3BlblhtbC5Db25kaXRpb25hbEZvcm1hdHRpbmc7CnVzaW5nIE9mZmljZU9wZW5YbWwuVXRpbHM7CnVzaW5nIElvbmljLlppcDsKdXNpbmcgT2ZmaWNlT3BlblhtbC5Gb3JtdWxhUGFyc2luZy5MZXhpY2FsQW5hbHlzaXM7CnVzaW5nIE9mZmljZU9wZW5YbWwuRm9ybXVsYVBhcnNpbmc7CnVzaW5nIE9mZmljZU9wZW5YbWwuUGFja2FnaW5nLklvbmljLlppcDsKbmFtZXNwYWNlIE9mZmljZU9wZW5YbWwKewogICAgLy8vIDxzdW1tYXJ5PgogICAgLy8vIFdvcmtzaGVldCBoaWRkZW4gZW51bWVyYXRpb24KICAgIC8vLyA8L3N1bW1hcnk+CiAgICBwdWJsaWMgZW51bSBlV29ya1NoZWV0SGlkZGVuCiAgICB7CiAgICAgICAgLy8vIDxzdW1tYXJ5PgogICAgICAgIC8vLyBUaGUgd29ya3NoZWV0IGlzIHZpc2libGUKICAgICAgICAvLy8gPC9zdW1tYXJ5PgogICAgICAgIFZpc2libGUsCiAgICAgICAgLy8vIDxzdW1tYXJ5PgogICAgICAgIC8vLyBUaGUgd29ya3NoZWV0IGlzIGhpZGRlbiBidXQgY2FuIGJlIHNob3duIGJ5IHRoZSB1c2VyIHZpYSB0aGUgdXNlciBpbnRlcmZhY2UKICAgICAgICAvLy8gPC9zdW1tYXJ5PgogICAgICAgIEhpZGRlbiwKICAgICAgICAvLy8gPHN1bW1hcnk+CiAgICAgICAgLy8vIFRoZSB3b3Jrc2hlZXQgaXMgaGlkZGVuIGFuZCBjYW5ub3QgYmUgc2hvd24gYnkgdGhlIHVzZXIgdmlhIHRoZSB1c2VyIGludGVyZmFjZQogICAgICAgIC8vLyA8L3N1bW1hcnk+CiAgICAgICAgVmVyeUhpZGRlbgogICAgfQogICAgW0ZsYWdzXQogICAgaW50ZXJuYWwgZW51bSBDZWxsRmxhZ3MKICAgIHsKICAgICAgICAvL01lcmdlZCA9IDB4MSwKICAgICAgICBSaWNoVGV4dCA9IDB4MiwKICAgICAgICBTaGFyZWRGb3JtdWxhID0gMHg0LAogICAgICAgIEFycmF5Rm9ybXVsYSA9IDB4OAogICAgfQogICAgLy8vIDxzdW1tYXJ5PgogICAgLy8vIFJlcHJlc2VudHMgYW4gRXhjZWwgQ2hhcnRzaGVldCBhbmQgcHJvdmlkZXMgYWNjZXNzIHRvIGl0cyBwcm9wZXJ0aWVzIGFuZCBtZXRob2RzCiAgICAvLy8gPC9zdW1tYXJ5PgogICAgcHVibGljIGNsYXNzIEV4Y2VsQ2hhcnRzaGVldCA6IEV4Y2VsV29ya3NoZWV0CiAgICB7CiAgICAgICAgLy9FeGNlbERyYXdpbmdzIGRyYXdzOwogICAgICAgIHB1YmxpYyBFeGNlbENoYXJ0c2hlZXQoWG1sTmFtZXNwYWNlTWFuYWdlciBucywgRXhjZWxQYWNrYWdlIHBjaywgc3RyaW5nIHJlbElELCBVcmkgdXJpV29ya3NoZWV0LCBzdHJpbmcgc2hlZXROYW1lLCBpbnQgc2hlZXRJRCwgaW50IHBvc2l0aW9uSUQsIGVXb3JrU2hlZXRIaWRkZW4gaGlkZGVuLCBlQ2hhcnRUeXBlIGNoYXJ0VHlwZSkgOgogICAgICAgICAgICBiYXNlKG5zLCBwY2ssIHJlbElELCB1cmlXb3Jrc2hlZXQsIHNoZWV0TmFtZSwgc2hlZXRJRCwgcG9zaXRpb25JRCwgaGlkZGVuKQogICAgICAgIHsKICAgICAgICAgICAgdGhpcy5EcmF3aW5ncy5BZGRDaGFydCgiQ2hhcnQgMSIsIGNoYXJ0VHlwZSk7CiAgICAgICAgfQogICAgICAgIHB1YmxpYyBFeGNlbENoYXJ0c2hlZXQoWG1sTmFtZXNwYWNlTWFuYWdlciBucywgRXhjZWxQYWNrYWdlIHBjaywgc3RyaW5nIHJlbElELCBVcmkgdXJpV29ya3NoZWV0LCBzdHJpbmcgc2hlZXROYW1lLCBpbnQgc2hlZXRJRCwgaW50IHBvc2l0aW9uSUQsIGVXb3JrU2hlZXRIaWRkZW4gaGlkZGVuKSA6CiAgICAgICAgICAgIGJhc2UobnMsIHBjaywgcmVsSUQsIHVyaVdvcmtzaGVldCwgc2hlZXROYW1lLCBzaGVldElELCBwb3NpdGlvbklELCBoaWRkZW4pCiAgICAgICAgewogICAgICAgIH0KICAgICAgICBwdWJsaWMgRXhjZWxDaGFydCBDaGFydCAKICAgICAgICB7CiAgICAgICAgICAgIGdldAogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICByZXR1cm4gKEV4Y2VsQ2hhcnQpRHJhd2luZ3NbMF07CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICB9CiAgICAvLy8gPHN1bW1hcnk+CgkvLy8gUmVwcmVzZW50cyBhbiBFeGNlbCB3b3Jrc2hlZXQgYW5kIHByb3ZpZGVzIGFjY2VzcyB0byBpdHMgcHJvcGVydGllcyBhbmQgbWV0aG9kcwoJLy8vIDwvc3VtbWFyeT4KICAgIHB1YmxpYyBjbGFzcyBFeGNlbFdvcmtzaGVldCA6IFhtbEhlbHBlciwgSUVxdWFsaXR5Q29tcGFyZXI8RXhjZWxXb3Jrc2hlZXQ+LCBJRGlzcG9zYWJsZQoJewogICAgICAgIGludGVybmFsIGNsYXNzIEZvcm11bGFzCiAgICAgICAgewogICAgICAgICAgICBwdWJsaWMgRm9ybXVsYXMoSVNvdXJjZUNvZGVUb2tlbml6ZXIgdG9rZW5pemVyKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBfdG9rZW5pemVyID0gdG9rZW5pemVyOwogICAgICAgICAgICB9CgogICAgICAgICAgICBwdWJsaWMgc3RhdGljIHN0cmluZyBSZW1vdmVEdW1teUZ1bmN0aW9uKHN0cmluZyBmb3JtdWxhKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBjb25zdCBzdHJpbmcgRHVtbXlGdW5jdGlvblByZWZpeCA9ICJJRkVSUk9SKF9feGx1ZGYuRFVNTVlGVU5DVElPTihcIiI7CiAgICAgICAgICAgICAgICBjb25zdCBzdHJpbmcgRHVtbXlGdW5jdGlvblN1ZmZpeCA9ICJcIiksXCIiOwoKICAgICAgICAgICAgICAgIGlmIChzdHJpbmcuSXNOdWxsT3JFbXB0eShmb3JtdWxhKSkKICAgICAgICAgICAgICAgICAgICByZXR1cm4gZm9ybXVsYTsKCiAgICAgICAgICAgICAgICAvLyBMb29rIGZvciBQcmVmaXgKICAgICAgICAgICAgICAgIGlmICghZm9ybXVsYS5TdGFydHNXaXRoKER1bW15RnVuY3Rpb25QcmVmaXgpKQogICAgICAgICAgICAgICAgICAgIHJldHVybiBmb3JtdWxhOwoKICAgICAgICAgICAgICAgIC8vIExvb2sgZm9yIFN1ZmZpeAogICAgICAgICAgICAgICAgaW50IGluZGV4ID0gZm9ybXVsYS5MYXN0SW5kZXhPZihEdW1teUZ1bmN0aW9uU3VmZml4KTsKICAgICAgICAgICAgICAgIGlmIChpbmRleCA8IDApCiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGZvcm11bGE7CgogICAgICAgICAgICAgICAgLy8gVHJpbSBTdWZmaXgKICAgICAgICAgICAgICAgIGZvcm11bGEgPSBmb3JtdWxhLlN1YnN0cmluZygwLCBpbmRleCk7CgogICAgICAgICAgICAgICAgLy8gVHJpbSBQcmVmaXgKICAgICAgICAgICAgICAgIGZvcm11bGEgPSBmb3JtdWxhLlJlcGxhY2UoRHVtbXlGdW5jdGlvblByZWZpeCwgIiIpOwoKICAgICAgICAgICAgICAgIC8vIFJlcGxhY2UgZG91YmxlZCBxdW90ZXMgd2l0aCBzaW5nbGUgcXVvdGUKICAgICAgICAgICAgICAgIGZvcm11bGEgPSBmb3JtdWxhLlJlcGxhY2UoIlwiXCIiLCAiXCIiKTsKCiAgICAgICAgICAgICAgICAvLyBSZXR1cm4gZm9ybXVsYQogICAgICAgICAgICAgICAgcmV0dXJuIGZvcm11bGE7CiAgICAgICAgICAgIH0KCQkJCiAgICAgICAgICAgcHJpdmF0ZSBJU291cmNlQ29kZVRva2VuaXplciBfdG9rZW5pemVyOwogICAgICAgICAgICBpbnRlcm5hbCBpbnQgSW5kZXggeyBnZXQ7IHNldDsgfQogICAgICAgICAgICBpbnRlcm5hbCBzdHJpbmcgQWRkcmVzcyB7IGdldDsgc2V0OyB9CiAgICAgICAgICAgIGludGVybmFsIGJvb2wgSXNBcnJheSB7IGdldDsgc2V0OyB9CiAgICAgICAgICAgIHB1YmxpYyBzdHJpbmcgRm9ybXVsYSB7IGdldDsgc2V0OyB9CiAgICAgICAgICAgIHB1YmxpYyBpbnQgU3RhcnRSb3cgeyBnZXQ7IHNldDsgfQogICAgICAgICAgICBwdWJsaWMgaW50IFN0YXJ0Q29sIHsgZ2V0OyBzZXQ7IH0KCiAgICAgICAgICAgIHByaXZhdGUgSUVudW1lcmFibGU8VG9rZW4+IFRva2VucyB7Z2V0OyBzZXQ7fQogICAgICAgICAgIAoKICAgICAgICAgICAgaW50ZXJuYWwgc3RyaW5nIEdldEZvcm11bGEoaW50IHJvdywgaW50IGNvbHVtbiwgc3RyaW5nIHdvcmtzaGVldCkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgaWYgKChTdGFydFJvdyA9PSByb3cgJiYgU3RhcnRDb2wgPT0gY29sdW1uKSB8fCBJc0FycmF5KQogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIHJldHVybiBSZW1vdmVEdW1teUZ1bmN0aW9uKEZvcm11bGEpOwogICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgIGlmIChUb2tlbnMgPT0gbnVsbCkKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICBUb2tlbnMgPSBfdG9rZW5pemVyLlRva2VuaXplKFJlbW92ZUR1bW15RnVuY3Rpb24oRm9ybXVsYSksIHdvcmtzaGVldCk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgIHN0cmluZyBmID0gIiI7CiAgICAgICAgICAgICAgICBmb3JlYWNoICh2YXIgdG9rZW4gaW4gVG9rZW5zKQogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIGlmICh0b2tlbi5Ub2tlblR5cGUgPT0gVG9rZW5UeXBlLkV4Y2VsQWRkcmVzcykKICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgIHZhciBhID0gbmV3IEV4Y2VsRm9ybXVsYUFkZHJlc3ModG9rZW4uVmFsdWUpOwogICAgICAgICAgICAgICAgICAgICAgICBmICs9IGEuR2V0T2Zmc2V0KHJvdyAtIFN0YXJ0Um93LCBjb2x1bW4gLSBTdGFydENvbCk7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIGVsc2UKICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgIGYgKz0gdG9rZW4uVmFsdWU7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgcmV0dXJuIGY7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgLy8vIDxzdW1tYXJ5PgogICAgICAgIC8vLyBDb2xsZWN0aW9uIGNvbnRhaW5pbmcgbWVyZ2VkIGNlbGwgYWRkcmVzc2VzCiAgICAgICAgLy8vIDwvc3VtbWFyeT4KICAgICAgICBwdWJsaWMgY2xhc3MgTWVyZ2VDZWxsc0NvbGxlY3Rpb24gOiBJRW51bWVyYWJsZTxzdHJpbmc+CiAgICAgICAgewogICAgICAgICAgICBpbnRlcm5hbCBNZXJnZUNlbGxzQ29sbGVjdGlvbigpCiAgICAgICAgICAgIHsKCiAgICAgICAgICAgIH0KICAgICAgICAgICAgaW50ZXJuYWwgQ2VsbFN0b3JlPGludD4gX2NlbGxzID0gbmV3IENlbGxTdG9yZTxpbnQ+KCk7CiAgICAgICAgICAgIExpc3Q8c3RyaW5nPiBfbGlzdCA9IG5ldyBMaXN0PHN0cmluZz4oKTsKICAgICAgICAgICAgaW50ZXJuYWwgTGlzdDxzdHJpbmc+IExpc3QgeyBnZXQge3JldHVybiBfbGlzdDt9IH0KICAgICAgICAgICAgcHVibGljIHN0cmluZyB0aGlzW2ludCByb3csIGludCBjb2x1bW5dCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIGdldAogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIGludCBpeD0tMTsKICAgICAgICAgICAgICAgICAgICBpZiAoX2NlbGxzLkV4aXN0cyhyb3csIGNvbHVtbiwgcmVmIGl4KSAmJiBpeCA+PSAwICYmIGl4IDwgTGlzdC5Db3VudCkgIC8vRml4ZXMgaXNzdWUgMTUwNzUKICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBMaXN0W2l4XTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgZWxzZQogICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIG51bGw7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgICAgIHB1YmxpYyBzdHJpbmcgdGhpc1tpbnQgaW5kZXhdCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIGdldAogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIHJldHVybiBfbGlzdFtpbmRleF07CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICAgICAgaW50ZXJuYWwgdm9pZCBBZGQoRXhjZWxBZGRyZXNzQmFzZSBhZGRyZXNzLCBib29sIGRvVmFsaWRhdGUpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIGludCBpeD0wOwoKICAgICAgICAgICAgICAgIC8vVmFsaWRhdGUKICAgICAgICAgICAgICAgIGlmIChkb1ZhbGlkYXRlICYmIFZhbGlkYXRlKGFkZHJlc3MpID09IGZhbHNlKQogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIHRocm93KG5ldyBBcmd1bWVudEV4Y2VwdGlvbigiQ2FuJ3QgbWVyZ2UgYW5kIGFscmVhZHkgbWVyZ2VkIHJhbmdlIikpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgbG9jayh0aGlzKQogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIGl4ID0gX2xpc3QuQ291bnQ7CiAgICAgICAgICAgICAgICAgICAgX2xpc3QuQWRkKGFkZHJlc3MuQWRkcmVzcyk7CiAgICAgICAgICAgICAgICAgICAgU2V0SW5kZXgoYWRkcmVzcywgaXgpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CgogICAgICAgICAgICBwcml2YXRlIGJvb2wgVmFsaWRhdGUoRXhjZWxBZGRyZXNzQmFzZSBhZGRyZXNzKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBpbnQgaXg9MDsKICAgICAgICAgICAgICAgIGlmKF9jZWxscy5FeGlzdHMoYWRkcmVzcy5fZnJvbVJvdywgYWRkcmVzcy5fZnJvbUNvbCwgcmVmIGl4KSkKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICBpZiAoaXg+PTAgJiYgaXggPCBfbGlzdC5Db3VudCAmJiBfbGlzdFtpeF0hPW51bGwgJiYgYWRkcmVzcy5BZGRyZXNzID09IF9saXN0W2l4XSkKICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiB0cnVlOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICBlbHNlCiAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICB2YXIgY3NlID0gbmV3IENlbGxzU3RvcmVFbnVtZXJhdG9yPGludD4oX2NlbGxzLCBhZGRyZXNzLl9mcm9tUm93LCBhZGRyZXNzLl9mcm9tQ29sLCBhZGRyZXNzLl90b1JvdywgYWRkcmVzcy5fdG9Db2wpOwogICAgICAgICAgICAgICAgLy9jZWxscwogICAgICAgICAgICAgICAgd2hpbGUoY3NlLk5leHQoKSkKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAvL0VudGlyZSBjb2x1bW4KICAgICAgICAgICAgICAgIGNzZSA9IG5ldyBDZWxsc1N0b3JlRW51bWVyYXRvcjxpbnQ+KF9jZWxscywgMCwgYWRkcmVzcy5fZnJvbUNvbCwgMCwgYWRkcmVzcy5fdG9Db2wpOwogICAgICAgICAgICAgICAgd2hpbGUgKGNzZS5OZXh0KCkpCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgLy9FbnRpcmUgcm93CiAgICAgICAgICAgICAgICBjc2UgPSBuZXcgQ2VsbHNTdG9yZUVudW1lcmF0b3I8aW50PihfY2VsbHMsIGFkZHJlc3MuX2Zyb21Sb3csIDAsIGFkZHJlc3MuX3RvUm93LCAwKTsKICAgICAgICAgICAgICAgIHdoaWxlIChjc2UuTmV4dCgpKQogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIHJldHVybiB0cnVlOwogICAgICAgICAgICB9CgogICAgICAgICAgICBpbnRlcm5hbCB2b2lkIFNldEluZGV4KEV4Y2VsQWRkcmVzc0Jhc2UgYWRkcmVzcywgaW50IGl4KQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBpZiAoYWRkcmVzcy5fZnJvbVJvdyA9PSAxICYmIGFkZHJlc3MuX3RvUm93ID09IEV4Y2VsUGFja2FnZS5NYXhSb3dzKSAvL0VudGlyZSByb3cKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICBmb3IgKGludCBjb2wgPSBhZGRyZXNzLl9mcm9tQ29sOyBjb2wgPD0gYWRkcmVzcy5fdG9Db2w7IGNvbCsrKQogICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgX2NlbGxzLlNldFZhbHVlKDAsIGNvbCwgaXgpOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGVsc2UgaWYgKGFkZHJlc3MuX2Zyb21Db2wgPT0gMSAmJiBhZGRyZXNzLl90b0NvbCA9PSBFeGNlbFBhY2thZ2UuTWF4Q29sdW1ucykgLy9FbnRpcmUgcm93CiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgZm9yIChpbnQgcm93ID0gYWRkcmVzcy5fZnJvbVJvdzsgcm93IDw9IGFkZHJlc3MuX3RvUm93OyByb3crKykKICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgIF9jZWxscy5TZXRWYWx1ZShyb3csIDAsIGl4KTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBlbHNlCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgZm9yIChpbnQgY29sID0gYWRkcmVzcy5fZnJvbUNvbDsgY29sIDw9IGFkZHJlc3MuX3RvQ29sOyBjb2wrKykKICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgIGZvciAoaW50IHJvdyA9IGFkZHJlc3MuX2Zyb21Sb3c7IHJvdyA8PSBhZGRyZXNzLl90b1Jvdzsgcm93KyspCiAgICAgICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIF9jZWxscy5TZXRWYWx1ZShyb3csIGNvbCwgaXgpOwogICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgICAgIHB1YmxpYyBpbnQgQ291bnQKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgZ2V0CiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIF9saXN0LkNvdW50OwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgICAgIGludGVybmFsIHZvaWQgUmVtb3ZlKHN0cmluZyBJdGVtKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBfbGlzdC5SZW1vdmUoSXRlbSk7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgI3JlZ2lvbiBJRW51bWVyYWJsZTxzdHJpbmc+IE1lbWJlcnMKCiAgICAgICAgICAgIHB1YmxpYyBJRW51bWVyYXRvcjxzdHJpbmc+IEdldEVudW1lcmF0b3IoKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICByZXR1cm4gX2xpc3QuR2V0RW51bWVyYXRvcigpOwogICAgICAgICAgICB9CgogICAgICAgICAgICAjZW5kcmVnaW9uCgogICAgICAgICAgICAjcmVnaW9uIElFbnVtZXJhYmxlIE1lbWJlcnMKCiAgICAgICAgICAgIFN5c3RlbS5Db2xsZWN0aW9ucy5JRW51bWVyYXRvciBTeXN0ZW0uQ29sbGVjdGlvbnMuSUVudW1lcmFibGUuR2V0RW51bWVyYXRvcigpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIHJldHVybiBfbGlzdC5HZXRFbnVtZXJhdG9yKCk7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgCiAgICAgICAgICAgICNlbmRyZWdpb24KICAgICAgICAgICAgaW50ZXJuYWwgdm9pZCBDbGVhcihFeGNlbEFkZHJlc3NCYXNlIERlc3RpbmF0aW9uKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICB2YXIgY3NlID0gbmV3IENlbGxzU3RvcmVFbnVtZXJhdG9yPGludD4oX2NlbGxzLCBEZXN0aW5hdGlvbi5fZnJvbVJvdywgRGVzdGluYXRpb24uX2Zyb21Db2wsIERlc3RpbmF0aW9uLl90b1JvdywgRGVzdGluYXRpb24uX3RvQ29sKTsKICAgICAgICAgICAgICAgIHZhciB1c2VkPW5ldyBIYXNoU2V0PGludD4oKTsKICAgICAgICAgICAgICAgIHdoaWxlKGNzZS5OZXh0KCkpCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgdmFyIHY9Y3NlLlZhbHVlOwogICAgICAgICAgICAgICAgICAgIGlmICghdXNlZC5Db250YWlucyh2KSAmJiBfbGlzdFt2XSE9bnVsbCkKICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgIHZhciBhZHI9bmV3IEV4Y2VsQWRkcmVzc0Jhc2UoX2xpc3Rbdl0pOwogICAgICAgICAgICAgICAgICAgICAgICBpZiAoIShEZXN0aW5hdGlvbi5Db2xsaWRlKGFkcikgPT0gRXhjZWxBZGRyZXNzQmFzZS5lQWRkcmVzc0NvbGxpdGlvbi5JbnNpZGUgfHwgRGVzdGluYXRpb24uQ29sbGlkZShhZHIpPT1FeGNlbEFkZHJlc3NCYXNlLmVBZGRyZXNzQ29sbGl0aW9uLkVxdWFsKSkKICAgICAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhyb3cobmV3IEludmFsaWRPcGVyYXRpb25FeGNlcHRpb24oc3RyaW5nLkZvcm1hdCgiQ2FuJ3QgZGVsZXRlIG1lcmdlZCBjZWxscy4gQSByYW5nZSBpcyBwYXJ0bHkgbWVyZ2VkIHdpdGggdGhlIGRlbGV0ZWQgcmFuZ2UuIHswfSIsIGFkci5fYWRkcmVzcykpKTsKICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICAgICB1c2VkLkFkZCh2KTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgX2NlbGxzLkNsZWFyKERlc3RpbmF0aW9uLl9mcm9tUm93LCBEZXN0aW5hdGlvbi5fZnJvbUNvbCwgRGVzdGluYXRpb24uX3RvUm93IC0gRGVzdGluYXRpb24uX2Zyb21Sb3cgKyAxLCBEZXN0aW5hdGlvbi5fdG9Db2wgLSBEZXN0aW5hdGlvbi5fZnJvbUNvbCArIDEpOwogICAgICAgICAgICAgICAgZm9yZWFjaCh2YXIgaSBpbiB1c2VkKQogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIF9saXN0W2ldID0gbnVsbDsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgIH0KICAgICAgICBpbnRlcm5hbCBDZWxsU3RvcmU8b2JqZWN0PiBfdmFsdWVzOwogICAgICAgIGludGVybmFsIENlbGxTdG9yZTxzdHJpbmc+IF90eXBlczsKICAgICAgICBpbnRlcm5hbCBDZWxsU3RvcmU8aW50PiBfc3R5bGVzOwogICAgICAgIGludGVybmFsIENlbGxTdG9yZTxvYmplY3Q+IF9mb3JtdWxhczsKICAgICAgICBpbnRlcm5hbCBGbGFnQ2VsbFN0b3JlIF9mbGFnczsKICAgICAgICBpbnRlcm5hbCBDZWxsU3RvcmU8TGlzdDxUb2tlbj4+IF9mb3JtdWxhVG9rZW5zOwoKICAgICAgICBpbnRlcm5hbCBDZWxsU3RvcmU8VXJpPiBfaHlwZXJMaW5rczsKICAgICAgICBpbnRlcm5hbCBDZWxsU3RvcmU8RXhjZWxDb21tZW50PiBfY29tbWVudHNTdG9yZTsKCiAgICAgICAgaW50ZXJuYWwgRGljdGlvbmFyeTxpbnQsIEZvcm11bGFzPiBfc2hhcmVkRm9ybXVsYXMgPSBuZXcgRGljdGlvbmFyeTxpbnQsIEZvcm11bGFzPigpOwogICAgICAgIGludGVybmFsIGludCBfbWluQ29sID0gRXhjZWxQYWNrYWdlLk1heENvbHVtbnM7CiAgICAgICAgaW50ZXJuYWwgaW50IF9tYXhDb2wgPSAwOwogICAgICAgICNyZWdpb24gV29ya3NoZWV0IFByaXZhdGUgUHJvcGVydGllcwogICAgICAgIGludGVybmFsIEV4Y2VsUGFja2FnZSBfcGFja2FnZTsKCQlwcml2YXRlIFVyaSBfd29ya3NoZWV0VXJpOwoJCXByaXZhdGUgc3RyaW5nIF9uYW1lOwoJCXByaXZhdGUgaW50IF9zaGVldElEOwogICAgICAgIHByaXZhdGUgaW50IF9wb3NpdGlvbklEOwoJCXByaXZhdGUgc3RyaW5nIF9yZWxhdGlvbnNoaXBJRDsKCQlwcml2YXRlIFhtbERvY3VtZW50IF93b3Jrc2hlZXRYbWw7CiAgICAgICAgaW50ZXJuYWwgRXhjZWxXb3Jrc2hlZXRWaWV3IF9zaGVldFZpZXc7CgkJaW50ZXJuYWwgRXhjZWxIZWFkZXJGb290ZXIgX2hlYWRlckZvb3RlcjsKICAgICAgICAjZW5kcmVnaW9uCiAgICAgICAgI3JlZ2lvbiBFeGNlbFdvcmtzaGVldCBDb25zdHJ1Y3RvcgogICAgICAgIC8vLyA8c3VtbWFyeT4KICAgICAgICAvLy8gQSB3b3Jrc2hlZXQKICAgICAgICAvLy8gPC9zdW1tYXJ5PgogICAgICAgIC8vLyA8cGFyYW0gbmFtZT0ibnMiPk5hbWVzcGFjZW1hbmFnZXI8L3BhcmFtPgogICAgICAgIC8vLyA8cGFyYW0gbmFtZT0iZXhjZWxQYWNrYWdlIj5QYWNrYWdlPC9wYXJhbT4KICAgICAgICAvLy8gPHBhcmFtIG5hbWU9InJlbElEIj5SZWxhdGlvbnNoaXAgSUQ8L3BhcmFtPgogICAgICAgIC8vLyA8cGFyYW0gbmFtZT0idXJpV29ya3NoZWV0Ij5VUkk8L3BhcmFtPgogICAgICAgIC8vLyA8cGFyYW0gbmFtZT0ic2hlZXROYW1lIj5OYW1lIG9mIHRoZSBzaGVldDwvcGFyYW0+CiAgICAgICAgLy8vIDxwYXJhbSBuYW1lPSJzaGVldElEIj5TaGVldCBpZDwvcGFyYW0+CiAgICAgICAgLy8vIDxwYXJhbSBuYW1lPSJwb3NpdGlvbklEIj5Qb3NpdGlvbjwvcGFyYW0+CiAgICAgICAgLy8vIDxwYXJhbSBuYW1lPSJoaWRlIj5oaWRlPC9wYXJhbT4KICAgICAgICBwdWJsaWMgRXhjZWxXb3Jrc2hlZXQoWG1sTmFtZXNwYWNlTWFuYWdlciBucywgRXhjZWxQYWNrYWdlIGV4Y2VsUGFja2FnZSwgc3RyaW5nIHJlbElELCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgVXJpIHVyaVdvcmtzaGVldCwgc3RyaW5nIHNoZWV0TmFtZSwgaW50IHNoZWV0SUQsIGludCBwb3NpdGlvbklELAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlV29ya1NoZWV0SGlkZGVuIGhpZGUpIDoKICAgICAgICAgICAgYmFzZShucywgbnVsbCkKICAgICAgICB7CiAgICAgICAgICAgIFNjaGVtYU5vZGVPcmRlciA9IG5ldyBzdHJpbmdbXSB7ICJzaGVldFByIiwgInRhYkNvbG9yIiwgIm91dGxpbmVQciIsICJwYWdlU2V0VXBQciIsICJkaW1lbnNpb24iLCAic2hlZXRWaWV3cyIsICJzaGVldEZvcm1hdFByIiwgImNvbHMiLCAic2hlZXREYXRhIiwgInNoZWV0UHJvdGVjdGlvbiIsICJwcm90ZWN0ZWRSYW5nZXMiLCJzY2VuYXJpb3MiLCAiYXV0b0ZpbHRlciIsICJzb3J0U3RhdGUiLCAiZGF0YUNvbnNvbGlkYXRlIiwgImN1c3RvbVNoZWV0Vmlld3MiLCAiY3VzdG9tU2hlZXRWaWV3cyIsICJtZXJnZUNlbGxzIiwgInBob25ldGljUHIiLCAiY29uZGl0aW9uYWxGb3JtYXR0aW5nIiwgImRhdGFWYWxpZGF0aW9ucyIsICJoeXBlcmxpbmtzIiwgInByaW50T3B0aW9ucyIsICJwYWdlTWFyZ2lucyIsICJwYWdlU2V0dXAiLCAiaGVhZGVyRm9vdGVyIiwgImxpbmVQcmludCIsICJyb3dCcmVha3MiLCAiY29sQnJlYWtzIiwgImN1c3RvbVByb3BlcnRpZXMiLCAiY2VsbFdhdGNoZXMiLCAiaWdub3JlZEVycm9ycyIsICJzbWFydFRhZ3MiLCAiZHJhd2luZyIsICJsZWdhY3lEcmF3aW5nIiwgImxlZ2FjeURyYXdpbmdIRiIsICJwaWN0dXJlIiwgIm9sZU9iamVjdHMiLCAiYWN0aXZlWENvbnRyb2xzIiwgIndlYlB1Ymxpc2hJdGVtcyIsICJ0YWJsZVBhcnRzIiAsICJleHRMc3QiIH07CiAgICAgICAgICAgIF9wYWNrYWdlID0gZXhjZWxQYWNrYWdlOyAgIAogICAgICAgICAgICBfcmVsYXRpb25zaGlwSUQgPSByZWxJRDsKICAgICAgICAgICAgX3dvcmtzaGVldFVyaSA9IHVyaVdvcmtzaGVldDsKICAgICAgICAgICAgX25hbWUgPSBzaGVldE5hbWU7CiAgICAgICAgICAgIF9zaGVldElEID0gc2hlZXRJRDsKICAgICAgICAgICAgX3Bvc2l0aW9uSUQgPSBwb3NpdGlvbklEOwogICAgICAgICAgICBIaWRkZW4gPSBoaWRlOwogICAgICAgICAgIAogICAgICAgICAgICAvKioqKiBDZWxsc3RvcmUgKioqKi8KICAgICAgICAgICAgX3ZhbHVlcz1uZXcgQ2VsbFN0b3JlPG9iamVjdD4oKTsKICAgICAgICAgICAgX3R5cGVzID0gbmV3IENlbGxTdG9yZTxzdHJpbmc+KCk7CiAgICAgICAgICAgIF9zdHlsZXMgPSBuZXcgQ2VsbFN0b3JlPGludD4oKTsKICAgICAgICAgICAgX2Zvcm11bGFzID0gbmV3IENlbGxTdG9yZTxvYmplY3Q+KCk7CiAgICAgICAgICAgIF9mbGFncyA9IG5ldyBGbGFnQ2VsbFN0b3JlKCk7CiAgICAgICAgICAgIF9jb21tZW50c1N0b3JlID0gbmV3IENlbGxTdG9yZTxFeGNlbENvbW1lbnQ+KCk7CiAgICAgICAgICAgIF9oeXBlckxpbmtzID0gbmV3IENlbGxTdG9yZTxVcmk+KCk7CiAgICAgICAgICAgIAogICAgICAgICAgICBfbmFtZXMgPSBuZXcgRXhjZWxOYW1lZFJhbmdlQ29sbGVjdGlvbihXb3JrYm9vayx0aGlzKTsKCiAgICAgICAgICAgIENyZWF0ZVhtbCgpOwogICAgICAgICAgICBUb3BOb2RlID0gX3dvcmtzaGVldFhtbC5Eb2N1bWVudEVsZW1lbnQ7CiAgICAgICAgfQoKICAgICAgICAjZW5kcmVnaW9uCiAgICAgICAgLy8vIDxzdW1tYXJ5PgogICAgICAgIC8vLyBUaGUgVXJpIHRvIHRoZSB3b3Jrc2hlZXQgd2l0aGluIHRoZSBwYWNrYWdlCiAgICAgICAgLy8vIDwvc3VtbWFyeT4KICAgICAgICBpbnRlcm5hbCBVcmkgV29ya3NoZWV0VXJpIHsgZ2V0IHsgcmV0dXJuIChfd29ya3NoZWV0VXJpKTsgfSB9CiAgICAgICAgLy8vIDxzdW1tYXJ5PgogICAgICAgIC8vLyBUaGUgWmlwLlppcFBhY2thZ2VQYXJ0IGZvciB0aGUgd29ya3NoZWV0IHdpdGhpbiB0aGUgcGFja2FnZQogICAgICAgIC8vLyA8L3N1bW1hcnk+CiAgICAgICAgaW50ZXJuYWwgUGFja2FnaW5nLlppcFBhY2thZ2VQYXJ0IFBhcnQgeyBnZXQgeyByZXR1cm4gKF9wYWNrYWdlLlBhY2thZ2UuR2V0UGFydChXb3Jrc2hlZXRVcmkpKTsgfSB9CiAgICAgICAgLy8vIDxzdW1tYXJ5PgogICAgICAgIC8vLyBUaGUgSUQgZm9yIHRoZSB3b3Jrc2hlZXQncyByZWxhdGlvbnNoaXAgd2l0aCB0aGUgd29ya2Jvb2sgaW4gdGhlIHBhY2thZ2UKICAgICAgICAvLy8gPC9zdW1tYXJ5PgogICAgICAgIGludGVybmFsIHN0cmluZyBSZWxhdGlvbnNoaXBJRCB7IGdldCB7IHJldHVybiAoX3JlbGF0aW9uc2hpcElEKTsgfSB9CiAgICAgICAgLy8vIDxzdW1tYXJ5PgogICAgICAgIC8vLyBUaGUgdW5pcXVlIGlkZW50aWZpZXIgZm9yIHRoZSB3b3Jrc2hlZXQuCiAgICAgICAgLy8vIDwvc3VtbWFyeT4KICAgICAgICBpbnRlcm5hbCBpbnQgU2hlZXRJRCB7IGdldCB7IHJldHVybiAoX3NoZWV0SUQpOyB9IH0KICAgICAgICAvLy8gPHN1bW1hcnk+CiAgICAgICAgLy8vIFRoZSBwb3NpdGlvbiBvZiB0aGUgd29ya3NoZWV0LgogICAgICAgIC8vLyA8L3N1bW1hcnk+CiAgICAgICAgaW50ZXJuYWwgaW50IFBvc2l0aW9uSUQgeyBnZXQgeyByZXR1cm4gKF9wb3NpdGlvbklEKTsgfSBzZXQgeyBfcG9zaXRpb25JRCA9IHZhbHVlOyB9IH0KCQkjcmVnaW9uIFdvcmtzaGVldCBQdWJsaWMgUHJvcGVydGllcwogICAgCS8vLyA8c3VtbWFyeT4KICAgICAgICAvLy8gVGhlIGluZGV4IGluIHRoZSB3b3Jrc2hlZXRzIGNvbGxlY3Rpb24KICAgICAgICAvLy8gPC9zdW1tYXJ5PgogICAgICAgIHB1YmxpYyBpbnQgSW5kZXggeyBnZXQgeyByZXR1cm4gKF9wb3NpdGlvbklEKTsgfSB9CiAgICAgICAgLy8vIDxzdW1tYXJ5PgogICAgICAgIC8vLyBBZGRyZXNzIGZvciBhdXRvZmlsdGVyCiAgICAgICAgLy8vIDxzZWVhbHNvIGNyZWY9IkV4Y2VsUmFuZ2VCYXNlLkF1dG9GaWx0ZXIiIC8+ICAgICAgICAKICAgICAgICAvLy8gPC9zdW1tYXJ5PgogICAgICAgIHB1YmxpYyBFeGNlbEFkZHJlc3NCYXNlIEF1dG9GaWx0ZXJBZGRyZXNzCiAgICAgICAgewogICAgICAgICAgICBnZXQKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgQ2hlY2tTaGVldFR5cGUoKTsKICAgICAgICAgICAgICAgIHN0cmluZyBhZGRyZXNzID0gR2V0WG1sTm9kZVN0cmluZygiZDphdXRvRmlsdGVyL0ByZWYiKTsKICAgICAgICAgICAgICAgIGlmIChhZGRyZXNzID09ICIiKQogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIHJldHVybiBudWxsOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgZWxzZQogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIHJldHVybiBuZXcgRXhjZWxBZGRyZXNzQmFzZShhZGRyZXNzKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgICAgICBpbnRlcm5hbCBzZXQKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgQ2hlY2tTaGVldFR5cGUoKTsKICAgICAgICAgICAgICAgIFNldFhtbE5vZGVTdHJpbmcoImQ6YXV0b0ZpbHRlci9AcmVmIiwgdmFsdWUuQWRkcmVzcyk7CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIGludGVybmFsIHZvaWQgQ2hlY2tTaGVldFR5cGUoKQogICAgICAgIHsKICAgICAgICAgICAgaWYgKHRoaXMgaXMgRXhjZWxDaGFydHNoZWV0KQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICB0aHJvdyAobmV3IE5vdFN1cHBvcnRlZEV4Y2VwdGlvbigiVGhpcyBwcm9wZXJ0eSBvciBtZXRob2QgaXMgbm90IHN1cHBvcnRlZCBmb3IgYSBDaGFydHNoZWV0IikpOwogICAgICAgICAgICB9CiAgICAgICAgfQoKCQkvLy8gPHN1bW1hcnk+CgkJLy8vIFJldHVybnMgYSBFeGNlbFdvcmtzaGVldFZpZXcgb2JqZWN0IHRoYXQgYWxsb3dzIHlvdSB0byBzZXQgdGhlIHZpZXcgc3RhdGUgcHJvcGVydGllcyBvZiB0aGUgd29ya3NoZWV0CgkJLy8vIDwvc3VtbWFyeT4KCQlwdWJsaWMgRXhjZWxXb3Jrc2hlZXRWaWV3IFZpZXcKCQl7CgkJCWdldAoJCQl7CgkJCQlpZiAoX3NoZWV0VmlldyA9PSBudWxsKQoJCQkJewogICAgICAgICAgICAgICAgICAgIFhtbE5vZGUgbm9kZSA9IFRvcE5vZGUuU2VsZWN0U2luZ2xlTm9kZSgiZDpzaGVldFZpZXdzL2Q6c2hlZXRWaWV3IiwgTmFtZVNwYWNlTWFuYWdlcik7CiAgICAgICAgICAgICAgICAgICAgaWYgKG5vZGUgPT0gbnVsbCkKICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgIENyZWF0ZU5vZGUoImQ6c2hlZXRWaWV3cy9kOnNoZWV0VmlldyIpOyAvL3RoaXMgb25lIHNob3VscyBhbHdheXMgZXhpc3QuIGJ1dCBjaGVjayBhbnl3YXkKICAgICAgICAgICAgICAgICAgICAgICAgbm9kZSA9IFRvcE5vZGUuU2VsZWN0U2luZ2xlTm9kZSgiZDpzaGVldFZpZXdzL2Q6c2hlZXRWaWV3IiwgTmFtZVNwYWNlTWFuYWdlcik7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIF9zaGVldFZpZXcgPSBuZXcgRXhjZWxXb3Jrc2hlZXRWaWV3KE5hbWVTcGFjZU1hbmFnZXIsIG5vZGUsIHRoaXMpOwoJCQkJfQoJCQkJcmV0dXJuIChfc2hlZXRWaWV3KTsKCQkJfQoJCX0KCgkJLy8vIDxzdW1tYXJ5PgoJCS8vLyBUaGUgd29ya3NoZWV0J3MgZGlzcGxheSBuYW1lIGFzIGl0IGFwcGVhcnMgb24gdGhlIHRhYgoJCS8vLyA8L3N1bW1hcnk+CgkJcHVibGljIHN0cmluZyBOYW1lCgkJewoJCQlnZXQgeyByZXR1cm4gKF9uYW1lKTsgfQoJCQlzZXQKCQkJewogICAgICAgICAgICAgICAgaWYgKHZhbHVlID09IF9uYW1lKSByZXR1cm47CiAgICAgICAgICAgICAgICB2YWx1ZT1fcGFja2FnZS5Xb3JrYm9vay5Xb3Jrc2hlZXRzLlZhbGlkYXRlRml4U2hlZXROYW1lKHZhbHVlKTsKICAgICAgICAgICAgICAgIGZvcmVhY2godmFyIHdzIGluIFdvcmtib29rLldvcmtzaGVldHMpCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgaWYod3MuUG9zaXRpb25JRCE9UG9zaXRpb25JRCAmJiB3cy5OYW1lLkVxdWFscyh2YWx1ZSxTdHJpbmdDb21wYXJpc29uLkludmFyaWFudEN1bHR1cmVJZ25vcmVDYXNlKSkKICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgIHRocm93IChuZXcgQXJndW1lbnRFeGNlcHRpb24oIldvcmtzaGVldCBuYW1lIG11c3QgYmUgdW5pcXVlIikpOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIF9wYWNrYWdlLldvcmtib29rLlNldFhtbE5vZGVTdHJpbmcoc3RyaW5nLkZvcm1hdCgiZDpzaGVldHMvZDpzaGVldFtAc2hlZXRJZD17MH1dL0BuYW1lIiwgX3NoZWV0SUQpLCB2YWx1ZSk7CiAgICAgICAgICAgICAgICBDaGFuZ2VOYW1lcyh2YWx1ZSk7CgogICAgICAgICAgICAgICAgX25hbWUgPSB2YWx1ZTsKICAgICAgICAgICAgfQoJCX0KCiAgICAgICAgcHJpdmF0ZSB2b2lkIENoYW5nZU5hbWVzKHN0cmluZyB2YWx1ZSkKICAgICAgICB7CiAgICAgICAgICAgIC8vUmVuYW1lcyBuYW1lIGluIHRoaXMgV29ya3NoZWV0OwogICAgICAgICAgICBmb3JlYWNoICh2YXIgbiBpbiBXb3JrYm9vay5OYW1lcykKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgaWYgKHN0cmluZy5Jc051bGxPckVtcHR5KG4uTmFtZUZvcm11bGEpICYmIG4uTmFtZVZhbHVlPT1udWxsKQogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIG4uQ2hhbmdlV29ya3NoZWV0KF9uYW1lLCB2YWx1ZSk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICAgICAgZm9yZWFjaCAodmFyIHdzIGluIFdvcmtib29rLldvcmtzaGVldHMpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIGlmICghKHdzIGlzIEV4Y2VsQ2hhcnRzaGVldCkpCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgZm9yZWFjaCAodmFyIG4gaW4gd3MuTmFtZXMpCiAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICBpZiAoc3RyaW5nLklzTnVsbE9yRW1wdHkobi5OYW1lRm9ybXVsYSkgJiYgbi5OYW1lVmFsdWUgPT0gbnVsbCkKICAgICAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgbi5DaGFuZ2VXb3Jrc2hlZXQoX25hbWUsIHZhbHVlKTsKICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgIH0KICAgICAgICBpbnRlcm5hbCBFeGNlbE5hbWVkUmFuZ2VDb2xsZWN0aW9uIF9uYW1lczsKICAgICAgICAvLy8gPHN1bW1hcnk+CiAgICAgICAgLy8vIFByb3ZpZGVzIGFjY2VzcyB0byBuYW1lZCByYW5nZXMKICAgICAgICAvLy8gPC9zdW1tYXJ5PgogICAgICAgIHB1YmxpYyBFeGNlbE5hbWVkUmFuZ2VDb2xsZWN0aW9uIE5hbWVzIAogICAgICAgIHsKICAgICAgICAgICAgZ2V0CiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIENoZWNrU2hlZXRUeXBlKCk7CiAgICAgICAgICAgICAgICByZXR1cm4gX25hbWVzOwogICAgICAgICAgICB9CiAgICAgICAgfQoJCS8vLyA8c3VtbWFyeT4KCQkvLy8gSW5kaWNhdGVzIGlmIHRoZSB3b3Jrc2hlZXQgaXMgaGlkZGVuIGluIHRoZSB3b3JrYm9vawoJCS8vLyA8L3N1bW1hcnk+CgkJcHVibGljIGVXb3JrU2hlZXRIaWRkZW4gSGlkZGVuCgkJewoJCQlnZXQgCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIHN0cmluZyBzdGF0ZT1fcGFja2FnZS5Xb3JrYm9vay5HZXRYbWxOb2RlU3RyaW5nKHN0cmluZy5Gb3JtYXQoImQ6c2hlZXRzL2Q6c2hlZXRbQHNoZWV0SWQ9ezB9XS9Ac3RhdGUiLCBfc2hlZXRJRCkpOwogICAgICAgICAgICAgICAgaWYgKHN0YXRlID09ICJoaWRkZW4iKQogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIHJldHVybiBlV29ya1NoZWV0SGlkZGVuLkhpZGRlbjsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGVsc2UgaWYgKHN0YXRlID09ICJ2ZXJ5SGlkZGVuIikKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICByZXR1cm4gZVdvcmtTaGVldEhpZGRlbi5WZXJ5SGlkZGVuOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgcmV0dXJuIGVXb3JrU2hlZXRIaWRkZW4uVmlzaWJsZTsKICAgICAgICAgICAgfQoJCQlzZXQKCQkJewogICAgICAgICAgICAgICAgICAgIGlmICh2YWx1ZSA9PSBlV29ya1NoZWV0SGlkZGVuLlZpc2libGUpCiAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICBfcGFja2FnZS5Xb3JrYm9vay5EZWxldGVOb2RlKHN0cmluZy5Gb3JtYXQoImQ6c2hlZXRzL2Q6c2hlZXRbQHNoZWV0SWQ9ezB9XS9Ac3RhdGUiLCBfc2hlZXRJRCkpOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICBlbHNlCiAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICBzdHJpbmcgdjsKICAgICAgICAgICAgICAgICAgICAgICAgdj12YWx1ZS5Ub1N0cmluZygpOyAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICB2PXYuU3Vic3RyaW5nKDAsMSkuVG9Mb3dlcihDdWx0dXJlSW5mby5JbnZhcmlhbnRDdWx0dXJlKSt2LlN1YnN0cmluZygxKTsKICAgICAgICAgICAgICAgICAgICAgICAgX3BhY2thZ2UuV29ya2Jvb2suU2V0WG1sTm9kZVN0cmluZyhzdHJpbmcuRm9ybWF0KCJkOnNoZWV0cy9kOnNoZWV0W0BzaGVldElkPXswfV0vQHN0YXRlIiwgX3NoZWV0SUQpLHYgKTsKICAgICAgICAgICAgICAgICAgICB9CgkJICAgIH0KCQl9CiAgICAgICAgZG91YmxlIF9kZWZhdWx0Um93SGVpZ2h0ID0gZG91YmxlLk5hTjsKICAgICAgICAvLy8gPHN1bW1hcnk+CgkJLy8vIEdldC9zZXQgdGhlIGRlZmF1bHQgaGVpZ2h0IG9mIGFsbCByb3dzIGluIHRoZSB3b3Jrc2hlZXQKCQkvLy8gPC9zdW1tYXJ5PgogICAgICAgIHB1YmxpYyBkb3VibGUgRGVmYXVsdFJvd0hlaWdodAoJCXsKCQkJZ2V0IAoJCQl7CiAgICAgICAgICAgICAgICBDaGVja1NoZWV0VHlwZSgpOwogICAgICAgICAgICAgICAgaWYgKGRvdWJsZS5Jc05hTihfZGVmYXVsdFJvd0hlaWdodCkpCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgX2RlZmF1bHRSb3dIZWlnaHQgPSBHZXRYbWxOb2RlRG91YmxlKCJkOnNoZWV0Rm9ybWF0UHIvQGRlZmF1bHRSb3dIZWlnaHQiKTsKICAgICAgICAgICAgICAgICAgICBpZihkb3VibGUuSXNOYU4oX2RlZmF1bHRSb3dIZWlnaHQpKQogICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgX2RlZmF1bHRSb3dIZWlnaHQgPSAxNTsgLy8gRXhjZWwgZGVmYXVsdCBoZWlnaHQKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9CgkJCQlyZXR1cm4gX2RlZmF1bHRSb3dIZWlnaHQ7CgkJCX0KCQkJc2V0CgkJCXsKICAgICAgICAgICAgICAgIENoZWNrU2hlZXRUeXBlKCk7CiAgICAgICAgICAgICAgICBfZGVmYXVsdFJvd0hlaWdodCA9IHZhbHVlOwogICAgICAgICAgICAgICAgU2V0WG1sTm9kZVN0cmluZygiZDpzaGVldEZvcm1hdFByL0BkZWZhdWx0Um93SGVpZ2h0IiwgdmFsdWUuVG9TdHJpbmcoQ3VsdHVyZUluZm8uSW52YXJpYW50Q3VsdHVyZSkpOwogICAgICAgICAgICAgICAgU2V0WG1sTm9kZUJvb2woImQ6c2hlZXRGb3JtYXRQci9AY3VzdG9tSGVpZ2h0IiwgdmFsdWUgIT0gMTUpOwoKICAgICAgICAgICAgICAgIGlmIChkb3VibGUuSXNOYU4oR2V0WG1sTm9kZURvdWJsZSgiZDpzaGVldEZvcm1hdFByL0BkZWZhdWx0Q29sV2lkdGgiKSkpCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgRGVmYXVsdENvbFdpZHRoID0gOS4xNDA2MjU7CiAgICAgICAgICAgICAgICB9CgkJCX0KCQl9CiAgICAgICAgLy8vIDxzdW1tYXJ5PgogICAgICAgIC8vLyBHZXQvc2V0IHRoZSBkZWZhdWx0IHdpZHRoIG9mIGFsbCByb3dzIGluIHRoZSB3b3Jrc2hlZXQKICAgICAgICAvLy8gPC9zdW1tYXJ5PgogICAgICAgIHB1YmxpYyBkb3VibGUgRGVmYXVsdENvbFdpZHRoCiAgICAgICAgewogICAgICAgICAgICBnZXQKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgQ2hlY2tTaGVldFR5cGUoKTsKICAgICAgICAgICAgICAgIGRvdWJsZSByZXQgPSBHZXRYbWxOb2RlRG91YmxlKCJkOnNoZWV0Rm9ybWF0UHIvQGRlZmF1bHRDb2xXaWR0aCIpOwogICAgICAgICAgICAgICAgaWYgKGRvdWJsZS5Jc05hTihyZXQpKQogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIHJldCA9IDkuMTQwNjI1OyAvLyBFeGNlbCdzIGRlZmF1bHQgd2lkdGgKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIHJldHVybiByZXQ7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgc2V0CiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIENoZWNrU2hlZXRUeXBlKCk7CiAgICAgICAgICAgICAgICBTZXRYbWxOb2RlU3RyaW5nKCJkOnNoZWV0Rm9ybWF0UHIvQGRlZmF1bHRDb2xXaWR0aCIsIHZhbHVlLlRvU3RyaW5nKEN1bHR1cmVJbmZvLkludmFyaWFudEN1bHR1cmUpKTsKCiAgICAgICAgICAgICAgICBpZiAoZG91YmxlLklzTmFOKEdldFhtbE5vZGVEb3VibGUoImQ6c2hlZXRGb3JtYXRQci9AZGVmYXVsdFJvd0hlaWdodCIpKSkKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICBEZWZhdWx0Um93SGVpZ2h0ID0gMTU7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgLyoqIDxvdXRsaW5lUHIgYXBwbHlTdHlsZXM9IjEiIHN1bW1hcnlCZWxvdz0iMCIgc3VtbWFyeVJpZ2h0PSIwIiAvPiAqKi8KICAgICAgICBjb25zdCBzdHJpbmcgb3V0TGluZVN1bW1hcnlCZWxvd1BhdGggPSAiZDpzaGVldFByL2Q6b3V0bGluZVByL0BzdW1tYXJ5QmVsb3ciOwogICAgICAgIC8vLyA8c3VtbWFyeT4KICAgICAgICAvLy8gU3VtbWFyeSByb3dzIGJlbG93IGRldGFpbHMgCiAgICAgICAgLy8vIDwvc3VtbWFyeT4KICAgICAgICBwdWJsaWMgYm9vbCBPdXRMaW5lU3VtbWFyeUJlbG93CiAgICAgICAgeyAKICAgICAgICAgICAgZ2V0CiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIENoZWNrU2hlZXRUeXBlKCk7CiAgICAgICAgICAgICAgICByZXR1cm4gR2V0WG1sTm9kZUJvb2wob3V0TGluZVN1bW1hcnlCZWxvd1BhdGgpOwogICAgICAgICAgICB9CiAgICAgICAgICAgIHNldAogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBDaGVja1NoZWV0VHlwZSgpOwogICAgICAgICAgICAgICAgU2V0WG1sTm9kZVN0cmluZyhvdXRMaW5lU3VtbWFyeUJlbG93UGF0aCwgdmFsdWUgPyAiMSIgOiAiMCIpOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIGNvbnN0IHN0cmluZyBvdXRMaW5lU3VtbWFyeVJpZ2h0UGF0aCA9ICJkOnNoZWV0UHIvZDpvdXRsaW5lUHIvQHN1bW1hcnlSaWdodCI7CiAgICAgICAgLy8vIDxzdW1tYXJ5PgogICAgICAgIC8vLyBTdW1tYXJ5IHJvd3MgdG8gcmlnaHQgb2YgZGV0YWlscwogICAgICAgIC8vLyA8L3N1bW1hcnk+CiAgICAgICAgcHVibGljIGJvb2wgT3V0TGluZVN1bW1hcnlSaWdodAogICAgICAgIHsKICAgICAgICAgICAgZ2V0CiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIENoZWNrU2hlZXRUeXBlKCk7CiAgICAgICAgICAgICAgICByZXR1cm4gR2V0WG1sTm9kZUJvb2wob3V0TGluZVN1bW1hcnlSaWdodFBhdGgpOwogICAgICAgICAgICB9CiAgICAgICAgICAgIHNldAogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBDaGVja1NoZWV0VHlwZSgpOwogICAgICAgICAgICAgICAgU2V0WG1sTm9kZVN0cmluZyhvdXRMaW5lU3VtbWFyeVJpZ2h0UGF0aCwgdmFsdWUgPyAiMSIgOiAiMCIpOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIGNvbnN0IHN0cmluZyBvdXRMaW5lQXBwbHlTdHlsZVBhdGggPSAiZDpzaGVldFByL2Q6b3V0bGluZVByL0BhcHBseVN0eWxlcyI7CiAgICAgICAgLy8vIDxzdW1tYXJ5PgogICAgICAgIC8vLyBBdXRvbWF0aWMgc3R5bGVzCiAgICAgICAgLy8vIDwvc3VtbWFyeT4KICAgICAgICBwdWJsaWMgYm9vbCBPdXRMaW5lQXBwbHlTdHlsZQogICAgICAgIHsKICAgICAgICAgICAgZ2V0CiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIENoZWNrU2hlZXRUeXBlKCk7CiAgICAgICAgICAgICAgICByZXR1cm4gR2V0WG1sTm9kZUJvb2wob3V0TGluZUFwcGx5U3R5bGVQYXRoKTsKICAgICAgICAgICAgfQogICAgICAgICAgICBzZXQKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgQ2hlY2tTaGVldFR5cGUoKTsKICAgICAgICAgICAgICAgIFNldFhtbE5vZGVTdHJpbmcob3V0TGluZUFwcGx5U3R5bGVQYXRoLCB2YWx1ZSA/ICIxIiA6ICIwIik7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgY29uc3Qgc3RyaW5nIHRhYkNvbG9yUGF0aCA9ICJkOnNoZWV0UHIvZDp0YWJDb2xvci9AcmdiIjsKICAgICAgICAvLy8gPHN1bW1hcnk+CiAgICAgICAgLy8vIENvbG9yIG9mIHRoZSBzaGVldCB0YWIKICAgICAgICAvLy8gPC9zdW1tYXJ5PgogICAgICAgIHB1YmxpYyBDb2xvciBUYWJDb2xvcgogICAgICAgIHsKICAgICAgICAgICAgZ2V0CiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIHN0cmluZyBjb2wgPSBHZXRYbWxOb2RlU3RyaW5nKHRhYkNvbG9yUGF0aCk7CiAgICAgICAgICAgICAgICBpZiAoY29sID09ICIiKQogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIHJldHVybiBDb2xvci5FbXB0eTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGVsc2UKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICByZXR1cm4gQ29sb3IuRnJvbUFyZ2IoaW50LlBhcnNlKGNvbCwgU3lzdGVtLkdsb2JhbGl6YXRpb24uTnVtYmVyU3R5bGVzLkFsbG93SGV4U3BlY2lmaWVyKSk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICAgICAgc2V0CiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIFNldFhtbE5vZGVTdHJpbmcodGFiQ29sb3JQYXRoLCB2YWx1ZS5Ub0FyZ2IoKS5Ub1N0cmluZygiWCIpKTsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgICAgICBjb25zdCBzdHJpbmcgY29kZU1vZHVsZU5hbWVQYXRoID0gImQ6c2hlZXRQci9AY29kZU5hbWUiOwogICAgICAgIGludGVybmFsIHN0cmluZyBDb2RlTW9kdWxlTmFtZQogICAgICAgIHsKICAgICAgICAgICAgZ2V0CiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIHJldHVybiBHZXRYbWxOb2RlU3RyaW5nKGNvZGVNb2R1bGVOYW1lUGF0aCk7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgc2V0CiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIFNldFhtbE5vZGVTdHJpbmcoY29kZU1vZHVsZU5hbWVQYXRoLCB2YWx1ZSk7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgaW50ZXJuYWwgdm9pZCBDb2RlTmFtZUNoYW5nZShzdHJpbmcgdmFsdWUpCiAgICAgICAgewogICAgICAgICAgICBDb2RlTW9kdWxlTmFtZSA9IHZhbHVlOwogICAgICAgIH0KICAgICAgICBwdWJsaWMgVkJBLkV4Y2VsVkJBTW9kdWxlIENvZGVNb2R1bGUKICAgICAgICB7CiAgICAgICAgICAgIGdldAogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBpZiAoX3BhY2thZ2UuV29ya2Jvb2suVmJhUHJvamVjdCAhPSBudWxsKQogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIHJldHVybiBfcGFja2FnZS5Xb3JrYm9vay5WYmFQcm9qZWN0Lk1vZHVsZXNbQ29kZU1vZHVsZU5hbWVdOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgZWxzZQogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIHJldHVybiBudWxsOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgICNyZWdpb24gV29ya3NoZWV0WG1sCgkJLy8vIDxzdW1tYXJ5PgoJCS8vLyBUaGUgWE1MIGRvY3VtZW50IGhvbGRpbmcgdGhlIHdvcmtzaGVldCBkYXRhLgogICAgICAgIC8vLyBBbGwgY29sdW1uLCByb3csIGNlbGwsIHBhZ2VicmVhaywgbWVyZ2VkIGNlbGwgYW5kIGh5cGVybGluay1kYXRhIGFyZSBsb2FkZWQgaW50byBtZW1vcnkgYW5kIHJlbW92ZWQgZnJvbSB0aGUgZG9jdW1lbnQgd2hlbiBsb2FkaW5nIHRoZSBkb2N1bWVudC4gICAgICAgIAoJCS8vLyA8L3N1bW1hcnk+CgkJcHVibGljIFhtbERvY3VtZW50IFdvcmtzaGVldFhtbAoJCXsKCQkJZ2V0CgkJCXsKCQkJCXJldHVybiAoX3dvcmtzaGVldFhtbCk7CgkJCX0KCQl9CiAgICAgICAgaW50ZXJuYWwgRXhjZWxWbWxEcmF3aW5nQ29tbWVudENvbGxlY3Rpb24gX3ZtbERyYXdpbmdzID0gbnVsbDsKICAgICAgICAvLy8gPHN1bW1hcnk+CiAgICAgICAgLy8vIFZtbCBkcmF3aW5ncy4gdW5kZXJsYXlpbmcgb2JqZWN0IGZvciBjb21tZW50cwogICAgICAgIC8vLyA8L3N1bW1hcnk+CiAgICAgICAgaW50ZXJuYWwgRXhjZWxWbWxEcmF3aW5nQ29tbWVudENvbGxlY3Rpb24gVm1sRHJhd2luZ3NDb21tZW50cwogICAgICAgIHsKICAgICAgICAgICAgZ2V0CiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIGlmIChfdm1sRHJhd2luZ3MgPT0gbnVsbCkKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICBDcmVhdGVWbWxDb2xsZWN0aW9uKCk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICByZXR1cm4gX3ZtbERyYXdpbmdzOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIGludGVybmFsIEV4Y2VsQ29tbWVudENvbGxlY3Rpb24gX2NvbW1lbnRzID0gbnVsbDsKICAgICAgICAvLy8gPHN1bW1hcnk+CiAgICAgICAgLy8vIENvbGxlY3Rpb24gb2YgY29tbWVudHMKICAgICAgICAvLy8gPC9zdW1tYXJ5PgogICAgICAgIHB1YmxpYyBFeGNlbENvbW1lbnRDb2xsZWN0aW9uIENvbW1lbnRzCiAgICAgICAgewogICAgICAgICAgICBnZXQKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgQ2hlY2tTaGVldFR5cGUoKTsKICAgICAgICAgICAgICAgIGlmIChfY29tbWVudHMgPT0gbnVsbCkKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICBDcmVhdGVWbWxDb2xsZWN0aW9uKCk7CiAgICAgICAgICAgICAgICAgICAgX2NvbW1lbnRzID0gbmV3IEV4Y2VsQ29tbWVudENvbGxlY3Rpb24oX3BhY2thZ2UsIHRoaXMsIE5hbWVTcGFjZU1hbmFnZXIpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgcmV0dXJuIF9jb21tZW50czsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgICAgICBwcml2YXRlIHZvaWQgQ3JlYXRlVm1sQ29sbGVjdGlvbigpCiAgICAgICAgewogICAgICAgICAgICB2YXIgdm1sTm9kZSA9IF93b3Jrc2hlZXRYbWwuRG9jdW1lbnRFbGVtZW50LlNlbGVjdFNpbmdsZU5vZGUoImQ6bGVnYWN5RHJhd2luZy9AcjppZCIsIE5hbWVTcGFjZU1hbmFnZXIpOwogICAgICAgICAgICBpZiAodm1sTm9kZSA9PSBudWxsKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBfdm1sRHJhd2luZ3MgPSBuZXcgRXhjZWxWbWxEcmF3aW5nQ29tbWVudENvbGxlY3Rpb24oX3BhY2thZ2UsIHRoaXMsIG51bGwpOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGVsc2UKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgaWYgKFBhcnQuUmVsYXRpb25zaGlwRXhpc3RzKHZtbE5vZGUuVmFsdWUpKQogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIHZhciByZWwgPSBQYXJ0LkdldFJlbGF0aW9uc2hpcCh2bWxOb2RlLlZhbHVlKTsKICAgICAgICAgICAgICAgICAgICB2YXIgdm1sVXJpID0gVXJpSGVscGVyLlJlc29sdmVQYXJ0VXJpKHJlbC5Tb3VyY2VVcmksIHJlbC5UYXJnZXRVcmkpOwoKICAgICAgICAgICAgICAgICAgICBfdm1sRHJhd2luZ3MgPSBuZXcgRXhjZWxWbWxEcmF3aW5nQ29tbWVudENvbGxlY3Rpb24oX3BhY2thZ2UsIHRoaXMsIHZtbFVyaSk7CiAgICAgICAgICAgICAgICAgICAgX3ZtbERyYXdpbmdzLlJlbElkID0gcmVsLklkOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICBwcml2YXRlIHZvaWQgQ3JlYXRlWG1sKCkKICAgICAgICB7CiAgICAgICAgICAgIF93b3Jrc2hlZXRYbWwgPSBuZXcgWG1sRG9jdW1lbnQoKTsKICAgICAgICAgICAgX3dvcmtzaGVldFhtbC5QcmVzZXJ2ZVdoaXRlc3BhY2UgPSBFeGNlbFBhY2thZ2UucHJlc2VydmVXaGl0ZXNwYWNlOwogICAgICAgICAgICBQYWNrYWdpbmcuWmlwUGFja2FnZVBhcnQgcGFja1BhcnQgPSBfcGFja2FnZS5QYWNrYWdlLkdldFBhcnQoV29ya3NoZWV0VXJpKTsKICAgICAgICAgICAgc3RyaW5nIHhtbCA9ICIiOwoKICAgICAgICAgICAgLy8gRmlyc3QgQ29sdW1ucywgcm93cywgY2VsbHMsIG1lcmdlY2VsbHMsIGh5cGVybGlua3MgYW5kIHBhZ2VicmVha2VzIGFyZSBsb2FkZWQgZnJvbSBhIHhtbHN0cmVhbSB0byBvcHRpbWl6ZSBzcGVlZC4uLgogICAgICAgICAgICBib29sIGRvQWRqdXN0ID0gX3BhY2thZ2UuRG9BZGp1c3REcmF3aW5nczsKICAgICAgICAgICAgX3BhY2thZ2UuRG9BZGp1c3REcmF3aW5ncyA9IGZhbHNlOwogICAgICAgICAgICBTdHJlYW0gc3RyZWFtID0gcGFja1BhcnQuR2V0U3RyZWFtKCk7CgogICAgICAgICAgICBYbWxUZXh0UmVhZGVyIHhyID0gbmV3IFhtbFRleHRSZWFkZXIoc3RyZWFtKTsKICAgICAgICAgICAgeHIuUHJvaGliaXREdGQgPSB0cnVlOwogICAgICAgICAgICB4ci5XaGl0ZXNwYWNlSGFuZGxpbmcgPSBXaGl0ZXNwYWNlSGFuZGxpbmcuTm9uZTsKICAgICAgICAgICAgTG9hZENvbHVtbnMoeHIpOyAgICAvL2NvbHVtblhtbAogICAgICAgICAgICBsb25nIHN0YXJ0ID0gc3RyZWFtLlBvc2l0aW9uOwogICAgICAgICAgICBMb2FkQ2VsbHMoeHIpOwogICAgICAgICAgICB2YXIgbmV4dEVsZW1lbnRMZW5ndGggPSBHZXRBdHRyaWJ1dGVMZW5ndGgoeHIpOwogICAgICAgICAgICBsb25nIGVuZCA9IHN0cmVhbS5Qb3NpdGlvbiAtIG5leHRFbGVtZW50TGVuZ3RoOwogICAgICAgICAgICBMb2FkTWVyZ2VDZWxscyh4cik7CiAgICAgICAgICAgIExvYWRIeXBlckxpbmtzKHhyKTsKICAgICAgICAgICAgTG9hZFJvd1BhZ2VCcmVha2VzKHhyKTsKICAgICAgICAgICAgTG9hZENvbFBhZ2VCcmVha2VzKHhyKTsKICAgICAgICAgICAgLy8uLi50aGVuIHRoZSByZXN0IG9mIHRoZSBYbWwgaXMgZXh0cmFjdGVkIGFuZCBsb2FkZWQgaW50byB0aGUgV29ya3NoZWV0WG1sIGRvY3VtZW50LgogICAgICAgICAgICBzdHJlYW0uU2VlaygwLCBTZWVrT3JpZ2luLkJlZ2luKTsKICAgICAgICAgICAgRW5jb2RpbmcgZW5jb2Rpbmc7CiAgICAgICAgICAgIHhtbCA9IEdldFdvcmtTaGVldFhtbChzdHJlYW0sIHN0YXJ0LCBlbmQsIG91dCBlbmNvZGluZyk7CgogICAgICAgICAgICAvL2ZpcnN0IGNoYXIgaXMgaW52YWxpZCBzb21ldGltZXM/PyAKICAgICAgICAgICAgaWYgKHhtbFswXSAhPSAnPCcpCiAgICAgICAgICAgICAgICBMb2FkWG1sU2FmZShfd29ya3NoZWV0WG1sLCB4bWwuU3Vic3RyaW5nKDEsIHhtbC5MZW5ndGggLSAxKSwgZW5jb2RpbmcpOwogICAgICAgICAgICBlbHNlCiAgICAgICAgICAgICAgICBMb2FkWG1sU2FmZShfd29ya3NoZWV0WG1sLCB4bWwsIGVuY29kaW5nKTsKCiAgICAgICAgICAgIF9wYWNrYWdlLkRvQWRqdXN0RHJhd2luZ3MgPSBkb0FkanVzdDsKICAgICAgICAgICAgQ2xlYXJOb2RlcygpOwogICAgICAgIH0KICAgICAgICAvLy8gPHN1bW1hcnk+CiAgICAgICAgLy8vIEdldCB0aGUgbGVudGggb2YgdGhlIGF0dHJpYnV0ZXMKICAgICAgICAvLy8gQ29uZGl0aW9uYWwgZm9ybWF0dGluZyBhdHRyaWJ1dGVzIGNhbiBiZSBleHRyZW1seSBsb25nIHNvbSBnZXQgbGVuZ3RoIG9mIHRoZSBhdHRyaWJ1dGVzIHRvIGZpbmV0dW5lIHBvc2l0aW9uLgogICAgICAgIC8vLyA8L3N1bW1hcnk+CiAgICAgICAgLy8vIDxwYXJhbSBuYW1lPSJ4ciI+PC9wYXJhbT4KICAgICAgICAvLy8gPHJldHVybnM+PC9yZXR1cm5zPgogICAgICAgIHByaXZhdGUgaW50IEdldEF0dHJpYnV0ZUxlbmd0aChYbWxUZXh0UmVhZGVyIHhyKQogICAgICAgIHsKICAgICAgICAgICAgaWYgKHhyLk5vZGVUeXBlICE9IFhtbE5vZGVUeXBlLkVsZW1lbnQpIHJldHVybiAwOwogICAgICAgICAgICB2YXIgbGVuZ3RoID0gMDsKICAgICAgICAgICAgCiAgICAgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgeHIuQXR0cmlidXRlQ291bnQ7IGkrKykKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgdmFyIGE9eHIuR2V0QXR0cmlidXRlKGkpOwogICAgICAgICAgICAgICAgbGVuZ3RoICs9IHN0cmluZy5Jc051bGxPckVtcHR5KGEpID8gMCA6IGEuTGVuZ3RoOwogICAgICAgICAgICB9CiAgICAgICAgICAgIHJldHVybiBsZW5ndGg7CiAgICAgICAgfQogICAgICAgIHByaXZhdGUgdm9pZCBMb2FkUm93UGFnZUJyZWFrZXMoWG1sVGV4dFJlYWRlciB4cikKICAgICAgICB7CiAgICAgICAgICAgIGlmKCFSZWFkVW50aWwoeHIsICJyb3dCcmVha3MiLCJjb2xCcmVha3MiKSkgcmV0dXJuOwogICAgICAgICAgICB3aGlsZSAoeHIuUmVhZCgpKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBpZiAoeHIuTG9jYWxOYW1lID09ICJicmsiKQogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIGlmICh4ci5Ob2RlVHlwZSA9PSBYbWxOb2RlVHlwZS5FbGVtZW50KQogICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgaW50IGlkOwogICAgICAgICAgICAgICAgICAgICAgICBpZiAoaW50LlRyeVBhcnNlKHhyLkdldEF0dHJpYnV0ZSgiaWQiKSwgb3V0IGlkKSkKICAgICAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgUm93KGlkKS5QYWdlQnJlYWsgPSB0cnVlOwogICAgICAgICAgICAgICAgICAgICAgICB9ICAgCiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgZWxzZQogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIHByaXZhdGUgdm9pZCBMb2FkQ29sUGFnZUJyZWFrZXMoWG1sVGV4dFJlYWRlciB4cikKICAgICAgICB7CiAgICAgICAgICAgIGlmICghUmVhZFVudGlsKHhyLCAiY29sQnJlYWtzIikpIHJldHVybjsKICAgICAgICAgICAgd2hpbGUgKHhyLlJlYWQoKSkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgaWYgKHhyLkxvY2FsTmFtZSA9PSAiYnJrIikKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICBpZiAoeHIuTm9kZVR5cGUgPT0gWG1sTm9kZVR5cGUuRWxlbWVudCkKICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgIGludCBpZDsKICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGludC5UcnlQYXJzZSh4ci5HZXRBdHRyaWJ1dGUoImlkIiksIG91dCBpZCkpCiAgICAgICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIENvbHVtbihpZCkuUGFnZUJyZWFrID0gdHJ1ZTsKICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGVsc2UKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgcHJpdmF0ZSB2b2lkIENsZWFyTm9kZXMoKQogICAgICAgIHsKICAgICAgICAgICAgaWYgKF93b3Jrc2hlZXRYbWwuU2VsZWN0U2luZ2xlTm9kZSgiLy9kOmNvbHMiLCBOYW1lU3BhY2VNYW5hZ2VyKSE9bnVsbCkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgX3dvcmtzaGVldFhtbC5TZWxlY3RTaW5nbGVOb2RlKCIvL2Q6Y29scyIsIE5hbWVTcGFjZU1hbmFnZXIpLlJlbW92ZUFsbCgpOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGlmIChfd29ya3NoZWV0WG1sLlNlbGVjdFNpbmdsZU5vZGUoIi8vZDptZXJnZUNlbGxzIiwgTmFtZVNwYWNlTWFuYWdlcikgIT0gbnVsbCkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgX3dvcmtzaGVldFhtbC5TZWxlY3RTaW5nbGVOb2RlKCIvL2Q6bWVyZ2VDZWxscyIsIE5hbWVTcGFjZU1hbmFnZXIpLlJlbW92ZUFsbCgpOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGlmIChfd29ya3NoZWV0WG1sLlNlbGVjdFNpbmdsZU5vZGUoIi8vZDpoeXBlcmxpbmtzIiwgTmFtZVNwYWNlTWFuYWdlcikgIT0gbnVsbCkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgX3dvcmtzaGVldFhtbC5TZWxlY3RTaW5nbGVOb2RlKCIvL2Q6aHlwZXJsaW5rcyIsIE5hbWVTcGFjZU1hbmFnZXIpLlJlbW92ZUFsbCgpOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGlmIChfd29ya3NoZWV0WG1sLlNlbGVjdFNpbmdsZU5vZGUoIi8vZDpyb3dCcmVha3MiLCBOYW1lU3BhY2VNYW5hZ2VyKSAhPSBudWxsKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBfd29ya3NoZWV0WG1sLlNlbGVjdFNpbmdsZU5vZGUoIi8vZDpyb3dCcmVha3MiLCBOYW1lU3BhY2VNYW5hZ2VyKS5SZW1vdmVBbGwoKTsKICAgICAgICAgICAgfQogICAgICAgICAgICBpZiAoX3dvcmtzaGVldFhtbC5TZWxlY3RTaW5nbGVOb2RlKCIvL2Q6Y29sQnJlYWtzIiwgTmFtZVNwYWNlTWFuYWdlcikgIT0gbnVsbCkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgX3dvcmtzaGVldFhtbC5TZWxlY3RTaW5nbGVOb2RlKCIvL2Q6Y29sQnJlYWtzIiwgTmFtZVNwYWNlTWFuYWdlcikuUmVtb3ZlQWxsKCk7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgY29uc3QgaW50IEJMT0NLU0laRT04MTkyOwogICAgICAgIHByaXZhdGUgc3RyaW5nIEdldFdvcmtTaGVldFhtbChTdHJlYW0gc3RyZWFtLCBsb25nIHN0YXJ0LCBsb25nIGVuZCwgb3V0IEVuY29kaW5nIGVuY29kaW5nKQogICAgICAgIHsKICAgICAgICAgICAgU3RyZWFtUmVhZGVyIHNyID0gbmV3IFN0cmVhbVJlYWRlcihzdHJlYW0pOwogICAgICAgICAgICBpbnQgbGVuZ3RoID0gMDsKICAgICAgICAgICAgY2hhcltdIGJsb2NrOwogICAgICAgICAgICBpbnQgcG9zOwogICAgICAgICAgICBTdHJpbmdCdWlsZGVyIHNiID0gbmV3IFN0cmluZ0J1aWxkZXIoKTsgICAgICAgICAgICAKICAgICAgICAgICAgTWF0Y2ggc3RhcnRtTWF0Y2gsIGVuZE1hdGNoOwogICAgICAgICAgICBkbwogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBpbnQgc2l6ZSA9IHN0cmVhbS5MZW5ndGggPCBCTE9DS1NJWkUgPyAoaW50KXN0cmVhbS5MZW5ndGggOiBCTE9DS1NJWkU7CiAgICAgICAgICAgICAgICBibG9jayA9IG5ldyBjaGFyW3NpemVdOwogICAgICAgICAgICAgICAgcG9zID0gc3IuUmVhZEJsb2NrKGJsb2NrLCAwLCBzaXplKTsgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgIHNiLkFwcGVuZChibG9jaywwLHBvcyk7CiAgICAgICAgICAgICAgICBsZW5ndGggKz0gc2l6ZTsKICAgICAgICAgICAgfQogICAgICAgICAgICB3aGlsZSAobGVuZ3RoIDwgc3RhcnQgKyAyMCAmJiBsZW5ndGggPCBlbmQpOwogICAgICAgICAgICBzdGFydG1NYXRjaCA9IFJlZ2V4Lk1hdGNoKHNiLlRvU3RyaW5nKCksIHN0cmluZy5Gb3JtYXQoIig8W14+XSp7MH1bXj5dKj4pIiwgInNoZWV0RGF0YSIpKTsKICAgICAgICAgICAgaWYgKCFzdGFydG1NYXRjaC5TdWNjZXNzKSAvL05vdCBmb3VuZAogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBlbmNvZGluZyA9IHNyLkN1cnJlbnRFbmNvZGluZzsKICAgICAgICAgICAgICAgIHJldHVybiBzYi5Ub1N0cmluZygpOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGVsc2UKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgc3RyaW5nIHMgPSBzYi5Ub1N0cmluZygpOwogICAgICAgICAgICAgICAgc3RyaW5nIHhtbCA9IHMuU3Vic3RyaW5nKDAsIHN0YXJ0bU1hdGNoLkluZGV4KTsgCiAgICAgICAgICAgICAgICBpZihzdGFydG1NYXRjaC5WYWx1ZS5FbmRzV2l0aCgiLz4iKSkKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICB4bWwgKz0gcy5TdWJzdHJpbmcoc3RhcnRtTWF0Y2guSW5kZXgsIHMuTGVuZ3RoIC0gc3RhcnRtTWF0Y2guSW5kZXgpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgZWxzZQogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIGlmIChzci5QZWVrKCkgIT0gLTEpCiAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICAvKioqKiBGaXhlcyBpc3N1ZSAxNDc4OC4gRml4IGJ5IFBoaWxpcCBHYXJyZXR0ICoqKiovCiAgICAgICAgICAgICAgICAgICAgICAgIGxvbmcgZW5kU2Vla1N0YXJ0ID0gZW5kOwoKICAgICAgICAgICAgICAgICAgICAgICAgd2hpbGUgKGVuZFNlZWtTdGFydCA+PSAwKQogICAgICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBlbmRTZWVrU3RhcnQgPSBNYXRoLk1heChlbmRTZWVrU3RhcnQgLSBCTE9DS1NJWkUsIDApOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgaW50IHNpemUgPSAoaW50KShlbmQgLSBlbmRTZWVrU3RhcnQpOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgc3RyZWFtLlNlZWsoZW5kU2Vla1N0YXJ0LCBTZWVrT3JpZ2luLkJlZ2luKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJsb2NrID0gbmV3IGNoYXJbc2l6ZV07CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBzciA9IG5ldyBTdHJlYW1SZWFkZXIoc3RyZWFtKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBvcyA9IHNyLlJlYWRCbG9jayhibG9jaywgMCwgc2l6ZSk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBzYiA9IG5ldyBTdHJpbmdCdWlsZGVyKCk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBzYi5BcHBlbmQoYmxvY2ssIDAsIHBvcyk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBzID0gc2IuVG9TdHJpbmcoKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVuZE1hdGNoID0gUmVnZXguTWF0Y2gocywgc3RyaW5nLkZvcm1hdCgiKDwvW14+XSp7MH1bXj5dKj4pIiwgInNoZWV0RGF0YSIpKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChlbmRNYXRjaC5TdWNjZXNzKQogICAgICAgICAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIGVuZE1hdGNoID0gUmVnZXguTWF0Y2gocywgc3RyaW5nLkZvcm1hdCgiKDwvW14+XSp7MH1bXj5dKj4pIiwgInNoZWV0RGF0YSIpKTsKICAgICAgICAgICAgICAgICAgICB4bWwgKz0gIjxzaGVldERhdGEvPiIgKyBzLlN1YnN0cmluZyhlbmRNYXRjaC5JbmRleCArIGVuZE1hdGNoLkxlbmd0aCwgcy5MZW5ndGggLSAoZW5kTWF0Y2guSW5kZXggKyBlbmRNYXRjaC5MZW5ndGgpKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGlmIChzci5QZWVrKCkgPiAtMSkKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICB4bWwgKz0gc3IuUmVhZFRvRW5kKCk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgIGVuY29kaW5nID0gc3IuQ3VycmVudEVuY29kaW5nOwogICAgICAgICAgICAgICAgcmV0dXJuIHhtbDsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgICAgICBwcml2YXRlIHZvaWQgR2V0QmxvY2tQb3Moc3RyaW5nIHhtbCwgc3RyaW5nIHRhZywgcmVmIGludCBzdGFydCwgcmVmIGludCBlbmQpCiAgICAgICAgewogICAgICAgICAgICBNYXRjaCBzdGFydG1NYXRjaCwgZW5kTWF0Y2g7CiAgICAgICAgICAgIHN0YXJ0bU1hdGNoID0gUmVnZXguTWF0Y2goeG1sLlN1YnN0cmluZyhzdGFydCksIHN0cmluZy5Gb3JtYXQoIig8W14+XSp7MH1bXj5dKj4pIiwgdGFnKSk7IC8vIjxbYS16QS1aOl0qIiArIHRhZyArICJbP10qPiIpOwoKICAgICAgICAgICAgaWYgKCFzdGFydG1NYXRjaC5TdWNjZXNzKSAvL05vdCBmb3VuZAogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBzdGFydCA9IC0xOwogICAgICAgICAgICAgICAgZW5kID0gLTE7CiAgICAgICAgICAgICAgICByZXR1cm47CiAgICAgICAgICAgIH0KICAgICAgICAgICAgdmFyIHN0YXJ0UG9zPXN0YXJ0bU1hdGNoLkluZGV4K3N0YXJ0OwogICAgICAgICAgICBpZihzdGFydG1NYXRjaC5WYWx1ZS5TdWJzdHJpbmcoc3RhcnRtTWF0Y2guVmFsdWUuTGVuZ3RoLTIsMSk9PSIvIikKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgZW5kID0gc3RhcnRQb3MgKyBzdGFydG1NYXRjaC5MZW5ndGg7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgZWxzZQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBlbmRNYXRjaCA9IFJlZ2V4Lk1hdGNoKHhtbC5TdWJzdHJpbmcoc3RhcnQpLCBzdHJpbmcuRm9ybWF0KCIoPC9bXj5dKnswfVtePl0qPikiLCB0YWcpKTsKICAgICAgICAgICAgICAgIGlmIChlbmRNYXRjaC5TdWNjZXNzKQogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIGVuZCA9IGVuZE1hdGNoLkluZGV4ICsgZW5kTWF0Y2guTGVuZ3RoICsgc3RhcnQ7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICAgICAgc3RhcnQgPSBzdGFydFBvczsKICAgICAgICB9CiAgICAgICAgcHJpdmF0ZSBib29sIFJlYWRVbnRpbChYbWxUZXh0UmVhZGVyIHhyLHBhcmFtcyBzdHJpbmdbXSB0YWdOYW1lKQogICAgICAgIHsKICAgICAgICAgICAgaWYgKHhyLkVPRikgcmV0dXJuIGZhbHNlOwogICAgICAgICAgICB3aGlsZSAoIUFycmF5LkV4aXN0cyh0YWdOYW1lLCB0YWcgPT4geHIuTG9jYWxOYW1lLkVuZHNXaXRoKHRhZykpKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICB4ci5SZWFkKCk7CiAgICAgICAgICAgICAgICBpZiAoeHIuRU9GKSByZXR1cm4gZmFsc2U7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgcmV0dXJuICh4ci5Mb2NhbE5hbWUuRW5kc1dpdGgodGFnTmFtZVswXSkpOwogICAgICAgIH0KICAgICAgICBwcml2YXRlIHZvaWQgTG9hZENvbHVtbnMgKFhtbFRleHRSZWFkZXIgeHIpLy8oc3RyaW5nIHhtbCkKICAgICAgICB7CiAgICAgICAgICAgIHZhciBjb2xMaXN0ID0gbmV3IExpc3Q8SVJhbmdlSUQ+KCk7CiAgICAgICAgICAgIGlmIChSZWFkVW50aWwoeHIsICJjb2xzIiwgInNoZWV0RGF0YSIpKQogICAgICAgICAgICB7CiAgICAgICAgICAgIC8vaWYgKHhtbCAhPSAiIikKICAgICAgICAgICAgLy97CiAgICAgICAgICAgICAgICAvL3ZhciB4cj1uZXcgWG1sVGV4dFJlYWRlcihuZXcgU3RyaW5nUmVhZGVyKHhtbCkpOwogICAgICAgICAgICAgICAgd2hpbGUoeHIuUmVhZCgpKQogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIGlmICh4ci5Ob2RlVHlwZSA9PSBYbWxOb2RlVHlwZS5XaGl0ZXNwYWNlKSBjb250aW51ZTsKICAgICAgICAgICAgICAgICAgICBpZiAoeHIuTG9jYWxOYW1lICE9ICJjb2wiKSBicmVhazsKICAgICAgICAgICAgICAgICAgICBpZiAoeHIuTm9kZVR5cGUgPT0gWG1sTm9kZVR5cGUuRWxlbWVudCkKICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgIGludCBtaW4gPSBpbnQuUGFyc2UoeHIuR2V0QXR0cmlidXRlKCJtaW4iKSk7CgogICAgICAgICAgICAgICAgICAgICAgICBFeGNlbENvbHVtbiBjb2wgPSBuZXcgRXhjZWxDb2x1bW4odGhpcywgbWluKTsKCiAgICAgICAgICAgICAgICAgICAgICAgIGNvbC5Db2x1bW5NYXggPSBpbnQuUGFyc2UoeHIuR2V0QXR0cmlidXRlKCJtYXgiKSk7CiAgICAgICAgICAgICAgICAgICAgICAgIGNvbC5XaWR0aCA9IHhyLkdldEF0dHJpYnV0ZSgid2lkdGgiKSA9PSBudWxsID8gMCA6IGRvdWJsZS5QYXJzZSh4ci5HZXRBdHRyaWJ1dGUoIndpZHRoIiksIEN1bHR1cmVJbmZvLkludmFyaWFudEN1bHR1cmUpOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgY29sLkJlc3RGaXQgPSB4ci5HZXRBdHRyaWJ1dGUoImJlc3RGaXQiKSAhPSBudWxsICYmIHhyLkdldEF0dHJpYnV0ZSgiYmVzdEZpdCIpID09ICIxIiA/IHRydWUgOiBmYWxzZTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbC5Db2xsYXBzZWQgPSB4ci5HZXRBdHRyaWJ1dGUoImNvbGxhcHNlZCIpICE9IG51bGwgJiYgeHIuR2V0QXR0cmlidXRlKCJjb2xsYXBzZWQiKSA9PSAiMSIgPyB0cnVlIDogZmFsc2U7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb2wuUGhvbmV0aWMgPSB4ci5HZXRBdHRyaWJ1dGUoInBob25ldGljIikgIT0gbnVsbCAmJiB4ci5HZXRBdHRyaWJ1dGUoInBob25ldGljIikgPT0gIjEiID8gdHJ1ZSA6IGZhbHNlOwogICAgICAgICAgICAgICAgICAgICAgICBjb2wuT3V0bGluZUxldmVsID0gKHNob3J0KSh4ci5HZXRBdHRyaWJ1dGUoIm91dGxpbmVMZXZlbCIpID09IG51bGwgPyAwIDogaW50LlBhcnNlKHhyLkdldEF0dHJpYnV0ZSgib3V0bGluZUxldmVsIiksIEN1bHR1cmVJbmZvLkludmFyaWFudEN1bHR1cmUpKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbC5IaWRkZW4gPSB4ci5HZXRBdHRyaWJ1dGUoImhpZGRlbiIpICE9IG51bGwgJiYgeHIuR2V0QXR0cmlidXRlKCJoaWRkZW4iKSA9PSAiMSIgPyB0cnVlIDogZmFsc2U7CiAgICAgICAgICAgICAgICAgICAgICAgIF92YWx1ZXMuU2V0VmFsdWUoMCwgbWluLCBjb2wpOwogICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICBpbnQgc3R5bGU7CiAgICAgICAgICAgICAgICAgICAgICAgIGlmICghKHhyLkdldEF0dHJpYnV0ZSgic3R5bGUiKSA9PSBudWxsIHx8ICFpbnQuVHJ5UGFyc2UoeHIuR2V0QXR0cmlidXRlKCJzdHlsZSIpLCBvdXQgc3R5bGUpKSkKICAgICAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgX3N0eWxlcy5TZXRWYWx1ZSgwLCBtaW4sIHN0eWxlKTsKICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgIH0KICAgICAgICAvLy8gPHN1bW1hcnk+CiAgICAgICAgLy8vIFJlYWQgdW50aWwgdGhlIG5vZGUgaXMgZm91bmQuIElmIG5vdCBmb3VuZCB0aGUgeG1scmVhZGVyIGlzIHJlc2V0ZWQuCiAgICAgICAgLy8vIDwvc3VtbWFyeT4KICAgICAgICAvLy8gPHBhcmFtIG5hbWU9InhyIj5UaGUgcmVhZGVyPC9wYXJhbT4KICAgICAgICAvLy8gPHBhcmFtIG5hbWU9Im5vZGVUZXh0Ij5UZXh0IHRvIHNlYXJjaCBmb3I8L3BhcmFtPgogICAgICAgIC8vLyA8cGFyYW0gbmFtZT0iYWx0Tm9kZSI+QWx0ZXJuYXRpdmUgdGV4dCB0byBzZWFyY2ggZm9yPC9wYXJhbT4KICAgICAgICAvLy8gPHJldHVybnM+PC9yZXR1cm5zPgogICAgICAgIHByaXZhdGUgc3RhdGljIGJvb2wgUmVhZFhtbFJlYWRlclVudGlsKFhtbFRleHRSZWFkZXIgeHIsIHN0cmluZyBub2RlVGV4dCwgc3RyaW5nIGFsdE5vZGUpCiAgICAgICAgewogICAgICAgICAgICBkbwogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBpZiAoeHIuTG9jYWxOYW1lID09IG5vZGVUZXh0IHx8IHhyLkxvY2FsTmFtZSA9PSBhbHROb2RlKSByZXR1cm4gdHJ1ZTsKICAgICAgICAgICAgfQogICAgICAgICAgICB3aGlsZSh4ci5SZWFkKCkpOwogICAgICAgICAgICB4ci5DbG9zZSgpOwogICAgICAgICAgICByZXR1cm4gZmFsc2U7CiAgICAgICAgfQogICAgICAgIC8vLyA8c3VtbWFyeT4KICAgICAgICAvLy8gTG9hZCBIeXBlcmxpbmtzCiAgICAgICAgLy8vIDwvc3VtbWFyeT4KICAgICAgICAvLy8gPHBhcmFtIG5hbWU9InhyIj5UaGUgcmVhZGVyPC9wYXJhbT4KICAgICAgICBwcml2YXRlIHZvaWQgTG9hZEh5cGVyTGlua3MoWG1sVGV4dFJlYWRlciB4cikKICAgICAgICB7CiAgICAgICAgICAgIGlmICghUmVhZFVudGlsKHhyLCAiaHlwZXJsaW5rcyIsICJyb3dCcmVha3MiLCAiY29sQnJlYWtzIikpIHJldHVybjsKICAgICAgICAgICAgd2hpbGUgKHhyLlJlYWQoKSkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgaWYgKHhyLkxvY2FsTmFtZSA9PSAiaHlwZXJsaW5rIikKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICBpbnQgZnJvbVJvdywgZnJvbUNvbCwgdG9Sb3csIHRvQ29sOwogICAgICAgICAgICAgICAgICAgIEV4Y2VsQ2VsbEJhc2UuR2V0Um93Q29sRnJvbUFkZHJlc3MoeHIuR2V0QXR0cmlidXRlKCJyZWYiKSwgb3V0IGZyb21Sb3csIG91dCBmcm9tQ29sLCBvdXQgdG9Sb3csIG91dCB0b0NvbCk7CiAgICAgICAgICAgICAgICAgICAgRXhjZWxIeXBlckxpbmsgaGwgPSBudWxsOwogICAgICAgICAgICAgICAgICAgIGlmICh4ci5HZXRBdHRyaWJ1dGUoImlkIiwgRXhjZWxQYWNrYWdlLnNjaGVtYVJlbGF0aW9uc2hpcHMpICE9IG51bGwpCiAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICB2YXIgcklkID0geHIuR2V0QXR0cmlidXRlKCJpZCIsIEV4Y2VsUGFja2FnZS5zY2hlbWFSZWxhdGlvbnNoaXBzKTsKICAgICAgICAgICAgICAgICAgICAgICAgdmFyIHVyaSA9IFBhcnQuR2V0UmVsYXRpb25zaGlwKHJJZCkuVGFyZ2V0VXJpOwogICAgICAgICAgICAgICAgICAgICAgICBpZiAodXJpLklzQWJzb2x1dGVVcmkpCiAgICAgICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRyeQogICAgICAgICAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGhsID0gbmV3IEV4Y2VsSHlwZXJMaW5rKHVyaS5BYnNvbHV0ZVVyaSk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjYXRjaAogICAgICAgICAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGhsID0gbmV3IEV4Y2VsSHlwZXJMaW5rKHVyaS5PcmlnaW5hbFN0cmluZywgVXJpS2luZC5BYnNvbHV0ZSk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgZWxzZQogICAgICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBobCA9IG5ldyBFeGNlbEh5cGVyTGluayh1cmkuT3JpZ2luYWxTdHJpbmcsIFVyaUtpbmQuUmVsYXRpdmUpOwogICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgICAgIGhsLlJJZCA9IHJJZDsKICAgICAgICAgICAgICAgICAgICAgICAgUGFydC5EZWxldGVSZWxhdGlvbnNoaXAocklkKTsgLy9EZWxldGUgdGhlIHJlbGF0aW9uc2hpcCwgaXQgaXMgcmVjcmVhdGVkIHdoZW4gd2Ugc2F2ZSB0aGUgcGFja2FnZS4KICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgZWxzZSBpZiAoeHIuR2V0QXR0cmlidXRlKCJsb2NhdGlvbiIpICE9IG51bGwpCiAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICBobCA9IG5ldyBFeGNlbEh5cGVyTGluayh4ci5HZXRBdHRyaWJ1dGUoImxvY2F0aW9uIiksIHhyLkdldEF0dHJpYnV0ZSgiZGlzcGxheSIpKTsKICAgICAgICAgICAgICAgICAgICAgICAgaGwuUm93U3Bhbm4gPSB0b1JvdyAtIGZyb21Sb3c7CiAgICAgICAgICAgICAgICAgICAgICAgIGhsLkNvbFNwYW5uID0gdG9Db2wgLSBmcm9tQ29sOwogICAgICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICAgICAgc3RyaW5nIHR0ID0geHIuR2V0QXR0cmlidXRlKCJ0b29sdGlwIik7CiAgICAgICAgICAgICAgICAgICAgaWYgKCFzdHJpbmcuSXNOdWxsT3JFbXB0eSh0dCkpCiAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICBobC5Ub29sVGlwID0gdHQ7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIF9oeXBlckxpbmtzLlNldFZhbHVlKGZyb21Sb3csIGZyb21Db2wsIGhsKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGVsc2UKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgIH0KICAgICAgICAvLy8gPHN1bW1hcnk+CiAgICAgICAgLy8vIExvYWQgY2VsbHMKICAgICAgICAvLy8gPC9zdW1tYXJ5PgogICAgICAgIC8vLyA8cGFyYW0gbmFtZT0ieHIiPlRoZSByZWFkZXI8L3BhcmFtPgogICAgICAgIHByaXZhdGUgdm9pZCBMb2FkQ2VsbHMoWG1sVGV4dFJlYWRlciB4cikKICAgICAgICB7CiAgICAgICAgICAgIC8vdmFyIGNlbGxMaXN0PW5ldyBMaXN0PElSYW5nZUlEPigpOwogICAgICAgICAgICAvL3ZhciByb3dMaXN0ID0gbmV3IExpc3Q8SVJhbmdlSUQ+KCk7CiAgICAgICAgICAgIC8vdmFyIGZvcm11bGFMaXN0ID0gbmV3IExpc3Q8SVJhbmdlSUQ+KCk7CiAgICAgICAgICAgIFJlYWRVbnRpbCh4ciwgInNoZWV0RGF0YSIsICJtZXJnZUNlbGxzIiwgImh5cGVybGlua3MiLCAicm93QnJlYWtzIiwgImNvbEJyZWFrcyIpOwogICAgICAgICAgICBFeGNlbEFkZHJlc3NCYXNlIGFkZHJlc3M9bnVsbDsKICAgICAgICAgICAgc3RyaW5nIHR5cGU9IiI7CiAgICAgICAgICAgIGludCBzdHlsZT0wOwogICAgICAgICAgICBpbnQgcm93ID0gMDsKICAgICAgICAgICAgaW50IGNvbCA9IDA7CiAgICAgICAgICAgIHhyLlJlYWQoKTsKICAgICAgICAgICAgCiAgICAgICAgICAgIHdoaWxlICgheHIuRU9GKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICB3aGlsZSAoeHIuTm9kZVR5cGUgPT0gWG1sTm9kZVR5cGUuRW5kRWxlbWVudCkKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICB4ci5SZWFkKCk7CiAgICAgICAgICAgICAgICAgICAgY29udGludWU7CiAgICAgICAgICAgICAgICB9ICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgaWYgKHhyLkxvY2FsTmFtZSA9PSAicm93IikKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICB2YXIgciA9IHhyLkdldEF0dHJpYnV0ZSgiciIpOwogICAgICAgICAgICAgICAgICAgIGlmIChyID09IG51bGwpCiAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICByb3crKzsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgZWxzZQogICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgcm93ID0gQ29udmVydC5Ub0ludDMyKHIpOwogICAgICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICAgICAgaWYgKERvQWRkUm93KHhyKSkKICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgIF92YWx1ZXMuU2V0VmFsdWUocm93LCAwLCBBZGRSb3coeHIsIHJvdykpOwogICAgICAgICAgICAgICAgICAgICAgICBpZih4ci5HZXRBdHRyaWJ1dGUoInMiKSAhPSBudWxsKQogICAgICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBfc3R5bGVzLlNldFZhbHVlKHJvdywgMCwgaW50LlBhcnNlKHhyLkdldEF0dHJpYnV0ZSgicyIpLCBDdWx0dXJlSW5mby5JbnZhcmlhbnRDdWx0dXJlKSk7CiAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgeHIuUmVhZCgpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgZWxzZSBpZiAoeHIuTG9jYWxOYW1lID09ICJjIikKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAvL2lmIChjZWxsICE9IG51bGwpIGNlbGxMaXN0LkFkZChjZWxsKTsKICAgICAgICAgICAgICAgICAgICAvL2NlbGwgPSBuZXcgRXhjZWxDZWxsKHRoaXMsIHhyLkdldEF0dHJpYnV0ZSgiciIpKTsKICAgICAgICAgICAgICAgICAgICB2YXIgciA9IHhyLkdldEF0dHJpYnV0ZSgiciIpOwogICAgICAgICAgICAgICAgICAgIGlmIChyID09IG51bGwpCiAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICAvL0hhbmRsZSBjZWxscyB3aXRoIG5vIHJlZmVyZW5jZQogICAgICAgICAgICAgICAgICAgICAgICBjb2wrKzsKICAgICAgICAgICAgICAgICAgICAgICAgYWRkcmVzcyA9IG5ldyBFeGNlbEFkZHJlc3NCYXNlKHJvdywgY29sLCByb3csIGNvbCk7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIGVsc2UKICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgIGFkZHJlc3MgPSBuZXcgRXhjZWxBZGRyZXNzQmFzZShyKTsKICAgICAgICAgICAgICAgICAgICAgICAgY29sID0gYWRkcmVzcy5fZnJvbUNvbDsKICAgICAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgIC8vRGF0ZXR5cGUKICAgICAgICAgICAgICAgICAgICBpZiAoeHIuR2V0QXR0cmlidXRlKCJ0IikgIT0gbnVsbCkKICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgIHR5cGU9eHIuR2V0QXR0cmlidXRlKCJ0Iik7CiAgICAgICAgICAgICAgICAgICAgICAgIF90eXBlcy5TZXRWYWx1ZShhZGRyZXNzLl9mcm9tUm93LCBhZGRyZXNzLl9mcm9tQ29sLCB0eXBlKTsgCiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIGVsc2UKICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgIHR5cGU9IiI7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIC8vU3R5bGUKICAgICAgICAgICAgICAgICAgICBpZih4ci5HZXRBdHRyaWJ1dGUoInMiKSAhPSBudWxsKQogICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgc3R5bGU9aW50LlBhcnNlKHhyLkdldEF0dHJpYnV0ZSgicyIpKTsKICAgICAgICAgICAgICAgICAgICAgICAgX3N0eWxlcy5TZXRWYWx1ZShhZGRyZXNzLl9mcm9tUm93LCBhZGRyZXNzLl9mcm9tQ29sLCBzdHlsZSk7CiAgICAgICAgICAgICAgICAgICAgICAgIF92YWx1ZXMuU2V0VmFsdWUoYWRkcmVzcy5fZnJvbVJvdywgYWRkcmVzcy5fZnJvbUNvbCwgbnVsbCk7IC8vVE9ETzpCZXR0ZXIgUGVyZm9ybWFuY2UgPz8KICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgZWxzZQogICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgc3R5bGUgPSAwOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICB4ci5SZWFkKCk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBlbHNlIGlmICh4ci5Mb2NhbE5hbWUgPT0gInYiKQogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIFNldFZhbHVlRnJvbVhtbCh4ciwgdHlwZSwgc3R5bGUsIGFkZHJlc3MuX2Zyb21Sb3csIGFkZHJlc3MuX2Zyb21Db2wpOwogICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgIHhyLlJlYWQoKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGVsc2UgaWYgKHhyLkxvY2FsTmFtZSA9PSAiZiIpCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgc3RyaW5nIHQgPSB4ci5HZXRBdHRyaWJ1dGUoInQiKTsKICAgICAgICAgICAgICAgICAgICBpZiAodCA9PSBudWxsKQogICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgX2Zvcm11bGFzLlNldFZhbHVlKGFkZHJlc3MuX2Zyb21Sb3csIGFkZHJlc3MuX2Zyb21Db2wsIHhyLlJlYWRFbGVtZW50Q29udGVudEFzU3RyaW5nKCkpOwogICAgICAgICAgICAgICAgICAgICAgICBfdmFsdWVzLlNldFZhbHVlKGFkZHJlc3MuX2Zyb21Sb3csIGFkZHJlc3MuX2Zyb21Db2wsIG51bGwpOwogICAgICAgICAgICAgICAgICAgICAgICAvL2Zvcm11bGFMaXN0LkFkZChjZWxsKTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgZWxzZSBpZiAodCA9PSAic2hhcmVkIikKICAgICAgICAgICAgICAgICAgICB7CgogICAgICAgICAgICAgICAgICAgICAgICBzdHJpbmcgc2kgPSB4ci5HZXRBdHRyaWJ1dGUoInNpIik7CiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChzaSAhPSBudWxsKQogICAgICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICB2YXIgc2ZJbmRleCA9IGludC5QYXJzZShzaSk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBfZm9ybXVsYXMuU2V0VmFsdWUoYWRkcmVzcy5fZnJvbVJvdywgYWRkcmVzcy5fZnJvbUNvbCwgc2ZJbmRleCk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBfdmFsdWVzLlNldFZhbHVlKGFkZHJlc3MuX2Zyb21Sb3csIGFkZHJlc3MuX2Zyb21Db2wsIG51bGwpOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgc3RyaW5nIGZBZGRyZXNzID0geHIuR2V0QXR0cmlidXRlKCJyZWYiKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN0cmluZyBmb3JtdWxhID0gQ29udmVydFV0aWwuRXhjZWxEZWNvZGVTdHJpbmcoeHIuUmVhZEVsZW1lbnRDb250ZW50QXNTdHJpbmcoKSk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoZm9ybXVsYSAhPSAiIikKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBfc2hhcmVkRm9ybXVsYXMuQWRkKHNmSW5kZXgsIG5ldyBGb3JtdWxhcyhTb3VyY2VDb2RlVG9rZW5pemVyLkRlZmF1bHQpIHsgSW5kZXggPSBzZkluZGV4LCBGb3JtdWxhID0gZm9ybXVsYSwgQWRkcmVzcyA9IGZBZGRyZXNzLCBTdGFydFJvdyA9IGFkZHJlc3MuX2Zyb21Sb3csIFN0YXJ0Q29sID0gYWRkcmVzcy5fZnJvbUNvbCB9KTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICAgICBlbHNlCiAgICAgICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHhyLlJlYWQoKTsgIC8vU29tZXRoaW5nIGlzIHdyb25nIGluIHRoZSBzaGVldCwgcmVhZCBuZXh0CiAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgZWxzZSBpZiAodCA9PSAiYXJyYXkiKSAvL1RPRE86IEFycmF5IGZ1bmN0aW9ucyBhcmUgbm90IHN1cHBvcnQgeWV0LiBSZWFkIHRoZSBmb3JtdWxhIGZvciB0aGUgc3RhcnQgY2VsbCBvbmx5LgogICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgc3RyaW5nIGFBZGRyZXNzID0geHIuR2V0QXR0cmlidXRlKCJyZWYiKTsKICAgICAgICAgICAgICAgICAgICAgICAgRXhjZWxSYW5nZSBhZGRyZXNzUmFuZ2UgPSBuZXcgRXhjZWxSYW5nZSh0aGlzLCBhQWRkcmVzcyk7ICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICBzdHJpbmcgZm9ybXVsYSA9IHhyLlJlYWRFbGVtZW50Q29udGVudEFzU3RyaW5nKCk7CiAgICAgICAgICAgICAgICAgICAgICAgIGJvb2wgaXNJbmRleE1hdGNoRm9ybXVsYSA9IFJlZ2V4LklzTWF0Y2goZm9ybXVsYSwgQCJJTkRFWFwoIiwgUmVnZXhPcHRpb25zLklnbm9yZUNhc2UpICYmIFJlZ2V4LklzTWF0Y2goZm9ybXVsYSwgQCJNQVRDSFwoIiwgUmVnZXhPcHRpb25zLklnbm9yZUNhc2UpICYmICFhQWRkcmVzcy5Db250YWlucygiOiIpOwogICAgICAgICAgICAgICAgICAgICAgICBpZiAoaXNJbmRleE1hdGNoRm9ybXVsYSkKICAgICAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgYWRkcmVzc1JhbmdlLklzQXJyYXlGb3JtdWxhID0gZmFsc2U7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBmb3IgKGludCBjb2xJbmRleCA9IGFkZHJlc3NSYW5nZS5TdGFydC5Db2x1bW47IGNvbEluZGV4IDw9IGFkZHJlc3NSYW5nZS5FbmQuQ29sdW1uOyBjb2xJbmRleCsrKQogICAgICAgICAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZvciAoaW50IHJvd0luZGV4ID0gYWRkcmVzc1JhbmdlLlN0YXJ0LlJvdzsgcm93SW5kZXggPD0gYWRkcmVzc1JhbmdlLkVuZC5Sb3c7IHJvd0luZGV4KyspCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB2YXIgYWZJbmRleCA9IEdldE1heFNoYXJlRnVuY3Rpb25JbmRleCh0cnVlKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgX2Zvcm11bGFzLlNldFZhbHVlKHJvd0luZGV4LCBjb2xJbmRleCwgYWZJbmRleCk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIF92YWx1ZXMuU2V0VmFsdWUocm93SW5kZXgsIGNvbEluZGV4LCBudWxsKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgX3NoYXJlZEZvcm11bGFzLkFkZChhZkluZGV4LCBuZXcgRm9ybXVsYXMoU291cmNlQ29kZVRva2VuaXplci5EZWZhdWx0KSB7IEluZGV4ID0gYWZJbmRleCwgRm9ybXVsYSA9IGZvcm11bGEsIEFkZHJlc3MgPSBhQWRkcmVzcywgU3RhcnRSb3cgPSBhZGRyZXNzLl9mcm9tUm93LCBTdGFydENvbCA9IGFkZHJlc3MuX2Zyb21Db2wsIElzQXJyYXkgPSBmYWxzZSB9KTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgZWxzZQogICAgICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBhZGRyZXNzUmFuZ2UuSXNBcnJheUZvcm11bGEgPSB0cnVlOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgdmFyIGFmSW5kZXggPSBHZXRNYXhTaGFyZUZ1bmN0aW9uSW5kZXgodHJ1ZSk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBmb3IgKGludCBjb2xJbmRleCA9IGFkZHJlc3NSYW5nZS5TdGFydC5Db2x1bW47IGNvbEluZGV4IDw9IGFkZHJlc3NSYW5nZS5FbmQuQ29sdW1uOyBjb2xJbmRleCsrKQogICAgICAgICAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZvciAoaW50IHJvd0luZGV4ID0gYWRkcmVzc1JhbmdlLlN0YXJ0LlJvdzsgcm93SW5kZXggPD0gYWRkcmVzc1JhbmdlLkVuZC5Sb3c7IHJvd0luZGV4KyspCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBfZm9ybXVsYXMuU2V0VmFsdWUocm93SW5kZXgsIGNvbEluZGV4LCBhZkluZGV4KTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgX3ZhbHVlcy5TZXRWYWx1ZShyb3dJbmRleCwgY29sSW5kZXgsIG51bGwpOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgICAgIF9zaGFyZWRGb3JtdWxhcy5BZGQoYWZJbmRleCwgbmV3IEZvcm11bGFzKFNvdXJjZUNvZGVUb2tlbml6ZXIuRGVmYXVsdCkgeyBJbmRleCA9IGFmSW5kZXgsIEZvcm11bGEgPSBmb3JtdWxhLCBBZGRyZXNzID0gYUFkZHJlc3MsIFN0YXJ0Um93ID0gYWRkcmVzcy5fZnJvbVJvdywgU3RhcnRDb2wgPSBhZGRyZXNzLl9mcm9tQ29sLCBJc0FycmF5ID0gdHJ1ZSB9KTsKICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICBlbHNlIC8vID8/PyBzb21lIG90aGVyIHR5cGUKICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgIHhyLlJlYWQoKTsgIC8vU29tZXRoaW5nIGlzIHdyb25nIGluIHRoZSBzaGVldCwgcmVhZCBuZXh0CiAgICAgICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGVsc2UgaWYgKHhyLkxvY2FsTmFtZSA9PSAiaXMiKSAgIC8vSW5saW5lIHN0cmluZwogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIHhyLlJlYWQoKTsKICAgICAgICAgICAgICAgICAgICBpZiAoeHIuTG9jYWxOYW1lID09ICJ0IikKICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgIF92YWx1ZXMuU2V0VmFsdWUoYWRkcmVzcy5fZnJvbVJvdywgYWRkcmVzcy5fZnJvbUNvbCwgQ29udmVydFV0aWwuRXhjZWxEZWNvZGVTdHJpbmcoeHIuUmVhZEVsZW1lbnRDb250ZW50QXNTdHJpbmcoKSkpOwogICAgICAgICAgICAgICAgICAgICAgICAvL2NlbGwuX3ZhbHVlID0geHIuUmVhZElubmVyWG1sKCk7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIGVsc2UKICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgIF92YWx1ZXMuU2V0VmFsdWUoYWRkcmVzcy5fZnJvbVJvdywgYWRkcmVzcy5fZnJvbUNvbCwgeHIuUmVhZE91dGVyWG1sKCkpOwogICAgICAgICAgICAgICAgICAgICAgICBfdHlwZXMuU2V0VmFsdWUoYWRkcmVzcy5fZnJvbVJvdywgYWRkcmVzcy5fZnJvbUNvbCwgInJ0Iik7CiAgICAgICAgICAgICAgICAgICAgICAgIF9mbGFncy5TZXRGbGFnVmFsdWUoYWRkcmVzcy5fZnJvbVJvdywgYWRkcmVzcy5fZnJvbUNvbCwgdHJ1ZSwgQ2VsbEZsYWdzLlJpY2hUZXh0KTsKICAgICAgICAgICAgICAgICAgICAgICAgLy9jZWxsLklzUmljaFRleHQgPSB0cnVlOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGVsc2UKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgICAgICAvL2lmIChjZWxsICE9IG51bGwpIGNlbGxMaXN0LkFkZChjZWxsKTsKCiAgICAgICAgICAgIC8vX2NlbGxzID0gbmV3IFJhbmdlQ29sbGVjdGlvbihjZWxsTGlzdCk7CiAgICAgICAgICAgIC8vX3Jvd3MgPSBuZXcgUmFuZ2VDb2xsZWN0aW9uKHJvd0xpc3QpOwogICAgICAgICAgICAvL19mb3JtdWxhQ2VsbHMgPSBuZXcgUmFuZ2VDb2xsZWN0aW9uKGZvcm11bGFMaXN0KTsKICAgICAgICB9CgogICAgICAgIHByaXZhdGUgYm9vbCBEb0FkZFJvdyhYbWxUZXh0UmVhZGVyIHhyKQogICAgICAgIHsKICAgICAgICAgICAgdmFyIGMgPSB4ci5HZXRBdHRyaWJ1dGUoInIiKT09bnVsbCA/IDA6MTsKICAgICAgICAgICAgaWYgKHhyLkdldEF0dHJpYnV0ZSgic3BhbnMiKSAhPSBudWxsKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBjKys7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgcmV0dXJuIHhyLkF0dHJpYnV0ZUNvdW50ID4gYzsKICAgICAgICB9CiAgICAgICAgLy8vIDxzdW1tYXJ5PgogICAgICAgIC8vLyBMb2FkIG1lcmdlZCBjZWxscwogICAgICAgIC8vLyA8L3N1bW1hcnk+CiAgICAgICAgLy8vIDxwYXJhbSBuYW1lPSJ4ciI+PC9wYXJhbT4KICAgICAgICBwcml2YXRlIHZvaWQgTG9hZE1lcmdlQ2VsbHMoWG1sVGV4dFJlYWRlciB4cikKICAgICAgICB7CiAgICAgICAgICAgIGlmKFJlYWRVbnRpbCh4ciwgIm1lcmdlQ2VsbHMiLCAiaHlwZXJsaW5rcyIsICJyb3dCcmVha3MiLCAiY29sQnJlYWtzIikgJiYgIXhyLkVPRikKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgd2hpbGUgKHhyLlJlYWQoKSkKICAgICAgICAgICAgICAgIHsgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgIGlmICh4ci5Mb2NhbE5hbWUgIT0gIm1lcmdlQ2VsbCIpIGJyZWFrOwogICAgICAgICAgICAgICAgICAgIGlmICh4ci5Ob2RlVHlwZSA9PSBYbWxOb2RlVHlwZS5FbGVtZW50KQogICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgc3RyaW5nIGFkZHJlc3MgPSB4ci5HZXRBdHRyaWJ1dGUoInJlZiIpOwogICAgICAgICAgICAgICAgICAgICAgICAvL2ludCBmcm9tUm93LCBmcm9tQ29sLCB0b1JvdywgdG9Db2w7CiAgICAgICAgICAgICAgICAgICAgICAgIC8vRXhjZWxDZWxsQmFzZS5HZXRSb3dDb2xGcm9tQWRkcmVzcyhhZGRyZXNzLCBvdXQgZnJvbVJvdywgb3V0IGZyb21Db2wsIG91dCB0b1Jvdywgb3V0IHRvQ29sKTsKICAgICAgICAgICAgICAgICAgICAgICAgLy9mb3IgKGludCByb3cgPSBmcm9tUm93OyByb3cgPD0gdG9Sb3c7IHJvdysrKQogICAgICAgICAgICAgICAgICAgICAgICAvL3sKICAgICAgICAgICAgICAgICAgICAgICAgLy8gICAgZm9yIChpbnQgY29sID0gZnJvbUNvbDsgY29sIDw9IHRvQ29sOyBjb2wrKykKICAgICAgICAgICAgICAgICAgICAgICAgLy8gICAgewogICAgICAgICAgICAgICAgICAgICAgICAvLyAgICAgICAgX2ZsYWdzLlNldEZsYWdWYWx1ZShyb3csIGNvbCwgdHJ1ZSxDZWxsRmxhZ3MuTWVyZ2VkKTsKICAgICAgICAgICAgICAgICAgICAgICAgLy8gICAgfQogICAgICAgICAgICAgICAgICAgICAgICAvL30KICAgICAgICAgICAgICAgICAgICAgICAgLy9fbWVyZ2VkQ2VsbHMuTGlzdC5BZGQoYWRkcmVzcyk7CiAgICAgICAgICAgICAgICAgICAgICAgIF9tZXJnZWRDZWxscy5BZGQobmV3IEV4Y2VsQWRkcmVzcyhhZGRyZXNzKSwgZmFsc2UpOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgIH0KICAgICAgICAvLy8gPHN1bW1hcnk+CiAgICAgICAgLy8vIFVwZGF0ZSBtZXJnZWQgY2VsbHMKICAgICAgICAvLy8gPC9zdW1tYXJ5PgogICAgICAgIC8vLyA8cGFyYW0gbmFtZT0ic3ciPlRoZSB3cml0ZXI8L3BhcmFtPgogICAgICAgIHByaXZhdGUgdm9pZCBVcGRhdGVNZXJnZWRDZWxscyhTdHJlYW1Xcml0ZXIgc3cpCiAgICAgICAgewogICAgICAgICAgICBzdy5Xcml0ZSgiPG1lcmdlQ2VsbHM+Iik7CiAgICAgICAgICAgIGZvcmVhY2ggKHN0cmluZyBhZGRyZXNzIGluIF9tZXJnZWRDZWxscykKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgc3cuV3JpdGUoIjxtZXJnZUNlbGwgcmVmPVwiezB9XCIgLz4iLCBhZGRyZXNzKTsKICAgICAgICAgICAgfQogICAgICAgICAgICBzdy5Xcml0ZSgiPC9tZXJnZUNlbGxzPiIpOwogICAgICAgIH0KICAgICAgICAvLy8gPHN1bW1hcnk+CiAgICAgICAgLy8vIFJlYWRzIGEgcm93IGZyb20gdGhlIFhNTCByZWFkZXIKICAgICAgICAvLy8gPC9zdW1tYXJ5PgogICAgICAgIC8vLyA8cGFyYW0gbmFtZT0ieHIiPlRoZSByZWFkZXI8L3BhcmFtPgogICAgICAgIC8vLyA8cGFyYW0gbmFtZT0icm93Ij5UaGUgcm93IG51bWJlcjwvcGFyYW0+CiAgICAgICAgLy8vIDxyZXR1cm5zPjwvcmV0dXJucz4KICAgICAgICBwcml2YXRlIFJvd0ludGVybmFsIEFkZFJvdyhYbWxUZXh0UmVhZGVyIHhyLCBpbnQgcm93KQogICAgICAgIHsKICAgICAgICAgICAgcmV0dXJuIG5ldyBSb3dJbnRlcm5hbCgpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIENvbGxhcHNlZD0oeHIuR2V0QXR0cmlidXRlKCJjb2xsYXBzZWQiKSAhPSBudWxsICYmIHhyLkdldEF0dHJpYnV0ZSgiY29sbGFwc2VkIik9PSAiMSIgPyB0cnVlIDogZmFsc2UpLAogICAgICAgICAgICAgICAgT3V0bGluZUxldmVsID0gKHhyLkdldEF0dHJpYnV0ZSgib3V0bGluZUxldmVsIikgPT0gbnVsbCA/IChzaG9ydCkwIDogc2hvcnQuUGFyc2UoeHIuR2V0QXR0cmlidXRlKCJvdXRsaW5lTGV2ZWwiKSwgQ3VsdHVyZUluZm8uSW52YXJpYW50Q3VsdHVyZSkpLAogICAgICAgICAgICAgICAgSGVpZ2h0ID0gKHhyLkdldEF0dHJpYnV0ZSgiaHQiKSA9PSBudWxsID8gLTEgOiBkb3VibGUuUGFyc2UoeHIuR2V0QXR0cmlidXRlKCJodCIpLCBDdWx0dXJlSW5mby5JbnZhcmlhbnRDdWx0dXJlKSksCiAgICAgICAgICAgICAgICBIaWRkZW4gPSAoeHIuR2V0QXR0cmlidXRlKCJoaWRkZW4iKSAhPSBudWxsICYmIHhyLkdldEF0dHJpYnV0ZSgiaGlkZGVuIikgPT0gIjEiID8gdHJ1ZSA6IGZhbHNlKSwKICAgICAgICAgICAgICAgIFBob25ldGljID0geHIuR2V0QXR0cmlidXRlKCJwaCIpICE9IG51bGwgJiYgeHIuR2V0QXR0cmlidXRlKCJwaCIpID09ICIxIiA/IHRydWUgOiBmYWxzZSwKICAgICAgICAgICAgICAgIEN1c3RvbUhlaWdodCA9IHhyLkdldEF0dHJpYnV0ZSgiY3VzdG9tSGVpZ2h0IikgPT0gbnVsbCA/IGZhbHNlIDogeHIuR2V0QXR0cmlidXRlKCJjdXN0b21IZWlnaHQiKT09IjEiCiAgICAgICAgICAgIH07CiAgICAgICAgfQoKICAgICAgICBwcml2YXRlIERhdGVUaW1lIER1cmF0aW9uRnJvbU9BRGF0ZShkb3VibGUgdmFsdWUpCiAgICAgICAgewogICAgICAgICAgICAvLyBDb252ZXJ0IHRoZSBEdXJhdGlvbiB2YWx1ZSBpbnRvIHRoZSBjb3JyZXNwb25kaW5nIERhdGVUaW1lIHZhbHVlLgogICAgICAgICAgICAvLyBUaGUgRHVyYXRpb24gdmFsdWUgaXMgcGFzc2VkIGluIGFzIGEgZnJhY3Rpb25hbCBPZmZpY2UgQXV0b21hdGlvbiBkb3VibGUgdmFsdWVzIHdoZXJlIHRoZSAKICAgICAgICAgICAgLy8gd2hvbGUgcG9ydGlvbiBpcyB0aGUgbnVtYmVyIG9mIGRheXMgYW5kIHRoZSBmcmFjdGlvbmFsIHBvcnRpb24gb2YgdGhlIG51bWJlciBpcyB0aGUgaG91cnMuCiAgICAgICAgICAgIC8vIEZvciBleGFtcGxlLCB0aGUgRHVyYXRpb24gdmFsdWUgLTEuNSByZXByZXNlbnRzIGEgbmVnYXRpdmUgZHVyYXRpb24gb2Ygb25lIGRheSBhbmQgMTIgaG91cnMuCiAgICAgICAgICAgIC8vIFdlIHVzZSB0aGlzIHRlY2huaXF1ZSByYXRoZXIgdGhhbiBjYWxsaW5nIHRoZSAnRGF0ZVRpbWUuRnJvbU9BRGF0ZSgpJyBtZXRob2QsIGJlY2F1c2UKICAgICAgICAgICAgLy8gdGhpcyB0ZWNobmlxdWUgd29ya3MgZm9yIGJvdGggcG9zaXRpdmUgYW5kIG5lZ2F0aXZlIGR1cmF0aW9uIHZhbHVlcy4gdW5saWtlICdEYXRlVGltZS5Gcm9tT0FEYXRlKCknCiAgICAgICAgICAgIC8vIHdoaWNoIHlpZWxkcyB0aGUgd3JvbmcgcmVzdWx0IGZvciBuZWdhdGl2ZSBEdXJhdGlvbiB2YWx1ZXMuCiAgICAgICAgICAgIHJldHVybiBuZXcgRGF0ZVRpbWUoMTg5OSwgMTIsIDMwKSArIFRpbWVTcGFuLkZyb21EYXlzKHZhbHVlKTsKICAgICAgICB9CgogICAgICAgIHByaXZhdGUgdm9pZCBTZXRWYWx1ZUZyb21YbWwoWG1sVGV4dFJlYWRlciB4ciwgc3RyaW5nIHR5cGUsIGludCBzdHlsZUlELCBpbnQgcm93LCBpbnQgY29sKQogICAgICAgIHsKICAgICAgICAgICAgLy9YbWxOb2RlIHZub2RlID0gY29sTm9kZS5TZWxlY3RTaW5nbGVOb2RlKCJkOnYiLCBOYW1lU3BhY2VNYW5hZ2VyKTsKICAgICAgICAgICAgLy9pZiAodm5vZGUgPT0gbnVsbCkgcmV0dXJuIG51bGw7CiAgICAgICAgICAgIGlmICh0eXBlID09ICJzIikKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgaW50IGl4ID0geHIuUmVhZEVsZW1lbnRDb250ZW50QXNJbnQoKTsKCiAgICAgICAgICAgICAgICAvLyBUZW1wb3JhcnkgZGVidWdnaW5nIGNvZGUgdG8gbG9jYXRlIGludGVybWl0dGVudCAnSW5kZXggd2FzIG91dCBvZiByYW5nZScgZXhjZXB0aW9uLgogICAgICAgICAgICAgICAgaWYgKGl4IDwgMCkKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICB0aHJvdyBuZXcgRXhjZXB0aW9uKHN0cmluZy5Gb3JtYXQoIlJlYWRFbGVtZW50Q29udGVudEFzSW50IHJldHVybmVkIHZhbHVlICd7MH0nIHdoaWNoIGlzIGxlc3MgdGhhbiB6ZXJvLiIsIGl4KSk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBpZiAoaXggPj0gX3BhY2thZ2UuV29ya2Jvb2suX3NoYXJlZFN0cmluZ3NMaXN0LkNvdW50KQogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIHRocm93IG5ldyBFeGNlcHRpb24oc3RyaW5nLkZvcm1hdCgiUmVhZEVsZW1lbnRDb250ZW50QXNJbnQgcmV0dXJuZWQgaW5kZXggdmFsdWUgJ3swfScgd2hpY2ggaXMgZ3JlYXRlciB0aGFuIF9zaGFyZWRTdHJpbmdzTGlzdCBjb3VudCBvZiB7MX0uIiwgaXgsIF9wYWNrYWdlLldvcmtib29rLl9zaGFyZWRTdHJpbmdzTGlzdC5Db3VudCkpOwogICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgIF92YWx1ZXMuU2V0VmFsdWUocm93LCBjb2wsIF9wYWNrYWdlLldvcmtib29rLl9zaGFyZWRTdHJpbmdzTGlzdFtpeF0uVGV4dCk7CiAgICAgICAgICAgICAgICBpZiAoX3BhY2thZ2UuV29ya2Jvb2suX3NoYXJlZFN0cmluZ3NMaXN0W2l4XS5pc1JpY2hUZXh0KQogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIF9mbGFncy5TZXRGbGFnVmFsdWUocm93LCBjb2wsIHRydWUsIENlbGxGbGFncy5SaWNoVGV4dCk7CiAgICAgICAgICAgICAgICB9ICAgICAgICAgICAgICAgIAogICAgICAgICAgICB9CiAgICAgICAgICAgIGVsc2UgaWYgKHR5cGUgPT0gInN0ciIpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIF92YWx1ZXMuU2V0VmFsdWUocm93LCBjb2wsIENvbnZlcnRVdGlsLkV4Y2VsRGVjb2RlU3RyaW5nKHhyLlJlYWRFbGVtZW50Q29udGVudEFzU3RyaW5nKCkpKTsKICAgICAgICAgICAgfQogICAgICAgICAgICBlbHNlIGlmICh0eXBlID09ICJiIikKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgX3ZhbHVlcy5TZXRWYWx1ZShyb3csIGNvbCwgKHhyLlJlYWRFbGVtZW50Q29udGVudEFzU3RyaW5nKCkhPSIwIikpOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGVsc2UgaWYgKHR5cGUgPT0gImUiKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBfdmFsdWVzLlNldFZhbHVlKHJvdywgY29sLCBHZXRFcnJvclR5cGUoeHIuUmVhZEVsZW1lbnRDb250ZW50QXNTdHJpbmcoKSkpOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGVsc2UKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgc3RyaW5nIHYgPSB4ci5SZWFkRWxlbWVudENvbnRlbnRBc1N0cmluZygpOwogICAgICAgICAgICAgICAgdmFyIG5mID0gV29ya2Jvb2suU3R5bGVzLkNlbGxYZnNbc3R5bGVJRF0uTnVtYmVyRm9ybWF0SWQ7CiAgICAgICAgICAgICAgICBpZiAoKG5mID49IDIwICYmIG5mIDw9IDIxKSB8fCAobmYgPj0gNDUgJiYgbmYgPD0gNDcpKSAgLy8gRHVyYXRpb24KICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICBkb3VibGUgcmVzOwogICAgICAgICAgICAgICAgICAgIGlmIChkb3VibGUuVHJ5UGFyc2UodiwgTnVtYmVyU3R5bGVzLkFueSwgQ3VsdHVyZUluZm8uSW52YXJpYW50Q3VsdHVyZSwgb3V0IHJlcykpCiAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICBpZiAoV29ya2Jvb2suRGF0ZTE5MDQpCiAgICAgICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlcyArPSBFeGNlbFdvcmtib29rLmRhdGUxOTA0T2Zmc2V0OwogICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChyZXMgPj0gLTY1NzQzNS4wICYmIHJlcyA8IDI5NTg0NjUuOTk5OTk5OSkKICAgICAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gR2V0IHRoZSBEdXJhdGlvbiB2YWx1ZSBleHByZXNzZWQgYXMgYSBEYXRlVGltZS4KICAgICAgICAgICAgICAgICAgICAgICAgICAgIF92YWx1ZXMuU2V0VmFsdWUocm93LCBjb2wsIER1cmF0aW9uRnJvbU9BRGF0ZShyZXMpKTsKICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICAgICBlbHNlCiAgICAgICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIF92YWx1ZXMuU2V0VmFsdWUocm93LCBjb2wsICIiKTsKICAgICAgICAgICAgICAgICAgICAgICAgfSAKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgZWxzZQogICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgX3ZhbHVlcy5TZXRWYWx1ZShyb3csIGNvbCwgIiIpOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGVsc2UgaWYgKChuZiA+PSAxNCAmJiBuZiA8PSAxOSkgfHwgKG5mID09IDIyKSkgICAvLyBEYXRlVGltZQogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIGRvdWJsZSByZXM7CiAgICAgICAgICAgICAgICAgICAgaWYgKGRvdWJsZS5UcnlQYXJzZSh2LCBOdW1iZXJTdHlsZXMuQW55LCBDdWx0dXJlSW5mby5JbnZhcmlhbnRDdWx0dXJlLCBvdXQgcmVzKSkKICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChXb3JrYm9vay5EYXRlMTkwNCkKICAgICAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVzICs9IEV4Y2VsV29ya2Jvb2suZGF0ZTE5MDRPZmZzZXQ7CiAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHJlcyA+PSAtNjU3NDM1LjAgJiYgcmVzIDwgMjk1ODQ2NS45OTk5OTk5KQogICAgICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBfdmFsdWVzLlNldFZhbHVlKHJvdywgY29sLCBEYXRlVGltZS5Gcm9tT0FEYXRlKHJlcykpOwogICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgICAgIGVsc2UKICAgICAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgX3ZhbHVlcy5TZXRWYWx1ZShyb3csIGNvbCwgIiIpOwogICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIGVsc2UKICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgIF92YWx1ZXMuU2V0VmFsdWUocm93LCBjb2wsICIiKTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBlbHNlCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgZG91YmxlIGQ7CiAgICAgICAgICAgICAgICAgICAgaWYgKGRvdWJsZS5UcnlQYXJzZSh2LCBOdW1iZXJTdHlsZXMuQW55LCBDdWx0dXJlSW5mby5JbnZhcmlhbnRDdWx0dXJlLCBvdXQgZCkpCiAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICBfdmFsdWVzLlNldFZhbHVlKHJvdywgY29sLCBkKTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgZWxzZQogICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgX3ZhbHVlcy5TZXRWYWx1ZShyb3csIGNvbCwgZG91YmxlLk5hTik7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICBwcml2YXRlIG9iamVjdCBHZXRFcnJvclR5cGUoc3RyaW5nIHYpCiAgICAgICAgewogICAgICAgICAgICByZXR1cm4gRXhjZWxFcnJvclZhbHVlLlBhcnNlKHYuVG9VcHBlcihDdWx0dXJlSW5mby5JbnZhcmlhbnRDdWx0dXJlKSk7CiAgICAgICAgICAgIC8vc3dpdGNoKHYuVG9VcHBlcigpKQogICAgICAgICAgICAvL3sKICAgICAgICAgICAgLy8gICAgY2FzZSAiI0RJVi8wISI6CiAgICAgICAgICAgIC8vICAgICAgICByZXR1cm4gbmV3IEV4Y2VsRXJyb3JWYWx1ZS5jcmUoZUVycm9yVHlwZS5EaXYwKTsKICAgICAgICAgICAgLy8gICAgY2FzZSAiI1JFRiEiOgogICAgICAgICAgICAvLyAgICAgICAgcmV0dXJuIG5ldyBFeGNlbEVycm9yVmFsdWUoZUVycm9yVHlwZS5SZWYpOwogICAgICAgICAgICAvLyAgICBjYXNlICIjTi9BIjoKICAgICAgICAgICAgLy8gICAgICAgIHJldHVybiBuZXcgRXhjZWxFcnJvclZhbHVlKGVFcnJvclR5cGUuTkEpOwogICAgICAgICAgICAvLyAgICBjYXNlICIjTkFNRT8iOgogICAgICAgICAgICAvLyAgICAgICAgcmV0dXJuIG5ldyBFeGNlbEVycm9yVmFsdWUoZUVycm9yVHlwZS5OYW1lKTsKICAgICAgICAgICAgLy8gICAgY2FzZSAiI05VTEwhIjoKICAgICAgICAgICAgLy8gICAgICAgIHJldHVybiBuZXcgRXhjZWxFcnJvclZhbHVlKGVFcnJvclR5cGUuTnVsbCk7CiAgICAgICAgICAgIC8vICAgIGNhc2UgIiNOVU0hIjoKICAgICAgICAgICAgLy8gICAgICAgIHJldHVybiBuZXcgRXhjZWxFcnJvclZhbHVlKGVFcnJvclR5cGUuTnVtKTsKICAgICAgICAgICAgLy8gICAgZGVmYXVsdDoKICAgICAgICAgICAgLy8gICAgICAgIHJldHVybiBuZXcgRXhjZWxFcnJvclZhbHVlKGVFcnJvclR5cGUuVmFsdWUpOwogICAgICAgICAgICAvL30KICAgICAgICB9CiAgICAgICAgLy9wcml2YXRlIHN0cmluZyBHZXRTaGFyZWRTdHJpbmcoaW50IHN0cmluZ0lEKQogICAgICAgIC8vewogICAgICAgIC8vICAgIHN0cmluZyByZXRWYWx1ZSA9IG51bGw7CiAgICAgICAgLy8gICAgWG1sTm9kZUxpc3Qgc3RyaW5nTm9kZXMgPSB4bFBhY2thZ2UuV29ya2Jvb2suU2hhcmVkU3RyaW5nc1htbC5TZWxlY3ROb2RlcyhzdHJpbmcuRm9ybWF0KCIvL2Q6c2kiLCBzdHJpbmdJRCksIE5hbWVTcGFjZU1hbmFnZXIpOwogICAgICAgIC8vICAgIFhtbE5vZGUgc3RyaW5nTm9kZSA9IHN0cmluZ05vZGVzW3N0cmluZ0lEXTsKICAgICAgICAvLyAgICBpZiAoc3RyaW5nTm9kZSAhPSBudWxsKQogICAgICAgIC8vICAgICAgICByZXRWYWx1ZSA9IHN0cmluZ05vZGUuSW5uZXJUZXh0OwogICAgICAgIC8vICAgIHJldHVybiAocmV0VmFsdWUpOwogICAgICAgIC8vfQogICAgICAgICNlbmRyZWdpb24KCQkjcmVnaW9uIEhlYWRlckZvb3RlcgoJCS8vLyA8c3VtbWFyeT4KCQkvLy8gQSByZWZlcmVuY2UgdG8gdGhlIGhlYWRlciBhbmQgZm9vdGVyIGNsYXNzIHdoaWNoIGFsbG93cyB5b3UgdG8gCgkJLy8vIHNldCB0aGUgaGVhZGVyIGFuZCBmb290ZXIgZm9yIGFsbCBvZGQsIGV2ZW4gYW5kIGZpcnN0IHBhZ2VzIG9mIHRoZSB3b3Jrc2hlZXQKICAgICAgICAvLy8gPC9zdW1tYXJ5PgogICAgICAgIC8vLyA8cmVtYXJrcz4KICAgICAgICAvLy8gVG8gZm9ybWF0IHRoZSB0ZXh0IHlvdSBjYW4gdXNlIHRoZSBmb2xsb3dpbmcgZm9ybWF0CiAgICAgICAgLy8vIDxsaXN0IHR5cGU9InRhYmxlIj4KICAgICAgICAvLy8gPGxpc3RoZWFkZXI+PHRlcm0+UHJlZml4PC90ZXJtPjxkZXNjcmlwdGlvbj5EZXNjcmlwdGlvbjwvZGVzY3JpcHRpb24+PC9saXN0aGVhZGVyPgogICAgICAgIC8vLyA8aXRlbT48dGVybT4mYW1wO1U8L3Rlcm0+PGRlc2NyaXB0aW9uPlVuZGVybGluZWQ8L2Rlc2NyaXB0aW9uPjwvaXRlbT4KICAgICAgICAvLy8gPGl0ZW0+PHRlcm0+JmFtcDtFPC90ZXJtPjxkZXNjcmlwdGlvbj5Eb3VibGUgVW5kZXJsaW5lPC9kZXNjcmlwdGlvbj48L2l0ZW0+CiAgICAgICAgLy8vIDxpdGVtPjx0ZXJtPiZhbXA7Szp4eHh4eHg8L3Rlcm0+PGRlc2NyaXB0aW9uPkNvbG9yLiBleCAmYW1wO0s6RkYwMDAwIGZvciByZWQ8L2Rlc2NyaXB0aW9uPjwvaXRlbT4KICAgICAgICAvLy8gPGl0ZW0+PHRlcm0+JmFtcDsiRm9udCxSZWd1bGFyIEJvbGQgSXRhbGljIjwvdGVybT48ZGVzY3JpcHRpb24+Q2hhbmdlcyB0aGUgZm9udC4gUmVndWxhciBvciBCb2xkIG9yIEl0YWxpYyBvciBCb2xkIEl0YWxpYyBjYW4gYmUgdXNlZC4gZXggJmFtcDsiQXJpYWwsQm9sZCBJdGFsaWMiPC9kZXNjcmlwdGlvbj48L2l0ZW0+CiAgICAgICAgLy8vIDxpdGVtPjx0ZXJtPiZhbXA7bm48L3Rlcm0+PGRlc2NyaXB0aW9uPkNoYW5nZSBmb250IHNpemUuIG5uIGlzIGFuIGludGVnZXIuIGV4ICZhbXA7MjQ8L2Rlc2NyaXB0aW9uPjwvaXRlbT4KICAgICAgICAvLy8gPGl0ZW0+PHRlcm0+JmFtcDtHPC90ZXJtPjxkZXNjcmlwdGlvbj5QbGFjZWhvbGRlciBmb3IgaW1hZ2VzLiBJbWFnZXMgY2FuIG5vdCBiZSBhZGRlZCBieSB0aGUgbGlicmFyeSwgYnV0IGl0cyBwb3NzaWJsZSB0byB1c2UgaW4gYSB0ZW1wbGF0ZS48L2Rlc2NyaXB0aW9uPjwvaXRlbT4KICAgICAgICAvLy8gPC9saXN0PgogICAgICAgIC8vLyA8L3JlbWFya3M+CiAgICAgICAgcHVibGljIEV4Y2VsSGVhZGVyRm9vdGVyIEhlYWRlckZvb3RlcgoJCXsKCQkJZ2V0CgkJCXsKCQkJCWlmIChfaGVhZGVyRm9vdGVyID09IG51bGwpCgkJCQl7CiAgICAgICAgICAgICAgICAgICAgWG1sTm9kZSBoZWFkZXJGb290ZXJOb2RlID0gVG9wTm9kZS5TZWxlY3RTaW5nbGVOb2RlKCJkOmhlYWRlckZvb3RlciIsIE5hbWVTcGFjZU1hbmFnZXIpOwogICAgICAgICAgICAgICAgICAgIGlmIChoZWFkZXJGb290ZXJOb2RlID09IG51bGwpCiAgICAgICAgICAgICAgICAgICAgICAgIGhlYWRlckZvb3Rlck5vZGU9IENyZWF0ZU5vZGUoImQ6aGVhZGVyRm9vdGVyIik7CiAgICAgICAgICAgICAgICAgICAgX2hlYWRlckZvb3RlciA9IG5ldyBFeGNlbEhlYWRlckZvb3RlcihOYW1lU3BhY2VNYW5hZ2VyLCBoZWFkZXJGb290ZXJOb2RlLCB0aGlzKTsKCQkJCX0gICAgICAgICAgICAgICAgCgkJCQlyZXR1cm4gKF9oZWFkZXJGb290ZXIpOwoJCQl9CgkJfQoJCSNlbmRyZWdpb24KCiAgICAgICAgI3JlZ2lvbiAiUHJpbnRlclNldHRpbmdzIgogICAgICAgIC8vLyA8c3VtbWFyeT4KICAgICAgICAvLy8gUHJpbnRlciBzZXR0aW5ncwogICAgICAgIC8vLyA8L3N1bW1hcnk+CiAgICAgICAgcHVibGljIEV4Y2VsUHJpbnRlclNldHRpbmdzIFByaW50ZXJTZXR0aW5ncwogICAgICAgIHsKICAgICAgICAgICAgZ2V0CiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIHZhciBwcyA9IG5ldyBFeGNlbFByaW50ZXJTZXR0aW5ncyhOYW1lU3BhY2VNYW5hZ2VyLCBUb3BOb2RlLCB0aGlzKTsKICAgICAgICAgICAgICAgIHBzLlNjaGVtYU5vZGVPcmRlciA9IFNjaGVtYU5vZGVPcmRlcjsKICAgICAgICAgICAgICAgIHJldHVybiBwczsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgICAgICAjZW5kcmVnaW9uCgoJCSNlbmRyZWdpb24gLy8gRU5EIFdvcmtzaGVldCBQdWJsaWMgUHJvcGVydGllcwoKCQkjcmVnaW9uIFdvcmtzaGVldCBQdWJsaWMgTWV0aG9kcwogICAgICAgIAogICAgICAgIC8vLy8vIDxzdW1tYXJ5PgogICAgICAgIC8vLy8vIFByb3ZpZGVzIGFjY2VzcyB0byBhbiBpbmRpdmlkdWFsIGNlbGwgd2l0aGluIHRoZSB3b3Jrc2hlZXQuCiAgICAgICAgLy8vLy8gPC9zdW1tYXJ5PgogICAgICAgIC8vLy8vIDxwYXJhbSBuYW1lPSJyb3ciPlRoZSByb3cgbnVtYmVyIGluIHRoZSB3b3Jrc2hlZXQ8L3BhcmFtPgogICAgICAgIC8vLy8vIDxwYXJhbSBuYW1lPSJjb2wiPlRoZSBjb2x1bW4gbnVtYmVyIGluIHRoZSB3b3Jrc2hlZXQ8L3BhcmFtPgogICAgICAgIC8vLy8vIDxyZXR1cm5zPjwvcmV0dXJucz4JCQogICAgICAgIC8vaW50ZXJuYWwgRXhjZWxDZWxsIENlbGwoaW50IHJvdywgaW50IGNvbCkKICAgICAgICAvL3sKICAgICAgICAvLyAgICByZXR1cm4gbmV3IEV4Y2VsQ2VsbChfdmFsdWVzLCByb3csIGNvbCk7CiAgICAgICAgLy99CiAgICAgICAgIC8vLyA8c3VtbWFyeT4KICAgICAgICAgLy8vIFByb3ZpZGVzIGFjY2VzcyB0byBhIHJhbmdlIG9mIGNlbGxzCiAgICAgICAgLy8vIDwvc3VtbWFyeT4gIAogICAgICAgIHB1YmxpYyBFeGNlbFJhbmdlIENlbGxzCiAgICAgICAgewogICAgICAgICAgICBnZXQKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgQ2hlY2tTaGVldFR5cGUoKTsKICAgICAgICAgICAgICAgIHJldHVybiBuZXcgRXhjZWxSYW5nZSh0aGlzLCAxLCAxLCBFeGNlbFBhY2thZ2UuTWF4Um93cywgRXhjZWxQYWNrYWdlLk1heENvbHVtbnMpOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIC8vLyA8c3VtbWFyeT4KICAgICAgICAvLy8gUHJvdmlkZXMgYWNjZXNzIHRvIHRoZSBzZWxlY3RlZCByYW5nZSBvZiBjZWxscwogICAgICAgIC8vLyA8L3N1bW1hcnk+ICAKICAgICAgICBwdWJsaWMgRXhjZWxSYW5nZSBTZWxlY3RlZFJhbmdlCiAgICAgICAgewogICAgICAgICAgICBnZXQKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgQ2hlY2tTaGVldFR5cGUoKTsKICAgICAgICAgICAgICAgIHJldHVybiBuZXcgRXhjZWxSYW5nZSh0aGlzLCBWaWV3LlNlbGVjdGVkUmFuZ2UpOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIE1lcmdlQ2VsbHNDb2xsZWN0aW9uIF9tZXJnZWRDZWxscyA9IG5ldyBNZXJnZUNlbGxzQ29sbGVjdGlvbigpOwogICAgICAgIC8vLyA8c3VtbWFyeT4KICAgICAgICAvLy8gQWRkcmVzc2VzIHRvIG1lcmdlZCByYW5nZXMKICAgICAgICAvLy8gPC9zdW1tYXJ5PgogICAgICAgIHB1YmxpYyBNZXJnZUNlbGxzQ29sbGVjdGlvbiBNZXJnZWRDZWxscwogICAgICAgIHsKICAgICAgICAgICAgZ2V0CiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIENoZWNrU2hlZXRUeXBlKCk7CiAgICAgICAgICAgICAgICByZXR1cm4gX21lcmdlZENlbGxzOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIC8vLyA8c3VtbWFyeT4KCQkvLy8gUHJvdmlkZXMgYWNjZXNzIHRvIGFuIGluZGl2aWR1YWwgcm93IHdpdGhpbiB0aGUgd29ya3NoZWV0IHNvIHlvdSBjYW4gc2V0IGl0cyBwcm9wZXJ0aWVzLgoJCS8vLyA8L3N1bW1hcnk+CgkJLy8vIDxwYXJhbSBuYW1lPSJyb3ciPlRoZSByb3cgbnVtYmVyIGluIHRoZSB3b3Jrc2hlZXQ8L3BhcmFtPgoJCS8vLyA8cmV0dXJucz48L3JldHVybnM+CgkJcHVibGljIEV4Y2VsUm93IFJvdyhpbnQgcm93KQoJCXsKICAgICAgICAgICAgLy9FeGNlbFJvdyByOwogICAgICAgICAgICAvL3Vsb25nIGlkID0gRXhjZWxSb3cuR2V0Um93SUQoX3NoZWV0SUQsIHJvdyk7CiAgICAgICAgICAgIC8vVE9ETzogRml4YS4KICAgICAgICAgICAgLy92YXIgdiA9IF92YWx1ZXMuR2V0VmFsdWUocm93LCAwKTsKICAgICAgICAgICAgLy9pZiAodiE9bnVsbCkKICAgICAgICAgICAgLy97CiAgICAgICAgICAgIC8vICAgIHZhciByaT0oUm93SW50ZXJuYWwpdjsKICAgICAgICAgICAgLy8gICAgciA9IG5ldyBFeGNlbFJvdyh0aGlzLCByb3cpCiAgICAgICAgICAgIC8vfQogICAgICAgICAgICAvL2Vsc2UKICAgICAgICAgICAgLy97CiAgICAgICAgICAgICAgICAvL3IgPSBuZXcgRXhjZWxSb3codGhpcywgcm93KTsKICAgICAgICAgICAgICAgIC8vX3ZhbHVlcy5TZXRWYWx1ZShyb3csIDAsIHIpOwogICAgICAgICAgICAgICAgLy9fcm93cy5BZGQocik7CiAgICAgICAgICAgIC8vfQogICAgICAgICAgICBDaGVja1NoZWV0VHlwZSgpOwogICAgICAgICAgICBpZiAocm93IDwgMSB8fCByb3cgPiBFeGNlbFBhY2thZ2UuTWF4Um93cykKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgdGhyb3cgKG5ldyBBcmd1bWVudEV4Y2VwdGlvbigiUm93IG51bWJlciBvdXQgb2YgYm91bmRzIikpOwogICAgICAgICAgICB9CiAgICAgICAgICAgIHJldHVybiBuZXcgRXhjZWxSb3codGhpcywgcm93KTsKICAgICAgICAgICAgLy9yZXR1cm4gcjsKCQl9CgkJLy8vIDxzdW1tYXJ5PgoJCS8vLyBQcm92aWRlcyBhY2Nlc3MgdG8gYW4gaW5kaXZpZHVhbCBjb2x1bW4gd2l0aGluIHRoZSB3b3Jrc2hlZXQgc28geW91IGNhbiBzZXQgaXRzIHByb3BlcnRpZXMuCgkJLy8vIDwvc3VtbWFyeT4KCQkvLy8gPHBhcmFtIG5hbWU9ImNvbCI+VGhlIGNvbHVtbiBudW1iZXIgaW4gdGhlIHdvcmtzaGVldDwvcGFyYW0+CgkJLy8vIDxyZXR1cm5zPjwvcmV0dXJucz4KCQlwdWJsaWMgRXhjZWxDb2x1bW4gQ29sdW1uKGludCBjb2wpCgkJeyAgICAgICAgICAgIAogICAgICAgICAgICBDaGVja1NoZWV0VHlwZSgpOwogICAgICAgICAgICBpZiAoY29sIDwgMSB8fCBjb2wgPiBFeGNlbFBhY2thZ2UuTWF4Q29sdW1ucykKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgdGhyb3cgKG5ldyBBcmd1bWVudEV4Y2VwdGlvbigiQ29sdW1uIG51bWJlciBvdXQgb2YgYm91bmRzIikpOwogICAgICAgICAgICB9CiAgICAgICAgICAgIHZhciBjb2x1bW4gPSBfdmFsdWVzLkdldFZhbHVlKDAsIGNvbCkgYXMgRXhjZWxDb2x1bW47CiAgICAgICAgICAgIGlmIChjb2x1bW4hPW51bGwpCiAgICAgICAgICAgIHsgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgIGlmIChjb2x1bW4uQ29sdW1uTWluICE9IGNvbHVtbi5Db2x1bW5NYXgpCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgaW50IG1heENvbCA9IGNvbHVtbi5Db2x1bW5NYXg7CiAgICAgICAgICAgICAgICAgICAgY29sdW1uLkNvbHVtbk1heCA9IGNvbDsKICAgICAgICAgICAgICAgICAgICBFeGNlbENvbHVtbiBjb3B5ID0gQ29weUNvbHVtbihjb2x1bW4sIGNvbCArIDEsIG1heENvbCk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICAgICAgZWxzZQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBpbnQgcj0wLCBjPWNvbDsKICAgICAgICAgICAgICAgIGlmIChfdmFsdWVzLlByZXZDZWxsKHJlZiByLCByZWYgYykpCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgY29sdW1uID0gX3ZhbHVlcy5HZXRWYWx1ZSgwLCBjKSBhcyBFeGNlbENvbHVtbjsKICAgICAgICAgICAgICAgICAgICBpbnQgbWF4Q29sID0gY29sdW1uLkNvbHVtbk1heDsKICAgICAgICAgICAgICAgICAgICBpZiAobWF4Q29sID49IGNvbCkKICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgIGNvbHVtbi5Db2x1bW5NYXggPSBjb2wtMTsKICAgICAgICAgICAgICAgICAgICAgICAgaWYgKG1heENvbCA+IGNvbCkKICAgICAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgRXhjZWxDb2x1bW4gbmV3QyA9IENvcHlDb2x1bW4oY29sdW1uLCBjb2wgKyAxLCBtYXhDb2wpOwogICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBDb3B5Q29sdW1uKGNvbHVtbiwgY29sLCBjb2wpOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIC8vZm9yZWFjaCAoRXhjZWxDb2x1bW4gY2hlY2tDb2x1bW4gaW4gX2NvbHVtbnMpCiAgICAgICAgICAgICAgICAvL3sKICAgICAgICAgICAgICAgIC8vICAgIGlmIChjb2wgPiBjaGVja0NvbHVtbi5Db2x1bW5NaW4gJiYgY29sIDw9IGNoZWNrQ29sdW1uLkNvbHVtbk1heCkKICAgICAgICAgICAgICAgIC8vICAgIHsKICAgICAgICAgICAgICAgIC8vICAgICAgICBpbnQgbWF4Q29sID0gY2hlY2tDb2x1bW4uQ29sdW1uTWF4OwogICAgICAgICAgICAgICAgLy8gICAgICAgIGNoZWNrQ29sdW1uLkNvbHVtbk1heCA9IGNvbCAtIDE7CiAgICAgICAgICAgICAgICAvLyAgICAgICAgaWYgKG1heENvbCA+IGNvbCkKICAgICAgICAgICAgICAgIC8vICAgICAgICB7CiAgICAgICAgICAgICAgICAvLyAgICAgICAgICAgIEV4Y2VsQ29sdW1uIG5ld0MgPSBDb3B5Q29sdW1uKGNoZWNrQ29sdW1uLCBjb2wgKyAxLCBtYXhDb2wpOwogICAgICAgICAgICAgICAgLy8gICAgICAgIH0KICAgICAgICAgICAgICAgIC8vICAgICAgICByZXR1cm4gQ29weUNvbHVtbihjaGVja0NvbHVtbiwgY29sLGNvbCk7ICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAvLyAgICB9CiAgICAgICAgICAgICAgICAvL30KICAgICAgICAgICAgICAgIGNvbHVtbiA9IG5ldyBFeGNlbENvbHVtbih0aGlzLCBjb2wpOwogICAgICAgICAgICAgICAgX3ZhbHVlcy5TZXRWYWx1ZSgwLCBjb2wsIGNvbHVtbik7CiAgICAgICAgICAgICAgICAvL19jb2x1bW5zLkFkZChjb2x1bW4pOwogICAgICAgICAgICAgfQogICAgICAgICAgICByZXR1cm4gY29sdW1uOwoJCX0KCiAgICAgICAgLy8vIDxzdW1tYXJ5PgogICAgICAgIC8vLyBSZXR1cm5zIHRoZSBuYW1lIG9mIHRoZSB3b3Jrc2hlZXQKICAgICAgICAvLy8gPC9zdW1tYXJ5PgogICAgICAgIC8vLyA8cmV0dXJucz5UaGUgbmFtZSBvZiB0aGUgd29ya3NoZWV0PC9yZXR1cm5zPgogICAgICAgIHB1YmxpYyBvdmVycmlkZSBzdHJpbmcgVG9TdHJpbmcoKQogICAgICAgIHsKICAgICAgICAgICAgcmV0dXJuIE5hbWU7CiAgICAgICAgfQogICAgICAgIGludGVybmFsIEV4Y2VsQ29sdW1uIENvcHlDb2x1bW4oRXhjZWxDb2x1bW4gYywgaW50IGNvbCwgaW50IG1heENvbCkKICAgICAgICB7CiAgICAgICAgICAgIEV4Y2VsQ29sdW1uIG5ld0MgPSBuZXcgRXhjZWxDb2x1bW4odGhpcywgY29sKTsKICAgICAgICAgICAgbmV3Qy5Db2x1bW5NYXggPSBtYXhDb2wgPCBFeGNlbFBhY2thZ2UuTWF4Q29sdW1ucyA/IG1heENvbCA6IEV4Y2VsUGFja2FnZS5NYXhDb2x1bW5zOwogICAgICAgICAgICBpZiAoYy5TdHlsZU5hbWUgIT0gIiIpCiAgICAgICAgICAgICAgICBuZXdDLlN0eWxlTmFtZSA9IGMuU3R5bGVOYW1lOwogICAgICAgICAgICBlbHNlCiAgICAgICAgICAgICAgICBuZXdDLlN0eWxlSUQgPSBjLlN0eWxlSUQ7CgogICAgICAgICAgICBuZXdDLk91dGxpbmVMZXZlbCA9IGMuT3V0bGluZUxldmVsOwogICAgICAgICAgICBuZXdDLlBob25ldGljID0gYy5QaG9uZXRpYzsKICAgICAgICAgICAgbmV3Qy5CZXN0Rml0ID0gYy5CZXN0Rml0OwogICAgICAgICAgICAvL19jb2x1bW5zLkFkZChuZXdDKTsKICAgICAgICAgICAgX3ZhbHVlcy5TZXRWYWx1ZSgwLCBjb2wsIG5ld0MpOwogICAgICAgICAgICBuZXdDLl93aWR0aCA9IGMuX3dpZHRoOwogICAgICAgICAgICBuZXdDLl9oaWRkZW4gPSBjLl9oaWRkZW47CiAgICAgICAgICAgIHJldHVybiBuZXdDOwogICAgICAgfQogICAgICAgIC8vLyA8c3VtbWFyeT4KICAgICAgICAvLy8gTWFrZSB0aGUgY3VycmVudCB3b3Jrc2hlZXQgYWN0aXZlLgogICAgICAgIC8vLyA8L3N1bW1hcnk+CiAgICAgICAgcHVibGljIHZvaWQgU2VsZWN0KCkKICAgICAgICB7CiAgICAgICAgICAgIFZpZXcuVGFiU2VsZWN0ZWQgPSB0cnVlOwogICAgICAgICAgICAvL1NlbGVjdChBZGRyZXNzLCB0cnVlKTsKICAgICAgICB9CiAgICAgICAgLy8vIDxzdW1tYXJ5PgogICAgICAgIC8vLyBTZWxlY3RzIGEgcmFuZ2UgaW4gdGhlIHdvcmtzaGVldC4gVGhlIGFjdGl2ZSBjZWxsIGlzIHRoZSB0b3Btb3N0IGNlbGwuCiAgICAgICAgLy8vIE1ha2UgdGhlIGN1cnJlbnQgd29ya3NoZWV0IGFjdGl2ZS4KICAgICAgICAvLy8gPC9zdW1tYXJ5PgogICAgICAgIC8vLyA8cGFyYW0gbmFtZT0iQWRkcmVzcyI+QW4gYWRkcmVzcyByYW5nZTwvcGFyYW0+CiAgICAgICAgcHVibGljIHZvaWQgU2VsZWN0KHN0cmluZyBBZGRyZXNzKQogICAgICAgIHsKICAgICAgICAgICAgU2VsZWN0KEFkZHJlc3MsIHRydWUpOwogICAgICAgIH0KICAgICAgICAvLy8gPHN1bW1hcnk+CiAgICAgICAgLy8vIFNlbGVjdHMgYSByYW5nZSBpbiB0aGUgd29ya3NoZWV0LiBUaGUgYWN0aWNlIGNlbGwgaXMgdGhlIHRvcG1vc3QgY2VsbC4KICAgICAgICAvLy8gPC9zdW1tYXJ5PgogICAgICAgIC8vLyA8cGFyYW0gbmFtZT0iQWRkcmVzcyI+QSByYW5nZSBvZiBjZWxsczwvcGFyYW0+CiAgICAgICAgLy8vIDxwYXJhbSBuYW1lPSJTZWxlY3RTaGVldCI+TWFrZSB0aGUgc2hlZXQgYWN0aXZlPC9wYXJhbT4KICAgICAgICBwdWJsaWMgdm9pZCBTZWxlY3Qoc3RyaW5nIEFkZHJlc3MsIGJvb2wgU2VsZWN0U2hlZXQpCiAgICAgICAgewogICAgICAgICAgICBDaGVja1NoZWV0VHlwZSgpOwogICAgICAgICAgICBpbnQgZnJvbUNvbCwgZnJvbVJvdywgdG9Db2wsIHRvUm93OwogICAgICAgICAgICAvL0dldCByb3dzIGFuZCBjb2x1bW5zIGFuZCB2YWxpZGF0ZSBhcyB3ZWxsCiAgICAgICAgICAgIEV4Y2VsQ2VsbEJhc2UuR2V0Um93Q29sRnJvbUFkZHJlc3MoQWRkcmVzcywgb3V0IGZyb21Sb3csIG91dCBmcm9tQ29sLCBvdXQgdG9Sb3csIG91dCB0b0NvbCk7CgogICAgICAgICAgICBpZiAoU2VsZWN0U2hlZXQpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIFZpZXcuVGFiU2VsZWN0ZWQgPSB0cnVlOwogICAgICAgICAgICB9CiAgICAgICAgICAgIFZpZXcuU2VsZWN0ZWRSYW5nZSA9IEFkZHJlc3M7CiAgICAgICAgICAgIFZpZXcuQWN0aXZlQ2VsbCA9IEV4Y2VsQ2VsbEJhc2UuR2V0QWRkcmVzcyhmcm9tUm93LCBmcm9tQ29sKTsgICAgICAgICAgICAKICAgICAgICB9CiAgICAgICAgLy8vIDxzdW1tYXJ5PgogICAgICAgIC8vLyBTZWxlY3RzIGEgcmFuZ2UgaW4gdGhlIHdvcmtzaGVldC4gVGhlIGFjdGl2ZSBjZWxsIGlzIHRoZSB0b3Btb3N0IGNlbGwgb2YgdGhlIGZpcnN0IGFkZHJlc3MuCiAgICAgICAgLy8vIE1ha2UgdGhlIGN1cnJlbnQgd29ya3NoZWV0IGFjdGl2ZS4KICAgICAgICAvLy8gPC9zdW1tYXJ5PgogICAgICAgIC8vLyA8cGFyYW0gbmFtZT0iQWRkcmVzcyI+QW4gYWRkcmVzcyByYW5nZTwvcGFyYW0+CiAgICAgICAgcHVibGljIHZvaWQgU2VsZWN0KEV4Y2VsQWRkcmVzcyBBZGRyZXNzKQogICAgICAgIHsKICAgICAgICAgICAgQ2hlY2tTaGVldFR5cGUoKTsKICAgICAgICAgICAgU2VsZWN0KEFkZHJlc3MsIHRydWUpOwogICAgICAgIH0KICAgICAgICAvLy8gPHN1bW1hcnk+CiAgICAgICAgLy8vIFNlbGVjdHMgYSByYW5nZSBpbiB0aGUgd29ya3NoZWV0LiBUaGUgYWN0aXZlIGNlbGwgaXMgdGhlIHRvcG1vc3QgY2VsbCBvZiB0aGUgZmlyc3QgYWRkcmVzcy4KICAgICAgICAvLy8gPC9zdW1tYXJ5PgogICAgICAgIC8vLyA8cGFyYW0gbmFtZT0iQWRkcmVzcyI+QSByYW5nZSBvZiBjZWxsczwvcGFyYW0+CiAgICAgICAgLy8vIDxwYXJhbSBuYW1lPSJTZWxlY3RTaGVldCI+TWFrZSB0aGUgc2hlZXQgYWN0aXZlPC9wYXJhbT4KICAgICAgICBwdWJsaWMgdm9pZCBTZWxlY3QoRXhjZWxBZGRyZXNzIEFkZHJlc3MsIGJvb2wgU2VsZWN0U2hlZXQpCiAgICAgICAgewoKICAgICAgICAgICAgQ2hlY2tTaGVldFR5cGUoKTsKICAgICAgICAgICAgaWYgKFNlbGVjdFNoZWV0KQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBWaWV3LlRhYlNlbGVjdGVkID0gdHJ1ZTsKICAgICAgICAgICAgfQogICAgICAgICAgICBzdHJpbmcgc2VsQWRkcmVzcyA9IEV4Y2VsQ2VsbEJhc2UuR2V0QWRkcmVzcyhBZGRyZXNzLlN0YXJ0LlJvdywgQWRkcmVzcy5TdGFydC5Db2x1bW4pICsgIjoiICsgRXhjZWxDZWxsQmFzZS5HZXRBZGRyZXNzKEFkZHJlc3MuRW5kLlJvdywgQWRkcmVzcy5FbmQuQ29sdW1uKTsKICAgICAgICAgICAgaWYgKEFkZHJlc3MuQWRkcmVzc2VzICE9IG51bGwpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIGZvcmVhY2ggKHZhciBhIGluIEFkZHJlc3MuQWRkcmVzc2VzKQogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIHNlbEFkZHJlc3MgKz0gIiAiICsgRXhjZWxDZWxsQmFzZS5HZXRBZGRyZXNzKGEuU3RhcnQuUm93LCBhLlN0YXJ0LkNvbHVtbikgKyAiOiIgKyBFeGNlbENlbGxCYXNlLkdldEFkZHJlc3MoYS5FbmQuUm93LCBhLkVuZC5Db2x1bW4pOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgICAgIFZpZXcuU2VsZWN0ZWRSYW5nZSA9IHNlbEFkZHJlc3M7CiAgICAgICAgICAgIFZpZXcuQWN0aXZlQ2VsbCA9IEV4Y2VsQ2VsbEJhc2UuR2V0QWRkcmVzcyhBZGRyZXNzLlN0YXJ0LlJvdywgQWRkcmVzcy5TdGFydC5Db2x1bW4pOwogICAgICAgIH0KCgkJI3JlZ2lvbiBJbnNlcnRSb3cKICAgICAgICAvLy8gPHN1bW1hcnk+CiAgICAgICAgLy8vIEluc2VydHMgYSBuZXcgcm93IGludG8gdGhlIHNwcmVhZHNoZWV0LiAgRXhpc3Rpbmcgcm93cyBiZWxvdyB0aGUgcG9zaXRpb24gYXJlIAogICAgICAgIC8vLyBzaGlmdGVkIGRvd24uICBBbGwgZm9ybXVsYSBhcmUgdXBkYXRlZCB0byB0YWtlIGFjY291bnQgb2YgdGhlIG5ldyByb3cuCiAgICAgICAgLy8vIDwvc3VtbWFyeT4KICAgICAgICAvLy8gPHBhcmFtIG5hbWU9InJvd0Zyb20iPlRoZSBwb3NpdGlvbiBvZiB0aGUgbmV3IHJvdzwvcGFyYW0+CiAgICAgICAgLy8vIDxwYXJhbSBuYW1lPSJyb3dzIj5OdW1iZXIgb2Ygcm93cyB0byBpbnNlcnQ8L3BhcmFtPgogICAgICAgIHB1YmxpYyB2b2lkIEluc2VydFJvdyhpbnQgcm93RnJvbSwgaW50IHJvd3MpCiAgICAgICAgewogICAgICAgICAgICBJbnNlcnRSb3cocm93RnJvbSwgcm93cywgMCk7CiAgICAgICAgfQogICAgICAgIC8vLyA8c3VtbWFyeT4KCQkvLy8gSW5zZXJ0cyBhIG5ldyByb3cgaW50byB0aGUgc3ByZWFkc2hlZXQuICBFeGlzdGluZyByb3dzIGJlbG93IHRoZSBwb3NpdGlvbiBhcmUgCgkJLy8vIHNoaWZ0ZWQgZG93bi4gIEFsbCBmb3JtdWxhIGFyZSB1cGRhdGVkIHRvIHRha2UgYWNjb3VudCBvZiB0aGUgbmV3IHJvdy4KCQkvLy8gPC9zdW1tYXJ5PgogICAgICAgIC8vLyA8cGFyYW0gbmFtZT0icm93RnJvbSI+VGhlIHBvc2l0aW9uIG9mIHRoZSBuZXcgcm93PC9wYXJhbT4KICAgICAgICAvLy8gPHBhcmFtIG5hbWU9InJvd3MiPk51bWJlciBvZiByb3dzIHRvIGluc2VydC48L3BhcmFtPgogICAgICAgIC8vLyA8cGFyYW0gbmFtZT0iY29weVN0eWxlc0Zyb21Sb3ciPkNvcHkgU3R5bGVzIGZyb20gdGhpcyByb3cuIEFwcGxpZWQgdG8gYWxsIGluc2VydGVkIHJvd3M8L3BhcmFtPgoJCXB1YmxpYyB2b2lkICBJbnNlcnRSb3coaW50IHJvd0Zyb20sIGludCByb3dzLCBpbnQgY29weVN0eWxlc0Zyb21Sb3cpCgkJewogICAgICAgICAgICBDaGVja1NoZWV0VHlwZSgpOwogICAgICAgICAgICAgICAgdmFyIGQgPSBEaW1lbnNpb247CgogICAgICAgICAgICBpZiAocm93RnJvbSA8IDEpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIHRocm93IChuZXcgQXJndW1lbnRPdXRPZlJhbmdlRXhjZXB0aW9uKCJyb3dGcm9tIGNhbid0IGJlIGxlc3NlciB0aGF0IDEiKSk7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIC8vQ2hlY2sgdGhhdCBjZWxscyBhcmVuJ3Qgc2hpZnRlZCBvdXRzaWRlIHRoZSBib3VuZHJpZXMKICAgICAgICAgICAgaWYgKGQgIT0gbnVsbCAmJiBkLkVuZC5Sb3cgPiByb3dGcm9tICYmIGQuRW5kLlJvdyArIHJvd3MgPiBFeGNlbFBhY2thZ2UuTWF4Um93cykKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgdGhyb3cgKG5ldyBBcmd1bWVudE91dE9mUmFuZ2VFeGNlcHRpb24oIkNhbid0IGluc2VydC4gUm93cyB3aWxsIGJlIHNoaWZ0ZWQgb3V0c2lkZSB0aGUgYm91bmRyaWVzIG9mIHRoZSB3b3Jrc2hlZXQuIikpOwogICAgICAgICAgICB9CgogICAgICAgICAgICBsb2NrICh0aGlzKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBfdmFsdWVzLkluc2VydChyb3dGcm9tLCAwLCByb3dzLCAwKTsKICAgICAgICAgICAgICAgIF9mb3JtdWxhcy5JbnNlcnQocm93RnJvbSwgMCwgcm93cywgMCk7CiAgICAgICAgICAgICAgICBfc3R5bGVzLkluc2VydChyb3dGcm9tLCAwLCByb3dzLCAwKTsKICAgICAgICAgICAgICAgIF90eXBlcy5JbnNlcnQocm93RnJvbSwgMCwgcm93cywgMCk7CiAgICAgICAgICAgICAgICBfY29tbWVudHNTdG9yZS5JbnNlcnQocm93RnJvbSwgMCwgcm93cywgMCk7CiAgICAgICAgICAgICAgICBfaHlwZXJMaW5rcy5JbnNlcnQocm93RnJvbSwgMCwgcm93cywgMCk7CiAgICAgICAgICAgICAgICBfZmxhZ3MuSW5zZXJ0KHJvd0Zyb20sIDAsIHJvd3MsIDApOwoKICAgICAgICAgICAgICAgIGZvcmVhY2ggKHZhciBmIGluIF9zaGFyZWRGb3JtdWxhcy5WYWx1ZXMpCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgaWYgKGYuU3RhcnRSb3cgPj0gcm93RnJvbSkgZi5TdGFydFJvdyArPSByb3dzOwogICAgICAgICAgICAgICAgICAgIHZhciBhID0gbmV3IEV4Y2VsQWRkcmVzc0Jhc2UoZi5BZGRyZXNzKTsKICAgICAgICAgICAgICAgICAgICBpZiAoYS5fZnJvbVJvdyA+PSByb3dGcm9tKQogICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgYS5fZnJvbVJvdyArPSByb3dzOwogICAgICAgICAgICAgICAgICAgICAgICBhLl90b1JvdyArPSByb3dzOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICBlbHNlIGlmIChhLl90b1JvdyA+PSByb3dGcm9tKQogICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgYS5fdG9Sb3cgKz0gcm93czsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgZi5BZGRyZXNzID0gRXhjZWxBZGRyZXNzQmFzZS5HZXRBZGRyZXNzKGEuX2Zyb21Sb3csIGEuX2Zyb21Db2wsIGEuX3RvUm93LCBhLl90b0NvbCk7CiAgICAgICAgICAgICAgICAgICAgZi5Gb3JtdWxhID0gRXhjZWxDZWxsQmFzZS5VcGRhdGVGb3JtdWxhUmVmZXJlbmNlcyhmLkZvcm11bGEsIHJvd3MsIDAsIHJvd0Zyb20sIDApOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgdmFyIGNzZSA9IG5ldyBDZWxsc1N0b3JlRW51bWVyYXRvcjxvYmplY3Q+KF9mb3JtdWxhcyk7CiAgICAgICAgICAgICAgICB3aGlsZSAoY3NlLk5leHQoKSkKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICBpZiAoY3NlLlZhbHVlIGlzIHN0cmluZykKICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgIGNzZS5WYWx1ZSA9IEV4Y2VsQ2VsbEJhc2UuVXBkYXRlRm9ybXVsYVJlZmVyZW5jZXMoY3NlLlZhbHVlLlRvU3RyaW5nKCksIHJvd3MsIDAsIHJvd0Zyb20sIDApOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICBGaXhNZXJnZWRDZWxsc1Jvdyhyb3dGcm9tLCByb3dzLCBmYWxzZSk7CiAgICAgICAgICAgICAgICBpZiAoY29weVN0eWxlc0Zyb21Sb3cgPiAwKQogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIHZhciBjc2VTID0gbmV3IENlbGxzU3RvcmVFbnVtZXJhdG9yPGludD4oX3N0eWxlcywgY29weVN0eWxlc0Zyb21Sb3csIDAsIGNvcHlTdHlsZXNGcm9tUm93LCBFeGNlbFBhY2thZ2UuTWF4Q29sdW1ucyk7IC8vRml4ZXMgaXNzdWUgMTUwNjggLCAxNTA5MAogICAgICAgICAgICAgICAgICAgIHdoaWxlKGNzZVMuTmV4dCgpKQogICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgZm9yICh2YXIgciA9IDA7IHIgPCByb3dzOyByKyspCiAgICAgICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIF9zdHlsZXMuU2V0VmFsdWUocm93RnJvbSArIHIsIGNzZVMuQ29sdW1uLCBjc2VTLlZhbHVlKTsKICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGZvcmVhY2ggKHZhciB0YmwgaW4gVGFibGVzKQogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIHRibC5BZGRyZXNzID0gdGJsLkFkZHJlc3MuQWRkUm93KHJvd0Zyb20sIHJvd3MpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIC8vLyA8c3VtbWFyeT4KICAgICAgICAvLy8gSW5zZXJ0cyBhIG5ldyBjb2x1bW4gaW50byB0aGUgc3ByZWFkc2hlZXQuICBFeGlzdGluZyBjb2x1bW5zIGJlbG93IHRoZSBwb3NpdGlvbiBhcmUgCiAgICAgICAgLy8vIHNoaWZ0ZWQgZG93bi4gIEFsbCBmb3JtdWxhIGFyZSB1cGRhdGVkIHRvIHRha2UgYWNjb3VudCBvZiB0aGUgbmV3IGNvbHVtbi4KICAgICAgICAvLy8gPC9zdW1tYXJ5PgogICAgICAgIC8vLyA8cGFyYW0gbmFtZT0iY29sdW1uRnJvbSI+VGhlIHBvc2l0aW9uIG9mIHRoZSBuZXcgY29sdW1uPC9wYXJhbT4KICAgICAgICAvLy8gPHBhcmFtIG5hbWU9ImNvbHVtbnMiPk51bWJlciBvZiBjb2x1bW5zIHRvIGluc2VydDwvcGFyYW0+ICAgICAgICAKICAgICAgICBwdWJsaWMgdm9pZCBJbnNlcnRDb2x1bW4oaW50IGNvbHVtbkZyb20sIGludCBjb2x1bW5zKQogICAgICAgIHsKICAgICAgICAgICAgSW5zZXJ0Q29sdW1uKGNvbHVtbkZyb20sIGNvbHVtbnMsIDApOwogICAgICAgIH0KICAgICAgICAvLy88c3VtbWFyeT4KICAgICAgICAvLy8gSW5zZXJ0cyBhIG5ldyBjb2x1bW4gaW50byB0aGUgc3ByZWFkc2hlZXQuICBFeGlzdGluZyBjb2x1bW4gdG8gdGhlIGxlZnQgYXJlIAogICAgICAgIC8vLyBzaGlmdGVkLiAgQWxsIGZvcm11bGEgYXJlIHVwZGF0ZWQgdG8gdGFrZSBhY2NvdW50IG9mIHRoZSBuZXcgY29sdW1uLgogICAgICAgIC8vLyA8L3N1bW1hcnk+CiAgICAgICAgLy8vIDxwYXJhbSBuYW1lPSJjb2x1bW5Gcm9tIj5UaGUgcG9zaXRpb24gb2YgdGhlIG5ldyBjb2x1bW48L3BhcmFtPgogICAgICAgIC8vLyA8cGFyYW0gbmFtZT0iY29sdW1ucyI+TnVtYmVyIG9mIGNvbHVtbnMgdG8gaW5zZXJ0LjwvcGFyYW0+CiAgICAgICAgLy8vIDxwYXJhbSBuYW1lPSJjb3B5U3R5bGVzRnJvbUNvbHVtbiI+Q29weSBTdHlsZXMgZnJvbSB0aGlzIGNvbHVtbi4gQXBwbGllZCB0byBhbGwgaW5zZXJ0ZWQgY29sdW1uczwvcGFyYW0+CiAgICAgICAgcHVibGljIHZvaWQgSW5zZXJ0Q29sdW1uKGludCBjb2x1bW5Gcm9tLCBpbnQgY29sdW1ucywgaW50IGNvcHlTdHlsZXNGcm9tQ29sdW1uKQogICAgICAgIHsKICAgICAgICAgICAgQ2hlY2tTaGVldFR5cGUoKTsKICAgICAgICAgICAgdmFyIGQgPSBEaW1lbnNpb247CgogICAgICAgICAgICBpZiAoY29sdW1uRnJvbSA8IDEpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIHRocm93IChuZXcgQXJndW1lbnRPdXRPZlJhbmdlRXhjZXB0aW9uKCJjb2x1bW5Gcm9tIGNhbid0IGJlIGxlc3NlciB0aGF0IDEiKSk7CiAgICAgICAgICAgIH0gICAgICAgICAgICAKICAgICAgICAgICAgLy9DaGVjayB0aGF0IGNlbGxzIGFyZW4ndCBzaGlmdGVkIG91dHNpZGUgdGhlIGJvdW5kcmllcwogICAgICAgICAgICBpZiAoZCAhPSBudWxsICYmIGQuRW5kLkNvbHVtbiA+IGNvbHVtbkZyb20gJiYgZC5FbmQuQ29sdW1uICsgY29sdW1ucyA+IEV4Y2VsUGFja2FnZS5NYXhDb2x1bW5zKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICB0aHJvdyAobmV3IEFyZ3VtZW50T3V0T2ZSYW5nZUV4Y2VwdGlvbigiQ2FuJ3QgaW5zZXJ0LiBDb2x1bW5zIHdpbGwgYmUgc2hpZnRlZCBvdXRzaWRlIHRoZSBib3VuZHJpZXMgb2YgdGhlIHdvcmtzaGVldC4iKSk7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIGxvY2sgKHRoaXMpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIF92YWx1ZXMuSW5zZXJ0KDAsIGNvbHVtbkZyb20sIDAsIGNvbHVtbnMpOwogICAgICAgICAgICAgICAgX2Zvcm11bGFzLkluc2VydCgwLCBjb2x1bW5Gcm9tLCAwLCBjb2x1bW5zKTsKICAgICAgICAgICAgICAgIF9zdHlsZXMuSW5zZXJ0KDAsIGNvbHVtbkZyb20sIDAsIGNvbHVtbnMpOwogICAgICAgICAgICAgICAgX3R5cGVzLkluc2VydCgwLCBjb2x1bW5Gcm9tLCAwLCBjb2x1bW5zKTsKICAgICAgICAgICAgICAgIF9jb21tZW50c1N0b3JlLkluc2VydCgwLCBjb2x1bW5Gcm9tLCAwLCBjb2x1bW5zKTsKICAgICAgICAgICAgICAgIF9oeXBlckxpbmtzLkluc2VydCgwLCBjb2x1bW5Gcm9tLCAwLCBjb2x1bW5zKTsKICAgICAgICAgICAgICAgIF9mbGFncy5JbnNlcnQoMCwgY29sdW1uRnJvbSwgMCwgY29sdW1ucyk7CgogICAgICAgICAgICAgICAgZm9yZWFjaCAodmFyIGYgaW4gX3NoYXJlZEZvcm11bGFzLlZhbHVlcykKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICBpZiAoZi5TdGFydENvbCA+PSBjb2x1bW5Gcm9tKSBmLlN0YXJ0Q29sICs9IGNvbHVtbnM7CiAgICAgICAgICAgICAgICAgICAgdmFyIGEgPSBuZXcgRXhjZWxBZGRyZXNzQmFzZShmLkFkZHJlc3MpOwogICAgICAgICAgICAgICAgICAgIGlmIChhLl9mcm9tQ29sID49IGNvbHVtbkZyb20pCiAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICBhLl9mcm9tQ29sICs9IGNvbHVtbnM7CiAgICAgICAgICAgICAgICAgICAgICAgIGEuX3RvQ29sICs9IGNvbHVtbnM7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIGVsc2UgaWYgKGEuX3RvQ29sID49IGNvbHVtbkZyb20pCiAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICBhLl90b0NvbCArPSBjb2x1bW5zOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICBmLkFkZHJlc3MgPSBFeGNlbEFkZHJlc3NCYXNlLkdldEFkZHJlc3MoYS5fZnJvbVJvdywgYS5fZnJvbUNvbCwgYS5fdG9Sb3csIGEuX3RvQ29sKTsKICAgICAgICAgICAgICAgICAgICBmLkZvcm11bGEgPSBFeGNlbENlbGxCYXNlLlVwZGF0ZUZvcm11bGFSZWZlcmVuY2VzKGYuRm9ybXVsYSwgMCwgY29sdW1ucywgMCwgY29sdW1uRnJvbSk7CiAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgdmFyIGNzZSA9IG5ldyBDZWxsc1N0b3JlRW51bWVyYXRvcjxvYmplY3Q+KF9mb3JtdWxhcyk7CiAgICAgICAgICAgICAgICB3aGlsZSAoY3NlLk5leHQoKSkKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICBpZiAoY3NlLlZhbHVlIGlzIHN0cmluZykKICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgIGNzZS5WYWx1ZSA9IEV4Y2VsQ2VsbEJhc2UuVXBkYXRlRm9ybXVsYVJlZmVyZW5jZXMoY3NlLlZhbHVlLlRvU3RyaW5nKCksIDAsIGNvbHVtbnMsIDAsIGNvbHVtbkZyb20pOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICBGaXhNZXJnZWRDZWxsc0NvbHVtbihjb2x1bW5Gcm9tLCBjb2x1bW5zLCBmYWxzZSk7CgogICAgICAgICAgICAgICAgdmFyIGNzZWMgPSBuZXcgQ2VsbHNTdG9yZUVudW1lcmF0b3I8b2JqZWN0PihfdmFsdWVzLCAwLCAxLCAwLCBFeGNlbFBhY2thZ2UuTWF4Q29sdW1ucyk7CiAgICAgICAgICAgICAgICB2YXIgbHN0ID0gbmV3IExpc3Q8RXhjZWxDb2x1bW4+KCk7CiAgICAgICAgICAgICAgICBmb3JlYWNoICh2YXIgY29sIGluIGNzZWMpCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgaWYgKGNvbCBpcyBFeGNlbENvbHVtbikKICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgIGxzdC5BZGQoKEV4Y2VsQ29sdW1uKWNvbCk7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgIGZvciAoaW50IGkgPSBsc3QuQ291bnQtMTsgaSA+PSAwOyBpLS0pCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgdmFyIGMgPSBsc3RbaV07CiAgICAgICAgICAgICAgICAgICAgaWYgKGMuX2NvbHVtbk1pbiA+PSBjb2x1bW5Gcm9tKQogICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGMuX2NvbHVtbk1pbiArIGNvbHVtbnMgPD0gRXhjZWxQYWNrYWdlLk1heENvbHVtbnMpCiAgICAgICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGMuX2NvbHVtbk1pbiArPSBjb2x1bW5zOwogICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgICAgIGVsc2UKICAgICAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgYy5fY29sdW1uTWluID0gRXhjZWxQYWNrYWdlLk1heENvbHVtbnM7CiAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChjLl9jb2x1bW5NYXggKyBjb2x1bW5zIDw9IEV4Y2VsUGFja2FnZS5NYXhDb2x1bW5zKQogICAgICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjLl9jb2x1bW5NYXggKz0gY29sdW1uczsKICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICAgICBlbHNlCiAgICAgICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGMuX2NvbHVtbk1heCA9IEV4Y2VsUGFja2FnZS5NYXhDb2x1bW5zOwogICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIGVsc2UgaWYgKGMuX2NvbHVtbk1heCA+PSBjb2x1bW5Gcm9tKQogICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgdmFyIGNjID0gYy5fY29sdW1uTWF4IC0gY29sdW1uRnJvbTsKICAgICAgICAgICAgICAgICAgICAgICAgYy5fY29sdW1uTWF4ID0gY29sdW1uRnJvbSAtIDE7CiAgICAgICAgICAgICAgICAgICAgICAgIENvcHlDb2x1bW4oYywgY29sdW1uRnJvbSArIGNvbHVtbnMsIGNvbHVtbkZyb20gKyBjb2x1bW5zICsgY2MpOwogICAgICAgICAgICAgICAgICAgIH0gICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgfQoKCiAgICAgICAgICAgICAgICBpZiAoY29weVN0eWxlc0Zyb21Db2x1bW4gPiAwKQogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIGZvciAodmFyIGMgPSAwOyBjIDwgY29sdW1uczsgYysrKQogICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgdmFyIGNvbCA9IHRoaXMuQ29sdW1uKGNvbHVtbkZyb20gKyBjKTsKICAgICAgICAgICAgICAgICAgICAgICAgY29sLlN0eWxlSUQgPSB0aGlzLkNvbHVtbihjb3B5U3R5bGVzRnJvbUNvbHVtbikuU3R5bGVJRDsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAvL0FkanVzdCB0YWJsZXMKICAgICAgICAgICAgICAgIGZvcmVhY2ggKHZhciB0YmwgaW4gVGFibGVzKQogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIGlmIChjb2x1bW5Gcm9tID4gdGJsLkFkZHJlc3MuU3RhcnQuQ29sdW1uICYmIGNvbHVtbkZyb20gPD0gdGJsLkFkZHJlc3MuRW5kLkNvbHVtbikKICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgIEluc2VydFRhYmxlQ29sdW1ucyhjb2x1bW5Gcm9tLCBjb2x1bW5zLCB0YmwpOwogICAgICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICAgICAgdGJsLkFkZHJlc3M9dGJsLkFkZHJlc3MuQWRkQ29sdW1uKGNvbHVtbkZyb20sIGNvbHVtbnMpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICBwcml2YXRlIHN0YXRpYyB2b2lkIEluc2VydFRhYmxlQ29sdW1ucyhpbnQgY29sdW1uRnJvbSwgaW50IGNvbHVtbnMsIEV4Y2VsVGFibGUgdGJsKQogICAgICAgIHsKICAgICAgICAgICAgdmFyIG5vZGUgPSB0YmwuQ29sdW1uc1swXS5Ub3BOb2RlLlBhcmVudE5vZGU7CiAgICAgICAgICAgIHZhciBpeCA9IGNvbHVtbkZyb20gLSB0YmwuQWRkcmVzcy5TdGFydC5Db2x1bW4gLSAxOwogICAgICAgICAgICB2YXIgaW5zUG9zID0gbm9kZS5DaGlsZE5vZGVzW2l4XTsKICAgICAgICAgICAgaXggKz0gMjsKICAgICAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBjb2x1bW5zOyBpKyspCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIHZhciBuYW1lID0KICAgICAgICAgICAgICAgICAgICB0YmwuQ29sdW1ucy5HZXRVbmlxdWVOYW1lKHN0cmluZy5Gb3JtYXQoIkNvbHVtbnswfSIsCiAgICAgICAgICAgICAgICAgICAgICAgIChpeCsrKS5Ub1N0cmluZyhDdWx0dXJlSW5mby5JbnZhcmlhbnRDdWx0dXJlKSkpOwogICAgICAgICAgICAgICAgWG1sRWxlbWVudCB0YWJsZUNvbHVtbiA9CiAgICAgICAgICAgICAgICAgICAgKFhtbEVsZW1lbnQpIHRibC5UYWJsZVhtbC5DcmVhdGVOb2RlKFhtbE5vZGVUeXBlLkVsZW1lbnQsICJ0YWJsZUNvbHVtbiIsIEV4Y2VsUGFja2FnZS5zY2hlbWFNYWluKTsKICAgICAgICAgICAgICAgIHRhYmxlQ29sdW1uLlNldEF0dHJpYnV0ZSgiaWQiLCAodGJsLkNvbHVtbnMuQ291bnQgKyBpICsgMSkuVG9TdHJpbmcoQ3VsdHVyZUluZm8uSW52YXJpYW50Q3VsdHVyZSkpOwogICAgICAgICAgICAgICAgdGFibGVDb2x1bW4uU2V0QXR0cmlidXRlKCJuYW1lIiwgbmFtZSk7CiAgICAgICAgICAgICAgICBpbnNQb3MgPSBub2RlLkluc2VydEFmdGVyKHRhYmxlQ29sdW1uLCBpbnNQb3MpOwogICAgICAgICAgICB9IC8vQ3JlYXRlIHRibCBDb2x1bW4KICAgICAgICAgICAgdGJsLl9jb2xzID0gbmV3IEV4Y2VsVGFibGVDb2x1bW5Db2xsZWN0aW9uKHRibCk7CiAgICAgICAgfQoKICAgICAgICAvLy8gPHN1bW1hcnk+CiAgICAgICAgLy8vIEFkZHMgYSB2YWx1ZSB0byB0aGUgcm93IG9mIG1lcmdlZCBjZWxscyB0byBmaXggZm9yIGluc2VydHMgb3IgZGVsZXRlcwogICAgICAgIC8vLyA8L3N1bW1hcnk+CiAgICAgICAgLy8vIDxwYXJhbSBuYW1lPSJyb3ciPjwvcGFyYW0+CiAgICAgICAgLy8vIDxwYXJhbSBuYW1lPSJyb3dzIj48L3BhcmFtPiAKICAgICAgICAvLy8gPHBhcmFtIG5hbWU9ImRlbGV0ZSI+PC9wYXJhbT4KICAgICAgICBwcml2YXRlIHZvaWQgRml4TWVyZ2VkQ2VsbHNSb3coaW50IHJvdywgaW50IHJvd3MsIGJvb2wgZGVsZXRlKQogICAgICAgIHsKICAgICAgICAgICAgaWYgKGRlbGV0ZSkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgX21lcmdlZENlbGxzLl9jZWxscy5EZWxldGUocm93LCAwLCByb3dzLCAwKTsKICAgICAgICAgICAgfQogICAgICAgICAgICBlbHNlCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIF9tZXJnZWRDZWxscy5fY2VsbHMuSW5zZXJ0KHJvdywgMCwgcm93cywgMCk7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIExpc3Q8aW50PiByZW1vdmVJbmRleCA9IG5ldyBMaXN0PGludD4oKTsKICAgICAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBfbWVyZ2VkQ2VsbHMuQ291bnQ7IGkrKykKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgaWYgKCFzdHJpbmcuSXNOdWxsT3JFbXB0eSggX21lcmdlZENlbGxzW2ldKSkKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICBFeGNlbEFkZHJlc3NCYXNlIGFkZHIgPSBuZXcgRXhjZWxBZGRyZXNzQmFzZShfbWVyZ2VkQ2VsbHNbaV0pLCBuZXdBZGRyOwogICAgICAgICAgICAgICAgICAgIGlmIChkZWxldGUpCiAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICBuZXdBZGRyID0gYWRkci5EZWxldGVSb3cocm93LCByb3dzKTsKICAgICAgICAgICAgICAgICAgICAgICAgaWYgKG5ld0FkZHIgPT0gbnVsbCkKICAgICAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVtb3ZlSW5kZXguQWRkKGkpOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgY29udGludWU7CiAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgZWxzZQogICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgbmV3QWRkciA9IGFkZHIuQWRkUm93KHJvdywgcm93cyk7CiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChuZXdBZGRyLkFkZHJlc3MgIT0gYWRkci5BZGRyZXNzKQogICAgICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgIC8vICAgIF9tZXJnZWRDZWxscy5fY2VsbHMuSW5zZXJ0KHJvdywgMCwgcm93cywgMCk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBfbWVyZ2VkQ2VsbHMuU2V0SW5kZXgobmV3QWRkciwgaSk7CiAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgICAgIGlmIChuZXdBZGRyLkFkZHJlc3MgIT0gYWRkci5BZGRyZXNzKQogICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgX21lcmdlZENlbGxzLkxpc3RbaV0gPSBuZXdBZGRyLl9hZGRyZXNzOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgICAgICBmb3IgKGludCBpID0gcmVtb3ZlSW5kZXguQ291bnQgLSAxOyBpID49IDA7IGktLSkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgX21lcmdlZENlbGxzLkxpc3QuUmVtb3ZlQXQocmVtb3ZlSW5kZXhbaV0pOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIC8vLyA8c3VtbWFyeT4KICAgICAgICAvLy8gQWRkcyBhIHZhbHVlIHRvIHRoZSByb3cgb2YgbWVyZ2VkIGNlbGxzIHRvIGZpeCBmb3IgaW5zZXJ0cyBvciBkZWxldGVzCiAgICAgICAgLy8vIDwvc3VtbWFyeT4KICAgICAgICAvLy8gPHBhcmFtIG5hbWU9ImNvbHVtbiI+PC9wYXJhbT4KICAgICAgICAvLy8gPHBhcmFtIG5hbWU9ImNvbHVtbnMiPjwvcGFyYW0+CiAgICAgICAgLy8vIDxwYXJhbSBuYW1lPSJkZWxldGUiPjwvcGFyYW0+CiAgICAgICAgcHJpdmF0ZSB2b2lkIEZpeE1lcmdlZENlbGxzQ29sdW1uKGludCBjb2x1bW4sIGludCBjb2x1bW5zLCBib29sIGRlbGV0ZSkKICAgICAgICB7CiAgICAgICAgICAgIGlmIChkZWxldGUpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIF9tZXJnZWRDZWxscy5fY2VsbHMuRGVsZXRlKDAsIGNvbHVtbiwgMCwgY29sdW1ucyk7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgZWxzZQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBfbWVyZ2VkQ2VsbHMuX2NlbGxzLkluc2VydCgwLCBjb2x1bW4sIDAsIGNvbHVtbnMpOyAgICAgICAgICAgICAgICAKICAgICAgICAgICAgfQogICAgICAgICAgICBMaXN0PGludD4gcmVtb3ZlSW5kZXggPSBuZXcgTGlzdDxpbnQ+KCk7CiAgICAgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgX21lcmdlZENlbGxzLkNvdW50OyBpKyspCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIGlmICghc3RyaW5nLklzTnVsbE9yRW1wdHkoX21lcmdlZENlbGxzW2ldKSkKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICBFeGNlbEFkZHJlc3NCYXNlIGFkZHIgPSBuZXcgRXhjZWxBZGRyZXNzQmFzZShfbWVyZ2VkQ2VsbHNbaV0pLCBuZXdBZGRyOwogICAgICAgICAgICAgICAgICAgIGlmIChkZWxldGUpCiAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICBuZXdBZGRyID0gYWRkci5EZWxldGVDb2x1bW4oY29sdW1uLCBjb2x1bW5zKTsKICAgICAgICAgICAgICAgICAgICAgICAgaWYgKG5ld0FkZHIgPT0gbnVsbCkKICAgICAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVtb3ZlSW5kZXguQWRkKGkpOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgY29udGludWU7CiAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgZWxzZQogICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgbmV3QWRkciA9IGFkZHIuQWRkQ29sdW1uKGNvbHVtbiwgY29sdW1ucyk7CiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChuZXdBZGRyLkFkZHJlc3MgIT0gYWRkci5BZGRyZXNzKQogICAgICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBfbWVyZ2VkQ2VsbHMuU2V0SW5kZXgobmV3QWRkciwgaSk7CiAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgICAgIGlmIChuZXdBZGRyLkFkZHJlc3MgIT0gYWRkci5BZGRyZXNzKQogICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgX21lcmdlZENlbGxzLkxpc3RbaV0gPSBuZXdBZGRyLl9hZGRyZXNzOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgICAgICBmb3IgKGludCBpID0gcmVtb3ZlSW5kZXguQ291bnQgLSAxOyBpID49IDA7IGktLSkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgX21lcmdlZENlbGxzLkxpc3QuUmVtb3ZlQXQocmVtb3ZlSW5kZXhbaV0pOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIHByaXZhdGUgdm9pZCBGaXhTaGFyZWRGb3JtdWxhc1Jvd3MoaW50IHBvc2l0aW9uLCBpbnQgcm93cykKICAgICAgICB7CiAgICAgICAgICAgIExpc3Q8Rm9ybXVsYXM+IGFkZGVkID0gbmV3IExpc3Q8Rm9ybXVsYXM+KCk7CiAgICAgICAgICAgIExpc3Q8Rm9ybXVsYXM+IGRlbGV0ZWQgPSBuZXcgTGlzdDxGb3JtdWxhcz4oKTsKCiAgICAgICAgICAgIGZvcmVhY2ggKGludCBpZCBpbiBfc2hhcmVkRm9ybXVsYXMuS2V5cykKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgdmFyIGYgPSBfc2hhcmVkRm9ybXVsYXNbaWRdOwogICAgICAgICAgICAgICAgaW50IGZyb21Db2wsIGZyb21Sb3csIHRvQ29sLCB0b1JvdzsKCiAgICAgICAgICAgICAgICBFeGNlbENlbGxCYXNlLkdldFJvd0NvbEZyb21BZGRyZXNzKGYuQWRkcmVzcywgb3V0IGZyb21Sb3csIG91dCBmcm9tQ29sLCBvdXQgdG9Sb3csIG91dCB0b0NvbCk7CiAgICAgICAgICAgICAgICBpZiAocG9zaXRpb24gPj0gZnJvbVJvdyAmJiBwb3NpdGlvbisoTWF0aC5BYnMocm93cykpIDw9IHRvUm93KSAvL0luc2VydC9kZWxldGUgaXMgd2hpdGhpbiB0aGUgc2hhcmUgZm9ybXVsYSBhZGRyZXNzCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgaWYgKHJvd3MgPiAwKSAvL0luc2VydAogICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgZi5BZGRyZXNzID0gRXhjZWxDZWxsQmFzZS5HZXRBZGRyZXNzKGZyb21Sb3csIGZyb21Db2wpICsgIjoiICsgRXhjZWxDZWxsQmFzZS5HZXRBZGRyZXNzKHBvc2l0aW9uIC0gMSwgdG9Db2wpOwogICAgICAgICAgICAgICAgICAgICAgICBpZiAodG9Sb3cgIT0gZnJvbVJvdykKICAgICAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgRm9ybXVsYXMgbmV3RiA9IG5ldyBGb3JtdWxhcyhTb3VyY2VDb2RlVG9rZW5pemVyLkRlZmF1bHQpOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgbmV3Ri5TdGFydENvbCA9IGYuU3RhcnRDb2w7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBuZXdGLlN0YXJ0Um93ID0gcG9zaXRpb24gKyByb3dzOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgbmV3Ri5BZGRyZXNzID0gRXhjZWxDZWxsQmFzZS5HZXRBZGRyZXNzKHBvc2l0aW9uICsgcm93cywgZnJvbUNvbCkgKyAiOiIgKyBFeGNlbENlbGxCYXNlLkdldEFkZHJlc3ModG9Sb3cgKyByb3dzLCB0b0NvbCk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBuZXdGLkZvcm11bGEgPSBFeGNlbENlbGxCYXNlLlRyYW5zbGF0ZUZyb21SMUMxKEV4Y2VsQ2VsbEJhc2UuVHJhbnNsYXRlVG9SMUMxKGYuRm9ybXVsYSwgZi5TdGFydFJvdywgZi5TdGFydENvbCksIHBvc2l0aW9uLCBmLlN0YXJ0Q29sKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGFkZGVkLkFkZChuZXdGKTsKICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICBlbHNlCiAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICBpZiAoZnJvbVJvdyAtIHJvd3MgPCB0b1JvdykKICAgICAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgZi5BZGRyZXNzID0gRXhjZWxDZWxsQmFzZS5HZXRBZGRyZXNzKGZyb21Sb3csIGZyb21Db2wsIHRvUm93K3Jvd3MsIHRvQ29sKTsKICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICAgICBlbHNlCiAgICAgICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGYuQWRkcmVzcyA9IEV4Y2VsQ2VsbEJhc2UuR2V0QWRkcmVzcyhmcm9tUm93LCBmcm9tQ29sKSArICI6IiArIEV4Y2VsQ2VsbEJhc2UuR2V0QWRkcmVzcyh0b1JvdyArIHJvd3MsIHRvQ29sKTsKICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGVsc2UgaWYgKHBvc2l0aW9uIDw9IHRvUm93KQogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIGlmIChyb3dzID4gMCkgLy9JbnNlcnQgYmVmb3JlIHNoaWZ0IGRvd24KICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgIGYuU3RhcnRSb3cgKz0gcm93czsKICAgICAgICAgICAgICAgICAgICAgICAgLy9mLkZvcm11bGEgPSBFeGNlbENlbGwuVXBkYXRlRm9ybXVsYVJlZmVyZW5jZXMoZi5Gb3JtdWxhLCByb3dzLCAwLCBwb3NpdGlvbiwgMCk7IC8vUmVjYWxjIHRoZSBjZWxscyBwb3NpdGlvbnMKICAgICAgICAgICAgICAgICAgICAgICAgZi5BZGRyZXNzID0gRXhjZWxDZWxsQmFzZS5HZXRBZGRyZXNzKGZyb21Sb3cgKyByb3dzLCBmcm9tQ29sKSArICI6IiArIEV4Y2VsQ2VsbEJhc2UuR2V0QWRkcmVzcyh0b1JvdyArIHJvd3MsIHRvQ29sKTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgZWxzZQogICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgLy9DZWxsc1tmLkFkZHJlc3NdLlNldFNoYXJlZEZvcm11bGFJRChpbnQuTWluVmFsdWUpOwogICAgICAgICAgICAgICAgICAgICAgICBpZiAocG9zaXRpb24gPD0gZnJvbVJvdyAmJiBwb3NpdGlvbiArIE1hdGguQWJzKHJvd3MpID4gdG9Sb3cpICAvL0RlbGV0ZSB0aGUgZm9ybXVsYSAKICAgICAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgZGVsZXRlZC5BZGQoZik7CiAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgZWxzZQogICAgICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0b1JvdyA9IHRvUm93ICsgcm93cyA8IHBvc2l0aW9uIC0gMSA/IHBvc2l0aW9uIC0gMSA6IHRvUm93ICsgcm93czsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChwb3NpdGlvbiA8PSBmcm9tUm93KQogICAgICAgICAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZyb21Sb3cgPSBmcm9tUm93ICsgcm93cyA8IHBvc2l0aW9uID8gcG9zaXRpb24gOiBmcm9tUm93ICsgcm93czsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBmLkFkZHJlc3MgPSBFeGNlbENlbGxCYXNlLkdldEFkZHJlc3MoZnJvbVJvdywgZnJvbUNvbCwgdG9Sb3csIHRvQ29sKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIENlbGxzW2YuQWRkcmVzc10uU2V0U2hhcmVkRm9ybXVsYUlEKGYuSW5kZXgpOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgLy9mLlN0YXJ0Um93ID0gZnJvbVJvdzsKCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAvL2YuRm9ybXVsYSA9IEV4Y2VsQ2VsbC5VcGRhdGVGb3JtdWxhUmVmZXJlbmNlcyhmLkZvcm11bGEsIHJvd3MsIDAsIHBvc2l0aW9uLCAwKTsKICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQoKICAgICAgICAgICAgQWRkRm9ybXVsYXMoYWRkZWQsIHBvc2l0aW9uLCByb3dzKTsKCiAgICAgICAgICAgIC8vUmVtb3ZlIGZvcm11bGFzCiAgICAgICAgICAgIGZvcmVhY2ggKEZvcm11bGFzIGYgaW4gZGVsZXRlZCkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgX3NoYXJlZEZvcm11bGFzLlJlbW92ZShmLkluZGV4KTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgLy9GaXggRm9ybXVsYXMKICAgICAgICAgICAgYWRkZWQgPSBuZXcgTGlzdDxGb3JtdWxhcz4oKTsKICAgICAgICAgICAgZm9yZWFjaCAoaW50IGlkIGluIF9zaGFyZWRGb3JtdWxhcy5LZXlzKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICB2YXIgZiA9IF9zaGFyZWRGb3JtdWxhc1tpZF07CiAgICAgICAgICAgICAgICBVcGRhdGVTaGFyZWRGb3JtdWxhUm93KHJlZiBmLCBwb3NpdGlvbiwgcm93cywgcmVmIGFkZGVkKTsKICAgICAgICAgICAgfQogICAgICAgICAgICBBZGRGb3JtdWxhcyhhZGRlZCwgcG9zaXRpb24sIHJvd3MpOwogICAgICAgIH0KCiAgICAgICAgcHJpdmF0ZSB2b2lkIEFkZEZvcm11bGFzKExpc3Q8Rm9ybXVsYXM+IGFkZGVkLCBpbnQgcG9zaXRpb24sIGludCByb3dzKQogICAgICAgIHsKICAgICAgICAgICAgLy9BZGQgbmV3IGZvcm11bGFzCiAgICAgICAgICAgIGZvcmVhY2ggKEZvcm11bGFzIGYgaW4gYWRkZWQpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIGYuSW5kZXggPSBHZXRNYXhTaGFyZUZ1bmN0aW9uSW5kZXgoZmFsc2UpOwogICAgICAgICAgICAgICAgX3NoYXJlZEZvcm11bGFzLkFkZChmLkluZGV4LCBmKTsKICAgICAgICAgICAgICAgIENlbGxzW2YuQWRkcmVzc10uU2V0U2hhcmVkRm9ybXVsYUlEKGYuSW5kZXgpOwogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICBwcml2YXRlIHZvaWQgVXBkYXRlU2hhcmVkRm9ybXVsYVJvdyhyZWYgRm9ybXVsYXMgZm9ybXVsYSwgaW50IHN0YXJ0Um93LCBpbnQgcm93cywgcmVmIExpc3Q8Rm9ybXVsYXM+IG5ld0Zvcm11bGFzKQogICAgICAgIHsKICAgICAgICAgICAgaW50IGZyb21Sb3csZnJvbUNvbCwgdG9Sb3csIHRvQ29sOwogICAgICAgICAgICBpbnQgbmV3Rm9ybXVsYXNDb3VudCA9IG5ld0Zvcm11bGFzLkNvdW50OwogICAgICAgICAgICBFeGNlbENlbGxCYXNlLkdldFJvd0NvbEZyb21BZGRyZXNzKGZvcm11bGEuQWRkcmVzcywgb3V0IGZyb21Sb3csIG91dCBmcm9tQ29sLCBvdXQgdG9Sb3csIG91dCB0b0NvbCk7CiAgICAgICAgICAgIC8vaW50IHJlZlNwbGl0cyA9IFJlZ2V4LlNwbGl0KGZvcm11bGEuRm9ybXVsYSwgIiNSRUYhIikuR2V0VXBwZXJCb3VuZCgwKTsKICAgICAgICAgICAgc3RyaW5nIGZvcm11YWxSMUMxOwogICAgICAgICAgICBpZiAocm93cyA+IDAgfHwgZnJvbVJvdyA8PSBzdGFydFJvdykKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgZm9ybXVhbFIxQzEgPSBFeGNlbFJhbmdlQmFzZS5UcmFuc2xhdGVUb1IxQzEoZm9ybXVsYS5Gb3JtdWxhLCBmb3JtdWxhLlN0YXJ0Um93LCBmb3JtdWxhLlN0YXJ0Q29sKTsKICAgICAgICAgICAgICAgIGZvcm11bGEuRm9ybXVsYSA9IEV4Y2VsUmFuZ2VCYXNlLlRyYW5zbGF0ZUZyb21SMUMxKGZvcm11YWxSMUMxLCBmcm9tUm93LCBmb3JtdWxhLlN0YXJ0Q29sKTsKICAgICAgICAgICAgfQogICAgICAgICAgICBlbHNlCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIGZvcm11YWxSMUMxID0gRXhjZWxSYW5nZUJhc2UuVHJhbnNsYXRlVG9SMUMxKGZvcm11bGEuRm9ybXVsYSwgZm9ybXVsYS5TdGFydFJvdy1yb3dzLCBmb3JtdWxhLlN0YXJ0Q29sKTsKICAgICAgICAgICAgICAgIGZvcm11bGEuRm9ybXVsYSA9IEV4Y2VsUmFuZ2VCYXNlLlRyYW5zbGF0ZUZyb21SMUMxKGZvcm11YWxSMUMxLCBmb3JtdWxhLlN0YXJ0Um93LCBmb3JtdWxhLlN0YXJ0Q29sKTsKICAgICAgICAgICAgfQogICAgICAgICAgICAvL2Jvb2wgaXNSZWYgPSBmYWxzZTsKICAgICAgICAgICAgLy9Gb3JtdWxhcyByZXN0Rm9ybXVsYT1mb3JtdWxhOwogICAgICAgICAgICBzdHJpbmcgcHJldkZvcm11YWxSMUMxID0gZm9ybXVhbFIxQzE7CiAgICAgICAgICAgIGZvciAoaW50IHJvdyA9IGZyb21Sb3c7IHJvdyA8PSB0b1Jvdzsgcm93KyspCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIGZvciAoaW50IGNvbCA9IGZyb21Db2w7IGNvbCA8PSB0b0NvbDsgY29sKyspCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgc3RyaW5nIG5ld0Zvcm11bGE7CiAgICAgICAgICAgICAgICAgICAgc3RyaW5nIGN1cnJlbnRGb3JtdWxhUjFDMTsKICAgICAgICAgICAgICAgICAgICBpZiAocm93cyA+IDAgfHwgcm93IDwgc3RhcnRSb3cpCiAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICBuZXdGb3JtdWxhID0gRXhjZWxDZWxsQmFzZS5VcGRhdGVGb3JtdWxhUmVmZXJlbmNlcyhFeGNlbENlbGxCYXNlLlRyYW5zbGF0ZUZyb21SMUMxKGZvcm11YWxSMUMxLCByb3csIGNvbCksIHJvd3MsIDAsIHN0YXJ0Um93LCAwKTsKICAgICAgICAgICAgICAgICAgICAgICAgY3VycmVudEZvcm11bGFSMUMxID0gRXhjZWxSYW5nZUJhc2UuVHJhbnNsYXRlVG9SMUMxKG5ld0Zvcm11bGEsIHJvdywgY29sKTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgZWxzZQogICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgbmV3Rm9ybXVsYSA9IEV4Y2VsQ2VsbEJhc2UuVXBkYXRlRm9ybXVsYVJlZmVyZW5jZXMoRXhjZWxDZWxsQmFzZS5UcmFuc2xhdGVGcm9tUjFDMShmb3JtdWFsUjFDMSwgcm93LXJvd3MsIGNvbCksIHJvd3MsIDAsIHN0YXJ0Um93LCAwKTsKICAgICAgICAgICAgICAgICAgICAgICAgY3VycmVudEZvcm11bGFSMUMxID0gRXhjZWxSYW5nZUJhc2UuVHJhbnNsYXRlVG9SMUMxKG5ld0Zvcm11bGEsIHJvdywgY29sKTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgaWYgKGN1cnJlbnRGb3JtdWxhUjFDMSAhPSBwcmV2Rm9ybXVhbFIxQzEpIC8vbmV3Rm9ybXVsYS5Db250YWlucygiI1JFRiEiKSkKICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgIC8vaWYgKHJlZlNwbGl0cyA9PSAwIHx8IFJlZ2V4LlNwbGl0KG5ld0Zvcm11bGEsICIjUkVGISIpLkdldFVwcGVyQm91bmQoMCkgIT0gcmVmU3BsaXRzKQogICAgICAgICAgICAgICAgICAgICAgICAvL3sKICAgICAgICAgICAgICAgICAgICAgICAgLy9pc1JlZiA9IHRydWU7CiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChyb3cgPT0gZnJvbVJvdyAmJiBjb2wgPT0gZnJvbUNvbCkKICAgICAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgZm9ybXVsYS5Gb3JtdWxhID0gbmV3Rm9ybXVsYTsKICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICAgICBlbHNlCiAgICAgICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChuZXdGb3JtdWxhcy5Db3VudCA9PSBuZXdGb3JtdWxhc0NvdW50KQogICAgICAgICAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZvcm11bGEuQWRkcmVzcyA9IEV4Y2VsQ2VsbEJhc2UuR2V0QWRkcmVzcyhmb3JtdWxhLlN0YXJ0Um93LCBmb3JtdWxhLlN0YXJ0Q29sLCByb3cgLSAxLCBjb2wpOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICAgICAgICAgZWxzZQogICAgICAgICAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5ld0Zvcm11bGFzW25ld0Zvcm11bGFzLkNvdW50IC0gMV0uQWRkcmVzcyA9IEV4Y2VsQ2VsbEJhc2UuR2V0QWRkcmVzcyhuZXdGb3JtdWxhc1tuZXdGb3JtdWxhcy5Db3VudCAtIDFdLlN0YXJ0Um93LCBuZXdGb3JtdWxhc1tuZXdGb3JtdWxhcy5Db3VudCAtIDFdLlN0YXJ0Q29sLCByb3cgLSAxLCBjb2wpOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICAgICAgICAgdmFyIHJlZkZvcm11bGEgPSBuZXcgRm9ybXVsYXMoU291cmNlQ29kZVRva2VuaXplci5EZWZhdWx0KTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlZkZvcm11bGEuRm9ybXVsYSA9IG5ld0Zvcm11bGE7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICByZWZGb3JtdWxhLlN0YXJ0Um93ID0gcm93OwogICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVmRm9ybXVsYS5TdGFydENvbCA9IGNvbDsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5ld0Zvcm11bGFzLkFkZChyZWZGb3JtdWxhKTsKCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAvL3Jlc3RGb3JtdWxhID0gbnVsbDsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHByZXZGb3JtdWFsUjFDMSA9IGN1cnJlbnRGb3JtdWxhUjFDMTsKICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAvLyAgICB9CiAgICAgICAgICAgICAgICAgICAgLy8gICAgZWxzZQogICAgICAgICAgICAgICAgICAgIC8vICAgIHsKICAgICAgICAgICAgICAgICAgICAvLyAgICAgICAgaXNSZWYgPSBmYWxzZTsKICAgICAgICAgICAgICAgICAgICAvLyAgICB9CiAgICAgICAgICAgICAgICAgICAgLy99CiAgICAgICAgICAgICAgICAgICAgLy9lbHNlCiAgICAgICAgICAgICAgICAgICAgLy97CiAgICAgICAgICAgICAgICAgICAgLy8gICAgaXNSZWYgPSBmYWxzZTsKICAgICAgICAgICAgICAgICAgICAvL30KICAgICAgICAgICAgICAgICAgICAvL2lmIChyZXN0Rm9ybXVsYT09bnVsbCkKICAgICAgICAgICAgICAgICAgICAvL3sKICAgICAgICAgICAgICAgICAgICAgICAgLy9pZiAobmV3Rm9ybXVsYXMuQ291bnQgPT0gbmV3Rm9ybXVsYXNDb3VudCkKICAgICAgICAgICAgICAgICAgICAgICAgLy97CiAgICAgICAgICAgICAgICAgICAgICAgIC8vICAgIGZvcm11bGEuQWRkcmVzcyA9IEV4Y2VsQ2VsbEJhc2UuR2V0QWRkcmVzcyhmb3JtdWxhLlN0YXJ0Um93LCBmb3JtdWxhLlN0YXJ0Q29sLCByb3cgLSAxLCBjb2wpOwogICAgICAgICAgICAgICAgICAgICAgICAvL30KICAgICAgICAgICAgICAgICAgICAgICAgLy9lbHNlCiAgICAgICAgICAgICAgICAgICAgICAgIC8vewovLyAgICAgICAgICAgICAgICAgICAgICAgICAgICBuZXdGb3JtdWxhc1tuZXdGb3JtdWxhcy5Db3VudCAtIDFdLkFkZHJlc3MgPSBFeGNlbENlbGxCYXNlLkdldEFkZHJlc3MobmV3Rm9ybXVsYXNbbmV3Rm9ybXVsYXMuQ291bnQgLSAxXS5TdGFydFJvdywgbmV3Rm9ybXVsYXNbMF0uU3RhcnRDb2wsIHJvdyAtIDEsIGNvbCk7CiAgICAgICAgICAgICAgICAgICAgICAgIC8vfQoKICAgICAgICAgICAgICAgICAgICAgICAgLy9yZXN0Rm9ybXVsYSA9IG5ldyBGb3JtdWxhcygpOwogICAgICAgICAgICAgICAgICAgICAgICAvL3Jlc3RGb3JtdWxhLkZvcm11bGEgPSBuZXdGb3JtdWxhOwogICAgICAgICAgICAgICAgICAgICAgICAvL3Jlc3RGb3JtdWxhLlN0YXJ0Um93ID0gcm93OwogICAgICAgICAgICAgICAgICAgICAgICAvL3Jlc3RGb3JtdWxhLlN0YXJ0Q29sID0gY29sOwogICAgICAgICAgICAgICAgICAgICAgICAvL25ld0Zvcm11bGFzLkFkZChyZXN0Rm9ybXVsYSk7CiAgICAgICAgICAgICAgICAgICAgLy99CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICAgICAgaWYgKHJvd3MgPCAwICYmIGZvcm11bGEuU3RhcnRSb3cgPiBzdGFydFJvdykKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgaWYgKGZvcm11bGEuU3RhcnRSb3cgKyByb3dzIDwgc3RhcnRSb3cpCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgZm9ybXVsYS5TdGFydFJvdyA9IHN0YXJ0Um93OwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgZWxzZQogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIGZvcm11bGEuU3RhcnRSb3cgKz0gcm93czsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgICAgICBpZiAobmV3Rm9ybXVsYXMuQ291bnQgPiBuZXdGb3JtdWxhc0NvdW50KQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBuZXdGb3JtdWxhc1tuZXdGb3JtdWxhcy5Db3VudCAtIDFdLkFkZHJlc3MgPSBFeGNlbENlbGxCYXNlLkdldEFkZHJlc3MobmV3Rm9ybXVsYXNbbmV3Rm9ybXVsYXMuQ291bnQgLSAxXS5TdGFydFJvdywgbmV3Rm9ybXVsYXNbbmV3Rm9ybXVsYXMuQ291bnQgLSAxXS5TdGFydENvbCwgdG9Sb3csIHRvQ29sKTsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgICAgICAjZW5kcmVnaW9uCgogICAgICAgICNyZWdpb24gRGVsZXRlUm93CiAgICAgICAgLy8vIDxzdW1tYXJ5PgogICAgICAgIC8vLyBEZWxldGUgdGhlIHNwZWNpZmllZCByb3cgZnJvbSB0aGUgd29ya3NoZWV0LgogICAgICAgIC8vLyA8L3N1bW1hcnk+CiAgICAgICAgLy8vIDxwYXJhbSBuYW1lPSJyb3ciPkEgcm93IHRvIGJlIGRlbGV0ZWQ8L3BhcmFtPgogICAgICAgIHB1YmxpYyB2b2lkIERlbGV0ZVJvdyhpbnQgcm93KQogICAgICAgIHsKICAgICAgICAgICAgRGVsZXRlUm93KHJvdywgMSk7CiAgICAgICAgfQogICAgICAgIC8vLyA8c3VtbWFyeT4KICAgICAgICAvLy8gRGVsZXRlIHRoZSBzcGVjaWZpZWQgcm93IGZyb20gdGhlIHdvcmtzaGVldC4KICAgICAgICAvLy8gPC9zdW1tYXJ5PgogICAgICAgIC8vLyA8cGFyYW0gbmFtZT0icm93RnJvbSI+VGhlIHN0YXJ0IHJvdzwvcGFyYW0+CiAgICAgICAgLy8vIDxwYXJhbSBuYW1lPSJyb3dzIj5OdW1iZXIgb2Ygcm93cyB0byBkZWxldGU8L3BhcmFtPgogICAgICAgIHB1YmxpYyB2b2lkIERlbGV0ZVJvdyhpbnQgcm93RnJvbSwgaW50IHJvd3MpCiAgICAgICAgewogICAgICAgICAgICBDaGVja1NoZWV0VHlwZSgpOwogICAgICAgICAgICBpZiAocm93RnJvbSA8IDEgfHwgcm93RnJvbSArIHJvd3MgPiBFeGNlbFBhY2thZ2UuTWF4Um93cykKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgdGhyb3cobmV3IEFyZ3VtZW50RXhjZXB0aW9uKCJSb3cgb3V0IG9mIHJhbmdlLiBTcGFucyBmcm9tIDEgdG8gIiArIEV4Y2VsUGFja2FnZS5NYXhSb3dzLlRvU3RyaW5nKEN1bHR1cmVJbmZvLkludmFyaWFudEN1bHR1cmUpKSk7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgbG9jayAodGhpcykKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgX3ZhbHVlcy5EZWxldGUocm93RnJvbSwgMCwgcm93cywgRXhjZWxQYWNrYWdlLk1heENvbHVtbnMpOwogICAgICAgICAgICAgICAgX3R5cGVzLkRlbGV0ZShyb3dGcm9tLCAwLCByb3dzLCBFeGNlbFBhY2thZ2UuTWF4Q29sdW1ucyk7CiAgICAgICAgICAgICAgICBfZm9ybXVsYXMuRGVsZXRlKHJvd0Zyb20sIDAsIHJvd3MsIEV4Y2VsUGFja2FnZS5NYXhDb2x1bW5zKTsKICAgICAgICAgICAgICAgIF9zdHlsZXMuRGVsZXRlKHJvd0Zyb20sIDAsIHJvd3MsIEV4Y2VsUGFja2FnZS5NYXhDb2x1bW5zKTsKICAgICAgICAgICAgICAgIF9mbGFncy5EZWxldGUocm93RnJvbSwgMCwgcm93cywgRXhjZWxQYWNrYWdlLk1heENvbHVtbnMpOwogICAgICAgICAgICAgICAgX2NvbW1lbnRzU3RvcmUuRGVsZXRlKHJvd0Zyb20sIDAsIHJvd3MsIEV4Y2VsUGFja2FnZS5NYXhDb2x1bW5zKTsKICAgICAgICAgICAgICAgIF9oeXBlckxpbmtzLkRlbGV0ZShyb3dGcm9tLCAwLCByb3dzLCBFeGNlbFBhY2thZ2UuTWF4Q29sdW1ucyk7CgogICAgICAgICAgICAgICAgQWRqdXN0Rm9ybXVsYXNSb3cocm93RnJvbSwgcm93cyk7CiAgICAgICAgICAgICAgICBGaXhNZXJnZWRDZWxsc1Jvdyhyb3dGcm9tLCByb3dzLCB0cnVlKTsKCiAgICAgICAgICAgICAgICBmb3JlYWNoICh2YXIgdGJsIGluIFRhYmxlcykKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICB0YmwuQWRkcmVzcyA9IHRibC5BZGRyZXNzLkRlbGV0ZVJvdyhyb3dGcm9tLCByb3dzKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgIH0KICAgICAgICAvLy8gPHN1bW1hcnk+CiAgICAgICAgLy8vIERlbGV0ZSB0aGUgc3BlY2lmaWVkIGNvbHVtbiBmcm9tIHRoZSB3b3Jrc2hlZXQuCiAgICAgICAgLy8vIDwvc3VtbWFyeT4KICAgICAgICAvLy8gPHBhcmFtIG5hbWU9ImNvbHVtbiI+VGhlIGNvbHVtbiB0byBiZSBkZWxldGVkPC9wYXJhbT4KICAgICAgICBwdWJsaWMgdm9pZCBEZWxldGVDb2x1bW4oaW50IGNvbHVtbikKICAgICAgICB7CiAgICAgICAgICAgIERlbGV0ZUNvbHVtbihjb2x1bW4sMSk7CiAgICAgICAgfQogICAgICAgIC8vLyA8c3VtbWFyeT4KICAgICAgICAvLy8gRGVsZXRlIHRoZSBzcGVjaWZpZWQgY29sdW1uIGZyb20gdGhlIHdvcmtzaGVldC4KICAgICAgICAvLy8gPC9zdW1tYXJ5PgogICAgICAgIC8vLyA8cGFyYW0gbmFtZT0iY29sdW1uRnJvbSI+VGhlIHN0YXJ0IGNvbHVtbjwvcGFyYW0+CiAgICAgICAgLy8vIDxwYXJhbSBuYW1lPSJjb2x1bW5zIj5OdW1iZXIgb2YgY29sdW1ucyB0byBkZWxldGU8L3BhcmFtPgogICAgICAgIHB1YmxpYyB2b2lkIERlbGV0ZUNvbHVtbihpbnQgY29sdW1uRnJvbSwgaW50IGNvbHVtbnMpCiAgICAgICAgewogICAgICAgICAgICBpZiAoY29sdW1uRnJvbSA8IDEgfHwgY29sdW1uRnJvbSArIGNvbHVtbnMgPiBFeGNlbFBhY2thZ2UuTWF4Q29sdW1ucykKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgdGhyb3cgKG5ldyBBcmd1bWVudEV4Y2VwdGlvbigiQ29sdW1uIG91dCBvZiByYW5nZS4gU3BhbnMgZnJvbSAxIHRvICIgKyBFeGNlbFBhY2thZ2UuTWF4Q29sdW1ucy5Ub1N0cmluZyhDdWx0dXJlSW5mby5JbnZhcmlhbnRDdWx0dXJlKSkpOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGxvY2sgKHRoaXMpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIHZhciBjb2wgPSBfdmFsdWVzLkdldFZhbHVlKDAsIGNvbHVtbkZyb20pIGFzIEV4Y2VsQ29sdW1uOwogICAgICAgICAgICAgICAgaWYgKGNvbCA9PSBudWxsKQogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIHZhciByID0gMDsgCiAgICAgICAgICAgICAgICAgICAgdmFyIGMgPSBjb2x1bW5Gcm9tOwogICAgICAgICAgICAgICAgICAgIGlmKF92YWx1ZXMuUHJldkNlbGwocmVmIHIscmVmIGMpKQogICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgY29sID0gX3ZhbHVlcy5HZXRWYWx1ZSgwLCBjKSBhcyBFeGNlbENvbHVtbjsKICAgICAgICAgICAgICAgICAgICAgICAgaWYoY29sLl9jb2x1bW5NYXggPj0gY29sdW1uRnJvbSkKICAgICAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgY29sLkNvbHVtbk1heD1jb2x1bW5Gcm9tLTE7CiAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgX3ZhbHVlcy5EZWxldGUoMCwgY29sdW1uRnJvbSwgRXhjZWxQYWNrYWdlLk1heFJvd3MsIGNvbHVtbnMpOwogICAgICAgICAgICAgICAgX3R5cGVzLkRlbGV0ZSgwLCBjb2x1bW5Gcm9tLCBFeGNlbFBhY2thZ2UuTWF4Um93cywgY29sdW1ucyk7CiAgICAgICAgICAgICAgICBfZm9ybXVsYXMuRGVsZXRlKDAsIGNvbHVtbkZyb20sIEV4Y2VsUGFja2FnZS5NYXhSb3dzLCBjb2x1bW5zKTsKICAgICAgICAgICAgICAgIF9zdHlsZXMuRGVsZXRlKDAsIGNvbHVtbkZyb20sIEV4Y2VsUGFja2FnZS5NYXhSb3dzLCBjb2x1bW5zKTsKICAgICAgICAgICAgICAgIF9mbGFncy5EZWxldGUoMCwgY29sdW1uRnJvbSwgRXhjZWxQYWNrYWdlLk1heFJvd3MsIGNvbHVtbnMpOwogICAgICAgICAgICAgICAgX2NvbW1lbnRzU3RvcmUuRGVsZXRlKDAsIGNvbHVtbkZyb20sIEV4Y2VsUGFja2FnZS5NYXhSb3dzLCBjb2x1bW5zKTsKICAgICAgICAgICAgICAgIF9oeXBlckxpbmtzLkRlbGV0ZSgwLCBjb2x1bW5Gcm9tLCBFeGNlbFBhY2thZ2UuTWF4Um93cywgY29sdW1ucyk7CgogICAgICAgICAgICAgICAgQWRqdXN0Rm9ybXVsYXNDb2x1bW4oY29sdW1uRnJvbSwgY29sdW1ucyk7CiAgICAgICAgICAgICAgICBGaXhNZXJnZWRDZWxsc0NvbHVtbihjb2x1bW5Gcm9tLCBjb2x1bW5zLCB0cnVlKTsKCiAgICAgICAgICAgICAgICB2YXIgY3NlYyA9IG5ldyBDZWxsc1N0b3JlRW51bWVyYXRvcjxvYmplY3Q+KF92YWx1ZXMsIDAsIGNvbHVtbkZyb20sIDAsIEV4Y2VsUGFja2FnZS5NYXhDb2x1bW5zKTsKICAgICAgICAgICAgICAgIGZvcmVhY2ggKHZhciBjb2x1bW4gaW4gY3NlYykgICAgCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgaWYgKGNvbHVtbiBpcyBFeGNlbENvbHVtbikKICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgIHZhciBjID0gKEV4Y2VsQ29sdW1uKWNvbHVtbjsKICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGMuX2NvbHVtbk1pbiA+PSBjb2x1bW5Gcm9tKQogICAgICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjLl9jb2x1bW5NaW4gLT0gY29sdW1uczsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGMuX2NvbHVtbk1heCAtPSBjb2x1bW5zOwogICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgIGZvcmVhY2ggKHZhciB0YmwgaW4gVGFibGVzKQogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIGlmIChjb2x1bW5Gcm9tID49IHRibC5BZGRyZXNzLlN0YXJ0LkNvbHVtbiAmJiBjb2x1bW5Gcm9tIDw9IHRibC5BZGRyZXNzLkVuZC5Db2x1bW4pCiAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICB2YXIgbm9kZSA9IHRibC5Db2x1bW5zWzBdLlRvcE5vZGUuUGFyZW50Tm9kZTsKICAgICAgICAgICAgICAgICAgICAgICAgdmFyIGl4ID0gY29sdW1uRnJvbSAtIHRibC5BZGRyZXNzLlN0YXJ0LkNvbHVtbjsKICAgICAgICAgICAgICAgICAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBjb2x1bW5zOyBpKyspCiAgICAgICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChub2RlLkNoaWxkTm9kZXMuQ291bnQgPiBpeCkKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBub2RlLlJlbW92ZUNoaWxkKG5vZGUuQ2hpbGROb2Rlc1tpeF0pOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICAgICB9IAogICAgICAgICAgICAgICAgICAgICAgICB0YmwuX2NvbHMgPSBuZXcgRXhjZWxUYWJsZUNvbHVtbkNvbGxlY3Rpb24odGJsKTsKICAgICAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgICAgIHRibC5BZGRyZXNzID0gdGJsLkFkZHJlc3MuRGVsZXRlQ29sdW1uKGNvbHVtbkZyb20sIGNvbHVtbnMpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIGludGVybmFsIHZvaWQgQWRqdXN0Rm9ybXVsYXNSb3coaW50IHJvd0Zyb20sIGludCByb3dzKQogICAgICAgIHsKICAgICAgICAgICAgdmFyIGRlbFNGID0gbmV3IExpc3Q8aW50PigpOwogICAgICAgICAgICBmb3JlYWNoICh2YXIgc2YgaW4gX3NoYXJlZEZvcm11bGFzLlZhbHVlcykKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgdmFyIGEgPSBuZXcgRXhjZWxBZGRyZXNzKHNmLkFkZHJlc3MpLkRlbGV0ZVJvdyhyb3dGcm9tLCByb3dzKTsKICAgICAgICAgICAgICAgIGlmIChhPT1udWxsKQogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIGRlbFNGLkFkZChzZi5JbmRleCk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBlbHNlCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgc2YuQWRkcmVzcyA9IGEuQWRkcmVzczsKICAgICAgICAgICAgICAgICAgICBpZiAoc2YuU3RhcnRSb3cgPiByb3dGcm9tKQogICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgdmFyIHIgPSBNYXRoLk1pbihzZi5TdGFydFJvdyAtIHJvd0Zyb20sIHJvd3MpOwogICAgICAgICAgICAgICAgICAgICAgICBzZi5Gb3JtdWxhID0gRXhjZWxDZWxsQmFzZS5VcGRhdGVGb3JtdWxhUmVmZXJlbmNlcyhzZi5Gb3JtdWxhLCAtciwgMCwgcm93RnJvbSwgMCk7CiAgICAgICAgICAgICAgICAgICAgICAgIHNmLlN0YXJ0Um93IC09IHI7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgICAgIGZvcmVhY2ggKHZhciBpeCBpbiBkZWxTRikKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgX3NoYXJlZEZvcm11bGFzLlJlbW92ZShpeCk7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgZGVsU0YgPSBudWxsOwogICAgICAgICAgICB2YXIgY3NlID0gbmV3IENlbGxzU3RvcmVFbnVtZXJhdG9yPG9iamVjdD4oX2Zvcm11bGFzLCAxLCAxLCBFeGNlbFBhY2thZ2UuTWF4Um93cywgRXhjZWxQYWNrYWdlLk1heENvbHVtbnMpOwogICAgICAgICAgICB3aGlsZSAoY3NlLk5leHQoKSkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgaWYgKGNzZS5WYWx1ZSBpcyBzdHJpbmcpCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgY3NlLlZhbHVlID0gRXhjZWxDZWxsQmFzZS5VcGRhdGVGb3JtdWxhUmVmZXJlbmNlcyhjc2UuVmFsdWUuVG9TdHJpbmcoKSwgLXJvd3MsIDAsIHJvd0Zyb20sIDApOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIGludGVybmFsIHZvaWQgQWRqdXN0Rm9ybXVsYXNDb2x1bW4oaW50IGNvbHVtbkZyb20sIGludCBjb2x1bW5zKQogICAgICAgIHsKICAgICAgICAgICAgdmFyIGRlbFNGID0gbmV3IExpc3Q8aW50PigpOwogICAgICAgICAgICBmb3JlYWNoICh2YXIgc2YgaW4gX3NoYXJlZEZvcm11bGFzLlZhbHVlcykKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgdmFyIGEgPSBuZXcgRXhjZWxBZGRyZXNzKHNmLkFkZHJlc3MpLkRlbGV0ZUNvbHVtbihjb2x1bW5Gcm9tLCBjb2x1bW5zKTsKICAgICAgICAgICAgICAgIGlmIChhID09IG51bGwpCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgZGVsU0YuQWRkKHNmLkluZGV4KTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGVsc2UKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICBzZi5BZGRyZXNzID0gYS5BZGRyZXNzOwogICAgICAgICAgICAgICAgICAgIC8vc2YuRm9ybXVsYSA9IEV4Y2VsQ2VsbEJhc2UuVXBkYXRlRm9ybXVsYVJlZmVyZW5jZXMoc2YuRm9ybXVsYSwgMCwgLWNvbHVtbnMsIDAsIGNvbHVtbkZyb20pOwogICAgICAgICAgICAgICAgICAgIGlmIChzZi5TdGFydENvbCA+IGNvbHVtbkZyb20pCiAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICB2YXIgYyA9IE1hdGguTWluKHNmLlN0YXJ0Q29sIC0gY29sdW1uRnJvbSwgY29sdW1ucyk7CiAgICAgICAgICAgICAgICAgICAgICAgIHNmLkZvcm11bGEgPSBFeGNlbENlbGxCYXNlLlVwZGF0ZUZvcm11bGFSZWZlcmVuY2VzKHNmLkZvcm11bGEsIDAsIC1jLCAwLCAxKTsKICAgICAgICAgICAgICAgICAgICAgICAgc2YuU3RhcnRDb2wtPSBjOwogICAgICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICAgICAgLy9zZi5BZGRyZXNzID0gYS5BZGRyZXNzOwogICAgICAgICAgICAgICAgICAgIC8vc2YuRm9ybXVsYSA9IEV4Y2VsQ2VsbEJhc2UuVXBkYXRlRm9ybXVsYVJlZmVyZW5jZXMoc2YuRm9ybXVsYSwgMCwtY29sdW1ucywwLCBjb2x1bW5Gcm9tKTsKICAgICAgICAgICAgICAgICAgICAvL2lmIChzZi5TdGFydENvbCA+PSBjb2x1bW5Gcm9tKQogICAgICAgICAgICAgICAgICAgIC8vewogICAgICAgICAgICAgICAgICAgIC8vICAgIHNmLlN0YXJ0Q29sIC09IHNmLlN0YXJ0Q29sOwogICAgICAgICAgICAgICAgICAgIC8vfQogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgICAgIGZvcmVhY2ggKHZhciBpeCBpbiBkZWxTRikKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgX3NoYXJlZEZvcm11bGFzLlJlbW92ZShpeCk7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgZGVsU0YgPSBudWxsOwogICAgICAgICAgICB2YXIgY3NlID0gbmV3IENlbGxzU3RvcmVFbnVtZXJhdG9yPG9iamVjdD4oX2Zvcm11bGFzLCAxLCAxLCAgRXhjZWxQYWNrYWdlLk1heFJvd3MsIEV4Y2VsUGFja2FnZS5NYXhDb2x1bW5zKTsKICAgICAgICAgICAgd2hpbGUgKGNzZS5OZXh0KCkpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIGlmIChjc2UuVmFsdWUgaXMgc3RyaW5nKQogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIGNzZS5WYWx1ZSA9IEV4Y2VsQ2VsbEJhc2UuVXBkYXRlRm9ybXVsYVJlZmVyZW5jZXMoY3NlLlZhbHVlLlRvU3RyaW5nKCksIDAsIC1jb2x1bW5zLCAwLCBjb2x1bW5Gcm9tKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgIH0KICAgICAgICAvLy8gPHN1bW1hcnk+CiAgICAgICAgLy8vIERlbGV0ZXMgdGhlIHNwZWNpZmllZCByb3cgZnJvbSB0aGUgd29ya3NoZWV0LgogICAgICAgIC8vLyA8L3N1bW1hcnk+CiAgICAgICAgLy8vIDxwYXJhbSBuYW1lPSJyb3dGcm9tIj5UaGUgbnVtYmVyIG9mIHRoZSBzdGFydCByb3cgdG8gYmUgZGVsZXRlZDwvcGFyYW0+CiAgICAgICAgLy8vIDxwYXJhbSBuYW1lPSJyb3dzIj5OdW1iZXIgb2Ygcm93cyB0byBkZWxldGU8L3BhcmFtPgogICAgICAgIC8vLyA8cGFyYW0gbmFtZT0ic2hpZnRPdGhlclJvd3NVcCI+Tm90IHVzZWQuIFJvd3MgYXJlIGFsd2F5cyBzaGlmdGVkPC9wYXJhbT4KICAgICAgICBwdWJsaWMgdm9pZCBEZWxldGVSb3coaW50IHJvd0Zyb20sIGludCByb3dzLCBib29sIHNoaWZ0T3RoZXJSb3dzVXApCgkJewogICAgICAgICAgICBEZWxldGVSb3cocm93RnJvbSwgcm93cyk7CiAgICAgICAgfQoJCSNlbmRyZWdpb24KICAgICAgICAvLy8gPHN1bW1hcnk+CiAgICAgICAgLy8vIEdldCB0aGUgY2VsbCB2YWx1ZSBmcm9tIHRodyB3b3Jrc2hlZXQKICAgICAgICAvLy8gPC9zdW1tYXJ5PgogICAgICAgIC8vLyA8cGFyYW0gbmFtZT0iUm93Ij5UaGUgcm93IG51bWJlcjwvcGFyYW0+CiAgICAgICAgLy8vIDxwYXJhbSBuYW1lPSJDb2x1bW4iPlRoZSByb3cgbnVtYmVyPC9wYXJhbT4KICAgICAgICAvLy8gPHJldHVybnM+VGhlIHZhbHVlPC9yZXR1cm5zPgogICAgICAgIHB1YmxpYyBvYmplY3QgR2V0VmFsdWUoaW50IFJvdywgaW50IENvbHVtbikKICAgICAgICB7CiAgICAgICAgICAgIENoZWNrU2hlZXRUeXBlKCk7CiAgICAgICAgICAgIC8vdWxvbmcgY2VsbElEID0gRXhjZWxDZWxsQmFzZS5HZXRDZWxsSUQoU2hlZXRJRCwgUm93LCBDb2x1bW4pOwogICAgICAgICAgICB2YXIgdiA9IF92YWx1ZXMuR2V0VmFsdWUoUm93LCBDb2x1bW4pOwogICAgICAgICAgICBpZiAodiE9bnVsbCkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgLy92YXIgY2VsbCA9ICgoRXhjZWxDZWxsKV9jZWxsc1tjZWxsSURdKTsKICAgICAgICAgICAgICAgIGlmIChfZmxhZ3MuR2V0RmxhZ1ZhbHVlKFJvdywgQ29sdW1uLCBDZWxsRmxhZ3MuUmljaFRleHQpKQogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIHJldHVybiAob2JqZWN0KUNlbGxzW1JvdywgQ29sdW1uXS5SaWNoVGV4dC5UZXh0OwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgZWxzZQogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIHJldHVybiB2OwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgICAgIGVsc2UKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgcmV0dXJuIG51bGw7CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIC8vLyA8c3VtbWFyeT4KICAgICAgICAvLy8gR2V0IGEgc3Ryb25nbHkgdHlwZWQgY2VsbCB2YWx1ZSBmcm9tIHRoZSB3b3Jrc2hlZXQKICAgICAgICAvLy8gPC9zdW1tYXJ5PgogICAgICAgIC8vLyA8dHlwZXBhcmFtIG5hbWU9IlQiPlRoZSB0eXBlPC90eXBlcGFyYW0+CiAgICAgICAgLy8vIDxwYXJhbSBuYW1lPSJSb3ciPlRoZSByb3cgbnVtYmVyPC9wYXJhbT4KICAgICAgICAvLy8gPHBhcmFtIG5hbWU9IkNvbHVtbiI+VGhlIHJvdyBudW1iZXI8L3BhcmFtPgogICAgICAgIC8vLyA8cmV0dXJucz5UaGUgdmFsdWUuIElmIHRoZSB2YWx1ZSBjYW4ndCBiZSBjb252ZXJ0ZWQgdG8gdGhlIHNwZWNpZmllZCB0eXBlLCB0aGUgZGVmYXVsdCB2YWx1ZSB3aWxsIGJlIHJldHVybmVkPC9yZXR1cm5zPgogICAgICAgIHB1YmxpYyBUIEdldFZhbHVlPFQ+KGludCBSb3csIGludCBDb2x1bW4pCiAgICAgICAgewogICAgICAgICAgICBDaGVja1NoZWV0VHlwZSgpOwogICAgICAgICAgICAvL3Vsb25nIGNlbGxJRD1FeGNlbENlbGxCYXNlLkdldENlbGxJRChTaGVldElELCBSb3csIENvbHVtbik7CiAgICAgICAgICAgIHZhciB2ID0gX3ZhbHVlcy5HZXRWYWx1ZShSb3csIENvbHVtbik7ICAgICAgICAgICAKICAgICAgICAgICAgaWYgKHY9PW51bGwpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIHJldHVybiBkZWZhdWx0KFQpOwogICAgICAgICAgICB9CgogICAgICAgICAgICAvL3ZhciBjZWxsPSgoRXhjZWxDZWxsKV9jZWxsc1tjZWxsSURdKTsKICAgICAgICAgICAgaWYgKF9mbGFncy5HZXRGbGFnVmFsdWUoUm93LCBDb2x1bW4sIENlbGxGbGFncy5SaWNoVGV4dCkpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIHJldHVybiAoVCkob2JqZWN0KUNlbGxzW1JvdywgQ29sdW1uXS5SaWNoVGV4dC5UZXh0OwogICAgICAgICAgICB9CiAgICAgICAgICAgIGVsc2UKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgcmV0dXJuIEdldFR5cGVkVmFsdWU8VD4odik7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgLy9UaGFua3MgdG8gTWljaGFlbCBUcmFuIGZvciBwYXJ0cyBvZiB0aGlzIG1ldGhvZAogICAgICAgIGludGVybmFsIFQgR2V0VHlwZWRWYWx1ZTxUPihvYmplY3QgdikKICAgICAgICB7CiAgICAgICAgICAgIGlmICh2ID09IG51bGwpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIHJldHVybiBkZWZhdWx0KFQpOwogICAgICAgICAgICB9CiAgICAgICAgICAgIFR5cGUgZnJvbVR5cGUgPSB2LkdldFR5cGUoKTsKICAgICAgICAgICAgVHlwZSB0b1R5cGUgPSB0eXBlb2YoVCk7CiAgICAgICAgICAgIGlmIChmcm9tVHlwZSA9PSB0b1R5cGUpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIHJldHVybiAoVCl2OwogICAgICAgICAgICB9CiAgICAgICAgICAgIHZhciBjbnYgPSBUeXBlRGVzY3JpcHRvci5HZXRDb252ZXJ0ZXIoZnJvbVR5cGUpOwogICAgICAgICAgICBpZiAodG9UeXBlID09IHR5cGVvZihEYXRlVGltZSkpICAgIC8vSGFuZGxlIGRhdGVzCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIGlmIChmcm9tVHlwZSA9PSB0eXBlb2YoVGltZVNwYW4pKQogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIHJldHVybiAoKFQpKG9iamVjdCkobmV3IERhdGVUaW1lKCgoVGltZVNwYW4pdikuVGlja3MpKSk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBlbHNlIGlmIChmcm9tVHlwZSA9PSB0eXBlb2Yoc3RyaW5nKSkKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICBEYXRlVGltZSBkdDsKICAgICAgICAgICAgICAgICAgICBpZiAoRGF0ZVRpbWUuVHJ5UGFyc2Uodi5Ub1N0cmluZygpLCBvdXQgZHQpKQogICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIChUKShvYmplY3QpKGR0KTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgZWxzZQogICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGRlZmF1bHQoVCk7CiAgICAgICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGVsc2UKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICBpZiAoY252LkNhbkNvbnZlcnRUbyh0eXBlb2YoZG91YmxlKSkpCiAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gKFQpKG9iamVjdCkoRGF0ZVRpbWUuRnJvbU9BRGF0ZSgoZG91YmxlKWNudi5Db252ZXJ0VG8odiwgdHlwZW9mKGRvdWJsZSkpKSk7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIGVsc2UKICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBkZWZhdWx0KFQpOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgICAgICBlbHNlIGlmICh0b1R5cGUgPT0gdHlwZW9mKFRpbWVTcGFuKSkgICAgLy9IYW5kbGUgdGltZXNwYW4KICAgICAgICAgICAgewogICAgICAgICAgICAgICAgaWYgKGZyb21UeXBlID09IHR5cGVvZihEYXRlVGltZSkpCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgcmV0dXJuICgoVCkob2JqZWN0KShuZXcgVGltZVNwYW4oKChEYXRlVGltZSl2KS5UaWNrcykpKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGVsc2UgaWYgKGZyb21UeXBlID09IHR5cGVvZihzdHJpbmcpKQogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIFRpbWVTcGFuIHRzOwogICAgICAgICAgICAgICAgICAgIGlmIChUaW1lU3Bhbi5UcnlQYXJzZSh2LlRvU3RyaW5nKCksIG91dCB0cykpCiAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gKFQpKG9iamVjdCkodHMpOyAKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgZWxzZQogICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGRlZmF1bHQoVCk7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgZWxzZQogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIGlmIChjbnYuQ2FuQ29udmVydFRvKHR5cGVvZihkb3VibGUpKSkKICAgICAgICAgICAgICAgICAgICB7CgogICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gKFQpKG9iamVjdCkobmV3IFRpbWVTcGFuKERhdGVUaW1lLkZyb21PQURhdGUoKGRvdWJsZSljbnYuQ29udmVydFRvKHYsIHR5cGVvZihkb3VibGUpKSkuVGlja3MpKTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgZWxzZQogICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgdHJ5CiAgICAgICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIElzc3VlIDE0NjgyIC0tICJHZXRWYWx1ZTxkZWNpbWFsPigpIHdvbid0IGNvbnZlcnQgc3RyaW5ncyIKICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIEFzIHN1Z2dlc3RlZCwgYWZ0ZXIgYWxsIHNwZWNpYWwgY2FzZXMsIGFsbCAuTkVUIHRvIGRvIGl0J3MgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBwcmVmZXJyZWQgY29udmVyc2lvbiByYXRoZXIgdGhhbiBzaW1wbHkgcmV0dXJuaW5nIHRoZSBkZWZhdWx0CiAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gKFQpQ29udmVydC5DaGFuZ2VUeXBlKHYsIHR5cGVvZihUKSk7CiAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgY2F0Y2ggKEV4Y2VwdGlvbikKICAgICAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gVGhpcyB3YXMgdGhlIHByZXZpb3VzIGJlaGF2aW91ciAtLSBubyBjb252ZXJzaW9uIGlzIGF2YWlsYWJsZS4KICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBkZWZhdWx0KFQpOwogICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgICAgIGVsc2UKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgaWYgKGNudi5DYW5Db252ZXJ0VG8odG9UeXBlKSkKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICByZXR1cm4gKFQpY252LkNvbnZlcnRUbyh2LCB0eXBlb2YoVCkpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgZWxzZQogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIGlmICh0b1R5cGUuSXNHZW5lcmljVHlwZSAmJiB0b1R5cGUuR2V0R2VuZXJpY1R5cGVEZWZpbml0aW9uKCkuRXF1YWxzKHR5cGVvZihOdWxsYWJsZTw+KSkpCiAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICB0b1R5cGUgPSBOdWxsYWJsZS5HZXRVbmRlcmx5aW5nVHlwZSh0b1R5cGUpOwogICAgICAgICAgICAgICAgICAgICAgICBpZiAoY252LkNhbkNvbnZlcnRUbyh0b1R5cGUpKQogICAgICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gKFQpY252LkNvbnZlcnRUbyh2LCB0eXBlb2YoVCkpOwogICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgICAgICBpZihmcm9tVHlwZT09dHlwZW9mKGRvdWJsZSkgJiYgdG9UeXBlPT10eXBlb2YoZGVjaW1hbCkpCiAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gKFQpKG9iamVjdClDb252ZXJ0LlRvRGVjaW1hbCh2KTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgZWxzZSBpZiAoZnJvbVR5cGUgPT0gdHlwZW9mKGRlY2ltYWwpICYmIHRvVHlwZSA9PSB0eXBlb2YoZG91YmxlKSkKICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiAoVCkob2JqZWN0KUNvbnZlcnQuVG9Eb3VibGUodik7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIGVsc2UKICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBkZWZhdWx0KFQpOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgIH0KICAgICAgICAvLy8gPHN1bW1hcnk+CiAgICAgICAgLy8vIFNldCB0aGUgdmFsdWUgb2YgYSBjZWxsCiAgICAgICAgLy8vIDwvc3VtbWFyeT4KICAgICAgICAvLy8gPHBhcmFtIG5hbWU9IlJvdyI+VGhlIHJvdyBudW1iZXI8L3BhcmFtPgogICAgICAgIC8vLyA8cGFyYW0gbmFtZT0iQ29sdW1uIj5UaGUgY29sdW1uIG51bWJlcjwvcGFyYW0+CiAgICAgICAgLy8vIDxwYXJhbSBuYW1lPSJWYWx1ZSI+VGhlIHZhbHVlPC9wYXJhbT4KICAgICAgICBwdWJsaWMgdm9pZCBTZXRWYWx1ZShpbnQgUm93LCBpbnQgQ29sdW1uLCBvYmplY3QgVmFsdWUpCiAgICAgICAgewogICAgICAgICAgICBDaGVja1NoZWV0VHlwZSgpOwogICAgICAgICAgICBpZiAoUm93IDwgMSB8fCBDb2x1bW4gPCAxIHx8IFJvdyA+IEV4Y2VsUGFja2FnZS5NYXhSb3dzICYmIENvbHVtbiA+IEV4Y2VsUGFja2FnZS5NYXhDb2x1bW5zKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICB0aHJvdyBuZXcgQXJndW1lbnRPdXRPZlJhbmdlRXhjZXB0aW9uKCJSb3cgb3IgQ29sdW1uIG91dCBvZiByYW5nZSIpOwogICAgICAgICAgICB9ICAgICAgICAgICAgCiAgICAgICAgICAgIF92YWx1ZXMuU2V0VmFsdWUoUm93LCBDb2x1bW4sIFZhbHVlKTsKICAgICAgICB9CiAgICAgICAgLy8vIDxzdW1tYXJ5PgogICAgICAgIC8vLyBTZXQgdGhlIHZhbHVlIG9mIGEgY2VsbAogICAgICAgIC8vLyA8L3N1bW1hcnk+CiAgICAgICAgLy8vIDxwYXJhbSBuYW1lPSJBZGRyZXNzIj5UaGUgRXhjZWwgYWRkcmVzczwvcGFyYW0+CiAgICAgICAgLy8vIDxwYXJhbSBuYW1lPSJWYWx1ZSI+VGhlIHZhbHVlPC9wYXJhbT4KICAgICAgICBwdWJsaWMgdm9pZCBTZXRWYWx1ZShzdHJpbmcgQWRkcmVzcywgb2JqZWN0IFZhbHVlKQogICAgICAgIHsKICAgICAgICAgICAgQ2hlY2tTaGVldFR5cGUoKTsKICAgICAgICAgICAgaW50IHJvdywgY29sOwogICAgICAgICAgICBFeGNlbEFkZHJlc3NCYXNlLkdldFJvd0NvbChBZGRyZXNzLCBvdXQgcm93LCBvdXQgY29sLCB0cnVlKTsKICAgICAgICAgICAgaWYgKHJvdyA8IDEgfHwgY29sIDwgMSB8fCByb3cgPiBFeGNlbFBhY2thZ2UuTWF4Um93cyAmJiBjb2wgPiBFeGNlbFBhY2thZ2UuTWF4Q29sdW1ucykKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgdGhyb3cgbmV3IEFyZ3VtZW50T3V0T2ZSYW5nZUV4Y2VwdGlvbigiQWRkcmVzcyBpcyBpbnZhbGlkIG9yIG91dCBvZiByYW5nZSIpOwogICAgICAgICAgICB9CiAgICAgICAgICAgIF92YWx1ZXMuU2V0VmFsdWUocm93LCBjb2wsIFZhbHVlKTsgICAgICAgICAgIAogICAgICAgIH0KCiAgICAgICAgI3JlZ2lvbiBNZXJnZUNlbGxJZAoKICAgICAgICAvLy8gPHN1bW1hcnk+CiAgICAgICAgLy8vIEdldCBNZXJnZUNlbGwgSW5kZXggTm8KICAgICAgICAvLy8gPC9zdW1tYXJ5PgogICAgICAgIC8vLyA8cGFyYW0gbmFtZT0icm93Ij48L3BhcmFtPgogICAgICAgIC8vLyA8cGFyYW0gbmFtZT0iY29sdW1uIj48L3BhcmFtPgogICAgICAgIC8vLyA8cmV0dXJucz48L3JldHVybnM+CiAgICAgICAgcHVibGljIGludCBHZXRNZXJnZUNlbGxJZChpbnQgcm93LCBpbnQgY29sdW1uKQogICAgICAgIHsKICAgICAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBfbWVyZ2VkQ2VsbHMuQ291bnQ7IGkrKykKICAgICAgICAgICAgewogICAgICAgICAgICAgICBpZighc3RyaW5nLklzTnVsbE9yRW1wdHkoIF9tZXJnZWRDZWxsc1tpXSkpCiAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICBFeGNlbFJhbmdlIHJhbmdlID0gQ2VsbHNbX21lcmdlZENlbGxzW2ldXTsKCiAgICAgICAgICAgICAgICAgICAgaWYgKHJhbmdlLlN0YXJ0LlJvdyA8PSByb3cgJiYgcm93IDw9IHJhbmdlLkVuZC5Sb3cpCiAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICBpZiAocmFuZ2UuU3RhcnQuQ29sdW1uIDw9IGNvbHVtbiAmJiBjb2x1bW4gPD0gcmFuZ2UuRW5kLkNvbHVtbikKICAgICAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGkgKyAxOwogICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgICAgIHJldHVybiAwOwogICAgICAgIH0KCiAgICAgICAgI2VuZHJlZ2lvbgoJCSNlbmRyZWdpb24gLy8gRU5EIFdvcmtzaGVldCBQdWJsaWMgTWV0aG9kcwoKCQkjcmVnaW9uIFdvcmtzaGVldCBQcml2YXRlIE1ldGhvZHMKCgkJI3JlZ2lvbiBXb3Jrc2hlZXQgU2F2ZQogICAgICAgIGludGVybmFsIHZvaWQgU2F2ZSgpCiAgICAgICAgewogICAgICAgICAgICAgICAgRGVsZXRlUHJpbnRlclNldHRpbmdzKCk7CgogICAgICAgICAgICAgICAgaWYgKF93b3Jrc2hlZXRYbWwgIT0gbnVsbCkKICAgICAgICAgICAgICAgIHsKCiAgICAgICAgICAgICAgICAgICAgaWYgKCEodGhpcyBpcyBFeGNlbENoYXJ0c2hlZXQpKQogICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgLy8gc2F2ZSB0aGUgaGVhZGVyICYgZm9vdGVyIChpZiBkZWZpbmVkKQogICAgICAgICAgICAgICAgICAgICAgICBpZiAoX2hlYWRlckZvb3RlciAhPSBudWxsKQogICAgICAgICAgICAgICAgICAgICAgICAgICAgSGVhZGVyRm9vdGVyLlNhdmUoKTsKCiAgICAgICAgICAgICAgICAgICAgICAgIHZhciBkID0gRGltZW5zaW9uOwogICAgICAgICAgICAgICAgICAgICAgICBpZiAoZCA9PSBudWxsKQogICAgICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLkRlbGV0ZUFsbE5vZGUoImQ6ZGltZW5zaW9uL0ByZWYiKTsKICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICAgICBlbHNlCiAgICAgICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuU2V0WG1sTm9kZVN0cmluZygiZDpkaW1lbnNpb24vQHJlZiIsIGQuQWRkcmVzcyk7CiAgICAgICAgICAgICAgICAgICAgICAgIH0KCgogICAgICAgICAgICAgICAgICAgICAgICBpZiAoRHJhd2luZ3MuQ291bnQgPT0gMCkKICAgICAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgLy9SZW1vdmUgbm9kZSBpZiBubyBkcmF3aW5ncyBleGlzdHMuCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBEZWxldGVOb2RlKCJkOmRyYXdpbmciKTsKICAgICAgICAgICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgICAgICAgICAgU2F2ZUNvbW1lbnRzKCk7CiAgICAgICAgICAgICAgICAgICAgICAgIEhlYWRlckZvb3Rlci5TYXZlSGVhZGVyRm9vdGVySW1hZ2VzKCk7CiAgICAgICAgICAgICAgICAgICAgICAgIFNhdmVUYWJsZXMoKTsKICAgICAgICAgICAgICAgICAgICAgICAgU2F2ZVBpdm90VGFibGVzKCk7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgIGlmIChEcmF3aW5ncy5VcmlEcmF3aW5nIT1udWxsKQogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIGlmIChEcmF3aW5ncy5Db3VudCA9PSAwKQogICAgICAgICAgICAgICAgICAgIHsgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICBQYXJ0LkRlbGV0ZVJlbGF0aW9uc2hpcChEcmF3aW5ncy5fZHJhd2luZ1JlbGF0aW9uLklkKTsKICAgICAgICAgICAgICAgICAgICAgICAgX3BhY2thZ2UuUGFja2FnZS5EZWxldGVQYXJ0KERyYXdpbmdzLlVyaURyYXdpbmcpOyAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIGVsc2UKICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgIFBhY2thZ2luZy5aaXBQYWNrYWdlUGFydCBwYXJ0UGFjayA9IERyYXdpbmdzLlBhcnQ7CiAgICAgICAgICAgICAgICAgICAgICAgIERyYXdpbmdzLkRyYXdpbmdYbWwuU2F2ZShwYXJ0UGFjay5HZXRTdHJlYW0oRmlsZU1vZGUuQ3JlYXRlLCBGaWxlQWNjZXNzLldyaXRlKSk7CiAgICAgICAgICAgICAgICAgICAgICAgIGZvcmVhY2ggKEV4Y2VsRHJhd2luZyBkIGluIERyYXdpbmdzKQogICAgICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoZCBpcyBFeGNlbENoYXJ0KQogICAgICAgICAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEV4Y2VsQ2hhcnQgYyA9IChFeGNlbENoYXJ0KWQ7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYy5DaGFydFhtbC5TYXZlKGMuUGFydC5HZXRTdHJlYW0oRmlsZU1vZGUuQ3JlYXRlLCBGaWxlQWNjZXNzLldyaXRlKSk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIGludGVybmFsIHZvaWQgU2F2ZUhhbmRsZXIoWmlwT3V0cHV0U3RyZWFtIHN0cmVhbSwgQ29tcHJlc3Npb25MZXZlbCBjb21wcmVzc2lvbkxldmVsLCBzdHJpbmcgZmlsZU5hbWUpCiAgICAgICAgewogICAgICAgICAgICAgICAgICAgIC8vSW5pdCBaaXAKICAgICAgICAgICAgICAgICAgICBzdHJlYW0uQ29kZWNCdWZmZXJTaXplID0gODA5NjsKICAgICAgICAgICAgICAgICAgICBzdHJlYW0uQ29tcHJlc3Npb25MZXZlbCA9IChPZmZpY2VPcGVuWG1sLlBhY2thZ2luZy5Jb25pYy5abGliLkNvbXByZXNzaW9uTGV2ZWwpY29tcHJlc3Npb25MZXZlbDsKICAgICAgICAgICAgICAgICAgICBzdHJlYW0uUHV0TmV4dEVudHJ5KGZpbGVOYW1lKTsKCiAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgU2F2ZVhtbChzdHJlYW0pOwogICAgICAgIH0KCiAgICAgICAgCgogICAgICAgIC8vLy8vIDxzdW1tYXJ5PgogICAgICAgIC8vLy8vIFNhdmVzIHRoZSB3b3Jrc2hlZXQgdG8gdGhlIHBhY2thZ2UuCiAgICAgICAgLy8vLy8gPC9zdW1tYXJ5PgogICAgICAgIC8vaW50ZXJuYWwgdm9pZCBTYXZlKCkgIC8vIFdvcmtzaGVldCBTYXZlCiAgICAgICAgLy97CiAgICAgICAgLy8gICAgRGVsZXRlUHJpbnRlclNldHRpbmdzKCk7CgogICAgICAgIC8vICAgIGlmIChfd29ya3NoZWV0WG1sICE9IG51bGwpCiAgICAgICAgLy8gICAgewogICAgICAgICAgICAgICAgCiAgICAgICAgLy8gICAgICAgIC8vIHNhdmUgdGhlIGhlYWRlciAmIGZvb3RlciAoaWYgZGVmaW5lZCkKICAgICAgICAvLyAgICAgICAgaWYgKF9oZWFkZXJGb290ZXIgIT0gbnVsbCkKICAgICAgICAvLyAgICAgICAgICAgIEhlYWRlckZvb3Rlci5TYXZlKCk7CgogICAgICAgIC8vICAgICAgICB2YXIgZCA9IERpbWVuc2lvbjsKICAgICAgICAvLyAgICAgICAgaWYgKGQgPT0gbnVsbCkKICAgICAgICAvLyAgICAgICAgewogICAgICAgIC8vICAgICAgICAgICAgdGhpcy5EZWxldGVBbGxOb2RlKCJkOmRpbWVuc2lvbi9AcmVmIik7CiAgICAgICAgLy8gICAgICAgIH0KICAgICAgICAvLyAgICAgICAgZWxzZQogICAgICAgIC8vICAgICAgICB7CiAgICAgICAgLy8gICAgICAgICAgICB0aGlzLlNldFhtbE5vZGVTdHJpbmcoImQ6ZGltZW5zaW9uL0ByZWYiLCBkLkFkZHJlc3MpOwogICAgICAgIC8vICAgICAgICB9CiAgICAgICAgICAgICAgICAKCiAgICAgICAgLy8gICAgICAgIGlmIChfZHJhd2luZ3MgIT0gbnVsbCAmJiBfZHJhd2luZ3MuQ291bnQgPT0gMCkKICAgICAgICAvLyAgICAgICAgewogICAgICAgIC8vICAgICAgICAgICAgLy9SZW1vdmUgbm9kZSBpZiBubyBkcmF3aW5ncyBleGlzdHMuCiAgICAgICAgLy8gICAgICAgICAgICBEZWxldGVOb2RlKCJkOmRyYXdpbmciKTsKICAgICAgICAvLyAgICAgICAgfQoKICAgICAgICAvLyAgICAgICAgU2F2ZUNvbW1lbnRzKCk7CiAgICAgICAgLy8gICAgICAgIEhlYWRlckZvb3Rlci5TYXZlSGVhZGVyRm9vdGVySW1hZ2VzKCk7CiAgICAgICAgLy8gICAgICAgIFNhdmVUYWJsZXMoKTsKICAgICAgICAvLyAgICAgICAgU2F2ZVBpdm90VGFibGVzKCk7CiAgICAgICAgLy8gICAgICAgIFNhdmVYbWwoKTsKICAgICAgICAvLyAgICB9CiAgICAgICAgICAgIAogICAgICAgIC8vICAgIGlmIChEcmF3aW5ncy5VcmlEcmF3aW5nIT1udWxsKQogICAgICAgIC8vICAgIHsKICAgICAgICAvLyAgICAgICAgaWYgKERyYXdpbmdzLkNvdW50ID09IDApCiAgICAgICAgLy8gICAgICAgIHsgICAgICAgICAgICAgICAgICAgIAogICAgICAgIC8vICAgICAgICAgICAgUGFydC5EZWxldGVSZWxhdGlvbnNoaXAoRHJhd2luZ3MuX2RyYXdpbmdSZWxhdGlvbi5JZCk7CiAgICAgICAgLy8gICAgICAgICAgICBfcGFja2FnZS5QYWNrYWdlLkRlbGV0ZVBhcnQoRHJhd2luZ3MuVXJpRHJhd2luZyk7ICAgICAgICAgICAgICAgICAgICAKICAgICAgICAvLyAgICAgICAgfQogICAgICAgIC8vICAgICAgICBlbHNlCiAgICAgICAgLy8gICAgICAgIHsKICAgICAgICAvLyAgICAgICAgICAgIFBhY2thZ2luZy5aaXBQYWNrYWdlUGFydCBwYXJ0UGFjayA9IERyYXdpbmdzLlBhcnQ7CiAgICAgICAgLy8gICAgICAgICAgICBEcmF3aW5ncy5EcmF3aW5nWG1sLlNhdmUocGFydFBhY2suR2V0U3RyZWFtKEZpbGVNb2RlLkNyZWF0ZSwgRmlsZUFjY2Vzcy5Xcml0ZSkpOwogICAgICAgIC8vICAgICAgICAgICAgZm9yZWFjaCAoRXhjZWxEcmF3aW5nIGQgaW4gRHJhd2luZ3MpCiAgICAgICAgLy8gICAgICAgICAgICB7CiAgICAgICAgLy8gICAgICAgICAgICAgICAgaWYgKGQgaXMgRXhjZWxDaGFydCkKICAgICAgICAvLyAgICAgICAgICAgICAgICB7CiAgICAgICAgLy8gICAgICAgICAgICAgICAgICAgIEV4Y2VsQ2hhcnQgYyA9IChFeGNlbENoYXJ0KWQ7CiAgICAgICAgLy8gICAgICAgICAgICAgICAgICAgIGMuQ2hhcnRYbWwuU2F2ZShjLlBhcnQuR2V0U3RyZWFtKEZpbGVNb2RlLkNyZWF0ZSwgRmlsZUFjY2Vzcy5Xcml0ZSkpOwogICAgICAgIC8vICAgICAgICAgICAgICAgIH0KICAgICAgICAvLyAgICAgICAgICAgIH0KICAgICAgICAvLyAgICAgICAgfQogICAgICAgIC8vICAgIH0KICAgICAgICAvL30KCiAgICAgICAgLy8vIDxzdW1tYXJ5PgogICAgICAgIC8vLyBEZWxldGUgdGhlIHByaW50ZXJzZXR0aW5ncyByZWxhdGlvbnNoaXAgYW5kIHBhcnQuCiAgICAgICAgLy8vIDwvc3VtbWFyeT4KICAgICAgICBwcml2YXRlIHZvaWQgRGVsZXRlUHJpbnRlclNldHRpbmdzKCkKICAgICAgICB7CiAgICAgICAgICAgIC8vRGVsZXRlIHRoZSByZWxhdGlvbnNoaXAgZnJvbSB0aGUgcGFnZVNldHVwIHRhZwogICAgICAgICAgICBYbWxBdHRyaWJ1dGUgYXR0ciA9IChYbWxBdHRyaWJ1dGUpV29ya3NoZWV0WG1sLlNlbGVjdFNpbmdsZU5vZGUoIi8vZDpwYWdlU2V0dXAvQHI6aWQiLCBOYW1lU3BhY2VNYW5hZ2VyKTsKICAgICAgICAgICAgaWYgKGF0dHIgIT0gbnVsbCkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgc3RyaW5nIHJlbElEID0gYXR0ci5WYWx1ZTsKICAgICAgICAgICAgICAgIC8vRmlyc3QgZGVsZXRlIHRoZSBhdHRyaWJ1dGUgZnJvbSB0aGUgWE1MCiAgICAgICAgICAgICAgICBhdHRyLk93bmVyRWxlbWVudC5BdHRyaWJ1dGVzLlJlbW92ZShhdHRyKTsKICAgICAgICAgICAgICAgIGlmKFBhcnQuUmVsYXRpb25zaGlwRXhpc3RzKHJlbElEKSkKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICB2YXIgcmVsID0gUGFydC5HZXRSZWxhdGlvbnNoaXAocmVsSUQpOwogICAgICAgICAgICAgICAgICAgIFVyaSBwcmludGVyU2V0dGluZ3NVcmkgPSBVcmlIZWxwZXIuUmVzb2x2ZVBhcnRVcmkocmVsLlNvdXJjZVVyaSwgcmVsLlRhcmdldFVyaSk7CiAgICAgICAgICAgICAgICAgICAgUGFydC5EZWxldGVSZWxhdGlvbnNoaXAocmVsLklkKTsKCiAgICAgICAgICAgICAgICAgICAgLy9EZWxldGUgdGhlIHBhcnQgZnJvbSB0aGUgcGFja2FnZQogICAgICAgICAgICAgICAgICAgIGlmKF9wYWNrYWdlLlBhY2thZ2UuUGFydEV4aXN0cyhwcmludGVyU2V0dGluZ3NVcmkpKQogICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgX3BhY2thZ2UuUGFja2FnZS5EZWxldGVQYXJ0KHByaW50ZXJTZXR0aW5nc1VyaSk7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIHByaXZhdGUgdm9pZCBTYXZlQ29tbWVudHMoKQogICAgICAgIHsKICAgICAgICAgICAgaWYgKF9jb21tZW50cyAhPSBudWxsKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBpZiAoX2NvbW1lbnRzLkNvdW50ID09IDApCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgaWYgKF9jb21tZW50cy5VcmkgIT0gbnVsbCkKICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgIFBhcnQuRGVsZXRlUmVsYXRpb25zaGlwKF9jb21tZW50cy5SZWxJZCk7CiAgICAgICAgICAgICAgICAgICAgICAgIF9wYWNrYWdlLlBhY2thZ2UuRGVsZXRlUGFydChfY29tbWVudHMuVXJpKTsgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgUmVtb3ZlTGVnYWN5RHJhd2luZ1JlbChWbWxEcmF3aW5nc0NvbW1lbnRzLlJlbElkKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGVsc2UKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICBpZiAoX2NvbW1lbnRzLlVyaSA9PSBudWxsKQogICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgX2NvbW1lbnRzLlVyaT1uZXcgVXJpKHN0cmluZy5Gb3JtYXQoQCIveGwvY29tbWVudHN7MH0ueG1sIiwgU2hlZXRJRCksIFVyaUtpbmQuUmVsYXRpdmUpOyAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICBpZihfY29tbWVudHMuUGFydD09bnVsbCkKICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgIF9jb21tZW50cy5QYXJ0ID0gX3BhY2thZ2UuUGFja2FnZS5DcmVhdGVQYXJ0KF9jb21tZW50cy5VcmksICJhcHBsaWNhdGlvbi92bmQub3BlbnhtbGZvcm1hdHMtb2ZmaWNlZG9jdW1lbnQuc3ByZWFkc2hlZXRtbC5jb21tZW50cyt4bWwiLCBfcGFja2FnZS5Db21wcmVzc2lvbik7CiAgICAgICAgICAgICAgICAgICAgICAgIHZhciByZWwgPSBQYXJ0LkNyZWF0ZVJlbGF0aW9uc2hpcChVcmlIZWxwZXIuR2V0UmVsYXRpdmVVcmkoV29ya3NoZWV0VXJpLCBfY29tbWVudHMuVXJpKSwgUGFja2FnaW5nLlRhcmdldE1vZGUuSW50ZXJuYWwsIEV4Y2VsUGFja2FnZS5zY2hlbWFSZWxhdGlvbnNoaXBzKyIvY29tbWVudHMiKTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgX2NvbW1lbnRzLkNvbW1lbnRYbWwuU2F2ZShfY29tbWVudHMuUGFydC5HZXRTdHJlYW0oRmlsZU1vZGUuQ3JlYXRlKSk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIGlmIChfdm1sRHJhd2luZ3MgIT0gbnVsbCkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgaWYgKF92bWxEcmF3aW5ncy5Db3VudCA9PSAwKQogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIGlmIChfdm1sRHJhd2luZ3MuVXJpICE9IG51bGwpCiAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICBQYXJ0LkRlbGV0ZVJlbGF0aW9uc2hpcChfdm1sRHJhd2luZ3MuUmVsSWQpOwogICAgICAgICAgICAgICAgICAgICAgICBfcGFja2FnZS5QYWNrYWdlLkRlbGV0ZVBhcnQoX3ZtbERyYXdpbmdzLlVyaSk7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgZWxzZQogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIGlmIChfdm1sRHJhd2luZ3MuVXJpID09IG51bGwpCiAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICBfdm1sRHJhd2luZ3MuVXJpID0gWG1sSGVscGVyLkdldE5ld1VyaShfcGFja2FnZS5QYWNrYWdlLCBAIi94bC9kcmF3aW5ncy92bWxEcmF3aW5nezB9LnZtbCIpOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICBpZiAoX3ZtbERyYXdpbmdzLlBhcnQgPT0gbnVsbCkKICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgIF92bWxEcmF3aW5ncy5QYXJ0ID0gX3BhY2thZ2UuUGFja2FnZS5DcmVhdGVQYXJ0KF92bWxEcmF3aW5ncy5VcmksICJhcHBsaWNhdGlvbi92bmQub3BlbnhtbGZvcm1hdHMtb2ZmaWNlZG9jdW1lbnQudm1sRHJhd2luZyIsIF9wYWNrYWdlLkNvbXByZXNzaW9uKTsKICAgICAgICAgICAgICAgICAgICAgICAgdmFyIHJlbCA9IFBhcnQuQ3JlYXRlUmVsYXRpb25zaGlwKFVyaUhlbHBlci5HZXRSZWxhdGl2ZVVyaShXb3Jrc2hlZXRVcmksIF92bWxEcmF3aW5ncy5VcmkpLCBQYWNrYWdpbmcuVGFyZ2V0TW9kZS5JbnRlcm5hbCwgRXhjZWxQYWNrYWdlLnNjaGVtYVJlbGF0aW9uc2hpcHMgKyAiL3ZtbERyYXdpbmciKTsKICAgICAgICAgICAgICAgICAgICAgICAgU2V0WG1sTm9kZVN0cmluZygiZDpsZWdhY3lEcmF3aW5nL0ByOmlkIiwgcmVsLklkKTsKICAgICAgICAgICAgICAgICAgICAgICAgX3ZtbERyYXdpbmdzLlJlbElkID0gcmVsLklkOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICBfdm1sRHJhd2luZ3MuVm1sRHJhd2luZ1htbC5TYXZlKF92bWxEcmF3aW5ncy5QYXJ0LkdldFN0cmVhbSgpKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgIH0KICAgICAgICAvLy8gPHN1bW1hcnk+CiAgICAgICAgLy8vIFNhdmUgYWxsIHRhYmxlIGRhdGEKICAgICAgICAvLy8gPC9zdW1tYXJ5PgogICAgICAgIHByaXZhdGUgdm9pZCBTYXZlVGFibGVzKCkKICAgICAgICB7CiAgICAgICAgICAgIGZvcmVhY2ggKHZhciB0YmwgaW4gVGFibGVzKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBpZiAodGJsLlNob3dIZWFkZXIgfHwgdGJsLlNob3dUb3RhbCkKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICBpbnQgY29sTnVtID0gdGJsLkFkZHJlc3MuX2Zyb21Db2w7CiAgICAgICAgICAgICAgICAgICAgdmFyIGNvbFZhbCA9IG5ldyBIYXNoU2V0PHN0cmluZz4oKTsKICAgICAgICAgICAgICAgICAgICBmb3JlYWNoICh2YXIgY29sIGluIHRibC5Db2x1bW5zKQogICAgICAgICAgICAgICAgICAgIHsgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgc3RyaW5nIG49Y29sLk5hbWUuVG9Mb3dlcihDdWx0dXJlSW5mby5JbnZhcmlhbnRDdWx0dXJlKTsKICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHRibC5TaG93SGVhZGVyKQogICAgICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBuID0gdGJsLldvcmtTaGVldC5HZXRWYWx1ZTxzdHJpbmc+KHRibC5BZGRyZXNzLl9mcm9tUm93LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRibC5BZGRyZXNzLl9mcm9tQ29sICsgY29sLlBvc2l0aW9uKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChzdHJpbmcuSXNOdWxsT3JFbXB0eShuKSkKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBuID0gY29sLk5hbWUuVG9Mb3dlcihDdWx0dXJlSW5mby5JbnZhcmlhbnRDdWx0dXJlKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVsc2UKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb2wuTmFtZSA9IG47CiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgZWxzZQogICAgICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBuID0gY29sLk5hbWUuVG9Mb3dlcihDdWx0dXJlSW5mby5JbnZhcmlhbnRDdWx0dXJlKTsKICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICBpZihjb2xWYWwuQ29udGFpbnMobikpCiAgICAgICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRocm93KG5ldyBJbnZhbGlkRGF0YUV4Y2VwdGlvbihzdHJpbmcuRm9ybWF0KCJUYWJsZSB7MH0gQ29sdW1uIHsxfSBkb2VzIG5vdCBoYXZlIGEgdW5pcXVlIG5hbWUuIiwgdGJsLk5hbWUsIGNvbC5OYW1lKSkpOwogICAgICAgICAgICAgICAgICAgICAgICB9ICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgIGNvbFZhbC5BZGQobik7CiAgICAgICAgICAgICAgICAgICAgICAgIGNvbC5OYW1lID0gQ29udmVydFV0aWwuRXhjZWxFbmNvZGVTdHJpbmcoY29sLk5hbWUpOwogICAgICAgICAgICAgICAgICAgICAgICBpZiAodGJsLlNob3dIZWFkZXIpCiAgICAgICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIF92YWx1ZXMuU2V0VmFsdWUodGJsLkFkZHJlc3MuX2Zyb21Sb3csIGNvbE51bSwgY29sLk5hbWUpOwogICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgICAgIGlmICh0YmwuU2hvd1RvdGFsKQogICAgICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBTZXRUYWJsZVRvdGFsRnVuY3Rpb24odGJsLCBjb2wsIGNvbE51bSk7CiAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgaWYgKCFzdHJpbmcuSXNOdWxsT3JFbXB0eShjb2wuQ2FsY3VsYXRlZENvbHVtbkZvcm11bGEpKQogICAgICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbnQgZnJvbVJvdyA9IHRibC5TaG93SGVhZGVyID8gdGJsLkFkZHJlc3MuX2Zyb21Sb3cgKyAxIDogdGJsLkFkZHJlc3MuX2Zyb21Sb3c7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbnQgdG9Sb3cgPSB0YmwuU2hvd1RvdGFsID8gdGJsLkFkZHJlc3MuX3RvUm93IC0gMSA6IHRibC5BZGRyZXNzLl90b1JvdzsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZvciAoaW50IHJvdyA9IGZyb21Sb3c7IHJvdyA8PSB0b1Jvdzsgcm93KyspCiAgICAgICAgICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy9DZWxsKHJvdywgY29sTnVtKS5Gb3JtdWxhID0gY29sLkNhbGN1bGF0ZWRDb2x1bW5Gb3JtdWxhOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFNldEZvcm11bGEocm93LCBjb2xOdW0sIGNvbC5DYWxjdWxhdGVkQ29sdW1uRm9ybXVsYSk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9ICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgICAgIGNvbE51bSsrOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0gICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICBpZiAodGJsLlBhcnQgPT0gbnVsbCkKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICB0YmwuVGFibGVVcmkgPSBHZXROZXdVcmkoX3BhY2thZ2UuUGFja2FnZSwgQCIveGwvdGFibGVzL3RhYmxlezB9LnhtbCIsIHRibC5JZCk7CiAgICAgICAgICAgICAgICAgICAgdGJsLlBhcnQgPSBfcGFja2FnZS5QYWNrYWdlLkNyZWF0ZVBhcnQodGJsLlRhYmxlVXJpLCAiYXBwbGljYXRpb24vdm5kLm9wZW54bWxmb3JtYXRzLW9mZmljZWRvY3VtZW50LnNwcmVhZHNoZWV0bWwudGFibGUreG1sIiwgV29ya2Jvb2suX3BhY2thZ2UuQ29tcHJlc3Npb24pOwogICAgICAgICAgICAgICAgICAgIHZhciBzdHJlYW0gPSB0YmwuUGFydC5HZXRTdHJlYW0oRmlsZU1vZGUuQ3JlYXRlKTsKICAgICAgICAgICAgICAgICAgICB0YmwuVGFibGVYbWwuU2F2ZShzdHJlYW0pOwogICAgICAgICAgICAgICAgICAgIHZhciByZWwgPSBQYXJ0LkNyZWF0ZVJlbGF0aW9uc2hpcChVcmlIZWxwZXIuR2V0UmVsYXRpdmVVcmkoV29ya3NoZWV0VXJpLCB0YmwuVGFibGVVcmkpLCBQYWNrYWdpbmcuVGFyZ2V0TW9kZS5JbnRlcm5hbCwgRXhjZWxQYWNrYWdlLnNjaGVtYVJlbGF0aW9uc2hpcHMgKyAiL3RhYmxlIik7CiAgICAgICAgICAgICAgICAgICAgdGJsLlJlbGF0aW9uc2hpcElEID0gcmVsLklkOwoKICAgICAgICAgICAgICAgICAgICBDcmVhdGVOb2RlKCJkOnRhYmxlUGFydHMiKTsKICAgICAgICAgICAgICAgICAgICBYbWxOb2RlIHRibHMgPSBUb3BOb2RlLlNlbGVjdFNpbmdsZU5vZGUoImQ6dGFibGVQYXJ0cyIsTmFtZVNwYWNlTWFuYWdlcik7CgogICAgICAgICAgICAgICAgICAgIHZhciB0YmxOb2RlID0gdGJscy5Pd25lckRvY3VtZW50LkNyZWF0ZUVsZW1lbnQoInRhYmxlUGFydCIsRXhjZWxQYWNrYWdlLnNjaGVtYU1haW4pOwogICAgICAgICAgICAgICAgICAgIHRibHMuQXBwZW5kQ2hpbGQodGJsTm9kZSk7CiAgICAgICAgICAgICAgICAgICAgdGJsTm9kZS5TZXRBdHRyaWJ1dGUoImlkIixFeGNlbFBhY2thZ2Uuc2NoZW1hUmVsYXRpb25zaGlwcywgcmVsLklkKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGVsc2UKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICB2YXIgc3RyZWFtID0gdGJsLlBhcnQuR2V0U3RyZWFtKEZpbGVNb2RlLkNyZWF0ZSk7CiAgICAgICAgICAgICAgICAgICAgdGJsLlRhYmxlWG1sLlNhdmUoc3RyZWFtKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgaW50ZXJuYWwgdm9pZCBTZXRUYWJsZVRvdGFsRnVuY3Rpb24oRXhjZWxUYWJsZSB0YmwsIEV4Y2VsVGFibGVDb2x1bW4gY29sLCBpbnQgY29sTnVtPS0xKQogICAgICAgIHsKICAgICAgICAgICAgaWYgKHRibC5TaG93VG90YWwgPT0gZmFsc2UpIHJldHVybjsKICAgICAgICAgICAgaWYgKGNvbE51bSA9PSAtMSkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCB0YmwuQ29sdW1ucy5Db3VudDsgaSsrKQogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIGlmICh0YmwuQ29sdW1uc1tpXS5OYW1lID09IGNvbC5OYW1lKQogICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgY29sTnVtID0gdGJsLkFkZHJlc3MuX2Zyb21Db2wgKyBpOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgICAgICBpZiAoY29sLlRvdGFsc1Jvd0Z1bmN0aW9uID09IFJvd0Z1bmN0aW9ucy5DdXN0b20pCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIFNldEZvcm11bGEodGJsLkFkZHJlc3MuX3RvUm93LCBjb2xOdW0sIGNvbC5Ub3RhbHNSb3dGb3JtdWxhKTsKICAgICAgICAgICAgfQogICAgICAgICAgICBlbHNlIGlmIChjb2wuVG90YWxzUm93RnVuY3Rpb24gIT0gUm93RnVuY3Rpb25zLk5vbmUpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIHN3aXRjaCAoY29sLlRvdGFsc1Jvd0Z1bmN0aW9uKQogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIGNhc2UgUm93RnVuY3Rpb25zLkF2ZXJhZ2U6CiAgICAgICAgICAgICAgICAgICAgICAgIFNldEZvcm11bGEodGJsLkFkZHJlc3MuX3RvUm93LCBjb2xOdW0sIEdldFRvdGFsRnVuY3Rpb24oY29sLCAiMTAxIikpOwogICAgICAgICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgICAgICBjYXNlIFJvd0Z1bmN0aW9ucy5Db3VudDoKICAgICAgICAgICAgICAgICAgICAgICAgU2V0Rm9ybXVsYSh0YmwuQWRkcmVzcy5fdG9Sb3csIGNvbE51bSwgR2V0VG90YWxGdW5jdGlvbihjb2wsICIxMDIiKSk7CiAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgICAgIGNhc2UgUm93RnVuY3Rpb25zLkNvdW50TnVtczoKICAgICAgICAgICAgICAgICAgICAgICAgU2V0Rm9ybXVsYSh0YmwuQWRkcmVzcy5fdG9Sb3csIGNvbE51bSwgR2V0VG90YWxGdW5jdGlvbihjb2wsICIxMDMiKSk7CiAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgICAgIGNhc2UgUm93RnVuY3Rpb25zLk1heDoKICAgICAgICAgICAgICAgICAgICAgICAgU2V0Rm9ybXVsYSh0YmwuQWRkcmVzcy5fdG9Sb3csIGNvbE51bSwgR2V0VG90YWxGdW5jdGlvbihjb2wsICIxMDQiKSk7CiAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgICAgIGNhc2UgUm93RnVuY3Rpb25zLk1pbjoKICAgICAgICAgICAgICAgICAgICAgICAgU2V0Rm9ybXVsYSh0YmwuQWRkcmVzcy5fdG9Sb3csIGNvbE51bSwgR2V0VG90YWxGdW5jdGlvbihjb2wsICIxMDUiKSk7CiAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgICAgIGNhc2UgUm93RnVuY3Rpb25zLlN0ZERldjoKICAgICAgICAgICAgICAgICAgICAgICAgU2V0Rm9ybXVsYSh0YmwuQWRkcmVzcy5fdG9Sb3csIGNvbE51bSwgR2V0VG90YWxGdW5jdGlvbihjb2wsICIxMDciKSk7CiAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgICAgIGNhc2UgUm93RnVuY3Rpb25zLlZhcjoKICAgICAgICAgICAgICAgICAgICAgICAgU2V0Rm9ybXVsYSh0YmwuQWRkcmVzcy5fdG9Sb3csIGNvbE51bSwgR2V0VG90YWxGdW5jdGlvbihjb2wsICIxMTAiKSk7CiAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgICAgIGNhc2UgUm93RnVuY3Rpb25zLlN1bToKICAgICAgICAgICAgICAgICAgICAgICAgU2V0Rm9ybXVsYSh0YmwuQWRkcmVzcy5fdG9Sb3csIGNvbE51bSwgR2V0VG90YWxGdW5jdGlvbihjb2wsICIxMDkiKSk7CiAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgICAgIGRlZmF1bHQ6CiAgICAgICAgICAgICAgICAgICAgICAgIHRocm93IChuZXcgRXhjZXB0aW9uKCJVbmtub3duIFJvd0Z1bmN0aW9uIGVudW0iKSk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICAgICAgZWxzZQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBfdmFsdWVzLlNldFZhbHVlKHRibC5BZGRyZXNzLl90b1JvdywgY29sTnVtLCBjb2wuVG90YWxzUm93TGFiZWwpOwoKICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgaW50ZXJuYWwgdm9pZCBTZXRGb3JtdWxhKGludCByb3csIGludCBjb2wsIG9iamVjdCB2YWx1ZSkKICAgICAgICB7CiAgICAgICAgICAgIF9mb3JtdWxhcy5TZXRWYWx1ZShyb3csIGNvbCwgdmFsdWUpOwogICAgICAgICAgICBpZiAoIV92YWx1ZXMuRXhpc3RzKHJvdywgY29sKSkgX3ZhbHVlcy5TZXRWYWx1ZShyb3csIGNvbCwgbnVsbCk7CiAgICAgICAgfQogICAgICAgIGludGVybmFsIHZvaWQgU2V0U3R5bGUoaW50IHJvdywgaW50IGNvbCwgaW50IHZhbHVlKQogICAgICAgIHsKICAgICAgICAgICAgX3N0eWxlcy5TZXRWYWx1ZShyb3csIGNvbCwgdmFsdWUpOwogICAgICAgICAgICBpZighX3ZhbHVlcy5FeGlzdHMocm93LGNvbCkpIF92YWx1ZXMuU2V0VmFsdWUocm93LCBjb2wsIG51bGwpOwogICAgICAgIH0KICAgICAgICAKICAgICAgICBwcml2YXRlIHZvaWQgU2F2ZVBpdm90VGFibGVzKCkKICAgICAgICB7CiAgICAgICAgICAgIGZvcmVhY2ggKHZhciBwdCBpbiBQaXZvdFRhYmxlcykKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgaWYgKHB0LkRhdGFGaWVsZHMuQ291bnQgPiAxKQogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIFhtbEVsZW1lbnQgcGFyZW50Tm9kZTsKICAgICAgICAgICAgICAgICAgICBpZihwdC5EYXRhT25Sb3dzPT10cnVlKQogICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgcGFyZW50Tm9kZSA9ICBwdC5QaXZvdFRhYmxlWG1sLlNlbGVjdFNpbmdsZU5vZGUoIi8vZDpyb3dGaWVsZHMiLCBwdC5OYW1lU3BhY2VNYW5hZ2VyKSBhcyBYbWxFbGVtZW50OwogICAgICAgICAgICAgICAgICAgICAgICBpZiAocGFyZW50Tm9kZSA9PSBudWxsKQogICAgICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBwdC5DcmVhdGVOb2RlKCJkOnJvd0ZpZWxkcyIpOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgcGFyZW50Tm9kZSA9IHB0LlBpdm90VGFibGVYbWwuU2VsZWN0U2luZ2xlTm9kZSgiLy9kOnJvd0ZpZWxkcyIsIHB0Lk5hbWVTcGFjZU1hbmFnZXIpIGFzIFhtbEVsZW1lbnQ7CiAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgZWxzZQogICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgcGFyZW50Tm9kZSA9ICBwdC5QaXZvdFRhYmxlWG1sLlNlbGVjdFNpbmdsZU5vZGUoIi8vZDpjb2xGaWVsZHMiLCBwdC5OYW1lU3BhY2VNYW5hZ2VyKSBhcyBYbWxFbGVtZW50OwogICAgICAgICAgICAgICAgICAgICAgICBpZiAocGFyZW50Tm9kZSA9PSBudWxsKQogICAgICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBwdC5DcmVhdGVOb2RlKCJkOmNvbEZpZWxkcyIpOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgcGFyZW50Tm9kZSA9IHB0LlBpdm90VGFibGVYbWwuU2VsZWN0U2luZ2xlTm9kZSgiLy9kOmNvbEZpZWxkcyIsIHB0Lk5hbWVTcGFjZU1hbmFnZXIpIGFzIFhtbEVsZW1lbnQ7CiAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgICAgIGlmIChwYXJlbnROb2RlLlNlbGVjdFNpbmdsZU5vZGUoImQ6ZmllbGRbQCB4PSBcIi0yXCJdIiwgcHQuTmFtZVNwYWNlTWFuYWdlcikgPT0gbnVsbCkKICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgIFhtbEVsZW1lbnQgZmllbGROb2RlID0gcHQuUGl2b3RUYWJsZVhtbC5DcmVhdGVFbGVtZW50KCJmaWVsZCIsIEV4Y2VsUGFja2FnZS5zY2hlbWFNYWluKTsKICAgICAgICAgICAgICAgICAgICAgICAgZmllbGROb2RlLlNldEF0dHJpYnV0ZSgieCIsICItMiIpOwogICAgICAgICAgICAgICAgICAgICAgICBwYXJlbnROb2RlLkFwcGVuZENoaWxkKGZpZWxkTm9kZSk7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgdmFyIHdzID0gV29ya2Jvb2suV29ya3NoZWV0c1twdC5DYWNoZURlZmluaXRpb24uU291cmNlUmFuZ2UuV29ya1NoZWV0XTsKICAgICAgICAgICAgICAgIHZhciB0ID0gd3MuVGFibGVzLkdldEZyb21SYW5nZShwdC5DYWNoZURlZmluaXRpb24uU291cmNlUmFuZ2UpOwogICAgICAgICAgICAgICAgdmFyIGZpZWxkcyA9CiAgICAgICAgICAgICAgICAgICAgcHQuQ2FjaGVEZWZpbml0aW9uLkNhY2hlRGVmaW5pdGlvblhtbC5TZWxlY3ROb2RlcygKICAgICAgICAgICAgICAgICAgICAgICAgImQ6cGl2b3RDYWNoZURlZmluaXRpb24vZDpjYWNoZUZpZWxkcy9kOmNhY2hlRmllbGQiLCBOYW1lU3BhY2VNYW5hZ2VyKTsKICAgICAgICAgICAgICAgIGludCBpeCA9IDA7CiAgICAgICAgICAgICAgICBpZiAoZmllbGRzICE9IG51bGwpCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgdmFyIGZsZHMgPSBuZXcgSGFzaFNldDxzdHJpbmc+KCk7CiAgICAgICAgICAgICAgICAgICAgZm9yZWFjaCAoWG1sRWxlbWVudCBub2RlIGluIGZpZWxkcykKICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChpeCA+PSBwdC5DYWNoZURlZmluaXRpb24uU291cmNlUmFuZ2UuQ29sdW1ucykgYnJlYWs7CiAgICAgICAgICAgICAgICAgICAgICAgIHZhciBmbGROYW1lID0gbm9kZS5HZXRBdHRyaWJ1dGUoIm5hbWUiKTsgICAgICAgICAgICAgICAgICAgICAgICAvL0ZpeGVzIGlzc3VlIDE1Mjk1IGR1cCBuYW1lIGVycm9yCiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChzdHJpbmcuSXNOdWxsT3JFbXB0eShmbGROYW1lKSkKICAgICAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgZmxkTmFtZSA9ICh0ID09IG51bGwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA/IHB0LkNhY2hlRGVmaW5pdGlvbi5Tb3VyY2VSYW5nZS5PZmZzZXQoMCwgaXgrKywgMSwgMSkuVmFsdWUuVG9TdHJpbmcoKQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDogdC5Db2x1bW5zW2l4KytdLk5hbWUpOwogICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChmbGRzLkNvbnRhaW5zKGZsZE5hbWUpKQogICAgICAgICAgICAgICAgICAgICAgICB7ICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgZmxkTmFtZSA9IEdldE5ld05hbWUoZmxkcywgZmxkTmFtZSk7CiAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgZmxkcy5BZGQoZmxkTmFtZSk7CiAgICAgICAgICAgICAgICAgICAgICAgIG5vZGUuU2V0QXR0cmlidXRlKCJuYW1lIiwgZmxkTmFtZSk7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIGZvcmVhY2ggKHZhciBkZiBpbiBwdC5EYXRhRmllbGRzKQogICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHN0cmluZy5Jc051bGxPckVtcHR5KGRmLk5hbWUpKQogICAgICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBzdHJpbmcgbmFtZTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChkZi5GdW5jdGlvbiA9PSBEYXRhRmllbGRGdW5jdGlvbnMuTm9uZSkKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBuYW1lID0gZGYuRmllbGQuTmFtZTsgLy9OYW1lIG11c3QgYmUgc2V0IG9yIEV4Y2VsIHdpbGwgY3Jhc2ggb24gcmVuYW1lLiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBlbHNlCiAgICAgICAgICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbmFtZSA9IGRmLkZ1bmN0aW9uLlRvU3RyaW5nKCkgKyAiIG9mICIgKyBkZi5GaWVsZC5OYW1lOyAvL05hbWUgbXVzdCBiZSBzZXQgb3IgRXhjZWwgd2lsbCBjcmFzaCBvbiByZW5hbWUuCiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAvL01ha2Ugc3VyZSBuYW1lIGlzIHVuaXF1ZQogICAgICAgICAgICAgICAgICAgICAgICAgICAgdmFyIG5ld05hbWUgPSBuYW1lOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgdmFyIGkgPSAyOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgd2hpbGUgKHB0LkRhdGFGaWVsZHMuRXhpc3RzRGZOYW1lKG5ld05hbWUsIGRmKSkKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBuZXdOYW1lID0gbmFtZSArIChpKyspLlRvU3RyaW5nKEN1bHR1cmVJbmZvLkludmFyaWFudEN1bHR1cmUpOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICAgICAgICAgZGYuTmFtZSA9IG5ld05hbWU7CiAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBwdC5QaXZvdFRhYmxlWG1sLlNhdmUocHQuUGFydC5HZXRTdHJlYW0oRmlsZU1vZGUuQ3JlYXRlKSk7CiAgICAgICAgICAgICAgICBwdC5DYWNoZURlZmluaXRpb24uQ2FjaGVEZWZpbml0aW9uWG1sLlNhdmUocHQuQ2FjaGVEZWZpbml0aW9uLlBhcnQuR2V0U3RyZWFtKEZpbGVNb2RlLkNyZWF0ZSkpOwogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICBwcml2YXRlIHN0cmluZyBHZXROZXdOYW1lKEhhc2hTZXQ8c3RyaW5nPiBmbGRzLCBzdHJpbmcgZmxkTmFtZSkKICAgICAgICB7CiAgICAgICAgICAgIGludCBpeCA9IDI7CiAgICAgICAgICAgIHdoaWxlIChmbGRzLkNvbnRhaW5zKGZsZE5hbWUgKyBpeC5Ub1N0cmluZyhDdWx0dXJlSW5mby5JbnZhcmlhbnRDdWx0dXJlKSkpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIGl4Kys7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgcmV0dXJuIGZsZE5hbWUgKyBpeC5Ub1N0cmluZyhDdWx0dXJlSW5mby5JbnZhcmlhbnRDdWx0dXJlKTsKICAgICAgICB9CgogICAgICAgIHByaXZhdGUgc3RhdGljIHN0cmluZyBHZXRUb3RhbEZ1bmN0aW9uKEV4Y2VsVGFibGVDb2x1bW4gY29sLHN0cmluZyBGdW5jdGlvbk51bSkKICAgICAgICB7CiAgICAgICAgICAgIHJldHVybiBzdHJpbmcuRm9ybWF0KCJTVUJUT1RBTCh7MH0sezF9W3syfV0pIiwgRnVuY3Rpb25OdW0sIGNvbC5fdGJsLk5hbWUsIGNvbC5OYW1lKTsKICAgICAgICB9CiAgICAgICAgcHJpdmF0ZSB2b2lkIFNhdmVYbWwoU3RyZWFtIHN0cmVhbSkKICAgICAgICB7CiAgICAgICAgICAgIC8vQ3JlYXRlIHRoZSBub2RlcyBpZiB0aGV5IGRvIG5vdCBleGlzdC4KICAgICAgICAgICAgU3RyZWFtV3JpdGVyIHN3ID0gbmV3IFN0cmVhbVdyaXRlcihzdHJlYW0sIFN5c3RlbS5UZXh0LkVuY29kaW5nLlVURjgsIDY1NTM2KTsKICAgICAgICAgICAgaWYgKHRoaXMgaXMgRXhjZWxDaGFydHNoZWV0KQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBzdy5Xcml0ZShfd29ya3NoZWV0WG1sLk91dGVyWG1sKTsKICAgICAgICAgICAgfQogICAgICAgICAgICBlbHNlCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIENyZWF0ZU5vZGUoImQ6Y29scyIpOwogICAgICAgICAgICAgICAgQ3JlYXRlTm9kZSgiZDpzaGVldERhdGEiKTsKICAgICAgICAgICAgICAgIENyZWF0ZU5vZGUoImQ6bWVyZ2VDZWxscyIpOwogICAgICAgICAgICAgICAgQ3JlYXRlTm9kZSgiZDpoeXBlcmxpbmtzIik7CiAgICAgICAgICAgICAgICBDcmVhdGVOb2RlKCJkOnJvd0JyZWFrcyIpOwogICAgICAgICAgICAgICAgQ3JlYXRlTm9kZSgiZDpjb2xCcmVha3MiKTsKCiAgICAgICAgICAgICAgICAvL1N0cmVhbVdyaXRlciBzdz1uZXcgU3RyZWFtV3JpdGVyKFBhcnQuR2V0U3RyZWFtKEZpbGVNb2RlLkNyZWF0ZSwgRmlsZUFjY2Vzcy5Xcml0ZSkpOwogICAgICAgICAgICAgICAgdmFyIHhtbCA9IF93b3Jrc2hlZXRYbWwuT3V0ZXJYbWw7CiAgICAgICAgICAgICAgICBpbnQgY29sU3RhcnQgPSAwLCBjb2xFbmQgPSAwOwogICAgICAgICAgICAgICAgR2V0QmxvY2tQb3MoeG1sLCAiY29scyIsIHJlZiBjb2xTdGFydCwgcmVmIGNvbEVuZCk7CgogICAgICAgICAgICAgICAgc3cuV3JpdGUoeG1sLlN1YnN0cmluZygwLCBjb2xTdGFydCkpOwogICAgICAgICAgICAgICAgdmFyIGNvbEJyZWFrcyA9IG5ldyBMaXN0PGludD4oKTsKICAgICAgICAgICAgICAgIC8vaWYgKF9jb2x1bW5zLkNvdW50ID4gMCkKICAgICAgICAgICAgICAgIC8vewogICAgICAgICAgICAgICAgVXBkYXRlQ29sdW1uRGF0YShzdyk7CiAgICAgICAgICAgICAgICAvL30KCiAgICAgICAgICAgICAgICBpbnQgY2VsbFN0YXJ0ID0gY29sRW5kLCBjZWxsRW5kID0gY29sRW5kOwogICAgICAgICAgICAgICAgR2V0QmxvY2tQb3MoeG1sLCAic2hlZXREYXRhIiwgcmVmIGNlbGxTdGFydCwgcmVmIGNlbGxFbmQpOwoKICAgICAgICAgICAgICAgIHN3LldyaXRlKHhtbC5TdWJzdHJpbmcoY29sRW5kLCBjZWxsU3RhcnQgLSBjb2xFbmQpKTsKICAgICAgICAgICAgICAgIHZhciByb3dCcmVha3MgPSBuZXcgTGlzdDxpbnQ+KCk7CiAgICAgICAgICAgICAgICBVcGRhdGVSb3dDZWxsRGF0YShzdyk7CgogICAgICAgICAgICAgICAgaW50IG1lcmdlU3RhcnQgPSBjZWxsRW5kLCBtZXJnZUVuZCA9IGNlbGxFbmQ7CgogICAgICAgICAgICAgICAgR2V0QmxvY2tQb3MoeG1sLCAibWVyZ2VDZWxscyIsIHJlZiBtZXJnZVN0YXJ0LCByZWYgbWVyZ2VFbmQpOwogICAgICAgICAgICAgICAgc3cuV3JpdGUoeG1sLlN1YnN0cmluZyhjZWxsRW5kLCBtZXJnZVN0YXJ0IC0gY2VsbEVuZCkpOwoKICAgICAgICAgICAgICAgIENsZWFudXBNZXJnZWRDZWxscyhfbWVyZ2VkQ2VsbHMpOwogICAgICAgICAgICAgICAgaWYgKF9tZXJnZWRDZWxscy5Db3VudCA+IDApCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgVXBkYXRlTWVyZ2VkQ2VsbHMoc3cpOwogICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgIGludCBoeXBlclN0YXJ0ID0gbWVyZ2VFbmQsIGh5cGVyRW5kID0gbWVyZ2VFbmQ7CiAgICAgICAgICAgICAgICBHZXRCbG9ja1Bvcyh4bWwsICJoeXBlcmxpbmtzIiwgcmVmIGh5cGVyU3RhcnQsIHJlZiBoeXBlckVuZCk7CiAgICAgICAgICAgICAgICBzdy5Xcml0ZSh4bWwuU3Vic3RyaW5nKG1lcmdlRW5kLCBoeXBlclN0YXJ0IC0gbWVyZ2VFbmQpKTsKICAgICAgICAgICAgICAgIC8vaWYgKF9oeXBlckxpbmtDZWxscy5Db3VudCA+IDApCiAgICAgICAgICAgICAgICAvL3sKICAgICAgICAgICAgICAgIFVwZGF0ZUh5cGVyTGlua3Moc3cpOwogICAgICAgICAgICAgICAgLy8gfQoKICAgICAgICAgICAgICAgIGludCByb3dCcmVha1N0YXJ0ID0gaHlwZXJFbmQsIHJvd0JyZWFrRW5kID0gaHlwZXJFbmQ7CiAgICAgICAgICAgICAgICBHZXRCbG9ja1Bvcyh4bWwsICJyb3dCcmVha3MiLCByZWYgcm93QnJlYWtTdGFydCwgcmVmIHJvd0JyZWFrRW5kKTsKICAgICAgICAgICAgICAgIHN3LldyaXRlKHhtbC5TdWJzdHJpbmcoaHlwZXJFbmQsIHJvd0JyZWFrU3RhcnQgLSBoeXBlckVuZCkpOwogICAgICAgICAgICAgICAgLy9pZiAocm93QnJlYWtzLkNvdW50ID4gMCkKICAgICAgICAgICAgICAgIC8vewogICAgICAgICAgICAgICAgVXBkYXRlUm93QnJlYWtzKHN3KTsKICAgICAgICAgICAgICAgIC8vfQoKICAgICAgICAgICAgICAgIGludCBjb2xCcmVha1N0YXJ0ID0gcm93QnJlYWtFbmQsIGNvbEJyZWFrRW5kID0gcm93QnJlYWtFbmQ7CiAgICAgICAgICAgICAgICBHZXRCbG9ja1Bvcyh4bWwsICJjb2xCcmVha3MiLCByZWYgY29sQnJlYWtTdGFydCwgcmVmIGNvbEJyZWFrRW5kKTsKICAgICAgICAgICAgICAgIHN3LldyaXRlKHhtbC5TdWJzdHJpbmcocm93QnJlYWtFbmQsIGNvbEJyZWFrU3RhcnQgLSByb3dCcmVha0VuZCkpOwogICAgICAgICAgICAgICAgLy9pZiAoY29sQnJlYWtzLkNvdW50ID4gMCkKICAgICAgICAgICAgICAgIC8vewogICAgICAgICAgICAgICAgVXBkYXRlQ29sQnJlYWtzKHN3KTsKICAgICAgICAgICAgICAgIC8vfQogICAgICAgICAgICAgICAgc3cuV3JpdGUoeG1sLlN1YnN0cmluZyhjb2xCcmVha0VuZCwgeG1sLkxlbmd0aCAtIGNvbEJyZWFrRW5kKSk7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgc3cuRmx1c2goKTsKICAgICAgICAgICAgLy9zdy5DbG9zZSgpOwogICAgICAgIH0KCiAgICAgICAgcHJpdmF0ZSB2b2lkIENsZWFudXBNZXJnZWRDZWxscyhNZXJnZUNlbGxzQ29sbGVjdGlvbiBfbWVyZ2VkQ2VsbHMpCiAgICAgICAgewogICAgICAgICAgICBpbnQgaT0wOwogICAgICAgICAgICB3aGlsZSAoaSA8IF9tZXJnZWRDZWxscy5MaXN0LkNvdW50KQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBpZiAoX21lcmdlZENlbGxzW2ldID09IG51bGwpCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgX21lcmdlZENlbGxzLkxpc3QuUmVtb3ZlQXQoaSk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBlbHNlCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgaSsrOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIHByaXZhdGUgdm9pZCBVcGRhdGVDb2xCcmVha3MoU3RyZWFtV3JpdGVyIHN3KQogICAgICAgIHsKICAgICAgICAgICAgU3RyaW5nQnVpbGRlciBicmVha3MgPSBuZXcgU3RyaW5nQnVpbGRlcigpOwogICAgICAgICAgICBpbnQgY291bnQgPSAwOwogICAgICAgICAgICB2YXIgY3NlID0gbmV3IENlbGxzU3RvcmVFbnVtZXJhdG9yPG9iamVjdD4oX3ZhbHVlcywgMCwgMCwgMCwgRXhjZWxQYWNrYWdlLk1heENvbHVtbnMpOwogICAgICAgICAgICAvL2ZvcmVhY2ggKEV4Y2VsQ29sdW1uIGNvbCBpbiBfY29sdW1ucykKICAgICAgICAgICAgd2hpbGUoY3NlLk5leHQoKSkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgdmFyIGNvbD1jc2UuVmFsdWUgYXMgRXhjZWxDb2x1bW47CiAgICAgICAgICAgICAgICBpZiAoY29sICE9IG51bGwgJiYgY29sLlBhZ2VCcmVhaykKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICBicmVha3MuQXBwZW5kRm9ybWF0KCI8YnJrIGlkPVwiezB9XCIgbWF4PVwiMTYzODNcIiBtYW49XCIxXCIgLz4iLCBjc2UuQ29sdW1uKTsKICAgICAgICAgICAgICAgICAgICBjb3VudCsrOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgICAgIGlmIChjb3VudCA+IDApCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIHN3LldyaXRlKHN0cmluZy5Gb3JtYXQoIjxjb2xCcmVha3MgY291bnQ9XCJ7MH1cIiBtYW51YWxCcmVha0NvdW50PVwiezB9XCI+ezF9PC9jb2xCcmVha3M+IiwgY291bnQsIGJyZWFrcy5Ub1N0cmluZygpKSk7CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIHByaXZhdGUgdm9pZCBVcGRhdGVSb3dCcmVha3MoU3RyZWFtV3JpdGVyIHN3KQogICAgICAgIHsKICAgICAgICAgICAgU3RyaW5nQnVpbGRlciBicmVha3M9bmV3IFN0cmluZ0J1aWxkZXIoKTsKICAgICAgICAgICAgaW50IGNvdW50ID0gMDsKICAgICAgICAgICAgdmFyIGNzZSA9IG5ldyBDZWxsc1N0b3JlRW51bWVyYXRvcjxvYmplY3Q+KF92YWx1ZXMsIDAsIDAsIEV4Y2VsUGFja2FnZS5NYXhSb3dzLCAwKTsKICAgICAgICAgICAgLy9mb3JlYWNoKEV4Y2VsUm93IHJvdyBpbiBfcm93cykgICAgICAgICAgICAKICAgICAgICAgICAgd2hpbGUoY3NlLk5leHQoKSkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgdmFyIHJvdz1jc2UuVmFsdWUgYXMgUm93SW50ZXJuYWw7CiAgICAgICAgICAgICAgICBpZiAocm93ICE9IG51bGwgJiYgcm93LlBhZ2VCcmVhaykKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICBicmVha3MuQXBwZW5kRm9ybWF0KCI8YnJrIGlkPVwiezB9XCIgbWF4PVwiMTA0ODU3NVwiIG1hbj1cIjFcIiAvPiIsIGNzZS5Sb3cpOwogICAgICAgICAgICAgICAgICAgIGNvdW50Kys7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICAgICAgaWYgKGNvdW50PjApCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIHN3LldyaXRlKHN0cmluZy5Gb3JtYXQoIjxyb3dCcmVha3MgY291bnQ9XCJ7MH1cIiBtYW51YWxCcmVha0NvdW50PVwiezB9XCI+ezF9PC9yb3dCcmVha3M+IiwgY291bnQsIGJyZWFrcy5Ub1N0cmluZygpKSk7ICAgICAgICAgICAgICAgIAogICAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIC8vLyA8c3VtbWFyeT4KICAgICAgICAvLy8gSW5zZXJ0cyB0aGUgY29scyBjb2xsZWN0aW9uIGludG8gdGhlIFhNTCBkb2N1bWVudAogICAgICAgIC8vLyA8L3N1bW1hcnk+CiAgICAgICAgcHJpdmF0ZSB2b2lkIFVwZGF0ZUNvbHVtbkRhdGEoU3RyZWFtV3JpdGVyIHN3KQogICAgICAgIHsKICAgICAgICAgICAgLy9FeGNlbENvbHVtbiBwcmV2Q29sID0gbnVsbDsgICAvL2NvbW1lbnRlZCBvdXQgMTEvMS0xMiBKSyAKICAgICAgICAgICAgLy9mb3JlYWNoIChFeGNlbENvbHVtbiBjb2wgaW4gX2NvbHVtbnMpCiAgICAgICAgICAgIC8veyAgICAgICAgICAgICAgICAKICAgICAgICAgICAgLy8gICAgaWYgKHByZXZDb2wgIT0gbnVsbCkKICAgICAgICAgICAgLy8gICAgewogICAgICAgICAgICAvLyAgICAgICAgaWYocHJldkNvbC5Db2x1bW5NYXggIT0gY29sLkNvbHVtbk1pbi0xKQogICAgICAgICAgICAvLyAgICAgICAgewogICAgICAgICAgICAvLyAgICAgICAgICAgIHByZXZDb2wuX2NvbHVtbk1heD1jb2wuQ29sdW1uTWluLTE7CiAgICAgICAgICAgIC8vICAgICAgICB9CiAgICAgICAgICAgIC8vICAgIH0KICAgICAgICAgICAgLy8gICAgcHJldkNvbCA9IGNvbDsKICAgICAgICAgICAgLy99CiAgICAgICAgICAgIHZhciBjc2UgPSBuZXcgQ2VsbHNTdG9yZUVudW1lcmF0b3I8b2JqZWN0PihfdmFsdWVzLCAwLCAxLCAwLCBFeGNlbFBhY2thZ2UuTWF4Q29sdW1ucyk7CiAgICAgICAgICAgIC8vc3cuV3JpdGUoIjxjb2xzPiIpOwogICAgICAgICAgICAvL2ZvcmVhY2ggKEV4Y2VsQ29sdW1uIGNvbCBpbiBfY29sdW1ucykKICAgICAgICAgICAgYm9vbCBmaXJzdCA9IHRydWU7CiAgICAgICAgICAgIHdoaWxlKGNzZS5OZXh0KCkpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIGlmIChmaXJzdCkKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICBzdy5Xcml0ZSgiPGNvbHM+Iik7CiAgICAgICAgICAgICAgICAgICAgZmlyc3QgPSBmYWxzZTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIHZhciBjb2wgPSBjc2UuVmFsdWUgYXMgRXhjZWxDb2x1bW47CiAgICAgICAgICAgICAgICBFeGNlbFN0eWxlQ29sbGVjdGlvbjxFeGNlbFhmcz4gY2VsbFhmcyA9IF9wYWNrYWdlLldvcmtib29rLlN0eWxlcy5DZWxsWGZzOwoKICAgICAgICAgICAgICAgIHN3LldyaXRlKCI8Y29sIG1pbj1cInswfVwiIG1heD1cInsxfVwiIiwgY29sLkNvbHVtbk1pbiwgY29sLkNvbHVtbk1heCk7CiAgICAgICAgICAgICAgICBpZiAoY29sLkhpZGRlbiA9PSB0cnVlKQogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIC8vc2JYbWwuQXBwZW5kKCIgd2lkdGg9XCIwXCIgaGlkZGVuPVwiMVwiIGN1c3RvbVdpZHRoPVwiMVwiIik7CiAgICAgICAgICAgICAgICAgICAgc3cuV3JpdGUoIiBoaWRkZW49XCIxXCIiKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGVsc2UgaWYgKGNvbC5CZXN0Rml0KQogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIHN3LldyaXRlKCIgYmVzdEZpdD1cIjFcIiIpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgc3cuV3JpdGUoc3RyaW5nLkZvcm1hdChDdWx0dXJlSW5mby5JbnZhcmlhbnRDdWx0dXJlLCAiIHdpZHRoPVwiezB9XCIgY3VzdG9tV2lkdGg9XCIxXCIiLCBjb2wuV2lkdGgpKTsKICAgICAgICAgICAgICAgIGlmIChjb2wuT3V0bGluZUxldmVsID4gMCkKICAgICAgICAgICAgICAgIHsgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgIHN3LldyaXRlKCIgb3V0bGluZUxldmVsPVwiezB9XCIgIiwgY29sLk91dGxpbmVMZXZlbCk7CiAgICAgICAgICAgICAgICAgICAgaWYgKGNvbC5Db2xsYXBzZWQpCiAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICBpZiAoY29sLkhpZGRlbikKICAgICAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgc3cuV3JpdGUoIiBjb2xsYXBzZWQ9XCIxXCIiKTsKICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICAgICBlbHNlCiAgICAgICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN3LldyaXRlKCIgY29sbGFwc2VkPVwiMVwiIGhpZGRlbj1cIjFcIiIpOyAvL0Fsd2F5cyBoaWRkZW4KICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGlmIChjb2wuUGhvbmV0aWMpCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgc3cuV3JpdGUoIiBwaG9uZXRpYz1cIjFcIiIpOwogICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgIHZhciBzdHlsZUlEID0gY29sLlN0eWxlSUQgPj0gMCA/IGNlbGxYZnNbY29sLlN0eWxlSURdLm5ld0lEIDogY29sLlN0eWxlSUQ7CiAgICAgICAgICAgICAgICBpZiAoc3R5bGVJRCA+IDApCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgc3cuV3JpdGUoIiBzdHlsZT1cInswfVwiIiwgc3R5bGVJRCk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBzdy5Xcml0ZSgiIC8+Iik7CgogICAgICAgICAgICAgICAgLy9pZiAoY29sLlBhZ2VCcmVhaykKICAgICAgICAgICAgICAgIC8vewogICAgICAgICAgICAgICAgLy8gICAgY29sQnJlYWtzLkFkZChjb2wuQ29sdW1uTWluKTsKICAgICAgICAgICAgICAgIC8vfQogICAgICAgICAgICB9CiAgICAgICAgICAgIGlmICghZmlyc3QpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIHN3LldyaXRlKCI8L2NvbHM+Iik7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgLy8vIDxzdW1tYXJ5PgogICAgICAgIC8vLyBJbnNlcnQgcm93IGFuZCBjZWxscyBpbnRvIHRoZSBYTUwgZG9jdW1lbnQKICAgICAgICAvLy8gPC9zdW1tYXJ5PgogICAgICAgIHByaXZhdGUgdm9pZCBVcGRhdGVSb3dDZWxsRGF0YShTdHJlYW1Xcml0ZXIgc3cpCiAgICAgICAgewogICAgICAgICAgICBFeGNlbFN0eWxlQ29sbGVjdGlvbjxFeGNlbFhmcz4gY2VsbFhmcyA9IF9wYWNrYWdlLldvcmtib29rLlN0eWxlcy5DZWxsWGZzOwogICAgICAgICAgICAKICAgICAgICAgICAgaW50IHJvdyA9IC0xOwoKICAgICAgICAgICAgU3RyaW5nQnVpbGRlciBzYlhtbCA9IG5ldyBTdHJpbmdCdWlsZGVyKCk7CiAgICAgICAgICAgIHZhciBzcyA9IF9wYWNrYWdlLldvcmtib29rLl9zaGFyZWRTdHJpbmdzOwogICAgICAgICAgICB2YXIgc3R5bGVzID0gX3BhY2thZ2UuV29ya2Jvb2suU3R5bGVzOwogICAgICAgICAgICB2YXIgY2FjaGUgPSBuZXcgU3RyaW5nQnVpbGRlcigpOwogICAgICAgICAgICBjYWNoZS5BcHBlbmQoIjxzaGVldERhdGE+Iik7CiAgICAgICAgICAgIAogICAgICAgICAgICAvL1NldCBhIHZhbHVlIGZvciBjZWxscyB3aXRoIHN0eWxlIGFuZCBubyB2YWx1ZSBzZXQuCiAgICAgICAgICAgIHZhciBjc2VTdHlsZSA9IG5ldyBDZWxsc1N0b3JlRW51bWVyYXRvcjxpbnQ+KF9zdHlsZXMsIDAsIDAsIEV4Y2VsUGFja2FnZS5NYXhSb3dzLCBFeGNlbFBhY2thZ2UuTWF4Q29sdW1ucyk7CiAgICAgICAgICAgIGZvcmVhY2ggKHZhciBzIGluIGNzZVN0eWxlKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBpZighX3ZhbHVlcy5FeGlzdHMoY3NlU3R5bGUuUm93LCBjc2VTdHlsZS5Db2x1bW4pKQogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIF92YWx1ZXMuU2V0VmFsdWUoY3NlU3R5bGUuUm93LCBjc2VTdHlsZS5Db2x1bW4sIG51bGwpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CgogICAgICAgICAgICB2YXIgY3NlID0gbmV3IENlbGxzU3RvcmVFbnVtZXJhdG9yPG9iamVjdD4oX3ZhbHVlcywgMSwgMCwgRXhjZWxQYWNrYWdlLk1heFJvd3MsIEV4Y2VsUGFja2FnZS5NYXhDb2x1bW5zKTsKICAgICAgICAgICAgLy9mb3JlYWNoIChJUmFuZ2VJRCByIGluIF9jZWxscykKICAgICAgICAgICAgd2hpbGUoY3NlLk5leHQoKSkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgaWYgKGNzZS5Db2x1bW4+MCkKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICBpbnQgc3R5bGVJRCA9IGNlbGxYZnNbc3R5bGVzLkdldFN0eWxlSWQodGhpcywgY3NlLlJvdywgY3NlLkNvbHVtbildLm5ld0lEOwogICAgICAgICAgICAgICAgICAgIC8vQWRkIHRoZSByb3cgZWxlbWVudCBpZiBpdCdzIGEgbmV3IHJvdwogICAgICAgICAgICAgICAgICAgIGlmIChjc2UuUm93ICE9IHJvdykKICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgIFdyaXRlUm93KGNhY2hlLCBjZWxsWGZzLCByb3csIGNzZS5Sb3cpOwogICAgICAgICAgICAgICAgICAgICAgICByb3cgPSBjc2UuUm93OwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICBvYmplY3QgdiA9IGNzZS5WYWx1ZTsKICAgICAgICAgICAgICAgICAgICBvYmplY3QgZm9ybXVsYSA9IF9mb3JtdWxhcy5HZXRWYWx1ZShjc2UuUm93LCBjc2UuQ29sdW1uKTsKICAgICAgICAgICAgICAgICAgICBpZiAoZm9ybXVsYSBpcyBpbnQpCiAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICBpbnQgc2ZJZCA9IChpbnQpZm9ybXVsYTsKICAgICAgICAgICAgICAgICAgICAgICAgdmFyIGYgPSBfc2hhcmVkRm9ybXVsYXNbKGludClzZklkXTsKICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGYuQWRkcmVzcy5JbmRleE9mKCc6JykgPiAwKQogICAgICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoZi5TdGFydENvbCA9PSBjc2UuQ29sdW1uICYmIGYuU3RhcnRSb3cgPT0gY3NlLlJvdykKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoZi5Jc0FycmF5KQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY2FjaGUuQXBwZW5kRm9ybWF0KCI8YyByPVwiezB9XCIgcz1cInsxfVwiezV9PjxmIHJlZj1cInsyfVwiIHQ9XCJhcnJheVwiPnszfTwvZj57NH08L2M+IiwgY3NlLkNlbGxBZGRyZXNzLCBzdHlsZUlEIDwgMCA/IDAgOiBzdHlsZUlELCBmLkFkZHJlc3MsIFNlY3VyaXR5RWxlbWVudC5Fc2NhcGUoZi5Gb3JtdWxhKSwgR2V0Rm9ybXVsYVZhbHVlKHYpLCBHZXRDZWxsVHlwZSh2LHRydWUpKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZWxzZQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY2FjaGUuQXBwZW5kRm9ybWF0KCI8YyByPVwiezB9XCIgcz1cInsxfVwiezZ9PjxmIHJlZj1cInsyfVwiIHQ9XCJzaGFyZWRcIiAgc2k9XCJ7M31cIj57NH08L2Y+ezV9PC9jPiIsIGNzZS5DZWxsQWRkcmVzcywgc3R5bGVJRCA8IDAgPyAwIDogc3R5bGVJRCwgZi5BZGRyZXNzLCBzZklkLCBTZWN1cml0eUVsZW1lbnQuRXNjYXBlKGYuRm9ybXVsYSksIEdldEZvcm11bGFWYWx1ZSh2KSwgR2V0Q2VsbFR5cGUodix0cnVlKSk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVsc2UgaWYgKGYuSXNBcnJheSkKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjYWNoZS5BcHBlbmRGb3JtYXQoIjxjIHI9XCJ7MH1cIiBzPVwiezF9XCIgLz4iLCBjc2UuQ2VsbEFkZHJlc3MsIHN0eWxlSUQgPCAwID8gMCA6IHN0eWxlSUQpOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICAgICAgICAgZWxzZQogICAgICAgICAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNhY2hlLkFwcGVuZEZvcm1hdCgiPGMgcj1cInswfVwiIHM9XCJ7MX1cIns0fT48ZiB0PVwic2hhcmVkXCIgc2k9XCJ7Mn1cIiAvPnszfTwvYz4iLCBjc2UuQ2VsbEFkZHJlc3MsIHN0eWxlSUQgPCAwID8gMCA6IHN0eWxlSUQsIHNmSWQsIEdldEZvcm11bGFWYWx1ZSh2KSwgR2V0Q2VsbFR5cGUodix0cnVlKSk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgZWxzZQogICAgICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBXZSBjYW4gYWxzbyBoYXZlIGEgc2luZ2xlIGNlbGwgYXJyYXkgZm9ybXVsYQogICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYoZi5Jc0FycmF5KQogICAgICAgICAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNhY2hlLkFwcGVuZEZvcm1hdCgiPGMgcj1cInswfVwiIHM9XCJ7MX1cIns1fT48ZiByZWY9XCJ7Mn1cIiB0PVwiYXJyYXlcIj57M308L2Y+ezR9PC9jPiIsIGNzZS5DZWxsQWRkcmVzcywgc3R5bGVJRCA8IDAgPyAwIDogc3R5bGVJRCwgc3RyaW5nLkZvcm1hdCgiezB9OnsxfSIsIGYuQWRkcmVzcywgZi5BZGRyZXNzKSwgU2VjdXJpdHlFbGVtZW50LkVzY2FwZShmLkZvcm11bGEpLCBHZXRGb3JtdWxhVmFsdWUodiksIEdldENlbGxUeXBlKHYsdHJ1ZSkpOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICAgICAgICAgZWxzZQogICAgICAgICAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNhY2hlLkFwcGVuZEZvcm1hdCgiPGMgcj1cInswfVwiIHM9XCJ7MX1cIj4iLCBmLkFkZHJlc3MsIHN0eWxlSUQgPCAwID8gMCA6IHN0eWxlSUQpOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNhY2hlLkFwcGVuZEZvcm1hdCgiPGY+ezB9PC9mPnsxfTwvYz4iLCBTZWN1cml0eUVsZW1lbnQuRXNjYXBlKGYuRm9ybXVsYSksIEdldEZvcm11bGFWYWx1ZSh2KSk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgZWxzZSBpZiAoZm9ybXVsYSE9bnVsbCAmJiBmb3JtdWxhLlRvU3RyaW5nKCkhPSIiKQogICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgY2FjaGUuQXBwZW5kRm9ybWF0KCI8YyByPVwiezB9XCIgcz1cInsxfVwiezJ9PiIsIGNzZS5DZWxsQWRkcmVzcywgc3R5bGVJRCA8IDAgPyAwIDogc3R5bGVJRCwgR2V0Q2VsbFR5cGUodix0cnVlKSk7CiAgICAgICAgICAgICAgICAgICAgICAgIGNhY2hlLkFwcGVuZEZvcm1hdCgiPGY+ezB9PC9mPnsxfTwvYz4iLCBTZWN1cml0eUVsZW1lbnQuRXNjYXBlKGZvcm11bGEuVG9TdHJpbmcoKSksIEdldEZvcm11bGFWYWx1ZSh2KSk7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIGVsc2UKICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgIGlmICh2ID09IG51bGwgJiYgc3R5bGVJRCA+IDApCiAgICAgICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNhY2hlLkFwcGVuZEZvcm1hdCgiPGMgcj1cInswfVwiIHM9XCJ7MX1cIiAvPiIsIGNzZS5DZWxsQWRkcmVzcywgc3R5bGVJRCA8IDAgPyAwIDogc3R5bGVJRCk7CiAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgZWxzZSBpZih2ICE9IG51bGwpCiAgICAgICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmICgodi5HZXRUeXBlKCkuSXNQcmltaXRpdmUgfHwgdiBpcyBkb3VibGUgfHwgdiBpcyBkZWNpbWFsIHx8IHYgaXMgRGF0ZVRpbWUgfHwgdiBpcyBUaW1lU3BhbikpCiAgICAgICAgICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy9zdHJpbmcgc3YgPSBHZXRWYWx1ZUZvclhtbCh2KTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjYWNoZS5BcHBlbmRGb3JtYXQoIjxjIHI9XCJ7MH1cIiBzPVwiezF9XCIgezJ9PiIsIGNzZS5DZWxsQWRkcmVzcywgc3R5bGVJRCA8IDAgPyAwIDogc3R5bGVJRCwgR2V0Q2VsbFR5cGUodikpOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNhY2hlLkFwcGVuZEZvcm1hdCgiezB9PC9jPiIsIEdldEZvcm11bGFWYWx1ZSh2KSk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBlbHNlCiAgICAgICAgICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaW50IGl4OwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmICghc3MuQ29udGFpbnNLZXkodi5Ub1N0cmluZygpKSkKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGl4ID0gc3MuQ291bnQ7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNzLkFkZCh2LlRvU3RyaW5nKCksIG5ldyBFeGNlbFdvcmtib29rLlNoYXJlZFN0cmluZ0l0ZW0oKSB7IGlzUmljaFRleHQgPSBfZmxhZ3MuR2V0RmxhZ1ZhbHVlKGNzZS5Sb3csY3NlLkNvbHVtbixDZWxsRmxhZ3MuUmljaFRleHQpLCBwb3MgPSBpeCB9KTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZWxzZQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaXggPSBzc1t2LlRvU3RyaW5nKCldLnBvczsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY2FjaGUuQXBwZW5kRm9ybWF0KCI8YyByPVwiezB9XCIgcz1cInsxfVwiIHQ9XCJzXCI+IiwgY3NlLkNlbGxBZGRyZXNzLCBzdHlsZUlEIDwgMCA/IDAgOiBzdHlsZUlEKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjYWNoZS5BcHBlbmRGb3JtYXQoIjx2PnswfTwvdj48L2M+IiwgaXgpOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIC8vLy9VcGRhdGUgaHlwZXJsaW5rcy4KICAgICAgICAgICAgICAgICAgIC8vaWYgKGNlbGwuSHlwZXJsaW5rICE9IG51bGwpCiAgICAgICAgICAgICAgICAgICAgLy97CiAgICAgICAgICAgICAgICAgICAgLy8gICAgX2h5cGVyTGlua0NlbGxzLkFkZChjZWxsLkNlbGxJRCk7CiAgICAgICAgICAgICAgICAgICAgLy99CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBlbHNlICAvL0V4Y2VsUm93CiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgLy9pbnQgbmV3Um93PSgoRXhjZWxSb3cpY3NlLlZhbHVlKS5Sb3c7CiAgICAgICAgICAgICAgICAgICAgV3JpdGVSb3coY2FjaGUsIGNlbGxYZnMsIHJvdywgY3NlLlJvdyk7CiAgICAgICAgICAgICAgICAgICAgcm93ID0gY3NlLlJvdzsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGlmIChjYWNoZS5MZW5ndGggPiAweDYwMDAwMCkKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICBzdy5Xcml0ZShjYWNoZS5Ub1N0cmluZygpKTsKICAgICAgICAgICAgICAgICAgICBjYWNoZSA9IG5ldyBTdHJpbmdCdWlsZGVyKCk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIGlmIChyb3cgIT0gLTEpIGNhY2hlLkFwcGVuZCgiPC9yb3c+Iik7CiAgICAgICAgICAgIGNhY2hlLkFwcGVuZCgiPC9zaGVldERhdGE+Iik7CiAgICAgICAgICAgIHN3LldyaXRlKGNhY2hlLlRvU3RyaW5nKCkpOwogICAgICAgICAgICBzdy5GbHVzaCgpOwogICAgICAgIH0KCiAgICAgICAgcHJpdmF0ZSBvYmplY3QgR2V0Rm9ybXVsYVZhbHVlKG9iamVjdCB2KQogICAgICAgIHsKICAgICAgICAgICAgLy9pZiAoX3BhY2thZ2UuV29ya2Jvb2suX2lzQ2FsY3VsYXRlZCkKICAgICAgICAgICAgLy97ICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgaWYgKHYgIT0gbnVsbCAmJiB2LlRvU3RyaW5nKCkhPSIiKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICByZXR1cm4gIjx2PiIgKyBTZWN1cml0eUVsZW1lbnQuRXNjYXBlKEdldFZhbHVlRm9yWG1sKHYpKSArICI8L3Y+IjsgLy9GaXhlcyBpc3N1ZSAxNTA3MQogICAgICAgICAgICB9ICAgICAgICAgICAgCiAgICAgICAgICAgIGVsc2UKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgcmV0dXJuICIiOwogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICBwcml2YXRlIHN0cmluZyBHZXRDZWxsVHlwZShvYmplY3QgdiwgYm9vbCBhbGxvd1N0cj1mYWxzZSkKICAgICAgICB7CiAgICAgICAgICAgIGlmICh2IGlzIGJvb2wpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIHJldHVybiAiIHQ9XCJiXCIiOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGVsc2UgaWYgKCh2IGlzIGRvdWJsZSAmJiBkb3VibGUuSXNJbmZpbml0eSgoZG91YmxlKXYpKSB8fCB2IGlzIEV4Y2VsRXJyb3JWYWx1ZSkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgcmV0dXJuICIgdD1cImVcIiI7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgZWxzZSBpZihhbGxvd1N0ciAmJiB2IT1udWxsICYmICEodi5HZXRUeXBlKCkuSXNQcmltaXRpdmUgfHwgdiBpcyBkb3VibGUgfHwgdiBpcyBkZWNpbWFsIHx8IHYgaXMgRGF0ZVRpbWUgfHwgdiBpcyBUaW1lU3BhbikpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIHJldHVybiAiIHQ9XCJzdHJcIiI7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgZWxzZQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICByZXR1cm4gIiI7CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIHByaXZhdGUgc3RyaW5nIEdldFZhbHVlRm9yWG1sKG9iamVjdCB2KQogICAgICAgIHsKICAgICAgICAgICAgc3RyaW5nIHM7CiAgICAgICAgICAgIHRyeQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBpZiAodiBpcyBEYXRlVGltZSkKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICBkb3VibGUgc2R2ID0gKChEYXRlVGltZSl2KS5Ub09BRGF0ZSgpOwoKICAgICAgICAgICAgICAgICAgICBpZiAoV29ya2Jvb2suRGF0ZTE5MDQpCiAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICBzZHYgLT0gRXhjZWxXb3JrYm9vay5kYXRlMTkwNE9mZnNldDsKICAgICAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgICAgIHMgPSBzZHYuVG9TdHJpbmcoQ3VsdHVyZUluZm8uSW52YXJpYW50Q3VsdHVyZSk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBlbHNlIGlmICh2IGlzIFRpbWVTcGFuKQogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIHMgPSBuZXcgRGF0ZVRpbWUoKChUaW1lU3Bhbil2KS5UaWNrcykuVG9PQURhdGUoKS5Ub1N0cmluZyhDdWx0dXJlSW5mby5JbnZhcmlhbnRDdWx0dXJlKTsgOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgZWxzZSBpZih2LkdldFR5cGUoKS5Jc1ByaW1pdGl2ZSB8fCB2IGlzIGRvdWJsZSB8fCB2IGlzIGRlY2ltYWwpCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgaWYgKHYgaXMgZG91YmxlICYmIGRvdWJsZS5Jc05hTigoZG91YmxlKXYpKQogICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgcyA9ICIiOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICBlbHNlIGlmICh2IGlzIGRvdWJsZSAmJiBkb3VibGUuSXNJbmZpbml0eSgoZG91YmxlKXYpKQogICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgcyA9ICIjTlVNISI7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIGVsc2UKICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgIHMgPSBDb252ZXJ0LlRvRG91YmxlKHYsIEN1bHR1cmVJbmZvLkludmFyaWFudEN1bHR1cmUpLlRvU3RyaW5nKCJSMTUiLCBDdWx0dXJlSW5mby5JbnZhcmlhbnRDdWx0dXJlKTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBlbHNlCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgcyA9IHYuVG9TdHJpbmcoKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQoKICAgICAgICAgICAgY2F0Y2gKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgcyA9ICIwIjsKICAgICAgICAgICAgfQogICAgICAgICAgICByZXR1cm4gczsKICAgICAgICB9CiAgICAgICAgcHJpdmF0ZSB2b2lkIFdyaXRlUm93KFN0cmluZ0J1aWxkZXIgY2FjaGUsIEV4Y2VsU3R5bGVDb2xsZWN0aW9uPEV4Y2VsWGZzPiBjZWxsWGZzLCBpbnQgcHJldlJvdywgaW50IHJvdykKICAgICAgICB7CiAgICAgICAgICAgIGlmIChwcmV2Um93ICE9IC0xKSBjYWNoZS5BcHBlbmQoIjwvcm93PiIpOwogICAgICAgICAgICAvL3Vsb25nIHJvd0lEID0gRXhjZWxSb3cuR2V0Um93SUQoU2hlZXRJRCwgcm93KTsKICAgICAgICAgICAgY2FjaGUuQXBwZW5kRm9ybWF0KCI8cm93IHI9XCJ7MH1cIiAiLCByb3cpOwogICAgICAgICAgICBSb3dJbnRlcm5hbCBjdXJyUm93ID0gX3ZhbHVlcy5HZXRWYWx1ZShyb3csIDApIGFzIFJvd0ludGVybmFsOwogICAgICAgICAgICBpZiAoY3VyclJvdyAhPSBudWxsKQogICAgICAgICAgICB7CgogICAgICAgICAgICAgICAgaWYgKGN1cnJSb3cuSGlkZGVuID09IHRydWUpCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgY2FjaGUuQXBwZW5kKCJodD1cIjBcIiBoaWRkZW49XCIxXCIgIik7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBlbHNlIGlmIChjdXJyUm93LkhlaWdodCAhPSBEZWZhdWx0Um93SGVpZ2h0ICYmIGN1cnJSb3cuSGVpZ2h0Pj0wKQogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIGNhY2hlLkFwcGVuZEZvcm1hdChzdHJpbmcuRm9ybWF0KEN1bHR1cmVJbmZvLkludmFyaWFudEN1bHR1cmUsICJodD1cInswfVwiICIsIGN1cnJSb3cuSGVpZ2h0KSk7CiAgICAgICAgICAgICAgICAgICAgaWYgKGN1cnJSb3cuQ3VzdG9tSGVpZ2h0KQogICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgY2FjaGUuQXBwZW5kKCJjdXN0b21IZWlnaHQ9XCIxXCIgIik7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgIGlmIChjdXJyUm93Lk91dGxpbmVMZXZlbCA+IDApCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgY2FjaGUuQXBwZW5kRm9ybWF0KCJvdXRsaW5lTGV2ZWwgPVwiezB9XCIgIiwgY3VyclJvdy5PdXRsaW5lTGV2ZWwpOwogICAgICAgICAgICAgICAgICAgIGlmIChjdXJyUm93LkNvbGxhcHNlZCkKICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChjdXJyUm93LkhpZGRlbikKICAgICAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgY2FjaGUuQXBwZW5kKCIgY29sbGFwc2VkPVwiMVwiICIpOwogICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgICAgIGVsc2UKICAgICAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgY2FjaGUuQXBwZW5kKCIgY29sbGFwc2VkPVwiMVwiIGhpZGRlbj1cIjFcIiAiKTsgLy9BbHdheXMgaGlkZGVuCiAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBpZiAoY3VyclJvdy5QaG9uZXRpYykKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICBjYWNoZS5BcHBlbmQoInBoPVwiMVwiICIpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgICAgIHZhciBzID0gX3N0eWxlcy5HZXRWYWx1ZShyb3csIDApOwogICAgICAgICAgICBpZiAocyA+IDApCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIGNhY2hlLkFwcGVuZEZvcm1hdCgicz1cInswfVwiIGN1c3RvbUZvcm1hdD1cIjFcIiIsIGNlbGxYZnNbc10ubmV3SUQpOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGNhY2hlLkFwcGVuZCgiPiIpOwogICAgICAgIH0KICAgICAgICBwcml2YXRlIHZvaWQgV3JpdGVSb3coU3RyZWFtV3JpdGVyIHN3LCBFeGNlbFN0eWxlQ29sbGVjdGlvbjxFeGNlbFhmcz4gY2VsbFhmcywgaW50IHByZXZSb3csIGludCByb3cpCiAgICAgICAgewogICAgICAgICAgICBpZiAocHJldlJvdyAhPSAtMSkgc3cuV3JpdGUoIjwvcm93PiIpOwogICAgICAgICAgICAvL3Vsb25nIHJvd0lEID0gRXhjZWxSb3cuR2V0Um93SUQoU2hlZXRJRCwgcm93KTsKICAgICAgICAgICAgc3cuV3JpdGUoIjxyb3cgcj1cInswfVwiICIsIHJvdyk7CiAgICAgICAgICAgIFJvd0ludGVybmFsIGN1cnJSb3cgPSBfdmFsdWVzLkdldFZhbHVlKHJvdywgMCkgYXMgUm93SW50ZXJuYWw7CiAgICAgICAgICAgIGlmIChjdXJyUm93IT1udWxsKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgIGlmIChjdXJyUm93LkhpZGRlbiA9PSB0cnVlKQogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIHN3LldyaXRlKCJodD1cIjBcIiBoaWRkZW49XCIxXCIgIik7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBlbHNlIGlmIChjdXJyUm93LkhlaWdodCAhPSBEZWZhdWx0Um93SGVpZ2h0KQogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIHN3LldyaXRlKHN0cmluZy5Gb3JtYXQoQ3VsdHVyZUluZm8uSW52YXJpYW50Q3VsdHVyZSwgImh0PVwiezB9XCIgIiwgY3VyclJvdy5IZWlnaHQpKTsKICAgICAgICAgICAgICAgICAgICBpZiAoY3VyclJvdy5DdXN0b21IZWlnaHQpCiAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICBzdy5Xcml0ZSgiY3VzdG9tSGVpZ2h0PVwiMVwiICIpOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICBpZiAoY3VyclJvdy5PdXRsaW5lTGV2ZWwgPiAwKQogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIHN3LldyaXRlKCJvdXRsaW5lTGV2ZWwgPVwiezB9XCIgIiwgY3VyclJvdy5PdXRsaW5lTGV2ZWwpOwogICAgICAgICAgICAgICAgICAgIGlmIChjdXJyUm93LkNvbGxhcHNlZCkKICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChjdXJyUm93LkhpZGRlbikKICAgICAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgc3cuV3JpdGUoIiBjb2xsYXBzZWQ9XCIxXCIgIik7CiAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgZWxzZQogICAgICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBzdy5Xcml0ZSgiIGNvbGxhcHNlZD1cIjFcIiBoaWRkZW49XCIxXCIgIik7IC8vQWx3YXlzIGhpZGRlbgogICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgaWYgKGN1cnJSb3cuUGhvbmV0aWMpCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgc3cuV3JpdGUoInBoPVwiMVwiICIpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgICAgIHZhciBzID0gX3N0eWxlcy5HZXRWYWx1ZShyb3csIDApOwogICAgICAgICAgICBpZiAocyA+IDApCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIHN3LldyaXRlKCJzPVwiezB9XCIgY3VzdG9tRm9ybWF0PVwiMVwiIiwgY2VsbFhmc1tzXS5uZXdJRCk7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgc3cuV3JpdGUoIj4iKTsKICAgICAgICB9CgogICAgICAgIC8vLyA8c3VtbWFyeT4KICAgICAgICAvLy8gVXBkYXRlIHhtbCB3aXRoIGh5cGVybGlua3MgCiAgICAgICAgLy8vIDwvc3VtbWFyeT4KICAgICAgICAvLy8gPHBhcmFtIG5hbWU9InN3Ij5UaGUgc3RyZWFtPC9wYXJhbT4KICAgICAgICBwcml2YXRlIHZvaWQgVXBkYXRlSHlwZXJMaW5rcyhTdHJlYW1Xcml0ZXIgc3cpCiAgICAgICAgewogICAgICAgICAgICAgICAgRGljdGlvbmFyeTxzdHJpbmcsIHN0cmluZz4gaHlwcyA9IG5ldyBEaWN0aW9uYXJ5PHN0cmluZywgc3RyaW5nPigpOwogICAgICAgICAgICAgICAgdmFyIGNzZSA9IG5ldyBDZWxsc1N0b3JlRW51bWVyYXRvcjxVcmk+KF9oeXBlckxpbmtzKTsKICAgICAgICAgICAgICAgIGJvb2wgZmlyc3QgPSB0cnVlOwogICAgICAgICAgICAgICAgLy9mb3JlYWNoICh1bG9uZyBjZWxsIGluIF9oeXBlckxpbmtzKQogICAgICAgICAgICAgICAgd2hpbGUoY3NlLk5leHQoKSkKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICBpZiAoZmlyc3QpCiAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICBzdy5Xcml0ZSgiPGh5cGVybGlua3M+Iik7CiAgICAgICAgICAgICAgICAgICAgICAgIGZpcnN0ID0gZmFsc2U7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIC8vaW50IHJvdywgY29sOwogICAgICAgICAgICAgICAgICAgIHZhciB1cmkgPSBfaHlwZXJMaW5rcy5HZXRWYWx1ZShjc2UuUm93LCBjc2UuQ29sdW1uKTsKICAgICAgICAgICAgICAgICAgICAvL0V4Y2VsQ2VsbCBjZWxsID0gX2NlbGxzW2NlbGxJZF0gYXMgRXhjZWxDZWxsOwogICAgICAgICAgICAgICAgICAgIGlmICh1cmkgaXMgRXhjZWxIeXBlckxpbmsgJiYgIXN0cmluZy5Jc051bGxPckVtcHR5KCh1cmkgYXMgRXhjZWxIeXBlckxpbmspLlJlZmVyZW5jZUFkZHJlc3MpKQogICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgRXhjZWxIeXBlckxpbmsgaGwgPSB1cmkgYXMgRXhjZWxIeXBlckxpbms7CiAgICAgICAgICAgICAgICAgICAgICAgIHN3LldyaXRlKCI8aHlwZXJsaW5rIHJlZj1cInswfVwiIGxvY2F0aW9uPVwiezF9XCIgezJ9ezN9Lz4iLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIENlbGxzW2NzZS5Sb3csIGNzZS5Db2x1bW4sIGNzZS5Sb3cgKyBobC5Sb3dTcGFubiwgY3NlLkNvbHVtbiArIGhsLkNvbFNwYW5uXS5BZGRyZXNzLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBFeGNlbENlbGxCYXNlLkdldEZ1bGxBZGRyZXNzKFNlY3VyaXR5RWxlbWVudC5Fc2NhcGUoTmFtZSksIFNlY3VyaXR5RWxlbWVudC5Fc2NhcGUoaGwuUmVmZXJlbmNlQWRkcmVzcykpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzdHJpbmcuSXNOdWxsT3JFbXB0eShobC5EaXNwbGF5KSA/ICIiIDogImRpc3BsYXk9XCIiICsgU2VjdXJpdHlFbGVtZW50LkVzY2FwZShobC5EaXNwbGF5KSArICJcIiAiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzdHJpbmcuSXNOdWxsT3JFbXB0eShobC5Ub29sVGlwKSA/ICIiIDogInRvb2x0aXA9XCIiICsgU2VjdXJpdHlFbGVtZW50LkVzY2FwZShobC5Ub29sVGlwKSArICJcIiAiKTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgZWxzZSBpZiggdXJpIT1udWxsKQogICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgc3RyaW5nIGlkOwogICAgICAgICAgICAgICAgICAgICAgICBVcmkgaHlwOwogICAgICAgICAgICAgICAgICAgICAgICBpZiAodXJpIGlzIEV4Y2VsSHlwZXJMaW5rKQogICAgICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBoeXAgPSAoKEV4Y2VsSHlwZXJMaW5rKXVyaSkuT3JpZ2luYWxVcmk7CiAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgZWxzZQogICAgICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBoeXAgPSB1cmk7CiAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGh5cHMuQ29udGFpbnNLZXkoaHlwLk9yaWdpbmFsU3RyaW5nKSkKICAgICAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgaWQgPSBoeXBzW2h5cC5PcmlnaW5hbFN0cmluZ107CiAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgZWxzZQogICAgICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICB2YXIgcmVsYXRpb25zaGlwID0gUGFydC5DcmVhdGVSZWxhdGlvbnNoaXAoaHlwLCBQYWNrYWdpbmcuVGFyZ2V0TW9kZS5FeHRlcm5hbCwgRXhjZWxQYWNrYWdlLnNjaGVtYUh5cGVybGluayk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAodXJpIGlzIEV4Y2VsSHlwZXJMaW5rKQogICAgICAgICAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEV4Y2VsSHlwZXJMaW5rIGhsID0gdXJpIGFzIEV4Y2VsSHlwZXJMaW5rOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN3LldyaXRlKCI8aHlwZXJsaW5rIHJlZj1cInswfVwiIHsyfXszfXI6aWQ9XCJ7MX1cIiAvPiIsIEV4Y2VsQ2VsbEJhc2UuR2V0QWRkcmVzcyhjc2UuUm93LCBjc2UuQ29sdW1uKSwgcmVsYXRpb25zaGlwLklkLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN0cmluZy5Jc051bGxPckVtcHR5KGhsLkRpc3BsYXkpID8gIiIgOiAiZGlzcGxheT1cIiIgKyBTZWN1cml0eUVsZW1lbnQuRXNjYXBlKGhsLkRpc3BsYXkpICsgIlwiICIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN0cmluZy5Jc051bGxPckVtcHR5KGhsLlRvb2xUaXApID8gIiIgOiAidG9vbHRpcD1cIiIgKyBTZWN1cml0eUVsZW1lbnQuRXNjYXBlKGhsLlRvb2xUaXApICsgIlwiICIpOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICAgICAgICAgZWxzZQogICAgICAgICAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN3LldyaXRlKCI8aHlwZXJsaW5rIHJlZj1cInswfVwiIHI6aWQ9XCJ7MX1cIiAvPiIsIEV4Y2VsQ2VsbEJhc2UuR2V0QWRkcmVzcyhjc2UuUm93LCBjc2UuQ29sdW1uKSwgcmVsYXRpb25zaGlwLklkKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlkID0gcmVsYXRpb25zaGlwLklkOwogICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgICAgIC8vY2VsbC5IeXBlckxpbmtSSWQgPSBpZDsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBpZiAoIWZpcnN0KQogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIHN3LldyaXRlKCI8L2h5cGVybGlua3M+Iik7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIC8vLyA8c3VtbWFyeT4KICAgICAgICAvLy8gQ3JlYXRlIHRoZSBoeXBlcmxpbmtzIG5vZGUgaW4gdGhlIFhNTAogICAgICAgIC8vLyA8L3N1bW1hcnk+CiAgICAgICAgLy8vIDxyZXR1cm5zPjwvcmV0dXJucz4KICAgICAgICBwcml2YXRlIFhtbE5vZGUgQ3JlYXRlSHlwZXJMaW5rQ29sbGVjdGlvbigpCiAgICAgICAgewogICAgICAgICAgICBYbWxFbGVtZW50IGhsPV93b3Jrc2hlZXRYbWwuQ3JlYXRlRWxlbWVudCgiaHlwZXJsaW5rcyIsRXhjZWxQYWNrYWdlLnNjaGVtYU1haW4pOwogICAgICAgICAgICBYbWxOb2RlIHByZXZOb2RlID0gX3dvcmtzaGVldFhtbC5TZWxlY3RTaW5nbGVOb2RlKCIvL2Q6Y29uZGl0aW9uYWxGb3JtYXR0aW5nIiwgTmFtZVNwYWNlTWFuYWdlcik7CiAgICAgICAgICAgIGlmIChwcmV2Tm9kZSA9PSBudWxsKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBwcmV2Tm9kZSA9IF93b3Jrc2hlZXRYbWwuU2VsZWN0U2luZ2xlTm9kZSgiLy9kOm1lcmdlQ2VsbHMiLCBOYW1lU3BhY2VNYW5hZ2VyKTsKICAgICAgICAgICAgICAgIGlmIChwcmV2Tm9kZSA9PSBudWxsKQogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIHByZXZOb2RlID0gX3dvcmtzaGVldFhtbC5TZWxlY3RTaW5nbGVOb2RlKCIvL2Q6c2hlZXREYXRhIiwgTmFtZVNwYWNlTWFuYWdlcik7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICAgICAgcmV0dXJuIF93b3Jrc2hlZXRYbWwuRG9jdW1lbnRFbGVtZW50Lkluc2VydEFmdGVyKGhsLCBwcmV2Tm9kZSk7CiAgICAgICAgfQogICAgICAgIC8vLyA8c3VtbWFyeT4KICAgICAgICAvLy8gRGltZW5zaW9uIGFkZHJlc3MgZm9yIHRoZSB3b3Jrc2hlZXQuIAogICAgICAgIC8vLyBUb3AgbGVmdCBjZWxsIHRvIEJvdHRvbSByaWdodC4KICAgICAgICAvLy8gSWYgdGhlIHdvcmtzaGVldCBoYXMgbm8gY2VsbHMsIG51bGwgaXMgcmV0dXJuZWQKICAgICAgICAvLy8gPC9zdW1tYXJ5PgogICAgICAgIHB1YmxpYyBFeGNlbEFkZHJlc3NCYXNlIERpbWVuc2lvbgogICAgICAgIHsKICAgICAgICAgICAgZ2V0CiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIENoZWNrU2hlZXRUeXBlKCk7CiAgICAgICAgICAgICAgICBpbnQgZnJvbVJvdywgZnJvbUNvbCwgdG9Sb3csIHRvQ29sOwogICAgICAgICAgICAgICAgaWYgKF92YWx1ZXMuR2V0RGltZW5zaW9uKG91dCBmcm9tUm93LCBvdXQgZnJvbUNvbCwgb3V0IHRvUm93LCBvdXQgdG9Db2wpKQogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIHZhciBhZGRyID0gbmV3IEV4Y2VsQWRkcmVzc0Jhc2UoZnJvbVJvdywgZnJvbUNvbCwgdG9Sb3csIHRvQ29sKTsKICAgICAgICAgICAgICAgICAgICBhZGRyLl93cyA9IE5hbWU7CiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGFkZHI7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBlbHNlCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIG51bGw7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgRXhjZWxTaGVldFByb3RlY3Rpb24gX3Byb3RlY3Rpb249bnVsbDsKICAgICAgICAvLy8gPHN1bW1hcnk+CiAgICAgICAgLy8vIEFjY2VzcyB0byBzaGVldCBwcm90ZWN0aW9uIHByb3BlcnRpZXMKICAgICAgICAvLy8gPC9zdW1tYXJ5PgogICAgICAgIHB1YmxpYyBFeGNlbFNoZWV0UHJvdGVjdGlvbiBQcm90ZWN0aW9uCiAgICAgICAgewogICAgICAgICAgICBnZXQKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgaWYgKF9wcm90ZWN0aW9uID09IG51bGwpCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgX3Byb3RlY3Rpb24gPSBuZXcgRXhjZWxTaGVldFByb3RlY3Rpb24oTmFtZVNwYWNlTWFuYWdlciwgVG9wTm9kZSwgdGhpcyk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICByZXR1cm4gX3Byb3RlY3Rpb247CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIHByaXZhdGUgRXhjZWxQcm90ZWN0ZWRSYW5nZUNvbGxlY3Rpb24gX3Byb3RlY3RlZFJhbmdlczsKICAgICAgICBwdWJsaWMgRXhjZWxQcm90ZWN0ZWRSYW5nZUNvbGxlY3Rpb24gUHJvdGVjdGVkUmFuZ2VzCiAgICAgICAgewogICAgICAgICAgICBnZXQKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgaWYgKF9wcm90ZWN0ZWRSYW5nZXMgPT0gbnVsbCkKICAgICAgICAgICAgICAgICAgICBfcHJvdGVjdGVkUmFuZ2VzID0gbmV3IEV4Y2VsUHJvdGVjdGVkUmFuZ2VDb2xsZWN0aW9uKE5hbWVTcGFjZU1hbmFnZXIsIFRvcE5vZGUsIHRoaXMpOwogICAgICAgICAgICAgICAgcmV0dXJuIF9wcm90ZWN0ZWRSYW5nZXM7CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgICNyZWdpb24gRHJhd2luZwogICAgICAgIEV4Y2VsRHJhd2luZ3MgX2RyYXdpbmdzID0gbnVsbDsKICAgICAgICAvLy8gPHN1bW1hcnk+CiAgICAgICAgLy8vIENvbGxlY3Rpb24gb2YgZHJhd2luZy1vYmplY3RzIGxpa2Ugc2hhcGVzLCBpbWFnZXMgYW5kIGNoYXJ0cwogICAgICAgIC8vLyA8L3N1bW1hcnk+CiAgICAgICAgcHVibGljIEV4Y2VsRHJhd2luZ3MgRHJhd2luZ3MKICAgICAgICB7CiAgICAgICAgICAgIGdldAogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBpZiAoX2RyYXdpbmdzID09IG51bGwpCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgX2RyYXdpbmdzID0gbmV3IEV4Y2VsRHJhd2luZ3MoX3BhY2thZ2UsIHRoaXMpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgcmV0dXJuIF9kcmF3aW5nczsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgICAgICAjZW5kcmVnaW9uCiAgICAgICAgRXhjZWxUYWJsZUNvbGxlY3Rpb24gX3RhYmxlcyA9IG51bGw7CiAgICAgICAgLy8vIDxzdW1tYXJ5PgogICAgICAgIC8vLyBUYWJsZXMgZGVmaW5lZCBpbiB0aGUgd29ya3NoZWV0LgogICAgICAgIC8vLyA8L3N1bW1hcnk+CiAgICAgICAgcHVibGljIEV4Y2VsVGFibGVDb2xsZWN0aW9uIFRhYmxlcwogICAgICAgIHsKICAgICAgICAgICAgZ2V0CiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIENoZWNrU2hlZXRUeXBlKCk7CiAgICAgICAgICAgICAgICBpZiAoV29ya2Jvb2suX25leHRUYWJsZUlEID09IGludC5NaW5WYWx1ZSkgV29ya2Jvb2suUmVhZEFsbFRhYmxlcygpOwogICAgICAgICAgICAgICAgaWYgKF90YWJsZXMgPT0gbnVsbCkKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICBfdGFibGVzID0gbmV3IEV4Y2VsVGFibGVDb2xsZWN0aW9uKHRoaXMpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgcmV0dXJuIF90YWJsZXM7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgRXhjZWxQaXZvdFRhYmxlQ29sbGVjdGlvbiBfcGl2b3RUYWJsZXMgPSBudWxsOwogICAgICAgIC8vLyA8c3VtbWFyeT4KICAgICAgICAvLy8gUGl2b3R0YWJsZXMgZGVmaW5lZCBpbiB0aGUgd29ya3NoZWV0LgogICAgICAgIC8vLyA8L3N1bW1hcnk+CiAgICAgICAgcHVibGljIEV4Y2VsUGl2b3RUYWJsZUNvbGxlY3Rpb24gUGl2b3RUYWJsZXMKICAgICAgICB7CiAgICAgICAgICAgIGdldAogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBDaGVja1NoZWV0VHlwZSgpOwogICAgICAgICAgICAgICAgaWYgKF9waXZvdFRhYmxlcyA9PSBudWxsKQogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIGlmIChXb3JrYm9vay5fbmV4dFBpdm90VGFibGVJRCA9PSBpbnQuTWluVmFsdWUpIFdvcmtib29rLlJlYWRBbGxUYWJsZXMoKTsKICAgICAgICAgICAgICAgICAgICBfcGl2b3RUYWJsZXMgPSBuZXcgRXhjZWxQaXZvdFRhYmxlQ29sbGVjdGlvbih0aGlzKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIHJldHVybiBfcGl2b3RUYWJsZXM7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgcHJpdmF0ZSBFeGNlbENvbmRpdGlvbmFsRm9ybWF0dGluZ0NvbGxlY3Rpb24gX2NvbmRpdGlvbmFsRm9ybWF0dGluZyA9IG51bGw7CiAgICAgICAgLy8vIDxzdW1tYXJ5PgogICAgICAgIC8vLyBDb25kaXRpb25hbEZvcm1hdHRpbmcgZGVmaW5lZCBpbiB0aGUgd29ya3NoZWV0LiBVc2UgdGhlIEFkZCBtZXRob2RzIHRvIGNyZWF0ZSBDb25kaXRpb25hbEZvcm1hdHRpbmcgYW5kIGFkZCB0aGVtIHRvIHRoZSB3b3Jrc2hlZXQuIFRoZW4KICAgICAgICAvLy8gc2V0IHRoZSBwcm9wZXJ0aWVzIG9uIHRoZSBpbnN0YW5jZSByZXR1cm5lZC4KICAgICAgICAvLy8gPC9zdW1tYXJ5PgogICAgICAgIC8vLyA8c2VlYWxzbyBjcmVmPSJFeGNlbENvbmRpdGlvbmFsRm9ybWF0dGluZ0NvbGxlY3Rpb24iLz4KICAgICAgICBwdWJsaWMgRXhjZWxDb25kaXRpb25hbEZvcm1hdHRpbmdDb2xsZWN0aW9uIENvbmRpdGlvbmFsRm9ybWF0dGluZwogICAgICAgIHsKICAgICAgICAgICAgZ2V0CiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIENoZWNrU2hlZXRUeXBlKCk7CiAgICAgICAgICAgICAgICBpZiAoX2NvbmRpdGlvbmFsRm9ybWF0dGluZyA9PSBudWxsKQogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIF9jb25kaXRpb25hbEZvcm1hdHRpbmcgPSBuZXcgRXhjZWxDb25kaXRpb25hbEZvcm1hdHRpbmdDb2xsZWN0aW9uKHRoaXMpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgcmV0dXJuIF9jb25kaXRpb25hbEZvcm1hdHRpbmc7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgcHJpdmF0ZSBFeGNlbERhdGFWYWxpZGF0aW9uQ29sbGVjdGlvbiBfZGF0YVZhbGlkYXRpb24gPSBudWxsOwogICAgICAgIC8vLyA8c3VtbWFyeT4KICAgICAgICAvLy8gRGF0YVZhbGlkYXRpb24gZGVmaW5lZCBpbiB0aGUgd29ya3NoZWV0LiBVc2UgdGhlIEFkZCBtZXRob2RzIHRvIGNyZWF0ZSBEYXRhVmFsaWRhdGlvbnMgYW5kIGFkZCB0aGVtIHRvIHRoZSB3b3Jrc2hlZXQuIFRoZW4KICAgICAgICAvLy8gc2V0IHRoZSBwcm9wZXJ0aWVzIG9uIHRoZSBpbnN0YW5jZSByZXR1cm5lZC4KICAgICAgICAvLy8gPC9zdW1tYXJ5PgogICAgICAgIC8vLyA8c2VlYWxzbyBjcmVmPSJFeGNlbERhdGFWYWxpZGF0aW9uQ29sbGVjdGlvbiIvPgogICAgICAgIHB1YmxpYyBFeGNlbERhdGFWYWxpZGF0aW9uQ29sbGVjdGlvbiBEYXRhVmFsaWRhdGlvbnMKICAgICAgICB7CiAgICAgICAgICAgIGdldAogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBDaGVja1NoZWV0VHlwZSgpOwogICAgICAgICAgICAgICAgaWYgKF9kYXRhVmFsaWRhdGlvbiA9PSBudWxsKQogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIF9kYXRhVmFsaWRhdGlvbiA9IG5ldyBFeGNlbERhdGFWYWxpZGF0aW9uQ29sbGVjdGlvbih0aGlzKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIHJldHVybiBfZGF0YVZhbGlkYXRpb247CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgRXhjZWxCYWNrZ3JvdW5kSW1hZ2UgX2JhY2tncm91bmRJbWFnZSA9IG51bGw7CiAgICAgICAgLy8vIDxzdW1tYXJ5PgogICAgICAgIC8vLyBBbiBpbWFnZSBkaXNwbGF5ZWQgYXMgdGhlIGJhY2tncm91bmQgb2YgdGhlIHdvcmtzaGVldC4KICAgICAgICAvLy8gPC9zdW1tYXJ5PgogICAgICAgIHB1YmxpYyBFeGNlbEJhY2tncm91bmRJbWFnZSBCYWNrZ3JvdW5kSW1hZ2UKICAgICAgICB7CiAgICAgICAgICAgIGdldAogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBpZiAoX2JhY2tncm91bmRJbWFnZSA9PSBudWxsKQogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIF9iYWNrZ3JvdW5kSW1hZ2UgPSBuZXcgRXhjZWxCYWNrZ3JvdW5kSW1hZ2UoTmFtZVNwYWNlTWFuYWdlciwgVG9wTm9kZSwgdGhpcyk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICByZXR1cm4gX2JhY2tncm91bmRJbWFnZTsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgICAgICAvLy8gPHN1bW1hcnk+CgkJLy8vIFJldHVybnMgdGhlIHN0eWxlIElEIGdpdmVuIGEgc3R5bGUgbmFtZS4gIAoJCS8vLyBUaGUgc3R5bGUgSUQgd2lsbCBiZSBjcmVhdGVkIGlmIG5vdCBmb3VuZCwgYnV0IG9ubHkgaWYgdGhlIHN0eWxlIG5hbWUgZXhpc3RzIQoJCS8vLyA8L3N1bW1hcnk+CgkJLy8vIDxwYXJhbSBuYW1lPSJTdHlsZU5hbWUiPjwvcGFyYW0+CgkJLy8vIDxyZXR1cm5zPjwvcmV0dXJucz4KCQlpbnRlcm5hbCBpbnQgR2V0U3R5bGVJRChzdHJpbmcgU3R5bGVOYW1lKQoJCXsKCQkJRXhjZWxOYW1lZFN0eWxlWG1sIG5hbWVkU3R5bGU9bnVsbDsKICAgICAgICAgICAgV29ya2Jvb2suU3R5bGVzLk5hbWVkU3R5bGVzLkZpbmRCeUlEKFN0eWxlTmFtZSwgcmVmIG5hbWVkU3R5bGUpOwogICAgICAgICAgICBpZiAobmFtZWRTdHlsZS5YZklkID09IGludC5NaW5WYWx1ZSkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgbmFtZWRTdHlsZS5YZklkPVdvcmtib29rLlN0eWxlcy5DZWxsWGZzLkZpbmRJbmRleEJ5SUQobmFtZWRTdHlsZS5TdHlsZS5JZCk7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgcmV0dXJuIG5hbWVkU3R5bGUuWGZJZDsKCQl9CiAgICAgICAgLy8vIDxzdW1tYXJ5PgogICAgICAgIC8vLyBUaGUgd29ya2Jvb2sgb2JqZWN0CiAgICAgICAgLy8vIDwvc3VtbWFyeT4KICAgICAgICBwdWJsaWMgRXhjZWxXb3JrYm9vayBXb3JrYm9vawogICAgICAgIHsKICAgICAgICAgICAgZ2V0CiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIHJldHVybiBfcGFja2FnZS5Xb3JrYm9vazsKICAgICAgICAgICAgfQogICAgICAgIH0KCQkjZW5kcmVnaW9uCiAgICAgICAgI2VuZHJlZ2lvbiAgLy8gRU5EIFdvcmtzaGVldCBQcml2YXRlIE1ldGhvZHMKCiAgICAgICAgLy8vIDxzdW1tYXJ5PgogICAgICAgIC8vLyBHZXQgdGhlIG5leHQgSUQgZnJvbSBhIHNoYXJlZCBmb3JtdWxhIG9yIGFuIEFycmF5IGZvcm11bGEKICAgICAgICAvLy8gU2hhcmVkZm9ydW1sYXMgd2lsbCBoYXZlIGFuIGlkIGZyb20gMC14LiBBcnJheSBmb3JtdWxhIGlkcyBzdGFydCBmcm9tIDB4NDAwMDAwMS0uIAogICAgICAgIC8vLyA8L3N1bW1hcnk+CiAgICAgICAgLy8vIDxwYXJhbSBuYW1lPSJpc0FycmF5Ij5JZiB0aGUgZm9ybXVsYSBpcyBhbiBhcnJheSBmb3JtdWxhPC9wYXJhbT4KICAgICAgICAvLy8gPHJldHVybnM+PC9yZXR1cm5zPgogICAgICAgIGludGVybmFsIGludCBHZXRNYXhTaGFyZUZ1bmN0aW9uSW5kZXgoYm9vbCBpc0FycmF5KQogICAgICAgIHsKICAgICAgICAgICAgaW50IGk9X3NoYXJlZEZvcm11bGFzLkNvdW50ICsgMTsKICAgICAgICAgICAgaWYgKGlzQXJyYXkpCiAgICAgICAgICAgICAgICBpIHw9IDB4NDAwMDAwMDA7CgogICAgICAgICAgICB3aGlsZShfc2hhcmVkRm9ybXVsYXMuQ29udGFpbnNLZXkoaSkpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIGkrKzsKICAgICAgICAgICAgfQogICAgICAgICAgICByZXR1cm4gaTsKICAgICAgICB9CiAgICAgICAgaW50ZXJuYWwgdm9pZCBTZXRIRkxlZ2FjeURyYXdpbmdSZWwoc3RyaW5nIHJlbElEKQogICAgICAgIHsKICAgICAgICAgICAgU2V0WG1sTm9kZVN0cmluZygiZDpsZWdhY3lEcmF3aW5nSEYvQHI6aWQiLCByZWxJRCk7CiAgICAgICAgfQogICAgICAgIGludGVybmFsIHZvaWQgUmVtb3ZlTGVnYWN5RHJhd2luZ1JlbChzdHJpbmcgcmVsSUQpCiAgICAgICAgewogICAgICAgICAgICB2YXIgbiA9IFdvcmtzaGVldFhtbC5Eb2N1bWVudEVsZW1lbnQuU2VsZWN0U2luZ2xlTm9kZShzdHJpbmcuRm9ybWF0KCJkOmxlZ2FjeURyYXdpbmdbQHI6aWQ9XCJ7MH1cIl0iLCByZWxJRCksIE5hbWVTcGFjZU1hbmFnZXIpOwogICAgICAgICAgICBpZiAobiAhPSBudWxsKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBuLlBhcmVudE5vZGUuUmVtb3ZlQ2hpbGQobik7CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIGludGVybmFsIHZvaWQgVXBkYXRlQ2VsbHNXaXRoRGF0ZTE5MDRTZXR0aW5nKCkKICAgICAgICB7CiAgICAgICAgICAgIHZhciBjc2UgPSBuZXcgQ2VsbHNTdG9yZUVudW1lcmF0b3I8b2JqZWN0PihfdmFsdWVzKTsKICAgICAgICAgICAgdmFyIG9mZnNldCA9IFdvcmtib29rLkRhdGUxOTA0ID8gLUV4Y2VsV29ya2Jvb2suZGF0ZTE5MDRPZmZzZXQgOiBFeGNlbFdvcmtib29rLmRhdGUxOTA0T2Zmc2V0OwogICAgICAgICAgICB3aGlsZShjc2UuTW92ZU5leHQoKSkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgaWYgKGNzZS5WYWx1ZSBpcyBEYXRlVGltZSkKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICB0cnkKICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgIGRvdWJsZSBzZHYgPSAoKERhdGVUaW1lKWNzZS5WYWx1ZSkuVG9PQURhdGUoKTsKICAgICAgICAgICAgICAgICAgICAgICAgc2R2ICs9IG9mZnNldDsKCiAgICAgICAgICAgICAgICAgICAgICAgIGNzZS5WYWx1ZSA9IERhdGVUaW1lLkZyb21PQURhdGUoc2R2KTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgY2F0Y2gKICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIGludGVybmFsIHN0cmluZyBHZXRGb3JtdWxhKGludCByb3csIGludCBjb2wpCiAgICAgICAgewogICAgICAgICAgICB2YXIgdiA9IF9mb3JtdWxhcy5HZXRWYWx1ZShyb3csIGNvbCk7CiAgICAgICAgICAgIGlmICh2IGlzIGludCkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgcmV0dXJuIF9zaGFyZWRGb3JtdWxhc1soaW50KXZdLkdldEZvcm11bGEocm93LGNvbCwgTmFtZSk7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgZWxzZSBpZiAodiAhPSBudWxsKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICByZXR1cm4gdi5Ub1N0cmluZygpOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGVsc2UKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgcmV0dXJuICIiOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIGludGVybmFsIHN0cmluZyBHZXRGb3JtdWxhUjFDMShpbnQgcm93LCBpbnQgY29sKQogICAgICAgIHsKICAgICAgICAgICAgdmFyIHYgPSBfZm9ybXVsYXMuR2V0VmFsdWUocm93LCBjb2wpOwogICAgICAgICAgICBpZiAodiBpcyBpbnQpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIHZhciBzZiA9IF9zaGFyZWRGb3JtdWxhc1soaW50KXZdOwogICAgICAgICAgICAgICAgcmV0dXJuIEV4Y2VsQ2VsbEJhc2UuVHJhbnNsYXRlVG9SMUMxKEZvcm11bGFzLlJlbW92ZUR1bW15RnVuY3Rpb24oc2YuRm9ybXVsYSksIHNmLlN0YXJ0Um93LCBzZi5TdGFydENvbCk7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgZWxzZSBpZiAodiAhPSBudWxsKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICByZXR1cm4gRXhjZWxDZWxsQmFzZS5UcmFuc2xhdGVUb1IxQzEodi5Ub1N0cmluZygpLCByb3csIGNvbCk7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgZWxzZQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICByZXR1cm4gIiI7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgaW50ZXJuYWwgc3RyaW5nIEdldEFycmF5Rm9ybXVsYUFkZHJlc3MoaW50IHJvdywgaW50IGNvbCkKICAgICAgICB7CiAgICAgICAgICAgIHZhciB2ID0gX2Zvcm11bGFzLkdldFZhbHVlKHJvdywgY29sKTsKICAgICAgICAgICAgaWYgKCh2IGlzIGludCkgJiYgKF9zaGFyZWRGb3JtdWxhc1soaW50KXZdLklzQXJyYXkpKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICByZXR1cm4gX3NoYXJlZEZvcm11bGFzWyhpbnQpdl0uQWRkcmVzczsKICAgICAgICAgICAgfQogICAgICAgICAgICBlbHNlCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIHJldHVybiAiIjsKICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgcHJpdmF0ZSB2b2lkIERpc3Bvc2VJbnRlcm5hbChJRGlzcG9zYWJsZSBjYW5kaWRhdGVEaXNwb3NhYmxlKQogICAgICAgIHsKICAgICAgICAgICAgaWYgKGNhbmRpZGF0ZURpc3Bvc2FibGUgIT0gbnVsbCkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgY2FuZGlkYXRlRGlzcG9zYWJsZS5EaXNwb3NlKCk7CiAgICAgICAgICAgIH0KICAgICAgICB9CgoKICAgICAgICBwdWJsaWMgdm9pZCBEaXNwb3NlKCkKICAgICAgICB7CiAgICAgICAgICAgIERpc3Bvc2VJbnRlcm5hbChfdmFsdWVzKTsKICAgICAgICAgICAgRGlzcG9zZUludGVybmFsKF9mb3JtdWxhcyk7CiAgICAgICAgICAgIERpc3Bvc2VJbnRlcm5hbChfZmxhZ3MpOwogICAgICAgICAgICBEaXNwb3NlSW50ZXJuYWwoX2h5cGVyTGlua3MpOwogICAgICAgICAgICBEaXNwb3NlSW50ZXJuYWwoX3N0eWxlcyk7CiAgICAgICAgICAgIERpc3Bvc2VJbnRlcm5hbChfdHlwZXMpOwogICAgICAgICAgICBEaXNwb3NlSW50ZXJuYWwoX2NvbW1lbnRzU3RvcmUpOwogICAgICAgICAgICBEaXNwb3NlSW50ZXJuYWwoX2Zvcm11bGFUb2tlbnMpOwoKICAgICAgICAgICAgX3ZhbHVlcyA9IG51bGw7CiAgICAgICAgICAgIF9mb3JtdWxhcyA9IG51bGw7CiAgICAgICAgICAgIF9mbGFncyA9IG51bGw7CiAgICAgICAgICAgIF9oeXBlckxpbmtzID0gbnVsbDsKICAgICAgICAgICAgX3N0eWxlcyA9IG51bGw7CiAgICAgICAgICAgIF90eXBlcyA9IG51bGw7CiAgICAgICAgICAgIF9jb21tZW50c1N0b3JlID0gbnVsbDsKICAgICAgICAgICAgX2Zvcm11bGFUb2tlbnMgPSBudWxsOwoKICAgICAgICAgICAgX3BhY2thZ2UgPSBudWxsOwogICAgICAgICAgICBfcGl2b3RUYWJsZXMgPSBudWxsOwogICAgICAgICAgICBfcHJvdGVjdGlvbiA9IG51bGw7CiAgICAgICAgICAgIGlmKF9zaGFyZWRGb3JtdWxhcyAhPSBudWxsKSBfc2hhcmVkRm9ybXVsYXMuQ2xlYXIoKTsKICAgICAgICAgICAgX3NoYXJlZEZvcm11bGFzID0gbnVsbDsKICAgICAgICAgICAgX3NoZWV0VmlldyA9IG51bGw7CiAgICAgICAgICAgIF90YWJsZXMgPSBudWxsOwogICAgICAgICAgICBfdm1sRHJhd2luZ3MgPSBudWxsOwogICAgICAgICAgICBfY29uZGl0aW9uYWxGb3JtYXR0aW5nID0gbnVsbDsKICAgICAgICAgICAgX2RhdGFWYWxpZGF0aW9uID0gbnVsbDsKICAgICAgICAgICAgX2RyYXdpbmdzID0gbnVsbDsKICAgICAgICB9CgogICAgICAgIC8vLyA8c3VtbWFyeT4KICAgICAgICAvLy8gR2V0IHRoZSBFeGNlbENvbHVtbiBmb3IgY29sdW1uIChzcGFuIENvbHVtbk1pbiBhbmQgQ29sdW1uTWF4KQogICAgICAgIC8vLyA8L3N1bW1hcnk+CiAgICAgICAgLy8vIDxwYXJhbSBuYW1lPSJjb2x1bW4iPjwvcGFyYW0+CiAgICAgICAgLy8vIDxyZXR1cm5zPjwvcmV0dXJucz4KICAgICAgICBpbnRlcm5hbCBFeGNlbENvbHVtbiBHZXRDb2x1bW4oaW50IGNvbHVtbikKICAgICAgICB7CiAgICAgICAgICAgIHZhciBjID0gX3ZhbHVlcy5HZXRWYWx1ZSgwLCBjb2x1bW4pIGFzIEV4Y2VsQ29sdW1uOwogICAgICAgICAgICBpZiAoYyA9PSBudWxsKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBpbnQgcm93ID0gMCwgY29sID0gY29sdW1uOwogICAgICAgICAgICAgICAgaWYgKF92YWx1ZXMuUHJldkNlbGwocmVmIHJvdywgcmVmIGNvbCkpCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgYyA9IF92YWx1ZXMuR2V0VmFsdWUoMCwgY29sKSBhcyBFeGNlbENvbHVtbjsKICAgICAgICAgICAgICAgICAgICBpZiAoYyAhPSBudWxsICYmIGMuQ29sdW1uTWF4ID49IGNvbHVtbikKICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBjOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICByZXR1cm4gbnVsbDsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgICAgICByZXR1cm4gYzsKCiAgICAgICAgfQoKICAgICAgICBwdWJsaWMgYm9vbCBFcXVhbHMoRXhjZWxXb3Jrc2hlZXQgeCwgRXhjZWxXb3Jrc2hlZXQgeSkKICAgICAgICB7CiAgICAgICAgICAgIHJldHVybiB4Lk5hbWUgPT0geS5OYW1lICYmIHguU2hlZXRJRCA9PSB5LlNoZWV0SUQgJiYgeC5Xb3Jrc2hlZXRYbWwuT3V0ZXJYbWwgPT0geS5Xb3Jrc2hlZXRYbWwuT3V0ZXJYbWw7CiAgICAgICAgfQoKICAgICAgICBwdWJsaWMgaW50IEdldEhhc2hDb2RlKEV4Y2VsV29ya3NoZWV0IG9iaikKICAgICAgICB7CiAgICAgICAgICAgIHJldHVybiBvYmouV29ya3NoZWV0WG1sLk91dGVyWG1sLkdldEhhc2hDb2RlKCk7CiAgICAgICAgfQoJfSAgLy8gRU5EIGNsYXNzIFdvcmtzaGVldAp9Cg==