LyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogQ29weXJpZ2h0IChjKSAyMDE2IEZ1bmRhY2nzbiBUZWNuYWxpYSBSZXNlYXJjaCAmIElubm92YXRpb24uCiAqCiAqIEFsbCByaWdodHMgcmVzZXJ2ZWQuIFRoaXMgcHJvZ3JhbSBhbmQgdGhlIGFjY29tcGFueWluZyBtYXRlcmlhbHMKICogYXJlIG1hZGUgYXZhaWxhYmxlIHVuZGVyIHRoZSB0ZXJtcyBvZiB0aGUgRWNsaXBzZSBQdWJsaWMgTGljZW5zZSB2MS4wCiAqIHdoaWNoIGFjY29tcGFuaWVzIHRoaXMgZGlzdHJpYnV0aW9uLCBhbmQgaXMgYXZhaWxhYmxlIGF0CiAqIGh0dHA6Ly93d3cuZWNsaXBzZS5vcmcvbGVnYWwvZXBsLXYxMC5odG1sCiAqCiAqIENvbnRyaWJ1dG9yczoKICogICBIdWFzY2FyIEVzcGlub3phIC0gaW5pdGlhbCBBUEkgYW5kIGltcGxlbWVudGF0aW9uCiAqICAgQWxlamFuZHJhIFJ17XogLSBpbml0aWFsIEFQSSBhbmQgaW1wbGVtZW50YXRpb24KICogICBJZG95YSBEZWwgUu1vIC0gaW5pdGlhbCBBUEkgYW5kIGltcGxlbWVudGF0aW9uCiAqICAgTWFyaSBDYXJtZW4gUGFsYWNpb3MgLSBpbml0aWFsIEFQSSBhbmQgaW1wbGVtZW50YXRpb24KICogICBBbmdlbCBM83BleiAtIGluaXRpYWwgQVBJIGFuZCBpbXBsZW1lbnRhdGlvbgogKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8KLyoqCiAqIEdlbmVyYXRlZCB3aXRoIEFjY2VsZW8KICovCnBhY2thZ2Ugb3JnLmVjbGlwc2Uub3BlbmNlcnQuYXBtLmJhc2VsaW5lLmJhc2VsaW5lLnBhcnRzLmltcGw7CgovLyBTdGFydCBvZiB1c2VyIGNvZGUgZm9yIGltcG9ydHMKaW1wb3J0IGphdmEudXRpbC5BcnJheUxpc3Q7CmltcG9ydCBqYXZhLnV0aWwuSXRlcmF0b3I7CmltcG9ydCBqYXZhLnV0aWwuTGlzdDsKCmltcG9ydCBvcmcuZWNsaXBzZS5lbWYuZWNvcmUuRU9iamVjdDsKCmltcG9ydCBvcmcuZWNsaXBzZS5lbWYuZWVmLnJ1bnRpbWUuYXBpLmNvbXBvbmVudC5JUHJvcGVydGllc0VkaXRpb25Db21wb25lbnQ7CgppbXBvcnQgb3JnLmVjbGlwc2UuZW1mLmVlZi5ydW50aW1lLmFwaS5ub3RpZnkuSVByb3BlcnRpZXNFZGl0aW9uRXZlbnQ7CgppbXBvcnQgb3JnLmVjbGlwc2UuZW1mLmVlZi5ydW50aW1lLmFwaS5wYXJ0cy5JU1dUUHJvcGVydGllc0VkaXRpb25QYXJ0OwoKaW1wb3J0IG9yZy5lY2xpcHNlLmVtZi5lZWYucnVudGltZS5jb250ZXh0LmltcGwuRU9iamVjdFByb3BlcnRpZXNFZGl0aW9uQ29udGV4dDsKCmltcG9ydCBvcmcuZWNsaXBzZS5lbWYuZWVmLnJ1bnRpbWUuaW1wbC5ub3RpZnkuUHJvcGVydGllc0VkaXRpb25FdmVudDsKCmltcG9ydCBvcmcuZWNsaXBzZS5lbWYuZWVmLnJ1bnRpbWUuaW1wbC5wYXJ0cy5Db21wb3NpdGVQcm9wZXJ0aWVzRWRpdGlvblBhcnQ7CgppbXBvcnQgb3JnLmVjbGlwc2UuZW1mLmVlZi5ydW50aW1lLnBvbGljaWVzLlByb3BlcnRpZXNFZGl0aW5nUG9saWN5OwoKaW1wb3J0IG9yZy5lY2xpcHNlLmVtZi5lZWYucnVudGltZS5wcm92aWRlcnMuUHJvcGVydGllc0VkaXRpbmdQcm92aWRlcjsKCmltcG9ydCBvcmcuZWNsaXBzZS5lbWYuZWVmLnJ1bnRpbWUudWkucGFydHMuUGFydENvbXBvc2VyOwoKaW1wb3J0IG9yZy5lY2xpcHNlLmVtZi5lZWYucnVudGltZS51aS5wYXJ0cy5zZXF1ZW5jZS5CaW5kaW5nQ29tcG9zaXRpb25TZXF1ZW5jZTsKaW1wb3J0IG9yZy5lY2xpcHNlLmVtZi5lZWYucnVudGltZS51aS5wYXJ0cy5zZXF1ZW5jZS5Db21wb3NpdGlvblNlcXVlbmNlOwppbXBvcnQgb3JnLmVjbGlwc2UuZW1mLmVlZi5ydW50aW1lLnVpLnBhcnRzLnNlcXVlbmNlLkNvbXBvc2l0aW9uU3RlcDsKCmltcG9ydCBvcmcuZWNsaXBzZS5lbWYuZWVmLnJ1bnRpbWUudWkudXRpbHMuRWRpdGluZ1V0aWxzOwoKaW1wb3J0IG9yZy5lY2xpcHNlLmVtZi5lZWYucnVudGltZS51aS53aWRnZXRzLlJlZmVyZW5jZXNUYWJsZTsKCmltcG9ydCBvcmcuZWNsaXBzZS5lbWYuZWVmLnJ1bnRpbWUudWkud2lkZ2V0cy5SZWZlcmVuY2VzVGFibGUuUmVmZXJlbmNlc1RhYmxlTGlzdGVuZXI7CgppbXBvcnQgb3JnLmVjbGlwc2UuZW1mLmVlZi5ydW50aW1lLnVpLndpZGdldHMuU1dUVXRpbHM7CmltcG9ydCBvcmcuZWNsaXBzZS5lbWYuZWVmLnJ1bnRpbWUudWkud2lkZ2V0cy5UYWJFbGVtZW50VHJlZVNlbGVjdGlvbkRpYWxvZzsKCmltcG9ydCBvcmcuZWNsaXBzZS5lbWYuZWVmLnJ1bnRpbWUudWkud2lkZ2V0cy5yZWZlcmVuY2VzdGFibGUuUmVmZXJlbmNlc1RhYmxlQ29udGVudFByb3ZpZGVyOwppbXBvcnQgb3JnLmVjbGlwc2UuZW1mLmVlZi5ydW50aW1lLnVpLndpZGdldHMucmVmZXJlbmNlc3RhYmxlLlJlZmVyZW5jZXNUYWJsZVNldHRpbmdzOwoKaW1wb3J0IG9yZy5lY2xpcHNlLmpmYWNlLnZpZXdlcnMuSVN0cnVjdHVyZWRTZWxlY3Rpb247CmltcG9ydCBvcmcuZWNsaXBzZS5qZmFjZS52aWV3ZXJzLlZpZXdlckZpbHRlcjsKCmltcG9ydCBvcmcuZWNsaXBzZS5zd3QuU1dUOwoKaW1wb3J0IG9yZy5lY2xpcHNlLnN3dC5ldmVudHMuRm9jdXNBZGFwdGVyOwppbXBvcnQgb3JnLmVjbGlwc2Uuc3d0LmV2ZW50cy5Gb2N1c0V2ZW50OwppbXBvcnQgb3JnLmVjbGlwc2Uuc3d0LmV2ZW50cy5LZXlBZGFwdGVyOwppbXBvcnQgb3JnLmVjbGlwc2Uuc3d0LmV2ZW50cy5LZXlFdmVudDsKaW1wb3J0IG9yZy5lY2xpcHNlLnN3dC5ldmVudHMuU2VsZWN0aW9uQWRhcHRlcjsKaW1wb3J0IG9yZy5lY2xpcHNlLnN3dC5ldmVudHMuU2VsZWN0aW9uRXZlbnQ7CgppbXBvcnQgb3JnLmVjbGlwc2Uuc3d0LmxheW91dC5HcmlkRGF0YTsKaW1wb3J0IG9yZy5lY2xpcHNlLnN3dC5sYXlvdXQuR3JpZExheW91dDsKCmltcG9ydCBvcmcuZWNsaXBzZS5zd3Qud2lkZ2V0cy5Db21wb3NpdGU7CmltcG9ydCBvcmcuZWNsaXBzZS5zd3Qud2lkZ2V0cy5Hcm91cDsKaW1wb3J0IG9yZy5lY2xpcHNlLnN3dC53aWRnZXRzLkxhYmVsOwppbXBvcnQgb3JnLmVjbGlwc2Uuc3d0LndpZGdldHMuVGV4dDsKCmltcG9ydCBvcmcuZWNsaXBzZS5vcGVuY2VydC5hcG0uYmFzZWxpbmUuYmFzZWxpbmUucGFydHMuQmFzZUFydGVmYWN0UHJvcGVydGllc0VkaXRpb25QYXJ0OwppbXBvcnQgb3JnLmVjbGlwc2Uub3BlbmNlcnQuYXBtLmJhc2VsaW5lLmJhc2VsaW5lLnBhcnRzLkJhc2VsaW5lVmlld3NSZXBvc2l0b3J5OwoKaW1wb3J0IG9yZy5lY2xpcHNlLm9wZW5jZXJ0LmFwbS5iYXNlbGluZS5iYXNlbGluZS5wcm92aWRlcnMuQmFzZWxpbmVNZXNzYWdlczsKCi8vIEVuZCBvZiB1c2VyIGNvZGUKCi8qKgogKiAKICogCiAqLwpwdWJsaWMgY2xhc3MgQmFzZUFydGVmYWN0UHJvcGVydGllc0VkaXRpb25QYXJ0SW1wbCBleHRlbmRzIENvbXBvc2l0ZVByb3BlcnRpZXNFZGl0aW9uUGFydCBpbXBsZW1lbnRzIElTV1RQcm9wZXJ0aWVzRWRpdGlvblBhcnQsIEJhc2VBcnRlZmFjdFByb3BlcnRpZXNFZGl0aW9uUGFydCB7CgoJcHJvdGVjdGVkIFRleHQgaWQ7Cglwcm90ZWN0ZWQgVGV4dCBuYW1lOwoJcHJvdGVjdGVkIFRleHQgZGVzY3JpcHRpb247Cglwcm90ZWN0ZWQgVGV4dCByZWZlcmVuY2U7Cglwcm90ZWN0ZWQgUmVmZXJlbmNlc1RhYmxlIGNvbnN0cmFpbmluZ1JlcXVpcmVtZW50OwoJcHJvdGVjdGVkIExpc3Q8Vmlld2VyRmlsdGVyPiBjb25zdHJhaW5pbmdSZXF1aXJlbWVudEJ1c2luZXNzRmlsdGVycyA9IG5ldyBBcnJheUxpc3Q8Vmlld2VyRmlsdGVyPigpOwoJcHJvdGVjdGVkIExpc3Q8Vmlld2VyRmlsdGVyPiBjb25zdHJhaW5pbmdSZXF1aXJlbWVudEZpbHRlcnMgPSBuZXcgQXJyYXlMaXN0PFZpZXdlckZpbHRlcj4oKTsKCXByb3RlY3RlZCBSZWZlcmVuY2VzVGFibGUgYXBwbGljYWJsZVRlY2huaXF1ZTsKCXByb3RlY3RlZCBMaXN0PFZpZXdlckZpbHRlcj4gYXBwbGljYWJsZVRlY2huaXF1ZUJ1c2luZXNzRmlsdGVycyA9IG5ldyBBcnJheUxpc3Q8Vmlld2VyRmlsdGVyPigpOwoJcHJvdGVjdGVkIExpc3Q8Vmlld2VyRmlsdGVyPiBhcHBsaWNhYmxlVGVjaG5pcXVlRmlsdGVycyA9IG5ldyBBcnJheUxpc3Q8Vmlld2VyRmlsdGVyPigpOwoJcHJvdGVjdGVkIFJlZmVyZW5jZXNUYWJsZSBvd25lZFJlbDsKCXByb3RlY3RlZCBMaXN0PFZpZXdlckZpbHRlcj4gb3duZWRSZWxCdXNpbmVzc0ZpbHRlcnMgPSBuZXcgQXJyYXlMaXN0PFZpZXdlckZpbHRlcj4oKTsKCXByb3RlY3RlZCBMaXN0PFZpZXdlckZpbHRlcj4gb3duZWRSZWxGaWx0ZXJzID0gbmV3IEFycmF5TGlzdDxWaWV3ZXJGaWx0ZXI+KCk7Cglwcm90ZWN0ZWQgUmVmZXJlbmNlc1RhYmxlIHByb3BlcnR5OwoJcHJvdGVjdGVkIExpc3Q8Vmlld2VyRmlsdGVyPiBwcm9wZXJ0eUJ1c2luZXNzRmlsdGVycyA9IG5ldyBBcnJheUxpc3Q8Vmlld2VyRmlsdGVyPigpOwoJcHJvdGVjdGVkIExpc3Q8Vmlld2VyRmlsdGVyPiBwcm9wZXJ0eUZpbHRlcnMgPSBuZXcgQXJyYXlMaXN0PFZpZXdlckZpbHRlcj4oKTsKCgoKCS8qKgoJICogRGVmYXVsdCBjb25zdHJ1Y3RvcgoJICogQHBhcmFtIGVkaXRpb25Db21wb25lbnQgdGhlIHtAbGluayBJUHJvcGVydGllc0VkaXRpb25Db21wb25lbnR9IHRoYXQgbWFuYWdlIHRoaXMgcGFydAoJICogCgkgKi8KCXB1YmxpYyBCYXNlQXJ0ZWZhY3RQcm9wZXJ0aWVzRWRpdGlvblBhcnRJbXBsKElQcm9wZXJ0aWVzRWRpdGlvbkNvbXBvbmVudCBlZGl0aW9uQ29tcG9uZW50KSB7CgkJc3VwZXIoZWRpdGlvbkNvbXBvbmVudCk7Cgl9CgoJLyoqCgkgKiB7QGluaGVyaXREb2N9CgkgKiAKCSAqIEBzZWUgb3JnLmVjbGlwc2UuZW1mLmVlZi5ydW50aW1lLmFwaS5wYXJ0cy5JU1dUUHJvcGVydGllc0VkaXRpb25QYXJ0IwoJICogCQkJY3JlYXRlRmlndXJlKG9yZy5lY2xpcHNlLnN3dC53aWRnZXRzLkNvbXBvc2l0ZSkKCSAqIAoJICovCglwdWJsaWMgQ29tcG9zaXRlIGNyZWF0ZUZpZ3VyZShmaW5hbCBDb21wb3NpdGUgcGFyZW50KSB7CgkJdmlldyA9IG5ldyBDb21wb3NpdGUocGFyZW50LCBTV1QuTk9ORSk7CgkJR3JpZExheW91dCBsYXlvdXQgPSBuZXcgR3JpZExheW91dCgpOwoJCWxheW91dC5udW1Db2x1bW5zID0gMzsKCQl2aWV3LnNldExheW91dChsYXlvdXQpOwoJCWNyZWF0ZUNvbnRyb2xzKHZpZXcpOwoJCXJldHVybiB2aWV3OwoJfQoKCS8qKgoJICoge0Bpbmhlcml0RG9jfQoJICogCgkgKiBAc2VlIG9yZy5lY2xpcHNlLmVtZi5lZWYucnVudGltZS5hcGkucGFydHMuSVNXVFByb3BlcnRpZXNFZGl0aW9uUGFydCMKCSAqIAkJCWNyZWF0ZUNvbnRyb2xzKG9yZy5lY2xpcHNlLnN3dC53aWRnZXRzLkNvbXBvc2l0ZSkKCSAqIAoJICovCglwdWJsaWMgdm9pZCBjcmVhdGVDb250cm9scyhDb21wb3NpdGUgdmlldykgeyAKCQlDb21wb3NpdGlvblNlcXVlbmNlIGJhc2VBcnRlZmFjdFN0ZXAgPSBuZXcgQmluZGluZ0NvbXBvc2l0aW9uU2VxdWVuY2UocHJvcGVydGllc0VkaXRpb25Db21wb25lbnQpOwoJCUNvbXBvc2l0aW9uU3RlcCBwcm9wZXJ0aWVzU3RlcCA9IGJhc2VBcnRlZmFjdFN0ZXAuYWRkU3RlcChCYXNlbGluZVZpZXdzUmVwb3NpdG9yeS5CYXNlQXJ0ZWZhY3QuUHJvcGVydGllcy5jbGFzcyk7CgkJcHJvcGVydGllc1N0ZXAuYWRkU3RlcChCYXNlbGluZVZpZXdzUmVwb3NpdG9yeS5CYXNlQXJ0ZWZhY3QuUHJvcGVydGllcy5pZCk7CgkJcHJvcGVydGllc1N0ZXAuYWRkU3RlcChCYXNlbGluZVZpZXdzUmVwb3NpdG9yeS5CYXNlQXJ0ZWZhY3QuUHJvcGVydGllcy5uYW1lKTsKCQlwcm9wZXJ0aWVzU3RlcC5hZGRTdGVwKEJhc2VsaW5lVmlld3NSZXBvc2l0b3J5LkJhc2VBcnRlZmFjdC5Qcm9wZXJ0aWVzLmRlc2NyaXB0aW9uKTsKCQlwcm9wZXJ0aWVzU3RlcC5hZGRTdGVwKEJhc2VsaW5lVmlld3NSZXBvc2l0b3J5LkJhc2VBcnRlZmFjdC5Qcm9wZXJ0aWVzLnJlZmVyZW5jZSk7CgkJcHJvcGVydGllc1N0ZXAuYWRkU3RlcChCYXNlbGluZVZpZXdzUmVwb3NpdG9yeS5CYXNlQXJ0ZWZhY3QuUHJvcGVydGllcy5jb25zdHJhaW5pbmdSZXF1aXJlbWVudCk7CgkJcHJvcGVydGllc1N0ZXAuYWRkU3RlcChCYXNlbGluZVZpZXdzUmVwb3NpdG9yeS5CYXNlQXJ0ZWZhY3QuUHJvcGVydGllcy5hcHBsaWNhYmxlVGVjaG5pcXVlKTsKCQlwcm9wZXJ0aWVzU3RlcC5hZGRTdGVwKEJhc2VsaW5lVmlld3NSZXBvc2l0b3J5LkJhc2VBcnRlZmFjdC5Qcm9wZXJ0aWVzLm93bmVkUmVsKTsKCQlwcm9wZXJ0aWVzU3RlcC5hZGRTdGVwKEJhc2VsaW5lVmlld3NSZXBvc2l0b3J5LkJhc2VBcnRlZmFjdC5Qcm9wZXJ0aWVzLnByb3BlcnR5KTsKCQkKCQkKCQljb21wb3NlciA9IG5ldyBQYXJ0Q29tcG9zZXIoYmFzZUFydGVmYWN0U3RlcCkgewoKCQkJQE92ZXJyaWRlCgkJCXB1YmxpYyBDb21wb3NpdGUgYWRkVG9QYXJ0KENvbXBvc2l0ZSBwYXJlbnQsIE9iamVjdCBrZXkpIHsKCQkJCWlmIChrZXkgPT0gQmFzZWxpbmVWaWV3c1JlcG9zaXRvcnkuQmFzZUFydGVmYWN0LlByb3BlcnRpZXMuY2xhc3MpIHsKCQkJCQlyZXR1cm4gY3JlYXRlUHJvcGVydGllc0dyb3VwKHBhcmVudCk7CgkJCQl9CgkJCQlpZiAoa2V5ID09IEJhc2VsaW5lVmlld3NSZXBvc2l0b3J5LkJhc2VBcnRlZmFjdC5Qcm9wZXJ0aWVzLmlkKSB7CgkJCQkJcmV0dXJuIGNyZWF0ZUlkVGV4dChwYXJlbnQpOwoJCQkJfQoJCQkJaWYgKGtleSA9PSBCYXNlbGluZVZpZXdzUmVwb3NpdG9yeS5CYXNlQXJ0ZWZhY3QuUHJvcGVydGllcy5uYW1lKSB7CgkJCQkJcmV0dXJuIGNyZWF0ZU5hbWVUZXh0KHBhcmVudCk7CgkJCQl9CgkJCQlpZiAoa2V5ID09IEJhc2VsaW5lVmlld3NSZXBvc2l0b3J5LkJhc2VBcnRlZmFjdC5Qcm9wZXJ0aWVzLmRlc2NyaXB0aW9uKSB7CgkJCQkJcmV0dXJuIGNyZWF0ZURlc2NyaXB0aW9uVGV4dGFyZWEocGFyZW50KTsKCQkJCX0KCQkJCWlmIChrZXkgPT0gQmFzZWxpbmVWaWV3c1JlcG9zaXRvcnkuQmFzZUFydGVmYWN0LlByb3BlcnRpZXMucmVmZXJlbmNlKSB7CgkJCQkJcmV0dXJuIGNyZWF0ZVJlZmVyZW5jZVRleHQocGFyZW50KTsKCQkJCX0KCQkJCWlmIChrZXkgPT0gQmFzZWxpbmVWaWV3c1JlcG9zaXRvcnkuQmFzZUFydGVmYWN0LlByb3BlcnRpZXMuY29uc3RyYWluaW5nUmVxdWlyZW1lbnQpIHsKCQkJCQlyZXR1cm4gY3JlYXRlQ29uc3RyYWluaW5nUmVxdWlyZW1lbnRBZHZhbmNlZFJlZmVyZW5jZXNUYWJsZShwYXJlbnQpOwoJCQkJfQoJCQkJaWYgKGtleSA9PSBCYXNlbGluZVZpZXdzUmVwb3NpdG9yeS5CYXNlQXJ0ZWZhY3QuUHJvcGVydGllcy5hcHBsaWNhYmxlVGVjaG5pcXVlKSB7CgkJCQkJcmV0dXJuIGNyZWF0ZUFwcGxpY2FibGVUZWNobmlxdWVBZHZhbmNlZFJlZmVyZW5jZXNUYWJsZShwYXJlbnQpOwoJCQkJfQoJCQkJaWYgKGtleSA9PSBCYXNlbGluZVZpZXdzUmVwb3NpdG9yeS5CYXNlQXJ0ZWZhY3QuUHJvcGVydGllcy5vd25lZFJlbCkgewoJCQkJCXJldHVybiBjcmVhdGVPd25lZFJlbEFkdmFuY2VkVGFibGVDb21wb3NpdGlvbihwYXJlbnQpOwoJCQkJfQoJCQkJaWYgKGtleSA9PSBCYXNlbGluZVZpZXdzUmVwb3NpdG9yeS5CYXNlQXJ0ZWZhY3QuUHJvcGVydGllcy5wcm9wZXJ0eSkgewoJCQkJCXJldHVybiBjcmVhdGVQcm9wZXJ0eUFkdmFuY2VkUmVmZXJlbmNlc1RhYmxlKHBhcmVudCk7CgkJCQl9CgkJCQlyZXR1cm4gcGFyZW50OwoJCQl9CgkJfTsKCQljb21wb3Nlci5jb21wb3NlKHZpZXcpOwoJfQoKCS8qKgoJICogCgkgKi8KCXByb3RlY3RlZCBDb21wb3NpdGUgY3JlYXRlUHJvcGVydGllc0dyb3VwKENvbXBvc2l0ZSBwYXJlbnQpIHsKCQlHcm91cCBwcm9wZXJ0aWVzR3JvdXAgPSBuZXcgR3JvdXAocGFyZW50LCBTV1QuTk9ORSk7CgkJcHJvcGVydGllc0dyb3VwLnNldFRleHQoQmFzZWxpbmVNZXNzYWdlcy5CYXNlQXJ0ZWZhY3RQcm9wZXJ0aWVzRWRpdGlvblBhcnRfUHJvcGVydGllc0dyb3VwTGFiZWwpOwoJCUdyaWREYXRhIHByb3BlcnRpZXNHcm91cERhdGEgPSBuZXcgR3JpZERhdGEoR3JpZERhdGEuRklMTF9IT1JJWk9OVEFMKTsKCQlwcm9wZXJ0aWVzR3JvdXBEYXRhLmhvcml6b250YWxTcGFuID0gMzsKCQlwcm9wZXJ0aWVzR3JvdXAuc2V0TGF5b3V0RGF0YShwcm9wZXJ0aWVzR3JvdXBEYXRhKTsKCQlHcmlkTGF5b3V0IHByb3BlcnRpZXNHcm91cExheW91dCA9IG5ldyBHcmlkTGF5b3V0KCk7CgkJcHJvcGVydGllc0dyb3VwTGF5b3V0Lm51bUNvbHVtbnMgPSAzOwoJCXByb3BlcnRpZXNHcm91cC5zZXRMYXlvdXQocHJvcGVydGllc0dyb3VwTGF5b3V0KTsKCQlyZXR1cm4gcHJvcGVydGllc0dyb3VwOwoJfQoKCQoJcHJvdGVjdGVkIENvbXBvc2l0ZSBjcmVhdGVJZFRleHQoQ29tcG9zaXRlIHBhcmVudCkgewoJCWNyZWF0ZURlc2NyaXB0aW9uKHBhcmVudCwgQmFzZWxpbmVWaWV3c1JlcG9zaXRvcnkuQmFzZUFydGVmYWN0LlByb3BlcnRpZXMuaWQsIEJhc2VsaW5lTWVzc2FnZXMuQmFzZUFydGVmYWN0UHJvcGVydGllc0VkaXRpb25QYXJ0X0lkTGFiZWwpOwoJCWlkID0gU1dUVXRpbHMuY3JlYXRlU2Nyb2xsYWJsZVRleHQocGFyZW50LCBTV1QuQk9SREVSKTsKCQlHcmlkRGF0YSBpZERhdGEgPSBuZXcgR3JpZERhdGEoR3JpZERhdGEuRklMTF9IT1JJWk9OVEFMKTsKCQlpZC5zZXRMYXlvdXREYXRhKGlkRGF0YSk7CgkJaWQuYWRkRm9jdXNMaXN0ZW5lcihuZXcgRm9jdXNBZGFwdGVyKCkgewoKCQkJLyoqCgkJCSAqIHtAaW5oZXJpdERvY30KCQkJICogCgkJCSAqIEBzZWUgb3JnLmVjbGlwc2Uuc3d0LmV2ZW50cy5Gb2N1c0FkYXB0ZXIjZm9jdXNMb3N0KG9yZy5lY2xpcHNlLnN3dC5ldmVudHMuRm9jdXNFdmVudCkKCQkJICogCgkJCSAqLwoJCQlAT3ZlcnJpZGUKCQkJQFN1cHByZXNzV2FybmluZ3MoInN5bnRoZXRpYy1hY2Nlc3MiKQoJCQlwdWJsaWMgdm9pZCBmb2N1c0xvc3QoRm9jdXNFdmVudCBlKSB7CgkJCQlpZiAocHJvcGVydGllc0VkaXRpb25Db21wb25lbnQgIT0gbnVsbCkKCQkJCQlwcm9wZXJ0aWVzRWRpdGlvbkNvbXBvbmVudC5maXJlUHJvcGVydGllc0NoYW5nZWQobmV3IFByb3BlcnRpZXNFZGl0aW9uRXZlbnQoQmFzZUFydGVmYWN0UHJvcGVydGllc0VkaXRpb25QYXJ0SW1wbC50aGlzLCBCYXNlbGluZVZpZXdzUmVwb3NpdG9yeS5CYXNlQXJ0ZWZhY3QuUHJvcGVydGllcy5pZCwgUHJvcGVydGllc0VkaXRpb25FdmVudC5DT01NSVQsIFByb3BlcnRpZXNFZGl0aW9uRXZlbnQuU0VULCBudWxsLCBpZC5nZXRUZXh0KCkpKTsKCQkJfQoKCQl9KTsKCQlpZC5hZGRLZXlMaXN0ZW5lcihuZXcgS2V5QWRhcHRlcigpIHsKCgkJCS8qKgoJCQkgKiB7QGluaGVyaXREb2N9CgkJCSAqIAoJCQkgKiBAc2VlIG9yZy5lY2xpcHNlLnN3dC5ldmVudHMuS2V5QWRhcHRlciNrZXlQcmVzc2VkKG9yZy5lY2xpcHNlLnN3dC5ldmVudHMuS2V5RXZlbnQpCgkJCSAqIAoJCQkgKi8KCQkJQE92ZXJyaWRlCgkJCUBTdXBwcmVzc1dhcm5pbmdzKCJzeW50aGV0aWMtYWNjZXNzIikKCQkJcHVibGljIHZvaWQga2V5UHJlc3NlZChLZXlFdmVudCBlKSB7CgkJCQlpZiAoZS5jaGFyYWN0ZXIgPT0gU1dULkNSKSB7CgkJCQkJaWYgKHByb3BlcnRpZXNFZGl0aW9uQ29tcG9uZW50ICE9IG51bGwpCgkJCQkJCXByb3BlcnRpZXNFZGl0aW9uQ29tcG9uZW50LmZpcmVQcm9wZXJ0aWVzQ2hhbmdlZChuZXcgUHJvcGVydGllc0VkaXRpb25FdmVudChCYXNlQXJ0ZWZhY3RQcm9wZXJ0aWVzRWRpdGlvblBhcnRJbXBsLnRoaXMsIEJhc2VsaW5lVmlld3NSZXBvc2l0b3J5LkJhc2VBcnRlZmFjdC5Qcm9wZXJ0aWVzLmlkLCBQcm9wZXJ0aWVzRWRpdGlvbkV2ZW50LkNPTU1JVCwgUHJvcGVydGllc0VkaXRpb25FdmVudC5TRVQsIG51bGwsIGlkLmdldFRleHQoKSkpOwoJCQkJfQoJCQl9CgoJCX0pOwoJCUVkaXRpbmdVdGlscy5zZXRJRChpZCwgQmFzZWxpbmVWaWV3c1JlcG9zaXRvcnkuQmFzZUFydGVmYWN0LlByb3BlcnRpZXMuaWQpOwoJCUVkaXRpbmdVdGlscy5zZXRFRUZ0eXBlKGlkLCAiZWVmOjpUZXh0Iik7IC8vJE5PTi1OTFMtMSQKCQlTV1RVdGlscy5jcmVhdGVIZWxwQnV0dG9uKHBhcmVudCwgcHJvcGVydGllc0VkaXRpb25Db21wb25lbnQuZ2V0SGVscENvbnRlbnQoQmFzZWxpbmVWaWV3c1JlcG9zaXRvcnkuQmFzZUFydGVmYWN0LlByb3BlcnRpZXMuaWQsIEJhc2VsaW5lVmlld3NSZXBvc2l0b3J5LlNXVF9LSU5EKSwgbnVsbCk7IC8vJE5PTi1OTFMtMSQKCQkvLyBTdGFydCBvZiB1c2VyIGNvZGUgZm9yIGNyZWF0ZUlkVGV4dAoKCQkvLyBFbmQgb2YgdXNlciBjb2RlCgkJcmV0dXJuIHBhcmVudDsKCX0KCgkKCXByb3RlY3RlZCBDb21wb3NpdGUgY3JlYXRlTmFtZVRleHQoQ29tcG9zaXRlIHBhcmVudCkgewoJCWNyZWF0ZURlc2NyaXB0aW9uKHBhcmVudCwgQmFzZWxpbmVWaWV3c1JlcG9zaXRvcnkuQmFzZUFydGVmYWN0LlByb3BlcnRpZXMubmFtZSwgQmFzZWxpbmVNZXNzYWdlcy5CYXNlQXJ0ZWZhY3RQcm9wZXJ0aWVzRWRpdGlvblBhcnRfTmFtZUxhYmVsKTsKCQluYW1lID0gU1dUVXRpbHMuY3JlYXRlU2Nyb2xsYWJsZVRleHQocGFyZW50LCBTV1QuQk9SREVSKTsKCQlHcmlkRGF0YSBuYW1lRGF0YSA9IG5ldyBHcmlkRGF0YShHcmlkRGF0YS5GSUxMX0hPUklaT05UQUwpOwoJCW5hbWUuc2V0TGF5b3V0RGF0YShuYW1lRGF0YSk7CgkJbmFtZS5hZGRGb2N1c0xpc3RlbmVyKG5ldyBGb2N1c0FkYXB0ZXIoKSB7CgoJCQkvKioKCQkJICoge0Bpbmhlcml0RG9jfQoJCQkgKiAKCQkJICogQHNlZSBvcmcuZWNsaXBzZS5zd3QuZXZlbnRzLkZvY3VzQWRhcHRlciNmb2N1c0xvc3Qob3JnLmVjbGlwc2Uuc3d0LmV2ZW50cy5Gb2N1c0V2ZW50KQoJCQkgKiAKCQkJICovCgkJCUBPdmVycmlkZQoJCQlAU3VwcHJlc3NXYXJuaW5ncygic3ludGhldGljLWFjY2VzcyIpCgkJCXB1YmxpYyB2b2lkIGZvY3VzTG9zdChGb2N1c0V2ZW50IGUpIHsKCQkJCWlmIChwcm9wZXJ0aWVzRWRpdGlvbkNvbXBvbmVudCAhPSBudWxsKQoJCQkJCXByb3BlcnRpZXNFZGl0aW9uQ29tcG9uZW50LmZpcmVQcm9wZXJ0aWVzQ2hhbmdlZChuZXcgUHJvcGVydGllc0VkaXRpb25FdmVudChCYXNlQXJ0ZWZhY3RQcm9wZXJ0aWVzRWRpdGlvblBhcnRJbXBsLnRoaXMsIEJhc2VsaW5lVmlld3NSZXBvc2l0b3J5LkJhc2VBcnRlZmFjdC5Qcm9wZXJ0aWVzLm5hbWUsIFByb3BlcnRpZXNFZGl0aW9uRXZlbnQuQ09NTUlULCBQcm9wZXJ0aWVzRWRpdGlvbkV2ZW50LlNFVCwgbnVsbCwgbmFtZS5nZXRUZXh0KCkpKTsKCQkJfQoKCQl9KTsKCQluYW1lLmFkZEtleUxpc3RlbmVyKG5ldyBLZXlBZGFwdGVyKCkgewoKCQkJLyoqCgkJCSAqIHtAaW5oZXJpdERvY30KCQkJICogCgkJCSAqIEBzZWUgb3JnLmVjbGlwc2Uuc3d0LmV2ZW50cy5LZXlBZGFwdGVyI2tleVByZXNzZWQob3JnLmVjbGlwc2Uuc3d0LmV2ZW50cy5LZXlFdmVudCkKCQkJICogCgkJCSAqLwoJCQlAT3ZlcnJpZGUKCQkJQFN1cHByZXNzV2FybmluZ3MoInN5bnRoZXRpYy1hY2Nlc3MiKQoJCQlwdWJsaWMgdm9pZCBrZXlQcmVzc2VkKEtleUV2ZW50IGUpIHsKCQkJCWlmIChlLmNoYXJhY3RlciA9PSBTV1QuQ1IpIHsKCQkJCQlpZiAocHJvcGVydGllc0VkaXRpb25Db21wb25lbnQgIT0gbnVsbCkKCQkJCQkJcHJvcGVydGllc0VkaXRpb25Db21wb25lbnQuZmlyZVByb3BlcnRpZXNDaGFuZ2VkKG5ldyBQcm9wZXJ0aWVzRWRpdGlvbkV2ZW50KEJhc2VBcnRlZmFjdFByb3BlcnRpZXNFZGl0aW9uUGFydEltcGwudGhpcywgQmFzZWxpbmVWaWV3c1JlcG9zaXRvcnkuQmFzZUFydGVmYWN0LlByb3BlcnRpZXMubmFtZSwgUHJvcGVydGllc0VkaXRpb25FdmVudC5DT01NSVQsIFByb3BlcnRpZXNFZGl0aW9uRXZlbnQuU0VULCBudWxsLCBuYW1lLmdldFRleHQoKSkpOwoJCQkJfQoJCQl9CgoJCX0pOwoJCUVkaXRpbmdVdGlscy5zZXRJRChuYW1lLCBCYXNlbGluZVZpZXdzUmVwb3NpdG9yeS5CYXNlQXJ0ZWZhY3QuUHJvcGVydGllcy5uYW1lKTsKCQlFZGl0aW5nVXRpbHMuc2V0RUVGdHlwZShuYW1lLCAiZWVmOjpUZXh0Iik7IC8vJE5PTi1OTFMtMSQKCQlTV1RVdGlscy5jcmVhdGVIZWxwQnV0dG9uKHBhcmVudCwgcHJvcGVydGllc0VkaXRpb25Db21wb25lbnQuZ2V0SGVscENvbnRlbnQoQmFzZWxpbmVWaWV3c1JlcG9zaXRvcnkuQmFzZUFydGVmYWN0LlByb3BlcnRpZXMubmFtZSwgQmFzZWxpbmVWaWV3c1JlcG9zaXRvcnkuU1dUX0tJTkQpLCBudWxsKTsgLy8kTk9OLU5MUy0xJAoJCS8vIFN0YXJ0IG9mIHVzZXIgY29kZSBmb3IgY3JlYXRlTmFtZVRleHQKCgkJLy8gRW5kIG9mIHVzZXIgY29kZQoJCXJldHVybiBwYXJlbnQ7Cgl9CgoJCglwcm90ZWN0ZWQgQ29tcG9zaXRlIGNyZWF0ZURlc2NyaXB0aW9uVGV4dGFyZWEoQ29tcG9zaXRlIHBhcmVudCkgewoJCUxhYmVsIGRlc2NyaXB0aW9uTGFiZWwgPSBjcmVhdGVEZXNjcmlwdGlvbihwYXJlbnQsIEJhc2VsaW5lVmlld3NSZXBvc2l0b3J5LkJhc2VBcnRlZmFjdC5Qcm9wZXJ0aWVzLmRlc2NyaXB0aW9uLCBCYXNlbGluZU1lc3NhZ2VzLkJhc2VBcnRlZmFjdFByb3BlcnRpZXNFZGl0aW9uUGFydF9EZXNjcmlwdGlvbkxhYmVsKTsKCQlHcmlkRGF0YSBkZXNjcmlwdGlvbkxhYmVsRGF0YSA9IG5ldyBHcmlkRGF0YShHcmlkRGF0YS5GSUxMX0hPUklaT05UQUwpOwoJCWRlc2NyaXB0aW9uTGFiZWxEYXRhLmhvcml6b250YWxTcGFuID0gMzsKCQlkZXNjcmlwdGlvbkxhYmVsLnNldExheW91dERhdGEoZGVzY3JpcHRpb25MYWJlbERhdGEpOwoJCWRlc2NyaXB0aW9uID0gU1dUVXRpbHMuY3JlYXRlU2Nyb2xsYWJsZVRleHQocGFyZW50LCBTV1QuQk9SREVSIHwgU1dULldSQVAgfCBTV1QuTVVMVEkgfCBTV1QuVl9TQ1JPTEwpOwoJCUdyaWREYXRhIGRlc2NyaXB0aW9uRGF0YSA9IG5ldyBHcmlkRGF0YShHcmlkRGF0YS5GSUxMX0hPUklaT05UQUwpOwoJCWRlc2NyaXB0aW9uRGF0YS5ob3Jpem9udGFsU3BhbiA9IDI7CgkJZGVzY3JpcHRpb25EYXRhLmhlaWdodEhpbnQgPSA4MDsKCQlkZXNjcmlwdGlvbkRhdGEud2lkdGhIaW50ID0gMjAwOwoJCWRlc2NyaXB0aW9uLnNldExheW91dERhdGEoZGVzY3JpcHRpb25EYXRhKTsKCQlkZXNjcmlwdGlvbi5hZGRGb2N1c0xpc3RlbmVyKG5ldyBGb2N1c0FkYXB0ZXIoKSB7CgoJCQkvKioKCQkJICoge0Bpbmhlcml0RG9jfQoJCQkgKiAKCQkJICogQHNlZSBvcmcuZWNsaXBzZS5zd3QuZXZlbnRzLkZvY3VzQWRhcHRlciNmb2N1c0xvc3Qob3JnLmVjbGlwc2Uuc3d0LmV2ZW50cy5Gb2N1c0V2ZW50KQoJCQkgKiAKCQkJICovCgkJCXB1YmxpYyB2b2lkIGZvY3VzTG9zdChGb2N1c0V2ZW50IGUpIHsKCQkJCWlmIChwcm9wZXJ0aWVzRWRpdGlvbkNvbXBvbmVudCAhPSBudWxsKQoJCQkJCXByb3BlcnRpZXNFZGl0aW9uQ29tcG9uZW50LmZpcmVQcm9wZXJ0aWVzQ2hhbmdlZChuZXcgUHJvcGVydGllc0VkaXRpb25FdmVudChCYXNlQXJ0ZWZhY3RQcm9wZXJ0aWVzRWRpdGlvblBhcnRJbXBsLnRoaXMsIEJhc2VsaW5lVmlld3NSZXBvc2l0b3J5LkJhc2VBcnRlZmFjdC5Qcm9wZXJ0aWVzLmRlc2NyaXB0aW9uLCBQcm9wZXJ0aWVzRWRpdGlvbkV2ZW50LkNPTU1JVCwgUHJvcGVydGllc0VkaXRpb25FdmVudC5TRVQsIG51bGwsIGRlc2NyaXB0aW9uLmdldFRleHQoKSkpOwoJCQl9CgoJCX0pOwoJCUVkaXRpbmdVdGlscy5zZXRJRChkZXNjcmlwdGlvbiwgQmFzZWxpbmVWaWV3c1JlcG9zaXRvcnkuQmFzZUFydGVmYWN0LlByb3BlcnRpZXMuZGVzY3JpcHRpb24pOwoJCUVkaXRpbmdVdGlscy5zZXRFRUZ0eXBlKGRlc2NyaXB0aW9uLCAiZWVmOjpUZXh0YXJlYSIpOyAvLyROT04tTkxTLTEkCgkJU1dUVXRpbHMuY3JlYXRlSGVscEJ1dHRvbihwYXJlbnQsIHByb3BlcnRpZXNFZGl0aW9uQ29tcG9uZW50LmdldEhlbHBDb250ZW50KEJhc2VsaW5lVmlld3NSZXBvc2l0b3J5LkJhc2VBcnRlZmFjdC5Qcm9wZXJ0aWVzLmRlc2NyaXB0aW9uLCBCYXNlbGluZVZpZXdzUmVwb3NpdG9yeS5TV1RfS0lORCksIG51bGwpOyAvLyROT04tTkxTLTEkCgkJLy8gU3RhcnQgb2YgdXNlciBjb2RlIGZvciBjcmVhdGVEZXNjcmlwdGlvblRleHRBcmVhCgoJCS8vIEVuZCBvZiB1c2VyIGNvZGUKCQlyZXR1cm4gcGFyZW50OwoJfQoKCQoJcHJvdGVjdGVkIENvbXBvc2l0ZSBjcmVhdGVSZWZlcmVuY2VUZXh0KENvbXBvc2l0ZSBwYXJlbnQpIHsKCQljcmVhdGVEZXNjcmlwdGlvbihwYXJlbnQsIEJhc2VsaW5lVmlld3NSZXBvc2l0b3J5LkJhc2VBcnRlZmFjdC5Qcm9wZXJ0aWVzLnJlZmVyZW5jZSwgQmFzZWxpbmVNZXNzYWdlcy5CYXNlQXJ0ZWZhY3RQcm9wZXJ0aWVzRWRpdGlvblBhcnRfUmVmZXJlbmNlTGFiZWwpOwoJCXJlZmVyZW5jZSA9IFNXVFV0aWxzLmNyZWF0ZVNjcm9sbGFibGVUZXh0KHBhcmVudCwgU1dULkJPUkRFUik7CgkJR3JpZERhdGEgcmVmZXJlbmNlRGF0YSA9IG5ldyBHcmlkRGF0YShHcmlkRGF0YS5GSUxMX0hPUklaT05UQUwpOwoJCXJlZmVyZW5jZS5zZXRMYXlvdXREYXRhKHJlZmVyZW5jZURhdGEpOwoJCXJlZmVyZW5jZS5hZGRGb2N1c0xpc3RlbmVyKG5ldyBGb2N1c0FkYXB0ZXIoKSB7CgoJCQkvKioKCQkJICoge0Bpbmhlcml0RG9jfQoJCQkgKiAKCQkJICogQHNlZSBvcmcuZWNsaXBzZS5zd3QuZXZlbnRzLkZvY3VzQWRhcHRlciNmb2N1c0xvc3Qob3JnLmVjbGlwc2Uuc3d0LmV2ZW50cy5Gb2N1c0V2ZW50KQoJCQkgKiAKCQkJICovCgkJCUBPdmVycmlkZQoJCQlAU3VwcHJlc3NXYXJuaW5ncygic3ludGhldGljLWFjY2VzcyIpCgkJCXB1YmxpYyB2b2lkIGZvY3VzTG9zdChGb2N1c0V2ZW50IGUpIHsKCQkJCWlmIChwcm9wZXJ0aWVzRWRpdGlvbkNvbXBvbmVudCAhPSBudWxsKQoJCQkJCXByb3BlcnRpZXNFZGl0aW9uQ29tcG9uZW50LmZpcmVQcm9wZXJ0aWVzQ2hhbmdlZChuZXcgUHJvcGVydGllc0VkaXRpb25FdmVudChCYXNlQXJ0ZWZhY3RQcm9wZXJ0aWVzRWRpdGlvblBhcnRJbXBsLnRoaXMsIEJhc2VsaW5lVmlld3NSZXBvc2l0b3J5LkJhc2VBcnRlZmFjdC5Qcm9wZXJ0aWVzLnJlZmVyZW5jZSwgUHJvcGVydGllc0VkaXRpb25FdmVudC5DT01NSVQsIFByb3BlcnRpZXNFZGl0aW9uRXZlbnQuU0VULCBudWxsLCByZWZlcmVuY2UuZ2V0VGV4dCgpKSk7CgkJCX0KCgkJfSk7CgkJcmVmZXJlbmNlLmFkZEtleUxpc3RlbmVyKG5ldyBLZXlBZGFwdGVyKCkgewoKCQkJLyoqCgkJCSAqIHtAaW5oZXJpdERvY30KCQkJICogCgkJCSAqIEBzZWUgb3JnLmVjbGlwc2Uuc3d0LmV2ZW50cy5LZXlBZGFwdGVyI2tleVByZXNzZWQob3JnLmVjbGlwc2Uuc3d0LmV2ZW50cy5LZXlFdmVudCkKCQkJICogCgkJCSAqLwoJCQlAT3ZlcnJpZGUKCQkJQFN1cHByZXNzV2FybmluZ3MoInN5bnRoZXRpYy1hY2Nlc3MiKQoJCQlwdWJsaWMgdm9pZCBrZXlQcmVzc2VkKEtleUV2ZW50IGUpIHsKCQkJCWlmIChlLmNoYXJhY3RlciA9PSBTV1QuQ1IpIHsKCQkJCQlpZiAocHJvcGVydGllc0VkaXRpb25Db21wb25lbnQgIT0gbnVsbCkKCQkJCQkJcHJvcGVydGllc0VkaXRpb25Db21wb25lbnQuZmlyZVByb3BlcnRpZXNDaGFuZ2VkKG5ldyBQcm9wZXJ0aWVzRWRpdGlvbkV2ZW50KEJhc2VBcnRlZmFjdFByb3BlcnRpZXNFZGl0aW9uUGFydEltcGwudGhpcywgQmFzZWxpbmVWaWV3c1JlcG9zaXRvcnkuQmFzZUFydGVmYWN0LlByb3BlcnRpZXMucmVmZXJlbmNlLCBQcm9wZXJ0aWVzRWRpdGlvbkV2ZW50LkNPTU1JVCwgUHJvcGVydGllc0VkaXRpb25FdmVudC5TRVQsIG51bGwsIHJlZmVyZW5jZS5nZXRUZXh0KCkpKTsKCQkJCX0KCQkJfQoKCQl9KTsKCQlFZGl0aW5nVXRpbHMuc2V0SUQocmVmZXJlbmNlLCBCYXNlbGluZVZpZXdzUmVwb3NpdG9yeS5CYXNlQXJ0ZWZhY3QuUHJvcGVydGllcy5yZWZlcmVuY2UpOwoJCUVkaXRpbmdVdGlscy5zZXRFRUZ0eXBlKHJlZmVyZW5jZSwgImVlZjo6VGV4dCIpOyAvLyROT04tTkxTLTEkCgkJU1dUVXRpbHMuY3JlYXRlSGVscEJ1dHRvbihwYXJlbnQsIHByb3BlcnRpZXNFZGl0aW9uQ29tcG9uZW50LmdldEhlbHBDb250ZW50KEJhc2VsaW5lVmlld3NSZXBvc2l0b3J5LkJhc2VBcnRlZmFjdC5Qcm9wZXJ0aWVzLnJlZmVyZW5jZSwgQmFzZWxpbmVWaWV3c1JlcG9zaXRvcnkuU1dUX0tJTkQpLCBudWxsKTsgLy8kTk9OLU5MUy0xJAoJCS8vIFN0YXJ0IG9mIHVzZXIgY29kZSBmb3IgY3JlYXRlUmVmZXJlbmNlVGV4dAoKCQkvLyBFbmQgb2YgdXNlciBjb2RlCgkJcmV0dXJuIHBhcmVudDsKCX0KCgkvKioKCSAqIAoJICovCglwcm90ZWN0ZWQgQ29tcG9zaXRlIGNyZWF0ZUNvbnN0cmFpbmluZ1JlcXVpcmVtZW50QWR2YW5jZWRSZWZlcmVuY2VzVGFibGUoQ29tcG9zaXRlIHBhcmVudCkgewoJCVN0cmluZyBsYWJlbCA9IGdldERlc2NyaXB0aW9uKEJhc2VsaW5lVmlld3NSZXBvc2l0b3J5LkJhc2VBcnRlZmFjdC5Qcm9wZXJ0aWVzLmNvbnN0cmFpbmluZ1JlcXVpcmVtZW50LCBCYXNlbGluZU1lc3NhZ2VzLkJhc2VBcnRlZmFjdFByb3BlcnRpZXNFZGl0aW9uUGFydF9Db25zdHJhaW5pbmdSZXF1aXJlbWVudExhYmVsKTsJCSAKCQl0aGlzLmNvbnN0cmFpbmluZ1JlcXVpcmVtZW50ID0gbmV3IFJlZmVyZW5jZXNUYWJsZShsYWJlbCwgbmV3IFJlZmVyZW5jZXNUYWJsZUxpc3RlbmVyKCkgewoJCQlwdWJsaWMgdm9pZCBoYW5kbGVBZGQoKSB7IGFkZENvbnN0cmFpbmluZ1JlcXVpcmVtZW50KCk7IH0KCQkJcHVibGljIHZvaWQgaGFuZGxlRWRpdChFT2JqZWN0IGVsZW1lbnQpIHsgZWRpdENvbnN0cmFpbmluZ1JlcXVpcmVtZW50KGVsZW1lbnQpOyB9CgkJCXB1YmxpYyB2b2lkIGhhbmRsZU1vdmUoRU9iamVjdCBlbGVtZW50LCBpbnQgb2xkSW5kZXgsIGludCBuZXdJbmRleCkgeyBtb3ZlQ29uc3RyYWluaW5nUmVxdWlyZW1lbnQoZWxlbWVudCwgb2xkSW5kZXgsIG5ld0luZGV4KTsgfQoJCQlwdWJsaWMgdm9pZCBoYW5kbGVSZW1vdmUoRU9iamVjdCBlbGVtZW50KSB7IHJlbW92ZUZyb21Db25zdHJhaW5pbmdSZXF1aXJlbWVudChlbGVtZW50KTsgfQoJCQlwdWJsaWMgdm9pZCBuYXZpZ2F0ZVRvKEVPYmplY3QgZWxlbWVudCkgeyB9CgkJfSk7CgkJdGhpcy5jb25zdHJhaW5pbmdSZXF1aXJlbWVudC5zZXRIZWxwVGV4dChwcm9wZXJ0aWVzRWRpdGlvbkNvbXBvbmVudC5nZXRIZWxwQ29udGVudChCYXNlbGluZVZpZXdzUmVwb3NpdG9yeS5CYXNlQXJ0ZWZhY3QuUHJvcGVydGllcy5jb25zdHJhaW5pbmdSZXF1aXJlbWVudCwgQmFzZWxpbmVWaWV3c1JlcG9zaXRvcnkuU1dUX0tJTkQpKTsKCQl0aGlzLmNvbnN0cmFpbmluZ1JlcXVpcmVtZW50LmNyZWF0ZUNvbnRyb2xzKHBhcmVudCk7CgkJdGhpcy5jb25zdHJhaW5pbmdSZXF1aXJlbWVudC5hZGRTZWxlY3Rpb25MaXN0ZW5lcihuZXcgU2VsZWN0aW9uQWRhcHRlcigpIHsKCQkJCgkJCXB1YmxpYyB2b2lkIHdpZGdldFNlbGVjdGVkKFNlbGVjdGlvbkV2ZW50IGUpIHsKCQkJCWlmIChlLml0ZW0gIT0gbnVsbCAmJiBlLml0ZW0uZ2V0RGF0YSgpIGluc3RhbmNlb2YgRU9iamVjdCkgewoJCQkJCXByb3BlcnRpZXNFZGl0aW9uQ29tcG9uZW50LmZpcmVQcm9wZXJ0aWVzQ2hhbmdlZChuZXcgUHJvcGVydGllc0VkaXRpb25FdmVudChCYXNlQXJ0ZWZhY3RQcm9wZXJ0aWVzRWRpdGlvblBhcnRJbXBsLnRoaXMsIEJhc2VsaW5lVmlld3NSZXBvc2l0b3J5LkJhc2VBcnRlZmFjdC5Qcm9wZXJ0aWVzLmNvbnN0cmFpbmluZ1JlcXVpcmVtZW50LCBQcm9wZXJ0aWVzRWRpdGlvbkV2ZW50LkNIQU5HRSwgUHJvcGVydGllc0VkaXRpb25FdmVudC5TRUxFQ1RJT05fQ0hBTkdFRCwgbnVsbCwgZS5pdGVtLmdldERhdGEoKSkpOwoJCQkJfQoJCQl9CgkJCQoJCX0pOwoJCUdyaWREYXRhIGNvbnN0cmFpbmluZ1JlcXVpcmVtZW50RGF0YSA9IG5ldyBHcmlkRGF0YShHcmlkRGF0YS5GSUxMX0hPUklaT05UQUwpOwoJCWNvbnN0cmFpbmluZ1JlcXVpcmVtZW50RGF0YS5ob3Jpem9udGFsU3BhbiA9IDM7CgkJdGhpcy5jb25zdHJhaW5pbmdSZXF1aXJlbWVudC5zZXRMYXlvdXREYXRhKGNvbnN0cmFpbmluZ1JlcXVpcmVtZW50RGF0YSk7CgkJdGhpcy5jb25zdHJhaW5pbmdSZXF1aXJlbWVudC5kaXNhYmxlTW92ZSgpOwoJCWNvbnN0cmFpbmluZ1JlcXVpcmVtZW50LnNldElEKEJhc2VsaW5lVmlld3NSZXBvc2l0b3J5LkJhc2VBcnRlZmFjdC5Qcm9wZXJ0aWVzLmNvbnN0cmFpbmluZ1JlcXVpcmVtZW50KTsKCQljb25zdHJhaW5pbmdSZXF1aXJlbWVudC5zZXRFRUZUeXBlKCJlZWY6OkFkdmFuY2VkUmVmZXJlbmNlc1RhYmxlIik7IC8vJE5PTi1OTFMtMSQKCQlyZXR1cm4gcGFyZW50OwoJfQoKCS8qKgoJICogCgkgKi8KCXByb3RlY3RlZCB2b2lkIGFkZENvbnN0cmFpbmluZ1JlcXVpcmVtZW50KCkgewoJCVRhYkVsZW1lbnRUcmVlU2VsZWN0aW9uRGlhbG9nIGRpYWxvZyA9IG5ldyBUYWJFbGVtZW50VHJlZVNlbGVjdGlvbkRpYWxvZyhjb25zdHJhaW5pbmdSZXF1aXJlbWVudC5nZXRJbnB1dCgpLCBjb25zdHJhaW5pbmdSZXF1aXJlbWVudEZpbHRlcnMsIGNvbnN0cmFpbmluZ1JlcXVpcmVtZW50QnVzaW5lc3NGaWx0ZXJzLAoJCSJjb25zdHJhaW5pbmdSZXF1aXJlbWVudCIsIHByb3BlcnRpZXNFZGl0aW9uQ29tcG9uZW50LmdldEVkaXRpbmdDb250ZXh0KCkuZ2V0QWRhcHRlckZhY3RvcnkoKSwgY3VycmVudC5lUmVzb3VyY2UoKSkgewoJCQlAT3ZlcnJpZGUKCQkJcHVibGljIHZvaWQgcHJvY2VzcyhJU3RydWN0dXJlZFNlbGVjdGlvbiBzZWxlY3Rpb24pIHsKCQkJCWZvciAoSXRlcmF0b3I8Pz4gaXRlciA9IHNlbGVjdGlvbi5pdGVyYXRvcigpOyBpdGVyLmhhc05leHQoKTspIHsKCQkJCQlFT2JqZWN0IGVsZW0gPSAoRU9iamVjdCkgaXRlci5uZXh0KCk7CgkJCQkJcHJvcGVydGllc0VkaXRpb25Db21wb25lbnQuZmlyZVByb3BlcnRpZXNDaGFuZ2VkKG5ldyBQcm9wZXJ0aWVzRWRpdGlvbkV2ZW50KEJhc2VBcnRlZmFjdFByb3BlcnRpZXNFZGl0aW9uUGFydEltcGwudGhpcywgQmFzZWxpbmVWaWV3c1JlcG9zaXRvcnkuQmFzZUFydGVmYWN0LlByb3BlcnRpZXMuY29uc3RyYWluaW5nUmVxdWlyZW1lbnQsCgkJCQkJCVByb3BlcnRpZXNFZGl0aW9uRXZlbnQuQ09NTUlULCBQcm9wZXJ0aWVzRWRpdGlvbkV2ZW50LkFERCwgbnVsbCwgZWxlbSkpOwoJCQkJfQoJCQkJY29uc3RyYWluaW5nUmVxdWlyZW1lbnQucmVmcmVzaCgpOwoJCQl9CgkJfTsKCQlkaWFsb2cub3BlbigpOwoJfQoKCS8qKgoJICogCgkgKi8KCXByb3RlY3RlZCB2b2lkIG1vdmVDb25zdHJhaW5pbmdSZXF1aXJlbWVudChFT2JqZWN0IGVsZW1lbnQsIGludCBvbGRJbmRleCwgaW50IG5ld0luZGV4KSB7CgkJcHJvcGVydGllc0VkaXRpb25Db21wb25lbnQuZmlyZVByb3BlcnRpZXNDaGFuZ2VkKG5ldyBQcm9wZXJ0aWVzRWRpdGlvbkV2ZW50KEJhc2VBcnRlZmFjdFByb3BlcnRpZXNFZGl0aW9uUGFydEltcGwudGhpcywgQmFzZWxpbmVWaWV3c1JlcG9zaXRvcnkuQmFzZUFydGVmYWN0LlByb3BlcnRpZXMuY29uc3RyYWluaW5nUmVxdWlyZW1lbnQsIFByb3BlcnRpZXNFZGl0aW9uRXZlbnQuQ09NTUlULCBQcm9wZXJ0aWVzRWRpdGlvbkV2ZW50Lk1PVkUsIGVsZW1lbnQsIG5ld0luZGV4KSk7CgkJY29uc3RyYWluaW5nUmVxdWlyZW1lbnQucmVmcmVzaCgpOwoJfQoKCS8qKgoJICogCgkgKi8KCXByb3RlY3RlZCB2b2lkIHJlbW92ZUZyb21Db25zdHJhaW5pbmdSZXF1aXJlbWVudChFT2JqZWN0IGVsZW1lbnQpIHsKCQlwcm9wZXJ0aWVzRWRpdGlvbkNvbXBvbmVudC5maXJlUHJvcGVydGllc0NoYW5nZWQobmV3IFByb3BlcnRpZXNFZGl0aW9uRXZlbnQoQmFzZUFydGVmYWN0UHJvcGVydGllc0VkaXRpb25QYXJ0SW1wbC50aGlzLCBCYXNlbGluZVZpZXdzUmVwb3NpdG9yeS5CYXNlQXJ0ZWZhY3QuUHJvcGVydGllcy5jb25zdHJhaW5pbmdSZXF1aXJlbWVudCwgUHJvcGVydGllc0VkaXRpb25FdmVudC5DT01NSVQsIFByb3BlcnRpZXNFZGl0aW9uRXZlbnQuUkVNT1ZFLCBudWxsLCBlbGVtZW50KSk7CgkJY29uc3RyYWluaW5nUmVxdWlyZW1lbnQucmVmcmVzaCgpOwoJfQoKCS8qKgoJICogCgkgKi8KCXByb3RlY3RlZCB2b2lkIGVkaXRDb25zdHJhaW5pbmdSZXF1aXJlbWVudChFT2JqZWN0IGVsZW1lbnQpIHsKCQlFT2JqZWN0UHJvcGVydGllc0VkaXRpb25Db250ZXh0IGNvbnRleHQgPSBuZXcgRU9iamVjdFByb3BlcnRpZXNFZGl0aW9uQ29udGV4dChwcm9wZXJ0aWVzRWRpdGlvbkNvbXBvbmVudC5nZXRFZGl0aW5nQ29udGV4dCgpLCBwcm9wZXJ0aWVzRWRpdGlvbkNvbXBvbmVudCwgZWxlbWVudCwgYWRhcHRlckZhY3RvcnkpOwoJCVByb3BlcnRpZXNFZGl0aW5nUHJvdmlkZXIgcHJvdmlkZXIgPSAoUHJvcGVydGllc0VkaXRpbmdQcm92aWRlcilhZGFwdGVyRmFjdG9yeS5hZGFwdChlbGVtZW50LCBQcm9wZXJ0aWVzRWRpdGluZ1Byb3ZpZGVyLmNsYXNzKTsKCQlpZiAocHJvdmlkZXIgIT0gbnVsbCkgewoJCQlQcm9wZXJ0aWVzRWRpdGluZ1BvbGljeSBwb2xpY3kgPSBwcm92aWRlci5nZXRQb2xpY3koY29udGV4dCk7CgkJCWlmIChwb2xpY3kgIT0gbnVsbCkgewoJCQkJcG9saWN5LmV4ZWN1dGUoKTsKCQkJCWNvbnN0cmFpbmluZ1JlcXVpcmVtZW50LnJlZnJlc2goKTsKCQkJfQoJCX0KCX0KCgkvKioKCSAqIAoJICovCglwcm90ZWN0ZWQgQ29tcG9zaXRlIGNyZWF0ZUFwcGxpY2FibGVUZWNobmlxdWVBZHZhbmNlZFJlZmVyZW5jZXNUYWJsZShDb21wb3NpdGUgcGFyZW50KSB7CgkJU3RyaW5nIGxhYmVsID0gZ2V0RGVzY3JpcHRpb24oQmFzZWxpbmVWaWV3c1JlcG9zaXRvcnkuQmFzZUFydGVmYWN0LlByb3BlcnRpZXMuYXBwbGljYWJsZVRlY2huaXF1ZSwgQmFzZWxpbmVNZXNzYWdlcy5CYXNlQXJ0ZWZhY3RQcm9wZXJ0aWVzRWRpdGlvblBhcnRfQXBwbGljYWJsZVRlY2huaXF1ZUxhYmVsKTsJCSAKCQl0aGlzLmFwcGxpY2FibGVUZWNobmlxdWUgPSBuZXcgUmVmZXJlbmNlc1RhYmxlKGxhYmVsLCBuZXcgUmVmZXJlbmNlc1RhYmxlTGlzdGVuZXIoKSB7CgkJCXB1YmxpYyB2b2lkIGhhbmRsZUFkZCgpIHsgYWRkQXBwbGljYWJsZVRlY2huaXF1ZSgpOyB9CgkJCXB1YmxpYyB2b2lkIGhhbmRsZUVkaXQoRU9iamVjdCBlbGVtZW50KSB7IGVkaXRBcHBsaWNhYmxlVGVjaG5pcXVlKGVsZW1lbnQpOyB9CgkJCXB1YmxpYyB2b2lkIGhhbmRsZU1vdmUoRU9iamVjdCBlbGVtZW50LCBpbnQgb2xkSW5kZXgsIGludCBuZXdJbmRleCkgeyBtb3ZlQXBwbGljYWJsZVRlY2huaXF1ZShlbGVtZW50LCBvbGRJbmRleCwgbmV3SW5kZXgpOyB9CgkJCXB1YmxpYyB2b2lkIGhhbmRsZVJlbW92ZShFT2JqZWN0IGVsZW1lbnQpIHsgcmVtb3ZlRnJvbUFwcGxpY2FibGVUZWNobmlxdWUoZWxlbWVudCk7IH0KCQkJcHVibGljIHZvaWQgbmF2aWdhdGVUbyhFT2JqZWN0IGVsZW1lbnQpIHsgfQoJCX0pOwoJCXRoaXMuYXBwbGljYWJsZVRlY2huaXF1ZS5zZXRIZWxwVGV4dChwcm9wZXJ0aWVzRWRpdGlvbkNvbXBvbmVudC5nZXRIZWxwQ29udGVudChCYXNlbGluZVZpZXdzUmVwb3NpdG9yeS5CYXNlQXJ0ZWZhY3QuUHJvcGVydGllcy5hcHBsaWNhYmxlVGVjaG5pcXVlLCBCYXNlbGluZVZpZXdzUmVwb3NpdG9yeS5TV1RfS0lORCkpOwoJCXRoaXMuYXBwbGljYWJsZVRlY2huaXF1ZS5jcmVhdGVDb250cm9scyhwYXJlbnQpOwoJCXRoaXMuYXBwbGljYWJsZVRlY2huaXF1ZS5hZGRTZWxlY3Rpb25MaXN0ZW5lcihuZXcgU2VsZWN0aW9uQWRhcHRlcigpIHsKCQkJCgkJCXB1YmxpYyB2b2lkIHdpZGdldFNlbGVjdGVkKFNlbGVjdGlvbkV2ZW50IGUpIHsKCQkJCWlmIChlLml0ZW0gIT0gbnVsbCAmJiBlLml0ZW0uZ2V0RGF0YSgpIGluc3RhbmNlb2YgRU9iamVjdCkgewoJCQkJCXByb3BlcnRpZXNFZGl0aW9uQ29tcG9uZW50LmZpcmVQcm9wZXJ0aWVzQ2hhbmdlZChuZXcgUHJvcGVydGllc0VkaXRpb25FdmVudChCYXNlQXJ0ZWZhY3RQcm9wZXJ0aWVzRWRpdGlvblBhcnRJbXBsLnRoaXMsIEJhc2VsaW5lVmlld3NSZXBvc2l0b3J5LkJhc2VBcnRlZmFjdC5Qcm9wZXJ0aWVzLmFwcGxpY2FibGVUZWNobmlxdWUsIFByb3BlcnRpZXNFZGl0aW9uRXZlbnQuQ0hBTkdFLCBQcm9wZXJ0aWVzRWRpdGlvbkV2ZW50LlNFTEVDVElPTl9DSEFOR0VELCBudWxsLCBlLml0ZW0uZ2V0RGF0YSgpKSk7CgkJCQl9CgkJCX0KCQkJCgkJfSk7CgkJR3JpZERhdGEgYXBwbGljYWJsZVRlY2huaXF1ZURhdGEgPSBuZXcgR3JpZERhdGEoR3JpZERhdGEuRklMTF9IT1JJWk9OVEFMKTsKCQlhcHBsaWNhYmxlVGVjaG5pcXVlRGF0YS5ob3Jpem9udGFsU3BhbiA9IDM7CgkJdGhpcy5hcHBsaWNhYmxlVGVjaG5pcXVlLnNldExheW91dERhdGEoYXBwbGljYWJsZVRlY2huaXF1ZURhdGEpOwoJCXRoaXMuYXBwbGljYWJsZVRlY2huaXF1ZS5kaXNhYmxlTW92ZSgpOwoJCWFwcGxpY2FibGVUZWNobmlxdWUuc2V0SUQoQmFzZWxpbmVWaWV3c1JlcG9zaXRvcnkuQmFzZUFydGVmYWN0LlByb3BlcnRpZXMuYXBwbGljYWJsZVRlY2huaXF1ZSk7CgkJYXBwbGljYWJsZVRlY2huaXF1ZS5zZXRFRUZUeXBlKCJlZWY6OkFkdmFuY2VkUmVmZXJlbmNlc1RhYmxlIik7IC8vJE5PTi1OTFMtMSQKCQlyZXR1cm4gcGFyZW50OwoJfQoKCS8qKgoJICogCgkgKi8KCXByb3RlY3RlZCB2b2lkIGFkZEFwcGxpY2FibGVUZWNobmlxdWUoKSB7CgkJVGFiRWxlbWVudFRyZWVTZWxlY3Rpb25EaWFsb2cgZGlhbG9nID0gbmV3IFRhYkVsZW1lbnRUcmVlU2VsZWN0aW9uRGlhbG9nKGFwcGxpY2FibGVUZWNobmlxdWUuZ2V0SW5wdXQoKSwgYXBwbGljYWJsZVRlY2huaXF1ZUZpbHRlcnMsIGFwcGxpY2FibGVUZWNobmlxdWVCdXNpbmVzc0ZpbHRlcnMsCgkJImFwcGxpY2FibGVUZWNobmlxdWUiLCBwcm9wZXJ0aWVzRWRpdGlvbkNvbXBvbmVudC5nZXRFZGl0aW5nQ29udGV4dCgpLmdldEFkYXB0ZXJGYWN0b3J5KCksIGN1cnJlbnQuZVJlc291cmNlKCkpIHsKCQkJQE92ZXJyaWRlCgkJCXB1YmxpYyB2b2lkIHByb2Nlc3MoSVN0cnVjdHVyZWRTZWxlY3Rpb24gc2VsZWN0aW9uKSB7CgkJCQlmb3IgKEl0ZXJhdG9yPD8+IGl0ZXIgPSBzZWxlY3Rpb24uaXRlcmF0b3IoKTsgaXRlci5oYXNOZXh0KCk7KSB7CgkJCQkJRU9iamVjdCBlbGVtID0gKEVPYmplY3QpIGl0ZXIubmV4dCgpOwoJCQkJCXByb3BlcnRpZXNFZGl0aW9uQ29tcG9uZW50LmZpcmVQcm9wZXJ0aWVzQ2hhbmdlZChuZXcgUHJvcGVydGllc0VkaXRpb25FdmVudChCYXNlQXJ0ZWZhY3RQcm9wZXJ0aWVzRWRpdGlvblBhcnRJbXBsLnRoaXMsIEJhc2VsaW5lVmlld3NSZXBvc2l0b3J5LkJhc2VBcnRlZmFjdC5Qcm9wZXJ0aWVzLmFwcGxpY2FibGVUZWNobmlxdWUsCgkJCQkJCVByb3BlcnRpZXNFZGl0aW9uRXZlbnQuQ09NTUlULCBQcm9wZXJ0aWVzRWRpdGlvbkV2ZW50LkFERCwgbnVsbCwgZWxlbSkpOwoJCQkJfQoJCQkJYXBwbGljYWJsZVRlY2huaXF1ZS5yZWZyZXNoKCk7CgkJCX0KCQl9OwoJCWRpYWxvZy5vcGVuKCk7Cgl9CgoJLyoqCgkgKiAKCSAqLwoJcHJvdGVjdGVkIHZvaWQgbW92ZUFwcGxpY2FibGVUZWNobmlxdWUoRU9iamVjdCBlbGVtZW50LCBpbnQgb2xkSW5kZXgsIGludCBuZXdJbmRleCkgewoJCXByb3BlcnRpZXNFZGl0aW9uQ29tcG9uZW50LmZpcmVQcm9wZXJ0aWVzQ2hhbmdlZChuZXcgUHJvcGVydGllc0VkaXRpb25FdmVudChCYXNlQXJ0ZWZhY3RQcm9wZXJ0aWVzRWRpdGlvblBhcnRJbXBsLnRoaXMsIEJhc2VsaW5lVmlld3NSZXBvc2l0b3J5LkJhc2VBcnRlZmFjdC5Qcm9wZXJ0aWVzLmFwcGxpY2FibGVUZWNobmlxdWUsIFByb3BlcnRpZXNFZGl0aW9uRXZlbnQuQ09NTUlULCBQcm9wZXJ0aWVzRWRpdGlvbkV2ZW50Lk1PVkUsIGVsZW1lbnQsIG5ld0luZGV4KSk7CgkJYXBwbGljYWJsZVRlY2huaXF1ZS5yZWZyZXNoKCk7Cgl9CgoJLyoqCgkgKiAKCSAqLwoJcHJvdGVjdGVkIHZvaWQgcmVtb3ZlRnJvbUFwcGxpY2FibGVUZWNobmlxdWUoRU9iamVjdCBlbGVtZW50KSB7CgkJcHJvcGVydGllc0VkaXRpb25Db21wb25lbnQuZmlyZVByb3BlcnRpZXNDaGFuZ2VkKG5ldyBQcm9wZXJ0aWVzRWRpdGlvbkV2ZW50KEJhc2VBcnRlZmFjdFByb3BlcnRpZXNFZGl0aW9uUGFydEltcGwudGhpcywgQmFzZWxpbmVWaWV3c1JlcG9zaXRvcnkuQmFzZUFydGVmYWN0LlByb3BlcnRpZXMuYXBwbGljYWJsZVRlY2huaXF1ZSwgUHJvcGVydGllc0VkaXRpb25FdmVudC5DT01NSVQsIFByb3BlcnRpZXNFZGl0aW9uRXZlbnQuUkVNT1ZFLCBudWxsLCBlbGVtZW50KSk7CgkJYXBwbGljYWJsZVRlY2huaXF1ZS5yZWZyZXNoKCk7Cgl9CgoJLyoqCgkgKiAKCSAqLwoJcHJvdGVjdGVkIHZvaWQgZWRpdEFwcGxpY2FibGVUZWNobmlxdWUoRU9iamVjdCBlbGVtZW50KSB7CgkJRU9iamVjdFByb3BlcnRpZXNFZGl0aW9uQ29udGV4dCBjb250ZXh0ID0gbmV3IEVPYmplY3RQcm9wZXJ0aWVzRWRpdGlvbkNvbnRleHQocHJvcGVydGllc0VkaXRpb25Db21wb25lbnQuZ2V0RWRpdGluZ0NvbnRleHQoKSwgcHJvcGVydGllc0VkaXRpb25Db21wb25lbnQsIGVsZW1lbnQsIGFkYXB0ZXJGYWN0b3J5KTsKCQlQcm9wZXJ0aWVzRWRpdGluZ1Byb3ZpZGVyIHByb3ZpZGVyID0gKFByb3BlcnRpZXNFZGl0aW5nUHJvdmlkZXIpYWRhcHRlckZhY3RvcnkuYWRhcHQoZWxlbWVudCwgUHJvcGVydGllc0VkaXRpbmdQcm92aWRlci5jbGFzcyk7CgkJaWYgKHByb3ZpZGVyICE9IG51bGwpIHsKCQkJUHJvcGVydGllc0VkaXRpbmdQb2xpY3kgcG9saWN5ID0gcHJvdmlkZXIuZ2V0UG9saWN5KGNvbnRleHQpOwoJCQlpZiAocG9saWN5ICE9IG51bGwpIHsKCQkJCXBvbGljeS5leGVjdXRlKCk7CgkJCQlhcHBsaWNhYmxlVGVjaG5pcXVlLnJlZnJlc2goKTsKCQkJfQoJCX0KCX0KCgkvKioKCSAqIEBwYXJhbSBjb250YWluZXIKCSAqIAoJICovCglwcm90ZWN0ZWQgQ29tcG9zaXRlIGNyZWF0ZU93bmVkUmVsQWR2YW5jZWRUYWJsZUNvbXBvc2l0aW9uKENvbXBvc2l0ZSBwYXJlbnQpIHsKCQl0aGlzLm93bmVkUmVsID0gbmV3IFJlZmVyZW5jZXNUYWJsZShnZXREZXNjcmlwdGlvbihCYXNlbGluZVZpZXdzUmVwb3NpdG9yeS5CYXNlQXJ0ZWZhY3QuUHJvcGVydGllcy5vd25lZFJlbCwgQmFzZWxpbmVNZXNzYWdlcy5CYXNlQXJ0ZWZhY3RQcm9wZXJ0aWVzRWRpdGlvblBhcnRfT3duZWRSZWxMYWJlbCksIG5ldyBSZWZlcmVuY2VzVGFibGVMaXN0ZW5lcigpIHsKCQkJcHVibGljIHZvaWQgaGFuZGxlQWRkKCkgeyAKCQkJCXByb3BlcnRpZXNFZGl0aW9uQ29tcG9uZW50LmZpcmVQcm9wZXJ0aWVzQ2hhbmdlZChuZXcgUHJvcGVydGllc0VkaXRpb25FdmVudChCYXNlQXJ0ZWZhY3RQcm9wZXJ0aWVzRWRpdGlvblBhcnRJbXBsLnRoaXMsIEJhc2VsaW5lVmlld3NSZXBvc2l0b3J5LkJhc2VBcnRlZmFjdC5Qcm9wZXJ0aWVzLm93bmVkUmVsLCBQcm9wZXJ0aWVzRWRpdGlvbkV2ZW50LkNPTU1JVCwgUHJvcGVydGllc0VkaXRpb25FdmVudC5BREQsIG51bGwsIG51bGwpKTsKCQkJCW93bmVkUmVsLnJlZnJlc2goKTsKCQkJfQoJCQlwdWJsaWMgdm9pZCBoYW5kbGVFZGl0KEVPYmplY3QgZWxlbWVudCkgewoJCQkJcHJvcGVydGllc0VkaXRpb25Db21wb25lbnQuZmlyZVByb3BlcnRpZXNDaGFuZ2VkKG5ldyBQcm9wZXJ0aWVzRWRpdGlvbkV2ZW50KEJhc2VBcnRlZmFjdFByb3BlcnRpZXNFZGl0aW9uUGFydEltcGwudGhpcywgQmFzZWxpbmVWaWV3c1JlcG9zaXRvcnkuQmFzZUFydGVmYWN0LlByb3BlcnRpZXMub3duZWRSZWwsIFByb3BlcnRpZXNFZGl0aW9uRXZlbnQuQ09NTUlULCBQcm9wZXJ0aWVzRWRpdGlvbkV2ZW50LkVESVQsIG51bGwsIGVsZW1lbnQpKTsKCQkJCW93bmVkUmVsLnJlZnJlc2goKTsKCQkJfQoJCQlwdWJsaWMgdm9pZCBoYW5kbGVNb3ZlKEVPYmplY3QgZWxlbWVudCwgaW50IG9sZEluZGV4LCBpbnQgbmV3SW5kZXgpIHsgCgkJCQlwcm9wZXJ0aWVzRWRpdGlvbkNvbXBvbmVudC5maXJlUHJvcGVydGllc0NoYW5nZWQobmV3IFByb3BlcnRpZXNFZGl0aW9uRXZlbnQoQmFzZUFydGVmYWN0UHJvcGVydGllc0VkaXRpb25QYXJ0SW1wbC50aGlzLCBCYXNlbGluZVZpZXdzUmVwb3NpdG9yeS5CYXNlQXJ0ZWZhY3QuUHJvcGVydGllcy5vd25lZFJlbCwgUHJvcGVydGllc0VkaXRpb25FdmVudC5DT01NSVQsIFByb3BlcnRpZXNFZGl0aW9uRXZlbnQuTU9WRSwgZWxlbWVudCwgbmV3SW5kZXgpKTsKCQkJCW93bmVkUmVsLnJlZnJlc2goKTsKCQkJfQoJCQlwdWJsaWMgdm9pZCBoYW5kbGVSZW1vdmUoRU9iamVjdCBlbGVtZW50KSB7IAoJCQkJcHJvcGVydGllc0VkaXRpb25Db21wb25lbnQuZmlyZVByb3BlcnRpZXNDaGFuZ2VkKG5ldyBQcm9wZXJ0aWVzRWRpdGlvbkV2ZW50KEJhc2VBcnRlZmFjdFByb3BlcnRpZXNFZGl0aW9uUGFydEltcGwudGhpcywgQmFzZWxpbmVWaWV3c1JlcG9zaXRvcnkuQmFzZUFydGVmYWN0LlByb3BlcnRpZXMub3duZWRSZWwsIFByb3BlcnRpZXNFZGl0aW9uRXZlbnQuQ09NTUlULCBQcm9wZXJ0aWVzRWRpdGlvbkV2ZW50LlJFTU9WRSwgbnVsbCwgZWxlbWVudCkpOwoJCQkJb3duZWRSZWwucmVmcmVzaCgpOwoJCQl9CgkJCXB1YmxpYyB2b2lkIG5hdmlnYXRlVG8oRU9iamVjdCBlbGVtZW50KSB7IH0KCQl9KTsKCQlmb3IgKFZpZXdlckZpbHRlciBmaWx0ZXIgOiB0aGlzLm93bmVkUmVsRmlsdGVycykgewoJCQl0aGlzLm93bmVkUmVsLmFkZEZpbHRlcihmaWx0ZXIpOwoJCX0KCQl0aGlzLm93bmVkUmVsLnNldEhlbHBUZXh0KHByb3BlcnRpZXNFZGl0aW9uQ29tcG9uZW50LmdldEhlbHBDb250ZW50KEJhc2VsaW5lVmlld3NSZXBvc2l0b3J5LkJhc2VBcnRlZmFjdC5Qcm9wZXJ0aWVzLm93bmVkUmVsLCBCYXNlbGluZVZpZXdzUmVwb3NpdG9yeS5TV1RfS0lORCkpOwoJCXRoaXMub3duZWRSZWwuY3JlYXRlQ29udHJvbHMocGFyZW50KTsKCQl0aGlzLm93bmVkUmVsLmFkZFNlbGVjdGlvbkxpc3RlbmVyKG5ldyBTZWxlY3Rpb25BZGFwdGVyKCkgewoJCQkKCQkJcHVibGljIHZvaWQgd2lkZ2V0U2VsZWN0ZWQoU2VsZWN0aW9uRXZlbnQgZSkgewoJCQkJaWYgKGUuaXRlbSAhPSBudWxsICYmIGUuaXRlbS5nZXREYXRhKCkgaW5zdGFuY2VvZiBFT2JqZWN0KSB7CgkJCQkJcHJvcGVydGllc0VkaXRpb25Db21wb25lbnQuZmlyZVByb3BlcnRpZXNDaGFuZ2VkKG5ldyBQcm9wZXJ0aWVzRWRpdGlvbkV2ZW50KEJhc2VBcnRlZmFjdFByb3BlcnRpZXNFZGl0aW9uUGFydEltcGwudGhpcywgQmFzZWxpbmVWaWV3c1JlcG9zaXRvcnkuQmFzZUFydGVmYWN0LlByb3BlcnRpZXMub3duZWRSZWwsIFByb3BlcnRpZXNFZGl0aW9uRXZlbnQuQ0hBTkdFLCBQcm9wZXJ0aWVzRWRpdGlvbkV2ZW50LlNFTEVDVElPTl9DSEFOR0VELCBudWxsLCBlLml0ZW0uZ2V0RGF0YSgpKSk7CgkJCQl9CgkJCX0KCQkJCgkJfSk7CgkJR3JpZERhdGEgb3duZWRSZWxEYXRhID0gbmV3IEdyaWREYXRhKEdyaWREYXRhLkZJTExfSE9SSVpPTlRBTCk7CgkJb3duZWRSZWxEYXRhLmhvcml6b250YWxTcGFuID0gMzsKCQl0aGlzLm93bmVkUmVsLnNldExheW91dERhdGEob3duZWRSZWxEYXRhKTsKCQl0aGlzLm93bmVkUmVsLnNldExvd2VyQm91bmQoMCk7CgkJdGhpcy5vd25lZFJlbC5zZXRVcHBlckJvdW5kKC0xKTsKCQlvd25lZFJlbC5zZXRJRChCYXNlbGluZVZpZXdzUmVwb3NpdG9yeS5CYXNlQXJ0ZWZhY3QuUHJvcGVydGllcy5vd25lZFJlbCk7CgkJb3duZWRSZWwuc2V0RUVGVHlwZSgiZWVmOjpBZHZhbmNlZFRhYmxlQ29tcG9zaXRpb24iKTsgLy8kTk9OLU5MUy0xJAoJCS8vIFN0YXJ0IG9mIHVzZXIgY29kZSBmb3IgY3JlYXRlT3duZWRSZWxBZHZhbmNlZFRhYmxlQ29tcG9zaXRpb24KCgkJLy8gRW5kIG9mIHVzZXIgY29kZQoJCXJldHVybiBwYXJlbnQ7Cgl9CgoJLyoqCgkgKiAKCSAqLwoJcHJvdGVjdGVkIENvbXBvc2l0ZSBjcmVhdGVQcm9wZXJ0eUFkdmFuY2VkUmVmZXJlbmNlc1RhYmxlKENvbXBvc2l0ZSBwYXJlbnQpIHsKCQlTdHJpbmcgbGFiZWwgPSBnZXREZXNjcmlwdGlvbihCYXNlbGluZVZpZXdzUmVwb3NpdG9yeS5CYXNlQXJ0ZWZhY3QuUHJvcGVydGllcy5wcm9wZXJ0eSwgQmFzZWxpbmVNZXNzYWdlcy5CYXNlQXJ0ZWZhY3RQcm9wZXJ0aWVzRWRpdGlvblBhcnRfUHJvcGVydHlMYWJlbCk7CQkgCgkJdGhpcy5wcm9wZXJ0eSA9IG5ldyBSZWZlcmVuY2VzVGFibGUobGFiZWwsIG5ldyBSZWZlcmVuY2VzVGFibGVMaXN0ZW5lcigpIHsKCQkJcHVibGljIHZvaWQgaGFuZGxlQWRkKCkgeyBhZGRQcm9wZXJ0eSgpOyB9CgkJCXB1YmxpYyB2b2lkIGhhbmRsZUVkaXQoRU9iamVjdCBlbGVtZW50KSB7IGVkaXRQcm9wZXJ0eShlbGVtZW50KTsgfQoJCQlwdWJsaWMgdm9pZCBoYW5kbGVNb3ZlKEVPYmplY3QgZWxlbWVudCwgaW50IG9sZEluZGV4LCBpbnQgbmV3SW5kZXgpIHsgbW92ZVByb3BlcnR5KGVsZW1lbnQsIG9sZEluZGV4LCBuZXdJbmRleCk7IH0KCQkJcHVibGljIHZvaWQgaGFuZGxlUmVtb3ZlKEVPYmplY3QgZWxlbWVudCkgeyByZW1vdmVGcm9tUHJvcGVydHkoZWxlbWVudCk7IH0KCQkJcHVibGljIHZvaWQgbmF2aWdhdGVUbyhFT2JqZWN0IGVsZW1lbnQpIHsgfQoJCX0pOwoJCXRoaXMucHJvcGVydHkuc2V0SGVscFRleHQocHJvcGVydGllc0VkaXRpb25Db21wb25lbnQuZ2V0SGVscENvbnRlbnQoQmFzZWxpbmVWaWV3c1JlcG9zaXRvcnkuQmFzZUFydGVmYWN0LlByb3BlcnRpZXMucHJvcGVydHksIEJhc2VsaW5lVmlld3NSZXBvc2l0b3J5LlNXVF9LSU5EKSk7CgkJdGhpcy5wcm9wZXJ0eS5jcmVhdGVDb250cm9scyhwYXJlbnQpOwoJCXRoaXMucHJvcGVydHkuYWRkU2VsZWN0aW9uTGlzdGVuZXIobmV3IFNlbGVjdGlvbkFkYXB0ZXIoKSB7CgkJCQoJCQlwdWJsaWMgdm9pZCB3aWRnZXRTZWxlY3RlZChTZWxlY3Rpb25FdmVudCBlKSB7CgkJCQlpZiAoZS5pdGVtICE9IG51bGwgJiYgZS5pdGVtLmdldERhdGEoKSBpbnN0YW5jZW9mIEVPYmplY3QpIHsKCQkJCQlwcm9wZXJ0aWVzRWRpdGlvbkNvbXBvbmVudC5maXJlUHJvcGVydGllc0NoYW5nZWQobmV3IFByb3BlcnRpZXNFZGl0aW9uRXZlbnQoQmFzZUFydGVmYWN0UHJvcGVydGllc0VkaXRpb25QYXJ0SW1wbC50aGlzLCBCYXNlbGluZVZpZXdzUmVwb3NpdG9yeS5CYXNlQXJ0ZWZhY3QuUHJvcGVydGllcy5wcm9wZXJ0eSwgUHJvcGVydGllc0VkaXRpb25FdmVudC5DSEFOR0UsIFByb3BlcnRpZXNFZGl0aW9uRXZlbnQuU0VMRUNUSU9OX0NIQU5HRUQsIG51bGwsIGUuaXRlbS5nZXREYXRhKCkpKTsKCQkJCX0KCQkJfQoJCQkKCQl9KTsKCQlHcmlkRGF0YSBwcm9wZXJ0eURhdGEgPSBuZXcgR3JpZERhdGEoR3JpZERhdGEuRklMTF9IT1JJWk9OVEFMKTsKCQlwcm9wZXJ0eURhdGEuaG9yaXpvbnRhbFNwYW4gPSAzOwoJCXRoaXMucHJvcGVydHkuc2V0TGF5b3V0RGF0YShwcm9wZXJ0eURhdGEpOwoJCXRoaXMucHJvcGVydHkuZGlzYWJsZU1vdmUoKTsKCQlwcm9wZXJ0eS5zZXRJRChCYXNlbGluZVZpZXdzUmVwb3NpdG9yeS5CYXNlQXJ0ZWZhY3QuUHJvcGVydGllcy5wcm9wZXJ0eSk7CgkJcHJvcGVydHkuc2V0RUVGVHlwZSgiZWVmOjpBZHZhbmNlZFJlZmVyZW5jZXNUYWJsZSIpOyAvLyROT04tTkxTLTEkCgkJcmV0dXJuIHBhcmVudDsKCX0KCgkvKioKCSAqIAoJICovCglwcm90ZWN0ZWQgdm9pZCBhZGRQcm9wZXJ0eSgpIHsKCQlUYWJFbGVtZW50VHJlZVNlbGVjdGlvbkRpYWxvZyBkaWFsb2cgPSBuZXcgVGFiRWxlbWVudFRyZWVTZWxlY3Rpb25EaWFsb2cocHJvcGVydHkuZ2V0SW5wdXQoKSwgcHJvcGVydHlGaWx0ZXJzLCBwcm9wZXJ0eUJ1c2luZXNzRmlsdGVycywKCQkicHJvcGVydHkiLCBwcm9wZXJ0aWVzRWRpdGlvbkNvbXBvbmVudC5nZXRFZGl0aW5nQ29udGV4dCgpLmdldEFkYXB0ZXJGYWN0b3J5KCksIGN1cnJlbnQuZVJlc291cmNlKCkpIHsKCQkJQE92ZXJyaWRlCgkJCXB1YmxpYyB2b2lkIHByb2Nlc3MoSVN0cnVjdHVyZWRTZWxlY3Rpb24gc2VsZWN0aW9uKSB7CgkJCQlmb3IgKEl0ZXJhdG9yPD8+IGl0ZXIgPSBzZWxlY3Rpb24uaXRlcmF0b3IoKTsgaXRlci5oYXNOZXh0KCk7KSB7CgkJCQkJRU9iamVjdCBlbGVtID0gKEVPYmplY3QpIGl0ZXIubmV4dCgpOwoJCQkJCXByb3BlcnRpZXNFZGl0aW9uQ29tcG9uZW50LmZpcmVQcm9wZXJ0aWVzQ2hhbmdlZChuZXcgUHJvcGVydGllc0VkaXRpb25FdmVudChCYXNlQXJ0ZWZhY3RQcm9wZXJ0aWVzRWRpdGlvblBhcnRJbXBsLnRoaXMsIEJhc2VsaW5lVmlld3NSZXBvc2l0b3J5LkJhc2VBcnRlZmFjdC5Qcm9wZXJ0aWVzLnByb3BlcnR5LAoJCQkJCQlQcm9wZXJ0aWVzRWRpdGlvbkV2ZW50LkNPTU1JVCwgUHJvcGVydGllc0VkaXRpb25FdmVudC5BREQsIG51bGwsIGVsZW0pKTsKCQkJCX0KCQkJCXByb3BlcnR5LnJlZnJlc2goKTsKCQkJfQoJCX07CgkJZGlhbG9nLm9wZW4oKTsKCX0KCgkvKioKCSAqIAoJICovCglwcm90ZWN0ZWQgdm9pZCBtb3ZlUHJvcGVydHkoRU9iamVjdCBlbGVtZW50LCBpbnQgb2xkSW5kZXgsIGludCBuZXdJbmRleCkgewoJCXByb3BlcnRpZXNFZGl0aW9uQ29tcG9uZW50LmZpcmVQcm9wZXJ0aWVzQ2hhbmdlZChuZXcgUHJvcGVydGllc0VkaXRpb25FdmVudChCYXNlQXJ0ZWZhY3RQcm9wZXJ0aWVzRWRpdGlvblBhcnRJbXBsLnRoaXMsIEJhc2VsaW5lVmlld3NSZXBvc2l0b3J5LkJhc2VBcnRlZmFjdC5Qcm9wZXJ0aWVzLnByb3BlcnR5LCBQcm9wZXJ0aWVzRWRpdGlvbkV2ZW50LkNPTU1JVCwgUHJvcGVydGllc0VkaXRpb25FdmVudC5NT1ZFLCBlbGVtZW50LCBuZXdJbmRleCkpOwoJCXByb3BlcnR5LnJlZnJlc2goKTsKCX0KCgkvKioKCSAqIAoJICovCglwcm90ZWN0ZWQgdm9pZCByZW1vdmVGcm9tUHJvcGVydHkoRU9iamVjdCBlbGVtZW50KSB7CgkJcHJvcGVydGllc0VkaXRpb25Db21wb25lbnQuZmlyZVByb3BlcnRpZXNDaGFuZ2VkKG5ldyBQcm9wZXJ0aWVzRWRpdGlvbkV2ZW50KEJhc2VBcnRlZmFjdFByb3BlcnRpZXNFZGl0aW9uUGFydEltcGwudGhpcywgQmFzZWxpbmVWaWV3c1JlcG9zaXRvcnkuQmFzZUFydGVmYWN0LlByb3BlcnRpZXMucHJvcGVydHksIFByb3BlcnRpZXNFZGl0aW9uRXZlbnQuQ09NTUlULCBQcm9wZXJ0aWVzRWRpdGlvbkV2ZW50LlJFTU9WRSwgbnVsbCwgZWxlbWVudCkpOwoJCXByb3BlcnR5LnJlZnJlc2goKTsKCX0KCgkvKioKCSAqIAoJICovCglwcm90ZWN0ZWQgdm9pZCBlZGl0UHJvcGVydHkoRU9iamVjdCBlbGVtZW50KSB7CgkJRU9iamVjdFByb3BlcnRpZXNFZGl0aW9uQ29udGV4dCBjb250ZXh0ID0gbmV3IEVPYmplY3RQcm9wZXJ0aWVzRWRpdGlvbkNvbnRleHQocHJvcGVydGllc0VkaXRpb25Db21wb25lbnQuZ2V0RWRpdGluZ0NvbnRleHQoKSwgcHJvcGVydGllc0VkaXRpb25Db21wb25lbnQsIGVsZW1lbnQsIGFkYXB0ZXJGYWN0b3J5KTsKCQlQcm9wZXJ0aWVzRWRpdGluZ1Byb3ZpZGVyIHByb3ZpZGVyID0gKFByb3BlcnRpZXNFZGl0aW5nUHJvdmlkZXIpYWRhcHRlckZhY3RvcnkuYWRhcHQoZWxlbWVudCwgUHJvcGVydGllc0VkaXRpbmdQcm92aWRlci5jbGFzcyk7CgkJaWYgKHByb3ZpZGVyICE9IG51bGwpIHsKCQkJUHJvcGVydGllc0VkaXRpbmdQb2xpY3kgcG9saWN5ID0gcHJvdmlkZXIuZ2V0UG9saWN5KGNvbnRleHQpOwoJCQlpZiAocG9saWN5ICE9IG51bGwpIHsKCQkJCXBvbGljeS5leGVjdXRlKCk7CgkJCQlwcm9wZXJ0eS5yZWZyZXNoKCk7CgkJCX0KCQl9Cgl9CgoKCS8qKgoJICoge0Bpbmhlcml0RG9jfQoJICogCgkgKiBAc2VlIG9yZy5lY2xpcHNlLmVtZi5lZWYucnVudGltZS5hcGkubm90aWZ5LklQcm9wZXJ0aWVzRWRpdGlvbkxpc3RlbmVyI2ZpcmVQcm9wZXJ0aWVzQ2hhbmdlZChvcmcuZWNsaXBzZS5lbWYuZWVmLnJ1bnRpbWUuYXBpLm5vdGlmeS5JUHJvcGVydGllc0VkaXRpb25FdmVudCkKCSAqIAoJICovCglwdWJsaWMgdm9pZCBmaXJlUHJvcGVydGllc0NoYW5nZWQoSVByb3BlcnRpZXNFZGl0aW9uRXZlbnQgZXZlbnQpIHsKCQkvLyBTdGFydCBvZiB1c2VyIGNvZGUgZm9yIHRhYiBzeW5jaHJvbml6YXRpb24KCQkKCQkvLyBFbmQgb2YgdXNlciBjb2RlCgl9CgoJLyoqCgkgKiB7QGluaGVyaXREb2N9CgkgKiAKCSAqIEBzZWUgb3JnLmVjbGlwc2Uub3BlbmNlcnQuYXBtLmJhc2VsaW5lLmJhc2VsaW5lLnBhcnRzLkJhc2VBcnRlZmFjdFByb3BlcnRpZXNFZGl0aW9uUGFydCNnZXRJZCgpCgkgKiAKCSAqLwoJcHVibGljIFN0cmluZyBnZXRJZCgpIHsKCQlyZXR1cm4gaWQuZ2V0VGV4dCgpOwoJfQoKCS8qKgoJICoge0Bpbmhlcml0RG9jfQoJICogCgkgKiBAc2VlIG9yZy5lY2xpcHNlLm9wZW5jZXJ0LmFwbS5iYXNlbGluZS5iYXNlbGluZS5wYXJ0cy5CYXNlQXJ0ZWZhY3RQcm9wZXJ0aWVzRWRpdGlvblBhcnQjc2V0SWQoU3RyaW5nIG5ld1ZhbHVlKQoJICogCgkgKi8KCXB1YmxpYyB2b2lkIHNldElkKFN0cmluZyBuZXdWYWx1ZSkgewoJCWlmIChuZXdWYWx1ZSAhPSBudWxsKSB7CgkJCWlkLnNldFRleHQobmV3VmFsdWUpOwoJCX0gZWxzZSB7CgkJCWlkLnNldFRleHQoIiIpOyAvLyROT04tTkxTLTEkCgkJfQoJCWJvb2xlYW4gZWVmRWxlbWVudEVkaXRvclJlYWRPbmx5U3RhdGUgPSBpc1JlYWRPbmx5KEJhc2VsaW5lVmlld3NSZXBvc2l0b3J5LkJhc2VBcnRlZmFjdC5Qcm9wZXJ0aWVzLmlkKTsKCQlpZiAoZWVmRWxlbWVudEVkaXRvclJlYWRPbmx5U3RhdGUgJiYgaWQuaXNFbmFibGVkKCkpIHsKCQkJaWQuc2V0RW5hYmxlZChmYWxzZSk7CgkJCWlkLnNldFRvb2xUaXBUZXh0KEJhc2VsaW5lTWVzc2FnZXMuQmFzZUFydGVmYWN0X1JlYWRPbmx5KTsKCQl9IGVsc2UgaWYgKCFlZWZFbGVtZW50RWRpdG9yUmVhZE9ubHlTdGF0ZSAmJiAhaWQuaXNFbmFibGVkKCkpIHsKCQkJaWQuc2V0RW5hYmxlZCh0cnVlKTsKCQl9CQoJCQoJfQoKCS8qKgoJICoge0Bpbmhlcml0RG9jfQoJICogCgkgKiBAc2VlIG9yZy5lY2xpcHNlLm9wZW5jZXJ0LmFwbS5iYXNlbGluZS5iYXNlbGluZS5wYXJ0cy5CYXNlQXJ0ZWZhY3RQcm9wZXJ0aWVzRWRpdGlvblBhcnQjZ2V0TmFtZSgpCgkgKiAKCSAqLwoJcHVibGljIFN0cmluZyBnZXROYW1lKCkgewoJCXJldHVybiBuYW1lLmdldFRleHQoKTsKCX0KCgkvKioKCSAqIHtAaW5oZXJpdERvY30KCSAqIAoJICogQHNlZSBvcmcuZWNsaXBzZS5vcGVuY2VydC5hcG0uYmFzZWxpbmUuYmFzZWxpbmUucGFydHMuQmFzZUFydGVmYWN0UHJvcGVydGllc0VkaXRpb25QYXJ0I3NldE5hbWUoU3RyaW5nIG5ld1ZhbHVlKQoJICogCgkgKi8KCXB1YmxpYyB2b2lkIHNldE5hbWUoU3RyaW5nIG5ld1ZhbHVlKSB7CgkJaWYgKG5ld1ZhbHVlICE9IG51bGwpIHsKCQkJbmFtZS5zZXRUZXh0KG5ld1ZhbHVlKTsKCQl9IGVsc2UgewoJCQluYW1lLnNldFRleHQoIiIpOyAvLyROT04tTkxTLTEkCgkJfQoJCWJvb2xlYW4gZWVmRWxlbWVudEVkaXRvclJlYWRPbmx5U3RhdGUgPSBpc1JlYWRPbmx5KEJhc2VsaW5lVmlld3NSZXBvc2l0b3J5LkJhc2VBcnRlZmFjdC5Qcm9wZXJ0aWVzLm5hbWUpOwoJCWlmIChlZWZFbGVtZW50RWRpdG9yUmVhZE9ubHlTdGF0ZSAmJiBuYW1lLmlzRW5hYmxlZCgpKSB7CgkJCW5hbWUuc2V0RW5hYmxlZChmYWxzZSk7CgkJCW5hbWUuc2V0VG9vbFRpcFRleHQoQmFzZWxpbmVNZXNzYWdlcy5CYXNlQXJ0ZWZhY3RfUmVhZE9ubHkpOwoJCX0gZWxzZSBpZiAoIWVlZkVsZW1lbnRFZGl0b3JSZWFkT25seVN0YXRlICYmICFuYW1lLmlzRW5hYmxlZCgpKSB7CgkJCW5hbWUuc2V0RW5hYmxlZCh0cnVlKTsKCQl9CQoJCQoJfQoKCS8qKgoJICoge0Bpbmhlcml0RG9jfQoJICogCgkgKiBAc2VlIG9yZy5lY2xpcHNlLm9wZW5jZXJ0LmFwbS5iYXNlbGluZS5iYXNlbGluZS5wYXJ0cy5CYXNlQXJ0ZWZhY3RQcm9wZXJ0aWVzRWRpdGlvblBhcnQjZ2V0RGVzY3JpcHRpb24oKQoJICogCgkgKi8KCXB1YmxpYyBTdHJpbmcgZ2V0RGVzY3JpcHRpb24oKSB7CgkJcmV0dXJuIGRlc2NyaXB0aW9uLmdldFRleHQoKTsKCX0KCgkvKioKCSAqIHtAaW5oZXJpdERvY30KCSAqIAoJICogQHNlZSBvcmcuZWNsaXBzZS5vcGVuY2VydC5hcG0uYmFzZWxpbmUuYmFzZWxpbmUucGFydHMuQmFzZUFydGVmYWN0UHJvcGVydGllc0VkaXRpb25QYXJ0I3NldERlc2NyaXB0aW9uKFN0cmluZyBuZXdWYWx1ZSkKCSAqIAoJICovCglwdWJsaWMgdm9pZCBzZXREZXNjcmlwdGlvbihTdHJpbmcgbmV3VmFsdWUpIHsKCQlpZiAobmV3VmFsdWUgIT0gbnVsbCkgewoJCQlkZXNjcmlwdGlvbi5zZXRUZXh0KG5ld1ZhbHVlKTsKCQl9IGVsc2UgewoJCQlkZXNjcmlwdGlvbi5zZXRUZXh0KCIiKTsgLy8kTk9OLU5MUy0xJAoJCX0KCQlib29sZWFuIGVlZkVsZW1lbnRFZGl0b3JSZWFkT25seVN0YXRlID0gaXNSZWFkT25seShCYXNlbGluZVZpZXdzUmVwb3NpdG9yeS5CYXNlQXJ0ZWZhY3QuUHJvcGVydGllcy5kZXNjcmlwdGlvbik7CgkJaWYgKGVlZkVsZW1lbnRFZGl0b3JSZWFkT25seVN0YXRlICYmIGRlc2NyaXB0aW9uLmlzRW5hYmxlZCgpKSB7CgkJCWRlc2NyaXB0aW9uLnNldEVuYWJsZWQoZmFsc2UpOwoJCQlkZXNjcmlwdGlvbi5zZXRCYWNrZ3JvdW5kKGRlc2NyaXB0aW9uLmdldERpc3BsYXkoKS5nZXRTeXN0ZW1Db2xvcihTV1QuQ09MT1JfV0lER0VUX0JBQ0tHUk9VTkQpKTsKCQkJZGVzY3JpcHRpb24uc2V0VG9vbFRpcFRleHQoQmFzZWxpbmVNZXNzYWdlcy5CYXNlQXJ0ZWZhY3RfUmVhZE9ubHkpOwoJCX0gZWxzZSBpZiAoIWVlZkVsZW1lbnRFZGl0b3JSZWFkT25seVN0YXRlICYmICFkZXNjcmlwdGlvbi5pc0VuYWJsZWQoKSkgewoJCQlkZXNjcmlwdGlvbi5zZXRFbmFibGVkKHRydWUpOwoJCX0JCgkJCgl9CgoJLyoqCgkgKiB7QGluaGVyaXREb2N9CgkgKiAKCSAqIEBzZWUgb3JnLmVjbGlwc2Uub3BlbmNlcnQuYXBtLmJhc2VsaW5lLmJhc2VsaW5lLnBhcnRzLkJhc2VBcnRlZmFjdFByb3BlcnRpZXNFZGl0aW9uUGFydCNnZXRSZWZlcmVuY2UoKQoJICogCgkgKi8KCXB1YmxpYyBTdHJpbmcgZ2V0UmVmZXJlbmNlKCkgewoJCXJldHVybiByZWZlcmVuY2UuZ2V0VGV4dCgpOwoJfQoKCS8qKgoJICoge0Bpbmhlcml0RG9jfQoJICogCgkgKiBAc2VlIG9yZy5lY2xpcHNlLm9wZW5jZXJ0LmFwbS5iYXNlbGluZS5iYXNlbGluZS5wYXJ0cy5CYXNlQXJ0ZWZhY3RQcm9wZXJ0aWVzRWRpdGlvblBhcnQjc2V0UmVmZXJlbmNlKFN0cmluZyBuZXdWYWx1ZSkKCSAqIAoJICovCglwdWJsaWMgdm9pZCBzZXRSZWZlcmVuY2UoU3RyaW5nIG5ld1ZhbHVlKSB7CgkJaWYgKG5ld1ZhbHVlICE9IG51bGwpIHsKCQkJcmVmZXJlbmNlLnNldFRleHQobmV3VmFsdWUpOwoJCX0gZWxzZSB7CgkJCXJlZmVyZW5jZS5zZXRUZXh0KCIiKTsgLy8kTk9OLU5MUy0xJAoJCX0KCQlib29sZWFuIGVlZkVsZW1lbnRFZGl0b3JSZWFkT25seVN0YXRlID0gaXNSZWFkT25seShCYXNlbGluZVZpZXdzUmVwb3NpdG9yeS5CYXNlQXJ0ZWZhY3QuUHJvcGVydGllcy5yZWZlcmVuY2UpOwoJCWlmIChlZWZFbGVtZW50RWRpdG9yUmVhZE9ubHlTdGF0ZSAmJiByZWZlcmVuY2UuaXNFbmFibGVkKCkpIHsKCQkJcmVmZXJlbmNlLnNldEVuYWJsZWQoZmFsc2UpOwoJCQlyZWZlcmVuY2Uuc2V0VG9vbFRpcFRleHQoQmFzZWxpbmVNZXNzYWdlcy5CYXNlQXJ0ZWZhY3RfUmVhZE9ubHkpOwoJCX0gZWxzZSBpZiAoIWVlZkVsZW1lbnRFZGl0b3JSZWFkT25seVN0YXRlICYmICFyZWZlcmVuY2UuaXNFbmFibGVkKCkpIHsKCQkJcmVmZXJlbmNlLnNldEVuYWJsZWQodHJ1ZSk7CgkJfQkKCQkKCX0KCgoKCS8qKgoJICoge0Bpbmhlcml0RG9jfQoJICogCgkgKiBAc2VlIG9yZy5lY2xpcHNlLm9wZW5jZXJ0LmFwbS5iYXNlbGluZS5iYXNlbGluZS5wYXJ0cy5CYXNlQXJ0ZWZhY3RQcm9wZXJ0aWVzRWRpdGlvblBhcnQjaW5pdENvbnN0cmFpbmluZ1JlcXVpcmVtZW50KG9yZy5lY2xpcHNlLmVtZi5lZWYucnVudGltZS51aS53aWRnZXRzLnJlZmVyZW5jZXN0YWJsZS5SZWZlcmVuY2VzVGFibGVTZXR0aW5ncykKCSAqLwoJcHVibGljIHZvaWQgaW5pdENvbnN0cmFpbmluZ1JlcXVpcmVtZW50KFJlZmVyZW5jZXNUYWJsZVNldHRpbmdzIHNldHRpbmdzKSB7CgkJaWYgKGN1cnJlbnQuZVJlc291cmNlKCkgIT0gbnVsbCAmJiBjdXJyZW50LmVSZXNvdXJjZSgpLmdldFJlc291cmNlU2V0KCkgIT0gbnVsbCkKCQkJdGhpcy5yZXNvdXJjZVNldCA9IGN1cnJlbnQuZVJlc291cmNlKCkuZ2V0UmVzb3VyY2VTZXQoKTsKCQlSZWZlcmVuY2VzVGFibGVDb250ZW50UHJvdmlkZXIgY29udGVudFByb3ZpZGVyID0gbmV3IFJlZmVyZW5jZXNUYWJsZUNvbnRlbnRQcm92aWRlcigpOwoJCWNvbnN0cmFpbmluZ1JlcXVpcmVtZW50LnNldENvbnRlbnRQcm92aWRlcihjb250ZW50UHJvdmlkZXIpOwoJCWNvbnN0cmFpbmluZ1JlcXVpcmVtZW50LnNldElucHV0KHNldHRpbmdzKTsKCQlib29sZWFuIGVlZkVsZW1lbnRFZGl0b3JSZWFkT25seVN0YXRlID0gaXNSZWFkT25seShCYXNlbGluZVZpZXdzUmVwb3NpdG9yeS5CYXNlQXJ0ZWZhY3QuUHJvcGVydGllcy5jb25zdHJhaW5pbmdSZXF1aXJlbWVudCk7CgkJaWYgKGVlZkVsZW1lbnRFZGl0b3JSZWFkT25seVN0YXRlICYmIGNvbnN0cmFpbmluZ1JlcXVpcmVtZW50LmdldFRhYmxlKCkuaXNFbmFibGVkKCkpIHsKCQkJY29uc3RyYWluaW5nUmVxdWlyZW1lbnQuc2V0RW5hYmxlZChmYWxzZSk7CgkJCWNvbnN0cmFpbmluZ1JlcXVpcmVtZW50LnNldFRvb2xUaXBUZXh0KEJhc2VsaW5lTWVzc2FnZXMuQmFzZUFydGVmYWN0X1JlYWRPbmx5KTsKCQl9IGVsc2UgaWYgKCFlZWZFbGVtZW50RWRpdG9yUmVhZE9ubHlTdGF0ZSAmJiAhY29uc3RyYWluaW5nUmVxdWlyZW1lbnQuZ2V0VGFibGUoKS5pc0VuYWJsZWQoKSkgewoJCQljb25zdHJhaW5pbmdSZXF1aXJlbWVudC5zZXRFbmFibGVkKHRydWUpOwoJCX0KCQkKCX0KCgkvKioKCSAqIHtAaW5oZXJpdERvY30KCSAqIAoJICogQHNlZSBvcmcuZWNsaXBzZS5vcGVuY2VydC5hcG0uYmFzZWxpbmUuYmFzZWxpbmUucGFydHMuQmFzZUFydGVmYWN0UHJvcGVydGllc0VkaXRpb25QYXJ0I3VwZGF0ZUNvbnN0cmFpbmluZ1JlcXVpcmVtZW50KCkKCSAqIAoJICovCglwdWJsaWMgdm9pZCB1cGRhdGVDb25zdHJhaW5pbmdSZXF1aXJlbWVudCgpIHsKCWNvbnN0cmFpbmluZ1JlcXVpcmVtZW50LnJlZnJlc2goKTsKfQoKCS8qKgoJICoge0Bpbmhlcml0RG9jfQoJICogCgkgKiBAc2VlIG9yZy5lY2xpcHNlLm9wZW5jZXJ0LmFwbS5iYXNlbGluZS5iYXNlbGluZS5wYXJ0cy5CYXNlQXJ0ZWZhY3RQcm9wZXJ0aWVzRWRpdGlvblBhcnQjYWRkRmlsdGVyQ29uc3RyYWluaW5nUmVxdWlyZW1lbnQoVmlld2VyRmlsdGVyIGZpbHRlcikKCSAqIAoJICovCglwdWJsaWMgdm9pZCBhZGRGaWx0ZXJUb0NvbnN0cmFpbmluZ1JlcXVpcmVtZW50KFZpZXdlckZpbHRlciBmaWx0ZXIpIHsKCQljb25zdHJhaW5pbmdSZXF1aXJlbWVudEZpbHRlcnMuYWRkKGZpbHRlcik7Cgl9CgoJLyoqCgkgKiB7QGluaGVyaXREb2N9CgkgKiAKCSAqIEBzZWUgb3JnLmVjbGlwc2Uub3BlbmNlcnQuYXBtLmJhc2VsaW5lLmJhc2VsaW5lLnBhcnRzLkJhc2VBcnRlZmFjdFByb3BlcnRpZXNFZGl0aW9uUGFydCNhZGRCdXNpbmVzc0ZpbHRlckNvbnN0cmFpbmluZ1JlcXVpcmVtZW50KFZpZXdlckZpbHRlciBmaWx0ZXIpCgkgKiAKCSAqLwoJcHVibGljIHZvaWQgYWRkQnVzaW5lc3NGaWx0ZXJUb0NvbnN0cmFpbmluZ1JlcXVpcmVtZW50KFZpZXdlckZpbHRlciBmaWx0ZXIpIHsKCQljb25zdHJhaW5pbmdSZXF1aXJlbWVudEJ1c2luZXNzRmlsdGVycy5hZGQoZmlsdGVyKTsKCX0KCgkvKioKCSAqIHtAaW5oZXJpdERvY30KCSAqIAoJICogQHNlZSBvcmcuZWNsaXBzZS5vcGVuY2VydC5hcG0uYmFzZWxpbmUuYmFzZWxpbmUucGFydHMuQmFzZUFydGVmYWN0UHJvcGVydGllc0VkaXRpb25QYXJ0I2lzQ29udGFpbmVkSW5Db25zdHJhaW5pbmdSZXF1aXJlbWVudFRhYmxlKEVPYmplY3QgZWxlbWVudCkKCSAqIAoJICovCglwdWJsaWMgYm9vbGVhbiBpc0NvbnRhaW5lZEluQ29uc3RyYWluaW5nUmVxdWlyZW1lbnRUYWJsZShFT2JqZWN0IGVsZW1lbnQpIHsKCQlyZXR1cm4gKChSZWZlcmVuY2VzVGFibGVTZXR0aW5ncyljb25zdHJhaW5pbmdSZXF1aXJlbWVudC5nZXRJbnB1dCgpKS5jb250YWlucyhlbGVtZW50KTsKCX0KCgoKCS8qKgoJICoge0Bpbmhlcml0RG9jfQoJICogCgkgKiBAc2VlIG9yZy5lY2xpcHNlLm9wZW5jZXJ0LmFwbS5iYXNlbGluZS5iYXNlbGluZS5wYXJ0cy5CYXNlQXJ0ZWZhY3RQcm9wZXJ0aWVzRWRpdGlvblBhcnQjaW5pdEFwcGxpY2FibGVUZWNobmlxdWUob3JnLmVjbGlwc2UuZW1mLmVlZi5ydW50aW1lLnVpLndpZGdldHMucmVmZXJlbmNlc3RhYmxlLlJlZmVyZW5jZXNUYWJsZVNldHRpbmdzKQoJICovCglwdWJsaWMgdm9pZCBpbml0QXBwbGljYWJsZVRlY2huaXF1ZShSZWZlcmVuY2VzVGFibGVTZXR0aW5ncyBzZXR0aW5ncykgewoJCWlmIChjdXJyZW50LmVSZXNvdXJjZSgpICE9IG51bGwgJiYgY3VycmVudC5lUmVzb3VyY2UoKS5nZXRSZXNvdXJjZVNldCgpICE9IG51bGwpCgkJCXRoaXMucmVzb3VyY2VTZXQgPSBjdXJyZW50LmVSZXNvdXJjZSgpLmdldFJlc291cmNlU2V0KCk7CgkJUmVmZXJlbmNlc1RhYmxlQ29udGVudFByb3ZpZGVyIGNvbnRlbnRQcm92aWRlciA9IG5ldyBSZWZlcmVuY2VzVGFibGVDb250ZW50UHJvdmlkZXIoKTsKCQlhcHBsaWNhYmxlVGVjaG5pcXVlLnNldENvbnRlbnRQcm92aWRlcihjb250ZW50UHJvdmlkZXIpOwoJCWFwcGxpY2FibGVUZWNobmlxdWUuc2V0SW5wdXQoc2V0dGluZ3MpOwoJCWJvb2xlYW4gZWVmRWxlbWVudEVkaXRvclJlYWRPbmx5U3RhdGUgPSBpc1JlYWRPbmx5KEJhc2VsaW5lVmlld3NSZXBvc2l0b3J5LkJhc2VBcnRlZmFjdC5Qcm9wZXJ0aWVzLmFwcGxpY2FibGVUZWNobmlxdWUpOwoJCWlmIChlZWZFbGVtZW50RWRpdG9yUmVhZE9ubHlTdGF0ZSAmJiBhcHBsaWNhYmxlVGVjaG5pcXVlLmdldFRhYmxlKCkuaXNFbmFibGVkKCkpIHsKCQkJYXBwbGljYWJsZVRlY2huaXF1ZS5zZXRFbmFibGVkKGZhbHNlKTsKCQkJYXBwbGljYWJsZVRlY2huaXF1ZS5zZXRUb29sVGlwVGV4dChCYXNlbGluZU1lc3NhZ2VzLkJhc2VBcnRlZmFjdF9SZWFkT25seSk7CgkJfSBlbHNlIGlmICghZWVmRWxlbWVudEVkaXRvclJlYWRPbmx5U3RhdGUgJiYgIWFwcGxpY2FibGVUZWNobmlxdWUuZ2V0VGFibGUoKS5pc0VuYWJsZWQoKSkgewoJCQlhcHBsaWNhYmxlVGVjaG5pcXVlLnNldEVuYWJsZWQodHJ1ZSk7CgkJfQoJCQoJfQoKCS8qKgoJICoge0Bpbmhlcml0RG9jfQoJICogCgkgKiBAc2VlIG9yZy5lY2xpcHNlLm9wZW5jZXJ0LmFwbS5iYXNlbGluZS5iYXNlbGluZS5wYXJ0cy5CYXNlQXJ0ZWZhY3RQcm9wZXJ0aWVzRWRpdGlvblBhcnQjdXBkYXRlQXBwbGljYWJsZVRlY2huaXF1ZSgpCgkgKiAKCSAqLwoJcHVibGljIHZvaWQgdXBkYXRlQXBwbGljYWJsZVRlY2huaXF1ZSgpIHsKCWFwcGxpY2FibGVUZWNobmlxdWUucmVmcmVzaCgpOwp9CgoJLyoqCgkgKiB7QGluaGVyaXREb2N9CgkgKiAKCSAqIEBzZWUgb3JnLmVjbGlwc2Uub3BlbmNlcnQuYXBtLmJhc2VsaW5lLmJhc2VsaW5lLnBhcnRzLkJhc2VBcnRlZmFjdFByb3BlcnRpZXNFZGl0aW9uUGFydCNhZGRGaWx0ZXJBcHBsaWNhYmxlVGVjaG5pcXVlKFZpZXdlckZpbHRlciBmaWx0ZXIpCgkgKiAKCSAqLwoJcHVibGljIHZvaWQgYWRkRmlsdGVyVG9BcHBsaWNhYmxlVGVjaG5pcXVlKFZpZXdlckZpbHRlciBmaWx0ZXIpIHsKCQlhcHBsaWNhYmxlVGVjaG5pcXVlRmlsdGVycy5hZGQoZmlsdGVyKTsKCX0KCgkvKioKCSAqIHtAaW5oZXJpdERvY30KCSAqIAoJICogQHNlZSBvcmcuZWNsaXBzZS5vcGVuY2VydC5hcG0uYmFzZWxpbmUuYmFzZWxpbmUucGFydHMuQmFzZUFydGVmYWN0UHJvcGVydGllc0VkaXRpb25QYXJ0I2FkZEJ1c2luZXNzRmlsdGVyQXBwbGljYWJsZVRlY2huaXF1ZShWaWV3ZXJGaWx0ZXIgZmlsdGVyKQoJICogCgkgKi8KCXB1YmxpYyB2b2lkIGFkZEJ1c2luZXNzRmlsdGVyVG9BcHBsaWNhYmxlVGVjaG5pcXVlKFZpZXdlckZpbHRlciBmaWx0ZXIpIHsKCQlhcHBsaWNhYmxlVGVjaG5pcXVlQnVzaW5lc3NGaWx0ZXJzLmFkZChmaWx0ZXIpOwoJfQoKCS8qKgoJICoge0Bpbmhlcml0RG9jfQoJICogCgkgKiBAc2VlIG9yZy5lY2xpcHNlLm9wZW5jZXJ0LmFwbS5iYXNlbGluZS5iYXNlbGluZS5wYXJ0cy5CYXNlQXJ0ZWZhY3RQcm9wZXJ0aWVzRWRpdGlvblBhcnQjaXNDb250YWluZWRJbkFwcGxpY2FibGVUZWNobmlxdWVUYWJsZShFT2JqZWN0IGVsZW1lbnQpCgkgKiAKCSAqLwoJcHVibGljIGJvb2xlYW4gaXNDb250YWluZWRJbkFwcGxpY2FibGVUZWNobmlxdWVUYWJsZShFT2JqZWN0IGVsZW1lbnQpIHsKCQlyZXR1cm4gKChSZWZlcmVuY2VzVGFibGVTZXR0aW5ncylhcHBsaWNhYmxlVGVjaG5pcXVlLmdldElucHV0KCkpLmNvbnRhaW5zKGVsZW1lbnQpOwoJfQoKCgoJLyoqCgkgKiB7QGluaGVyaXREb2N9CgkgKiAKCSAqIEBzZWUgb3JnLmVjbGlwc2Uub3BlbmNlcnQuYXBtLmJhc2VsaW5lLmJhc2VsaW5lLnBhcnRzLkJhc2VBcnRlZmFjdFByb3BlcnRpZXNFZGl0aW9uUGFydCNpbml0T3duZWRSZWwoRU9iamVjdCBjdXJyZW50LCBFUmVmZXJlbmNlIGNvbnRhaW5pbmdGZWF0dXJlLCBFUmVmZXJlbmNlIGZlYXR1cmUpCgkgKi8KCXB1YmxpYyB2b2lkIGluaXRPd25lZFJlbChSZWZlcmVuY2VzVGFibGVTZXR0aW5ncyBzZXR0aW5ncykgewoJCWlmIChjdXJyZW50LmVSZXNvdXJjZSgpICE9IG51bGwgJiYgY3VycmVudC5lUmVzb3VyY2UoKS5nZXRSZXNvdXJjZVNldCgpICE9IG51bGwpCgkJCXRoaXMucmVzb3VyY2VTZXQgPSBjdXJyZW50LmVSZXNvdXJjZSgpLmdldFJlc291cmNlU2V0KCk7CgkJUmVmZXJlbmNlc1RhYmxlQ29udGVudFByb3ZpZGVyIGNvbnRlbnRQcm92aWRlciA9IG5ldyBSZWZlcmVuY2VzVGFibGVDb250ZW50UHJvdmlkZXIoKTsKCQlvd25lZFJlbC5zZXRDb250ZW50UHJvdmlkZXIoY29udGVudFByb3ZpZGVyKTsKCQlvd25lZFJlbC5zZXRJbnB1dChzZXR0aW5ncyk7CgkJYm9vbGVhbiBlZWZFbGVtZW50RWRpdG9yUmVhZE9ubHlTdGF0ZSA9IGlzUmVhZE9ubHkoQmFzZWxpbmVWaWV3c1JlcG9zaXRvcnkuQmFzZUFydGVmYWN0LlByb3BlcnRpZXMub3duZWRSZWwpOwoJCWlmIChlZWZFbGVtZW50RWRpdG9yUmVhZE9ubHlTdGF0ZSAmJiBvd25lZFJlbC5pc0VuYWJsZWQoKSkgewoJCQlvd25lZFJlbC5zZXRFbmFibGVkKGZhbHNlKTsKCQkJb3duZWRSZWwuc2V0VG9vbFRpcFRleHQoQmFzZWxpbmVNZXNzYWdlcy5CYXNlQXJ0ZWZhY3RfUmVhZE9ubHkpOwoJCX0gZWxzZSBpZiAoIWVlZkVsZW1lbnRFZGl0b3JSZWFkT25seVN0YXRlICYmICFvd25lZFJlbC5pc0VuYWJsZWQoKSkgewoJCQlvd25lZFJlbC5zZXRFbmFibGVkKHRydWUpOwoJCX0JCgkJCgl9CgoJLyoqCgkgKiB7QGluaGVyaXREb2N9CgkgKiAKCSAqIEBzZWUgb3JnLmVjbGlwc2Uub3BlbmNlcnQuYXBtLmJhc2VsaW5lLmJhc2VsaW5lLnBhcnRzLkJhc2VBcnRlZmFjdFByb3BlcnRpZXNFZGl0aW9uUGFydCN1cGRhdGVPd25lZFJlbCgpCgkgKiAKCSAqLwoJcHVibGljIHZvaWQgdXBkYXRlT3duZWRSZWwoKSB7Cglvd25lZFJlbC5yZWZyZXNoKCk7Cn0KCgkvKioKCSAqIHtAaW5oZXJpdERvY30KCSAqIAoJICogQHNlZSBvcmcuZWNsaXBzZS5vcGVuY2VydC5hcG0uYmFzZWxpbmUuYmFzZWxpbmUucGFydHMuQmFzZUFydGVmYWN0UHJvcGVydGllc0VkaXRpb25QYXJ0I2FkZEZpbHRlck93bmVkUmVsKFZpZXdlckZpbHRlciBmaWx0ZXIpCgkgKiAKCSAqLwoJcHVibGljIHZvaWQgYWRkRmlsdGVyVG9Pd25lZFJlbChWaWV3ZXJGaWx0ZXIgZmlsdGVyKSB7CgkJb3duZWRSZWxGaWx0ZXJzLmFkZChmaWx0ZXIpOwoJCWlmICh0aGlzLm93bmVkUmVsICE9IG51bGwpIHsKCQkJdGhpcy5vd25lZFJlbC5hZGRGaWx0ZXIoZmlsdGVyKTsKCQl9Cgl9CgoJLyoqCgkgKiB7QGluaGVyaXREb2N9CgkgKiAKCSAqIEBzZWUgb3JnLmVjbGlwc2Uub3BlbmNlcnQuYXBtLmJhc2VsaW5lLmJhc2VsaW5lLnBhcnRzLkJhc2VBcnRlZmFjdFByb3BlcnRpZXNFZGl0aW9uUGFydCNhZGRCdXNpbmVzc0ZpbHRlck93bmVkUmVsKFZpZXdlckZpbHRlciBmaWx0ZXIpCgkgKiAKCSAqLwoJcHVibGljIHZvaWQgYWRkQnVzaW5lc3NGaWx0ZXJUb093bmVkUmVsKFZpZXdlckZpbHRlciBmaWx0ZXIpIHsKCQlvd25lZFJlbEJ1c2luZXNzRmlsdGVycy5hZGQoZmlsdGVyKTsKCX0KCgkvKioKCSAqIHtAaW5oZXJpdERvY30KCSAqIAoJICogQHNlZSBvcmcuZWNsaXBzZS5vcGVuY2VydC5hcG0uYmFzZWxpbmUuYmFzZWxpbmUucGFydHMuQmFzZUFydGVmYWN0UHJvcGVydGllc0VkaXRpb25QYXJ0I2lzQ29udGFpbmVkSW5Pd25lZFJlbFRhYmxlKEVPYmplY3QgZWxlbWVudCkKCSAqIAoJICovCglwdWJsaWMgYm9vbGVhbiBpc0NvbnRhaW5lZEluT3duZWRSZWxUYWJsZShFT2JqZWN0IGVsZW1lbnQpIHsKCQlyZXR1cm4gKChSZWZlcmVuY2VzVGFibGVTZXR0aW5ncylvd25lZFJlbC5nZXRJbnB1dCgpKS5jb250YWlucyhlbGVtZW50KTsKCX0KCgoKCS8qKgoJICoge0Bpbmhlcml0RG9jfQoJICogCgkgKiBAc2VlIG9yZy5lY2xpcHNlLm9wZW5jZXJ0LmFwbS5iYXNlbGluZS5iYXNlbGluZS5wYXJ0cy5CYXNlQXJ0ZWZhY3RQcm9wZXJ0aWVzRWRpdGlvblBhcnQjaW5pdFByb3BlcnR5KG9yZy5lY2xpcHNlLmVtZi5lZWYucnVudGltZS51aS53aWRnZXRzLnJlZmVyZW5jZXN0YWJsZS5SZWZlcmVuY2VzVGFibGVTZXR0aW5ncykKCSAqLwoJcHVibGljIHZvaWQgaW5pdFByb3BlcnR5KFJlZmVyZW5jZXNUYWJsZVNldHRpbmdzIHNldHRpbmdzKSB7CgkJaWYgKGN1cnJlbnQuZVJlc291cmNlKCkgIT0gbnVsbCAmJiBjdXJyZW50LmVSZXNvdXJjZSgpLmdldFJlc291cmNlU2V0KCkgIT0gbnVsbCkKCQkJdGhpcy5yZXNvdXJjZVNldCA9IGN1cnJlbnQuZVJlc291cmNlKCkuZ2V0UmVzb3VyY2VTZXQoKTsKCQlSZWZlcmVuY2VzVGFibGVDb250ZW50UHJvdmlkZXIgY29udGVudFByb3ZpZGVyID0gbmV3IFJlZmVyZW5jZXNUYWJsZUNvbnRlbnRQcm92aWRlcigpOwoJCXByb3BlcnR5LnNldENvbnRlbnRQcm92aWRlcihjb250ZW50UHJvdmlkZXIpOwoJCXByb3BlcnR5LnNldElucHV0KHNldHRpbmdzKTsKCQlib29sZWFuIGVlZkVsZW1lbnRFZGl0b3JSZWFkT25seVN0YXRlID0gaXNSZWFkT25seShCYXNlbGluZVZpZXdzUmVwb3NpdG9yeS5CYXNlQXJ0ZWZhY3QuUHJvcGVydGllcy5wcm9wZXJ0eSk7CgkJaWYgKGVlZkVsZW1lbnRFZGl0b3JSZWFkT25seVN0YXRlICYmIHByb3BlcnR5LmdldFRhYmxlKCkuaXNFbmFibGVkKCkpIHsKCQkJcHJvcGVydHkuc2V0RW5hYmxlZChmYWxzZSk7CgkJCXByb3BlcnR5LnNldFRvb2xUaXBUZXh0KEJhc2VsaW5lTWVzc2FnZXMuQmFzZUFydGVmYWN0X1JlYWRPbmx5KTsKCQl9IGVsc2UgaWYgKCFlZWZFbGVtZW50RWRpdG9yUmVhZE9ubHlTdGF0ZSAmJiAhcHJvcGVydHkuZ2V0VGFibGUoKS5pc0VuYWJsZWQoKSkgewoJCQlwcm9wZXJ0eS5zZXRFbmFibGVkKHRydWUpOwoJCX0KCQkKCX0KCgkvKioKCSAqIHtAaW5oZXJpdERvY30KCSAqIAoJICogQHNlZSBvcmcuZWNsaXBzZS5vcGVuY2VydC5hcG0uYmFzZWxpbmUuYmFzZWxpbmUucGFydHMuQmFzZUFydGVmYWN0UHJvcGVydGllc0VkaXRpb25QYXJ0I3VwZGF0ZVByb3BlcnR5KCkKCSAqIAoJICovCglwdWJsaWMgdm9pZCB1cGRhdGVQcm9wZXJ0eSgpIHsKCXByb3BlcnR5LnJlZnJlc2goKTsKfQoKCS8qKgoJICoge0Bpbmhlcml0RG9jfQoJICogCgkgKiBAc2VlIG9yZy5lY2xpcHNlLm9wZW5jZXJ0LmFwbS5iYXNlbGluZS5iYXNlbGluZS5wYXJ0cy5CYXNlQXJ0ZWZhY3RQcm9wZXJ0aWVzRWRpdGlvblBhcnQjYWRkRmlsdGVyUHJvcGVydHkoVmlld2VyRmlsdGVyIGZpbHRlcikKCSAqIAoJICovCglwdWJsaWMgdm9pZCBhZGRGaWx0ZXJUb1Byb3BlcnR5KFZpZXdlckZpbHRlciBmaWx0ZXIpIHsKCQlwcm9wZXJ0eUZpbHRlcnMuYWRkKGZpbHRlcik7Cgl9CgoJLyoqCgkgKiB7QGluaGVyaXREb2N9CgkgKiAKCSAqIEBzZWUgb3JnLmVjbGlwc2Uub3BlbmNlcnQuYXBtLmJhc2VsaW5lLmJhc2VsaW5lLnBhcnRzLkJhc2VBcnRlZmFjdFByb3BlcnRpZXNFZGl0aW9uUGFydCNhZGRCdXNpbmVzc0ZpbHRlclByb3BlcnR5KFZpZXdlckZpbHRlciBmaWx0ZXIpCgkgKiAKCSAqLwoJcHVibGljIHZvaWQgYWRkQnVzaW5lc3NGaWx0ZXJUb1Byb3BlcnR5KFZpZXdlckZpbHRlciBmaWx0ZXIpIHsKCQlwcm9wZXJ0eUJ1c2luZXNzRmlsdGVycy5hZGQoZmlsdGVyKTsKCX0KCgkvKioKCSAqIHtAaW5oZXJpdERvY30KCSAqIAoJICogQHNlZSBvcmcuZWNsaXBzZS5vcGVuY2VydC5hcG0uYmFzZWxpbmUuYmFzZWxpbmUucGFydHMuQmFzZUFydGVmYWN0UHJvcGVydGllc0VkaXRpb25QYXJ0I2lzQ29udGFpbmVkSW5Qcm9wZXJ0eVRhYmxlKEVPYmplY3QgZWxlbWVudCkKCSAqIAoJICovCglwdWJsaWMgYm9vbGVhbiBpc0NvbnRhaW5lZEluUHJvcGVydHlUYWJsZShFT2JqZWN0IGVsZW1lbnQpIHsKCQlyZXR1cm4gKChSZWZlcmVuY2VzVGFibGVTZXR0aW5ncylwcm9wZXJ0eS5nZXRJbnB1dCgpKS5jb250YWlucyhlbGVtZW50KTsKCX0KCgoKCgoKCS8qKgoJICoge0Bpbmhlcml0RG9jfQoJICoKCSAqIEBzZWUgb3JnLmVjbGlwc2UuZW1mLmVlZi5ydW50aW1lLmFwaS5wYXJ0cy5JUHJvcGVydGllc0VkaXRpb25QYXJ0I2dldFRpdGxlKCkKCSAqIAoJICovCglwdWJsaWMgU3RyaW5nIGdldFRpdGxlKCkgewoJCXJldHVybiBCYXNlbGluZU1lc3NhZ2VzLkJhc2VBcnRlZmFjdF9QYXJ0X1RpdGxlOwoJfQoKCS8vIFN0YXJ0IG9mIHVzZXIgY29kZSBhZGRpdGlvbmFsIG1ldGhvZHMKCQoJLy8gRW5kIG9mIHVzZXIgY29kZQoKCn0K