LyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogQ29weXJpZ2h0IChjKSAyMDAxLCAyMDA4IElCTSBDb3Jwb3JhdGlvbiBhbmQgb3RoZXJzLgogKiBBbGwgcmlnaHRzIHJlc2VydmVkLiBUaGlzIHByb2dyYW0gYW5kIHRoZSBhY2NvbXBhbnlpbmcgbWF0ZXJpYWxzCiAqIGFyZSBtYWRlIGF2YWlsYWJsZSB1bmRlciB0aGUgdGVybXMgb2YgdGhlIEVjbGlwc2UgUHVibGljIExpY2Vuc2UgdjEuMAogKiB3aGljaCBhY2NvbXBhbmllcyB0aGlzIGRpc3RyaWJ1dGlvbiwgYW5kIGlzIGF2YWlsYWJsZSBhdAogKiBodHRwOi8vd3d3LmVjbGlwc2Uub3JnL2xlZ2FsL2VwbC12MTAuaHRtbAogKgogKiBDb250cmlidXRvcnM6CiAqIElCTSBDb3Jwb3JhdGlvbiAtIGluaXRpYWwgQVBJIGFuZCBpbXBsZW1lbnRhdGlvbgogKiB5eXl5bW1kZCBidWcgICAgICBFbWFpbCBhbmQgb3RoZXIgY29udGFjdCBpbmZvcm1hdGlvbgogKiAtLS0tLS0tLSAtLS0tLS0tLSAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQogKiAyMDA2MDExMiAgIDEyMTE5OSBqZXNwZXJAc2Vsc2thYmV0Lm9yZyAtIEplc3BlciBN+GxsZXIKICogMjAwNzA4MTMgICAxODg5OTkgcG1vb2drQGNhLmlibS5jb20gLSBQZXRlciBNb29nawogKiAyMDA4MDYxMyAgIDIzNjUyMyBtYWthbmRyZUBjYS5pYm0uY29tIC0gQW5kcmV3IE1haywgT3ZlcndyaXRlIHNldHRpbmcgb24gV2ViIHNlcnZpY2Ugd2l6YXJkIGlzIGNvdXBsZWQgd2l0aCBwcmVmZXJlbmNlCiAqIDIwMDgwNjI1ICAgMjM3MTI5IG1ha2FuZHJlQGNhLmlibS5jb20gLSBBbmRyZXcgTWFrLCBFcnJvciBtb3ZpbmcgcmVzb3VyY2U6IG51bGwKICogMjAwODA3MTEgICAyNDA0MDggcmtrbGFpQGNhLmlibS5jb20gLSBSYXltb25kIExhaSwgc3VwcG9ydCBjYXNlLWluc2Vuc2l0aXZlIHBsYXRmb3JtIG1ha2VGaWxlIHdoZW4gYSBmaWxlIHdpdGggdmFyaWFudCBjYXNlIGV4aXN0cwogKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8KcGFja2FnZSBvcmcuZWNsaXBzZS53c3QuY29tbWFuZC5pbnRlcm5hbC5lbnYuY29tbW9uOwoKCmltcG9ydCBqYXZhLmlvLklPRXhjZXB0aW9uOwppbXBvcnQgamF2YS5pby5JbnB1dFN0cmVhbTsKaW1wb3J0IGphdmEuaW8uT3V0cHV0U3RyZWFtOwppbXBvcnQgamF2YS51dGlsLlZlY3RvcjsKCmltcG9ydCBvcmcuZWNsaXBzZS5jb3JlLnJlc291cmNlcy5JQ29udGFpbmVyOwppbXBvcnQgb3JnLmVjbGlwc2UuY29yZS5yZXNvdXJjZXMuSUZpbGU7CmltcG9ydCBvcmcuZWNsaXBzZS5jb3JlLnJlc291cmNlcy5JRm9sZGVyOwppbXBvcnQgb3JnLmVjbGlwc2UuY29yZS5yZXNvdXJjZXMuSVByb2plY3Q7CmltcG9ydCBvcmcuZWNsaXBzZS5jb3JlLnJlc291cmNlcy5JUmVzb3VyY2U7CmltcG9ydCBvcmcuZWNsaXBzZS5jb3JlLnJlc291cmNlcy5JUmVzb3VyY2VTdGF0dXM7CmltcG9ydCBvcmcuZWNsaXBzZS5jb3JlLnJlc291cmNlcy5JV29ya3NwYWNlOwppbXBvcnQgb3JnLmVjbGlwc2UuY29yZS5yZXNvdXJjZXMuSVdvcmtzcGFjZVJvb3Q7CmltcG9ydCBvcmcuZWNsaXBzZS5jb3JlLnJlc291cmNlcy5SZXNvdXJjZXNQbHVnaW47CmltcG9ydCBvcmcuZWNsaXBzZS5jb3JlLnJ1bnRpbWUuQ29yZUV4Y2VwdGlvbjsKaW1wb3J0IG9yZy5lY2xpcHNlLmNvcmUucnVudGltZS5JUGF0aDsKaW1wb3J0IG9yZy5lY2xpcHNlLmNvcmUucnVudGltZS5JUHJvZ3Jlc3NNb25pdG9yOwppbXBvcnQgb3JnLmVjbGlwc2UuY29yZS5ydW50aW1lLklTdGF0dXM7CmltcG9ydCBvcmcuZWNsaXBzZS5jb3JlLnJ1bnRpbWUuUGF0aDsKaW1wb3J0IG9yZy5lY2xpcHNlLmNvcmUucnVudGltZS5QbHVnaW47CmltcG9ydCBvcmcuZWNsaXBzZS5jb3JlLnJ1bnRpbWUuU3RhdHVzOwppbXBvcnQgb3JnLmVjbGlwc2Uub3NnaS51dGlsLk5MUzsKaW1wb3J0IG9yZy5lY2xpcHNlLndzdC5jb21tYW5kLmludGVybmFsLmVudi5FbnZpcm9ubWVudE1lc3NhZ2VzOwppbXBvcnQgb3JnLmVjbGlwc2Uud3N0LmNvbW1hbmQuaW50ZXJuYWwuZW52LmNvbnRleHQuUGVyc2lzdGVudFJlc291cmNlQ29udGV4dDsKaW1wb3J0IG9yZy5lY2xpcHNlLndzdC5jb21tYW5kLmludGVybmFsLmVudi5jb3JlLmNvbW1vbi5TdGF0dXNVdGlsczsKaW1wb3J0IG9yZy5lY2xpcHNlLndzdC5jb21tYW5kLmludGVybmFsLmVudi5jb3JlLmNvbnRleHQuUmVzb3VyY2VDb250ZXh0OwppbXBvcnQgb3JnLmVjbGlwc2Uud3N0LmNvbW1vbi5lbnZpcm9ubWVudC5DaG9pY2U7CmltcG9ydCBvcmcuZWNsaXBzZS53c3QuY29tbW9uLmVudmlyb25tZW50LklTdGF0dXNIYW5kbGVyOwppbXBvcnQgb3JnLmVjbGlwc2Uud3N0LmNvbW1vbi5lbnZpcm9ubWVudC5TdGF0dXNFeGNlcHRpb247CgoKCi8qKgoqIFRoaXMgY2xhc3MgY29udGFpbnMgdXNlZnVsIG1ldGhvZHMgZm9yIHdvcmtpbmcgd2l0aCBFY2xpcHNlIHJlc291cmNlcy4KKi8KcHVibGljIGZpbmFsIGNsYXNzIEZpbGVSZXNvdXJjZVV0aWxzCnsKICAvLwogIC8vIEtlZXBzIHRoZSBJV29ya3NwYWNlIGhhbmdpbmcgYXJvdW5kLiBTZWUgZ2V0V29ya3NwYWNlKCkuCiAgLy8KICBwcml2YXRlIHN0YXRpYyBJV29ya3NwYWNlIHdvcmtzcGFjZV8gPSBudWxsOwogIC8vCiAgLy8gS2VlcHMgdGhlIElXb3Jrc3BhY2VSb290IGhhbmdpbmcgYXJvdW5kLiBTZWUgZ2V0V29ya3NwYWNlUm9vdCgpLgogIC8vCiAgcHJpdmF0ZSBzdGF0aWMgSVdvcmtzcGFjZVJvb3Qgcm9vdF8gPSBudWxsOwogIAovLyAgcHJpdmF0ZSBzdGF0aWMgTWVzc2FnZVV0aWxzIG1zZ18gPSBuZXcgTWVzc2FnZVV0aWxzKCAib3JnLmVjbGlwc2Uud3N0LmNvbW1hbmQuaW50ZXJuYWwuZW52LmNvbW1vbi5lbnZpcm9ubWVudCIsIG5ldyBGaWxlUmVzb3VyY2VVdGlscygpICk7CgoKIC8qKgogICogUmV0dXJucyB0aGUgSVdvcmtzcGFjZVJvb3Qgb2JqZWN0LgogICogQHJldHVybiBUaGUgSVdvcmtzcGFjZVJvb3Qgb2JqZWN0LgogICovCiAgcHVibGljIHN0YXRpYyBJV29ya3NwYWNlUm9vdCBnZXRXb3Jrc3BhY2VSb290ICgpCiAgewogICAgaWYgKHJvb3RfID09IG51bGwpCiAgICB7CiAgICAgIHJvb3RfID0gUmVzb3VyY2VzUGx1Z2luLmdldFdvcmtzcGFjZSgpLmdldFJvb3QoKTsKICAgIH0KICAgIHJldHVybiByb290XzsKICB9CgogIC8qKgoJICogUmV0dXJucyB0aGUgSVdvcmtzcGFjZSBvYmplY3QuCgkgKiAKCSAqIEByZXR1cm4gVGhlIElXb3Jrc3BhY2Ugb2JqZWN0LgoJICovCiAgcHVibGljIHN0YXRpYyBJV29ya3NwYWNlIGdldFdvcmtzcGFjZSAoKQogIHsKICAgIGlmICh3b3Jrc3BhY2VfID09IG51bGwpCiAgICB7CiAgICAgIGlmIChyb290XyA9PSBudWxsKQogICAgICB7CiAgICAgICAgcm9vdF8gPSBSZXNvdXJjZXNQbHVnaW4uZ2V0V29ya3NwYWNlKCkuZ2V0Um9vdCgpOwogICAgICB9CiAgICAgIAogICAgICB3b3Jrc3BhY2VfID0gcm9vdF8uZ2V0V29ya3NwYWNlKCk7CiAgICB9CiAgICAKICAgIHJldHVybiB3b3Jrc3BhY2VfOwogIH0KICAKICAvKioKICAgKiAKICAgKiBAcmV0dXJuIHJldHVybnMgYW4gYXJyYXkgb2YgdGhyZWUgY29tbW9uIGNob2ljZXMuIChpZS4gWWVzLCB5ZXMgYWxsLCBhbmQgY2FuY2VsICkKICAgKi8KICBwdWJsaWMgc3RhdGljIENob2ljZVtdIGdldFRocmVlU3RhdGVGaWxlT3B0aW9ucygpIAogIHsKICAgIFZlY3RvciBjaG9pY2VzID0gbmV3IFZlY3RvcigpOwogICAgCiAgICBjaG9pY2VzLmFkZChuZXcgQ2hvaWNlKCAnWScsIEVudmlyb25tZW50TWVzc2FnZXMuTEFCRUxfWUVTKSk7CiAgICBjaG9pY2VzLmFkZChuZXcgQ2hvaWNlKCAnQScsIEVudmlyb25tZW50TWVzc2FnZXMuTEFCRUxfWUVTX1RPX0FMTCkpOwogICAgY2hvaWNlcy5hZGQobmV3IENob2ljZSggJ0MnLCBFbnZpcm9ubWVudE1lc3NhZ2VzLkxBQkVMX0NBTkNFTCkpOwogICAgCiAgICByZXR1cm4gKENob2ljZVtdKWNob2ljZXMudG9BcnJheShuZXcgQ2hvaWNlW2Nob2ljZXMuc2l6ZSgpXSk7CiAgfQogIAogIC8qKgogICogUmV0dXJucyBhbgogICoge0BsaW5rIG9yZy5lY2xpcHNlLmNvcmUucmVzb3VyY2VzLklSZXNvdXJjZSBJUmVzb3VyY2V9CiAgKiBvZiB0aGUgZ2l2ZW4gYWJzb2x1dGUgcGF0aG5hbWUgb3IgbnVsbCBpZiBubyBzdWNoIHJlc291cmNlIGV4aXN0cy4KICAqIEBwYXJhbSBhYnNvbHV0ZVBhdGhuYW1lIFRoZSBhYnNvbHV0ZSBwYXRoIG9mIHRoZSByZXNvdXJjZS4KICAqIEByZXR1cm4gVGhlIDxjb2RlPklSZXNvdXJjZTwvY29kZT4uCiAgKi8KICBwdWJsaWMgc3RhdGljIElSZXNvdXJjZSBmaW5kUmVzb3VyY2UgKCBTdHJpbmcgYWJzb2x1dGVQYXRobmFtZSApCiAgewogICAgaWYgKGFic29sdXRlUGF0aG5hbWUgPT0gbnVsbCkKICAgIHsKICAgICAgcmV0dXJuIG51bGw7CiAgICB9CiAgICAKICAgIHJldHVybiBmaW5kUmVzb3VyY2UobmV3IFBhdGgoYWJzb2x1dGVQYXRobmFtZSkpOwogIH0KCiAgLyoqCiAgKiBSZXR1cm5zIGFuCiAgKiB7QGxpbmsgb3JnLmVjbGlwc2UuY29yZS5yZXNvdXJjZXMuSVJlc291cmNlIElSZXNvdXJjZX0KICAqIG9mIHRoZSBnaXZlbiBhYnNvbHV0ZSBwYXRoIG9yIG51bGwgaWYgbm8gc3VjaCByZXNvdXJjZSBleGlzdHMuCiAgKiBAcGFyYW0gYWJzb2x1dGVQYXRoIFRoZSBhYnNvbHV0ZSA8Y29kZT5JUGF0aDwvY29kZT4gb2YgdGhlIHJlc291cmNlLgogICogQHJldHVybiBUaGUgPGNvZGU+SVJlc291cmNlPC9jb2RlPi4KICAqLwogIHB1YmxpYyBzdGF0aWMgSVJlc291cmNlIGZpbmRSZXNvdXJjZSAoIElQYXRoIGFic29sdXRlUGF0aCApCiAgewogICAgaWYgKGFic29sdXRlUGF0aCA9PSBudWxsKQogICAgewogICAgICByZXR1cm4gbnVsbDsKICAgIH0KICAgIAogICAgcmV0dXJuIEZpbGVSZXNvdXJjZVV0aWxzLmdldFdvcmtzcGFjZVJvb3QoKS5maW5kTWVtYmVyKGFic29sdXRlUGF0aCk7CiAgfQogIAogIC8qKgogICAqIENvcGllcyBhIGZpbGUgZnJvbSBhIHBsdWdpbidzIGluc3RhbGxhdGlvbiBsb2NhdGlvbgogICAqIHRvIGFuIEVjbGlwc2UgZm9sZGVyLgogICAqIEBwYXJhbSBwbHVnaW4gVGhlIHBsdWdpbiBjb250YWluaW5nIHRoZSBmaWxlcyB0byBjb3B5LgogICAqIE11c3Qgbm90IGJlIG51bGwuCiAgICogQHBhcmFtIHNvdXJjZVBhdGggVGhlIHBhdGgsIHJlbGF0aXZlIHRvIHRoZSA8Y29kZT5wbHVnaW48L2NvZGU+CiAgICogaW5zdGFsbCBsb2NhdGlvbiwgY29udGFpbmluZyB0aGUgZmlsZXMgdG8gY29weS4KICAgKiBJZiBudWxsLCB0aGVuIHRoZSBwbHVnaW4gaW5zdGFsbCBsb2NhdGlvbiBpcyB0aGUgc291cmNlIHBhdGgKICAgKiAoaWUuIG51bGwgaXMgZXF1aXZhbGVudCB0byAiLiIpLgogICAqIEBwYXJhbSBwYXRobmFtZSBUaGUgcGF0aG5hbWUgb2YgdGhlIGZpbGUgdG8gY29weS4KICAgKiBUaGUgcGF0aG5hbWUgaXMgcmVsYXRpdmUgdG8gdGhlIDxjb2RlPnBsdWdpbiBzb3VyY2VQYXRoPC9jb2RlPi4KICAgKiBNdXN0IG5vdCBiZSBudWxsLgogICAqIEBwYXJhbSB0YXJnZXRQYXRoIFRoZSBhYnNvbHV0ZSBFY2xpcHNlIHBhdGggb2YgdGhlIGZvbGRlciB0bwogICAqIHdoaWNoIHRoZSBmaWxlIHdpbGwgYmUgY29waWVkLiBUaGUgcmVsYXRpdmUgcGF0aG5hbWUgb2YgdGhlCiAgICogZmlsZSBpcyBwcmVzZXJ2ZWQuCiAgICogTXVzdCBub3QgYmUgbnVsbC4KICAgKiBAcGFyYW0gY3JlYXRlRm9sZGVycyBUaGUgaW50ZXJtZWRpYXRlIGZvbGRlciBjcmVhdGlvbiBwb2xpY3ksIG9uZSBvZgogICAqIHtAbGluayAjQ1JFQVRFIENSRUFURX0gb3Ige0BsaW5rICNET05UX0NSRUFURSBET05UX0NSRUFURX0uCiAgICogPHVsPgogICAqIDxsaT48Y29kZT5DUkVBVEU8L2NvZGU+IC0KICAgKiBJZiBhbnkgaW50ZXJtZWRpYXRlIGZvbGRlcnMgaW4gdGhlIGdpdmVuIDxjb2RlPmFic29sdXRlUGF0aDwvY29kZT4KICAgKiBkbyBub3QgZXhpc3QsIHRoZXkgd2lsbCBiZSBjcmVhdGVkLgogICAqIDxsaT48Y29kZT5ET05UX0NSRUFURTwvY29kZT4gLQogICAqIElmIGFueSBpbnRlcm1lZGlhdGUgZm9sZGVycyBpbiB0aGUgZ2l2ZW4gPGNvZGU+YWJzb2x1dGVQYXRoPC9jb2RlPgogICAqIGRvIG5vdCBleGlzdCwgdGhlIG1ldGhvZCB3aWxsIHRocm93IGEgPGNvZGU+Q29yZUV4Y2VwdGlvbjwvY29kZT4uCiAgICogPC91bD4KICAgKiBAcGFyYW0gb3ZlcndyaXRlRmlsZSBUaGUgcG9saWN5IGZvciBleGlzdGluZyBmaWxlcywgb25lIG9mCiAgICoge0BsaW5rICNPVkVSV1JJVEUgT1ZFUldSSVRFfSBvciB7QGxpbmsgI0RPTlRfT1ZFUldSSVRFIERPTlRfT1ZFUldSSVRFfS4KICAgKiA8dWw+CiAgICogPGxpPjxjb2RlPk9WRVJXUklURTwvY29kZT4gLQogICAqIElmIGEgcmVzb3VyY2Ugb2YgdGhlIHNhbWUgbmFtZSBhcyB0aGUgZ2l2ZW4KICAgKiA8Y29kZT5hYnNvbHV0ZVBhdGg8L2NvZGU+IGFscmVhZHkgZXhpc3RzIGFuZCBpcyBhIGZpbGUsCiAgICogaXQgd2lsbCBiZSByZXBsYWNlZC4KICAgKiBJZiB0aGUgcmVzb3VyY2UgYWxyZWFkeSBleGlzdHMgYW5kIGl0IGlzIG5vdCBhIGZpbGUsCiAgICogdGhlbiBubyBmaWxlIHdpbGwgYmUgY3JlYXRlZCBhbmQKICAgKiBhIDxjb2RlPkNvcmVFeGNlcHRpb248L2NvZGU+IHdpbGwgYmUgdGhyb3duLgogICAqIDxsaT48Y29kZT5ET05UX09WRVJXUklURTwvY29kZT4gLQogICAqIElmIGFueSByZXNvdXJjZSBvZiB0aGUgc2FtZSBuYW1lIGFzIHRoZSBnaXZlbgogICAqIDxjb2RlPmFic29sdXRlUGF0aDwvY29kZT4gYWxyZWFkeSBleGlzdHMsCiAgICogdGhlbiBubyBmaWxlIHdpbGwgYmUgY3JlYXRlZCBhbmQKICAgKiBhIDxjb2RlPkNvcmVFeGNlcHRpb248L2NvZGU+IHdpbGwgYmUgdGhyb3duLgogICAqIDwvdWw+CiAgICogQHBhcmFtIHByb2dyZXNzTW9uaXRvciBUaGUgcHJvZ3Jlc3MgbW9uaXRvciBmb3IgdGhlIG9wZXJhdGlvbiwgb3IgbnVsbC4KICAgKiBAdGhyb3dzIENvcmVFeGNlcHRpb24gQW4gZXhjZXB0aW9uIGNvbnRhaW5pbmcgYW4KICAgKiB7QGxpbmsgb3JnLmVjbGlwc2UuY29yZS5ydW50aW1lLklTdGF0dXMgSVN0YXR1c30KICAgKiB3aXRoIGEgc2V2ZXJpdHkgb2YgPGNvZGU+SVN0YXR1cy5FUlJPUjwvY29kZT4gYW5kIGEKICAgKiBsb2NhbGUtc3BlY2lmaWMgZGVzY3JpcHRpb24gb2YgdGhlIGNhdXNlLgogICAqLwogICBzdGF0aWMgcHVibGljIHZvaWQgY29weUZpbGUoIFJlc291cmNlQ29udGV4dCByZXNvdXJjZUNvbnRleHQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgUGx1Z2luIHBsdWdpbiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBJUGF0aCBzb3VyY2VQYXRoLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIElQYXRoIHBhdGhuYW1lLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIElQYXRoIHRhcmdldFBhdGgsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgSVByb2dyZXNzTW9uaXRvciBwcm9ncmVzc01vbml0b3IsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgSVN0YXR1c0hhbmRsZXIgc3RhdHVzTW9uaXRvciApCiAgICAgdGhyb3dzIENvcmVFeGNlcHRpb24KICAgewogICAgIHRyeQogICAgIHsKICAgICAgIElQYXRoIHRhcmdldCA9IHRhcmdldFBhdGguYXBwZW5kKHBhdGhuYW1lKTsKICAgICAgIElQYXRoIHNvdXJjZSA9IHNvdXJjZVBhdGggPT0gbnVsbCA/IHBhdGhuYW1lIDogc291cmNlUGF0aC5hcHBlbmQocGF0aG5hbWUpOwogICAgICAgSW5wdXRTdHJlYW0gaW5wdXQgPSBwbHVnaW4ub3BlblN0cmVhbShzb3VyY2UpOwogICAgICAgY3JlYXRlRmlsZShyZXNvdXJjZUNvbnRleHQsIHRhcmdldCwgaW5wdXQsIHByb2dyZXNzTW9uaXRvciwgc3RhdHVzTW9uaXRvcik7CiAgICAgfQogICAgIGNhdGNoIChJT0V4Y2VwdGlvbiBlKQogICAgIHsKICAgICAgIHRocm93IG5ldyBDb3JlRXhjZXB0aW9uKG5ldyBTdGF0dXMoSVN0YXR1cy5FUlJPUiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBsdWdpbi5nZXRCdW5kbGUoKS5nZXRTeW1ib2xpY05hbWUoKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDAsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBFbnZpcm9ubWVudE1lc3NhZ2VzLk1TR19FUlJPUl9JTyxlKSk7CiAgICAgfQogICB9CiAgIAogIC8qKgogICAqIERlbGV0ZXMgYSBmaWxlIHVuZGVyIGEgY29udGFpbmVyLgogICAqIFRoZSBjb250YWluZXIgbXVzdCBhbHJlYWR5IGV4aXN0LgogICAqIEBwYXJhbSBmaWxlIC0gdGhlIElGaWxlIHRvIGJlIGRlbGV0ZWQKICAgKiBAcGFyYW0gcHJvZ3Jlc3NNb25pdG9yCiAgICogQHBhcmFtIHN0YXR1c01vbml0b3IKICAgKiBAcmV0dXJuIFRydWUgaWYgdGhlIGZpbGUgZG9lcyBub3QgZXhpc3Qgb3IgaWYgaXQgZXhpc3RzIGFuZCBpcyBzdWNjZXNzZnVsbHkgZGVsZXRlZC4gRmFsc2Ugb3RoZXJ3aXNlLgogICAqLwogIHB1YmxpYyBzdGF0aWMgYm9vbGVhbiBkZWxldGVGaWxlKCBSZXNvdXJjZUNvbnRleHQgcmVzb3VyY2VDb250ZXh0LCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgSUZpbGUgZmlsZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgSVByb2dyZXNzTW9uaXRvciBwcm9ncmVzc01vbml0b3IsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBJU3RhdHVzSGFuZGxlciBzdGF0dXNNb25pdG9yKQogICAgdGhyb3dzIENvcmVFeGNlcHRpb24KICB7CiAgICBpZiAoZmlsZS5leGlzdHMoKSkKICAgIHsKICAgICAgaWYgKCFyZXNvdXJjZUNvbnRleHQuaXNPdmVyd3JpdGVGaWxlc0VuYWJsZWQoKSkKICAgICAgewogICAgICAgIElTdGF0dXMgc3RhdHVzIAogICAgICAgICAgPSBTdGF0dXNVdGlscy53YXJuaW5nU3RhdHVzKCBOTFMuYmluZChFbnZpcm9ubWVudE1lc3NhZ2VzLk1TR19FUlJPUl9GSUxFX09WRVJXUklURV9ESVNBQkxFRCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBuZXcgT2JqZWN0W117IGZpbGUuZ2V0UGFyZW50KCkuZ2V0RnVsbFBhdGgoKS50b1N0cmluZygpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZmlsZS5nZXROYW1lKCl9KSApOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgCiAgICAgICAgQ2hvaWNlIGNob2ljZSA9IHN0YXR1c01vbml0b3IucmVwb3J0KCBzdGF0dXMsIGdldFRocmVlU3RhdGVGaWxlT3B0aW9ucygpICk7CiAgICAgICAgCiAgICAgICAgaWYoIGNob2ljZS5nZXRTaG9ydGN1dCgpID09ICdDJyApIHJldHVybiBmYWxzZTsKICAgICAgICAKICAgICAgICBpZiggY2hvaWNlLmdldFNob3J0Y3V0KCkgPT0gJ0EnICkgewogICAgICAgIAlyZXNvdXJjZUNvbnRleHQuc2V0T3ZlcndyaXRlRmlsZXNFbmFibGVkKHRydWUpOwogICAgICAgIAlQZXJzaXN0ZW50UmVzb3VyY2VDb250ZXh0LmdldEluc3RhbmNlKCkuc2V0T3ZlcndyaXRlRmlsZXNFbmFibGVkKHRydWUpOwogICAgICAgIH0KICAgICAgfQogICAgICAKICAgICAgLy9XZSBoYXZlIHBlcm1pc3Npb24gdG8gb3ZlcndyaXRlIHNvIGNoZWNrIGlmIGZpbGUgaXMgcmVhZC1vbmx5CiAgICAgIGlmIChmaWxlLmlzUmVhZE9ubHkoKSkKICAgICAgewogICAgICAgIGlmICghcmVzb3VyY2VDb250ZXh0LmlzQ2hlY2tvdXRGaWxlc0VuYWJsZWQoKSkKICAgICAgICB7CiAgICAgICAgICBJU3RhdHVzIHN0YXR1cyAKICAgICAgICAgICAgPSBTdGF0dXNVdGlscy53YXJuaW5nU3RhdHVzKCBOTFMuYmluZChFbnZpcm9ubWVudE1lc3NhZ2VzLk1TR19FUlJPUl9GSUxFX0NIRUNLT1VUX0RJU0FCTEVELAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbmV3IE9iamVjdFtdeyBmaWxlLmdldFBhcmVudCgpLmdldEZ1bGxQYXRoKCkudG9TdHJpbmcoKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZmlsZS5nZXROYW1lKCl9KSApOwogICAgICAgICAgCiAgICAgICAgICBDaG9pY2UgY2hvaWNlID0gc3RhdHVzTW9uaXRvci5yZXBvcnQoIHN0YXR1cywgZ2V0VGhyZWVTdGF0ZUZpbGVPcHRpb25zKCkgKTsKICAgICAgICAgIAogICAgICAgICAgaWYoIGNob2ljZS5nZXRTaG9ydGN1dCgpID09ICdDJyApIHJldHVybiBmYWxzZTsKICAgICAgICAgIAogICAgICAgICAgaWYoIGNob2ljZS5nZXRTaG9ydGN1dCgpID09ICdBJyApIHsKICAgICAgICAJICByZXNvdXJjZUNvbnRleHQuc2V0Q2hlY2tvdXRGaWxlc0VuYWJsZWQodHJ1ZSk7CiAgICAgICAgCSAgUGVyc2lzdGVudFJlc291cmNlQ29udGV4dC5nZXRJbnN0YW5jZSgpLnNldENoZWNrb3V0RmlsZXNFbmFibGVkKHRydWUpOwogICAgICAgICAgfQogICAgICAgIH0KICAgICAgICAKICAgICAgICBJRmlsZVtdIGZpbGVzID0gbmV3IElGaWxlWzFdOwogICAgICAgIGZpbGVzWzBdID0gZmlsZTsKICAgICAgICBJU3RhdHVzIHN0YXR1cyA9IGdldFdvcmtzcGFjZSgpLnZhbGlkYXRlRWRpdChmaWxlcywgbnVsbCk7CiAgICAgICAgCiAgICAgICAgaWYoIHN0YXR1cy5nZXRTZXZlcml0eSgpID09IElTdGF0dXMuRVJST1IgKQogICAgICAgIHsKICAgICAgICAgIHN0YXR1c01vbml0b3IucmVwb3J0RXJyb3IoIHN0YXR1cyApOwogICAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgICAgIH0KICAgICAgfQogICAgICAKICAgICAgZmlsZS5kZWxldGUodHJ1ZSwgbnVsbCk7CiAgICB9CiAgICAvL0F0IHRoaXMgcG9pbnQsIGVpdGhlciB0aGUgZmlsZSBkaWQgbm90IGV4aXN0IG9yIHdlIHN1Y2Nlc3NmdWxseSBkZWxldGVkCiAgICAvLyBpdC4gUmV0dXJuIHN1Y2Nlc3MuCiAgICByZXR1cm4gdHJ1ZTsKICB9CgogIC8qKgogICAqIERlbGV0ZXMgYSBmb2xkZXIgdW5kZXIgYSBjb250YWluZXIuCiAgICogQHBhcmFtIGZvbGRlciAtIHRoZSBJRm9sZGVyIHRvIGJlIGRlbGV0ZWQKICAgKiBAcGFyYW0gcHJvZ3Jlc3NNb25pdG9yCiAgICogQHBhcmFtIHN0YXR1c01vbml0b3IKICAgKiBAcmV0dXJuIFRydWUgaWYgdGhlIGZvbGRlciBkb2VzIG5vdCBleGlzdCBvciBpZiBpdCBleGlzdHMgYW5kIGlzIHN1Y2Nlc3NmdWxseSBkZWxldGVkIGFsb25nIHdpdGggaXRzIG1lbWJlcnMuIEZhbHNlIG90aGVyd2lzZS4KICAgKi8KICAgcHVibGljIHN0YXRpYyBib29sZWFuIGRlbGV0ZUZvbGRlciggUmVzb3VyY2VDb250ZXh0IHJlc291cmNlQ29udGV4dCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgSUZvbGRlciBmb2xkZXIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIElQcm9ncmVzc01vbml0b3IgcHJvZ3Jlc3NNb25pdG9yLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBJU3RhdHVzSGFuZGxlciBzdGF0dXNNb25pdG9yICkKICAgICB0aHJvd3MgQ29yZUV4Y2VwdGlvbgogICB7CiAgICAgaWYgKCFmb2xkZXIuZXhpc3RzKCkpIHJldHVybiB0cnVlOwoKICAgICBib29sZWFuICAgICBkZWxldGVkICAgPSB0cnVlOwogICAgIElSZXNvdXJjZVtdIHJlc291cmNlcyA9IGZvbGRlci5tZW1iZXJzKCk7CiAgICAgCiAgICAgZm9yIChpbnQgaT0wOyBpPHJlc291cmNlcy5sZW5ndGg7IGkrKykKICAgICB7CiAgICAgICBJUmVzb3VyY2UgcmVzb3VyY2UgPSByZXNvdXJjZXNbaV07CiAgICAgICBpZiAocmVzb3VyY2UgaW5zdGFuY2VvZiBJRmlsZSkKICAgICAgIHsKICAgICAgICAgZGVsZXRlZCA9IGRlbGV0ZUZpbGUocmVzb3VyY2VDb250ZXh0LCAoSUZpbGUpcmVzb3VyY2UsIHByb2dyZXNzTW9uaXRvciwgc3RhdHVzTW9uaXRvcik7CiAgICAgICB9CiAgICAgICBpZiAocmVzb3VyY2UgaW5zdGFuY2VvZiBJRm9sZGVyKQogICAgICAgewogICAgICAgICBkZWxldGVkID0gZGVsZXRlRm9sZGVyKCByZXNvdXJjZUNvbnRleHQsIChJRm9sZGVyKXJlc291cmNlLCBwcm9ncmVzc01vbml0b3IsIHN0YXR1c01vbml0b3IpOwogICAgICAgfQoKICAgICAgIGlmKCAhZGVsZXRlZCApIGJyZWFrOwogICAgIH0KICAgICAKICAgICBpZiggZGVsZXRlZCApCiAgICAgewogICAgICAgZm9sZGVyLmRlbGV0ZSh0cnVlLCB0cnVlLCBudWxsKTsKICAgICAgIHJldHVybiB0cnVlOwogICAgIH0KICAgICBlbHNlCiAgICAgICByZXR1cm4gZmFsc2U7CiAgIH0KCiAgLyoqCiAgKiBDcmVhdGVzIGEgZmlsZSBvZiB0aGUgZ2l2ZW4gPGNvZGU+YWJzb2x1dGVQYXRoPC9jb2RlPgogICogYW5kIHJldHVybnMgaXRzIGhhbmRsZSBhcyBhbiA8Y29kZT5JRmlsZTwvY29kZT4uCiAgKiBJZiB0aGUgZmlsZSBjYW5ub3QgYmUgY3JlYXRlZCwgYQogICogPGNvZGU+Q29yZUV4Y2VwdGlvbjwvY29kZT4gY29udGFpbmluZyBhbgogICogPGNvZGU+SVN0YXR1czwvY29kZT4gb2JqZWN0IGlzIHRocm93bi4KICAqIEBwYXJhbSBhYnNvbHV0ZVBhdGggVGhlIGFic29sdXRlIHBhdGggb2YgdGhlIGZpbGUgdG8gY3JlYXRlLgogICogVGhlIHByb2plY3QgYXQgdGhlIGJlZ2lubmluZyBvZiB0aGUgcGF0aCBtdXN0IGFscmVhZHkgZXhpc3QsCiAgKiB0aGF0IGlzLCB0aGlzIG1ldGhvZCBjYW5ub3QgYmUgdXNlZCB0byBjcmVhdGUgcHJvamVjdHMuCiAgKiBAcGFyYW0gcHJvZ3Jlc3NNb25pdG9yIFRoZSBwcm9ncmVzcyBtb25pdG9yIGZvciB0aGUgb3BlcmF0aW9uLCBvciBudWxsLgogICogQHJldHVybiBUaGUge0BsaW5rIG9yZy5lY2xpcHNlLmNvcmUucmVzb3VyY2VzLklGaWxlIElGaWxlfQogICogaGFuZGxlIG9mIHRoZSBmaWxlLgogICogQHRocm93cyBDb3JlRXhjZXB0aW9uIEFuIGV4Y2VwdGlvbiBjb250YWluaW5nIGFuCiAgKiB7QGxpbmsgb3JnLmVjbGlwc2UuY29yZS5ydW50aW1lLklTdGF0dXMgSVN0YXR1c30KICAqIHdpdGggYSBzZXZlcml0eSBvZiA8Y29kZT5JU3RhdHVzLkVSUk9SPC9jb2RlPiBhbmQgYQogICogbG9jYWxlLXNwZWNpZmljIGRlc2NyaXB0aW9uIG9mIHRoZSBjYXVzZS4KICAqLwogIHB1YmxpYyBzdGF0aWMgSUZpbGUgY3JlYXRlRmlsZSAoCiAgICBSZXNvdXJjZUNvbnRleHQgcmVzb3VyY2VDb250ZXh0LAogICAgSVBhdGggICAgICAgICAgIGFic29sdXRlUGF0aCwKICAgIElucHV0U3RyZWFtICAgICBpbnB1dFN0cmVhbSwKICAgIElQcm9ncmVzc01vbml0b3IgcHJvZ3Jlc3NNb25pdG9yLAogICAgSVN0YXR1c0hhbmRsZXIgICBzdGF0dXNIYW5kbGVyICkKCiAgICB0aHJvd3MgQ29yZUV4Y2VwdGlvbiAKICB7ICAgIAogICAgaWYgKCFhYnNvbHV0ZVBhdGguaXNBYnNvbHV0ZSgpKQogICAgewogICAgICB0aHJvdyBuZXcgQ29yZUV4Y2VwdGlvbihuZXcgU3RhdHVzKElTdGF0dXMuRVJST1IsICJSZXNvdXJjZVV0aWxzIiwwLE5MUy5iaW5kKEVudmlyb25tZW50TWVzc2FnZXMuTVNHX0VSUk9SX1BBVEhfTk9UX0FCU09MVVRFLG5ldyBPYmplY3RbXSB7YWJzb2x1dGVQYXRoLnRvU3RyaW5nKCl9KSxudWxsKSk7CiAgICB9CiAgICBpZiAoYWJzb2x1dGVQYXRoLnNlZ21lbnRDb3VudCgpIDwgMSkKICAgIHsKICAgICAgdGhyb3cgbmV3IENvcmVFeGNlcHRpb24obmV3IFN0YXR1cyhJU3RhdHVzLkVSUk9SLCJSZXNvdXJjZVV0aWxzIiwwLE5MUy5iaW5kKEVudmlyb25tZW50TWVzc2FnZXMuTVNHX0VSUk9SX1BBVEhfRU1QVFksbmV3IE9iamVjdFtdIHthYnNvbHV0ZVBhdGgudG9TdHJpbmcoKX0pLG51bGwpKTsKICAgIH0KICAgIGlmIChhYnNvbHV0ZVBhdGguc2VnbWVudENvdW50KCkgPCAyKQogICAgewogICAgICB0aHJvdyBuZXcgQ29yZUV4Y2VwdGlvbihuZXcgU3RhdHVzKElTdGF0dXMuRVJST1IsIlJlc291cmNlVXRpbHMiLDAsTkxTLmJpbmQoRW52aXJvbm1lbnRNZXNzYWdlcy5NU0dfRVJST1JfUEFUSF9OT1RfRk9MREVSLG5ldyBPYmplY3RbXSB7YWJzb2x1dGVQYXRoLnRvU3RyaW5nKCl9KSxudWxsKSk7CiAgICB9CiAgICBJQ29udGFpbmVyIHBhcmVudCAgID0gbWFrZUZvbGRlclBhdGgocmVzb3VyY2VDb250ZXh0LCBhYnNvbHV0ZVBhdGgucmVtb3ZlTGFzdFNlZ21lbnRzKDEpLCBwcm9ncmVzc01vbml0b3IsIHN0YXR1c0hhbmRsZXIpOwogICAgU3RyaW5nICAgICBmaWxlTmFtZSA9IGFic29sdXRlUGF0aC5sYXN0U2VnbWVudCgpOwogICAgCiAgICByZXR1cm4gbWFrZUZpbGUocmVzb3VyY2VDb250ZXh0LCBwYXJlbnQsIGZpbGVOYW1lLCBpbnB1dFN0cmVhbSwgcHJvZ3Jlc3NNb25pdG9yLCBzdGF0dXNIYW5kbGVyKTsKICB9CgogIC8qKgogICogQ3JlYXRlcyB1bmRlciB0aGUgZ2l2ZW4gPGNvZGU+cHJvamVjdDwvY29kZT4KICAqIGEgZmlsZSBvZiB0aGUgZ2l2ZW4gPGNvZGU+cmVsYXRpdmVQYXRoPC9jb2RlPgogICogYW5kIHJldHVybnMgaXRzIGhhbmRsZSBhcyBhbiA8Y29kZT5JRmlsZTwvY29kZT4uCiAgKiBJZiB0aGUgZmlsZSBjYW5ub3QgYmUgY3JlYXRlZCwgYQogICogPGNvZGU+Q29yZUV4Y2VwdGlvbjwvY29kZT4gY29udGFpbmluZyBhbgogICogPGNvZGU+SVN0YXR1czwvY29kZT4gb2JqZWN0IGlzIHRocm93bi4KICAqIEBwYXJhbSBhYnNvbHV0ZVBhdGggVGhlIGFic29sdXRlIHBhdGggb2YgdGhlIGZpbGUgdG8gY3JlYXRlLgogICogVGhlIHByb2plY3QgYXQgdGhlIGJlZ2lubmluZyBvZiB0aGUgcGF0aCBtdXN0IGFscmVhZHkgZXhpc3QsCiAgKiB0aGF0IGlzLCB0aGlzIG1ldGhvZCBjYW5ub3QgYmUgdXNlZCB0byBjcmVhdGUgcHJvamVjdHMuCiAgKiBAcGFyYW0gY3JlYXRlRm9sZGVycyBUaGUgaW50ZXJtZWRpYXRlIGZvbGRlciBjcmVhdGlvbiBwb2xpY3ksIG9uZSBvZgogICoge0BsaW5rICNDUkVBVEUgQ1JFQVRFfSBvciB7QGxpbmsgI0RPTlRfQ1JFQVRFIERPTlRfQ1JFQVRFfS4KICAqIDx1bD4KICAqIDxsaT48Y29kZT5DUkVBVEU8L2NvZGU+IC0KICAqIElmIGFueSBpbnRlcm1lZGlhdGUgZm9sZGVycyBpbiB0aGUgZ2l2ZW4gPGNvZGU+YWJzb2x1dGVQYXRoPC9jb2RlPgogICogZG8gbm90IGV4aXN0LCB0aGV5IHdpbGwgYmUgY3JlYXRlZC4KICAqIDxsaT48Y29kZT5ET05UX0NSRUFURTwvY29kZT4gLQogICogSWYgYW55IGludGVybWVkaWF0ZSBmb2xkZXJzIGluIHRoZSBnaXZlbiA8Y29kZT5hYnNvbHV0ZVBhdGg8L2NvZGU+CiAgKiBkbyBub3QgZXhpc3QsIHRoZSBtZXRob2Qgd2lsbCB0aHJvdyBhIDxjb2RlPkNvcmVFeGNlcHRpb248L2NvZGU+LgogICogPC91bD4KICAqIEBwYXJhbSBvdmVyd3JpdGVGaWxlIFRoZSBwb2xpY3kgZm9yIGV4aXN0aW5nIGZpbGVzLCBvbmUgb2YKICAqIHtAbGluayAjT1ZFUldSSVRFIE9WRVJXUklURX0gb3Ige0BsaW5rICNET05UX09WRVJXUklURSBET05UX09WRVJXUklURX0uCiAgKiA8dWw+CiAgKiA8bGk+PGNvZGU+T1ZFUldSSVRFPC9jb2RlPiAtCiAgKiBJZiBhIHJlc291cmNlIG9mIHRoZSBzYW1lIG5hbWUgYXMgdGhlIGdpdmVuCiAgKiA8Y29kZT5hYnNvbHV0ZVBhdGg8L2NvZGU+IGFscmVhZHkgZXhpc3RzIGFuZCBpcyBhIGZpbGUsCiAgKiBpdCB3aWxsIGJlIHJlcGxhY2VkLgogICogSWYgdGhlIHJlc291cmNlIGFscmVhZHkgZXhpc3RzIGFuZCBpdCBpcyBub3QgYSBmaWxlLAogICogdGhlbiBubyBmaWxlIHdpbGwgYmUgY3JlYXRlZCBhbmQKICAqIGEgPGNvZGU+Q29yZUV4Y2VwdGlvbjwvY29kZT4gd2lsbCBiZSB0aHJvd24uCiAgKiA8bGk+PGNvZGU+RE9OVF9PVkVSV1JJVEU8L2NvZGU+IC0KICAqIElmIGFueSByZXNvdXJjZSBvZiB0aGUgc2FtZSBuYW1lIGFzIHRoZSBnaXZlbgogICogPGNvZGU+YWJzb2x1dGVQYXRoPC9jb2RlPiBhbHJlYWR5IGV4aXN0cywKICAqIHRoZW4gbm8gZmlsZSB3aWxsIGJlIGNyZWF0ZWQgYW5kCiAgKiBhIDxjb2RlPkNvcmVFeGNlcHRpb248L2NvZGU+IHdpbGwgYmUgdGhyb3duLgogICogPC91bD4KICAqIEBwYXJhbSBwcm9ncmVzc01vbml0b3IgVGhlIHByb2dyZXNzIG1vbml0b3IgZm9yIHRoZSBvcGVyYXRpb24sIG9yIG51bGwuCiAgKiBAcmV0dXJuIFRoZSB7QGxpbmsgb3JnLmVjbGlwc2UuY29yZS5yZXNvdXJjZXMuSUZpbGUgSUZpbGV9CiAgKiBoYW5kbGUgb2YgdGhlIGZpbGUuCiAgKiBAdGhyb3dzIENvcmVFeGNlcHRpb24gQW4gZXhjZXB0aW9uIGNvbnRhaW5pbmcgYW4KICAqIHtAbGluayBvcmcuZWNsaXBzZS5jb3JlLnJ1bnRpbWUuSVN0YXR1cyBJU3RhdHVzfQogICogd2l0aCBhIHNldmVyaXR5IG9mIDxjb2RlPklTdGF0dXMuRVJST1I8L2NvZGU+IGFuZCBhCiAgKiBsb2NhbGUtc3BlY2lmaWMgZGVzY3JpcHRpb24gb2YgdGhlIGNhdXNlLgogICovCiAgcHVibGljIHN0YXRpYyBJRmlsZSBjcmVhdGVGaWxlICgKICAgIFJlc291cmNlQ29udGV4dCByZXNvdXJjZUNvbnRleHQsCiAgICBJUHJvamVjdCAgICAgICAgcHJvamVjdCwKICAgIElQYXRoICAgICAgICAgICByZWxhdGl2ZVBhdGgsCiAgICBJbnB1dFN0cmVhbSAgICAgaW5wdXRTdHJlYW0sCiAgICBJUHJvZ3Jlc3NNb25pdG9yIHByb2dyZXNzTW9uaXRvciwKICAgIElTdGF0dXNIYW5kbGVyICAgc3RhdHVzTW9uaXRvciApCiAKICAgIHRocm93cyBDb3JlRXhjZXB0aW9uIAogIHsKICAgIElQYXRoIGFic29sdXRlUGF0aCA9IHByb2plY3QuZ2V0RnVsbFBhdGgoKS5hcHBlbmQocmVsYXRpdmVQYXRoKTsKICAgIHJldHVybiBjcmVhdGVGaWxlKHJlc291cmNlQ29udGV4dCwgYWJzb2x1dGVQYXRoLCBpbnB1dFN0cmVhbSwgcHJvZ3Jlc3NNb25pdG9yLCBzdGF0dXNNb25pdG9yKTsKICB9CgogIC8qKgogICogQ3JlYXRlcyBhbiBvdXRwdXQgc3RyZWFtIHRoYXQgY2FuIGJlIHVzZWQgdG8gd3JpdGUgdG8gdGhlCiAgKiBnaXZlbiA8Y29kZT5maWxlPC9jb2RlPi4gQWN0dWFsIGNoYW5nZXMgdG8gdGhlIHdvcmtzcGFjZQogICogbWF5IG9jY3VyIGR1cmluZyBjcmVhdGlvbiBvZiB0aGUgc3RyZWFtLCB3aGlsZSB3cml0aW5nIHRvCiAgKiB0aGUgc3RyZWFtLCBvciB3aGVuIHRoZSBzdHJlYW0gaXMgY2xvc2VkLgogICogQSA8Y29kZT5Db3JlRXhjZXB0aW9uPC9jb2RlPiBjb250YWluaW5nCiAgKiBhbiA8Y29kZT5JU3RhdHVzPC9jb2RlPiB3aWxsIGJlIHRocm93bgogICogYXQgc29tZSBwb2ludCBpbiB0aGUgbGlmZWN5Y2xlIG9mIHRoZSBzdHJlYW0KICAqIGlmIHRoZSBmaWxlIHJlc291cmNlIGNhbm5vdCBiZSBjcmVhdGVkLgogICogQHBhcmFtIGZpbGUgVGhlIHtAbGluayBvcmcuZWNsaXBzZS5jb3JlLnJlc291cmNlcy5JRmlsZSBJRmlsZX0KICAqIGhhbmRsZSBvZiB0aGUgZmlsZSByZXNvdXJjZSB0byBjcmVhdGUuIFRoZSBwcm9qZWN0IGltcGxpZWQgYnkgdGhlCiAgKiBwYXRobmFtZSBvZiB0aGUgZmlsZSBtdXN0IGFscmVhZHkgZXhpc3QsCiAgKiB0aGF0IGlzLCB0aGlzIG1ldGhvZCBjYW5ub3QgYmUgdXNlZCB0byBjcmVhdGUgcHJvamVjdHMuCiAgKiBAcGFyYW0gcHJvZ3Jlc3NNb25pdG9yIFRoZSBwcm9ncmVzcyBtb25pdG9yIGZvciB0aGUgb3BlcmF0aW9uLCBvciBudWxsLgogICogQHJldHVybiBBbiA8Y29kZT5PdXRwdXRTdHJlYW08L2NvZGU+IHRpZWQgdG8gdGhlIGZpbGUgcmVzb3VyY2UuCiAgKiBBY3R1YWwgY2hlY2tzIG9mIG9yIGNoYW5nZXMgdG8gdGhlIHdvcmtzcGFjZSBtYXkgb2NjdXIgYXMgZWFybHkgZHVyaW5nCiAgKiBzdHJlYW0gY3JlYXRpb24sIGNsb3N1cmUsIG9yIGFueSB0aW1lIGluIGJldHdlZW4uCiAgKiBAdGhyb3dzIENvcmVFeGNlcHRpb24gQW4gZXhjZXB0aW9uIGNvbnRhaW5pbmcgYW4KICAqIHtAbGluayBvcmcuZWNsaXBzZS5jb3JlLnJ1bnRpbWUuSVN0YXR1cyBJU3RhdHVzfQogICogd2l0aCBhIHNldmVyaXR5IG9mIDxjb2RlPklTdGF0dXMuRVJST1I8L2NvZGU+IGFuZCBhCiAgKiBsb2NhbGUtc3BlY2lmaWMgZGVzY3JpcHRpb24gb2YgdGhlIGNhdXNlLgogICogUmVhc29ucyBpbmNsdWRlOgogICogPG9sPgogICogPGxpPlRoZSBwcm9qZWN0IG9mIHRoZSBnaXZlbiBmaWxlJ3MgcGF0aCBkb2VzIG5vdCBleGlzdC4KICAqIDxsaT5BIG5vbi1maWxlIHJlc291cmNlIG9mIHRoZSBzYW1lIG5hbWUgb2YgdGhlIGdpdmVuIGZpbGUKICAqIGFscmVhZHkgZXhpc3RzLgogICogPGxpPkEgZmlsZSByZXNvdXJjZSBvZiB0aGUgc2FtZSBuYW1lIG9mIHRoZSBnaXZlbiBmaWxlCiAgKiBhbHJlYWR5IGV4aXN0cywgYW5kIDxjb2RlPm92ZXJ3cml0ZUZpbGU8L2NvZGU+IGlzIGZhbHNlLgogICogPGxpPk9uZSBvciBtb3JlIGludGVybWVkaWF0ZSBmb2xkZXJzIHRvIHRoZSBnaXZlbiBmaWxlCiAgKiBkbyBub3QgZXhpc3QsIGFuZCA8Y29kZT5jcmVhdGVGb2xkZXJzPC9jb2RlPiBpcyBmYWxzZS4KICAqIDwvb2w+CiAgKi8KCiAgcHVibGljIHN0YXRpYyBPdXRwdXRTdHJlYW0gbmV3RmlsZU91dHB1dFN0cmVhbSAoCiAgICAgICBSZXNvdXJjZUNvbnRleHQgIGNvbnRleHQsCiAgICAgICBJUGF0aCAgICAgICAgICAgIGZpbGUsCiAgICAgICBJUHJvZ3Jlc3NNb25pdG9yIHByb2dyZXNzTW9uaXRvciwKICAgICAgIElTdGF0dXNIYW5kbGVyICAgIHN0YXR1c0hhbmRsZXIgKQogCiAgewogICAgcmV0dXJuIG5ldyBGaWxlUmVzb3VyY2VPdXRwdXRTdHJlYW0oY29udGV4dCwgZmlsZSwgcHJvZ3Jlc3NNb25pdG9yLCBzdGF0dXNIYW5kbGVyKTsKICB9CgogIC8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQogIC8vIE5hdWdodHkgYml0cy4uLgogIC8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQoKICAvLwogIC8vIENyZWF0ZXMgYSBwYXRoIG9mIGZvbGRlcnMuCiAgLy8gRG8gbm90IGNhbGwgd2l0aCBhbiBhYnNvbHV0ZVBhdGggb2YgbGVzcyB0aGFuIG9uZSBzZWdtZW50LgogIC8vCiAgLyoqCiAgICogQ3JlYXRlcyBhIHBhdGggb2YgZm9sZGVycy4KICAgKiBEbyBub3QgY2FsbCB3aXRoIGFuIGFic29sdXRlUGF0aCBvZiBsZXNzIHRoYW4gb25lIHNlZ21lbnQuCiAgICogQHBhcmFtIHJlc291cmNlQ29udGV4dCB0aGUgcmVzb3VyY2UgY29udGV4dCBmb3IgbWFraW5nIGZvbGRlcnMuCiAgICogQHBhcmFtIGFic29sdXRlUGF0aCB0aGUgcGF0aCBvZiBmb2xkZXJzIHRoYXQgd2lsbCBiZSBjcmVhdGVkLgogICAqIEBwYXJhbSBwcm9ncmVzc01vbml0b3IgdGhlIHByb2dyZXNzIG1vbml0b3IgdG8gYmUgdXNlZC4KICAgKiBAcGFyYW0gc3RhdHVzSGFuZGxlciB0aGUgc3RhdHVzIGhhbmRsZXIuCiAgICogQHJldHVybiByZXR1cm5zIHRoZSBJQ29udGFpbmVyIG9mIHRoZSBjcmVhdGVkIGZvbGRlci4KICAgKi8KICBwdWJsaWMgc3RhdGljIElDb250YWluZXIgbWFrZUZvbGRlclBhdGggKAogICAgUmVzb3VyY2VDb250ZXh0ICByZXNvdXJjZUNvbnRleHQsCiAgICBJUGF0aCAgICAgICAgICAgIGFic29sdXRlUGF0aCwKICAgIElQcm9ncmVzc01vbml0b3IgcHJvZ3Jlc3NNb25pdG9yLAogICAgSVN0YXR1c0hhbmRsZXIgICAgc3RhdHVzSGFuZGxlciApCiAgCiAgICB0aHJvd3MgQ29yZUV4Y2VwdGlvbgogIHsKICAgIGlmIChhYnNvbHV0ZVBhdGguc2VnbWVudENvdW50KCkgPD0gMSkKICAgIHsKICAgICAgcmV0dXJuIGdldFdvcmtzcGFjZVJvb3QoKS5nZXRQcm9qZWN0KGFic29sdXRlUGF0aC5zZWdtZW50KDApKTsKICAgIH0KICAgIGVsc2UKICAgIHsKICAgICAgSUNvbnRhaW5lciBwYXJlbnQgPSBtYWtlRm9sZGVyUGF0aChyZXNvdXJjZUNvbnRleHQsIGFic29sdXRlUGF0aC5yZW1vdmVMYXN0U2VnbWVudHMoMSksIHByb2dyZXNzTW9uaXRvciwgc3RhdHVzSGFuZGxlciApOwogICAgICBTdHJpbmcgZm9sZGVyTmFtZSA9IGFic29sdXRlUGF0aC5sYXN0U2VnbWVudCgpOwogICAgICAKICAgICAgY2hlY2tQYXJlbnQoIHBhcmVudCwgYWJzb2x1dGVQYXRoICk7CiAgICAgIHJldHVybiBtYWtlRm9sZGVyKHJlc291cmNlQ29udGV4dCwgcGFyZW50LGZvbGRlck5hbWUsIHByb2dyZXNzTW9uaXRvciAsIHN0YXR1c0hhbmRsZXIgKTsKICAgIH0KICB9CiAgCiAgcHJpdmF0ZSBzdGF0aWMgdm9pZCBjaGVja1BhcmVudCggSUNvbnRhaW5lciBwYXJlbnQsIElQYXRoIGFic29sdXRlUGF0aCApIHRocm93cyBDb3JlRXhjZXB0aW9uCiAgewogICAgaWYoIHBhcmVudCA9PSBudWxsICkKICAgIHsKICAgICAgLy8gVGhlIHBhcmVudCBpcyBudWxsLCBzbyB0aGVyZSBtdXN0IGhhdmUgYmVlbiBwcm9ibGVtcyBjcmVhdGluZyBpdC4gIFdlIHdpbGwgdGhyb3cKICAgICAgLy8gYSBDb3JlRXhjZXB0aW9uIHdhcm5pbmcgZm9yIHRoaXMgcHJvYmxlbS4KICAgICAgSVBhdGggIHBhcmVudFBhdGggPSBhYnNvbHV0ZVBhdGgucmVtb3ZlTGFzdFNlZ21lbnRzKDEpOwogICAgICBTdHJpbmcgZm9sZGVyUGF0aCA9IGFic29sdXRlUGF0aC5sYXN0U2VnbWVudCgpOwogICAgICB0aHJvdyBuZXcgQ29yZUV4Y2VwdGlvbiggU3RhdHVzVXRpbHMud2FybmluZ1N0YXR1cygKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIE5MUy5iaW5kKEVudmlyb25tZW50TWVzc2FnZXMuTVNHX0VSUk9SX0ZPTERFUl9DUkVBVElPTl9ESVNBQkxFRCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5ldyBPYmplY3RbXXsgcGFyZW50UGF0aC50b1N0cmluZygpLCBmb2xkZXJQYXRofSApICkgKTsKICAgIH0gIAogIH0KICAKICAvLwogIC8vIENyZWF0ZXMgYSBmb2xkZXIgdW5kZXIgYSBjb250YWluZXIuCiAgLy8gVGhlIGNvbnRhaW5lciBtdXN0IGFscmVhZHkgZXhpc3QuCiAgLy8KIHByaXZhdGUgc3RhdGljIElGb2xkZXIgbWFrZUZvbGRlciAoCiAgICBSZXNvdXJjZUNvbnRleHQgIHJlc291cmNlQ29udGV4dCwKICAgIElDb250YWluZXIgICAgICAgcGFyZW50LAogICAgU3RyaW5nICAgICAgICAgICBmb2xkZXJOYW1lLAogICAgSVByb2dyZXNzTW9uaXRvciBwcm9ncmVzc01vbml0b3IsCiAgICBJU3RhdHVzSGFuZGxlciAgICBzdGF0dXNIYW5kbGVyICkKICAKICB0aHJvd3MgQ29yZUV4Y2VwdGlvbgogIHsKICAgIElSZXNvdXJjZSBjaGlsZCAgPSBwYXJlbnQuZmluZE1lbWJlcihmb2xkZXJOYW1lKTsKICAgIENob2ljZSAgICByZXN1bHQgPSBudWxsOwogICAgCiAgICBpZiggY2hpbGQgPT0gbnVsbCApCiAgICB7CiAgICAgIGlmICghcmVzb3VyY2VDb250ZXh0LmlzQ3JlYXRlRm9sZGVyc0VuYWJsZWQoKSkgIAogICAgICB7CiAgICAgICAgcmVzdWx0ID0gc3RhdHVzSGFuZGxlci5yZXBvcnQoCiAgICAgICAgICAgICAgICBTdGF0dXNVdGlscy53YXJuaW5nU3RhdHVzKAogICAgICAgICAgICAgICAgCQlOTFMuYmluZChFbnZpcm9ubWVudE1lc3NhZ2VzLk1TR19FUlJPUl9GT0xERVJfQ1JFQVRJT05fRElTQUJMRUQsCiAgICAgICAgCSAgICAgICAgICAgICAgICAgICAgICBuZXcgT2JqZWN0W117IHBhcmVudC5nZXRGdWxsUGF0aCgpLnRvU3RyaW5nKCksIGZvbGRlck5hbWV9ICkgKSwgCiAgICAgICAgICAgICAgICBnZXRUaHJlZVN0YXRlRmlsZU9wdGlvbnMoKSApOwogICAgICAgIAogICAgICAgIGlmKCByZXN1bHQgPT0gbnVsbCB8fCByZXN1bHQuZ2V0U2hvcnRjdXQoKSA9PSAnQycgKQogICAgICAgIHsKICAgICAgICAgIHJldHVybiBudWxsOwogICAgICAgIH0KICAgICAgICBlbHNlIGlmKCByZXN1bHQuZ2V0U2hvcnRjdXQoKSA9PSAnQScgKQogICAgICAgIHsKICAgICAgICAgIHJlc291cmNlQ29udGV4dC5zZXRDcmVhdGVGb2xkZXJzRW5hYmxlZCh0cnVlKTsKICAgICAgICAgIFBlcnNpc3RlbnRSZXNvdXJjZUNvbnRleHQuZ2V0SW5zdGFuY2UoKS5zZXRDcmVhdGVGb2xkZXJzRW5hYmxlZCh0cnVlKTsKICAgICAgICB9CiAgICAgIH0KICAgICAgCiAgICAgIElGb2xkZXIgZm9sZGVyID0gcGFyZW50LmdldEZvbGRlcihuZXcgUGF0aChmb2xkZXJOYW1lKSk7CiAgICAgIGZvbGRlci5jcmVhdGUodHJ1ZSx0cnVlLG51bGwpOwogICAgICByZXR1cm4gZm9sZGVyOwogICAgfQogICAgZWxzZSBpZiggY2hpbGQuZ2V0VHlwZSgpID09IElSZXNvdXJjZS5GT0xERVIgKQogICAgewogICAgICByZXR1cm4gKElGb2xkZXIpY2hpbGQ7CiAgICB9CiAgICBlbHNlCiAgICB7CiAgICAgIHRocm93IG5ldyBDb3JlRXhjZXB0aW9uKAogICAgICAgIG5ldyBTdGF0dXMoIElTdGF0dXMuRVJST1IsIAogICAgICAgICAgICAgICAgICAgICJSZXNvdXJjZVV0aWxzIiwKICAgICAgICAgICAgICAgICAgICAwLCAKICAgICAgICAgICAgICAgICAgICBOTFMuYmluZChFbnZpcm9ubWVudE1lc3NhZ2VzLk1TR19FUlJPUl9SRVNPVVJDRV9OT1RfRk9MREVSLAoJCQkJCSAgICAgICAgICAgICAgICAgbmV3IE9iamVjdFtdeyBwYXJlbnQuZ2V0RnVsbFBhdGgoKS5hcHBlbmQoZm9sZGVyTmFtZSkudG9TdHJpbmcoKSB9KSwKCQkJbnVsbCApICk7CiAgICB9CiAgfQoKICAvLwogIC8vIENyZWF0ZXMgYSBmaWxlIHVuZGVyIGEgY29udGFpbmVyLgogIC8vIFRoZSBjb250YWluZXIgbXVzdCBhbHJlYWR5IGV4aXN0LgogIC8vCiBwcml2YXRlIHN0YXRpYyBJRmlsZSBtYWtlRmlsZSAoCiAgICBSZXNvdXJjZUNvbnRleHQgIHJlc291cmNlQ29udGV4dCwKICAgIElDb250YWluZXIgICAgICAgcGFyZW50LAogICAgU3RyaW5nICAgICAgICAgICBmaWxlTmFtZSwKICAgIElucHV0U3RyZWFtICAgICAgaW5wdXRTdHJlYW0sCiAgICBJUHJvZ3Jlc3NNb25pdG9yIHByb2dyZXNzTW9uaXRvciwKICAgIElTdGF0dXNIYW5kbGVyICAgIHN0YXR1c0hhbmRsZXIgKQogCiAgICB0aHJvd3MgQ29yZUV4Y2VwdGlvbgogIHsKCSBJRmlsZSBmaWxlID0gcGFyZW50LmdldEZpbGUoIG5ldyBQYXRoKGZpbGVOYW1lKSApOwoKCSAvLyBjcmVhdGUgdGhlIGZpbGUgaWYgaXQgZG9lc24ndCBleGlzdAoJIGlmICghZmlsZS5leGlzdHMoKSkgewoJCSB0cnkgewoJCQkgZmlsZS5jcmVhdGUoIGlucHV0U3RyZWFtLCB0cnVlLCBudWxsKTsgICAgCgkJCSByZXR1cm4gZmlsZTsKCQkgfSBjYXRjaCAoQ29yZUV4Y2VwdGlvbiBjb3JlRXhjZXB0aW9uKSB7CgkJCSAvLyB0aGlzIGVycm9yIG9ubHkgaGFwcGVucyBpbiBhIGNhc2UtaW5zZW5zaXRpdmUgZmlsZSBzeXN0ZW07IHNvIGlnbm9yZSB0aGUgY2FzZXMuCgkJCSBpZiAoY29yZUV4Y2VwdGlvbi5nZXRTdGF0dXMoKS5nZXRDb2RlKCkgPT0gSVJlc291cmNlU3RhdHVzLkNBU0VfVkFSSUFOVF9FWElTVFMpIHsKCQkJCSBib29sZWFuIGZvdW5kSWdub3JpbmdDYXNlID0gZmFsc2U7CgoJCQkJIGZvciAoSVJlc291cmNlIHJlc291cmNlIDogcGFyZW50Lm1lbWJlcnMoKSkgewoJCQkJCSBpZiAocmVzb3VyY2UuZ2V0TmFtZSgpLmVxdWFsc0lnbm9yZUNhc2UoZmlsZU5hbWUpKSB7CgkJCQkJCSAvLyBmb3VuZCB0aGUgZmlsZQoJCQkJCQkgZm91bmRJZ25vcmluZ0Nhc2UgPSB0cnVlOwoJCQkJCQkgZmlsZU5hbWUgPSByZXNvdXJjZS5nZXROYW1lKCk7CgkJCQkJCSBmaWxlID0gcGFyZW50LmdldEZpbGUoIG5ldyBQYXRoKGZpbGVOYW1lKSk7CgkJCQkJCSBicmVhazsKCQkJCQkgfQoJCQkJIH0KCgkJCQkgLy8gY2FuJ3QgZmluZCB0aGUgZmlsZSBjYXVzaW5nIHRoZSBDQVNFX1ZBUklBTlRfRVhJU1RTIGV4Y2VwdGlvbjsgdGhyb3cgdGhlIGV4Y2VwdGlvbgoJCQkJIGlmICghZm91bmRJZ25vcmluZ0Nhc2UpCgkJCQkJIHRocm93IGNvcmVFeGNlcHRpb247CgkJCSB9IGVsc2UgewoJCQkJIC8vIHRocm93IG90aGVyIGV4Y2VwdGlvbnMKCQkJCSB0aHJvdyBjb3JlRXhjZXB0aW9uOwoJCQkgfQoJCSB9CgkgfQoKCSAKICAgIENob2ljZSAgICByZXN1bHQgPSBudWxsOwogICAgCgogICAgaWYoIGZpbGUuZ2V0VHlwZSgpID09IElSZXNvdXJjZS5GSUxFICkKICAgIHsKICAgICAgaWYoICFyZXNvdXJjZUNvbnRleHQuaXNPdmVyd3JpdGVGaWxlc0VuYWJsZWQoKSApICAgCiAgICAgIHsKICAgICAgICByZXN1bHQgPSBzdGF0dXNIYW5kbGVyLnJlcG9ydCggCiAgICAgICAgICAgICAgU3RhdHVzVXRpbHMud2FybmluZ1N0YXR1cyggTkxTLmJpbmQoRW52aXJvbm1lbnRNZXNzYWdlcy5NU0dfRVJST1JfRklMRV9PVkVSV1JJVEVfRElTQUJMRUQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbmV3IE9iamVjdFtdIHtwYXJlbnQuZ2V0RnVsbFBhdGgoKS50b1N0cmluZygpLGZpbGVOYW1lfSkgKSwJCQkJCSAgCQkgICAgCiAgICAgICAgICAgICAgZ2V0VGhyZWVTdGF0ZUZpbGVPcHRpb25zKCkgKTsKICAgICAgICAKICAgICAgICBpZiggcmVzdWx0ID09IG51bGwgfHwgcmVzdWx0LmdldFNob3J0Y3V0KCkgPT0gJ0MnICkKICAgICAgICB7CiAgICAgICAgICByZXR1cm4gbnVsbDsKICAgICAgICB9CiAgICAgICAgZWxzZSBpZiggcmVzdWx0LmdldFNob3J0Y3V0KCkgPT0gJ0EnICkKICAgICAgICB7CiAgICAgICAgICByZXNvdXJjZUNvbnRleHQuc2V0T3ZlcndyaXRlRmlsZXNFbmFibGVkKHRydWUpOwogICAgICAgICAgUGVyc2lzdGVudFJlc291cmNlQ29udGV4dC5nZXRJbnN0YW5jZSgpLnNldE92ZXJ3cml0ZUZpbGVzRW5hYmxlZCh0cnVlKTsKICAgICAgICB9CiAgICAgIH0JCiAgICAgICAgCiAgICAgIC8vV2UgaGF2ZSBwZXJtaXNzaW9uIHRvIG92ZXJ3cml0ZSBzbyBjaGVjayBpZiBmaWxlIGlzIHJlYWQtb25seQogICAgICBpZiggZmlsZS5nZXRSZXNvdXJjZUF0dHJpYnV0ZXMoKSA9PSBudWxsICkKICAgICAgewogICAgICAJLy8gcmVzb3VyY2UgaXMgbGlrZWx5IG91dC1vZi1zeW5jIHdpdGggZmlsZXN5c3RlbQogICAgICAJdGhyb3cgbmV3IENvcmVFeGNlcHRpb24oIAogICAgICAJICAgICAgICAgIG5ldyBTdGF0dXMoIElTdGF0dXMuRVJST1IsCiAgICAgIAkgICAgICAgICAgICAgICAgICAgICAgIlJlc291cmNlVXRpbHMiLAogICAgICAJICAgICAgICAgICAgICAgICAgICAgIDAsIAogICAgICAJICAgICAgICAgICAgICAgICAgICAgIGZpbGUuZ2V0RnVsbFBhdGgoKS50b1N0cmluZygpLAogICAgICAJCQkJCQkgIG51bGwgKSApOwogICAgICB9CiAgICAgIGVsc2UgaWYoIGZpbGUuZ2V0UmVzb3VyY2VBdHRyaWJ1dGVzKCkuaXNSZWFkT25seSgpICkKICAgICAgewogICAgICAgIGlmKCAhcmVzb3VyY2VDb250ZXh0LmlzQ2hlY2tvdXRGaWxlc0VuYWJsZWQoKSApIAogICAgICAgIHsgICAgICAgICAgICAKICAgICAgICAgIHJlc3VsdCA9IHN0YXR1c0hhbmRsZXIucmVwb3J0KCAKICAgICAgICAgICAgICAgICAgICAgICBTdGF0dXNVdGlscy5lcnJvclN0YXR1cyggTkxTLmJpbmQoRW52aXJvbm1lbnRNZXNzYWdlcy5NU0dfRVJST1JfRklMRV9DSEVDS09VVF9ESVNBQkxFRCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbmV3IE9iamVjdFtdeyBwYXJlbnQuZ2V0RnVsbFBhdGgoKS50b1N0cmluZygpLGZpbGVOYW1lfSApICksIAogICAgICAgICAgICAgICAgICAgICAgIGdldFRocmVlU3RhdGVGaWxlT3B0aW9ucygpICk7CiAgICAgICAgICAKICAgICAgICAgIGlmKCByZXN1bHQgPT0gbnVsbCB8fCByZXN1bHQuZ2V0U2hvcnRjdXQoKSA9PSAnQycgKQogICAgICAgICAgewogICAgICAgICAgICByZXR1cm4gbnVsbDsKCQkgIH0KICAgICAgICAgIGVsc2UgaWYoIHJlc3VsdC5nZXRTaG9ydGN1dCgpID09ICdBJyApCiAgICAgICAgICB7CiAgICAgICAgICAgIHJlc291cmNlQ29udGV4dC5zZXRDaGVja291dEZpbGVzRW5hYmxlZCh0cnVlKTsKICAgICAgICAgICAgUGVyc2lzdGVudFJlc291cmNlQ29udGV4dC5nZXRJbnN0YW5jZSgpLnNldENoZWNrb3V0RmlsZXNFbmFibGVkKHRydWUpOwogICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgSUZpbGVbXSBmaWxlcyA9IG5ldyBJRmlsZVsxXTsKICAgICAgICBmaWxlc1swXSA9IChJRmlsZSlmaWxlOwogICAgICAgICAgCiAgICAgICAgSVN0YXR1cyBzdGF0dXMgPSBnZXRXb3Jrc3BhY2UoKS52YWxpZGF0ZUVkaXQoZmlsZXMsbnVsbCk7CiAgICAgICAgCiAgICAgICAgdHJ5CiAgICAgICAgewogICAgICAgICAgc3RhdHVzSGFuZGxlci5yZXBvcnQoIHN0YXR1cyApOwogICAgICAgIH0KICAgICAgICBjYXRjaCggU3RhdHVzRXhjZXB0aW9uIGV4YyApCiAgICAgICAgewogICAgICAgICAgcmV0dXJuIG51bGw7CiAgICAgICAgfQogICAgICB9CiAgICAgIGZpbGUuc2V0Q29udGVudHMoIGlucHV0U3RyZWFtLCB0cnVlLCB0cnVlLCBudWxsICk7CiAgICAgICAgCiAgICAgIHJldHVybiBmaWxlOwogICAgICAKICAgIH0KICAgIGVsc2UKICAgIHsKICAgICAgdGhyb3cgbmV3IENvcmVFeGNlcHRpb24oIAogICAgICAgIG5ldyBTdGF0dXMoIElTdGF0dXMuRVJST1IsCiAgICAgICAgICAgICAgICAgICAgIlJlc291cmNlVXRpbHMiLAogICAgICAgICAgICAgICAgICAgIDAsIAogICAgICAgICAgICAgICAgICAgIE5MUy5iaW5kKEVudmlyb25tZW50TWVzc2FnZXMuTVNHX0VSUk9SX1JFU09VUkNFX05PVF9GSUxFLAoJCSAgICAgICAgICAgICAgICAgICAgICAgbmV3IE9iamVjdFtdIHtwYXJlbnQuZ2V0RnVsbFBhdGgoKS5hcHBlbmQoZmlsZU5hbWUpfSksCgkJICAgICAgICAgICAgICAgICAgICAgICBudWxsICkgKTsKICAgIH0KICB9CgogCiAvKioKICAgKiBDcmVhdGVzIGEgZmlsZSBvZiB0aGUgZ2l2ZW4gPGNvZGU+YWJzb2x1dGVQYXRoPC9jb2RlPgogICAqIGFuZCByZXR1cm5zIGl0cyBoYW5kbGUgYXMgYW4gPGNvZGU+SUZpbGU8L2NvZGU+LgogICAqIElmIHRoZSBmaWxlIGNhbm5vdCBiZSBjcmVhdGVkLCBhCiAgICogPGNvZGU+Q29yZUV4Y2VwdGlvbjwvY29kZT4gY29udGFpbmluZyBhbgogICAqIDxjb2RlPklTdGF0dXM8L2NvZGU+IG9iamVjdCBpcyB0aHJvd24uCiAgICogQHBhcmFtIGFic29sdXRlUGF0aCBUaGUgYWJzb2x1dGUgcGF0aCBvZiB0aGUgZmlsZSB0byBjcmVhdGUuCiAgICogVGhlIHByb2plY3QgYXQgdGhlIGJlZ2lubmluZyBvZiB0aGUgcGF0aCBtdXN0IGFscmVhZHkgZXhpc3QsCiAgICogdGhhdCBpcywgdGhpcyBtZXRob2QgY2Fubm90IGJlIHVzZWQgdG8gY3JlYXRlIHByb2plY3RzLgogICAqIEBwYXJhbSBwcm9ncmVzc01vbml0b3IgVGhlIHByb2dyZXNzIG1vbml0b3IgZm9yIHRoZSBvcGVyYXRpb24sIG9yIG51bGwuCiAgICogQHJldHVybiBUaGUge0BsaW5rIG9yZy5lY2xpcHNlLmNvcmUucmVzb3VyY2VzLklGaWxlIElGaWxlfQogICAqIGhhbmRsZSBvZiB0aGUgZmlsZS4KICAgKiBAdGhyb3dzIENvcmVFeGNlcHRpb24gQW4gZXhjZXB0aW9uIGNvbnRhaW5pbmcgYW4KICAgKiB7QGxpbmsgb3JnLmVjbGlwc2UuY29yZS5ydW50aW1lLklTdGF0dXMgSVN0YXR1c30KICAgKiB3aXRoIGEgc2V2ZXJpdHkgb2YgPGNvZGU+SVN0YXR1cy5FUlJPUjwvY29kZT4gYW5kIGEKICAgKiBsb2NhbGUtc3BlY2lmaWMgZGVzY3JpcHRpb24gb2YgdGhlIGNhdXNlLgogICAqLwogICBwdWJsaWMgc3RhdGljIElGaWxlIGNyZWF0ZUZpbGVBdExvY2F0aW9uICgKICAgICBSZXNvdXJjZUNvbnRleHQgcmVzb3VyY2VDb250ZXh0LAogICAgIElQYXRoICAgICAgICAgICBhYnNvbHV0ZVBhdGgsCiAgICAgSW5wdXRTdHJlYW0gICAgIGlucHV0U3RyZWFtLAogICAgIElQcm9ncmVzc01vbml0b3IgcHJvZ3Jlc3NNb25pdG9yLAogICAgIElTdGF0dXNIYW5kbGVyICAgc3RhdHVzSGFuZGxlciApCgogICAgIHRocm93cyBDb3JlRXhjZXB0aW9uIAogICB7ICAgIAogICAgIGlmICghYWJzb2x1dGVQYXRoLmlzQWJzb2x1dGUoKSkKICAgICB7CiAgICAgICB0aHJvdyBuZXcgQ29yZUV4Y2VwdGlvbihuZXcgU3RhdHVzKElTdGF0dXMuRVJST1IsICJSZXNvdXJjZVV0aWxzIiwwLE5MUy5iaW5kKEVudmlyb25tZW50TWVzc2FnZXMuTVNHX0VSUk9SX1BBVEhfTk9UX0FCU09MVVRFLG5ldyBPYmplY3RbXSB7YWJzb2x1dGVQYXRoLnRvU3RyaW5nKCl9KSxudWxsKSk7CiAgICAgfQogICAgIGlmIChhYnNvbHV0ZVBhdGguc2VnbWVudENvdW50KCkgPCAxKQogICAgIHsKICAgICAgIHRocm93IG5ldyBDb3JlRXhjZXB0aW9uKG5ldyBTdGF0dXMoSVN0YXR1cy5FUlJPUiwiUmVzb3VyY2VVdGlscyIsMCxOTFMuYmluZChFbnZpcm9ubWVudE1lc3NhZ2VzLk1TR19FUlJPUl9QQVRIX0VNUFRZLG5ldyBPYmplY3RbXSB7YWJzb2x1dGVQYXRoLnRvU3RyaW5nKCl9KSxudWxsKSk7CiAgICAgfQogICAgIGlmIChhYnNvbHV0ZVBhdGguc2VnbWVudENvdW50KCkgPCAyKQogICAgIHsKICAgICAgIHRocm93IG5ldyBDb3JlRXhjZXB0aW9uKG5ldyBTdGF0dXMoSVN0YXR1cy5FUlJPUiwiUmVzb3VyY2VVdGlscyIsMCxOTFMuYmluZChFbnZpcm9ubWVudE1lc3NhZ2VzLk1TR19FUlJPUl9QQVRIX05PVF9GT0xERVIsbmV3IE9iamVjdFtdIHthYnNvbHV0ZVBhdGgudG9TdHJpbmcoKX0pLG51bGwpKTsKICAgICB9CiAgICAgSUNvbnRhaW5lciBwYXJlbnQgICA9IG1ha2VGb2xkZXJQYXRoQXRMb2NhdGlvbihyZXNvdXJjZUNvbnRleHQsIGFic29sdXRlUGF0aC5yZW1vdmVMYXN0U2VnbWVudHMoMSksIHByb2dyZXNzTW9uaXRvciwgc3RhdHVzSGFuZGxlcik7CiAgICAgU3RyaW5nICAgICBmaWxlTmFtZSA9IGFic29sdXRlUGF0aC5sYXN0U2VnbWVudCgpOwogICAgIAogICAgIGNoZWNrUGFyZW50KCBwYXJlbnQsIGFic29sdXRlUGF0aCApOwogICAgIAogICAgIHJldHVybiBtYWtlRmlsZShyZXNvdXJjZUNvbnRleHQsIHBhcmVudCwgZmlsZU5hbWUsIGlucHV0U3RyZWFtLCBwcm9ncmVzc01vbml0b3IsIHN0YXR1c0hhbmRsZXIpOwogICB9CgovKioKICAqIENyZWF0ZXMgYSBwYXRoIG9mIGZvbGRlcnMgdXNpbmcgYWJzb2x1dGUgZmlsZW5hbWVzLgogICogRG8gbm90IGNhbGwgd2l0aCBhbiBhYnNvbHV0ZVBhdGggb2YgbGVzcyB0aGFuIG9uZSBzZWdtZW50LgogICogQHBhcmFtIHJlc291cmNlQ29udGV4dCB0aGUgcmVzb3VyY2UgY29udGV4dCBmb3IgbWFraW5nIGZvbGRlcnMuCiAgKiBAcGFyYW0gcmVzb3VyY2UgdGhlIHJlc291cmNlIHRoYXQgd2lsbCBiZSBjcmVhdGVkLgogICogQHBhcmFtIHByb2dyZXNzTW9uaXRvciB0aGUgcHJvZ3Jlc3MgbW9uaXRvciB0byBiZSB1c2VkLgogICogQHBhcmFtIHN0YXR1c0hhbmRsZXIgdGhlIHN0YXR1cyBoYW5kbGVyLgogICogQHJldHVybiByZXR1cm5zIHRoZSBJQ29udGFpbmVyIG9mIHRoZSBjcmVhdGVkIGZvbGRlci4KICAqLwogcHVibGljIHN0YXRpYyBJQ29udGFpbmVyIG1ha2VGb2xkZXJQYXRoQXRMb2NhdGlvbiAoCiAgIFJlc291cmNlQ29udGV4dCAgcmVzb3VyY2VDb250ZXh0LAogICBJQ29udGFpbmVyICAgICAgIHJlc291cmNlLAogICBJUHJvZ3Jlc3NNb25pdG9yIHByb2dyZXNzTW9uaXRvciwKICAgSVN0YXR1c0hhbmRsZXIgICBzdGF0dXNIYW5kbGVyICkKIAogICB0aHJvd3MgQ29yZUV4Y2VwdGlvbgogICB7CgkgaWYgKHJlc291cmNlLmV4aXN0cygpKQoJIHsKCQkgaWYgKHJlc291cmNlIGluc3RhbmNlb2YgSUNvbnRhaW5lcikKCQkgewoJCQkgcmV0dXJuIChJQ29udGFpbmVyKSByZXNvdXJjZTsKCQkgfQoJCSBlbHNlCgkJIHsKCQkJIHRocm93IG5ldyBDb3JlRXhjZXB0aW9uKAoJCQkJCSBuZXcgU3RhdHVzKCBJU3RhdHVzLkVSUk9SLCAKCQkJCQkJCSAiUmVzb3VyY2VVdGlscyIsCgkJCQkJCQkgMCwgCgkJCQkJCQkgTkxTLmJpbmQoRW52aXJvbm1lbnRNZXNzYWdlcy5NU0dfRVJST1JfUkVTT1VSQ0VfTk9UX0ZPTERFUiwKCQkJCQkJCQkJIG5ldyBPYmplY3RbXXsgcmVzb3VyY2UuZ2V0RnVsbFBhdGgoKS50b1N0cmluZygpIH0pLAoJCQkJCQkJCQkgbnVsbCApICk7CgkJIH0KCSB9CgkgZWxzZQoJIHsKCQkgSUNvbnRhaW5lciBwYXJlbnQgPSBtYWtlRm9sZGVyUGF0aEF0TG9jYXRpb24ocmVzb3VyY2VDb250ZXh0LCByZXNvdXJjZS5nZXRQYXJlbnQoKSwgcHJvZ3Jlc3NNb25pdG9yLCBzdGF0dXNIYW5kbGVyICk7CgkJIFN0cmluZyBmb2xkZXJOYW1lID0gcmVzb3VyY2UuZ2V0TmFtZSgpOwoJCSAKCQkgcmV0dXJuIG1ha2VGb2xkZXIocmVzb3VyY2VDb250ZXh0LCBwYXJlbnQsIGZvbGRlck5hbWUsIHByb2dyZXNzTW9uaXRvciAsIHN0YXR1c0hhbmRsZXIgKTsKCSB9CiB9CiAKIC8qKgogICogQ3JlYXRlcyBhIHBhdGggb2YgZm9sZGVycy4KICAqIERvIG5vdCBjYWxsIHdpdGggYW4gYWJzb2x1dGVQYXRoIG9mIGxlc3MgdGhhbiBvbmUgc2VnbWVudC4KICAqIEBwYXJhbSByZXNvdXJjZUNvbnRleHQgdGhlIHJlc291cmNlIGNvbnRleHQgZm9yIG1ha2luZyBmb2xkZXJzLgogICogQHBhcmFtIGFic29sdXRlUGF0aCB0aGUgcGF0aCBvZiBmb2xkZXJzIHRoYXQgd2lsbCBiZSBjcmVhdGVkLgogICogQHBhcmFtIHByb2dyZXNzTW9uaXRvciB0aGUgcHJvZ3Jlc3MgbW9uaXRvciB0byBiZSB1c2VkLgogICogQHBhcmFtIHN0YXR1c0hhbmRsZXIgdGhlIHN0YXR1cyBoYW5kbGVyLgogICogQHJldHVybiByZXR1cm5zIHRoZSBJQ29udGFpbmVyIG9mIHRoZSBjcmVhdGVkIGZvbGRlci4KICAqLwogcHVibGljIHN0YXRpYyBJQ29udGFpbmVyIG1ha2VGb2xkZXJQYXRoQXRMb2NhdGlvbiAoCiAgIFJlc291cmNlQ29udGV4dCAgcmVzb3VyY2VDb250ZXh0LAogICBJUGF0aCAgICAgICAgICAgIGFic29sdXRlUGF0aCwKICAgSVByb2dyZXNzTW9uaXRvciBwcm9ncmVzc01vbml0b3IsCiAgIElTdGF0dXNIYW5kbGVyICAgIHN0YXR1c0hhbmRsZXIgKQogCiAgIHRocm93cyBDb3JlRXhjZXB0aW9uCiB7CiAJcmV0dXJuIG1ha2VGb2xkZXJQYXRoQXRMb2NhdGlvbihyZXNvdXJjZUNvbnRleHQsCiAJCWdldFdvcmtzcGFjZVJvb3QoKS5nZXRDb250YWluZXJGb3JMb2NhdGlvbihhYnNvbHV0ZVBhdGgpLAogCQlwcm9ncmVzc01vbml0b3IsIHN0YXR1c0hhbmRsZXIpOwogfQogCiAKCn0K