cGFja2FnZSBvcmcuZWNsaXBzZS51aS5pbnRlcm5hbC5kaWFsb2dzOwoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKQ29weXJpZ2h0IChjKSAyMDAwLCAyMDAyIElCTSBDb3JwLiBhbmQgb3RoZXJzLgpBbGwgcmlnaHRzIHJlc2VydmVkLiCgIFRoaXMgcHJvZ3JhbSBhbmQgdGhlIGFjY29tcGFueWluZyBtYXRlcmlhbHMKYXJlIG1hZGUgYXZhaWxhYmxlIHVuZGVyIHRoZSB0ZXJtcyBvZiB0aGUgQ29tbW9uIFB1YmxpYyBMaWNlbnNlIHYwLjUKd2hpY2ggYWNjb21wYW5pZXMgdGhpcyBkaXN0cmlidXRpb24sIGFuZCBpcyBhdmFpbGFibGUgYXQKaHR0cDovL3d3dy5lY2xpcHNlLm9yZy9sZWdhbC9jcGwtdjA1Lmh0bWwKoApDb250cmlidXRvcnM6CioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCgppbXBvcnQgamF2YS51dGlsLlRyZWVTZXQ7CgppbXBvcnQgb3JnLmVjbGlwc2UuY29yZS5yZXNvdXJjZXMuKjsKaW1wb3J0IG9yZy5lY2xpcHNlLmNvcmUucnVudGltZS5Db3JlRXhjZXB0aW9uOwppbXBvcnQgb3JnLmVjbGlwc2UuamZhY2UuZGlhbG9ncy5EaWFsb2c7CmltcG9ydCBvcmcuZWNsaXBzZS5qZmFjZS5wcmVmZXJlbmNlLlByZWZlcmVuY2VQYWdlOwppbXBvcnQgb3JnLmVjbGlwc2UuamZhY2Uudmlld2Vycy5JTGFiZWxQcm92aWRlcjsKaW1wb3J0IG9yZy5lY2xpcHNlLmpmYWNlLnZpZXdlcnMuTGFiZWxQcm92aWRlcjsKaW1wb3J0IG9yZy5lY2xpcHNlLnN3dC5TV1Q7CmltcG9ydCBvcmcuZWNsaXBzZS5zd3QuZXZlbnRzLio7CmltcG9ydCBvcmcuZWNsaXBzZS5zd3QuZ3JhcGhpY3MuRm9udDsKaW1wb3J0IG9yZy5lY2xpcHNlLnN3dC5sYXlvdXQuR3JpZERhdGE7CmltcG9ydCBvcmcuZWNsaXBzZS5zd3QubGF5b3V0LkdyaWRMYXlvdXQ7CmltcG9ydCBvcmcuZWNsaXBzZS5zd3Qud2lkZ2V0cy4qOwppbXBvcnQgb3JnLmVjbGlwc2UudWkuSVdvcmtiZW5jaDsKaW1wb3J0IG9yZy5lY2xpcHNlLnVpLklXb3JrYmVuY2hQcmVmZXJlbmNlUGFnZTsKaW1wb3J0IG9yZy5lY2xpcHNlLnVpLmFjdGlvbnMuR2xvYmFsQnVpbGRBY3Rpb247CmltcG9ydCBvcmcuZWNsaXBzZS51aS5kaWFsb2dzLkxpc3RTZWxlY3Rpb25EaWFsb2c7CmltcG9ydCBvcmcuZWNsaXBzZS51aS5oZWxwLldvcmtiZW5jaEhlbHA7CmltcG9ydCBvcmcuZWNsaXBzZS51aS5pbnRlcm5hbC5JSGVscENvbnRleHRJZHM7CmltcG9ydCBvcmcuZWNsaXBzZS51aS5pbnRlcm5hbC5Xb3JrYmVuY2hNZXNzYWdlczsKCi8qKgogKiBUaGUgQnVpbGRPcmRlclBhZ2UgaXMgdGhlIHBhZ2UgdGhhdCBpcyB1c2VkIHRvIGRldGVybWluZSB3aGF0IG9yZGVyIHByb2plY3RzCiAqIHdpbGwgYmUgYnVpbHQgaW4gYnkgdGhlIHdvcmtzcGFjZS4KICovCnB1YmxpYyBjbGFzcyBCdWlsZE9yZGVyUHJlZmVyZW5jZVBhZ2UKCWV4dGVuZHMgUHJlZmVyZW5jZVBhZ2UKCWltcGxlbWVudHMgSVdvcmtiZW5jaFByZWZlcmVuY2VQYWdlIHsKCQkKCXByaXZhdGUgSVdvcmtiZW5jaCB3b3JrYmVuY2g7CgkJCglwcml2YXRlIEJ1dHRvbiBkZWZhdWx0T3JkZXJCdXR0b247Cglwcml2YXRlIExhYmVsIGJ1aWxkTGFiZWw7Cglwcml2YXRlIExpc3QgYnVpbGRMaXN0OwoJcHJpdmF0ZSBDb21wb3NpdGUgYnV0dG9uQ29tcG9zaXRlOwoJcHJpdmF0ZSBMYWJlbCBub3RlTGFiZWw7CgkKCXByaXZhdGUgU3RyaW5nW10gZGVmYXVsdEJ1aWxkT3JkZXI7Cglwcml2YXRlIFN0cmluZ1tdIGN1c3RvbUJ1aWxkT3JkZXI7CgoJcHJpdmF0ZSBzdGF0aWMgU3RyaW5nIFVQX0xBQkVMID0gV29ya2JlbmNoTWVzc2FnZXMuZ2V0U3RyaW5nKCJCdWlsZE9yZGVyUHJlZmVyZW5jZS51cCIpOyAvLyROT04tTkxTLTEkCglwcml2YXRlIHN0YXRpYyBTdHJpbmcgRE9XTl9MQUJFTCA9IFdvcmtiZW5jaE1lc3NhZ2VzLmdldFN0cmluZygiQnVpbGRPcmRlclByZWZlcmVuY2UuZG93biIpOyAvLyROT04tTkxTLTEkCglwcml2YXRlIHN0YXRpYyBTdHJpbmcgQUREX0xBQkVMID0gV29ya2JlbmNoTWVzc2FnZXMuZ2V0U3RyaW5nKCJCdWlsZE9yZGVyUHJlZmVyZW5jZS5hZGQiKTsgLy8kTk9OLU5MUy0xJAoJcHJpdmF0ZSBzdGF0aWMgU3RyaW5nIFJFTU9WRV9MQUJFTCA9IFdvcmtiZW5jaE1lc3NhZ2VzLmdldFN0cmluZygiQnVpbGRPcmRlclByZWZlcmVuY2UucmVtb3ZlIik7IC8vJE5PTi1OTFMtMSQKCXByaXZhdGUgc3RhdGljIFN0cmluZyBVTlNFTEVDVEVEX1BST0pFQ1RTID0gV29ya2JlbmNoTWVzc2FnZXMuZ2V0U3RyaW5nKCJCdWlsZE9yZGVyUHJlZmVyZW5jZS5zZWxlY3RQcm9qZWN0Iik7IC8vJE5PTi1OTFMtMSQKCXByaXZhdGUgc3RhdGljIFN0cmluZyBQUk9KRUNUX1NFTEVDVElPTl9NRVNTQUdFID0gV29ya2JlbmNoTWVzc2FnZXMuZ2V0U3RyaW5nKCJCdWlsZE9yZGVyUHJlZmVyZW5jZS5zZWxlY3RPdGhlclByb2plY3RzIik7IC8vJE5PTi1OTFMtMSQKCXByaXZhdGUgc3RhdGljIFN0cmluZyBERUZBVUxUU19MQUJFTCA9IFdvcmtiZW5jaE1lc3NhZ2VzLmdldFN0cmluZygiQnVpbGRPcmRlclByZWZlcmVuY2UudXNlRGVmYXVsdHMiKTsgLy8kTk9OLU5MUy0xJAoJcHJpdmF0ZSBzdGF0aWMgU3RyaW5nIExJU1RfTEFCRUwgPSBXb3JrYmVuY2hNZXNzYWdlcy5nZXRTdHJpbmcoIkJ1aWxkT3JkZXJQcmVmZXJlbmNlLnByb2plY3RCdWlsZE9yZGVyIik7IC8vJE5PTi1OTFMtMSQKCXByaXZhdGUgc3RhdGljIFN0cmluZyBOT1RFX0xBQkVMID0gV29ya2JlbmNoTWVzc2FnZXMuZ2V0U3RyaW5nKCJCdWlsZE9yZGVyUHJlZmVyZW5jZS5ub3RlIik7IC8vJE5PTi1OTFMtMSQKCQoJLy8gbWFya3MgcHJvamVjdHMgd2l0aCB1bnNwZWNpZmllZCBidWlsZCBvcmRlcnMKCXByaXZhdGUgc3RhdGljIGZpbmFsIFN0cmluZyBNQVJLRVIgPSAiKiI7IC8vJE5PTi1OTFMtMSQKCQoJLy8gdGhlIGluZGV4IG9mIHRoZSBmaXJzdCBwcm9qZWN0IHdpdGggYW4gdW5zcGVjaWZpZWQgYnVpbGQgb3JkZXIKCS8vIHRoZSByZXN0IG9mIHRoZSBsaXN0IGNvbnNpc3RzIG9mIHByb2plY3RzIHdpdGggdW5zcGVjaWZpZWQgYnVpbGQgb3JkZXJzCglwcml2YXRlIGludCBtYXJrZWRJdGVtc1N0YXJ0SW5kZXggPSAwOwoJCgkvLyB3aGV0aGVyIG9yIG5vdCB0aGUgdXNlIGRlZmF1bHRzIG9wdGlvbiB3YXMgc2VsZWN0ZWQgd2hlbiBBcHBseSAob3IgT0spIHdhcyBsYXN0IHByZXNzZWQKCS8vIChvciB3aGVuIHRoZSBwcmVmZXJlbmNlIHBhZ2Ugd2FzIG9wZW5lZCkuIFRoaXMgcmVwcmVzZW50cyB0aGUgbW9zdCByZWNlbnQgYXBwbGllZCBzdGF0ZS4KCXByaXZhdGUgYm9vbGVhbiBkZWZhdWx0T3JkZXJJbml0aWFsbHlTZWxlY3RlZDsKCQovKioKICogQWRkIGFub3RoZXIgcHJvamVjdCB0byB0aGUgbGlzdCBhdCB0aGUgZW5kLgogKi8KcHJpdmF0ZSB2b2lkIGFkZFByb2plY3QoKSB7CgoJU3RyaW5nW10gY3VycmVudEl0ZW1zID0gdGhpcy5idWlsZExpc3QuZ2V0SXRlbXMoKTsKCglJUHJvamVjdFtdIGFsbFByb2plY3RzID0gZ2V0V29ya3NwYWNlKCkuZ2V0Um9vdCgpLmdldFByb2plY3RzKCk7CgkKCUlMYWJlbFByb3ZpZGVyIGxhYmVsUHJvdmlkZXIgPSBuZXcgTGFiZWxQcm92aWRlcigpIHsKCQlwdWJsaWMgU3RyaW5nIGdldFRleHQoT2JqZWN0IGVsZW1lbnQpIHsKCQkJcmV0dXJuIChTdHJpbmcpIGVsZW1lbnQ7CgkJfQoJfTsKCglTaW1wbGVMaXN0Q29udGVudFByb3ZpZGVyIGNvbnRlbnRzUHJvdmlkZXIgPSBuZXcgU2ltcGxlTGlzdENvbnRlbnRQcm92aWRlcigpOwoJY29udGVudHNQcm92aWRlci5zZXRFbGVtZW50cyhzb3J0ZWREaWZmZXJlbmNlKGFsbFByb2plY3RzLCBjdXJyZW50SXRlbXMpKTsKCglMaXN0U2VsZWN0aW9uRGlhbG9nIGRpYWxvZyA9CgkJbmV3IExpc3RTZWxlY3Rpb25EaWFsb2coCgkJCXRoaXMuZ2V0U2hlbGwoKSwKCQkJdGhpcywKCQkJY29udGVudHNQcm92aWRlciwKCQkJbGFiZWxQcm92aWRlciwKCQkJUFJPSkVDVF9TRUxFQ1RJT05fTUVTU0FHRSk7CgoJaWYgKGRpYWxvZy5vcGVuKCkgIT0gRGlhbG9nLk9LKQoJCXJldHVybjsKCglPYmplY3RbXSByZXN1bHQgPSBkaWFsb2cuZ2V0UmVzdWx0KCk7CgoJaW50IGN1cnJlbnRJdGVtc0xlbmd0aCA9IGN1cnJlbnRJdGVtcy5sZW5ndGg7CglpbnQgcmVzdWx0TGVuZ3RoID0gcmVzdWx0Lmxlbmd0aDsKCVN0cmluZ1tdIG5ld0l0ZW1zID0gbmV3IFN0cmluZ1tjdXJyZW50SXRlbXNMZW5ndGggKyByZXN1bHRMZW5ndGhdOwoKCVN5c3RlbS5hcnJheWNvcHkoY3VycmVudEl0ZW1zLCAwLCBuZXdJdGVtcywgMCwgY3VycmVudEl0ZW1zTGVuZ3RoKTsKCVN5c3RlbS5hcnJheWNvcHkoCgkJcmVzdWx0LAoJCTAsCgkJbmV3SXRlbXMsCgkJY3VycmVudEl0ZW1zTGVuZ3RoLAoJCXJlc3VsdC5sZW5ndGgpOwoJdGhpcy5idWlsZExpc3Quc2V0SXRlbXMobmV3SXRlbXMpOwp9Ci8qKgogKiBDcmVhdGUgdGhlIGxpc3Qgb2YgYnVpbGQgcGF0aHMuIElmIHRoZSBjdXJyZW50IGJ1aWxkIG9yZGVyIGlzIGVtcHR5IG1ha2UgdGhlIGxpc3QgZW1wdHkKICogYW5kIGRpc2FibGUgaXQuCiAqIEBwYXJhbSBjb21wb3NpdGUgLSB0aGUgcGFyZW50IHRvIGNyZWF0ZSB0aGUgbGlzdCBpbgogKiBAcGFyYW0gLSBlbmFibGVkIC0gdGhlIGJvb2xlYW4gdGhhdCBpbmRjYXRlcyBpZiB0aGUgbGlzdCB3aWxsIGJlIHNlbnNpdGl2ZSBpbml0aWFsbHkgb3Igbm90CiAqLwpwcml2YXRlIHZvaWQgY3JlYXRlQnVpbGRPcmRlckxpc3QoQ29tcG9zaXRlIGNvbXBvc2l0ZSwgYm9vbGVhbiBlbmFibGVkKSB7CgkKCUZvbnQgZm9udCA9IGNvbXBvc2l0ZS5nZXRGb250KCk7CgoJdGhpcy5idWlsZExhYmVsID0gbmV3IExhYmVsKGNvbXBvc2l0ZSwgU1dULk5PTkUpOwoJdGhpcy5idWlsZExhYmVsLnNldFRleHQoTElTVF9MQUJFTCk7Cgl0aGlzLmJ1aWxkTGFiZWwuc2V0RW5hYmxlZChlbmFibGVkKTsKCUdyaWREYXRhIGdyaWREYXRhID0gbmV3IEdyaWREYXRhKCk7CglncmlkRGF0YS5ob3Jpem9udGFsQWxpZ25tZW50ID0gR3JpZERhdGEuRklMTDsKCWdyaWREYXRhLmhvcml6b250YWxTcGFuID0gMjsKCXRoaXMuYnVpbGRMYWJlbC5zZXRMYXlvdXREYXRhKGdyaWREYXRhKTsKCXRoaXMuYnVpbGRMYWJlbC5zZXRGb250KGZvbnQpOwoJCgl0aGlzLmJ1aWxkTGlzdCA9IG5ldyBMaXN0KGNvbXBvc2l0ZSwgU1dULkJPUkRFUiB8IFNXVC5NVUxUSSB8IFNXVC5IX1NDUk9MTCB8IFNXVC5WX1NDUk9MTCk7Cgl0aGlzLmJ1aWxkTGlzdC5zZXRFbmFibGVkKGVuYWJsZWQpOwoJR3JpZERhdGEgZGF0YSA9IG5ldyBHcmlkRGF0YSgpOwoJLy9TZXQgaGVpZ2h0SGludCB3aXRoIGEgc21hbGwgdmFsdWUgc28gdGhlIGxpc3Qgc2l6ZSB3aWxsIGJlIGRlZmluZWQgYnkgCgkvL3RoZSBzcGFjZSBhdmFpbGFibGUgaW4gdGhlIGRpYWxvZyBpbnN0ZWFkIG9mIHJlc2l6aW5nIHRoZSBkaWFsb2cgdG8KCS8vZml0IGFsbCB0aGUgaXRlbXMgaW4gdGhlIGxpc3QuCglkYXRhLmhlaWdodEhpbnQgPSBidWlsZExpc3QuZ2V0SXRlbUhlaWdodCgpOwoJZGF0YS52ZXJ0aWNhbEFsaWdubWVudCA9IEdyaWREYXRhLkZJTEw7CglkYXRhLmhvcml6b250YWxBbGlnbm1lbnQgPSBHcmlkRGF0YS5GSUxMOwoJZGF0YS5ncmFiRXhjZXNzSG9yaXpvbnRhbFNwYWNlID0gdHJ1ZTsKCWRhdGEuZ3JhYkV4Y2Vzc1ZlcnRpY2FsU3BhY2UgPSB0cnVlOwoJdGhpcy5idWlsZExpc3Quc2V0TGF5b3V0RGF0YShkYXRhKTsKCXRoaXMuYnVpbGRMaXN0LnNldEZvbnQoZm9udCk7Cn0KLyoqCiAqIENyZWF0ZSB0aGUgd2lkZ2V0cyB0aGF0IGFyZSB1c2VkIHRvIGRldGVybWluZSB0aGUgYnVpbGQgb3JkZXIuCiAqCiAqIEBwYXJhbSBwYXJlbnQgdGhlIHBhcmVudCBjb21wb3NpdGUKICogQHJldHVybiB0aGUgbmV3IGNvbnRyb2wKICovCnByb3RlY3RlZCBDb250cm9sIGNyZWF0ZUNvbnRlbnRzKENvbXBvc2l0ZSBwYXJlbnQpIHsKCglXb3JrYmVuY2hIZWxwLnNldEhlbHAocGFyZW50LCBJSGVscENvbnRleHRJZHMuQlVJTERfT1JERVJfUFJFRkVSRU5DRV9QQUdFKTsKCQoJRm9udCBmb250ID0gcGFyZW50LmdldEZvbnQoKTsKCgkvL1RoZSBtYWluIGNvbXBvc2l0ZQoJQ29tcG9zaXRlIGNvbXBvc2l0ZSA9IG5ldyBDb21wb3NpdGUocGFyZW50LCBTV1QuTlVMTCk7CglHcmlkTGF5b3V0IGxheW91dCA9IG5ldyBHcmlkTGF5b3V0KCk7CglsYXlvdXQubnVtQ29sdW1ucyA9IDI7CglsYXlvdXQubWFyZ2luV2lkdGggPSAwOwoJbGF5b3V0Lm1hcmdpbkhlaWdodCA9IDA7Cgljb21wb3NpdGUuc2V0TGF5b3V0KGxheW91dCk7CglHcmlkRGF0YSBkYXRhID0gbmV3IEdyaWREYXRhKCk7CglkYXRhLnZlcnRpY2FsQWxpZ25tZW50ID0gR3JpZERhdGEuRklMTDsKCWRhdGEuaG9yaXpvbnRhbEFsaWdubWVudCA9IEdyaWREYXRhLkZJTEw7Cgljb21wb3NpdGUuc2V0TGF5b3V0RGF0YShkYXRhKTsKCWNvbXBvc2l0ZS5zZXRGb250KGZvbnQpOwoKCVN0cmluZ1tdIGJ1aWxkT3JkZXIgPSBnZXRDdXJyZW50QnVpbGRPcmRlcigpOwoJYm9vbGVhbiB1c2VEZWZhdWx0ID0gKGJ1aWxkT3JkZXIubGVuZ3RoIDwgMSk7CgkKCWNyZWF0ZURlZmF1bHRQYXRoQnV0dG9uKGNvbXBvc2l0ZSwgdXNlRGVmYXVsdCk7CgkvLyBMaXN0IGFsd2F5cyBlbmFibGVkIHNvIHVzZXIgY2FuIHNjcm9sbCBsaXN0LgoJLy8gT25seSB0aGUgYnV0dG9uIG5lZWQgdG8gYmUgZGlzYWJsZWQuCgljcmVhdGVCdWlsZE9yZGVyTGlzdChjb21wb3NpdGUsIHRydWUpOwoJY3JlYXRlTGlzdEJ1dHRvbnMoY29tcG9zaXRlLCAhdXNlRGVmYXVsdCk7CgkKCS8vIGEgbm90ZSBhYm91dCBwcm9qZWN0cyB3aXRoIHVuc3BlY2lmaWVkIGJ1aWxkIG9yZGVycwoJbm90ZUxhYmVsID0gbmV3IExhYmVsKGNvbXBvc2l0ZSwgU1dULk5PTkUpOwoJbm90ZUxhYmVsLnNldFRleHQoTk9URV9MQUJFTCk7Cglub3RlTGFiZWwuc2V0Rm9udChmb250KTsKCgoJaWYgKHVzZURlZmF1bHQpIHsKCQl0aGlzLmJ1aWxkTGlzdC5zZXRJdGVtcyhnZXREZWZhdWx0UHJvamVjdE9yZGVyKCkpOwoJCS8vIGlmIHRoZXJlIGFyZSBubyBtYXJrZWQgaXRlbXMsIGRvIG5vdCBzaG93IHRoZSBub3RlCgkJaWYobWFya2VkSXRlbXNTdGFydEluZGV4ID49IGJ1aWxkTGlzdC5nZXRJdGVtQ291bnQoKSkKCQkJbm90ZUxhYmVsLnNldFZpc2libGUoZmFsc2UpOwoJfSBlbHNlIHsKCQl0aGlzLmJ1aWxkTGlzdC5zZXRJdGVtcyhidWlsZE9yZGVyKTsKCQkvLyB3aGVuIG5vdCB1c2luZyBkZWZhdWx0IGJ1aWxkIG9yZGVyLCBkbyBub3Qgc2hvdyB0aGUgbm90ZQoJCW5vdGVMYWJlbC5zZXRWaXNpYmxlKGZhbHNlKTsKCX0KCQoJcmV0dXJuIGNvbXBvc2l0ZTsKCn0KLyoqCiAqIENyZWF0ZSB0aGUgZGVmYXVsdCBwYXRoIGJ1dHRvbi4gU2V0IGl0IHRvIHNlbGVjdGVkIGJhc2VkIG9uIHRoZSBjdXJyZW50IHdvcmtzcGFjZQogKiBidWlsZCBwYXRoLgogKiBAcGFyYW0gY29tcG9zaXRlIG9yZy5lY2xpcHNlLnN3dC53aWRnZXRzLkNvbXBvc2l0ZQogKiBAcGFyYW0gc2VsZWN0ZWQgLSB0aGUgYm9vbGVhbiB0aGF0IGluZGljYXRlcyB0aGUgYnV0dG9ucyBpbml0aWFsIHN0YXRlCiAqLwpwcml2YXRlIHZvaWQgY3JlYXRlRGVmYXVsdFBhdGhCdXR0b24oQ29tcG9zaXRlIGNvbXBvc2l0ZSwgYm9vbGVhbiBzZWxlY3RlZCkgewoKCWRlZmF1bHRPcmRlckluaXRpYWxseVNlbGVjdGVkID0gc2VsZWN0ZWQ7CgoJdGhpcy5kZWZhdWx0T3JkZXJCdXR0b24gPSBuZXcgQnV0dG9uKGNvbXBvc2l0ZSwgU1dULkxFRlQgfCBTV1QuQ0hFQ0spOwoJdGhpcy5kZWZhdWx0T3JkZXJCdXR0b24uc2V0U2VsZWN0aW9uKHNlbGVjdGVkKTsKCXRoaXMuZGVmYXVsdE9yZGVyQnV0dG9uLnNldFRleHQoREVGQVVMVFNfTEFCRUwpOwoJU2VsZWN0aW9uTGlzdGVuZXIgbGlzdGVuZXIgPSBuZXcgU2VsZWN0aW9uQWRhcHRlcigpIHsKCQlwdWJsaWMgdm9pZCB3aWRnZXRTZWxlY3RlZChTZWxlY3Rpb25FdmVudCBlKSB7CgkJCWRlZmF1bHRzQnV0dG9uU2VsZWN0ZWQoZGVmYXVsdE9yZGVyQnV0dG9uLmdldFNlbGVjdGlvbigpKTsKCQl9Cgl9OwoJdGhpcy5kZWZhdWx0T3JkZXJCdXR0b24uYWRkU2VsZWN0aW9uTGlzdGVuZXIobGlzdGVuZXIpOwoKCUdyaWREYXRhIGdyaWREYXRhID0gbmV3IEdyaWREYXRhKCk7CglncmlkRGF0YS5ob3Jpem9udGFsQWxpZ25tZW50ID0gR3JpZERhdGEuRklMTDsKCWdyaWREYXRhLmhvcml6b250YWxTcGFuID0gMjsKCXRoaXMuZGVmYXVsdE9yZGVyQnV0dG9uLnNldExheW91dERhdGEoZ3JpZERhdGEpOwoJdGhpcy5kZWZhdWx0T3JkZXJCdXR0b24uc2V0Rm9udChjb21wb3NpdGUuZ2V0Rm9udCgpKTsKfQovKioKICogQ3JlYXRlIHRoZSBidXR0b25zIHVzZWQgdG8gbWFuaXB1bGF0ZSB0aGUgbGlzdC4gVGhlc2UgQWRkLCBSZW1vdmUgYW5kIE1vdmUgVXAgb3IgRG93bgogKiB0aGUgbGlzdCBpdGVtcy4KICogQHBhcmFtIGNvbXBvc2l0ZSB0aGUgcGFyZW50IG9mIHRoZSBidXR0b25zCiAqIEBwYXJhbSBlbmFibGVDb21wb3NpdGUgLSBib29sZWFuIHRoYXQgaW5kaWNhdGVzIGlmIGEgY29tcG9zaXRlIHNob3VsZCBiZSBlbmFibGVkCiAqLwpwcml2YXRlIHZvaWQgY3JlYXRlTGlzdEJ1dHRvbnMoQ29tcG9zaXRlIGNvbXBvc2l0ZSwgYm9vbGVhbiBlbmFibGVDb21wb3NpdGUpIHsKCQoJRm9udCBmb250ID0gY29tcG9zaXRlLmdldEZvbnQoKTsKCgkvL0NyZWF0ZSBhbiBpbnRlcm1lZGl0YXRlIGNvbXBvc2l0ZSB0byBrZWVwIHRoZSBidXR0b25zIGluIHRoZSBzYW1lIGNvbHVtbgoJdGhpcy5idXR0b25Db21wb3NpdGUgPSBuZXcgQ29tcG9zaXRlKGNvbXBvc2l0ZSwgU1dULlJJR0hUKTsKCUdyaWRMYXlvdXQgbGF5b3V0ID0gbmV3IEdyaWRMYXlvdXQoKTsKCWxheW91dC5tYXJnaW5XaWR0aCA9IDA7CglsYXlvdXQubWFyZ2luSGVpZ2h0ID0gMDsKCXRoaXMuYnV0dG9uQ29tcG9zaXRlLnNldExheW91dChsYXlvdXQpOwoJR3JpZERhdGEgZ3JpZERhdGEgPSBuZXcgR3JpZERhdGEoKTsKCWdyaWREYXRhLnZlcnRpY2FsQWxpZ25tZW50ID0gR3JpZERhdGEuRklMTDsKCWdyaWREYXRhLmhvcml6b250YWxBbGlnbm1lbnQgPSBHcmlkRGF0YS5GSUxMOwoJdGhpcy5idXR0b25Db21wb3NpdGUuc2V0TGF5b3V0RGF0YShncmlkRGF0YSk7Cgl0aGlzLmJ1dHRvbkNvbXBvc2l0ZS5zZXRGb250KGZvbnQpOwoKCUJ1dHRvbiB1cEJ1dHRvbiA9IG5ldyBCdXR0b24odGhpcy5idXR0b25Db21wb3NpdGUsIFNXVC5DRU5URVIgfCBTV1QuUFVTSCk7Cgl1cEJ1dHRvbi5zZXRUZXh0KFVQX0xBQkVMKTsKCXVwQnV0dG9uLnNldEVuYWJsZWQoZW5hYmxlQ29tcG9zaXRlKTsKCXVwQnV0dG9uLnNldEZvbnQoZm9udCk7CglzZXRCdXR0b25MYXlvdXREYXRhKHVwQnV0dG9uKTsKCQoJU2VsZWN0aW9uTGlzdGVuZXIgbGlzdGVuZXIgPSBuZXcgU2VsZWN0aW9uQWRhcHRlcigpIHsKCQlwdWJsaWMgdm9pZCB3aWRnZXRTZWxlY3RlZChTZWxlY3Rpb25FdmVudCBlKSB7CgkJCW1vdmVTZWxlY3Rpb25VcCgpOwoJCX0KCX07Cgl1cEJ1dHRvbi5hZGRTZWxlY3Rpb25MaXN0ZW5lcihsaXN0ZW5lcik7CgoJQnV0dG9uIGRvd25CdXR0b24gPSBuZXcgQnV0dG9uKHRoaXMuYnV0dG9uQ29tcG9zaXRlLCBTV1QuQ0VOVEVSIHwgU1dULlBVU0gpOwoJZG93bkJ1dHRvbi5zZXRUZXh0KERPV05fTEFCRUwpOwoJZG93bkJ1dHRvbi5zZXRFbmFibGVkKGVuYWJsZUNvbXBvc2l0ZSk7CglsaXN0ZW5lciA9IG5ldyBTZWxlY3Rpb25BZGFwdGVyKCkgewoJCXB1YmxpYyB2b2lkIHdpZGdldFNlbGVjdGVkKFNlbGVjdGlvbkV2ZW50IGUpIHsKCQkJbW92ZVNlbGVjdGlvbkRvd24oKTsKCQl9Cgl9OwoJZG93bkJ1dHRvbi5hZGRTZWxlY3Rpb25MaXN0ZW5lcihsaXN0ZW5lcik7Cglkb3duQnV0dG9uLnNldEZvbnQoZm9udCk7CglzZXRCdXR0b25MYXlvdXREYXRhKGRvd25CdXR0b24pOwoKCUJ1dHRvbiBhZGRCdXR0b24gPSBuZXcgQnV0dG9uKHRoaXMuYnV0dG9uQ29tcG9zaXRlLCBTV1QuQ0VOVEVSIHwgU1dULlBVU0gpOwoJYWRkQnV0dG9uLnNldFRleHQoQUREX0xBQkVMKTsKCWxpc3RlbmVyID0gbmV3IFNlbGVjdGlvbkFkYXB0ZXIoKSB7CgkJcHVibGljIHZvaWQgd2lkZ2V0U2VsZWN0ZWQoU2VsZWN0aW9uRXZlbnQgZSkgewoJCQlhZGRQcm9qZWN0KCk7CgkJfQoJfTsKCWFkZEJ1dHRvbi5hZGRTZWxlY3Rpb25MaXN0ZW5lcihsaXN0ZW5lcik7CglhZGRCdXR0b24uc2V0RW5hYmxlZChlbmFibGVDb21wb3NpdGUpOwoJYWRkQnV0dG9uLnNldEZvbnQoZm9udCk7CglzZXRCdXR0b25MYXlvdXREYXRhKGFkZEJ1dHRvbik7CgoJQnV0dG9uIHJlbW92ZUJ1dHRvbiA9IG5ldyBCdXR0b24odGhpcy5idXR0b25Db21wb3NpdGUsIFNXVC5DRU5URVIgfCBTV1QuUFVTSCk7CglyZW1vdmVCdXR0b24uc2V0VGV4dChSRU1PVkVfTEFCRUwpOwoJbGlzdGVuZXIgPSBuZXcgU2VsZWN0aW9uQWRhcHRlcigpIHsKCQlwdWJsaWMgdm9pZCB3aWRnZXRTZWxlY3RlZChTZWxlY3Rpb25FdmVudCBlKSB7CgkJCXJlbW92ZVNlbGVjdGlvbigpOwoJCX0KCX07CglyZW1vdmVCdXR0b24uYWRkU2VsZWN0aW9uTGlzdGVuZXIobGlzdGVuZXIpOwoJcmVtb3ZlQnV0dG9uLnNldEVuYWJsZWQoZW5hYmxlQ29tcG9zaXRlKTsKCXJlbW92ZUJ1dHRvbi5zZXRGb250KGZvbnQpOwoJc2V0QnV0dG9uTGF5b3V0RGF0YShyZW1vdmVCdXR0b24pOwoKfQovKioKICogVGhlIGRlZmF1bHRzIGJ1dHRvbiBoYXMgYmVlbiBzZWxlY3RlZCAtIHVwZGF0ZSB0aGUgb3RoZXIgd2lkZ2V0cyBhcyByZXF1aXJlZC4KICogQHBhcmFtIHNlbGVjdGVkIC0gd2hldGhlciBvciBub3QgdGhlIGRlZmF1bHRzIGJ1dHRvbiBnb3Qgc2VsZWN0ZWQKICovCnByaXZhdGUgdm9pZCBkZWZhdWx0c0J1dHRvblNlbGVjdGVkKGJvb2xlYW4gc2VsZWN0ZWQpIHsKCWlmIChzZWxlY3RlZCkgewoJCXNldEJ1aWxkT3JkZXJXaWRnZXRzRW5hYmxlbWVudChmYWxzZSk7CgkJYnVpbGRMaXN0LnNldEl0ZW1zKGdldERlZmF1bHRQcm9qZWN0T3JkZXIoKSk7CgkJLy8gaWYgdGhlcmUgYXJlIG1hcmtlZCBpdGVtcywgbWFrZSB0aGUgbm90ZSB2aXNpYmxlCgkJaWYobWFya2VkSXRlbXNTdGFydEluZGV4IDwgYnVpbGRMaXN0LmdldEl0ZW1Db3VudCgpKQoJCQlub3RlTGFiZWwuc2V0VmlzaWJsZSh0cnVlKTsKCX0KCWVsc2UgewoJCXNldEJ1aWxkT3JkZXJXaWRnZXRzRW5hYmxlbWVudCh0cnVlKTsKCQlTdHJpbmdbXSBidWlsZE9yZGVyID0gZ2V0Q3VycmVudEJ1aWxkT3JkZXIoKTsKCQlpZiAoYnVpbGRPcmRlci5sZW5ndGggPCAxKSB7CgkJCS8vIEdldCBhIGNvcHkgb2YgdGhlIGRlZmF1bHQgb3JkZXIgYW5kIHJlbW92ZSBtYXJrZXJzCgkJCVN0cmluZ1tdIG5hbWVzID0gZ2V0RGVmYXVsdFByb2plY3RPcmRlcigpOwoJCQlTdHJpbmdbXSBjb3B5ID0gbmV3IFN0cmluZ1tuYW1lcy5sZW5ndGhdOwoJCQlTeXN0ZW0uYXJyYXljb3B5KG5hbWVzLCAwLCBjb3B5LCAwLCBuYW1lcy5sZW5ndGgpOwoJCQlmb3IgKGludCBpID0gbWFya2VkSXRlbXNTdGFydEluZGV4OyBpIDwgY29weS5sZW5ndGg7IGkrKykKCQkJCWNvcHlbaV0gPSBuYW1lc1tpXS5zdWJzdHJpbmcoMSk7CgkJCWJ1aWxkTGlzdC5zZXRJdGVtcyhjb3B5KTsKCQl9IGVsc2UgewoJCQlidWlsZExpc3Quc2V0SXRlbXMoYnVpbGRPcmRlcik7CgkJfQoJCS8vIG1ha2UgdGhlIG5vdGUgaW52aXNpYmxlCgkJbm90ZUxhYmVsLnNldFZpc2libGUoZmFsc2UpOwoJfQp9Ci8qKgogKiBHZXQgdGhlIHByb2plY3QgbmFtZXMgZm9yIHRoZSBjdXJyZW50IGN1c3RvbSBidWlsZAogKiBvcmRlciBzdG9yZWQgaW4gdGhlIHdvcmtzcGFjZSBkZXNjcmlwdGlvbi4KICogCiAqIEByZXR1cm4gamF2YS5sYW5nLlN0cmluZ1tdCiAqLwpwcml2YXRlIFN0cmluZ1tdIGdldEN1cnJlbnRCdWlsZE9yZGVyKCkgewoJaWYgKGN1c3RvbUJ1aWxkT3JkZXIgPT0gbnVsbCkgewoJCWN1c3RvbUJ1aWxkT3JkZXIgPSBnZXRXb3Jrc3BhY2UoKS5nZXREZXNjcmlwdGlvbigpLmdldEJ1aWxkT3JkZXIoKTsKCQlpZiAoY3VzdG9tQnVpbGRPcmRlciA9PSBudWxsKQoJCQljdXN0b21CdWlsZE9yZGVyID0gbmV3IFN0cmluZ1swXTsKCX0KCQoJcmV0dXJuIGN1c3RvbUJ1aWxkT3JkZXI7Cn0KLyoqCiAqIEdldCB0aGUgcHJvamVjdCBuYW1lcyBpbiB0aGUgZGVmYXVsdCBidWlsZCBvcmRlcgogKiBiYXNlZCBvbiB0aGUgY3VycmVudCBXb3Jrc3BhY2Ugc2V0dGluZ3MuCiAqIAogKiBAcmV0dXJuIGphdmEubGFuZy5TdHJpbmdbXQogKi8KcHJpdmF0ZSBTdHJpbmdbXSBnZXREZWZhdWx0UHJvamVjdE9yZGVyKCkgewoJaWYgKGRlZmF1bHRCdWlsZE9yZGVyID09IG51bGwpIHsKCQlJV29ya3NwYWNlIHdvcmtzcGFjZSA9IGdldFdvcmtzcGFjZSgpOwoJCUlQcm9qZWN0W11bXSBwcm9qZWN0T3JkZXIgPQoJCQlnZXRXb3Jrc3BhY2UoKS5jb21wdXRlUHJlcmVxdWlzaXRlT3JkZXIod29ya3NwYWNlLmdldFJvb3QoKS5nZXRQcm9qZWN0cygpKTsKCgkJSVByb2plY3RbXSBmb3VuZFByb2plY3RzID0gcHJvamVjdE9yZGVyWzBdOwoJCUlQcm9qZWN0W10gYW1iaWd1b3VzUHJvamVjdHMgPSBwcm9qZWN0T3JkZXJbMV07CgoJCWRlZmF1bHRCdWlsZE9yZGVyID0KCQkJbmV3IFN0cmluZ1tmb3VuZFByb2plY3RzLmxlbmd0aCArIGFtYmlndW91c1Byb2plY3RzLmxlbmd0aF07CgkJaW50IGZvdW5kU2l6ZSA9IGZvdW5kUHJvamVjdHMubGVuZ3RoOwoJCWZvciAoaW50IGkgPSAwOyBpIDwgZm91bmRTaXplOyBpKyspCgkJCWRlZmF1bHRCdWlsZE9yZGVyW2ldID0gZm91bmRQcm9qZWN0c1tpXS5nZXROYW1lKCk7CgkJbWFya2VkSXRlbXNTdGFydEluZGV4ID0gZm91bmRTaXplOwoJCWZvciAoaW50IGkgPSAwOyBpIDwgYW1iaWd1b3VzUHJvamVjdHMubGVuZ3RoOyBpKyspCgkJCWRlZmF1bHRCdWlsZE9yZGVyW2kgKyBmb3VuZFNpemVdID0gTUFSS0VSICsgYW1iaWd1b3VzUHJvamVjdHNbaV0uZ2V0TmFtZSgpOwoJfQoJCglyZXR1cm4gZGVmYXVsdEJ1aWxkT3JkZXI7Cn0KLyoqCiAqIFJldHVybiB0aGUgV29ya3NwYWNlIHRoZSBidWlsZCBvcmRlciBpcyBmcm9tLgogKiBAcmV0dXJuIG9yZy5lY2xpcHNlLmNvcmUucmVzb3VyY2VzLklXb3Jrc3BhY2UKICovCnByaXZhdGUgSVdvcmtzcGFjZSBnZXRXb3Jrc3BhY2UoKSB7CglyZXR1cm4gUmVzb3VyY2VzUGx1Z2luLmdldFdvcmtzcGFjZSgpOwp9Ci8qKgogKiBSZXR1cm4gd2hldGhlciBvciBub3Qgc2VhcmNoRWxlbWVudCBpcyBpbiB0ZXN0QXJyYXkuCiAqLwpwcml2YXRlIGJvb2xlYW4gaW5jbHVkZXMoU3RyaW5nW10gdGVzdEFycmF5LCBTdHJpbmcgc2VhcmNoRWxlbWVudCkgewoKCWZvciAoaW50IGkgPSAwOyBpIDwgdGVzdEFycmF5Lmxlbmd0aDsgaSsrKSB7CgkJaWYgKHNlYXJjaEVsZW1lbnQuZXF1YWxzKHRlc3RBcnJheVtpXSkpCgkJCXJldHVybiB0cnVlOwoJfQoJcmV0dXJuIGZhbHNlOwoKfQovKioKICogU2VlIElXb3JrYmVuY2hQcmVmZXJlbmNlUGFnZS4gVGhpcyBjbGFzcyBkb2VzIG5vdGhpbmcgd2l0aCBoZSBXb3JrYmVuY2guCiAqLwpwdWJsaWMgdm9pZCBpbml0KElXb3JrYmVuY2ggd29ya2JlbmNoKSB7Cgl0aGlzLndvcmtiZW5jaCA9IHdvcmtiZW5jaDsKfQovKioKICogTW92ZSB0aGUgY3VycmVudCBzZWxlY3Rpb24gaW4gdGhlIGJ1aWxkIGxpc3QgZG93bi4KICovCnByaXZhdGUgdm9pZCBtb3ZlU2VsZWN0aW9uRG93bigpIHsKCgkvL09ubHkgZG8gdGhpcyBvcGVyYXRpb24gb24gYSBzaW5nbGUgc2VsZWN0aW9uCglpZiAodGhpcy5idWlsZExpc3QuZ2V0U2VsZWN0aW9uQ291bnQoKSA9PSAxKSB7CgkJaW50IGN1cnJlbnRJbmRleCA9IHRoaXMuYnVpbGRMaXN0LmdldFNlbGVjdGlvbkluZGV4KCk7CgkJaWYgKGN1cnJlbnRJbmRleCA8IHRoaXMuYnVpbGRMaXN0LmdldEl0ZW1Db3VudCgpIC0gMSkgewoJCQlTdHJpbmcgZWxlbWVudFRvTW92ZSA9IHRoaXMuYnVpbGRMaXN0LmdldEl0ZW0oY3VycmVudEluZGV4KTsKCQkJdGhpcy5idWlsZExpc3QucmVtb3ZlKGN1cnJlbnRJbmRleCk7CgkJCXRoaXMuYnVpbGRMaXN0LmFkZChlbGVtZW50VG9Nb3ZlLCBjdXJyZW50SW5kZXggKyAxKTsKCQkJdGhpcy5idWlsZExpc3Quc2VsZWN0KGN1cnJlbnRJbmRleCArIDEpOwoJCX0KCX0KfQovKioKICogTW92ZSB0aGUgY3VycmVudCBzZWxlY3Rpb24gaW4gdGhlIGJ1aWxkIGxpc3QgdXAuCiAqLwpwcml2YXRlIHZvaWQgbW92ZVNlbGVjdGlvblVwKCkgewoKCWludCBjdXJyZW50SW5kZXggPSB0aGlzLmJ1aWxkTGlzdC5nZXRTZWxlY3Rpb25JbmRleCgpOwoKCS8vT25seSBkbyB0aGlzIG9wZXJhdGlvbiBvbiBhIHNpbmdsZSBzZWxlY3Rpb24KCWlmIChjdXJyZW50SW5kZXggPiAwICYmIHRoaXMuYnVpbGRMaXN0LmdldFNlbGVjdGlvbkNvdW50KCkgPT0gMSkgewoJCVN0cmluZyBlbGVtZW50VG9Nb3ZlID0gdGhpcy5idWlsZExpc3QuZ2V0SXRlbShjdXJyZW50SW5kZXgpOwoJCXRoaXMuYnVpbGRMaXN0LnJlbW92ZShjdXJyZW50SW5kZXgpOwoJCXRoaXMuYnVpbGRMaXN0LmFkZChlbGVtZW50VG9Nb3ZlLCBjdXJyZW50SW5kZXggLSAxKTsKCQl0aGlzLmJ1aWxkTGlzdC5zZWxlY3QoY3VycmVudEluZGV4IC0gMSk7Cgl9Cn0KLyoqCiAqIFBlcmZvcm1zIHNwZWNpYWwgcHJvY2Vzc2luZyB3aGVuIHRoaXMgcGFnZSdzIERlZmF1bHRzIGJ1dHRvbiBoYXMgYmVlbiBwcmVzc2VkLgogKiBJbiB0aGlzIGNhc2UgY2hhbmdlIHRoZSBkZWZhdWx0T3JkZXJCdXR0b24gdG8gaGF2ZSBpdCdzIHNlbGVjdGlvbiBzZXQgdG8gdHJ1ZS4KICovCnByb3RlY3RlZCB2b2lkIHBlcmZvcm1EZWZhdWx0cygpIHsKCXRoaXMuZGVmYXVsdE9yZGVyQnV0dG9uLnNldFNlbGVjdGlvbih0cnVlKTsKCWRlZmF1bHRzQnV0dG9uU2VsZWN0ZWQodHJ1ZSk7CglzdXBlci5wZXJmb3JtRGVmYXVsdHMoKTsKfQovKiogCiAqIE9LIGhhcyBiZWVuIHByZXNzZWQuIElmIHRoZSBkZWZ1YWx0IGJ1dHRvbiBpcyBwcmVzc2VkIHRoZW4gcmVzZXQgdGhlIGJ1aWxkIG9yZGVyIHRvIGZhbHNlOwogKiBvdGhlcndpc2Ugc2V0IGl0IHRvIHRoZSBjb250ZW50cyBvZiB0aGUgbGlzdC4KICovCnB1YmxpYyBib29sZWFuIHBlcmZvcm1PaygpIHsKCglTdHJpbmdbXSBidWlsZE9yZGVyID0gbnVsbDsKCWJvb2xlYW4gdXNlRGVmYXVsdCA9IGRlZmF1bHRPcmRlckJ1dHRvbi5nZXRTZWxlY3Rpb24oKTsKCgkvLyBpZiB1c2UgZGVmYXVsdHMgaXMgdHVybmVkIG9mZgoJaWYgKCF1c2VEZWZhdWx0KQoJCWJ1aWxkT3JkZXIgPSBidWlsZExpc3QuZ2V0SXRlbXMoKTsKCgkvL0dldCBhIGNvcHkgb2YgdGhlIGRlc2NyaXB0aW9uIGZyb20gdGhlIHdvcmtzcGFjZSwgc2V0IHRoZSBidWlsZCBvcmRlciBhbmQgdGhlbgoJLy9hcHBseSBpdCB0byB0aGUgd29ya3NwYWNlLgoJSVdvcmtzcGFjZURlc2NyaXB0aW9uIGRlc2NyaXB0aW9uID0gZ2V0V29ya3NwYWNlKCkuZ2V0RGVzY3JpcHRpb24oKTsKCWRlc2NyaXB0aW9uLnNldEJ1aWxkT3JkZXIoYnVpbGRPcmRlcik7Cgl0cnkgewoJCWdldFdvcmtzcGFjZSgpLnNldERlc2NyaXB0aW9uKGRlc2NyaXB0aW9uKTsKCX0gY2F0Y2ggKENvcmVFeGNlcHRpb24gZXhjZXB0aW9uKSB7CgkJLy9mYWlsZWQgLSByZXR1cm4gZmFsc2UKCQlyZXR1cm4gZmFsc2U7Cgl9CgkKCS8vIFBlcmZvcm0gYXV0by1idWlsZCBpZiB1c2UgZGVmYXVsdCBpcyBvZmYgKGJlY2F1c2UKCS8vIG9yZGVyIGNvdWxkIGhhdmUgY2hhbmdlZCkgb3IgaWYgdXNlIGRlZmF1bHQgc2V0dGluZwoJLy8gd2FzIGNoYW5nZWQuCglpZiAoIXVzZURlZmF1bHQgfHwgKHVzZURlZmF1bHQgIT0gZGVmYXVsdE9yZGVySW5pdGlhbGx5U2VsZWN0ZWQpKSB7CgkJZGVmYXVsdE9yZGVySW5pdGlhbGx5U2VsZWN0ZWQgPSB1c2VEZWZhdWx0OwoJCS8vIElmIGF1dG8gYnVpbGQgaXMgdHVybmVkIG9uLCB0aGVuIGRvIGEgZ2xvYmFsIGluY3JlbWVudGFsCgkJLy8gYnVpbGQgb24gYWxsIHRoZSBwcm9qZWN0cy4KCQlpZiAoUmVzb3VyY2VzUGx1Z2luLmdldFdvcmtzcGFjZSgpLmlzQXV0b0J1aWxkaW5nKCkpIHsKCQkJR2xvYmFsQnVpbGRBY3Rpb24gYWN0aW9uID0gbmV3IEdsb2JhbEJ1aWxkQWN0aW9uKHdvcmtiZW5jaCwgZ2V0U2hlbGwoKSwgSW5jcmVtZW50YWxQcm9qZWN0QnVpbGRlci5JTkNSRU1FTlRBTF9CVUlMRCk7CgkJCWFjdGlvbi5kb0J1aWxkKCk7CgkJfQkKCX0KCgkvLyBDbGVhciB0aGUgY3VzdG9tIGJ1aWxkIG9yZGVyIGNhY2hlCgljdXN0b21CdWlsZE9yZGVyID0gbnVsbDsKCQoJcmV0dXJuIHRydWU7Cn0KLyoqCiAqIFJlbW92ZSB0aGUgY3VycmVudCBzZWxlY3Rpb24gaW4gdGhlIGJ1aWxkIGxpc3QuCiAqLwpwcml2YXRlIHZvaWQgcmVtb3ZlU2VsZWN0aW9uKCkgewoKCXRoaXMuYnVpbGRMaXN0LnJlbW92ZSh0aGlzLmJ1aWxkTGlzdC5nZXRTZWxlY3Rpb25JbmRpY2VzKCkpOwp9Ci8qKgogKiBTZXQgdGhlIHdpZGdldHMgdGhhdCBzZWxlY3QgYnVpbGQgb3JkZXIgdG8gYmUgZW5hYmxlZCBvciBkaWFibGVkLgogKiBAcGFyYW0gdmFsdWUgYm9vbGVhbgogKi8KcHJpdmF0ZSB2b2lkIHNldEJ1aWxkT3JkZXJXaWRnZXRzRW5hYmxlbWVudChib29sZWFuIHZhbHVlKSB7CgoJLy8gT25seSBjaGFuZ2UgZW5hYmxlbWVudCBvZiBidXR0b25zLiBMZWF2ZSBsaXN0IGFsb25lCgkvLyBiZWNhdXNlIHlvdSBjYW4ndCBzY3JvbGwgaXQgd2hlbiBkaXNhYmxlZC4KCUNvbnRyb2xbXSBjaGlsZHJlbiA9IHRoaXMuYnV0dG9uQ29tcG9zaXRlLmdldENoaWxkcmVuKCk7Cglmb3IgKGludCBpID0gMDsgaSA8IGNoaWxkcmVuLmxlbmd0aDsgaSsrKSB7CgkJY2hpbGRyZW5baV0uc2V0RW5hYmxlZCh2YWx1ZSk7Cgl9Cn0KCi8qKgogKiBSZXR1cm4gYSBzb3J0ZWQgYXJyYXkgb2YgdGhlIG5hbWVzIG9mIHRoZSBwcm9qZWN0cyB0aGF0IGFyZSBhbHJlYWR5IGluIHRoZSBjdXJyZW50bHkgCiAqIGRpc3BsYXllZCBuYW1lcy4KICogQHJldHVybiBTdHJpbmdbXQogKiBAcGFyYW0gYWxsUHJvamVjdHMgLSBhbGwgb2YgdGhlIHByb2plY3RzIGluIHRoZSB3b3Jrc3BhY2UgCiAqIEBwYXJhbSBjdXJyZW50bHlEaXNwbGF5ZWQgLSB0aGUgbmFtZXMgb2YgdGhlIHByb2plY3RzIGFscmVhZHkgYmVpbmcgZGlzcGxheWVkCiAqLwpwcml2YXRlIFN0cmluZ1tdIHNvcnRlZERpZmZlcmVuY2UoSVByb2plY3RbXSBhbGxQcm9qZWN0cywgU3RyaW5nW10gY3VycmVudGx5RGlzcGxheWVkKSB7CgoJVHJlZVNldCBkaWZmZXJlbmNlID0gbmV3IFRyZWVTZXQoKTsKCglmb3IoaW50IGkgPSAwOyBpIDwgYWxsUHJvamVjdHMubGVuZ3RoOyBpICsrKXsKCQlpZighaW5jbHVkZXMoY3VycmVudGx5RGlzcGxheWVkLGFsbFByb2plY3RzW2ldLmdldE5hbWUoKSkpCgkJCWRpZmZlcmVuY2UuYWRkKGFsbFByb2plY3RzW2ldLmdldE5hbWUoKSk7Cgl9CgoJU3RyaW5nIFtdIHJldHVyblZhbHVlID0gbmV3IFN0cmluZ1tkaWZmZXJlbmNlLnNpemUoKV07CglkaWZmZXJlbmNlLnRvQXJyYXkocmV0dXJuVmFsdWUpOwoJcmV0dXJuIHJldHVyblZhbHVlOwp9Cn0K