LyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioNCiAqIENvcHlyaWdodCAoYykgMjAxNiBGdW5kYWNp824gVGVjbmFsaWEgUmVzZWFyY2ggJiBJbm5vdmF0aW9uLg0KICoNCiAqIEFsbCByaWdodHMgcmVzZXJ2ZWQuIFRoaXMgcHJvZ3JhbSBhbmQgdGhlIGFjY29tcGFueWluZyBtYXRlcmlhbHMNCiAqIGFyZSBtYWRlIGF2YWlsYWJsZSB1bmRlciB0aGUgdGVybXMgb2YgdGhlIEVjbGlwc2UgUHVibGljIExpY2Vuc2UgdjIuMA0KICogd2hpY2ggYWNjb21wYW5pZXMgdGhpcyBkaXN0cmlidXRpb24sIGFuZCBpcyBhdmFpbGFibGUgYXQNCiAqIGh0dHBzOi8vd3d3LmVjbGlwc2Uub3JnL29yZy9kb2N1bWVudHMvZXBsLTIuMC9FUEwtMi4wLmh0bWwNCiAqDQogKiBTUERYLUxpY2Vuc2UtSWRlbnRpZmllcjogRVBMLTIuMA0KICoNCiAqIENvbnRyaWJ1dG9yczoNCiAqICAgSHVhc2NhciBFc3Bpbm96YSAtIGluaXRpYWwgQVBJIGFuZCBpbXBsZW1lbnRhdGlvbg0KICogICBBbGVqYW5kcmEgUnXteiAtIGluaXRpYWwgQVBJIGFuZCBpbXBsZW1lbnRhdGlvbg0KICogICBJZG95YSBEZWwgUu1vIC0gaW5pdGlhbCBBUEkgYW5kIGltcGxlbWVudGF0aW9uDQogKiAgIE1hcmkgQ2FybWVuIFBhbGFjaW9zIC0gaW5pdGlhbCBBUEkgYW5kIGltcGxlbWVudGF0aW9uDQogKiAgIEFuZ2VsIEzzcGV6IC0gaW5pdGlhbCBBUEkgYW5kIGltcGxlbWVudGF0aW9uDQogKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8NCnBhY2thZ2Ugb3JnLmVjbGlwc2Uub3BlbmNlcnQuc2FtLmFyZy5hcmcuZGlhZ3JhbS5lZGl0LnBhcnRzOw0KDQppbXBvcnQgamF2YS51dGlsLkNvbGxlY3Rpb25zOw0KaW1wb3J0IGphdmEudXRpbC5MaXN0Ow0KDQppbXBvcnQgb3JnLmVjbGlwc2UuZHJhdzJkLklGaWd1cmU7DQppbXBvcnQgb3JnLmVjbGlwc2UuZHJhdzJkLkxhYmVsOw0KaW1wb3J0IG9yZy5lY2xpcHNlLmRyYXcyZC5nZW9tZXRyeS5Qb2ludDsNCmltcG9ydCBvcmcuZWNsaXBzZS5lbWYuY29tbW9uLm5vdGlmeS5Ob3RpZmljYXRpb247DQppbXBvcnQgb3JnLmVjbGlwc2UuZW1mLmVjb3JlLkVPYmplY3Q7DQppbXBvcnQgb3JnLmVjbGlwc2UuZW1mLnRyYW5zYWN0aW9uLlJ1bm5hYmxlV2l0aFJlc3VsdDsNCmltcG9ydCBvcmcuZWNsaXBzZS5nZWYuQWNjZXNzaWJsZUVkaXRQYXJ0Ow0KaW1wb3J0IG9yZy5lY2xpcHNlLmdlZi5FZGl0UGFydDsNCmltcG9ydCBvcmcuZWNsaXBzZS5nZWYuRWRpdFBvbGljeTsNCmltcG9ydCBvcmcuZWNsaXBzZS5nZWYuUmVxdWVzdDsNCmltcG9ydCBvcmcuZWNsaXBzZS5nZWYucmVxdWVzdHMuRGlyZWN0RWRpdFJlcXVlc3Q7DQppbXBvcnQgb3JnLmVjbGlwc2UuZ2VmLnRvb2xzLkRpcmVjdEVkaXRNYW5hZ2VyOw0KaW1wb3J0IG9yZy5lY2xpcHNlLmdtZi5ydW50aW1lLmNvbW1vbi51aS5zZXJ2aWNlcy5wYXJzZXIuSVBhcnNlcjsNCmltcG9ydCBvcmcuZWNsaXBzZS5nbWYucnVudGltZS5jb21tb24udWkuc2VydmljZXMucGFyc2VyLklQYXJzZXJFZGl0U3RhdHVzOw0KaW1wb3J0IG9yZy5lY2xpcHNlLmdtZi5ydW50aW1lLmNvbW1vbi51aS5zZXJ2aWNlcy5wYXJzZXIuUGFyc2VyRWRpdFN0YXR1czsNCmltcG9ydCBvcmcuZWNsaXBzZS5nbWYucnVudGltZS5jb21tb24udWkuc2VydmljZXMucGFyc2VyLlBhcnNlck9wdGlvbnM7DQppbXBvcnQgb3JnLmVjbGlwc2UuZ21mLnJ1bnRpbWUuZGlhZ3JhbS51aS5lZGl0cGFydHMuQ29tcGFydG1lbnRFZGl0UGFydDsNCmltcG9ydCBvcmcuZWNsaXBzZS5nbWYucnVudGltZS5kaWFncmFtLnVpLmVkaXRwYXJ0cy5JR3JhcGhpY2FsRWRpdFBhcnQ7DQppbXBvcnQgb3JnLmVjbGlwc2UuZ21mLnJ1bnRpbWUuZGlhZ3JhbS51aS5lZGl0cGFydHMuSVRleHRBd2FyZUVkaXRQYXJ0Ow0KaW1wb3J0IG9yZy5lY2xpcHNlLmdtZi5ydW50aW1lLmRpYWdyYW0udWkuZWRpdHBhcnRzLlNoYXBlTm9kZUVkaXRQYXJ0Ow0KaW1wb3J0IG9yZy5lY2xpcHNlLmdtZi5ydW50aW1lLmRpYWdyYW0udWkuZWRpdHBvbGljaWVzLkxhYmVsRGlyZWN0RWRpdFBvbGljeTsNCmltcG9ydCBvcmcuZWNsaXBzZS5nbWYucnVudGltZS5kaWFncmFtLnVpLmwxMG4uRGlhZ3JhbUNvbG9yUmVnaXN0cnk7DQppbXBvcnQgb3JnLmVjbGlwc2UuZ21mLnJ1bnRpbWUuZGlhZ3JhbS51aS5sYWJlbC5JTGFiZWxEZWxlZ2F0ZTsNCmltcG9ydCBvcmcuZWNsaXBzZS5nbWYucnVudGltZS5kaWFncmFtLnVpLmxhYmVsLldyYXBwaW5nTGFiZWxEZWxlZ2F0ZTsNCmltcG9ydCBvcmcuZWNsaXBzZS5nbWYucnVudGltZS5kaWFncmFtLnVpLnJlcXVlc3RzLlJlcXVlc3RDb25zdGFudHM7DQppbXBvcnQgb3JnLmVjbGlwc2UuZ21mLnJ1bnRpbWUuZGlhZ3JhbS51aS50b29scy5UZXh0RGlyZWN0RWRpdE1hbmFnZXI7DQppbXBvcnQgb3JnLmVjbGlwc2UuZ21mLnJ1bnRpbWUuZHJhdzJkLnVpLmZpZ3VyZXMuV3JhcHBpbmdMYWJlbDsNCmltcG9ydCBvcmcuZWNsaXBzZS5nbWYucnVudGltZS5lbWYuY29yZS51dGlsLkVPYmplY3RBZGFwdGVyOw0KaW1wb3J0IG9yZy5lY2xpcHNlLmdtZi5ydW50aW1lLmVtZi51aS5zZXJ2aWNlcy5wYXJzZXIuSVNlbWFudGljUGFyc2VyOw0KaW1wb3J0IG9yZy5lY2xpcHNlLmdtZi5ydW50aW1lLm5vdGF0aW9uLkZvbnRTdHlsZTsNCmltcG9ydCBvcmcuZWNsaXBzZS5nbWYucnVudGltZS5ub3RhdGlvbi5Ob3RhdGlvblBhY2thZ2U7DQppbXBvcnQgb3JnLmVjbGlwc2UuZ21mLnJ1bnRpbWUubm90YXRpb24uU2hhcGU7DQppbXBvcnQgb3JnLmVjbGlwc2UuZ21mLnJ1bnRpbWUubm90YXRpb24uVmlldzsNCmltcG9ydCBvcmcuZWNsaXBzZS5nbWYudG9vbGluZy5ydW50aW1lLmRpcmVjdGVkaXQuVGV4dERpcmVjdEVkaXRNYW5hZ2VyMjsNCmltcG9ydCBvcmcuZWNsaXBzZS5nbWYudG9vbGluZy5ydW50aW1lLmRyYXcyZC5sYWJlbHMuU2ltcGxlTGFiZWxEZWxlZ2F0ZTsNCmltcG9ydCBvcmcuZWNsaXBzZS5nbWYudG9vbGluZy5ydW50aW1lLmVkaXQucG9saWNpZXMuRGVmYXVsdE5vZGVMYWJlbERyYWdQb2xpY3k7DQppbXBvcnQgb3JnLmVjbGlwc2UuZ21mLnRvb2xpbmcucnVudGltZS5lZGl0LnBvbGljaWVzLmxhYmVscy5JUmVmcmVzaGFibGVGZWVkYmFja0VkaXRQb2xpY3k7DQppbXBvcnQgb3JnLmVjbGlwc2UuamZhY2UudGV4dC5jb250ZW50YXNzaXN0LklDb250ZW50QXNzaXN0UHJvY2Vzc29yOw0KaW1wb3J0IG9yZy5lY2xpcHNlLmpmYWNlLnZpZXdlcnMuSUNlbGxFZGl0b3JWYWxpZGF0b3I7DQppbXBvcnQgb3JnLmVjbGlwc2Uuc3d0LlNXVDsNCmltcG9ydCBvcmcuZWNsaXBzZS5zd3QuYWNjZXNzaWJpbGl0eS5BY2Nlc3NpYmxlRXZlbnQ7DQppbXBvcnQgb3JnLmVjbGlwc2Uuc3d0LmdyYXBoaWNzLkNvbG9yOw0KaW1wb3J0IG9yZy5lY2xpcHNlLnN3dC5ncmFwaGljcy5Gb250RGF0YTsNCmltcG9ydCBvcmcuZWNsaXBzZS5zd3QuZ3JhcGhpY3MuSW1hZ2U7DQppbXBvcnQgb3JnLmVjbGlwc2Uub3BlbmNlcnQuc2FtLmFyZy5hcmcuQXJnUGFja2FnZTsNCmltcG9ydCBvcmcuZWNsaXBzZS5vcGVuY2VydC5zYW0uYXJnLmFyZy5DbGFpbTsNCmltcG9ydCBvcmcuZWNsaXBzZS5vcGVuY2VydC5zYW0uYXJnLmFyZy5kaWFncmFtLmVkaXQucG9saWNpZXMuQXJnVGV4dFNlbGVjdGlvbkVkaXRQb2xpY3k7DQppbXBvcnQgb3JnLmVjbGlwc2Uub3BlbmNlcnQuc2FtLmFyZy5hcmcuZGlhZ3JhbS5wYXJ0LkFyZ1Zpc3VhbElEUmVnaXN0cnk7DQppbXBvcnQgb3JnLmVjbGlwc2Uub3BlbmNlcnQuc2FtLmFyZy5hcmcuZGlhZ3JhbS5wcm92aWRlcnMuQXJnRWxlbWVudFR5cGVzOw0KaW1wb3J0IG9yZy5lY2xpcHNlLm9wZW5jZXJ0LnNhbS5hcmcuYXJnLmRpYWdyYW0ucHJvdmlkZXJzLkFyZ1BhcnNlclByb3ZpZGVyOw0KaW1wb3J0IG9yZy5lY2xpcHNlLm9wZW5jZXJ0LnVzZXJndWlkYW5jZS5jZWxsZWRpdG9yLlRleHREaXJlY3RFZGl0TWFuYWdlcjM7DQoNCi8qKg0KICogQGdlbmVyYXRlZA0KICovDQpwdWJsaWMgY2xhc3MgQ2xhaW1EZXNjcmlwdGlvbkVkaXRQYXJ0IGV4dGVuZHMgQ29tcGFydG1lbnRFZGl0UGFydCBpbXBsZW1lbnRzDQoJCUlUZXh0QXdhcmVFZGl0UGFydCB7DQoNCgkvKioNCgkgKiBAZ2VuZXJhdGVkDQoJICovDQoJcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgVklTVUFMX0lEID0gNTAwNDsNCg0KCS8qKg0KCSAqIEBnZW5lcmF0ZWQNCgkgKi8NCglwcml2YXRlIERpcmVjdEVkaXRNYW5hZ2VyIG1hbmFnZXI7DQoNCgkvKioNCgkgKiBAZ2VuZXJhdGVkDQoJICovDQoJcHJpdmF0ZSBJUGFyc2VyIHBhcnNlcjsNCg0KCS8qKg0KCSAqIEBnZW5lcmF0ZWQNCgkgKi8NCglwcml2YXRlIExpc3Q8Pz4gcGFyc2VyRWxlbWVudHM7DQoNCgkvKioNCgkgKiBAZ2VuZXJhdGVkDQoJICovDQoJcHJpdmF0ZSBTdHJpbmcgZGVmYXVsdFRleHQ7DQoNCgkvKioNCgkgKiBAZ2VuZXJhdGVkDQoJICovDQoJcHJpdmF0ZSBJTGFiZWxEZWxlZ2F0ZSBsYWJlbERlbGVnYXRlOw0KDQoJLyoqDQoJICogQGdlbmVyYXRlZA0KCSAqLw0KCXB1YmxpYyBDbGFpbURlc2NyaXB0aW9uRWRpdFBhcnQoVmlldyB2aWV3KSB7DQoJCXN1cGVyKHZpZXcpOw0KCX0NCg0KCS8qKg0KCSAqIEBnZW5lcmF0ZWQNCgkgKi8NCglwcm90ZWN0ZWQgdm9pZCBjcmVhdGVEZWZhdWx0RWRpdFBvbGljaWVzKCkgew0KCQlzdXBlci5jcmVhdGVEZWZhdWx0RWRpdFBvbGljaWVzKCk7DQoJCWluc3RhbGxFZGl0UG9saWN5KEVkaXRQb2xpY3kuU0VMRUNUSU9OX0ZFRURCQUNLX1JPTEUsDQoJCQkJbmV3IEFyZ1RleHRTZWxlY3Rpb25FZGl0UG9saWN5KCkpOw0KCQlpbnN0YWxsRWRpdFBvbGljeShFZGl0UG9saWN5LkRJUkVDVF9FRElUX1JPTEUsDQoJCQkJbmV3IExhYmVsRGlyZWN0RWRpdFBvbGljeSgpKTsNCgkJaW5zdGFsbEVkaXRQb2xpY3koRWRpdFBvbGljeS5QUklNQVJZX0RSQUdfUk9MRSwNCgkJCQluZXcgRGVmYXVsdE5vZGVMYWJlbERyYWdQb2xpY3koKSk7DQoJfQ0KDQoJLyoqDQoJICogQGdlbmVyYXRlZA0KCSAqLw0KCXByb3RlY3RlZCBTdHJpbmcgZ2V0TGFiZWxUZXh0SGVscGVyKElGaWd1cmUgZmlndXJlKSB7DQoJCWlmIChmaWd1cmUgaW5zdGFuY2VvZiBXcmFwcGluZ0xhYmVsKSB7DQoJCQlyZXR1cm4gKChXcmFwcGluZ0xhYmVsKSBmaWd1cmUpLmdldFRleHQoKTsNCgkJfSBlbHNlIGlmIChmaWd1cmUgaW5zdGFuY2VvZiBMYWJlbCkgew0KCQkJcmV0dXJuICgoTGFiZWwpIGZpZ3VyZSkuZ2V0VGV4dCgpOw0KCQl9IGVsc2Ugew0KCQkJcmV0dXJuIGdldExhYmVsRGVsZWdhdGUoKS5nZXRUZXh0KCk7DQoJCX0NCgl9DQoNCgkvKioNCgkgKiBAZ2VuZXJhdGVkDQoJICovDQoJcHJvdGVjdGVkIHZvaWQgc2V0TGFiZWxUZXh0SGVscGVyKElGaWd1cmUgZmlndXJlLCBTdHJpbmcgdGV4dCkgew0KCQlpZiAoZmlndXJlIGluc3RhbmNlb2YgV3JhcHBpbmdMYWJlbCkgew0KCQkJKChXcmFwcGluZ0xhYmVsKSBmaWd1cmUpLnNldFRleHQodGV4dCk7DQoJCX0gZWxzZSBpZiAoZmlndXJlIGluc3RhbmNlb2YgTGFiZWwpIHsNCgkJCSgoTGFiZWwpIGZpZ3VyZSkuc2V0VGV4dCh0ZXh0KTsNCgkJfSBlbHNlIHsNCgkJCWdldExhYmVsRGVsZWdhdGUoKS5zZXRUZXh0KHRleHQpOw0KCQl9DQoJfQ0KDQoJLyoqDQoJICogQGdlbmVyYXRlZA0KCSAqLw0KCXByb3RlY3RlZCBJbWFnZSBnZXRMYWJlbEljb25IZWxwZXIoSUZpZ3VyZSBmaWd1cmUpIHsNCgkJaWYgKGZpZ3VyZSBpbnN0YW5jZW9mIFdyYXBwaW5nTGFiZWwpIHsNCgkJCXJldHVybiAoKFdyYXBwaW5nTGFiZWwpIGZpZ3VyZSkuZ2V0SWNvbigpOw0KCQl9IGVsc2UgaWYgKGZpZ3VyZSBpbnN0YW5jZW9mIExhYmVsKSB7DQoJCQlyZXR1cm4gKChMYWJlbCkgZmlndXJlKS5nZXRJY29uKCk7DQoJCX0gZWxzZSB7DQoJCQlyZXR1cm4gZ2V0TGFiZWxEZWxlZ2F0ZSgpLmdldEljb24oMCk7DQoJCX0NCgl9DQoNCgkvKioNCgkgKiBAZ2VuZXJhdGVkDQoJICovDQoJcHJvdGVjdGVkIHZvaWQgc2V0TGFiZWxJY29uSGVscGVyKElGaWd1cmUgZmlndXJlLCBJbWFnZSBpY29uKSB7DQoJCWlmIChmaWd1cmUgaW5zdGFuY2VvZiBXcmFwcGluZ0xhYmVsKSB7DQoJCQkoKFdyYXBwaW5nTGFiZWwpIGZpZ3VyZSkuc2V0SWNvbihpY29uKTsNCgkJCXJldHVybjsNCgkJfSBlbHNlIGlmIChmaWd1cmUgaW5zdGFuY2VvZiBMYWJlbCkgew0KCQkJKChMYWJlbCkgZmlndXJlKS5zZXRJY29uKGljb24pOw0KCQkJcmV0dXJuOw0KCQl9IGVsc2Ugew0KCQkJZ2V0TGFiZWxEZWxlZ2F0ZSgpLnNldEljb24oaWNvbiwgMCk7DQoJCX0NCgl9DQoNCgkvKioNCgkgKiBAZ2VuZXJhdGVkDQoJICovDQoJcHVibGljIHZvaWQgc2V0TGFiZWwoV3JhcHBpbmdMYWJlbCBmaWd1cmUpIHsNCgkJdW5yZWdpc3RlclZpc3VhbHMoKTsNCgkJc2V0RmlndXJlKGZpZ3VyZSk7DQoJCWRlZmF1bHRUZXh0ID0gZ2V0TGFiZWxUZXh0SGVscGVyKGZpZ3VyZSk7DQoJCXJlZ2lzdGVyVmlzdWFscygpOw0KCQlyZWZyZXNoVmlzdWFscygpOw0KCX0NCg0KCS8qKg0KCSAqIEBnZW5lcmF0ZWQNCgkgKi8NCglAU3VwcHJlc3NXYXJuaW5ncygicmF3dHlwZXMiKQ0KCXByb3RlY3RlZCBMaXN0IGdldE1vZGVsQ2hpbGRyZW4oKSB7DQoJCXJldHVybiBDb2xsZWN0aW9ucy5FTVBUWV9MSVNUOw0KCX0NCg0KCS8qKg0KCSAqIEBnZW5lcmF0ZWQNCgkgKi8NCglwdWJsaWMgSUdyYXBoaWNhbEVkaXRQYXJ0IGdldENoaWxkQnlTZW1hbnRpY0hpbnQoU3RyaW5nIHNlbWFudGljSGludCkgew0KCQlyZXR1cm4gbnVsbDsNCgl9DQoNCgkvKioNCgkgKiBAZ2VuZXJhdGVkDQoJICovDQoJcHJvdGVjdGVkIEVPYmplY3QgZ2V0UGFyc2VyRWxlbWVudCgpIHsNCgkJcmV0dXJuIHJlc29sdmVTZW1hbnRpY0VsZW1lbnQoKTsNCgl9DQoNCgkvKioNCgkgKiBAZ2VuZXJhdGVkDQoJICovDQoJcHJvdGVjdGVkIEltYWdlIGdldExhYmVsSWNvbigpIHsNCgkJcmV0dXJuIG51bGw7DQoJfQ0KDQoJLyoqDQoJICogQGdlbmVyYXRlZA0KCSAqLw0KCXByb3RlY3RlZCBTdHJpbmcgZ2V0TGFiZWxUZXh0KCkgew0KCQlTdHJpbmcgdGV4dCA9IG51bGw7DQoJCUVPYmplY3QgcGFyc2VyRWxlbWVudCA9IGdldFBhcnNlckVsZW1lbnQoKTsNCgkJaWYgKHBhcnNlckVsZW1lbnQgIT0gbnVsbCAmJiBnZXRQYXJzZXIoKSAhPSBudWxsKSB7DQoJCQl0ZXh0ID0gZ2V0UGFyc2VyKCkuZ2V0UHJpbnRTdHJpbmcoDQoJCQkJCW5ldyBFT2JqZWN0QWRhcHRlcihwYXJzZXJFbGVtZW50KSwNCgkJCQkJZ2V0UGFyc2VyT3B0aW9ucygpLmludFZhbHVlKCkpOw0KCQl9DQoJCWlmICh0ZXh0ID09IG51bGwgfHwgdGV4dC5sZW5ndGgoKSA9PSAwKSB7DQoJCQl0ZXh0ID0gZGVmYXVsdFRleHQ7DQoJCX0NCgkJcmV0dXJuIHRleHQ7DQoJfQ0KDQoJLyoqDQoJICogQGdlbmVyYXRlZA0KCSAqLw0KCXB1YmxpYyB2b2lkIHNldExhYmVsVGV4dChTdHJpbmcgdGV4dCkgew0KCQlzZXRMYWJlbFRleHRIZWxwZXIoZ2V0RmlndXJlKCksIHRleHQpOw0KCQlyZWZyZXNoU2VsZWN0aW9uRmVlZGJhY2soKTsNCgl9DQoNCgkvKioNCgkgKiBAZ2VuZXJhdGVkDQoJICovDQoJcHVibGljIFN0cmluZyBnZXRFZGl0VGV4dCgpIHsNCgkJaWYgKGdldFBhcnNlckVsZW1lbnQoKSA9PSBudWxsIHx8IGdldFBhcnNlcigpID09IG51bGwpIHsNCgkJCXJldHVybiAiIjsgLy8kTk9OLU5MUy0xJA0KCQl9DQoJCXJldHVybiBnZXRQYXJzZXIoKS5nZXRFZGl0U3RyaW5nKA0KCQkJCW5ldyBFT2JqZWN0QWRhcHRlcihnZXRQYXJzZXJFbGVtZW50KCkpLA0KCQkJCWdldFBhcnNlck9wdGlvbnMoKS5pbnRWYWx1ZSgpKTsNCgl9DQoNCgkvKioNCgkgKiBAZ2VuZXJhdGVkDQoJICovDQoJcHJvdGVjdGVkIGJvb2xlYW4gaXNFZGl0YWJsZSgpIHsNCgkJcmV0dXJuIGdldFBhcnNlcigpICE9IG51bGw7DQoJfQ0KDQoJLyoqDQoJICogQGdlbmVyYXRlZA0KCSAqLw0KCXB1YmxpYyBJQ2VsbEVkaXRvclZhbGlkYXRvciBnZXRFZGl0VGV4dFZhbGlkYXRvcigpIHsNCgkJcmV0dXJuIG5ldyBJQ2VsbEVkaXRvclZhbGlkYXRvcigpIHsNCg0KCQkJcHVibGljIFN0cmluZyBpc1ZhbGlkKGZpbmFsIE9iamVjdCB2YWx1ZSkgew0KCQkJCWlmICh2YWx1ZSBpbnN0YW5jZW9mIFN0cmluZykgew0KCQkJCQlmaW5hbCBFT2JqZWN0IGVsZW1lbnQgPSBnZXRQYXJzZXJFbGVtZW50KCk7DQoJCQkJCWZpbmFsIElQYXJzZXIgcGFyc2VyID0gZ2V0UGFyc2VyKCk7DQoJCQkJCXRyeSB7DQoJCQkJCQlJUGFyc2VyRWRpdFN0YXR1cyB2YWxpZCA9IChJUGFyc2VyRWRpdFN0YXR1cykgZ2V0RWRpdGluZ0RvbWFpbigpDQoJCQkJCQkJCS5ydW5FeGNsdXNpdmUoDQoJCQkJCQkJCQkJbmV3IFJ1bm5hYmxlV2l0aFJlc3VsdC5JbXBsPElQYXJzZXJFZGl0U3RhdHVzPigpIHsNCg0KCQkJCQkJCQkJCQlwdWJsaWMgdm9pZCBydW4oKSB7DQoJCQkJCQkJCQkJCQlzZXRSZXN1bHQocGFyc2VyDQoJCQkJCQkJCQkJCQkJCS5pc1ZhbGlkRWRpdFN0cmluZygNCgkJCQkJCQkJCQkJCQkJCQluZXcgRU9iamVjdEFkYXB0ZXIoDQoJCQkJCQkJCQkJCQkJCQkJCQllbGVtZW50KSwNCgkJCQkJCQkJCQkJCQkJCQkoU3RyaW5nKSB2YWx1ZSkpOw0KCQkJCQkJCQkJCQl9DQoJCQkJCQkJCQkJfSk7DQoJCQkJCQlyZXR1cm4gdmFsaWQuZ2V0Q29kZSgpID09IFBhcnNlckVkaXRTdGF0dXMuRURJVEFCTEUgPyBudWxsDQoJCQkJCQkJCTogdmFsaWQuZ2V0TWVzc2FnZSgpOw0KCQkJCQl9IGNhdGNoIChJbnRlcnJ1cHRlZEV4Y2VwdGlvbiBpZSkgew0KCQkJCQkJaWUucHJpbnRTdGFja1RyYWNlKCk7DQoJCQkJCX0NCgkJCQl9DQoNCgkJCQkvLyBzaG91bGRuJ3QgZ2V0IGhlcmUNCgkJCQlyZXR1cm4gbnVsbDsNCgkJCX0NCgkJfTsNCgl9DQoNCgkvKioNCgkgKiBAZ2VuZXJhdGVkDQoJICovDQoJcHVibGljIElDb250ZW50QXNzaXN0UHJvY2Vzc29yIGdldENvbXBsZXRpb25Qcm9jZXNzb3IoKSB7DQoJCWlmIChnZXRQYXJzZXJFbGVtZW50KCkgPT0gbnVsbCB8fCBnZXRQYXJzZXIoKSA9PSBudWxsKSB7DQoJCQlyZXR1cm4gbnVsbDsNCgkJfQ0KCQlyZXR1cm4gZ2V0UGFyc2VyKCkuZ2V0Q29tcGxldGlvblByb2Nlc3NvcigNCgkJCQluZXcgRU9iamVjdEFkYXB0ZXIoZ2V0UGFyc2VyRWxlbWVudCgpKSk7DQoJfQ0KDQoJLyoqDQoJICogQGdlbmVyYXRlZA0KCSAqLw0KCXB1YmxpYyBQYXJzZXJPcHRpb25zIGdldFBhcnNlck9wdGlvbnMoKSB7DQoJCXJldHVybiBQYXJzZXJPcHRpb25zLk5PTkU7DQoJfQ0KDQoJLyoqDQoJICogQGdlbmVyYXRlZA0KCSAqLw0KCXB1YmxpYyBJUGFyc2VyIGdldFBhcnNlcigpIHsNCgkJaWYgKHBhcnNlciA9PSBudWxsKSB7DQoJCQlwYXJzZXIgPSBBcmdQYXJzZXJQcm92aWRlcg0KCQkJCQkuZ2V0UGFyc2VyKA0KCQkJCQkJCUFyZ0VsZW1lbnRUeXBlcy5DbGFpbV8yMDAxLA0KCQkJCQkJCWdldFBhcnNlckVsZW1lbnQoKSwNCgkJCQkJCQlBcmdWaXN1YWxJRFJlZ2lzdHJ5DQoJCQkJCQkJCQkuZ2V0VHlwZShvcmcuZWNsaXBzZS5vcGVuY2VydC5zYW0uYXJnLmFyZy5kaWFncmFtLmVkaXQucGFydHMuQ2xhaW1EZXNjcmlwdGlvbkVkaXRQYXJ0LlZJU1VBTF9JRCkpOw0KCQl9DQoJCXJldHVybiBwYXJzZXI7DQoJfQ0KDQoJLyoqDQoJICogQGdlbmVyYXRlZA0KCSAqLw0KCXByb3RlY3RlZCBEaXJlY3RFZGl0TWFuYWdlciBnZXRNYW5hZ2VyKCkgew0KCQlpZiAobWFuYWdlciA9PSBudWxsKSB7DQoJCQlUZXh0RGlyZWN0RWRpdE1hbmFnZXIzIG1hbmFnZXIgPSBuZXcgVGV4dERpcmVjdEVkaXRNYW5hZ2VyMyh0aGlzLA0KCQkJCQludWxsLCBBcmdFZGl0UGFydEZhY3RvcnkuZ2V0VGV4dENlbGxFZGl0b3JMb2NhdG9yKHRoaXMpLA0KCQkJCQlnZXRNb2RlbEVsZW1lbnQoKSwgQXJnUGFja2FnZS5DTEFJTV9fREVTQ1JJUFRJT04pOw0KCQkJc2V0TWFuYWdlcihtYW5hZ2VyKTsNCgkJfQ0KCQkvL2lmIChtYW5hZ2VyID09IG51bGwpIHsNCgkJLy8Jc2V0TWFuYWdlcihuZXcgVGV4dERpcmVjdEVkaXRNYW5hZ2VyMih0aGlzLCBudWxsLA0KCQkvLwkJCUFyZ0VkaXRQYXJ0RmFjdG9yeS5nZXRUZXh0Q2VsbEVkaXRvckxvY2F0b3IodGhpcykpKTsNCgkJLy99DQoJCXJldHVybiBtYW5hZ2VyOw0KCX0NCg0KCXByaXZhdGUgRU9iamVjdCBnZXRNb2RlbEVsZW1lbnQoKSB7DQoJCWlmICh0aGlzIGluc3RhbmNlb2YgQ29tcGFydG1lbnRFZGl0UGFydCkgew0KCQkJRWRpdFBhcnQgcGFyZW50ID0gKChDb21wYXJ0bWVudEVkaXRQYXJ0KSB0aGlzKS5nZXRQYXJlbnQoKTsNCgkJCWlmIChwYXJlbnQgaW5zdGFuY2VvZiBTaGFwZU5vZGVFZGl0UGFydCkgew0KCQkJCWlmIChwYXJlbnQuZ2V0TW9kZWwoKSBpbnN0YW5jZW9mIFNoYXBlKSB7DQoJCQkJCVNoYXBlIHNoYXBlID0gKFNoYXBlKSBwYXJlbnQuZ2V0TW9kZWwoKTsNCgkJCQkJRU9iamVjdCBlb2JqID0gc2hhcGUuZ2V0RWxlbWVudCgpOw0KCQkJCQlpZiAoZW9iaiBpbnN0YW5jZW9mIENsYWltKSB7DQoJCQkJCQlyZXR1cm4gZW9iajsNCgkJCQkJfQ0KCQkJCX0NCgkJCX0NCgkJfQ0KDQoJCXJldHVybiBudWxsOw0KCX0NCg0KCS8qKg0KCSAqIEBnZW5lcmF0ZWQNCgkgKi8NCglwcm90ZWN0ZWQgdm9pZCBzZXRNYW5hZ2VyKERpcmVjdEVkaXRNYW5hZ2VyIG1hbmFnZXIpIHsNCgkJdGhpcy5tYW5hZ2VyID0gbWFuYWdlcjsNCgl9DQoNCgkvKioNCgkgKiBAZ2VuZXJhdGVkDQoJICovDQoJcHJvdGVjdGVkIHZvaWQgcGVyZm9ybURpcmVjdEVkaXQoKSB7DQoJCWdldE1hbmFnZXIoKS5zaG93KCk7DQoJfQ0KDQoJLyoqDQoJICogQGdlbmVyYXRlZA0KCSAqLw0KCXByb3RlY3RlZCB2b2lkIHBlcmZvcm1EaXJlY3RFZGl0KFBvaW50IGV2ZW50TG9jYXRpb24pIHsNCi8vCQlpZiAoZ2V0TWFuYWdlcigpLmdldENsYXNzKCkgPT0gVGV4dERpcmVjdEVkaXRNYW5hZ2VyMy5jbGFzcykgew0KCQlpZiAoZ2V0TWFuYWdlcigpLmdldENsYXNzKCkgPT0gVGV4dERpcmVjdEVkaXRNYW5hZ2VyMi5jbGFzcykgew0KCQkJKChUZXh0RGlyZWN0RWRpdE1hbmFnZXIyKSBnZXRNYW5hZ2VyKCkpLnNob3coZXZlbnRMb2NhdGlvbg0KCQkJCQkuZ2V0U1dUUG9pbnQoKSk7DQoJCX0NCgl9DQoNCgkvKioNCgkgKiBAZ2VuZXJhdGVkDQoJICovDQoJcHJpdmF0ZSB2b2lkIHBlcmZvcm1EaXJlY3RFZGl0KGNoYXIgaW5pdGlhbENoYXJhY3Rlcikgew0KCQlpZiAoZ2V0TWFuYWdlcigpIGluc3RhbmNlb2YgVGV4dERpcmVjdEVkaXRNYW5hZ2VyKSB7DQoJCQkoKFRleHREaXJlY3RFZGl0TWFuYWdlcikgZ2V0TWFuYWdlcigpKS5zaG93KGluaXRpYWxDaGFyYWN0ZXIpOw0KCQl9IGVsc2UgLy8NCi8vCQlpZiAoZ2V0TWFuYWdlcigpIGluc3RhbmNlb2YgVGV4dERpcmVjdEVkaXRNYW5hZ2VyMykgew0KCQlpZiAoZ2V0TWFuYWdlcigpIGluc3RhbmNlb2YgVGV4dERpcmVjdEVkaXRNYW5hZ2VyMikgew0KCQkJKChUZXh0RGlyZWN0RWRpdE1hbmFnZXIyKSBnZXRNYW5hZ2VyKCkpLnNob3coaW5pdGlhbENoYXJhY3Rlcik7DQoJCX0gZWxzZSAvLw0KCQl7DQoJCQlwZXJmb3JtRGlyZWN0RWRpdCgpOw0KCQl9DQoJfQ0KDQoJLyoqDQoJICogQGdlbmVyYXRlZA0KCSAqLw0KCXByb3RlY3RlZCB2b2lkIHBlcmZvcm1EaXJlY3RFZGl0UmVxdWVzdChSZXF1ZXN0IHJlcXVlc3QpIHsNCgkJZmluYWwgUmVxdWVzdCB0aGVSZXF1ZXN0ID0gcmVxdWVzdDsNCgkJdHJ5IHsNCgkJCWdldEVkaXRpbmdEb21haW4oKS5ydW5FeGNsdXNpdmUobmV3IFJ1bm5hYmxlKCkgew0KDQoJCQkJcHVibGljIHZvaWQgcnVuKCkgew0KCQkJCQlpZiAoaXNBY3RpdmUoKSAmJiBpc0VkaXRhYmxlKCkpIHsNCgkJCQkJCWlmICh0aGVSZXF1ZXN0DQoJCQkJCQkJCS5nZXRFeHRlbmRlZERhdGEoKQ0KCQkJCQkJCQkuZ2V0KFJlcXVlc3RDb25zdGFudHMuUkVRX0RJUkVDVEVESVRfRVhURU5ERUREQVRBX0lOSVRJQUxfQ0hBUikgaW5zdGFuY2VvZiBDaGFyYWN0ZXIpIHsNCgkJCQkJCQlDaGFyYWN0ZXIgaW5pdGlhbENoYXIgPSAoQ2hhcmFjdGVyKSB0aGVSZXF1ZXN0DQoJCQkJCQkJCQkuZ2V0RXh0ZW5kZWREYXRhKCkNCgkJCQkJCQkJCS5nZXQoUmVxdWVzdENvbnN0YW50cy5SRVFfRElSRUNURURJVF9FWFRFTkRFRERBVEFfSU5JVElBTF9DSEFSKTsNCgkJCQkJCQlwZXJmb3JtRGlyZWN0RWRpdChpbml0aWFsQ2hhci5jaGFyVmFsdWUoKSk7DQoJCQkJCQl9IGVsc2UgaWYgKCh0aGVSZXF1ZXN0IGluc3RhbmNlb2YgRGlyZWN0RWRpdFJlcXVlc3QpDQoJCQkJCQkJCSYmIChnZXRFZGl0VGV4dCgpLmVxdWFscyhnZXRMYWJlbFRleHQoKSkpKSB7DQoJCQkJCQkJRGlyZWN0RWRpdFJlcXVlc3QgZWRpdFJlcXVlc3QgPSAoRGlyZWN0RWRpdFJlcXVlc3QpIHRoZVJlcXVlc3Q7DQoJCQkJCQkJcGVyZm9ybURpcmVjdEVkaXQoZWRpdFJlcXVlc3QuZ2V0TG9jYXRpb24oKSk7DQoJCQkJCQl9IGVsc2Ugew0KCQkJCQkJCXBlcmZvcm1EaXJlY3RFZGl0KCk7DQoJCQkJCQl9DQoJCQkJCX0NCgkJCQl9DQoJCQl9KTsNCgkJfSBjYXRjaCAoSW50ZXJydXB0ZWRFeGNlcHRpb24gZSkgew0KCQkJZS5wcmludFN0YWNrVHJhY2UoKTsNCgkJfQ0KCX0NCg0KCS8qKg0KCSAqIEBnZW5lcmF0ZWQNCgkgKi8NCglwcm90ZWN0ZWQgdm9pZCByZWZyZXNoVmlzdWFscygpIHsNCgkJc3VwZXIucmVmcmVzaFZpc3VhbHMoKTsNCgkJcmVmcmVzaExhYmVsKCk7DQoJCXJlZnJlc2hGb250KCk7DQoJCXJlZnJlc2hGb250Q29sb3IoKTsNCgkJcmVmcmVzaFVuZGVybGluZSgpOw0KCQlyZWZyZXNoU3RyaWtlVGhyb3VnaCgpOw0KCX0NCg0KCS8qKg0KCSAqIEBnZW5lcmF0ZWQNCgkgKi8NCglwcm90ZWN0ZWQgdm9pZCByZWZyZXNoTGFiZWwoKSB7DQoJCXNldExhYmVsVGV4dEhlbHBlcihnZXRGaWd1cmUoKSwgZ2V0TGFiZWxUZXh0KCkpOw0KCQlzZXRMYWJlbEljb25IZWxwZXIoZ2V0RmlndXJlKCksIGdldExhYmVsSWNvbigpKTsNCgkJcmVmcmVzaFNlbGVjdGlvbkZlZWRiYWNrKCk7DQoJfQ0KDQoJLyoqDQoJICogQGdlbmVyYXRlZA0KCSAqLw0KCXByb3RlY3RlZCB2b2lkIHJlZnJlc2hVbmRlcmxpbmUoKSB7DQoJCUZvbnRTdHlsZSBzdHlsZSA9IChGb250U3R5bGUpIGdldEZvbnRTdHlsZU93bmVyVmlldygpLmdldFN0eWxlKA0KCQkJCU5vdGF0aW9uUGFja2FnZS5lSU5TVEFOQ0UuZ2V0Rm9udFN0eWxlKCkpOw0KCQlpZiAoc3R5bGUgIT0gbnVsbCAmJiBnZXRGaWd1cmUoKSBpbnN0YW5jZW9mIFdyYXBwaW5nTGFiZWwpIHsNCgkJCSgoV3JhcHBpbmdMYWJlbCkgZ2V0RmlndXJlKCkpLnNldFRleHRVbmRlcmxpbmUoc3R5bGUuaXNVbmRlcmxpbmUoKSk7DQoJCX0NCgl9DQoNCgkvKioNCgkgKiBAZ2VuZXJhdGVkDQoJICovDQoJcHJvdGVjdGVkIHZvaWQgcmVmcmVzaFN0cmlrZVRocm91Z2goKSB7DQoJCUZvbnRTdHlsZSBzdHlsZSA9IChGb250U3R5bGUpIGdldEZvbnRTdHlsZU93bmVyVmlldygpLmdldFN0eWxlKA0KCQkJCU5vdGF0aW9uUGFja2FnZS5lSU5TVEFOQ0UuZ2V0Rm9udFN0eWxlKCkpOw0KCQlpZiAoc3R5bGUgIT0gbnVsbCAmJiBnZXRGaWd1cmUoKSBpbnN0YW5jZW9mIFdyYXBwaW5nTGFiZWwpIHsNCgkJCSgoV3JhcHBpbmdMYWJlbCkgZ2V0RmlndXJlKCkpLnNldFRleHRTdHJpa2VUaHJvdWdoKHN0eWxlDQoJCQkJCS5pc1N0cmlrZVRocm91Z2goKSk7DQoJCX0NCgl9DQoNCgkvKioNCgkgKiBAZ2VuZXJhdGVkDQoJICovDQoJcHJvdGVjdGVkIHZvaWQgcmVmcmVzaEZvbnQoKSB7DQoJCUZvbnRTdHlsZSBzdHlsZSA9IChGb250U3R5bGUpIGdldEZvbnRTdHlsZU93bmVyVmlldygpLmdldFN0eWxlKA0KCQkJCU5vdGF0aW9uUGFja2FnZS5lSU5TVEFOQ0UuZ2V0Rm9udFN0eWxlKCkpOw0KCQlpZiAoc3R5bGUgIT0gbnVsbCkgew0KCQkJRm9udERhdGEgZm9udERhdGEgPSBuZXcgRm9udERhdGEoc3R5bGUuZ2V0Rm9udE5hbWUoKSwNCgkJCQkJc3R5bGUuZ2V0Rm9udEhlaWdodCgpLCAoc3R5bGUuaXNCb2xkKCkgPyBTV1QuQk9MRA0KCQkJCQkJCTogU1dULk5PUk1BTCkNCgkJCQkJCQl8IChzdHlsZS5pc0l0YWxpYygpID8gU1dULklUQUxJQyA6IFNXVC5OT1JNQUwpKTsNCgkJCXNldEZvbnQoZm9udERhdGEpOw0KCQl9DQoJfQ0KDQoJLyoqDQoJICogQGdlbmVyYXRlZA0KCSAqLw0KCXByaXZhdGUgdm9pZCByZWZyZXNoU2VsZWN0aW9uRmVlZGJhY2soKSB7DQoJCXJlcXVlc3RFZGl0UG9saWN5RmVlZGJhY2tSZWZyZXNoKEVkaXRQb2xpY3kuUFJJTUFSWV9EUkFHX1JPTEUpOw0KCQlyZXF1ZXN0RWRpdFBvbGljeUZlZWRiYWNrUmVmcmVzaChFZGl0UG9saWN5LlNFTEVDVElPTl9GRUVEQkFDS19ST0xFKTsNCgl9DQoNCgkvKioNCgkgKiBAZ2VuZXJhdGVkDQoJICovDQoJcHJpdmF0ZSB2b2lkIHJlcXVlc3RFZGl0UG9saWN5RmVlZGJhY2tSZWZyZXNoKFN0cmluZyBlZGl0UG9saWN5S2V5KSB7DQoJCU9iamVjdCBlZGl0UG9saWN5ID0gZ2V0RWRpdFBvbGljeShlZGl0UG9saWN5S2V5KTsNCgkJaWYgKGVkaXRQb2xpY3kgaW5zdGFuY2VvZiBJUmVmcmVzaGFibGVGZWVkYmFja0VkaXRQb2xpY3kpIHsNCgkJCSgoSVJlZnJlc2hhYmxlRmVlZGJhY2tFZGl0UG9saWN5KSBlZGl0UG9saWN5KS5yZWZyZXNoRmVlZGJhY2soKTsNCgkJfQ0KCX0NCg0KCS8qKg0KCSAqIEBnZW5lcmF0ZWQNCgkgKi8NCglwcm90ZWN0ZWQgdm9pZCBzZXRGb250Q29sb3IoQ29sb3IgY29sb3IpIHsNCgkJZ2V0RmlndXJlKCkuc2V0Rm9yZWdyb3VuZENvbG9yKGNvbG9yKTsNCgl9DQoNCgkvKioNCgkgKiBAZ2VuZXJhdGVkDQoJICovDQoJcHJvdGVjdGVkIHZvaWQgYWRkU2VtYW50aWNMaXN0ZW5lcnMoKSB7DQoJCWlmIChnZXRQYXJzZXIoKSBpbnN0YW5jZW9mIElTZW1hbnRpY1BhcnNlcikgew0KCQkJRU9iamVjdCBlbGVtZW50ID0gcmVzb2x2ZVNlbWFudGljRWxlbWVudCgpOw0KCQkJcGFyc2VyRWxlbWVudHMgPSAoKElTZW1hbnRpY1BhcnNlcikgZ2V0UGFyc2VyKCkpDQoJCQkJCS5nZXRTZW1hbnRpY0VsZW1lbnRzQmVpbmdQYXJzZWQoZWxlbWVudCk7DQoJCQlmb3IgKGludCBpID0gMDsgaSA8IHBhcnNlckVsZW1lbnRzLnNpemUoKTsgaSsrKSB7DQoJCQkJYWRkTGlzdGVuZXJGaWx0ZXIoDQoJCQkJCQkiU2VtYW50aWNNb2RlbCIgKyBpLCB0aGlzLCAoRU9iamVjdCkgcGFyc2VyRWxlbWVudHMuZ2V0KGkpKTsgLy8kTk9OLU5MUy0xJA0KCQkJfQ0KCQl9IGVsc2Ugew0KCQkJc3VwZXIuYWRkU2VtYW50aWNMaXN0ZW5lcnMoKTsNCgkJfQ0KCX0NCg0KCS8qKg0KCSAqIEBnZW5lcmF0ZWQNCgkgKi8NCglwcm90ZWN0ZWQgdm9pZCByZW1vdmVTZW1hbnRpY0xpc3RlbmVycygpIHsNCgkJaWYgKHBhcnNlckVsZW1lbnRzICE9IG51bGwpIHsNCgkJCWZvciAoaW50IGkgPSAwOyBpIDwgcGFyc2VyRWxlbWVudHMuc2l6ZSgpOyBpKyspIHsNCgkJCQlyZW1vdmVMaXN0ZW5lckZpbHRlcigiU2VtYW50aWNNb2RlbCIgKyBpKTsgLy8kTk9OLU5MUy0xJA0KCQkJfQ0KCQl9IGVsc2Ugew0KCQkJc3VwZXIucmVtb3ZlU2VtYW50aWNMaXN0ZW5lcnMoKTsNCgkJfQ0KCX0NCg0KCS8qKg0KCSAqIEBnZW5lcmF0ZWQNCgkgKi8NCglwcm90ZWN0ZWQgQWNjZXNzaWJsZUVkaXRQYXJ0IGdldEFjY2Vzc2libGVFZGl0UGFydCgpIHsNCgkJaWYgKGFjY2Vzc2libGVFUCA9PSBudWxsKSB7DQoJCQlhY2Nlc3NpYmxlRVAgPSBuZXcgQWNjZXNzaWJsZUdyYXBoaWNhbEVkaXRQYXJ0KCkgew0KDQoJCQkJcHVibGljIHZvaWQgZ2V0TmFtZShBY2Nlc3NpYmxlRXZlbnQgZSkgew0KCQkJCQllLnJlc3VsdCA9IGdldExhYmVsVGV4dEhlbHBlcihnZXRGaWd1cmUoKSk7DQoJCQkJfQ0KCQkJfTsNCgkJfQ0KCQlyZXR1cm4gYWNjZXNzaWJsZUVQOw0KCX0NCg0KCS8qKg0KCSAqIEBnZW5lcmF0ZWQNCgkgKi8NCglwcml2YXRlIFZpZXcgZ2V0Rm9udFN0eWxlT3duZXJWaWV3KCkgew0KCQlyZXR1cm4gKFZpZXcpIGdldE1vZGVsKCk7DQoJfQ0KDQoJLyoqDQoJICogQGdlbmVyYXRlZA0KCSAqLw0KCXByaXZhdGUgSUxhYmVsRGVsZWdhdGUgZ2V0TGFiZWxEZWxlZ2F0ZSgpIHsNCgkJaWYgKGxhYmVsRGVsZWdhdGUgPT0gbnVsbCkgew0KCQkJSUZpZ3VyZSBsYWJlbCA9IGdldEZpZ3VyZSgpOw0KCQkJaWYgKGxhYmVsIGluc3RhbmNlb2YgV3JhcHBpbmdMYWJlbCkgew0KCQkJCWxhYmVsRGVsZWdhdGUgPSBuZXcgV3JhcHBpbmdMYWJlbERlbGVnYXRlKChXcmFwcGluZ0xhYmVsKSBsYWJlbCk7DQoJCQl9IGVsc2Ugew0KCQkJCWxhYmVsRGVsZWdhdGUgPSBuZXcgU2ltcGxlTGFiZWxEZWxlZ2F0ZSgoTGFiZWwpIGxhYmVsKTsNCgkJCX0NCgkJfQ0KCQlyZXR1cm4gbGFiZWxEZWxlZ2F0ZTsNCgl9DQoNCgkvKioNCgkgKiBAZ2VuZXJhdGVkDQoJICovDQoJQE92ZXJyaWRlDQoJcHVibGljIE9iamVjdCBnZXRBZGFwdGVyKENsYXNzIGtleSkgew0KCQlpZiAoSUxhYmVsRGVsZWdhdGUuY2xhc3MuZXF1YWxzKGtleSkpIHsNCgkJCXJldHVybiBnZXRMYWJlbERlbGVnYXRlKCk7DQoJCX0NCgkJcmV0dXJuIHN1cGVyLmdldEFkYXB0ZXIoa2V5KTsNCgl9DQoNCgkvKioNCgkgKiBAZ2VuZXJhdGVkDQoJICovDQoJcHJvdGVjdGVkIHZvaWQgYWRkTm90YXRpb25hbExpc3RlbmVycygpIHsNCgkJc3VwZXIuYWRkTm90YXRpb25hbExpc3RlbmVycygpOw0KCQlhZGRMaXN0ZW5lckZpbHRlcigiUHJpbWFyeVZpZXciLCB0aGlzLCBnZXRQcmltYXJ5VmlldygpKTsgLy8kTk9OLU5MUy0xJA0KCX0NCg0KCS8qKg0KCSAqIEBnZW5lcmF0ZWQNCgkgKi8NCglwcm90ZWN0ZWQgdm9pZCByZW1vdmVOb3RhdGlvbmFsTGlzdGVuZXJzKCkgew0KCQlzdXBlci5yZW1vdmVOb3RhdGlvbmFsTGlzdGVuZXJzKCk7DQoJCXJlbW92ZUxpc3RlbmVyRmlsdGVyKCJQcmltYXJ5VmlldyIpOyAvLyROT04tTkxTLTEkDQoJfQ0KDQoJLyoqDQoJICogQGdlbmVyYXRlZA0KCSAqLw0KCXByb3RlY3RlZCB2b2lkIGhhbmRsZU5vdGlmaWNhdGlvbkV2ZW50KE5vdGlmaWNhdGlvbiBldmVudCkgew0KCQlPYmplY3QgZmVhdHVyZSA9IGV2ZW50LmdldEZlYXR1cmUoKTsNCgkJaWYgKE5vdGF0aW9uUGFja2FnZS5lSU5TVEFOQ0UuZ2V0Rm9udFN0eWxlX0ZvbnRDb2xvcigpLmVxdWFscyhmZWF0dXJlKSkgew0KCQkJSW50ZWdlciBjID0gKEludGVnZXIpIGV2ZW50LmdldE5ld1ZhbHVlKCk7DQoJCQlzZXRGb250Q29sb3IoRGlhZ3JhbUNvbG9yUmVnaXN0cnkuZ2V0SW5zdGFuY2UoKS5nZXRDb2xvcihjKSk7DQoJCX0gZWxzZSBpZiAoTm90YXRpb25QYWNrYWdlLmVJTlNUQU5DRS5nZXRGb250U3R5bGVfVW5kZXJsaW5lKCkuZXF1YWxzKA0KCQkJCWZlYXR1cmUpKSB7DQoJCQlyZWZyZXNoVW5kZXJsaW5lKCk7DQoJCX0gZWxzZSBpZiAoTm90YXRpb25QYWNrYWdlLmVJTlNUQU5DRS5nZXRGb250U3R5bGVfU3RyaWtlVGhyb3VnaCgpDQoJCQkJLmVxdWFscyhmZWF0dXJlKSkgew0KCQkJcmVmcmVzaFN0cmlrZVRocm91Z2goKTsNCgkJfSBlbHNlIGlmIChOb3RhdGlvblBhY2thZ2UuZUlOU1RBTkNFLmdldEZvbnRTdHlsZV9Gb250SGVpZ2h0KCkuZXF1YWxzKA0KCQkJCWZlYXR1cmUpDQoJCQkJfHwgTm90YXRpb25QYWNrYWdlLmVJTlNUQU5DRS5nZXRGb250U3R5bGVfRm9udE5hbWUoKS5lcXVhbHMoDQoJCQkJCQlmZWF0dXJlKQ0KCQkJCXx8IE5vdGF0aW9uUGFja2FnZS5lSU5TVEFOQ0UuZ2V0Rm9udFN0eWxlX0JvbGQoKQ0KCQkJCQkJLmVxdWFscyhmZWF0dXJlKQ0KCQkJCXx8IE5vdGF0aW9uUGFja2FnZS5lSU5TVEFOQ0UuZ2V0Rm9udFN0eWxlX0l0YWxpYygpLmVxdWFscygNCgkJCQkJCWZlYXR1cmUpKSB7DQoJCQlyZWZyZXNoRm9udCgpOw0KCQl9IGVsc2Ugew0KCQkJaWYgKGdldFBhcnNlcigpICE9IG51bGwNCgkJCQkJJiYgZ2V0UGFyc2VyKCkuaXNBZmZlY3RpbmdFdmVudChldmVudCwNCgkJCQkJCQlnZXRQYXJzZXJPcHRpb25zKCkuaW50VmFsdWUoKSkpIHsNCgkJCQlyZWZyZXNoTGFiZWwoKTsNCgkJCX0NCgkJCWlmIChnZXRQYXJzZXIoKSBpbnN0YW5jZW9mIElTZW1hbnRpY1BhcnNlcikgew0KCQkJCUlTZW1hbnRpY1BhcnNlciBtb2RlbFBhcnNlciA9IChJU2VtYW50aWNQYXJzZXIpIGdldFBhcnNlcigpOw0KCQkJCWlmIChtb2RlbFBhcnNlci5hcmVTZW1hbnRpY0VsZW1lbnRzQWZmZWN0ZWQobnVsbCwgZXZlbnQpKSB7DQoJCQkJCXJlbW92ZVNlbWFudGljTGlzdGVuZXJzKCk7DQoJCQkJCWlmIChyZXNvbHZlU2VtYW50aWNFbGVtZW50KCkgIT0gbnVsbCkgew0KCQkJCQkJYWRkU2VtYW50aWNMaXN0ZW5lcnMoKTsNCgkJCQkJfQ0KCQkJCQlyZWZyZXNoTGFiZWwoKTsNCgkJCQl9DQoJCQl9DQoJCX0NCgkJc3VwZXIuaGFuZGxlTm90aWZpY2F0aW9uRXZlbnQoZXZlbnQpOw0KCX0NCg0KCS8qKg0KCSAqIEBnZW5lcmF0ZWQNCgkgKi8NCglwcm90ZWN0ZWQgSUZpZ3VyZSBjcmVhdGVGaWd1cmUoKSB7DQoJCS8vIFBhcmVudCBzaG91bGQgYXNzaWduIG9uZSB1c2luZyBzZXRMYWJlbCgpIG1ldGhvZA0KCQlyZXR1cm4gbnVsbDsNCgl9DQoNCn0NCg==