LyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogQ29weXJpZ2h0IChjKSAyMDE2IEZ1bmRhY2nzbiBUZWNuYWxpYSBSZXNlYXJjaCAmIElubm92YXRpb24uCiAqCiAqIEFsbCByaWdodHMgcmVzZXJ2ZWQuIFRoaXMgcHJvZ3JhbSBhbmQgdGhlIGFjY29tcGFueWluZyBtYXRlcmlhbHMKICogYXJlIG1hZGUgYXZhaWxhYmxlIHVuZGVyIHRoZSB0ZXJtcyBvZiB0aGUgRWNsaXBzZSBQdWJsaWMgTGljZW5zZSB2MS4wCiAqIHdoaWNoIGFjY29tcGFuaWVzIHRoaXMgZGlzdHJpYnV0aW9uLCBhbmQgaXMgYXZhaWxhYmxlIGF0CiAqIGh0dHA6Ly93d3cuZWNsaXBzZS5vcmcvbGVnYWwvZXBsLXYxMC5odG1sCiAqCiAqIENvbnRyaWJ1dG9yczoKICogICBIdWFzY2FyIEVzcGlub3phIC0gaW5pdGlhbCBBUEkgYW5kIGltcGxlbWVudGF0aW9uCiAqICAgQWxlamFuZHJhIFJ17XogLSBpbml0aWFsIEFQSSBhbmQgaW1wbGVtZW50YXRpb24KICogICBJZG95YSBEZWwgUu1vIC0gaW5pdGlhbCBBUEkgYW5kIGltcGxlbWVudGF0aW9uCiAqICAgTWFyaSBDYXJtZW4gUGFsYWNpb3MgLSBpbml0aWFsIEFQSSBhbmQgaW1wbGVtZW50YXRpb24KICogICBBbmdlbCBM83BleiAtIGluaXRpYWwgQVBJIGFuZCBpbXBsZW1lbnRhdGlvbgogKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8KLyoqCiAqIEdlbmVyYXRlZCB3aXRoIEFjY2VsZW8KICovCnBhY2thZ2Ugb3JnLmVjbGlwc2Uub3BlbmNlcnQuZXZtLmV2aWRzcGVjLmV2aWRlbmNlLnBhcnRzLmZvcm1zOwoKLy8gU3RhcnQgb2YgdXNlciBjb2RlIGZvciBpbXBvcnRzCmltcG9ydCBqYXZhLnV0aWwuQXJyYXlMaXN0OwppbXBvcnQgamF2YS51dGlsLkxpc3Q7CgppbXBvcnQgb3JnLmVjbGlwc2UuZW1mLmVjb3JlLkVPYmplY3Q7CmltcG9ydCBvcmcuZWNsaXBzZS5lbWYuZWVmLnJ1bnRpbWUuYXBpLmNvbXBvbmVudC5JUHJvcGVydGllc0VkaXRpb25Db21wb25lbnQ7CmltcG9ydCBvcmcuZWNsaXBzZS5lbWYuZWVmLnJ1bnRpbWUuYXBpLm5vdGlmeS5JUHJvcGVydGllc0VkaXRpb25FdmVudDsKaW1wb3J0IG9yZy5lY2xpcHNlLmVtZi5lZWYucnVudGltZS5hcGkucGFydHMuSUZvcm1Qcm9wZXJ0aWVzRWRpdGlvblBhcnQ7CmltcG9ydCBvcmcuZWNsaXBzZS5lbWYuZWVmLnJ1bnRpbWUuaW1wbC5ub3RpZnkuUHJvcGVydGllc0VkaXRpb25FdmVudDsKaW1wb3J0IG9yZy5lY2xpcHNlLmVtZi5lZWYucnVudGltZS5wYXJ0LmltcGwuU2VjdGlvblByb3BlcnRpZXNFZGl0aW5nUGFydDsKaW1wb3J0IG9yZy5lY2xpcHNlLmVtZi5lZWYucnVudGltZS51aS5wYXJ0cy5QYXJ0Q29tcG9zZXI7CmltcG9ydCBvcmcuZWNsaXBzZS5lbWYuZWVmLnJ1bnRpbWUudWkucGFydHMuc2VxdWVuY2UuQmluZGluZ0NvbXBvc2l0aW9uU2VxdWVuY2U7CmltcG9ydCBvcmcuZWNsaXBzZS5lbWYuZWVmLnJ1bnRpbWUudWkucGFydHMuc2VxdWVuY2UuQ29tcG9zaXRpb25TZXF1ZW5jZTsKaW1wb3J0IG9yZy5lY2xpcHNlLmVtZi5lZWYucnVudGltZS51aS5wYXJ0cy5zZXF1ZW5jZS5Db21wb3NpdGlvblN0ZXA7CmltcG9ydCBvcmcuZWNsaXBzZS5lbWYuZWVmLnJ1bnRpbWUudWkudXRpbHMuRWRpdGluZ1V0aWxzOwppbXBvcnQgb3JnLmVjbGlwc2UuZW1mLmVlZi5ydW50aW1lLnVpLndpZGdldHMuRm9ybVV0aWxzOwppbXBvcnQgb3JnLmVjbGlwc2UuZW1mLmVlZi5ydW50aW1lLnVpLndpZGdldHMuUmVmZXJlbmNlc1RhYmxlOwppbXBvcnQgb3JnLmVjbGlwc2UuZW1mLmVlZi5ydW50aW1lLnVpLndpZGdldHMuUmVmZXJlbmNlc1RhYmxlLlJlZmVyZW5jZXNUYWJsZUxpc3RlbmVyOwppbXBvcnQgb3JnLmVjbGlwc2UuZW1mLmVlZi5ydW50aW1lLnVpLndpZGdldHMucmVmZXJlbmNlc3RhYmxlLlJlZmVyZW5jZXNUYWJsZUNvbnRlbnRQcm92aWRlcjsKaW1wb3J0IG9yZy5lY2xpcHNlLmVtZi5lZWYucnVudGltZS51aS53aWRnZXRzLnJlZmVyZW5jZXN0YWJsZS5SZWZlcmVuY2VzVGFibGVTZXR0aW5nczsKaW1wb3J0IG9yZy5lY2xpcHNlLmpmYWNlLmRpYWxvZ3MuTWVzc2FnZURpYWxvZzsKaW1wb3J0IG9yZy5lY2xpcHNlLmpmYWNlLnZpZXdlcnMuVmlld2VyRmlsdGVyOwppbXBvcnQgb3JnLmVjbGlwc2Uuc3d0LlNXVDsKaW1wb3J0IG9yZy5lY2xpcHNlLnN3dC5ldmVudHMuRm9jdXNBZGFwdGVyOwppbXBvcnQgb3JnLmVjbGlwc2Uuc3d0LmV2ZW50cy5Gb2N1c0V2ZW50OwppbXBvcnQgb3JnLmVjbGlwc2Uuc3d0LmV2ZW50cy5LZXlBZGFwdGVyOwppbXBvcnQgb3JnLmVjbGlwc2Uuc3d0LmV2ZW50cy5LZXlFdmVudDsKaW1wb3J0IG9yZy5lY2xpcHNlLnN3dC5ldmVudHMuU2VsZWN0aW9uQWRhcHRlcjsKaW1wb3J0IG9yZy5lY2xpcHNlLnN3dC5ldmVudHMuU2VsZWN0aW9uRXZlbnQ7CmltcG9ydCBvcmcuZWNsaXBzZS5zd3QubGF5b3V0LkdyaWREYXRhOwppbXBvcnQgb3JnLmVjbGlwc2Uuc3d0LmxheW91dC5HcmlkTGF5b3V0OwppbXBvcnQgb3JnLmVjbGlwc2Uuc3d0LndpZGdldHMuQnV0dG9uOwppbXBvcnQgb3JnLmVjbGlwc2Uuc3d0LndpZGdldHMuQ29tcG9zaXRlOwppbXBvcnQgb3JnLmVjbGlwc2Uuc3d0LndpZGdldHMuU2hlbGw7CmltcG9ydCBvcmcuZWNsaXBzZS5zd3Qud2lkZ2V0cy5UZXh0OwppbXBvcnQgb3JnLmVjbGlwc2UudWkuZm9ybXMud2lkZ2V0cy5Gb3JtOwppbXBvcnQgb3JnLmVjbGlwc2UudWkuZm9ybXMud2lkZ2V0cy5Gb3JtVG9vbGtpdDsKaW1wb3J0IG9yZy5lY2xpcHNlLnVpLmZvcm1zLndpZGdldHMuU2Nyb2xsZWRGb3JtOwppbXBvcnQgb3JnLmVjbGlwc2UudWkuZm9ybXMud2lkZ2V0cy5TZWN0aW9uOwppbXBvcnQgb3JnLmVjbGlwc2Uub3BlbmNlcnQuZXZtLmV2aWRzcGVjLmV2aWRlbmNlLnBhcnRzLkFydGVmYWN0VmVyc2lvblByb3BlcnRpZXNFZGl0aW9uUGFydDsKaW1wb3J0IG9yZy5lY2xpcHNlLm9wZW5jZXJ0LmV2bS5ldmlkc3BlYy5ldmlkZW5jZS5wYXJ0cy5FdmlkZW5jZVZpZXdzUmVwb3NpdG9yeTsKaW1wb3J0IG9yZy5lY2xpcHNlLm9wZW5jZXJ0LmV2bS5ldmlkc3BlYy5ldmlkZW5jZS5wcm92aWRlcnMuRXZpZGVuY2VNZXNzYWdlczsKCi8vIEVuZCBvZiB1c2VyIGNvZGUKCi8qKgogKiAKICogCiAqLwpwdWJsaWMgY2xhc3MgQXJ0ZWZhY3RWZXJzaW9uUHJvcGVydGllc0VkaXRpb25QYXJ0Rm9ybSBleHRlbmRzIFNlY3Rpb25Qcm9wZXJ0aWVzRWRpdGluZ1BhcnQgaW1wbGVtZW50cyBJRm9ybVByb3BlcnRpZXNFZGl0aW9uUGFydCwgQXJ0ZWZhY3RWZXJzaW9uUHJvcGVydGllc0VkaXRpb25QYXJ0IHsKCglwcm90ZWN0ZWQgVGV4dCB2ZXJzaW9uSUQ7Cglwcm90ZWN0ZWQgVGV4dCBkYXRlOwoJcHJvdGVjdGVkIFRleHQgY2hhbmdlczsKCXByb3RlY3RlZCBCdXR0b24gaXNMYXN0VmVyc2lvbjsKCXByb3RlY3RlZCBCdXR0b24gaXNUZW1wbGF0ZTsKCXByb3RlY3RlZCBCdXR0b24gaXNDb25maWd1cmFibGU7Cglwcm90ZWN0ZWQgUmVmZXJlbmNlc1RhYmxlIHJlc291cmNlOwoJcHJvdGVjdGVkIExpc3Q8Vmlld2VyRmlsdGVyPiByZXNvdXJjZUJ1c2luZXNzRmlsdGVycyA9IG5ldyBBcnJheUxpc3Q8Vmlld2VyRmlsdGVyPigpOwoJcHJvdGVjdGVkIExpc3Q8Vmlld2VyRmlsdGVyPiByZXNvdXJjZUZpbHRlcnMgPSBuZXcgQXJyYXlMaXN0PFZpZXdlckZpbHRlcj4oKTsKCgoKCS8qKgoJICogRm9yIHtAbGluayBJU2VjdGlvbn0gdXNlIG9ubHkuCgkgKi8KCXB1YmxpYyBBcnRlZmFjdFZlcnNpb25Qcm9wZXJ0aWVzRWRpdGlvblBhcnRGb3JtKCkgeyBzdXBlcigpOyB9CgoJLyoqCgkgKiBEZWZhdWx0IGNvbnN0cnVjdG9yCgkgKiBAcGFyYW0gZWRpdGlvbkNvbXBvbmVudCB0aGUge0BsaW5rIElQcm9wZXJ0aWVzRWRpdGlvbkNvbXBvbmVudH0gdGhhdCBtYW5hZ2UgdGhpcyBwYXJ0CgkgKiAKCSAqLwoJcHVibGljIEFydGVmYWN0VmVyc2lvblByb3BlcnRpZXNFZGl0aW9uUGFydEZvcm0oSVByb3BlcnRpZXNFZGl0aW9uQ29tcG9uZW50IGVkaXRpb25Db21wb25lbnQpIHsKCQlzdXBlcihlZGl0aW9uQ29tcG9uZW50KTsKCX0KCgkvKioKCSAqIHtAaW5oZXJpdERvY30KCSAqIAoJICogQHNlZSBvcmcuZWNsaXBzZS5lbWYuZWVmLnJ1bnRpbWUuYXBpLnBhcnRzLklGb3JtUHJvcGVydGllc0VkaXRpb25QYXJ0IwoJICogIGNyZWF0ZUZpZ3VyZShvcmcuZWNsaXBzZS5zd3Qud2lkZ2V0cy5Db21wb3NpdGUsIG9yZy5lY2xpcHNlLnVpLmZvcm1zLndpZGdldHMuRm9ybVRvb2xraXQpCgkgKiAKCSAqLwoJcHVibGljIENvbXBvc2l0ZSBjcmVhdGVGaWd1cmUoZmluYWwgQ29tcG9zaXRlIHBhcmVudCwgZmluYWwgRm9ybVRvb2xraXQgd2lkZ2V0RmFjdG9yeSkgewoJCVNjcm9sbGVkRm9ybSBzY3JvbGxlZEZvcm0gPSB3aWRnZXRGYWN0b3J5LmNyZWF0ZVNjcm9sbGVkRm9ybShwYXJlbnQpOwoJCUZvcm0gZm9ybSA9IHNjcm9sbGVkRm9ybS5nZXRGb3JtKCk7CgkJdmlldyA9IGZvcm0uZ2V0Qm9keSgpOwoJCUdyaWRMYXlvdXQgbGF5b3V0ID0gbmV3IEdyaWRMYXlvdXQoKTsKCQlsYXlvdXQubnVtQ29sdW1ucyA9IDM7CgkJdmlldy5zZXRMYXlvdXQobGF5b3V0KTsKCQljcmVhdGVDb250cm9scyh3aWRnZXRGYWN0b3J5LCB2aWV3KTsKCQlyZXR1cm4gc2Nyb2xsZWRGb3JtOwoJfQoKCS8qKgoJICoge0Bpbmhlcml0RG9jfQoJICogCgkgKiBAc2VlIG9yZy5lY2xpcHNlLmVtZi5lZWYucnVudGltZS5hcGkucGFydHMuSUZvcm1Qcm9wZXJ0aWVzRWRpdGlvblBhcnQjCgkgKiAgY3JlYXRlQ29udHJvbHMob3JnLmVjbGlwc2UudWkuZm9ybXMud2lkZ2V0cy5Gb3JtVG9vbGtpdCwgb3JnLmVjbGlwc2Uuc3d0LndpZGdldHMuQ29tcG9zaXRlKQoJICogCgkgKi8KCXB1YmxpYyB2b2lkIGNyZWF0ZUNvbnRyb2xzKGZpbmFsIEZvcm1Ub29sa2l0IHdpZGdldEZhY3RvcnksIENvbXBvc2l0ZSB2aWV3KSB7CgkJQ29tcG9zaXRpb25TZXF1ZW5jZSBhcnRlZmFjdFZlcnNpb25TdGVwID0gbmV3IEJpbmRpbmdDb21wb3NpdGlvblNlcXVlbmNlKHByb3BlcnRpZXNFZGl0aW9uQ29tcG9uZW50KTsKCQlDb21wb3NpdGlvblN0ZXAgcHJvcGVydGllc1N0ZXAgPSBhcnRlZmFjdFZlcnNpb25TdGVwLmFkZFN0ZXAoRXZpZGVuY2VWaWV3c1JlcG9zaXRvcnkuQXJ0ZWZhY3RWZXJzaW9uLlByb3BlcnRpZXMuY2xhc3MpOwoJCXByb3BlcnRpZXNTdGVwLmFkZFN0ZXAoRXZpZGVuY2VWaWV3c1JlcG9zaXRvcnkuQXJ0ZWZhY3RWZXJzaW9uLlByb3BlcnRpZXMudmVyc2lvbklEKTsKCQlwcm9wZXJ0aWVzU3RlcC5hZGRTdGVwKEV2aWRlbmNlVmlld3NSZXBvc2l0b3J5LkFydGVmYWN0VmVyc2lvbi5Qcm9wZXJ0aWVzLmRhdGUpOwoJCXByb3BlcnRpZXNTdGVwLmFkZFN0ZXAoRXZpZGVuY2VWaWV3c1JlcG9zaXRvcnkuQXJ0ZWZhY3RWZXJzaW9uLlByb3BlcnRpZXMuY2hhbmdlcyk7CgkJcHJvcGVydGllc1N0ZXAuYWRkU3RlcChFdmlkZW5jZVZpZXdzUmVwb3NpdG9yeS5BcnRlZmFjdFZlcnNpb24uUHJvcGVydGllcy5pc0xhc3RWZXJzaW9uKTsKCQlwcm9wZXJ0aWVzU3RlcC5hZGRTdGVwKEV2aWRlbmNlVmlld3NSZXBvc2l0b3J5LkFydGVmYWN0VmVyc2lvbi5Qcm9wZXJ0aWVzLmlzVGVtcGxhdGUpOwoJCXByb3BlcnRpZXNTdGVwLmFkZFN0ZXAoRXZpZGVuY2VWaWV3c1JlcG9zaXRvcnkuQXJ0ZWZhY3RWZXJzaW9uLlByb3BlcnRpZXMuaXNDb25maWd1cmFibGUpOwoJCXByb3BlcnRpZXNTdGVwLmFkZFN0ZXAoRXZpZGVuY2VWaWV3c1JlcG9zaXRvcnkuQXJ0ZWZhY3RWZXJzaW9uLlByb3BlcnRpZXMucmVzb3VyY2UpOwoJCQoJCQoJCWNvbXBvc2VyID0gbmV3IFBhcnRDb21wb3NlcihhcnRlZmFjdFZlcnNpb25TdGVwKSB7CgoJCQlAT3ZlcnJpZGUKCQkJcHVibGljIENvbXBvc2l0ZSBhZGRUb1BhcnQoQ29tcG9zaXRlIHBhcmVudCwgT2JqZWN0IGtleSkgewoJCQkJaWYgKGtleSA9PSBFdmlkZW5jZVZpZXdzUmVwb3NpdG9yeS5BcnRlZmFjdFZlcnNpb24uUHJvcGVydGllcy5jbGFzcykgewoJCQkJCXJldHVybiBjcmVhdGVQcm9wZXJ0aWVzR3JvdXAod2lkZ2V0RmFjdG9yeSwgcGFyZW50KTsKCQkJCX0KCQkJCWlmIChrZXkgPT0gRXZpZGVuY2VWaWV3c1JlcG9zaXRvcnkuQXJ0ZWZhY3RWZXJzaW9uLlByb3BlcnRpZXMudmVyc2lvbklEKSB7CgkJCQkJcmV0dXJuIGNyZWF0ZVZlcnNpb25JRFRleHQod2lkZ2V0RmFjdG9yeSwgcGFyZW50KTsKCQkJCX0KCQkJCWlmIChrZXkgPT0gRXZpZGVuY2VWaWV3c1JlcG9zaXRvcnkuQXJ0ZWZhY3RWZXJzaW9uLlByb3BlcnRpZXMuZGF0ZSkgewoJCQkJCXJldHVybiBjcmVhdGVEYXRlVGV4dCh3aWRnZXRGYWN0b3J5LCBwYXJlbnQpOwoJCQkJfQoJCQkJaWYgKGtleSA9PSBFdmlkZW5jZVZpZXdzUmVwb3NpdG9yeS5BcnRlZmFjdFZlcnNpb24uUHJvcGVydGllcy5jaGFuZ2VzKSB7CgkJCQkJcmV0dXJuIGNyZWF0ZUNoYW5nZXNUZXh0KHdpZGdldEZhY3RvcnksIHBhcmVudCk7CgkJCQl9CgkJCQlpZiAoa2V5ID09IEV2aWRlbmNlVmlld3NSZXBvc2l0b3J5LkFydGVmYWN0VmVyc2lvbi5Qcm9wZXJ0aWVzLmlzTGFzdFZlcnNpb24pIHsKCQkJCQlyZXR1cm4gY3JlYXRlSXNMYXN0VmVyc2lvbkNoZWNrYm94KHdpZGdldEZhY3RvcnksIHBhcmVudCk7CgkJCQl9CgkJCQlpZiAoa2V5ID09IEV2aWRlbmNlVmlld3NSZXBvc2l0b3J5LkFydGVmYWN0VmVyc2lvbi5Qcm9wZXJ0aWVzLmlzVGVtcGxhdGUpIHsKCQkJCQlyZXR1cm4gY3JlYXRlSXNUZW1wbGF0ZUNoZWNrYm94KHdpZGdldEZhY3RvcnksIHBhcmVudCk7CgkJCQl9CgkJCQlpZiAoa2V5ID09IEV2aWRlbmNlVmlld3NSZXBvc2l0b3J5LkFydGVmYWN0VmVyc2lvbi5Qcm9wZXJ0aWVzLmlzQ29uZmlndXJhYmxlKSB7CgkJCQkJcmV0dXJuIGNyZWF0ZUlzQ29uZmlndXJhYmxlQ2hlY2tib3god2lkZ2V0RmFjdG9yeSwgcGFyZW50KTsKCQkJCX0KCQkJCWlmIChrZXkgPT0gRXZpZGVuY2VWaWV3c1JlcG9zaXRvcnkuQXJ0ZWZhY3RWZXJzaW9uLlByb3BlcnRpZXMucmVzb3VyY2UpIHsKCQkJCQlyZXR1cm4gY3JlYXRlUmVzb3VyY2VUYWJsZUNvbXBvc2l0aW9uKHdpZGdldEZhY3RvcnksIHBhcmVudCk7CgkJCQl9CgkJCQlyZXR1cm4gcGFyZW50OwoJCQl9CgkJfTsKCQljb21wb3Nlci5jb21wb3NlKHZpZXcpOwoJfQoJLyoqCgkgKiAKCSAqLwoJcHJvdGVjdGVkIENvbXBvc2l0ZSBjcmVhdGVQcm9wZXJ0aWVzR3JvdXAoRm9ybVRvb2xraXQgd2lkZ2V0RmFjdG9yeSwgZmluYWwgQ29tcG9zaXRlIHBhcmVudCkgewoJCVNlY3Rpb24gcHJvcGVydGllc1NlY3Rpb24gPSB3aWRnZXRGYWN0b3J5LmNyZWF0ZVNlY3Rpb24ocGFyZW50LCBTZWN0aW9uLlRJVExFX0JBUiB8IFNlY3Rpb24uVFdJU1RJRSB8IFNlY3Rpb24uRVhQQU5ERUQpOwoJCXByb3BlcnRpZXNTZWN0aW9uLnNldFRleHQoRXZpZGVuY2VNZXNzYWdlcy5BcnRlZmFjdFZlcnNpb25Qcm9wZXJ0aWVzRWRpdGlvblBhcnRfUHJvcGVydGllc0dyb3VwTGFiZWwpOwoJCUdyaWREYXRhIHByb3BlcnRpZXNTZWN0aW9uRGF0YSA9IG5ldyBHcmlkRGF0YShHcmlkRGF0YS5GSUxMX0hPUklaT05UQUwpOwoJCXByb3BlcnRpZXNTZWN0aW9uRGF0YS5ob3Jpem9udGFsU3BhbiA9IDM7CgkJcHJvcGVydGllc1NlY3Rpb24uc2V0TGF5b3V0RGF0YShwcm9wZXJ0aWVzU2VjdGlvbkRhdGEpOwoJCUNvbXBvc2l0ZSBwcm9wZXJ0aWVzR3JvdXAgPSB3aWRnZXRGYWN0b3J5LmNyZWF0ZUNvbXBvc2l0ZShwcm9wZXJ0aWVzU2VjdGlvbik7CgkJR3JpZExheW91dCBwcm9wZXJ0aWVzR3JvdXBMYXlvdXQgPSBuZXcgR3JpZExheW91dCgpOwoJCXByb3BlcnRpZXNHcm91cExheW91dC5udW1Db2x1bW5zID0gMzsKCQlwcm9wZXJ0aWVzR3JvdXAuc2V0TGF5b3V0KHByb3BlcnRpZXNHcm91cExheW91dCk7CgkJcHJvcGVydGllc1NlY3Rpb24uc2V0Q2xpZW50KHByb3BlcnRpZXNHcm91cCk7CgkJcmV0dXJuIHByb3BlcnRpZXNHcm91cDsKCX0KCgkKCXByb3RlY3RlZCBDb21wb3NpdGUgY3JlYXRlVmVyc2lvbklEVGV4dChGb3JtVG9vbGtpdCB3aWRnZXRGYWN0b3J5LCBDb21wb3NpdGUgcGFyZW50KSB7CgkJY3JlYXRlRGVzY3JpcHRpb24ocGFyZW50LCBFdmlkZW5jZVZpZXdzUmVwb3NpdG9yeS5BcnRlZmFjdFZlcnNpb24uUHJvcGVydGllcy52ZXJzaW9uSUQsIEV2aWRlbmNlTWVzc2FnZXMuQXJ0ZWZhY3RWZXJzaW9uUHJvcGVydGllc0VkaXRpb25QYXJ0X1ZlcnNpb25JRExhYmVsKTsKCQl2ZXJzaW9uSUQgPSB3aWRnZXRGYWN0b3J5LmNyZWF0ZVRleHQocGFyZW50LCAiIik7IC8vJE5PTi1OTFMtMSQKCQl2ZXJzaW9uSUQuc2V0RGF0YShGb3JtVG9vbGtpdC5LRVlfRFJBV19CT1JERVIsIEZvcm1Ub29sa2l0LlRFWFRfQk9SREVSKTsKCQl3aWRnZXRGYWN0b3J5LnBhaW50Qm9yZGVyc0ZvcihwYXJlbnQpOwoJCUdyaWREYXRhIHZlcnNpb25JRERhdGEgPSBuZXcgR3JpZERhdGEoR3JpZERhdGEuRklMTF9IT1JJWk9OVEFMKTsKCQl2ZXJzaW9uSUQuc2V0TGF5b3V0RGF0YSh2ZXJzaW9uSUREYXRhKTsKCQl2ZXJzaW9uSUQuYWRkRm9jdXNMaXN0ZW5lcihuZXcgRm9jdXNBZGFwdGVyKCkgewoJCQkvKioKCQkJICogQHNlZSBvcmcuZWNsaXBzZS5zd3QuZXZlbnRzLkZvY3VzQWRhcHRlciNmb2N1c0xvc3Qob3JnLmVjbGlwc2Uuc3d0LmV2ZW50cy5Gb2N1c0V2ZW50KQoJCQkgKiAKCQkJICovCgkJCUBPdmVycmlkZQoJCQlAU3VwcHJlc3NXYXJuaW5ncygic3ludGhldGljLWFjY2VzcyIpCgkJCXB1YmxpYyB2b2lkIGZvY3VzTG9zdChGb2N1c0V2ZW50IGUpIHsKCQkJCWlmIChwcm9wZXJ0aWVzRWRpdGlvbkNvbXBvbmVudCAhPSBudWxsKSB7CgkJCQkJcHJvcGVydGllc0VkaXRpb25Db21wb25lbnQuZmlyZVByb3BlcnRpZXNDaGFuZ2VkKG5ldyBQcm9wZXJ0aWVzRWRpdGlvbkV2ZW50KAoJCQkJCQkJQXJ0ZWZhY3RWZXJzaW9uUHJvcGVydGllc0VkaXRpb25QYXJ0Rm9ybS50aGlzLAoJCQkJCQkJRXZpZGVuY2VWaWV3c1JlcG9zaXRvcnkuQXJ0ZWZhY3RWZXJzaW9uLlByb3BlcnRpZXMudmVyc2lvbklELAoJCQkJCQkJUHJvcGVydGllc0VkaXRpb25FdmVudC5DT01NSVQsIFByb3BlcnRpZXNFZGl0aW9uRXZlbnQuU0VULCBudWxsLCB2ZXJzaW9uSUQuZ2V0VGV4dCgpKSk7CgkJCQkJcHJvcGVydGllc0VkaXRpb25Db21wb25lbnQKCQkJCQkJCS5maXJlUHJvcGVydGllc0NoYW5nZWQobmV3IFByb3BlcnRpZXNFZGl0aW9uRXZlbnQoCgkJCQkJCQkJCUFydGVmYWN0VmVyc2lvblByb3BlcnRpZXNFZGl0aW9uUGFydEZvcm0udGhpcywKCQkJCQkJCQkJRXZpZGVuY2VWaWV3c1JlcG9zaXRvcnkuQXJ0ZWZhY3RWZXJzaW9uLlByb3BlcnRpZXMudmVyc2lvbklELAoJCQkJCQkJCQlQcm9wZXJ0aWVzRWRpdGlvbkV2ZW50LkZPQ1VTX0NIQU5HRUQsIFByb3BlcnRpZXNFZGl0aW9uRXZlbnQuRk9DVVNfTE9TVCwKCQkJCQkJCQkJbnVsbCwgdmVyc2lvbklELmdldFRleHQoKSkpOwoJCQkJfQoJCQl9CgoJCQkvKioKCQkJICogQHNlZSBvcmcuZWNsaXBzZS5zd3QuZXZlbnRzLkZvY3VzQWRhcHRlciNmb2N1c0dhaW5lZChvcmcuZWNsaXBzZS5zd3QuZXZlbnRzLkZvY3VzRXZlbnQpCgkJCSAqLwoJCQlAT3ZlcnJpZGUKCQkJcHVibGljIHZvaWQgZm9jdXNHYWluZWQoRm9jdXNFdmVudCBlKSB7CgkJCQlpZiAocHJvcGVydGllc0VkaXRpb25Db21wb25lbnQgIT0gbnVsbCkgewoJCQkJCXByb3BlcnRpZXNFZGl0aW9uQ29tcG9uZW50CgkJCQkJCQkuZmlyZVByb3BlcnRpZXNDaGFuZ2VkKG5ldyBQcm9wZXJ0aWVzRWRpdGlvbkV2ZW50KAoJCQkJCQkJCQlBcnRlZmFjdFZlcnNpb25Qcm9wZXJ0aWVzRWRpdGlvblBhcnRGb3JtLnRoaXMsCgkJCQkJCQkJCW51bGwsCgkJCQkJCQkJCVByb3BlcnRpZXNFZGl0aW9uRXZlbnQuRk9DVVNfQ0hBTkdFRCwgUHJvcGVydGllc0VkaXRpb25FdmVudC5GT0NVU19HQUlORUQsCgkJCQkJCQkJCW51bGwsIG51bGwpKTsKCQkJCX0KCQkJfQoJCX0pOwoJCXZlcnNpb25JRC5hZGRLZXlMaXN0ZW5lcihuZXcgS2V5QWRhcHRlcigpIHsKCQkJLyoqCgkJCSAqIEBzZWUgb3JnLmVjbGlwc2Uuc3d0LmV2ZW50cy5LZXlBZGFwdGVyI2tleVByZXNzZWQob3JnLmVjbGlwc2Uuc3d0LmV2ZW50cy5LZXlFdmVudCkKCQkJICogCgkJCSAqLwoJCQlAT3ZlcnJpZGUKCQkJQFN1cHByZXNzV2FybmluZ3MoInN5bnRoZXRpYy1hY2Nlc3MiKQoJCQlwdWJsaWMgdm9pZCBrZXlQcmVzc2VkKEtleUV2ZW50IGUpIHsKCQkJCWlmIChlLmNoYXJhY3RlciA9PSBTV1QuQ1IpIHsKCQkJCQlpZiAocHJvcGVydGllc0VkaXRpb25Db21wb25lbnQgIT0gbnVsbCkKCQkJCQkJcHJvcGVydGllc0VkaXRpb25Db21wb25lbnQuZmlyZVByb3BlcnRpZXNDaGFuZ2VkKG5ldyBQcm9wZXJ0aWVzRWRpdGlvbkV2ZW50KEFydGVmYWN0VmVyc2lvblByb3BlcnRpZXNFZGl0aW9uUGFydEZvcm0udGhpcywgRXZpZGVuY2VWaWV3c1JlcG9zaXRvcnkuQXJ0ZWZhY3RWZXJzaW9uLlByb3BlcnRpZXMudmVyc2lvbklELCBQcm9wZXJ0aWVzRWRpdGlvbkV2ZW50LkNPTU1JVCwgUHJvcGVydGllc0VkaXRpb25FdmVudC5TRVQsIG51bGwsIHZlcnNpb25JRC5nZXRUZXh0KCkpKTsKCQkJCX0KCQkJfQoJCX0pOwoJCUVkaXRpbmdVdGlscy5zZXRJRCh2ZXJzaW9uSUQsIEV2aWRlbmNlVmlld3NSZXBvc2l0b3J5LkFydGVmYWN0VmVyc2lvbi5Qcm9wZXJ0aWVzLnZlcnNpb25JRCk7CgkJRWRpdGluZ1V0aWxzLnNldEVFRnR5cGUodmVyc2lvbklELCAiZWVmOjpUZXh0Iik7IC8vJE5PTi1OTFMtMSQKCQlGb3JtVXRpbHMuY3JlYXRlSGVscEJ1dHRvbih3aWRnZXRGYWN0b3J5LCBwYXJlbnQsIHByb3BlcnRpZXNFZGl0aW9uQ29tcG9uZW50LmdldEhlbHBDb250ZW50KEV2aWRlbmNlVmlld3NSZXBvc2l0b3J5LkFydGVmYWN0VmVyc2lvbi5Qcm9wZXJ0aWVzLnZlcnNpb25JRCwgRXZpZGVuY2VWaWV3c1JlcG9zaXRvcnkuRk9STV9LSU5EKSwgbnVsbCk7IC8vJE5PTi1OTFMtMSQKCQkvLyBTdGFydCBvZiB1c2VyIGNvZGUgZm9yIGNyZWF0ZVZlcnNpb25JRFRleHQKCgkJLy8gRW5kIG9mIHVzZXIgY29kZQoJCXJldHVybiBwYXJlbnQ7Cgl9CgoJCglwcm90ZWN0ZWQgQ29tcG9zaXRlIGNyZWF0ZURhdGVUZXh0KEZvcm1Ub29sa2l0IHdpZGdldEZhY3RvcnksIENvbXBvc2l0ZSBwYXJlbnQpIHsKCQljcmVhdGVEZXNjcmlwdGlvbihwYXJlbnQsIEV2aWRlbmNlVmlld3NSZXBvc2l0b3J5LkFydGVmYWN0VmVyc2lvbi5Qcm9wZXJ0aWVzLmRhdGUsIEV2aWRlbmNlTWVzc2FnZXMuQXJ0ZWZhY3RWZXJzaW9uUHJvcGVydGllc0VkaXRpb25QYXJ0X0RhdGVMYWJlbCk7CgkJZGF0ZSA9IHdpZGdldEZhY3RvcnkuY3JlYXRlVGV4dChwYXJlbnQsICIiKTsgLy8kTk9OLU5MUy0xJAoJCWRhdGUuc2V0RGF0YShGb3JtVG9vbGtpdC5LRVlfRFJBV19CT1JERVIsIEZvcm1Ub29sa2l0LlRFWFRfQk9SREVSKTsKCQl3aWRnZXRGYWN0b3J5LnBhaW50Qm9yZGVyc0ZvcihwYXJlbnQpOwoJCUdyaWREYXRhIGRhdGVEYXRhID0gbmV3IEdyaWREYXRhKEdyaWREYXRhLkZJTExfSE9SSVpPTlRBTCk7CgkJZGF0ZS5zZXRMYXlvdXREYXRhKGRhdGVEYXRhKTsKCQlkYXRlLmFkZEZvY3VzTGlzdGVuZXIobmV3IEZvY3VzQWRhcHRlcigpIHsKCQkJLyoqCgkJCSAqIEBzZWUgb3JnLmVjbGlwc2Uuc3d0LmV2ZW50cy5Gb2N1c0FkYXB0ZXIjZm9jdXNMb3N0KG9yZy5lY2xpcHNlLnN3dC5ldmVudHMuRm9jdXNFdmVudCkKCQkJICogCgkJCSAqLwoJCQlAT3ZlcnJpZGUKCQkJQFN1cHByZXNzV2FybmluZ3MoInN5bnRoZXRpYy1hY2Nlc3MiKQoJCQlwdWJsaWMgdm9pZCBmb2N1c0xvc3QoRm9jdXNFdmVudCBlKSB7CgkJCQlpZiAocHJvcGVydGllc0VkaXRpb25Db21wb25lbnQgIT0gbnVsbCkgewoJCQkJCXByb3BlcnRpZXNFZGl0aW9uQ29tcG9uZW50LmZpcmVQcm9wZXJ0aWVzQ2hhbmdlZChuZXcgUHJvcGVydGllc0VkaXRpb25FdmVudCgKCQkJCQkJCUFydGVmYWN0VmVyc2lvblByb3BlcnRpZXNFZGl0aW9uUGFydEZvcm0udGhpcywKCQkJCQkJCUV2aWRlbmNlVmlld3NSZXBvc2l0b3J5LkFydGVmYWN0VmVyc2lvbi5Qcm9wZXJ0aWVzLmRhdGUsCgkJCQkJCQlQcm9wZXJ0aWVzRWRpdGlvbkV2ZW50LkNPTU1JVCwgUHJvcGVydGllc0VkaXRpb25FdmVudC5TRVQsIG51bGwsIGRhdGUuZ2V0VGV4dCgpKSk7CgkJCQkJcHJvcGVydGllc0VkaXRpb25Db21wb25lbnQKCQkJCQkJCS5maXJlUHJvcGVydGllc0NoYW5nZWQobmV3IFByb3BlcnRpZXNFZGl0aW9uRXZlbnQoCgkJCQkJCQkJCUFydGVmYWN0VmVyc2lvblByb3BlcnRpZXNFZGl0aW9uUGFydEZvcm0udGhpcywKCQkJCQkJCQkJRXZpZGVuY2VWaWV3c1JlcG9zaXRvcnkuQXJ0ZWZhY3RWZXJzaW9uLlByb3BlcnRpZXMuZGF0ZSwKCQkJCQkJCQkJUHJvcGVydGllc0VkaXRpb25FdmVudC5GT0NVU19DSEFOR0VELCBQcm9wZXJ0aWVzRWRpdGlvbkV2ZW50LkZPQ1VTX0xPU1QsCgkJCQkJCQkJCW51bGwsIGRhdGUuZ2V0VGV4dCgpKSk7CgkJCQl9CgkJCX0KCgkJCS8qKgoJCQkgKiBAc2VlIG9yZy5lY2xpcHNlLnN3dC5ldmVudHMuRm9jdXNBZGFwdGVyI2ZvY3VzR2FpbmVkKG9yZy5lY2xpcHNlLnN3dC5ldmVudHMuRm9jdXNFdmVudCkKCQkJICovCgkJCUBPdmVycmlkZQoJCQlwdWJsaWMgdm9pZCBmb2N1c0dhaW5lZChGb2N1c0V2ZW50IGUpIHsKCQkJCWlmIChwcm9wZXJ0aWVzRWRpdGlvbkNvbXBvbmVudCAhPSBudWxsKSB7CgkJCQkJcHJvcGVydGllc0VkaXRpb25Db21wb25lbnQKCQkJCQkJCS5maXJlUHJvcGVydGllc0NoYW5nZWQobmV3IFByb3BlcnRpZXNFZGl0aW9uRXZlbnQoCgkJCQkJCQkJCUFydGVmYWN0VmVyc2lvblByb3BlcnRpZXNFZGl0aW9uUGFydEZvcm0udGhpcywKCQkJCQkJCQkJbnVsbCwKCQkJCQkJCQkJUHJvcGVydGllc0VkaXRpb25FdmVudC5GT0NVU19DSEFOR0VELCBQcm9wZXJ0aWVzRWRpdGlvbkV2ZW50LkZPQ1VTX0dBSU5FRCwKCQkJCQkJCQkJbnVsbCwgbnVsbCkpOwoJCQkJfQoJCQl9CgkJfSk7CgkJZGF0ZS5hZGRLZXlMaXN0ZW5lcihuZXcgS2V5QWRhcHRlcigpIHsKCQkJLyoqCgkJCSAqIEBzZWUgb3JnLmVjbGlwc2Uuc3d0LmV2ZW50cy5LZXlBZGFwdGVyI2tleVByZXNzZWQob3JnLmVjbGlwc2Uuc3d0LmV2ZW50cy5LZXlFdmVudCkKCQkJICogCgkJCSAqLwoJCQlAT3ZlcnJpZGUKCQkJQFN1cHByZXNzV2FybmluZ3MoInN5bnRoZXRpYy1hY2Nlc3MiKQoJCQlwdWJsaWMgdm9pZCBrZXlQcmVzc2VkKEtleUV2ZW50IGUpIHsKCQkJCWlmIChlLmNoYXJhY3RlciA9PSBTV1QuQ1IpIHsKCQkJCQlpZiAocHJvcGVydGllc0VkaXRpb25Db21wb25lbnQgIT0gbnVsbCkKCQkJCQkJcHJvcGVydGllc0VkaXRpb25Db21wb25lbnQuZmlyZVByb3BlcnRpZXNDaGFuZ2VkKG5ldyBQcm9wZXJ0aWVzRWRpdGlvbkV2ZW50KEFydGVmYWN0VmVyc2lvblByb3BlcnRpZXNFZGl0aW9uUGFydEZvcm0udGhpcywgRXZpZGVuY2VWaWV3c1JlcG9zaXRvcnkuQXJ0ZWZhY3RWZXJzaW9uLlByb3BlcnRpZXMuZGF0ZSwgUHJvcGVydGllc0VkaXRpb25FdmVudC5DT01NSVQsIFByb3BlcnRpZXNFZGl0aW9uRXZlbnQuU0VULCBudWxsLCBkYXRlLmdldFRleHQoKSkpOwoJCQkJfQoJCQl9CgkJfSk7CgkJRWRpdGluZ1V0aWxzLnNldElEKGRhdGUsIEV2aWRlbmNlVmlld3NSZXBvc2l0b3J5LkFydGVmYWN0VmVyc2lvbi5Qcm9wZXJ0aWVzLmRhdGUpOwoJCUVkaXRpbmdVdGlscy5zZXRFRUZ0eXBlKGRhdGUsICJlZWY6OlRleHQiKTsgLy8kTk9OLU5MUy0xJAoJCUZvcm1VdGlscy5jcmVhdGVIZWxwQnV0dG9uKHdpZGdldEZhY3RvcnksIHBhcmVudCwgcHJvcGVydGllc0VkaXRpb25Db21wb25lbnQuZ2V0SGVscENvbnRlbnQoRXZpZGVuY2VWaWV3c1JlcG9zaXRvcnkuQXJ0ZWZhY3RWZXJzaW9uLlByb3BlcnRpZXMuZGF0ZSwgRXZpZGVuY2VWaWV3c1JlcG9zaXRvcnkuRk9STV9LSU5EKSwgbnVsbCk7IC8vJE5PTi1OTFMtMSQKCQkvLyBTdGFydCBvZiB1c2VyIGNvZGUgZm9yIGNyZWF0ZURhdGVUZXh0CgoJCS8vIEVuZCBvZiB1c2VyIGNvZGUKCQlyZXR1cm4gcGFyZW50OwoJfQoKCQoJcHJvdGVjdGVkIENvbXBvc2l0ZSBjcmVhdGVDaGFuZ2VzVGV4dChGb3JtVG9vbGtpdCB3aWRnZXRGYWN0b3J5LCBDb21wb3NpdGUgcGFyZW50KSB7CgkJY3JlYXRlRGVzY3JpcHRpb24ocGFyZW50LCBFdmlkZW5jZVZpZXdzUmVwb3NpdG9yeS5BcnRlZmFjdFZlcnNpb24uUHJvcGVydGllcy5jaGFuZ2VzLCBFdmlkZW5jZU1lc3NhZ2VzLkFydGVmYWN0VmVyc2lvblByb3BlcnRpZXNFZGl0aW9uUGFydF9DaGFuZ2VzTGFiZWwpOwoJCWNoYW5nZXMgPSB3aWRnZXRGYWN0b3J5LmNyZWF0ZVRleHQocGFyZW50LCAiIik7IC8vJE5PTi1OTFMtMSQKCQljaGFuZ2VzLnNldERhdGEoRm9ybVRvb2xraXQuS0VZX0RSQVdfQk9SREVSLCBGb3JtVG9vbGtpdC5URVhUX0JPUkRFUik7CgkJd2lkZ2V0RmFjdG9yeS5wYWludEJvcmRlcnNGb3IocGFyZW50KTsKCQlHcmlkRGF0YSBjaGFuZ2VzRGF0YSA9IG5ldyBHcmlkRGF0YShHcmlkRGF0YS5GSUxMX0hPUklaT05UQUwpOwoJCWNoYW5nZXMuc2V0TGF5b3V0RGF0YShjaGFuZ2VzRGF0YSk7CgkJY2hhbmdlcy5hZGRGb2N1c0xpc3RlbmVyKG5ldyBGb2N1c0FkYXB0ZXIoKSB7CgkJCS8qKgoJCQkgKiBAc2VlIG9yZy5lY2xpcHNlLnN3dC5ldmVudHMuRm9jdXNBZGFwdGVyI2ZvY3VzTG9zdChvcmcuZWNsaXBzZS5zd3QuZXZlbnRzLkZvY3VzRXZlbnQpCgkJCSAqIAoJCQkgKi8KCQkJQE92ZXJyaWRlCgkJCUBTdXBwcmVzc1dhcm5pbmdzKCJzeW50aGV0aWMtYWNjZXNzIikKCQkJcHVibGljIHZvaWQgZm9jdXNMb3N0KEZvY3VzRXZlbnQgZSkgewoJCQkJaWYgKHByb3BlcnRpZXNFZGl0aW9uQ29tcG9uZW50ICE9IG51bGwpIHsKCQkJCQlwcm9wZXJ0aWVzRWRpdGlvbkNvbXBvbmVudC5maXJlUHJvcGVydGllc0NoYW5nZWQobmV3IFByb3BlcnRpZXNFZGl0aW9uRXZlbnQoCgkJCQkJCQlBcnRlZmFjdFZlcnNpb25Qcm9wZXJ0aWVzRWRpdGlvblBhcnRGb3JtLnRoaXMsCgkJCQkJCQlFdmlkZW5jZVZpZXdzUmVwb3NpdG9yeS5BcnRlZmFjdFZlcnNpb24uUHJvcGVydGllcy5jaGFuZ2VzLAoJCQkJCQkJUHJvcGVydGllc0VkaXRpb25FdmVudC5DT01NSVQsIFByb3BlcnRpZXNFZGl0aW9uRXZlbnQuU0VULCBudWxsLCBjaGFuZ2VzLmdldFRleHQoKSkpOwoJCQkJCXByb3BlcnRpZXNFZGl0aW9uQ29tcG9uZW50CgkJCQkJCQkuZmlyZVByb3BlcnRpZXNDaGFuZ2VkKG5ldyBQcm9wZXJ0aWVzRWRpdGlvbkV2ZW50KAoJCQkJCQkJCQlBcnRlZmFjdFZlcnNpb25Qcm9wZXJ0aWVzRWRpdGlvblBhcnRGb3JtLnRoaXMsCgkJCQkJCQkJCUV2aWRlbmNlVmlld3NSZXBvc2l0b3J5LkFydGVmYWN0VmVyc2lvbi5Qcm9wZXJ0aWVzLmNoYW5nZXMsCgkJCQkJCQkJCVByb3BlcnRpZXNFZGl0aW9uRXZlbnQuRk9DVVNfQ0hBTkdFRCwgUHJvcGVydGllc0VkaXRpb25FdmVudC5GT0NVU19MT1NULAoJCQkJCQkJCQludWxsLCBjaGFuZ2VzLmdldFRleHQoKSkpOwoJCQkJfQoJCQl9CgoJCQkvKioKCQkJICogQHNlZSBvcmcuZWNsaXBzZS5zd3QuZXZlbnRzLkZvY3VzQWRhcHRlciNmb2N1c0dhaW5lZChvcmcuZWNsaXBzZS5zd3QuZXZlbnRzLkZvY3VzRXZlbnQpCgkJCSAqLwoJCQlAT3ZlcnJpZGUKCQkJcHVibGljIHZvaWQgZm9jdXNHYWluZWQoRm9jdXNFdmVudCBlKSB7CgkJCQlpZiAocHJvcGVydGllc0VkaXRpb25Db21wb25lbnQgIT0gbnVsbCkgewoJCQkJCXByb3BlcnRpZXNFZGl0aW9uQ29tcG9uZW50CgkJCQkJCQkuZmlyZVByb3BlcnRpZXNDaGFuZ2VkKG5ldyBQcm9wZXJ0aWVzRWRpdGlvbkV2ZW50KAoJCQkJCQkJCQlBcnRlZmFjdFZlcnNpb25Qcm9wZXJ0aWVzRWRpdGlvblBhcnRGb3JtLnRoaXMsCgkJCQkJCQkJCW51bGwsCgkJCQkJCQkJCVByb3BlcnRpZXNFZGl0aW9uRXZlbnQuRk9DVVNfQ0hBTkdFRCwgUHJvcGVydGllc0VkaXRpb25FdmVudC5GT0NVU19HQUlORUQsCgkJCQkJCQkJCW51bGwsIG51bGwpKTsKCQkJCX0KCQkJfQoJCX0pOwoJCWNoYW5nZXMuYWRkS2V5TGlzdGVuZXIobmV3IEtleUFkYXB0ZXIoKSB7CgkJCS8qKgoJCQkgKiBAc2VlIG9yZy5lY2xpcHNlLnN3dC5ldmVudHMuS2V5QWRhcHRlciNrZXlQcmVzc2VkKG9yZy5lY2xpcHNlLnN3dC5ldmVudHMuS2V5RXZlbnQpCgkJCSAqIAoJCQkgKi8KCQkJQE92ZXJyaWRlCgkJCUBTdXBwcmVzc1dhcm5pbmdzKCJzeW50aGV0aWMtYWNjZXNzIikKCQkJcHVibGljIHZvaWQga2V5UHJlc3NlZChLZXlFdmVudCBlKSB7CgkJCQlpZiAoZS5jaGFyYWN0ZXIgPT0gU1dULkNSKSB7CgkJCQkJaWYgKHByb3BlcnRpZXNFZGl0aW9uQ29tcG9uZW50ICE9IG51bGwpCgkJCQkJCXByb3BlcnRpZXNFZGl0aW9uQ29tcG9uZW50LmZpcmVQcm9wZXJ0aWVzQ2hhbmdlZChuZXcgUHJvcGVydGllc0VkaXRpb25FdmVudChBcnRlZmFjdFZlcnNpb25Qcm9wZXJ0aWVzRWRpdGlvblBhcnRGb3JtLnRoaXMsIEV2aWRlbmNlVmlld3NSZXBvc2l0b3J5LkFydGVmYWN0VmVyc2lvbi5Qcm9wZXJ0aWVzLmNoYW5nZXMsIFByb3BlcnRpZXNFZGl0aW9uRXZlbnQuQ09NTUlULCBQcm9wZXJ0aWVzRWRpdGlvbkV2ZW50LlNFVCwgbnVsbCwgY2hhbmdlcy5nZXRUZXh0KCkpKTsKCQkJCX0KCQkJfQoJCX0pOwoJCUVkaXRpbmdVdGlscy5zZXRJRChjaGFuZ2VzLCBFdmlkZW5jZVZpZXdzUmVwb3NpdG9yeS5BcnRlZmFjdFZlcnNpb24uUHJvcGVydGllcy5jaGFuZ2VzKTsKCQlFZGl0aW5nVXRpbHMuc2V0RUVGdHlwZShjaGFuZ2VzLCAiZWVmOjpUZXh0Iik7IC8vJE5PTi1OTFMtMSQKCQlGb3JtVXRpbHMuY3JlYXRlSGVscEJ1dHRvbih3aWRnZXRGYWN0b3J5LCBwYXJlbnQsIHByb3BlcnRpZXNFZGl0aW9uQ29tcG9uZW50LmdldEhlbHBDb250ZW50KEV2aWRlbmNlVmlld3NSZXBvc2l0b3J5LkFydGVmYWN0VmVyc2lvbi5Qcm9wZXJ0aWVzLmNoYW5nZXMsIEV2aWRlbmNlVmlld3NSZXBvc2l0b3J5LkZPUk1fS0lORCksIG51bGwpOyAvLyROT04tTkxTLTEkCgkJLy8gU3RhcnQgb2YgdXNlciBjb2RlIGZvciBjcmVhdGVDaGFuZ2VzVGV4dAoKCQkvLyBFbmQgb2YgdXNlciBjb2RlCgkJcmV0dXJuIHBhcmVudDsKCX0KCgkKCXByb3RlY3RlZCBDb21wb3NpdGUgY3JlYXRlSXNMYXN0VmVyc2lvbkNoZWNrYm94KEZvcm1Ub29sa2l0IHdpZGdldEZhY3RvcnksIENvbXBvc2l0ZSBwYXJlbnQpIHsKCQlpc0xhc3RWZXJzaW9uID0gd2lkZ2V0RmFjdG9yeS5jcmVhdGVCdXR0b24ocGFyZW50LCBnZXREZXNjcmlwdGlvbihFdmlkZW5jZVZpZXdzUmVwb3NpdG9yeS5BcnRlZmFjdFZlcnNpb24uUHJvcGVydGllcy5pc0xhc3RWZXJzaW9uLCBFdmlkZW5jZU1lc3NhZ2VzLkFydGVmYWN0VmVyc2lvblByb3BlcnRpZXNFZGl0aW9uUGFydF9Jc0xhc3RWZXJzaW9uTGFiZWwpLCBTV1QuQ0hFQ0spOwoJCWlzTGFzdFZlcnNpb24uYWRkU2VsZWN0aW9uTGlzdGVuZXIobmV3IFNlbGVjdGlvbkFkYXB0ZXIoKSB7CgoJCQkvKioKCQkJICoge0Bpbmhlcml0RG9jfQoJCQkgKgoJCQkgKiBAc2VlIG9yZy5lY2xpcHNlLnN3dC5ldmVudHMuU2VsZWN0aW9uQWRhcHRlciN3aWRnZXRTZWxlY3RlZChvcmcuZWNsaXBzZS5zd3QuZXZlbnRzLlNlbGVjdGlvbkV2ZW50KQoJCQkgKiAJCgkJCSAqLwoJCQlwdWJsaWMgdm9pZCB3aWRnZXRTZWxlY3RlZChTZWxlY3Rpb25FdmVudCBlKSB7CgkJCQlpZiAocHJvcGVydGllc0VkaXRpb25Db21wb25lbnQgIT0gbnVsbCkKCQkJCQlwcm9wZXJ0aWVzRWRpdGlvbkNvbXBvbmVudC5maXJlUHJvcGVydGllc0NoYW5nZWQobmV3IFByb3BlcnRpZXNFZGl0aW9uRXZlbnQoQXJ0ZWZhY3RWZXJzaW9uUHJvcGVydGllc0VkaXRpb25QYXJ0Rm9ybS50aGlzLCBFdmlkZW5jZVZpZXdzUmVwb3NpdG9yeS5BcnRlZmFjdFZlcnNpb24uUHJvcGVydGllcy5pc0xhc3RWZXJzaW9uLCBQcm9wZXJ0aWVzRWRpdGlvbkV2ZW50LkNPTU1JVCwgUHJvcGVydGllc0VkaXRpb25FdmVudC5TRVQsIG51bGwsIG5ldyBCb29sZWFuKGlzTGFzdFZlcnNpb24uZ2V0U2VsZWN0aW9uKCkpKSk7CgkJCX0KCgkJfSk7CgkJR3JpZERhdGEgaXNMYXN0VmVyc2lvbkRhdGEgPSBuZXcgR3JpZERhdGEoR3JpZERhdGEuRklMTF9IT1JJWk9OVEFMKTsKCQlpc0xhc3RWZXJzaW9uRGF0YS5ob3Jpem9udGFsU3BhbiA9IDI7CgkJaXNMYXN0VmVyc2lvbi5zZXRMYXlvdXREYXRhKGlzTGFzdFZlcnNpb25EYXRhKTsKCQlFZGl0aW5nVXRpbHMuc2V0SUQoaXNMYXN0VmVyc2lvbiwgRXZpZGVuY2VWaWV3c1JlcG9zaXRvcnkuQXJ0ZWZhY3RWZXJzaW9uLlByb3BlcnRpZXMuaXNMYXN0VmVyc2lvbik7CgkJRWRpdGluZ1V0aWxzLnNldEVFRnR5cGUoaXNMYXN0VmVyc2lvbiwgImVlZjo6Q2hlY2tib3giKTsgLy8kTk9OLU5MUy0xJAoJCUZvcm1VdGlscy5jcmVhdGVIZWxwQnV0dG9uKHdpZGdldEZhY3RvcnksIHBhcmVudCwgcHJvcGVydGllc0VkaXRpb25Db21wb25lbnQuZ2V0SGVscENvbnRlbnQoRXZpZGVuY2VWaWV3c1JlcG9zaXRvcnkuQXJ0ZWZhY3RWZXJzaW9uLlByb3BlcnRpZXMuaXNMYXN0VmVyc2lvbiwgRXZpZGVuY2VWaWV3c1JlcG9zaXRvcnkuRk9STV9LSU5EKSwgbnVsbCk7IC8vJE5PTi1OTFMtMSQKCQkvLyBTdGFydCBvZiB1c2VyIGNvZGUgZm9yIGNyZWF0ZUlzTGFzdFZlcnNpb25DaGVja2JveAoKCQkvLyBFbmQgb2YgdXNlciBjb2RlCgkJcmV0dXJuIHBhcmVudDsKCX0KCgkKCXByb3RlY3RlZCBDb21wb3NpdGUgY3JlYXRlSXNUZW1wbGF0ZUNoZWNrYm94KEZvcm1Ub29sa2l0IHdpZGdldEZhY3RvcnksIENvbXBvc2l0ZSBwYXJlbnQpIHsKCQlpc1RlbXBsYXRlID0gd2lkZ2V0RmFjdG9yeS5jcmVhdGVCdXR0b24ocGFyZW50LCBnZXREZXNjcmlwdGlvbihFdmlkZW5jZVZpZXdzUmVwb3NpdG9yeS5BcnRlZmFjdFZlcnNpb24uUHJvcGVydGllcy5pc1RlbXBsYXRlLCBFdmlkZW5jZU1lc3NhZ2VzLkFydGVmYWN0VmVyc2lvblByb3BlcnRpZXNFZGl0aW9uUGFydF9Jc1RlbXBsYXRlTGFiZWwpLCBTV1QuQ0hFQ0spOwoJCWlzVGVtcGxhdGUuYWRkU2VsZWN0aW9uTGlzdGVuZXIobmV3IFNlbGVjdGlvbkFkYXB0ZXIoKSB7CgoJCQkvKioKCQkJICoge0Bpbmhlcml0RG9jfQoJCQkgKgoJCQkgKiBAc2VlIG9yZy5lY2xpcHNlLnN3dC5ldmVudHMuU2VsZWN0aW9uQWRhcHRlciN3aWRnZXRTZWxlY3RlZChvcmcuZWNsaXBzZS5zd3QuZXZlbnRzLlNlbGVjdGlvbkV2ZW50KQoJCQkgKiAJCgkJCSAqLwoJCQlwdWJsaWMgdm9pZCB3aWRnZXRTZWxlY3RlZChTZWxlY3Rpb25FdmVudCBlKSB7CgkJCQlpZiAocHJvcGVydGllc0VkaXRpb25Db21wb25lbnQgIT0gbnVsbCkKCQkJCQlwcm9wZXJ0aWVzRWRpdGlvbkNvbXBvbmVudC5maXJlUHJvcGVydGllc0NoYW5nZWQobmV3IFByb3BlcnRpZXNFZGl0aW9uRXZlbnQoQXJ0ZWZhY3RWZXJzaW9uUHJvcGVydGllc0VkaXRpb25QYXJ0Rm9ybS50aGlzLCBFdmlkZW5jZVZpZXdzUmVwb3NpdG9yeS5BcnRlZmFjdFZlcnNpb24uUHJvcGVydGllcy5pc1RlbXBsYXRlLCBQcm9wZXJ0aWVzRWRpdGlvbkV2ZW50LkNPTU1JVCwgUHJvcGVydGllc0VkaXRpb25FdmVudC5TRVQsIG51bGwsIG5ldyBCb29sZWFuKGlzVGVtcGxhdGUuZ2V0U2VsZWN0aW9uKCkpKSk7CgkJCX0KCgkJfSk7CgkJR3JpZERhdGEgaXNUZW1wbGF0ZURhdGEgPSBuZXcgR3JpZERhdGEoR3JpZERhdGEuRklMTF9IT1JJWk9OVEFMKTsKCQlpc1RlbXBsYXRlRGF0YS5ob3Jpem9udGFsU3BhbiA9IDI7CgkJaXNUZW1wbGF0ZS5zZXRMYXlvdXREYXRhKGlzVGVtcGxhdGVEYXRhKTsKCQlFZGl0aW5nVXRpbHMuc2V0SUQoaXNUZW1wbGF0ZSwgRXZpZGVuY2VWaWV3c1JlcG9zaXRvcnkuQXJ0ZWZhY3RWZXJzaW9uLlByb3BlcnRpZXMuaXNUZW1wbGF0ZSk7CgkJRWRpdGluZ1V0aWxzLnNldEVFRnR5cGUoaXNUZW1wbGF0ZSwgImVlZjo6Q2hlY2tib3giKTsgLy8kTk9OLU5MUy0xJAoJCUZvcm1VdGlscy5jcmVhdGVIZWxwQnV0dG9uKHdpZGdldEZhY3RvcnksIHBhcmVudCwgcHJvcGVydGllc0VkaXRpb25Db21wb25lbnQuZ2V0SGVscENvbnRlbnQoRXZpZGVuY2VWaWV3c1JlcG9zaXRvcnkuQXJ0ZWZhY3RWZXJzaW9uLlByb3BlcnRpZXMuaXNUZW1wbGF0ZSwgRXZpZGVuY2VWaWV3c1JlcG9zaXRvcnkuRk9STV9LSU5EKSwgbnVsbCk7IC8vJE5PTi1OTFMtMSQKCQkvLyBTdGFydCBvZiB1c2VyIGNvZGUgZm9yIGNyZWF0ZUlzVGVtcGxhdGVDaGVja2JveAoKCQkvLyBFbmQgb2YgdXNlciBjb2RlCgkJcmV0dXJuIHBhcmVudDsKCX0KCgkKCXByb3RlY3RlZCBDb21wb3NpdGUgY3JlYXRlSXNDb25maWd1cmFibGVDaGVja2JveChGb3JtVG9vbGtpdCB3aWRnZXRGYWN0b3J5LCBDb21wb3NpdGUgcGFyZW50KSB7CgkJaXNDb25maWd1cmFibGUgPSB3aWRnZXRGYWN0b3J5LmNyZWF0ZUJ1dHRvbihwYXJlbnQsIGdldERlc2NyaXB0aW9uKEV2aWRlbmNlVmlld3NSZXBvc2l0b3J5LkFydGVmYWN0VmVyc2lvbi5Qcm9wZXJ0aWVzLmlzQ29uZmlndXJhYmxlLCBFdmlkZW5jZU1lc3NhZ2VzLkFydGVmYWN0VmVyc2lvblByb3BlcnRpZXNFZGl0aW9uUGFydF9Jc0NvbmZpZ3VyYWJsZUxhYmVsKSwgU1dULkNIRUNLKTsKCQlpc0NvbmZpZ3VyYWJsZS5hZGRTZWxlY3Rpb25MaXN0ZW5lcihuZXcgU2VsZWN0aW9uQWRhcHRlcigpIHsKCgkJCS8qKgoJCQkgKiB7QGluaGVyaXREb2N9CgkJCSAqCgkJCSAqIEBzZWUgb3JnLmVjbGlwc2Uuc3d0LmV2ZW50cy5TZWxlY3Rpb25BZGFwdGVyI3dpZGdldFNlbGVjdGVkKG9yZy5lY2xpcHNlLnN3dC5ldmVudHMuU2VsZWN0aW9uRXZlbnQpCgkJCSAqIAkKCQkJICovCgkJCXB1YmxpYyB2b2lkIHdpZGdldFNlbGVjdGVkKFNlbGVjdGlvbkV2ZW50IGUpIHsKCQkJCWlmIChwcm9wZXJ0aWVzRWRpdGlvbkNvbXBvbmVudCAhPSBudWxsKQoJCQkJCXByb3BlcnRpZXNFZGl0aW9uQ29tcG9uZW50LmZpcmVQcm9wZXJ0aWVzQ2hhbmdlZChuZXcgUHJvcGVydGllc0VkaXRpb25FdmVudChBcnRlZmFjdFZlcnNpb25Qcm9wZXJ0aWVzRWRpdGlvblBhcnRGb3JtLnRoaXMsIEV2aWRlbmNlVmlld3NSZXBvc2l0b3J5LkFydGVmYWN0VmVyc2lvbi5Qcm9wZXJ0aWVzLmlzQ29uZmlndXJhYmxlLCBQcm9wZXJ0aWVzRWRpdGlvbkV2ZW50LkNPTU1JVCwgUHJvcGVydGllc0VkaXRpb25FdmVudC5TRVQsIG51bGwsIG5ldyBCb29sZWFuKGlzQ29uZmlndXJhYmxlLmdldFNlbGVjdGlvbigpKSkpOwoJCQl9CgoJCX0pOwoJCUdyaWREYXRhIGlzQ29uZmlndXJhYmxlRGF0YSA9IG5ldyBHcmlkRGF0YShHcmlkRGF0YS5GSUxMX0hPUklaT05UQUwpOwoJCWlzQ29uZmlndXJhYmxlRGF0YS5ob3Jpem9udGFsU3BhbiA9IDI7CgkJaXNDb25maWd1cmFibGUuc2V0TGF5b3V0RGF0YShpc0NvbmZpZ3VyYWJsZURhdGEpOwoJCUVkaXRpbmdVdGlscy5zZXRJRChpc0NvbmZpZ3VyYWJsZSwgRXZpZGVuY2VWaWV3c1JlcG9zaXRvcnkuQXJ0ZWZhY3RWZXJzaW9uLlByb3BlcnRpZXMuaXNDb25maWd1cmFibGUpOwoJCUVkaXRpbmdVdGlscy5zZXRFRUZ0eXBlKGlzQ29uZmlndXJhYmxlLCAiZWVmOjpDaGVja2JveCIpOyAvLyROT04tTkxTLTEkCgkJRm9ybVV0aWxzLmNyZWF0ZUhlbHBCdXR0b24od2lkZ2V0RmFjdG9yeSwgcGFyZW50LCBwcm9wZXJ0aWVzRWRpdGlvbkNvbXBvbmVudC5nZXRIZWxwQ29udGVudChFdmlkZW5jZVZpZXdzUmVwb3NpdG9yeS5BcnRlZmFjdFZlcnNpb24uUHJvcGVydGllcy5pc0NvbmZpZ3VyYWJsZSwgRXZpZGVuY2VWaWV3c1JlcG9zaXRvcnkuRk9STV9LSU5EKSwgbnVsbCk7IC8vJE5PTi1OTFMtMSQKCQkvLyBTdGFydCBvZiB1c2VyIGNvZGUgZm9yIGNyZWF0ZUlzQ29uZmlndXJhYmxlQ2hlY2tib3gKCgkJLy8gRW5kIG9mIHVzZXIgY29kZQoJCXJldHVybiBwYXJlbnQ7Cgl9CgoJLyoqCgkgKiBAcGFyYW0gY29udGFpbmVyCgkgKiAKCSAqLwoJcHJvdGVjdGVkIENvbXBvc2l0ZSBjcmVhdGVSZXNvdXJjZVRhYmxlQ29tcG9zaXRpb24oRm9ybVRvb2xraXQgd2lkZ2V0RmFjdG9yeSwgQ29tcG9zaXRlIHBhcmVudCkgewoJCXRoaXMucmVzb3VyY2UgPSBuZXcgUmVmZXJlbmNlc1RhYmxlKGdldERlc2NyaXB0aW9uKEV2aWRlbmNlVmlld3NSZXBvc2l0b3J5LkFydGVmYWN0VmVyc2lvbi5Qcm9wZXJ0aWVzLnJlc291cmNlLCBFdmlkZW5jZU1lc3NhZ2VzLkFydGVmYWN0VmVyc2lvblByb3BlcnRpZXNFZGl0aW9uUGFydF9SZXNvdXJjZUxhYmVsKSwgbmV3IFJlZmVyZW5jZXNUYWJsZUxpc3RlbmVyKCkgewoJCQlwdWJsaWMgdm9pZCBoYW5kbGVBZGQoKSB7CgkJCQlwcm9wZXJ0aWVzRWRpdGlvbkNvbXBvbmVudC5maXJlUHJvcGVydGllc0NoYW5nZWQobmV3IFByb3BlcnRpZXNFZGl0aW9uRXZlbnQoQXJ0ZWZhY3RWZXJzaW9uUHJvcGVydGllc0VkaXRpb25QYXJ0Rm9ybS50aGlzLCBFdmlkZW5jZVZpZXdzUmVwb3NpdG9yeS5BcnRlZmFjdFZlcnNpb24uUHJvcGVydGllcy5yZXNvdXJjZSwgUHJvcGVydGllc0VkaXRpb25FdmVudC5DT01NSVQsIFByb3BlcnRpZXNFZGl0aW9uRXZlbnQuQURELCBudWxsLCBudWxsKSk7CgkJCQlyZXNvdXJjZS5yZWZyZXNoKCk7CgkJCX0KCQkJcHVibGljIHZvaWQgaGFuZGxlRWRpdChFT2JqZWN0IGVsZW1lbnQpIHsKCQkJCXByb3BlcnRpZXNFZGl0aW9uQ29tcG9uZW50LmZpcmVQcm9wZXJ0aWVzQ2hhbmdlZChuZXcgUHJvcGVydGllc0VkaXRpb25FdmVudChBcnRlZmFjdFZlcnNpb25Qcm9wZXJ0aWVzRWRpdGlvblBhcnRGb3JtLnRoaXMsIEV2aWRlbmNlVmlld3NSZXBvc2l0b3J5LkFydGVmYWN0VmVyc2lvbi5Qcm9wZXJ0aWVzLnJlc291cmNlLCBQcm9wZXJ0aWVzRWRpdGlvbkV2ZW50LkNPTU1JVCwgUHJvcGVydGllc0VkaXRpb25FdmVudC5FRElULCBudWxsLCBlbGVtZW50KSk7CgkJCQlyZXNvdXJjZS5yZWZyZXNoKCk7CgkJCX0KCQkJcHVibGljIHZvaWQgaGFuZGxlTW92ZShFT2JqZWN0IGVsZW1lbnQsIGludCBvbGRJbmRleCwgaW50IG5ld0luZGV4KSB7CgkJCQlwcm9wZXJ0aWVzRWRpdGlvbkNvbXBvbmVudC5maXJlUHJvcGVydGllc0NoYW5nZWQobmV3IFByb3BlcnRpZXNFZGl0aW9uRXZlbnQoQXJ0ZWZhY3RWZXJzaW9uUHJvcGVydGllc0VkaXRpb25QYXJ0Rm9ybS50aGlzLCBFdmlkZW5jZVZpZXdzUmVwb3NpdG9yeS5BcnRlZmFjdFZlcnNpb24uUHJvcGVydGllcy5yZXNvdXJjZSwgUHJvcGVydGllc0VkaXRpb25FdmVudC5DT01NSVQsIFByb3BlcnRpZXNFZGl0aW9uRXZlbnQuTU9WRSwgZWxlbWVudCwgbmV3SW5kZXgpKTsKCQkJCXJlc291cmNlLnJlZnJlc2goKTsKCQkJfQoJCQlwdWJsaWMgdm9pZCBoYW5kbGVSZW1vdmUoRU9iamVjdCBlbGVtZW50KSB7CgkJCQlwcm9wZXJ0aWVzRWRpdGlvbkNvbXBvbmVudC5maXJlUHJvcGVydGllc0NoYW5nZWQobmV3IFByb3BlcnRpZXNFZGl0aW9uRXZlbnQoQXJ0ZWZhY3RWZXJzaW9uUHJvcGVydGllc0VkaXRpb25QYXJ0Rm9ybS50aGlzLCBFdmlkZW5jZVZpZXdzUmVwb3NpdG9yeS5BcnRlZmFjdFZlcnNpb24uUHJvcGVydGllcy5yZXNvdXJjZSwgUHJvcGVydGllc0VkaXRpb25FdmVudC5DT01NSVQsIFByb3BlcnRpZXNFZGl0aW9uRXZlbnQuUkVNT1ZFLCBudWxsLCBlbGVtZW50KSk7CgkJCQlyZXNvdXJjZS5yZWZyZXNoKCk7CgkJCX0KCQkJcHVibGljIHZvaWQgbmF2aWdhdGVUbyhFT2JqZWN0IGVsZW1lbnQpIHsgfQoJCX0pOwoJCWZvciAoVmlld2VyRmlsdGVyIGZpbHRlciA6IHRoaXMucmVzb3VyY2VGaWx0ZXJzKSB7CgkJCXRoaXMucmVzb3VyY2UuYWRkRmlsdGVyKGZpbHRlcik7CgkJfQoJCXRoaXMucmVzb3VyY2Uuc2V0SGVscFRleHQocHJvcGVydGllc0VkaXRpb25Db21wb25lbnQuZ2V0SGVscENvbnRlbnQoRXZpZGVuY2VWaWV3c1JlcG9zaXRvcnkuQXJ0ZWZhY3RWZXJzaW9uLlByb3BlcnRpZXMucmVzb3VyY2UsIEV2aWRlbmNlVmlld3NSZXBvc2l0b3J5LkZPUk1fS0lORCkpOwoJCXRoaXMucmVzb3VyY2UuY3JlYXRlQ29udHJvbHMocGFyZW50LCB3aWRnZXRGYWN0b3J5KTsKCQl0aGlzLnJlc291cmNlLmFkZFNlbGVjdGlvbkxpc3RlbmVyKG5ldyBTZWxlY3Rpb25BZGFwdGVyKCkgewoJCQkKCQkJcHVibGljIHZvaWQgd2lkZ2V0U2VsZWN0ZWQoU2VsZWN0aW9uRXZlbnQgZSkgewoJCQkJaWYgKGUuaXRlbSAhPSBudWxsICYmIGUuaXRlbS5nZXREYXRhKCkgaW5zdGFuY2VvZiBFT2JqZWN0KSB7CgkJCQkJcHJvcGVydGllc0VkaXRpb25Db21wb25lbnQuZmlyZVByb3BlcnRpZXNDaGFuZ2VkKG5ldyBQcm9wZXJ0aWVzRWRpdGlvbkV2ZW50KEFydGVmYWN0VmVyc2lvblByb3BlcnRpZXNFZGl0aW9uUGFydEZvcm0udGhpcywgRXZpZGVuY2VWaWV3c1JlcG9zaXRvcnkuQXJ0ZWZhY3RWZXJzaW9uLlByb3BlcnRpZXMucmVzb3VyY2UsIFByb3BlcnRpZXNFZGl0aW9uRXZlbnQuQ0hBTkdFLCBQcm9wZXJ0aWVzRWRpdGlvbkV2ZW50LlNFTEVDVElPTl9DSEFOR0VELCBudWxsLCBlLml0ZW0uZ2V0RGF0YSgpKSk7CgkJCQl9CgkJCX0KCQkJCgkJfSk7CgkJR3JpZERhdGEgcmVzb3VyY2VEYXRhID0gbmV3IEdyaWREYXRhKEdyaWREYXRhLkZJTExfSE9SSVpPTlRBTCk7CgkJcmVzb3VyY2VEYXRhLmhvcml6b250YWxTcGFuID0gMzsKCQl0aGlzLnJlc291cmNlLnNldExheW91dERhdGEocmVzb3VyY2VEYXRhKTsKCQl0aGlzLnJlc291cmNlLnNldExvd2VyQm91bmQoMCk7CgkJdGhpcy5yZXNvdXJjZS5zZXRVcHBlckJvdW5kKC0xKTsKCQlyZXNvdXJjZS5zZXRJRChFdmlkZW5jZVZpZXdzUmVwb3NpdG9yeS5BcnRlZmFjdFZlcnNpb24uUHJvcGVydGllcy5yZXNvdXJjZSk7CgkJcmVzb3VyY2Uuc2V0RUVGVHlwZSgiZWVmOjpBZHZhbmNlZFRhYmxlQ29tcG9zaXRpb24iKTsgLy8kTk9OLU5MUy0xJAoJCS8vIFN0YXJ0IG9mIHVzZXIgY29kZSBmb3IgY3JlYXRlUmVzb3VyY2VUYWJsZUNvbXBvc2l0aW9uCgoJCS8vIEVuZCBvZiB1c2VyIGNvZGUKCQlyZXR1cm4gcGFyZW50OwoJfQoKCgkvKioKCSAqIHtAaW5oZXJpdERvY30KCSAqIAoJICogQHNlZSBvcmcuZWNsaXBzZS5lbWYuZWVmLnJ1bnRpbWUuYXBpLm5vdGlmeS5JUHJvcGVydGllc0VkaXRpb25MaXN0ZW5lciNmaXJlUHJvcGVydGllc0NoYW5nZWQob3JnLmVjbGlwc2UuZW1mLmVlZi5ydW50aW1lLmFwaS5ub3RpZnkuSVByb3BlcnRpZXNFZGl0aW9uRXZlbnQpCgkgKiAKCSAqLwoJcHVibGljIHZvaWQgZmlyZVByb3BlcnRpZXNDaGFuZ2VkKElQcm9wZXJ0aWVzRWRpdGlvbkV2ZW50IGV2ZW50KSB7CgkJLy8gU3RhcnQgb2YgdXNlciBjb2RlIGZvciB0YWIgc3luY2hyb25pemF0aW9uCgkJU2hlbGwgdGhpc1M9IHRoaXMuY29udGFpbmVyLmdldFNoZWxsKCk7CgkJTWVzc2FnZURpYWxvZy5vcGVuSW5mb3JtYXRpb24odGhpc1MsICJDb25maXJtIiwgIkFydGVmYWN0IENoYW5nZWQiKTsKCQkvLyBFbmQgb2YgdXNlciBjb2RlCgl9CgoJLyoqCgkgKiB7QGluaGVyaXREb2N9CgkgKiAKCSAqIEBzZWUgb3JnLmVjbGlwc2Uub3BlbmNlcnQuZXZtLmV2aWRzcGVjLmV2aWRlbmNlLnBhcnRzLkFydGVmYWN0VmVyc2lvblByb3BlcnRpZXNFZGl0aW9uUGFydCNnZXRWZXJzaW9uSUQoKQoJICogCgkgKi8KCXB1YmxpYyBTdHJpbmcgZ2V0VmVyc2lvbklEKCkgewoJCXJldHVybiB2ZXJzaW9uSUQuZ2V0VGV4dCgpOwoJfQoKCS8qKgoJICoge0Bpbmhlcml0RG9jfQoJICogCgkgKiBAc2VlIG9yZy5lY2xpcHNlLm9wZW5jZXJ0LmV2bS5ldmlkc3BlYy5ldmlkZW5jZS5wYXJ0cy5BcnRlZmFjdFZlcnNpb25Qcm9wZXJ0aWVzRWRpdGlvblBhcnQjc2V0VmVyc2lvbklEKFN0cmluZyBuZXdWYWx1ZSkKCSAqIAoJICovCglwdWJsaWMgdm9pZCBzZXRWZXJzaW9uSUQoU3RyaW5nIG5ld1ZhbHVlKSB7CgkJaWYgKG5ld1ZhbHVlICE9IG51bGwpIHsKCQkJdmVyc2lvbklELnNldFRleHQobmV3VmFsdWUpOwoJCX0gZWxzZSB7CgkJCXZlcnNpb25JRC5zZXRUZXh0KCIiKTsgLy8kTk9OLU5MUy0xJAoJCX0KCQlib29sZWFuIGVlZkVsZW1lbnRFZGl0b3JSZWFkT25seVN0YXRlID0gaXNSZWFkT25seShFdmlkZW5jZVZpZXdzUmVwb3NpdG9yeS5BcnRlZmFjdFZlcnNpb24uUHJvcGVydGllcy52ZXJzaW9uSUQpOwoJCWlmIChlZWZFbGVtZW50RWRpdG9yUmVhZE9ubHlTdGF0ZSAmJiB2ZXJzaW9uSUQuaXNFbmFibGVkKCkpIHsKCQkJdmVyc2lvbklELnNldEVuYWJsZWQoZmFsc2UpOwoJCQl2ZXJzaW9uSUQuc2V0VG9vbFRpcFRleHQoRXZpZGVuY2VNZXNzYWdlcy5BcnRlZmFjdFZlcnNpb25fUmVhZE9ubHkpOwoJCX0gZWxzZSBpZiAoIWVlZkVsZW1lbnRFZGl0b3JSZWFkT25seVN0YXRlICYmICF2ZXJzaW9uSUQuaXNFbmFibGVkKCkpIHsKCQkJdmVyc2lvbklELnNldEVuYWJsZWQodHJ1ZSk7CgkJfQkKCQkKCX0KCgkvKioKCSAqIHtAaW5oZXJpdERvY30KCSAqIAoJICogQHNlZSBvcmcuZWNsaXBzZS5vcGVuY2VydC5ldm0uZXZpZHNwZWMuZXZpZGVuY2UucGFydHMuQXJ0ZWZhY3RWZXJzaW9uUHJvcGVydGllc0VkaXRpb25QYXJ0I2dldERhdGUoKQoJICogCgkgKi8KCXB1YmxpYyBTdHJpbmcgZ2V0RGF0ZSgpIHsKCQlyZXR1cm4gZGF0ZS5nZXRUZXh0KCk7Cgl9CgoJLyoqCgkgKiB7QGluaGVyaXREb2N9CgkgKiAKCSAqIEBzZWUgb3JnLmVjbGlwc2Uub3BlbmNlcnQuZXZtLmV2aWRzcGVjLmV2aWRlbmNlLnBhcnRzLkFydGVmYWN0VmVyc2lvblByb3BlcnRpZXNFZGl0aW9uUGFydCNzZXREYXRlKFN0cmluZyBuZXdWYWx1ZSkKCSAqIAoJICovCglwdWJsaWMgdm9pZCBzZXREYXRlKFN0cmluZyBuZXdWYWx1ZSkgewoJCWlmIChuZXdWYWx1ZSAhPSBudWxsKSB7CgkJCWRhdGUuc2V0VGV4dChuZXdWYWx1ZSk7CgkJfSBlbHNlIHsKCQkJZGF0ZS5zZXRUZXh0KCIiKTsgLy8kTk9OLU5MUy0xJAoJCX0KCQlib29sZWFuIGVlZkVsZW1lbnRFZGl0b3JSZWFkT25seVN0YXRlID0gaXNSZWFkT25seShFdmlkZW5jZVZpZXdzUmVwb3NpdG9yeS5BcnRlZmFjdFZlcnNpb24uUHJvcGVydGllcy5kYXRlKTsKCQlpZiAoZWVmRWxlbWVudEVkaXRvclJlYWRPbmx5U3RhdGUgJiYgZGF0ZS5pc0VuYWJsZWQoKSkgewoJCQlkYXRlLnNldEVuYWJsZWQoZmFsc2UpOwoJCQlkYXRlLnNldFRvb2xUaXBUZXh0KEV2aWRlbmNlTWVzc2FnZXMuQXJ0ZWZhY3RWZXJzaW9uX1JlYWRPbmx5KTsKCQl9IGVsc2UgaWYgKCFlZWZFbGVtZW50RWRpdG9yUmVhZE9ubHlTdGF0ZSAmJiAhZGF0ZS5pc0VuYWJsZWQoKSkgewoJCQlkYXRlLnNldEVuYWJsZWQodHJ1ZSk7CgkJfQkKCQkKCX0KCgkvKioKCSAqIHtAaW5oZXJpdERvY30KCSAqIAoJICogQHNlZSBvcmcuZWNsaXBzZS5vcGVuY2VydC5ldm0uZXZpZHNwZWMuZXZpZGVuY2UucGFydHMuQXJ0ZWZhY3RWZXJzaW9uUHJvcGVydGllc0VkaXRpb25QYXJ0I2dldENoYW5nZXMoKQoJICogCgkgKi8KCXB1YmxpYyBTdHJpbmcgZ2V0Q2hhbmdlcygpIHsKCQlyZXR1cm4gY2hhbmdlcy5nZXRUZXh0KCk7Cgl9CgoJLyoqCgkgKiB7QGluaGVyaXREb2N9CgkgKiAKCSAqIEBzZWUgb3JnLmVjbGlwc2Uub3BlbmNlcnQuZXZtLmV2aWRzcGVjLmV2aWRlbmNlLnBhcnRzLkFydGVmYWN0VmVyc2lvblByb3BlcnRpZXNFZGl0aW9uUGFydCNzZXRDaGFuZ2VzKFN0cmluZyBuZXdWYWx1ZSkKCSAqIAoJICovCglwdWJsaWMgdm9pZCBzZXRDaGFuZ2VzKFN0cmluZyBuZXdWYWx1ZSkgewoJCWlmIChuZXdWYWx1ZSAhPSBudWxsKSB7CgkJCWNoYW5nZXMuc2V0VGV4dChuZXdWYWx1ZSk7CgkJfSBlbHNlIHsKCQkJY2hhbmdlcy5zZXRUZXh0KCIiKTsgLy8kTk9OLU5MUy0xJAoJCX0KCQlib29sZWFuIGVlZkVsZW1lbnRFZGl0b3JSZWFkT25seVN0YXRlID0gaXNSZWFkT25seShFdmlkZW5jZVZpZXdzUmVwb3NpdG9yeS5BcnRlZmFjdFZlcnNpb24uUHJvcGVydGllcy5jaGFuZ2VzKTsKCQlpZiAoZWVmRWxlbWVudEVkaXRvclJlYWRPbmx5U3RhdGUgJiYgY2hhbmdlcy5pc0VuYWJsZWQoKSkgewoJCQljaGFuZ2VzLnNldEVuYWJsZWQoZmFsc2UpOwoJCQljaGFuZ2VzLnNldFRvb2xUaXBUZXh0KEV2aWRlbmNlTWVzc2FnZXMuQXJ0ZWZhY3RWZXJzaW9uX1JlYWRPbmx5KTsKCQl9IGVsc2UgaWYgKCFlZWZFbGVtZW50RWRpdG9yUmVhZE9ubHlTdGF0ZSAmJiAhY2hhbmdlcy5pc0VuYWJsZWQoKSkgewoJCQljaGFuZ2VzLnNldEVuYWJsZWQodHJ1ZSk7CgkJfQkKCQkKCX0KCgkvKioKCSAqIHtAaW5oZXJpdERvY30KCSAqIAoJICogQHNlZSBvcmcuZWNsaXBzZS5vcGVuY2VydC5ldm0uZXZpZHNwZWMuZXZpZGVuY2UucGFydHMuQXJ0ZWZhY3RWZXJzaW9uUHJvcGVydGllc0VkaXRpb25QYXJ0I2dldElzTGFzdFZlcnNpb24oKQoJICogCgkgKi8KCXB1YmxpYyBCb29sZWFuIGdldElzTGFzdFZlcnNpb24oKSB7CgkJcmV0dXJuIEJvb2xlYW4udmFsdWVPZihpc0xhc3RWZXJzaW9uLmdldFNlbGVjdGlvbigpKTsKCX0KCgkvKioKCSAqIHtAaW5oZXJpdERvY30KCSAqIAoJICogQHNlZSBvcmcuZWNsaXBzZS5vcGVuY2VydC5ldm0uZXZpZHNwZWMuZXZpZGVuY2UucGFydHMuQXJ0ZWZhY3RWZXJzaW9uUHJvcGVydGllc0VkaXRpb25QYXJ0I3NldElzTGFzdFZlcnNpb24oQm9vbGVhbiBuZXdWYWx1ZSkKCSAqIAoJICovCglwdWJsaWMgdm9pZCBzZXRJc0xhc3RWZXJzaW9uKEJvb2xlYW4gbmV3VmFsdWUpIHsKCQlpZiAobmV3VmFsdWUgIT0gbnVsbCkgewoJCQlpc0xhc3RWZXJzaW9uLnNldFNlbGVjdGlvbihuZXdWYWx1ZS5ib29sZWFuVmFsdWUoKSk7CgkJfSBlbHNlIHsKCQkJaXNMYXN0VmVyc2lvbi5zZXRTZWxlY3Rpb24oZmFsc2UpOwoJCX0KCQlib29sZWFuIGVlZkVsZW1lbnRFZGl0b3JSZWFkT25seVN0YXRlID0gaXNSZWFkT25seShFdmlkZW5jZVZpZXdzUmVwb3NpdG9yeS5BcnRlZmFjdFZlcnNpb24uUHJvcGVydGllcy5pc0xhc3RWZXJzaW9uKTsKCQlpZiAoZWVmRWxlbWVudEVkaXRvclJlYWRPbmx5U3RhdGUgJiYgaXNMYXN0VmVyc2lvbi5pc0VuYWJsZWQoKSkgewoJCQlpc0xhc3RWZXJzaW9uLnNldEVuYWJsZWQoZmFsc2UpOwoJCQlpc0xhc3RWZXJzaW9uLnNldFRvb2xUaXBUZXh0KEV2aWRlbmNlTWVzc2FnZXMuQXJ0ZWZhY3RWZXJzaW9uX1JlYWRPbmx5KTsKCQl9IGVsc2UgaWYgKCFlZWZFbGVtZW50RWRpdG9yUmVhZE9ubHlTdGF0ZSAmJiAhaXNMYXN0VmVyc2lvbi5pc0VuYWJsZWQoKSkgewoJCQlpc0xhc3RWZXJzaW9uLnNldEVuYWJsZWQodHJ1ZSk7CgkJfQkKCQkKCX0KCgkvKioKCSAqIHtAaW5oZXJpdERvY30KCSAqIAoJICogQHNlZSBvcmcuZWNsaXBzZS5vcGVuY2VydC5ldm0uZXZpZHNwZWMuZXZpZGVuY2UucGFydHMuQXJ0ZWZhY3RWZXJzaW9uUHJvcGVydGllc0VkaXRpb25QYXJ0I2dldElzVGVtcGxhdGUoKQoJICogCgkgKi8KCXB1YmxpYyBCb29sZWFuIGdldElzVGVtcGxhdGUoKSB7CgkJcmV0dXJuIEJvb2xlYW4udmFsdWVPZihpc1RlbXBsYXRlLmdldFNlbGVjdGlvbigpKTsKCX0KCgkvKioKCSAqIHtAaW5oZXJpdERvY30KCSAqIAoJICogQHNlZSBvcmcuZWNsaXBzZS5vcGVuY2VydC5ldm0uZXZpZHNwZWMuZXZpZGVuY2UucGFydHMuQXJ0ZWZhY3RWZXJzaW9uUHJvcGVydGllc0VkaXRpb25QYXJ0I3NldElzVGVtcGxhdGUoQm9vbGVhbiBuZXdWYWx1ZSkKCSAqIAoJICovCglwdWJsaWMgdm9pZCBzZXRJc1RlbXBsYXRlKEJvb2xlYW4gbmV3VmFsdWUpIHsKCQlpZiAobmV3VmFsdWUgIT0gbnVsbCkgewoJCQlpc1RlbXBsYXRlLnNldFNlbGVjdGlvbihuZXdWYWx1ZS5ib29sZWFuVmFsdWUoKSk7CgkJfSBlbHNlIHsKCQkJaXNUZW1wbGF0ZS5zZXRTZWxlY3Rpb24oZmFsc2UpOwoJCX0KCQlib29sZWFuIGVlZkVsZW1lbnRFZGl0b3JSZWFkT25seVN0YXRlID0gaXNSZWFkT25seShFdmlkZW5jZVZpZXdzUmVwb3NpdG9yeS5BcnRlZmFjdFZlcnNpb24uUHJvcGVydGllcy5pc1RlbXBsYXRlKTsKCQlpZiAoZWVmRWxlbWVudEVkaXRvclJlYWRPbmx5U3RhdGUgJiYgaXNUZW1wbGF0ZS5pc0VuYWJsZWQoKSkgewoJCQlpc1RlbXBsYXRlLnNldEVuYWJsZWQoZmFsc2UpOwoJCQlpc1RlbXBsYXRlLnNldFRvb2xUaXBUZXh0KEV2aWRlbmNlTWVzc2FnZXMuQXJ0ZWZhY3RWZXJzaW9uX1JlYWRPbmx5KTsKCQl9IGVsc2UgaWYgKCFlZWZFbGVtZW50RWRpdG9yUmVhZE9ubHlTdGF0ZSAmJiAhaXNUZW1wbGF0ZS5pc0VuYWJsZWQoKSkgewoJCQlpc1RlbXBsYXRlLnNldEVuYWJsZWQodHJ1ZSk7CgkJfQkKCQkKCX0KCgkvKioKCSAqIHtAaW5oZXJpdERvY30KCSAqIAoJICogQHNlZSBvcmcuZWNsaXBzZS5vcGVuY2VydC5ldm0uZXZpZHNwZWMuZXZpZGVuY2UucGFydHMuQXJ0ZWZhY3RWZXJzaW9uUHJvcGVydGllc0VkaXRpb25QYXJ0I2dldElzQ29uZmlndXJhYmxlKCkKCSAqIAoJICovCglwdWJsaWMgQm9vbGVhbiBnZXRJc0NvbmZpZ3VyYWJsZSgpIHsKCQlyZXR1cm4gQm9vbGVhbi52YWx1ZU9mKGlzQ29uZmlndXJhYmxlLmdldFNlbGVjdGlvbigpKTsKCX0KCgkvKioKCSAqIHtAaW5oZXJpdERvY30KCSAqIAoJICogQHNlZSBvcmcuZWNsaXBzZS5vcGVuY2VydC5ldm0uZXZpZHNwZWMuZXZpZGVuY2UucGFydHMuQXJ0ZWZhY3RWZXJzaW9uUHJvcGVydGllc0VkaXRpb25QYXJ0I3NldElzQ29uZmlndXJhYmxlKEJvb2xlYW4gbmV3VmFsdWUpCgkgKiAKCSAqLwoJcHVibGljIHZvaWQgc2V0SXNDb25maWd1cmFibGUoQm9vbGVhbiBuZXdWYWx1ZSkgewoJCWlmIChuZXdWYWx1ZSAhPSBudWxsKSB7CgkJCWlzQ29uZmlndXJhYmxlLnNldFNlbGVjdGlvbihuZXdWYWx1ZS5ib29sZWFuVmFsdWUoKSk7CgkJfSBlbHNlIHsKCQkJaXNDb25maWd1cmFibGUuc2V0U2VsZWN0aW9uKGZhbHNlKTsKCQl9CgkJYm9vbGVhbiBlZWZFbGVtZW50RWRpdG9yUmVhZE9ubHlTdGF0ZSA9IGlzUmVhZE9ubHkoRXZpZGVuY2VWaWV3c1JlcG9zaXRvcnkuQXJ0ZWZhY3RWZXJzaW9uLlByb3BlcnRpZXMuaXNDb25maWd1cmFibGUpOwoJCWlmIChlZWZFbGVtZW50RWRpdG9yUmVhZE9ubHlTdGF0ZSAmJiBpc0NvbmZpZ3VyYWJsZS5pc0VuYWJsZWQoKSkgewoJCQlpc0NvbmZpZ3VyYWJsZS5zZXRFbmFibGVkKGZhbHNlKTsKCQkJaXNDb25maWd1cmFibGUuc2V0VG9vbFRpcFRleHQoRXZpZGVuY2VNZXNzYWdlcy5BcnRlZmFjdFZlcnNpb25fUmVhZE9ubHkpOwoJCX0gZWxzZSBpZiAoIWVlZkVsZW1lbnRFZGl0b3JSZWFkT25seVN0YXRlICYmICFpc0NvbmZpZ3VyYWJsZS5pc0VuYWJsZWQoKSkgewoJCQlpc0NvbmZpZ3VyYWJsZS5zZXRFbmFibGVkKHRydWUpOwoJCX0JCgkJCgl9CgoKCgkvKioKCSAqIHtAaW5oZXJpdERvY30KCSAqIAoJICogQHNlZSBvcmcuZWNsaXBzZS5vcGVuY2VydC5ldm0uZXZpZHNwZWMuZXZpZGVuY2UucGFydHMuQXJ0ZWZhY3RWZXJzaW9uUHJvcGVydGllc0VkaXRpb25QYXJ0I2luaXRSZXNvdXJjZShFT2JqZWN0IGN1cnJlbnQsIEVSZWZlcmVuY2UgY29udGFpbmluZ0ZlYXR1cmUsIEVSZWZlcmVuY2UgZmVhdHVyZSkKCSAqLwoJcHVibGljIHZvaWQgaW5pdFJlc291cmNlKFJlZmVyZW5jZXNUYWJsZVNldHRpbmdzIHNldHRpbmdzKSB7CgkJaWYgKGN1cnJlbnQuZVJlc291cmNlKCkgIT0gbnVsbCAmJiBjdXJyZW50LmVSZXNvdXJjZSgpLmdldFJlc291cmNlU2V0KCkgIT0gbnVsbCkKCQkJdGhpcy5yZXNvdXJjZVNldCA9IGN1cnJlbnQuZVJlc291cmNlKCkuZ2V0UmVzb3VyY2VTZXQoKTsKCQlSZWZlcmVuY2VzVGFibGVDb250ZW50UHJvdmlkZXIgY29udGVudFByb3ZpZGVyID0gbmV3IFJlZmVyZW5jZXNUYWJsZUNvbnRlbnRQcm92aWRlcigpOwoJCXJlc291cmNlLnNldENvbnRlbnRQcm92aWRlcihjb250ZW50UHJvdmlkZXIpOwoJCXJlc291cmNlLnNldElucHV0KHNldHRpbmdzKTsKCQlib29sZWFuIGVlZkVsZW1lbnRFZGl0b3JSZWFkT25seVN0YXRlID0gaXNSZWFkT25seShFdmlkZW5jZVZpZXdzUmVwb3NpdG9yeS5BcnRlZmFjdFZlcnNpb24uUHJvcGVydGllcy5yZXNvdXJjZSk7CgkJaWYgKGVlZkVsZW1lbnRFZGl0b3JSZWFkT25seVN0YXRlICYmIHJlc291cmNlLmlzRW5hYmxlZCgpKSB7CgkJCXJlc291cmNlLnNldEVuYWJsZWQoZmFsc2UpOwoJCQlyZXNvdXJjZS5zZXRUb29sVGlwVGV4dChFdmlkZW5jZU1lc3NhZ2VzLkFydGVmYWN0VmVyc2lvbl9SZWFkT25seSk7CgkJfSBlbHNlIGlmICghZWVmRWxlbWVudEVkaXRvclJlYWRPbmx5U3RhdGUgJiYgIXJlc291cmNlLmlzRW5hYmxlZCgpKSB7CgkJCXJlc291cmNlLnNldEVuYWJsZWQodHJ1ZSk7CgkJfQkKCQkKCX0KCgkvKioKCSAqIHtAaW5oZXJpdERvY30KCSAqIAoJICogQHNlZSBvcmcuZWNsaXBzZS5vcGVuY2VydC5ldm0uZXZpZHNwZWMuZXZpZGVuY2UucGFydHMuQXJ0ZWZhY3RWZXJzaW9uUHJvcGVydGllc0VkaXRpb25QYXJ0I3VwZGF0ZVJlc291cmNlKCkKCSAqIAoJICovCglwdWJsaWMgdm9pZCB1cGRhdGVSZXNvdXJjZSgpIHsKCXJlc291cmNlLnJlZnJlc2goKTsKfQoKCS8qKgoJICoge0Bpbmhlcml0RG9jfQoJICogCgkgKiBAc2VlIG9yZy5lY2xpcHNlLm9wZW5jZXJ0LmV2bS5ldmlkc3BlYy5ldmlkZW5jZS5wYXJ0cy5BcnRlZmFjdFZlcnNpb25Qcm9wZXJ0aWVzRWRpdGlvblBhcnQjYWRkRmlsdGVyUmVzb3VyY2UoVmlld2VyRmlsdGVyIGZpbHRlcikKCSAqIAoJICovCglwdWJsaWMgdm9pZCBhZGRGaWx0ZXJUb1Jlc291cmNlKFZpZXdlckZpbHRlciBmaWx0ZXIpIHsKCQlyZXNvdXJjZUZpbHRlcnMuYWRkKGZpbHRlcik7CgkJaWYgKHRoaXMucmVzb3VyY2UgIT0gbnVsbCkgewoJCQl0aGlzLnJlc291cmNlLmFkZEZpbHRlcihmaWx0ZXIpOwoJCX0KCX0KCgkvKioKCSAqIHtAaW5oZXJpdERvY30KCSAqIAoJICogQHNlZSBvcmcuZWNsaXBzZS5vcGVuY2VydC5ldm0uZXZpZHNwZWMuZXZpZGVuY2UucGFydHMuQXJ0ZWZhY3RWZXJzaW9uUHJvcGVydGllc0VkaXRpb25QYXJ0I2FkZEJ1c2luZXNzRmlsdGVyUmVzb3VyY2UoVmlld2VyRmlsdGVyIGZpbHRlcikKCSAqIAoJICovCglwdWJsaWMgdm9pZCBhZGRCdXNpbmVzc0ZpbHRlclRvUmVzb3VyY2UoVmlld2VyRmlsdGVyIGZpbHRlcikgewoJCXJlc291cmNlQnVzaW5lc3NGaWx0ZXJzLmFkZChmaWx0ZXIpOwoJfQoKCS8qKgoJICoge0Bpbmhlcml0RG9jfQoJICogCgkgKiBAc2VlIG9yZy5lY2xpcHNlLm9wZW5jZXJ0LmV2bS5ldmlkc3BlYy5ldmlkZW5jZS5wYXJ0cy5BcnRlZmFjdFZlcnNpb25Qcm9wZXJ0aWVzRWRpdGlvblBhcnQjaXNDb250YWluZWRJblJlc291cmNlVGFibGUoRU9iamVjdCBlbGVtZW50KQoJICogCgkgKi8KCXB1YmxpYyBib29sZWFuIGlzQ29udGFpbmVkSW5SZXNvdXJjZVRhYmxlKEVPYmplY3QgZWxlbWVudCkgewoJCXJldHVybiAoKFJlZmVyZW5jZXNUYWJsZVNldHRpbmdzKXJlc291cmNlLmdldElucHV0KCkpLmNvbnRhaW5zKGVsZW1lbnQpOwoJfQoKCgoKCgoJLyoqCgkgKiB7QGluaGVyaXREb2N9CgkgKgoJICogQHNlZSBvcmcuZWNsaXBzZS5lbWYuZWVmLnJ1bnRpbWUuYXBpLnBhcnRzLklQcm9wZXJ0aWVzRWRpdGlvblBhcnQjZ2V0VGl0bGUoKQoJICogCgkgKi8KCXB1YmxpYyBTdHJpbmcgZ2V0VGl0bGUoKSB7CgkJcmV0dXJuIEV2aWRlbmNlTWVzc2FnZXMuQXJ0ZWZhY3RWZXJzaW9uX1BhcnRfVGl0bGU7Cgl9CgoJLy8gU3RhcnQgb2YgdXNlciBjb2RlIGFkZGl0aW9uYWwgbWV0aG9kcwoJCgkvLyBFbmQgb2YgdXNlciBjb2RlCgoKfQo=