cGFja2FnZSBvcmcuZWNsaXBzZS51aS5leHRlcm5hbHRvb2xzLmludGVybmFsLnVpOwoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKQ29weXJpZ2h0IChjKSAyMDAyIElCTSBDb3JwLiBhbmQgb3RoZXJzLgpBbGwgcmlnaHRzIHJlc2VydmVkLiCgIFRoaXMgcHJvZ3JhbSBhbmQgdGhlIGFjY29tcGFueWluZyBtYXRlcmlhbHMKYXJlIG1hZGUgYXZhaWxhYmxlIHVuZGVyIHRoZSB0ZXJtcyBvZiB0aGUgQ29tbW9uIFB1YmxpYyBMaWNlbnNlIHYwLjUKd2hpY2ggYWNjb21wYW5pZXMgdGhpcyBkaXN0cmlidXRpb24sIGFuZCBpcyBhdmFpbGFibGUgYXQKaHR0cDovL3d3dy5lY2xpcHNlLm9yZy9sZWdhbC9jcGwtdjA1Lmh0bWwKoApDb250cmlidXRvcnM6CioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCmltcG9ydCBqYXZhLm5ldC5VUkw7CgppbXBvcnQgb3JnLmVjbGlwc2UuYW50LmNvcmUuQW50Q29yZVBsdWdpbjsKaW1wb3J0IG9yZy5lY2xpcHNlLmpmYWNlLmRpYWxvZ3MuKjsKaW1wb3J0IG9yZy5lY2xpcHNlLnN3dC5TV1Q7CmltcG9ydCBvcmcuZWNsaXBzZS5zd3QuZXZlbnRzLio7CmltcG9ydCBvcmcuZWNsaXBzZS5zd3QubGF5b3V0Lio7CmltcG9ydCBvcmcuZWNsaXBzZS5zd3Qud2lkZ2V0cy4qOwppbXBvcnQgb3JnLmVjbGlwc2UudWkuZXh0ZXJuYWx0b29scy5pbnRlcm5hbC5jb3JlLlRvb2xNZXNzYWdlczsKaW1wb3J0IG9yZy5lY2xpcHNlLnVpLmhlbHAuV29ya2JlbmNoSGVscDsKCmltcG9ydCBvcmcuZWNsaXBzZS5qZmFjZS5kaWFsb2dzLkRpYWxvZzsKCi8qKgogKiBEaWFsb2cgdG8gcHJvbXB0IHRoZSB1c2VyIHRvIGFkZCBhIGN1c3RvbSBhbnQgdGFzayBvciB0eXBlLgogKi8KcHVibGljIGNsYXNzIEFkZFRhc2tEaWFsb2cgZXh0ZW5kcyBEaWFsb2cgewoJcHJpdmF0ZSBTdHJpbmcgdGl0bGU7Cglwcml2YXRlIFN0cmluZyBkZXNjcmlwdGlvbjsKCgkvL3Rhc2svdHlwZSBhdHRyaWJ1dGVzCglwcml2YXRlIFN0cmluZyB0YXNrTmFtZTsKCXByaXZhdGUgU3RyaW5nIGNsYXNzTmFtZTsKCXByaXZhdGUgVVJMIGxpYnJhcnk7CgoJLy93aWRnZXRzCglwcml2YXRlIEJ1dHRvbiBva0J1dHRvbjsKCXByaXZhdGUgVGV4dCBuYW1lRmllbGQ7Cglwcml2YXRlIFRleHQgY2xhc3NGaWVsZDsKCXByaXZhdGUgQ29tYm8gbGlicmFyeUZpZWxkOwoKCXByaXZhdGUgVVJMW10gbGlicmFyeVVybHM7CgoJLyoqCgkgKiBDcmVhdGVzIGEgbmV3IHRhc2sgZGlhbG9nIHdpdGggdGhlIGdpdmVuIHNoZWxsIGFuZCB0aXRsZS4KCSAqLwoJcHJvdGVjdGVkIEFkZFRhc2tEaWFsb2coCgkJU2hlbGwgcGFyZW50U2hlbGwsCgkJU3RyaW5nIHRpdGxlLAoJCVN0cmluZyBkZXNjcmlwdGlvbikgewoJCXN1cGVyKHBhcmVudFNoZWxsKTsKCQl0aGlzLnRpdGxlID0gdGl0bGU7CgkJdGhpcy5kZXNjcmlwdGlvbiA9IGRlc2NyaXB0aW9uOwoJfQoJLyoqCgkgKiBAc2VlIFdpbmRvdyNjb25maWd1cmVTaGVsbChTaGVsbCkKCSAqLwoJcHJvdGVjdGVkIHZvaWQgY29uZmlndXJlU2hlbGwoU2hlbGwgbmV3U2hlbGwpIHsKCQlzdXBlci5jb25maWd1cmVTaGVsbChuZXdTaGVsbCk7CgkJbmV3U2hlbGwuc2V0VGV4dCh0aXRsZSk7CgkJV29ya2JlbmNoSGVscC5zZXRIZWxwKG5ld1NoZWxsLCBJSGVscENvbnRleHRJZHMuQUREX1RBU0tfRElBTE9HKTsKCX0KCS8qKgoJICogQHNlZSBEaWFsb2cjY3JlYXRlQnV0dG9uc0ZvckJ1dHRvbkJhcihDb21wb3NpdGUpCgkgKi8KCXByb3RlY3RlZCB2b2lkIGNyZWF0ZUJ1dHRvbnNGb3JCdXR0b25CYXIoQ29tcG9zaXRlIHBhcmVudCkgewoJCW9rQnV0dG9uID0KCQkJY3JlYXRlQnV0dG9uKAoJCQkJcGFyZW50LAoJCQkJSURpYWxvZ0NvbnN0YW50cy5PS19JRCwKCQkJCUlEaWFsb2dDb25zdGFudHMuT0tfTEFCRUwsCgkJCQl0cnVlKTsKCQljcmVhdGVCdXR0b24oCgkJCXBhcmVudCwKCQkJSURpYWxvZ0NvbnN0YW50cy5DQU5DRUxfSUQsCgkJCUlEaWFsb2dDb25zdGFudHMuQ0FOQ0VMX0xBQkVMLAoJCQlmYWxzZSk7CgkJdXBkYXRlRW5hYmxlbWVudCgpOwoJfQoJLyoqCgkgKiBAc2VlIERpYWxvZyNjcmVhdGVEaWFsb2dBcmVhKENvbXBvc2l0ZSkKCSAqLwoJcHJvdGVjdGVkIENvbnRyb2wgY3JlYXRlRGlhbG9nQXJlYShDb21wb3NpdGUgcGFyZW50KSB7CgkJQ29tcG9zaXRlIGRpYWxvZ0FyZWEgPSBuZXcgQ29tcG9zaXRlKHBhcmVudCwgU1dULk5PTkUpOwoJCUdyaWRMYXlvdXQgbGF5b3V0ID0gbmV3IEdyaWRMYXlvdXQoKTsKCQlsYXlvdXQubnVtQ29sdW1ucyA9IDI7CgkJbGF5b3V0Lm1hcmdpbkhlaWdodCA9IDEwOwoJCWxheW91dC5tYXJnaW5XaWR0aCA9IDEwOwoJCWRpYWxvZ0FyZWEuc2V0TGF5b3V0KGxheW91dCk7CgoJCUxhYmVsIGxhYmVsID0gbmV3IExhYmVsKGRpYWxvZ0FyZWEsIFNXVC5OT05FKTsKCQlsYWJlbC5zZXRUZXh0KGRlc2NyaXB0aW9uKTsKCQlHcmlkRGF0YSBkYXRhID0gbmV3IEdyaWREYXRhKEdyaWREYXRhLkZJTExfSE9SSVpPTlRBTCk7CgkJZGF0YS5ob3Jpem9udGFsU3BhbiA9IDI7CgkJbGFiZWwuc2V0TGF5b3V0RGF0YShkYXRhKTsKCgkJbGFiZWwgPSBuZXcgTGFiZWwoZGlhbG9nQXJlYSwgU1dULk5PTkUpOwoJCWxhYmVsLnNldFRleHQoVG9vbE1lc3NhZ2VzLmdldFN0cmluZygiQWRkVGFza0RpYWxvZy5uYW1lIikpOyAvLyROT04tTkxTLTEkOwoJCW5hbWVGaWVsZCA9IG5ldyBUZXh0KGRpYWxvZ0FyZWEsIFNXVC5CT1JERVIpOwoJCWRhdGEgPSBuZXcgR3JpZERhdGEoR3JpZERhdGEuRklMTF9IT1JJWk9OVEFMKTsKCQlkYXRhLndpZHRoSGludCA9IElEaWFsb2dDb25zdGFudHMuRU5UUllfRklFTERfV0lEVEg7CgkJbmFtZUZpZWxkLnNldExheW91dERhdGEoZGF0YSk7CgkJbmFtZUZpZWxkLmFkZE1vZGlmeUxpc3RlbmVyKG5ldyBNb2RpZnlMaXN0ZW5lcigpIHsKCQkJcHVibGljIHZvaWQgbW9kaWZ5VGV4dChNb2RpZnlFdmVudCBlKSB7CgkJCQl1cGRhdGVFbmFibGVtZW50KCk7CgkJCX0KCQl9KTsKCgkJbGFiZWwgPSBuZXcgTGFiZWwoZGlhbG9nQXJlYSwgU1dULk5PTkUpOwoJCWxhYmVsLnNldFRleHQoVG9vbE1lc3NhZ2VzLmdldFN0cmluZygiQWRkVGFza0RpYWxvZy5jbGFzcyIpKTsgLy8kTk9OLU5MUy0xJDsKCQljbGFzc0ZpZWxkID0gbmV3IFRleHQoZGlhbG9nQXJlYSwgU1dULkJPUkRFUik7CgkJZGF0YSA9IG5ldyBHcmlkRGF0YShHcmlkRGF0YS5GSUxMX0hPUklaT05UQUwpOwoJCWRhdGEud2lkdGhIaW50ID0gSURpYWxvZ0NvbnN0YW50cy5FTlRSWV9GSUVMRF9XSURUSDsKCQljbGFzc0ZpZWxkLnNldExheW91dERhdGEoZGF0YSk7CgkJY2xhc3NGaWVsZC5hZGRNb2RpZnlMaXN0ZW5lcihuZXcgTW9kaWZ5TGlzdGVuZXIoKSB7CgkJCXB1YmxpYyB2b2lkIG1vZGlmeVRleHQoTW9kaWZ5RXZlbnQgZSkgewoJCQkJdXBkYXRlRW5hYmxlbWVudCgpOwoJCQl9CgkJfSk7CgoJCWxhYmVsID0gbmV3IExhYmVsKGRpYWxvZ0FyZWEsIFNXVC5OT05FKTsKCQlsYWJlbC5zZXRUZXh0KFRvb2xNZXNzYWdlcy5nZXRTdHJpbmcoIkFkZFRhc2tEaWFsb2cubGlicmFyeSIpKTsgLy8kTk9OLU5MUy0xJDsKCQlsaWJyYXJ5RmllbGQgPSBuZXcgQ29tYm8oZGlhbG9nQXJlYSwgU1dULlJFQURfT05MWSB8IFNXVC5CT1JERVIpOwoJCWRhdGEgPSBuZXcgR3JpZERhdGEoR3JpZERhdGEuRklMTF9IT1JJWk9OVEFMKTsKCQlkYXRhLndpZHRoSGludCA9IElEaWFsb2dDb25zdGFudHMuRU5UUllfRklFTERfV0lEVEg7CgkJbGlicmFyeUZpZWxkLnNldExheW91dERhdGEoZGF0YSk7CgkJbGlicmFyeUZpZWxkLmFkZFNlbGVjdGlvbkxpc3RlbmVyKG5ldyBTZWxlY3Rpb25BZGFwdGVyKCkgewoJCQlwdWJsaWMgdm9pZCB3aWRnZXRTZWxlY3RlZChTZWxlY3Rpb25FdmVudCBlKSB7CgkJCQl1cGRhdGVFbmFibGVtZW50KCk7CgkJCX0KCQl9KTsKCgkJLy9wb3B1bGF0ZSBsaWJyYXJ5IGNvbWJvIGFuZCBzZWxlY3QgaW5wdXQgbGlicmFyeQoJCWxpYnJhcnlVcmxzID0KCQkJQW50Q29yZVBsdWdpbi5nZXRQbHVnaW4oKS5nZXRQcmVmZXJlbmNlcygpLmdldEN1c3RvbVVSTHMoKTsKCQlpbnQgc2VsZWN0aW9uID0gMDsKCQlmb3IgKGludCBpID0gMDsgaSA8IGxpYnJhcnlVcmxzLmxlbmd0aDsgaSsrKSB7CgkJCWxpYnJhcnlGaWVsZC5hZGQobGlicmFyeVVybHNbaV0uZ2V0RmlsZSgpKTsKCQkJaWYgKGxpYnJhcnlVcmxzW2ldLmVxdWFscyhsaWJyYXJ5KSkKCQkJCXNlbGVjdGlvbiA9IGk7CgkJfQoKCQkvL2ludGlhbGl6ZSBmaWVsZHMKCQlpZiAodGFza05hbWUgIT0gbnVsbCkKCQkJbmFtZUZpZWxkLnNldFRleHQodGFza05hbWUpOwoJCWlmIChjbGFzc05hbWUgIT0gbnVsbCkKCQkJY2xhc3NGaWVsZC5zZXRUZXh0KGNsYXNzTmFtZSk7CgkJaWYgKGxpYnJhcnlVcmxzLmxlbmd0aCA+PSAwKQoJCQlsaWJyYXJ5RmllbGQuc2VsZWN0KHNlbGVjdGlvbik7CgkJcmV0dXJuIGRpYWxvZ0FyZWE7Cgl9CgoJcHVibGljIFN0cmluZyBnZXRDbGFzc05hbWUoKSB7CgkJcmV0dXJuIGNsYXNzTmFtZTsKCX0KCXB1YmxpYyB2b2lkIHNldENsYXNzTmFtZShTdHJpbmcgY2xhc3NOYW1lKSB7CgkJdGhpcy5jbGFzc05hbWUgPSBjbGFzc05hbWU7Cgl9CglwdWJsaWMgVVJMIGdldExpYnJhcnkoKSB7CgkJcmV0dXJuIGxpYnJhcnk7Cgl9CgkvKioKCSAqIEBzZWUgRGlhbG9nI29rUHJlc3NlZCgpCgkgKi8KCXByb3RlY3RlZCB2b2lkIG9rUHJlc3NlZCgpIHsKCQljbGFzc05hbWUgPSBjbGFzc0ZpZWxkLmdldFRleHQoKTsKCQl0YXNrTmFtZSA9IG5hbWVGaWVsZC5nZXRUZXh0KCk7CgkJaW50IHNlbGVjdGlvbiA9IGxpYnJhcnlGaWVsZC5nZXRTZWxlY3Rpb25JbmRleCgpOwoJCWlmIChzZWxlY3Rpb24gPj0gMCkKCQkJbGlicmFyeSA9IGxpYnJhcnlVcmxzW3NlbGVjdGlvbl07CgkJc3VwZXIub2tQcmVzc2VkKCk7Cgl9CglwdWJsaWMgdm9pZCBzZXRMaWJyYXJ5KFVSTCBsaWJyYXJ5KSB7CgkJdGhpcy5saWJyYXJ5ID0gbGlicmFyeTsKCX0KCXB1YmxpYyBTdHJpbmcgZ2V0VGFza05hbWUoKSB7CgkJcmV0dXJuIHRhc2tOYW1lOwoJfQoJcHVibGljIHZvaWQgc2V0VGFza05hbWUoU3RyaW5nIHRhc2tOYW1lKSB7CgkJdGhpcy50YXNrTmFtZSA9IHRhc2tOYW1lOwoJfQoJcHJpdmF0ZSB2b2lkIHVwZGF0ZUVuYWJsZW1lbnQoKSB7CgkJaWYgKG9rQnV0dG9uICE9IG51bGwpCgkJCW9rQnV0dG9uLnNldEVuYWJsZWQoCgkJCQluYW1lRmllbGQuZ2V0VGV4dCgpLmxlbmd0aCgpID4gMAoJCQkJCSYmIGNsYXNzRmllbGQuZ2V0VGV4dCgpLmxlbmd0aCgpID4gMAoJCQkJCSYmIGxpYnJhcnlGaWVsZC5nZXRTZWxlY3Rpb25JbmRleCgpID49IDApOwoJfQp9