LyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogWW91IG1heSBhbWVuZCBhbmQgZGlzdHJpYnV0ZSBhcyB5b3UgbGlrZSwgYnV0IGRvbid0IHJlbW92ZSB0aGlzIGhlYWRlciEKICoKICogRVBQbHVzIHByb3ZpZGVzIHNlcnZlci1zaWRlIGdlbmVyYXRpb24gb2YgRXhjZWwgMjAwNy8yMDEwIHNwcmVhZHNoZWV0cy4KICogU2VlIGh0dHA6Ly93d3cuY29kZXBsZXguY29tL0VQUGx1cyBmb3IgZGV0YWlscy4KICoKICogQ29weXJpZ2h0IChDKSAyMDExICBKYW4gS+RsbG1hbgogKgogKiBUaGlzIGxpYnJhcnkgaXMgZnJlZSBzb2Z0d2FyZTsgeW91IGNhbiByZWRpc3RyaWJ1dGUgaXQgYW5kL29yCiAqIG1vZGlmeSBpdCB1bmRlciB0aGUgdGVybXMgb2YgdGhlIEdOVSBMZXNzZXIgR2VuZXJhbCBQdWJsaWMKICogTGljZW5zZSBhcyBwdWJsaXNoZWQgYnkgdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbjsgZWl0aGVyCiAqIHZlcnNpb24gMi4xIG9mIHRoZSBMaWNlbnNlLCBvciAoYXQgeW91ciBvcHRpb24pIGFueSBsYXRlciB2ZXJzaW9uLgoKICogVGhpcyBsaWJyYXJ5IGlzIGRpc3RyaWJ1dGVkIGluIHRoZSBob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsCiAqIGJ1dCBXSVRIT1VUIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuIHRoZSBpbXBsaWVkIHdhcnJhbnR5IG9mCiAqIE1FUkNIQU5UQUJJTElUWSBvciBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRS4gIAogKiBTZWUgdGhlIEdOVSBMZXNzZXIgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSBmb3IgbW9yZSBkZXRhaWxzLgogKgogKiBUaGUgR05VIExlc3NlciBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIGNhbiBiZSB2aWV3ZWQgYXQgaHR0cDovL3d3dy5vcGVuc291cmNlLm9yZy9saWNlbnNlcy9sZ3BsLWxpY2Vuc2UucGhwCiAqIElmIHlvdSB1bmZhbWlsaWFyIHdpdGggdGhpcyBsaWNlbnNlIG9yIGhhdmUgcXVlc3Rpb25zIGFib3V0IGl0LCBoZXJlIGlzIGFuIGh0dHA6Ly93d3cuZ251Lm9yZy9saWNlbnNlcy9ncGwtZmFxLmh0bWwKICoKICogQWxsIGNvZGUgYW5kIGV4ZWN1dGFibGVzIGFyZSBwcm92aWRlZCAiYXMgaXMiIHdpdGggbm8gd2FycmFudHkgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4gCiAqIFRoZSBhdXRob3IgYWNjZXB0cyBubyBsaWFiaWxpdHkgZm9yIGFueSBkYW1hZ2Ugb3IgbG9zcyBvZiBidXNpbmVzcyB0aGF0IHRoaXMgcHJvZHVjdCBtYXkgY2F1c2UuCiAqCiAqIENvZGUgY2hhbmdlIG5vdGVzOgogKiAKICogQXV0aG9yCQkJCQkJCUNoYW5nZQkJCQkJCURhdGUKICogKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIEphbiBL5GxsbWFuCQkgICAgSW5pdGlhbCBSZWxlYXNlCQkgICAgICAgMjAwOS0xMC0wMQogKiBKYW4gS+RsbG1hbgkJICAgIExpY2Vuc2UgY2hhbmdlZCBHUEwtLT5MR1BMIDIwMTEtMTItMjcKICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCnVzaW5nIFN5c3RlbTsKdXNpbmcgU3lzdGVtLkNvbGxlY3Rpb25zOwp1c2luZyBTeXN0ZW0uQ29sbGVjdGlvbnMuR2VuZXJpYzsKdXNpbmcgU3lzdGVtLlNlY3VyaXR5LkNyeXB0b2dyYXBoeS5YbWw7CnVzaW5nIFN5c3RlbS5UZXh0Owp1c2luZyBTeXN0ZW0uWG1sOwp1c2luZyBTeXN0ZW0uSU87CnVzaW5nIFN5c3RlbS5MaW5xOwp1c2luZyBPZmZpY2VPcGVuWG1sLkZvcm11bGFQYXJzaW5nLkV4Y2VsLkZ1bmN0aW9ucy5Mb2dpY2FsOwp1c2luZyBPZmZpY2VPcGVuWG1sLlN0eWxlOwp1c2luZyBPZmZpY2VPcGVuWG1sLkRyYXdpbmc7CnVzaW5nIE9mZmljZU9wZW5YbWwuRHJhd2luZy5DaGFydDsKdXNpbmcgT2ZmaWNlT3BlblhtbC5TdHlsZS5YbWxBY2Nlc3M7CnVzaW5nIE9mZmljZU9wZW5YbWwuRHJhd2luZy5WbWw7CnVzaW5nIE9mZmljZU9wZW5YbWwuUGFja2FnaW5nLklvbmljLlpsaWI7CnVzaW5nIE9mZmljZU9wZW5YbWwuVXRpbHM7CnVzaW5nIE9mZmljZU9wZW5YbWwuVkJBOwpuYW1lc3BhY2UgT2ZmaWNlT3BlblhtbAp7CgkvLy8gPHN1bW1hcnk+CgkvLy8gVGhlIGNvbGxlY3Rpb24gb2Ygd29ya3NoZWV0cyBmb3IgdGhlIHdvcmtib29rCgkvLy8gPC9zdW1tYXJ5PgoJcHVibGljIGNsYXNzIEV4Y2VsV29ya3NoZWV0cyA6IFhtbEhlbHBlciwgSUVudW1lcmFibGU8RXhjZWxXb3Jrc2hlZXQ+LCBJRGlzcG9zYWJsZQoJewoJCSNyZWdpb24gUHJpdmF0ZSBQcm9wZXJ0aWVzCiAgICAgICAgcHJpdmF0ZSBFeGNlbFBhY2thZ2UgX3BjazsKICAgICAgICBwcml2YXRlIERpY3Rpb25hcnk8aW50LCBFeGNlbFdvcmtzaGVldD4gX3dvcmtzaGVldHM7CgkJcHJpdmF0ZSBYbWxOYW1lc3BhY2VNYW5hZ2VyIF9uYW1lc3BhY2VNYW5hZ2VyOwoJCSNlbmRyZWdpb24KCQkjcmVnaW9uIEV4Y2VsV29ya3NoZWV0cyBDb25zdHJ1Y3RvcgoJCWludGVybmFsIEV4Y2VsV29ya3NoZWV0cyhFeGNlbFBhY2thZ2UgcGNrLCBYbWxOYW1lc3BhY2VNYW5hZ2VyIG5zbSwgWG1sTm9kZSB0b3BOb2RlKSA6CiAgICAgICAgICAgIGJhc2UobnNtLCB0b3BOb2RlKQoJCXsKCQkJX3BjayA9IHBjazsKICAgICAgICAgICAgX25hbWVzcGFjZU1hbmFnZXIgPSBuc207CgkJCV93b3Jrc2hlZXRzID0gbmV3IERpY3Rpb25hcnk8aW50LCBFeGNlbFdvcmtzaGVldD4oKTsKCQkJaW50IHBvc2l0aW9uSUQgPSAxOwoKICAgICAgICAgICAgZm9yZWFjaCAoWG1sTm9kZSBzaGVldE5vZGUgaW4gdG9wTm9kZS5DaGlsZE5vZGVzKQoJCQl7CiAgICAgICAgICAgICAgICBpZiAoc2hlZXROb2RlLk5vZGVUeXBlID09IFhtbE5vZGVUeXBlLkVsZW1lbnQpCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgc3RyaW5nIG5hbWUgPSBzaGVldE5vZGUuQXR0cmlidXRlc1sibmFtZSJdLlZhbHVlOwogICAgICAgICAgICAgICAgICAgIC8vR2V0IHRoZSByZWxhdGlvbnNoaXAgaWQKICAgICAgICAgICAgICAgICAgICAgICAgc3RyaW5nIHJlbElkID0gc2hlZXROb2RlLkF0dHJpYnV0ZXNbInI6aWQiXS5WYWx1ZTsKICAgICAgICAgICAgICAgICAgICBpbnQgc2hlZXRJRCA9IENvbnZlcnQuVG9JbnQzMihzaGVldE5vZGUuQXR0cmlidXRlc1sic2hlZXRJZCJdLlZhbHVlKTsKCiAgICAgICAgICAgICAgICAgICAgLy9IaWRkZW4gcHJvcGVydHkKICAgICAgICAgICAgICAgICAgICBlV29ya1NoZWV0SGlkZGVuIGhpZGRlbiA9IGVXb3JrU2hlZXRIaWRkZW4uVmlzaWJsZTsKICAgICAgICAgICAgICAgICAgICBYbWxOb2RlIGF0dHIgPSBzaGVldE5vZGUuQXR0cmlidXRlc1sic3RhdGUiXTsKICAgICAgICAgICAgICAgICAgICBpZiAoYXR0ciAhPSBudWxsKQogICAgICAgICAgICAgICAgICAgICAgICBoaWRkZW4gPSBUcmFuc2xhdGVIaWRkZW4oYXR0ci5WYWx1ZSk7CgogICAgICAgICAgICAgICAgICAgIHZhciBzaGVldFJlbGF0aW9uID0gcGNrLldvcmtib29rLlBhcnQuR2V0UmVsYXRpb25zaGlwKHJlbElkKTsKICAgICAgICAgICAgICAgICAgICBVcmkgdXJpV29ya3NoZWV0ID0gVXJpSGVscGVyLlJlc29sdmVQYXJ0VXJpKHBjay5Xb3JrYm9vay5Xb3JrYm9va1VyaSwgc2hlZXRSZWxhdGlvbi5UYXJnZXRVcmkpOwoKICAgICAgICAgICAgICAgICAgICAvL2FkZCB0aGUgd29ya3NoZWV0CiAgICAgICAgICAgICAgICAgICAgaWYgKHNoZWV0UmVsYXRpb24uUmVsYXRpb25zaGlwVHlwZS5FbmRzV2l0aCgiY2hhcnRzaGVldCIpKQogICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgX3dvcmtzaGVldHMuQWRkKHBvc2l0aW9uSUQsIG5ldyBFeGNlbENoYXJ0c2hlZXQoX25hbWVzcGFjZU1hbmFnZXIsIF9wY2ssIHJlbElkLCB1cmlXb3Jrc2hlZXQsIG5hbWUsIHNoZWV0SUQsIHBvc2l0aW9uSUQsIGhpZGRlbikpOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICBlbHNlCiAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICBfd29ya3NoZWV0cy5BZGQocG9zaXRpb25JRCwgbmV3IEV4Y2VsV29ya3NoZWV0KF9uYW1lc3BhY2VNYW5hZ2VyLCBfcGNrLCByZWxJZCwgdXJpV29ya3NoZWV0LCBuYW1lLCBzaGVldElELCBwb3NpdGlvbklELCBoaWRkZW4pKTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgcG9zaXRpb25JRCsrOwogICAgICAgICAgICAgICAgfQoJCQl9CgkJfQoKICAgICAgICBwcml2YXRlIGVXb3JrU2hlZXRIaWRkZW4gVHJhbnNsYXRlSGlkZGVuKHN0cmluZyB2YWx1ZSkKICAgICAgICB7CiAgICAgICAgICAgIHN3aXRjaCAodmFsdWUpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIGNhc2UgImhpZGRlbiI6CiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGVXb3JrU2hlZXRIaWRkZW4uSGlkZGVuOwogICAgICAgICAgICAgICAgY2FzZSAidmVyeUhpZGRlbiI6CiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGVXb3JrU2hlZXRIaWRkZW4uVmVyeUhpZGRlbjsKICAgICAgICAgICAgICAgIGRlZmF1bHQ6CiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGVXb3JrU2hlZXRIaWRkZW4uVmlzaWJsZTsKICAgICAgICAgICAgfQogICAgICAgIH0KCQkjZW5kcmVnaW9uCgkJI3JlZ2lvbiBFeGNlbFdvcmtzaGVldHMgUHVibGljIFByb3BlcnRpZXMKCQkvLy8gPHN1bW1hcnk+CgkJLy8vIFJldHVybnMgdGhlIG51bWJlciBvZiB3b3Jrc2hlZXRzIGluIHRoZSB3b3JrYm9vawoJCS8vLyA8L3N1bW1hcnk+CgkJcHVibGljIGludCBDb3VudAoJCXsKCQkJZ2V0IHsgcmV0dXJuIChfd29ya3NoZWV0cy5Db3VudCk7IH0KCQl9CgkJI2VuZHJlZ2lvbgogICAgICAgIHByaXZhdGUgY29uc3Qgc3RyaW5nIEVSUl9EVVBfV09SS1NIRUVUID0gIkEgd29ya3NoZWV0IHdpdGggdGhpcyBuYW1lIGFscmVhZHkgZXhpc3RzIGluIHRoZSB3b3JrYm9vayI7CiAgICAgICAgaW50ZXJuYWwgY29uc3Qgc3RyaW5nIFdPUktTSEVFVF9DT05URU5UVFlQRSA9IEAiYXBwbGljYXRpb24vdm5kLm9wZW54bWxmb3JtYXRzLW9mZmljZWRvY3VtZW50LnNwcmVhZHNoZWV0bWwud29ya3NoZWV0K3htbCI7CiAgICAgICAgaW50ZXJuYWwgY29uc3Qgc3RyaW5nIENIQVJUU0hFRVRfQ09OVEVOVFRZUEUgPSBAImFwcGxpY2F0aW9uL3ZuZC5vcGVueG1sZm9ybWF0cy1vZmZpY2Vkb2N1bWVudC5zcHJlYWRzaGVldG1sLmNoYXJ0c2hlZXQreG1sIjsKCQkjcmVnaW9uIEV4Y2VsV29ya3NoZWV0cyBQdWJsaWMgTWV0aG9kcwoJCS8vLyA8c3VtbWFyeT4KICAgICAgICAvLy8gRm9yZWFjaCBzdXBwb3J0CgkJLy8vIDwvc3VtbWFyeT4KCQkvLy8gPHJldHVybnM+QW4gZW51bWVyYXRvcjwvcmV0dXJucz4KCQlwdWJsaWMgSUVudW1lcmF0b3I8RXhjZWxXb3Jrc2hlZXQ+IEdldEVudW1lcmF0b3IoKQoJCXsKCQkJcmV0dXJuIChfd29ya3NoZWV0cy5WYWx1ZXMuR2V0RW51bWVyYXRvcigpKTsKICAgICAgICB9CiAgICAgICAgI3JlZ2lvbiBJRW51bWVyYWJsZSBNZW1iZXJzCgogICAgICAgIElFbnVtZXJhdG9yIElFbnVtZXJhYmxlLkdldEVudW1lcmF0b3IoKQogICAgICAgIHsKICAgICAgICAgICAgcmV0dXJuIChfd29ya3NoZWV0cy5WYWx1ZXMuR2V0RW51bWVyYXRvcigpKTsKICAgICAgICB9CgogICAgICAgICNlbmRyZWdpb24KCQkjcmVnaW9uIEFkZCBXb3Jrc2hlZXQKCQkvLy8gPHN1bW1hcnk+CgkJLy8vIEFkZHMgYSBuZXcgYmxhbmsgd29ya3NoZWV0LgoJCS8vLyA8L3N1bW1hcnk+CgkJLy8vIDxwYXJhbSBuYW1lPSJOYW1lIj5UaGUgbmFtZSBvZiB0aGUgd29ya2Jvb2s8L3BhcmFtPgoJCXB1YmxpYyBFeGNlbFdvcmtzaGVldCBBZGQoc3RyaW5nIE5hbWUpCgkJewogICAgICAgICAgICBFeGNlbFdvcmtzaGVldCB3b3Jrc2hlZXQgPSBBZGRTaGVldChOYW1lLGZhbHNlLCBudWxsKTsKCQkJcmV0dXJuIHdvcmtzaGVldDsKCQl9CiAgICAgICAgcHJpdmF0ZSBFeGNlbFdvcmtzaGVldCBBZGRTaGVldChzdHJpbmcgTmFtZSwgYm9vbCBpc0NoYXJ0LCBlQ2hhcnRUeXBlPyBjaGFydFR5cGUpCiAgICAgICAgewogICAgICAgICAgICBpbnQgc2hlZXRJRDsKICAgICAgICAgICAgVXJpIHVyaVdvcmtzaGVldDsKICAgICAgICAgICAgbG9jayAoX3dvcmtzaGVldHMpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIE5hbWUgPSBWYWxpZGF0ZUZpeFNoZWV0TmFtZShOYW1lKTsKICAgICAgICAgICAgICAgIGlmIChHZXRCeU5hbWUoTmFtZSkgIT0gbnVsbCkKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICB0aHJvdyAobmV3IEludmFsaWRPcGVyYXRpb25FeGNlcHRpb24oRVJSX0RVUF9XT1JLU0hFRVQgKyAiIDogIiArIE5hbWUpKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIEdldFNoZWV0VVJJKHJlZiBOYW1lLCBvdXQgc2hlZXRJRCwgb3V0IHVyaVdvcmtzaGVldCwgaXNDaGFydCk7CiAgICAgICAgICAgICAgICBQYWNrYWdpbmcuWmlwUGFja2FnZVBhcnQgd29ya3NoZWV0UGFydCA9IF9wY2suUGFja2FnZS5DcmVhdGVQYXJ0KHVyaVdvcmtzaGVldCwgaXNDaGFydCA/IENIQVJUU0hFRVRfQ09OVEVOVFRZUEUgOiBXT1JLU0hFRVRfQ09OVEVOVFRZUEUsIF9wY2suQ29tcHJlc3Npb24pOwoKICAgICAgICAgICAgICAgIC8vQ3JlYXRlIHRoZSBuZXcsIGVtcHR5IHdvcmtzaGVldCBhbmQgc2F2ZSBpdCB0byB0aGUgcGFja2FnZQogICAgICAgICAgICAgICAgU3RyZWFtV3JpdGVyIHN0cmVhbVdvcmtzaGVldCA9IG5ldyBTdHJlYW1Xcml0ZXIod29ya3NoZWV0UGFydC5HZXRTdHJlYW0oRmlsZU1vZGUuQ3JlYXRlLCBGaWxlQWNjZXNzLldyaXRlKSk7CiAgICAgICAgICAgICAgICBYbWxEb2N1bWVudCB3b3Jrc2hlZXRYbWwgPSBDcmVhdGVOZXdXb3Jrc2hlZXQoaXNDaGFydCk7CiAgICAgICAgICAgICAgICB3b3Jrc2hlZXRYbWwuU2F2ZShzdHJlYW1Xb3Jrc2hlZXQpOwogICAgICAgICAgICAgICAgX3Bjay5QYWNrYWdlLkZsdXNoKCk7CgogICAgICAgICAgICAgICAgc3RyaW5nIHJlbCA9IENyZWF0ZVdvcmtib29rUmVsKE5hbWUsIHNoZWV0SUQsIHVyaVdvcmtzaGVldCwgaXNDaGFydCk7CgogICAgICAgICAgICAgICAgaW50IHBvc2l0aW9uSUQgPSBfd29ya3NoZWV0cy5Db3VudCArIDE7CiAgICAgICAgICAgICAgICBFeGNlbFdvcmtzaGVldCB3b3Jrc2hlZXQ7CiAgICAgICAgICAgICAgICBpZiAoaXNDaGFydCkKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICB3b3Jrc2hlZXQgPSBuZXcgRXhjZWxDaGFydHNoZWV0KF9uYW1lc3BhY2VNYW5hZ2VyLCBfcGNrLCByZWwsIHVyaVdvcmtzaGVldCwgTmFtZSwgc2hlZXRJRCwgcG9zaXRpb25JRCwgZVdvcmtTaGVldEhpZGRlbi5WaXNpYmxlLCAoZUNoYXJ0VHlwZSljaGFydFR5cGUpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgZWxzZQogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIHdvcmtzaGVldCA9IG5ldyBFeGNlbFdvcmtzaGVldChfbmFtZXNwYWNlTWFuYWdlciwgX3BjaywgcmVsLCB1cmlXb3Jrc2hlZXQsIE5hbWUsIHNoZWV0SUQsIHBvc2l0aW9uSUQsIGVXb3JrU2hlZXRIaWRkZW4uVmlzaWJsZSk7CiAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgX3dvcmtzaGVldHMuQWRkKHBvc2l0aW9uSUQsIHdvcmtzaGVldCk7CiNpZiAhTU9OTwogICAgICAgICAgICAgICAgaWYgKF9wY2suV29ya2Jvb2suVmJhUHJvamVjdCAhPSBudWxsKQogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIHZhciBuYW1lID0gX3Bjay5Xb3JrYm9vay5WYmFQcm9qZWN0LkdldE1vZHVsZU5hbWVGcm9tV29ya3NoZWV0KHdvcmtzaGVldCk7CiAgICAgICAgICAgICAgICAgICAgX3Bjay5Xb3JrYm9vay5WYmFQcm9qZWN0Lk1vZHVsZXMuQWRkKG5ldyBFeGNlbFZCQU1vZHVsZSh3b3Jrc2hlZXQuQ29kZU5hbWVDaGFuZ2UpIHsgTmFtZSA9IG5hbWUsIENvZGUgPSAiIiwgQXR0cmlidXRlcyA9IF9wY2suV29ya2Jvb2suVmJhUHJvamVjdC5HZXREb2N1bWVudEF0dHJpYnV0ZXMoTmFtZSwgIjB7MDAwMjA4MjAtMDAwMC0wMDAwLUMwMDAtMDAwMDAwMDAwMDQ2fSIpLCBUeXBlID0gZU1vZHVsZVR5cGUuRG9jdW1lbnQsIEhlbHBDb250ZXh0ID0gMCB9KTsKICAgICAgICAgICAgICAgICAgICB3b3Jrc2hlZXQuQ29kZU1vZHVsZU5hbWUgPSBuYW1lOwoKICAgICAgICAgICAgICAgIH0KI2VuZGlmCiAgICAgICAgICAgICAgICByZXR1cm4gd29ya3NoZWV0OwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIC8vLyA8c3VtbWFyeT4KICAgICAgICAvLy8gQWRkcyBhIGNvcHkgb2YgYSB3b3Jrc2hlZXQKICAgICAgICAvLy8gPC9zdW1tYXJ5PgogICAgICAgIC8vLyA8cGFyYW0gbmFtZT0iTmFtZSI+VGhlIG5hbWUgb2YgdGhlIHdvcmtib29rPC9wYXJhbT4KICAgICAgICAvLy8gPHBhcmFtIG5hbWU9IkNvcHkiPlRoZSB3b3Jrc2hlZXQgdG8gYmUgY29waWVkPC9wYXJhbT4KICAgICAgICBwdWJsaWMgRXhjZWxXb3Jrc2hlZXQgQWRkKHN0cmluZyBOYW1lLCBFeGNlbFdvcmtzaGVldCBDb3B5KQogICAgICAgIHsKICAgICAgICAgICAgbG9jayAoX3dvcmtzaGVldHMpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIGludCBzaGVldElEOwogICAgICAgICAgICAgICAgVXJpIHVyaVdvcmtzaGVldDsKICAgICAgICAgICAgICAgIGlmIChDb3B5IGlzIEV4Y2VsQ2hhcnRzaGVldCkKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICB0aHJvdyAobmV3IEFyZ3VtZW50RXhjZXB0aW9uKCJDYW4gbm90IGNvcHkgYSBjaGFydHNoZWV0IikpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgaWYgKEdldEJ5TmFtZShOYW1lKSAhPSBudWxsKQogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIHRocm93IChuZXcgSW52YWxpZE9wZXJhdGlvbkV4Y2VwdGlvbihFUlJfRFVQX1dPUktTSEVFVCkpOwogICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgIEdldFNoZWV0VVJJKHJlZiBOYW1lLCBvdXQgc2hlZXRJRCwgb3V0IHVyaVdvcmtzaGVldCwgZmFsc2UpOwoKICAgICAgICAgICAgICAgIC8vQ3JlYXRlIGEgY29weSBvZiB0aGUgd29ya3NoZWV0IFhNTAogICAgICAgICAgICAgICAgUGFja2FnaW5nLlppcFBhY2thZ2VQYXJ0IHdvcmtzaGVldFBhcnQgPSBfcGNrLlBhY2thZ2UuQ3JlYXRlUGFydCh1cmlXb3Jrc2hlZXQsIFdPUktTSEVFVF9DT05URU5UVFlQRSwgX3Bjay5Db21wcmVzc2lvbik7CiAgICAgICAgICAgICAgICBTdHJlYW1Xcml0ZXIgc3RyZWFtV29ya3NoZWV0ID0gbmV3IFN0cmVhbVdyaXRlcih3b3Jrc2hlZXRQYXJ0LkdldFN0cmVhbShGaWxlTW9kZS5DcmVhdGUsIEZpbGVBY2Nlc3MuV3JpdGUpKTsKICAgICAgICAgICAgICAgIFhtbERvY3VtZW50IHdvcmtzaGVldFhtbCA9IG5ldyBYbWxEb2N1bWVudCgpOwogICAgICAgICAgICAgICAgd29ya3NoZWV0WG1sLkxvYWRYbWwoQ29weS5Xb3Jrc2hlZXRYbWwuT3V0ZXJYbWwpOwogICAgICAgICAgICAgICAgd29ya3NoZWV0WG1sLlNhdmUoc3RyZWFtV29ya3NoZWV0KTsKICAgICAgICAgICAgICAgIC8vc3RyZWFtV29ya3NoZWV0LkNsb3NlKCk7CiAgICAgICAgICAgICAgICBfcGNrLlBhY2thZ2UuRmx1c2goKTsKCgogICAgICAgICAgICAgICAgLy9DcmVhdGUgYSByZWxhdGlvbiB0byB0aGUgd29ya2Jvb2sKICAgICAgICAgICAgICAgIHN0cmluZyByZWxJRCA9IENyZWF0ZVdvcmtib29rUmVsKE5hbWUsIHNoZWV0SUQsIHVyaVdvcmtzaGVldCwgZmFsc2UpOwogICAgICAgICAgICAgICAgRXhjZWxXb3Jrc2hlZXQgYWRkZWQgPSBuZXcgRXhjZWxXb3Jrc2hlZXQoX25hbWVzcGFjZU1hbmFnZXIsIF9wY2ssIHJlbElELCB1cmlXb3Jrc2hlZXQsIE5hbWUsIHNoZWV0SUQsIF93b3Jrc2hlZXRzLkNvdW50ICsgMSwgZVdvcmtTaGVldEhpZGRlbi5WaXNpYmxlKTsKCiAgICAgICAgICAgICAgICAvL0NvcHkgY29tbWVudHMKICAgICAgICAgICAgICAgIGlmIChDb3B5LkNvbW1lbnRzLkNvdW50ID4gMCkKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICBDb3B5Q29tbWVudChDb3B5LCBhZGRlZCk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBlbHNlIGlmIChDb3B5LlZtbERyYXdpbmdzQ29tbWVudHMuQ291bnQgPiAwKSAgICAvL1ZtbCBkcmF3aW5ncyBhcmUgY29waWVkIGFzIHBhcnQgb2YgdGhlIGNvbW1lbnRzLiAKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICBDb3B5Vm1sRHJhd2luZyhDb3B5LCBhZGRlZCk7CiAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgLy9Db3B5IEhlYWRlckZvb3RlcgogICAgICAgICAgICAgICAgQ29weUhlYWRlckZvb3RlclBpY3R1cmVzKENvcHksIGFkZGVkKTsKCiAgICAgICAgICAgICAgICAvL0NvcHkgYWxsIHJlbGF0aW9uc2hpcHMgCiAgICAgICAgICAgICAgICAvL0NvcHlSZWxhdGlvblNoaXBzKENvcHksIGFkZGVkKTsKICAgICAgICAgICAgICAgIGlmIChDb3B5LkRyYXdpbmdzLkNvdW50ID4gMCkKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICBDb3B5RHJhd2luZyhDb3B5LCBhZGRlZCk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBpZiAoQ29weS5UYWJsZXMuQ291bnQgPiAwKQogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIENvcHlUYWJsZShDb3B5LCBhZGRlZCk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBpZiAoQ29weS5QaXZvdFRhYmxlcy5Db3VudCA+IDApCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgQ29weVBpdm90VGFibGUoQ29weSwgYWRkZWQpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgaWYgKENvcHkuTmFtZXMuQ291bnQgPiAwKQogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIENvcHlTaGVldE5hbWVzKENvcHksIGFkZGVkKTsKICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICAvL0NvcHkgYWxsIGNlbGxzCiAgICAgICAgICAgICAgICBDbG9uZUNlbGxzKENvcHksIGFkZGVkKTsKCiAgICAgICAgICAgICAgICAvL0NvcHkgdGhlIFZCQSBjb2RlCiNpZiAhTU9OTwogICAgICAgICAgICAgICAgaWYgKF9wY2suV29ya2Jvb2suVmJhUHJvamVjdCAhPSBudWxsKQogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIHZhciBuYW1lID0gX3Bjay5Xb3JrYm9vay5WYmFQcm9qZWN0LkdldE1vZHVsZU5hbWVGcm9tV29ya3NoZWV0KGFkZGVkKTsKICAgICAgICAgICAgICAgICAgICBfcGNrLldvcmtib29rLlZiYVByb2plY3QuTW9kdWxlcy5BZGQobmV3IEV4Y2VsVkJBTW9kdWxlKGFkZGVkLkNvZGVOYW1lQ2hhbmdlKSB7IE5hbWUgPSBuYW1lLCBDb2RlID0gQ29weS5Db2RlTW9kdWxlLkNvZGUsIEF0dHJpYnV0ZXMgPSBfcGNrLldvcmtib29rLlZiYVByb2plY3QuR2V0RG9jdW1lbnRBdHRyaWJ1dGVzKE5hbWUsICIwezAwMDIwODIwLTAwMDAtMDAwMC1DMDAwLTAwMDAwMDAwMDA0Nn0iKSwgVHlwZSA9IGVNb2R1bGVUeXBlLkRvY3VtZW50LCBIZWxwQ29udGV4dCA9IDAgfSk7CiAgICAgICAgICAgICAgICAgICAgQ29weS5Db2RlTW9kdWxlTmFtZSA9IG5hbWU7CiAgICAgICAgICAgICAgICB9CiNlbmRpZgoKICAgICAgICAgICAgICAgIF93b3Jrc2hlZXRzLkFkZChfd29ya3NoZWV0cy5Db3VudCArIDEsIGFkZGVkKTsKCiAgICAgICAgICAgICAgICAvL1JlbW92ZSBhbnkgcmVsYXRpb24gdG8gcHJpbnRlcnNldHRpbmdzLgogICAgICAgICAgICAgICAgWG1sTm9kZSBwYWdlU2V0dXAgPSBhZGRlZC5Xb3Jrc2hlZXRYbWwuU2VsZWN0U2luZ2xlTm9kZSgiLy9kOnBhZ2VTZXR1cCIsIF9uYW1lc3BhY2VNYW5hZ2VyKTsKICAgICAgICAgICAgICAgIGlmIChwYWdlU2V0dXAgIT0gbnVsbCkKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICBYbWxBdHRyaWJ1dGUgYXR0ciA9IChYbWxBdHRyaWJ1dGUpcGFnZVNldHVwLkF0dHJpYnV0ZXMuR2V0TmFtZWRJdGVtKCJpZCIsIEV4Y2VsUGFja2FnZS5zY2hlbWFSZWxhdGlvbnNoaXBzKTsKICAgICAgICAgICAgICAgICAgICBpZiAoYXR0ciAhPSBudWxsKQogICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgcmVsSUQgPSBhdHRyLlZhbHVlOwogICAgICAgICAgICAgICAgICAgICAgICAvLyBmaXJzdCBkZWxldGUgdGhlIGF0dHJpYnV0ZSBmcm9tIHRoZSBYTUwKICAgICAgICAgICAgICAgICAgICAgICAgcGFnZVNldHVwLkF0dHJpYnV0ZXMuUmVtb3ZlKGF0dHIpOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIHJldHVybiBhZGRlZDsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgICAgICBwdWJsaWMgRXhjZWxDaGFydHNoZWV0IEFkZENoYXJ0KHN0cmluZyBOYW1lLCBlQ2hhcnRUeXBlIGNoYXJ0VHlwZSkKICAgICAgICB7CiAgICAgICAgICAgIHJldHVybiAoRXhjZWxDaGFydHNoZWV0KUFkZFNoZWV0KE5hbWUsIHRydWUsIGNoYXJ0VHlwZSk7CiAgICAgICAgfQogICAgICAgIHByaXZhdGUgdm9pZCBDb3B5U2hlZXROYW1lcyhFeGNlbFdvcmtzaGVldCBDb3B5LCBFeGNlbFdvcmtzaGVldCBhZGRlZCkKICAgICAgICB7CiAgICAgICAgICAgIGZvcmVhY2ggKHZhciBuYW1lIGluIENvcHkuTmFtZXMpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIEV4Y2VsTmFtZWRSYW5nZSBuZXdOYW1lOwogICAgICAgICAgICAgICAgaWYgKCFuYW1lLklzTmFtZSkKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICBpZiAobmFtZS5Xb3JrU2hlZXQgPT0gQ29weS5OYW1lKQogICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgbmV3TmFtZSA9IGFkZGVkLk5hbWVzLkFkZChuYW1lLk5hbWUsIGFkZGVkLkNlbGxzW25hbWUuRmlyc3RBZGRyZXNzXSk7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIGVsc2UKICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgIG5ld05hbWUgPSBhZGRlZC5OYW1lcy5BZGQobmFtZS5OYW1lLCBhZGRlZC5Xb3JrYm9vay5Xb3Jrc2hlZXRzW25hbWUuV29ya1NoZWV0XS5DZWxsc1tuYW1lLkZpcnN0QWRkcmVzc10pOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGVsc2UgaWYgKCFzdHJpbmcuSXNOdWxsT3JFbXB0eShuYW1lLk5hbWVGb3JtdWxhKSkKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICBuZXdOYW1lPWFkZGVkLk5hbWVzLkFkZEZvcm11bGEobmFtZS5OYW1lLCBuYW1lLkZvcm11bGEpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgZWxzZQogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIG5ld05hbWU9YWRkZWQuTmFtZXMuQWRkVmFsdWUobmFtZS5OYW1lLCBuYW1lLlZhbHVlKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgbmV3TmFtZS5OYW1lQ29tbWVudCA9IG5hbWUuTmFtZUNvbW1lbnQ7CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIHByaXZhdGUgdm9pZCBDb3B5VGFibGUoRXhjZWxXb3Jrc2hlZXQgQ29weSwgRXhjZWxXb3Jrc2hlZXQgYWRkZWQpCiAgICAgICAgewogICAgICAgICAgICBzdHJpbmcgcHJldk5hbWUgPSAiIjsKICAgICAgICAgICAgLy9GaXJzdCBjb3B5IHRoZSB0YWJsZSBYTUwKICAgICAgICAgICAgZm9yZWFjaCAodmFyIHRibCBpbiBDb3B5LlRhYmxlcykKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgc3RyaW5nIHhtbD10YmwuVGFibGVYbWwuT3V0ZXJYbWw7CiAgICAgICAgICAgICAgICBpbnQgSWQgPSBfcGNrLldvcmtib29rLl9uZXh0VGFibGVJRCsrOwogICAgICAgICAgICAgICAgc3RyaW5nIG5hbWU7CiAgICAgICAgICAgICAgICBpZiAocHJldk5hbWUgPT0gIiIpCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgbmFtZSA9IENvcHkuVGFibGVzLkdldE5ld1RhYmxlTmFtZSgpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgZWxzZQogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIGludCBpeCA9IGludC5QYXJzZShwcmV2TmFtZS5TdWJzdHJpbmcoNSkpICsgMTsKICAgICAgICAgICAgICAgICAgICBuYW1lID0gc3RyaW5nLkZvcm1hdCgiVGFibGV7MH0iLCBpeCk7CiAgICAgICAgICAgICAgICAgICAgd2hpbGUgKF9wY2suV29ya2Jvb2suRXhpc3RzUGl2b3RUYWJsZU5hbWUobmFtZSkpCiAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICBuYW1lID0gc3RyaW5nLkZvcm1hdCgiVGFibGV7MH0iLCArK2l4KTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBwcmV2TmFtZSA9IG5hbWU7CiAgICAgICAgICAgICAgICBYbWxEb2N1bWVudCB4bWxEb2MgPSBuZXcgWG1sRG9jdW1lbnQoKTsKICAgICAgICAgICAgICAgIHhtbERvYy5Mb2FkWG1sKHhtbCk7CiAgICAgICAgICAgICAgICB4bWxEb2MuU2VsZWN0U2luZ2xlTm9kZSgiLy9kOnRhYmxlL0BpZCIsIHRibC5OYW1lU3BhY2VNYW5hZ2VyKS5WYWx1ZSA9IElkLlRvU3RyaW5nKCk7CiAgICAgICAgICAgICAgICB4bWxEb2MuU2VsZWN0U2luZ2xlTm9kZSgiLy9kOnRhYmxlL0BuYW1lIiwgdGJsLk5hbWVTcGFjZU1hbmFnZXIpLlZhbHVlID0gbmFtZTsKICAgICAgICAgICAgICAgIHhtbERvYy5TZWxlY3RTaW5nbGVOb2RlKCIvL2Q6dGFibGUvQGRpc3BsYXlOYW1lIiwgdGJsLk5hbWVTcGFjZU1hbmFnZXIpLlZhbHVlID0gbmFtZTsKICAgICAgICAgICAgICAgIHhtbCA9IHhtbERvYy5PdXRlclhtbDsKCiAgICAgICAgICAgICAgICB2YXIgdXJpVGJsID0gbmV3IFVyaShzdHJpbmcuRm9ybWF0KCIveGwvdGFibGVzL3RhYmxlezB9LnhtbCIsIElkKSwgVXJpS2luZC5SZWxhdGl2ZSk7CiAgICAgICAgICAgICAgICB2YXIgcGFydCA9IF9wY2suUGFja2FnZS5DcmVhdGVQYXJ0KHVyaVRibCwgImFwcGxpY2F0aW9uL3ZuZC5vcGVueG1sZm9ybWF0cy1vZmZpY2Vkb2N1bWVudC5zcHJlYWRzaGVldG1sLnRhYmxlK3htbCIsIF9wY2suQ29tcHJlc3Npb24pOwogICAgICAgICAgICAgICAgU3RyZWFtV3JpdGVyIHN0cmVhbVRibCA9IG5ldyBTdHJlYW1Xcml0ZXIocGFydC5HZXRTdHJlYW0oRmlsZU1vZGUuQ3JlYXRlLCBGaWxlQWNjZXNzLldyaXRlKSk7CiAgICAgICAgICAgICAgICBzdHJlYW1UYmwuV3JpdGUoeG1sKTsKICAgICAgICAgICAgICAgIC8vc3RyZWFtVGJsLkNsb3NlKCk7CiAgICAgICAgICAgICAgICBzdHJlYW1UYmwuRmx1c2goKTsKCiAgICAgICAgICAgICAgICAvL2NyZWF0ZSB0aGUgcmVsYXRpb25zaGlwIGFuZCBhZGQgdGhlIElEIHRvIHRoZSB3b3Jrc2hlZXQgeG1sLgogICAgICAgICAgICAgICAgdmFyIHJlbCA9IGFkZGVkLlBhcnQuQ3JlYXRlUmVsYXRpb25zaGlwKFVyaUhlbHBlci5HZXRSZWxhdGl2ZVVyaShhZGRlZC5Xb3Jrc2hlZXRVcmksdXJpVGJsKSwgUGFja2FnaW5nLlRhcmdldE1vZGUuSW50ZXJuYWwsIEV4Y2VsUGFja2FnZS5zY2hlbWFSZWxhdGlvbnNoaXBzICsgIi90YWJsZSIpOwoKICAgICAgICAgICAgICAgIGlmICh0YmwuUmVsYXRpb25zaGlwSUQgPT0gbnVsbCkKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICB2YXIgdG9wTm9kZSA9IGFkZGVkLldvcmtzaGVldFhtbC5TZWxlY3RTaW5nbGVOb2RlKCIvL2Q6dGFibGVQYXJ0cyIsIHRibC5OYW1lU3BhY2VNYW5hZ2VyKTsKICAgICAgICAgICAgICAgICAgICBpZiAodG9wTm9kZSA9PSBudWxsKQogICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgYWRkZWQuQ3JlYXRlTm9kZSgiZDp0YWJsZVBhcnRzIik7CiAgICAgICAgICAgICAgICAgICAgICAgIHRvcE5vZGUgPSBhZGRlZC5Xb3Jrc2hlZXRYbWwuU2VsZWN0U2luZ2xlTm9kZSgiLy9kOnRhYmxlUGFydHMiLCB0YmwuTmFtZVNwYWNlTWFuYWdlcik7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIFhtbEVsZW1lbnQgZWxlbSA9IGFkZGVkLldvcmtzaGVldFhtbC5DcmVhdGVFbGVtZW50KCJ0YWJsZVBhcnQiLCBFeGNlbFBhY2thZ2Uuc2NoZW1hTWFpbik7CiAgICAgICAgICAgICAgICAgICAgdG9wTm9kZS5BcHBlbmRDaGlsZChlbGVtKTsKICAgICAgICAgICAgICAgICAgICBlbGVtLlNldEF0dHJpYnV0ZSgiaWQiLEV4Y2VsUGFja2FnZS5zY2hlbWFSZWxhdGlvbnNoaXBzLCByZWwuSWQpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgZWxzZQogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIFhtbEF0dHJpYnV0ZSByZWxBdHQ7CiAgICAgICAgICAgICAgICAgICAgcmVsQXR0ID0gYWRkZWQuV29ya3NoZWV0WG1sLlNlbGVjdFNpbmdsZU5vZGUoc3RyaW5nLkZvcm1hdCgiLy9kOnRhYmxlUGFydHMvZDp0YWJsZVBhcnQvQHI6aWRbLj0nezB9J10iLCB0YmwuUmVsYXRpb25zaGlwSUQpLCB0YmwuTmFtZVNwYWNlTWFuYWdlcikgYXMgWG1sQXR0cmlidXRlOwogICAgICAgICAgICAgICAgICAgIHJlbEF0dC5WYWx1ZSA9IHJlbC5JZDsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgIH0KICAgICAgICBwcml2YXRlIHZvaWQgQ29weVBpdm90VGFibGUoRXhjZWxXb3Jrc2hlZXQgQ29weSwgRXhjZWxXb3Jrc2hlZXQgYWRkZWQpCiAgICAgICAgewogICAgICAgICAgICBzdHJpbmcgcHJldk5hbWUgPSAiIjsKICAgICAgICAgICAgZm9yZWFjaCAodmFyIHRibCBpbiBDb3B5LlBpdm90VGFibGVzKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBzdHJpbmcgeG1sID0gdGJsLlBpdm90VGFibGVYbWwuT3V0ZXJYbWw7CiAgICAgICAgICAgICAgICBpbnQgSWQgPSBfcGNrLldvcmtib29rLl9uZXh0UGl2b3RUYWJsZUlEKys7CgogICAgICAgICAgICAgICAgc3RyaW5nIG5hbWU7CiAgICAgICAgICAgICAgICBpZiAocHJldk5hbWUgPT0gIiIpCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgbmFtZSA9IENvcHkuUGl2b3RUYWJsZXMuR2V0TmV3VGFibGVOYW1lKCk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBlbHNlCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgaW50IGl4PWludC5QYXJzZShwcmV2TmFtZS5TdWJzdHJpbmcoMTApKSsxOwogICAgICAgICAgICAgICAgICAgIG5hbWUgPSBzdHJpbmcuRm9ybWF0KCJQaXZvdFRhYmxlezB9IiwgaXgpOwogICAgICAgICAgICAgICAgICAgIHdoaWxlIChfcGNrLldvcmtib29rLkV4aXN0c1Bpdm90VGFibGVOYW1lKG5hbWUpKQogICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgbmFtZSA9IHN0cmluZy5Gb3JtYXQoIlBpdm90VGFibGV7MH0iLCArK2l4KTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBwcmV2TmFtZT1uYW1lOwogICAgICAgICAgICAgICAgWG1sRG9jdW1lbnQgeG1sRG9jID0gbmV3IFhtbERvY3VtZW50KCk7CiAgICAgICAgICAgICAgICAvL1RPRE86IEZpeCBzYXZlIHBpdm90dGFibGUgaGVyZQogICAgICAgICAgICAgICAgLy9Db3B5LlNhdmUoKTsgICAgLy9TYXZlIHRoZSB3b3Jrc2hlZXQgZmlyc3QKICAgICAgICAgICAgICAgIHhtbERvYy5Mb2FkWG1sKHhtbCk7CiAgICAgICAgICAgICAgICAvL3htbERvYy5TZWxlY3RTaW5nbGVOb2RlKCIvL2Q6dGFibGUvQGlkIiwgdGJsLk5hbWVTcGFjZU1hbmFnZXIpLlZhbHVlID0gSWQuVG9TdHJpbmcoKTsKICAgICAgICAgICAgICAgIHhtbERvYy5TZWxlY3RTaW5nbGVOb2RlKCIvL2Q6cGl2b3RUYWJsZURlZmluaXRpb24vQG5hbWUiLCB0YmwuTmFtZVNwYWNlTWFuYWdlcikuVmFsdWUgPSBuYW1lOwogICAgICAgICAgICAgICAgeG1sID0geG1sRG9jLk91dGVyWG1sOwoKICAgICAgICAgICAgICAgIHZhciB1cmlUYmwgPSBuZXcgVXJpKHN0cmluZy5Gb3JtYXQoIi94bC9waXZvdFRhYmxlcy9waXZvdFRhYmxlezB9LnhtbCIsIElkKSwgVXJpS2luZC5SZWxhdGl2ZSk7CiAgICAgICAgICAgICAgICB2YXIgcGFydFRibCA9IF9wY2suUGFja2FnZS5DcmVhdGVQYXJ0KHVyaVRibCwgRXhjZWxQYWNrYWdlLnNjaGVtYVBpdm90VGFibGUgLCBfcGNrLkNvbXByZXNzaW9uKTsKICAgICAgICAgICAgICAgIFN0cmVhbVdyaXRlciBzdHJlYW1UYmwgPSBuZXcgU3RyZWFtV3JpdGVyKHBhcnRUYmwuR2V0U3RyZWFtKEZpbGVNb2RlLkNyZWF0ZSwgRmlsZUFjY2Vzcy5Xcml0ZSkpOwogICAgICAgICAgICAgICAgc3RyZWFtVGJsLldyaXRlKHhtbCk7CiAgICAgICAgICAgICAgICAvL3N0cmVhbVRibC5DbG9zZSgpOwogICAgICAgICAgICAgICAgc3RyZWFtVGJsLkZsdXNoKCk7CgogICAgICAgICAgICAgICAgeG1sID0gdGJsLkNhY2hlRGVmaW5pdGlvbi5DYWNoZURlZmluaXRpb25YbWwuT3V0ZXJYbWw7ICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgdmFyIHVyaUNkID0gbmV3IFVyaShzdHJpbmcuRm9ybWF0KCIveGwvcGl2b3RDYWNoZS9waXZvdGNhY2hlZGVmaW5pdGlvbnswfS54bWwiLCBJZCksIFVyaUtpbmQuUmVsYXRpdmUpOwogICAgICAgICAgICAgICAgd2hpbGUgKF9wY2suUGFja2FnZS5QYXJ0RXhpc3RzKHVyaUNkKSkKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICB1cmlDZCA9IG5ldyBVcmkoc3RyaW5nLkZvcm1hdCgiL3hsL3Bpdm90Q2FjaGUvcGl2b3RjYWNoZWRlZmluaXRpb257MH0ueG1sIiwgKytJZCksIFVyaUtpbmQuUmVsYXRpdmUpOwogICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgIHZhciBwYXJ0Q2QgPSBfcGNrLlBhY2thZ2UuQ3JlYXRlUGFydCh1cmlDZCwgRXhjZWxQYWNrYWdlLnNjaGVtYVBpdm90Q2FjaGVEZWZpbml0aW9uLCBfcGNrLkNvbXByZXNzaW9uKTsKICAgICAgICAgICAgICAgIFN0cmVhbVdyaXRlciBzdHJlYW1DZCA9IG5ldyBTdHJlYW1Xcml0ZXIocGFydENkLkdldFN0cmVhbShGaWxlTW9kZS5DcmVhdGUsIEZpbGVBY2Nlc3MuV3JpdGUpKTsKICAgICAgICAgICAgICAgIHN0cmVhbUNkLldyaXRlKHhtbCk7CiAgICAgICAgICAgICAgICBzdHJlYW1DZC5GbHVzaCgpOwoKICAgICAgICAgICAgICAgIHhtbCA9ICI8cGl2b3RDYWNoZVJlY29yZHMgeG1sbnM9XCJodHRwOi8vc2NoZW1hcy5vcGVueG1sZm9ybWF0cy5vcmcvc3ByZWFkc2hlZXRtbC8yMDA2L21haW5cIiB4bWxuczpyPVwiaHR0cDovL3NjaGVtYXMub3BlbnhtbGZvcm1hdHMub3JnL29mZmljZURvY3VtZW50LzIwMDYvcmVsYXRpb25zaGlwc1wiIGNvdW50PVwiMFwiIC8+IjsKICAgICAgICAgICAgICAgIHZhciB1cmlSZWMgPSBuZXcgVXJpKHN0cmluZy5Gb3JtYXQoIi94bC9waXZvdENhY2hlL3Bpdm90cmVjb3Jkc3swfS54bWwiLCBJZCksIFVyaUtpbmQuUmVsYXRpdmUpOwogICAgICAgICAgICAgICAgd2hpbGUgKF9wY2suUGFja2FnZS5QYXJ0RXhpc3RzKHVyaVJlYykpCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgdXJpUmVjID0gbmV3IFVyaShzdHJpbmcuRm9ybWF0KCIveGwvcGl2b3RDYWNoZS9waXZvdHJlY29yZHN7MH0ueG1sIiwgKytJZCksIFVyaUtpbmQuUmVsYXRpdmUpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgdmFyIHBhcnRSZWMgPSBfcGNrLlBhY2thZ2UuQ3JlYXRlUGFydCh1cmlSZWMsIEV4Y2VsUGFja2FnZS5zY2hlbWFQaXZvdENhY2hlUmVjb3JkcywgX3Bjay5Db21wcmVzc2lvbik7CiAgICAgICAgICAgICAgICBTdHJlYW1Xcml0ZXIgc3RyZWFtUmVjID0gbmV3IFN0cmVhbVdyaXRlcihwYXJ0UmVjLkdldFN0cmVhbShGaWxlTW9kZS5DcmVhdGUsIEZpbGVBY2Nlc3MuV3JpdGUpKTsKICAgICAgICAgICAgICAgIHN0cmVhbVJlYy5Xcml0ZSh4bWwpOwogICAgICAgICAgICAgICAgc3RyZWFtUmVjLkZsdXNoKCk7CgogICAgICAgICAgICAgICAgLy9jcmVhdGUgdGhlIHJlbGF0aW9uc2hpcCBhbmQgYWRkIHRoZSBJRCB0byB0aGUgd29ya3NoZWV0IHhtbC4KICAgICAgICAgICAgICAgIGFkZGVkLlBhcnQuQ3JlYXRlUmVsYXRpb25zaGlwKFVyaUhlbHBlci5SZXNvbHZlUGFydFVyaShhZGRlZC5Xb3Jrc2hlZXRVcmksIHVyaVRibCksIFBhY2thZ2luZy5UYXJnZXRNb2RlLkludGVybmFsLCBFeGNlbFBhY2thZ2Uuc2NoZW1hUmVsYXRpb25zaGlwcyArICIvcGl2b3RUYWJsZSIpOwogICAgICAgICAgICAgICAgcGFydFRibC5DcmVhdGVSZWxhdGlvbnNoaXAoVXJpSGVscGVyLlJlc29sdmVQYXJ0VXJpKHRibC5SZWxhdGlvbnNoaXAuU291cmNlVXJpLCB1cmlDZCksIHRibC5DYWNoZURlZmluaXRpb24uUmVsYXRpb25zaGlwLlRhcmdldE1vZGUsIHRibC5DYWNoZURlZmluaXRpb24uUmVsYXRpb25zaGlwLlJlbGF0aW9uc2hpcFR5cGUpOwogICAgICAgICAgICAgICAgcGFydENkLkNyZWF0ZVJlbGF0aW9uc2hpcChVcmlIZWxwZXIuUmVzb2x2ZVBhcnRVcmkodXJpQ2QsIHVyaVJlYyksIFBhY2thZ2luZy5UYXJnZXRNb2RlLkludGVybmFsLCBFeGNlbFBhY2thZ2Uuc2NoZW1hUmVsYXRpb25zaGlwcyArICIvcGl2b3RDYWNoZVJlY29yZHMiKTsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgICAgICBwcml2YXRlIHZvaWQgQ29weUhlYWRlckZvb3RlclBpY3R1cmVzKEV4Y2VsV29ya3NoZWV0IENvcHksIEV4Y2VsV29ya3NoZWV0IGFkZGVkKQogICAgICAgIHsKICAgICAgICAgICAgaWYgKENvcHkuVG9wTm9kZSAhPSBudWxsICYmIENvcHkuVG9wTm9kZS5TZWxlY3RTaW5nbGVOb2RlKCJkOmhlYWRlckZvb3RlciIsIE5hbWVTcGFjZU1hbmFnZXIpPT1udWxsKSByZXR1cm47CiAgICAgICAgICAgIC8vQ29weSB0aGUgdGV4dHMKICAgICAgICAgICAgQ29weVRleHQoQ29weS5IZWFkZXJGb290ZXIuX29kZEhlYWRlciwgYWRkZWQuSGVhZGVyRm9vdGVyLk9kZEhlYWRlcik7CiAgICAgICAgICAgIENvcHlUZXh0KENvcHkuSGVhZGVyRm9vdGVyLl9vZGRGb290ZXIsIGFkZGVkLkhlYWRlckZvb3Rlci5PZGRGb290ZXIpOwogICAgICAgICAgICBDb3B5VGV4dChDb3B5LkhlYWRlckZvb3Rlci5fZXZlbkhlYWRlciwgYWRkZWQuSGVhZGVyRm9vdGVyLkV2ZW5IZWFkZXIpOwogICAgICAgICAgICBDb3B5VGV4dChDb3B5LkhlYWRlckZvb3Rlci5fZXZlbkZvb3RlciwgYWRkZWQuSGVhZGVyRm9vdGVyLkV2ZW5Gb290ZXIpOwogICAgICAgICAgICBDb3B5VGV4dChDb3B5LkhlYWRlckZvb3Rlci5fZmlyc3RIZWFkZXIsIGFkZGVkLkhlYWRlckZvb3Rlci5GaXJzdEhlYWRlcik7CiAgICAgICAgICAgIENvcHlUZXh0KENvcHkuSGVhZGVyRm9vdGVyLl9maXJzdEZvb3RlciwgYWRkZWQuSGVhZGVyRm9vdGVyLkZpcnN0Rm9vdGVyKTsKICAgICAgICAgICAgCiAgICAgICAgICAgIC8vQ29weSBhbnkgaW1hZ2VzOwogICAgICAgICAgICBpZiAoQ29weS5IZWFkZXJGb290ZXIuUGljdHVyZXMuQ291bnQgPiAwKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBVcmkgc291cmNlID0gQ29weS5IZWFkZXJGb290ZXIuUGljdHVyZXMuVXJpOwogICAgICAgICAgICAgICAgVXJpIGRlc3QgPSBYbWxIZWxwZXIuR2V0TmV3VXJpKF9wY2suUGFja2FnZSwgQCIveGwvZHJhd2luZ3Mvdm1sRHJhd2luZ3swfS52bWwiKTsKICAgICAgICAgICAgICAgIGFkZGVkLkRlbGV0ZU5vZGUoImQ6bGVnYWN5RHJhd2luZ0hGIik7CgogICAgICAgICAgICAgICAgLy92YXIgcGFydCA9IF9wY2suUGFja2FnZS5DcmVhdGVQYXJ0KGRlc3QsICJhcHBsaWNhdGlvbi92bmQub3BlbnhtbGZvcm1hdHMtb2ZmaWNlZG9jdW1lbnQudm1sRHJhd2luZyIsIF9wY2suQ29tcHJlc3Npb24pOwogICAgICAgICAgICAgICAgZm9yZWFjaCAoRXhjZWxWbWxEcmF3aW5nUGljdHVyZSBwaWMgaW4gQ29weS5IZWFkZXJGb290ZXIuUGljdHVyZXMpCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgdmFyIGl0ZW0gPSBhZGRlZC5IZWFkZXJGb290ZXIuUGljdHVyZXMuQWRkKHBpYy5JZCwgcGljLkltYWdlVXJpLCBwaWMuVGl0bGUsIHBpYy5XaWR0aCwgcGljLkhlaWdodCk7CiAgICAgICAgICAgICAgICAgICAgZm9yZWFjaCAoWG1sQXR0cmlidXRlIGF0dCBpbiBwaWMuVG9wTm9kZS5BdHRyaWJ1dGVzKQogICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgKGl0ZW0uVG9wTm9kZSBhcyBYbWxFbGVtZW50KS5TZXRBdHRyaWJ1dGUoYXR0Lk5hbWUsIGF0dC5WYWx1ZSk7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIGl0ZW0uVG9wTm9kZS5Jbm5lclhtbCA9IHBpYy5Ub3BOb2RlLklubmVyWG1sOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICBwcml2YXRlIHZvaWQgQ29weVRleHQoRXhjZWxIZWFkZXJGb290ZXJUZXh0IGZyb20sIEV4Y2VsSGVhZGVyRm9vdGVyVGV4dCB0bykKICAgICAgICB7CiAgICAgICAgICAgIGlmIChmcm9tID09IG51bGwpIHJldHVybjsKICAgICAgICAgICAgdG8uTGVmdEFsaWduZWRUZXh0PWZyb20uTGVmdEFsaWduZWRUZXh0OwogICAgICAgICAgICB0by5DZW50ZXJlZFRleHQgPSBmcm9tLkNlbnRlcmVkVGV4dDsKICAgICAgICAgICAgdG8uUmlnaHRBbGlnbmVkVGV4dCA9IGZyb20uUmlnaHRBbGlnbmVkVGV4dDsKICAgICAgICB9CiAgICAgICAgcHJpdmF0ZSB2b2lkIENsb25lQ2VsbHMoRXhjZWxXb3Jrc2hlZXQgQ29weSwgRXhjZWxXb3Jrc2hlZXQgYWRkZWQpCiAgICAgICAgewogICAgICAgICAgICBib29sIHNhbWVXb3JrYm9vaz0oQ29weS5Xb3JrYm9vayA9PSBfcGNrLldvcmtib29rKTsKCiAgICAgICAgICAgIGJvb2wgZG9BZGp1c3QgPSBfcGNrLkRvQWRqdXN0RHJhd2luZ3M7CiAgICAgICAgICAgIF9wY2suRG9BZGp1c3REcmF3aW5ncyA9IGZhbHNlOwogICAgICAgICAgICBhZGRlZC5NZXJnZWRDZWxscy5MaXN0LkFkZFJhbmdlKENvcHkuTWVyZ2VkQ2VsbHMuTGlzdCk7CiAgICAgICAgICAgIC8vRm9ybXVsYXMKICAgICAgICAgICAgLy9mb3JlYWNoIChJUmFuZ2VJRCBmIGluIENvcHkuX2Zvcm11bGFDZWxscykKICAgICAgICAgICAgLy97CiAgICAgICAgICAgIC8vICAgIGFkZGVkLl9mb3JtdWxhQ2VsbHMuQWRkKGYpOwogICAgICAgICAgICAvL30KICAgICAgICAgICAgLy9TaGFyZWQgRm9ybXVsYXMKICAgICAgICAgICAgZm9yZWFjaCAoaW50IGtleSBpbiBDb3B5Ll9zaGFyZWRGb3JtdWxhcy5LZXlzKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBhZGRlZC5fc2hhcmVkRm9ybXVsYXMuQWRkKGtleSwgQ29weS5fc2hhcmVkRm9ybXVsYXNba2V5XSk7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgCiAgICAgICAgICAgIERpY3Rpb25hcnk8aW50LCBpbnQ+IHN0eWxlQ2FzaGUgPSBuZXcgRGljdGlvbmFyeTxpbnQsIGludD4oKTsKICAgICAgICAgICAgLy9DZWxscwogICAgICAgICAgICBpbnQgcm93LGNvbDsKICAgICAgICAgICAgdmFyIHZhbCA9IG5ldyBDZWxsc1N0b3JlRW51bWVyYXRvcjxvYmplY3Q+KENvcHkuX3ZhbHVlcyk7CiAgICAgICAgICAgIC8vb2JqZWN0IGY9bnVsbDsKICAgICAgICAgICAgLy9mb3JlYWNoICh2YXIgYWRkciBpbiB2YWwpCiAgICAgICAgICAgIHdoaWxlKHZhbC5OZXh0KCkpCiAgICAgICAgICAgIHsgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAvL3Jvdz0oaW50KWFkZHI+PjMyOwogICAgICAgICAgICAgICAgLy9jb2w9KGludClhZGRyJjMyOwogICAgICAgICAgICAgICAgcm93ID0gdmFsLlJvdzsKICAgICAgICAgICAgICAgIGNvbCA9IHZhbC5Db2x1bW47CiAgICAgICAgICAgICAgICAvL2FkZGVkLl9jZWxscy5BZGQoY2VsbC5DbG9uZShhZGRlZCkpOwogICAgICAgICAgICAgICAgaW50IHN0eWxlSUQ9MDsKICAgICAgICAgICAgICAgIGlmIChyb3cgPT0gMCkgLy9Db2x1bW4KICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICB2YXIgYyA9IENvcHkuX3ZhbHVlcy5HZXRWYWx1ZShyb3csIGNvbCkgYXMgRXhjZWxDb2x1bW47CiAgICAgICAgICAgICAgICAgICAgaWYgKGMgIT0gbnVsbCkKICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgIHZhciBjbG9uZSA9IGMuQ2xvbmUoYWRkZWQsIGMuQ29sdW1uTWluKTsKICAgICAgICAgICAgICAgICAgICAgICAgY2xvbmUuU3R5bGVJRCA9IGMuU3R5bGVJRDsKICAgICAgICAgICAgICAgICAgICAgICAgYWRkZWQuX3ZhbHVlcy5TZXRWYWx1ZShyb3csIGNvbCwgY2xvbmUpOwogICAgICAgICAgICAgICAgICAgICAgICBzdHlsZUlEID0gYy5TdHlsZUlEOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGVsc2UgaWYgKGNvbCA9PSAwKSAvL1JvdwogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIHZhciByPUNvcHkuUm93KHJvdyk7CiAgICAgICAgICAgICAgICAgICAgaWYgKHIgIT0gbnVsbCkKICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgIHIuQ2xvbmUoYWRkZWQpOwogICAgICAgICAgICAgICAgICAgICAgICBzdHlsZUlEID0gci5TdHlsZUlEOwogICAgICAgICAgICAgICAgICAgICAgICAvL2FkZGVkLl92YWx1ZXMuU2V0VmFsdWUocm93LCBjb2wsIHIuQ2xvbmUoYWRkZWQpKTsgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBlbHNlCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICBzdHlsZUlEID0gQ29weVZhbHVlcyhDb3B5LCBhZGRlZCwgcm93LCBjb2wpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgaWYgKCFzYW1lV29ya2Jvb2spCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgaWYgKHN0eWxlQ2FzaGUuQ29udGFpbnNLZXkoc3R5bGVJRCkpCiAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICBhZGRlZC5fc3R5bGVzLlNldFZhbHVlKHJvdywgY29sLCBzdHlsZUNhc2hlW3N0eWxlSURdKTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgZWxzZQogICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgdmFyIHMgPSBhZGRlZC5Xb3JrYm9vay5TdHlsZXMuQ2xvbmVTdHlsZShDb3B5Lldvcmtib29rLlN0eWxlcywgc3R5bGVJRCk7CiAgICAgICAgICAgICAgICAgICAgICAgIHN0eWxlQ2FzaGUuQWRkKHN0eWxlSUQsIHMpOwogICAgICAgICAgICAgICAgICAgICAgICBhZGRlZC5fc3R5bGVzLlNldFZhbHVlKHJvdywgY29sLCBzKTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICAgICAgYWRkZWQuX3BhY2thZ2UuRG9BZGp1c3REcmF3aW5ncyA9IGRvQWRqdXN0OwogICAgICAgIH0KCiAgICAgICAgcHJpdmF0ZSBpbnQgQ29weVZhbHVlcyhFeGNlbFdvcmtzaGVldCBDb3B5LCBFeGNlbFdvcmtzaGVldCBhZGRlZCwgaW50IHJvdywgaW50IGNvbCkKICAgICAgICB7CiAgICAgICAgICAgIGFkZGVkLl92YWx1ZXMuU2V0VmFsdWUocm93LCBjb2wsIENvcHkuX3ZhbHVlcy5HZXRWYWx1ZShyb3csIGNvbCkpOwogICAgICAgICAgICB2YXIgdCA9IENvcHkuX3R5cGVzLkdldFZhbHVlKHJvdywgY29sKTsKICAgICAgICAgICAgaWYgKHQgIT0gbnVsbCkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgYWRkZWQuX3R5cGVzLlNldFZhbHVlKHJvdywgY29sLCB0KTsKICAgICAgICAgICAgfQogICAgICAgICAgICBieXRlIGZsPTA7CiAgICAgICAgICAgIGlmIChDb3B5Ll9mbGFncy5FeGlzdHMocm93LGNvbCxyZWYgZmwpKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBhZGRlZC5fZmxhZ3MuU2V0VmFsdWUocm93LCBjb2wsIGZsKTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgdmFyIHYgPSBDb3B5Ll9mb3JtdWxhcy5HZXRWYWx1ZShyb3csIGNvbCk7CiAgICAgICAgICAgIGlmICh2ICE9IG51bGwpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIGFkZGVkLlNldEZvcm11bGEocm93LCBjb2wsIHYpOwogICAgICAgICAgICB9CiAgICAgICAgICAgIHZhciBzID0gQ29weS5fc3R5bGVzLkdldFZhbHVlKHJvdywgY29sKTsKICAgICAgICAgICAgaWYgKHMgIT0gMCkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgYWRkZWQuX3N0eWxlcy5TZXRWYWx1ZShyb3csIGNvbCwgcyk7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgdmFyIGYgPSBDb3B5Ll9mb3JtdWxhcy5HZXRWYWx1ZShyb3csIGNvbCk7CiAgICAgICAgICAgIGlmIChmICE9IG51bGwpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIGFkZGVkLl9mb3JtdWxhcy5TZXRWYWx1ZShyb3csIGNvbCwgZik7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgcmV0dXJuIHM7CiAgICAgICAgfQoKICAgICAgICBwcml2YXRlIHZvaWQgQ29weUNvbW1lbnQoRXhjZWxXb3Jrc2hlZXQgQ29weSwgRXhjZWxXb3Jrc2hlZXQgd29ya1NoZWV0KQogICAgICAgIHsgICAgICAgICAgICAKICAgICAgICAgICAgLy9GaXJzdCBjb3B5IHRoZSBkcmF3aW5nIFhNTAogICAgICAgICAgICBzdHJpbmcgeG1sID0gQ29weS5Db21tZW50cy5Db21tZW50WG1sLklubmVyWG1sOwogICAgICAgICAgICB2YXIgdXJpQ29tbWVudCA9IG5ldyBVcmkoc3RyaW5nLkZvcm1hdCgiL3hsL2NvbW1lbnRzezB9LnhtbCIsIHdvcmtTaGVldC5TaGVldElEKSwgVXJpS2luZC5SZWxhdGl2ZSk7CiAgICAgICAgICAgIGlmIChfcGNrLlBhY2thZ2UuUGFydEV4aXN0cyh1cmlDb21tZW50KSkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgdXJpQ29tbWVudCA9IFhtbEhlbHBlci5HZXROZXdVcmkoX3Bjay5QYWNrYWdlLCAiL3hsL2RyYXdpbmdzL3ZtbGRyYXdpbmd7MH0udm1sIik7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIHZhciBwYXJ0ID0gX3Bjay5QYWNrYWdlLkNyZWF0ZVBhcnQodXJpQ29tbWVudCwgImFwcGxpY2F0aW9uL3ZuZC5vcGVueG1sZm9ybWF0cy1vZmZpY2Vkb2N1bWVudC5zcHJlYWRzaGVldG1sLmNvbW1lbnRzK3htbCIsIF9wY2suQ29tcHJlc3Npb24pOwoKICAgICAgICAgICAgU3RyZWFtV3JpdGVyIHN0cmVhbURyYXdpbmcgPSBuZXcgU3RyZWFtV3JpdGVyKHBhcnQuR2V0U3RyZWFtKEZpbGVNb2RlLkNyZWF0ZSwgRmlsZUFjY2Vzcy5Xcml0ZSkpOwogICAgICAgICAgICBzdHJlYW1EcmF3aW5nLldyaXRlKHhtbCk7CiAgICAgICAgICAgIC8vc3RyZWFtRHJhd2luZy5DbG9zZSgpOwogICAgICAgICAgICBzdHJlYW1EcmF3aW5nLkZsdXNoKCk7CgogICAgICAgICAgICAvL0FkZCB0aGUgcmVsYXRpb25zaGlwIElEIHRvIHRoZSB3b3Jrc2hlZXQgeG1sLgogICAgICAgICAgICB2YXIgY29tbWVudFJlbGF0aW9uID0gd29ya1NoZWV0LlBhcnQuQ3JlYXRlUmVsYXRpb25zaGlwKFVyaUhlbHBlci5HZXRSZWxhdGl2ZVVyaSh3b3JrU2hlZXQuV29ya3NoZWV0VXJpLHVyaUNvbW1lbnQpLCBQYWNrYWdpbmcuVGFyZ2V0TW9kZS5JbnRlcm5hbCwgRXhjZWxQYWNrYWdlLnNjaGVtYVJlbGF0aW9uc2hpcHMgKyAiL2NvbW1lbnRzIik7CgogICAgICAgICAgICB4bWwgPSBDb3B5LlZtbERyYXdpbmdzQ29tbWVudHMuVm1sRHJhd2luZ1htbC5Jbm5lclhtbDsKCiAgICAgICAgICAgIHZhciB1cmlWbWwgPSBuZXcgVXJpKHN0cmluZy5Gb3JtYXQoIi94bC9kcmF3aW5ncy92bWxkcmF3aW5nezB9LnZtbCIsIHdvcmtTaGVldC5TaGVldElEKSwgVXJpS2luZC5SZWxhdGl2ZSk7CiAgICAgICAgICAgIGlmIChfcGNrLlBhY2thZ2UuUGFydEV4aXN0cyh1cmlWbWwpKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICB1cmlWbWwgPSBYbWxIZWxwZXIuR2V0TmV3VXJpKF9wY2suUGFja2FnZSwgIi94bC9kcmF3aW5ncy92bWxkcmF3aW5nezB9LnZtbCIpOwogICAgICAgICAgICB9CgogICAgICAgICAgICB2YXIgdm1sUGFydCA9IF9wY2suUGFja2FnZS5DcmVhdGVQYXJ0KHVyaVZtbCwgImFwcGxpY2F0aW9uL3ZuZC5vcGVueG1sZm9ybWF0cy1vZmZpY2Vkb2N1bWVudC52bWxEcmF3aW5nIiwgX3Bjay5Db21wcmVzc2lvbik7CiAgICAgICAgICAgIFN0cmVhbVdyaXRlciBzdHJlYW1WbWwgPSBuZXcgU3RyZWFtV3JpdGVyKHZtbFBhcnQuR2V0U3RyZWFtKEZpbGVNb2RlLkNyZWF0ZSwgRmlsZUFjY2Vzcy5Xcml0ZSkpOwogICAgICAgICAgICBzdHJlYW1WbWwuV3JpdGUoeG1sKTsKICAgICAgICAgICAgLy9zdHJlYW1WbWwuQ2xvc2UoKTsKICAgICAgICAgICAgc3RyZWFtVm1sLkZsdXNoKCk7CgogICAgICAgICAgICB2YXIgbmV3Vm1sUmVsID0gd29ya1NoZWV0LlBhcnQuQ3JlYXRlUmVsYXRpb25zaGlwKFVyaUhlbHBlci5HZXRSZWxhdGl2ZVVyaSh3b3JrU2hlZXQuV29ya3NoZWV0VXJpLHVyaVZtbCksIFBhY2thZ2luZy5UYXJnZXRNb2RlLkludGVybmFsLCBFeGNlbFBhY2thZ2Uuc2NoZW1hUmVsYXRpb25zaGlwcyArICIvdm1sRHJhd2luZyIpOwoKICAgICAgICAgICAgLy9BZGQgdGhlIHJlbGF0aW9uc2hpcCBJRCB0byB0aGUgd29ya3NoZWV0IHhtbC4KICAgICAgICAgICAgWG1sRWxlbWVudCBlID0gd29ya1NoZWV0LldvcmtzaGVldFhtbC5TZWxlY3RTaW5nbGVOb2RlKCIvL2Q6bGVnYWN5RHJhd2luZyIsIF9uYW1lc3BhY2VNYW5hZ2VyKSBhcyBYbWxFbGVtZW50OwogICAgICAgICAgICBpZiAoZSA9PSBudWxsKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICB3b3JrU2hlZXQuQ3JlYXRlTm9kZSgiZDpsZWdhY3lEcmF3aW5nIik7CiAgICAgICAgICAgICAgICBlID0gd29ya1NoZWV0LldvcmtzaGVldFhtbC5TZWxlY3RTaW5nbGVOb2RlKCIvL2Q6bGVnYWN5RHJhd2luZyIsIF9uYW1lc3BhY2VNYW5hZ2VyKSBhcyBYbWxFbGVtZW50OwogICAgICAgICAgICB9CgogICAgICAgICAgICBlLlNldEF0dHJpYnV0ZSgiaWQiLCBFeGNlbFBhY2thZ2Uuc2NoZW1hUmVsYXRpb25zaGlwcywgbmV3Vm1sUmVsLklkKTsKICAgICAgICB9CiAgICAgICAgcHJpdmF0ZSB2b2lkIENvcHlEcmF3aW5nKEV4Y2VsV29ya3NoZWV0IENvcHksIEV4Y2VsV29ya3NoZWV0IHdvcmtTaGVldC8qLCBQYWNrYWdlUmVsYXRpb25zaGlwIHIqLykKICAgICAgICB7CiAgICAgICAgICAgIAogICAgICAgICAgICAvL0NoZWNrIGlmIHRoZSB3b3Jrc2hlZXQgaGFzIGRyYXdpbmdzCiAgICAgICAgICAgIC8vaWYoX3hsUGFja2FnZS5QYWNrYWdlLlBhcnRFeGlzdHMoci5UYXJnZXRVcmkpKQogICAgICAgICAgICAvL3sKICAgICAgICAgICAgICAgIC8vRmlyc3QgY29weSB0aGUgZHJhd2luZyBYTUwgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICBzdHJpbmcgeG1sID0gQ29weS5EcmF3aW5ncy5EcmF3aW5nWG1sLk91dGVyWG1sOyAgICAgICAgICAgIAogICAgICAgICAgICAgICAgdmFyIHVyaURyYXc9bmV3IFVyaShzdHJpbmcuRm9ybWF0KCIveGwvZHJhd2luZ3MvZHJhd2luZ3swfS54bWwiLCB3b3JrU2hlZXQuU2hlZXRJRCksICBVcmlLaW5kLlJlbGF0aXZlKTsKICAgICAgICAgICAgICAgIHZhciBwYXJ0PSBfcGNrLlBhY2thZ2UuQ3JlYXRlUGFydCh1cmlEcmF3LCJhcHBsaWNhdGlvbi92bmQub3BlbnhtbGZvcm1hdHMtb2ZmaWNlZG9jdW1lbnQuZHJhd2luZyt4bWwiLCBfcGNrLkNvbXByZXNzaW9uKTsKICAgICAgICAgICAgICAgIFN0cmVhbVdyaXRlciBzdHJlYW1EcmF3aW5nID0gbmV3IFN0cmVhbVdyaXRlcihwYXJ0LkdldFN0cmVhbShGaWxlTW9kZS5DcmVhdGUsIEZpbGVBY2Nlc3MuV3JpdGUpKTsKICAgICAgICAgICAgICAgIHN0cmVhbURyYXdpbmcuV3JpdGUoeG1sKTsKICAgICAgICAgICAgICAgIC8vc3RyZWFtRHJhd2luZy5DbG9zZSgpOwogICAgICAgICAgICAgICAgc3RyZWFtRHJhd2luZy5GbHVzaCgpOwoKICAgICAgICAgICAgICAgIFhtbERvY3VtZW50IGRyYXdYbWwgPSBuZXcgWG1sRG9jdW1lbnQoKTsKICAgICAgICAgICAgICAgIGRyYXdYbWwuTG9hZFhtbCh4bWwpOwogICAgICAgICAgICAgICAgLy9BZGQgdGhlIHJlbGF0aW9uc2hpcCBJRCB0byB0aGUgd29ya3NoZWV0IHhtbC4KICAgICAgICAgICAgICAgIHZhciBkcmF3UmVsYXRpb24gPSB3b3JrU2hlZXQuUGFydC5DcmVhdGVSZWxhdGlvbnNoaXAoVXJpSGVscGVyLkdldFJlbGF0aXZlVXJpKHdvcmtTaGVldC5Xb3Jrc2hlZXRVcmksdXJpRHJhdyksIFBhY2thZ2luZy5UYXJnZXRNb2RlLkludGVybmFsLCBFeGNlbFBhY2thZ2Uuc2NoZW1hUmVsYXRpb25zaGlwcyArICIvZHJhd2luZyIpOwogICAgICAgICAgICAgICAgWG1sRWxlbWVudCBlID0gd29ya1NoZWV0LldvcmtzaGVldFhtbC5TZWxlY3RTaW5nbGVOb2RlKCIvL2Q6ZHJhd2luZyIsIF9uYW1lc3BhY2VNYW5hZ2VyKSBhcyBYbWxFbGVtZW50OwogICAgICAgICAgICAgICAgZS5TZXRBdHRyaWJ1dGUoImlkIixFeGNlbFBhY2thZ2Uuc2NoZW1hUmVsYXRpb25zaGlwcywgZHJhd1JlbGF0aW9uLklkKTsKCiAgICAgICAgICAgICAgICBmb3JlYWNoIChFeGNlbERyYXdpbmcgZHJhdyBpbiBDb3B5LkRyYXdpbmdzKQogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIGlmIChkcmF3IGlzIEV4Y2VsQ2hhcnQpCiAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICBFeGNlbENoYXJ0IGNoYXJ0ID0gZHJhdyBhcyBFeGNlbENoYXJ0OwogICAgICAgICAgICAgICAgICAgICAgICB4bWwgPSBjaGFydC5DaGFydFhtbC5Jbm5lclhtbDsKCiAgICAgICAgICAgICAgICAgICAgICAgIHZhciBVcmlDaGFydCA9IFhtbEhlbHBlci5HZXROZXdVcmkoX3Bjay5QYWNrYWdlLCAiL3hsL2NoYXJ0cy9jaGFydHswfS54bWwiKTsKICAgICAgICAgICAgICAgICAgICAgICAgdmFyIGNoYXJ0UGFydCA9IF9wY2suUGFja2FnZS5DcmVhdGVQYXJ0KFVyaUNoYXJ0LCAiYXBwbGljYXRpb24vdm5kLm9wZW54bWxmb3JtYXRzLW9mZmljZWRvY3VtZW50LmRyYXdpbmdtbC5jaGFydCt4bWwiLCBfcGNrLkNvbXByZXNzaW9uKTsKICAgICAgICAgICAgICAgICAgICAgICAgU3RyZWFtV3JpdGVyIHN0cmVhbUNoYXJ0ID0gbmV3IFN0cmVhbVdyaXRlcihjaGFydFBhcnQuR2V0U3RyZWFtKEZpbGVNb2RlLkNyZWF0ZSwgRmlsZUFjY2Vzcy5Xcml0ZSkpOwogICAgICAgICAgICAgICAgICAgICAgICBzdHJlYW1DaGFydC5Xcml0ZSh4bWwpOwogICAgICAgICAgICAgICAgICAgICAgICAvL3N0cmVhbUNoYXJ0LkNsb3NlKCk7CiAgICAgICAgICAgICAgICAgICAgICAgIHN0cmVhbUNoYXJ0LkZsdXNoKCk7CiAgICAgICAgICAgICAgICAgICAgICAgIC8vTm93IGNyZWF0ZSB0aGUgbmV3IHJlbGF0aW9uc2hpcCB0byB0aGUgY29waWVkIGNoYXJ0IHhtbAogICAgICAgICAgICAgICAgICAgICAgICB2YXIgcHJldlJlbElEPWRyYXcuVG9wTm9kZS5TZWxlY3RTaW5nbGVOb2RlKCJ4ZHI6Z3JhcGhpY0ZyYW1lL2E6Z3JhcGhpYy9hOmdyYXBoaWNEYXRhL2M6Y2hhcnQvQHI6aWQiLCBDb3B5LkRyYXdpbmdzLk5hbWVTcGFjZU1hbmFnZXIpLlZhbHVlOwogICAgICAgICAgICAgICAgICAgICAgICB2YXIgcmVsID0gcGFydC5DcmVhdGVSZWxhdGlvbnNoaXAoVXJpSGVscGVyLkdldFJlbGF0aXZlVXJpKHVyaURyYXcsVXJpQ2hhcnQpLCBQYWNrYWdpbmcuVGFyZ2V0TW9kZS5JbnRlcm5hbCwgRXhjZWxQYWNrYWdlLnNjaGVtYVJlbGF0aW9uc2hpcHMgKyAiL2NoYXJ0Iik7CiAgICAgICAgICAgICAgICAgICAgICAgIFhtbEF0dHJpYnV0ZSByZWxBdHQgPSBkcmF3WG1sLlNlbGVjdFNpbmdsZU5vZGUoc3RyaW5nLkZvcm1hdCgiLy9jOmNoYXJ0L0ByOmlkWy49J3swfSddIiwgcHJldlJlbElEKSwgQ29weS5EcmF3aW5ncy5OYW1lU3BhY2VNYW5hZ2VyKSBhcyBYbWxBdHRyaWJ1dGU7CiAgICAgICAgICAgICAgICAgICAgICAgIHJlbEF0dC5WYWx1ZT1yZWwuSWQ7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIGVsc2UgaWYgKGRyYXcgaXMgRXhjZWxQaWN0dXJlKQogICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgRXhjZWxQaWN0dXJlIHBpYyA9IGRyYXcgYXMgRXhjZWxQaWN0dXJlOwogICAgICAgICAgICAgICAgICAgICAgICB2YXIgdXJpID0gcGljLlVyaVBpYzsKICAgICAgICAgICAgICAgICAgICAgICAgaWYoIXdvcmtTaGVldC5Xb3JrYm9vay5fcGFja2FnZS5QYWNrYWdlLlBhcnRFeGlzdHModXJpKSkKICAgICAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgdmFyIHBpY1BhcnQgPSB3b3JrU2hlZXQuV29ya2Jvb2suX3BhY2thZ2UuUGFja2FnZS5DcmVhdGVQYXJ0KHVyaSwgcGljLkNvbnRlbnRUeXBlLCBDb21wcmVzc2lvbkxldmVsLk5vbmUpOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgcGljLkltYWdlLlNhdmUocGljUGFydC5HZXRTdHJlYW0oRmlsZU1vZGUuQ3JlYXRlLCBGaWxlQWNjZXNzLldyaXRlKSwgcGljLkltYWdlRm9ybWF0KTsKICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgdmFyIHJlbCA9IHBhcnQuQ3JlYXRlUmVsYXRpb25zaGlwKFVyaUhlbHBlci5HZXRSZWxhdGl2ZVVyaSh3b3JrU2hlZXQuV29ya3NoZWV0VXJpLCB1cmkpLCBQYWNrYWdpbmcuVGFyZ2V0TW9kZS5JbnRlcm5hbCwgRXhjZWxQYWNrYWdlLnNjaGVtYVJlbGF0aW9uc2hpcHMgKyAiL2ltYWdlIik7CiAgICAgICAgICAgICAgICAgICAgICAgIC8vRml4ZXMgcHJvYmxlbSB3aXRoIGludmFsaWQgaW1hZ2Ugd2hlbiB0aGUgc2FtZSBpbWFnZSBpcyB1c2VkIG1vcmUgdGhhbiBvbmNlLgogICAgICAgICAgICAgICAgICAgICAgICBYbWxOb2RlIHJlbEF0dCA9CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBkcmF3WG1sLlNlbGVjdFNpbmdsZU5vZGUoCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc3RyaW5nLkZvcm1hdCgKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIi8veGRyOnBpYy94ZHI6bnZQaWNQci94ZHI6Y052UHIvQG5hbWVbLj0nezB9J10vLi4vLi4vLi4veGRyOmJsaXBGaWxsL2E6YmxpcC9AcjplbWJlZCIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBpYy5OYW1lKSwgQ29weS5EcmF3aW5ncy5OYW1lU3BhY2VNYW5hZ2VyKTsKICAgICAgICAgICAgICAgICAgICAgICAgaWYocmVsQXR0IT1udWxsKQogICAgICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICByZWxBdHQuVmFsdWUgPSByZWwuSWQ7CiAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgaWYgKF9wY2suX2ltYWdlcy5Db250YWluc0tleShwaWMuSW1hZ2VIYXNoKSkKICAgICAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgX3Bjay5faW1hZ2VzW3BpYy5JbWFnZUhhc2hdLlJlZkNvdW50Kys7CiAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAvL3Jld3JpdGUgdGhlIGRyYXdpbmcgeG1sIHdpdGggdGhlIG5ldyByZWxJRCdzCiAgICAgICAgICAgICAgICBzdHJlYW1EcmF3aW5nID0gbmV3IFN0cmVhbVdyaXRlcihwYXJ0LkdldFN0cmVhbShGaWxlTW9kZS5DcmVhdGUsIEZpbGVBY2Nlc3MuV3JpdGUpKTsKICAgICAgICAgICAgICAgIHN0cmVhbURyYXdpbmcuV3JpdGUoZHJhd1htbC5PdXRlclhtbCk7CiAgICAgICAgICAgICAgIC8vIHN0cmVhbURyYXdpbmcuQ2xvc2UoKTsKICAgICAgICAgICAgICAgIHN0cmVhbURyYXdpbmcuRmx1c2goKTsKCiAgICAgICAgICAgIC8vfQogICAgICAgIH0KCgkJcHJpdmF0ZSB2b2lkIENvcHlWbWxEcmF3aW5nKEV4Y2VsV29ya3NoZWV0IG9yaWdTaGVldCwgRXhjZWxXb3Jrc2hlZXQgbmV3U2hlZXQpCgkJewoJCQl2YXIgeG1sID0gb3JpZ1NoZWV0LlZtbERyYXdpbmdzQ29tbWVudHMuVm1sRHJhd2luZ1htbC5PdXRlclhtbDsKCQkJdmFyIHZtbFVyaSA9IG5ldyBVcmkoc3RyaW5nLkZvcm1hdCgiL3hsL2RyYXdpbmdzL3ZtbERyYXdpbmd7MH0udm1sIiwgbmV3U2hlZXQuU2hlZXRJRCksIFVyaUtpbmQuUmVsYXRpdmUpOwoJCQl2YXIgcGFydCA9IF9wY2suUGFja2FnZS5DcmVhdGVQYXJ0KHZtbFVyaSwgImFwcGxpY2F0aW9uL3ZuZC5vcGVueG1sZm9ybWF0cy1vZmZpY2Vkb2N1bWVudC52bWxEcmF3aW5nIiwgX3Bjay5Db21wcmVzc2lvbik7CgkJCXVzaW5nICh2YXIgc3RyZWFtRHJhd2luZyA9IG5ldyBTdHJlYW1Xcml0ZXIocGFydC5HZXRTdHJlYW0oRmlsZU1vZGUuQ3JlYXRlLCBGaWxlQWNjZXNzLldyaXRlKSkpCgkJCXsKCQkJCXN0cmVhbURyYXdpbmcuV3JpdGUoeG1sKTsKICAgICAgICAgICAgICAgIHN0cmVhbURyYXdpbmcuRmx1c2goKTsKICAgICAgICAgICAgfQoJCQkKICAgICAgICAgICAgLy9BZGQgdGhlIHJlbGF0aW9uc2hpcCBJRCB0byB0aGUgd29ya3NoZWV0IHhtbC4KCQkJdmFyIHZtbFJlbGF0aW9uID0gbmV3U2hlZXQuUGFydC5DcmVhdGVSZWxhdGlvbnNoaXAoVXJpSGVscGVyLkdldFJlbGF0aXZlVXJpKG5ld1NoZWV0LldvcmtzaGVldFVyaSx2bWxVcmkpLCBQYWNrYWdpbmcuVGFyZ2V0TW9kZS5JbnRlcm5hbCwgRXhjZWxQYWNrYWdlLnNjaGVtYVJlbGF0aW9uc2hpcHMgKyAiL3ZtbERyYXdpbmciKTsKCQkJdmFyIGUgPSBuZXdTaGVldC5Xb3Jrc2hlZXRYbWwuU2VsZWN0U2luZ2xlTm9kZSgiLy9kOmxlZ2FjeURyYXdpbmciLCBfbmFtZXNwYWNlTWFuYWdlcikgYXMgWG1sRWxlbWVudDsKCQkJaWYgKGUgPT0gbnVsbCkKCQkJewoJCQkJZSA9IG5ld1NoZWV0LldvcmtzaGVldFhtbC5DcmVhdGVOb2RlKFhtbE5vZGVUeXBlLkVudGl0eSwgIi8vZDpsZWdhY3lEcmF3aW5nIiwgX25hbWVzcGFjZU1hbmFnZXIuTG9va3VwTmFtZXNwYWNlKCJkIikpIGFzIFhtbEVsZW1lbnQ7CgkJCX0KCQkJaWYgKGUgIT0gbnVsbCkKCQkJewoJCQkJZS5TZXRBdHRyaWJ1dGUoImlkIiwgRXhjZWxQYWNrYWdlLnNjaGVtYVJlbGF0aW9uc2hpcHMsIHZtbFJlbGF0aW9uLklkKTsKCQkJfQoJCX0KCgkJc3RyaW5nIENyZWF0ZVdvcmtib29rUmVsKHN0cmluZyBOYW1lLCBpbnQgc2hlZXRJRCwgVXJpIHVyaVdvcmtzaGVldCwgYm9vbCBpc0NoYXJ0KQogICAgICAgIHsKICAgICAgICAgICAgLy9DcmVhdGUgdGhlIHJlbGF0aW9uc2hpcCBiZXR3ZWVuIHRoZSB3b3JrYm9vayBhbmQgdGhlIG5ldyB3b3Jrc2hlZXQKICAgICAgICAgICAgdmFyIHJlbCA9IF9wY2suV29ya2Jvb2suUGFydC5DcmVhdGVSZWxhdGlvbnNoaXAoVXJpSGVscGVyLkdldFJlbGF0aXZlVXJpKF9wY2suV29ya2Jvb2suV29ya2Jvb2tVcmksIHVyaVdvcmtzaGVldCksIFBhY2thZ2luZy5UYXJnZXRNb2RlLkludGVybmFsLCBFeGNlbFBhY2thZ2Uuc2NoZW1hUmVsYXRpb25zaGlwcyArICIvIiArIChpc0NoYXJ0ID8gImNoYXJ0c2hlZXQiIDogIndvcmtzaGVldCIpKTsKICAgICAgICAgICAgX3Bjay5QYWNrYWdlLkZsdXNoKCk7CgogICAgICAgICAgICAvL0NyZWF0ZSB0aGUgbmV3IHNoZWV0IG5vZGUKICAgICAgICAgICAgWG1sRWxlbWVudCB3b3Jrc2hlZXROb2RlID0gX3Bjay5Xb3JrYm9vay5Xb3JrYm9va1htbC5DcmVhdGVFbGVtZW50KCJzaGVldCIsIEV4Y2VsUGFja2FnZS5zY2hlbWFNYWluKTsKICAgICAgICAgICAgd29ya3NoZWV0Tm9kZS5TZXRBdHRyaWJ1dGUoIm5hbWUiLCBOYW1lKTsKICAgICAgICAgICAgd29ya3NoZWV0Tm9kZS5TZXRBdHRyaWJ1dGUoInNoZWV0SWQiLCBzaGVldElELlRvU3RyaW5nKCkpOwogICAgICAgICAgICB3b3Jrc2hlZXROb2RlLlNldEF0dHJpYnV0ZSgiaWQiLCBFeGNlbFBhY2thZ2Uuc2NoZW1hUmVsYXRpb25zaGlwcywgcmVsLklkKTsKCiAgICAgICAgICAgIFRvcE5vZGUuQXBwZW5kQ2hpbGQod29ya3NoZWV0Tm9kZSk7CiAgICAgICAgICAgIHJldHVybiByZWwuSWQ7CiAgICAgICAgfQogICAgICAgIHByaXZhdGUgdm9pZCBHZXRTaGVldFVSSShyZWYgc3RyaW5nIE5hbWUsIG91dCBpbnQgc2hlZXRJRCwgb3V0IFVyaSB1cmlXb3Jrc2hlZXQsIGJvb2wgaXNDaGFydCkKICAgICAgICB7CiAgICAgICAgICAgIE5hbWUgPSBWYWxpZGF0ZUZpeFNoZWV0TmFtZShOYW1lKTsKCiAgICAgICAgICAgIC8vRmlyc3QgZmluZCBtYXhpbXVtIGV4aXN0aW5nIHNoZWV0SUQKICAgICAgICAgICAgc2hlZXRJRCA9IDA7CiAgICAgICAgICAgIGZvcmVhY2godmFyIHdzIGluIHRoaXMpCiAgICAgICAgICAgIHsgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICBpZiAod3MuU2hlZXRJRCA+IHNoZWV0SUQpCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgc2hlZXRJRCA9IHdzLlNoZWV0SUQ7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICAgICAgLy8gd2Ugbm93IGhhdmUgdGhlIG1heCBleGlzdGluZyB2YWx1ZXMsIHNvIGFkZCBvbmUKICAgICAgICAgICAgc2hlZXRJRCsrOwoKICAgICAgICAgICAgLy8gYWRkIHRoZSBuZXcgd29ya3NoZWV0IHRvIHRoZSBwYWNrYWdlCiAgICAgICAgICAgIGlmIChpc0NoYXJ0KQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICB1cmlXb3Jrc2hlZXQgPSBuZXcgVXJpKCIveGwvY2hhcnRzaGVldHMvY2hhcnRzaGVldCIgKyBzaGVldElELlRvU3RyaW5nKCkgKyAiLnhtbCIsIFVyaUtpbmQuUmVsYXRpdmUpOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGVsc2UKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgdXJpV29ya3NoZWV0ID0gbmV3IFVyaSgiL3hsL3dvcmtzaGVldHMvc2hlZXQiICsgc2hlZXRJRC5Ub1N0cmluZygpICsgIi54bWwiLCBVcmlLaW5kLlJlbGF0aXZlKTsKICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgaW50ZXJuYWwgc3RyaW5nIFZhbGlkYXRlRml4U2hlZXROYW1lKHN0cmluZyBOYW1lKQogICAgICAgIHsKICAgICAgICAgICAgLy9yZW1vdmUgaW52YWxpZCBjaGFyYWN0ZXJzCiAgICAgICAgICAgIGlmIChWYWxpZGF0ZU5hbWUoTmFtZSkpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIGlmIChOYW1lLkluZGV4T2YoJzonKSA+IC0xKSBOYW1lID0gTmFtZS5SZXBsYWNlKCI6IiwgIiAiKTsKICAgICAgICAgICAgICAgIGlmIChOYW1lLkluZGV4T2YoJy8nKSA+IC0xKSBOYW1lID0gTmFtZS5SZXBsYWNlKCIvIiwgIiAiKTsKICAgICAgICAgICAgICAgIGlmIChOYW1lLkluZGV4T2YoJ1xcJykgPiAtMSkgTmFtZSA9IE5hbWUuUmVwbGFjZSgiXFwiLCAiICIpOwogICAgICAgICAgICAgICAgaWYgKE5hbWUuSW5kZXhPZignPycpID4gLTEpIE5hbWUgPSBOYW1lLlJlcGxhY2UoIj8iLCAiICIpOwogICAgICAgICAgICAgICAgaWYgKE5hbWUuSW5kZXhPZignWycpID4gLTEpIE5hbWUgPSBOYW1lLlJlcGxhY2UoIlsiLCAiICIpOwogICAgICAgICAgICAgICAgaWYgKE5hbWUuSW5kZXhPZignXScpID4gLTEpIE5hbWUgPSBOYW1lLlJlcGxhY2UoIl0iLCAiICIpOwogICAgICAgICAgICB9CgogICAgICAgICAgICBpZiAoTmFtZS5UcmltKCkgPT0gIiIpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIHRocm93IG5ldyBBcmd1bWVudEV4Y2VwdGlvbigiVGhlIHdvcmtzaGVldCBjYW4gbm90IGhhdmUgYW4gZW1wdHkgbmFtZSIpOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGlmIChOYW1lLkxlbmd0aCA+IDMxKSBOYW1lID0gTmFtZS5TdWJzdHJpbmcoMCwgMzEpOyAgIC8vQSBzaGVldCBjYW4gaGF2ZSBtYXggMzEgY2hhcidzICAgICAgICAgICAgCiAgICAgICAgICAgIHJldHVybiBOYW1lOwogICAgICAgIH0KICAgICAgICAvLy8gPHN1bW1hcnk+CiAgICAgICAgLy8vIFZhbGlkYXRlIHRoZSBzaGVldG5hbWUKICAgICAgICAvLy8gPC9zdW1tYXJ5PgogICAgICAgIC8vLyA8cGFyYW0gbmFtZT0iTmFtZSI+VGhlIE5hbWU8L3BhcmFtPgogICAgICAgIC8vLyA8cmV0dXJucz5UcnVlIGlmIHZhbGlkPC9yZXR1cm5zPgogICAgICAgIHByaXZhdGUgYm9vbCBWYWxpZGF0ZU5hbWUoc3RyaW5nIE5hbWUpCiAgICAgICAgewogICAgICAgICAgICByZXR1cm4gU3lzdGVtLlRleHQuUmVndWxhckV4cHJlc3Npb25zLlJlZ2V4LklzTWF0Y2goTmFtZSwgQCI6fFw/fC98XFx8XFt8XF0iKTsKICAgICAgICB9CgoJCS8vLyA8c3VtbWFyeT4KCQkvLy8gQ3JlYXRlcyB0aGUgWE1MIGRvY3VtZW50IHJlcHJlc2VudGluZyBhIG5ldyBlbXB0eSB3b3Jrc2hlZXQKCQkvLy8gPC9zdW1tYXJ5PgoJCS8vLyA8cmV0dXJucz48L3JldHVybnM+CgkJaW50ZXJuYWwgWG1sRG9jdW1lbnQgQ3JlYXRlTmV3V29ya3NoZWV0KGJvb2wgaXNDaGFydCkKCQl7CgkJCVhtbERvY3VtZW50IHhtbERvYyA9IG5ldyBYbWxEb2N1bWVudCgpOwogICAgICAgICAgICBYbWxFbGVtZW50IGVsZW1XcyA9IHhtbERvYy5DcmVhdGVFbGVtZW50KGlzQ2hhcnQgPyAiY2hhcnRzaGVldCIgOiAid29ya3NoZWV0IiwgRXhjZWxQYWNrYWdlLnNjaGVtYU1haW4pOwogICAgICAgICAgICBlbGVtV3MuU2V0QXR0cmlidXRlKCJ4bWxuczpyIiwgRXhjZWxQYWNrYWdlLnNjaGVtYVJlbGF0aW9uc2hpcHMpOwogICAgICAgICAgICB4bWxEb2MuQXBwZW5kQ2hpbGQoZWxlbVdzKTsKCgogICAgICAgICAgICBpZiAoaXNDaGFydCkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgWG1sRWxlbWVudCBlbGVtU2hlZXRQciA9IHhtbERvYy5DcmVhdGVFbGVtZW50KCJzaGVldFByIiwgRXhjZWxQYWNrYWdlLnNjaGVtYU1haW4pOwogICAgICAgICAgICAgICAgZWxlbVdzLkFwcGVuZENoaWxkKGVsZW1TaGVldFByKTsKCiAgICAgICAgICAgICAgICBYbWxFbGVtZW50IGVsZW1TaGVldFZpZXdzID0geG1sRG9jLkNyZWF0ZUVsZW1lbnQoInNoZWV0Vmlld3MiLCBFeGNlbFBhY2thZ2Uuc2NoZW1hTWFpbik7CiAgICAgICAgICAgICAgICBlbGVtV3MuQXBwZW5kQ2hpbGQoZWxlbVNoZWV0Vmlld3MpOwoKICAgICAgICAgICAgICAgIFhtbEVsZW1lbnQgZWxlbVNoZWV0VmlldyA9IHhtbERvYy5DcmVhdGVFbGVtZW50KCJzaGVldFZpZXciLCBFeGNlbFBhY2thZ2Uuc2NoZW1hTWFpbik7CiAgICAgICAgICAgICAgICBlbGVtU2hlZXRWaWV3LlNldEF0dHJpYnV0ZSgid29ya2Jvb2tWaWV3SWQiLCAiMCIpOwogICAgICAgICAgICAgICAgZWxlbVNoZWV0Vmlldy5TZXRBdHRyaWJ1dGUoInpvb21Ub0ZpdCIsICIxIik7CgogICAgICAgICAgICAgICAgZWxlbVNoZWV0Vmlld3MuQXBwZW5kQ2hpbGQoZWxlbVNoZWV0Vmlldyk7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgZWxzZQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBYbWxFbGVtZW50IGVsZW1TaGVldFZpZXdzID0geG1sRG9jLkNyZWF0ZUVsZW1lbnQoInNoZWV0Vmlld3MiLCBFeGNlbFBhY2thZ2Uuc2NoZW1hTWFpbik7CiAgICAgICAgICAgICAgICBlbGVtV3MuQXBwZW5kQ2hpbGQoZWxlbVNoZWV0Vmlld3MpOwoKICAgICAgICAgICAgICAgIFhtbEVsZW1lbnQgZWxlbVNoZWV0VmlldyA9IHhtbERvYy5DcmVhdGVFbGVtZW50KCJzaGVldFZpZXciLCBFeGNlbFBhY2thZ2Uuc2NoZW1hTWFpbik7CiAgICAgICAgICAgICAgICBlbGVtU2hlZXRWaWV3LlNldEF0dHJpYnV0ZSgid29ya2Jvb2tWaWV3SWQiLCAiMCIpOwogICAgICAgICAgICAgICAgZWxlbVNoZWV0Vmlld3MuQXBwZW5kQ2hpbGQoZWxlbVNoZWV0Vmlldyk7CgogICAgICAgICAgICAgICAgWG1sRWxlbWVudCBlbGVtU2hlZXRGb3JtYXRQciA9IHhtbERvYy5DcmVhdGVFbGVtZW50KCJzaGVldEZvcm1hdFByIiwgRXhjZWxQYWNrYWdlLnNjaGVtYU1haW4pOwogICAgICAgICAgICAgICAgZWxlbVNoZWV0Rm9ybWF0UHIuU2V0QXR0cmlidXRlKCJkZWZhdWx0Um93SGVpZ2h0IiwgIjE1Iik7CiAgICAgICAgICAgICAgICBlbGVtV3MuQXBwZW5kQ2hpbGQoZWxlbVNoZWV0Rm9ybWF0UHIpOwoKICAgICAgICAgICAgICAgIFhtbEVsZW1lbnQgZWxlbVNoZWV0RGF0YSA9IHhtbERvYy5DcmVhdGVFbGVtZW50KCJzaGVldERhdGEiLCBFeGNlbFBhY2thZ2Uuc2NoZW1hTWFpbik7CiAgICAgICAgICAgICAgICBlbGVtV3MuQXBwZW5kQ2hpbGQoZWxlbVNoZWV0RGF0YSk7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgcmV0dXJuIHhtbERvYzsKCQl9CgkJI2VuZHJlZ2lvbgoJCSNyZWdpb24gRGVsZXRlIFdvcmtzaGVldAoJCS8vLyA8c3VtbWFyeT4KCQkvLy8gRGVsZXRlcyBhIHdvcmtzaGVldCBmcm9tIHRoZSBjb2xsZWN0aW9uCgkJLy8vIDwvc3VtbWFyeT4KCQkvLy8gPHBhcmFtIG5hbWU9IkluZGV4Ij5UaGUgcG9zaXRpb24gb2YgdGhlIHdvcmtzaGVldCBpbiB0aGUgd29ya2Jvb2s8L3BhcmFtPgoJCXB1YmxpYyB2b2lkIERlbGV0ZShpbnQgSW5kZXgpCgkJewoJCQkvKgogICAgICAgICAgICAqIEhhY2sgdG8gcHJlZmV0Y2ggYWxsIHRoZSBkcmF3aW5ncywKICAgICAgICAgICAgKiBzbyB0aGF0IGFsbCB0aGUgaW1hZ2VzIGFyZSByZWZlcmVuY2VkLCAKICAgICAgICAgICAgKiB0byBwcmV2ZW50IHRoZSBkZWxldGlvbiBvZiB0aGUgaW1hZ2UgZmlsZSwgCiAgICAgICAgICAgICogd2hlbiByZWZlcmVuY2VkIG1vcmUgdGhhbiBvbmNlCiAgICAgICAgICAgICovCiAgICAgICAgICAgIGZvcmVhY2ggKHZhciB3cyBpbiBfd29ya3NoZWV0cykKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgdmFyIGRyYXdpbmdzID0gd3MuVmFsdWUuRHJhd2luZ3M7IAogICAgICAgICAgICB9CQkJCiAgICAgICAgICAgIAogICAgICAgICAgICBFeGNlbFdvcmtzaGVldCB3b3Jrc2hlZXQgPSBfd29ya3NoZWV0c1tJbmRleF07CiAgICAgICAgICAgIGlmICh3b3Jrc2hlZXQuRHJhd2luZ3MuQ291bnQgPiAwKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICB3b3Jrc2hlZXQuRHJhd2luZ3MuQ2xlYXJEcmF3aW5ncygpOwogICAgICAgICAgICB9CgogICAgICAgICAgICAvL1JlbW92ZSBhbGwgY29tbWVudHMKICAgICAgICAgICAgaWYgKCEod29ya3NoZWV0IGlzIEV4Y2VsQ2hhcnRzaGVldCkgJiYgd29ya3NoZWV0LkNvbW1lbnRzLkNvdW50ID4gMCkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgd29ya3NoZWV0LkNvbW1lbnRzLkNsZWFyKCk7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgCgkJICAgIC8vRGVsZXRlIGFueSBwYXJ0cyBzdGlsbCB3aXRoIHJlbGF0aW9ucyB0byB0aGUgV29ya3NoZWV0LgogICAgICAgICAgICBEZWxldGVSZWxhdGlvbnNBbmRQYXJ0cyh3b3Jrc2hlZXQuUGFydCk7CgoKICAgICAgICAgICAgLy9EZWxldGUgdGhlIHdvcmtzaGVldCBwYXJ0IGFuZCByZWxhdGlvbiBmcm9tIHRoZSBwYWNrYWdlIAoJCQlfcGNrLldvcmtib29rLlBhcnQuRGVsZXRlUmVsYXRpb25zaGlwKHdvcmtzaGVldC5SZWxhdGlvbnNoaXBJRCk7CgogICAgICAgICAgICAvL0RlbGV0ZSB3b3Jrc2hlZXQgZnJvbSB0aGUgd29ya2Jvb2sgWE1MCgkJCVhtbE5vZGUgc2hlZXRzTm9kZSA9IF9wY2suV29ya2Jvb2suV29ya2Jvb2tYbWwuU2VsZWN0U2luZ2xlTm9kZSgiLy9kOndvcmtib29rL2Q6c2hlZXRzIiwgX25hbWVzcGFjZU1hbmFnZXIpOwoJCQlpZiAoc2hlZXRzTm9kZSAhPSBudWxsKQoJCQl7CgkJCQlYbWxOb2RlIHNoZWV0Tm9kZSA9IHNoZWV0c05vZGUuU2VsZWN0U2luZ2xlTm9kZShzdHJpbmcuRm9ybWF0KCIuL2Q6c2hlZXRbQHNoZWV0SWQ9ezB9XSIsIHdvcmtzaGVldC5TaGVldElEKSwgX25hbWVzcGFjZU1hbmFnZXIpOwoJCQkJaWYgKHNoZWV0Tm9kZSAhPSBudWxsKQoJCQkJewoJCQkJCXNoZWV0c05vZGUuUmVtb3ZlQ2hpbGQoc2hlZXROb2RlKTsKCQkJCX0KCQkJfQoJCQlfd29ya3NoZWV0cy5SZW1vdmUoSW5kZXgpOwogICAgICAgICAgICBpZiAoX3Bjay5Xb3JrYm9vay5WYmFQcm9qZWN0ICE9IG51bGwpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIF9wY2suV29ya2Jvb2suVmJhUHJvamVjdC5Nb2R1bGVzLlJlbW92ZSh3b3Jrc2hlZXQuQ29kZU1vZHVsZSk7CiAgICAgICAgICAgIH0KCQkJUmVpbmRleFdvcmtzaGVldERpY3Rpb25hcnkoKTsKICAgICAgICAgICAgLy9JZiB0aGUgYWN0aXZlIHNoZWV0IGlzIGRlbGV0ZWQsIHNldCB0aGUgZmlyc3QgdGFiIGFzIGFjdGl2ZS4KICAgICAgICAgICAgaWYgKF9wY2suV29ya2Jvb2suVmlldy5BY3RpdmVUYWIgPj0gX3Bjay5Xb3JrYm9vay5Xb3Jrc2hlZXRzLkNvdW50KQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBfcGNrLldvcmtib29rLlZpZXcuQWN0aXZlVGFiID0gX3Bjay5Xb3JrYm9vay5WaWV3LkFjdGl2ZVRhYi0xOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGlmIChfcGNrLldvcmtib29rLlZpZXcuQWN0aXZlVGFiID09IHdvcmtzaGVldC5TaGVldElEKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBfcGNrLldvcmtib29rLldvcmtzaGVldHNbMV0uVmlldy5UYWJTZWxlY3RlZCA9IHRydWU7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgd29ya3NoZWV0ID0gbnVsbDsKICAgICAgICB9CgogICAgICAgIHByaXZhdGUgdm9pZCBEZWxldGVSZWxhdGlvbnNBbmRQYXJ0cyhQYWNrYWdpbmcuWmlwUGFja2FnZVBhcnQgcGFydCkKICAgICAgICB7CiAgICAgICAgICAgIHZhciByZWxzID0gcGFydC5HZXRSZWxhdGlvbnNoaXBzKCkuVG9MaXN0KCk7CiAgICAgICAgICAgIGZvcihpbnQgaT0wO2k8cmVscy5Db3VudDtpKyspCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIHZhciByZWwgPSByZWxzW2ldOwogICAgICAgICAgICAgICAgaWYgKHJlbC5SZWxhdGlvbnNoaXBUeXBlICE9IEV4Y2VsUGFja2FnZS5zY2hlbWFJbWFnZSkKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICBEZWxldGVSZWxhdGlvbnNBbmRQYXJ0cyhfcGNrLlBhY2thZ2UuR2V0UGFydChVcmlIZWxwZXIuUmVzb2x2ZVBhcnRVcmkocmVsLlNvdXJjZVVyaSwgcmVsLlRhcmdldFVyaSkpKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIHBhcnQuRGVsZXRlUmVsYXRpb25zaGlwKHJlbC5JZCk7CiAgICAgICAgICAgIH0gICAgICAgICAgICAKICAgICAgICAgICAgX3Bjay5QYWNrYWdlLkRlbGV0ZVBhcnQocGFydC5VcmkpOwogICAgICAgIH0KCgkJLy8vIDxzdW1tYXJ5PgoJCS8vLyBEZWxldGVzIGEgd29ya3NoZWV0IGZyb20gdGhlIGNvbGxlY3Rpb24KCQkvLy8gPC9zdW1tYXJ5PgoJCS8vLyA8cGFyYW0gbmFtZT0ibmFtZSI+VGhlIG5hbWUgb2YgdGhlIHdvcmtzaGVldCBpbiB0aGUgd29ya2Jvb2s8L3BhcmFtPgoJCXB1YmxpYyB2b2lkIERlbGV0ZShzdHJpbmcgbmFtZSkKCQl7CgkJCXZhciBzaGVldCA9IHRoaXNbbmFtZV07CgkJCWlmIChzaGVldCA9PSBudWxsKQoJCQl7CgkJCQl0aHJvdyBuZXcgQXJndW1lbnRFeGNlcHRpb24oc3RyaW5nLkZvcm1hdCgiQ291bGQgbm90IGZpbmQgd29ya3NoZWV0IHRvIGRlbGV0ZSAnezB9JyIsIG5hbWUpKTsKCQkJfQoJCQlEZWxldGUoc2hlZXQuUG9zaXRpb25JRCk7CgkJfQoJCS8vLyA8c3VtbWFyeT4KICAgICAgICAvLy8gRGVsZXRlIGEgd29ya3NoZWV0IGZyb20gdGhlIGNvbGxlY3Rpb24KICAgICAgICAvLy8gPC9zdW1tYXJ5PgogICAgICAgIC8vLyA8cGFyYW0gbmFtZT0iV29ya3NoZWV0Ij5UaGUgd29ya3NoZWV0IHRvIGRlbGV0ZTwvcGFyYW0+CiAgICAgICAgcHVibGljIHZvaWQgRGVsZXRlKEV4Y2VsV29ya3NoZWV0IFdvcmtzaGVldCkKCQl7CiAgICAgICAgICAgIGlmIChXb3Jrc2hlZXQuUG9zaXRpb25JRCA8PSBfd29ya3NoZWV0cy5Db3VudCAmJiBXb3Jrc2hlZXQgPT0gX3dvcmtzaGVldHNbV29ya3NoZWV0LlBvc2l0aW9uSURdKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBEZWxldGUoV29ya3NoZWV0LlBvc2l0aW9uSUQpOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGVsc2UKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgdGhyb3cgKG5ldyBBcmd1bWVudEV4Y2VwdGlvbigiV29ya3NoZWV0IGlzIG5vdCBpbiB0aGUgY29sbGVjdGlvbi4iKSk7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgI2VuZHJlZ2lvbgoJCXByaXZhdGUgdm9pZCBSZWluZGV4V29ya3NoZWV0RGljdGlvbmFyeSgpCgkJewoJCQl2YXIgaW5kZXggPSAxOwoJCQl2YXIgd29ya3NoZWV0cyA9IG5ldyBEaWN0aW9uYXJ5PGludCwgRXhjZWxXb3Jrc2hlZXQ+KCk7CgkJCWZvcmVhY2ggKHZhciBlbnRyeSBpbiBfd29ya3NoZWV0cykKCQkJewoJCQkJZW50cnkuVmFsdWUuUG9zaXRpb25JRCA9IGluZGV4OwoJCQkJd29ya3NoZWV0cy5BZGQoaW5kZXgrKywgZW50cnkuVmFsdWUpOwoJCQl9CgkJCV93b3Jrc2hlZXRzID0gd29ya3NoZWV0czsKCQl9CgoJCS8vLyA8c3VtbWFyeT4KCQkvLy8gUmV0dXJucyB0aGUgd29ya3NoZWV0IGF0IHRoZSBzcGVjaWZpZWQgcG9zaXRpb24uICAKCQkvLy8gPC9zdW1tYXJ5PgoJCS8vLyA8cGFyYW0gbmFtZT0iUG9zaXRpb25JRCI+VGhlIHBvc2l0aW9uIG9mIHRoZSB3b3Jrc2hlZXQuIDEtYmFzZTwvcGFyYW0+CgkJLy8vIDxyZXR1cm5zPjwvcmV0dXJucz4KCQlwdWJsaWMgRXhjZWxXb3Jrc2hlZXQgdGhpc1tpbnQgUG9zaXRpb25JRF0KCQl7CgkJCWdldAoJCQl7CgkJCSAgICBpZiAoX3dvcmtzaGVldHMuQ29udGFpbnNLZXkoUG9zaXRpb25JRCkpCgkJCSAgICB7CgkJCSAgICAgICAgcmV0dXJuIF93b3Jrc2hlZXRzW1Bvc2l0aW9uSURdOwoJCQkgICAgfQoJCQkgICAgZWxzZQoJCQkgICAgewoJCQkgICAgICAgIHRocm93IChuZXcgSW5kZXhPdXRPZlJhbmdlRXhjZXB0aW9uKCJXb3Jrc2hlZXQgcG9zaXRpb24gb3V0IG9mIHJhbmdlLiIpKTsKCQkJICAgIH0KCQkJfQoJCX0KCgkJLy8vIDxzdW1tYXJ5PgoJCS8vLyBSZXR1cm5zIHRoZSB3b3Jrc2hlZXQgbWF0Y2hpbmcgdGhlIHNwZWNpZmllZCBuYW1lCgkJLy8vIDwvc3VtbWFyeT4KCQkvLy8gPHBhcmFtIG5hbWU9Ik5hbWUiPlRoZSBuYW1lIG9mIHRoZSB3b3Jrc2hlZXQ8L3BhcmFtPgoJCS8vLyA8cmV0dXJucz48L3JldHVybnM+CgkJcHVibGljIEV4Y2VsV29ya3NoZWV0IHRoaXNbc3RyaW5nIE5hbWVdCgkJewoJCQlnZXQKCQkJewogICAgICAgICAgICAgICAgcmV0dXJuIEdldEJ5TmFtZShOYW1lKTsKCQkJfQoJCX0KCQkvLy8gPHN1bW1hcnk+CgkJLy8vIENvcGllcyB0aGUgbmFtZWQgd29ya3NoZWV0IGFuZCBjcmVhdGVzIGEgbmV3IHdvcmtzaGVldCBpbiB0aGUgc2FtZSB3b3JrYm9vawoJCS8vLyA8L3N1bW1hcnk+CgkJLy8vIDxwYXJhbSBuYW1lPSJOYW1lIj5UaGUgbmFtZSBvZiB0aGUgZXhpc3Rpbmcgd29ya3NoZWV0PC9wYXJhbT4KCQkvLy8gPHBhcmFtIG5hbWU9Ik5ld05hbWUiPlRoZSBuYW1lIG9mIHRoZSBuZXcgd29ya3NoZWV0IHRvIGNyZWF0ZTwvcGFyYW0+CgkJLy8vIDxyZXR1cm5zPlRoZSBuZXcgY29weSBhZGRlZCB0byB0aGUgZW5kIG9mIHRoZSB3b3Jrc2hlZXRzIGNvbGxlY3Rpb248L3JldHVybnM+CgkJcHVibGljIEV4Y2VsV29ya3NoZWV0IENvcHkoc3RyaW5nIE5hbWUsIHN0cmluZyBOZXdOYW1lKQoJCXsKICAgICAgICAgICAgRXhjZWxXb3Jrc2hlZXQgQ29weSA9IHRoaXNbTmFtZV07CiAgICAgICAgICAgIGlmIChDb3B5ID09IG51bGwpCiAgICAgICAgICAgICAgICB0aHJvdyBuZXcgQXJndW1lbnRFeGNlcHRpb24oc3RyaW5nLkZvcm1hdCgiQ29weSB3b3Jrc2hlZXQgZXJyb3I6IENvdWxkIG5vdCBmaW5kIHdvcmtzaGVldCB0byBjb3B5ICd7MH0nIiwgTmFtZSkpOwoKICAgICAgICAgICAgRXhjZWxXb3Jrc2hlZXQgYWRkZWQgPSBBZGQoTmV3TmFtZSwgQ29weSk7CiAgICAgICAgICAgIHJldHVybiBhZGRlZDsKICAgICAgICB9CgkJI2VuZHJlZ2lvbgogICAgICAgIGludGVybmFsIEV4Y2VsV29ya3NoZWV0IEdldEJ5U2hlZXRJRChpbnQgbG9jYWxTaGVldElEKQogICAgICAgIHsKICAgICAgICAgICAgZm9yZWFjaCAoRXhjZWxXb3Jrc2hlZXQgd3MgaW4gdGhpcykKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgaWYgKHdzLlNoZWV0SUQgPT0gbG9jYWxTaGVldElEKQogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIHJldHVybiB3czsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgICAgICByZXR1cm4gbnVsbDsKICAgICAgICB9CiAgICAgICAgcHJpdmF0ZSBFeGNlbFdvcmtzaGVldCBHZXRCeU5hbWUoc3RyaW5nIE5hbWUpCiAgICAgICAgewogICAgICAgICAgICBpZiAoc3RyaW5nLklzTnVsbE9yRW1wdHkoTmFtZSkpIHJldHVybiBudWxsOwogICAgICAgICAgICBFeGNlbFdvcmtzaGVldCB4bFdvcmtzaGVldCA9IG51bGw7CiAgICAgICAgICAgIGZvcmVhY2ggKEV4Y2VsV29ya3NoZWV0IHdvcmtzaGVldCBpbiBfd29ya3NoZWV0cy5WYWx1ZXMpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIGlmICh3b3Jrc2hlZXQuTmFtZS5FcXVhbHMoTmFtZSwgU3RyaW5nQ29tcGFyaXNvbi5JbnZhcmlhbnRDdWx0dXJlSWdub3JlQ2FzZSkpCiAgICAgICAgICAgICAgICAgICAgeGxXb3Jrc2hlZXQgPSB3b3Jrc2hlZXQ7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgcmV0dXJuICh4bFdvcmtzaGVldCk7CiAgICAgICAgfQoJCSNyZWdpb24gTW92ZUJlZm9yZSBhbmQgTW92ZUFmdGVyIE1ldGhvZHMKCQkvLy8gPHN1bW1hcnk+CgkJLy8vIE1vdmVzIHRoZSBzb3VyY2Ugd29ya3NoZWV0IHRvIHRoZSBwb3NpdGlvbiBiZWZvcmUgdGhlIHRhcmdldCB3b3Jrc2hlZXQKCQkvLy8gPC9zdW1tYXJ5PgoJCS8vLyA8cGFyYW0gbmFtZT0ic291cmNlTmFtZSI+VGhlIG5hbWUgb2YgdGhlIHNvdXJjZSB3b3Jrc2hlZXQ8L3BhcmFtPgoJCS8vLyA8cGFyYW0gbmFtZT0idGFyZ2V0TmFtZSI+VGhlIG5hbWUgb2YgdGhlIHRhcmdldCB3b3Jrc2hlZXQ8L3BhcmFtPgoJCXB1YmxpYyB2b2lkIE1vdmVCZWZvcmUoc3RyaW5nIHNvdXJjZU5hbWUsIHN0cmluZyB0YXJnZXROYW1lKQoJCXsKCQkJTW92ZShzb3VyY2VOYW1lLCB0YXJnZXROYW1lLCBmYWxzZSk7CgkJfQoKCQkvLy8gPHN1bW1hcnk+CgkJLy8vIE1vdmVzIHRoZSBzb3VyY2Ugd29ya3NoZWV0IHRvIHRoZSBwb3NpdGlvbiBiZWZvcmUgdGhlIHRhcmdldCB3b3Jrc2hlZXQKCQkvLy8gPC9zdW1tYXJ5PgoJCS8vLyA8cGFyYW0gbmFtZT0ic291cmNlUG9zaXRpb25JZCI+VGhlIGlkIG9mIHRoZSBzb3VyY2Ugd29ya3NoZWV0PC9wYXJhbT4KCQkvLy8gPHBhcmFtIG5hbWU9InRhcmdldFBvc2l0aW9uSWQiPlRoZSBpZCBvZiB0aGUgdGFyZ2V0IHdvcmtzaGVldDwvcGFyYW0+CgkJcHVibGljIHZvaWQgTW92ZUJlZm9yZShpbnQgc291cmNlUG9zaXRpb25JZCwgaW50IHRhcmdldFBvc2l0aW9uSWQpCgkJewoJCQlNb3ZlKHNvdXJjZVBvc2l0aW9uSWQsIHRhcmdldFBvc2l0aW9uSWQsIGZhbHNlKTsKCQl9CgoJCS8vLyA8c3VtbWFyeT4KCQkvLy8gTW92ZXMgdGhlIHNvdXJjZSB3b3Jrc2hlZXQgdG8gdGhlIHBvc2l0aW9uIGFmdGVyIHRoZSB0YXJnZXQgd29ya3NoZWV0CgkJLy8vIDwvc3VtbWFyeT4KCQkvLy8gPHBhcmFtIG5hbWU9InNvdXJjZU5hbWUiPlRoZSBuYW1lIG9mIHRoZSBzb3VyY2Ugd29ya3NoZWV0PC9wYXJhbT4KCQkvLy8gPHBhcmFtIG5hbWU9InRhcmdldE5hbWUiPlRoZSBuYW1lIG9mIHRoZSB0YXJnZXQgd29ya3NoZWV0PC9wYXJhbT4KCQlwdWJsaWMgdm9pZCBNb3ZlQWZ0ZXIoc3RyaW5nIHNvdXJjZU5hbWUsIHN0cmluZyB0YXJnZXROYW1lKQoJCXsKCQkJTW92ZShzb3VyY2VOYW1lLCB0YXJnZXROYW1lLCB0cnVlKTsKCQl9CgoJCS8vLyA8c3VtbWFyeT4KCQkvLy8gTW92ZXMgdGhlIHNvdXJjZSB3b3Jrc2hlZXQgdG8gdGhlIHBvc2l0aW9uIGFmdGVyIHRoZSB0YXJnZXQgd29ya3NoZWV0CgkJLy8vIDwvc3VtbWFyeT4KCQkvLy8gPHBhcmFtIG5hbWU9InNvdXJjZVBvc2l0aW9uSWQiPlRoZSBpZCBvZiB0aGUgc291cmNlIHdvcmtzaGVldDwvcGFyYW0+CgkJLy8vIDxwYXJhbSBuYW1lPSJ0YXJnZXRQb3NpdGlvbklkIj5UaGUgaWQgb2YgdGhlIHRhcmdldCB3b3Jrc2hlZXQ8L3BhcmFtPgoJCXB1YmxpYyB2b2lkIE1vdmVBZnRlcihpbnQgc291cmNlUG9zaXRpb25JZCwgaW50IHRhcmdldFBvc2l0aW9uSWQpCgkJewoJCQlNb3ZlKHNvdXJjZVBvc2l0aW9uSWQsIHRhcmdldFBvc2l0aW9uSWQsIHRydWUpOwoJCX0KCgkJLy8vIDxzdW1tYXJ5PgoJCS8vLyAKCQkvLy8gPC9zdW1tYXJ5PgoJCS8vLyA8cGFyYW0gbmFtZT0ic291cmNlTmFtZSI+PC9wYXJhbT4KCQlwdWJsaWMgdm9pZCBNb3ZlVG9TdGFydChzdHJpbmcgc291cmNlTmFtZSkKCQl7CgkJCXZhciBzb3VyY2VTaGVldCA9IHRoaXNbc291cmNlTmFtZV07CgkJCWlmIChzb3VyY2VTaGVldCA9PSBudWxsKQoJCQl7CgkJCQl0aHJvdyBuZXcgRXhjZXB0aW9uKHN0cmluZy5Gb3JtYXQoIk1vdmUgd29ya3NoZWV0IGVycm9yOiBDb3VsZCBub3QgZmluZCB3b3Jrc2hlZXQgdG8gbW92ZSAnezB9JyIsIHNvdXJjZU5hbWUpKTsKCQkJfQoJCQlNb3ZlKHNvdXJjZVNoZWV0LlBvc2l0aW9uSUQsIDEsIGZhbHNlKTsKCQl9CgoJCS8vLyA8c3VtbWFyeT4KCQkvLy8gCgkJLy8vIDwvc3VtbWFyeT4KCQkvLy8gPHBhcmFtIG5hbWU9InNvdXJjZVBvc2l0aW9uSWQiPjwvcGFyYW0+CgkJcHVibGljIHZvaWQgTW92ZVRvU3RhcnQoaW50IHNvdXJjZVBvc2l0aW9uSWQpCgkJewoJCQlNb3ZlKHNvdXJjZVBvc2l0aW9uSWQsIDEsIGZhbHNlKTsKCQl9CgoJCS8vLyA8c3VtbWFyeT4KCQkvLy8gCgkJLy8vIDwvc3VtbWFyeT4KCQkvLy8gPHBhcmFtIG5hbWU9InNvdXJjZU5hbWUiPjwvcGFyYW0+CgkJcHVibGljIHZvaWQgTW92ZVRvRW5kKHN0cmluZyBzb3VyY2VOYW1lKQoJCXsKCQkJdmFyIHNvdXJjZVNoZWV0ID0gdGhpc1tzb3VyY2VOYW1lXTsKCQkJaWYgKHNvdXJjZVNoZWV0ID09IG51bGwpCgkJCXsKCQkJCXRocm93IG5ldyBFeGNlcHRpb24oc3RyaW5nLkZvcm1hdCgiTW92ZSB3b3Jrc2hlZXQgZXJyb3I6IENvdWxkIG5vdCBmaW5kIHdvcmtzaGVldCB0byBtb3ZlICd7MH0nIiwgc291cmNlTmFtZSkpOwoJCQl9CgkJCU1vdmUoc291cmNlU2hlZXQuUG9zaXRpb25JRCwgX3dvcmtzaGVldHMuQ291bnQsIHRydWUpOwoJCX0KCgkJLy8vIDxzdW1tYXJ5PgoJCS8vLyAKCQkvLy8gPC9zdW1tYXJ5PgoJCS8vLyA8cGFyYW0gbmFtZT0ic291cmNlUG9zaXRpb25JZCI+PC9wYXJhbT4KCQlwdWJsaWMgdm9pZCBNb3ZlVG9FbmQoaW50IHNvdXJjZVBvc2l0aW9uSWQpCgkJewoJCQlNb3ZlKHNvdXJjZVBvc2l0aW9uSWQsIF93b3Jrc2hlZXRzLkNvdW50LCB0cnVlKTsKCQl9CgoJCXByaXZhdGUgdm9pZCBNb3ZlKHN0cmluZyBzb3VyY2VOYW1lLCBzdHJpbmcgdGFyZ2V0TmFtZSwgYm9vbCBwbGFjZUFmdGVyKQoJCXsKCQkJdmFyIHNvdXJjZVNoZWV0ID0gdGhpc1tzb3VyY2VOYW1lXTsKCQkJaWYgKHNvdXJjZVNoZWV0ID09IG51bGwpCgkJCXsKCQkJCXRocm93IG5ldyBFeGNlcHRpb24oc3RyaW5nLkZvcm1hdCgiTW92ZSB3b3Jrc2hlZXQgZXJyb3I6IENvdWxkIG5vdCBmaW5kIHdvcmtzaGVldCB0byBtb3ZlICd7MH0nIiwgc291cmNlTmFtZSkpOwoJCQl9CgkJCXZhciB0YXJnZXRTaGVldCA9IHRoaXNbdGFyZ2V0TmFtZV07CgkJCWlmICh0YXJnZXRTaGVldCA9PSBudWxsKQoJCQl7CgkJCQl0aHJvdyBuZXcgRXhjZXB0aW9uKHN0cmluZy5Gb3JtYXQoIk1vdmUgd29ya3NoZWV0IGVycm9yOiBDb3VsZCBub3QgZmluZCB3b3Jrc2hlZXQgdG8gbW92ZSAnezB9JyIsIHRhcmdldE5hbWUpKTsKCQkJfQoJCQlNb3ZlKHNvdXJjZVNoZWV0LlBvc2l0aW9uSUQsIHRhcmdldFNoZWV0LlBvc2l0aW9uSUQsIHBsYWNlQWZ0ZXIpOwoJCX0KCgkJcHJpdmF0ZSB2b2lkIE1vdmUoaW50IHNvdXJjZVBvc2l0aW9uSWQsIGludCB0YXJnZXRQb3NpdGlvbklkLCBib29sIHBsYWNlQWZ0ZXIpCgkJewogICAgICAgICAgICAvLyBCdWdmaXg6IGlmIHNvdXJjZSBhbmQgdGFyZ2V0IGFyZSB0aGUgc2FtZSB3b3Jrc2hlZXQgdGhlIGZvbGxvd2luZyBjb2RlIHdpbGwgY3JlYXRlIGEgZHVwbGljYXRlCiAgICAgICAgICAgIC8vICAgICAgICAgd2hpY2ggd2lsbCBjYXVzZSBhIGNvcnJ1cHQgd29ya2Jvb2suIC9zd21hbCAyMDE0LTA1LTEwCgkJICAgIGlmIChzb3VyY2VQb3NpdGlvbklkID09IHRhcmdldFBvc2l0aW9uSWQpIHJldHVybjsKCiAgICAgICAgICAgIGxvY2sgKF93b3Jrc2hlZXRzKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICB2YXIgc291cmNlU2hlZXQgPSB0aGlzW3NvdXJjZVBvc2l0aW9uSWRdOwogICAgICAgICAgICAgICAgaWYgKHNvdXJjZVNoZWV0ID09IG51bGwpCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgdGhyb3cgbmV3IEV4Y2VwdGlvbihzdHJpbmcuRm9ybWF0KCJNb3ZlIHdvcmtzaGVldCBlcnJvcjogQ291bGQgbm90IGZpbmQgd29ya3NoZWV0IGF0IHBvc2l0aW9uICd7MH0nIiwgc291cmNlUG9zaXRpb25JZCkpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgdmFyIHRhcmdldFNoZWV0ID0gdGhpc1t0YXJnZXRQb3NpdGlvbklkXTsKICAgICAgICAgICAgICAgIGlmICh0YXJnZXRTaGVldCA9PSBudWxsKQogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIHRocm93IG5ldyBFeGNlcHRpb24oc3RyaW5nLkZvcm1hdCgiTW92ZSB3b3Jrc2hlZXQgZXJyb3I6IENvdWxkIG5vdCBmaW5kIHdvcmtzaGVldCBhdCBwb3NpdGlvbiAnezB9JyIsIHRhcmdldFBvc2l0aW9uSWQpKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGlmIChzb3VyY2VQb3NpdGlvbklkID09IHRhcmdldFBvc2l0aW9uSWQgJiYgX3dvcmtzaGVldHMuQ291bnQgPCAyKQogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIHJldHVybjsJCS8vLS0tIG5vIHJlYXNvbiB0byBhdHRlbXB0IHRvIHJlLWFycmFuZ2UgYSBzaW5nbGUgaXRlbSB3aXRoIGl0c2VsZgogICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgIHZhciBpbmRleCA9IDE7CiAgICAgICAgICAgICAgICB2YXIgbmV3T3JkZXIgPSBuZXcgRGljdGlvbmFyeTxpbnQsIEV4Y2VsV29ya3NoZWV0PigpOwogICAgICAgICAgICAgICAgZm9yZWFjaCAodmFyIGVudHJ5IGluIF93b3Jrc2hlZXRzKQogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIGlmIChlbnRyeS5LZXkgPT0gdGFyZ2V0UG9zaXRpb25JZCkKICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgIGlmICghcGxhY2VBZnRlcikKICAgICAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgc291cmNlU2hlZXQuUG9zaXRpb25JRCA9IGluZGV4OwogICAgICAgICAgICAgICAgICAgICAgICAgICAgbmV3T3JkZXIuQWRkKGluZGV4KyssIHNvdXJjZVNoZWV0KTsKICAgICAgICAgICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgICAgICAgICAgZW50cnkuVmFsdWUuUG9zaXRpb25JRCA9IGluZGV4OwogICAgICAgICAgICAgICAgICAgICAgICBuZXdPcmRlci5BZGQoaW5kZXgrKywgZW50cnkuVmFsdWUpOwoKICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHBsYWNlQWZ0ZXIpCiAgICAgICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNvdXJjZVNoZWV0LlBvc2l0aW9uSUQgPSBpbmRleDsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5ld09yZGVyLkFkZChpbmRleCsrLCBzb3VyY2VTaGVldCk7CiAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgZWxzZSBpZiAoZW50cnkuS2V5ID09IHNvdXJjZVBvc2l0aW9uSWQpCiAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICAvLy0tLSBkbyBub3RoaW5nCiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIGVsc2UKICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgIGVudHJ5LlZhbHVlLlBvc2l0aW9uSUQgPSBpbmRleDsKICAgICAgICAgICAgICAgICAgICAgICAgbmV3T3JkZXIuQWRkKGluZGV4KyssIGVudHJ5LlZhbHVlKTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBfd29ya3NoZWV0cyA9IG5ld09yZGVyOwoKICAgICAgICAgICAgICAgIE1vdmVTaGVldFhtbE5vZGUoc291cmNlU2hlZXQsIHRhcmdldFNoZWV0LCBwbGFjZUFmdGVyKTsKICAgICAgICAgICAgfQoJCX0KCgkJcHJpdmF0ZSB2b2lkIE1vdmVTaGVldFhtbE5vZGUoRXhjZWxXb3Jrc2hlZXQgc291cmNlU2hlZXQsIEV4Y2VsV29ya3NoZWV0IHRhcmdldFNoZWV0LCBib29sIHBsYWNlQWZ0ZXIpCgkJewogICAgICAgICAgICBsb2NrIChUb3BOb2RlLk93bmVyRG9jdW1lbnQpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIHZhciBzb3VyY2VOb2RlID0gVG9wTm9kZS5TZWxlY3RTaW5nbGVOb2RlKHN0cmluZy5Gb3JtYXQoImQ6c2hlZXRbQHNoZWV0SWQgPSAnezB9J10iLCBzb3VyY2VTaGVldC5TaGVldElEKSwgX25hbWVzcGFjZU1hbmFnZXIpOwogICAgICAgICAgICAgICAgdmFyIHRhcmdldE5vZGUgPSBUb3BOb2RlLlNlbGVjdFNpbmdsZU5vZGUoc3RyaW5nLkZvcm1hdCgiZDpzaGVldFtAc2hlZXRJZCA9ICd7MH0nXSIsIHRhcmdldFNoZWV0LlNoZWV0SUQpLCBfbmFtZXNwYWNlTWFuYWdlcik7CiAgICAgICAgICAgICAgICBpZiAoc291cmNlTm9kZSA9PSBudWxsIHx8IHRhcmdldE5vZGUgPT0gbnVsbCkKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICB0aHJvdyBuZXcgRXhjZXB0aW9uKCJTb3VyY2UgU2hlZXRJZCBhbmQgVGFyZ2V0IFNoZWV0SWQgbXVzdCBiZSB2YWxpZCIpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgaWYgKHBsYWNlQWZ0ZXIpCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgVG9wTm9kZS5JbnNlcnRBZnRlcihzb3VyY2VOb2RlLCB0YXJnZXROb2RlKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGVsc2UKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICBUb3BOb2RlLkluc2VydEJlZm9yZShzb3VyY2VOb2RlLCB0YXJnZXROb2RlKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQoJCX0KCgkJI2VuZHJlZ2lvbgogICAgICAgIHB1YmxpYyB2b2lkIERpc3Bvc2UoKQogICAgICAgIHsgICAgICAgICAgICAKICAgICAgICAgICAgIGZvcmVhY2ggKHZhciBzaGVldCBpbiB0aGlzLl93b3Jrc2hlZXRzLlZhbHVlcykgCiAgICAgICAgICAgICB7IAogICAgICAgICAgICAgICAgICgoSURpc3Bvc2FibGUpc2hlZXQpLkRpc3Bvc2UoKTsgCiAgICAgICAgICAgICB9IAogICAgICAgICAgICAgX3dvcmtzaGVldHMgPSBudWxsOwogICAgICAgICAgICAgX3BjayA9IG51bGw7ICAgICAgICAgICAgCiAgICAgICAgfQogICAgfSAvLyBlbmQgY2xhc3MgV29ya3NoZWV0cwp9Cg==