LyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogQ29weXJpZ2h0IChjKSAyMDA4IElPTkEgVGVjaG5vbG9naWVzIFBMQwogKiBBbGwgcmlnaHRzIHJlc2VydmVkLiBUaGlzIHByb2dyYW0gYW5kIHRoZSBhY2NvbXBhbnlpbmcgbWF0ZXJpYWxzCiAqIGFyZSBtYWRlIGF2YWlsYWJsZSB1bmRlciB0aGUgdGVybXMgb2YgdGhlIEVjbGlwc2UgUHVibGljIExpY2Vuc2UgdjEuMAogKiB3aGljaCBhY2NvbXBhbmllcyB0aGlzIGRpc3RyaWJ1dGlvbiwgYW5kIGlzIGF2YWlsYWJsZSBhdAogKiBodHRwOi8vd3d3LmVjbGlwc2Uub3JnL2xlZ2FsL2VwbC12MTAuaHRtbAogKgogKiBDb250cmlidXRvcnM6CiAqIElPTkEgVGVjaG5vbG9naWVzIFBMQyAtIGluaXRpYWwgQVBJIGFuZCBpbXBsZW1lbnRhdGlvbgogKiBCdWcgIzI3NDI5MyAtIHN1ZGhhbkBwcm9ncmVzcy5jb20KICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCnBhY2thZ2Ugb3JnLmVjbGlwc2UuanN0LndzLmpheHdzLmNvcmUudXRpbHM7CgppbXBvcnQgamF2YS5pby5GaWxlOwppbXBvcnQgamF2YS5pby5GaWxlT3V0cHV0U3RyZWFtOwppbXBvcnQgamF2YS5pby5JT0V4Y2VwdGlvbjsKaW1wb3J0IGphdmEuaW8uSW5wdXRTdHJlYW07CmltcG9ydCBqYXZhLmlvLk91dHB1dFN0cmVhbTsKaW1wb3J0IGphdmEubmV0Lk1hbGZvcm1lZFVSTEV4Y2VwdGlvbjsKaW1wb3J0IGphdmEubmV0LlVSSTsKaW1wb3J0IGphdmEubmV0LlVSSVN5bnRheEV4Y2VwdGlvbjsKaW1wb3J0IGphdmEubmV0LlVSTDsKaW1wb3J0IGphdmEubmV0LlVSTENvbm5lY3Rpb247CmltcG9ydCBqYXZhLnV0aWwuQXJyYXlMaXN0OwppbXBvcnQgamF2YS51dGlsLkFycmF5czsKaW1wb3J0IGphdmEudXRpbC5Db2xsZWN0aW9uczsKaW1wb3J0IGphdmEudXRpbC5JdGVyYXRvcjsKaW1wb3J0IGphdmEudXRpbC5MaXN0OwppbXBvcnQgamF2YS51dGlsLk1hcDsKaW1wb3J0IGphdmEudXRpbC5TZXQ7CgppbXBvcnQgamF2YXgud3NkbC5EZWZpbml0aW9uOwppbXBvcnQgamF2YXgud3NkbC5Qb3J0OwppbXBvcnQgamF2YXgud3NkbC5TZXJ2aWNlOwppbXBvcnQgamF2YXgud3NkbC5XU0RMRXhjZXB0aW9uOwppbXBvcnQgamF2YXgud3NkbC5leHRlbnNpb25zLkV4dGVuc2liaWxpdHlFbGVtZW50OwppbXBvcnQgamF2YXgud3NkbC5leHRlbnNpb25zLnNvYXAuU09BUEFkZHJlc3M7CmltcG9ydCBqYXZheC53c2RsLmV4dGVuc2lvbnMuc29hcDEyLlNPQVAxMkFkZHJlc3M7CmltcG9ydCBqYXZheC53c2RsLmZhY3RvcnkuV1NETEZhY3Rvcnk7CmltcG9ydCBqYXZheC53c2RsLnhtbC5XU0RMUmVhZGVyOwppbXBvcnQgamF2YXgud3NkbC54bWwuV1NETFdyaXRlcjsKCmltcG9ydCBvcmcuZWNsaXBzZS5jb3JlLmZpbGVzeXN0ZW0uVVJJVXRpbDsKaW1wb3J0IG9yZy5lY2xpcHNlLmNvcmUucmVzb3VyY2VzLklGaWxlOwppbXBvcnQgb3JnLmVjbGlwc2UuY29yZS5yZXNvdXJjZXMuSUZvbGRlcjsKaW1wb3J0IG9yZy5lY2xpcHNlLmNvcmUucmVzb3VyY2VzLklQcm9qZWN0OwppbXBvcnQgb3JnLmVjbGlwc2UuY29yZS5yZXNvdXJjZXMuSVJlc291cmNlOwppbXBvcnQgb3JnLmVjbGlwc2UuY29yZS5yZXNvdXJjZXMuUmVzb3VyY2VzUGx1Z2luOwppbXBvcnQgb3JnLmVjbGlwc2UuY29yZS5ydW50aW1lLkNvcmVFeGNlcHRpb247CmltcG9ydCBvcmcuZWNsaXBzZS5jb3JlLnJ1bnRpbWUuSVBhdGg7CmltcG9ydCBvcmcuZWNsaXBzZS5jb3JlLnJ1bnRpbWUuTnVsbFByb2dyZXNzTW9uaXRvcjsKaW1wb3J0IG9yZy5lY2xpcHNlLmNvcmUucnVudGltZS5QYXRoOwppbXBvcnQgb3JnLmVjbGlwc2UuanN0LndzLmludGVybmFsLmpheHdzLmNvcmUuSkFYV1NDb3JlUGx1Z2luOwppbXBvcnQgb3JnLmVjbGlwc2Uud3N0LmNvbW1vbi5jb21wb25lbnRjb3JlLkNvbXBvbmVudENvcmU7CmltcG9ydCBvcmcuZWNsaXBzZS53c3QuY29tbW9uLmNvbXBvbmVudGNvcmUucmVzb3VyY2VzLklWaXJ0dWFsQ29tcG9uZW50OwppbXBvcnQgb3JnLnhtbC5zYXguSW5wdXRTb3VyY2U7CgovKioKICogV1NETCBVdGlsaXR5IGNsYXNzLgogKiA8cD4KICogPHN0cm9uZz5Qcm92aXNpb25hbCBBUEk6PC9zdHJvbmc+IFRoaXMgY2xhc3MvaW50ZXJmYWNlIGlzIHBhcnQgb2YgYW4gaW50ZXJpbSBBUEkgdGhhdCBpcyBzdGlsbCB1bmRlcgogKiBkZXZlbG9wbWVudCBhbmQgZXhwZWN0ZWQgdG8gY2hhbmdlIHNpZ25pZmljYW50bHkgYmVmb3JlIHJlYWNoaW5nIHN0YWJpbGl0eS4gSXQgaXMgYmVpbmcgbWFkZSBhdmFpbGFibGUgYXQKICogdGhpcyBlYXJseSBzdGFnZSB0byBzb2xpY2l0IGZlZWRiYWNrIGZyb20gcGlvbmVlcmluZyBhZG9wdGVycyBvbiB0aGUgdW5kZXJzdGFuZGluZyB0aGF0IGFueSBjb2RlIHRoYXQgdXNlcwogKiB0aGlzIEFQSSB3aWxsIGFsbW9zdCBjZXJ0YWlubHkgYmUgYnJva2VuIChyZXBlYXRlZGx5KSBhcyB0aGUgQVBJIGV2b2x2ZXMuCiAqIDwvcD4KICovCnB1YmxpYyBmaW5hbCBjbGFzcyBXU0RMVXRpbHMgewogICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgU3RyaW5nIFdTRExfRklMRV9OQU1FX1BBVFRFUk4gPSAiW2EtekEtWjAtOV9cXC1dKy53c2RsIjsvLyROT04tTkxTLTEkCiAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBTdHJpbmcgV1NETF9RVUVSWSA9ICI/d3NkbCI7IC8vJE5PTi1OTFMtMSQKCiAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBJUGF0aCBXU0RMX0ZPTERFUl9QQVRIID0gbmV3IFBhdGgoIndzZGwvIik7IC8vJE5PTi1OTFMtMSQKICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGludCBUSU1FT1VUID0gMzAwMDA7CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgV1NETF9GSUxFX0VYVEVOU0lPTiA9ICIud3NkbCI7IC8vJE5PTi1OTFMtMSQKCiAgICBwcml2YXRlIFdTRExVdGlscygpIHsKICAgIH0KCiAgICAvKioKICAgICAqIFJldHVybnMgYSA8Y29kZT5qYXZheC53c2RsLkRlZmluaXRpb248L2NvZGU+IGJ5IHJlYWRpbmcgdGhlIFdTREwgZG9jdW1lbnQgYXQgdGhlIGdpdmVuIFVSTCBvciBudWxsIGlmIG5vbmUgY2FuIGJlIGZvdW5kCiAgICAgKiBvciBpZiB0aGUgY29ubmVjdGlvbiB0aW1lcyBvdXQuCiAgICAgKiBAcGFyYW0gd3NkbFVSTCB0aGUgdXJsIG9mIHRoZSB3c2RsIGRvY3VtZW50IHRvIHJlYWQuCiAgICAgKiBAcmV0dXJuIHRoZSBkZWZpbml0aW9uIGRlc2NyaWJlZCBpbiB0aGUgd3NkbCBkb2N1bWVudCBwb2ludGVkIHRvIGJ5IHRoZSBnaXZlbiBVUkwuCiAgICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uIGlmIGFuIEkvTyBleGNlcHRpb24gb2NjdXJzLgogICAgICovCiAgICBwdWJsaWMgc3RhdGljIERlZmluaXRpb24gcmVhZFdTREwoVVJMIHdzZGxVUkwpIHRocm93cyBJT0V4Y2VwdGlvbiB7CiAgICAgICAgVVJMQ29ubmVjdGlvbiB1cmxDb25uZWN0aW9uID0gd3NkbFVSTC5vcGVuQ29ubmVjdGlvbigpOwogICAgICAgIHVybENvbm5lY3Rpb24uc2V0Q29ubmVjdFRpbWVvdXQoVElNRU9VVCk7CiAgICAgICAgdXJsQ29ubmVjdGlvbi5zZXRSZWFkVGltZW91dChUSU1FT1VUKTsKICAgICAgICBJbnB1dFN0cmVhbSBpbnB1dFN0cmVhbSA9IG51bGw7CiAgICAgICAgdHJ5IHsKICAgICAgICAgICAgaW5wdXRTdHJlYW0gPSB1cmxDb25uZWN0aW9uLmdldElucHV0U3RyZWFtKCk7CiAgICAgICAgICAgIElucHV0U291cmNlIGlucHV0U291cmNlID0gbmV3IElucHV0U291cmNlKGlucHV0U3RyZWFtKTsKICAgICAgICAgICAgV1NETEZhY3Rvcnkgd3NkbEZhY3RvcnkgPSBXU0RMRmFjdG9yeS5uZXdJbnN0YW5jZSgpOwogICAgICAgICAgICBXU0RMUmVhZGVyIHdzZGxSZWFkZXIgPSB3c2RsRmFjdG9yeS5uZXdXU0RMUmVhZGVyKCk7CiAgICAgICAgICAgIERlZmluaXRpb24gZGVmaW5pdGlvbiA9IHdzZGxSZWFkZXIucmVhZFdTREwod3NkbFVSTC5nZXRQYXRoKCksIGlucHV0U291cmNlKTsKICAgICAgICAgICAgcmV0dXJuIGRlZmluaXRpb247CiAgICAgICAgfSBjYXRjaCAoV1NETEV4Y2VwdGlvbiB3c2RsZSkgewogICAgICAgICAgICBKQVhXU0NvcmVQbHVnaW4ubG9nKHdzZGxlKTsKICAgICAgICB9IGZpbmFsbHkgewogICAgICAgICAgICBpZiAoaW5wdXRTdHJlYW0gIT0gbnVsbCkgewogICAgICAgICAgICAgICAgaW5wdXRTdHJlYW0uY2xvc2UoKTsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgICAgICByZXR1cm4gbnVsbDsKICAgIH0KCiAgICAvKioKICAgICAqIFdyaXRlcyB0aGUgZ2l2ZW4gPGNvZGU+amF2YXgud3NkbC5EZWZpbml0aW9uPC9jb2RlPiB0byB0aGUgd3NkbCBkb2N1bWVudCBhdCB0aGUgZ2l2ZW4gVVJMLgogICAgICogQHBhcmFtIHdzZGxVUkwgdGhlIHVybCBvZiB0aGUgd3NkbCBkb2N1bWVudCB0byB3cml0ZSB0by4KICAgICAqIEBwYXJhbSBkZWZpbml0aW9uIHRoZSBXU0RMIGRlZmluaXRpb24gdG8gYmUgd3JpdHRlbi4KICAgICAqIEB0aHJvd3MgSU9FeGNlcHRpb24gIGlmIGFuIEkvTyBleGNlcHRpb24gb2NjdXJzLgogICAgICogQHRocm93cyBDb3JlRXhjZXB0aW9uIGlmIGFuIGV4Y2VwdGlvbiBvY2N1cnMgcmVmcmVzaGluZyB0aGUgZmlsZSBpbiB0aGUgd29ya3NwYWNlIGlmIGl0IGV4aXN0cy4KICAgICAqLwogICAgcHVibGljIHN0YXRpYyB2b2lkIHdyaXRlV1NETChVUkwgd3NkbFVSTCwgRGVmaW5pdGlvbiBkZWZpbml0aW9uKSB0aHJvd3MgSU9FeGNlcHRpb24sIENvcmVFeGNlcHRpb24gewogICAgICAgIFVSSSB3c2RsVVJJID0gbnVsbDsKICAgICAgICBPdXRwdXRTdHJlYW0gd3NkbE91dHB1dFN0cmVhbSA9IG51bGw7CiAgICAgICAgdHJ5IHsKICAgICAgICAgICAgd3NkbFVSSSA9IHdzZGxVUkwudG9VUkkoKTsKICAgICAgICAgICAgRmlsZSB3c2RsRmlsZSA9IG5ldyBGaWxlKHdzZGxVUkkpOwogICAgICAgICAgICB3c2RsT3V0cHV0U3RyZWFtID0gbmV3IEZpbGVPdXRwdXRTdHJlYW0od3NkbEZpbGUpOwogICAgICAgICAgICBXU0RMRmFjdG9yeSB3c2RsRmFjdG9yeSA9IFdTRExGYWN0b3J5Lm5ld0luc3RhbmNlKCk7CiAgICAgICAgICAgIFdTRExXcml0ZXIgd3NkbFdyaXRlciA9IHdzZGxGYWN0b3J5Lm5ld1dTRExXcml0ZXIoKTsKICAgICAgICAgICAgd3NkbFdyaXRlci53cml0ZVdTREwoZGVmaW5pdGlvbiwgd3NkbE91dHB1dFN0cmVhbSk7CiAgICAgICAgfSBjYXRjaCAoV1NETEV4Y2VwdGlvbiB3c2RsZSkgewogICAgICAgICAgICBKQVhXU0NvcmVQbHVnaW4ubG9nKHdzZGxlKTsKICAgICAgICB9IGNhdGNoIChVUklTeW50YXhFeGNlcHRpb24gdXJpc2UpIHsKICAgICAgICAgICAgSkFYV1NDb3JlUGx1Z2luLmxvZyh1cmlzZSk7CiAgICAgICAgfSBmaW5hbGx5IHsKICAgICAgICAgICAgaWYgKHdzZGxPdXRwdXRTdHJlYW0gIT0gbnVsbCkgewogICAgICAgICAgICAgICAgd3NkbE91dHB1dFN0cmVhbS5jbG9zZSgpOwogICAgICAgICAgICAgICAgSUZpbGUgZmlsZSA9IFJlc291cmNlc1BsdWdpbi5nZXRXb3Jrc3BhY2UoKS5nZXRSb290KCkKICAgICAgICAgICAgICAgIC5nZXRGaWxlRm9yTG9jYXRpb24oVVJJVXRpbC50b1BhdGgod3NkbFVSSSkpOwogICAgICAgICAgICAgICAgaWYgKGZpbGUgIT0gbnVsbCAmJiBmaWxlLmV4aXN0cygpKSB7CiAgICAgICAgICAgICAgICAgICAgZmlsZS5yZWZyZXNoTG9jYWwoSVJlc291cmNlLkRFUFRIX09ORSwgbmV3IE51bGxQcm9ncmVzc01vbml0b3IoKSk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICB9CgogICAgLyoqCiAgICAgKiBSZXR1cm5zIDxjb2RlPnRydWU8L2NvZGU+IGlmIHRoZSBnaXZlbiBmaWxlIG5hbWUgY29udGFpbnMgQWxwaGFudW1lcmljIGNoYXJhY3RlcnMsIHVuZGVyc2NvcmUgJ18nLAogICAgICogZGFzaGVzICctJyBhbmQgZW5kcyB3aXRoIHRoZSAnLndzZGwnIGV4dGVuc2lvbi4gT3RoZXJ3aXNlIHJldHVybnMgPGNvZGU+ZmFsc2U8L2NvZGU+LgogICAgICogQHBhcmFtIHdzZGxGaWxlTmFtZSB0aGUgd3NkbCBmaWxlIG5hbWUKICAgICAqIEByZXR1cm4gPGNvZGU+dHJ1ZTwvY29kZT4gaWYgdmFsaWQsIGNvZGU+ZmFsc2U8L2NvZGU+IG90aGVyd2lzZS4KICAgICAqLwogICAgcHVibGljIHN0YXRpYyBib29sZWFuIGlzVmFsaWRXU0RMRmlsZU5hbWUoU3RyaW5nIHdzZGxGaWxlTmFtZSkgewogICAgICAgIHJldHVybiB3c2RsRmlsZU5hbWUgIT0gbnVsbCAmJiB3c2RsRmlsZU5hbWUubWF0Y2hlcyhXU0RMX0ZJTEVfTkFNRV9QQVRURVJOKTsKICAgIH0KCiAgICBwcml2YXRlIHN0YXRpYyBJUHJvamVjdCBnZXRQcm9qZWN0KFN0cmluZyBwcm9qZWN0TmFtZSkgewogICAgICAgIHJldHVybiBSZXNvdXJjZXNQbHVnaW4uZ2V0V29ya3NwYWNlKCkuZ2V0Um9vdCgpLmdldFByb2plY3QocHJvamVjdE5hbWUpOwogICAgfQoKICAgIC8qKgogICAgICogUmV0dXJucyB0aGUgV2ViIENvbnRlbnQgZm9sZGVyIG9mIHRoZSBnaXZlbiBwcm9qZWN0LiBUaGUgcmV0dXJuZWQgcmVzb3VyY2UgbWF5IG5vdCBleGlzdC4KICAgICAqIEBwYXJhbSBwcm9qZWN0IHRoZSBuYW1lIG9mIHRoZSB3ZWIgcHJvamVjdAogICAgICogQHJldHVybiB0aGUgd2ViIGNvbnRlbnQgZm9sZGVyCiAgICAgKi8KICAgIHB1YmxpYyBzdGF0aWMgSUZvbGRlciBnZXRXZWJDb250ZW50Rm9sZGVyKElQcm9qZWN0IHByb2plY3QpIHsKICAgICAgICByZXR1cm4gUmVzb3VyY2VzUGx1Z2luLmdldFdvcmtzcGFjZSgpLmdldFJvb3QoKS5nZXRGb2xkZXIoCiAgICAgICAgICAgICAgICBXU0RMVXRpbHMuZ2V0V2ViQ29udGVudFBhdGgocHJvamVjdCkpOwogICAgfQoKICAgIC8qKgogICAgICogUmV0dXJucyB0aGUgV1NETCBmb2xkZXIgb2YgdGhlIHByb2plY3Qgd2l0aCB0aGUgZ2l2ZW4gbmFtZS4gVGhlIFdTREwgZm9sZGVyIHBhdGggaXMgdGhlIHByb2plY3RzIHdlYiBjb250ZW50IGZvbGRlcgogICAgICogcGF0aCBhcHBlbmRlZCB3aXRoIHRoZSAnV1NETCcgZGlyZWN0b3J5LiBUaGUgcmV0dXJuZWQgcmVzb3VyY2UgbWF5IG5vdCBleGlzdC4KICAgICAqIEBwYXJhbSBwcm9qZWN0TmFtZSB0aGUgbmFtZSBvZiB0aGUgd2ViIHByb2plY3QKICAgICAqIEByZXR1cm4gdGhlIHdzZGwgZm9sZGVyCiAgICAgKi8KICAgIHB1YmxpYyBzdGF0aWMgSUZvbGRlciBnZXRXU0RMRm9sZGVyKFN0cmluZyBwcm9qZWN0TmFtZSkgewogICAgICAgIHJldHVybiBXU0RMVXRpbHMuZ2V0V1NETEZvbGRlcihXU0RMVXRpbHMuZ2V0UHJvamVjdChwcm9qZWN0TmFtZSkpOwogICAgfQoKICAgIC8qKgogICAgICogUmV0dXJucyB0aGUgV1NETCBmb2xkZXIgb2YgdGhlIGdpdmVuIHByb2plY3QuIFRoZSBXU0RMIGZvbGRlciBwYXRoIGlzIHRoZSBwcm9qZWN0cyB3ZWIgY29udGVudCBmb2xkZXIKICAgICAqIHBhdGggYXBwZW5kZWQgd2l0aCB0aGUgJ1dTREwnIGRpcmVjdG9yeS4gVGhlIHJldHVybmVkIHJlc291cmNlIG1heSBub3QgZXhpc3QuCiAgICAgKiBAcGFyYW0gcHJvamVjdCB0aGUgd2ViIHByb2plY3QKICAgICAqIEByZXR1cm4gdGhlIHdzZGwgZm9sZGVyCiAgICAgKi8KICAgIHB1YmxpYyBzdGF0aWMgSUZvbGRlciBnZXRXU0RMRm9sZGVyKElQcm9qZWN0IHByb2plY3QpIHsKICAgICAgICBJUGF0aCB3c2RsRm9sZGVyUGF0aCA9IFdTRExVdGlscy5nZXRXZWJDb250ZW50UGF0aChwcm9qZWN0KS5hcHBlbmQoV1NETFV0aWxzLldTRExfRk9MREVSX1BBVEgpOwogICAgICAgIElGb2xkZXIgd3NkbEZvbGRlciA9IFJlc291cmNlc1BsdWdpbi5nZXRXb3Jrc3BhY2UoKS5nZXRSb290KCkuZ2V0Rm9sZGVyKHdzZGxGb2xkZXJQYXRoKTsKICAgICAgICBpZiAoIXdzZGxGb2xkZXIuZXhpc3RzKCkpIHsKICAgICAgICAgICAgdHJ5IHsKICAgICAgICAgICAgICAgIHdzZGxGb2xkZXIuY3JlYXRlKHRydWUsIHRydWUsIG5ldyBOdWxsUHJvZ3Jlc3NNb25pdG9yKCkpOwogICAgICAgICAgICB9IGNhdGNoIChDb3JlRXhjZXB0aW9uIGNlKSB7CiAgICAgICAgICAgICAgICBKQVhXU0NvcmVQbHVnaW4ubG9nKGNlLmdldFN0YXR1cygpKTsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgICAgICByZXR1cm4gd3NkbEZvbGRlcjsKICAgIH0KCiAgICBwcml2YXRlIHN0YXRpYyBJUGF0aCBnZXRXZWJDb250ZW50UGF0aChJUHJvamVjdCBwcm9qZWN0KSB7CiAgICAgICAgSVZpcnR1YWxDb21wb25lbnQgdmlydHVhbENvbXBvbmVudCA9IENvbXBvbmVudENvcmUuY3JlYXRlQ29tcG9uZW50KHByb2plY3QpOwogICAgICAgIHJldHVybiB2aXJ0dWFsQ29tcG9uZW50LmdldFJvb3RGb2xkZXIoKS5nZXRXb3Jrc3BhY2VSZWxhdGl2ZVBhdGgoKTsKICAgIH0KCiAgICAvKioKICAgICAqIFJldHVybnMgdGhlIGZpcnN0IDxjb2RlPlNPQVBBZGRyZXNzPC9jb2RlPiBvciA8Y29kZT5TT0FQMTJBZGRyZXNzPC9jb2RlPiBmb3VuZCBpbiB0aGUgZ2l2ZW4KICAgICAqIDxjb2RlPkRlZmluaXRpb248L2NvZGU+IG9yIG51bGwgaWYgbm9uZSBpcyBmb3VuZC4KICAgICAqIEBwYXJhbSBkZWZpbml0aW9uIHRoZSBnaXZlbiBkZWZpbml0aW9uLgogICAgICogQHJldHVybiByZXR1cm4gb25lIG9mOgogICAgICogPGxpPlNPQVBBZGRyZXNzPGxpPlNPQVAxMkFkZHJlc3M8bGk+bnVsbCBpZiBpdCBjYW4gbm90IGZpbmQgYSBzb2FwIGFkZHJlc3MKICAgICAqLwogICAgQFN1cHByZXNzV2FybmluZ3MoInVuY2hlY2tlZCIpCiAgICBwdWJsaWMgc3RhdGljIEV4dGVuc2liaWxpdHlFbGVtZW50IGdldEVuZHBvaW50QWRkcmVzcyhEZWZpbml0aW9uIGRlZmluaXRpb24pIHsKICAgICAgICBpZiAoZGVmaW5pdGlvbiAhPSBudWxsKSB7CiAgICAgICAgICAgIE1hcCBzZXJ2aWNlc01hcCA9IGRlZmluaXRpb24uZ2V0U2VydmljZXMoKTsKICAgICAgICAgICAgU2V0PE1hcC5FbnRyeT4gc2VydmljZXNTZXQgPSBzZXJ2aWNlc01hcC5lbnRyeVNldCgpOwogICAgICAgICAgICBmb3IgKE1hcC5FbnRyeSBzZXJ2aWNlRW50cnkgOiBzZXJ2aWNlc1NldCkgewogICAgICAgICAgICAgICAgU2VydmljZSBzZXJ2aWNlID0gKFNlcnZpY2UpIHNlcnZpY2VFbnRyeS5nZXRWYWx1ZSgpOwogICAgICAgICAgICAgICAgTWFwIHBvcnRzTWFwID0gc2VydmljZS5nZXRQb3J0cygpOwogICAgICAgICAgICAgICAgU2V0PE1hcC5FbnRyeT4gcG9ydHNTZXQgPSBwb3J0c01hcC5lbnRyeVNldCgpOwogICAgICAgICAgICAgICAgZm9yIChNYXAuRW50cnkgcG9ydEVudHJ5IDogcG9ydHNTZXQpIHsKICAgICAgICAgICAgICAgICAgICBQb3J0IHBvcnQgPSAoUG9ydCkgcG9ydEVudHJ5LmdldFZhbHVlKCk7CiAgICAgICAgICAgICAgICAgICAgTGlzdCBleHRlbnNpYmlsaXR5RWxlbWVudHMgPSBwb3J0LmdldEV4dGVuc2liaWxpdHlFbGVtZW50cygpOwogICAgICAgICAgICAgICAgICAgIGZvciAoT2JqZWN0IG9iamVjdCA6IGV4dGVuc2liaWxpdHlFbGVtZW50cykgewogICAgICAgICAgICAgICAgICAgICAgICBpZiAob2JqZWN0IGluc3RhbmNlb2YgU09BUEFkZHJlc3MgfHwgb2JqZWN0IGluc3RhbmNlb2YgU09BUDEyQWRkcmVzcykgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIChFeHRlbnNpYmlsaXR5RWxlbWVudCkgb2JqZWN0OwogICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIHJldHVybiBudWxsOwogICAgfQoKICAgIC8qKgogICAgICogUmV0dXJucyB0aGUgbG9jYXRpb24gVVJJIGZyb20gdGhlIGZpcnN0IDxjb2RlPlNPQVBBZGRyZXNzPC9jb2RlPiBvciA8Y29kZT5TT0FQMTJBZGRyZXNzPC9jb2RlPiBmb3VuZAogICAgICogaW4gdGhlIGdpdmVuIDxjb2RlPkRlZmluaXRpb248L2NvZGU+IG9yIG51bGwgaWYgbm9uZSBpcyBmb3VuZC4gVGhlIHJldHVybmVkIGxvY2F0aW9uIFVSSSBpcyBhcHBlbmRlZCB3aXRoCiAgICAgKiB0aGUgJz93c2RsJyBxdWVyeSBpZiB0aGUgcXVlcnkgd2FzIG5vdCBwcmVzZW50IGluIHRoZSA8Y29kZT5TT0FQQWRkcmVzczwvY29kZT4gb3IgPGNvZGU+U09BUDEyQWRkcmVzczwvY29kZT4gbG9jYXRpb24gVVJJLgogICAgICogQHBhcmFtIGRlZmluaXRpb24gdGhlIGdpdmVuIGRlZmludGlvbi4KICAgICAqIEByZXR1cm4gdGhlIGxvY2F0aW9uIFVSSSBvciB0aGUgZmlyc3QgPGNvZGU+U09BUEFkZHJlc3M8L2NvZGU+IG9yIDxjb2RlPlNPQVAxMkFkZHJlc3M8L2NvZGU+IGZvdW5kIGluIHRoZSBnaXZlbiBkZWZpbml0aW9uLgogICAgICogQHRocm93cyBNYWxmb3JtZWRVUkxFeGNlcHRpb24gaWYgYW4gZXJyb3Igb2NjdXJzIHRlc3RpbmcgdGhlIGxvY2F0aW9uIFVSSSBmb3IgYSBxdWVyeSBwYXJ0LgogICAgICovCiAgICBwdWJsaWMgc3RhdGljIFN0cmluZyBnZXRXU0RMTG9jYXRpb24oRGVmaW5pdGlvbiBkZWZpbml0aW9uKSB0aHJvd3MgTWFsZm9ybWVkVVJMRXhjZXB0aW9uIHsKICAgICAgICBFeHRlbnNpYmlsaXR5RWxlbWVudCBleHRlbnNpYmlsaXR5RWxlbWVudCA9IFdTRExVdGlscy5nZXRFbmRwb2ludEFkZHJlc3MoZGVmaW5pdGlvbik7CiAgICAgICAgaWYgKGV4dGVuc2liaWxpdHlFbGVtZW50ICE9IG51bGwpIHsKICAgICAgICAgICAgU3RyaW5nIGxvY2F0aW9uVVJJID0gZ2V0TG9jYXRpb25VUkkoZXh0ZW5zaWJpbGl0eUVsZW1lbnQpOwogICAgICAgICAgICBpZiAobG9jYXRpb25VUkkubGVuZ3RoKCkgPiAwKSB7CiAgICAgICAgICAgICAgICBVUkwgZW5kcG9pbnRVUkwgPSBuZXcgVVJMKGxvY2F0aW9uVVJJKTsKICAgICAgICAgICAgICAgIGlmIChlbmRwb2ludFVSTC5nZXRRdWVyeSgpID09IG51bGwpIHsKICAgICAgICAgICAgICAgICAgICBsb2NhdGlvblVSSSArPSBXU0RMX1FVRVJZOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgcmV0dXJuIGxvY2F0aW9uVVJJOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIHJldHVybiBudWxsOwogICAgfQoKICAgIHByaXZhdGUgc3RhdGljIFN0cmluZyBnZXRMb2NhdGlvblVSSShFeHRlbnNpYmlsaXR5RWxlbWVudCBleHRlbnNpYmlsaXR5RWxlbWVudCkgewogICAgICAgIGlmIChleHRlbnNpYmlsaXR5RWxlbWVudCBpbnN0YW5jZW9mIFNPQVBBZGRyZXNzKSB7CiAgICAgICAgICAgIHJldHVybiAoKFNPQVBBZGRyZXNzKSBleHRlbnNpYmlsaXR5RWxlbWVudCkuZ2V0TG9jYXRpb25VUkkoKTsKICAgICAgICB9CiAgICAgICAgaWYgKGV4dGVuc2liaWxpdHlFbGVtZW50IGluc3RhbmNlb2YgU09BUDEyQWRkcmVzcykgewogICAgICAgICAgICByZXR1cm4gKChTT0FQMTJBZGRyZXNzKSBleHRlbnNpYmlsaXR5RWxlbWVudCkuZ2V0TG9jYXRpb25VUkkoKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuICIiOyAvLyROT04tTkxTLTEkCiAgICB9CgogICAgLyoqCiAgICAgKiBDb25zdHJ1Y3RzIGEgZG90IHNlcGFyYXRlZCBwYWNrYWdlIG5hbWUgZnJvbSBhIGdpdmVuIG5hbWVzcGFjZS4KICAgICAqIDxwPkUuZy4sIHRoZSBuYW1lc3BhY2Ug0mh0dHA6Ly93cy5leGFtcGxlLmNvbS/TIHdvdWxkIHJldHVybiB0aGUgSmF2YSBwYWNrYWdlIG5hbWUg0mNvbS5leGFtcGxlLndz0y48L3A+CiAgICAgKiA8cD5OLkIuIFRoaXMgbWV0aG9kIGRvZXMgbm90IHByZXNlcnZlICd3d3cnIGluIHRoZSByZXR1cm5lZCBwYWNrYWdlIG5hbWUgaWYgaXQgZXhpc3RzIGluIHRoZSBnaXZlbiBuYW1lc3BhY2UuPC9wPgogICAgICogQHBhcmFtIG5hbWVzcGFjZSB0aGUgZ2l2ZW4gbmFtZS4KICAgICAqIEByZXR1cm4gYSBwYWNrYWdlIG5hbWUuCiAgICAgKi8KICAgIHB1YmxpYyBzdGF0aWMgU3RyaW5nIGdldFBhY2thZ2VOYW1lRnJvbU5hbWVzcGFjZShTdHJpbmcgbmFtZXNwYWNlKSB7CiAgICAgICAgU3RyaW5nIHBhY2thZ2VOYW1lID0gIiI7IC8vJE5PTi1OTFMtMSQKICAgICAgICB0cnkgewogICAgICAgICAgICBMaXN0PFN0cmluZz4gcGFja2FnZU5hbWVFbGVtZW50cyA9IG5ldyBBcnJheUxpc3Q8U3RyaW5nPigpOwoKICAgICAgICAgICAgVVJMIG5hbWVzcGFjZVVSTCA9IG5ldyBVUkwobmFtZXNwYWNlKTsKCiAgICAgICAgICAgIC8vIFJlbW92ZSB3d3cgaWYgdGhlcmUKICAgICAgICAgICAgU3RyaW5nIGF1dGhvcml0eSA9IG5hbWVzcGFjZVVSTC5nZXRBdXRob3JpdHkoKTsKICAgICAgICAgICAgaWYgKGF1dGhvcml0eS5pbmRleE9mKCJ3d3ciKSAhPSAtMSkgeyAvLyROT04tTkxTLTEkCiAgICAgICAgICAgICAgICBhdXRob3JpdHkgPSBhdXRob3JpdHkuc3Vic3RyaW5nKGF1dGhvcml0eS5pbmRleE9mKCIuIikgKyAxLCBhdXRob3JpdHkubGVuZ3RoKCkpOyAvLyROT04tTkxTLTEkCiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIExpc3Q8U3RyaW5nPiBhdXRob3JpdHlFbGVtZW50cyA9IEFycmF5cy5hc0xpc3QoYXV0aG9yaXR5LnNwbGl0KCJcXC4iKSk7IC8vJE5PTi1OTFMtMSQKICAgICAgICAgICAgQ29sbGVjdGlvbnMucmV2ZXJzZShhdXRob3JpdHlFbGVtZW50cyk7CiAgICAgICAgICAgIHBhY2thZ2VOYW1lRWxlbWVudHMuYWRkQWxsKGF1dGhvcml0eUVsZW1lbnRzKTsKCiAgICAgICAgICAgIFN0cmluZyBwYXRoID0gbmFtZXNwYWNlVVJMLmdldFBhdGgoKTsKICAgICAgICAgICAgTGlzdDxTdHJpbmc+IHBhdGhFbGVtZW50cyA9IEFycmF5cy5hc0xpc3QocGF0aC5zcGxpdCgiWy9cXFxcXSIpKTsgLy8kTk9OLU5MUy0xJAogICAgICAgICAgICBwYWNrYWdlTmFtZUVsZW1lbnRzLmFkZEFsbChwYXRoRWxlbWVudHMpOwoKICAgICAgICAgICAgSXRlcmF0b3I8U3RyaW5nPiBwYWNrYWdlSXRlcmF0b3IgPSBwYWNrYWdlTmFtZUVsZW1lbnRzLml0ZXJhdG9yKCk7CiAgICAgICAgICAgIHdoaWxlIChwYWNrYWdlSXRlcmF0b3IuaGFzTmV4dCgpKSB7CiAgICAgICAgICAgICAgICBTdHJpbmcgZWxlbWVudCA9IHBhY2thZ2VJdGVyYXRvci5uZXh0KCk7CiAgICAgICAgICAgICAgICBpZiAoZWxlbWVudC50cmltKCkubGVuZ3RoKCkgPiAwKSB7CiAgICAgICAgICAgICAgICAgICAgcGFja2FnZU5hbWUgKz0gZWxlbWVudDsKICAgICAgICAgICAgICAgICAgICBpZiAocGFja2FnZUl0ZXJhdG9yLmhhc05leHQoKSkgewogICAgICAgICAgICAgICAgICAgICAgICBwYWNrYWdlTmFtZSArPSAiLiI7IC8vJE5PTi1OTFMtMSQKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICB9IGNhdGNoIChNYWxmb3JtZWRVUkxFeGNlcHRpb24gbXVybGUpIHsKICAgICAgICAgICAgSkFYV1NDb3JlUGx1Z2luLmxvZyhtdXJsZSk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBwYWNrYWdlTmFtZS50b0xvd2VyQ2FzZSgpOwogICAgfQp9Cg==