LyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogQ29weXJpZ2h0IChjKSAyMDA4IElPTkEgVGVjaG5vbG9naWVzIFBMQwogKiBBbGwgcmlnaHRzIHJlc2VydmVkLiBUaGlzIHByb2dyYW0gYW5kIHRoZSBhY2NvbXBhbnlpbmcgbWF0ZXJpYWxzCiAqIGFyZSBtYWRlIGF2YWlsYWJsZSB1bmRlciB0aGUgdGVybXMgb2YgdGhlIEVjbGlwc2UgUHVibGljIExpY2Vuc2UgdjEuMAogKiB3aGljaCBhY2NvbXBhbmllcyB0aGlzIGRpc3RyaWJ1dGlvbiwgYW5kIGlzIGF2YWlsYWJsZSBhdAogKiBodHRwOi8vd3d3LmVjbGlwc2Uub3JnL2xlZ2FsL2VwbC12MTAuaHRtbAogKgogKiBDb250cmlidXRvcnM6CiAqIElPTkEgVGVjaG5vbG9naWVzIFBMQyAtIGluaXRpYWwgQVBJIGFuZCBpbXBsZW1lbnRhdGlvbgogKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8KcGFja2FnZSBvcmcuZWNsaXBzZS5qc3Qud3MuamF4d3MuY29yZS51dGlsczsKCmltcG9ydCBqYXZhLmlvLkZpbGU7CmltcG9ydCBqYXZhLmlvLkZpbGVPdXRwdXRTdHJlYW07CmltcG9ydCBqYXZhLmlvLklPRXhjZXB0aW9uOwppbXBvcnQgamF2YS5pby5JbnB1dFN0cmVhbTsKaW1wb3J0IGphdmEuaW8uT3V0cHV0U3RyZWFtOwppbXBvcnQgamF2YS5uZXQuTWFsZm9ybWVkVVJMRXhjZXB0aW9uOwppbXBvcnQgamF2YS5uZXQuVVJJOwppbXBvcnQgamF2YS5uZXQuVVJJU3ludGF4RXhjZXB0aW9uOwppbXBvcnQgamF2YS5uZXQuVVJMOwppbXBvcnQgamF2YS5uZXQuVVJMQ29ubmVjdGlvbjsKaW1wb3J0IGphdmEudXRpbC5BcnJheUxpc3Q7CmltcG9ydCBqYXZhLnV0aWwuQXJyYXlzOwppbXBvcnQgamF2YS51dGlsLkNvbGxlY3Rpb25zOwppbXBvcnQgamF2YS51dGlsLkl0ZXJhdG9yOwppbXBvcnQgamF2YS51dGlsLkxpc3Q7CmltcG9ydCBqYXZhLnV0aWwuTWFwOwppbXBvcnQgamF2YS51dGlsLlNldDsKCmltcG9ydCBqYXZheC53c2RsLkRlZmluaXRpb247CmltcG9ydCBqYXZheC53c2RsLlBvcnQ7CmltcG9ydCBqYXZheC53c2RsLlNlcnZpY2U7CmltcG9ydCBqYXZheC53c2RsLldTRExFeGNlcHRpb247CmltcG9ydCBqYXZheC53c2RsLmV4dGVuc2lvbnMuRXh0ZW5zaWJpbGl0eUVsZW1lbnQ7CmltcG9ydCBqYXZheC53c2RsLmV4dGVuc2lvbnMuc29hcC5TT0FQQWRkcmVzczsKaW1wb3J0IGphdmF4LndzZGwuZXh0ZW5zaW9ucy5zb2FwMTIuU09BUDEyQWRkcmVzczsKaW1wb3J0IGphdmF4LndzZGwuZmFjdG9yeS5XU0RMRmFjdG9yeTsKaW1wb3J0IGphdmF4LndzZGwueG1sLldTRExSZWFkZXI7CmltcG9ydCBqYXZheC53c2RsLnhtbC5XU0RMV3JpdGVyOwoKaW1wb3J0IG9yZy5lY2xpcHNlLmNvcmUuZmlsZXN5c3RlbS5VUklVdGlsOwppbXBvcnQgb3JnLmVjbGlwc2UuY29yZS5yZXNvdXJjZXMuSUZpbGU7CmltcG9ydCBvcmcuZWNsaXBzZS5jb3JlLnJlc291cmNlcy5JRm9sZGVyOwppbXBvcnQgb3JnLmVjbGlwc2UuY29yZS5yZXNvdXJjZXMuSVByb2plY3Q7CmltcG9ydCBvcmcuZWNsaXBzZS5jb3JlLnJlc291cmNlcy5JUmVzb3VyY2U7CmltcG9ydCBvcmcuZWNsaXBzZS5jb3JlLnJlc291cmNlcy5SZXNvdXJjZXNQbHVnaW47CmltcG9ydCBvcmcuZWNsaXBzZS5jb3JlLnJ1bnRpbWUuQ29yZUV4Y2VwdGlvbjsKaW1wb3J0IG9yZy5lY2xpcHNlLmNvcmUucnVudGltZS5JUGF0aDsKaW1wb3J0IG9yZy5lY2xpcHNlLmNvcmUucnVudGltZS5OdWxsUHJvZ3Jlc3NNb25pdG9yOwppbXBvcnQgb3JnLmVjbGlwc2UuY29yZS5ydW50aW1lLlBhdGg7CmltcG9ydCBvcmcuZWNsaXBzZS5qc3Qud3MuaW50ZXJuYWwuY29tbW9uLkoyRUVVdGlsczsKaW1wb3J0IG9yZy5lY2xpcHNlLmpzdC53cy5pbnRlcm5hbC5qYXh3cy5jb3JlLkpBWFdTQ29yZVBsdWdpbjsKaW1wb3J0IG9yZy54bWwuc2F4LklucHV0U291cmNlOwoKLyoqCiAqIFdTREwgVXRpbGl0eSBjbGFzcy4KICogPHA+CiAqIDxzdHJvbmc+UHJvdmlzaW9uYWwgQVBJOjwvc3Ryb25nPiBUaGlzIGNsYXNzL2ludGVyZmFjZSBpcyBwYXJ0IG9mIGFuIGludGVyaW0gQVBJIHRoYXQgaXMgc3RpbGwgdW5kZXIKICogZGV2ZWxvcG1lbnQgYW5kIGV4cGVjdGVkIHRvIGNoYW5nZSBzaWduaWZpY2FudGx5IGJlZm9yZSByZWFjaGluZyBzdGFiaWxpdHkuIEl0IGlzIGJlaW5nIG1hZGUgYXZhaWxhYmxlIGF0CiAqIHRoaXMgZWFybHkgc3RhZ2UgdG8gc29saWNpdCBmZWVkYmFjayBmcm9tIHBpb25lZXJpbmcgYWRvcHRlcnMgb24gdGhlIHVuZGVyc3RhbmRpbmcgdGhhdCBhbnkgY29kZSB0aGF0IHVzZXMKICogdGhpcyBBUEkgd2lsbCBhbG1vc3QgY2VydGFpbmx5IGJlIGJyb2tlbiAocmVwZWF0ZWRseSkgYXMgdGhlIEFQSSBldm9sdmVzLgogKiA8L3A+CiAqLwpwdWJsaWMgZmluYWwgY2xhc3MgV1NETFV0aWxzIHsKICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIFN0cmluZyBXU0RMX0ZJTEVfTkFNRV9QQVRURVJOID0gIlthLXpBLVowLTlfXFwtXSsud3NkbCI7Ly8kTk9OLU5MUy0xJAogICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgU3RyaW5nIFdTRExfUVVFUlkgPSAiP3dzZGwiOyAvLyROT04tTkxTLTEkCgoJcHJpdmF0ZSBzdGF0aWMgZmluYWwgSVBhdGggV1NETF9GT0xERVJfUEFUSCA9IG5ldyBQYXRoKCJ3c2RsLyIpOyAvLyROT04tTkxTLTEkCiAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBpbnQgVElNRU9VVCA9IDMwMDAwOwoKCXB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIFdTRExfRklMRV9FWFRFTlNJT04gPSAiLndzZGwiOyAvLyROT04tTkxTLTEkCgogICAgcHJpdmF0ZSBXU0RMVXRpbHMoKSB7CiAgICB9CgogICAgLyoqCiAgICAgKiBSZXR1cm5zIGEgPGNvZGU+amF2YXgud3NkbC5EZWZpbml0aW9uPC9jb2RlPiBieSByZWFkaW5nIHRoZSBXU0RMIGRvY3VtZW50IGF0IHRoZSBnaXZlbiBVUkwgb3IgbnVsbCBpZiBub25lIGNhbiBiZSBmb3VuZAogICAgICogb3IgaWYgdGhlIGNvbm5lY3Rpb24gdGltZXMgb3V0LgogICAgICogQHBhcmFtIHdzZGxVUkwgdGhlIHVybCBvZiB0aGUgd3NkbCBkb2N1bWVudCB0byByZWFkLgogICAgICogQHJldHVybiB0aGUgZGVmaW5pdGlvbiBkZXNjcmliZWQgaW4gdGhlIHdzZGwgZG9jdW1lbnQgcG9pbnRlZCB0byBieSB0aGUgZ2l2ZW4gVVJMLgogICAgICogQHRocm93cyBJT0V4Y2VwdGlvbiBpZiBhbiBJL08gZXhjZXB0aW9uIG9jY3Vycy4KICAgICAqLwogICAgcHVibGljIHN0YXRpYyBEZWZpbml0aW9uIHJlYWRXU0RMKFVSTCB3c2RsVVJMKSB0aHJvd3MgSU9FeGNlcHRpb24gewogICAgCVVSTENvbm5lY3Rpb24gdXJsQ29ubmVjdGlvbiA9IHdzZGxVUkwub3BlbkNvbm5lY3Rpb24oKTsKICAgIAl1cmxDb25uZWN0aW9uLnNldENvbm5lY3RUaW1lb3V0KFRJTUVPVVQpOwogICAgCXVybENvbm5lY3Rpb24uc2V0UmVhZFRpbWVvdXQoVElNRU9VVCk7CiAgICAJSW5wdXRTdHJlYW0gaW5wdXRTdHJlYW0gPSBudWxsOwogICAgICAgIHRyeSB7CiAgICAgICAgICAgIGlucHV0U3RyZWFtID0gdXJsQ29ubmVjdGlvbi5nZXRJbnB1dFN0cmVhbSgpOwogICAgICAgICAgICBJbnB1dFNvdXJjZSBpbnB1dFNvdXJjZSA9IG5ldyBJbnB1dFNvdXJjZShpbnB1dFN0cmVhbSk7CiAgICAgICAgICAgIFdTRExGYWN0b3J5IHdzZGxGYWN0b3J5ID0gV1NETEZhY3RvcnkubmV3SW5zdGFuY2UoKTsKICAgICAgICAgICAgV1NETFJlYWRlciB3c2RsUmVhZGVyID0gd3NkbEZhY3RvcnkubmV3V1NETFJlYWRlcigpOwogICAgICAgICAgICBEZWZpbml0aW9uIGRlZmluaXRpb24gPSB3c2RsUmVhZGVyLnJlYWRXU0RMKHdzZGxVUkwuZ2V0UGF0aCgpLCBpbnB1dFNvdXJjZSk7CiAgICAgICAgICAgIHJldHVybiBkZWZpbml0aW9uOwogICAgICAgIH0gY2F0Y2ggKFdTRExFeGNlcHRpb24gd3NkbGUpIHsKICAgICAgICAgICAgSkFYV1NDb3JlUGx1Z2luLmxvZyh3c2RsZSk7CiAgICAgICAgfSBmaW5hbGx5IHsKICAgICAgICAgICAgaWYgKGlucHV0U3RyZWFtICE9IG51bGwpIHsKICAgICAgICAgICAgICAgIGlucHV0U3RyZWFtLmNsb3NlKCk7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgcmV0dXJuIG51bGw7CiAgICB9CgogICAgLyoqCiAgICAgKiBXcml0ZXMgdGhlIGdpdmVuIDxjb2RlPmphdmF4LndzZGwuRGVmaW5pdGlvbjwvY29kZT4gdG8gdGhlIHdzZGwgZG9jdW1lbnQgYXQgdGhlIGdpdmVuIFVSTC4KICAgICAqIEBwYXJhbSB3c2RsVVJMIHRoZSB1cmwgb2YgdGhlIHdzZGwgZG9jdW1lbnQgdG8gd3JpdGUgdG8uCiAgICAgKiBAcGFyYW0gZGVmaW5pdGlvbiB0aGUgV1NETCBkZWZpbml0aW9uIHRvIGJlIHdyaXR0ZW4uCiAgICAgKiBAdGhyb3dzIElPRXhjZXB0aW9uICBpZiBhbiBJL08gZXhjZXB0aW9uIG9jY3Vycy4KICAgICAqIEB0aHJvd3MgQ29yZUV4Y2VwdGlvbiBpZiBhbiBleGNlcHRpb24gb2NjdXJzIHJlZnJlc2hpbmcgdGhlIGZpbGUgaW4gdGhlIHdvcmtzcGFjZSBpZiBpdCBleGlzdHMuCiAgICAgKi8KICAgIHB1YmxpYyBzdGF0aWMgdm9pZCB3cml0ZVdTREwoVVJMIHdzZGxVUkwsIERlZmluaXRpb24gZGVmaW5pdGlvbikgdGhyb3dzIElPRXhjZXB0aW9uLCBDb3JlRXhjZXB0aW9uIHsKICAgIAlVUkkgd3NkbFVSSSA9IG51bGw7CiAgICAgICAgT3V0cHV0U3RyZWFtIHdzZGxPdXRwdXRTdHJlYW0gPSBudWxsOwogICAgICAgIHRyeSB7CiAgICAgICAgCXdzZGxVUkkgPSB3c2RsVVJMLnRvVVJJKCk7CiAgICAgICAgICAgIEZpbGUgd3NkbEZpbGUgPSBuZXcgRmlsZSh3c2RsVVJJKTsKICAgICAgICAgICAgd3NkbE91dHB1dFN0cmVhbSA9IG5ldyBGaWxlT3V0cHV0U3RyZWFtKHdzZGxGaWxlKTsKICAgICAgICAgICAgV1NETEZhY3Rvcnkgd3NkbEZhY3RvcnkgPSBXU0RMRmFjdG9yeS5uZXdJbnN0YW5jZSgpOwogICAgICAgICAgICBXU0RMV3JpdGVyIHdzZGxXcml0ZXIgPSB3c2RsRmFjdG9yeS5uZXdXU0RMV3JpdGVyKCk7CiAgICAgICAgICAgIHdzZGxXcml0ZXIud3JpdGVXU0RMKGRlZmluaXRpb24sIHdzZGxPdXRwdXRTdHJlYW0pOwogICAgICAgIH0gY2F0Y2ggKFdTRExFeGNlcHRpb24gd3NkbGUpIHsKICAgICAgICAJSkFYV1NDb3JlUGx1Z2luLmxvZyh3c2RsZSk7CiAgICAgICAgfSBjYXRjaCAoVVJJU3ludGF4RXhjZXB0aW9uIHVyaXNlKSB7CiAgICAgICAgCUpBWFdTQ29yZVBsdWdpbi5sb2codXJpc2UpOwogICAgICAgIH0gZmluYWxseSB7CiAgICAgICAgICAgIGlmICh3c2RsT3V0cHV0U3RyZWFtICE9IG51bGwpIHsKICAgICAgICAgICAgICAgIHdzZGxPdXRwdXRTdHJlYW0uY2xvc2UoKTsKICAgICAgICAgICAgICAgIElGaWxlIGZpbGUgPSBSZXNvdXJjZXNQbHVnaW4uZ2V0V29ya3NwYWNlKCkuZ2V0Um9vdCgpCgkJCQkJCS5nZXRGaWxlRm9yTG9jYXRpb24oVVJJVXRpbC50b1BhdGgod3NkbFVSSSkpOwogICAgICAgICAgICAgICAgaWYgKGZpbGUgIT0gbnVsbCAmJiBmaWxlLmV4aXN0cygpKSB7CiAgICAgICAgICAgICAgICAJZmlsZS5yZWZyZXNoTG9jYWwoSVJlc291cmNlLkRFUFRIX09ORSwgbmV3IE51bGxQcm9ncmVzc01vbml0b3IoKSk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICB9CgogICAgLyoqCiAgICAgKiBSZXR1cm5zIDxjb2RlPnRydWU8L2NvZGU+IGlmIHRoZSBnaXZlbiBmaWxlIG5hbWUgY29udGFpbnMgQWxwaGFudW1lcmljIGNoYXJhY3RlcnMsIHVuZGVyc2NvcmUgJ18nLAogICAgICogZGFzaGVzICctJyBhbmQgZW5kcyB3aXRoIHRoZSAnLndzZGwnIGV4dGVuc2lvbi4gT3RoZXJ3aXNlIHJldHVybnMgPGNvZGU+ZmFsc2U8L2NvZGU+LgogICAgICogQHBhcmFtIHdzZGxGaWxlTmFtZSB0aGUgd3NkbCBmaWxlIG5hbWUKICAgICAqIEByZXR1cm4gPGNvZGU+dHJ1ZTwvY29kZT4gaWYgdmFsaWQsIGNvZGU+ZmFsc2U8L2NvZGU+IG90aGVyd2lzZS4KICAgICAqLwogICAgcHVibGljIHN0YXRpYyBib29sZWFuIGlzVmFsaWRXU0RMRmlsZU5hbWUoU3RyaW5nIHdzZGxGaWxlTmFtZSkgewogICAgICAgIHJldHVybiB3c2RsRmlsZU5hbWUgIT0gbnVsbCAmJiB3c2RsRmlsZU5hbWUubWF0Y2hlcyhXU0RMX0ZJTEVfTkFNRV9QQVRURVJOKTsKICAgIH0KCiAgICBwcml2YXRlIHN0YXRpYyBJUHJvamVjdCBnZXRQcm9qZWN0KFN0cmluZyBwcm9qZWN0TmFtZSkgewogICAgICAgIHJldHVybiBSZXNvdXJjZXNQbHVnaW4uZ2V0V29ya3NwYWNlKCkuZ2V0Um9vdCgpLmdldFByb2plY3QocHJvamVjdE5hbWUpOwogICAgfQoKICAgIC8qKgogICAgICogUmV0dXJucyB0aGUgV2ViIENvbnRlbnQgZm9sZGVyIG9mIHRoZSBnaXZlbiBwcm9qZWN0LiBUaGUgcmV0dXJuZWQgcmVzb3VyY2UgbWF5IG5vdCBleGlzdC4KICAgICAqIEBwYXJhbSBwcm9qZWN0IHRoZSBuYW1lIG9mIHRoZSB3ZWIgcHJvamVjdAogICAgICogQHJldHVybiB0aGUgd2ViIGNvbnRlbnQgZm9sZGVyCiAgICAgKi8KICAgIHB1YmxpYyBzdGF0aWMgSUZvbGRlciBnZXRXZWJDb250ZW50Rm9sZGVyKElQcm9qZWN0IHByb2plY3QpIHsKCQlyZXR1cm4gUmVzb3VyY2VzUGx1Z2luLmdldFdvcmtzcGFjZSgpLmdldFJvb3QoKS5nZXRGb2xkZXIoCgkJCQlXU0RMVXRpbHMuZ2V0V2ViQ29udGVudFBhdGgocHJvamVjdCkpOwoJfQoKICAgIC8qKgogICAgICogUmV0dXJucyB0aGUgV1NETCBmb2xkZXIgb2YgdGhlIHByb2plY3Qgd2l0aCB0aGUgZ2l2ZW4gbmFtZS4gVGhlIFdTREwgZm9sZGVyIHBhdGggaXMgdGhlIHByb2plY3RzIHdlYiBjb250ZW50IGZvbGRlcgogICAgICogcGF0aCBhcHBlbmRlZCB3aXRoIHRoZSAnV1NETCcgZGlyZWN0b3J5LiBUaGUgcmV0dXJuZWQgcmVzb3VyY2UgbWF5IG5vdCBleGlzdC4KICAgICAqIEBwYXJhbSBwcm9qZWN0TmFtZSB0aGUgbmFtZSBvZiB0aGUgd2ViIHByb2plY3QKICAgICAqIEByZXR1cm4gdGhlIHdzZGwgZm9sZGVyCiAgICAgKi8KICAgIHB1YmxpYyBzdGF0aWMgSUZvbGRlciBnZXRXU0RMRm9sZGVyKFN0cmluZyBwcm9qZWN0TmFtZSkgewogICAgICAgIHJldHVybiBXU0RMVXRpbHMuZ2V0V1NETEZvbGRlcihXU0RMVXRpbHMuZ2V0UHJvamVjdChwcm9qZWN0TmFtZSkpOwogICAgfQoKICAgIC8qKgogICAgICogUmV0dXJucyB0aGUgV1NETCBmb2xkZXIgb2YgdGhlIGdpdmVuIHByb2plY3QuIFRoZSBXU0RMIGZvbGRlciBwYXRoIGlzIHRoZSBwcm9qZWN0cyB3ZWIgY29udGVudCBmb2xkZXIKICAgICAqIHBhdGggYXBwZW5kZWQgd2l0aCB0aGUgJ1dTREwnIGRpcmVjdG9yeS4gVGhlIHJldHVybmVkIHJlc291cmNlIG1heSBub3QgZXhpc3QuCiAgICAgKiBAcGFyYW0gcHJvamVjdE5hbWUgdGhlIG5hbWUgb2YgdGhlIHdlYiBwcm9qZWN0CiAgICAgKiBAcmV0dXJuIHRoZSB3c2RsIGZvbGRlcgogICAgICovCiAgICBwdWJsaWMgc3RhdGljIElGb2xkZXIgZ2V0V1NETEZvbGRlcihJUHJvamVjdCBwcm9qZWN0KSB7CiAgICAgICAgSVBhdGggd3NkbEZvbGRlclBhdGggPSBXU0RMVXRpbHMuZ2V0V2ViQ29udGVudFBhdGgocHJvamVjdCkuYXBwZW5kKFdTRExVdGlscy5XU0RMX0ZPTERFUl9QQVRIKTsKICAgICAgICBJRm9sZGVyIHdzZGxGb2xkZXIgPSBSZXNvdXJjZXNQbHVnaW4uZ2V0V29ya3NwYWNlKCkuZ2V0Um9vdCgpLmdldEZvbGRlcih3c2RsRm9sZGVyUGF0aCk7CiAgICAgICAgaWYgKCF3c2RsRm9sZGVyLmV4aXN0cygpKSB7CiAgICAgICAgICAgIHRyeSB7CiAgICAgICAgICAgICAgICB3c2RsRm9sZGVyLmNyZWF0ZSh0cnVlLCB0cnVlLCBuZXcgTnVsbFByb2dyZXNzTW9uaXRvcigpKTsKICAgICAgICAgICAgfSBjYXRjaCAoQ29yZUV4Y2VwdGlvbiBjZSkgewogICAgICAgICAgICAgICAgSkFYV1NDb3JlUGx1Z2luLmxvZyhjZS5nZXRTdGF0dXMoKSk7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgcmV0dXJuIHdzZGxGb2xkZXI7CiAgICB9CgogICAgcHJpdmF0ZSBzdGF0aWMgSVBhdGggZ2V0V2ViQ29udGVudFBhdGgoSVByb2plY3QgcHJvamVjdCkgewogICAgICAgIHJldHVybiBKMkVFVXRpbHMuZ2V0V2ViQ29udGVudFBhdGgocHJvamVjdCkuYWRkVHJhaWxpbmdTZXBhcmF0b3IoKTsKICAgIH0KCiAgICAvKioKICAgICAqIFJldHVybnMgdGhlIGZpcnN0IDxjb2RlPlNPQVBBZGRyZXNzPC9jb2RlPiBvciA8Y29kZT5TT0FQMTJBZGRyZXNzPC9jb2RlPiBmb3VuZCBpbiB0aGUgZ2l2ZW4KICAgICAqIDxjb2RlPkRlZmluaXRpb248L2NvZGU+IG9yIG51bGwgaWYgbm9uZSBpcyBmb3VuZC4KICAgICAqIEBwYXJhbSBkZWZpbml0aW9uIHRoZSBnaXZlbiBkZWZpbml0aW9uLgogICAgICogQHJldHVybiByZXR1cm4gb25lIG9mOgogICAgICogPGxpPlNPQVBBZGRyZXNzPGxpPlNPQVAxMkFkZHJlc3M8bGk+bnVsbCBpZiBpdCBjYW4gbm90IGZpbmQgYSBzb2FwIGFkZHJlc3MKICAgICAqLwogICAgQFN1cHByZXNzV2FybmluZ3MoInVuY2hlY2tlZCIpCiAgICBwdWJsaWMgc3RhdGljIEV4dGVuc2liaWxpdHlFbGVtZW50IGdldEVuZHBvaW50QWRkcmVzcyhEZWZpbml0aW9uIGRlZmluaXRpb24pIHsKICAgICAgICBpZiAoZGVmaW5pdGlvbiAhPSBudWxsKSB7CiAgICAgICAgICAgIE1hcCBzZXJ2aWNlc01hcCA9IGRlZmluaXRpb24uZ2V0U2VydmljZXMoKTsKICAgICAgICAgICAgU2V0PE1hcC5FbnRyeT4gc2VydmljZXNTZXQgPSBzZXJ2aWNlc01hcC5lbnRyeVNldCgpOwogICAgICAgICAgICBmb3IgKE1hcC5FbnRyeSBzZXJ2aWNlRW50cnkgOiBzZXJ2aWNlc1NldCkgewogICAgICAgICAgICAgICAgU2VydmljZSBzZXJ2aWNlID0gKFNlcnZpY2UpIHNlcnZpY2VFbnRyeS5nZXRWYWx1ZSgpOwogICAgICAgICAgICAgICAgTWFwIHBvcnRzTWFwID0gc2VydmljZS5nZXRQb3J0cygpOwogICAgICAgICAgICAgICAgU2V0PE1hcC5FbnRyeT4gcG9ydHNTZXQgPSBwb3J0c01hcC5lbnRyeVNldCgpOwogICAgICAgICAgICAgICAgZm9yIChNYXAuRW50cnkgcG9ydEVudHJ5IDogcG9ydHNTZXQpIHsKICAgICAgICAgICAgICAgICAgICBQb3J0IHBvcnQgPSAoUG9ydCkgcG9ydEVudHJ5LmdldFZhbHVlKCk7CiAgICAgICAgICAgICAgICAgICAgTGlzdCBleHRlbnNpYmlsaXR5RWxlbWVudHMgPSBwb3J0LmdldEV4dGVuc2liaWxpdHlFbGVtZW50cygpOwogICAgICAgICAgICAgICAgICAgIGZvciAoT2JqZWN0IG9iamVjdCA6IGV4dGVuc2liaWxpdHlFbGVtZW50cykgewogICAgICAgICAgICAgICAgICAgICAgICBpZiAob2JqZWN0IGluc3RhbmNlb2YgU09BUEFkZHJlc3MgfHwgb2JqZWN0IGluc3RhbmNlb2YgU09BUDEyQWRkcmVzcykgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIChFeHRlbnNpYmlsaXR5RWxlbWVudCkgb2JqZWN0OwogICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgIH0KICAgICAgICByZXR1cm4gbnVsbDsKICAgIH0KCiAgICAvKioKICAgICAqIFJldHVybnMgdGhlIGxvY2F0aW9uIFVSSSBmcm9tIHRoZSBmaXJzdCA8Y29kZT5TT0FQQWRkcmVzczwvY29kZT4gb3IgPGNvZGU+U09BUDEyQWRkcmVzczwvY29kZT4gZm91bmQKICAgICAqIGluIHRoZSBnaXZlbiA8Y29kZT5EZWZpbml0aW9uPC9jb2RlPiBvciBudWxsIGlmIG5vbmUgaXMgZm91bmQuIFRoZSByZXR1cm5lZCBsb2NhdGlvbiBVUkkgaXMgYXBwZW5kZWQgd2l0aAogICAgICogdGhlICc/d3NkbCcgcXVlcnkgaWYgdGhlIHF1ZXJ5IHdhcyBub3QgcHJlc2VudCBpbiB0aGUgPGNvZGU+U09BUEFkZHJlc3M8L2NvZGU+IG9yIDxjb2RlPlNPQVAxMkFkZHJlc3M8L2NvZGU+IGxvY2F0aW9uIFVSSS4KICAgICAqIEBwYXJhbSBkZWZpbml0aW9uIHRoZSBnaXZlbiBkZWZpbnRpb24uCiAgICAgKiBAcmV0dXJuIHRoZSBsb2NhdGlvbiBVUkkgb3IgdGhlIGZpcnN0IDxjb2RlPlNPQVBBZGRyZXNzPC9jb2RlPiBvciA8Y29kZT5TT0FQMTJBZGRyZXNzPC9jb2RlPiBmb3VuZCBpbiB0aGUgZ2l2ZW4gZGVmaW5pdGlvbi4KICAgICAqIEB0aHJvd3MgTWFsZm9ybWVkVVJMRXhjZXB0aW9uIGlmIGFuIGVycm9yIG9jY3VycyB0ZXN0aW5nIHRoZSBsb2NhdGlvbiBVUkkgZm9yIGEgcXVlcnkgcGFydC4KICAgICAqLwogICAgcHVibGljIHN0YXRpYyBTdHJpbmcgZ2V0V1NETExvY2F0aW9uKERlZmluaXRpb24gZGVmaW5pdGlvbikgdGhyb3dzIE1hbGZvcm1lZFVSTEV4Y2VwdGlvbiB7CgkJRXh0ZW5zaWJpbGl0eUVsZW1lbnQgZXh0ZW5zaWJpbGl0eUVsZW1lbnQgPSBXU0RMVXRpbHMuZ2V0RW5kcG9pbnRBZGRyZXNzKGRlZmluaXRpb24pOwoJCWlmIChleHRlbnNpYmlsaXR5RWxlbWVudCAhPSBudWxsKSB7CgkgICAgICAgIFN0cmluZyBsb2NhdGlvblVSSSA9IGdldExvY2F0aW9uVVJJKGV4dGVuc2liaWxpdHlFbGVtZW50KTsKCSAgICAgICAgaWYgKGxvY2F0aW9uVVJJLmxlbmd0aCgpID4gMCkgewoJICAgICAgICAgICAgVVJMIGVuZHBvaW50VVJMID0gbmV3IFVSTChsb2NhdGlvblVSSSk7CgkgICAgICAgICAgICBpZiAoZW5kcG9pbnRVUkwuZ2V0UXVlcnkoKSA9PSBudWxsKSB7CgkgICAgICAgICAgICAgICAgbG9jYXRpb25VUkkgKz0gV1NETF9RVUVSWTsKCSAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIHJldHVybiBsb2NhdGlvblVSSTsKCSAgICAgICAgfQoJCX0KCSAgICByZXR1cm4gbnVsbDsKICAgIH0KCiAgICBwcml2YXRlIHN0YXRpYyBTdHJpbmcgZ2V0TG9jYXRpb25VUkkoRXh0ZW5zaWJpbGl0eUVsZW1lbnQgZXh0ZW5zaWJpbGl0eUVsZW1lbnQpIHsKCSAgICBpZiAoZXh0ZW5zaWJpbGl0eUVsZW1lbnQgaW5zdGFuY2VvZiBTT0FQQWRkcmVzcykgewogICAgICAgICAgICByZXR1cm4gKChTT0FQQWRkcmVzcykgZXh0ZW5zaWJpbGl0eUVsZW1lbnQpLmdldExvY2F0aW9uVVJJKCk7CiAgICAgICAgfQogICAgICAgIGlmIChleHRlbnNpYmlsaXR5RWxlbWVudCBpbnN0YW5jZW9mIFNPQVAxMkFkZHJlc3MpIHsKICAgICAgICAgICAgcmV0dXJuICgoU09BUDEyQWRkcmVzcykgZXh0ZW5zaWJpbGl0eUVsZW1lbnQpLmdldExvY2F0aW9uVVJJKCk7CiAgICAgICAgfQoJCXJldHVybiAiIjsgLy8kTk9OLU5MUy0xJAogICAgfQoKICAgIC8qKgogICAgICogQ29uc3RydWN0cyBhIGRvdCBzZXBhcmF0ZWQgcGFja2FnZSBuYW1lIGZyb20gYSBnaXZlbiBuYW1lc3BhY2UuCiAgICAgKiA8cD5FLmcuLCB0aGUgbmFtZXNwYWNlINJodHRwOi8vd3MuZXhhbXBsZS5jb20v0yB3b3VsZCByZXR1cm4gdGhlIEphdmEgcGFja2FnZSBuYW1lINJjb20uZXhhbXBsZS53c9MuPC9wPgogICAgICogPHA+Ti5CLiBUaGlzIG1ldGhvZCBkb2VzIG5vdCBwcmVzZXJ2ZSAnd3d3JyBpbiB0aGUgcmV0dXJuZWQgcGFja2FnZSBuYW1lIGlmIGl0IGV4aXN0cyBpbiB0aGUgZ2l2ZW4gbmFtZXNwYWNlLjwvcD4KICAgICAqIEBwYXJhbSBuYW1lc3BhY2UgdGhlIGdpdmVuIG5hbWUuCiAgICAgKiBAcmV0dXJuIGEgcGFja2FnZSBuYW1lLgogICAgICovCiAgICBwdWJsaWMgc3RhdGljIFN0cmluZyBnZXRQYWNrYWdlTmFtZUZyb21OYW1lc3BhY2UoU3RyaW5nIG5hbWVzcGFjZSkgewogICAgICAgIFN0cmluZyBwYWNrYWdlTmFtZSA9ICIiOyAvLyROT04tTkxTLTEkCiAgICAgICAgdHJ5IHsKICAgICAgICAgICAgTGlzdDxTdHJpbmc+IHBhY2thZ2VOYW1lRWxlbWVudHMgPSBuZXcgQXJyYXlMaXN0PFN0cmluZz4oKTsKCiAgICAgICAgICAgIFVSTCBuYW1lc3BhY2VVUkwgPSBuZXcgVVJMKG5hbWVzcGFjZSk7CgogICAgICAgICAgICAvLyBSZW1vdmUgd3d3IGlmIHRoZXJlCiAgICAgICAgICAgIFN0cmluZyBhdXRob3JpdHkgPSBuYW1lc3BhY2VVUkwuZ2V0QXV0aG9yaXR5KCk7CiAgICAgICAgICAgIGlmIChhdXRob3JpdHkuaW5kZXhPZigid3d3IikgIT0gLTEpIHsgLy8kTk9OLU5MUy0xJAogICAgICAgICAgICAgICAgYXV0aG9yaXR5ID0gYXV0aG9yaXR5LnN1YnN0cmluZyhhdXRob3JpdHkuaW5kZXhPZigiLiIpICsgMSwgYXV0aG9yaXR5Lmxlbmd0aCgpKTsgLy8kTk9OLU5MUy0xJAogICAgICAgICAgICB9CgogICAgICAgICAgICBMaXN0PFN0cmluZz4gYXV0aG9yaXR5RWxlbWVudHMgPSBBcnJheXMuYXNMaXN0KGF1dGhvcml0eS5zcGxpdCgiXFwuIikpOyAvLyROT04tTkxTLTEkCiAgICAgICAgICAgIENvbGxlY3Rpb25zLnJldmVyc2UoYXV0aG9yaXR5RWxlbWVudHMpOwogICAgICAgICAgICBwYWNrYWdlTmFtZUVsZW1lbnRzLmFkZEFsbChhdXRob3JpdHlFbGVtZW50cyk7CgogICAgICAgICAgICBTdHJpbmcgcGF0aCA9IG5hbWVzcGFjZVVSTC5nZXRQYXRoKCk7CiAgICAgICAgICAgIExpc3Q8U3RyaW5nPiBwYXRoRWxlbWVudHMgPSBBcnJheXMuYXNMaXN0KHBhdGguc3BsaXQoIlsvXFxcXF0iKSk7IC8vJE5PTi1OTFMtMSQKICAgICAgICAgICAgcGFja2FnZU5hbWVFbGVtZW50cy5hZGRBbGwocGF0aEVsZW1lbnRzKTsKCiAgICAgICAgICAgIEl0ZXJhdG9yPFN0cmluZz4gcGFja2FnZUl0ZXJhdG9yID0gcGFja2FnZU5hbWVFbGVtZW50cy5pdGVyYXRvcigpOwogICAgICAgICAgICB3aGlsZSAocGFja2FnZUl0ZXJhdG9yLmhhc05leHQoKSkgewogICAgICAgICAgICAgICAgU3RyaW5nIGVsZW1lbnQgPSBwYWNrYWdlSXRlcmF0b3IubmV4dCgpOwogICAgICAgICAgICAgICAgaWYgKGVsZW1lbnQudHJpbSgpLmxlbmd0aCgpID4gMCkgewogICAgICAgICAgICAgICAgICAgIHBhY2thZ2VOYW1lICs9IGVsZW1lbnQ7CiAgICAgICAgICAgICAgICAgICAgaWYgKHBhY2thZ2VJdGVyYXRvci5oYXNOZXh0KCkpIHsKICAgICAgICAgICAgICAgICAgICAgICAgcGFja2FnZU5hbWUgKz0gIi4iOyAvLyROT04tTkxTLTEkCiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgfSBjYXRjaCAoTWFsZm9ybWVkVVJMRXhjZXB0aW9uIG11cmxlKSB7CiAgICAgICAgICAgIEpBWFdTQ29yZVBsdWdpbi5sb2cobXVybGUpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gcGFja2FnZU5hbWUudG9Mb3dlckNhc2UoKTsKICAgIH0KfQo=