LyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogQ29weXJpZ2h0IChjKSAyMDAxLCAyMDA3IElCTSBDb3Jwb3JhdGlvbiBhbmQgb3RoZXJzLgogKiBBbGwgcmlnaHRzIHJlc2VydmVkLiBUaGlzIHByb2dyYW0gYW5kIHRoZSBhY2NvbXBhbnlpbmcgbWF0ZXJpYWxzCiAqIGFyZSBtYWRlIGF2YWlsYWJsZSB1bmRlciB0aGUgdGVybXMgb2YgdGhlIEVjbGlwc2UgUHVibGljIExpY2Vuc2UgdjEuMAogKiB3aGljaCBhY2NvbXBhbmllcyB0aGlzIGRpc3RyaWJ1dGlvbiwgYW5kIGlzIGF2YWlsYWJsZSBhdAogKiBodHRwOi8vd3d3LmVjbGlwc2Uub3JnL2xlZ2FsL2VwbC12MTAuaHRtbAogKgogKiBDb250cmlidXRvcnM6CiAqIElCTSBDb3Jwb3JhdGlvbiAtIGluaXRpYWwgQVBJIGFuZCBpbXBsZW1lbnRhdGlvbgogKiB5eXl5bW1kZCBidWcgICAgICBFbWFpbCBhbmQgb3RoZXIgY29udGFjdCBpbmZvcm1hdGlvbgogKiAtLS0tLS0tLSAtLS0tLS0tLSAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQogKiAyMDA2MDExMiAgIDEyMTE5OSBqZXNwZXJAc2Vsc2thYmV0Lm9yZyAtIEplc3BlciBN+GxsZXIKICogMjAwNzA4MTMgICAxODg5OTkgcG1vb2drQGNhLmlibS5jb20gLSBQZXRlciBNb29nawogKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8KcGFja2FnZSBvcmcuZWNsaXBzZS53c3QuY29tbWFuZC5pbnRlcm5hbC5lbnYuY29tbW9uOwoKCmltcG9ydCBqYXZhLmlvLklPRXhjZXB0aW9uOwppbXBvcnQgamF2YS5pby5JbnB1dFN0cmVhbTsKaW1wb3J0IGphdmEuaW8uT3V0cHV0U3RyZWFtOwppbXBvcnQgamF2YS51dGlsLlZlY3RvcjsKCmltcG9ydCBvcmcuZWNsaXBzZS5jb3JlLnJlc291cmNlcy5JQ29udGFpbmVyOwppbXBvcnQgb3JnLmVjbGlwc2UuY29yZS5yZXNvdXJjZXMuSUZpbGU7CmltcG9ydCBvcmcuZWNsaXBzZS5jb3JlLnJlc291cmNlcy5JRm9sZGVyOwppbXBvcnQgb3JnLmVjbGlwc2UuY29yZS5yZXNvdXJjZXMuSVByb2plY3Q7CmltcG9ydCBvcmcuZWNsaXBzZS5jb3JlLnJlc291cmNlcy5JUmVzb3VyY2U7CmltcG9ydCBvcmcuZWNsaXBzZS5jb3JlLnJlc291cmNlcy5JV29ya3NwYWNlOwppbXBvcnQgb3JnLmVjbGlwc2UuY29yZS5yZXNvdXJjZXMuSVdvcmtzcGFjZVJvb3Q7CmltcG9ydCBvcmcuZWNsaXBzZS5jb3JlLnJlc291cmNlcy5SZXNvdXJjZXNQbHVnaW47CmltcG9ydCBvcmcuZWNsaXBzZS5jb3JlLnJ1bnRpbWUuQ29yZUV4Y2VwdGlvbjsKaW1wb3J0IG9yZy5lY2xpcHNlLmNvcmUucnVudGltZS5JUGF0aDsKaW1wb3J0IG9yZy5lY2xpcHNlLmNvcmUucnVudGltZS5JUHJvZ3Jlc3NNb25pdG9yOwppbXBvcnQgb3JnLmVjbGlwc2UuY29yZS5ydW50aW1lLklTdGF0dXM7CmltcG9ydCBvcmcuZWNsaXBzZS5jb3JlLnJ1bnRpbWUuUGF0aDsKaW1wb3J0IG9yZy5lY2xpcHNlLmNvcmUucnVudGltZS5QbHVnaW47CmltcG9ydCBvcmcuZWNsaXBzZS5jb3JlLnJ1bnRpbWUuU3RhdHVzOwppbXBvcnQgb3JnLmVjbGlwc2Uub3NnaS51dGlsLk5MUzsKaW1wb3J0IG9yZy5lY2xpcHNlLndzdC5jb21tYW5kLmludGVybmFsLmVudi5FbnZpcm9ubWVudE1lc3NhZ2VzOwppbXBvcnQgb3JnLmVjbGlwc2Uud3N0LmNvbW1hbmQuaW50ZXJuYWwuZW52LmNvcmUuY29tbW9uLlN0YXR1c1V0aWxzOwppbXBvcnQgb3JnLmVjbGlwc2Uud3N0LmNvbW1hbmQuaW50ZXJuYWwuZW52LmNvcmUuY29udGV4dC5SZXNvdXJjZUNvbnRleHQ7CmltcG9ydCBvcmcuZWNsaXBzZS53c3QuY29tbW9uLmVudmlyb25tZW50LkNob2ljZTsKaW1wb3J0IG9yZy5lY2xpcHNlLndzdC5jb21tb24uZW52aXJvbm1lbnQuSVN0YXR1c0hhbmRsZXI7CmltcG9ydCBvcmcuZWNsaXBzZS53c3QuY29tbW9uLmVudmlyb25tZW50LlN0YXR1c0V4Y2VwdGlvbjsKCgoKLyoqCiogVGhpcyBjbGFzcyBjb250YWlucyB1c2VmdWwgbWV0aG9kcyBmb3Igd29ya2luZyB3aXRoIEVjbGlwc2UgcmVzb3VyY2VzLgoqLwpwdWJsaWMgZmluYWwgY2xhc3MgRmlsZVJlc291cmNlVXRpbHMKewogIC8vCiAgLy8gS2VlcHMgdGhlIElXb3Jrc3BhY2UgaGFuZ2luZyBhcm91bmQuIFNlZSBnZXRXb3Jrc3BhY2UoKS4KICAvLwogIHByaXZhdGUgc3RhdGljIElXb3Jrc3BhY2Ugd29ya3NwYWNlXyA9IG51bGw7CiAgLy8KICAvLyBLZWVwcyB0aGUgSVdvcmtzcGFjZVJvb3QgaGFuZ2luZyBhcm91bmQuIFNlZSBnZXRXb3Jrc3BhY2VSb290KCkuCiAgLy8KICBwcml2YXRlIHN0YXRpYyBJV29ya3NwYWNlUm9vdCByb290XyA9IG51bGw7CiAgCi8vICBwcml2YXRlIHN0YXRpYyBNZXNzYWdlVXRpbHMgbXNnXyA9IG5ldyBNZXNzYWdlVXRpbHMoICJvcmcuZWNsaXBzZS53c3QuY29tbWFuZC5pbnRlcm5hbC5lbnYuY29tbW9uLmVudmlyb25tZW50IiwgbmV3IEZpbGVSZXNvdXJjZVV0aWxzKCkgKTsKCgogLyoqCiAgKiBSZXR1cm5zIHRoZSBJV29ya3NwYWNlUm9vdCBvYmplY3QuCiAgKiBAcmV0dXJuIFRoZSBJV29ya3NwYWNlUm9vdCBvYmplY3QuCiAgKi8KICBwdWJsaWMgc3RhdGljIElXb3Jrc3BhY2VSb290IGdldFdvcmtzcGFjZVJvb3QgKCkKICB7CiAgICBpZiAocm9vdF8gPT0gbnVsbCkKICAgIHsKICAgICAgcm9vdF8gPSBSZXNvdXJjZXNQbHVnaW4uZ2V0V29ya3NwYWNlKCkuZ2V0Um9vdCgpOwogICAgfQogICAgcmV0dXJuIHJvb3RfOwogIH0KCiAgLyoqCgkgKiBSZXR1cm5zIHRoZSBJV29ya3NwYWNlIG9iamVjdC4KCSAqIAoJICogQHJldHVybiBUaGUgSVdvcmtzcGFjZSBvYmplY3QuCgkgKi8KICBwdWJsaWMgc3RhdGljIElXb3Jrc3BhY2UgZ2V0V29ya3NwYWNlICgpCiAgewogICAgaWYgKHdvcmtzcGFjZV8gPT0gbnVsbCkKICAgIHsKICAgICAgaWYgKHJvb3RfID09IG51bGwpCiAgICAgIHsKICAgICAgICByb290XyA9IFJlc291cmNlc1BsdWdpbi5nZXRXb3Jrc3BhY2UoKS5nZXRSb290KCk7CiAgICAgIH0KICAgICAgCiAgICAgIHdvcmtzcGFjZV8gPSByb290Xy5nZXRXb3Jrc3BhY2UoKTsKICAgIH0KICAgIAogICAgcmV0dXJuIHdvcmtzcGFjZV87CiAgfQogIAogIC8qKgogICAqIAogICAqIEByZXR1cm4gcmV0dXJucyBhbiBhcnJheSBvZiB0aHJlZSBjb21tb24gY2hvaWNlcy4gKGllLiBZZXMsIHllcyBhbGwsIGFuZCBjYW5jZWwgKQogICAqLwogIHB1YmxpYyBzdGF0aWMgQ2hvaWNlW10gZ2V0VGhyZWVTdGF0ZUZpbGVPcHRpb25zKCkgCiAgewogICAgVmVjdG9yIGNob2ljZXMgPSBuZXcgVmVjdG9yKCk7CiAgICAKICAgIGNob2ljZXMuYWRkKG5ldyBDaG9pY2UoICdZJywgRW52aXJvbm1lbnRNZXNzYWdlcy5MQUJFTF9ZRVMpKTsKICAgIGNob2ljZXMuYWRkKG5ldyBDaG9pY2UoICdBJywgRW52aXJvbm1lbnRNZXNzYWdlcy5MQUJFTF9ZRVNfVE9fQUxMKSk7CiAgICBjaG9pY2VzLmFkZChuZXcgQ2hvaWNlKCAnQycsIEVudmlyb25tZW50TWVzc2FnZXMuTEFCRUxfQ0FOQ0VMKSk7CiAgICAKICAgIHJldHVybiAoQ2hvaWNlW10pY2hvaWNlcy50b0FycmF5KG5ldyBDaG9pY2VbY2hvaWNlcy5zaXplKCldKTsKICB9CiAgCiAgLyoqCiAgKiBSZXR1cm5zIGFuCiAgKiB7QGxpbmsgb3JnLmVjbGlwc2UuY29yZS5yZXNvdXJjZXMuSVJlc291cmNlIElSZXNvdXJjZX0KICAqIG9mIHRoZSBnaXZlbiBhYnNvbHV0ZSBwYXRobmFtZSBvciBudWxsIGlmIG5vIHN1Y2ggcmVzb3VyY2UgZXhpc3RzLgogICogQHBhcmFtIGFic29sdXRlUGF0aG5hbWUgVGhlIGFic29sdXRlIHBhdGggb2YgdGhlIHJlc291cmNlLgogICogQHJldHVybiBUaGUgPGNvZGU+SVJlc291cmNlPC9jb2RlPi4KICAqLwogIHB1YmxpYyBzdGF0aWMgSVJlc291cmNlIGZpbmRSZXNvdXJjZSAoIFN0cmluZyBhYnNvbHV0ZVBhdGhuYW1lICkKICB7CiAgICBpZiAoYWJzb2x1dGVQYXRobmFtZSA9PSBudWxsKQogICAgewogICAgICByZXR1cm4gbnVsbDsKICAgIH0KICAgIAogICAgcmV0dXJuIGZpbmRSZXNvdXJjZShuZXcgUGF0aChhYnNvbHV0ZVBhdGhuYW1lKSk7CiAgfQoKICAvKioKICAqIFJldHVybnMgYW4KICAqIHtAbGluayBvcmcuZWNsaXBzZS5jb3JlLnJlc291cmNlcy5JUmVzb3VyY2UgSVJlc291cmNlfQogICogb2YgdGhlIGdpdmVuIGFic29sdXRlIHBhdGggb3IgbnVsbCBpZiBubyBzdWNoIHJlc291cmNlIGV4aXN0cy4KICAqIEBwYXJhbSBhYnNvbHV0ZVBhdGggVGhlIGFic29sdXRlIDxjb2RlPklQYXRoPC9jb2RlPiBvZiB0aGUgcmVzb3VyY2UuCiAgKiBAcmV0dXJuIFRoZSA8Y29kZT5JUmVzb3VyY2U8L2NvZGU+LgogICovCiAgcHVibGljIHN0YXRpYyBJUmVzb3VyY2UgZmluZFJlc291cmNlICggSVBhdGggYWJzb2x1dGVQYXRoICkKICB7CiAgICBpZiAoYWJzb2x1dGVQYXRoID09IG51bGwpCiAgICB7CiAgICAgIHJldHVybiBudWxsOwogICAgfQogICAgCiAgICByZXR1cm4gRmlsZVJlc291cmNlVXRpbHMuZ2V0V29ya3NwYWNlUm9vdCgpLmZpbmRNZW1iZXIoYWJzb2x1dGVQYXRoKTsKICB9CiAgCiAgLyoqCiAgICogQ29waWVzIGEgZmlsZSBmcm9tIGEgcGx1Z2luJ3MgaW5zdGFsbGF0aW9uIGxvY2F0aW9uCiAgICogdG8gYW4gRWNsaXBzZSBmb2xkZXIuCiAgICogQHBhcmFtIHBsdWdpbiBUaGUgcGx1Z2luIGNvbnRhaW5pbmcgdGhlIGZpbGVzIHRvIGNvcHkuCiAgICogTXVzdCBub3QgYmUgbnVsbC4KICAgKiBAcGFyYW0gc291cmNlUGF0aCBUaGUgcGF0aCwgcmVsYXRpdmUgdG8gdGhlIDxjb2RlPnBsdWdpbjwvY29kZT4KICAgKiBpbnN0YWxsIGxvY2F0aW9uLCBjb250YWluaW5nIHRoZSBmaWxlcyB0byBjb3B5LgogICAqIElmIG51bGwsIHRoZW4gdGhlIHBsdWdpbiBpbnN0YWxsIGxvY2F0aW9uIGlzIHRoZSBzb3VyY2UgcGF0aAogICAqIChpZS4gbnVsbCBpcyBlcXVpdmFsZW50IHRvICIuIikuCiAgICogQHBhcmFtIHBhdGhuYW1lIFRoZSBwYXRobmFtZSBvZiB0aGUgZmlsZSB0byBjb3B5LgogICAqIFRoZSBwYXRobmFtZSBpcyByZWxhdGl2ZSB0byB0aGUgPGNvZGU+cGx1Z2luIHNvdXJjZVBhdGg8L2NvZGU+LgogICAqIE11c3Qgbm90IGJlIG51bGwuCiAgICogQHBhcmFtIHRhcmdldFBhdGggVGhlIGFic29sdXRlIEVjbGlwc2UgcGF0aCBvZiB0aGUgZm9sZGVyIHRvCiAgICogd2hpY2ggdGhlIGZpbGUgd2lsbCBiZSBjb3BpZWQuIFRoZSByZWxhdGl2ZSBwYXRobmFtZSBvZiB0aGUKICAgKiBmaWxlIGlzIHByZXNlcnZlZC4KICAgKiBNdXN0IG5vdCBiZSBudWxsLgogICAqIEBwYXJhbSBjcmVhdGVGb2xkZXJzIFRoZSBpbnRlcm1lZGlhdGUgZm9sZGVyIGNyZWF0aW9uIHBvbGljeSwgb25lIG9mCiAgICoge0BsaW5rICNDUkVBVEUgQ1JFQVRFfSBvciB7QGxpbmsgI0RPTlRfQ1JFQVRFIERPTlRfQ1JFQVRFfS4KICAgKiA8dWw+CiAgICogPGxpPjxjb2RlPkNSRUFURTwvY29kZT4gLQogICAqIElmIGFueSBpbnRlcm1lZGlhdGUgZm9sZGVycyBpbiB0aGUgZ2l2ZW4gPGNvZGU+YWJzb2x1dGVQYXRoPC9jb2RlPgogICAqIGRvIG5vdCBleGlzdCwgdGhleSB3aWxsIGJlIGNyZWF0ZWQuCiAgICogPGxpPjxjb2RlPkRPTlRfQ1JFQVRFPC9jb2RlPiAtCiAgICogSWYgYW55IGludGVybWVkaWF0ZSBmb2xkZXJzIGluIHRoZSBnaXZlbiA8Y29kZT5hYnNvbHV0ZVBhdGg8L2NvZGU+CiAgICogZG8gbm90IGV4aXN0LCB0aGUgbWV0aG9kIHdpbGwgdGhyb3cgYSA8Y29kZT5Db3JlRXhjZXB0aW9uPC9jb2RlPi4KICAgKiA8L3VsPgogICAqIEBwYXJhbSBvdmVyd3JpdGVGaWxlIFRoZSBwb2xpY3kgZm9yIGV4aXN0aW5nIGZpbGVzLCBvbmUgb2YKICAgKiB7QGxpbmsgI09WRVJXUklURSBPVkVSV1JJVEV9IG9yIHtAbGluayAjRE9OVF9PVkVSV1JJVEUgRE9OVF9PVkVSV1JJVEV9LgogICAqIDx1bD4KICAgKiA8bGk+PGNvZGU+T1ZFUldSSVRFPC9jb2RlPiAtCiAgICogSWYgYSByZXNvdXJjZSBvZiB0aGUgc2FtZSBuYW1lIGFzIHRoZSBnaXZlbgogICAqIDxjb2RlPmFic29sdXRlUGF0aDwvY29kZT4gYWxyZWFkeSBleGlzdHMgYW5kIGlzIGEgZmlsZSwKICAgKiBpdCB3aWxsIGJlIHJlcGxhY2VkLgogICAqIElmIHRoZSByZXNvdXJjZSBhbHJlYWR5IGV4aXN0cyBhbmQgaXQgaXMgbm90IGEgZmlsZSwKICAgKiB0aGVuIG5vIGZpbGUgd2lsbCBiZSBjcmVhdGVkIGFuZAogICAqIGEgPGNvZGU+Q29yZUV4Y2VwdGlvbjwvY29kZT4gd2lsbCBiZSB0aHJvd24uCiAgICogPGxpPjxjb2RlPkRPTlRfT1ZFUldSSVRFPC9jb2RlPiAtCiAgICogSWYgYW55IHJlc291cmNlIG9mIHRoZSBzYW1lIG5hbWUgYXMgdGhlIGdpdmVuCiAgICogPGNvZGU+YWJzb2x1dGVQYXRoPC9jb2RlPiBhbHJlYWR5IGV4aXN0cywKICAgKiB0aGVuIG5vIGZpbGUgd2lsbCBiZSBjcmVhdGVkIGFuZAogICAqIGEgPGNvZGU+Q29yZUV4Y2VwdGlvbjwvY29kZT4gd2lsbCBiZSB0aHJvd24uCiAgICogPC91bD4KICAgKiBAcGFyYW0gcHJvZ3Jlc3NNb25pdG9yIFRoZSBwcm9ncmVzcyBtb25pdG9yIGZvciB0aGUgb3BlcmF0aW9uLCBvciBudWxsLgogICAqIEB0aHJvd3MgQ29yZUV4Y2VwdGlvbiBBbiBleGNlcHRpb24gY29udGFpbmluZyBhbgogICAqIHtAbGluayBvcmcuZWNsaXBzZS5jb3JlLnJ1bnRpbWUuSVN0YXR1cyBJU3RhdHVzfQogICAqIHdpdGggYSBzZXZlcml0eSBvZiA8Y29kZT5JU3RhdHVzLkVSUk9SPC9jb2RlPiBhbmQgYQogICAqIGxvY2FsZS1zcGVjaWZpYyBkZXNjcmlwdGlvbiBvZiB0aGUgY2F1c2UuCiAgICovCiAgIHN0YXRpYyBwdWJsaWMgdm9pZCBjb3B5RmlsZSggUmVzb3VyY2VDb250ZXh0IHJlc291cmNlQ29udGV4dCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBQbHVnaW4gcGx1Z2luLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIElQYXRoIHNvdXJjZVBhdGgsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgSVBhdGggcGF0aG5hbWUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgSVBhdGggdGFyZ2V0UGF0aCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBJUHJvZ3Jlc3NNb25pdG9yIHByb2dyZXNzTW9uaXRvciwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBJU3RhdHVzSGFuZGxlciBzdGF0dXNNb25pdG9yICkKICAgICB0aHJvd3MgQ29yZUV4Y2VwdGlvbgogICB7CiAgICAgdHJ5CiAgICAgewogICAgICAgSVBhdGggdGFyZ2V0ID0gdGFyZ2V0UGF0aC5hcHBlbmQocGF0aG5hbWUpOwogICAgICAgSVBhdGggc291cmNlID0gc291cmNlUGF0aCA9PSBudWxsID8gcGF0aG5hbWUgOiBzb3VyY2VQYXRoLmFwcGVuZChwYXRobmFtZSk7CiAgICAgICBJbnB1dFN0cmVhbSBpbnB1dCA9IHBsdWdpbi5vcGVuU3RyZWFtKHNvdXJjZSk7CiAgICAgICBjcmVhdGVGaWxlKHJlc291cmNlQ29udGV4dCwgdGFyZ2V0LCBpbnB1dCwgcHJvZ3Jlc3NNb25pdG9yLCBzdGF0dXNNb25pdG9yKTsKICAgICB9CiAgICAgY2F0Y2ggKElPRXhjZXB0aW9uIGUpCiAgICAgewogICAgICAgdGhyb3cgbmV3IENvcmVFeGNlcHRpb24obmV3IFN0YXR1cyhJU3RhdHVzLkVSUk9SLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcGx1Z2luLmdldEJ1bmRsZSgpLmdldFN5bWJvbGljTmFtZSgpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgMCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEVudmlyb25tZW50TWVzc2FnZXMuTVNHX0VSUk9SX0lPLGUpKTsKICAgICB9CiAgIH0KICAgCiAgLyoqCiAgICogRGVsZXRlcyBhIGZpbGUgdW5kZXIgYSBjb250YWluZXIuCiAgICogVGhlIGNvbnRhaW5lciBtdXN0IGFscmVhZHkgZXhpc3QuCiAgICogQHBhcmFtIGZpbGUgLSB0aGUgSUZpbGUgdG8gYmUgZGVsZXRlZAogICAqIEBwYXJhbSBwcm9ncmVzc01vbml0b3IKICAgKiBAcGFyYW0gc3RhdHVzTW9uaXRvcgogICAqIEByZXR1cm4gVHJ1ZSBpZiB0aGUgZmlsZSBkb2VzIG5vdCBleGlzdCBvciBpZiBpdCBleGlzdHMgYW5kIGlzIHN1Y2Nlc3NmdWxseSBkZWxldGVkLiBGYWxzZSBvdGhlcndpc2UuCiAgICovCiAgcHVibGljIHN0YXRpYyBib29sZWFuIGRlbGV0ZUZpbGUoIFJlc291cmNlQ29udGV4dCByZXNvdXJjZUNvbnRleHQsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBJRmlsZSBmaWxlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBJUHJvZ3Jlc3NNb25pdG9yIHByb2dyZXNzTW9uaXRvciwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIElTdGF0dXNIYW5kbGVyIHN0YXR1c01vbml0b3IpCiAgICB0aHJvd3MgQ29yZUV4Y2VwdGlvbgogIHsKICAgIGlmIChmaWxlLmV4aXN0cygpKQogICAgewogICAgICBpZiAoIXJlc291cmNlQ29udGV4dC5pc092ZXJ3cml0ZUZpbGVzRW5hYmxlZCgpKQogICAgICB7CiAgICAgICAgSVN0YXR1cyBzdGF0dXMgCiAgICAgICAgICA9IFN0YXR1c1V0aWxzLndhcm5pbmdTdGF0dXMoIE5MUy5iaW5kKEVudmlyb25tZW50TWVzc2FnZXMuTVNHX0VSUk9SX0ZJTEVfT1ZFUldSSVRFX0RJU0FCTEVELAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5ldyBPYmplY3RbXXsgZmlsZS5nZXRQYXJlbnQoKS5nZXRGdWxsUGF0aCgpLnRvU3RyaW5nKCksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmaWxlLmdldE5hbWUoKX0pICk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAKICAgICAgICBDaG9pY2UgY2hvaWNlID0gc3RhdHVzTW9uaXRvci5yZXBvcnQoIHN0YXR1cywgZ2V0VGhyZWVTdGF0ZUZpbGVPcHRpb25zKCkgKTsKICAgICAgICAKICAgICAgICBpZiggY2hvaWNlLmdldFNob3J0Y3V0KCkgPT0gJ0MnICkgcmV0dXJuIGZhbHNlOwogICAgICAgIAogICAgICAgIGlmKCBjaG9pY2UuZ2V0U2hvcnRjdXQoKSA9PSAnQScgKSByZXNvdXJjZUNvbnRleHQuc2V0T3ZlcndyaXRlRmlsZXNFbmFibGVkKHRydWUpOwogICAgICB9CiAgICAgIAogICAgICAvL1dlIGhhdmUgcGVybWlzc2lvbiB0byBvdmVyd3JpdGUgc28gY2hlY2sgaWYgZmlsZSBpcyByZWFkLW9ubHkKICAgICAgaWYgKGZpbGUuaXNSZWFkT25seSgpKQogICAgICB7CiAgICAgICAgaWYgKCFyZXNvdXJjZUNvbnRleHQuaXNDaGVja291dEZpbGVzRW5hYmxlZCgpKQogICAgICAgIHsKICAgICAgICAgIElTdGF0dXMgc3RhdHVzIAogICAgICAgICAgICA9IFN0YXR1c1V0aWxzLndhcm5pbmdTdGF0dXMoIE5MUy5iaW5kKEVudmlyb25tZW50TWVzc2FnZXMuTVNHX0VSUk9SX0ZJTEVfQ0hFQ0tPVVRfRElTQUJMRUQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBuZXcgT2JqZWN0W117IGZpbGUuZ2V0UGFyZW50KCkuZ2V0RnVsbFBhdGgoKS50b1N0cmluZygpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmaWxlLmdldE5hbWUoKX0pICk7CiAgICAgICAgICAKICAgICAgICAgIENob2ljZSBjaG9pY2UgPSBzdGF0dXNNb25pdG9yLnJlcG9ydCggc3RhdHVzLCBnZXRUaHJlZVN0YXRlRmlsZU9wdGlvbnMoKSApOwogICAgICAgICAgCiAgICAgICAgICBpZiggY2hvaWNlLmdldFNob3J0Y3V0KCkgPT0gJ0MnICkgcmV0dXJuIGZhbHNlOwogICAgICAgICAgCiAgICAgICAgICBpZiggY2hvaWNlLmdldFNob3J0Y3V0KCkgPT0gJ0EnICkgcmVzb3VyY2VDb250ZXh0LnNldENoZWNrb3V0RmlsZXNFbmFibGVkKHRydWUpOyAgICAgICAgICAKICAgICAgICB9CiAgICAgICAgCiAgICAgICAgSUZpbGVbXSBmaWxlcyA9IG5ldyBJRmlsZVsxXTsKICAgICAgICBmaWxlc1swXSA9IGZpbGU7CiAgICAgICAgSVN0YXR1cyBzdGF0dXMgPSBnZXRXb3Jrc3BhY2UoKS52YWxpZGF0ZUVkaXQoZmlsZXMsIG51bGwpOwogICAgICAgIAogICAgICAgIGlmKCBzdGF0dXMuZ2V0U2V2ZXJpdHkoKSA9PSBJU3RhdHVzLkVSUk9SICkKICAgICAgICB7CiAgICAgICAgICBzdGF0dXNNb25pdG9yLnJlcG9ydEVycm9yKCBzdGF0dXMgKTsKICAgICAgICAgIHJldHVybiBmYWxzZTsKICAgICAgICB9CiAgICAgIH0KICAgICAgCiAgICAgIGZpbGUuZGVsZXRlKHRydWUsIG51bGwpOwogICAgfQogICAgLy9BdCB0aGlzIHBvaW50LCBlaXRoZXIgdGhlIGZpbGUgZGlkIG5vdCBleGlzdCBvciB3ZSBzdWNjZXNzZnVsbHkgZGVsZXRlZAogICAgLy8gaXQuIFJldHVybiBzdWNjZXNzLgogICAgcmV0dXJuIHRydWU7CiAgfQoKICAvKioKICAgKiBEZWxldGVzIGEgZm9sZGVyIHVuZGVyIGEgY29udGFpbmVyLgogICAqIEBwYXJhbSBmb2xkZXIgLSB0aGUgSUZvbGRlciB0byBiZSBkZWxldGVkCiAgICogQHBhcmFtIHByb2dyZXNzTW9uaXRvcgogICAqIEBwYXJhbSBzdGF0dXNNb25pdG9yCiAgICogQHJldHVybiBUcnVlIGlmIHRoZSBmb2xkZXIgZG9lcyBub3QgZXhpc3Qgb3IgaWYgaXQgZXhpc3RzIGFuZCBpcyBzdWNjZXNzZnVsbHkgZGVsZXRlZCBhbG9uZyB3aXRoIGl0cyBtZW1iZXJzLiBGYWxzZSBvdGhlcndpc2UuCiAgICovCiAgIHB1YmxpYyBzdGF0aWMgYm9vbGVhbiBkZWxldGVGb2xkZXIoIFJlc291cmNlQ29udGV4dCByZXNvdXJjZUNvbnRleHQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIElGb2xkZXIgZm9sZGVyLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBJUHJvZ3Jlc3NNb25pdG9yIHByb2dyZXNzTW9uaXRvciwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgSVN0YXR1c0hhbmRsZXIgc3RhdHVzTW9uaXRvciApCiAgICAgdGhyb3dzIENvcmVFeGNlcHRpb24KICAgewogICAgIGlmICghZm9sZGVyLmV4aXN0cygpKSByZXR1cm4gdHJ1ZTsKCiAgICAgYm9vbGVhbiAgICAgZGVsZXRlZCAgID0gdHJ1ZTsKICAgICBJUmVzb3VyY2VbXSByZXNvdXJjZXMgPSBmb2xkZXIubWVtYmVycygpOwogICAgIAogICAgIGZvciAoaW50IGk9MDsgaTxyZXNvdXJjZXMubGVuZ3RoOyBpKyspCiAgICAgewogICAgICAgSVJlc291cmNlIHJlc291cmNlID0gcmVzb3VyY2VzW2ldOwogICAgICAgaWYgKHJlc291cmNlIGluc3RhbmNlb2YgSUZpbGUpCiAgICAgICB7CiAgICAgICAgIGRlbGV0ZWQgPSBkZWxldGVGaWxlKHJlc291cmNlQ29udGV4dCwgKElGaWxlKXJlc291cmNlLCBwcm9ncmVzc01vbml0b3IsIHN0YXR1c01vbml0b3IpOwogICAgICAgfQogICAgICAgaWYgKHJlc291cmNlIGluc3RhbmNlb2YgSUZvbGRlcikKICAgICAgIHsKICAgICAgICAgZGVsZXRlZCA9IGRlbGV0ZUZvbGRlciggcmVzb3VyY2VDb250ZXh0LCAoSUZvbGRlcilyZXNvdXJjZSwgcHJvZ3Jlc3NNb25pdG9yLCBzdGF0dXNNb25pdG9yKTsKICAgICAgIH0KCiAgICAgICBpZiggIWRlbGV0ZWQgKSBicmVhazsKICAgICB9CiAgICAgCiAgICAgaWYoIGRlbGV0ZWQgKQogICAgIHsKICAgICAgIGZvbGRlci5kZWxldGUodHJ1ZSwgdHJ1ZSwgbnVsbCk7CiAgICAgICByZXR1cm4gdHJ1ZTsKICAgICB9CiAgICAgZWxzZQogICAgICAgcmV0dXJuIGZhbHNlOwogICB9CgogIC8qKgogICogQ3JlYXRlcyBhIGZpbGUgb2YgdGhlIGdpdmVuIDxjb2RlPmFic29sdXRlUGF0aDwvY29kZT4KICAqIGFuZCByZXR1cm5zIGl0cyBoYW5kbGUgYXMgYW4gPGNvZGU+SUZpbGU8L2NvZGU+LgogICogSWYgdGhlIGZpbGUgY2Fubm90IGJlIGNyZWF0ZWQsIGEKICAqIDxjb2RlPkNvcmVFeGNlcHRpb248L2NvZGU+IGNvbnRhaW5pbmcgYW4KICAqIDxjb2RlPklTdGF0dXM8L2NvZGU+IG9iamVjdCBpcyB0aHJvd24uCiAgKiBAcGFyYW0gYWJzb2x1dGVQYXRoIFRoZSBhYnNvbHV0ZSBwYXRoIG9mIHRoZSBmaWxlIHRvIGNyZWF0ZS4KICAqIFRoZSBwcm9qZWN0IGF0IHRoZSBiZWdpbm5pbmcgb2YgdGhlIHBhdGggbXVzdCBhbHJlYWR5IGV4aXN0LAogICogdGhhdCBpcywgdGhpcyBtZXRob2QgY2Fubm90IGJlIHVzZWQgdG8gY3JlYXRlIHByb2plY3RzLgogICogQHBhcmFtIHByb2dyZXNzTW9uaXRvciBUaGUgcHJvZ3Jlc3MgbW9uaXRvciBmb3IgdGhlIG9wZXJhdGlvbiwgb3IgbnVsbC4KICAqIEByZXR1cm4gVGhlIHtAbGluayBvcmcuZWNsaXBzZS5jb3JlLnJlc291cmNlcy5JRmlsZSBJRmlsZX0KICAqIGhhbmRsZSBvZiB0aGUgZmlsZS4KICAqIEB0aHJvd3MgQ29yZUV4Y2VwdGlvbiBBbiBleGNlcHRpb24gY29udGFpbmluZyBhbgogICoge0BsaW5rIG9yZy5lY2xpcHNlLmNvcmUucnVudGltZS5JU3RhdHVzIElTdGF0dXN9CiAgKiB3aXRoIGEgc2V2ZXJpdHkgb2YgPGNvZGU+SVN0YXR1cy5FUlJPUjwvY29kZT4gYW5kIGEKICAqIGxvY2FsZS1zcGVjaWZpYyBkZXNjcmlwdGlvbiBvZiB0aGUgY2F1c2UuCiAgKi8KICBwdWJsaWMgc3RhdGljIElGaWxlIGNyZWF0ZUZpbGUgKAogICAgUmVzb3VyY2VDb250ZXh0IHJlc291cmNlQ29udGV4dCwKICAgIElQYXRoICAgICAgICAgICBhYnNvbHV0ZVBhdGgsCiAgICBJbnB1dFN0cmVhbSAgICAgaW5wdXRTdHJlYW0sCiAgICBJUHJvZ3Jlc3NNb25pdG9yIHByb2dyZXNzTW9uaXRvciwKICAgIElTdGF0dXNIYW5kbGVyICAgc3RhdHVzSGFuZGxlciApCgogICAgdGhyb3dzIENvcmVFeGNlcHRpb24gCiAgeyAgICAKICAgIGlmICghYWJzb2x1dGVQYXRoLmlzQWJzb2x1dGUoKSkKICAgIHsKICAgICAgdGhyb3cgbmV3IENvcmVFeGNlcHRpb24obmV3IFN0YXR1cyhJU3RhdHVzLkVSUk9SLCAiUmVzb3VyY2VVdGlscyIsMCxOTFMuYmluZChFbnZpcm9ubWVudE1lc3NhZ2VzLk1TR19FUlJPUl9QQVRIX05PVF9BQlNPTFVURSxuZXcgT2JqZWN0W10ge2Fic29sdXRlUGF0aC50b1N0cmluZygpfSksbnVsbCkpOwogICAgfQogICAgaWYgKGFic29sdXRlUGF0aC5zZWdtZW50Q291bnQoKSA8IDEpCiAgICB7CiAgICAgIHRocm93IG5ldyBDb3JlRXhjZXB0aW9uKG5ldyBTdGF0dXMoSVN0YXR1cy5FUlJPUiwiUmVzb3VyY2VVdGlscyIsMCxOTFMuYmluZChFbnZpcm9ubWVudE1lc3NhZ2VzLk1TR19FUlJPUl9QQVRIX0VNUFRZLG5ldyBPYmplY3RbXSB7YWJzb2x1dGVQYXRoLnRvU3RyaW5nKCl9KSxudWxsKSk7CiAgICB9CiAgICBpZiAoYWJzb2x1dGVQYXRoLnNlZ21lbnRDb3VudCgpIDwgMikKICAgIHsKICAgICAgdGhyb3cgbmV3IENvcmVFeGNlcHRpb24obmV3IFN0YXR1cyhJU3RhdHVzLkVSUk9SLCJSZXNvdXJjZVV0aWxzIiwwLE5MUy5iaW5kKEVudmlyb25tZW50TWVzc2FnZXMuTVNHX0VSUk9SX1BBVEhfTk9UX0ZPTERFUixuZXcgT2JqZWN0W10ge2Fic29sdXRlUGF0aC50b1N0cmluZygpfSksbnVsbCkpOwogICAgfQogICAgSUNvbnRhaW5lciBwYXJlbnQgICA9IG1ha2VGb2xkZXJQYXRoKHJlc291cmNlQ29udGV4dCwgYWJzb2x1dGVQYXRoLnJlbW92ZUxhc3RTZWdtZW50cygxKSwgcHJvZ3Jlc3NNb25pdG9yLCBzdGF0dXNIYW5kbGVyKTsKICAgIFN0cmluZyAgICAgZmlsZU5hbWUgPSBhYnNvbHV0ZVBhdGgubGFzdFNlZ21lbnQoKTsKICAgIAogICAgcmV0dXJuIG1ha2VGaWxlKHJlc291cmNlQ29udGV4dCwgcGFyZW50LCBmaWxlTmFtZSwgaW5wdXRTdHJlYW0sIHByb2dyZXNzTW9uaXRvciwgc3RhdHVzSGFuZGxlcik7CiAgfQoKICAvKioKICAqIENyZWF0ZXMgdW5kZXIgdGhlIGdpdmVuIDxjb2RlPnByb2plY3Q8L2NvZGU+CiAgKiBhIGZpbGUgb2YgdGhlIGdpdmVuIDxjb2RlPnJlbGF0aXZlUGF0aDwvY29kZT4KICAqIGFuZCByZXR1cm5zIGl0cyBoYW5kbGUgYXMgYW4gPGNvZGU+SUZpbGU8L2NvZGU+LgogICogSWYgdGhlIGZpbGUgY2Fubm90IGJlIGNyZWF0ZWQsIGEKICAqIDxjb2RlPkNvcmVFeGNlcHRpb248L2NvZGU+IGNvbnRhaW5pbmcgYW4KICAqIDxjb2RlPklTdGF0dXM8L2NvZGU+IG9iamVjdCBpcyB0aHJvd24uCiAgKiBAcGFyYW0gYWJzb2x1dGVQYXRoIFRoZSBhYnNvbHV0ZSBwYXRoIG9mIHRoZSBmaWxlIHRvIGNyZWF0ZS4KICAqIFRoZSBwcm9qZWN0IGF0IHRoZSBiZWdpbm5pbmcgb2YgdGhlIHBhdGggbXVzdCBhbHJlYWR5IGV4aXN0LAogICogdGhhdCBpcywgdGhpcyBtZXRob2QgY2Fubm90IGJlIHVzZWQgdG8gY3JlYXRlIHByb2plY3RzLgogICogQHBhcmFtIGNyZWF0ZUZvbGRlcnMgVGhlIGludGVybWVkaWF0ZSBmb2xkZXIgY3JlYXRpb24gcG9saWN5LCBvbmUgb2YKICAqIHtAbGluayAjQ1JFQVRFIENSRUFURX0gb3Ige0BsaW5rICNET05UX0NSRUFURSBET05UX0NSRUFURX0uCiAgKiA8dWw+CiAgKiA8bGk+PGNvZGU+Q1JFQVRFPC9jb2RlPiAtCiAgKiBJZiBhbnkgaW50ZXJtZWRpYXRlIGZvbGRlcnMgaW4gdGhlIGdpdmVuIDxjb2RlPmFic29sdXRlUGF0aDwvY29kZT4KICAqIGRvIG5vdCBleGlzdCwgdGhleSB3aWxsIGJlIGNyZWF0ZWQuCiAgKiA8bGk+PGNvZGU+RE9OVF9DUkVBVEU8L2NvZGU+IC0KICAqIElmIGFueSBpbnRlcm1lZGlhdGUgZm9sZGVycyBpbiB0aGUgZ2l2ZW4gPGNvZGU+YWJzb2x1dGVQYXRoPC9jb2RlPgogICogZG8gbm90IGV4aXN0LCB0aGUgbWV0aG9kIHdpbGwgdGhyb3cgYSA8Y29kZT5Db3JlRXhjZXB0aW9uPC9jb2RlPi4KICAqIDwvdWw+CiAgKiBAcGFyYW0gb3ZlcndyaXRlRmlsZSBUaGUgcG9saWN5IGZvciBleGlzdGluZyBmaWxlcywgb25lIG9mCiAgKiB7QGxpbmsgI09WRVJXUklURSBPVkVSV1JJVEV9IG9yIHtAbGluayAjRE9OVF9PVkVSV1JJVEUgRE9OVF9PVkVSV1JJVEV9LgogICogPHVsPgogICogPGxpPjxjb2RlPk9WRVJXUklURTwvY29kZT4gLQogICogSWYgYSByZXNvdXJjZSBvZiB0aGUgc2FtZSBuYW1lIGFzIHRoZSBnaXZlbgogICogPGNvZGU+YWJzb2x1dGVQYXRoPC9jb2RlPiBhbHJlYWR5IGV4aXN0cyBhbmQgaXMgYSBmaWxlLAogICogaXQgd2lsbCBiZSByZXBsYWNlZC4KICAqIElmIHRoZSByZXNvdXJjZSBhbHJlYWR5IGV4aXN0cyBhbmQgaXQgaXMgbm90IGEgZmlsZSwKICAqIHRoZW4gbm8gZmlsZSB3aWxsIGJlIGNyZWF0ZWQgYW5kCiAgKiBhIDxjb2RlPkNvcmVFeGNlcHRpb248L2NvZGU+IHdpbGwgYmUgdGhyb3duLgogICogPGxpPjxjb2RlPkRPTlRfT1ZFUldSSVRFPC9jb2RlPiAtCiAgKiBJZiBhbnkgcmVzb3VyY2Ugb2YgdGhlIHNhbWUgbmFtZSBhcyB0aGUgZ2l2ZW4KICAqIDxjb2RlPmFic29sdXRlUGF0aDwvY29kZT4gYWxyZWFkeSBleGlzdHMsCiAgKiB0aGVuIG5vIGZpbGUgd2lsbCBiZSBjcmVhdGVkIGFuZAogICogYSA8Y29kZT5Db3JlRXhjZXB0aW9uPC9jb2RlPiB3aWxsIGJlIHRocm93bi4KICAqIDwvdWw+CiAgKiBAcGFyYW0gcHJvZ3Jlc3NNb25pdG9yIFRoZSBwcm9ncmVzcyBtb25pdG9yIGZvciB0aGUgb3BlcmF0aW9uLCBvciBudWxsLgogICogQHJldHVybiBUaGUge0BsaW5rIG9yZy5lY2xpcHNlLmNvcmUucmVzb3VyY2VzLklGaWxlIElGaWxlfQogICogaGFuZGxlIG9mIHRoZSBmaWxlLgogICogQHRocm93cyBDb3JlRXhjZXB0aW9uIEFuIGV4Y2VwdGlvbiBjb250YWluaW5nIGFuCiAgKiB7QGxpbmsgb3JnLmVjbGlwc2UuY29yZS5ydW50aW1lLklTdGF0dXMgSVN0YXR1c30KICAqIHdpdGggYSBzZXZlcml0eSBvZiA8Y29kZT5JU3RhdHVzLkVSUk9SPC9jb2RlPiBhbmQgYQogICogbG9jYWxlLXNwZWNpZmljIGRlc2NyaXB0aW9uIG9mIHRoZSBjYXVzZS4KICAqLwogIHB1YmxpYyBzdGF0aWMgSUZpbGUgY3JlYXRlRmlsZSAoCiAgICBSZXNvdXJjZUNvbnRleHQgcmVzb3VyY2VDb250ZXh0LAogICAgSVByb2plY3QgICAgICAgIHByb2plY3QsCiAgICBJUGF0aCAgICAgICAgICAgcmVsYXRpdmVQYXRoLAogICAgSW5wdXRTdHJlYW0gICAgIGlucHV0U3RyZWFtLAogICAgSVByb2dyZXNzTW9uaXRvciBwcm9ncmVzc01vbml0b3IsCiAgICBJU3RhdHVzSGFuZGxlciAgIHN0YXR1c01vbml0b3IgKQogCiAgICB0aHJvd3MgQ29yZUV4Y2VwdGlvbiAKICB7CiAgICBJUGF0aCBhYnNvbHV0ZVBhdGggPSBwcm9qZWN0LmdldEZ1bGxQYXRoKCkuYXBwZW5kKHJlbGF0aXZlUGF0aCk7CiAgICByZXR1cm4gY3JlYXRlRmlsZShyZXNvdXJjZUNvbnRleHQsIGFic29sdXRlUGF0aCwgaW5wdXRTdHJlYW0sIHByb2dyZXNzTW9uaXRvciwgc3RhdHVzTW9uaXRvcik7CiAgfQoKICAvKioKICAqIENyZWF0ZXMgYW4gb3V0cHV0IHN0cmVhbSB0aGF0IGNhbiBiZSB1c2VkIHRvIHdyaXRlIHRvIHRoZQogICogZ2l2ZW4gPGNvZGU+ZmlsZTwvY29kZT4uIEFjdHVhbCBjaGFuZ2VzIHRvIHRoZSB3b3Jrc3BhY2UKICAqIG1heSBvY2N1ciBkdXJpbmcgY3JlYXRpb24gb2YgdGhlIHN0cmVhbSwgd2hpbGUgd3JpdGluZyB0bwogICogdGhlIHN0cmVhbSwgb3Igd2hlbiB0aGUgc3RyZWFtIGlzIGNsb3NlZC4KICAqIEEgPGNvZGU+Q29yZUV4Y2VwdGlvbjwvY29kZT4gY29udGFpbmluZwogICogYW4gPGNvZGU+SVN0YXR1czwvY29kZT4gd2lsbCBiZSB0aHJvd24KICAqIGF0IHNvbWUgcG9pbnQgaW4gdGhlIGxpZmVjeWNsZSBvZiB0aGUgc3RyZWFtCiAgKiBpZiB0aGUgZmlsZSByZXNvdXJjZSBjYW5ub3QgYmUgY3JlYXRlZC4KICAqIEBwYXJhbSBmaWxlIFRoZSB7QGxpbmsgb3JnLmVjbGlwc2UuY29yZS5yZXNvdXJjZXMuSUZpbGUgSUZpbGV9CiAgKiBoYW5kbGUgb2YgdGhlIGZpbGUgcmVzb3VyY2UgdG8gY3JlYXRlLiBUaGUgcHJvamVjdCBpbXBsaWVkIGJ5IHRoZQogICogcGF0aG5hbWUgb2YgdGhlIGZpbGUgbXVzdCBhbHJlYWR5IGV4aXN0LAogICogdGhhdCBpcywgdGhpcyBtZXRob2QgY2Fubm90IGJlIHVzZWQgdG8gY3JlYXRlIHByb2plY3RzLgogICogQHBhcmFtIHByb2dyZXNzTW9uaXRvciBUaGUgcHJvZ3Jlc3MgbW9uaXRvciBmb3IgdGhlIG9wZXJhdGlvbiwgb3IgbnVsbC4KICAqIEByZXR1cm4gQW4gPGNvZGU+T3V0cHV0U3RyZWFtPC9jb2RlPiB0aWVkIHRvIHRoZSBmaWxlIHJlc291cmNlLgogICogQWN0dWFsIGNoZWNrcyBvZiBvciBjaGFuZ2VzIHRvIHRoZSB3b3Jrc3BhY2UgbWF5IG9jY3VyIGFzIGVhcmx5IGR1cmluZwogICogc3RyZWFtIGNyZWF0aW9uLCBjbG9zdXJlLCBvciBhbnkgdGltZSBpbiBiZXR3ZWVuLgogICogQHRocm93cyBDb3JlRXhjZXB0aW9uIEFuIGV4Y2VwdGlvbiBjb250YWluaW5nIGFuCiAgKiB7QGxpbmsgb3JnLmVjbGlwc2UuY29yZS5ydW50aW1lLklTdGF0dXMgSVN0YXR1c30KICAqIHdpdGggYSBzZXZlcml0eSBvZiA8Y29kZT5JU3RhdHVzLkVSUk9SPC9jb2RlPiBhbmQgYQogICogbG9jYWxlLXNwZWNpZmljIGRlc2NyaXB0aW9uIG9mIHRoZSBjYXVzZS4KICAqIFJlYXNvbnMgaW5jbHVkZToKICAqIDxvbD4KICAqIDxsaT5UaGUgcHJvamVjdCBvZiB0aGUgZ2l2ZW4gZmlsZSdzIHBhdGggZG9lcyBub3QgZXhpc3QuCiAgKiA8bGk+QSBub24tZmlsZSByZXNvdXJjZSBvZiB0aGUgc2FtZSBuYW1lIG9mIHRoZSBnaXZlbiBmaWxlCiAgKiBhbHJlYWR5IGV4aXN0cy4KICAqIDxsaT5BIGZpbGUgcmVzb3VyY2Ugb2YgdGhlIHNhbWUgbmFtZSBvZiB0aGUgZ2l2ZW4gZmlsZQogICogYWxyZWFkeSBleGlzdHMsIGFuZCA8Y29kZT5vdmVyd3JpdGVGaWxlPC9jb2RlPiBpcyBmYWxzZS4KICAqIDxsaT5PbmUgb3IgbW9yZSBpbnRlcm1lZGlhdGUgZm9sZGVycyB0byB0aGUgZ2l2ZW4gZmlsZQogICogZG8gbm90IGV4aXN0LCBhbmQgPGNvZGU+Y3JlYXRlRm9sZGVyczwvY29kZT4gaXMgZmFsc2UuCiAgKiA8L29sPgogICovCgogIHB1YmxpYyBzdGF0aWMgT3V0cHV0U3RyZWFtIG5ld0ZpbGVPdXRwdXRTdHJlYW0gKAogICAgICAgUmVzb3VyY2VDb250ZXh0ICBjb250ZXh0LAogICAgICAgSVBhdGggICAgICAgICAgICBmaWxlLAogICAgICAgSVByb2dyZXNzTW9uaXRvciBwcm9ncmVzc01vbml0b3IsCiAgICAgICBJU3RhdHVzSGFuZGxlciAgICBzdGF0dXNIYW5kbGVyICkKIAogIHsKICAgIHJldHVybiBuZXcgRmlsZVJlc291cmNlT3V0cHV0U3RyZWFtKGNvbnRleHQsIGZpbGUsIHByb2dyZXNzTW9uaXRvciwgc3RhdHVzSGFuZGxlcik7CiAgfQoKICAvLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KICAvLyBOYXVnaHR5IGJpdHMuLi4KICAvLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KCiAgLy8KICAvLyBDcmVhdGVzIGEgcGF0aCBvZiBmb2xkZXJzLgogIC8vIERvIG5vdCBjYWxsIHdpdGggYW4gYWJzb2x1dGVQYXRoIG9mIGxlc3MgdGhhbiBvbmUgc2VnbWVudC4KICAvLwogIC8qKgogICAqIENyZWF0ZXMgYSBwYXRoIG9mIGZvbGRlcnMuCiAgICogRG8gbm90IGNhbGwgd2l0aCBhbiBhYnNvbHV0ZVBhdGggb2YgbGVzcyB0aGFuIG9uZSBzZWdtZW50LgogICAqIEBwYXJhbSByZXNvdXJjZUNvbnRleHQgdGhlIHJlc291cmNlIGNvbnRleHQgZm9yIG1ha2luZyBmb2xkZXJzLgogICAqIEBwYXJhbSBhYnNvbHV0ZVBhdGggdGhlIHBhdGggb2YgZm9sZGVycyB0aGF0IHdpbGwgYmUgY3JlYXRlZC4KICAgKiBAcGFyYW0gcHJvZ3Jlc3NNb25pdG9yIHRoZSBwcm9ncmVzcyBtb25pdG9yIHRvIGJlIHVzZWQuCiAgICogQHBhcmFtIHN0YXR1c0hhbmRsZXIgdGhlIHN0YXR1cyBoYW5kbGVyLgogICAqIEByZXR1cm4gcmV0dXJucyB0aGUgSUNvbnRhaW5lciBvZiB0aGUgY3JlYXRlZCBmb2xkZXIuCiAgICovCiAgcHVibGljIHN0YXRpYyBJQ29udGFpbmVyIG1ha2VGb2xkZXJQYXRoICgKICAgIFJlc291cmNlQ29udGV4dCAgcmVzb3VyY2VDb250ZXh0LAogICAgSVBhdGggICAgICAgICAgICBhYnNvbHV0ZVBhdGgsCiAgICBJUHJvZ3Jlc3NNb25pdG9yIHByb2dyZXNzTW9uaXRvciwKICAgIElTdGF0dXNIYW5kbGVyICAgIHN0YXR1c0hhbmRsZXIgKQogIAogICAgdGhyb3dzIENvcmVFeGNlcHRpb24KICB7CiAgICBpZiAoYWJzb2x1dGVQYXRoLnNlZ21lbnRDb3VudCgpIDw9IDEpCiAgICB7CiAgICAgIHJldHVybiBnZXRXb3Jrc3BhY2VSb290KCkuZ2V0UHJvamVjdChhYnNvbHV0ZVBhdGguc2VnbWVudCgwKSk7CiAgICB9CiAgICBlbHNlCiAgICB7CiAgICAgIElDb250YWluZXIgcGFyZW50ID0gbWFrZUZvbGRlclBhdGgocmVzb3VyY2VDb250ZXh0LCBhYnNvbHV0ZVBhdGgucmVtb3ZlTGFzdFNlZ21lbnRzKDEpLCBwcm9ncmVzc01vbml0b3IsIHN0YXR1c0hhbmRsZXIgKTsKICAgICAgU3RyaW5nIGZvbGRlck5hbWUgPSBhYnNvbHV0ZVBhdGgubGFzdFNlZ21lbnQoKTsKICAgICAgCiAgICAgIGNoZWNrUGFyZW50KCBwYXJlbnQsIGFic29sdXRlUGF0aCApOwogICAgICByZXR1cm4gbWFrZUZvbGRlcihyZXNvdXJjZUNvbnRleHQsIHBhcmVudCxmb2xkZXJOYW1lLCBwcm9ncmVzc01vbml0b3IgLCBzdGF0dXNIYW5kbGVyICk7CiAgICB9CiAgfQogIAogIHByaXZhdGUgc3RhdGljIHZvaWQgY2hlY2tQYXJlbnQoIElDb250YWluZXIgcGFyZW50LCBJUGF0aCBhYnNvbHV0ZVBhdGggKSB0aHJvd3MgQ29yZUV4Y2VwdGlvbgogIHsKICAgIGlmKCBwYXJlbnQgPT0gbnVsbCApCiAgICB7CiAgICAgIC8vIFRoZSBwYXJlbnQgaXMgbnVsbCwgc28gdGhlcmUgbXVzdCBoYXZlIGJlZW4gcHJvYmxlbXMgY3JlYXRpbmcgaXQuICBXZSB3aWxsIHRocm93CiAgICAgIC8vIGEgQ29yZUV4Y2VwdGlvbiB3YXJuaW5nIGZvciB0aGlzIHByb2JsZW0uCiAgICAgIElQYXRoICBwYXJlbnRQYXRoID0gYWJzb2x1dGVQYXRoLnJlbW92ZUxhc3RTZWdtZW50cygxKTsKICAgICAgU3RyaW5nIGZvbGRlclBhdGggPSBhYnNvbHV0ZVBhdGgubGFzdFNlZ21lbnQoKTsKICAgICAgdGhyb3cgbmV3IENvcmVFeGNlcHRpb24oIFN0YXR1c1V0aWxzLndhcm5pbmdTdGF0dXMoCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBOTFMuYmluZChFbnZpcm9ubWVudE1lc3NhZ2VzLk1TR19FUlJPUl9GT0xERVJfQ1JFQVRJT05fRElTQUJMRUQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBuZXcgT2JqZWN0W117IHBhcmVudFBhdGgudG9TdHJpbmcoKSwgZm9sZGVyUGF0aH0gKSApICk7CiAgICB9ICAKICB9CiAgCiAgLy8KICAvLyBDcmVhdGVzIGEgZm9sZGVyIHVuZGVyIGEgY29udGFpbmVyLgogIC8vIFRoZSBjb250YWluZXIgbXVzdCBhbHJlYWR5IGV4aXN0LgogIC8vCiBwcml2YXRlIHN0YXRpYyBJRm9sZGVyIG1ha2VGb2xkZXIgKAogICAgUmVzb3VyY2VDb250ZXh0ICByZXNvdXJjZUNvbnRleHQsCiAgICBJQ29udGFpbmVyICAgICAgIHBhcmVudCwKICAgIFN0cmluZyAgICAgICAgICAgZm9sZGVyTmFtZSwKICAgIElQcm9ncmVzc01vbml0b3IgcHJvZ3Jlc3NNb25pdG9yLAogICAgSVN0YXR1c0hhbmRsZXIgICAgc3RhdHVzSGFuZGxlciApCiAgCiAgdGhyb3dzIENvcmVFeGNlcHRpb24KICB7CiAgICBJUmVzb3VyY2UgY2hpbGQgID0gcGFyZW50LmZpbmRNZW1iZXIoZm9sZGVyTmFtZSk7CiAgICBDaG9pY2UgICAgcmVzdWx0ID0gbnVsbDsKICAgIAogICAgaWYoIGNoaWxkID09IG51bGwgKQogICAgewogICAgICBpZiAoIXJlc291cmNlQ29udGV4dC5pc0NyZWF0ZUZvbGRlcnNFbmFibGVkKCkpICAKICAgICAgewogICAgICAgIHJlc3VsdCA9IHN0YXR1c0hhbmRsZXIucmVwb3J0KAogICAgICAgICAgICAgICAgU3RhdHVzVXRpbHMud2FybmluZ1N0YXR1cygKICAgICAgICAgICAgICAgIAkJTkxTLmJpbmQoRW52aXJvbm1lbnRNZXNzYWdlcy5NU0dfRVJST1JfRk9MREVSX0NSRUFUSU9OX0RJU0FCTEVELAogICAgICAgIAkgICAgICAgICAgICAgICAgICAgICAgbmV3IE9iamVjdFtdeyBwYXJlbnQuZ2V0RnVsbFBhdGgoKS50b1N0cmluZygpLCBmb2xkZXJOYW1lfSApICksIAogICAgICAgICAgICAgICAgZ2V0VGhyZWVTdGF0ZUZpbGVPcHRpb25zKCkgKTsKICAgICAgICAKICAgICAgICBpZiggcmVzdWx0ID09IG51bGwgfHwgcmVzdWx0LmdldFNob3J0Y3V0KCkgPT0gJ0MnICkKICAgICAgICB7CiAgICAgICAgICByZXR1cm4gbnVsbDsKICAgICAgICB9CiAgICAgICAgZWxzZSBpZiggcmVzdWx0LmdldFNob3J0Y3V0KCkgPT0gJ0EnICkKICAgICAgICB7CiAgICAgICAgICByZXNvdXJjZUNvbnRleHQuc2V0Q3JlYXRlRm9sZGVyc0VuYWJsZWQodHJ1ZSk7CiAgICAgICAgfQogICAgICB9CiAgICAgIAogICAgICBJRm9sZGVyIGZvbGRlciA9IHBhcmVudC5nZXRGb2xkZXIobmV3IFBhdGgoZm9sZGVyTmFtZSkpOwogICAgICBmb2xkZXIuY3JlYXRlKHRydWUsdHJ1ZSxudWxsKTsKICAgICAgcmV0dXJuIGZvbGRlcjsKICAgIH0KICAgIGVsc2UgaWYoIGNoaWxkLmdldFR5cGUoKSA9PSBJUmVzb3VyY2UuRk9MREVSICkKICAgIHsKICAgICAgcmV0dXJuIChJRm9sZGVyKWNoaWxkOwogICAgfQogICAgZWxzZQogICAgewogICAgICB0aHJvdyBuZXcgQ29yZUV4Y2VwdGlvbigKICAgICAgICBuZXcgU3RhdHVzKCBJU3RhdHVzLkVSUk9SLCAKICAgICAgICAgICAgICAgICAgICAiUmVzb3VyY2VVdGlscyIsCiAgICAgICAgICAgICAgICAgICAgMCwgCiAgICAgICAgICAgICAgICAgICAgTkxTLmJpbmQoRW52aXJvbm1lbnRNZXNzYWdlcy5NU0dfRVJST1JfUkVTT1VSQ0VfTk9UX0ZPTERFUiwKCQkJCQkgICAgICAgICAgICAgICAgIG5ldyBPYmplY3RbXXsgcGFyZW50LmdldEZ1bGxQYXRoKCkuYXBwZW5kKGZvbGRlck5hbWUpLnRvU3RyaW5nKCkgfSksCgkJCW51bGwgKSApOwogICAgfQogIH0KCiAgLy8KICAvLyBDcmVhdGVzIGEgZmlsZSB1bmRlciBhIGNvbnRhaW5lci4KICAvLyBUaGUgY29udGFpbmVyIG11c3QgYWxyZWFkeSBleGlzdC4KICAvLwogcHJpdmF0ZSBzdGF0aWMgSUZpbGUgbWFrZUZpbGUgKAogICAgUmVzb3VyY2VDb250ZXh0ICByZXNvdXJjZUNvbnRleHQsCiAgICBJQ29udGFpbmVyICAgICAgIHBhcmVudCwKICAgIFN0cmluZyAgICAgICAgICAgZmlsZU5hbWUsCiAgICBJbnB1dFN0cmVhbSAgICAgIGlucHV0U3RyZWFtLAogICAgSVByb2dyZXNzTW9uaXRvciBwcm9ncmVzc01vbml0b3IsCiAgICBJU3RhdHVzSGFuZGxlciAgICBzdGF0dXNIYW5kbGVyICkKIAogICAgdGhyb3dzIENvcmVFeGNlcHRpb24KICB7CiAgICBJUmVzb3VyY2UgY2hpbGQgID0gcGFyZW50LmZpbmRNZW1iZXIoZmlsZU5hbWUpOwogICAgQ2hvaWNlICAgIHJlc3VsdCA9IG51bGw7CiAgICAKICAgIGlmKCBjaGlsZCAhPSBudWxsICkKICAgIHsKICAgICAgaWYoIGNoaWxkLmdldFR5cGUoKSA9PSBJUmVzb3VyY2UuRklMRSApCiAgICAgIHsKICAgICAgICBpZiggIXJlc291cmNlQ29udGV4dC5pc092ZXJ3cml0ZUZpbGVzRW5hYmxlZCgpICkgICAKICAgICAgICB7CiAgICAgICAgICByZXN1bHQgPSBzdGF0dXNIYW5kbGVyLnJlcG9ydCggCiAgICAgICAgICAgICAgICBTdGF0dXNVdGlscy53YXJuaW5nU3RhdHVzKCBOTFMuYmluZChFbnZpcm9ubWVudE1lc3NhZ2VzLk1TR19FUlJPUl9GSUxFX09WRVJXUklURV9ESVNBQkxFRCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5ldyBPYmplY3RbXSB7cGFyZW50LmdldEZ1bGxQYXRoKCkudG9TdHJpbmcoKSxmaWxlTmFtZX0pICksCQkJCQkgIAkJICAgIAogICAgICAgICAgICAgICAgZ2V0VGhyZWVTdGF0ZUZpbGVPcHRpb25zKCkgKTsKICAgICAgICAgIAogICAgICAgICAgaWYoIHJlc3VsdCA9PSBudWxsIHx8IHJlc3VsdC5nZXRTaG9ydGN1dCgpID09ICdDJyApCiAgICAgICAgICB7CiAgICAgICAgICAgIHJldHVybiBudWxsOwogICAgICAgICAgfQogICAgICAgICAgZWxzZSBpZiggcmVzdWx0LmdldFNob3J0Y3V0KCkgPT0gJ0EnICkKICAgICAgICAgIHsKICAgICAgICAgICAgcmVzb3VyY2VDb250ZXh0LnNldE92ZXJ3cml0ZUZpbGVzRW5hYmxlZCh0cnVlKTsKICAgICAgICAgIH0KICAgICAgICB9CQogICAgICAgIAogICAgICAgIC8vV2UgaGF2ZSBwZXJtaXNzaW9uIHRvIG92ZXJ3cml0ZSBzbyBjaGVjayBpZiBmaWxlIGlzIHJlYWQtb25seQogICAgICAgIGlmKCBjaGlsZC5nZXRSZXNvdXJjZUF0dHJpYnV0ZXMoKS5pc1JlYWRPbmx5KCkgKQogICAgICAgIHsKICAgICAgICAgIGlmKCAhcmVzb3VyY2VDb250ZXh0LmlzQ2hlY2tvdXRGaWxlc0VuYWJsZWQoKSApIAogICAgICAgICAgeyAgICAgICAgICAgIAogICAgICAgICAgICByZXN1bHQgPSBzdGF0dXNIYW5kbGVyLnJlcG9ydCggCiAgICAgICAgICAgICAgICAgICAgICAgICBTdGF0dXNVdGlscy5lcnJvclN0YXR1cyggTkxTLmJpbmQoRW52aXJvbm1lbnRNZXNzYWdlcy5NU0dfRVJST1JfRklMRV9DSEVDS09VVF9ESVNBQkxFRCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBuZXcgT2JqZWN0W117IHBhcmVudC5nZXRGdWxsUGF0aCgpLnRvU3RyaW5nKCksZmlsZU5hbWV9ICkgKSwgCiAgICAgICAgICAgICAgICAgICAgICAgICBnZXRUaHJlZVN0YXRlRmlsZU9wdGlvbnMoKSApOwogICAgICAgICAgICAKCQkgICAgaWYoIHJlc3VsdCA9PSBudWxsIHx8IHJlc3VsdC5nZXRTaG9ydGN1dCgpID09ICdDJyApCgkJICAgIHsKICAgICAgICAgICAgICByZXR1cm4gbnVsbDsKCQkgICAgfQogICAgICAgICAgICBlbHNlIGlmKCByZXN1bHQuZ2V0U2hvcnRjdXQoKSA9PSAnQScgKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgcmVzb3VyY2VDb250ZXh0LnNldENoZWNrb3V0RmlsZXNFbmFibGVkKHRydWUpOwogICAgICAgICAgICB9CiAgICAgICAgICB9CgogICAgICAgICAgSUZpbGVbXSBmaWxlcyA9IG5ldyBJRmlsZVsxXTsKICAgICAgICAgIGZpbGVzWzBdID0gKElGaWxlKWNoaWxkOwogICAgICAgICAgCiAgICAgICAgICBJU3RhdHVzIHN0YXR1cyA9IGdldFdvcmtzcGFjZSgpLnZhbGlkYXRlRWRpdChmaWxlcyxudWxsKTsKICAgICAgICAgIAogICAgICAgICAgdHJ5CiAgICAgICAgICB7CiAgICAgICAgICAgIHN0YXR1c0hhbmRsZXIucmVwb3J0KCBzdGF0dXMgKTsKICAgICAgICAgIH0KICAgICAgICAgIGNhdGNoKCBTdGF0dXNFeGNlcHRpb24gZXhjICkKICAgICAgICAgIHsKICAgICAgICAgICAgcmV0dXJuIG51bGw7CiAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICAvL0NoYW5nZSB0aGUgY29udGVudHMgb2YgdGhlIGV4aXN0aW5nIGZpbGUuCiAgICAgICAgSUZpbGUgZmlsZSA9IHBhcmVudC5nZXRGaWxlKCBuZXcgUGF0aChmaWxlTmFtZSkgKTsKICAgICAgICBmaWxlLnNldENvbnRlbnRzKCBpbnB1dFN0cmVhbSwgdHJ1ZSwgdHJ1ZSwgbnVsbCApOwogICAgICAgIAogICAgICAgIHJldHVybiBmaWxlOwogICAgICAKICAgICAgfQogICAgICBlbHNlCiAgICAgIHsKICAgICAgICB0aHJvdyBuZXcgQ29yZUV4Y2VwdGlvbiggCiAgICAgICAgICBuZXcgU3RhdHVzKCBJU3RhdHVzLkVSUk9SLAogICAgICAgICAgICAgICAgICAgICAgIlJlc291cmNlVXRpbHMiLAogICAgICAgICAgICAgICAgICAgICAgMCwgCiAgICAgICAgICAgICAgICAgICAgICBOTFMuYmluZChFbnZpcm9ubWVudE1lc3NhZ2VzLk1TR19FUlJPUl9SRVNPVVJDRV9OT1RfRklMRSwKCQkJCSAgICAgICAgICAgICAgICAgICAgICAgbmV3IE9iamVjdFtdIHtwYXJlbnQuZ2V0RnVsbFBhdGgoKS5hcHBlbmQoZmlsZU5hbWUpfSksCgkJCQkJICBudWxsICkgKTsKICAgICAgfQogICAgfQogICAgZWxzZQogICAgewogICAgICAvL0NyZWF0ZSBhIG5ldyBmaWxlLgogICAgICBJRmlsZSBmaWxlID0gcGFyZW50LmdldEZpbGUoIG5ldyBQYXRoKGZpbGVOYW1lKSApOwogICAgICBmaWxlLmNyZWF0ZSggaW5wdXRTdHJlYW0sIHRydWUsIG51bGwpOwogICAgICAKICAgICAgcmV0dXJuIGZpbGU7CiAgICB9CiAgfQoKIAogLyoqCiAgICogQ3JlYXRlcyBhIGZpbGUgb2YgdGhlIGdpdmVuIDxjb2RlPmFic29sdXRlUGF0aDwvY29kZT4KICAgKiBhbmQgcmV0dXJucyBpdHMgaGFuZGxlIGFzIGFuIDxjb2RlPklGaWxlPC9jb2RlPi4KICAgKiBJZiB0aGUgZmlsZSBjYW5ub3QgYmUgY3JlYXRlZCwgYQogICAqIDxjb2RlPkNvcmVFeGNlcHRpb248L2NvZGU+IGNvbnRhaW5pbmcgYW4KICAgKiA8Y29kZT5JU3RhdHVzPC9jb2RlPiBvYmplY3QgaXMgdGhyb3duLgogICAqIEBwYXJhbSBhYnNvbHV0ZVBhdGggVGhlIGFic29sdXRlIHBhdGggb2YgdGhlIGZpbGUgdG8gY3JlYXRlLgogICAqIFRoZSBwcm9qZWN0IGF0IHRoZSBiZWdpbm5pbmcgb2YgdGhlIHBhdGggbXVzdCBhbHJlYWR5IGV4aXN0LAogICAqIHRoYXQgaXMsIHRoaXMgbWV0aG9kIGNhbm5vdCBiZSB1c2VkIHRvIGNyZWF0ZSBwcm9qZWN0cy4KICAgKiBAcGFyYW0gcHJvZ3Jlc3NNb25pdG9yIFRoZSBwcm9ncmVzcyBtb25pdG9yIGZvciB0aGUgb3BlcmF0aW9uLCBvciBudWxsLgogICAqIEByZXR1cm4gVGhlIHtAbGluayBvcmcuZWNsaXBzZS5jb3JlLnJlc291cmNlcy5JRmlsZSBJRmlsZX0KICAgKiBoYW5kbGUgb2YgdGhlIGZpbGUuCiAgICogQHRocm93cyBDb3JlRXhjZXB0aW9uIEFuIGV4Y2VwdGlvbiBjb250YWluaW5nIGFuCiAgICoge0BsaW5rIG9yZy5lY2xpcHNlLmNvcmUucnVudGltZS5JU3RhdHVzIElTdGF0dXN9CiAgICogd2l0aCBhIHNldmVyaXR5IG9mIDxjb2RlPklTdGF0dXMuRVJST1I8L2NvZGU+IGFuZCBhCiAgICogbG9jYWxlLXNwZWNpZmljIGRlc2NyaXB0aW9uIG9mIHRoZSBjYXVzZS4KICAgKi8KICAgcHVibGljIHN0YXRpYyBJRmlsZSBjcmVhdGVGaWxlQXRMb2NhdGlvbiAoCiAgICAgUmVzb3VyY2VDb250ZXh0IHJlc291cmNlQ29udGV4dCwKICAgICBJUGF0aCAgICAgICAgICAgYWJzb2x1dGVQYXRoLAogICAgIElucHV0U3RyZWFtICAgICBpbnB1dFN0cmVhbSwKICAgICBJUHJvZ3Jlc3NNb25pdG9yIHByb2dyZXNzTW9uaXRvciwKICAgICBJU3RhdHVzSGFuZGxlciAgIHN0YXR1c0hhbmRsZXIgKQoKICAgICB0aHJvd3MgQ29yZUV4Y2VwdGlvbiAKICAgeyAgICAKICAgICBpZiAoIWFic29sdXRlUGF0aC5pc0Fic29sdXRlKCkpCiAgICAgewogICAgICAgdGhyb3cgbmV3IENvcmVFeGNlcHRpb24obmV3IFN0YXR1cyhJU3RhdHVzLkVSUk9SLCAiUmVzb3VyY2VVdGlscyIsMCxOTFMuYmluZChFbnZpcm9ubWVudE1lc3NhZ2VzLk1TR19FUlJPUl9QQVRIX05PVF9BQlNPTFVURSxuZXcgT2JqZWN0W10ge2Fic29sdXRlUGF0aC50b1N0cmluZygpfSksbnVsbCkpOwogICAgIH0KICAgICBpZiAoYWJzb2x1dGVQYXRoLnNlZ21lbnRDb3VudCgpIDwgMSkKICAgICB7CiAgICAgICB0aHJvdyBuZXcgQ29yZUV4Y2VwdGlvbihuZXcgU3RhdHVzKElTdGF0dXMuRVJST1IsIlJlc291cmNlVXRpbHMiLDAsTkxTLmJpbmQoRW52aXJvbm1lbnRNZXNzYWdlcy5NU0dfRVJST1JfUEFUSF9FTVBUWSxuZXcgT2JqZWN0W10ge2Fic29sdXRlUGF0aC50b1N0cmluZygpfSksbnVsbCkpOwogICAgIH0KICAgICBpZiAoYWJzb2x1dGVQYXRoLnNlZ21lbnRDb3VudCgpIDwgMikKICAgICB7CiAgICAgICB0aHJvdyBuZXcgQ29yZUV4Y2VwdGlvbihuZXcgU3RhdHVzKElTdGF0dXMuRVJST1IsIlJlc291cmNlVXRpbHMiLDAsTkxTLmJpbmQoRW52aXJvbm1lbnRNZXNzYWdlcy5NU0dfRVJST1JfUEFUSF9OT1RfRk9MREVSLG5ldyBPYmplY3RbXSB7YWJzb2x1dGVQYXRoLnRvU3RyaW5nKCl9KSxudWxsKSk7CiAgICAgfQogICAgIElDb250YWluZXIgcGFyZW50ICAgPSBtYWtlRm9sZGVyUGF0aEF0TG9jYXRpb24ocmVzb3VyY2VDb250ZXh0LCBhYnNvbHV0ZVBhdGgucmVtb3ZlTGFzdFNlZ21lbnRzKDEpLCBwcm9ncmVzc01vbml0b3IsIHN0YXR1c0hhbmRsZXIpOwogICAgIFN0cmluZyAgICAgZmlsZU5hbWUgPSBhYnNvbHV0ZVBhdGgubGFzdFNlZ21lbnQoKTsKICAgICAKICAgICBjaGVja1BhcmVudCggcGFyZW50LCBhYnNvbHV0ZVBhdGggKTsKICAgICAKICAgICByZXR1cm4gbWFrZUZpbGUocmVzb3VyY2VDb250ZXh0LCBwYXJlbnQsIGZpbGVOYW1lLCBpbnB1dFN0cmVhbSwgcHJvZ3Jlc3NNb25pdG9yLCBzdGF0dXNIYW5kbGVyKTsKICAgfQoKLyoqCiAgKiBDcmVhdGVzIGEgcGF0aCBvZiBmb2xkZXJzIHVzaW5nIGFic29sdXRlIGZpbGVuYW1lcy4KICAqIERvIG5vdCBjYWxsIHdpdGggYW4gYWJzb2x1dGVQYXRoIG9mIGxlc3MgdGhhbiBvbmUgc2VnbWVudC4KICAqIEBwYXJhbSByZXNvdXJjZUNvbnRleHQgdGhlIHJlc291cmNlIGNvbnRleHQgZm9yIG1ha2luZyBmb2xkZXJzLgogICogQHBhcmFtIHJlc291cmNlIHRoZSByZXNvdXJjZSB0aGF0IHdpbGwgYmUgY3JlYXRlZC4KICAqIEBwYXJhbSBwcm9ncmVzc01vbml0b3IgdGhlIHByb2dyZXNzIG1vbml0b3IgdG8gYmUgdXNlZC4KICAqIEBwYXJhbSBzdGF0dXNIYW5kbGVyIHRoZSBzdGF0dXMgaGFuZGxlci4KICAqIEByZXR1cm4gcmV0dXJucyB0aGUgSUNvbnRhaW5lciBvZiB0aGUgY3JlYXRlZCBmb2xkZXIuCiAgKi8KIHB1YmxpYyBzdGF0aWMgSUNvbnRhaW5lciBtYWtlRm9sZGVyUGF0aEF0TG9jYXRpb24gKAogICBSZXNvdXJjZUNvbnRleHQgIHJlc291cmNlQ29udGV4dCwKICAgSUNvbnRhaW5lciAgICAgICByZXNvdXJjZSwKICAgSVByb2dyZXNzTW9uaXRvciBwcm9ncmVzc01vbml0b3IsCiAgIElTdGF0dXNIYW5kbGVyICAgc3RhdHVzSGFuZGxlciApCiAKICAgdGhyb3dzIENvcmVFeGNlcHRpb24KICAgewoJIGlmIChyZXNvdXJjZS5leGlzdHMoKSkKCSB7CgkJIGlmIChyZXNvdXJjZSBpbnN0YW5jZW9mIElDb250YWluZXIpCgkJIHsKCQkJIHJldHVybiAoSUNvbnRhaW5lcikgcmVzb3VyY2U7CgkJIH0KCQkgZWxzZQoJCSB7CgkJCSB0aHJvdyBuZXcgQ29yZUV4Y2VwdGlvbigKCQkJCQkgbmV3IFN0YXR1cyggSVN0YXR1cy5FUlJPUiwgCgkJCQkJCQkgIlJlc291cmNlVXRpbHMiLAoJCQkJCQkJIDAsIAoJCQkJCQkJIE5MUy5iaW5kKEVudmlyb25tZW50TWVzc2FnZXMuTVNHX0VSUk9SX1JFU09VUkNFX05PVF9GT0xERVIsCgkJCQkJCQkJCSBuZXcgT2JqZWN0W117IHJlc291cmNlLmdldEZ1bGxQYXRoKCkudG9TdHJpbmcoKSB9KSwKCQkJCQkJCQkJIG51bGwgKSApOwoJCSB9CgkgfQoJIGVsc2UKCSB7CgkJIElDb250YWluZXIgcGFyZW50ID0gbWFrZUZvbGRlclBhdGhBdExvY2F0aW9uKHJlc291cmNlQ29udGV4dCwgcmVzb3VyY2UuZ2V0UGFyZW50KCksIHByb2dyZXNzTW9uaXRvciwgc3RhdHVzSGFuZGxlciApOwoJCSBTdHJpbmcgZm9sZGVyTmFtZSA9IHJlc291cmNlLmdldE5hbWUoKTsKCQkgCgkJIHJldHVybiBtYWtlRm9sZGVyKHJlc291cmNlQ29udGV4dCwgcGFyZW50LCBmb2xkZXJOYW1lLCBwcm9ncmVzc01vbml0b3IgLCBzdGF0dXNIYW5kbGVyICk7CgkgfQogfQogCiAvKioKICAqIENyZWF0ZXMgYSBwYXRoIG9mIGZvbGRlcnMuCiAgKiBEbyBub3QgY2FsbCB3aXRoIGFuIGFic29sdXRlUGF0aCBvZiBsZXNzIHRoYW4gb25lIHNlZ21lbnQuCiAgKiBAcGFyYW0gcmVzb3VyY2VDb250ZXh0IHRoZSByZXNvdXJjZSBjb250ZXh0IGZvciBtYWtpbmcgZm9sZGVycy4KICAqIEBwYXJhbSBhYnNvbHV0ZVBhdGggdGhlIHBhdGggb2YgZm9sZGVycyB0aGF0IHdpbGwgYmUgY3JlYXRlZC4KICAqIEBwYXJhbSBwcm9ncmVzc01vbml0b3IgdGhlIHByb2dyZXNzIG1vbml0b3IgdG8gYmUgdXNlZC4KICAqIEBwYXJhbSBzdGF0dXNIYW5kbGVyIHRoZSBzdGF0dXMgaGFuZGxlci4KICAqIEByZXR1cm4gcmV0dXJucyB0aGUgSUNvbnRhaW5lciBvZiB0aGUgY3JlYXRlZCBmb2xkZXIuCiAgKi8KIHB1YmxpYyBzdGF0aWMgSUNvbnRhaW5lciBtYWtlRm9sZGVyUGF0aEF0TG9jYXRpb24gKAogICBSZXNvdXJjZUNvbnRleHQgIHJlc291cmNlQ29udGV4dCwKICAgSVBhdGggICAgICAgICAgICBhYnNvbHV0ZVBhdGgsCiAgIElQcm9ncmVzc01vbml0b3IgcHJvZ3Jlc3NNb25pdG9yLAogICBJU3RhdHVzSGFuZGxlciAgICBzdGF0dXNIYW5kbGVyICkKIAogICB0aHJvd3MgQ29yZUV4Y2VwdGlvbgogewogCXJldHVybiBtYWtlRm9sZGVyUGF0aEF0TG9jYXRpb24ocmVzb3VyY2VDb250ZXh0LAogCQlnZXRXb3Jrc3BhY2VSb290KCkuZ2V0Q29udGFpbmVyRm9yTG9jYXRpb24oYWJzb2x1dGVQYXRoKSwKIAkJcHJvZ3Jlc3NNb25pdG9yLCBzdGF0dXNIYW5kbGVyKTsKIH0KIAogCgp9Cg==