cGFja2FnZSBvcmcuZWNsaXBzZS51aS5leHRlcm5hbHRvb2xzLmludGVybmFsLnVpOwoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKQ29weXJpZ2h0IChjKSAyMDAyIElCTSBDb3JwLiBhbmQgb3RoZXJzLgpBbGwgcmlnaHRzIHJlc2VydmVkLiCgIFRoaXMgcHJvZ3JhbSBhbmQgdGhlIGFjY29tcGFueWluZyBtYXRlcmlhbHMKYXJlIG1hZGUgYXZhaWxhYmxlIHVuZGVyIHRoZSB0ZXJtcyBvZiB0aGUgQ29tbW9uIFB1YmxpYyBMaWNlbnNlIHYwLjUKd2hpY2ggYWNjb21wYW5pZXMgdGhpcyBkaXN0cmlidXRpb24sIGFuZCBpcyBhdmFpbGFibGUgYXQKaHR0cDovL3d3dy5lY2xpcHNlLm9yZy9sZWdhbC9jcGwtdjA1Lmh0bWwKoApDb250cmlidXRvcnM6CioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCmltcG9ydCBqYXZhLmlvLkZpbGU7CmltcG9ydCBqYXZhLnV0aWwuQXJyYXlMaXN0OwoKaW1wb3J0IG9yZy5lY2xpcHNlLmNvcmUucmVzb3VyY2VzLio7CmltcG9ydCBvcmcuZWNsaXBzZS5jb3JlLnJ1bnRpbWUuKjsKaW1wb3J0IG9yZy5lY2xpcHNlLmpmYWNlLmRpYWxvZ3MuKjsKaW1wb3J0IG9yZy5lY2xpcHNlLmpmYWNlLnZpZXdlcnMuKjsKaW1wb3J0IG9yZy5lY2xpcHNlLnN3dC5TV1Q7CmltcG9ydCBvcmcuZWNsaXBzZS5zd3QuZXZlbnRzLio7CmltcG9ydCBvcmcuZWNsaXBzZS5zd3QuZ3JhcGhpY3MuUG9pbnQ7CmltcG9ydCBvcmcuZWNsaXBzZS5zd3QubGF5b3V0Lio7CmltcG9ydCBvcmcuZWNsaXBzZS5zd3Qud2lkZ2V0cy4qOwppbXBvcnQgb3JnLmVjbGlwc2UudWkuKjsKaW1wb3J0IG9yZy5lY2xpcHNlLnVpLmhlbHAuV29ya2JlbmNoSGVscDsKaW1wb3J0IG9yZy5lY2xpcHNlLnVpLm1vZGVsLio7CmltcG9ydCBvcmcuZWNsaXBzZS51aS5kaWFsb2dzLio7CmltcG9ydCBvcmcuZWNsaXBzZS51aS5leHRlcm5hbHRvb2xzLmludGVybmFsLmNvcmUuKjsKaW1wb3J0IG9yZy5lY2xpcHNlLnVpLmV4dGVybmFsdG9vbHMuaW50ZXJuYWwuY29yZS5Ub29sVXRpbC5WYXJpYWJsZURlZmluaXRpb247CgovKioKICogRGlhbG9nIGJveCB0byBlbnRlciB0aGUgcmVxdWlyZWQgaW5mb3JtYXRpb24gZm9yIHJ1bm5pbmcKICogYW4gZXh0ZXJuYWwgdG9vbC4KICovCnB1YmxpYyBjbGFzcyBFZGl0RGlhbG9nIGV4dGVuZHMgVGl0bGVBcmVhRGlhbG9nIHsKCS8vIFRoZSB3aWR0aCBvZiBtb3N0IHRleHQgZmllbGRzIGluIHRoZSBkaWFsb2cuCgkvLyBGaWVsZHMgdGhhdCBoYXZlIGxhYmVscyBvbiB0aGUgc2FtZSBsaW5lIGFyZSBzaG9ydGVyLgoJLy8gQXMgc3VjaCwgYWxsIGZpZWxkcyBlbmQgaW4gdGhlIHNhbWUgdmVydGljYWwgcG9zaXRpb24uCglwcml2YXRlIHN0YXRpYyBmaW5hbCBpbnQgRklFTERfV0lEVEggPSAzMDA7CgkvLyBUaGUgc3BhY2luZyB1c2VkIHRvIHNlcGVyYXRlIGdyb3VwcyBpbiB0aGUgZGlhbG9nLgoJcHJpdmF0ZSBzdGF0aWMgZmluYWwgaW50IEdST1VQX1NQQUNFID0gMjA7CgkvLyBUaGUgc3BhY2luZyB1c2VkIHRvIHNlcGVyYXRlIHdpZGdldHMgaW4gYSBncm91cAoJcHJpdmF0ZSBzdGF0aWMgZmluYWwgaW50IFdJREdFVF9TUEFDRSA9IDU7CgkvLyBUaGUgc3BhY2luZyBvZiBtYXJnaW5zIGluIHRoZSBkaWFsb2cKCXByaXZhdGUgc3RhdGljIGZpbmFsIGludCBNQVJHSU5fU1BBQ0UgPSA1OwoJCgkvLyBkaWFsb2cgc2l6aW5nIGNvbnN0YW50cwoJcHJpdmF0ZSBzdGF0aWMgZmluYWwgaW50IFNJWklOR19TRUxFQ1RJT05fUEFORV9IRUlHSFQgPSAzMDA7Cglwcml2YXRlIHN0YXRpYyBmaW5hbCBpbnQgU0laSU5HX1NFTEVDVElPTl9QQU5FX1dJRFRIID0gMzAwOwkKCQoJcHJpdmF0ZSBzdGF0aWMgZmluYWwgYm9vbGVhbiBJTklUSUFMX1NIT1dfTE9HID0gdHJ1ZTsKCQoJcHJpdmF0ZSBUZXh0IG5hbWVGaWVsZDsKCXByaXZhdGUgVGV4dCBsb2NhdGlvbkZpZWxkOwoJcHJpdmF0ZSBUZXh0IGFyZ3VtZW50c0ZpZWxkOwoJcHJpdmF0ZSBUZXh0IGRpcmVjdG9yeUZpZWxkOwoJcHJpdmF0ZSBUZXh0IHJlZnJlc2hGaWVsZDsKCXByaXZhdGUgQnV0dG9uIGxvY2F0aW9uQnJvd3NlV29ya3NwYWNlOwoJcHJpdmF0ZSBCdXR0b24gbG9jYXRpb25Ccm93c2VGaWxlU3lzdGVtOwoJcHJpdmF0ZSBCdXR0b24gYXJndW1lbnRzQnJvd3NlVmFyaWFibGU7Ci8vCXByaXZhdGUgQnV0dG9uIGRpcmVjdG9yeUJyb3dzZVdvcmtzcGFjZTsKCXByaXZhdGUgQnV0dG9uIGRpcmVjdG9yeUJyb3dzZUJ1dHRvbjsKCXByaXZhdGUgQnV0dG9uIHJlZnJlc2hPcHRpb25CdXR0b247Cglwcml2YXRlIEJ1dHRvbiBzaG93TG9nOwoJCglwcml2YXRlIGJvb2xlYW4gZWRpdE1vZGUgPSBmYWxzZTsKCXByaXZhdGUgRXh0ZXJuYWxUb29sIHRvb2w7Cglwcml2YXRlIFN0cmluZyByZWZyZXNoU2NvcGU7CgoJcHJpdmF0ZSBpbnQgbWF4QnV0dG9uV2lkdGggPSAwOwoJLy8gVGhlIGRpZmZlcmVuY2UgYmV0d2VlbiB0aGUgaGVpZ2h0IG9mIGEgYnV0dG9uIGFuZAoJLy8gdGhlIGhlaWdodCBvZiBhIGxhYmVsLgoJcHJpdmF0ZSBpbnQgYnV0dG9uTGFiZWxIZWlnaHREaWZmOwoJCgkvKioKCSAqIEluc3RhbnRpYXRlIGEgbmV3IHRvb2wgdG9vbCBlZGl0IGRpYWxvZy4KCSAqCgkgKiBAcGFyYW0gcGFyZW50U2hlbGwgdGhlIHBhcmVudCBTV1Qgc2hlbGwKCSAqIEBwYXJhbSB0b29sIHRoZSB0b29sIHRvb2wgdG8gZWRpdCwgPGNvZGU+bnVsbDwvY29kZT4gaWYgbmV3CgkgKi8KCXB1YmxpYyBFZGl0RGlhbG9nKFNoZWxsIHBhcmVudFNoZWxsLCBFeHRlcm5hbFRvb2wgdG9vbCkgewoJCXN1cGVyKHBhcmVudFNoZWxsKTsKCQlpZiAodG9vbCA9PSBudWxsKSB7CgkJCXRoaXMudG9vbCA9IG5ldyBFeHRlcm5hbFRvb2woKTsKCQkJdGhpcy5lZGl0TW9kZSA9IGZhbHNlOwoJCX0gZWxzZSB7CgkJCXRoaXMudG9vbCA9IHRvb2w7CgkJCXRoaXMuZWRpdE1vZGUgPSB0cnVlOwoJCX0KCX0KCQoJLyogKG5vbi1KYXZhZG9jKQoJICogTWV0aG9kIGRlY2xhcmVkIGluIFdpbmRvdy4KCSAqLwoJcHJvdGVjdGVkIHZvaWQgY29uZmlndXJlU2hlbGwoU2hlbGwgc2hlbGwpIHsKCQlzdXBlci5jb25maWd1cmVTaGVsbChzaGVsbCk7CgkJaWYgKGVkaXRNb2RlKQoJCQlzaGVsbC5zZXRUZXh0KFRvb2xNZXNzYWdlcy5nZXRTdHJpbmcoIkVkaXREaWFsb2cuZWRpdFNoZWxsVGl0bGUiKSk7IC8vJE5PTi1OTFMtMSQKCQllbHNlCgkJCXNoZWxsLnNldFRleHQoVG9vbE1lc3NhZ2VzLmdldFN0cmluZygiRWRpdERpYWxvZy5uZXdTaGVsbFRpdGxlIikpOyAvLyROT04tTkxTLTEkCgkJV29ya2JlbmNoSGVscC5zZXRIZWxwKAoJCQlzaGVsbCwKCQkJSUhlbHBDb250ZXh0SWRzLkVESVRfRElBTE9HKTsKCX0KCgkvKiAobm9uLUphdmFkb2MpCgkgKiBNZXRob2QgZGVjbGFyZWQgb24gRGlhbG9nLgoJICovCglwcm90ZWN0ZWQgdm9pZCBjcmVhdGVCdXR0b25zRm9yQnV0dG9uQmFyKENvbXBvc2l0ZSBwYXJlbnQpIHsKCQljcmVhdGVCdXR0b24ocGFyZW50LCBJRGlhbG9nQ29uc3RhbnRzLk9LX0lELCBJRGlhbG9nQ29uc3RhbnRzLk9LX0xBQkVMLCB0cnVlKTsKCQljcmVhdGVCdXR0b24ocGFyZW50LCBJRGlhbG9nQ29uc3RhbnRzLkNBTkNFTF9JRCwgSURpYWxvZ0NvbnN0YW50cy5DQU5DRUxfTEFCRUwsIGZhbHNlKTsKCQkKCQlpZiAoIWVkaXRNb2RlKQoJCQlnZXRCdXR0b24oSURpYWxvZ0NvbnN0YW50cy5PS19JRCkuc2V0RW5hYmxlZChmYWxzZSk7CgkJCQoJCS8vIE5vdyB0aGF0IGJvdGggdGhlIGRpYWxvZyBhcmVhIGFuZCBidXR0b25zIGhhdmUgYmVlbgoJCS8vIGNyZWF0ZWQsIHVwZGF0ZSB0aGUgbWVzc2FnZSBkZXNjcmlwdGlvbi4KCQl2YWxpZGF0ZUZpZWxkcygpOwoJfQoJCgkvKiAobm9uLUphdmFkb2MpCgkgKiBNZXRob2QgZGVjbGFyZWQgb24gRGlhbG9nLgoJICovCglwcm90ZWN0ZWQgQ29udHJvbCBjcmVhdGVEaWFsb2dBcmVhKENvbXBvc2l0ZSBwYXJlbnQpIHsKCQlDb21wb3NpdGUgZGlhbG9nQ29tcCA9IChDb21wb3NpdGUpc3VwZXIuY3JlYXRlRGlhbG9nQXJlYShwYXJlbnQpOwoJCQkJCgkJLy8gU2V0IHRpdGxlIGFuZCBtZXNzYWdlIG5vdyB0aGF0IHRoZSBjb250cm9scyBleGlzdAoJCXNldFRpdGxlKFRvb2xNZXNzYWdlcy5nZXRTdHJpbmcoIkVkaXREaWFsb2cuZGlhbG9nVGl0bGUiKSk7IC8vJE5PTi1OTFMtMSQKCQlpZiAoZWRpdE1vZGUpCgkJCXNldE1lc3NhZ2UoVG9vbE1lc3NhZ2VzLmdldFN0cmluZygiRWRpdERpYWxvZy5lZGl0RGlhbG9nTWVzc2FnZSIpKTsgLy8kTk9OLU5MUy0xJAoJCWVsc2UKCQkJc2V0TWVzc2FnZShUb29sTWVzc2FnZXMuZ2V0U3RyaW5nKCJFZGl0RGlhbG9nLm5ld0RpYWxvZ01lc3NhZ2UiKSk7IC8vJE5PTi1OTFMtMSQKCQlzZXRUaXRsZUltYWdlKEV4dGVybmFsVG9vbHNQbHVnaW4uZ2V0RGVmYXVsdCgpLmdldEltYWdlRGVzY3JpcHRvcihFeHRlcm5hbFRvb2xzUGx1Z2luLklNR19XSVpCQU5fRVhURVJOQUxfVE9PTFMpLmNyZWF0ZUltYWdlKCkpOwoJCQoJCS8vIEJ1aWxkIHRoZSB0b3AgY29udGFpbmVyCgkJQ29tcG9zaXRlIHRvcENvbXAgPSBuZXcgQ29tcG9zaXRlKGRpYWxvZ0NvbXAsIFNXVC5OT05FKTsKCQlGb3JtTGF5b3V0IGxheW91dCA9IG5ldyBGb3JtTGF5b3V0KCk7CgkJdG9wQ29tcC5zZXRMYXlvdXQobGF5b3V0KTsKCQlsYXlvdXQubWFyZ2luSGVpZ2h0ID0gTUFSR0lOX1NQQUNFOwoJCWxheW91dC5tYXJnaW5XaWR0aCA9IE1BUkdJTl9TUEFDRTsKCQkKCQkvLyBOZWVkIHRvIGtlZXAgdHJhY2sgb2YgdGhlIEZvcm1EYXRhJ3MgZm9yIHRoZSBidXR0b25zIHRvIHNldAoJCS8vIHRoZSB3aWR0aCBvZiBhbGwgdGhlIGJ1dHRvbnMgdG8gYmUgdGhlIHNhbWUgYXMgdGhlIGxhcmdlc3QKCQkvLyBidXR0b24gd2lkdGgKCQlGb3JtRGF0YVtdIGJ1dHRvbkRhdGEgPSBuZXcgRm9ybURhdGFbNV07CgkJCgkJLy8gQ3JlYXRlIG5hbWUgbGFiZWwKCQlMYWJlbCBuYW1lTGFiZWwgPSBuZXcgTGFiZWwodG9wQ29tcCwgU1dULk5PTkUpOwoJCW5hbWVMYWJlbC5zZXRUZXh0KFRvb2xNZXNzYWdlcy5nZXRTdHJpbmcoIkVkaXREaWFsb2cubmFtZUxhYmVsIikpOyAvLyROT04tTkxTLTEkCgkJRm9ybURhdGEgZGF0YSA9IG5ldyBGb3JtRGF0YSgpOwoJCWRhdGEudG9wID0gbmV3IEZvcm1BdHRhY2htZW50KDAsIE1BUkdJTl9TUEFDRSk7CgkJbmFtZUxhYmVsLnNldExheW91dERhdGEoZGF0YSk7CgoJCS8vIENyZWF0ZSBuYW1lIHRleHQgZmllbGQKCQluYW1lRmllbGQgPSBuZXcgVGV4dCh0b3BDb21wLCBTV1QuQk9SREVSKTsKCQlkYXRhID0gbmV3IEZvcm1EYXRhKCk7CgkJZGF0YS5sZWZ0ID0gbmV3IEZvcm1BdHRhY2htZW50KG5hbWVMYWJlbCwgTUFSR0lOX1NQQUNFLCBTV1QuUklHSFQpOwoJCWRhdGEudG9wID0gbmV3IEZvcm1BdHRhY2htZW50KG5hbWVMYWJlbCwgMCwgU1dULkNFTlRFUik7CgkJZGF0YS53aWR0aCA9IEZJRUxEX1dJRFRIIC0gTUFSR0lOX1NQQUNFIC0gbmFtZUxhYmVsLmNvbXB1dGVTaXplKFNXVC5ERUZBVUxULCBTV1QuREVGQVVMVCwgZmFsc2UpLng7CgkJbmFtZUZpZWxkLnNldExheW91dERhdGEoZGF0YSk7CgoJCS8vIENyZWF0ZSBsb2NhdGlvbiBicm93c2Ugd29ya3NwYWNlIGJ1dHRvbgoJCWxvY2F0aW9uQnJvd3NlV29ya3NwYWNlID0gbmV3IEJ1dHRvbih0b3BDb21wLCBTV1QuUFVTSCk7CgkJbG9jYXRpb25Ccm93c2VXb3Jrc3BhY2Uuc2V0VGV4dChUb29sTWVzc2FnZXMuZ2V0U3RyaW5nKCJFZGl0RGlhbG9nLmJyb3dzZVdrc3BCdXR0b24xIikpOyAvLyROT04tTkxTLTEkCgkJYnV0dG9uRGF0YVswXSA9IG5ldyBGb3JtRGF0YSgpOwoJCWJ1dHRvbkRhdGFbMF0ubGVmdCA9IG5ldyBGb3JtQXR0YWNobWVudChuYW1lRmllbGQsIE1BUkdJTl9TUEFDRSwgU1dULlJJR0hUKTsKCQlidXR0b25EYXRhWzBdLnRvcCA9IG5ldyBGb3JtQXR0YWNobWVudChuYW1lRmllbGQsIEdST1VQX1NQQUNFLCBTV1QuQk9UVE9NKTsKCQlsb2NhdGlvbkJyb3dzZVdvcmtzcGFjZS5zZXRMYXlvdXREYXRhKGJ1dHRvbkRhdGFbMF0pOwoJCWNoZWNrRm9yTWF4V2lkdGgobG9jYXRpb25Ccm93c2VXb3Jrc3BhY2UpOwoJCQoJCS8vIENhbGN1bGF0ZSB0aGUgZGlmZmVyZW5jZSBpbiBoZWlnaHQgYmV0d2VlbiBhIGxhYmVsIGFuZCBhIGJ1dHRvbi4KCQkvLyBUaGlzIHZhcmlhYmxlIHdpbGwgYmUgdXNlZCB0byBlbnN1cmUgZXF1YWwgc3BhY2luZyBiZXR3ZWVuIGdyb3Vwcy4KCQlidXR0b25MYWJlbEhlaWdodERpZmYgPSBsb2NhdGlvbkJyb3dzZVdvcmtzcGFjZS5jb21wdXRlU2l6ZShTV1QuREVGQVVMVCwgU1dULkRFRkFVTFQsIGZhbHNlKS55IC0gbmFtZUxhYmVsLmNvbXB1dGVTaXplKFNXVC5ERUZBVUxULCBTV1QuREVGQVVMVCwgZmFsc2UpLnk7CgoJCS8vIENyZWF0ZSBsYWJlbCBmb3IgbG9jYXRpb24gdGV4dCBmaWVsZC4KCQlMYWJlbCBsb2NhdGlvbkxhYmVsID0gbmV3IExhYmVsKHRvcENvbXAsIFNXVC5OT05FKTsKCQlsb2NhdGlvbkxhYmVsLnNldFRleHQoVG9vbE1lc3NhZ2VzLmdldFN0cmluZygiRWRpdERpYWxvZy5sb2NhdGlvbkxhYmVsIikpOyAvLyROT04tTkxTLTEkCgkJZGF0YSA9IG5ldyBGb3JtRGF0YSgpOwoJCWRhdGEuYm90dG9tID0gbmV3IEZvcm1BdHRhY2htZW50KGxvY2F0aW9uQnJvd3NlV29ya3NwYWNlLCAwLCBTV1QuQk9UVE9NKTsKCQlsb2NhdGlvbkxhYmVsLnNldExheW91dERhdGEoZGF0YSk7CgoJCS8vIENyZWF0ZSBsb2NhdGlvbiB0ZXh0IGZpZWxkLgoJCWxvY2F0aW9uRmllbGQgPSBuZXcgVGV4dCh0b3BDb21wLCBTV1QuQk9SREVSKTsKCQlkYXRhID0gbmV3IEZvcm1EYXRhKCk7CgkJZGF0YS5sZWZ0ID0gbmV3IEZvcm1BdHRhY2htZW50KDAsIDApOwoJCWRhdGEucmlnaHQgPSBuZXcgRm9ybUF0dGFjaG1lbnQobG9jYXRpb25Ccm93c2VXb3Jrc3BhY2UsIC1NQVJHSU5fU1BBQ0UsIFNXVC5MRUZUKTsKCQlkYXRhLnRvcCA9IG5ldyBGb3JtQXR0YWNobWVudChsb2NhdGlvbkJyb3dzZVdvcmtzcGFjZSwgV0lER0VUX1NQQUNFLCBTV1QuQk9UVE9NKTsKCQlkYXRhLndpZHRoID0gRklFTERfV0lEVEg7CgkJbG9jYXRpb25GaWVsZC5zZXRMYXlvdXREYXRhKGRhdGEpOwoKCQkvLyBDcmVhdGUgbG9jYXRpb24gYnJvd3NlIGZpbGUgc3lzdGVtIGJ1dHRvbi4KCQlsb2NhdGlvbkJyb3dzZUZpbGVTeXN0ZW0gPSBuZXcgQnV0dG9uKHRvcENvbXAsIFNXVC5QVVNIKTsKCQlsb2NhdGlvbkJyb3dzZUZpbGVTeXN0ZW0uc2V0VGV4dChUb29sTWVzc2FnZXMuZ2V0U3RyaW5nKCJFZGl0RGlhbG9nLmJyb3dzZUZpbGVTeXNCdXR0b24xIikpOyAvLyROT04tTkxTLTEkCgkJYnV0dG9uRGF0YVsxXSA9IG5ldyBGb3JtRGF0YSgpOwoJCWJ1dHRvbkRhdGFbMV0ubGVmdCA9IG5ldyBGb3JtQXR0YWNobWVudChsb2NhdGlvbkJyb3dzZVdvcmtzcGFjZSwgMCwgU1dULkxFRlQpOwoJCWJ1dHRvbkRhdGFbMV0udG9wID0gbmV3IEZvcm1BdHRhY2htZW50KGxvY2F0aW9uQnJvd3NlV29ya3NwYWNlLCBXSURHRVRfU1BBQ0UsIFNXVC5CT1RUT00pOwoJCWxvY2F0aW9uQnJvd3NlRmlsZVN5c3RlbS5zZXRMYXlvdXREYXRhKGJ1dHRvbkRhdGFbMV0pOwoJCWNoZWNrRm9yTWF4V2lkdGgobG9jYXRpb25Ccm93c2VGaWxlU3lzdGVtKTsKCgkJLy8gQ3JlYXRlIGxhYmVsIGZvciBhcmd1bWVudHMgdGV4dCBmaWVsZC4KCQlMYWJlbCBhcmd1bWVudHNMYWJlbCA9IG5ldyBMYWJlbCh0b3BDb21wLCBTV1QuTk9ORSk7CgkJYXJndW1lbnRzTGFiZWwuc2V0VGV4dChUb29sTWVzc2FnZXMuZ2V0U3RyaW5nKCJFZGl0RGlhbG9nLmFyZ3VtZW50TGFiZWwiKSk7IC8vJE5PTi1OTFMtMSQKCQlkYXRhID0gbmV3IEZvcm1EYXRhKCk7CgkJZGF0YS50b3AgPSBuZXcgRm9ybUF0dGFjaG1lbnQobG9jYXRpb25GaWVsZCwgR1JPVVBfU1BBQ0UrYnV0dG9uTGFiZWxIZWlnaHREaWZmLCBTV1QuQk9UVE9NKTsKCQlhcmd1bWVudHNMYWJlbC5zZXRMYXlvdXREYXRhKGRhdGEpOwoKCQkvLyBDcmVhdGUgYXJndW1lbnRzIHRleHQgZmllbGQuCgkJYXJndW1lbnRzRmllbGQgPSBuZXcgVGV4dCh0b3BDb21wLCBTV1QuQk9SREVSKTsKCQlkYXRhID0gbmV3IEZvcm1EYXRhICgpOwoJCWRhdGEubGVmdCA9IG5ldyBGb3JtQXR0YWNobWVudCgwLCAwKTsKCQlkYXRhLnJpZ2h0ID0gbmV3IEZvcm1BdHRhY2htZW50KGxvY2F0aW9uQnJvd3NlRmlsZVN5c3RlbSwgLU1BUkdJTl9TUEFDRSwgU1dULkxFRlQpOwoJCWRhdGEudG9wID0gbmV3IEZvcm1BdHRhY2htZW50KGFyZ3VtZW50c0xhYmVsLCBXSURHRVRfU1BBQ0UsIFNXVC5CT1RUT00pOwoJCWRhdGEud2lkdGggPSBGSUVMRF9XSURUSDsKCQlhcmd1bWVudHNGaWVsZC5zZXRMYXlvdXREYXRhKGRhdGEpOwoKCQkvLyBDcmVhdGUgYXJndW1lbnQgYnJvd3NlIHZhcmlhYmxlIGJ1dHRvbi4KCQlhcmd1bWVudHNCcm93c2VWYXJpYWJsZSA9IG5ldyBCdXR0b24odG9wQ29tcCwgU1dULlBVU0gpOwoJCWFyZ3VtZW50c0Jyb3dzZVZhcmlhYmxlLnNldFRleHQoVG9vbE1lc3NhZ2VzLmdldFN0cmluZygiRWRpdERpYWxvZy5icm93c2VWYXJzQnV0dG9uIikpOyAvLyROT04tTkxTLTEkCgkJYnV0dG9uRGF0YVsyXSA9IG5ldyBGb3JtRGF0YSgpOwoJCWJ1dHRvbkRhdGFbMl0ubGVmdCA9IG5ldyBGb3JtQXR0YWNobWVudChsb2NhdGlvbkJyb3dzZUZpbGVTeXN0ZW0sIDAsIFNXVC5MRUZUKTsKCQlidXR0b25EYXRhWzJdLmJvdHRvbSA9IG5ldyBGb3JtQXR0YWNobWVudChhcmd1bWVudHNGaWVsZCwgMCwgU1dULkJPVFRPTSk7CgkJYXJndW1lbnRzQnJvd3NlVmFyaWFibGUuc2V0TGF5b3V0RGF0YShidXR0b25EYXRhWzJdKTsKCQljaGVja0Zvck1heFdpZHRoKGFyZ3VtZW50c0Jyb3dzZVZhcmlhYmxlKTsKCgkJLy8gQ3JlYXRlIGxhYmVsIGZvciBkaXJlY3RvcnkgdGV4dCBmaWVsZC4KCQlMYWJlbCBkaXJMYWJlbCA9IG5ldyBMYWJlbCh0b3BDb21wLCBTV1QuTk9ORSk7CgkJZGlyTGFiZWwuc2V0VGV4dChUb29sTWVzc2FnZXMuZ2V0U3RyaW5nKCJFZGl0RGlhbG9nLmRpckxhYmVsIikpOyAvLyROT04tTkxTLTEkCgkJZGF0YSA9IG5ldyBGb3JtRGF0YSgpOwoJCWRhdGEudG9wID0gbmV3IEZvcm1BdHRhY2htZW50KGFyZ3VtZW50c0ZpZWxkLCBHUk9VUF9TUEFDRStidXR0b25MYWJlbEhlaWdodERpZmYsIFNXVC5CT1RUT00pOwoJCWRpckxhYmVsLnNldExheW91dERhdGEoZGF0YSk7CgoJCS8vIENyZWF0ZSBkaXJlY3RvcnkgdGV4dCBmaWVsZC4KCQlkaXJlY3RvcnlGaWVsZCA9IG5ldyBUZXh0KHRvcENvbXAsIFNXVC5CT1JERVIpOwoJCWRhdGEgPSBuZXcgRm9ybURhdGEoKTsKCQlkYXRhLmxlZnQgPSBuZXcgRm9ybUF0dGFjaG1lbnQoMCwgMCk7CgkJZGF0YS5yaWdodCA9IG5ldyBGb3JtQXR0YWNobWVudChhcmd1bWVudHNCcm93c2VWYXJpYWJsZSwgLU1BUkdJTl9TUEFDRSwgU1dULkxFRlQpOwoJCWRhdGEudG9wID0gbmV3IEZvcm1BdHRhY2htZW50KGRpckxhYmVsLCBXSURHRVRfU1BBQ0UsIFNXVC5CT1RUT00pOwoJCWRhdGEud2lkdGggPSBGSUVMRF9XSURUSDsKCQlkaXJlY3RvcnlGaWVsZC5zZXRMYXlvdXREYXRhKGRhdGEpOwoKCQkvLyBDcmVhdGUgZGlyZWN0b3J5IGJyb3dzZSBmaWxlIHN5c3RlbSBidXR0b24uCgkJZGlyZWN0b3J5QnJvd3NlQnV0dG9uID0gbmV3IEJ1dHRvbih0b3BDb21wLCBTV1QuUFVTSCk7CgkJZGlyZWN0b3J5QnJvd3NlQnV0dG9uLnNldFRleHQoVG9vbE1lc3NhZ2VzLmdldFN0cmluZygiRWRpdERpYWxvZy5kaXJlY3RvcnlCcm93c2VCdXR0b24iKSk7IC8vJE5PTi1OTFMtMSQKCQlidXR0b25EYXRhWzNdID0gbmV3IEZvcm1EYXRhKCk7CgkJYnV0dG9uRGF0YVszXS5sZWZ0ID0gbmV3IEZvcm1BdHRhY2htZW50KGFyZ3VtZW50c0ZpZWxkLCBNQVJHSU5fU1BBQ0UsIFNXVC5SSUdIVCk7CgkJYnV0dG9uRGF0YVszXS5ib3R0b20gPSBuZXcgRm9ybUF0dGFjaG1lbnQoZGlyZWN0b3J5RmllbGQsIDAsIFNXVC5CT1RUT00pOwoJCWRpcmVjdG9yeUJyb3dzZUJ1dHRvbi5zZXRMYXlvdXREYXRhKGJ1dHRvbkRhdGFbM10pOwoJCWNoZWNrRm9yTWF4V2lkdGgoZGlyZWN0b3J5QnJvd3NlQnV0dG9uKTsKCQkKCQkvLyBDcmVhdGUgcmVmcmVzaCBjaGVjayBib3ggYW5kIGxhYmVsLgoJCUxhYmVsIHJlZnJlc2hMYWJlbCA9IG5ldyBMYWJlbCh0b3BDb21wLCBTV1QuTk9ORSk7CgkJcmVmcmVzaExhYmVsLnNldFRleHQoVG9vbE1lc3NhZ2VzLmdldFN0cmluZygiRWRpdERpYWxvZy5yZWZyZXNoT3B0aW9uIikpOyAvLyROT04tTkxTLTEkCgkJZGF0YSA9IG5ldyBGb3JtRGF0YSgpOwoJCWRhdGEubGVmdCA9IG5ldyBGb3JtQXR0YWNobWVudCgwLDApOwoJCWRhdGEudG9wID0gbmV3IEZvcm1BdHRhY2htZW50KGRpcmVjdG9yeUZpZWxkLCBHUk9VUF9TUEFDRStidXR0b25MYWJlbEhlaWdodERpZmYsIFNXVC5CT1RUT00pOwoJCXJlZnJlc2hMYWJlbC5zZXRMYXlvdXREYXRhKGRhdGEpOwoJCQoJCS8vIENyZWF0ZSByZWZyZXNoIHRleHQgZmllbGQuCgkJcmVmcmVzaEZpZWxkID0gbmV3IFRleHQodG9wQ29tcCwgU1dULlNJTkdMRSB8IFNXVC5IX1NDUk9MTCB8IFNXVC5CT1JERVIpOwoJCXJlZnJlc2hGaWVsZC5zZXRFZGl0YWJsZShmYWxzZSk7CgkJZGF0YSA9IG5ldyBGb3JtRGF0YSgpOwoJCWRhdGEubGVmdCA9IG5ldyBGb3JtQXR0YWNobWVudChyZWZyZXNoTGFiZWwsIE1BUkdJTl9TUEFDRSwgU1dULlJJR0hUKTsKCQlkYXRhLnRvcCA9IG5ldyBGb3JtQXR0YWNobWVudChyZWZyZXNoTGFiZWwsIDAsIFNXVC5DRU5URVIpOwoJCWRhdGEud2lkdGggPSBGSUVMRF9XSURUSCAtIE1BUkdJTl9TUEFDRSAtIHJlZnJlc2hMYWJlbC5jb21wdXRlU2l6ZShTV1QuREVGQVVMVCwgU1dULkRFRkFVTFQsIGZhbHNlKS54OwoJCXJlZnJlc2hGaWVsZC5zZXRMYXlvdXREYXRhKGRhdGEpOwoKCQkvLyBDcmVhdGUgcmVmcmVzaCBzY29wZS4KCQlyZWZyZXNoT3B0aW9uQnV0dG9uID0gbmV3IEJ1dHRvbih0b3BDb21wLCBTV1QuUFVTSCk7CgkJcmVmcmVzaE9wdGlvbkJ1dHRvbi5zZXRUZXh0KFRvb2xNZXNzYWdlcy5nZXRTdHJpbmcoIkVkaXREaWFsb2cucmVmcmVzaE9wdGlvbkJ1dHRvbiIpKTsgLy8kTk9OLU5MUy0xJAoJCWJ1dHRvbkRhdGFbNF0gPSBuZXcgRm9ybURhdGEoKTsKCQlidXR0b25EYXRhWzRdLmxlZnQgPSBuZXcgRm9ybUF0dGFjaG1lbnQoZGlyZWN0b3J5QnJvd3NlQnV0dG9uLCAwLCBTV1QuTEVGVCk7CgkJYnV0dG9uRGF0YVs0XS50b3AgPSBuZXcgRm9ybUF0dGFjaG1lbnQocmVmcmVzaEZpZWxkLCAwLCBTV1QuVE9QKTsKCQlyZWZyZXNoT3B0aW9uQnV0dG9uLnNldExheW91dERhdGEoYnV0dG9uRGF0YVs0XSk7CgkJY2hlY2tGb3JNYXhXaWR0aChyZWZyZXNoT3B0aW9uQnV0dG9uKTsKCQkKCQkvLyBDcmVhdGUgc2hvdyBsb2cgY2hlY2tib3gKCQlzaG93TG9nID0gbmV3IEJ1dHRvbih0b3BDb21wLCBTV1QuQ0hFQ0spOwoJCXNob3dMb2cuc2V0VGV4dChUb29sTWVzc2FnZXMuZ2V0U3RyaW5nKCJFZGl0RGlhbG9nLnNob3dMb2dMYWJlbCIpKTsgLy8kTk9OLU5MUy0xJAoJCXNob3dMb2cuc2V0U2VsZWN0aW9uKElOSVRJQUxfU0hPV19MT0cpOwoJCWRhdGEgPSBuZXcgRm9ybURhdGEoKTsKCQlkYXRhLmxlZnQgPSBuZXcgRm9ybUF0dGFjaG1lbnQoMCwwKTsKCQlkYXRhLnRvcCA9IG5ldyBGb3JtQXR0YWNobWVudChyZWZyZXNoRmllbGQsIEdST1VQX1NQQUNFLCBTV1QuQk9UVE9NKTsKCQlzaG93TG9nLnNldExheW91dERhdGEoZGF0YSk7CgkJCgkJLy8gZ2l2ZSBhbGwgdGhlIGJ1dHRvbnMgdGhlIHNhbWUgd2lkdGgKCQlmb3IgKGludCBpPTA7IGk8YnV0dG9uRGF0YS5sZW5ndGg7IGkrKykgewoJCQlidXR0b25EYXRhW2ldLndpZHRoID0gbWF4QnV0dG9uV2lkdGg7CQoJCX0JCgkJCgkJLy8gQnVpbGQgdGhlIHNlcGFyYXRvciBsaW5lCgkJTGFiZWwgc2VwYXJhdG9yID0gbmV3IExhYmVsKGRpYWxvZ0NvbXAsIFNXVC5IT1JJWk9OVEFMIHwgU1dULlNFUEFSQVRPUik7CgkJc2VwYXJhdG9yLnNldExheW91dERhdGEobmV3IEdyaWREYXRhKEdyaWREYXRhLkZJTExfSE9SSVpPTlRBTCkpOwoJCQoJCS8vIEluaXQgZmllbGQgdmFsdWVzCgkJaWYgKGVkaXRNb2RlKSB7CgkJCW5hbWVGaWVsZC5zZXRUZXh0KHRvb2wuZ2V0TmFtZSgpKTsKCQkJbG9jYXRpb25GaWVsZC5zZXRUZXh0KHRvb2wuZ2V0TG9jYXRpb24oKSk7CgkJCWFyZ3VtZW50c0ZpZWxkLnNldFRleHQodG9vbC5nZXRBcmd1bWVudHMoKSk7CgkJCWRpcmVjdG9yeUZpZWxkLnNldFRleHQodG9vbC5nZXRXb3JraW5nRGlyZWN0b3J5KCkpOwoJCQlzaG93TG9nLnNldFNlbGVjdGlvbih0b29sLmdldFNob3dMb2coKSk7CgkJfQoJCXJlZnJlc2hTY29wZSA9IHRvb2wuZ2V0UmVmcmVzaFNjb3BlKCk7CgkJdXBkYXRlUmVmcmVzaEZpZWxkKCk7CgoJCS8vIFNldCB0aGUgcHJvcGVyIHRhYiBvcmRlcgoJCUNvbnRyb2xbXSB0YWJMaXN0ID0gbmV3IENvbnRyb2xbXSB7CgkJCW5hbWVGaWVsZCwgCgkJCWxvY2F0aW9uRmllbGQsIAoJCQlsb2NhdGlvbkJyb3dzZVdvcmtzcGFjZSwKCQkJbG9jYXRpb25Ccm93c2VGaWxlU3lzdGVtLAoJCQlhcmd1bWVudHNGaWVsZCwKCQkJYXJndW1lbnRzQnJvd3NlVmFyaWFibGUsCgkJCWRpcmVjdG9yeUZpZWxkLAoJCQlkaXJlY3RvcnlCcm93c2VCdXR0b24sCgkJCXJlZnJlc2hGaWVsZCwKCQkJcmVmcmVzaE9wdGlvbkJ1dHRvbn07CgkJdG9wQ29tcC5zZXRUYWJMaXN0KHRhYkxpc3QpOwoJCQoJCS8vIEZpbmlzaCBzZXR1cAoJCWhvb2tCdXR0b25BY3Rpb25zKCk7CgkJaG9va0ZpZWxkVmFsaWRhdGlvbigpOwoJCW5hbWVGaWVsZC5zZXRGb2N1cygpOwoKCQlyZXR1cm4gZGlhbG9nQ29tcDsKCX0KCQoJLyoqCgkgKiBDaGVjayB0byBzZWUgaWYgdGhlIHN1cHBsaWVkIGJ1dHRvbiBoYXMgdGhlIG1heGltdW0gd2lkdGggb2YKCSAqIGFsbCB0aGUgYnV0dG9ucyBzbyBmYXIuIElmIGl0IGlzLCBzdG9yZSB0aGUgd2lkdGggaW4KCSAqIHRoZSBpbnRlZ2VyIHZhcmlhYmxlIDxjb2RlPm1heEJ1dHRvbldpZHRoPC9jb2RlPi4KCSAqLwoJcHJpdmF0ZSB2b2lkIGNoZWNrRm9yTWF4V2lkdGgoQnV0dG9uIGJ1dHRvbikgewoJCVBvaW50IHNpemUgPSBidXR0b24uY29tcHV0ZVNpemUoU1dULkRFRkFVTFQsIFNXVC5ERUZBVUxULCB0cnVlKTsKCQlpZiAoc2l6ZS54ID4gbWF4QnV0dG9uV2lkdGgpCgkJCW1heEJ1dHRvbldpZHRoID0gc2l6ZS54OwkJCgl9CgkKCS8qKgoJICogUmV0dXJucyB0aGUgdG9vbCB0b29sIGFwcGxpY2FibGUgdG8gdGhpcyBkaWFsb2cuCgkgKi8KCXB1YmxpYyBFeHRlcm5hbFRvb2wgZ2V0RXh0ZXJuYWxUb29sKCkgewoJCXJldHVybiB0b29sOwoJfQoJCgkvKioKCSAqIEhvb2tzIHRoZSBhY3Rpb24gaGFuZGxlciBmb3Igd2hlbiBhIGJ1dHRvbiBpcyBwcmVzc2VkCgkgKi8KCXByaXZhdGUgdm9pZCBob29rQnV0dG9uQWN0aW9ucygpIHsKCQlsb2NhdGlvbkJyb3dzZVdvcmtzcGFjZS5hZGRTZWxlY3Rpb25MaXN0ZW5lcihuZXcgU2VsZWN0aW9uQWRhcHRlcigpIHsKCQkJcHVibGljIHZvaWQgd2lkZ2V0U2VsZWN0ZWQoU2VsZWN0aW9uRXZlbnQgZSkgewoJCQkJUmVzb3VyY2VTZWxlY3Rpb25EaWFsb2cgZGlhbG9nOwoJCQkJZGlhbG9nID0gbmV3IFJlc291cmNlU2VsZWN0aW9uRGlhbG9nKAoJCQkJCWdldFNoZWxsKCksIAoJCQkJCVJlc291cmNlc1BsdWdpbi5nZXRXb3Jrc3BhY2UoKS5nZXRSb290KCksCgkJCQkJVG9vbE1lc3NhZ2VzLmdldFN0cmluZygiRWRpdERpYWxvZy5zZWxlY3RUb29sIikpOyAvLyROT04tTkxTLTEkCgkJCQlkaWFsb2cub3BlbigpOwoJCQkJT2JqZWN0W10gcmVzdWx0cyA9IGRpYWxvZy5nZXRSZXN1bHQoKTsKCQkJCWlmIChyZXN1bHRzID09IG51bGwgfHwgcmVzdWx0cy5sZW5ndGggPCAxKQoJCQkJCXJldHVybjsKCQkJCUlSZXNvdXJjZSByZXNvdXJjZSA9IChJUmVzb3VyY2UpcmVzdWx0c1swXTsKCQkJCVN0cmluZ0J1ZmZlciBidWYgPSBuZXcgU3RyaW5nQnVmZmVyKCk7CgkJCQlUb29sVXRpbC5idWlsZFZhcmlhYmxlVGFnKEV4dGVybmFsVG9vbC5WQVJfV09SS1NQQUNFX0xPQywgcmVzb3VyY2UuZ2V0RnVsbFBhdGgoKS50b1N0cmluZygpLCBidWYpOwoJCQkJbG9jYXRpb25GaWVsZC5zZXRUZXh0KGJ1Zi50b1N0cmluZygpKTsKCQkJfQoJCX0pOwoJCQoJCWxvY2F0aW9uQnJvd3NlRmlsZVN5c3RlbS5hZGRTZWxlY3Rpb25MaXN0ZW5lcihuZXcgU2VsZWN0aW9uQWRhcHRlcigpIHsKCQkJcHVibGljIHZvaWQgd2lkZ2V0U2VsZWN0ZWQoU2VsZWN0aW9uRXZlbnQgZSkgewoJCQkJRmlsZURpYWxvZyBkaWFsb2cgPSBuZXcgRmlsZURpYWxvZyhnZXRTaGVsbCgpLCBTV1QuTk9ORSk7CgkJCQlkaWFsb2cuc2V0RmlsZU5hbWUobG9jYXRpb25GaWVsZC5nZXRUZXh0KCkpOwoJCQkJU3RyaW5nIGZpbGVuYW1lID0gZGlhbG9nLm9wZW4oKTsKCQkJCWlmIChmaWxlbmFtZSAhPSBudWxsKSB7CgkJCQkJbG9jYXRpb25GaWVsZC5zZXRUZXh0KGZpbGVuYW1lKTsKCQkJCX0KCQkJfQoJCX0pOwoKCQlhcmd1bWVudHNCcm93c2VWYXJpYWJsZS5hZGRTZWxlY3Rpb25MaXN0ZW5lcihuZXcgU2VsZWN0aW9uQWRhcHRlcigpIHsKCQkJcHVibGljIHZvaWQgd2lkZ2V0U2VsZWN0ZWQoU2VsZWN0aW9uRXZlbnQgZSkgewoJCQkJVmFyaWFibGVTZWxlY3Rpb25EaWFsb2cgZGlhbG9nOwoJCQkJZGlhbG9nID0gbmV3IFZhcmlhYmxlU2VsZWN0aW9uRGlhbG9nKGdldFNoZWxsKCkpOwoJCQkJZGlhbG9nLm9wZW4oKTsKCQkJCU9iamVjdFtdIHJlc3VsdHMgPSBkaWFsb2cuZ2V0UmVzdWx0KCk7CgkJCQlpZiAocmVzdWx0cyA9PSBudWxsIHx8IHJlc3VsdHMubGVuZ3RoIDwgMSkKCQkJCQlyZXR1cm47CgkJCQlTdHJpbmcgYXJncyA9IGFyZ3VtZW50c0ZpZWxkLmdldFRleHQoKTsKCQkJCWFyZ3MgPSBhcmdzICsgKFN0cmluZylyZXN1bHRzWzBdOwoJCQkJYXJndW1lbnRzRmllbGQuc2V0VGV4dChhcmdzKTsKCQkJfQoJCX0pOwoJCQoJCWRpcmVjdG9yeUJyb3dzZUJ1dHRvbi5hZGRTZWxlY3Rpb25MaXN0ZW5lcihuZXcgU2VsZWN0aW9uQWRhcHRlcigpIHsKCQkJcHVibGljIHZvaWQgd2lkZ2V0U2VsZWN0ZWQoU2VsZWN0aW9uRXZlbnQgZSkgewoJCQkJRGlyZWN0b3J5U2VsZWN0aW9uRGlhbG9nIGRpYWxvZyA9IG5ldyBEaXJlY3RvcnlTZWxlY3Rpb25EaWFsb2coZ2V0U2hlbGwoKSk7CgkJCQlkaWFsb2cub3BlbigpOwoJCQkJT2JqZWN0W10gcmVzdWx0cyA9IGRpYWxvZy5nZXRSZXN1bHQoKTsKCQkJCVN0cmluZyBzZWxlY3RlZERpcmVjdG9yeSA9IG51bGw7CgkJCQlpZiAocmVzdWx0cyAhPSBudWxsICYmIHJlc3VsdHMubGVuZ3RoID4gMCkKCQkJCQlzZWxlY3RlZERpcmVjdG9yeSA9IChTdHJpbmcpcmVzdWx0c1swXTsKCQkJCWlmIChzZWxlY3RlZERpcmVjdG9yeSAhPSBudWxsKSB7CgkJCQkJZGlyZWN0b3J5RmllbGQuc2V0VGV4dChzZWxlY3RlZERpcmVjdG9yeSk7CgkJCQl9CgkJCX0KCQl9KTsKCgkJcmVmcmVzaE9wdGlvbkJ1dHRvbi5hZGRTZWxlY3Rpb25MaXN0ZW5lcihuZXcgU2VsZWN0aW9uQWRhcHRlcigpIHsKCQkJcHVibGljIHZvaWQgd2lkZ2V0U2VsZWN0ZWQoU2VsZWN0aW9uRXZlbnQgZSkgewoJCQkJUmVmcmVzaFNlbGVjdGlvbkRpYWxvZyBkaWFsb2c7CgkJCQlkaWFsb2cgPSBuZXcgUmVmcmVzaFNlbGVjdGlvbkRpYWxvZyhnZXRTaGVsbCgpKTsKCQkJCWRpYWxvZy5vcGVuKCk7CgkJCQlPYmplY3RbXSByZXN1bHRzID0gZGlhbG9nLmdldFJlc3VsdCgpOwoJCQkJaWYgKHJlc3VsdHMgPT0gbnVsbCB8fCByZXN1bHRzLmxlbmd0aCA8IDEpCgkJCQkJcmV0dXJuOwoJCQkJcmVmcmVzaFNjb3BlID0gKFN0cmluZylyZXN1bHRzWzBdOwoJCQkJdXBkYXRlUmVmcmVzaEZpZWxkKCk7CgkJCX0KCQl9KTsKCX0KCQoJLyoqCgkgKiBIb29rcyB0aGUgbmVjZXNzYXJ5IGZpZWxkIHZhbGlkYXRpb24KCSAqLwoJcHJpdmF0ZSB2b2lkIGhvb2tGaWVsZFZhbGlkYXRpb24oKSB7CgkJbmFtZUZpZWxkLmFkZE1vZGlmeUxpc3RlbmVyKG5ldyBNb2RpZnlMaXN0ZW5lcigpIHsKCQkJcHVibGljIHZvaWQgbW9kaWZ5VGV4dChNb2RpZnlFdmVudCBlKSB7CgkJCQl2YWxpZGF0ZUZpZWxkcygpOwoJCQl9CgkJfSk7CgkJCgkJbG9jYXRpb25GaWVsZC5hZGRNb2RpZnlMaXN0ZW5lcihuZXcgTW9kaWZ5TGlzdGVuZXIoKSB7CgkJCXB1YmxpYyB2b2lkIG1vZGlmeVRleHQoTW9kaWZ5RXZlbnQgZSkgewoJCQkJdmFsaWRhdGVGaWVsZHMoKTsKCQkJfQoJCX0pOwoJCQoJCWRpcmVjdG9yeUZpZWxkLmFkZE1vZGlmeUxpc3RlbmVyKG5ldyBNb2RpZnlMaXN0ZW5lcigpIHsKCQkJcHVibGljIHZvaWQgbW9kaWZ5VGV4dChNb2RpZnlFdmVudCBlKSB7CgkJCQl2YWxpZGF0ZUZpZWxkcygpOwoJCQl9CgkJfSk7Cgl9CgoJLyoqCgkgKiBWYWxpZGF0ZSB0aGUgZmllbGRzIGZvciBhY2NlcHRhYmxlIHZhbHVlcwoJICovCglwcml2YXRlIHZvaWQgdmFsaWRhdGVGaWVsZHMoKSB7CgkJU3RyaW5nIHZhbHVlID0gbmFtZUZpZWxkLmdldFRleHQoKS50cmltKCk7CgkJaWYgKHZhbHVlLmxlbmd0aCgpIDwgMSkgewoJCQlzZXRNZXNzYWdlKFRvb2xNZXNzYWdlcy5nZXRTdHJpbmcoIkVkaXREaWFsb2cubm9Ub29sTmFtZSIpLCBJTWVzc2FnZVByb3ZpZGVyLk5PTkUpOyAvLyROT04tTkxTLTEkCgkJCWdldEJ1dHRvbihJRGlhbG9nQ29uc3RhbnRzLk9LX0lEKS5zZXRFbmFibGVkKGZhbHNlKTsKCQkJcmV0dXJuOwoJCX0KCQkKCQl2YWx1ZSA9IGxvY2F0aW9uRmllbGQuZ2V0VGV4dCgpLnRyaW0oKTsKCQlpZiAodmFsdWUubGVuZ3RoKCkgPCAxKSB7CgkJCXNldE1lc3NhZ2UoVG9vbE1lc3NhZ2VzLmdldFN0cmluZygiRWRpdERpYWxvZy5ub1Rvb2xMb2NhdGlvbiIpLCBJTWVzc2FnZVByb3ZpZGVyLk5PTkUpOyAvLyROT04tTkxTLTEkCgkJCWdldEJ1dHRvbihJRGlhbG9nQ29uc3RhbnRzLk9LX0lEKS5zZXRFbmFibGVkKGZhbHNlKTsKCQkJcmV0dXJuOwoJCX0KCgkJZ2V0QnV0dG9uKElEaWFsb2dDb25zdGFudHMuT0tfSUQpLnNldEVuYWJsZWQodHJ1ZSk7CgkJCgkJLy8gVHJhbnNsYXRlIGZpZWxkIGNvbnRlbnRzIHRvIHRoZSBhY3R1YWwgZmlsZSBsb2NhdGlvbiBzbyB3ZQoJCS8vIGNhbiBjaGVjayB0byBlbnN1cmUgdGhlIGZpbGUgYWN0dWFsbHkgZXhpc3RzLgoJCXZhbHVlID0gVG9vbFV0aWwuZ2V0TG9jYXRpb25Gcm9tVGV4dCh2YWx1ZSk7CgkJCgkJaWYgKHZhbHVlID09IG51bGwpIHsgLy8gVGhlIHJlc291cmNlIGNvdWxkIG5vdCBiZSBmb3VuZC4KCQkJc2V0TWVzc2FnZShUb29sTWVzc2FnZXMuZ2V0U3RyaW5nKCJFZGl0RGlhbG9nLm1pc3NpbmdUb29sTG9jYXRpb24iKSwgSU1lc3NhZ2VQcm92aWRlci5XQVJOSU5HKTsgLy8kTk9OLU5MUy0xJAoJCQlyZXR1cm47CQkJCgkJfQoJCUZpbGUgZmlsZSA9IG5ldyBGaWxlKHZhbHVlKTsKCQlpZiAoIWZpbGUuZXhpc3RzKCkpIHsgLy8gVGhlIGZpbGUgZG9lcyBub3QgZXhpc3QuCgkJCXNldE1lc3NhZ2UoVG9vbE1lc3NhZ2VzLmdldFN0cmluZygiRWRpdERpYWxvZy5taXNzaW5nVG9vbExvY2F0aW9uIiksIElNZXNzYWdlUHJvdmlkZXIuV0FSTklORyk7IC8vJE5PTi1OTFMtMSQKCQkJcmV0dXJuOwoJCX0KCQlTdHJpbmcgZmlsZU5hbWUgPSB2YWx1ZTsKCQkKCQl2YWx1ZSA9IGRpcmVjdG9yeUZpZWxkLmdldFRleHQoKS50cmltKCk7CgkJaWYgKHZhbHVlLmxlbmd0aCgpID4gMCkgewoJCQkvLyBUcmFuc2xhdGUgZmllbGQgY29udGVudHMgdG8gdGhlIGFjdHVhbCBkaXJlY3RvcnkgbG9jYXRpb24gc28gd2UKCQkJLy8gY2FuIGNoZWNrIHRvIGVuc3VyZSB0aGUgZGlyZWN0b3J5IGFjdHVhbGx5IGV4aXN0cy4KCQkJdmFsdWUgPSBUb29sVXRpbC5nZXRMb2NhdGlvbkZyb21UZXh0KHZhbHVlKTsKCQkJCgkJCWlmICh2YWx1ZSA9PSBudWxsKSB7IC8vIFRoZSByZXNvdXJjZSBjb3VsZCBub3QgYmUgZm91bmQuCgkJCQlzZXRNZXNzYWdlKFRvb2xNZXNzYWdlcy5nZXRTdHJpbmcoIkVkaXREaWFsb2cubWlzc2luZ1Rvb2xEaXJlY3RvcnkiKSwgSU1lc3NhZ2VQcm92aWRlci5XQVJOSU5HKTsgLy8kTk9OLU5MUy0xJAoJCQkJcmV0dXJuOwkJCQoJCQl9CQkJCgkJCWZpbGUgPSBuZXcgRmlsZSh2YWx1ZSk7CgkJCWlmICghZmlsZS5leGlzdHMoKSkgeyAvLyBUaGUgZGlyZWN0b3J5IGRvZXMgbm90IGV4aXN0LgoJCQkJc2V0TWVzc2FnZShUb29sTWVzc2FnZXMuZ2V0U3RyaW5nKCJFZGl0RGlhbG9nLm1pc3NpbmdUb29sRGlyZWN0b3J5IiksIElNZXNzYWdlUHJvdmlkZXIuV0FSTklORyk7IC8vJE5PTi1OTFMtMSQKCQkJCXJldHVybjsKCQkJfQoJCX0KCQkKCQlpZiAoZmlsZU5hbWUuZW5kc1dpdGgoIi54bWwiKSkgeyAvLyROT04tTkxTLTEkCgkJCXNldE1lc3NhZ2UoVG9vbE1lc3NhZ2VzLmdldFN0cmluZygiRWRpdERpYWxvZy5ob3dUb1NlbGVjdEFudFRhcmdldHMiKSwgSU1lc3NhZ2VQcm92aWRlci5JTkZPUk1BVElPTik7IC8vJE5PTi1OTFMtMSQKCQkJcmV0dXJuOwoJCX0KCQkKCQlpZiAoZWRpdE1vZGUpCgkJCXNldE1lc3NhZ2UoVG9vbE1lc3NhZ2VzLmdldFN0cmluZygiRWRpdERpYWxvZy5lZGl0RGlhbG9nTWVzc2FnZSIpKTsgLy8kTk9OLU5MUy0xJAoJCWVsc2UKCQkJc2V0TWVzc2FnZShUb29sTWVzc2FnZXMuZ2V0U3RyaW5nKCJFZGl0RGlhbG9nLm5ld0RpYWxvZ01lc3NhZ2UiKSk7IC8vJE5PTi1OTFMtMSQKCX0KCQoJLyogKG5vbi1KYXZhZG9jKQoJICogTWV0aG9kIGRlY2xhcmVkIG9uIERpYWxvZy4KCSAqLwoJcHJvdGVjdGVkIHZvaWQgb2tQcmVzc2VkKCkgewoJCVN0cmluZyBjb21tYW5kID0gbG9jYXRpb25GaWVsZC5nZXRUZXh0KCkudHJpbSgpOwoJCVN0cmluZyB2YWx1ZSA9IFRvb2xVdGlsLmdldExvY2F0aW9uRnJvbVRleHQoY29tbWFuZCk7CgkJaWYgKHZhbHVlICE9IG51bGwgJiYgdmFsdWUuZW5kc1dpdGgoIi54bWwiKSkgLy8kTk9OLU5MUy0xJAoJCQl0b29sLnNldFR5cGUodG9vbC5UT09MX1RZUEVfQU5UKTsKCQllbHNlCgkJCXRvb2wuc2V0VHlwZSh0b29sLlRPT0xfVFlQRV9QUk9HUkFNKTsKCQl0b29sLnNldE5hbWUobmFtZUZpZWxkLmdldFRleHQoKS50cmltKCkpOwoJCXRvb2wuc2V0TG9jYXRpb24oY29tbWFuZCk7CgkJdG9vbC5zZXRBcmd1bWVudHMoYXJndW1lbnRzRmllbGQuZ2V0VGV4dCgpLnRyaW0oKSk7CgkJdG9vbC5zZXRXb3JraW5nRGlyZWN0b3J5KGRpcmVjdG9yeUZpZWxkLmdldFRleHQoKS50cmltKCkpOwoJCXRvb2wuc2V0UmVmcmVzaFNjb3BlKHJlZnJlc2hTY29wZSk7CgkJdG9vbC5zZXRTaG93TG9nKHNob3dMb2cuZ2V0U2VsZWN0aW9uKCkpOwoJCQoJCXN1cGVyLm9rUHJlc3NlZCgpOwoJfQoJCgkvKioKCSAqIFVwZGF0ZSB0aGUgcmVmcmVzaCBzY29wZSBmaWVsZAoJICovCglwcml2YXRlIHZvaWQgdXBkYXRlUmVmcmVzaEZpZWxkKCkgewoJCVRvb2xVdGlsLlZhcmlhYmxlRGVmaW5pdGlvbiByZXN1bHQgPSBUb29sVXRpbC5leHRyYWN0VmFyaWFibGVUYWcocmVmcmVzaFNjb3BlLCAwKTsKCQlpZiAocmVzdWx0Lm5hbWUgPT0gbnVsbCkgewoJCQlyZWZyZXNoU2NvcGUgPSBUb29sVXRpbC5idWlsZFZhcmlhYmxlVGFnKHRvb2wuUkVGUkVTSF9TQ09QRV9OT05FLCBudWxsKTsKCQkJcmVzdWx0Lm5hbWUgPSB0b29sLlJFRlJFU0hfU0NPUEVfTk9ORTsKCQl9CgkJCgkJaWYgKHRvb2wuUkVGUkVTSF9TQ09QRV9OT05FLmVxdWFscyhyZXN1bHQubmFtZSkpIHsKCQkJcmVmcmVzaEZpZWxkLnNldFRleHQoVG9vbE1lc3NhZ2VzLmdldFN0cmluZygiRWRpdERpYWxvZy5yZWZyZXNoU2NvcGVOb25lIikpOyAvLyROT04tTkxTLTEkCgkJCXJldHVybjsKCQl9CgkJaWYgKHRvb2wuUkVGUkVTSF9TQ09QRV9XT1JLU1BBQ0UuZXF1YWxzKHJlc3VsdC5uYW1lKSkgewoJCQlyZWZyZXNoRmllbGQuc2V0VGV4dChUb29sTWVzc2FnZXMuZ2V0U3RyaW5nKCJFZGl0RGlhbG9nLnJlZnJlc2hTY29wZVdvcmtzcGFjZSIpKTsgLy8kTk9OLU5MUy0xJAoJCQlyZXR1cm47CgkJfQoJCWlmICh0b29sLlJFRlJFU0hfU0NPUEVfUFJPSkVDVC5lcXVhbHMocmVzdWx0Lm5hbWUpKSB7CgkJCWlmIChyZXN1bHQuYXJndW1lbnQgPT0gbnVsbCkKCQkJCXJlZnJlc2hGaWVsZC5zZXRUZXh0KFRvb2xNZXNzYWdlcy5nZXRTdHJpbmcoIkVkaXREaWFsb2cucmVmcmVzaFNjb3BlUHJvamVjdCIpKTsgLy8kTk9OLU5MUy0xJAoJCQllbHNlCgkJCQlyZWZyZXNoRmllbGQuc2V0VGV4dChUb29sTWVzc2FnZXMuZm9ybWF0KCJFZGl0RGlhbG9nLnJlZnJlc2hTY29wZVByb2plY3RYIiwgbmV3IE9iamVjdFtdIHtyZXN1bHQuYXJndW1lbnR9KSk7IC8vJE5PTi1OTFMtMSQKCQkJcmV0dXJuOwoJCX0KCQlpZiAodG9vbC5SRUZSRVNIX1NDT1BFX1dPUktJTkdfU0VULmVxdWFscyhyZXN1bHQubmFtZSkpIHsKCQkJaWYgKHJlc3VsdC5hcmd1bWVudCA9PSBudWxsKSB7CgkJCQlyZWZyZXNoU2NvcGUgPSBUb29sVXRpbC5idWlsZFZhcmlhYmxlVGFnKHRvb2wuUkVGUkVTSF9TQ09QRV9OT05FLCBudWxsKTsKCQkJCXJlZnJlc2hGaWVsZC5zZXRUZXh0KFRvb2xNZXNzYWdlcy5nZXRTdHJpbmcoIkVkaXREaWFsb2cucmVmcmVzaFNjb3BlTm9uZSIpKTsgLy8kTk9OLU5MUy0xJAoJCQl9CgkJCWVsc2UKCQkJCXJlZnJlc2hGaWVsZC5zZXRUZXh0KFRvb2xNZXNzYWdlcy5mb3JtYXQoIkVkaXREaWFsb2cucmVmcmVzaFNjb3BlV29ya2luZ1NldCIsIG5ldyBPYmplY3RbXSB7cmVzdWx0LmFyZ3VtZW50fSkpOyAvLyROT04tTkxTLTEkCgkJCXJldHVybjsKCQl9Cgl9CgkKCS8qKgoJICogSW50ZXJuYWwgZGlhbG9nIHRvIHNob3cgYXZhaWxhYmxlIHJlc291cmNlcyBmcm9tIHdoaWNoCgkgKiB0aGUgdXNlciBjYW4gc2VsZWN0IG9uZQoJICovCglwcml2YXRlIGNsYXNzIFJlc291cmNlU2VsZWN0aW9uRGlhbG9nIGV4dGVuZHMgU2VsZWN0aW9uRGlhbG9nIHsKCQlTdHJpbmcgbGFiZWxUZXh0OwoJCUlDb250YWluZXIgcm9vdDsKCQlUcmVlVmlld2VyIHdzVHJlZTsKCQkKCQlwdWJsaWMgUmVzb3VyY2VTZWxlY3Rpb25EaWFsb2coU2hlbGwgcGFyZW50LCBJQ29udGFpbmVyIHJvb3QsIFN0cmluZyBsYWJlbFRleHQpIHsKCQkJc3VwZXIocGFyZW50KTsKCQkJdGhpcy5yb290ID0gcm9vdDsKCQkJdGhpcy5sYWJlbFRleHQgPSBsYWJlbFRleHQ7CgkJCXNldFNoZWxsU3R5bGUoZ2V0U2hlbGxTdHlsZSgpIHwgU1dULlJFU0laRSk7CgkJCXNldFRpdGxlKFRvb2xNZXNzYWdlcy5nZXRTdHJpbmcoIkVkaXREaWFsb2cuYnJvd3NlV29ya3NwYWNlVGl0bGUiKSk7IC8vJE5PTi1OTFMtMSQKCQkJV29ya2JlbmNoSGVscC5zZXRIZWxwKHBhcmVudCwgSUhlbHBDb250ZXh0SWRzLlJFU09VUkNFX1NFTEVDVElPTl9ESUFMT0cpOwoJCX0KCgkJLyogKG5vbi1KYXZhZG9jKQoJCSAqIE1ldGhvZCBkZWNsYXJlZCBvbiBEaWFsb2cuCgkJICovCgkJcHJvdGVjdGVkIENvbnRyb2wgY3JlYXRlRGlhbG9nQXJlYShDb21wb3NpdGUgcGFyZW50KSB7CgkJCS8vIGNyZWF0ZSBjb21wb3NpdGUgCgkJCUNvbXBvc2l0ZSBkaWFsb2dBcmVhID0gKENvbXBvc2l0ZSlzdXBlci5jcmVhdGVEaWFsb2dBcmVhKHBhcmVudCk7CgkJCQoJCQlMYWJlbCBsYWJlbCA9IG5ldyBMYWJlbChkaWFsb2dBcmVhLCBTV1QuTEVGVCk7CgkJCWxhYmVsLnNldFRleHQobGFiZWxUZXh0KTsKCQkJCgkJCVRyZWUgdHJlZSA9IG5ldyBUcmVlKGRpYWxvZ0FyZWEsIFNXVC5IX1NDUk9MTCB8IFNXVC5WX1NDUk9MTCB8IFNXVC5TSU5HTEUgfCBTV1QuQk9SREVSKTsKCQkJR3JpZERhdGEgZGF0YSA9IG5ldyBHcmlkRGF0YShHcmlkRGF0YS5GSUxMX0JPVEgpOwoJCQlkYXRhLmhlaWdodEhpbnQgPSBTSVpJTkdfU0VMRUNUSU9OX1BBTkVfSEVJR0hUOwoJCQlkYXRhLndpZHRoSGludCA9IFNJWklOR19TRUxFQ1RJT05fUEFORV9XSURUSDsKCQkJdHJlZS5zZXRMYXlvdXREYXRhKGRhdGEpOwoJCQl3c1RyZWUgPSBuZXcgVHJlZVZpZXdlcih0cmVlKTsKCQkJd3NUcmVlLnNldENvbnRlbnRQcm92aWRlcihuZXcgV29ya2JlbmNoQ29udGVudFByb3ZpZGVyKCkpOwoJCQl3c1RyZWUuc2V0TGFiZWxQcm92aWRlcihuZXcgV29ya2JlbmNoTGFiZWxQcm92aWRlcigpKTsKCQkJd3NUcmVlLnNldElucHV0KHJvb3QpOwoJCQkKCQkJcmV0dXJuIGRpYWxvZ0FyZWE7CgkJfQoJCQoJCS8qIChub24tSmF2YWRvYykKCQkgKiBNZXRob2QgZGVjbGFyZWQgb24gRGlhbG9nLgoJCSAqLwoJCXByb3RlY3RlZCB2b2lkIG9rUHJlc3NlZCgpIHsKCQkJSVN0cnVjdHVyZWRTZWxlY3Rpb24gc2VsID0gKElTdHJ1Y3R1cmVkU2VsZWN0aW9uKXdzVHJlZS5nZXRTZWxlY3Rpb24oKTsKCQkJaWYgKHNlbCAhPSBudWxsKQoJCQkJc2V0U2VsZWN0aW9uUmVzdWx0KHNlbC50b0FycmF5KCkpOwoJCQlzdXBlci5va1ByZXNzZWQoKTsKCQl9Cgl9CgoKCS8qKgoJICogSW50ZXJuYWwgZGlhbG9nIHRvIHNob3cgYXZhaWxhYmxlIHZhcmlhYmxlcyBmcm9tIHdoaWNoCgkgKiB0aGUgdXNlciBjYW4gc2VsZWN0IG9uZS4KCSAqLwoJcHJpdmF0ZSBjbGFzcyBWYXJpYWJsZVNlbGVjdGlvbkRpYWxvZyBleHRlbmRzIFNlbGVjdGlvbkRpYWxvZyB7CgkJU3RyaW5nIGxvY2F0aW9uOwoJCUxpc3QgbGlzdDsKCQkKCQlwdWJsaWMgVmFyaWFibGVTZWxlY3Rpb25EaWFsb2coU2hlbGwgcGFyZW50KSB7CgkJCXN1cGVyKHBhcmVudCk7CgkJCXNldFRpdGxlKFRvb2xNZXNzYWdlcy5nZXRTdHJpbmcoIkVkaXREaWFsb2cuYnJvd3NlVmFyVGl0bGUiKSk7IC8vJE5PTi1OTFMtMSQKCQkJV29ya2JlbmNoSGVscC5zZXRIZWxwKHBhcmVudCwgSUhlbHBDb250ZXh0SWRzLlZBUklBQkxFX1NFTEVDVElPTl9ESUFMT0cpOwoJCX0KCgkJLyogKG5vbi1KYXZhZG9jKQoJCSAqIE1ldGhvZCBkZWNsYXJlZCBvbiBEaWFsb2cuCgkJICovCgkJcHJvdGVjdGVkIENvbnRyb2wgY3JlYXRlRGlhbG9nQXJlYShDb21wb3NpdGUgcGFyZW50KSB7CgkJCS8vIGNyZWF0ZSBjb21wb3NpdGUgCgkJCUNvbXBvc2l0ZSBkaWFsb2dBcmVhID0gKENvbXBvc2l0ZSlzdXBlci5jcmVhdGVEaWFsb2dBcmVhKHBhcmVudCk7CgkJCQoJCQlMYWJlbCBsYWJlbCA9IG5ldyBMYWJlbChkaWFsb2dBcmVhLCBTV1QuTEVGVCk7CgkJCWxhYmVsLnNldFRleHQoVG9vbE1lc3NhZ2VzLmdldFN0cmluZygiRWRpdERpYWxvZy5zZWxlY3RWYXIiKSk7IC8vJE5PTi1OTFMtMSQKCQkJCgkJCWxpc3QgPSBuZXcgTGlzdChkaWFsb2dBcmVhLCBTV1QuSF9TQ1JPTEwgfCBTV1QuVl9TQ1JPTEwgfCBTV1QuU0lOR0xFIHwgU1dULkJPUkRFUik7CgkJCUdyaWREYXRhIGRhdGEgPSBuZXcgR3JpZERhdGEoR3JpZERhdGEuRklMTF9CT1RIKTsKCQkJZGF0YS5oZWlnaHRIaW50ID0gU0laSU5HX1NFTEVDVElPTl9QQU5FX0hFSUdIVDsKCQkJZGF0YS53aWR0aEhpbnQgPSBTSVpJTkdfU0VMRUNUSU9OX1BBTkVfV0lEVEg7CgkJCWxpc3Quc2V0TGF5b3V0RGF0YShkYXRhKTsKCgkJCWxpc3QuYWRkKFRvb2xNZXNzYWdlcy5nZXRTdHJpbmcoIkVkaXREaWFsb2cudmFyV29ya3NwYWNlTG9jTGFiZWwiKSk7IC8vJE5PTi1OTFMtMSQKCQkJbGlzdC5hZGQoVG9vbE1lc3NhZ2VzLmdldFN0cmluZygiRWRpdERpYWxvZy52YXJQcm9qZWN0TG9jTGFiZWwiKSk7IC8vJE5PTi1OTFMtMSQKCQkJbGlzdC5hZGQoVG9vbE1lc3NhZ2VzLmdldFN0cmluZygiRWRpdERpYWxvZy52YXJDb250YWluZXJMb2NMYWJlbCIpKTsgLy8kTk9OLU5MUy0xJAoJCQlsaXN0LmFkZChUb29sTWVzc2FnZXMuZ2V0U3RyaW5nKCJFZGl0RGlhbG9nLnZhclJlc291cmNlTG9jTGFiZWwiKSk7IC8vJE5PTi1OTFMtMSQKCQkJbGlzdC5hZGQoVG9vbE1lc3NhZ2VzLmdldFN0cmluZygiRWRpdERpYWxvZy52YXJQcm9qZWN0UGF0aExhYmVsIikpOyAvLyROT04tTkxTLTEkCgkJCWxpc3QuYWRkKFRvb2xNZXNzYWdlcy5nZXRTdHJpbmcoIkVkaXREaWFsb2cudmFyQ29udGFpbmVyUGF0aExhYmVsIikpOyAvLyROT04tTkxTLTEkCgkJCWxpc3QuYWRkKFRvb2xNZXNzYWdlcy5nZXRTdHJpbmcoIkVkaXREaWFsb2cudmFyUmVzb3VyY2VQYXRoTGFiZWwiKSk7IC8vJE5PTi1OTFMtMSQKCQkJbGlzdC5hZGQoVG9vbE1lc3NhZ2VzLmdldFN0cmluZygiRWRpdERpYWxvZy52YXJQcm9qZWN0TmFtZUxhYmVsIikpOyAvLyROT04tTkxTLTEkCgkJCWxpc3QuYWRkKFRvb2xNZXNzYWdlcy5nZXRTdHJpbmcoIkVkaXREaWFsb2cudmFyQ29udGFpbmVyTmFtZUxhYmVsIikpOyAvLyROT04tTkxTLTEkCQoJCQlsaXN0LmFkZChUb29sTWVzc2FnZXMuZ2V0U3RyaW5nKCJFZGl0RGlhbG9nLnZhclJlc291cmNlTmFtZUxhYmVsIikpOyAvLyROT04tTkxTLTEkCgkJCWxpc3QuYWRkKFRvb2xNZXNzYWdlcy5nZXRTdHJpbmcoIkVkaXREaWFsb2cudmFyUHJvamVjdFhMb2NMYWJlbCIpKTsgLy8kTk9OLU5MUy0xJAoJCQlsaXN0LmFkZChUb29sTWVzc2FnZXMuZ2V0U3RyaW5nKCJFZGl0RGlhbG9nLnZhckNvbnRhaW5lclhMb2NMYWJlbCIpKTsgLy8kTk9OLU5MUy0xJAoJCQlsaXN0LmFkZChUb29sTWVzc2FnZXMuZ2V0U3RyaW5nKCJFZGl0RGlhbG9nLnZhclJlc291cmNlWExvY0xhYmVsIikpOyAvLyROT04tTkxTLTEkCgkJCWxpc3QuYWRkKFRvb2xNZXNzYWdlcy5nZXRTdHJpbmcoIkVkaXREaWFsb2cudmFyUHJvamVjdFhQYXRoTGFiZWwiKSk7IC8vJE5PTi1OTFMtMSQJCgkJCWxpc3QuYWRkKFRvb2xNZXNzYWdlcy5nZXRTdHJpbmcoIkVkaXREaWFsb2cudmFyQ29udGFpbmVyWFBhdGhMYWJlbCIpKTsgLy8kTk9OLU5MUy0xJAoJCQlsaXN0LmFkZChUb29sTWVzc2FnZXMuZ2V0U3RyaW5nKCJFZGl0RGlhbG9nLnZhclJlc291cmNlWFBhdGhMYWJlbCIpKTsgLy8kTk9OLU5MUy0xJAoJCQlsaXN0LmFkZChUb29sTWVzc2FnZXMuZ2V0U3RyaW5nKCJFZGl0RGlhbG9nLnZhclByb2plY3RYTmFtZUxhYmVsIikpOyAvLyROT04tTkxTLTEkCgkJCWxpc3QuYWRkKFRvb2xNZXNzYWdlcy5nZXRTdHJpbmcoIkVkaXREaWFsb2cudmFyQ29udGFpbmVyWE5hbWVMYWJlbCIpKTsgLy8kTk9OLU5MUy0xJAoJCQlsaXN0LmFkZChUb29sTWVzc2FnZXMuZ2V0U3RyaW5nKCJFZGl0RGlhbG9nLnZhclJlc291cmNlWE5hbWVMYWJlbCIpKTsgLy8kTk9OLU5MUy0xJAkKCQkJbGlzdC5hZGQoVG9vbE1lc3NhZ2VzLmdldFN0cmluZygiRWRpdERpYWxvZy52YXJCdWlsZFR5cGVOYW1lTGFiZWwiKSk7IC8vJE5PTi1OTFMtMSQJCgoJCQlsb2NhdGlvbiA9IFRvb2xVdGlsLmdldExvY2F0aW9uRnJvbVRleHQobG9jYXRpb25GaWVsZC5nZXRUZXh0KCkudHJpbSgpKTsKCQkJaWYgKGxvY2F0aW9uICE9IG51bGwgJiYgbG9jYXRpb24uZW5kc1dpdGgoIi54bWwiKSkgeyAvLyROT04tTkxTLTEkCgkJCQlsaXN0LmFkZChUb29sTWVzc2FnZXMuZ2V0U3RyaW5nKCJFZGl0RGlhbG9nLnZhckFudFRhcmdldExhYmVsIikpOyAvLyROT04tTkxTLTEkCgkJCX0JCQoJCQkKCQkJcmV0dXJuIGRpYWxvZ0FyZWE7CgkJfQoJCQoJCS8qIChub24tSmF2YWRvYykKCQkgKiBNZXRob2QgZGVjbGFyZWQgb24gRGlhbG9nLgoJCSAqLwoJCXByb3RlY3RlZCB2b2lkIG9rUHJlc3NlZCgpIHsKCQkJaW50IHNlbCA9IGxpc3QuZ2V0U2VsZWN0aW9uSW5kZXgoKTsKCQkJU3RyaW5nIHJlc3VsdCA9IG51bGw7CgkJCQoJCQlzd2l0Y2ggKHNlbCkgewoJCQkJY2FzZSAwIDoKCQkJCQlyZXN1bHQgPSBUb29sVXRpbC5idWlsZFZhcmlhYmxlVGFnKEV4dGVybmFsVG9vbC5WQVJfV09SS1NQQUNFX0xPQywgbnVsbCk7CgkJCQkJYnJlYWs7CgoJCQkJY2FzZSAxIDoKCQkJCQlyZXN1bHQgPSBUb29sVXRpbC5idWlsZFZhcmlhYmxlVGFnKEV4dGVybmFsVG9vbC5WQVJfUFJPSkVDVF9MT0MsIG51bGwpOwoJCQkJCWJyZWFrOwoKCQkJCWNhc2UgMiA6CgkJCQkJcmVzdWx0ID0gVG9vbFV0aWwuYnVpbGRWYXJpYWJsZVRhZyhFeHRlcm5hbFRvb2wuVkFSX0NPTlRBSU5FUl9MT0MsIG51bGwpOwoJCQkJCWJyZWFrOwoKCQkJCWNhc2UgMyA6CgkJCQkJcmVzdWx0ID0gVG9vbFV0aWwuYnVpbGRWYXJpYWJsZVRhZyhFeHRlcm5hbFRvb2wuVkFSX1JFU09VUkNFX0xPQywgbnVsbCk7CgkJCQkJYnJlYWs7CgoJCQkJY2FzZSA0IDoKCQkJCQlyZXN1bHQgPSBUb29sVXRpbC5idWlsZFZhcmlhYmxlVGFnKEV4dGVybmFsVG9vbC5WQVJfUFJPSkVDVF9QQVRILCBudWxsKTsKCQkJCQlicmVhazsKCgkJCQljYXNlIDUgOgoJCQkJCXJlc3VsdCA9IFRvb2xVdGlsLmJ1aWxkVmFyaWFibGVUYWcoRXh0ZXJuYWxUb29sLlZBUl9DT05UQUlORVJfUEFUSCwgbnVsbCk7CgkJCQkJYnJlYWs7CgoJCQkJY2FzZSA2IDoKCQkJCQlyZXN1bHQgPSBUb29sVXRpbC5idWlsZFZhcmlhYmxlVGFnKEV4dGVybmFsVG9vbC5WQVJfUkVTT1VSQ0VfUEFUSCwgbnVsbCk7CgkJCQkJYnJlYWs7CgoJCQkJY2FzZSA3IDoKCQkJCQlyZXN1bHQgPSBUb29sVXRpbC5idWlsZFZhcmlhYmxlVGFnKEV4dGVybmFsVG9vbC5WQVJfUFJPSkVDVF9OQU1FLCBudWxsKTsKCQkJCQlicmVhazsKCgkJCQljYXNlIDggOgoJCQkJCXJlc3VsdCA9IFRvb2xVdGlsLmJ1aWxkVmFyaWFibGVUYWcoRXh0ZXJuYWxUb29sLlZBUl9DT05UQUlORVJfTkFNRSwgbnVsbCk7CgkJCQkJYnJlYWs7CgoJCQkJY2FzZSA5IDoKCQkJCQlyZXN1bHQgPSBUb29sVXRpbC5idWlsZFZhcmlhYmxlVGFnKEV4dGVybmFsVG9vbC5WQVJfUkVTT1VSQ0VfTkFNRSwgbnVsbCk7CgkJCQkJYnJlYWs7CgoJCQkJY2FzZSAxMCA6CgkJCQkJcmVzdWx0ID0gc2hvd1Jlc291cmNlRGlhbG9nKEV4dGVybmFsVG9vbC5WQVJfUFJPSkVDVF9MT0MpOwoJCQkJCWJyZWFrOwoKCQkJCWNhc2UgMTEgOgoJCQkJCXJlc3VsdCA9IHNob3dSZXNvdXJjZURpYWxvZyhFeHRlcm5hbFRvb2wuVkFSX0NPTlRBSU5FUl9MT0MpOwoJCQkJCWJyZWFrOwoKCQkJCWNhc2UgMTIgOgoJCQkJCXJlc3VsdCA9IHNob3dSZXNvdXJjZURpYWxvZyhFeHRlcm5hbFRvb2wuVkFSX1JFU09VUkNFX0xPQyk7CgkJCQkJYnJlYWs7CgoJCQkJY2FzZSAxMyA6CgkJCQkJcmVzdWx0ID0gc2hvd1Jlc291cmNlRGlhbG9nKEV4dGVybmFsVG9vbC5WQVJfUFJPSkVDVF9QQVRIKTsKCQkJCQlicmVhazsKCgkJCQljYXNlIDE0IDoKCQkJCQlyZXN1bHQgPSBzaG93UmVzb3VyY2VEaWFsb2coRXh0ZXJuYWxUb29sLlZBUl9DT05UQUlORVJfUEFUSCk7CgkJCQkJYnJlYWs7CgoJCQkJY2FzZSAxNSA6CgkJCQkJcmVzdWx0ID0gc2hvd1Jlc291cmNlRGlhbG9nKEV4dGVybmFsVG9vbC5WQVJfUkVTT1VSQ0VfUEFUSCk7CgkJCQkJYnJlYWs7CgoJCQkJY2FzZSAxNiA6CgkJCQkJcmVzdWx0ID0gc2hvd1Jlc291cmNlRGlhbG9nKEV4dGVybmFsVG9vbC5WQVJfUFJPSkVDVF9OQU1FKTsKCQkJCQlicmVhazsKCgkJCQljYXNlIDE3IDoKCQkJCQlyZXN1bHQgPSBzaG93UmVzb3VyY2VEaWFsb2coRXh0ZXJuYWxUb29sLlZBUl9DT05UQUlORVJfTkFNRSk7CgkJCQkJYnJlYWs7CgoJCQkJY2FzZSAxOCA6CgkJCQkJcmVzdWx0ID0gc2hvd1Jlc291cmNlRGlhbG9nKEV4dGVybmFsVG9vbC5WQVJfUkVTT1VSQ0VfTkFNRSk7CgkJCQkJYnJlYWs7CgkJCQkJCgkJCQljYXNlIDE5IDoKCQkJCQlyZXN1bHQgPSBUb29sVXRpbC5idWlsZFZhcmlhYmxlVGFnKEV4dGVybmFsVG9vbC5WQVJfQlVJTERfVFlQRSwgbnVsbCk7CgkJCQkJYnJlYWs7CgkJCQkJCgkJCQljYXNlIDIwIDoKCQkJCQlBbnRUYXJnZXRMaXN0IHRhcmdldExpc3QgPSBudWxsOwoJCQkJCXRyeSB7CgkJCQkJCXRhcmdldExpc3QgPSBBbnRVdGlsLmdldFRhcmdldExpc3QobmV3IFBhdGgobG9jYXRpb24pKTsKCQkJCQl9IGNhdGNoIChDb3JlRXhjZXB0aW9uIGUpIHsKCQkJCQkJRXJyb3JEaWFsb2cub3BlbkVycm9yKAoJCQkJCQkJZ2V0U2hlbGwoKSwKCQkJCQkJCVRvb2xNZXNzYWdlcy5nZXRTdHJpbmcoIkVkaXREaWFsb2cuZXJyb3JUaXRsZSIpLCAvLyROT04tTkxTLTEkCgkJCQkJCQlUb29sTWVzc2FnZXMuZm9ybWF0KCJFZGl0RGlhbG9nLmVycm9yUmVhZEFudEZpbGUiLCBuZXcgT2JqZWN0W10ge2xvY2F0aW9ufSksIC8vJE5PTi1OTFMtMSQ7CgkJCQkJCQllLmdldFN0YXR1cygpKTsKCQkJCQkJYnJlYWs7CgkJCQkJfQoJCQkJCQoJCQkJCWlmICh0YXJnZXRMaXN0ID09IG51bGwpIHsKCQkJCQkJTWVzc2FnZURpYWxvZy5vcGVuRXJyb3IoCgkJCQkJCQlnZXRTaGVsbCgpLAoJCQkJCQkJVG9vbE1lc3NhZ2VzLmdldFN0cmluZygiRWRpdERpYWxvZy5lcnJvclRpdGxlIiksIC8vJE5PTi1OTFMtMSQ7CgkJCQkJCQlUb29sTWVzc2FnZXMuZm9ybWF0KCJFZGl0RGlhbG9nLm5vQW50VGFyZ2V0cyIsIG5ldyBPYmplY3RbXSB7bG9jYXRpb259KSk7IC8vJE5PTi1OTFMtMSQ7CgkJCQkJCWJyZWFrOwoJCQkJCX0KCgkJCQkJVGFyZ2V0U2VsZWN0aW9uRGlhbG9nIHRhcmdldERpYWxvZzsKCQkJCQl0YXJnZXREaWFsb2cgPSBuZXcgVGFyZ2V0U2VsZWN0aW9uRGlhbG9nKGdldFNoZWxsKCksIHRhcmdldExpc3QpOwoJCQkJCXRhcmdldERpYWxvZy5vcGVuKCk7CgkJCQkJT2JqZWN0W10gdGFyZ2V0cyA9IHRhcmdldERpYWxvZy5nZXRSZXN1bHQoKTsKCQkJCQlpZiAodGFyZ2V0cyAhPSBudWxsICYmIHRhcmdldHMubGVuZ3RoID4gMCkgewoJCQkJCQlTdHJpbmdCdWZmZXIgYnVmID0gbmV3IFN0cmluZ0J1ZmZlcigpOwoJCQkJCQlUb29sVXRpbC5idWlsZFZhcmlhYmxlVGFncyhFeHRlcm5hbFRvb2wuVkFSX0FOVF9UQVJHRVQsIChTdHJpbmdbXSl0YXJnZXRzLCBidWYpOwoJCQkJCQlyZXN1bHQgPSBidWYudG9TdHJpbmcoKS50cmltKCk7CgkJCQkJfQoJCQkJCWJyZWFrOwoJCQl9CgkJCQoJCQlpZiAocmVzdWx0ICE9IG51bGwpCgkJCQlzZXRTZWxlY3Rpb25SZXN1bHQobmV3IE9iamVjdFtdIHtyZXN1bHR9KTsKCQkJc3VwZXIub2tQcmVzc2VkKCk7CgkJfQoJCQoJCXByaXZhdGUgU3RyaW5nIHNob3dSZXNvdXJjZURpYWxvZyhTdHJpbmcgdmFyTmFtZSkgewoJCQlSZXNvdXJjZVNlbGVjdGlvbkRpYWxvZyByZXNEaWFsb2c7CgkJCXJlc0RpYWxvZyA9IG5ldyBSZXNvdXJjZVNlbGVjdGlvbkRpYWxvZygKCQkJCWdldFNoZWxsKCksIAoJCQkJUmVzb3VyY2VzUGx1Z2luLmdldFdvcmtzcGFjZSgpLmdldFJvb3QoKSwKCQkJCVRvb2xNZXNzYWdlcy5nZXRTdHJpbmcoIkVkaXREaWFsb2cuc2VsZWN0UmVzb3VyY2UiKSk7IC8vJE5PTi1OTFMtMSQKCQkJcmVzRGlhbG9nLm9wZW4oKTsKCQkJT2JqZWN0W10gcmVzb3VyY2UgPSByZXNEaWFsb2cuZ2V0UmVzdWx0KCk7CgkJCWlmIChyZXNvdXJjZSAhPSBudWxsICYmIHJlc291cmNlLmxlbmd0aCA+IDApCgkJCQlyZXR1cm4gVG9vbFV0aWwuYnVpbGRWYXJpYWJsZVRhZyh2YXJOYW1lLCAoKElSZXNvdXJjZSlyZXNvdXJjZVswXSkuZ2V0RnVsbFBhdGgoKS50b1N0cmluZygpKTsKCQkJZWxzZQoJCQkJcmV0dXJuIG51bGw7CgkJfQoJfQoJCgkJLyoqCgkgKiBJbnRlcm5hbCBkaWFsb2cgdG8gc2hvdyBhdmFpbGFibGUgdmFyaWFibGVzIGZyb20gd2hpY2gKCSAqIHRoZSB1c2VyIGNhbiBzZWxlY3Qgb25lLgoJICovCglwcml2YXRlIGNsYXNzIERpcmVjdG9yeVNlbGVjdGlvbkRpYWxvZyBleHRlbmRzIFNlbGVjdGlvbkRpYWxvZyB7CgkJU3RyaW5nIGxvY2F0aW9uOwoJCUxpc3QgbGlzdDsKCQkKCQlwdWJsaWMgRGlyZWN0b3J5U2VsZWN0aW9uRGlhbG9nKFNoZWxsIHBhcmVudCkgewoJCQlzdXBlcihwYXJlbnQpOwoJCQlzZXRUaXRsZShUb29sTWVzc2FnZXMuZ2V0U3RyaW5nKCJFZGl0RGlhbG9nLmJyb3dzZURpclRpdGxlIikpOyAvLyROT04tTkxTLTEkCgkJCVdvcmtiZW5jaEhlbHAuc2V0SGVscChwYXJlbnQsIElIZWxwQ29udGV4dElkcy5WQVJJQUJMRV9TRUxFQ1RJT05fRElBTE9HKTsKCQl9CgoJCS8qIChub24tSmF2YWRvYykKCQkgKiBNZXRob2QgZGVjbGFyZWQgb24gRGlhbG9nLgoJCSAqLwoJCXByb3RlY3RlZCBDb250cm9sIGNyZWF0ZURpYWxvZ0FyZWEoQ29tcG9zaXRlIHBhcmVudCkgewoJCQkvLyBjcmVhdGUgY29tcG9zaXRlIAoJCQlDb21wb3NpdGUgZGlhbG9nQXJlYSA9IChDb21wb3NpdGUpc3VwZXIuY3JlYXRlRGlhbG9nQXJlYShwYXJlbnQpOwoJCQkKCQkJTGFiZWwgbGFiZWwgPSBuZXcgTGFiZWwoZGlhbG9nQXJlYSwgU1dULkxFRlQpOwoJCQlsYWJlbC5zZXRUZXh0KFRvb2xNZXNzYWdlcy5nZXRTdHJpbmcoIkVkaXREaWFsb2cuc2VsZWN0RGlyIikpOyAvLyROT04tTkxTLTEkCgkJCQoJCQlsaXN0ID0gbmV3IExpc3QoZGlhbG9nQXJlYSwgU1dULkhfU0NST0xMIHwgU1dULlZfU0NST0xMIHwgU1dULlNJTkdMRSB8IFNXVC5CT1JERVIpOwoJCQlHcmlkRGF0YSBkYXRhID0gbmV3IEdyaWREYXRhKEdyaWREYXRhLkZJTExfQk9USCk7CgkJCWRhdGEuaGVpZ2h0SGludCA9IFNJWklOR19TRUxFQ1RJT05fUEFORV9IRUlHSFQ7CgkJCWRhdGEud2lkdGhIaW50ID0gU0laSU5HX1NFTEVDVElPTl9QQU5FX1dJRFRIOwoJCQlsaXN0LnNldExheW91dERhdGEoZGF0YSk7CgoJCQlsaXN0LmFkZChUb29sTWVzc2FnZXMuZ2V0U3RyaW5nKCJFZGl0RGlhbG9nLnZhcldvcmtzcGFjZUxvY0xhYmVsIikpOyAvLyROT04tTkxTLTEkCgkJCWxpc3QuYWRkKFRvb2xNZXNzYWdlcy5nZXRTdHJpbmcoIkVkaXREaWFsb2cudmFyUHJvamVjdExvY0xhYmVsIikpOyAvLyROT04tTkxTLTEkCgkJCWxpc3QuYWRkKFRvb2xNZXNzYWdlcy5nZXRTdHJpbmcoIkVkaXREaWFsb2cudmFyQ29udGFpbmVyTG9jTGFiZWwiKSk7IC8vJE5PTi1OTFMtMSQKCQkJbGlzdC5hZGQoVG9vbE1lc3NhZ2VzLmdldFN0cmluZygiRWRpdERpYWxvZy52YXJSZXNvdXJjZUxvY0xhYmVsIikpOyAvLyROT04tTkxTLTEkCgkJCWxpc3QuYWRkKFRvb2xNZXNzYWdlcy5nZXRTdHJpbmcoIkVkaXREaWFsb2cuZGlyQnJvd3NlV29ya3NwYWNlIikpOyAvLyROT04tTkxTLTEkCgkJCWxpc3QuYWRkKFRvb2xNZXNzYWdlcy5nZXRTdHJpbmcoIkVkaXREaWFsb2cuZGlyQnJvd3NlRmlsZVN5c3RlbSIpKTsgLy9OT04tTkxTLTEkKQoJCQkKCQkJcmV0dXJuIGRpYWxvZ0FyZWE7CgkJfQoJCQoJCS8qIChub24tSmF2YWRvYykKCQkgKiBNZXRob2QgZGVjbGFyZWQgb24gRGlhbG9nLgoJCSAqLwoJCXByb3RlY3RlZCB2b2lkIG9rUHJlc3NlZCgpIHsKCQkJaW50IHNlbCA9IGxpc3QuZ2V0U2VsZWN0aW9uSW5kZXgoKTsKCQkJU3RyaW5nIHJlc3VsdCA9IG51bGw7CgkJCQoJCQlzd2l0Y2ggKHNlbCkgewoJCQkJY2FzZSAwIDoKCQkJCQlyZXN1bHQgPSBUb29sVXRpbC5idWlsZFZhcmlhYmxlVGFnKEV4dGVybmFsVG9vbC5WQVJfV09SS1NQQUNFX0xPQywgbnVsbCk7CgkJCQkJYnJlYWs7CgoJCQkJY2FzZSAxIDoKCQkJCQlyZXN1bHQgPSBUb29sVXRpbC5idWlsZFZhcmlhYmxlVGFnKEV4dGVybmFsVG9vbC5WQVJfUFJPSkVDVF9MT0MsIG51bGwpOwoJCQkJCWJyZWFrOwoKCQkJCWNhc2UgMiA6CgkJCQkJcmVzdWx0ID0gVG9vbFV0aWwuYnVpbGRWYXJpYWJsZVRhZyhFeHRlcm5hbFRvb2wuVkFSX0NPTlRBSU5FUl9MT0MsIG51bGwpOwoJCQkJCWJyZWFrOwoKCQkJCWNhc2UgMyA6CgkJCQkJcmVzdWx0ID0gVG9vbFV0aWwuYnVpbGRWYXJpYWJsZVRhZyhFeHRlcm5hbFRvb2wuVkFSX1JFU09VUkNFX0xPQywgbnVsbCk7CgkJCQkJYnJlYWs7CgoJCQkJY2FzZSA0IDoKCQkJCQlyZXN1bHQgPSBzaG93Q29udGFpbmVyRGlhbG9nKCk7CgkJCQkJYnJlYWs7CgoJCQkJY2FzZSA1IDoKCQkJCQlyZXN1bHQgPSBzaG93RGlyZWN0b3J5RGlhbG9nKCk7CgkJCQkJYnJlYWs7CgkJCQkKCQkJfQoJCQkKCQkJaWYgKHJlc3VsdCAhPSBudWxsKQoJCQkJc2V0U2VsZWN0aW9uUmVzdWx0KG5ldyBPYmplY3RbXSB7cmVzdWx0fSk7CgkJCXN1cGVyLm9rUHJlc3NlZCgpOwoJCX0KCQkKCQlwcml2YXRlIFN0cmluZyBzaG93Q29udGFpbmVyRGlhbG9nKCkgewoJCQlTdHJpbmcgdmFyTmFtZSA9IEV4dGVybmFsVG9vbC5WQVJfV09SS1NQQUNFX0xPQzsKCQkJQ29udGFpbmVyU2VsZWN0aW9uRGlhbG9nIGNvbnRhaW5lckRpYWxvZzsKCQkJY29udGFpbmVyRGlhbG9nID0gbmV3IENvbnRhaW5lclNlbGVjdGlvbkRpYWxvZygKCQkJCWdldFNoZWxsKCksIAoJCQkJUmVzb3VyY2VzUGx1Z2luLmdldFdvcmtzcGFjZSgpLmdldFJvb3QoKSwKCQkJCWZhbHNlLAoJCQkJVG9vbE1lc3NhZ2VzLmdldFN0cmluZygiRWRpdERpYWxvZy5zZWxlY3RDb250YWluZXIiKSk7IC8vJE5PTi1OTFMtMSQKCQkJY29udGFpbmVyRGlhbG9nLm9wZW4oKTsKCQkJT2JqZWN0W10gcmVzb3VyY2UgPSBjb250YWluZXJEaWFsb2cuZ2V0UmVzdWx0KCk7CgkJCWlmIChyZXNvdXJjZSAhPSBudWxsICYmIHJlc291cmNlLmxlbmd0aCA+IDApCgkJCQlyZXR1cm4gVG9vbFV0aWwuYnVpbGRWYXJpYWJsZVRhZyh2YXJOYW1lLCAoKElQYXRoKXJlc291cmNlWzBdKS50b1N0cmluZygpKTsKCQkJZWxzZQoJCQkJcmV0dXJuIG51bGw7CgkJfQoJCQoJCXByaXZhdGUgU3RyaW5nIHNob3dEaXJlY3RvcnlEaWFsb2coKSB7CgkJCQlEaXJlY3RvcnlEaWFsb2cgZGlhbG9nID0gbmV3IERpcmVjdG9yeURpYWxvZyhnZXRTaGVsbCgpLCBTV1QuU0FWRSk7CgkJCQlkaWFsb2cuc2V0TWVzc2FnZShUb29sTWVzc2FnZXMuZ2V0U3RyaW5nKCJFZGl0RGlhbG9nLnNlbGVjdERpcmVjdG9yeSIpKTsgLy8kTk9OLU5MUy0xJAoJCQkJZGlhbG9nLnNldEZpbHRlclBhdGgoZGlyZWN0b3J5RmllbGQuZ2V0VGV4dCgpKTsKCQkJCXJldHVybiBkaWFsb2cub3BlbigpOwkKCQl9Cgl9CgkKCS8qKgoJICogSW50ZXJuYWwgZGlhbG9nIHRvIHNob3cgYXZhaWxhYmxlIHJlZnJlc2ggc2NvcGUgZnJvbSB3aGljaAoJICogdGhlIHVzZXIgY2FuIHNlbGVjdCBvbmUuCgkgKi8KCXByaXZhdGUgY2xhc3MgUmVmcmVzaFNlbGVjdGlvbkRpYWxvZyBleHRlbmRzIFNlbGVjdGlvbkRpYWxvZyB7CgkJTGlzdCBsaXN0OwoJCQoJCXB1YmxpYyBSZWZyZXNoU2VsZWN0aW9uRGlhbG9nKFNoZWxsIHBhcmVudCkgewoJCQlzdXBlcihwYXJlbnQpOwoJCQlzZXRUaXRsZShUb29sTWVzc2FnZXMuZ2V0U3RyaW5nKCJFZGl0RGlhbG9nLmJyb3dzZVJlZnJlc2hUaXRsZSIpKTsgLy8kTk9OLU5MUy0xJAoJCQlXb3JrYmVuY2hIZWxwLnNldEhlbHAocGFyZW50LCBJSGVscENvbnRleHRJZHMuUkVGUkVTSF9TRUxFQ1RJT05fRElBTE9HKTsKCgkJfQoKCQkvKiAobm9uLUphdmFkb2MpCgkJICogTWV0aG9kIGRlY2xhcmVkIG9uIERpYWxvZy4KCQkgKi8KCQlwcm90ZWN0ZWQgQ29udHJvbCBjcmVhdGVEaWFsb2dBcmVhKENvbXBvc2l0ZSBwYXJlbnQpIHsKCQkJLy8gY3JlYXRlIGNvbXBvc2l0ZSAKCQkJQ29tcG9zaXRlIGRpYWxvZ0FyZWEgPSAoQ29tcG9zaXRlKXN1cGVyLmNyZWF0ZURpYWxvZ0FyZWEocGFyZW50KTsKCQkJCgkJCUxhYmVsIGxhYmVsID0gbmV3IExhYmVsKGRpYWxvZ0FyZWEsIFNXVC5MRUZUKTsKCQkJbGFiZWwuc2V0VGV4dChUb29sTWVzc2FnZXMuZ2V0U3RyaW5nKCJFZGl0RGlhbG9nLnNlbGVjdFJlZnJlc2giKSk7IC8vJE5PTi1OTFMtMSQKCQkJCgkJCWxpc3QgPSBuZXcgTGlzdChkaWFsb2dBcmVhLCBTV1QuSF9TQ1JPTEwgfCBTV1QuVl9TQ1JPTEwgfCBTV1QuU0lOR0xFIHwgU1dULkJPUkRFUik7CgkJCUdyaWREYXRhIGRhdGEgPSBuZXcgR3JpZERhdGEoR3JpZERhdGEuRklMTF9CT1RIKTsKCQkJZGF0YS5oZWlnaHRIaW50ID0gU0laSU5HX1NFTEVDVElPTl9QQU5FX0hFSUdIVDsKCQkJZGF0YS53aWR0aEhpbnQgPSBTSVpJTkdfU0VMRUNUSU9OX1BBTkVfV0lEVEg7CgkJCWxpc3Quc2V0TGF5b3V0RGF0YShkYXRhKTsKCQkJCgkJCWxpc3QuYWRkKFRvb2xNZXNzYWdlcy5nZXRTdHJpbmcoIkVkaXREaWFsb2cucmVmcmVzaE5vdGhpbmdMYWJlbCIpKTsgLy8kTk9OLU5MUy0xJAoJCQlsaXN0LmFkZChUb29sTWVzc2FnZXMuZ2V0U3RyaW5nKCJFZGl0RGlhbG9nLnJlZnJlc2hXb3Jrc3BhY2VMYWJlbCIpKTsgLy8kTk9OLU5MUy0xJAoJCQlsaXN0LmFkZChUb29sTWVzc2FnZXMuZ2V0U3RyaW5nKCJFZGl0RGlhbG9nLnJlZnJlc2hQcm9qZWN0TGFiZWwiKSk7IC8vJE5PTi1OTFMtMSQKCQkJbGlzdC5hZGQoVG9vbE1lc3NhZ2VzLmdldFN0cmluZygiRWRpdERpYWxvZy5yZWZyZXNoUHJvamVjdFhMYWJlbCIpKTsgLy8kTk9OLU5MUy0xJAoJCQlsaXN0LmFkZChUb29sTWVzc2FnZXMuZ2V0U3RyaW5nKCJFZGl0RGlhbG9nLnJlZnJlc2hXb3JraW5nU2V0TGFiZWwiKSk7IC8vJE5PTi1OTFMtMSQKCgkJCXJldHVybiBkaWFsb2dBcmVhOwoJCX0KCQkKCQkvKiAobm9uLUphdmFkb2MpCgkJICogTWV0aG9kIGRlY2xhcmVkIG9uIERpYWxvZy4KCQkgKi8KCQlwcm90ZWN0ZWQgdm9pZCBva1ByZXNzZWQoKSB7CgkJCWludCBzZWwgPSBsaXN0LmdldFNlbGVjdGlvbkluZGV4KCk7CgkJCVN0cmluZyByZXN1bHQgPSBudWxsOwoJCQkKCQkJc3dpdGNoIChzZWwpIHsKCQkJCWNhc2UgMCA6CgkJCQkJcmVzdWx0ID0gVG9vbFV0aWwuYnVpbGRWYXJpYWJsZVRhZyhFeHRlcm5hbFRvb2wuUkVGUkVTSF9TQ09QRV9OT05FLCBudWxsKTsKCQkJCQlicmVhazsKCQkJCQkKCQkJCWNhc2UgMSA6CgkJCQkJcmVzdWx0ID0gVG9vbFV0aWwuYnVpbGRWYXJpYWJsZVRhZyhFeHRlcm5hbFRvb2wuUkVGUkVTSF9TQ09QRV9XT1JLU1BBQ0UsIG51bGwpOwoJCQkJCWJyZWFrOwoKCQkJCWNhc2UgMiA6CgkJCQkJcmVzdWx0ID0gVG9vbFV0aWwuYnVpbGRWYXJpYWJsZVRhZyhFeHRlcm5hbFRvb2wuUkVGUkVTSF9TQ09QRV9QUk9KRUNULCBudWxsKTsKCQkJCQlicmVhazsKCgkJCQljYXNlIDMgOgoJCQkJCVByb2plY3RTZWxlY3Rpb25EaWFsb2cgcHJqRGlhbG9nOwoJCQkJCXByakRpYWxvZyA9IG5ldyBQcm9qZWN0U2VsZWN0aW9uRGlhbG9nKGdldFNoZWxsKCkpOwoJCQkJCXByakRpYWxvZy5vcGVuKCk7CgkJCQkJT2JqZWN0W10gbmFtZSA9IHByakRpYWxvZy5nZXRSZXN1bHQoKTsKCQkJCQlpZiAobmFtZSAhPSBudWxsICYmIG5hbWUubGVuZ3RoID4gMCkKCQkJCQkJcmVzdWx0ID0gVG9vbFV0aWwuYnVpbGRWYXJpYWJsZVRhZyhFeHRlcm5hbFRvb2wuUkVGUkVTSF9TQ09QRV9QUk9KRUNULCAoU3RyaW5nKW5hbWVbMF0pOwoJCQkJCWJyZWFrOwoKCQkJCWNhc2UgNCA6CgkJCQkJSVdvcmtpbmdTZXRTZWxlY3Rpb25EaWFsb2cgc2V0RGlhbG9nOwoJCQkJCXNldERpYWxvZyA9IFBsYXRmb3JtVUkuZ2V0V29ya2JlbmNoKCkuZ2V0V29ya2luZ1NldE1hbmFnZXIoKS5jcmVhdGVXb3JraW5nU2V0U2VsZWN0aW9uRGlhbG9nKGdldFNoZWxsKCksIGZhbHNlKTsKCQkJCQlzZXREaWFsb2cub3BlbigpOwoJCQkJCUlXb3JraW5nU2V0W10gc2V0cyA9IHNldERpYWxvZy5nZXRTZWxlY3Rpb24oKTsKCQkJCQlpZiAoc2V0cyAhPSBudWxsICYmIHNldHMubGVuZ3RoID4gMCkKCQkJCQkJcmVzdWx0ID0gVG9vbFV0aWwuYnVpbGRWYXJpYWJsZVRhZyhFeHRlcm5hbFRvb2wuUkVGUkVTSF9TQ09QRV9XT1JLSU5HX1NFVCwgc2V0c1swXS5nZXROYW1lKCkpOwoJCQkJCWJyZWFrOwoJCQl9CgkJCQoJCQlpZiAocmVzdWx0ICE9IG51bGwpCgkJCQlzZXRTZWxlY3Rpb25SZXN1bHQobmV3IE9iamVjdFtdIHtyZXN1bHR9KTsKCQkJc3VwZXIub2tQcmVzc2VkKCk7CgkJfQoJfQoJCgkvKioKCSAqIEludGVybmFsIGRpYWxvZyB0byBzaG93IGF2YWlsYWJsZSBwcm9qZWN0cyBmcm9tIHdoaWNoCgkgKiB0aGUgdXNlciBjYW4gc2VsZWN0IG9uZS4KCSAqLwoJcHJpdmF0ZSBjbGFzcyBQcm9qZWN0U2VsZWN0aW9uRGlhbG9nIGV4dGVuZHMgU2VsZWN0aW9uRGlhbG9nIHsKCQlMaXN0IGxpc3Q7CgkJCgkJcHVibGljIFByb2plY3RTZWxlY3Rpb25EaWFsb2coU2hlbGwgcGFyZW50KSB7CgkJCXN1cGVyKHBhcmVudCk7CgkJCXNldFRpdGxlKFRvb2xNZXNzYWdlcy5nZXRTdHJpbmcoIkVkaXREaWFsb2cuYnJvd3NlUHJvamVjdFRpdGxlIikpOyAvLyROT04tTkxTLTEkCgkJCVdvcmtiZW5jaEhlbHAuc2V0SGVscChwYXJlbnQsIElIZWxwQ29udGV4dElkcy5QUk9KRUNUX1NFTEVDVElPTl9ESUFMT0cpOwoJCX0KCgkJLyogKG5vbi1KYXZhZG9jKQoJCSAqIE1ldGhvZCBkZWNsYXJlZCBvbiBEaWFsb2cuCgkJICovCgkJcHJvdGVjdGVkIENvbnRyb2wgY3JlYXRlRGlhbG9nQXJlYShDb21wb3NpdGUgcGFyZW50KSB7CgkJCS8vIGNyZWF0ZSBjb21wb3NpdGUgCgkJCUNvbXBvc2l0ZSBkaWFsb2dBcmVhID0gKENvbXBvc2l0ZSlzdXBlci5jcmVhdGVEaWFsb2dBcmVhKHBhcmVudCk7CgkJCQoJCQlMYWJlbCBsYWJlbCA9IG5ldyBMYWJlbChkaWFsb2dBcmVhLCBTV1QuTEVGVCk7CgkJCWxhYmVsLnNldFRleHQoVG9vbE1lc3NhZ2VzLmdldFN0cmluZygiRWRpdERpYWxvZy5zZWxlY3RQcm9qZWN0IikpOyAvLyROT04tTkxTLTEkCgkJCQoJCQlsaXN0ID0gbmV3IExpc3QoZGlhbG9nQXJlYSwgU1dULkhfU0NST0xMIHwgU1dULlZfU0NST0xMIHwgU1dULlNJTkdMRSB8IFNXVC5CT1JERVIpOwoJCQlHcmlkRGF0YSBkYXRhID0gbmV3IEdyaWREYXRhKEdyaWREYXRhLkZJTExfQk9USCk7CgkJCWRhdGEuaGVpZ2h0SGludCA9IFNJWklOR19TRUxFQ1RJT05fUEFORV9IRUlHSFQ7CgkJCWRhdGEud2lkdGhIaW50ID0gU0laSU5HX1NFTEVDVElPTl9QQU5FX1dJRFRIOwoJCQlsaXN0LnNldExheW91dERhdGEoZGF0YSk7CgkJCQoJCQlJV29ya3NwYWNlUm9vdCByb290ID0gUmVzb3VyY2VzUGx1Z2luLmdldFdvcmtzcGFjZSgpLmdldFJvb3QoKTsKCQkJSVByb2plY3RbXSBwcm9qZWN0cyA9IHJvb3QuZ2V0UHJvamVjdHMoKTsKCQkJZm9yIChpbnQgaSA9IDA7IGkgPCBwcm9qZWN0cy5sZW5ndGg7IGkrKykgewoJCQkJbGlzdC5hZGQocHJvamVjdHNbaV0uZ2V0TmFtZSgpKTsKCQkJfQoJCQkKCQkJcmV0dXJuIGRpYWxvZ0FyZWE7CgkJfQoJCQoJCS8qIChub24tSmF2YWRvYykKCQkgKiBNZXRob2QgZGVjbGFyZWQgb24gRGlhbG9nLgoJCSAqLwoJCXByb3RlY3RlZCB2b2lkIG9rUHJlc3NlZCgpIHsKCQkJc2V0U2VsZWN0aW9uUmVzdWx0KGxpc3QuZ2V0U2VsZWN0aW9uKCkpOwoJCQlzdXBlci5va1ByZXNzZWQoKTsKCQl9Cgl9CgkKCXByaXZhdGUgY2xhc3MgVGFyZ2V0U2VsZWN0aW9uRGlhbG9nIGV4dGVuZHMgU2VsZWN0aW9uRGlhbG9nIGltcGxlbWVudHMgSUNoZWNrU3RhdGVMaXN0ZW5lciB7CgkJcHJpdmF0ZSBBcnJheUxpc3Qgc2VsZWN0ZWRUYXJnZXRzID0gbmV3IEFycmF5TGlzdCgpOwoJCXByaXZhdGUgQ2hlY2tib3hUYWJsZVZpZXdlciBsaXN0Vmlld2VyOwoJCXByaXZhdGUgQW50VGFyZ2V0TGlzdCB0YXJnZXRMaXN0OwoJCXByaXZhdGUgQW50VGFyZ2V0TGFiZWxQcm92aWRlciBsYWJlbFByb3ZpZGVyID0gbmV3IEFudFRhcmdldExhYmVsUHJvdmlkZXIoKTsJCgkJCgkJcHVibGljIFRhcmdldFNlbGVjdGlvbkRpYWxvZyhTaGVsbCBwYXJlbnQsIEFudFRhcmdldExpc3QgdGFyZ2V0TGlzdCkgewoJCQlzdXBlcihwYXJlbnQpOwoJCQl0aGlzLnRhcmdldExpc3QgPSB0YXJnZXRMaXN0OwoJCQlzZXRUaXRsZShUb29sTWVzc2FnZXMuZ2V0U3RyaW5nKCJFZGl0RGlhbG9nLnZhckFudFRhcmdldExhYmVsIikpOyAvLyROT04tTkxTLTEkCgkJCVdvcmtiZW5jaEhlbHAuc2V0SGVscChwYXJlbnQsIElIZWxwQ29udGV4dElkcy5UQVJHRVRfU0VMRUNUSU9OX0RJQUxPRyk7CgkJfQoJCQoJCXB1YmxpYyB2b2lkIGNoZWNrU3RhdGVDaGFuZ2VkKENoZWNrU3RhdGVDaGFuZ2VkRXZlbnQgZSkgewoJCQlTdHJpbmcgY2hlY2tlZFRhcmdldCA9IChTdHJpbmcpZS5nZXRFbGVtZW50KCk7CgkJCWlmIChlLmdldENoZWNrZWQoKSkKCQkJCXNlbGVjdGVkVGFyZ2V0cy5hZGQoY2hlY2tlZFRhcmdldCk7CgkJCWVsc2UKCQkJCXNlbGVjdGVkVGFyZ2V0cy5yZW1vdmUoY2hlY2tlZFRhcmdldCk7CgkJCQkKCQkJbGFiZWxQcm92aWRlci5zZXRTZWxlY3RlZFRhcmdldHMoc2VsZWN0ZWRUYXJnZXRzKTsKCQkJbGlzdFZpZXdlci5yZWZyZXNoKCk7CgkJfQoJCQoJCXByb3RlY3RlZCBDb250cm9sIGNyZWF0ZURpYWxvZ0FyZWEoQ29tcG9zaXRlIHBhcmVudCkgewoJCQlDb21wb3NpdGUgZGlhbG9nQXJlYSA9IChDb21wb3NpdGUpc3VwZXIuY3JlYXRlRGlhbG9nQXJlYShwYXJlbnQpOwoJCQkKCQkJTGFiZWwgbGFiZWwgPSBuZXcgTGFiZWwoZGlhbG9nQXJlYSwgU1dULkxFRlQpOwoJCQlsYWJlbC5zZXRUZXh0KFRvb2xNZXNzYWdlcy5nZXRTdHJpbmcoIkVkaXREaWFsb2cuc2VsZWN0VGFyZ2V0cyIpKTsgLy8kTk9OLU5MUy0xJAoJCQkKCQkJbGlzdFZpZXdlciA9IENoZWNrYm94VGFibGVWaWV3ZXIubmV3Q2hlY2tMaXN0KGRpYWxvZ0FyZWEsIFNXVC5CT1JERVIpOwoJCQlHcmlkRGF0YSBkYXRhID0gbmV3IEdyaWREYXRhKEdyaWREYXRhLkZJTExfQk9USCk7CgkJCWRhdGEuaGVpZ2h0SGludCA9IFNJWklOR19TRUxFQ1RJT05fUEFORV9IRUlHSFQ7CgkJCWRhdGEud2lkdGhIaW50ID0gU0laSU5HX1NFTEVDVElPTl9QQU5FX1dJRFRIOwoJCQlsaXN0Vmlld2VyLmdldFRhYmxlKCkuc2V0TGF5b3V0RGF0YShkYXRhKTsKCQkJbGlzdFZpZXdlci5zZXRTb3J0ZXIobmV3IFZpZXdlclNvcnRlcigpIHsKCQkJCXB1YmxpYyBpbnQgY29tcGFyZShWaWV3ZXIgdmlld2VyLE9iamVjdCBvMSxPYmplY3QgbzIpIHsKCQkJCQlyZXR1cm4gKChTdHJpbmcpbzEpLmNvbXBhcmVUbygoU3RyaW5nKW8yKTsKCQkJCX0KCQkJfSk7CgkJCQoJCQlpZiAodGFyZ2V0TGlzdCAhPSBudWxsICYmIHRhcmdldExpc3QuZ2V0RGVmYXVsdFRhcmdldCgpICE9IG51bGwpCgkJCQlsYWJlbFByb3ZpZGVyLnNldERlZmF1bHRUYXJnZXROYW1lKHRhcmdldExpc3QuZ2V0RGVmYXVsdFRhcmdldCgpKTsKCQkJbGlzdFZpZXdlci5zZXRMYWJlbFByb3ZpZGVyKGxhYmVsUHJvdmlkZXIpOwoJCQlsaXN0Vmlld2VyLnNldENvbnRlbnRQcm92aWRlcihuZXcgQW50VGFyZ2V0Q29udGVudFByb3ZpZGVyKCkpOwoJCQlsaXN0Vmlld2VyLnNldElucHV0KHRhcmdldExpc3QpOwoJCQkKCQkJbGlzdFZpZXdlci5hZGRDaGVja1N0YXRlTGlzdGVuZXIodGhpcyk7CgkJCWxpc3RWaWV3ZXIucmVmcmVzaCgpOwoJCQkKCQkJcmV0dXJuIGRpYWxvZ0FyZWE7CgkJfQoJCQoJCS8qIChub24tSmF2YWRvYykKCQkgKiBNZXRob2QgZGVjbGFyZWQgb24gRGlhbG9nLgoJCSAqLwoJCXByb3RlY3RlZCB2b2lkIG9rUHJlc3NlZCgpIHsKCQkJc2V0U2VsZWN0aW9uUmVzdWx0KGdldFRhcmdldE5hbWVzKCkpOwoJCQlzdXBlci5va1ByZXNzZWQoKTsKCQl9CgkJCgkJcHJvdGVjdGVkIFN0cmluZ1tdIGdldFRhcmdldE5hbWVzKCkgewoJCQlTdHJpbmdbXSByZXN1bHQgPSBuZXcgU3RyaW5nW3NlbGVjdGVkVGFyZ2V0cy5zaXplKCldOwoJCQlzZWxlY3RlZFRhcmdldHMudG9BcnJheShyZXN1bHQpOwoJCQlyZXR1cm4gcmVzdWx0OwoJCX0KCX0KCQp9Cg==