LyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogQ29weXJpZ2h0IChjKSAyMDAxLCAyMDA0IElCTSBDb3Jwb3JhdGlvbiBhbmQgb3RoZXJzLgogKiBBbGwgcmlnaHRzIHJlc2VydmVkLiBUaGlzIHByb2dyYW0gYW5kIHRoZSBhY2NvbXBhbnlpbmcgbWF0ZXJpYWxzCiAqIGFyZSBtYWRlIGF2YWlsYWJsZSB1bmRlciB0aGUgdGVybXMgb2YgdGhlIEVjbGlwc2UgUHVibGljIExpY2Vuc2UgdjEuMAogKiB3aGljaCBhY2NvbXBhbmllcyB0aGlzIGRpc3RyaWJ1dGlvbiwgYW5kIGlzIGF2YWlsYWJsZSBhdAogKiBodHRwOi8vd3d3LmVjbGlwc2Uub3JnL2xlZ2FsL2VwbC12MTAuaHRtbAogKgogKiBDb250cmlidXRvcnM6CiAqIElCTSBDb3Jwb3JhdGlvbiAtIGluaXRpYWwgQVBJIGFuZCBpbXBsZW1lbnRhdGlvbgogKiB5eXl5bW1kZCBidWcgICAgICBFbWFpbCBhbmQgb3RoZXIgY29udGFjdCBpbmZvcm1hdGlvbgogKiAtLS0tLS0tLSAtLS0tLS0tLSAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQogKiAyMDA2MDExMiAgIDEyMTE5OSBqZXNwZXJAc2Vsc2thYmV0Lm9yZyAtIEplc3BlciBN+GxsZXIKICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCnBhY2thZ2Ugb3JnLmVjbGlwc2Uud3N0LmNvbW1hbmQuaW50ZXJuYWwuZW52LmNvbW1vbjsKCgppbXBvcnQgamF2YS5pby5JT0V4Y2VwdGlvbjsKaW1wb3J0IGphdmEuaW8uSW5wdXRTdHJlYW07CmltcG9ydCBqYXZhLmlvLk91dHB1dFN0cmVhbTsKaW1wb3J0IGphdmEudXRpbC5WZWN0b3I7CgppbXBvcnQgb3JnLmVjbGlwc2UuY29yZS5yZXNvdXJjZXMuSUNvbnRhaW5lcjsKaW1wb3J0IG9yZy5lY2xpcHNlLmNvcmUucmVzb3VyY2VzLklGaWxlOwppbXBvcnQgb3JnLmVjbGlwc2UuY29yZS5yZXNvdXJjZXMuSUZvbGRlcjsKaW1wb3J0IG9yZy5lY2xpcHNlLmNvcmUucmVzb3VyY2VzLklQcm9qZWN0OwppbXBvcnQgb3JnLmVjbGlwc2UuY29yZS5yZXNvdXJjZXMuSVJlc291cmNlOwppbXBvcnQgb3JnLmVjbGlwc2UuY29yZS5yZXNvdXJjZXMuSVdvcmtzcGFjZTsKaW1wb3J0IG9yZy5lY2xpcHNlLmNvcmUucmVzb3VyY2VzLklXb3Jrc3BhY2VSb290OwppbXBvcnQgb3JnLmVjbGlwc2UuY29yZS5yZXNvdXJjZXMuUmVzb3VyY2VzUGx1Z2luOwppbXBvcnQgb3JnLmVjbGlwc2UuY29yZS5ydW50aW1lLkNvcmVFeGNlcHRpb247CmltcG9ydCBvcmcuZWNsaXBzZS5jb3JlLnJ1bnRpbWUuSVBhdGg7CmltcG9ydCBvcmcuZWNsaXBzZS5jb3JlLnJ1bnRpbWUuSVByb2dyZXNzTW9uaXRvcjsKaW1wb3J0IG9yZy5lY2xpcHNlLmNvcmUucnVudGltZS5JU3RhdHVzOwppbXBvcnQgb3JnLmVjbGlwc2UuY29yZS5ydW50aW1lLlBhdGg7CmltcG9ydCBvcmcuZWNsaXBzZS5jb3JlLnJ1bnRpbWUuUGx1Z2luOwppbXBvcnQgb3JnLmVjbGlwc2UuY29yZS5ydW50aW1lLlN0YXR1czsKaW1wb3J0IG9yZy5lY2xpcHNlLm9zZ2kudXRpbC5OTFM7CmltcG9ydCBvcmcuZWNsaXBzZS53c3QuY29tbWFuZC5pbnRlcm5hbC5lbnYuRW52aXJvbm1lbnRNZXNzYWdlczsKaW1wb3J0IG9yZy5lY2xpcHNlLndzdC5jb21tYW5kLmludGVybmFsLmVudi5jb3JlLmNvbW1vbi5TdGF0dXNVdGlsczsKaW1wb3J0IG9yZy5lY2xpcHNlLndzdC5jb21tYW5kLmludGVybmFsLmVudi5jb3JlLmNvbnRleHQuUmVzb3VyY2VDb250ZXh0OwppbXBvcnQgb3JnLmVjbGlwc2Uud3N0LmNvbW1vbi5lbnZpcm9ubWVudC5DaG9pY2U7CmltcG9ydCBvcmcuZWNsaXBzZS53c3QuY29tbW9uLmVudmlyb25tZW50LklTdGF0dXNIYW5kbGVyOwppbXBvcnQgb3JnLmVjbGlwc2Uud3N0LmNvbW1vbi5lbnZpcm9ubWVudC5TdGF0dXNFeGNlcHRpb247CgoKCi8qKgoqIFRoaXMgY2xhc3MgY29udGFpbnMgdXNlZnVsIG1ldGhvZHMgZm9yIHdvcmtpbmcgd2l0aCBFY2xpcHNlIHJlc291cmNlcy4KKi8KcHVibGljIGZpbmFsIGNsYXNzIEZpbGVSZXNvdXJjZVV0aWxzCnsKICAvLwogIC8vIEtlZXBzIHRoZSBJV29ya3NwYWNlIGhhbmdpbmcgYXJvdW5kLiBTZWUgZ2V0V29ya3NwYWNlKCkuCiAgLy8KICBwcml2YXRlIHN0YXRpYyBJV29ya3NwYWNlIHdvcmtzcGFjZV8gPSBudWxsOwogIC8vCiAgLy8gS2VlcHMgdGhlIElXb3Jrc3BhY2VSb290IGhhbmdpbmcgYXJvdW5kLiBTZWUgZ2V0V29ya3NwYWNlUm9vdCgpLgogIC8vCiAgcHJpdmF0ZSBzdGF0aWMgSVdvcmtzcGFjZVJvb3Qgcm9vdF8gPSBudWxsOwogIAovLyAgcHJpdmF0ZSBzdGF0aWMgTWVzc2FnZVV0aWxzIG1zZ18gPSBuZXcgTWVzc2FnZVV0aWxzKCAib3JnLmVjbGlwc2Uud3N0LmNvbW1hbmQuaW50ZXJuYWwuZW52LmNvbW1vbi5lbnZpcm9ubWVudCIsIG5ldyBGaWxlUmVzb3VyY2VVdGlscygpICk7CgoKIC8qKgogICogUmV0dXJucyB0aGUgSVdvcmtzcGFjZVJvb3Qgb2JqZWN0LgogICogQHJldHVybiBUaGUgSVdvcmtzcGFjZVJvb3Qgb2JqZWN0LgogICovCiAgcHVibGljIHN0YXRpYyBJV29ya3NwYWNlUm9vdCBnZXRXb3Jrc3BhY2VSb290ICgpCiAgewogICAgaWYgKHJvb3RfID09IG51bGwpCiAgICB7CiAgICAgIHJvb3RfID0gUmVzb3VyY2VzUGx1Z2luLmdldFdvcmtzcGFjZSgpLmdldFJvb3QoKTsKICAgIH0KICAgIHJldHVybiByb290XzsKICB9CgogIC8qKgoJICogUmV0dXJucyB0aGUgSVdvcmtzcGFjZSBvYmplY3QuCgkgKiAKCSAqIEByZXR1cm4gVGhlIElXb3Jrc3BhY2Ugb2JqZWN0LgoJICovCiAgcHVibGljIHN0YXRpYyBJV29ya3NwYWNlIGdldFdvcmtzcGFjZSAoKQogIHsKICAgIGlmICh3b3Jrc3BhY2VfID09IG51bGwpCiAgICB7CiAgICAgIGlmIChyb290XyA9PSBudWxsKQogICAgICB7CiAgICAgICAgcm9vdF8gPSBSZXNvdXJjZXNQbHVnaW4uZ2V0V29ya3NwYWNlKCkuZ2V0Um9vdCgpOwogICAgICB9CiAgICAgIAogICAgICB3b3Jrc3BhY2VfID0gcm9vdF8uZ2V0V29ya3NwYWNlKCk7CiAgICB9CiAgICAKICAgIHJldHVybiB3b3Jrc3BhY2VfOwogIH0KICAKICAvKioKICAgKiAKICAgKiBAcmV0dXJuIHJldHVybnMgYW4gYXJyYXkgb2YgdGhyZWUgY29tbW9uIGNob2ljZXMuIChpZS4gWWVzLCB5ZXMgYWxsLCBhbmQgY2FuY2VsICkKICAgKi8KICBwdWJsaWMgc3RhdGljIENob2ljZVtdIGdldFRocmVlU3RhdGVGaWxlT3B0aW9ucygpIAogIHsKICAgIFZlY3RvciBjaG9pY2VzID0gbmV3IFZlY3RvcigpOwogICAgCiAgICBjaG9pY2VzLmFkZChuZXcgQ2hvaWNlKCAnWScsIEVudmlyb25tZW50TWVzc2FnZXMuTEFCRUxfWUVTKSk7CiAgICBjaG9pY2VzLmFkZChuZXcgQ2hvaWNlKCAnQScsIEVudmlyb25tZW50TWVzc2FnZXMuTEFCRUxfWUVTX1RPX0FMTCkpOwogICAgY2hvaWNlcy5hZGQobmV3IENob2ljZSggJ0MnLCBFbnZpcm9ubWVudE1lc3NhZ2VzLkxBQkVMX0NBTkNFTCkpOwogICAgCiAgICByZXR1cm4gKENob2ljZVtdKWNob2ljZXMudG9BcnJheShuZXcgQ2hvaWNlW2Nob2ljZXMuc2l6ZSgpXSk7CiAgfQogIAogIC8qKgogICogUmV0dXJucyBhbgogICoge0BsaW5rIG9yZy5lY2xpcHNlLmNvcmUucmVzb3VyY2VzLklSZXNvdXJjZSBJUmVzb3VyY2V9CiAgKiBvZiB0aGUgZ2l2ZW4gYWJzb2x1dGUgcGF0aG5hbWUgb3IgbnVsbCBpZiBubyBzdWNoIHJlc291cmNlIGV4aXN0cy4KICAqIEBwYXJhbSBhYnNvbHV0ZVBhdGhuYW1lIFRoZSBhYnNvbHV0ZSBwYXRoIG9mIHRoZSByZXNvdXJjZS4KICAqIEByZXR1cm4gVGhlIDxjb2RlPklSZXNvdXJjZTwvY29kZT4uCiAgKi8KICBwdWJsaWMgc3RhdGljIElSZXNvdXJjZSBmaW5kUmVzb3VyY2UgKCBTdHJpbmcgYWJzb2x1dGVQYXRobmFtZSApCiAgewogICAgaWYgKGFic29sdXRlUGF0aG5hbWUgPT0gbnVsbCkKICAgIHsKICAgICAgcmV0dXJuIG51bGw7CiAgICB9CiAgICAKICAgIHJldHVybiBmaW5kUmVzb3VyY2UobmV3IFBhdGgoYWJzb2x1dGVQYXRobmFtZSkpOwogIH0KCiAgLyoqCiAgKiBSZXR1cm5zIGFuCiAgKiB7QGxpbmsgb3JnLmVjbGlwc2UuY29yZS5yZXNvdXJjZXMuSVJlc291cmNlIElSZXNvdXJjZX0KICAqIG9mIHRoZSBnaXZlbiBhYnNvbHV0ZSBwYXRoIG9yIG51bGwgaWYgbm8gc3VjaCByZXNvdXJjZSBleGlzdHMuCiAgKiBAcGFyYW0gYWJzb2x1dGVQYXRoIFRoZSBhYnNvbHV0ZSA8Y29kZT5JUGF0aDwvY29kZT4gb2YgdGhlIHJlc291cmNlLgogICogQHJldHVybiBUaGUgPGNvZGU+SVJlc291cmNlPC9jb2RlPi4KICAqLwogIHB1YmxpYyBzdGF0aWMgSVJlc291cmNlIGZpbmRSZXNvdXJjZSAoIElQYXRoIGFic29sdXRlUGF0aCApCiAgewogICAgaWYgKGFic29sdXRlUGF0aCA9PSBudWxsKQogICAgewogICAgICByZXR1cm4gbnVsbDsKICAgIH0KICAgIAogICAgcmV0dXJuIEZpbGVSZXNvdXJjZVV0aWxzLmdldFdvcmtzcGFjZVJvb3QoKS5maW5kTWVtYmVyKGFic29sdXRlUGF0aCk7CiAgfQogIAogIC8qKgogICAqIENvcGllcyBhIGZpbGUgZnJvbSBhIHBsdWdpbidzIGluc3RhbGxhdGlvbiBsb2NhdGlvbgogICAqIHRvIGFuIEVjbGlwc2UgZm9sZGVyLgogICAqIEBwYXJhbSBwbHVnaW4gVGhlIHBsdWdpbiBjb250YWluaW5nIHRoZSBmaWxlcyB0byBjb3B5LgogICAqIE11c3Qgbm90IGJlIG51bGwuCiAgICogQHBhcmFtIHNvdXJjZVBhdGggVGhlIHBhdGgsIHJlbGF0aXZlIHRvIHRoZSA8Y29kZT5wbHVnaW48L2NvZGU+CiAgICogaW5zdGFsbCBsb2NhdGlvbiwgY29udGFpbmluZyB0aGUgZmlsZXMgdG8gY29weS4KICAgKiBJZiBudWxsLCB0aGVuIHRoZSBwbHVnaW4gaW5zdGFsbCBsb2NhdGlvbiBpcyB0aGUgc291cmNlIHBhdGgKICAgKiAoaWUuIG51bGwgaXMgZXF1aXZhbGVudCB0byAiLiIpLgogICAqIEBwYXJhbSBwYXRobmFtZSBUaGUgcGF0aG5hbWUgb2YgdGhlIGZpbGUgdG8gY29weS4KICAgKiBUaGUgcGF0aG5hbWUgaXMgcmVsYXRpdmUgdG8gdGhlIDxjb2RlPnBsdWdpbiBzb3VyY2VQYXRoPC9jb2RlPi4KICAgKiBNdXN0IG5vdCBiZSBudWxsLgogICAqIEBwYXJhbSB0YXJnZXRQYXRoIFRoZSBhYnNvbHV0ZSBFY2xpcHNlIHBhdGggb2YgdGhlIGZvbGRlciB0bwogICAqIHdoaWNoIHRoZSBmaWxlIHdpbGwgYmUgY29waWVkLiBUaGUgcmVsYXRpdmUgcGF0aG5hbWUgb2YgdGhlCiAgICogZmlsZSBpcyBwcmVzZXJ2ZWQuCiAgICogTXVzdCBub3QgYmUgbnVsbC4KICAgKiBAcGFyYW0gY3JlYXRlRm9sZGVycyBUaGUgaW50ZXJtZWRpYXRlIGZvbGRlciBjcmVhdGlvbiBwb2xpY3ksIG9uZSBvZgogICAqIHtAbGluayAjQ1JFQVRFIENSRUFURX0gb3Ige0BsaW5rICNET05UX0NSRUFURSBET05UX0NSRUFURX0uCiAgICogPHVsPgogICAqIDxsaT48Y29kZT5DUkVBVEU8L2NvZGU+IC0KICAgKiBJZiBhbnkgaW50ZXJtZWRpYXRlIGZvbGRlcnMgaW4gdGhlIGdpdmVuIDxjb2RlPmFic29sdXRlUGF0aDwvY29kZT4KICAgKiBkbyBub3QgZXhpc3QsIHRoZXkgd2lsbCBiZSBjcmVhdGVkLgogICAqIDxsaT48Y29kZT5ET05UX0NSRUFURTwvY29kZT4gLQogICAqIElmIGFueSBpbnRlcm1lZGlhdGUgZm9sZGVycyBpbiB0aGUgZ2l2ZW4gPGNvZGU+YWJzb2x1dGVQYXRoPC9jb2RlPgogICAqIGRvIG5vdCBleGlzdCwgdGhlIG1ldGhvZCB3aWxsIHRocm93IGEgPGNvZGU+Q29yZUV4Y2VwdGlvbjwvY29kZT4uCiAgICogPC91bD4KICAgKiBAcGFyYW0gb3ZlcndyaXRlRmlsZSBUaGUgcG9saWN5IGZvciBleGlzdGluZyBmaWxlcywgb25lIG9mCiAgICoge0BsaW5rICNPVkVSV1JJVEUgT1ZFUldSSVRFfSBvciB7QGxpbmsgI0RPTlRfT1ZFUldSSVRFIERPTlRfT1ZFUldSSVRFfS4KICAgKiA8dWw+CiAgICogPGxpPjxjb2RlPk9WRVJXUklURTwvY29kZT4gLQogICAqIElmIGEgcmVzb3VyY2Ugb2YgdGhlIHNhbWUgbmFtZSBhcyB0aGUgZ2l2ZW4KICAgKiA8Y29kZT5hYnNvbHV0ZVBhdGg8L2NvZGU+IGFscmVhZHkgZXhpc3RzIGFuZCBpcyBhIGZpbGUsCiAgICogaXQgd2lsbCBiZSByZXBsYWNlZC4KICAgKiBJZiB0aGUgcmVzb3VyY2UgYWxyZWFkeSBleGlzdHMgYW5kIGl0IGlzIG5vdCBhIGZpbGUsCiAgICogdGhlbiBubyBmaWxlIHdpbGwgYmUgY3JlYXRlZCBhbmQKICAgKiBhIDxjb2RlPkNvcmVFeGNlcHRpb248L2NvZGU+IHdpbGwgYmUgdGhyb3duLgogICAqIDxsaT48Y29kZT5ET05UX09WRVJXUklURTwvY29kZT4gLQogICAqIElmIGFueSByZXNvdXJjZSBvZiB0aGUgc2FtZSBuYW1lIGFzIHRoZSBnaXZlbgogICAqIDxjb2RlPmFic29sdXRlUGF0aDwvY29kZT4gYWxyZWFkeSBleGlzdHMsCiAgICogdGhlbiBubyBmaWxlIHdpbGwgYmUgY3JlYXRlZCBhbmQKICAgKiBhIDxjb2RlPkNvcmVFeGNlcHRpb248L2NvZGU+IHdpbGwgYmUgdGhyb3duLgogICAqIDwvdWw+CiAgICogQHBhcmFtIHByb2dyZXNzTW9uaXRvciBUaGUgcHJvZ3Jlc3MgbW9uaXRvciBmb3IgdGhlIG9wZXJhdGlvbiwgb3IgbnVsbC4KICAgKiBAdGhyb3dzIENvcmVFeGNlcHRpb24gQW4gZXhjZXB0aW9uIGNvbnRhaW5pbmcgYW4KICAgKiB7QGxpbmsgb3JnLmVjbGlwc2UuY29yZS5ydW50aW1lLklTdGF0dXMgSVN0YXR1c30KICAgKiB3aXRoIGEgc2V2ZXJpdHkgb2YgPGNvZGU+SVN0YXR1cy5FUlJPUjwvY29kZT4gYW5kIGEKICAgKiBsb2NhbGUtc3BlY2lmaWMgZGVzY3JpcHRpb24gb2YgdGhlIGNhdXNlLgogICAqLwogICBzdGF0aWMgcHVibGljIHZvaWQgY29weUZpbGUoIFJlc291cmNlQ29udGV4dCByZXNvdXJjZUNvbnRleHQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgUGx1Z2luIHBsdWdpbiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBJUGF0aCBzb3VyY2VQYXRoLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIElQYXRoIHBhdGhuYW1lLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIElQYXRoIHRhcmdldFBhdGgsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgSVByb2dyZXNzTW9uaXRvciBwcm9ncmVzc01vbml0b3IsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgSVN0YXR1c0hhbmRsZXIgc3RhdHVzTW9uaXRvciApCiAgICAgdGhyb3dzIENvcmVFeGNlcHRpb24KICAgewogICAgIHRyeQogICAgIHsKICAgICAgIElQYXRoIHRhcmdldCA9IHRhcmdldFBhdGguYXBwZW5kKHBhdGhuYW1lKTsKICAgICAgIElQYXRoIHNvdXJjZSA9IHNvdXJjZVBhdGggPT0gbnVsbCA/IHBhdGhuYW1lIDogc291cmNlUGF0aC5hcHBlbmQocGF0aG5hbWUpOwogICAgICAgSW5wdXRTdHJlYW0gaW5wdXQgPSBwbHVnaW4ub3BlblN0cmVhbShzb3VyY2UpOwogICAgICAgY3JlYXRlRmlsZShyZXNvdXJjZUNvbnRleHQsIHRhcmdldCwgaW5wdXQsIHByb2dyZXNzTW9uaXRvciwgc3RhdHVzTW9uaXRvcik7CiAgICAgfQogICAgIGNhdGNoIChJT0V4Y2VwdGlvbiBlKQogICAgIHsKICAgICAgIHRocm93IG5ldyBDb3JlRXhjZXB0aW9uKG5ldyBTdGF0dXMoSVN0YXR1cy5FUlJPUiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBsdWdpbi5nZXRCdW5kbGUoKS5nZXRTeW1ib2xpY05hbWUoKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDAsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBFbnZpcm9ubWVudE1lc3NhZ2VzLk1TR19FUlJPUl9JTyxlKSk7CiAgICAgfQogICB9CiAgIAogIC8qKgogICAqIERlbGV0ZXMgYSBmaWxlIHVuZGVyIGEgY29udGFpbmVyLgogICAqIFRoZSBjb250YWluZXIgbXVzdCBhbHJlYWR5IGV4aXN0LgogICAqIEBwYXJhbSBmaWxlIC0gdGhlIElGaWxlIHRvIGJlIGRlbGV0ZWQKICAgKiBAcGFyYW0gcHJvZ3Jlc3NNb25pdG9yCiAgICogQHBhcmFtIHN0YXR1c01vbml0b3IKICAgKiBAcmV0dXJuIFRydWUgaWYgdGhlIGZpbGUgZG9lcyBub3QgZXhpc3Qgb3IgaWYgaXQgZXhpc3RzIGFuZCBpcyBzdWNjZXNzZnVsbHkgZGVsZXRlZC4gRmFsc2Ugb3RoZXJ3aXNlLgogICAqLwogIHB1YmxpYyBzdGF0aWMgYm9vbGVhbiBkZWxldGVGaWxlKCBSZXNvdXJjZUNvbnRleHQgcmVzb3VyY2VDb250ZXh0LCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgSUZpbGUgZmlsZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgSVByb2dyZXNzTW9uaXRvciBwcm9ncmVzc01vbml0b3IsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBJU3RhdHVzSGFuZGxlciBzdGF0dXNNb25pdG9yKQogICAgdGhyb3dzIENvcmVFeGNlcHRpb24KICB7CiAgICBpZiAoZmlsZS5leGlzdHMoKSkKICAgIHsKICAgICAgaWYgKCFyZXNvdXJjZUNvbnRleHQuaXNPdmVyd3JpdGVGaWxlc0VuYWJsZWQoKSkKICAgICAgewogICAgICAgIElTdGF0dXMgc3RhdHVzIAogICAgICAgICAgPSBTdGF0dXNVdGlscy53YXJuaW5nU3RhdHVzKCBOTFMuYmluZChFbnZpcm9ubWVudE1lc3NhZ2VzLk1TR19FUlJPUl9GSUxFX09WRVJXUklURV9ESVNBQkxFRCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBuZXcgT2JqZWN0W117IGZpbGUuZ2V0UGFyZW50KCkuZ2V0RnVsbFBhdGgoKS50b1N0cmluZygpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZmlsZS5nZXROYW1lKCl9KSApOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgCiAgICAgICAgQ2hvaWNlIGNob2ljZSA9IHN0YXR1c01vbml0b3IucmVwb3J0KCBzdGF0dXMsIGdldFRocmVlU3RhdGVGaWxlT3B0aW9ucygpICk7CiAgICAgICAgCiAgICAgICAgaWYoIGNob2ljZS5nZXRTaG9ydGN1dCgpID09ICdDJyApIHJldHVybiBmYWxzZTsKICAgICAgICAKICAgICAgICBpZiggY2hvaWNlLmdldFNob3J0Y3V0KCkgPT0gJ0EnICkgcmVzb3VyY2VDb250ZXh0LnNldE92ZXJ3cml0ZUZpbGVzRW5hYmxlZCh0cnVlKTsKICAgICAgfQogICAgICAKICAgICAgLy9XZSBoYXZlIHBlcm1pc3Npb24gdG8gb3ZlcndyaXRlIHNvIGNoZWNrIGlmIGZpbGUgaXMgcmVhZC1vbmx5CiAgICAgIGlmIChmaWxlLmlzUmVhZE9ubHkoKSkKICAgICAgewogICAgICAgIGlmICghcmVzb3VyY2VDb250ZXh0LmlzQ2hlY2tvdXRGaWxlc0VuYWJsZWQoKSkKICAgICAgICB7CiAgICAgICAgICBJU3RhdHVzIHN0YXR1cyAKICAgICAgICAgICAgPSBTdGF0dXNVdGlscy53YXJuaW5nU3RhdHVzKCBOTFMuYmluZChFbnZpcm9ubWVudE1lc3NhZ2VzLk1TR19FUlJPUl9GSUxFX0NIRUNLT1VUX0RJU0FCTEVELAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbmV3IE9iamVjdFtdeyBmaWxlLmdldFBhcmVudCgpLmdldEZ1bGxQYXRoKCkudG9TdHJpbmcoKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZmlsZS5nZXROYW1lKCl9KSApOwogICAgICAgICAgCiAgICAgICAgICBDaG9pY2UgY2hvaWNlID0gc3RhdHVzTW9uaXRvci5yZXBvcnQoIHN0YXR1cywgZ2V0VGhyZWVTdGF0ZUZpbGVPcHRpb25zKCkgKTsKICAgICAgICAgIAogICAgICAgICAgaWYoIGNob2ljZS5nZXRTaG9ydGN1dCgpID09ICdDJyApIHJldHVybiBmYWxzZTsKICAgICAgICAgIAogICAgICAgICAgaWYoIGNob2ljZS5nZXRTaG9ydGN1dCgpID09ICdBJyApIHJlc291cmNlQ29udGV4dC5zZXRDaGVja291dEZpbGVzRW5hYmxlZCh0cnVlKTsgICAgICAgICAgCiAgICAgICAgfQogICAgICAgIAogICAgICAgIElGaWxlW10gZmlsZXMgPSBuZXcgSUZpbGVbMV07CiAgICAgICAgZmlsZXNbMF0gPSBmaWxlOwogICAgICAgIElTdGF0dXMgc3RhdHVzID0gZ2V0V29ya3NwYWNlKCkudmFsaWRhdGVFZGl0KGZpbGVzLCBudWxsKTsKICAgICAgICAKICAgICAgICBpZiggc3RhdHVzLmdldFNldmVyaXR5KCkgPT0gSVN0YXR1cy5FUlJPUiApCiAgICAgICAgewogICAgICAgICAgc3RhdHVzTW9uaXRvci5yZXBvcnRFcnJvciggc3RhdHVzICk7CiAgICAgICAgICByZXR1cm4gZmFsc2U7CiAgICAgICAgfQogICAgICB9CiAgICAgIAogICAgICBmaWxlLmRlbGV0ZSh0cnVlLCBudWxsKTsKICAgIH0KICAgIC8vQXQgdGhpcyBwb2ludCwgZWl0aGVyIHRoZSBmaWxlIGRpZCBub3QgZXhpc3Qgb3Igd2Ugc3VjY2Vzc2Z1bGx5IGRlbGV0ZWQKICAgIC8vIGl0LiBSZXR1cm4gc3VjY2Vzcy4KICAgIHJldHVybiB0cnVlOwogIH0KCiAgLyoqCiAgICogRGVsZXRlcyBhIGZvbGRlciB1bmRlciBhIGNvbnRhaW5lci4KICAgKiBAcGFyYW0gZm9sZGVyIC0gdGhlIElGb2xkZXIgdG8gYmUgZGVsZXRlZAogICAqIEBwYXJhbSBwcm9ncmVzc01vbml0b3IKICAgKiBAcGFyYW0gc3RhdHVzTW9uaXRvcgogICAqIEByZXR1cm4gVHJ1ZSBpZiB0aGUgZm9sZGVyIGRvZXMgbm90IGV4aXN0IG9yIGlmIGl0IGV4aXN0cyBhbmQgaXMgc3VjY2Vzc2Z1bGx5IGRlbGV0ZWQgYWxvbmcgd2l0aCBpdHMgbWVtYmVycy4gRmFsc2Ugb3RoZXJ3aXNlLgogICAqLwogICBwdWJsaWMgc3RhdGljIGJvb2xlYW4gZGVsZXRlRm9sZGVyKCBSZXNvdXJjZUNvbnRleHQgcmVzb3VyY2VDb250ZXh0LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBJRm9sZGVyIGZvbGRlciwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgSVByb2dyZXNzTW9uaXRvciBwcm9ncmVzc01vbml0b3IsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIElTdGF0dXNIYW5kbGVyIHN0YXR1c01vbml0b3IgKQogICAgIHRocm93cyBDb3JlRXhjZXB0aW9uCiAgIHsKICAgICBpZiAoIWZvbGRlci5leGlzdHMoKSkgcmV0dXJuIHRydWU7CgogICAgIGJvb2xlYW4gICAgIGRlbGV0ZWQgICA9IHRydWU7CiAgICAgSVJlc291cmNlW10gcmVzb3VyY2VzID0gZm9sZGVyLm1lbWJlcnMoKTsKICAgICAKICAgICBmb3IgKGludCBpPTA7IGk8cmVzb3VyY2VzLmxlbmd0aDsgaSsrKQogICAgIHsKICAgICAgIElSZXNvdXJjZSByZXNvdXJjZSA9IHJlc291cmNlc1tpXTsKICAgICAgIGlmIChyZXNvdXJjZSBpbnN0YW5jZW9mIElGaWxlKQogICAgICAgewogICAgICAgICBkZWxldGVkID0gZGVsZXRlRmlsZShyZXNvdXJjZUNvbnRleHQsIChJRmlsZSlyZXNvdXJjZSwgcHJvZ3Jlc3NNb25pdG9yLCBzdGF0dXNNb25pdG9yKTsKICAgICAgIH0KICAgICAgIGlmIChyZXNvdXJjZSBpbnN0YW5jZW9mIElGb2xkZXIpCiAgICAgICB7CiAgICAgICAgIGRlbGV0ZWQgPSBkZWxldGVGb2xkZXIoIHJlc291cmNlQ29udGV4dCwgKElGb2xkZXIpcmVzb3VyY2UsIHByb2dyZXNzTW9uaXRvciwgc3RhdHVzTW9uaXRvcik7CiAgICAgICB9CgogICAgICAgaWYoICFkZWxldGVkICkgYnJlYWs7CiAgICAgfQogICAgIAogICAgIGlmKCBkZWxldGVkICkKICAgICB7CiAgICAgICBmb2xkZXIuZGVsZXRlKHRydWUsIHRydWUsIG51bGwpOwogICAgICAgcmV0dXJuIHRydWU7CiAgICAgfQogICAgIGVsc2UKICAgICAgIHJldHVybiBmYWxzZTsKICAgfQoKICAvKioKICAqIENyZWF0ZXMgYSBmaWxlIG9mIHRoZSBnaXZlbiA8Y29kZT5hYnNvbHV0ZVBhdGg8L2NvZGU+CiAgKiBhbmQgcmV0dXJucyBpdHMgaGFuZGxlIGFzIGFuIDxjb2RlPklGaWxlPC9jb2RlPi4KICAqIElmIHRoZSBmaWxlIGNhbm5vdCBiZSBjcmVhdGVkLCBhCiAgKiA8Y29kZT5Db3JlRXhjZXB0aW9uPC9jb2RlPiBjb250YWluaW5nIGFuCiAgKiA8Y29kZT5JU3RhdHVzPC9jb2RlPiBvYmplY3QgaXMgdGhyb3duLgogICogQHBhcmFtIGFic29sdXRlUGF0aCBUaGUgYWJzb2x1dGUgcGF0aCBvZiB0aGUgZmlsZSB0byBjcmVhdGUuCiAgKiBUaGUgcHJvamVjdCBhdCB0aGUgYmVnaW5uaW5nIG9mIHRoZSBwYXRoIG11c3QgYWxyZWFkeSBleGlzdCwKICAqIHRoYXQgaXMsIHRoaXMgbWV0aG9kIGNhbm5vdCBiZSB1c2VkIHRvIGNyZWF0ZSBwcm9qZWN0cy4KICAqIEBwYXJhbSBwcm9ncmVzc01vbml0b3IgVGhlIHByb2dyZXNzIG1vbml0b3IgZm9yIHRoZSBvcGVyYXRpb24sIG9yIG51bGwuCiAgKiBAcmV0dXJuIFRoZSB7QGxpbmsgb3JnLmVjbGlwc2UuY29yZS5yZXNvdXJjZXMuSUZpbGUgSUZpbGV9CiAgKiBoYW5kbGUgb2YgdGhlIGZpbGUuCiAgKiBAdGhyb3dzIENvcmVFeGNlcHRpb24gQW4gZXhjZXB0aW9uIGNvbnRhaW5pbmcgYW4KICAqIHtAbGluayBvcmcuZWNsaXBzZS5jb3JlLnJ1bnRpbWUuSVN0YXR1cyBJU3RhdHVzfQogICogd2l0aCBhIHNldmVyaXR5IG9mIDxjb2RlPklTdGF0dXMuRVJST1I8L2NvZGU+IGFuZCBhCiAgKiBsb2NhbGUtc3BlY2lmaWMgZGVzY3JpcHRpb24gb2YgdGhlIGNhdXNlLgogICovCiAgcHVibGljIHN0YXRpYyBJRmlsZSBjcmVhdGVGaWxlICgKICAgIFJlc291cmNlQ29udGV4dCByZXNvdXJjZUNvbnRleHQsCiAgICBJUGF0aCAgICAgICAgICAgYWJzb2x1dGVQYXRoLAogICAgSW5wdXRTdHJlYW0gICAgIGlucHV0U3RyZWFtLAogICAgSVByb2dyZXNzTW9uaXRvciBwcm9ncmVzc01vbml0b3IsCiAgICBJU3RhdHVzSGFuZGxlciAgIHN0YXR1c0hhbmRsZXIgKQoKICAgIHRocm93cyBDb3JlRXhjZXB0aW9uIAogIHsgICAgCiAgICBpZiAoIWFic29sdXRlUGF0aC5pc0Fic29sdXRlKCkpCiAgICB7CiAgICAgIHRocm93IG5ldyBDb3JlRXhjZXB0aW9uKG5ldyBTdGF0dXMoSVN0YXR1cy5FUlJPUiwgIlJlc291cmNlVXRpbHMiLDAsTkxTLmJpbmQoRW52aXJvbm1lbnRNZXNzYWdlcy5NU0dfRVJST1JfUEFUSF9OT1RfQUJTT0xVVEUsbmV3IE9iamVjdFtdIHthYnNvbHV0ZVBhdGgudG9TdHJpbmcoKX0pLG51bGwpKTsKICAgIH0KICAgIGlmIChhYnNvbHV0ZVBhdGguc2VnbWVudENvdW50KCkgPCAxKQogICAgewogICAgICB0aHJvdyBuZXcgQ29yZUV4Y2VwdGlvbihuZXcgU3RhdHVzKElTdGF0dXMuRVJST1IsIlJlc291cmNlVXRpbHMiLDAsTkxTLmJpbmQoRW52aXJvbm1lbnRNZXNzYWdlcy5NU0dfRVJST1JfUEFUSF9FTVBUWSxuZXcgT2JqZWN0W10ge2Fic29sdXRlUGF0aC50b1N0cmluZygpfSksbnVsbCkpOwogICAgfQogICAgaWYgKGFic29sdXRlUGF0aC5zZWdtZW50Q291bnQoKSA8IDIpCiAgICB7CiAgICAgIHRocm93IG5ldyBDb3JlRXhjZXB0aW9uKG5ldyBTdGF0dXMoSVN0YXR1cy5FUlJPUiwiUmVzb3VyY2VVdGlscyIsMCxOTFMuYmluZChFbnZpcm9ubWVudE1lc3NhZ2VzLk1TR19FUlJPUl9QQVRIX05PVF9GT0xERVIsbmV3IE9iamVjdFtdIHthYnNvbHV0ZVBhdGgudG9TdHJpbmcoKX0pLG51bGwpKTsKICAgIH0KICAgIElDb250YWluZXIgcGFyZW50ICAgPSBtYWtlRm9sZGVyUGF0aChyZXNvdXJjZUNvbnRleHQsIGFic29sdXRlUGF0aC5yZW1vdmVMYXN0U2VnbWVudHMoMSksIHByb2dyZXNzTW9uaXRvciwgc3RhdHVzSGFuZGxlcik7CiAgICBTdHJpbmcgICAgIGZpbGVOYW1lID0gYWJzb2x1dGVQYXRoLmxhc3RTZWdtZW50KCk7CiAgICAKICAgIHJldHVybiBtYWtlRmlsZShyZXNvdXJjZUNvbnRleHQsIHBhcmVudCwgZmlsZU5hbWUsIGlucHV0U3RyZWFtLCBwcm9ncmVzc01vbml0b3IsIHN0YXR1c0hhbmRsZXIpOwogIH0KCiAgLyoqCiAgKiBDcmVhdGVzIHVuZGVyIHRoZSBnaXZlbiA8Y29kZT5wcm9qZWN0PC9jb2RlPgogICogYSBmaWxlIG9mIHRoZSBnaXZlbiA8Y29kZT5yZWxhdGl2ZVBhdGg8L2NvZGU+CiAgKiBhbmQgcmV0dXJucyBpdHMgaGFuZGxlIGFzIGFuIDxjb2RlPklGaWxlPC9jb2RlPi4KICAqIElmIHRoZSBmaWxlIGNhbm5vdCBiZSBjcmVhdGVkLCBhCiAgKiA8Y29kZT5Db3JlRXhjZXB0aW9uPC9jb2RlPiBjb250YWluaW5nIGFuCiAgKiA8Y29kZT5JU3RhdHVzPC9jb2RlPiBvYmplY3QgaXMgdGhyb3duLgogICogQHBhcmFtIGFic29sdXRlUGF0aCBUaGUgYWJzb2x1dGUgcGF0aCBvZiB0aGUgZmlsZSB0byBjcmVhdGUuCiAgKiBUaGUgcHJvamVjdCBhdCB0aGUgYmVnaW5uaW5nIG9mIHRoZSBwYXRoIG11c3QgYWxyZWFkeSBleGlzdCwKICAqIHRoYXQgaXMsIHRoaXMgbWV0aG9kIGNhbm5vdCBiZSB1c2VkIHRvIGNyZWF0ZSBwcm9qZWN0cy4KICAqIEBwYXJhbSBjcmVhdGVGb2xkZXJzIFRoZSBpbnRlcm1lZGlhdGUgZm9sZGVyIGNyZWF0aW9uIHBvbGljeSwgb25lIG9mCiAgKiB7QGxpbmsgI0NSRUFURSBDUkVBVEV9IG9yIHtAbGluayAjRE9OVF9DUkVBVEUgRE9OVF9DUkVBVEV9LgogICogPHVsPgogICogPGxpPjxjb2RlPkNSRUFURTwvY29kZT4gLQogICogSWYgYW55IGludGVybWVkaWF0ZSBmb2xkZXJzIGluIHRoZSBnaXZlbiA8Y29kZT5hYnNvbHV0ZVBhdGg8L2NvZGU+CiAgKiBkbyBub3QgZXhpc3QsIHRoZXkgd2lsbCBiZSBjcmVhdGVkLgogICogPGxpPjxjb2RlPkRPTlRfQ1JFQVRFPC9jb2RlPiAtCiAgKiBJZiBhbnkgaW50ZXJtZWRpYXRlIGZvbGRlcnMgaW4gdGhlIGdpdmVuIDxjb2RlPmFic29sdXRlUGF0aDwvY29kZT4KICAqIGRvIG5vdCBleGlzdCwgdGhlIG1ldGhvZCB3aWxsIHRocm93IGEgPGNvZGU+Q29yZUV4Y2VwdGlvbjwvY29kZT4uCiAgKiA8L3VsPgogICogQHBhcmFtIG92ZXJ3cml0ZUZpbGUgVGhlIHBvbGljeSBmb3IgZXhpc3RpbmcgZmlsZXMsIG9uZSBvZgogICoge0BsaW5rICNPVkVSV1JJVEUgT1ZFUldSSVRFfSBvciB7QGxpbmsgI0RPTlRfT1ZFUldSSVRFIERPTlRfT1ZFUldSSVRFfS4KICAqIDx1bD4KICAqIDxsaT48Y29kZT5PVkVSV1JJVEU8L2NvZGU+IC0KICAqIElmIGEgcmVzb3VyY2Ugb2YgdGhlIHNhbWUgbmFtZSBhcyB0aGUgZ2l2ZW4KICAqIDxjb2RlPmFic29sdXRlUGF0aDwvY29kZT4gYWxyZWFkeSBleGlzdHMgYW5kIGlzIGEgZmlsZSwKICAqIGl0IHdpbGwgYmUgcmVwbGFjZWQuCiAgKiBJZiB0aGUgcmVzb3VyY2UgYWxyZWFkeSBleGlzdHMgYW5kIGl0IGlzIG5vdCBhIGZpbGUsCiAgKiB0aGVuIG5vIGZpbGUgd2lsbCBiZSBjcmVhdGVkIGFuZAogICogYSA8Y29kZT5Db3JlRXhjZXB0aW9uPC9jb2RlPiB3aWxsIGJlIHRocm93bi4KICAqIDxsaT48Y29kZT5ET05UX09WRVJXUklURTwvY29kZT4gLQogICogSWYgYW55IHJlc291cmNlIG9mIHRoZSBzYW1lIG5hbWUgYXMgdGhlIGdpdmVuCiAgKiA8Y29kZT5hYnNvbHV0ZVBhdGg8L2NvZGU+IGFscmVhZHkgZXhpc3RzLAogICogdGhlbiBubyBmaWxlIHdpbGwgYmUgY3JlYXRlZCBhbmQKICAqIGEgPGNvZGU+Q29yZUV4Y2VwdGlvbjwvY29kZT4gd2lsbCBiZSB0aHJvd24uCiAgKiA8L3VsPgogICogQHBhcmFtIHByb2dyZXNzTW9uaXRvciBUaGUgcHJvZ3Jlc3MgbW9uaXRvciBmb3IgdGhlIG9wZXJhdGlvbiwgb3IgbnVsbC4KICAqIEByZXR1cm4gVGhlIHtAbGluayBvcmcuZWNsaXBzZS5jb3JlLnJlc291cmNlcy5JRmlsZSBJRmlsZX0KICAqIGhhbmRsZSBvZiB0aGUgZmlsZS4KICAqIEB0aHJvd3MgQ29yZUV4Y2VwdGlvbiBBbiBleGNlcHRpb24gY29udGFpbmluZyBhbgogICoge0BsaW5rIG9yZy5lY2xpcHNlLmNvcmUucnVudGltZS5JU3RhdHVzIElTdGF0dXN9CiAgKiB3aXRoIGEgc2V2ZXJpdHkgb2YgPGNvZGU+SVN0YXR1cy5FUlJPUjwvY29kZT4gYW5kIGEKICAqIGxvY2FsZS1zcGVjaWZpYyBkZXNjcmlwdGlvbiBvZiB0aGUgY2F1c2UuCiAgKi8KICBwdWJsaWMgc3RhdGljIElGaWxlIGNyZWF0ZUZpbGUgKAogICAgUmVzb3VyY2VDb250ZXh0IHJlc291cmNlQ29udGV4dCwKICAgIElQcm9qZWN0ICAgICAgICBwcm9qZWN0LAogICAgSVBhdGggICAgICAgICAgIHJlbGF0aXZlUGF0aCwKICAgIElucHV0U3RyZWFtICAgICBpbnB1dFN0cmVhbSwKICAgIElQcm9ncmVzc01vbml0b3IgcHJvZ3Jlc3NNb25pdG9yLAogICAgSVN0YXR1c0hhbmRsZXIgICBzdGF0dXNNb25pdG9yICkKIAogICAgdGhyb3dzIENvcmVFeGNlcHRpb24gCiAgewogICAgSVBhdGggYWJzb2x1dGVQYXRoID0gcHJvamVjdC5nZXRGdWxsUGF0aCgpLmFwcGVuZChyZWxhdGl2ZVBhdGgpOwogICAgcmV0dXJuIGNyZWF0ZUZpbGUocmVzb3VyY2VDb250ZXh0LCBhYnNvbHV0ZVBhdGgsIGlucHV0U3RyZWFtLCBwcm9ncmVzc01vbml0b3IsIHN0YXR1c01vbml0b3IpOwogIH0KCiAgLyoqCiAgKiBDcmVhdGVzIGFuIG91dHB1dCBzdHJlYW0gdGhhdCBjYW4gYmUgdXNlZCB0byB3cml0ZSB0byB0aGUKICAqIGdpdmVuIDxjb2RlPmZpbGU8L2NvZGU+LiBBY3R1YWwgY2hhbmdlcyB0byB0aGUgd29ya3NwYWNlCiAgKiBtYXkgb2NjdXIgZHVyaW5nIGNyZWF0aW9uIG9mIHRoZSBzdHJlYW0sIHdoaWxlIHdyaXRpbmcgdG8KICAqIHRoZSBzdHJlYW0sIG9yIHdoZW4gdGhlIHN0cmVhbSBpcyBjbG9zZWQuCiAgKiBBIDxjb2RlPkNvcmVFeGNlcHRpb248L2NvZGU+IGNvbnRhaW5pbmcKICAqIGFuIDxjb2RlPklTdGF0dXM8L2NvZGU+IHdpbGwgYmUgdGhyb3duCiAgKiBhdCBzb21lIHBvaW50IGluIHRoZSBsaWZlY3ljbGUgb2YgdGhlIHN0cmVhbQogICogaWYgdGhlIGZpbGUgcmVzb3VyY2UgY2Fubm90IGJlIGNyZWF0ZWQuCiAgKiBAcGFyYW0gZmlsZSBUaGUge0BsaW5rIG9yZy5lY2xpcHNlLmNvcmUucmVzb3VyY2VzLklGaWxlIElGaWxlfQogICogaGFuZGxlIG9mIHRoZSBmaWxlIHJlc291cmNlIHRvIGNyZWF0ZS4gVGhlIHByb2plY3QgaW1wbGllZCBieSB0aGUKICAqIHBhdGhuYW1lIG9mIHRoZSBmaWxlIG11c3QgYWxyZWFkeSBleGlzdCwKICAqIHRoYXQgaXMsIHRoaXMgbWV0aG9kIGNhbm5vdCBiZSB1c2VkIHRvIGNyZWF0ZSBwcm9qZWN0cy4KICAqIEBwYXJhbSBwcm9ncmVzc01vbml0b3IgVGhlIHByb2dyZXNzIG1vbml0b3IgZm9yIHRoZSBvcGVyYXRpb24sIG9yIG51bGwuCiAgKiBAcmV0dXJuIEFuIDxjb2RlPk91dHB1dFN0cmVhbTwvY29kZT4gdGllZCB0byB0aGUgZmlsZSByZXNvdXJjZS4KICAqIEFjdHVhbCBjaGVja3Mgb2Ygb3IgY2hhbmdlcyB0byB0aGUgd29ya3NwYWNlIG1heSBvY2N1ciBhcyBlYXJseSBkdXJpbmcKICAqIHN0cmVhbSBjcmVhdGlvbiwgY2xvc3VyZSwgb3IgYW55IHRpbWUgaW4gYmV0d2Vlbi4KICAqIEB0aHJvd3MgQ29yZUV4Y2VwdGlvbiBBbiBleGNlcHRpb24gY29udGFpbmluZyBhbgogICoge0BsaW5rIG9yZy5lY2xpcHNlLmNvcmUucnVudGltZS5JU3RhdHVzIElTdGF0dXN9CiAgKiB3aXRoIGEgc2V2ZXJpdHkgb2YgPGNvZGU+SVN0YXR1cy5FUlJPUjwvY29kZT4gYW5kIGEKICAqIGxvY2FsZS1zcGVjaWZpYyBkZXNjcmlwdGlvbiBvZiB0aGUgY2F1c2UuCiAgKiBSZWFzb25zIGluY2x1ZGU6CiAgKiA8b2w+CiAgKiA8bGk+VGhlIHByb2plY3Qgb2YgdGhlIGdpdmVuIGZpbGUncyBwYXRoIGRvZXMgbm90IGV4aXN0LgogICogPGxpPkEgbm9uLWZpbGUgcmVzb3VyY2Ugb2YgdGhlIHNhbWUgbmFtZSBvZiB0aGUgZ2l2ZW4gZmlsZQogICogYWxyZWFkeSBleGlzdHMuCiAgKiA8bGk+QSBmaWxlIHJlc291cmNlIG9mIHRoZSBzYW1lIG5hbWUgb2YgdGhlIGdpdmVuIGZpbGUKICAqIGFscmVhZHkgZXhpc3RzLCBhbmQgPGNvZGU+b3ZlcndyaXRlRmlsZTwvY29kZT4gaXMgZmFsc2UuCiAgKiA8bGk+T25lIG9yIG1vcmUgaW50ZXJtZWRpYXRlIGZvbGRlcnMgdG8gdGhlIGdpdmVuIGZpbGUKICAqIGRvIG5vdCBleGlzdCwgYW5kIDxjb2RlPmNyZWF0ZUZvbGRlcnM8L2NvZGU+IGlzIGZhbHNlLgogICogPC9vbD4KICAqLwoKICBwdWJsaWMgc3RhdGljIE91dHB1dFN0cmVhbSBuZXdGaWxlT3V0cHV0U3RyZWFtICgKICAgICAgIFJlc291cmNlQ29udGV4dCAgY29udGV4dCwKICAgICAgIElQYXRoICAgICAgICAgICAgZmlsZSwKICAgICAgIElQcm9ncmVzc01vbml0b3IgcHJvZ3Jlc3NNb25pdG9yLAogICAgICAgSVN0YXR1c0hhbmRsZXIgICAgc3RhdHVzSGFuZGxlciApCiAKICB7CiAgICByZXR1cm4gbmV3IEZpbGVSZXNvdXJjZU91dHB1dFN0cmVhbShjb250ZXh0LCBmaWxlLCBwcm9ncmVzc01vbml0b3IsIHN0YXR1c0hhbmRsZXIpOwogIH0KCiAgLy8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCiAgLy8gTmF1Z2h0eSBiaXRzLi4uCiAgLy8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCgogIC8vCiAgLy8gQ3JlYXRlcyBhIHBhdGggb2YgZm9sZGVycy4KICAvLyBEbyBub3QgY2FsbCB3aXRoIGFuIGFic29sdXRlUGF0aCBvZiBsZXNzIHRoYW4gb25lIHNlZ21lbnQuCiAgLy8KICAvKioKICAgKiBDcmVhdGVzIGEgcGF0aCBvZiBmb2xkZXJzLgogICAqIERvIG5vdCBjYWxsIHdpdGggYW4gYWJzb2x1dGVQYXRoIG9mIGxlc3MgdGhhbiBvbmUgc2VnbWVudC4KICAgKiBAcGFyYW0gcmVzb3VyY2VDb250ZXh0IHRoZSByZXNvdXJjZSBjb250ZXh0IGZvciBtYWtpbmcgZm9sZGVycy4KICAgKiBAcGFyYW0gYWJzb2x1dGVQYXRoIHRoZSBwYXRoIG9mIGZvbGRlcnMgdGhhdCB3aWxsIGJlIGNyZWF0ZWQuCiAgICogQHBhcmFtIHByb2dyZXNzTW9uaXRvciB0aGUgcHJvZ3Jlc3MgbW9uaXRvciB0byBiZSB1c2VkLgogICAqIEBwYXJhbSBzdGF0dXNIYW5kbGVyIHRoZSBzdGF0dXMgaGFuZGxlci4KICAgKiBAcmV0dXJuIHJldHVybnMgdGhlIElDb250YWluZXIgb2YgdGhlIGNyZWF0ZWQgZm9sZGVyLgogICAqLwogIHB1YmxpYyBzdGF0aWMgSUNvbnRhaW5lciBtYWtlRm9sZGVyUGF0aCAoCiAgICBSZXNvdXJjZUNvbnRleHQgIHJlc291cmNlQ29udGV4dCwKICAgIElQYXRoICAgICAgICAgICAgYWJzb2x1dGVQYXRoLAogICAgSVByb2dyZXNzTW9uaXRvciBwcm9ncmVzc01vbml0b3IsCiAgICBJU3RhdHVzSGFuZGxlciAgICBzdGF0dXNIYW5kbGVyICkKICAKICAgIHRocm93cyBDb3JlRXhjZXB0aW9uCiAgewogICAgaWYgKGFic29sdXRlUGF0aC5zZWdtZW50Q291bnQoKSA8PSAxKQogICAgewogICAgICByZXR1cm4gZ2V0V29ya3NwYWNlUm9vdCgpLmdldFByb2plY3QoYWJzb2x1dGVQYXRoLnNlZ21lbnQoMCkpOwogICAgfQogICAgZWxzZQogICAgewogICAgICBJQ29udGFpbmVyIHBhcmVudCA9IG1ha2VGb2xkZXJQYXRoKHJlc291cmNlQ29udGV4dCwgYWJzb2x1dGVQYXRoLnJlbW92ZUxhc3RTZWdtZW50cygxKSwgcHJvZ3Jlc3NNb25pdG9yLCBzdGF0dXNIYW5kbGVyICk7CiAgICAgIFN0cmluZyBmb2xkZXJOYW1lID0gYWJzb2x1dGVQYXRoLmxhc3RTZWdtZW50KCk7CiAgICAgIAogICAgICByZXR1cm4gbWFrZUZvbGRlcihyZXNvdXJjZUNvbnRleHQsIHBhcmVudCxmb2xkZXJOYW1lLCBwcm9ncmVzc01vbml0b3IgLCBzdGF0dXNIYW5kbGVyICk7CiAgICB9CiAgfQogIC8vCiAgLy8gQ3JlYXRlcyBhIGZvbGRlciB1bmRlciBhIGNvbnRhaW5lci4KICAvLyBUaGUgY29udGFpbmVyIG11c3QgYWxyZWFkeSBleGlzdC4KICAvLwogcHJpdmF0ZSBzdGF0aWMgSUZvbGRlciBtYWtlRm9sZGVyICgKICAgIFJlc291cmNlQ29udGV4dCAgcmVzb3VyY2VDb250ZXh0LAogICAgSUNvbnRhaW5lciAgICAgICBwYXJlbnQsCiAgICBTdHJpbmcgICAgICAgICAgIGZvbGRlck5hbWUsCiAgICBJUHJvZ3Jlc3NNb25pdG9yIHByb2dyZXNzTW9uaXRvciwKICAgIElTdGF0dXNIYW5kbGVyICAgIHN0YXR1c0hhbmRsZXIgKQogIAogIHRocm93cyBDb3JlRXhjZXB0aW9uCiAgewogICAgSVJlc291cmNlIGNoaWxkICA9IHBhcmVudC5maW5kTWVtYmVyKGZvbGRlck5hbWUpOwogICAgQ2hvaWNlICAgIHJlc3VsdCA9IG51bGw7CiAgICAKICAgIGlmKCBjaGlsZCA9PSBudWxsICkKICAgIHsKICAgICAgaWYgKCFyZXNvdXJjZUNvbnRleHQuaXNDcmVhdGVGb2xkZXJzRW5hYmxlZCgpKSAgCiAgICAgIHsKICAgICAgICByZXN1bHQgPSBzdGF0dXNIYW5kbGVyLnJlcG9ydCgKICAgICAgICAgICAgICAgIFN0YXR1c1V0aWxzLndhcm5pbmdTdGF0dXMoCiAgICAgICAgICAgICAgICAJCU5MUy5iaW5kKEVudmlyb25tZW50TWVzc2FnZXMuTVNHX0VSUk9SX0ZPTERFUl9DUkVBVElPTl9ESVNBQkxFRCwKICAgICAgICAJICAgICAgICAgICAgICAgICAgICAgIG5ldyBPYmplY3RbXXsgcGFyZW50LmdldEZ1bGxQYXRoKCkudG9TdHJpbmcoKSwgZm9sZGVyTmFtZX0gKSApLCAKICAgICAgICAgICAgICAgIGdldFRocmVlU3RhdGVGaWxlT3B0aW9ucygpICk7CiAgICAgICAgCiAgICAgICAgaWYoIHJlc3VsdCA9PSBudWxsIHx8IHJlc3VsdC5nZXRTaG9ydGN1dCgpID09ICdDJyApCiAgICAgICAgewogICAgICAgICAgcmV0dXJuIG51bGw7CiAgICAgICAgfQogICAgICAgIGVsc2UgaWYoIHJlc3VsdC5nZXRTaG9ydGN1dCgpID09ICdBJyApCiAgICAgICAgewogICAgICAgICAgcmVzb3VyY2VDb250ZXh0LnNldENyZWF0ZUZvbGRlcnNFbmFibGVkKHRydWUpOwogICAgICAgIH0KICAgICAgfQogICAgICAKICAgICAgSUZvbGRlciBmb2xkZXIgPSBwYXJlbnQuZ2V0Rm9sZGVyKG5ldyBQYXRoKGZvbGRlck5hbWUpKTsKICAgICAgZm9sZGVyLmNyZWF0ZSh0cnVlLHRydWUsbnVsbCk7CiAgICAgIHJldHVybiBmb2xkZXI7CiAgICB9CiAgICBlbHNlIGlmKCBjaGlsZC5nZXRUeXBlKCkgPT0gSVJlc291cmNlLkZPTERFUiApCiAgICB7CiAgICAgIHJldHVybiAoSUZvbGRlciljaGlsZDsKICAgIH0KICAgIGVsc2UKICAgIHsKICAgICAgdGhyb3cgbmV3IENvcmVFeGNlcHRpb24oCiAgICAgICAgbmV3IFN0YXR1cyggSVN0YXR1cy5FUlJPUiwgCiAgICAgICAgICAgICAgICAgICAgIlJlc291cmNlVXRpbHMiLAogICAgICAgICAgICAgICAgICAgIDAsIAogICAgICAgICAgICAgICAgICAgIE5MUy5iaW5kKEVudmlyb25tZW50TWVzc2FnZXMuTVNHX0VSUk9SX1JFU09VUkNFX05PVF9GT0xERVIsCgkJCQkJICAgICAgICAgICAgICAgICBuZXcgT2JqZWN0W117IHBhcmVudC5nZXRGdWxsUGF0aCgpLmFwcGVuZChmb2xkZXJOYW1lKS50b1N0cmluZygpIH0pLAoJCQludWxsICkgKTsKICAgIH0KICB9CgogIC8vCiAgLy8gQ3JlYXRlcyBhIGZpbGUgdW5kZXIgYSBjb250YWluZXIuCiAgLy8gVGhlIGNvbnRhaW5lciBtdXN0IGFscmVhZHkgZXhpc3QuCiAgLy8KIHByaXZhdGUgc3RhdGljIElGaWxlIG1ha2VGaWxlICgKICAgIFJlc291cmNlQ29udGV4dCAgcmVzb3VyY2VDb250ZXh0LAogICAgSUNvbnRhaW5lciAgICAgICBwYXJlbnQsCiAgICBTdHJpbmcgICAgICAgICAgIGZpbGVOYW1lLAogICAgSW5wdXRTdHJlYW0gICAgICBpbnB1dFN0cmVhbSwKICAgIElQcm9ncmVzc01vbml0b3IgcHJvZ3Jlc3NNb25pdG9yLAogICAgSVN0YXR1c0hhbmRsZXIgICAgc3RhdHVzSGFuZGxlciApCiAKICAgIHRocm93cyBDb3JlRXhjZXB0aW9uCiAgewogICAgSVJlc291cmNlIGNoaWxkICA9IHBhcmVudC5maW5kTWVtYmVyKGZpbGVOYW1lKTsKICAgIENob2ljZSAgICByZXN1bHQgPSBudWxsOwogICAgCiAgICBpZiggY2hpbGQgIT0gbnVsbCApCiAgICB7CiAgICAgIGlmKCBjaGlsZC5nZXRUeXBlKCkgPT0gSVJlc291cmNlLkZJTEUgKQogICAgICB7CiAgICAgICAgaWYoICFyZXNvdXJjZUNvbnRleHQuaXNPdmVyd3JpdGVGaWxlc0VuYWJsZWQoKSApICAgCiAgICAgICAgewogICAgICAgICAgcmVzdWx0ID0gc3RhdHVzSGFuZGxlci5yZXBvcnQoIAogICAgICAgICAgICAgICAgU3RhdHVzVXRpbHMud2FybmluZ1N0YXR1cyggTkxTLmJpbmQoRW52aXJvbm1lbnRNZXNzYWdlcy5NU0dfRVJST1JfRklMRV9PVkVSV1JJVEVfRElTQUJMRUQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBuZXcgT2JqZWN0W10ge3BhcmVudC5nZXRGdWxsUGF0aCgpLnRvU3RyaW5nKCksZmlsZU5hbWV9KSApLAkJCQkJICAJCSAgICAKICAgICAgICAgICAgICAgIGdldFRocmVlU3RhdGVGaWxlT3B0aW9ucygpICk7CiAgICAgICAgICAKICAgICAgICAgIGlmKCByZXN1bHQgPT0gbnVsbCB8fCByZXN1bHQuZ2V0U2hvcnRjdXQoKSA9PSAnQycgKQogICAgICAgICAgewogICAgICAgICAgICByZXR1cm4gbnVsbDsKICAgICAgICAgIH0KICAgICAgICAgIGVsc2UgaWYoIHJlc3VsdC5nZXRTaG9ydGN1dCgpID09ICdBJyApCiAgICAgICAgICB7CiAgICAgICAgICAgIHJlc291cmNlQ29udGV4dC5zZXRPdmVyd3JpdGVGaWxlc0VuYWJsZWQodHJ1ZSk7CiAgICAgICAgICB9CiAgICAgICAgfQkKICAgICAgICAKICAgICAgICAvL1dlIGhhdmUgcGVybWlzc2lvbiB0byBvdmVyd3JpdGUgc28gY2hlY2sgaWYgZmlsZSBpcyByZWFkLW9ubHkKICAgICAgICBpZiggY2hpbGQuZ2V0UmVzb3VyY2VBdHRyaWJ1dGVzKCkuaXNSZWFkT25seSgpICkKICAgICAgICB7CiAgICAgICAgICBpZiggIXJlc291cmNlQ29udGV4dC5pc0NoZWNrb3V0RmlsZXNFbmFibGVkKCkgKSAKICAgICAgICAgIHsgICAgICAgICAgICAKICAgICAgICAgICAgcmVzdWx0ID0gc3RhdHVzSGFuZGxlci5yZXBvcnQoIAogICAgICAgICAgICAgICAgICAgICAgICAgU3RhdHVzVXRpbHMuZXJyb3JTdGF0dXMoIE5MUy5iaW5kKEVudmlyb25tZW50TWVzc2FnZXMuTVNHX0VSUk9SX0ZJTEVfQ0hFQ0tPVVRfRElTQUJMRUQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbmV3IE9iamVjdFtdeyBwYXJlbnQuZ2V0RnVsbFBhdGgoKS50b1N0cmluZygpLGZpbGVOYW1lfSApICksIAogICAgICAgICAgICAgICAgICAgICAgICAgZ2V0VGhyZWVTdGF0ZUZpbGVPcHRpb25zKCkgKTsKICAgICAgICAgICAgCgkJICAgIGlmKCByZXN1bHQgPT0gbnVsbCB8fCByZXN1bHQuZ2V0U2hvcnRjdXQoKSA9PSAnQycgKQoJCSAgICB7CiAgICAgICAgICAgICAgcmV0dXJuIG51bGw7CgkJICAgIH0KICAgICAgICAgICAgZWxzZSBpZiggcmVzdWx0LmdldFNob3J0Y3V0KCkgPT0gJ0EnICkKICAgICAgICAgICAgewogICAgICAgICAgICAgIHJlc291cmNlQ29udGV4dC5zZXRDaGVja291dEZpbGVzRW5hYmxlZCh0cnVlKTsKICAgICAgICAgICAgfQogICAgICAgICAgfQoKICAgICAgICAgIElGaWxlW10gZmlsZXMgPSBuZXcgSUZpbGVbMV07CiAgICAgICAgICBmaWxlc1swXSA9IChJRmlsZSljaGlsZDsKICAgICAgICAgIAogICAgICAgICAgSVN0YXR1cyBzdGF0dXMgPSBnZXRXb3Jrc3BhY2UoKS52YWxpZGF0ZUVkaXQoZmlsZXMsbnVsbCk7CiAgICAgICAgICAKICAgICAgICAgIHRyeQogICAgICAgICAgewogICAgICAgICAgICBzdGF0dXNIYW5kbGVyLnJlcG9ydCggc3RhdHVzICk7CiAgICAgICAgICB9CiAgICAgICAgICBjYXRjaCggU3RhdHVzRXhjZXB0aW9uIGV4YyApCiAgICAgICAgICB7CiAgICAgICAgICAgIHJldHVybiBudWxsOwogICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgLy9DaGFuZ2UgdGhlIGNvbnRlbnRzIG9mIHRoZSBleGlzdGluZyBmaWxlLgogICAgICAgIElGaWxlIGZpbGUgPSBwYXJlbnQuZ2V0RmlsZSggbmV3IFBhdGgoZmlsZU5hbWUpICk7CiAgICAgICAgZmlsZS5zZXRDb250ZW50cyggaW5wdXRTdHJlYW0sIHRydWUsIHRydWUsIG51bGwgKTsKICAgICAgICAKICAgICAgICByZXR1cm4gZmlsZTsKICAgICAgCiAgICAgIH0KICAgICAgZWxzZQogICAgICB7CiAgICAgICAgdGhyb3cgbmV3IENvcmVFeGNlcHRpb24oIAogICAgICAgICAgbmV3IFN0YXR1cyggSVN0YXR1cy5FUlJPUiwKICAgICAgICAgICAgICAgICAgICAgICJSZXNvdXJjZVV0aWxzIiwKICAgICAgICAgICAgICAgICAgICAgIDAsIAogICAgICAgICAgICAgICAgICAgICAgTkxTLmJpbmQoRW52aXJvbm1lbnRNZXNzYWdlcy5NU0dfRVJST1JfUkVTT1VSQ0VfTk9UX0ZJTEUsCgkJCQkgICAgICAgICAgICAgICAgICAgICAgIG5ldyBPYmplY3RbXSB7cGFyZW50LmdldEZ1bGxQYXRoKCkuYXBwZW5kKGZpbGVOYW1lKX0pLAoJCQkJCSAgbnVsbCApICk7CiAgICAgIH0KICAgIH0KICAgIGVsc2UKICAgIHsKICAgICAgLy9DcmVhdGUgYSBuZXcgZmlsZS4KICAgICAgSUZpbGUgZmlsZSA9IHBhcmVudC5nZXRGaWxlKCBuZXcgUGF0aChmaWxlTmFtZSkgKTsKICAgICAgZmlsZS5jcmVhdGUoIGlucHV0U3RyZWFtLCB0cnVlLCBudWxsKTsKICAgICAgCiAgICAgIHJldHVybiBmaWxlOwogICAgfQogIH0KCiAKIC8qKgogICAqIENyZWF0ZXMgYSBmaWxlIG9mIHRoZSBnaXZlbiA8Y29kZT5hYnNvbHV0ZVBhdGg8L2NvZGU+CiAgICogYW5kIHJldHVybnMgaXRzIGhhbmRsZSBhcyBhbiA8Y29kZT5JRmlsZTwvY29kZT4uCiAgICogSWYgdGhlIGZpbGUgY2Fubm90IGJlIGNyZWF0ZWQsIGEKICAgKiA8Y29kZT5Db3JlRXhjZXB0aW9uPC9jb2RlPiBjb250YWluaW5nIGFuCiAgICogPGNvZGU+SVN0YXR1czwvY29kZT4gb2JqZWN0IGlzIHRocm93bi4KICAgKiBAcGFyYW0gYWJzb2x1dGVQYXRoIFRoZSBhYnNvbHV0ZSBwYXRoIG9mIHRoZSBmaWxlIHRvIGNyZWF0ZS4KICAgKiBUaGUgcHJvamVjdCBhdCB0aGUgYmVnaW5uaW5nIG9mIHRoZSBwYXRoIG11c3QgYWxyZWFkeSBleGlzdCwKICAgKiB0aGF0IGlzLCB0aGlzIG1ldGhvZCBjYW5ub3QgYmUgdXNlZCB0byBjcmVhdGUgcHJvamVjdHMuCiAgICogQHBhcmFtIHByb2dyZXNzTW9uaXRvciBUaGUgcHJvZ3Jlc3MgbW9uaXRvciBmb3IgdGhlIG9wZXJhdGlvbiwgb3IgbnVsbC4KICAgKiBAcmV0dXJuIFRoZSB7QGxpbmsgb3JnLmVjbGlwc2UuY29yZS5yZXNvdXJjZXMuSUZpbGUgSUZpbGV9CiAgICogaGFuZGxlIG9mIHRoZSBmaWxlLgogICAqIEB0aHJvd3MgQ29yZUV4Y2VwdGlvbiBBbiBleGNlcHRpb24gY29udGFpbmluZyBhbgogICAqIHtAbGluayBvcmcuZWNsaXBzZS5jb3JlLnJ1bnRpbWUuSVN0YXR1cyBJU3RhdHVzfQogICAqIHdpdGggYSBzZXZlcml0eSBvZiA8Y29kZT5JU3RhdHVzLkVSUk9SPC9jb2RlPiBhbmQgYQogICAqIGxvY2FsZS1zcGVjaWZpYyBkZXNjcmlwdGlvbiBvZiB0aGUgY2F1c2UuCiAgICovCiAgIHB1YmxpYyBzdGF0aWMgSUZpbGUgY3JlYXRlRmlsZUF0TG9jYXRpb24gKAogICAgIFJlc291cmNlQ29udGV4dCByZXNvdXJjZUNvbnRleHQsCiAgICAgSVBhdGggICAgICAgICAgIGFic29sdXRlUGF0aCwKICAgICBJbnB1dFN0cmVhbSAgICAgaW5wdXRTdHJlYW0sCiAgICAgSVByb2dyZXNzTW9uaXRvciBwcm9ncmVzc01vbml0b3IsCiAgICAgSVN0YXR1c0hhbmRsZXIgICBzdGF0dXNIYW5kbGVyICkKCiAgICAgdGhyb3dzIENvcmVFeGNlcHRpb24gCiAgIHsgICAgCiAgICAgaWYgKCFhYnNvbHV0ZVBhdGguaXNBYnNvbHV0ZSgpKQogICAgIHsKICAgICAgIHRocm93IG5ldyBDb3JlRXhjZXB0aW9uKG5ldyBTdGF0dXMoSVN0YXR1cy5FUlJPUiwgIlJlc291cmNlVXRpbHMiLDAsTkxTLmJpbmQoRW52aXJvbm1lbnRNZXNzYWdlcy5NU0dfRVJST1JfUEFUSF9OT1RfQUJTT0xVVEUsbmV3IE9iamVjdFtdIHthYnNvbHV0ZVBhdGgudG9TdHJpbmcoKX0pLG51bGwpKTsKICAgICB9CiAgICAgaWYgKGFic29sdXRlUGF0aC5zZWdtZW50Q291bnQoKSA8IDEpCiAgICAgewogICAgICAgdGhyb3cgbmV3IENvcmVFeGNlcHRpb24obmV3IFN0YXR1cyhJU3RhdHVzLkVSUk9SLCJSZXNvdXJjZVV0aWxzIiwwLE5MUy5iaW5kKEVudmlyb25tZW50TWVzc2FnZXMuTVNHX0VSUk9SX1BBVEhfRU1QVFksbmV3IE9iamVjdFtdIHthYnNvbHV0ZVBhdGgudG9TdHJpbmcoKX0pLG51bGwpKTsKICAgICB9CiAgICAgaWYgKGFic29sdXRlUGF0aC5zZWdtZW50Q291bnQoKSA8IDIpCiAgICAgewogICAgICAgdGhyb3cgbmV3IENvcmVFeGNlcHRpb24obmV3IFN0YXR1cyhJU3RhdHVzLkVSUk9SLCJSZXNvdXJjZVV0aWxzIiwwLE5MUy5iaW5kKEVudmlyb25tZW50TWVzc2FnZXMuTVNHX0VSUk9SX1BBVEhfTk9UX0ZPTERFUixuZXcgT2JqZWN0W10ge2Fic29sdXRlUGF0aC50b1N0cmluZygpfSksbnVsbCkpOwogICAgIH0KICAgICBJQ29udGFpbmVyIHBhcmVudCAgID0gbWFrZUZvbGRlclBhdGhBdExvY2F0aW9uKHJlc291cmNlQ29udGV4dCwgYWJzb2x1dGVQYXRoLnJlbW92ZUxhc3RTZWdtZW50cygxKSwgcHJvZ3Jlc3NNb25pdG9yLCBzdGF0dXNIYW5kbGVyKTsKICAgICBTdHJpbmcgICAgIGZpbGVOYW1lID0gYWJzb2x1dGVQYXRoLmxhc3RTZWdtZW50KCk7CiAgICAgCiAgICAgcmV0dXJuIG1ha2VGaWxlKHJlc291cmNlQ29udGV4dCwgcGFyZW50LCBmaWxlTmFtZSwgaW5wdXRTdHJlYW0sIHByb2dyZXNzTW9uaXRvciwgc3RhdHVzSGFuZGxlcik7CiAgIH0KCi8qKgogICogQ3JlYXRlcyBhIHBhdGggb2YgZm9sZGVycyB1c2luZyBhYnNvbHV0ZSBmaWxlbmFtZXMuCiAgKiBEbyBub3QgY2FsbCB3aXRoIGFuIGFic29sdXRlUGF0aCBvZiBsZXNzIHRoYW4gb25lIHNlZ21lbnQuCiAgKiBAcGFyYW0gcmVzb3VyY2VDb250ZXh0IHRoZSByZXNvdXJjZSBjb250ZXh0IGZvciBtYWtpbmcgZm9sZGVycy4KICAqIEBwYXJhbSByZXNvdXJjZSB0aGUgcmVzb3VyY2UgdGhhdCB3aWxsIGJlIGNyZWF0ZWQuCiAgKiBAcGFyYW0gcHJvZ3Jlc3NNb25pdG9yIHRoZSBwcm9ncmVzcyBtb25pdG9yIHRvIGJlIHVzZWQuCiAgKiBAcGFyYW0gc3RhdHVzSGFuZGxlciB0aGUgc3RhdHVzIGhhbmRsZXIuCiAgKiBAcmV0dXJuIHJldHVybnMgdGhlIElDb250YWluZXIgb2YgdGhlIGNyZWF0ZWQgZm9sZGVyLgogICovCiBwdWJsaWMgc3RhdGljIElDb250YWluZXIgbWFrZUZvbGRlclBhdGhBdExvY2F0aW9uICgKICAgUmVzb3VyY2VDb250ZXh0ICByZXNvdXJjZUNvbnRleHQsCiAgIElDb250YWluZXIgICAgICAgcmVzb3VyY2UsCiAgIElQcm9ncmVzc01vbml0b3IgcHJvZ3Jlc3NNb25pdG9yLAogICBJU3RhdHVzSGFuZGxlciAgIHN0YXR1c0hhbmRsZXIgKQogCiAgIHRocm93cyBDb3JlRXhjZXB0aW9uCiAgIHsKCSBpZiAocmVzb3VyY2UuZXhpc3RzKCkpCgkgewoJCSBpZiAocmVzb3VyY2UgaW5zdGFuY2VvZiBJQ29udGFpbmVyKQoJCSB7CgkJCSByZXR1cm4gKElDb250YWluZXIpIHJlc291cmNlOwoJCSB9CgkJIGVsc2UKCQkgewoJCQkgdGhyb3cgbmV3IENvcmVFeGNlcHRpb24oCgkJCQkJIG5ldyBTdGF0dXMoIElTdGF0dXMuRVJST1IsIAoJCQkJCQkJICJSZXNvdXJjZVV0aWxzIiwKCQkJCQkJCSAwLCAKCQkJCQkJCSBOTFMuYmluZChFbnZpcm9ubWVudE1lc3NhZ2VzLk1TR19FUlJPUl9SRVNPVVJDRV9OT1RfRk9MREVSLAoJCQkJCQkJCQkgbmV3IE9iamVjdFtdeyByZXNvdXJjZS5nZXRGdWxsUGF0aCgpLnRvU3RyaW5nKCkgfSksCgkJCQkJCQkJCSBudWxsICkgKTsKCQkgfQoJIH0KCSBlbHNlCgkgewoJCSBJQ29udGFpbmVyIHBhcmVudCA9IG1ha2VGb2xkZXJQYXRoQXRMb2NhdGlvbihyZXNvdXJjZUNvbnRleHQsIHJlc291cmNlLmdldFBhcmVudCgpLCBwcm9ncmVzc01vbml0b3IsIHN0YXR1c0hhbmRsZXIgKTsKCQkgU3RyaW5nIGZvbGRlck5hbWUgPSByZXNvdXJjZS5nZXROYW1lKCk7CgkJIAoJCSByZXR1cm4gbWFrZUZvbGRlcihyZXNvdXJjZUNvbnRleHQsIHBhcmVudCwgZm9sZGVyTmFtZSwgcHJvZ3Jlc3NNb25pdG9yICwgc3RhdHVzSGFuZGxlciApOwoJIH0KIH0KIAogLyoqCiAgKiBDcmVhdGVzIGEgcGF0aCBvZiBmb2xkZXJzLgogICogRG8gbm90IGNhbGwgd2l0aCBhbiBhYnNvbHV0ZVBhdGggb2YgbGVzcyB0aGFuIG9uZSBzZWdtZW50LgogICogQHBhcmFtIHJlc291cmNlQ29udGV4dCB0aGUgcmVzb3VyY2UgY29udGV4dCBmb3IgbWFraW5nIGZvbGRlcnMuCiAgKiBAcGFyYW0gYWJzb2x1dGVQYXRoIHRoZSBwYXRoIG9mIGZvbGRlcnMgdGhhdCB3aWxsIGJlIGNyZWF0ZWQuCiAgKiBAcGFyYW0gcHJvZ3Jlc3NNb25pdG9yIHRoZSBwcm9ncmVzcyBtb25pdG9yIHRvIGJlIHVzZWQuCiAgKiBAcGFyYW0gc3RhdHVzSGFuZGxlciB0aGUgc3RhdHVzIGhhbmRsZXIuCiAgKiBAcmV0dXJuIHJldHVybnMgdGhlIElDb250YWluZXIgb2YgdGhlIGNyZWF0ZWQgZm9sZGVyLgogICovCiBwdWJsaWMgc3RhdGljIElDb250YWluZXIgbWFrZUZvbGRlclBhdGhBdExvY2F0aW9uICgKICAgUmVzb3VyY2VDb250ZXh0ICByZXNvdXJjZUNvbnRleHQsCiAgIElQYXRoICAgICAgICAgICAgYWJzb2x1dGVQYXRoLAogICBJUHJvZ3Jlc3NNb25pdG9yIHByb2dyZXNzTW9uaXRvciwKICAgSVN0YXR1c0hhbmRsZXIgICAgc3RhdHVzSGFuZGxlciApCiAKICAgdGhyb3dzIENvcmVFeGNlcHRpb24KIHsKIAlyZXR1cm4gbWFrZUZvbGRlclBhdGhBdExvY2F0aW9uKHJlc291cmNlQ29udGV4dCwKIAkJZ2V0V29ya3NwYWNlUm9vdCgpLmdldENvbnRhaW5lckZvckxvY2F0aW9uKGFic29sdXRlUGF0aCksCiAJCXByb2dyZXNzTW9uaXRvciwgc3RhdHVzSGFuZGxlcik7CiB9CiAKIAoKfQo=