LyoKICogQ29weXJpZ2h0ICAyMDAwLTIwMDQgVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uCiAqCiAqICBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKICogIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KICogIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAogKgogKiAgICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAogKgogKiAgVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQogKiAgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKICogIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgogKiAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAogKiAgbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCiAqCiAqICAyMDA2LTEyLTI5OiBNb2RpZmllZCB0byB3b3JrIGZvciBhbnRscjMgYnkgSvxyZ2VuIFBmdW5kdAogKiAgMjAwNy0wMS0wNDogU29tZSBtaW5vciBjb3JyZWN0aW9uIGFmdGVyIGNoZWNraW5nIGNvZGUgd2l0aCBmaW5kQnVncyB0b29sCiAqICAyMDA3LTAyLTEwOiBBZGFwdGVkIHRoZSBncmFtbWFyIHR5cGUgcmVjb2duaXRpb24gdG8gdGhlIGNoYW5nZWQgbmFtaW5nCiAqICAgICAgICAgICAgICBjb252ZW50aW9ucyBmb3IgVHJlZSBQYXJzZXIKICogIDIwMDctMTAtMTc6IE9wdGlvbnMgInRyYWNlIiwgInRyYWNlTGV4ZXIiLCAidHJhY2VQYXJzZXIiIGFuZCAiZ2xpYiIgZW1pdAogKiAgICAgICAgICAgICAgd2FybmluZ3Mgd2hlbiBiZWluZyB1c2VkLgogKiAgICAgICAgICAgICAgQWRkZWQgcmVjb2duaXRpb24gb2YgInBhcnNlciBncmFtbWFyIFQiLgogKiAgICAgICAgICAgICAgQWRkZWQgb3B0aW9ucyAibm9jb2xsYXBzZSIsICJub3BydW5lIi4KICogICAgICAgICAgICAgIEFOVExSIG9wdGlvbiAiZGVwZW5kIiBpcyBiZWluZyB1c2VkIHRvIHJlc29sdmUgYnVpbGQgZGVwZW5kZW5jaWVzLgogKiAgMjAwNy0xMS0xNTogRW1iZWRkZWQgQ2xhc3NwYXRoIHN0YXRlbWVudCBoYWQgbm90IGJlZW4gb2JzZXJ2ZWQKICogICAgICAgICAgICAgIHdpdGggb3B0aW9uIGRlcGVuZD0idHJ1ZSIgKFJlcG9ydGVkIGJ5IE1hdHMgQmVocmUpCiAqICAyMDA4LTAzLTMxOiBTdXBwb3J0IHRoZSBvcHRpb24gY29udmVyc2lvbnRpbWVvdXQuIChKaW0gSWRsZSkKICogIDIwMDctMTItMzE6IFdpdGggb3B0aW9uICJkZXBlbmQ9dHJ1ZSIgcHJvY2VlZCBldmVuIGlmIGZpcnN0IHBhc3MgZmFpbGVkIHNvCiAqICAgICAgICAgICAgICB0aGF0IEFOVExSIGNhbiBzcGl0IG91dCBpdHMgZXJyb3JzCiAqICAyMDA4LTA4LTA5OiBJbnNwZWN0aW5nIGVudmlyb25tZW50IHZhcmlhYmxlIEFOVExSX0hPTUUgdG8gZGV0ZWN0IGFuZCBhZGQKICogICAgICAgICAgICAgIGFudGxyLSBhbmQgc3RyaW5ndGVtcGxhdGUgbGlicmFyaWVzIHRvIHRoZSBjbGFzc3BhdGgKICogIDIwMDgtMDgtMDk6IFJlbW92ZWQgcm91dGluZSBjaGVja0dlbmVyYXRlRmlsZS4gSXQgZ290IGZlZWJsZSB3aXRoIHRoZQogKiAgICAgICAgICAgICAgaW50cm9kdWN0aW9uIG9mIGNvbXBvc2VkIGdyYW1tYXJzLCBlLmcuICJpbXBvcnQgVC5nIiBhbmQgYWZ0ZXIKICogICAgICAgICAgICAgIGEgc2hvcnQgc3RydWdnbGUgaXQgc3RhcnRlZCBpdCdzIGpvdXJuZXkgdG8gL2Rldi9udWxsLgogKiAgICAgICAgICAgICAgRnJvbSBub3cgb25lIGl0IGlzIGFsd2F5cyBhbnRsciBpdHNlbGYgdmlhIHRoZSBkZXBlbmQgb3B0aW9uCiAqICAgICAgICAgICAgICB3aGljaCBkZWNpZGVzIGFib3V0IGRlcGVuZGVjaWVzCiAqICAyMDA4LTA4LTE5OiBEZXBlbmRlbmN5IGNoZWNrIGZvciBjb21wb3NlZCBncmFtbWFycyBhZGRlZC4KICogICAgICAgICAgICAgIE1pZ2h0IG5lZWQgc29tZSBmdXJ0aGVyIGltcHJvdmVtZW50cy4KICovCnBhY2thZ2Ugb3JnLmFwYWNoZS50b29scy5hbnQuYW50bHI7CgppbXBvcnQgamF2YS51dGlsLnJlZ2V4Lio7CmltcG9ydCBqYXZhLmlvLio7CmltcG9ydCBqYXZhLnV0aWwuTWFwOwppbXBvcnQgb3JnLmFwYWNoZS50b29scy5hbnQuQnVpbGRFeGNlcHRpb247CmltcG9ydCBvcmcuYXBhY2hlLnRvb2xzLmFudC5EaXJlY3RvcnlTY2FubmVyOwppbXBvcnQgb3JnLmFwYWNoZS50b29scy5hbnQuUHJvamVjdDsKaW1wb3J0IG9yZy5hcGFjaGUudG9vbHMuYW50LlRhc2s7CmltcG9ydCBvcmcuYXBhY2hlLnRvb2xzLmFudC50YXNrZGVmcy5FeGVjdXRlOwppbXBvcnQgb3JnLmFwYWNoZS50b29scy5hbnQudGFza2RlZnMuTG9nT3V0cHV0U3RyZWFtOwppbXBvcnQgb3JnLmFwYWNoZS50b29scy5hbnQudGFza2RlZnMuUHVtcFN0cmVhbUhhbmRsZXI7CmltcG9ydCBvcmcuYXBhY2hlLnRvb2xzLmFudC50YXNrZGVmcy5SZWRpcmVjdG9yOwppbXBvcnQgb3JnLmFwYWNoZS50b29scy5hbnQudHlwZXMuQ29tbWFuZGxpbmU7CmltcG9ydCBvcmcuYXBhY2hlLnRvb2xzLmFudC50eXBlcy5Db21tYW5kbGluZUphdmE7CmltcG9ydCBvcmcuYXBhY2hlLnRvb2xzLmFudC50eXBlcy5QYXRoOwppbXBvcnQgb3JnLmFwYWNoZS50b29scy5hbnQudXRpbC5KYXZhRW52VXRpbHM7CmltcG9ydCBvcmcuYXBhY2hlLnRvb2xzLmFudC51dGlsLkxvYWRlclV0aWxzOwppbXBvcnQgb3JnLmFwYWNoZS50b29scy5hbnQudXRpbC5UZWVPdXRwdXRTdHJlYW07CmltcG9ydCBvcmcuYXBhY2hlLnRvb2xzLmFudC51dGlsLkZpbGVVdGlsczsKCi8qKgogKiAgSW52b2tlcyB0aGUgQU5UTFIzIFRyYW5zbGF0b3IgZ2VuZXJhdG9yIG9uIGEgZ3JhbW1hciBmaWxlLgogKgogKi8KcHVibGljIGNsYXNzIEFOVExSMyBleHRlbmRzIFRhc2sgewoKICAgIHByaXZhdGUgQ29tbWFuZGxpbmVKYXZhIGNvbW1hbmRsaW5lID0gbmV3IENvbW1hbmRsaW5lSmF2YSgpOwogICAgLyoqIHRoZSBmaWxlIHRvIHByb2Nlc3MgKi8KICAgIHByaXZhdGUgRmlsZSB0YXJnZXQgPSBudWxsOwogICAgLyoqIHdoZXJlIHRvIG91dHB1dCB0aGUgcmVzdWx0ICovCiAgICBwcml2YXRlIEZpbGUgb3V0cHV0RGlyZWN0b3J5ID0gbnVsbDsKICAgIC8qKiBsb2NhdGlvbiBvZiB0b2tlbiBmaWxlcyAqLwogICAgcHJpdmF0ZSBGaWxlIGxpYkRpcmVjdG9yeSA9IG51bGw7CiAgICAvKiogYW4gb3B0aW9uYWwgc3VwZXIgZ3JhbW1hciBmaWxlICovCiAgICBwcml2YXRlIEZpbGUgc3VwZXJHcmFtbWFyOwogICAgLyoqIGRlcGVuZCAqLwogICAgcHJpdmF0ZSBib29sZWFuIGRlcGVuZCA9IGZhbHNlOwogICAgLyoqIGZvcmsgKi8KICAgIHByaXZhdGUgYm9vbGVhbiBmb3JrOwogICAgLyoqIG5hbWUgb2Ygb3V0cHV0IHN0eWxlIGZvciBtZXNzYWdlcyAqLwogICAgcHJpdmF0ZSBTdHJpbmcgbWVzc2FnZUZvcm1hdE5hbWU7CiAgICAvKiogb3B0aW9uYWwgZmxhZyB0byBwcmludCBvdXQgYSBkaWFnbm9zdGljIGZpbGUgKi8KICAgIHByaXZhdGUgYm9vbGVhbiBkaWFnbm9zdGljOwogICAgLyoqIG9wdGlvbmFsIGZsYWcgdG8gYWRkIG1ldGhvZHMgKi8KICAgIHByaXZhdGUgYm9vbGVhbiB0cmFjZTsKICAgIC8qKiBvcHRpb25hbCBmbGFnIHRvIGFkZCB0cmFjZSBtZXRob2RzIHRvIHRoZSBwYXJzZXIgb25seSAqLwogICAgcHJpdmF0ZSBib29sZWFuIHRyYWNlUGFyc2VyOwogICAgLyoqIG9wdGlvbmFsIGZsYWcgdG8gYWRkIHRyYWNlIG1ldGhvZHMgdG8gdGhlIGxleGVyIG9ubHkgKi8KICAgIHByaXZhdGUgYm9vbGVhbiB0cmFjZUxleGVyOwogICAgLyoqIHdvcmtpbmcgZGlyZWN0b3J5ICovCiAgICBwcml2YXRlIEZpbGUgd29ya2luZ2RpciA9IG51bGw7CiAgICAvKiogY2FwdHVyZXMgQU5UTFIncyBvdXRwdXQgKi8KICAgIHByaXZhdGUgQnl0ZUFycmF5T3V0cHV0U3RyZWFtIGJvcyA9IG5ldyBCeXRlQXJyYXlPdXRwdXRTdHJlYW0oKTsKICAgIC8qKiBUaGUgZGVidWcgYXR0cmlidXRlICovCiAgICBwcml2YXRlIGJvb2xlYW4gZGVidWc7CiAgICAvKiogVGhlIHJlcG9ydCBhdHRyaWJ1dGUgKi8KICAgIHByaXZhdGUgYm9vbGVhbiByZXBvcnQ7CiAgICAvKiogVGhlIHByaW50IGF0dHJpYnV0ZSAqLwogICAgcHJpdmF0ZSBib29sZWFuIHByaW50OwogICAgLyoqIFRoZSBwcm9maWxlIGF0dHJpYnV0ZSAqLwogICAgcHJpdmF0ZSBib29sZWFuIHByb2ZpbGU7CiAgICAvKiogVGhlIG5mYSBhdHRyaWJ1dGUgKi8KICAgIHByaXZhdGUgYm9vbGVhbiBuZmE7CiAgICAvKiogVGhlIGRmYSBhdHRyaWJ1dGUgKi8KICAgIHByaXZhdGUgYm9vbGVhbiBkZmE7CiAgICAvKiogbXVsdGkgdGhyZWFkZWQgYW5hbHlzaXMgKi8KICAgIHByaXZhdGUgYm9vbGVhbiBtdWx0aVRocmVhZGVkOwogICAgLyoqIGNvbGxhcHNlIGluY2lkZW50IGVkZ2VzIGludG8gREZBIHN0YXRlcyAqLwogICAgcHJpdmF0ZSBib29sZWFuIG5vY29sbGFwc2U7CiAgICAvKiogdGVzdCBsb29rYWhlYWQgYWdhaW5zdCBFQk5GIGJsb2NrIGV4aXQgYnJhbmNoZXMgKi8KICAgIHByaXZhdGUgYm9vbGVhbiBub3BydW5lOwogICAgLyoqIHB1dCB0YWdzIGF0IHN0YXJ0L3N0b3Agb2YgYWxsIHRlbXBsYXRlcyBpbiBvdXRwdXQgKi8KICAgIHByaXZhdGUgYm9vbGVhbiBkYmdTVDsKICAgIC8qKiBwcmludCBBU1QgKi8KICAgIHByaXZhdGUgYm9vbGVhbiBncmFtbWFyVHJlZTsKICAgIC8qKiBJbnN0YW5jZSBvZiBhIHV0aWxpdHkgY2xhc3MgdG8gdXNlIGZvciBmaWxlIG9wZXJhdGlvbnMuICovCiAgICBwcml2YXRlIEZpbGVVdGlscyBmaWxlVXRpbHM7CiAgICAvKioKICAgICAqIFdoZXRoZXIgdG8gb3ZlcnJpZGUgdGhlIGRlZmF1bHQgY29udmVyc2lvbiB0aW1lb3V0IHdpdGggLVhjb252ZXJzaW9udGltZW91dCBubm5uCiAgICAgKi8KICAgIHByaXZhdGUgU3RyaW5nIGNvbnZlcnNpb250aW1lb3V0OwoKICAgIHB1YmxpYyBBTlRMUjMoKSB7CiAgICAgICAgY29tbWFuZGxpbmUuc2V0Vm0oSmF2YUVudlV0aWxzLmdldEpyZUV4ZWN1dGFibGUoImphdmEiKSk7CiAgICAgICAgY29tbWFuZGxpbmUuc2V0Q2xhc3NuYW1lKCJvcmcuYW50bHIuVG9vbCIpOwogICAgICAgIGZpbGVVdGlscyA9IEZpbGVVdGlscy5nZXRGaWxlVXRpbHMoKTsKICAgIH0KCiAgICAvKioKICAgICAqIFRoZSBncmFtbWFyIGZpbGUgdG8gcHJvY2Vzcy4KICAgICAqLwogICAgcHVibGljIHZvaWQgc2V0VGFyZ2V0KEZpbGUgdGFyZ2V0RmlsZSkgewogICAgICAgIGxvZygiU2V0dGluZyB0YXJnZXQgdG86ICIgKyB0YXJnZXRGaWxlLnRvU3RyaW5nKCksIFByb2plY3QuTVNHX1ZFUkJPU0UpOwogICAgICAgIHRoaXMudGFyZ2V0ID0gdGFyZ2V0RmlsZTsKICAgIH0KCiAgICAvKioKICAgICAqIFRoZSBkaXJlY3RvcnkgdG8gd3JpdGUgdGhlIGdlbmVyYXRlZCBmaWxlcyB0by4KICAgICAqLwogICAgcHVibGljIHZvaWQgc2V0T3V0cHV0ZGlyZWN0b3J5KEZpbGUgb3V0cHV0RGlyZWN0b3J5RmlsZSkgewogICAgICAgIGxvZygiU2V0dGluZyBvdXRwdXQgZGlyZWN0b3J5IHRvOiAiICsgb3V0cHV0RGlyZWN0b3J5RmlsZS50b1N0cmluZygpLCBQcm9qZWN0Lk1TR19WRVJCT1NFKTsKICAgICAgICB0aGlzLm91dHB1dERpcmVjdG9yeSA9IG91dHB1dERpcmVjdG9yeUZpbGU7CiAgICB9CgogICAgLyoqCiAgICAgKiBUaGUgZGlyZWN0b3J5IHRvIHdyaXRlIHRoZSBnZW5lcmF0ZWQgZmlsZXMgdG8uCiAgICAgKi8KICAgIHB1YmxpYyBGaWxlIGdldE91dHB1dGRpcmVjdG9yeSgpIHsKICAgICAgICByZXR1cm4gb3V0cHV0RGlyZWN0b3J5OwogICAgfQoKICAgIC8qKgogICAgICogVGhlIHRva2VuIGZpbGVzIG91dHB1dCBkaXJlY3RvcnkuCiAgICAgKi8KICAgIHB1YmxpYyB2b2lkIHNldExpYmRpcmVjdG9yeShGaWxlIGxpYkRpcmVjdG9yeUZpbGUpIHsKICAgICAgICBsb2coIlNldHRpbmcgbGliIGRpcmVjdG9yeSB0bzogIiArIGxpYkRpcmVjdG9yeUZpbGUudG9TdHJpbmcoKSwgUHJvamVjdC5NU0dfVkVSQk9TRSk7CiAgICAgICAgdGhpcy5saWJEaXJlY3RvcnkgPSBsaWJEaXJlY3RvcnlGaWxlOwogICAgfQoKICAgIC8qKgogICAgICogVGhlIG91dHB1dCBzdHlsZSBmb3IgbWVzc2FnZXMuCiAgICAgKi8KICAgIHB1YmxpYyB2b2lkIHNldE1lc3NhZ2Vmb3JtYXQoU3RyaW5nIG5hbWUpIHsKICAgICAgICBsb2coIlNldHRpbmcgbWVzc2FnZS1mb3JtYXQgdG86ICIgKyBuYW1lLCBQcm9qZWN0Lk1TR19WRVJCT1NFKTsKICAgICAgICB0aGlzLm1lc3NhZ2VGb3JtYXROYW1lID0gbmFtZTsKICAgIH0KCiAgICAvKioKICAgICAqIFNldHMgYW4gb3B0aW9uYWwgc3VwZXIgZ3JhbW1hciBmaWxlCiAgICAgKiBAZGVwcmVjYXRlZAogICAgICovCiAgICBwdWJsaWMgdm9pZCBzZXRHbGliKEZpbGUgc3VwZXJHcmFtbWFyRmlsZSkgewogICAgICAgIHRoaXMuc3VwZXJHcmFtbWFyID0gc3VwZXJHcmFtbWFyRmlsZTsKICAgIH0KCiAgICAvKioKICAgICAqIFNldHMgYSBmbGFnIHRvIGVuYWJsZSBQYXJzZVZpZXcgZGVidWdnaW5nCiAgICAgKi8KICAgIHB1YmxpYyB2b2lkIHNldERlYnVnKGJvb2xlYW4gZW5hYmxlKSB7CiAgICAgICAgdGhpcy5kZWJ1ZyA9IGVuYWJsZTsKICAgIH0KCiAgICAvKioKICAgICAqIFNldHMgYSBmbGFnIHRvIGVuYWJsZSByZXBvcnQgc3RhdGlzdGljcwogICAgICovCiAgICBwdWJsaWMgdm9pZCBzZXRSZXBvcnQoYm9vbGVhbiBlbmFibGUpIHsKICAgICAgICB0aGlzLnJlcG9ydCA9IGVuYWJsZTsKICAgIH0KCiAgICAvKioKICAgICAqIFNldHMgYSBmbGFnIHRvIHByaW50IG91dCB0aGUgZ3JhbW1hciB3aXRob3V0IGFjdGlvbnMKICAgICAqLwogICAgcHVibGljIHZvaWQgc2V0UHJpbnQoYm9vbGVhbiBlbmFibGUpIHsKICAgICAgICB0aGlzLnByaW50ID0gZW5hYmxlOwogICAgfQoKICAgIC8qKgogICAgICogU2V0cyBhIGZsYWcgdG8gZW5hYmxlIHByb2ZpbGluZwogICAgICovCiAgICBwdWJsaWMgdm9pZCBzZXRQcm9maWxlKGJvb2xlYW4gZW5hYmxlKSB7CiAgICAgICAgdGhpcy5wcm9maWxlID0gZW5hYmxlOwogICAgfQoKICAgIC8qKgogICAgICogU2V0cyBhIGZsYWcgdG8gZW5hYmxlIG5mYSBnZW5lcmF0aW9uCiAgICAgKi8KICAgIHB1YmxpYyB2b2lkIHNldE5mYShib29sZWFuIGVuYWJsZSkgewogICAgICAgIHRoaXMubmZhID0gZW5hYmxlOwogICAgfQoKICAgIC8qKgogICAgICogU2V0cyBhIGZsYWcgdG8gZW5hYmxlIG5mYSBnZW5lcmF0aW9uCiAgICAgKi8KICAgIHB1YmxpYyB2b2lkIHNldERmYShib29sZWFuIGVuYWJsZSkgewogICAgICAgIHRoaXMuZGZhID0gZW5hYmxlOwogICAgfQoKICAgIC8qKgogICAgICogUnVuIHRoZSBhbmFseXNpcyBtdWx0aXRocmVhZGVkCiAgICAgKiBAcGFyYW0gZW5hYmxlCiAgICAgKi8KICAgIHB1YmxpYyB2b2lkIHNldE11bHRpdGhyZWFkZWQoYm9vbGVhbiBlbmFibGUpIHsKICAgICAgICBtdWx0aVRocmVhZGVkID0gZW5hYmxlOwogICAgfQoKICAgIC8qKgogICAgICogY29sbGFwc2UgaW5jaWRlbnQgZWRnZXMgaW50byBERkEgc3RhdGVzCiAgICAgKiBAcGFyYW0gZW5hYmxlCiAgICAgKi8KICAgIHB1YmxpYyB2b2lkIHNldE5vY29sbGFwc2UoYm9vbGVhbiBlbmFibGUpIHsKICAgICAgICBub2NvbGxhcHNlID0gZW5hYmxlOwogICAgfQoKICAgIC8qKgogICAgICogdGVzdCBsb29rYWhlYWQgYWdhaW5zdCBFQk5GIGJsb2NrIGV4aXQgYnJhbmNoZXMKICAgICAqIEBwYXJhbSBlbmFibGUKICAgICAqLwogICAgcHVibGljIHZvaWQgc2V0Tm9wcnVuZShib29sZWFuIGVuYWJsZSkgewogICAgICAgIG5vcHJ1bmUgPSBlbmFibGU7CiAgICB9CgogICAgLyoqCiAgICAgKiB0ZXN0IGxvb2thaGVhZCBhZ2FpbnN0IEVCTkYgYmxvY2sgZXhpdCBicmFuY2hlcwogICAgICogQHBhcmFtIGVuYWJsZQogICAgICovCiAgICBwdWJsaWMgdm9pZCBzZXREYmdTVChib29sZWFuIGVuYWJsZSkgewogICAgICAgIGRiZ1NUID0gZW5hYmxlOwogICAgfQoKICAgIC8qKgogICAgICogb3ZlcnJpZGUgdGhlIGRlZmF1bHQgY29udmVyc2lvbiB0aW1lb3V0IHdpdGggLVhjb252ZXJzaW9udGltZW91dCBubm5uCiAgICAgKiBAcGFyYW0gY29udmVyc2lvbnRpbWVvdXRTdHJpbmcKICAgICAqLwogICAgcHVibGljIHZvaWQgc2V0Q29udmVyc2lvbnRpbWVvdXQoU3RyaW5nIGNvbnZlcnNpb250aW1lb3V0U3RyaW5nKSB7CiAgICAgICAgbG9nKCJTZXR0aW5nIGNvbnZlcnNpb250aW1lb3V0IHRvOiAiICsgY29udmVyc2lvbnRpbWVvdXRTdHJpbmcsIFByb2plY3QuTVNHX1ZFUkJPU0UpOwogICAgICAgIHRyeSB7CiAgICAgICAgICAgIGludCB0aW1lb3V0ID0gSW50ZWdlci52YWx1ZU9mKGNvbnZlcnNpb250aW1lb3V0U3RyaW5nKTsKICAgICAgICAgICAgdGhpcy5jb252ZXJzaW9udGltZW91dCA9IGNvbnZlcnNpb250aW1lb3V0U3RyaW5nOwogICAgICAgIH0gY2F0Y2ggKE51bWJlckZvcm1hdEV4Y2VwdGlvbiBlKSB7CiAgICAgICAgICAgIGxvZygiT3B0aW9uIENvbnZlcnNpb25UaW1lT3V0IGlnbm9yZWQgZHVlIHRvIGlsbGVnYWwgdmFsdWU6ICciICsgY29udmVyc2lvbnRpbWVvdXRTdHJpbmcgKyAiJyIsIFByb2plY3QuTVNHX0VSUik7CiAgICAgICAgfQogICAgfQoKICAgIC8qKgogICAgICogU2V0IGEgZmxhZyB0byBlbmFibGUgcHJpbnRpbmcgb2YgdGhlIGdyYW1tYXIgdHJlZQogICAgICovCiAgICBwdWJsaWMgdm9pZCBzZXRHcmFtbWFydHJlZShib29sZWFuIGVuYWJsZSkgewogICAgICAgIGdyYW1tYXJUcmVlID0gZW5hYmxlOwogICAgfQoKICAgIC8qKgogICAgICogU2V0IGEgZmxhZyB0byBlbmFibGUgZGVwZW5kZW5jeSBjaGVja2luZyBieSBBTlRMUiBpdHNlbGYKICAgICAqIFRoZSBkZXBlbmQgb3B0aW9uIGlzIGFsd2F5cyB1c2VkIGltcGxpY2l0ZWx5IGluc2lkZSB0aGUgYW50bHIzIHRhc2sKICAgICAqIEBkZXByZWNhdGVkCiAgICAgKi8KICAgIHB1YmxpYyB2b2lkIHNldERlcGVuZChib29sZWFuIHMpIHsKICAgICAgICB0aGlzLmRlcGVuZCA9IHM7CiAgICB9CgogICAgLyoqCiAgICAgKiBTZXRzIGEgZmxhZyB0byBlbWl0IGRpYWdub3N0aWMgdGV4dAogICAgICovCiAgICBwdWJsaWMgdm9pZCBzZXREaWFnbm9zdGljKGJvb2xlYW4gZW5hYmxlKSB7CiAgICAgICAgZGlhZ25vc3RpYyA9IGVuYWJsZTsKICAgIH0KCiAgICAvKioKICAgICAqIElmIHRydWUsIGVuYWJsZXMgYWxsIHRyYWNpbmcuCiAgICAgKiBAZGVwcmVjYXRlZAogICAgICovCiAgICBwdWJsaWMgdm9pZCBzZXRUcmFjZShib29sZWFuIGVuYWJsZSkgewogICAgICAgIHRyYWNlID0gZW5hYmxlOwogICAgfQoKICAgIC8qKgogICAgICogSWYgdHJ1ZSwgZW5hYmxlcyBwYXJzZXIgdHJhY2luZy4KICAgICAqIEBkZXByZWNhdGVkCiAgICAgKi8KICAgIHB1YmxpYyB2b2lkIHNldFRyYWNlUGFyc2VyKGJvb2xlYW4gZW5hYmxlKSB7CiAgICAgICAgdHJhY2VQYXJzZXIgPSBlbmFibGU7CiAgICB9CgogICAgLyoqCiAgICAgKiBJZiB0cnVlLCBlbmFibGVzIGxleGVyIHRyYWNpbmcuCiAgICAgKiBAZGVwcmVjYXRlZAogICAgICovCiAgICBwdWJsaWMgdm9pZCBzZXRUcmFjZUxleGVyKGJvb2xlYW4gZW5hYmxlKSB7CiAgICAgICAgdHJhY2VMZXhlciA9IGVuYWJsZTsKICAgIH0KCiAgICAvLyB3ZSBhcmUgZm9yY2VkIHRvIGZvcmsgQU5UTFIgc2luY2UgdGhlcmUgaXMgYSBjYWxsCiAgICAvLyB0byBTeXN0ZW0uZXhpdCgpIGFuZCB0aGVyZSBpcyBub3RoaW5nIHdlIGNhbiBkbwogICAgLy8gcmlnaHQgbm93IHRvIGF2b2lkIHRoaXMuIDotKCAoU0JhKQogICAgLy8gSSdtIG5vdCByZW1vdmluZyB0aGlzIG1ldGhvZCB0byBrZWVwIGJhY2t3YXJkIGNvbXBhdGliaWxpdHkKICAgIC8qKgogICAgICogQGFudC5hdHRyaWJ1dGUgaWdub3JlPSJ0cnVlIgogICAgICovCiAgICBwdWJsaWMgdm9pZCBzZXRGb3JrKGJvb2xlYW4gcykgewogICAgICAgIHRoaXMuZm9yayA9IHM7CiAgICB9CgogICAgLyoqCiAgICAgKiBUaGUgd29ya2luZyBkaXJlY3Rvcnkgb2YgdGhlIHByb2Nlc3MKICAgICAqLwogICAgcHVibGljIHZvaWQgc2V0RGlyKEZpbGUgZCkgewogICAgICAgIHRoaXMud29ya2luZ2RpciA9IGQ7CiAgICB9CgogICAgLyoqCiAgICAgKiBBZGRzIGEgY2xhc3NwYXRoIHRvIGJlIHNldAogICAgICogYmVjYXVzZSBhIGRpcmVjdG9yeSBtaWdodCBiZSBnaXZlbiBmb3IgQW50bHIgZGVidWcuCiAgICAgKi8KICAgIHB1YmxpYyBQYXRoIGNyZWF0ZUNsYXNzcGF0aCgpIHsKICAgICAgICByZXR1cm4gY29tbWFuZGxpbmUuY3JlYXRlQ2xhc3NwYXRoKGdldFByb2plY3QoKSkuY3JlYXRlUGF0aCgpOwogICAgfQoKICAgIC8qKgogICAgICogQWRkcyBhIG5ldyBKVk0gYXJndW1lbnQuCiAgICAgKiBAcmV0dXJuICBjcmVhdGUgYSBuZXcgSlZNIGFyZ3VtZW50IHNvIHRoYXQgYW55IGFyZ3VtZW50IGNhbiBiZSBwYXNzZWQgdG8gdGhlIEpWTS4KICAgICAqIEBzZWUgI3NldEZvcmsoYm9vbGVhbikKICAgICAqLwogICAgcHVibGljIENvbW1hbmRsaW5lLkFyZ3VtZW50IGNyZWF0ZUp2bWFyZygpIHsKICAgICAgICByZXR1cm4gY29tbWFuZGxpbmUuY3JlYXRlVm1Bcmd1bWVudCgpOwogICAgfQoKICAgIC8qKgogICAgICogQWRkcyB0aGUgamFycyBvciBkaXJlY3RvcmllcyBjb250YWluaW5nIEFudGxyIGFuZCBhc3NvY2lhdGVzLgogICAgICogVGhpcyBzaG91bGQgbWFrZSB0aGUgZm9ya2VkIEpWTSB3b3JrIHdpdGhvdXQgaGF2aW5nIHRvCiAgICAgKiBzcGVjaWZ5IGl0IGRpcmVjdGx5LgogICAgICovCiAgICBAT3ZlcnJpZGUKICAgIHB1YmxpYyB2b2lkIGluaXQoKSB0aHJvd3MgQnVpbGRFeGNlcHRpb24gewogICAgICAgIC8qIElucXVpcmUgZW52aXJvbm1lbnQgdmFyaWFibGVzICovCiAgICAgICAgTWFwPFN0cmluZywgU3RyaW5nPiB2YXJpYWJsZXMgPSBTeXN0ZW0uZ2V0ZW52KCk7CiAgICAgICAgLyogR2V0IHZhbHVlIGZvciBrZXkgIkFOVExSX0hPTUUiIHdoaWNoIHNob3VsZCBob3BlZnVsbHkgcG9pbnQgdG8KICAgICAgICAgKiB0aGUgZGlyZWN0b3J5IHdoZXJlIHRoZSBjdXJyZW50IHZlcnNpb24gb2YgYW50bHIzIGlzIGluc3RhbGxlZCAqLwogICAgICAgIFN0cmluZyBhbnRsckhvbWUgPSB2YXJpYWJsZXMuZ2V0KCJBTlRMUl9IT01FIik7CiAgICAgICAgaWYgKGFudGxySG9tZSAhPSBudWxsKSB7CiAgICAgICAgICAgIC8qIEVudmlyb25tZW50IHZhcmlhYmxlIEFOVExSX0hPTUUgaGFzIGJlZW4gZGVmaW5lZC4KICAgICAgICAgICAgICogTm93IGFkZCBhbGwgYW50bHIgYW5kIHN0cmluZ3RlbXBsYXRlIGxpYnJhcmllcyB0byB0aGUKICAgICAgICAgICAgICogY2xhc3NwYXRoICovCiAgICAgICAgICAgIGFkZEFudGxySmFyc1RvQ2xhc3NwYXRoKGFudGxySG9tZSArICIvbGliIik7CiAgICAgICAgfQogICAgICAgIGFkZENsYXNzcGF0aEVudHJ5KCIvYW50bHIvQU5UTFJHcmFtbWFyUGFyc2VCZWhhdmlvci5jbGFzcyIsICJBbnRMUjIiKTsKICAgICAgICBhZGRDbGFzc3BhdGhFbnRyeSgiL29yZy9hbnRsci90b29sL0FOVExSUGFyc2VyLmNsYXNzIiwgIkFudExSMyIpOwogICAgICAgIGFkZENsYXNzcGF0aEVudHJ5KCIvb3JnL2FudGxyL3N0cmluZ3RlbXBsYXRlL1N0cmluZ1RlbXBsYXRlLmNsYXNzIiwgIlN0cmluZ3RlbXBsYXRlIik7CgoKICAgIH0KCiAgICAvKioKICAgICAqIFNlYXJjaCBmb3IgdGhlIGdpdmVuIHJlc291cmNlIGFuZCBhZGQgdGhlIGRpcmVjdG9yeSBvciBhcmNoaXZlCiAgICAgKiB0aGF0IGNvbnRhaW5zIGl0IHRvIHRoZSBjbGFzc3BhdGguCiAgICAgKgogICAgICogPHA+RG9lc24ndCB3b3JrIGZvciBhcmNoaXZlcyBpbiBKREsgMS4xIGFzIHRoZSBVUkwgcmV0dXJuZWQgYnkKICAgICAqIGdldFJlc291cmNlIGRvZXNuJ3QgY29udGFpbiB0aGUgbmFtZSBvZiB0aGUgYXJjaGl2ZS48L3A+CiAgICAgKi8KICAgIHByb3RlY3RlZCB2b2lkIGFkZENsYXNzcGF0aEVudHJ5KFN0cmluZyByZXNvdXJjZSwgU3RyaW5nIG1zZykgewogICAgICAgIC8qCiAgICAgICAgICogcHJlIEFudCAxLjYgdGhpcyBtZXRob2QgdXNlZCB0byBjYWxsIGdldENsYXNzKCkuZ2V0UmVzb3VyY2UKICAgICAgICAgKiB3aGlsZSBBbnQgMS42IHdpbGwgY2FsbCBDbGFzc0xvYWRlci5nZXRSZXNvdXJjZSgpLgogICAgICAgICAqCiAgICAgICAgICogVGhlIGRpZmZlcmVuY2UgaXMgdGhhdCBDbGFzcy5nZXRSZXNvdXJjZSBleHBlY3RzIGEgbGVhZGluZwogICAgICAgICAqIHNsYXNoIGZvciAiYWJzb2x1dGUiIHJlc291cmNlcyBhbmQgd2lsbCBzdHJpcCBpdCBiZWZvcmUKICAgICAgICAgKiBkZWxlZ2F0aW5nIHRvIENsYXNzTG9hZGVyLmdldFJlc291cmNlIC0gc28gd2Ugbm93IGhhdmUgdG8KICAgICAgICAgKiBlbXVsYXRlIENsYXNzJ3MgYmVoYXZpb3IuCiAgICAgICAgICovCiAgICAgICAgaWYgKHJlc291cmNlLnN0YXJ0c1dpdGgoIi8iKSkgewogICAgICAgICAgICByZXNvdXJjZSA9IHJlc291cmNlLnN1YnN0cmluZygxKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgICByZXNvdXJjZSA9ICJvcmcvYXBhY2hlL3Rvb2xzL2FudC90YXNrZGVmcy9vcHRpb25hbC8iICsgcmVzb3VyY2U7CiAgICAgICAgfQoKICAgICAgICBGaWxlIGYgPSBMb2FkZXJVdGlscy5nZXRSZXNvdXJjZVNvdXJjZShnZXRDbGFzcygpLmdldENsYXNzTG9hZGVyKCksIHJlc291cmNlKTsKICAgICAgICBpZiAoZiAhPSBudWxsKSB7CiAgICAgICAgICAgIGxvZygiRm91bmQgdmlhIGNsYXNzcGF0aDogIiArIGYuZ2V0QWJzb2x1dGVQYXRoKCksIFByb2plY3QuTVNHX1ZFUkJPU0UpOwogICAgICAgICAgICBjcmVhdGVDbGFzc3BhdGgoKS5zZXRMb2NhdGlvbihmKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgICBsb2coIkNvdWxkblwndCBmaW5kIHJlc291cmNlICIgKyByZXNvdXJjZSArICIgZm9yIGxpYnJhcnkgIiArIG1zZyArICIgaW4gZXh0ZXJuYWwgY2xhc3NwYXRoIiwgUHJvamVjdC5NU0dfVkVSQk9TRSk7CiAgICAgICAgfQogICAgfQoKICAgIC8qKgogICAgICogSWYgdGhlIGVudmlyb25tZW50IHZhcmlhYmxlIEFOVExSX0hPTUUgaXMgZGVmaW5lZCBhbmQgcG9pbnRzCiAgICAgKiB0byB0aGUgaW5zdGFsbGF0aW9uIGRpcmVjdG9yeSBvZiBhbnRscjMgdGhlbiBsb29rIGZvciBhbGwgYW50bHItKi5qYXIgYW5kCiAgICAgKiBzdHJpbmd0ZW1wbGF0ZS0qLmphciBmaWxlcyBpbiB0aGUgbGliIGRpcmVjdG9yeSBhbmQgYWRkIHRoZW0KICAgICAqIHRvIHRoZSBjbGFzc3BhdGguCiAgICAgKiBUaGlzIGZlYXR1cmUgc2hvdWxkIG1ha2Ugd29ya2luZyB3aXRoIGVjbGlwc2Ugb3IgbmV0YmVhbnMgcHJvamVjdHMgYQogICAgICogbGl0dGxlIGJpdCBlYXNpZXIuIEFzIHdpbGRjYXJkcyBhcmUgYmVpbmcgdXNlZCBmb3IgdGhlIHZlcnNpb24gcGFydAogICAgICogb2YgdGhlIGphci1hcmNoaXZlcyBpdCBtYWtlcyB0aGUgdGFzayBpbmRlcGVuZGVudCBvZgogICAgICogbmV3IHJlbGVhc2VzLiBKdXN0IGxldCBBTlRMUl9IT01FIHBvaW50IHRvIHRoZSBuZXcgaW5zdGFsbGF0aW9uCiAgICAgKiBkaXJlY3RvcnkuCiAgICAgKi8KICAgIHByaXZhdGUgdm9pZCBhZGRBbnRsckphcnNUb0NsYXNzcGF0aChTdHJpbmcgYW50bHJMaWJEaXIpIHsKICAgICAgICBTdHJpbmdbXSBpbmNsdWRlcyA9IHsiYW50bHItKi5qYXIiLCAic3RyaW5ndGVtcGxhdGUtKi5qYXIifTsKCiAgICAgICAgRGlyZWN0b3J5U2Nhbm5lciBkcyA9IG5ldyBEaXJlY3RvcnlTY2FubmVyKCk7CiAgICAgICAgZHMuc2V0SW5jbHVkZXMoaW5jbHVkZXMpOwogICAgICAgIGRzLnNldEJhc2VkaXIobmV3IEZpbGUoYW50bHJMaWJEaXIpKTsKICAgICAgICBkcy5zZXRDYXNlU2Vuc2l0aXZlKHRydWUpOwogICAgICAgIGRzLnNjYW4oKTsKCiAgICAgICAgU3RyaW5nIHNlcGFyYXRvciA9IFN5c3RlbS5nZXRQcm9wZXJ0eSgiZmlsZS5zZXBhcmF0b3IiKTsKICAgICAgICBTdHJpbmdbXSBmaWxlcyA9IGRzLmdldEluY2x1ZGVkRmlsZXMoKTsKICAgICAgICBmb3IgKFN0cmluZyBmaWxlIDogZmlsZXMpIHsKICAgICAgICAgICAgRmlsZSBmID0gbmV3IEZpbGUoYW50bHJMaWJEaXIgKyBzZXBhcmF0b3IgKyBmaWxlKTsKICAgICAgICAgICAgbG9nKCJGb3VuZCB2aWEgQU5UTFJfSE9NRTogIiArIGYuZ2V0QWJzb2x1dGVQYXRoKCksIFByb2plY3QuTVNHX1ZFUkJPU0UpOwogICAgICAgICAgICBjcmVhdGVDbGFzc3BhdGgoKS5zZXRMb2NhdGlvbihmKTsKICAgICAgICB9CiAgICB9CgogICAgQE92ZXJyaWRlCiAgICBwdWJsaWMgdm9pZCBleGVjdXRlKCkgdGhyb3dzIEJ1aWxkRXhjZXB0aW9uIHsKCiAgICAgICAgdmFsaWRhdGVBdHRyaWJ1dGVzKCk7CgogICAgICAgIC8vIFVzZSBBTlRMUiBpdHNlbGYgdG8gcmVzb2x2ZSBkZXBlbmRlbmNpZXMgYW5kIGRlY2lkZSB3aGV0aGVyCiAgICAgICAgLy8gdG8gaW52b2tlIEFOVExSIGZvciBjb21waWxhdGlvbgogICAgICAgIGlmIChkZXBlbmRlbmN5Q2hlY2soKSkgewogICAgICAgICAgICBwb3B1bGF0ZUF0dHJpYnV0ZXMoKTsKICAgICAgICAgICAgY29tbWFuZGxpbmUuY3JlYXRlQXJndW1lbnQoKS5zZXRWYWx1ZSh0YXJnZXQudG9TdHJpbmcoKSk7CgogICAgICAgICAgICBsb2coY29tbWFuZGxpbmUuZGVzY3JpYmVDb21tYW5kKCksIFByb2plY3QuTVNHX1ZFUkJPU0UpOwogICAgICAgICAgICBpbnQgZXJyID0gMDsKICAgICAgICAgICAgdHJ5IHsKICAgICAgICAgICAgICAgIGVyciA9IHJ1bihjb21tYW5kbGluZS5nZXRDb21tYW5kbGluZSgpLCBuZXcgTG9nT3V0cHV0U3RyZWFtKHRoaXMsIFByb2plY3QuTVNHX0lORk8pLCBuZXcgTG9nT3V0cHV0U3RyZWFtKHRoaXMsIFByb2plY3QuTVNHX1dBUk4pKTsKICAgICAgICAgICAgfSBjYXRjaCAoSU9FeGNlcHRpb24gZSkgewogICAgICAgICAgICAgICAgdGhyb3cgbmV3IEJ1aWxkRXhjZXB0aW9uKGUsIGdldExvY2F0aW9uKCkpOwogICAgICAgICAgICB9IGZpbmFsbHkgewogICAgICAgICAgICAgICAgdHJ5IHsKICAgICAgICAgICAgICAgICAgICBib3MuY2xvc2UoKTsKICAgICAgICAgICAgICAgIH0gY2F0Y2ggKElPRXhjZXB0aW9uIGUpIHsKICAgICAgICAgICAgICAgICAgICAvLyBpZ25vcmUKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQoKICAgICAgICAgICAgaWYgKGVyciAhPSAwKSB7CiAgICAgICAgICAgICAgICB0aHJvdyBuZXcgQnVpbGRFeGNlcHRpb24oIkFOVExSIHJldHVybmVkOiAiICsgZXJyLCBnZXRMb2NhdGlvbigpKTsKICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgIFBhdHRlcm4gcCA9IFBhdHRlcm4uY29tcGlsZSgiZXJyb3JcXChbMC05XStcXCk6Iik7CiAgICAgICAgICAgICAgICBNYXRjaGVyIG0gPSBwLm1hdGNoZXIoYm9zLnRvU3RyaW5nKCkpOwogICAgICAgICAgICAgICAgaWYgKG0uZmluZCgpKSB7CiAgICAgICAgICAgICAgICAgICAgdGhyb3cgbmV3IEJ1aWxkRXhjZXB0aW9uKCJBTlRMUiBzaWduYWxlZCBhbiBlcnJvci4iLCBnZXRMb2NhdGlvbigpKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIHRyeSB7CiAgICAgICAgICAgICAgICBsb2coIkFsbCBkZXBlbmRlbmNpZXMgb2YgZ3JhbW1hciBmaWxlIFwnIiArIHRhcmdldC5nZXRDYW5vbmljYWxQYXRoKCkgKyAiXCcgYXJlIHVwIHRvIGRhdGUuIiwgUHJvamVjdC5NU0dfVkVSQk9TRSk7CiAgICAgICAgICAgIH0gY2F0Y2ggKElPRXhjZXB0aW9uIGV4KSB7CiAgICAgICAgICAgICAgICBsb2coIkFsbCBkZXBlbmRlbmNpZXMgb2YgZ3JhbW1hciBmaWxlIFwnIiArIHRhcmdldC50b1N0cmluZygpICsgIlwnIGFyZSB1cCB0byBkYXRlLiIsIFByb2plY3QuTVNHX1ZFUkJPU0UpOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgfQoKICAgIC8qKgogICAgICogQSByZWZhY3RvcmVkIG1ldGhvZCBmb3IgcG9wdWxhdGluZyBhbGwgdGhlIGNvbW1hbmQgbGluZSBhcmd1bWVudHMgYmFzZWQKICAgICAqIG9uIHRoZSB1c2VyLXNwZWNpZmllZCBhdHRyaWJ1dGVzLgogICAgICovCiAgICBwcml2YXRlIHZvaWQgcG9wdWxhdGVBdHRyaWJ1dGVzKCkgewoKICAgICAgICBjb21tYW5kbGluZS5jcmVhdGVBcmd1bWVudCgpLnNldFZhbHVlKCItbyIpOwogICAgICAgIGNvbW1hbmRsaW5lLmNyZWF0ZUFyZ3VtZW50KCkuc2V0VmFsdWUob3V0cHV0RGlyZWN0b3J5LnRvU3RyaW5nKCkpOwoKICAgICAgICBjb21tYW5kbGluZS5jcmVhdGVBcmd1bWVudCgpLnNldFZhbHVlKCItbGliIik7CiAgICAgICAgY29tbWFuZGxpbmUuY3JlYXRlQXJndW1lbnQoKS5zZXRWYWx1ZShsaWJEaXJlY3RvcnkudG9TdHJpbmcoKSk7CgogICAgICAgIGlmIChzdXBlckdyYW1tYXIgIT0gbnVsbCkgewogICAgICAgICAgICBsb2coIk9wdGlvbiAnZ2xpYicgaXMgbm90IHN1cHBvcnRlZCBieSBBTlRMUiB2My4gT3B0aW9uIGlnbm9yZWQhIiwgUHJvamVjdC5NU0dfV0FSTik7CiAgICAgICAgfQoKICAgICAgICBpZiAoZGlhZ25vc3RpYykgewogICAgICAgICAgICBjb21tYW5kbGluZS5jcmVhdGVBcmd1bWVudCgpLnNldFZhbHVlKCItZGlhZ25vc3RpYyIpOwogICAgICAgIH0KICAgICAgICBpZiAoZGVwZW5kKSB7CiAgICAgICAgICAgIGxvZygiT3B0aW9uICdkZXBlbmQnIGlzIGltcGxpY2l0ZWx5IGFsd2F5cyB1c2VkIGJ5IEFOVExSIHYzLiBPcHRpb24gY2FuIHNhZmVseSBiZSBvbWl0dGVkISIsIFByb2plY3QuTVNHX1dBUk4pOwogICAgICAgIH0KICAgICAgICBpZiAodHJhY2UpIHsKICAgICAgICAgICAgbG9nKCJPcHRpb24gJ3RyYWNlJyBpcyBub3Qgc3VwcG9ydGVkIGJ5IEFOVExSIHYzLiBPcHRpb24gaWdub3JlZCEiLCBQcm9qZWN0Lk1TR19XQVJOKTsKICAgICAgICB9CiAgICAgICAgaWYgKHRyYWNlUGFyc2VyKSB7CiAgICAgICAgICAgIGxvZygiT3B0aW9uICd0cmFjZVBhcnNlcicgaXMgbm90IHN1cHBvcnRlZCBieSBBTlRMUiB2My4gT3B0aW9uIGlnbm9yZWQhIiwgUHJvamVjdC5NU0dfV0FSTik7CiAgICAgICAgfQogICAgICAgIGlmICh0cmFjZUxleGVyKSB7CiAgICAgICAgICAgIGxvZygiT3B0aW9uICd0cmFjZUxleGVyJyBpcyBub3Qgc3VwcG9ydGVkIGJ5IEFOVExSIHYzLiBPcHRpb24gaWdub3JlZCEiLCBQcm9qZWN0Lk1TR19XQVJOKTsKICAgICAgICB9CiAgICAgICAgaWYgKGRlYnVnKSB7CiAgICAgICAgICAgIGNvbW1hbmRsaW5lLmNyZWF0ZUFyZ3VtZW50KCkuc2V0VmFsdWUoIi1kZWJ1ZyIpOwogICAgICAgIH0KICAgICAgICBpZiAocmVwb3J0KSB7CiAgICAgICAgICAgIGNvbW1hbmRsaW5lLmNyZWF0ZUFyZ3VtZW50KCkuc2V0VmFsdWUoIi1yZXBvcnQiKTsKICAgICAgICB9CiAgICAgICAgaWYgKHByaW50KSB7CiAgICAgICAgICAgIGNvbW1hbmRsaW5lLmNyZWF0ZUFyZ3VtZW50KCkuc2V0VmFsdWUoIi1wcmludCIpOwogICAgICAgIH0KICAgICAgICBpZiAocHJvZmlsZSkgewogICAgICAgICAgICBjb21tYW5kbGluZS5jcmVhdGVBcmd1bWVudCgpLnNldFZhbHVlKCItcHJvZmlsZSIpOwogICAgICAgIH0KICAgICAgICBpZiAobWVzc2FnZUZvcm1hdE5hbWUgIT0gbnVsbCkgewogICAgICAgICAgICBjb21tYW5kbGluZS5jcmVhdGVBcmd1bWVudCgpLnNldFZhbHVlKCItbWVzc2FnZS1mb3JtYXQiKTsKICAgICAgICAgICAgY29tbWFuZGxpbmUuY3JlYXRlQXJndW1lbnQoKS5zZXRWYWx1ZShtZXNzYWdlRm9ybWF0TmFtZSk7CiAgICAgICAgfQogICAgICAgIGlmIChuZmEpIHsKICAgICAgICAgICAgY29tbWFuZGxpbmUuY3JlYXRlQXJndW1lbnQoKS5zZXRWYWx1ZSgiLW5mYSIpOwogICAgICAgIH0KICAgICAgICBpZiAoZGZhKSB7CiAgICAgICAgICAgIGNvbW1hbmRsaW5lLmNyZWF0ZUFyZ3VtZW50KCkuc2V0VmFsdWUoIi1kZmEiKTsKICAgICAgICB9CiAgICAgICAgaWYgKG11bHRpVGhyZWFkZWQpIHsKICAgICAgICAgICAgY29tbWFuZGxpbmUuY3JlYXRlQXJndW1lbnQoKS5zZXRWYWx1ZSgiLVhtdWx0aXRocmVhZGVkIik7CiAgICAgICAgfQogICAgICAgIGlmIChub2NvbGxhcHNlKSB7CiAgICAgICAgICAgIGNvbW1hbmRsaW5lLmNyZWF0ZUFyZ3VtZW50KCkuc2V0VmFsdWUoIi1Ybm9jb2xsYXBzZSIpOwogICAgICAgIH0KICAgICAgICBpZiAobm9wcnVuZSkgewogICAgICAgICAgICBjb21tYW5kbGluZS5jcmVhdGVBcmd1bWVudCgpLnNldFZhbHVlKCItWG5vcHJ1bmUiKTsKICAgICAgICB9CiAgICAgICAgaWYgKGRiZ1NUKSB7CiAgICAgICAgICAgIGNvbW1hbmRsaW5lLmNyZWF0ZUFyZ3VtZW50KCkuc2V0VmFsdWUoIi1YZGJnU1QiKTsKICAgICAgICB9CiAgICAgICAgaWYgKGNvbnZlcnNpb250aW1lb3V0ICE9IG51bGwpIHsKICAgICAgICAgICAgY29tbWFuZGxpbmUuY3JlYXRlQXJndW1lbnQoKS5zZXRWYWx1ZSgiLVhjb252ZXJzaW9udGltZW91dCIpOwogICAgICAgICAgICBjb21tYW5kbGluZS5jcmVhdGVBcmd1bWVudCgpLnNldFZhbHVlKGNvbnZlcnNpb250aW1lb3V0KTsKICAgICAgICB9CiAgICAgICAgaWYgKGdyYW1tYXJUcmVlKSB7CiAgICAgICAgICAgIGNvbW1hbmRsaW5lLmNyZWF0ZUFyZ3VtZW50KCkuc2V0VmFsdWUoIi1YZ3J0cmVlIik7CiAgICAgICAgfQogICAgfQoKICAgIHByaXZhdGUgdm9pZCB2YWxpZGF0ZUF0dHJpYnV0ZXMoKSB0aHJvd3MgQnVpbGRFeGNlcHRpb24gewoKICAgICAgICBpZiAodGFyZ2V0ID09IG51bGwpIHsKICAgICAgICAgICAgdGhyb3cgbmV3IEJ1aWxkRXhjZXB0aW9uKCJObyB0YXJnZXQgZ3JhbW1hciwgbGV4ZXIgZ3JhbW1hciBvciB0cmVlIHBhcnNlciBzcGVjaWZpZWQhIik7CiAgICAgICAgfSBlbHNlIGlmICghdGFyZ2V0LmlzRmlsZSgpKSB7CiAgICAgICAgICAgIHRocm93IG5ldyBCdWlsZEV4Y2VwdGlvbigiVGFyZ2V0OiAiICsgdGFyZ2V0ICsgIiBpcyBub3QgYSBmaWxlISIpOwogICAgICAgIH0KCiAgICAgICAgLy8gaWYgbm8gb3V0cHV0IGRpcmVjdG9yeSBpcyBzcGVjaWZpZWQsIHVzZSB0aGUgdGFyZ2V0J3MgZGlyZWN0b3J5CiAgICAgICAgaWYgKG91dHB1dERpcmVjdG9yeSA9PSBudWxsKSB7CiAgICAgICAgICAgIHNldE91dHB1dGRpcmVjdG9yeShuZXcgRmlsZSh0YXJnZXQuZ2V0UGFyZW50KCkpKTsKICAgICAgICB9CgogICAgICAgIGlmICghb3V0cHV0RGlyZWN0b3J5LmlzRGlyZWN0b3J5KCkpIHsKICAgICAgICAgICAgdGhyb3cgbmV3IEJ1aWxkRXhjZXB0aW9uKCJJbnZhbGlkIG91dHB1dCBkaXJlY3Rvcnk6ICIgKyBvdXRwdXREaXJlY3RvcnkpOwogICAgICAgIH0KCiAgICAgICAgaWYgKHdvcmtpbmdkaXIgIT0gbnVsbCAmJiAhd29ya2luZ2Rpci5pc0RpcmVjdG9yeSgpKSB7CiAgICAgICAgICAgIHRocm93IG5ldyBCdWlsZEV4Y2VwdGlvbigiSW52YWxpZCB3b3JraW5nIGRpcmVjdG9yeTogIiArIHdvcmtpbmdkaXIpOwogICAgICAgIH0KCiAgICAgICAgLy8gaWYgbm8gbGliRGlyZWN0b3J5IGlzIHNwZWNpZmllZCwgdXNlIHRoZSB0YXJnZXQncyBkaXJlY3RvcnkKICAgICAgICBpZiAobGliRGlyZWN0b3J5ID09IG51bGwpIHsKICAgICAgICAgICAgc2V0TGliZGlyZWN0b3J5KG5ldyBGaWxlKHRhcmdldC5nZXRQYXJlbnQoKSkpOwogICAgICAgIH0KCiAgICAgICAgaWYgKCFsaWJEaXJlY3RvcnkuaXNEaXJlY3RvcnkoKSkgewogICAgICAgICAgICB0aHJvdyBuZXcgQnVpbGRFeGNlcHRpb24oIkludmFsaWQgbGliIGRpcmVjdG9yeTogIiArIGxpYkRpcmVjdG9yeSk7CiAgICAgICAgfQogICAgfQoKICAgIHByaXZhdGUgYm9vbGVhbiBkZXBlbmRlbmN5Q2hlY2soKSB0aHJvd3MgQnVpbGRFeGNlcHRpb24gewogICAgICAgIC8vIHVzaW5nICJhbnRsciAtbyA8T3V0cHV0RGlyZWN0b3J5PiAtbGliIDxMaWJEaXJlY3Rvcnk+IC1kZXBlbmQgPFQ+IgogICAgICAgIC8vIHRvIGdldCB0aGUgbGlzdCBvZiBkZXBlbmRlbmNpZXMKICAgICAgICBDb21tYW5kbGluZUphdmEgY21kbGluZTsKICAgICAgICB0cnkgewogICAgICAgICAgICBjbWRsaW5lID0gKENvbW1hbmRsaW5lSmF2YSkgY29tbWFuZGxpbmUuY2xvbmUoKTsKICAgICAgICB9IGNhdGNoIChqYXZhLmxhbmcuQ2xvbmVOb3RTdXBwb3J0ZWRFeGNlcHRpb24gZSkgewogICAgICAgICAgICB0aHJvdyBuZXcgQnVpbGRFeGNlcHRpb24oIkNsb25lIG9mIGNvbW1hbmRsaW5lIGZhaWxlZDogIiArIGUpOwogICAgICAgIH0KCiAgICAgICAgY21kbGluZS5jcmVhdGVBcmd1bWVudCgpLnNldFZhbHVlKCItZGVwZW5kIik7CiAgICAgICAgY21kbGluZS5jcmVhdGVBcmd1bWVudCgpLnNldFZhbHVlKCItbyIpOwogICAgICAgIGNtZGxpbmUuY3JlYXRlQXJndW1lbnQoKS5zZXRWYWx1ZShvdXRwdXREaXJlY3RvcnkudG9TdHJpbmcoKSk7CiAgICAgICAgY21kbGluZS5jcmVhdGVBcmd1bWVudCgpLnNldFZhbHVlKCItbGliIik7CiAgICAgICAgY21kbGluZS5jcmVhdGVBcmd1bWVudCgpLnNldFZhbHVlKGxpYkRpcmVjdG9yeS50b1N0cmluZygpKTsKICAgICAgICBjbWRsaW5lLmNyZWF0ZUFyZ3VtZW50KCkuc2V0VmFsdWUodGFyZ2V0LnRvU3RyaW5nKCkpOwoKICAgICAgICBsb2coY21kbGluZS5kZXNjcmliZUNvbW1hbmQoKSwgUHJvamVjdC5NU0dfVkVSQk9TRSk7CgogICAgICAgIC8vIHJlZGlyZWN0IG91dHB1dCBnZW5lcmF0ZWQgYnkgQU5UTFIgdG8gdGVtcG9yYXJ5IGZpbGUKICAgICAgICBSZWRpcmVjdG9yIHIgPSBuZXcgUmVkaXJlY3Rvcih0aGlzKTsKICAgICAgICBGaWxlIGY7CiAgICAgICAgdHJ5IHsKICAgICAgICAgICAgZiA9IEZpbGUuY3JlYXRlVGVtcEZpbGUoImRlcGVuZCIsIG51bGwsIGdldE91dHB1dGRpcmVjdG9yeSgpKTsKICAgICAgICAgICAgZi5kZWxldGVPbkV4aXQoKTsKICAgICAgICAgICAgbG9nKCJXcml0ZSBkZXBlbmRlbmNpZXMgZm9yICciICsgdGFyZ2V0LnRvU3RyaW5nKCkgKyAiJyB0byBmaWxlICciICsgZi5nZXRDYW5vbmljYWxQYXRoKCkgKyAiJyIsIFByb2plY3QuTVNHX1ZFUkJPU0UpOwogICAgICAgICAgICByLnNldE91dHB1dChmKTsKICAgICAgICAgICAgci5zZXRBbHdheXNMb2coZmFsc2UpOwogICAgICAgICAgICByLmNyZWF0ZVN0cmVhbXMoKTsKICAgICAgICB9IGNhdGNoIChJT0V4Y2VwdGlvbiBlKSB7CiAgICAgICAgICAgIHRocm93IG5ldyBCdWlsZEV4Y2VwdGlvbigiUmVkaXJlY3Rpb24gb2Ygb3V0cHV0IGZhaWxlZDogIiArIGUpOwogICAgICAgIH0KCiAgICAgICAgLy8gZXhlY3V0ZSBhbnRsciAtZGVwZW5kIC4uLgogICAgICAgIGludCBlcnIgPSAwOwogICAgICAgIHRyeSB7CiAgICAgICAgICAgIGVyciA9IHJ1bihjbWRsaW5lLmdldENvbW1hbmRsaW5lKCksIHIuZ2V0T3V0cHV0U3RyZWFtKCksIG51bGwpOwogICAgICAgIH0gY2F0Y2ggKElPRXhjZXB0aW9uIGUpIHsKICAgICAgICAgICAgdHJ5IHsKICAgICAgICAgICAgICAgIHIuY29tcGxldGUoKTsKICAgICAgICAgICAgICAgIGxvZygiUmVkaXJlY3Rpb24gb2Ygb3V0cHV0IHRlcm1pbmF0ZWQuIiwgUHJvamVjdC5NU0dfVkVSQk9TRSk7CiAgICAgICAgICAgIH0gY2F0Y2ggKElPRXhjZXB0aW9uIGV4KSB7CiAgICAgICAgICAgICAgICBsb2coIlRlcm1pbmF0aW9uIG9mIG91dHB1dCByZWRpcmVjdGlvbiBmYWlsZWQ6ICIgKyBleCwgUHJvamVjdC5NU0dfRVJSKTsKICAgICAgICAgICAgfQogICAgICAgICAgICB0aHJvdyBuZXcgQnVpbGRFeGNlcHRpb24oZSwgZ2V0TG9jYXRpb24oKSk7CiAgICAgICAgfSBmaW5hbGx5IHsKICAgICAgICAgICAgdHJ5IHsKICAgICAgICAgICAgICAgIGJvcy5jbG9zZSgpOwogICAgICAgICAgICB9IGNhdGNoIChJT0V4Y2VwdGlvbiBlKSB7CiAgICAgICAgICAgICAgICAvLyBpZ25vcmUKICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgdHJ5IHsKICAgICAgICAgICAgci5jb21wbGV0ZSgpOwogICAgICAgICAgICBsb2coIlJlZGlyZWN0aW9uIG9mIG91dHB1dCB0ZXJtaW5hdGVkLiIsIFByb2plY3QuTVNHX1ZFUkJPU0UpOwogICAgICAgIH0gY2F0Y2ggKElPRXhjZXB0aW9uIGUpIHsKICAgICAgICAgICAgbG9nKCJUZXJtaW5hdGlvbiBvZiBvdXRwdXQgcmVkaXJlY3Rpb24gZmFpbGVkOiAiICsgZSwgUHJvamVjdC5NU0dfRVJSKTsKICAgICAgICB9CgogICAgICAgIGlmIChlcnIgIT0gMCkgewogICAgICAgICAgICBpZiAoZi5leGlzdHMoKSkgewogICAgICAgICAgICAgICAgZi5kZWxldGUoKTsKICAgICAgICAgICAgfQogICAgICAgICAgICBpZiAoY21kbGluZS5nZXRDbGFzc3BhdGgoKSA9PSBudWxsKSB7CiAgICAgICAgICAgICAgICBsb2coIkFudGxyIGxpYnJhcmllcyBub3QgZm91bmQgaW4gZXh0ZXJuYWwgY2xhc3NwYXRoIG9yIGVtYmVkZGVkIGNsYXNzcGF0aCBzdGF0ZW1lbnQgIiwgUHJvamVjdC5NU0dfRVJSKTsKICAgICAgICAgICAgfQogICAgICAgICAgICBsb2coIkRlcGVuZGVuY3kgY2hlY2sgZmFpbGVkLiBBTlRMUiByZXR1cm5lZDogIiArIGVyciwgUHJvamVjdC5NU0dfRVJSKTsKICAgICAgICAgICAgcmV0dXJuIHRydWU7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgUGF0dGVybiBwID0gUGF0dGVybi5jb21waWxlKCJlcnJvclxcKFswLTldK1xcKToiKTsKICAgICAgICAgICAgTWF0Y2hlciBtID0gcC5tYXRjaGVyKGJvcy50b1N0cmluZygpKTsKICAgICAgICAgICAgaWYgKG0uZmluZCgpKSB7CiAgICAgICAgICAgICAgICBpZiAoZi5leGlzdHMoKSkgewogICAgICAgICAgICAgICAgICAgIGYuZGVsZXRlKCk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAvLyBPbiBlcnJvciBhbHdheXMgcmVjb21waWxlCiAgICAgICAgICAgICAgICByZXR1cm4gdHJ1ZTsKICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgYm9vbGVhbiBjb21waWxlID0gZmFsc2U7CgogICAgICAgIC8vIG9wZW4gdGVtcG9yYXJ5IGZpbGUKICAgICAgICBCdWZmZXJlZFJlYWRlciBpbiA9IG51bGw7CiAgICAgICAgdHJ5IHsKICAgICAgICAgICAgaW4gPSBuZXcgQnVmZmVyZWRSZWFkZXIobmV3IEZpbGVSZWFkZXIoZikpOwogICAgICAgIH0gY2F0Y2ggKElPRXhjZXB0aW9uIGUpIHsKICAgICAgICAgICAgdHJ5IHsKICAgICAgICAgICAgICAgIGlmIChpbiAhPSBudWxsKSB7CiAgICAgICAgICAgICAgICAgICAgaW4uY2xvc2UoKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfSBjYXRjaCAoSU9FeGNlcHRpb24gZXgpIHsKICAgICAgICAgICAgICAgIHRocm93IG5ldyBCdWlsZEV4Y2VwdGlvbigiQ291bGQgbm90IGNsb3NlIGZpbGVcJyIgKyBmLnRvU3RyaW5nKCkgKyAiXCcuIik7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgaWYgKGYuZXhpc3RzKCkpIHsKICAgICAgICAgICAgICAgIGYuZGVsZXRlKCk7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgdHJ5IHsKICAgICAgICAgICAgICAgIHRocm93IG5ldyBCdWlsZEV4Y2VwdGlvbigiQ291bGQgbm90IG9wZW4gXCciICsgZi5nZXRDYW5vbmljYWxQYXRoKCkgKyAiXCcgZm9yIHJlYWRpbmcuIik7CiAgICAgICAgICAgIH0gY2F0Y2ggKElPRXhjZXB0aW9uIGV4KSB7CiAgICAgICAgICAgICAgICB0aHJvdyBuZXcgQnVpbGRFeGNlcHRpb24oIkNvdWxkIG5vdCBvcGVuIFwnIiArIGYudG9TdHJpbmcoKSArICJcJyBmb3IgcmVhZGluZy4iKTsKICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgLy8gZXZhbHVhdGUgZGVwZW5kZW5jaWVzIGluIHRlbXBvcmFyeSBmaWxlCiAgICAgICAgU3RyaW5nIHM7CgogICAgICAgIHRyeSB7CiAgICAgICAgICAgIHdoaWxlICgocyA9IGluLnJlYWRMaW5lKCkpICE9IG51bGwpIHsKICAgICAgICAgICAgICAgIFN0cmluZyBhOwogICAgICAgICAgICAgICAgU3RyaW5nIGI7CiAgICAgICAgICAgICAgICAvLyBBcyB0aGUgc2VwYXJhdG9yIHN0cmluZyBpbiBsaW5lcyBlbWl0dGVkIGJ5IHRoZSBkZXBlbmQgb3B0aW9uCiAgICAgICAgICAgICAgICAvLyBpcyBlaXRoZXIgIiA6ICIgb3IgIjogIiB0cmltIGlzIGludm9rZWQgZm9yIHRoZSBmaXJzdCBmaWxlIG5hbWUgb2YgYSBsaW5lCiAgICAgICAgICAgICAgICBpbnQgdG8gPSBzLmluZGV4T2YoIjogIik7CiAgICAgICAgICAgICAgICBpZiAodG8gPj0gMCkgewogICAgICAgICAgICAgICAgICAgIGEgPSBzLnN1YnN0cmluZygwLCB0bykudHJpbSgpOwogICAgICAgICAgICAgICAgICAgIEZpbGUgbGhzID0gbmV3IEZpbGUoYSk7CiAgICAgICAgICAgICAgICAgICAgaWYgKCFsaHMuaXNGaWxlKCkpIHsKICAgICAgICAgICAgICAgICAgICAgICAgbG9nKCJGaWxlICciICsgYSArICInIGlzIG5vdCBhIHJlZ3VsYXIgZmlsZSIsIFByb2plY3QuTVNHX1ZFUkJPU0UpOwogICAgICAgICAgICAgICAgICAgICAgICBTdHJpbmcgbmFtZSA9IGxocy5nZXROYW1lKCk7CiAgICAgICAgICAgICAgICAgICAgICAgIFN0cmluZ1tdIHBhcnRzID0gc3BsaXRSaWdodEhhbmRTaWRlKG5hbWUsICJcXHUwMDJFIik7CiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChwYXJ0cy5sZW5ndGggPD0gMSkgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgYSArPSAiLmphdmEiOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgbGhzID0gbmV3IEZpbGUoYSk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAobGhzLmlzRmlsZSgpKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbG9nKCJGaWxlICciICsgYSArICInIGlzIGEgcmVndWxhciBmaWxlIGxhc3QgbW9kaWZpZWQgYXQgIiArIGxocy5sYXN0TW9kaWZpZWQoKSwgUHJvamVjdC5NU0dfVkVSQk9TRSk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgICAgIGIgPSBzLnN1YnN0cmluZyh0byArICI6ICIubGVuZ3RoKCkpOwogICAgICAgICAgICAgICAgICAgIFN0cmluZ1tdIG5hbWVzID0gc3BsaXRSaWdodEhhbmRTaWRlKGIsICIsID8iKTsKICAgICAgICAgICAgICAgICAgICBGaWxlIGFGaWxlID0gbmV3IEZpbGUoYSk7CiAgICAgICAgICAgICAgICAgICAgZm9yIChTdHJpbmcgbmFtZSA6IG5hbWVzKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIEZpbGUgYkZpbGUgPSBuZXcgRmlsZShuYW1lKTsKICAgICAgICAgICAgICAgICAgICAgICAgbG9nKCJGaWxlICciICsgYSArICInIGRlcGVuZHMgb24gZmlsZSAnIiArIG5hbWUgKyAiJyIsIFByb2plY3QuTVNHX1ZFUkJPU0UpOwogICAgICAgICAgICAgICAgICAgICAgICBsb2coIkZpbGUgJyIgKyBhICsgIicgbW9kaWZpZWQgYXQgIiArIGFGaWxlLmxhc3RNb2RpZmllZCgpLCBQcm9qZWN0Lk1TR19WRVJCT1NFKTsKICAgICAgICAgICAgICAgICAgICAgICAgbG9nKCJGaWxlICciICsgbmFtZSArICInIG1vZGlmaWVkIGF0ICIgKyBiRmlsZS5sYXN0TW9kaWZpZWQoKSwgUHJvamVjdC5NU0dfVkVSQk9TRSk7CiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChmaWxlVXRpbHMuaXNVcFRvRGF0ZShhRmlsZSwgYkZpbGUpKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBsb2coIkNvbXBpbGluZyAiICsgdGFyZ2V0ICsgIiBhcyAnIiArIG5hbWUgKyAiJyBpcyBuZXdlciB0aGFuICciICsgYSArICInIiwgUHJvamVjdC5NU0dfVkVSQk9TRSk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBGZWVsaW5nIG5vdCBxdWl0ZSBjb21mb3J0YWJsZSB3aXRoIHRvdWNoaW5nIHRoZSBmaWxlCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBmaWxlVXRpbHMuc2V0RmlsZUxhc3RNb2RpZmllZChhRmlsZSwgLTEpOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgbG9nKCJUb3VjaGluZyBmaWxlICciICsgYSArICInIiwgUHJvamVjdC5NU0dfVkVSQk9TRSk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb21waWxlID0gdHJ1ZTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIGlmIChjb21waWxlKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgICAgICBpbi5jbG9zZSgpOwogICAgICAgIH0gY2F0Y2ggKElPRXhjZXB0aW9uIGUpIHsKICAgICAgICAgICAgaWYgKGYuZXhpc3RzKCkpIHsKICAgICAgICAgICAgICAgIGYuZGVsZXRlKCk7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgdGhyb3cgbmV3IEJ1aWxkRXhjZXB0aW9uKCJFcnJvciByZWFkaW5nIGZpbGUgJyIgKyBmLnRvU3RyaW5nKCkgKyAiJyIpOwogICAgICAgIH0KCiAgICAgICAgaWYgKGYuZXhpc3RzKCkpIHsKICAgICAgICAgICAgZi5kZWxldGUoKTsKICAgICAgICB9CgogICAgICAgIHJldHVybiBjb21waWxlOwogICAgfQoKICAgIHByaXZhdGUgU3RyaW5nW10gc3BsaXRSaWdodEhhbmRTaWRlKFN0cmluZyBmaWxlTmFtZXMsIFN0cmluZyBwYXR0ZXJuKSB7CiAgICAgICAgU3RyaW5nW10gbmFtZXMgPSBmaWxlTmFtZXMuc3BsaXQocGF0dGVybik7CiAgICAgICAgZm9yIChTdHJpbmcgbmFtZSA6IG5hbWVzKSB7CiAgICAgICAgICAgIGxvZygiU3BsaXQgcmlnaHQgaGFuZCBzaWRlICciICsgbmFtZSArICInIiwgUHJvamVjdC5NU0dfVkVSQk9TRSk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBuYW1lczsKICAgIH0KCiAgICAvKiogZXhlY3V0ZSBpbiBhIGZvcmtlZCBWTSAqLwogICAgcHJpdmF0ZSBpbnQgcnVuKFN0cmluZ1tdIGNvbW1hbmQsIE91dHB1dFN0cmVhbSBvdXQsIE91dHB1dFN0cmVhbSBlcnIpIHRocm93cyBJT0V4Y2VwdGlvbiB7CiAgICAgICAgUHVtcFN0cmVhbUhhbmRsZXIgcHNoOwogICAgICAgIGlmIChlcnIgPT0gbnVsbCkgewogICAgICAgICAgICBwc2ggPSBuZXcgUHVtcFN0cmVhbUhhbmRsZXIob3V0LCBib3MpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIHBzaCA9IG5ldyBQdW1wU3RyZWFtSGFuZGxlcihvdXQsIG5ldyBUZWVPdXRwdXRTdHJlYW0oZXJyLCBib3MpKTsKICAgICAgICB9CgogICAgICAgIEV4ZWN1dGUgZXhlID0gbmV3IEV4ZWN1dGUocHNoLCBudWxsKTsKCiAgICAgICAgZXhlLnNldEFudFJ1bihnZXRQcm9qZWN0KCkpOwogICAgICAgIGlmICh3b3JraW5nZGlyICE9IG51bGwpIHsKICAgICAgICAgICAgZXhlLnNldFdvcmtpbmdEaXJlY3Rvcnkod29ya2luZ2Rpcik7CiAgICAgICAgfQoKICAgICAgICBleGUuc2V0Q29tbWFuZGxpbmUoY29tbWFuZCk7CgogICAgICAgIHJldHVybiBleGUuZXhlY3V0ZSgpOwogICAgfQp9Cg==