cGFja2FnZSBvcmcuZWNsaXBzZS53c3Quc2VydmVyLnVpLmludGVybmFsLnB1Ymxpc2g7CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBDb3B5cmlnaHQgKGMpIDIwMDMgSUJNIENvcnBvcmF0aW9uIGFuZCBvdGhlcnMuCiAqIEFsbCByaWdodHMgcmVzZXJ2ZWQuIKAgVGhpcyBwcm9ncmFtIGFuZCB0aGUgYWNjb21wYW55aW5nIG1hdGVyaWFscwogKiBhcmUgbWFkZSBhdmFpbGFibGUgdW5kZXIgdGhlIHRlcm1zIG9mIHRoZSBDb21tb24gUHVibGljIExpY2Vuc2UgdjEuMAogKiB3aGljaCBhY2NvbXBhbmllcyB0aGlzIGRpc3RyaWJ1dGlvbiwgYW5kIGlzIGF2YWlsYWJsZSBhdAogKiBodHRwOi8vd3d3LmVjbGlwc2Uub3JnL2xlZ2FsL2NwbC12MTAuaHRtbAqgKgogKiBDb250cmlidXRvcnM6CiAqICAgIElCTSAtIEluaXRpYWwgQVBJIGFuZCBpbXBsZW1lbnRhdGlvbgogKgogKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8KaW1wb3J0IG9yZy5lY2xpcHNlLmpmYWNlLmRpYWxvZ3MuRGlhbG9nOwppbXBvcnQgb3JnLmVjbGlwc2UuamZhY2UuZGlhbG9ncy5JRGlhbG9nQ29uc3RhbnRzOwppbXBvcnQgb3JnLmVjbGlwc2UuamZhY2Uudmlld2Vycy5DaGVja2JveFRhYmxlVmlld2VyOwppbXBvcnQgb3JnLmVjbGlwc2UuamZhY2Uudmlld2Vycy5JTGFiZWxQcm92aWRlckxpc3RlbmVyOwppbXBvcnQgb3JnLmVjbGlwc2UuamZhY2Uudmlld2Vycy5JU3RydWN0dXJlZENvbnRlbnRQcm92aWRlcjsKaW1wb3J0IG9yZy5lY2xpcHNlLmpmYWNlLnZpZXdlcnMuSVRhYmxlTGFiZWxQcm92aWRlcjsKaW1wb3J0IG9yZy5lY2xpcHNlLmpmYWNlLnZpZXdlcnMuVmlld2VyOwppbXBvcnQgb3JnLmVjbGlwc2Uud3N0LnNlcnZlci51aS5pbnRlcm5hbC5Db250ZXh0SWRzOwppbXBvcnQgb3JnLmVjbGlwc2Uud3N0LnNlcnZlci51aS5pbnRlcm5hbC5TZXJ2ZXJVSVBsdWdpbjsKaW1wb3J0IG9yZy5lY2xpcHNlLnN3dC5TV1Q7CmltcG9ydCBvcmcuZWNsaXBzZS5zd3QuZXZlbnRzLlNlbGVjdGlvbkFkYXB0ZXI7CmltcG9ydCBvcmcuZWNsaXBzZS5zd3QuZXZlbnRzLlNlbGVjdGlvbkV2ZW50OwppbXBvcnQgb3JnLmVjbGlwc2Uuc3d0LmdyYXBoaWNzLkltYWdlOwppbXBvcnQgb3JnLmVjbGlwc2Uuc3d0LmxheW91dC5HcmlkRGF0YTsKaW1wb3J0IG9yZy5lY2xpcHNlLnN3dC5sYXlvdXQuR3JpZExheW91dDsKaW1wb3J0IG9yZy5lY2xpcHNlLnN3dC53aWRnZXRzLkNvbXBvc2l0ZTsKaW1wb3J0IG9yZy5lY2xpcHNlLnN3dC53aWRnZXRzLkNvbnRyb2w7CmltcG9ydCBvcmcuZWNsaXBzZS5zd3Qud2lkZ2V0cy5MYWJlbDsKaW1wb3J0IG9yZy5lY2xpcHNlLnN3dC53aWRnZXRzLlNoZWxsOwppbXBvcnQgb3JnLmVjbGlwc2Uuc3d0LndpZGdldHMuVGFibGVJdGVtOwppbXBvcnQgb3JnLmVjbGlwc2UudWkuaGVscC5Xb3JrYmVuY2hIZWxwOwovKioKICogRGlhbG9nIHRvIG1vZGlmeSB0aGUgZmlsdGVyIHVzZWQgaW4gdGhlIHB1Ymxpc2ggdmlld2VyCiAqIG9mIHRoZSB2aXN1YWwgcHVibGlzaGVyLgogKi8KcHVibGljIGNsYXNzIFB1Ymxpc2hWaWV3ZXJGaWx0ZXJEaWFsb2cgZXh0ZW5kcyBEaWFsb2cgewoJcHJvdGVjdGVkIFB1Ymxpc2hWaWV3ZXJGaWx0ZXIgZmlsdGVyOwoJcHJvdGVjdGVkIENoZWNrYm94VGFibGVWaWV3ZXIgdmlld2VyOwoKCXByb3RlY3RlZCBzdGF0aWMgZmluYWwgU3RyaW5nW10gZmlsdGVyU3RyaW5ncyA9IG5ldyBTdHJpbmdbXSB7CgkJU2VydmVyVUlQbHVnaW4uZ2V0UmVzb3VyY2UoIiV3aXpQdWJsaXNoRmlsdGVyVW5wdWJsaXNoZWQiKSwKCQlTZXJ2ZXJVSVBsdWdpbi5nZXRSZXNvdXJjZSgiJXdpelB1Ymxpc2hGaWx0ZXJOZXciKSwKCQlTZXJ2ZXJVSVBsdWdpbi5nZXRSZXNvdXJjZSgiJXdpelB1Ymxpc2hGaWx0ZXJVbm1vZGlmaWVkIiksCgkJU2VydmVyVUlQbHVnaW4uZ2V0UmVzb3VyY2UoIiV3aXpQdWJsaXNoRmlsdGVyTW9kaWZpZWQiKSwKCQlTZXJ2ZXJVSVBsdWdpbi5nZXRSZXNvdXJjZSgiJXdpelB1Ymxpc2hGaWx0ZXJEZWxldGVkIil9OwoKCXByb3RlY3RlZCBzdGF0aWMgZmluYWwgU3RyaW5nW10gZmlsdGVyRGVzY3JpcHRpb25zID0gbmV3IFN0cmluZ1tdIHsKCQlTZXJ2ZXJVSVBsdWdpbi5nZXRSZXNvdXJjZSgiJXdpelB1Ymxpc2hGaWx0ZXJVbnB1Ymxpc2hlZERlc2NyaXB0aW9uIiksCgkJU2VydmVyVUlQbHVnaW4uZ2V0UmVzb3VyY2UoIiV3aXpQdWJsaXNoRmlsdGVyTmV3RGVzY3JpcHRpb24iKSwKCQlTZXJ2ZXJVSVBsdWdpbi5nZXRSZXNvdXJjZSgiJXdpelB1Ymxpc2hGaWx0ZXJVbm1vZGlmaWVkRGVzY3JpcHRpb24iKSwKCQlTZXJ2ZXJVSVBsdWdpbi5nZXRSZXNvdXJjZSgiJXdpelB1Ymxpc2hGaWx0ZXJNb2RpZmllZERlc2NyaXB0aW9uIiksCgkJU2VydmVyVUlQbHVnaW4uZ2V0UmVzb3VyY2UoIiV3aXpQdWJsaXNoRmlsdGVyRGVsZXRlZERlc2NyaXB0aW9uIil9OwoKCXB1YmxpYyBjbGFzcyBGaWx0ZXJMYWJlbFByb3ZpZGVyIGltcGxlbWVudHMgSVRhYmxlTGFiZWxQcm92aWRlciB7CgkJcHVibGljIHZvaWQgYWRkTGlzdGVuZXIoSUxhYmVsUHJvdmlkZXJMaXN0ZW5lciBsaXN0ZW5lcikgeyB9CgkJcHVibGljIHZvaWQgZGlzcG9zZSgpIHsgfQoJCQoJCXB1YmxpYyBJbWFnZSBnZXRDb2x1bW5JbWFnZShPYmplY3QgZWxlbWVudCwgaW50IGNvbHVtbkluZGV4KSB7CgkJCXJldHVybiBudWxsOwoJCX0KCQkKCQlwdWJsaWMgU3RyaW5nIGdldENvbHVtblRleHQoT2JqZWN0IGVsZW1lbnQsIGludCBjb2x1bW5JbmRleCkgewoJCQlyZXR1cm4gZmlsdGVyU3RyaW5nc1soKEludGVnZXIpIGVsZW1lbnQpLmludFZhbHVlKCldOwoJCX0KCQlwdWJsaWMgYm9vbGVhbiBpc0xhYmVsUHJvcGVydHkoT2JqZWN0IGVsZW1lbnQsIFN0cmluZyBwcm9wZXJ0eSkgewoJCQlyZXR1cm4gZmFsc2U7CgkJfQoJCXB1YmxpYyB2b2lkIHJlbW92ZUxpc3RlbmVyKElMYWJlbFByb3ZpZGVyTGlzdGVuZXIgbGlzdGVuZXIpIHsgfQoJfQoJCglwdWJsaWMgY2xhc3MgRmlsdGVyQ29udGVudFByb3ZpZGVyIGltcGxlbWVudHMgSVN0cnVjdHVyZWRDb250ZW50UHJvdmlkZXIgewoJCXB1YmxpYyB2b2lkIGRpc3Bvc2UoKSB7IH0KCQoJCXB1YmxpYyBPYmplY3RbXSBnZXRFbGVtZW50cyhPYmplY3QgZWxlbWVudCkgewoJCQlyZXR1cm4gbmV3IEludGVnZXJbXSB7CgkJCQluZXcgSW50ZWdlcigwKSwgbmV3IEludGVnZXIoMSksIG5ldyBJbnRlZ2VyKDIpLAoJCQkJbmV3IEludGVnZXIoMyksIG5ldyBJbnRlZ2VyKDQpfTsKCQl9CgkKCQlwdWJsaWMgdm9pZCBpbnB1dENoYW5nZWQoVmlld2VyIG5ld1ZpZXdlciwgT2JqZWN0IG9sZElucHV0LCBPYmplY3QgbmV3SW5wdXQpIHsgfQoJfQoKCS8qKgoJICogUHVibGlzaFZpZXdlckZpbHRlckRpYWxvZyBjb25zdHJ1Y3RvciBjb21tZW50LgoJICogQHBhcmFtIHBhcmVudFNoZWxsIG9yZy5lY2xpcHNlLnN3dC53aWRnZXRzLlNoZWxsCgkgKi8KCXB1YmxpYyBQdWJsaXNoVmlld2VyRmlsdGVyRGlhbG9nKFNoZWxsIHBhcmVudFNoZWxsLCBQdWJsaXNoVmlld2VyRmlsdGVyIGZpbHRlcikgewoJCXN1cGVyKHBhcmVudFNoZWxsKTsKCQl0aGlzLmZpbHRlciA9IGZpbHRlcjsKCX0KCgkvKioKCSAqCgkgKi8KCXByb3RlY3RlZCB2b2lkIGNvbmZpZ3VyZVNoZWxsKFNoZWxsIG5ld1NoZWxsKSB7CgkJc3VwZXIuY29uZmlndXJlU2hlbGwobmV3U2hlbGwpOwoJCW5ld1NoZWxsLnNldFRleHQoU2VydmVyVUlQbHVnaW4uZ2V0UmVzb3VyY2UoIiV3aXpQdWJsaXNoRmlsdGVyVGl0bGUiKSk7Cgl9CgoJLyoqCgkgKiBDcmVhdGVzIGFuZCByZXR1cm5zIHRoZSBjb250ZW50cyBvZiB0aGUgdXBwZXIgcGFydCAKCSAqIG9mIHRoaXMgZGlhbG9nIChhYm92ZSB0aGUgYnV0dG9uIGJhcikuCgkgKiA8cD4KCSAqIFRoZSA8Y29kZT5EaWFsb2c8L2NvZGU+IGltcGxlbWVudGF0aW9uIG9mIHRoaXMgZnJhbWV3b3JrIG1ldGhvZAoJICogY3JlYXRlcyBhbmQgcmV0dXJucyBhIG5ldyA8Y29kZT5Db21wb3NpdGU8L2NvZGU+IHdpdGgKCSAqIHN0YW5kYXJkIG1hcmdpbnMgYW5kIHNwYWNpbmcuIFN1YmNsYXNzZXMgc2hvdWxkIG92ZXJyaWRlLgoJICogPC9wPgoJICoKCSAqIEBwYXJhbSB0aGUgcGFyZW50IGNvbXBvc2l0ZSB0byBjb250YWluIHRoZSBkaWFsb2cgYXJlYQoJICogQHJldHVybiB0aGUgZGlhbG9nIGFyZWEgY29udHJvbAoJICovCglwcm90ZWN0ZWQgQ29udHJvbCBjcmVhdGVEaWFsb2dBcmVhKENvbXBvc2l0ZSBwYXJlbnQpIHsKCQkvLyBjcmVhdGUgYSBjb21wb3NpdGUgd2l0aCBzdGFuZGFyZCBtYXJnaW5zIGFuZCBzcGFjaW5nCgkJQ29tcG9zaXRlIGNvbXBvc2l0ZSA9IG5ldyBDb21wb3NpdGUocGFyZW50LCBTV1QuTk9ORSk7CgkJR3JpZExheW91dCBsYXlvdXQgPSBuZXcgR3JpZExheW91dCgpOwoJCWxheW91dC5udW1Db2x1bW5zID0gMTsKCQlsYXlvdXQubWFyZ2luSGVpZ2h0ID0gY29udmVydFZlcnRpY2FsRExVc1RvUGl4ZWxzKElEaWFsb2dDb25zdGFudHMuVkVSVElDQUxfTUFSR0lOKTsKCQlsYXlvdXQubWFyZ2luV2lkdGggPSBjb252ZXJ0SG9yaXpvbnRhbERMVXNUb1BpeGVscyhJRGlhbG9nQ29uc3RhbnRzLkhPUklaT05UQUxfTUFSR0lOKTsKCQlsYXlvdXQudmVydGljYWxTcGFjaW5nID0gY29udmVydFZlcnRpY2FsRExVc1RvUGl4ZWxzKElEaWFsb2dDb25zdGFudHMuVkVSVElDQUxfU1BBQ0lORyk7CgkJbGF5b3V0Lmhvcml6b250YWxTcGFjaW5nID0gY29udmVydEhvcml6b250YWxETFVzVG9QaXhlbHMoSURpYWxvZ0NvbnN0YW50cy5IT1JJWk9OVEFMX1NQQUNJTkcpOwoJCWNvbXBvc2l0ZS5zZXRMYXlvdXQobGF5b3V0KTsKCQljb21wb3NpdGUuc2V0TGF5b3V0RGF0YShuZXcgR3JpZERhdGEoR3JpZERhdGEuRklMTF9CT1RIKSk7CgkJY29tcG9zaXRlLnNldEZvbnQocGFyZW50LmdldEZvbnQoKSk7CgkJV29ya2JlbmNoSGVscC5zZXRIZWxwKGNvbXBvc2l0ZSwgQ29udGV4dElkcy5QVUJMSVNIRVJfRElBTE9HX0ZJTFRFUl9ESUFMT0cpOwoJCgkJTGFiZWwgbGFiZWwgPSBuZXcgTGFiZWwoY29tcG9zaXRlLCBTV1QuTk9ORSk7CgkJbGFiZWwuc2V0VGV4dChTZXJ2ZXJVSVBsdWdpbi5nZXRSZXNvdXJjZSgiJXdpelB1Ymxpc2hGaWx0ZXJNZXNzYWdlIikpOwoJCgkJdmlld2VyID0gQ2hlY2tib3hUYWJsZVZpZXdlci5uZXdDaGVja0xpc3QoY29tcG9zaXRlLCBTV1QuQk9SREVSKTsKCQl2aWV3ZXIuc2V0Q29udGVudFByb3ZpZGVyKG5ldyBGaWx0ZXJDb250ZW50UHJvdmlkZXIoKSk7CgkJdmlld2VyLnNldExhYmVsUHJvdmlkZXIobmV3IEZpbHRlckxhYmVsUHJvdmlkZXIoKSk7CgkJdmlld2VyLnNldElucHV0KCJyb290Iik7CgkJV29ya2JlbmNoSGVscC5zZXRIZWxwKHZpZXdlci5nZXRUYWJsZSgpLCBDb250ZXh0SWRzLlBVQkxJU0hFUl9ESUFMT0dfRklMVEVSX0RJQUxPRyk7CgkKCQlHcmlkRGF0YSBkYXRhID0gbmV3IEdyaWREYXRhKEdyaWREYXRhLkZJTExfSE9SSVpPTlRBTCk7CgkJZGF0YS53aWR0aEhpbnQgPSAyMDA7CgkJZGF0YS5oZWlnaHRIaW50ID0gOTA7CgkJdmlld2VyLmdldFRhYmxlKCkuc2V0TGF5b3V0RGF0YShkYXRhKTsKCQoJCWlmIChmaWx0ZXIuaXNGaWx0ZXJpbmdVbnB1Ymxpc2hhYmxlKCkpCgkJCXZpZXdlci5zZXRDaGVja2VkKG5ldyBJbnRlZ2VyKDApLCB0cnVlKTsKCQlpZiAoZmlsdGVyLmlzRmlsdGVyaW5nTmV3KCkpCgkJCXZpZXdlci5zZXRDaGVja2VkKG5ldyBJbnRlZ2VyKDEpLCB0cnVlKTsKCQlpZiAoZmlsdGVyLmlzRmlsdGVyaW5nVW5tb2RpZmllZCgpKQoJCQl2aWV3ZXIuc2V0Q2hlY2tlZChuZXcgSW50ZWdlcigyKSwgdHJ1ZSk7CgkJaWYgKGZpbHRlci5pc0ZpbHRlcmluZ01vZGlmaWVkKCkpCgkJCXZpZXdlci5zZXRDaGVja2VkKG5ldyBJbnRlZ2VyKDMpLCB0cnVlKTsKCQlpZiAoZmlsdGVyLmlzRmlsdGVyaW5nRGVsZXRlZCgpKQoJCQl2aWV3ZXIuc2V0Q2hlY2tlZChuZXcgSW50ZWdlcig0KSwgdHJ1ZSk7CgkKCQlmaW5hbCBMYWJlbCBkZXNjcmlwdGlvbiA9IG5ldyBMYWJlbChjb21wb3NpdGUsIFNXVC5XUkFQKTsKCQlkZXNjcmlwdGlvbi5zZXRUZXh0KCIgXG4gIik7CgkJZGF0YSA9IG5ldyBHcmlkRGF0YShHcmlkRGF0YS5IT1JJWk9OVEFMX0FMSUdOX0ZJTEwgfCBHcmlkRGF0YS5WRVJUSUNBTF9BTElHTl9GSUxMKTsKCQlkYXRhLmhlaWdodEhpbnQgPSAzNTsKCQlkZXNjcmlwdGlvbi5zZXRMYXlvdXREYXRhKGRhdGEpOwoJCQoJCXZpZXdlci5nZXRUYWJsZSgpLmFkZFNlbGVjdGlvbkxpc3RlbmVyKG5ldyBTZWxlY3Rpb25BZGFwdGVyKCkgewoJCQlwdWJsaWMgdm9pZCB3aWRnZXRTZWxlY3RlZChTZWxlY3Rpb25FdmVudCBldmVudCkgewoJCQkJdHJ5IHsKCQkJCQlUYWJsZUl0ZW0gaXRlbSA9IHZpZXdlci5nZXRUYWJsZSgpLmdldFNlbGVjdGlvbigpWzBdOwoJCQkJCUludGVnZXIgaW4gPSAoSW50ZWdlcikgaXRlbS5nZXREYXRhKCk7CgkJCQkJZGVzY3JpcHRpb24uc2V0VGV4dChmaWx0ZXJEZXNjcmlwdGlvbnNbaW4uaW50VmFsdWUoKV0pOwoJCQkJfSBjYXRjaCAoRXhjZXB0aW9uIGUpIHsKCQkJCQlkZXNjcmlwdGlvbi5zZXRUZXh0KCIiKTsKCQkJCX0KCQkJfQoJCQlwdWJsaWMgdm9pZCB3aWRnZXREZWZhdWx0U2VsZWN0ZWQoU2VsZWN0aW9uRXZlbnQgZXZlbnQpIHsKCQkJfQoJCX0pOwoJCQoJCURpYWxvZy5hcHBseURpYWxvZ0ZvbnQoY29tcG9zaXRlKTsKCQoJCXJldHVybiBjb21wb3NpdGU7Cgl9CgoJLyoqCgkgKiBSZXR1cm4gdGhlIGZpbHRlci4KCSAqCgkgKiBAcmV0dXJuIG9yZy5lY2xpcHNlLndzdC5zZXJ2ZXIudWkuaW50ZXJuYWwucHVibGlzaC5QdWJsaXNoVmlld2VyRmlsdGVyCgkgKi8KCXB1YmxpYyBQdWJsaXNoVmlld2VyRmlsdGVyIGdldEZpbHRlcigpIHsKCQlyZXR1cm4gZmlsdGVyOwoJfQoKCXByb3RlY3RlZCB2b2lkIG9rUHJlc3NlZCgpIHsKCQlmaWx0ZXIuc2V0RmlsdGVyaW5nVW5wdWJsaXNoYWJsZSh2aWV3ZXIuZ2V0Q2hlY2tlZChuZXcgSW50ZWdlcigwKSkpOwoJCWZpbHRlci5zZXRGaWx0ZXJpbmdOZXcodmlld2VyLmdldENoZWNrZWQobmV3IEludGVnZXIoMSkpKTsKCQlmaWx0ZXIuc2V0RmlsdGVyaW5nVW5tb2RpZmllZCh2aWV3ZXIuZ2V0Q2hlY2tlZChuZXcgSW50ZWdlcigyKSkpOwoJCWZpbHRlci5zZXRGaWx0ZXJpbmdNb2RpZmllZCh2aWV3ZXIuZ2V0Q2hlY2tlZChuZXcgSW50ZWdlcigzKSkpOwoJCWZpbHRlci5zZXRGaWx0ZXJpbmdEZWxldGVkKHZpZXdlci5nZXRDaGVja2VkKG5ldyBJbnRlZ2VyKDQpKSk7CgkKCQlzdXBlci5va1ByZXNzZWQoKTsKCX0KfQo=