LyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogQ29weXJpZ2h0IChjKSAyMDE2IEZ1bmRhY2nzbiBUZWNuYWxpYSBSZXNlYXJjaCAmIElubm92YXRpb24uCiAqCiAqIEFsbCByaWdodHMgcmVzZXJ2ZWQuIFRoaXMgcHJvZ3JhbSBhbmQgdGhlIGFjY29tcGFueWluZyBtYXRlcmlhbHMKICogYXJlIG1hZGUgYXZhaWxhYmxlIHVuZGVyIHRoZSB0ZXJtcyBvZiB0aGUgRWNsaXBzZSBQdWJsaWMgTGljZW5zZSB2MS4wCiAqIHdoaWNoIGFjY29tcGFuaWVzIHRoaXMgZGlzdHJpYnV0aW9uLCBhbmQgaXMgYXZhaWxhYmxlIGF0CiAqIGh0dHA6Ly93d3cuZWNsaXBzZS5vcmcvbGVnYWwvZXBsLXYxMC5odG1sCiAqCiAqIENvbnRyaWJ1dG9yczoKICogICBIdWFzY2FyIEVzcGlub3phIC0gaW5pdGlhbCBBUEkgYW5kIGltcGxlbWVudGF0aW9uCiAqICAgQWxlamFuZHJhIFJ17XogLSBpbml0aWFsIEFQSSBhbmQgaW1wbGVtZW50YXRpb24KICogICBJZG95YSBEZWwgUu1vIC0gaW5pdGlhbCBBUEkgYW5kIGltcGxlbWVudGF0aW9uCiAqICAgTWFyaSBDYXJtZW4gUGFsYWNpb3MgLSBpbml0aWFsIEFQSSBhbmQgaW1wbGVtZW50YXRpb24KICogICBBbmdlbCBM83BleiAtIGluaXRpYWwgQVBJIGFuZCBpbXBsZW1lbnRhdGlvbgogKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8KLyoqCiAqIEdlbmVyYXRlZCB3aXRoIEFjY2VsZW8KICovCnBhY2thZ2Ugb3JnLmVjbGlwc2Uub3BlbmNlcnQuc2FtLmFyZy5hcmcucGFydHMuaW1wbDsKCi8vIFN0YXJ0IG9mIHVzZXIgY29kZSBmb3IgaW1wb3J0cwppbXBvcnQgamF2YS51dGlsLkFycmF5TGlzdDsKaW1wb3J0IGphdmEudXRpbC5JdGVyYXRvcjsKaW1wb3J0IGphdmEudXRpbC5MaXN0OwoKaW1wb3J0IG9yZy5lY2xpcHNlLmVtZi5lY29yZS5FT2JqZWN0OwoKaW1wb3J0IG9yZy5lY2xpcHNlLmVtZi5lZWYucnVudGltZS5hcGkuY29tcG9uZW50LklQcm9wZXJ0aWVzRWRpdGlvbkNvbXBvbmVudDsKCmltcG9ydCBvcmcuZWNsaXBzZS5lbWYuZWVmLnJ1bnRpbWUuYXBpLm5vdGlmeS5JUHJvcGVydGllc0VkaXRpb25FdmVudDsKCmltcG9ydCBvcmcuZWNsaXBzZS5lbWYuZWVmLnJ1bnRpbWUuYXBpLnBhcnRzLklTV1RQcm9wZXJ0aWVzRWRpdGlvblBhcnQ7CgppbXBvcnQgb3JnLmVjbGlwc2UuZW1mLmVlZi5ydW50aW1lLmNvbnRleHQuaW1wbC5FT2JqZWN0UHJvcGVydGllc0VkaXRpb25Db250ZXh0OwoKaW1wb3J0IG9yZy5lY2xpcHNlLmVtZi5lZWYucnVudGltZS5pbXBsLm5vdGlmeS5Qcm9wZXJ0aWVzRWRpdGlvbkV2ZW50OwoKaW1wb3J0IG9yZy5lY2xpcHNlLmVtZi5lZWYucnVudGltZS5pbXBsLnBhcnRzLkNvbXBvc2l0ZVByb3BlcnRpZXNFZGl0aW9uUGFydDsKCmltcG9ydCBvcmcuZWNsaXBzZS5lbWYuZWVmLnJ1bnRpbWUucG9saWNpZXMuUHJvcGVydGllc0VkaXRpbmdQb2xpY3k7CgppbXBvcnQgb3JnLmVjbGlwc2UuZW1mLmVlZi5ydW50aW1lLnByb3ZpZGVycy5Qcm9wZXJ0aWVzRWRpdGluZ1Byb3ZpZGVyOwoKaW1wb3J0IG9yZy5lY2xpcHNlLmVtZi5lZWYucnVudGltZS51aS5wYXJ0cy5QYXJ0Q29tcG9zZXI7CgppbXBvcnQgb3JnLmVjbGlwc2UuZW1mLmVlZi5ydW50aW1lLnVpLnBhcnRzLnNlcXVlbmNlLkJpbmRpbmdDb21wb3NpdGlvblNlcXVlbmNlOwppbXBvcnQgb3JnLmVjbGlwc2UuZW1mLmVlZi5ydW50aW1lLnVpLnBhcnRzLnNlcXVlbmNlLkNvbXBvc2l0aW9uU2VxdWVuY2U7CmltcG9ydCBvcmcuZWNsaXBzZS5lbWYuZWVmLnJ1bnRpbWUudWkucGFydHMuc2VxdWVuY2UuQ29tcG9zaXRpb25TdGVwOwoKaW1wb3J0IG9yZy5lY2xpcHNlLmVtZi5lZWYucnVudGltZS51aS51dGlscy5FZGl0aW5nVXRpbHM7CgppbXBvcnQgb3JnLmVjbGlwc2UuZW1mLmVlZi5ydW50aW1lLnVpLndpZGdldHMuUmVmZXJlbmNlc1RhYmxlOwoKaW1wb3J0IG9yZy5lY2xpcHNlLmVtZi5lZWYucnVudGltZS51aS53aWRnZXRzLlJlZmVyZW5jZXNUYWJsZS5SZWZlcmVuY2VzVGFibGVMaXN0ZW5lcjsKCmltcG9ydCBvcmcuZWNsaXBzZS5lbWYuZWVmLnJ1bnRpbWUudWkud2lkZ2V0cy5TV1RVdGlsczsKaW1wb3J0IG9yZy5lY2xpcHNlLmVtZi5lZWYucnVudGltZS51aS53aWRnZXRzLlRhYkVsZW1lbnRUcmVlU2VsZWN0aW9uRGlhbG9nOwoKaW1wb3J0IG9yZy5lY2xpcHNlLmVtZi5lZWYucnVudGltZS51aS53aWRnZXRzLnJlZmVyZW5jZXN0YWJsZS5SZWZlcmVuY2VzVGFibGVDb250ZW50UHJvdmlkZXI7CmltcG9ydCBvcmcuZWNsaXBzZS5lbWYuZWVmLnJ1bnRpbWUudWkud2lkZ2V0cy5yZWZlcmVuY2VzdGFibGUuUmVmZXJlbmNlc1RhYmxlU2V0dGluZ3M7CgppbXBvcnQgb3JnLmVjbGlwc2UuamZhY2Uudmlld2Vycy5JU3RydWN0dXJlZFNlbGVjdGlvbjsKaW1wb3J0IG9yZy5lY2xpcHNlLmpmYWNlLnZpZXdlcnMuVmlld2VyRmlsdGVyOwoKaW1wb3J0IG9yZy5lY2xpcHNlLnN3dC5TV1Q7CgppbXBvcnQgb3JnLmVjbGlwc2Uuc3d0LmV2ZW50cy5Gb2N1c0FkYXB0ZXI7CmltcG9ydCBvcmcuZWNsaXBzZS5zd3QuZXZlbnRzLkZvY3VzRXZlbnQ7CmltcG9ydCBvcmcuZWNsaXBzZS5zd3QuZXZlbnRzLktleUFkYXB0ZXI7CmltcG9ydCBvcmcuZWNsaXBzZS5zd3QuZXZlbnRzLktleUV2ZW50OwppbXBvcnQgb3JnLmVjbGlwc2Uuc3d0LmV2ZW50cy5TZWxlY3Rpb25BZGFwdGVyOwppbXBvcnQgb3JnLmVjbGlwc2Uuc3d0LmV2ZW50cy5TZWxlY3Rpb25FdmVudDsKCmltcG9ydCBvcmcuZWNsaXBzZS5zd3QubGF5b3V0LkdyaWREYXRhOwppbXBvcnQgb3JnLmVjbGlwc2Uuc3d0LmxheW91dC5HcmlkTGF5b3V0OwoKaW1wb3J0IG9yZy5lY2xpcHNlLnN3dC53aWRnZXRzLkNvbXBvc2l0ZTsKaW1wb3J0IG9yZy5lY2xpcHNlLnN3dC53aWRnZXRzLkdyb3VwOwppbXBvcnQgb3JnLmVjbGlwc2Uuc3d0LndpZGdldHMuVGV4dDsKCmltcG9ydCBvcmcuZWNsaXBzZS5vcGVuY2VydC5zYW0uYXJnLmFyZy5wYXJ0cy5BcmdWaWV3c1JlcG9zaXRvcnk7CmltcG9ydCBvcmcuZWNsaXBzZS5vcGVuY2VydC5zYW0uYXJnLmFyZy5wYXJ0cy5Bc3NlcnRlZENoYWxsZW5nZVByb3BlcnRpZXNFZGl0aW9uUGFydDsKCmltcG9ydCBvcmcuZWNsaXBzZS5vcGVuY2VydC5zYW0uYXJnLmFyZy5wcm92aWRlcnMuQXJnTWVzc2FnZXM7CgovLyBFbmQgb2YgdXNlciBjb2RlCgovKioKICogCiAqIAogKi8KcHVibGljIGNsYXNzIEFzc2VydGVkQ2hhbGxlbmdlUHJvcGVydGllc0VkaXRpb25QYXJ0SW1wbCBleHRlbmRzIENvbXBvc2l0ZVByb3BlcnRpZXNFZGl0aW9uUGFydCBpbXBsZW1lbnRzIElTV1RQcm9wZXJ0aWVzRWRpdGlvblBhcnQsIEFzc2VydGVkQ2hhbGxlbmdlUHJvcGVydGllc0VkaXRpb25QYXJ0IHsKCglwcm90ZWN0ZWQgVGV4dCBpZDsKCXByb3RlY3RlZCBUZXh0IG5hbWU7Cglwcm90ZWN0ZWQgVGV4dCBkZXNjcmlwdGlvbjsKCXByb3RlY3RlZCBUZXh0IGNvbnRlbnQ7Cglwcm90ZWN0ZWQgUmVmZXJlbmNlc1RhYmxlIHNvdXJjZTsKCXByb3RlY3RlZCBMaXN0PFZpZXdlckZpbHRlcj4gc291cmNlQnVzaW5lc3NGaWx0ZXJzID0gbmV3IEFycmF5TGlzdDxWaWV3ZXJGaWx0ZXI+KCk7Cglwcm90ZWN0ZWQgTGlzdDxWaWV3ZXJGaWx0ZXI+IHNvdXJjZUZpbHRlcnMgPSBuZXcgQXJyYXlMaXN0PFZpZXdlckZpbHRlcj4oKTsKCXByb3RlY3RlZCBSZWZlcmVuY2VzVGFibGUgdGFyZ2V0OwoJcHJvdGVjdGVkIExpc3Q8Vmlld2VyRmlsdGVyPiB0YXJnZXRCdXNpbmVzc0ZpbHRlcnMgPSBuZXcgQXJyYXlMaXN0PFZpZXdlckZpbHRlcj4oKTsKCXByb3RlY3RlZCBMaXN0PFZpZXdlckZpbHRlcj4gdGFyZ2V0RmlsdGVycyA9IG5ldyBBcnJheUxpc3Q8Vmlld2VyRmlsdGVyPigpOwoKCgoJLyoqCgkgKiBEZWZhdWx0IGNvbnN0cnVjdG9yCgkgKiBAcGFyYW0gZWRpdGlvbkNvbXBvbmVudCB0aGUge0BsaW5rIElQcm9wZXJ0aWVzRWRpdGlvbkNvbXBvbmVudH0gdGhhdCBtYW5hZ2UgdGhpcyBwYXJ0CgkgKiAKCSAqLwoJcHVibGljIEFzc2VydGVkQ2hhbGxlbmdlUHJvcGVydGllc0VkaXRpb25QYXJ0SW1wbChJUHJvcGVydGllc0VkaXRpb25Db21wb25lbnQgZWRpdGlvbkNvbXBvbmVudCkgewoJCXN1cGVyKGVkaXRpb25Db21wb25lbnQpOwoJfQoKCS8qKgoJICoge0Bpbmhlcml0RG9jfQoJICogCgkgKiBAc2VlIG9yZy5lY2xpcHNlLmVtZi5lZWYucnVudGltZS5hcGkucGFydHMuSVNXVFByb3BlcnRpZXNFZGl0aW9uUGFydCMKCSAqIAkJCWNyZWF0ZUZpZ3VyZShvcmcuZWNsaXBzZS5zd3Qud2lkZ2V0cy5Db21wb3NpdGUpCgkgKiAKCSAqLwoJcHVibGljIENvbXBvc2l0ZSBjcmVhdGVGaWd1cmUoZmluYWwgQ29tcG9zaXRlIHBhcmVudCkgewoJCXZpZXcgPSBuZXcgQ29tcG9zaXRlKHBhcmVudCwgU1dULk5PTkUpOwoJCUdyaWRMYXlvdXQgbGF5b3V0ID0gbmV3IEdyaWRMYXlvdXQoKTsKCQlsYXlvdXQubnVtQ29sdW1ucyA9IDM7CgkJdmlldy5zZXRMYXlvdXQobGF5b3V0KTsKCQljcmVhdGVDb250cm9scyh2aWV3KTsKCQlyZXR1cm4gdmlldzsKCX0KCgkvKioKCSAqIHtAaW5oZXJpdERvY30KCSAqIAoJICogQHNlZSBvcmcuZWNsaXBzZS5lbWYuZWVmLnJ1bnRpbWUuYXBpLnBhcnRzLklTV1RQcm9wZXJ0aWVzRWRpdGlvblBhcnQjCgkgKiAJCQljcmVhdGVDb250cm9scyhvcmcuZWNsaXBzZS5zd3Qud2lkZ2V0cy5Db21wb3NpdGUpCgkgKiAKCSAqLwoJcHVibGljIHZvaWQgY3JlYXRlQ29udHJvbHMoQ29tcG9zaXRlIHZpZXcpIHsgCgkJQ29tcG9zaXRpb25TZXF1ZW5jZSBhc3NlcnRlZENoYWxsZW5nZVN0ZXAgPSBuZXcgQmluZGluZ0NvbXBvc2l0aW9uU2VxdWVuY2UocHJvcGVydGllc0VkaXRpb25Db21wb25lbnQpOwoJCUNvbXBvc2l0aW9uU3RlcCBwcm9wZXJ0aWVzU3RlcCA9IGFzc2VydGVkQ2hhbGxlbmdlU3RlcC5hZGRTdGVwKEFyZ1ZpZXdzUmVwb3NpdG9yeS5Bc3NlcnRlZENoYWxsZW5nZS5Qcm9wZXJ0aWVzLmNsYXNzKTsKCQlwcm9wZXJ0aWVzU3RlcC5hZGRTdGVwKEFyZ1ZpZXdzUmVwb3NpdG9yeS5Bc3NlcnRlZENoYWxsZW5nZS5Qcm9wZXJ0aWVzLmlkKTsKCQlwcm9wZXJ0aWVzU3RlcC5hZGRTdGVwKEFyZ1ZpZXdzUmVwb3NpdG9yeS5Bc3NlcnRlZENoYWxsZW5nZS5Qcm9wZXJ0aWVzLm5hbWUpOwoJCXByb3BlcnRpZXNTdGVwLmFkZFN0ZXAoQXJnVmlld3NSZXBvc2l0b3J5LkFzc2VydGVkQ2hhbGxlbmdlLlByb3BlcnRpZXMuZGVzY3JpcHRpb24pOwoJCXByb3BlcnRpZXNTdGVwLmFkZFN0ZXAoQXJnVmlld3NSZXBvc2l0b3J5LkFzc2VydGVkQ2hhbGxlbmdlLlByb3BlcnRpZXMuY29udGVudCk7CgkJcHJvcGVydGllc1N0ZXAuYWRkU3RlcChBcmdWaWV3c1JlcG9zaXRvcnkuQXNzZXJ0ZWRDaGFsbGVuZ2UuUHJvcGVydGllcy5zb3VyY2UpOwoJCXByb3BlcnRpZXNTdGVwLmFkZFN0ZXAoQXJnVmlld3NSZXBvc2l0b3J5LkFzc2VydGVkQ2hhbGxlbmdlLlByb3BlcnRpZXMudGFyZ2V0KTsKCQkKCQkKCQljb21wb3NlciA9IG5ldyBQYXJ0Q29tcG9zZXIoYXNzZXJ0ZWRDaGFsbGVuZ2VTdGVwKSB7CgoJCQlAT3ZlcnJpZGUKCQkJcHVibGljIENvbXBvc2l0ZSBhZGRUb1BhcnQoQ29tcG9zaXRlIHBhcmVudCwgT2JqZWN0IGtleSkgewoJCQkJaWYgKGtleSA9PSBBcmdWaWV3c1JlcG9zaXRvcnkuQXNzZXJ0ZWRDaGFsbGVuZ2UuUHJvcGVydGllcy5jbGFzcykgewoJCQkJCXJldHVybiBjcmVhdGVQcm9wZXJ0aWVzR3JvdXAocGFyZW50KTsKCQkJCX0KCQkJCWlmIChrZXkgPT0gQXJnVmlld3NSZXBvc2l0b3J5LkFzc2VydGVkQ2hhbGxlbmdlLlByb3BlcnRpZXMuaWQpIHsKCQkJCQlyZXR1cm4gY3JlYXRlSWRUZXh0KHBhcmVudCk7CgkJCQl9CgkJCQlpZiAoa2V5ID09IEFyZ1ZpZXdzUmVwb3NpdG9yeS5Bc3NlcnRlZENoYWxsZW5nZS5Qcm9wZXJ0aWVzLm5hbWUpIHsKCQkJCQlyZXR1cm4gY3JlYXRlTmFtZVRleHQocGFyZW50KTsKCQkJCX0KCQkJCWlmIChrZXkgPT0gQXJnVmlld3NSZXBvc2l0b3J5LkFzc2VydGVkQ2hhbGxlbmdlLlByb3BlcnRpZXMuZGVzY3JpcHRpb24pIHsKCQkJCQlyZXR1cm4gY3JlYXRlRGVzY3JpcHRpb25UZXh0KHBhcmVudCk7CgkJCQl9CgkJCQlpZiAoa2V5ID09IEFyZ1ZpZXdzUmVwb3NpdG9yeS5Bc3NlcnRlZENoYWxsZW5nZS5Qcm9wZXJ0aWVzLmNvbnRlbnQpIHsKCQkJCQlyZXR1cm4gY3JlYXRlQ29udGVudFRleHQocGFyZW50KTsKCQkJCX0KCQkJCWlmIChrZXkgPT0gQXJnVmlld3NSZXBvc2l0b3J5LkFzc2VydGVkQ2hhbGxlbmdlLlByb3BlcnRpZXMuc291cmNlKSB7CgkJCQkJcmV0dXJuIGNyZWF0ZVNvdXJjZUFkdmFuY2VkUmVmZXJlbmNlc1RhYmxlKHBhcmVudCk7CgkJCQl9CgkJCQlpZiAoa2V5ID09IEFyZ1ZpZXdzUmVwb3NpdG9yeS5Bc3NlcnRlZENoYWxsZW5nZS5Qcm9wZXJ0aWVzLnRhcmdldCkgewoJCQkJCXJldHVybiBjcmVhdGVUYXJnZXRBZHZhbmNlZFJlZmVyZW5jZXNUYWJsZShwYXJlbnQpOwoJCQkJfQoJCQkJcmV0dXJuIHBhcmVudDsKCQkJfQoJCX07CgkJY29tcG9zZXIuY29tcG9zZSh2aWV3KTsKCX0KCgkvKioKCSAqIAoJICovCglwcm90ZWN0ZWQgQ29tcG9zaXRlIGNyZWF0ZVByb3BlcnRpZXNHcm91cChDb21wb3NpdGUgcGFyZW50KSB7CgkJR3JvdXAgcHJvcGVydGllc0dyb3VwID0gbmV3IEdyb3VwKHBhcmVudCwgU1dULk5PTkUpOwoJCXByb3BlcnRpZXNHcm91cC5zZXRUZXh0KEFyZ01lc3NhZ2VzLkFzc2VydGVkQ2hhbGxlbmdlUHJvcGVydGllc0VkaXRpb25QYXJ0X1Byb3BlcnRpZXNHcm91cExhYmVsKTsKCQlHcmlkRGF0YSBwcm9wZXJ0aWVzR3JvdXBEYXRhID0gbmV3IEdyaWREYXRhKEdyaWREYXRhLkZJTExfSE9SSVpPTlRBTCk7CgkJcHJvcGVydGllc0dyb3VwRGF0YS5ob3Jpem9udGFsU3BhbiA9IDM7CgkJcHJvcGVydGllc0dyb3VwLnNldExheW91dERhdGEocHJvcGVydGllc0dyb3VwRGF0YSk7CgkJR3JpZExheW91dCBwcm9wZXJ0aWVzR3JvdXBMYXlvdXQgPSBuZXcgR3JpZExheW91dCgpOwoJCXByb3BlcnRpZXNHcm91cExheW91dC5udW1Db2x1bW5zID0gMzsKCQlwcm9wZXJ0aWVzR3JvdXAuc2V0TGF5b3V0KHByb3BlcnRpZXNHcm91cExheW91dCk7CgkJcmV0dXJuIHByb3BlcnRpZXNHcm91cDsKCX0KCgkKCXByb3RlY3RlZCBDb21wb3NpdGUgY3JlYXRlSWRUZXh0KENvbXBvc2l0ZSBwYXJlbnQpIHsKCQljcmVhdGVEZXNjcmlwdGlvbihwYXJlbnQsIEFyZ1ZpZXdzUmVwb3NpdG9yeS5Bc3NlcnRlZENoYWxsZW5nZS5Qcm9wZXJ0aWVzLmlkLCBBcmdNZXNzYWdlcy5Bc3NlcnRlZENoYWxsZW5nZVByb3BlcnRpZXNFZGl0aW9uUGFydF9JZExhYmVsKTsKCQlpZCA9IFNXVFV0aWxzLmNyZWF0ZVNjcm9sbGFibGVUZXh0KHBhcmVudCwgU1dULkJPUkRFUik7CgkJR3JpZERhdGEgaWREYXRhID0gbmV3IEdyaWREYXRhKEdyaWREYXRhLkZJTExfSE9SSVpPTlRBTCk7CgkJaWQuc2V0TGF5b3V0RGF0YShpZERhdGEpOwoJCWlkLmFkZEZvY3VzTGlzdGVuZXIobmV3IEZvY3VzQWRhcHRlcigpIHsKCgkJCS8qKgoJCQkgKiB7QGluaGVyaXREb2N9CgkJCSAqIAoJCQkgKiBAc2VlIG9yZy5lY2xpcHNlLnN3dC5ldmVudHMuRm9jdXNBZGFwdGVyI2ZvY3VzTG9zdChvcmcuZWNsaXBzZS5zd3QuZXZlbnRzLkZvY3VzRXZlbnQpCgkJCSAqIAoJCQkgKi8KCQkJQE92ZXJyaWRlCgkJCUBTdXBwcmVzc1dhcm5pbmdzKCJzeW50aGV0aWMtYWNjZXNzIikKCQkJcHVibGljIHZvaWQgZm9jdXNMb3N0KEZvY3VzRXZlbnQgZSkgewoJCQkJaWYgKHByb3BlcnRpZXNFZGl0aW9uQ29tcG9uZW50ICE9IG51bGwpCgkJCQkJcHJvcGVydGllc0VkaXRpb25Db21wb25lbnQuZmlyZVByb3BlcnRpZXNDaGFuZ2VkKG5ldyBQcm9wZXJ0aWVzRWRpdGlvbkV2ZW50KEFzc2VydGVkQ2hhbGxlbmdlUHJvcGVydGllc0VkaXRpb25QYXJ0SW1wbC50aGlzLCBBcmdWaWV3c1JlcG9zaXRvcnkuQXNzZXJ0ZWRDaGFsbGVuZ2UuUHJvcGVydGllcy5pZCwgUHJvcGVydGllc0VkaXRpb25FdmVudC5DT01NSVQsIFByb3BlcnRpZXNFZGl0aW9uRXZlbnQuU0VULCBudWxsLCBpZC5nZXRUZXh0KCkpKTsKCQkJfQoKCQl9KTsKCQlpZC5hZGRLZXlMaXN0ZW5lcihuZXcgS2V5QWRhcHRlcigpIHsKCgkJCS8qKgoJCQkgKiB7QGluaGVyaXREb2N9CgkJCSAqIAoJCQkgKiBAc2VlIG9yZy5lY2xpcHNlLnN3dC5ldmVudHMuS2V5QWRhcHRlciNrZXlQcmVzc2VkKG9yZy5lY2xpcHNlLnN3dC5ldmVudHMuS2V5RXZlbnQpCgkJCSAqIAoJCQkgKi8KCQkJQE92ZXJyaWRlCgkJCUBTdXBwcmVzc1dhcm5pbmdzKCJzeW50aGV0aWMtYWNjZXNzIikKCQkJcHVibGljIHZvaWQga2V5UHJlc3NlZChLZXlFdmVudCBlKSB7CgkJCQlpZiAoZS5jaGFyYWN0ZXIgPT0gU1dULkNSKSB7CgkJCQkJaWYgKHByb3BlcnRpZXNFZGl0aW9uQ29tcG9uZW50ICE9IG51bGwpCgkJCQkJCXByb3BlcnRpZXNFZGl0aW9uQ29tcG9uZW50LmZpcmVQcm9wZXJ0aWVzQ2hhbmdlZChuZXcgUHJvcGVydGllc0VkaXRpb25FdmVudChBc3NlcnRlZENoYWxsZW5nZVByb3BlcnRpZXNFZGl0aW9uUGFydEltcGwudGhpcywgQXJnVmlld3NSZXBvc2l0b3J5LkFzc2VydGVkQ2hhbGxlbmdlLlByb3BlcnRpZXMuaWQsIFByb3BlcnRpZXNFZGl0aW9uRXZlbnQuQ09NTUlULCBQcm9wZXJ0aWVzRWRpdGlvbkV2ZW50LlNFVCwgbnVsbCwgaWQuZ2V0VGV4dCgpKSk7CgkJCQl9CgkJCX0KCgkJfSk7CgkJRWRpdGluZ1V0aWxzLnNldElEKGlkLCBBcmdWaWV3c1JlcG9zaXRvcnkuQXNzZXJ0ZWRDaGFsbGVuZ2UuUHJvcGVydGllcy5pZCk7CgkJRWRpdGluZ1V0aWxzLnNldEVFRnR5cGUoaWQsICJlZWY6OlRleHQiKTsgLy8kTk9OLU5MUy0xJAoJCVNXVFV0aWxzLmNyZWF0ZUhlbHBCdXR0b24ocGFyZW50LCBwcm9wZXJ0aWVzRWRpdGlvbkNvbXBvbmVudC5nZXRIZWxwQ29udGVudChBcmdWaWV3c1JlcG9zaXRvcnkuQXNzZXJ0ZWRDaGFsbGVuZ2UuUHJvcGVydGllcy5pZCwgQXJnVmlld3NSZXBvc2l0b3J5LlNXVF9LSU5EKSwgbnVsbCk7IC8vJE5PTi1OTFMtMSQKCQkvLyBTdGFydCBvZiB1c2VyIGNvZGUgZm9yIGNyZWF0ZUlkVGV4dAoKCQkvLyBFbmQgb2YgdXNlciBjb2RlCgkJcmV0dXJuIHBhcmVudDsKCX0KCgkKCXByb3RlY3RlZCBDb21wb3NpdGUgY3JlYXRlTmFtZVRleHQoQ29tcG9zaXRlIHBhcmVudCkgewoJCWNyZWF0ZURlc2NyaXB0aW9uKHBhcmVudCwgQXJnVmlld3NSZXBvc2l0b3J5LkFzc2VydGVkQ2hhbGxlbmdlLlByb3BlcnRpZXMubmFtZSwgQXJnTWVzc2FnZXMuQXNzZXJ0ZWRDaGFsbGVuZ2VQcm9wZXJ0aWVzRWRpdGlvblBhcnRfTmFtZUxhYmVsKTsKCQluYW1lID0gU1dUVXRpbHMuY3JlYXRlU2Nyb2xsYWJsZVRleHQocGFyZW50LCBTV1QuQk9SREVSKTsKCQlHcmlkRGF0YSBuYW1lRGF0YSA9IG5ldyBHcmlkRGF0YShHcmlkRGF0YS5GSUxMX0hPUklaT05UQUwpOwoJCW5hbWUuc2V0TGF5b3V0RGF0YShuYW1lRGF0YSk7CgkJbmFtZS5hZGRGb2N1c0xpc3RlbmVyKG5ldyBGb2N1c0FkYXB0ZXIoKSB7CgoJCQkvKioKCQkJICoge0Bpbmhlcml0RG9jfQoJCQkgKiAKCQkJICogQHNlZSBvcmcuZWNsaXBzZS5zd3QuZXZlbnRzLkZvY3VzQWRhcHRlciNmb2N1c0xvc3Qob3JnLmVjbGlwc2Uuc3d0LmV2ZW50cy5Gb2N1c0V2ZW50KQoJCQkgKiAKCQkJICovCgkJCUBPdmVycmlkZQoJCQlAU3VwcHJlc3NXYXJuaW5ncygic3ludGhldGljLWFjY2VzcyIpCgkJCXB1YmxpYyB2b2lkIGZvY3VzTG9zdChGb2N1c0V2ZW50IGUpIHsKCQkJCWlmIChwcm9wZXJ0aWVzRWRpdGlvbkNvbXBvbmVudCAhPSBudWxsKQoJCQkJCXByb3BlcnRpZXNFZGl0aW9uQ29tcG9uZW50LmZpcmVQcm9wZXJ0aWVzQ2hhbmdlZChuZXcgUHJvcGVydGllc0VkaXRpb25FdmVudChBc3NlcnRlZENoYWxsZW5nZVByb3BlcnRpZXNFZGl0aW9uUGFydEltcGwudGhpcywgQXJnVmlld3NSZXBvc2l0b3J5LkFzc2VydGVkQ2hhbGxlbmdlLlByb3BlcnRpZXMubmFtZSwgUHJvcGVydGllc0VkaXRpb25FdmVudC5DT01NSVQsIFByb3BlcnRpZXNFZGl0aW9uRXZlbnQuU0VULCBudWxsLCBuYW1lLmdldFRleHQoKSkpOwoJCQl9CgoJCX0pOwoJCW5hbWUuYWRkS2V5TGlzdGVuZXIobmV3IEtleUFkYXB0ZXIoKSB7CgoJCQkvKioKCQkJICoge0Bpbmhlcml0RG9jfQoJCQkgKiAKCQkJICogQHNlZSBvcmcuZWNsaXBzZS5zd3QuZXZlbnRzLktleUFkYXB0ZXIja2V5UHJlc3NlZChvcmcuZWNsaXBzZS5zd3QuZXZlbnRzLktleUV2ZW50KQoJCQkgKiAKCQkJICovCgkJCUBPdmVycmlkZQoJCQlAU3VwcHJlc3NXYXJuaW5ncygic3ludGhldGljLWFjY2VzcyIpCgkJCXB1YmxpYyB2b2lkIGtleVByZXNzZWQoS2V5RXZlbnQgZSkgewoJCQkJaWYgKGUuY2hhcmFjdGVyID09IFNXVC5DUikgewoJCQkJCWlmIChwcm9wZXJ0aWVzRWRpdGlvbkNvbXBvbmVudCAhPSBudWxsKQoJCQkJCQlwcm9wZXJ0aWVzRWRpdGlvbkNvbXBvbmVudC5maXJlUHJvcGVydGllc0NoYW5nZWQobmV3IFByb3BlcnRpZXNFZGl0aW9uRXZlbnQoQXNzZXJ0ZWRDaGFsbGVuZ2VQcm9wZXJ0aWVzRWRpdGlvblBhcnRJbXBsLnRoaXMsIEFyZ1ZpZXdzUmVwb3NpdG9yeS5Bc3NlcnRlZENoYWxsZW5nZS5Qcm9wZXJ0aWVzLm5hbWUsIFByb3BlcnRpZXNFZGl0aW9uRXZlbnQuQ09NTUlULCBQcm9wZXJ0aWVzRWRpdGlvbkV2ZW50LlNFVCwgbnVsbCwgbmFtZS5nZXRUZXh0KCkpKTsKCQkJCX0KCQkJfQoKCQl9KTsKCQlFZGl0aW5nVXRpbHMuc2V0SUQobmFtZSwgQXJnVmlld3NSZXBvc2l0b3J5LkFzc2VydGVkQ2hhbGxlbmdlLlByb3BlcnRpZXMubmFtZSk7CgkJRWRpdGluZ1V0aWxzLnNldEVFRnR5cGUobmFtZSwgImVlZjo6VGV4dCIpOyAvLyROT04tTkxTLTEkCgkJU1dUVXRpbHMuY3JlYXRlSGVscEJ1dHRvbihwYXJlbnQsIHByb3BlcnRpZXNFZGl0aW9uQ29tcG9uZW50LmdldEhlbHBDb250ZW50KEFyZ1ZpZXdzUmVwb3NpdG9yeS5Bc3NlcnRlZENoYWxsZW5nZS5Qcm9wZXJ0aWVzLm5hbWUsIEFyZ1ZpZXdzUmVwb3NpdG9yeS5TV1RfS0lORCksIG51bGwpOyAvLyROT04tTkxTLTEkCgkJLy8gU3RhcnQgb2YgdXNlciBjb2RlIGZvciBjcmVhdGVOYW1lVGV4dAoKCQkvLyBFbmQgb2YgdXNlciBjb2RlCgkJcmV0dXJuIHBhcmVudDsKCX0KCgkKCXByb3RlY3RlZCBDb21wb3NpdGUgY3JlYXRlRGVzY3JpcHRpb25UZXh0KENvbXBvc2l0ZSBwYXJlbnQpIHsKCQljcmVhdGVEZXNjcmlwdGlvbihwYXJlbnQsIEFyZ1ZpZXdzUmVwb3NpdG9yeS5Bc3NlcnRlZENoYWxsZW5nZS5Qcm9wZXJ0aWVzLmRlc2NyaXB0aW9uLCBBcmdNZXNzYWdlcy5Bc3NlcnRlZENoYWxsZW5nZVByb3BlcnRpZXNFZGl0aW9uUGFydF9EZXNjcmlwdGlvbkxhYmVsKTsKCQlkZXNjcmlwdGlvbiA9IFNXVFV0aWxzLmNyZWF0ZVNjcm9sbGFibGVUZXh0KHBhcmVudCwgU1dULkJPUkRFUik7CgkJR3JpZERhdGEgZGVzY3JpcHRpb25EYXRhID0gbmV3IEdyaWREYXRhKEdyaWREYXRhLkZJTExfSE9SSVpPTlRBTCk7CgkJZGVzY3JpcHRpb24uc2V0TGF5b3V0RGF0YShkZXNjcmlwdGlvbkRhdGEpOwoJCWRlc2NyaXB0aW9uLmFkZEZvY3VzTGlzdGVuZXIobmV3IEZvY3VzQWRhcHRlcigpIHsKCgkJCS8qKgoJCQkgKiB7QGluaGVyaXREb2N9CgkJCSAqIAoJCQkgKiBAc2VlIG9yZy5lY2xpcHNlLnN3dC5ldmVudHMuRm9jdXNBZGFwdGVyI2ZvY3VzTG9zdChvcmcuZWNsaXBzZS5zd3QuZXZlbnRzLkZvY3VzRXZlbnQpCgkJCSAqIAoJCQkgKi8KCQkJQE92ZXJyaWRlCgkJCUBTdXBwcmVzc1dhcm5pbmdzKCJzeW50aGV0aWMtYWNjZXNzIikKCQkJcHVibGljIHZvaWQgZm9jdXNMb3N0KEZvY3VzRXZlbnQgZSkgewoJCQkJaWYgKHByb3BlcnRpZXNFZGl0aW9uQ29tcG9uZW50ICE9IG51bGwpCgkJCQkJcHJvcGVydGllc0VkaXRpb25Db21wb25lbnQuZmlyZVByb3BlcnRpZXNDaGFuZ2VkKG5ldyBQcm9wZXJ0aWVzRWRpdGlvbkV2ZW50KEFzc2VydGVkQ2hhbGxlbmdlUHJvcGVydGllc0VkaXRpb25QYXJ0SW1wbC50aGlzLCBBcmdWaWV3c1JlcG9zaXRvcnkuQXNzZXJ0ZWRDaGFsbGVuZ2UuUHJvcGVydGllcy5kZXNjcmlwdGlvbiwgUHJvcGVydGllc0VkaXRpb25FdmVudC5DT01NSVQsIFByb3BlcnRpZXNFZGl0aW9uRXZlbnQuU0VULCBudWxsLCBkZXNjcmlwdGlvbi5nZXRUZXh0KCkpKTsKCQkJfQoKCQl9KTsKCQlkZXNjcmlwdGlvbi5hZGRLZXlMaXN0ZW5lcihuZXcgS2V5QWRhcHRlcigpIHsKCgkJCS8qKgoJCQkgKiB7QGluaGVyaXREb2N9CgkJCSAqIAoJCQkgKiBAc2VlIG9yZy5lY2xpcHNlLnN3dC5ldmVudHMuS2V5QWRhcHRlciNrZXlQcmVzc2VkKG9yZy5lY2xpcHNlLnN3dC5ldmVudHMuS2V5RXZlbnQpCgkJCSAqIAoJCQkgKi8KCQkJQE92ZXJyaWRlCgkJCUBTdXBwcmVzc1dhcm5pbmdzKCJzeW50aGV0aWMtYWNjZXNzIikKCQkJcHVibGljIHZvaWQga2V5UHJlc3NlZChLZXlFdmVudCBlKSB7CgkJCQlpZiAoZS5jaGFyYWN0ZXIgPT0gU1dULkNSKSB7CgkJCQkJaWYgKHByb3BlcnRpZXNFZGl0aW9uQ29tcG9uZW50ICE9IG51bGwpCgkJCQkJCXByb3BlcnRpZXNFZGl0aW9uQ29tcG9uZW50LmZpcmVQcm9wZXJ0aWVzQ2hhbmdlZChuZXcgUHJvcGVydGllc0VkaXRpb25FdmVudChBc3NlcnRlZENoYWxsZW5nZVByb3BlcnRpZXNFZGl0aW9uUGFydEltcGwudGhpcywgQXJnVmlld3NSZXBvc2l0b3J5LkFzc2VydGVkQ2hhbGxlbmdlLlByb3BlcnRpZXMuZGVzY3JpcHRpb24sIFByb3BlcnRpZXNFZGl0aW9uRXZlbnQuQ09NTUlULCBQcm9wZXJ0aWVzRWRpdGlvbkV2ZW50LlNFVCwgbnVsbCwgZGVzY3JpcHRpb24uZ2V0VGV4dCgpKSk7CgkJCQl9CgkJCX0KCgkJfSk7CgkJRWRpdGluZ1V0aWxzLnNldElEKGRlc2NyaXB0aW9uLCBBcmdWaWV3c1JlcG9zaXRvcnkuQXNzZXJ0ZWRDaGFsbGVuZ2UuUHJvcGVydGllcy5kZXNjcmlwdGlvbik7CgkJRWRpdGluZ1V0aWxzLnNldEVFRnR5cGUoZGVzY3JpcHRpb24sICJlZWY6OlRleHQiKTsgLy8kTk9OLU5MUy0xJAoJCVNXVFV0aWxzLmNyZWF0ZUhlbHBCdXR0b24ocGFyZW50LCBwcm9wZXJ0aWVzRWRpdGlvbkNvbXBvbmVudC5nZXRIZWxwQ29udGVudChBcmdWaWV3c1JlcG9zaXRvcnkuQXNzZXJ0ZWRDaGFsbGVuZ2UuUHJvcGVydGllcy5kZXNjcmlwdGlvbiwgQXJnVmlld3NSZXBvc2l0b3J5LlNXVF9LSU5EKSwgbnVsbCk7IC8vJE5PTi1OTFMtMSQKCQkvLyBTdGFydCBvZiB1c2VyIGNvZGUgZm9yIGNyZWF0ZURlc2NyaXB0aW9uVGV4dAoKCQkvLyBFbmQgb2YgdXNlciBjb2RlCgkJcmV0dXJuIHBhcmVudDsKCX0KCgkKCXByb3RlY3RlZCBDb21wb3NpdGUgY3JlYXRlQ29udGVudFRleHQoQ29tcG9zaXRlIHBhcmVudCkgewoJCWNyZWF0ZURlc2NyaXB0aW9uKHBhcmVudCwgQXJnVmlld3NSZXBvc2l0b3J5LkFzc2VydGVkQ2hhbGxlbmdlLlByb3BlcnRpZXMuY29udGVudCwgQXJnTWVzc2FnZXMuQXNzZXJ0ZWRDaGFsbGVuZ2VQcm9wZXJ0aWVzRWRpdGlvblBhcnRfQ29udGVudExhYmVsKTsKCQljb250ZW50ID0gU1dUVXRpbHMuY3JlYXRlU2Nyb2xsYWJsZVRleHQocGFyZW50LCBTV1QuQk9SREVSKTsKCQlHcmlkRGF0YSBjb250ZW50RGF0YSA9IG5ldyBHcmlkRGF0YShHcmlkRGF0YS5GSUxMX0hPUklaT05UQUwpOwoJCWNvbnRlbnQuc2V0TGF5b3V0RGF0YShjb250ZW50RGF0YSk7CgkJY29udGVudC5hZGRGb2N1c0xpc3RlbmVyKG5ldyBGb2N1c0FkYXB0ZXIoKSB7CgoJCQkvKioKCQkJICoge0Bpbmhlcml0RG9jfQoJCQkgKiAKCQkJICogQHNlZSBvcmcuZWNsaXBzZS5zd3QuZXZlbnRzLkZvY3VzQWRhcHRlciNmb2N1c0xvc3Qob3JnLmVjbGlwc2Uuc3d0LmV2ZW50cy5Gb2N1c0V2ZW50KQoJCQkgKiAKCQkJICovCgkJCUBPdmVycmlkZQoJCQlAU3VwcHJlc3NXYXJuaW5ncygic3ludGhldGljLWFjY2VzcyIpCgkJCXB1YmxpYyB2b2lkIGZvY3VzTG9zdChGb2N1c0V2ZW50IGUpIHsKCQkJCWlmIChwcm9wZXJ0aWVzRWRpdGlvbkNvbXBvbmVudCAhPSBudWxsKQoJCQkJCXByb3BlcnRpZXNFZGl0aW9uQ29tcG9uZW50LmZpcmVQcm9wZXJ0aWVzQ2hhbmdlZChuZXcgUHJvcGVydGllc0VkaXRpb25FdmVudChBc3NlcnRlZENoYWxsZW5nZVByb3BlcnRpZXNFZGl0aW9uUGFydEltcGwudGhpcywgQXJnVmlld3NSZXBvc2l0b3J5LkFzc2VydGVkQ2hhbGxlbmdlLlByb3BlcnRpZXMuY29udGVudCwgUHJvcGVydGllc0VkaXRpb25FdmVudC5DT01NSVQsIFByb3BlcnRpZXNFZGl0aW9uRXZlbnQuU0VULCBudWxsLCBjb250ZW50LmdldFRleHQoKSkpOwoJCQl9CgoJCX0pOwoJCWNvbnRlbnQuYWRkS2V5TGlzdGVuZXIobmV3IEtleUFkYXB0ZXIoKSB7CgoJCQkvKioKCQkJICoge0Bpbmhlcml0RG9jfQoJCQkgKiAKCQkJICogQHNlZSBvcmcuZWNsaXBzZS5zd3QuZXZlbnRzLktleUFkYXB0ZXIja2V5UHJlc3NlZChvcmcuZWNsaXBzZS5zd3QuZXZlbnRzLktleUV2ZW50KQoJCQkgKiAKCQkJICovCgkJCUBPdmVycmlkZQoJCQlAU3VwcHJlc3NXYXJuaW5ncygic3ludGhldGljLWFjY2VzcyIpCgkJCXB1YmxpYyB2b2lkIGtleVByZXNzZWQoS2V5RXZlbnQgZSkgewoJCQkJaWYgKGUuY2hhcmFjdGVyID09IFNXVC5DUikgewoJCQkJCWlmIChwcm9wZXJ0aWVzRWRpdGlvbkNvbXBvbmVudCAhPSBudWxsKQoJCQkJCQlwcm9wZXJ0aWVzRWRpdGlvbkNvbXBvbmVudC5maXJlUHJvcGVydGllc0NoYW5nZWQobmV3IFByb3BlcnRpZXNFZGl0aW9uRXZlbnQoQXNzZXJ0ZWRDaGFsbGVuZ2VQcm9wZXJ0aWVzRWRpdGlvblBhcnRJbXBsLnRoaXMsIEFyZ1ZpZXdzUmVwb3NpdG9yeS5Bc3NlcnRlZENoYWxsZW5nZS5Qcm9wZXJ0aWVzLmNvbnRlbnQsIFByb3BlcnRpZXNFZGl0aW9uRXZlbnQuQ09NTUlULCBQcm9wZXJ0aWVzRWRpdGlvbkV2ZW50LlNFVCwgbnVsbCwgY29udGVudC5nZXRUZXh0KCkpKTsKCQkJCX0KCQkJfQoKCQl9KTsKCQlFZGl0aW5nVXRpbHMuc2V0SUQoY29udGVudCwgQXJnVmlld3NSZXBvc2l0b3J5LkFzc2VydGVkQ2hhbGxlbmdlLlByb3BlcnRpZXMuY29udGVudCk7CgkJRWRpdGluZ1V0aWxzLnNldEVFRnR5cGUoY29udGVudCwgImVlZjo6VGV4dCIpOyAvLyROT04tTkxTLTEkCgkJU1dUVXRpbHMuY3JlYXRlSGVscEJ1dHRvbihwYXJlbnQsIHByb3BlcnRpZXNFZGl0aW9uQ29tcG9uZW50LmdldEhlbHBDb250ZW50KEFyZ1ZpZXdzUmVwb3NpdG9yeS5Bc3NlcnRlZENoYWxsZW5nZS5Qcm9wZXJ0aWVzLmNvbnRlbnQsIEFyZ1ZpZXdzUmVwb3NpdG9yeS5TV1RfS0lORCksIG51bGwpOyAvLyROT04tTkxTLTEkCgkJLy8gU3RhcnQgb2YgdXNlciBjb2RlIGZvciBjcmVhdGVDb250ZW50VGV4dAoKCQkvLyBFbmQgb2YgdXNlciBjb2RlCgkJcmV0dXJuIHBhcmVudDsKCX0KCgkvKioKCSAqIAoJICovCglwcm90ZWN0ZWQgQ29tcG9zaXRlIGNyZWF0ZVNvdXJjZUFkdmFuY2VkUmVmZXJlbmNlc1RhYmxlKENvbXBvc2l0ZSBwYXJlbnQpIHsKCQlTdHJpbmcgbGFiZWwgPSBnZXREZXNjcmlwdGlvbihBcmdWaWV3c1JlcG9zaXRvcnkuQXNzZXJ0ZWRDaGFsbGVuZ2UuUHJvcGVydGllcy5zb3VyY2UsIEFyZ01lc3NhZ2VzLkFzc2VydGVkQ2hhbGxlbmdlUHJvcGVydGllc0VkaXRpb25QYXJ0X1NvdXJjZUxhYmVsKTsJCSAKCQl0aGlzLnNvdXJjZSA9IG5ldyBSZWZlcmVuY2VzVGFibGUobGFiZWwsIG5ldyBSZWZlcmVuY2VzVGFibGVMaXN0ZW5lcigpIHsKCQkJcHVibGljIHZvaWQgaGFuZGxlQWRkKCkgeyBhZGRTb3VyY2UoKTsgfQoJCQlwdWJsaWMgdm9pZCBoYW5kbGVFZGl0KEVPYmplY3QgZWxlbWVudCkgeyBlZGl0U291cmNlKGVsZW1lbnQpOyB9CgkJCXB1YmxpYyB2b2lkIGhhbmRsZU1vdmUoRU9iamVjdCBlbGVtZW50LCBpbnQgb2xkSW5kZXgsIGludCBuZXdJbmRleCkgeyBtb3ZlU291cmNlKGVsZW1lbnQsIG9sZEluZGV4LCBuZXdJbmRleCk7IH0KCQkJcHVibGljIHZvaWQgaGFuZGxlUmVtb3ZlKEVPYmplY3QgZWxlbWVudCkgeyByZW1vdmVGcm9tU291cmNlKGVsZW1lbnQpOyB9CgkJCXB1YmxpYyB2b2lkIG5hdmlnYXRlVG8oRU9iamVjdCBlbGVtZW50KSB7IH0KCQl9KTsKCQl0aGlzLnNvdXJjZS5zZXRIZWxwVGV4dChwcm9wZXJ0aWVzRWRpdGlvbkNvbXBvbmVudC5nZXRIZWxwQ29udGVudChBcmdWaWV3c1JlcG9zaXRvcnkuQXNzZXJ0ZWRDaGFsbGVuZ2UuUHJvcGVydGllcy5zb3VyY2UsIEFyZ1ZpZXdzUmVwb3NpdG9yeS5TV1RfS0lORCkpOwoJCXRoaXMuc291cmNlLmNyZWF0ZUNvbnRyb2xzKHBhcmVudCk7CgkJdGhpcy5zb3VyY2UuYWRkU2VsZWN0aW9uTGlzdGVuZXIobmV3IFNlbGVjdGlvbkFkYXB0ZXIoKSB7CgkJCQoJCQlwdWJsaWMgdm9pZCB3aWRnZXRTZWxlY3RlZChTZWxlY3Rpb25FdmVudCBlKSB7CgkJCQlpZiAoZS5pdGVtICE9IG51bGwgJiYgZS5pdGVtLmdldERhdGEoKSBpbnN0YW5jZW9mIEVPYmplY3QpIHsKCQkJCQlwcm9wZXJ0aWVzRWRpdGlvbkNvbXBvbmVudC5maXJlUHJvcGVydGllc0NoYW5nZWQobmV3IFByb3BlcnRpZXNFZGl0aW9uRXZlbnQoQXNzZXJ0ZWRDaGFsbGVuZ2VQcm9wZXJ0aWVzRWRpdGlvblBhcnRJbXBsLnRoaXMsIEFyZ1ZpZXdzUmVwb3NpdG9yeS5Bc3NlcnRlZENoYWxsZW5nZS5Qcm9wZXJ0aWVzLnNvdXJjZSwgUHJvcGVydGllc0VkaXRpb25FdmVudC5DSEFOR0UsIFByb3BlcnRpZXNFZGl0aW9uRXZlbnQuU0VMRUNUSU9OX0NIQU5HRUQsIG51bGwsIGUuaXRlbS5nZXREYXRhKCkpKTsKCQkJCX0KCQkJfQoJCQkKCQl9KTsKCQlHcmlkRGF0YSBzb3VyY2VEYXRhID0gbmV3IEdyaWREYXRhKEdyaWREYXRhLkZJTExfSE9SSVpPTlRBTCk7CgkJc291cmNlRGF0YS5ob3Jpem9udGFsU3BhbiA9IDM7CgkJdGhpcy5zb3VyY2Uuc2V0TGF5b3V0RGF0YShzb3VyY2VEYXRhKTsKCQl0aGlzLnNvdXJjZS5kaXNhYmxlTW92ZSgpOwoJCXNvdXJjZS5zZXRJRChBcmdWaWV3c1JlcG9zaXRvcnkuQXNzZXJ0ZWRDaGFsbGVuZ2UuUHJvcGVydGllcy5zb3VyY2UpOwoJCXNvdXJjZS5zZXRFRUZUeXBlKCJlZWY6OkFkdmFuY2VkUmVmZXJlbmNlc1RhYmxlIik7IC8vJE5PTi1OTFMtMSQKCQlyZXR1cm4gcGFyZW50OwoJfQoKCS8qKgoJICogCgkgKi8KCXByb3RlY3RlZCB2b2lkIGFkZFNvdXJjZSgpIHsKCQlUYWJFbGVtZW50VHJlZVNlbGVjdGlvbkRpYWxvZyBkaWFsb2cgPSBuZXcgVGFiRWxlbWVudFRyZWVTZWxlY3Rpb25EaWFsb2coc291cmNlLmdldElucHV0KCksIHNvdXJjZUZpbHRlcnMsIHNvdXJjZUJ1c2luZXNzRmlsdGVycywKCQkic291cmNlIiwgcHJvcGVydGllc0VkaXRpb25Db21wb25lbnQuZ2V0RWRpdGluZ0NvbnRleHQoKS5nZXRBZGFwdGVyRmFjdG9yeSgpLCBjdXJyZW50LmVSZXNvdXJjZSgpKSB7CgkJCUBPdmVycmlkZQoJCQlwdWJsaWMgdm9pZCBwcm9jZXNzKElTdHJ1Y3R1cmVkU2VsZWN0aW9uIHNlbGVjdGlvbikgewoJCQkJZm9yIChJdGVyYXRvcjw/PiBpdGVyID0gc2VsZWN0aW9uLml0ZXJhdG9yKCk7IGl0ZXIuaGFzTmV4dCgpOykgewoJCQkJCUVPYmplY3QgZWxlbSA9IChFT2JqZWN0KSBpdGVyLm5leHQoKTsKCQkJCQlwcm9wZXJ0aWVzRWRpdGlvbkNvbXBvbmVudC5maXJlUHJvcGVydGllc0NoYW5nZWQobmV3IFByb3BlcnRpZXNFZGl0aW9uRXZlbnQoQXNzZXJ0ZWRDaGFsbGVuZ2VQcm9wZXJ0aWVzRWRpdGlvblBhcnRJbXBsLnRoaXMsIEFyZ1ZpZXdzUmVwb3NpdG9yeS5Bc3NlcnRlZENoYWxsZW5nZS5Qcm9wZXJ0aWVzLnNvdXJjZSwKCQkJCQkJUHJvcGVydGllc0VkaXRpb25FdmVudC5DT01NSVQsIFByb3BlcnRpZXNFZGl0aW9uRXZlbnQuQURELCBudWxsLCBlbGVtKSk7CgkJCQl9CgkJCQlzb3VyY2UucmVmcmVzaCgpOwoJCQl9CgkJfTsKCQlkaWFsb2cub3BlbigpOwoJfQoKCS8qKgoJICogCgkgKi8KCXByb3RlY3RlZCB2b2lkIG1vdmVTb3VyY2UoRU9iamVjdCBlbGVtZW50LCBpbnQgb2xkSW5kZXgsIGludCBuZXdJbmRleCkgewoJCXByb3BlcnRpZXNFZGl0aW9uQ29tcG9uZW50LmZpcmVQcm9wZXJ0aWVzQ2hhbmdlZChuZXcgUHJvcGVydGllc0VkaXRpb25FdmVudChBc3NlcnRlZENoYWxsZW5nZVByb3BlcnRpZXNFZGl0aW9uUGFydEltcGwudGhpcywgQXJnVmlld3NSZXBvc2l0b3J5LkFzc2VydGVkQ2hhbGxlbmdlLlByb3BlcnRpZXMuc291cmNlLCBQcm9wZXJ0aWVzRWRpdGlvbkV2ZW50LkNPTU1JVCwgUHJvcGVydGllc0VkaXRpb25FdmVudC5NT1ZFLCBlbGVtZW50LCBuZXdJbmRleCkpOwoJCXNvdXJjZS5yZWZyZXNoKCk7Cgl9CgoJLyoqCgkgKiAKCSAqLwoJcHJvdGVjdGVkIHZvaWQgcmVtb3ZlRnJvbVNvdXJjZShFT2JqZWN0IGVsZW1lbnQpIHsKCQlwcm9wZXJ0aWVzRWRpdGlvbkNvbXBvbmVudC5maXJlUHJvcGVydGllc0NoYW5nZWQobmV3IFByb3BlcnRpZXNFZGl0aW9uRXZlbnQoQXNzZXJ0ZWRDaGFsbGVuZ2VQcm9wZXJ0aWVzRWRpdGlvblBhcnRJbXBsLnRoaXMsIEFyZ1ZpZXdzUmVwb3NpdG9yeS5Bc3NlcnRlZENoYWxsZW5nZS5Qcm9wZXJ0aWVzLnNvdXJjZSwgUHJvcGVydGllc0VkaXRpb25FdmVudC5DT01NSVQsIFByb3BlcnRpZXNFZGl0aW9uRXZlbnQuUkVNT1ZFLCBudWxsLCBlbGVtZW50KSk7CgkJc291cmNlLnJlZnJlc2goKTsKCX0KCgkvKioKCSAqIAoJICovCglwcm90ZWN0ZWQgdm9pZCBlZGl0U291cmNlKEVPYmplY3QgZWxlbWVudCkgewoJCUVPYmplY3RQcm9wZXJ0aWVzRWRpdGlvbkNvbnRleHQgY29udGV4dCA9IG5ldyBFT2JqZWN0UHJvcGVydGllc0VkaXRpb25Db250ZXh0KHByb3BlcnRpZXNFZGl0aW9uQ29tcG9uZW50LmdldEVkaXRpbmdDb250ZXh0KCksIHByb3BlcnRpZXNFZGl0aW9uQ29tcG9uZW50LCBlbGVtZW50LCBhZGFwdGVyRmFjdG9yeSk7CgkJUHJvcGVydGllc0VkaXRpbmdQcm92aWRlciBwcm92aWRlciA9IChQcm9wZXJ0aWVzRWRpdGluZ1Byb3ZpZGVyKWFkYXB0ZXJGYWN0b3J5LmFkYXB0KGVsZW1lbnQsIFByb3BlcnRpZXNFZGl0aW5nUHJvdmlkZXIuY2xhc3MpOwoJCWlmIChwcm92aWRlciAhPSBudWxsKSB7CgkJCVByb3BlcnRpZXNFZGl0aW5nUG9saWN5IHBvbGljeSA9IHByb3ZpZGVyLmdldFBvbGljeShjb250ZXh0KTsKCQkJaWYgKHBvbGljeSAhPSBudWxsKSB7CgkJCQlwb2xpY3kuZXhlY3V0ZSgpOwoJCQkJc291cmNlLnJlZnJlc2goKTsKCQkJfQoJCX0KCX0KCgkvKioKCSAqIAoJICovCglwcm90ZWN0ZWQgQ29tcG9zaXRlIGNyZWF0ZVRhcmdldEFkdmFuY2VkUmVmZXJlbmNlc1RhYmxlKENvbXBvc2l0ZSBwYXJlbnQpIHsKCQlTdHJpbmcgbGFiZWwgPSBnZXREZXNjcmlwdGlvbihBcmdWaWV3c1JlcG9zaXRvcnkuQXNzZXJ0ZWRDaGFsbGVuZ2UuUHJvcGVydGllcy50YXJnZXQsIEFyZ01lc3NhZ2VzLkFzc2VydGVkQ2hhbGxlbmdlUHJvcGVydGllc0VkaXRpb25QYXJ0X1RhcmdldExhYmVsKTsJCSAKCQl0aGlzLnRhcmdldCA9IG5ldyBSZWZlcmVuY2VzVGFibGUobGFiZWwsIG5ldyBSZWZlcmVuY2VzVGFibGVMaXN0ZW5lcigpIHsKCQkJcHVibGljIHZvaWQgaGFuZGxlQWRkKCkgeyBhZGRUYXJnZXQoKTsgfQoJCQlwdWJsaWMgdm9pZCBoYW5kbGVFZGl0KEVPYmplY3QgZWxlbWVudCkgeyBlZGl0VGFyZ2V0KGVsZW1lbnQpOyB9CgkJCXB1YmxpYyB2b2lkIGhhbmRsZU1vdmUoRU9iamVjdCBlbGVtZW50LCBpbnQgb2xkSW5kZXgsIGludCBuZXdJbmRleCkgeyBtb3ZlVGFyZ2V0KGVsZW1lbnQsIG9sZEluZGV4LCBuZXdJbmRleCk7IH0KCQkJcHVibGljIHZvaWQgaGFuZGxlUmVtb3ZlKEVPYmplY3QgZWxlbWVudCkgeyByZW1vdmVGcm9tVGFyZ2V0KGVsZW1lbnQpOyB9CgkJCXB1YmxpYyB2b2lkIG5hdmlnYXRlVG8oRU9iamVjdCBlbGVtZW50KSB7IH0KCQl9KTsKCQl0aGlzLnRhcmdldC5zZXRIZWxwVGV4dChwcm9wZXJ0aWVzRWRpdGlvbkNvbXBvbmVudC5nZXRIZWxwQ29udGVudChBcmdWaWV3c1JlcG9zaXRvcnkuQXNzZXJ0ZWRDaGFsbGVuZ2UuUHJvcGVydGllcy50YXJnZXQsIEFyZ1ZpZXdzUmVwb3NpdG9yeS5TV1RfS0lORCkpOwoJCXRoaXMudGFyZ2V0LmNyZWF0ZUNvbnRyb2xzKHBhcmVudCk7CgkJdGhpcy50YXJnZXQuYWRkU2VsZWN0aW9uTGlzdGVuZXIobmV3IFNlbGVjdGlvbkFkYXB0ZXIoKSB7CgkJCQoJCQlwdWJsaWMgdm9pZCB3aWRnZXRTZWxlY3RlZChTZWxlY3Rpb25FdmVudCBlKSB7CgkJCQlpZiAoZS5pdGVtICE9IG51bGwgJiYgZS5pdGVtLmdldERhdGEoKSBpbnN0YW5jZW9mIEVPYmplY3QpIHsKCQkJCQlwcm9wZXJ0aWVzRWRpdGlvbkNvbXBvbmVudC5maXJlUHJvcGVydGllc0NoYW5nZWQobmV3IFByb3BlcnRpZXNFZGl0aW9uRXZlbnQoQXNzZXJ0ZWRDaGFsbGVuZ2VQcm9wZXJ0aWVzRWRpdGlvblBhcnRJbXBsLnRoaXMsIEFyZ1ZpZXdzUmVwb3NpdG9yeS5Bc3NlcnRlZENoYWxsZW5nZS5Qcm9wZXJ0aWVzLnRhcmdldCwgUHJvcGVydGllc0VkaXRpb25FdmVudC5DSEFOR0UsIFByb3BlcnRpZXNFZGl0aW9uRXZlbnQuU0VMRUNUSU9OX0NIQU5HRUQsIG51bGwsIGUuaXRlbS5nZXREYXRhKCkpKTsKCQkJCX0KCQkJfQoJCQkKCQl9KTsKCQlHcmlkRGF0YSB0YXJnZXREYXRhID0gbmV3IEdyaWREYXRhKEdyaWREYXRhLkZJTExfSE9SSVpPTlRBTCk7CgkJdGFyZ2V0RGF0YS5ob3Jpem9udGFsU3BhbiA9IDM7CgkJdGhpcy50YXJnZXQuc2V0TGF5b3V0RGF0YSh0YXJnZXREYXRhKTsKCQl0aGlzLnRhcmdldC5kaXNhYmxlTW92ZSgpOwoJCXRhcmdldC5zZXRJRChBcmdWaWV3c1JlcG9zaXRvcnkuQXNzZXJ0ZWRDaGFsbGVuZ2UuUHJvcGVydGllcy50YXJnZXQpOwoJCXRhcmdldC5zZXRFRUZUeXBlKCJlZWY6OkFkdmFuY2VkUmVmZXJlbmNlc1RhYmxlIik7IC8vJE5PTi1OTFMtMSQKCQlyZXR1cm4gcGFyZW50OwoJfQoKCS8qKgoJICogCgkgKi8KCXByb3RlY3RlZCB2b2lkIGFkZFRhcmdldCgpIHsKCQlUYWJFbGVtZW50VHJlZVNlbGVjdGlvbkRpYWxvZyBkaWFsb2cgPSBuZXcgVGFiRWxlbWVudFRyZWVTZWxlY3Rpb25EaWFsb2codGFyZ2V0LmdldElucHV0KCksIHRhcmdldEZpbHRlcnMsIHRhcmdldEJ1c2luZXNzRmlsdGVycywKCQkidGFyZ2V0IiwgcHJvcGVydGllc0VkaXRpb25Db21wb25lbnQuZ2V0RWRpdGluZ0NvbnRleHQoKS5nZXRBZGFwdGVyRmFjdG9yeSgpLCBjdXJyZW50LmVSZXNvdXJjZSgpKSB7CgkJCUBPdmVycmlkZQoJCQlwdWJsaWMgdm9pZCBwcm9jZXNzKElTdHJ1Y3R1cmVkU2VsZWN0aW9uIHNlbGVjdGlvbikgewoJCQkJZm9yIChJdGVyYXRvcjw/PiBpdGVyID0gc2VsZWN0aW9uLml0ZXJhdG9yKCk7IGl0ZXIuaGFzTmV4dCgpOykgewoJCQkJCUVPYmplY3QgZWxlbSA9IChFT2JqZWN0KSBpdGVyLm5leHQoKTsKCQkJCQlwcm9wZXJ0aWVzRWRpdGlvbkNvbXBvbmVudC5maXJlUHJvcGVydGllc0NoYW5nZWQobmV3IFByb3BlcnRpZXNFZGl0aW9uRXZlbnQoQXNzZXJ0ZWRDaGFsbGVuZ2VQcm9wZXJ0aWVzRWRpdGlvblBhcnRJbXBsLnRoaXMsIEFyZ1ZpZXdzUmVwb3NpdG9yeS5Bc3NlcnRlZENoYWxsZW5nZS5Qcm9wZXJ0aWVzLnRhcmdldCwKCQkJCQkJUHJvcGVydGllc0VkaXRpb25FdmVudC5DT01NSVQsIFByb3BlcnRpZXNFZGl0aW9uRXZlbnQuQURELCBudWxsLCBlbGVtKSk7CgkJCQl9CgkJCQl0YXJnZXQucmVmcmVzaCgpOwoJCQl9CgkJfTsKCQlkaWFsb2cub3BlbigpOwoJfQoKCS8qKgoJICogCgkgKi8KCXByb3RlY3RlZCB2b2lkIG1vdmVUYXJnZXQoRU9iamVjdCBlbGVtZW50LCBpbnQgb2xkSW5kZXgsIGludCBuZXdJbmRleCkgewoJCXByb3BlcnRpZXNFZGl0aW9uQ29tcG9uZW50LmZpcmVQcm9wZXJ0aWVzQ2hhbmdlZChuZXcgUHJvcGVydGllc0VkaXRpb25FdmVudChBc3NlcnRlZENoYWxsZW5nZVByb3BlcnRpZXNFZGl0aW9uUGFydEltcGwudGhpcywgQXJnVmlld3NSZXBvc2l0b3J5LkFzc2VydGVkQ2hhbGxlbmdlLlByb3BlcnRpZXMudGFyZ2V0LCBQcm9wZXJ0aWVzRWRpdGlvbkV2ZW50LkNPTU1JVCwgUHJvcGVydGllc0VkaXRpb25FdmVudC5NT1ZFLCBlbGVtZW50LCBuZXdJbmRleCkpOwoJCXRhcmdldC5yZWZyZXNoKCk7Cgl9CgoJLyoqCgkgKiAKCSAqLwoJcHJvdGVjdGVkIHZvaWQgcmVtb3ZlRnJvbVRhcmdldChFT2JqZWN0IGVsZW1lbnQpIHsKCQlwcm9wZXJ0aWVzRWRpdGlvbkNvbXBvbmVudC5maXJlUHJvcGVydGllc0NoYW5nZWQobmV3IFByb3BlcnRpZXNFZGl0aW9uRXZlbnQoQXNzZXJ0ZWRDaGFsbGVuZ2VQcm9wZXJ0aWVzRWRpdGlvblBhcnRJbXBsLnRoaXMsIEFyZ1ZpZXdzUmVwb3NpdG9yeS5Bc3NlcnRlZENoYWxsZW5nZS5Qcm9wZXJ0aWVzLnRhcmdldCwgUHJvcGVydGllc0VkaXRpb25FdmVudC5DT01NSVQsIFByb3BlcnRpZXNFZGl0aW9uRXZlbnQuUkVNT1ZFLCBudWxsLCBlbGVtZW50KSk7CgkJdGFyZ2V0LnJlZnJlc2goKTsKCX0KCgkvKioKCSAqIAoJICovCglwcm90ZWN0ZWQgdm9pZCBlZGl0VGFyZ2V0KEVPYmplY3QgZWxlbWVudCkgewoJCUVPYmplY3RQcm9wZXJ0aWVzRWRpdGlvbkNvbnRleHQgY29udGV4dCA9IG5ldyBFT2JqZWN0UHJvcGVydGllc0VkaXRpb25Db250ZXh0KHByb3BlcnRpZXNFZGl0aW9uQ29tcG9uZW50LmdldEVkaXRpbmdDb250ZXh0KCksIHByb3BlcnRpZXNFZGl0aW9uQ29tcG9uZW50LCBlbGVtZW50LCBhZGFwdGVyRmFjdG9yeSk7CgkJUHJvcGVydGllc0VkaXRpbmdQcm92aWRlciBwcm92aWRlciA9IChQcm9wZXJ0aWVzRWRpdGluZ1Byb3ZpZGVyKWFkYXB0ZXJGYWN0b3J5LmFkYXB0KGVsZW1lbnQsIFByb3BlcnRpZXNFZGl0aW5nUHJvdmlkZXIuY2xhc3MpOwoJCWlmIChwcm92aWRlciAhPSBudWxsKSB7CgkJCVByb3BlcnRpZXNFZGl0aW5nUG9saWN5IHBvbGljeSA9IHByb3ZpZGVyLmdldFBvbGljeShjb250ZXh0KTsKCQkJaWYgKHBvbGljeSAhPSBudWxsKSB7CgkJCQlwb2xpY3kuZXhlY3V0ZSgpOwoJCQkJdGFyZ2V0LnJlZnJlc2goKTsKCQkJfQoJCX0KCX0KCgoJLyoqCgkgKiB7QGluaGVyaXREb2N9CgkgKiAKCSAqIEBzZWUgb3JnLmVjbGlwc2UuZW1mLmVlZi5ydW50aW1lLmFwaS5ub3RpZnkuSVByb3BlcnRpZXNFZGl0aW9uTGlzdGVuZXIjZmlyZVByb3BlcnRpZXNDaGFuZ2VkKG9yZy5lY2xpcHNlLmVtZi5lZWYucnVudGltZS5hcGkubm90aWZ5LklQcm9wZXJ0aWVzRWRpdGlvbkV2ZW50KQoJICogCgkgKi8KCXB1YmxpYyB2b2lkIGZpcmVQcm9wZXJ0aWVzQ2hhbmdlZChJUHJvcGVydGllc0VkaXRpb25FdmVudCBldmVudCkgewoJCS8vIFN0YXJ0IG9mIHVzZXIgY29kZSBmb3IgdGFiIHN5bmNocm9uaXphdGlvbgoJCQoJCS8vIEVuZCBvZiB1c2VyIGNvZGUKCX0KCgkvKioKCSAqIHtAaW5oZXJpdERvY30KCSAqIAoJICogQHNlZSBvcmcuZWNsaXBzZS5vcGVuY2VydC5zYW0uYXJnLmFyZy5wYXJ0cy5Bc3NlcnRlZENoYWxsZW5nZVByb3BlcnRpZXNFZGl0aW9uUGFydCNnZXRJZCgpCgkgKiAKCSAqLwoJcHVibGljIFN0cmluZyBnZXRJZCgpIHsKCQlyZXR1cm4gaWQuZ2V0VGV4dCgpOwoJfQoKCS8qKgoJICoge0Bpbmhlcml0RG9jfQoJICogCgkgKiBAc2VlIG9yZy5lY2xpcHNlLm9wZW5jZXJ0LnNhbS5hcmcuYXJnLnBhcnRzLkFzc2VydGVkQ2hhbGxlbmdlUHJvcGVydGllc0VkaXRpb25QYXJ0I3NldElkKFN0cmluZyBuZXdWYWx1ZSkKCSAqIAoJICovCglwdWJsaWMgdm9pZCBzZXRJZChTdHJpbmcgbmV3VmFsdWUpIHsKCQlpZiAobmV3VmFsdWUgIT0gbnVsbCkgewoJCQlpZC5zZXRUZXh0KG5ld1ZhbHVlKTsKCQl9IGVsc2UgewoJCQlpZC5zZXRUZXh0KCIiKTsgLy8kTk9OLU5MUy0xJAoJCX0KCQlib29sZWFuIGVlZkVsZW1lbnRFZGl0b3JSZWFkT25seVN0YXRlID0gaXNSZWFkT25seShBcmdWaWV3c1JlcG9zaXRvcnkuQXNzZXJ0ZWRDaGFsbGVuZ2UuUHJvcGVydGllcy5pZCk7CgkJaWYgKGVlZkVsZW1lbnRFZGl0b3JSZWFkT25seVN0YXRlICYmIGlkLmlzRW5hYmxlZCgpKSB7CgkJCWlkLnNldEVuYWJsZWQoZmFsc2UpOwoJCQlpZC5zZXRUb29sVGlwVGV4dChBcmdNZXNzYWdlcy5Bc3NlcnRlZENoYWxsZW5nZV9SZWFkT25seSk7CgkJfSBlbHNlIGlmICghZWVmRWxlbWVudEVkaXRvclJlYWRPbmx5U3RhdGUgJiYgIWlkLmlzRW5hYmxlZCgpKSB7CgkJCWlkLnNldEVuYWJsZWQodHJ1ZSk7CgkJfQkKCQkKCX0KCgkvKioKCSAqIHtAaW5oZXJpdERvY30KCSAqIAoJICogQHNlZSBvcmcuZWNsaXBzZS5vcGVuY2VydC5zYW0uYXJnLmFyZy5wYXJ0cy5Bc3NlcnRlZENoYWxsZW5nZVByb3BlcnRpZXNFZGl0aW9uUGFydCNnZXROYW1lKCkKCSAqIAoJICovCglwdWJsaWMgU3RyaW5nIGdldE5hbWUoKSB7CgkJcmV0dXJuIG5hbWUuZ2V0VGV4dCgpOwoJfQoKCS8qKgoJICoge0Bpbmhlcml0RG9jfQoJICogCgkgKiBAc2VlIG9yZy5lY2xpcHNlLm9wZW5jZXJ0LnNhbS5hcmcuYXJnLnBhcnRzLkFzc2VydGVkQ2hhbGxlbmdlUHJvcGVydGllc0VkaXRpb25QYXJ0I3NldE5hbWUoU3RyaW5nIG5ld1ZhbHVlKQoJICogCgkgKi8KCXB1YmxpYyB2b2lkIHNldE5hbWUoU3RyaW5nIG5ld1ZhbHVlKSB7CgkJaWYgKG5ld1ZhbHVlICE9IG51bGwpIHsKCQkJbmFtZS5zZXRUZXh0KG5ld1ZhbHVlKTsKCQl9IGVsc2UgewoJCQluYW1lLnNldFRleHQoIiIpOyAvLyROT04tTkxTLTEkCgkJfQoJCWJvb2xlYW4gZWVmRWxlbWVudEVkaXRvclJlYWRPbmx5U3RhdGUgPSBpc1JlYWRPbmx5KEFyZ1ZpZXdzUmVwb3NpdG9yeS5Bc3NlcnRlZENoYWxsZW5nZS5Qcm9wZXJ0aWVzLm5hbWUpOwoJCWlmIChlZWZFbGVtZW50RWRpdG9yUmVhZE9ubHlTdGF0ZSAmJiBuYW1lLmlzRW5hYmxlZCgpKSB7CgkJCW5hbWUuc2V0RW5hYmxlZChmYWxzZSk7CgkJCW5hbWUuc2V0VG9vbFRpcFRleHQoQXJnTWVzc2FnZXMuQXNzZXJ0ZWRDaGFsbGVuZ2VfUmVhZE9ubHkpOwoJCX0gZWxzZSBpZiAoIWVlZkVsZW1lbnRFZGl0b3JSZWFkT25seVN0YXRlICYmICFuYW1lLmlzRW5hYmxlZCgpKSB7CgkJCW5hbWUuc2V0RW5hYmxlZCh0cnVlKTsKCQl9CQoJCQoJfQoKCS8qKgoJICoge0Bpbmhlcml0RG9jfQoJICogCgkgKiBAc2VlIG9yZy5lY2xpcHNlLm9wZW5jZXJ0LnNhbS5hcmcuYXJnLnBhcnRzLkFzc2VydGVkQ2hhbGxlbmdlUHJvcGVydGllc0VkaXRpb25QYXJ0I2dldERlc2NyaXB0aW9uKCkKCSAqIAoJICovCglwdWJsaWMgU3RyaW5nIGdldERlc2NyaXB0aW9uKCkgewoJCXJldHVybiBkZXNjcmlwdGlvbi5nZXRUZXh0KCk7Cgl9CgoJLyoqCgkgKiB7QGluaGVyaXREb2N9CgkgKiAKCSAqIEBzZWUgb3JnLmVjbGlwc2Uub3BlbmNlcnQuc2FtLmFyZy5hcmcucGFydHMuQXNzZXJ0ZWRDaGFsbGVuZ2VQcm9wZXJ0aWVzRWRpdGlvblBhcnQjc2V0RGVzY3JpcHRpb24oU3RyaW5nIG5ld1ZhbHVlKQoJICogCgkgKi8KCXB1YmxpYyB2b2lkIHNldERlc2NyaXB0aW9uKFN0cmluZyBuZXdWYWx1ZSkgewoJCWlmIChuZXdWYWx1ZSAhPSBudWxsKSB7CgkJCWRlc2NyaXB0aW9uLnNldFRleHQobmV3VmFsdWUpOwoJCX0gZWxzZSB7CgkJCWRlc2NyaXB0aW9uLnNldFRleHQoIiIpOyAvLyROT04tTkxTLTEkCgkJfQoJCWJvb2xlYW4gZWVmRWxlbWVudEVkaXRvclJlYWRPbmx5U3RhdGUgPSBpc1JlYWRPbmx5KEFyZ1ZpZXdzUmVwb3NpdG9yeS5Bc3NlcnRlZENoYWxsZW5nZS5Qcm9wZXJ0aWVzLmRlc2NyaXB0aW9uKTsKCQlpZiAoZWVmRWxlbWVudEVkaXRvclJlYWRPbmx5U3RhdGUgJiYgZGVzY3JpcHRpb24uaXNFbmFibGVkKCkpIHsKCQkJZGVzY3JpcHRpb24uc2V0RW5hYmxlZChmYWxzZSk7CgkJCWRlc2NyaXB0aW9uLnNldFRvb2xUaXBUZXh0KEFyZ01lc3NhZ2VzLkFzc2VydGVkQ2hhbGxlbmdlX1JlYWRPbmx5KTsKCQl9IGVsc2UgaWYgKCFlZWZFbGVtZW50RWRpdG9yUmVhZE9ubHlTdGF0ZSAmJiAhZGVzY3JpcHRpb24uaXNFbmFibGVkKCkpIHsKCQkJZGVzY3JpcHRpb24uc2V0RW5hYmxlZCh0cnVlKTsKCQl9CQoJCQoJfQoKCS8qKgoJICoge0Bpbmhlcml0RG9jfQoJICogCgkgKiBAc2VlIG9yZy5lY2xpcHNlLm9wZW5jZXJ0LnNhbS5hcmcuYXJnLnBhcnRzLkFzc2VydGVkQ2hhbGxlbmdlUHJvcGVydGllc0VkaXRpb25QYXJ0I2dldENvbnRlbnQoKQoJICogCgkgKi8KCXB1YmxpYyBTdHJpbmcgZ2V0Q29udGVudCgpIHsKCQlyZXR1cm4gY29udGVudC5nZXRUZXh0KCk7Cgl9CgoJLyoqCgkgKiB7QGluaGVyaXREb2N9CgkgKiAKCSAqIEBzZWUgb3JnLmVjbGlwc2Uub3BlbmNlcnQuc2FtLmFyZy5hcmcucGFydHMuQXNzZXJ0ZWRDaGFsbGVuZ2VQcm9wZXJ0aWVzRWRpdGlvblBhcnQjc2V0Q29udGVudChTdHJpbmcgbmV3VmFsdWUpCgkgKiAKCSAqLwoJcHVibGljIHZvaWQgc2V0Q29udGVudChTdHJpbmcgbmV3VmFsdWUpIHsKCQlpZiAobmV3VmFsdWUgIT0gbnVsbCkgewoJCQljb250ZW50LnNldFRleHQobmV3VmFsdWUpOwoJCX0gZWxzZSB7CgkJCWNvbnRlbnQuc2V0VGV4dCgiIik7IC8vJE5PTi1OTFMtMSQKCQl9CgkJYm9vbGVhbiBlZWZFbGVtZW50RWRpdG9yUmVhZE9ubHlTdGF0ZSA9IGlzUmVhZE9ubHkoQXJnVmlld3NSZXBvc2l0b3J5LkFzc2VydGVkQ2hhbGxlbmdlLlByb3BlcnRpZXMuY29udGVudCk7CgkJaWYgKGVlZkVsZW1lbnRFZGl0b3JSZWFkT25seVN0YXRlICYmIGNvbnRlbnQuaXNFbmFibGVkKCkpIHsKCQkJY29udGVudC5zZXRFbmFibGVkKGZhbHNlKTsKCQkJY29udGVudC5zZXRUb29sVGlwVGV4dChBcmdNZXNzYWdlcy5Bc3NlcnRlZENoYWxsZW5nZV9SZWFkT25seSk7CgkJfSBlbHNlIGlmICghZWVmRWxlbWVudEVkaXRvclJlYWRPbmx5U3RhdGUgJiYgIWNvbnRlbnQuaXNFbmFibGVkKCkpIHsKCQkJY29udGVudC5zZXRFbmFibGVkKHRydWUpOwoJCX0JCgkJCgl9CgoKCgkvKioKCSAqIHtAaW5oZXJpdERvY30KCSAqIAoJICogQHNlZSBvcmcuZWNsaXBzZS5vcGVuY2VydC5zYW0uYXJnLmFyZy5wYXJ0cy5Bc3NlcnRlZENoYWxsZW5nZVByb3BlcnRpZXNFZGl0aW9uUGFydCNpbml0U291cmNlKG9yZy5lY2xpcHNlLmVtZi5lZWYucnVudGltZS51aS53aWRnZXRzLnJlZmVyZW5jZXN0YWJsZS5SZWZlcmVuY2VzVGFibGVTZXR0aW5ncykKCSAqLwoJcHVibGljIHZvaWQgaW5pdFNvdXJjZShSZWZlcmVuY2VzVGFibGVTZXR0aW5ncyBzZXR0aW5ncykgewoJCWlmIChjdXJyZW50LmVSZXNvdXJjZSgpICE9IG51bGwgJiYgY3VycmVudC5lUmVzb3VyY2UoKS5nZXRSZXNvdXJjZVNldCgpICE9IG51bGwpCgkJCXRoaXMucmVzb3VyY2VTZXQgPSBjdXJyZW50LmVSZXNvdXJjZSgpLmdldFJlc291cmNlU2V0KCk7CgkJUmVmZXJlbmNlc1RhYmxlQ29udGVudFByb3ZpZGVyIGNvbnRlbnRQcm92aWRlciA9IG5ldyBSZWZlcmVuY2VzVGFibGVDb250ZW50UHJvdmlkZXIoKTsKCQlzb3VyY2Uuc2V0Q29udGVudFByb3ZpZGVyKGNvbnRlbnRQcm92aWRlcik7CgkJc291cmNlLnNldElucHV0KHNldHRpbmdzKTsKCQlib29sZWFuIGVlZkVsZW1lbnRFZGl0b3JSZWFkT25seVN0YXRlID0gaXNSZWFkT25seShBcmdWaWV3c1JlcG9zaXRvcnkuQXNzZXJ0ZWRDaGFsbGVuZ2UuUHJvcGVydGllcy5zb3VyY2UpOwoJCWlmIChlZWZFbGVtZW50RWRpdG9yUmVhZE9ubHlTdGF0ZSAmJiBzb3VyY2UuZ2V0VGFibGUoKS5pc0VuYWJsZWQoKSkgewoJCQlzb3VyY2Uuc2V0RW5hYmxlZChmYWxzZSk7CgkJCXNvdXJjZS5zZXRUb29sVGlwVGV4dChBcmdNZXNzYWdlcy5Bc3NlcnRlZENoYWxsZW5nZV9SZWFkT25seSk7CgkJfSBlbHNlIGlmICghZWVmRWxlbWVudEVkaXRvclJlYWRPbmx5U3RhdGUgJiYgIXNvdXJjZS5nZXRUYWJsZSgpLmlzRW5hYmxlZCgpKSB7CgkJCXNvdXJjZS5zZXRFbmFibGVkKHRydWUpOwoJCX0KCQkKCX0KCgkvKioKCSAqIHtAaW5oZXJpdERvY30KCSAqIAoJICogQHNlZSBvcmcuZWNsaXBzZS5vcGVuY2VydC5zYW0uYXJnLmFyZy5wYXJ0cy5Bc3NlcnRlZENoYWxsZW5nZVByb3BlcnRpZXNFZGl0aW9uUGFydCN1cGRhdGVTb3VyY2UoKQoJICogCgkgKi8KCXB1YmxpYyB2b2lkIHVwZGF0ZVNvdXJjZSgpIHsKCXNvdXJjZS5yZWZyZXNoKCk7Cn0KCgkvKioKCSAqIHtAaW5oZXJpdERvY30KCSAqIAoJICogQHNlZSBvcmcuZWNsaXBzZS5vcGVuY2VydC5zYW0uYXJnLmFyZy5wYXJ0cy5Bc3NlcnRlZENoYWxsZW5nZVByb3BlcnRpZXNFZGl0aW9uUGFydCNhZGRGaWx0ZXJTb3VyY2UoVmlld2VyRmlsdGVyIGZpbHRlcikKCSAqIAoJICovCglwdWJsaWMgdm9pZCBhZGRGaWx0ZXJUb1NvdXJjZShWaWV3ZXJGaWx0ZXIgZmlsdGVyKSB7CgkJc291cmNlRmlsdGVycy5hZGQoZmlsdGVyKTsKCX0KCgkvKioKCSAqIHtAaW5oZXJpdERvY30KCSAqIAoJICogQHNlZSBvcmcuZWNsaXBzZS5vcGVuY2VydC5zYW0uYXJnLmFyZy5wYXJ0cy5Bc3NlcnRlZENoYWxsZW5nZVByb3BlcnRpZXNFZGl0aW9uUGFydCNhZGRCdXNpbmVzc0ZpbHRlclNvdXJjZShWaWV3ZXJGaWx0ZXIgZmlsdGVyKQoJICogCgkgKi8KCXB1YmxpYyB2b2lkIGFkZEJ1c2luZXNzRmlsdGVyVG9Tb3VyY2UoVmlld2VyRmlsdGVyIGZpbHRlcikgewoJCXNvdXJjZUJ1c2luZXNzRmlsdGVycy5hZGQoZmlsdGVyKTsKCX0KCgkvKioKCSAqIHtAaW5oZXJpdERvY30KCSAqIAoJICogQHNlZSBvcmcuZWNsaXBzZS5vcGVuY2VydC5zYW0uYXJnLmFyZy5wYXJ0cy5Bc3NlcnRlZENoYWxsZW5nZVByb3BlcnRpZXNFZGl0aW9uUGFydCNpc0NvbnRhaW5lZEluU291cmNlVGFibGUoRU9iamVjdCBlbGVtZW50KQoJICogCgkgKi8KCXB1YmxpYyBib29sZWFuIGlzQ29udGFpbmVkSW5Tb3VyY2VUYWJsZShFT2JqZWN0IGVsZW1lbnQpIHsKCQlyZXR1cm4gKChSZWZlcmVuY2VzVGFibGVTZXR0aW5ncylzb3VyY2UuZ2V0SW5wdXQoKSkuY29udGFpbnMoZWxlbWVudCk7Cgl9CgoKCgkvKioKCSAqIHtAaW5oZXJpdERvY30KCSAqIAoJICogQHNlZSBvcmcuZWNsaXBzZS5vcGVuY2VydC5zYW0uYXJnLmFyZy5wYXJ0cy5Bc3NlcnRlZENoYWxsZW5nZVByb3BlcnRpZXNFZGl0aW9uUGFydCNpbml0VGFyZ2V0KG9yZy5lY2xpcHNlLmVtZi5lZWYucnVudGltZS51aS53aWRnZXRzLnJlZmVyZW5jZXN0YWJsZS5SZWZlcmVuY2VzVGFibGVTZXR0aW5ncykKCSAqLwoJcHVibGljIHZvaWQgaW5pdFRhcmdldChSZWZlcmVuY2VzVGFibGVTZXR0aW5ncyBzZXR0aW5ncykgewoJCWlmIChjdXJyZW50LmVSZXNvdXJjZSgpICE9IG51bGwgJiYgY3VycmVudC5lUmVzb3VyY2UoKS5nZXRSZXNvdXJjZVNldCgpICE9IG51bGwpCgkJCXRoaXMucmVzb3VyY2VTZXQgPSBjdXJyZW50LmVSZXNvdXJjZSgpLmdldFJlc291cmNlU2V0KCk7CgkJUmVmZXJlbmNlc1RhYmxlQ29udGVudFByb3ZpZGVyIGNvbnRlbnRQcm92aWRlciA9IG5ldyBSZWZlcmVuY2VzVGFibGVDb250ZW50UHJvdmlkZXIoKTsKCQl0YXJnZXQuc2V0Q29udGVudFByb3ZpZGVyKGNvbnRlbnRQcm92aWRlcik7CgkJdGFyZ2V0LnNldElucHV0KHNldHRpbmdzKTsKCQlib29sZWFuIGVlZkVsZW1lbnRFZGl0b3JSZWFkT25seVN0YXRlID0gaXNSZWFkT25seShBcmdWaWV3c1JlcG9zaXRvcnkuQXNzZXJ0ZWRDaGFsbGVuZ2UuUHJvcGVydGllcy50YXJnZXQpOwoJCWlmIChlZWZFbGVtZW50RWRpdG9yUmVhZE9ubHlTdGF0ZSAmJiB0YXJnZXQuZ2V0VGFibGUoKS5pc0VuYWJsZWQoKSkgewoJCQl0YXJnZXQuc2V0RW5hYmxlZChmYWxzZSk7CgkJCXRhcmdldC5zZXRUb29sVGlwVGV4dChBcmdNZXNzYWdlcy5Bc3NlcnRlZENoYWxsZW5nZV9SZWFkT25seSk7CgkJfSBlbHNlIGlmICghZWVmRWxlbWVudEVkaXRvclJlYWRPbmx5U3RhdGUgJiYgIXRhcmdldC5nZXRUYWJsZSgpLmlzRW5hYmxlZCgpKSB7CgkJCXRhcmdldC5zZXRFbmFibGVkKHRydWUpOwoJCX0KCQkKCX0KCgkvKioKCSAqIHtAaW5oZXJpdERvY30KCSAqIAoJICogQHNlZSBvcmcuZWNsaXBzZS5vcGVuY2VydC5zYW0uYXJnLmFyZy5wYXJ0cy5Bc3NlcnRlZENoYWxsZW5nZVByb3BlcnRpZXNFZGl0aW9uUGFydCN1cGRhdGVUYXJnZXQoKQoJICogCgkgKi8KCXB1YmxpYyB2b2lkIHVwZGF0ZVRhcmdldCgpIHsKCXRhcmdldC5yZWZyZXNoKCk7Cn0KCgkvKioKCSAqIHtAaW5oZXJpdERvY30KCSAqIAoJICogQHNlZSBvcmcuZWNsaXBzZS5vcGVuY2VydC5zYW0uYXJnLmFyZy5wYXJ0cy5Bc3NlcnRlZENoYWxsZW5nZVByb3BlcnRpZXNFZGl0aW9uUGFydCNhZGRGaWx0ZXJUYXJnZXQoVmlld2VyRmlsdGVyIGZpbHRlcikKCSAqIAoJICovCglwdWJsaWMgdm9pZCBhZGRGaWx0ZXJUb1RhcmdldChWaWV3ZXJGaWx0ZXIgZmlsdGVyKSB7CgkJdGFyZ2V0RmlsdGVycy5hZGQoZmlsdGVyKTsKCX0KCgkvKioKCSAqIHtAaW5oZXJpdERvY30KCSAqIAoJICogQHNlZSBvcmcuZWNsaXBzZS5vcGVuY2VydC5zYW0uYXJnLmFyZy5wYXJ0cy5Bc3NlcnRlZENoYWxsZW5nZVByb3BlcnRpZXNFZGl0aW9uUGFydCNhZGRCdXNpbmVzc0ZpbHRlclRhcmdldChWaWV3ZXJGaWx0ZXIgZmlsdGVyKQoJICogCgkgKi8KCXB1YmxpYyB2b2lkIGFkZEJ1c2luZXNzRmlsdGVyVG9UYXJnZXQoVmlld2VyRmlsdGVyIGZpbHRlcikgewoJCXRhcmdldEJ1c2luZXNzRmlsdGVycy5hZGQoZmlsdGVyKTsKCX0KCgkvKioKCSAqIHtAaW5oZXJpdERvY30KCSAqIAoJICogQHNlZSBvcmcuZWNsaXBzZS5vcGVuY2VydC5zYW0uYXJnLmFyZy5wYXJ0cy5Bc3NlcnRlZENoYWxsZW5nZVByb3BlcnRpZXNFZGl0aW9uUGFydCNpc0NvbnRhaW5lZEluVGFyZ2V0VGFibGUoRU9iamVjdCBlbGVtZW50KQoJICogCgkgKi8KCXB1YmxpYyBib29sZWFuIGlzQ29udGFpbmVkSW5UYXJnZXRUYWJsZShFT2JqZWN0IGVsZW1lbnQpIHsKCQlyZXR1cm4gKChSZWZlcmVuY2VzVGFibGVTZXR0aW5ncyl0YXJnZXQuZ2V0SW5wdXQoKSkuY29udGFpbnMoZWxlbWVudCk7Cgl9CgoKCgoKCgkvKioKCSAqIHtAaW5oZXJpdERvY30KCSAqCgkgKiBAc2VlIG9yZy5lY2xpcHNlLmVtZi5lZWYucnVudGltZS5hcGkucGFydHMuSVByb3BlcnRpZXNFZGl0aW9uUGFydCNnZXRUaXRsZSgpCgkgKiAKCSAqLwoJcHVibGljIFN0cmluZyBnZXRUaXRsZSgpIHsKCQlyZXR1cm4gQXJnTWVzc2FnZXMuQXNzZXJ0ZWRDaGFsbGVuZ2VfUGFydF9UaXRsZTsKCX0KCgkvLyBTdGFydCBvZiB1c2VyIGNvZGUgYWRkaXRpb25hbCBtZXRob2RzCgkKCS8vIEVuZCBvZiB1c2VyIGNvZGUKCgp9Cg==