cGFja2FnZSBvcmcuZWNsaXBzZS51aS5leHRlcm5hbHRvb2xzLmludGVybmFsLnVpOwoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKQ29weXJpZ2h0IChjKSAyMDAyIElCTSBDb3JwLiBhbmQgb3RoZXJzLgpBbGwgcmlnaHRzIHJlc2VydmVkLiCgIFRoaXMgcHJvZ3JhbSBhbmQgdGhlIGFjY29tcGFueWluZyBtYXRlcmlhbHMKYXJlIG1hZGUgYXZhaWxhYmxlIHVuZGVyIHRoZSB0ZXJtcyBvZiB0aGUgQ29tbW9uIFB1YmxpYyBMaWNlbnNlIHYwLjUKd2hpY2ggYWNjb21wYW5pZXMgdGhpcyBkaXN0cmlidXRpb24sIGFuZCBpcyBhdmFpbGFibGUgYXQKaHR0cDovL3d3dy5lY2xpcHNlLm9yZy9sZWdhbC9jcGwtdjA1Lmh0bWwKoApDb250cmlidXRvcnM6CioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCmltcG9ydCBqYXZhLmlvLkZpbGU7CmltcG9ydCBqYXZhLnV0aWwuQXJyYXlMaXN0OwoKaW1wb3J0IG9yZy5lY2xpcHNlLmNvcmUucmVzb3VyY2VzLio7CmltcG9ydCBvcmcuZWNsaXBzZS5jb3JlLnJ1bnRpbWUuKjsKaW1wb3J0IG9yZy5lY2xpcHNlLmpmYWNlLmRpYWxvZ3MuKjsKaW1wb3J0IG9yZy5lY2xpcHNlLmpmYWNlLnZpZXdlcnMuKjsKaW1wb3J0IG9yZy5lY2xpcHNlLnN3dC5TV1Q7CmltcG9ydCBvcmcuZWNsaXBzZS5zd3QuZXZlbnRzLio7CmltcG9ydCBvcmcuZWNsaXBzZS5zd3QuZ3JhcGhpY3MuUG9pbnQ7CmltcG9ydCBvcmcuZWNsaXBzZS5zd3QubGF5b3V0Lio7CmltcG9ydCBvcmcuZWNsaXBzZS5zd3Qud2lkZ2V0cy4qOwppbXBvcnQgb3JnLmVjbGlwc2UudWkuKjsKaW1wb3J0IG9yZy5lY2xpcHNlLnVpLmhlbHAuV29ya2JlbmNoSGVscDsKaW1wb3J0IG9yZy5lY2xpcHNlLnVpLm1vZGVsLio7CmltcG9ydCBvcmcuZWNsaXBzZS51aS5kaWFsb2dzLio7CmltcG9ydCBvcmcuZWNsaXBzZS51aS5leHRlcm5hbHRvb2xzLmludGVybmFsLmNvcmUuKjsKaW1wb3J0IG9yZy5lY2xpcHNlLnVpLmV4dGVybmFsdG9vbHMuaW50ZXJuYWwuY29yZS5Ub29sVXRpbC5WYXJpYWJsZURlZmluaXRpb247CgovKioKICogRGlhbG9nIGJveCB0byBlbnRlciB0aGUgcmVxdWlyZWQgaW5mb3JtYXRpb24gZm9yIHJ1bm5pbmcKICogYW4gZXh0ZXJuYWwgdG9vbC4KICovCnB1YmxpYyBjbGFzcyBFZGl0RGlhbG9nIGV4dGVuZHMgVGl0bGVBcmVhRGlhbG9nIHsKCS8vIFRoZSB3aWR0aCBvZiBtb3N0IHRleHQgZmllbGRzIGluIHRoZSBkaWFsb2cuCgkvLyBGaWVsZHMgdGhhdCBoYXZlIGxhYmVscyBvbiB0aGUgc2FtZSBsaW5lIGFyZSBzaG9ydGVyLgoJLy8gQXMgc3VjaCwgYWxsIGZpZWxkcyBlbmQgaW4gdGhlIHNhbWUgdmVydGljYWwgcG9zaXRpb24uCglwcml2YXRlIHN0YXRpYyBmaW5hbCBpbnQgRklFTERfV0lEVEggPSAzMDA7CgkvLyBUaGUgc3BhY2luZyB1c2VkIHRvIHNlcGVyYXRlIGdyb3VwcyBpbiB0aGUgZGlhbG9nLgoJcHJpdmF0ZSBzdGF0aWMgZmluYWwgaW50IEdST1VQX1NQQUNFID0gMjA7CgkvLyBUaGUgc3BhY2luZyB1c2VkIHRvIHNlcGVyYXRlIHdpZGdldHMgaW4gYSBncm91cAoJcHJpdmF0ZSBzdGF0aWMgZmluYWwgaW50IFdJREdFVF9TUEFDRSA9IDU7CgkvLyBUaGUgc3BhY2luZyBvZiBtYXJnaW5zIGluIHRoZSBkaWFsb2cKCXByaXZhdGUgc3RhdGljIGZpbmFsIGludCBNQVJHSU5fU1BBQ0UgPSA1OwoJCgkvLyBkaWFsb2cgc2l6aW5nIGNvbnN0YW50cwoJcHJpdmF0ZSBzdGF0aWMgZmluYWwgaW50IFNJWklOR19TRUxFQ1RJT05fUEFORV9IRUlHSFQgPSAyNTA7Cglwcml2YXRlIHN0YXRpYyBmaW5hbCBpbnQgU0laSU5HX1NFTEVDVElPTl9QQU5FX1dJRFRIID0gMzAwOwkKCQoJcHJpdmF0ZSBzdGF0aWMgZmluYWwgYm9vbGVhbiBJTklUSUFMX1NIT1dfTE9HID0gdHJ1ZTsKCQoJcHJpdmF0ZSBUZXh0IG5hbWVGaWVsZDsKCXByaXZhdGUgVGV4dCBsb2NhdGlvbkZpZWxkOwoJcHJpdmF0ZSBUZXh0IGFyZ3VtZW50c0ZpZWxkOwoJcHJpdmF0ZSBUZXh0IGRpcmVjdG9yeUZpZWxkOwoJcHJpdmF0ZSBUZXh0IHJlZnJlc2hGaWVsZDsKCXByaXZhdGUgQnV0dG9uIGxvY2F0aW9uQnJvd3NlV29ya3NwYWNlOwoJcHJpdmF0ZSBCdXR0b24gbG9jYXRpb25Ccm93c2VGaWxlU3lzdGVtOwoJcHJpdmF0ZSBCdXR0b24gYXJndW1lbnRzQnJvd3NlVmFyaWFibGU7Cglwcml2YXRlIEJ1dHRvbiBkaXJlY3RvcnlCcm93c2VXb3Jrc3BhY2U7Cglwcml2YXRlIEJ1dHRvbiBkaXJlY3RvcnlCcm93c2VGaWxlU3lzdGVtOwoJcHJpdmF0ZSBCdXR0b24gcmVmcmVzaE9wdGlvbkJ1dHRvbjsKCXByaXZhdGUgQnV0dG9uIHNob3dMb2c7CgkKCXByaXZhdGUgYm9vbGVhbiBlZGl0TW9kZSA9IGZhbHNlOwoJcHJpdmF0ZSBFeHRlcm5hbFRvb2wgdG9vbDsKCXByaXZhdGUgU3RyaW5nIHJlZnJlc2hTY29wZTsKCglwcml2YXRlIGludCBtYXhCdXR0b25XaWR0aCA9IDA7CgkvLyBUaGUgZGlmZmVyZW5jZSBiZXR3ZWVuIHRoZSBoZWlnaHQgb2YgYSBidXR0b24gYW5kCgkvLyB0aGUgaGVpZ2h0IG9mIGEgbGFiZWwuCglwcml2YXRlIGludCBidXR0b25MYWJlbEhlaWdodERpZmY7CgkKCS8qKgoJICogSW5zdGFudGlhdGUgYSBuZXcgdG9vbCB0b29sIGVkaXQgZGlhbG9nLgoJICoKCSAqIEBwYXJhbSBwYXJlbnRTaGVsbCB0aGUgcGFyZW50IFNXVCBzaGVsbAoJICogQHBhcmFtIHRvb2wgdGhlIHRvb2wgdG9vbCB0byBlZGl0LCA8Y29kZT5udWxsPC9jb2RlPiBpZiBuZXcKCSAqLwoJcHVibGljIEVkaXREaWFsb2coU2hlbGwgcGFyZW50U2hlbGwsIEV4dGVybmFsVG9vbCB0b29sKSB7CgkJc3VwZXIocGFyZW50U2hlbGwpOwoJCWlmICh0b29sID09IG51bGwpIHsKCQkJdGhpcy50b29sID0gbmV3IEV4dGVybmFsVG9vbCgpOwoJCQl0aGlzLmVkaXRNb2RlID0gZmFsc2U7CgkJfSBlbHNlIHsKCQkJdGhpcy50b29sID0gdG9vbDsKCQkJdGhpcy5lZGl0TW9kZSA9IHRydWU7CgkJfQoJfQoJCgkvKiAobm9uLUphdmFkb2MpCgkgKiBNZXRob2QgZGVjbGFyZWQgaW4gV2luZG93LgoJICovCglwcm90ZWN0ZWQgdm9pZCBjb25maWd1cmVTaGVsbChTaGVsbCBzaGVsbCkgewoJCXN1cGVyLmNvbmZpZ3VyZVNoZWxsKHNoZWxsKTsKCQlpZiAoZWRpdE1vZGUpCgkJCXNoZWxsLnNldFRleHQoVG9vbE1lc3NhZ2VzLmdldFN0cmluZygiRWRpdERpYWxvZy5lZGl0U2hlbGxUaXRsZSIpKTsgLy8kTk9OLU5MUy0xJAoJCWVsc2UKCQkJc2hlbGwuc2V0VGV4dChUb29sTWVzc2FnZXMuZ2V0U3RyaW5nKCJFZGl0RGlhbG9nLm5ld1NoZWxsVGl0bGUiKSk7IC8vJE5PTi1OTFMtMSQKCQlXb3JrYmVuY2hIZWxwLnNldEhlbHAoCgkJCXNoZWxsLAoJCQlJSGVscENvbnRleHRJZHMuRURJVF9ESUFMT0cpOwoJfQoKCS8qIChub24tSmF2YWRvYykKCSAqIE1ldGhvZCBkZWNsYXJlZCBvbiBEaWFsb2cuCgkgKi8KCXByb3RlY3RlZCB2b2lkIGNyZWF0ZUJ1dHRvbnNGb3JCdXR0b25CYXIoQ29tcG9zaXRlIHBhcmVudCkgewoJCWNyZWF0ZUJ1dHRvbihwYXJlbnQsIElEaWFsb2dDb25zdGFudHMuT0tfSUQsIElEaWFsb2dDb25zdGFudHMuT0tfTEFCRUwsIHRydWUpOwoJCWNyZWF0ZUJ1dHRvbihwYXJlbnQsIElEaWFsb2dDb25zdGFudHMuQ0FOQ0VMX0lELCBJRGlhbG9nQ29uc3RhbnRzLkNBTkNFTF9MQUJFTCwgZmFsc2UpOwoJCQoJCWlmICghZWRpdE1vZGUpCgkJCWdldEJ1dHRvbihJRGlhbG9nQ29uc3RhbnRzLk9LX0lEKS5zZXRFbmFibGVkKGZhbHNlKTsKCX0KCQoJLyogKG5vbi1KYXZhZG9jKQoJICogTWV0aG9kIGRlY2xhcmVkIG9uIERpYWxvZy4KCSAqLwoJcHJvdGVjdGVkIENvbnRyb2wgY3JlYXRlRGlhbG9nQXJlYShDb21wb3NpdGUgcGFyZW50KSB7CgkJQ29tcG9zaXRlIGRpYWxvZ0NvbXAgPSAoQ29tcG9zaXRlKXN1cGVyLmNyZWF0ZURpYWxvZ0FyZWEocGFyZW50KTsKCQkJCQoJCS8vIFNldCB0aXRsZSBhbmQgbWVzc2FnZSBub3cgdGhhdCB0aGUgY29udHJvbHMgZXhpc3QKCQlzZXRUaXRsZShUb29sTWVzc2FnZXMuZ2V0U3RyaW5nKCJFZGl0RGlhbG9nLmRpYWxvZ1RpdGxlIikpOyAvLyROT04tTkxTLTEkCgkJaWYgKGVkaXRNb2RlKQoJCQlzZXRNZXNzYWdlKFRvb2xNZXNzYWdlcy5nZXRTdHJpbmcoIkVkaXREaWFsb2cuZWRpdERpYWxvZ01lc3NhZ2UiKSk7IC8vJE5PTi1OTFMtMSQKCQllbHNlCgkJCXNldE1lc3NhZ2UoVG9vbE1lc3NhZ2VzLmdldFN0cmluZygiRWRpdERpYWxvZy5uZXdEaWFsb2dNZXNzYWdlIikpOyAvLyROT04tTkxTLTEkCgkJCgkJLy8gQnVpbGQgdGhlIHRvcCBjb250YWluZXIKCQlDb21wb3NpdGUgdG9wQ29tcCA9IG5ldyBDb21wb3NpdGUoZGlhbG9nQ29tcCwgU1dULk5PTkUpOwoJCUZvcm1MYXlvdXQgbGF5b3V0ID0gbmV3IEZvcm1MYXlvdXQoKTsKCQl0b3BDb21wLnNldExheW91dChsYXlvdXQpOwoJCWxheW91dC5tYXJnaW5IZWlnaHQgPSBNQVJHSU5fU1BBQ0U7CgkJbGF5b3V0Lm1hcmdpbldpZHRoID0gTUFSR0lOX1NQQUNFOwoJCQoJCS8vIE5lZWQgdG8ga2VlcCB0cmFjayBvZiB0aGUgRm9ybURhdGEncyBmb3IgdGhlIGJ1dHRvbnMgdG8gc2V0CgkJLy8gdGhlIHdpZHRoIG9mIGFsbCB0aGUgYnV0dG9ucyB0byBiZSB0aGUgc2FtZSBhcyB0aGUgbGFyZ2VzdAoJCS8vIGJ1dHRvbiB3aWR0aAoJCUZvcm1EYXRhW10gYnV0dG9uRGF0YSA9IG5ldyBGb3JtRGF0YVs2XTsKCQkKCQkvLyBDcmVhdGUgbmFtZSBsYWJlbAoJCUxhYmVsIG5hbWVMYWJlbCA9IG5ldyBMYWJlbCh0b3BDb21wLCBTV1QuTk9ORSk7CgkJbmFtZUxhYmVsLnNldFRleHQoVG9vbE1lc3NhZ2VzLmdldFN0cmluZygiRWRpdERpYWxvZy5uYW1lTGFiZWwiKSk7IC8vJE5PTi1OTFMtMSQKCQlGb3JtRGF0YSBkYXRhID0gbmV3IEZvcm1EYXRhKCk7CgkJZGF0YS50b3AgPSBuZXcgRm9ybUF0dGFjaG1lbnQoMCwgTUFSR0lOX1NQQUNFKTsKCQluYW1lTGFiZWwuc2V0TGF5b3V0RGF0YShkYXRhKTsKCgkJLy8gQ3JlYXRlIG5hbWUgdGV4dCBmaWVsZAoJCW5hbWVGaWVsZCA9IG5ldyBUZXh0KHRvcENvbXAsIFNXVC5CT1JERVIpOwoJCWRhdGEgPSBuZXcgRm9ybURhdGEoKTsKCQlkYXRhLmxlZnQgPSBuZXcgRm9ybUF0dGFjaG1lbnQobmFtZUxhYmVsLCBNQVJHSU5fU1BBQ0UsIFNXVC5SSUdIVCk7CgkJZGF0YS50b3AgPSBuZXcgRm9ybUF0dGFjaG1lbnQobmFtZUxhYmVsLCAwLCBTV1QuQ0VOVEVSKTsKCQlkYXRhLndpZHRoID0gRklFTERfV0lEVEggLSBNQVJHSU5fU1BBQ0UgLSBuYW1lTGFiZWwuY29tcHV0ZVNpemUoU1dULkRFRkFVTFQsIFNXVC5ERUZBVUxULCBmYWxzZSkueDsKCQluYW1lRmllbGQuc2V0TGF5b3V0RGF0YShkYXRhKTsKCgkJLy8gQ3JlYXRlIGxvY2F0aW9uIGJyb3dzZSB3b3Jrc3BhY2UgYnV0dG9uCgkJbG9jYXRpb25Ccm93c2VXb3Jrc3BhY2UgPSBuZXcgQnV0dG9uKHRvcENvbXAsIFNXVC5QVVNIKTsKCQlsb2NhdGlvbkJyb3dzZVdvcmtzcGFjZS5zZXRUZXh0KFRvb2xNZXNzYWdlcy5nZXRTdHJpbmcoIkVkaXREaWFsb2cuYnJvd3NlV2tzcEJ1dHRvbjEiKSk7IC8vJE5PTi1OTFMtMSQKCQlidXR0b25EYXRhWzBdID0gbmV3IEZvcm1EYXRhKCk7CgkJYnV0dG9uRGF0YVswXS5sZWZ0ID0gbmV3IEZvcm1BdHRhY2htZW50KG5hbWVGaWVsZCwgTUFSR0lOX1NQQUNFLCBTV1QuUklHSFQpOwoJCWJ1dHRvbkRhdGFbMF0udG9wID0gbmV3IEZvcm1BdHRhY2htZW50KG5hbWVGaWVsZCwgR1JPVVBfU1BBQ0UsIFNXVC5CT1RUT00pOwoJCWxvY2F0aW9uQnJvd3NlV29ya3NwYWNlLnNldExheW91dERhdGEoYnV0dG9uRGF0YVswXSk7CgkJY2hlY2tGb3JNYXhXaWR0aChsb2NhdGlvbkJyb3dzZVdvcmtzcGFjZSk7CgkJCgkJLy8gQ2FsY3VsYXRlIHRoZSBkaWZmZXJlbmNlIGluIGhlaWdodCBiZXR3ZWVuIGEgbGFiZWwgYW5kIGEgYnV0dG9uLgoJCS8vIFRoaXMgdmFyaWFibGUgd2lsbCBiZSB1c2VkIHRvIGVuc3VyZSBlcXVhbCBzcGFjaW5nIGJldHdlZW4gZ3JvdXBzLgoJCWJ1dHRvbkxhYmVsSGVpZ2h0RGlmZiA9IGxvY2F0aW9uQnJvd3NlV29ya3NwYWNlLmNvbXB1dGVTaXplKFNXVC5ERUZBVUxULCBTV1QuREVGQVVMVCwgZmFsc2UpLnkgLSBuYW1lTGFiZWwuY29tcHV0ZVNpemUoU1dULkRFRkFVTFQsIFNXVC5ERUZBVUxULCBmYWxzZSkueTsKCgkJLy8gQ3JlYXRlIGxhYmVsIGZvciBsb2NhdGlvbiB0ZXh0IGZpZWxkLgoJCUxhYmVsIGxvY2F0aW9uTGFiZWwgPSBuZXcgTGFiZWwodG9wQ29tcCwgU1dULk5PTkUpOwoJCWxvY2F0aW9uTGFiZWwuc2V0VGV4dChUb29sTWVzc2FnZXMuZ2V0U3RyaW5nKCJFZGl0RGlhbG9nLmxvY2F0aW9uTGFiZWwiKSk7IC8vJE5PTi1OTFMtMSQKCQlkYXRhID0gbmV3IEZvcm1EYXRhKCk7CgkJZGF0YS5ib3R0b20gPSBuZXcgRm9ybUF0dGFjaG1lbnQobG9jYXRpb25Ccm93c2VXb3Jrc3BhY2UsIDAsIFNXVC5CT1RUT00pOwoJCWxvY2F0aW9uTGFiZWwuc2V0TGF5b3V0RGF0YShkYXRhKTsKCgkJLy8gQ3JlYXRlIGxvY2F0aW9uIHRleHQgZmllbGQuCgkJbG9jYXRpb25GaWVsZCA9IG5ldyBUZXh0KHRvcENvbXAsIFNXVC5CT1JERVIpOwoJCWRhdGEgPSBuZXcgRm9ybURhdGEoKTsKCQlkYXRhLmxlZnQgPSBuZXcgRm9ybUF0dGFjaG1lbnQoMCwgMCk7CgkJZGF0YS5yaWdodCA9IG5ldyBGb3JtQXR0YWNobWVudChsb2NhdGlvbkJyb3dzZVdvcmtzcGFjZSwgLU1BUkdJTl9TUEFDRSwgU1dULkxFRlQpOwoJCWRhdGEudG9wID0gbmV3IEZvcm1BdHRhY2htZW50KGxvY2F0aW9uQnJvd3NlV29ya3NwYWNlLCBXSURHRVRfU1BBQ0UsIFNXVC5CT1RUT00pOwoJCWRhdGEud2lkdGggPSBGSUVMRF9XSURUSDsKCQlsb2NhdGlvbkZpZWxkLnNldExheW91dERhdGEoZGF0YSk7CgoJCS8vIENyZWF0ZSBsb2NhdGlvbiBicm93c2UgZmlsZSBzeXN0ZW0gYnV0dG9uLgoJCWxvY2F0aW9uQnJvd3NlRmlsZVN5c3RlbSA9IG5ldyBCdXR0b24odG9wQ29tcCwgU1dULlBVU0gpOwoJCWxvY2F0aW9uQnJvd3NlRmlsZVN5c3RlbS5zZXRUZXh0KFRvb2xNZXNzYWdlcy5nZXRTdHJpbmcoIkVkaXREaWFsb2cuYnJvd3NlRmlsZVN5c0J1dHRvbjEiKSk7IC8vJE5PTi1OTFMtMSQKCQlidXR0b25EYXRhWzFdID0gbmV3IEZvcm1EYXRhKCk7CgkJYnV0dG9uRGF0YVsxXS5sZWZ0ID0gbmV3IEZvcm1BdHRhY2htZW50KGxvY2F0aW9uQnJvd3NlV29ya3NwYWNlLCAwLCBTV1QuTEVGVCk7CgkJYnV0dG9uRGF0YVsxXS50b3AgPSBuZXcgRm9ybUF0dGFjaG1lbnQobG9jYXRpb25Ccm93c2VXb3Jrc3BhY2UsIFdJREdFVF9TUEFDRSwgU1dULkJPVFRPTSk7CgkJbG9jYXRpb25Ccm93c2VGaWxlU3lzdGVtLnNldExheW91dERhdGEoYnV0dG9uRGF0YVsxXSk7CgkJY2hlY2tGb3JNYXhXaWR0aChsb2NhdGlvbkJyb3dzZUZpbGVTeXN0ZW0pOwoKCQkvLyBDcmVhdGUgbGFiZWwgZm9yIGFyZ3VtZW50cyB0ZXh0IGZpZWxkLgoJCUxhYmVsIGFyZ3VtZW50c0xhYmVsID0gbmV3IExhYmVsKHRvcENvbXAsIFNXVC5OT05FKTsKCQlhcmd1bWVudHNMYWJlbC5zZXRUZXh0KFRvb2xNZXNzYWdlcy5nZXRTdHJpbmcoIkVkaXREaWFsb2cuYXJndW1lbnRMYWJlbCIpKTsgLy8kTk9OLU5MUy0xJAoJCWRhdGEgPSBuZXcgRm9ybURhdGEoKTsKCQlkYXRhLnRvcCA9IG5ldyBGb3JtQXR0YWNobWVudChsb2NhdGlvbkZpZWxkLCBHUk9VUF9TUEFDRStidXR0b25MYWJlbEhlaWdodERpZmYsIFNXVC5CT1RUT00pOwoJCWFyZ3VtZW50c0xhYmVsLnNldExheW91dERhdGEoZGF0YSk7CgoJCS8vIENyZWF0ZSBhcmd1bWVudHMgdGV4dCBmaWVsZC4KCQlhcmd1bWVudHNGaWVsZCA9IG5ldyBUZXh0KHRvcENvbXAsIFNXVC5CT1JERVIpOwoJCWRhdGEgPSBuZXcgRm9ybURhdGEgKCk7CgkJZGF0YS5sZWZ0ID0gbmV3IEZvcm1BdHRhY2htZW50KDAsIDApOwoJCWRhdGEucmlnaHQgPSBuZXcgRm9ybUF0dGFjaG1lbnQobG9jYXRpb25Ccm93c2VGaWxlU3lzdGVtLCAtTUFSR0lOX1NQQUNFLCBTV1QuTEVGVCk7CgkJZGF0YS50b3AgPSBuZXcgRm9ybUF0dGFjaG1lbnQoYXJndW1lbnRzTGFiZWwsIFdJREdFVF9TUEFDRSwgU1dULkJPVFRPTSk7CgkJZGF0YS53aWR0aCA9IEZJRUxEX1dJRFRIOwoJCWFyZ3VtZW50c0ZpZWxkLnNldExheW91dERhdGEoZGF0YSk7CgoJCS8vIENyZWF0ZSBhcmd1bWVudCBicm93c2UgdmFyaWFibGUgYnV0dG9uLgoJCWFyZ3VtZW50c0Jyb3dzZVZhcmlhYmxlID0gbmV3IEJ1dHRvbih0b3BDb21wLCBTV1QuUFVTSCk7CgkJYXJndW1lbnRzQnJvd3NlVmFyaWFibGUuc2V0VGV4dChUb29sTWVzc2FnZXMuZ2V0U3RyaW5nKCJFZGl0RGlhbG9nLmJyb3dzZVZhcnNCdXR0b24iKSk7IC8vJE5PTi1OTFMtMSQKCQlidXR0b25EYXRhWzJdID0gbmV3IEZvcm1EYXRhKCk7CgkJYnV0dG9uRGF0YVsyXS5sZWZ0ID0gbmV3IEZvcm1BdHRhY2htZW50KGxvY2F0aW9uQnJvd3NlRmlsZVN5c3RlbSwgMCwgU1dULkxFRlQpOwoJCWJ1dHRvbkRhdGFbMl0uYm90dG9tID0gbmV3IEZvcm1BdHRhY2htZW50KGFyZ3VtZW50c0ZpZWxkLCAwLCBTV1QuQk9UVE9NKTsKCQlhcmd1bWVudHNCcm93c2VWYXJpYWJsZS5zZXRMYXlvdXREYXRhKGJ1dHRvbkRhdGFbMl0pOwoJCWNoZWNrRm9yTWF4V2lkdGgoYXJndW1lbnRzQnJvd3NlVmFyaWFibGUpOwoKCQkvLyBDcmVhdGUgZGlyZWN0b3J5IGJyb3dzZSB3b3Jrc3BhY2UgYnV0dG9uLgoJCWRpcmVjdG9yeUJyb3dzZVdvcmtzcGFjZSA9IG5ldyBCdXR0b24odG9wQ29tcCwgU1dULlBVU0gpOwoJCWRpcmVjdG9yeUJyb3dzZVdvcmtzcGFjZS5zZXRUZXh0KFRvb2xNZXNzYWdlcy5nZXRTdHJpbmcoIkVkaXREaWFsb2cuYnJvd3NlV2tzcEJ1dHRvbjIiKSk7IC8vJE5PTi1OTFMtMSQKCQlidXR0b25EYXRhWzNdID0gbmV3IEZvcm1EYXRhKCk7CgkJYnV0dG9uRGF0YVszXS5sZWZ0ID0gbmV3IEZvcm1BdHRhY2htZW50KGFyZ3VtZW50c0Jyb3dzZVZhcmlhYmxlLCAwLCBTV1QuTEVGVCk7CgkJYnV0dG9uRGF0YVszXS50b3AgPSBuZXcgRm9ybUF0dGFjaG1lbnQoYXJndW1lbnRzQnJvd3NlVmFyaWFibGUsIEdST1VQX1NQQUNFLCBTV1QuQk9UVE9NKTsKCQlkaXJlY3RvcnlCcm93c2VXb3Jrc3BhY2Uuc2V0TGF5b3V0RGF0YShidXR0b25EYXRhWzNdKTsKCQljaGVja0Zvck1heFdpZHRoKGRpcmVjdG9yeUJyb3dzZVdvcmtzcGFjZSk7CgoJCS8vIENyZWF0ZSBsYWJlbCBmb3IgZGlyZWN0b3J5IHRleHQgZmllbGQuCgkJTGFiZWwgZGlyTGFiZWwgPSBuZXcgTGFiZWwodG9wQ29tcCwgU1dULk5PTkUpOwoJCWRpckxhYmVsLnNldFRleHQoVG9vbE1lc3NhZ2VzLmdldFN0cmluZygiRWRpdERpYWxvZy5kaXJMYWJlbCIpKTsgLy8kTk9OLU5MUy0xJAoJCWRhdGEgPSBuZXcgRm9ybURhdGEoKTsKCQlkYXRhLmJvdHRvbSA9IG5ldyBGb3JtQXR0YWNobWVudChkaXJlY3RvcnlCcm93c2VXb3Jrc3BhY2UsIDAsIFNXVC5CT1RUT00pOwoJCWRpckxhYmVsLnNldExheW91dERhdGEoZGF0YSk7CgoJCS8vIENyZWF0ZSBkaXJlY3RvcnkgdGV4dCBmaWVsZC4KCQlkaXJlY3RvcnlGaWVsZCA9IG5ldyBUZXh0KHRvcENvbXAsIFNXVC5CT1JERVIpOwoJCWRhdGEgPSBuZXcgRm9ybURhdGEoKTsKCQlkYXRhLmxlZnQgPSBuZXcgRm9ybUF0dGFjaG1lbnQoMCwgMCk7CgkJZGF0YS5yaWdodCA9IG5ldyBGb3JtQXR0YWNobWVudChkaXJlY3RvcnlCcm93c2VXb3Jrc3BhY2UsIC1NQVJHSU5fU1BBQ0UsIFNXVC5MRUZUKTsKCQlkYXRhLnRvcCA9IG5ldyBGb3JtQXR0YWNobWVudChkaXJlY3RvcnlCcm93c2VXb3Jrc3BhY2UsIFdJREdFVF9TUEFDRSwgU1dULkJPVFRPTSk7CgkJZGF0YS53aWR0aCA9IEZJRUxEX1dJRFRIOwoJCWRpcmVjdG9yeUZpZWxkLnNldExheW91dERhdGEoZGF0YSk7CgoJCS8vIENyZWF0ZSBkaXJlY3RvcnkgYnJvd3NlIGZpbGUgc3lzdGVtIGJ1dHRvbi4KCQlkaXJlY3RvcnlCcm93c2VGaWxlU3lzdGVtID0gbmV3IEJ1dHRvbih0b3BDb21wLCBTV1QuUFVTSCk7CgkJZGlyZWN0b3J5QnJvd3NlRmlsZVN5c3RlbS5zZXRUZXh0KFRvb2xNZXNzYWdlcy5nZXRTdHJpbmcoIkVkaXREaWFsb2cuYnJvd3NlRmlsZVN5c0J1dHRvbjIiKSk7IC8vJE5PTi1OTFMtMSQKCQlidXR0b25EYXRhWzRdID0gbmV3IEZvcm1EYXRhKCk7CgkJYnV0dG9uRGF0YVs0XS5sZWZ0ID0gbmV3IEZvcm1BdHRhY2htZW50KGFyZ3VtZW50c0ZpZWxkLCBNQVJHSU5fU1BBQ0UsIFNXVC5SSUdIVCk7CgkJYnV0dG9uRGF0YVs0XS5ib3R0b20gPSBuZXcgRm9ybUF0dGFjaG1lbnQoZGlyZWN0b3J5RmllbGQsIDAsIFNXVC5CT1RUT00pOwoJCWRpcmVjdG9yeUJyb3dzZUZpbGVTeXN0ZW0uc2V0TGF5b3V0RGF0YShidXR0b25EYXRhWzRdKTsKCQljaGVja0Zvck1heFdpZHRoKGRpcmVjdG9yeUJyb3dzZUZpbGVTeXN0ZW0pOwoJCQoJCS8vIENyZWF0ZSByZWZyZXNoIGNoZWNrIGJveCBhbmQgbGFiZWwuCgkJTGFiZWwgcmVmcmVzaExhYmVsID0gbmV3IExhYmVsKHRvcENvbXAsIFNXVC5OT05FKTsKCQlyZWZyZXNoTGFiZWwuc2V0VGV4dChUb29sTWVzc2FnZXMuZ2V0U3RyaW5nKCJFZGl0RGlhbG9nLnJlZnJlc2hPcHRpb24iKSk7IC8vJE5PTi1OTFMtMSQKCQlkYXRhID0gbmV3IEZvcm1EYXRhKCk7CgkJZGF0YS5sZWZ0ID0gbmV3IEZvcm1BdHRhY2htZW50KDAsMCk7CgkJZGF0YS50b3AgPSBuZXcgRm9ybUF0dGFjaG1lbnQoZGlyZWN0b3J5RmllbGQsIEdST1VQX1NQQUNFK2J1dHRvbkxhYmVsSGVpZ2h0RGlmZiwgU1dULkJPVFRPTSk7CgkJcmVmcmVzaExhYmVsLnNldExheW91dERhdGEoZGF0YSk7CgkJCgkJLy8gQ3JlYXRlIHJlZnJlc2ggdGV4dCBmaWVsZC4KCQlyZWZyZXNoRmllbGQgPSBuZXcgVGV4dCh0b3BDb21wLCBTV1QuU0lOR0xFIHwgU1dULkhfU0NST0xMIHwgU1dULkJPUkRFUik7CgkJcmVmcmVzaEZpZWxkLnNldEVkaXRhYmxlKGZhbHNlKTsKCQlkYXRhID0gbmV3IEZvcm1EYXRhKCk7CgkJZGF0YS5sZWZ0ID0gbmV3IEZvcm1BdHRhY2htZW50KHJlZnJlc2hMYWJlbCwgTUFSR0lOX1NQQUNFLCBTV1QuUklHSFQpOwoJCWRhdGEudG9wID0gbmV3IEZvcm1BdHRhY2htZW50KHJlZnJlc2hMYWJlbCwgMCwgU1dULkNFTlRFUik7CgkJZGF0YS53aWR0aCA9IEZJRUxEX1dJRFRIIC0gTUFSR0lOX1NQQUNFIC0gcmVmcmVzaExhYmVsLmNvbXB1dGVTaXplKFNXVC5ERUZBVUxULCBTV1QuREVGQVVMVCwgZmFsc2UpLng7CgkJcmVmcmVzaEZpZWxkLnNldExheW91dERhdGEoZGF0YSk7CgoJCS8vIENyZWF0ZSByZWZyZXNoIHNjb3BlLgoJCXJlZnJlc2hPcHRpb25CdXR0b24gPSBuZXcgQnV0dG9uKHRvcENvbXAsIFNXVC5QVVNIKTsKCQlyZWZyZXNoT3B0aW9uQnV0dG9uLnNldFRleHQoVG9vbE1lc3NhZ2VzLmdldFN0cmluZygiRWRpdERpYWxvZy5yZWZyZXNoT3B0aW9uQnV0dG9uIikpOyAvLyROT04tTkxTLTEkCgkJYnV0dG9uRGF0YVs1XSA9IG5ldyBGb3JtRGF0YSgpOwoJCWJ1dHRvbkRhdGFbNV0ubGVmdCA9IG5ldyBGb3JtQXR0YWNobWVudChkaXJlY3RvcnlCcm93c2VGaWxlU3lzdGVtLCAwLCBTV1QuTEVGVCk7CgkJYnV0dG9uRGF0YVs1XS50b3AgPSBuZXcgRm9ybUF0dGFjaG1lbnQocmVmcmVzaEZpZWxkLCAwLCBTV1QuVE9QKTsKCQlyZWZyZXNoT3B0aW9uQnV0dG9uLnNldExheW91dERhdGEoYnV0dG9uRGF0YVs1XSk7CgkJCgkJLy8gQ3JlYXRlIHNob3cgbG9nIGNoZWNrYm94CgkJc2hvd0xvZyA9IG5ldyBCdXR0b24odG9wQ29tcCwgU1dULkNIRUNLKTsKCQlzaG93TG9nLnNldFRleHQoVG9vbE1lc3NhZ2VzLmdldFN0cmluZygiRWRpdERpYWxvZy5zaG93TG9nTGFiZWwiKSk7IC8vJE5PTi1OTFMtMSQKCQlzaG93TG9nLnNldFNlbGVjdGlvbihJTklUSUFMX1NIT1dfTE9HKTsKCQlkYXRhID0gbmV3IEZvcm1EYXRhKCk7CgkJZGF0YS5sZWZ0ID0gbmV3IEZvcm1BdHRhY2htZW50KDAsMCk7CgkJZGF0YS50b3AgPSBuZXcgRm9ybUF0dGFjaG1lbnQocmVmcmVzaEZpZWxkLCBHUk9VUF9TUEFDRSwgU1dULkJPVFRPTSk7CgkJc2hvd0xvZy5zZXRMYXlvdXREYXRhKGRhdGEpOwoJCQoJCS8vIGdpdmUgYWxsIHRoZSBidXR0b25zIHRoZSBzYW1lIHdpZHRoCgkJZm9yIChpbnQgaT0wOyBpPGJ1dHRvbkRhdGEubGVuZ3RoOyBpKyspIHsKCQkJYnV0dG9uRGF0YVtpXS53aWR0aCA9IG1heEJ1dHRvbldpZHRoOwkKCQl9CQoJCQoJCS8vIEJ1aWxkIHRoZSBzZXBhcmF0b3IgbGluZQoJCUxhYmVsIHNlcGFyYXRvciA9IG5ldyBMYWJlbChkaWFsb2dDb21wLCBTV1QuSE9SSVpPTlRBTCB8IFNXVC5TRVBBUkFUT1IpOwoJCXNlcGFyYXRvci5zZXRMYXlvdXREYXRhKG5ldyBHcmlkRGF0YShHcmlkRGF0YS5GSUxMX0hPUklaT05UQUwpKTsKCQkKCQkvLyBJbml0IGZpZWxkIHZhbHVlcwoJCWlmIChlZGl0TW9kZSkgewoJCQluYW1lRmllbGQuc2V0VGV4dCh0b29sLmdldE5hbWUoKSk7CgkJCWxvY2F0aW9uRmllbGQuc2V0VGV4dCh0b29sLmdldExvY2F0aW9uKCkpOwoJCQlhcmd1bWVudHNGaWVsZC5zZXRUZXh0KHRvb2wuZ2V0QXJndW1lbnRzKCkpOwoJCQlkaXJlY3RvcnlGaWVsZC5zZXRUZXh0KHRvb2wuZ2V0V29ya2luZ0RpcmVjdG9yeSgpKTsKCQkJc2hvd0xvZy5zZXRTZWxlY3Rpb24odG9vbC5nZXRTaG93TG9nKCkpOwoJCX0KCQlyZWZyZXNoU2NvcGUgPSB0b29sLmdldFJlZnJlc2hTY29wZSgpOwoJCXVwZGF0ZVJlZnJlc2hGaWVsZCgpOwoKCQkvLyBTZXQgdGhlIHByb3BlciB0YWIgb3JkZXIKCQlDb250cm9sW10gdGFiTGlzdCA9IG5ldyBDb250cm9sW10gewoJCQluYW1lRmllbGQsIAoJCQlsb2NhdGlvbkZpZWxkLCAKCQkJbG9jYXRpb25Ccm93c2VXb3Jrc3BhY2UsCgkJCWxvY2F0aW9uQnJvd3NlRmlsZVN5c3RlbSwKCQkJYXJndW1lbnRzRmllbGQsCgkJCWFyZ3VtZW50c0Jyb3dzZVZhcmlhYmxlLAoJCQlkaXJlY3RvcnlGaWVsZCwKCQkJZGlyZWN0b3J5QnJvd3NlV29ya3NwYWNlLAoJCQlkaXJlY3RvcnlCcm93c2VGaWxlU3lzdGVtLAoJCQlyZWZyZXNoRmllbGQsCgkJCXJlZnJlc2hPcHRpb25CdXR0b259OwoJCXRvcENvbXAuc2V0VGFiTGlzdCh0YWJMaXN0KTsKCQkKCQkvLyBGaW5pc2ggc2V0dXAKCQlob29rQnV0dG9uQWN0aW9ucygpOwoJCWhvb2tGaWVsZFZhbGlkYXRpb24oKTsKCQluYW1lRmllbGQuc2V0Rm9jdXMoKTsKCQkKCQlyZXR1cm4gZGlhbG9nQ29tcDsKCX0KCQoJLyoqCgkgKiBDaGVjayB0byBzZWUgaWYgdGhlIHN1cHBsaWVkIGJ1dHRvbiBoYXMgdGhlIG1heGltdW0gd2lkdGggb2YKCSAqIGFsbCB0aGUgYnV0dG9ucyBzbyBmYXIuIElmIGl0IGlzLCBzdG9yZSB0aGUgd2lkdGggaW4KCSAqIHRoZSBpbnRlZ2VyIHZhcmlhYmxlIDxjb2RlPm1heEJ1dHRvbldpZHRoPC9jb2RlPi4KCSAqLwoJcHJpdmF0ZSB2b2lkIGNoZWNrRm9yTWF4V2lkdGgoQnV0dG9uIGJ1dHRvbikgewoJCVBvaW50IHNpemUgPSBidXR0b24uY29tcHV0ZVNpemUoU1dULkRFRkFVTFQsIFNXVC5ERUZBVUxULCB0cnVlKTsKCQlpZiAoc2l6ZS54ID4gbWF4QnV0dG9uV2lkdGgpCgkJCW1heEJ1dHRvbldpZHRoID0gc2l6ZS54OwkJCgl9CgkKCS8qKgoJICogUmV0dXJucyB0aGUgdG9vbCB0b29sIGFwcGxpY2FibGUgdG8gdGhpcyBkaWFsb2cuCgkgKi8KCXB1YmxpYyBFeHRlcm5hbFRvb2wgZ2V0RXh0ZXJuYWxUb29sKCkgewoJCXJldHVybiB0b29sOwoJfQoJCgkvKioKCSAqIEhvb2tzIHRoZSBhY3Rpb24gaGFuZGxlciBmb3Igd2hlbiBhIGJ1dHRvbiBpcyBwcmVzc2VkCgkgKi8KCXByaXZhdGUgdm9pZCBob29rQnV0dG9uQWN0aW9ucygpIHsKCQlsb2NhdGlvbkJyb3dzZVdvcmtzcGFjZS5hZGRTZWxlY3Rpb25MaXN0ZW5lcihuZXcgU2VsZWN0aW9uQWRhcHRlcigpIHsKCQkJcHVibGljIHZvaWQgd2lkZ2V0U2VsZWN0ZWQoU2VsZWN0aW9uRXZlbnQgZSkgewoJCQkJUmVzb3VyY2VTZWxlY3Rpb25EaWFsb2cgZGlhbG9nOwoJCQkJZGlhbG9nID0gbmV3IFJlc291cmNlU2VsZWN0aW9uRGlhbG9nKGdldFNoZWxsKCksIFJlc291cmNlc1BsdWdpbi5nZXRXb3Jrc3BhY2UoKS5nZXRSb290KCkpOwoJCQkJZGlhbG9nLm9wZW4oKTsKCQkJCU9iamVjdFtdIHJlc3VsdHMgPSBkaWFsb2cuZ2V0UmVzdWx0KCk7CgkJCQlpZiAocmVzdWx0cyA9PSBudWxsIHx8IHJlc3VsdHMubGVuZ3RoIDwgMSkKCQkJCQlyZXR1cm47CgkJCQlJUmVzb3VyY2UgcmVzb3VyY2UgPSAoSVJlc291cmNlKXJlc3VsdHNbMF07CgkJCQlTdHJpbmcgdmFyID0gVG9vbFV0aWwuYnVpbGRWYXJpYWJsZVRhZyhFeHRlcm5hbFRvb2wuVkFSX1dPUktTUEFDRV9MT0MsIG51bGwpOwoJCQkJbG9jYXRpb25GaWVsZC5zZXRUZXh0KHZhciArIHJlc291cmNlLmdldEZ1bGxQYXRoKCkpOwoJCQl9CgkJfSk7CgkJCgkJbG9jYXRpb25Ccm93c2VGaWxlU3lzdGVtLmFkZFNlbGVjdGlvbkxpc3RlbmVyKG5ldyBTZWxlY3Rpb25BZGFwdGVyKCkgewoJCQlwdWJsaWMgdm9pZCB3aWRnZXRTZWxlY3RlZChTZWxlY3Rpb25FdmVudCBlKSB7CgkJCQlGaWxlRGlhbG9nIGRpYWxvZyA9IG5ldyBGaWxlRGlhbG9nKGdldFNoZWxsKCksIFNXVC5OT05FKTsKCQkJCWRpYWxvZy5zZXRGaWxlTmFtZShsb2NhdGlvbkZpZWxkLmdldFRleHQoKSk7CgkJCQlTdHJpbmcgZmlsZW5hbWUgPSBkaWFsb2cub3BlbigpOwoJCQkJaWYgKGZpbGVuYW1lICE9IG51bGwpIHsKCQkJCQlsb2NhdGlvbkZpZWxkLnNldFRleHQoZmlsZW5hbWUpOwoJCQkJfQoJCQl9CgkJfSk7CgoJCWFyZ3VtZW50c0Jyb3dzZVZhcmlhYmxlLmFkZFNlbGVjdGlvbkxpc3RlbmVyKG5ldyBTZWxlY3Rpb25BZGFwdGVyKCkgewoJCQlwdWJsaWMgdm9pZCB3aWRnZXRTZWxlY3RlZChTZWxlY3Rpb25FdmVudCBlKSB7CgkJCQlWYXJpYWJsZVNlbGVjdGlvbkRpYWxvZyBkaWFsb2c7CgkJCQlkaWFsb2cgPSBuZXcgVmFyaWFibGVTZWxlY3Rpb25EaWFsb2coZ2V0U2hlbGwoKSk7CgkJCQlkaWFsb2cub3BlbigpOwoJCQkJT2JqZWN0W10gcmVzdWx0cyA9IGRpYWxvZy5nZXRSZXN1bHQoKTsKCQkJCWlmIChyZXN1bHRzID09IG51bGwgfHwgcmVzdWx0cy5sZW5ndGggPCAxKQoJCQkJCXJldHVybjsKCQkJCVN0cmluZyBhcmdzID0gYXJndW1lbnRzRmllbGQuZ2V0VGV4dCgpOwoJCQkJYXJncyA9IGFyZ3MgKyAoU3RyaW5nKXJlc3VsdHNbMF07CgkJCQlhcmd1bWVudHNGaWVsZC5zZXRUZXh0KGFyZ3MpOwoJCQl9CgkJfSk7CgkJCgkJZGlyZWN0b3J5QnJvd3NlV29ya3NwYWNlLmFkZFNlbGVjdGlvbkxpc3RlbmVyKG5ldyBTZWxlY3Rpb25BZGFwdGVyKCkgewoJCQlwdWJsaWMgdm9pZCB3aWRnZXRTZWxlY3RlZChTZWxlY3Rpb25FdmVudCBlKSB7CgkJCQlDb250YWluZXJTZWxlY3Rpb25EaWFsb2cgZGlhbG9nID0gbmV3IENvbnRhaW5lclNlbGVjdGlvbkRpYWxvZygKCQkJCQlnZXRTaGVsbCgpLCAKCQkJCQlSZXNvdXJjZXNQbHVnaW4uZ2V0V29ya3NwYWNlKCkuZ2V0Um9vdCgpLCAKCQkJCQlmYWxzZSwgCgkJCQkJVG9vbE1lc3NhZ2VzLmdldFN0cmluZygiRWRpdERpYWxvZy5zZWxlY3RGb2xkZXIiKSk7IC8vJE5PTi1OTFMtMSQKCQkJCWRpYWxvZy5zaG93Q2xvc2VkUHJvamVjdHMoZmFsc2UpOwoJCQkJZGlhbG9nLnNldFRpdGxlKFRvb2xNZXNzYWdlcy5nZXRTdHJpbmcoIkVkaXREaWFsb2cuYnJvd3NlV29ya3NwYWNlVGl0bGUiKSk7IC8vJE5PTi1OTFMtMSQKCQkJCWRpYWxvZy5vcGVuKCk7CgkJCQlPYmplY3RbXSByZXN1bHQgPSBkaWFsb2cuZ2V0UmVzdWx0KCk7CgkJCQlpZiAocmVzdWx0ICE9IG51bGwgJiYgcmVzdWx0Lmxlbmd0aCA9PSAxKSB7CgkJCQkJU3RyaW5nQnVmZmVyIGJ1ZiA9IG5ldyBTdHJpbmdCdWZmZXIoKTsKCQkJCQlUb29sVXRpbC5idWlsZFZhcmlhYmxlVGFnKEV4dGVybmFsVG9vbC5WQVJfV09SS1NQQUNFX0xPQywgbnVsbCwgYnVmKTsKCQkJCQlidWYuYXBwZW5kKHJlc3VsdFswXS50b1N0cmluZygpKTsKCQkJCQlkaXJlY3RvcnlGaWVsZC5zZXRUZXh0KGJ1Zi50b1N0cmluZygpKTsKCQkJCX0KCQkJfQoJCX0pOwoJCQoJCWRpcmVjdG9yeUJyb3dzZUZpbGVTeXN0ZW0uYWRkU2VsZWN0aW9uTGlzdGVuZXIobmV3IFNlbGVjdGlvbkFkYXB0ZXIoKSB7CgkJCXB1YmxpYyB2b2lkIHdpZGdldFNlbGVjdGVkKFNlbGVjdGlvbkV2ZW50IGUpIHsKCQkJCURpcmVjdG9yeURpYWxvZyBkaWFsb2cgPSBuZXcgRGlyZWN0b3J5RGlhbG9nKGdldFNoZWxsKCksIFNXVC5TQVZFKTsKCQkJCWRpYWxvZy5zZXRNZXNzYWdlKFRvb2xNZXNzYWdlcy5nZXRTdHJpbmcoIkVkaXREaWFsb2cuc2VsZWN0RGlyZWN0b3J5IikpOyAvLyROT04tTkxTLTEkCgkJCQlkaWFsb2cuc2V0RmlsdGVyUGF0aChkaXJlY3RvcnlGaWVsZC5nZXRUZXh0KCkpOwoJCQkJU3RyaW5nIHNlbGVjdGVkRGlyZWN0b3J5ID0gZGlhbG9nLm9wZW4oKTsKCQkJCWlmIChzZWxlY3RlZERpcmVjdG9yeSAhPSBudWxsKSB7CgkJCQkJZGlyZWN0b3J5RmllbGQuc2V0VGV4dChzZWxlY3RlZERpcmVjdG9yeSk7CgkJCQl9CgkJCX0KCQl9KTsKCgkJcmVmcmVzaE9wdGlvbkJ1dHRvbi5hZGRTZWxlY3Rpb25MaXN0ZW5lcihuZXcgU2VsZWN0aW9uQWRhcHRlcigpIHsKCQkJcHVibGljIHZvaWQgd2lkZ2V0U2VsZWN0ZWQoU2VsZWN0aW9uRXZlbnQgZSkgewoJCQkJUmVmcmVzaFNlbGVjdGlvbkRpYWxvZyBkaWFsb2c7CgkJCQlkaWFsb2cgPSBuZXcgUmVmcmVzaFNlbGVjdGlvbkRpYWxvZyhnZXRTaGVsbCgpKTsKCQkJCWRpYWxvZy5vcGVuKCk7CgkJCQlPYmplY3RbXSByZXN1bHRzID0gZGlhbG9nLmdldFJlc3VsdCgpOwoJCQkJaWYgKHJlc3VsdHMgPT0gbnVsbCB8fCByZXN1bHRzLmxlbmd0aCA8IDEpCgkJCQkJcmV0dXJuOwoJCQkJcmVmcmVzaFNjb3BlID0gKFN0cmluZylyZXN1bHRzWzBdOwoJCQkJdXBkYXRlUmVmcmVzaEZpZWxkKCk7CgkJCX0KCQl9KTsKCX0KCQoJLyoqCgkgKiBIb29rcyB0aGUgbmVjZXNzYXJ5IGZpZWxkIHZhbGlkYXRpb24KCSAqLwoJcHJpdmF0ZSB2b2lkIGhvb2tGaWVsZFZhbGlkYXRpb24oKSB7CgkJbmFtZUZpZWxkLmFkZE1vZGlmeUxpc3RlbmVyKG5ldyBNb2RpZnlMaXN0ZW5lcigpIHsKCQkJcHVibGljIHZvaWQgbW9kaWZ5VGV4dChNb2RpZnlFdmVudCBlKSB7CgkJCQl2YWxpZGF0ZUZpZWxkcygpOwoJCQl9CgkJfSk7CgkJCgkJbG9jYXRpb25GaWVsZC5hZGRNb2RpZnlMaXN0ZW5lcihuZXcgTW9kaWZ5TGlzdGVuZXIoKSB7CgkJCXB1YmxpYyB2b2lkIG1vZGlmeVRleHQoTW9kaWZ5RXZlbnQgZSkgewoJCQkJdmFsaWRhdGVGaWVsZHMoKTsKCQkJfQoJCX0pOwoJCQoJCWRpcmVjdG9yeUZpZWxkLmFkZE1vZGlmeUxpc3RlbmVyKG5ldyBNb2RpZnlMaXN0ZW5lcigpIHsKCQkJcHVibGljIHZvaWQgbW9kaWZ5VGV4dChNb2RpZnlFdmVudCBlKSB7CgkJCQl2YWxpZGF0ZUZpZWxkcygpOwoJCQl9CgkJfSk7Cgl9CgoJLyoqCgkgKiBWYWxpZGF0ZSB0aGUgZmllbGRzIGZvciBhY2NlcHRhYmxlIHZhbHVlcwoJICovCglwcml2YXRlIHZvaWQgdmFsaWRhdGVGaWVsZHMoKSB7CgkJU3RyaW5nIHZhbHVlID0gbmFtZUZpZWxkLmdldFRleHQoKS50cmltKCk7CgkJaWYgKHZhbHVlLmxlbmd0aCgpIDwgMSkgewoJCQlzZXRNZXNzYWdlKFRvb2xNZXNzYWdlcy5nZXRTdHJpbmcoIkVkaXREaWFsb2cubm9Ub29sTmFtZSIpLCBJTWVzc2FnZVByb3ZpZGVyLk5PTkUpOyAvLyROT04tTkxTLTEkCgkJCWdldEJ1dHRvbihJRGlhbG9nQ29uc3RhbnRzLk9LX0lEKS5zZXRFbmFibGVkKGZhbHNlKTsKCQkJcmV0dXJuOwoJCX0KCQkKCQl2YWx1ZSA9IGxvY2F0aW9uRmllbGQuZ2V0VGV4dCgpLnRyaW0oKTsKCQlpZiAodmFsdWUubGVuZ3RoKCkgPCAxKSB7CgkJCXNldE1lc3NhZ2UoVG9vbE1lc3NhZ2VzLmdldFN0cmluZygiRWRpdERpYWxvZy5ub1Rvb2xMb2NhdGlvbiIpLCBJTWVzc2FnZVByb3ZpZGVyLk5PTkUpOyAvLyROT04tTkxTLTEkCgkJCWdldEJ1dHRvbihJRGlhbG9nQ29uc3RhbnRzLk9LX0lEKS5zZXRFbmFibGVkKGZhbHNlKTsKCQkJcmV0dXJuOwoJCX0KCgkJZ2V0QnV0dG9uKElEaWFsb2dDb25zdGFudHMuT0tfSUQpLnNldEVuYWJsZWQodHJ1ZSk7CgkJCgkJRmlsZSBmaWxlID0gbmV3IEZpbGUodmFsdWUpOwoJCWlmICghZmlsZS5leGlzdHMoKSkgewoJCQlzZXRNZXNzYWdlKFRvb2xNZXNzYWdlcy5nZXRTdHJpbmcoIkVkaXREaWFsb2cubWlzc2luZ1Rvb2xMb2NhdGlvbiIpLCBJTWVzc2FnZVByb3ZpZGVyLldBUk5JTkcpOyAvLyROT04tTkxTLTEkCgkJCXJldHVybjsKCQl9CgkJCgkJdmFsdWUgPSBkaXJlY3RvcnlGaWVsZC5nZXRUZXh0KCkudHJpbSgpOwoJCWlmICh2YWx1ZS5sZW5ndGgoKSA+IDApIHsKCQkJZmlsZSA9IG5ldyBGaWxlKHZhbHVlKTsKCQkJaWYgKCFmaWxlLmV4aXN0cygpKSB7CgkJCQlzZXRNZXNzYWdlKFRvb2xNZXNzYWdlcy5nZXRTdHJpbmcoIkVkaXREaWFsb2cubWlzc2luZ1Rvb2xEaXJlY3RvcnkiKSwgSU1lc3NhZ2VQcm92aWRlci5XQVJOSU5HKTsgLy8kTk9OLU5MUy0xJAoJCQkJcmV0dXJuOwoJCQl9CgkJfQoJCQoJCWlmIChlZGl0TW9kZSkKCQkJc2V0TWVzc2FnZShUb29sTWVzc2FnZXMuZ2V0U3RyaW5nKCJFZGl0RGlhbG9nLmVkaXREaWFsb2dNZXNzYWdlIikpOyAvLyROT04tTkxTLTEkCgkJZWxzZQoJCQlzZXRNZXNzYWdlKFRvb2xNZXNzYWdlcy5nZXRTdHJpbmcoIkVkaXREaWFsb2cubmV3RGlhbG9nTWVzc2FnZSIpKTsgLy8kTk9OLU5MUy0xJAoJfQoJCgkvKiAobm9uLUphdmFkb2MpCgkgKiBNZXRob2QgZGVjbGFyZWQgb24gRGlhbG9nLgoJICovCglwcm90ZWN0ZWQgdm9pZCBva1ByZXNzZWQoKSB7CgkJU3RyaW5nIGNvbW1hbmQgPSBsb2NhdGlvbkZpZWxkLmdldFRleHQoKS50cmltKCk7CgkJaWYgKGNvbW1hbmQuZW5kc1dpdGgoIi54bWwiKSkgLy8kTk9OLU5MUy0xJAoJCQl0b29sLnNldFR5cGUodG9vbC5UT09MX1RZUEVfQU5UKTsKCQllbHNlCgkJCXRvb2wuc2V0VHlwZSh0b29sLlRPT0xfVFlQRV9QUk9HUkFNKTsKCQl0b29sLnNldE5hbWUobmFtZUZpZWxkLmdldFRleHQoKS50cmltKCkpOwoJCXRvb2wuc2V0TG9jYXRpb24oY29tbWFuZCk7CgkJdG9vbC5zZXRBcmd1bWVudHMoYXJndW1lbnRzRmllbGQuZ2V0VGV4dCgpLnRyaW0oKSk7CgkJdG9vbC5zZXRXb3JraW5nRGlyZWN0b3J5KGRpcmVjdG9yeUZpZWxkLmdldFRleHQoKS50cmltKCkpOwoJCXRvb2wuc2V0UmVmcmVzaFNjb3BlKHJlZnJlc2hTY29wZSk7CgkJdG9vbC5zZXRTaG93TG9nKHNob3dMb2cuZ2V0U2VsZWN0aW9uKCkpOwoJCQoJCXN1cGVyLm9rUHJlc3NlZCgpOwoJfQoJCgkvKioKCSAqIFVwZGF0ZSB0aGUgcmVmcmVzaCBzY29wZSBmaWVsZAoJICovCglwcml2YXRlIHZvaWQgdXBkYXRlUmVmcmVzaEZpZWxkKCkgewoJCVRvb2xVdGlsLlZhcmlhYmxlRGVmaW5pdGlvbiByZXN1bHQgPSBUb29sVXRpbC5leHRyYWN0VmFyaWFibGVUYWcocmVmcmVzaFNjb3BlLCAwKTsKCQlpZiAocmVzdWx0Lm5hbWUgPT0gbnVsbCkgewoJCQlyZWZyZXNoU2NvcGUgPSBUb29sVXRpbC5idWlsZFZhcmlhYmxlVGFnKHRvb2wuUkVGUkVTSF9TQ09QRV9OT05FLCBudWxsKTsKCQkJcmVzdWx0Lm5hbWUgPSB0b29sLlJFRlJFU0hfU0NPUEVfTk9ORTsKCQl9CgkJCgkJaWYgKHRvb2wuUkVGUkVTSF9TQ09QRV9OT05FLmVxdWFscyhyZXN1bHQubmFtZSkpIHsKCQkJcmVmcmVzaEZpZWxkLnNldFRleHQoVG9vbE1lc3NhZ2VzLmdldFN0cmluZygiRWRpdERpYWxvZy5yZWZyZXNoU2NvcGVOb25lIikpOyAvLyROT04tTkxTLTEkCgkJCXJldHVybjsKCQl9CgkJaWYgKHRvb2wuUkVGUkVTSF9TQ09QRV9XT1JLU1BBQ0UuZXF1YWxzKHJlc3VsdC5uYW1lKSkgewoJCQlyZWZyZXNoRmllbGQuc2V0VGV4dChUb29sTWVzc2FnZXMuZ2V0U3RyaW5nKCJFZGl0RGlhbG9nLnJlZnJlc2hTY29wZVdvcmtzcGFjZSIpKTsgLy8kTk9OLU5MUy0xJAoJCQlyZXR1cm47CgkJfQoJCWlmICh0b29sLlJFRlJFU0hfU0NPUEVfUFJPSkVDVC5lcXVhbHMocmVzdWx0Lm5hbWUpKSB7CgkJCWlmIChyZXN1bHQuYXJndW1lbnQgPT0gbnVsbCkKCQkJCXJlZnJlc2hGaWVsZC5zZXRUZXh0KFRvb2xNZXNzYWdlcy5nZXRTdHJpbmcoIkVkaXREaWFsb2cucmVmcmVzaFNjb3BlUHJvamVjdCIpKTsgLy8kTk9OLU5MUy0xJAoJCQllbHNlCgkJCQlyZWZyZXNoRmllbGQuc2V0VGV4dChUb29sTWVzc2FnZXMuZm9ybWF0KCJFZGl0RGlhbG9nLnJlZnJlc2hTY29wZVByb2plY3RYIiwgbmV3IE9iamVjdFtdIHtyZXN1bHQuYXJndW1lbnR9KSk7IC8vJE5PTi1OTFMtMSQKCQkJcmV0dXJuOwoJCX0KCQlpZiAodG9vbC5SRUZSRVNIX1NDT1BFX1dPUktJTkdfU0VULmVxdWFscyhyZXN1bHQubmFtZSkpIHsKCQkJaWYgKHJlc3VsdC5hcmd1bWVudCA9PSBudWxsKSB7CgkJCQlyZWZyZXNoU2NvcGUgPSBUb29sVXRpbC5idWlsZFZhcmlhYmxlVGFnKHRvb2wuUkVGUkVTSF9TQ09QRV9OT05FLCBudWxsKTsKCQkJCXJlZnJlc2hGaWVsZC5zZXRUZXh0KFRvb2xNZXNzYWdlcy5nZXRTdHJpbmcoIkVkaXREaWFsb2cucmVmcmVzaFNjb3BlTm9uZSIpKTsgLy8kTk9OLU5MUy0xJAoJCQl9CgkJCWVsc2UKCQkJCXJlZnJlc2hGaWVsZC5zZXRUZXh0KFRvb2xNZXNzYWdlcy5mb3JtYXQoIkVkaXREaWFsb2cucmVmcmVzaFNjb3BlV29ya2luZ1NldCIsIG5ldyBPYmplY3RbXSB7cmVzdWx0LmFyZ3VtZW50fSkpOyAvLyROT04tTkxTLTEkCgkJCXJldHVybjsKCQl9Cgl9CgkKCS8qKgoJICogSW50ZXJuYWwgZGlhbG9nIHRvIHNob3cgYXZhaWxhYmxlIHJlc291cmNlcyBmcm9tIHdoaWNoCgkgKiB0aGUgdXNlciBjYW4gc2VsZWN0IG9uZQoJICovCglwcml2YXRlIGNsYXNzIFJlc291cmNlU2VsZWN0aW9uRGlhbG9nIGV4dGVuZHMgU2VsZWN0aW9uRGlhbG9nIHsKCQlJQ29udGFpbmVyIHJvb3Q7CgkJVHJlZVZpZXdlciB3c1RyZWU7CgkJCgkJcHVibGljIFJlc291cmNlU2VsZWN0aW9uRGlhbG9nKFNoZWxsIHBhcmVudCwgSUNvbnRhaW5lciByb290KSB7CgkJCXN1cGVyKHBhcmVudCk7CgkJCXRoaXMucm9vdCA9IHJvb3Q7CgkJCXNldFNoZWxsU3R5bGUoZ2V0U2hlbGxTdHlsZSgpIHwgU1dULlJFU0laRSk7CgkJCXNldFRpdGxlKFRvb2xNZXNzYWdlcy5nZXRTdHJpbmcoIkVkaXREaWFsb2cuYnJvd3NlV29ya3NwYWNlVGl0bGUiKSk7IC8vJE5PTi1OTFMtMSQKCQl9CgoJCS8qIChub24tSmF2YWRvYykKCQkgKiBNZXRob2QgZGVjbGFyZWQgb24gRGlhbG9nLgoJCSAqLwoJCXByb3RlY3RlZCBDb250cm9sIGNyZWF0ZURpYWxvZ0FyZWEoQ29tcG9zaXRlIHBhcmVudCkgewoJCQkvLyBjcmVhdGUgY29tcG9zaXRlIAoJCQlDb21wb3NpdGUgZGlhbG9nQXJlYSA9IChDb21wb3NpdGUpc3VwZXIuY3JlYXRlRGlhbG9nQXJlYShwYXJlbnQpOwoJCQkKCQkJTGFiZWwgbGFiZWwgPSBuZXcgTGFiZWwoZGlhbG9nQXJlYSwgU1dULkxFRlQpOwoJCQlsYWJlbC5zZXRUZXh0KFRvb2xNZXNzYWdlcy5nZXRTdHJpbmcoIkVkaXREaWFsb2cuc2VsZWN0UmVzb3VyY2UiKSk7IC8vJE5PTi1OTFMtMSQKCQkJCgkJCVRyZWUgdHJlZSA9IG5ldyBUcmVlKGRpYWxvZ0FyZWEsIFNXVC5IX1NDUk9MTCB8IFNXVC5WX1NDUk9MTCB8IFNXVC5TSU5HTEUgfCBTV1QuQk9SREVSKTsKCQkJR3JpZERhdGEgZGF0YSA9IG5ldyBHcmlkRGF0YShHcmlkRGF0YS5GSUxMX0JPVEgpOwoJCQlkYXRhLmhlaWdodEhpbnQgPSBTSVpJTkdfU0VMRUNUSU9OX1BBTkVfSEVJR0hUOwoJCQlkYXRhLndpZHRoSGludCA9IFNJWklOR19TRUxFQ1RJT05fUEFORV9XSURUSDsKCQkJdHJlZS5zZXRMYXlvdXREYXRhKGRhdGEpOwoJCQl3c1RyZWUgPSBuZXcgVHJlZVZpZXdlcih0cmVlKTsKCQkJd3NUcmVlLnNldENvbnRlbnRQcm92aWRlcihuZXcgV29ya2JlbmNoQ29udGVudFByb3ZpZGVyKCkpOwoJCQl3c1RyZWUuc2V0TGFiZWxQcm92aWRlcihuZXcgV29ya2JlbmNoTGFiZWxQcm92aWRlcigpKTsKCQkJd3NUcmVlLnNldElucHV0KHJvb3QpOwoJCQkKCQkJcmV0dXJuIGRpYWxvZ0FyZWE7CgkJfQoJCQoJCS8qIChub24tSmF2YWRvYykKCQkgKiBNZXRob2QgZGVjbGFyZWQgb24gRGlhbG9nLgoJCSAqLwoJCXByb3RlY3RlZCB2b2lkIG9rUHJlc3NlZCgpIHsKCQkJSVN0cnVjdHVyZWRTZWxlY3Rpb24gc2VsID0gKElTdHJ1Y3R1cmVkU2VsZWN0aW9uKXdzVHJlZS5nZXRTZWxlY3Rpb24oKTsKCQkJaWYgKHNlbCAhPSBudWxsKQoJCQkJc2V0U2VsZWN0aW9uUmVzdWx0KHNlbC50b0FycmF5KCkpOwoJCQlzdXBlci5va1ByZXNzZWQoKTsKCQl9Cgl9CgoKCS8qKgoJICogSW50ZXJuYWwgZGlhbG9nIHRvIHNob3cgYXZhaWxhYmxlIHZhcmlhYmxlcyBmcm9tIHdoaWNoCgkgKiB0aGUgdXNlciBjYW4gc2VsZWN0IG9uZS4KCSAqLwoJcHJpdmF0ZSBjbGFzcyBWYXJpYWJsZVNlbGVjdGlvbkRpYWxvZyBleHRlbmRzIFNlbGVjdGlvbkRpYWxvZyB7CgkJU3RyaW5nIGxvY2F0aW9uOwoJCUxpc3QgbGlzdDsKCQkKCQlwdWJsaWMgVmFyaWFibGVTZWxlY3Rpb25EaWFsb2coU2hlbGwgcGFyZW50KSB7CgkJCXN1cGVyKHBhcmVudCk7CgkJCXNldFRpdGxlKFRvb2xNZXNzYWdlcy5nZXRTdHJpbmcoIkVkaXREaWFsb2cuYnJvd3NlVmFyVGl0bGUiKSk7IC8vJE5PTi1OTFMtMSQKCQl9CgoJCS8qIChub24tSmF2YWRvYykKCQkgKiBNZXRob2QgZGVjbGFyZWQgb24gRGlhbG9nLgoJCSAqLwoJCXByb3RlY3RlZCBDb250cm9sIGNyZWF0ZURpYWxvZ0FyZWEoQ29tcG9zaXRlIHBhcmVudCkgewoJCQkvLyBjcmVhdGUgY29tcG9zaXRlIAoJCQlDb21wb3NpdGUgZGlhbG9nQXJlYSA9IChDb21wb3NpdGUpc3VwZXIuY3JlYXRlRGlhbG9nQXJlYShwYXJlbnQpOwoJCQkKCQkJTGFiZWwgbGFiZWwgPSBuZXcgTGFiZWwoZGlhbG9nQXJlYSwgU1dULkxFRlQpOwoJCQlsYWJlbC5zZXRUZXh0KFRvb2xNZXNzYWdlcy5nZXRTdHJpbmcoIkVkaXREaWFsb2cuc2VsZWN0VmFyIikpOyAvLyROT04tTkxTLTEkCgkJCQoJCQlsaXN0ID0gbmV3IExpc3QoZGlhbG9nQXJlYSwgU1dULkhfU0NST0xMIHwgU1dULlZfU0NST0xMIHwgU1dULlNJTkdMRSB8IFNXVC5CT1JERVIpOwoJCQlHcmlkRGF0YSBkYXRhID0gbmV3IEdyaWREYXRhKEdyaWREYXRhLkZJTExfQk9USCk7CgkJCWRhdGEuaGVpZ2h0SGludCA9IFNJWklOR19TRUxFQ1RJT05fUEFORV9IRUlHSFQ7CgkJCWRhdGEud2lkdGhIaW50ID0gU0laSU5HX1NFTEVDVElPTl9QQU5FX1dJRFRIOwoJCQlsaXN0LnNldExheW91dERhdGEoZGF0YSk7CgkJCQoJCQlsaXN0LmFkZChUb29sTWVzc2FnZXMuZ2V0U3RyaW5nKCJFZGl0RGlhbG9nLnZhcldvcmtzcGFjZURpckxhYmVsIikpOyAvLyROT04tTkxTLTEkCgkJCWxpc3QuYWRkKFRvb2xNZXNzYWdlcy5nZXRTdHJpbmcoIkVkaXREaWFsb2cudmFyUHJvamVjdERpckxhYmVsIikpOyAvLyROT04tTkxTLTEkCgkJCWxpc3QuYWRkKFRvb2xNZXNzYWdlcy5nZXRTdHJpbmcoIkVkaXREaWFsb2cudmFyUHJvamVjdFhEaXJMYWJlbCIpKTsgLy8kTk9OLU5MUy0xJAoJCQlsaXN0LmFkZChUb29sTWVzc2FnZXMuZ2V0U3RyaW5nKCJFZGl0RGlhbG9nLnZhclJlc291cmNlRGlyTGFiZWwiKSk7IC8vJE5PTi1OTFMtMSQKCQkJbGlzdC5hZGQoVG9vbE1lc3NhZ2VzLmdldFN0cmluZygiRWRpdERpYWxvZy52YXJSZXNvdXJjZVhEaXJMYWJlbCIpKTsgLy8kTk9OLU5MUy0xJAkKCQkJCgkJCWxvY2F0aW9uID0gbG9jYXRpb25GaWVsZC5nZXRUZXh0KCkudHJpbSgpOwoJCQlQYXRoIHBhdGggPSBudWxsOwoJCQlWYXJpYWJsZURlZmluaXRpb24gdmFyRGVmID0gVG9vbFV0aWwuZXh0cmFjdFZhcmlhYmxlVGFnKGxvY2F0aW9uLCAwKTsKCQkJaWYgKHZhckRlZi5zdGFydCA+PSAwICYmIEV4dGVybmFsVG9vbC5WQVJfV09SS1NQQUNFX0xPQy5lcXVhbHModmFyRGVmLm5hbWUpKQoJCQkJbG9jYXRpb24gPSBQbGF0Zm9ybS5nZXRMb2NhdGlvbigpLnRvU3RyaW5nKCkgKyBsb2NhdGlvbi5zdWJzdHJpbmcodmFyRGVmLmVuZCk7CgkJCXBhdGggPSBuZXcgUGF0aChsb2NhdGlvbik7CgkJCUFudFRhcmdldExpc3QgdGFyZ2V0TGlzdCA9IEFudFV0aWwuZ2V0VGFyZ2V0TGlzdChwYXRoKTsKCQkJaWYgKHRhcmdldExpc3QgIT0gbnVsbCkKCQkJCWxpc3QuYWRkKFRvb2xNZXNzYWdlcy5nZXRTdHJpbmcoIkVkaXREaWFsb2cudmFyQW50VGFyZ2V0TGFiZWwiKSk7IC8vJE5PTi1OTFMtMSQKCQkJCgkJCXJldHVybiBkaWFsb2dBcmVhOwoJCX0KCQkKCQkvKiAobm9uLUphdmFkb2MpCgkJICogTWV0aG9kIGRlY2xhcmVkIG9uIERpYWxvZy4KCQkgKi8KCQlwcm90ZWN0ZWQgdm9pZCBva1ByZXNzZWQoKSB7CgkJCWludCBzZWwgPSBsaXN0LmdldFNlbGVjdGlvbkluZGV4KCk7CgkJCVN0cmluZyByZXN1bHQgPSBudWxsOwoJCQkKCQkJc3dpdGNoIChzZWwpIHsKCQkJCWNhc2UgMCA6CgkJCQkJcmVzdWx0ID0gVG9vbFV0aWwuYnVpbGRWYXJpYWJsZVRhZyhFeHRlcm5hbFRvb2wuVkFSX1dPUktTUEFDRV9MT0MsIG51bGwpOwoJCQkJCWJyZWFrOwoKCQkJCWNhc2UgMSA6CgkJCQkJcmVzdWx0ID0gVG9vbFV0aWwuYnVpbGRWYXJpYWJsZVRhZyhFeHRlcm5hbFRvb2wuVkFSX1BST0pFQ1RfTE9DLCBudWxsKTsKCQkJCQlicmVhazsKCgkJCQljYXNlIDIgOgoJCQkJCVByb2plY3RTZWxlY3Rpb25EaWFsb2cgZGlhbG9nOwoJCQkJCWRpYWxvZyA9IG5ldyBQcm9qZWN0U2VsZWN0aW9uRGlhbG9nKGdldFNoZWxsKCkpOwoJCQkJCWRpYWxvZy5vcGVuKCk7CgkJCQkJT2JqZWN0W10gbmFtZSA9IGRpYWxvZy5nZXRSZXN1bHQoKTsKCQkJCQlpZiAobmFtZSAhPSBudWxsICYmIG5hbWUubGVuZ3RoID4gMCkKCQkJCQkJcmVzdWx0ID0gVG9vbFV0aWwuYnVpbGRWYXJpYWJsZVRhZyhFeHRlcm5hbFRvb2wuVkFSX1BST0pFQ1RfTE9DLCAoU3RyaW5nKW5hbWVbMF0pOwoJCQkJCWJyZWFrOwoJCQkJCQoJCQkJY2FzZSAzIDoKCQkJCQlyZXN1bHQgPSBUb29sVXRpbC5idWlsZFZhcmlhYmxlVGFnKEV4dGVybmFsVG9vbC5WQVJfUkVTT1VSQ0VfTE9DLCBudWxsKTsKCQkJCQlicmVhazsKCgkJCQljYXNlIDQgOgoJCQkJCVJlc291cmNlU2VsZWN0aW9uRGlhbG9nIHJlc0RpYWxvZzsKCQkJCQlyZXNEaWFsb2cgPSBuZXcgUmVzb3VyY2VTZWxlY3Rpb25EaWFsb2coZ2V0U2hlbGwoKSwgUmVzb3VyY2VzUGx1Z2luLmdldFdvcmtzcGFjZSgpLmdldFJvb3QoKSk7CgkJCQkJcmVzRGlhbG9nLm9wZW4oKTsKCQkJCQlPYmplY3RbXSByZXNvdXJjZSA9IHJlc0RpYWxvZy5nZXRSZXN1bHQoKTsKCQkJCQlpZiAocmVzb3VyY2UgIT0gbnVsbCAmJiByZXNvdXJjZS5sZW5ndGggPiAwKQoJCQkJCQlyZXN1bHQgPSBUb29sVXRpbC5idWlsZFZhcmlhYmxlVGFnKEV4dGVybmFsVG9vbC5WQVJfUkVTT1VSQ0VfTE9DLCAoKElSZXNvdXJjZSlyZXNvdXJjZVswXSkuZ2V0RnVsbFBhdGgoKS50b1N0cmluZygpKTsKCQkJCQlicmVhazsKCgkJCQljYXNlIDUgOgoJCQkJCVRhcmdldFNlbGVjdGlvbkRpYWxvZyB0YXJnZXREaWFsb2c7CgkJCQkJdGFyZ2V0RGlhbG9nID0gbmV3IFRhcmdldFNlbGVjdGlvbkRpYWxvZyhnZXRTaGVsbCgpLCBsb2NhdGlvbik7CgkJCQkJdGFyZ2V0RGlhbG9nLm9wZW4oKTsKCQkJCQlPYmplY3RbXSB0YXJnZXRzID0gdGFyZ2V0RGlhbG9nLmdldFJlc3VsdCgpOwoJCQkJCWlmICh0YXJnZXRzICE9IG51bGwgJiYgdGFyZ2V0cy5sZW5ndGggPiAwKSB7CgkJCQkJCVN0cmluZ0J1ZmZlciBidWYgPSBuZXcgU3RyaW5nQnVmZmVyKCk7CgkJCQkJCVRvb2xVdGlsLmJ1aWxkVmFyaWFibGVUYWdzKEV4dGVybmFsVG9vbC5WQVJfQU5UX1RBUkdFVCwgKFN0cmluZ1tdKXRhcmdldHMsIGJ1Zik7CgkJCQkJCXJlc3VsdCA9IGJ1Zi50b1N0cmluZygpLnRyaW0oKTsKCQkJCQl9CgkJCQkJYnJlYWs7CgkJCX0KCQkJCgkJCWlmIChyZXN1bHQgIT0gbnVsbCkKCQkJCXNldFNlbGVjdGlvblJlc3VsdChuZXcgT2JqZWN0W10ge3Jlc3VsdH0pOwoJCQlzdXBlci5va1ByZXNzZWQoKTsKCQl9Cgl9CgkKCS8qKgoJICogSW50ZXJuYWwgZGlhbG9nIHRvIHNob3cgYXZhaWxhYmxlIHJlZnJlc2ggc2NvcGUgZnJvbSB3aGljaAoJICogdGhlIHVzZXIgY2FuIHNlbGVjdCBvbmUuCgkgKi8KCXByaXZhdGUgY2xhc3MgUmVmcmVzaFNlbGVjdGlvbkRpYWxvZyBleHRlbmRzIFNlbGVjdGlvbkRpYWxvZyB7CgkJTGlzdCBsaXN0OwoJCQoJCXB1YmxpYyBSZWZyZXNoU2VsZWN0aW9uRGlhbG9nKFNoZWxsIHBhcmVudCkgewoJCQlzdXBlcihwYXJlbnQpOwoJCQlzZXRUaXRsZShUb29sTWVzc2FnZXMuZ2V0U3RyaW5nKCJFZGl0RGlhbG9nLmJyb3dzZVJlZnJlc2hUaXRsZSIpKTsgLy8kTk9OLU5MUy0xJAoJCX0KCgkJLyogKG5vbi1KYXZhZG9jKQoJCSAqIE1ldGhvZCBkZWNsYXJlZCBvbiBEaWFsb2cuCgkJICovCgkJcHJvdGVjdGVkIENvbnRyb2wgY3JlYXRlRGlhbG9nQXJlYShDb21wb3NpdGUgcGFyZW50KSB7CgkJCS8vIGNyZWF0ZSBjb21wb3NpdGUgCgkJCUNvbXBvc2l0ZSBkaWFsb2dBcmVhID0gKENvbXBvc2l0ZSlzdXBlci5jcmVhdGVEaWFsb2dBcmVhKHBhcmVudCk7CgkJCQoJCQlMYWJlbCBsYWJlbCA9IG5ldyBMYWJlbChkaWFsb2dBcmVhLCBTV1QuTEVGVCk7CgkJCWxhYmVsLnNldFRleHQoVG9vbE1lc3NhZ2VzLmdldFN0cmluZygiRWRpdERpYWxvZy5zZWxlY3RSZWZyZXNoIikpOyAvLyROT04tTkxTLTEkCgkJCQoJCQlsaXN0ID0gbmV3IExpc3QoZGlhbG9nQXJlYSwgU1dULkhfU0NST0xMIHwgU1dULlZfU0NST0xMIHwgU1dULlNJTkdMRSB8IFNXVC5CT1JERVIpOwoJCQlHcmlkRGF0YSBkYXRhID0gbmV3IEdyaWREYXRhKEdyaWREYXRhLkZJTExfQk9USCk7CgkJCWRhdGEuaGVpZ2h0SGludCA9IFNJWklOR19TRUxFQ1RJT05fUEFORV9IRUlHSFQ7CgkJCWRhdGEud2lkdGhIaW50ID0gU0laSU5HX1NFTEVDVElPTl9QQU5FX1dJRFRIOwoJCQlsaXN0LnNldExheW91dERhdGEoZGF0YSk7CgkJCQoJCQlsaXN0LmFkZChUb29sTWVzc2FnZXMuZ2V0U3RyaW5nKCJFZGl0RGlhbG9nLnJlZnJlc2hOb3RoaW5nTGFiZWwiKSk7IC8vJE5PTi1OTFMtMSQKCQkJbGlzdC5hZGQoVG9vbE1lc3NhZ2VzLmdldFN0cmluZygiRWRpdERpYWxvZy5yZWZyZXNoV29ya3NwYWNlTGFiZWwiKSk7IC8vJE5PTi1OTFMtMSQKCQkJbGlzdC5hZGQoVG9vbE1lc3NhZ2VzLmdldFN0cmluZygiRWRpdERpYWxvZy5yZWZyZXNoUHJvamVjdExhYmVsIikpOyAvLyROT04tTkxTLTEkCgkJCWxpc3QuYWRkKFRvb2xNZXNzYWdlcy5nZXRTdHJpbmcoIkVkaXREaWFsb2cucmVmcmVzaFByb2plY3RYTGFiZWwiKSk7IC8vJE5PTi1OTFMtMSQKCQkJbGlzdC5hZGQoVG9vbE1lc3NhZ2VzLmdldFN0cmluZygiRWRpdERpYWxvZy5yZWZyZXNoV29ya2luZ1NldExhYmVsIikpOyAvLyROT04tTkxTLTEkCgoJCQlyZXR1cm4gZGlhbG9nQXJlYTsKCQl9CgkJCgkJLyogKG5vbi1KYXZhZG9jKQoJCSAqIE1ldGhvZCBkZWNsYXJlZCBvbiBEaWFsb2cuCgkJICovCgkJcHJvdGVjdGVkIHZvaWQgb2tQcmVzc2VkKCkgewoJCQlpbnQgc2VsID0gbGlzdC5nZXRTZWxlY3Rpb25JbmRleCgpOwoJCQlTdHJpbmcgcmVzdWx0ID0gbnVsbDsKCQkJCgkJCXN3aXRjaCAoc2VsKSB7CgkJCQljYXNlIDAgOgoJCQkJCXJlc3VsdCA9IFRvb2xVdGlsLmJ1aWxkVmFyaWFibGVUYWcoRXh0ZXJuYWxUb29sLlJFRlJFU0hfU0NPUEVfTk9ORSwgbnVsbCk7CgkJCQkJYnJlYWs7CgkJCQkJCgkJCQljYXNlIDEgOgoJCQkJCXJlc3VsdCA9IFRvb2xVdGlsLmJ1aWxkVmFyaWFibGVUYWcoRXh0ZXJuYWxUb29sLlJFRlJFU0hfU0NPUEVfV09SS1NQQUNFLCBudWxsKTsKCQkJCQlicmVhazsKCgkJCQljYXNlIDIgOgoJCQkJCXJlc3VsdCA9IFRvb2xVdGlsLmJ1aWxkVmFyaWFibGVUYWcoRXh0ZXJuYWxUb29sLlJFRlJFU0hfU0NPUEVfUFJPSkVDVCwgbnVsbCk7CgkJCQkJYnJlYWs7CgoJCQkJY2FzZSAzIDoKCQkJCQlQcm9qZWN0U2VsZWN0aW9uRGlhbG9nIHByakRpYWxvZzsKCQkJCQlwcmpEaWFsb2cgPSBuZXcgUHJvamVjdFNlbGVjdGlvbkRpYWxvZyhnZXRTaGVsbCgpKTsKCQkJCQlwcmpEaWFsb2cub3BlbigpOwoJCQkJCU9iamVjdFtdIG5hbWUgPSBwcmpEaWFsb2cuZ2V0UmVzdWx0KCk7CgkJCQkJaWYgKG5hbWUgIT0gbnVsbCAmJiBuYW1lLmxlbmd0aCA+IDApCgkJCQkJCXJlc3VsdCA9IFRvb2xVdGlsLmJ1aWxkVmFyaWFibGVUYWcoRXh0ZXJuYWxUb29sLlJFRlJFU0hfU0NPUEVfUFJPSkVDVCwgKFN0cmluZyluYW1lWzBdKTsKCQkJCQlicmVhazsKCgkJCQljYXNlIDQgOgoJCQkJCUlXb3JraW5nU2V0U2VsZWN0aW9uRGlhbG9nIHNldERpYWxvZzsKCQkJCQlzZXREaWFsb2cgPSBQbGF0Zm9ybVVJLmdldFdvcmtiZW5jaCgpLmdldFdvcmtpbmdTZXRNYW5hZ2VyKCkuY3JlYXRlV29ya2luZ1NldFNlbGVjdGlvbkRpYWxvZyhnZXRTaGVsbCgpLCBmYWxzZSk7CgkJCQkJc2V0RGlhbG9nLm9wZW4oKTsKCQkJCQlJV29ya2luZ1NldFtdIHNldHMgPSBzZXREaWFsb2cuZ2V0U2VsZWN0aW9uKCk7CgkJCQkJaWYgKHNldHMgIT0gbnVsbCAmJiBzZXRzLmxlbmd0aCA+IDApCgkJCQkJCXJlc3VsdCA9IFRvb2xVdGlsLmJ1aWxkVmFyaWFibGVUYWcoRXh0ZXJuYWxUb29sLlJFRlJFU0hfU0NPUEVfV09SS0lOR19TRVQsIHNldHNbMF0uZ2V0TmFtZSgpKTsKCQkJCQlicmVhazsKCQkJfQoJCQkKCQkJaWYgKHJlc3VsdCAhPSBudWxsKQoJCQkJc2V0U2VsZWN0aW9uUmVzdWx0KG5ldyBPYmplY3RbXSB7cmVzdWx0fSk7CgkJCXN1cGVyLm9rUHJlc3NlZCgpOwoJCX0KCX0KCQoJLyoqCgkgKiBJbnRlcm5hbCBkaWFsb2cgdG8gc2hvdyBhdmFpbGFibGUgcHJvamVjdHMgZnJvbSB3aGljaAoJICogdGhlIHVzZXIgY2FuIHNlbGVjdCBvbmUuCgkgKi8KCXByaXZhdGUgY2xhc3MgUHJvamVjdFNlbGVjdGlvbkRpYWxvZyBleHRlbmRzIFNlbGVjdGlvbkRpYWxvZyB7CgkJTGlzdCBsaXN0OwoJCQoJCXB1YmxpYyBQcm9qZWN0U2VsZWN0aW9uRGlhbG9nKFNoZWxsIHBhcmVudCkgewoJCQlzdXBlcihwYXJlbnQpOwoJCQlzZXRUaXRsZShUb29sTWVzc2FnZXMuZ2V0U3RyaW5nKCJFZGl0RGlhbG9nLmJyb3dzZVByb2plY3RUaXRsZSIpKTsgLy8kTk9OLU5MUy0xJAoJCX0KCgkJLyogKG5vbi1KYXZhZG9jKQoJCSAqIE1ldGhvZCBkZWNsYXJlZCBvbiBEaWFsb2cuCgkJICovCgkJcHJvdGVjdGVkIENvbnRyb2wgY3JlYXRlRGlhbG9nQXJlYShDb21wb3NpdGUgcGFyZW50KSB7CgkJCS8vIGNyZWF0ZSBjb21wb3NpdGUgCgkJCUNvbXBvc2l0ZSBkaWFsb2dBcmVhID0gKENvbXBvc2l0ZSlzdXBlci5jcmVhdGVEaWFsb2dBcmVhKHBhcmVudCk7CgkJCQoJCQlMYWJlbCBsYWJlbCA9IG5ldyBMYWJlbChkaWFsb2dBcmVhLCBTV1QuTEVGVCk7CgkJCWxhYmVsLnNldFRleHQoVG9vbE1lc3NhZ2VzLmdldFN0cmluZygiRWRpdERpYWxvZy5zZWxlY3RQcm9qZWN0IikpOyAvLyROT04tTkxTLTEkCgkJCQoJCQlsaXN0ID0gbmV3IExpc3QoZGlhbG9nQXJlYSwgU1dULkhfU0NST0xMIHwgU1dULlZfU0NST0xMIHwgU1dULlNJTkdMRSB8IFNXVC5CT1JERVIpOwoJCQlHcmlkRGF0YSBkYXRhID0gbmV3IEdyaWREYXRhKEdyaWREYXRhLkZJTExfQk9USCk7CgkJCWRhdGEuaGVpZ2h0SGludCA9IFNJWklOR19TRUxFQ1RJT05fUEFORV9IRUlHSFQ7CgkJCWRhdGEud2lkdGhIaW50ID0gU0laSU5HX1NFTEVDVElPTl9QQU5FX1dJRFRIOwoJCQlsaXN0LnNldExheW91dERhdGEoZGF0YSk7CgkJCQoJCQlJV29ya3NwYWNlUm9vdCByb290ID0gUmVzb3VyY2VzUGx1Z2luLmdldFdvcmtzcGFjZSgpLmdldFJvb3QoKTsKCQkJSVByb2plY3RbXSBwcm9qZWN0cyA9IHJvb3QuZ2V0UHJvamVjdHMoKTsKCQkJZm9yIChpbnQgaSA9IDA7IGkgPCBwcm9qZWN0cy5sZW5ndGg7IGkrKykgewoJCQkJbGlzdC5hZGQocHJvamVjdHNbaV0uZ2V0TmFtZSgpKTsKCQkJfQoJCQkKCQkJcmV0dXJuIGRpYWxvZ0FyZWE7CgkJfQoJCQoJCS8qIChub24tSmF2YWRvYykKCQkgKiBNZXRob2QgZGVjbGFyZWQgb24gRGlhbG9nLgoJCSAqLwoJCXByb3RlY3RlZCB2b2lkIG9rUHJlc3NlZCgpIHsKCQkJc2V0U2VsZWN0aW9uUmVzdWx0KGxpc3QuZ2V0U2VsZWN0aW9uKCkpOwoJCQlzdXBlci5va1ByZXNzZWQoKTsKCQl9Cgl9CgkKCXByaXZhdGUgY2xhc3MgVGFyZ2V0U2VsZWN0aW9uRGlhbG9nIGV4dGVuZHMgU2VsZWN0aW9uRGlhbG9nIGltcGxlbWVudHMgSUNoZWNrU3RhdGVMaXN0ZW5lciB7CgkJcHJpdmF0ZSBBcnJheUxpc3Qgc2VsZWN0ZWRUYXJnZXRzID0gbmV3IEFycmF5TGlzdCgpOwoJCXByaXZhdGUgQ2hlY2tib3hUYWJsZVZpZXdlciBsaXN0Vmlld2VyOwoJCXByaXZhdGUgQW50VGFyZ2V0TGlzdCB0YXJnZXRMaXN0OwoJCXByaXZhdGUgQW50VGFyZ2V0TGFiZWxQcm92aWRlciBsYWJlbFByb3ZpZGVyID0gbmV3IEFudFRhcmdldExhYmVsUHJvdmlkZXIoKTsJCgkJCgkJcHVibGljIFRhcmdldFNlbGVjdGlvbkRpYWxvZyhTaGVsbCBwYXJlbnQsIFN0cmluZyBsb2NhdGlvbikgewoJCQlzdXBlcihwYXJlbnQpOwoJCQlJUGF0aCBwYXRoID0gbmV3IFBhdGgobG9jYXRpb24pOwoJCQl0YXJnZXRMaXN0ID0gQW50VXRpbC5nZXRUYXJnZXRMaXN0KHBhdGgpOwoJCQlzZXRUaXRsZShUb29sTWVzc2FnZXMuZ2V0U3RyaW5nKCJFZGl0RGlhbG9nLnZhckFudFRhcmdldExhYmVsIikpOyAvLyROT04tTkxTLTEkCgkJfQoJCQoJCXB1YmxpYyB2b2lkIGNoZWNrU3RhdGVDaGFuZ2VkKENoZWNrU3RhdGVDaGFuZ2VkRXZlbnQgZSkgewoJCQlTdHJpbmcgY2hlY2tlZFRhcmdldCA9IChTdHJpbmcpZS5nZXRFbGVtZW50KCk7CgkJCWlmIChlLmdldENoZWNrZWQoKSkKCQkJCXNlbGVjdGVkVGFyZ2V0cy5hZGQoY2hlY2tlZFRhcmdldCk7CgkJCWVsc2UKCQkJCXNlbGVjdGVkVGFyZ2V0cy5yZW1vdmUoY2hlY2tlZFRhcmdldCk7CgkJCQkKCQkJbGFiZWxQcm92aWRlci5zZXRTZWxlY3RlZFRhcmdldHMoc2VsZWN0ZWRUYXJnZXRzKTsKCQkJbGlzdFZpZXdlci5yZWZyZXNoKCk7CgkJfQoJCQoJCXByb3RlY3RlZCBDb250cm9sIGNyZWF0ZURpYWxvZ0FyZWEoQ29tcG9zaXRlIHBhcmVudCkgewoJCQlDb21wb3NpdGUgZGlhbG9nQXJlYSA9IChDb21wb3NpdGUpc3VwZXIuY3JlYXRlRGlhbG9nQXJlYShwYXJlbnQpOwoJCQkKCQkJTGFiZWwgbGFiZWwgPSBuZXcgTGFiZWwoZGlhbG9nQXJlYSwgU1dULkxFRlQpOwoJCQlsYWJlbC5zZXRUZXh0KFRvb2xNZXNzYWdlcy5nZXRTdHJpbmcoIkVkaXREaWFsb2cuc2VsZWN0VGFyZ2V0cyIpKTsgLy8kTk9OLU5MUy0xJAoJCQkKCQkJbGlzdFZpZXdlciA9IENoZWNrYm94VGFibGVWaWV3ZXIubmV3Q2hlY2tMaXN0KGRpYWxvZ0FyZWEsIFNXVC5CT1JERVIpOwoJCQlHcmlkRGF0YSBkYXRhID0gbmV3IEdyaWREYXRhKEdyaWREYXRhLkZJTExfQk9USCk7CgkJCWRhdGEuaGVpZ2h0SGludCA9IFNJWklOR19TRUxFQ1RJT05fUEFORV9IRUlHSFQ7CgkJCWRhdGEud2lkdGhIaW50ID0gU0laSU5HX1NFTEVDVElPTl9QQU5FX1dJRFRIOwoJCQlsaXN0Vmlld2VyLmdldFRhYmxlKCkuc2V0TGF5b3V0RGF0YShkYXRhKTsKCQkJbGlzdFZpZXdlci5zZXRTb3J0ZXIobmV3IFZpZXdlclNvcnRlcigpIHsKCQkJCXB1YmxpYyBpbnQgY29tcGFyZShWaWV3ZXIgdmlld2VyLE9iamVjdCBvMSxPYmplY3QgbzIpIHsKCQkJCQlyZXR1cm4gKChTdHJpbmcpbzEpLmNvbXBhcmVUbygoU3RyaW5nKW8yKTsKCQkJCX0KCQkJfSk7CgkJCQoJCQlpZiAodGFyZ2V0TGlzdCAhPSBudWxsICYmIHRhcmdldExpc3QuZ2V0RGVmYXVsdFRhcmdldCgpICE9IG51bGwpCgkJCQlsYWJlbFByb3ZpZGVyLnNldERlZmF1bHRUYXJnZXROYW1lKHRhcmdldExpc3QuZ2V0RGVmYXVsdFRhcmdldCgpKTsKCQkJbGlzdFZpZXdlci5zZXRMYWJlbFByb3ZpZGVyKGxhYmVsUHJvdmlkZXIpOwoJCQlsaXN0Vmlld2VyLnNldENvbnRlbnRQcm92aWRlcihuZXcgQW50VGFyZ2V0Q29udGVudFByb3ZpZGVyKCkpOwoJCQlsaXN0Vmlld2VyLnNldElucHV0KHRhcmdldExpc3QpOwoJCQkKCQkJbGlzdFZpZXdlci5hZGRDaGVja1N0YXRlTGlzdGVuZXIodGhpcyk7CgkJCWxpc3RWaWV3ZXIucmVmcmVzaCgpOwoJCQkKCQkJcmV0dXJuIGRpYWxvZ0FyZWE7CgkJfQoJCQoJCS8qIChub24tSmF2YWRvYykKCQkgKiBNZXRob2QgZGVjbGFyZWQgb24gRGlhbG9nLgoJCSAqLwoJCXByb3RlY3RlZCB2b2lkIG9rUHJlc3NlZCgpIHsKCQkJc2V0U2VsZWN0aW9uUmVzdWx0KGdldFRhcmdldE5hbWVzKCkpOwoJCQlzdXBlci5va1ByZXNzZWQoKTsKCQl9CgkJCgkJcHJvdGVjdGVkIFN0cmluZ1tdIGdldFRhcmdldE5hbWVzKCkgewoJCQlTdHJpbmdbXSByZXN1bHQgPSBuZXcgU3RyaW5nW3NlbGVjdGVkVGFyZ2V0cy5zaXplKCldOwoJCQlzZWxlY3RlZFRhcmdldHMudG9BcnJheShyZXN1bHQpOwoJCQlyZXR1cm4gcmVzdWx0OwoJCX0KCX0KCQp9Cg==