LyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogQ29weXJpZ2h0IChjKSAyMDAwLCAyMDExIElCTSBDb3Jwb3JhdGlvbiBhbmQgb3RoZXJzLgogKiBBbGwgcmlnaHRzIHJlc2VydmVkLiBUaGlzIHByb2dyYW0gYW5kIHRoZSBhY2NvbXBhbnlpbmcgbWF0ZXJpYWxzCiAqIGFyZSBtYWRlIGF2YWlsYWJsZSB1bmRlciB0aGUgdGVybXMgb2YgdGhlIEVjbGlwc2UgUHVibGljIExpY2Vuc2UgdjEuMAogKiB3aGljaCBhY2NvbXBhbmllcyB0aGlzIGRpc3RyaWJ1dGlvbiwgYW5kIGlzIGF2YWlsYWJsZSBhdAogKiBodHRwOi8vd3d3LmVjbGlwc2Uub3JnL2xlZ2FsL2VwbC12MTAuaHRtbAogKgogKiBDb250cmlidXRvcnM6CiAqICAgICBJQk0gQ29ycG9yYXRpb24gLSBpbml0aWFsIEFQSSBhbmQgaW1wbGVtZW50YXRpb24KICogICAgIEFuZHJlIFNvZXJlbmcgPGFuZHJlaXNAZmFzdC5ubz4gLSBbc3ludGF4IGhpZ2hsaWdodGluZ10gaGlnaGxpZ2h0IG51bWJlcnMgLSBodHRwczovL2J1Z3MuZWNsaXBzZS5vcmcvYnVncy9zaG93X2J1Zy5jZ2k/aWQ9NjM1NzMKICogICAgIEJq9nJuIE1pY2hhZWwgPGIubWljaGFlbEBnbXguZGU+IC0gW3N5bnRheCBoaWdobGlnaHRpbmddIFN5bnRheCBjb2xvcmluZyBmb3IgYWJzdHJhY3QgY2xhc3NlcyAtIGh0dHBzOi8vYnVncy5lY2xpcHNlLm9yZy8zMzEzMTEKICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCnBhY2thZ2Ugb3JnLmVjbGlwc2UuamR0LmludGVybmFsLnVpLmphdmFlZGl0b3I7CgppbXBvcnQgb3JnLmVjbGlwc2Uuc3d0LmdyYXBoaWNzLlJHQjsKCmltcG9ydCBvcmcuZWNsaXBzZS5qZmFjZS5wcmVmZXJlbmNlLklQcmVmZXJlbmNlU3RvcmU7CmltcG9ydCBvcmcuZWNsaXBzZS5qZmFjZS5wcmVmZXJlbmNlLlByZWZlcmVuY2VDb252ZXJ0ZXI7CmltcG9ydCBvcmcuZWNsaXBzZS5qZmFjZS51dGlsLlByb3BlcnR5Q2hhbmdlRXZlbnQ7CgppbXBvcnQgb3JnLmVjbGlwc2UuamR0LmNvcmUuZG9tLkFTVE5vZGU7CmltcG9ydCBvcmcuZWNsaXBzZS5qZHQuY29yZS5kb20uQW5ub3RhdGlvblR5cGVNZW1iZXJEZWNsYXJhdGlvbjsKaW1wb3J0IG9yZy5lY2xpcHNlLmpkdC5jb3JlLmRvbS5BcnJheUFjY2VzczsKaW1wb3J0IG9yZy5lY2xpcHNlLmpkdC5jb3JlLmRvbS5DYXN0RXhwcmVzc2lvbjsKaW1wb3J0IG9yZy5lY2xpcHNlLmpkdC5jb3JlLmRvbS5DbGFzc0luc3RhbmNlQ3JlYXRpb247CmltcG9ydCBvcmcuZWNsaXBzZS5qZHQuY29yZS5kb20uQ29uZGl0aW9uYWxFeHByZXNzaW9uOwppbXBvcnQgb3JnLmVjbGlwc2UuamR0LmNvcmUuZG9tLkV4cHJlc3Npb247CmltcG9ydCBvcmcuZWNsaXBzZS5qZHQuY29yZS5kb20uRmllbGREZWNsYXJhdGlvbjsKaW1wb3J0IG9yZy5lY2xpcHNlLmpkdC5jb3JlLmRvbS5JQmluZGluZzsKaW1wb3J0IG9yZy5lY2xpcHNlLmpkdC5jb3JlLmRvbS5JTWV0aG9kQmluZGluZzsKaW1wb3J0IG9yZy5lY2xpcHNlLmpkdC5jb3JlLmRvbS5JVHlwZUJpbmRpbmc7CmltcG9ydCBvcmcuZWNsaXBzZS5qZHQuY29yZS5kb20uSVZhcmlhYmxlQmluZGluZzsKaW1wb3J0IG9yZy5lY2xpcHNlLmpkdC5jb3JlLmRvbS5JbmZpeEV4cHJlc3Npb247CmltcG9ydCBvcmcuZWNsaXBzZS5qZHQuY29yZS5kb20uTWVtYmVyVmFsdWVQYWlyOwppbXBvcnQgb3JnLmVjbGlwc2UuamR0LmNvcmUuZG9tLk1ldGhvZERlY2xhcmF0aW9uOwppbXBvcnQgb3JnLmVjbGlwc2UuamR0LmNvcmUuZG9tLk1vZGlmaWVyOwppbXBvcnQgb3JnLmVjbGlwc2UuamR0LmNvcmUuZG9tLlBhcmFtZXRlcml6ZWRUeXBlOwppbXBvcnQgb3JnLmVjbGlwc2UuamR0LmNvcmUuZG9tLlByZWZpeEV4cHJlc3Npb247CmltcG9ydCBvcmcuZWNsaXBzZS5qZHQuY29yZS5kb20uUXVhbGlmaWVkTmFtZTsKaW1wb3J0IG9yZy5lY2xpcHNlLmpkdC5jb3JlLmRvbS5RdWFsaWZpZWRUeXBlOwppbXBvcnQgb3JnLmVjbGlwc2UuamR0LmNvcmUuZG9tLlNpbXBsZU5hbWU7CmltcG9ydCBvcmcuZWNsaXBzZS5qZHQuY29yZS5kb20uU2ltcGxlVHlwZTsKaW1wb3J0IG9yZy5lY2xpcHNlLmpkdC5jb3JlLmRvbS5TaW5nbGVWYXJpYWJsZURlY2xhcmF0aW9uOwppbXBvcnQgb3JnLmVjbGlwc2UuamR0LmNvcmUuZG9tLlN0cnVjdHVyYWxQcm9wZXJ0eURlc2NyaXB0b3I7CmltcG9ydCBvcmcuZWNsaXBzZS5qZHQuY29yZS5kb20uVHlwZTsKaW1wb3J0IG9yZy5lY2xpcHNlLmpkdC5jb3JlLmRvbS5WYXJpYWJsZURlY2xhcmF0aW9uOwppbXBvcnQgb3JnLmVjbGlwc2UuamR0LmNvcmUuZG9tLlZhcmlhYmxlRGVjbGFyYXRpb25GcmFnbWVudDsKCmltcG9ydCBvcmcuZWNsaXBzZS5qZHQuaW50ZXJuYWwuY29yZXh0LmRvbS5CaW5kaW5nczsKCmltcG9ydCBvcmcuZWNsaXBzZS5qZHQudWkuUHJlZmVyZW5jZUNvbnN0YW50czsKCgovKioKICogU2VtYW50aWMgaGlnaGxpZ2h0aW5ncwogKgogKiBAc2luY2UgMy4wCiAqLwpwdWJsaWMgY2xhc3MgU2VtYW50aWNIaWdobGlnaHRpbmdzIHsKCgkvKioKCSAqIEEgbmFtZWQgcHJlZmVyZW5jZSBwYXJ0IHRoYXQgY29udHJvbHMgdGhlIGhpZ2hsaWdodGluZyBvZiBzdGF0aWMgZmluYWwgZmllbGRzLgoJICovCglwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBTVEFUSUNfRklOQUxfRklFTEQ9InN0YXRpY0ZpbmFsRmllbGQiOyAvLyROT04tTkxTLTEkCgoJLyoqCgkgKiBBIG5hbWVkIHByZWZlcmVuY2UgcGFydCB0aGF0IGNvbnRyb2xzIHRoZSBoaWdobGlnaHRpbmcgb2Ygc3RhdGljIGZpZWxkcy4KCSAqLwoJcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgU1RBVElDX0ZJRUxEPSJzdGF0aWNGaWVsZCI7IC8vJE5PTi1OTFMtMSQKCgkvKioKCSAqIEEgbmFtZWQgcHJlZmVyZW5jZSBwYXJ0IHRoYXQgY29udHJvbHMgdGhlIGhpZ2hsaWdodGluZyBvZiBmaWVsZHMuCgkgKi8KCXB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEZJRUxEPSJmaWVsZCI7IC8vJE5PTi1OTFMtMSQKCgkvKioKCSAqIEEgbmFtZWQgcHJlZmVyZW5jZSBwYXJ0IHRoYXQgY29udHJvbHMgdGhlIGhpZ2hsaWdodGluZyBvZiBtZXRob2QgZGVjbGFyYXRpb25zLgoJICovCglwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBNRVRIT0RfREVDTEFSQVRJT049Im1ldGhvZERlY2xhcmF0aW9uTmFtZSI7IC8vJE5PTi1OTFMtMSQKCgkvKioKCSAqIEEgbmFtZWQgcHJlZmVyZW5jZSBwYXJ0IHRoYXQgY29udHJvbHMgdGhlIGhpZ2hsaWdodGluZyBvZiBzdGF0aWMgbWV0aG9kIGludm9jYXRpb25zLgoJICovCglwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBTVEFUSUNfTUVUSE9EX0lOVk9DQVRJT049InN0YXRpY01ldGhvZEludm9jYXRpb24iOyAvLyROT04tTkxTLTEkCgoJLyoqCgkgKiBBIG5hbWVkIHByZWZlcmVuY2UgcGFydCB0aGF0IGNvbnRyb2xzIHRoZSBoaWdobGlnaHRpbmcgb2YgaW5oZXJpdGVkIG1ldGhvZCBpbnZvY2F0aW9ucy4KCSAqLwoJcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgSU5IRVJJVEVEX01FVEhPRF9JTlZPQ0FUSU9OPSJpbmhlcml0ZWRNZXRob2RJbnZvY2F0aW9uIjsgLy8kTk9OLU5MUy0xJAoKCS8qKgoJICogQSBuYW1lZCBwcmVmZXJlbmNlIHBhcnQgdGhhdCBjb250cm9scyB0aGUgaGlnaGxpZ2h0aW5nIG9mIGFubm90YXRpb24gZWxlbWVudCByZWZlcmVuY2VzLgoJICogQHNpbmNlIDMuMQoJICovCglwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBBTk5PVEFUSU9OX0VMRU1FTlRfUkVGRVJFTkNFPSJhbm5vdGF0aW9uRWxlbWVudFJlZmVyZW5jZSI7IC8vJE5PTi1OTFMtMSQKCgkvKioKCSAqIEEgbmFtZWQgcHJlZmVyZW5jZSBwYXJ0IHRoYXQgY29udHJvbHMgdGhlIGhpZ2hsaWdodGluZyBvZiBhYnN0cmFjdCBtZXRob2QgaW52b2NhdGlvbnMuCgkgKi8KCXB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEFCU1RSQUNUX01FVEhPRF9JTlZPQ0FUSU9OPSJhYnN0cmFjdE1ldGhvZEludm9jYXRpb24iOyAvLyROT04tTkxTLTEkCgoJLyoqCgkgKiBBIG5hbWVkIHByZWZlcmVuY2UgcGFydCB0aGF0IGNvbnRyb2xzIHRoZSBoaWdobGlnaHRpbmcgb2YgbG9jYWwgdmFyaWFibGVzLgoJICovCglwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBMT0NBTF9WQVJJQUJMRV9ERUNMQVJBVElPTj0ibG9jYWxWYXJpYWJsZURlY2xhcmF0aW9uIjsgLy8kTk9OLU5MUy0xJAoKCS8qKgoJICogQSBuYW1lZCBwcmVmZXJlbmNlIHBhcnQgdGhhdCBjb250cm9scyB0aGUgaGlnaGxpZ2h0aW5nIG9mIGxvY2FsIHZhcmlhYmxlcy4KCSAqLwoJcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgTE9DQUxfVkFSSUFCTEU9ImxvY2FsVmFyaWFibGUiOyAvLyROT04tTkxTLTEkCgoJLyoqCgkgKiBBIG5hbWVkIHByZWZlcmVuY2UgcGFydCB0aGF0IGNvbnRyb2xzIHRoZSBoaWdobGlnaHRpbmcgb2YgcGFyYW1ldGVyIHZhcmlhYmxlcy4KCSAqLwoJcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgUEFSQU1FVEVSX1ZBUklBQkxFPSJwYXJhbWV0ZXJWYXJpYWJsZSI7IC8vJE5PTi1OTFMtMSQKCgkvKioKCSAqIEEgbmFtZWQgcHJlZmVyZW5jZSBwYXJ0IHRoYXQgY29udHJvbHMgdGhlIGhpZ2hsaWdodGluZyBvZiBkZXByZWNhdGVkIG1lbWJlcnMuCgkgKi8KCXB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIERFUFJFQ0FURURfTUVNQkVSPSJkZXByZWNhdGVkTWVtYmVyIjsgLy8kTk9OLU5MUy0xJAoKCS8qKgoJICogQSBuYW1lZCBwcmVmZXJlbmNlIHBhcnQgdGhhdCBjb250cm9scyB0aGUgaGlnaGxpZ2h0aW5nIG9mIHR5cGUgcGFyYW1ldGVycy4KCSAqIEBzaW5jZSAzLjEKCSAqLwoJcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgVFlQRV9WQVJJQUJMRT0idHlwZVBhcmFtZXRlciI7IC8vJE5PTi1OTFMtMSQKCgkvKioKCSAqIEEgbmFtZWQgcHJlZmVyZW5jZSBwYXJ0IHRoYXQgY29udHJvbHMgdGhlIGhpZ2hsaWdodGluZyBvZiBtZXRob2RzCgkgKiAoaW52b2NhdGlvbnMgYW5kIGRlY2xhcmF0aW9ucykuCgkgKgoJICogQHNpbmNlIDMuMQoJICovCglwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBNRVRIT0Q9Im1ldGhvZCI7IC8vJE5PTi1OTFMtMSQKCgkvKioKCSAqIEEgbmFtZWQgcHJlZmVyZW5jZSBwYXJ0IHRoYXQgY29udHJvbHMgdGhlIGhpZ2hsaWdodGluZyBvZiBhdXRvKHVuKWJveGVkCgkgKiBleHByZXNzaW9ucy4KCSAqCgkgKiBAc2luY2UgMy4xCgkgKi8KCXB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEFVVE9CT1hJTkc9ImF1dG9ib3hpbmciOyAvLyROT04tTkxTLTEkCgoJLyoqCgkgKiBBIG5hbWVkIHByZWZlcmVuY2UgcGFydCB0aGF0IGNvbnRyb2xzIHRoZSBoaWdobGlnaHRpbmcgb2YgY2xhc3Nlcy4KCSAqCgkgKiBAc2luY2UgMy4yCgkgKi8KCXB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIENMQVNTPSJjbGFzcyI7IC8vJE5PTi1OTFMtMSQKCgkvKioKCSAqIEEgbmFtZWQgcHJlZmVyZW5jZSBwYXJ0IHRoYXQgY29udHJvbHMgdGhlIGhpZ2hsaWdodGluZyBvZiBlbnVtcy4KCSAqCgkgKiBAc2luY2UgMy4yCgkgKi8KCXB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEVOVU09ImVudW0iOyAvLyROT04tTkxTLTEkCgoJLyoqCgkgKiBBIG5hbWVkIHByZWZlcmVuY2UgcGFydCB0aGF0IGNvbnRyb2xzIHRoZSBoaWdobGlnaHRpbmcgb2YgaW50ZXJmYWNlcy4KCSAqCgkgKiBAc2luY2UgMy4yCgkgKi8KCXB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIElOVEVSRkFDRT0iaW50ZXJmYWNlIjsgLy8kTk9OLU5MUy0xJAoKCS8qKgoJICogQSBuYW1lZCBwcmVmZXJlbmNlIHBhcnQgdGhhdCBjb250cm9scyB0aGUgaGlnaGxpZ2h0aW5nIG9mIGFubm90YXRpb25zLgoJICoKCSAqIEBzaW5jZSAzLjIKCSAqLwoJcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgQU5OT1RBVElPTj0iYW5ub3RhdGlvbiI7IC8vJE5PTi1OTFMtMSQKCgkvKioKCSAqIEEgbmFtZWQgcHJlZmVyZW5jZSBwYXJ0IHRoYXQgY29udHJvbHMgdGhlIGhpZ2hsaWdodGluZyBvZiB0eXBlIGFyZ3VtZW50cy4KCSAqCgkgKiBAc2luY2UgMy4yCgkgKi8KCXB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIFRZUEVfQVJHVU1FTlQ9InR5cGVBcmd1bWVudCI7IC8vJE5PTi1OTFMtMSQKCgkvKioKCSAqIEEgbmFtZWQgcHJlZmVyZW5jZSBwYXJ0IHRoYXQgY29udHJvbHMgdGhlIGhpZ2hsaWdodGluZyBvZiBudW1iZXJzLgoJICoKCSAqIEBzaW5jZSAzLjQKCSAqLwoJcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgTlVNQkVSPSJudW1iZXIiOyAvLyROT04tTkxTLTEkCgoJLyoqCgkgKiBBIG5hbWVkIHByZWZlcmVuY2UgcGFydCB0aGF0IGNvbnRyb2xzIHRoZSBoaWdobGlnaHRpbmcgb2YgYWJzdHJhY3QgY2xhc3Nlcy4KCSAqCgkgKiBAc2luY2UgMy43CgkgKi8KCXB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEFCU1RSQUNUX0NMQVNTPSJhYnN0cmFjdENsYXNzIjsgLy8kTk9OLU5MUy0xJAoKCS8qKgoJICogU2VtYW50aWMgaGlnaGxpZ2h0aW5ncwoJICovCglwcml2YXRlIHN0YXRpYyBTZW1hbnRpY0hpZ2hsaWdodGluZ1tdIGZnU2VtYW50aWNIaWdobGlnaHRpbmdzOwoKCS8qKgoJICogU2VtYW50aWMgaGlnaGxpZ2h0aW5nIGZvciBzdGF0aWMgZmluYWwgZmllbGRzLgoJICovCglwcml2YXRlIHN0YXRpYyBmaW5hbCBjbGFzcyBTdGF0aWNGaW5hbEZpZWxkSGlnaGxpZ2h0aW5nIGV4dGVuZHMgU2VtYW50aWNIaWdobGlnaHRpbmcgewoKCQkvKgoJCSAqIEBzZWUgb3JnLmVjbGlwc2UuamR0LmludGVybmFsLnVpLmphdmFlZGl0b3IuU2VtYW50aWNIaWdobGlnaHRpbmcjZ2V0UHJlZmVyZW5jZUtleSgpCgkJICovCgkJQE92ZXJyaWRlCgkJcHVibGljIFN0cmluZyBnZXRQcmVmZXJlbmNlS2V5KCkgewoJCQlyZXR1cm4gU1RBVElDX0ZJTkFMX0ZJRUxEOwoJCX0KCgkJLyoKCQkgKiBAc2VlIG9yZy5lY2xpcHNlLmpkdC5pbnRlcm5hbC51aS5qYXZhZWRpdG9yLklTZW1hbnRpY0hpZ2hsaWdodGluZyNnZXREZWZhdWx0VGV4dENvbG9yKCkKCQkgKi8KCQlAT3ZlcnJpZGUKCQlwdWJsaWMgUkdCIGdldERlZmF1bHREZWZhdWx0VGV4dENvbG9yKCkgewoJCQlyZXR1cm4gbmV3IFJHQigwLCAwLCAwKTsKCQl9CgoJCS8qCgkJICogQHNlZSBvcmcuZWNsaXBzZS5qZHQuaW50ZXJuYWwudWkuamF2YWVkaXRvci5JU2VtYW50aWNIaWdobGlnaHRpbmcjZ2V0RGVmYXVsdFRleHRTdHlsZUJvbGQoKQoJCSAqLwoJCUBPdmVycmlkZQoJCXB1YmxpYyBib29sZWFuIGlzQm9sZEJ5RGVmYXVsdCgpIHsKCQkJcmV0dXJuIGZhbHNlOwoJCX0KCgkJLyoKCQkgKiBAc2VlIG9yZy5lY2xpcHNlLmpkdC5pbnRlcm5hbC51aS5qYXZhZWRpdG9yLlNlbWFudGljSGlnaGxpZ2h0aW5nI2lzSXRhbGljQnlEZWZhdWx0KCkKCQkgKi8KCQlAT3ZlcnJpZGUKCQlwdWJsaWMgYm9vbGVhbiBpc0l0YWxpY0J5RGVmYXVsdCgpIHsKCQkJcmV0dXJuIGZhbHNlOwoJCX0KCgkJLyoKCQkgKiBAc2VlIG9yZy5lY2xpcHNlLmpkdC5pbnRlcm5hbC51aS5qYXZhZWRpdG9yLlNlbWFudGljSGlnaGxpZ2h0aW5nI2lzRW5hYmxlZEJ5RGVmYXVsdCgpCgkJICovCgkJQE92ZXJyaWRlCgkJcHVibGljIGJvb2xlYW4gaXNFbmFibGVkQnlEZWZhdWx0KCkgewoJCQlyZXR1cm4gZmFsc2U7CgkJfQoKCQkvKgoJCSAqIEBzZWUgb3JnLmVjbGlwc2UuamR0LmludGVybmFsLnVpLmphdmFlZGl0b3IuSVNlbWFudGljSGlnaGxpZ2h0aW5nI2dldERpc3BsYXlOYW1lKCkKCQkgKi8KCQlAT3ZlcnJpZGUKCQlwdWJsaWMgU3RyaW5nIGdldERpc3BsYXlOYW1lKCkgewoJCQlyZXR1cm4gSmF2YUVkaXRvck1lc3NhZ2VzLlNlbWFudGljSGlnaGxpZ2h0aW5nX3N0YXRpY0ZpbmFsRmllbGQ7CgkJfQoKCQkvKgoJCSAqIEBzZWUgb3JnLmVjbGlwc2UuamR0LmludGVybmFsLnVpLmphdmFlZGl0b3IuU2VtYW50aWNIaWdobGlnaHRpbmcjY29uc3VtZXMob3JnLmVjbGlwc2UuamR0LmludGVybmFsLnVpLmphdmFlZGl0b3IuU2VtYW50aWNUb2tlbikKCQkgKi8KCQlAT3ZlcnJpZGUKCQlwdWJsaWMgYm9vbGVhbiBjb25zdW1lcyhTZW1hbnRpY1Rva2VuIHRva2VuKSB7CgkJCUlCaW5kaW5nIGJpbmRpbmc9IHRva2VuLmdldEJpbmRpbmcoKTsKCQkJcmV0dXJuIGJpbmRpbmcgIT0gbnVsbCAmJiBiaW5kaW5nLmdldEtpbmQoKSA9PSBJQmluZGluZy5WQVJJQUJMRSAmJiAoKElWYXJpYWJsZUJpbmRpbmcpYmluZGluZykuaXNGaWVsZCgpICYmIChiaW5kaW5nLmdldE1vZGlmaWVycygpICYgKE1vZGlmaWVyLkZJTkFMIHwgTW9kaWZpZXIuU1RBVElDKSkgPT0gKE1vZGlmaWVyLkZJTkFMIHwgTW9kaWZpZXIuU1RBVElDKTsKCQl9Cgl9CgoJLyoqCgkgKiBTZW1hbnRpYyBoaWdobGlnaHRpbmcgZm9yIHN0YXRpYyBmaWVsZHMuCgkgKi8KCXByaXZhdGUgc3RhdGljIGZpbmFsIGNsYXNzIFN0YXRpY0ZpZWxkSGlnaGxpZ2h0aW5nIGV4dGVuZHMgU2VtYW50aWNIaWdobGlnaHRpbmcgewoKCQkvKgoJCSAqIEBzZWUgb3JnLmVjbGlwc2UuamR0LmludGVybmFsLnVpLmphdmFlZGl0b3IuU2VtYW50aWNIaWdobGlnaHRpbmcjZ2V0UHJlZmVyZW5jZUtleSgpCgkJICovCgkJQE92ZXJyaWRlCgkJcHVibGljIFN0cmluZyBnZXRQcmVmZXJlbmNlS2V5KCkgewoJCQlyZXR1cm4gU1RBVElDX0ZJRUxEOwoJCX0KCgkJLyoKCQkgKiBAc2VlIG9yZy5lY2xpcHNlLmpkdC5pbnRlcm5hbC51aS5qYXZhZWRpdG9yLklTZW1hbnRpY0hpZ2hsaWdodGluZyNnZXREZWZhdWx0VGV4dENvbG9yKCkKCQkgKi8KCQlAT3ZlcnJpZGUKCQlwdWJsaWMgUkdCIGdldERlZmF1bHREZWZhdWx0VGV4dENvbG9yKCkgewoJCQlyZXR1cm4gbmV3IFJHQigwLCAwLCAxOTIpOwoJCX0KCgkJLyoKCQkgKiBAc2VlIG9yZy5lY2xpcHNlLmpkdC5pbnRlcm5hbC51aS5qYXZhZWRpdG9yLklTZW1hbnRpY0hpZ2hsaWdodGluZyNnZXREZWZhdWx0VGV4dFN0eWxlQm9sZCgpCgkJICovCgkJQE92ZXJyaWRlCgkJcHVibGljIGJvb2xlYW4gaXNCb2xkQnlEZWZhdWx0KCkgewoJCQlyZXR1cm4gZmFsc2U7CgkJfQoKCQkvKgoJCSAqIEBzZWUgb3JnLmVjbGlwc2UuamR0LmludGVybmFsLnVpLmphdmFlZGl0b3IuU2VtYW50aWNIaWdobGlnaHRpbmcjaXNJdGFsaWNCeURlZmF1bHQoKQoJCSAqLwoJCUBPdmVycmlkZQoJCXB1YmxpYyBib29sZWFuIGlzSXRhbGljQnlEZWZhdWx0KCkgewoJCQlyZXR1cm4gdHJ1ZTsKCQl9CgoJCS8qCgkJICogQHNlZSBvcmcuZWNsaXBzZS5qZHQuaW50ZXJuYWwudWkuamF2YWVkaXRvci5TZW1hbnRpY0hpZ2hsaWdodGluZyNpc0VuYWJsZWRCeURlZmF1bHQoKQoJCSAqLwoJCUBPdmVycmlkZQoJCXB1YmxpYyBib29sZWFuIGlzRW5hYmxlZEJ5RGVmYXVsdCgpIHsKCQkJcmV0dXJuIHRydWU7CgkJfQoKCQkvKgoJCSAqIEBzZWUgb3JnLmVjbGlwc2UuamR0LmludGVybmFsLnVpLmphdmFlZGl0b3IuSVNlbWFudGljSGlnaGxpZ2h0aW5nI2dldERpc3BsYXlOYW1lKCkKCQkgKi8KCQlAT3ZlcnJpZGUKCQlwdWJsaWMgU3RyaW5nIGdldERpc3BsYXlOYW1lKCkgewoJCQlyZXR1cm4gSmF2YUVkaXRvck1lc3NhZ2VzLlNlbWFudGljSGlnaGxpZ2h0aW5nX3N0YXRpY0ZpZWxkOwoJCX0KCgkJLyoKCQkgKiBAc2VlIG9yZy5lY2xpcHNlLmpkdC5pbnRlcm5hbC51aS5qYXZhZWRpdG9yLlNlbWFudGljSGlnaGxpZ2h0aW5nI2NvbnN1bWVzKG9yZy5lY2xpcHNlLmpkdC5pbnRlcm5hbC51aS5qYXZhZWRpdG9yLlNlbWFudGljVG9rZW4pCgkJICovCgkJQE92ZXJyaWRlCgkJcHVibGljIGJvb2xlYW4gY29uc3VtZXMoU2VtYW50aWNUb2tlbiB0b2tlbikgewoJCQlJQmluZGluZyBiaW5kaW5nPSB0b2tlbi5nZXRCaW5kaW5nKCk7CgkJCXJldHVybiBiaW5kaW5nICE9IG51bGwgJiYgYmluZGluZy5nZXRLaW5kKCkgPT0gSUJpbmRpbmcuVkFSSUFCTEUgJiYgKChJVmFyaWFibGVCaW5kaW5nKWJpbmRpbmcpLmlzRmllbGQoKSAmJiAoYmluZGluZy5nZXRNb2RpZmllcnMoKSAmIE1vZGlmaWVyLlNUQVRJQykgPT0gTW9kaWZpZXIuU1RBVElDOwoJCX0KCX0KCgkvKioKCSAqIFNlbWFudGljIGhpZ2hsaWdodGluZyBmb3IgZmllbGRzLgoJICovCglwcml2YXRlIHN0YXRpYyBmaW5hbCBjbGFzcyBGaWVsZEhpZ2hsaWdodGluZyBleHRlbmRzIFNlbWFudGljSGlnaGxpZ2h0aW5nIHsKCgkJLyoKCQkgKiBAc2VlIG9yZy5lY2xpcHNlLmpkdC5pbnRlcm5hbC51aS5qYXZhZWRpdG9yLlNlbWFudGljSGlnaGxpZ2h0aW5nI2dldFByZWZlcmVuY2VLZXkoKQoJCSAqLwoJCUBPdmVycmlkZQoJCXB1YmxpYyBTdHJpbmcgZ2V0UHJlZmVyZW5jZUtleSgpIHsKCQkJcmV0dXJuIEZJRUxEOwoJCX0KCgkJLyoKCQkgKiBAc2VlIG9yZy5lY2xpcHNlLmpkdC5pbnRlcm5hbC51aS5qYXZhZWRpdG9yLklTZW1hbnRpY0hpZ2hsaWdodGluZyNnZXREZWZhdWx0VGV4dENvbG9yKCkKCQkgKi8KCQlAT3ZlcnJpZGUKCQlwdWJsaWMgUkdCIGdldERlZmF1bHREZWZhdWx0VGV4dENvbG9yKCkgewoJCQlyZXR1cm4gbmV3IFJHQigwLCAwLCAxOTIpOwoJCX0KCgkJLyoKCQkgKiBAc2VlIG9yZy5lY2xpcHNlLmpkdC5pbnRlcm5hbC51aS5qYXZhZWRpdG9yLklTZW1hbnRpY0hpZ2hsaWdodGluZyNnZXREZWZhdWx0VGV4dFN0eWxlQm9sZCgpCgkJICovCgkJQE92ZXJyaWRlCgkJcHVibGljIGJvb2xlYW4gaXNCb2xkQnlEZWZhdWx0KCkgewoJCQlyZXR1cm4gZmFsc2U7CgkJfQoKCQkvKgoJCSAqIEBzZWUgb3JnLmVjbGlwc2UuamR0LmludGVybmFsLnVpLmphdmFlZGl0b3IuU2VtYW50aWNIaWdobGlnaHRpbmcjaXNJdGFsaWNCeURlZmF1bHQoKQoJCSAqLwoJCUBPdmVycmlkZQoJCXB1YmxpYyBib29sZWFuIGlzSXRhbGljQnlEZWZhdWx0KCkgewoJCQlyZXR1cm4gZmFsc2U7CgkJfQoKCQkvKgoJCSAqIEBzZWUgb3JnLmVjbGlwc2UuamR0LmludGVybmFsLnVpLmphdmFlZGl0b3IuU2VtYW50aWNIaWdobGlnaHRpbmcjaXNFbmFibGVkQnlEZWZhdWx0KCkKCQkgKi8KCQlAT3ZlcnJpZGUKCQlwdWJsaWMgYm9vbGVhbiBpc0VuYWJsZWRCeURlZmF1bHQoKSB7CgkJCXJldHVybiB0cnVlOwoJCX0KCgkJLyoKCQkgKiBAc2VlIG9yZy5lY2xpcHNlLmpkdC5pbnRlcm5hbC51aS5qYXZhZWRpdG9yLklTZW1hbnRpY0hpZ2hsaWdodGluZyNnZXREaXNwbGF5TmFtZSgpCgkJICovCgkJQE92ZXJyaWRlCgkJcHVibGljIFN0cmluZyBnZXREaXNwbGF5TmFtZSgpIHsKCQkJcmV0dXJuIEphdmFFZGl0b3JNZXNzYWdlcy5TZW1hbnRpY0hpZ2hsaWdodGluZ19maWVsZDsKCQl9CgoJCS8qCgkJICogQHNlZSBvcmcuZWNsaXBzZS5qZHQuaW50ZXJuYWwudWkuamF2YWVkaXRvci5TZW1hbnRpY0hpZ2hsaWdodGluZyNjb25zdW1lcyhvcmcuZWNsaXBzZS5qZHQuaW50ZXJuYWwudWkuamF2YWVkaXRvci5TZW1hbnRpY1Rva2VuKQoJCSAqLwoJCUBPdmVycmlkZQoJCXB1YmxpYyBib29sZWFuIGNvbnN1bWVzKFNlbWFudGljVG9rZW4gdG9rZW4pIHsKCQkJSUJpbmRpbmcgYmluZGluZz0gdG9rZW4uZ2V0QmluZGluZygpOwoJCQlyZXR1cm4gYmluZGluZyAhPSBudWxsICYmIGJpbmRpbmcuZ2V0S2luZCgpID09IElCaW5kaW5nLlZBUklBQkxFICYmICgoSVZhcmlhYmxlQmluZGluZyliaW5kaW5nKS5pc0ZpZWxkKCk7CgkJfQoJfQoKCS8qKgoJICogU2VtYW50aWMgaGlnaGxpZ2h0aW5nIGZvciBhdXRvKHVuKWJveGVkIGV4cHJlc3Npb25zLgoJICovCglwcml2YXRlIHN0YXRpYyBmaW5hbCBjbGFzcyBBdXRvYm94SGlnaGxpZ2h0aW5nIGV4dGVuZHMgU2VtYW50aWNIaWdobGlnaHRpbmcgewoKCQkvKgoJCSAqIEBzZWUgb3JnLmVjbGlwc2UuamR0LmludGVybmFsLnVpLmphdmFlZGl0b3IuU2VtYW50aWNIaWdobGlnaHRpbmcjZ2V0UHJlZmVyZW5jZUtleSgpCgkJICovCgkJQE92ZXJyaWRlCgkJcHVibGljIFN0cmluZyBnZXRQcmVmZXJlbmNlS2V5KCkgewoJCQlyZXR1cm4gQVVUT0JPWElORzsKCQl9CgoJCS8qCgkJICogQHNlZSBvcmcuZWNsaXBzZS5qZHQuaW50ZXJuYWwudWkuamF2YWVkaXRvci5JU2VtYW50aWNIaWdobGlnaHRpbmcjZ2V0RGVmYXVsdFRleHRDb2xvcigpCgkJICovCgkJQE92ZXJyaWRlCgkJcHVibGljIFJHQiBnZXREZWZhdWx0RGVmYXVsdFRleHRDb2xvcigpIHsKCQkJcmV0dXJuIG5ldyBSR0IoMTcxLCA0OCwgMCk7CgkJfQoKCQkvKgoJCSAqIEBzZWUgb3JnLmVjbGlwc2UuamR0LmludGVybmFsLnVpLmphdmFlZGl0b3IuSVNlbWFudGljSGlnaGxpZ2h0aW5nI2dldERlZmF1bHRUZXh0U3R5bGVCb2xkKCkKCQkgKi8KCQlAT3ZlcnJpZGUKCQlwdWJsaWMgYm9vbGVhbiBpc0JvbGRCeURlZmF1bHQoKSB7CgkJCXJldHVybiBmYWxzZTsKCQl9CgoJCS8qCgkJICogQHNlZSBvcmcuZWNsaXBzZS5qZHQuaW50ZXJuYWwudWkuamF2YWVkaXRvci5TZW1hbnRpY0hpZ2hsaWdodGluZyNpc0l0YWxpY0J5RGVmYXVsdCgpCgkJICovCgkJQE92ZXJyaWRlCgkJcHVibGljIGJvb2xlYW4gaXNJdGFsaWNCeURlZmF1bHQoKSB7CgkJCXJldHVybiBmYWxzZTsKCQl9CgoJCS8qCgkJICogQHNlZSBvcmcuZWNsaXBzZS5qZHQuaW50ZXJuYWwudWkuamF2YWVkaXRvci5TZW1hbnRpY0hpZ2hsaWdodGluZyNpc0VuYWJsZWRCeURlZmF1bHQoKQoJCSAqLwoJCUBPdmVycmlkZQoJCXB1YmxpYyBib29sZWFuIGlzRW5hYmxlZEJ5RGVmYXVsdCgpIHsKCQkJcmV0dXJuIGZhbHNlOwoJCX0KCgkJLyoKCQkgKiBAc2VlIG9yZy5lY2xpcHNlLmpkdC5pbnRlcm5hbC51aS5qYXZhZWRpdG9yLklTZW1hbnRpY0hpZ2hsaWdodGluZyNnZXREaXNwbGF5TmFtZSgpCgkJICovCgkJQE92ZXJyaWRlCgkJcHVibGljIFN0cmluZyBnZXREaXNwbGF5TmFtZSgpIHsKCQkJcmV0dXJuIEphdmFFZGl0b3JNZXNzYWdlcy5TZW1hbnRpY0hpZ2hsaWdodGluZ19hdXRvYm94aW5nOwoJCX0KCgkJLyoKCQkgKiBAc2VlIG9yZy5lY2xpcHNlLmpkdC5pbnRlcm5hbC51aS5qYXZhZWRpdG9yLlNlbWFudGljSGlnaGxpZ2h0aW5nI2NvbnN1bWVzTGl0ZXJhbChvcmcuZWNsaXBzZS5qZHQuaW50ZXJuYWwudWkuamF2YWVkaXRvci5TZW1hbnRpY1Rva2VuKQoJCSAqLwoJCUBPdmVycmlkZQoJCXB1YmxpYyBib29sZWFuIGNvbnN1bWVzTGl0ZXJhbChTZW1hbnRpY1Rva2VuIHRva2VuKSB7CgkJCXJldHVybiBpc0F1dG9VbkJveGluZyh0b2tlbi5nZXRMaXRlcmFsKCkpOwoJCX0KCgkJLyoKCQkgKiBAc2VlIG9yZy5lY2xpcHNlLmpkdC5pbnRlcm5hbC51aS5qYXZhZWRpdG9yLlNlbWFudGljSGlnaGxpZ2h0aW5nI2NvbnN1bWVzKG9yZy5lY2xpcHNlLmpkdC5pbnRlcm5hbC51aS5qYXZhZWRpdG9yLlNlbWFudGljVG9rZW4pCgkJICovCgkJQE92ZXJyaWRlCgkJcHVibGljIGJvb2xlYW4gY29uc3VtZXMoU2VtYW50aWNUb2tlbiB0b2tlbikgewoJCQlyZXR1cm4gaXNBdXRvVW5Cb3hpbmcodG9rZW4uZ2V0Tm9kZSgpKTsKCQl9CgoJCXByaXZhdGUgYm9vbGVhbiBpc0F1dG9VbkJveGluZyhFeHByZXNzaW9uIG5vZGUpIHsKCQkJaWYgKGlzQXV0b1VuQm94aW5nRXhwcmVzc2lvbihub2RlKSkKCQkJCXJldHVybiB0cnVlOwoJCQkvLyBzcGVjaWFsIGNhc2VzOiB0aGUgYXV0b2JveGluZyBjb252ZXJzaW9ucyBoYXBwZW5zIGF0IGEKCQkJLy8gbG9jYXRpb24gdGhhdCBpcyBub3QgbWFwcGVkIGRpcmVjdGx5IHRvIGEgc2ltcGxlIG5hbWUKCQkJLy8gb3IgYSBsaXRlcmFsLCBidXQgY2FuIHN0aWxsIGJlIG1hcHBlZCBzb21laG93CgkJCS8vIEEpIGV4cHJlc3Npb25zCgkJCVN0cnVjdHVyYWxQcm9wZXJ0eURlc2NyaXB0b3IgZGVzYz0gbm9kZS5nZXRMb2NhdGlvbkluUGFyZW50KCk7CgkJCWlmIChkZXNjID09IEFycmF5QWNjZXNzLkFSUkFZX1BST1BFUlRZCgkJCQkJfHwgZGVzYyA9PSBJbmZpeEV4cHJlc3Npb24uTEVGVF9PUEVSQU5EX1BST1BFUlRZCgkJCQkJfHwgZGVzYyA9PSBJbmZpeEV4cHJlc3Npb24uUklHSFRfT1BFUkFORF9QUk9QRVJUWQoJCQkJCXx8IGRlc2MgPT0gQ29uZGl0aW9uYWxFeHByZXNzaW9uLlRIRU5fRVhQUkVTU0lPTl9QUk9QRVJUWQoJCQkJCXx8IGRlc2MgPT0gUHJlZml4RXhwcmVzc2lvbi5PUEVSQU5EX1BST1BFUlRZCgkJCQkJfHwgZGVzYyA9PSBDYXN0RXhwcmVzc2lvbi5FWFBSRVNTSU9OX1BST1BFUlRZCgkJCQkJfHwgZGVzYyA9PSBDb25kaXRpb25hbEV4cHJlc3Npb24uRUxTRV9FWFBSRVNTSU9OX1BST1BFUlRZKSB7CgkJCQlBU1ROb2RlIHBhcmVudD0gbm9kZS5nZXRQYXJlbnQoKTsKCQkJCWlmIChwYXJlbnQgaW5zdGFuY2VvZiBFeHByZXNzaW9uKQoJCQkJCXJldHVybiBpc0F1dG9VbkJveGluZ0V4cHJlc3Npb24oKEV4cHJlc3Npb24pIHBhcmVudCk7CgkJCX0KCQkJLy8gQikgY29uc3RydWN0b3IgaW52b2NhdGlvbnMKCQkJaWYgKGRlc2MgPT0gU2ltcGxlVHlwZS5OQU1FX1BST1BFUlRZIHx8IGRlc2MgPT0gUXVhbGlmaWVkVHlwZS5OQU1FX1BST1BFUlRZKSB7CgkJCQlBU1ROb2RlIHBhcmVudD0gbm9kZS5nZXRQYXJlbnQoKTsKCQkJCWlmIChwYXJlbnQgIT0gbnVsbCAmJiBwYXJlbnQuZ2V0TG9jYXRpb25JblBhcmVudCgpID09IENsYXNzSW5zdGFuY2VDcmVhdGlvbi5UWVBFX1BST1BFUlRZKSB7CgkJCQkJcGFyZW50PSBwYXJlbnQuZ2V0UGFyZW50KCk7CgkJCQkJaWYgKHBhcmVudCBpbnN0YW5jZW9mIEV4cHJlc3Npb24pCgkJCQkJCXJldHVybiBpc0F1dG9VbkJveGluZ0V4cHJlc3Npb24oKEV4cHJlc3Npb24pIHBhcmVudCk7CgkJCQl9CgkJCX0KCQkJcmV0dXJuIGZhbHNlOwoJCX0KCgkJcHJpdmF0ZSBib29sZWFuIGlzQXV0b1VuQm94aW5nRXhwcmVzc2lvbihFeHByZXNzaW9uIGV4cHJlc3Npb24pIHsKCQkJcmV0dXJuIGV4cHJlc3Npb24ucmVzb2x2ZUJveGluZygpIHx8IGV4cHJlc3Npb24ucmVzb2x2ZVVuYm94aW5nKCk7CgkJfQoJfQoKCS8qKgoJICogU2VtYW50aWMgaGlnaGxpZ2h0aW5nIGZvciBtZXRob2QgZGVjbGFyYXRpb25zLgoJICovCglwcml2YXRlIHN0YXRpYyBmaW5hbCBjbGFzcyBNZXRob2REZWNsYXJhdGlvbkhpZ2hsaWdodGluZyBleHRlbmRzIFNlbWFudGljSGlnaGxpZ2h0aW5nIHsKCgkJLyoKCQkgKiBAc2VlIG9yZy5lY2xpcHNlLmpkdC5pbnRlcm5hbC51aS5qYXZhZWRpdG9yLlNlbWFudGljSGlnaGxpZ2h0aW5nI2dldFByZWZlcmVuY2VLZXkoKQoJCSAqLwoJCUBPdmVycmlkZQoJCXB1YmxpYyBTdHJpbmcgZ2V0UHJlZmVyZW5jZUtleSgpIHsKCQkJcmV0dXJuIE1FVEhPRF9ERUNMQVJBVElPTjsKCQl9CgoJCS8qCgkJICogQHNlZSBvcmcuZWNsaXBzZS5qZHQuaW50ZXJuYWwudWkuamF2YWVkaXRvci5JU2VtYW50aWNIaWdobGlnaHRpbmcjZ2V0RGVmYXVsdFRleHRDb2xvcigpCgkJICovCgkJQE92ZXJyaWRlCgkJcHVibGljIFJHQiBnZXREZWZhdWx0RGVmYXVsdFRleHRDb2xvcigpIHsKCQkJcmV0dXJuIG5ldyBSR0IoMCwgMCwgMCk7CgkJfQoKCQkvKgoJCSAqIEBzZWUgb3JnLmVjbGlwc2UuamR0LmludGVybmFsLnVpLmphdmFlZGl0b3IuSVNlbWFudGljSGlnaGxpZ2h0aW5nI2dldERlZmF1bHRUZXh0U3R5bGVCb2xkKCkKCQkgKi8KCQlAT3ZlcnJpZGUKCQlwdWJsaWMgYm9vbGVhbiBpc0JvbGRCeURlZmF1bHQoKSB7CgkJCXJldHVybiB0cnVlOwoJCX0KCgkJLyoKCQkgKiBAc2VlIG9yZy5lY2xpcHNlLmpkdC5pbnRlcm5hbC51aS5qYXZhZWRpdG9yLlNlbWFudGljSGlnaGxpZ2h0aW5nI2lzSXRhbGljQnlEZWZhdWx0KCkKCQkgKi8KCQlAT3ZlcnJpZGUKCQlwdWJsaWMgYm9vbGVhbiBpc0l0YWxpY0J5RGVmYXVsdCgpIHsKCQkJcmV0dXJuIGZhbHNlOwoJCX0KCgkJLyoKCQkgKiBAc2VlIG9yZy5lY2xpcHNlLmpkdC5pbnRlcm5hbC51aS5qYXZhZWRpdG9yLlNlbWFudGljSGlnaGxpZ2h0aW5nI2lzRW5hYmxlZEJ5RGVmYXVsdCgpCgkJICovCgkJQE92ZXJyaWRlCgkJcHVibGljIGJvb2xlYW4gaXNFbmFibGVkQnlEZWZhdWx0KCkgewoJCQlyZXR1cm4gZmFsc2U7CgkJfQoKCQkvKgoJCSAqIEBzZWUgb3JnLmVjbGlwc2UuamR0LmludGVybmFsLnVpLmphdmFlZGl0b3IuSVNlbWFudGljSGlnaGxpZ2h0aW5nI2dldERpc3BsYXlOYW1lKCkKCQkgKi8KCQlAT3ZlcnJpZGUKCQlwdWJsaWMgU3RyaW5nIGdldERpc3BsYXlOYW1lKCkgewoJCQlyZXR1cm4gSmF2YUVkaXRvck1lc3NhZ2VzLlNlbWFudGljSGlnaGxpZ2h0aW5nX21ldGhvZERlY2xhcmF0aW9uOwoJCX0KCgkJLyoKCQkgKiBAc2VlIG9yZy5lY2xpcHNlLmpkdC5pbnRlcm5hbC51aS5qYXZhZWRpdG9yLklTZW1hbnRpY0hpZ2hsaWdodGluZyNpc01hdGNoZWQob3JnLmVjbGlwc2UuamR0LmNvcmUuZG9tLkFTVE5vZGUpCgkJICovCgkJQE92ZXJyaWRlCgkJcHVibGljIGJvb2xlYW4gY29uc3VtZXMoU2VtYW50aWNUb2tlbiB0b2tlbikgewoJCQlTdHJ1Y3R1cmFsUHJvcGVydHlEZXNjcmlwdG9yIGxvY2F0aW9uPSB0b2tlbi5nZXROb2RlKCkuZ2V0TG9jYXRpb25JblBhcmVudCgpOwoJCQlyZXR1cm4gbG9jYXRpb24gPT0gTWV0aG9kRGVjbGFyYXRpb24uTkFNRV9QUk9QRVJUWSB8fCBsb2NhdGlvbiA9PSBBbm5vdGF0aW9uVHlwZU1lbWJlckRlY2xhcmF0aW9uLk5BTUVfUFJPUEVSVFk7CgkJfQoJfQoKCS8qKgoJICogU2VtYW50aWMgaGlnaGxpZ2h0aW5nIGZvciBzdGF0aWMgbWV0aG9kIGludm9jYXRpb25zLgoJICovCglwcml2YXRlIHN0YXRpYyBmaW5hbCBjbGFzcyBTdGF0aWNNZXRob2RJbnZvY2F0aW9uSGlnaGxpZ2h0aW5nIGV4dGVuZHMgU2VtYW50aWNIaWdobGlnaHRpbmcgewoKCQkvKgoJCSAqIEBzZWUgb3JnLmVjbGlwc2UuamR0LmludGVybmFsLnVpLmphdmFlZGl0b3IuU2VtYW50aWNIaWdobGlnaHRpbmcjZ2V0UHJlZmVyZW5jZUtleSgpCgkJICovCgkJQE92ZXJyaWRlCgkJcHVibGljIFN0cmluZyBnZXRQcmVmZXJlbmNlS2V5KCkgewoJCQlyZXR1cm4gU1RBVElDX01FVEhPRF9JTlZPQ0FUSU9OOwoJCX0KCgkJLyoKCQkgKiBAc2VlIG9yZy5lY2xpcHNlLmpkdC5pbnRlcm5hbC51aS5qYXZhZWRpdG9yLklTZW1hbnRpY0hpZ2hsaWdodGluZyNnZXREZWZhdWx0VGV4dENvbG9yKCkKCQkgKi8KCQlAT3ZlcnJpZGUKCQlwdWJsaWMgUkdCIGdldERlZmF1bHREZWZhdWx0VGV4dENvbG9yKCkgewoJCQlyZXR1cm4gbmV3IFJHQigwLCAwLCAwKTsKCQl9CgoJCS8qCgkJICogQHNlZSBvcmcuZWNsaXBzZS5qZHQuaW50ZXJuYWwudWkuamF2YWVkaXRvci5JU2VtYW50aWNIaWdobGlnaHRpbmcjZ2V0RGVmYXVsdFRleHRTdHlsZUJvbGQoKQoJCSAqLwoJCUBPdmVycmlkZQoJCXB1YmxpYyBib29sZWFuIGlzQm9sZEJ5RGVmYXVsdCgpIHsKCQkJcmV0dXJuIGZhbHNlOwoJCX0KCgkJLyoKCQkgKiBAc2VlIG9yZy5lY2xpcHNlLmpkdC5pbnRlcm5hbC51aS5qYXZhZWRpdG9yLlNlbWFudGljSGlnaGxpZ2h0aW5nI2lzSXRhbGljQnlEZWZhdWx0KCkKCQkgKi8KCQlAT3ZlcnJpZGUKCQlwdWJsaWMgYm9vbGVhbiBpc0l0YWxpY0J5RGVmYXVsdCgpIHsKCQkJcmV0dXJuIHRydWU7CgkJfQoKCQkvKgoJCSAqIEBzZWUgb3JnLmVjbGlwc2UuamR0LmludGVybmFsLnVpLmphdmFlZGl0b3IuU2VtYW50aWNIaWdobGlnaHRpbmcjaXNFbmFibGVkQnlEZWZhdWx0KCkKCQkgKi8KCQlAT3ZlcnJpZGUKCQlwdWJsaWMgYm9vbGVhbiBpc0VuYWJsZWRCeURlZmF1bHQoKSB7CgkJCXJldHVybiB0cnVlOwoJCX0KCgkJLyoKCQkgKiBAc2VlIG9yZy5lY2xpcHNlLmpkdC5pbnRlcm5hbC51aS5qYXZhZWRpdG9yLklTZW1hbnRpY0hpZ2hsaWdodGluZyNnZXREaXNwbGF5TmFtZSgpCgkJICovCgkJQE92ZXJyaWRlCgkJcHVibGljIFN0cmluZyBnZXREaXNwbGF5TmFtZSgpIHsKCQkJcmV0dXJuIEphdmFFZGl0b3JNZXNzYWdlcy5TZW1hbnRpY0hpZ2hsaWdodGluZ19zdGF0aWNNZXRob2RJbnZvY2F0aW9uOwoJCX0KCgkJLyoKCQkgKiBAc2VlIG9yZy5lY2xpcHNlLmpkdC5pbnRlcm5hbC51aS5qYXZhZWRpdG9yLklTZW1hbnRpY0hpZ2hsaWdodGluZyNpc01hdGNoZWQob3JnLmVjbGlwc2UuamR0LmNvcmUuZG9tLkFTVE5vZGUpCgkJICovCgkJQE92ZXJyaWRlCgkJcHVibGljIGJvb2xlYW4gY29uc3VtZXMoU2VtYW50aWNUb2tlbiB0b2tlbikgewoJCQlTaW1wbGVOYW1lIG5vZGU9IHRva2VuLmdldE5vZGUoKTsKCQkJaWYgKG5vZGUuaXNEZWNsYXJhdGlvbigpKQoJCQkJcmV0dXJuIGZhbHNlOwoKCQkJSUJpbmRpbmcgYmluZGluZz0gdG9rZW4uZ2V0QmluZGluZygpOwoJCQlyZXR1cm4gYmluZGluZyAhPSBudWxsICYmIGJpbmRpbmcuZ2V0S2luZCgpID09IElCaW5kaW5nLk1FVEhPRCAmJiAoYmluZGluZy5nZXRNb2RpZmllcnMoKSAmIE1vZGlmaWVyLlNUQVRJQykgPT0gTW9kaWZpZXIuU1RBVElDOwoJCX0KCX0KCgkvKioKCSAqIFNlbWFudGljIGhpZ2hsaWdodGluZyBmb3IgYW5ub3RhdGlvbiBlbGVtZW50IHJlZmVyZW5jZXMuCgkgKiBAc2luY2UgMy4xCgkgKi8KCXByaXZhdGUgc3RhdGljIGZpbmFsIGNsYXNzIEFubm90YXRpb25FbGVtZW50UmVmZXJlbmNlSGlnaGxpZ2h0aW5nIGV4dGVuZHMgU2VtYW50aWNIaWdobGlnaHRpbmcgewoKCQkvKgoJCSAqIEBzZWUgb3JnLmVjbGlwc2UuamR0LmludGVybmFsLnVpLmphdmFlZGl0b3IuU2VtYW50aWNIaWdobGlnaHRpbmcjZ2V0UHJlZmVyZW5jZUtleSgpCgkJICovCgkJQE92ZXJyaWRlCgkJcHVibGljIFN0cmluZyBnZXRQcmVmZXJlbmNlS2V5KCkgewoJCQlyZXR1cm4gQU5OT1RBVElPTl9FTEVNRU5UX1JFRkVSRU5DRTsKCQl9CgoJCS8qCgkJICogQHNlZSBvcmcuZWNsaXBzZS5qZHQuaW50ZXJuYWwudWkuamF2YWVkaXRvci5JU2VtYW50aWNIaWdobGlnaHRpbmcjZ2V0RGVmYXVsdFRleHRDb2xvcigpCgkJICovCgkJQE92ZXJyaWRlCgkJcHVibGljIFJHQiBnZXREZWZhdWx0RGVmYXVsdFRleHRDb2xvcigpIHsKCQkJcmV0dXJuIG5ldyBSR0IoMCwgMCwgMCk7CgkJfQoKCQkvKgoJCSAqIEBzZWUgb3JnLmVjbGlwc2UuamR0LmludGVybmFsLnVpLmphdmFlZGl0b3IuSVNlbWFudGljSGlnaGxpZ2h0aW5nI2dldERlZmF1bHRUZXh0U3R5bGVCb2xkKCkKCQkgKi8KCQlAT3ZlcnJpZGUKCQlwdWJsaWMgYm9vbGVhbiBpc0JvbGRCeURlZmF1bHQoKSB7CgkJCXJldHVybiBmYWxzZTsKCQl9CgoJCS8qCgkJICogQHNlZSBvcmcuZWNsaXBzZS5qZHQuaW50ZXJuYWwudWkuamF2YWVkaXRvci5TZW1hbnRpY0hpZ2hsaWdodGluZyNpc0l0YWxpY0J5RGVmYXVsdCgpCgkJICovCgkJQE92ZXJyaWRlCgkJcHVibGljIGJvb2xlYW4gaXNJdGFsaWNCeURlZmF1bHQoKSB7CgkJCXJldHVybiBmYWxzZTsKCQl9CgoJCS8qCgkJICogQHNlZSBvcmcuZWNsaXBzZS5qZHQuaW50ZXJuYWwudWkuamF2YWVkaXRvci5TZW1hbnRpY0hpZ2hsaWdodGluZyNpc0VuYWJsZWRCeURlZmF1bHQoKQoJCSAqLwoJCUBPdmVycmlkZQoJCXB1YmxpYyBib29sZWFuIGlzRW5hYmxlZEJ5RGVmYXVsdCgpIHsKCQkJcmV0dXJuIGZhbHNlOwoJCX0KCgkJLyoKCQkgKiBAc2VlIG9yZy5lY2xpcHNlLmpkdC5pbnRlcm5hbC51aS5qYXZhZWRpdG9yLklTZW1hbnRpY0hpZ2hsaWdodGluZyNnZXREaXNwbGF5TmFtZSgpCgkJICovCgkJQE92ZXJyaWRlCgkJcHVibGljIFN0cmluZyBnZXREaXNwbGF5TmFtZSgpIHsKCQkJcmV0dXJuIEphdmFFZGl0b3JNZXNzYWdlcy5TZW1hbnRpY0hpZ2hsaWdodGluZ19hbm5vdGF0aW9uRWxlbWVudFJlZmVyZW5jZTsKCQl9CgoJCS8qCgkJICogQHNlZSBvcmcuZWNsaXBzZS5qZHQuaW50ZXJuYWwudWkuamF2YWVkaXRvci5JU2VtYW50aWNIaWdobGlnaHRpbmcjaXNNYXRjaGVkKG9yZy5lY2xpcHNlLmpkdC5jb3JlLmRvbS5BU1ROb2RlKQoJCSAqLwoJCUBPdmVycmlkZQoJCXB1YmxpYyBib29sZWFuIGNvbnN1bWVzKFNlbWFudGljVG9rZW4gdG9rZW4pIHsKCQkJU2ltcGxlTmFtZSBub2RlPSB0b2tlbi5nZXROb2RlKCk7CgkJCWlmIChub2RlLmdldFBhcmVudCgpIGluc3RhbmNlb2YgTWVtYmVyVmFsdWVQYWlyKSB7CgkJCQlJQmluZGluZyBiaW5kaW5nPSB0b2tlbi5nZXRCaW5kaW5nKCk7CgkJCQlib29sZWFuIGlzQW5ub3RhdGlvbkVsZW1lbnQ9IGJpbmRpbmcgIT0gbnVsbCAmJiBiaW5kaW5nLmdldEtpbmQoKSA9PSBJQmluZGluZy5NRVRIT0Q7CgoJCQkJcmV0dXJuIGlzQW5ub3RhdGlvbkVsZW1lbnQ7CgkJCX0KCgkJCXJldHVybiBmYWxzZTsKCQl9Cgl9CgoJLyoqCgkgKiBTZW1hbnRpYyBoaWdobGlnaHRpbmcgZm9yIGFic3RyYWN0IG1ldGhvZCBpbnZvY2F0aW9ucy4KCSAqLwoJcHJpdmF0ZSBzdGF0aWMgZmluYWwgY2xhc3MgQWJzdHJhY3RNZXRob2RJbnZvY2F0aW9uSGlnaGxpZ2h0aW5nIGV4dGVuZHMgU2VtYW50aWNIaWdobGlnaHRpbmcgewoKCQkvKgoJCSAqIEBzZWUgb3JnLmVjbGlwc2UuamR0LmludGVybmFsLnVpLmphdmFlZGl0b3IuU2VtYW50aWNIaWdobGlnaHRpbmcjZ2V0UHJlZmVyZW5jZUtleSgpCgkJICovCgkJQE92ZXJyaWRlCgkJcHVibGljIFN0cmluZyBnZXRQcmVmZXJlbmNlS2V5KCkgewoJCQlyZXR1cm4gQUJTVFJBQ1RfTUVUSE9EX0lOVk9DQVRJT047CgkJfQoKCQkvKgoJCSAqIEBzZWUgb3JnLmVjbGlwc2UuamR0LmludGVybmFsLnVpLmphdmFlZGl0b3IuSVNlbWFudGljSGlnaGxpZ2h0aW5nI2dldERlZmF1bHRUZXh0Q29sb3IoKQoJCSAqLwoJCUBPdmVycmlkZQoJCXB1YmxpYyBSR0IgZ2V0RGVmYXVsdERlZmF1bHRUZXh0Q29sb3IoKSB7CgkJCXJldHVybiBuZXcgUkdCKDAsIDAsIDApOwoJCX0KCgkJLyoKCQkgKiBAc2VlIG9yZy5lY2xpcHNlLmpkdC5pbnRlcm5hbC51aS5qYXZhZWRpdG9yLklTZW1hbnRpY0hpZ2hsaWdodGluZyNnZXREZWZhdWx0VGV4dFN0eWxlQm9sZCgpCgkJICovCgkJQE92ZXJyaWRlCgkJcHVibGljIGJvb2xlYW4gaXNCb2xkQnlEZWZhdWx0KCkgewoJCQlyZXR1cm4gZmFsc2U7CgkJfQoKCQkvKgoJCSAqIEBzZWUgb3JnLmVjbGlwc2UuamR0LmludGVybmFsLnVpLmphdmFlZGl0b3IuU2VtYW50aWNIaWdobGlnaHRpbmcjaXNJdGFsaWNCeURlZmF1bHQoKQoJCSAqLwoJCUBPdmVycmlkZQoJCXB1YmxpYyBib29sZWFuIGlzSXRhbGljQnlEZWZhdWx0KCkgewoJCQlyZXR1cm4gZmFsc2U7CgkJfQoKCQkvKgoJCSAqIEBzZWUgb3JnLmVjbGlwc2UuamR0LmludGVybmFsLnVpLmphdmFlZGl0b3IuU2VtYW50aWNIaWdobGlnaHRpbmcjaXNFbmFibGVkQnlEZWZhdWx0KCkKCQkgKi8KCQlAT3ZlcnJpZGUKCQlwdWJsaWMgYm9vbGVhbiBpc0VuYWJsZWRCeURlZmF1bHQoKSB7CgkJCXJldHVybiBmYWxzZTsKCQl9CgoJCS8qCgkJICogQHNlZSBvcmcuZWNsaXBzZS5qZHQuaW50ZXJuYWwudWkuamF2YWVkaXRvci5JU2VtYW50aWNIaWdobGlnaHRpbmcjZ2V0RGlzcGxheU5hbWUoKQoJCSAqLwoJCUBPdmVycmlkZQoJCXB1YmxpYyBTdHJpbmcgZ2V0RGlzcGxheU5hbWUoKSB7CgkJCXJldHVybiBKYXZhRWRpdG9yTWVzc2FnZXMuU2VtYW50aWNIaWdobGlnaHRpbmdfYWJzdHJhY3RNZXRob2RJbnZvY2F0aW9uOwoJCX0KCgkJLyoKCQkgKiBAc2VlIG9yZy5lY2xpcHNlLmpkdC5pbnRlcm5hbC51aS5qYXZhZWRpdG9yLklTZW1hbnRpY0hpZ2hsaWdodGluZyNpc01hdGNoZWQob3JnLmVjbGlwc2UuamR0LmNvcmUuZG9tLkFTVE5vZGUpCgkJICovCgkJQE92ZXJyaWRlCgkJcHVibGljIGJvb2xlYW4gY29uc3VtZXMoU2VtYW50aWNUb2tlbiB0b2tlbikgewoJCQlTaW1wbGVOYW1lIG5vZGU9IHRva2VuLmdldE5vZGUoKTsKCQkJaWYgKG5vZGUuaXNEZWNsYXJhdGlvbigpKQoJCQkJcmV0dXJuIGZhbHNlOwoKCQkJSUJpbmRpbmcgYmluZGluZz0gdG9rZW4uZ2V0QmluZGluZygpOwoJCQlib29sZWFuIGlzQWJzdHJhY3RNZXRob2Q9IGJpbmRpbmcgIT0gbnVsbCAmJiBiaW5kaW5nLmdldEtpbmQoKSA9PSBJQmluZGluZy5NRVRIT0QgJiYgKGJpbmRpbmcuZ2V0TW9kaWZpZXJzKCkgJiBNb2RpZmllci5BQlNUUkFDVCkgPT0gTW9kaWZpZXIuQUJTVFJBQ1Q7CgkJCWlmICghaXNBYnN0cmFjdE1ldGhvZCkKCQkJCXJldHVybiBmYWxzZTsKCgkJCS8vIGZpbHRlciBvdXQgYW5ub3RhdGlvbiB2YWx1ZSByZWZlcmVuY2VzCgkJCWlmIChiaW5kaW5nICE9IG51bGwpIHsKCQkJCUlUeXBlQmluZGluZyBkZWNsYXJpbmdUeXBlPSAoKElNZXRob2RCaW5kaW5nKWJpbmRpbmcpLmdldERlY2xhcmluZ0NsYXNzKCk7CgkJCQlpZiAoZGVjbGFyaW5nVHlwZS5pc0Fubm90YXRpb24oKSkKCQkJCQlyZXR1cm4gZmFsc2U7CgkJCX0KCgkJCXJldHVybiB0cnVlOwoJCX0KCX0KCgkvKioKCSAqIFNlbWFudGljIGhpZ2hsaWdodGluZyBmb3IgaW5oZXJpdGVkIG1ldGhvZCBpbnZvY2F0aW9ucy4KCSAqLwoJcHJpdmF0ZSBzdGF0aWMgZmluYWwgY2xhc3MgSW5oZXJpdGVkTWV0aG9kSW52b2NhdGlvbkhpZ2hsaWdodGluZyBleHRlbmRzIFNlbWFudGljSGlnaGxpZ2h0aW5nIHsKCgkJLyoKCQkgKiBAc2VlIG9yZy5lY2xpcHNlLmpkdC5pbnRlcm5hbC51aS5qYXZhZWRpdG9yLlNlbWFudGljSGlnaGxpZ2h0aW5nI2dldFByZWZlcmVuY2VLZXkoKQoJCSAqLwoJCUBPdmVycmlkZQoJCXB1YmxpYyBTdHJpbmcgZ2V0UHJlZmVyZW5jZUtleSgpIHsKCQkJcmV0dXJuIElOSEVSSVRFRF9NRVRIT0RfSU5WT0NBVElPTjsKCQl9CgoJCS8qCgkJICogQHNlZSBvcmcuZWNsaXBzZS5qZHQuaW50ZXJuYWwudWkuamF2YWVkaXRvci5JU2VtYW50aWNIaWdobGlnaHRpbmcjZ2V0RGVmYXVsdFRleHRDb2xvcigpCgkJICovCgkJQE92ZXJyaWRlCgkJcHVibGljIFJHQiBnZXREZWZhdWx0RGVmYXVsdFRleHRDb2xvcigpIHsKCQkJcmV0dXJuIG5ldyBSR0IoMCwgMCwgMCk7CgkJfQoKCQkvKgoJCSAqIEBzZWUgb3JnLmVjbGlwc2UuamR0LmludGVybmFsLnVpLmphdmFlZGl0b3IuSVNlbWFudGljSGlnaGxpZ2h0aW5nI2dldERlZmF1bHRUZXh0U3R5bGVCb2xkKCkKCQkgKi8KCQlAT3ZlcnJpZGUKCQlwdWJsaWMgYm9vbGVhbiBpc0JvbGRCeURlZmF1bHQoKSB7CgkJCXJldHVybiBmYWxzZTsKCQl9CgoJCS8qCgkJICogQHNlZSBvcmcuZWNsaXBzZS5qZHQuaW50ZXJuYWwudWkuamF2YWVkaXRvci5TZW1hbnRpY0hpZ2hsaWdodGluZyNpc0l0YWxpY0J5RGVmYXVsdCgpCgkJICovCgkJQE92ZXJyaWRlCgkJcHVibGljIGJvb2xlYW4gaXNJdGFsaWNCeURlZmF1bHQoKSB7CgkJCXJldHVybiBmYWxzZTsKCQl9CgoJCS8qCgkJICogQHNlZSBvcmcuZWNsaXBzZS5qZHQuaW50ZXJuYWwudWkuamF2YWVkaXRvci5TZW1hbnRpY0hpZ2hsaWdodGluZyNpc0VuYWJsZWRCeURlZmF1bHQoKQoJCSAqLwoJCUBPdmVycmlkZQoJCXB1YmxpYyBib29sZWFuIGlzRW5hYmxlZEJ5RGVmYXVsdCgpIHsKCQkJcmV0dXJuIGZhbHNlOwoJCX0KCgkJLyoKCQkgKiBAc2VlIG9yZy5lY2xpcHNlLmpkdC5pbnRlcm5hbC51aS5qYXZhZWRpdG9yLklTZW1hbnRpY0hpZ2hsaWdodGluZyNnZXREaXNwbGF5TmFtZSgpCgkJICovCgkJQE92ZXJyaWRlCgkJcHVibGljIFN0cmluZyBnZXREaXNwbGF5TmFtZSgpIHsKCQkJcmV0dXJuIEphdmFFZGl0b3JNZXNzYWdlcy5TZW1hbnRpY0hpZ2hsaWdodGluZ19pbmhlcml0ZWRNZXRob2RJbnZvY2F0aW9uOwoJCX0KCgkJLyoKCQkgKiBAc2VlIG9yZy5lY2xpcHNlLmpkdC5pbnRlcm5hbC51aS5qYXZhZWRpdG9yLklTZW1hbnRpY0hpZ2hsaWdodGluZyNpc01hdGNoZWQob3JnLmVjbGlwc2UuamR0LmNvcmUuZG9tLkFTVE5vZGUpCgkJICovCgkJQE92ZXJyaWRlCgkJcHVibGljIGJvb2xlYW4gY29uc3VtZXMoU2VtYW50aWNUb2tlbiB0b2tlbikgewoJCQlTaW1wbGVOYW1lIG5vZGU9IHRva2VuLmdldE5vZGUoKTsKCQkJaWYgKG5vZGUuaXNEZWNsYXJhdGlvbigpKQoJCQkJcmV0dXJuIGZhbHNlOwoKCQkJSUJpbmRpbmcgYmluZGluZz0gdG9rZW4uZ2V0QmluZGluZygpOwoJCQlpZiAoYmluZGluZyA9PSBudWxsIHx8IGJpbmRpbmcuZ2V0S2luZCgpICE9IElCaW5kaW5nLk1FVEhPRCkKCQkJCXJldHVybiBmYWxzZTsKCgkJCUlUeXBlQmluZGluZyBjdXJyZW50VHlwZT0gQmluZGluZ3MuZ2V0QmluZGluZ09mUGFyZW50VHlwZShub2RlKTsKCQkJSVR5cGVCaW5kaW5nIGRlY2xhcmluZ1R5cGU9ICgoSU1ldGhvZEJpbmRpbmcpIGJpbmRpbmcpLmdldERlY2xhcmluZ0NsYXNzKCk7CgkJCWlmIChjdXJyZW50VHlwZSA9PSBkZWNsYXJpbmdUeXBlIHx8IGN1cnJlbnRUeXBlID09IG51bGwpCgkJCQlyZXR1cm4gZmFsc2U7CgoJCQlyZXR1cm4gQmluZGluZ3MuaXNTdXBlclR5cGUoZGVjbGFyaW5nVHlwZSwgY3VycmVudFR5cGUpOwoJCX0KCX0KCgkvKioKCSAqIFNlbWFudGljIGhpZ2hsaWdodGluZyBmb3IgaW5oZXJpdGVkIG1ldGhvZCBpbnZvY2F0aW9ucy4KCSAqLwoJcHJpdmF0ZSBzdGF0aWMgZmluYWwgY2xhc3MgTWV0aG9kSGlnaGxpZ2h0aW5nIGV4dGVuZHMgU2VtYW50aWNIaWdobGlnaHRpbmcgewoKCQkvKgoJCSAqIEBzZWUgb3JnLmVjbGlwc2UuamR0LmludGVybmFsLnVpLmphdmFlZGl0b3IuU2VtYW50aWNIaWdobGlnaHRpbmcjZ2V0UHJlZmVyZW5jZUtleSgpCgkJICovCgkJQE92ZXJyaWRlCgkJcHVibGljIFN0cmluZyBnZXRQcmVmZXJlbmNlS2V5KCkgewoJCQlyZXR1cm4gTUVUSE9EOwoJCX0KCgkJLyoKCQkgKiBAc2VlIG9yZy5lY2xpcHNlLmpkdC5pbnRlcm5hbC51aS5qYXZhZWRpdG9yLklTZW1hbnRpY0hpZ2hsaWdodGluZyNnZXREZWZhdWx0VGV4dENvbG9yKCkKCQkgKi8KCQlAT3ZlcnJpZGUKCQlwdWJsaWMgUkdCIGdldERlZmF1bHREZWZhdWx0VGV4dENvbG9yKCkgewoJCQlyZXR1cm4gbmV3IFJHQigwLCAwLCAwKTsKCQl9CgoJCS8qCgkJICogQHNlZSBvcmcuZWNsaXBzZS5qZHQuaW50ZXJuYWwudWkuamF2YWVkaXRvci5JU2VtYW50aWNIaWdobGlnaHRpbmcjZ2V0RGVmYXVsdFRleHRTdHlsZUJvbGQoKQoJCSAqLwoJCUBPdmVycmlkZQoJCXB1YmxpYyBib29sZWFuIGlzQm9sZEJ5RGVmYXVsdCgpIHsKCQkJcmV0dXJuIGZhbHNlOwoJCX0KCgkJLyoKCQkgKiBAc2VlIG9yZy5lY2xpcHNlLmpkdC5pbnRlcm5hbC51aS5qYXZhZWRpdG9yLlNlbWFudGljSGlnaGxpZ2h0aW5nI2lzSXRhbGljQnlEZWZhdWx0KCkKCQkgKi8KCQlAT3ZlcnJpZGUKCQlwdWJsaWMgYm9vbGVhbiBpc0l0YWxpY0J5RGVmYXVsdCgpIHsKCQkJcmV0dXJuIGZhbHNlOwoJCX0KCgkJLyoKCQkgKiBAc2VlIG9yZy5lY2xpcHNlLmpkdC5pbnRlcm5hbC51aS5qYXZhZWRpdG9yLlNlbWFudGljSGlnaGxpZ2h0aW5nI2lzRW5hYmxlZEJ5RGVmYXVsdCgpCgkJICovCgkJQE92ZXJyaWRlCgkJcHVibGljIGJvb2xlYW4gaXNFbmFibGVkQnlEZWZhdWx0KCkgewoJCQlyZXR1cm4gZmFsc2U7CgkJfQoKCQkvKgoJCSAqIEBzZWUgb3JnLmVjbGlwc2UuamR0LmludGVybmFsLnVpLmphdmFlZGl0b3IuSVNlbWFudGljSGlnaGxpZ2h0aW5nI2dldERpc3BsYXlOYW1lKCkKCQkgKi8KCQlAT3ZlcnJpZGUKCQlwdWJsaWMgU3RyaW5nIGdldERpc3BsYXlOYW1lKCkgewoJCQlyZXR1cm4gSmF2YUVkaXRvck1lc3NhZ2VzLlNlbWFudGljSGlnaGxpZ2h0aW5nX21ldGhvZDsKCQl9CgoJCS8qCgkJICogQHNlZSBvcmcuZWNsaXBzZS5qZHQuaW50ZXJuYWwudWkuamF2YWVkaXRvci5JU2VtYW50aWNIaWdobGlnaHRpbmcjaXNNYXRjaGVkKG9yZy5lY2xpcHNlLmpkdC5jb3JlLmRvbS5BU1ROb2RlKQoJCSAqLwoJCUBPdmVycmlkZQoJCXB1YmxpYyBib29sZWFuIGNvbnN1bWVzKFNlbWFudGljVG9rZW4gdG9rZW4pIHsKCQkJSUJpbmRpbmcgYmluZGluZz0gZ2V0TWV0aG9kQmluZGluZyh0b2tlbik7CgkJCXJldHVybiBiaW5kaW5nICE9IG51bGwgJiYgYmluZGluZy5nZXRLaW5kKCkgPT0gSUJpbmRpbmcuTUVUSE9EOwoJCX0KCgkJLyoqCgkJICogRXh0cmFjdHMgdGhlIG1ldGhvZCBiaW5kaW5nIGZyb20gdGhlIHRva2VuJ3Mgc2ltcGxlIG5hbWUuIFRoZSBtZXRob2QKCQkgKiBiaW5kaW5nIGlzIGVpdGhlciB0aGUgdG9rZW4ncyBiaW5kaW5nIChpZiB0aGUgcGFyZW50IG9mIHRva2VuIGlzIGEKCQkgKiBtZXRob2QgY2FsbCBvciBkZWNsYXJhdGlvbikgb3IgdGhlIGNvbnN0cnVjdG9yIGJpbmRpbmcgb2YgYSBjbGFzcwoJCSAqIGluc3RhbmNlIGNyZWF0aW9uIGlmIHRoZSBub2RlIGlzIHRoZSB0eXBlIG5hbWUgb2YgYSBjbGFzcyBpbnN0YW5jZQoJCSAqIGNyZWF0aW9uLgoJCSAqCgkJICogQHBhcmFtIHRva2VuIHRoZSB0b2tlbiB0byBleHRyYWN0IHRoZSBtZXRob2QgYmluZGluZyBmcm9tCgkJICogQHJldHVybiB0aGUgY29ycmVzcG9uZGluZyBtZXRob2QgYmluZGluZywgb3IgPGNvZGU+bnVsbDwvY29kZT4KCQkgKi8KCQlwcml2YXRlIElCaW5kaW5nIGdldE1ldGhvZEJpbmRpbmcoU2VtYW50aWNUb2tlbiB0b2tlbikgewoJCQlJQmluZGluZyBiaW5kaW5nPSBudWxsOwoJCQkvLyB3b3JrIGFyb3VuZDogaHR0cHM6Ly9idWdzLmVjbGlwc2Uub3JnL2J1Z3Mvc2hvd19idWcuY2dpP2lkPTYyNjA1CgkJCUFTVE5vZGUgbm9kZT0gdG9rZW4uZ2V0Tm9kZSgpOwoJCQlBU1ROb2RlIHBhcmVudD0gbm9kZS5nZXRQYXJlbnQoKTsKCQkJd2hpbGUgKGlzVHlwZVBhdGgobm9kZSwgcGFyZW50KSkgewoJCQkJbm9kZT0gcGFyZW50OwoJCQkJcGFyZW50PSBwYXJlbnQuZ2V0UGFyZW50KCk7CgkJCX0KCgkJCWlmIChwYXJlbnQgIT0gbnVsbCAmJiBub2RlLmdldExvY2F0aW9uSW5QYXJlbnQoKSA9PSBDbGFzc0luc3RhbmNlQ3JlYXRpb24uVFlQRV9QUk9QRVJUWSkKCQkJCWJpbmRpbmc9ICgoQ2xhc3NJbnN0YW5jZUNyZWF0aW9uKSBwYXJlbnQpLnJlc29sdmVDb25zdHJ1Y3RvckJpbmRpbmcoKTsKCQkJZWxzZQoJCQkJYmluZGluZz0gdG9rZW4uZ2V0QmluZGluZygpOwoJCQlyZXR1cm4gYmluZGluZzsKCQl9CgoJCS8qKgoJCSAqIFJldHVybnMgPGNvZGU+dHJ1ZTwvY29kZT4gaWYgdGhlIGdpdmVuIGNoaWxkL3BhcmVudCBub2RlcyBhcmUgdmFsaWQKCQkgKiBzdWIgbm9kZXMgb2YgYSA8Y29kZT5UeXBlPC9jb2RlPiBBU1ROb2RlLgoJCSAqIEBwYXJhbSBjaGlsZCB0aGUgY2hpbGQgbm9kZQoJCSAqIEBwYXJhbSBwYXJlbnQgdGhlIHBhcmVudCBub2RlCgkJICogQHJldHVybiA8Y29kZT50cnVlPC9jb2RlPiBpZiB0aGUgbm9kZXMgbWF5IGJlIHRoZSBzdWIgbm9kZXMgb2YgYSB0eXBlIG5vZGUsIGZhbHNlIG90aGVyd2lzZQoJCSAqLwoJCXByaXZhdGUgYm9vbGVhbiBpc1R5cGVQYXRoKEFTVE5vZGUgY2hpbGQsIEFTVE5vZGUgcGFyZW50KSB7CgkJCWlmIChwYXJlbnQgaW5zdGFuY2VvZiBUeXBlKSB7CgkJCQlTdHJ1Y3R1cmFsUHJvcGVydHlEZXNjcmlwdG9yIGxvY2F0aW9uPSBjaGlsZC5nZXRMb2NhdGlvbkluUGFyZW50KCk7CgkJCQlyZXR1cm4gbG9jYXRpb24gPT0gUGFyYW1ldGVyaXplZFR5cGUuVFlQRV9QUk9QRVJUWSB8fCBsb2NhdGlvbiA9PSBTaW1wbGVUeXBlLk5BTUVfUFJPUEVSVFk7CgkJCX0gZWxzZSBpZiAocGFyZW50IGluc3RhbmNlb2YgUXVhbGlmaWVkTmFtZSkgewoJCQkJU3RydWN0dXJhbFByb3BlcnR5RGVzY3JpcHRvciBsb2NhdGlvbj0gY2hpbGQuZ2V0TG9jYXRpb25JblBhcmVudCgpOwoJCQkJcmV0dXJuIGxvY2F0aW9uID09IFF1YWxpZmllZE5hbWUuTkFNRV9QUk9QRVJUWTsKCQkJfQoJCQlyZXR1cm4gZmFsc2U7CgkJfQoJfQoKCS8qKgoJICogU2VtYW50aWMgaGlnaGxpZ2h0aW5nIGZvciBsb2NhbCB2YXJpYWJsZSBkZWNsYXJhdGlvbnMuCgkgKi8KCXByaXZhdGUgc3RhdGljIGZpbmFsIGNsYXNzIExvY2FsVmFyaWFibGVEZWNsYXJhdGlvbkhpZ2hsaWdodGluZyBleHRlbmRzIFNlbWFudGljSGlnaGxpZ2h0aW5nIHsKCgkJLyoKCQkgKiBAc2VlIG9yZy5lY2xpcHNlLmpkdC5pbnRlcm5hbC51aS5qYXZhZWRpdG9yLlNlbWFudGljSGlnaGxpZ2h0aW5nI2dldFByZWZlcmVuY2VLZXkoKQoJCSAqLwoJCUBPdmVycmlkZQoJCXB1YmxpYyBTdHJpbmcgZ2V0UHJlZmVyZW5jZUtleSgpIHsKCQkJcmV0dXJuIExPQ0FMX1ZBUklBQkxFX0RFQ0xBUkFUSU9OOwoJCX0KCgkJLyoKCQkgKiBAc2VlIG9yZy5lY2xpcHNlLmpkdC5pbnRlcm5hbC51aS5qYXZhZWRpdG9yLklTZW1hbnRpY0hpZ2hsaWdodGluZyNnZXREZWZhdWx0VGV4dENvbG9yKCkKCQkgKi8KCQlAT3ZlcnJpZGUKCQlwdWJsaWMgUkdCIGdldERlZmF1bHREZWZhdWx0VGV4dENvbG9yKCkgewoJCQlyZXR1cm4gbmV3IFJHQigwLCAwLCAwKTsKCQl9CgoJCS8qCgkJICogQHNlZSBvcmcuZWNsaXBzZS5qZHQuaW50ZXJuYWwudWkuamF2YWVkaXRvci5JU2VtYW50aWNIaWdobGlnaHRpbmcjZ2V0RGVmYXVsdFRleHRTdHlsZUJvbGQoKQoJCSAqLwoJCUBPdmVycmlkZQoJCXB1YmxpYyBib29sZWFuIGlzQm9sZEJ5RGVmYXVsdCgpIHsKCQkJcmV0dXJuIGZhbHNlOwoJCX0KCgkJLyoKCQkgKiBAc2VlIG9yZy5lY2xpcHNlLmpkdC5pbnRlcm5hbC51aS5qYXZhZWRpdG9yLlNlbWFudGljSGlnaGxpZ2h0aW5nI2lzSXRhbGljQnlEZWZhdWx0KCkKCQkgKi8KCQlAT3ZlcnJpZGUKCQlwdWJsaWMgYm9vbGVhbiBpc0l0YWxpY0J5RGVmYXVsdCgpIHsKCQkJcmV0dXJuIGZhbHNlOwoJCX0KCgkJLyoKCQkgKiBAc2VlIG9yZy5lY2xpcHNlLmpkdC5pbnRlcm5hbC51aS5qYXZhZWRpdG9yLlNlbWFudGljSGlnaGxpZ2h0aW5nI2lzRW5hYmxlZEJ5RGVmYXVsdCgpCgkJICovCgkJQE92ZXJyaWRlCgkJcHVibGljIGJvb2xlYW4gaXNFbmFibGVkQnlEZWZhdWx0KCkgewoJCQlyZXR1cm4gZmFsc2U7CgkJfQoKCQkvKgoJCSAqIEBzZWUgb3JnLmVjbGlwc2UuamR0LmludGVybmFsLnVpLmphdmFlZGl0b3IuSVNlbWFudGljSGlnaGxpZ2h0aW5nI2dldERpc3BsYXlOYW1lKCkKCQkgKi8KCQlAT3ZlcnJpZGUKCQlwdWJsaWMgU3RyaW5nIGdldERpc3BsYXlOYW1lKCkgewoJCQlyZXR1cm4gSmF2YUVkaXRvck1lc3NhZ2VzLlNlbWFudGljSGlnaGxpZ2h0aW5nX2xvY2FsVmFyaWFibGVEZWNsYXJhdGlvbjsKCQl9CgoJCS8qCgkJICogQHNlZSBvcmcuZWNsaXBzZS5qZHQuaW50ZXJuYWwudWkuamF2YWVkaXRvci5TZW1hbnRpY0hpZ2hsaWdodGluZyNjb25zdW1lcyhvcmcuZWNsaXBzZS5qZHQuaW50ZXJuYWwudWkuamF2YWVkaXRvci5TZW1hbnRpY1Rva2VuKQoJCSAqLwoJCUBPdmVycmlkZQoJCXB1YmxpYyBib29sZWFuIGNvbnN1bWVzKFNlbWFudGljVG9rZW4gdG9rZW4pIHsKCQkJU2ltcGxlTmFtZSBub2RlPSB0b2tlbi5nZXROb2RlKCk7CgkJCVN0cnVjdHVyYWxQcm9wZXJ0eURlc2NyaXB0b3IgbG9jYXRpb249IG5vZGUuZ2V0TG9jYXRpb25JblBhcmVudCgpOwoJCQlpZiAobG9jYXRpb24gPT0gVmFyaWFibGVEZWNsYXJhdGlvbkZyYWdtZW50Lk5BTUVfUFJPUEVSVFkgfHwgbG9jYXRpb24gPT0gU2luZ2xlVmFyaWFibGVEZWNsYXJhdGlvbi5OQU1FX1BST1BFUlRZKSB7CgkJCQlBU1ROb2RlIHBhcmVudD0gbm9kZS5nZXRQYXJlbnQoKTsKCQkJCWlmIChwYXJlbnQgaW5zdGFuY2VvZiBWYXJpYWJsZURlY2xhcmF0aW9uKSB7CgkJCQkJcGFyZW50PSBwYXJlbnQuZ2V0UGFyZW50KCk7CgkJCQkJcmV0dXJuIHBhcmVudCA9PSBudWxsIHx8ICEocGFyZW50IGluc3RhbmNlb2YgRmllbGREZWNsYXJhdGlvbik7CgkJCQl9CgkJCX0KCQkJcmV0dXJuIGZhbHNlOwoJCX0KCX0KCgkvKioKCSAqIFNlbWFudGljIGhpZ2hsaWdodGluZyBmb3IgbG9jYWwgdmFyaWFibGVzLgoJICovCglwcml2YXRlIHN0YXRpYyBmaW5hbCBjbGFzcyBMb2NhbFZhcmlhYmxlSGlnaGxpZ2h0aW5nIGV4dGVuZHMgU2VtYW50aWNIaWdobGlnaHRpbmcgewoKCQkvKgoJCSAqIEBzZWUgb3JnLmVjbGlwc2UuamR0LmludGVybmFsLnVpLmphdmFlZGl0b3IuU2VtYW50aWNIaWdobGlnaHRpbmcjZ2V0UHJlZmVyZW5jZUtleSgpCgkJICovCgkJQE92ZXJyaWRlCgkJcHVibGljIFN0cmluZyBnZXRQcmVmZXJlbmNlS2V5KCkgewoJCQlyZXR1cm4gTE9DQUxfVkFSSUFCTEU7CgkJfQoKCQkvKgoJCSAqIEBzZWUgb3JnLmVjbGlwc2UuamR0LmludGVybmFsLnVpLmphdmFlZGl0b3IuSVNlbWFudGljSGlnaGxpZ2h0aW5nI2dldERlZmF1bHRUZXh0Q29sb3IoKQoJCSAqLwoJCUBPdmVycmlkZQoJCXB1YmxpYyBSR0IgZ2V0RGVmYXVsdERlZmF1bHRUZXh0Q29sb3IoKSB7CgkJCXJldHVybiBuZXcgUkdCKDAsIDAsIDApOwoJCX0KCgkJLyoKCQkgKiBAc2VlIG9yZy5lY2xpcHNlLmpkdC5pbnRlcm5hbC51aS5qYXZhZWRpdG9yLklTZW1hbnRpY0hpZ2hsaWdodGluZyNnZXREZWZhdWx0VGV4dFN0eWxlQm9sZCgpCgkJICovCgkJQE92ZXJyaWRlCgkJcHVibGljIGJvb2xlYW4gaXNCb2xkQnlEZWZhdWx0KCkgewoJCQlyZXR1cm4gZmFsc2U7CgkJfQoKCQkvKgoJCSAqIEBzZWUgb3JnLmVjbGlwc2UuamR0LmludGVybmFsLnVpLmphdmFlZGl0b3IuU2VtYW50aWNIaWdobGlnaHRpbmcjaXNJdGFsaWNCeURlZmF1bHQoKQoJCSAqLwoJCUBPdmVycmlkZQoJCXB1YmxpYyBib29sZWFuIGlzSXRhbGljQnlEZWZhdWx0KCkgewoJCQlyZXR1cm4gZmFsc2U7CgkJfQoKCQkvKgoJCSAqIEBzZWUgb3JnLmVjbGlwc2UuamR0LmludGVybmFsLnVpLmphdmFlZGl0b3IuU2VtYW50aWNIaWdobGlnaHRpbmcjaXNFbmFibGVkQnlEZWZhdWx0KCkKCQkgKi8KCQlAT3ZlcnJpZGUKCQlwdWJsaWMgYm9vbGVhbiBpc0VuYWJsZWRCeURlZmF1bHQoKSB7CgkJCXJldHVybiBmYWxzZTsKCQl9CgoJCS8qCgkJICogQHNlZSBvcmcuZWNsaXBzZS5qZHQuaW50ZXJuYWwudWkuamF2YWVkaXRvci5JU2VtYW50aWNIaWdobGlnaHRpbmcjZ2V0RGlzcGxheU5hbWUoKQoJCSAqLwoJCUBPdmVycmlkZQoJCXB1YmxpYyBTdHJpbmcgZ2V0RGlzcGxheU5hbWUoKSB7CgkJCXJldHVybiBKYXZhRWRpdG9yTWVzc2FnZXMuU2VtYW50aWNIaWdobGlnaHRpbmdfbG9jYWxWYXJpYWJsZTsKCQl9CgoJCS8qCgkJICogQHNlZSBvcmcuZWNsaXBzZS5qZHQuaW50ZXJuYWwudWkuamF2YWVkaXRvci5TZW1hbnRpY0hpZ2hsaWdodGluZyNjb25zdW1lcyhvcmcuZWNsaXBzZS5qZHQuaW50ZXJuYWwudWkuamF2YWVkaXRvci5TZW1hbnRpY1Rva2VuKQoJCSAqLwoJCUBPdmVycmlkZQoJCXB1YmxpYyBib29sZWFuIGNvbnN1bWVzKFNlbWFudGljVG9rZW4gdG9rZW4pIHsKCQkJSUJpbmRpbmcgYmluZGluZz0gdG9rZW4uZ2V0QmluZGluZygpOwoJCQlpZiAoYmluZGluZyAhPSBudWxsICYmIGJpbmRpbmcuZ2V0S2luZCgpID09IElCaW5kaW5nLlZBUklBQkxFICYmICEoKElWYXJpYWJsZUJpbmRpbmcpIGJpbmRpbmcpLmlzRmllbGQoKSkgewoJCQkJQVNUTm9kZSBkZWNsPSB0b2tlbi5nZXRSb290KCkuZmluZERlY2xhcmluZ05vZGUoYmluZGluZyk7CgkJCQlyZXR1cm4gZGVjbCBpbnN0YW5jZW9mIFZhcmlhYmxlRGVjbGFyYXRpb247CgkJCX0KCQkJcmV0dXJuIGZhbHNlOwoJCX0KCX0KCgkvKioKCSAqIFNlbWFudGljIGhpZ2hsaWdodGluZyBmb3IgcGFyYW1ldGVyIHZhcmlhYmxlcy4KCSAqLwoJcHJpdmF0ZSBzdGF0aWMgZmluYWwgY2xhc3MgUGFyYW1ldGVyVmFyaWFibGVIaWdobGlnaHRpbmcgZXh0ZW5kcyBTZW1hbnRpY0hpZ2hsaWdodGluZyB7CgoJCS8qCgkJICogQHNlZSBvcmcuZWNsaXBzZS5qZHQuaW50ZXJuYWwudWkuamF2YWVkaXRvci5TZW1hbnRpY0hpZ2hsaWdodGluZyNnZXRQcmVmZXJlbmNlS2V5KCkKCQkgKi8KCQlAT3ZlcnJpZGUKCQlwdWJsaWMgU3RyaW5nIGdldFByZWZlcmVuY2VLZXkoKSB7CgkJCXJldHVybiBQQVJBTUVURVJfVkFSSUFCTEU7CgkJfQoKCQkvKgoJCSAqIEBzZWUgb3JnLmVjbGlwc2UuamR0LmludGVybmFsLnVpLmphdmFlZGl0b3IuSVNlbWFudGljSGlnaGxpZ2h0aW5nI2dldERlZmF1bHRUZXh0Q29sb3IoKQoJCSAqLwoJCUBPdmVycmlkZQoJCXB1YmxpYyBSR0IgZ2V0RGVmYXVsdERlZmF1bHRUZXh0Q29sb3IoKSB7CgkJCXJldHVybiBuZXcgUkdCKDAsIDAsIDApOwoJCX0KCgkJLyoKCQkgKiBAc2VlIG9yZy5lY2xpcHNlLmpkdC5pbnRlcm5hbC51aS5qYXZhZWRpdG9yLklTZW1hbnRpY0hpZ2hsaWdodGluZyNnZXREZWZhdWx0VGV4dFN0eWxlQm9sZCgpCgkJICovCgkJQE92ZXJyaWRlCgkJcHVibGljIGJvb2xlYW4gaXNCb2xkQnlEZWZhdWx0KCkgewoJCQlyZXR1cm4gZmFsc2U7CgkJfQoKCQkvKgoJCSAqIEBzZWUgb3JnLmVjbGlwc2UuamR0LmludGVybmFsLnVpLmphdmFlZGl0b3IuU2VtYW50aWNIaWdobGlnaHRpbmcjaXNJdGFsaWNCeURlZmF1bHQoKQoJCSAqLwoJCUBPdmVycmlkZQoJCXB1YmxpYyBib29sZWFuIGlzSXRhbGljQnlEZWZhdWx0KCkgewoJCQlyZXR1cm4gZmFsc2U7CgkJfQoKCQkvKgoJCSAqIEBzZWUgb3JnLmVjbGlwc2UuamR0LmludGVybmFsLnVpLmphdmFlZGl0b3IuU2VtYW50aWNIaWdobGlnaHRpbmcjaXNFbmFibGVkQnlEZWZhdWx0KCkKCQkgKi8KCQlAT3ZlcnJpZGUKCQlwdWJsaWMgYm9vbGVhbiBpc0VuYWJsZWRCeURlZmF1bHQoKSB7CgkJCXJldHVybiBmYWxzZTsKCQl9CgoJCS8qCgkJICogQHNlZSBvcmcuZWNsaXBzZS5qZHQuaW50ZXJuYWwudWkuamF2YWVkaXRvci5JU2VtYW50aWNIaWdobGlnaHRpbmcjZ2V0RGlzcGxheU5hbWUoKQoJCSAqLwoJCUBPdmVycmlkZQoJCXB1YmxpYyBTdHJpbmcgZ2V0RGlzcGxheU5hbWUoKSB7CgkJCXJldHVybiBKYXZhRWRpdG9yTWVzc2FnZXMuU2VtYW50aWNIaWdobGlnaHRpbmdfcGFyYW1ldGVyVmFyaWFibGU7CgkJfQoKCQkvKgoJCSAqIEBzZWUgb3JnLmVjbGlwc2UuamR0LmludGVybmFsLnVpLmphdmFlZGl0b3IuU2VtYW50aWNIaWdobGlnaHRpbmcjY29uc3VtZXMob3JnLmVjbGlwc2UuamR0LmludGVybmFsLnVpLmphdmFlZGl0b3IuU2VtYW50aWNUb2tlbikKCQkgKi8KCQlAT3ZlcnJpZGUKCQlwdWJsaWMgYm9vbGVhbiBjb25zdW1lcyhTZW1hbnRpY1Rva2VuIHRva2VuKSB7CgkJCUlCaW5kaW5nIGJpbmRpbmc9IHRva2VuLmdldEJpbmRpbmcoKTsKCQkJaWYgKGJpbmRpbmcgIT0gbnVsbCAmJiBiaW5kaW5nLmdldEtpbmQoKSA9PSBJQmluZGluZy5WQVJJQUJMRSAmJiAhKChJVmFyaWFibGVCaW5kaW5nKSBiaW5kaW5nKS5pc0ZpZWxkKCkpIHsKCQkJCUFTVE5vZGUgZGVjbD0gdG9rZW4uZ2V0Um9vdCgpLmZpbmREZWNsYXJpbmdOb2RlKGJpbmRpbmcpOwoJCQkJcmV0dXJuIGRlY2wgIT0gbnVsbCAmJiBkZWNsLmdldExvY2F0aW9uSW5QYXJlbnQoKSA9PSBNZXRob2REZWNsYXJhdGlvbi5QQVJBTUVURVJTX1BST1BFUlRZOwoJCQl9CgkJCXJldHVybiBmYWxzZTsKCQl9Cgl9CgoJLyoqCgkgKiBTZW1hbnRpYyBoaWdobGlnaHRpbmcgZm9yIGRlcHJlY2F0ZWQgbWVtYmVycy4KCSAqLwoJc3RhdGljIGZpbmFsIGNsYXNzIERlcHJlY2F0ZWRNZW1iZXJIaWdobGlnaHRpbmcgZXh0ZW5kcyBTZW1hbnRpY0hpZ2hsaWdodGluZyB7CgoJCS8qCgkJICogQHNlZSBvcmcuZWNsaXBzZS5qZHQuaW50ZXJuYWwudWkuamF2YWVkaXRvci5TZW1hbnRpY0hpZ2hsaWdodGluZyNnZXRQcmVmZXJlbmNlS2V5KCkKCQkgKi8KCQlAT3ZlcnJpZGUKCQlwdWJsaWMgU3RyaW5nIGdldFByZWZlcmVuY2VLZXkoKSB7CgkJCXJldHVybiBERVBSRUNBVEVEX01FTUJFUjsKCQl9CgoJCS8qCgkJICogQHNlZSBvcmcuZWNsaXBzZS5qZHQuaW50ZXJuYWwudWkuamF2YWVkaXRvci5JU2VtYW50aWNIaWdobGlnaHRpbmcjZ2V0RGVmYXVsdFRleHRDb2xvcigpCgkJICovCgkJQE92ZXJyaWRlCgkJcHVibGljIFJHQiBnZXREZWZhdWx0RGVmYXVsdFRleHRDb2xvcigpIHsKCQkJcmV0dXJuIG5ldyBSR0IoMCwgMCwgMCk7CgkJfQoKCQkvKgoJCSAqIEBzZWUgb3JnLmVjbGlwc2UuamR0LmludGVybmFsLnVpLmphdmFlZGl0b3IuSVNlbWFudGljSGlnaGxpZ2h0aW5nI2dldERlZmF1bHRUZXh0U3R5bGVCb2xkKCkKCQkgKi8KCQlAT3ZlcnJpZGUKCQlwdWJsaWMgYm9vbGVhbiBpc0JvbGRCeURlZmF1bHQoKSB7CgkJCXJldHVybiBmYWxzZTsKCQl9CgoJCS8qCgkJICogQHNlZSBvcmcuZWNsaXBzZS5qZHQuaW50ZXJuYWwudWkuamF2YWVkaXRvci5TZW1hbnRpY0hpZ2hsaWdodGluZyNpc0l0YWxpY0J5RGVmYXVsdCgpCgkJICovCgkJQE92ZXJyaWRlCgkJcHVibGljIGJvb2xlYW4gaXNJdGFsaWNCeURlZmF1bHQoKSB7CgkJCXJldHVybiBmYWxzZTsKCQl9CgoJCS8qCgkJICogQHNlZSBvcmcuZWNsaXBzZS5qZHQuaW50ZXJuYWwudWkuamF2YWVkaXRvci5TZW1hbnRpY0hpZ2hsaWdodGluZyNpc1N0cmlrZXRocm91Z2hCeURlZmF1bHQoKQoJCSAqIEBzaW5jZSAzLjEKCQkgKi8KCQlAT3ZlcnJpZGUKCQlwdWJsaWMgYm9vbGVhbiBpc1N0cmlrZXRocm91Z2hCeURlZmF1bHQoKSB7CgkJCXJldHVybiB0cnVlOwoJCX0KCgkJLyoKCQkgKiBAc2VlIG9yZy5lY2xpcHNlLmpkdC5pbnRlcm5hbC51aS5qYXZhZWRpdG9yLlNlbWFudGljSGlnaGxpZ2h0aW5nI2lzRW5hYmxlZEJ5RGVmYXVsdCgpCgkJICovCgkJQE92ZXJyaWRlCgkJcHVibGljIGJvb2xlYW4gaXNFbmFibGVkQnlEZWZhdWx0KCkgewoJCQlyZXR1cm4gdHJ1ZTsKCQl9CgoJCS8qCgkJICogQHNlZSBvcmcuZWNsaXBzZS5qZHQuaW50ZXJuYWwudWkuamF2YWVkaXRvci5JU2VtYW50aWNIaWdobGlnaHRpbmcjZ2V0RGlzcGxheU5hbWUoKQoJCSAqLwoJCUBPdmVycmlkZQoJCXB1YmxpYyBTdHJpbmcgZ2V0RGlzcGxheU5hbWUoKSB7CgkJCXJldHVybiBKYXZhRWRpdG9yTWVzc2FnZXMuU2VtYW50aWNIaWdobGlnaHRpbmdfZGVwcmVjYXRlZE1lbWJlcjsKCQl9CgoJCS8qCgkJICogQHNlZSBvcmcuZWNsaXBzZS5qZHQuaW50ZXJuYWwudWkuamF2YWVkaXRvci5TZW1hbnRpY0hpZ2hsaWdodGluZyNjb25zdW1lcyhvcmcuZWNsaXBzZS5qZHQuaW50ZXJuYWwudWkuamF2YWVkaXRvci5TZW1hbnRpY1Rva2VuKQoJCSAqLwoJCUBPdmVycmlkZQoJCXB1YmxpYyBib29sZWFuIGNvbnN1bWVzKFNlbWFudGljVG9rZW4gdG9rZW4pIHsKCQkJSUJpbmRpbmcgYmluZGluZz0gZ2V0TWV0aG9kQmluZGluZyh0b2tlbik7CgkJCWlmIChiaW5kaW5nICE9IG51bGwpIHsKCQkJCWlmIChiaW5kaW5nLmlzRGVwcmVjYXRlZCgpKQoJCQkJCXJldHVybiB0cnVlOwoJCQkJaWYgKGJpbmRpbmcgaW5zdGFuY2VvZiBJTWV0aG9kQmluZGluZykgewoJCQkJCUlNZXRob2RCaW5kaW5nIG1ldGhvZEJpbmRpbmc9IChJTWV0aG9kQmluZGluZykgYmluZGluZzsKCQkJCQlpZiAobWV0aG9kQmluZGluZy5pc0NvbnN0cnVjdG9yKCkgJiYgbWV0aG9kQmluZGluZy5nZXRKYXZhRWxlbWVudCgpID09IG51bGwpIHsKCQkJCQkJSVR5cGVCaW5kaW5nIGRlY2xhcmluZ0NsYXNzPSBtZXRob2RCaW5kaW5nLmdldERlY2xhcmluZ0NsYXNzKCk7CgkJCQkJCWlmIChkZWNsYXJpbmdDbGFzcy5pc0Fub255bW91cygpKSB7CgkJCQkJCQlJVHlwZUJpbmRpbmdbXSBpbnRlcmZhY2VzPSBkZWNsYXJpbmdDbGFzcy5nZXRJbnRlcmZhY2VzKCk7CgkJCQkJCQlpZiAoaW50ZXJmYWNlcy5sZW5ndGggPiAwKQoJCQkJCQkJCXJldHVybiBpbnRlcmZhY2VzWzBdLmlzRGVwcmVjYXRlZCgpOwoJCQkJCQkJZWxzZQoJCQkJCQkJCXJldHVybiBkZWNsYXJpbmdDbGFzcy5nZXRTdXBlcmNsYXNzKCkuaXNEZXByZWNhdGVkKCk7CgkJCQkJCX0KCQkJCQkJcmV0dXJuIGRlY2xhcmluZ0NsYXNzLmlzRGVwcmVjYXRlZCgpOwoJCQkJCX0KCQkJCX0KCQkJfQoJCQlyZXR1cm4gZmFsc2U7CgkJfQoKCQkvKioKCQkgKiBFeHRyYWN0cyB0aGUgbWV0aG9kIGJpbmRpbmcgZnJvbSB0aGUgdG9rZW4ncyBzaW1wbGUgbmFtZS4gVGhlIG1ldGhvZAoJCSAqIGJpbmRpbmcgaXMgZWl0aGVyIHRoZSB0b2tlbidzIGJpbmRpbmcgKGlmIHRoZSBwYXJlbnQgb2YgdG9rZW4gaXMgYQoJCSAqIG1ldGhvZCBjYWxsIG9yIGRlY2xhcmF0aW9uKSBvciB0aGUgY29uc3RydWN0b3IgYmluZGluZyBvZiBhIGNsYXNzCgkJICogaW5zdGFuY2UgY3JlYXRpb24gaWYgdGhlIG5vZGUgaXMgdGhlIHR5cGUgbmFtZSBvZiBhIGNsYXNzIGluc3RhbmNlCgkJICogY3JlYXRpb24uCgkJICoKCQkgKiBAcGFyYW0gdG9rZW4gdGhlIHRva2VuIHRvIGV4dHJhY3QgdGhlIG1ldGhvZCBiaW5kaW5nIGZyb20KCQkgKiBAcmV0dXJuIHRoZSBjb3JyZXNwb25kaW5nIG1ldGhvZCBiaW5kaW5nLCBvciA8Y29kZT5udWxsPC9jb2RlPgoJCSAqLwoJCXByaXZhdGUgSUJpbmRpbmcgZ2V0TWV0aG9kQmluZGluZyhTZW1hbnRpY1Rva2VuIHRva2VuKSB7CgkJCUlCaW5kaW5nIGJpbmRpbmc9IG51bGw7CgkJCS8vIHdvcmsgYXJvdW5kOiBodHRwczovL2J1Z3MuZWNsaXBzZS5vcmcvYnVncy9zaG93X2J1Zy5jZ2k/aWQ9NjI2MDUKCQkJQVNUTm9kZSBub2RlPSB0b2tlbi5nZXROb2RlKCk7CgkJCUFTVE5vZGUgcGFyZW50PSBub2RlLmdldFBhcmVudCgpOwoJCQl3aGlsZSAoaXNUeXBlUGF0aChub2RlLCBwYXJlbnQpKSB7CgkJCQlub2RlPSBwYXJlbnQ7CgkJCQlwYXJlbnQ9IHBhcmVudC5nZXRQYXJlbnQoKTsKCQkJfQoKCQkJaWYgKHBhcmVudCAhPSBudWxsICYmIG5vZGUuZ2V0TG9jYXRpb25JblBhcmVudCgpID09IENsYXNzSW5zdGFuY2VDcmVhdGlvbi5UWVBFX1BST1BFUlRZKQoJCQkJYmluZGluZz0gKChDbGFzc0luc3RhbmNlQ3JlYXRpb24pIHBhcmVudCkucmVzb2x2ZUNvbnN0cnVjdG9yQmluZGluZygpOwoJCQllbHNlCgkJCQliaW5kaW5nPSB0b2tlbi5nZXRCaW5kaW5nKCk7CgkJCXJldHVybiBiaW5kaW5nOwoJCX0KCgkJLyoqCgkJICogUmV0dXJucyA8Y29kZT50cnVlPC9jb2RlPiBpZiB0aGUgZ2l2ZW4gY2hpbGQvcGFyZW50IG5vZGVzIGFyZSB2YWxpZAoJCSAqIHN1YiBub2RlcyBvZiBhIDxjb2RlPlR5cGU8L2NvZGU+IEFTVE5vZGUuCgkJICogQHBhcmFtIGNoaWxkIHRoZSBjaGlsZCBub2RlCgkJICogQHBhcmFtIHBhcmVudCB0aGUgcGFyZW50IG5vZGUKCQkgKiBAcmV0dXJuIDxjb2RlPnRydWU8L2NvZGU+IGlmIHRoZSBub2RlcyBtYXkgYmUgdGhlIHN1YiBub2RlcyBvZiBhIHR5cGUgbm9kZSwgZmFsc2Ugb3RoZXJ3aXNlCgkJICovCgkJcHJpdmF0ZSBib29sZWFuIGlzVHlwZVBhdGgoQVNUTm9kZSBjaGlsZCwgQVNUTm9kZSBwYXJlbnQpIHsKCQkJaWYgKHBhcmVudCBpbnN0YW5jZW9mIFR5cGUpIHsKCQkJCVN0cnVjdHVyYWxQcm9wZXJ0eURlc2NyaXB0b3IgbG9jYXRpb249IGNoaWxkLmdldExvY2F0aW9uSW5QYXJlbnQoKTsKCQkJCXJldHVybiBsb2NhdGlvbiA9PSBQYXJhbWV0ZXJpemVkVHlwZS5UWVBFX1BST1BFUlRZIHx8IGxvY2F0aW9uID09IFNpbXBsZVR5cGUuTkFNRV9QUk9QRVJUWTsKCQkJfSBlbHNlIGlmIChwYXJlbnQgaW5zdGFuY2VvZiBRdWFsaWZpZWROYW1lKSB7CgkJCQlTdHJ1Y3R1cmFsUHJvcGVydHlEZXNjcmlwdG9yIGxvY2F0aW9uPSBjaGlsZC5nZXRMb2NhdGlvbkluUGFyZW50KCk7CgkJCQlyZXR1cm4gbG9jYXRpb24gPT0gUXVhbGlmaWVkTmFtZS5OQU1FX1BST1BFUlRZOwoJCQl9CgkJCXJldHVybiBmYWxzZTsKCQl9Cgl9CgoJLyoqCgkgKiBTZW1hbnRpYyBoaWdobGlnaHRpbmcgZm9yIHR5cGUgdmFyaWFibGVzLgoJICogQHNpbmNlIDMuMQoJICovCglwcml2YXRlIHN0YXRpYyBmaW5hbCBjbGFzcyBUeXBlVmFyaWFibGVIaWdobGlnaHRpbmcgZXh0ZW5kcyBTZW1hbnRpY0hpZ2hsaWdodGluZyB7CgoJCS8qCgkJICogQHNlZSBvcmcuZWNsaXBzZS5qZHQuaW50ZXJuYWwudWkuamF2YWVkaXRvci5TZW1hbnRpY0hpZ2hsaWdodGluZyNnZXRQcmVmZXJlbmNlS2V5KCkKCQkgKi8KCQlAT3ZlcnJpZGUKCQlwdWJsaWMgU3RyaW5nIGdldFByZWZlcmVuY2VLZXkoKSB7CgkJCXJldHVybiBUWVBFX1ZBUklBQkxFOwoJCX0KCgkJLyoKCQkgKiBAc2VlIG9yZy5lY2xpcHNlLmpkdC5pbnRlcm5hbC51aS5qYXZhZWRpdG9yLklTZW1hbnRpY0hpZ2hsaWdodGluZyNnZXREZWZhdWx0VGV4dENvbG9yKCkKCQkgKi8KCQlAT3ZlcnJpZGUKCQlwdWJsaWMgUkdCIGdldERlZmF1bHREZWZhdWx0VGV4dENvbG9yKCkgewoJCQlyZXR1cm4gbmV3IFJHQigxMDAsIDcwLCA1MCk7CgkJfQoKCQkvKgoJCSAqIEBzZWUgb3JnLmVjbGlwc2UuamR0LmludGVybmFsLnVpLmphdmFlZGl0b3IuSVNlbWFudGljSGlnaGxpZ2h0aW5nI2dldERlZmF1bHRUZXh0U3R5bGVCb2xkKCkKCQkgKi8KCQlAT3ZlcnJpZGUKCQlwdWJsaWMgYm9vbGVhbiBpc0JvbGRCeURlZmF1bHQoKSB7CgkJCXJldHVybiB0cnVlOwoJCX0KCgkJLyoKCQkgKiBAc2VlIG9yZy5lY2xpcHNlLmpkdC5pbnRlcm5hbC51aS5qYXZhZWRpdG9yLlNlbWFudGljSGlnaGxpZ2h0aW5nI2lzSXRhbGljQnlEZWZhdWx0KCkKCQkgKi8KCQlAT3ZlcnJpZGUKCQlwdWJsaWMgYm9vbGVhbiBpc0l0YWxpY0J5RGVmYXVsdCgpIHsKCQkJcmV0dXJuIGZhbHNlOwoJCX0KCgkJLyoKCQkgKiBAc2VlIG9yZy5lY2xpcHNlLmpkdC5pbnRlcm5hbC51aS5qYXZhZWRpdG9yLlNlbWFudGljSGlnaGxpZ2h0aW5nI2lzRW5hYmxlZEJ5RGVmYXVsdCgpCgkJICovCgkJQE92ZXJyaWRlCgkJcHVibGljIGJvb2xlYW4gaXNFbmFibGVkQnlEZWZhdWx0KCkgewoJCQlyZXR1cm4gZmFsc2U7CgkJfQoKCQkvKgoJCSAqIEBzZWUgb3JnLmVjbGlwc2UuamR0LmludGVybmFsLnVpLmphdmFlZGl0b3IuSVNlbWFudGljSGlnaGxpZ2h0aW5nI2dldERpc3BsYXlOYW1lKCkKCQkgKi8KCQlAT3ZlcnJpZGUKCQlwdWJsaWMgU3RyaW5nIGdldERpc3BsYXlOYW1lKCkgewoJCQlyZXR1cm4gSmF2YUVkaXRvck1lc3NhZ2VzLlNlbWFudGljSGlnaGxpZ2h0aW5nX3R5cGVWYXJpYWJsZXM7CgkJfQoKCQkvKgoJCSAqIEBzZWUgb3JnLmVjbGlwc2UuamR0LmludGVybmFsLnVpLmphdmFlZGl0b3IuU2VtYW50aWNIaWdobGlnaHRpbmcjY29uc3VtZXMob3JnLmVjbGlwc2UuamR0LmludGVybmFsLnVpLmphdmFlZGl0b3IuU2VtYW50aWNUb2tlbikKCQkgKi8KCQlAT3ZlcnJpZGUKCQlwdWJsaWMgYm9vbGVhbiBjb25zdW1lcyhTZW1hbnRpY1Rva2VuIHRva2VuKSB7CgoJCQkvLyAxOiBtYXRjaCB0eXBlcyBpbiB0eXBlIHBhcmFtZXRlciBsaXN0cwoJCQlTaW1wbGVOYW1lIG5hbWU9IHRva2VuLmdldE5vZGUoKTsKCQkJQVNUTm9kZSBub2RlPSBuYW1lLmdldFBhcmVudCgpOwoJCQlpZiAobm9kZS5nZXROb2RlVHlwZSgpICE9IEFTVE5vZGUuU0lNUExFX1RZUEUgJiYgbm9kZS5nZXROb2RlVHlwZSgpICE9IEFTVE5vZGUuVFlQRV9QQVJBTUVURVIpCgkJCQlyZXR1cm4gZmFsc2U7CgoJCQkvLyAyOiBtYXRjaCBnZW5lcmljIHR5cGUgdmFyaWFibGUgcmVmZXJlbmNlcwoJCQlJQmluZGluZyBiaW5kaW5nPSB0b2tlbi5nZXRCaW5kaW5nKCk7CgkJCXJldHVybiBiaW5kaW5nIGluc3RhbmNlb2YgSVR5cGVCaW5kaW5nICYmICgoSVR5cGVCaW5kaW5nKSBiaW5kaW5nKS5pc1R5cGVWYXJpYWJsZSgpOwoJCX0KCX0KCgkvKioKCSAqIFNlbWFudGljIGhpZ2hsaWdodGluZyBmb3IgY2xhc3Nlcy4KCSAqIEBzaW5jZSAzLjIKCSAqLwoJcHJpdmF0ZSBzdGF0aWMgZmluYWwgY2xhc3MgQ2xhc3NIaWdobGlnaHRpbmcgZXh0ZW5kcyBTZW1hbnRpY0hpZ2hsaWdodGluZyB7CgoJCS8qCgkJICogQHNlZSBvcmcuZWNsaXBzZS5qZHQuaW50ZXJuYWwudWkuamF2YWVkaXRvci5TZW1hbnRpY0hpZ2hsaWdodGluZyNnZXRQcmVmZXJlbmNlS2V5KCkKCQkgKi8KCQlAT3ZlcnJpZGUKCQlwdWJsaWMgU3RyaW5nIGdldFByZWZlcmVuY2VLZXkoKSB7CgkJCXJldHVybiBDTEFTUzsKCQl9CgoJCS8qCgkJICogQHNlZSBvcmcuZWNsaXBzZS5qZHQuaW50ZXJuYWwudWkuamF2YWVkaXRvci5JU2VtYW50aWNIaWdobGlnaHRpbmcjZ2V0RGVmYXVsdFRleHRDb2xvcigpCgkJICovCgkJQE92ZXJyaWRlCgkJcHVibGljIFJHQiBnZXREZWZhdWx0RGVmYXVsdFRleHRDb2xvcigpIHsKCQkJcmV0dXJuIG5ldyBSR0IoMCwgODAsIDUwKTsKCQl9CgoJCS8qCgkJICogQHNlZSBvcmcuZWNsaXBzZS5qZHQuaW50ZXJuYWwudWkuamF2YWVkaXRvci5JU2VtYW50aWNIaWdobGlnaHRpbmcjZ2V0RGVmYXVsdFRleHRTdHlsZUJvbGQoKQoJCSAqLwoJCUBPdmVycmlkZQoJCXB1YmxpYyBib29sZWFuIGlzQm9sZEJ5RGVmYXVsdCgpIHsKCQkJcmV0dXJuIGZhbHNlOwoJCX0KCgkJLyoKCQkgKiBAc2VlIG9yZy5lY2xpcHNlLmpkdC5pbnRlcm5hbC51aS5qYXZhZWRpdG9yLlNlbWFudGljSGlnaGxpZ2h0aW5nI2lzSXRhbGljQnlEZWZhdWx0KCkKCQkgKi8KCQlAT3ZlcnJpZGUKCQlwdWJsaWMgYm9vbGVhbiBpc0l0YWxpY0J5RGVmYXVsdCgpIHsKCQkJcmV0dXJuIGZhbHNlOwoJCX0KCgkJLyoKCQkgKiBAc2VlIG9yZy5lY2xpcHNlLmpkdC5pbnRlcm5hbC51aS5qYXZhZWRpdG9yLlNlbWFudGljSGlnaGxpZ2h0aW5nI2lzRW5hYmxlZEJ5RGVmYXVsdCgpCgkJICovCgkJQE92ZXJyaWRlCgkJcHVibGljIGJvb2xlYW4gaXNFbmFibGVkQnlEZWZhdWx0KCkgewoJCQlyZXR1cm4gZmFsc2U7CgkJfQoKCQkvKgoJCSAqIEBzZWUgb3JnLmVjbGlwc2UuamR0LmludGVybmFsLnVpLmphdmFlZGl0b3IuSVNlbWFudGljSGlnaGxpZ2h0aW5nI2dldERpc3BsYXlOYW1lKCkKCQkgKi8KCQlAT3ZlcnJpZGUKCQlwdWJsaWMgU3RyaW5nIGdldERpc3BsYXlOYW1lKCkgewoJCQlyZXR1cm4gSmF2YUVkaXRvck1lc3NhZ2VzLlNlbWFudGljSGlnaGxpZ2h0aW5nX2NsYXNzZXM7CgkJfQoKCQkvKgoJCSAqIEBzZWUgb3JnLmVjbGlwc2UuamR0LmludGVybmFsLnVpLmphdmFlZGl0b3IuU2VtYW50aWNIaWdobGlnaHRpbmcjY29uc3VtZXMob3JnLmVjbGlwc2UuamR0LmludGVybmFsLnVpLmphdmFlZGl0b3IuU2VtYW50aWNUb2tlbikKCQkgKi8KCQlAT3ZlcnJpZGUKCQlwdWJsaWMgYm9vbGVhbiBjb25zdW1lcyhTZW1hbnRpY1Rva2VuIHRva2VuKSB7CgoJCQkvLyAxOiBtYXRjaCB0eXBlcwoJCQlTaW1wbGVOYW1lIG5hbWU9IHRva2VuLmdldE5vZGUoKTsKCQkJQVNUTm9kZSBub2RlPSBuYW1lLmdldFBhcmVudCgpOwoJCQlpbnQgbm9kZVR5cGU9IG5vZGUuZ2V0Tm9kZVR5cGUoKTsKCQkJaWYgKG5vZGVUeXBlICE9IEFTVE5vZGUuU0lNUExFX1RZUEUgJiYgbm9kZVR5cGUgIT0gQVNUTm9kZS5USElTX0VYUFJFU1NJT04gJiYgbm9kZVR5cGUgIT0gQVNUTm9kZS5RVUFMSUZJRURfVFlQRSAgJiYgbm9kZVR5cGUgIT0gQVNUTm9kZS5RVUFMSUZJRURfTkFNRSAmJiBub2RlVHlwZSAhPSBBU1ROb2RlLlRZUEVfREVDTEFSQVRJT04gJiYgbm9kZVR5cGUgIT0gQVNUTm9kZS5NRVRIT0RfSU5WT0NBVElPTikKCQkJCXJldHVybiBmYWxzZTsKCQkJd2hpbGUgKG5vZGVUeXBlID09IEFTVE5vZGUuUVVBTElGSUVEX05BTUUpIHsKCQkJCW5vZGU9IG5vZGUuZ2V0UGFyZW50KCk7CgkJCQlub2RlVHlwZT0gbm9kZS5nZXROb2RlVHlwZSgpOwoJCQkJaWYgKG5vZGVUeXBlID09IEFTVE5vZGUuSU1QT1JUX0RFQ0xBUkFUSU9OKQoJCQkJCXJldHVybiBmYWxzZTsKCQkJfQoKCQkJLy8gMjogbWF0Y2ggY2xhc3NlcwoJCQlJQmluZGluZyBiaW5kaW5nPSB0b2tlbi5nZXRCaW5kaW5nKCk7CgkJCXJldHVybiBiaW5kaW5nIGluc3RhbmNlb2YgSVR5cGVCaW5kaW5nICYmICgoSVR5cGVCaW5kaW5nKSBiaW5kaW5nKS5pc0NsYXNzKCk7CgkJfQoJfQoKCS8qKgoJICogU2VtYW50aWMgaGlnaGxpZ2h0aW5nIGZvciBlbnVtcy4KCSAqIEBzaW5jZSAzLjIKCSAqLwoJcHJpdmF0ZSBzdGF0aWMgZmluYWwgY2xhc3MgRW51bUhpZ2hsaWdodGluZyBleHRlbmRzIFNlbWFudGljSGlnaGxpZ2h0aW5nIHsKCgkJLyoKCQkgKiBAc2VlIG9yZy5lY2xpcHNlLmpkdC5pbnRlcm5hbC51aS5qYXZhZWRpdG9yLlNlbWFudGljSGlnaGxpZ2h0aW5nI2dldFByZWZlcmVuY2VLZXkoKQoJCSAqLwoJCUBPdmVycmlkZQoJCXB1YmxpYyBTdHJpbmcgZ2V0UHJlZmVyZW5jZUtleSgpIHsKCQkJcmV0dXJuIEVOVU07CgkJfQoKCQkvKgoJCSAqIEBzZWUgb3JnLmVjbGlwc2UuamR0LmludGVybmFsLnVpLmphdmFlZGl0b3IuSVNlbWFudGljSGlnaGxpZ2h0aW5nI2dldERlZmF1bHRUZXh0Q29sb3IoKQoJCSAqLwoJCUBPdmVycmlkZQoJCXB1YmxpYyBSR0IgZ2V0RGVmYXVsdERlZmF1bHRUZXh0Q29sb3IoKSB7CgkJCXJldHVybiBuZXcgUkdCKDEwMCwgNzAsIDUwKTsKCQl9CgoJCS8qCgkJICogQHNlZSBvcmcuZWNsaXBzZS5qZHQuaW50ZXJuYWwudWkuamF2YWVkaXRvci5JU2VtYW50aWNIaWdobGlnaHRpbmcjZ2V0RGVmYXVsdFRleHRTdHlsZUJvbGQoKQoJCSAqLwoJCUBPdmVycmlkZQoJCXB1YmxpYyBib29sZWFuIGlzQm9sZEJ5RGVmYXVsdCgpIHsKCQkJcmV0dXJuIGZhbHNlOwoJCX0KCgkJLyoKCQkgKiBAc2VlIG9yZy5lY2xpcHNlLmpkdC5pbnRlcm5hbC51aS5qYXZhZWRpdG9yLlNlbWFudGljSGlnaGxpZ2h0aW5nI2lzSXRhbGljQnlEZWZhdWx0KCkKCQkgKi8KCQlAT3ZlcnJpZGUKCQlwdWJsaWMgYm9vbGVhbiBpc0l0YWxpY0J5RGVmYXVsdCgpIHsKCQkJcmV0dXJuIGZhbHNlOwoJCX0KCgkJLyoKCQkgKiBAc2VlIG9yZy5lY2xpcHNlLmpkdC5pbnRlcm5hbC51aS5qYXZhZWRpdG9yLlNlbWFudGljSGlnaGxpZ2h0aW5nI2lzRW5hYmxlZEJ5RGVmYXVsdCgpCgkJICovCgkJQE92ZXJyaWRlCgkJcHVibGljIGJvb2xlYW4gaXNFbmFibGVkQnlEZWZhdWx0KCkgewoJCQlyZXR1cm4gZmFsc2U7CgkJfQoKCQkvKgoJCSAqIEBzZWUgb3JnLmVjbGlwc2UuamR0LmludGVybmFsLnVpLmphdmFlZGl0b3IuSVNlbWFudGljSGlnaGxpZ2h0aW5nI2dldERpc3BsYXlOYW1lKCkKCQkgKi8KCQlAT3ZlcnJpZGUKCQlwdWJsaWMgU3RyaW5nIGdldERpc3BsYXlOYW1lKCkgewoJCQlyZXR1cm4gSmF2YUVkaXRvck1lc3NhZ2VzLlNlbWFudGljSGlnaGxpZ2h0aW5nX2VudW1zOwoJCX0KCgkJLyoKCQkgKiBAc2VlIG9yZy5lY2xpcHNlLmpkdC5pbnRlcm5hbC51aS5qYXZhZWRpdG9yLlNlbWFudGljSGlnaGxpZ2h0aW5nI2NvbnN1bWVzKG9yZy5lY2xpcHNlLmpkdC5pbnRlcm5hbC51aS5qYXZhZWRpdG9yLlNlbWFudGljVG9rZW4pCgkJICovCgkJQE92ZXJyaWRlCgkJcHVibGljIGJvb2xlYW4gY29uc3VtZXMoU2VtYW50aWNUb2tlbiB0b2tlbikgewoKCQkJLy8gMTogbWF0Y2ggdHlwZXMKCQkJU2ltcGxlTmFtZSBuYW1lPSB0b2tlbi5nZXROb2RlKCk7CgkJCUFTVE5vZGUgbm9kZT0gbmFtZS5nZXRQYXJlbnQoKTsKCQkJaW50IG5vZGVUeXBlPSBub2RlLmdldE5vZGVUeXBlKCk7CgkJCWlmIChub2RlVHlwZSAhPSBBU1ROb2RlLk1FVEhPRF9JTlZPQ0FUSU9OICYmIG5vZGVUeXBlICE9IEFTVE5vZGUuU0lNUExFX1RZUEUgJiYgbm9kZVR5cGUgIT0gQVNUTm9kZS5RVUFMSUZJRURfVFlQRSAmJiBub2RlVHlwZSAhPSBBU1ROb2RlLlFVQUxJRklFRF9OQU1FCgkJCQkJJiYgbm9kZVR5cGUgIT0gQVNUTm9kZS5RVUFMSUZJRURfTkFNRSAmJiBub2RlVHlwZSAhPSBBU1ROb2RlLkVOVU1fREVDTEFSQVRJT04pCgkJCQlyZXR1cm4gZmFsc2U7CgkJCXdoaWxlIChub2RlVHlwZSA9PSBBU1ROb2RlLlFVQUxJRklFRF9OQU1FKSB7CgkJCQlub2RlPSBub2RlLmdldFBhcmVudCgpOwoJCQkJbm9kZVR5cGU9IG5vZGUuZ2V0Tm9kZVR5cGUoKTsKCQkJCWlmIChub2RlVHlwZSA9PSBBU1ROb2RlLklNUE9SVF9ERUNMQVJBVElPTikKCQkJCQlyZXR1cm4gZmFsc2U7CgkJCX0KCgkJCS8vIDI6IG1hdGNoIGVudW1zCgkJCUlCaW5kaW5nIGJpbmRpbmc9IHRva2VuLmdldEJpbmRpbmcoKTsKCQkJcmV0dXJuIGJpbmRpbmcgaW5zdGFuY2VvZiBJVHlwZUJpbmRpbmcgJiYgKChJVHlwZUJpbmRpbmcpIGJpbmRpbmcpLmlzRW51bSgpOwoJCX0KCX0KCgkvKioKCSAqIFNlbWFudGljIGhpZ2hsaWdodGluZyBmb3IgaW50ZXJmYWNlcy4KCSAqIEBzaW5jZSAzLjIKCSAqLwoJcHJpdmF0ZSBzdGF0aWMgZmluYWwgY2xhc3MgSW50ZXJmYWNlSGlnaGxpZ2h0aW5nIGV4dGVuZHMgU2VtYW50aWNIaWdobGlnaHRpbmcgewoKCQkvKgoJCSAqIEBzZWUgb3JnLmVjbGlwc2UuamR0LmludGVybmFsLnVpLmphdmFlZGl0b3IuU2VtYW50aWNIaWdobGlnaHRpbmcjZ2V0UHJlZmVyZW5jZUtleSgpCgkJICovCgkJQE92ZXJyaWRlCgkJcHVibGljIFN0cmluZyBnZXRQcmVmZXJlbmNlS2V5KCkgewoJCQlyZXR1cm4gSU5URVJGQUNFOwoJCX0KCgkJLyoKCQkgKiBAc2VlIG9yZy5lY2xpcHNlLmpkdC5pbnRlcm5hbC51aS5qYXZhZWRpdG9yLklTZW1hbnRpY0hpZ2hsaWdodGluZyNnZXREZWZhdWx0VGV4dENvbG9yKCkKCQkgKi8KCQlAT3ZlcnJpZGUKCQlwdWJsaWMgUkdCIGdldERlZmF1bHREZWZhdWx0VGV4dENvbG9yKCkgewoJCQlyZXR1cm4gbmV3IFJHQig1MCwgNjMsIDExMik7CgkJfQoKCQkvKgoJCSAqIEBzZWUgb3JnLmVjbGlwc2UuamR0LmludGVybmFsLnVpLmphdmFlZGl0b3IuSVNlbWFudGljSGlnaGxpZ2h0aW5nI2dldERlZmF1bHRUZXh0U3R5bGVCb2xkKCkKCQkgKi8KCQlAT3ZlcnJpZGUKCQlwdWJsaWMgYm9vbGVhbiBpc0JvbGRCeURlZmF1bHQoKSB7CgkJCXJldHVybiBmYWxzZTsKCQl9CgoJCS8qCgkJICogQHNlZSBvcmcuZWNsaXBzZS5qZHQuaW50ZXJuYWwudWkuamF2YWVkaXRvci5TZW1hbnRpY0hpZ2hsaWdodGluZyNpc0l0YWxpY0J5RGVmYXVsdCgpCgkJICovCgkJQE92ZXJyaWRlCgkJcHVibGljIGJvb2xlYW4gaXNJdGFsaWNCeURlZmF1bHQoKSB7CgkJCXJldHVybiBmYWxzZTsKCQl9CgoJCS8qCgkJICogQHNlZSBvcmcuZWNsaXBzZS5qZHQuaW50ZXJuYWwudWkuamF2YWVkaXRvci5TZW1hbnRpY0hpZ2hsaWdodGluZyNpc0VuYWJsZWRCeURlZmF1bHQoKQoJCSAqLwoJCUBPdmVycmlkZQoJCXB1YmxpYyBib29sZWFuIGlzRW5hYmxlZEJ5RGVmYXVsdCgpIHsKCQkJcmV0dXJuIGZhbHNlOwoJCX0KCgkJLyoKCQkgKiBAc2VlIG9yZy5lY2xpcHNlLmpkdC5pbnRlcm5hbC51aS5qYXZhZWRpdG9yLklTZW1hbnRpY0hpZ2hsaWdodGluZyNnZXREaXNwbGF5TmFtZSgpCgkJICovCgkJQE92ZXJyaWRlCgkJcHVibGljIFN0cmluZyBnZXREaXNwbGF5TmFtZSgpIHsKCQkJcmV0dXJuIEphdmFFZGl0b3JNZXNzYWdlcy5TZW1hbnRpY0hpZ2hsaWdodGluZ19pbnRlcmZhY2VzOwoJCX0KCgkJLyoKCQkgKiBAc2VlIG9yZy5lY2xpcHNlLmpkdC5pbnRlcm5hbC51aS5qYXZhZWRpdG9yLlNlbWFudGljSGlnaGxpZ2h0aW5nI2NvbnN1bWVzKG9yZy5lY2xpcHNlLmpkdC5pbnRlcm5hbC51aS5qYXZhZWRpdG9yLlNlbWFudGljVG9rZW4pCgkJICovCgkJQE92ZXJyaWRlCgkJcHVibGljIGJvb2xlYW4gY29uc3VtZXMoU2VtYW50aWNUb2tlbiB0b2tlbikgewoKCQkJLy8gMTogbWF0Y2ggdHlwZXMKCQkJU2ltcGxlTmFtZSBuYW1lPSB0b2tlbi5nZXROb2RlKCk7CgkJCUFTVE5vZGUgbm9kZT0gbmFtZS5nZXRQYXJlbnQoKTsKCQkJaW50IG5vZGVUeXBlPSBub2RlLmdldE5vZGVUeXBlKCk7CgkJCWlmIChub2RlVHlwZSAhPSBBU1ROb2RlLlNJTVBMRV9UWVBFICYmIG5vZGVUeXBlICE9IEFTVE5vZGUuUVVBTElGSUVEX1RZUEUgICYmIG5vZGVUeXBlICE9IEFTVE5vZGUuUVVBTElGSUVEX05BTUUgJiYgbm9kZVR5cGUgIT0gQVNUTm9kZS5UWVBFX0RFQ0xBUkFUSU9OKQoJCQkJcmV0dXJuIGZhbHNlOwoJCQl3aGlsZSAobm9kZVR5cGUgPT0gQVNUTm9kZS5RVUFMSUZJRURfTkFNRSkgewoJCQkJbm9kZT0gbm9kZS5nZXRQYXJlbnQoKTsKCQkJCW5vZGVUeXBlPSBub2RlLmdldE5vZGVUeXBlKCk7CgkJCQlpZiAobm9kZVR5cGUgPT0gQVNUTm9kZS5JTVBPUlRfREVDTEFSQVRJT04pCgkJCQkJcmV0dXJuIGZhbHNlOwoJCQl9CgoJCQkvLyAyOiBtYXRjaCBpbnRlcmZhY2VzCgkJCUlCaW5kaW5nIGJpbmRpbmc9IHRva2VuLmdldEJpbmRpbmcoKTsKCQkJcmV0dXJuIGJpbmRpbmcgaW5zdGFuY2VvZiBJVHlwZUJpbmRpbmcgJiYgKChJVHlwZUJpbmRpbmcpIGJpbmRpbmcpLmlzSW50ZXJmYWNlKCk7CgkJfQoJfQoKCS8qKgoJICogU2VtYW50aWMgaGlnaGxpZ2h0aW5nIGZvciBhbm5vdGF0aW9uIHR5cGVzLgoJICogQHNpbmNlIDMuMgoJICovCglwcml2YXRlIHN0YXRpYyBmaW5hbCBjbGFzcyBBbm5vdGF0aW9uSGlnaGxpZ2h0aW5nIGV4dGVuZHMgU2VtYW50aWNIaWdobGlnaHRpbmcgewoKCQkvKgoJCSAqIEBzZWUgb3JnLmVjbGlwc2UuamR0LmludGVybmFsLnVpLmphdmFlZGl0b3IuU2VtYW50aWNIaWdobGlnaHRpbmcjZ2V0UHJlZmVyZW5jZUtleSgpCgkJICovCgkJQE92ZXJyaWRlCgkJcHVibGljIFN0cmluZyBnZXRQcmVmZXJlbmNlS2V5KCkgewoJCQlyZXR1cm4gQU5OT1RBVElPTjsKCQl9CgoJCS8qCgkJICogQHNlZSBvcmcuZWNsaXBzZS5qZHQuaW50ZXJuYWwudWkuamF2YWVkaXRvci5JU2VtYW50aWNIaWdobGlnaHRpbmcjZ2V0RGVmYXVsdFRleHRDb2xvcigpCgkJICovCgkJQE92ZXJyaWRlCgkJcHVibGljIFJHQiBnZXREZWZhdWx0RGVmYXVsdFRleHRDb2xvcigpIHsKCQkJcmV0dXJuIG5ldyBSR0IoMTAwLCAxMDAsIDEwMCk7CgkJfQoKCQkvKgoJCSAqIEBzZWUgb3JnLmVjbGlwc2UuamR0LmludGVybmFsLnVpLmphdmFlZGl0b3IuSVNlbWFudGljSGlnaGxpZ2h0aW5nI2dldERlZmF1bHRUZXh0U3R5bGVCb2xkKCkKCQkgKi8KCQlAT3ZlcnJpZGUKCQlwdWJsaWMgYm9vbGVhbiBpc0JvbGRCeURlZmF1bHQoKSB7CgkJCXJldHVybiBmYWxzZTsKCQl9CgoJCS8qCgkJICogQHNlZSBvcmcuZWNsaXBzZS5qZHQuaW50ZXJuYWwudWkuamF2YWVkaXRvci5TZW1hbnRpY0hpZ2hsaWdodGluZyNpc0l0YWxpY0J5RGVmYXVsdCgpCgkJICovCgkJQE92ZXJyaWRlCgkJcHVibGljIGJvb2xlYW4gaXNJdGFsaWNCeURlZmF1bHQoKSB7CgkJCXJldHVybiBmYWxzZTsKCQl9CgoJCS8qCgkJICogQHNlZSBvcmcuZWNsaXBzZS5qZHQuaW50ZXJuYWwudWkuamF2YWVkaXRvci5TZW1hbnRpY0hpZ2hsaWdodGluZyNpc0VuYWJsZWRCeURlZmF1bHQoKQoJCSAqLwoJCUBPdmVycmlkZQoJCXB1YmxpYyBib29sZWFuIGlzRW5hYmxlZEJ5RGVmYXVsdCgpIHsKCQkJcmV0dXJuIHRydWU7IC8vIGFzIGl0IHJlcGxhY2VzIHRoZSBzeW50YXggYmFzZWQgaGlnaGxpZ2h0aW5nIHdoaWNoIGlzIGFsd2F5cyBlbmFibGVkCgkJfQoKCQkvKgoJCSAqIEBzZWUgb3JnLmVjbGlwc2UuamR0LmludGVybmFsLnVpLmphdmFlZGl0b3IuSVNlbWFudGljSGlnaGxpZ2h0aW5nI2dldERpc3BsYXlOYW1lKCkKCQkgKi8KCQlAT3ZlcnJpZGUKCQlwdWJsaWMgU3RyaW5nIGdldERpc3BsYXlOYW1lKCkgewoJCQlyZXR1cm4gSmF2YUVkaXRvck1lc3NhZ2VzLlNlbWFudGljSGlnaGxpZ2h0aW5nX2Fubm90YXRpb25zOwoJCX0KCgkJLyoKCQkgKiBAc2VlIG9yZy5lY2xpcHNlLmpkdC5pbnRlcm5hbC51aS5qYXZhZWRpdG9yLlNlbWFudGljSGlnaGxpZ2h0aW5nI2NvbnN1bWVzKG9yZy5lY2xpcHNlLmpkdC5pbnRlcm5hbC51aS5qYXZhZWRpdG9yLlNlbWFudGljVG9rZW4pCgkJICovCgkJQE92ZXJyaWRlCgkJcHVibGljIGJvb2xlYW4gY29uc3VtZXMoU2VtYW50aWNUb2tlbiB0b2tlbikgewoKCQkJLy8gMTogbWF0Y2ggdHlwZXMKCQkJU2ltcGxlTmFtZSBuYW1lPSB0b2tlbi5nZXROb2RlKCk7CgkJCUFTVE5vZGUgbm9kZT0gbmFtZS5nZXRQYXJlbnQoKTsKCQkJaW50IG5vZGVUeXBlPSBub2RlLmdldE5vZGVUeXBlKCk7CgkJCWlmIChub2RlVHlwZSAhPSBBU1ROb2RlLlNJTVBMRV9UWVBFICYmIG5vZGVUeXBlICE9IEFTVE5vZGUuUVVBTElGSUVEX1RZUEUgICYmIG5vZGVUeXBlICE9IEFTVE5vZGUuUVVBTElGSUVEX05BTUUgJiYgbm9kZVR5cGUgIT0gQVNUTm9kZS5BTk5PVEFUSU9OX1RZUEVfREVDTEFSQVRJT04KCQkJCQkmJiBub2RlVHlwZSAhPSBBU1ROb2RlLk1BUktFUl9BTk5PVEFUSU9OICYmIG5vZGVUeXBlICE9IEFTVE5vZGUuTk9STUFMX0FOTk9UQVRJT04gJiYgbm9kZVR5cGUgIT0gQVNUTm9kZS5TSU5HTEVfTUVNQkVSX0FOTk9UQVRJT04pCgkJCQlyZXR1cm4gZmFsc2U7CgkJCXdoaWxlIChub2RlVHlwZSA9PSBBU1ROb2RlLlFVQUxJRklFRF9OQU1FKSB7CgkJCQlub2RlPSBub2RlLmdldFBhcmVudCgpOwoJCQkJbm9kZVR5cGU9IG5vZGUuZ2V0Tm9kZVR5cGUoKTsKCQkJCWlmIChub2RlVHlwZSA9PSBBU1ROb2RlLklNUE9SVF9ERUNMQVJBVElPTikKCQkJCQlyZXR1cm4gZmFsc2U7CgkJCX0KCgkJCS8vIDI6IG1hdGNoIGFubm90YXRpb25zCgkJCUlCaW5kaW5nIGJpbmRpbmc9IHRva2VuLmdldEJpbmRpbmcoKTsKCQkJcmV0dXJuIGJpbmRpbmcgaW5zdGFuY2VvZiBJVHlwZUJpbmRpbmcgJiYgKChJVHlwZUJpbmRpbmcpIGJpbmRpbmcpLmlzQW5ub3RhdGlvbigpOwoJCX0KCX0KCgkvKioKCSAqIFNlbWFudGljIGhpZ2hsaWdodGluZyBmb3IgYW5ub3RhdGlvbiB0eXBlcy4KCSAqIEBzaW5jZSAzLjIKCSAqLwoJcHJpdmF0ZSBzdGF0aWMgZmluYWwgY2xhc3MgVHlwZUFyZ3VtZW50SGlnaGxpZ2h0aW5nIGV4dGVuZHMgU2VtYW50aWNIaWdobGlnaHRpbmcgewoKCQkvKgoJCSAqIEBzZWUgb3JnLmVjbGlwc2UuamR0LmludGVybmFsLnVpLmphdmFlZGl0b3IuU2VtYW50aWNIaWdobGlnaHRpbmcjZ2V0UHJlZmVyZW5jZUtleSgpCgkJICovCgkJQE92ZXJyaWRlCgkJcHVibGljIFN0cmluZyBnZXRQcmVmZXJlbmNlS2V5KCkgewoJCQlyZXR1cm4gVFlQRV9BUkdVTUVOVDsKCQl9CgoJCS8qCgkJICogQHNlZSBvcmcuZWNsaXBzZS5qZHQuaW50ZXJuYWwudWkuamF2YWVkaXRvci5JU2VtYW50aWNIaWdobGlnaHRpbmcjZ2V0RGVmYXVsdFRleHRDb2xvcigpCgkJICovCgkJQE92ZXJyaWRlCgkJcHVibGljIFJHQiBnZXREZWZhdWx0RGVmYXVsdFRleHRDb2xvcigpIHsKCQkJcmV0dXJuIG5ldyBSR0IoMTMsIDEwMCwgMCk7CgkJfQoKCQkvKgoJCSAqIEBzZWUgb3JnLmVjbGlwc2UuamR0LmludGVybmFsLnVpLmphdmFlZGl0b3IuSVNlbWFudGljSGlnaGxpZ2h0aW5nI2dldERlZmF1bHRUZXh0U3R5bGVCb2xkKCkKCQkgKi8KCQlAT3ZlcnJpZGUKCQlwdWJsaWMgYm9vbGVhbiBpc0JvbGRCeURlZmF1bHQoKSB7CgkJCXJldHVybiBmYWxzZTsKCQl9CgoJCS8qCgkJICogQHNlZSBvcmcuZWNsaXBzZS5qZHQuaW50ZXJuYWwudWkuamF2YWVkaXRvci5TZW1hbnRpY0hpZ2hsaWdodGluZyNpc0l0YWxpY0J5RGVmYXVsdCgpCgkJICovCgkJQE92ZXJyaWRlCgkJcHVibGljIGJvb2xlYW4gaXNJdGFsaWNCeURlZmF1bHQoKSB7CgkJCXJldHVybiBmYWxzZTsKCQl9CgoJCS8qCgkJICogQHNlZSBvcmcuZWNsaXBzZS5qZHQuaW50ZXJuYWwudWkuamF2YWVkaXRvci5TZW1hbnRpY0hpZ2hsaWdodGluZyNpc0VuYWJsZWRCeURlZmF1bHQoKQoJCSAqLwoJCUBPdmVycmlkZQoJCXB1YmxpYyBib29sZWFuIGlzRW5hYmxlZEJ5RGVmYXVsdCgpIHsKCQkJcmV0dXJuIGZhbHNlOwoJCX0KCgkJLyoKCQkgKiBAc2VlIG9yZy5lY2xpcHNlLmpkdC5pbnRlcm5hbC51aS5qYXZhZWRpdG9yLklTZW1hbnRpY0hpZ2hsaWdodGluZyNnZXREaXNwbGF5TmFtZSgpCgkJICovCgkJQE92ZXJyaWRlCgkJcHVibGljIFN0cmluZyBnZXREaXNwbGF5TmFtZSgpIHsKCQkJcmV0dXJuIEphdmFFZGl0b3JNZXNzYWdlcy5TZW1hbnRpY0hpZ2hsaWdodGluZ190eXBlQXJndW1lbnRzOwoJCX0KCgkJLyoKCQkgKiBAc2VlIG9yZy5lY2xpcHNlLmpkdC5pbnRlcm5hbC51aS5qYXZhZWRpdG9yLlNlbWFudGljSGlnaGxpZ2h0aW5nI2NvbnN1bWVzKG9yZy5lY2xpcHNlLmpkdC5pbnRlcm5hbC51aS5qYXZhZWRpdG9yLlNlbWFudGljVG9rZW4pCgkJICovCgkJQE92ZXJyaWRlCgkJcHVibGljIGJvb2xlYW4gY29uc3VtZXMoU2VtYW50aWNUb2tlbiB0b2tlbikgewoKCQkJLy8gMTogbWF0Y2ggdHlwZXMKCQkJU2ltcGxlTmFtZSBuYW1lPSB0b2tlbi5nZXROb2RlKCk7CgkJCUFTVE5vZGUgbm9kZT0gbmFtZS5nZXRQYXJlbnQoKTsKCQkJaW50IG5vZGVUeXBlPSBub2RlLmdldE5vZGVUeXBlKCk7CgkJCWlmIChub2RlVHlwZSAhPSBBU1ROb2RlLlNJTVBMRV9UWVBFICYmIG5vZGVUeXBlICE9IEFTVE5vZGUuUVVBTElGSUVEX1RZUEUpCgkJCQlyZXR1cm4gZmFsc2U7CgoJCQkvLyAyOiBtYXRjaCB0eXBlIGFyZ3VtZW50cwoJCQlTdHJ1Y3R1cmFsUHJvcGVydHlEZXNjcmlwdG9yIGxvY2F0aW9uSW5QYXJlbnQ9IG5vZGUuZ2V0TG9jYXRpb25JblBhcmVudCgpOwoJCQlpZiAobG9jYXRpb25JblBhcmVudCA9PSBQYXJhbWV0ZXJpemVkVHlwZS5UWVBFX0FSR1VNRU5UU19QUk9QRVJUWSkKCQkJCXJldHVybiB0cnVlOwoKCQkJcmV0dXJuIGZhbHNlOwoJCX0KCX0KCgkvKioKCSAqIFNlbWFudGljIGhpZ2hsaWdodGluZyBmb3IgbnVtYmVycy4KCSAqIEBzaW5jZSAzLjQKCSAqLwoJcHJpdmF0ZSBzdGF0aWMgZmluYWwgY2xhc3MgTnVtYmVySGlnaGxpZ2h0aW5nIGV4dGVuZHMgU2VtYW50aWNIaWdobGlnaHRpbmcgewoKCQkvKgoJCSAqIEBzZWUgb3JnLmVjbGlwc2UuamR0LmludGVybmFsLnVpLmphdmFlZGl0b3IuU2VtYW50aWNIaWdobGlnaHRpbmcjZ2V0UHJlZmVyZW5jZUtleSgpCgkJICovCgkJQE92ZXJyaWRlCgkJcHVibGljIFN0cmluZyBnZXRQcmVmZXJlbmNlS2V5KCkgewoJCQlyZXR1cm4gTlVNQkVSOwoJCX0KCgkJLyoKCQkgKiBAc2VlIG9yZy5lY2xpcHNlLmpkdC5pbnRlcm5hbC51aS5qYXZhZWRpdG9yLklTZW1hbnRpY0hpZ2hsaWdodGluZyNnZXREZWZhdWx0VGV4dENvbG9yKCkKCQkgKi8KCQlAT3ZlcnJpZGUKCQlwdWJsaWMgUkdCIGdldERlZmF1bHREZWZhdWx0VGV4dENvbG9yKCkgewoJCQlyZXR1cm4gbmV3IFJHQig0MiwgMCwgMjU1KTsKCQl9CgoJCS8qCgkJICogQHNlZSBvcmcuZWNsaXBzZS5qZHQuaW50ZXJuYWwudWkuamF2YWVkaXRvci5JU2VtYW50aWNIaWdobGlnaHRpbmcjZ2V0RGVmYXVsdFRleHRTdHlsZUJvbGQoKQoJCSAqLwoJCUBPdmVycmlkZQoJCXB1YmxpYyBib29sZWFuIGlzQm9sZEJ5RGVmYXVsdCgpIHsKCQkJcmV0dXJuIGZhbHNlOwoJCX0KCgkJLyoKCQkgKiBAc2VlIG9yZy5lY2xpcHNlLmpkdC5pbnRlcm5hbC51aS5qYXZhZWRpdG9yLlNlbWFudGljSGlnaGxpZ2h0aW5nI2lzSXRhbGljQnlEZWZhdWx0KCkKCQkgKi8KCQlAT3ZlcnJpZGUKCQlwdWJsaWMgYm9vbGVhbiBpc0l0YWxpY0J5RGVmYXVsdCgpIHsKCQkJcmV0dXJuIGZhbHNlOwoJCX0KCgkJLyoKCQkgKiBAc2VlIG9yZy5lY2xpcHNlLmpkdC5pbnRlcm5hbC51aS5qYXZhZWRpdG9yLlNlbWFudGljSGlnaGxpZ2h0aW5nI2lzRW5hYmxlZEJ5RGVmYXVsdCgpCgkJICovCgkJQE92ZXJyaWRlCgkJcHVibGljIGJvb2xlYW4gaXNFbmFibGVkQnlEZWZhdWx0KCkgewoJCQlyZXR1cm4gZmFsc2U7CgkJfQoKCQkvKgoJCSAqIEBzZWUgb3JnLmVjbGlwc2UuamR0LmludGVybmFsLnVpLmphdmFlZGl0b3IuSVNlbWFudGljSGlnaGxpZ2h0aW5nI2dldERpc3BsYXlOYW1lKCkKCQkgKi8KCQlAT3ZlcnJpZGUKCQlwdWJsaWMgU3RyaW5nIGdldERpc3BsYXlOYW1lKCkgewoJCQlyZXR1cm4gSmF2YUVkaXRvck1lc3NhZ2VzLlNlbWFudGljSGlnaGxpZ2h0aW5nX251bWJlcnM7CgkJfQoKCQkvKgoJCSAqIEBzZWUgb3JnLmVjbGlwc2UuamR0LmludGVybmFsLnVpLmphdmFlZGl0b3IuU2VtYW50aWNIaWdobGlnaHRpbmcjY29uc3VtZXMob3JnLmVjbGlwc2UuamR0LmludGVybmFsLnVpLmphdmFlZGl0b3IuU2VtYW50aWNUb2tlbikKCQkgKi8KCQlAT3ZlcnJpZGUKCQlwdWJsaWMgYm9vbGVhbiBjb25zdW1lcyhTZW1hbnRpY1Rva2VuIHRva2VuKSB7CgkJCXJldHVybiBmYWxzZTsKCQl9CgoJCS8qCgkJICogQHNlZSBvcmcuZWNsaXBzZS5qZHQuaW50ZXJuYWwudWkuamF2YWVkaXRvci5TZW1hbnRpY0hpZ2hsaWdodGluZyNjb25zdW1lc0xpdGVyYWwob3JnLmVjbGlwc2UuamR0LmludGVybmFsLnVpLmphdmFlZGl0b3IuU2VtYW50aWNUb2tlbikKCQkgKi8KCQlAT3ZlcnJpZGUKCQlwdWJsaWMgYm9vbGVhbiBjb25zdW1lc0xpdGVyYWwoU2VtYW50aWNUb2tlbiB0b2tlbikgewoJCQlFeHByZXNzaW9uIGV4cHI9IHRva2VuLmdldExpdGVyYWwoKTsKCQkJcmV0dXJuIGV4cHIgIT0gbnVsbCAmJiBleHByLmdldE5vZGVUeXBlKCkgPT0gQVNUTm9kZS5OVU1CRVJfTElURVJBTDsKCQl9Cgl9CgoJLyoqCgkgKiBTZW1hbnRpYyBoaWdobGlnaHRpbmcgZm9yIGNsYXNzZXMuCgkgKiBAc2luY2UgMy43CgkgKi8KCXByaXZhdGUgc3RhdGljIGZpbmFsIGNsYXNzIEFic3RyYWN0Q2xhc3NIaWdobGlnaHRpbmcgZXh0ZW5kcyBTZW1hbnRpY0hpZ2hsaWdodGluZyB7CgoJCS8qCgkJICogQHNlZSBvcmcuZWNsaXBzZS5qZHQuaW50ZXJuYWwudWkuamF2YWVkaXRvci5TZW1hbnRpY0hpZ2hsaWdodGluZyNnZXRQcmVmZXJlbmNlS2V5KCkKCQkgKi8KCQlAT3ZlcnJpZGUKCQlwdWJsaWMgU3RyaW5nIGdldFByZWZlcmVuY2VLZXkoKSB7CgkJCXJldHVybiBBQlNUUkFDVF9DTEFTUzsKCQl9CgoJCS8qCgkJICogQHNlZSBvcmcuZWNsaXBzZS5qZHQuaW50ZXJuYWwudWkuamF2YWVkaXRvci5JU2VtYW50aWNIaWdobGlnaHRpbmcjZ2V0RGVmYXVsdFRleHRDb2xvcigpCgkJICovCgkJQE92ZXJyaWRlCgkJcHVibGljIFJHQiBnZXREZWZhdWx0RGVmYXVsdFRleHRDb2xvcigpIHsKCQkJcmV0dXJuIG5ldyBSR0IoMTM5LCAxMzYsIDIyKTsKCQl9CgoJCS8qCgkJICogQHNlZSBvcmcuZWNsaXBzZS5qZHQuaW50ZXJuYWwudWkuamF2YWVkaXRvci5JU2VtYW50aWNIaWdobGlnaHRpbmcjZ2V0RGVmYXVsdFRleHRTdHlsZUJvbGQoKQoJCSAqLwoJCUBPdmVycmlkZQoJCXB1YmxpYyBib29sZWFuIGlzQm9sZEJ5RGVmYXVsdCgpIHsKCQkJcmV0dXJuIGZhbHNlOwoJCX0KCgkJLyoKCQkgKiBAc2VlIG9yZy5lY2xpcHNlLmpkdC5pbnRlcm5hbC51aS5qYXZhZWRpdG9yLlNlbWFudGljSGlnaGxpZ2h0aW5nI2lzSXRhbGljQnlEZWZhdWx0KCkKCQkgKi8KCQlAT3ZlcnJpZGUKCQlwdWJsaWMgYm9vbGVhbiBpc0l0YWxpY0J5RGVmYXVsdCgpIHsKCQkJcmV0dXJuIGZhbHNlOwoJCX0KCgkJLyoKCQkgKiBAc2VlIG9yZy5lY2xpcHNlLmpkdC5pbnRlcm5hbC51aS5qYXZhZWRpdG9yLlNlbWFudGljSGlnaGxpZ2h0aW5nI2lzRW5hYmxlZEJ5RGVmYXVsdCgpCgkJICovCgkJQE92ZXJyaWRlCgkJcHVibGljIGJvb2xlYW4gaXNFbmFibGVkQnlEZWZhdWx0KCkgewoJCQlyZXR1cm4gZmFsc2U7CgkJfQoKCQkvKgoJCSAqIEBzZWUgb3JnLmVjbGlwc2UuamR0LmludGVybmFsLnVpLmphdmFlZGl0b3IuSVNlbWFudGljSGlnaGxpZ2h0aW5nI2dldERpc3BsYXlOYW1lKCkKCQkgKi8KCQlAT3ZlcnJpZGUKCQlwdWJsaWMgU3RyaW5nIGdldERpc3BsYXlOYW1lKCkgewoJCQlyZXR1cm4gSmF2YUVkaXRvck1lc3NhZ2VzLlNlbWFudGljSGlnaGxpZ2h0aW5nX2Fic3RyYWN0Q2xhc3NlczsKCQl9CgoJCS8qCgkJICogQHNlZSBvcmcuZWNsaXBzZS5qZHQuaW50ZXJuYWwudWkuamF2YWVkaXRvci5TZW1hbnRpY0hpZ2hsaWdodGluZyNjb25zdW1lcyhvcmcuZWNsaXBzZS5qZHQuaW50ZXJuYWwudWkuamF2YWVkaXRvci5TZW1hbnRpY1Rva2VuKQoJCSAqLwoJCUBPdmVycmlkZQoJCXB1YmxpYyBib29sZWFuIGNvbnN1bWVzKFNlbWFudGljVG9rZW4gdG9rZW4pIHsKCgkJCS8vIDE6IG1hdGNoIHR5cGVzCgkJCVNpbXBsZU5hbWUgbmFtZT0gdG9rZW4uZ2V0Tm9kZSgpOwoJCQlBU1ROb2RlIG5vZGU9IG5hbWUuZ2V0UGFyZW50KCk7CgkJCWludCBub2RlVHlwZT0gbm9kZS5nZXROb2RlVHlwZSgpOwoJCQlpZiAobm9kZVR5cGUgIT0gQVNUTm9kZS5TSU1QTEVfVFlQRSAmJiBub2RlVHlwZSAhPSBBU1ROb2RlLlRISVNfRVhQUkVTU0lPTiAmJiBub2RlVHlwZSAhPSBBU1ROb2RlLlFVQUxJRklFRF9UWVBFICAmJiBub2RlVHlwZSAhPSBBU1ROb2RlLlFVQUxJRklFRF9OQU1FICYmIG5vZGVUeXBlICE9IEFTVE5vZGUuVFlQRV9ERUNMQVJBVElPTiAmJiBub2RlVHlwZSAhPSBBU1ROb2RlLk1FVEhPRF9JTlZPQ0FUSU9OKQoJCQkJcmV0dXJuIGZhbHNlOwoJCQl3aGlsZSAobm9kZVR5cGUgPT0gQVNUTm9kZS5RVUFMSUZJRURfTkFNRSkgewoJCQkJbm9kZT0gbm9kZS5nZXRQYXJlbnQoKTsKCQkJCW5vZGVUeXBlPSBub2RlLmdldE5vZGVUeXBlKCk7CgkJCQlpZiAobm9kZVR5cGUgPT0gQVNUTm9kZS5JTVBPUlRfREVDTEFSQVRJT04pCgkJCQkJcmV0dXJuIGZhbHNlOwoJCQl9CgoJCQkvLyAyOiBtYXRjaCBjbGFzc2VzCgkJCUlCaW5kaW5nIGJpbmRpbmc9IHRva2VuLmdldEJpbmRpbmcoKTsKCQkJaWYgKGJpbmRpbmcgaW5zdGFuY2VvZiBJVHlwZUJpbmRpbmcpIHsKCQkJCUlUeXBlQmluZGluZyB0eXBlQmluZGluZz0gKElUeXBlQmluZGluZykgYmluZGluZzsKCQkJCS8vIHNlZSBhbHNvIENsYXNzSGlnaGxpZ2h0aW5nCgkJCQlyZXR1cm4gdHlwZUJpbmRpbmcuaXNDbGFzcygpICYmICh0eXBlQmluZGluZy5nZXRNb2RpZmllcnMoKSAmIE1vZGlmaWVyLkFCU1RSQUNUKSAhPSAwOwoJCQl9CgoJCQlyZXR1cm4gZmFsc2U7CgkJfQoJfQoKCS8qKgoJICogQSBuYW1lZCBwcmVmZXJlbmNlIHRoYXQgY29udHJvbHMgdGhlIGdpdmVuIHNlbWFudGljIGhpZ2hsaWdodGluZydzIGNvbG9yLgoJICoKCSAqIEBwYXJhbSBzZW1hbnRpY0hpZ2hsaWdodGluZyB0aGUgc2VtYW50aWMgaGlnaGxpZ2h0aW5nCgkgKiBAcmV0dXJuIHRoZSBjb2xvciBwcmVmZXJlbmNlIGtleQoJICovCglwdWJsaWMgc3RhdGljIFN0cmluZyBnZXRDb2xvclByZWZlcmVuY2VLZXkoU2VtYW50aWNIaWdobGlnaHRpbmcgc2VtYW50aWNIaWdobGlnaHRpbmcpIHsKCQlyZXR1cm4gUHJlZmVyZW5jZUNvbnN0YW50cy5FRElUT1JfU0VNQU5USUNfSElHSExJR0hUSU5HX1BSRUZJWCArIHNlbWFudGljSGlnaGxpZ2h0aW5nLmdldFByZWZlcmVuY2VLZXkoKSArIFByZWZlcmVuY2VDb25zdGFudHMuRURJVE9SX1NFTUFOVElDX0hJR0hMSUdIVElOR19DT0xPUl9TVUZGSVg7Cgl9CgoJLyoqCgkgKiBBIG5hbWVkIHByZWZlcmVuY2UgdGhhdCBjb250cm9scyBpZiB0aGUgZ2l2ZW4gc2VtYW50aWMgaGlnaGxpZ2h0aW5nIGhhcyB0aGUgdGV4dCBhdHRyaWJ1dGUgYm9sZC4KCSAqCgkgKiBAcGFyYW0gc2VtYW50aWNIaWdobGlnaHRpbmcgdGhlIHNlbWFudGljIGhpZ2hsaWdodGluZwoJICogQHJldHVybiB0aGUgYm9sZCBwcmVmZXJlbmNlIGtleQoJICovCglwdWJsaWMgc3RhdGljIFN0cmluZyBnZXRCb2xkUHJlZmVyZW5jZUtleShTZW1hbnRpY0hpZ2hsaWdodGluZyBzZW1hbnRpY0hpZ2hsaWdodGluZykgewoJCXJldHVybiBQcmVmZXJlbmNlQ29uc3RhbnRzLkVESVRPUl9TRU1BTlRJQ19ISUdITElHSFRJTkdfUFJFRklYICsgc2VtYW50aWNIaWdobGlnaHRpbmcuZ2V0UHJlZmVyZW5jZUtleSgpICsgUHJlZmVyZW5jZUNvbnN0YW50cy5FRElUT1JfU0VNQU5USUNfSElHSExJR0hUSU5HX0JPTERfU1VGRklYOwoJfQoKCS8qKgoJICogQSBuYW1lZCBwcmVmZXJlbmNlIHRoYXQgY29udHJvbHMgaWYgdGhlIGdpdmVuIHNlbWFudGljIGhpZ2hsaWdodGluZyBoYXMgdGhlIHRleHQgYXR0cmlidXRlIGl0YWxpYy4KCSAqCgkgKiBAcGFyYW0gc2VtYW50aWNIaWdobGlnaHRpbmcgdGhlIHNlbWFudGljIGhpZ2hsaWdodGluZwoJICogQHJldHVybiB0aGUgaXRhbGljIHByZWZlcmVuY2Uga2V5CgkgKi8KCXB1YmxpYyBzdGF0aWMgU3RyaW5nIGdldEl0YWxpY1ByZWZlcmVuY2VLZXkoU2VtYW50aWNIaWdobGlnaHRpbmcgc2VtYW50aWNIaWdobGlnaHRpbmcpIHsKCQlyZXR1cm4gUHJlZmVyZW5jZUNvbnN0YW50cy5FRElUT1JfU0VNQU5USUNfSElHSExJR0hUSU5HX1BSRUZJWCArIHNlbWFudGljSGlnaGxpZ2h0aW5nLmdldFByZWZlcmVuY2VLZXkoKSArIFByZWZlcmVuY2VDb25zdGFudHMuRURJVE9SX1NFTUFOVElDX0hJR0hMSUdIVElOR19JVEFMSUNfU1VGRklYOwoJfQoKCS8qKgoJICogQSBuYW1lZCBwcmVmZXJlbmNlIHRoYXQgY29udHJvbHMgaWYgdGhlIGdpdmVuIHNlbWFudGljIGhpZ2hsaWdodGluZyBoYXMgdGhlIHRleHQgYXR0cmlidXRlIHN0cmlrZXRocm91Z2guCgkgKgoJICogQHBhcmFtIHNlbWFudGljSGlnaGxpZ2h0aW5nIHRoZSBzZW1hbnRpYyBoaWdobGlnaHRpbmcKCSAqIEByZXR1cm4gdGhlIHN0cmlrZXRocm91Z2ggcHJlZmVyZW5jZSBrZXkKCSAqIEBzaW5jZSAzLjEKCSAqLwoJcHVibGljIHN0YXRpYyBTdHJpbmcgZ2V0U3RyaWtldGhyb3VnaFByZWZlcmVuY2VLZXkoU2VtYW50aWNIaWdobGlnaHRpbmcgc2VtYW50aWNIaWdobGlnaHRpbmcpIHsKCQlyZXR1cm4gUHJlZmVyZW5jZUNvbnN0YW50cy5FRElUT1JfU0VNQU5USUNfSElHSExJR0hUSU5HX1BSRUZJWCArIHNlbWFudGljSGlnaGxpZ2h0aW5nLmdldFByZWZlcmVuY2VLZXkoKSArIFByZWZlcmVuY2VDb25zdGFudHMuRURJVE9SX1NFTUFOVElDX0hJR0hMSUdIVElOR19TVFJJS0VUSFJPVUdIX1NVRkZJWDsKCX0KCgkvKioKCSAqIEEgbmFtZWQgcHJlZmVyZW5jZSB0aGF0IGNvbnRyb2xzIGlmIHRoZSBnaXZlbiBzZW1hbnRpYyBoaWdobGlnaHRpbmcgaGFzIHRoZSB0ZXh0IGF0dHJpYnV0ZSB1bmRlcmxpbmUuCgkgKgoJICogQHBhcmFtIHNlbWFudGljSGlnaGxpZ2h0aW5nIHRoZSBzZW1hbnRpYyBoaWdobGlnaHRpbmcKCSAqIEByZXR1cm4gdGhlIHVuZGVybGluZSBwcmVmZXJlbmNlIGtleQoJICogQHNpbmNlIDMuMQoJICovCglwdWJsaWMgc3RhdGljIFN0cmluZyBnZXRVbmRlcmxpbmVQcmVmZXJlbmNlS2V5KFNlbWFudGljSGlnaGxpZ2h0aW5nIHNlbWFudGljSGlnaGxpZ2h0aW5nKSB7CgkJcmV0dXJuIFByZWZlcmVuY2VDb25zdGFudHMuRURJVE9SX1NFTUFOVElDX0hJR0hMSUdIVElOR19QUkVGSVggKyBzZW1hbnRpY0hpZ2hsaWdodGluZy5nZXRQcmVmZXJlbmNlS2V5KCkgKyBQcmVmZXJlbmNlQ29uc3RhbnRzLkVESVRPUl9TRU1BTlRJQ19ISUdITElHSFRJTkdfVU5ERVJMSU5FX1NVRkZJWDsKCX0KCgkvKioKCSAqIEEgbmFtZWQgcHJlZmVyZW5jZSB0aGF0IGNvbnRyb2xzIGlmIHRoZSBnaXZlbiBzZW1hbnRpYyBoaWdobGlnaHRpbmcgaXMgZW5hYmxlZC4KCSAqCgkgKiBAcGFyYW0gc2VtYW50aWNIaWdobGlnaHRpbmcgdGhlIHNlbWFudGljIGhpZ2hsaWdodGluZwoJICogQHJldHVybiB0aGUgZW5hYmxlZCBwcmVmZXJlbmNlIGtleQoJICovCglwdWJsaWMgc3RhdGljIFN0cmluZyBnZXRFbmFibGVkUHJlZmVyZW5jZUtleShTZW1hbnRpY0hpZ2hsaWdodGluZyBzZW1hbnRpY0hpZ2hsaWdodGluZykgewoJCXJldHVybiBQcmVmZXJlbmNlQ29uc3RhbnRzLkVESVRPUl9TRU1BTlRJQ19ISUdITElHSFRJTkdfUFJFRklYICsgc2VtYW50aWNIaWdobGlnaHRpbmcuZ2V0UHJlZmVyZW5jZUtleSgpICsgUHJlZmVyZW5jZUNvbnN0YW50cy5FRElUT1JfU0VNQU5USUNfSElHSExJR0hUSU5HX0VOQUJMRURfU1VGRklYOwoJfQoKCS8qKgoJICogQHJldHVybiBUaGUgc2VtYW50aWMgaGlnaGxpZ2h0aW5ncywgdGhlIG9yZGVyIGRlZmluZXMgdGhlIHByZWNlZGVuY2Ugb2YgbWF0Y2hlcywgdGhlIGZpcnN0IG1hdGNoIHdpbnMuCgkgKi8KCXB1YmxpYyBzdGF0aWMgU2VtYW50aWNIaWdobGlnaHRpbmdbXSBnZXRTZW1hbnRpY0hpZ2hsaWdodGluZ3MoKSB7CgkJaWYgKGZnU2VtYW50aWNIaWdobGlnaHRpbmdzID09IG51bGwpCgkJCWZnU2VtYW50aWNIaWdobGlnaHRpbmdzPSBuZXcgU2VtYW50aWNIaWdobGlnaHRpbmdbXSB7CgkJCQluZXcgRGVwcmVjYXRlZE1lbWJlckhpZ2hsaWdodGluZygpLAoJCQkJbmV3IEF1dG9ib3hIaWdobGlnaHRpbmcoKSwKCQkJCW5ldyBTdGF0aWNGaW5hbEZpZWxkSGlnaGxpZ2h0aW5nKCksCgkJCQluZXcgU3RhdGljRmllbGRIaWdobGlnaHRpbmcoKSwKCQkJCW5ldyBGaWVsZEhpZ2hsaWdodGluZygpLAoJCQkJbmV3IE1ldGhvZERlY2xhcmF0aW9uSGlnaGxpZ2h0aW5nKCksCgkJCQluZXcgU3RhdGljTWV0aG9kSW52b2NhdGlvbkhpZ2hsaWdodGluZygpLAoJCQkJbmV3IEFic3RyYWN0TWV0aG9kSW52b2NhdGlvbkhpZ2hsaWdodGluZygpLAoJCQkJbmV3IEFubm90YXRpb25FbGVtZW50UmVmZXJlbmNlSGlnaGxpZ2h0aW5nKCksCgkJCQluZXcgSW5oZXJpdGVkTWV0aG9kSW52b2NhdGlvbkhpZ2hsaWdodGluZygpLAoJCQkJbmV3IFBhcmFtZXRlclZhcmlhYmxlSGlnaGxpZ2h0aW5nKCksCgkJCQluZXcgTG9jYWxWYXJpYWJsZURlY2xhcmF0aW9uSGlnaGxpZ2h0aW5nKCksCgkJCQluZXcgTG9jYWxWYXJpYWJsZUhpZ2hsaWdodGluZygpLAoJCQkJbmV3IFR5cGVWYXJpYWJsZUhpZ2hsaWdodGluZygpLCAvLyBiZWZvcmUgdHlwZSBhcmd1bWVudHMhCgkJCQluZXcgTWV0aG9kSGlnaGxpZ2h0aW5nKCksIC8vIGJlZm9yZSB0eXBlcyB0byBnZXQgY3RvcnMKCQkJCW5ldyBUeXBlQXJndW1lbnRIaWdobGlnaHRpbmcoKSwgLy8gYmVmb3JlIG90aGVyIHR5cGVzCgkJCQluZXcgQWJzdHJhY3RDbGFzc0hpZ2hsaWdodGluZygpLCAvLyBiZWZvcmUgY2xhc3NlcwoJCQkJbmV3IENsYXNzSGlnaGxpZ2h0aW5nKCksCgkJCQluZXcgRW51bUhpZ2hsaWdodGluZygpLAoJCQkJbmV3IEFubm90YXRpb25IaWdobGlnaHRpbmcoKSwgLy8gYmVmb3JlIGludGVyZmFjZXMKCQkJCW5ldyBJbnRlcmZhY2VIaWdobGlnaHRpbmcoKSwKCQkJCW5ldyBOdW1iZXJIaWdobGlnaHRpbmcoKSwKCQkJfTsKCQlyZXR1cm4gZmdTZW1hbnRpY0hpZ2hsaWdodGluZ3M7Cgl9CgoJLyoqCgkgKiBJbml0aWFsaXplIGRlZmF1bHQgcHJlZmVyZW5jZXMgaW4gdGhlIGdpdmVuIHByZWZlcmVuY2Ugc3RvcmUuCgkgKiBAcGFyYW0gc3RvcmUgVGhlIHByZWZlcmVuY2Ugc3RvcmUKCSAqLwoJcHVibGljIHN0YXRpYyB2b2lkIGluaXREZWZhdWx0cyhJUHJlZmVyZW5jZVN0b3JlIHN0b3JlKSB7CgkJU2VtYW50aWNIaWdobGlnaHRpbmdbXSBzZW1hbnRpY0hpZ2hsaWdodGluZ3M9IGdldFNlbWFudGljSGlnaGxpZ2h0aW5ncygpOwoJCWZvciAoaW50IGk9IDAsIG49IHNlbWFudGljSGlnaGxpZ2h0aW5ncy5sZW5ndGg7IGkgPCBuOyBpKyspIHsKCQkJU2VtYW50aWNIaWdobGlnaHRpbmcgc2VtYW50aWNIaWdobGlnaHRpbmc9IHNlbWFudGljSGlnaGxpZ2h0aW5nc1tpXTsKCQkJc2V0RGVmYXVsdEFuZEZpcmVFdmVudChzdG9yZSwgU2VtYW50aWNIaWdobGlnaHRpbmdzLmdldENvbG9yUHJlZmVyZW5jZUtleShzZW1hbnRpY0hpZ2hsaWdodGluZyksIHNlbWFudGljSGlnaGxpZ2h0aW5nLmdldERlZmF1bHRUZXh0Q29sb3IoKSk7CgkJCXN0b3JlLnNldERlZmF1bHQoU2VtYW50aWNIaWdobGlnaHRpbmdzLmdldEJvbGRQcmVmZXJlbmNlS2V5KHNlbWFudGljSGlnaGxpZ2h0aW5nKSwgc2VtYW50aWNIaWdobGlnaHRpbmcuaXNCb2xkQnlEZWZhdWx0KCkpOwoJCQlzdG9yZS5zZXREZWZhdWx0KFNlbWFudGljSGlnaGxpZ2h0aW5ncy5nZXRJdGFsaWNQcmVmZXJlbmNlS2V5KHNlbWFudGljSGlnaGxpZ2h0aW5nKSwgc2VtYW50aWNIaWdobGlnaHRpbmcuaXNJdGFsaWNCeURlZmF1bHQoKSk7CgkJCXN0b3JlLnNldERlZmF1bHQoU2VtYW50aWNIaWdobGlnaHRpbmdzLmdldFN0cmlrZXRocm91Z2hQcmVmZXJlbmNlS2V5KHNlbWFudGljSGlnaGxpZ2h0aW5nKSwgc2VtYW50aWNIaWdobGlnaHRpbmcuaXNTdHJpa2V0aHJvdWdoQnlEZWZhdWx0KCkpOwoJCQlzdG9yZS5zZXREZWZhdWx0KFNlbWFudGljSGlnaGxpZ2h0aW5ncy5nZXRVbmRlcmxpbmVQcmVmZXJlbmNlS2V5KHNlbWFudGljSGlnaGxpZ2h0aW5nKSwgc2VtYW50aWNIaWdobGlnaHRpbmcuaXNVbmRlcmxpbmVCeURlZmF1bHQoKSk7CgkJCXN0b3JlLnNldERlZmF1bHQoU2VtYW50aWNIaWdobGlnaHRpbmdzLmdldEVuYWJsZWRQcmVmZXJlbmNlS2V5KHNlbWFudGljSGlnaGxpZ2h0aW5nKSwgc2VtYW50aWNIaWdobGlnaHRpbmcuaXNFbmFibGVkQnlEZWZhdWx0KCkpOwoJCX0KCgkJY29udmVydE1ldGhvZEhpZ2hsaWdodGluZ1ByZWZlcmVuY2VzKHN0b3JlKTsKCQljb252ZXJ0QW5ub3RhdGlvbkhpZ2hsaWdodGluZ1ByZWZlcmVuY2VzKHN0b3JlKTsKCX0KCgkvKioKCSAqIFRlc3RzIHdoZXRoZXIgPGNvZGU+ZXZlbnQ8L2NvZGU+IGluIDxjb2RlPnN0b3JlPC9jb2RlPiBhZmZlY3RzIHRoZQoJICogZW5hYmxlbWVudCBvZiBzZW1hbnRpYyBoaWdobGlnaHRpbmcuCgkgKgoJICogQHBhcmFtIHN0b3JlIHRoZSBwcmVmZXJlbmNlIHN0b3JlIHdoZXJlIDxjb2RlPmV2ZW50PC9jb2RlPiB3YXMgb2JzZXJ2ZWQKCSAqIEBwYXJhbSBldmVudCB0aGUgcHJvcGVydHkgY2hhbmdlIHVuZGVyIGV4YW1pbmF0aW9uCgkgKiBAcmV0dXJuIDxjb2RlPnRydWU8L2NvZGU+IGlmIDxjb2RlPmV2ZW50PC9jb2RlPiBjaGFuZ2VkIHNlbWFudGljCgkgKiAgICAgICAgIGhpZ2hsaWdodGluZyBlbmFibGVtZW50LCA8Y29kZT5mYWxzZTwvY29kZT4gaWYgaXQgZGlkIG5vdAoJICogQHNpbmNlIDMuMQoJICovCglwdWJsaWMgc3RhdGljIGJvb2xlYW4gYWZmZWN0c0VuYWJsZW1lbnQoSVByZWZlcmVuY2VTdG9yZSBzdG9yZSwgUHJvcGVydHlDaGFuZ2VFdmVudCBldmVudCkgewoJCVN0cmluZyByZWxldmFudEtleT0gbnVsbDsKCQlTZW1hbnRpY0hpZ2hsaWdodGluZ1tdIGhpZ2hsaWdodGluZ3M9IGdldFNlbWFudGljSGlnaGxpZ2h0aW5ncygpOwoJCWZvciAoaW50IGk9IDA7IGkgPCBoaWdobGlnaHRpbmdzLmxlbmd0aDsgaSsrKSB7CgkJCWlmIChldmVudC5nZXRQcm9wZXJ0eSgpLmVxdWFscyhnZXRFbmFibGVkUHJlZmVyZW5jZUtleShoaWdobGlnaHRpbmdzW2ldKSkpIHsKCQkJCXJlbGV2YW50S2V5PSBldmVudC5nZXRQcm9wZXJ0eSgpOwoJCQkJYnJlYWs7CgkJCX0KCQl9CgkJaWYgKHJlbGV2YW50S2V5ID09IG51bGwpCgkJCXJldHVybiBmYWxzZTsKCgkJZm9yIChpbnQgaT0gMDsgaSA8IGhpZ2hsaWdodGluZ3MubGVuZ3RoOyBpKyspIHsKCQkJU3RyaW5nIGtleT0gZ2V0RW5hYmxlZFByZWZlcmVuY2VLZXkoaGlnaGxpZ2h0aW5nc1tpXSk7CgkJCWlmIChrZXkuZXF1YWxzKHJlbGV2YW50S2V5KSkKCQkJCWNvbnRpbnVlOwoJCQlpZiAoc3RvcmUuZ2V0Qm9vbGVhbihrZXkpKQoJCQkJcmV0dXJuIGZhbHNlOyAvLyBhbm90aGVyIGlzIHN0aWxsIGVuYWJsZWQgb3Igd2FzIGVuYWJsZWQgYmVmb3JlCgkJfQoKCQkvLyBhbGwgb3RoZXJzIGFyZSBkaXNhYmxlZCwgc28gdG9nZ2xpbmcgcmVsZXZhbnRLZXkgYWZmZWN0cyB0aGUgZW5hYmxlbWVudAoJCXJldHVybiB0cnVlOwoJfQoKCS8qKgoJICogVGVzdHMgd2hldGhlciBzZW1hbnRpYyBoaWdobGlnaHRpbmcgaXMgY3VycmVudGx5IGVuYWJsZWQuCgkgKgoJICogQHBhcmFtIHN0b3JlIHRoZSBwcmVmZXJlbmNlIHN0b3JlIHRvIGNvbnN1bHQKCSAqIEByZXR1cm4gPGNvZGU+dHJ1ZTwvY29kZT4gaWYgc2VtYW50aWMgaGlnaGxpZ2h0aW5nIGlzIGVuYWJsZWQsCgkgKiAgICAgICAgIDxjb2RlPmZhbHNlPC9jb2RlPiBpZiBpdCBpcyBub3QKCSAqIEBzaW5jZSAzLjEKCSAqLwoJcHVibGljIHN0YXRpYyBib29sZWFuIGlzRW5hYmxlZChJUHJlZmVyZW5jZVN0b3JlIHN0b3JlKSB7CgkJU2VtYW50aWNIaWdobGlnaHRpbmdbXSBoaWdobGlnaHRpbmdzPSBnZXRTZW1hbnRpY0hpZ2hsaWdodGluZ3MoKTsKCQlib29sZWFuIGVuYWJsZT0gZmFsc2U7CgkJZm9yIChpbnQgaT0gMDsgaSA8IGhpZ2hsaWdodGluZ3MubGVuZ3RoOyBpKyspIHsKCQkJU3RyaW5nIGVuYWJsZWRLZXk9IGdldEVuYWJsZWRQcmVmZXJlbmNlS2V5KGhpZ2hsaWdodGluZ3NbaV0pOwoJCQlpZiAoc3RvcmUuZ2V0Qm9vbGVhbihlbmFibGVkS2V5KSkgewoJCQkJZW5hYmxlPSB0cnVlOwoJCQkJYnJlYWs7CgkJCX0KCQl9CgoJCXJldHVybiBlbmFibGU7Cgl9CgoJLyoqCgkgKiBJbiAzLjAsIG1ldGhvZHMgd2VyZSBoaWdobGlnaHRlZCBieSBhIHJ1bGUtYmFzZWQgd29yZCBtYXRjaGVyIHRoYXQKCSAqIG1hdGNoZWQgYW55IGlkZW50aWZpZXIgdGhhdCB3YXMgZm9sbG93ZWQgYnkgcG9zc2libHkgd2hpdGUgc3BhY2UgYW5kIGEKCSAqIGxlZnQgcGFyZW50aGVzaXMuCgkgKiA8cD4KCSAqIFdpdGggZ2VuZXJpY3MsIHRoaXMgZG9lcyBub3Qgd29yayBhbnkgbG9uZ2VyIGZvciBjb25zdHJ1Y3RvcnMgb2YgZ2VuZXJpYwoJICogdHlwZXMsIGFuZCB0aGUgaGlnaGxpZ2h0aW5nIGhhcyBiZWVuIG1vdmVkIHRvIGJlIGEgc2VtYW50aWMgaGlnaGxpZ2h0aW5nLgoJICogQmVjYXVzZSBkaWZmZXJlbnQgcHJlZmVyZW5jZSBrZXkgbmFtaW5nIHNjaGVtZXMgYXJlIHVzZWQsIHdlIGhhdmUgdG8KCSAqIG1pZ3JhdGUgdGhlIG9sZCBzZXR0aW5ncyB0byB0aGUgbmV3IG9uZXMsIHdoaWNoIGlzIGRvbmUgaGVyZS4gTm90aGluZwoJICogbmVlZHMgdG8gYmUgZG9uZSBpZiB0aGUgb2xkIHNldHRpbmdzIHdlcmUgc2V0IHRvIHRoZSBkZWZhdWx0IHZhbHVlcy4KCSAqIDwvcD4KCSAqCgkgKiBAcGFyYW0gc3RvcmUgdGhlIHByZWZlcmVuY2Ugc3RvcmUgdG8gbWlncmF0ZQoJICogQHNpbmNlIDMuMQoJICovCglwcml2YXRlIHN0YXRpYyB2b2lkIGNvbnZlcnRNZXRob2RIaWdobGlnaHRpbmdQcmVmZXJlbmNlcyhJUHJlZmVyZW5jZVN0b3JlIHN0b3JlKSB7CgkJU3RyaW5nIGNvbG9ya2V5PSBQcmVmZXJlbmNlQ29uc3RhbnRzLkVESVRPUl9TRU1BTlRJQ19ISUdITElHSFRJTkdfUFJFRklYICsgTUVUSE9EICsgUHJlZmVyZW5jZUNvbnN0YW50cy5FRElUT1JfU0VNQU5USUNfSElHSExJR0hUSU5HX0NPTE9SX1NVRkZJWDsKCQlTdHJpbmcgYm9sZGtleT0gUHJlZmVyZW5jZUNvbnN0YW50cy5FRElUT1JfU0VNQU5USUNfSElHSExJR0hUSU5HX1BSRUZJWCArIE1FVEhPRCArIFByZWZlcmVuY2VDb25zdGFudHMuRURJVE9SX1NFTUFOVElDX0hJR0hMSUdIVElOR19CT0xEX1NVRkZJWDsKCQlTdHJpbmcgaXRhbGlja2V5PSBQcmVmZXJlbmNlQ29uc3RhbnRzLkVESVRPUl9TRU1BTlRJQ19ISUdITElHSFRJTkdfUFJFRklYICsgTUVUSE9EICsgUHJlZmVyZW5jZUNvbnN0YW50cy5FRElUT1JfU0VNQU5USUNfSElHSExJR0hUSU5HX0lUQUxJQ19TVUZGSVg7CgkJU3RyaW5nIGVuYWJsZWRrZXk9IFByZWZlcmVuY2VDb25zdGFudHMuRURJVE9SX1NFTUFOVElDX0hJR0hMSUdIVElOR19QUkVGSVggKyBNRVRIT0QgKyBQcmVmZXJlbmNlQ29uc3RhbnRzLkVESVRPUl9TRU1BTlRJQ19ISUdITElHSFRJTkdfRU5BQkxFRF9TVUZGSVg7CgoJCVN0cmluZyBvbGRDb2xvcmtleT0gUHJlZmVyZW5jZUNvbnN0YW50cy5FRElUT1JfSkFWQV9NRVRIT0RfTkFNRV9DT0xPUjsKCQlTdHJpbmcgb2xkQm9sZGtleT0gUHJlZmVyZW5jZUNvbnN0YW50cy5FRElUT1JfSkFWQV9NRVRIT0RfTkFNRV9CT0xEOwoJCVN0cmluZyBvbGRJdGFsaWNrZXk9IFByZWZlcmVuY2VDb25zdGFudHMuRURJVE9SX0pBVkFfTUVUSE9EX05BTUVfSVRBTElDOwoKCQlpZiAoY29uZGl0aW9uYWxSZXNldChzdG9yZSwgb2xkQ29sb3JrZXksIGNvbG9ya2V5KQoJCQkJfHwgY29uZGl0aW9uYWxSZXNldChzdG9yZSwgb2xkQm9sZGtleSwgYm9sZGtleSkKCQkJCXx8IGNvbmRpdGlvbmFsUmVzZXQoc3RvcmUsIG9sZEl0YWxpY2tleSwgaXRhbGlja2V5KSkgewoJCQlzdG9yZS5zZXRWYWx1ZShlbmFibGVka2V5LCB0cnVlKTsKCQl9CgoJfQoKCS8qKgoJICogSW4gMy4xLCBhbm5vdGF0aW9ucyB3ZXJlIGhpZ2hsaWdodGVkIGJ5IGEgcnVsZS1iYXNlZCB3b3JkIG1hdGNoZXIgdGhhdCBtYXRjaGVkIGFueSBpZGVudGlmaWVyCgkgKiBwcmVjZWRlZCBieSBhbiAnQCcgc2lnbiBhbmQgcG9zc2libHkgd2hpdGUgc3BhY2UuCgkgKiA8cD4KCSAqIFRoaXMgZG9lcyBub3Qgd29yayB3aGVuIHRoZXJlIGlzIGEgY29tbWVudCBiZXR3ZWVuIHRoZSAnQCcgYW5kIHRoZSBhbm5vdGF0aW9uLCByZXN1bHRzIGluCgkgKiBzdGFsZSBoaWdobGlnaHRpbmcgaWYgdGhlcmUgaXMgYSBuZXcgbGluZSBiZXR3ZWVuIHRoZSAnQCcgYW5kIHRoZSBhbm5vdGF0aW9uLCBhbmQgZG9lcyBub3QKCSAqIHdvcmsgZm9yIGhpZ2hsaWdodGluZyBhbm5vdGF0aW9uIGRlY2xhcmF0aW9ucy4gQmVjYXVzZSBkaWZmZXJlbnQgcHJlZmVyZW5jZSBrZXkgbmFtaW5nCgkgKiBzY2hlbWVzIGFyZSB1c2VkLCB3ZSBoYXZlIHRvIG1pZ3JhdGUgdGhlIG9sZCBzZXR0aW5ncyB0byB0aGUgbmV3IG9uZXMsIHdoaWNoIGlzIGRvbmUgaGVyZS4KCSAqIE5vdGhpbmcgbmVlZHMgdG8gYmUgZG9uZSBpZiB0aGUgb2xkIHNldHRpbmdzIHdlcmUgc2V0IHRvIHRoZSBkZWZhdWx0IHZhbHVlcy4KCSAqIDwvcD4KCSAqCgkgKiBAcGFyYW0gc3RvcmUgdGhlIHByZWZlcmVuY2Ugc3RvcmUgdG8gbWlncmF0ZQoJICogQHNpbmNlIDMuMgoJICovCglwcml2YXRlIHN0YXRpYyB2b2lkIGNvbnZlcnRBbm5vdGF0aW9uSGlnaGxpZ2h0aW5nUHJlZmVyZW5jZXMoSVByZWZlcmVuY2VTdG9yZSBzdG9yZSkgewoJCVN0cmluZyBjb2xvcmtleT0gUHJlZmVyZW5jZUNvbnN0YW50cy5FRElUT1JfU0VNQU5USUNfSElHSExJR0hUSU5HX1BSRUZJWCArIEFOTk9UQVRJT04gKyBQcmVmZXJlbmNlQ29uc3RhbnRzLkVESVRPUl9TRU1BTlRJQ19ISUdITElHSFRJTkdfQ09MT1JfU1VGRklYOwoJCVN0cmluZyBib2xka2V5PSBQcmVmZXJlbmNlQ29uc3RhbnRzLkVESVRPUl9TRU1BTlRJQ19ISUdITElHSFRJTkdfUFJFRklYICsgQU5OT1RBVElPTiArIFByZWZlcmVuY2VDb25zdGFudHMuRURJVE9SX1NFTUFOVElDX0hJR0hMSUdIVElOR19CT0xEX1NVRkZJWDsKCQlTdHJpbmcgaXRhbGlja2V5PSBQcmVmZXJlbmNlQ29uc3RhbnRzLkVESVRPUl9TRU1BTlRJQ19ISUdITElHSFRJTkdfUFJFRklYICsgQU5OT1RBVElPTiArIFByZWZlcmVuY2VDb25zdGFudHMuRURJVE9SX1NFTUFOVElDX0hJR0hMSUdIVElOR19JVEFMSUNfU1VGRklYOwoJCVN0cmluZyBzdHJpa2V0aHJvdWdoS2V5PSBQcmVmZXJlbmNlQ29uc3RhbnRzLkVESVRPUl9TRU1BTlRJQ19ISUdITElHSFRJTkdfUFJFRklYICsgQU5OT1RBVElPTiArIFByZWZlcmVuY2VDb25zdGFudHMuRURJVE9SX1NFTUFOVElDX0hJR0hMSUdIVElOR19TVFJJS0VUSFJPVUdIX1NVRkZJWDsKCQlTdHJpbmcgdW5kZXJsaW5lS2V5PSBQcmVmZXJlbmNlQ29uc3RhbnRzLkVESVRPUl9TRU1BTlRJQ19ISUdITElHSFRJTkdfUFJFRklYICsgQU5OT1RBVElPTiArIFByZWZlcmVuY2VDb25zdGFudHMuRURJVE9SX1NFTUFOVElDX0hJR0hMSUdIVElOR19VTkRFUkxJTkVfU1VGRklYOwoJCVN0cmluZyBlbmFibGVka2V5PSBQcmVmZXJlbmNlQ29uc3RhbnRzLkVESVRPUl9TRU1BTlRJQ19ISUdITElHSFRJTkdfUFJFRklYICsgQU5OT1RBVElPTiArIFByZWZlcmVuY2VDb25zdGFudHMuRURJVE9SX1NFTUFOVElDX0hJR0hMSUdIVElOR19FTkFCTEVEX1NVRkZJWDsKCgkJU3RyaW5nIG9sZENvbG9ya2V5PSBQcmVmZXJlbmNlQ29uc3RhbnRzLkVESVRPUl9KQVZBX0FOTk9UQVRJT05fQ09MT1I7CgkJU3RyaW5nIG9sZEJvbGRrZXk9IFByZWZlcmVuY2VDb25zdGFudHMuRURJVE9SX0pBVkFfQU5OT1RBVElPTl9CT0xEOwoJCVN0cmluZyBvbGRJdGFsaWNrZXk9IFByZWZlcmVuY2VDb25zdGFudHMuRURJVE9SX0pBVkFfQU5OT1RBVElPTl9JVEFMSUM7CgkJU3RyaW5nIG9sZFN0cmlrZXRocm91Z2hLZXk9IFByZWZlcmVuY2VDb25zdGFudHMuRURJVE9SX0pBVkFfQU5OT1RBVElPTl9TVFJJS0VUSFJPVUdIOwoJCVN0cmluZyBvbGRVbmRlcmxpbmVLZXk9IFByZWZlcmVuY2VDb25zdGFudHMuRURJVE9SX0pBVkFfQU5OT1RBVElPTl9VTkRFUkxJTkU7CgoJCWlmIChjb25kaXRpb25hbFJlc2V0KHN0b3JlLCBvbGRDb2xvcmtleSwgY29sb3JrZXkpCgkJCQl8fCBjb25kaXRpb25hbFJlc2V0KHN0b3JlLCBvbGRCb2xka2V5LCBib2xka2V5KQoJCQkJfHwgY29uZGl0aW9uYWxSZXNldChzdG9yZSwgb2xkSXRhbGlja2V5LCBpdGFsaWNrZXkpCgkJCQl8fCBjb25kaXRpb25hbFJlc2V0KHN0b3JlLCBvbGRTdHJpa2V0aHJvdWdoS2V5LCBzdHJpa2V0aHJvdWdoS2V5KQoJCQkJfHwgY29uZGl0aW9uYWxSZXNldChzdG9yZSwgb2xkVW5kZXJsaW5lS2V5LCB1bmRlcmxpbmVLZXkpKSB7CgkJCXN0b3JlLnNldFZhbHVlKGVuYWJsZWRrZXksIHRydWUpOwoJCX0KCgl9CgoJLyoqCgkgKiBJZiB0aGUgc2V0dGluZyBwb2ludGVkIHRvIGJ5IDxjb2RlPm9sZEtleTwvY29kZT4gaXMgbm90IHRoZSBkZWZhdWx0CgkgKiBzZXR0aW5nLCBzdG9yZSB0aGF0IHNldHRpbmcgdW5kZXIgPGNvZGU+bmV3S2V5PC9jb2RlPiBhbmQgcmVzZXQKCSAqIDxjb2RlPm9sZEtleTwvY29kZT4gdG8gaXRzIGRlZmF1bHQgc2V0dGluZy4KCSAqIDxwPgoJICogUmV0dXJucyA8Y29kZT50cnVlPC9jb2RlPiBpZiBhbnkgY2hhbmdlcyB3ZXJlIG1hZGUuCgkgKiA8L3A+CgkgKgoJICogQHBhcmFtIHN0b3JlIHRoZSBwcmVmZXJlbmNlIHN0b3JlIHRvIHJlYWQgZnJvbSBhbmQgd3JpdGUgdG8KCSAqIEBwYXJhbSBvbGRLZXkgdGhlIG9sZCBwcmVmZXJlbmNlIGtleQoJICogQHBhcmFtIG5ld0tleSB0aGUgbmV3IHByZWZlcmVuY2Uga2V5CgkgKiBAcmV0dXJuIDxjb2RlPnRydWU8L2NvZGU+IGlmIDxjb2RlPnN0b3JlPC9jb2RlPiB3YXMgbW9kaWZpZWQsCgkgKiAgICAgICAgIDxjb2RlPmZhbHNlPC9jb2RlPiBpZiBub3QKCSAqIEBzaW5jZSAzLjEKCSAqLwoJcHJpdmF0ZSBzdGF0aWMgYm9vbGVhbiBjb25kaXRpb25hbFJlc2V0KElQcmVmZXJlbmNlU3RvcmUgc3RvcmUsIFN0cmluZyBvbGRLZXksIFN0cmluZyBuZXdLZXkpIHsKCQlpZiAoIXN0b3JlLmlzRGVmYXVsdChvbGRLZXkpKSB7CgkJCWlmIChzdG9yZS5pc0RlZmF1bHQobmV3S2V5KSkKCQkJCXN0b3JlLnNldFZhbHVlKG5ld0tleSwgc3RvcmUuZ2V0U3RyaW5nKG9sZEtleSkpOwoJCQlzdG9yZS5zZXRUb0RlZmF1bHQob2xkS2V5KTsKCQkJcmV0dXJuIHRydWU7CgkJfQoJCXJldHVybiBmYWxzZTsKCX0KCgkvKioKCSAqIFNldHMgdGhlIGRlZmF1bHQgdmFsdWUgYW5kIGZpcmVzIGEgcHJvcGVydHkKCSAqIGNoYW5nZSBldmVudCBpZiBuZWNlc3NhcnkuCgkgKgoJICogQHBhcmFtIHN0b3JlCXRoZSBwcmVmZXJlbmNlIHN0b3JlCgkgKiBAcGFyYW0ga2V5IHRoZSBwcmVmZXJlbmNlIGtleQoJICogQHBhcmFtIG5ld1ZhbHVlIHRoZSBuZXcgdmFsdWUKCSAqIEBzaW5jZSAzLjMKCSAqLwoJcHJpdmF0ZSBzdGF0aWMgdm9pZCBzZXREZWZhdWx0QW5kRmlyZUV2ZW50KElQcmVmZXJlbmNlU3RvcmUgc3RvcmUsIFN0cmluZyBrZXksIFJHQiBuZXdWYWx1ZSkgewoJCVJHQiBvbGRWYWx1ZT0gbnVsbDsKCQlpZiAoc3RvcmUuaXNEZWZhdWx0KGtleSkpCgkJCW9sZFZhbHVlPSBQcmVmZXJlbmNlQ29udmVydGVyLmdldERlZmF1bHRDb2xvcihzdG9yZSwga2V5KTsKCgkJUHJlZmVyZW5jZUNvbnZlcnRlci5zZXREZWZhdWx0KHN0b3JlLCBrZXksIG5ld1ZhbHVlKTsKCgkJaWYgKG9sZFZhbHVlICE9IG51bGwgJiYgIW9sZFZhbHVlLmVxdWFscyhuZXdWYWx1ZSkpCgkJCXN0b3JlLmZpcmVQcm9wZXJ0eUNoYW5nZUV2ZW50KGtleSwgb2xkVmFsdWUsIG5ld1ZhbHVlKTsKCX0KCgkvKioKCSAqIERvIG5vdCBpbnN0YW50aWF0ZQoJICovCglwcml2YXRlIFNlbWFudGljSGlnaGxpZ2h0aW5ncygpIHsKCX0KfQo=