LyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogQ29weXJpZ2h0IChjKSAyMDE2IEZ1bmRhY2nzbiBUZWNuYWxpYSBSZXNlYXJjaCAmIElubm92YXRpb24uCiAqCiAqIEFsbCByaWdodHMgcmVzZXJ2ZWQuIFRoaXMgcHJvZ3JhbSBhbmQgdGhlIGFjY29tcGFueWluZyBtYXRlcmlhbHMKICogYXJlIG1hZGUgYXZhaWxhYmxlIHVuZGVyIHRoZSB0ZXJtcyBvZiB0aGUgRWNsaXBzZSBQdWJsaWMgTGljZW5zZSB2MS4wCiAqIHdoaWNoIGFjY29tcGFuaWVzIHRoaXMgZGlzdHJpYnV0aW9uLCBhbmQgaXMgYXZhaWxhYmxlIGF0CiAqIGh0dHA6Ly93d3cuZWNsaXBzZS5vcmcvbGVnYWwvZXBsLXYxMC5odG1sCiAqCiAqIENvbnRyaWJ1dG9yczoKICogICBIdWFzY2FyIEVzcGlub3phIC0gaW5pdGlhbCBBUEkgYW5kIGltcGxlbWVudGF0aW9uCiAqICAgQWxlamFuZHJhIFJ17XogLSBpbml0aWFsIEFQSSBhbmQgaW1wbGVtZW50YXRpb24KICogICBJZG95YSBEZWwgUu1vIC0gaW5pdGlhbCBBUEkgYW5kIGltcGxlbWVudGF0aW9uCiAqICAgTWFyaSBDYXJtZW4gUGFsYWNpb3MgLSBpbml0aWFsIEFQSSBhbmQgaW1wbGVtZW50YXRpb24KICogICBBbmdlbCBM83BleiAtIGluaXRpYWwgQVBJIGFuZCBpbXBsZW1lbnRhdGlvbgogKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8KLyoqCiAqIEdlbmVyYXRlZCB3aXRoIEFjY2VsZW8KICovCnBhY2thZ2Ugb3JnLmVjbGlwc2Uub3BlbmNlcnQucGttLnJlZmZyYW1ld29yay5yZWZmcmFtZXdvcmsucGFydHMuaW1wbDsKCi8vIFN0YXJ0IG9mIHVzZXIgY29kZSBmb3IgaW1wb3J0cwppbXBvcnQgamF2YS51dGlsLkFycmF5TGlzdDsKaW1wb3J0IGphdmEudXRpbC5MaXN0OwoKaW1wb3J0IG9yZy5lY2xpcHNlLmVtZi5lY29yZS5FT2JqZWN0OwppbXBvcnQgb3JnLmVjbGlwc2UuZW1mLmVkaXQudWkucHJvdmlkZXIuQWRhcHRlckZhY3RvcnlMYWJlbFByb3ZpZGVyOwppbXBvcnQgb3JnLmVjbGlwc2UuZW1mLmVlZi5ydW50aW1lLmFwaS5jb21wb25lbnQuSVByb3BlcnRpZXNFZGl0aW9uQ29tcG9uZW50OwppbXBvcnQgb3JnLmVjbGlwc2UuZW1mLmVlZi5ydW50aW1lLmFwaS5ub3RpZnkuSVByb3BlcnRpZXNFZGl0aW9uRXZlbnQ7CmltcG9ydCBvcmcuZWNsaXBzZS5lbWYuZWVmLnJ1bnRpbWUuYXBpLnBhcnRzLklTV1RQcm9wZXJ0aWVzRWRpdGlvblBhcnQ7CmltcG9ydCBvcmcuZWNsaXBzZS5lbWYuZWVmLnJ1bnRpbWUuaW1wbC5ub3RpZnkuUHJvcGVydGllc0VkaXRpb25FdmVudDsKaW1wb3J0IG9yZy5lY2xpcHNlLmVtZi5lZWYucnVudGltZS5pbXBsLnBhcnRzLkNvbXBvc2l0ZVByb3BlcnRpZXNFZGl0aW9uUGFydDsKaW1wb3J0IG9yZy5lY2xpcHNlLmVtZi5lZWYucnVudGltZS51aS5wYXJ0cy5QYXJ0Q29tcG9zZXI7CmltcG9ydCBvcmcuZWNsaXBzZS5lbWYuZWVmLnJ1bnRpbWUudWkucGFydHMuc2VxdWVuY2UuQmluZGluZ0NvbXBvc2l0aW9uU2VxdWVuY2U7CmltcG9ydCBvcmcuZWNsaXBzZS5lbWYuZWVmLnJ1bnRpbWUudWkucGFydHMuc2VxdWVuY2UuQ29tcG9zaXRpb25TZXF1ZW5jZTsKaW1wb3J0IG9yZy5lY2xpcHNlLmVtZi5lZWYucnVudGltZS51aS5wYXJ0cy5zZXF1ZW5jZS5Db21wb3NpdGlvblN0ZXA7CmltcG9ydCBvcmcuZWNsaXBzZS5lbWYuZWVmLnJ1bnRpbWUudWkudXRpbHMuRWRpdGluZ1V0aWxzOwppbXBvcnQgb3JnLmVjbGlwc2UuZW1mLmVlZi5ydW50aW1lLnVpLndpZGdldHMuQnV0dG9uc01vZGVFbnVtOwppbXBvcnQgb3JnLmVjbGlwc2UuZW1mLmVlZi5ydW50aW1lLnVpLndpZGdldHMuRU9iamVjdEZsYXRDb21ib1ZpZXdlcjsKaW1wb3J0IG9yZy5lY2xpcHNlLmVtZi5lZWYucnVudGltZS51aS53aWRnZXRzLlJlZmVyZW5jZXNUYWJsZTsKaW1wb3J0IG9yZy5lY2xpcHNlLmVtZi5lZWYucnVudGltZS51aS53aWRnZXRzLlJlZmVyZW5jZXNUYWJsZS5SZWZlcmVuY2VzVGFibGVMaXN0ZW5lcjsKaW1wb3J0IG9yZy5lY2xpcHNlLmVtZi5lZWYucnVudGltZS51aS53aWRnZXRzLlNXVFV0aWxzOwppbXBvcnQgb3JnLmVjbGlwc2UuZW1mLmVlZi5ydW50aW1lLnVpLndpZGdldHMuZW9iamZsYXRjb21iby5FT2JqZWN0RmxhdENvbWJvU2V0dGluZ3M7CmltcG9ydCBvcmcuZWNsaXBzZS5lbWYuZWVmLnJ1bnRpbWUudWkud2lkZ2V0cy5yZWZlcmVuY2VzdGFibGUuUmVmZXJlbmNlc1RhYmxlQ29udGVudFByb3ZpZGVyOwppbXBvcnQgb3JnLmVjbGlwc2UuZW1mLmVlZi5ydW50aW1lLnVpLndpZGdldHMucmVmZXJlbmNlc3RhYmxlLlJlZmVyZW5jZXNUYWJsZVNldHRpbmdzOwppbXBvcnQgb3JnLmVjbGlwc2UuamZhY2Uudmlld2Vycy5BcnJheUNvbnRlbnRQcm92aWRlcjsKaW1wb3J0IG9yZy5lY2xpcHNlLmpmYWNlLnZpZXdlcnMuSUxhYmVsUHJvdmlkZXJMaXN0ZW5lcjsKaW1wb3J0IG9yZy5lY2xpcHNlLmpmYWNlLnZpZXdlcnMuSVNlbGVjdGlvbkNoYW5nZWRMaXN0ZW5lcjsKaW1wb3J0IG9yZy5lY2xpcHNlLmpmYWNlLnZpZXdlcnMuSVN0cnVjdHVyZWRTZWxlY3Rpb247CmltcG9ydCBvcmcuZWNsaXBzZS5qZmFjZS52aWV3ZXJzLklUYWJsZUxhYmVsUHJvdmlkZXI7CmltcG9ydCBvcmcuZWNsaXBzZS5qZmFjZS52aWV3ZXJzLlNlbGVjdGlvbkNoYW5nZWRFdmVudDsKaW1wb3J0IG9yZy5lY2xpcHNlLmpmYWNlLnZpZXdlcnMuU3RydWN0dXJlZFNlbGVjdGlvbjsKaW1wb3J0IG9yZy5lY2xpcHNlLmpmYWNlLnZpZXdlcnMuVGFibGVWaWV3ZXI7CmltcG9ydCBvcmcuZWNsaXBzZS5qZmFjZS52aWV3ZXJzLlZpZXdlckZpbHRlcjsKaW1wb3J0IG9yZy5lY2xpcHNlLnN3dC5TV1Q7CmltcG9ydCBvcmcuZWNsaXBzZS5zd3QuZXZlbnRzLkZvY3VzQWRhcHRlcjsKaW1wb3J0IG9yZy5lY2xpcHNlLnN3dC5ldmVudHMuRm9jdXNFdmVudDsKaW1wb3J0IG9yZy5lY2xpcHNlLnN3dC5ldmVudHMuS2V5QWRhcHRlcjsKaW1wb3J0IG9yZy5lY2xpcHNlLnN3dC5ldmVudHMuS2V5RXZlbnQ7CmltcG9ydCBvcmcuZWNsaXBzZS5zd3QuZXZlbnRzLlNlbGVjdGlvbkFkYXB0ZXI7CmltcG9ydCBvcmcuZWNsaXBzZS5zd3QuZXZlbnRzLlNlbGVjdGlvbkV2ZW50OwppbXBvcnQgb3JnLmVjbGlwc2Uuc3d0LmdyYXBoaWNzLkltYWdlOwppbXBvcnQgb3JnLmVjbGlwc2Uuc3d0LmxheW91dC5HcmlkRGF0YTsKaW1wb3J0IG9yZy5lY2xpcHNlLnN3dC5sYXlvdXQuR3JpZExheW91dDsKaW1wb3J0IG9yZy5lY2xpcHNlLnN3dC53aWRnZXRzLkJ1dHRvbjsKaW1wb3J0IG9yZy5lY2xpcHNlLnN3dC53aWRnZXRzLkNvbXBvc2l0ZTsKaW1wb3J0IG9yZy5lY2xpcHNlLnN3dC53aWRnZXRzLkV2ZW50OwppbXBvcnQgb3JnLmVjbGlwc2Uuc3d0LndpZGdldHMuR3JvdXA7CmltcG9ydCBvcmcuZWNsaXBzZS5zd3Qud2lkZ2V0cy5MYWJlbDsKaW1wb3J0IG9yZy5lY2xpcHNlLnN3dC53aWRnZXRzLkxpc3RlbmVyOwppbXBvcnQgb3JnLmVjbGlwc2Uuc3d0LndpZGdldHMuVGFibGVDb2x1bW47CmltcG9ydCBvcmcuZWNsaXBzZS5zd3Qud2lkZ2V0cy5UZXh0OwppbXBvcnQgb3JnLmVjbGlwc2Uub3BlbmNlcnQucGttLnJlZmZyYW1ld29yay5yZWZmcmFtZXdvcmsuUmVmQXBwbGljYWJpbGl0eUxldmVsOwppbXBvcnQgb3JnLmVjbGlwc2Uub3BlbmNlcnQucGttLnJlZmZyYW1ld29yay5yZWZmcmFtZXdvcmsuUmVmQ3JpdGljYWxpdHlBcHBsaWNhYmlsaXR5OwppbXBvcnQgb3JnLmVjbGlwc2Uub3BlbmNlcnQucGttLnJlZmZyYW1ld29yay5yZWZmcmFtZXdvcmsuUmVmQ3JpdGljYWxpdHlMZXZlbDsKaW1wb3J0IG9yZy5lY2xpcHNlLm9wZW5jZXJ0LnBrbS5yZWZmcmFtZXdvcmsucmVmZnJhbWV3b3JrLnBhcnRzLlJlZkFwcGxpY2FiaWxpdHlQcm9wZXJ0aWVzRWRpdGlvblBhcnQ7CmltcG9ydCBvcmcuZWNsaXBzZS5vcGVuY2VydC5wa20ucmVmZnJhbWV3b3JrLnJlZmZyYW1ld29yay5wYXJ0cy5SZWZmcmFtZXdvcmtWaWV3c1JlcG9zaXRvcnk7CmltcG9ydCBvcmcuZWNsaXBzZS5vcGVuY2VydC5wa20ucmVmZnJhbWV3b3JrLnJlZmZyYW1ld29yay5wcm92aWRlcnMuUmVmZnJhbWV3b3JrTWVzc2FnZXM7CgovLyBFbmQgb2YgdXNlciBjb2RlCgovKioKICogCiAqIAogKi8KcHVibGljIGNsYXNzIFJlZkFwcGxpY2FiaWxpdHlQcm9wZXJ0aWVzRWRpdGlvblBhcnRJbXBsIGV4dGVuZHMgQ29tcG9zaXRlUHJvcGVydGllc0VkaXRpb25QYXJ0IGltcGxlbWVudHMgSVNXVFByb3BlcnRpZXNFZGl0aW9uUGFydCwgUmVmQXBwbGljYWJpbGl0eVByb3BlcnRpZXNFZGl0aW9uUGFydCB7CgoJcHJvdGVjdGVkIFRleHQgaWQ7Cglwcm90ZWN0ZWQgVGV4dCBuYW1lOwoJcHJvdGVjdGVkIFJlZmVyZW5jZXNUYWJsZSBhcHBsaWNDcml0aWM7Cglwcm90ZWN0ZWQgTGlzdDxWaWV3ZXJGaWx0ZXI+IGFwcGxpY0NyaXRpY0J1c2luZXNzRmlsdGVycyA9IG5ldyBBcnJheUxpc3Q8Vmlld2VyRmlsdGVyPigpOwoJcHJvdGVjdGVkIExpc3Q8Vmlld2VyRmlsdGVyPiBhcHBsaWNDcml0aWNGaWx0ZXJzID0gbmV3IEFycmF5TGlzdDxWaWV3ZXJGaWx0ZXI+KCk7Cglwcm90ZWN0ZWQgVGFibGVWaWV3ZXIgYXBwbGljQ3JpdGljVGFibGU7Cglwcm90ZWN0ZWQgTGlzdDxWaWV3ZXJGaWx0ZXI+IGFwcGxpY0NyaXRpY1RhYmxlQnVzaW5lc3NGaWx0ZXJzID0gbmV3IEFycmF5TGlzdDxWaWV3ZXJGaWx0ZXI+KCk7Cglwcm90ZWN0ZWQgTGlzdDxWaWV3ZXJGaWx0ZXI+IGFwcGxpY0NyaXRpY1RhYmxlRmlsdGVycyA9IG5ldyBBcnJheUxpc3Q8Vmlld2VyRmlsdGVyPigpOwoJcHJvdGVjdGVkIEJ1dHRvbiBhZGRBcHBsaWNDcml0aWNUYWJsZTsKCXByb3RlY3RlZCBCdXR0b24gcmVtb3ZlQXBwbGljQ3JpdGljVGFibGU7Cglwcm90ZWN0ZWQgQnV0dG9uIGVkaXRBcHBsaWNDcml0aWNUYWJsZTsKCXByb3RlY3RlZCBUZXh0IGNvbW1lbnRzOwoJcHJvdGVjdGVkIEVPYmplY3RGbGF0Q29tYm9WaWV3ZXIgYXBwbGljVGFyZ2V0OwoJcHJvdGVjdGVkIFJlZmVyZW5jZXNUYWJsZSBvd25lZFJlbDsKCXByb3RlY3RlZCBMaXN0PFZpZXdlckZpbHRlcj4gb3duZWRSZWxCdXNpbmVzc0ZpbHRlcnMgPSBuZXcgQXJyYXlMaXN0PFZpZXdlckZpbHRlcj4oKTsKCXByb3RlY3RlZCBMaXN0PFZpZXdlckZpbHRlcj4gb3duZWRSZWxGaWx0ZXJzID0gbmV3IEFycmF5TGlzdDxWaWV3ZXJGaWx0ZXI+KCk7CgoKCgkvKioKCSAqIERlZmF1bHQgY29uc3RydWN0b3IKCSAqIEBwYXJhbSBlZGl0aW9uQ29tcG9uZW50IHRoZSB7QGxpbmsgSVByb3BlcnRpZXNFZGl0aW9uQ29tcG9uZW50fSB0aGF0IG1hbmFnZSB0aGlzIHBhcnQKCSAqIAoJICovCglwdWJsaWMgUmVmQXBwbGljYWJpbGl0eVByb3BlcnRpZXNFZGl0aW9uUGFydEltcGwoSVByb3BlcnRpZXNFZGl0aW9uQ29tcG9uZW50IGVkaXRpb25Db21wb25lbnQpIHsKCQlzdXBlcihlZGl0aW9uQ29tcG9uZW50KTsKCX0KCgkvKioKCSAqIHtAaW5oZXJpdERvY30KCSAqIAoJICogQHNlZSBvcmcuZWNsaXBzZS5lbWYuZWVmLnJ1bnRpbWUuYXBpLnBhcnRzLklTV1RQcm9wZXJ0aWVzRWRpdGlvblBhcnQjCgkgKiAJCQljcmVhdGVGaWd1cmUob3JnLmVjbGlwc2Uuc3d0LndpZGdldHMuQ29tcG9zaXRlKQoJICogCgkgKi8KCXB1YmxpYyBDb21wb3NpdGUgY3JlYXRlRmlndXJlKGZpbmFsIENvbXBvc2l0ZSBwYXJlbnQpIHsKCQl2aWV3ID0gbmV3IENvbXBvc2l0ZShwYXJlbnQsIFNXVC5OT05FKTsKCQlHcmlkTGF5b3V0IGxheW91dCA9IG5ldyBHcmlkTGF5b3V0KCk7CgkJbGF5b3V0Lm51bUNvbHVtbnMgPSAzOwoJCXZpZXcuc2V0TGF5b3V0KGxheW91dCk7CgkJY3JlYXRlQ29udHJvbHModmlldyk7CgkJcmV0dXJuIHZpZXc7Cgl9CgoJLyoqCgkgKiB7QGluaGVyaXREb2N9CgkgKiAKCSAqIEBzZWUgb3JnLmVjbGlwc2UuZW1mLmVlZi5ydW50aW1lLmFwaS5wYXJ0cy5JU1dUUHJvcGVydGllc0VkaXRpb25QYXJ0IwoJICogCQkJY3JlYXRlQ29udHJvbHMob3JnLmVjbGlwc2Uuc3d0LndpZGdldHMuQ29tcG9zaXRlKQoJICogCgkgKi8KCXB1YmxpYyB2b2lkIGNyZWF0ZUNvbnRyb2xzKENvbXBvc2l0ZSB2aWV3KSB7IAoJCUNvbXBvc2l0aW9uU2VxdWVuY2UgcmVmQXBwbGljYWJpbGl0eVN0ZXAgPSBuZXcgQmluZGluZ0NvbXBvc2l0aW9uU2VxdWVuY2UocHJvcGVydGllc0VkaXRpb25Db21wb25lbnQpOwoJCUNvbXBvc2l0aW9uU3RlcCBwcm9wZXJ0aWVzU3RlcCA9IHJlZkFwcGxpY2FiaWxpdHlTdGVwLmFkZFN0ZXAoUmVmZnJhbWV3b3JrVmlld3NSZXBvc2l0b3J5LlJlZkFwcGxpY2FiaWxpdHkuUHJvcGVydGllcy5jbGFzcyk7CgkJcHJvcGVydGllc1N0ZXAuYWRkU3RlcChSZWZmcmFtZXdvcmtWaWV3c1JlcG9zaXRvcnkuUmVmQXBwbGljYWJpbGl0eS5Qcm9wZXJ0aWVzLmlkKTsKCQlwcm9wZXJ0aWVzU3RlcC5hZGRTdGVwKFJlZmZyYW1ld29ya1ZpZXdzUmVwb3NpdG9yeS5SZWZBcHBsaWNhYmlsaXR5LlByb3BlcnRpZXMubmFtZSk7CgkJLy8gU3RhcnQgSVJSCgkJLy8gcHJvcGVydGllc1N0ZXAuYWRkU3RlcChSZWZmcmFtZXdvcmtWaWV3c1JlcG9zaXRvcnkuUmVmQXBwbGljYWJpbGl0eS5Qcm9wZXJ0aWVzLmFwcGxpY0NyaXRpYyk7CgkJLy8gRW5kIElSUgoJCXByb3BlcnRpZXNTdGVwLmFkZFN0ZXAoUmVmZnJhbWV3b3JrVmlld3NSZXBvc2l0b3J5LlJlZkFwcGxpY2FiaWxpdHkuUHJvcGVydGllcy5hcHBsaWNDcml0aWNUYWJsZSk7CgkJcHJvcGVydGllc1N0ZXAuYWRkU3RlcChSZWZmcmFtZXdvcmtWaWV3c1JlcG9zaXRvcnkuUmVmQXBwbGljYWJpbGl0eS5Qcm9wZXJ0aWVzLmNvbW1lbnRzKTsKCQlwcm9wZXJ0aWVzU3RlcC5hZGRTdGVwKFJlZmZyYW1ld29ya1ZpZXdzUmVwb3NpdG9yeS5SZWZBcHBsaWNhYmlsaXR5LlByb3BlcnRpZXMuYXBwbGljVGFyZ2V0KTsKCQlwcm9wZXJ0aWVzU3RlcC5hZGRTdGVwKFJlZmZyYW1ld29ya1ZpZXdzUmVwb3NpdG9yeS5SZWZBcHBsaWNhYmlsaXR5LlByb3BlcnRpZXMub3duZWRSZWwpOwoJCQoJCQoJCWNvbXBvc2VyID0gbmV3IFBhcnRDb21wb3NlcihyZWZBcHBsaWNhYmlsaXR5U3RlcCkgewoKCQkJQE92ZXJyaWRlCgkJCXB1YmxpYyBDb21wb3NpdGUgYWRkVG9QYXJ0KENvbXBvc2l0ZSBwYXJlbnQsIE9iamVjdCBrZXkpIHsKCQkJCWlmIChrZXkgPT0gUmVmZnJhbWV3b3JrVmlld3NSZXBvc2l0b3J5LlJlZkFwcGxpY2FiaWxpdHkuUHJvcGVydGllcy5jbGFzcykgewoJCQkJCXJldHVybiBjcmVhdGVQcm9wZXJ0aWVzR3JvdXAocGFyZW50KTsKCQkJCX0KCQkJCWlmIChrZXkgPT0gUmVmZnJhbWV3b3JrVmlld3NSZXBvc2l0b3J5LlJlZkFwcGxpY2FiaWxpdHkuUHJvcGVydGllcy5pZCkgewoJCQkJCXJldHVybiBjcmVhdGVJZFRleHQocGFyZW50KTsKCQkJCX0KCQkJCWlmIChrZXkgPT0gUmVmZnJhbWV3b3JrVmlld3NSZXBvc2l0b3J5LlJlZkFwcGxpY2FiaWxpdHkuUHJvcGVydGllcy5uYW1lKSB7CgkJCQkJcmV0dXJuIGNyZWF0ZU5hbWVUZXh0KHBhcmVudCk7CgkJCQl9CgkJCQlpZiAoa2V5ID09IFJlZmZyYW1ld29ya1ZpZXdzUmVwb3NpdG9yeS5SZWZBcHBsaWNhYmlsaXR5LlByb3BlcnRpZXMuYXBwbGljQ3JpdGljKSB7CgkJCQkJcmV0dXJuIGNyZWF0ZUFwcGxpY0NyaXRpY0FkdmFuY2VkVGFibGVDb21wb3NpdGlvbihwYXJlbnQpOwoJCQkJfQoJCQkJaWYgKGtleSA9PSBSZWZmcmFtZXdvcmtWaWV3c1JlcG9zaXRvcnkuUmVmQXBwbGljYWJpbGl0eS5Qcm9wZXJ0aWVzLmFwcGxpY0NyaXRpY1RhYmxlKSB7CgkJCQkJcmV0dXJuIGNyZWF0ZUFwcGxpY0NyaXRpY1RhYmxlVGFibGVDb21wb3NpdGlvbihwYXJlbnQpOwoJCQkJfQoJCQkJaWYgKGtleSA9PSBSZWZmcmFtZXdvcmtWaWV3c1JlcG9zaXRvcnkuUmVmQXBwbGljYWJpbGl0eS5Qcm9wZXJ0aWVzLmNvbW1lbnRzKSB7CgkJCQkJcmV0dXJuIGNyZWF0ZUNvbW1lbnRzVGV4dGFyZWEocGFyZW50KTsKCQkJCX0KCQkJCWlmIChrZXkgPT0gUmVmZnJhbWV3b3JrVmlld3NSZXBvc2l0b3J5LlJlZkFwcGxpY2FiaWxpdHkuUHJvcGVydGllcy5hcHBsaWNUYXJnZXQpIHsKCQkJCQlyZXR1cm4gY3JlYXRlQXBwbGljVGFyZ2V0RmxhdENvbWJvVmlld2VyKHBhcmVudCk7CgkJCQl9CgkJCQlpZiAoa2V5ID09IFJlZmZyYW1ld29ya1ZpZXdzUmVwb3NpdG9yeS5SZWZBcHBsaWNhYmlsaXR5LlByb3BlcnRpZXMub3duZWRSZWwpIHsKCQkJCQlyZXR1cm4gY3JlYXRlT3duZWRSZWxBZHZhbmNlZFRhYmxlQ29tcG9zaXRpb24ocGFyZW50KTsKCQkJCX0KCQkJCXJldHVybiBwYXJlbnQ7CgkJCX0KCQl9OwoJCWNvbXBvc2VyLmNvbXBvc2Uodmlldyk7Cgl9CgoJLyoqCgkgKiAKCSAqLwoJcHJvdGVjdGVkIENvbXBvc2l0ZSBjcmVhdGVQcm9wZXJ0aWVzR3JvdXAoQ29tcG9zaXRlIHBhcmVudCkgewoJCUdyb3VwIHByb3BlcnRpZXNHcm91cCA9IG5ldyBHcm91cChwYXJlbnQsIFNXVC5OT05FKTsKCQlwcm9wZXJ0aWVzR3JvdXAuc2V0VGV4dChSZWZmcmFtZXdvcmtNZXNzYWdlcy5SZWZBcHBsaWNhYmlsaXR5UHJvcGVydGllc0VkaXRpb25QYXJ0X1Byb3BlcnRpZXNHcm91cExhYmVsKTsKCQlHcmlkRGF0YSBwcm9wZXJ0aWVzR3JvdXBEYXRhID0gbmV3IEdyaWREYXRhKEdyaWREYXRhLkZJTExfSE9SSVpPTlRBTCk7CgkJcHJvcGVydGllc0dyb3VwRGF0YS5ob3Jpem9udGFsU3BhbiA9IDM7CgkJcHJvcGVydGllc0dyb3VwLnNldExheW91dERhdGEocHJvcGVydGllc0dyb3VwRGF0YSk7CgkJR3JpZExheW91dCBwcm9wZXJ0aWVzR3JvdXBMYXlvdXQgPSBuZXcgR3JpZExheW91dCgpOwoJCXByb3BlcnRpZXNHcm91cExheW91dC5udW1Db2x1bW5zID0gMzsKCQlwcm9wZXJ0aWVzR3JvdXAuc2V0TGF5b3V0KHByb3BlcnRpZXNHcm91cExheW91dCk7CgkJcmV0dXJuIHByb3BlcnRpZXNHcm91cDsKCX0KCgkKCXByb3RlY3RlZCBDb21wb3NpdGUgY3JlYXRlSWRUZXh0KENvbXBvc2l0ZSBwYXJlbnQpIHsKCQljcmVhdGVEZXNjcmlwdGlvbihwYXJlbnQsIFJlZmZyYW1ld29ya1ZpZXdzUmVwb3NpdG9yeS5SZWZBcHBsaWNhYmlsaXR5LlByb3BlcnRpZXMuaWQsIFJlZmZyYW1ld29ya01lc3NhZ2VzLlJlZkFwcGxpY2FiaWxpdHlQcm9wZXJ0aWVzRWRpdGlvblBhcnRfSWRMYWJlbCk7CgkJaWQgPSBTV1RVdGlscy5jcmVhdGVTY3JvbGxhYmxlVGV4dChwYXJlbnQsIFNXVC5CT1JERVIpOwoJCUdyaWREYXRhIGlkRGF0YSA9IG5ldyBHcmlkRGF0YShHcmlkRGF0YS5GSUxMX0hPUklaT05UQUwpOwoJCWlkLnNldExheW91dERhdGEoaWREYXRhKTsKCQlpZC5hZGRGb2N1c0xpc3RlbmVyKG5ldyBGb2N1c0FkYXB0ZXIoKSB7CgoJCQkvKioKCQkJICoge0Bpbmhlcml0RG9jfQoJCQkgKiAKCQkJICogQHNlZSBvcmcuZWNsaXBzZS5zd3QuZXZlbnRzLkZvY3VzQWRhcHRlciNmb2N1c0xvc3Qob3JnLmVjbGlwc2Uuc3d0LmV2ZW50cy5Gb2N1c0V2ZW50KQoJCQkgKiAKCQkJICovCgkJCUBPdmVycmlkZQoJCQlAU3VwcHJlc3NXYXJuaW5ncygic3ludGhldGljLWFjY2VzcyIpCgkJCXB1YmxpYyB2b2lkIGZvY3VzTG9zdChGb2N1c0V2ZW50IGUpIHsKCQkJCWlmIChwcm9wZXJ0aWVzRWRpdGlvbkNvbXBvbmVudCAhPSBudWxsKQoJCQkJCXByb3BlcnRpZXNFZGl0aW9uQ29tcG9uZW50LmZpcmVQcm9wZXJ0aWVzQ2hhbmdlZChuZXcgUHJvcGVydGllc0VkaXRpb25FdmVudChSZWZBcHBsaWNhYmlsaXR5UHJvcGVydGllc0VkaXRpb25QYXJ0SW1wbC50aGlzLCBSZWZmcmFtZXdvcmtWaWV3c1JlcG9zaXRvcnkuUmVmQXBwbGljYWJpbGl0eS5Qcm9wZXJ0aWVzLmlkLCBQcm9wZXJ0aWVzRWRpdGlvbkV2ZW50LkNPTU1JVCwgUHJvcGVydGllc0VkaXRpb25FdmVudC5TRVQsIG51bGwsIGlkLmdldFRleHQoKSkpOwoJCQl9CgoJCX0pOwoJCWlkLmFkZEtleUxpc3RlbmVyKG5ldyBLZXlBZGFwdGVyKCkgewoKCQkJLyoqCgkJCSAqIHtAaW5oZXJpdERvY30KCQkJICogCgkJCSAqIEBzZWUgb3JnLmVjbGlwc2Uuc3d0LmV2ZW50cy5LZXlBZGFwdGVyI2tleVByZXNzZWQob3JnLmVjbGlwc2Uuc3d0LmV2ZW50cy5LZXlFdmVudCkKCQkJICogCgkJCSAqLwoJCQlAT3ZlcnJpZGUKCQkJQFN1cHByZXNzV2FybmluZ3MoInN5bnRoZXRpYy1hY2Nlc3MiKQoJCQlwdWJsaWMgdm9pZCBrZXlQcmVzc2VkKEtleUV2ZW50IGUpIHsKCQkJCWlmIChlLmNoYXJhY3RlciA9PSBTV1QuQ1IpIHsKCQkJCQlpZiAocHJvcGVydGllc0VkaXRpb25Db21wb25lbnQgIT0gbnVsbCkKCQkJCQkJcHJvcGVydGllc0VkaXRpb25Db21wb25lbnQuZmlyZVByb3BlcnRpZXNDaGFuZ2VkKG5ldyBQcm9wZXJ0aWVzRWRpdGlvbkV2ZW50KFJlZkFwcGxpY2FiaWxpdHlQcm9wZXJ0aWVzRWRpdGlvblBhcnRJbXBsLnRoaXMsIFJlZmZyYW1ld29ya1ZpZXdzUmVwb3NpdG9yeS5SZWZBcHBsaWNhYmlsaXR5LlByb3BlcnRpZXMuaWQsIFByb3BlcnRpZXNFZGl0aW9uRXZlbnQuQ09NTUlULCBQcm9wZXJ0aWVzRWRpdGlvbkV2ZW50LlNFVCwgbnVsbCwgaWQuZ2V0VGV4dCgpKSk7CgkJCQl9CgkJCX0KCgkJfSk7CgkJRWRpdGluZ1V0aWxzLnNldElEKGlkLCBSZWZmcmFtZXdvcmtWaWV3c1JlcG9zaXRvcnkuUmVmQXBwbGljYWJpbGl0eS5Qcm9wZXJ0aWVzLmlkKTsKCQlFZGl0aW5nVXRpbHMuc2V0RUVGdHlwZShpZCwgImVlZjo6VGV4dCIpOyAvLyROT04tTkxTLTEkCgkJU1dUVXRpbHMuY3JlYXRlSGVscEJ1dHRvbihwYXJlbnQsIHByb3BlcnRpZXNFZGl0aW9uQ29tcG9uZW50LmdldEhlbHBDb250ZW50KFJlZmZyYW1ld29ya1ZpZXdzUmVwb3NpdG9yeS5SZWZBcHBsaWNhYmlsaXR5LlByb3BlcnRpZXMuaWQsIFJlZmZyYW1ld29ya1ZpZXdzUmVwb3NpdG9yeS5TV1RfS0lORCksIG51bGwpOyAvLyROT04tTkxTLTEkCgkJLy8gU3RhcnQgb2YgdXNlciBjb2RlIGZvciBjcmVhdGVJZFRleHQKCgkJLy8gRW5kIG9mIHVzZXIgY29kZQoJCXJldHVybiBwYXJlbnQ7Cgl9CgoJCglwcm90ZWN0ZWQgQ29tcG9zaXRlIGNyZWF0ZU5hbWVUZXh0KENvbXBvc2l0ZSBwYXJlbnQpIHsKCQljcmVhdGVEZXNjcmlwdGlvbihwYXJlbnQsIFJlZmZyYW1ld29ya1ZpZXdzUmVwb3NpdG9yeS5SZWZBcHBsaWNhYmlsaXR5LlByb3BlcnRpZXMubmFtZSwgUmVmZnJhbWV3b3JrTWVzc2FnZXMuUmVmQXBwbGljYWJpbGl0eVByb3BlcnRpZXNFZGl0aW9uUGFydF9OYW1lTGFiZWwpOwoJCW5hbWUgPSBTV1RVdGlscy5jcmVhdGVTY3JvbGxhYmxlVGV4dChwYXJlbnQsIFNXVC5CT1JERVIpOwoJCUdyaWREYXRhIG5hbWVEYXRhID0gbmV3IEdyaWREYXRhKEdyaWREYXRhLkZJTExfSE9SSVpPTlRBTCk7CgkJbmFtZS5zZXRMYXlvdXREYXRhKG5hbWVEYXRhKTsKCQluYW1lLmFkZEZvY3VzTGlzdGVuZXIobmV3IEZvY3VzQWRhcHRlcigpIHsKCgkJCS8qKgoJCQkgKiB7QGluaGVyaXREb2N9CgkJCSAqIAoJCQkgKiBAc2VlIG9yZy5lY2xpcHNlLnN3dC5ldmVudHMuRm9jdXNBZGFwdGVyI2ZvY3VzTG9zdChvcmcuZWNsaXBzZS5zd3QuZXZlbnRzLkZvY3VzRXZlbnQpCgkJCSAqIAoJCQkgKi8KCQkJQE92ZXJyaWRlCgkJCUBTdXBwcmVzc1dhcm5pbmdzKCJzeW50aGV0aWMtYWNjZXNzIikKCQkJcHVibGljIHZvaWQgZm9jdXNMb3N0KEZvY3VzRXZlbnQgZSkgewoJCQkJaWYgKHByb3BlcnRpZXNFZGl0aW9uQ29tcG9uZW50ICE9IG51bGwpCgkJCQkJcHJvcGVydGllc0VkaXRpb25Db21wb25lbnQuZmlyZVByb3BlcnRpZXNDaGFuZ2VkKG5ldyBQcm9wZXJ0aWVzRWRpdGlvbkV2ZW50KFJlZkFwcGxpY2FiaWxpdHlQcm9wZXJ0aWVzRWRpdGlvblBhcnRJbXBsLnRoaXMsIFJlZmZyYW1ld29ya1ZpZXdzUmVwb3NpdG9yeS5SZWZBcHBsaWNhYmlsaXR5LlByb3BlcnRpZXMubmFtZSwgUHJvcGVydGllc0VkaXRpb25FdmVudC5DT01NSVQsIFByb3BlcnRpZXNFZGl0aW9uRXZlbnQuU0VULCBudWxsLCBuYW1lLmdldFRleHQoKSkpOwoJCQl9CgoJCX0pOwoJCW5hbWUuYWRkS2V5TGlzdGVuZXIobmV3IEtleUFkYXB0ZXIoKSB7CgoJCQkvKioKCQkJICoge0Bpbmhlcml0RG9jfQoJCQkgKiAKCQkJICogQHNlZSBvcmcuZWNsaXBzZS5zd3QuZXZlbnRzLktleUFkYXB0ZXIja2V5UHJlc3NlZChvcmcuZWNsaXBzZS5zd3QuZXZlbnRzLktleUV2ZW50KQoJCQkgKiAKCQkJICovCgkJCUBPdmVycmlkZQoJCQlAU3VwcHJlc3NXYXJuaW5ncygic3ludGhldGljLWFjY2VzcyIpCgkJCXB1YmxpYyB2b2lkIGtleVByZXNzZWQoS2V5RXZlbnQgZSkgewoJCQkJaWYgKGUuY2hhcmFjdGVyID09IFNXVC5DUikgewoJCQkJCWlmIChwcm9wZXJ0aWVzRWRpdGlvbkNvbXBvbmVudCAhPSBudWxsKQoJCQkJCQlwcm9wZXJ0aWVzRWRpdGlvbkNvbXBvbmVudC5maXJlUHJvcGVydGllc0NoYW5nZWQobmV3IFByb3BlcnRpZXNFZGl0aW9uRXZlbnQoUmVmQXBwbGljYWJpbGl0eVByb3BlcnRpZXNFZGl0aW9uUGFydEltcGwudGhpcywgUmVmZnJhbWV3b3JrVmlld3NSZXBvc2l0b3J5LlJlZkFwcGxpY2FiaWxpdHkuUHJvcGVydGllcy5uYW1lLCBQcm9wZXJ0aWVzRWRpdGlvbkV2ZW50LkNPTU1JVCwgUHJvcGVydGllc0VkaXRpb25FdmVudC5TRVQsIG51bGwsIG5hbWUuZ2V0VGV4dCgpKSk7CgkJCQl9CgkJCX0KCgkJfSk7CgkJRWRpdGluZ1V0aWxzLnNldElEKG5hbWUsIFJlZmZyYW1ld29ya1ZpZXdzUmVwb3NpdG9yeS5SZWZBcHBsaWNhYmlsaXR5LlByb3BlcnRpZXMubmFtZSk7CgkJRWRpdGluZ1V0aWxzLnNldEVFRnR5cGUobmFtZSwgImVlZjo6VGV4dCIpOyAvLyROT04tTkxTLTEkCgkJU1dUVXRpbHMuY3JlYXRlSGVscEJ1dHRvbihwYXJlbnQsIHByb3BlcnRpZXNFZGl0aW9uQ29tcG9uZW50LmdldEhlbHBDb250ZW50KFJlZmZyYW1ld29ya1ZpZXdzUmVwb3NpdG9yeS5SZWZBcHBsaWNhYmlsaXR5LlByb3BlcnRpZXMubmFtZSwgUmVmZnJhbWV3b3JrVmlld3NSZXBvc2l0b3J5LlNXVF9LSU5EKSwgbnVsbCk7IC8vJE5PTi1OTFMtMSQKCQkvLyBTdGFydCBvZiB1c2VyIGNvZGUgZm9yIGNyZWF0ZU5hbWVUZXh0CgoJCS8vIEVuZCBvZiB1c2VyIGNvZGUKCQlyZXR1cm4gcGFyZW50OwoJfQoKCS8qKgoJICogQHBhcmFtIGNvbnRhaW5lcgoJICogCgkgKi8KCXByb3RlY3RlZCBDb21wb3NpdGUgY3JlYXRlQXBwbGljQ3JpdGljQWR2YW5jZWRUYWJsZUNvbXBvc2l0aW9uKENvbXBvc2l0ZSBwYXJlbnQpIHsKCQl0aGlzLmFwcGxpY0NyaXRpYyA9IG5ldyBSZWZlcmVuY2VzVGFibGUoZ2V0RGVzY3JpcHRpb24oUmVmZnJhbWV3b3JrVmlld3NSZXBvc2l0b3J5LlJlZkFwcGxpY2FiaWxpdHkuUHJvcGVydGllcy5hcHBsaWNDcml0aWMsIFJlZmZyYW1ld29ya01lc3NhZ2VzLlJlZkFwcGxpY2FiaWxpdHlQcm9wZXJ0aWVzRWRpdGlvblBhcnRfQXBwbGljQ3JpdGljTGFiZWwpLCBuZXcgUmVmZXJlbmNlc1RhYmxlTGlzdGVuZXIoKSB7CgkJCXB1YmxpYyB2b2lkIGhhbmRsZUFkZCgpIHsgCgkJCQlwcm9wZXJ0aWVzRWRpdGlvbkNvbXBvbmVudC5maXJlUHJvcGVydGllc0NoYW5nZWQobmV3IFByb3BlcnRpZXNFZGl0aW9uRXZlbnQoUmVmQXBwbGljYWJpbGl0eVByb3BlcnRpZXNFZGl0aW9uUGFydEltcGwudGhpcywgUmVmZnJhbWV3b3JrVmlld3NSZXBvc2l0b3J5LlJlZkFwcGxpY2FiaWxpdHkuUHJvcGVydGllcy5hcHBsaWNDcml0aWMsIFByb3BlcnRpZXNFZGl0aW9uRXZlbnQuQ09NTUlULCBQcm9wZXJ0aWVzRWRpdGlvbkV2ZW50LkFERCwgbnVsbCwgbnVsbCkpOwoJCQkJYXBwbGljQ3JpdGljLnJlZnJlc2goKTsKCQkJfQoJCQlwdWJsaWMgdm9pZCBoYW5kbGVFZGl0KEVPYmplY3QgZWxlbWVudCkgewoJCQkJcHJvcGVydGllc0VkaXRpb25Db21wb25lbnQuZmlyZVByb3BlcnRpZXNDaGFuZ2VkKG5ldyBQcm9wZXJ0aWVzRWRpdGlvbkV2ZW50KFJlZkFwcGxpY2FiaWxpdHlQcm9wZXJ0aWVzRWRpdGlvblBhcnRJbXBsLnRoaXMsIFJlZmZyYW1ld29ya1ZpZXdzUmVwb3NpdG9yeS5SZWZBcHBsaWNhYmlsaXR5LlByb3BlcnRpZXMuYXBwbGljQ3JpdGljLCBQcm9wZXJ0aWVzRWRpdGlvbkV2ZW50LkNPTU1JVCwgUHJvcGVydGllc0VkaXRpb25FdmVudC5FRElULCBudWxsLCBlbGVtZW50KSk7CgkJCQlhcHBsaWNDcml0aWMucmVmcmVzaCgpOwoJCQl9CgkJCXB1YmxpYyB2b2lkIGhhbmRsZU1vdmUoRU9iamVjdCBlbGVtZW50LCBpbnQgb2xkSW5kZXgsIGludCBuZXdJbmRleCkgeyAKCQkJCXByb3BlcnRpZXNFZGl0aW9uQ29tcG9uZW50LmZpcmVQcm9wZXJ0aWVzQ2hhbmdlZChuZXcgUHJvcGVydGllc0VkaXRpb25FdmVudChSZWZBcHBsaWNhYmlsaXR5UHJvcGVydGllc0VkaXRpb25QYXJ0SW1wbC50aGlzLCBSZWZmcmFtZXdvcmtWaWV3c1JlcG9zaXRvcnkuUmVmQXBwbGljYWJpbGl0eS5Qcm9wZXJ0aWVzLmFwcGxpY0NyaXRpYywgUHJvcGVydGllc0VkaXRpb25FdmVudC5DT01NSVQsIFByb3BlcnRpZXNFZGl0aW9uRXZlbnQuTU9WRSwgZWxlbWVudCwgbmV3SW5kZXgpKTsKCQkJCWFwcGxpY0NyaXRpYy5yZWZyZXNoKCk7CgkJCX0KCQkJcHVibGljIHZvaWQgaGFuZGxlUmVtb3ZlKEVPYmplY3QgZWxlbWVudCkgeyAKCQkJCXByb3BlcnRpZXNFZGl0aW9uQ29tcG9uZW50LmZpcmVQcm9wZXJ0aWVzQ2hhbmdlZChuZXcgUHJvcGVydGllc0VkaXRpb25FdmVudChSZWZBcHBsaWNhYmlsaXR5UHJvcGVydGllc0VkaXRpb25QYXJ0SW1wbC50aGlzLCBSZWZmcmFtZXdvcmtWaWV3c1JlcG9zaXRvcnkuUmVmQXBwbGljYWJpbGl0eS5Qcm9wZXJ0aWVzLmFwcGxpY0NyaXRpYywgUHJvcGVydGllc0VkaXRpb25FdmVudC5DT01NSVQsIFByb3BlcnRpZXNFZGl0aW9uRXZlbnQuUkVNT1ZFLCBudWxsLCBlbGVtZW50KSk7CgkJCQlhcHBsaWNDcml0aWMucmVmcmVzaCgpOwoJCQl9CgkJCXB1YmxpYyB2b2lkIG5hdmlnYXRlVG8oRU9iamVjdCBlbGVtZW50KSB7IH0KCQl9KTsKCQlmb3IgKFZpZXdlckZpbHRlciBmaWx0ZXIgOiB0aGlzLmFwcGxpY0NyaXRpY0ZpbHRlcnMpIHsKCQkJdGhpcy5hcHBsaWNDcml0aWMuYWRkRmlsdGVyKGZpbHRlcik7CgkJfQoJCXRoaXMuYXBwbGljQ3JpdGljLnNldEhlbHBUZXh0KHByb3BlcnRpZXNFZGl0aW9uQ29tcG9uZW50LmdldEhlbHBDb250ZW50KFJlZmZyYW1ld29ya1ZpZXdzUmVwb3NpdG9yeS5SZWZBcHBsaWNhYmlsaXR5LlByb3BlcnRpZXMuYXBwbGljQ3JpdGljLCBSZWZmcmFtZXdvcmtWaWV3c1JlcG9zaXRvcnkuU1dUX0tJTkQpKTsKCQl0aGlzLmFwcGxpY0NyaXRpYy5jcmVhdGVDb250cm9scyhwYXJlbnQpOwoJCXRoaXMuYXBwbGljQ3JpdGljLmFkZFNlbGVjdGlvbkxpc3RlbmVyKG5ldyBTZWxlY3Rpb25BZGFwdGVyKCkgewoJCQkKCQkJcHVibGljIHZvaWQgd2lkZ2V0U2VsZWN0ZWQoU2VsZWN0aW9uRXZlbnQgZSkgewoJCQkJaWYgKGUuaXRlbSAhPSBudWxsICYmIGUuaXRlbS5nZXREYXRhKCkgaW5zdGFuY2VvZiBFT2JqZWN0KSB7CgkJCQkJcHJvcGVydGllc0VkaXRpb25Db21wb25lbnQuZmlyZVByb3BlcnRpZXNDaGFuZ2VkKG5ldyBQcm9wZXJ0aWVzRWRpdGlvbkV2ZW50KFJlZkFwcGxpY2FiaWxpdHlQcm9wZXJ0aWVzRWRpdGlvblBhcnRJbXBsLnRoaXMsIFJlZmZyYW1ld29ya1ZpZXdzUmVwb3NpdG9yeS5SZWZBcHBsaWNhYmlsaXR5LlByb3BlcnRpZXMuYXBwbGljQ3JpdGljLCBQcm9wZXJ0aWVzRWRpdGlvbkV2ZW50LkNIQU5HRSwgUHJvcGVydGllc0VkaXRpb25FdmVudC5TRUxFQ1RJT05fQ0hBTkdFRCwgbnVsbCwgZS5pdGVtLmdldERhdGEoKSkpOwoJCQkJfQoJCQl9CgkJCQoJCX0pOwoJCUdyaWREYXRhIGFwcGxpY0NyaXRpY0RhdGEgPSBuZXcgR3JpZERhdGEoR3JpZERhdGEuRklMTF9IT1JJWk9OVEFMKTsKCQlhcHBsaWNDcml0aWNEYXRhLmhvcml6b250YWxTcGFuID0gMzsKCQl0aGlzLmFwcGxpY0NyaXRpYy5zZXRMYXlvdXREYXRhKGFwcGxpY0NyaXRpY0RhdGEpOwoJCXRoaXMuYXBwbGljQ3JpdGljLnNldExvd2VyQm91bmQoMCk7CgkJdGhpcy5hcHBsaWNDcml0aWMuc2V0VXBwZXJCb3VuZCgtMSk7CgkJYXBwbGljQ3JpdGljLnNldElEKFJlZmZyYW1ld29ya1ZpZXdzUmVwb3NpdG9yeS5SZWZBcHBsaWNhYmlsaXR5LlByb3BlcnRpZXMuYXBwbGljQ3JpdGljKTsKCQlhcHBsaWNDcml0aWMuc2V0RUVGVHlwZSgiZWVmOjpBZHZhbmNlZFRhYmxlQ29tcG9zaXRpb24iKTsgLy8kTk9OLU5MUy0xJAoJCS8vIFN0YXJ0IG9mIHVzZXIgY29kZSBmb3IgY3JlYXRlQXBwbGljQ3JpdGljQWR2YW5jZWRUYWJsZUNvbXBvc2l0aW9uCgoJCS8vIEVuZCBvZiB1c2VyIGNvZGUKCQlyZXR1cm4gcGFyZW50OwoJfQoKCS8qKgoJICogQHBhcmFtIGNvbnRhaW5lcgoJICogCgkgKi8KCXByb3RlY3RlZCBDb21wb3NpdGUgY3JlYXRlQXBwbGljQ3JpdGljVGFibGVUYWJsZUNvbXBvc2l0aW9uKENvbXBvc2l0ZSBjb250YWluZXIpIHsKCQlDb21wb3NpdGUgdGFibGVDb250YWluZXIgPSBuZXcgQ29tcG9zaXRlKGNvbnRhaW5lciwgU1dULk5PTkUpOwoJCUdyaWRMYXlvdXQgdGFibGVDb250YWluZXJMYXlvdXQgPSBuZXcgR3JpZExheW91dCgpOwoJCUdyaWREYXRhIHRhYmxlQ29udGFpbmVyRGF0YSA9IG5ldyBHcmlkRGF0YShHcmlkRGF0YS5GSUxMX0JPVEgpOwoJCXRhYmxlQ29udGFpbmVyRGF0YS5ob3Jpem9udGFsU3BhbiA9IDM7CgkJdGFibGVDb250YWluZXIuc2V0TGF5b3V0RGF0YSh0YWJsZUNvbnRhaW5lckRhdGEpOwoJCXRhYmxlQ29udGFpbmVyTGF5b3V0Lm51bUNvbHVtbnMgPSAyOwoJCXRhYmxlQ29udGFpbmVyLnNldExheW91dCh0YWJsZUNvbnRhaW5lckxheW91dCk7CgkJb3JnLmVjbGlwc2Uuc3d0LndpZGdldHMuVGFibGUgdGFibGVBcHBsaWNDcml0aWNUYWJsZSA9IG5ldyBvcmcuZWNsaXBzZS5zd3Qud2lkZ2V0cy5UYWJsZSh0YWJsZUNvbnRhaW5lciwgU1dULkZVTExfU0VMRUNUSU9OKTsKCQl0YWJsZUFwcGxpY0NyaXRpY1RhYmxlLnNldEhlYWRlclZpc2libGUodHJ1ZSk7CgkJR3JpZERhdGEgZ2RBcHBsaWNDcml0aWNUYWJsZSA9IG5ldyBHcmlkRGF0YSgpOwoJCWdkQXBwbGljQ3JpdGljVGFibGUuZ3JhYkV4Y2Vzc0hvcml6b250YWxTcGFjZSA9IHRydWU7CgkJZ2RBcHBsaWNDcml0aWNUYWJsZS5ob3Jpem9udGFsQWxpZ25tZW50ID0gR3JpZERhdGEuRklMTDsKCQlnZEFwcGxpY0NyaXRpY1RhYmxlLmdyYWJFeGNlc3NWZXJ0aWNhbFNwYWNlID0gdHJ1ZTsKCQlnZEFwcGxpY0NyaXRpY1RhYmxlLnZlcnRpY2FsQWxpZ25tZW50ID0gR3JpZERhdGEuRklMTDsKCQl0YWJsZUFwcGxpY0NyaXRpY1RhYmxlLnNldExheW91dERhdGEoZ2RBcHBsaWNDcml0aWNUYWJsZSk7CgkJdGFibGVBcHBsaWNDcml0aWNUYWJsZS5zZXRMaW5lc1Zpc2libGUodHJ1ZSk7CgoJCS8vIFN0YXJ0IG9mIHVzZXIgY29kZSBmb3IgY29sdW1ucyBkZWZpbml0aW9uIGZvciBBcHBsaWNDcml0aWNUYWJsZQoJCS8vIFN0YXJ0IElSUgoJCVRhYmxlQ29sdW1uIG5hbWUgPSBuZXcgVGFibGVDb2x1bW4odGFibGVBcHBsaWNDcml0aWNUYWJsZSwgU1dULk5PTkUpOwoJCW5hbWUuc2V0V2lkdGgoMTAwKTsKCQluYW1lLnNldFRleHQoIkNyaXRpY2FsaXR5Iik7IC8vJE5PTi1OTFMtMSQKCQlUYWJsZUNvbHVtbiBuYW1lMSA9IG5ldyBUYWJsZUNvbHVtbih0YWJsZUFwcGxpY0NyaXRpY1RhYmxlLCBTV1QuTk9ORSk7CgkJbmFtZTEuc2V0V2lkdGgoMTAwKTsKCQluYW1lMS5zZXRUZXh0KCJBcHBsaWNhYmlsaXR5Iik7IC8vJE5PTi1OTFMtMSQKCQkvLyBFbmQgSVJSCgkJLy8gRW5kIG9mIHVzZXIgY29kZQoKCQlhcHBsaWNDcml0aWNUYWJsZSA9IG5ldyBUYWJsZVZpZXdlcih0YWJsZUFwcGxpY0NyaXRpY1RhYmxlKTsKCQlhcHBsaWNDcml0aWNUYWJsZS5zZXRDb250ZW50UHJvdmlkZXIobmV3IEFycmF5Q29udGVudFByb3ZpZGVyKCkpOwoJCWFwcGxpY0NyaXRpY1RhYmxlLnNldExhYmVsUHJvdmlkZXIobmV3IElUYWJsZUxhYmVsUHJvdmlkZXIoKSB7CgkJCS8vIFN0YXJ0IG9mIHVzZXIgY29kZSBmb3IgbGFiZWwgcHJvdmlkZXIgZGVmaW5pdGlvbiBmb3IKCQkJLy8gQXBwbGljQ3JpdGljVGFibGUKCQkJcHVibGljIFN0cmluZyBnZXRDb2x1bW5UZXh0KE9iamVjdCBvYmplY3QsIGludCBjb2x1bW5JbmRleCkgewoJCQkJLy8gU3RhcnQgSVJSCgkJCQkvLyBBZGFwdGVyRmFjdG9yeUxhYmVsUHJvdmlkZXIgbGFiZWxQcm92aWRlciA9IG5ldwoJCQkJLy8gQWRhcHRlckZhY3RvcnlMYWJlbFByb3ZpZGVyKGFkYXB0ZXJGYWN0b3J5KTsKCgkJCQkvKgoJCQkJICogaWYgKG9iamVjdCBpbnN0YW5jZW9mIEVPYmplY3QpIHsgc3dpdGNoIChjb2x1bW5JbmRleCkgeyBjYXNlCgkJCQkgKiAwOiByZXR1cm4gbGFiZWxQcm92aWRlci5nZXRUZXh0KG9iamVjdCk7IH0gfQoJCQkJICovCgoJCQkJaWYgKG9iamVjdCBpbnN0YW5jZW9mIEVPYmplY3QpIHsKCgkJCQkJUmVmQ3JpdGljYWxpdHlBcHBsaWNhYmlsaXR5IHJlZkNyaXRBcHBsaSA9IChSZWZDcml0aWNhbGl0eUFwcGxpY2FiaWxpdHkpIG9iamVjdDsKCgkJCQkJc3dpdGNoIChjb2x1bW5JbmRleCkgewoJCQkJCWNhc2UgMDoKCQkJCQkJUmVmQ3JpdGljYWxpdHlMZXZlbCByZWZDcml0aWNhbGl0eUxldmVsID0gcmVmQ3JpdEFwcGxpCgkJCQkJCQkJLmdldENyaXRpY0xldmVsKCk7CgkJCQkJCWlmIChyZWZDcml0aWNhbGl0eUxldmVsICE9IG51bGwpCgkJCQkJCQlyZXR1cm4gcmVmQ3JpdGljYWxpdHlMZXZlbC5nZXRJZCgpOwoJCQkJCWNhc2UgMToKCQkJCQkJLyoKCQkJCQkJICogUmVmQXBwbGljYWJpbGl0eSByZWZBcHBsaWNhYmlsaXR5ID0KCQkJCQkJICogKFJlZkFwcGxpY2FiaWxpdHkpIHJlZkNyaXRBcHBsaS5lQ29udGFpbmVyKCk7CgkJCQkJCSAqIAoJCQkJCQkgKiBpZiAocmVmQXBwbGljYWJpbGl0eS5nZXRBcHBsaWNUYXJnZXQoKSBpbnN0YW5jZW9mCgkJCQkJCSAqIFJlZlJlcXVpcmVtZW50KXsgUmVmQXBwbGljYWJpbGl0eUxldmVsCgkJCQkJCSAqIHJlZkluZGVwZW5kZW5jeUxldmVsID0gKFJlZkFwcGxpY2FiaWxpdHlMZXZlbCkKCQkJCQkJICogcmVmQ3JpdEFwcGxpLmdldEFwcGxpY0xldmVsKCk7IGlmCgkJCQkJCSAqIChyZWZJbmRlcGVuZGVuY3lMZXZlbCAhPSBudWxsKSByZXR1cm4KCQkJCQkJICogcmVmSW5kZXBlbmRlbmN5TGV2ZWwuZ2V0SWQoKTsgfSBlbHNlIGlmCgkJCQkJCSAqIChyZWZBcHBsaWNhYmlsaXR5LmdldEFwcGxpY1RhcmdldCgpIGluc3RhbmNlb2YKCQkJCQkJICogUmVmVGVjaG5pcXVlKXsgUmVmQXBwbGljYWJpbGl0eUxldmVsCgkJCQkJCSAqIHJlZlJlY29tbWVuZGF0aW9uTGV2ZWwgPSAoUmVmQXBwbGljYWJpbGl0eUxldmVsKQoJCQkJCQkgKiByZWZDcml0QXBwbGkuZ2V0QXBwbGljTGV2ZWwoKTsgaWYKCQkJCQkJICogKHJlZlJlY29tbWVuZGF0aW9uTGV2ZWwgIT0gbnVsbCkgcmV0dXJuCgkJCQkJCSAqIHJlZlJlY29tbWVuZGF0aW9uTGV2ZWwuZ2V0SWQoKTsgfSBlbHNlIGlmCgkJCQkJCSAqIChyZWZBcHBsaWNhYmlsaXR5LmdldEFwcGxpY1RhcmdldCgpIGluc3RhbmNlb2YKCQkJCQkJICogUmVmQXJ0ZWZhY3QpeyBSZWZBcHBsaWNhYmlsaXR5TGV2ZWwKCQkJCQkJICogcmVmQ29udHJvbENhdGVnb3J5ID0gKFJlZkFwcGxpY2FiaWxpdHlMZXZlbCkKCQkJCQkJICogcmVmQ3JpdEFwcGxpLmdldEFwcGxpY0xldmVsKCk7IGlmIChyZWZDb250cm9sQ2F0ZWdvcnkKCQkJCQkJICogIT0gbnVsbCkgcmV0dXJuIHJlZkNvbnRyb2xDYXRlZ29yeS5nZXRJZCgpOyB9IGVsc2UgewoJCQkJCQkgKiByZXR1cm4gIiI7IH0KCQkJCQkJICovCgoJCQkJCQlSZWZBcHBsaWNhYmlsaXR5TGV2ZWwgcmVmYXBwID0gKFJlZkFwcGxpY2FiaWxpdHlMZXZlbCkgcmVmQ3JpdEFwcGxpCgkJCQkJCQkJLmdldEFwcGxpY0xldmVsKCk7CgkJCQkJCWlmIChyZWZhcHAgIT0gbnVsbCkKCQkJCQkJCXJldHVybiByZWZhcHAuZ2V0SWQoKTsKCQkJCQkJZWxzZQoJCQkJCQkJcmV0dXJuICIiOwoJCQkJCX0gLy8gRW5kIHN3aXRjaAoKCQkJCX0KCgkJCQkvLyBFbmQgSVJSCgkJCQlyZXR1cm4gIiI7IC8vJE5PTi1OTFMtMSQKCQkJfQoJCQkKCQkJCQkJcHVibGljIEltYWdlIGdldENvbHVtbkltYWdlKE9iamVjdCBlbGVtZW50LCBpbnQgY29sdW1uSW5kZXgpIHsKCQkJCQkJCXJldHVybiBudWxsOwoJCQkJCQl9CgkJCQoJCQkvL0VuZCBvZiB1c2VyIGNvZGUKCgkJCXB1YmxpYyB2b2lkIGFkZExpc3RlbmVyKElMYWJlbFByb3ZpZGVyTGlzdGVuZXIgbGlzdGVuZXIpIHsKCQkJfQoKCQkJcHVibGljIHZvaWQgZGlzcG9zZSgpIHsKCQkJfQoKCQkJcHVibGljIGJvb2xlYW4gaXNMYWJlbFByb3BlcnR5KE9iamVjdCBlbGVtZW50LCBTdHJpbmcgcHJvcGVydHkpIHsKCQkJCXJldHVybiBmYWxzZTsKCQkJfQoKCQkJcHVibGljIHZvaWQgcmVtb3ZlTGlzdGVuZXIoSUxhYmVsUHJvdmlkZXJMaXN0ZW5lciBsaXN0ZW5lcikgewoJCQl9CgoJCX0pOwoJCWFwcGxpY0NyaXRpY1RhYmxlLmdldFRhYmxlKCkuYWRkTGlzdGVuZXIoU1dULk1vdXNlRG91YmxlQ2xpY2ssIG5ldyBMaXN0ZW5lcigpewoKCQkJcHVibGljIHZvaWQgaGFuZGxlRXZlbnQoRXZlbnQgZXZlbnQpIHsKCQkJCWlmIChhcHBsaWNDcml0aWNUYWJsZS5nZXRTZWxlY3Rpb24oKSBpbnN0YW5jZW9mIElTdHJ1Y3R1cmVkU2VsZWN0aW9uKSB7CgkJCQkJSVN0cnVjdHVyZWRTZWxlY3Rpb24gc2VsZWN0aW9uID0gKElTdHJ1Y3R1cmVkU2VsZWN0aW9uKSBhcHBsaWNDcml0aWNUYWJsZS5nZXRTZWxlY3Rpb24oKTsKCQkJCQlpZiAoc2VsZWN0aW9uLmdldEZpcnN0RWxlbWVudCgpIGluc3RhbmNlb2YgRU9iamVjdCkgewoJCQkJCQlwcm9wZXJ0aWVzRWRpdGlvbkNvbXBvbmVudC5maXJlUHJvcGVydGllc0NoYW5nZWQobmV3IFByb3BlcnRpZXNFZGl0aW9uRXZlbnQoUmVmQXBwbGljYWJpbGl0eVByb3BlcnRpZXNFZGl0aW9uUGFydEltcGwudGhpcywgUmVmZnJhbWV3b3JrVmlld3NSZXBvc2l0b3J5LlJlZkFwcGxpY2FiaWxpdHkuUHJvcGVydGllcy5hcHBsaWNDcml0aWNUYWJsZSwgUHJvcGVydGllc0VkaXRpb25FdmVudC5DT01NSVQsIFByb3BlcnRpZXNFZGl0aW9uRXZlbnQuRURJVCwgbnVsbCwgc2VsZWN0aW9uLmdldEZpcnN0RWxlbWVudCgpKSk7CgkJCQkJCWFwcGxpY0NyaXRpY1RhYmxlLnJlZnJlc2goKTsKCQkJCQl9CgkJCQl9CgkJCX0KCgkJfSk7CgkJR3JpZERhdGEgYXBwbGljQ3JpdGljVGFibGVEYXRhID0gbmV3IEdyaWREYXRhKEdyaWREYXRhLkZJTExfSE9SSVpPTlRBTCk7CgkJYXBwbGljQ3JpdGljVGFibGVEYXRhLm1pbmltdW1IZWlnaHQgPSAxMjA7CgkJYXBwbGljQ3JpdGljVGFibGVEYXRhLmhlaWdodEhpbnQgPSAxMjA7CgkJYXBwbGljQ3JpdGljVGFibGUuZ2V0VGFibGUoKS5zZXRMYXlvdXREYXRhKGFwcGxpY0NyaXRpY1RhYmxlRGF0YSk7CgkJZm9yIChWaWV3ZXJGaWx0ZXIgZmlsdGVyIDogdGhpcy5hcHBsaWNDcml0aWNUYWJsZUZpbHRlcnMpIHsKCQkJYXBwbGljQ3JpdGljVGFibGUuYWRkRmlsdGVyKGZpbHRlcik7CgkJfQoJCUVkaXRpbmdVdGlscy5zZXRJRChhcHBsaWNDcml0aWNUYWJsZS5nZXRUYWJsZSgpLCBSZWZmcmFtZXdvcmtWaWV3c1JlcG9zaXRvcnkuUmVmQXBwbGljYWJpbGl0eS5Qcm9wZXJ0aWVzLmFwcGxpY0NyaXRpY1RhYmxlKTsKCQlFZGl0aW5nVXRpbHMuc2V0RUVGdHlwZShhcHBsaWNDcml0aWNUYWJsZS5nZXRUYWJsZSgpLCAiZWVmOjpUYWJsZUNvbXBvc2l0aW9uOjpmaWVsZCIpOyAvLyROT04tTkxTLTEkCgkJY3JlYXRlQXBwbGljQ3JpdGljVGFibGVQYW5lbCh0YWJsZUNvbnRhaW5lcik7CgkJLy8gU3RhcnQgb2YgdXNlciBjb2RlIGZvciBjcmVhdGVBcHBsaWNDcml0aWNUYWJsZVRhYmxlQ29tcG9zaXRpb24KCgkJLy8gRW5kIG9mIHVzZXIgY29kZQoJCXJldHVybiBjb250YWluZXI7Cgl9CgoJLyoqCgkgKiBAcGFyYW0gY29udGFpbmVyCgkgKiAKCSAqLwoJcHJvdGVjdGVkIENvbXBvc2l0ZSBjcmVhdGVBcHBsaWNDcml0aWNUYWJsZVBhbmVsKENvbXBvc2l0ZSBjb250YWluZXIpIHsKCQlDb21wb3NpdGUgYXBwbGljQ3JpdGljVGFibGVQYW5lbCA9IG5ldyBDb21wb3NpdGUoY29udGFpbmVyLCBTV1QuTk9ORSk7CgkJR3JpZExheW91dCBhcHBsaWNDcml0aWNUYWJsZVBhbmVsTGF5b3V0ID0gbmV3IEdyaWRMYXlvdXQoKTsKCQlhcHBsaWNDcml0aWNUYWJsZVBhbmVsTGF5b3V0Lm51bUNvbHVtbnMgPSAxOwoJCWFwcGxpY0NyaXRpY1RhYmxlUGFuZWwuc2V0TGF5b3V0KGFwcGxpY0NyaXRpY1RhYmxlUGFuZWxMYXlvdXQpOwoJCWFkZEFwcGxpY0NyaXRpY1RhYmxlID0gbmV3IEJ1dHRvbihhcHBsaWNDcml0aWNUYWJsZVBhbmVsLCBTV1QuTk9ORSk7CgkJYWRkQXBwbGljQ3JpdGljVGFibGUuc2V0VGV4dChSZWZmcmFtZXdvcmtNZXNzYWdlcy5Qcm9wZXJ0aWVzRWRpdGlvblBhcnRfQWRkVGFibGVWaWV3ZXJMYWJlbCk7CgkJR3JpZERhdGEgYWRkQXBwbGljQ3JpdGljVGFibGVEYXRhID0gbmV3IEdyaWREYXRhKEdyaWREYXRhLkZJTExfSE9SSVpPTlRBTCk7CgkJYWRkQXBwbGljQ3JpdGljVGFibGUuc2V0TGF5b3V0RGF0YShhZGRBcHBsaWNDcml0aWNUYWJsZURhdGEpOwoJCWFkZEFwcGxpY0NyaXRpY1RhYmxlLmFkZFNlbGVjdGlvbkxpc3RlbmVyKG5ldyBTZWxlY3Rpb25BZGFwdGVyKCkgewoKCQkJLyoqCgkJCSAqIHtAaW5oZXJpdERvY30KCQkJICogCgkJCSAqIEBzZWUgb3JnLmVjbGlwc2Uuc3d0LmV2ZW50cy5TZWxlY3Rpb25BZGFwdGVyI3dpZGdldFNlbGVjdGVkKG9yZy5lY2xpcHNlLnN3dC5ldmVudHMuU2VsZWN0aW9uRXZlbnQpCgkJCSAqIAoJCQkgKi8KCQkJcHVibGljIHZvaWQgd2lkZ2V0U2VsZWN0ZWQoU2VsZWN0aW9uRXZlbnQgZSkgewoJCQkJcHJvcGVydGllc0VkaXRpb25Db21wb25lbnQuZmlyZVByb3BlcnRpZXNDaGFuZ2VkKG5ldyBQcm9wZXJ0aWVzRWRpdGlvbkV2ZW50KFJlZkFwcGxpY2FiaWxpdHlQcm9wZXJ0aWVzRWRpdGlvblBhcnRJbXBsLnRoaXMsIFJlZmZyYW1ld29ya1ZpZXdzUmVwb3NpdG9yeS5SZWZBcHBsaWNhYmlsaXR5LlByb3BlcnRpZXMuYXBwbGljQ3JpdGljVGFibGUsIFByb3BlcnRpZXNFZGl0aW9uRXZlbnQuQ09NTUlULCBQcm9wZXJ0aWVzRWRpdGlvbkV2ZW50LkFERCwgbnVsbCwgbnVsbCkpOwoJCQkJYXBwbGljQ3JpdGljVGFibGUucmVmcmVzaCgpOwoJCQl9CgkJfSk7CgkJRWRpdGluZ1V0aWxzLnNldElEKGFkZEFwcGxpY0NyaXRpY1RhYmxlLCBSZWZmcmFtZXdvcmtWaWV3c1JlcG9zaXRvcnkuUmVmQXBwbGljYWJpbGl0eS5Qcm9wZXJ0aWVzLmFwcGxpY0NyaXRpY1RhYmxlKTsKCQlFZGl0aW5nVXRpbHMuc2V0RUVGdHlwZShhZGRBcHBsaWNDcml0aWNUYWJsZSwgImVlZjo6VGFibGVDb21wb3NpdGlvbjo6YWRkYnV0dG9uIik7IC8vJE5PTi1OTFMtMSQKCQlyZW1vdmVBcHBsaWNDcml0aWNUYWJsZSA9IG5ldyBCdXR0b24oYXBwbGljQ3JpdGljVGFibGVQYW5lbCwgU1dULk5PTkUpOwoJCXJlbW92ZUFwcGxpY0NyaXRpY1RhYmxlLnNldFRleHQoUmVmZnJhbWV3b3JrTWVzc2FnZXMuUHJvcGVydGllc0VkaXRpb25QYXJ0X1JlbW92ZVRhYmxlVmlld2VyTGFiZWwpOwoJCUdyaWREYXRhIHJlbW92ZUFwcGxpY0NyaXRpY1RhYmxlRGF0YSA9IG5ldyBHcmlkRGF0YShHcmlkRGF0YS5GSUxMX0hPUklaT05UQUwpOwoJCXJlbW92ZUFwcGxpY0NyaXRpY1RhYmxlLnNldExheW91dERhdGEocmVtb3ZlQXBwbGljQ3JpdGljVGFibGVEYXRhKTsKCQlyZW1vdmVBcHBsaWNDcml0aWNUYWJsZS5hZGRTZWxlY3Rpb25MaXN0ZW5lcihuZXcgU2VsZWN0aW9uQWRhcHRlcigpIHsKCgkJCS8qKgoJCQkgKiB7QGluaGVyaXREb2N9CgkJCSAqIAoJCQkgKiBAc2VlIG9yZy5lY2xpcHNlLnN3dC5ldmVudHMuU2VsZWN0aW9uQWRhcHRlciN3aWRnZXRTZWxlY3RlZChvcmcuZWNsaXBzZS5zd3QuZXZlbnRzLlNlbGVjdGlvbkV2ZW50KQoJCQkgKiAKCQkJICovCgkJCXB1YmxpYyB2b2lkIHdpZGdldFNlbGVjdGVkKFNlbGVjdGlvbkV2ZW50IGUpIHsKCQkJCWlmIChhcHBsaWNDcml0aWNUYWJsZS5nZXRTZWxlY3Rpb24oKSBpbnN0YW5jZW9mIElTdHJ1Y3R1cmVkU2VsZWN0aW9uKSB7CgkJCQkJSVN0cnVjdHVyZWRTZWxlY3Rpb24gc2VsZWN0aW9uID0gKElTdHJ1Y3R1cmVkU2VsZWN0aW9uKSBhcHBsaWNDcml0aWNUYWJsZS5nZXRTZWxlY3Rpb24oKTsKCQkJCQlpZiAoc2VsZWN0aW9uLmdldEZpcnN0RWxlbWVudCgpIGluc3RhbmNlb2YgRU9iamVjdCkgewoJCQkJCQlFT2JqZWN0IHNlbGVjdGVkRWxlbWVudCA9IChFT2JqZWN0KSBzZWxlY3Rpb24uZ2V0Rmlyc3RFbGVtZW50KCk7CgkJCQkJCXByb3BlcnRpZXNFZGl0aW9uQ29tcG9uZW50LmZpcmVQcm9wZXJ0aWVzQ2hhbmdlZChuZXcgUHJvcGVydGllc0VkaXRpb25FdmVudChSZWZBcHBsaWNhYmlsaXR5UHJvcGVydGllc0VkaXRpb25QYXJ0SW1wbC50aGlzLCBSZWZmcmFtZXdvcmtWaWV3c1JlcG9zaXRvcnkuUmVmQXBwbGljYWJpbGl0eS5Qcm9wZXJ0aWVzLmFwcGxpY0NyaXRpY1RhYmxlLCBQcm9wZXJ0aWVzRWRpdGlvbkV2ZW50LkNIQU5HRSwgUHJvcGVydGllc0VkaXRpb25FdmVudC5SRU1PVkUsIG51bGwsIHNlbGVjdGVkRWxlbWVudCkpOwoJCQkJCQlhcHBsaWNDcml0aWNUYWJsZS5yZWZyZXNoKCk7CgkJCQkJfQoJCQkJfQoJCQl9CgoJCX0pOwoJCUVkaXRpbmdVdGlscy5zZXRJRChyZW1vdmVBcHBsaWNDcml0aWNUYWJsZSwgUmVmZnJhbWV3b3JrVmlld3NSZXBvc2l0b3J5LlJlZkFwcGxpY2FiaWxpdHkuUHJvcGVydGllcy5hcHBsaWNDcml0aWNUYWJsZSk7CgkJRWRpdGluZ1V0aWxzLnNldEVFRnR5cGUocmVtb3ZlQXBwbGljQ3JpdGljVGFibGUsICJlZWY6OlRhYmxlQ29tcG9zaXRpb246OnJlbW92ZWJ1dHRvbiIpOyAvLyROT04tTkxTLTEkCgkJZWRpdEFwcGxpY0NyaXRpY1RhYmxlID0gbmV3IEJ1dHRvbihhcHBsaWNDcml0aWNUYWJsZVBhbmVsLCBTV1QuTk9ORSk7CgkJZWRpdEFwcGxpY0NyaXRpY1RhYmxlLnNldFRleHQoUmVmZnJhbWV3b3JrTWVzc2FnZXMuUHJvcGVydGllc0VkaXRpb25QYXJ0X0VkaXRUYWJsZVZpZXdlckxhYmVsKTsKCQlHcmlkRGF0YSBlZGl0QXBwbGljQ3JpdGljVGFibGVEYXRhID0gbmV3IEdyaWREYXRhKEdyaWREYXRhLkZJTExfSE9SSVpPTlRBTCk7CgkJZWRpdEFwcGxpY0NyaXRpY1RhYmxlLnNldExheW91dERhdGEoZWRpdEFwcGxpY0NyaXRpY1RhYmxlRGF0YSk7CgkJZWRpdEFwcGxpY0NyaXRpY1RhYmxlLmFkZFNlbGVjdGlvbkxpc3RlbmVyKG5ldyBTZWxlY3Rpb25BZGFwdGVyKCkgewoKCQkJLyoqCgkJCSAqIHtAaW5oZXJpdERvY30KCQkJICogCgkJCSAqIEBzZWUgb3JnLmVjbGlwc2Uuc3d0LmV2ZW50cy5TZWxlY3Rpb25BZGFwdGVyI3dpZGdldFNlbGVjdGVkKG9yZy5lY2xpcHNlLnN3dC5ldmVudHMuU2VsZWN0aW9uRXZlbnQpCgkJCSAqIAoJCQkgKi8KCQkJcHVibGljIHZvaWQgd2lkZ2V0U2VsZWN0ZWQoU2VsZWN0aW9uRXZlbnQgZSkgewoJCQkJaWYgKGFwcGxpY0NyaXRpY1RhYmxlLmdldFNlbGVjdGlvbigpIGluc3RhbmNlb2YgSVN0cnVjdHVyZWRTZWxlY3Rpb24pIHsKCQkJCQlJU3RydWN0dXJlZFNlbGVjdGlvbiBzZWxlY3Rpb24gPSAoSVN0cnVjdHVyZWRTZWxlY3Rpb24pIGFwcGxpY0NyaXRpY1RhYmxlLmdldFNlbGVjdGlvbigpOwoJCQkJCWlmIChzZWxlY3Rpb24uZ2V0Rmlyc3RFbGVtZW50KCkgaW5zdGFuY2VvZiBFT2JqZWN0KSB7CgkJCQkJCXByb3BlcnRpZXNFZGl0aW9uQ29tcG9uZW50LmZpcmVQcm9wZXJ0aWVzQ2hhbmdlZChuZXcgUHJvcGVydGllc0VkaXRpb25FdmVudChSZWZBcHBsaWNhYmlsaXR5UHJvcGVydGllc0VkaXRpb25QYXJ0SW1wbC50aGlzLCBSZWZmcmFtZXdvcmtWaWV3c1JlcG9zaXRvcnkuUmVmQXBwbGljYWJpbGl0eS5Qcm9wZXJ0aWVzLmFwcGxpY0NyaXRpY1RhYmxlLCBQcm9wZXJ0aWVzRWRpdGlvbkV2ZW50LkNPTU1JVCwgUHJvcGVydGllc0VkaXRpb25FdmVudC5FRElULCBudWxsLCBzZWxlY3Rpb24uZ2V0Rmlyc3RFbGVtZW50KCkpKTsKCQkJCQkJYXBwbGljQ3JpdGljVGFibGUucmVmcmVzaCgpOwoJCQkJCX0KCQkJCX0KCQkJfQoKCQl9KTsKCQlFZGl0aW5nVXRpbHMuc2V0SUQoZWRpdEFwcGxpY0NyaXRpY1RhYmxlLCBSZWZmcmFtZXdvcmtWaWV3c1JlcG9zaXRvcnkuUmVmQXBwbGljYWJpbGl0eS5Qcm9wZXJ0aWVzLmFwcGxpY0NyaXRpY1RhYmxlKTsKCQlFZGl0aW5nVXRpbHMuc2V0RUVGdHlwZShlZGl0QXBwbGljQ3JpdGljVGFibGUsICJlZWY6OlRhYmxlQ29tcG9zaXRpb246OmVkaXRidXR0b24iKTsgLy8kTk9OLU5MUy0xJAoJCS8vIFN0YXJ0IG9mIHVzZXIgY29kZSBmb3IgY3JlYXRlQXBwbGljQ3JpdGljVGFibGVQYW5lbAoKCQkvLyBFbmQgb2YgdXNlciBjb2RlCgkJcmV0dXJuIGFwcGxpY0NyaXRpY1RhYmxlUGFuZWw7Cgl9CgoJCglwcm90ZWN0ZWQgQ29tcG9zaXRlIGNyZWF0ZUNvbW1lbnRzVGV4dGFyZWEoQ29tcG9zaXRlIHBhcmVudCkgewoJCUxhYmVsIGNvbW1lbnRzTGFiZWwgPSBjcmVhdGVEZXNjcmlwdGlvbihwYXJlbnQsIFJlZmZyYW1ld29ya1ZpZXdzUmVwb3NpdG9yeS5SZWZBcHBsaWNhYmlsaXR5LlByb3BlcnRpZXMuY29tbWVudHMsIFJlZmZyYW1ld29ya01lc3NhZ2VzLlJlZkFwcGxpY2FiaWxpdHlQcm9wZXJ0aWVzRWRpdGlvblBhcnRfQ29tbWVudHNMYWJlbCk7CgkJR3JpZERhdGEgY29tbWVudHNMYWJlbERhdGEgPSBuZXcgR3JpZERhdGEoR3JpZERhdGEuRklMTF9IT1JJWk9OVEFMKTsKCQljb21tZW50c0xhYmVsRGF0YS5ob3Jpem9udGFsU3BhbiA9IDM7CgkJY29tbWVudHNMYWJlbC5zZXRMYXlvdXREYXRhKGNvbW1lbnRzTGFiZWxEYXRhKTsKCQljb21tZW50cyA9IFNXVFV0aWxzLmNyZWF0ZVNjcm9sbGFibGVUZXh0KHBhcmVudCwgU1dULkJPUkRFUiB8IFNXVC5XUkFQIHwgU1dULk1VTFRJIHwgU1dULlZfU0NST0xMKTsKCQlHcmlkRGF0YSBjb21tZW50c0RhdGEgPSBuZXcgR3JpZERhdGEoR3JpZERhdGEuRklMTF9IT1JJWk9OVEFMKTsKCQljb21tZW50c0RhdGEuaG9yaXpvbnRhbFNwYW4gPSAyOwoJCWNvbW1lbnRzRGF0YS5oZWlnaHRIaW50ID0gODA7CgkJY29tbWVudHNEYXRhLndpZHRoSGludCA9IDIwMDsKCQljb21tZW50cy5zZXRMYXlvdXREYXRhKGNvbW1lbnRzRGF0YSk7CgkJY29tbWVudHMuYWRkRm9jdXNMaXN0ZW5lcihuZXcgRm9jdXNBZGFwdGVyKCkgewoKCQkJLyoqCgkJCSAqIHtAaW5oZXJpdERvY30KCQkJICogCgkJCSAqIEBzZWUgb3JnLmVjbGlwc2Uuc3d0LmV2ZW50cy5Gb2N1c0FkYXB0ZXIjZm9jdXNMb3N0KG9yZy5lY2xpcHNlLnN3dC5ldmVudHMuRm9jdXNFdmVudCkKCQkJICogCgkJCSAqLwoJCQlwdWJsaWMgdm9pZCBmb2N1c0xvc3QoRm9jdXNFdmVudCBlKSB7CgkJCQlpZiAocHJvcGVydGllc0VkaXRpb25Db21wb25lbnQgIT0gbnVsbCkKCQkJCQlwcm9wZXJ0aWVzRWRpdGlvbkNvbXBvbmVudC5maXJlUHJvcGVydGllc0NoYW5nZWQobmV3IFByb3BlcnRpZXNFZGl0aW9uRXZlbnQoUmVmQXBwbGljYWJpbGl0eVByb3BlcnRpZXNFZGl0aW9uUGFydEltcGwudGhpcywgUmVmZnJhbWV3b3JrVmlld3NSZXBvc2l0b3J5LlJlZkFwcGxpY2FiaWxpdHkuUHJvcGVydGllcy5jb21tZW50cywgUHJvcGVydGllc0VkaXRpb25FdmVudC5DT01NSVQsIFByb3BlcnRpZXNFZGl0aW9uRXZlbnQuU0VULCBudWxsLCBjb21tZW50cy5nZXRUZXh0KCkpKTsKCQkJfQoKCQl9KTsKCQlFZGl0aW5nVXRpbHMuc2V0SUQoY29tbWVudHMsIFJlZmZyYW1ld29ya1ZpZXdzUmVwb3NpdG9yeS5SZWZBcHBsaWNhYmlsaXR5LlByb3BlcnRpZXMuY29tbWVudHMpOwoJCUVkaXRpbmdVdGlscy5zZXRFRUZ0eXBlKGNvbW1lbnRzLCAiZWVmOjpUZXh0YXJlYSIpOyAvLyROT04tTkxTLTEkCgkJU1dUVXRpbHMuY3JlYXRlSGVscEJ1dHRvbihwYXJlbnQsIHByb3BlcnRpZXNFZGl0aW9uQ29tcG9uZW50LmdldEhlbHBDb250ZW50KFJlZmZyYW1ld29ya1ZpZXdzUmVwb3NpdG9yeS5SZWZBcHBsaWNhYmlsaXR5LlByb3BlcnRpZXMuY29tbWVudHMsIFJlZmZyYW1ld29ya1ZpZXdzUmVwb3NpdG9yeS5TV1RfS0lORCksIG51bGwpOyAvLyROT04tTkxTLTEkCgkJLy8gU3RhcnQgb2YgdXNlciBjb2RlIGZvciBjcmVhdGVDb21tZW50c1RleHRBcmVhCgoJCS8vIEVuZCBvZiB1c2VyIGNvZGUKCQlyZXR1cm4gcGFyZW50OwoJfQoKCS8qKgoJICogQHBhcmFtIHBhcmVudCB0aGUgcGFyZW50IGNvbXBvc2l0ZQoJICogCgkgKi8KCXByb3RlY3RlZCBDb21wb3NpdGUgY3JlYXRlQXBwbGljVGFyZ2V0RmxhdENvbWJvVmlld2VyKENvbXBvc2l0ZSBwYXJlbnQpIHsKCQljcmVhdGVEZXNjcmlwdGlvbihwYXJlbnQsIFJlZmZyYW1ld29ya1ZpZXdzUmVwb3NpdG9yeS5SZWZBcHBsaWNhYmlsaXR5LlByb3BlcnRpZXMuYXBwbGljVGFyZ2V0LCBSZWZmcmFtZXdvcmtNZXNzYWdlcy5SZWZBcHBsaWNhYmlsaXR5UHJvcGVydGllc0VkaXRpb25QYXJ0X0FwcGxpY1RhcmdldExhYmVsKTsKCQlhcHBsaWNUYXJnZXQgPSBuZXcgRU9iamVjdEZsYXRDb21ib1ZpZXdlcihwYXJlbnQsICFwcm9wZXJ0aWVzRWRpdGlvbkNvbXBvbmVudC5pc1JlcXVpcmVkKFJlZmZyYW1ld29ya1ZpZXdzUmVwb3NpdG9yeS5SZWZBcHBsaWNhYmlsaXR5LlByb3BlcnRpZXMuYXBwbGljVGFyZ2V0LCBSZWZmcmFtZXdvcmtWaWV3c1JlcG9zaXRvcnkuU1dUX0tJTkQpKTsKCQlhcHBsaWNUYXJnZXQuc2V0TGFiZWxQcm92aWRlcihuZXcgQWRhcHRlckZhY3RvcnlMYWJlbFByb3ZpZGVyKGFkYXB0ZXJGYWN0b3J5KSk7CgoJCWFwcGxpY1RhcmdldC5hZGRTZWxlY3Rpb25DaGFuZ2VkTGlzdGVuZXIobmV3IElTZWxlY3Rpb25DaGFuZ2VkTGlzdGVuZXIoKSB7CgoJCQlwdWJsaWMgdm9pZCBzZWxlY3Rpb25DaGFuZ2VkKFNlbGVjdGlvbkNoYW5nZWRFdmVudCBldmVudCkgewoJCQkJcHJvcGVydGllc0VkaXRpb25Db21wb25lbnQuZmlyZVByb3BlcnRpZXNDaGFuZ2VkKG5ldyBQcm9wZXJ0aWVzRWRpdGlvbkV2ZW50KFJlZkFwcGxpY2FiaWxpdHlQcm9wZXJ0aWVzRWRpdGlvblBhcnRJbXBsLnRoaXMsIFJlZmZyYW1ld29ya1ZpZXdzUmVwb3NpdG9yeS5SZWZBcHBsaWNhYmlsaXR5LlByb3BlcnRpZXMuYXBwbGljVGFyZ2V0LCBQcm9wZXJ0aWVzRWRpdGlvbkV2ZW50LkNIQU5HRSwgUHJvcGVydGllc0VkaXRpb25FdmVudC5TRVQsIG51bGwsIGdldEFwcGxpY1RhcmdldCgpKSk7CgkJCX0KCgkJfSk7CgkJR3JpZERhdGEgYXBwbGljVGFyZ2V0RGF0YSA9IG5ldyBHcmlkRGF0YShHcmlkRGF0YS5GSUxMX0hPUklaT05UQUwpOwoJCWFwcGxpY1RhcmdldC5zZXRMYXlvdXREYXRhKGFwcGxpY1RhcmdldERhdGEpOwoJCWFwcGxpY1RhcmdldC5zZXRJRChSZWZmcmFtZXdvcmtWaWV3c1JlcG9zaXRvcnkuUmVmQXBwbGljYWJpbGl0eS5Qcm9wZXJ0aWVzLmFwcGxpY1RhcmdldCk7CgkJU1dUVXRpbHMuY3JlYXRlSGVscEJ1dHRvbihwYXJlbnQsIHByb3BlcnRpZXNFZGl0aW9uQ29tcG9uZW50LmdldEhlbHBDb250ZW50KFJlZmZyYW1ld29ya1ZpZXdzUmVwb3NpdG9yeS5SZWZBcHBsaWNhYmlsaXR5LlByb3BlcnRpZXMuYXBwbGljVGFyZ2V0LCBSZWZmcmFtZXdvcmtWaWV3c1JlcG9zaXRvcnkuU1dUX0tJTkQpLCBudWxsKTsgLy8kTk9OLU5MUy0xJAoJCS8vIFN0YXJ0IG9mIHVzZXIgY29kZSBmb3IgY3JlYXRlQXBwbGljVGFyZ2V0RmxhdENvbWJvVmlld2VyCgoJCS8vIEVuZCBvZiB1c2VyIGNvZGUKCQlyZXR1cm4gcGFyZW50OwoJfQoKCS8qKgoJICogQHBhcmFtIGNvbnRhaW5lcgoJICogCgkgKi8KCXByb3RlY3RlZCBDb21wb3NpdGUgY3JlYXRlT3duZWRSZWxBZHZhbmNlZFRhYmxlQ29tcG9zaXRpb24oQ29tcG9zaXRlIHBhcmVudCkgewoJCXRoaXMub3duZWRSZWwgPSBuZXcgUmVmZXJlbmNlc1RhYmxlKGdldERlc2NyaXB0aW9uKFJlZmZyYW1ld29ya1ZpZXdzUmVwb3NpdG9yeS5SZWZBcHBsaWNhYmlsaXR5LlByb3BlcnRpZXMub3duZWRSZWwsIFJlZmZyYW1ld29ya01lc3NhZ2VzLlJlZkFwcGxpY2FiaWxpdHlQcm9wZXJ0aWVzRWRpdGlvblBhcnRfT3duZWRSZWxMYWJlbCksIG5ldyBSZWZlcmVuY2VzVGFibGVMaXN0ZW5lcigpIHsKCQkJcHVibGljIHZvaWQgaGFuZGxlQWRkKCkgeyAKCQkJCXByb3BlcnRpZXNFZGl0aW9uQ29tcG9uZW50LmZpcmVQcm9wZXJ0aWVzQ2hhbmdlZChuZXcgUHJvcGVydGllc0VkaXRpb25FdmVudChSZWZBcHBsaWNhYmlsaXR5UHJvcGVydGllc0VkaXRpb25QYXJ0SW1wbC50aGlzLCBSZWZmcmFtZXdvcmtWaWV3c1JlcG9zaXRvcnkuUmVmQXBwbGljYWJpbGl0eS5Qcm9wZXJ0aWVzLm93bmVkUmVsLCBQcm9wZXJ0aWVzRWRpdGlvbkV2ZW50LkNPTU1JVCwgUHJvcGVydGllc0VkaXRpb25FdmVudC5BREQsIG51bGwsIG51bGwpKTsKCQkJCW93bmVkUmVsLnJlZnJlc2goKTsKCQkJfQoJCQlwdWJsaWMgdm9pZCBoYW5kbGVFZGl0KEVPYmplY3QgZWxlbWVudCkgewoJCQkJcHJvcGVydGllc0VkaXRpb25Db21wb25lbnQuZmlyZVByb3BlcnRpZXNDaGFuZ2VkKG5ldyBQcm9wZXJ0aWVzRWRpdGlvbkV2ZW50KFJlZkFwcGxpY2FiaWxpdHlQcm9wZXJ0aWVzRWRpdGlvblBhcnRJbXBsLnRoaXMsIFJlZmZyYW1ld29ya1ZpZXdzUmVwb3NpdG9yeS5SZWZBcHBsaWNhYmlsaXR5LlByb3BlcnRpZXMub3duZWRSZWwsIFByb3BlcnRpZXNFZGl0aW9uRXZlbnQuQ09NTUlULCBQcm9wZXJ0aWVzRWRpdGlvbkV2ZW50LkVESVQsIG51bGwsIGVsZW1lbnQpKTsKCQkJCW93bmVkUmVsLnJlZnJlc2goKTsKCQkJfQoJCQlwdWJsaWMgdm9pZCBoYW5kbGVNb3ZlKEVPYmplY3QgZWxlbWVudCwgaW50IG9sZEluZGV4LCBpbnQgbmV3SW5kZXgpIHsgCgkJCQlwcm9wZXJ0aWVzRWRpdGlvbkNvbXBvbmVudC5maXJlUHJvcGVydGllc0NoYW5nZWQobmV3IFByb3BlcnRpZXNFZGl0aW9uRXZlbnQoUmVmQXBwbGljYWJpbGl0eVByb3BlcnRpZXNFZGl0aW9uUGFydEltcGwudGhpcywgUmVmZnJhbWV3b3JrVmlld3NSZXBvc2l0b3J5LlJlZkFwcGxpY2FiaWxpdHkuUHJvcGVydGllcy5vd25lZFJlbCwgUHJvcGVydGllc0VkaXRpb25FdmVudC5DT01NSVQsIFByb3BlcnRpZXNFZGl0aW9uRXZlbnQuTU9WRSwgZWxlbWVudCwgbmV3SW5kZXgpKTsKCQkJCW93bmVkUmVsLnJlZnJlc2goKTsKCQkJfQoJCQlwdWJsaWMgdm9pZCBoYW5kbGVSZW1vdmUoRU9iamVjdCBlbGVtZW50KSB7IAoJCQkJcHJvcGVydGllc0VkaXRpb25Db21wb25lbnQuZmlyZVByb3BlcnRpZXNDaGFuZ2VkKG5ldyBQcm9wZXJ0aWVzRWRpdGlvbkV2ZW50KFJlZkFwcGxpY2FiaWxpdHlQcm9wZXJ0aWVzRWRpdGlvblBhcnRJbXBsLnRoaXMsIFJlZmZyYW1ld29ya1ZpZXdzUmVwb3NpdG9yeS5SZWZBcHBsaWNhYmlsaXR5LlByb3BlcnRpZXMub3duZWRSZWwsIFByb3BlcnRpZXNFZGl0aW9uRXZlbnQuQ09NTUlULCBQcm9wZXJ0aWVzRWRpdGlvbkV2ZW50LlJFTU9WRSwgbnVsbCwgZWxlbWVudCkpOwoJCQkJb3duZWRSZWwucmVmcmVzaCgpOwoJCQl9CgkJCXB1YmxpYyB2b2lkIG5hdmlnYXRlVG8oRU9iamVjdCBlbGVtZW50KSB7IH0KCQl9KTsKCQlmb3IgKFZpZXdlckZpbHRlciBmaWx0ZXIgOiB0aGlzLm93bmVkUmVsRmlsdGVycykgewoJCQl0aGlzLm93bmVkUmVsLmFkZEZpbHRlcihmaWx0ZXIpOwoJCX0KCQl0aGlzLm93bmVkUmVsLnNldEhlbHBUZXh0KHByb3BlcnRpZXNFZGl0aW9uQ29tcG9uZW50LmdldEhlbHBDb250ZW50KFJlZmZyYW1ld29ya1ZpZXdzUmVwb3NpdG9yeS5SZWZBcHBsaWNhYmlsaXR5LlByb3BlcnRpZXMub3duZWRSZWwsIFJlZmZyYW1ld29ya1ZpZXdzUmVwb3NpdG9yeS5TV1RfS0lORCkpOwoJCXRoaXMub3duZWRSZWwuY3JlYXRlQ29udHJvbHMocGFyZW50KTsKCQl0aGlzLm93bmVkUmVsLmFkZFNlbGVjdGlvbkxpc3RlbmVyKG5ldyBTZWxlY3Rpb25BZGFwdGVyKCkgewoJCQkKCQkJcHVibGljIHZvaWQgd2lkZ2V0U2VsZWN0ZWQoU2VsZWN0aW9uRXZlbnQgZSkgewoJCQkJaWYgKGUuaXRlbSAhPSBudWxsICYmIGUuaXRlbS5nZXREYXRhKCkgaW5zdGFuY2VvZiBFT2JqZWN0KSB7CgkJCQkJcHJvcGVydGllc0VkaXRpb25Db21wb25lbnQuZmlyZVByb3BlcnRpZXNDaGFuZ2VkKG5ldyBQcm9wZXJ0aWVzRWRpdGlvbkV2ZW50KFJlZkFwcGxpY2FiaWxpdHlQcm9wZXJ0aWVzRWRpdGlvblBhcnRJbXBsLnRoaXMsIFJlZmZyYW1ld29ya1ZpZXdzUmVwb3NpdG9yeS5SZWZBcHBsaWNhYmlsaXR5LlByb3BlcnRpZXMub3duZWRSZWwsIFByb3BlcnRpZXNFZGl0aW9uRXZlbnQuQ0hBTkdFLCBQcm9wZXJ0aWVzRWRpdGlvbkV2ZW50LlNFTEVDVElPTl9DSEFOR0VELCBudWxsLCBlLml0ZW0uZ2V0RGF0YSgpKSk7CgkJCQl9CgkJCX0KCQkJCgkJfSk7CgkJR3JpZERhdGEgb3duZWRSZWxEYXRhID0gbmV3IEdyaWREYXRhKEdyaWREYXRhLkZJTExfSE9SSVpPTlRBTCk7CgkJb3duZWRSZWxEYXRhLmhvcml6b250YWxTcGFuID0gMzsKCQl0aGlzLm93bmVkUmVsLnNldExheW91dERhdGEob3duZWRSZWxEYXRhKTsKCQl0aGlzLm93bmVkUmVsLnNldExvd2VyQm91bmQoMCk7CgkJdGhpcy5vd25lZFJlbC5zZXRVcHBlckJvdW5kKC0xKTsKCQlvd25lZFJlbC5zZXRJRChSZWZmcmFtZXdvcmtWaWV3c1JlcG9zaXRvcnkuUmVmQXBwbGljYWJpbGl0eS5Qcm9wZXJ0aWVzLm93bmVkUmVsKTsKCQlvd25lZFJlbC5zZXRFRUZUeXBlKCJlZWY6OkFkdmFuY2VkVGFibGVDb21wb3NpdGlvbiIpOyAvLyROT04tTkxTLTEkCgkJLy8gU3RhcnQgb2YgdXNlciBjb2RlIGZvciBjcmVhdGVPd25lZFJlbEFkdmFuY2VkVGFibGVDb21wb3NpdGlvbgoKCQkvLyBFbmQgb2YgdXNlciBjb2RlCgkJcmV0dXJuIHBhcmVudDsKCX0KCgoJLyoqCgkgKiB7QGluaGVyaXREb2N9CgkgKiAKCSAqIEBzZWUgb3JnLmVjbGlwc2UuZW1mLmVlZi5ydW50aW1lLmFwaS5ub3RpZnkuSVByb3BlcnRpZXNFZGl0aW9uTGlzdGVuZXIjZmlyZVByb3BlcnRpZXNDaGFuZ2VkKG9yZy5lY2xpcHNlLmVtZi5lZWYucnVudGltZS5hcGkubm90aWZ5LklQcm9wZXJ0aWVzRWRpdGlvbkV2ZW50KQoJICogCgkgKi8KCXB1YmxpYyB2b2lkIGZpcmVQcm9wZXJ0aWVzQ2hhbmdlZChJUHJvcGVydGllc0VkaXRpb25FdmVudCBldmVudCkgewoJCS8vIFN0YXJ0IG9mIHVzZXIgY29kZSBmb3IgdGFiIHN5bmNocm9uaXphdGlvbgoJCQoJCS8vIEVuZCBvZiB1c2VyIGNvZGUKCX0KCgkvKioKCSAqIHtAaW5oZXJpdERvY30KCSAqIAoJICogQHNlZSBvcmcuZWNsaXBzZS5vcGVuY2VydC5wa20ucmVmZnJhbWV3b3JrLnJlZmZyYW1ld29yay5wYXJ0cy5SZWZBcHBsaWNhYmlsaXR5UHJvcGVydGllc0VkaXRpb25QYXJ0I2dldElkKCkKCSAqIAoJICovCglwdWJsaWMgU3RyaW5nIGdldElkKCkgewoJCXJldHVybiBpZC5nZXRUZXh0KCk7Cgl9CgoJLyoqCgkgKiB7QGluaGVyaXREb2N9CgkgKiAKCSAqIEBzZWUgb3JnLmVjbGlwc2Uub3BlbmNlcnQucGttLnJlZmZyYW1ld29yay5yZWZmcmFtZXdvcmsucGFydHMuUmVmQXBwbGljYWJpbGl0eVByb3BlcnRpZXNFZGl0aW9uUGFydCNzZXRJZChTdHJpbmcgbmV3VmFsdWUpCgkgKiAKCSAqLwoJcHVibGljIHZvaWQgc2V0SWQoU3RyaW5nIG5ld1ZhbHVlKSB7CgkJaWYgKG5ld1ZhbHVlICE9IG51bGwpIHsKCQkJaWQuc2V0VGV4dChuZXdWYWx1ZSk7CgkJfSBlbHNlIHsKCQkJaWQuc2V0VGV4dCgiIik7IC8vJE5PTi1OTFMtMSQKCQl9CgkJYm9vbGVhbiBlZWZFbGVtZW50RWRpdG9yUmVhZE9ubHlTdGF0ZSA9IGlzUmVhZE9ubHkoUmVmZnJhbWV3b3JrVmlld3NSZXBvc2l0b3J5LlJlZkFwcGxpY2FiaWxpdHkuUHJvcGVydGllcy5pZCk7CgkJaWYgKGVlZkVsZW1lbnRFZGl0b3JSZWFkT25seVN0YXRlICYmIGlkLmlzRW5hYmxlZCgpKSB7CgkJCWlkLnNldEVuYWJsZWQoZmFsc2UpOwoJCQlpZC5zZXRUb29sVGlwVGV4dChSZWZmcmFtZXdvcmtNZXNzYWdlcy5SZWZBcHBsaWNhYmlsaXR5X1JlYWRPbmx5KTsKCQl9IGVsc2UgaWYgKCFlZWZFbGVtZW50RWRpdG9yUmVhZE9ubHlTdGF0ZSAmJiAhaWQuaXNFbmFibGVkKCkpIHsKCQkJaWQuc2V0RW5hYmxlZCh0cnVlKTsKCQl9CQoJCQoJfQoKCS8qKgoJICoge0Bpbmhlcml0RG9jfQoJICogCgkgKiBAc2VlIG9yZy5lY2xpcHNlLm9wZW5jZXJ0LnBrbS5yZWZmcmFtZXdvcmsucmVmZnJhbWV3b3JrLnBhcnRzLlJlZkFwcGxpY2FiaWxpdHlQcm9wZXJ0aWVzRWRpdGlvblBhcnQjZ2V0TmFtZSgpCgkgKiAKCSAqLwoJcHVibGljIFN0cmluZyBnZXROYW1lKCkgewoJCXJldHVybiBuYW1lLmdldFRleHQoKTsKCX0KCgkvKioKCSAqIHtAaW5oZXJpdERvY30KCSAqIAoJICogQHNlZSBvcmcuZWNsaXBzZS5vcGVuY2VydC5wa20ucmVmZnJhbWV3b3JrLnJlZmZyYW1ld29yay5wYXJ0cy5SZWZBcHBsaWNhYmlsaXR5UHJvcGVydGllc0VkaXRpb25QYXJ0I3NldE5hbWUoU3RyaW5nIG5ld1ZhbHVlKQoJICogCgkgKi8KCXB1YmxpYyB2b2lkIHNldE5hbWUoU3RyaW5nIG5ld1ZhbHVlKSB7CgkJaWYgKG5ld1ZhbHVlICE9IG51bGwpIHsKCQkJbmFtZS5zZXRUZXh0KG5ld1ZhbHVlKTsKCQl9IGVsc2UgewoJCQluYW1lLnNldFRleHQoIiIpOyAvLyROT04tTkxTLTEkCgkJfQoJCWJvb2xlYW4gZWVmRWxlbWVudEVkaXRvclJlYWRPbmx5U3RhdGUgPSBpc1JlYWRPbmx5KFJlZmZyYW1ld29ya1ZpZXdzUmVwb3NpdG9yeS5SZWZBcHBsaWNhYmlsaXR5LlByb3BlcnRpZXMubmFtZSk7CgkJaWYgKGVlZkVsZW1lbnRFZGl0b3JSZWFkT25seVN0YXRlICYmIG5hbWUuaXNFbmFibGVkKCkpIHsKCQkJbmFtZS5zZXRFbmFibGVkKGZhbHNlKTsKCQkJbmFtZS5zZXRUb29sVGlwVGV4dChSZWZmcmFtZXdvcmtNZXNzYWdlcy5SZWZBcHBsaWNhYmlsaXR5X1JlYWRPbmx5KTsKCQl9IGVsc2UgaWYgKCFlZWZFbGVtZW50RWRpdG9yUmVhZE9ubHlTdGF0ZSAmJiAhbmFtZS5pc0VuYWJsZWQoKSkgewoJCQluYW1lLnNldEVuYWJsZWQodHJ1ZSk7CgkJfQkKCQkKCX0KCgoKCS8qKgoJICoge0Bpbmhlcml0RG9jfQoJICogCgkgKiBAc2VlIG9yZy5lY2xpcHNlLm9wZW5jZXJ0LnBrbS5yZWZmcmFtZXdvcmsucmVmZnJhbWV3b3JrLnBhcnRzLlJlZkFwcGxpY2FiaWxpdHlQcm9wZXJ0aWVzRWRpdGlvblBhcnQjaW5pdEFwcGxpY0NyaXRpYyhFT2JqZWN0IGN1cnJlbnQsIEVSZWZlcmVuY2UgY29udGFpbmluZ0ZlYXR1cmUsIEVSZWZlcmVuY2UgZmVhdHVyZSkKCSAqLwoJcHVibGljIHZvaWQgaW5pdEFwcGxpY0NyaXRpYyhSZWZlcmVuY2VzVGFibGVTZXR0aW5ncyBzZXR0aW5ncykgewoJCWlmIChjdXJyZW50LmVSZXNvdXJjZSgpICE9IG51bGwgJiYgY3VycmVudC5lUmVzb3VyY2UoKS5nZXRSZXNvdXJjZVNldCgpICE9IG51bGwpCgkJCXRoaXMucmVzb3VyY2VTZXQgPSBjdXJyZW50LmVSZXNvdXJjZSgpLmdldFJlc291cmNlU2V0KCk7CgkJUmVmZXJlbmNlc1RhYmxlQ29udGVudFByb3ZpZGVyIGNvbnRlbnRQcm92aWRlciA9IG5ldyBSZWZlcmVuY2VzVGFibGVDb250ZW50UHJvdmlkZXIoKTsKCQlhcHBsaWNDcml0aWMuc2V0Q29udGVudFByb3ZpZGVyKGNvbnRlbnRQcm92aWRlcik7CgkJYXBwbGljQ3JpdGljLnNldElucHV0KHNldHRpbmdzKTsKCQlib29sZWFuIGVlZkVsZW1lbnRFZGl0b3JSZWFkT25seVN0YXRlID0gaXNSZWFkT25seShSZWZmcmFtZXdvcmtWaWV3c1JlcG9zaXRvcnkuUmVmQXBwbGljYWJpbGl0eS5Qcm9wZXJ0aWVzLmFwcGxpY0NyaXRpYyk7CgkJaWYgKGVlZkVsZW1lbnRFZGl0b3JSZWFkT25seVN0YXRlICYmIGFwcGxpY0NyaXRpYy5pc0VuYWJsZWQoKSkgewoJCQlhcHBsaWNDcml0aWMuc2V0RW5hYmxlZChmYWxzZSk7CgkJCWFwcGxpY0NyaXRpYy5zZXRUb29sVGlwVGV4dChSZWZmcmFtZXdvcmtNZXNzYWdlcy5SZWZBcHBsaWNhYmlsaXR5X1JlYWRPbmx5KTsKCQl9IGVsc2UgaWYgKCFlZWZFbGVtZW50RWRpdG9yUmVhZE9ubHlTdGF0ZSAmJiAhYXBwbGljQ3JpdGljLmlzRW5hYmxlZCgpKSB7CgkJCWFwcGxpY0NyaXRpYy5zZXRFbmFibGVkKHRydWUpOwoJCX0JCgkJCgl9CgoJLyoqCgkgKiB7QGluaGVyaXREb2N9CgkgKiAKCSAqIEBzZWUgb3JnLmVjbGlwc2Uub3BlbmNlcnQucGttLnJlZmZyYW1ld29yay5yZWZmcmFtZXdvcmsucGFydHMuUmVmQXBwbGljYWJpbGl0eVByb3BlcnRpZXNFZGl0aW9uUGFydCN1cGRhdGVBcHBsaWNDcml0aWMoKQoJICogCgkgKi8KCXB1YmxpYyB2b2lkIHVwZGF0ZUFwcGxpY0NyaXRpYygpIHsKCWFwcGxpY0NyaXRpYy5yZWZyZXNoKCk7Cn0KCgkvKioKCSAqIHtAaW5oZXJpdERvY30KCSAqIAoJICogQHNlZSBvcmcuZWNsaXBzZS5vcGVuY2VydC5wa20ucmVmZnJhbWV3b3JrLnJlZmZyYW1ld29yay5wYXJ0cy5SZWZBcHBsaWNhYmlsaXR5UHJvcGVydGllc0VkaXRpb25QYXJ0I2FkZEZpbHRlckFwcGxpY0NyaXRpYyhWaWV3ZXJGaWx0ZXIgZmlsdGVyKQoJICogCgkgKi8KCXB1YmxpYyB2b2lkIGFkZEZpbHRlclRvQXBwbGljQ3JpdGljKFZpZXdlckZpbHRlciBmaWx0ZXIpIHsKCQlhcHBsaWNDcml0aWNGaWx0ZXJzLmFkZChmaWx0ZXIpOwoJCWlmICh0aGlzLmFwcGxpY0NyaXRpYyAhPSBudWxsKSB7CgkJCXRoaXMuYXBwbGljQ3JpdGljLmFkZEZpbHRlcihmaWx0ZXIpOwoJCX0KCX0KCgkvKioKCSAqIHtAaW5oZXJpdERvY30KCSAqIAoJICogQHNlZSBvcmcuZWNsaXBzZS5vcGVuY2VydC5wa20ucmVmZnJhbWV3b3JrLnJlZmZyYW1ld29yay5wYXJ0cy5SZWZBcHBsaWNhYmlsaXR5UHJvcGVydGllc0VkaXRpb25QYXJ0I2FkZEJ1c2luZXNzRmlsdGVyQXBwbGljQ3JpdGljKFZpZXdlckZpbHRlciBmaWx0ZXIpCgkgKiAKCSAqLwoJcHVibGljIHZvaWQgYWRkQnVzaW5lc3NGaWx0ZXJUb0FwcGxpY0NyaXRpYyhWaWV3ZXJGaWx0ZXIgZmlsdGVyKSB7CgkJYXBwbGljQ3JpdGljQnVzaW5lc3NGaWx0ZXJzLmFkZChmaWx0ZXIpOwoJfQoKCS8qKgoJICoge0Bpbmhlcml0RG9jfQoJICogCgkgKiBAc2VlIG9yZy5lY2xpcHNlLm9wZW5jZXJ0LnBrbS5yZWZmcmFtZXdvcmsucmVmZnJhbWV3b3JrLnBhcnRzLlJlZkFwcGxpY2FiaWxpdHlQcm9wZXJ0aWVzRWRpdGlvblBhcnQjaXNDb250YWluZWRJbkFwcGxpY0NyaXRpY1RhYmxlKEVPYmplY3QgZWxlbWVudCkKCSAqIAoJICovCglwdWJsaWMgYm9vbGVhbiBpc0NvbnRhaW5lZEluQXBwbGljQ3JpdGljVGFibGUoRU9iamVjdCBlbGVtZW50KSB7CgkJcmV0dXJuICgoUmVmZXJlbmNlc1RhYmxlU2V0dGluZ3MpYXBwbGljQ3JpdGljLmdldElucHV0KCkpLmNvbnRhaW5zKGVsZW1lbnQpOwoJfQoKCgoJLyoqCgkgKiB7QGluaGVyaXREb2N9CgkgKiAKCSAqIEBzZWUgb3JnLmVjbGlwc2Uub3BlbmNlcnQucGttLnJlZmZyYW1ld29yay5yZWZmcmFtZXdvcmsucGFydHMuUmVmQXBwbGljYWJpbGl0eVByb3BlcnRpZXNFZGl0aW9uUGFydCNpbml0QXBwbGljQ3JpdGljVGFibGUoRU9iamVjdCBjdXJyZW50LCBFUmVmZXJlbmNlIGNvbnRhaW5pbmdGZWF0dXJlLCBFUmVmZXJlbmNlIGZlYXR1cmUpCgkgKi8KCXB1YmxpYyB2b2lkIGluaXRBcHBsaWNDcml0aWNUYWJsZShSZWZlcmVuY2VzVGFibGVTZXR0aW5ncyBzZXR0aW5ncykgewoJCWlmIChjdXJyZW50LmVSZXNvdXJjZSgpICE9IG51bGwgJiYgY3VycmVudC5lUmVzb3VyY2UoKS5nZXRSZXNvdXJjZVNldCgpICE9IG51bGwpCgkJCXRoaXMucmVzb3VyY2VTZXQgPSBjdXJyZW50LmVSZXNvdXJjZSgpLmdldFJlc291cmNlU2V0KCk7CgkJUmVmZXJlbmNlc1RhYmxlQ29udGVudFByb3ZpZGVyIGNvbnRlbnRQcm92aWRlciA9IG5ldyBSZWZlcmVuY2VzVGFibGVDb250ZW50UHJvdmlkZXIoKTsKCQlhcHBsaWNDcml0aWNUYWJsZS5zZXRDb250ZW50UHJvdmlkZXIoY29udGVudFByb3ZpZGVyKTsKCQlhcHBsaWNDcml0aWNUYWJsZS5zZXRJbnB1dChzZXR0aW5ncyk7CgkJYm9vbGVhbiBlZWZFbGVtZW50RWRpdG9yUmVhZE9ubHlTdGF0ZSA9IGlzUmVhZE9ubHkoUmVmZnJhbWV3b3JrVmlld3NSZXBvc2l0b3J5LlJlZkFwcGxpY2FiaWxpdHkuUHJvcGVydGllcy5hcHBsaWNDcml0aWNUYWJsZSk7CgkJaWYgKGVlZkVsZW1lbnRFZGl0b3JSZWFkT25seVN0YXRlICYmIGFwcGxpY0NyaXRpY1RhYmxlLmdldFRhYmxlKCkuaXNFbmFibGVkKCkpIHsKCQkJYXBwbGljQ3JpdGljVGFibGUuZ2V0VGFibGUoKS5zZXRFbmFibGVkKGZhbHNlKTsKCQkJYXBwbGljQ3JpdGljVGFibGUuZ2V0VGFibGUoKS5zZXRUb29sVGlwVGV4dChSZWZmcmFtZXdvcmtNZXNzYWdlcy5SZWZBcHBsaWNhYmlsaXR5X1JlYWRPbmx5KTsKCQkJYWRkQXBwbGljQ3JpdGljVGFibGUuc2V0RW5hYmxlZChmYWxzZSk7CgkJCWFkZEFwcGxpY0NyaXRpY1RhYmxlLnNldFRvb2xUaXBUZXh0KFJlZmZyYW1ld29ya01lc3NhZ2VzLlJlZkFwcGxpY2FiaWxpdHlfUmVhZE9ubHkpOwoJCQlyZW1vdmVBcHBsaWNDcml0aWNUYWJsZS5zZXRFbmFibGVkKGZhbHNlKTsKCQkJcmVtb3ZlQXBwbGljQ3JpdGljVGFibGUuc2V0VG9vbFRpcFRleHQoUmVmZnJhbWV3b3JrTWVzc2FnZXMuUmVmQXBwbGljYWJpbGl0eV9SZWFkT25seSk7CgkJCWVkaXRBcHBsaWNDcml0aWNUYWJsZS5zZXRFbmFibGVkKGZhbHNlKTsKCQkJZWRpdEFwcGxpY0NyaXRpY1RhYmxlLnNldFRvb2xUaXBUZXh0KFJlZmZyYW1ld29ya01lc3NhZ2VzLlJlZkFwcGxpY2FiaWxpdHlfUmVhZE9ubHkpOwoJCX0gZWxzZSBpZiAoIWVlZkVsZW1lbnRFZGl0b3JSZWFkT25seVN0YXRlICYmICFhcHBsaWNDcml0aWNUYWJsZS5nZXRUYWJsZSgpLmlzRW5hYmxlZCgpKSB7CgkJCWFwcGxpY0NyaXRpY1RhYmxlLmdldFRhYmxlKCkuc2V0RW5hYmxlZCh0cnVlKTsKCQkJYWRkQXBwbGljQ3JpdGljVGFibGUuc2V0RW5hYmxlZCh0cnVlKTsKCQkJcmVtb3ZlQXBwbGljQ3JpdGljVGFibGUuc2V0RW5hYmxlZCh0cnVlKTsKCQkJZWRpdEFwcGxpY0NyaXRpY1RhYmxlLnNldEVuYWJsZWQodHJ1ZSk7CgkJfQoJCQoJfQoKCS8qKgoJICoge0Bpbmhlcml0RG9jfQoJICogCgkgKiBAc2VlIG9yZy5lY2xpcHNlLm9wZW5jZXJ0LnBrbS5yZWZmcmFtZXdvcmsucmVmZnJhbWV3b3JrLnBhcnRzLlJlZkFwcGxpY2FiaWxpdHlQcm9wZXJ0aWVzRWRpdGlvblBhcnQjdXBkYXRlQXBwbGljQ3JpdGljVGFibGUoKQoJICogCgkgKi8KCXB1YmxpYyB2b2lkIHVwZGF0ZUFwcGxpY0NyaXRpY1RhYmxlKCkgewoJYXBwbGljQ3JpdGljVGFibGUucmVmcmVzaCgpOwp9CgoJLyoqCgkgKiB7QGluaGVyaXREb2N9CgkgKiAKCSAqIEBzZWUgb3JnLmVjbGlwc2Uub3BlbmNlcnQucGttLnJlZmZyYW1ld29yay5yZWZmcmFtZXdvcmsucGFydHMuUmVmQXBwbGljYWJpbGl0eVByb3BlcnRpZXNFZGl0aW9uUGFydCNhZGRGaWx0ZXJBcHBsaWNDcml0aWNUYWJsZShWaWV3ZXJGaWx0ZXIgZmlsdGVyKQoJICogCgkgKi8KCXB1YmxpYyB2b2lkIGFkZEZpbHRlclRvQXBwbGljQ3JpdGljVGFibGUoVmlld2VyRmlsdGVyIGZpbHRlcikgewoJCWFwcGxpY0NyaXRpY1RhYmxlRmlsdGVycy5hZGQoZmlsdGVyKTsKCQlpZiAodGhpcy5hcHBsaWNDcml0aWNUYWJsZSAhPSBudWxsKSB7CgkJCXRoaXMuYXBwbGljQ3JpdGljVGFibGUuYWRkRmlsdGVyKGZpbHRlcik7CgkJfQoJfQoKCS8qKgoJICoge0Bpbmhlcml0RG9jfQoJICogCgkgKiBAc2VlIG9yZy5lY2xpcHNlLm9wZW5jZXJ0LnBrbS5yZWZmcmFtZXdvcmsucmVmZnJhbWV3b3JrLnBhcnRzLlJlZkFwcGxpY2FiaWxpdHlQcm9wZXJ0aWVzRWRpdGlvblBhcnQjYWRkQnVzaW5lc3NGaWx0ZXJBcHBsaWNDcml0aWNUYWJsZShWaWV3ZXJGaWx0ZXIgZmlsdGVyKQoJICogCgkgKi8KCXB1YmxpYyB2b2lkIGFkZEJ1c2luZXNzRmlsdGVyVG9BcHBsaWNDcml0aWNUYWJsZShWaWV3ZXJGaWx0ZXIgZmlsdGVyKSB7CgkJYXBwbGljQ3JpdGljVGFibGVCdXNpbmVzc0ZpbHRlcnMuYWRkKGZpbHRlcik7Cgl9CgoJLyoqCgkgKiB7QGluaGVyaXREb2N9CgkgKiAKCSAqIEBzZWUgb3JnLmVjbGlwc2Uub3BlbmNlcnQucGttLnJlZmZyYW1ld29yay5yZWZmcmFtZXdvcmsucGFydHMuUmVmQXBwbGljYWJpbGl0eVByb3BlcnRpZXNFZGl0aW9uUGFydCNpc0NvbnRhaW5lZEluQXBwbGljQ3JpdGljVGFibGVUYWJsZShFT2JqZWN0IGVsZW1lbnQpCgkgKiAKCSAqLwoJcHVibGljIGJvb2xlYW4gaXNDb250YWluZWRJbkFwcGxpY0NyaXRpY1RhYmxlVGFibGUoRU9iamVjdCBlbGVtZW50KSB7CgkJcmV0dXJuICgoUmVmZXJlbmNlc1RhYmxlU2V0dGluZ3MpYXBwbGljQ3JpdGljVGFibGUuZ2V0SW5wdXQoKSkuY29udGFpbnMoZWxlbWVudCk7Cgl9CgoJLyoqCgkgKiB7QGluaGVyaXREb2N9CgkgKiAKCSAqIEBzZWUgb3JnLmVjbGlwc2Uub3BlbmNlcnQucGttLnJlZmZyYW1ld29yay5yZWZmcmFtZXdvcmsucGFydHMuUmVmQXBwbGljYWJpbGl0eVByb3BlcnRpZXNFZGl0aW9uUGFydCNnZXRDb21tZW50cygpCgkgKiAKCSAqLwoJcHVibGljIFN0cmluZyBnZXRDb21tZW50cygpIHsKCQlyZXR1cm4gY29tbWVudHMuZ2V0VGV4dCgpOwoJfQoKCS8qKgoJICoge0Bpbmhlcml0RG9jfQoJICogCgkgKiBAc2VlIG9yZy5lY2xpcHNlLm9wZW5jZXJ0LnBrbS5yZWZmcmFtZXdvcmsucmVmZnJhbWV3b3JrLnBhcnRzLlJlZkFwcGxpY2FiaWxpdHlQcm9wZXJ0aWVzRWRpdGlvblBhcnQjc2V0Q29tbWVudHMoU3RyaW5nIG5ld1ZhbHVlKQoJICogCgkgKi8KCXB1YmxpYyB2b2lkIHNldENvbW1lbnRzKFN0cmluZyBuZXdWYWx1ZSkgewoJCWlmIChuZXdWYWx1ZSAhPSBudWxsKSB7CgkJCWNvbW1lbnRzLnNldFRleHQobmV3VmFsdWUpOwoJCX0gZWxzZSB7CgkJCWNvbW1lbnRzLnNldFRleHQoIiIpOyAvLyROT04tTkxTLTEkCgkJfQoJCWJvb2xlYW4gZWVmRWxlbWVudEVkaXRvclJlYWRPbmx5U3RhdGUgPSBpc1JlYWRPbmx5KFJlZmZyYW1ld29ya1ZpZXdzUmVwb3NpdG9yeS5SZWZBcHBsaWNhYmlsaXR5LlByb3BlcnRpZXMuY29tbWVudHMpOwoJCWlmIChlZWZFbGVtZW50RWRpdG9yUmVhZE9ubHlTdGF0ZSAmJiBjb21tZW50cy5pc0VuYWJsZWQoKSkgewoJCQljb21tZW50cy5zZXRFbmFibGVkKGZhbHNlKTsKCQkJY29tbWVudHMuc2V0QmFja2dyb3VuZChjb21tZW50cy5nZXREaXNwbGF5KCkuZ2V0U3lzdGVtQ29sb3IoU1dULkNPTE9SX1dJREdFVF9CQUNLR1JPVU5EKSk7CgkJCWNvbW1lbnRzLnNldFRvb2xUaXBUZXh0KFJlZmZyYW1ld29ya01lc3NhZ2VzLlJlZkFwcGxpY2FiaWxpdHlfUmVhZE9ubHkpOwoJCX0gZWxzZSBpZiAoIWVlZkVsZW1lbnRFZGl0b3JSZWFkT25seVN0YXRlICYmICFjb21tZW50cy5pc0VuYWJsZWQoKSkgewoJCQljb21tZW50cy5zZXRFbmFibGVkKHRydWUpOwoJCX0JCgkJCgl9CgoJLyoqCgkgKiB7QGluaGVyaXREb2N9CgkgKiAKCSAqIEBzZWUgb3JnLmVjbGlwc2Uub3BlbmNlcnQucGttLnJlZmZyYW1ld29yay5yZWZmcmFtZXdvcmsucGFydHMuUmVmQXBwbGljYWJpbGl0eVByb3BlcnRpZXNFZGl0aW9uUGFydCNnZXRBcHBsaWNUYXJnZXQoKQoJICogCgkgKi8KCXB1YmxpYyBFT2JqZWN0IGdldEFwcGxpY1RhcmdldCgpIHsKCQlpZiAoYXBwbGljVGFyZ2V0LmdldFNlbGVjdGlvbigpIGluc3RhbmNlb2YgU3RydWN0dXJlZFNlbGVjdGlvbikgewoJCQlPYmplY3QgZmlyc3RFbGVtZW50ID0gKChTdHJ1Y3R1cmVkU2VsZWN0aW9uKSBhcHBsaWNUYXJnZXQuZ2V0U2VsZWN0aW9uKCkpLmdldEZpcnN0RWxlbWVudCgpOwoJCQlpZiAoZmlyc3RFbGVtZW50IGluc3RhbmNlb2YgRU9iamVjdCkKCQkJCXJldHVybiAoRU9iamVjdCkgZmlyc3RFbGVtZW50OwoJCX0KCQlyZXR1cm4gbnVsbDsKCX0KCgkvKioKCSAqIHtAaW5oZXJpdERvY30KCSAqIAoJICogQHNlZSBvcmcuZWNsaXBzZS5vcGVuY2VydC5wa20ucmVmZnJhbWV3b3JrLnJlZmZyYW1ld29yay5wYXJ0cy5SZWZBcHBsaWNhYmlsaXR5UHJvcGVydGllc0VkaXRpb25QYXJ0I2luaXRBcHBsaWNUYXJnZXQoRU9iamVjdEZsYXRDb21ib1NldHRpbmdzKQoJICovCglwdWJsaWMgdm9pZCBpbml0QXBwbGljVGFyZ2V0KEVPYmplY3RGbGF0Q29tYm9TZXR0aW5ncyBzZXR0aW5ncykgewoJCWFwcGxpY1RhcmdldC5zZXRJbnB1dChzZXR0aW5ncyk7CgkJaWYgKGN1cnJlbnQgIT0gbnVsbCkgewoJCQlhcHBsaWNUYXJnZXQuc2V0U2VsZWN0aW9uKG5ldyBTdHJ1Y3R1cmVkU2VsZWN0aW9uKHNldHRpbmdzLmdldFZhbHVlKCkpKTsKCQl9CgkJYm9vbGVhbiBlZWZFbGVtZW50RWRpdG9yUmVhZE9ubHlTdGF0ZSA9IGlzUmVhZE9ubHkoUmVmZnJhbWV3b3JrVmlld3NSZXBvc2l0b3J5LlJlZkFwcGxpY2FiaWxpdHkuUHJvcGVydGllcy5hcHBsaWNUYXJnZXQpOwoJCWlmIChlZWZFbGVtZW50RWRpdG9yUmVhZE9ubHlTdGF0ZSAmJiBhcHBsaWNUYXJnZXQuaXNFbmFibGVkKCkpIHsKCQkJYXBwbGljVGFyZ2V0LnNldEVuYWJsZWQoZmFsc2UpOwoJCQlhcHBsaWNUYXJnZXQuc2V0VG9vbFRpcFRleHQoUmVmZnJhbWV3b3JrTWVzc2FnZXMuUmVmQXBwbGljYWJpbGl0eV9SZWFkT25seSk7CgkJfSBlbHNlIGlmICghZWVmRWxlbWVudEVkaXRvclJlYWRPbmx5U3RhdGUgJiYgIWFwcGxpY1RhcmdldC5pc0VuYWJsZWQoKSkgewoJCQlhcHBsaWNUYXJnZXQuc2V0RW5hYmxlZCh0cnVlKTsKCQl9CQoJCQoJfQoKCS8qKgoJICoge0Bpbmhlcml0RG9jfQoJICogCgkgKiBAc2VlIG9yZy5lY2xpcHNlLm9wZW5jZXJ0LnBrbS5yZWZmcmFtZXdvcmsucmVmZnJhbWV3b3JrLnBhcnRzLlJlZkFwcGxpY2FiaWxpdHlQcm9wZXJ0aWVzRWRpdGlvblBhcnQjc2V0QXBwbGljVGFyZ2V0KEVPYmplY3QgbmV3VmFsdWUpCgkgKiAKCSAqLwoJcHVibGljIHZvaWQgc2V0QXBwbGljVGFyZ2V0KEVPYmplY3QgbmV3VmFsdWUpIHsKCQlpZiAobmV3VmFsdWUgIT0gbnVsbCkgewoJCQlhcHBsaWNUYXJnZXQuc2V0U2VsZWN0aW9uKG5ldyBTdHJ1Y3R1cmVkU2VsZWN0aW9uKG5ld1ZhbHVlKSk7CgkJfSBlbHNlIHsKCQkJYXBwbGljVGFyZ2V0LnNldFNlbGVjdGlvbihuZXcgU3RydWN0dXJlZFNlbGVjdGlvbigpKTsgLy8kTk9OLU5MUy0xJAoJCX0KCQlib29sZWFuIGVlZkVsZW1lbnRFZGl0b3JSZWFkT25seVN0YXRlID0gaXNSZWFkT25seShSZWZmcmFtZXdvcmtWaWV3c1JlcG9zaXRvcnkuUmVmQXBwbGljYWJpbGl0eS5Qcm9wZXJ0aWVzLmFwcGxpY1RhcmdldCk7CgkJaWYgKGVlZkVsZW1lbnRFZGl0b3JSZWFkT25seVN0YXRlICYmIGFwcGxpY1RhcmdldC5pc0VuYWJsZWQoKSkgewoJCQlhcHBsaWNUYXJnZXQuc2V0RW5hYmxlZChmYWxzZSk7CgkJCWFwcGxpY1RhcmdldC5zZXRUb29sVGlwVGV4dChSZWZmcmFtZXdvcmtNZXNzYWdlcy5SZWZBcHBsaWNhYmlsaXR5X1JlYWRPbmx5KTsKCQl9IGVsc2UgaWYgKCFlZWZFbGVtZW50RWRpdG9yUmVhZE9ubHlTdGF0ZSAmJiAhYXBwbGljVGFyZ2V0LmlzRW5hYmxlZCgpKSB7CgkJCWFwcGxpY1RhcmdldC5zZXRFbmFibGVkKHRydWUpOwoJCX0JCgkJCgl9CgoJLyoqCgkgKiB7QGluaGVyaXREb2N9CgkgKiAKCSAqIEBzZWUgb3JnLmVjbGlwc2Uub3BlbmNlcnQucGttLnJlZmZyYW1ld29yay5yZWZmcmFtZXdvcmsucGFydHMuUmVmQXBwbGljYWJpbGl0eVByb3BlcnRpZXNFZGl0aW9uUGFydCNzZXRBcHBsaWNUYXJnZXRCdXR0b25Nb2RlKEJ1dHRvbnNNb2RlRW51bSBuZXdWYWx1ZSkKCSAqLwoJcHVibGljIHZvaWQgc2V0QXBwbGljVGFyZ2V0QnV0dG9uTW9kZShCdXR0b25zTW9kZUVudW0gbmV3VmFsdWUpIHsKCQlhcHBsaWNUYXJnZXQuc2V0QnV0dG9uTW9kZShuZXdWYWx1ZSk7Cgl9CgoJLyoqCgkgKiB7QGluaGVyaXREb2N9CgkgKiAKCSAqIEBzZWUgb3JnLmVjbGlwc2Uub3BlbmNlcnQucGttLnJlZmZyYW1ld29yay5yZWZmcmFtZXdvcmsucGFydHMuUmVmQXBwbGljYWJpbGl0eVByb3BlcnRpZXNFZGl0aW9uUGFydCNhZGRGaWx0ZXJBcHBsaWNUYXJnZXQoVmlld2VyRmlsdGVyIGZpbHRlcikKCSAqIAoJICovCglwdWJsaWMgdm9pZCBhZGRGaWx0ZXJUb0FwcGxpY1RhcmdldChWaWV3ZXJGaWx0ZXIgZmlsdGVyKSB7CgkJYXBwbGljVGFyZ2V0LmFkZEZpbHRlcihmaWx0ZXIpOwoJfQoKCS8qKgoJICoge0Bpbmhlcml0RG9jfQoJICogCgkgKiBAc2VlIG9yZy5lY2xpcHNlLm9wZW5jZXJ0LnBrbS5yZWZmcmFtZXdvcmsucmVmZnJhbWV3b3JrLnBhcnRzLlJlZkFwcGxpY2FiaWxpdHlQcm9wZXJ0aWVzRWRpdGlvblBhcnQjYWRkQnVzaW5lc3NGaWx0ZXJBcHBsaWNUYXJnZXQoVmlld2VyRmlsdGVyIGZpbHRlcikKCSAqIAoJICovCglwdWJsaWMgdm9pZCBhZGRCdXNpbmVzc0ZpbHRlclRvQXBwbGljVGFyZ2V0KFZpZXdlckZpbHRlciBmaWx0ZXIpIHsKCQlhcHBsaWNUYXJnZXQuYWRkQnVzaW5lc3NSdWxlRmlsdGVyKGZpbHRlcik7Cgl9CgoKCgkvKioKCSAqIHtAaW5oZXJpdERvY30KCSAqIAoJICogQHNlZSBvcmcuZWNsaXBzZS5vcGVuY2VydC5wa20ucmVmZnJhbWV3b3JrLnJlZmZyYW1ld29yay5wYXJ0cy5SZWZBcHBsaWNhYmlsaXR5UHJvcGVydGllc0VkaXRpb25QYXJ0I2luaXRPd25lZFJlbChFT2JqZWN0IGN1cnJlbnQsIEVSZWZlcmVuY2UgY29udGFpbmluZ0ZlYXR1cmUsIEVSZWZlcmVuY2UgZmVhdHVyZSkKCSAqLwoJcHVibGljIHZvaWQgaW5pdE93bmVkUmVsKFJlZmVyZW5jZXNUYWJsZVNldHRpbmdzIHNldHRpbmdzKSB7CgkJaWYgKGN1cnJlbnQuZVJlc291cmNlKCkgIT0gbnVsbCAmJiBjdXJyZW50LmVSZXNvdXJjZSgpLmdldFJlc291cmNlU2V0KCkgIT0gbnVsbCkKCQkJdGhpcy5yZXNvdXJjZVNldCA9IGN1cnJlbnQuZVJlc291cmNlKCkuZ2V0UmVzb3VyY2VTZXQoKTsKCQlSZWZlcmVuY2VzVGFibGVDb250ZW50UHJvdmlkZXIgY29udGVudFByb3ZpZGVyID0gbmV3IFJlZmVyZW5jZXNUYWJsZUNvbnRlbnRQcm92aWRlcigpOwoJCW93bmVkUmVsLnNldENvbnRlbnRQcm92aWRlcihjb250ZW50UHJvdmlkZXIpOwoJCW93bmVkUmVsLnNldElucHV0KHNldHRpbmdzKTsKCQlib29sZWFuIGVlZkVsZW1lbnRFZGl0b3JSZWFkT25seVN0YXRlID0gaXNSZWFkT25seShSZWZmcmFtZXdvcmtWaWV3c1JlcG9zaXRvcnkuUmVmQXBwbGljYWJpbGl0eS5Qcm9wZXJ0aWVzLm93bmVkUmVsKTsKCQlpZiAoZWVmRWxlbWVudEVkaXRvclJlYWRPbmx5U3RhdGUgJiYgb3duZWRSZWwuaXNFbmFibGVkKCkpIHsKCQkJb3duZWRSZWwuc2V0RW5hYmxlZChmYWxzZSk7CgkJCW93bmVkUmVsLnNldFRvb2xUaXBUZXh0KFJlZmZyYW1ld29ya01lc3NhZ2VzLlJlZkFwcGxpY2FiaWxpdHlfUmVhZE9ubHkpOwoJCX0gZWxzZSBpZiAoIWVlZkVsZW1lbnRFZGl0b3JSZWFkT25seVN0YXRlICYmICFvd25lZFJlbC5pc0VuYWJsZWQoKSkgewoJCQlvd25lZFJlbC5zZXRFbmFibGVkKHRydWUpOwoJCX0JCgkJCgl9CgoJLyoqCgkgKiB7QGluaGVyaXREb2N9CgkgKiAKCSAqIEBzZWUgb3JnLmVjbGlwc2Uub3BlbmNlcnQucGttLnJlZmZyYW1ld29yay5yZWZmcmFtZXdvcmsucGFydHMuUmVmQXBwbGljYWJpbGl0eVByb3BlcnRpZXNFZGl0aW9uUGFydCN1cGRhdGVPd25lZFJlbCgpCgkgKiAKCSAqLwoJcHVibGljIHZvaWQgdXBkYXRlT3duZWRSZWwoKSB7Cglvd25lZFJlbC5yZWZyZXNoKCk7Cn0KCgkvKioKCSAqIHtAaW5oZXJpdERvY30KCSAqIAoJICogQHNlZSBvcmcuZWNsaXBzZS5vcGVuY2VydC5wa20ucmVmZnJhbWV3b3JrLnJlZmZyYW1ld29yay5wYXJ0cy5SZWZBcHBsaWNhYmlsaXR5UHJvcGVydGllc0VkaXRpb25QYXJ0I2FkZEZpbHRlck93bmVkUmVsKFZpZXdlckZpbHRlciBmaWx0ZXIpCgkgKiAKCSAqLwoJcHVibGljIHZvaWQgYWRkRmlsdGVyVG9Pd25lZFJlbChWaWV3ZXJGaWx0ZXIgZmlsdGVyKSB7CgkJb3duZWRSZWxGaWx0ZXJzLmFkZChmaWx0ZXIpOwoJCWlmICh0aGlzLm93bmVkUmVsICE9IG51bGwpIHsKCQkJdGhpcy5vd25lZFJlbC5hZGRGaWx0ZXIoZmlsdGVyKTsKCQl9Cgl9CgoJLyoqCgkgKiB7QGluaGVyaXREb2N9CgkgKiAKCSAqIEBzZWUgb3JnLmVjbGlwc2Uub3BlbmNlcnQucGttLnJlZmZyYW1ld29yay5yZWZmcmFtZXdvcmsucGFydHMuUmVmQXBwbGljYWJpbGl0eVByb3BlcnRpZXNFZGl0aW9uUGFydCNhZGRCdXNpbmVzc0ZpbHRlck93bmVkUmVsKFZpZXdlckZpbHRlciBmaWx0ZXIpCgkgKiAKCSAqLwoJcHVibGljIHZvaWQgYWRkQnVzaW5lc3NGaWx0ZXJUb093bmVkUmVsKFZpZXdlckZpbHRlciBmaWx0ZXIpIHsKCQlvd25lZFJlbEJ1c2luZXNzRmlsdGVycy5hZGQoZmlsdGVyKTsKCX0KCgkvKioKCSAqIHtAaW5oZXJpdERvY30KCSAqIAoJICogQHNlZSBvcmcuZWNsaXBzZS5vcGVuY2VydC5wa20ucmVmZnJhbWV3b3JrLnJlZmZyYW1ld29yay5wYXJ0cy5SZWZBcHBsaWNhYmlsaXR5UHJvcGVydGllc0VkaXRpb25QYXJ0I2lzQ29udGFpbmVkSW5Pd25lZFJlbFRhYmxlKEVPYmplY3QgZWxlbWVudCkKCSAqIAoJICovCglwdWJsaWMgYm9vbGVhbiBpc0NvbnRhaW5lZEluT3duZWRSZWxUYWJsZShFT2JqZWN0IGVsZW1lbnQpIHsKCQlyZXR1cm4gKChSZWZlcmVuY2VzVGFibGVTZXR0aW5ncylvd25lZFJlbC5nZXRJbnB1dCgpKS5jb250YWlucyhlbGVtZW50KTsKCX0KCgoKCgoKCS8qKgoJICoge0Bpbmhlcml0RG9jfQoJICoKCSAqIEBzZWUgb3JnLmVjbGlwc2UuZW1mLmVlZi5ydW50aW1lLmFwaS5wYXJ0cy5JUHJvcGVydGllc0VkaXRpb25QYXJ0I2dldFRpdGxlKCkKCSAqIAoJICovCglwdWJsaWMgU3RyaW5nIGdldFRpdGxlKCkgewoJCXJldHVybiBSZWZmcmFtZXdvcmtNZXNzYWdlcy5SZWZBcHBsaWNhYmlsaXR5X1BhcnRfVGl0bGU7Cgl9CgoJLy8gU3RhcnQgb2YgdXNlciBjb2RlIGFkZGl0aW9uYWwgbWV0aG9kcwoJCgkvLyBFbmQgb2YgdXNlciBjb2RlCgoKfQo=