cGFja2FnZSBvcmcuYXBhY2hlLm1hdmVuLnNjbS5wcm92aWRlci5iYXphYXIuY29tbWFuZC5kaWZmOwoKLyoKICogTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZQogKiBvciBtb3JlIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUKICogZGlzdHJpYnV0ZWQgd2l0aCB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24KICogcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZQogKiB0byB5b3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlCiAqICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2UKICogd2l0aCB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAogKgogKiBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKICoKICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLAogKiBzb2Z0d2FyZSBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbgogKiAiQVMgSVMiIEJBU0lTLCBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkKICogS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4gIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlCiAqIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQgbGltaXRhdGlvbnMKICogdW5kZXIgdGhlIExpY2Vuc2UuCiAqLwoKaW1wb3J0IG9yZy5hcGFjaGUubWF2ZW4uc2NtLlNjbUZpbGU7CmltcG9ydCBvcmcuYXBhY2hlLm1hdmVuLnNjbS5TY21GaWxlU3RhdHVzOwppbXBvcnQgb3JnLmFwYWNoZS5tYXZlbi5zY20ubG9nLlNjbUxvZ2dlcjsKaW1wb3J0IG9yZy5hcGFjaGUubWF2ZW4uc2NtLnByb3ZpZGVyLmJhemFhci5jb21tYW5kLkJhemFhckNvbnN1bWVyOwoKaW1wb3J0IGphdmEuaW8uRmlsZTsKaW1wb3J0IGphdmEudXRpbC5BcnJheUxpc3Q7CmltcG9ydCBqYXZhLnV0aWwuSGFzaE1hcDsKaW1wb3J0IGphdmEudXRpbC5MaXN0OwppbXBvcnQgamF2YS51dGlsLk1hcDsKCi8qKgogKiBAYXV0aG9yIDxhIGhyZWY9Im1haWx0bzp0b3Jiam9ybkBzbW9yZ3Jhdi5vcmciPlRvcmJq+HJuIEVpa2xpIFNt+HJncmF2PC9hPgogKi8KcHVibGljIGNsYXNzIEJhemFhckRpZmZDb25zdW1lcgogICAgZXh0ZW5kcyBCYXphYXJDb25zdW1lcgp7CgogICAgcHJpdmF0ZSBmaW5hbCBzdGF0aWMgU3RyaW5nIE1PRElGSUVEX0ZJTEVfVE9LRU4gPSAiPT09IG1vZGlmaWVkIGZpbGUgIjsKCiAgICBwcml2YXRlIGZpbmFsIHN0YXRpYyBTdHJpbmcgQURERURfRklMRV9UT0tFTiA9ICI9PT0gYWRkZWQgZmlsZSAiOwoKICAgIHByaXZhdGUgZmluYWwgc3RhdGljIFN0cmluZyBERUxFVEVEX0ZJTEVfVE9LRU4gPSAiPT09IGRlbGV0ZWQgZmlsZSAiOwoKICAgIHByaXZhdGUgZmluYWwgc3RhdGljIFN0cmluZyBOT19ORVdMSU5FX1RPS0VOID0gIlxcIE5vIG5ld2xpbmUgYXQgZW5kIG9mIGZpbGUiOwoKICAgIHByaXZhdGUgZmluYWwgc3RhdGljIFN0cmluZyBGUk9NX0ZJTEVfVE9LRU4gPSAiLS0tIjsKCiAgICBwcml2YXRlIGZpbmFsIHN0YXRpYyBTdHJpbmcgVE9fRklMRV9UT0tFTiA9ICIrKysiOwoKICAgIHByaXZhdGUgZmluYWwgc3RhdGljIFN0cmluZyBBRERFRF9MSU5FX1RPS0VOID0gIisiOwoKICAgIHByaXZhdGUgZmluYWwgc3RhdGljIFN0cmluZyBSRU1PVkVEX0xJTkVfVE9LRU4gPSAiLSI7CgogICAgcHJpdmF0ZSBmaW5hbCBzdGF0aWMgU3RyaW5nIFVOQ0hBTkdFRF9MSU5FX1RPS0VOID0gIiAiOwoKICAgIHByaXZhdGUgZmluYWwgc3RhdGljIFN0cmluZyBSQU5HRV9UT0tFTiA9ICJAQCI7CgogICAgcHJpdmF0ZSBTY21Mb2dnZXIgbG9nZ2VyOwoKICAgIHByaXZhdGUgRmlsZSB3b3JraW5nRGlyZWN0b3J5OwoKICAgIHByaXZhdGUgU3RyaW5nIGN1cnJlbnRGaWxlOwoKICAgIHByaXZhdGUgU3RyaW5nQnVmZmVyIGN1cnJlbnREaWZmZXJlbmNlOwoKICAgIHByaXZhdGUgTGlzdCBjaGFuZ2VkRmlsZXMgPSBuZXcgQXJyYXlMaXN0KCk7CgogICAgcHJpdmF0ZSBNYXAgZGlmZmVyZW5jZXMgPSBuZXcgSGFzaE1hcCgpOwoKICAgIHByaXZhdGUgU3RyaW5nQnVmZmVyIHBhdGNoID0gbmV3IFN0cmluZ0J1ZmZlcigpOwoKICAgIHB1YmxpYyBCYXphYXJEaWZmQ29uc3VtZXIoIFNjbUxvZ2dlciBsb2dnZXIsIEZpbGUgd29ya2luZ0RpcmVjdG9yeSApCiAgICB7CiAgICAgICAgc3VwZXIoIGxvZ2dlciApOwogICAgICAgIHRoaXMubG9nZ2VyID0gbG9nZ2VyOwogICAgICAgIHRoaXMud29ya2luZ0RpcmVjdG9yeSA9IHdvcmtpbmdEaXJlY3Rvcnk7CiAgICB9CgogICAgcHVibGljIHZvaWQgZG9Db25zdW1lKCBTY21GaWxlU3RhdHVzIHN0YXR1cywgU3RyaW5nIGxpbmUgKQogICAgewogICAgICAgIFN0cmluZyB0bXBMaW5lID0gbmV3IFN0cmluZyggbGluZSApOwogICAgICAgIHBhdGNoLmFwcGVuZCggbGluZSApLmFwcGVuZCggIlxuIiApOwoKICAgICAgICAvLyBQYXJzZSBsaW5lCiAgICAgICAgaWYgKCBsaW5lLnN0YXJ0c1dpdGgoIE1PRElGSUVEX0ZJTEVfVE9LRU4gKSApCiAgICAgICAgewogICAgICAgICAgICB0bXBMaW5lID0gbGluZS5zdWJzdHJpbmcoIE1PRElGSUVEX0ZJTEVfVE9LRU4ubGVuZ3RoKCkgKTsKICAgICAgICAgICAgdG1wTGluZSA9IHRtcExpbmUudHJpbSgpOwogICAgICAgICAgICBzdGF0dXMgPSBTY21GaWxlU3RhdHVzLk1PRElGSUVEOwogICAgICAgICAgICBhZGRDaGFuZ2VkRmlsZSggc3RhdHVzLCBsaW5lLCB0bXBMaW5lICk7CiAgICAgICAgfQogICAgICAgIGVsc2UgaWYgKCBsaW5lLnN0YXJ0c1dpdGgoIEFEREVEX0ZJTEVfVE9LRU4gKSApCiAgICAgICAgewogICAgICAgICAgICB0bXBMaW5lID0gbGluZS5zdWJzdHJpbmcoIEFEREVEX0ZJTEVfVE9LRU4ubGVuZ3RoKCkgKTsKICAgICAgICAgICAgdG1wTGluZSA9IHRtcExpbmUudHJpbSgpOwogICAgICAgICAgICBzdGF0dXMgPSBTY21GaWxlU3RhdHVzLkFEREVEOwogICAgICAgICAgICBhZGRDaGFuZ2VkRmlsZSggc3RhdHVzLCBsaW5lLCB0bXBMaW5lICk7CiAgICAgICAgfQogICAgICAgIGVsc2UgaWYgKCBsaW5lLnN0YXJ0c1dpdGgoIERFTEVURURfRklMRV9UT0tFTiApICkKICAgICAgICB7CiAgICAgICAgICAgIHRtcExpbmUgPSBsaW5lLnN1YnN0cmluZyggREVMRVRFRF9GSUxFX1RPS0VOLmxlbmd0aCgpICk7CiAgICAgICAgICAgIHRtcExpbmUgPSB0bXBMaW5lLnRyaW0oKTsKICAgICAgICAgICAgc3RhdHVzID0gU2NtRmlsZVN0YXR1cy5ERUxFVEVEOwogICAgICAgICAgICBhZGRDaGFuZ2VkRmlsZSggc3RhdHVzLCBsaW5lLCB0bXBMaW5lICk7CiAgICAgICAgfQogICAgICAgIGVsc2UgaWYgKCBsaW5lLnN0YXJ0c1dpdGgoIFRPX0ZJTEVfVE9LRU4gKSB8fCBsaW5lLnN0YXJ0c1dpdGgoIEZST01fRklMRV9UT0tFTiApICkKICAgICAgICB7CiAgICAgICAgICAgIC8vIGlnbm9yZSAodG8gYXZvaWQgY29uZmxpY3RzIHdpdGggYWRkIGFuZCByZW1vdmUgdG9rZW5zKQogICAgICAgIH0KICAgICAgICBlbHNlIGlmICggbGluZS5zdGFydHNXaXRoKCBBRERFRF9MSU5FX1RPS0VOICkgfHwgbGluZS5zdGFydHNXaXRoKCBSRU1PVkVEX0xJTkVfVE9LRU4gKSB8fAogICAgICAgICAgICBsaW5lLnN0YXJ0c1dpdGgoIFVOQ0hBTkdFRF9MSU5FX1RPS0VOICkgfHwgbGluZS5zdGFydHNXaXRoKCBSQU5HRV9UT0tFTiApIHx8CiAgICAgICAgICAgIGxpbmUuc3RhcnRzV2l0aCggTk9fTkVXTElORV9UT0tFTiApICkKICAgICAgICB7CiAgICAgICAgICAgIGN1cnJlbnREaWZmZXJlbmNlLmFwcGVuZCggbGluZSApLmFwcGVuZCggIlxuIiApOwogICAgICAgIH0KICAgIH0KCiAgICAvKioKICAgICAqIFRoaXMgbWV0aG9kIHRha2VzIGludG8gYWNjb3VudCB0d28gdHlwZXMgb2YgZGlmZiBvdXRwdXQuIDxicj4KICAgICAqIC0gQmF6YWFyIDAuNyBmb3JtYXQ6IGRpci9kaXIvbXlmaWxlICA8YnI+CiAgICAgKiAtIEJhemFhciAwLjggZm9ybWF0OiBhL2Rpci9kaXIvbXlmaWxlIDxicj4KICAgICAqCiAgICAgKiBAcGFyYW0gc3RhdHVzICBFZy4gbW9kaWZpZWQgb3IgYWRkZWQKICAgICAqIEBwYXJhbSBsaW5lICAgIFRoZSBvcmlnaW5hbCBiYXphYXIgb3V0cHV0IHRvIHByb2Nlc3MgKGZvciBsb2dnaW5nKQogICAgICogQHBhcmFtIHRtcExpbmUgVGhlIGJhemFhciBvdXRwdXQgdG8gcHJvY2VzcwogICAgICovCiAgICBwcml2YXRlIHZvaWQgYWRkQ2hhbmdlZEZpbGUoIFNjbUZpbGVTdGF0dXMgc3RhdHVzLCBTdHJpbmcgbGluZSwgU3RyaW5nIHRtcExpbmUgKQogICAgewogICAgICAgIHRtcExpbmUgPSB0bXBMaW5lLnN1YnN0cmluZyggMSwgdG1wTGluZS5sZW5ndGgoKSAtIDEgKTsKICAgICAgICBib29sZWFuIG9rID0gYWRkQ2hhbmdlZEZpbGUoIHN0YXR1cywgdG1wTGluZSApOwoKICAgICAgICBpZiAoICFvayApCiAgICAgICAgewogICAgICAgICAgICBpbnQgaW5kZXggPSB0bXBMaW5lLmluZGV4T2YoICIvIiApOwogICAgICAgICAgICBpZiAoIGluZGV4ID4gLTEgKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICB0bXBMaW5lID0gdG1wTGluZS5zdWJzdHJpbmcoIGluZGV4ICsgMSApOwogICAgICAgICAgICAgICAgb2sgPSBhZGRDaGFuZ2VkRmlsZSggc3RhdHVzLCB0bXBMaW5lICk7CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIGlmICggIW9rICkKICAgICAgICB7CiAgICAgICAgICAgIGxvZ2dlci53YXJuKCAiQ291bGQgbm90IGZpZ3VyZSBvdXQgb2YgbGluZTogIiArIGxpbmUgKTsKICAgICAgICB9CiAgICB9CgogICAgLyoqCiAgICAgKiBAcmV0dXJuIFRydWUgaWYgdG1wTGluZSB3YXMgYSB2YWxpZCBmaWxlIGFuZCB0aHVzIGFkZGVkIHRvIHRoZSBjaGFuZ2VzZXQKICAgICAqLwogICAgcHJpdmF0ZSBib29sZWFuIGFkZENoYW5nZWRGaWxlKCBTY21GaWxlU3RhdHVzIHN0YXR1cywgU3RyaW5nIHRtcExpbmUgKQogICAgewogICAgICAgIEZpbGUgdG1wRmlsZSA9IG5ldyBGaWxlKCB3b3JraW5nRGlyZWN0b3J5LCB0bXBMaW5lICk7CiAgICAgICAgaWYgKCBzdGF0dXMuZXF1YWxzKCBTY21GaWxlU3RhdHVzLkRFTEVURUQgKSApCiAgICAgICAgewogICAgICAgICAgICByZXR1cm4gdHJ1ZTsKICAgICAgICB9CgogICAgICAgIGlmICggdG1wRmlsZS5pc0ZpbGUoKSApCiAgICAgICAgewogICAgICAgICAgICBjdXJyZW50RmlsZSA9IHRtcExpbmU7CiAgICAgICAgICAgIGN1cnJlbnREaWZmZXJlbmNlID0gbmV3IFN0cmluZ0J1ZmZlcigpOwogICAgICAgICAgICBkaWZmZXJlbmNlcy5wdXQoIGN1cnJlbnRGaWxlLCBjdXJyZW50RGlmZmVyZW5jZSApOwogICAgICAgICAgICBjaGFuZ2VkRmlsZXMuYWRkKCBuZXcgU2NtRmlsZSggdG1wTGluZSwgc3RhdHVzICkgKTsKICAgICAgICAgICAgcmV0dXJuIHRydWU7CiAgICAgICAgfQoKICAgICAgICByZXR1cm4gZmFsc2U7CiAgICB9CgogICAgcHVibGljIExpc3QgZ2V0Q2hhbmdlZEZpbGVzKCkKICAgIHsKICAgICAgICByZXR1cm4gY2hhbmdlZEZpbGVzOwogICAgfQoKICAgIHB1YmxpYyBNYXAgZ2V0RGlmZmVyZW5jZXMoKQogICAgewogICAgICAgIHJldHVybiBkaWZmZXJlbmNlczsKICAgIH0KCiAgICBwdWJsaWMgU3RyaW5nIGdldFBhdGNoKCkKICAgIHsKICAgICAgICByZXR1cm4gcGF0Y2gudG9TdHJpbmcoKTsKICAgIH0KfQo=