LyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogWW91IG1heSBhbWVuZCBhbmQgZGlzdHJpYnV0ZSBhcyB5b3UgbGlrZSwgYnV0IGRvbid0IHJlbW92ZSB0aGlzIGhlYWRlciEKICoKICogRVBQbHVzIHByb3ZpZGVzIHNlcnZlci1zaWRlIGdlbmVyYXRpb24gb2YgRXhjZWwgMjAwNy8yMDEwIHNwcmVhZHNoZWV0cy4KICogU2VlIGh0dHA6Ly93d3cuY29kZXBsZXguY29tL0VQUGx1cyBmb3IgZGV0YWlscy4KICoKICogQ29weXJpZ2h0IChDKSAyMDExICBKYW4gS+RsbG1hbgogKgogKiBUaGlzIGxpYnJhcnkgaXMgZnJlZSBzb2Z0d2FyZTsgeW91IGNhbiByZWRpc3RyaWJ1dGUgaXQgYW5kL29yCiAqIG1vZGlmeSBpdCB1bmRlciB0aGUgdGVybXMgb2YgdGhlIEdOVSBMZXNzZXIgR2VuZXJhbCBQdWJsaWMKICogTGljZW5zZSBhcyBwdWJsaXNoZWQgYnkgdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbjsgZWl0aGVyCiAqIHZlcnNpb24gMi4xIG9mIHRoZSBMaWNlbnNlLCBvciAoYXQgeW91ciBvcHRpb24pIGFueSBsYXRlciB2ZXJzaW9uLgoKICogVGhpcyBsaWJyYXJ5IGlzIGRpc3RyaWJ1dGVkIGluIHRoZSBob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsCiAqIGJ1dCBXSVRIT1VUIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuIHRoZSBpbXBsaWVkIHdhcnJhbnR5IG9mCiAqIE1FUkNIQU5UQUJJTElUWSBvciBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRS4gIAogKiBTZWUgdGhlIEdOVSBMZXNzZXIgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSBmb3IgbW9yZSBkZXRhaWxzLgogKgogKiBUaGUgR05VIExlc3NlciBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIGNhbiBiZSB2aWV3ZWQgYXQgaHR0cDovL3d3dy5vcGVuc291cmNlLm9yZy9saWNlbnNlcy9sZ3BsLWxpY2Vuc2UucGhwCiAqIElmIHlvdSB1bmZhbWlsaWFyIHdpdGggdGhpcyBsaWNlbnNlIG9yIGhhdmUgcXVlc3Rpb25zIGFib3V0IGl0LCBoZXJlIGlzIGFuIGh0dHA6Ly93d3cuZ251Lm9yZy9saWNlbnNlcy9ncGwtZmFxLmh0bWwKICoKICogQWxsIGNvZGUgYW5kIGV4ZWN1dGFibGVzIGFyZSBwcm92aWRlZCAiYXMgaXMiIHdpdGggbm8gd2FycmFudHkgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4gCiAqIFRoZSBhdXRob3IgYWNjZXB0cyBubyBsaWFiaWxpdHkgZm9yIGFueSBkYW1hZ2Ugb3IgbG9zcyBvZiBidXNpbmVzcyB0aGF0IHRoaXMgcHJvZHVjdCBtYXkgY2F1c2UuCiAqCiAqIENvZGUgY2hhbmdlIG5vdGVzOgogKiAKICogQXV0aG9yCQkJCQkJCUNoYW5nZQkJCQkJCURhdGUKICogKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIEphbiBL5GxsbWFuCQkgICAgICAgICAgICAgICAgSW5pdGlhbCBSZWxlYXNlCQkgICAgICAgIDIwMDktMTAtMDEKICogU3Rhcm51dG8gRGkgVG9wbyAmIEphbiBL5GxsbWFuICAgQWRkZWQgc3RyZWFtIGNvbnN0cnVjdG9ycyAKICogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYW5kIExvYWQgbWV0aG9kIFNhdmUgYXMgCiAqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN0cmVhbSAgICAgICAgICAgICAgICAgICAgICAyMDEwLTAzLTE0CiAqIEphbiBL5GxsbWFuCQlMaWNlbnNlIGNoYW5nZWQgR1BMLS0+TEdQTCAyMDExLTEyLTI3CiAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwp1c2luZyBTeXN0ZW07CnVzaW5nIFN5c3RlbS5YbWw7CnVzaW5nIFN5c3RlbS5JTzsKdXNpbmcgU3lzdGVtLkNvbGxlY3Rpb25zLkdlbmVyaWM7CnVzaW5nIFN5c3RlbS5TZWN1cml0eS5DcnlwdG9ncmFwaHk7CnVzaW5nIE9mZmljZU9wZW5YbWwuRHJhd2luZzsKdXNpbmcgT2ZmaWNlT3BlblhtbC5VdGlsczsKdXNpbmcgT2ZmaWNlT3BlblhtbC5QYWNrYWdpbmcuSW9uaWMuWmxpYjsKdXNpbmcgT2ZmaWNlT3BlblhtbC5Gb3JtdWxhUGFyc2luZzsKdXNpbmcgT2ZmaWNlT3BlblhtbC5FbmNyeXB0aW9uOwpuYW1lc3BhY2UgT2ZmaWNlT3BlblhtbAp7CiAgICAvLy8gPHN1bW1hcnk+CiAgICAvLy8gTWFwcyB0byBEb3ROZXRaaXBzIENvbXByZXNzaW9uTGV2ZWwgZW51bQogICAgLy8vIDwvc3VtbWFyeT4KICAgIHB1YmxpYyBlbnVtIENvbXByZXNzaW9uTGV2ZWwKICAgIHsKICAgICAgICBMZXZlbDAgPSAwLAogICAgICAgIE5vbmUgPSAwLAogICAgICAgIExldmVsMSA9IDEsCiAgICAgICAgQmVzdFNwZWVkID0gMSwKICAgICAgICBMZXZlbDIgPSAyLAogICAgICAgIExldmVsMyA9IDMsCiAgICAgICAgTGV2ZWw0ID0gNCwKICAgICAgICBMZXZlbDUgPSA1LAogICAgICAgIExldmVsNiA9IDYsCiAgICAgICAgRGVmYXVsdCA9IDYsCiAgICAgICAgTGV2ZWw3ID0gNywKICAgICAgICBMZXZlbDggPSA4LAogICAgICAgIEJlc3RDb21wcmVzc2lvbiA9IDksCiAgICAgICAgTGV2ZWw5ID0gOSwKICAgIH0KICAgIC8vLyA8c3VtbWFyeT4KICAgIC8vLyBSZXByZXNlbnRzIGFuIEV4Y2VsIDIwMDcvMjAxMCBYTFNYIGZpbGUgcGFja2FnZS4gIAogICAgLy8vIFRoaXMgaXMgdGhlIHRvcC1sZXZlbCBvYmplY3QgdG8gYWNjZXNzIGFsbCBwYXJ0cyBvZiB0aGUgZG9jdW1lbnQuCiAgICAvLy8gPGNvZGU+CgkvLy8gICAgIEZpbGVJbmZvIG5ld0ZpbGUgPSBuZXcgRmlsZUluZm8ob3V0cHV0RGlyLkZ1bGxOYW1lICsgQCJcc2FtcGxlMS54bHN4Iik7CgkvLy8gCWlmIChuZXdGaWxlLkV4aXN0cykKCS8vLyAJewoJLy8vIAkJbmV3RmlsZS5EZWxldGUoKTsgIC8vIGVuc3VyZXMgd2UgY3JlYXRlIGEgbmV3IHdvcmtib29rCgkvLy8gCQluZXdGaWxlID0gbmV3IEZpbGVJbmZvKG91dHB1dERpci5GdWxsTmFtZSArIEAiXHNhbXBsZTEueGxzeCIpOwoJLy8vIAl9CgkvLy8gCXVzaW5nIChFeGNlbFBhY2thZ2UgcGFja2FnZSA9IG5ldyBFeGNlbFBhY2thZ2UobmV3RmlsZSkpCiAgICAvLy8gICAgIHsKICAgIC8vLyAgICAgICAgIC8vIGFkZCBhIG5ldyB3b3Jrc2hlZXQgdG8gdGhlIGVtcHR5IHdvcmtib29rCiAgICAvLy8gICAgICAgICBFeGNlbFdvcmtzaGVldCB3b3Jrc2hlZXQgPSBwYWNrYWdlLldvcmtib29rLldvcmtzaGVldHMuQWRkKCJJbnZlbnRvcnkiKTsKICAgIC8vLyAgICAgICAgIC8vQWRkIHRoZSBoZWFkZXJzCiAgICAvLy8gICAgICAgICB3b3Jrc2hlZXQuQ2VsbHNbMSwgMV0uVmFsdWUgPSAiSUQiOwogICAgLy8vICAgICAgICAgd29ya3NoZWV0LkNlbGxzWzEsIDJdLlZhbHVlID0gIlByb2R1Y3QiOwogICAgLy8vICAgICAgICAgd29ya3NoZWV0LkNlbGxzWzEsIDNdLlZhbHVlID0gIlF1YW50aXR5IjsKICAgIC8vLyAgICAgICAgIHdvcmtzaGVldC5DZWxsc1sxLCA0XS5WYWx1ZSA9ICJQcmljZSI7CiAgICAvLy8gICAgICAgICB3b3Jrc2hlZXQuQ2VsbHNbMSwgNV0uVmFsdWUgPSAiVmFsdWUiOwogICAgLy8vCiAgICAvLy8gICAgICAgICAvL0FkZCBzb21lIGl0ZW1zLi4uCiAgICAvLy8gICAgICAgICB3b3Jrc2hlZXQuQ2VsbHNbIkEyIl0uVmFsdWUgPSAiMTIwMDEiOwogICAgLy8vICAgICAgICAgd29ya3NoZWV0LkNlbGxzWyJCMiJdLlZhbHVlID0gIk5haWxzIjsKICAgIC8vLyAgICAgICAgIHdvcmtzaGVldC5DZWxsc1siQzIiXS5WYWx1ZSA9IDM3OwogICAgLy8vICAgICAgICAgd29ya3NoZWV0LkNlbGxzWyJEMiJdLlZhbHVlID0gMy45OTsKICAgIC8vLwogICAgLy8vICAgICAgICAgd29ya3NoZWV0LkNlbGxzWyJBMyJdLlZhbHVlID0gIjEyMDAyIjsKICAgIC8vLyAgICAgICAgIHdvcmtzaGVldC5DZWxsc1siQjMiXS5WYWx1ZSA9ICJIYW1tZXIiOwogICAgLy8vICAgICAgICAgd29ya3NoZWV0LkNlbGxzWyJDMyJdLlZhbHVlID0gNTsKICAgIC8vLyAgICAgICAgIHdvcmtzaGVldC5DZWxsc1siRDMiXS5WYWx1ZSA9IDEyLjEwOwogICAgLy8vCiAgICAvLy8gICAgICAgICB3b3Jrc2hlZXQuQ2VsbHNbIkE0Il0uVmFsdWUgPSAiMTIwMDMiOwogICAgLy8vICAgICAgICAgd29ya3NoZWV0LkNlbGxzWyJCNCJdLlZhbHVlID0gIlNhdyI7CiAgICAvLy8gICAgICAgICB3b3Jrc2hlZXQuQ2VsbHNbIkM0Il0uVmFsdWUgPSAxMjsKICAgIC8vLyAgICAgICAgIHdvcmtzaGVldC5DZWxsc1siRDQiXS5WYWx1ZSA9IDE1LjM3OwogICAgLy8vCiAgICAvLy8gICAgICAgICAvL0FkZCBhIGZvcm11bGEgZm9yIHRoZSB2YWx1ZS1jb2x1bW4KICAgIC8vLyAgICAgICAgIHdvcmtzaGVldC5DZWxsc1siRTI6RTQiXS5Gb3JtdWxhID0gIkMyKkQyIjsKICAgIC8vLwogICAgLy8vICAgICAgICAgICAgLy9PayBub3cgZm9ybWF0IHRoZSB2YWx1ZXM7CiAgICAvLy8gICAgICAgICB1c2luZyAodmFyIHJhbmdlID0gd29ya3NoZWV0LkNlbGxzWzEsIDEsIDEsIDVdKSAKICAgIC8vLyAgICAgICAgICB7CiAgICAvLy8gICAgICAgICAgICAgcmFuZ2UuU3R5bGUuRm9udC5Cb2xkID0gdHJ1ZTsKICAgIC8vLyAgICAgICAgICAgICByYW5nZS5TdHlsZS5GaWxsLlBhdHRlcm5UeXBlID0gRXhjZWxGaWxsU3R5bGUuU29saWQ7CiAgICAvLy8gICAgICAgICAgICAgcmFuZ2UuU3R5bGUuRmlsbC5CYWNrZ3JvdW5kQ29sb3IuU2V0Q29sb3IoQ29sb3IuRGFya0JsdWUpOwogICAgLy8vICAgICAgICAgICAgIHJhbmdlLlN0eWxlLkZvbnQuQ29sb3IuU2V0Q29sb3IoQ29sb3IuV2hpdGUpOwogICAgLy8vICAgICAgICAgfQogICAgLy8vCiAgICAvLy8gICAgICAgICB3b3Jrc2hlZXQuQ2VsbHNbIkE1OkU1Il0uU3R5bGUuQm9yZGVyLlRvcC5TdHlsZSA9IEV4Y2VsQm9yZGVyU3R5bGUuVGhpbjsKICAgIC8vLyAgICAgICAgIHdvcmtzaGVldC5DZWxsc1siQTU6RTUiXS5TdHlsZS5Gb250LkJvbGQgPSB0cnVlOwogICAgLy8vCiAgICAvLy8gICAgICAgICB3b3Jrc2hlZXQuQ2VsbHNbNSwgMywgNSwgNV0uRm9ybXVsYSA9IHN0cmluZy5Gb3JtYXQoIlNVQlRPVEFMKDksezB9KSIsIG5ldyBFeGNlbEFkZHJlc3MoMiwzLDQsMykuQWRkcmVzcyk7CiAgICAvLy8gICAgICAgICB3b3Jrc2hlZXQuQ2VsbHNbIkMyOkM1Il0uU3R5bGUuTnVtYmVyZm9ybWF0LkZvcm1hdCA9ICIjLCMjMCI7CiAgICAvLy8gICAgICAgICB3b3Jrc2hlZXQuQ2VsbHNbIkQyOkU1Il0uU3R5bGUuTnVtYmVyZm9ybWF0LkZvcm1hdCA9ICIjLCMjMC4wMCI7CiAgICAvLy8KICAgIC8vLyAgICAgICAgIC8vQ3JlYXRlIGFuIGF1dG9maWx0ZXIgZm9yIHRoZSByYW5nZQogICAgLy8vICAgICAgICAgd29ya3NoZWV0LkNlbGxzWyJBMTpFNCJdLkF1dG9GaWx0ZXIgPSB0cnVlOwogICAgLy8vCiAgICAvLy8gICAgICAgICB3b3Jrc2hlZXQuQ2VsbHNbIkExOkU1Il0uQXV0b0ZpdENvbHVtbnMoMCk7CiAgICAvLy8KICAgIC8vLyAgICAgICAgIC8vIGxldHMgc2V0IHRoZSBoZWFkZXIgdGV4dCAKICAgIC8vLyAgICAgICAgIHdvcmtzaGVldC5IZWFkZXJGb290ZXIub2RkSGVhZGVyLkNlbnRlcmVkVGV4dCA9ICImYW1wOzI0JmFtcDtVJmFtcDtcIkFyaWFsLFJlZ3VsYXIgQm9sZFwiIEludmVudG9yeSI7CiAgICAvLy8gICAgICAgICAvLyBhZGQgdGhlIHBhZ2UgbnVtYmVyIHRvIHRoZSBmb290ZXIgcGx1cyB0aGUgdG90YWwgbnVtYmVyIG9mIHBhZ2VzCiAgICAvLy8gICAgICAgICB3b3Jrc2hlZXQuSGVhZGVyRm9vdGVyLm9kZEZvb3Rlci5SaWdodEFsaWduZWRUZXh0ID0KICAgIC8vLyAgICAgICAgIHN0cmluZy5Gb3JtYXQoIlBhZ2UgezB9IG9mIHsxfSIsIEV4Y2VsSGVhZGVyRm9vdGVyLlBhZ2VOdW1iZXIsIEV4Y2VsSGVhZGVyRm9vdGVyLk51bWJlck9mUGFnZXMpOwogICAgLy8vICAgICAgICAgLy8gYWRkIHRoZSBzaGVldCBuYW1lIHRvIHRoZSBmb290ZXIKICAgIC8vLyAgICAgICAgIHdvcmtzaGVldC5IZWFkZXJGb290ZXIub2RkRm9vdGVyLkNlbnRlcmVkVGV4dCA9IEV4Y2VsSGVhZGVyRm9vdGVyLlNoZWV0TmFtZTsKICAgIC8vLyAgICAgICAgIC8vIGFkZCB0aGUgZmlsZSBwYXRoIHRvIHRoZSBmb290ZXIKICAgIC8vLyAgICAgICAgIHdvcmtzaGVldC5IZWFkZXJGb290ZXIub2RkRm9vdGVyLkxlZnRBbGlnbmVkVGV4dCA9IEV4Y2VsSGVhZGVyRm9vdGVyLkZpbGVQYXRoICsgRXhjZWxIZWFkZXJGb290ZXIuRmlsZU5hbWU7CiAgICAvLy8KICAgIC8vLyAgICAgICAgIHdvcmtzaGVldC5QcmludGVyU2V0dGluZ3MuUmVwZWF0Um93cyA9IHdvcmtzaGVldC5DZWxsc1siMToyIl07CiAgICAvLy8gICAgICAgICB3b3Jrc2hlZXQuUHJpbnRlclNldHRpbmdzLlJlcGVhdENvbHVtbnMgPSB3b3Jrc2hlZXQuQ2VsbHNbIkE6RyJdOwogICAgLy8vCiAgICAvLy8gICAgICAgICAgLy8gQ2hhbmdlIHRoZSBzaGVldCB2aWV3IHRvIHNob3cgaXQgaW4gcGFnZSBsYXlvdXQgbW9kZQogICAgLy8vICAgICAgICAgICB3b3Jrc2hlZXQuVmlldy5QYWdlTGF5b3V0VmlldyA9IHRydWU7CiAgICAvLy8KICAgIC8vLyAgICAgICAgIC8vIHNldCBzb21lIGRvY3VtZW50IHByb3BlcnRpZXMKICAgIC8vLyAgICAgICAgIHBhY2thZ2UuV29ya2Jvb2suUHJvcGVydGllcy5UaXRsZSA9ICJJbnZlcnRvcnkiOwogICAgLy8vICAgICAgICAgcGFja2FnZS5Xb3JrYm9vay5Qcm9wZXJ0aWVzLkF1dGhvciA9ICJKYW4gS+RsbG1hbiI7CiAgICAvLy8gICAgICAgICBwYWNrYWdlLldvcmtib29rLlByb3BlcnRpZXMuQ29tbWVudHMgPSAiVGhpcyBzYW1wbGUgZGVtb25zdHJhdGVzIGhvdyB0byBjcmVhdGUgYW4gRXhjZWwgMjAwNyB3b3JrYm9vayB1c2luZyBFUFBsdXMiOwogICAgLy8vCiAgICAvLy8gICAgICAgICAvLyBzZXQgc29tZSBleHRlbmRlZCBwcm9wZXJ0eSB2YWx1ZXMKICAgIC8vLyAgICAgICAgIHBhY2thZ2UuV29ya2Jvb2suUHJvcGVydGllcy5Db21wYW55ID0gIkFkdmVudHVyZVdvcmtzIEluYy4iOwogICAgLy8vCiAgICAvLy8gICAgICAgICAvLyBzZXQgc29tZSBjdXN0b20gcHJvcGVydHkgdmFsdWVzCiAgICAvLy8gICAgICAgICBwYWNrYWdlLldvcmtib29rLlByb3BlcnRpZXMuU2V0Q3VzdG9tUHJvcGVydHlWYWx1ZSgiQ2hlY2tlZCBieSIsICJKYW4gS+RsbG1hbiIpOwogICAgLy8vICAgICAgICAgcGFja2FnZS5Xb3JrYm9vay5Qcm9wZXJ0aWVzLlNldEN1c3RvbVByb3BlcnR5VmFsdWUoIkFzc2VtYmx5TmFtZSIsICJFUFBsdXMiKTsKICAgIC8vLwogICAgLy8vICAgICAgICAgLy8gc2F2ZSBvdXIgbmV3IHdvcmtib29rIGFuZCB3ZSBhcmUgZG9uZSEKICAgIC8vLyAgICAgICAgIHBhY2thZ2UuU2F2ZSgpOwogICAgLy8vCiAgICAvLy8gICAgICAgfQogICAgLy8vCiAgICAvLy8gICAgICAgcmV0dXJuIG5ld0ZpbGUuRnVsbE5hbWU7CiAgICAvLy8gPC9jb2RlPgogICAgLy8vIE1vcmUgc2FtcGxlcyBjYW4gYmUgZm91bmQgYXQgIDxhIGhyZWY9Imh0dHA6Ly9lcHBsdXMuY29kZXBsZXguY29tLyI+aHR0cDovL2VwcGx1cy5jb2RlcGxleC5jb20vPC9hPgogICAgLy8vIDwvc3VtbWFyeT4KCXB1YmxpYyBzZWFsZWQgY2xhc3MgRXhjZWxQYWNrYWdlIDogSURpc3Bvc2FibGUKCXsKICAgICAgICBpbnRlcm5hbCBjb25zdCBib29sIHByZXNlcnZlV2hpdGVzcGFjZT1mYWxzZTsKICAgICAgICBTdHJlYW0gX3N0cmVhbSA9IG51bGw7CiAgICAgICAgcHJpdmF0ZSBib29sIF9pc0V4dGVybmFsU3RyZWFtPWZhbHNlOwogICAgICAgIGludGVybmFsIGNsYXNzIEltYWdlSW5mbwogICAgICAgIHsKICAgICAgICAgICAgaW50ZXJuYWwgc3RyaW5nIEhhc2ggeyBnZXQ7IHNldDsgfQogICAgICAgICAgICBpbnRlcm5hbCBVcmkgVXJpe2dldDtzZXQ7fQogICAgICAgICAgICBpbnRlcm5hbCBpbnQgUmVmQ291bnQgeyBnZXQ7IHNldDsgfQogICAgICAgICAgICBpbnRlcm5hbCBQYWNrYWdpbmcuWmlwUGFja2FnZVBhcnQgUGFydCB7IGdldDsgc2V0OyB9CiAgICAgICAgfQogICAgICAgIGludGVybmFsIERpY3Rpb25hcnk8c3RyaW5nLCBJbWFnZUluZm8+IF9pbWFnZXMgPSBuZXcgRGljdGlvbmFyeTxzdHJpbmcsIEltYWdlSW5mbz4oKTsKCQkjcmVnaW9uIFByb3BlcnRpZXMKCQkvLy8gPHN1bW1hcnk+CgkJLy8vIEV4dGVudGlvbiBTY2hlbWEgdHlwZXMKCQkvLy8gPC9zdW1tYXJ5PgogICAgICAgIGludGVybmFsIGNvbnN0IHN0cmluZyBzY2hlbWFYbWxFeHRlbnNpb24gPSAiYXBwbGljYXRpb24veG1sIjsKICAgICAgICBpbnRlcm5hbCBjb25zdCBzdHJpbmcgc2NoZW1hUmVsc0V4dGVuc2lvbiA9ICJhcHBsaWNhdGlvbi92bmQub3BlbnhtbGZvcm1hdHMtcGFja2FnZS5yZWxhdGlvbnNoaXBzK3htbCI7CiAgICAgICAgLy8vIDxzdW1tYXJ5PgoJCS8vLyBNYWluIFhtbCBzY2hlbWEgbmFtZQoJCS8vLyA8L3N1bW1hcnk+CgkJaW50ZXJuYWwgY29uc3Qgc3RyaW5nIHNjaGVtYU1haW4gPSBAImh0dHA6Ly9zY2hlbWFzLm9wZW54bWxmb3JtYXRzLm9yZy9zcHJlYWRzaGVldG1sLzIwMDYvbWFpbiI7CgkJLy8vIDxzdW1tYXJ5PgoJCS8vLyBSZWxhdGlvbnNoaXAgc2NoZW1hIG5hbWUKCQkvLy8gPC9zdW1tYXJ5PgoJCWludGVybmFsIGNvbnN0IHN0cmluZyBzY2hlbWFSZWxhdGlvbnNoaXBzID0gQCJodHRwOi8vc2NoZW1hcy5vcGVueG1sZm9ybWF0cy5vcmcvb2ZmaWNlRG9jdW1lbnQvMjAwNi9yZWxhdGlvbnNoaXBzIjsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgaW50ZXJuYWwgY29uc3Qgc3RyaW5nIHNjaGVtYURyYXdpbmdzID0gQCJodHRwOi8vc2NoZW1hcy5vcGVueG1sZm9ybWF0cy5vcmcvZHJhd2luZ21sLzIwMDYvbWFpbiI7CiAgICAgICAgaW50ZXJuYWwgY29uc3Qgc3RyaW5nIHNjaGVtYVNoZWV0RHJhd2luZ3MgPSBAImh0dHA6Ly9zY2hlbWFzLm9wZW54bWxmb3JtYXRzLm9yZy9kcmF3aW5nbWwvMjAwNi9zcHJlYWRzaGVldERyYXdpbmciOwogICAgICAgIGludGVybmFsIGNvbnN0IHN0cmluZyBzY2hlbWFNYXJrdXBDb21wYXRpYmlsaXR5ID0gQCJodHRwOi8vc2NoZW1hcy5vcGVueG1sZm9ybWF0cy5vcmcvbWFya3VwLWNvbXBhdGliaWxpdHkvMjAwNiI7CgogICAgICAgIGludGVybmFsIGNvbnN0IHN0cmluZyBzY2hlbWFNaWNyb3NvZnRWbWwgPSBAInVybjpzY2hlbWFzLW1pY3Jvc29mdC1jb206dm1sIjsKICAgICAgICBpbnRlcm5hbCBjb25zdCBzdHJpbmcgc2NoZW1hTWljcm9zb2Z0T2ZmaWNlID0gInVybjpzY2hlbWFzLW1pY3Jvc29mdC1jb206b2ZmaWNlOm9mZmljZSI7CiAgICAgICAgaW50ZXJuYWwgY29uc3Qgc3RyaW5nIHNjaGVtYU1pY3Jvc29mdEV4Y2VsID0gInVybjpzY2hlbWFzLW1pY3Jvc29mdC1jb206b2ZmaWNlOmV4Y2VsIjsKCiAgICAgICAgaW50ZXJuYWwgY29uc3Qgc3RyaW5nIHNjaGVtYUNoYXJ0ID0gQCJodHRwOi8vc2NoZW1hcy5vcGVueG1sZm9ybWF0cy5vcmcvZHJhd2luZ21sLzIwMDYvY2hhcnQiOyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgaW50ZXJuYWwgY29uc3Qgc3RyaW5nIHNjaGVtYUh5cGVybGluayA9IEAiaHR0cDovL3NjaGVtYXMub3BlbnhtbGZvcm1hdHMub3JnL29mZmljZURvY3VtZW50LzIwMDYvcmVsYXRpb25zaGlwcy9oeXBlcmxpbmsiOwogICAgICAgIGludGVybmFsIGNvbnN0IHN0cmluZyBzY2hlbWFDb21tZW50ID0gQCJodHRwOi8vc2NoZW1hcy5vcGVueG1sZm9ybWF0cy5vcmcvb2ZmaWNlRG9jdW1lbnQvMjAwNi9yZWxhdGlvbnNoaXBzL2NvbW1lbnRzIjsKICAgICAgICBpbnRlcm5hbCBjb25zdCBzdHJpbmcgc2NoZW1hSW1hZ2UgPSBAImh0dHA6Ly9zY2hlbWFzLm9wZW54bWxmb3JtYXRzLm9yZy9vZmZpY2VEb2N1bWVudC8yMDA2L3JlbGF0aW9uc2hpcHMvaW1hZ2UiOwogICAgICAgIC8vT2ZmaWNlIHByb3BlcnRpZXMKICAgICAgICBpbnRlcm5hbCBjb25zdCBzdHJpbmcgc2NoZW1hQ29yZSA9IEAiaHR0cDovL3NjaGVtYXMub3BlbnhtbGZvcm1hdHMub3JnL3BhY2thZ2UvMjAwNi9tZXRhZGF0YS9jb3JlLXByb3BlcnRpZXMiOwogICAgICAgIGludGVybmFsIGNvbnN0IHN0cmluZyBzY2hlbWFFeHRlbmRlZCA9IEAiaHR0cDovL3NjaGVtYXMub3BlbnhtbGZvcm1hdHMub3JnL29mZmljZURvY3VtZW50LzIwMDYvZXh0ZW5kZWQtcHJvcGVydGllcyI7CiAgICAgICAgaW50ZXJuYWwgY29uc3Qgc3RyaW5nIHNjaGVtYUN1c3RvbSA9IEAiaHR0cDovL3NjaGVtYXMub3BlbnhtbGZvcm1hdHMub3JnL29mZmljZURvY3VtZW50LzIwMDYvY3VzdG9tLXByb3BlcnRpZXMiOwogICAgICAgIGludGVybmFsIGNvbnN0IHN0cmluZyBzY2hlbWFEYyA9IEAiaHR0cDovL3B1cmwub3JnL2RjL2VsZW1lbnRzLzEuMS8iOwogICAgICAgIGludGVybmFsIGNvbnN0IHN0cmluZyBzY2hlbWFEY1Rlcm1zID0gQCJodHRwOi8vcHVybC5vcmcvZGMvdGVybXMvIjsKICAgICAgICBpbnRlcm5hbCBjb25zdCBzdHJpbmcgc2NoZW1hRGNtaVR5cGUgPSBAImh0dHA6Ly9wdXJsLm9yZy9kYy9kY21pdHlwZS8iOwogICAgICAgIGludGVybmFsIGNvbnN0IHN0cmluZyBzY2hlbWFYc2kgPSBAImh0dHA6Ly93d3cudzMub3JnLzIwMDEvWE1MU2NoZW1hLWluc3RhbmNlIjsKICAgICAgICBpbnRlcm5hbCBjb25zdCBzdHJpbmcgc2NoZW1hVnQgPSBAImh0dHA6Ly9zY2hlbWFzLm9wZW54bWxmb3JtYXRzLm9yZy9vZmZpY2VEb2N1bWVudC8yMDA2L2RvY1Byb3BzVlR5cGVzIjsKCiAgICAgICAgLy9QaXZvdHRhYmxlcwogICAgICAgIGludGVybmFsIGNvbnN0IHN0cmluZyBzY2hlbWFQaXZvdFRhYmxlID0gQCJhcHBsaWNhdGlvbi92bmQub3BlbnhtbGZvcm1hdHMtb2ZmaWNlZG9jdW1lbnQuc3ByZWFkc2hlZXRtbC5waXZvdFRhYmxlK3htbCI7CiAgICAgICAgaW50ZXJuYWwgY29uc3Qgc3RyaW5nIHNjaGVtYVBpdm90Q2FjaGVEZWZpbml0aW9uID0gQCJhcHBsaWNhdGlvbi92bmQub3BlbnhtbGZvcm1hdHMtb2ZmaWNlZG9jdW1lbnQuc3ByZWFkc2hlZXRtbC5waXZvdENhY2hlRGVmaW5pdGlvbit4bWwiOwogICAgICAgIGludGVybmFsIGNvbnN0IHN0cmluZyBzY2hlbWFQaXZvdENhY2hlUmVjb3JkcyA9IEAiYXBwbGljYXRpb24vdm5kLm9wZW54bWxmb3JtYXRzLW9mZmljZWRvY3VtZW50LnNwcmVhZHNoZWV0bWwucGl2b3RDYWNoZVJlY29yZHMreG1sIjsKCiAgICAgICAgLy9WQkEKICAgICAgICBpbnRlcm5hbCBjb25zdCBzdHJpbmcgc2NoZW1hVkJBID0gQCJhcHBsaWNhdGlvbi92bmQubXMtb2ZmaWNlLnZiYVByb2plY3QiOwogICAgICAgIGludGVybmFsIGNvbnN0IHN0cmluZyBzY2hlbWFWQkFTaWduYXR1cmUgPSBAImFwcGxpY2F0aW9uL3ZuZC5tcy1vZmZpY2UudmJhUHJvamVjdFNpZ25hdHVyZSI7CgogICAgICAgIGludGVybmFsIGNvbnN0IHN0cmluZyBjb250ZW50VHlwZVdvcmtib29rRGVmYXVsdCA9IEAiYXBwbGljYXRpb24vdm5kLm9wZW54bWxmb3JtYXRzLW9mZmljZWRvY3VtZW50LnNwcmVhZHNoZWV0bWwuc2hlZXQubWFpbit4bWwiOwogICAgICAgIGludGVybmFsIGNvbnN0IHN0cmluZyBjb250ZW50VHlwZVdvcmtib29rTWFjcm9FbmFibGVkID0gImFwcGxpY2F0aW9uL3ZuZC5tcy1leGNlbC5zaGVldC5tYWNyb0VuYWJsZWQubWFpbit4bWwiOwogICAgICAgIGludGVybmFsIGNvbnN0IHN0cmluZyBjb250ZW50VHlwZVNoYXJlZFN0cmluZyA9IEAiYXBwbGljYXRpb24vdm5kLm9wZW54bWxmb3JtYXRzLW9mZmljZWRvY3VtZW50LnNwcmVhZHNoZWV0bWwuc2hhcmVkU3RyaW5ncyt4bWwiOwogICAgICAgIC8vUGFja2FnZSByZWZlcmVuY2UKICAgICAgICBwcml2YXRlIFBhY2thZ2luZy5aaXBQYWNrYWdlIF9wYWNrYWdlOwoJCWludGVybmFsIEV4Y2VsV29ya2Jvb2sgX3dvcmtib29rOwogICAgICAgIC8vLyA8c3VtbWFyeT4KICAgICAgICAvLy8gTWF4aW11bSBudW1iZXIgb2YgY29sdW1ucyBpbiBhIHdvcmtzaGVldCAoMTYzODQpLiAKICAgICAgICAvLy8gPC9zdW1tYXJ5PgogICAgICAgIHB1YmxpYyBjb25zdCBpbnQgTWF4Q29sdW1ucyA9IDE2Mzg0OwogICAgICAgIC8vLyA8c3VtbWFyeT4KICAgICAgICAvLy8gTWF4aW11bSBudW1iZXIgb2Ygcm93cyBpbiBhIHdvcmtzaGVldCAoMTA0ODU3NikuIAogICAgICAgIC8vLyA8L3N1bW1hcnk+CiAgICAgICAgcHVibGljIGNvbnN0IGludCBNYXhSb3dzID0gMTA0ODU3NjsKCQkjZW5kcmVnaW9uCgoJCSNyZWdpb24gRXhjZWxQYWNrYWdlIENvbnN0cnVjdG9ycwogICAgICAgIC8vLyA8c3VtbWFyeT4KICAgICAgICAvLy8gQ3JlYXRlIGEgbmV3IGluc3RhbmNlIG9mIHRoZSBFeGNlbFBhY2thZ2UuIE91dHB1dCBpcyBhY2Nlc3NlZCB0aHJvdWdoIHRoZSBTdHJlYW0gcHJvcGVydHkuCiAgICAgICAgLy8vIDwvc3VtbWFyeT4KICAgICAgICBwdWJsaWMgRXhjZWxQYWNrYWdlKCkKICAgICAgICB7CiAgICAgICAgICAgIEluaXQoKTsKICAgICAgICAgICAgQ29uc3RydWN0TmV3RmlsZShudWxsKTsKICAgICAgICB9CiAgICAgICAgLy8vIDxzdW1tYXJ5PgoJCS8vLyBDcmVhdGUgYSBuZXcgaW5zdGFuY2Ugb2YgdGhlIEV4Y2VsUGFja2FnZSBjbGFzcyBiYXNlZCBvbiBhIGV4aXN0aW5nIGZpbGUgb3IgY3JlYXRlcyBhIG5ldyBmaWxlLiAKCQkvLy8gPC9zdW1tYXJ5PgoJCS8vLyA8cGFyYW0gbmFtZT0ibmV3RmlsZSI+SWYgbmV3RmlsZSBleGlzdHMsIGl0IGlzIG9wZW5lZC4gIE90aGVyd2lzZSBpdCBpcyBjcmVhdGVkIGZyb20gc2NyYXRjaC48L3BhcmFtPgogICAgICAgIHB1YmxpYyBFeGNlbFBhY2thZ2UoRmlsZUluZm8gbmV3RmlsZSkKCQl7CiAgICAgICAgICAgIEluaXQoKTsKICAgICAgICAgICAgRmlsZSA9IG5ld0ZpbGU7CiAgICAgICAgICAgIENvbnN0cnVjdE5ld0ZpbGUobnVsbCk7CiAgICAgICAgfQogICAgICAgIC8vLyA8c3VtbWFyeT4KICAgICAgICAvLy8gQ3JlYXRlIGEgbmV3IGluc3RhbmNlIG9mIHRoZSBFeGNlbFBhY2thZ2UgY2xhc3MgYmFzZWQgb24gYSBleGlzdGluZyBmaWxlIG9yIGNyZWF0ZXMgYSBuZXcgZmlsZS4gCiAgICAgICAgLy8vIDwvc3VtbWFyeT4KICAgICAgICAvLy8gPHBhcmFtIG5hbWU9Im5ld0ZpbGUiPklmIG5ld0ZpbGUgZXhpc3RzLCBpdCBpcyBvcGVuZWQuICBPdGhlcndpc2UgaXQgaXMgY3JlYXRlZCBmcm9tIHNjcmF0Y2guPC9wYXJhbT4KICAgICAgICAvLy8gPHBhcmFtIG5hbWU9InBhc3N3b3JkIj5QYXNzd29yZCBmb3IgYW4gZW5jcnlwdGVkIHBhY2thZ2U8L3BhcmFtPgogICAgICAgIHB1YmxpYyBFeGNlbFBhY2thZ2UoRmlsZUluZm8gbmV3RmlsZSwgc3RyaW5nIHBhc3N3b3JkKQogICAgICAgIHsKICAgICAgICAgICAgSW5pdCgpOwogICAgICAgICAgICBGaWxlID0gbmV3RmlsZTsKICAgICAgICAgICAgQ29uc3RydWN0TmV3RmlsZShwYXNzd29yZCk7CiAgICAgICAgfQoJCS8vLyA8c3VtbWFyeT4KCQkvLy8gQ3JlYXRlIGEgbmV3IGluc3RhbmNlIG9mIHRoZSBFeGNlbFBhY2thZ2UgY2xhc3MgYmFzZWQgb24gYSBleGlzdGluZyB0ZW1wbGF0ZS4KCQkvLy8gSWYgbmV3RmlsZSBleGlzdHMsIGl0IHdpbGwgYmUgb3ZlcndyaXR0ZW4gd2hlbiB0aGUgU2F2ZSBtZXRob2QgaXMgY2FsbGVkCgkJLy8vIDwvc3VtbWFyeT4KCQkvLy8gPHBhcmFtIG5hbWU9Im5ld0ZpbGUiPlRoZSBuYW1lIG9mIHRoZSBFeGNlbCBmaWxlIHRvIGJlIGNyZWF0ZWQ8L3BhcmFtPgoJCS8vLyA8cGFyYW0gbmFtZT0idGVtcGxhdGUiPlRoZSBuYW1lIG9mIHRoZSBFeGNlbCB0ZW1wbGF0ZSB0byB1c2UgYXMgdGhlIGJhc2lzIG9mIHRoZSBuZXcgRXhjZWwgZmlsZTwvcGFyYW0+CgkJcHVibGljIEV4Y2VsUGFja2FnZShGaWxlSW5mbyBuZXdGaWxlLCBGaWxlSW5mbyB0ZW1wbGF0ZSkKCQl7CiAgICAgICAgICAgIEluaXQoKTsKICAgICAgICAgICAgRmlsZSA9IG5ld0ZpbGU7CiAgICAgICAgICAgIENyZWF0ZUZyb21UZW1wbGF0ZSh0ZW1wbGF0ZSwgbnVsbCk7CgkJfQogICAgICAgIC8vLyA8c3VtbWFyeT4KICAgICAgICAvLy8gQ3JlYXRlIGEgbmV3IGluc3RhbmNlIG9mIHRoZSBFeGNlbFBhY2thZ2UgY2xhc3MgYmFzZWQgb24gYSBleGlzdGluZyB0ZW1wbGF0ZS4KICAgICAgICAvLy8gSWYgbmV3RmlsZSBleGlzdHMsIGl0IHdpbGwgYmUgb3ZlcndyaXR0ZW4gd2hlbiB0aGUgU2F2ZSBtZXRob2QgaXMgY2FsbGVkCiAgICAgICAgLy8vIDwvc3VtbWFyeT4KICAgICAgICAvLy8gPHBhcmFtIG5hbWU9Im5ld0ZpbGUiPlRoZSBuYW1lIG9mIHRoZSBFeGNlbCBmaWxlIHRvIGJlIGNyZWF0ZWQ8L3BhcmFtPgogICAgICAgIC8vLyA8cGFyYW0gbmFtZT0idGVtcGxhdGUiPlRoZSBuYW1lIG9mIHRoZSBFeGNlbCB0ZW1wbGF0ZSB0byB1c2UgYXMgdGhlIGJhc2lzIG9mIHRoZSBuZXcgRXhjZWwgZmlsZTwvcGFyYW0+CiAgICAgICAgLy8vIDxwYXJhbSBuYW1lPSJwYXNzd29yZCI+UGFzc3dvcmQgdG8gZGVjcnlwdGVkIHRoZSB0ZW1wbGF0ZTwvcGFyYW0+CiAgICAgICAgcHVibGljIEV4Y2VsUGFja2FnZShGaWxlSW5mbyBuZXdGaWxlLCBGaWxlSW5mbyB0ZW1wbGF0ZSwgc3RyaW5nIHBhc3N3b3JkKQogICAgICAgIHsKICAgICAgICAgICAgSW5pdCgpOwogICAgICAgICAgICBGaWxlID0gbmV3RmlsZTsKICAgICAgICAgICAgQ3JlYXRlRnJvbVRlbXBsYXRlKHRlbXBsYXRlLCBwYXNzd29yZCk7CiAgICAgICAgfQogICAgICAgIC8vLyA8c3VtbWFyeT4KICAgICAgICAvLy8gQ3JlYXRlIGEgbmV3IGluc3RhbmNlIG9mIHRoZSBFeGNlbFBhY2thZ2UgY2xhc3MgYmFzZWQgb24gYSBleGlzdGluZyB0ZW1wbGF0ZS4KICAgICAgICAvLy8gPC9zdW1tYXJ5PgogICAgICAgIC8vLyA8cGFyYW0gbmFtZT0idGVtcGxhdGUiPlRoZSBuYW1lIG9mIHRoZSBFeGNlbCB0ZW1wbGF0ZSB0byB1c2UgYXMgdGhlIGJhc2lzIG9mIHRoZSBuZXcgRXhjZWwgZmlsZTwvcGFyYW0+CiAgICAgICAgLy8vIDxwYXJhbSBuYW1lPSJ1c2VTdHJlYW0iPmlmIHRydWUgdXNlIGEgc3RyZWFtLiBJZiBmYWxzZSBjcmVhdGUgYSBmaWxlIGluIHRoZSB0ZW1wIGRpciB3aXRoIGEgcmFuZG9tIG5hbWU8L3BhcmFtPgogICAgICAgIHB1YmxpYyBFeGNlbFBhY2thZ2UoRmlsZUluZm8gdGVtcGxhdGUsIGJvb2wgdXNlU3RyZWFtKQogICAgICAgIHsKICAgICAgICAgICAgSW5pdCgpOwogICAgICAgICAgICBDcmVhdGVGcm9tVGVtcGxhdGUodGVtcGxhdGUsIG51bGwpOwogICAgICAgICAgICBpZiAodXNlU3RyZWFtID09IGZhbHNlKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBGaWxlID0gbmV3IEZpbGVJbmZvKFBhdGguR2V0VGVtcFBhdGgoKSArIEd1aWQuTmV3R3VpZCgpLlRvU3RyaW5nKCkgKyAiLnhsc3giKTsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgICAgICAvLy8gPHN1bW1hcnk+CiAgICAgICAgLy8vIENyZWF0ZSBhIG5ldyBpbnN0YW5jZSBvZiB0aGUgRXhjZWxQYWNrYWdlIGNsYXNzIGJhc2VkIG9uIGEgZXhpc3RpbmcgdGVtcGxhdGUuCiAgICAgICAgLy8vIDwvc3VtbWFyeT4KICAgICAgICAvLy8gPHBhcmFtIG5hbWU9InRlbXBsYXRlIj5UaGUgbmFtZSBvZiB0aGUgRXhjZWwgdGVtcGxhdGUgdG8gdXNlIGFzIHRoZSBiYXNpcyBvZiB0aGUgbmV3IEV4Y2VsIGZpbGU8L3BhcmFtPgogICAgICAgIC8vLyA8cGFyYW0gbmFtZT0idXNlU3RyZWFtIj5pZiB0cnVlIHVzZSBhIHN0cmVhbS4gSWYgZmFsc2UgY3JlYXRlIGEgZmlsZSBpbiB0aGUgdGVtcCBkaXIgd2l0aCBhIHJhbmRvbSBuYW1lPC9wYXJhbT4KICAgICAgICAvLy8gPHBhcmFtIG5hbWU9InBhc3N3b3JkIj5QYXNzd29yZCB0byBkZWNyeXB0ZWQgdGhlIHRlbXBsYXRlPC9wYXJhbT4KICAgICAgICBwdWJsaWMgRXhjZWxQYWNrYWdlKEZpbGVJbmZvIHRlbXBsYXRlLCBib29sIHVzZVN0cmVhbSwgc3RyaW5nIHBhc3N3b3JkKQogICAgICAgIHsKICAgICAgICAgICAgSW5pdCgpOwogICAgICAgICAgICBDcmVhdGVGcm9tVGVtcGxhdGUodGVtcGxhdGUsIHBhc3N3b3JkKTsKICAgICAgICAgICAgaWYgKHVzZVN0cmVhbSA9PSBmYWxzZSkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgRmlsZSA9IG5ldyBGaWxlSW5mbyhQYXRoLkdldFRlbXBQYXRoKCkgKyBHdWlkLk5ld0d1aWQoKS5Ub1N0cmluZygpICsgIi54bHN4Iik7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgLy8vIDxzdW1tYXJ5PgogICAgICAgIC8vLyBDcmVhdGUgYSBuZXcgaW5zdGFuY2Ugb2YgdGhlIEV4Y2VsUGFja2FnZSBjbGFzcyBiYXNlZCBvbiBhIHN0cmVhbQogICAgICAgIC8vLyA8L3N1bW1hcnk+CiAgICAgICAgLy8vIDxwYXJhbSBuYW1lPSJuZXdTdHJlYW0iPlRoZSBzdHJlYW0gb2JqZWN0IGNhbiBiZSBlbXB0eSBvciBjb250YWluIGEgcGFja2FnZS4gVGhlIHN0cmVhbSBtdXN0IGJlIFJlYWQvV3JpdGU8L3BhcmFtPgogICAgICAgIHB1YmxpYyBFeGNlbFBhY2thZ2UoU3RyZWFtIG5ld1N0cmVhbSkgCiAgICAgICAgewogICAgICAgICAgICBJbml0KCk7CiAgICAgICAgICAgIGlmIChuZXdTdHJlYW0uTGVuZ3RoID09IDApCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIF9zdHJlYW0gPSBuZXdTdHJlYW07CiAgICAgICAgICAgICAgICBfaXNFeHRlcm5hbFN0cmVhbSA9IHRydWU7CiAgICAgICAgICAgICAgICBDb25zdHJ1Y3ROZXdGaWxlKG51bGwpOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGVsc2UKICAgICAgICAgICAgeyAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgIExvYWQobmV3U3RyZWFtKTsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgICAgICAvLy8gPHN1bW1hcnk+CiAgICAgICAgLy8vIENyZWF0ZSBhIG5ldyBpbnN0YW5jZSBvZiB0aGUgRXhjZWxQYWNrYWdlIGNsYXNzIGJhc2VkIG9uIGEgc3RyZWFtCiAgICAgICAgLy8vIDwvc3VtbWFyeT4KICAgICAgICAvLy8gPHBhcmFtIG5hbWU9Im5ld1N0cmVhbSI+VGhlIHN0cmVhbSBvYmplY3QgY2FuIGJlIGVtcHR5IG9yIGNvbnRhaW4gYSBwYWNrYWdlLiBUaGUgc3RyZWFtIG11c3QgYmUgUmVhZC9Xcml0ZTwvcGFyYW0+CiAgICAgICAgLy8vIDxwYXJhbSBuYW1lPSJQYXNzd29yZCI+VGhlIHBhc3N3b3JkIHRvIGRlY3J5cHQgdGhlIGRvY3VtZW50PC9wYXJhbT4KICAgICAgICBwdWJsaWMgRXhjZWxQYWNrYWdlKFN0cmVhbSBuZXdTdHJlYW0sIHN0cmluZyBQYXNzd29yZCkKICAgICAgICB7CiAgICAgICAgICAgIGlmICghKG5ld1N0cmVhbS5DYW5SZWFkICYmIG5ld1N0cmVhbS5DYW5Xcml0ZSkpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIHRocm93IG5ldyBFeGNlcHRpb24oIlRoZSBzdHJlYW0gbXVzdCBiZSByZWFkL3dyaXRlIik7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIEluaXQoKTsKICAgICAgICAgICAgaWYgKG5ld1N0cmVhbS5MZW5ndGggPiAwKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBMb2FkKG5ld1N0cmVhbSxQYXNzd29yZCk7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgZWxzZQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBfc3RyZWFtID0gbmV3U3RyZWFtOwogICAgICAgICAgICAgICAgX2lzRXh0ZXJuYWxTdHJlYW0gPSB0cnVlOwogICAgICAgICAgICAgICAgLy9fcGFja2FnZSA9IFBhY2thZ2UuT3Blbihfc3RyZWFtLCBGaWxlTW9kZS5DcmVhdGUsIEZpbGVBY2Nlc3MuUmVhZFdyaXRlKTsgVE9ETzpSZW1vdmUKICAgICAgICAgICAgICAgIF9wYWNrYWdlID0gbmV3IFBhY2thZ2luZy5aaXBQYWNrYWdlKF9zdHJlYW0pOwogICAgICAgICAgICAgICAgQ3JlYXRlQmxhbmtXYigpOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIC8vLyA8c3VtbWFyeT4KICAgICAgICAvLy8gQ3JlYXRlIGEgbmV3IGluc3RhbmNlIG9mIHRoZSBFeGNlbFBhY2thZ2UgY2xhc3MgYmFzZWQgb24gYSBzdHJlYW0KICAgICAgICAvLy8gPC9zdW1tYXJ5PgogICAgICAgIC8vLyA8cGFyYW0gbmFtZT0ibmV3U3RyZWFtIj5UaGUgb3V0cHV0IHN0cmVhbS4gTXVzdCBiZSBhbiBlbXB0eSByZWFkL3dyaXRlIHN0cmVhbS48L3BhcmFtPgogICAgICAgIC8vLyA8cGFyYW0gbmFtZT0idGVtcGxhdGVTdHJlYW0iPlRoaXMgc3RyZWFtIGlzIGNvcGllZCB0byB0aGUgb3V0cHV0IHN0cmVhbSBhdCBsb2FkPC9wYXJhbT4KICAgICAgICBwdWJsaWMgRXhjZWxQYWNrYWdlKFN0cmVhbSBuZXdTdHJlYW0sIFN0cmVhbSB0ZW1wbGF0ZVN0cmVhbSkKICAgICAgICB7CiAgICAgICAgICAgIGlmIChuZXdTdHJlYW0uTGVuZ3RoID4gMCkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgdGhyb3cobmV3IEV4Y2VwdGlvbigiVGhlIG91dHB1dCBzdHJlYW0gbXVzdCBiZSBlbXB0eS4gTGVuZ3RoID4gMCIpKTsKICAgICAgICAgICAgfQogICAgICAgICAgICBlbHNlIGlmICghKG5ld1N0cmVhbS5DYW5SZWFkICYmIG5ld1N0cmVhbS5DYW5Xcml0ZSkpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIHRocm93IG5ldyBFeGNlcHRpb24oIlRoZSBzdHJlYW0gbXVzdCBiZSByZWFkL3dyaXRlIik7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgSW5pdCgpOwogICAgICAgICAgICBMb2FkKHRlbXBsYXRlU3RyZWFtLCBuZXdTdHJlYW0sIG51bGwpOwogICAgICAgIH0KICAgICAgICAvLy8gPHN1bW1hcnk+CiAgICAgICAgLy8vIENyZWF0ZSBhIG5ldyBpbnN0YW5jZSBvZiB0aGUgRXhjZWxQYWNrYWdlIGNsYXNzIGJhc2VkIG9uIGEgc3RyZWFtCiAgICAgICAgLy8vIDwvc3VtbWFyeT4KICAgICAgICAvLy8gPHBhcmFtIG5hbWU9Im5ld1N0cmVhbSI+VGhlIG91dHB1dCBzdHJlYW0uIE11c3QgYmUgYW4gZW1wdHkgcmVhZC93cml0ZSBzdHJlYW0uPC9wYXJhbT4KICAgICAgICAvLy8gPHBhcmFtIG5hbWU9InRlbXBsYXRlU3RyZWFtIj5UaGlzIHN0cmVhbSBpcyBjb3BpZWQgdG8gdGhlIG91dHB1dCBzdHJlYW0gYXQgbG9hZDwvcGFyYW0+CiAgICAgICAgLy8vIDxwYXJhbSBuYW1lPSJQYXNzd29yZCI+UGFzc3dvcmQgdG8gZGVjcnlwdGVkIHRoZSB0ZW1wbGF0ZTwvcGFyYW0+CiAgICAgICAgcHVibGljIEV4Y2VsUGFja2FnZShTdHJlYW0gbmV3U3RyZWFtLCBTdHJlYW0gdGVtcGxhdGVTdHJlYW0sIHN0cmluZyBQYXNzd29yZCkKICAgICAgICB7CiAgICAgICAgICAgIGlmIChuZXdTdHJlYW0uTGVuZ3RoID4gMCkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgdGhyb3cgKG5ldyBFeGNlcHRpb24oIlRoZSBvdXRwdXQgc3RyZWFtIG11c3QgYmUgZW1wdHkuIExlbmd0aCA+IDAiKSk7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgZWxzZSBpZiAoIShuZXdTdHJlYW0uQ2FuUmVhZCAmJiBuZXdTdHJlYW0uQ2FuV3JpdGUpKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICB0aHJvdyBuZXcgRXhjZXB0aW9uKCJUaGUgc3RyZWFtIG11c3QgYmUgcmVhZC93cml0ZSIpOwogICAgICAgICAgICB9CiAgICAgICAgICAgIEluaXQoKTsKICAgICAgICAgICAgTG9hZCh0ZW1wbGF0ZVN0cmVhbSwgbmV3U3RyZWFtLCBQYXNzd29yZCk7CiAgICAgICAgfQogICAgICAgICNlbmRyZWdpb24KICAgICAgICBpbnRlcm5hbCBJbWFnZUluZm8gQWRkSW1hZ2UoYnl0ZVtdIGltYWdlKQogICAgICAgIHsKICAgICAgICAgICAgcmV0dXJuIEFkZEltYWdlKGltYWdlLCBudWxsLCAiIik7CiAgICAgICAgfQogICAgICAgIGludGVybmFsIEltYWdlSW5mbyBBZGRJbWFnZShieXRlW10gaW1hZ2UsIFVyaSB1cmksIHN0cmluZyBjb250ZW50VHlwZSkKICAgICAgICB7CiAgICAgICAgICAgIHZhciBoYXNoUHJvdmlkZXIgPSBuZXcgU0hBMUNyeXB0b1NlcnZpY2VQcm92aWRlcigpOwogICAgICAgICAgICB2YXIgaGFzaCA9IEJpdENvbnZlcnRlci5Ub1N0cmluZyhoYXNoUHJvdmlkZXIuQ29tcHV0ZUhhc2goaW1hZ2UpKS5SZXBsYWNlKCItIiwiIik7CiAgICAgICAgICAgIGxvY2sgKF9pbWFnZXMpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIGlmIChfaW1hZ2VzLkNvbnRhaW5zS2V5KGhhc2gpKQogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIF9pbWFnZXNbaGFzaF0uUmVmQ291bnQrKzsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGVsc2UKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICBQYWNrYWdpbmcuWmlwUGFja2FnZVBhcnQgaW1hZ2VQYXJ0OwogICAgICAgICAgICAgICAgICAgIGlmICh1cmkgPT0gbnVsbCkKICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgIHVyaSA9IEdldE5ld1VyaShQYWNrYWdlLCAiL3hsL21lZGlhL2ltYWdlezB9LmpwZyIpOwogICAgICAgICAgICAgICAgICAgICAgICBpbWFnZVBhcnQgPSBQYWNrYWdlLkNyZWF0ZVBhcnQodXJpLCAiaW1hZ2UvanBlZyIsIENvbXByZXNzaW9uTGV2ZWwuTm9uZSk7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIGVsc2UKICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgIGltYWdlUGFydCA9IFBhY2thZ2UuQ3JlYXRlUGFydCh1cmksIGNvbnRlbnRUeXBlLCBDb21wcmVzc2lvbkxldmVsLk5vbmUpOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICB2YXIgc3RyZWFtID0gaW1hZ2VQYXJ0LkdldFN0cmVhbShGaWxlTW9kZS5DcmVhdGUsIEZpbGVBY2Nlc3MuV3JpdGUpOwogICAgICAgICAgICAgICAgICAgIHN0cmVhbS5Xcml0ZShpbWFnZSwgMCwgaW1hZ2UuR2V0TGVuZ3RoKDApKTsKCiAgICAgICAgICAgICAgICAgICAgX2ltYWdlcy5BZGQoaGFzaCwgbmV3IEltYWdlSW5mbygpIHsgVXJpID0gdXJpLCBSZWZDb3VudCA9IDEsIEhhc2ggPSBoYXNoLCBQYXJ0ID0gaW1hZ2VQYXJ0IH0pOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgICAgIHJldHVybiBfaW1hZ2VzW2hhc2hdOwogICAgICAgIH0KICAgICAgICBpbnRlcm5hbCBJbWFnZUluZm8gTG9hZEltYWdlKGJ5dGVbXSBpbWFnZSwgVXJpIHVyaSwgUGFja2FnaW5nLlppcFBhY2thZ2VQYXJ0IGltYWdlUGFydCkKICAgICAgICB7CiAgICAgICAgICAgIHZhciBoYXNoUHJvdmlkZXIgPSBuZXcgU0hBMUNyeXB0b1NlcnZpY2VQcm92aWRlcigpOwogICAgICAgICAgICB2YXIgaGFzaCA9IEJpdENvbnZlcnRlci5Ub1N0cmluZyhoYXNoUHJvdmlkZXIuQ29tcHV0ZUhhc2goaW1hZ2UpKS5SZXBsYWNlKCItIiwgIiIpOwogICAgICAgICAgICBpZiAoX2ltYWdlcy5Db250YWluc0tleShoYXNoKSkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgX2ltYWdlc1toYXNoXS5SZWZDb3VudCsrOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGVsc2UKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgX2ltYWdlcy5BZGQoaGFzaCwgbmV3IEltYWdlSW5mbygpIHsgVXJpID0gdXJpLCBSZWZDb3VudCA9IDEsIEhhc2ggPSBoYXNoLCBQYXJ0ID0gaW1hZ2VQYXJ0IH0pOwogICAgICAgICAgICB9CiAgICAgICAgICAgIHJldHVybiBfaW1hZ2VzW2hhc2hdOwogICAgICAgIH0KICAgICAgICBpbnRlcm5hbCB2b2lkIFJlbW92ZUltYWdlKHN0cmluZyBoYXNoKQogICAgICAgIHsKICAgICAgICAgICAgbG9jayAoX2ltYWdlcykKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgaWYgKF9pbWFnZXMuQ29udGFpbnNLZXkoaGFzaCkpCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgdmFyIGlpID0gX2ltYWdlc1toYXNoXTsKICAgICAgICAgICAgICAgICAgICBpaS5SZWZDb3VudC0tOwogICAgICAgICAgICAgICAgICAgIGlmIChpaS5SZWZDb3VudCA9PSAwKQogICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgUGFja2FnZS5EZWxldGVQYXJ0KGlpLlVyaSk7CiAgICAgICAgICAgICAgICAgICAgICAgIF9pbWFnZXMuUmVtb3ZlKGhhc2gpOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgIH0KICAgICAgICBpbnRlcm5hbCBJbWFnZUluZm8gR2V0SW1hZ2VJbmZvKGJ5dGVbXSBpbWFnZSkKICAgICAgICB7CiAgICAgICAgICAgIHZhciBoYXNoUHJvdmlkZXIgPSBuZXcgU0hBMUNyeXB0b1NlcnZpY2VQcm92aWRlcigpOwogICAgICAgICAgICB2YXIgaGFzaCA9IEJpdENvbnZlcnRlci5Ub1N0cmluZyhoYXNoUHJvdmlkZXIuQ29tcHV0ZUhhc2goaW1hZ2UpKS5SZXBsYWNlKCItIiwiIik7CgogICAgICAgICAgICBpZiAoX2ltYWdlcy5Db250YWluc0tleShoYXNoKSkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgcmV0dXJuIF9pbWFnZXNbaGFzaF07CiAgICAgICAgICAgIH0KICAgICAgICAgICAgZWxzZQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICByZXR1cm4gbnVsbDsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgICAgICBwcml2YXRlIFVyaSBHZXROZXdVcmkoUGFja2FnaW5nLlppcFBhY2thZ2UgcGFja2FnZSwgc3RyaW5nIHNVcmkpCiAgICAgICAgewogICAgICAgICAgICBpbnQgaWQgPSAxOwogICAgICAgICAgICBVcmkgdXJpOwogICAgICAgICAgICBkbwogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICB1cmkgPSBuZXcgVXJpKHN0cmluZy5Gb3JtYXQoc1VyaSwgaWQrKyksIFVyaUtpbmQuUmVsYXRpdmUpOwogICAgICAgICAgICB9CiAgICAgICAgICAgIHdoaWxlIChwYWNrYWdlLlBhcnRFeGlzdHModXJpKSk7CiAgICAgICAgICAgIHJldHVybiB1cmk7CiAgICAgICAgfQogICAgICAgIC8vLyA8c3VtbWFyeT4KICAgICAgICAvLy8gSW5pdCB2YWx1ZXMgaGVyZQogICAgICAgIC8vLyA8L3N1bW1hcnk+CiAgICAgICAgcHJpdmF0ZSB2b2lkIEluaXQoKQogICAgICAgIHsKICAgICAgICAgICAgRG9BZGp1c3REcmF3aW5ncyA9IHRydWU7CiAgICAgICAgfQogICAgICAgIC8vLyA8c3VtbWFyeT4KICAgICAgICAvLy8gQ3JlYXRlIGEgbmV3IGZpbGUgZnJvbSBhIHRlbXBsYXRlCiAgICAgICAgLy8vIDwvc3VtbWFyeT4KICAgICAgICAvLy8gPHBhcmFtIG5hbWU9InRlbXBsYXRlIj5BbiBleGlzdGluZyB4bHN4IGZpbGUgdG8gdXNlIGFzIGEgdGVtcGxhdGU8L3BhcmFtPgogICAgICAgIC8vLyA8cGFyYW0gbmFtZT0icGFzc3dvcmQiPlRoZSBwYXNzd29yZCB0byBkZWNyeXB0IHRoZSBwYWNrYWdlLjwvcGFyYW0+CiAgICAgICAgLy8vIDxyZXR1cm5zPjwvcmV0dXJucz4KICAgICAgICBwcml2YXRlIHZvaWQgQ3JlYXRlRnJvbVRlbXBsYXRlKEZpbGVJbmZvIHRlbXBsYXRlLCBzdHJpbmcgcGFzc3dvcmQpCiAgICAgICAgewogICAgICAgICAgICBpZiAodGVtcGxhdGUgIT0gbnVsbCkgdGVtcGxhdGUuUmVmcmVzaCgpOwogICAgICAgICAgICBpZiAodGVtcGxhdGUuRXhpc3RzKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBpZihfc3RyZWFtPT1udWxsKSBfc3RyZWFtPW5ldyBNZW1vcnlTdHJlYW0oKTsKICAgICAgICAgICAgICAgIHZhciBtcyA9IG5ldyBNZW1vcnlTdHJlYW0oKTsKICAgICAgICAgICAgICAgIGlmIChwYXNzd29yZCAhPSBudWxsKQogICAgICAgICAgICAgICAgewojaWYgIU1PTk8KICAgICAgICAgICAgICAgICAgICBFbmNyeXB0aW9uLklzRW5jcnlwdGVkID0gdHJ1ZTsKICAgICAgICAgICAgICAgICAgICBFbmNyeXB0aW9uLlBhc3N3b3JkID0gcGFzc3dvcmQ7CiAgICAgICAgICAgICAgICAgICAgdmFyIGVuY3JIYW5kbGVyID0gbmV3IEVuY3J5cHRlZFBhY2thZ2VIYW5kbGVyKCk7CiAgICAgICAgICAgICAgICAgICAgbXMgPSBlbmNySGFuZGxlci5EZWNyeXB0UGFja2FnZSh0ZW1wbGF0ZSwgRW5jcnlwdGlvbik7CiAgICAgICAgICAgICAgICAgICAgZW5jckhhbmRsZXIgPSBudWxsOwojZW5kaWYKI2lmIE1PTk8KCSAgICAgICAgICAgICAgICB0aHJvdyAobmV3IE5vdEltcGxlbWVudGVkRXhjZXB0aW9uKCJObyBzdXBwb3J0IGZvciBFbmNyeXB0ZWQgcGFja2FnZXMgaW4gTW9ubyIpKTsKI2VuZGlmCgkgICAgICAgICAgICAgICAgLy90aHJvdyAobmV3IE5vdEltcGxlbWVudGVkRXhjZXB0aW9uKCJObyBzdXBwb3J0IGZvciBFbmNyeXB0ZWQgcGFja2FnZXMgaW4gdGhpcyB2ZXJzaW9uIikpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgZWxzZQogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIGJ5dGVbXSBiID0gU3lzdGVtLklPLkZpbGUuUmVhZEFsbEJ5dGVzKHRlbXBsYXRlLkZ1bGxOYW1lKTsKICAgICAgICAgICAgICAgICAgICBtcy5Xcml0ZShiLCAwLCBiLkxlbmd0aCk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB0cnkKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAvL19wYWNrYWdlID0gUGFja2FnZS5PcGVuKF9zdHJlYW0sIEZpbGVNb2RlLk9wZW4sIEZpbGVBY2Nlc3MuUmVhZFdyaXRlKTsKICAgICAgICAgICAgICAgICAgICBfcGFja2FnZSA9IG5ldyBQYWNrYWdpbmcuWmlwUGFja2FnZShtcyk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBjYXRjaCAoRXhjZXB0aW9uIGV4KQogICAgICAgICAgICAgICAgewojaWYgIU1PTk8KICAgICAgICAgICAgICAgICAgICBpZiAocGFzc3dvcmQgPT0gbnVsbCAmJiBDb21wb3VuZERvY3VtZW50LklzU3RvcmFnZUZpbGUodGVtcGxhdGUuRnVsbE5hbWUpPT0wKQogICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgdGhyb3cgbmV3IEV4Y2VwdGlvbigiQ2FuIG5vdCBvcGVuIHRoZSBwYWNrYWdlLiBQYWNrYWdlIGlzIGFuIE9MRSBjb21wb3VuZCBkb2N1bWVudC4gSWYgdGhpcyBpcyBhbiBlbmNyeXB0ZWQgcGFja2FnZSwgcGxlYXNlIHN1cHBseSB0aGUgcGFzc3dvcmQiLCBleCk7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIGVsc2UKICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgIHRocm93OwogICAgICAgICAgICAgICAgICAgIH0KI2VuZGlmCiNpZiBNT05PCiAgICAgICAgICAgICAgICAgICAgdGhyb3c7CiNlbmRpZgogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgICAgIGVsc2UKICAgICAgICAgICAgICAgIHRocm93IG5ldyBFeGNlcHRpb24oIlBhc3NlZCBpbnZhbGlkIFRlbXBsYXRlUGF0aCB0byBFeGNlbCBUZW1wbGF0ZSIpOwogICAgICAgICAgICAvL3JldHVybiBuZXdGaWxlOwogICAgICAgIH0KICAgICAgICBwcml2YXRlIHZvaWQgQ29uc3RydWN0TmV3RmlsZShzdHJpbmcgcGFzc3dvcmQpCiAgICAgICAgewogICAgICAgICAgICB2YXIgbXMgPSBuZXcgTWVtb3J5U3RyZWFtKCk7CiAgICAgICAgICAgIGlmIChfc3RyZWFtID09IG51bGwpIF9zdHJlYW0gPSBuZXcgTWVtb3J5U3RyZWFtKCk7CiAgICAgICAgICAgIGlmIChGaWxlICE9IG51bGwpIEZpbGUuUmVmcmVzaCgpOwogICAgICAgICAgICBpZiAoRmlsZSAhPSBudWxsICYmIEZpbGUuRXhpc3RzKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBpZiAocGFzc3dvcmQgIT0gbnVsbCkKICAgICAgICAgICAgICAgIHsKI2lmICFNT05PCiAgICAgICAgICAgICAgICAgICAgdmFyIGVuY3JIYW5kbGVyID0gbmV3IEVuY3J5cHRlZFBhY2thZ2VIYW5kbGVyKCk7CiAgICAgICAgICAgICAgICAgICAgRW5jcnlwdGlvbi5Jc0VuY3J5cHRlZCA9IHRydWU7CiAgICAgICAgICAgICAgICAgICAgRW5jcnlwdGlvbi5QYXNzd29yZCA9IHBhc3N3b3JkOwogICAgICAgICAgICAgICAgICAgIG1zID0gZW5jckhhbmRsZXIuRGVjcnlwdFBhY2thZ2UoRmlsZSwgRW5jcnlwdGlvbik7CiAgICAgICAgICAgICAgICAgICAgZW5jckhhbmRsZXIgPSBudWxsOwojZW5kaWYKI2lmIE1PTk8KICAgICAgICAgICAgICAgICAgICB0aHJvdyBuZXcgTm90SW1wbGVtZW50ZWRFeGNlcHRpb24oIk5vIHN1cHBvcnQgZm9yIEVuY3J5cHRlZCBwYWNrYWdlcyBpbiBNb25vIik7CiNlbmRpZgogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgZWxzZQogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIGJ5dGVbXSBiID0gU3lzdGVtLklPLkZpbGUuUmVhZEFsbEJ5dGVzKEZpbGUuRnVsbE5hbWUpOwogICAgICAgICAgICAgICAgICAgIG1zLldyaXRlKGIsIDAsIGIuTGVuZ3RoKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIHRyeQogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIC8vX3BhY2thZ2UgPSBQYWNrYWdlLk9wZW4oX3N0cmVhbSwgRmlsZU1vZGUuT3BlbiwgRmlsZUFjY2Vzcy5SZWFkV3JpdGUpOwogICAgICAgICAgICAgICAgICAgIF9wYWNrYWdlID0gbmV3IFBhY2thZ2luZy5aaXBQYWNrYWdlKG1zKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGNhdGNoIChFeGNlcHRpb24gZXgpCiAgICAgICAgICAgICAgIHsKI2lmICFNT05PCiAgICAgICAgICAgICAgICAgICAgaWYgKHBhc3N3b3JkID09IG51bGwgJiYgQ29tcG91bmREb2N1bWVudC5Jc1N0b3JhZ2VGaWxlKEZpbGUuRnVsbE5hbWUpPT0wKQogICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgdGhyb3cgbmV3IEV4Y2VwdGlvbigiQ2FuIG5vdCBvcGVuIHRoZSBwYWNrYWdlLiBQYWNrYWdlIGlzIGFuIE9MRSBjb21wb3VuZCBkb2N1bWVudC4gSWYgdGhpcyBpcyBhbiBlbmNyeXB0ZWQgcGFja2FnZSwgcGxlYXNlIHN1cHBseSB0aGUgcGFzc3dvcmQiLCBleCk7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIGVsc2UKICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgIHRocm93OwogICAgICAgICAgICAgICAgICAgIH0KI2VuZGlmCiNpZiBNT05PCiAgICAgICAgICAgICAgICAgICAgdGhyb3c7CiNlbmRpZgogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgICAgIGVsc2UKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgLy9fcGFja2FnZSA9IFBhY2thZ2UuT3Blbihfc3RyZWFtLCBGaWxlTW9kZS5DcmVhdGUsIEZpbGVBY2Nlc3MuUmVhZFdyaXRlKTsKICAgICAgICAgICAgICAgIF9wYWNrYWdlID0gbmV3IFBhY2thZ2luZy5aaXBQYWNrYWdlKG1zKTsKICAgICAgICAgICAgICAgIENyZWF0ZUJsYW5rV2IoKTsKICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgcHJpdmF0ZSB2b2lkIENyZWF0ZUJsYW5rV2IoKQogICAgICAgIHsKICAgICAgICAgICAgWG1sRG9jdW1lbnQgd29ya2Jvb2sgPSBXb3JrYm9vay5Xb3JrYm9va1htbDsgLy8gdGhpcyB3aWxsIGNyZWF0ZSB0aGUgd29ya2Jvb2sgeG1sIGluIHRoZSBwYWNrYWdlCiAgICAgICAgICAgIC8vIGNyZWF0ZSB0aGUgcmVsYXRpb25zaGlwIHRvIHRoZSBtYWluIHBhcnQKICAgICAgICAgICAgX3BhY2thZ2UuQ3JlYXRlUmVsYXRpb25zaGlwKFVyaUhlbHBlci5HZXRSZWxhdGl2ZVVyaShuZXcgVXJpKCIveGwiLCBVcmlLaW5kLlJlbGF0aXZlKSwgV29ya2Jvb2suV29ya2Jvb2tVcmkpLCBQYWNrYWdpbmcuVGFyZ2V0TW9kZS5JbnRlcm5hbCwgc2NoZW1hUmVsYXRpb25zaGlwcyArICIvb2ZmaWNlRG9jdW1lbnQiKTsKICAgICAgICB9CgoJCS8vLyA8c3VtbWFyeT4KCQkvLy8gUmV0dXJucyBhIHJlZmVyZW5jZSB0byB0aGUgcGFja2FnZQoJCS8vLyA8L3N1bW1hcnk+CgkJcHVibGljIFBhY2thZ2luZy5aaXBQYWNrYWdlIFBhY2thZ2UgeyBnZXQgeyByZXR1cm4gKF9wYWNrYWdlKTsgfSB9CiAgICAgICAgRXhjZWxFbmNyeXB0aW9uIF9lbmNyeXB0aW9uPW51bGw7CiAgICAgICAgLy8vIDxzdW1tYXJ5PgogICAgICAgIC8vLyBJbmZvcm1hdGlvbiBob3cgYW5kIGlmIHRoZSBwYWNrYWdlIGlzIGVuY3J5cHRlZAogICAgICAgIC8vLyA8L3N1bW1hcnk+CiAgICAgICAgcHVibGljIEV4Y2VsRW5jcnlwdGlvbiBFbmNyeXB0aW9uCiAgICAgICAgewogICAgICAgICAgICBnZXQKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgaWYgKF9lbmNyeXB0aW9uID09IG51bGwpCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgX2VuY3J5cHRpb24gPSBuZXcgRXhjZWxFbmNyeXB0aW9uKCk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICByZXR1cm4gX2VuY3J5cHRpb247CiAgICAgICAgICAgIH0KICAgICAgICB9CgkJLy8vIDxzdW1tYXJ5PgoJCS8vLyBSZXR1cm5zIGEgcmVmZXJlbmNlIHRvIHRoZSB3b3JrYm9vayBjb21wb25lbnQgd2l0aGluIHRoZSBwYWNrYWdlLgoJCS8vLyBBbGwgd29ya3NoZWV0cyBhbmQgY2VsbHMgY2FuIGJlIGFjY2Vzc2VkIHRocm91Z2ggdGhlIHdvcmtib29rLgoJCS8vLyA8L3N1bW1hcnk+CgkJcHVibGljIEV4Y2VsV29ya2Jvb2sgV29ya2Jvb2sKCQl7CgkJCWdldAoJCQl7CiAgICAgICAgICAgICAgICBpZiAoX3dvcmtib29rID09IG51bGwpCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgdmFyIG5zbSA9IENyZWF0ZURlZmF1bHROU00oKTsKCiAgICAgICAgICAgICAgICAgICAgX3dvcmtib29rID0gbmV3IEV4Y2VsV29ya2Jvb2sodGhpcywgbnNtKTsKCiAgICAgICAgICAgICAgICAgICAgX3dvcmtib29rLkdldEV4dGVybmFsUmVmZXJlbmNlcygpOwogICAgICAgICAgICAgICAgICAgIF93b3JrYm9vay5HZXREZWZpbmVkTmFtZXMoKTsKCiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICByZXR1cm4gKF93b3JrYm9vayk7CgkJCX0KCQl9CiAgICAgICAgLy8vIDxzdW1tYXJ5PgogICAgICAgIC8vLyBBdXRvbWF0aWNsbHkgYWRqdXN0IGRyYXdpbmcgc2l6ZSB3aGVuIGNvbHVtbiB3aWR0aC9yb3cgaGVpZ2h0IGFyZSBhZGp1c3RlZCwgZGVwZW5kaW5nIG9uIHRoZSBkcmF3aW5ncyBlZGl0QnkgcHJvcGVydHkuCiAgICAgICAgLy8vIERlZmF1bHQgVHJ1ZQogICAgICAgIC8vLyA8L3N1bW1hcnk+CiAgICAgICAgcHVibGljIGJvb2wgRG9BZGp1c3REcmF3aW5ncwogICAgICAgIHsKICAgICAgICAgICAgZ2V0OwogICAgICAgICAgICBzZXQ7CiAgICAgICAgfQogICAgICAgIHByaXZhdGUgWG1sTmFtZXNwYWNlTWFuYWdlciBDcmVhdGVEZWZhdWx0TlNNKCkKICAgICAgICB7CiAgICAgICAgICAgIC8vICBDcmVhdGUgYSBOYW1lc3BhY2VNYW5hZ2VyIHRvIGhhbmRsZSB0aGUgZGVmYXVsdCBuYW1lc3BhY2UsIAogICAgICAgICAgICAvLyAgYW5kIGNyZWF0ZSBhIHByZWZpeCBmb3IgdGhlIGRlZmF1bHQgbmFtZXNwYWNlOgogICAgICAgICAgICBOYW1lVGFibGUgbnQgPSBuZXcgTmFtZVRhYmxlKCk7CiAgICAgICAgICAgIHZhciBucyA9IG5ldyBYbWxOYW1lc3BhY2VNYW5hZ2VyKG50KTsKICAgICAgICAgICAgbnMuQWRkTmFtZXNwYWNlKHN0cmluZy5FbXB0eSwgRXhjZWxQYWNrYWdlLnNjaGVtYU1haW4pOwogICAgICAgICAgICBucy5BZGROYW1lc3BhY2UoImQiLCBFeGNlbFBhY2thZ2Uuc2NoZW1hTWFpbik7CiAgICAgICAgICAgIG5zLkFkZE5hbWVzcGFjZSgiciIsIEV4Y2VsUGFja2FnZS5zY2hlbWFSZWxhdGlvbnNoaXBzKTsKICAgICAgICAgICAgbnMuQWRkTmFtZXNwYWNlKCJjIiwgRXhjZWxQYWNrYWdlLnNjaGVtYUNoYXJ0KTsKICAgICAgICAgICAgbnMuQWRkTmFtZXNwYWNlKCJ2dCIsIHNjaGVtYVZ0KTsKICAgICAgICAgICAgLy8gZXh0ZW5kZWQgcHJvcGVydGllcyAoYXBwLnhtbCkKICAgICAgICAgICAgbnMuQWRkTmFtZXNwYWNlKCJ4cCIsIHNjaGVtYUV4dGVuZGVkKTsKICAgICAgICAgICAgLy8gY3VzdG9tIHByb3BlcnRpZXMKICAgICAgICAgICAgbnMuQWRkTmFtZXNwYWNlKCJjdHAiLCBzY2hlbWFDdXN0b20pOwogICAgICAgICAgICAvLyBjb3JlIHByb3BlcnRpZXMKICAgICAgICAgICAgbnMuQWRkTmFtZXNwYWNlKCJjcCIsIHNjaGVtYUNvcmUpOwogICAgICAgICAgICAvLyBjb3JlIHByb3BlcnR5IG5hbWVzcGFjZXMgCiAgICAgICAgICAgIG5zLkFkZE5hbWVzcGFjZSgiZGMiLCBzY2hlbWFEYyk7CiAgICAgICAgICAgIG5zLkFkZE5hbWVzcGFjZSgiZGN0ZXJtcyIsIHNjaGVtYURjVGVybXMpOwogICAgICAgICAgICBucy5BZGROYW1lc3BhY2UoImRjbWl0eXBlIiwgc2NoZW1hRGNtaVR5cGUpOwogICAgICAgICAgICBucy5BZGROYW1lc3BhY2UoInhzaSIsIHNjaGVtYVhzaSk7CiAgICAgICAgICAgIHJldHVybiBuczsKICAgICAgICB9CgkJCgkJI3JlZ2lvbiBTYXZlUGFydAoJCS8vLyA8c3VtbWFyeT4KCQkvLy8gU2F2ZXMgdGhlIFhtbERvY3VtZW50IGludG8gdGhlIHBhY2thZ2UgYXQgdGhlIHNwZWNpZmllZCBVcmkuCgkJLy8vIDwvc3VtbWFyeT4KCQkvLy8gPHBhcmFtIG5hbWU9InVyaSI+VGhlIFVyaSBvZiB0aGUgY29tcG9uZW50PC9wYXJhbT4KCQkvLy8gPHBhcmFtIG5hbWU9InhtbERvYyI+VGhlIFhtbERvY3VtZW50IHRvIHNhdmU8L3BhcmFtPgoJCWludGVybmFsIHZvaWQgU2F2ZVBhcnQoVXJpIHVyaSwgWG1sRG9jdW1lbnQgeG1sRG9jKQoJCXsKICAgICAgICAgICAgUGFja2FnaW5nLlppcFBhY2thZ2VQYXJ0IHBhcnQgPSBfcGFja2FnZS5HZXRQYXJ0KHVyaSk7CgkJCXhtbERvYy5TYXZlKHBhcnQuR2V0U3RyZWFtKEZpbGVNb2RlLkNyZWF0ZSwgRmlsZUFjY2Vzcy5Xcml0ZSkpOwoJCX0KICAgICAgICAvLy8gPHN1bW1hcnk+CgkJLy8vIFNhdmVzIHRoZSBYbWxEb2N1bWVudCBpbnRvIHRoZSBwYWNrYWdlIGF0IHRoZSBzcGVjaWZpZWQgVXJpLgoJCS8vLyA8L3N1bW1hcnk+CgkJLy8vIDxwYXJhbSBuYW1lPSJ1cmkiPlRoZSBVcmkgb2YgdGhlIGNvbXBvbmVudDwvcGFyYW0+CgkJLy8vIDxwYXJhbSBuYW1lPSJ4bWxEb2MiPlRoZSBYbWxEb2N1bWVudCB0byBzYXZlPC9wYXJhbT4KICAgICAgICBpbnRlcm5hbCB2b2lkIFNhdmVXb3JrYm9vayhVcmkgdXJpLCBYbWxEb2N1bWVudCB4bWxEb2MpCgkJewogICAgICAgICAgICBQYWNrYWdpbmcuWmlwUGFja2FnZVBhcnQgcGFydCA9IF9wYWNrYWdlLkdldFBhcnQodXJpKTsKICAgICAgICAgICAgaWYoV29ya2Jvb2suVmJhUHJvamVjdD09bnVsbCkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgaWYgKHBhcnQuQ29udGVudFR5cGUgIT0gY29udGVudFR5cGVXb3JrYm9va0RlZmF1bHQpCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgcGFydCA9IF9wYWNrYWdlLkNyZWF0ZVBhcnQodXJpLCBjb250ZW50VHlwZVdvcmtib29rRGVmYXVsdCwgQ29tcHJlc3Npb24pOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgICAgIGVsc2UKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgaWYgKHBhcnQuQ29udGVudFR5cGUgIT0gY29udGVudFR5cGVXb3JrYm9va01hY3JvRW5hYmxlZCkKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICB2YXIgcmVscyA9IHBhcnQuR2V0UmVsYXRpb25zaGlwcygpOwogICAgICAgICAgICAgICAgICAgIF9wYWNrYWdlLkRlbGV0ZVBhcnQodXJpKTsKICAgICAgICAgICAgICAgICAgICBwYXJ0ID0gUGFja2FnZS5DcmVhdGVQYXJ0KHVyaSwgY29udGVudFR5cGVXb3JrYm9va01hY3JvRW5hYmxlZCk7CiAgICAgICAgICAgICAgICAgICAgZm9yZWFjaCAodmFyIHJlbCBpbiByZWxzKQogICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgUGFja2FnZS5EZWxldGVSZWxhdGlvbnNoaXAocmVsLklkKTsKICAgICAgICAgICAgICAgICAgICAgICAgcGFydC5DcmVhdGVSZWxhdGlvbnNoaXAocmVsLlRhcmdldFVyaSwgcmVsLlRhcmdldE1vZGUsIHJlbC5SZWxhdGlvbnNoaXBUeXBlKTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KCQkJeG1sRG9jLlNhdmUocGFydC5HZXRTdHJlYW0oRmlsZU1vZGUuQ3JlYXRlLCBGaWxlQWNjZXNzLldyaXRlKSk7CgkJfQoKICAgICAgICAjZW5kcmVnaW9uCgoJCSNyZWdpb24gRGlzcG9zZQoJCS8vLyA8c3VtbWFyeT4KCQkvLy8gQ2xvc2VzIHRoZSBwYWNrYWdlLgoJCS8vLyA8L3N1bW1hcnk+CgkJcHVibGljIHZvaWQgRGlzcG9zZSgpCgkJewogICAgICAgICAgICBpZihfcGFja2FnZSAhPSBudWxsKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBpZiAoX2lzRXh0ZXJuYWxTdHJlYW09PWZhbHNlICYmIFN0cmVhbSAhPSBudWxsICYmIChTdHJlYW0uQ2FuUmVhZCB8fCBTdHJlYW0uQ2FuV3JpdGUpKQogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIFN0cmVhbS5DbG9zZSgpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgX3BhY2thZ2UuQ2xvc2UoKTsKICAgICAgICAgICAgICAgIGlmKF9pc0V4dGVybmFsU3RyZWFtPT1mYWxzZSkgKChJRGlzcG9zYWJsZSlfc3RyZWFtKS5EaXNwb3NlKCk7CiAgICAgICAgICAgICAgICBpZihfd29ya2Jvb2sgIT0gbnVsbCkKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICBfd29ya2Jvb2suRGlzcG9zZSgpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgX3BhY2thZ2UgPSBudWxsOwogICAgICAgICAgICAgICAgX2ltYWdlcyA9IG51bGw7CiAgICAgICAgICAgICAgICBfZmlsZSA9IG51bGw7CiAgICAgICAgICAgICAgICBfd29ya2Jvb2sgPSBudWxsOwogICAgICAgICAgICAgICAgX3N0cmVhbSA9IG51bGw7CiAgICAgICAgICAgICAgICBfd29ya2Jvb2sgPSBudWxsOwogICAgICAgICAgICB9CgkJfQoJCSNlbmRyZWdpb24KCgkJI3JlZ2lvbiBTYXZlICAvLyBFeGNlbFBhY2thZ2Ugc2F2ZQogICAgICAgIC8vLyA8c3VtbWFyeT4KICAgICAgICAvLy8gU2F2ZXMgYWxsIHRoZSBjb21wb25lbnRzIGJhY2sgaW50byB0aGUgcGFja2FnZS4KICAgICAgICAvLy8gVGhpcyBtZXRob2QgcmVjdXJzaXZlbHkgY2FsbHMgdGhlIFNhdmUgbWV0aG9kIG9uIGFsbCBzdWItY29tcG9uZW50cy4KICAgICAgICAvLy8gV2UgY2xvc2UgdGhlIHBhY2thZ2UgYWZ0ZXIgdGhlIHNhdmUgaXMgZG9uZS4KICAgICAgICAvLy8gPC9zdW1tYXJ5PgogICAgICAgIHB1YmxpYyB2b2lkIFNhdmUoKQogICAgICAgIHsKICAgICAgICAgICAgdHJ5CiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIFdvcmtib29rLlNhdmUoKTsKICAgICAgICAgICAgICAgIGlmIChGaWxlID09IG51bGwpCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgaWYoRW5jcnlwdGlvbi5Jc0VuY3J5cHRlZCkKICAgICAgICAgICAgICAgICAgICB7CiNpZiAhTU9OTwogICAgICAgICAgICAgICAgICAgICAgICB2YXIgbXMgPSBuZXcgTWVtb3J5U3RyZWFtKCk7CiAgICAgICAgICAgICAgICAgICAgICAgIF9wYWNrYWdlLlNhdmUobXMpOwogICAgICAgICAgICAgICAgICAgICAgICBieXRlW10gZmlsZSA9IG1zLlRvQXJyYXkoKTsKICAgICAgICAgICAgICAgICAgICAgICAgRW5jcnlwdGVkUGFja2FnZUhhbmRsZXIgZXBoID0gbmV3IEVuY3J5cHRlZFBhY2thZ2VIYW5kbGVyKCk7CiAgICAgICAgICAgICAgICAgICAgICAgIHZhciBtc0VuYyA9IGVwaC5FbmNyeXB0UGFja2FnZShmaWxlLCBFbmNyeXB0aW9uKTsKICAgICAgICAgICAgICAgICAgICAgICAgQ29weVN0cmVhbShtc0VuYywgcmVmIF9zdHJlYW0pOwojZW5kaWYKI2lmIE1PTk8KICAgICAgICAgICAgICAgICAgICAgICAgdGhyb3cgbmV3IE5vdFN1cHBvcnRlZEV4Y2VwdGlvbigiRW5jcnlwdGlvbiBpcyBub3Qgc3VwcG9ydGVkIHVuZGVyIE1vbm8uIik7CiNlbmRpZgogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICBlbHNlCiAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICBfcGFja2FnZS5TYXZlKF9zdHJlYW0pOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICBfc3RyZWFtLkZsdXNoKCk7CiAgICAgICAgICAgICAgICAgICAgX3BhY2thZ2UuQ2xvc2UoKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGVsc2UKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICBpZiAoU3lzdGVtLklPLkZpbGUuRXhpc3RzKEZpbGUuRnVsbE5hbWUpKQogICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgdHJ5CiAgICAgICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIFN5c3RlbS5JTy5GaWxlLkRlbGV0ZShGaWxlLkZ1bGxOYW1lKTsKICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICAgICBjYXRjaCAoRXhjZXB0aW9uIGV4KQogICAgICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aHJvdyAobmV3IEV4Y2VwdGlvbihzdHJpbmcuRm9ybWF0KCJFcnJvciBvdmVyd3JpdGluZyBmaWxlIHswfSIsIEZpbGUuRnVsbE5hbWUpLCBleCkpOwogICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgICAgICBfcGFja2FnZS5TYXZlKF9zdHJlYW0pOwogICAgICAgICAgICAgICAgICAgIF9wYWNrYWdlLkNsb3NlKCk7CiAgICAgICAgICAgICAgICAgICAgaWYgKFN0cmVhbSBpcyBNZW1vcnlTdHJlYW0pCiAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICB2YXIgZmkgPSBuZXcgRmlsZVN0cmVhbShGaWxlLkZ1bGxOYW1lLCBGaWxlTW9kZS5DcmVhdGUpOwogICAgICAgICAgICAgICAgICAgICAgICAvL0VuY3J5cHRQYWNrYWdlCiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChFbmNyeXB0aW9uLklzRW5jcnlwdGVkKQogICAgICAgICAgICAgICAgICAgICAgICB7CiNpZiAhTU9OTwogICAgICAgICAgICAgICAgICAgICAgICAgICAgYnl0ZVtdIGZpbGUgPSAoKE1lbW9yeVN0cmVhbSlTdHJlYW0pLlRvQXJyYXkoKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIEVuY3J5cHRlZFBhY2thZ2VIYW5kbGVyIGVwaCA9IG5ldyBFbmNyeXB0ZWRQYWNrYWdlSGFuZGxlcigpOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgdmFyIG1zID0gZXBoLkVuY3J5cHRQYWNrYWdlKGZpbGUsIEVuY3J5cHRpb24pOwoKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZpLldyaXRlKG1zLkdldEJ1ZmZlcigpLCAwLCAoaW50KW1zLkxlbmd0aCk7CiNlbmRpZgojaWYgTU9OTwogICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhyb3cgbmV3IE5vdFN1cHBvcnRlZEV4Y2VwdGlvbigiRW5jcnlwdGlvbiBpcyBub3Qgc3VwcG9ydGVkIHVuZGVyIE1vbm8uIik7CiNlbmRpZgogICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgICAgIGVsc2UKICAgICAgICAgICAgICAgICAgICAgICAgeyAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZpLldyaXRlKCgoTWVtb3J5U3RyZWFtKVN0cmVhbSkuR2V0QnVmZmVyKCksIDAsIChpbnQpU3RyZWFtLkxlbmd0aCk7CiAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgZmkuQ2xvc2UoKTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgZWxzZQogICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgU3lzdGVtLklPLkZpbGUuV3JpdGVBbGxCeXRlcyhGaWxlLkZ1bGxOYW1lLCBHZXRBc0J5dGVBcnJheShmYWxzZSkpOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgICAgICBjYXRjaCAoRXhjZXB0aW9uIGV4KQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBpZiAoRmlsZSA9PSBudWxsKQogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIHRocm93OwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgZWxzZQogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIHRocm93IChuZXcgSW52YWxpZE9wZXJhdGlvbkV4Y2VwdGlvbihzdHJpbmcuRm9ybWF0KCJFcnJvciBzYXZpbmcgZmlsZSB7MH0iLCBGaWxlLkZ1bGxOYW1lKSwgZXgpKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgIH0KICAgICAgICAvLy8gPHN1bW1hcnk+CiAgICAgICAgLy8vIFNhdmVzIGFsbCB0aGUgY29tcG9uZW50cyBiYWNrIGludG8gdGhlIHBhY2thZ2UuCiAgICAgICAgLy8vIFRoaXMgbWV0aG9kIHJlY3Vyc2l2ZWx5IGNhbGxzIHRoZSBTYXZlIG1ldGhvZCBvbiBhbGwgc3ViLWNvbXBvbmVudHMuCiAgICAgICAgLy8vIFRoZSBwYWNrYWdlIGlzIGNsb3NlZCBhZnRlciBpdCBoYQogICAgICAgIC8vLyBkIHRvIGVuY3J5cHQgdGhlIHdvcmtib29rIHdpdGguIAogICAgICAgIC8vLyA8L3N1bW1hcnk+CiAgICAgICAgLy8vIDxwYXJhbSBuYW1lPSJwYXNzd29yZCI+VGhpcyBwYXJhbWV0ZXIgb3ZlcnJpZGVzIHRoZSBXb3JrYm9vay5FbmNyeXB0aW9uLlBhc3N3b3JkLjwvcGFyYW0+CiAgICAgICAgcHVibGljIHZvaWQgU2F2ZShzdHJpbmcgcGFzc3dvcmQpCgkJewogICAgICAgICAgICBFbmNyeXB0aW9uLlBhc3N3b3JkID0gcGFzc3dvcmQ7CiAgICAgICAgICAgIFNhdmUoKTsKICAgICAgICB9CiAgICAgICAgLy8vIDxzdW1tYXJ5PgogICAgICAgIC8vLyBTYXZlcyB0aGUgd29ya2Jvb2sgdG8gYSBuZXcgZmlsZQogICAgICAgIC8vLyBUaGUgcGFja2FnZSBpcyBjbG9zZWQgYWZ0ZXIgaXQgaGFzIGJlZW4gc2F2ZWQgICAgICAgIAogICAgICAgIC8vLyA8L3N1bW1hcnk+CiAgICAgICAgLy8vIDxwYXJhbSBuYW1lPSJmaWxlIj5UaGUgZmlsZSBsb2NhdGlvbjwvcGFyYW0+CiAgICAgICAgcHVibGljIHZvaWQgU2F2ZUFzKEZpbGVJbmZvIGZpbGUpCiAgICAgICAgewogICAgICAgICAgICBGaWxlID0gZmlsZTsKICAgICAgICAgICAgU2F2ZSgpOwogICAgICAgIH0KICAgICAgICAvLy8gPHN1bW1hcnk+CiAgICAgICAgLy8vIFNhdmVzIHRoZSB3b3JrYm9vayB0byBhIG5ldyBmaWxlCiAgICAgICAgLy8vIFRoZSBwYWNrYWdlIGlzIGNsb3NlZCBhZnRlciBpdCBoYXMgYmVlbiBzYXZlZAogICAgICAgIC8vLyA8L3N1bW1hcnk+CiAgICAgICAgLy8vIDxwYXJhbSBuYW1lPSJmaWxlIj5UaGUgZmlsZTwvcGFyYW0+CiAgICAgICAgLy8vIDxwYXJhbSBuYW1lPSJwYXNzd29yZCI+VGhlIHBhc3N3b3JkIHRvIGVuY3J5cHQgdGhlIHdvcmtib29rIHdpdGguIAogICAgICAgIC8vLyBUaGlzIHBhcmFtZXRlciBvdmVycmlkZXMgdGhlIEVuY3J5cHRpb24uUGFzc3dvcmQuPC9wYXJhbT4KICAgICAgICBwdWJsaWMgdm9pZCBTYXZlQXMoRmlsZUluZm8gZmlsZSwgc3RyaW5nIHBhc3N3b3JkKQogICAgICAgIHsKICAgICAgICAgICAgRmlsZSA9IGZpbGU7CiAgICAgICAgICAgIEVuY3J5cHRpb24uUGFzc3dvcmQgPSBwYXNzd29yZDsKICAgICAgICAgICAgU2F2ZSgpOwogICAgICAgIH0KICAgICAgICAvLy8gPHN1bW1hcnk+CiAgICAgICAgLy8vIENvcGllcyB0aGUgUGFja2FnZSB0byB0aGUgT3V0c3RyZWFtCiAgICAgICAgLy8vIFRoZSBwYWNrYWdlIGlzIGNsb3NlZCBhZnRlciBpdCBoYXMgYmVlbiBzYXZlZAogICAgICAgIC8vLyA8L3N1bW1hcnk+CiAgICAgICAgLy8vIDxwYXJhbSBuYW1lPSJPdXRwdXRTdHJlYW0iPlRoZSBzdHJlYW0gdG8gY29weSB0aGUgcGFja2FnZSB0bzwvcGFyYW0+CiAgICAgICAgcHVibGljIHZvaWQgU2F2ZUFzKFN0cmVhbSBPdXRwdXRTdHJlYW0pCiAgICAgICAgewogICAgICAgICAgICBGaWxlID0gbnVsbDsKICAgICAgICAgICAgU2F2ZSgpOwoKICAgICAgICAgICAgaWYgKE91dHB1dFN0cmVhbSAhPSBfc3RyZWFtKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBpZiAoRW5jcnlwdGlvbi5Jc0VuY3J5cHRlZCkKICAgICAgICAgICAgICAgIHsKI2lmICFNT05PCiAgICAgICAgICAgICAgICAgICAgLy9FbmNyeXB0IFdvcmtib29rCiAgICAgICAgICAgICAgICAgICAgQnl0ZVtdIGZpbGUgPSBuZXcgYnl0ZVtTdHJlYW0uTGVuZ3RoXTsKICAgICAgICAgICAgICAgICAgICBsb25nIHBvcyA9IFN0cmVhbS5Qb3NpdGlvbjsKICAgICAgICAgICAgICAgICAgICBTdHJlYW0uU2VlaygwLCBTZWVrT3JpZ2luLkJlZ2luKTsKICAgICAgICAgICAgICAgICAgICBTdHJlYW0uUmVhZChmaWxlLCAwLCAoaW50KSBTdHJlYW0uTGVuZ3RoKTsKICAgICAgICAgICAgICAgICAgICBFbmNyeXB0ZWRQYWNrYWdlSGFuZGxlciBlcGggPSBuZXcgRW5jcnlwdGVkUGFja2FnZUhhbmRsZXIoKTsKICAgICAgICAgICAgICAgICAgICB2YXIgbXMgPSBlcGguRW5jcnlwdFBhY2thZ2UoZmlsZSwgRW5jcnlwdGlvbik7CiAgICAgICAgICAgICAgICAgICAgQ29weVN0cmVhbShtcywgcmVmIE91dHB1dFN0cmVhbSk7CiNlbmRpZgojaWYgTU9OTwogICAgICAgICAgICAgICAgdGhyb3cgbmV3IE5vdFN1cHBvcnRlZEV4Y2VwdGlvbigiRW5jcnlwdGlvbiBpcyBub3Qgc3VwcG9ydGVkIHVuZGVyIE1vbm8uIik7CiNlbmRpZgogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgZWxzZQogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIENvcHlTdHJlYW0oX3N0cmVhbSwgcmVmIE91dHB1dFN0cmVhbSk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgLy8vIDxzdW1tYXJ5PgogICAgICAgIC8vLyBDb3BpZXMgdGhlIFBhY2thZ2UgdG8gdGhlIE91dHN0cmVhbQogICAgICAgIC8vLyBUaGUgcGFja2FnZSBpcyBjbG9zZWQgYWZ0ZXIgaXQgaGFzIGJlZW4gc2F2ZWQKICAgICAgICAvLy8gPC9zdW1tYXJ5PgogICAgICAgIC8vLyA8cGFyYW0gbmFtZT0iT3V0cHV0U3RyZWFtIj5UaGUgc3RyZWFtIHRvIGNvcHkgdGhlIHBhY2thZ2UgdG88L3BhcmFtPgogICAgICAgIC8vLyA8cGFyYW0gbmFtZT0icGFzc3dvcmQiPlRoZSBwYXNzd29yZCB0byBlbmNyeXB0IHRoZSB3b3JrYm9vayB3aXRoLiAKICAgICAgICAvLy8gVGhpcyBwYXJhbWV0ZXIgb3ZlcnJpZGVzIHRoZSBFbmNyeXB0aW9uLlBhc3N3b3JkLjwvcGFyYW0+CiAgICAgICAgcHVibGljIHZvaWQgU2F2ZUFzKFN0cmVhbSBPdXRwdXRTdHJlYW0sIHN0cmluZyBwYXNzd29yZCkKICAgICAgICB7CiAgICAgICAgICAgIEVuY3J5cHRpb24uUGFzc3dvcmQgPSBwYXNzd29yZDsKICAgICAgICAgICAgU2F2ZUFzKE91dHB1dFN0cmVhbSk7CiAgICAgICAgfQogICAgICAgIEZpbGVJbmZvIF9maWxlID0gbnVsbDsKCiAgICAgICAgLy8vIDxzdW1tYXJ5PgogICAgICAgIC8vLyBUaGUgb3V0cHV0IGZpbGUuIE51bGwgaWYgbm8gZmlsZSBpcyB1c2VkCiAgICAgICAgLy8vIDwvc3VtbWFyeT4KICAgICAgICBwdWJsaWMgRmlsZUluZm8gRmlsZQogICAgICAgIHsKICAgICAgICAgICAgZ2V0CiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIHJldHVybiBfZmlsZTsKICAgICAgICAgICAgfQogICAgICAgICAgICBzZXQKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgX2ZpbGUgPSB2YWx1ZTsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgICAgICAvLy8gPHN1bW1hcnk+CiAgICAgICAgLy8vIFRoZSBvdXRwdXQgc3RyZWFtLiBUaGlzIHN0cmVhbSBpcyB0aGUgbm90IHRoZSBlbmNyeXB0ZWQgcGFja2FnZS4KICAgICAgICAvLy8gVG8gZ2V0IHRoZSBlbmNyeXB0ZWQgcGFja2FnZSB1c2UgdGhlIFNhdmVBcyhzdHJlYW0pIG1ldGhvZC4KICAgICAgICAvLy8gPC9zdW1tYXJ5PgogICAgICAgIHB1YmxpYyBTdHJlYW0gU3RyZWFtCiAgICAgICAgewogICAgICAgICAgICBnZXQKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgcmV0dXJuIF9zdHJlYW07CiAgICAgICAgICAgIH0KICAgICAgICB9CgkJI2VuZHJlZ2lvbgogICAgICAgIC8vLyA8c3VtbWFyeT4KICAgICAgICAvLy8gQ29tcHJlc3Npb24gb3B0aW9uIGZvciB0aGUgcGFja2FnZQogICAgICAgIC8vLyA8L3N1bW1hcnk+ICAgICAgICAKICAgICAgICBwdWJsaWMgQ29tcHJlc3Npb25MZXZlbCBDb21wcmVzc2lvbiAKICAgICAgICB7IAogICAgICAgICAgICBnZXQKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgcmV0dXJuIFBhY2thZ2UuQ29tcHJlc3Npb247CiAgICAgICAgICAgIH0KICAgICAgICAgICAgc2V0CiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIFBhY2thZ2UuQ29tcHJlc3Npb24gPSB2YWx1ZTsKICAgICAgICAgICAgfQogICAgICAgIH0KCQkjcmVnaW9uIEdldFhtbEZyb21VcmkKCQkvLy8gPHN1bW1hcnk+CgkJLy8vIEdldCB0aGUgWG1sRG9jdW1lbnQgZnJvbSBhbiBVUkkKCQkvLy8gPC9zdW1tYXJ5PgoJCS8vLyA8cGFyYW0gbmFtZT0idXJpIj5UaGUgVXJpIHRvIHRoZSBwYXJ0PC9wYXJhbT4KCQkvLy8gPHJldHVybnM+VGhlIFhtbERvY3VtZW50PC9yZXR1cm5zPgoJCWludGVybmFsIFhtbERvY3VtZW50IEdldFhtbEZyb21VcmkoVXJpIHVyaSkKCQl7CgkJCVhtbERvY3VtZW50IHhtbCA9IG5ldyBYbWxEb2N1bWVudCgpOwoJCQlQYWNrYWdpbmcuWmlwUGFja2FnZVBhcnQgcGFydCA9IF9wYWNrYWdlLkdldFBhcnQodXJpKTsKICAgICAgICAgICAgWG1sSGVscGVyLkxvYWRYbWxTYWZlKHhtbCwgcGFydC5HZXRTdHJlYW0oKSk7IAoJCQlyZXR1cm4gKHhtbCk7CgkJfQoJCSNlbmRyZWdpb24KCiAgICAgICAgLy8vIDxzdW1tYXJ5PgogICAgICAgIC8vLyBTYXZlcyBhbmQgcmV0dXJucyB0aGUgRXhjZWwgZmlsZXMgYXMgYSBieXRlYXJyYXkuCiAgICAgICAgLy8vIE5vdGUgdGhhdCB0aGUgcGFja2FnZSBpcyBjbG9zZWQgdXBvbiBzYXZlCiAgICAgICAgLy8vIDwvc3VtbWFyeT4KICAgICAgICAvLy8gPGV4YW1wbGU+ICAgICAgCiAgICAgICAgLy8vIEV4YW1wbGUgaG93IHRvIHJldHVybiBhIGRvY3VtZW50IGZyb20gYSBXZWJzZXJ2ZXIuLi4KICAgICAgICAvLy8gPGNvZGU+IAogICAgICAgIC8vLyAgRXhjZWxQYWNrYWdlIHBhY2thZ2U9bmV3IEV4Y2VsUGFja2FnZSgpOwogICAgICAgIC8vLyAgLyoqKiogLi4uIENyZWF0ZSB0aGUgZG9jdW1lbnQgKioqKi8KICAgICAgICAvLy8gIEJ5dGVbXSBiaW4gPSBwYWNrYWdlLkdldEFzQnl0ZUFycmF5KCk7CiAgICAgICAgLy8vICBSZXNwb25zZS5Db250ZW50VHlwZSA9ICJBcHBsaWNhdGlvbi92bmQubXMtRXhjZWwiOwogICAgICAgIC8vLyAgUmVzcG9uc2UuQWRkSGVhZGVyKCJjb250ZW50LWRpc3Bvc2l0aW9uIiwgImF0dGFjaG1lbnQ7ICBmaWxlbmFtZT1UaGVGaWxlLnhsc3giKTsKCQkvLy8gIFJlc3BvbnNlLkJpbmFyeVdyaXRlKGJpbik7CiAgICAgICAgLy8vIDwvY29kZT4KICAgICAgICAvLy8gPC9leGFtcGxlPgogICAgICAgIC8vLyA8cmV0dXJucz48L3JldHVybnM+CiAgICAgICAgcHVibGljIGJ5dGVbXSBHZXRBc0J5dGVBcnJheSgpCiAgICAgICAgewogICAgICAgICAgIHJldHVybiBHZXRBc0J5dGVBcnJheSh0cnVlKTsKICAgICAgICB9CiAgICAgICAgLy8vIDxzdW1tYXJ5PgogICAgICAgIC8vLyBTYXZlcyBhbmQgcmV0dXJucyB0aGUgRXhjZWwgZmlsZXMgYXMgYSBieXRlYXJyYXkKICAgICAgICAvLy8gTm90ZSB0aGF0IHRoZSBwYWNrYWdlIGlzIGNsb3NlZCB1cG9uIHNhdmUKICAgICAgICAvLy8gPC9zdW1tYXJ5PgogICAgICAgIC8vLyA8ZXhhbXBsZT4gICAgICAKICAgICAgICAvLy8gRXhhbXBsZSBob3cgdG8gcmV0dXJuIGEgZG9jdW1lbnQgZnJvbSBhIFdlYnNlcnZlci4uLgogICAgICAgIC8vLyA8Y29kZT4gCiAgICAgICAgLy8vICBFeGNlbFBhY2thZ2UgcGFja2FnZT1uZXcgRXhjZWxQYWNrYWdlKCk7CiAgICAgICAgLy8vICAvKioqKiAuLi4gQ3JlYXRlIHRoZSBkb2N1bWVudCAqKioqLwogICAgICAgIC8vLyAgQnl0ZVtdIGJpbiA9IHBhY2thZ2UuR2V0QXNCeXRlQXJyYXkoKTsKICAgICAgICAvLy8gIFJlc3BvbnNlLkNvbnRlbnRUeXBlID0gIkFwcGxpY2F0aW9uL3ZuZC5tcy1FeGNlbCI7CiAgICAgICAgLy8vICBSZXNwb25zZS5BZGRIZWFkZXIoImNvbnRlbnQtZGlzcG9zaXRpb24iLCAiYXR0YWNobWVudDsgIGZpbGVuYW1lPVRoZUZpbGUueGxzeCIpOwogICAgICAgIC8vLyAgUmVzcG9uc2UuQmluYXJ5V3JpdGUoYmluKTsKICAgICAgICAvLy8gPC9jb2RlPgogICAgICAgIC8vLyA8L2V4YW1wbGU+CiAgICAgICAgLy8vIDxwYXJhbSBuYW1lPSJwYXNzd29yZCI+VGhlIHBhc3N3b3JkIHRvIGVuY3J5cHQgdGhlIHdvcmtib29rIHdpdGguIAogICAgICAgIC8vLyBUaGlzIHBhcmFtZXRlciBvdmVycmlkZXMgdGhlIEVuY3J5cHRpb24uUGFzc3dvcmQuPC9wYXJhbT4KICAgICAgICAvLy8gPHJldHVybnM+PC9yZXR1cm5zPgogICAgICAgIHB1YmxpYyBieXRlW10gR2V0QXNCeXRlQXJyYXkoc3RyaW5nIHBhc3N3b3JkKQogICAgICAgIHsKICAgICAgICAgICAgaWYgKHBhc3N3b3JkICE9IG51bGwpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIEVuY3J5cHRpb24uUGFzc3dvcmQgPSBwYXNzd29yZDsKICAgICAgICAgICAgfQogICAgICAgICAgICByZXR1cm4gR2V0QXNCeXRlQXJyYXkodHJ1ZSk7CiAgICAgICAgfQogICAgICAgIGludGVybmFsIGJ5dGVbXSBHZXRBc0J5dGVBcnJheShib29sIHNhdmUpCiAgICAgICAgewogICAgICAgICAgICBpZiAoc2F2ZSkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgV29ya2Jvb2suU2F2ZSgpOwogICAgICAgICAgICAgICAgX3BhY2thZ2UuQ2xvc2UoKTsKICAgICAgICAgICAgICAgIF9wYWNrYWdlLlNhdmUoX3N0cmVhbSk7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgQnl0ZVtdIGJ5UmV0ID0gbmV3IGJ5dGVbU3RyZWFtLkxlbmd0aF07CiAgICAgICAgICAgIGxvbmcgcG9zID0gU3RyZWFtLlBvc2l0aW9uOyAgICAgICAgICAgIAogICAgICAgICAgICBTdHJlYW0uU2VlaygwLCBTZWVrT3JpZ2luLkJlZ2luKTsKICAgICAgICAgICAgU3RyZWFtLlJlYWQoYnlSZXQsIDAsIChpbnQpU3RyZWFtLkxlbmd0aCk7CgogICAgICAgICAgICAvL0VuY3J5cHQgV29ya2Jvb2s/CiAgICAgICAgICAgIGlmIChFbmNyeXB0aW9uLklzRW5jcnlwdGVkKQogICAgICAgICAgICB7CiNpZiAhTU9OTwogICAgICAgICAgICAgICAgRW5jcnlwdGVkUGFja2FnZUhhbmRsZXIgZXBoPW5ldyBFbmNyeXB0ZWRQYWNrYWdlSGFuZGxlcigpOwogICAgICAgICAgICAgICAgdmFyIG1zID0gZXBoLkVuY3J5cHRQYWNrYWdlKGJ5UmV0LCBFbmNyeXB0aW9uKTsKICAgICAgICAgICAgICAgIGJ5UmV0ID0gbXMuVG9BcnJheSgpOwojZW5kaWYKICAgICAgICAgICAgfQoKICAgICAgICAgICAgU3RyZWFtLlNlZWsocG9zLCBTZWVrT3JpZ2luLkJlZ2luKTsKICAgICAgICAgICAgU3RyZWFtLkNsb3NlKCk7CiAgICAgICAgICAgIHJldHVybiBieVJldDsKICAgICAgICB9CiAgICAgICAgLy8vIDxzdW1tYXJ5PgogICAgICAgIC8vLyBMb2FkcyB0aGUgc3BlY2lmaWVkIHBhY2thZ2UgZGF0YSBmcm9tIGEgc3RyZWFtLgogICAgICAgIC8vLyA8L3N1bW1hcnk+CiAgICAgICAgLy8vIDxwYXJhbSBuYW1lPSJpbnB1dCI+VGhlIGlucHV0LjwvcGFyYW0+CiAgICAgICAgcHVibGljIHZvaWQgTG9hZChTdHJlYW0gaW5wdXQpCiAgICAgICAgewogICAgICAgICAgICBMb2FkKGlucHV0LCBuZXcgTWVtb3J5U3RyZWFtKCksIG51bGwpOwogICAgICAgIH0KICAgICAgICAvLy8gPHN1bW1hcnk+CiAgICAgICAgLy8vIExvYWRzIHRoZSBzcGVjaWZpZWQgcGFja2FnZSBkYXRhIGZyb20gYSBzdHJlYW0uCiAgICAgICAgLy8vIDwvc3VtbWFyeT4KICAgICAgICAvLy8gPHBhcmFtIG5hbWU9ImlucHV0Ij5UaGUgaW5wdXQuPC9wYXJhbT4KICAgICAgICAvLy8gPHBhcmFtIG5hbWU9IlBhc3N3b3JkIj5UaGUgcGFzc3dvcmQgdG8gZGVjcnlwdCB0aGUgZG9jdW1lbnQ8L3BhcmFtPgogICAgICAgIHB1YmxpYyB2b2lkIExvYWQoU3RyZWFtIGlucHV0LCBzdHJpbmcgUGFzc3dvcmQpCiAgICAgICAgewogICAgICAgICAgICBMb2FkKGlucHV0LCBuZXcgTWVtb3J5U3RyZWFtKCksIFBhc3N3b3JkKTsKICAgICAgICB9CiAgICAgICAgLy8vIDxzdW1tYXJ5PgogICAgICAgIC8vLyAKICAgICAgICAvLy8gPC9zdW1tYXJ5PgogICAgICAgIC8vLyA8cGFyYW0gbmFtZT0iaW5wdXQiPjwvcGFyYW0+ICAgIAogICAgICAgIC8vLyA8cGFyYW0gbmFtZT0ib3V0cHV0Ij48L3BhcmFtPgogICAgICAgIC8vLyA8cGFyYW0gbmFtZT0iUGFzc3dvcmQiPjwvcGFyYW0+CiAgICAgICAgcHJpdmF0ZSB2b2lkIExvYWQoU3RyZWFtIGlucHV0LCBTdHJlYW0gb3V0cHV0LCBzdHJpbmcgUGFzc3dvcmQpCiAgICAgICAgewogICAgICAgICAgICAvL1JlbGVhc2Ugc29tZSByZXNvdXJjZXM6CiAgICAgICAgICAgIGlmICh0aGlzLl9wYWNrYWdlICE9IG51bGwpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIHRoaXMuX3BhY2thZ2UuQ2xvc2UoKTsKICAgICAgICAgICAgICAgIHRoaXMuX3BhY2thZ2UgPSBudWxsOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGlmICh0aGlzLl9zdHJlYW0gIT0gbnVsbCkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgdGhpcy5fc3RyZWFtLkNsb3NlKCk7CiAgICAgICAgICAgICAgICB0aGlzLl9zdHJlYW0uRGlzcG9zZSgpOwogICAgICAgICAgICAgICAgdGhpcy5fc3RyZWFtID0gbnVsbDsKICAgICAgICAgICAgfQogICAgICAgICAgICBfaXNFeHRlcm5hbFN0cmVhbSA9IHRydWU7CiAgICAgICAgICAgIGlmIChpbnB1dC5MZW5ndGggPT0gMCkgLy8gVGVtcGxhdGUgaXMgYmxhbmssIENvbnN0cnVjdCBuZXcKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgX3N0cmVhbSA9IG91dHB1dDsKICAgICAgICAgICAgICAgIENvbnN0cnVjdE5ld0ZpbGUoUGFzc3dvcmQpOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGVsc2UKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgU3RyZWFtIG1zOwogICAgICAgICAgICAgICAgdGhpcy5fc3RyZWFtID0gb3V0cHV0OwogICAgICAgICAgICAgICAgaWYgKFBhc3N3b3JkICE9IG51bGwpCiAgICAgICAgICAgICAgICB7CiNpZiAhTU9OTwogICAgICAgICAgICAgICAgICAgIFN0cmVhbSBlbmNyU3RyZWFtID0gbmV3IE1lbW9yeVN0cmVhbSgpOwogICAgICAgICAgICAgICAgICAgIENvcHlTdHJlYW0oaW5wdXQsIHJlZiBlbmNyU3RyZWFtKTsKICAgICAgICAgICAgICAgICAgICBFbmNyeXB0ZWRQYWNrYWdlSGFuZGxlciBlcGggPSBuZXcgRW5jcnlwdGVkUGFja2FnZUhhbmRsZXIoKTsKICAgICAgICAgICAgICAgICAgICBFbmNyeXB0aW9uLlBhc3N3b3JkID0gUGFzc3dvcmQ7CiAgICAgICAgICAgICAgICAgICAgbXMgPSBlcGguRGVjcnlwdFBhY2thZ2UoKE1lbW9yeVN0cmVhbSllbmNyU3RyZWFtLCBFbmNyeXB0aW9uKTsKI2VuZGlmCiNpZiBNT05PCiAgICAgICAgICAgICAgICAgICAgdGhyb3cgbmV3IE5vdFN1cHBvcnRlZEV4Y2VwdGlvbigiRW5jcnlwdGlvbiBpcyBub3Qgc3VwcG9ydGVkIHVuZGVyIE1vbm8uIik7CiNlbmRpZgogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgZWxzZQogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIG1zID0gbmV3IE1lbW9yeVN0cmVhbSgpOwogICAgICAgICAgICAgICAgICAgIENvcHlTdHJlYW0oaW5wdXQsIHJlZiBtcyk7CiAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgdHJ5CiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgLy90aGlzLl9wYWNrYWdlID0gUGFja2FnZS5PcGVuKHRoaXMuX3N0cmVhbSwgRmlsZU1vZGUuT3BlbiwgRmlsZUFjY2Vzcy5SZWFkV3JpdGUpOwogICAgICAgICAgICAgICAgICAgIF9wYWNrYWdlID0gbmV3IFBhY2thZ2luZy5aaXBQYWNrYWdlKG1zKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGNhdGNoIChFeGNlcHRpb24gZXgpCiAgICAgICAgICAgICAgICB7CiNpZiAhTU9OTwogICAgICAgICAgICAgICAgICAgIEVuY3J5cHRlZFBhY2thZ2VIYW5kbGVyIGVwaCA9IG5ldyBFbmNyeXB0ZWRQYWNrYWdlSGFuZGxlcigpOwogICAgICAgICAgICAgICAgICAgIGlmIChQYXNzd29yZCA9PSBudWxsICYmIENvbXBvdW5kRG9jdW1lbnQuSXNTdG9yYWdlSUxvY2tCeXRlcyhDb21wb3VuZERvY3VtZW50LkdldExvY2tieXRlKChNZW1vcnlTdHJlYW0pX3N0cmVhbSkpID09IDApCiAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICB0aHJvdyBuZXcgRXhjZXB0aW9uKCJDYW4gbm90IG9wZW4gdGhlIHBhY2thZ2UuIFBhY2thZ2UgaXMgYW4gT0xFIGNvbXBvdW5kIGRvY3VtZW50LiBJZiB0aGlzIGlzIGFuIGVuY3J5cHRlZCBwYWNrYWdlLCBwbGVhc2Ugc3VwcGx5IHRoZSBwYXNzd29yZCIsIGV4KTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgZWxzZQogICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgdGhyb3c7CiAgICAgICAgICAgICAgICAgICAgfQojZW5kaWYKI2lmIE1PTk8KICAgICAgICAgICAgICAgICAgICB0aHJvdzsKI2VuZGlmCiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0gICAgICAgICAgICAKICAgICAgICAgICAgLy9DbGVhciB0aGUgd29ya2Jvb2sgc28gdGhhdCBpdCBnZXRzIHJlaW5pdGlhbGl6ZWQgbmV4dCB0aW1lCiAgICAgICAgICAgIHRoaXMuX3dvcmtib29rID0gbnVsbDsKICAgICAgICB9CiAgICAgICAgc3RhdGljIG9iamVjdCBfbG9jaz1uZXcgb2JqZWN0KCk7CiAgICAgICAgLy8vIDxzdW1tYXJ5PgogICAgICAgIC8vLyBDb3BpZXMgdGhlIGlucHV0IHN0cmVhbSB0byB0aGUgb3V0cHV0IHN0cmVhbS4KICAgICAgICAvLy8gPC9zdW1tYXJ5PgogICAgICAgIC8vLyA8cGFyYW0gbmFtZT0iaW5wdXRTdHJlYW0iPlRoZSBpbnB1dCBzdHJlYW0uPC9wYXJhbT4KICAgICAgICAvLy8gPHBhcmFtIG5hbWU9Im91dHB1dFN0cmVhbSI+VGhlIG91dHB1dCBzdHJlYW0uPC9wYXJhbT4KICAgICAgICBpbnRlcm5hbCBzdGF0aWMgdm9pZCBDb3B5U3RyZWFtKFN0cmVhbSBpbnB1dFN0cmVhbSwgcmVmIFN0cmVhbSBvdXRwdXRTdHJlYW0pCiAgICAgICAgewogICAgICAgICAgICBpZiAoIWlucHV0U3RyZWFtLkNhblJlYWQpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIHRocm93IChuZXcgRXhjZXB0aW9uKCJDYW4gbm90IHJlYWQgZnJvbSBpbnB1dHN0cmVhbSIpKTsKICAgICAgICAgICAgfQogICAgICAgICAgICBpZiAoIW91dHB1dFN0cmVhbS5DYW5Xcml0ZSkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgdGhyb3cgKG5ldyBFeGNlcHRpb24oIkNhbiBub3Qgd3JpdGUgdG8gb3V0cHV0c3RyZWFtIikpOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGlmIChpbnB1dFN0cmVhbS5DYW5TZWVrKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBpbnB1dFN0cmVhbS5TZWVrKDAsIFNlZWtPcmlnaW4uQmVnaW4pOwogICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgY29uc3QgaW50IGJ1ZmZlckxlbmd0aCA9IDgwOTY7CiAgICAgICAgICAgICAgICB2YXIgYnVmZmVyID0gbmV3IEJ5dGVbYnVmZmVyTGVuZ3RoXTsKICAgICAgICAgICAgICAgIGxvY2sgKF9sb2NrKQogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIGludCBieXRlc1JlYWQgPSBpbnB1dFN0cmVhbS5SZWFkKGJ1ZmZlciwgMCwgYnVmZmVyTGVuZ3RoKTsKICAgICAgICAgICAgICAgICAgICAvLyB3cml0ZSB0aGUgcmVxdWlyZWQgYnl0ZXMKICAgICAgICAgICAgICAgICAgICB3aGlsZSAoYnl0ZXNSZWFkID4gMCkKICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgIG91dHB1dFN0cmVhbS5Xcml0ZShidWZmZXIsIDAsIGJ5dGVzUmVhZCk7CiAgICAgICAgICAgICAgICAgICAgICAgIGJ5dGVzUmVhZCA9IGlucHV0U3RyZWFtLlJlYWQoYnVmZmVyLCAwLCBidWZmZXJMZW5ndGgpOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICBvdXRwdXRTdHJlYW0uRmx1c2goKTsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgIH0KfQ==