LyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogWW91IG1heSBhbWVuZCBhbmQgZGlzdHJpYnV0ZSBhcyB5b3UgbGlrZSwgYnV0IGRvbid0IHJlbW92ZSB0aGlzIGhlYWRlciEKICoKICogRVBQbHVzIHByb3ZpZGVzIHNlcnZlci1zaWRlIGdlbmVyYXRpb24gb2YgRXhjZWwgMjAwNy8yMDEwIHNwcmVhZHNoZWV0cy4KICogU2VlIGh0dHA6Ly93d3cuY29kZXBsZXguY29tL0VQUGx1cyBmb3IgZGV0YWlscy4KICoKICogQ29weXJpZ2h0IChDKSAyMDExICBKYW4gS+RsbG1hbgogKgogKiBUaGlzIGxpYnJhcnkgaXMgZnJlZSBzb2Z0d2FyZTsgeW91IGNhbiByZWRpc3RyaWJ1dGUgaXQgYW5kL29yCiAqIG1vZGlmeSBpdCB1bmRlciB0aGUgdGVybXMgb2YgdGhlIEdOVSBMZXNzZXIgR2VuZXJhbCBQdWJsaWMKICogTGljZW5zZSBhcyBwdWJsaXNoZWQgYnkgdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbjsgZWl0aGVyCiAqIHZlcnNpb24gMi4xIG9mIHRoZSBMaWNlbnNlLCBvciAoYXQgeW91ciBvcHRpb24pIGFueSBsYXRlciB2ZXJzaW9uLgoKICogVGhpcyBsaWJyYXJ5IGlzIGRpc3RyaWJ1dGVkIGluIHRoZSBob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsCiAqIGJ1dCBXSVRIT1VUIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuIHRoZSBpbXBsaWVkIHdhcnJhbnR5IG9mCiAqIE1FUkNIQU5UQUJJTElUWSBvciBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRS4gIAogKiBTZWUgdGhlIEdOVSBMZXNzZXIgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSBmb3IgbW9yZSBkZXRhaWxzLgogKgogKiBUaGUgR05VIExlc3NlciBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIGNhbiBiZSB2aWV3ZWQgYXQgaHR0cDovL3d3dy5vcGVuc291cmNlLm9yZy9saWNlbnNlcy9sZ3BsLWxpY2Vuc2UucGhwCiAqIElmIHlvdSB1bmZhbWlsaWFyIHdpdGggdGhpcyBsaWNlbnNlIG9yIGhhdmUgcXVlc3Rpb25zIGFib3V0IGl0LCBoZXJlIGlzIGFuIGh0dHA6Ly93d3cuZ251Lm9yZy9saWNlbnNlcy9ncGwtZmFxLmh0bWwKICoKICogQWxsIGNvZGUgYW5kIGV4ZWN1dGFibGVzIGFyZSBwcm92aWRlZCAiYXMgaXMiIHdpdGggbm8gd2FycmFudHkgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4gCiAqIFRoZSBhdXRob3IgYWNjZXB0cyBubyBsaWFiaWxpdHkgZm9yIGFueSBkYW1hZ2Ugb3IgbG9zcyBvZiBidXNpbmVzcyB0aGF0IHRoaXMgcHJvZHVjdCBtYXkgY2F1c2UuCiAqCiAqIENvZGUgY2hhbmdlIG5vdGVzOgogKiAKICogQXV0aG9yCQkJCQkJCUNoYW5nZQkJCQkJCURhdGUKICogKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIEphbiBL5GxsbWFuCQkgICAgSW5pdGlhbCBSZWxlYXNlCQkgICAgICAgMjAxMS0wMS0wMQogKiBKYW4gS+RsbG1hbgkJICAgIExpY2Vuc2UgY2hhbmdlZCBHUEwtLT5MR1BMIDIwMTEtMTItMjcKICogUmljaGFyZCBUYWxsZW50CQlGaXggZXNjYXBpbmcgb2YgcXVvdGVzCQkJCQkyMDEyLTEwLTMxCiAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwp1c2luZyBTeXN0ZW07CnVzaW5nIFN5c3RlbS5MaW5xOwp1c2luZyBTeXN0ZW0uWG1sOwp1c2luZyBTeXN0ZW0uSU87CnVzaW5nIFN5c3RlbS5Db2xsZWN0aW9ucy5HZW5lcmljOwp1c2luZyBTeXN0ZW0uVGV4dDsKdXNpbmcgU3lzdGVtLkdsb2JhbGl6YXRpb247CnVzaW5nIE9mZmljZU9wZW5YbWwuVkJBOwp1c2luZyBPZmZpY2VPcGVuWG1sLlV0aWxzOwp1c2luZyBPZmZpY2VPcGVuWG1sLkZvcm11bGFQYXJzaW5nOwp1c2luZyBPZmZpY2VPcGVuWG1sLkZvcm11bGFQYXJzaW5nLkxleGljYWxBbmFseXNpczsKdXNpbmcgT2ZmaWNlT3BlblhtbC5QYWNrYWdpbmcuSW9uaWMuWmlwOwp1c2luZyBTeXN0ZW0uRHJhd2luZzsKCm5hbWVzcGFjZSBPZmZpY2VPcGVuWG1sCnsKCSNyZWdpb24gUHVibGljIEVudW0gRXhjZWxDYWxjTW9kZQoJLy8vIDxzdW1tYXJ5PgoJLy8vIEhvdyB0aGUgYXBwbGljYXRpb24gc2hvdWxkIGNhbGN1bGF0ZSBmb3JtdWxhcyBpbiB0aGUgd29ya2Jvb2sKCS8vLyA8L3N1bW1hcnk+CglwdWJsaWMgZW51bSBFeGNlbENhbGNNb2RlCgl7CgkJLy8vIDxzdW1tYXJ5PgoJCS8vLyBJbmRpY2F0ZXMgdGhhdCBjYWxjdWxhdGlvbnMgaW4gdGhlIHdvcmtib29rIGFyZSBwZXJmb3JtZWQgYXV0b21hdGljYWxseSB3aGVuIGNlbGwgdmFsdWVzIGNoYW5nZS4gCgkJLy8vIFRoZSBhcHBsaWNhdGlvbiByZWNhbGN1bGF0ZXMgdGhvc2UgY2VsbHMgdGhhdCBhcmUgZGVwZW5kZW50IG9uIG90aGVyIGNlbGxzIHRoYXQgY29udGFpbiBjaGFuZ2VkIHZhbHVlcy4gCgkJLy8vIFRoaXMgbW9kZSBvZiBjYWxjdWxhdGlvbiBoZWxwcyB0byBhdm9pZCB1bm5lY2Vzc2FyeSBjYWxjdWxhdGlvbnMuCgkJLy8vIDwvc3VtbWFyeT4KCQlBdXRvbWF0aWMsCgkJLy8vIDxzdW1tYXJ5PgoJCS8vLyBJbmRpY2F0ZXMgdGFibGVzIGJlIGV4Y2x1ZGVkIGR1cmluZyBhdXRvbWF0aWMgY2FsY3VsYXRpb24KCQkvLy8gPC9zdW1tYXJ5PgoJCUF1dG9tYXRpY05vVGFibGUsCgkJLy8vIDxzdW1tYXJ5PgoJCS8vLyBJbmRpY2F0ZXMgdGhhdCBjYWxjdWxhdGlvbnMgaW4gdGhlIHdvcmtib29rIGJlIHRyaWdnZXJlZCBtYW51YWxseSBieSB0aGUgdXNlci4gCgkJLy8vIDwvc3VtbWFyeT4KCQlNYW51YWwKCX0KCSNlbmRyZWdpb24KCgkvLy8gPHN1bW1hcnk+CgkvLy8gUmVwcmVzZW50cyB0aGUgRXhjZWwgd29ya2Jvb2sgYW5kIHByb3ZpZGVzIGFjY2VzcyB0byBhbGwgdGhlIAoJLy8vIGRvY3VtZW50IHByb3BlcnRpZXMgYW5kIHdvcmtzaGVldHMgd2l0aGluIHRoZSB3b3JrYm9vay4KCS8vLyA8L3N1bW1hcnk+CglwdWJsaWMgc2VhbGVkIGNsYXNzIEV4Y2VsV29ya2Jvb2sgOiBYbWxIZWxwZXIsIElEaXNwb3NhYmxlCgl7CgkJaW50ZXJuYWwgY2xhc3MgU2hhcmVkU3RyaW5nSXRlbQoJCXsKCQkJaW50ZXJuYWwgaW50IHBvczsKCQkJaW50ZXJuYWwgc3RyaW5nIFRleHQ7CgkJCWludGVybmFsIGJvb2wgaXNSaWNoVGV4dCA9IGZhbHNlOwoJCX0KCQkjcmVnaW9uIFByaXZhdGUgUHJvcGVydGllcwoJCWludGVybmFsIEV4Y2VsUGFja2FnZSBfcGFja2FnZTsKCQlwcml2YXRlIEV4Y2VsV29ya3NoZWV0cyBfd29ya3NoZWV0czsKCQlwcml2YXRlIE9mZmljZVByb3BlcnRpZXMgX3Byb3BlcnRpZXM7CgoJCXByaXZhdGUgRXhjZWxTdHlsZXMgX3N0eWxlczsKCQkjZW5kcmVnaW9uCgoJCSNyZWdpb24gRXhjZWxXb3JrYm9vayBDb25zdHJ1Y3RvcgoJCS8vLyA8c3VtbWFyeT4KCQkvLy8gQ3JlYXRlcyBhIG5ldyBpbnN0YW5jZSBvZiB0aGUgRXhjZWxXb3JrYm9vayBjbGFzcy4KCQkvLy8gPC9zdW1tYXJ5PgoJCS8vLyA8cGFyYW0gbmFtZT0icGFja2FnZSI+VGhlIHBhcmVudCBwYWNrYWdlPC9wYXJhbT4KCQkvLy8gPHBhcmFtIG5hbWU9Im5hbWVzcGFjZU1hbmFnZXIiPk5hbWVzcGFjZU1hbmFnZXI8L3BhcmFtPgoJCWludGVybmFsIEV4Y2VsV29ya2Jvb2soRXhjZWxQYWNrYWdlIHBhY2thZ2UsIFhtbE5hbWVzcGFjZU1hbmFnZXIgbmFtZXNwYWNlTWFuYWdlcikgOgoJCQliYXNlKG5hbWVzcGFjZU1hbmFnZXIpCgkJewoJCQlfcGFja2FnZSA9IHBhY2thZ2U7CgkJCVdvcmtib29rVXJpID0gbmV3IFVyaSgiL3hsL3dvcmtib29rLnhtbCIsIFVyaUtpbmQuUmVsYXRpdmUpOwoJCQlTaGFyZWRTdHJpbmdzVXJpID0gbmV3IFVyaSgiL3hsL3NoYXJlZFN0cmluZ3MueG1sIiwgVXJpS2luZC5SZWxhdGl2ZSk7CgkJCVN0eWxlc1VyaSA9IG5ldyBVcmkoIi94bC9zdHlsZXMueG1sIiwgVXJpS2luZC5SZWxhdGl2ZSk7CgoJCQlfbmFtZXMgPSBuZXcgRXhjZWxOYW1lZFJhbmdlQ29sbGVjdGlvbih0aGlzKTsKCQkJX25hbWVzcGFjZU1hbmFnZXIgPSBuYW1lc3BhY2VNYW5hZ2VyOwoJCQlUb3BOb2RlID0gV29ya2Jvb2tYbWwuRG9jdW1lbnRFbGVtZW50OwoJCQlTY2hlbWFOb2RlT3JkZXIgPSBuZXcgc3RyaW5nW10geyAiZmlsZVZlcnNpb24iLCAiZmlsZVNoYXJpbmciLCAid29ya2Jvb2tQciIsICJ3b3JrYm9va1Byb3RlY3Rpb24iLCAiYm9va1ZpZXdzIiwgInNoZWV0cyIsICJmdW5jdGlvbkdyb3VwcyIsICJmdW5jdGlvblByb3RvdHlwZXMiLCAiZXh0ZXJuYWxSZWZlcmVuY2VzIiwgImRlZmluZWROYW1lcyIsICJjYWxjUHIiLCAib2xlU2l6ZSIsICJjdXN0b21Xb3JrYm9va1ZpZXdzIiwgInBpdm90Q2FjaGVzIiwgInNtYXJ0VGFnUHIiLCAic21hcnRUYWdUeXBlcyIsICJ3ZWJQdWJsaXNoaW5nIiwgImZpbGVSZWNvdmVyeVByIiwgfTsKCQkgICAgRnVsbENhbGNPbkxvYWQgPSB0cnVlOyAgLy9GdWxsIGNhbGN1bGF0aW9uIG9uIGxvYWQgYnkgZGVmYXVsdCwgZm9yIGJvdGggbmV3IHdvcmtib29rcyBhbmQgdGVtcGxhdGVzLgoJCQlHZXRTaGFyZWRTdHJpbmdzKCk7CgkJfQoJCSNlbmRyZWdpb24KCgkJaW50ZXJuYWwgRGljdGlvbmFyeTxzdHJpbmcsIFNoYXJlZFN0cmluZ0l0ZW0+IF9zaGFyZWRTdHJpbmdzID0gbmV3IERpY3Rpb25hcnk8c3RyaW5nLCBTaGFyZWRTdHJpbmdJdGVtPigpOyAvL1VzZWQgd2hlbiByZWFkaW5nIGNlbGxzLgoJCWludGVybmFsIExpc3Q8U2hhcmVkU3RyaW5nSXRlbT4gX3NoYXJlZFN0cmluZ3NMaXN0ID0gbmV3IExpc3Q8U2hhcmVkU3RyaW5nSXRlbT4oKTsgLy9Vc2VkIHdoZW4gcmVhZGluZyBjZWxscy4KCQlpbnRlcm5hbCBFeGNlbE5hbWVkUmFuZ2VDb2xsZWN0aW9uIF9uYW1lczsKCQlpbnRlcm5hbCBpbnQgX25leHREcmF3aW5nSUQgPSAwOwoJCWludGVybmFsIGludCBfbmV4dFRhYmxlSUQgPSBpbnQuTWluVmFsdWU7CiAgICAgICAgaW50ZXJuYWwgaW50IF9uZXh0UGl2b3RUYWJsZUlEID0gaW50Lk1pblZhbHVlOwoJCWludGVybmFsIFhtbE5hbWVzcGFjZU1hbmFnZXIgX25hbWVzcGFjZU1hbmFnZXI7CiAgICAgICAgaW50ZXJuYWwgRm9ybXVsYVBhcnNlciBfZm9ybXVsYVBhcnNlciA9IG51bGw7CgkgICAgaW50ZXJuYWwgRm9ybXVsYVBhcnNlck1hbmFnZXIgX3BhcnNlck1hbmFnZXI7CiAgICAgICAgaW50ZXJuYWwgQ2VsbFN0b3JlPExpc3Q8VG9rZW4+PiBfZm9ybXVsYVRva2VuczsKCQkvLy8gPHN1bW1hcnk+CgkJLy8vIFJlYWQgc2hhcmVkIHN0cmluZ3MgdG8gbGlzdAoJCS8vLyA8L3N1bW1hcnk+CgkJcHJpdmF0ZSB2b2lkIEdldFNoYXJlZFN0cmluZ3MoKQoJCXsKCQkJaWYgKF9wYWNrYWdlLlBhY2thZ2UuUGFydEV4aXN0cyhTaGFyZWRTdHJpbmdzVXJpKSkKCQkJewoJCQkJdmFyIHhtbCA9IF9wYWNrYWdlLkdldFhtbEZyb21VcmkoU2hhcmVkU3RyaW5nc1VyaSk7CgkJCQlYbWxOb2RlTGlzdCBubCA9IHhtbC5TZWxlY3ROb2RlcygiLy9kOnNzdC9kOnNpIiwgTmFtZVNwYWNlTWFuYWdlcik7CgkJCQlfc2hhcmVkU3RyaW5nc0xpc3QgPSBuZXcgTGlzdDxTaGFyZWRTdHJpbmdJdGVtPigpOwoJCQkJaWYgKG5sICE9IG51bGwpCgkJCQl7CgkJCQkJZm9yZWFjaCAoWG1sTm9kZSBub2RlIGluIG5sKQoJCQkJCXsKCQkJCQkJWG1sTm9kZSBuID0gbm9kZS5TZWxlY3RTaW5nbGVOb2RlKCJkOnQiLCBOYW1lU3BhY2VNYW5hZ2VyKTsKCQkJCQkJaWYgKG4gIT0gbnVsbCkKCQkJCQkJewogICAgICAgICAgICAgICAgICAgICAgICAgICAgX3NoYXJlZFN0cmluZ3NMaXN0LkFkZChuZXcgU2hhcmVkU3RyaW5nSXRlbSgpIHsgVGV4dCA9IENvbnZlcnRVdGlsLkV4Y2VsRGVjb2RlU3RyaW5nKG4uSW5uZXJUZXh0KSB9KTsKCQkJCQkJfQoJCQkJCQllbHNlCgkJCQkJCXsKCQkJCQkJCV9zaGFyZWRTdHJpbmdzTGlzdC5BZGQobmV3IFNoYXJlZFN0cmluZ0l0ZW0oKSB7IFRleHQgPSBub2RlLklubmVyWG1sLCBpc1JpY2hUZXh0ID0gdHJ1ZSB9KTsKCQkJCQkJfQoJCQkJCX0KCQkJCX0KICAgICAgICAgICAgICAgIC8vRGVsZXRlIHRoZSBzaGFyZWQgc3RyaW5nIHBhcnQsIGl0IHdpbGwgYmUgcmVjcmVhdGVkIHdoZW4gdGhlIHBhY2thZ2UgaXMgc2F2ZWQuCiAgICAgICAgICAgICAgICBmb3JlYWNoICh2YXIgcmVsIGluIFBhcnQuR2V0UmVsYXRpb25zaGlwcygpKQogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIGlmIChyZWwuVGFyZ2V0VXJpLk9yaWdpbmFsU3RyaW5nLkVuZHNXaXRoKCJzaGFyZWRzdHJpbmdzLnhtbCIsIFN0cmluZ0NvbXBhcmlzb24uSW52YXJpYW50Q3VsdHVyZUlnbm9yZUNhc2UpKQogICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgUGFydC5EZWxldGVSZWxhdGlvbnNoaXAocmVsLklkKTsKICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfSAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgIF9wYWNrYWdlLlBhY2thZ2UuRGVsZXRlUGFydChTaGFyZWRTdHJpbmdzVXJpKTsgLy9SZW1vdmUgdGhlIHBhcnQsIGl0IGlzIHJlY3JlYXRlZCB3aGVuIHNhdmVkLgoJCQl9CgkJfQoJCWludGVybmFsIHZvaWQgR2V0RGVmaW5lZE5hbWVzKCkKCQl7CgkJCVhtbE5vZGVMaXN0IG5sID0gV29ya2Jvb2tYbWwuU2VsZWN0Tm9kZXMoIi8vZDpkZWZpbmVkTmFtZXMvZDpkZWZpbmVkTmFtZSIsIE5hbWVTcGFjZU1hbmFnZXIpOwoJCQlpZiAobmwgIT0gbnVsbCkKCQkJewoJCQkJZm9yZWFjaCAoWG1sRWxlbWVudCBlbGVtIGluIG5sKQoJCQkJeyAKCQkJCQlzdHJpbmcgZnVsbEFkZHJlc3MgPSBlbGVtLklubmVyVGV4dDsKCgkJCQkJaW50IGxvY2FsU2hlZXRJRDsKCQkJCQlFeGNlbFdvcmtzaGVldCBuYW1lV29ya3NoZWV0OwoJCQkJCWlmKCFpbnQuVHJ5UGFyc2UoZWxlbS5HZXRBdHRyaWJ1dGUoImxvY2FsU2hlZXRJZCIpLCBvdXQgbG9jYWxTaGVldElEKSkKCQkJCQl7CgkJCQkJCWxvY2FsU2hlZXRJRCA9IC0xOwoJCQkJCQluYW1lV29ya3NoZWV0PW51bGw7CgkJCQkJfQoJCQkJCWVsc2UKCQkJCQl7CgkJCQkJCW5hbWVXb3Jrc2hlZXQ9V29ya3NoZWV0c1tsb2NhbFNoZWV0SUQgKyAxXTsKCQkJCQl9CgkJCQkJdmFyIGFkZHJlc3NUeXBlID0gRXhjZWxBZGRyZXNzQmFzZS5Jc1ZhbGlkKGZ1bGxBZGRyZXNzKTsKCQkJCQlFeGNlbFJhbmdlQmFzZSByYW5nZTsKCQkJCQlFeGNlbE5hbWVkUmFuZ2UgbmFtZWRSYW5nZTsKCgkJCQkJaWYgKGZ1bGxBZGRyZXNzLkluZGV4T2YoIlsiKSA9PSAwKQoJCQkJCXsKCQkJCQkJaW50IHN0YXJ0ID0gZnVsbEFkZHJlc3MuSW5kZXhPZigiWyIpOwoJCQkJCQlpbnQgZW5kID0gZnVsbEFkZHJlc3MuSW5kZXhPZigiXSIsIHN0YXJ0KTsKCQkJCQkJaWYgKHN0YXJ0ID49IDAgJiYgZW5kID49IDApCgkJCQkJCXsKCgkJCQkJCQlzdHJpbmcgZXh0ZXJuYWxJbmRleCA9IGZ1bGxBZGRyZXNzLlN1YnN0cmluZyhzdGFydCArIDEsIGVuZCAtIHN0YXJ0IC0gMSk7CgkJCQkJCQlpbnQgaW5kZXg7CgkJCQkJCQlpZiAoaW50LlRyeVBhcnNlKGV4dGVybmFsSW5kZXgsIG91dCBpbmRleCkpCgkJCQkJCQl7CgkJCQkJCQkJaWYgKGluZGV4ID4gMCAmJiBpbmRleCA8PSBfZXh0ZXJuYWxSZWZlcmVuY2VzLkNvdW50KQoJCQkJCQkJCXsKCQkJCQkJCQkJZnVsbEFkZHJlc3MgPSBmdWxsQWRkcmVzcy5TdWJzdHJpbmcoMCwgc3RhcnQpICsgIlsiICsgX2V4dGVybmFsUmVmZXJlbmNlc1tpbmRleCAtIDFdICsgIl0iICsgZnVsbEFkZHJlc3MuU3Vic3RyaW5nKGVuZCArIDEpOwoJCQkJCQkJCX0KCQkJCQkJCX0KCQkJCQkJfQoJCQkJCX0KCgkJCQkJaWYgKGFkZHJlc3NUeXBlID09IEV4Y2VsQWRkcmVzc0Jhc2UuQWRkcmVzc1R5cGUuSW52YWxpZCB8fCBhZGRyZXNzVHlwZSA9PSBFeGNlbEFkZHJlc3NCYXNlLkFkZHJlc3NUeXBlLkludGVybmFsTmFtZSB8fCBhZGRyZXNzVHlwZSA9PSBFeGNlbEFkZHJlc3NCYXNlLkFkZHJlc3NUeXBlLkV4dGVybmFsTmFtZSB8fCBhZGRyZXNzVHlwZT09RXhjZWxBZGRyZXNzQmFzZS5BZGRyZXNzVHlwZS5Gb3JtdWxhIHx8IGFkZHJlc3NUeXBlPT1FeGNlbEFkZHJlc3NCYXNlLkFkZHJlc3NUeXBlLkV4dGVybmFsQWRkcmVzcykgICAgLy9BIHZhbHVlIG9yIGEgZm9ybXVsYQoJCQkJCXsKCQkJCQkJZG91YmxlIHZhbHVlOwoJCQkJCQlyYW5nZSA9IG5ldyBFeGNlbFJhbmdlQmFzZSh0aGlzLCBuYW1lV29ya3NoZWV0LCBlbGVtLkdldEF0dHJpYnV0ZSgibmFtZSIpLCB0cnVlKTsKCQkJCQkJaWYgKG5hbWVXb3Jrc2hlZXQgPT0gbnVsbCkKCQkJCQkJewoJCQkJCQkJbmFtZWRSYW5nZSA9IF9uYW1lcy5BZGQoZWxlbS5HZXRBdHRyaWJ1dGUoIm5hbWUiKSwgcmFuZ2UpOwoJCQkJCQl9CgkJCQkJCWVsc2UKCQkJCQkJewoJCQkJCQkJbmFtZWRSYW5nZSA9IG5hbWVXb3Jrc2hlZXQuTmFtZXMuQWRkKGVsZW0uR2V0QXR0cmlidXRlKCJuYW1lIiksIHJhbmdlKTsKCQkJCQkJfQoJCQkJCQkKCQkJCQkJaWYgKGZ1bGxBZGRyZXNzLlN0YXJ0c1dpdGgoIlwiIikpIC8vU3RyaW5nIHZhbHVlCgkJCQkJCXsKCQkJCQkJCW5hbWVkUmFuZ2UuTmFtZVZhbHVlID0gZnVsbEFkZHJlc3MuU3Vic3RyaW5nKDEsZnVsbEFkZHJlc3MuTGVuZ3RoLTIpOwoJCQkJCQl9CgkJCQkJCWVsc2UgaWYgKGRvdWJsZS5UcnlQYXJzZShmdWxsQWRkcmVzcywgTnVtYmVyU3R5bGVzLkFueSwgQ3VsdHVyZUluZm8uSW52YXJpYW50Q3VsdHVyZSwgb3V0IHZhbHVlKSkKCQkJCQkJewoJCQkJCQkJbmFtZWRSYW5nZS5OYW1lVmFsdWUgPSB2YWx1ZTsKCQkJCQkJfQoJCQkJCQllbHNlCgkJCQkJCXsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vaWYgKGFkZHJlc3NUeXBlID09IEV4Y2VsQWRkcmVzc0Jhc2UuQWRkcmVzc1R5cGUuRXh0ZXJuYWxBZGRyZXNzIHx8IGFkZHJlc3NUeXBlID09IEV4Y2VsQWRkcmVzc0Jhc2UuQWRkcmVzc1R5cGUuRXh0ZXJuYWxOYW1lKQogICAgICAgICAgICAgICAgICAgICAgICAgICAgLy97CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyAgICB2YXIgciA9IG5ldyBFeGNlbEFkZHJlc3MoZnVsbEFkZHJlc3MpOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gICAgbmFtZWRSYW5nZS5OYW1lRm9ybXVsYSA9ICdcJ1snICsgci5fd2IKICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vfQogICAgICAgICAgICAgICAgICAgICAgICAgICAgLy9lbHNlCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAvL3sKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBuYW1lZFJhbmdlLk5hbWVGb3JtdWxhID0gZnVsbEFkZHJlc3M7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAvL30KCQkJCQkJfQoJCQkJCX0KCQkJCQllbHNlCgkJCQkJewoJCQkJCQlFeGNlbEFkZHJlc3MgYWRkciA9IG5ldyBFeGNlbEFkZHJlc3MoZnVsbEFkZHJlc3MsIF9wYWNrYWdlLCBudWxsKTsKCQkJCQkJaWYgKGxvY2FsU2hlZXRJRCA+IC0xKQoJCQkJCQl7CgkJCQkJCQlpZiAoc3RyaW5nLklzTnVsbE9yRW1wdHkoYWRkci5fd3MpKQoJCQkJCQkJewoJCQkJCQkJCW5hbWVkUmFuZ2UgPSBXb3Jrc2hlZXRzW2xvY2FsU2hlZXRJRCArIDFdLk5hbWVzLkFkZChlbGVtLkdldEF0dHJpYnV0ZSgibmFtZSIpLCBuZXcgRXhjZWxSYW5nZUJhc2UodGhpcywgV29ya3NoZWV0c1tsb2NhbFNoZWV0SUQgKyAxXSwgZnVsbEFkZHJlc3MsIGZhbHNlKSk7CgkJCQkJCQl9CgkJCQkJCQllbHNlCgkJCQkJCQl7CgkJCQkJCQkJbmFtZWRSYW5nZSA9IFdvcmtzaGVldHNbbG9jYWxTaGVldElEICsgMV0uTmFtZXMuQWRkKGVsZW0uR2V0QXR0cmlidXRlKCJuYW1lIiksIG5ldyBFeGNlbFJhbmdlQmFzZSh0aGlzLCBXb3Jrc2hlZXRzW2FkZHIuX3dzXSwgZnVsbEFkZHJlc3MsIGZhbHNlKSk7CgkJCQkJCQl9CgkJCQkJCX0KCQkJCQkJZWxzZQoJCQkJCQl7CgkJCQkJCQl2YXIgd3MgPSBXb3Jrc2hlZXRzW2FkZHIuX3dzXTsKCQkJCQkJCW5hbWVkUmFuZ2UgPSBfbmFtZXMuQWRkKGVsZW0uR2V0QXR0cmlidXRlKCJuYW1lIiksIG5ldyBFeGNlbFJhbmdlQmFzZSh0aGlzLCB3cywgZnVsbEFkZHJlc3MsIGZhbHNlKSk7CgkJCQkJCX0KCQkJCQl9CgkJCQkJaWYgKGVsZW0uR2V0QXR0cmlidXRlKCJoaWRkZW4iKSA9PSAiMSIgJiYgbmFtZWRSYW5nZSAhPSBudWxsKSBuYW1lZFJhbmdlLklzTmFtZUhpZGRlbiA9IHRydWU7CgkJCQkJaWYoIXN0cmluZy5Jc051bGxPckVtcHR5KGVsZW0uR2V0QXR0cmlidXRlKCJjb21tZW50IikpKSBuYW1lZFJhbmdlLk5hbWVDb21tZW50PWVsZW0uR2V0QXR0cmlidXRlKCJjb21tZW50Iik7CgkJCQl9CgkJCX0KCQl9CgkJI3JlZ2lvbiBXb3Jrc2hlZXRzCgkJLy8vIDxzdW1tYXJ5PgoJCS8vLyBQcm92aWRlcyBhY2Nlc3MgdG8gYWxsIHRoZSB3b3Jrc2hlZXRzIGluIHRoZSB3b3JrYm9vay4KCQkvLy8gPC9zdW1tYXJ5PgoJCXB1YmxpYyBFeGNlbFdvcmtzaGVldHMgV29ya3NoZWV0cwoJCXsKCQkJZ2V0CgkJCXsKCQkJCWlmIChfd29ya3NoZWV0cyA9PSBudWxsKQoJCQkJewoJCQkJCXZhciBzaGVldHNOb2RlID0gX3dvcmtib29rWG1sLkRvY3VtZW50RWxlbWVudC5TZWxlY3RTaW5nbGVOb2RlKCJkOnNoZWV0cyIsIF9uYW1lc3BhY2VNYW5hZ2VyKTsKCQkJCQlpZiAoc2hlZXRzTm9kZSA9PSBudWxsKQoJCQkJCXsKCQkJCQkJc2hlZXRzTm9kZSA9IENyZWF0ZU5vZGUoImQ6c2hlZXRzIik7CgkJCQkJfQoJCQkJCQoJCQkJCV93b3Jrc2hlZXRzID0gbmV3IEV4Y2VsV29ya3NoZWV0cyhfcGFja2FnZSwgX25hbWVzcGFjZU1hbmFnZXIsIHNoZWV0c05vZGUpOwoJCQkJfQoJCQkJcmV0dXJuIChfd29ya3NoZWV0cyk7CgkJCX0KCQl9CgkJI2VuZHJlZ2lvbgoKCQkvLy8gPHN1bW1hcnk+CgkJLy8vIFByb3ZpZGVzIGFjY2VzcyB0byBuYW1lZCByYW5nZXMKCQkvLy8gPC9zdW1tYXJ5PgoJCXB1YmxpYyBFeGNlbE5hbWVkUmFuZ2VDb2xsZWN0aW9uIE5hbWVzCgkJewoJCQlnZXQKCQkJewoJCQkJcmV0dXJuIF9uYW1lczsKCQkJfQoJCX0KCQkjcmVnaW9uIFdvcmtib29rIFByb3BlcnRpZXMKCQlkZWNpbWFsIF9zdGFuZGFyZEZvbnRXaWR0aCA9IGRlY2ltYWwuTWluVmFsdWU7CiAgICAgICAgc3RyaW5nIF9mb250SUQgPSAiIjsKICAgICAgICBpbnRlcm5hbCBGb3JtdWxhUGFyc2VyIEZvcm11bGFQYXJzZXIKICAgICAgICB7CiAgICAgICAgICAgIGdldAogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBpZiAoX2Zvcm11bGFQYXJzZXIgPT0gbnVsbCkKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICBfZm9ybXVsYVBhcnNlciA9IG5ldyBGb3JtdWxhUGFyc2VyKG5ldyBFcHBsdXNFeGNlbERhdGFQcm92aWRlcihfcGFja2FnZSkpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgcmV0dXJuIF9mb3JtdWxhUGFyc2VyOwogICAgICAgICAgICB9CiAgICAgICAgfQoKCSAgICBwdWJsaWMgRm9ybXVsYVBhcnNlck1hbmFnZXIgRm9ybXVsYVBhcnNlck1hbmFnZXIKCSAgICB7CgkgICAgICAgIGdldAoJICAgICAgICB7CgkgICAgICAgICAgICBpZiAoX3BhcnNlck1hbmFnZXIgPT0gbnVsbCkKCSAgICAgICAgICAgIHsKCSAgICAgICAgICAgICAgICBfcGFyc2VyTWFuYWdlciA9IG5ldyBGb3JtdWxhUGFyc2VyTWFuYWdlcihGb3JtdWxhUGFyc2VyKTsKCSAgICAgICAgICAgIH0KCSAgICAgICAgICAgIHJldHVybiBfcGFyc2VyTWFuYWdlcjsKCSAgICAgICAgfQoJICAgIH0KCiAgICAgICAgLy8vIDxzdW1tYXJ5PgoJCS8vLyBNYXggZm9udCB3aWR0aCBmb3IgdGhlIHdvcmtib29rCiAgICAgICAgLy8vIDxyZW1hcmtzPlRoaXMgbWV0aG9kIHVzZXMgR0RJLiBJZiB5b3UgdXNlIEFzdXJlIG9yIGFub3RoZXIgZW52aXJvbm1lbnQgdGhhdCBkb2VzIG5vdCBzdXBwb3J0IEdESSwgeW91IGhhdmUgdG8gc2V0IHRoaXMgdmFsdWUgbWFudWFsbHkgaWYgeW91IGRvbid0IHVzZSB0aGUgc3RhbmRhcmQgQ2FsaWJyaSBmb250PC9yZW1hcmtzPgoJCS8vLyA8L3N1bW1hcnk+CgkJcHVibGljIGRlY2ltYWwgTWF4Rm9udFdpZHRoIAoJCXsKCQkJZ2V0CgkJCXsKICAgICAgICAgICAgICAgIGlmIChfc3RhbmRhcmRGb250V2lkdGggPT0gZGVjaW1hbC5NaW5WYWx1ZSB8fCBfZm9udElEICE9IFN0eWxlcy5Gb250c1swXS5JZCkKCQkJCXsKCQkJCQl2YXIgZm9udCA9IFN0eWxlcy5Gb250c1swXTsKICAgICAgICAgICAgICAgICAgICB0cnkKICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgIHZhciBmID0gbmV3IEZvbnQoZm9udC5OYW1lLCBmb250LlNpemUpOwogICAgICAgICAgICAgICAgICAgICAgICBfc3RhbmRhcmRGb250V2lkdGggPSAwOwogICAgICAgICAgICAgICAgICAgICAgICBfZm9udElEID0gZm9udC5JZDsKICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgLy9SZW1vdmUgdGhlIFByZXNlbnRhaW9uQ29yZSBEZXBlbmRlbmNleS4gVGhpcyBtaWdodCBlZmZlY3QgY29tcG9uZW50cyBydW5uaW5nIHVuZGVyIEF6dXJlIG5vdCBoYXZpbmcgc3VwcG9ydCBmb3IgR0RJKwoKICAgICAgICAgICAgICAgICAgICAgICAgLy9UeXBlZmFjZSB0ZiA9IG5ldyBUeXBlZmFjZShuZXcgU3lzdGVtLldpbmRvd3MuTWVkaWEuRm9udEZhbWlseShmb250Lk5hbWUpLAogICAgICAgICAgICAgICAgICAgICAgICAvLy8vICAgICAgICAgICAgICAgICAgICAgICAgICAgICAoZm9udC5JdGFsaWMpID8gRm9udFN0eWxlcy5Ob3JtYWwgOiBGb250U3R5bGVzLkl0YWxpYywKICAgICAgICAgICAgICAgICAgICAgICAgLy8gICAgICAgICAgICAgICAgICAgICAgICAgICAgIChmb250LkJvbGQpID8gRm9udFdlaWdodHMuQm9sZCA6IEZvbnRXZWlnaHRzLk5vcm1hbCwKICAgICAgICAgICAgICAgICAgICAgICAgLy8gICAgICAgICAgICAgICAgICAgICAgICAgICAgIEZvbnRTdHJldGNoZXMuTm9ybWFsKTsKICAgICAgICAgICAgICAgICAgICAgICAgLy9mb3IoaW50IGk9MDtpPDEwO2krKykKICAgICAgICAgICAgICAgICAgICAgICAgLy97CiAgICAgICAgICAgICAgICAgICAgICAgIC8vICAgIHZhciBmdCA9IG5ldyBTeXN0ZW0uV2luZG93cy5NZWRpYS5Gb3JtYXR0ZWRUZXh0KCIwMTIzNDU2Nzg5Ii5TdWJzdHJpbmcoaSwxKSwgQ3VsdHVyZUluZm8uSW52YXJpYW50Q3VsdHVyZSwgU3lzdGVtLldpbmRvd3MuRmxvd0RpcmVjdGlvbi5MZWZ0VG9SaWdodCwgdGYsIGZvbnQuU2l6ZSAqICg5NkQgLyA3MkQpLCBuZXcgRHJhd2luZ0JydXNoKCkpOwogICAgICAgICAgICAgICAgICAgICAgICAvLyAgICB2YXIgd2lkdGg9KGludClNYXRoLlJvdW5kKGZ0LldpZHRoLDApOyAgIAogICAgICAgICAgICAgICAgICAgICAgICAvLyAgICBpZih3aWR0aD5fc3RhbmRhcmRGb250V2lkdGgpCiAgICAgICAgICAgICAgICAgICAgICAgIC8vICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgLy8gICAgICAgIF9zdGFuZGFyZEZvbnRXaWR0aCA9IHdpZHRoOwogICAgICAgICAgICAgICAgICAgICAgICAvLyAgICB9CiAgICAgICAgICAgICAgICAgICAgICAgIC8vfQoKICAgICAgICAgICAgICAgICAgICAgICAgLy92YXIgc2l6ZSA9IG5ldyBTeXN0ZW0uV2luZG93cy5TaXplIHsgV2lkdGggPSBmdC5XaWR0aEluY2x1ZGluZ1RyYWlsaW5nV2hpdGVzcGFjZSwgSGVpZ2h0ID0gZnQuSGVpZ2h0IH07CgogICAgICAgICAgICAgICAgICAgICAgICBfc3RhbmRhcmRGb250V2lkdGggPSBHZXRXaWR0aFBpeGVscyhmLCIxMjM0NTY3ODkwIik7CiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChfc3RhbmRhcmRGb250V2lkdGggPD0gMCkgLy9ObyBHREk/CiAgICAgICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIF9zdGFuZGFyZEZvbnRXaWR0aCA9IChpbnQpKGZvbnQuU2l6ZSAqICgyRCAvIDNEKSk7IC8vQXByb3guIGZvciBDYWxpYnJpLgogICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIGNhdGNoICAgLy9FcnJvciwgc2V0IGRlZmF1bHQgdmFsdWUKICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgIF9zdGFuZGFyZEZvbnRXaWR0aCA9IChpbnQpKGZvbnQuU2l6ZSAqICgyRCAvIDNEKSk7IC8vQXByb3ggZm9yIENhbGlicmkuCiAgICAgICAgICAgICAgICAgICAgfQoJCQkJfQoJCQkJcmV0dXJuIF9zdGFuZGFyZEZvbnRXaWR0aDsKCQkJfQogICAgICAgICAgICBzZXQKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgX3N0YW5kYXJkRm9udFdpZHRoID0gdmFsdWU7CiAgICAgICAgICAgIH0KCQl9CgoJICAgIGludGVybmFsIHN0YXRpYyBkZWNpbWFsIEdldFdpZHRoUGl4ZWxzKEZvbnQgZiwgc3RyaW5nIHMpCgkgICAgewoJICAgICAgICB2YXIgcmV0ID0gME07CiAgICAgICAgICAgIHVzaW5nICh2YXIgYiA9IG5ldyBCaXRtYXAoMSwgMSkpCgkgICAgICAgIHsKCSAgICAgICAgICAgIHVzaW5nIChHcmFwaGljcyBnID0gR3JhcGhpY3MuRnJvbUltYWdlKGIpKQoJICAgICAgICAgICAgewoJICAgICAgICAgICAgICAgIGcuUGFnZVVuaXQgPSBHcmFwaGljc1VuaXQuUGl4ZWw7CgoJICAgICAgICAgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgcy5MZW5ndGg7IGkrKykKCSAgICAgICAgICAgICAgICB7CgkgICAgICAgICAgICAgICAgICAgIHZhciBjID0gc1tpXTsKCSAgICAgICAgICAgICAgICAgICAgdmFyIHdpZHRoID0KCSAgICAgICAgICAgICAgICAgICAgICAgIChkZWNpbWFsKQoJICAgICAgICAgICAgICAgICAgICAgICAgICAgIE1hdGguVHJ1bmNhdGUoCgkgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGcuTWVhc3VyZVN0cmluZyhuZXcgc3RyaW5nKGMsIDIpLCBmLCAxMDAwLCBTdHJpbmdGb3JtYXQuR2VuZXJpY1R5cG9ncmFwaGljKS5XaWR0aCAtCgkgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGcuTWVhc3VyZVN0cmluZyhuZXcgc3RyaW5nKGMsIDEpLCBmLCAxMDAwLCBTdHJpbmdGb3JtYXQuR2VuZXJpY1R5cG9ncmFwaGljKS5XaWR0aCk7CiAgICAgICAgICAgICAgICAgICAgICAgIGlmICh3aWR0aCA+IHJldCkKCSAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgcmV0ID0gd2lkdGg7CgkgICAgICAgICAgICAgICAgICAgIH0KCSAgICAgICAgICAgICAgICB9CgkgICAgICAgICAgICB9CgkgICAgICAgIH0KCSAgICAgICAgcmV0dXJuIHJldDsKCSAgICB9CgoJICAgIEV4Y2VsUHJvdGVjdGlvbiBfcHJvdGVjdGlvbiA9IG51bGw7CgkJLy8vIDxzdW1tYXJ5PgoJCS8vLyBBY2Nlc3MgcHJvcGVydGllcyB0byBwcm90ZWN0IG9yIHVucHJvdGVjdCBhIHdvcmtib29rCgkJLy8vIDwvc3VtbWFyeT4KCQlwdWJsaWMgRXhjZWxQcm90ZWN0aW9uIFByb3RlY3Rpb24KCQl7CgkJCWdldAoJCQl7CgkJCQlpZiAoX3Byb3RlY3Rpb24gPT0gbnVsbCkKCQkJCXsKCQkJCQlfcHJvdGVjdGlvbiA9IG5ldyBFeGNlbFByb3RlY3Rpb24oTmFtZVNwYWNlTWFuYWdlciwgVG9wTm9kZSwgdGhpcyk7CgkJCQkJX3Byb3RlY3Rpb24uU2NoZW1hTm9kZU9yZGVyID0gU2NoZW1hTm9kZU9yZGVyOwoJCQkJfQoJCQkJcmV0dXJuIF9wcm90ZWN0aW9uOwoJCQl9CgkJfSAgICAgICAgCgkJRXhjZWxXb3JrYm9va1ZpZXcgX3ZpZXcgPSBudWxsOwoJCS8vLyA8c3VtbWFyeT4KCQkvLy8gQWNjZXNzIHRvIHdvcmtib29rIHZpZXcgcHJvcGVydGllcwoJCS8vLyA8L3N1bW1hcnk+CgkJcHVibGljIEV4Y2VsV29ya2Jvb2tWaWV3IFZpZXcKCQl7CgkJCWdldAoJCQl7CgkJCQlpZiAoX3ZpZXcgPT0gbnVsbCkKCQkJCXsKCQkJCQlfdmlldyA9IG5ldyBFeGNlbFdvcmtib29rVmlldyhOYW1lU3BhY2VNYW5hZ2VyLCBUb3BOb2RlLCB0aGlzKTsKCQkJCX0KCQkJCXJldHVybiBfdmlldzsKCQkJfQoJCX0KICAgICAgICBFeGNlbFZiYVByb2plY3QgX3ZiYSA9IG51bGw7CiAgICAgICAgLy8vIDxzdW1tYXJ5PgogICAgICAgIC8vLyBBIHJlZmVyZW5jZSB0byB0aGUgVkJBIHByb2plY3QuCiAgICAgICAgLy8vIE51bGwgaWYgbm8gcHJvamVjdCBleGlzdHMuCiAgICAgICAgLy8vIFVzZSBXb3JrYm9vay5DcmVhdGVWQkFQcm9qZWN0IHRvIGNyZWF0ZSBhIG5ldyBWQkEtUHJvamVjdAogICAgICAgIC8vLyA8L3N1bW1hcnk+CiAgICAgICAgcHVibGljIEV4Y2VsVmJhUHJvamVjdCBWYmFQcm9qZWN0CiAgICAgICAgewogICAgICAgICAgICBnZXQKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgaWYgKF92YmEgPT0gbnVsbCkKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICBpZihfcGFja2FnZS5QYWNrYWdlLlBhcnRFeGlzdHMobmV3IFVyaShFeGNlbFZiYVByb2plY3QuUGFydFVyaSwgVXJpS2luZC5SZWxhdGl2ZSkpKQogICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgX3ZiYSA9IG5ldyBFeGNlbFZiYVByb2plY3QodGhpcyk7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgcmV0dXJuIF92YmE7CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIC8vLyA8c3VtbWFyeT4KICAgICAgICAvLy8gQ3JlYXRlIGFuIGVtcHR5IFZCQSBwcm9qZWN0LgogICAgICAgIC8vLyA8L3N1bW1hcnk+CiAgICAgICAgcHVibGljIHZvaWQgQ3JlYXRlVkJBUHJvamVjdCgpCiAgICAgICAgewojaWYgIU1PTk8KICAgICAgICAgICAgaWYgKF92YmEgIT0gbnVsbCB8fCBfcGFja2FnZS5QYWNrYWdlLlBhcnRFeGlzdHMobmV3IFVyaShFeGNlbFZiYVByb2plY3QuUGFydFVyaSwgVXJpS2luZC5SZWxhdGl2ZSkpKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICB0aHJvdyAobmV3IEludmFsaWRPcGVyYXRpb25FeGNlcHRpb24oIlZCQSBwcm9qZWN0IGFscmVhZHkgZXhpc3RzLiIpKTsKICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgX3ZiYSA9IG5ldyBFeGNlbFZiYVByb2plY3QodGhpcyk7CiAgICAgICAgICAgIF92YmEuQ3JlYXRlKCk7CiNlbmRpZgojaWYgTU9OTwogICAgICAgICAgICB0aHJvdyBuZXcgTm90U3VwcG9ydGVkRXhjZXB0aW9uKCJDcmVhdGluZyBhIFZCQSBwcm9qZWN0IGlzIG5vdCBzdXBwb3J0ZWQgdW5kZXIgTW9uby4iKTsKI2VuZGlmCgkJCQl9CgkJLy8vIDxzdW1tYXJ5PgoJCS8vLyBVUkkgdG8gdGhlIHdvcmtib29rIGluc2lkZSB0aGUgcGFja2FnZQoJCS8vLyA8L3N1bW1hcnk+CgkJaW50ZXJuYWwgVXJpIFdvcmtib29rVXJpIHsgZ2V0OyBwcml2YXRlIHNldDsgfQoJCS8vLyA8c3VtbWFyeT4KICAgICAgICAvLy8gVVJJIHRvIHRoZSBzdHlsZXMgaW5zaWRlIHRoZSBwYWNrYWdlCgkJLy8vIDwvc3VtbWFyeT4KCQlpbnRlcm5hbCBVcmkgU3R5bGVzVXJpIHsgZ2V0OyBwcml2YXRlIHNldDsgfQoJCS8vLyA8c3VtbWFyeT4KICAgICAgICAvLy8gVVJJIHRvIHRoZSBzaGFyZWQgc3RyaW5ncyBpbnNpZGUgdGhlIHBhY2thZ2UKCQkvLy8gPC9zdW1tYXJ5PgoJCWludGVybmFsIFVyaSBTaGFyZWRTdHJpbmdzVXJpIHsgZ2V0OyBwcml2YXRlIHNldDsgfQoJCS8vLyA8c3VtbWFyeT4KCQkvLy8gUmV0dXJucyBhIHJlZmVyZW5jZSB0byB0aGUgd29ya2Jvb2sncyBwYXJ0IHdpdGhpbiB0aGUgcGFja2FnZQoJCS8vLyA8L3N1bW1hcnk+CgkJaW50ZXJuYWwgUGFja2FnaW5nLlppcFBhY2thZ2VQYXJ0IFBhcnQgeyBnZXQgeyByZXR1cm4gKF9wYWNrYWdlLlBhY2thZ2UuR2V0UGFydChXb3JrYm9va1VyaSkpOyB9IH0KCQkKCQkjcmVnaW9uIFdvcmtib29rWG1sCgkJcHJpdmF0ZSBYbWxEb2N1bWVudCBfd29ya2Jvb2tYbWw7CgkJLy8vIDxzdW1tYXJ5PgoJCS8vLyBQcm92aWRlcyBhY2Nlc3MgdG8gdGhlIFhNTCBkYXRhIHJlcHJlc2VudGluZyB0aGUgd29ya2Jvb2sgaW4gdGhlIHBhY2thZ2UuCgkJLy8vIDwvc3VtbWFyeT4KCQlwdWJsaWMgWG1sRG9jdW1lbnQgV29ya2Jvb2tYbWwKCQl7CgkJCWdldAoJCQl7CgkJCQlpZiAoX3dvcmtib29rWG1sID09IG51bGwpCgkJCQl7CgkJCQkJQ3JlYXRlV29ya2Jvb2tYbWwoX25hbWVzcGFjZU1hbmFnZXIpOwoJCQkJfQoJCQkJcmV0dXJuIChfd29ya2Jvb2tYbWwpOwoJCQl9CgkJfQogICAgICAgIGNvbnN0IHN0cmluZyBjb2RlTW9kdWxlTmFtZVBhdGggPSAiZDp3b3JrYm9va1ByL0Bjb2RlTmFtZSI7CiAgICAgICAgaW50ZXJuYWwgc3RyaW5nIENvZGVNb2R1bGVOYW1lCiAgICAgICAgewogICAgICAgICAgICBnZXQKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgcmV0dXJuIEdldFhtbE5vZGVTdHJpbmcoY29kZU1vZHVsZU5hbWVQYXRoKTsKICAgICAgICAgICAgfQogICAgICAgICAgICBzZXQKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgU2V0WG1sTm9kZVN0cmluZyhjb2RlTW9kdWxlTmFtZVBhdGgsdmFsdWUpOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIGludGVybmFsIHZvaWQgQ29kZU5hbWVDaGFuZ2Uoc3RyaW5nIHZhbHVlKQogICAgICAgIHsKICAgICAgICAgICAgQ29kZU1vZHVsZU5hbWUgPSB2YWx1ZTsKICAgICAgICB9CiAgICAgICAgcHVibGljIFZCQS5FeGNlbFZCQU1vZHVsZSBDb2RlTW9kdWxlCiAgICAgICAgewogICAgICAgICAgICBnZXQKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgaWYgKFZiYVByb2plY3QgIT0gbnVsbCkKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICByZXR1cm4gVmJhUHJvamVjdC5Nb2R1bGVzW0NvZGVNb2R1bGVOYW1lXTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGVsc2UKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICByZXR1cm4gbnVsbDsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgY29uc3Qgc3RyaW5nIGRhdGUxOTA0UGF0aCA9ICJkOndvcmtib29rUHIvQGRhdGUxOTA0IjsKICAgICAgICBpbnRlcm5hbCBjb25zdCBkb3VibGUgZGF0ZTE5MDRPZmZzZXQgPSAzNjUuNSAqIDQ7ICAvLyBvZmZzZXQgdG8gZml4IDE5MDAgYW5kIDE5MDQgZGlmZmVyZW5jZXMsIDQgT0xFIHllYXJzCiAgICAgICAgLy8vIDxzdW1tYXJ5PgogICAgICAgIC8vLyBUaGUgZGF0ZSBzeXN0ZW1zIHVzZWQgYnkgTWljcm9zb2Z0IEV4Y2VsIGNhbiBiZSBiYXNlZCBvbiBvbmUgb2YgdHdvIGRpZmZlcmVudCBkYXRlcy4gQnkgZGVmYXVsdCwgYSBzZXJpYWwgbnVtYmVyIG9mIDEgaW4gTWljcm9zb2Z0IEV4Y2VsIHJlcHJlc2VudHMgSmFudWFyeSAxLCAxOTAwLgogICAgICAgIC8vLyBUaGUgZGVmYXVsdCBmb3IgdGhlIHNlcmlhbCBudW1iZXIgMSBjYW4gYmUgY2hhbmdlZCB0byByZXByZXNlbnQgSmFudWFyeSAyLCAxOTA0LgogICAgICAgIC8vLyBUaGlzIG9wdGlvbiB3YXMgaW5jbHVkZWQgaW4gTWljcm9zb2Z0IEV4Y2VsIGZvciBXaW5kb3dzIHRvIG1ha2UgaXQgY29tcGF0aWJsZSB3aXRoIEV4Y2VsIGZvciB0aGUgTWFjaW50b3NoLCB3aGljaCBkZWZhdWx0cyB0byBKYW51YXJ5IDIsIDE5MDQuCiAgICAgICAgLy8vIDwvc3VtbWFyeT4KICAgICAgICBwdWJsaWMgYm9vbCBEYXRlMTkwNAogICAgICAgIHsKICAgICAgICAgICAgZ2V0CiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIHJldHVybiBHZXRYbWxOb2RlQm9vbChkYXRlMTkwNFBhdGgsIGZhbHNlKTsKICAgICAgICAgICAgICAgCiAgICAgICAgICAgIH0KICAgICAgICAgICAgc2V0CiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIGlmIChEYXRlMTkwNCAhPSB2YWx1ZSkKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAvLyBMaWtlIEV4Y2VsIHdoZW4gdGhlIG9wdGlvbiBpdCdzIGNoYW5nZWQgdXBkYXRlIGl0IGFsbCBjZWxscyB3aXRoIERhdGUgZm9ybWF0CiAgICAgICAgICAgICAgICAgICAgZm9yZWFjaCAodmFyIGl0ZW0gaW4gV29ya3NoZWV0cykKICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgIGl0ZW0uVXBkYXRlQ2VsbHNXaXRoRGF0ZTE5MDRTZXR0aW5nKCk7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgIFNldFhtbE5vZGVCb29sKGRhdGUxOTA0UGF0aCwgdmFsdWUsIGZhbHNlKTsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgICAKICAgICAgIAoJCS8vLyA8c3VtbWFyeT4KCQkvLy8gQ3JlYXRlIG9yIHJlYWQgdGhlIFhNTCBmb3IgdGhlIHdvcmtib29rLgoJCS8vLyA8L3N1bW1hcnk+CgkJcHJpdmF0ZSB2b2lkIENyZWF0ZVdvcmtib29rWG1sKFhtbE5hbWVzcGFjZU1hbmFnZXIgbmFtZXNwYWNlTWFuYWdlcikKCQl7CgkJCWlmIChfcGFja2FnZS5QYWNrYWdlLlBhcnRFeGlzdHMoV29ya2Jvb2tVcmkpKQoJCQkJX3dvcmtib29rWG1sID0gX3BhY2thZ2UuR2V0WG1sRnJvbVVyaShXb3JrYm9va1VyaSk7CgkJCWVsc2UKCQkJewoJCQkJLy8gY3JlYXRlIGEgbmV3IHdvcmtib29rIHBhcnQgYW5kIGFkZCB0byB0aGUgcGFja2FnZQoJCQkJUGFja2FnaW5nLlppcFBhY2thZ2VQYXJ0IHBhcnRXb3JrYm9vayA9IF9wYWNrYWdlLlBhY2thZ2UuQ3JlYXRlUGFydChXb3JrYm9va1VyaSwgQCJhcHBsaWNhdGlvbi92bmQub3BlbnhtbGZvcm1hdHMtb2ZmaWNlZG9jdW1lbnQuc3ByZWFkc2hlZXRtbC5zaGVldC5tYWluK3htbCIsIF9wYWNrYWdlLkNvbXByZXNzaW9uKTsKCgkJCQkvLyBjcmVhdGUgdGhlIHdvcmtib29rCgkJCQlfd29ya2Jvb2tYbWwgPSBuZXcgWG1sRG9jdW1lbnQobmFtZXNwYWNlTWFuYWdlci5OYW1lVGFibGUpOyAgICAgICAgICAgICAgICAKCQkJCQoJCQkJX3dvcmtib29rWG1sLlByZXNlcnZlV2hpdGVzcGFjZSA9IEV4Y2VsUGFja2FnZS5wcmVzZXJ2ZVdoaXRlc3BhY2U7CgkJCQkvLyBjcmVhdGUgdGhlIHdvcmtib29rIGVsZW1lbnQKCQkJCVhtbEVsZW1lbnQgd2JFbGVtID0gX3dvcmtib29rWG1sLkNyZWF0ZUVsZW1lbnQoIndvcmtib29rIiwgRXhjZWxQYWNrYWdlLnNjaGVtYU1haW4pOwoKCQkJCS8vIEFkZCB0aGUgcmVsYXRpb25zaGlwcyBuYW1lc3BhY2UKCQkJCXdiRWxlbS5TZXRBdHRyaWJ1dGUoInhtbG5zOnIiLCBFeGNlbFBhY2thZ2Uuc2NoZW1hUmVsYXRpb25zaGlwcyk7CgoJCQkJX3dvcmtib29rWG1sLkFwcGVuZENoaWxkKHdiRWxlbSk7CgoJCQkJLy8gY3JlYXRlIHRoZSBib29rVmlld3MgYW5kIHdvcmtib29rcyBlbGVtZW50CgkJCQlYbWxFbGVtZW50IGJvb2tWaWV3cyA9IF93b3JrYm9va1htbC5DcmVhdGVFbGVtZW50KCJib29rVmlld3MiLCBFeGNlbFBhY2thZ2Uuc2NoZW1hTWFpbik7CgkJCQl3YkVsZW0uQXBwZW5kQ2hpbGQoYm9va1ZpZXdzKTsKCQkJCVhtbEVsZW1lbnQgd29ya2Jvb2tWaWV3ID0gX3dvcmtib29rWG1sLkNyZWF0ZUVsZW1lbnQoIndvcmtib29rVmlldyIsIEV4Y2VsUGFja2FnZS5zY2hlbWFNYWluKTsKCQkJCWJvb2tWaWV3cy5BcHBlbmRDaGlsZCh3b3JrYm9va1ZpZXcpOwoKCQkJCS8vIHNhdmUgaXQgdG8gdGhlIHBhY2thZ2UKCQkJCVN0cmVhbVdyaXRlciBzdHJlYW0gPSBuZXcgU3RyZWFtV3JpdGVyKHBhcnRXb3JrYm9vay5HZXRTdHJlYW0oRmlsZU1vZGUuQ3JlYXRlLCBGaWxlQWNjZXNzLldyaXRlKSk7CgkJCQlfd29ya2Jvb2tYbWwuU2F2ZShzdHJlYW0pOwoJCQkJLy9zdHJlYW0uQ2xvc2UoKTsKCQkJCV9wYWNrYWdlLlBhY2thZ2UuRmx1c2goKTsKCQkJfQoJCX0KCQkjZW5kcmVnaW9uCgkJI3JlZ2lvbiBTdHlsZXNYbWwKCQlwcml2YXRlIFhtbERvY3VtZW50IF9zdHlsZXNYbWw7CgkJLy8vIDxzdW1tYXJ5PgoJCS8vLyBQcm92aWRlcyBhY2Nlc3MgdG8gdGhlIFhNTCBkYXRhIHJlcHJlc2VudGluZyB0aGUgc3R5bGVzIGluIHRoZSBwYWNrYWdlLiAKCQkvLy8gPC9zdW1tYXJ5PgoJCXB1YmxpYyBYbWxEb2N1bWVudCBTdHlsZXNYbWwKCQl7CgkJCWdldAoJCQl7CgkJCQlpZiAoX3N0eWxlc1htbCA9PSBudWxsKQoJCQkJewoJCQkJCWlmIChfcGFja2FnZS5QYWNrYWdlLlBhcnRFeGlzdHMoU3R5bGVzVXJpKSkKCQkJCQkJX3N0eWxlc1htbCA9IF9wYWNrYWdlLkdldFhtbEZyb21VcmkoU3R5bGVzVXJpKTsKCQkJCQllbHNlCgkJCQkJewoJCQkJCQkvLyBjcmVhdGUgYSBuZXcgc3R5bGVzIHBhcnQgYW5kIGFkZCB0byB0aGUgcGFja2FnZQoJCQkJCQlQYWNrYWdpbmcuWmlwUGFja2FnZVBhcnQgcGFydCA9IF9wYWNrYWdlLlBhY2thZ2UuQ3JlYXRlUGFydChTdHlsZXNVcmksIEAiYXBwbGljYXRpb24vdm5kLm9wZW54bWxmb3JtYXRzLW9mZmljZWRvY3VtZW50LnNwcmVhZHNoZWV0bWwuc3R5bGVzK3htbCIsIF9wYWNrYWdlLkNvbXByZXNzaW9uKTsKCQkJCQkJLy8gY3JlYXRlIHRoZSBzdHlsZSBzaGVldAoKCQkJCQkJU3RyaW5nQnVpbGRlciB4bWwgPSBuZXcgU3RyaW5nQnVpbGRlcigiPHN0eWxlU2hlZXQgeG1sbnM9XCJodHRwOi8vc2NoZW1hcy5vcGVueG1sZm9ybWF0cy5vcmcvc3ByZWFkc2hlZXRtbC8yMDA2L21haW5cIj4iKTsKCQkJCQkJeG1sLkFwcGVuZCgiPG51bUZtdHMgLz4iKTsKCQkJCQkJeG1sLkFwcGVuZCgiPGZvbnRzIGNvdW50PVwiMVwiPjxmb250PjxzeiB2YWw9XCIxMVwiIC8+PG5hbWUgdmFsPVwiQ2FsaWJyaVwiIC8+PC9mb250PjwvZm9udHM+Iik7CgkJCQkJCXhtbC5BcHBlbmQoIjxmaWxscz48ZmlsbD48cGF0dGVybkZpbGwgcGF0dGVyblR5cGU9XCJub25lXCIgLz48L2ZpbGw+PGZpbGw+PHBhdHRlcm5GaWxsIHBhdHRlcm5UeXBlPVwiZ3JheTEyNVwiIC8+PC9maWxsPjwvZmlsbHM+Iik7CgkJCQkJCXhtbC5BcHBlbmQoIjxib3JkZXJzPjxib3JkZXI+PGxlZnQgLz48cmlnaHQgLz48dG9wIC8+PGJvdHRvbSAvPjxkaWFnb25hbCAvPjwvYm9yZGVyPjwvYm9yZGVycz4iKTsKCQkJCQkJeG1sLkFwcGVuZCgiPGNlbGxTdHlsZVhmcyBjb3VudD1cIjFcIj48eGYgbnVtRm10SWQ9XCIwXCIgZm9udElkPVwiMFwiIC8+PC9jZWxsU3R5bGVYZnM+Iik7CgkJCQkJCXhtbC5BcHBlbmQoIjxjZWxsWGZzIGNvdW50PVwiMVwiPjx4ZiBudW1GbXRJZD1cIjBcIiBmb250SWQ9XCIwXCIgeGZJZD1cIjBcIiAvPjwvY2VsbFhmcz4iKTsKCQkJCQkJeG1sLkFwcGVuZCgiPGNlbGxTdHlsZXM+PGNlbGxTdHlsZSBuYW1lPVwiTm9ybWFsXCIgeGZJZD1cIjBcIiBidWlsdGluSWQ9XCIwXCIgLz48L2NlbGxTdHlsZXM+Iik7CiAgICAgICAgICAgICAgICAgICAgICAgIHhtbC5BcHBlbmQoIjxkeGZzIGNvdW50PVwiMFwiIC8+Iik7CiAgICAgICAgICAgICAgICAgICAgICAgIHhtbC5BcHBlbmQoIjwvc3R5bGVTaGVldD4iKTsKCQkJCQkJCgkJCQkJCV9zdHlsZXNYbWwgPSBuZXcgWG1sRG9jdW1lbnQoKTsKCQkJCQkJX3N0eWxlc1htbC5Mb2FkWG1sKHhtbC5Ub1N0cmluZygpKTsKCQkJCQkJCgkJCQkJCS8vU2F2ZSBpdCB0byB0aGUgcGFja2FnZQoJCQkJCQlTdHJlYW1Xcml0ZXIgc3RyZWFtID0gbmV3IFN0cmVhbVdyaXRlcihwYXJ0LkdldFN0cmVhbShGaWxlTW9kZS5DcmVhdGUsIEZpbGVBY2Nlc3MuV3JpdGUpKTsKCgkJCQkJCV9zdHlsZXNYbWwuU2F2ZShzdHJlYW0pOwoJCQkJCQkvL3N0cmVhbS5DbG9zZSgpOwoJCQkJCQlfcGFja2FnZS5QYWNrYWdlLkZsdXNoKCk7CgoJCQkJCQkvLyBjcmVhdGUgdGhlIHJlbGF0aW9uc2hpcCBiZXR3ZWVuIHRoZSB3b3JrYm9vayBhbmQgdGhlIG5ldyBzaGFyZWQgc3RyaW5ncyBwYXJ0CgkJCQkJCV9wYWNrYWdlLldvcmtib29rLlBhcnQuQ3JlYXRlUmVsYXRpb25zaGlwKFVyaUhlbHBlci5HZXRSZWxhdGl2ZVVyaShXb3JrYm9va1VyaSwgU3R5bGVzVXJpKSwgUGFja2FnaW5nLlRhcmdldE1vZGUuSW50ZXJuYWwsIEV4Y2VsUGFja2FnZS5zY2hlbWFSZWxhdGlvbnNoaXBzICsgIi9zdHlsZXMiKTsKCQkJCQkJX3BhY2thZ2UuUGFja2FnZS5GbHVzaCgpOwoJCQkJCX0KCQkJCX0KCQkJCXJldHVybiAoX3N0eWxlc1htbCk7CgkJCX0KCQkJc2V0CgkJCXsKCQkJCV9zdHlsZXNYbWwgPSB2YWx1ZTsKCQkJfQoJCX0KCQkvLy8gPHN1bW1hcnk+CgkJLy8vIFBhY2thZ2Ugc3R5bGVzIGNvbGxlY3Rpb24uIFVzZWQgaW50ZXJuYWxseSB0byBhY2Nlc3Mgc3R5bGUgZGF0YS4KCQkvLy8gPC9zdW1tYXJ5PgoJCXB1YmxpYyBFeGNlbFN0eWxlcyBTdHlsZXMKCQl7CgkJCWdldAoJCQl7CgkJCQlpZiAoX3N0eWxlcyA9PSBudWxsKQoJCQkJewoJCQkJCV9zdHlsZXMgPSBuZXcgRXhjZWxTdHlsZXMoTmFtZVNwYWNlTWFuYWdlciwgU3R5bGVzWG1sLCB0aGlzKTsKCQkJCX0KCQkJCXJldHVybiBfc3R5bGVzOwoJCQl9CgkJfQoJCSNlbmRyZWdpb24KCgkJI3JlZ2lvbiBPZmZpY2UgRG9jdW1lbnQgUHJvcGVydGllcwoJCS8vLyA8c3VtbWFyeT4KCQkvLy8gVGhlIG9mZmljZSBkb2N1bWVudCBwcm9wZXJ0aWVzCgkJLy8vIDwvc3VtbWFyeT4KCQlwdWJsaWMgT2ZmaWNlUHJvcGVydGllcyBQcm9wZXJ0aWVzCgkJewoJCQlnZXQgCgkJCXsKCQkJCWlmIChfcHJvcGVydGllcyA9PSBudWxsKQoJCQkJewoJCQkJCS8vICBDcmVhdGUgYSBOYW1lc3BhY2VNYW5hZ2VyIHRvIGhhbmRsZSB0aGUgZGVmYXVsdCBuYW1lc3BhY2UsIAoJCQkJCS8vICBhbmQgY3JlYXRlIGEgcHJlZml4IGZvciB0aGUgZGVmYXVsdCBuYW1lc3BhY2U6ICAgICAgICAgICAgICAgICAgIAoJCQkJCV9wcm9wZXJ0aWVzID0gbmV3IE9mZmljZVByb3BlcnRpZXMoX3BhY2thZ2UsIE5hbWVTcGFjZU1hbmFnZXIpOwoJCQkJfQoJCQkJcmV0dXJuIF9wcm9wZXJ0aWVzOwoJCQl9CgkJfQoJCSNlbmRyZWdpb24KCgkJI3JlZ2lvbiBDYWxjTW9kZQoJCXByaXZhdGUgc3RyaW5nIENBTENfTU9ERV9QQVRIID0gImQ6Y2FsY1ByL0BjYWxjTW9kZSI7CgkJLy8vIDxzdW1tYXJ5PgoJCS8vLyBDYWxjdWxhdGlvbiBtb2RlIGZvciB0aGUgd29ya2Jvb2suCgkJLy8vIDwvc3VtbWFyeT4KCQlwdWJsaWMgRXhjZWxDYWxjTW9kZSBDYWxjTW9kZQoJCXsKCQkJZ2V0CgkJCXsKCQkJCXN0cmluZyBjYWxjTW9kZSA9IEdldFhtbE5vZGVTdHJpbmcoQ0FMQ19NT0RFX1BBVEgpOwoJCQkJc3dpdGNoIChjYWxjTW9kZSkKCQkJCXsKCQkJCQljYXNlICJhdXRvTm9UYWJsZSI6CgkJCQkJCXJldHVybiBFeGNlbENhbGNNb2RlLkF1dG9tYXRpY05vVGFibGU7CgkJCQkJY2FzZSAibWFudWFsIjoKCQkJCQkJcmV0dXJuIEV4Y2VsQ2FsY01vZGUuTWFudWFsOwoJCQkJCWRlZmF1bHQ6CgkJCQkJCXJldHVybiBFeGNlbENhbGNNb2RlLkF1dG9tYXRpYzsKICAgICAgICAgICAgICAgICAgICAgICAgCgkJCQl9CgkJCX0KCQkJc2V0CgkJCXsKCQkJCXN3aXRjaCAodmFsdWUpCgkJCQl7CgkJCQkJY2FzZSBFeGNlbENhbGNNb2RlLkF1dG9tYXRpY05vVGFibGU6CgkJCQkJCVNldFhtbE5vZGVTdHJpbmcoQ0FMQ19NT0RFX1BBVEgsICJhdXRvTm9UYWJsZSIpIDsKCQkJCQkJYnJlYWs7CgkJCQkJY2FzZSBFeGNlbENhbGNNb2RlLk1hbnVhbDoKCQkJCQkJU2V0WG1sTm9kZVN0cmluZyhDQUxDX01PREVfUEFUSCwgIm1hbnVhbCIpOwoJCQkJCQlicmVhazsKCQkJCQlkZWZhdWx0OgoJCQkJCQlTZXRYbWxOb2RlU3RyaW5nKENBTENfTU9ERV9QQVRILCAiYXV0byIpOwoJCQkJCQlicmVhazsKCgkJCQl9CgkJCX0KCQkJI2VuZHJlZ2lvbgoJCX0KCiAgICAgICAgcHJpdmF0ZSBjb25zdCBzdHJpbmcgRlVMTF9DQUxDX09OX0xPQURfUEFUSCA9ICJkOmNhbGNQci9AZnVsbENhbGNPbkxvYWQiOwogICAgICAgIC8vLyA8c3VtbWFyeT4KICAgICAgICAvLy8gU2hvdWxkIEV4Y2VsIGRvIGEgZnVsbCBjYWxjdWxhdGlvbiBhZnRlciB0aGUgd29ya2Jvb2sgaGFzIGJlZW4gbG9hZGVkPwogICAgICAgIC8vLyA8cmVtYXJrcz5UaGlzIHByb3BlcnR5IGlzIGFsd2F5cyB0cnVlIGZvciBib3RoIG5ldyB3b3JrYm9va3MgYW5kIGxvYWRlZCB0ZW1wbGF0ZXMob24gbG9hZCkuIElmIHRoaXMgaXMgbm90IHRoZSB3YW50ZWQgYmVoYXZpb3Igc2V0IHRoaXMgcHJvcGVydHkgdG8gZmFsc2UuPC9yZW1hcmtzPgogICAgICAgIC8vLyA8L3N1bW1hcnk+CiAgICAgICAgcHVibGljIGJvb2wgRnVsbENhbGNPbkxvYWQKCSAgICB7CgkgICAgICAgIGdldAoJICAgICAgICB7CiAgICAgICAgICAgICAgICByZXR1cm4gR2V0WG1sTm9kZUJvb2woRlVMTF9DQUxDX09OX0xPQURfUEFUSCk7ICAgCgkgICAgICAgIH0KCSAgICAgICAgc2V0CgkgICAgICAgIHsKICAgICAgICAgICAgICAgIFNldFhtbE5vZGVCb29sKEZVTExfQ0FMQ19PTl9MT0FEX1BBVEgsIHZhbHVlKTsKCSAgICAgICAgfQoJICAgIH0KCQkjZW5kcmVnaW9uCgkJI3JlZ2lvbiBXb3JrYm9vayBQcml2YXRlIE1ldGhvZHMKCQkJCgkJI3JlZ2lvbiBTYXZlIC8vIFdvcmtib29rIFNhdmUKCQkvLy8gPHN1bW1hcnk+CgkJLy8vIFNhdmVzIHRoZSB3b3JrYm9vayBhbmQgYWxsIGl0cyBjb21wb25lbnRzIHRvIHRoZSBwYWNrYWdlLgoJCS8vLyBGb3IgaW50ZXJuYWwgdXNlIG9ubHkhCgkJLy8vIDwvc3VtbWFyeT4KCQlpbnRlcm5hbCB2b2lkIFNhdmUoKSAgLy8gV29ya2Jvb2sgU2F2ZQoJCXsKCQkJaWYgKFdvcmtzaGVldHMuQ291bnQgPT0gMCkKCQkJCXRocm93IG5ldyBJbnZhbGlkT3BlcmF0aW9uRXhjZXB0aW9uKCJUaGUgd29ya2Jvb2sgbXVzdCBjb250YWluIGF0IGxlYXN0IG9uZSB3b3Jrc2hlZXQiKTsKCgkJCURlbGV0ZUNhbGNDaGFpbigpOwoKICAgICAgICAgICAgaWYgKF92YmEgPT0gbnVsbCAmJiAhX3BhY2thZ2UuUGFja2FnZS5QYXJ0RXhpc3RzKG5ldyBVcmkoRXhjZWxWYmFQcm9qZWN0LlBhcnRVcmksIFVyaUtpbmQuUmVsYXRpdmUpKSkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgaWYgKFBhcnQuQ29udGVudFR5cGUgIT0gRXhjZWxQYWNrYWdlLmNvbnRlbnRUeXBlV29ya2Jvb2tEZWZhdWx0KQogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIFBhcnQuQ29udGVudFR5cGUgPSBFeGNlbFBhY2thZ2UuY29udGVudFR5cGVXb3JrYm9va0RlZmF1bHQ7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICAgICAgZWxzZQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBpZiAoUGFydC5Db250ZW50VHlwZSAhPSBFeGNlbFBhY2thZ2UuY29udGVudFR5cGVXb3JrYm9va01hY3JvRW5hYmxlZCkKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICBQYXJ0LkNvbnRlbnRUeXBlID0gRXhjZWxQYWNrYWdlLmNvbnRlbnRUeXBlV29ya2Jvb2tNYWNyb0VuYWJsZWQ7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KCQkJCiAgICAgICAgICAgIFVwZGF0ZURlZmluZWROYW1lc1htbCgpOwoKCQkJLy8gc2F2ZSB0aGUgd29ya2Jvb2sKCQkJaWYgKF93b3JrYm9va1htbCAhPSBudWxsKQoJCQl7CgkJCQlfcGFja2FnZS5TYXZlUGFydChXb3JrYm9va1VyaSwgX3dvcmtib29rWG1sKTsKCQkJfQoKCQkJLy8gc2F2ZSB0aGUgcHJvcGVydGllcyBvZiB0aGUgd29ya2Jvb2sKCQkJaWYgKF9wcm9wZXJ0aWVzICE9IG51bGwpCgkJCXsKCQkJCV9wcm9wZXJ0aWVzLlNhdmUoKTsKCQkJfQoKCQkJLy8gc2F2ZSB0aGUgc3R5bGUgc2hlZXQKCQkJU3R5bGVzLlVwZGF0ZVhtbCgpOwoJCQlfcGFja2FnZS5TYXZlUGFydChTdHlsZXNVcmksIF9zdHlsZXNYbWwpOwoKCQkJLy8gc2F2ZSBhbGwgdGhlIG9wZW4gd29ya3NoZWV0cwoJCQl2YXIgaXNQcm90ZWN0ZWQgPSBQcm90ZWN0aW9uLkxvY2tXaW5kb3dzIHx8IFByb3RlY3Rpb24uTG9ja1N0cnVjdHVyZTsKCQkJZm9yZWFjaCAoRXhjZWxXb3Jrc2hlZXQgd29ya3NoZWV0IGluIFdvcmtzaGVldHMpCgkJCXsKCQkJCWlmIChpc1Byb3RlY3RlZCAmJiBQcm90ZWN0aW9uLkxvY2tXaW5kb3dzKQoJCQkJewoJCQkJCXdvcmtzaGVldC5WaWV3LldpbmRvd1Byb3RlY3Rpb24gPSB0cnVlOwoJCQkJfQoJCQkJd29ya3NoZWV0LlNhdmUoKTsKICAgICAgICAgICAgICAgIHdvcmtzaGVldC5QYXJ0LlNhdmVIYW5kbGVyID0gd29ya3NoZWV0LlNhdmVIYW5kbGVyOwoJCQl9CgogICAgICAgICAgICB2YXIgcGFydCA9IF9wYWNrYWdlLlBhY2thZ2UuQ3JlYXRlUGFydChTaGFyZWRTdHJpbmdzVXJpLCBFeGNlbFBhY2thZ2UuY29udGVudFR5cGVTaGFyZWRTdHJpbmcsIF9wYWNrYWdlLkNvbXByZXNzaW9uKTsKICAgICAgICAgICAgcGFydC5TYXZlSGFuZGxlciA9IFNhdmVTaGFyZWRTdHJpbmdIYW5kbGVyOwogICAgICAgICAgICBQYXJ0LkNyZWF0ZVJlbGF0aW9uc2hpcChVcmlIZWxwZXIuR2V0UmVsYXRpdmVVcmkoV29ya2Jvb2tVcmksIFNoYXJlZFN0cmluZ3NVcmkpLCBQYWNrYWdpbmcuVGFyZ2V0TW9kZS5JbnRlcm5hbCwgRXhjZWxQYWNrYWdlLnNjaGVtYVJlbGF0aW9uc2hpcHMgKyAiL3NoYXJlZFN0cmluZ3MiKTsKICAgICAgICAgICAgLy9VcGRhdGVTaGFyZWRTdHJpbmdzWG1sKCk7CgkJCQoJCQkvLyBEYXRhIHZhbGlkYXRpb24KCQkJVmFsaWRhdGVEYXRhVmFsaWRhdGlvbnMoKTsKCiAgICAgICAgICAgIC8vVkJBCiAgICAgICAgICAgIGlmIChfdmJhIT1udWxsKQogICAgICAgICAgICB7CiNpZiAhTU9OTwogICAgICAgICAgICAgICAgVmJhUHJvamVjdC5TYXZlKCk7CiNlbmRpZgogICAgICAgICAgICB9CgoJCX0KCQlwcml2YXRlIHZvaWQgRGVsZXRlQ2FsY0NoYWluKCkKCQl7CgkJCS8vUmVtb3ZlIHRoZSBjYWxjIGNoYWluIGlmIGl0IGV4aXN0cy4KCQkJVXJpIHVyaUNhbGNDaGFpbiA9IG5ldyBVcmkoIi94bC9jYWxjQ2hhaW4ueG1sIiwgVXJpS2luZC5SZWxhdGl2ZSk7CgkJCWlmIChfcGFja2FnZS5QYWNrYWdlLlBhcnRFeGlzdHModXJpQ2FsY0NoYWluKSkKCQkJewoJCQkJVXJpIGNhbGNDaGFpbiA9IG5ldyBVcmkoImNhbGNDaGFpbi54bWwiLCBVcmlLaW5kLlJlbGF0aXZlKTsKCQkJCWZvcmVhY2ggKHZhciByZWxhdGlvbnNoaXAgaW4gX3BhY2thZ2UuV29ya2Jvb2suUGFydC5HZXRSZWxhdGlvbnNoaXBzKCkpCgkJCQl7CgkJCQkJaWYgKHJlbGF0aW9uc2hpcC5UYXJnZXRVcmkgPT0gY2FsY0NoYWluKQoJCQkJCXsKCQkJCQkJX3BhY2thZ2UuV29ya2Jvb2suUGFydC5EZWxldGVSZWxhdGlvbnNoaXAocmVsYXRpb25zaGlwLklkKTsKCQkJCQkJYnJlYWs7CgkJCQkJfQoJCQkJfQoJCQkJLy8gZGVsZXRlIHRoZSBjYWxjQ2hhaW4gcGFydAoJCQkJX3BhY2thZ2UuUGFja2FnZS5EZWxldGVQYXJ0KHVyaUNhbGNDaGFpbik7CgkJCX0KCQl9CgoJCXByaXZhdGUgdm9pZCBWYWxpZGF0ZURhdGFWYWxpZGF0aW9ucygpCgkJewoJCQlmb3JlYWNoICh2YXIgc2hlZXQgaW4gX3BhY2thZ2UuV29ya2Jvb2suV29ya3NoZWV0cykKCQkJewogICAgICAgICAgICAgICAgaWYgKCEoc2hlZXQgaXMgRXhjZWxDaGFydHNoZWV0KSkKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICBzaGVldC5EYXRhVmFsaWRhdGlvbnMuVmFsaWRhdGVBbGwoKTsKICAgICAgICAgICAgICAgIH0KCQkJfQoJCX0KCiAgICAgICAgcHJpdmF0ZSB2b2lkIFNhdmVTaGFyZWRTdHJpbmdIYW5kbGVyKFppcE91dHB1dFN0cmVhbSBzdHJlYW0sIENvbXByZXNzaW9uTGV2ZWwgY29tcHJlc3Npb25MZXZlbCwgc3RyaW5nIGZpbGVOYW1lKQoJCXsKICAgICAgICAgICAgLy9QYWNrYWdpbmcuWmlwUGFja2FnZVBhcnQgc3RyaW5nUGFydDsKICAgICAgICAgICAgLy9pZiAoX3BhY2thZ2UuUGFja2FnZS5QYXJ0RXhpc3RzKFNoYXJlZFN0cmluZ3NVcmkpKQogICAgICAgICAgICAvL3sKICAgICAgICAgICAgLy8gICAgc3RyaW5nUGFydD1fcGFja2FnZS5QYWNrYWdlLkdldFBhcnQoU2hhcmVkU3RyaW5nc1VyaSk7CiAgICAgICAgICAgIC8vfQogICAgICAgICAgICAvL2Vsc2UKICAgICAgICAgICAgLy97CiAgICAgICAgICAgIC8vICAgIHN0cmluZ1BhcnQgPSBfcGFja2FnZS5QYWNrYWdlLkNyZWF0ZVBhcnQoU2hhcmVkU3RyaW5nc1VyaSwgQCJhcHBsaWNhdGlvbi92bmQub3BlbnhtbGZvcm1hdHMtb2ZmaWNlZG9jdW1lbnQuc3ByZWFkc2hlZXRtbC5zaGFyZWRTdHJpbmdzK3htbCIsIF9wYWNrYWdlLkNvbXByZXNzaW9uKTsKICAgICAgICAgICAgICAgICAgLy9QYXJ0LkNyZWF0ZVJlbGF0aW9uc2hpcChVcmlIZWxwZXIuR2V0UmVsYXRpdmVVcmkoV29ya2Jvb2tVcmksIFNoYXJlZFN0cmluZ3NVcmkpLCBQYWNrYWdpbmcuVGFyZ2V0TW9kZS5JbnRlcm5hbCwgRXhjZWxQYWNrYWdlLnNjaGVtYVJlbGF0aW9uc2hpcHMgKyAiL3NoYXJlZFN0cmluZ3MiKTsKICAgICAgICAgICAgLy99CgoJCQkvL1N0cmVhbVdyaXRlciBzdyA9IG5ldyBTdHJlYW1Xcml0ZXIoc3RyaW5nUGFydC5HZXRTdHJlYW0oRmlsZU1vZGUuQ3JlYXRlLCBGaWxlQWNjZXNzLldyaXRlKSk7CiAgICAgICAgICAgIC8vSW5pdCBaaXAKICAgICAgICAgICAgc3RyZWFtLkNvbXByZXNzaW9uTGV2ZWwgPSAoT2ZmaWNlT3BlblhtbC5QYWNrYWdpbmcuSW9uaWMuWmxpYi5Db21wcmVzc2lvbkxldmVsKWNvbXByZXNzaW9uTGV2ZWw7CiAgICAgICAgICAgIHN0cmVhbS5QdXROZXh0RW50cnkoZmlsZU5hbWUpOwoKICAgICAgICAgICAgdmFyIGNhY2hlID0gbmV3IFN0cmluZ0J1aWxkZXIoKTsgICAgICAgICAgICAKICAgICAgICAgICAgdmFyIHN3ID0gbmV3IFN0cmVhbVdyaXRlcihzdHJlYW0pOwogICAgICAgICAgICBjYWNoZS5BcHBlbmRGb3JtYXQoIjw/eG1sIHZlcnNpb249XCIxLjBcIiBlbmNvZGluZz1cIlVURi04XCIgc3RhbmRhbG9uZT1cInllc1wiID8+PHNzdCB4bWxucz1cImh0dHA6Ly9zY2hlbWFzLm9wZW54bWxmb3JtYXRzLm9yZy9zcHJlYWRzaGVldG1sLzIwMDYvbWFpblwiIGNvdW50PVwiezB9XCIgdW5pcXVlQ291bnQ9XCJ7MH1cIj4iLCBfc2hhcmVkU3RyaW5ncy5Db3VudCk7CgkJCWZvcmVhY2ggKHN0cmluZyB0IGluIF9zaGFyZWRTdHJpbmdzLktleXMpCgkJCXsKCgkJCQlTaGFyZWRTdHJpbmdJdGVtIHNzaSA9IF9zaGFyZWRTdHJpbmdzW3RdOwoJCQkJaWYgKHNzaS5pc1JpY2hUZXh0KQoJCQkJewogICAgICAgICAgICAgICAgICAgIGNhY2hlLkFwcGVuZCgiPHNpPiIpOwogICAgICAgICAgICAgICAgICAgIENvbnZlcnRVdGlsLkV4Y2VsRW5jb2RlU3RyaW5nKGNhY2hlLCB0KTsKICAgICAgICAgICAgICAgICAgICBjYWNoZS5BcHBlbmQoIjwvc2k+Iik7CgkJCQl9CgkJCQllbHNlCgkJCQl7CiAgICAgICAgICAgICAgICAgICAgaWYgKHQuTGVuZ3RoID4gMCAmJiAodFswXSA9PSAnICcgfHwgdFt0Lkxlbmd0aCAtIDFdID09ICcgJyB8fCB0LkNvbnRhaW5zKCIgICIpIHx8IHQuQ29udGFpbnMoIlx0IikgfHwgdC5Db250YWlucygiXG4iKSB8fCB0LkNvbnRhaW5zKCJcbiIpKSkgICAvL0ZpeGVzIGlzc3VlIDE0ODQ5CgkJCQkJewogICAgICAgICAgICAgICAgICAgICAgICBjYWNoZS5BcHBlbmQoIjxzaT48dCB4bWw6c3BhY2U9XCJwcmVzZXJ2ZVwiPiIpOwoJCQkJCX0KCQkJCQllbHNlCgkJCQkJewogICAgICAgICAgICAgICAgICAgICAgICBjYWNoZS5BcHBlbmQoIjxzaT48dD4iKTsKCQkJCQl9CiAgICAgICAgICAgICAgICAgICAgQ29udmVydFV0aWwuRXhjZWxFbmNvZGVTdHJpbmcoY2FjaGUsIENvbnZlcnRVdGlsLkV4Y2VsRXNjYXBlU3RyaW5nKHQpKTsKICAgICAgICAgICAgICAgICAgICBjYWNoZS5BcHBlbmQoIjwvdD48L3NpPiIpOwoJCQkJfQogICAgICAgICAgICAgICAgaWYgKGNhY2hlLkxlbmd0aCA+IDB4NjAwMDAwKQogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIHN3LldyaXRlKGNhY2hlLlRvU3RyaW5nKCkpOwogICAgICAgICAgICAgICAgICAgIGNhY2hlID0gbmV3IFN0cmluZ0J1aWxkZXIoKTsgICAgICAgICAgICAKICAgICAgICAgICAgICAgIH0KCQkJfQogICAgICAgICAgICBjYWNoZS5BcHBlbmQoIjwvc3N0PiIpOwogICAgICAgICAgICBzdy5Xcml0ZShjYWNoZS5Ub1N0cmluZygpKTsKICAgICAgICAgICAgc3cuRmx1c2goKTsKICAgICAgICAgICAgUGFydC5DcmVhdGVSZWxhdGlvbnNoaXAoVXJpSGVscGVyLkdldFJlbGF0aXZlVXJpKFdvcmtib29rVXJpLCBTaGFyZWRTdHJpbmdzVXJpKSwgUGFja2FnaW5nLlRhcmdldE1vZGUuSW50ZXJuYWwsIEV4Y2VsUGFja2FnZS5zY2hlbWFSZWxhdGlvbnNoaXBzICsgIi9zaGFyZWRTdHJpbmdzIik7CgkJfQoJCXByaXZhdGUgdm9pZCBVcGRhdGVEZWZpbmVkTmFtZXNYbWwoKQoJCXsKCQkJdHJ5CgkJCXsKICAgICAgICAgICAgICAgIFhtbE5vZGUgdG9wID0gV29ya2Jvb2tYbWwuU2VsZWN0U2luZ2xlTm9kZSgiLy9kOmRlZmluZWROYW1lcyIsIE5hbWVTcGFjZU1hbmFnZXIpOwoJCQkJaWYgKCFFeGlzdHNOYW1lcygpKQoJCQkJewoJCQkJCWlmICh0b3AgIT0gbnVsbCkgVG9wTm9kZS5SZW1vdmVDaGlsZCh0b3ApOwoJCQkJCXJldHVybjsKCQkJCX0KCQkJCWVsc2UKCQkJCXsKCQkJCQlpZiAodG9wID09IG51bGwpCgkJCQkJewoJCQkJCQlDcmVhdGVOb2RlKCJkOmRlZmluZWROYW1lcyIpOwoJCQkJCQl0b3AgPSBXb3JrYm9va1htbC5TZWxlY3RTaW5nbGVOb2RlKCIvL2Q6ZGVmaW5lZE5hbWVzIiwgTmFtZVNwYWNlTWFuYWdlcik7CgkJCQkJfQoJCQkJCWVsc2UKCQkJCQl7CgkJCQkJCXRvcC5SZW1vdmVBbGwoKTsKCQkJCQl9CgkJCQkJZm9yZWFjaCAoRXhjZWxOYW1lZFJhbmdlIG5hbWUgaW4gX25hbWVzKQoJCQkJCXsKCgkJCQkJCVhtbEVsZW1lbnQgZWxlbSA9IFdvcmtib29rWG1sLkNyZWF0ZUVsZW1lbnQoImRlZmluZWROYW1lIiwgRXhjZWxQYWNrYWdlLnNjaGVtYU1haW4pOwoJCQkJCQl0b3AuQXBwZW5kQ2hpbGQoZWxlbSk7CgkJCQkJCWVsZW0uU2V0QXR0cmlidXRlKCJuYW1lIiwgbmFtZS5OYW1lKTsKCQkJCQkJaWYgKG5hbWUuSXNOYW1lSGlkZGVuKSBlbGVtLlNldEF0dHJpYnV0ZSgiaGlkZGVuIiwgIjEiKTsKCQkJCQkJaWYgKCFzdHJpbmcuSXNOdWxsT3JFbXB0eShuYW1lLk5hbWVDb21tZW50KSkgZWxlbS5TZXRBdHRyaWJ1dGUoImNvbW1lbnQiLCBuYW1lLk5hbWVDb21tZW50KTsKCQkJCQkJU2V0TmFtZUVsZW1lbnQobmFtZSwgZWxlbSk7CgkJCQkJfQoJCQkJfQoJCQkJZm9yZWFjaCAoRXhjZWxXb3Jrc2hlZXQgd3MgaW4gX3dvcmtzaGVldHMpCgkJCQl7CiAgICAgICAgICAgICAgICAgICAgaWYgKCEod3MgaXMgRXhjZWxDaGFydHNoZWV0KSkKICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgIGZvcmVhY2ggKEV4Y2VsTmFtZWRSYW5nZSBuYW1lIGluIHdzLk5hbWVzKQogICAgICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBYbWxFbGVtZW50IGVsZW0gPSBXb3JrYm9va1htbC5DcmVhdGVFbGVtZW50KCJkZWZpbmVkTmFtZSIsIEV4Y2VsUGFja2FnZS5zY2hlbWFNYWluKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRvcC5BcHBlbmRDaGlsZChlbGVtKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVsZW0uU2V0QXR0cmlidXRlKCJuYW1lIiwgbmFtZS5OYW1lKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVsZW0uU2V0QXR0cmlidXRlKCJsb2NhbFNoZWV0SWQiLCBuYW1lLkxvY2FsU2hlZXRJZC5Ub1N0cmluZygpKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChuYW1lLklzTmFtZUhpZGRlbikgZWxlbS5TZXRBdHRyaWJ1dGUoImhpZGRlbiIsICIxIik7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoIXN0cmluZy5Jc051bGxPckVtcHR5KG5hbWUuTmFtZUNvbW1lbnQpKSBlbGVtLlNldEF0dHJpYnV0ZSgiY29tbWVudCIsIG5hbWUuTmFtZUNvbW1lbnQpOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgU2V0TmFtZUVsZW1lbnQobmFtZSwgZWxlbSk7CiAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICB9CgkJCQl9CgkJCX0KCQkJY2F0Y2ggKEV4Y2VwdGlvbiBleCkKCQkJewoJCQkJdGhyb3cgbmV3IEV4Y2VwdGlvbigiSW50ZXJuYWwgZXJyb3IgdXBkYXRpbmcgbmFtZWQgcmFuZ2VzICIsZXgpOwoJCQl9CgkJfQoKCQlwcml2YXRlIHZvaWQgU2V0TmFtZUVsZW1lbnQoRXhjZWxOYW1lZFJhbmdlIG5hbWUsIFhtbEVsZW1lbnQgZWxlbSkKCQl7CgkJCWlmIChuYW1lLklzTmFtZSkKCQkJewoJCQkJaWYgKHN0cmluZy5Jc051bGxPckVtcHR5KG5hbWUuTmFtZUZvcm11bGEpKQoJCQkJewoJCQkJCWlmICgobmFtZS5OYW1lVmFsdWUuR2V0VHlwZSgpLklzUHJpbWl0aXZlIHx8IG5hbWUuTmFtZVZhbHVlIGlzIGRvdWJsZSB8fCBuYW1lLk5hbWVWYWx1ZSBpcyBkZWNpbWFsKSkKCQkJCQl7CgkJCQkJCWVsZW0uSW5uZXJUZXh0ID0gQ29udmVydC5Ub0RvdWJsZShuYW1lLk5hbWVWYWx1ZSwgQ3VsdHVyZUluZm8uSW52YXJpYW50Q3VsdHVyZSkuVG9TdHJpbmcoIlIxNSIsIEN1bHR1cmVJbmZvLkludmFyaWFudEN1bHR1cmUpOyAKCQkJCQl9CgkJCQkJZWxzZSBpZiAobmFtZS5OYW1lVmFsdWUgaXMgRGF0ZVRpbWUpCgkJCQkJewoJCQkJCQllbGVtLklubmVyVGV4dCA9ICgoRGF0ZVRpbWUpbmFtZS5OYW1lVmFsdWUpLlRvT0FEYXRlKCkuVG9TdHJpbmcoQ3VsdHVyZUluZm8uSW52YXJpYW50Q3VsdHVyZSk7CgkJCQkJfQoJCQkJCWVsc2UKCQkJCQl7CgkJCQkJCWVsZW0uSW5uZXJUZXh0ID0gIlwiIiArIG5hbWUuTmFtZVZhbHVlLlRvU3RyaW5nKCkgKyAiXCIiOwoJCQkJCX0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAoJCQkJfQoJCQkJZWxzZQoJCQkJewoJCQkJCWVsZW0uSW5uZXJUZXh0ID0gbmFtZS5OYW1lRm9ybXVsYTsKCQkJCX0KCQkJfQoJCQllbHNlCgkJCXsKICAgICAgICAgICAgICAgIGVsZW0uSW5uZXJUZXh0ID0gbmFtZS5GdWxsQWRkcmVzc0Fic29sdXRlOwoJCQl9CgkJfQoJCS8vLyA8c3VtbWFyeT4KCQkvLy8gSXMgdGhlaXIgYW55IG5hbWVzIGluIHRoZSB3b3JrYm9vayBvciBpbiB0aGUgc2hlZXRzLgoJCS8vLyA8L3N1bW1hcnk+CgkJLy8vIDxyZXR1cm5zPj88L3JldHVybnM+CgkJcHJpdmF0ZSBib29sIEV4aXN0c05hbWVzKCkKCQl7CgkJCWlmIChfbmFtZXMuQ291bnQgPT0gMCkKCQkJewoJCQkJZm9yZWFjaCAoRXhjZWxXb3Jrc2hlZXQgd3MgaW4gV29ya3NoZWV0cykKCQkJCXsKICAgICAgICAgICAgICAgICAgICBpZiAod3MgaXMgRXhjZWxDaGFydHNoZWV0KSBjb250aW51ZTsKICAgICAgICAgICAgICAgICAgICBpZih3cy5OYW1lcy5Db3VudD4wKQoJCQkJCXsKCQkJCQkJcmV0dXJuIHRydWU7CgkJCQkJfQoJCQkJfQoJCQl9CgkJCWVsc2UKCQkJewoJCQkJcmV0dXJuIHRydWU7CgkJCX0KCQkJcmV0dXJuIGZhbHNlOwoJCX0gICAgICAgIAoJCSNlbmRyZWdpb24KCgkJI2VuZHJlZ2lvbgoJCWludGVybmFsIGJvb2wgRXhpc3RzVGFibGVOYW1lKHN0cmluZyBOYW1lKQoJCXsKCQkJZm9yZWFjaCAodmFyIHdzIGluIFdvcmtzaGVldHMpCgkJCXsKCQkJCWlmKHdzLlRhYmxlcy5fdGFibGVOYW1lcy5Db250YWluc0tleShOYW1lKSkKCQkJCXsKCQkJCQlyZXR1cm4gdHJ1ZTsKCQkJCX0KCQkJfQoJCQlyZXR1cm4gZmFsc2U7CgkJfQoJCWludGVybmFsIGJvb2wgRXhpc3RzUGl2b3RUYWJsZU5hbWUoc3RyaW5nIE5hbWUpCgkJewoJCQlmb3JlYWNoICh2YXIgd3MgaW4gV29ya3NoZWV0cykKCQkJewoJCQkJaWYgKHdzLlBpdm90VGFibGVzLl9waXZvdFRhYmxlTmFtZXMuQ29udGFpbnNLZXkoTmFtZSkpCgkJCQl7CgkJCQkJcmV0dXJuIHRydWU7CgkJCQl9CgkJCX0KCQkJcmV0dXJuIGZhbHNlOwoJCX0KCQlpbnRlcm5hbCB2b2lkIEFkZFBpdm90VGFibGUoc3RyaW5nIGNhY2hlSUQsIFVyaSBkZWZVcmkpCgkJewoJCQlDcmVhdGVOb2RlKCJkOnBpdm90Q2FjaGVzIik7CgoJCQlYbWxFbGVtZW50IGl0ZW0gPSBXb3JrYm9va1htbC5DcmVhdGVFbGVtZW50KCJwaXZvdENhY2hlIiwgRXhjZWxQYWNrYWdlLnNjaGVtYU1haW4pOwoJCQlpdGVtLlNldEF0dHJpYnV0ZSgiY2FjaGVJZCIsIGNhY2hlSUQpOwoJCQl2YXIgcmVsID0gUGFydC5DcmVhdGVSZWxhdGlvbnNoaXAoVXJpSGVscGVyLlJlc29sdmVQYXJ0VXJpKFdvcmtib29rVXJpLCBkZWZVcmkpLCBQYWNrYWdpbmcuVGFyZ2V0TW9kZS5JbnRlcm5hbCwgRXhjZWxQYWNrYWdlLnNjaGVtYVJlbGF0aW9uc2hpcHMgKyAiL3Bpdm90Q2FjaGVEZWZpbml0aW9uIik7CgkJCWl0ZW0uU2V0QXR0cmlidXRlKCJpZCIsIEV4Y2VsUGFja2FnZS5zY2hlbWFSZWxhdGlvbnNoaXBzLCByZWwuSWQpOwoKCQkJdmFyIHBpdm90Q2FjaGVzID0gV29ya2Jvb2tYbWwuU2VsZWN0U2luZ2xlTm9kZSgiLy9kOnBpdm90Q2FjaGVzIiwgTmFtZVNwYWNlTWFuYWdlcik7CgkJCXBpdm90Q2FjaGVzLkFwcGVuZENoaWxkKGl0ZW0pOwoJCX0KCQlpbnRlcm5hbCBMaXN0PHN0cmluZz4gX2V4dGVybmFsUmVmZXJlbmNlcyA9IG5ldyBMaXN0PHN0cmluZz4oKTsKICAgICAgICAvL2ludGVybmFsIGJvb2wgX2lzQ2FsY3VsYXRlZD1mYWxzZTsKCQlpbnRlcm5hbCB2b2lkIEdldEV4dGVybmFsUmVmZXJlbmNlcygpCgkJewoJCQlYbWxOb2RlTGlzdCBubCA9IFdvcmtib29rWG1sLlNlbGVjdE5vZGVzKCIvL2Q6ZXh0ZXJuYWxSZWZlcmVuY2VzL2Q6ZXh0ZXJuYWxSZWZlcmVuY2UiLCBOYW1lU3BhY2VNYW5hZ2VyKTsKCQkJaWYgKG5sICE9IG51bGwpCgkJCXsKCQkJCWZvcmVhY2ggKFhtbEVsZW1lbnQgZWxlbSBpbiBubCkKCQkJCXsKCQkJCQlzdHJpbmcgcklEID0gZWxlbS5HZXRBdHRyaWJ1dGUoInI6aWQiKTsKCQkJCQl2YXIgcmVsID0gUGFydC5HZXRSZWxhdGlvbnNoaXAocklEKTsKCQkJCQl2YXIgcGFydCA9IF9wYWNrYWdlLlBhY2thZ2UuR2V0UGFydChVcmlIZWxwZXIuUmVzb2x2ZVBhcnRVcmkocmVsLlNvdXJjZVVyaSwgcmVsLlRhcmdldFVyaSkpOwoJCQkJCVhtbERvY3VtZW50IHhtbEV4dFJlZiA9IG5ldyBYbWxEb2N1bWVudCgpOwogICAgICAgICAgICAgICAgICAgIExvYWRYbWxTYWZlKHhtbEV4dFJlZiwgcGFydC5HZXRTdHJlYW0oKSk7IAoKCQkJCQlYbWxFbGVtZW50IGJvb2s9eG1sRXh0UmVmLlNlbGVjdFNpbmdsZU5vZGUoIi8vZDpleHRlcm5hbEJvb2siLCBOYW1lU3BhY2VNYW5hZ2VyKSBhcyBYbWxFbGVtZW50OwoJCQkJCWlmKGJvb2shPW51bGwpCgkJCQkJewoJCQkJCQlzdHJpbmcgcklkX0V4dFJlZiA9IGJvb2suR2V0QXR0cmlidXRlKCJyOmlkIik7CgkJCQkJCXZhciByZWxfZXh0UmVmID0gcGFydC5HZXRSZWxhdGlvbnNoaXAocklkX0V4dFJlZik7CgkJCQkJCWlmIChyZWxfZXh0UmVmICE9IG51bGwpCgkJCQkJCXsKCQkJCQkJCV9leHRlcm5hbFJlZmVyZW5jZXMuQWRkKHJlbF9leHRSZWYuVGFyZ2V0VXJpLk9yaWdpbmFsU3RyaW5nKTsKCQkJCQkJfQoKCQkJCQl9CgkJCQl9CgkJCX0KCQl9CgogICAgICAgIHB1YmxpYyB2b2lkIERpc3Bvc2UoKQogICAgICAgIHsKICAgICAgICAgICAgaWYgKF9zaGFyZWRTdHJpbmdzICE9IG51bGwpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIF9zaGFyZWRTdHJpbmdzLkNsZWFyKCk7CiAgICAgICAgICAgICAgICBfc2hhcmVkU3RyaW5ncyA9IG51bGw7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgaWYgKF9zaGFyZWRTdHJpbmdzTGlzdCAhPSBudWxsKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBfc2hhcmVkU3RyaW5nc0xpc3QuQ2xlYXIoKTsKICAgICAgICAgICAgICAgIF9zaGFyZWRTdHJpbmdzTGlzdCA9IG51bGw7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgX3ZiYSA9IG51bGw7CiAgICAgICAgICAgIGlmIChfd29ya3NoZWV0cyAhPSBudWxsKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBfd29ya3NoZWV0cy5EaXNwb3NlKCk7CiAgICAgICAgICAgICAgICBfd29ya3NoZWV0cyA9IG51bGw7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgX3BhY2thZ2UgPSBudWxsOwogICAgICAgICAgICBfcHJvcGVydGllcyA9IG51bGw7CiAgICAgICAgICAgIGlmIChfZm9ybXVsYVBhcnNlciAhPSBudWxsKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBfZm9ybXVsYVBhcnNlci5EaXNwb3NlKCk7CiAgICAgICAgICAgICAgICBfZm9ybXVsYVBhcnNlciA9IG51bGw7CiAgICAgICAgICAgIH0gICAKICAgICAgICB9CgogICAgICAgIGludGVybmFsIHZvaWQgUmVhZEFsbFRhYmxlcygpCiAgICAgICAgewogICAgICAgICAgICBpZiAoX25leHRUYWJsZUlEID4gMCkgcmV0dXJuOwogICAgICAgICAgICBfbmV4dFRhYmxlSUQgPSAxOwogICAgICAgICAgICBfbmV4dFBpdm90VGFibGVJRCA9IDE7CiAgICAgICAgICAgIGZvcmVhY2ggKHZhciB3cyBpbiBXb3Jrc2hlZXRzKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBpZiAoISh3cyBpcyBFeGNlbENoYXJ0c2hlZXQpKSAvL0ZpeGVzIDE1MjczLiBDaGFydHNoZWV0cyBzaG91bGQgYmUgaWdub3JlZC4KICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICBmb3JlYWNoICh2YXIgdGJsIGluIHdzLlRhYmxlcykKICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgIGlmICh0YmwuSWQgPj0gX25leHRUYWJsZUlEKQogICAgICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBfbmV4dFRhYmxlSUQgPSB0YmwuSWQgKyAxOwogICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIGZvcmVhY2ggKHZhciBwdCBpbiB3cy5QaXZvdFRhYmxlcykKICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChwdC5DYWNoZUlEID49IF9uZXh0UGl2b3RUYWJsZUlEKQogICAgICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBfbmV4dFBpdm90VGFibGVJRCA9IHB0LkNhY2hlSUQgKyAxOwogICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgfQogICAgfSAvLyBlbmQgV29ya2Jvb2sKfQo=