LyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogQ29weXJpZ2h0IChjKSAyMDA4IElPTkEgVGVjaG5vbG9naWVzIFBMQwogKiBBbGwgcmlnaHRzIHJlc2VydmVkLiBUaGlzIHByb2dyYW0gYW5kIHRoZSBhY2NvbXBhbnlpbmcgbWF0ZXJpYWxzCiAqIGFyZSBtYWRlIGF2YWlsYWJsZSB1bmRlciB0aGUgdGVybXMgb2YgdGhlIEVjbGlwc2UgUHVibGljIExpY2Vuc2UgdjEuMAogKiB3aGljaCBhY2NvbXBhbmllcyB0aGlzIGRpc3RyaWJ1dGlvbiwgYW5kIGlzIGF2YWlsYWJsZSBhdAogKiBodHRwOi8vd3d3LmVjbGlwc2Uub3JnL2xlZ2FsL2VwbC12MTAuaHRtbAogKgogKiBDb250cmlidXRvcnM6CiAqIElPTkEgVGVjaG5vbG9naWVzIFBMQyAtIGluaXRpYWwgQVBJIGFuZCBpbXBsZW1lbnRhdGlvbgogKiBCdWcgIzI3NDI5MyAtIHN1ZGhhbkBwcm9ncmVzcy5jb20KICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCnBhY2thZ2Ugb3JnLmVjbGlwc2UuanN0LndzLmpheHdzLmNvcmUudXRpbHM7CgppbXBvcnQgamF2YS5pby5GaWxlOwppbXBvcnQgamF2YS5pby5GaWxlT3V0cHV0U3RyZWFtOwppbXBvcnQgamF2YS5pby5JT0V4Y2VwdGlvbjsKaW1wb3J0IGphdmEuaW8uSW5wdXRTdHJlYW07CmltcG9ydCBqYXZhLmlvLk91dHB1dFN0cmVhbTsKaW1wb3J0IGphdmEubmV0Lk1hbGZvcm1lZFVSTEV4Y2VwdGlvbjsKaW1wb3J0IGphdmEubmV0LlVSSTsKaW1wb3J0IGphdmEubmV0LlVSSVN5bnRheEV4Y2VwdGlvbjsKaW1wb3J0IGphdmEubmV0LlVSTDsKaW1wb3J0IGphdmEubmV0LlVSTENvbm5lY3Rpb247CmltcG9ydCBqYXZhLnV0aWwuQXJyYXlMaXN0OwppbXBvcnQgamF2YS51dGlsLkFycmF5czsKaW1wb3J0IGphdmEudXRpbC5Db2xsZWN0aW9uczsKaW1wb3J0IGphdmEudXRpbC5JdGVyYXRvcjsKaW1wb3J0IGphdmEudXRpbC5MaXN0OwppbXBvcnQgamF2YS51dGlsLk1hcDsKaW1wb3J0IGphdmEudXRpbC5TZXQ7CgppbXBvcnQgamF2YXgud3NkbC5EZWZpbml0aW9uOwppbXBvcnQgamF2YXgud3NkbC5Qb3J0OwppbXBvcnQgamF2YXgud3NkbC5TZXJ2aWNlOwppbXBvcnQgamF2YXgud3NkbC5XU0RMRXhjZXB0aW9uOwppbXBvcnQgamF2YXgud3NkbC5leHRlbnNpb25zLkV4dGVuc2liaWxpdHlFbGVtZW50OwppbXBvcnQgamF2YXgud3NkbC5leHRlbnNpb25zLnNvYXAuU09BUEFkZHJlc3M7CmltcG9ydCBqYXZheC53c2RsLmV4dGVuc2lvbnMuc29hcDEyLlNPQVAxMkFkZHJlc3M7CmltcG9ydCBqYXZheC53c2RsLmZhY3RvcnkuV1NETEZhY3Rvcnk7CmltcG9ydCBqYXZheC53c2RsLnhtbC5XU0RMUmVhZGVyOwppbXBvcnQgamF2YXgud3NkbC54bWwuV1NETFdyaXRlcjsKCmltcG9ydCBvcmcuZWNsaXBzZS5jb3JlLmZpbGVzeXN0ZW0uVVJJVXRpbDsKaW1wb3J0IG9yZy5lY2xpcHNlLmNvcmUucmVzb3VyY2VzLklGaWxlOwppbXBvcnQgb3JnLmVjbGlwc2UuY29yZS5yZXNvdXJjZXMuSUZvbGRlcjsKaW1wb3J0IG9yZy5lY2xpcHNlLmNvcmUucmVzb3VyY2VzLklQcm9qZWN0OwppbXBvcnQgb3JnLmVjbGlwc2UuY29yZS5yZXNvdXJjZXMuSVJlc291cmNlOwppbXBvcnQgb3JnLmVjbGlwc2UuY29yZS5yZXNvdXJjZXMuUmVzb3VyY2VzUGx1Z2luOwppbXBvcnQgb3JnLmVjbGlwc2UuY29yZS5ydW50aW1lLkNvcmVFeGNlcHRpb247CmltcG9ydCBvcmcuZWNsaXBzZS5jb3JlLnJ1bnRpbWUuSVBhdGg7CmltcG9ydCBvcmcuZWNsaXBzZS5jb3JlLnJ1bnRpbWUuTnVsbFByb2dyZXNzTW9uaXRvcjsKaW1wb3J0IG9yZy5lY2xpcHNlLmNvcmUucnVudGltZS5QYXRoOwppbXBvcnQgb3JnLmVjbGlwc2UuanN0LndzLmludGVybmFsLmpheHdzLmNvcmUuSkFYV1NDb3JlUGx1Z2luOwppbXBvcnQgb3JnLmVjbGlwc2Uud3N0LmNvbW1vbi5jb21wb25lbnRjb3JlLkNvbXBvbmVudENvcmU7CmltcG9ydCBvcmcuZWNsaXBzZS53c3QuY29tbW9uLmNvbXBvbmVudGNvcmUucmVzb3VyY2VzLklWaXJ0dWFsQ29tcG9uZW50OwppbXBvcnQgb3JnLnhtbC5zYXguSW5wdXRTb3VyY2U7CgovKioKICogV1NETCBVdGlsaXR5IGNsYXNzLgogKiA8cD4KICogPHN0cm9uZz5Qcm92aXNpb25hbCBBUEk6PC9zdHJvbmc+IFRoaXMgY2xhc3MvaW50ZXJmYWNlIGlzIHBhcnQgb2YgYW4gaW50ZXJpbSBBUEkgdGhhdCBpcyBzdGlsbCB1bmRlcgogKiBkZXZlbG9wbWVudCBhbmQgZXhwZWN0ZWQgdG8gY2hhbmdlIHNpZ25pZmljYW50bHkgYmVmb3JlIHJlYWNoaW5nIHN0YWJpbGl0eS4gSXQgaXMgYmVpbmcgbWFkZSBhdmFpbGFibGUgYXQKICogdGhpcyBlYXJseSBzdGFnZSB0byBzb2xpY2l0IGZlZWRiYWNrIGZyb20gcGlvbmVlcmluZyBhZG9wdGVycyBvbiB0aGUgdW5kZXJzdGFuZGluZyB0aGF0IGFueSBjb2RlIHRoYXQgdXNlcwogKiB0aGlzIEFQSSB3aWxsIGFsbW9zdCBjZXJ0YWlubHkgYmUgYnJva2VuIChyZXBlYXRlZGx5KSBhcyB0aGUgQVBJIGV2b2x2ZXMuCiAqIDwvcD4KICovCnB1YmxpYyBmaW5hbCBjbGFzcyBXU0RMVXRpbHMgewogICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgU3RyaW5nIFdTRExfRklMRV9OQU1FX1BBVFRFUk4gPSAiW2EtekEtWjAtOV9cXC1dKy53c2RsIjsvLyROT04tTkxTLTEkCiAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBTdHJpbmcgV1NETF9RVUVSWSA9ICI/d3NkbCI7IC8vJE5PTi1OTFMtMSQKCiAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBJUGF0aCBXU0RMX0ZPTERFUl9QQVRIID0gbmV3IFBhdGgoIndzZGwvIik7IC8vJE5PTi1OTFMtMSQKICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGludCBUSU1FT1VUID0gMzAwMDA7CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgV1NETF9GSUxFX0VYVEVOU0lPTiA9ICIud3NkbCI7IC8vJE5PTi1OTFMtMSQKCiAgICBwcml2YXRlIFdTRExVdGlscygpIHsKICAgIH0KCiAgICAvKioKICAgICAqIFJldHVybnMgYSA8Y29kZT5qYXZheC53c2RsLkRlZmluaXRpb248L2NvZGU+IGJ5IHJlYWRpbmcgdGhlIFdTREwgZG9jdW1lbnQgYXQgdGhlIGdpdmVuIFVSTCBvciBudWxsIGlmIG5vbmUgY2FuIGJlIGZvdW5kCiAgICAgKiBvciBpZiB0aGUgY29ubmVjdGlvbiB0aW1lcyBvdXQuCiAgICAgKiBAcGFyYW0gd3NkbFVSTCB0aGUgdXJsIG9mIHRoZSB3c2RsIGRvY3VtZW50IHRvIHJlYWQuCiAgICAgKiBAcmV0dXJuIHRoZSBkZWZpbml0aW9uIGRlc2NyaWJlZCBpbiB0aGUgd3NkbCBkb2N1bWVudCBwb2ludGVkIHRvIGJ5IHRoZSBnaXZlbiBVUkwuCiAgICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uIGlmIGFuIEkvTyBleGNlcHRpb24gb2NjdXJzLgogICAgICovCiAgICBwdWJsaWMgc3RhdGljIERlZmluaXRpb24gcmVhZFdTREwoVVJMIHdzZGxVUkwpIHRocm93cyBJT0V4Y2VwdGlvbiB7CiAgICAgICAgVVJMQ29ubmVjdGlvbiB1cmxDb25uZWN0aW9uID0gd3NkbFVSTC5vcGVuQ29ubmVjdGlvbigpOwogICAgICAgIHVybENvbm5lY3Rpb24uc2V0Q29ubmVjdFRpbWVvdXQoVElNRU9VVCk7CiAgICAgICAgdXJsQ29ubmVjdGlvbi5zZXRSZWFkVGltZW91dChUSU1FT1VUKTsKICAgICAgICBJbnB1dFN0cmVhbSBpbnB1dFN0cmVhbSA9IG51bGw7CiAgICAgICAgdHJ5IHsKICAgICAgICAgICAgaW5wdXRTdHJlYW0gPSB1cmxDb25uZWN0aW9uLmdldElucHV0U3RyZWFtKCk7CiAgICAgICAgICAgIElucHV0U291cmNlIGlucHV0U291cmNlID0gbmV3IElucHV0U291cmNlKGlucHV0U3RyZWFtKTsKICAgICAgICAgICAgV1NETEZhY3Rvcnkgd3NkbEZhY3RvcnkgPSBXU0RMRmFjdG9yeS5uZXdJbnN0YW5jZSgpOwogICAgICAgICAgICBXU0RMUmVhZGVyIHdzZGxSZWFkZXIgPSB3c2RsRmFjdG9yeS5uZXdXU0RMUmVhZGVyKCk7CiAgICAgICAgICAgIERlZmluaXRpb24gZGVmaW5pdGlvbiA9IHdzZGxSZWFkZXIucmVhZFdTREwod3NkbFVSTC5nZXRQYXRoKCksIGlucHV0U291cmNlKTsKICAgICAgICAgICAgcmV0dXJuIGRlZmluaXRpb247CiAgICAgICAgfSBjYXRjaCAoV1NETEV4Y2VwdGlvbiB3c2RsZSkgewogICAgICAgICAgICBKQVhXU0NvcmVQbHVnaW4ubG9nKHdzZGxlKTsKICAgICAgICB9IGZpbmFsbHkgewogICAgICAgICAgICBpZiAoaW5wdXRTdHJlYW0gIT0gbnVsbCkgewogICAgICAgICAgICAgICAgaW5wdXRTdHJlYW0uY2xvc2UoKTsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgICAgICByZXR1cm4gbnVsbDsKICAgIH0KCiAgICAvKioKICAgICAqIFdyaXRlcyB0aGUgZ2l2ZW4gPGNvZGU+amF2YXgud3NkbC5EZWZpbml0aW9uPC9jb2RlPiB0byB0aGUgd3NkbCBkb2N1bWVudCBhdCB0aGUgZ2l2ZW4gVVJMLgogICAgICogQHBhcmFtIHdzZGxVUkwgdGhlIHVybCBvZiB0aGUgd3NkbCBkb2N1bWVudCB0byB3cml0ZSB0by4KICAgICAqIEBwYXJhbSBkZWZpbml0aW9uIHRoZSBXU0RMIGRlZmluaXRpb24gdG8gYmUgd3JpdHRlbi4KICAgICAqIEB0aHJvd3MgSU9FeGNlcHRpb24gIGlmIGFuIEkvTyBleGNlcHRpb24gb2NjdXJzLgogICAgICogQHRocm93cyBDb3JlRXhjZXB0aW9uIGlmIGFuIGV4Y2VwdGlvbiBvY2N1cnMgcmVmcmVzaGluZyB0aGUgZmlsZSBpbiB0aGUgd29ya3NwYWNlIGlmIGl0IGV4aXN0cy4KICAgICAqLwogICAgcHVibGljIHN0YXRpYyB2b2lkIHdyaXRlV1NETChVUkwgd3NkbFVSTCwgRGVmaW5pdGlvbiBkZWZpbml0aW9uKSB0aHJvd3MgSU9FeGNlcHRpb24sIENvcmVFeGNlcHRpb24gewogICAgICAgIFVSSSB3c2RsVVJJID0gbnVsbDsKICAgICAgICBPdXRwdXRTdHJlYW0gd3NkbE91dHB1dFN0cmVhbSA9IG51bGw7CiAgICAgICAgdHJ5IHsKICAgICAgICAgICAgd3NkbFVSSSA9IHdzZGxVUkwudG9VUkkoKTsKICAgICAgICAgICAgRmlsZSB3c2RsRmlsZSA9IG5ldyBGaWxlKHdzZGxVUkkpOwogICAgICAgICAgICB3c2RsT3V0cHV0U3RyZWFtID0gbmV3IEZpbGVPdXRwdXRTdHJlYW0od3NkbEZpbGUpOwogICAgICAgICAgICBXU0RMRmFjdG9yeSB3c2RsRmFjdG9yeSA9IFdTRExGYWN0b3J5Lm5ld0luc3RhbmNlKCk7CiAgICAgICAgICAgIFdTRExXcml0ZXIgd3NkbFdyaXRlciA9IHdzZGxGYWN0b3J5Lm5ld1dTRExXcml0ZXIoKTsKICAgICAgICAgICAgd3NkbFdyaXRlci53cml0ZVdTREwoZGVmaW5pdGlvbiwgd3NkbE91dHB1dFN0cmVhbSk7CiAgICAgICAgfSBjYXRjaCAoV1NETEV4Y2VwdGlvbiB3c2RsZSkgewogICAgICAgICAgICBKQVhXU0NvcmVQbHVnaW4ubG9nKHdzZGxlKTsKICAgICAgICB9IGNhdGNoIChVUklTeW50YXhFeGNlcHRpb24gdXJpc2UpIHsKICAgICAgICAgICAgSkFYV1NDb3JlUGx1Z2luLmxvZyh1cmlzZSk7CiAgICAgICAgfSBmaW5hbGx5IHsKICAgICAgICAgICAgaWYgKHdzZGxPdXRwdXRTdHJlYW0gIT0gbnVsbCkgewogICAgICAgICAgICAgICAgd3NkbE91dHB1dFN0cmVhbS5jbG9zZSgpOwogICAgICAgICAgICAgICAgSUZpbGUgZmlsZSA9IFJlc291cmNlc1BsdWdpbi5nZXRXb3Jrc3BhY2UoKS5nZXRSb290KCkKICAgICAgICAgICAgICAgIC5nZXRGaWxlRm9yTG9jYXRpb24oVVJJVXRpbC50b1BhdGgod3NkbFVSSSkpOwogICAgICAgICAgICAgICAgaWYgKGZpbGUgIT0gbnVsbCAmJiBmaWxlLmV4aXN0cygpKSB7CiAgICAgICAgICAgICAgICAgICAgZmlsZS5yZWZyZXNoTG9jYWwoSVJlc291cmNlLkRFUFRIX09ORSwgbmV3IE51bGxQcm9ncmVzc01vbml0b3IoKSk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICB9CgogICAgLyoqCiAgICAgKiBSZXR1cm5zIDxjb2RlPnRydWU8L2NvZGU+IGlmIHRoZSBnaXZlbiBmaWxlIG5hbWUgY29udGFpbnMgQWxwaGFudW1lcmljIGNoYXJhY3RlcnMsIHVuZGVyc2NvcmUgJ18nLAogICAgICogZGFzaGVzICctJyBhbmQgZW5kcyB3aXRoIHRoZSAnLndzZGwnIGV4dGVuc2lvbi4gT3RoZXJ3aXNlIHJldHVybnMgPGNvZGU+ZmFsc2U8L2NvZGU+LgogICAgICogQHBhcmFtIHdzZGxGaWxlTmFtZSB0aGUgd3NkbCBmaWxlIG5hbWUKICAgICAqIEByZXR1cm4gPGNvZGU+dHJ1ZTwvY29kZT4gaWYgdmFsaWQsIGNvZGU+ZmFsc2U8L2NvZGU+IG90aGVyd2lzZS4KICAgICAqLwogICAgcHVibGljIHN0YXRpYyBib29sZWFuIGlzVmFsaWRXU0RMRmlsZU5hbWUoU3RyaW5nIHdzZGxGaWxlTmFtZSkgewogICAgICAgIHJldHVybiB3c2RsRmlsZU5hbWUgIT0gbnVsbCAmJiB3c2RsRmlsZU5hbWUubWF0Y2hlcyhXU0RMX0ZJTEVfTkFNRV9QQVRURVJOKTsKICAgIH0KCiAgICBwcml2YXRlIHN0YXRpYyBJUHJvamVjdCBnZXRQcm9qZWN0KFN0cmluZyBwcm9qZWN0TmFtZSkgewogICAgICAgIHJldHVybiBSZXNvdXJjZXNQbHVnaW4uZ2V0V29ya3NwYWNlKCkuZ2V0Um9vdCgpLmdldFByb2plY3QocHJvamVjdE5hbWUpOwogICAgfQoKICAgIC8qKgogICAgICogUmV0dXJucyB0aGUgV2ViIENvbnRlbnQgZm9sZGVyIG9mIHRoZSBnaXZlbiBwcm9qZWN0LiBUaGUgcmV0dXJuZWQgcmVzb3VyY2UgbWF5IG5vdCBleGlzdC4KICAgICAqIEBwYXJhbSBwcm9qZWN0IHRoZSBuYW1lIG9mIHRoZSB3ZWIgcHJvamVjdAogICAgICogQHJldHVybiB0aGUgd2ViIGNvbnRlbnQgZm9sZGVyCiAgICAgKi8KICAgIHB1YmxpYyBzdGF0aWMgSUZvbGRlciBnZXRXZWJDb250ZW50Rm9sZGVyKElQcm9qZWN0IHByb2plY3QpIHsKICAgICAgICByZXR1cm4gUmVzb3VyY2VzUGx1Z2luLmdldFdvcmtzcGFjZSgpLmdldFJvb3QoKS5nZXRGb2xkZXIoCiAgICAgICAgICAgICAgICBXU0RMVXRpbHMuZ2V0V2ViQ29udGVudFBhdGgocHJvamVjdCkpOwogICAgfQoKICAgIC8qKgogICAgICogUmV0dXJucyB0aGUgV1NETCBmb2xkZXIgb2YgdGhlIHByb2plY3Qgd2l0aCB0aGUgZ2l2ZW4gbmFtZS4gVGhlIFdTREwgZm9sZGVyIHBhdGggaXMgdGhlIHByb2plY3RzIHdlYiBjb250ZW50IGZvbGRlcgogICAgICogcGF0aCBhcHBlbmRlZCB3aXRoIHRoZSAnV1NETCcgZGlyZWN0b3J5LiBUaGUgcmV0dXJuZWQgcmVzb3VyY2UgbWF5IG5vdCBleGlzdC4KICAgICAqIEBwYXJhbSBwcm9qZWN0TmFtZSB0aGUgbmFtZSBvZiB0aGUgd2ViIHByb2plY3QKICAgICAqIEByZXR1cm4gdGhlIHdzZGwgZm9sZGVyCiAgICAgKi8KICAgIHB1YmxpYyBzdGF0aWMgSUZvbGRlciBnZXRXU0RMRm9sZGVyKFN0cmluZyBwcm9qZWN0TmFtZSkgewogICAgICAgIHJldHVybiBXU0RMVXRpbHMuZ2V0V1NETEZvbGRlcihXU0RMVXRpbHMuZ2V0UHJvamVjdChwcm9qZWN0TmFtZSkpOwogICAgfQoKICAgIC8qKgogICAgICogUmV0dXJucyB0aGUgV1NETCBmb2xkZXIgb2YgdGhlIGdpdmVuIHByb2plY3QuIFRoZSBXU0RMIGZvbGRlciBwYXRoIGlzIHRoZSBwcm9qZWN0cyB3ZWIgY29udGVudCBmb2xkZXIKICAgICAqIHBhdGggYXBwZW5kZWQgd2l0aCB0aGUgJ1dTREwnIGRpcmVjdG9yeS4gVGhlIHJldHVybmVkIHJlc291cmNlIG1heSBub3QgZXhpc3QuCiAgICAgKiBAcGFyYW0gcHJvamVjdE5hbWUgdGhlIG5hbWUgb2YgdGhlIHdlYiBwcm9qZWN0CiAgICAgKiBAcmV0dXJuIHRoZSB3c2RsIGZvbGRlcgogICAgICovCiAgICBwdWJsaWMgc3RhdGljIElGb2xkZXIgZ2V0V1NETEZvbGRlcihJUHJvamVjdCBwcm9qZWN0KSB7CiAgICAgICAgSVBhdGggd3NkbEZvbGRlclBhdGggPSBXU0RMVXRpbHMuZ2V0V2ViQ29udGVudFBhdGgocHJvamVjdCkuYXBwZW5kKFdTRExVdGlscy5XU0RMX0ZPTERFUl9QQVRIKTsKICAgICAgICBJRm9sZGVyIHdzZGxGb2xkZXIgPSBSZXNvdXJjZXNQbHVnaW4uZ2V0V29ya3NwYWNlKCkuZ2V0Um9vdCgpLmdldEZvbGRlcih3c2RsRm9sZGVyUGF0aCk7CiAgICAgICAgaWYgKCF3c2RsRm9sZGVyLmV4aXN0cygpKSB7CiAgICAgICAgICAgIHRyeSB7CiAgICAgICAgICAgICAgICB3c2RsRm9sZGVyLmNyZWF0ZSh0cnVlLCB0cnVlLCBuZXcgTnVsbFByb2dyZXNzTW9uaXRvcigpKTsKICAgICAgICAgICAgfSBjYXRjaCAoQ29yZUV4Y2VwdGlvbiBjZSkgewogICAgICAgICAgICAgICAgSkFYV1NDb3JlUGx1Z2luLmxvZyhjZS5nZXRTdGF0dXMoKSk7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgcmV0dXJuIHdzZGxGb2xkZXI7CiAgICB9CgogICAgcHJpdmF0ZSBzdGF0aWMgSVBhdGggZ2V0V2ViQ29udGVudFBhdGgoSVByb2plY3QgcHJvamVjdCkgewogICAgICAgIElWaXJ0dWFsQ29tcG9uZW50IHZpcnR1YWxDb21wb25lbnQgPSBDb21wb25lbnRDb3JlLmNyZWF0ZUNvbXBvbmVudChwcm9qZWN0KTsKICAgICAgICByZXR1cm4gdmlydHVhbENvbXBvbmVudC5nZXRSb290Rm9sZGVyKCkuZ2V0V29ya3NwYWNlUmVsYXRpdmVQYXRoKCk7CiAgICB9CgogICAgLyoqCiAgICAgKiBSZXR1cm5zIHRoZSBmaXJzdCA8Y29kZT5TT0FQQWRkcmVzczwvY29kZT4gb3IgPGNvZGU+U09BUDEyQWRkcmVzczwvY29kZT4gZm91bmQgaW4gdGhlIGdpdmVuCiAgICAgKiA8Y29kZT5EZWZpbml0aW9uPC9jb2RlPiBvciBudWxsIGlmIG5vbmUgaXMgZm91bmQuCiAgICAgKiBAcGFyYW0gZGVmaW5pdGlvbiB0aGUgZ2l2ZW4gZGVmaW5pdGlvbi4KICAgICAqIEByZXR1cm4gcmV0dXJuIG9uZSBvZjoKICAgICAqIDxsaT5TT0FQQWRkcmVzczxsaT5TT0FQMTJBZGRyZXNzPGxpPm51bGwgaWYgaXQgY2FuIG5vdCBmaW5kIGEgc29hcCBhZGRyZXNzCiAgICAgKi8KICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJ1bmNoZWNrZWQiKQogICAgcHVibGljIHN0YXRpYyBFeHRlbnNpYmlsaXR5RWxlbWVudCBnZXRFbmRwb2ludEFkZHJlc3MoRGVmaW5pdGlvbiBkZWZpbml0aW9uKSB7CiAgICAgICAgaWYgKGRlZmluaXRpb24gIT0gbnVsbCkgewogICAgICAgICAgICBNYXAgc2VydmljZXNNYXAgPSBkZWZpbml0aW9uLmdldFNlcnZpY2VzKCk7CiAgICAgICAgICAgIFNldDxNYXAuRW50cnk+IHNlcnZpY2VzU2V0ID0gc2VydmljZXNNYXAuZW50cnlTZXQoKTsKICAgICAgICAgICAgZm9yIChNYXAuRW50cnkgc2VydmljZUVudHJ5IDogc2VydmljZXNTZXQpIHsKICAgICAgICAgICAgICAgIFNlcnZpY2Ugc2VydmljZSA9IChTZXJ2aWNlKSBzZXJ2aWNlRW50cnkuZ2V0VmFsdWUoKTsKICAgICAgICAgICAgICAgIE1hcCBwb3J0c01hcCA9IHNlcnZpY2UuZ2V0UG9ydHMoKTsKICAgICAgICAgICAgICAgIFNldDxNYXAuRW50cnk+IHBvcnRzU2V0ID0gcG9ydHNNYXAuZW50cnlTZXQoKTsKICAgICAgICAgICAgICAgIGZvciAoTWFwLkVudHJ5IHBvcnRFbnRyeSA6IHBvcnRzU2V0KSB7CiAgICAgICAgICAgICAgICAgICAgUG9ydCBwb3J0ID0gKFBvcnQpIHBvcnRFbnRyeS5nZXRWYWx1ZSgpOwogICAgICAgICAgICAgICAgICAgIExpc3QgZXh0ZW5zaWJpbGl0eUVsZW1lbnRzID0gcG9ydC5nZXRFeHRlbnNpYmlsaXR5RWxlbWVudHMoKTsKICAgICAgICAgICAgICAgICAgICBmb3IgKE9iamVjdCBvYmplY3QgOiBleHRlbnNpYmlsaXR5RWxlbWVudHMpIHsKICAgICAgICAgICAgICAgICAgICAgICAgaWYgKG9iamVjdCBpbnN0YW5jZW9mIFNPQVBBZGRyZXNzIHx8IG9iamVjdCBpbnN0YW5jZW9mIFNPQVAxMkFkZHJlc3MpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiAoRXh0ZW5zaWJpbGl0eUVsZW1lbnQpIG9iamVjdDsKICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgIH0KICAgICAgICByZXR1cm4gbnVsbDsKICAgIH0KCiAgICAvKioKICAgICAqIFJldHVybnMgdGhlIGxvY2F0aW9uIFVSSSBmcm9tIHRoZSBmaXJzdCA8Y29kZT5TT0FQQWRkcmVzczwvY29kZT4gb3IgPGNvZGU+U09BUDEyQWRkcmVzczwvY29kZT4gZm91bmQKICAgICAqIGluIHRoZSBnaXZlbiA8Y29kZT5EZWZpbml0aW9uPC9jb2RlPiBvciBudWxsIGlmIG5vbmUgaXMgZm91bmQuIFRoZSByZXR1cm5lZCBsb2NhdGlvbiBVUkkgaXMgYXBwZW5kZWQgd2l0aAogICAgICogdGhlICc/d3NkbCcgcXVlcnkgaWYgdGhlIHF1ZXJ5IHdhcyBub3QgcHJlc2VudCBpbiB0aGUgPGNvZGU+U09BUEFkZHJlc3M8L2NvZGU+IG9yIDxjb2RlPlNPQVAxMkFkZHJlc3M8L2NvZGU+IGxvY2F0aW9uIFVSSS4KICAgICAqIEBwYXJhbSBkZWZpbml0aW9uIHRoZSBnaXZlbiBkZWZpbnRpb24uCiAgICAgKiBAcmV0dXJuIHRoZSBsb2NhdGlvbiBVUkkgb3IgdGhlIGZpcnN0IDxjb2RlPlNPQVBBZGRyZXNzPC9jb2RlPiBvciA8Y29kZT5TT0FQMTJBZGRyZXNzPC9jb2RlPiBmb3VuZCBpbiB0aGUgZ2l2ZW4gZGVmaW5pdGlvbi4KICAgICAqIEB0aHJvd3MgTWFsZm9ybWVkVVJMRXhjZXB0aW9uIGlmIGFuIGVycm9yIG9jY3VycyB0ZXN0aW5nIHRoZSBsb2NhdGlvbiBVUkkgZm9yIGEgcXVlcnkgcGFydC4KICAgICAqLwogICAgcHVibGljIHN0YXRpYyBTdHJpbmcgZ2V0V1NETExvY2F0aW9uKERlZmluaXRpb24gZGVmaW5pdGlvbikgdGhyb3dzIE1hbGZvcm1lZFVSTEV4Y2VwdGlvbiB7CiAgICAgICAgRXh0ZW5zaWJpbGl0eUVsZW1lbnQgZXh0ZW5zaWJpbGl0eUVsZW1lbnQgPSBXU0RMVXRpbHMuZ2V0RW5kcG9pbnRBZGRyZXNzKGRlZmluaXRpb24pOwogICAgICAgIGlmIChleHRlbnNpYmlsaXR5RWxlbWVudCAhPSBudWxsKSB7CiAgICAgICAgICAgIFN0cmluZyBsb2NhdGlvblVSSSA9IGdldExvY2F0aW9uVVJJKGV4dGVuc2liaWxpdHlFbGVtZW50KTsKICAgICAgICAgICAgaWYgKGxvY2F0aW9uVVJJLmxlbmd0aCgpID4gMCkgewogICAgICAgICAgICAgICAgVVJMIGVuZHBvaW50VVJMID0gbmV3IFVSTChsb2NhdGlvblVSSSk7CiAgICAgICAgICAgICAgICBpZiAoZW5kcG9pbnRVUkwuZ2V0UXVlcnkoKSA9PSBudWxsKSB7CiAgICAgICAgICAgICAgICAgICAgbG9jYXRpb25VUkkgKz0gV1NETF9RVUVSWTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIHJldHVybiBsb2NhdGlvblVSSTsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgICAgICByZXR1cm4gbnVsbDsKICAgIH0KCiAgICBwcml2YXRlIHN0YXRpYyBTdHJpbmcgZ2V0TG9jYXRpb25VUkkoRXh0ZW5zaWJpbGl0eUVsZW1lbnQgZXh0ZW5zaWJpbGl0eUVsZW1lbnQpIHsKICAgICAgICBpZiAoZXh0ZW5zaWJpbGl0eUVsZW1lbnQgaW5zdGFuY2VvZiBTT0FQQWRkcmVzcykgewogICAgICAgICAgICByZXR1cm4gKChTT0FQQWRkcmVzcykgZXh0ZW5zaWJpbGl0eUVsZW1lbnQpLmdldExvY2F0aW9uVVJJKCk7CiAgICAgICAgfQogICAgICAgIGlmIChleHRlbnNpYmlsaXR5RWxlbWVudCBpbnN0YW5jZW9mIFNPQVAxMkFkZHJlc3MpIHsKICAgICAgICAgICAgcmV0dXJuICgoU09BUDEyQWRkcmVzcykgZXh0ZW5zaWJpbGl0eUVsZW1lbnQpLmdldExvY2F0aW9uVVJJKCk7CiAgICAgICAgfQogICAgICAgIHJldHVybiAiIjsgLy8kTk9OLU5MUy0xJAogICAgfQoKICAgIC8qKgogICAgICogQ29uc3RydWN0cyBhIGRvdCBzZXBhcmF0ZWQgcGFja2FnZSBuYW1lIGZyb20gYSBnaXZlbiBuYW1lc3BhY2UuCiAgICAgKiA8cD5FLmcuLCB0aGUgbmFtZXNwYWNlINJodHRwOi8vd3MuZXhhbXBsZS5jb20v0yB3b3VsZCByZXR1cm4gdGhlIEphdmEgcGFja2FnZSBuYW1lINJjb20uZXhhbXBsZS53c9MuPC9wPgogICAgICogPHA+Ti5CLiBUaGlzIG1ldGhvZCBkb2VzIG5vdCBwcmVzZXJ2ZSAnd3d3JyBpbiB0aGUgcmV0dXJuZWQgcGFja2FnZSBuYW1lIGlmIGl0IGV4aXN0cyBpbiB0aGUgZ2l2ZW4gbmFtZXNwYWNlLjwvcD4KICAgICAqIEBwYXJhbSBuYW1lc3BhY2UgdGhlIGdpdmVuIG5hbWUuCiAgICAgKiBAcmV0dXJuIGEgcGFja2FnZSBuYW1lLgogICAgICovCiAgICBwdWJsaWMgc3RhdGljIFN0cmluZyBnZXRQYWNrYWdlTmFtZUZyb21OYW1lc3BhY2UoU3RyaW5nIG5hbWVzcGFjZSkgewogICAgICAgIFN0cmluZyBwYWNrYWdlTmFtZSA9ICIiOyAvLyROT04tTkxTLTEkCiAgICAgICAgdHJ5IHsKICAgICAgICAgICAgTGlzdDxTdHJpbmc+IHBhY2thZ2VOYW1lRWxlbWVudHMgPSBuZXcgQXJyYXlMaXN0PFN0cmluZz4oKTsKCiAgICAgICAgICAgIFVSTCBuYW1lc3BhY2VVUkwgPSBuZXcgVVJMKG5hbWVzcGFjZSk7CgogICAgICAgICAgICAvLyBSZW1vdmUgd3d3IGlmIHRoZXJlCiAgICAgICAgICAgIFN0cmluZyBhdXRob3JpdHkgPSBuYW1lc3BhY2VVUkwuZ2V0QXV0aG9yaXR5KCk7CiAgICAgICAgICAgIGlmIChhdXRob3JpdHkuaW5kZXhPZigid3d3IikgIT0gLTEpIHsgLy8kTk9OLU5MUy0xJAogICAgICAgICAgICAgICAgYXV0aG9yaXR5ID0gYXV0aG9yaXR5LnN1YnN0cmluZyhhdXRob3JpdHkuaW5kZXhPZigiLiIpICsgMSwgYXV0aG9yaXR5Lmxlbmd0aCgpKTsgLy8kTk9OLU5MUy0xJAogICAgICAgICAgICB9CgogICAgICAgICAgICBMaXN0PFN0cmluZz4gYXV0aG9yaXR5RWxlbWVudHMgPSBBcnJheXMuYXNMaXN0KGF1dGhvcml0eS5zcGxpdCgiXFwuIikpOyAvLyROT04tTkxTLTEkCiAgICAgICAgICAgIENvbGxlY3Rpb25zLnJldmVyc2UoYXV0aG9yaXR5RWxlbWVudHMpOwogICAgICAgICAgICBwYWNrYWdlTmFtZUVsZW1lbnRzLmFkZEFsbChhdXRob3JpdHlFbGVtZW50cyk7CgogICAgICAgICAgICBTdHJpbmcgcGF0aCA9IG5hbWVzcGFjZVVSTC5nZXRQYXRoKCk7CiAgICAgICAgICAgIExpc3Q8U3RyaW5nPiBwYXRoRWxlbWVudHMgPSBBcnJheXMuYXNMaXN0KHBhdGguc3BsaXQoIlsvXFxcXF0iKSk7IC8vJE5PTi1OTFMtMSQKICAgICAgICAgICAgcGFja2FnZU5hbWVFbGVtZW50cy5hZGRBbGwocGF0aEVsZW1lbnRzKTsKCiAgICAgICAgICAgIEl0ZXJhdG9yPFN0cmluZz4gcGFja2FnZUl0ZXJhdG9yID0gcGFja2FnZU5hbWVFbGVtZW50cy5pdGVyYXRvcigpOwogICAgICAgICAgICB3aGlsZSAocGFja2FnZUl0ZXJhdG9yLmhhc05leHQoKSkgewogICAgICAgICAgICAgICAgU3RyaW5nIGVsZW1lbnQgPSBwYWNrYWdlSXRlcmF0b3IubmV4dCgpOwogICAgICAgICAgICAgICAgaWYgKGVsZW1lbnQudHJpbSgpLmxlbmd0aCgpID4gMCkgewogICAgICAgICAgICAgICAgICAgIHBhY2thZ2VOYW1lICs9IGVsZW1lbnQ7CiAgICAgICAgICAgICAgICAgICAgaWYgKHBhY2thZ2VJdGVyYXRvci5oYXNOZXh0KCkpIHsKICAgICAgICAgICAgICAgICAgICAgICAgcGFja2FnZU5hbWUgKz0gIi4iOyAvLyROT04tTkxTLTEkCiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgfSBjYXRjaCAoTWFsZm9ybWVkVVJMRXhjZXB0aW9uIG11cmxlKSB7CiAgICAgICAgICAgIEpBWFdTQ29yZVBsdWdpbi5sb2cobXVybGUpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gcGFja2FnZU5hbWUudG9Mb3dlckNhc2UoKTsKICAgIH0KfQo=