LyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioNCiAqIENvcHlyaWdodCAoYykgMjAxNiBGdW5kYWNp824gVGVjbmFsaWEgUmVzZWFyY2ggJiBJbm5vdmF0aW9uLg0KICoNCiAqIEFsbCByaWdodHMgcmVzZXJ2ZWQuIFRoaXMgcHJvZ3JhbSBhbmQgdGhlIGFjY29tcGFueWluZyBtYXRlcmlhbHMNCiAqIGFyZSBtYWRlIGF2YWlsYWJsZSB1bmRlciB0aGUgdGVybXMgb2YgdGhlIEVjbGlwc2UgUHVibGljIExpY2Vuc2UgdjIuMA0KICogd2hpY2ggYWNjb21wYW5pZXMgdGhpcyBkaXN0cmlidXRpb24sIGFuZCBpcyBhdmFpbGFibGUgYXQNCiAqIGh0dHBzOi8vd3d3LmVjbGlwc2Uub3JnL29yZy9kb2N1bWVudHMvZXBsLTIuMC9FUEwtMi4wLmh0bWwNCiAqDQogKiBTUERYLUxpY2Vuc2UtSWRlbnRpZmllcjogRVBMLTIuMA0KICoNCiAqIENvbnRyaWJ1dG9yczoNCiAqICAgSHVhc2NhciBFc3Bpbm96YSAtIGluaXRpYWwgQVBJIGFuZCBpbXBsZW1lbnRhdGlvbg0KICogICBBbGVqYW5kcmEgUnXteiAtIGluaXRpYWwgQVBJIGFuZCBpbXBsZW1lbnRhdGlvbg0KICogICBJZG95YSBEZWwgUu1vIC0gaW5pdGlhbCBBUEkgYW5kIGltcGxlbWVudGF0aW9uDQogKiAgIE1hcmkgQ2FybWVuIFBhbGFjaW9zIC0gaW5pdGlhbCBBUEkgYW5kIGltcGxlbWVudGF0aW9uDQogKiAgIEFuZ2VsIEzzcGV6IC0gaW5pdGlhbCBBUEkgYW5kIGltcGxlbWVudGF0aW9uDQogKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8NCi8qKg0KICovDQpwYWNrYWdlIG9yZy5lY2xpcHNlLm9wZW5jZXJ0LnNhbS5hcmcuYXJnLnByZXNlbnRhdGlvbjsNCg0KDQppbXBvcnQgamF2YS5pby5JT0V4Y2VwdGlvbjsNCmltcG9ydCBqYXZhLmlvLklucHV0U3RyZWFtOw0KaW1wb3J0IGphdmEudXRpbC5BcnJheUxpc3Q7DQppbXBvcnQgamF2YS51dGlsLkNvbGxlY3Rpb247DQppbXBvcnQgamF2YS51dGlsLkNvbGxlY3Rpb25zOw0KaW1wb3J0IGphdmEudXRpbC5FdmVudE9iamVjdDsNCmltcG9ydCBqYXZhLnV0aWwuSGFzaE1hcDsNCmltcG9ydCBqYXZhLnV0aWwuSXRlcmF0b3I7DQppbXBvcnQgamF2YS51dGlsLkxpbmtlZEhhc2hNYXA7DQppbXBvcnQgamF2YS51dGlsLkxpc3Q7DQppbXBvcnQgamF2YS51dGlsLk1hcDsNCg0KaW1wb3J0IG9yZy5lY2xpcHNlLmNvcmUucmVzb3VyY2VzLklGaWxlOw0KaW1wb3J0IG9yZy5lY2xpcHNlLmNvcmUucmVzb3VyY2VzLklNYXJrZXI7DQppbXBvcnQgb3JnLmVjbGlwc2UuY29yZS5yZXNvdXJjZXMuSVJlc291cmNlOw0KaW1wb3J0IG9yZy5lY2xpcHNlLmNvcmUucmVzb3VyY2VzLklSZXNvdXJjZUNoYW5nZUV2ZW50Ow0KaW1wb3J0IG9yZy5lY2xpcHNlLmNvcmUucmVzb3VyY2VzLklSZXNvdXJjZUNoYW5nZUxpc3RlbmVyOw0KaW1wb3J0IG9yZy5lY2xpcHNlLmNvcmUucmVzb3VyY2VzLklSZXNvdXJjZURlbHRhOw0KaW1wb3J0IG9yZy5lY2xpcHNlLmNvcmUucmVzb3VyY2VzLklSZXNvdXJjZURlbHRhVmlzaXRvcjsNCmltcG9ydCBvcmcuZWNsaXBzZS5jb3JlLnJlc291cmNlcy5SZXNvdXJjZXNQbHVnaW47DQppbXBvcnQgb3JnLmVjbGlwc2UuY29yZS5ydW50aW1lLkNvcmVFeGNlcHRpb247DQppbXBvcnQgb3JnLmVjbGlwc2UuY29yZS5ydW50aW1lLklQYXRoOw0KaW1wb3J0IG9yZy5lY2xpcHNlLmNvcmUucnVudGltZS5JUHJvZ3Jlc3NNb25pdG9yOw0KaW1wb3J0IG9yZy5lY2xpcHNlLmNvcmUucnVudGltZS5OdWxsUHJvZ3Jlc3NNb25pdG9yOw0KaW1wb3J0IG9yZy5lY2xpcHNlLmpmYWNlLmFjdGlvbi5JTWVudUxpc3RlbmVyOw0KaW1wb3J0IG9yZy5lY2xpcHNlLmpmYWNlLmFjdGlvbi5JTWVudU1hbmFnZXI7DQppbXBvcnQgb3JnLmVjbGlwc2UuamZhY2UuYWN0aW9uLklTdGF0dXNMaW5lTWFuYWdlcjsNCmltcG9ydCBvcmcuZWNsaXBzZS5qZmFjZS5hY3Rpb24uSVRvb2xCYXJNYW5hZ2VyOw0KaW1wb3J0IG9yZy5lY2xpcHNlLmpmYWNlLmFjdGlvbi5NZW51TWFuYWdlcjsNCmltcG9ydCBvcmcuZWNsaXBzZS5qZmFjZS5hY3Rpb24uU2VwYXJhdG9yOw0KaW1wb3J0IG9yZy5lY2xpcHNlLmpmYWNlLmRpYWxvZ3MuTWVzc2FnZURpYWxvZzsNCmltcG9ydCBvcmcuZWNsaXBzZS5qZmFjZS5kaWFsb2dzLlByb2dyZXNzTW9uaXRvckRpYWxvZzsNCmltcG9ydCBvcmcuZWNsaXBzZS5qZmFjZS51dGlsLkxvY2FsU2VsZWN0aW9uVHJhbnNmZXI7DQppbXBvcnQgb3JnLmVjbGlwc2UuamZhY2Uudmlld2Vycy5BYnN0cmFjdFRyZWVWaWV3ZXI7DQppbXBvcnQgb3JnLmVjbGlwc2UuamZhY2Uudmlld2Vycy5DaGVja1N0YXRlQ2hhbmdlZEV2ZW50Ow0KaW1wb3J0IG9yZy5lY2xpcHNlLmpmYWNlLnZpZXdlcnMuQ29sdW1uV2VpZ2h0RGF0YTsNCmltcG9ydCBvcmcuZWNsaXBzZS5qZmFjZS52aWV3ZXJzLklDaGVja1N0YXRlTGlzdGVuZXI7DQppbXBvcnQgb3JnLmVjbGlwc2UuamZhY2Uudmlld2Vycy5JU2VsZWN0aW9uOw0KaW1wb3J0IG9yZy5lY2xpcHNlLmpmYWNlLnZpZXdlcnMuSVNlbGVjdGlvbkNoYW5nZWRMaXN0ZW5lcjsNCmltcG9ydCBvcmcuZWNsaXBzZS5qZmFjZS52aWV3ZXJzLklTZWxlY3Rpb25Qcm92aWRlcjsNCmltcG9ydCBvcmcuZWNsaXBzZS5qZmFjZS52aWV3ZXJzLklTdHJ1Y3R1cmVkU2VsZWN0aW9uOw0KaW1wb3J0IG9yZy5lY2xpcHNlLmpmYWNlLnZpZXdlcnMuTGlzdFZpZXdlcjsNCmltcG9ydCBvcmcuZWNsaXBzZS5qZmFjZS52aWV3ZXJzLlNlbGVjdGlvbkNoYW5nZWRFdmVudDsNCmltcG9ydCBvcmcuZWNsaXBzZS5qZmFjZS52aWV3ZXJzLlN0cnVjdHVyZWRTZWxlY3Rpb247DQppbXBvcnQgb3JnLmVjbGlwc2UuamZhY2Uudmlld2Vycy5TdHJ1Y3R1cmVkVmlld2VyOw0KaW1wb3J0IG9yZy5lY2xpcHNlLmpmYWNlLnZpZXdlcnMuVGFibGVMYXlvdXQ7DQppbXBvcnQgb3JnLmVjbGlwc2UuamZhY2Uudmlld2Vycy5UYWJsZVZpZXdlcjsNCmltcG9ydCBvcmcuZWNsaXBzZS5qZmFjZS52aWV3ZXJzLlRyZWVWaWV3ZXI7DQppbXBvcnQgb3JnLmVjbGlwc2UuamZhY2Uudmlld2Vycy5WaWV3ZXI7DQppbXBvcnQgb3JnLmVjbGlwc2Uub3BlbmNlcnQuYXBtLmFzc3VyYW5jZWFzc2V0cy5hc3N1cmFuY2Vhc3NldC5wcm92aWRlci5Bc3N1cmFuY2Vhc3NldEl0ZW1Qcm92aWRlckFkYXB0ZXJGYWN0b3J5Ow0KaW1wb3J0IG9yZy5lY2xpcHNlLm9wZW5jZXJ0LmFwbS5hc3N1cnByb2oudXRpbHMud2lkZ2V0LkNoZWNrYm94VHJlZVZpZXdlckV4dDsNCmltcG9ydCBvcmcuZWNsaXBzZS5vcGVuY2VydC5pbmZyYS5nZW5lcmFsLmdlbmVyYWwucHJvdmlkZXIuR2VuZXJhbEl0ZW1Qcm92aWRlckFkYXB0ZXJGYWN0b3J5Ow0KaW1wb3J0IG9yZy5lY2xpcHNlLm9wZW5jZXJ0LmluZnJhLnByb3BlcnRpZXMucHJvcGVydHkucHJvdmlkZXIuUHJvcGVydHlJdGVtUHJvdmlkZXJBZGFwdGVyRmFjdG9yeTsNCmltcG9ydCBvcmcuZWNsaXBzZS5zd3QuU1dUOw0KaW1wb3J0IG9yZy5lY2xpcHNlLnN3dC5jdXN0b20uQ1RhYkZvbGRlcjsNCmltcG9ydCBvcmcuZWNsaXBzZS5zd3QuZG5kLkRORDsNCmltcG9ydCBvcmcuZWNsaXBzZS5zd3QuZG5kLkZpbGVUcmFuc2ZlcjsNCmltcG9ydCBvcmcuZWNsaXBzZS5zd3QuZG5kLlRyYW5zZmVyOw0KaW1wb3J0IG9yZy5lY2xpcHNlLnN3dC5ldmVudHMuQ29udHJvbEFkYXB0ZXI7DQppbXBvcnQgb3JnLmVjbGlwc2Uuc3d0LmV2ZW50cy5Db250cm9sRXZlbnQ7DQppbXBvcnQgb3JnLmVjbGlwc2Uuc3d0LmdyYXBoaWNzLlBvaW50Ow0KaW1wb3J0IG9yZy5lY2xpcHNlLnN3dC5sYXlvdXQuRmlsbExheW91dDsNCmltcG9ydCBvcmcuZWNsaXBzZS5zd3Qud2lkZ2V0cy5Db21wb3NpdGU7DQppbXBvcnQgb3JnLmVjbGlwc2Uuc3d0LndpZGdldHMuTWVudTsNCmltcG9ydCBvcmcuZWNsaXBzZS5zd3Qud2lkZ2V0cy5UYWJsZTsNCmltcG9ydCBvcmcuZWNsaXBzZS5zd3Qud2lkZ2V0cy5UYWJsZUNvbHVtbjsNCmltcG9ydCBvcmcuZWNsaXBzZS5zd3Qud2lkZ2V0cy5UcmVlOw0KaW1wb3J0IG9yZy5lY2xpcHNlLnN3dC53aWRnZXRzLlRyZWVDb2x1bW47DQppbXBvcnQgb3JnLmVjbGlwc2Uuc3d0LndpZGdldHMuVHJlZUl0ZW07DQppbXBvcnQgb3JnLmVjbGlwc2UudWkuSUFjdGlvbkJhcnM7DQppbXBvcnQgb3JnLmVjbGlwc2UudWkuSUVkaXRvcklucHV0Ow0KaW1wb3J0IG9yZy5lY2xpcHNlLnVpLklFZGl0b3JQYXJ0Ow0KaW1wb3J0IG9yZy5lY2xpcHNlLnVpLklFZGl0b3JTaXRlOw0KaW1wb3J0IG9yZy5lY2xpcHNlLnVpLklQYXJ0TGlzdGVuZXI7DQppbXBvcnQgb3JnLmVjbGlwc2UudWkuSVdvcmtiZW5jaFBhcnQ7DQppbXBvcnQgb3JnLmVjbGlwc2UudWkuUGFydEluaXRFeGNlcHRpb247DQppbXBvcnQgb3JnLmVjbGlwc2UudWkuZGlhbG9ncy5TYXZlQXNEaWFsb2c7DQppbXBvcnQgb3JnLmVjbGlwc2UudWkuaWRlLklHb3RvTWFya2VyOw0KaW1wb3J0IG9yZy5lY2xpcHNlLnVpLnBhcnQuRmlsZUVkaXRvcklucHV0Ow0KaW1wb3J0IG9yZy5lY2xpcHNlLnVpLnBhcnQuTXVsdGlQYWdlRWRpdG9yUGFydDsNCmltcG9ydCBvcmcuZWNsaXBzZS51aS52aWV3cy5jb250ZW50b3V0bGluZS5Db250ZW50T3V0bGluZTsNCmltcG9ydCBvcmcuZWNsaXBzZS51aS52aWV3cy5jb250ZW50b3V0bGluZS5Db250ZW50T3V0bGluZVBhZ2U7DQppbXBvcnQgb3JnLmVjbGlwc2UudWkudmlld3MuY29udGVudG91dGxpbmUuSUNvbnRlbnRPdXRsaW5lUGFnZTsNCmltcG9ydCBvcmcuZWNsaXBzZS51aS52aWV3cy5wcm9wZXJ0aWVzLklQcm9wZXJ0eVNoZWV0UGFnZTsNCmltcG9ydCBvcmcuZWNsaXBzZS51aS52aWV3cy5wcm9wZXJ0aWVzLlByb3BlcnR5U2hlZXQ7DQppbXBvcnQgb3JnLmVjbGlwc2UudWkudmlld3MucHJvcGVydGllcy5Qcm9wZXJ0eVNoZWV0UGFnZTsNCmltcG9ydCBvcmcuZWNsaXBzZS51aS52aWV3cy5wcm9wZXJ0aWVzLnRhYmJlZC5JVGFiYmVkUHJvcGVydHlTaGVldFBhZ2VDb250cmlidXRvcjsNCmltcG9ydCBvcmcuZWNsaXBzZS51aS52aWV3cy5wcm9wZXJ0aWVzLnRhYmJlZC5UYWJiZWRQcm9wZXJ0eVNoZWV0UGFnZTsNCmltcG9ydCBvcmcuZWNsaXBzZS5lbWYuY29tbW9uLmNvbW1hbmQuQmFzaWNDb21tYW5kU3RhY2s7DQppbXBvcnQgb3JnLmVjbGlwc2UuZW1mLmNvbW1vbi5jb21tYW5kLkNvbW1hbmQ7DQppbXBvcnQgb3JnLmVjbGlwc2UuZW1mLmNvbW1vbi5jb21tYW5kLkNvbW1hbmRTdGFjazsNCmltcG9ydCBvcmcuZWNsaXBzZS5lbWYuY29tbW9uLmNvbW1hbmQuQ29tbWFuZFN0YWNrTGlzdGVuZXI7DQppbXBvcnQgb3JnLmVjbGlwc2UuZW1mLmNvbW1vbi5ub3RpZnkuQWRhcHRlckZhY3Rvcnk7DQppbXBvcnQgb3JnLmVjbGlwc2UuZW1mLmNvbW1vbi5ub3RpZnkuTm90aWZpY2F0aW9uOw0KaW1wb3J0IG9yZy5lY2xpcHNlLmVtZi5jb21tb24udWkuTWFya2VySGVscGVyOw0KaW1wb3J0IG9yZy5lY2xpcHNlLmVtZi5jb21tb24udWkuVmlld2VyUGFuZTsNCmltcG9ydCBvcmcuZWNsaXBzZS5lbWYuY29tbW9uLnVpLmVkaXRvci5Qcm9ibGVtRWRpdG9yUGFydDsNCmltcG9ydCBvcmcuZWNsaXBzZS5lbWYuY29tbW9uLnVpLnZpZXdlci5JVmlld2VyUHJvdmlkZXI7DQppbXBvcnQgb3JnLmVjbGlwc2UuZW1mLmNvbW1vbi51dGlsLkJhc2ljRGlhZ25vc3RpYzsNCmltcG9ydCBvcmcuZWNsaXBzZS5lbWYuY29tbW9uLnV0aWwuRGlhZ25vc3RpYzsNCmltcG9ydCBvcmcuZWNsaXBzZS5lbWYuY29tbW9uLnV0aWwuVVJJOw0KDQoNCmltcG9ydCBvcmcuZWNsaXBzZS5lbWYuZWNvcmUucmVzb3VyY2UuUmVzb3VyY2U7DQppbXBvcnQgb3JnLmVjbGlwc2UuZW1mLmVjb3JlLnJlc291cmNlLlJlc291cmNlU2V0Ow0KaW1wb3J0IG9yZy5lY2xpcHNlLmVtZi5lY29yZS51dGlsLkVDb250ZW50QWRhcHRlcjsNCmltcG9ydCBvcmcuZWNsaXBzZS5lbWYuZWNvcmUudXRpbC5FY29yZVV0aWw7DQppbXBvcnQgb3JnLmVjbGlwc2UuZW1mLmVkaXQuZG9tYWluLkFkYXB0ZXJGYWN0b3J5RWRpdGluZ0RvbWFpbjsNCmltcG9ydCBvcmcuZWNsaXBzZS5lbWYuZWRpdC5kb21haW4uRWRpdGluZ0RvbWFpbjsNCmltcG9ydCBvcmcuZWNsaXBzZS5lbWYuZWRpdC5kb21haW4uSUVkaXRpbmdEb21haW5Qcm92aWRlcjsNCmltcG9ydCBvcmcuZWNsaXBzZS5lbWYuZWRpdC5wcm92aWRlci5BZGFwdGVyRmFjdG9yeUl0ZW1EZWxlZ2F0b3I7DQppbXBvcnQgb3JnLmVjbGlwc2UuZW1mLmVkaXQucHJvdmlkZXIuQ29tcG9zZWRBZGFwdGVyRmFjdG9yeTsNCmltcG9ydCBvcmcuZWNsaXBzZS5lbWYuZWRpdC5wcm92aWRlci5SZWZsZWN0aXZlSXRlbVByb3ZpZGVyQWRhcHRlckZhY3Rvcnk7DQppbXBvcnQgb3JnLmVjbGlwc2UuZW1mLmVkaXQucHJvdmlkZXIucmVzb3VyY2UuUmVzb3VyY2VJdGVtUHJvdmlkZXJBZGFwdGVyRmFjdG9yeTsNCmltcG9ydCBvcmcuZWNsaXBzZS5lbWYuZWRpdC51aS5hY3Rpb24uRWRpdGluZ0RvbWFpbkFjdGlvbkJhckNvbnRyaWJ1dG9yOw0KaW1wb3J0IG9yZy5lY2xpcHNlLmVtZi5lZGl0LnVpLmNlbGxlZGl0b3IuQWRhcHRlckZhY3RvcnlUcmVlRWRpdG9yOw0KaW1wb3J0IG9yZy5lY2xpcHNlLmVtZi5lZGl0LnVpLmRuZC5FZGl0aW5nRG9tYWluVmlld2VyRHJvcEFkYXB0ZXI7DQppbXBvcnQgb3JnLmVjbGlwc2UuZW1mLmVkaXQudWkuZG5kLkxvY2FsVHJhbnNmZXI7DQppbXBvcnQgb3JnLmVjbGlwc2UuZW1mLmVkaXQudWkuZG5kLlZpZXdlckRyYWdBZGFwdGVyOw0KaW1wb3J0IG9yZy5lY2xpcHNlLmVtZi5lZGl0LnVpLnByb3ZpZGVyLkFkYXB0ZXJGYWN0b3J5Q29udGVudFByb3ZpZGVyOw0KaW1wb3J0IG9yZy5lY2xpcHNlLmVtZi5lZGl0LnVpLnByb3ZpZGVyLkFkYXB0ZXJGYWN0b3J5TGFiZWxQcm92aWRlcjsNCmltcG9ydCBvcmcuZWNsaXBzZS5lbWYuZWRpdC51aS5wcm92aWRlci5VbndyYXBwaW5nU2VsZWN0aW9uUHJvdmlkZXI7DQppbXBvcnQgb3JnLmVjbGlwc2UuZW1mLmVkaXQudWkudXRpbC5FZGl0VUlNYXJrZXJIZWxwZXI7DQppbXBvcnQgb3JnLmVjbGlwc2UuZW1mLmVkaXQudWkudXRpbC5FZGl0VUlVdGlsOw0KaW1wb3J0IG9yZy5lY2xpcHNlLmVtZi5lZGl0LnVpLnZpZXcuRXh0ZW5kZWRQcm9wZXJ0eVNoZWV0UGFnZTsNCmltcG9ydCBvcmcuZWNsaXBzZS5lbWYuZWVmLnJ1bnRpbWUudWkubm90aWZ5Lk9wZW5XaXphcmRPbkRvdWJsZUNsaWNrOw0KaW1wb3J0IG9yZy5lY2xpcHNlLm9wZW5jZXJ0LnNhbS5hcmcuYXJnLnByb3ZpZGVyLkFyZ0l0ZW1Qcm92aWRlckFkYXB0ZXJGYWN0b3J5Ow0KaW1wb3J0IG9yZy5lY2xpcHNlLnVpLmFjdGlvbnMuV29ya3NwYWNlTW9kaWZ5T3BlcmF0aW9uOw0KDQoNCi8qKg0KICogVGhpcyBpcyBhbiBleGFtcGxlIG9mIGEgQXJnIG1vZGVsIGVkaXRvci4NCiAqIDwhLS0gYmVnaW4tdXNlci1kb2MgLS0+DQogKiA8IS0tIGVuZC11c2VyLWRvYyAtLT4NCiAqIEBnZW5lcmF0ZWQNCiAqLw0KcHVibGljIGNsYXNzIEFyZ0VkaXRvcg0KCWV4dGVuZHMgTXVsdGlQYWdlRWRpdG9yUGFydA0KCWltcGxlbWVudHMgSUVkaXRpbmdEb21haW5Qcm92aWRlciwgSVNlbGVjdGlvblByb3ZpZGVyLCBJTWVudUxpc3RlbmVyLCBJVmlld2VyUHJvdmlkZXIsIElHb3RvTWFya2VyDQoJLy8gU3RhcnQgTUNQDQoJLCBJVGFiYmVkUHJvcGVydHlTaGVldFBhZ2VDb250cmlidXRvciB7DQoJCXByaXZhdGUgc3RhdGljIGZpbmFsIFN0cmluZyBBUkdfUFJPUEVSVElFUyA9ICJvcmcuZWNsaXBzZS5vcGVuY2VydC5zYW0uYXJnLmFyZy5wcm9wZXJ0aWVzIjsNCgkvLyBFbmQgTUNQDQoJCQ0KCS8qKg0KCSAqIFRoaXMga2VlcHMgdHJhY2sgb2YgdGhlIGVkaXRpbmcgZG9tYWluIHRoYXQgaXMgdXNlZCB0byB0cmFjayBhbGwgY2hhbmdlcyB0byB0aGUgbW9kZWwuDQoJICogPCEtLSBiZWdpbi11c2VyLWRvYyAtLT4NCgkgKiA8IS0tIGVuZC11c2VyLWRvYyAtLT4NCgkgKiBAZ2VuZXJhdGVkDQoJICovDQoJcHJvdGVjdGVkIEFkYXB0ZXJGYWN0b3J5RWRpdGluZ0RvbWFpbiBlZGl0aW5nRG9tYWluOw0KDQoJLyoqDQoJICogVGhpcyBpcyB0aGUgb25lIGFkYXB0ZXIgZmFjdG9yeSB1c2VkIGZvciBwcm92aWRpbmcgdmlld3Mgb2YgdGhlIG1vZGVsLg0KCSAqIDwhLS0gYmVnaW4tdXNlci1kb2MgLS0+DQoJICogPCEtLSBlbmQtdXNlci1kb2MgLS0+DQoJICogQGdlbmVyYXRlZA0KCSAqLw0KCXByb3RlY3RlZCBDb21wb3NlZEFkYXB0ZXJGYWN0b3J5IGFkYXB0ZXJGYWN0b3J5Ow0KDQoJLyoqDQoJICogVGhpcyBpcyB0aGUgY29udGVudCBvdXRsaW5lIHBhZ2UuDQoJICogPCEtLSBiZWdpbi11c2VyLWRvYyAtLT4NCgkgKiA8IS0tIGVuZC11c2VyLWRvYyAtLT4NCgkgKiBAZ2VuZXJhdGVkDQoJICovDQoJcHJvdGVjdGVkIElDb250ZW50T3V0bGluZVBhZ2UgY29udGVudE91dGxpbmVQYWdlOw0KDQoJLyoqDQoJICogVGhpcyBpcyBhIGtsdWRnZS4uLg0KCSAqIDwhLS0gYmVnaW4tdXNlci1kb2MgLS0+DQoJICogPCEtLSBlbmQtdXNlci1kb2MgLS0+DQoJICogQGdlbmVyYXRlZA0KCSAqLw0KCXByb3RlY3RlZCBJU3RhdHVzTGluZU1hbmFnZXIgY29udGVudE91dGxpbmVTdGF0dXNMaW5lTWFuYWdlcjsNCg0KCS8qKg0KCSAqIFRoaXMgaXMgdGhlIGNvbnRlbnQgb3V0bGluZSBwYWdlJ3Mgdmlld2VyLg0KCSAqIDwhLS0gYmVnaW4tdXNlci1kb2MgLS0+DQoJICogPCEtLSBlbmQtdXNlci1kb2MgLS0+DQoJICogQGdlbmVyYXRlZA0KCSAqLw0KCXByb3RlY3RlZCBUcmVlVmlld2VyIGNvbnRlbnRPdXRsaW5lVmlld2VyOw0KDQoJLyoqDQoJICogVGhpcyBpcyB0aGUgcHJvcGVydHkgc2hlZXQgcGFnZS4NCgkgKiA8IS0tIGJlZ2luLXVzZXItZG9jIC0tPg0KCSAqIDwhLS0gZW5kLXVzZXItZG9jIC0tPg0KCSAqIEBnZW5lcmF0ZWQNCgkgKi8NCglwcm90ZWN0ZWQgTGlzdDxQcm9wZXJ0eVNoZWV0UGFnZT4gcHJvcGVydHlTaGVldFBhZ2VzID0gbmV3IEFycmF5TGlzdDxQcm9wZXJ0eVNoZWV0UGFnZT4oKTsNCg0KCS8qKg0KCSAqIFRoaXMgaXMgdGhlIHZpZXdlciB0aGF0IHNoYWRvd3MgdGhlIHNlbGVjdGlvbiBpbiB0aGUgY29udGVudCBvdXRsaW5lLg0KCSAqIFRoZSBwYXJlbnQgcmVsYXRpb24gbXVzdCBiZSBjb3JyZWN0bHkgZGVmaW5lZCBmb3IgdGhpcyB0byB3b3JrLg0KCSAqIDwhLS0gYmVnaW4tdXNlci1kb2MgLS0+DQoJICogPCEtLSBlbmQtdXNlci1kb2MgLS0+DQoJICogQGdlbmVyYXRlZA0KCSAqLw0KCXByb3RlY3RlZCBUcmVlVmlld2VyIHNlbGVjdGlvblZpZXdlcjsNCg0KCS8qKg0KCSAqIFRoaXMgaW52ZXJ0cyB0aGUgcm9sbCBvZiBwYXJlbnQgYW5kIGNoaWxkIGluIHRoZSBjb250ZW50IHByb3ZpZGVyIGFuZCBzaG93IHBhcmVudHMgYXMgYSB0cmVlLg0KCSAqIDwhLS0gYmVnaW4tdXNlci1kb2MgLS0+DQoJICogPCEtLSBlbmQtdXNlci1kb2MgLS0+DQoJICogQGdlbmVyYXRlZA0KCSAqLw0KCXByb3RlY3RlZCBUcmVlVmlld2VyIHBhcmVudFZpZXdlcjsNCg0KCS8qKg0KCSAqIFRoaXMgc2hvd3MgaG93IGEgdHJlZSB2aWV3IHdvcmtzLg0KCSAqIDwhLS0gYmVnaW4tdXNlci1kb2MgLS0+DQoJICogPCEtLSBlbmQtdXNlci1kb2MgLS0+DQoJICogQGdlbmVyYXRlZA0KCSAqLw0KCXByb3RlY3RlZCBUcmVlVmlld2VyIHRyZWVWaWV3ZXI7DQoNCgkvKioNCgkgKiBUaGlzIHNob3dzIGhvdyBhIGxpc3QgdmlldyB3b3Jrcy4NCgkgKiBBIGxpc3Qgdmlld2VyIGRvZXNuJ3Qgc3VwcG9ydCBpY29ucy4NCgkgKiA8IS0tIGJlZ2luLXVzZXItZG9jIC0tPg0KCSAqIDwhLS0gZW5kLXVzZXItZG9jIC0tPg0KCSAqIEBnZW5lcmF0ZWQNCgkgKi8NCglwcm90ZWN0ZWQgTGlzdFZpZXdlciBsaXN0Vmlld2VyOw0KDQoJLyoqDQoJICogVGhpcyBzaG93cyBob3cgYSB0YWJsZSB2aWV3IHdvcmtzLg0KCSAqIEEgdGFibGUgY2FuIGJlIHVzZWQgYXMgYSBsaXN0IHdpdGggaWNvbnMuDQoJICogPCEtLSBiZWdpbi11c2VyLWRvYyAtLT4NCgkgKiA8IS0tIGVuZC11c2VyLWRvYyAtLT4NCgkgKiBAZ2VuZXJhdGVkDQoJICovDQoJcHJvdGVjdGVkIFRhYmxlVmlld2VyIHRhYmxlVmlld2VyOw0KDQoJLyoqDQoJICogVGhpcyBzaG93cyBob3cgYSB0cmVlIHZpZXcgd2l0aCBjb2x1bW5zIHdvcmtzLg0KCSAqIENoYW5nZWQgYnkgY2hlY2tib3ggdHJlZSAoYnkgSEVPKQ0KCSAqIEBub3QgZ2VuZXJhdGVkDQoJICovDQoJcHJvdGVjdGVkIENoZWNrYm94VHJlZVZpZXdlckV4dCB0cmVlVmlld2VyV2l0aENoZWNrOw0KDQoJLy9CZWdpbiBBTEMNCgkvKioJDQoJICogQ2hlY2tib3ggdHJlZSBhdXRvc2VsZWN0aW9uIEZsYWcgDQoJICogQG5vdCBnZW5lcmF0ZWQNCgkgKi8NCglwcm90ZWN0ZWQgYm9vbGVhbiBmaXJzdFRpbWU9dHJ1ZTsNCgkvL0VuZCBBTEMNCgkNCgkvKioNCgkgKiBUaGlzIGtlZXBzIHRyYWNrIG9mIHRoZSBhY3RpdmUgdmlld2VyIHBhbmUsIGluIHRoZSBib29rLg0KCSAqIDwhLS0gYmVnaW4tdXNlci1kb2MgLS0+DQoJICogPCEtLSBlbmQtdXNlci1kb2MgLS0+DQoJICogQGdlbmVyYXRlZA0KCSAqLw0KCXByb3RlY3RlZCBWaWV3ZXJQYW5lIGN1cnJlbnRWaWV3ZXJQYW5lOw0KDQoJLyoqDQoJICogVGhpcyBrZWVwcyB0cmFjayBvZiB0aGUgYWN0aXZlIGNvbnRlbnQgdmlld2VyLCB3aGljaCBtYXkgYmUgZWl0aGVyIG9uZSBvZiB0aGUgdmlld2VycyBpbiB0aGUgcGFnZXMgb3IgdGhlIGNvbnRlbnQgb3V0bGluZSB2aWV3ZXIuDQoJICogPCEtLSBiZWdpbi11c2VyLWRvYyAtLT4NCgkgKiA8IS0tIGVuZC11c2VyLWRvYyAtLT4NCgkgKiBAZ2VuZXJhdGVkDQoJICovDQoJcHJvdGVjdGVkIFZpZXdlciBjdXJyZW50Vmlld2VyOw0KDQoJLyoqDQoJICogVGhpcyBsaXN0ZW5zIHRvIHdoaWNoIGV2ZXIgdmlld2VyIGlzIGFjdGl2ZS4NCgkgKiA8IS0tIGJlZ2luLXVzZXItZG9jIC0tPg0KCSAqIDwhLS0gZW5kLXVzZXItZG9jIC0tPg0KCSAqIEBnZW5lcmF0ZWQNCgkgKi8NCglwcm90ZWN0ZWQgSVNlbGVjdGlvbkNoYW5nZWRMaXN0ZW5lciBzZWxlY3Rpb25DaGFuZ2VkTGlzdGVuZXI7DQoNCgkvKioNCgkgKiBUaGlzIGtlZXBzIHRyYWNrIG9mIGFsbCB0aGUge0BsaW5rIG9yZy5lY2xpcHNlLmpmYWNlLnZpZXdlcnMuSVNlbGVjdGlvbkNoYW5nZWRMaXN0ZW5lcn1zIHRoYXQgYXJlIGxpc3RlbmluZyB0byB0aGlzIGVkaXRvci4NCgkgKiA8IS0tIGJlZ2luLXVzZXItZG9jIC0tPg0KCSAqIDwhLS0gZW5kLXVzZXItZG9jIC0tPg0KCSAqIEBnZW5lcmF0ZWQNCgkgKi8NCglwcm90ZWN0ZWQgQ29sbGVjdGlvbjxJU2VsZWN0aW9uQ2hhbmdlZExpc3RlbmVyPiBzZWxlY3Rpb25DaGFuZ2VkTGlzdGVuZXJzID0gbmV3IEFycmF5TGlzdDxJU2VsZWN0aW9uQ2hhbmdlZExpc3RlbmVyPigpOw0KDQoJLyoqDQoJICogVGhpcyBrZWVwcyB0cmFjayBvZiB0aGUgc2VsZWN0aW9uIG9mIHRoZSBlZGl0b3IgYXMgYSB3aG9sZS4NCgkgKiA8IS0tIGJlZ2luLXVzZXItZG9jIC0tPg0KCSAqIDwhLS0gZW5kLXVzZXItZG9jIC0tPg0KCSAqIEBnZW5lcmF0ZWQNCgkgKi8NCglwcm90ZWN0ZWQgSVNlbGVjdGlvbiBlZGl0b3JTZWxlY3Rpb24gPSBTdHJ1Y3R1cmVkU2VsZWN0aW9uLkVNUFRZOw0KDQoJLyoqDQoJICogVGhlIE1hcmtlckhlbHBlciBpcyByZXNwb25zaWJsZSBmb3IgY3JlYXRpbmcgd29ya3NwYWNlIHJlc291cmNlIG1hcmtlcnMgcHJlc2VudGVkDQoJICogaW4gRWNsaXBzZSdzIFByb2JsZW1zIFZpZXcuDQoJICogPCEtLSBiZWdpbi11c2VyLWRvYyAtLT4NCgkgKiA8IS0tIGVuZC11c2VyLWRvYyAtLT4NCgkgKiBAZ2VuZXJhdGVkDQoJICovDQoJcHJvdGVjdGVkIE1hcmtlckhlbHBlciBtYXJrZXJIZWxwZXIgPSBuZXcgRWRpdFVJTWFya2VySGVscGVyKCk7DQoNCgkvKioNCgkgKiBUaGlzIGxpc3RlbnMgZm9yIHdoZW4gdGhlIG91dGxpbmUgYmVjb21lcyBhY3RpdmUNCgkgKiA8IS0tIGJlZ2luLXVzZXItZG9jIC0tPg0KCSAqIDwhLS0gZW5kLXVzZXItZG9jIC0tPg0KCSAqIEBnZW5lcmF0ZWQNCgkgKi8NCglwcm90ZWN0ZWQgSVBhcnRMaXN0ZW5lciBwYXJ0TGlzdGVuZXIgPQ0KCQluZXcgSVBhcnRMaXN0ZW5lcigpIHsNCgkJCXB1YmxpYyB2b2lkIHBhcnRBY3RpdmF0ZWQoSVdvcmtiZW5jaFBhcnQgcCkgew0KCQkJCWlmIChwIGluc3RhbmNlb2YgQ29udGVudE91dGxpbmUpIHsNCgkJCQkJaWYgKCgoQ29udGVudE91dGxpbmUpcCkuZ2V0Q3VycmVudFBhZ2UoKSA9PSBjb250ZW50T3V0bGluZVBhZ2UpIHsNCgkJCQkJCWdldEFjdGlvbkJhckNvbnRyaWJ1dG9yKCkuc2V0QWN0aXZlRWRpdG9yKEFyZ0VkaXRvci50aGlzKTsNCg0KCQkJCQkJc2V0Q3VycmVudFZpZXdlcihjb250ZW50T3V0bGluZVZpZXdlcik7DQoJCQkJCX0NCgkJCQl9DQoJCQkJZWxzZSBpZiAocCBpbnN0YW5jZW9mIFByb3BlcnR5U2hlZXQpIHsNCgkJCQkJaWYgKHByb3BlcnR5U2hlZXRQYWdlcy5jb250YWlucygoKFByb3BlcnR5U2hlZXQpcCkuZ2V0Q3VycmVudFBhZ2UoKSkpIHsNCgkJCQkJCWdldEFjdGlvbkJhckNvbnRyaWJ1dG9yKCkuc2V0QWN0aXZlRWRpdG9yKEFyZ0VkaXRvci50aGlzKTsNCgkJCQkJCWhhbmRsZUFjdGl2YXRlKCk7DQoJCQkJCX0NCgkJCQl9DQoJCQkJZWxzZSBpZiAocCA9PSBBcmdFZGl0b3IudGhpcykgew0KCQkJCQloYW5kbGVBY3RpdmF0ZSgpOw0KCQkJCX0NCgkJCX0NCgkJCXB1YmxpYyB2b2lkIHBhcnRCcm91Z2h0VG9Ub3AoSVdvcmtiZW5jaFBhcnQgcCkgew0KCQkJCS8vIElnbm9yZS4NCgkJCX0NCgkJCXB1YmxpYyB2b2lkIHBhcnRDbG9zZWQoSVdvcmtiZW5jaFBhcnQgcCkgew0KCQkJCS8vIElnbm9yZS4NCgkJCX0NCgkJCXB1YmxpYyB2b2lkIHBhcnREZWFjdGl2YXRlZChJV29ya2JlbmNoUGFydCBwKSB7DQoJCQkJLy8gSWdub3JlLg0KCQkJfQ0KCQkJcHVibGljIHZvaWQgcGFydE9wZW5lZChJV29ya2JlbmNoUGFydCBwKSB7DQoJCQkJLy8gSWdub3JlLg0KCQkJfQ0KCQl9Ow0KDQoJLyoqDQoJICogUmVzb3VyY2VzIHRoYXQgaGF2ZSBiZWVuIHJlbW92ZWQgc2luY2UgbGFzdCBhY3RpdmF0aW9uLg0KCSAqIDwhLS0gYmVnaW4tdXNlci1kb2MgLS0+DQoJICogPCEtLSBlbmQtdXNlci1kb2MgLS0+DQoJICogQGdlbmVyYXRlZA0KCSAqLw0KCXByb3RlY3RlZCBDb2xsZWN0aW9uPFJlc291cmNlPiByZW1vdmVkUmVzb3VyY2VzID0gbmV3IEFycmF5TGlzdDxSZXNvdXJjZT4oKTsNCg0KCS8qKg0KCSAqIFJlc291cmNlcyB0aGF0IGhhdmUgYmVlbiBjaGFuZ2VkIHNpbmNlIGxhc3QgYWN0aXZhdGlvbi4NCgkgKiA8IS0tIGJlZ2luLXVzZXItZG9jIC0tPg0KCSAqIDwhLS0gZW5kLXVzZXItZG9jIC0tPg0KCSAqIEBnZW5lcmF0ZWQNCgkgKi8NCglwcm90ZWN0ZWQgQ29sbGVjdGlvbjxSZXNvdXJjZT4gY2hhbmdlZFJlc291cmNlcyA9IG5ldyBBcnJheUxpc3Q8UmVzb3VyY2U+KCk7DQoNCgkvKioNCgkgKiBSZXNvdXJjZXMgdGhhdCBoYXZlIGJlZW4gc2F2ZWQuDQoJICogPCEtLSBiZWdpbi11c2VyLWRvYyAtLT4NCgkgKiA8IS0tIGVuZC11c2VyLWRvYyAtLT4NCgkgKiBAZ2VuZXJhdGVkDQoJICovDQoJcHJvdGVjdGVkIENvbGxlY3Rpb248UmVzb3VyY2U+IHNhdmVkUmVzb3VyY2VzID0gbmV3IEFycmF5TGlzdDxSZXNvdXJjZT4oKTsNCg0KCS8qKg0KCSAqIE1hcCB0byBzdG9yZSB0aGUgZGlhZ25vc3RpYyBhc3NvY2lhdGVkIHdpdGggYSByZXNvdXJjZS4NCgkgKiA8IS0tIGJlZ2luLXVzZXItZG9jIC0tPg0KCSAqIDwhLS0gZW5kLXVzZXItZG9jIC0tPg0KCSAqIEBnZW5lcmF0ZWQNCgkgKi8NCglwcm90ZWN0ZWQgTWFwPFJlc291cmNlLCBEaWFnbm9zdGljPiByZXNvdXJjZVRvRGlhZ25vc3RpY01hcCA9IG5ldyBMaW5rZWRIYXNoTWFwPFJlc291cmNlLCBEaWFnbm9zdGljPigpOw0KDQoJLyoqDQoJICogQ29udHJvbHMgd2hldGhlciB0aGUgcHJvYmxlbSBpbmRpY2F0aW9uIHNob3VsZCBiZSB1cGRhdGVkLg0KCSAqIDwhLS0gYmVnaW4tdXNlci1kb2MgLS0+DQoJICogPCEtLSBlbmQtdXNlci1kb2MgLS0+DQoJICogQGdlbmVyYXRlZA0KCSAqLw0KCXByb3RlY3RlZCBib29sZWFuIHVwZGF0ZVByb2JsZW1JbmRpY2F0aW9uID0gdHJ1ZTsNCg0KCS8qKg0KCSAqIEFkYXB0ZXIgdXNlZCB0byB1cGRhdGUgdGhlIHByb2JsZW0gaW5kaWNhdGlvbiB3aGVuIHJlc291cmNlcyBhcmUgZGVtYW5kZWQgbG9hZGVkLg0KCSAqIDwhLS0gYmVnaW4tdXNlci1kb2MgLS0+DQoJICogPCEtLSBlbmQtdXNlci1kb2MgLS0+DQoJICogQGdlbmVyYXRlZA0KCSAqLw0KCXByb3RlY3RlZCBFQ29udGVudEFkYXB0ZXIgcHJvYmxlbUluZGljYXRpb25BZGFwdGVyID0NCgkJbmV3IEVDb250ZW50QWRhcHRlcigpIHsNCgkJCUBPdmVycmlkZQ0KCQkJcHVibGljIHZvaWQgbm90aWZ5Q2hhbmdlZChOb3RpZmljYXRpb24gbm90aWZpY2F0aW9uKSB7DQoJCQkJaWYgKG5vdGlmaWNhdGlvbi5nZXROb3RpZmllcigpIGluc3RhbmNlb2YgUmVzb3VyY2UpIHsNCgkJCQkJc3dpdGNoIChub3RpZmljYXRpb24uZ2V0RmVhdHVyZUlEKFJlc291cmNlLmNsYXNzKSkgew0KCQkJCQkJY2FzZSBSZXNvdXJjZS5SRVNPVVJDRV9fSVNfTE9BREVEOg0KCQkJCQkJY2FzZSBSZXNvdXJjZS5SRVNPVVJDRV9fRVJST1JTOg0KCQkJCQkJY2FzZSBSZXNvdXJjZS5SRVNPVVJDRV9fV0FSTklOR1M6IHsNCgkJCQkJCQlSZXNvdXJjZSByZXNvdXJjZSA9IChSZXNvdXJjZSlub3RpZmljYXRpb24uZ2V0Tm90aWZpZXIoKTsNCgkJCQkJCQlEaWFnbm9zdGljIGRpYWdub3N0aWMgPSBhbmFseXplUmVzb3VyY2VQcm9ibGVtcyhyZXNvdXJjZSwgbnVsbCk7DQoJCQkJCQkJaWYgKGRpYWdub3N0aWMuZ2V0U2V2ZXJpdHkoKSAhPSBEaWFnbm9zdGljLk9LKSB7DQoJCQkJCQkJCXJlc291cmNlVG9EaWFnbm9zdGljTWFwLnB1dChyZXNvdXJjZSwgZGlhZ25vc3RpYyk7DQoJCQkJCQkJfQ0KCQkJCQkJCWVsc2Ugew0KCQkJCQkJCQlyZXNvdXJjZVRvRGlhZ25vc3RpY01hcC5yZW1vdmUocmVzb3VyY2UpOw0KCQkJCQkJCX0NCg0KCQkJCQkJCWlmICh1cGRhdGVQcm9ibGVtSW5kaWNhdGlvbikgew0KCQkJCQkJCQlnZXRTaXRlKCkuZ2V0U2hlbGwoKS5nZXREaXNwbGF5KCkuYXN5bmNFeGVjDQoJCQkJCQkJCQkobmV3IFJ1bm5hYmxlKCkgew0KCQkJCQkJCQkJCSBwdWJsaWMgdm9pZCBydW4oKSB7DQoJCQkJCQkJCQkJCSB1cGRhdGVQcm9ibGVtSW5kaWNhdGlvbigpOw0KCQkJCQkJCQkJCSB9DQoJCQkJCQkJCQkgfSk7DQoJCQkJCQkJfQ0KCQkJCQkJCWJyZWFrOw0KCQkJCQkJfQ0KCQkJCQl9DQoJCQkJfQ0KCQkJCWVsc2Ugew0KCQkJCQlzdXBlci5ub3RpZnlDaGFuZ2VkKG5vdGlmaWNhdGlvbik7DQoJCQkJfQ0KCQkJfQ0KDQoJCQlAT3ZlcnJpZGUNCgkJCXByb3RlY3RlZCB2b2lkIHNldFRhcmdldChSZXNvdXJjZSB0YXJnZXQpIHsNCgkJCQliYXNpY1NldFRhcmdldCh0YXJnZXQpOw0KCQkJfQ0KDQoJCQlAT3ZlcnJpZGUNCgkJCXByb3RlY3RlZCB2b2lkIHVuc2V0VGFyZ2V0KFJlc291cmNlIHRhcmdldCkgew0KCQkJCWJhc2ljVW5zZXRUYXJnZXQodGFyZ2V0KTsNCgkJCQlyZXNvdXJjZVRvRGlhZ25vc3RpY01hcC5yZW1vdmUodGFyZ2V0KTsNCgkJCQlpZiAodXBkYXRlUHJvYmxlbUluZGljYXRpb24pIHsNCgkJCQkJZ2V0U2l0ZSgpLmdldFNoZWxsKCkuZ2V0RGlzcGxheSgpLmFzeW5jRXhlYw0KCQkJCQkJKG5ldyBSdW5uYWJsZSgpIHsNCgkJCQkJCQkgcHVibGljIHZvaWQgcnVuKCkgew0KCQkJCQkJCQkgdXBkYXRlUHJvYmxlbUluZGljYXRpb24oKTsNCgkJCQkJCQkgfQ0KCQkJCQkJIH0pOw0KCQkJCX0NCgkJCX0NCgkJfTsNCg0KCS8qKg0KCSAqIFRoaXMgbGlzdGVucyBmb3Igd29ya3NwYWNlIGNoYW5nZXMuDQoJICogPCEtLSBiZWdpbi11c2VyLWRvYyAtLT4NCgkgKiA8IS0tIGVuZC11c2VyLWRvYyAtLT4NCgkgKiBAZ2VuZXJhdGVkDQoJICovDQoJcHJvdGVjdGVkIElSZXNvdXJjZUNoYW5nZUxpc3RlbmVyIHJlc291cmNlQ2hhbmdlTGlzdGVuZXIgPQ0KCQluZXcgSVJlc291cmNlQ2hhbmdlTGlzdGVuZXIoKSB7DQoJCQlwdWJsaWMgdm9pZCByZXNvdXJjZUNoYW5nZWQoSVJlc291cmNlQ2hhbmdlRXZlbnQgZXZlbnQpIHsNCgkJCQlJUmVzb3VyY2VEZWx0YSBkZWx0YSA9IGV2ZW50LmdldERlbHRhKCk7DQoJCQkJdHJ5IHsNCgkJCQkJY2xhc3MgUmVzb3VyY2VEZWx0YVZpc2l0b3IgaW1wbGVtZW50cyBJUmVzb3VyY2VEZWx0YVZpc2l0b3Igew0KCQkJCQkJcHJvdGVjdGVkIFJlc291cmNlU2V0IHJlc291cmNlU2V0ID0gZWRpdGluZ0RvbWFpbi5nZXRSZXNvdXJjZVNldCgpOw0KCQkJCQkJcHJvdGVjdGVkIENvbGxlY3Rpb248UmVzb3VyY2U+IGNoYW5nZWRSZXNvdXJjZXMgPSBuZXcgQXJyYXlMaXN0PFJlc291cmNlPigpOw0KCQkJCQkJcHJvdGVjdGVkIENvbGxlY3Rpb248UmVzb3VyY2U+IHJlbW92ZWRSZXNvdXJjZXMgPSBuZXcgQXJyYXlMaXN0PFJlc291cmNlPigpOw0KDQoJCQkJCQlwdWJsaWMgYm9vbGVhbiB2aXNpdChJUmVzb3VyY2VEZWx0YSBkZWx0YSkgew0KCQkJCQkJCWlmIChkZWx0YS5nZXRSZXNvdXJjZSgpLmdldFR5cGUoKSA9PSBJUmVzb3VyY2UuRklMRSkgew0KCQkJCQkJCQlpZiAoZGVsdGEuZ2V0S2luZCgpID09IElSZXNvdXJjZURlbHRhLlJFTU9WRUQgfHwNCgkJCQkJCQkJICAgIGRlbHRhLmdldEtpbmQoKSA9PSBJUmVzb3VyY2VEZWx0YS5DSEFOR0VEICYmIGRlbHRhLmdldEZsYWdzKCkgIT0gSVJlc291cmNlRGVsdGEuTUFSS0VSUykgew0KCQkJCQkJCQkJUmVzb3VyY2UgcmVzb3VyY2UgPSByZXNvdXJjZVNldC5nZXRSZXNvdXJjZShVUkkuY3JlYXRlUGxhdGZvcm1SZXNvdXJjZVVSSShkZWx0YS5nZXRGdWxsUGF0aCgpLnRvU3RyaW5nKCksIHRydWUpLCBmYWxzZSk7DQoJCQkJCQkJCQlpZiAocmVzb3VyY2UgIT0gbnVsbCkgew0KCQkJCQkJCQkJCWlmIChkZWx0YS5nZXRLaW5kKCkgPT0gSVJlc291cmNlRGVsdGEuUkVNT1ZFRCkgew0KCQkJCQkJCQkJCQlyZW1vdmVkUmVzb3VyY2VzLmFkZChyZXNvdXJjZSk7DQoJCQkJCQkJCQkJfQ0KCQkJCQkJCQkJCWVsc2UgaWYgKCFzYXZlZFJlc291cmNlcy5yZW1vdmUocmVzb3VyY2UpKSB7DQoJCQkJCQkJCQkJCWNoYW5nZWRSZXNvdXJjZXMuYWRkKHJlc291cmNlKTsNCgkJCQkJCQkJCQl9DQoJCQkJCQkJCQl9DQoJCQkJCQkJCX0NCgkJCQkJCQkJcmV0dXJuIGZhbHNlOw0KCQkJCQkJCX0NCg0KCQkJCQkJCXJldHVybiB0cnVlOw0KCQkJCQkJfQ0KDQoJCQkJCQlwdWJsaWMgQ29sbGVjdGlvbjxSZXNvdXJjZT4gZ2V0Q2hhbmdlZFJlc291cmNlcygpIHsNCgkJCQkJCQlyZXR1cm4gY2hhbmdlZFJlc291cmNlczsNCgkJCQkJCX0NCg0KCQkJCQkJcHVibGljIENvbGxlY3Rpb248UmVzb3VyY2U+IGdldFJlbW92ZWRSZXNvdXJjZXMoKSB7DQoJCQkJCQkJcmV0dXJuIHJlbW92ZWRSZXNvdXJjZXM7DQoJCQkJCQl9DQoJCQkJCX0NCg0KCQkJCQlmaW5hbCBSZXNvdXJjZURlbHRhVmlzaXRvciB2aXNpdG9yID0gbmV3IFJlc291cmNlRGVsdGFWaXNpdG9yKCk7DQoJCQkJCWRlbHRhLmFjY2VwdCh2aXNpdG9yKTsNCg0KCQkJCQlpZiAoIXZpc2l0b3IuZ2V0UmVtb3ZlZFJlc291cmNlcygpLmlzRW1wdHkoKSkgew0KCQkJCQkJZ2V0U2l0ZSgpLmdldFNoZWxsKCkuZ2V0RGlzcGxheSgpLmFzeW5jRXhlYw0KCQkJCQkJCShuZXcgUnVubmFibGUoKSB7DQoJCQkJCQkJCSBwdWJsaWMgdm9pZCBydW4oKSB7DQoJCQkJCQkJCQkgcmVtb3ZlZFJlc291cmNlcy5hZGRBbGwodmlzaXRvci5nZXRSZW1vdmVkUmVzb3VyY2VzKCkpOw0KCQkJCQkJCQkJIGlmICghaXNEaXJ0eSgpKSB7DQoJCQkJCQkJCQkJIGdldFNpdGUoKS5nZXRQYWdlKCkuY2xvc2VFZGl0b3IoQXJnRWRpdG9yLnRoaXMsIGZhbHNlKTsNCgkJCQkJCQkJCSB9DQoJCQkJCQkJCSB9DQoJCQkJCQkJIH0pOw0KCQkJCQl9DQoNCgkJCQkJaWYgKCF2aXNpdG9yLmdldENoYW5nZWRSZXNvdXJjZXMoKS5pc0VtcHR5KCkpIHsNCgkJCQkJCWdldFNpdGUoKS5nZXRTaGVsbCgpLmdldERpc3BsYXkoKS5hc3luY0V4ZWMNCgkJCQkJCQkobmV3IFJ1bm5hYmxlKCkgew0KCQkJCQkJCQkgcHVibGljIHZvaWQgcnVuKCkgew0KCQkJCQkJCQkJIGNoYW5nZWRSZXNvdXJjZXMuYWRkQWxsKHZpc2l0b3IuZ2V0Q2hhbmdlZFJlc291cmNlcygpKTsNCgkJCQkJCQkJCSBpZiAoZ2V0U2l0ZSgpLmdldFBhZ2UoKS5nZXRBY3RpdmVFZGl0b3IoKSA9PSBBcmdFZGl0b3IudGhpcykgew0KCQkJCQkJCQkJCSBoYW5kbGVBY3RpdmF0ZSgpOw0KCQkJCQkJCQkJIH0NCgkJCQkJCQkJIH0NCgkJCQkJCQkgfSk7DQoJCQkJCX0NCgkJCQl9DQoJCQkJY2F0Y2ggKENvcmVFeGNlcHRpb24gZXhjZXB0aW9uKSB7DQoJCQkJCUFyZ0VkaXRvclBsdWdpbi5JTlNUQU5DRS5sb2coZXhjZXB0aW9uKTsNCgkJCQl9DQoJCQl9DQoJCX07DQoNCgkvKioNCgkgKiBIYW5kbGVzIGFjdGl2YXRpb24gb2YgdGhlIGVkaXRvciBvciBpdCdzIGFzc29jaWF0ZWQgdmlld3MuDQoJICogPCEtLSBiZWdpbi11c2VyLWRvYyAtLT4NCgkgKiA8IS0tIGVuZC11c2VyLWRvYyAtLT4NCgkgKiBAZ2VuZXJhdGVkDQoJICovDQoJcHJvdGVjdGVkIHZvaWQgaGFuZGxlQWN0aXZhdGUoKSB7DQoJCS8vIFJlY29tcHV0ZSB0aGUgcmVhZCBvbmx5IHN0YXRlLg0KCQkvLw0KCQlpZiAoZWRpdGluZ0RvbWFpbi5nZXRSZXNvdXJjZVRvUmVhZE9ubHlNYXAoKSAhPSBudWxsKSB7DQoJCSAgZWRpdGluZ0RvbWFpbi5nZXRSZXNvdXJjZVRvUmVhZE9ubHlNYXAoKS5jbGVhcigpOw0KDQoJCSAgLy8gUmVmcmVzaCBhbnkgYWN0aW9ucyB0aGF0IG1heSBiZWNvbWUgZW5hYmxlZCBvciBkaXNhYmxlZC4NCgkJICAvLw0KCQkgIHNldFNlbGVjdGlvbihnZXRTZWxlY3Rpb24oKSk7DQoJCX0NCg0KCQlpZiAoIXJlbW92ZWRSZXNvdXJjZXMuaXNFbXB0eSgpKSB7DQoJCQlpZiAoaGFuZGxlRGlydHlDb25mbGljdCgpKSB7DQoJCQkJZ2V0U2l0ZSgpLmdldFBhZ2UoKS5jbG9zZUVkaXRvcihBcmdFZGl0b3IudGhpcywgZmFsc2UpOw0KCQkJfQ0KCQkJZWxzZSB7DQoJCQkJcmVtb3ZlZFJlc291cmNlcy5jbGVhcigpOw0KCQkJCWNoYW5nZWRSZXNvdXJjZXMuY2xlYXIoKTsNCgkJCQlzYXZlZFJlc291cmNlcy5jbGVhcigpOw0KCQkJfQ0KCQl9DQoJCWVsc2UgaWYgKCFjaGFuZ2VkUmVzb3VyY2VzLmlzRW1wdHkoKSkgew0KCQkJY2hhbmdlZFJlc291cmNlcy5yZW1vdmVBbGwoc2F2ZWRSZXNvdXJjZXMpOw0KCQkJaGFuZGxlQ2hhbmdlZFJlc291cmNlcygpOw0KCQkJY2hhbmdlZFJlc291cmNlcy5jbGVhcigpOw0KCQkJc2F2ZWRSZXNvdXJjZXMuY2xlYXIoKTsNCgkJfQ0KCX0NCg0KCS8qKg0KCSAqIEhhbmRsZXMgd2hhdCB0byBkbyB3aXRoIGNoYW5nZWQgcmVzb3VyY2VzIG9uIGFjdGl2YXRpb24uDQoJICogPCEtLSBiZWdpbi11c2VyLWRvYyAtLT4NCgkgKiA8IS0tIGVuZC11c2VyLWRvYyAtLT4NCgkgKiBAZ2VuZXJhdGVkDQoJICovDQoJcHJvdGVjdGVkIHZvaWQgaGFuZGxlQ2hhbmdlZFJlc291cmNlcygpIHsNCgkJaWYgKCFjaGFuZ2VkUmVzb3VyY2VzLmlzRW1wdHkoKSAmJiAoIWlzRGlydHkoKSB8fCBoYW5kbGVEaXJ0eUNvbmZsaWN0KCkpKSB7DQoJCQlpZiAoaXNEaXJ0eSgpKSB7DQoJCQkJY2hhbmdlZFJlc291cmNlcy5hZGRBbGwoZWRpdGluZ0RvbWFpbi5nZXRSZXNvdXJjZVNldCgpLmdldFJlc291cmNlcygpKTsNCgkJCX0NCgkJCWVkaXRpbmdEb21haW4uZ2V0Q29tbWFuZFN0YWNrKCkuZmx1c2goKTsNCg0KCQkJdXBkYXRlUHJvYmxlbUluZGljYXRpb24gPSBmYWxzZTsNCgkJCWZvciAoUmVzb3VyY2UgcmVzb3VyY2UgOiBjaGFuZ2VkUmVzb3VyY2VzKSB7DQoJCQkJaWYgKHJlc291cmNlLmlzTG9hZGVkKCkpIHsNCgkJCQkJcmVzb3VyY2UudW5sb2FkKCk7DQoJCQkJCXRyeSB7DQoJCQkJCQlyZXNvdXJjZS5sb2FkKENvbGxlY3Rpb25zLkVNUFRZX01BUCk7DQoJCQkJCX0NCgkJCQkJY2F0Y2ggKElPRXhjZXB0aW9uIGV4Y2VwdGlvbikgew0KCQkJCQkJaWYgKCFyZXNvdXJjZVRvRGlhZ25vc3RpY01hcC5jb250YWluc0tleShyZXNvdXJjZSkpIHsNCgkJCQkJCQlyZXNvdXJjZVRvRGlhZ25vc3RpY01hcC5wdXQocmVzb3VyY2UsIGFuYWx5emVSZXNvdXJjZVByb2JsZW1zKHJlc291cmNlLCBleGNlcHRpb24pKTsNCgkJCQkJCX0NCgkJCQkJfQ0KCQkJCX0NCgkJCX0NCg0KCQkJaWYgKEFkYXB0ZXJGYWN0b3J5RWRpdGluZ0RvbWFpbi5pc1N0YWxlKGVkaXRvclNlbGVjdGlvbikpIHsNCgkJCQlzZXRTZWxlY3Rpb24oU3RydWN0dXJlZFNlbGVjdGlvbi5FTVBUWSk7DQoJCQl9DQoNCgkJCXVwZGF0ZVByb2JsZW1JbmRpY2F0aW9uID0gdHJ1ZTsNCgkJCXVwZGF0ZVByb2JsZW1JbmRpY2F0aW9uKCk7DQoJCX0NCgl9DQoNCgkvKioNCgkgKiBVcGRhdGVzIHRoZSBwcm9ibGVtcyBpbmRpY2F0aW9uIHdpdGggdGhlIGluZm9ybWF0aW9uIGRlc2NyaWJlZCBpbiB0aGUgc3BlY2lmaWVkIGRpYWdub3N0aWMuDQoJICogPCEtLSBiZWdpbi11c2VyLWRvYyAtLT4NCgkgKiA8IS0tIGVuZC11c2VyLWRvYyAtLT4NCgkgKiBAZ2VuZXJhdGVkDQoJICovDQoJcHJvdGVjdGVkIHZvaWQgdXBkYXRlUHJvYmxlbUluZGljYXRpb24oKSB7DQoJCWlmICh1cGRhdGVQcm9ibGVtSW5kaWNhdGlvbikgew0KCQkJQmFzaWNEaWFnbm9zdGljIGRpYWdub3N0aWMgPQ0KCQkJCW5ldyBCYXNpY0RpYWdub3N0aWMNCgkJCQkJKERpYWdub3N0aWMuT0ssDQoJCQkJCSAib3JnLmVjbGlwc2Uub3BlbmNlcnQuc2FtLmFyZy5lZGl0b3IiLA0KCQkJCQkgMCwNCgkJCQkJIG51bGwsDQoJCQkJCSBuZXcgT2JqZWN0IFtdIHsgZWRpdGluZ0RvbWFpbi5nZXRSZXNvdXJjZVNldCgpIH0pOw0KCQkJZm9yIChEaWFnbm9zdGljIGNoaWxkRGlhZ25vc3RpYyA6IHJlc291cmNlVG9EaWFnbm9zdGljTWFwLnZhbHVlcygpKSB7DQoJCQkJaWYgKGNoaWxkRGlhZ25vc3RpYy5nZXRTZXZlcml0eSgpICE9IERpYWdub3N0aWMuT0spIHsNCgkJCQkJZGlhZ25vc3RpYy5hZGQoY2hpbGREaWFnbm9zdGljKTsNCgkJCQl9DQoJCQl9DQoNCgkJCWludCBsYXN0RWRpdG9yUGFnZSA9IGdldFBhZ2VDb3VudCgpIC0gMTsNCgkJCWlmIChsYXN0RWRpdG9yUGFnZSA+PSAwICYmIGdldEVkaXRvcihsYXN0RWRpdG9yUGFnZSkgaW5zdGFuY2VvZiBQcm9ibGVtRWRpdG9yUGFydCkgew0KCQkJCSgoUHJvYmxlbUVkaXRvclBhcnQpZ2V0RWRpdG9yKGxhc3RFZGl0b3JQYWdlKSkuc2V0RGlhZ25vc3RpYyhkaWFnbm9zdGljKTsNCgkJCQlpZiAoZGlhZ25vc3RpYy5nZXRTZXZlcml0eSgpICE9IERpYWdub3N0aWMuT0spIHsNCgkJCQkJc2V0QWN0aXZlUGFnZShsYXN0RWRpdG9yUGFnZSk7DQoJCQkJfQ0KCQkJfQ0KCQkJZWxzZSBpZiAoZGlhZ25vc3RpYy5nZXRTZXZlcml0eSgpICE9IERpYWdub3N0aWMuT0spIHsNCgkJCQlQcm9ibGVtRWRpdG9yUGFydCBwcm9ibGVtRWRpdG9yUGFydCA9IG5ldyBQcm9ibGVtRWRpdG9yUGFydCgpOw0KCQkJCXByb2JsZW1FZGl0b3JQYXJ0LnNldERpYWdub3N0aWMoZGlhZ25vc3RpYyk7DQoJCQkJcHJvYmxlbUVkaXRvclBhcnQuc2V0TWFya2VySGVscGVyKG1hcmtlckhlbHBlcik7DQoJCQkJdHJ5IHsNCgkJCQkJYWRkUGFnZSgrK2xhc3RFZGl0b3JQYWdlLCBwcm9ibGVtRWRpdG9yUGFydCwgZ2V0RWRpdG9ySW5wdXQoKSk7DQoJCQkJCXNldFBhZ2VUZXh0KGxhc3RFZGl0b3JQYWdlLCBwcm9ibGVtRWRpdG9yUGFydC5nZXRQYXJ0TmFtZSgpKTsNCgkJCQkJc2V0QWN0aXZlUGFnZShsYXN0RWRpdG9yUGFnZSk7DQoJCQkJCXNob3dUYWJzKCk7DQoJCQkJfQ0KCQkJCWNhdGNoIChQYXJ0SW5pdEV4Y2VwdGlvbiBleGNlcHRpb24pIHsNCgkJCQkJQXJnRWRpdG9yUGx1Z2luLklOU1RBTkNFLmxvZyhleGNlcHRpb24pOw0KCQkJCX0NCgkJCX0NCg0KCQkJaWYgKG1hcmtlckhlbHBlci5oYXNNYXJrZXJzKGVkaXRpbmdEb21haW4uZ2V0UmVzb3VyY2VTZXQoKSkpIHsNCgkJCQltYXJrZXJIZWxwZXIuZGVsZXRlTWFya2VycyhlZGl0aW5nRG9tYWluLmdldFJlc291cmNlU2V0KCkpOw0KCQkJCWlmIChkaWFnbm9zdGljLmdldFNldmVyaXR5KCkgIT0gRGlhZ25vc3RpYy5PSykgew0KCQkJCQl0cnkgew0KCQkJCQkJbWFya2VySGVscGVyLmNyZWF0ZU1hcmtlcnMoZGlhZ25vc3RpYyk7DQoJCQkJCX0NCgkJCQkJY2F0Y2ggKENvcmVFeGNlcHRpb24gZXhjZXB0aW9uKSB7DQoJCQkJCQlBcmdFZGl0b3JQbHVnaW4uSU5TVEFOQ0UubG9nKGV4Y2VwdGlvbik7DQoJCQkJCX0NCgkJCQl9DQoJCQl9DQoJCX0NCgl9DQoNCgkvKioNCgkgKiBTaG93cyBhIGRpYWxvZyB0aGF0IGFza3MgaWYgY29uZmxpY3RpbmcgY2hhbmdlcyBzaG91bGQgYmUgZGlzY2FyZGVkLg0KCSAqIDwhLS0gYmVnaW4tdXNlci1kb2MgLS0+DQoJICogPCEtLSBlbmQtdXNlci1kb2MgLS0+DQoJICogQGdlbmVyYXRlZA0KCSAqLw0KCXByb3RlY3RlZCBib29sZWFuIGhhbmRsZURpcnR5Q29uZmxpY3QoKSB7DQoJCXJldHVybg0KCQkJTWVzc2FnZURpYWxvZy5vcGVuUXVlc3Rpb24NCgkJCQkoZ2V0U2l0ZSgpLmdldFNoZWxsKCksDQoJCQkJIGdldFN0cmluZygiX1VJX0ZpbGVDb25mbGljdF9sYWJlbCIpLA0KCQkJCSBnZXRTdHJpbmcoIl9XQVJOX0ZpbGVDb25mbGljdCIpKTsNCgl9DQoNCgkvKioNCgkgKiBUaGlzIGNyZWF0ZXMgYSBtb2RlbCBlZGl0b3IuDQoJICogPCEtLSBiZWdpbi11c2VyLWRvYyAtLT4NCgkgKiA8IS0tIGVuZC11c2VyLWRvYyAtLT4NCgkgKiBAZ2VuZXJhdGVkDQoJICovDQoJcHVibGljIEFyZ0VkaXRvcigpIHsNCgkJc3VwZXIoKTsNCgkJaW5pdGlhbGl6ZUVkaXRpbmdEb21haW4oKTsNCgl9DQoNCgkvKioNCgkgKiBUaGlzIHNldHMgdXAgdGhlIGVkaXRpbmcgZG9tYWluIGZvciB0aGUgbW9kZWwgZWRpdG9yLg0KCSAqIDwhLS0gYmVnaW4tdXNlci1kb2MgLS0+DQoJICogPCEtLSBlbmQtdXNlci1kb2MgLS0+DQoJICogQGdlbmVyYXRlZA0KCSAqLw0KCXByb3RlY3RlZCB2b2lkIGluaXRpYWxpemVFZGl0aW5nRG9tYWluKCkgew0KCQkvLyBDcmVhdGUgYW4gYWRhcHRlciBmYWN0b3J5IHRoYXQgeWllbGRzIGl0ZW0gcHJvdmlkZXJzLg0KCQkvLw0KCQlhZGFwdGVyRmFjdG9yeSA9IG5ldyBDb21wb3NlZEFkYXB0ZXJGYWN0b3J5KENvbXBvc2VkQWRhcHRlckZhY3RvcnkuRGVzY3JpcHRvci5SZWdpc3RyeS5JTlNUQU5DRSk7DQoNCgkJYWRhcHRlckZhY3RvcnkuYWRkQWRhcHRlckZhY3RvcnkobmV3IFJlc291cmNlSXRlbVByb3ZpZGVyQWRhcHRlckZhY3RvcnkoKSk7DQoJCWFkYXB0ZXJGYWN0b3J5LmFkZEFkYXB0ZXJGYWN0b3J5KG5ldyBBcmdJdGVtUHJvdmlkZXJBZGFwdGVyRmFjdG9yeSgpKTsNCgkJYWRhcHRlckZhY3RvcnkuYWRkQWRhcHRlckZhY3RvcnkobmV3IEFzc3VyYW5jZWFzc2V0SXRlbVByb3ZpZGVyQWRhcHRlckZhY3RvcnkoKSk7DQoJCWFkYXB0ZXJGYWN0b3J5LmFkZEFkYXB0ZXJGYWN0b3J5KG5ldyBHZW5lcmFsSXRlbVByb3ZpZGVyQWRhcHRlckZhY3RvcnkoKSk7DQoJCWFkYXB0ZXJGYWN0b3J5LmFkZEFkYXB0ZXJGYWN0b3J5KG5ldyBQcm9wZXJ0eUl0ZW1Qcm92aWRlckFkYXB0ZXJGYWN0b3J5KCkpOw0KCQlhZGFwdGVyRmFjdG9yeS5hZGRBZGFwdGVyRmFjdG9yeShuZXcgUmVmbGVjdGl2ZUl0ZW1Qcm92aWRlckFkYXB0ZXJGYWN0b3J5KCkpOw0KDQoJCS8vIENyZWF0ZSB0aGUgY29tbWFuZCBzdGFjayB0aGF0IHdpbGwgbm90aWZ5IHRoaXMgZWRpdG9yIGFzIGNvbW1hbmRzIGFyZSBleGVjdXRlZC4NCgkJLy8NCgkJQmFzaWNDb21tYW5kU3RhY2sgY29tbWFuZFN0YWNrID0gbmV3IEJhc2ljQ29tbWFuZFN0YWNrKCk7DQoNCgkJLy8gQWRkIGEgbGlzdGVuZXIgdG8gc2V0IHRoZSBtb3N0IHJlY2VudCBjb21tYW5kJ3MgYWZmZWN0ZWQgb2JqZWN0cyB0byBiZSB0aGUgc2VsZWN0aW9uIG9mIHRoZSB2aWV3ZXIgd2l0aCBmb2N1cy4NCgkJLy8NCgkJY29tbWFuZFN0YWNrLmFkZENvbW1hbmRTdGFja0xpc3RlbmVyDQoJCQkobmV3IENvbW1hbmRTdGFja0xpc3RlbmVyKCkgew0KCQkJCSBwdWJsaWMgdm9pZCBjb21tYW5kU3RhY2tDaGFuZ2VkKGZpbmFsIEV2ZW50T2JqZWN0IGV2ZW50KSB7DQoJCQkJCSBnZXRDb250YWluZXIoKS5nZXREaXNwbGF5KCkuYXN5bmNFeGVjDQoJCQkJCQkgKG5ldyBSdW5uYWJsZSgpIHsNCgkJCQkJCQkgIHB1YmxpYyB2b2lkIHJ1bigpIHsNCgkJCQkJCQkJICBmaXJlUHJvcGVydHlDaGFuZ2UoSUVkaXRvclBhcnQuUFJPUF9ESVJUWSk7DQoNCgkJCQkJCQkJICAvLyBUcnkgdG8gc2VsZWN0IHRoZSBhZmZlY3RlZCBvYmplY3RzLg0KCQkJCQkJCQkgIC8vDQoJCQkJCQkJCSAgQ29tbWFuZCBtb3N0UmVjZW50Q29tbWFuZCA9ICgoQ29tbWFuZFN0YWNrKWV2ZW50LmdldFNvdXJjZSgpKS5nZXRNb3N0UmVjZW50Q29tbWFuZCgpOw0KCQkJCQkJCQkgIGlmIChtb3N0UmVjZW50Q29tbWFuZCAhPSBudWxsKSB7DQoJCQkJCQkJCQkgIHNldFNlbGVjdGlvblRvVmlld2VyKG1vc3RSZWNlbnRDb21tYW5kLmdldEFmZmVjdGVkT2JqZWN0cygpKTsNCgkJCQkJCQkJICB9DQoJCQkJCQkJCSAgZm9yIChJdGVyYXRvcjxQcm9wZXJ0eVNoZWV0UGFnZT4gaSA9IHByb3BlcnR5U2hlZXRQYWdlcy5pdGVyYXRvcigpOyBpLmhhc05leHQoKTsgKSB7DQoJCQkJCQkJCQkgIFByb3BlcnR5U2hlZXRQYWdlIHByb3BlcnR5U2hlZXRQYWdlID0gaS5uZXh0KCk7DQoJCQkJCQkJCQkgIGlmIChwcm9wZXJ0eVNoZWV0UGFnZS5nZXRDb250cm9sKCkuaXNEaXNwb3NlZCgpKSB7DQoJCQkJCQkJCQkJICBpLnJlbW92ZSgpOw0KCQkJCQkJCQkJICB9DQoJCQkJCQkJCQkgIGVsc2Ugew0KCQkJCQkJCQkJCSAgcHJvcGVydHlTaGVldFBhZ2UucmVmcmVzaCgpOw0KCQkJCQkJCQkJICB9DQoJCQkJCQkJCSAgfQ0KCQkJCQkJCSAgfQ0KCQkJCQkJICB9KTsNCgkJCQkgfQ0KCQkJIH0pOw0KDQoJCS8vIENyZWF0ZSB0aGUgZWRpdGluZyBkb21haW4gd2l0aCBhIHNwZWNpYWwgY29tbWFuZCBzdGFjay4NCgkJLy8NCgkJZWRpdGluZ0RvbWFpbiA9IG5ldyBBZGFwdGVyRmFjdG9yeUVkaXRpbmdEb21haW4oYWRhcHRlckZhY3RvcnksIGNvbW1hbmRTdGFjaywgbmV3IEhhc2hNYXA8UmVzb3VyY2UsIEJvb2xlYW4+KCkpOw0KCX0NCg0KCS8qKg0KCSAqIFRoaXMgaXMgaGVyZSBmb3IgdGhlIGxpc3RlbmVyIHRvIGJlIGFibGUgdG8gY2FsbCBpdC4NCgkgKiA8IS0tIGJlZ2luLXVzZXItZG9jIC0tPg0KCSAqIDwhLS0gZW5kLXVzZXItZG9jIC0tPg0KCSAqIEBnZW5lcmF0ZWQNCgkgKi8NCgkJCUBPdmVycmlkZQ0KCXByb3RlY3RlZCB2b2lkIGZpcmVQcm9wZXJ0eUNoYW5nZShpbnQgYWN0aW9uKSB7DQoJCXN1cGVyLmZpcmVQcm9wZXJ0eUNoYW5nZShhY3Rpb24pOw0KCX0NCg0KCS8qKg0KCSAqIFRoaXMgc2V0cyB0aGUgc2VsZWN0aW9uIGludG8gd2hpY2hldmVyIHZpZXdlciBpcyBhY3RpdmUuDQoJICogPCEtLSBiZWdpbi11c2VyLWRvYyAtLT4NCgkgKiA8IS0tIGVuZC11c2VyLWRvYyAtLT4NCgkgKiBAZ2VuZXJhdGVkDQoJICovDQoJcHVibGljIHZvaWQgc2V0U2VsZWN0aW9uVG9WaWV3ZXIoQ29sbGVjdGlvbjw/PiBjb2xsZWN0aW9uKSB7DQoJCWZpbmFsIENvbGxlY3Rpb248Pz4gdGhlU2VsZWN0aW9uID0gY29sbGVjdGlvbjsNCgkJLy8gTWFrZSBzdXJlIGl0J3Mgb2theS4NCgkJLy8NCgkJaWYgKHRoZVNlbGVjdGlvbiAhPSBudWxsICYmICF0aGVTZWxlY3Rpb24uaXNFbXB0eSgpKSB7DQoJCQlSdW5uYWJsZSBydW5uYWJsZSA9DQoJCQkJbmV3IFJ1bm5hYmxlKCkgew0KCQkJCQlwdWJsaWMgdm9pZCBydW4oKSB7DQoJCQkJCQkvLyBUcnkgdG8gc2VsZWN0IHRoZSBpdGVtcyBpbiB0aGUgY3VycmVudCBjb250ZW50IHZpZXdlciBvZiB0aGUgZWRpdG9yLg0KCQkJCQkJLy8NCgkJCQkJCWlmIChjdXJyZW50Vmlld2VyICE9IG51bGwpIHsNCgkJCQkJCQljdXJyZW50Vmlld2VyLnNldFNlbGVjdGlvbihuZXcgU3RydWN0dXJlZFNlbGVjdGlvbih0aGVTZWxlY3Rpb24udG9BcnJheSgpKSwgdHJ1ZSk7DQoJCQkJCQl9DQoJCQkJCX0NCgkJCQl9Ow0KCQkJZ2V0U2l0ZSgpLmdldFNoZWxsKCkuZ2V0RGlzcGxheSgpLmFzeW5jRXhlYyhydW5uYWJsZSk7DQoJCX0NCgl9DQoNCgkvKioNCgkgKiBUaGlzIHJldHVybnMgdGhlIGVkaXRpbmcgZG9tYWluIGFzIHJlcXVpcmVkIGJ5IHRoZSB7QGxpbmsgSUVkaXRpbmdEb21haW5Qcm92aWRlcn0gaW50ZXJmYWNlLg0KCSAqIFRoaXMgaXMgaW1wb3J0YW50IGZvciBpbXBsZW1lbnRpbmcgdGhlIHN0YXRpYyBtZXRob2RzIG9mIHtAbGluayBBZGFwdGVyRmFjdG9yeUVkaXRpbmdEb21haW59DQoJICogYW5kIGZvciBzdXBwb3J0aW5nIHtAbGluayBvcmcuZWNsaXBzZS5lbWYuZWRpdC51aS5hY3Rpb24uQ29tbWFuZEFjdGlvbn0uDQoJICogPCEtLSBiZWdpbi11c2VyLWRvYyAtLT4NCgkgKiA8IS0tIGVuZC11c2VyLWRvYyAtLT4NCgkgKiBAZ2VuZXJhdGVkDQoJICovDQoJcHVibGljIEVkaXRpbmdEb21haW4gZ2V0RWRpdGluZ0RvbWFpbigpIHsNCgkJcmV0dXJuIGVkaXRpbmdEb21haW47DQoJfQ0KDQoJLyoqDQoJICogPCEtLSBiZWdpbi11c2VyLWRvYyAtLT4NCgkgKiA8IS0tIGVuZC11c2VyLWRvYyAtLT4NCgkgKiBAZ2VuZXJhdGVkDQoJICovDQoJcHVibGljIGNsYXNzIFJldmVyc2VBZGFwdGVyRmFjdG9yeUNvbnRlbnRQcm92aWRlciBleHRlbmRzIEFkYXB0ZXJGYWN0b3J5Q29udGVudFByb3ZpZGVyIHsNCgkJLyoqDQoJCSAqIDwhLS0gYmVnaW4tdXNlci1kb2MgLS0+DQoJCSAqIDwhLS0gZW5kLXVzZXItZG9jIC0tPg0KCQkgKiBAZ2VuZXJhdGVkDQoJCSAqLw0KCQlwdWJsaWMgUmV2ZXJzZUFkYXB0ZXJGYWN0b3J5Q29udGVudFByb3ZpZGVyKEFkYXB0ZXJGYWN0b3J5IGFkYXB0ZXJGYWN0b3J5KSB7DQoJCQlzdXBlcihhZGFwdGVyRmFjdG9yeSk7DQoJCX0NCg0KCQkvKioNCgkJICogPCEtLSBiZWdpbi11c2VyLWRvYyAtLT4NCgkJICogPCEtLSBlbmQtdXNlci1kb2MgLS0+DQoJCSAqIEBnZW5lcmF0ZWQNCgkJICovDQoJCUBPdmVycmlkZQ0KCQlwdWJsaWMgT2JqZWN0IFtdIGdldEVsZW1lbnRzKE9iamVjdCBvYmplY3QpIHsNCgkJCU9iamVjdCBwYXJlbnQgPSBzdXBlci5nZXRQYXJlbnQob2JqZWN0KTsNCgkJCXJldHVybiAocGFyZW50ID09IG51bGwgPyBDb2xsZWN0aW9ucy5FTVBUWV9TRVQgOiBDb2xsZWN0aW9ucy5zaW5nbGV0b24ocGFyZW50KSkudG9BcnJheSgpOw0KCQl9DQoNCgkJLyoqDQoJCSAqIDwhLS0gYmVnaW4tdXNlci1kb2MgLS0+DQoJCSAqIDwhLS0gZW5kLXVzZXItZG9jIC0tPg0KCQkgKiBAZ2VuZXJhdGVkDQoJCSAqLw0KCQlAT3ZlcnJpZGUNCgkJcHVibGljIE9iamVjdCBbXSBnZXRDaGlsZHJlbihPYmplY3Qgb2JqZWN0KSB7DQoJCQlPYmplY3QgcGFyZW50ID0gc3VwZXIuZ2V0UGFyZW50KG9iamVjdCk7DQoJCQlyZXR1cm4gKHBhcmVudCA9PSBudWxsID8gQ29sbGVjdGlvbnMuRU1QVFlfU0VUIDogQ29sbGVjdGlvbnMuc2luZ2xldG9uKHBhcmVudCkpLnRvQXJyYXkoKTsNCgkJfQ0KDQoJCS8qKg0KCQkgKiA8IS0tIGJlZ2luLXVzZXItZG9jIC0tPg0KCQkgKiA8IS0tIGVuZC11c2VyLWRvYyAtLT4NCgkJICogQGdlbmVyYXRlZA0KCQkgKi8NCgkJQE92ZXJyaWRlDQoJCXB1YmxpYyBib29sZWFuIGhhc0NoaWxkcmVuKE9iamVjdCBvYmplY3QpIHsNCgkJCU9iamVjdCBwYXJlbnQgPSBzdXBlci5nZXRQYXJlbnQob2JqZWN0KTsNCgkJCXJldHVybiBwYXJlbnQgIT0gbnVsbDsNCgkJfQ0KDQoJCS8qKg0KCQkgKiA8IS0tIGJlZ2luLXVzZXItZG9jIC0tPg0KCQkgKiA8IS0tIGVuZC11c2VyLWRvYyAtLT4NCgkJICogQGdlbmVyYXRlZA0KCQkgKi8NCgkJQE92ZXJyaWRlDQoJCXB1YmxpYyBPYmplY3QgZ2V0UGFyZW50KE9iamVjdCBvYmplY3QpIHsNCgkJCXJldHVybiBudWxsOw0KCQl9DQoJfQ0KDQoJLyoqDQoJICogPCEtLSBiZWdpbi11c2VyLWRvYyAtLT4NCgkgKiA8IS0tIGVuZC11c2VyLWRvYyAtLT4NCgkgKiBAZ2VuZXJhdGVkDQoJICovDQoJcHVibGljIHZvaWQgc2V0Q3VycmVudFZpZXdlclBhbmUoVmlld2VyUGFuZSB2aWV3ZXJQYW5lKSB7DQoJCWlmIChjdXJyZW50Vmlld2VyUGFuZSAhPSB2aWV3ZXJQYW5lKSB7DQoJCQlpZiAoY3VycmVudFZpZXdlclBhbmUgIT0gbnVsbCkgew0KCQkJCWN1cnJlbnRWaWV3ZXJQYW5lLnNob3dGb2N1cyhmYWxzZSk7DQoJCQl9DQoJCQljdXJyZW50Vmlld2VyUGFuZSA9IHZpZXdlclBhbmU7DQoJCX0NCgkJc2V0Q3VycmVudFZpZXdlcihjdXJyZW50Vmlld2VyUGFuZS5nZXRWaWV3ZXIoKSk7DQoJfQ0KDQoJLyoqDQoJICogVGhpcyBtYWtlcyBzdXJlIHRoYXQgb25lIGNvbnRlbnQgdmlld2VyLCBlaXRoZXIgZm9yIHRoZSBjdXJyZW50IHBhZ2Ugb3IgdGhlIG91dGxpbmUgdmlldywgaWYgaXQgaGFzIGZvY3VzLA0KCSAqIGlzIHRoZSBjdXJyZW50IG9uZS4NCgkgKiA8IS0tIGJlZ2luLXVzZXItZG9jIC0tPg0KCSAqIDwhLS0gZW5kLXVzZXItZG9jIC0tPg0KCSAqIEBnZW5lcmF0ZWQNCgkgKi8NCglwdWJsaWMgdm9pZCBzZXRDdXJyZW50Vmlld2VyKFZpZXdlciB2aWV3ZXIpIHsNCgkJLy8gSWYgaXQgaXMgY2hhbmdpbmcuLi4NCgkJLy8NCgkJaWYgKGN1cnJlbnRWaWV3ZXIgIT0gdmlld2VyKSB7DQoJCQlpZiAoc2VsZWN0aW9uQ2hhbmdlZExpc3RlbmVyID09IG51bGwpIHsNCgkJCQkvLyBDcmVhdGUgdGhlIGxpc3RlbmVyIG9uIGRlbWFuZC4NCgkJCQkvLw0KCQkJCXNlbGVjdGlvbkNoYW5nZWRMaXN0ZW5lciA9DQoJCQkJCW5ldyBJU2VsZWN0aW9uQ2hhbmdlZExpc3RlbmVyKCkgew0KCQkJCQkJLy8gVGhpcyBqdXN0IG5vdGlmaWVzIHRob3NlIHRoaW5ncyB0aGF0IGFyZSBhZmZlY3RlZCBieSB0aGUgc2VjdGlvbi4NCgkJCQkJCS8vDQoJCQkJCQlwdWJsaWMgdm9pZCBzZWxlY3Rpb25DaGFuZ2VkKFNlbGVjdGlvbkNoYW5nZWRFdmVudCBzZWxlY3Rpb25DaGFuZ2VkRXZlbnQpIHsNCgkJCQkJCQlzZXRTZWxlY3Rpb24oc2VsZWN0aW9uQ2hhbmdlZEV2ZW50LmdldFNlbGVjdGlvbigpKTsNCgkJCQkJCX0NCgkJCQkJfTsNCgkJCX0NCg0KCQkJLy8gU3RvcCBsaXN0ZW5pbmcgdG8gdGhlIG9sZCBvbmUuDQoJCQkvLw0KCQkJaWYgKGN1cnJlbnRWaWV3ZXIgIT0gbnVsbCkgew0KCQkJCWN1cnJlbnRWaWV3ZXIucmVtb3ZlU2VsZWN0aW9uQ2hhbmdlZExpc3RlbmVyKHNlbGVjdGlvbkNoYW5nZWRMaXN0ZW5lcik7DQoJCQl9DQoNCgkJCS8vIFN0YXJ0IGxpc3RlbmluZyB0byB0aGUgbmV3IG9uZS4NCgkJCS8vDQoJCQlpZiAodmlld2VyICE9IG51bGwpIHsNCgkJCQl2aWV3ZXIuYWRkU2VsZWN0aW9uQ2hhbmdlZExpc3RlbmVyKHNlbGVjdGlvbkNoYW5nZWRMaXN0ZW5lcik7DQoJCQl9DQoNCgkJCS8vIFJlbWVtYmVyIGl0Lg0KCQkJLy8NCgkJCWN1cnJlbnRWaWV3ZXIgPSB2aWV3ZXI7DQoNCgkJCS8vIFNldCB0aGUgZWRpdG9ycyBzZWxlY3Rpb24gYmFzZWQgb24gdGhlIGN1cnJlbnQgdmlld2VyJ3Mgc2VsZWN0aW9uLg0KCQkJLy8NCgkJCXNldFNlbGVjdGlvbihjdXJyZW50Vmlld2VyID09IG51bGwgPyBTdHJ1Y3R1cmVkU2VsZWN0aW9uLkVNUFRZIDogY3VycmVudFZpZXdlci5nZXRTZWxlY3Rpb24oKSk7DQoJCX0NCgl9DQoNCgkvKioNCgkgKiBUaGlzIHJldHVybnMgdGhlIHZpZXdlciBhcyByZXF1aXJlZCBieSB0aGUge0BsaW5rIElWaWV3ZXJQcm92aWRlcn0gaW50ZXJmYWNlLg0KCSAqIDwhLS0gYmVnaW4tdXNlci1kb2MgLS0+DQoJICogPCEtLSBlbmQtdXNlci1kb2MgLS0+DQoJICogQGdlbmVyYXRlZA0KCSAqLw0KCXB1YmxpYyBWaWV3ZXIgZ2V0Vmlld2VyKCkgew0KCQlyZXR1cm4gY3VycmVudFZpZXdlcjsNCgl9DQoNCgkvKioNCgkgKiBUaGlzIGNyZWF0ZXMgYSBjb250ZXh0IG1lbnUgZm9yIHRoZSB2aWV3ZXIgYW5kIGFkZHMgYSBsaXN0ZW5lciBhcyB3ZWxsIHJlZ2lzdGVyaW5nIHRoZSBtZW51IGZvciBleHRlbnNpb24uDQoJICogPCEtLSBiZWdpbi11c2VyLWRvYyAtLT4NCgkgKiA8IS0tIGVuZC11c2VyLWRvYyAtLT4NCgkgKiBAZ2VuZXJhdGVkDQoJICovDQoJcHJvdGVjdGVkIHZvaWQgY3JlYXRlQ29udGV4dE1lbnVGb3IoU3RydWN0dXJlZFZpZXdlciB2aWV3ZXIpIHsNCgkJTWVudU1hbmFnZXIgY29udGV4dE1lbnUgPSBuZXcgTWVudU1hbmFnZXIoIiNQb3BVcCIpOw0KCQljb250ZXh0TWVudS5hZGQobmV3IFNlcGFyYXRvcigiYWRkaXRpb25zIikpOw0KCQljb250ZXh0TWVudS5zZXRSZW1vdmVBbGxXaGVuU2hvd24odHJ1ZSk7DQoJCWNvbnRleHRNZW51LmFkZE1lbnVMaXN0ZW5lcih0aGlzKTsNCgkJTWVudSBtZW51PSBjb250ZXh0TWVudS5jcmVhdGVDb250ZXh0TWVudSh2aWV3ZXIuZ2V0Q29udHJvbCgpKTsNCgkJdmlld2VyLmdldENvbnRyb2woKS5zZXRNZW51KG1lbnUpOw0KCQlnZXRTaXRlKCkucmVnaXN0ZXJDb250ZXh0TWVudShjb250ZXh0TWVudSwgbmV3IFVud3JhcHBpbmdTZWxlY3Rpb25Qcm92aWRlcih2aWV3ZXIpKTsNCg0KCQlpbnQgZG5kT3BlcmF0aW9ucyA9IERORC5EUk9QX0NPUFkgfCBETkQuRFJPUF9NT1ZFIHwgRE5ELkRST1BfTElOSzsNCgkJVHJhbnNmZXJbXSB0cmFuc2ZlcnMgPSBuZXcgVHJhbnNmZXJbXSB7IExvY2FsVHJhbnNmZXIuZ2V0SW5zdGFuY2UoKSwgTG9jYWxTZWxlY3Rpb25UcmFuc2Zlci5nZXRUcmFuc2ZlcigpLCBGaWxlVHJhbnNmZXIuZ2V0SW5zdGFuY2UoKSB9Ow0KCQl2aWV3ZXIuYWRkRHJhZ1N1cHBvcnQoZG5kT3BlcmF0aW9ucywgdHJhbnNmZXJzLCBuZXcgVmlld2VyRHJhZ0FkYXB0ZXIodmlld2VyKSk7DQoJCXZpZXdlci5hZGREcm9wU3VwcG9ydChkbmRPcGVyYXRpb25zLCB0cmFuc2ZlcnMsIG5ldyBFZGl0aW5nRG9tYWluVmlld2VyRHJvcEFkYXB0ZXIoZWRpdGluZ0RvbWFpbiwgdmlld2VyKSk7DQoJfQ0KDQoJLyoqDQoJICogVGhpcyBpcyB0aGUgbWV0aG9kIGNhbGxlZCB0byBsb2FkIGEgcmVzb3VyY2UgaW50byB0aGUgZWRpdGluZyBkb21haW4ncyByZXNvdXJjZSBzZXQgYmFzZWQgb24gdGhlIGVkaXRvcidzIGlucHV0Lg0KCSAqIDwhLS0gYmVnaW4tdXNlci1kb2MgLS0+DQoJICogPCEtLSBlbmQtdXNlci1kb2MgLS0+DQoJICogQGdlbmVyYXRlZA0KCSAqLw0KCXB1YmxpYyB2b2lkIGNyZWF0ZU1vZGVsKCkgew0KCQlVUkkgcmVzb3VyY2VVUkkgPSBFZGl0VUlVdGlsLmdldFVSSShnZXRFZGl0b3JJbnB1dCgpKTsNCgkJRXhjZXB0aW9uIGV4Y2VwdGlvbiA9IG51bGw7DQoJCVJlc291cmNlIHJlc291cmNlID0gbnVsbDsNCgkJdHJ5IHsNCgkJCS8vIExvYWQgdGhlIHJlc291cmNlIHRocm91Z2ggdGhlIGVkaXRpbmcgZG9tYWluLg0KCQkJLy8NCgkJCXJlc291cmNlID0gZWRpdGluZ0RvbWFpbi5nZXRSZXNvdXJjZVNldCgpLmdldFJlc291cmNlKHJlc291cmNlVVJJLCB0cnVlKTsNCgkJfQ0KCQljYXRjaCAoRXhjZXB0aW9uIGUpIHsNCgkJCWV4Y2VwdGlvbiA9IGU7DQoJCQlyZXNvdXJjZSA9IGVkaXRpbmdEb21haW4uZ2V0UmVzb3VyY2VTZXQoKS5nZXRSZXNvdXJjZShyZXNvdXJjZVVSSSwgZmFsc2UpOw0KCQl9DQoNCgkJRGlhZ25vc3RpYyBkaWFnbm9zdGljID0gYW5hbHl6ZVJlc291cmNlUHJvYmxlbXMocmVzb3VyY2UsIGV4Y2VwdGlvbik7DQoJCWlmIChkaWFnbm9zdGljLmdldFNldmVyaXR5KCkgIT0gRGlhZ25vc3RpYy5PSykgew0KCQkJcmVzb3VyY2VUb0RpYWdub3N0aWNNYXAucHV0KHJlc291cmNlLCAgYW5hbHl6ZVJlc291cmNlUHJvYmxlbXMocmVzb3VyY2UsIGV4Y2VwdGlvbikpOw0KCQl9DQoJCWVkaXRpbmdEb21haW4uZ2V0UmVzb3VyY2VTZXQoKS5lQWRhcHRlcnMoKS5hZGQocHJvYmxlbUluZGljYXRpb25BZGFwdGVyKTsNCgl9DQoNCgkvKioNCgkgKiBSZXR1cm5zIGEgZGlhZ25vc3RpYyBkZXNjcmliaW5nIHRoZSBlcnJvcnMgYW5kIHdhcm5pbmdzIGxpc3RlZCBpbiB0aGUgcmVzb3VyY2UNCgkgKiBhbmQgdGhlIHNwZWNpZmllZCBleGNlcHRpb24gKGlmIGFueSkuDQoJICogPCEtLSBiZWdpbi11c2VyLWRvYyAtLT4NCgkgKiA8IS0tIGVuZC11c2VyLWRvYyAtLT4NCgkgKiBAZ2VuZXJhdGVkDQoJICovDQoJcHVibGljIERpYWdub3N0aWMgYW5hbHl6ZVJlc291cmNlUHJvYmxlbXMoUmVzb3VyY2UgcmVzb3VyY2UsIEV4Y2VwdGlvbiBleGNlcHRpb24pIHsNCgkJaWYgKCFyZXNvdXJjZS5nZXRFcnJvcnMoKS5pc0VtcHR5KCkgfHwgIXJlc291cmNlLmdldFdhcm5pbmdzKCkuaXNFbXB0eSgpKSB7DQoJCQlCYXNpY0RpYWdub3N0aWMgYmFzaWNEaWFnbm9zdGljID0NCgkJCQluZXcgQmFzaWNEaWFnbm9zdGljDQoJCQkJCShEaWFnbm9zdGljLkVSUk9SLA0KCQkJCQkgIm9yZy5lY2xpcHNlLm9wZW5jZXJ0LnNhbS5hcmcuZWRpdG9yIiwNCgkJCQkJIDAsDQoJCQkJCSBnZXRTdHJpbmcoIl9VSV9DcmVhdGVNb2RlbEVycm9yX21lc3NhZ2UiLCByZXNvdXJjZS5nZXRVUkkoKSksDQoJCQkJCSBuZXcgT2JqZWN0IFtdIHsgZXhjZXB0aW9uID09IG51bGwgPyAoT2JqZWN0KXJlc291cmNlIDogZXhjZXB0aW9uIH0pOw0KCQkJYmFzaWNEaWFnbm9zdGljLm1lcmdlKEVjb3JlVXRpbC5jb21wdXRlRGlhZ25vc3RpYyhyZXNvdXJjZSwgdHJ1ZSkpOw0KCQkJcmV0dXJuIGJhc2ljRGlhZ25vc3RpYzsNCgkJfQ0KCQllbHNlIGlmIChleGNlcHRpb24gIT0gbnVsbCkgew0KCQkJcmV0dXJuDQoJCQkJbmV3IEJhc2ljRGlhZ25vc3RpYw0KCQkJCQkoRGlhZ25vc3RpYy5FUlJPUiwNCgkJCQkJICJvcmcuZWNsaXBzZS5vcGVuY2VydC5zYW0uYXJnLmVkaXRvciIsDQoJCQkJCSAwLA0KCQkJCQkgZ2V0U3RyaW5nKCJfVUlfQ3JlYXRlTW9kZWxFcnJvcl9tZXNzYWdlIiwgcmVzb3VyY2UuZ2V0VVJJKCkpLA0KCQkJCQkgbmV3IE9iamVjdFtdIHsgZXhjZXB0aW9uIH0pOw0KCQl9DQoJCWVsc2Ugew0KCQkJcmV0dXJuIERpYWdub3N0aWMuT0tfSU5TVEFOQ0U7DQoJCX0NCgl9DQoNCgkvKioNCgkgKiBUaGlzIGlzIHRoZSBtZXRob2QgdXNlZCBieSB0aGUgZnJhbWV3b3JrIHRvIGluc3RhbGwgeW91ciBvd24gY29udHJvbHMuDQoJICogPCEtLSBiZWdpbi11c2VyLWRvYyAtLT4NCgkgKiA8IS0tIGVuZC11c2VyLWRvYyAtLT4NCgkgKiBAZ2VuZXJhdGVkDQoJICovDQoJQE92ZXJyaWRlDQoJcHVibGljIHZvaWQgY3JlYXRlUGFnZXMoKSB7DQoJCS8vIENyZWF0ZXMgdGhlIG1vZGVsIGZyb20gdGhlIGVkaXRvciBpbnB1dA0KCQkvLw0KCQljcmVhdGVNb2RlbCgpOw0KDQoJCS8vIE9ubHkgY3JlYXRlcyB0aGUgb3RoZXIgcGFnZXMgaWYgdGhlcmUgaXMgc29tZXRoaW5nIHRoYXQgY2FuIGJlIGVkaXRlZA0KCQkvLw0KCQlpZiAoIWdldEVkaXRpbmdEb21haW4oKS5nZXRSZXNvdXJjZVNldCgpLmdldFJlc291cmNlcygpLmlzRW1wdHkoKSkgew0KCQkJLy8gQ3JlYXRlIGEgcGFnZSBmb3IgdGhlIHNlbGVjdGlvbiB0cmVlIHZpZXcuDQoJCQkvLw0KCQkJew0KCQkJCVZpZXdlclBhbmUgdmlld2VyUGFuZSA9DQoJCQkJCW5ldyBWaWV3ZXJQYW5lKGdldFNpdGUoKS5nZXRQYWdlKCksIEFyZ0VkaXRvci50aGlzKSB7DQoJCQkJCQlAT3ZlcnJpZGUNCgkJCQkJCXB1YmxpYyBWaWV3ZXIgY3JlYXRlVmlld2VyKENvbXBvc2l0ZSBjb21wb3NpdGUpIHsNCgkJCQkJCQlUcmVlIHRyZWUgPSBuZXcgVHJlZShjb21wb3NpdGUsIFNXVC5NVUxUSSk7DQoJCQkJCQkJVHJlZVZpZXdlciBuZXdUcmVlVmlld2VyID0gbmV3IFRyZWVWaWV3ZXIodHJlZSk7DQoJCQkJCQkJcmV0dXJuIG5ld1RyZWVWaWV3ZXI7DQoJCQkJCQl9DQoJCQkJCQlAT3ZlcnJpZGUNCgkJCQkJCXB1YmxpYyB2b2lkIHJlcXVlc3RBY3RpdmF0aW9uKCkgew0KCQkJCQkJCXN1cGVyLnJlcXVlc3RBY3RpdmF0aW9uKCk7DQoJCQkJCQkJc2V0Q3VycmVudFZpZXdlclBhbmUodGhpcyk7DQoJCQkJCQl9DQoJCQkJCX07DQoJCQkJdmlld2VyUGFuZS5jcmVhdGVDb250cm9sKGdldENvbnRhaW5lcigpKTsNCg0KCQkJCXNlbGVjdGlvblZpZXdlciA9IChUcmVlVmlld2VyKXZpZXdlclBhbmUuZ2V0Vmlld2VyKCk7DQoJCQkJc2VsZWN0aW9uVmlld2VyLnNldENvbnRlbnRQcm92aWRlcihuZXcgQWRhcHRlckZhY3RvcnlDb250ZW50UHJvdmlkZXIoYWRhcHRlckZhY3RvcnkpKTsNCg0KCQkJCXNlbGVjdGlvblZpZXdlci5zZXRMYWJlbFByb3ZpZGVyKG5ldyBBZGFwdGVyRmFjdG9yeUxhYmVsUHJvdmlkZXIoYWRhcHRlckZhY3RvcnkpKTsNCgkJCQlzZWxlY3Rpb25WaWV3ZXIuc2V0SW5wdXQoZWRpdGluZ0RvbWFpbi5nZXRSZXNvdXJjZVNldCgpLmdldFJlc291cmNlcygpLmdldCgwKSk7DQoJCQkJc2VsZWN0aW9uVmlld2VyLnNldFNlbGVjdGlvbihuZXcgU3RydWN0dXJlZFNlbGVjdGlvbihlZGl0aW5nRG9tYWluLmdldFJlc291cmNlU2V0KCkuZ2V0UmVzb3VyY2VzKCkuZ2V0KDApKSwgdHJ1ZSk7DQoJCQkJdmlld2VyUGFuZS5zZXRUaXRsZShlZGl0aW5nRG9tYWluLmdldFJlc291cmNlU2V0KCkpOw0KDQoJCQkJbmV3IEFkYXB0ZXJGYWN0b3J5VHJlZUVkaXRvcihzZWxlY3Rpb25WaWV3ZXIuZ2V0VHJlZSgpLCBhZGFwdGVyRmFjdG9yeSk7DQoNCgkJCQljcmVhdGVDb250ZXh0TWVudUZvcihzZWxlY3Rpb25WaWV3ZXIpOw0KCQkJCWludCBwYWdlSW5kZXggPSBhZGRQYWdlKHZpZXdlclBhbmUuZ2V0Q29udHJvbCgpKTsNCgkJCQlzZXRQYWdlVGV4dChwYWdlSW5kZXgsIGdldFN0cmluZygiX1VJX1NlbGVjdGlvblBhZ2VfbGFiZWwiKSk7DQoJCQl9DQoNCgkJCS8vIENyZWF0ZSBhIHBhZ2UgZm9yIHRoZSBwYXJlbnQgdHJlZSB2aWV3Lg0KCQkJLy8NCgkJCXsNCgkJCQlWaWV3ZXJQYW5lIHZpZXdlclBhbmUgPQ0KCQkJCQluZXcgVmlld2VyUGFuZShnZXRTaXRlKCkuZ2V0UGFnZSgpLCBBcmdFZGl0b3IudGhpcykgew0KCQkJCQkJQE92ZXJyaWRlDQoJCQkJCQlwdWJsaWMgVmlld2VyIGNyZWF0ZVZpZXdlcihDb21wb3NpdGUgY29tcG9zaXRlKSB7DQoJCQkJCQkJVHJlZSB0cmVlID0gbmV3IFRyZWUoY29tcG9zaXRlLCBTV1QuTVVMVEkpOw0KCQkJCQkJCVRyZWVWaWV3ZXIgbmV3VHJlZVZpZXdlciA9IG5ldyBUcmVlVmlld2VyKHRyZWUpOw0KCQkJCQkJCXJldHVybiBuZXdUcmVlVmlld2VyOw0KCQkJCQkJfQ0KCQkJCQkJQE92ZXJyaWRlDQoJCQkJCQlwdWJsaWMgdm9pZCByZXF1ZXN0QWN0aXZhdGlvbigpIHsNCgkJCQkJCQlzdXBlci5yZXF1ZXN0QWN0aXZhdGlvbigpOw0KCQkJCQkJCXNldEN1cnJlbnRWaWV3ZXJQYW5lKHRoaXMpOw0KCQkJCQkJfQ0KCQkJCQl9Ow0KCQkJCXZpZXdlclBhbmUuY3JlYXRlQ29udHJvbChnZXRDb250YWluZXIoKSk7DQoNCgkJCQlwYXJlbnRWaWV3ZXIgPSAoVHJlZVZpZXdlcil2aWV3ZXJQYW5lLmdldFZpZXdlcigpOw0KCQkJCXBhcmVudFZpZXdlci5zZXRBdXRvRXhwYW5kTGV2ZWwoMzApOw0KCQkJCXBhcmVudFZpZXdlci5zZXRDb250ZW50UHJvdmlkZXIobmV3IFJldmVyc2VBZGFwdGVyRmFjdG9yeUNvbnRlbnRQcm92aWRlcihhZGFwdGVyRmFjdG9yeSkpOw0KCQkJCXBhcmVudFZpZXdlci5zZXRMYWJlbFByb3ZpZGVyKG5ldyBBZGFwdGVyRmFjdG9yeUxhYmVsUHJvdmlkZXIoYWRhcHRlckZhY3RvcnkpKTsNCg0KCQkJCWNyZWF0ZUNvbnRleHRNZW51Rm9yKHBhcmVudFZpZXdlcik7DQoJCQkJaW50IHBhZ2VJbmRleCA9IGFkZFBhZ2Uodmlld2VyUGFuZS5nZXRDb250cm9sKCkpOw0KCQkJCXNldFBhZ2VUZXh0KHBhZ2VJbmRleCwgZ2V0U3RyaW5nKCJfVUlfUGFyZW50UGFnZV9sYWJlbCIpKTsNCgkJCX0NCg0KCQkJLy8gVGhpcyBpcyB0aGUgcGFnZSBmb3IgdGhlIGxpc3Qgdmlld2VyDQoJCQkvLw0KCQkJew0KCQkJCVZpZXdlclBhbmUgdmlld2VyUGFuZSA9DQoJCQkJCW5ldyBWaWV3ZXJQYW5lKGdldFNpdGUoKS5nZXRQYWdlKCksIEFyZ0VkaXRvci50aGlzKSB7DQoJCQkJCQlAT3ZlcnJpZGUNCgkJCQkJCXB1YmxpYyBWaWV3ZXIgY3JlYXRlVmlld2VyKENvbXBvc2l0ZSBjb21wb3NpdGUpIHsNCgkJCQkJCQlyZXR1cm4gbmV3IExpc3RWaWV3ZXIoY29tcG9zaXRlKTsNCgkJCQkJCX0NCgkJCQkJCUBPdmVycmlkZQ0KCQkJCQkJcHVibGljIHZvaWQgcmVxdWVzdEFjdGl2YXRpb24oKSB7DQoJCQkJCQkJc3VwZXIucmVxdWVzdEFjdGl2YXRpb24oKTsNCgkJCQkJCQlzZXRDdXJyZW50Vmlld2VyUGFuZSh0aGlzKTsNCgkJCQkJCX0NCgkJCQkJfTsNCgkJCQl2aWV3ZXJQYW5lLmNyZWF0ZUNvbnRyb2woZ2V0Q29udGFpbmVyKCkpOw0KCQkJCWxpc3RWaWV3ZXIgPSAoTGlzdFZpZXdlcil2aWV3ZXJQYW5lLmdldFZpZXdlcigpOw0KCQkJCWxpc3RWaWV3ZXIuc2V0Q29udGVudFByb3ZpZGVyKG5ldyBBZGFwdGVyRmFjdG9yeUNvbnRlbnRQcm92aWRlcihhZGFwdGVyRmFjdG9yeSkpOw0KCQkJCWxpc3RWaWV3ZXIuc2V0TGFiZWxQcm92aWRlcihuZXcgQWRhcHRlckZhY3RvcnlMYWJlbFByb3ZpZGVyKGFkYXB0ZXJGYWN0b3J5KSk7DQoNCgkJCQljcmVhdGVDb250ZXh0TWVudUZvcihsaXN0Vmlld2VyKTsNCgkJCQlpbnQgcGFnZUluZGV4ID0gYWRkUGFnZSh2aWV3ZXJQYW5lLmdldENvbnRyb2woKSk7DQoJCQkJc2V0UGFnZVRleHQocGFnZUluZGV4LCBnZXRTdHJpbmcoIl9VSV9MaXN0UGFnZV9sYWJlbCIpKTsNCgkJCX0NCg0KCQkJLy8gVGhpcyBpcyB0aGUgcGFnZSBmb3IgdGhlIHRyZWUgdmlld2VyDQoJCQkvLw0KCQkJew0KCQkJCVZpZXdlclBhbmUgdmlld2VyUGFuZSA9DQoJCQkJCW5ldyBWaWV3ZXJQYW5lKGdldFNpdGUoKS5nZXRQYWdlKCksIEFyZ0VkaXRvci50aGlzKSB7DQoJCQkJCQlAT3ZlcnJpZGUNCgkJCQkJCXB1YmxpYyBWaWV3ZXIgY3JlYXRlVmlld2VyKENvbXBvc2l0ZSBjb21wb3NpdGUpIHsNCgkJCQkJCQlyZXR1cm4gbmV3IFRyZWVWaWV3ZXIoY29tcG9zaXRlKTsNCgkJCQkJCX0NCgkJCQkJCUBPdmVycmlkZQ0KCQkJCQkJcHVibGljIHZvaWQgcmVxdWVzdEFjdGl2YXRpb24oKSB7DQoJCQkJCQkJc3VwZXIucmVxdWVzdEFjdGl2YXRpb24oKTsNCgkJCQkJCQlzZXRDdXJyZW50Vmlld2VyUGFuZSh0aGlzKTsNCgkJCQkJCX0NCgkJCQkJfTsNCgkJCQl2aWV3ZXJQYW5lLmNyZWF0ZUNvbnRyb2woZ2V0Q29udGFpbmVyKCkpOw0KCQkJCXRyZWVWaWV3ZXIgPSAoVHJlZVZpZXdlcil2aWV3ZXJQYW5lLmdldFZpZXdlcigpOw0KCQkJCXRyZWVWaWV3ZXIuc2V0Q29udGVudFByb3ZpZGVyKG5ldyBBZGFwdGVyRmFjdG9yeUNvbnRlbnRQcm92aWRlcihhZGFwdGVyRmFjdG9yeSkpOw0KCQkJCXRyZWVWaWV3ZXIuc2V0TGFiZWxQcm92aWRlcihuZXcgQWRhcHRlckZhY3RvcnlMYWJlbFByb3ZpZGVyKGFkYXB0ZXJGYWN0b3J5KSk7DQoNCgkJCQluZXcgQWRhcHRlckZhY3RvcnlUcmVlRWRpdG9yKHRyZWVWaWV3ZXIuZ2V0VHJlZSgpLCBhZGFwdGVyRmFjdG9yeSk7DQoNCgkJCQljcmVhdGVDb250ZXh0TWVudUZvcih0cmVlVmlld2VyKTsNCgkJCQlpbnQgcGFnZUluZGV4ID0gYWRkUGFnZSh2aWV3ZXJQYW5lLmdldENvbnRyb2woKSk7DQoJCQkJc2V0UGFnZVRleHQocGFnZUluZGV4LCBnZXRTdHJpbmcoIl9VSV9UcmVlUGFnZV9sYWJlbCIpKTsNCgkJCX0NCg0KCQkJLy8gVGhpcyBpcyB0aGUgcGFnZSBmb3IgdGhlIHRhYmxlIHZpZXdlci4NCgkJCS8vDQoJCQl7DQoJCQkJVmlld2VyUGFuZSB2aWV3ZXJQYW5lID0NCgkJCQkJbmV3IFZpZXdlclBhbmUoZ2V0U2l0ZSgpLmdldFBhZ2UoKSwgQXJnRWRpdG9yLnRoaXMpIHsNCgkJCQkJCUBPdmVycmlkZQ0KCQkJCQkJcHVibGljIFZpZXdlciBjcmVhdGVWaWV3ZXIoQ29tcG9zaXRlIGNvbXBvc2l0ZSkgew0KCQkJCQkJCXJldHVybiBuZXcgVGFibGVWaWV3ZXIoY29tcG9zaXRlKTsNCgkJCQkJCX0NCgkJCQkJCUBPdmVycmlkZQ0KCQkJCQkJcHVibGljIHZvaWQgcmVxdWVzdEFjdGl2YXRpb24oKSB7DQoJCQkJCQkJc3VwZXIucmVxdWVzdEFjdGl2YXRpb24oKTsNCgkJCQkJCQlzZXRDdXJyZW50Vmlld2VyUGFuZSh0aGlzKTsNCgkJCQkJCX0NCgkJCQkJfTsNCgkJCQl2aWV3ZXJQYW5lLmNyZWF0ZUNvbnRyb2woZ2V0Q29udGFpbmVyKCkpOw0KCQkJCXRhYmxlVmlld2VyID0gKFRhYmxlVmlld2VyKXZpZXdlclBhbmUuZ2V0Vmlld2VyKCk7DQoNCgkJCQlUYWJsZSB0YWJsZSA9IHRhYmxlVmlld2VyLmdldFRhYmxlKCk7DQoJCQkJVGFibGVMYXlvdXQgbGF5b3V0ID0gbmV3IFRhYmxlTGF5b3V0KCk7DQoJCQkJdGFibGUuc2V0TGF5b3V0KGxheW91dCk7DQoJCQkJdGFibGUuc2V0SGVhZGVyVmlzaWJsZSh0cnVlKTsNCgkJCQl0YWJsZS5zZXRMaW5lc1Zpc2libGUodHJ1ZSk7DQoNCgkJCQlUYWJsZUNvbHVtbiBvYmplY3RDb2x1bW4gPSBuZXcgVGFibGVDb2x1bW4odGFibGUsIFNXVC5OT05FKTsNCgkJCQlsYXlvdXQuYWRkQ29sdW1uRGF0YShuZXcgQ29sdW1uV2VpZ2h0RGF0YSgzLCAxMDAsIHRydWUpKTsNCgkJCQlvYmplY3RDb2x1bW4uc2V0VGV4dChnZXRTdHJpbmcoIl9VSV9PYmplY3RDb2x1bW5fbGFiZWwiKSk7DQoJCQkJb2JqZWN0Q29sdW1uLnNldFJlc2l6YWJsZSh0cnVlKTsNCg0KCQkJCVRhYmxlQ29sdW1uIHNlbGZDb2x1bW4gPSBuZXcgVGFibGVDb2x1bW4odGFibGUsIFNXVC5OT05FKTsNCgkJCQlsYXlvdXQuYWRkQ29sdW1uRGF0YShuZXcgQ29sdW1uV2VpZ2h0RGF0YSgyLCAxMDAsIHRydWUpKTsNCgkJCQlzZWxmQ29sdW1uLnNldFRleHQoZ2V0U3RyaW5nKCJfVUlfU2VsZkNvbHVtbl9sYWJlbCIpKTsNCgkJCQlzZWxmQ29sdW1uLnNldFJlc2l6YWJsZSh0cnVlKTsNCg0KCQkJCXRhYmxlVmlld2VyLnNldENvbHVtblByb3BlcnRpZXMobmV3IFN0cmluZyBbXSB7ImEiLCAiYiJ9KTsNCgkJCQl0YWJsZVZpZXdlci5zZXRDb250ZW50UHJvdmlkZXIobmV3IEFkYXB0ZXJGYWN0b3J5Q29udGVudFByb3ZpZGVyKGFkYXB0ZXJGYWN0b3J5KSk7DQoJCQkJdGFibGVWaWV3ZXIuc2V0TGFiZWxQcm92aWRlcihuZXcgQWRhcHRlckZhY3RvcnlMYWJlbFByb3ZpZGVyKGFkYXB0ZXJGYWN0b3J5KSk7DQoNCgkJCQljcmVhdGVDb250ZXh0TWVudUZvcih0YWJsZVZpZXdlcik7DQoJCQkJaW50IHBhZ2VJbmRleCA9IGFkZFBhZ2Uodmlld2VyUGFuZS5nZXRDb250cm9sKCkpOw0KCQkJCXNldFBhZ2VUZXh0KHBhZ2VJbmRleCwgZ2V0U3RyaW5nKCJfVUlfVGFibGVQYWdlX2xhYmVsIikpOw0KCQkJfQ0KDQoJCQkvLyBUaGlzIGlzIHRoZSBwYWdlIGZvciB0aGUgdGFibGUgdHJlZSB2aWV3ZXIuDQoJCQkvLyBDaGFuZ2VkIHRvIENoZWNrYm94IFRyZWUgYnkgSEVPDQoJCQl7DQoJCQkJVmlld2VyUGFuZSB2aWV3ZXJQYW5lID0NCgkJCQkJbmV3IFZpZXdlclBhbmUoZ2V0U2l0ZSgpLmdldFBhZ2UoKSwgQXJnRWRpdG9yLnRoaXMpIHsNCgkJCQkJCUBPdmVycmlkZQ0KCQkJCQkJcHVibGljIFZpZXdlciBjcmVhdGVWaWV3ZXIoQ29tcG9zaXRlIGNvbXBvc2l0ZSkgew0KCQkJCQkJCXJldHVybiBuZXcgQ2hlY2tib3hUcmVlVmlld2VyRXh0KGNvbXBvc2l0ZSk7DQoJCQkJCQl9DQoJCQkJCQlAT3ZlcnJpZGUNCgkJCQkJCXB1YmxpYyB2b2lkIHJlcXVlc3RBY3RpdmF0aW9uKCkgew0KCQkJCQkJCXN1cGVyLnJlcXVlc3RBY3RpdmF0aW9uKCk7DQoJCQkJCQkJc2V0Q3VycmVudFZpZXdlclBhbmUodGhpcyk7DQoJCQkJCQl9DQoJCQkJCX07DQoJCQkJdmlld2VyUGFuZS5jcmVhdGVDb250cm9sKGdldENvbnRhaW5lcigpKTsNCg0KCQkJCXRyZWVWaWV3ZXJXaXRoQ2hlY2sgPSAoQ2hlY2tib3hUcmVlVmlld2VyRXh0KXZpZXdlclBhbmUuZ2V0Vmlld2VyKCk7DQoNCgkJCQlUcmVlIHRyZWUgPSB0cmVlVmlld2VyV2l0aENoZWNrLmdldFRyZWUoKTsNCgkJCQl0cmVlLnNldExheW91dERhdGEobmV3IEZpbGxMYXlvdXQoKSk7DQoJCQkJdHJlZS5zZXRIZWFkZXJWaXNpYmxlKHRydWUpOw0KCQkJCXRyZWUuc2V0TGluZXNWaXNpYmxlKHRydWUpOw0KDQoJCQkJVHJlZUNvbHVtbiBvYmplY3RDb2x1bW4gPSBuZXcgVHJlZUNvbHVtbih0cmVlLCBTV1QuTk9ORSk7DQoJCQkJb2JqZWN0Q29sdW1uLnNldFRleHQoZ2V0U3RyaW5nKCJfVUlfT2JqZWN0Q29sdW1uX2xhYmVsIikpOw0KCQkJCW9iamVjdENvbHVtbi5zZXRSZXNpemFibGUodHJ1ZSk7DQoJCQkJb2JqZWN0Q29sdW1uLnNldFdpZHRoKDUwMCk7DQoNCi8vCQkJCVRyZWVDb2x1bW4gc2VsZkNvbHVtbiA9IG5ldyBUcmVlQ29sdW1uKHRyZWUsIFNXVC5OT05FKTsNCi8vCQkJCXNlbGZDb2x1bW4uc2V0VGV4dChnZXRTdHJpbmcoIl9VSV9TZWxmQ29sdW1uX2xhYmVsIikpOw0KLy8JCQkJc2VsZkNvbHVtbi5zZXRSZXNpemFibGUodHJ1ZSk7DQovLwkJCQlzZWxmQ29sdW1uLnNldFdpZHRoKDIwMCk7DQoNCgkJCQl0cmVlVmlld2VyV2l0aENoZWNrLnNldENvbHVtblByb3BlcnRpZXMobmV3IFN0cmluZyBbXSB7ImEiLCAiYiJ9KTsNCgkJCQl0cmVlVmlld2VyV2l0aENoZWNrLnNldENvbnRlbnRQcm92aWRlcihuZXcgQWRhcHRlckZhY3RvcnlDb250ZW50UHJvdmlkZXIoYWRhcHRlckZhY3RvcnkpKTsNCgkJCQl0cmVlVmlld2VyV2l0aENoZWNrLnNldExhYmVsUHJvdmlkZXIobmV3IEFkYXB0ZXJGYWN0b3J5TGFiZWxQcm92aWRlcihhZGFwdGVyRmFjdG9yeSkpOw0KCQkJCXRyZWVWaWV3ZXJXaXRoQ2hlY2suc2V0SW5wdXQoZWRpdGluZ0RvbWFpbi5nZXRSZXNvdXJjZVNldCgpLmdldFJlc291cmNlcygpLmdldCgwKSk7Ly9lZGl0aW5nRG9tYWluLmdldFJlc291cmNlU2V0KCkpOw0KCQkJCQ0KCQkJCWNyZWF0ZUNvbnRleHRNZW51Rm9yKHRyZWVWaWV3ZXJXaXRoQ2hlY2spOw0KCQkJCWludCBwYWdlSW5kZXggPSBhZGRQYWdlKHZpZXdlclBhbmUuZ2V0Q29udHJvbCgpKTsNCgkJCQlzZXRQYWdlVGV4dChwYWdlSW5kZXgsIGdldFN0cmluZygiX1VJX1RyZWVXaXRoQ2hlY2tQYWdlX2xhYmVsIikpOw0KLy8JCQkJc2V0UGFnZVRleHQocGFnZUluZGV4LCBnZXRTdHJpbmcoIl9VSV9UcmVlV2l0aENvbHVtbnNQYWdlX2xhYmVsIikpOw0KCQkJCQ0KCQkJCUlDaGVja1N0YXRlTGlzdGVuZXIgY2hlY2tTdGF0ZUxpc3RlbmVyID0gbmV3IElDaGVja1N0YXRlTGlzdGVuZXIoKXsNCgkJCQkJcHVibGljIHZvaWQgY2hlY2tTdGF0ZUNoYW5nZWQgKENoZWNrU3RhdGVDaGFuZ2VkRXZlbnQgZXZlbnQpew0KCQkJCQkJT2JqZWN0IGNoYW5nZWRFbGVtZW50ID0gZXZlbnQuZ2V0RWxlbWVudCgpOw0KCQkJCQkJYm9vbGVhbiBzdGF0dXMgPSB0cmVlVmlld2VyV2l0aENoZWNrLmdldENoZWNrZWQoY2hhbmdlZEVsZW1lbnQpOw0KCQkJCQkJYm9vbGVhbiBpc0V4cGFuZGVkID0gdHJlZVZpZXdlcldpdGhDaGVjay5nZXRFeHBhbmRlZFN0YXRlKGNoYW5nZWRFbGVtZW50KTsNCgkJCQkJCXRyZWVWaWV3ZXJXaXRoQ2hlY2suZXhwYW5kVG9MZXZlbChjaGFuZ2VkRWxlbWVudCwgQWJzdHJhY3RUcmVlVmlld2VyLkFMTF9MRVZFTFMpOw0KCQkJCQkJdHJlZVZpZXdlcldpdGhDaGVjay5zZXRTdWJ0cmVlQ2hlY2tlZChjaGFuZ2VkRWxlbWVudCwgc3RhdHVzKTsNCgkJCQkJCWlmICghaXNFeHBhbmRlZCl7DQoJCQkJCQkJdHJlZVZpZXdlcldpdGhDaGVjay5jb2xsYXBzZVRvTGV2ZWwoY2hhbmdlZEVsZW1lbnQsIEFic3RyYWN0VHJlZVZpZXdlci5BTExfTEVWRUxTKTsNCgkJCQkJCX0NCgkJCQkJCWlmIChzdGF0dXMpew0KCQkJCQkJCXRyZWVWaWV3ZXJXaXRoQ2hlY2suc2V0UGFyZW50c0NoZWNrZWQoY2hhbmdlZEVsZW1lbnQsdHJ1ZSk7DQoJCQkJCQl9DQovLwkJCQkJCWVsc2V7DQovLwkJCQkJCQlpZiAobW9kZWxWaWV3ZXIuYWxsQnJvdGhlcnNVbkNoZWNrZWQoY2hhbmdlZEVsZW1lbnQpKXsNCi8vCQkJCQkJCQltb2RlbFZpZXdlci5zZXRQYXJlbnRzQ2hlY2tlZChjaGFuZ2VkRWxlbWVudCxmYWxzZSk7DQovLwkJCQkJCQl9DQovLwkJCQkJCX0NCi8vCQkJCQkJcmVzdWx0cyA9IG1vZGVsVmlld2VyLmdldENoZWNrZWRFbGVtZW50cygpOw0KDQoJCQkJCX0NCgkJCQl9Ow0KCQkJCQ0KCQkJCXRyZWVWaWV3ZXJXaXRoQ2hlY2suYWRkQ2hlY2tTdGF0ZUxpc3RlbmVyKGNoZWNrU3RhdGVMaXN0ZW5lcik7DQoJCQkJdHJlZVZpZXdlcldpdGhDaGVjay5hZGREb3VibGVDbGlja0xpc3RlbmVyKG5ldyBPcGVuV2l6YXJkT25Eb3VibGVDbGljayhlZGl0aW5nRG9tYWluLCBhZGFwdGVyRmFjdG9yeSkpOw0KCQkJCS8vIEVuZCBvZjogQ2hhbmdlZCB0byBDaGVja2JveCBUcmVlIGJ5IEhFTw0KDQoJCQl9DQoNCgkJCWdldFNpdGUoKS5nZXRTaGVsbCgpLmdldERpc3BsYXkoKS5hc3luY0V4ZWMNCgkJCQkobmV3IFJ1bm5hYmxlKCkgew0KCQkJCQkgcHVibGljIHZvaWQgcnVuKCkgew0KCQkJCQkJIHNldEFjdGl2ZVBhZ2UoMCk7DQoJCQkJCSB9DQoJCQkJIH0pOw0KCQl9DQoNCgkJLy8gRW5zdXJlcyB0aGF0IHRoaXMgZWRpdG9yIHdpbGwgb25seSBkaXNwbGF5IHRoZSBwYWdlJ3MgdGFiDQoJCS8vIGFyZWEgaWYgdGhlcmUgYXJlIG1vcmUgdGhhbiBvbmUgcGFnZQ0KCQkvLw0KCQlnZXRDb250YWluZXIoKS5hZGRDb250cm9sTGlzdGVuZXINCgkJCShuZXcgQ29udHJvbEFkYXB0ZXIoKSB7DQoJCQkJYm9vbGVhbiBndWFyZCA9IGZhbHNlOw0KCQkJCUBPdmVycmlkZQ0KCQkJCXB1YmxpYyB2b2lkIGNvbnRyb2xSZXNpemVkKENvbnRyb2xFdmVudCBldmVudCkgew0KCQkJCQlpZiAoIWd1YXJkKSB7DQoJCQkJCQlndWFyZCA9IHRydWU7DQoJCQkJCQloaWRlVGFicygpOw0KCQkJCQkJZ3VhcmQgPSBmYWxzZTsNCgkJCQkJfQ0KCQkJCX0NCgkJCSB9KTsNCg0KCQlnZXRTaXRlKCkuZ2V0U2hlbGwoKS5nZXREaXNwbGF5KCkuYXN5bmNFeGVjDQoJCQkobmV3IFJ1bm5hYmxlKCkgew0KCQkJCSBwdWJsaWMgdm9pZCBydW4oKSB7DQoJCQkJCSB1cGRhdGVQcm9ibGVtSW5kaWNhdGlvbigpOw0KCQkJCSB9DQoJCQkgfSk7DQoJfQ0KCQ0KCS8qKg0KCSAqIEhFTw0KCSAqIEdldCBUcmVldmlld2VyIHdpdGggQ2hlY2tzDQoJICovDQoJcHVibGljIENoZWNrYm94VHJlZVZpZXdlckV4dCBnZXRUcmVlVmlld2VyV2l0aENoZWNrKCkgew0KCQlyZXR1cm4gdHJlZVZpZXdlcldpdGhDaGVjazsNCgl9DQoNCgkvKioNCgkgKiBIRU8NCgkgKiBTZXQgQWxsIENoZWNrcyBvZiBUcmVldmlld2VyDQoJICovDQoJcHVibGljIHZvaWQgc2V0VHJlZVZpZXdlcldpdGhDaGVjayhCb29sZWFuIHN0YXR1cykgew0KCQl0cmVlVmlld2VyV2l0aENoZWNrLmV4cGFuZEFsbCgpOw0KCQl0cmVlVmlld2VyV2l0aENoZWNrLnNldEFsbENoZWNrZWQoc3RhdHVzKTsNCgl9DQoNCgkvKioNCgkgKiBIRU8NCgkgKiBTZXQgQWN0aXZlIFBhZ2UgZXh0ZXJuYWxseQ0KCSAqLw0KCXB1YmxpYyB2b2lkIHNldEFjdGl2ZVBhZ2VQdWJsaWMoZmluYWwgaW50IHBhZ2VJbmRleCkgew0KCQlnZXRTaXRlKCkuZ2V0U2hlbGwoKS5nZXREaXNwbGF5KCkuYXN5bmNFeGVjDQoJCShuZXcgUnVubmFibGUoKSB7DQoJCQkgcHVibGljIHZvaWQgcnVuKCkgew0KCQkJCSBzZXRBY3RpdmVQYWdlKHBhZ2VJbmRleCk7DQoJCQkgfQ0KCQkgfSk7CQkNCgl9DQoJDQoNCgkvKioNCgkgKiBJZiB0aGVyZSBpcyBqdXN0IG9uZSBwYWdlIGluIHRoZSBtdWx0aS1wYWdlIGVkaXRvciBwYXJ0LA0KCSAqIHRoaXMgaGlkZXMgdGhlIHNpbmdsZSB0YWIgYXQgdGhlIGJvdHRvbS4NCgkgKiA8IS0tIGJlZ2luLXVzZXItZG9jIC0tPg0KCSAqIDwhLS0gZW5kLXVzZXItZG9jIC0tPg0KCSAqIEBnZW5lcmF0ZWQNCgkgKi8NCglwcm90ZWN0ZWQgdm9pZCBoaWRlVGFicygpIHsNCgkJaWYgKGdldFBhZ2VDb3VudCgpIDw9IDEpIHsNCgkJCXNldFBhZ2VUZXh0KDAsICIiKTsNCgkJCWlmIChnZXRDb250YWluZXIoKSBpbnN0YW5jZW9mIENUYWJGb2xkZXIpIHsNCgkJCQkoKENUYWJGb2xkZXIpZ2V0Q29udGFpbmVyKCkpLnNldFRhYkhlaWdodCgxKTsNCgkJCQlQb2ludCBwb2ludCA9IGdldENvbnRhaW5lcigpLmdldFNpemUoKTsNCgkJCQlnZXRDb250YWluZXIoKS5zZXRTaXplKHBvaW50LngsIHBvaW50LnkgKyA2KTsNCgkJCX0NCgkJfQ0KCX0NCg0KCS8qKg0KCSAqIElmIHRoZXJlIGlzIG1vcmUgdGhhbiBvbmUgcGFnZSBpbiB0aGUgbXVsdGktcGFnZSBlZGl0b3IgcGFydCwNCgkgKiB0aGlzIHNob3dzIHRoZSB0YWJzIGF0IHRoZSBib3R0b20uDQoJICogPCEtLSBiZWdpbi11c2VyLWRvYyAtLT4NCgkgKiA8IS0tIGVuZC11c2VyLWRvYyAtLT4NCgkgKiBAZ2VuZXJhdGVkDQoJICovDQoJcHJvdGVjdGVkIHZvaWQgc2hvd1RhYnMoKSB7DQoJCWlmIChnZXRQYWdlQ291bnQoKSA+IDEpIHsNCgkJCXNldFBhZ2VUZXh0KDAsIGdldFN0cmluZygiX1VJX1NlbGVjdGlvblBhZ2VfbGFiZWwiKSk7DQoJCQlpZiAoZ2V0Q29udGFpbmVyKCkgaW5zdGFuY2VvZiBDVGFiRm9sZGVyKSB7DQoJCQkJKChDVGFiRm9sZGVyKWdldENvbnRhaW5lcigpKS5zZXRUYWJIZWlnaHQoU1dULkRFRkFVTFQpOw0KCQkJCVBvaW50IHBvaW50ID0gZ2V0Q29udGFpbmVyKCkuZ2V0U2l6ZSgpOw0KCQkJCWdldENvbnRhaW5lcigpLnNldFNpemUocG9pbnQueCwgcG9pbnQueSAtIDYpOw0KCQkJfQ0KCQl9DQoJfQ0KDQoJLyoqDQoJICogVGhpcyBpcyB1c2VkIHRvIHRyYWNrIHRoZSBhY3RpdmUgdmlld2VyLg0KCSAqIDwhLS0gYmVnaW4tdXNlci1kb2MgLS0+DQoJICogPCEtLSBlbmQtdXNlci1kb2MgLS0+DQoJICogQGdlbmVyYXRlZA0KCSAqLw0KCUBPdmVycmlkZQ0KCXByb3RlY3RlZCB2b2lkIHBhZ2VDaGFuZ2UoaW50IHBhZ2VJbmRleCkgew0KCQlzdXBlci5wYWdlQ2hhbmdlKHBhZ2VJbmRleCk7DQoNCgkJaWYgKGNvbnRlbnRPdXRsaW5lUGFnZSAhPSBudWxsKSB7DQoJCQloYW5kbGVDb250ZW50T3V0bGluZVNlbGVjdGlvbihjb250ZW50T3V0bGluZVBhZ2UuZ2V0U2VsZWN0aW9uKCkpOw0KCQkJLy9CZWdpbiBBTEMNCgkJCS8vVG8gYXV0b3NlbGVjdCBieSBkZWZhdWx0IGFsbCB0aGUgbW9kZWwgY29udGVudHMgZm9yIHJldXNlLg0KCQkJaWYocGFnZUluZGV4PT01ICYmIGZpcnN0VGltZSl7DQoJCQkJDQoJCQkJaWYodHJlZVZpZXdlcldpdGhDaGVjay5nZXRUcmVlKCkuZ2V0VG9wSXRlbSgpIT1udWxsKXsNCgkJCQkJdHJlZVZpZXdlcldpdGhDaGVjay5leHBhbmRBbGwoKTsJCQkNCgkJCQkJDQoJCQkJCS8vdHJlZVZpZXdlcldpdGhDaGVjay5nZXRUcmVlKCkuZ2V0VG9wSXRlbSgpLnNldENoZWNrZWQodHJ1ZSk7DQoJCQkJCWNoZWNrSXRlbXModHJlZVZpZXdlcldpdGhDaGVjay5nZXRUcmVlKCkuZ2V0VG9wSXRlbSgpLHRydWUpOw0KCQkJCQkJCQkJCQ0KCQkJCQlmaXJzdFRpbWU9ZmFsc2U7DQoJCQkJfQ0KCQkJfQ0KCQl9DQoJfQ0KDQoJcHJpdmF0ZSAgdm9pZCBjaGVja0l0ZW1zKFRyZWVJdGVtIGl0ZW0sIGJvb2xlYW4gY2hlY2tlZCkgew0KICAgICAgICANCiAgICAgICAgaXRlbS5zZXRDaGVja2VkKGNoZWNrZWQpOw0KICAgICAgICBUcmVlSXRlbVtdIGl0ZW1zID0gaXRlbS5nZXRJdGVtcygpOw0KICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IGl0ZW1zLmxlbmd0aDsgaSsrKSB7DQogICAgICAgICAgICBjaGVja0l0ZW1zKGl0ZW1zW2ldLCBjaGVja2VkKTsNCiAgICAgICAgfQ0KICAgIH0NCg0KCS8vRW5kIEFMQw0KCQ0KCS8qKg0KCSAqIFRoaXMgaXMgaG93IHRoZSBmcmFtZXdvcmsgZGV0ZXJtaW5lcyB3aGljaCBpbnRlcmZhY2VzIHdlIGltcGxlbWVudC4NCgkgKiA8IS0tIGJlZ2luLXVzZXItZG9jIC0tPg0KCSAqIDwhLS0gZW5kLXVzZXItZG9jIC0tPg0KCSAqIEBnZW5lcmF0ZWQNCgkgKi8NCglAU3VwcHJlc3NXYXJuaW5ncygicmF3dHlwZXMiKQ0KCUBPdmVycmlkZQ0KCXB1YmxpYyBPYmplY3QgZ2V0QWRhcHRlcihDbGFzcyBrZXkpIHsNCgkJaWYgKGtleS5lcXVhbHMoSUNvbnRlbnRPdXRsaW5lUGFnZS5jbGFzcykpIHsNCgkJCXJldHVybiBzaG93T3V0bGluZVZpZXcoKSA/IGdldENvbnRlbnRPdXRsaW5lUGFnZSgpIDogbnVsbDsNCgkJfQ0KCQllbHNlIGlmIChrZXkuZXF1YWxzKElQcm9wZXJ0eVNoZWV0UGFnZS5jbGFzcykpIHsNCgkJCXJldHVybiBnZXRQcm9wZXJ0eVNoZWV0UGFnZSgpOw0KCQl9DQoJCWVsc2UgaWYgKGtleS5lcXVhbHMoSUdvdG9NYXJrZXIuY2xhc3MpKSB7DQoJCQlyZXR1cm4gdGhpczsNCgkJfQ0KCQllbHNlIHsNCgkJCXJldHVybiBzdXBlci5nZXRBZGFwdGVyKGtleSk7DQoJCX0NCgl9DQoNCgkvKioNCgkgKiBUaGlzIGFjY2Vzc2VzIGEgY2FjaGVkIHZlcnNpb24gb2YgdGhlIGNvbnRlbnQgb3V0bGluZXIuDQoJICogPCEtLSBiZWdpbi11c2VyLWRvYyAtLT4NCgkgKiA8IS0tIGVuZC11c2VyLWRvYyAtLT4NCgkgKiBAZ2VuZXJhdGVkDQoJICovDQoJcHVibGljIElDb250ZW50T3V0bGluZVBhZ2UgZ2V0Q29udGVudE91dGxpbmVQYWdlKCkgew0KCQlpZiAoY29udGVudE91dGxpbmVQYWdlID09IG51bGwpIHsNCgkJCS8vIFRoZSBjb250ZW50IG91dGxpbmUgaXMganVzdCBhIHRyZWUuDQoJCQkvLw0KCQkJY2xhc3MgTXlDb250ZW50T3V0bGluZVBhZ2UgZXh0ZW5kcyBDb250ZW50T3V0bGluZVBhZ2Ugew0KCQkJCUBPdmVycmlkZQ0KCQkJCXB1YmxpYyB2b2lkIGNyZWF0ZUNvbnRyb2woQ29tcG9zaXRlIHBhcmVudCkgew0KCQkJCQlzdXBlci5jcmVhdGVDb250cm9sKHBhcmVudCk7DQoJCQkJCWNvbnRlbnRPdXRsaW5lVmlld2VyID0gZ2V0VHJlZVZpZXdlcigpOw0KCQkJCQljb250ZW50T3V0bGluZVZpZXdlci5hZGRTZWxlY3Rpb25DaGFuZ2VkTGlzdGVuZXIodGhpcyk7DQoNCgkJCQkJLy8gU2V0IHVwIHRoZSB0cmVlIHZpZXdlci4NCgkJCQkJLy8NCgkJCQkJY29udGVudE91dGxpbmVWaWV3ZXIuc2V0Q29udGVudFByb3ZpZGVyKG5ldyBBZGFwdGVyRmFjdG9yeUNvbnRlbnRQcm92aWRlcihhZGFwdGVyRmFjdG9yeSkpOw0KCQkJCQljb250ZW50T3V0bGluZVZpZXdlci5zZXRMYWJlbFByb3ZpZGVyKG5ldyBBZGFwdGVyRmFjdG9yeUxhYmVsUHJvdmlkZXIoYWRhcHRlckZhY3RvcnkpKTsNCgkJCQkJY29udGVudE91dGxpbmVWaWV3ZXIuc2V0SW5wdXQoZWRpdGluZ0RvbWFpbi5nZXRSZXNvdXJjZVNldCgpKTsNCg0KCQkJCQkvLyBNYWtlIHN1cmUgb3VyIHBvcHVwcyB3b3JrLg0KCQkJCQkvLw0KCQkJCQljcmVhdGVDb250ZXh0TWVudUZvcihjb250ZW50T3V0bGluZVZpZXdlcik7DQoNCgkJCQkJaWYgKCFlZGl0aW5nRG9tYWluLmdldFJlc291cmNlU2V0KCkuZ2V0UmVzb3VyY2VzKCkuaXNFbXB0eSgpKSB7DQoJCQkJCSAgLy8gU2VsZWN0IHRoZSByb290IG9iamVjdCBpbiB0aGUgdmlldy4NCgkJCQkJICAvLw0KCQkJCQkgIGNvbnRlbnRPdXRsaW5lVmlld2VyLnNldFNlbGVjdGlvbihuZXcgU3RydWN0dXJlZFNlbGVjdGlvbihlZGl0aW5nRG9tYWluLmdldFJlc291cmNlU2V0KCkuZ2V0UmVzb3VyY2VzKCkuZ2V0KDApKSwgdHJ1ZSk7DQoJCQkJCX0NCgkJCQl9DQoNCgkJCQlAT3ZlcnJpZGUNCgkJCQlwdWJsaWMgdm9pZCBtYWtlQ29udHJpYnV0aW9ucyhJTWVudU1hbmFnZXIgbWVudU1hbmFnZXIsIElUb29sQmFyTWFuYWdlciB0b29sQmFyTWFuYWdlciwgSVN0YXR1c0xpbmVNYW5hZ2VyIHN0YXR1c0xpbmVNYW5hZ2VyKSB7DQoJCQkJCXN1cGVyLm1ha2VDb250cmlidXRpb25zKG1lbnVNYW5hZ2VyLCB0b29sQmFyTWFuYWdlciwgc3RhdHVzTGluZU1hbmFnZXIpOw0KCQkJCQljb250ZW50T3V0bGluZVN0YXR1c0xpbmVNYW5hZ2VyID0gc3RhdHVzTGluZU1hbmFnZXI7DQoJCQkJfQ0KDQoJCQkJQE92ZXJyaWRlDQoJCQkJcHVibGljIHZvaWQgc2V0QWN0aW9uQmFycyhJQWN0aW9uQmFycyBhY3Rpb25CYXJzKSB7DQoJCQkJCXN1cGVyLnNldEFjdGlvbkJhcnMoYWN0aW9uQmFycyk7DQoJCQkJCWdldEFjdGlvbkJhckNvbnRyaWJ1dG9yKCkuc2hhcmVHbG9iYWxBY3Rpb25zKHRoaXMsIGFjdGlvbkJhcnMpOw0KCQkJCX0NCgkJCX0NCg0KCQkJY29udGVudE91dGxpbmVQYWdlID0gbmV3IE15Q29udGVudE91dGxpbmVQYWdlKCk7DQoNCgkJCS8vIExpc3RlbiB0byBzZWxlY3Rpb24gc28gdGhhdCB3ZSBjYW4gaGFuZGxlIGl0IGlzIGEgc3BlY2lhbCB3YXkuDQoJCQkvLw0KCQkJY29udGVudE91dGxpbmVQYWdlLmFkZFNlbGVjdGlvbkNoYW5nZWRMaXN0ZW5lcg0KCQkJCShuZXcgSVNlbGVjdGlvbkNoYW5nZWRMaXN0ZW5lcigpIHsNCgkJCQkJIC8vIFRoaXMgZW5zdXJlcyB0aGF0IHdlIGhhbmRsZSBzZWxlY3Rpb25zIGNvcnJlY3RseS4NCgkJCQkJIC8vDQoJCQkJCSBwdWJsaWMgdm9pZCBzZWxlY3Rpb25DaGFuZ2VkKFNlbGVjdGlvbkNoYW5nZWRFdmVudCBldmVudCkgew0KCQkJCQkJIGhhbmRsZUNvbnRlbnRPdXRsaW5lU2VsZWN0aW9uKGV2ZW50LmdldFNlbGVjdGlvbigpKTsNCgkJCQkJIH0NCgkJCQkgfSk7DQoJCX0NCg0KCQlyZXR1cm4gY29udGVudE91dGxpbmVQYWdlOw0KCX0NCg0KCS8qKg0KCSAqIFRoaXMgYWNjZXNzZXMgYSBjYWNoZWQgdmVyc2lvbiBvZiB0aGUgcHJvcGVydHkgc2hlZXQuDQoJICogPCEtLSBiZWdpbi11c2VyLWRvYyAtLT4NCgkgKiA8IS0tIGVuZC11c2VyLWRvYyAtLT4NCgkgKiBAZ2VuZXJhdGVkIE5PVA0KCSAqLw0KCXB1YmxpYyBJUHJvcGVydHlTaGVldFBhZ2UgZ2V0UHJvcGVydHlTaGVldFBhZ2UoKSB7DQoJCS8vIFN0YXJ0IE1DUA0KCQlUYWJiZWRQcm9wZXJ0eVNoZWV0UGFnZSBwcm9wZXJ0eVNoZWV0UGFnZSA9IG5ldyBUYWJiZWRQcm9wZXJ0eVNoZWV0UGFnZShBcmdFZGl0b3IudGhpcyk7DQoJCS8vIEVuZCBNQ1ANCg0KCQlyZXR1cm4gcHJvcGVydHlTaGVldFBhZ2U7DQoJfQ0KDQoJLyoqDQoJICogVGhpcyBkZWFscyB3aXRoIGhvdyB3ZSB3YW50IHNlbGVjdGlvbiBpbiB0aGUgb3V0bGluZXIgdG8gYWZmZWN0IHRoZSBvdGhlciB2aWV3cy4NCgkgKiA8IS0tIGJlZ2luLXVzZXItZG9jIC0tPg0KCSAqIDwhLS0gZW5kLXVzZXItZG9jIC0tPg0KCSAqIEBnZW5lcmF0ZWQNCgkgKi8NCglwdWJsaWMgdm9pZCBoYW5kbGVDb250ZW50T3V0bGluZVNlbGVjdGlvbihJU2VsZWN0aW9uIHNlbGVjdGlvbikgew0KCQlpZiAoY3VycmVudFZpZXdlclBhbmUgIT0gbnVsbCAmJiAhc2VsZWN0aW9uLmlzRW1wdHkoKSAmJiBzZWxlY3Rpb24gaW5zdGFuY2VvZiBJU3RydWN0dXJlZFNlbGVjdGlvbikgew0KCQkJSXRlcmF0b3I8Pz4gc2VsZWN0ZWRFbGVtZW50cyA9ICgoSVN0cnVjdHVyZWRTZWxlY3Rpb24pc2VsZWN0aW9uKS5pdGVyYXRvcigpOw0KCQkJaWYgKHNlbGVjdGVkRWxlbWVudHMuaGFzTmV4dCgpKSB7DQoJCQkJLy8gR2V0IHRoZSBmaXJzdCBzZWxlY3RlZCBlbGVtZW50Lg0KCQkJCS8vDQoJCQkJT2JqZWN0IHNlbGVjdGVkRWxlbWVudCA9IHNlbGVjdGVkRWxlbWVudHMubmV4dCgpOw0KDQoJCQkJLy8gSWYgaXQncyB0aGUgc2VsZWN0aW9uIHZpZXdlciwgdGhlbiB3ZSB3YW50IGl0IHRvIHNlbGVjdCB0aGUgc2FtZSBzZWxlY3Rpb24gYXMgdGhpcyBzZWxlY3Rpb24uDQoJCQkJLy8NCgkJCQlpZiAoY3VycmVudFZpZXdlclBhbmUuZ2V0Vmlld2VyKCkgPT0gc2VsZWN0aW9uVmlld2VyKSB7DQoJCQkJCUFycmF5TGlzdDxPYmplY3Q+IHNlbGVjdGlvbkxpc3QgPSBuZXcgQXJyYXlMaXN0PE9iamVjdD4oKTsNCgkJCQkJc2VsZWN0aW9uTGlzdC5hZGQoc2VsZWN0ZWRFbGVtZW50KTsNCgkJCQkJd2hpbGUgKHNlbGVjdGVkRWxlbWVudHMuaGFzTmV4dCgpKSB7DQoJCQkJCQlzZWxlY3Rpb25MaXN0LmFkZChzZWxlY3RlZEVsZW1lbnRzLm5leHQoKSk7DQoJCQkJCX0NCg0KCQkJCQkvLyBTZXQgdGhlIHNlbGVjdGlvbiB0byB0aGUgd2lkZ2V0Lg0KCQkJCQkvLw0KCQkJCQlzZWxlY3Rpb25WaWV3ZXIuc2V0U2VsZWN0aW9uKG5ldyBTdHJ1Y3R1cmVkU2VsZWN0aW9uKHNlbGVjdGlvbkxpc3QpKTsNCgkJCQl9DQoJCQkJZWxzZSB7DQoJCQkJCS8vIFNldCB0aGUgaW5wdXQgdG8gdGhlIHdpZGdldC4NCgkJCQkJLy8NCgkJCQkJaWYgKGN1cnJlbnRWaWV3ZXJQYW5lLmdldFZpZXdlcigpLmdldElucHV0KCkgIT0gc2VsZWN0ZWRFbGVtZW50KSB7DQoJCQkJCQljdXJyZW50Vmlld2VyUGFuZS5nZXRWaWV3ZXIoKS5zZXRJbnB1dChzZWxlY3RlZEVsZW1lbnQpOw0KCQkJCQkJY3VycmVudFZpZXdlclBhbmUuc2V0VGl0bGUoc2VsZWN0ZWRFbGVtZW50KTsNCgkJCQkJfQ0KCQkJCX0NCgkJCX0NCgkJfQ0KCX0NCg0KCS8qKg0KCSAqIFRoaXMgaXMgZm9yIGltcGxlbWVudGluZyB7QGxpbmsgSUVkaXRvclBhcnR9IGFuZCBzaW1wbHkgdGVzdHMgdGhlIGNvbW1hbmQgc3RhY2suDQoJICogPCEtLSBiZWdpbi11c2VyLWRvYyAtLT4NCgkgKiA8IS0tIGVuZC11c2VyLWRvYyAtLT4NCgkgKiBAZ2VuZXJhdGVkDQoJICovDQoJQE92ZXJyaWRlDQoJcHVibGljIGJvb2xlYW4gaXNEaXJ0eSgpIHsNCgkJcmV0dXJuICgoQmFzaWNDb21tYW5kU3RhY2spZWRpdGluZ0RvbWFpbi5nZXRDb21tYW5kU3RhY2soKSkuaXNTYXZlTmVlZGVkKCk7DQoJfQ0KDQoJLyoqDQoJICogVGhpcyBpcyBmb3IgaW1wbGVtZW50aW5nIHtAbGluayBJRWRpdG9yUGFydH0gYW5kIHNpbXBseSBzYXZlcyB0aGUgbW9kZWwgZmlsZS4NCgkgKiA8IS0tIGJlZ2luLXVzZXItZG9jIC0tPg0KCSAqIDwhLS0gZW5kLXVzZXItZG9jIC0tPg0KCSAqIEBnZW5lcmF0ZWQNCgkgKi8NCglAT3ZlcnJpZGUNCglwdWJsaWMgdm9pZCBkb1NhdmUoSVByb2dyZXNzTW9uaXRvciBwcm9ncmVzc01vbml0b3IpIHsNCgkJLy8gU2F2ZSBvbmx5IHJlc291cmNlcyB0aGF0IGhhdmUgYWN0dWFsbHkgY2hhbmdlZC4NCgkJLy8NCgkJZmluYWwgTWFwPE9iamVjdCwgT2JqZWN0PiBzYXZlT3B0aW9ucyA9IG5ldyBIYXNoTWFwPE9iamVjdCwgT2JqZWN0PigpOw0KCQlzYXZlT3B0aW9ucy5wdXQoUmVzb3VyY2UuT1BUSU9OX1NBVkVfT05MWV9JRl9DSEFOR0VELCBSZXNvdXJjZS5PUFRJT05fU0FWRV9PTkxZX0lGX0NIQU5HRURfTUVNT1JZX0JVRkZFUik7DQoJCXNhdmVPcHRpb25zLnB1dChSZXNvdXJjZS5PUFRJT05fTElORV9ERUxJTUlURVIsIFJlc291cmNlLk9QVElPTl9MSU5FX0RFTElNSVRFUl9VTlNQRUNJRklFRCk7DQoNCgkJLy8gRG8gdGhlIHdvcmsgd2l0aGluIGFuIG9wZXJhdGlvbiBiZWNhdXNlIHRoaXMgaXMgYSBsb25nIHJ1bm5pbmcgYWN0aXZpdHkgdGhhdCBtb2RpZmllcyB0aGUgd29ya2JlbmNoLg0KCQkvLw0KCQlXb3Jrc3BhY2VNb2RpZnlPcGVyYXRpb24gb3BlcmF0aW9uID0NCgkJCW5ldyBXb3Jrc3BhY2VNb2RpZnlPcGVyYXRpb24oKSB7DQoJCQkJLy8gVGhpcyBpcyB0aGUgbWV0aG9kIHRoYXQgZ2V0cyBpbnZva2VkIHdoZW4gdGhlIG9wZXJhdGlvbiBydW5zLg0KCQkJCS8vDQoJCQkJQE92ZXJyaWRlDQoJCQkJcHVibGljIHZvaWQgZXhlY3V0ZShJUHJvZ3Jlc3NNb25pdG9yIG1vbml0b3IpIHsNCgkJCQkJLy8gU2F2ZSB0aGUgcmVzb3VyY2VzIHRvIHRoZSBmaWxlIHN5c3RlbS4NCgkJCQkJLy8NCgkJCQkJYm9vbGVhbiBmaXJzdCA9IHRydWU7DQoJCQkJCWZvciAoUmVzb3VyY2UgcmVzb3VyY2UgOiBlZGl0aW5nRG9tYWluLmdldFJlc291cmNlU2V0KCkuZ2V0UmVzb3VyY2VzKCkpIHsNCgkJCQkJCWlmICgoZmlyc3QgfHwgIXJlc291cmNlLmdldENvbnRlbnRzKCkuaXNFbXB0eSgpIHx8IGlzUGVyc2lzdGVkKHJlc291cmNlKSkgJiYgIWVkaXRpbmdEb21haW4uaXNSZWFkT25seShyZXNvdXJjZSkpIHsNCgkJCQkJCQl0cnkgew0KCQkJCQkJCQlsb25nIHRpbWVTdGFtcCA9IHJlc291cmNlLmdldFRpbWVTdGFtcCgpOw0KCQkJCQkJCQlyZXNvdXJjZS5zYXZlKHNhdmVPcHRpb25zKTsNCgkJCQkJCQkJaWYgKHJlc291cmNlLmdldFRpbWVTdGFtcCgpICE9IHRpbWVTdGFtcCkgew0KCQkJCQkJCQkJc2F2ZWRSZXNvdXJjZXMuYWRkKHJlc291cmNlKTsNCgkJCQkJCQkJfQ0KCQkJCQkJCX0NCgkJCQkJCQljYXRjaCAoRXhjZXB0aW9uIGV4Y2VwdGlvbikgew0KCQkJCQkJCQlyZXNvdXJjZVRvRGlhZ25vc3RpY01hcC5wdXQocmVzb3VyY2UsIGFuYWx5emVSZXNvdXJjZVByb2JsZW1zKHJlc291cmNlLCBleGNlcHRpb24pKTsNCgkJCQkJCQl9DQoJCQkJCQkJZmlyc3QgPSBmYWxzZTsNCgkJCQkJCX0NCgkJCQkJfQ0KCQkJCX0NCgkJCX07DQoNCgkJdXBkYXRlUHJvYmxlbUluZGljYXRpb24gPSBmYWxzZTsNCgkJdHJ5IHsNCgkJCS8vIFRoaXMgcnVucyB0aGUgb3B0aW9ucywgYW5kIHNob3dzIHByb2dyZXNzLg0KCQkJLy8NCgkJCW5ldyBQcm9ncmVzc01vbml0b3JEaWFsb2coZ2V0U2l0ZSgpLmdldFNoZWxsKCkpLnJ1bih0cnVlLCBmYWxzZSwgb3BlcmF0aW9uKTsNCg0KCQkJLy8gUmVmcmVzaCB0aGUgbmVjZXNzYXJ5IHN0YXRlLg0KCQkJLy8NCgkJCSgoQmFzaWNDb21tYW5kU3RhY2spZWRpdGluZ0RvbWFpbi5nZXRDb21tYW5kU3RhY2soKSkuc2F2ZUlzRG9uZSgpOw0KCQkJZmlyZVByb3BlcnR5Q2hhbmdlKElFZGl0b3JQYXJ0LlBST1BfRElSVFkpOw0KCQl9DQoJCWNhdGNoIChFeGNlcHRpb24gZXhjZXB0aW9uKSB7DQoJCQkvLyBTb21ldGhpbmcgd2VudCB3cm9uZyB0aGF0IHNob3VsZG4ndC4NCgkJCS8vDQoJCQlBcmdFZGl0b3JQbHVnaW4uSU5TVEFOQ0UubG9nKGV4Y2VwdGlvbik7DQoJCX0NCgkJdXBkYXRlUHJvYmxlbUluZGljYXRpb24gPSB0cnVlOw0KCQl1cGRhdGVQcm9ibGVtSW5kaWNhdGlvbigpOw0KCX0NCg0KCS8qKg0KCSAqIFRoaXMgcmV0dXJucyB3aGV0aGVyIHNvbWV0aGluZyBoYXMgYmVlbiBwZXJzaXN0ZWQgdG8gdGhlIFVSSSBvZiB0aGUgc3BlY2lmaWVkIHJlc291cmNlLg0KCSAqIFRoZSBpbXBsZW1lbnRhdGlvbiB1c2VzIHRoZSBVUkkgY29udmVydGVyIGZyb20gdGhlIGVkaXRvcidzIHJlc291cmNlIHNldCB0byB0cnkgdG8gb3BlbiBhbiBpbnB1dCBzdHJlYW0uDQoJICogPCEtLSBiZWdpbi11c2VyLWRvYyAtLT4NCgkgKiA8IS0tIGVuZC11c2VyLWRvYyAtLT4NCgkgKiBAZ2VuZXJhdGVkDQoJICovDQoJcHJvdGVjdGVkIGJvb2xlYW4gaXNQZXJzaXN0ZWQoUmVzb3VyY2UgcmVzb3VyY2UpIHsNCgkJYm9vbGVhbiByZXN1bHQgPSBmYWxzZTsNCgkJdHJ5IHsNCgkJCUlucHV0U3RyZWFtIHN0cmVhbSA9IGVkaXRpbmdEb21haW4uZ2V0UmVzb3VyY2VTZXQoKS5nZXRVUklDb252ZXJ0ZXIoKS5jcmVhdGVJbnB1dFN0cmVhbShyZXNvdXJjZS5nZXRVUkkoKSk7DQoJCQlpZiAoc3RyZWFtICE9IG51bGwpIHsNCgkJCQlyZXN1bHQgPSB0cnVlOw0KCQkJCXN0cmVhbS5jbG9zZSgpOw0KCQkJfQ0KCQl9DQoJCWNhdGNoIChJT0V4Y2VwdGlvbiBlKSB7DQoJCQkvLyBJZ25vcmUNCgkJfQ0KCQlyZXR1cm4gcmVzdWx0Ow0KCX0NCg0KCS8qKg0KCSAqIFRoaXMgYWx3YXlzIHJldHVybnMgdHJ1ZSBiZWNhdXNlIGl0IGlzIG5vdCBjdXJyZW50bHkgc3VwcG9ydGVkLg0KCSAqIDwhLS0gYmVnaW4tdXNlci1kb2MgLS0+DQoJICogPCEtLSBlbmQtdXNlci1kb2MgLS0+DQoJICogQGdlbmVyYXRlZA0KCSAqLw0KCUBPdmVycmlkZQ0KCXB1YmxpYyBib29sZWFuIGlzU2F2ZUFzQWxsb3dlZCgpIHsNCgkJcmV0dXJuIHRydWU7DQoJfQ0KDQoJLyoqDQoJICogVGhpcyBhbHNvIGNoYW5nZXMgdGhlIGVkaXRvcidzIGlucHV0Lg0KCSAqIDwhLS0gYmVnaW4tdXNlci1kb2MgLS0+DQoJICogPCEtLSBlbmQtdXNlci1kb2MgLS0+DQoJICogQGdlbmVyYXRlZA0KCSAqLw0KCUBPdmVycmlkZQ0KCXB1YmxpYyB2b2lkIGRvU2F2ZUFzKCkgew0KCQlTYXZlQXNEaWFsb2cgc2F2ZUFzRGlhbG9nID0gbmV3IFNhdmVBc0RpYWxvZyhnZXRTaXRlKCkuZ2V0U2hlbGwoKSk7DQoJCXNhdmVBc0RpYWxvZy5vcGVuKCk7DQoJCUlQYXRoIHBhdGggPSBzYXZlQXNEaWFsb2cuZ2V0UmVzdWx0KCk7DQoJCWlmIChwYXRoICE9IG51bGwpIHsNCgkJCUlGaWxlIGZpbGUgPSBSZXNvdXJjZXNQbHVnaW4uZ2V0V29ya3NwYWNlKCkuZ2V0Um9vdCgpLmdldEZpbGUocGF0aCk7DQoJCQlpZiAoZmlsZSAhPSBudWxsKSB7DQoJCQkJZG9TYXZlQXMoVVJJLmNyZWF0ZVBsYXRmb3JtUmVzb3VyY2VVUkkoZmlsZS5nZXRGdWxsUGF0aCgpLnRvU3RyaW5nKCksIHRydWUpLCBuZXcgRmlsZUVkaXRvcklucHV0KGZpbGUpKTsNCgkJCX0NCgkJfQ0KCX0NCg0KCS8qKg0KCSAqIDwhLS0gYmVnaW4tdXNlci1kb2MgLS0+DQoJICogPCEtLSBlbmQtdXNlci1kb2MgLS0+DQoJICogQGdlbmVyYXRlZA0KCSAqLw0KCXByb3RlY3RlZCB2b2lkIGRvU2F2ZUFzKFVSSSB1cmksIElFZGl0b3JJbnB1dCBlZGl0b3JJbnB1dCkgew0KCQkoZWRpdGluZ0RvbWFpbi5nZXRSZXNvdXJjZVNldCgpLmdldFJlc291cmNlcygpLmdldCgwKSkuc2V0VVJJKHVyaSk7DQoJCXNldElucHV0V2l0aE5vdGlmeShlZGl0b3JJbnB1dCk7DQoJCXNldFBhcnROYW1lKGVkaXRvcklucHV0LmdldE5hbWUoKSk7DQoJCUlQcm9ncmVzc01vbml0b3IgcHJvZ3Jlc3NNb25pdG9yID0NCgkJCWdldEFjdGlvbkJhcnMoKS5nZXRTdGF0dXNMaW5lTWFuYWdlcigpICE9IG51bGwgPw0KCQkJCWdldEFjdGlvbkJhcnMoKS5nZXRTdGF0dXNMaW5lTWFuYWdlcigpLmdldFByb2dyZXNzTW9uaXRvcigpIDoNCgkJCQluZXcgTnVsbFByb2dyZXNzTW9uaXRvcigpOw0KCQlkb1NhdmUocHJvZ3Jlc3NNb25pdG9yKTsNCgl9DQoNCgkvKioNCgkgKiA8IS0tIGJlZ2luLXVzZXItZG9jIC0tPg0KCSAqIDwhLS0gZW5kLXVzZXItZG9jIC0tPg0KCSAqIEBnZW5lcmF0ZWQNCgkgKi8NCglwdWJsaWMgdm9pZCBnb3RvTWFya2VyKElNYXJrZXIgbWFya2VyKSB7DQoJCUxpc3Q8Pz4gdGFyZ2V0T2JqZWN0cyA9IG1hcmtlckhlbHBlci5nZXRUYXJnZXRPYmplY3RzKGVkaXRpbmdEb21haW4sIG1hcmtlcik7DQoJCWlmICghdGFyZ2V0T2JqZWN0cy5pc0VtcHR5KCkpIHsNCgkJCXNldFNlbGVjdGlvblRvVmlld2VyKHRhcmdldE9iamVjdHMpOw0KCQl9DQoJfQ0KDQoJLyoqDQoJICogVGhpcyBpcyBjYWxsZWQgZHVyaW5nIHN0YXJ0dXAuDQoJICogPCEtLSBiZWdpbi11c2VyLWRvYyAtLT4NCgkgKiA8IS0tIGVuZC11c2VyLWRvYyAtLT4NCgkgKiBAZ2VuZXJhdGVkDQoJICovDQoJQE92ZXJyaWRlDQoJcHVibGljIHZvaWQgaW5pdChJRWRpdG9yU2l0ZSBzaXRlLCBJRWRpdG9ySW5wdXQgZWRpdG9ySW5wdXQpIHsNCgkJc2V0U2l0ZShzaXRlKTsNCgkJc2V0SW5wdXRXaXRoTm90aWZ5KGVkaXRvcklucHV0KTsNCgkJc2V0UGFydE5hbWUoZWRpdG9ySW5wdXQuZ2V0TmFtZSgpKTsNCgkJc2l0ZS5zZXRTZWxlY3Rpb25Qcm92aWRlcih0aGlzKTsNCgkJc2l0ZS5nZXRQYWdlKCkuYWRkUGFydExpc3RlbmVyKHBhcnRMaXN0ZW5lcik7DQoJCVJlc291cmNlc1BsdWdpbi5nZXRXb3Jrc3BhY2UoKS5hZGRSZXNvdXJjZUNoYW5nZUxpc3RlbmVyKHJlc291cmNlQ2hhbmdlTGlzdGVuZXIsIElSZXNvdXJjZUNoYW5nZUV2ZW50LlBPU1RfQ0hBTkdFKTsNCgl9DQoNCgkvKioNCgkgKiA8IS0tIGJlZ2luLXVzZXItZG9jIC0tPg0KCSAqIDwhLS0gZW5kLXVzZXItZG9jIC0tPg0KCSAqIEBnZW5lcmF0ZWQNCgkgKi8NCglAT3ZlcnJpZGUNCglwdWJsaWMgdm9pZCBzZXRGb2N1cygpIHsNCgkJaWYgKGN1cnJlbnRWaWV3ZXJQYW5lICE9IG51bGwpIHsNCgkJCWN1cnJlbnRWaWV3ZXJQYW5lLnNldEZvY3VzKCk7DQoJCX0NCgkJZWxzZSB7DQoJCQlnZXRDb250cm9sKGdldEFjdGl2ZVBhZ2UoKSkuc2V0Rm9jdXMoKTsNCgkJfQ0KCX0NCg0KCS8qKg0KCSAqIFRoaXMgaW1wbGVtZW50cyB7QGxpbmsgb3JnLmVjbGlwc2UuamZhY2Uudmlld2Vycy5JU2VsZWN0aW9uUHJvdmlkZXJ9Lg0KCSAqIDwhLS0gYmVnaW4tdXNlci1kb2MgLS0+DQoJICogPCEtLSBlbmQtdXNlci1kb2MgLS0+DQoJICogQGdlbmVyYXRlZA0KCSAqLw0KCXB1YmxpYyB2b2lkIGFkZFNlbGVjdGlvbkNoYW5nZWRMaXN0ZW5lcihJU2VsZWN0aW9uQ2hhbmdlZExpc3RlbmVyIGxpc3RlbmVyKSB7DQoJCXNlbGVjdGlvbkNoYW5nZWRMaXN0ZW5lcnMuYWRkKGxpc3RlbmVyKTsNCgl9DQoNCgkvKioNCgkgKiBUaGlzIGltcGxlbWVudHMge0BsaW5rIG9yZy5lY2xpcHNlLmpmYWNlLnZpZXdlcnMuSVNlbGVjdGlvblByb3ZpZGVyfS4NCgkgKiA8IS0tIGJlZ2luLXVzZXItZG9jIC0tPg0KCSAqIDwhLS0gZW5kLXVzZXItZG9jIC0tPg0KCSAqIEBnZW5lcmF0ZWQNCgkgKi8NCglwdWJsaWMgdm9pZCByZW1vdmVTZWxlY3Rpb25DaGFuZ2VkTGlzdGVuZXIoSVNlbGVjdGlvbkNoYW5nZWRMaXN0ZW5lciBsaXN0ZW5lcikgew0KCQlzZWxlY3Rpb25DaGFuZ2VkTGlzdGVuZXJzLnJlbW92ZShsaXN0ZW5lcik7DQoJfQ0KDQoJLyoqDQoJICogVGhpcyBpbXBsZW1lbnRzIHtAbGluayBvcmcuZWNsaXBzZS5qZmFjZS52aWV3ZXJzLklTZWxlY3Rpb25Qcm92aWRlcn0gdG8gcmV0dXJuIHRoaXMgZWRpdG9yJ3Mgb3ZlcmFsbCBzZWxlY3Rpb24uDQoJICogPCEtLSBiZWdpbi11c2VyLWRvYyAtLT4NCgkgKiA8IS0tIGVuZC11c2VyLWRvYyAtLT4NCgkgKiBAZ2VuZXJhdGVkDQoJICovDQoJcHVibGljIElTZWxlY3Rpb24gZ2V0U2VsZWN0aW9uKCkgew0KCQlyZXR1cm4gZWRpdG9yU2VsZWN0aW9uOw0KCX0NCg0KCS8qKg0KCSAqIFRoaXMgaW1wbGVtZW50cyB7QGxpbmsgb3JnLmVjbGlwc2UuamZhY2Uudmlld2Vycy5JU2VsZWN0aW9uUHJvdmlkZXJ9IHRvIHNldCB0aGlzIGVkaXRvcidzIG92ZXJhbGwgc2VsZWN0aW9uLg0KCSAqIENhbGxpbmcgdGhpcyByZXN1bHQgd2lsbCBub3RpZnkgdGhlIGxpc3RlbmVycy4NCgkgKiA8IS0tIGJlZ2luLXVzZXItZG9jIC0tPg0KCSAqIDwhLS0gZW5kLXVzZXItZG9jIC0tPg0KCSAqIEBnZW5lcmF0ZWQNCgkgKi8NCglwdWJsaWMgdm9pZCBzZXRTZWxlY3Rpb24oSVNlbGVjdGlvbiBzZWxlY3Rpb24pIHsNCgkJZWRpdG9yU2VsZWN0aW9uID0gc2VsZWN0aW9uOw0KDQoJCWZvciAoSVNlbGVjdGlvbkNoYW5nZWRMaXN0ZW5lciBsaXN0ZW5lciA6IHNlbGVjdGlvbkNoYW5nZWRMaXN0ZW5lcnMpIHsNCgkJCWxpc3RlbmVyLnNlbGVjdGlvbkNoYW5nZWQobmV3IFNlbGVjdGlvbkNoYW5nZWRFdmVudCh0aGlzLCBzZWxlY3Rpb24pKTsNCgkJfQ0KCQlzZXRTdGF0dXNMaW5lTWFuYWdlcihzZWxlY3Rpb24pOw0KCX0NCg0KCS8qKg0KCSAqIDwhLS0gYmVnaW4tdXNlci1kb2MgLS0+DQoJICogPCEtLSBlbmQtdXNlci1kb2MgLS0+DQoJICogQGdlbmVyYXRlZA0KCSAqLw0KCXB1YmxpYyB2b2lkIHNldFN0YXR1c0xpbmVNYW5hZ2VyKElTZWxlY3Rpb24gc2VsZWN0aW9uKSB7DQoJCUlTdGF0dXNMaW5lTWFuYWdlciBzdGF0dXNMaW5lTWFuYWdlciA9IGN1cnJlbnRWaWV3ZXIgIT0gbnVsbCAmJiBjdXJyZW50Vmlld2VyID09IGNvbnRlbnRPdXRsaW5lVmlld2VyID8NCgkJCWNvbnRlbnRPdXRsaW5lU3RhdHVzTGluZU1hbmFnZXIgOiBnZXRBY3Rpb25CYXJzKCkuZ2V0U3RhdHVzTGluZU1hbmFnZXIoKTsNCg0KCQlpZiAoc3RhdHVzTGluZU1hbmFnZXIgIT0gbnVsbCkgew0KCQkJaWYgKHNlbGVjdGlvbiBpbnN0YW5jZW9mIElTdHJ1Y3R1cmVkU2VsZWN0aW9uKSB7DQoJCQkJQ29sbGVjdGlvbjw/PiBjb2xsZWN0aW9uID0gKChJU3RydWN0dXJlZFNlbGVjdGlvbilzZWxlY3Rpb24pLnRvTGlzdCgpOw0KCQkJCXN3aXRjaCAoY29sbGVjdGlvbi5zaXplKCkpIHsNCgkJCQkJY2FzZSAwOiB7DQoJCQkJCQlzdGF0dXNMaW5lTWFuYWdlci5zZXRNZXNzYWdlKGdldFN0cmluZygiX1VJX05vT2JqZWN0U2VsZWN0ZWQiKSk7DQoJCQkJCQlicmVhazsNCgkJCQkJfQ0KCQkJCQljYXNlIDE6IHsNCgkJCQkJCVN0cmluZyB0ZXh0ID0gbmV3IEFkYXB0ZXJGYWN0b3J5SXRlbURlbGVnYXRvcihhZGFwdGVyRmFjdG9yeSkuZ2V0VGV4dChjb2xsZWN0aW9uLml0ZXJhdG9yKCkubmV4dCgpKTsNCgkJCQkJCXN0YXR1c0xpbmVNYW5hZ2VyLnNldE1lc3NhZ2UoZ2V0U3RyaW5nKCJfVUlfU2luZ2xlT2JqZWN0U2VsZWN0ZWQiLCB0ZXh0KSk7DQoJCQkJCQlicmVhazsNCgkJCQkJfQ0KCQkJCQlkZWZhdWx0OiB7DQoJCQkJCQlzdGF0dXNMaW5lTWFuYWdlci5zZXRNZXNzYWdlKGdldFN0cmluZygiX1VJX011bHRpT2JqZWN0U2VsZWN0ZWQiLCBJbnRlZ2VyLnRvU3RyaW5nKGNvbGxlY3Rpb24uc2l6ZSgpKSkpOw0KCQkJCQkJYnJlYWs7DQoJCQkJCX0NCgkJCQl9DQoJCQl9DQoJCQllbHNlIHsNCgkJCQlzdGF0dXNMaW5lTWFuYWdlci5zZXRNZXNzYWdlKCIiKTsNCgkJCX0NCgkJfQ0KCX0NCg0KCS8qKg0KCSAqIFRoaXMgbG9va3MgdXAgYSBzdHJpbmcgaW4gdGhlIHBsdWdpbidzIHBsdWdpbi5wcm9wZXJ0aWVzIGZpbGUuDQoJICogPCEtLSBiZWdpbi11c2VyLWRvYyAtLT4NCgkgKiA8IS0tIGVuZC11c2VyLWRvYyAtLT4NCgkgKiBAZ2VuZXJhdGVkDQoJICovDQoJcHJpdmF0ZSBzdGF0aWMgU3RyaW5nIGdldFN0cmluZyhTdHJpbmcga2V5KSB7DQoJCXJldHVybiBBcmdFZGl0b3JQbHVnaW4uSU5TVEFOQ0UuZ2V0U3RyaW5nKGtleSk7DQoJfQ0KDQoJLyoqDQoJICogVGhpcyBsb29rcyB1cCBhIHN0cmluZyBpbiBwbHVnaW4ucHJvcGVydGllcywgbWFraW5nIGEgc3Vic3RpdHV0aW9uLg0KCSAqIDwhLS0gYmVnaW4tdXNlci1kb2MgLS0+DQoJICogPCEtLSBlbmQtdXNlci1kb2MgLS0+DQoJICogQGdlbmVyYXRlZA0KCSAqLw0KCXByaXZhdGUgc3RhdGljIFN0cmluZyBnZXRTdHJpbmcoU3RyaW5nIGtleSwgT2JqZWN0IHMxKSB7DQoJCXJldHVybiBBcmdFZGl0b3JQbHVnaW4uSU5TVEFOQ0UuZ2V0U3RyaW5nKGtleSwgbmV3IE9iamVjdCBbXSB7IHMxIH0pOw0KCX0NCg0KCS8qKg0KCSAqIFRoaXMgaW1wbGVtZW50cyB7QGxpbmsgb3JnLmVjbGlwc2UuamZhY2UuYWN0aW9uLklNZW51TGlzdGVuZXJ9IHRvIGhlbHAgZmlsbCB0aGUgY29udGV4dCBtZW51cyB3aXRoIGNvbnRyaWJ1dGlvbnMgZnJvbSB0aGUgRWRpdCBtZW51Lg0KCSAqIDwhLS0gYmVnaW4tdXNlci1kb2MgLS0+DQoJICogPCEtLSBlbmQtdXNlci1kb2MgLS0+DQoJICogQGdlbmVyYXRlZA0KCSAqLw0KCXB1YmxpYyB2b2lkIG1lbnVBYm91dFRvU2hvdyhJTWVudU1hbmFnZXIgbWVudU1hbmFnZXIpIHsNCgkJKChJTWVudUxpc3RlbmVyKWdldEVkaXRvclNpdGUoKS5nZXRBY3Rpb25CYXJDb250cmlidXRvcigpKS5tZW51QWJvdXRUb1Nob3cobWVudU1hbmFnZXIpOw0KCX0NCg0KCS8qKg0KCSAqIDwhLS0gYmVnaW4tdXNlci1kb2MgLS0+DQoJICogPCEtLSBlbmQtdXNlci1kb2MgLS0+DQoJICogQGdlbmVyYXRlZA0KCSAqLw0KCXB1YmxpYyBFZGl0aW5nRG9tYWluQWN0aW9uQmFyQ29udHJpYnV0b3IgZ2V0QWN0aW9uQmFyQ29udHJpYnV0b3IoKSB7DQoJCXJldHVybiAoRWRpdGluZ0RvbWFpbkFjdGlvbkJhckNvbnRyaWJ1dG9yKWdldEVkaXRvclNpdGUoKS5nZXRBY3Rpb25CYXJDb250cmlidXRvcigpOw0KCX0NCg0KCS8qKg0KCSAqIDwhLS0gYmVnaW4tdXNlci1kb2MgLS0+DQoJICogPCEtLSBlbmQtdXNlci1kb2MgLS0+DQoJICogQGdlbmVyYXRlZA0KCSAqLw0KCXB1YmxpYyBJQWN0aW9uQmFycyBnZXRBY3Rpb25CYXJzKCkgew0KCQlyZXR1cm4gZ2V0QWN0aW9uQmFyQ29udHJpYnV0b3IoKS5nZXRBY3Rpb25CYXJzKCk7DQoJfQ0KDQoJLyoqDQoJICogPCEtLSBiZWdpbi11c2VyLWRvYyAtLT4NCgkgKiA8IS0tIGVuZC11c2VyLWRvYyAtLT4NCgkgKiBAZ2VuZXJhdGVkDQoJICovDQoJcHVibGljIEFkYXB0ZXJGYWN0b3J5IGdldEFkYXB0ZXJGYWN0b3J5KCkgew0KCQlyZXR1cm4gYWRhcHRlckZhY3Rvcnk7DQoJfQ0KDQoJLyoqDQoJICogPCEtLSBiZWdpbi11c2VyLWRvYyAtLT4NCgkgKiA8IS0tIGVuZC11c2VyLWRvYyAtLT4NCgkgKiBAZ2VuZXJhdGVkDQoJICovDQoJQE92ZXJyaWRlDQoJcHVibGljIHZvaWQgZGlzcG9zZSgpIHsNCgkJdXBkYXRlUHJvYmxlbUluZGljYXRpb24gPSBmYWxzZTsNCg0KCQlSZXNvdXJjZXNQbHVnaW4uZ2V0V29ya3NwYWNlKCkucmVtb3ZlUmVzb3VyY2VDaGFuZ2VMaXN0ZW5lcihyZXNvdXJjZUNoYW5nZUxpc3RlbmVyKTsNCg0KCQlnZXRTaXRlKCkuZ2V0UGFnZSgpLnJlbW92ZVBhcnRMaXN0ZW5lcihwYXJ0TGlzdGVuZXIpOw0KDQoJCWFkYXB0ZXJGYWN0b3J5LmRpc3Bvc2UoKTsNCg0KCQlpZiAoZ2V0QWN0aW9uQmFyQ29udHJpYnV0b3IoKS5nZXRBY3RpdmVFZGl0b3IoKSA9PSB0aGlzKSB7DQoJCQlnZXRBY3Rpb25CYXJDb250cmlidXRvcigpLnNldEFjdGl2ZUVkaXRvcihudWxsKTsNCgkJfQ0KDQoJCWZvciAoUHJvcGVydHlTaGVldFBhZ2UgcHJvcGVydHlTaGVldFBhZ2UgOiBwcm9wZXJ0eVNoZWV0UGFnZXMpIHsNCgkJCXByb3BlcnR5U2hlZXRQYWdlLmRpc3Bvc2UoKTsNCgkJfQ0KDQoJCWlmIChjb250ZW50T3V0bGluZVBhZ2UgIT0gbnVsbCkgew0KCQkJY29udGVudE91dGxpbmVQYWdlLmRpc3Bvc2UoKTsNCgkJfQ0KDQoJCXN1cGVyLmRpc3Bvc2UoKTsNCgl9DQoNCgkvKioNCgkgKiBSZXR1cm5zIHdoZXRoZXIgdGhlIG91dGxpbmUgdmlldyBzaG91bGQgYmUgcHJlc2VudGVkIHRvIHRoZSB1c2VyLg0KCSAqIDwhLS0gYmVnaW4tdXNlci1kb2MgLS0+DQoJICogPCEtLSBlbmQtdXNlci1kb2MgLS0+DQoJICogQGdlbmVyYXRlZA0KCSAqLw0KCXByb3RlY3RlZCBib29sZWFuIHNob3dPdXRsaW5lVmlldygpIHsNCgkJcmV0dXJuIHRydWU7DQoJfQ0KDQoJQE92ZXJyaWRlDQoJcHVibGljIFN0cmluZyBnZXRDb250cmlidXRvcklkKCkgew0KCQkvLyBTdGFydCBNQ1ANCgkJcmV0dXJuIEFSR19QUk9QRVJUSUVTOw0KCQkvLyBFbmQgTUNQCQkNCgl9DQp9DQo=