LyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogQ29weXJpZ2h0IChjKSAyMDAxLCAyMDA4IElCTSBDb3Jwb3JhdGlvbiBhbmQgb3RoZXJzLgogKiBBbGwgcmlnaHRzIHJlc2VydmVkLiBUaGlzIHByb2dyYW0gYW5kIHRoZSBhY2NvbXBhbnlpbmcgbWF0ZXJpYWxzCiAqIGFyZSBtYWRlIGF2YWlsYWJsZSB1bmRlciB0aGUgdGVybXMgb2YgdGhlIEVjbGlwc2UgUHVibGljIExpY2Vuc2UgdjEuMAogKiB3aGljaCBhY2NvbXBhbmllcyB0aGlzIGRpc3RyaWJ1dGlvbiwgYW5kIGlzIGF2YWlsYWJsZSBhdAogKiBodHRwOi8vd3d3LmVjbGlwc2Uub3JnL2xlZ2FsL2VwbC12MTAuaHRtbAogKgogKiBDb250cmlidXRvcnM6CiAqIElCTSBDb3Jwb3JhdGlvbiAtIGluaXRpYWwgQVBJIGFuZCBpbXBsZW1lbnRhdGlvbgogKiB5eXl5bW1kZCBidWcgICAgICBFbWFpbCBhbmQgb3RoZXIgY29udGFjdCBpbmZvcm1hdGlvbgogKiAtLS0tLS0tLSAtLS0tLS0tLSAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQogKiAyMDA2MDExMiAgIDEyMTE5OSBqZXNwZXJAc2Vsc2thYmV0Lm9yZyAtIEplc3BlciBN+GxsZXIKICogMjAwNzA4MTMgICAxODg5OTkgcG1vb2drQGNhLmlibS5jb20gLSBQZXRlciBNb29nawogKiAyMDA4MDYxMyAgIDIzNjUyMyBtYWthbmRyZUBjYS5pYm0uY29tIC0gQW5kcmV3IE1haywgT3ZlcndyaXRlIHNldHRpbmcgb24gV2ViIHNlcnZpY2Ugd2l6YXJkIGlzIGNvdXBsZWQgd2l0aCBwcmVmZXJlbmNlCiAqIDIwMDgwNjI1ICAgMjM3MTI5IG1ha2FuZHJlQGNhLmlibS5jb20gLSBBbmRyZXcgTWFrLCBFcnJvciBtb3ZpbmcgcmVzb3VyY2U6IG51bGwKICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCnBhY2thZ2Ugb3JnLmVjbGlwc2Uud3N0LmNvbW1hbmQuaW50ZXJuYWwuZW52LmNvbW1vbjsKCgppbXBvcnQgamF2YS5pby5JT0V4Y2VwdGlvbjsKaW1wb3J0IGphdmEuaW8uSW5wdXRTdHJlYW07CmltcG9ydCBqYXZhLmlvLk91dHB1dFN0cmVhbTsKaW1wb3J0IGphdmEudXRpbC5WZWN0b3I7CgppbXBvcnQgb3JnLmVjbGlwc2UuY29yZS5yZXNvdXJjZXMuSUNvbnRhaW5lcjsKaW1wb3J0IG9yZy5lY2xpcHNlLmNvcmUucmVzb3VyY2VzLklGaWxlOwppbXBvcnQgb3JnLmVjbGlwc2UuY29yZS5yZXNvdXJjZXMuSUZvbGRlcjsKaW1wb3J0IG9yZy5lY2xpcHNlLmNvcmUucmVzb3VyY2VzLklQcm9qZWN0OwppbXBvcnQgb3JnLmVjbGlwc2UuY29yZS5yZXNvdXJjZXMuSVJlc291cmNlOwppbXBvcnQgb3JnLmVjbGlwc2UuY29yZS5yZXNvdXJjZXMuSVdvcmtzcGFjZTsKaW1wb3J0IG9yZy5lY2xpcHNlLmNvcmUucmVzb3VyY2VzLklXb3Jrc3BhY2VSb290OwppbXBvcnQgb3JnLmVjbGlwc2UuY29yZS5yZXNvdXJjZXMuUmVzb3VyY2VzUGx1Z2luOwppbXBvcnQgb3JnLmVjbGlwc2UuY29yZS5ydW50aW1lLkNvcmVFeGNlcHRpb247CmltcG9ydCBvcmcuZWNsaXBzZS5jb3JlLnJ1bnRpbWUuSVBhdGg7CmltcG9ydCBvcmcuZWNsaXBzZS5jb3JlLnJ1bnRpbWUuSVByb2dyZXNzTW9uaXRvcjsKaW1wb3J0IG9yZy5lY2xpcHNlLmNvcmUucnVudGltZS5JU3RhdHVzOwppbXBvcnQgb3JnLmVjbGlwc2UuY29yZS5ydW50aW1lLlBhdGg7CmltcG9ydCBvcmcuZWNsaXBzZS5jb3JlLnJ1bnRpbWUuUGx1Z2luOwppbXBvcnQgb3JnLmVjbGlwc2UuY29yZS5ydW50aW1lLlN0YXR1czsKaW1wb3J0IG9yZy5lY2xpcHNlLm9zZ2kudXRpbC5OTFM7CmltcG9ydCBvcmcuZWNsaXBzZS53c3QuY29tbWFuZC5pbnRlcm5hbC5lbnYuRW52aXJvbm1lbnRNZXNzYWdlczsKaW1wb3J0IG9yZy5lY2xpcHNlLndzdC5jb21tYW5kLmludGVybmFsLmVudi5jb250ZXh0LlBlcnNpc3RlbnRSZXNvdXJjZUNvbnRleHQ7CmltcG9ydCBvcmcuZWNsaXBzZS53c3QuY29tbWFuZC5pbnRlcm5hbC5lbnYuY29yZS5jb21tb24uU3RhdHVzVXRpbHM7CmltcG9ydCBvcmcuZWNsaXBzZS53c3QuY29tbWFuZC5pbnRlcm5hbC5lbnYuY29yZS5jb250ZXh0LlJlc291cmNlQ29udGV4dDsKaW1wb3J0IG9yZy5lY2xpcHNlLndzdC5jb21tb24uZW52aXJvbm1lbnQuQ2hvaWNlOwppbXBvcnQgb3JnLmVjbGlwc2Uud3N0LmNvbW1vbi5lbnZpcm9ubWVudC5JU3RhdHVzSGFuZGxlcjsKaW1wb3J0IG9yZy5lY2xpcHNlLndzdC5jb21tb24uZW52aXJvbm1lbnQuU3RhdHVzRXhjZXB0aW9uOwoKCgovKioKKiBUaGlzIGNsYXNzIGNvbnRhaW5zIHVzZWZ1bCBtZXRob2RzIGZvciB3b3JraW5nIHdpdGggRWNsaXBzZSByZXNvdXJjZXMuCiovCnB1YmxpYyBmaW5hbCBjbGFzcyBGaWxlUmVzb3VyY2VVdGlscwp7CiAgLy8KICAvLyBLZWVwcyB0aGUgSVdvcmtzcGFjZSBoYW5naW5nIGFyb3VuZC4gU2VlIGdldFdvcmtzcGFjZSgpLgogIC8vCiAgcHJpdmF0ZSBzdGF0aWMgSVdvcmtzcGFjZSB3b3Jrc3BhY2VfID0gbnVsbDsKICAvLwogIC8vIEtlZXBzIHRoZSBJV29ya3NwYWNlUm9vdCBoYW5naW5nIGFyb3VuZC4gU2VlIGdldFdvcmtzcGFjZVJvb3QoKS4KICAvLwogIHByaXZhdGUgc3RhdGljIElXb3Jrc3BhY2VSb290IHJvb3RfID0gbnVsbDsKICAKLy8gIHByaXZhdGUgc3RhdGljIE1lc3NhZ2VVdGlscyBtc2dfID0gbmV3IE1lc3NhZ2VVdGlscyggIm9yZy5lY2xpcHNlLndzdC5jb21tYW5kLmludGVybmFsLmVudi5jb21tb24uZW52aXJvbm1lbnQiLCBuZXcgRmlsZVJlc291cmNlVXRpbHMoKSApOwoKCiAvKioKICAqIFJldHVybnMgdGhlIElXb3Jrc3BhY2VSb290IG9iamVjdC4KICAqIEByZXR1cm4gVGhlIElXb3Jrc3BhY2VSb290IG9iamVjdC4KICAqLwogIHB1YmxpYyBzdGF0aWMgSVdvcmtzcGFjZVJvb3QgZ2V0V29ya3NwYWNlUm9vdCAoKQogIHsKICAgIGlmIChyb290XyA9PSBudWxsKQogICAgewogICAgICByb290XyA9IFJlc291cmNlc1BsdWdpbi5nZXRXb3Jrc3BhY2UoKS5nZXRSb290KCk7CiAgICB9CiAgICByZXR1cm4gcm9vdF87CiAgfQoKICAvKioKCSAqIFJldHVybnMgdGhlIElXb3Jrc3BhY2Ugb2JqZWN0LgoJICogCgkgKiBAcmV0dXJuIFRoZSBJV29ya3NwYWNlIG9iamVjdC4KCSAqLwogIHB1YmxpYyBzdGF0aWMgSVdvcmtzcGFjZSBnZXRXb3Jrc3BhY2UgKCkKICB7CiAgICBpZiAod29ya3NwYWNlXyA9PSBudWxsKQogICAgewogICAgICBpZiAocm9vdF8gPT0gbnVsbCkKICAgICAgewogICAgICAgIHJvb3RfID0gUmVzb3VyY2VzUGx1Z2luLmdldFdvcmtzcGFjZSgpLmdldFJvb3QoKTsKICAgICAgfQogICAgICAKICAgICAgd29ya3NwYWNlXyA9IHJvb3RfLmdldFdvcmtzcGFjZSgpOwogICAgfQogICAgCiAgICByZXR1cm4gd29ya3NwYWNlXzsKICB9CiAgCiAgLyoqCiAgICogCiAgICogQHJldHVybiByZXR1cm5zIGFuIGFycmF5IG9mIHRocmVlIGNvbW1vbiBjaG9pY2VzLiAoaWUuIFllcywgeWVzIGFsbCwgYW5kIGNhbmNlbCApCiAgICovCiAgcHVibGljIHN0YXRpYyBDaG9pY2VbXSBnZXRUaHJlZVN0YXRlRmlsZU9wdGlvbnMoKSAKICB7CiAgICBWZWN0b3IgY2hvaWNlcyA9IG5ldyBWZWN0b3IoKTsKICAgIAogICAgY2hvaWNlcy5hZGQobmV3IENob2ljZSggJ1knLCBFbnZpcm9ubWVudE1lc3NhZ2VzLkxBQkVMX1lFUykpOwogICAgY2hvaWNlcy5hZGQobmV3IENob2ljZSggJ0EnLCBFbnZpcm9ubWVudE1lc3NhZ2VzLkxBQkVMX1lFU19UT19BTEwpKTsKICAgIGNob2ljZXMuYWRkKG5ldyBDaG9pY2UoICdDJywgRW52aXJvbm1lbnRNZXNzYWdlcy5MQUJFTF9DQU5DRUwpKTsKICAgIAogICAgcmV0dXJuIChDaG9pY2VbXSljaG9pY2VzLnRvQXJyYXkobmV3IENob2ljZVtjaG9pY2VzLnNpemUoKV0pOwogIH0KICAKICAvKioKICAqIFJldHVybnMgYW4KICAqIHtAbGluayBvcmcuZWNsaXBzZS5jb3JlLnJlc291cmNlcy5JUmVzb3VyY2UgSVJlc291cmNlfQogICogb2YgdGhlIGdpdmVuIGFic29sdXRlIHBhdGhuYW1lIG9yIG51bGwgaWYgbm8gc3VjaCByZXNvdXJjZSBleGlzdHMuCiAgKiBAcGFyYW0gYWJzb2x1dGVQYXRobmFtZSBUaGUgYWJzb2x1dGUgcGF0aCBvZiB0aGUgcmVzb3VyY2UuCiAgKiBAcmV0dXJuIFRoZSA8Y29kZT5JUmVzb3VyY2U8L2NvZGU+LgogICovCiAgcHVibGljIHN0YXRpYyBJUmVzb3VyY2UgZmluZFJlc291cmNlICggU3RyaW5nIGFic29sdXRlUGF0aG5hbWUgKQogIHsKICAgIGlmIChhYnNvbHV0ZVBhdGhuYW1lID09IG51bGwpCiAgICB7CiAgICAgIHJldHVybiBudWxsOwogICAgfQogICAgCiAgICByZXR1cm4gZmluZFJlc291cmNlKG5ldyBQYXRoKGFic29sdXRlUGF0aG5hbWUpKTsKICB9CgogIC8qKgogICogUmV0dXJucyBhbgogICoge0BsaW5rIG9yZy5lY2xpcHNlLmNvcmUucmVzb3VyY2VzLklSZXNvdXJjZSBJUmVzb3VyY2V9CiAgKiBvZiB0aGUgZ2l2ZW4gYWJzb2x1dGUgcGF0aCBvciBudWxsIGlmIG5vIHN1Y2ggcmVzb3VyY2UgZXhpc3RzLgogICogQHBhcmFtIGFic29sdXRlUGF0aCBUaGUgYWJzb2x1dGUgPGNvZGU+SVBhdGg8L2NvZGU+IG9mIHRoZSByZXNvdXJjZS4KICAqIEByZXR1cm4gVGhlIDxjb2RlPklSZXNvdXJjZTwvY29kZT4uCiAgKi8KICBwdWJsaWMgc3RhdGljIElSZXNvdXJjZSBmaW5kUmVzb3VyY2UgKCBJUGF0aCBhYnNvbHV0ZVBhdGggKQogIHsKICAgIGlmIChhYnNvbHV0ZVBhdGggPT0gbnVsbCkKICAgIHsKICAgICAgcmV0dXJuIG51bGw7CiAgICB9CiAgICAKICAgIHJldHVybiBGaWxlUmVzb3VyY2VVdGlscy5nZXRXb3Jrc3BhY2VSb290KCkuZmluZE1lbWJlcihhYnNvbHV0ZVBhdGgpOwogIH0KICAKICAvKioKICAgKiBDb3BpZXMgYSBmaWxlIGZyb20gYSBwbHVnaW4ncyBpbnN0YWxsYXRpb24gbG9jYXRpb24KICAgKiB0byBhbiBFY2xpcHNlIGZvbGRlci4KICAgKiBAcGFyYW0gcGx1Z2luIFRoZSBwbHVnaW4gY29udGFpbmluZyB0aGUgZmlsZXMgdG8gY29weS4KICAgKiBNdXN0IG5vdCBiZSBudWxsLgogICAqIEBwYXJhbSBzb3VyY2VQYXRoIFRoZSBwYXRoLCByZWxhdGl2ZSB0byB0aGUgPGNvZGU+cGx1Z2luPC9jb2RlPgogICAqIGluc3RhbGwgbG9jYXRpb24sIGNvbnRhaW5pbmcgdGhlIGZpbGVzIHRvIGNvcHkuCiAgICogSWYgbnVsbCwgdGhlbiB0aGUgcGx1Z2luIGluc3RhbGwgbG9jYXRpb24gaXMgdGhlIHNvdXJjZSBwYXRoCiAgICogKGllLiBudWxsIGlzIGVxdWl2YWxlbnQgdG8gIi4iKS4KICAgKiBAcGFyYW0gcGF0aG5hbWUgVGhlIHBhdGhuYW1lIG9mIHRoZSBmaWxlIHRvIGNvcHkuCiAgICogVGhlIHBhdGhuYW1lIGlzIHJlbGF0aXZlIHRvIHRoZSA8Y29kZT5wbHVnaW4gc291cmNlUGF0aDwvY29kZT4uCiAgICogTXVzdCBub3QgYmUgbnVsbC4KICAgKiBAcGFyYW0gdGFyZ2V0UGF0aCBUaGUgYWJzb2x1dGUgRWNsaXBzZSBwYXRoIG9mIHRoZSBmb2xkZXIgdG8KICAgKiB3aGljaCB0aGUgZmlsZSB3aWxsIGJlIGNvcGllZC4gVGhlIHJlbGF0aXZlIHBhdGhuYW1lIG9mIHRoZQogICAqIGZpbGUgaXMgcHJlc2VydmVkLgogICAqIE11c3Qgbm90IGJlIG51bGwuCiAgICogQHBhcmFtIGNyZWF0ZUZvbGRlcnMgVGhlIGludGVybWVkaWF0ZSBmb2xkZXIgY3JlYXRpb24gcG9saWN5LCBvbmUgb2YKICAgKiB7QGxpbmsgI0NSRUFURSBDUkVBVEV9IG9yIHtAbGluayAjRE9OVF9DUkVBVEUgRE9OVF9DUkVBVEV9LgogICAqIDx1bD4KICAgKiA8bGk+PGNvZGU+Q1JFQVRFPC9jb2RlPiAtCiAgICogSWYgYW55IGludGVybWVkaWF0ZSBmb2xkZXJzIGluIHRoZSBnaXZlbiA8Y29kZT5hYnNvbHV0ZVBhdGg8L2NvZGU+CiAgICogZG8gbm90IGV4aXN0LCB0aGV5IHdpbGwgYmUgY3JlYXRlZC4KICAgKiA8bGk+PGNvZGU+RE9OVF9DUkVBVEU8L2NvZGU+IC0KICAgKiBJZiBhbnkgaW50ZXJtZWRpYXRlIGZvbGRlcnMgaW4gdGhlIGdpdmVuIDxjb2RlPmFic29sdXRlUGF0aDwvY29kZT4KICAgKiBkbyBub3QgZXhpc3QsIHRoZSBtZXRob2Qgd2lsbCB0aHJvdyBhIDxjb2RlPkNvcmVFeGNlcHRpb248L2NvZGU+LgogICAqIDwvdWw+CiAgICogQHBhcmFtIG92ZXJ3cml0ZUZpbGUgVGhlIHBvbGljeSBmb3IgZXhpc3RpbmcgZmlsZXMsIG9uZSBvZgogICAqIHtAbGluayAjT1ZFUldSSVRFIE9WRVJXUklURX0gb3Ige0BsaW5rICNET05UX09WRVJXUklURSBET05UX09WRVJXUklURX0uCiAgICogPHVsPgogICAqIDxsaT48Y29kZT5PVkVSV1JJVEU8L2NvZGU+IC0KICAgKiBJZiBhIHJlc291cmNlIG9mIHRoZSBzYW1lIG5hbWUgYXMgdGhlIGdpdmVuCiAgICogPGNvZGU+YWJzb2x1dGVQYXRoPC9jb2RlPiBhbHJlYWR5IGV4aXN0cyBhbmQgaXMgYSBmaWxlLAogICAqIGl0IHdpbGwgYmUgcmVwbGFjZWQuCiAgICogSWYgdGhlIHJlc291cmNlIGFscmVhZHkgZXhpc3RzIGFuZCBpdCBpcyBub3QgYSBmaWxlLAogICAqIHRoZW4gbm8gZmlsZSB3aWxsIGJlIGNyZWF0ZWQgYW5kCiAgICogYSA8Y29kZT5Db3JlRXhjZXB0aW9uPC9jb2RlPiB3aWxsIGJlIHRocm93bi4KICAgKiA8bGk+PGNvZGU+RE9OVF9PVkVSV1JJVEU8L2NvZGU+IC0KICAgKiBJZiBhbnkgcmVzb3VyY2Ugb2YgdGhlIHNhbWUgbmFtZSBhcyB0aGUgZ2l2ZW4KICAgKiA8Y29kZT5hYnNvbHV0ZVBhdGg8L2NvZGU+IGFscmVhZHkgZXhpc3RzLAogICAqIHRoZW4gbm8gZmlsZSB3aWxsIGJlIGNyZWF0ZWQgYW5kCiAgICogYSA8Y29kZT5Db3JlRXhjZXB0aW9uPC9jb2RlPiB3aWxsIGJlIHRocm93bi4KICAgKiA8L3VsPgogICAqIEBwYXJhbSBwcm9ncmVzc01vbml0b3IgVGhlIHByb2dyZXNzIG1vbml0b3IgZm9yIHRoZSBvcGVyYXRpb24sIG9yIG51bGwuCiAgICogQHRocm93cyBDb3JlRXhjZXB0aW9uIEFuIGV4Y2VwdGlvbiBjb250YWluaW5nIGFuCiAgICoge0BsaW5rIG9yZy5lY2xpcHNlLmNvcmUucnVudGltZS5JU3RhdHVzIElTdGF0dXN9CiAgICogd2l0aCBhIHNldmVyaXR5IG9mIDxjb2RlPklTdGF0dXMuRVJST1I8L2NvZGU+IGFuZCBhCiAgICogbG9jYWxlLXNwZWNpZmljIGRlc2NyaXB0aW9uIG9mIHRoZSBjYXVzZS4KICAgKi8KICAgc3RhdGljIHB1YmxpYyB2b2lkIGNvcHlGaWxlKCBSZXNvdXJjZUNvbnRleHQgcmVzb3VyY2VDb250ZXh0LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFBsdWdpbiBwbHVnaW4sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgSVBhdGggc291cmNlUGF0aCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBJUGF0aCBwYXRobmFtZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBJUGF0aCB0YXJnZXRQYXRoLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIElQcm9ncmVzc01vbml0b3IgcHJvZ3Jlc3NNb25pdG9yLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIElTdGF0dXNIYW5kbGVyIHN0YXR1c01vbml0b3IgKQogICAgIHRocm93cyBDb3JlRXhjZXB0aW9uCiAgIHsKICAgICB0cnkKICAgICB7CiAgICAgICBJUGF0aCB0YXJnZXQgPSB0YXJnZXRQYXRoLmFwcGVuZChwYXRobmFtZSk7CiAgICAgICBJUGF0aCBzb3VyY2UgPSBzb3VyY2VQYXRoID09IG51bGwgPyBwYXRobmFtZSA6IHNvdXJjZVBhdGguYXBwZW5kKHBhdGhuYW1lKTsKICAgICAgIElucHV0U3RyZWFtIGlucHV0ID0gcGx1Z2luLm9wZW5TdHJlYW0oc291cmNlKTsKICAgICAgIGNyZWF0ZUZpbGUocmVzb3VyY2VDb250ZXh0LCB0YXJnZXQsIGlucHV0LCBwcm9ncmVzc01vbml0b3IsIHN0YXR1c01vbml0b3IpOwogICAgIH0KICAgICBjYXRjaCAoSU9FeGNlcHRpb24gZSkKICAgICB7CiAgICAgICB0aHJvdyBuZXcgQ29yZUV4Y2VwdGlvbihuZXcgU3RhdHVzKElTdGF0dXMuRVJST1IsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBwbHVnaW4uZ2V0QnVuZGxlKCkuZ2V0U3ltYm9saWNOYW1lKCksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAwLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRW52aXJvbm1lbnRNZXNzYWdlcy5NU0dfRVJST1JfSU8sZSkpOwogICAgIH0KICAgfQogICAKICAvKioKICAgKiBEZWxldGVzIGEgZmlsZSB1bmRlciBhIGNvbnRhaW5lci4KICAgKiBUaGUgY29udGFpbmVyIG11c3QgYWxyZWFkeSBleGlzdC4KICAgKiBAcGFyYW0gZmlsZSAtIHRoZSBJRmlsZSB0byBiZSBkZWxldGVkCiAgICogQHBhcmFtIHByb2dyZXNzTW9uaXRvcgogICAqIEBwYXJhbSBzdGF0dXNNb25pdG9yCiAgICogQHJldHVybiBUcnVlIGlmIHRoZSBmaWxlIGRvZXMgbm90IGV4aXN0IG9yIGlmIGl0IGV4aXN0cyBhbmQgaXMgc3VjY2Vzc2Z1bGx5IGRlbGV0ZWQuIEZhbHNlIG90aGVyd2lzZS4KICAgKi8KICBwdWJsaWMgc3RhdGljIGJvb2xlYW4gZGVsZXRlRmlsZSggUmVzb3VyY2VDb250ZXh0IHJlc291cmNlQ29udGV4dCwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIElGaWxlIGZpbGUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIElQcm9ncmVzc01vbml0b3IgcHJvZ3Jlc3NNb25pdG9yLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgSVN0YXR1c0hhbmRsZXIgc3RhdHVzTW9uaXRvcikKICAgIHRocm93cyBDb3JlRXhjZXB0aW9uCiAgewogICAgaWYgKGZpbGUuZXhpc3RzKCkpCiAgICB7CiAgICAgIGlmICghcmVzb3VyY2VDb250ZXh0LmlzT3ZlcndyaXRlRmlsZXNFbmFibGVkKCkpCiAgICAgIHsKICAgICAgICBJU3RhdHVzIHN0YXR1cyAKICAgICAgICAgID0gU3RhdHVzVXRpbHMud2FybmluZ1N0YXR1cyggTkxTLmJpbmQoRW52aXJvbm1lbnRNZXNzYWdlcy5NU0dfRVJST1JfRklMRV9PVkVSV1JJVEVfRElTQUJMRUQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbmV3IE9iamVjdFtdeyBmaWxlLmdldFBhcmVudCgpLmdldEZ1bGxQYXRoKCkudG9TdHJpbmcoKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZpbGUuZ2V0TmFtZSgpfSkgKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgIAogICAgICAgIENob2ljZSBjaG9pY2UgPSBzdGF0dXNNb25pdG9yLnJlcG9ydCggc3RhdHVzLCBnZXRUaHJlZVN0YXRlRmlsZU9wdGlvbnMoKSApOwogICAgICAgIAogICAgICAgIGlmKCBjaG9pY2UuZ2V0U2hvcnRjdXQoKSA9PSAnQycgKSByZXR1cm4gZmFsc2U7CiAgICAgICAgCiAgICAgICAgaWYoIGNob2ljZS5nZXRTaG9ydGN1dCgpID09ICdBJyApIHsKICAgICAgICAJcmVzb3VyY2VDb250ZXh0LnNldE92ZXJ3cml0ZUZpbGVzRW5hYmxlZCh0cnVlKTsKICAgICAgICAJUGVyc2lzdGVudFJlc291cmNlQ29udGV4dC5nZXRJbnN0YW5jZSgpLnNldE92ZXJ3cml0ZUZpbGVzRW5hYmxlZCh0cnVlKTsKICAgICAgICB9CiAgICAgIH0KICAgICAgCiAgICAgIC8vV2UgaGF2ZSBwZXJtaXNzaW9uIHRvIG92ZXJ3cml0ZSBzbyBjaGVjayBpZiBmaWxlIGlzIHJlYWQtb25seQogICAgICBpZiAoZmlsZS5pc1JlYWRPbmx5KCkpCiAgICAgIHsKICAgICAgICBpZiAoIXJlc291cmNlQ29udGV4dC5pc0NoZWNrb3V0RmlsZXNFbmFibGVkKCkpCiAgICAgICAgewogICAgICAgICAgSVN0YXR1cyBzdGF0dXMgCiAgICAgICAgICAgID0gU3RhdHVzVXRpbHMud2FybmluZ1N0YXR1cyggTkxTLmJpbmQoRW52aXJvbm1lbnRNZXNzYWdlcy5NU0dfRVJST1JfRklMRV9DSEVDS09VVF9ESVNBQkxFRCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5ldyBPYmplY3RbXXsgZmlsZS5nZXRQYXJlbnQoKS5nZXRGdWxsUGF0aCgpLnRvU3RyaW5nKCksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZpbGUuZ2V0TmFtZSgpfSkgKTsKICAgICAgICAgIAogICAgICAgICAgQ2hvaWNlIGNob2ljZSA9IHN0YXR1c01vbml0b3IucmVwb3J0KCBzdGF0dXMsIGdldFRocmVlU3RhdGVGaWxlT3B0aW9ucygpICk7CiAgICAgICAgICAKICAgICAgICAgIGlmKCBjaG9pY2UuZ2V0U2hvcnRjdXQoKSA9PSAnQycgKSByZXR1cm4gZmFsc2U7CiAgICAgICAgICAKICAgICAgICAgIGlmKCBjaG9pY2UuZ2V0U2hvcnRjdXQoKSA9PSAnQScgKSB7CiAgICAgICAgCSAgcmVzb3VyY2VDb250ZXh0LnNldENoZWNrb3V0RmlsZXNFbmFibGVkKHRydWUpOwogICAgICAgIAkgIFBlcnNpc3RlbnRSZXNvdXJjZUNvbnRleHQuZ2V0SW5zdGFuY2UoKS5zZXRDaGVja291dEZpbGVzRW5hYmxlZCh0cnVlKTsKICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgCiAgICAgICAgSUZpbGVbXSBmaWxlcyA9IG5ldyBJRmlsZVsxXTsKICAgICAgICBmaWxlc1swXSA9IGZpbGU7CiAgICAgICAgSVN0YXR1cyBzdGF0dXMgPSBnZXRXb3Jrc3BhY2UoKS52YWxpZGF0ZUVkaXQoZmlsZXMsIG51bGwpOwogICAgICAgIAogICAgICAgIGlmKCBzdGF0dXMuZ2V0U2V2ZXJpdHkoKSA9PSBJU3RhdHVzLkVSUk9SICkKICAgICAgICB7CiAgICAgICAgICBzdGF0dXNNb25pdG9yLnJlcG9ydEVycm9yKCBzdGF0dXMgKTsKICAgICAgICAgIHJldHVybiBmYWxzZTsKICAgICAgICB9CiAgICAgIH0KICAgICAgCiAgICAgIGZpbGUuZGVsZXRlKHRydWUsIG51bGwpOwogICAgfQogICAgLy9BdCB0aGlzIHBvaW50LCBlaXRoZXIgdGhlIGZpbGUgZGlkIG5vdCBleGlzdCBvciB3ZSBzdWNjZXNzZnVsbHkgZGVsZXRlZAogICAgLy8gaXQuIFJldHVybiBzdWNjZXNzLgogICAgcmV0dXJuIHRydWU7CiAgfQoKICAvKioKICAgKiBEZWxldGVzIGEgZm9sZGVyIHVuZGVyIGEgY29udGFpbmVyLgogICAqIEBwYXJhbSBmb2xkZXIgLSB0aGUgSUZvbGRlciB0byBiZSBkZWxldGVkCiAgICogQHBhcmFtIHByb2dyZXNzTW9uaXRvcgogICAqIEBwYXJhbSBzdGF0dXNNb25pdG9yCiAgICogQHJldHVybiBUcnVlIGlmIHRoZSBmb2xkZXIgZG9lcyBub3QgZXhpc3Qgb3IgaWYgaXQgZXhpc3RzIGFuZCBpcyBzdWNjZXNzZnVsbHkgZGVsZXRlZCBhbG9uZyB3aXRoIGl0cyBtZW1iZXJzLiBGYWxzZSBvdGhlcndpc2UuCiAgICovCiAgIHB1YmxpYyBzdGF0aWMgYm9vbGVhbiBkZWxldGVGb2xkZXIoIFJlc291cmNlQ29udGV4dCByZXNvdXJjZUNvbnRleHQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIElGb2xkZXIgZm9sZGVyLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBJUHJvZ3Jlc3NNb25pdG9yIHByb2dyZXNzTW9uaXRvciwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgSVN0YXR1c0hhbmRsZXIgc3RhdHVzTW9uaXRvciApCiAgICAgdGhyb3dzIENvcmVFeGNlcHRpb24KICAgewogICAgIGlmICghZm9sZGVyLmV4aXN0cygpKSByZXR1cm4gdHJ1ZTsKCiAgICAgYm9vbGVhbiAgICAgZGVsZXRlZCAgID0gdHJ1ZTsKICAgICBJUmVzb3VyY2VbXSByZXNvdXJjZXMgPSBmb2xkZXIubWVtYmVycygpOwogICAgIAogICAgIGZvciAoaW50IGk9MDsgaTxyZXNvdXJjZXMubGVuZ3RoOyBpKyspCiAgICAgewogICAgICAgSVJlc291cmNlIHJlc291cmNlID0gcmVzb3VyY2VzW2ldOwogICAgICAgaWYgKHJlc291cmNlIGluc3RhbmNlb2YgSUZpbGUpCiAgICAgICB7CiAgICAgICAgIGRlbGV0ZWQgPSBkZWxldGVGaWxlKHJlc291cmNlQ29udGV4dCwgKElGaWxlKXJlc291cmNlLCBwcm9ncmVzc01vbml0b3IsIHN0YXR1c01vbml0b3IpOwogICAgICAgfQogICAgICAgaWYgKHJlc291cmNlIGluc3RhbmNlb2YgSUZvbGRlcikKICAgICAgIHsKICAgICAgICAgZGVsZXRlZCA9IGRlbGV0ZUZvbGRlciggcmVzb3VyY2VDb250ZXh0LCAoSUZvbGRlcilyZXNvdXJjZSwgcHJvZ3Jlc3NNb25pdG9yLCBzdGF0dXNNb25pdG9yKTsKICAgICAgIH0KCiAgICAgICBpZiggIWRlbGV0ZWQgKSBicmVhazsKICAgICB9CiAgICAgCiAgICAgaWYoIGRlbGV0ZWQgKQogICAgIHsKICAgICAgIGZvbGRlci5kZWxldGUodHJ1ZSwgdHJ1ZSwgbnVsbCk7CiAgICAgICByZXR1cm4gdHJ1ZTsKICAgICB9CiAgICAgZWxzZQogICAgICAgcmV0dXJuIGZhbHNlOwogICB9CgogIC8qKgogICogQ3JlYXRlcyBhIGZpbGUgb2YgdGhlIGdpdmVuIDxjb2RlPmFic29sdXRlUGF0aDwvY29kZT4KICAqIGFuZCByZXR1cm5zIGl0cyBoYW5kbGUgYXMgYW4gPGNvZGU+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+Y3JlYXRlRm9sZGVyczwvY29kZT4gaXMgZmFsc2UuCiAgKiA8L29sPgogICovCgogIHB1YmxpYyBzdGF0aWMgT3V0cHV0U3RyZWFtIG5ld0ZpbGVPdXRwdXRTdHJlYW0gKAogICAgICAgUmVzb3VyY2VDb250ZXh0ICBjb250ZXh0LAogICAgICAgSVBhdGggICAgICAgICAgICBmaWxlLAogICAgICAgSVByb2dyZXNzTW9uaXRvciBwcm9ncmVzc01vbml0b3IsCiAgICAgICBJU3RhdHVzSGFuZGxlciAgICBzdGF0dXNIYW5kbGVyICkKIAogIHsKICAgIHJldHVybiBuZXcgRmlsZVJlc291cmNlT3V0cHV0U3RyZWFtKGNvbnRleHQsIGZpbGUsIHByb2dyZXNzTW9uaXRvciwgc3RhdHVzSGFuZGxlcik7CiAgfQoKICAvLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KICAvLyBOYXVnaHR5IGJpdHMuLi4KICAvLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KCiAgLy8KICAvLyBDcmVhdGVzIGEgcGF0aCBvZiBmb2xkZXJzLgogIC8vIERvIG5vdCBjYWxsIHdpdGggYW4gYWJzb2x1dGVQYXRoIG9mIGxlc3MgdGhhbiBvbmUgc2VnbWVudC4KICAvLwogIC8qKgogICAqIENyZWF0ZXMgYSBwYXRoIG9mIGZvbGRlcnMuCiAgICogRG8gbm90IGNhbGwgd2l0aCBhbiBhYnNvbHV0ZVBhdGggb2YgbGVzcyB0aGFuIG9uZSBzZWdtZW50LgogICAqIEBwYXJhbSByZXNvdXJjZUNvbnRleHQgdGhlIHJlc291cmNlIGNvbnRleHQgZm9yIG1ha2luZyBmb2xkZXJzLgogICAqIEBwYXJhbSBhYnNvbHV0ZVBhdGggdGhlIHBhdGggb2YgZm9sZGVycyB0aGF0IHdpbGwgYmUgY3JlYXRlZC4KICAgKiBAcGFyYW0gcHJvZ3Jlc3NNb25pdG9yIHRoZSBwcm9ncmVzcyBtb25pdG9yIHRvIGJlIHVzZWQuCiAgICogQHBhcmFtIHN0YXR1c0hhbmRsZXIgdGhlIHN0YXR1cyBoYW5kbGVyLgogICAqIEByZXR1cm4gcmV0dXJucyB0aGUgSUNvbnRhaW5lciBvZiB0aGUgY3JlYXRlZCBmb2xkZXIuCiAgICovCiAgcHVibGljIHN0YXRpYyBJQ29udGFpbmVyIG1ha2VGb2xkZXJQYXRoICgKICAgIFJlc291cmNlQ29udGV4dCAgcmVzb3VyY2VDb250ZXh0LAogICAgSVBhdGggICAgICAgICAgICBhYnNvbHV0ZVBhdGgsCiAgICBJUHJvZ3Jlc3NNb25pdG9yIHByb2dyZXNzTW9uaXRvciwKICAgIElTdGF0dXNIYW5kbGVyICAgIHN0YXR1c0hhbmRsZXIgKQogIAogICAgdGhyb3dzIENvcmVFeGNlcHRpb24KICB7CiAgICBpZiAoYWJzb2x1dGVQYXRoLnNlZ21lbnRDb3VudCgpIDw9IDEpCiAgICB7CiAgICAgIHJldHVybiBnZXRXb3Jrc3BhY2VSb290KCkuZ2V0UHJvamVjdChhYnNvbHV0ZVBhdGguc2VnbWVudCgwKSk7CiAgICB9CiAgICBlbHNlCiAgICB7CiAgICAgIElDb250YWluZXIgcGFyZW50ID0gbWFrZUZvbGRlclBhdGgocmVzb3VyY2VDb250ZXh0LCBhYnNvbHV0ZVBhdGgucmVtb3ZlTGFzdFNlZ21lbnRzKDEpLCBwcm9ncmVzc01vbml0b3IsIHN0YXR1c0hhbmRsZXIgKTsKICAgICAgU3RyaW5nIGZvbGRlck5hbWUgPSBhYnNvbHV0ZVBhdGgubGFzdFNlZ21lbnQoKTsKICAgICAgCiAgICAgIGNoZWNrUGFyZW50KCBwYXJlbnQsIGFic29sdXRlUGF0aCApOwogICAgICByZXR1cm4gbWFrZUZvbGRlcihyZXNvdXJjZUNvbnRleHQsIHBhcmVudCxmb2xkZXJOYW1lLCBwcm9ncmVzc01vbml0b3IgLCBzdGF0dXNIYW5kbGVyICk7CiAgICB9CiAgfQogIAogIHByaXZhdGUgc3RhdGljIHZvaWQgY2hlY2tQYXJlbnQoIElDb250YWluZXIgcGFyZW50LCBJUGF0aCBhYnNvbHV0ZVBhdGggKSB0aHJvd3MgQ29yZUV4Y2VwdGlvbgogIHsKICAgIGlmKCBwYXJlbnQgPT0gbnVsbCApCiAgICB7CiAgICAgIC8vIFRoZSBwYXJlbnQgaXMgbnVsbCwgc28gdGhlcmUgbXVzdCBoYXZlIGJlZW4gcHJvYmxlbXMgY3JlYXRpbmcgaXQuICBXZSB3aWxsIHRocm93CiAgICAgIC8vIGEgQ29yZUV4Y2VwdGlvbiB3YXJuaW5nIGZvciB0aGlzIHByb2JsZW0uCiAgICAgIElQYXRoICBwYXJlbnRQYXRoID0gYWJzb2x1dGVQYXRoLnJlbW92ZUxhc3RTZWdtZW50cygxKTsKICAgICAgU3RyaW5nIGZvbGRlclBhdGggPSBhYnNvbHV0ZVBhdGgubGFzdFNlZ21lbnQoKTsKICAgICAgdGhyb3cgbmV3IENvcmVFeGNlcHRpb24oIFN0YXR1c1V0aWxzLndhcm5pbmdTdGF0dXMoCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBOTFMuYmluZChFbnZpcm9ubWVudE1lc3NhZ2VzLk1TR19FUlJPUl9GT0xERVJfQ1JFQVRJT05fRElTQUJMRUQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBuZXcgT2JqZWN0W117IHBhcmVudFBhdGgudG9TdHJpbmcoKSwgZm9sZGVyUGF0aH0gKSApICk7CiAgICB9ICAKICB9CiAgCiAgLy8KICAvLyBDcmVhdGVzIGEgZm9sZGVyIHVuZGVyIGEgY29udGFpbmVyLgogIC8vIFRoZSBjb250YWluZXIgbXVzdCBhbHJlYWR5IGV4aXN0LgogIC8vCiBwcml2YXRlIHN0YXRpYyBJRm9sZGVyIG1ha2VGb2xkZXIgKAogICAgUmVzb3VyY2VDb250ZXh0ICByZXNvdXJjZUNvbnRleHQsCiAgICBJQ29udGFpbmVyICAgICAgIHBhcmVudCwKICAgIFN0cmluZyAgICAgICAgICAgZm9sZGVyTmFtZSwKICAgIElQcm9ncmVzc01vbml0b3IgcHJvZ3Jlc3NNb25pdG9yLAogICAgSVN0YXR1c0hhbmRsZXIgICAgc3RhdHVzSGFuZGxlciApCiAgCiAgdGhyb3dzIENvcmVFeGNlcHRpb24KICB7CiAgICBJUmVzb3VyY2UgY2hpbGQgID0gcGFyZW50LmZpbmRNZW1iZXIoZm9sZGVyTmFtZSk7CiAgICBDaG9pY2UgICAgcmVzdWx0ID0gbnVsbDsKICAgIAogICAgaWYoIGNoaWxkID09IG51bGwgKQogICAgewogICAgICBpZiAoIXJlc291cmNlQ29udGV4dC5pc0NyZWF0ZUZvbGRlcnNFbmFibGVkKCkpICAKICAgICAgewogICAgICAgIHJlc3VsdCA9IHN0YXR1c0hhbmRsZXIucmVwb3J0KAogICAgICAgICAgICAgICAgU3RhdHVzVXRpbHMud2FybmluZ1N0YXR1cygKICAgICAgICAgICAgICAgIAkJTkxTLmJpbmQoRW52aXJvbm1lbnRNZXNzYWdlcy5NU0dfRVJST1JfRk9MREVSX0NSRUFUSU9OX0RJU0FCTEVELAogICAgICAgIAkgICAgICAgICAgICAgICAgICAgICAgbmV3IE9iamVjdFtdeyBwYXJlbnQuZ2V0RnVsbFBhdGgoKS50b1N0cmluZygpLCBmb2xkZXJOYW1lfSApICksIAogICAgICAgICAgICAgICAgZ2V0VGhyZWVTdGF0ZUZpbGVPcHRpb25zKCkgKTsKICAgICAgICAKICAgICAgICBpZiggcmVzdWx0ID09IG51bGwgfHwgcmVzdWx0LmdldFNob3J0Y3V0KCkgPT0gJ0MnICkKICAgICAgICB7CiAgICAgICAgICByZXR1cm4gbnVsbDsKICAgICAgICB9CiAgICAgICAgZWxzZSBpZiggcmVzdWx0LmdldFNob3J0Y3V0KCkgPT0gJ0EnICkKICAgICAgICB7CiAgICAgICAgICByZXNvdXJjZUNvbnRleHQuc2V0Q3JlYXRlRm9sZGVyc0VuYWJsZWQodHJ1ZSk7CiAgICAgICAgICBQZXJzaXN0ZW50UmVzb3VyY2VDb250ZXh0LmdldEluc3RhbmNlKCkuc2V0Q3JlYXRlRm9sZGVyc0VuYWJsZWQodHJ1ZSk7CiAgICAgICAgfQogICAgICB9CiAgICAgIAogICAgICBJRm9sZGVyIGZvbGRlciA9IHBhcmVudC5nZXRGb2xkZXIobmV3IFBhdGgoZm9sZGVyTmFtZSkpOwogICAgICBmb2xkZXIuY3JlYXRlKHRydWUsdHJ1ZSxudWxsKTsKICAgICAgcmV0dXJuIGZvbGRlcjsKICAgIH0KICAgIGVsc2UgaWYoIGNoaWxkLmdldFR5cGUoKSA9PSBJUmVzb3VyY2UuRk9MREVSICkKICAgIHsKICAgICAgcmV0dXJuIChJRm9sZGVyKWNoaWxkOwogICAgfQogICAgZWxzZQogICAgewogICAgICB0aHJvdyBuZXcgQ29yZUV4Y2VwdGlvbigKICAgICAgICBuZXcgU3RhdHVzKCBJU3RhdHVzLkVSUk9SLCAKICAgICAgICAgICAgICAgICAgICAiUmVzb3VyY2VVdGlscyIsCiAgICAgICAgICAgICAgICAgICAgMCwgCiAgICAgICAgICAgICAgICAgICAgTkxTLmJpbmQoRW52aXJvbm1lbnRNZXNzYWdlcy5NU0dfRVJST1JfUkVTT1VSQ0VfTk9UX0ZPTERFUiwKCQkJCQkgICAgICAgICAgICAgICAgIG5ldyBPYmplY3RbXXsgcGFyZW50LmdldEZ1bGxQYXRoKCkuYXBwZW5kKGZvbGRlck5hbWUpLnRvU3RyaW5nKCkgfSksCgkJCW51bGwgKSApOwogICAgfQogIH0KCiAgLy8KICAvLyBDcmVhdGVzIGEgZmlsZSB1bmRlciBhIGNvbnRhaW5lci4KICAvLyBUaGUgY29udGFpbmVyIG11c3QgYWxyZWFkeSBleGlzdC4KICAvLwogcHJpdmF0ZSBzdGF0aWMgSUZpbGUgbWFrZUZpbGUgKAogICAgUmVzb3VyY2VDb250ZXh0ICByZXNvdXJjZUNvbnRleHQsCiAgICBJQ29udGFpbmVyICAgICAgIHBhcmVudCwKICAgIFN0cmluZyAgICAgICAgICAgZmlsZU5hbWUsCiAgICBJbnB1dFN0cmVhbSAgICAgIGlucHV0U3RyZWFtLAogICAgSVByb2dyZXNzTW9uaXRvciBwcm9ncmVzc01vbml0b3IsCiAgICBJU3RhdHVzSGFuZGxlciAgICBzdGF0dXNIYW5kbGVyICkKIAogICAgdGhyb3dzIENvcmVFeGNlcHRpb24KICB7CiAgICBJUmVzb3VyY2UgY2hpbGQgID0gcGFyZW50LmZpbmRNZW1iZXIoZmlsZU5hbWUpOwogICAgQ2hvaWNlICAgIHJlc3VsdCA9IG51bGw7CiAgICAKICAgIGlmKCBjaGlsZCAhPSBudWxsICkKICAgIHsKICAgICAgaWYoIGNoaWxkLmdldFR5cGUoKSA9PSBJUmVzb3VyY2UuRklMRSApCiAgICAgIHsKICAgICAgICBpZiggIXJlc291cmNlQ29udGV4dC5pc092ZXJ3cml0ZUZpbGVzRW5hYmxlZCgpICkgICAKICAgICAgICB7CiAgICAgICAgICByZXN1bHQgPSBzdGF0dXNIYW5kbGVyLnJlcG9ydCggCiAgICAgICAgICAgICAgICBTdGF0dXNVdGlscy53YXJuaW5nU3RhdHVzKCBOTFMuYmluZChFbnZpcm9ubWVudE1lc3NhZ2VzLk1TR19FUlJPUl9GSUxFX09WRVJXUklURV9ESVNBQkxFRCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5ldyBPYmplY3RbXSB7cGFyZW50LmdldEZ1bGxQYXRoKCkudG9TdHJpbmcoKSxmaWxlTmFtZX0pICksCQkJCQkgIAkJICAgIAogICAgICAgICAgICAgICAgZ2V0VGhyZWVTdGF0ZUZpbGVPcHRpb25zKCkgKTsKICAgICAgICAgIAogICAgICAgICAgaWYoIHJlc3VsdCA9PSBudWxsIHx8IHJlc3VsdC5nZXRTaG9ydGN1dCgpID09ICdDJyApCiAgICAgICAgICB7CiAgICAgICAgICAgIHJldHVybiBudWxsOwogICAgICAgICAgfQogICAgICAgICAgZWxzZSBpZiggcmVzdWx0LmdldFNob3J0Y3V0KCkgPT0gJ0EnICkKICAgICAgICAgIHsKICAgICAgICAgICAgcmVzb3VyY2VDb250ZXh0LnNldE92ZXJ3cml0ZUZpbGVzRW5hYmxlZCh0cnVlKTsKICAgICAgICAgICAgUGVyc2lzdGVudFJlc291cmNlQ29udGV4dC5nZXRJbnN0YW5jZSgpLnNldE92ZXJ3cml0ZUZpbGVzRW5hYmxlZCh0cnVlKTsKICAgICAgICAgIH0KICAgICAgICB9CQogICAgICAgIAogICAgICAgIC8vV2UgaGF2ZSBwZXJtaXNzaW9uIHRvIG92ZXJ3cml0ZSBzbyBjaGVjayBpZiBmaWxlIGlzIHJlYWQtb25seQogICAgICAgIGlmKCBjaGlsZC5nZXRSZXNvdXJjZUF0dHJpYnV0ZXMoKSA9PSBudWxsICkKICAgICAgICB7CiAgICAgICAgCS8vIHJlc291cmNlIGlzIGxpa2VseSBvdXQtb2Ytc3luYyB3aXRoIGZpbGVzeXN0ZW0KICAgICAgICAJdGhyb3cgbmV3IENvcmVFeGNlcHRpb24oIAogICAgICAgIAkgICAgICAgICAgbmV3IFN0YXR1cyggSVN0YXR1cy5FUlJPUiwKICAgICAgICAJICAgICAgICAgICAgICAgICAgICAgICJSZXNvdXJjZVV0aWxzIiwKICAgICAgICAJICAgICAgICAgICAgICAgICAgICAgIDAsIAogICAgICAgIAkgICAgICAgICAgICAgICAgICAgICAgY2hpbGQuZ2V0RnVsbFBhdGgoKS50b1N0cmluZygpLAogICAgICAgIAkJCQkJCSAgbnVsbCApICk7CiAgICAgICAgfQogICAgICAgIGVsc2UgaWYoIGNoaWxkLmdldFJlc291cmNlQXR0cmlidXRlcygpLmlzUmVhZE9ubHkoKSApCiAgICAgICAgewogICAgICAgICAgaWYoICFyZXNvdXJjZUNvbnRleHQuaXNDaGVja291dEZpbGVzRW5hYmxlZCgpICkgCiAgICAgICAgICB7ICAgICAgICAgICAgCiAgICAgICAgICAgIHJlc3VsdCA9IHN0YXR1c0hhbmRsZXIucmVwb3J0KCAKICAgICAgICAgICAgICAgICAgICAgICAgIFN0YXR1c1V0aWxzLmVycm9yU3RhdHVzKCBOTFMuYmluZChFbnZpcm9ubWVudE1lc3NhZ2VzLk1TR19FUlJPUl9GSUxFX0NIRUNLT1VUX0RJU0FCTEVELAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5ldyBPYmplY3RbXXsgcGFyZW50LmdldEZ1bGxQYXRoKCkudG9TdHJpbmcoKSxmaWxlTmFtZX0gKSApLCAKICAgICAgICAgICAgICAgICAgICAgICAgIGdldFRocmVlU3RhdGVGaWxlT3B0aW9ucygpICk7CiAgICAgICAgICAgIAoJCSAgICBpZiggcmVzdWx0ID09IG51bGwgfHwgcmVzdWx0LmdldFNob3J0Y3V0KCkgPT0gJ0MnICkKCQkgICAgewogICAgICAgICAgICAgIHJldHVybiBudWxsOwoJCSAgICB9CiAgICAgICAgICAgIGVsc2UgaWYoIHJlc3VsdC5nZXRTaG9ydGN1dCgpID09ICdBJyApCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICByZXNvdXJjZUNvbnRleHQuc2V0Q2hlY2tvdXRGaWxlc0VuYWJsZWQodHJ1ZSk7CiAgICAgICAgICAgICAgUGVyc2lzdGVudFJlc291cmNlQ29udGV4dC5nZXRJbnN0YW5jZSgpLnNldENoZWNrb3V0RmlsZXNFbmFibGVkKHRydWUpOwogICAgICAgICAgICB9CiAgICAgICAgICB9CgogICAgICAgICAgSUZpbGVbXSBmaWxlcyA9IG5ldyBJRmlsZVsxXTsKICAgICAgICAgIGZpbGVzWzBdID0gKElGaWxlKWNoaWxkOwogICAgICAgICAgCiAgICAgICAgICBJU3RhdHVzIHN0YXR1cyA9IGdldFdvcmtzcGFjZSgpLnZhbGlkYXRlRWRpdChmaWxlcyxudWxsKTsKICAgICAgICAgIAogICAgICAgICAgdHJ5CiAgICAgICAgICB7CiAgICAgICAgICAgIHN0YXR1c0hhbmRsZXIucmVwb3J0KCBzdGF0dXMgKTsKICAgICAgICAgIH0KICAgICAgICAgIGNhdGNoKCBTdGF0dXNFeGNlcHRpb24gZXhjICkKICAgICAgICAgIHsKICAgICAgICAgICAgcmV0dXJuIG51bGw7CiAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICAvL0NoYW5nZSB0aGUgY29udGVudHMgb2YgdGhlIGV4aXN0aW5nIGZpbGUuCiAgICAgICAgSUZpbGUgZmlsZSA9IHBhcmVudC5nZXRGaWxlKCBuZXcgUGF0aChmaWxlTmFtZSkgKTsKICAgICAgICBmaWxlLnNldENvbnRlbnRzKCBpbnB1dFN0cmVhbSwgdHJ1ZSwgdHJ1ZSwgbnVsbCApOwogICAgICAgIAogICAgICAgIHJldHVybiBmaWxlOwogICAgICAKICAgICAgfQogICAgICBlbHNlCiAgICAgIHsKICAgICAgICB0aHJvdyBuZXcgQ29yZUV4Y2VwdGlvbiggCiAgICAgICAgICBuZXcgU3RhdHVzKCBJU3RhdHVzLkVSUk9SLAogICAgICAgICAgICAgICAgICAgICAgIlJlc291cmNlVXRpbHMiLAogICAgICAgICAgICAgICAgICAgICAgMCwgCiAgICAgICAgICAgICAgICAgICAgICBOTFMuYmluZChFbnZpcm9ubWVudE1lc3NhZ2VzLk1TR19FUlJPUl9SRVNPVVJDRV9OT1RfRklMRSwKCQkJCSAgICAgICAgICAgICAgICAgICAgICAgbmV3IE9iamVjdFtdIHtwYXJlbnQuZ2V0RnVsbFBhdGgoKS5hcHBlbmQoZmlsZU5hbWUpfSksCgkJCQkJICBudWxsICkgKTsKICAgICAgfQogICAgfQogICAgZWxzZQogICAgewogICAgICAvL0NyZWF0ZSBhIG5ldyBmaWxlLgogICAgICBJRmlsZSBmaWxlID0gcGFyZW50LmdldEZpbGUoIG5ldyBQYXRoKGZpbGVOYW1lKSApOwogICAgICBmaWxlLmNyZWF0ZSggaW5wdXRTdHJlYW0sIHRydWUsIG51bGwpOwogICAgICAKICAgICAgcmV0dXJuIGZpbGU7CiAgICB9CiAgfQoKIAogLyoqCiAgICogQ3JlYXRlcyBhIGZpbGUgb2YgdGhlIGdpdmVuIDxjb2RlPmFic29sdXRlUGF0aDwvY29kZT4KICAgKiBhbmQgcmV0dXJucyBpdHMgaGFuZGxlIGFzIGFuIDxjb2RlPklGaWxlPC9jb2RlPi4KICAgKiBJZiB0aGUgZmlsZSBjYW5ub3QgYmUgY3JlYXRlZCwgYQogICAqIDxjb2RlPkNvcmVFeGNlcHRpb248L2NvZGU+IGNvbnRhaW5pbmcgYW4KICAgKiA8Y29kZT5JU3RhdHVzPC9jb2RlPiBvYmplY3QgaXMgdGhyb3duLgogICAqIEBwYXJhbSBhYnNvbHV0ZVBhdGggVGhlIGFic29sdXRlIHBhdGggb2YgdGhlIGZpbGUgdG8gY3JlYXRlLgogICAqIFRoZSBwcm9qZWN0IGF0IHRoZSBiZWdpbm5pbmcgb2YgdGhlIHBhdGggbXVzdCBhbHJlYWR5IGV4aXN0LAogICAqIHRoYXQgaXMsIHRoaXMgbWV0aG9kIGNhbm5vdCBiZSB1c2VkIHRvIGNyZWF0ZSBwcm9qZWN0cy4KICAgKiBAcGFyYW0gcHJvZ3Jlc3NNb25pdG9yIFRoZSBwcm9ncmVzcyBtb25pdG9yIGZvciB0aGUgb3BlcmF0aW9uLCBvciBudWxsLgogICAqIEByZXR1cm4gVGhlIHtAbGluayBvcmcuZWNsaXBzZS5jb3JlLnJlc291cmNlcy5JRmlsZSBJRmlsZX0KICAgKiBoYW5kbGUgb2YgdGhlIGZpbGUuCiAgICogQHRocm93cyBDb3JlRXhjZXB0aW9uIEFuIGV4Y2VwdGlvbiBjb250YWluaW5nIGFuCiAgICoge0BsaW5rIG9yZy5lY2xpcHNlLmNvcmUucnVudGltZS5JU3RhdHVzIElTdGF0dXN9CiAgICogd2l0aCBhIHNldmVyaXR5IG9mIDxjb2RlPklTdGF0dXMuRVJST1I8L2NvZGU+IGFuZCBhCiAgICogbG9jYWxlLXNwZWNpZmljIGRlc2NyaXB0aW9uIG9mIHRoZSBjYXVzZS4KICAgKi8KICAgcHVibGljIHN0YXRpYyBJRmlsZSBjcmVhdGVGaWxlQXRMb2NhdGlvbiAoCiAgICAgUmVzb3VyY2VDb250ZXh0IHJlc291cmNlQ29udGV4dCwKICAgICBJUGF0aCAgICAgICAgICAgYWJzb2x1dGVQYXRoLAogICAgIElucHV0U3RyZWFtICAgICBpbnB1dFN0cmVhbSwKICAgICBJUHJvZ3Jlc3NNb25pdG9yIHByb2dyZXNzTW9uaXRvciwKICAgICBJU3RhdHVzSGFuZGxlciAgIHN0YXR1c0hhbmRsZXIgKQoKICAgICB0aHJvd3MgQ29yZUV4Y2VwdGlvbiAKICAgeyAgICAKICAgICBpZiAoIWFic29sdXRlUGF0aC5pc0Fic29sdXRlKCkpCiAgICAgewogICAgICAgdGhyb3cgbmV3IENvcmVFeGNlcHRpb24obmV3IFN0YXR1cyhJU3RhdHVzLkVSUk9SLCAiUmVzb3VyY2VVdGlscyIsMCxOTFMuYmluZChFbnZpcm9ubWVudE1lc3NhZ2VzLk1TR19FUlJPUl9QQVRIX05PVF9BQlNPTFVURSxuZXcgT2JqZWN0W10ge2Fic29sdXRlUGF0aC50b1N0cmluZygpfSksbnVsbCkpOwogICAgIH0KICAgICBpZiAoYWJzb2x1dGVQYXRoLnNlZ21lbnRDb3VudCgpIDwgMSkKICAgICB7CiAgICAgICB0aHJvdyBuZXcgQ29yZUV4Y2VwdGlvbihuZXcgU3RhdHVzKElTdGF0dXMuRVJST1IsIlJlc291cmNlVXRpbHMiLDAsTkxTLmJpbmQoRW52aXJvbm1lbnRNZXNzYWdlcy5NU0dfRVJST1JfUEFUSF9FTVBUWSxuZXcgT2JqZWN0W10ge2Fic29sdXRlUGF0aC50b1N0cmluZygpfSksbnVsbCkpOwogICAgIH0KICAgICBpZiAoYWJzb2x1dGVQYXRoLnNlZ21lbnRDb3VudCgpIDwgMikKICAgICB7CiAgICAgICB0aHJvdyBuZXcgQ29yZUV4Y2VwdGlvbihuZXcgU3RhdHVzKElTdGF0dXMuRVJST1IsIlJlc291cmNlVXRpbHMiLDAsTkxTLmJpbmQoRW52aXJvbm1lbnRNZXNzYWdlcy5NU0dfRVJST1JfUEFUSF9OT1RfRk9MREVSLG5ldyBPYmplY3RbXSB7YWJzb2x1dGVQYXRoLnRvU3RyaW5nKCl9KSxudWxsKSk7CiAgICAgfQogICAgIElDb250YWluZXIgcGFyZW50ICAgPSBtYWtlRm9sZGVyUGF0aEF0TG9jYXRpb24ocmVzb3VyY2VDb250ZXh0LCBhYnNvbHV0ZVBhdGgucmVtb3ZlTGFzdFNlZ21lbnRzKDEpLCBwcm9ncmVzc01vbml0b3IsIHN0YXR1c0hhbmRsZXIpOwogICAgIFN0cmluZyAgICAgZmlsZU5hbWUgPSBhYnNvbHV0ZVBhdGgubGFzdFNlZ21lbnQoKTsKICAgICAKICAgICBjaGVja1BhcmVudCggcGFyZW50LCBhYnNvbHV0ZVBhdGggKTsKICAgICAKICAgICByZXR1cm4gbWFrZUZpbGUocmVzb3VyY2VDb250ZXh0LCBwYXJlbnQsIGZpbGVOYW1lLCBpbnB1dFN0cmVhbSwgcHJvZ3Jlc3NNb25pdG9yLCBzdGF0dXNIYW5kbGVyKTsKICAgfQoKLyoqCiAgKiBDcmVhdGVzIGEgcGF0aCBvZiBmb2xkZXJzIHVzaW5nIGFic29sdXRlIGZpbGVuYW1lcy4KICAqIERvIG5vdCBjYWxsIHdpdGggYW4gYWJzb2x1dGVQYXRoIG9mIGxlc3MgdGhhbiBvbmUgc2VnbWVudC4KICAqIEBwYXJhbSByZXNvdXJjZUNvbnRleHQgdGhlIHJlc291cmNlIGNvbnRleHQgZm9yIG1ha2luZyBmb2xkZXJzLgogICogQHBhcmFtIHJlc291cmNlIHRoZSByZXNvdXJjZSB0aGF0IHdpbGwgYmUgY3JlYXRlZC4KICAqIEBwYXJhbSBwcm9ncmVzc01vbml0b3IgdGhlIHByb2dyZXNzIG1vbml0b3IgdG8gYmUgdXNlZC4KICAqIEBwYXJhbSBzdGF0dXNIYW5kbGVyIHRoZSBzdGF0dXMgaGFuZGxlci4KICAqIEByZXR1cm4gcmV0dXJucyB0aGUgSUNvbnRhaW5lciBvZiB0aGUgY3JlYXRlZCBmb2xkZXIuCiAgKi8KIHB1YmxpYyBzdGF0aWMgSUNvbnRhaW5lciBtYWtlRm9sZGVyUGF0aEF0TG9jYXRpb24gKAogICBSZXNvdXJjZUNvbnRleHQgIHJlc291cmNlQ29udGV4dCwKICAgSUNvbnRhaW5lciAgICAgICByZXNvdXJjZSwKICAgSVByb2dyZXNzTW9uaXRvciBwcm9ncmVzc01vbml0b3IsCiAgIElTdGF0dXNIYW5kbGVyICAgc3RhdHVzSGFuZGxlciApCiAKICAgdGhyb3dzIENvcmVFeGNlcHRpb24KICAgewoJIGlmIChyZXNvdXJjZS5leGlzdHMoKSkKCSB7CgkJIGlmIChyZXNvdXJjZSBpbnN0YW5jZW9mIElDb250YWluZXIpCgkJIHsKCQkJIHJldHVybiAoSUNvbnRhaW5lcikgcmVzb3VyY2U7CgkJIH0KCQkgZWxzZQoJCSB7CgkJCSB0aHJvdyBuZXcgQ29yZUV4Y2VwdGlvbigKCQkJCQkgbmV3IFN0YXR1cyggSVN0YXR1cy5FUlJPUiwgCgkJCQkJCQkgIlJlc291cmNlVXRpbHMiLAoJCQkJCQkJIDAsIAoJCQkJCQkJIE5MUy5iaW5kKEVudmlyb25tZW50TWVzc2FnZXMuTVNHX0VSUk9SX1JFU09VUkNFX05PVF9GT0xERVIsCgkJCQkJCQkJCSBuZXcgT2JqZWN0W117IHJlc291cmNlLmdldEZ1bGxQYXRoKCkudG9TdHJpbmcoKSB9KSwKCQkJCQkJCQkJIG51bGwgKSApOwoJCSB9CgkgfQoJIGVsc2UKCSB7CgkJIElDb250YWluZXIgcGFyZW50ID0gbWFrZUZvbGRlclBhdGhBdExvY2F0aW9uKHJlc291cmNlQ29udGV4dCwgcmVzb3VyY2UuZ2V0UGFyZW50KCksIHByb2dyZXNzTW9uaXRvciwgc3RhdHVzSGFuZGxlciApOwoJCSBTdHJpbmcgZm9sZGVyTmFtZSA9IHJlc291cmNlLmdldE5hbWUoKTsKCQkgCgkJIHJldHVybiBtYWtlRm9sZGVyKHJlc291cmNlQ29udGV4dCwgcGFyZW50LCBmb2xkZXJOYW1lLCBwcm9ncmVzc01vbml0b3IgLCBzdGF0dXNIYW5kbGVyICk7CgkgfQogfQogCiAvKioKICAqIENyZWF0ZXMgYSBwYXRoIG9mIGZvbGRlcnMuCiAgKiBEbyBub3QgY2FsbCB3aXRoIGFuIGFic29sdXRlUGF0aCBvZiBsZXNzIHRoYW4gb25lIHNlZ21lbnQuCiAgKiBAcGFyYW0gcmVzb3VyY2VDb250ZXh0IHRoZSByZXNvdXJjZSBjb250ZXh0IGZvciBtYWtpbmcgZm9sZGVycy4KICAqIEBwYXJhbSBhYnNvbHV0ZVBhdGggdGhlIHBhdGggb2YgZm9sZGVycyB0aGF0IHdpbGwgYmUgY3JlYXRlZC4KICAqIEBwYXJhbSBwcm9ncmVzc01vbml0b3IgdGhlIHByb2dyZXNzIG1vbml0b3IgdG8gYmUgdXNlZC4KICAqIEBwYXJhbSBzdGF0dXNIYW5kbGVyIHRoZSBzdGF0dXMgaGFuZGxlci4KICAqIEByZXR1cm4gcmV0dXJucyB0aGUgSUNvbnRhaW5lciBvZiB0aGUgY3JlYXRlZCBmb2xkZXIuCiAgKi8KIHB1YmxpYyBzdGF0aWMgSUNvbnRhaW5lciBtYWtlRm9sZGVyUGF0aEF0TG9jYXRpb24gKAogICBSZXNvdXJjZUNvbnRleHQgIHJlc291cmNlQ29udGV4dCwKICAgSVBhdGggICAgICAgICAgICBhYnNvbHV0ZVBhdGgsCiAgIElQcm9ncmVzc01vbml0b3IgcHJvZ3Jlc3NNb25pdG9yLAogICBJU3RhdHVzSGFuZGxlciAgICBzdGF0dXNIYW5kbGVyICkKIAogICB0aHJvd3MgQ29yZUV4Y2VwdGlvbgogewogCXJldHVybiBtYWtlRm9sZGVyUGF0aEF0TG9jYXRpb24ocmVzb3VyY2VDb250ZXh0LAogCQlnZXRXb3Jrc3BhY2VSb290KCkuZ2V0Q29udGFpbmVyRm9yTG9jYXRpb24oYWJzb2x1dGVQYXRoKSwKIAkJcHJvZ3Jlc3NNb25pdG9yLCBzdGF0dXNIYW5kbGVyKTsKIH0KIAogCgp9Cg==