LyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogQ29weXJpZ2h0IChjKSAyMDE2IEZ1bmRhY2nzbiBUZWNuYWxpYSBSZXNlYXJjaCAmIElubm92YXRpb24uCiAqCiAqIEFsbCByaWdodHMgcmVzZXJ2ZWQuIFRoaXMgcHJvZ3JhbSBhbmQgdGhlIGFjY29tcGFueWluZyBtYXRlcmlhbHMKICogYXJlIG1hZGUgYXZhaWxhYmxlIHVuZGVyIHRoZSB0ZXJtcyBvZiB0aGUgRWNsaXBzZSBQdWJsaWMgTGljZW5zZSB2MS4wCiAqIHdoaWNoIGFjY29tcGFuaWVzIHRoaXMgZGlzdHJpYnV0aW9uLCBhbmQgaXMgYXZhaWxhYmxlIGF0CiAqIGh0dHA6Ly93d3cuZWNsaXBzZS5vcmcvbGVnYWwvZXBsLXYxMC5odG1sCiAqCiAqIENvbnRyaWJ1dG9yczoKICogICBIdWFzY2FyIEVzcGlub3phIC0gaW5pdGlhbCBBUEkgYW5kIGltcGxlbWVudGF0aW9uCiAqICAgQWxlamFuZHJhIFJ17XogLSBpbml0aWFsIEFQSSBhbmQgaW1wbGVtZW50YXRpb24KICogICBJZG95YSBEZWwgUu1vIC0gaW5pdGlhbCBBUEkgYW5kIGltcGxlbWVudGF0aW9uCiAqICAgTWFyaSBDYXJtZW4gUGFsYWNpb3MgLSBpbml0aWFsIEFQSSBhbmQgaW1wbGVtZW50YXRpb24KICogICBBbmdlbCBM83BleiAtIGluaXRpYWwgQVBJIGFuZCBpbXBsZW1lbnRhdGlvbgogKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8KLyoKICogCiAqLwpwYWNrYWdlIG9yZy5lY2xpcHNlLm9wZW5jZXJ0LnBrbS5yZWZmcmFtZXdvcmsucmVmZnJhbWV3b3JrLmRpYWdyYW0uZWRpdC5wYXJ0czsKCmltcG9ydCBqYXZhLnV0aWwuQ29sbGVjdGlvbnM7CmltcG9ydCBqYXZhLnV0aWwuTGlzdDsKCmltcG9ydCBvcmcuZWNsaXBzZS5kcmF3MmQuSUZpZ3VyZTsKaW1wb3J0IG9yZy5lY2xpcHNlLmRyYXcyZC5MYWJlbDsKaW1wb3J0IG9yZy5lY2xpcHNlLmRyYXcyZC5nZW9tZXRyeS5Qb2ludDsKaW1wb3J0IG9yZy5lY2xpcHNlLmVtZi5jb21tb24ubm90aWZ5Lk5vdGlmaWNhdGlvbjsKaW1wb3J0IG9yZy5lY2xpcHNlLmVtZi5lY29yZS5FT2JqZWN0OwppbXBvcnQgb3JnLmVjbGlwc2UuZW1mLnRyYW5zYWN0aW9uLlJ1bm5hYmxlV2l0aFJlc3VsdDsKaW1wb3J0IG9yZy5lY2xpcHNlLmdlZi5BY2Nlc3NpYmxlRWRpdFBhcnQ7CmltcG9ydCBvcmcuZWNsaXBzZS5nZWYuRWRpdFBvbGljeTsKaW1wb3J0IG9yZy5lY2xpcHNlLmdlZi5SZXF1ZXN0OwppbXBvcnQgb3JnLmVjbGlwc2UuZ2VmLnJlcXVlc3RzLkRpcmVjdEVkaXRSZXF1ZXN0OwppbXBvcnQgb3JnLmVjbGlwc2UuZ2VmLnRvb2xzLkRpcmVjdEVkaXRNYW5hZ2VyOwppbXBvcnQgb3JnLmVjbGlwc2UuZ21mLnJ1bnRpbWUuY29tbW9uLnVpLnNlcnZpY2VzLnBhcnNlci5JUGFyc2VyOwppbXBvcnQgb3JnLmVjbGlwc2UuZ21mLnJ1bnRpbWUuY29tbW9uLnVpLnNlcnZpY2VzLnBhcnNlci5JUGFyc2VyRWRpdFN0YXR1czsKaW1wb3J0IG9yZy5lY2xpcHNlLmdtZi5ydW50aW1lLmNvbW1vbi51aS5zZXJ2aWNlcy5wYXJzZXIuUGFyc2VyRWRpdFN0YXR1czsKaW1wb3J0IG9yZy5lY2xpcHNlLmdtZi5ydW50aW1lLmNvbW1vbi51aS5zZXJ2aWNlcy5wYXJzZXIuUGFyc2VyT3B0aW9uczsKaW1wb3J0IG9yZy5lY2xpcHNlLmdtZi5ydW50aW1lLmRpYWdyYW0udWkuZWRpdHBhcnRzLkNvbXBhcnRtZW50RWRpdFBhcnQ7CmltcG9ydCBvcmcuZWNsaXBzZS5nbWYucnVudGltZS5kaWFncmFtLnVpLmVkaXRwYXJ0cy5JR3JhcGhpY2FsRWRpdFBhcnQ7CmltcG9ydCBvcmcuZWNsaXBzZS5nbWYucnVudGltZS5kaWFncmFtLnVpLmVkaXRwYXJ0cy5JVGV4dEF3YXJlRWRpdFBhcnQ7CmltcG9ydCBvcmcuZWNsaXBzZS5nbWYucnVudGltZS5kaWFncmFtLnVpLmVkaXRwb2xpY2llcy5MYWJlbERpcmVjdEVkaXRQb2xpY3k7CmltcG9ydCBvcmcuZWNsaXBzZS5nbWYucnVudGltZS5kaWFncmFtLnVpLmwxMG4uRGlhZ3JhbUNvbG9yUmVnaXN0cnk7CmltcG9ydCBvcmcuZWNsaXBzZS5nbWYucnVudGltZS5kaWFncmFtLnVpLmxhYmVsLklMYWJlbERlbGVnYXRlOwppbXBvcnQgb3JnLmVjbGlwc2UuZ21mLnJ1bnRpbWUuZGlhZ3JhbS51aS5sYWJlbC5XcmFwcGluZ0xhYmVsRGVsZWdhdGU7CmltcG9ydCBvcmcuZWNsaXBzZS5nbWYucnVudGltZS5kaWFncmFtLnVpLnJlcXVlc3RzLlJlcXVlc3RDb25zdGFudHM7CmltcG9ydCBvcmcuZWNsaXBzZS5nbWYucnVudGltZS5kaWFncmFtLnVpLnRvb2xzLlRleHREaXJlY3RFZGl0TWFuYWdlcjsKaW1wb3J0IG9yZy5lY2xpcHNlLmdtZi5ydW50aW1lLmRyYXcyZC51aS5maWd1cmVzLldyYXBwaW5nTGFiZWw7CmltcG9ydCBvcmcuZWNsaXBzZS5nbWYucnVudGltZS5lbWYuY29yZS51dGlsLkVPYmplY3RBZGFwdGVyOwppbXBvcnQgb3JnLmVjbGlwc2UuZ21mLnJ1bnRpbWUuZW1mLnVpLnNlcnZpY2VzLnBhcnNlci5JU2VtYW50aWNQYXJzZXI7CmltcG9ydCBvcmcuZWNsaXBzZS5nbWYucnVudGltZS5ub3RhdGlvbi5Gb250U3R5bGU7CmltcG9ydCBvcmcuZWNsaXBzZS5nbWYucnVudGltZS5ub3RhdGlvbi5Ob3RhdGlvblBhY2thZ2U7CmltcG9ydCBvcmcuZWNsaXBzZS5nbWYucnVudGltZS5ub3RhdGlvbi5WaWV3OwppbXBvcnQgb3JnLmVjbGlwc2UuZ21mLnRvb2xpbmcucnVudGltZS5kaXJlY3RlZGl0LlRleHREaXJlY3RFZGl0TWFuYWdlcjI7CmltcG9ydCBvcmcuZWNsaXBzZS5nbWYudG9vbGluZy5ydW50aW1lLmRyYXcyZC5sYWJlbHMuU2ltcGxlTGFiZWxEZWxlZ2F0ZTsKaW1wb3J0IG9yZy5lY2xpcHNlLmdtZi50b29saW5nLnJ1bnRpbWUuZWRpdC5wb2xpY2llcy5EZWZhdWx0Tm9kZUxhYmVsRHJhZ1BvbGljeTsKaW1wb3J0IG9yZy5lY2xpcHNlLmdtZi50b29saW5nLnJ1bnRpbWUuZWRpdC5wb2xpY2llcy5sYWJlbHMuSVJlZnJlc2hhYmxlRmVlZGJhY2tFZGl0UG9saWN5OwppbXBvcnQgb3JnLmVjbGlwc2UuamZhY2UudGV4dC5jb250ZW50YXNzaXN0LklDb250ZW50QXNzaXN0UHJvY2Vzc29yOwppbXBvcnQgb3JnLmVjbGlwc2UuamZhY2Uudmlld2Vycy5JQ2VsbEVkaXRvclZhbGlkYXRvcjsKaW1wb3J0IG9yZy5lY2xpcHNlLnN3dC5TV1Q7CmltcG9ydCBvcmcuZWNsaXBzZS5zd3QuYWNjZXNzaWJpbGl0eS5BY2Nlc3NpYmxlRXZlbnQ7CmltcG9ydCBvcmcuZWNsaXBzZS5zd3QuZ3JhcGhpY3MuQ29sb3I7CmltcG9ydCBvcmcuZWNsaXBzZS5zd3QuZ3JhcGhpY3MuRm9udERhdGE7CmltcG9ydCBvcmcuZWNsaXBzZS5zd3QuZ3JhcGhpY3MuSW1hZ2U7CmltcG9ydCBvcmcuZWNsaXBzZS5vcGVuY2VydC5wa20ucmVmZnJhbWV3b3JrLnJlZmZyYW1ld29yay5kaWFncmFtLmVkaXQucG9saWNpZXMuUmVmZnJhbWV3b3JrVGV4dFNlbGVjdGlvbkVkaXRQb2xpY3k7CmltcG9ydCBvcmcuZWNsaXBzZS5vcGVuY2VydC5wa20ucmVmZnJhbWV3b3JrLnJlZmZyYW1ld29yay5kaWFncmFtLnBhcnQuUmVmZnJhbWV3b3JrVmlzdWFsSURSZWdpc3RyeTsKaW1wb3J0IG9yZy5lY2xpcHNlLm9wZW5jZXJ0LnBrbS5yZWZmcmFtZXdvcmsucmVmZnJhbWV3b3JrLmRpYWdyYW0ucHJvdmlkZXJzLlJlZmZyYW1ld29ya0VsZW1lbnRUeXBlczsKaW1wb3J0IG9yZy5lY2xpcHNlLm9wZW5jZXJ0LnBrbS5yZWZmcmFtZXdvcmsucmVmZnJhbWV3b3JrLmRpYWdyYW0ucHJvdmlkZXJzLlJlZmZyYW1ld29ya1BhcnNlclByb3ZpZGVyOwoKLyoqCiAqIEBnZW5lcmF0ZWQKICovCnB1YmxpYyBjbGFzcyBSZWZBY3Rpdml0eU5hbWVFZGl0UGFydCBleHRlbmRzIENvbXBhcnRtZW50RWRpdFBhcnQgaW1wbGVtZW50cwoJCUlUZXh0QXdhcmVFZGl0UGFydCB7CgoJLyoqCgkgKiBAZ2VuZXJhdGVkCgkgKi8KCXB1YmxpYyBzdGF0aWMgZmluYWwgaW50IFZJU1VBTF9JRCA9IDUwMDI7CgoJLyoqCgkgKiBAZ2VuZXJhdGVkCgkgKi8KCXByaXZhdGUgRGlyZWN0RWRpdE1hbmFnZXIgbWFuYWdlcjsKCgkvKioKCSAqIEBnZW5lcmF0ZWQKCSAqLwoJcHJpdmF0ZSBJUGFyc2VyIHBhcnNlcjsKCgkvKioKCSAqIEBnZW5lcmF0ZWQKCSAqLwoJcHJpdmF0ZSBMaXN0PD8+IHBhcnNlckVsZW1lbnRzOwoKCS8qKgoJICogQGdlbmVyYXRlZAoJICovCglwcml2YXRlIFN0cmluZyBkZWZhdWx0VGV4dDsKCgkvKioKCSAqIEBnZW5lcmF0ZWQKCSAqLwoJcHJpdmF0ZSBJTGFiZWxEZWxlZ2F0ZSBsYWJlbERlbGVnYXRlOwoKCS8qKgoJICogQGdlbmVyYXRlZAoJICovCglwdWJsaWMgUmVmQWN0aXZpdHlOYW1lRWRpdFBhcnQoVmlldyB2aWV3KSB7CgkJc3VwZXIodmlldyk7Cgl9CgoJLyoqCgkgKiBAZ2VuZXJhdGVkCgkgKi8KCXByb3RlY3RlZCB2b2lkIGNyZWF0ZURlZmF1bHRFZGl0UG9saWNpZXMoKSB7CgkJc3VwZXIuY3JlYXRlRGVmYXVsdEVkaXRQb2xpY2llcygpOwoJCWluc3RhbGxFZGl0UG9saWN5KEVkaXRQb2xpY3kuU0VMRUNUSU9OX0ZFRURCQUNLX1JPTEUsCgkJCQluZXcgUmVmZnJhbWV3b3JrVGV4dFNlbGVjdGlvbkVkaXRQb2xpY3koKSk7CgkJaW5zdGFsbEVkaXRQb2xpY3koRWRpdFBvbGljeS5ESVJFQ1RfRURJVF9ST0xFLAoJCQkJbmV3IExhYmVsRGlyZWN0RWRpdFBvbGljeSgpKTsKCQlpbnN0YWxsRWRpdFBvbGljeShFZGl0UG9saWN5LlBSSU1BUllfRFJBR19ST0xFLAoJCQkJbmV3IERlZmF1bHROb2RlTGFiZWxEcmFnUG9saWN5KCkpOwoJfQoKCS8qKgoJICogQGdlbmVyYXRlZAoJICovCglwcm90ZWN0ZWQgU3RyaW5nIGdldExhYmVsVGV4dEhlbHBlcihJRmlndXJlIGZpZ3VyZSkgewoJCWlmIChmaWd1cmUgaW5zdGFuY2VvZiBXcmFwcGluZ0xhYmVsKSB7CgkJCXJldHVybiAoKFdyYXBwaW5nTGFiZWwpIGZpZ3VyZSkuZ2V0VGV4dCgpOwoJCX0gZWxzZSBpZiAoZmlndXJlIGluc3RhbmNlb2YgTGFiZWwpIHsKCQkJcmV0dXJuICgoTGFiZWwpIGZpZ3VyZSkuZ2V0VGV4dCgpOwoJCX0gZWxzZSB7CgkJCXJldHVybiBnZXRMYWJlbERlbGVnYXRlKCkuZ2V0VGV4dCgpOwoJCX0KCX0KCgkvKioKCSAqIEBnZW5lcmF0ZWQKCSAqLwoJcHJvdGVjdGVkIHZvaWQgc2V0TGFiZWxUZXh0SGVscGVyKElGaWd1cmUgZmlndXJlLCBTdHJpbmcgdGV4dCkgewoJCWlmIChmaWd1cmUgaW5zdGFuY2VvZiBXcmFwcGluZ0xhYmVsKSB7CgkJCSgoV3JhcHBpbmdMYWJlbCkgZmlndXJlKS5zZXRUZXh0KHRleHQpOwoJCX0gZWxzZSBpZiAoZmlndXJlIGluc3RhbmNlb2YgTGFiZWwpIHsKCQkJKChMYWJlbCkgZmlndXJlKS5zZXRUZXh0KHRleHQpOwoJCX0gZWxzZSB7CgkJCWdldExhYmVsRGVsZWdhdGUoKS5zZXRUZXh0KHRleHQpOwoJCX0KCX0KCgkvKioKCSAqIEBnZW5lcmF0ZWQKCSAqLwoJcHJvdGVjdGVkIEltYWdlIGdldExhYmVsSWNvbkhlbHBlcihJRmlndXJlIGZpZ3VyZSkgewoJCWlmIChmaWd1cmUgaW5zdGFuY2VvZiBXcmFwcGluZ0xhYmVsKSB7CgkJCXJldHVybiAoKFdyYXBwaW5nTGFiZWwpIGZpZ3VyZSkuZ2V0SWNvbigpOwoJCX0gZWxzZSBpZiAoZmlndXJlIGluc3RhbmNlb2YgTGFiZWwpIHsKCQkJcmV0dXJuICgoTGFiZWwpIGZpZ3VyZSkuZ2V0SWNvbigpOwoJCX0gZWxzZSB7CgkJCXJldHVybiBnZXRMYWJlbERlbGVnYXRlKCkuZ2V0SWNvbigwKTsKCQl9Cgl9CgoJLyoqCgkgKiBAZ2VuZXJhdGVkCgkgKi8KCXByb3RlY3RlZCB2b2lkIHNldExhYmVsSWNvbkhlbHBlcihJRmlndXJlIGZpZ3VyZSwgSW1hZ2UgaWNvbikgewoJCWlmIChmaWd1cmUgaW5zdGFuY2VvZiBXcmFwcGluZ0xhYmVsKSB7CgkJCSgoV3JhcHBpbmdMYWJlbCkgZmlndXJlKS5zZXRJY29uKGljb24pOwoJCQlyZXR1cm47CgkJfSBlbHNlIGlmIChmaWd1cmUgaW5zdGFuY2VvZiBMYWJlbCkgewoJCQkoKExhYmVsKSBmaWd1cmUpLnNldEljb24oaWNvbik7CgkJCXJldHVybjsKCQl9IGVsc2UgewoJCQlnZXRMYWJlbERlbGVnYXRlKCkuc2V0SWNvbihpY29uLCAwKTsKCQl9Cgl9CgoJLyoqCgkgKiBAZ2VuZXJhdGVkCgkgKi8KCXB1YmxpYyB2b2lkIHNldExhYmVsKFdyYXBwaW5nTGFiZWwgZmlndXJlKSB7CgkJdW5yZWdpc3RlclZpc3VhbHMoKTsKCQlzZXRGaWd1cmUoZmlndXJlKTsKCQlkZWZhdWx0VGV4dCA9IGdldExhYmVsVGV4dEhlbHBlcihmaWd1cmUpOwoJCXJlZ2lzdGVyVmlzdWFscygpOwoJCXJlZnJlc2hWaXN1YWxzKCk7Cgl9CgoJLyoqCgkgKiBAZ2VuZXJhdGVkCgkgKi8KCUBTdXBwcmVzc1dhcm5pbmdzKCJyYXd0eXBlcyIpCglwcm90ZWN0ZWQgTGlzdCBnZXRNb2RlbENoaWxkcmVuKCkgewoJCXJldHVybiBDb2xsZWN0aW9ucy5FTVBUWV9MSVNUOwoJfQoKCS8qKgoJICogQGdlbmVyYXRlZAoJICovCglwdWJsaWMgSUdyYXBoaWNhbEVkaXRQYXJ0IGdldENoaWxkQnlTZW1hbnRpY0hpbnQoU3RyaW5nIHNlbWFudGljSGludCkgewoJCXJldHVybiBudWxsOwoJfQoKCS8qKgoJICogQGdlbmVyYXRlZAoJICovCglwcm90ZWN0ZWQgRU9iamVjdCBnZXRQYXJzZXJFbGVtZW50KCkgewoJCXJldHVybiByZXNvbHZlU2VtYW50aWNFbGVtZW50KCk7Cgl9CgoJLyoqCgkgKiBAZ2VuZXJhdGVkCgkgKi8KCXByb3RlY3RlZCBJbWFnZSBnZXRMYWJlbEljb24oKSB7CgkJRU9iamVjdCBwYXJzZXJFbGVtZW50ID0gZ2V0UGFyc2VyRWxlbWVudCgpOwoJCWlmIChwYXJzZXJFbGVtZW50ID09IG51bGwpIHsKCQkJcmV0dXJuIG51bGw7CgkJfQoJCXJldHVybiBSZWZmcmFtZXdvcmtFbGVtZW50VHlwZXMuZ2V0SW1hZ2UocGFyc2VyRWxlbWVudC5lQ2xhc3MoKSk7Cgl9CgoJLyoqCgkgKiBAZ2VuZXJhdGVkCgkgKi8KCXByb3RlY3RlZCBTdHJpbmcgZ2V0TGFiZWxUZXh0KCkgewoJCVN0cmluZyB0ZXh0ID0gbnVsbDsKCQlFT2JqZWN0IHBhcnNlckVsZW1lbnQgPSBnZXRQYXJzZXJFbGVtZW50KCk7CgkJaWYgKHBhcnNlckVsZW1lbnQgIT0gbnVsbCAmJiBnZXRQYXJzZXIoKSAhPSBudWxsKSB7CgkJCXRleHQgPSBnZXRQYXJzZXIoKS5nZXRQcmludFN0cmluZygKCQkJCQluZXcgRU9iamVjdEFkYXB0ZXIocGFyc2VyRWxlbWVudCksCgkJCQkJZ2V0UGFyc2VyT3B0aW9ucygpLmludFZhbHVlKCkpOwoJCX0KCQlpZiAodGV4dCA9PSBudWxsIHx8IHRleHQubGVuZ3RoKCkgPT0gMCkgewoJCQl0ZXh0ID0gZGVmYXVsdFRleHQ7CgkJfQoJCXJldHVybiB0ZXh0OwoJfQoKCS8qKgoJICogQGdlbmVyYXRlZAoJICovCglwdWJsaWMgdm9pZCBzZXRMYWJlbFRleHQoU3RyaW5nIHRleHQpIHsKCQlzZXRMYWJlbFRleHRIZWxwZXIoZ2V0RmlndXJlKCksIHRleHQpOwoJCXJlZnJlc2hTZWxlY3Rpb25GZWVkYmFjaygpOwoJfQoKCS8qKgoJICogQGdlbmVyYXRlZAoJICovCglwdWJsaWMgU3RyaW5nIGdldEVkaXRUZXh0KCkgewoJCWlmIChnZXRQYXJzZXJFbGVtZW50KCkgPT0gbnVsbCB8fCBnZXRQYXJzZXIoKSA9PSBudWxsKSB7CgkJCXJldHVybiAiIjsgLy8kTk9OLU5MUy0xJAoJCX0KCQlyZXR1cm4gZ2V0UGFyc2VyKCkuZ2V0RWRpdFN0cmluZygKCQkJCW5ldyBFT2JqZWN0QWRhcHRlcihnZXRQYXJzZXJFbGVtZW50KCkpLAoJCQkJZ2V0UGFyc2VyT3B0aW9ucygpLmludFZhbHVlKCkpOwoJfQoKCS8qKgoJICogQGdlbmVyYXRlZAoJICovCglwcm90ZWN0ZWQgYm9vbGVhbiBpc0VkaXRhYmxlKCkgewoJCXJldHVybiBnZXRQYXJzZXIoKSAhPSBudWxsOwoJfQoKCS8qKgoJICogQGdlbmVyYXRlZAoJICovCglwdWJsaWMgSUNlbGxFZGl0b3JWYWxpZGF0b3IgZ2V0RWRpdFRleHRWYWxpZGF0b3IoKSB7CgkJcmV0dXJuIG5ldyBJQ2VsbEVkaXRvclZhbGlkYXRvcigpIHsKCgkJCXB1YmxpYyBTdHJpbmcgaXNWYWxpZChmaW5hbCBPYmplY3QgdmFsdWUpIHsKCQkJCWlmICh2YWx1ZSBpbnN0YW5jZW9mIFN0cmluZykgewoJCQkJCWZpbmFsIEVPYmplY3QgZWxlbWVudCA9IGdldFBhcnNlckVsZW1lbnQoKTsKCQkJCQlmaW5hbCBJUGFyc2VyIHBhcnNlciA9IGdldFBhcnNlcigpOwoJCQkJCXRyeSB7CgkJCQkJCUlQYXJzZXJFZGl0U3RhdHVzIHZhbGlkID0gKElQYXJzZXJFZGl0U3RhdHVzKSBnZXRFZGl0aW5nRG9tYWluKCkKCQkJCQkJCQkucnVuRXhjbHVzaXZlKAoJCQkJCQkJCQkJbmV3IFJ1bm5hYmxlV2l0aFJlc3VsdC5JbXBsPElQYXJzZXJFZGl0U3RhdHVzPigpIHsKCgkJCQkJCQkJCQkJcHVibGljIHZvaWQgcnVuKCkgewoJCQkJCQkJCQkJCQlzZXRSZXN1bHQocGFyc2VyCgkJCQkJCQkJCQkJCQkJLmlzVmFsaWRFZGl0U3RyaW5nKAoJCQkJCQkJCQkJCQkJCQkJbmV3IEVPYmplY3RBZGFwdGVyKAoJCQkJCQkJCQkJCQkJCQkJCQllbGVtZW50KSwKCQkJCQkJCQkJCQkJCQkJCShTdHJpbmcpIHZhbHVlKSk7CgkJCQkJCQkJCQkJfQoJCQkJCQkJCQkJfSk7CgkJCQkJCXJldHVybiB2YWxpZC5nZXRDb2RlKCkgPT0gUGFyc2VyRWRpdFN0YXR1cy5FRElUQUJMRSA/IG51bGwKCQkJCQkJCQk6IHZhbGlkLmdldE1lc3NhZ2UoKTsKCQkJCQl9IGNhdGNoIChJbnRlcnJ1cHRlZEV4Y2VwdGlvbiBpZSkgewoJCQkJCQlpZS5wcmludFN0YWNrVHJhY2UoKTsKCQkJCQl9CgkJCQl9CgoJCQkJLy8gc2hvdWxkbid0IGdldCBoZXJlCgkJCQlyZXR1cm4gbnVsbDsKCQkJfQoJCX07Cgl9CgoJLyoqCgkgKiBAZ2VuZXJhdGVkCgkgKi8KCXB1YmxpYyBJQ29udGVudEFzc2lzdFByb2Nlc3NvciBnZXRDb21wbGV0aW9uUHJvY2Vzc29yKCkgewoJCWlmIChnZXRQYXJzZXJFbGVtZW50KCkgPT0gbnVsbCB8fCBnZXRQYXJzZXIoKSA9PSBudWxsKSB7CgkJCXJldHVybiBudWxsOwoJCX0KCQlyZXR1cm4gZ2V0UGFyc2VyKCkuZ2V0Q29tcGxldGlvblByb2Nlc3NvcigKCQkJCW5ldyBFT2JqZWN0QWRhcHRlcihnZXRQYXJzZXJFbGVtZW50KCkpKTsKCX0KCgkvKioKCSAqIEBnZW5lcmF0ZWQKCSAqLwoJcHVibGljIFBhcnNlck9wdGlvbnMgZ2V0UGFyc2VyT3B0aW9ucygpIHsKCQlyZXR1cm4gUGFyc2VyT3B0aW9ucy5OT05FOwoJfQoKCS8qKgoJICogQGdlbmVyYXRlZAoJICovCglwdWJsaWMgSVBhcnNlciBnZXRQYXJzZXIoKSB7CgkJaWYgKHBhcnNlciA9PSBudWxsKSB7CgkJCXBhcnNlciA9IFJlZmZyYW1ld29ya1BhcnNlclByb3ZpZGVyCgkJCQkJLmdldFBhcnNlcigKCQkJCQkJCVJlZmZyYW1ld29ya0VsZW1lbnRUeXBlcy5SZWZBY3Rpdml0eV8yMDAxLAoJCQkJCQkJZ2V0UGFyc2VyRWxlbWVudCgpLAoJCQkJCQkJUmVmZnJhbWV3b3JrVmlzdWFsSURSZWdpc3RyeQoJCQkJCQkJCQkuZ2V0VHlwZShvcmcuZWNsaXBzZS5vcGVuY2VydC5wa20ucmVmZnJhbWV3b3JrLnJlZmZyYW1ld29yay5kaWFncmFtLmVkaXQucGFydHMuUmVmQWN0aXZpdHlOYW1lRWRpdFBhcnQuVklTVUFMX0lEKSk7CgkJfQoJCXJldHVybiBwYXJzZXI7Cgl9CgoJLyoqCgkgKiBAZ2VuZXJhdGVkCgkgKi8KCXByb3RlY3RlZCBEaXJlY3RFZGl0TWFuYWdlciBnZXRNYW5hZ2VyKCkgewoJCWlmIChtYW5hZ2VyID09IG51bGwpIHsKCQkJc2V0TWFuYWdlcihuZXcgVGV4dERpcmVjdEVkaXRNYW5hZ2VyMih0aGlzLCBudWxsLAoJCQkJCVJlZmZyYW1ld29ya0VkaXRQYXJ0RmFjdG9yeS5nZXRUZXh0Q2VsbEVkaXRvckxvY2F0b3IodGhpcykpKTsKCQl9CgkJcmV0dXJuIG1hbmFnZXI7Cgl9CgoJLyoqCgkgKiBAZ2VuZXJhdGVkCgkgKi8KCXByb3RlY3RlZCB2b2lkIHNldE1hbmFnZXIoRGlyZWN0RWRpdE1hbmFnZXIgbWFuYWdlcikgewoJCXRoaXMubWFuYWdlciA9IG1hbmFnZXI7Cgl9CgoJLyoqCgkgKiBAZ2VuZXJhdGVkCgkgKi8KCXByb3RlY3RlZCB2b2lkIHBlcmZvcm1EaXJlY3RFZGl0KCkgewoJCWdldE1hbmFnZXIoKS5zaG93KCk7Cgl9CgoJLyoqCgkgKiBAZ2VuZXJhdGVkCgkgKi8KCXByb3RlY3RlZCB2b2lkIHBlcmZvcm1EaXJlY3RFZGl0KFBvaW50IGV2ZW50TG9jYXRpb24pIHsKCQlpZiAoZ2V0TWFuYWdlcigpLmdldENsYXNzKCkgPT0gVGV4dERpcmVjdEVkaXRNYW5hZ2VyMi5jbGFzcykgewoJCQkoKFRleHREaXJlY3RFZGl0TWFuYWdlcjIpIGdldE1hbmFnZXIoKSkuc2hvdyhldmVudExvY2F0aW9uCgkJCQkJLmdldFNXVFBvaW50KCkpOwoJCX0KCX0KCgkvKioKCSAqIEBnZW5lcmF0ZWQKCSAqLwoJcHJpdmF0ZSB2b2lkIHBlcmZvcm1EaXJlY3RFZGl0KGNoYXIgaW5pdGlhbENoYXJhY3RlcikgewoJCWlmIChnZXRNYW5hZ2VyKCkgaW5zdGFuY2VvZiBUZXh0RGlyZWN0RWRpdE1hbmFnZXIpIHsKCQkJKChUZXh0RGlyZWN0RWRpdE1hbmFnZXIpIGdldE1hbmFnZXIoKSkuc2hvdyhpbml0aWFsQ2hhcmFjdGVyKTsKCQl9IGVsc2UgLy8gCgkJaWYgKGdldE1hbmFnZXIoKSBpbnN0YW5jZW9mIFRleHREaXJlY3RFZGl0TWFuYWdlcjIpIHsKCQkJKChUZXh0RGlyZWN0RWRpdE1hbmFnZXIyKSBnZXRNYW5hZ2VyKCkpLnNob3coaW5pdGlhbENoYXJhY3Rlcik7CgkJfSBlbHNlIC8vCgkJewoJCQlwZXJmb3JtRGlyZWN0RWRpdCgpOwoJCX0KCX0KCgkvKioKCSAqIEBnZW5lcmF0ZWQKCSAqLwoJcHJvdGVjdGVkIHZvaWQgcGVyZm9ybURpcmVjdEVkaXRSZXF1ZXN0KFJlcXVlc3QgcmVxdWVzdCkgewoJCWZpbmFsIFJlcXVlc3QgdGhlUmVxdWVzdCA9IHJlcXVlc3Q7CgkJdHJ5IHsKCQkJZ2V0RWRpdGluZ0RvbWFpbigpLnJ1bkV4Y2x1c2l2ZShuZXcgUnVubmFibGUoKSB7CgoJCQkJcHVibGljIHZvaWQgcnVuKCkgewoJCQkJCWlmIChpc0FjdGl2ZSgpICYmIGlzRWRpdGFibGUoKSkgewoJCQkJCQlpZiAodGhlUmVxdWVzdAoJCQkJCQkJCS5nZXRFeHRlbmRlZERhdGEoKQoJCQkJCQkJCS5nZXQoUmVxdWVzdENvbnN0YW50cy5SRVFfRElSRUNURURJVF9FWFRFTkRFRERBVEFfSU5JVElBTF9DSEFSKSBpbnN0YW5jZW9mIENoYXJhY3RlcikgewoJCQkJCQkJQ2hhcmFjdGVyIGluaXRpYWxDaGFyID0gKENoYXJhY3RlcikgdGhlUmVxdWVzdAoJCQkJCQkJCQkuZ2V0RXh0ZW5kZWREYXRhKCkKCQkJCQkJCQkJLmdldChSZXF1ZXN0Q29uc3RhbnRzLlJFUV9ESVJFQ1RFRElUX0VYVEVOREVEREFUQV9JTklUSUFMX0NIQVIpOwoJCQkJCQkJcGVyZm9ybURpcmVjdEVkaXQoaW5pdGlhbENoYXIuY2hhclZhbHVlKCkpOwoJCQkJCQl9IGVsc2UgaWYgKCh0aGVSZXF1ZXN0IGluc3RhbmNlb2YgRGlyZWN0RWRpdFJlcXVlc3QpCgkJCQkJCQkJJiYgKGdldEVkaXRUZXh0KCkuZXF1YWxzKGdldExhYmVsVGV4dCgpKSkpIHsKCQkJCQkJCURpcmVjdEVkaXRSZXF1ZXN0IGVkaXRSZXF1ZXN0ID0gKERpcmVjdEVkaXRSZXF1ZXN0KSB0aGVSZXF1ZXN0OwoJCQkJCQkJcGVyZm9ybURpcmVjdEVkaXQoZWRpdFJlcXVlc3QuZ2V0TG9jYXRpb24oKSk7CgkJCQkJCX0gZWxzZSB7CgkJCQkJCQlwZXJmb3JtRGlyZWN0RWRpdCgpOwoJCQkJCQl9CgkJCQkJfQoJCQkJfQoJCQl9KTsKCQl9IGNhdGNoIChJbnRlcnJ1cHRlZEV4Y2VwdGlvbiBlKSB7CgkJCWUucHJpbnRTdGFja1RyYWNlKCk7CgkJfQoJfQoKCS8qKgoJICogQGdlbmVyYXRlZAoJICovCglwcm90ZWN0ZWQgdm9pZCByZWZyZXNoVmlzdWFscygpIHsKCQlzdXBlci5yZWZyZXNoVmlzdWFscygpOwoJCXJlZnJlc2hMYWJlbCgpOwoJCXJlZnJlc2hGb250KCk7CgkJcmVmcmVzaEZvbnRDb2xvcigpOwoJCXJlZnJlc2hVbmRlcmxpbmUoKTsKCQlyZWZyZXNoU3RyaWtlVGhyb3VnaCgpOwoJfQoKCS8qKgoJICogQGdlbmVyYXRlZAoJICovCglwcm90ZWN0ZWQgdm9pZCByZWZyZXNoTGFiZWwoKSB7CgkJc2V0TGFiZWxUZXh0SGVscGVyKGdldEZpZ3VyZSgpLCBnZXRMYWJlbFRleHQoKSk7CgkJc2V0TGFiZWxJY29uSGVscGVyKGdldEZpZ3VyZSgpLCBnZXRMYWJlbEljb24oKSk7CgkJcmVmcmVzaFNlbGVjdGlvbkZlZWRiYWNrKCk7Cgl9CgoJLyoqCgkgKiBAZ2VuZXJhdGVkCgkgKi8KCXByb3RlY3RlZCB2b2lkIHJlZnJlc2hVbmRlcmxpbmUoKSB7CgkJRm9udFN0eWxlIHN0eWxlID0gKEZvbnRTdHlsZSkgZ2V0Rm9udFN0eWxlT3duZXJWaWV3KCkuZ2V0U3R5bGUoCgkJCQlOb3RhdGlvblBhY2thZ2UuZUlOU1RBTkNFLmdldEZvbnRTdHlsZSgpKTsKCQlpZiAoc3R5bGUgIT0gbnVsbCAmJiBnZXRGaWd1cmUoKSBpbnN0YW5jZW9mIFdyYXBwaW5nTGFiZWwpIHsKCQkJKChXcmFwcGluZ0xhYmVsKSBnZXRGaWd1cmUoKSkuc2V0VGV4dFVuZGVybGluZShzdHlsZS5pc1VuZGVybGluZSgpKTsKCQl9Cgl9CgoJLyoqCgkgKiBAZ2VuZXJhdGVkCgkgKi8KCXByb3RlY3RlZCB2b2lkIHJlZnJlc2hTdHJpa2VUaHJvdWdoKCkgewoJCUZvbnRTdHlsZSBzdHlsZSA9IChGb250U3R5bGUpIGdldEZvbnRTdHlsZU93bmVyVmlldygpLmdldFN0eWxlKAoJCQkJTm90YXRpb25QYWNrYWdlLmVJTlNUQU5DRS5nZXRGb250U3R5bGUoKSk7CgkJaWYgKHN0eWxlICE9IG51bGwgJiYgZ2V0RmlndXJlKCkgaW5zdGFuY2VvZiBXcmFwcGluZ0xhYmVsKSB7CgkJCSgoV3JhcHBpbmdMYWJlbCkgZ2V0RmlndXJlKCkpLnNldFRleHRTdHJpa2VUaHJvdWdoKHN0eWxlCgkJCQkJLmlzU3RyaWtlVGhyb3VnaCgpKTsKCQl9Cgl9CgoJLyoqCgkgKiBAZ2VuZXJhdGVkCgkgKi8KCXByb3RlY3RlZCB2b2lkIHJlZnJlc2hGb250KCkgewoJCUZvbnRTdHlsZSBzdHlsZSA9IChGb250U3R5bGUpIGdldEZvbnRTdHlsZU93bmVyVmlldygpLmdldFN0eWxlKAoJCQkJTm90YXRpb25QYWNrYWdlLmVJTlNUQU5DRS5nZXRGb250U3R5bGUoKSk7CgkJaWYgKHN0eWxlICE9IG51bGwpIHsKCQkJRm9udERhdGEgZm9udERhdGEgPSBuZXcgRm9udERhdGEoc3R5bGUuZ2V0Rm9udE5hbWUoKSwKCQkJCQlzdHlsZS5nZXRGb250SGVpZ2h0KCksIChzdHlsZS5pc0JvbGQoKSA/IFNXVC5CT0xECgkJCQkJCQk6IFNXVC5OT1JNQUwpCgkJCQkJCQl8IChzdHlsZS5pc0l0YWxpYygpID8gU1dULklUQUxJQyA6IFNXVC5OT1JNQUwpKTsKCQkJc2V0Rm9udChmb250RGF0YSk7CgkJfQoJfQoKCS8qKgoJICogQGdlbmVyYXRlZAoJICovCglwcml2YXRlIHZvaWQgcmVmcmVzaFNlbGVjdGlvbkZlZWRiYWNrKCkgewoJCXJlcXVlc3RFZGl0UG9saWN5RmVlZGJhY2tSZWZyZXNoKEVkaXRQb2xpY3kuUFJJTUFSWV9EUkFHX1JPTEUpOwoJCXJlcXVlc3RFZGl0UG9saWN5RmVlZGJhY2tSZWZyZXNoKEVkaXRQb2xpY3kuU0VMRUNUSU9OX0ZFRURCQUNLX1JPTEUpOwoJfQoKCS8qKgoJICogQGdlbmVyYXRlZAoJICovCglwcml2YXRlIHZvaWQgcmVxdWVzdEVkaXRQb2xpY3lGZWVkYmFja1JlZnJlc2goU3RyaW5nIGVkaXRQb2xpY3lLZXkpIHsKCQlPYmplY3QgZWRpdFBvbGljeSA9IGdldEVkaXRQb2xpY3koZWRpdFBvbGljeUtleSk7CgkJaWYgKGVkaXRQb2xpY3kgaW5zdGFuY2VvZiBJUmVmcmVzaGFibGVGZWVkYmFja0VkaXRQb2xpY3kpIHsKCQkJKChJUmVmcmVzaGFibGVGZWVkYmFja0VkaXRQb2xpY3kpIGVkaXRQb2xpY3kpLnJlZnJlc2hGZWVkYmFjaygpOwoJCX0KCX0KCgkvKioKCSAqIEBnZW5lcmF0ZWQKCSAqLwoJcHJvdGVjdGVkIHZvaWQgc2V0Rm9udENvbG9yKENvbG9yIGNvbG9yKSB7CgkJZ2V0RmlndXJlKCkuc2V0Rm9yZWdyb3VuZENvbG9yKGNvbG9yKTsKCX0KCgkvKioKCSAqIEBnZW5lcmF0ZWQKCSAqLwoJcHJvdGVjdGVkIHZvaWQgYWRkU2VtYW50aWNMaXN0ZW5lcnMoKSB7CgkJaWYgKGdldFBhcnNlcigpIGluc3RhbmNlb2YgSVNlbWFudGljUGFyc2VyKSB7CgkJCUVPYmplY3QgZWxlbWVudCA9IHJlc29sdmVTZW1hbnRpY0VsZW1lbnQoKTsKCQkJcGFyc2VyRWxlbWVudHMgPSAoKElTZW1hbnRpY1BhcnNlcikgZ2V0UGFyc2VyKCkpCgkJCQkJLmdldFNlbWFudGljRWxlbWVudHNCZWluZ1BhcnNlZChlbGVtZW50KTsKCQkJZm9yIChpbnQgaSA9IDA7IGkgPCBwYXJzZXJFbGVtZW50cy5zaXplKCk7IGkrKykgewoJCQkJYWRkTGlzdGVuZXJGaWx0ZXIoCgkJCQkJCSJTZW1hbnRpY01vZGVsIiArIGksIHRoaXMsIChFT2JqZWN0KSBwYXJzZXJFbGVtZW50cy5nZXQoaSkpOyAvLyROT04tTkxTLTEkCgkJCX0KCQl9IGVsc2UgewoJCQlzdXBlci5hZGRTZW1hbnRpY0xpc3RlbmVycygpOwoJCX0KCX0KCgkvKioKCSAqIEBnZW5lcmF0ZWQKCSAqLwoJcHJvdGVjdGVkIHZvaWQgcmVtb3ZlU2VtYW50aWNMaXN0ZW5lcnMoKSB7CgkJaWYgKHBhcnNlckVsZW1lbnRzICE9IG51bGwpIHsKCQkJZm9yIChpbnQgaSA9IDA7IGkgPCBwYXJzZXJFbGVtZW50cy5zaXplKCk7IGkrKykgewoJCQkJcmVtb3ZlTGlzdGVuZXJGaWx0ZXIoIlNlbWFudGljTW9kZWwiICsgaSk7IC8vJE5PTi1OTFMtMSQKCQkJfQoJCX0gZWxzZSB7CgkJCXN1cGVyLnJlbW92ZVNlbWFudGljTGlzdGVuZXJzKCk7CgkJfQoJfQoKCS8qKgoJICogQGdlbmVyYXRlZAoJICovCglwcm90ZWN0ZWQgQWNjZXNzaWJsZUVkaXRQYXJ0IGdldEFjY2Vzc2libGVFZGl0UGFydCgpIHsKCQlpZiAoYWNjZXNzaWJsZUVQID09IG51bGwpIHsKCQkJYWNjZXNzaWJsZUVQID0gbmV3IEFjY2Vzc2libGVHcmFwaGljYWxFZGl0UGFydCgpIHsKCgkJCQlwdWJsaWMgdm9pZCBnZXROYW1lKEFjY2Vzc2libGVFdmVudCBlKSB7CgkJCQkJZS5yZXN1bHQgPSBnZXRMYWJlbFRleHRIZWxwZXIoZ2V0RmlndXJlKCkpOwoJCQkJfQoJCQl9OwoJCX0KCQlyZXR1cm4gYWNjZXNzaWJsZUVQOwoJfQoKCS8qKgoJICogQGdlbmVyYXRlZAoJICovCglwcml2YXRlIFZpZXcgZ2V0Rm9udFN0eWxlT3duZXJWaWV3KCkgewoJCXJldHVybiBnZXRQcmltYXJ5VmlldygpOwoJfQoKCS8qKgoJICogQGdlbmVyYXRlZAoJICovCglwcml2YXRlIElMYWJlbERlbGVnYXRlIGdldExhYmVsRGVsZWdhdGUoKSB7CgkJaWYgKGxhYmVsRGVsZWdhdGUgPT0gbnVsbCkgewoJCQlJRmlndXJlIGxhYmVsID0gZ2V0RmlndXJlKCk7CgkJCWlmIChsYWJlbCBpbnN0YW5jZW9mIFdyYXBwaW5nTGFiZWwpIHsKCQkJCWxhYmVsRGVsZWdhdGUgPSBuZXcgV3JhcHBpbmdMYWJlbERlbGVnYXRlKChXcmFwcGluZ0xhYmVsKSBsYWJlbCk7CgkJCX0gZWxzZSB7CgkJCQlsYWJlbERlbGVnYXRlID0gbmV3IFNpbXBsZUxhYmVsRGVsZWdhdGUoKExhYmVsKSBsYWJlbCk7CgkJCX0KCQl9CgkJcmV0dXJuIGxhYmVsRGVsZWdhdGU7Cgl9CgoJLyoqCgkgKiBAZ2VuZXJhdGVkCgkgKi8KCUBPdmVycmlkZQoJcHVibGljIE9iamVjdCBnZXRBZGFwdGVyKENsYXNzIGtleSkgewoJCWlmIChJTGFiZWxEZWxlZ2F0ZS5jbGFzcy5lcXVhbHMoa2V5KSkgewoJCQlyZXR1cm4gZ2V0TGFiZWxEZWxlZ2F0ZSgpOwoJCX0KCQlyZXR1cm4gc3VwZXIuZ2V0QWRhcHRlcihrZXkpOwoJfQoKCS8qKgoJICogQGdlbmVyYXRlZAoJICovCglwcm90ZWN0ZWQgdm9pZCBhZGROb3RhdGlvbmFsTGlzdGVuZXJzKCkgewoJCXN1cGVyLmFkZE5vdGF0aW9uYWxMaXN0ZW5lcnMoKTsKCQlhZGRMaXN0ZW5lckZpbHRlcigiUHJpbWFyeVZpZXciLCB0aGlzLCBnZXRQcmltYXJ5VmlldygpKTsgLy8kTk9OLU5MUy0xJAoJfQoKCS8qKgoJICogQGdlbmVyYXRlZAoJICovCglwcm90ZWN0ZWQgdm9pZCByZW1vdmVOb3RhdGlvbmFsTGlzdGVuZXJzKCkgewoJCXN1cGVyLnJlbW92ZU5vdGF0aW9uYWxMaXN0ZW5lcnMoKTsKCQlyZW1vdmVMaXN0ZW5lckZpbHRlcigiUHJpbWFyeVZpZXciKTsgLy8kTk9OLU5MUy0xJAoJfQoKCS8qKgoJICogQGdlbmVyYXRlZAoJICovCglwcm90ZWN0ZWQgdm9pZCBoYW5kbGVOb3RpZmljYXRpb25FdmVudChOb3RpZmljYXRpb24gZXZlbnQpIHsKCQlPYmplY3QgZmVhdHVyZSA9IGV2ZW50LmdldEZlYXR1cmUoKTsKCQlpZiAoTm90YXRpb25QYWNrYWdlLmVJTlNUQU5DRS5nZXRGb250U3R5bGVfRm9udENvbG9yKCkuZXF1YWxzKGZlYXR1cmUpKSB7CgkJCUludGVnZXIgYyA9IChJbnRlZ2VyKSBldmVudC5nZXROZXdWYWx1ZSgpOwoJCQlzZXRGb250Q29sb3IoRGlhZ3JhbUNvbG9yUmVnaXN0cnkuZ2V0SW5zdGFuY2UoKS5nZXRDb2xvcihjKSk7CgkJfSBlbHNlIGlmIChOb3RhdGlvblBhY2thZ2UuZUlOU1RBTkNFLmdldEZvbnRTdHlsZV9VbmRlcmxpbmUoKS5lcXVhbHMoCgkJCQlmZWF0dXJlKSkgewoJCQlyZWZyZXNoVW5kZXJsaW5lKCk7CgkJfSBlbHNlIGlmIChOb3RhdGlvblBhY2thZ2UuZUlOU1RBTkNFLmdldEZvbnRTdHlsZV9TdHJpa2VUaHJvdWdoKCkKCQkJCS5lcXVhbHMoZmVhdHVyZSkpIHsKCQkJcmVmcmVzaFN0cmlrZVRocm91Z2goKTsKCQl9IGVsc2UgaWYgKE5vdGF0aW9uUGFja2FnZS5lSU5TVEFOQ0UuZ2V0Rm9udFN0eWxlX0ZvbnRIZWlnaHQoKS5lcXVhbHMoCgkJCQlmZWF0dXJlKQoJCQkJfHwgTm90YXRpb25QYWNrYWdlLmVJTlNUQU5DRS5nZXRGb250U3R5bGVfRm9udE5hbWUoKS5lcXVhbHMoCgkJCQkJCWZlYXR1cmUpCgkJCQl8fCBOb3RhdGlvblBhY2thZ2UuZUlOU1RBTkNFLmdldEZvbnRTdHlsZV9Cb2xkKCkKCQkJCQkJLmVxdWFscyhmZWF0dXJlKQoJCQkJfHwgTm90YXRpb25QYWNrYWdlLmVJTlNUQU5DRS5nZXRGb250U3R5bGVfSXRhbGljKCkuZXF1YWxzKAoJCQkJCQlmZWF0dXJlKSkgewoJCQlyZWZyZXNoRm9udCgpOwoJCX0gZWxzZSB7CgkJCWlmIChnZXRQYXJzZXIoKSAhPSBudWxsCgkJCQkJJiYgZ2V0UGFyc2VyKCkuaXNBZmZlY3RpbmdFdmVudChldmVudCwKCQkJCQkJCWdldFBhcnNlck9wdGlvbnMoKS5pbnRWYWx1ZSgpKSkgewoJCQkJcmVmcmVzaExhYmVsKCk7CgkJCX0KCQkJaWYgKGdldFBhcnNlcigpIGluc3RhbmNlb2YgSVNlbWFudGljUGFyc2VyKSB7CgkJCQlJU2VtYW50aWNQYXJzZXIgbW9kZWxQYXJzZXIgPSAoSVNlbWFudGljUGFyc2VyKSBnZXRQYXJzZXIoKTsKCQkJCWlmIChtb2RlbFBhcnNlci5hcmVTZW1hbnRpY0VsZW1lbnRzQWZmZWN0ZWQobnVsbCwgZXZlbnQpKSB7CgkJCQkJcmVtb3ZlU2VtYW50aWNMaXN0ZW5lcnMoKTsKCQkJCQlpZiAocmVzb2x2ZVNlbWFudGljRWxlbWVudCgpICE9IG51bGwpIHsKCQkJCQkJYWRkU2VtYW50aWNMaXN0ZW5lcnMoKTsKCQkJCQl9CgkJCQkJcmVmcmVzaExhYmVsKCk7CgkJCQl9CgkJCX0KCQl9CgkJc3VwZXIuaGFuZGxlTm90aWZpY2F0aW9uRXZlbnQoZXZlbnQpOwoJfQoKCS8qKgoJICogQGdlbmVyYXRlZAoJICovCglwcm90ZWN0ZWQgSUZpZ3VyZSBjcmVhdGVGaWd1cmUoKSB7CgkJLy8gUGFyZW50IHNob3VsZCBhc3NpZ24gb25lIHVzaW5nIHNldExhYmVsKCkgbWV0aG9kCgkJcmV0dXJuIG51bGw7Cgl9Cgp9Cg==