LyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogQ29weXJpZ2h0IChjKSAyMDEyIEp1ZXJnZW4gSGF1ZwogKiBBbGwgcmlnaHRzIHJlc2VydmVkLiBUaGlzIHByb2dyYW0gYW5kIHRoZSBhY2NvbXBhbnlpbmcgbWF0ZXJpYWxzCiAqIGFyZSBtYWRlIGF2YWlsYWJsZSB1bmRlciB0aGUgdGVybXMgb2YgdGhlIEVjbGlwc2UgUHVibGljIExpY2Vuc2UgMi4wCiAqIHdoaWNoIGFjY29tcGFuaWVzIHRoaXMgZGlzdHJpYnV0aW9uLCBhbmQgaXMgYXZhaWxhYmxlIGF0CiAqIGh0dHBzOi8vd3d3LmVjbGlwc2Uub3JnL2xlZ2FsL2VwbC0yLjAvCiAqCiAqIFNQRFgtTGljZW5zZS1JZGVudGlmaWVyOiBFUEwtMi4wCiAqIAogKiBDT05UUklCVVRPUlM6CiAqIAkJSnVlcmdlbiBIYXVnCiAqIAkJUGV0ZXIgS2FybGl0c2NoZWsKICogCiAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwoKcGFja2FnZSBvcmcuZWNsaXBzZS5ldHJpY2UuZ2VuZXJhdG9yLmNwcC5nZW4KCmltcG9ydCBjb20uZ29vZ2xlLmluamVjdC5JbmplY3QKaW1wb3J0IGphdmEudXRpbC5BcnJheUxpc3QKaW1wb3J0IGphdmEudXRpbC5MaXN0CmltcG9ydCBvcmcuZWNsaXBzZS5ldHJpY2UuY29yZS5nZW5tb2RlbC5ldHJpY2VnZW4uQWN0b3JJbnN0YW5jZQppbXBvcnQgb3JnLmVjbGlwc2UuZXRyaWNlLmNvcmUuZ2VubW9kZWwuZXRyaWNlZ2VuLkluc3RhbmNlQmFzZQppbXBvcnQgb3JnLmVjbGlwc2UuZXRyaWNlLmNvcmUucm9vbS5BY3RvckNsYXNzCmltcG9ydCBvcmcuZWNsaXBzZS5ldHJpY2UuY29yZS5yb29tLkF0dHJpYnV0ZQppbXBvcnQgb3JnLmVjbGlwc2UuZXRyaWNlLmNvcmUucm9vbS5EYXRhQ2xhc3MKaW1wb3J0IG9yZy5lY2xpcHNlLmV0cmljZS5jb3JlLnJvb20uRW51bWVyYXRpb25UeXBlCmltcG9ydCBvcmcuZWNsaXBzZS5ldHJpY2UuY29yZS5yb29tLkV4dGVybmFsVHlwZQppbXBvcnQgb3JnLmVjbGlwc2UuZXRyaWNlLmNvcmUucm9vbS5QcmltaXRpdmVUeXBlCmltcG9ydCBvcmcuZWNsaXBzZS5ldHJpY2UuY29yZS5yb29tLnV0aWwuUm9vbUhlbHBlcnMKaW1wb3J0IG9yZy5lY2xpcHNlLmV0cmljZS5nZW5lcmF0b3IuYmFzZS5JRGF0YUNvbmZpZ3VyYXRpb24KaW1wb3J0IG9yZy5lY2xpcHNlLmV0cmljZS5nZW5lcmF0b3IuZ2VuZXJpYy5Qcm9jZWR1cmVIZWxwZXJzCmltcG9ydCBvcmcuZWNsaXBzZS5ldHJpY2UuZ2VuZXJhdG9yLmdlbmVyaWMuUm9vbUV4dGVuc2lvbnMKaW1wb3J0IG9yZy5lY2xpcHNlLmV0cmljZS5nZW5lcmF0b3IuZ2VuZXJpYy5UeXBlSGVscGVycwoKY2xhc3MgQ29uZmlnR2VuQWRkb24gewoJCglASW5qZWN0IGV4dGVuc2lvbiBDcHBFeHRlbnNpb25zIHN0ZEV4dAoJQEluamVjdCBleHRlbnNpb24gVHlwZUhlbHBlcnMgdHlwZUhlbHBlcnMKCUBJbmplY3QgZXh0ZW5zaW9uIFByb2NlZHVyZUhlbHBlcnMgaGVscGVycwoJQEluamVjdCBJRGF0YUNvbmZpZ3VyYXRpb24gZGF0YUNvbmZpZ0V4dAoJQEluamVjdCBleHRlbnNpb24gUm9vbUhlbHBlcnMKCUBJbmplY3QgZXh0ZW5zaW9uIFJvb21FeHRlbnNpb25zCgkKCS8vIEZvciBTdWJTeXN0ZW1DbGFzc0dlbgoJCglkZWYgZ2VuQWN0b3JJbnN0YW5jZUNvbmZpZyhBY3Rvckluc3RhbmNlIGFpLCBTdHJpbmcgYWlWYXJpYWJsZU5hbWUpeycnJwoJCQmrRk9SIGEgOiBhaS5hY3RvckNsYXNzLmFsbEF0dHJpYnV0ZXO7CgkJCQmrYXBwbHlJbnN0YW5jZUNvbmZpZyhhaSwgYWlWYXJpYWJsZU5hbWUsIG5ldyBBcnJheUxpc3Q8QXR0cmlidXRlPigpLnVuaW9uKGEpKbsKCQkJq0VOREZPUrsKCQkJq0ZPUiBwaSA6IGFpLm9yZGVyZWRJZkl0ZW1JbnN0YW5jZXO7CgkJCQmrdmFyIGF0dHJpYnMgPSBnZXRQb3J0Q2xhc3MocGkuaW50ZXJmYWNlSXRlbSk/LmF0dHJpYnV0ZXO7CgkJCQmrSUYgYXR0cmlicyAhPT0gbnVsbLsKCQkJCQmrRk9SIGEgOiBhdHRyaWJzuwoJCQkJCQmrYXBwbHlJbnN0YW5jZUNvbmZpZyhwaSwgYWlWYXJpYWJsZU5hbWUrIi4iK2ludm9rZUdldHRlcihwaS5uYW1lLCBudWxsKSwgbmV3IEFycmF5TGlzdDxBdHRyaWJ1dGU+KCkudW5pb24oYSkpuwoJCQkJCatFTkRGT1K7CgkJCQmrRU5ESUa7CgkJCatFTkRGT1K7CgkJJycnCgl9CgkKLy8JZGVmIHByaXZhdGUgTGlzdDxBdHRyaWJ1dGU+IGdldEF0dHJpYnV0ZXMoR2VuZXJhbFByb3RvY29sQ2xhc3MgZ3BjLCBib29sZWFuIHJlZ3VsYXIpewovLwkJdmFyIHJlc3VsdCA9IG5ldyBBcnJheUxpc3Q8QXR0cmlidXRlPgovLwkJaWYoZ3BjIGluc3RhbmNlb2YgUHJvdG9jb2xDbGFzcyl7Ci8vCQkJdmFyIHByb3RvY29sID0gZ3BjIGFzIFByb3RvY29sQ2xhc3MKLy8JCQlpZihyZWd1bGFyICYmIHByb3RvY29sLnJlZ3VsYXI/LmF0dHJpYnV0ZXMgIT0gbnVsbCkKLy8JCQkJcmVzdWx0LmFkZEFsbChwcm90b2NvbC5yZWd1bGFyLmF0dHJpYnV0ZXMpCi8vCQkJZWxzZSBpZighcmVndWxhciAmJiBwcm90b2NvbC5jb25qdWdhdGU/LmF0dHJpYnV0ZXMgIT0gbnVsbCkKLy8JCQkJcmVzdWx0LmFkZEFsbChwcm90b2NvbC5jb25qdWdhdGUuYXR0cmlidXRlcykKLy8JCX0KLy8JCXJldHVybiByZXN1bHQKLy8JfQoJCglkZWYgcHJpdmF0ZSBTdHJpbmcgYXBwbHlJbnN0YW5jZUNvbmZpZyhJbnN0YW5jZUJhc2UgaW5zdGFuY2UsIFN0cmluZyBpbnZva2VzLCBMaXN0PEF0dHJpYnV0ZT4gcGF0aCl7CgkJdmFyIGEgPSBwYXRoLmxhc3QKCQl2YXIgYVR5cGUgPSBhLnR5cGUudHlwZQoJCQoJCS8vIFRPRE8tRW51bQoJCWlmKGFUeXBlLnByaW1pdGl2ZSl7CgkJCXZhciB2YWx1ZSA9IHR5cGVIZWxwZXJzLmdldEF0dHJJbnN0YW5jZUNvbmZpZ1ZhbHVlKHBhdGgsIGluc3RhbmNlKQoJCQlpZih2YWx1ZSA9PT0gbnVsbCkKCQkJCScnJycnJwoJCQllbHNlIGlmKGEuc2l6ZSA9PSAwIHx8IGFUeXBlLmNoYXJhY3RlclR5cGUpCgkJCQknJyeraW52b2tlc7suq2EubmFtZS5pbnZva2VTZXR0ZXIobnVsbCwgKGFUeXBlIGFzIFByaW1pdGl2ZVR5cGUpLnRvVmFsdWVMaXRlcmFsKHZhbHVlKSm7OycnJwoJCQllbHNlIGlmKGEuc2l6ZSA9PSB2YWx1ZS5zcGxpdCgiLCIpLnNpemUpewoJCQkJdmFyIGFycmF5RXhwciA9ICcnJ3sgq0ZPUiBzIDogdmFsdWUuc3BsaXQoIiwiKSBTRVBBUkFUT1IgJywgJ7urKGFUeXBlIGFzIFByaW1pdGl2ZVR5cGUpLnRvVmFsdWVMaXRlcmFsKHMudHJpbSm7q0VOREZPUrsgfScnJwoJCQkJJycnq2ludm9rZXO7LqthLm5hbWUuaW52b2tlU2V0dGVyKG51bGwsICcnJ25ldyCrYVR5cGUudHlwZU5hbWW7W10gq2FycmF5RXhwcrsnJycudG9TdHJpbmcpuzsnJycKCQkJfSBlbHNlICcnJwoJCQkJCXsKCQkJCQkJq2FUeXBlLnR5cGVOYW1lu1tdIGFycmF5ID0gq2ludm9rZXO7LqthLm5hbWUuaW52b2tlR2V0dGVyKG51bGwpuzsKCQkJCQkJZm9yIChpbnQgaT0wO2k8q2Euc2l6Zbs7aSsrKXsKCQkJCQkJCWFycmF5W2ldID0gqyhhVHlwZSBhcyBQcmltaXRpdmVUeXBlKS50b1ZhbHVlTGl0ZXJhbCh2YWx1ZSm7OwoJCQkJCX0nJycKCQl9CgkJZWxzZSBpZiAoYVR5cGUuZGF0YUNsYXNzKScnJwoJCQkJq0ZPUiBlIDogKGFUeXBlIGFzIERhdGFDbGFzcykuYXR0cmlidXRlc7sKCQkJCQmrYXBwbHlJbnN0YW5jZUNvbmZpZyhpbnN0YW5jZSwgaW52b2tlcysiLiIrYS5uYW1lLmludm9rZUdldHRlcihudWxsKSwgcGF0aC51bmlvbihlKSm7CgkJCQmrRU5ERk9SuwoJCQknJycKCX0KCQoJLy8gRm9yIEFjdG9yQ2xhc3NHZW4KCQoJZGVmIGdlbkR5bkNvbmZpZ0dldHRlclNldHRlcihBY3RvckNsYXNzIGFjKXsnJycKCQmrRk9SIGEgOiBkYXRhQ29uZmlnRXh0LmdldER5bkNvbmZpZ1JlYWRBdHRyaWJ1dGVzKGFjKbsKCQkJcHVibGljIKthLnR5cGUudHlwZS50eXBlTmFtZburSUYgYS5zaXplPjC7W12rRU5ESUa7IGdldKthLm5hbWUudG9GaXJzdFVwcGVyuygpewoJCQkJaWYobG9ja1+rYS5uYW1luyA9PSBudWxsKQoJCQkJCXJldHVybiCrYS5uYW1luzsKCQkJCWVsc2UKCQkJCQlzeW5jaHJvbml6ZWQobG9ja1+rYS5uYW1luyl7CgkJCQkJCXJldHVybiCrYS5uYW1luzsKCQkJCQl9CgkJCX0KCQkJcHVibGljIHZvaWQgc2V0q2EubmFtZS50b0ZpcnN0VXBwZXK7KKthLnR5cGUudHlwZS50eXBlTmFtZburSUYgYS5zaXplPjC7W12rRU5ESUa7IKthLm5hbWW7KXsKCQkJCWlmKGxvY2tfq2EubmFtZbsgPT0gbnVsbCkKCQkJCQl0aGlzLqthLm5hbWW7ID0gq2EubmFtZbs7CgkJCQllbHNlCgkJCQkJc3luY2hyb25pemVkKGxvY2tfq2EubmFtZbspewoJCQkJCQl0aGlzLqthLm5hbWW7ID0gq2EubmFtZbs7CgkJCQkJfQoJCQl9CgkJCXB1YmxpYyBEeW5Db25maWdMb2NrIGdldKthLm5hbWUudG9GaXJzdFVwcGVyu0xvY2soKXsKCQkJCXJldHVybiBsb2NrX6thLm5hbWW7OwoJCQl9CQoJCatFTkRGT1K7CgkJq0ZPUiBhIDogZGF0YUNvbmZpZ0V4dC5nZXREeW5Db25maWdXcml0ZUF0dHJpYnV0ZXMoYWMpuwoJCQlwdWJsaWMgdm9pZCBzZXRBbmRXcml0ZathLm5hbWUudG9GaXJzdFVwcGVyuyirYS50eXBlLnR5cGUudHlwZU5hbWW7q0lGIGEuc2l6ZT4wu1tdq0VORElGuyCrYS5uYW1luyl7CgkJCQkJc2V0q2EubmFtZS50b0ZpcnN0VXBwZXK7KKthLm5hbWW7KTsKCQkJCQl2YXJpYWJsZVNlcnZpY2Uud3JpdGUodGhpcy5nZXRJbnN0YW5jZVBhdGgoKSsiL6thLm5hbWW7Iiwgq2EubmFtZbspOwoJCQl9CgkJq0VOREZPUrsKCScnJ30KCQoJZGVmIGdlbk1pbk1heENvbnN0YW50cyhBY3RvckNsYXNzIGFjKXsKCQl2YXIgcmVzdWx0ID0gJycnCgkJCatGT1IgYSA6IGFjLmF0dHJpYnV0ZXO7CgkJCQmrZ2VuTWluTWF4Q29uc3RhbnRzUmVjKGFjLCBhLm5hbWUsIG5ldyBBcnJheUxpc3Q8QXR0cmlidXRlPigpLnVuaW9uKGEpKbsKCQkJq0VOREZPUrsKCQknJycKCQlpZihyZXN1bHQubGVuZ3RoICE9IDApCgkJCXJlc3VsdCA9IHJlc3VsdCsnJycvLy0tLS0tLS0tLS0tLS0tLS0tLS0tLSBBdHRyaWJ1dGUgU3BlY2lmaWNhdGlvbnMnJycKCQlyZXR1cm4gcmVzdWx0Cgl9CgkKCWRlZiBwcml2YXRlIFN0cmluZyBnZW5NaW5NYXhDb25zdGFudHNSZWMoQWN0b3JDbGFzcyBhYywgU3RyaW5nIHZhck5hbWVQYXRoLCBMaXN0PEF0dHJpYnV0ZT4gcGF0aCl7CgkJdmFyIHRlbXAgPSBudWxsIGFzIFN0cmluZwoJCWlmIChwYXRoLmxhc3QudHlwZS50eXBlLmRhdGFDbGFzcykKCQkJJycnCgkJCQmrRk9SIGUgOiAocGF0aC5sYXN0LnR5cGUudHlwZSBhcyBEYXRhQ2xhc3MpLmFsbEF0dHJpYnV0ZXO7CgkJCQkJq2dlbk1pbk1heENvbnN0YW50c1JlYyhhYywgdmFyTmFtZVBhdGgrIl8iK2UubmFtZSwgcGF0aC51bmlvbihlKSm7CgkJCQmrRU5ERk9SuwoJCQknJycKCQllbHNlIGlmIChwYXRoLmxhc3QudHlwZS50eXBlIGluc3RhbmNlb2YgRXh0ZXJuYWxUeXBlKSB7CgkJCS8vIGRvIG5vdGhpbmcKCQl9CgkJZWxzZSBpZiAocGF0aC5sYXN0LnR5cGUudHlwZSBpbnN0YW5jZW9mIEVudW1lcmF0aW9uVHlwZSkgewoJCQkvLyBUT0RPLUVudW0KCQl9CgkJZWxzZQoJCXsKCQkJdmFyIGFUeXBlID0gKHBhdGgubGFzdC50eXBlLnR5cGUgYXMgUHJpbWl0aXZlVHlwZSkKCQkJJycnCgkJCQmrSUYgKHRlbXAgPSBkYXRhQ29uZmlnRXh0LmdldEF0dHJDbGFzc0NvbmZpZ01pblZhbHVlKGFjLCBwYXRoKSkgIT09IG51bGy7CgkJCQkJcHVibGljIHN0YXRpYyCrYVR5cGUubWluTWF4VHlwZbsgTUlOX6t2YXJOYW1lUGF0aLsgPSCrYVR5cGUudG9WYWx1ZUxpdGVyYWwodGVtcCm7OwoJCQkJq0VORElGuwoJCQkJq0lGICh0ZW1wID0gZGF0YUNvbmZpZ0V4dC5nZXRBdHRyQ2xhc3NDb25maWdNYXhWYWx1ZShhYywgcGF0aCkpICE9PSBudWxsuwoJCQkJCXB1YmxpYyBzdGF0aWMgq2FUeXBlLm1pbk1heFR5cGW7IE1BWF+rdmFyTmFtZVBhdGi7ID0gq2FUeXBlLnRvVmFsdWVMaXRlcmFsKHRlbXApuzsKCQkJCatFTkRJRrsKCQkJJycnCgkJfQoJfQoJCglkZWYgcHJpdmF0ZSBnZXRNaW5NYXhUeXBlKFByaW1pdGl2ZVR5cGUgdHlwZSl7CgkJcmV0dXJuIHN3aXRjaCh0eXBlLnR5cGVOYW1lKXsKCQkJY2FzZSAiYnl0ZSI6CgkJCQkiaW50IgoJCQljYXNlICJzaG9ydCI6CgkJCQkiaW50IgoJCQljYXNlICJmbG9hdCI6CgkJCQkiZG91YmxlIgoJCQlkZWZhdWx0OgoJCQkJdHlwZS50eXBlTmFtZQoJCX0KCX0KCQp9Cg==